|
|
|
|
# -*- encoding: utf-8 -*-
|
|
|
|
|
from NODE import *
|
|
|
|
|
from SOLVE import *
|
|
|
|
|
from EDGE import *
|
|
|
|
|
from WAYS import *
|
|
|
|
|
|
|
|
|
|
N = Node()
|
|
|
|
|
E = Edge()
|
|
|
|
|
W = Ways()
|
|
|
|
|
|
|
|
|
|
mode = tk.IntVar(value=1)
|
|
|
|
|
# 目前的操作状态:
|
|
|
|
|
# 1为节点操作
|
|
|
|
|
# 2为链接操作
|
|
|
|
|
# 3为路径操作
|
|
|
|
|
# 默认为1
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
RIGHT = -1
|
|
|
|
|
B = tk.Button(frame, text="修改", command=lambda: N.node_set())
|
|
|
|
|
B.place(x=180, y=10, width=50, height=30)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def left1(event):
|
|
|
|
|
# 查找鼠标左键按下时位置是否在某个节点内
|
|
|
|
|
n = -1
|
|
|
|
|
for node in d.Nodes:
|
|
|
|
|
if dir2([event.x, event.y], [node[3][0], node[3][1]]) < 20 * 20:
|
|
|
|
|
n = node[0]
|
|
|
|
|
|
|
|
|
|
# n为点击的节点,若没有则为-1
|
|
|
|
|
m = mode.get() # 查看现在操作类型
|
|
|
|
|
if m == 1 and not n == -1:
|
|
|
|
|
# 节点操作
|
|
|
|
|
|
|
|
|
|
N.node_mark(n)
|
|
|
|
|
elif m == 2 and not n == -1:
|
|
|
|
|
# 链接操作
|
|
|
|
|
if len(E.mark) == 0:
|
|
|
|
|
E.mark.append(n)
|
|
|
|
|
E.node_mark1(E.mark[0])
|
|
|
|
|
elif len(E.mark) == 1:
|
|
|
|
|
E.mark.append(n)
|
|
|
|
|
E.node_mark1(E.mark[0])
|
|
|
|
|
E.node_mark2(E.mark[1])
|
|
|
|
|
elif not n == E.mark[1]:
|
|
|
|
|
n1 = E.mark[1]
|
|
|
|
|
E.mark.clear()
|
|
|
|
|
E.mark.append(n1)
|
|
|
|
|
E.mark.append(n)
|
|
|
|
|
E.node_mark1(E.mark[0])
|
|
|
|
|
E.node_mark2(E.mark[1])
|
|
|
|
|
# 路径操作
|
|
|
|
|
elif m == 3 and not n == -1:
|
|
|
|
|
W.user_way_add(n)
|
|
|
|
|
# 自动判断操作
|
|
|
|
|
elif m == 4 and not n == -1:
|
|
|
|
|
if len(solve.mark) == 0:
|
|
|
|
|
solve.mark.append(n)
|
|
|
|
|
solve.node_mark1(solve.mark[0])
|
|
|
|
|
elif len(solve.mark) == 1:
|
|
|
|
|
solve.mark.append(n)
|
|
|
|
|
solve.node_mark1(solve.mark[0])
|
|
|
|
|
solve.node_mark2(solve.mark[1])
|
|
|
|
|
elif not n == solve.mark[1]:
|
|
|
|
|
n1 = solve.mark[1]
|
|
|
|
|
solve.mark.clear()
|
|
|
|
|
solve.mark.append(n1)
|
|
|
|
|
solve.mark.append(n)
|
|
|
|
|
solve.node_mark1(solve.mark[0])
|
|
|
|
|
solve.node_mark2(solve.mark[1])
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def onRightButtonUp(event):
|
|
|
|
|
global RIGHT
|
|
|
|
|
# 查找鼠标右键按下时位置是否在某个节点内
|
|
|
|
|
n = -1
|
|
|
|
|
for node in d.Nodes:
|
|
|
|
|
if dir2([event.x, event.y], [node[3][0], node[3][1]]) < 20 * 20:
|
|
|
|
|
n = node[0]
|
|
|
|
|
if n == -1:
|
|
|
|
|
menu.post(event.x_root, event.y_root)
|
|
|
|
|
else:
|
|
|
|
|
RIGHT = n
|
|
|
|
|
menu_node.post(event.x_root, event.y_root)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# 右键菜单
|
|
|
|
|
def m_node():
|
|
|
|
|
mode.set(1)
|
|
|
|
|
W.clear()
|
|
|
|
|
N.node_mark_display()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def m_edge():
|
|
|
|
|
mode.set(2)
|
|
|
|
|
W.clear()
|
|
|
|
|
E.edge_mark_display()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def m_ways():
|
|
|
|
|
mode.set(3)
|
|
|
|
|
W.user_way_clear()
|
|
|
|
|
W.way_mark_display()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def m_info():
|
|
|
|
|
d.edgeinfo ^= 1
|
|
|
|
|
G.draw()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def m_solve():
|
|
|
|
|
W.clear()
|
|
|
|
|
mode.set(4)
|
|
|
|
|
solve.Solve_display()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def graph_init():
|
|
|
|
|
nodes = random.randint(4, 10)
|
|
|
|
|
N.node_init(nodes)
|
|
|
|
|
G.draw()
|
|
|
|
|
N.node_mark_display()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def sourc_set(num):
|
|
|
|
|
W.clear()
|
|
|
|
|
d.source = num
|
|
|
|
|
N.node_init(nodes)
|
|
|
|
|
G.draw()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def node_del(num):
|
|
|
|
|
N.node_mark(num)
|
|
|
|
|
N.node_del_exact()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def node_name(num):
|
|
|
|
|
N.node_mark(num)
|
|
|
|
|
N.node_rename()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def node_condition(num):
|
|
|
|
|
d.Nodes[num][4] ^= 1
|
|
|
|
|
G.draw()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
menu = tk.Menu(root, tearoff=0)
|
|
|
|
|
menu.add_command(label='节点操作', command=m_node)
|
|
|
|
|
menu.add_command(label='连接操作', command=m_edge)
|
|
|
|
|
menu.add_command(label='路径操作', command=m_ways)
|
|
|
|
|
menu.add_command(label='显示/隐藏链接信息', command=m_info)
|
|
|
|
|
|
|
|
|
|
menu.add_command(label='自动判断相关', command=m_solve)
|
|
|
|
|
fmenu1 = Menu(menu, tearoff=False)
|
|
|
|
|
fmenu1.add_command(label='使用模拟数据', command=lambda: sourc_set(1))
|
|
|
|
|
fmenu1.add_command(label='使用黑龙江省数据', command=lambda: sourc_set(2))
|
|
|
|
|
fmenu1.add_command(label='使用辽宁省数据', command=lambda: sourc_set(3))
|
|
|
|
|
menu.add_cascade(label="切换数据源", menu=fmenu1)
|
|
|
|
|
|
|
|
|
|
menu_node = tk.Menu(root, tearoff=0)
|
|
|
|
|
menu_node.add_command(label='删除节点', command=lambda: node_del(RIGHT))
|
|
|
|
|
menu_node.add_command(label='切换必经/非必经', command=lambda: node_condition(RIGHT))
|
|
|
|
|
menu_node.add_command(label='重命名节点', command=lambda: node_name(RIGHT))
|
|
|
|
|
# menu_node.add_command(label='显示/隐藏链接信息', command=m_info)
|
|
|
|
|
|
|
|
|
|
cv.bind('<Button-1>', left1)
|
|
|
|
|
cv.bind('<ButtonRelease-3>', onRightButtonUp)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# 释放右键时打开菜单
|
|
|
|
|
|
|
|
|
|
def auto_opera_mu(menu: tk.Menu):
|
|
|
|
|
"""TSP问题自动生成与自动求解相关"""
|
|
|
|
|
menu_node = Menu(menu, tearoff=False)
|
|
|
|
|
menu_node.add_command(label="自动随机产生一个TSP问题", command=lambda: graph_init())
|
|
|
|
|
menu_node.add_command(label="重新生成", command=lambda: N.node_refresh())
|
|
|
|
|
menu_node.add_command(label="自动求解最优路径-遍历", command=lambda: solve.dfs_panel())
|
|
|
|
|
menu_node.add_command(label="自动求解优化路径-贪心", command=lambda: solve.greedy_panel())
|
|
|
|
|
menu_node.add_command(label="检查是否存在路径", command=lambda: solve.check())
|
|
|
|
|
|
|
|
|
|
# 在主目录菜单上新增"文件"选项,并通过menu参数与下拉菜单绑定
|
|
|
|
|
menu.add_cascade(label="TSP问题自动生成与自动求解相关", menu=menu_node)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def node_opera_mu(menu: tk.Menu):
|
|
|
|
|
"""节点操作"""
|
|
|
|
|
|
|
|
|
|
# fmenu1 = Menu(menu, tearoff=False)
|
|
|
|
|
# for i in range(10):
|
|
|
|
|
# fmenu1.add_command(label='选择节点 ' + str(i + 1), command=lambda num=i: node_mark(num))
|
|
|
|
|
|
|
|
|
|
menu_node = Menu(menu, tearoff=False)
|
|
|
|
|
menu_node.add_command(label="添加一个节点", command=lambda: N.node_add())
|
|
|
|
|
menu_node.add_command(label="删除一个节点", command=lambda: N.node_del())
|
|
|
|
|
# menu_node.add_cascade(label="选择一个节点", menu=fmenu1)
|
|
|
|
|
menu_node.add_command(label="选择一个节点", command=lambda: N.node_mark_display())
|
|
|
|
|
# menu_node.add_command(label="停止标记一个节点", command=lambda: node_mark_display1())
|
|
|
|
|
# menu_node.add_command(label="设置节点标签", command=lambda:node_rename())
|
|
|
|
|
|
|
|
|
|
# 在主目录菜单上新增"文件"选项,并通过menu参数与下拉菜单绑定
|
|
|
|
|
menu.add_cascade(label="节点操作", menu=menu_node)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def edge_opera_mu(menu: tk.Menu):
|
|
|
|
|
"""连接操作"""
|
|
|
|
|
|
|
|
|
|
# fmenu1 = Menu(menu, tearoff=False)
|
|
|
|
|
# for i in range(10):
|
|
|
|
|
# fmenu1.add_command(label='选择另一个节点 ' + str(i + 1), command=lambda num=i: node_mark2(num))
|
|
|
|
|
#
|
|
|
|
|
menu_node = Menu(menu, tearoff=False)
|
|
|
|
|
# menu_node.add_cascade(label="选择另一个节点", menu=fmenu1)
|
|
|
|
|
|
|
|
|
|
menu_node.add_command(label="选择一个连接", command=lambda: E.edge_mark_display())
|
|
|
|
|
|
|
|
|
|
# menu_node.add_command(label="建立一个连接",command=lambda :edge_add())
|
|
|
|
|
menu_node.add_command(label="删除所有连接", command=lambda: E.edge_delall())
|
|
|
|
|
menu_node.add_command(label="删除所有多余连接", command=lambda: E.newedge_del_all(1))
|
|
|
|
|
# menu_node.add_command(label="设置连接标签", command=lambda: edge_rename())
|
|
|
|
|
# 在主目录菜单上新增"文件"选项,并通过menu参数与下拉菜单绑定
|
|
|
|
|
menu.add_cascade(label="连接操作", menu=menu_node)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def path_opera_mu(menu: tk.Menu):
|
|
|
|
|
"""路径操作"""
|
|
|
|
|
menu_node = Menu(menu, tearoff=False)
|
|
|
|
|
menu_node.add_command(label="开始标记路径", command=lambda: W.way_mark_display())
|
|
|
|
|
menu_node.add_command(label="撤销一步路径", command=lambda: W.user_way_del())
|
|
|
|
|
menu_node.add_command(label="取消所有路径标记", command=lambda: W.user_way_clear())
|
|
|
|
|
# 在主目录菜单上新增"文件"选项,并通过menu参数与下拉菜单绑定
|
|
|
|
|
menu.add_cascade(label="路径操作", menu=menu_node, )
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
auto_opera_mu(main_menu)
|
|
|
|
|
node_opera_mu(main_menu)
|
|
|
|
|
edge_opera_mu(main_menu)
|
|
|
|
|
path_opera_mu(main_menu)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def main():
|
|
|
|
|
G = Graph()
|
|
|
|
|
G.draw()
|
|
|
|
|
sourc_set(2)
|
|
|
|
|
mainloop()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if __name__ == '__main__':
|
|
|
|
|
main()
|