Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/reactjs/27.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 在两个以上的维度中无限枚举_C#_Algorithm_Loops_Enumeration - Fatal编程技术网

C# 在两个以上的维度中无限枚举

C# 在两个以上的维度中无限枚举,c#,algorithm,loops,enumeration,C#,Algorithm,Loops,Enumeration,如果我想枚举多个有界值的所有组合,很容易: for(int i = 0; i <= iMax; i++) { for(int j = 0; j <= jMax; j++) { for(int k = 0; k <= kMax; k++) { DoSomething(i,j); } } } 但是,如何枚举多个无界值的所有组合?对于两个人,我知道的一个方法是“之字形”,就像这样: Bi

如果我想枚举多个有界值的所有组合,很容易:

for(int i = 0; i <= iMax; i++)
{
    for(int j = 0; j <= jMax; j++)
    {
        for(int k = 0; k <= kMax; k++)
        {
            DoSomething(i,j);
        }
    }
}
但是,如何枚举多个无界值的所有组合?对于两个人,我知道的一个方法是“之字形”,就像这样:

BigInteger i = 0;
BigInteger j = 0;
bool direction = true;
while(true)
{
    if(Condition(i,j)) { break; }

    if(direction)
    {
        if(j==0)
        {
            direction = false;
            i++;
        }
        else
        {
            i++;
            j--;
        }
    }
    else
    {
        if(i==0)
        {
            direction = true;
            j++;
        }
        else
        {
            j++;
            i--;
        }
    }
}
这将产生的前几个(
i
j
)对是:(0,0),(1,0),(0,1),(0,2),(1,1),(2,0),(3,0),(2,1),(1,2)

所以我的问题是:这个——或者其他一些方法——如何适应两个以上的维度?e、 g.如果我想在
I
j
k
上循环


注意:我知道有更好的方法来编写这些示例,为了简单起见,我已经尽可能简单地编写了它们。

这确实是一个组合数学问题,而不是计算机编程问题

在任何情况下,您都可以通过以下方式处理此无界多变量问题:

在0级,您有1个问题要检查[0,0,0]
在级别1,您有3个问题需要检查([0,0,1],[0,1,0],[1,0,0])
在2级,你有6个问题([0,0,2],[0,2,0],[2,0,0],[0,1,1],[1,0,1],[1,1,0])


因此,您必须为每个级别生成所有可能性(递归可能会有所帮助)

因此,正如您所提到的,一维很容易。从零开始数一数

2也没那么难,沿着对角线数数:

11 7 12 4 8 13 2 5 9 14 1 3 6 10 15 11 7 12 4 8 13 2 5 9 14 1 3 6 10 15 对于三维,我们可以想象一个金字塔,在其中我们每次添加一个新壳:

在这里,数字将表示该位置的高度,而不是每个项目的添加顺序

1 1.
1. 2 1
1. 2 1 3 2 1 您可以将此三维图想象为围绕球体添加壳(但移动到离散而非连续的比例),二维版本为同心圆,一维版本为这些同心圆的半径。当然,在所有情况下,我们只有图片的1/4,因为你把所有东西都限制为正值

那么,在第n种情况下,我们如何做到这一点呢

好的,每个壳由每个维度的值的组合来表示,这样它们的和是常数。因此,首先你找到每个维度的自然数值的每个组合,它们的和是
1
,然后你找到所有的和是
2
的组合,然后你找到所有和是3的组合,然后你继续到无穷远。

在2D中:生成所有对(j,k),使得j+k==i,增加i

for (i= 0; true; i++)
  for (j= 0, k= i; 0 <= k; j++, k--)


i=0 -> (0, 0)
i=1 -> (0, 1), (1, 0)
i=2 -> (0, 2), (1, 1), (2, 0)
...
for (i= 0; true; i++)
  for (j= 0, k= i; 0 <= k; j++, k--)
    for (l= 0, m= j; 0 <= m; l++, m--)


i=0, j=0 -> (0, 0, 0)
i=1, j=0 -> (0, 0, 1), (0, 1, 0)
i=1, j=1 -> (1, 0, 1), (1, 1, 0)
i=2, j=0 -> (0, 0, 2), (0, 1, 1), (0, 2, 0)
i=2, j=1 -> (1, 0, 2), (1, 1, 1), (1, 2, 0)
i=2, j=2 -> (2, 0, 2), (2, 1, 1), (2, 2, 0)
...
for(i=0;true;i++)
对于(j=0,k=i;0(0,0)
i=1->(0,1),(1,0)
i=2->(0,2)、(1,1)、(2,0)
...
在3D中:生成所有三元组(j,l,m),使l+m==j增加j,j+k=i增加i

for (i= 0; true; i++)
  for (j= 0, k= i; 0 <= k; j++, k--)


i=0 -> (0, 0)
i=1 -> (0, 1), (1, 0)
i=2 -> (0, 2), (1, 1), (2, 0)
...
for (i= 0; true; i++)
  for (j= 0, k= i; 0 <= k; j++, k--)
    for (l= 0, m= j; 0 <= m; l++, m--)


i=0, j=0 -> (0, 0, 0)
i=1, j=0 -> (0, 0, 1), (0, 1, 0)
i=1, j=1 -> (1, 0, 1), (1, 1, 0)
i=2, j=0 -> (0, 0, 2), (0, 1, 1), (0, 2, 0)
i=2, j=1 -> (1, 0, 2), (1, 1, 1), (1, 2, 0)
i=2, j=2 -> (2, 0, 2), (2, 1, 1), (2, 2, 0)
...
for(i=0;true;i++)
对于(j=0,k=i;0(0,0,1),(0,1,0)
i=1,j=1->(1,0,1),(1,1,0)
i=2,j=0->(0,0,2),(0,1,1),(0,2,0)
i=2,j=1->(1,0,2),(1,1,1),(1,2,0)
i=2,j=2->(2,0,2),(2,1,1),(2,2,0)
...
用于(限制=0;;++limit){

对于(i0=0;i0,你现在可以得到一个枚举2元组,你只需要看到
(x,y,z)
((x,y,z)之间有一个非常简单的一一对应关系
;这在某种程度上取决于中断条件是什么,以及您对它的了解程度。您需要避免向某个方向偏离而从未到达中断点的情况。问题显然是关于枚举所有组合的过程。
for (i= 0; true; i++)
  for (j= 0, k= i; 0 <= k; j++, k--)
    for (l= 0, m= j; 0 <= m; l++, m--)


i=0, j=0 -> (0, 0, 0)
i=1, j=0 -> (0, 0, 1), (0, 1, 0)
i=1, j=1 -> (1, 0, 1), (1, 1, 0)
i=2, j=0 -> (0, 0, 2), (0, 1, 1), (0, 2, 0)
i=2, j=1 -> (1, 0, 2), (1, 1, 1), (1, 2, 0)
i=2, j=2 -> (2, 0, 2), (2, 1, 1), (2, 2, 0)
...
for(limit=0;;++limit) {
  for(i0=0; i0<=limit; ++i0) {
    for(i1=0; i1<=limit-i0; ++i1) {
      for(i2=0; i2<=limit-i0-i1, ++i2) {
        for(i3=0; i3<=limit-i0-i1-i2, ++i3) {
          int i4 = limit-i0-i1-i2-i3;
          //do stuff with i0, i1, i2, i3, i4; break when had enough
      }}}}}}