枚举受蕴涵约束的整数 m 元组

发布于 2024-09-13 14:13:04 字数 1354 浏览 10 评论 0原文

如何枚举所有 m 元组非负整数 (a[1],...,a[m]) 并遵守以下约束?

  1. 对于 {1,...,m} 中的每个 i,都有一个数字 n[i] >= 0,使得 a[i] <= n[i]。

  2. 对于 {1,...,m} 中 i,j 的每个有序对 (i,j),有数字 c[i][j], d[i][j] >= 0 这样那:

    如果a[i]> c[i][j],则 a[j] <= d[i][j]。

  3. c[i][j] = c[j][i]。

到目前为止,我已经提出了以下解决方案。有没有更有效的方法来做到这一点?我正在使用 C 或 C++ 进行编程。

for a[1]=0,...,n[1] do 
{
    for j=2,...,m do
    {
        if a[1] > c[1][j] then n[j]:=min{n[j],d[1][j]}
                          else n[j]:=n[j]
    }
    for a[2]=0,...,n[2] do 
    {
        for j=3,...,m do
        {
            if a[2] > c[2][j] then n[j]:=min{n[j],d[2][j]}
                              else n[j]:=n[j]
        }
        for a[3]=0,...,n[3] do
        {
            .
            .
            .
            for a[m]=0,...,n[m] do
            {
                print (a[1],...,a[m])
            }
        }...}}

我发现该算法存在一个主要的低效率问题。为了简单起见,取 m=2。假设对于所有 i,j,n[1] = n[2] = 2 且 c[i][j] = d[i][j] = 0。现在让我们看一下算法。

从 a[1] = 0 开始:n[2] 不变,因为 a[1] <= 0。我们打印 (0,0),(0,1),(0,2)。

接下来是a[1] = 1:因为a[1] > c[1][2], n[2] 在循环中更改为 min{ n[2],d[1][j] } = 0。我们打印 (1,0)。

最后a[1] = 2:因为a[1]> c[1][2], n[2] 在循环中改为 min{ n[2],d[1][j] } = 0。(我们只是做了和以前一样的事情。这就是低效率。 ) 我们打印(2,0)。

备注:对于我的应用,可以假设 c[i][j]=d[i][j]。

How do I enumerate all m-tuples of nonnegative integers (a[1],...,a[m]) subject to the following constraints?

  1. For each i in {1,...,m}, there is a number n[i] >= 0 such that a[i] <= n[i].

  2. For each ordered pair (i,j) with i,j in {1,...,m}, there are numbers c[i][j], d[i][j] >= 0 such that:

    if a[i] > c[i][j], then a[j] <= d[i][j].

  3. c[i][j] = c[j][i].

So far, I have come up with the following solution. Is there a more efficient way to do this? I am programming in C or C++.

for a[1]=0,...,n[1] do 
{
    for j=2,...,m do
    {
        if a[1] > c[1][j] then n[j]:=min{n[j],d[1][j]}
                          else n[j]:=n[j]
    }
    for a[2]=0,...,n[2] do 
    {
        for j=3,...,m do
        {
            if a[2] > c[2][j] then n[j]:=min{n[j],d[2][j]}
                              else n[j]:=n[j]
        }
        for a[3]=0,...,n[3] do
        {
            .
            .
            .
            for a[m]=0,...,n[m] do
            {
                print (a[1],...,a[m])
            }
        }...}}

I see one major inefficiency in this algorithm. To see it, take m=2 for simplicity. Say n[1] = n[2] = 2 and c[i][j] = d[i][j] = 0 for all i,j. Now let's go through the algorithm.

Start at a[1] = 0: n[2] is unchanged because a[1] <= 0. We print (0,0),(0,1),(0,2).

Next is a[1] = 1: Since a[1] > c[1][2], n[2] is changed in the loop to min{ n[2],d[1][j] } = 0. We print (1,0).

Finally a[1] = 2: Since a[1] > c[1][2], n[2] is changed in the loop to min{ n[2],d[1][j] } = 0. (We just did the same thing as before. That's the inefficiency.) We print (2,0).

Remark: For my application, it can be assumed that c[i][j]=d[i][j].

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

小…红帽 2024-09-20 14:13:04

一个有趣的问题。

请注意,时间必然与要枚举的元组的数量成正比。所以不可能渐进地改进你所拥有的东西。

就代码长度而言,这不可能是最佳的,至少不是最佳的。你根本不必为每个 i = 1..m 编写一个单独的 for 循环,

稍后我可能会对算法进行修改;但长话短说,运行时间将以 m 为指数(除了约束等于 1 的小情况)。

An interesting problem.

Note that time is necessarily proportional to the number of tuples that are to be enumerated. So it isn't possible to improve asymptotically on what you've got.

In terms of length of code, this can't be optimal, not by a long shot. You simply shouldn't have to code a separate for loop for every single i = 1..m

I may take a whack at the algorithm later; but to make a long story short, the running time will be exponential in m (except for trivial cases where constraints are equal to one.)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文