JavaScript中的多向网络路由或寻径算法
我正试图用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.顺时针行驶,通过节点
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);