求多点之间的最短路径算法(至少是4点)

cs02308 2008-09-10 03:50:56
哪位大虾知道通过多点之间的最短路径算法,要求是通过这些点的路径最短,不确定起点和终点,例如有四个点abcd,不一定a是起点,d是终点,还有可能是cdab这样的顺序,只要求通过这些点路径是最短的,因为abcd这个顺序的路径有可能比acbd长,依此类推,求最短的路径是哪一条。
...全文
4493 16 打赏 收藏 转发到动态 举报
写回复
用AI写文章
16 条回复
切换为时间正序
请发表友善的回复…
发表回复
yuys168 2009-08-16
  • 打赏
  • 举报
回复
lizhu821126 2009-06-07
  • 打赏
  • 举报
回复
用模拟退火解决大规模的问题,小规模的用枚举就行了
dongxuechao1989 2009-06-07
  • 打赏
  • 举报
回复 1
可不可以放源代码啊?
zhenlu_123 2009-05-01
  • 打赏
  • 举报
回复
我同样也有一个这样的问题:我想找这样几个点,到其他几个点的距离之和最短?
homesos 2008-09-12
  • 打赏
  • 举报
回复
我觉得可以用A*算法解决
dracularking 2008-09-12
  • 打赏
  • 举报
回复
[Quote=引用 9 楼 cs02308 的回复:]
引用 6 楼 KGBKGB8888 的回复:
LZ要找的应该就是传说中的A*算法吧

我刚才看了看A*算法,应该说它的效率比dijkstra算法要好,但是它也不能解决上面的问题,因为我想找的是通过多个点的最短路径。
[/Quote]
应该可用A*算法 只不过特殊情况 任意两点之间都是相邻点 但要以各个点为起点各算一遍A*,来求整体最优解
了解一下A*算法就好做了

A*算法最核心的是这个等式
F = G + H
地图上每一点都有这三个属性 且随着寻路的过程不断优化更新
F是经由此点的起点到终点的路径长度
G是当前点到起点的沿某路径的最短长度
H是当前点到终点的估计长度

因此在寻路过程中随着路径的变更要不断优化每点的G值,以最终取得一个整体最优解
cs02308 2008-09-12
  • 打赏
  • 举报
回复
[Quote=引用 7 楼 xietingyan 的回复:]
2楼不是回答了么
[/Quote]
2楼的代码不完整,min这个最小值指的是什么,当第一次遍历时min的值是多少?
cs02308 2008-09-12
  • 打赏
  • 举报
回复
[Quote=引用 6 楼 KGBKGB8888 的回复:]
LZ要找的应该就是传说中的A*算法吧
[/Quote]
我刚才看了看A*算法,应该说它的效率比dijkstra算法要好,但是它也不能解决上面的问题,因为我想找的是通过多个点的最短路径。
yanhan0615 2008-09-11
  • 打赏
  • 举报
回复
2楼的回答不对,这个问题很麻烦,我也没想明白
xietingyan 2008-09-11
  • 打赏
  • 举报
回复
2楼不是回答了么
KGBKGB8888 2008-09-11
  • 打赏
  • 举报
回复
LZ要找的应该就是传说中的A*算法吧
sanmingwushi 2008-09-11
  • 打赏
  • 举报
回复
哪位高人进来指点指点?
cs02308 2008-09-11
  • 打赏
  • 举报
回复
哪位高人进来指点指点?
cs02308 2008-09-10
  • 打赏
  • 举报
回复
谢谢楼上两位的回复,但是我想要的是通过多个点的最短路径,例如一个网络图中一共有20个节点,我想要的是,提供4个节点,找到能通过这四个点的所有路径当中的最短那一条;不是两点之间的最短路径,而是多个点,并且这多个点不必区分哪个是起点和哪个是终点,只要求我的这条结果路径上有这四个点。
Harvey_He 2008-09-10
  • 打赏
  • 举报
