生命的游戏:试图用新的算法来提高计算效率,但没有成功.为什么?

Game of Life: Tried to increase computation efficiency with new algorithm, reduced in stead. Why?

本文关键字:效率 计算 为什么 成功 高计算 游戏 生命 算法      更新时间:2023-09-26

我正在为Conway的《人生游戏》编程,并制作了一个可工作、流畅的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 = ''
}

我的问题是,是什么让"改进"的算法如此缓慢,我如何降低它的成本?

版本1//第一个,最快的

版本2//新的,较慢的

您不断为新版本中的每一代分配新的数组;在旧版本中,您一直在重复使用相同的网格。除了速度变慢之外,如果不是速度变慢的原因的话,那就是你的内存占用不断增加。

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