【问题标题】:For loop that evaluates all values at once?一次评估所有值的for循环?
【发布时间】:2018-07-31 19:31:59
【问题描述】:

所以我有一个元胞自动机,我可以在其中将像素放置在图像上,并且它们每次“滴答”都会向下移动一个像素。现在的问题是因为for循环是这样的:

for(int x = 0; x < 100; x++){
   for(int y = 0; y < 100; y++){
     //Check if nothing below (x,y) pixel and move it down if so
   }
}

然后像素被传送到底部,因为它们在 y 循环的每次迭代中都向下移动。我通过使 y 循环从 100 下降到 0 而不是 0 到 100 来解决它,所以它向上迭代但是如果我想让我的像素在某些情况下向上移动它就行不通了。

可能是一个双循环,其中列出了要移动的像素以及第一个像素的移动位置,并在第二个中实际执行此操作,但这似乎性能很重,我确信有更好的解决方案

PS:如果你有更好的问题标题,请告诉我

【问题讨论】:

  • 你在哪里使用“tick”?是在这些 for 循环的内部还是外部?
  • 对不起,我无法理解您的问题,但您的标题绝对不是最佳的。我的意思是循环不可能一次评估所有迭代,因为它实际上是 iterate 的目的。
  • 所以基本上你的问题归结为:你想在某些情况下为 y 增加一个 for 循环,而在另一些情况下为 y 减少一个 for 循环?
  • 您能详细解释一下您要做什么吗?不清楚,你的代码肯定没有做你想做的,所以很难进行反向工程。

标签: c# cellular-automata


【解决方案1】:

您需要两个单元格副本。在伪代码中:

int[] currentCells = new int[...];
int[] nextCells = new int[...];

Initialize(currentCells);
while (true) {
    Draw(currentCells);
    Calculate next state by using currentCells as source and store result into nextCells;

    // exchange (this copies only references and is fast).
    var temp = currentCells;
    currentCells = nextCells;
    nextCells = temp;
}

请注意,我们循环遍历目标 (nextCells) 的每个单元格以获取它的新值。在整个过程中,我们从不查看nextCells 中的单元格,因为这些单元格可能已经被移动了。我们的来源严格来说是currentCells,它现在代表之前的(冻结)状态。

// Calculate next state.
for(int x = 0; x < 100; x++){
    for(int y = 0; y < 100; y++){
        if(currentCells[x, y] == 0 && y > 0) { // Nothing here
            // Take value from above
            nextCells[x, y] = currentCells[x, y - 1];
        } else {
            // Just copy
            nextCells[x, y] = currentCells[x, y];
        }
    }
}

例如,在Conway's Game of Life 中,您通过分析周围单元格的值来计算单元格的状态。这意味着向上或向下工作都不起作用。通过拥有 2 个缓冲区,您始终拥有一个在计算下一个状态期间不会更改的源缓冲区。

【讨论】:

  • 被接受为答案,但如果在 "currentCells[x, y] == 0 && y > 0" 中不应该有另一个,所以它不会覆盖如果任何单元格已经在 nextCells 中(如果一个正在移动向上和向下)
  • 不,因为我们忽略了 nextCells 中已经存在的先前值,并仅通过查看 currentCells 来计算新值。 currentCells 现在充当先前的单元格。所以实际的单元格([x, y])取自currentCells。如果currentCells[x, y] 是空的,这意味着我们确实有一个空的位置。
【解决方案2】:

假设你在内部 for 循环中想要做的事情正确,这样的事情会起作用吗?

static void MovePixels(bool moveUp)
{
    for (int x = 0; x < 100; x++)
    {
        if (moveUp)
        {
            for (int y = 0; y < 100; y++)
            {
            }
        }
        else
        {
            for (int y = 100; y > 0; y--)
            {
            }
        }
    }
}

【讨论】:

    猜你喜欢
    • 2019-01-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-12-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多