图及其应用-程序实现城市交通咨询模拟系统-Python

图及其应用-程序实现城市交通咨询模拟系统

交通路线图示例数据
假定根据城市道路抽象为如下图,起始地为V1顶点,目的地为V9顶点,对用弧上的距离和此时间段平均速度等信息如下表所示:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-xwRNilvJ-1720750382264)(https://i-blog.csdnimg.cn/direct/347497eb17884334b91cd9071b7bf489.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-EgYrkNZG-1720750382264)(https://i-blog.csdnimg.cn/direct/470de54722c9417e84ec232816a07502.png)]

图论知识:

  • 图的表示: 使用邻接表来表示图的结构,每个节点都存储了其相邻节点的信息,包括节点名称、距离和速度。
  • 最短路径算法: 使用 Dijkstra 算法来计算两个节点之间的最短路径,根据用户选择的标准(距离或时间)来计算最优路径。

编程知识:

  • 数据结构: 使用 Python 的字典(dict)来实现图的邻接表表示。
  • 算法实现: 使用 Python 的 heapq 模块来实现 Dijkstra 算法中的优先队列。
  • 图形用户界面: 使用 Tkinter 库来创建图形用户界面,包括各种控件如输入框、按钮、下拉列表等。
  • 事件处理: 通过绑定按钮的 command 属性来处理用户的输入和触发相应的功能,如添加边和查找最优路径。
  • 数据存取: 通过读取用户输入的起始节点、目标节点、距离和速度等信息来构建图的结构。
  • 结果显示: 将计算得到的最优路径信息显示在 Tkinter 的 Text 控件中。

代码

import tkinter as tk
from tkinter import ttk, messagebox
import heapq
class Graph:
    def __init__(self):
        self.nodes = {}
    def add_edge(self, from_node, to_node, distance, speed):
        if from_node not in self.nodes:
            self.nodes[from_node] = []
        if to_node not in self.nodes:
            self.nodes[to_node] = []
        self.nodes[from_node].append((to_node, distance, speed))
        self.nodes[to_node].append((from_node, distance, speed))
    def dijkstra(self, start, goal, criterion='distance'):
        queue = [(0, start, [])]
        seen = set()
        while queue:
            (cost, node, path) = heapq.heappop(queue)
            if node in seen:
                continue
            path = path + [node]
            seen.add(node)
            if node == goal:
                return (cost, path)
            for (next_node, distance, speed) in self.nodes[node]:
                if criterion == 'distance':
                    total_cost = cost + distance
                elif criterion == 'time':
                    total_cost = cost + (distance / speed)
                heapq.heappush(queue, (total_cost, next_node, path))
        return float("inf"), []
class App:
    def __init__(self, root):
        self.root = root
        self.root.title("城市交通咨询模拟系统")
        self.graph = Graph()
        self.create_widgets()
    def create_widgets(self):
        self.frame = ttk.Frame(self.root, padding="10")
        self.frame.grid(row=0, column=0, sticky=(tk.W, tk.E, tk.N, tk.S))
        ttk.Label(self.frame, text="起始地").grid(row=0, column=0, padx=5, pady=5)
        self.start_entry = ttk.Entry(self.frame)
        self.start_entry.grid(row=0, column=1, padx=5, pady=5)
        ttk.Label(self.frame, text="目的地").grid(row=1, column=0, padx=5, pady=5)
        self.end_entry = ttk.Entry(self.frame)
        self.end_entry.grid(row=1, column=1, padx=5, pady=5)
        ttk.Label(self.frame, text="长度").grid(row=2, column=0, padx=5, pady=5)
        self.distance_entry = ttk.Entry(self.frame)
        self.distance_entry.grid(row=2, column=1, padx=5, pady=5)
        ttk.Label(self.frame, text="平均速度").grid(row=3, column=0, padx=5, pady=5)
        self.speed_entry = ttk.Entry(self.frame)
        self.speed_entry.grid(row=3, column=1, padx=5, pady=5)
        self.add_btn = ttk.Button(self.frame, text="添加路线", command=self.add_edge)
        self.add_btn.grid(row=4, column=0, columnspan=2, padx=5, pady=5)
        ttk.Label(self.frame, text="选择起始地").grid(row=5, column=0, padx=5, pady=5)
        self.src_entry = ttk.Entry(self.frame)
        self.src_entry.grid(row=5, column=1, padx=5, pady=5)
        ttk.Label(self.frame, text="选择目的地").grid(row=6, column=0, padx=5, pady=5)
        self.dest_entry = ttk.Entry(self.frame)
        self.dest_entry.grid(row=6, column=1, padx=5, pady=5)
        ttk.Label(self.frame, text="决策类型").grid(row=7, column=0, padx=5, pady=5)
        self.criterion = ttk.Combobox(self.frame, values=["distance", "time"])
        self.criterion.grid(row=7, column=1, padx=5, pady=5)
        self.criterion.current(0)
        self.search_btn = ttk.Button(self.frame, text="查询最优路线", command=self.search_route)
        self.search_btn.grid(row=8, column=0, columnspan=2, padx=5, pady=5)
        self.result_text = tk.Text(self.frame, height=10, width=50)
        self.result_text.grid(row=9, column=0, columnspan=2, padx=5, pady=5)
    def add_edge(self):
        from_node = self.start_entry.get()
        to_node = self.end_entry.get()
        distance = int(self.distance_entry.get())
        speed = int(self.speed_entry.get())
        self.graph.add_edge(from_node, to_node, distance, speed)
        messagebox.showinfo("成功", f"已添加路线: {from_node} -> {to_node}, 长度: {distance}, 平均速度: {speed}")
        self.start_entry.delete(0, tk.END)
        self.end_entry.delete(0, tk.END)
        self.distance_entry.delete(0, tk.END)
        self.speed_entry.delete(0, tk.END)
    def search_route(self):
        start = self.src_entry.get()
        goal = self.dest_entry.get()
        criterion = self.criterion.get()
        cost, path = self.graph.dijkstra(start, goal, criterion)
        if criterion == 'distance':
            result = f"最短路程: {cost} 单位\n路径: {' -> '.join(path)}"
        elif criterion == 'time':
            result = f"最短时间: {cost} 小时\n路径: {' -> '.join(path)}"
        self.result_text.delete(1.0, tk.END)
        self.result_text.insert(tk.END, result)
if __name__ == "__main__":
    root = tk.Tk()
    app = App(root)
root.mainloop()

运行效果

运行界面

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-0ZDr9qK2-1720750382265)(https://i-blog.csdnimg.cn/direct/68dd96a4ab3c44d7a87c8a6e27fd61a5.png)]

依次输入数据

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-amKBIao4-1720750382266)(https://i-blog.csdnimg.cn/direct/79eb078660b84a46bde8eb7ff3fe35fc.png)]

运行结果

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-e0EgiMTr-1720750382266)(https://i-blog.csdnimg.cn/direct/00d1e3ed973740858286af5f5e0fdf7c.png)]

  • 21
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

鷇韩

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值