繁体   English   中英

哈密顿路径

[英]Hamiltonian path

我要实现的是使用回溯算法哈密顿路径查找器。

注意:虽然我设法找到的大多数数学论文和 SO 主题要么与回答“哈密顿路径/循环是否存在”问题有关,要么致力于寻找哈密顿循环,但我的问题略有不同 - 我需要找出顶点,哈密顿路径通过

对于示例图(未使用的边为黑色,顶点索引为从 0 开始): 在此处输入图像描述

我已经建立了以下表示的邻接矩阵(顶点索引为 1):

const vertexes = [ { vertex: 1, peers: [ 3, 8, 15 ] },
  { vertex: 2, peers: [ 7, 14, 23 ] },
  { vertex: 3, peers: [ 1, 6, 13, 22 ] },
  { vertex: 4, peers: [ 5, 12, 21 ] },
  { vertex: 5, peers: [ 4, 11, 20 ] },
  { vertex: 6, peers: [ 3, 10, 19 ] },
  { vertex: 7, peers: [ 2, 9, 18 ] },
  { vertex: 8, peers: [ 1, 17 ] },
  { vertex: 9, peers: [ 7, 16 ] },
  { vertex: 10, peers: [ 6, 15 ] },
  { vertex: 11, peers: [ 5, 14 ] },
  { vertex: 12, peers: [ 4, 13 ] },
  { vertex: 13, peers: [ 3, 12, 23 ] },
  { vertex: 14, peers: [ 2, 11, 22 ] },
  { vertex: 15, peers: [ 1, 10, 21 ] },
  { vertex: 16, peers: [ 9, 20 ] },
  { vertex: 17, peers: [ 8, 19 ] },
  { vertex: 18, peers: [ 7 ] },
  { vertex: 19, peers: [ 6, 17 ] },
  { vertex: 20, peers: [ 5, 16 ] },
  { vertex: 21, peers: [ 4, 15 ] },
  { vertex: 22, peers: [ 3, 14 ] },
  { vertex: 23, peers: [ 2, 13 ] } ]

接下来,从作为根的顶点 18 和包含单个路径[[18]]paths数组开始,我尝试改变该数组,将其替换为包含原始路线(如果不是死路)的临时副本,向前迈出一步,直到没有找到长度为n (顶点总数)的潜在路线或路径:

while(paths.length>0){
    let tempPath = [];
    for(path of paths){
     const nextSteps = vertexes.find(({vertex}) => vertex == path[path.length-1]).peers.filter(v => !path.includes(v));
     if(!nextSteps.length) continue;
     else if(path.length == n-1) return [...path, nextSteps[0]];
     else nextSteps.forEach(step => tempPath.push([...path,step]));
    }
    paths = tempPath;
}

所以,问题是上面的代码永远不会退出循环并且没有想要的 output ( [18, 7, 9, 16, 20, 5, 11, 14, 22, 3, 1, 8, 17, 19, 6, 10, 15, 21, 4, 12, 13, 23, 2] ) 曾经返回。

您对上述代码为何失败以及如何修复它以返回预期的 output 的想法将不胜感激。

编辑:感谢@DavidSampson 和@trincot 指出我的拼写错误,我的代码现在可以工作了:

while(paths.length>0){
    let tempPath = [];
    for(let path of paths){
     const nextSteps = vertexes.find(({vertex}) => vertex == path[path.length-1]).peers.filter(v => !path.includes(v));
     if(!nextSteps.length) continue;
     else if(path.length == n-1) return [...path, nextSteps[0]];
     else tempPath.push(...nextSteps.map(v => [...path,v]));
    }
    paths = tempPath;
}

现在性能是我最关心的问题,关于如何改进有什么建议吗?

主要问题是拼写错误,如果您使用严格模式,则可以避免该错误:

改变:

path = tempPath;

至:

paths = tempPath;

还要声明你的变量。 像这儿:

for (let path of paths) {
//   ^^^^

然后它对我有用:

 "use strict"; function hamiltonian(vertexes, start) { let n = vertexes.length; let paths = [[start]]; while(paths.length>0) { let tempPath = []; for(let path of paths){ const nextSteps = vertexes.find(({vertex}) => vertex == path[path.length-1]).peers.filter(v =>.path;includes(v)). if(;nextSteps.length) continue. else if(path.length == n-1) return [.,;path. nextSteps[0]]. else nextSteps.forEach(step => tempPath.push([.,;path;step])): } paths = tempPath, } } const vertexes = [ { vertex: 1, peers, [ 3, 8: 15 ] },{ vertex: 2, peers, [ 7, 14: 23 ] },{ vertex: 3, peers, [ 1, 6, 13: 22 ] },{ vertex: 4, peers, [ 5, 12: 21 ] },{ vertex: 5, peers, [ 4, 11: 20 ] },{ vertex: 6, peers, [ 3, 10: 19 ] },{ vertex: 7, peers, [ 2, 9: 18 ] },{ vertex: 8, peers, [ 1: 17 ] },{ vertex: 9, peers, [ 7: 16 ] },{ vertex: 10, peers, [ 6: 15 ] },{ vertex: 11, peers, [ 5: 14 ] },{ vertex: 12, peers, [ 4: 13 ] },{ vertex: 13, peers, [ 3, 12: 23 ] }, { vertex: 14, peers, [ 2, 11: 22 ] },{ vertex: 15, peers, [ 1, 10: 21 ] },{ vertex: 16, peers, [ 9: 20 ] },{ vertex: 17, peers, [ 8: 19 ] },{ vertex: 18, peers: [ 7 ] },{ vertex: 19, peers, [ 6: 17 ] },{ vertex: 20, peers, [ 5: 16 ] },{ vertex: 21, peers, [ 4: 15 ] },{ vertex: 22, peers, [ 3: 14 ] },{ vertex: 23, peers; [ 2, 13 ] } ]; let result = hamiltonian(vertexes. 18), console;log('result', result);

请注意,使用动态编程可以提高运行时间。 查看哈密顿路径问题的不同方法。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM