首页 > 编程语言 >运筹学练习Python精解——图与网络

运筹学练习Python精解——图与网络

时间:2024-06-09 16:43:39浏览次数:9  
标签:node 精解 Python mst edge v0 edges total 运筹学

练习1

北京(Pe)、东京(T)、纽约(N)、墨西哥(M)、伦敦(L)、巴黎(Pa)各城市之间的航线距离如下表所示。从北京(Pe)乘飞机到东京(T)、纽约(N)、墨西哥城(M)、伦敦(L)、巴黎(Pa)五城市做旅游,每城市恰去一次再返回北京,应如何安排旅游线,使旅程最短?

L M N Pa Pe T
L 0 56 35 21 51 60
M 56 0 21 57 78 70
N 35 21 0 36 68 68
Pa 21 57 36 0 51 61
Pe 51 78 68 51 0 13
T 60 70 68 61 13 0

解决这个问题需要使用旅行商问题(TSP)的经典算法之一。我们可以使用蛮力法来求解,因为这是一个小规模的问题,有6个城市。这种方法将考虑所有可能的路线并找到总距离最短的那个。可以使用Python编写代码来实现这个功能。

from itertools import permutations

# 城市的索引
cities = ["L", "M", "N", "Pa", "T"]

# 城市间的距离矩阵
dist_matrix = [
    [0, 56, 35, 21, 60],  # L
    [56, 0, 21, 57, 70],  # M
    [35, 21, 0, 36, 68],  # N
    [21, 57, 36, 0, 61],  # Pa
    [60, 70, 68, 61, 0],  # T
]

# 北京到其他城市的距离
beijing_distances = [51, 78, 68, 51, 13]

# 将城市名称映射到索引
city_indices = {city: i for i, city in enumerate(cities)}

# 获取所有城市的排列
city_permutations = permutations(cities)

# 定义一个函数计算一个路线的总距离
def total_distance(route):
    total_dist = beijing_distances[city_indices[route[0]]]  # 从北京到第一个城市的距离
    n = len(route)
    for i in range(n - 1):
        total_dist += dist_matrix[city_indices[route[i]]][city_indices[route[i + 1]]]
    total_dist += beijing_distances[city_indices[route[-1]]]  # 最后一个城市返回北京的距离
    return total_dist

# 变量初始化
min_distance = float('inf')
best_route = None

# 遍历所有可能的城市排列
for perm in city_permutations:
    dist = total_distance(perm)
    if dist < min_distance:
        min_distance = dist
        best_route = perm

# 输出最优路径和最短距离
print("最优路径: Pe ->", " -> ".join(best_route), "-> Pe")
print("最短距离:", min_distance)
最优路径: Pe -> Pa -> L -> N -> M -> T -> Pe
最短距离: 211

练习2

原图 网络图 最小树
import heapq
import networkx as nx
import matplotlib.pyplot as plt

# 定义图的邻接矩阵
graph = {
    'v0': {'v1': 2, 'v2': 1, 'v3': 3, 'v4': 4, 'v5': 4, 'v6': 2, 'v7': 5, 'v8': 4},
    'v1': {'v0': 2, 'v2': 4, 'v8': 1},
    'v2': {'v0': 1, 'v1': 4, 'v3': 1},
    'v3': {'v0': 3, 'v2': 1, 'v4': 1},
    'v4': {'v0': 4, 'v3': 1, 'v5': 5},
    'v5': {'v0': 4, 'v4': 5, 'v6': 2},
    'v6': {'v0': 2, 'v5': 2, 'v7': 3},
    'v7': {'v0': 5, 'v6': 3, 'v8': 5},
    'v8': {'v0': 4, 'v1': 1, 'v7': 5}
}

# 使用Prim算法计算最小生成树
def prim(graph, start):
    min_heap = [(0, start, None)]
    mst_edges = []
    total_cost = 0
    visited = set()

    while min_heap:
        cost, node, parent = heapq.heappop(min_heap)

        if node in visited:
            continue

        visited.add(node)
        if parent is not None:
            mst_edges.append((parent, node, cost))
            total_cost += cost

        for neighbor, weight in graph[node].items():
            if neighbor not in visited:
                heapq.heappush(min_heap, (weight, neighbor, node))

    return mst_edges, total_cost

# 计算最小生成树
mst_edges, total_cost = prim(graph, 'v0')

# 打印最小生成树的边和总权重
print("最小生成树的边:")
for edge in mst_edges:
    print(edge)
print("最小生成树的总权重:", total_cost)

# 创建NetworkX图
G = nx.Graph()

# 添加节点和边
for node, edges in graph.items():
    for neighbor, weight in edges.items():
        G.add_edge(node, neighbor, weight=weight)

# 使用相同的布局绘制原图和最小生成树图
pos = nx.spring_layout(G)

plt.figure(figsize=(8, 8))

