# -*- 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)