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

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