Python访问街区10个点,并俩俩绘制一条线,得到5条线,求最短的距离和?

  • 1. 效果图
  • 2. 源码
  • 参考

上一篇博客介绍了Python访问街区所有节点最短路径问题,并结合matplotlib可视化, 这一篇博客也基于博友的提问,将介绍平面图中散落10个点,两两配对,共得5条边,计算边的长度和,如何找到长度和最小的配对方案?

依然以上一篇的10个街区点为例,理一下思路:

  1. 10个点,俩俩配对,共得到5条边,很明显这是不考虑顺序的。可以用高中学到的排列组合来计算共有:C(2,10) * C(2,8) * C(2,6) * C(2,4) * C(2,2) / A(5,5) 种组合方法
    = 10 * 9/(2 * 1) * (8 * 7/(2 * 1))*(6 * 5/(2 * 1)) * (4 * 3/(2 * 1)) * (2 * 1/(2 * 1))/ (5 * 4 * 3 * 2 * 1)
    = 45 * 28 * 15 * 6/(5 * 4 * 3 * 2 * 1)
    = 9 * 7 * 5 * 3 = 945种方法。

  2. 计算每种路径5条边距离的总和

  3. 找出距离总和最小的路径,及对应的截取点坐标。

  4. 为了方便理解,用matplotlib可视化。

1. 效果图

5条线不考虑顺序的排列组合共有945种,最短路径为 ABDFCEGHIJ,距离和为449米,效果图如下:

如下图所示,10个街区 从A~J 用红色五角星表示,最短路径边分别为AB、DF、CE、GH、IJ

2. 源码

# 求最短路径问题(N个点全排列)
import mathimport 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 = 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)))# 计算一条路径的总距离
def get_dis(nodes):# 初始化总距离total_dis = 0# 遍历路径for i in range(len(nodes) // 2):# 间隔2个点计算路径 01 23 45 67 89dis = cal_dis(node_coor[node.index(nodes[i * 2])], node_coor[node.index(nodes[i * 2 + 1])])total_dis = total_dis + disreturn total_disprint('递归 start--------------------')
# 递归方法解决
nodes = node.copy()
path_set = set()# 排列组合(先2个全排列,然后每一小组排序忽略顺序~)
# 相当于C(2,10)*C(2,8)*C(2,6)*C(2,4)*C(2,2)/A(5,5) = 10*9/(2*1)*(8*7/(2*1))*(6*5/(2*1))
# *(4*3/(2*1))*(2*1/(2*1))/ (5*4*3*2*1)
# = 45*28*15*6/(5*4*3*2*1)
# = 9*7*5*3 = 945种
def permutations(position):if position == len(nodes) - 2:# print(nodes, "".join(["".join(sorted(set(nodes[i * 2] + nodes[i * 2 + 1]))) for i in range(len(nodes) // 2)]))path_set.add("".join(["".join(sorted(set(nodes[i * 2] + nodes[i * 2 + 1]))) for i in range(len(nodes) // 2)]))else:for index in range(position, len(nodes)):nodes[index], nodes[position] = nodes[position], nodes[index]permutations(position + 2)nodes[index], nodes[position] = nodes[position], nodes[index]permutations(0)  # 全排列print(sorted(path_set))
print('共有路径:', len(path_set))dict_path_dis = {}
# 计算距离
for path in path_set:dict_path_dis[path] = get_dis(list(np.array(list(path))))# 获取最小的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 = list(np.array(list(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 pltfig, ax = plt.subplots()  # 创建一个图表
x1 = [x for (x, y) in min_path_coor]
y1 = [y for (x, y) in min_path_coor]for i, (node_name, (x, y)) in enumerate(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})  # 中心点上方文字if (i % 2 == 0):print(node_name, '->', min_node[i + 1])# print(i, i + 1, [x, min_path_coor[i + 1][0]], [y, min_path_coor[i + 1][0]])ax.plot([x, min_path_coor[i + 1][0]], [y, min_path_coor[i + 1][1]])  # 绘制线plt.show()

参考

  • https://www.cnblogs.com/xiao-apple36/p/10861830.html