回复 2
最短路径问题是一个非常能联系实际的问题,下面我们以具体例题来看看这类问题的解法   例1、假设A、B、C、D、E各个城市之间旅费如下图所示。某人想从城市A出发游览各 城市一遍,而所用费用最少。试编程序输出结果。   解这类题时同学们往往不得要领,不少同学采用穷举法把所有可能的情况全部列出 ,再找出其中最短的那条路径;或是采用递归或深度搜索,找出所有路径,再找出最短 的那条。这两种方法可见都是费时非常多的解法,如果城市数目多的话则很可能要超时 了。   实际上我们知道,递归、深度搜索等算法一般用于求所有解问题(例如求A出发每个 城市走一遍一共有哪几种走法),而这几种算法对于求最短路径这类最优解问题显然是 不合适的,以下介绍的几种算法就要优越很多。   首先,对于这类图我们都应该先建立一个邻接矩阵来存放任意两点间的距离数据, 以便在程序中方便调用,如下: const dis:array[1..5,1..5] of integer =( ( 0, 7, 3,10,15),                       ( 7, 0, 5,13,12),                       ( 3, 5, 0, 5,10),                       (10,13, 5, 0,11),                       (15,12,10,11, 0));   以下是几种解法:   一、 宽度优先搜索   宽度优先搜索并不是一种很优秀的算法,只里只是简单介绍一下它的算法。   具体方法是:   1、 从A点开始依次展开得到AB、AC、AD、AE四个新结点(第二层结点),当然每个 新结点要记录下其距离;   2、 再次以AB展开得到ABC、ABD、ABE三个新结点(第三层结点),而由AC结点可展 开得到ACB、ACD、ACE三个新结点,自然AD可以展开得到ADB、ADC、ADE,AE可以展开得 到AEB、AEC、AED等新结点,对于每个结点也须记录下其距离;   3、 再把第三层结点全部展开,得到所有的第四层结点:ABCD、ABCE、ABDC、ABDE 、ABEC、ABED……AEDB、AEDC,每个结点也需记录下其距离;   4、 再把第四层结点全部展开,得到所有的第五层结点:ABCDE、ABCED、……、AE DBC、AEDCB,每个结点也需记录下其距离;   5、 到此,所有可能的结点均已展开,而第五层结点中最小的那个就是题目的解了 。   由上可见,这种算法也是把所有的可能路径都列出来再找最短的那条,显而易见这 也是一种很费时的算法。   二、 A*算法   A*算法是在宽度优先搜索算法的基础上,每次并不是把所有可展的结点展开,而是 对所有没有展开的结点,利用一个自己确定的估价函数对所有没展开的结点进行估价, 从而找出最应该被展开的结点(也就是说我们要找的答案最有可能是从该结点展开), 而把该结点展开,直到找到目标结点为止。   这种算法最关键的问题就是如何确定估价函数,估价函数越准则越快找到答案。A* 算法实现起来并不难,只不过难在找准估价函数,大家可以自已找资料看看。   三、等代价搜索法      等代价搜索法也是基于宽度优先搜索上进行了部分优化的一种算法,它与A*算法的 相似之处都是每次只展开某一个结点(不是展开所有结点),不同之处在于:它不需要 去另找专门的估价函数,而是以该结点到A点的距离作为估价值,也就是说,等代价搜索 法是A*算法的一种简化版本。它的大体思路是:   1、 从A点开始依次展开得到AB(7)、AC(3)、AD(10)、AE(15)四个新结点, 把第一层结点A标记为已展开,并且每个新结点要记录下其距离(括号中的数字);   2、 把未展开过的AB、AC、AD、AE四个结点中距离最小的一个展开,即展开AC(3) 结点,得到ACB(8)、ACD(16)、ACE(13)三个结点,并把结点AC标记为已展开;  3、 再从未展开的所有结点中找出距离最小的一个展开,即展开AB(7)结点,得到 ABC(12)、ABD(20)、ABE(19)三个结点,并把结点AB标记为已展开;   4、 再次从未展开的所有结点中找出距离最小的一个展开,即展开ACB(8)结点… …;   5、 每次展开所有未展开的结点中距离最小的那个结点,直到展开的新结点中出现目标情况(结点含有5个字母)时,即得到了结果。   由上可见,A*算法和等代价搜索法并没有象宽度优先搜索一样展开所有结点,只是 根据某一原则(或某一估价函数值)每次展开距离A点最近的那个结点(或是估价函数计算出的最可能的那个结点),反复下去即可最终得到答案。虽然中途有时也展开了一些 并不是答案的结点,但这种展开并不是大规模的,不是全部展开,因而耗时要比宽度优 先搜索小得多。   例2、题目基本同例1、但只要求求A到E点的最短路径(并不要求每个城市都要走一 遍)。   题目一改,问题的关键变了,所要求的结果并不是要求每个点都要走一遍,而是不 管走哪几个点,只要距离最短即可。再用宽度优先搜索已经没有什么意义了,那么等代 价搜索能不能再用在这题上呢?  答案是肯定的,但到底搜索到什么时候才能得到答案呢?这可是个很荆手的问题。   是不是搜索到一个结点是以E结束时就停止呢?显然不对。   那么是不是要把所有以E为结束的结点全部搜索出来呢?这简直就是宽度优先搜索了 ,显然不对。  实际上,应该是搜索到:当我们确定将要展开的某个结点(即所有未展开的结点中 距离最小的那个点)的最后一个字母是E时,这个结点就是我们所要求的答案!   那么,除了等代价搜索外,有没有其它办法了呢?下面就介绍求最短路径问题的第 四种算法:   四、Warshall算法   该算法的中心思想是:任意两点i,j间的最短距离(记为Dij)会等于从i点出发到达 j点的以任一点为中转点的所有可能的方案中,距离最短的一个。即:   Dij=min(Dij,Dik+Dkj,……),1<=k<=5。   这样,我所就找到了一个类似动态规划的表达式,只不过这里我们不把它当作动态 规划去处理,而是做一个二维数组用以存放任意两点间的最短距离,利用上述公式不断 地对数组中的数据进行处理,直到各数据不再变化为止,这时即可得到A到E的最短路径 。  算法如下:   1、 把上述邻接矩阵直接赋值给最短距离矩阵D;   2、 i=1;   3、 j=1;  4、 repeat  5、 c=false; {用以判断第6步是否有某个Dij值被修改过}   6、 Dij=min(Dij,Dik+Dkj,……), k=1 to 5 如果Dij被修改则c=true   7、 I=I+1   8、 J=j+1   9、 Until not c   10、 打印D15   这种算法是产生这样一个过程:不断地求一个数字最短距离矩阵中的数据的值,而 当所有数据都已经不能再变化时,就已经达到了目标的平衡状态,这时最短距离矩阵中 的值就是对应的两点间的最短距离。   五、动态规划  动态规划算法已经成为了许多难题的首选算法,只不过在很多的题目中动态规划的 算法表达式比较难找准,而恰恰最短距离问题如果用动态规划算法考虑则可以非常容易 地找准那个算法表达式。   我们知道,动态规划算法与递归算法的不同之处在于它们的算法表达式:   递归:类似f(n)=x1*f(n-1)+x2*f(n-2)………,即可以找到一个确定的关系的表达 式;   动态规划:类似f(n)=min(f(n-1)+x1,f(n-2)+x2……),即我们无法找到确定关系的 表达式,只能找到这样一个不确定关系的表达式,f(n)的值是动态的,随着f(n-1),f(n -2)等值的改变而确定跟谁相关。   就本题来说,我们记f(5)为A到E点的最短距离,则f(4)为A到D点的最短距离,f(1) 为A到A点的最短距离(为0)。   于是,f(5)的值应该是所有与E点相邻的点的最短距离值再加上该点到E点的直接距 离(dis矩阵中的值)所得到的值中最小的一个。 我们可以得到这样一个关系式:   f(5)=min(f(1)+dis(1,5), f(2)+dis(2,5), f(3)+dis(3,5), f(4)+dis(4,5))   以此关系式作一个递归函数即可求得A到E点的最短距离。不过,为了节省时间,我 们可以把f(1)-f(4)已经算得的结果保存起来给后面的递归直接调用,这样就能节约大量 的递归空间和时间,这对于数据量大时尤为重要。
upgrade_007 2008-09-10
  • 打赏
  • 举报
回复
写循环,两点之间一个个比距离
for( int i=0; i<n; i++ )
for( int j=i+1; j<n; j++ ){
dis=caldistance(i,j);
if(dis<min ) min=dis;
}

13,100

社区成员

发帖
与我相关
我的任务
社区描述
Java J2ME
社区管理员
  • J2ME社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