# 绘制原图
nx.draw(G, pos, with_labels=True, node_color='lightblue', node_size=1000, font_size=20)  # 放大节点和字体
labels = nx.get_edge_attributes(G, 'weight')
nx.draw_networkx_edge_labels(G, pos, edge_labels=labels, font_size=20)  # 放大权重标签

# 绘制最小生成树的边
mst_edges_set = set((u, v) for u, v, _ in mst_edges)
mst_labels = {edge: G.edges[edge]['weight'] for edge in mst_edges_set}
nx.draw_networkx_edges(G, pos, edgelist=mst_edges_set, edge_color='blue', width=4)  # 放大最小生成树的边
nx.draw_networkx_edge_labels(G, pos, edge_labels=mst_labels, font_color='blue', font_size=20)  # 放大最小生成树的权重标签

plt.title('Graph with Minimum Spanning Tree', fontsize=20)  # 放大标题字体
plt.show()

标签:node,精解,Python,mst,edge,v0,edges,total,运筹学
From: https://www.cnblogs.com/haohai9309/p/18239388

相关文章

  • 通过 Python 进行 ArcGIS 环境设置
    在ArcGIS中,环境设置可用于确保在控制环境下执行地理处理,您可以在控制环境中决定将处理限制到特定地理区域的处理范围、所有输出地理数据集的坐标系或输出栅格数据集的像元大小等。本文将以核密度分析为例,介绍通过Python进行ArcGISPro环境设置的方法。1导入相关模块impor......
  • 一个python 程序执行顺序
    1.Python程序执行顺序在Python中,程序的执行顺序通常遵循几个基本原则:(1)从上到下:Python代码通常从上到下顺序执行。(2)代码块:由缩进(如空格或制表符)定义的代码块(如函数定义、类定义、循环体、条件语句体等)内的代码会按照特定的逻辑顺序执行。(3)控制流语句:如if、for、while等控制流......
  • 一篇文章让你让你对python函数的掌握由基础到高级
    python中函数由低级到高级一函数基础1.1函数简介functioninputprint内置函数——》可以直接使用可复用性非常差函数就是存代码的总结函数的优点:1.遇到重复功能的时候,直接调用即可,减少代码量2.提升代码的结构性,分工明确,提高代码的可读性3.遇到扩展功能的时候,修......
  • 《Python程序设计(第二版)》第五章冷门点
    python小白考前复习集合关系运算去掉列表中重复元素,按原列表顺序输出无重复元素的列表集合的存储原理元素必须可哈希查找速度特别快字典函数存储原理字典可以作为if多路分支的替代写法计数作用多项式相加嵌套结构集合一般什么时候用集合呢?就是想要维护一大堆不重......
  • 一个python 程序执行顺序
    1.Python程序执行顺序在Python中,程序的执行顺序通常遵循几个基本原则:(1)从上到下:Python代码通常从上到下顺序执行。(2)代码块:由缩进(如空格或制表符)定义的代码块(如函数定义、类定义、循环体、条件语句体等)内的代码会按照特定的逻辑顺序执行。(3)控制流语句:如if、for、while等控制......
  • python-数据分析-Numpy-3、数组的运算
    数组的运算使用NumPy最为方便的是当需要对数组元素进行运算时,不用编写循环代码遍历每个元素,所有的运算都会自动的矢量化。简单的说就是,NumPy中的数学运算和数学函数会自动作用于数组中的每个成员。#-*-coding:utf-8-*-#数组的运算#使用NumPy最为方便的是当需要对数组......
  • python后端结合uniapp与uview组件tabs,实现自定义导航按钮与小标签颜色控制
    实现效果(红框内):后端api如下:@task_api.route('/user/task/states_list',methods=['POST','GET'])@visitor_token_requireddeftask_states(user):name_list=['待接单','设计中','交付中','已完成','......
  • Python: 2d arry
     score=[[58,80,74,90,45,82],[71,70,64,85,50,86],[87,63,65,84,62,83],[91,66,67,92,65,90],[83,74,81,82,57,82]]k=0whilek<5:subavg=0a=0whilea<6:subavg......
  • 《手把手教你》系列练习篇之15-python+ selenium自动化测试 -番外篇 - 最后一波啊!!!(详细
    1.简介 本来上一篇就是练习篇的最后一篇文章了,但是有的小伙伴私下反映说是做了那么多练习,没有一个比较综合的demo练练手。因此宏哥在这里又补存了一些常见的知识点进行练习,在文章最后也通过实例给小伙伴们或者童鞋们进行了一个登录模块的自动化测试的实例,其他的你可以照......
  • 《手把手教你》系列练习篇之14-python+ selenium自动化测试 -压台篇(详细教程)
    1.简介 本文是练习篇的最后一篇文章,虽然练习篇的文章到此就要和大家说拜拜了,但是我们的学习之路才刚刚开始。不要停下你的脚步,大步朝前走吧!比你优秀的人还在走着,我们有什么理由停下自己的脚步了,生命不止,学习亦是如此。好了,宏哥的毒鸡汤好喝吧,喝够了就开始学习吧。......