import sys
import math
import warnings
from PyQt5.QtWidgets import (QApplication, QMainWindow, QWidget, QVBoxLayout, QHBoxLayout,
QGridLayout, QPushButton, QLabel, QLineEdit, QTextEdit,
QSpinBox, QMessageBox, QFileDialog, QGroupBox, QRadioButton,
QButtonGroup, QInputDialog)
from PyQt5.QtGui import (QPainter, QPen, QBrush, QColor, QFont, QPixmap)
from PyQt5.QtCore import (Qt, QPointF, QSize)
# 过滤掉sipPyTypeDict弃用警告
warnings.filterwarnings("ignore", category=DeprecationWarning)
class Node:
"""节点类,表示交通网络中的交叉点或关键点"""
def __init__(self, id, x, y, name=""):
self.id = id # 节点ID
self.x = x # 节点x坐标
self.y = y # 节点y坐标
self.name = name # 节点名称
self.connections = [] # 连接的节点ID列表
def __repr__(self):
return f"Node(id={self.id}, name={self.name}, x={self.x}, y={self.y})"
class Edge:
"""边类,表示交通网络中的道路"""
def __init__(self, start_node, end_node, weight=1):
self.start_node = start_node # 起始节点ID
self.end_node = end_node # 结束节点ID
self.weight = weight # 边的权重(距离)
def __repr__(self):
return f"Edge({self.start_node}->{self.end_node}, weight={self.weight})"
class TrafficNetwork:
"""交通网络类,管理节点和边"""
def __init__(self):
self.nodes = {} # 节点字典,key: node_id, value: Node对象
self.edges = {} # 边字典,key: (start_node, end_node), value: Edge对象
self.next_node_id = 0
def add_node(self, x, y, name=""):
"""添加节点"""
try:
node_id = self.next_node_id
self.next_node_id += 1
node = Node(node_id, x, y, name)
self.nodes[node_id] = node
return node_id
except Exception as e:
print(f"添加节点失败: {e}")
return None
def remove_node(self, node_id):
"""删除节点及其相关相关的边"""
try:
if node_id not in self.nodes:
return False
# 删除与该节点相关的所有边
edges_to_remove = []
for (start, end), edge in self.edges.items():
if start == node_id or end == node_id:
edges_to_remove.append((start, end))
for edge_key in edges_to_remove:
del self.edges[edge_key]
# 删除节点
del self.nodes[node_id]
return True
except Exception as e:
print(f"删除节点失败: {e}")
return False
def add_edge(self, start_node, end_node, weight=1):
"""添加边"""
try:
if start_node not in self.nodes or end_node not in self.nodes:
return False
# 检查边是否是否已存在
if (start_node, end_node) in self.edges or (end_node, start_node) in self.edges:
return False
edge = Edge(start_node, end_node, weight)
self.edges[(start_node, end_node)] = edge
# 更新节点的连接信息
self.nodes[start_node].connections.append(end_node)
self.nodes[end_node].connections.append(start_node)
return True
except Exception as e:
print(f"添加边失败: {e}")
return False
def remove_edge(self, start_node, end_node):
"""删除边"""
try:
edge_key = (start_node, end_node)
if edge_key not in self.edges:
# 尝试相反方向
edge_key = (end_node, start_node)
if edge_key not in self.edges:
return False
del self.edges[edge_key]
# 更新节点的连接信息
if end_node in self.nodes[start_node].connections:
self.nodes[start_node].connections.remove(end_node)
if start_node in self.nodes[end_node].connections:
self.nodes[end_node].connections.remove(start_node)
return True
except Exception as e:
print(f"删除边失败: {e}")
return False
def get_adjacency_matrix(self):
"""获取邻接矩阵"""
try:
if not self.nodes:
return []
size = len(self.nodes)
matrix = [[0] * size for _ in range(size)]
for (start, end), edge in self.edges.items():
matrix[start][end] = edge.weight
matrix[end][start] = edge.weight # 假设是无向图
return matrix
except Exception as e:
print(f"获取邻接矩阵失败: {e}")
return []
def get_node_positions(self):
"""获取节点位置字典"""
try:
positions = {}
for node_id, node in self.nodes.items():
positions[node_id] = (node.x, node.y)
return positions
except Exception as e:
print(f"获取节点位置失败: {e}")
return {}
def clear(self):
"""清空网络"""
try:
self.nodes.clear()
self.edges.clear()
self.next_node_id = 0
except Exception as e:
print(f"清空网络失败: {e}")
class NetworkEditor(QWidget):
"""网络编辑组件,用于创建和编辑交通网络"""
def __init__(self, parent=None):
super().__init__(parent)
self.network = TrafficNetwork()
self.setMinimumSize(600, 400)
# 编辑状态
self.edit_mode = "add_node" # add_node, add_edge, remove_node, remove_edge, select_start, select_end
self.selected_node = None
self.edge_start_node = None
# 起点点和终点
self.start_node = None
self.end_node = None
# 最短路径
self.shortest_path = []
# 示例网络
self.create_example_network()
def create_example_network(self):
"""创建示例示例示例网络"""
try:
# 添加节点
node1 = self.network.add_node(100, 100, "A点")
node2 = self.network.add_node(250, 100, "B点")
node3 = self.network.add_node(400, 100, "C点")
node4 = self.network.add_node(100, 250, "D点")
node5 = self.network.add_node(250, 250, "E点")
node6 = self.network.add_node(400, 250, "F点")
# 添加边
self.network.add_edge(node1, node2, 2)
self.network.add_edge(node2, node3, 3)
self.network.add_edge(node1, node4, 4)
self.network.add_edge(node2, node5, 1)
self.network.add_edge(node3, node6, 2)
self.network.add_edge(node4, node5, 3)
self.network.add_edge(node5, node6, 1)
self.network.add_edge(node1, node5, 5)
except Exception as e:
print(f"创建示例网络失败: {e}")
def set_edit_mode(self, mode):
"""设置编辑模式"""
try:
self.edit_mode = mode
self.selected_node = None
self.edge_start_node = None
self.update()
except Exception as e:
print(f"设置编辑模式失败: {e}")
def set_start_node(self, node_id):
"""设置起点"""
try:
self.start_node = node_id
self.update()
except Exception as e:
print(f"设置起点失败: {e}")
def set_end_node(self, node_id):
"""设置终点"""
try:
self.end_node = node_id
self.update()
except Exception as e:
print(f"设置终点失败: {e}")
def set_shortest_path(self, path):
"""设置最短路径"""
try:
self.shortest_path = path
self.update()
except Exception as e:
print(f"设置最短路径失败: {e}")
def mousePressEvent(self, event):
"""鼠标按下事件"""
try:
pos = event.pos()
if self.edit_mode == "add_node":
# 添加节点
node_id = self.network.add_node(pos.x(), pos.y())
self.update()
elif self.edit_mode == "add_edge":
# 添加边
node_id = self.get_node_at_pos(pos)
if node_id is not None:
if self.edge_start_node is None:
self.edge_start_node = node_id
else:
if self.edge_start_node != node_id:
# 弹出对话框设置对话框设置边权重
weight, ok = QInputDialog.getInt(self, "设置边权重",
f"请输入从节点{self.edge_start_node}到节点{node_id}的距离:",
1, 1, 100)
if ok:
self.network.add_edge(self.edge_start_node, node_id, weight)
self.update()
self.edge_start_node = None
elif self.edit_mode == "remove_node":
# 删除节点
node_id = self.get_node_at_pos(pos)
if node_id is not None:
self.network.remove_node(node_id)
self.update()
elif self.edit_mode == "remove_edge":
# 删除边
node_id = self.get_node_at_pos(pos)
if node_id is not None:
if self.selected_node is None:
self.selected_node = node_id
else:
if self.selected_node != node_id:
self.network.remove_edge(self.selected_node, node_id)
self.update()
self.selected_node = None
elif self.edit_mode == "select_start":
# 选择起点 - 修复:只调用父窗口的set_start_node方法
node_id = self.get_node_at_pos(pos)
if node_id is not None:
# 通知父窗口更新UI
if hasattr(self.parent(), 'set_start_node'):
self.parent().set_start_node(node_id)
# 显示成功消息
QMessageBox.information(self, "选择成功", f"已选择节点 {node_id} 作为起点")
else:
QMessageBox.warning(self, "选择失败", "未找到节点,请点击节点中心")
elif self.edit_mode == "select_end":
# 选择终点 - 修复:只调用父窗口的set_end_node方法
node_id = self.get_node_at_pos(pos)
if node_id is not None:
# 通知父窗口更新UI
if hasattr(self.parent(), 'set_end_node'):
self.parent().set_end_node(node_id)
# 更新network_editor的终点
self.set_end_node(node_id)
# 显示成功消息
QMessageBox.information(self, "选择成功", f"已选择节点 {node_id} 作为终点")
else:
QMessageBox.warning(self, "选择失败", "未找到节点,请点击节点中心")
except Exception as e:
error_msg = f"鼠标事件处理失败: {str(e)}"
print(error_msg)
QMessageBox.critical(self, "错误", error_msg)
def get_node_at_pos(self, pos, radius=15):
"""根据位置获取节点ID"""
try:
for node_id, node in self.network.nodes.items():
distance = math.hypot(node.x - pos.x(), node.y - pos.y())
if distance <= radius:
return node_id
return None
except Exception as e:
print(f"获取节点位置失败: {e}")
return None
def paintEvent(self, event):
"""绘制网络"""
try:
painter = QPainter(self)
painter.setRenderHint(QPainter.Antialiasing)
# 绘制边
for (start, end), edge in self.network.edges.items():
start_node = self.network.nodes[start]
end_node = self.network.nodes[end]
# 检查是否是最短路径的一部分
is_path_edge = False
for i in range(len(self.shortest_path) - 1):
if (self.shortest_path[i] == start and self.shortest_path[i+1] == end) or \
(self.shortest_path[i] == end and self.shortest_path[i+1] == start):
is_path_edge = True
break
if is_path_edge:
painter.setPen(QPen(QColor(255, 0, 0), 3)) # 红色粗线表示最短路径
else:
painter.setPen(QPen(QColor(100, 100, 100), 2)) # 灰色线表示普通边
painter.drawLine(start_node.x, start_node.y, end_node.x, end_node.y)
# 绘制权重 - 使用QPointF避免类型错误
mid_x = (start_node.x + end_node.x) / 2
mid_y = (start_node.y + end_node.y) / 2
painter.setPen(QPen(QColor(0, 0, 0), 1))
painter.drawText(QPointF(mid_x, mid_y - 5), str(edge.weight))
# 绘制节点
for node_id, node in self.network.nodes.items():
# 检查是否是选中的起点或终点
is_start = self.start_node == node_id
is_end = self.end_node == node_id
# 设置节点颜色
if is_start:
painter.setBrush(QBrush(QColor(0, 255, 0), Qt.SolidPattern)) # 绿色表示起点
elif is_end:
painter.setBrush(QBrush(QColor(255, 0, 0), Qt.SolidPattern)) # 红色表示终点
else:
painter.setBrush(QBrush(QColor(0, 0, 255), Qt.SolidPattern)) # 蓝色表示普通节点
painter.setPen(QPen(QColor(0, 0, 0), 2))
painter.drawEllipse(QPointF(node.x, node.y), 15, 15)
# 绘制节点ID - 使用整数坐标避免类型错误
painter.setPen(QPen(QColor(255, 255, 255), 1))
painter.drawText(int(node.x) - 5, int(node.y) + 5, str(node_id))
except Exception as e:
print(f"绘制网络失败: {e}")
class PathFinder:
"""路径查找类,实现Dijkstra算法"""
@staticmethod
def dijkstra(adj_matrix, start, end):
"""
Dijkstra算法查找最短路径
参数:
adj_matrix: 邻接矩阵
start: 起点索引
end: 终点索引
返回:
(最短路径长度, 路径节点列表)
"""
try:
if not adj_matrix or len(adj_matrix) == 0:
return float('inf'), []
n = len(adj_matrix)
# 检查起点点和终点是否有效
if start < 0 or start >= n or end < 0 or end >= n:
return float('inf'), []
# 初始化距离数组
dist = [float('inf')] * n
dist[start] = 0
# 初始化前驱节点数组
prev = [-1] * n
# 初始化访问数组
visited = [False] * n
for _ in range(n):
# 找到距离最小的未访问节点
min_dist = float('inf')
u = -1
for i in range(n):
if not visited[i] and dist[i] < min_dist:
min_dist = dist[i]
u = i
if u == -1:
break # 所有可达节点已处理
if u == end:
break # 已到达终点
visited[u] = True
# 更新相邻节点的距离
for v in range(n):
if adj_matrix[u][v] > 0 and not visited[v]:
new_dist = dist[u] + adj_matrix[u][v]
if new_dist < dist[v]:
dist[v] = new_dist
prev[v] = u
# 重建路径
path = []
if dist[end] != float('inf'):
current = end
while current != -1:
path.insert(0, current)
current = prev[current]
return dist[end], path
except Exception as e:
print(f"Dijkstra算法执行失败: {e}")
return float('inf'), []
class MainWindow(QMainWindow):
"""主窗口类"""
def __init__(self):
try:
super().__init__()
self.setWindowTitle("交通最优最优路径搜索模型 - 警务务应用")
self.setGeometry(100, 100, 1000, 600)
# 初始化变量
self.start_node = None
self.end_node = None
self.shortest_path = []
self.shortest_distance = 0
# 创建主控件
self.central_widget = QWidget()
self.setCentralWidget(self.central_widget)
# 创建布局
self.main_layout = QHBoxLayout(self.central_widget)
# 创建 network editor
self.network_editor = NetworkEditor(self)
self.main_layout.addWidget(self.network_editor, 2)
# 创建控制面板
self.control_panel = QWidget()
self.control_layout = QVBoxLayout(self.control_panel)
self.main_layout.addWidget(self.control_panel, 1)
# 创建编辑模式选择
self.edit_mode_group = QGroupBox("编辑模式")
self.edit_mode_layout = QVBoxLayout(self.edit_mode_group)
self.mode_add_node = QRadioButton("添加节点")
self.mode_add_edge = QRadioButton("添加边")
self.mode_remove_node = QRadioButton("删除节点")
self.mode_remove_edge = QRadioButton("删除边")
self.mode_group = QButtonGroup()
self.mode_group.addButton(self.mode_add_node)
self.mode_group.addButton(self.mode_add_edge)
self.mode_group.addButton(self.mode_remove_node)
self.mode_group.addButton(self.mode_remove_edge)
self.mode_add_node.setChecked(True)
self.edit_mode_layout.addWidget(self.mode_add_node)
self.edit_mode_layout.addWidget(self.mode_add_edge)
self.edit_mode_layout.addWidget(self.mode_remove_node)
self.edit_mode_layout.addWidget(self.mode_remove_edge)
self.control_layout.addWidget(self.edit_mode_group)
# 创建起点终点选择
self.node_selection_group = QGroupBox("路径设置")
self.node_selection_layout = QVBoxLayout(self.node_selection_group)
self.btn_select_start = QPushButton("选择起点")
self.btn_select_end = QPushButton("选择终点")
self.lbl_start_node = QLabel("起点: 未选择")
self.lbl_end_node = QLabel("终点: 未选择")
self.node_selection_layout.addWidget(self.btn_select_start)
self.node_selection_layout.addWidget(self.lbl_start_node)
self.node_selection_layout.addWidget(self.btn_select_end)
self.node_selection_layout.addWidget(self.lbl_end_node)
self.control_layout.addWidget(self.node_selection_group)
# 创建算法控制
self.algorithm_group = QGroupBox("算法控制")
self.algorithm_layout = QVBoxLayout(self.algorithm_group)
self.btn_find_path = QPushButton("查找最短最短路径")
self.btn_clear_path = QPushButton("清除路径")
self.btn_reset_network = QPushButton("重置网络")
self.btn_test_path = QPushButton("测试路径查询") # 新增测试按钮
self.algorithm_layout.addWidget(self.btn_find_path)
self.algorithm_layout.addWidget(self.btn_clear_path)
self.algorithm_layout.addWidget(self.btn_reset_network)
self.algorithm_layout.addWidget(self.btn_test_path)
self.control_layout.addWidget(self.algorithm_group)
# 创建结果展示
self.result_group = QGroupBox("结果展示")
self.result_layout = QVBoxLayout(self.result_group)
self.lbl_distance = QLabel("最短距离: -")
self.lbl_path = QLabel("最短路径: -")
self.result_text = QTextEdit()
self.result_text.setReadOnly(True)
self.result_layout.addWidget(self.lbl_distance)
self.result_layout.addWidget(self.lbl_path)
self.result_layout.addWidget(self.result_text)
self.control_layout.addWidget(self.result_group)
# 创建学号姓名显示
self.student_info = QGroupBox("学生信息")
self.student_layout = QVBoxLayout(self.student_info)
# 更新为固定的学号和姓名显示
self.lbl_student_id = QLabel("学号: 202221220018")
self.lbl_student_name = QLabel("姓名: 华烁涵")
# 设置字体样式
font = QFont()
font.setBold(True)
font.setPointSize(12)
self.lbl_student_id.setFont(font)
self.lbl_student_name.setFont(font)
self.student_layout.addWidget(self.lbl_student_id)
self.student_layout.addWidget(self.lbl_student_name)
self.control_layout.addWidget(self.student_info)
# 添加拉伸项
self.control_layout.addStretch()
# 连接信号槽
self.mode_group.buttonClicked.connect(self.on_mode_changed)
self.btn_select_start.clicked.connect(self.on_select_start)
self.btn_select_end.clicked.connect(self.on_select_end)
self.btn_find_path.clicked.connect(self.on_find_path)
self.btn_clear_path.clicked.connect(self.on_clear_path)
self.btn_reset_network.clicked.connect(self.on_reset_network)
self.btn_test_path.clicked.connect(self.on_test_path) # 连接测试按钮
# 初始化
self.on_mode_changed(self.mode_add_node)
# 显示初始信息
self.show_initial_info()
except Exception as e:
print(f"创建MainWindow失败: {e}")
import traceback
traceback.print_exc()
raise
def show_initial_info(self):
"""显示初始信息"""
info = "欢迎使用交通最优路径搜索模型\n\n"
info += "使用步骤:\n"
info += "1. 点击'选择起点'按钮,然后点击网络图上的节点\n"
info += "2. 点击'选择终点'按钮,然后点击网络图上的另一个节点\n"
info += "3. 点击'查找最短路径'按钮获取结果\n\n"
info += "示例网络信息:\n"
info += "节点: 0(A), 1(B), 2(C), 3(D), 4(E), 5(F)\n"
info += "边:\n"
info += " 0 -> 1: 2\n"
info += " 1 -> 2: 3\n"
info += " 0 -> 3: 4\n"
info += " 1 -> 4: 1\n"
info += " 2 -> 5: 2\n"
info += " 3 -> 4: 3\n"
info += " 4 -> 5: 1\n"
info += " 0 -> 4: 5\n\n"
info += "点击'测试路径查询'按钮可以运行自动测试"
self.result_text.setText(info)
def on_mode_changed(self, button):
"""模式改变事件"""
try:
if button == self.mode_add_node:
self.network_editor.set_edit_mode("add_node")
elif button == self.mode_add_edge:
self.network_editor.set_edit_mode("add_edge")
elif button == self.mode_remove_node:
self.network_editor.set_edit_mode("remove_node")
elif button == self.mode_remove_edge:
self.network_editor.set_edit_mode("remove_edge")
except Exception as e:
QMessageBox.critical(self, "错误", f"模式改变失败: {str(e)}")
def on_select_start(self):
"""选择起点"""
try:
self.network_editor.set_edit_mode("select_start")
QMessageBox.information(self, "选择起点", "请在网络图上点击选择起点节点")
except Exception as e:
QMessageBox.critical(self, "错误", f"选择起点失败: {str(e)}")
def on_select_end(self):
"""选择终点"""
try:
self.network_editor.set_edit_mode("select_end")
QMessageBox.information(self, "选择终点", "请在网络图上点击选择终点节点")
except Exception as e:
QMessageBox.critical(self, "错误", f"选择终点失败: {str(e)}")
def set_start_node(self, node_id):
"""设置起点"""
try:
self.start_node = node_id
self.lbl_start_node.setText(f"起点: {node_id}")
# 通知network_editor更新起点
if hasattr(self.network_editor, 'set_start_node'):
self.network_editor.set_start_node(node_id)
# 切换回默认编辑模式
self.network_editor.set_edit_mode("add_node")
self.mode_add_node.setChecked(True)
# 添加调试信息
print(f"起点已设置为: {node_id}")
print(f"self.start_node = {self.start_node}")
except Exception as e:
print(f"设置起点失败: {e}")
def set_end_node(self, node_id):
"""设置终点"""
try:
self.end_node = node_id
self.lbl_end_node.setText(f"终点: {node_id}")
# 通知network_editor更新终点
if hasattr(self.network_editor, 'set_end_node'):
self.network_editor.set_end_node(node_id)
# 切换回默认编辑模式
self.network_editor.set_edit_mode("add_node")
self.mode_add_node.setChecked(True)
# 添加调试信息
print(f"终点已设置为: {node_id}")
print(f"self.end_node = {self.end_node}")
except Exception as e:
print(f"设置终点失败: {e}")
def on_find_path(self):
"""查找最短最短路径"""
try:
# 详细的调试信息
debug_info = f"查找路径调试信息:\n"
debug_info += f"start_node: {self.start_node} (类型: {type(self.start_node)})\n"
debug_info += f"end_node: {self.end_node} (类型: {type(self.end_node)})\n"
debug_info += f"网络节点: {list(self.network_editor.network.nodes.keys())}\n"
debug_info += f"网络边数: {len(self.network_editor.network.edges)}\n"
# 检查起点和终点是否已选择
if self.start_node is None or self.end_node is None:
debug_info += "错误: 起点或终点未选择\n"
self.result_text.setText(debug_info)
QMessageBox.warning(self, "错误", "请先选择起点和终点")
return
# 检查起点和终点是否存在于网络中
if self.start_node not in self.network_editor.network.nodes:
debug_info += f"错误: 起点 {self.start_node} 不存在于网络中\n"
self.result_text.setText(debug_info)
QMessageBox.warning(self, "错误", f"起点 {self.start_node} 不存在")
return
if self.end_node not in self.network_editor.network.nodes:
debug_info += f"错误: 终点 {self.end_node} 不存在于网络中\n"
self.result_text.setText(debug_info)
QMessageBox.warning(self, "错误", f"终点 {self.end_node} 不存在")
return
# 获取邻接矩阵
adj_matrix = self.network_editor.network.get_adjacency_matrix()
debug_info += f"邻接矩阵: {adj_matrix}\n"
# 检查矩阵大小
if not adj_matrix or len(adj_matrix) == 0:
debug_info += "错误: 邻接矩阵为空\n"
self.result_text.setText(debug_info)
QMessageBox.warning(self, "错误", "网络中没有节点")
return
# 使用Dijkstra算法查找最短路径
distance, path = PathFinder.dijkstra(adj_matrix, self.start_node, self.end_node)
debug_info += f"Dijkstra结果 - 距离: {distance}, 路径: {path}\n"
if not path:
debug_info += f"结果: 从起点 {self.start_node} 到终点 {self.end_node} 没有路径\n"
self.result_text.setText(debug_info)
QMessageBox.information(self, "结果", "从起点到终点没有路径")
return
# 保存结果
self.shortest_distance = distance
self.shortest_path = path
# 更新界面
self.lbl_distance.setText(f"最短距离: {distance}")
self.lbl_path.setText(f"最短路径: {' -> '.join(map(str, path))}")
# 显示详细信息
result_text = f"起点: {self.start_node}\n"
result_text += f"终点: {self.end_node}\n"
result_text += f"最短距离: {distance}\n"
result_text += f"最短路径: {' -> '.join(map(str, path))}\n\n"
result_text += "路径详情:\n"
total_distance = 0
for i in range(len(path) - 1):
start = path[i]
end = path[i + 1]
edge_key = (start, end) if (start, end) in self.network_editor.network.edges else (end, start)
if edge_key in self.network_editor.network.edges:
edge = self.network_editor.network.edges[edge_key]
total_distance += edge.weight
result_text += f" {start} -> {end}: {edge.weight}\n"
result_text += f"\n总距离: {total_distance}\n\n"
result_text += "调试信息:\n"
result_text += debug_info
self.result_text.setText(result_text)
# 更新网络图
self.network_editor.set_shortest_path(path)
# 显示成功消息
QMessageBox.information(self, "查询成功", f"已找到从节点 {self.start_node} 到节点 {self.end_node} 的最短路径")
except Exception as e:
QMessageBox.critical(self, "错误", f"查找最短路径失败: {str(e)}")
import traceback
traceback.print_exc()
def on_clear_path(self):
"""清除路径"""
try:
self.shortest_path = []
self.shortest_distance = 0
self.lbl_distance.setText("最短距离: -")
self.lbl_path.setText("最短路径: -")
self.result_text.clear()
# 清除起点和终点
self.start_node = None
self.end_node = None
self.lbl_start_node.setText("起点: 未选择")
self.lbl_end_node.setText("终点: 未选择")
# 通知network_editor清除起点和终点
if hasattr(self.network_editor, 'set_start_node'):
self.network_editor.set_start_node(None)
if hasattr(self.network_editor, 'set_end_node'):
self.network_editor.set_end_node(None)
if hasattr(self.network_editor, 'set_shortest_path'):
self.network_editor.set_shortest_path([])
self.network_editor.update()
# 显示初始信息
self.show_initial_info()
except Exception as e:
print(f"清除路径失败: {e}")
def on_reset_network(self):
"""重置网络"""
try:
self.network_editor.network.clear()
self.network_editor.create_example_network()
self.start_node = None
self.end_node = None
self.shortest_path = []
self.shortest_distance = 0
self.lbl_start_node.setText("起点: 未选择")
self.lbl_end_node.setText("终点: 未选择")
self.lbl_distance.setText("最短距离: -")
self.lbl_path.setText("最短路径: -")
self.result_text.clear()
# 通知network_editor清除起点和终点
if hasattr(self.network_editor, 'set_start_node'):
self.network_editor.set_start_node(None)
if hasattr(self.network_editor, 'set_end_node'):
self.network_editor.set_end_node(None)
if hasattr(self.network_editor, 'set_shortest_path'):
self.network_editor.set_shortest_path([])
self.network_editor.update()
# 显示初始信息
self.show_initial_info()
except Exception as e:
QMessageBox.critical(self, "错误", f"重置网络失败: {str(e)}")
def on_test_path(self):
"""测试路径查询功能"""
try:
self.result_text.append("\n=== 开始路径查询查询测试 ===")
# 设置测试起点和终点
test_start = 0
test_end = 5
self.result_text.append(f"测试: 从节点 {test_start} 到节点 {test_end}")
# 设置起点和终点
self.start_node = test_start
self.end_node = test_end
self.lbl_start_node.setText(f"起点: {test_start}")
self.lbl_end_node.setText(f"终点: {test_end}")
# 更新network_editor
self.network_editor.set_start_node(test_start)
self.network_editor.set_end_node(test_end)
# 获取邻接矩阵
adj_matrix = self.network_editor.network.get_adjacency_matrix()
self.result_text.append(f"邻接矩阵: {adj_matrix}")
# 使用Dijkstra算法算法查找最短路径
distance, path = PathFinder.dijkstra(adj_matrix, test_start, test_end)
self.result_text.append(f"算法结果: 距离={distance}, 路径={path}")
if path:
self.result_text.append(f"\n测试成功!")
self.result_text.append(f"最短路径: {' -> '.join(map(str, path))}")
self.result_text.append(f"最短距离: {distance}")
# 更新UI
self.shortest_distance = distance
self.shortest_path = path
self.lbl_distance.setText(f"最短距离: {distance}")
self.lbl_path.setText(f"最短路径: {' -> '.join(map(str, path))}")
self.network_editor.set_shortest_path(path)
QMessageBox.information(self, "测试成功", f"自动测试完成\n最短路径: {' -> '.join(map(str, path))}\n最短距离: {distance}")
else:
self.result_text.append("\n测试失败: 未找到路径")
QMessageBox.warning(self, "测试结果", "未找到路径")
except Exception as e:
error_msg = f"测试失败: {str(e)}"
self.result_text.append(error_msg)
QMessageBox.critical(self, "测试错误", error_msg)
import traceback
traceback.print_exc()
def main():
"""主函数"""
try:
# 创建应用程序对象
app = QApplication(sys.argv)
# 创建主窗口
window = MainWindow()
# 显示主窗口
window.show()
# 运行应用程序
return app.exec_()
except Exception as e:
print(f"应用程序启动失败: {e}")
import traceback
traceback.print_exc()
return 1
if __name__ == "__main__":
sys.exit(main())
这段代码运行的结果我选完起点终点去查最短路径,他说我没选起点终点
最新发布