Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/397.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
JavaScript中的多向网络路由或寻径算法_Javascript_Algorithm_Networking_Tree_Path Finding - Fatal编程技术网

JavaScript中的多向网络路由或寻径算法

JavaScript中的多向网络路由或寻径算法,javascript,algorithm,networking,tree,path-finding,Javascript,Algorithm,Networking,Tree,Path Finding,我正试图用JavaScript为以下由节点组成的网络编写一个路由/路径查找算法。每个节点都有规则来控制它是否可以用作入口点、出口点和/或被遍历 如果选择了有效的入口点,我需要解决以下两个问题: 网络的有效和可用出口点是什么 一旦确定并选择了有效的出口点,什么是最佳路线(需要穿越的节点) 网络规则: 只能输入具有入口点的节点,即节点A、B、C、D、e、F、G 只能退出具有退出点的节点,即节点B、C、e、F、G 行程方向由入口节点决定-这决定了您可以行驶和退出的方向。e、 g.顺时针行驶,通过节点

我正试图用JavaScript为以下由节点组成的网络编写一个路由/路径查找算法。每个节点都有规则来控制它是否可以用作入口点、出口点和/或被遍历

如果选择了有效的入口点,我需要解决以下两个问题:

  • 网络的有效和可用出口点是什么
  • 一旦确定并选择了有效的出口点,什么是最佳路线(需要穿越的节点)
  • 网络规则:

  • 只能输入具有入口点的节点,即节点A、B、C、D、e、F、G
  • 只能退出具有退出点的节点,即节点B、C、e、F、G
  • 行程方向由入口节点决定-这决定了您可以行驶和退出的方向。e、 g.顺时针行驶,通过节点A进入时退出
  • 一旦进入网络,就不能改变方向
  • 我将网络表示为一个对象数组,数组中的每个对象表示网络上的一个节点

        var network = [{
                         id: 'A',
                         canBeEntry: true,
                         ifEntryRouteIs: 'CW',
                         isExitIfRouteIs: 'N/A',
                         neighbourCW: ['B'],
                         neighbourCCW: ['H']
                        }, {
                         id: 'B',
                         canBeEntry: true,
                         ifEntryRouteIs: 'CW&CCW',
                         isExitIfRouteIs: 'CW',
                         neighbourCW: ['C'],
                         neighbourCCW: ['A']
                        },
                        .
                        .
                        .
                        {
                         id: 'H',
                         canBeEntry: false,
                         ifEntryRouteIs: 'N/A',
                         isExitIfRouteIs: 'N/A',
                         neighbourCW: ['A'],
                         neighbourCCW: ['G']
                        }];
    
    描述有效入口/出口节点、转换和权重的图表如下所示:

    我做过一些与寻路和路由相关的算法研究,比如Dijkstra的或a*搜索,但它们似乎是基于成本和权重的,我认为这不适用于我的网络

    关于如何用JavaScript编写算法,首先确定出口点,然后确定路线,有人有什么想法或方法吗

    这里是我试图在JavaScript中实现的JSFIDLE

    如果我理解正确,您希望找到给定的起始节点和方向、可能的出口以及到它们的最短路径。这应该有效:(必须稍微修改原始数据):

    var validExitPoints=[];
    var节点=[];
    var-tree_-path=[];
    push({node:entryPoint});
    已访问[入口点]=真;
    而(!nodes.length==0){
    var node=network_obj[nodes[0].node];
    nodes.shift();
    if(canExit(node.id,dir)){
    validExitPoints.push({node:node.id,路径:“”});
    }
    var neights=getneights(node.id,dir);
    
    对于(var i=0;i如果我理解正确,您希望找到给定的起始节点和方向、可能的出口以及到它们的最短路径。这应该可以:(必须稍微修改原始数据):

    var validExitPoints=[];
    var节点=[];
    var-tree_-path=[];
    push({node:entryPoint});
    已访问[入口点]=真;
    而(!nodes.length==0){
    var node=network_obj[nodes[0].node];
    nodes.shift();
    if(canExit(node.id,dir)){
    validExitPoints.push({node:node.id,路径:“”});
    }
    var neights=getneights(node.id,dir);
    
    对于(var i=0;i我发现网络的数据结构有点复杂。基本上有两个图(cw和cww)共享它们的顶点,但没有它们的边以及出口和入口点

    下面的实现定义了单独的图,并将它们连接到一个图网络中。您可以按照Juvian的建议,使用广度优先搜索为每个图创建最短路径列表。然后,您可以为所有图组合这些列表

    下面的代码只是没有GUI和FIDLE的路径搜索:

    // Return an object that contains a path for each
    // possible exit point
    function find_exits(g, id, func) {
        var visited = {};
        var list = {};
        var v = g[id];
        var q = [[id, [id]]];
    
        visited[id] = true;
        if (v.exit) list[id] = [id];
    
        while (q.length) {
            var x = q.shift();
            var path = x[1];
    
            id = x[0];                
            v = g[id];
    
            for (var i = 0; i < v.edge.length; i++) {
                var next =  v.edge[i];
                if (next in visited) continue;
    
                visited[next] = true;
                if (g[next].exit) {
                    list[next] = path.concat([next]);
                }
                q.push([next, path.concat([next])]);
            }
            path.pop();
        }
    
        return list;
    }
    
    // Combine two exit lists, choose the shorter path if there
    // is an exit in both lists
    function union(a, b) {
        var u = {};
    
        for (var x in a) u[x] = a[x];
        for (var x in b) {
            if (x in a && a[x].length < b[x].length) continue;
            u[x] = b[x];
        }
        return u;
    }
    
    var cw = {
        A: {
            entry: true,
            edge: ['B']
        },
        B: {
            entry: true,
            exit: true,
            edge: ['C']
        },
        C: {
            entry: true,
            edge: ['D']
        },
        D: {
            edge: ['E', 'F']
        },
        E: {
            exit: true
        },
        F: {
            entry: true,
            exit: true,
            edge: ['G']
        },
        G: {
            exit: true,
            edge: ['H']
        },
        H: {
            edge: ['A']
        }
    };
    
    var ccw = {
        A: {
            edge: ['H']
        },
        B: {
            entry: true,
            edge: ['A']
        },
        C: {
            exit: true,
            edge: ['B']
        },
        D: {
            entry: true,
            edge: ['C']
        },
        E: {
            entry: true,
            edge: ['D']
        },
        F: {
            entry: true,
            exit: true,
            edge: ['D']
        },
        G: {
            entry: true,
            edge: ['F']
        },
        H: {
            edge: ['G']
        }
    };
    
    // Housekeeping object for a network of several sub-graphs
    var network = {
        graphs: [cw, ccw],
        traverse: function(func) {
            for (var i = 0; i < this.graphs.length; i++) {
                func(this.graphs[i]);
            }
        }
    }
    
    // Ensure that every vertex has edge, exit, entry
    network.traverse(function(g) {
        for (var id in g) {
            var v = g[id];
    
            if (!("edge" in v)) v.edge = [];
            if (!("entry" in v)) v.entry = false;
            if (!("exit" in v)) v.exit = false;
        }
    });
    
    // Actual path-seeking
    
    var start = 'B';
    var exits = {};
    
    network.traverse(function(g) {
        if (g[start].entry) {
            exits = union(exits, find_exits(g, start));
        }
    });
    
    console.log(exits);
    
    //返回一个对象,该对象包含每个
    //可能的出口点
    函数find_退出(g,id,func){
    var={};
    var list={};
    var v=g[id];
    var q=[[id,[id]];
    已访问[id]=真;
    如果(v.exit)列表[id]=[id];
    while(q.长度){
    var x=q.shift();
    var路径=x[1];
    id=x[0];
    v=g[id];
    对于(变量i=0;i// Return an object that contains a path for each
    // possible exit point
    function find_exits(g, id, func) {
        var visited = {};
        var list = {};
        var v = g[id];
        var q = [[id, [id]]];
    
        visited[id] = true;
        if (v.exit) list[id] = [id];
    
        while (q.length) {
            var x = q.shift();
            var path = x[1];
    
            id = x[0];                
            v = g[id];
    
            for (var i = 0; i < v.edge.length; i++) {
                var next =  v.edge[i];
                if (next in visited) continue;
    
                visited[next] = true;
                if (g[next].exit) {
                    list[next] = path.concat([next]);
                }
                q.push([next, path.concat([next])]);
            }
            path.pop();
        }
    
        return list;
    }
    
    // Combine two exit lists, choose the shorter path if there
    // is an exit in both lists
    function union(a, b) {
        var u = {};
    
        for (var x in a) u[x] = a[x];
        for (var x in b) {
            if (x in a && a[x].length < b[x].length) continue;
            u[x] = b[x];
        }
        return u;
    }
    
    var cw = {
        A: {
            entry: true,
            edge: ['B']
        },
        B: {
            entry: true,
            exit: true,
            edge: ['C']
        },
        C: {
            entry: true,
            edge: ['D']
        },
        D: {
            edge: ['E', 'F']
        },
        E: {
            exit: true
        },
        F: {
            entry: true,
            exit: true,
            edge: ['G']
        },
        G: {
            exit: true,
            edge: ['H']
        },
        H: {
            edge: ['A']
        }
    };
    
    var ccw = {
        A: {
            edge: ['H']
        },
        B: {
            entry: true,
            edge: ['A']
        },
        C: {
            exit: true,
            edge: ['B']
        },
        D: {
            entry: true,
            edge: ['C']
        },
        E: {
            entry: true,
            edge: ['D']
        },
        F: {
            entry: true,
            exit: true,
            edge: ['D']
        },
        G: {
            entry: true,
            edge: ['F']
        },
        H: {
            edge: ['G']
        }
    };
    
    // Housekeeping object for a network of several sub-graphs
    var network = {
        graphs: [cw, ccw],
        traverse: function(func) {
            for (var i = 0; i < this.graphs.length; i++) {
                func(this.graphs[i]);
            }
        }
    }
    
    // Ensure that every vertex has edge, exit, entry
    network.traverse(function(g) {
        for (var id in g) {
            var v = g[id];
    
            if (!("edge" in v)) v.edge = [];
            if (!("entry" in v)) v.entry = false;
            if (!("exit" in v)) v.exit = false;
        }
    });
    
    // Actual path-seeking
    
    var start = 'B';
    var exits = {};
    
    network.traverse(function(g) {
        if (g[start].entry) {
            exits = union(exits, find_exits(g, start));
        }
    });
    
    console.log(exits);