当前位置:   article > 正文

最短路径算法python(一)(Floyd--弗洛伊德)_python最短路径算法完整代码

python最短路径算法完整代码

目录

前言

一、Floyd算法图文解析

二、找到最短路径的算法

三、完整代码

总结


前言

这段时间会出一些数学建模题的思路和解法,因为最近准备建模,先放放爬虫晚一些些有空了再发哈(其实后面也没什么了,scrapy框架爬取其实相差无几还是老套路,然后就是js逆向,这里推荐看看这个作者的文章我也在学)


一、Floyd算法图文解析

路径图(晚点补上)--->表

列表示从某点到某点的权(理解为距离也行但是不是距离看你输入的单位是什么)

如果不能直接连接即设置为无限大python表示为float('inf') 即可 这里我用10086表示最大值

 核心算法就是:

path 初始化路径

A      上表二维表

v       v是开始的点(从点0开始 v=0,从点1开始v=1)

大致看一下就好 然后直接看下面的式子: 

对于每个顶点V,和任一顶点对的(i,j),i≠j,v≠i,v≠j

如果A[i][j] > A[i][v] + A[v][j],则将A[i][j]更新为A[i][v] + A[v][j]的值,并将path[i][j]改为v

通俗的说就是:

例如 假设从V1点开始出发,(v=1)看表点(1)到点(4)的距离为Max

而从点V1->V2->V4: Max > 5+4 

整个式子就是           A【0】【3】> A【0】【1】+A【1】【3】

所以就要对A赋值:【0】【3】 = A【0】【1】+A【1】【3】

一整个就是按照这个去对着图看很简单的思路 狗都会那种

下面就是核心算法:

  1. for i in range(len(array_data)):
  2. for j in range(len(array_data)):
  3. path_k[i][j] = -1
  4. for k in range(len(array_data)):
  5. for i in range(len(array_data)):
  6. for j in range(len(array_data)):
  7. if array_data[i][j] > array_data[i][k] + array_data[k][j]:
  8. array_data[i][j] = array_data[i][k] + array_data[k][j]
  9. path_k[i][j] = k

二、找到最短路径的算法

在上面我们会得到一个新的path(就是计算后的路径)

 计算后的path的值:

例如我想从1到6:

path【0】【5】 = 1

path【1】【6】 = 4

path【4】【6】 = 0

路径就为:0-->1-->4-->6

这里停三分钟悟一下 理一下整体思路就可以去写代码了

核心算法:

这里的mid就是中间点 再从中间点到目标点(结合红字上面的推导就很清楚的)

  1. if new_path[start][end] == 0:
  2. all+=num[start][end]
  3. print(f'{start}---->{end}')
  4. return
  5. else:
  6. mid = path[start][end]
  7. find_small(new_path,start,mid)
  8. find_small(new_path,mid,end)

运行结果

从v1 到 v6的计算的最短路径:

 

 

三、完整代码

  1. import numpy as np
  2. from pprint import pprint
  3. inf = 10086
  4. num = [[0,4,6,inf,inf,inf],
  5. [inf,0,inf,5,4,inf],
  6. [inf,inf,0,4,7,inf],
  7. [inf,inf,inf,0,5,7],
  8. [inf,inf,inf,inf,0,5],
  9. [inf,inf,inf,inf,inf,0]]
  10. # print(np.array(num) <= 7)
  11. path = np.zeros((len(num),len(num)))
  12. for i in range(len(num)):
  13. for j in range(len(num)):
  14. if num[i][j] == inf:
  15. path[i][j] = inf
  16. print('初始化路径:\n',path)
  17. # pprint(num)
  18. def floyd(array_data,path_k):
  19. for i in range(len(array_data)):
  20. for j in range(len(array_data)):
  21. if path_k[i][j] != inf:
  22. path_k[i][j] = 0
  23. for k in range(len(array_data)):
  24. for i in range(len(array_data)):
  25. for j in range(len(array_data)):
  26. if array_data[i][j] > array_data[i][k] + array_data[k][j]:
  27. array_data[i][j] = array_data[i][k] + array_data[k][j]
  28. path_k[i][j] = k
  29. # pprint(array_data)
  30. return path_k
  31. ne_path = floyd(num,path)
  32. for i in range(len(num)):
  33. for j in range(len(num)):
  34. if num[i][j] == inf:
  35. ne_path[i][j] = inf
  36. print('计算后新path:\n',np.array(ne_path,dtype=int))
  37. all = 0
  38. def find_small(new_path,start,end):
  39. global all
  40. start = int(start)
  41. end = int(end)
  42. if new_path[start][end] == 0:
  43. all+=num[start][end]
  44. print(f'{start}---->{end}')
  45. return
  46. else:
  47. mid = path[start][end]
  48. find_small(new_path,start,mid)
  49. find_small(new_path,mid,end)
  50. find_small(ne_path,0,5)

总结

最好不要用float('inf')作为最大值吧 因为后面要转int好像不太行(当然也可以写一个判断去跳过这个索引也行)

还有好像有人说c语言里面的无线大乘还是加会变成无限小,总之用一个具体的极大值比较稳

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/我家小花儿/article/detail/550145
推荐阅读
相关标签
  

闽ICP备14008679号