Python访问街区10个点,并俩俩绘制一条线,得到5条线,求最短的距离和?相关推荐

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

    Python访问街区所有节点最短路径问题,并结合matplotlib可视化 1. 效果图 2. 源码 2.1 5个点全排列(递归+非递归算法) 2.2 python遍历全路径计算距离+matplot可 ...

  2. WSL2使用Python访问Windows 10上的MongoDB报错:pymongo.errors.ServerSelectionTimeoutError: localhost:27017: [Er

    WSL2使用Python访问Windows 10上的MongoDB报错:pymongo.errors.ServerSelectionTimeoutError: localhost:27017: [Er ...

  3. python访问memcached

    2019独角兽企业重金招聘Python工程师标准>>> python访问memcached memcached介绍 Memcached 是一个高性能的分布式内存对象缓存系统,用于动态 ...

  4. windows python 访问mtp存储空间_Python 3.7 已上架 Microsoft Store,让你 轻松使用 Python...

    在 Python 团队和开源社区的帮助下,Windows 10 的五月更新为 Microsoft Store 带来了 Python 3.7. 完成安装后,用户即可使用 Python,大大降低了在 Wi ...

  5. python 访问 zookeeper

    python 访问 zookeeper 1.安装: zookeeper python客户端依赖c客户端,所以要先安装c版本客户端 > wget -c http://apache.fayea.co ...

  6. linux python连接oracle数据库_Linux下通过python访问MySQL、Oracle、SQL Server数据库的方法...

    本文档主要描述了Linux下python数据库驱动的安装和配置,用来实现在Linux平台下通过python访问MySQL.Oracle.SQL Server数据库. 其中包括以下几个软件的安装及配置: ...

  7. python访问数据库

    1. python DB api简介 python DB api python访问数据库的统一接口规范,详细可参考https://www.python.org/dev/peps/pep-0249/ p ...

  8. Python学习笔记--10.Django框架快速入门之后台管理admin(书籍管理系统)

    Python学习笔记--10.Django框架快速入门之后台管理 一.Django框架介绍 二.创建第一个Django项目 三.应用的创建和使用 四.项目的数据库模型 ORM对象关系映射 sqlite ...

  9. Python中的10个常见安全漏洞及修复方法

    Python中的10个常见安全漏洞及修复方法 写安全的代码很困难,当你学习一门编程语言.一个模块或框架时,你会学习其使用方法.在考虑安全性时,你需要考虑如何避免代码被滥用,Python也不例外,即使在 ...

最新文章

  1. JAVA中关于JDBC与JDBC-ODBC数据源连接数据库的区别
  2. iOS 5解决Could not instantiate class named NSLayoutConstraint问题
  3. 使用ffmpeg+nginx将rtmp直播流转为hls直播流
  4. Docker 使用Dockerfile构建Docker(三)
  5. ASP.NET Core 集成测试中模拟登录用户的一种姿势
  6. vlc文件服务器局域网,vlc流媒体服务器配置
  7. 《数据结构C语言版》——线性表详解,你一定能够看得懂学得会的宝典
  8. 高中计算机网络功能,高中生自我教育中如何发挥计算机网络信息的作用
  9. Spring boot 2.0 with Oauth2 + Jwt
  10. logistic回归分析优点_干货——检验人最常用的统计学分析方法梳理(二)
  11. mysql建表语句转换成oracle,如何手动将ORACLE的sql建表语句转换为MYSQL的建表语句...
  12. 电脑休眠和睡眠的区别
  13. 听说今年金三银四变成金一银二了。。
  14. 【Linux】常用命令
  15. solr定时实时重建索引和增量更新——sxt
  16. 计算机等级考试第一次报什么,计算机等级考试一年是考两次,3月和9月各一次 如果第一次没有考过第二次考要再报名缴费吗?...
  17. Android答题计时的代码,Android答题倒计时
  18. 滑铁卢大学计算机学什么,为什么来滑铁卢大学学习数学和计算机
  19. 用qrcode生成微信支付二维码
  20. 1.14 JavaScript5:常用DOM操作

热门文章

  1. 2021年大数据ZooKeeper(六):ZooKeeper选举机制
  2. 2021年大数据Flink(六):Flink On Yarn模式
  3. DCN-cs6200 ipv6 6to4隧道
  4. Android 接口回调
  5. display:inline-block 的使用
  6. tp5.0 新增模块
  7. bitset类型, 标准库类型
  8. 编写函数求两个整数 a 和 b 之间的较大值。要求不能使用if, while, switch, for, ?: 以 及任何的比较语句。...
  9. C++ Windows进程管理
  10. Html_div圆角