【问题标题】:Breadth first iteration?广度第一次迭代?
【发布时间】:2013-10-24 06:50:11
【问题描述】:

如果我们希望覆盖一个搜索空间,例如所有三元组(x, y, z),其中xyz 介于1n 之间,我们可以使用嵌套循环来这样做:

for (int x = 1; x <= n; x++)
   for (int y = 1; y <= n; y++)
      for (int z = 1; z <= n; z++)

这会生成三元组:(1, 1, 1)(1, 1, 2)(1, 1, 3)(1, 1, 4) 等,实际上是“深度优先搜索”或深度优先迭代。

有没有办法以更“广度优先”的方式进行迭代?这样的迭代将按类似于以下的顺序生成三元组:

(1, 1, 1)(2, 1, 1)(1, 2, 1)(1, 1, 2)(2, 2, 1)(2, 1, 2)(1, 2, 2)(2, 2, 2)(3, 1, 1)等...

还有生成这种模式的算法的名称吗?

【问题讨论】:

  • 我建议只使用实际的广度优先搜索。从(1, 1, 1) 开始,每当您将(x, y, z) 出队时,将尚未入队且未超出界限的(x+1, y, z)(x, y+1, z)(x, y, z+1) 分别入队。

标签: algorithm search iteration


【解决方案1】:
This should work.  
        for (int x = 1; x <= n; x++)
           for (int y = 1; y <= n; y++)
              {
               for (int z = 1; z <= n; z++)
                {  
                  enqueue(the x-y-z triplet);
                }
                  print(till the queue empties);
                }
Sorry for my pseudo-C.

【讨论】:

  • 队列没有做任何事情。这与只有三个嵌套循环的“深度优先”迭代相同。
【解决方案2】:

这段 C# 代码生成了我所描述的模式,并且顺序很好,但我觉得有更好的方法来做到这一点。

void Visit(ISet<Tuple<int, int, int>> pSet, int pX, int pY, int pZ) {
   var value = Tuple.Create(pX, pY, pZ);
   if (pSet == null)
      Console.WriteLine(value);
   else if (!pSet.Contains(value)){
      pSet.Add(value);
      Console.WriteLine(value);
   }
}

void Iterate() {
   const int n = 5;
   for (int x = 1; x <= n; x++) {
      var set = new HashSet<Tuple<int, int, int>>();
      for (int y = 1; y <= x; y++)
         for (int z = 1; z <= y; z++) {
            Visit(set, z, y, x);
            Visit(set, z, x, y);
            Visit(set, y, z, x);
            Visit(set, y, x, z);
            Visit(set, x, z, y);
            Visit(set, x, y, z);
         }
   }
}

此代码在不维护任何列表或进行任何冲突检查的情况下生成模式。我已经确认它会生成没有重复的 n³ 元组(最多 n = 500)。唯一的问题是这仅适用于迭代 3 元组整数的特定情况,而不是任何数量的任何类型的集合。

static void Iterate() {
   const int n = 500;
   for (int x = 1; x <= n; x++) {
      for (int y = 1; y <= x; y++)
         for (int z = 1; z <= y; z++) {
            Visit(z, y, x);
            if (x == y && y == z && x == z)
               continue;

            if (x != y)
               Visit(z, x, y);

            if (z != y) {
               Visit(y, z, x);
               Visit(y, x, z);
            }

            if (x != y && x != z) {
               Visit(x, z, y);
               if (z != y)
                  Visit(x, y, z);
            }
         }
   }
}

【讨论】:

    猜你喜欢
    • 2016-04-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-04-02
    • 1970-01-01
    • 2021-05-05
    • 2013-10-03
    • 2010-12-28
    相关资源
    最近更新 更多