You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

429 lines
18 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

# -*- encoding: utf-8 -*-
import math
import random
import pandas as pd
from collections import Counter
def _init():
global _global_dict
_global_dict={}
class Data():
def __init__(self, source :int, num: int):
self.source = source
# 数据来源
# 1随机 2黑龙江省 3辽宁省
# 默认为1
self.edgeinfo = 1
# 是否显示详情
# 1显示 0不显示
# 默认为1
self.heidata = pd.read_excel("hei/data.xlsx") # 黑龙江省各市信息
self.heitime = pd.read_excel("hei/time.xlsx") # 黑龙江省各市通行时间
self.heidis = pd.read_excel("hei/distance.xlsx") # 黑龙江省各市通行距离
self.liaodata = pd.read_excel("liao/data.xlsx") # 辽宁省各市信息
self.liaotime = pd.read_excel("liao/time.xlsx") # 辽宁省各市通行时间
self.liaodis = pd.read_excel("liao/distance.xlsx") # 辽宁省各市通行距离
if self.source == 1:
self.data(num)
elif self.source == 2:
self.HEI_data(num)
elif self.source == 3:
self.LIAO_data(num)
def get_liaotime(self, i, j):
# print(self.heidata.iloc[i, 0])
# print(self.heidata.iloc[j, 0])
# print(self.heitime.iloc[i, j + 1])
return math.floor(self.liaotime.iloc[i, j + 1])
def get_liaodis(self, i, j):
# print(self.heidata.iloc[i, 0])
# print(self.heidata.iloc[j, 0])
# print(self.heidis.iloc[i, j + 1])
return math.floor(self.liaodis.iloc[i, j + 1] / 1000)
def get_heitime(self, i, j):
# print(self.heidata.iloc[i, 0])
# print(self.heidata.iloc[j, 0])
# print(self.heitime.iloc[i, j + 1])
return math.floor(self.heitime.iloc[i, j + 1])
def get_heidis(self, i, j):
# print(self.heidata.iloc[i, 0])
# print(self.heidata.iloc[j, 0])
# print(self.heidis.iloc[i, j + 1])
return math.floor(self.heidis.iloc[i, j + 1] / 1000)
def data(self, num: int):
if num <= 0:
raise ValueError("num must be a positive integer")
self.edgeinfo = 1
# 是否显示详情
# 1显示 0不显示
# 默认为1
self.nodes_num = num # 节点个数
self.ang = 360 / self.nodes_num # 圆心顶点角度
self.R = 300 # 外接圆半径
self.bc = 2 * self.R * math.sin(math.pi / self.nodes_num) # 节点之间的正多边形距离
self.canvas_len = int(2 * self.R + 80) # 画布边长
self.center = (self.canvas_len // 2, self.canvas_len // 2) # 画布中心点坐标
self.coordinate = self.coord_creat() # 纯节点坐标
self.Nodes = self.nodes_creat() # 创建节点列表
self.Edges = self.edges_creat() # 创建第一条连接
self.edge_add(2) # 创建第2条连接
self.edge_add(3) # 创建第3条连接
def HEI_data(self, num: int):
self.edgeinfo = 1
# 是否显示详情
# 1显示 0不显示
# 默认为1
self.number = []
for i in range(13):
self.number.append(i)
self.name = random.sample(self.number, num)
self.nodes_num = num # 节点个数
self.ang = 360 / self.nodes_num # 圆心顶点角度
self.R = 300 # 外接圆半径
self.bc = 2 * self.R * math.sin(math.pi / self.nodes_num) # 节点之间的正多边形距离
self.canvas_len = int(2 * self.R + 80) # 画布边长
self.center = (self.canvas_len // 2, self.canvas_len // 2) # 画布中心点
self.coordinate = self.coord_creat() # 纯节点坐标
self.Nodes = self.JI_nodes_creat() # 节点列表
self.Edges = self.JI_edges_creat()
self.JI_edge_add(2)
self.JI_edge_add(3)
def LIAO_data(self, num: int):
self.edgeinfo = 1
# 是否显示详情
# 1显示 0不显示
# 默认为1
self.number = []
for i in range(13):
self.number.append(i)
self.name = random.sample(self.number, num)
self.nodes_num = num # 节点个数
self.ang = 360 / self.nodes_num # 圆心顶点角度
self.R = 300 # 外接圆半径
self.bc = 2 * self.R * math.sin(math.pi / self.nodes_num) # 节点之间的正多边形距离
self.canvas_len = int(2 * self.R + 80) # 画布边长
self.center = (self.canvas_len // 2, self.canvas_len // 2) # 画布中心点
self.coordinate = self.coord_creat() # 纯节点坐标
self.Nodes = self.LIAO_nodes_creat() # 节点列表
self.Edges = self.LIAO_edges_creat()
self.LIAO_edge_add(2)
self.LIAO_edge_add(3)
def LIAO_nodes_creat(self, n_sum=None):
"""Nodes[]={<节点对象编号,节点标签,节点类别,节点坐标, 是否为必经节点(默认必经)>}"""
if n_sum == None:
n_sum = self.nodes_num
nodes = []
miny = float("inf")
minx = float("inf")
maxx = 0
maxy = 0
for i in self.name:
maxx = max(maxx, self.liaodata.iloc[i, 2])
minx = min(minx, self.liaodata.iloc[i, 2])
maxy = max(maxy, self.liaodata.iloc[i, 1])
miny = min(miny, self.liaodata.iloc[i, 1])
lenx = maxx - minx
leny = maxy - miny
Ox = (maxx + minx) / 2
Oy = (maxy + miny) / 2
x0 = self.center[0]
y0 = self.center[1]
for i in range(n_sum):
ix = self.liaodata.iloc[self.name[i], 2]
iy = self.liaodata.iloc[self.name[i], 1]
x = int(((ix - Ox) / lenx) * 550)
y = -int(((iy - Oy) / leny) * 550)
name = self.liaodata.iloc[self.name[i], 0]
# name=''+str(i+1)
mark = 0
dominator = 1
nodes.append([i, name, mark, (x0+x, y0+y), dominator])
return nodes
def LIAO_edges_creat(self):
'''
路径创建
Edges[] = { < 连接对象编号节点对象1编号节点对象2编号连接序号连接是否可用连接标签连接的距离 / 成本,连接的时间 >}
'''
edges = [] # 所有链接集合
ser = 0 # 链接对象编号
nodes = self.Nodes.copy() # 复制节点对象
nodes1 = self.Nodes.copy() # 复制节点对象
for node in nodes: # 遍历节点对象
if node in nodes1: # 删除nodes1中当期遍历的节点信息
nodes1.remove(node)
for node1 in nodes1: # 遍历删除后的节点信息
# Edges[] = { < 连接序号节点对象1编号节点对象2编号链接是否可用序号大于1连接是否标记连接标签连接的距离 / 成本,连接的时间,连接序号 >}
n1 = node[0] # 节点对象编号1
n2 = node1[0] # 节点对象编号2
seq = 1 # 链接序号
mark = False # 连接是否标记
tag = self.liaodis.iloc[self.name[n1], 0] + '-' + self.liaodis.iloc[self.name[n2], 0]
# tag = f"{n1+1}-{n2+1}" # 链接标签
dist_c = self.get_liaodis(n1, n2)
# dist_c = random.randint(30,120) # 距离成本
time_c = self.get_liaotime(n1, n2)
# time_c = random.randint(1,30) # 链接的时间
enable = 1 # 连接是否可用
edges.append([ser, n1, n2, enable, mark, tag, dist_c, time_c, seq])
ser += 1
return edges
def LIAO_edge_add(self, no):
nodes = self.Nodes.copy() # 复制节点对象
nodes1 = self.Nodes.copy() # 复制节点对象
for node in nodes: # 遍历节点对象
if node in nodes1: # 删除nodes1中当期遍历的节点信息
nodes1.remove(node)
for node1 in nodes1: # 遍历删除后的节点信息
# Edges[] = { < 连接序号节点对象1编号节点对象2编号链接是否显示序号大于1连接是否标记连接标签连接的距离 / 成本,连接的时间,连接序号 >}
ser = len(self.Edges) # 链接序号
n1 = node[0] # 节点对象编号1
n2 = node1[0] # 节点对象编号2
show = 0
mark = False # 连接是否标记
tag = f"{self.liaodis.iloc[self.name[n1], 0]}-{self.liaodis.iloc[self.name[n2], 0]}-{no}" # 链接标签
# tag = f"{n1 + 1}-{n2 + 1}-{no}" # 链接标签
dist_c = self.get_liaodis(n1, n2)
# dist_c = random.randint(30,120) # 距离成本
time_c = self.get_liaotime(n1, n2)
# time_c = random.randint(1,30) # 链接的时间
seq = no # 连接序号
self.Edges.append([ser, n1, n2, show, mark, tag, dist_c, time_c, seq])
def JI_nodes_creat(self, n_sum=None):
"""Nodes[]={<节点对象编号,节点标签,节点类别,节点坐标, 是否为必经节点(默认必经)>>}"""
if n_sum == None:
n_sum = self.nodes_num
nodes = []
miny = float("inf")
minx = float("inf")
maxx = 0
maxy = 0
for i in self.name:
# print(i, self.heidis.iloc[i, 0])
# print(self.heidata.iloc[i, 0], self.heidata.iloc[i, 1], self.heidata.iloc[i, 2])
maxx = max(maxx, self.heidata.iloc[i, 2])
minx = min(minx, self.heidata.iloc[i, 2])
maxy = max(maxy, self.heidata.iloc[i, 1])
miny = min(miny, self.heidata.iloc[i, 1])
# print(maxx, maxy, minx, miny)
lenx = maxx - minx
leny = maxy - miny
Ox = (maxx + minx) / 2
Oy = (maxy + miny) / 2
R = self.R
x0 = self.center[0]
y0 = self.center[1]
for i in range(n_sum):
# rad = math.radians(i*self.ang)
# x = int(math.cos(rad)*R)
# y = int(math.sin(rad)*R)
ix = self.heidata.iloc[self.name[i], 2]
iy = self.heidata.iloc[self.name[i], 1]
# print(int(math.cos(rad)*R))
# print(((ix - Ox) / lenx) * 300)
x = int(((ix - Ox) / lenx) * 550)
y = -int(((iy - Oy) / leny) * 550)
name = self.heidata.iloc[self.name[i], 0]
# name=''+str(i+1)
mark = 0
dominator = 1
nodes.append([i, name, mark, (x0+x, y0+y), dominator])
return nodes
def JI_edges_creat(self):
'''
路径创建
Edges[] = { < 连接对象编号节点对象1编号节点对象2编号连接序号连接是否可用连接标签连接的距离 / 成本,连接的时间 >}
'''
edges = [] # 所有链接集合
ser = 0 # 链接对象编号
nodes = self.Nodes.copy() # 复制节点对象
nodes1 = self.Nodes.copy() # 复制节点对象
for node in nodes: # 遍历节点对象
if node in nodes1: # 删除nodes1中当期遍历的节点信息
nodes1.remove(node)
for node1 in nodes1: # 遍历删除后的节点信息
for i in range(random.randint(1,1)):
# Edges[] = { < 连接序号节点对象1编号节点对象2编号链接是否可用序号大于1连接是否标记连接标签连接的距离 / 成本,连接的时间,连接序号 >}
n1 = node[0] # 节点对象编号1
n2 = node1[0] # 节点对象编号2
seq = 1 # 链接序号
mark = False # 连接是否标记
tag = self.heidis.iloc[self.name[n1], 0] + '-' + self.heidis.iloc[self.name[n2], 0]
# tag = f"{n1+1}-{n2+1}" # 链接标签
dist_c = self.get_heidis(n1, n2)
# dist_c = random.randint(30,120) # 距离成本
time_c = self.get_heitime(n1, n2)
# time_c = random.randint(1,30) # 链接的时间
enable = 1 # 连接是否可用
edges.append([ser, n1, n2, enable, mark, tag, dist_c, time_c, seq])
ser += 1
return edges
def JI_edge_add(self, no):
nodes = self.Nodes.copy() # 复制节点对象
nodes1 = self.Nodes.copy() # 复制节点对象
for node in nodes: # 遍历节点对象
if node in nodes1: # 删除nodes1中当期遍历的节点信息
nodes1.remove(node)
for node1 in nodes1: # 遍历删除后的节点信息
# Edges[] = { < 连接序号节点对象1编号节点对象2编号链接是否显示序号大于1连接是否标记连接标签连接的距离 / 成本,连接的时间,连接序号 >}
ser = len(self.Edges) # 链接序号
n1 = node[0] # 节点对象编号1
n2 = node1[0] # 节点对象编号2
show = 0
mark = False # 连接是否标记
tag = f"{self.heidis.iloc[self.name[n1], 0]}-{self.heidis.iloc[self.name[n2], 0]}-{no}" # 链接标签
# tag = f"{n1 + 1}-{n2 + 1}-{no}" # 链接标签
dist_c = self.get_heidis(n1, n2)
# dist_c = random.randint(30,120) # 距离成本
time_c = self.get_heitime(n1, n2)
# time_c = random.randint(1,30) # 链接的时间
seq = no # 连接序号
self.Edges.append([ser, n1, n2, show, mark, tag, dist_c, time_c, seq])
def coord_creat(self):
'''返回每个节点的坐标'''
coordinate = []
x0 = self.center[0]
y0 = self.center[1]
for i in range(self.nodes_num):
rad = math.radians(i*self.ang)
x = int(math.cos(rad)*self.R)
y = int(math.sin(rad)*self.R)
coordinate.append((x0+x,y0+y))
return coordinate
def nodes_creat(self, n_sum= None):
"""Nodes[]={<节点对象编号,节点标签,节点类别,节点坐标, 是否为必经节点(默认必经)>}"""
if n_sum == None:
n_sum = self.nodes_num
nodes = []#初始化node表
# 设置画布中心点坐标x0,y0
x0 = self.center[0]
y0 = self.center[1]
for i in range(n_sum):# 通过几何运算得到多边形各个顶点坐标
rad = math.radians(i * self.ang)# 计算第i个点的弧度
x = int(math.cos(rad) * self.R)# 计算第i个顶点x坐标
y = int(math.sin(rad) * self.R)# 计算第i个顶点y坐标
name = '' + str(i + 1)# 给第i个顶点命名
mark = 0#节点为未标记
dominator = 1#设置为必经节点
nodes.append([i, name, mark, (x0 + x, y0 + y), dominator])#将当前节点加入node中
return nodes
def edges_creat(self):
'''
路径创建
Edges[] = { < 连接对象编号节点对象1编号节点对象2编号连接是否存在连接是否标记连接标签连接的距离 / 成本,连接的时间,连接序号 >}
'''
edges = [] # 初始化所有链接集合
ser = 0 # 初始化链接对象编号
nodes = self.Nodes.copy() # 复制节点对象
nodes1 = self.Nodes.copy() # 复制节点对象
for node in nodes: # 遍历节点对象
if node in nodes1: # 删除nodes1中当期遍历的节点信息
nodes1.remove(node)
for node1 in nodes1: # 遍历删除后的节点信息
# Edges[] = { < 连接序号节点对象1编号节点对象2编号链接是否可用序号大于1连接是否标记连接标签连接的距离 / 成本,连接的时间,连接序号 >}
n1 = node[0] # 节点对象编号1
n2 = node1[0] # 节点对象编号2
seq = 1 # 链接序号
mark = False # 连接是否标记
tag = f"{n1+1}-{n2+1}" # 链接标签
dist_c = random.randint(10, 120) # 随机生成距离成本
time_c = random.randint(10, 120) # 随机生成链接的时间
enable = 1 # 连接是否可用
if dist_c >= 100 or time_c >= 100: # 设置某些节点为不显示
enable = 0
edges.append([ser, n1, n2, enable, mark, tag, dist_c, time_c, seq]) # 将连接加入到边的集合中
ser+=1# 计数加一
return edges
def node_count(self, node_num:tuple, node_co:list):
for node in node_num:
node_co.append(node)
def path_creat(self):
node_co = {} # 节点统计,
for node in self.Nodes:
node_co[node[0]] = 0
print(node_co)
for edge in self.Edges:
for num in node_co.keys():
if node_co[num] <=1:
if edge[1] == num or edge[2]== num:
node_co[num]+=1
print((edge[1],edge[2]))
print(node_co) # 每个节点出现的次数
def node_co(self,key): # 通过节点编号返回编号的坐标
"""通过节点编号返回编号的坐标"""
nodes = self.Nodes
for n in nodes:
if n[0] == key:
return n[3]
def edge_add(self, no):
nodes = self.Nodes.copy() # 复制节点对象
nodes1 = self.Nodes.copy() # 复制节点对象
for node in nodes: # 遍历节点对象
if node in nodes1: # 删除nodes1中当期遍历的节点信息
nodes1.remove(node)
for node1 in nodes1: # 遍历删除后的节点信息
# Edges[] = { < 连接序号节点对象1编号节点对象2编号链接是否显示序号大于1连接是否标记连接标签连接的距离 / 成本,连接的时间,连接序号 >}
ser = len(self.Edges) # 链接序号
n1 = node[0] # 节点对象编号1
n2 = node1[0] # 节点对象编号2
show = 0
mark = False # 连接是否标记
tag = f"{n1 + 1}-{n2 + 1}-{no}" # 链接标签
dist_c = random.randint(30, 100) # 距离成本
time_c = random.randint(1, 30) # 链接的时间
enable = no # 连接是否可用
self.Edges.append([ser, n1, n2, show, mark, tag, dist_c, time_c, enable])
if __name__ == '__main__':
d = Data(1, 5)
d.path_creat()
#print(d.Edges)