Javascript 噩梦

时间:2021-04-01 21:21:51

标签: javascript algorithm

我是 javascript 新手,想将我的 python A* 算法转换为 js 版本,以便我可以在网站中使用它。

我试图复制它,但我遇到了一个问题:

Uncaught RangeError: Maximum call stack size exceeded  script.js:34 
    at Array.includes (<anonymous>)
    at Graph.add_edge (script.js:34)
    at Graph.add_edge (script.js:40)
    at Graph.add_edge (script.js:40)
    at Graph.add_edge (script.js:40)
    at Graph.add_edge (script.js:40)
    at Graph.add_edge (script.js:40)
    at Graph.add_edge (script.js:40)
    at Graph.add_edge (script.js:40)
    at Graph.add_edge (script.js:40)

请在此处查看我的代码 https://pastebin.com/4gTm3enA

我正在通过一个空白网站运行 JS,并带有一个按钮来调用启动函数

编辑:这是我的代码粘贴在这里而不是 Pastebin -

class Node {
    constructor(name, g, h) {
        this.name = name;
        this.g = g;
        this.h = h;
        this.f = 0;
    }

}

class Edge {
    constructor(n1, n2, w) {
        this.node_1 = n1;
        this.node_2 = n2;
        this.weight = w;
    }
}

class Graph {
    constructor(start, end) {
        this.start = start;
        this.end = end;
        this.edges = new Array();
        this.nodes = new Array(start, end);
    }
    add_node(node) {
        if (this.nodes.includes(node)) {
            console.log('This node is already in the graph');
        } else {
            this.nodes.push(node);
        }
    }
    add_edge(n1, n2, w) {
        if (!(this.nodes.includes(n1))) {
            this.add_node(n1);
        }
        if (!(this.nodes.includes(n2))) {
            this.add_node(n2);
        }
        this.add_edge(n1, n2, w);
    }
    get_edges() {
        return this.edges;
    }
    get_nodes() {
        return this.nodes;
    }
}
function start_up(){
    console.log('running');
    var sn = new Node('a', 4, 4);
    var mn = new Node('b', 2, 2);
    var en = new Node('z', 0, 0);

    var e1 = new Edge(sn, mn, 2);
    var e2 = new Edge(mn, en, 2);

    var g = new Graph(sn, en);

    g.add_edge(sn, mn);
    g.add_edge(mn, en);

    a_star(g, new Array(), new Array(), sn);
}

function a_star(graph, visited, path, current) {
    var edges = graph.get_edges();
    var nodes = graph.get_nodes();

    if (current != graph.end) {
        visited.push(current);
        path.push(current.name);

        console.log("Current Node: " + current);
        console.log('Visited Nodes: ' + visited);

        c_from_c = new Array();
        for (i = 0; i < edges.length; i++) {
            if (current.name in edges[i]){
                tmp = edges[i].replace(current.name, '');
                c_from_c.push(tmp);
            }
        }
        var available_nodes = new Array();
        for (i = 0; i < c_from_c.length; i++){
            var f = parseInt(c_from_c[i][0]);
            for (j = 0; j < nodes.length; j++){
                if (nodes[j].name == c_from_c[i][0]){
                    f += nodes[j].h;
                    nodes[j].f = f;
                    available_nodes.push(nodes[j]);
                }
            }
        }
        var f_val = new Array();
        for (j = 0; j < available_nodes.length; j++){
            f_val.push(available_nodes[j].f)
        }
        var index = available_nodes.findIndex(Math.min(f_val));

        var current = available_nodes[index];

        a_star(graph, visited, path, current);
    }
    else {
        visited.push(current);
        var shortest = new Array();
        for (i = 0; i < visited.length; i++){
            shortest.push(visited[i])
        }
        console.log(shortest);
    }
}

1 个答案:

答案 0 :(得分:1)

您的 add_edge 正在递归调用自身。这会导致程序无法忍受的无限调用堆栈,从而引发堆栈溢出错误 (not to be confused with the company Stack Overflow :)

我不知道究竟你想要什么,我也不能读懂你想在这里做什么,但绝对不要递归调用它就这样。

如果您发现自己需要它一次又一次地调用自身,那么还有更好的替代方法,例如 window.setIntervalwindow.requestAnimationFrame不会破坏堆栈。 >

否则,如果满足特定条件,则在递归回调之前添加“return”语句,或者将回调语句置于满足特定条件时将/不会执行的条件中。

相关问题