IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 数据结构与算法 -> Python访问街区所有节点最短路径问题,并结合matplotlib可视化 -> 正文阅读

[数据结构与算法]Python访问街区所有节点最短路径问题,并结合matplotlib可视化

写这篇博客 基于博友的提问,这篇博客将介绍如何全排列街区的点,即规定起点不重复的走完所有街区,并找出最短路径。

在这里插入图片描述在这里插入图片描述这个问题分拆分为三部分:

1. N个点除去起点,即N-1个点全排列;
2. 计算每一条路径,相邻节点的距离,并求和。
3. 为了更加直观,便于可视化,可以matplotlib、pyecharts绘制路线出来~

1. 效果图

规定起点A,所有路径 递归 & 非递归效果图:
在这里插入图片描述在这里插入图片描述
最短路径,及其距离效果图:
在这里插入图片描述
图中10个点的最短路径结果:
在这里插入图片描述
使用matplotlib 可视化街区点及最短路径如下图:
如上最短路径 A B D F G H I J E C 如下图,
在这里插入图片描述

使用pyecharts绘制街区点及最短路径如下图:
在这里插入图片描述

2. 源码

2.1 5个点全排列(递归+非递归算法)

非递归的方法并不好,当点数有变化的时候需要对应修改代码

# 求最短路径问题(N个点全排列)

# 街区点
node = ['A', 'B', 'C', 'D', 'E']

# 路径全排列走法
count = 0
# 非递归算法
# 非递归算法找到所有可能的路径,并计算总距离
for i in node:
    for j in node:
        for k in node:
            for m in node:
                for n in node:
                    if i != 'A':  # 起点只能是A点
                        continue
                    # 同一个点不走第二次
                    if (i == j or i == k or i == m or i == n
                        or j == k or j == m or j == n
                        or k == m or k == n
                        or m == n):
                        continue
                    count = count + 1
                    print((count), (i, j, k, m, n))

print('递归 start--------------------')
# 递归方法解决
nodes = node.copy()


# 递归算法:
# 不重复的对n个点进行全排列
# positon,从数组下标哪个点开始全排列
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个点开始全排列

2.2 python遍历全路径计算距离+matplot可视化

# 求最短路径问题(python遍历全路径计算距离+matplot可视化)
import math
import numpy as np

# 街区点
node = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', "J"]
# 街区点对应坐标
node_coor = [(310, 385), (360, 305), (550, 330), (440, 270), (550, 250),
             (360, 225), (305, 150), (305, 90), (440, 120), (550, 65)]

# 计算俩个坐标点的距离
def cal_dis(pt1, pt2):
    x0, y0 = pt1
    x1, 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)))


# 计算一条路径的总距离
def get_dis(nodes):
    # 初始化总距离
    total_dis = 0

    # 遍历路径
    for i in range(len(nodes) - 1):
        # 根据相邻的俩个点计算距离
        dis = cal_dis(node_coor[node.index(nodes[i])], node_coor[node.index(nodes[i + 1])])
        total_dis = total_dis + dis
    return total_dis


print('递归 start--------------------')
# 递归方法解决
dict_path_dis = {}
nodes = node.copy()


# 递归算法:
# 不重复的对n个点进行全排列
# positon,从数组下标哪个点开始全排列
def permutations(position):
    if position == len(nodes) - 1:
        dis = get_dis(np.array(tuple(nodes)))
        dict_path_dis[tuple(nodes)] = dis
        print(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]


# 从下标1开始全排列,表示第一个值是固定的,此处是起点
permutations(1)

print('共有路径: ', len(dict_path_dis.keys()))
# 获取最小的value对应的key,即获取最短路径距离对应的路径
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——————————')
# 构建最短路径的街区点及坐标
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 np

fig, ax = plt.subplots()  # 创建一个图表
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') # 绘制街区点

for node_name, (x, y) in zip(min_node, min_path_coor):
    # 绘制坐标点及坐标点上方文字
    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})  # 中心点上方文字
ax.plot(x1, y1)  # 绘制线

plt.show()

2.3 pyecharts可视化源码

可在该页面复制下方代码进行在线可视化:https://echarts.apache.org/examples/en/editor.html?c=graph-simple

option = {
    title: {
        text: 'Graph 简单示例'
    },
    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: '节点A',
                x: 310,
                y: 385
            }, {
                name: '节点B',
                x: 360,
                y: 305
            }, {
                name: '节点C',
                x: 550,
                y: 330
            }, {
                name: '节点D',
                x: 440,
                y: 270
            }, {
                name: '节点E',
                x: 550,
                y: 250
            }, {
                name: '节点F',
                x: 360,
                y: 225
            }, {
                name: '节点G',
                x: 305,
                y: 150
            }, {
                name: '节点H',
                x: 305,
                y: 90
            }, {
                name: '节点I',
                x: 440,
                y: 120
            }, {
                name: '节点J',
                x: 550,
                y: 65
            }],
            links: [{
                source: '节点A',
                target: '节点B'
            }, {
                source: '节点B',
                target: '节点D'
            }, {
                source: '节点D',
                target: '节点F'
            }, {
                source: '节点F',
                target: '节点G'
            }, {
                source: '节点G',
                target: '节点H'
            }, {
                source: '节点H',
                target: '节点I'
            }, {
                source: '节点I',
                target: '节点J'
            }, {
                source: '节点J',
                target: '节点E'
            }, {
                source: '节点E',
                target: '节点C'
            }],
            lineStyle: {
                opacity: 0.9,
                width: 2,
                curveness: 0
            }
        }
    ]
};

参考

  数据结构与算法 最新文章
【力扣106】 从中序与后续遍历序列构造二叉
leetcode 322 零钱兑换
哈希的应用:海量数据处理
动态规划|最短Hamilton路径
华为机试_HJ41 称砝码【中等】【menset】【
【C与数据结构】——寒假提高每日练习Day1
基础算法——堆排序
2023王道数据结构线性表--单链表课后习题部
LeetCode 之 反转链表的一部分
【题解】lintcode必刷50题<有效的括号序列
上一篇文章      下一篇文章      查看所有文章
加:2021-09-14 13:36:45  更:2021-09-14 13:37:17 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/26 3:42:50-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码