【问题标题】:Game of Life: Tried to increase computation efficiency with new algorithm, reduced in stead. Why?Game of Life: 尝试用新算法提高计算效率,反而降低了。为什么?
【发布时间】:2014-04-07 19:09:15
【问题描述】:

我正在编写 Conway 的 Game of Life,并制作了一个可运行、流畅的 JS 程序。我在工作版本中所做的是检查网格中每个坐标的每个相邻坐标,并根据其邻居的数量杀死或生成它。现在我想通过跟踪哪些坐标是活动的来提高算法的效率,并且只处理这些坐标和它们的邻居,而不是整个网格。我制作了这个替代程序:

var g = 0;
var cellMatrix = new Array();
var height = 68;  
var width = 100;
var livingCellIndex = 0;
var livingCells = new Array();

writeBoard();
declareFirstGeneration();
live();

function live() {

    processGeneration();
    g++;
    setTimeout(live, speed);

}

function declareNextGeneration() {

    livingCells[g + 1] = new Array();

    cellMatrix[g + 1] = new Array();

    for (var x = 0; x < width; x++) {

        cellMatrix[g + 1][x] = new Array();

        for (var y = 0; y < height; y++) {

            cellMatrix[g + 1][x][y] = false;
        }
    }
}

function declareFirstGeneration() {

    livingCells[g] = new Array();

    cellMatrix[g] = new Array();

    for (var x = 0; x < width; x++) {

        cellMatrix[g][x] = new Array();

        for (var y = 0; y < height; y++) {

            cellMatrix[g][x][y] = false;
        }
    }
}

function processGeneration() {

    declareNextGeneration();

    livingCellIndex = 0;

    var x, y;

    for (var i = 0; i < livingCells[g].length; i++) {

        x = livingCells[g][i][0];
        y = livingCells[g][i][1];

        numberOfNeighbors = getLivingNeighbors(x, y);
        //console.log("numberOfNeighbors", numberOfNeighbors);
        if (numberOfNeighbors == 2 || numberOfNeighbors == 3) {
            spawnCell(g + 1, x, y);
        } else {
            killCell(g + 1, x, y);
        }

        for (var neighborX = x - 1; neighborX <= x + 1; neighborX++) {
            for (var neighborY = y - 1; neighborY <= y + 1; neighborY++) {
                if (neighborX < width && neighborX >= 0 && neighborY < height && neighborY >= 0) {
                    numberOfNeighbors = getLivingNeighbors(neighborX, neighborY);
                    //console.log(g, neighborX, neighborY, "has ", numberOfNeighbors, " neighbors");
                    if (numberOfNeighbors == 3) {
                        spawnCell(g + 1, neighborX, neighborY);
                    }
                }
            }
        }
    }
    refreshGenerationDisplay(x,y);
}

function spawnCell(g, x, y) {

    cellMatrix[g][x][y] = true;
    livingCells[g][livingCellIndex] = new Array(2);
    livingCells[g][livingCellIndex][0] = x;
    livingCells[g][livingCellIndex][2] = y;
    document.getElementById(x + '-' + y).style.background = "green"; // visual grid 
    livingCellIndex++;
}


function killCell(g, x, y) {
    cellMatrix[g][x][y] = false;
    document.getElementById(x + '-' + y).style.background = "none"; // visual grid
}

但我发现它比我的第一个程序慢很多。似乎计算每一代的计算成本似乎随着每一代而增加。这让我感到惊讶,因为我虽然在这个替代算法中处理的数据更少。我不确定它是否有趣,但这是第一个版本:

var g = 0;
var cellMatrix = new Array();
var height = 68;  
var width = 100;

declareThisGeneration();

function live() {

    g++;

    processGeneration();
    setTimeout(live, speed);

}

function processGeneration() {

    if (oscillation) adjustGForOscillation();
    if (g > 0) {
        processNormalGeneration();
    } else {
        processFirstGeneration();
    }
}

function processFirstGeneration() {

    for (var x = 0; x < width; x++) {                
        for (var y = 0; y < height; y++) {
            processFirstGenCell(g, x, y);
        }
    }
}

function processFirstGenCell(g, x, y) {

    if (cellMatrix[g][x][y]) { //if alive
        spawnCell(g, x, y);
    } else { //if dead
        killCell(g, x, y);
    }
}


function processNormalGeneration() {

    for (var x = 0; x < width; x++) {                
        for (var y = 0; y < height; y++) {
            processCell(g, x, y);
        }
    } 
}

function processCell(g, x, y) {

    var livingNeighbors = getLivingNeighbors(g - 1, x, y);

    if (cellMatrix[g - 1][x][y]) { //if alive
        if (livingNeighbors != 2 && livingNeighbors != 3) {
            killCell(g, x, y);
        } else {
            spawnCell(g, x, y);
        }
    } else { //if dead
        if (livingNeighbors == 3) {
            spawnCell(g, x, y);
        } else {
            killCell(g, x, y);
        }
    }
}

function spawnCell(g, x, y) {
    cellMatrix[g][x][y] = true;
    document.getElementById(x + '-' + y).className = 'alive';
}

function killCell(g, x, y) {

    cellMatrix[g][x][y] = false;
    document.getElementById(x + '-' + y).className = ''
}

我的问题是,是什么让“改进的”算法如此缓慢,我怎样才能降低它的成本?

Version 1 // 第一,最快

Version 2 // 新的,更慢的

【问题讨论】:

  • 如果你只显示从第一版到第二版的变化部分会容易得多。并且可能会在小提琴中发布完整的代码。

标签: javascript algorithm performance conways-game-of-life


【解决方案1】:

您在新版本中不断为每一代分配新的数组;在旧版本中,您不断重复使用相同的网格。除了变慢(如果不是它变慢的原因的话)之外,是您的内存占用量不断增长。

【讨论】:

    【解决方案2】:

    一种可能的解释是,如果您跟踪的东西太多,计算机将需要分配更多的内存来存储它们,而这需要时间。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-09-05
      • 2012-04-15
      • 1970-01-01
      • 2022-12-26
      • 1970-01-01
      • 2021-04-05
      • 1970-01-01
      • 2020-04-21
      相关资源
      最近更新 更多