寻找遍历图中所有顶点的路径的更好算法是什么?
What is a better algorithm for finding routes that traverse all vertices in a graph?
所以我有以下问题:
给定一个x × y维的网格,计算路径的数量通过它,从一个角落开始(我们说左上角),结束于另一个(右下),并通过每个顶点。
所以我现在的方法只是通过尝试每一条可能的路径,计算到达终点并遍历每个节点的路径。当它工作时,它是O(n^2)并且变得难以置信的慢。我不确定如何组合,因为要求路径遍历每个顶点。
我查过更复杂的算法,Hierholzer的计算欧拉路径的算法似乎有点相关,但并不完美,因为节点不能被遍历多次。
事实上,我的程序可以工作,但是很糟糕,我想使它更有效。我可以使用更好的算法吗?
编辑感谢到目前为止的回答。为了澄清,2d网格中的所有节点都是通过n/e/s/w
连接的。同样,网格也不一定是正方形
你能做的不多,因为这是一个np完全的哈密顿路径问题。
然而,你可能实际上搜索其他东西,并为你试图解决的问题添加一些限制…
编辑:正如@JanDvorak所指出的,您的特定限制是您正在使用方形网格。我目前的发现:
如果x
是偶数,那么没有办法遍历从左上角开始到右下角结束的所有顶点。证明:
让我们计算沿轴方向的运动,例如向上为-1
,向下为1
,向左为-1
,向右为-1
。所以,有x × x的网格,总移动量是2*x
。在每个顶点(除了最后一个!)你只选择一个方向。所以,如果你需要经过的顶点数是偶数,那么你的总移动将是偶数,反之亦然。如果x
是偶数,那么有奇数个顶点,但总移动仍然是偶数=>你无法找到任何方法
首先,如果x是偶数,有一个简单的奇偶校验参数表明答案总是零;方格,注意左上角和右下角的方格是相同的颜色,并且该颜色不能同时访问n2,因为n2是偶数而1是奇数。
如果x是奇数,我不知道如何计算路径,但请注意,总数至少以指数速度增长:对n*n网格的任何遍历都可以提升为对(n+2)*(n+2)网格的两次不同遍历。你沿着第一行向右,沿着第二行向左,沿着第一列向下,沿着第二列向上,然后在剩下的方格上做n*n的网格遍历;您可以通过以相反的顺序覆盖前两行和列来获得另一个。
这应该告诉你,暴力解决方案不太可能工作得很好。
这学期我在一门课上遇到了这样的问题。我认为你可以看看像我们这样的元启发式算法:
- 禁忌搜索算法进化计算
除非你真的需要改进,否则你可能想要使用蛮力;因为它们非常复杂
- C++:将控制台输出存储在宏中更好吗
- FFmpeg:制作一个应用程序比直接使用ffmepg更好吗
- 初始化具有非默认构造函数的std::数组项的更好方法
- 有没有比在库中添加一个并非由所有派生类实现的新虚拟函数更好的设计实践
- 为什么新的随机库比std::rand()更好
- 寻找一种更好的方法来表示无符号字符数组
- 哪种方法更好,性能明智
- 什么更好?返回对象指针列表?或返回指向对象列表的指针?
- 什么是更好的做法?通过指针或标识符传递类成员?
- 寻求更好地理解标准::访问
- 线程消息传递或更好:在"大师班"中访问其他班级的成员
- 有没有更好的方法来处理异常? try-catch块真的很丑
- 如何更好地检查两个 char 变量是否在一组值中?
- 有没有更好的方法对C++中的三个整数进行排序?
- 什么模板用法在阶乘中更好
- 平面缓冲区可以利用向量中的 0 吗?还是其他小波比哈尔变换更好?
- 我们应该如何使用枚举类进行索引(或者我们应该更好地避免这种情况)?
- 在C++中编译时提供库路径的更好方法
- 有没有更好的方法来通过 C/C++ 中的环境变量创建路径
- 寻找遍历图中所有顶点的路径的更好算法是什么?