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