第一题
import networkx as nx
import numpy as np
import random
import math
import matplotlib.pyplot as plt
import pylab as plb
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams['axes.unicode_minus'] = False
# matplotlib画图中中文显示会有问题,需要这两行设置默认字体
G=nx.Graph()
# 随机数模拟用户位置
lst=[]
for i in range(30):
x=random.randint(0,25)+random.random()
y = random.randint(0, 25) + random.random()
lst.append([x,y])
X=[];Y=[]
for i in range(1,30):
X.append(lst[i][0])
Y.append(lst[i][1])
plt.xlabel('X')
plt.ylabel('Y')
plt.xlim(xmax=26, xmin=0)
plt.ylim(ymax=26, ymin=0)
# 画两条(0-9)的坐标轴并设置轴标签x,y
x1 = X # 随机产生300个平均值为2,方差为1.2的浮点数,即第一簇点的x轴坐标
y1 = Y # 随机产生300个平均值为2,方差为1.2的浮点数,即第一簇点的y轴坐标
x2 = [lst[0][0],]
y2 = [lst[0][1],]
colors1 = '#00CED1' # 点的颜色
colors2 = '#DC143C'
area = np.pi * 4 ** 2 # 点面积
# 画散点图
plt.scatter(x1, y1, s=area, c=colors1, alpha=0.4, label='用户')
plt.scatter(x2, y2, s=area, c=colors2, alpha=0.4, label='电源')
# 图形构建
num = len(lst)
for i in range(num):
G.add_node(i)
for i in range(num-1):
for j in range(i+1,num):
Widget=math.sqrt(((lst[i][0]-lst[j][0])**2)+((lst[i][1]-lst[j][1])**2))
G.add_edge(i,j,weight=Widget)
T=nx.minimum_spanning_tree(G)
#plb.subplot(121)
#nx.draw(G, with_labels=True)
#plb.subplot(122)
#nx.draw(T, with_labels=True)
#plb.show()
# 边分类
road=list(T.edges)
Rnum=[]
for i in range(len(road)):
Rnum.append(0)
for i in range(1,num):
path=nx.dijkstra_path(T,0,i)
for j in range(len(path)-1):
for k in range(len(road)):
if path[j]==road[k][0]and path[j + 1]==road[k][1]:
Rnum[k]=Rnum[k]+1
if path[j] == road[k][1] and path[j + 1] == road[k][0]:
Rnum[k] = Rnum[k] + 1
for i in range(len(Rnum)):
if Rnum[i]==max(Rnum):
Rnum[i]=325.7/125.6
elif Rnum[i]>=3:
Rnum[i] = 239.4 / 125.6
else:
Rnum[i] = 1
# 迭代优化
G1=G
Sum0=0
for i in range(len(Rnum)):
Sum0=Sum0+math.sqrt(((lst[road[i][0]][0]-lst[road[i][1]][0])**2)+
((lst[road[i][0]][1]-lst[road[i][1]][1])**2))*Rnum[i]*125.6
# 1.更新边的权重
T1=T
Sum1=Sum0
dot=[]
while True:
for i in range(len(Rnum)):
G1.edges[road[i]]['weight']=G1.edges[road[i]]['weight']*Rnum[i]
# 2.重新规划最小生成树和线路分类
T2=nx.minimum_spanning_tree(G1)
road2=list(T2.edges)
Rnum2=[]
for i in range(len(road2)):
Rnum2.append(0)
for i in range(1,num):
path=nx.dijkstra_path(T2,0,i)
for j in range(len(path)-1):
for k in range(len(road2)):
if path[j]==road2[k][0]and path[j + 1]==road2[k][1]:
Rnum2[k]=Rnum2[k]+1
if path[j] == road2[k][1] and path[j + 1] == road2[k][0]:
Rnum2[k] = Rnum2[k] + 1
M=max(Rnum2)
for i in range(len(Rnum2)):
if Rnum2[i]>=2:
dot.append(road2[i][0])
dot.append(road2[i][1])
if Rnum2[i]==M:
Rnum2[i]=325.7/125.6
elif Rnum2[i]>=3:
Rnum2[i] = 239.4 / 125.6
else:
Rnum2[i] = 1
# 3.计算线路总造价
Sum=0
for i in range(len(Rnum2)):
Sum=Sum+math.sqrt(((lst[road2[i][0]][0]-lst[road2[i][1]][0])**2)+
((lst[road2[i][0]][1]-lst[road2[i][1]][1])**2))*Rnum2[i]*125.6
if Sum1==Sum:
break
else:
Sum1=Sum
dot=list(set(dot))
# 计算用电可靠性
bug=0.0
BUG=[]
for i in range(1,num):
bug = 0.0
path=nx.dijkstra_path(T2,0,i)
bug=bug+(len(path)-1)*0.2+1
for j in range(len(path)-1):
bug=bug+math.sqrt(((lst[path[j]][0] - lst[path[j+1]][0]) ** 2) +
((lst[path[j]][1] - lst[path[j+1]][1]) ** 2))*0.02
BUG.append(100-bug)
for i in range(len(road2)):
if Rnum2[i]==325.7/125.6:
plt.plot([lst[road2[i][0]][0], lst[road2[i][1]][0]], [lst[road2[i][0]][1], lst[road2[i][1]][1]], linewidth='2', color='#eb891a')
elif Rnum2[i]==239.4/125.6:
plt.plot([lst[road2[i][0]][0], lst[road2[i][1]][0]], [lst[road2[i][0]][1], lst[road2[i][1]][1]], linewidth='1', color='#2017a0')
elif Rnum2[i]==1:
plt.plot([lst[road2[i][0]][0], lst[road2[i][1]][0]], [lst[road2[i][0]][1], lst[road2[i][1]][1]], linewidth='1', color='g')
plt.legend()
plt.show()
print('最低线路成本为:%.6f'%Sum)
j=1
for i in BUG:
print("第{}个用户的用电可靠性:".format(j), "%.2f"%i)
j+=1
j=0
for i in dot:
print("第{}个节点坐标:".format(j), "X坐标为 %.4f"%lst[i][0],"Y坐标为 %.4f"%lst[i][1])
j+=1
print("-----使用的数据-----")
for i in range(1,num):
print("第{}个用户坐标:".format(i), "X坐标为 %.4f"%lst[i][0],"Y坐标为 %.4f"%lst[i][1])
第二题
import networkx as nx
import numpy as np
import random
import math
import matplotlib.pyplot as plt
import pylab as plb
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams['axes.unicode_minus'] = False
# matplotlib画图中中文显示会有问题,需要这两行设置默认字体
G=nx.Graph()
# 随机数模拟用户位置
lst=[]
for i in range(30):
x=random.randint(0,25)+random.random()
y = random.randint(0, 25) + random.random()
lst.append([x,y])
X=[];Y=[]
for i in range(2,30):
X.append(lst[i][0])
Y.append(lst[i][1])
plt.xlabel('X')
plt.ylabel('Y')
plt.xlim(xmax=27, xmin=-2)
plt.ylim(ymax=27, ymin=-2)
# 画两条(0-9)的坐标轴并设置轴标签x,y
x1 = X
y1 = Y
x2 = [lst[0][0],lst[1][0]]
y2 = [lst[0][1],lst[1][1]]
colors1 = '#00CED1' # 点的颜色
colors2 = '#DC143C'
area = np.pi * 4 ** 2 # 点面积
# 画散点图
plt.scatter(x1, y1, s=area, c=colors1, alpha=0.4, label='用户')
plt.scatter(x2, y2, s=area, c=colors2, alpha=0.4, label='电源')
# 图形构建
num = len(lst)
for i in range(num):
G.add_node(i)
for i in range(num-1):
for j in range(i+1,num):
Widget=math.sqrt(((lst[i][0]-lst[j][0])**2)+((lst[i][1]-lst[j][1])**2))
G.add_edge(i,j,weight=Widget)
T=nx.minimum_spanning_tree(G)
# 去掉两个电源之间的路的最长边
T1=T
Epath=nx.dijkstra_path(T1, 0, 1)
Elong=[]
for j in range(len(Epath)-1):
Elong.append(math.sqrt(((lst[Epath[j]][0] - lst[Epath[j+1]][0]) ** 2) +
((lst[Epath[j]][1] - lst[Epath[j+1]][1]) ** 2)))
for j in range(len(Epath)-1):
if math.sqrt(((lst[Epath[j]][0] - lst[Epath[j+1]][0]) ** 2) +
((lst[Epath[j]][1] - lst[Epath[j+1]][1]) ** 2))==max(Elong):
T1.remove_edge(Epath[j],Epath[j+1])
# 获取去掉最长边后的连通子图
SUBG=[]
for c in nx.connected_components(T1):
# 得到不连通的子集
subg = T1.subgraph(c)
# su=nx.minimum_spanning_tree(subg)
SUBG.append(subg)
print(SUBG[1].edges)
for m in range(2):
road = list(SUBG[m].edges)
Rnum = []
for i in range(len(road)):
Rnum.append(0)
for i in SUBG[m].nodes:
if 0 in SUBG[m].nodes:
path = nx.dijkstra_path(SUBG[m], 0, i)
elif 1 in SUBG[m].nodes:
path = nx.dijkstra_path(SUBG[m], 1, i)
else:
continue
for j in range(len(path) - 1):
for k in range(len(road)):
if path[j] == road[k][0] and path[j + 1] == road[k][1]:
Rnum[k] = Rnum[k] + 1
if path[j] == road[k][1] and path[j + 1] == road[k][0]:
Rnum[k] = Rnum[k] + 1
M=max(Rnum)
for i in range(len(Rnum)):
if Rnum[i] == M:
Rnum[i] = 325.7 / 125.6
elif Rnum[i] >= 3:
Rnum[i] = 239.4 / 125.6
else:
Rnum[i] = 1
# 迭代优化
G1 = G
Sum0 = 0
for i in range(len(Rnum)):
Sum0 = Sum0 + math.sqrt(((lst[road[i][0]][0] - lst[road[i][1]][0]) ** 2) +
((lst[road[i][0]][1] - lst[road[i][1]][1]) ** 2)) * Rnum[i] * 125.6
# 1.更新边的权重
T1 = SUBG[m]
Sum1 = Sum0
while True:
dot = []
for i in range(len(Rnum)):
G1.edges[road[i]]['weight'] = G1.edges[road[i]]['weight'] * Rnum[i]
# 2.重新规划每个子图的最小生成树和线路分类
subg2=nx.minimum_spanning_tree(G1.subgraph(SUBG[m].nodes))
road2 = list(subg2.edges)
Rnum2 = []
for i in range(len(road2)):
Rnum2.append(0)
for i in subg2.nodes:
if 0 in subg2.nodes:
path = nx.dijkstra_path(subg2, 0, i)
elif 1 in subg2.nodes:
path = nx.dijkstra_path(subg2, 1, i)
for j in range(len(path) - 1):
for k in range(len(road2)):
if path[j] == road2[k][0] and path[j + 1] == road2[k][1]:
Rnum2[k] = Rnum2[k] + 1
if path[j] == road2[k][1] and path[j + 1] == road2[k][0]:
Rnum2[k] = Rnum2[k] + 1
M=max(Rnum2)
for i in range(len(Rnum2)):
if Rnum2[i] >= 2:
dot.append(road2[i][0])
dot.append(road2[i][1])
if Rnum2[i] == M:
Rnum2[i] = 325.7 / 125.6
elif Rnum2[i] >= 3:
Rnum2[i] = 239.4 / 125.6
else:
Rnum2[i] = 1
# 3.计算线路总造价
Sum = 0
for i in range(len(Rnum2)):
Sum = Sum + math.sqrt(((lst[road2[i][0]][0] - lst[road2[i][1]][0]) ** 2) +
((lst[road2[i][0]][1] - lst[road2[i][1]][1]) ** 2)) * Rnum2[i] * 125.6
if Sum1 == Sum:
break
else:
Sum1 = Sum
for i in range(len(road2)):
if Rnum2[i] == 325.7 / 125.6:
plt.plot([lst[road2[i][0]][0], lst[road2[i][1]][0]], [lst[road2[i][0]][1], lst[road2[i][1]][1]],
linewidth='2', color='#eb891a')
elif Rnum2[i] == 239.4 / 125.6:
plt.plot([lst[road2[i][0]][0], lst[road2[i][1]][0]], [lst[road2[i][0]][1], lst[road2[i][1]][1]],
linewidth='1', color='#2017a0')
elif Rnum2[i] == 1:
plt.plot([lst[road2[i][0]][0], lst[road2[i][1]][0]], [lst[road2[i][0]][1], lst[road2[i][1]][1]],
linewidth='1', color='g')
# 计算用电可靠性
bug = 0.0
BUG = []
for i in subg2.nodes:
bug = 0.0
if 0 in SUBG[m].nodes:
path = nx.dijkstra_path(subg2, 0, i)
elif 1 in SUBG[m].nodes:
path = nx.dijkstra_path(subg2, 1, i)
bug = bug + (len(path) - 1) * 0.2 + 1
for j in range(len(path) - 1):
bug = bug + math.sqrt(((lst[path[j]][0] - lst[path[j + 1]][0]) ** 2) +
((lst[path[j]][1] - lst[path[j + 1]][1]) ** 2)) * 0.02
BUG.append(100 - bug)
print("在第%d条线路中:"%m)
print("线路{}的总造价为:".format(m), Sum)
j = 1
for i in BUG:
print("第{}个用户的用电可靠性:".format(j), "%.2f" % i)
j += 1
j = 0
for i in dot:
print("第{}个节点坐标:".format(j), "X坐标为 %.4f" % lst[i][0], "Y坐标为 %.4f" % lst[i][1])
j += 1
plt.legend()
plt.show()
print("-----使用的数据-----")
for i in range(1,num):
print("第{}个用户坐标:".format(i), "X坐标为 %.4f"%lst[i][0],"Y坐标为 %.4f"%lst[i][1])