日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 人文社科 > 生活经验 >内容正文

生活经验

Python访问街区所有节点最短路径问题,并结合matplotlib可视化

發(fā)布時(shí)間:2023/11/27 生活经验 44 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Python访问街区所有节点最短路径问题,并结合matplotlib可视化 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

Python訪問(wèn)街區(qū)所有節(jié)點(diǎn)最短路徑問(wèn)題,并結(jié)合matplotlib可視化

    • 1. 效果圖
    • 2. 源碼
      • 2.1 5個(gè)點(diǎn)全排列(遞歸+非遞歸算法)
      • 2.2 python遍歷全路徑計(jì)算距離+matplot可視化
      • 2.3 pyecharts可視化源碼
    • 參考

寫這篇博客 基于博友的提問(wèn),這篇博客將介紹如何全排列街區(qū)的點(diǎn),即規(guī)定起點(diǎn)不重復(fù)的走完所有街區(qū),并找出最短路徑。

這個(gè)問(wèn)題分拆分為三部分:

1. N個(gè)點(diǎn)除去起點(diǎn),即N-1個(gè)點(diǎn)全排列;
2. 計(jì)算每一條路徑,相鄰節(jié)點(diǎn)的距離,并求和。
3. 為了更加直觀,便于可視化,可以matplotlib、pyecharts繪制路線出來(lái)~

1. 效果圖

規(guī)定起點(diǎn)A,所有路徑 遞歸 & 非遞歸效果圖:

最短路徑,及其距離效果圖:

圖中10個(gè)點(diǎn)的最短路徑結(jié)果:

使用matplotlib 可視化街區(qū)點(diǎn)及最短路徑如下圖:
如上最短路徑 A B D F G H I J E C 如下圖,

使用pyecharts繪制街區(qū)點(diǎn)及最短路徑如下圖:

2. 源碼

2.1 5個(gè)點(diǎn)全排列(遞歸+非遞歸算法)

非遞歸的方法并不好,當(dāng)點(diǎn)數(shù)有變化的時(shí)候需要對(duì)應(yīng)修改代碼

# 求最短路徑問(wèn)題(N個(gè)點(diǎn)全排列)# 街區(qū)點(diǎn)
node = ['A', 'B', 'C', 'D', 'E']# 路徑全排列走法
count = 0
# 非遞歸算法
# 非遞歸算法找到所有可能的路徑,并計(jì)算總距離
for i in node:for j in node:for k in node:for m in node:for n in node:if i != 'A':  # 起點(diǎn)只能是A點(diǎn)continue# 同一個(gè)點(diǎn)不走第二次if (i == j or i == k or i == m or i == nor j == k or j == m or j == nor k == m or k == nor m == n):continuecount = count + 1print((count), (i, j, k, m, n))print('遞歸 start--------------------')
# 遞歸方法解決
nodes = node.copy()# 遞歸算法:
# 不重復(fù)的對(duì)n個(gè)點(diǎn)進(jìn)行全排列
# positon,從數(shù)組下標(biāo)哪個(gè)點(diǎn)開(kāi)始全排列
def permutations(position):if position == len(nodes) - 1:print(nodes)else:for index in range(position, len(nodes)):nodes[index], nodes[position] = nodes[position], nodes[index]permutations(position + 1)nodes[index], nodes[position] = nodes[position], nodes[index]# permutations(0) # 全排列
permutations(1)  # 從第2個(gè)點(diǎn)開(kāi)始全排列

2.2 python遍歷全路徑計(jì)算距離+matplot可視化

# 求最短路徑問(wèn)題(python遍歷全路徑計(jì)算距離+matplot可視化)
import math
import numpy as np# 街區(qū)點(diǎn)
node = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', "J"]
# 街區(qū)點(diǎn)對(duì)應(yīng)坐標(biāo)
node_coor = [(310, 385), (360, 305), (550, 330), (440, 270), (550, 250),(360, 225), (305, 150), (305, 90), (440, 120), (550, 65)]# 計(jì)算倆個(gè)坐標(biāo)點(diǎn)的距離
def cal_dis(pt1, pt2):x0, y0 = pt1x1, y1 = pt2# print('\t\tdis: ', pt1, pt2, math.sqrt((math.pow((x0 - x1), 2) + math.pow((y0 - y1), 2))))return math.sqrt((math.pow((x0 - x1), 2) + math.pow((y0 - y1), 2)))# 計(jì)算一條路徑的總距離
def get_dis(nodes):# 初始化總距離total_dis = 0# 遍歷路徑for i in range(len(nodes) - 1):# 根據(jù)相鄰的倆個(gè)點(diǎn)計(jì)算距離dis = cal_dis(node_coor[node.index(nodes[i])], node_coor[node.index(nodes[i + 1])])total_dis = total_dis + disreturn total_disprint('遞歸 start--------------------')
# 遞歸方法解決
dict_path_dis = {}
nodes = node.copy()# 遞歸算法:
# 不重復(fù)的對(duì)n個(gè)點(diǎn)進(jìn)行全排列
# positon,從數(shù)組下標(biāo)哪個(gè)點(diǎn)開(kāi)始全排列
def permutations(position):if position == len(nodes) - 1:dis = get_dis(np.array(tuple(nodes)))dict_path_dis[tuple(nodes)] = disprint(tuple(nodes), dis)else:for index in range(position, len(nodes)):nodes[index], nodes[position] = nodes[position], nodes[index]permutations(position + 1)nodes[index], nodes[position] = nodes[position], nodes[index]# 從下標(biāo)1開(kāi)始全排列,表示第一個(gè)值是固定的,此處是起點(diǎn)
permutations(1)print('共有路徑: ', len(dict_path_dis.keys()))
# 獲取最小的value對(duì)應(yīng)的key,即獲取最短路徑距離對(duì)應(yīng)的路徑
key_min = min(dict_path_dis.keys(), key=(lambda k: dict_path_dis[k]))
print('遞歸——Minimum path & dis: ', key_min, dict_path_dis[key_min])print('繪圖start——————————')
# 構(gòu)建最短路徑的街區(qū)點(diǎn)及坐標(biāo)
min_node = np.array(key_min)
min_path_coor = []
for i in min_node:min_path_coor.append(node_coor[node.index(i)])print('min_node: ', min_node)
print('min_path_coor: ', min_path_coor)import matplotlib.pyplot as plt
import numpy as npfig, ax = plt.subplots()  # 創(chuàng)建一個(gè)圖表
x1 = [x for (x, y) in min_path_coor]
y1 = [y for (x, y) in min_path_coor]
# ax.scatter(x1, y1, marker='*', c='red') # 繪制街區(qū)點(diǎn)for node_name, (x, y) in zip(min_node, min_path_coor):# 繪制坐標(biāo)點(diǎn)及坐標(biāo)點(diǎn)上方文字plt.scatter(x, y, s=120, c='red', marker='*')plt.text(x=x, y=y + 2, s=node_name + '(' + str(x) + ',' + str(y) + ')', ha='center', va='baseline',fontdict={'color': 'black','size': 8})  # 中心點(diǎn)上方文字
ax.plot(x1, y1)  # 繪制線plt.show()

2.3 pyecharts可視化源碼

可在該頁(yè)面復(fù)制下方代碼進(jìn)行在線可視化:https://echarts.apache.org/examples/en/editor.html?c=graph-simple

option = {title: {text: 'Graph 簡(jiǎn)單示例'},tooltip: {},animationDurationUpdate: 1500,animationEasingUpdate: 'quinticInOut',series: [{type: 'graph',layout: 'none',symbolSize: 50,roam: true,label: {show: true},edgeSymbol: ['circle', 'arrow'],edgeSymbolSize: [4, 10],edgeLabel: {fontSize: 20},data: [{name: '節(jié)點(diǎn)A',x: 310,y: 385}, {name: '節(jié)點(diǎn)B',x: 360,y: 305}, {name: '節(jié)點(diǎn)C',x: 550,y: 330}, {name: '節(jié)點(diǎn)D',x: 440,y: 270}, {name: '節(jié)點(diǎn)E',x: 550,y: 250}, {name: '節(jié)點(diǎn)F',x: 360,y: 225}, {name: '節(jié)點(diǎn)G',x: 305,y: 150}, {name: '節(jié)點(diǎn)H',x: 305,y: 90}, {name: '節(jié)點(diǎn)I',x: 440,y: 120}, {name: '節(jié)點(diǎn)J',x: 550,y: 65}],links: [{source: '節(jié)點(diǎn)A',target: '節(jié)點(diǎn)B'}, {source: '節(jié)點(diǎn)B',target: '節(jié)點(diǎn)D'}, {source: '節(jié)點(diǎn)D',target: '節(jié)點(diǎn)F'}, {source: '節(jié)點(diǎn)F',target: '節(jié)點(diǎn)G'}, {source: '節(jié)點(diǎn)G',target: '節(jié)點(diǎn)H'}, {source: '節(jié)點(diǎn)H',target: '節(jié)點(diǎn)I'}, {source: '節(jié)點(diǎn)I',target: '節(jié)點(diǎn)J'}, {source: '節(jié)點(diǎn)J',target: '節(jié)點(diǎn)E'}, {source: '節(jié)點(diǎn)E',target: '節(jié)點(diǎn)C'}],lineStyle: {opacity: 0.9,width: 2,curveness: 0}}]
};

參考

  • python實(shí)現(xiàn)四個(gè)數(shù)字的全排列

總結(jié)

以上是生活随笔為你收集整理的Python访问街区所有节点最短路径问题,并结合matplotlib可视化的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。