Loading... # 前言 麻烦给个三连吧~~~ 课程·任务书和源码都在: 通过网盘分享的文件:交通规划课程设计.zip 链接: https://pan.baidu.com/s/1HULrttoIKGPb85Vr6xXGQQ?pwd=esqw 提取码: esqw 没有残缺,很完整的一个项目,如果觉得对你有用,求打赏,最后还有个优化改进后的代码,都用python的面向对象,输出结果都是一样的,避免查重可用。 --- ——交通需求预测中“四阶段法”的实践 # 2.a容量限制-增量加载法最短路法.py ```python #OD分布流量矩阵输入 from numpy import * flowm = mat([[0,0,0,0,0,0,0,0], [0,0,0,0,350,400,0,500], [0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0], [0,300,0,0,0,100,0,350], [0,400,0,0,200,0,0,700], [0,0,0,0,0,0,0,0], [0,500,0,0,350,700,0,0]]) flow1m = 0.6*flowm flow2m = 0.3*flowm flow3m = 0.1*flowm flow1, flow2, flow3 = flow1m.tolist(), flow2m.tolist(), flow3m.tolist() Q12 = Q13 = Q24 = Q34 = Q35 = Q46 = Q56 = Q57 = Q67 = 0 Q21 = Q31 = Q42 = Q43 = Q53 = Q64 = Q65 = Q75 = Q76 = 0 #图矩阵化 def graph2adjacent_matrix(graph): vnum = len(graph) dict = {'1':0,'2':1,'3':2,'4':3,'5':4,'6':5,'7':6} adjacent_matrix = [[0 if row==col else float('inf') for col in range(vnum)] for row in range(vnum)] vertices = graph.keys() for vertex in vertices: for edge in graph[vertex]: w,u,v = edge adjacent_matrix[dict.get(u)][dict.get(v)]=w return adjacent_matrix #floyd算法 def floyd(adjacent_matrix): vnum = len(adjacent_matrix) a = [[adjacent_matrix[row][col] for col in range(vnum)] for row in range(vnum)] nvertex = [[-1 if adjacent_matrix[row][col]==float('inf') else col for col in range(vnum)] for row in range(vnum)] for k in range(vnum): for i in range(vnum): for j in range(vnum): if a[i][j]>a[i][k]+a[k][j]: a[i][j]=a[i][k]+a[k][j] nvertex[i][j] = nvertex[i][k] return nvertex, a #判断最短路径 def route(allroute,nvertex): for i in allroute.keys(): sp = int(i[5:6]) dp = int(i[:-2:-1]) allroute[i].append(sp) while True: if nvertex[allroute[i][-1]-1][dp-1] != dp: allroute[i].append(nvertex[allroute[i][-1]-1][dp-1]) else: allroute[i].append(dp) break return allroute #创建路段流量矩阵 allflow = [[], [0,0,Q12,Q13], [0,Q21,0,0,Q24], [0,Q31,0,0,Q34,Q35], [0,0,Q42,Q43,0,0,Q46], [0,0,0,Q53,0,0,Q56,Q57], [0,0,0,0,Q64,Q65,0,Q67], [0,0,0,0,0,Q75,Q76]] #3次循环分配 time=1 flows=[flow1,flow2,flow3] for flow in flows: #出行时间输入 time13 = 5 time35 = 4 time57 = 3 time24 = 2 time67 = 1.5 time12 = 3 + 0.02 * (allflow[1][2]+allflow[2][1]) time46 = 3 + 0.02 * (allflow[4][6]+allflow[6][4]) time34 = 1.5 + 0.06 * (allflow[4][3]+allflow[3][4]) time56 = 0.5 + 0.06 * (allflow[5][6]+allflow[6][5]) #图输入 graph = {'1': [(time12, '1', '2'), (time13, '1', '3')], '2': [(time12, '2', '1'), (time24, '2', '4')], '3': [(time13, '3', '1'), (time34, '3', '4'), (time35, '3', '5')], '4': [(time24, '4', '2'), (time34, '4', '3'), (time46,'4','6')], '5': [(time35, '5', '3'), (time56, '5', '6'), (time57, '5', '7')], '6': [(time46, '6', '4'), (time56, '6', '5'), (time67, '6', '7')], '7': [(time57, '7', '5'), (time67, '7', '6')]} adjacent_matrix = graph2adjacent_matrix(graph) nvertex, a = floyd(adjacent_matrix) allroute = {'route1-4':[], 'route1-5':[], 'route1-7':[], 'route4-5':[], 'route4-7':[], 'route5-7':[], 'route7-5':[], 'route5-4':[], 'route7-4':[], 'route4-1':[], 'route5-1':[], 'route7-1':[]} #输出最短路径 for i in range(len(nvertex)): for j in range(len(nvertex[i])): nvertex[i][j] += 1 route(allroute,nvertex) print('第' + str(time) + '次分配确定的OD点对间的最短路径如下:\n') for i in allroute.items(): print(i) print() #分配流量 for i in allroute.values(): for j in range(len(i)-1): allflow[i[j]][i[j+1]] += flow[i[0]][i[-1]] #输出各路段流量 print('第' + str(time) + '次分配后各路段的流量如下:\n') x = 0 for i in range(len(allflow)): for j in range(len(allflow[i])): if allflow[i][j] !=0: st='Q'+str(i)+'-'+str(j)+'='+str(int(allflow[i][j])) print('{:<15}'.format(st),end='') x += 1 if x%2 == 0: print() print('-'*50) time+=1 print('注:\n routei-j表示点i与点j间的最短路径,两个方向均输出\n'+ ' 但因本题中各路段均为双向,也可视为不具有方向性\n'+ ' 例:(\'route1-4\', [1, 2, 4])表示点1到点4的最短路径为1-2-4\n'+ ' 则点4到点1的最短路径为4-2-1\n\n' ' Qi-j表示连接点i与点j的路段上所分配的流量,具有方向性\n'+ ' 没有出现的路段分配流量为0\n'+ ' 例:Q1-2=791 表示此路段点1到点2方向的流量为785\n'+ ' Q2-1=750 表示此路段点2到点1方向的流量为750') ``` # 2.b容量限制-增量加载法多路径分配法.py ```python #OD分布流量矩阵输入 from numpy import * flowm = mat([[0,0,0,0,0,0,0,0], [0,0,0,0,350,400,0,500], [0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0], [0,300,0,0,0,100,0,350], [0,400,0,0,200,0,0,700], [0,0,0,0,0,0,0,0], [0,500,0,0,350,700,0,0]]) flow1m = 0.6*flowm flow2m = 0.4*flowm flow1, flow2 = flow1m.tolist(), flow2m.tolist() Q12 = Q13 = Q24 = Q34 = Q35 = Q46 = Q56 = Q57 = Q67 = 0 Q21 = Q31 = Q42 = Q43 = Q53 = Q64 = Q65 = Q75 = Q76 = 0 #图矩阵化 def graph2adjacent_matrix(graph): vnum = len(graph) dict = {'1':0,'2':1,'3':2,'4':3,'5':4,'6':5,'7':6} adjacent_matrix = [[0 if row==col else float('inf') for col in range(vnum)] for row in range(vnum)] vertices = graph.keys() for vertex in vertices: for edge in graph[vertex]: w,u,v = edge adjacent_matrix[dict.get(u)][dict.get(v)]=w return adjacent_matrix #floyd算法 def floyd(adjacent_matrix): vnum = len(adjacent_matrix) a = [[adjacent_matrix[row][col] for col in range(vnum)] for row in range(vnum)] nvertex = [[-1 if adjacent_matrix[row][col]==float('inf') else col for col in range(vnum)] for row in range(vnum)] for k in range(vnum): for i in range(vnum): for j in range(vnum): if a[i][j]>a[i][k]+a[k][j]: a[i][j]=a[i][k]+a[k][j] nvertex[i][j] = nvertex[i][k] return nvertex, a #判断有效路径 def route(nvertex,a,graph,validroute): for i in validroute.keys(): sp = int(i[5:6]) dp = int(i[:-2:-1]) for j in graph[str(sp)]: if a[sp-1][dp-1] >= a[int(j[-1])-1][dp-1]: if dp != int(j[-1]): validroute[i].append( [sp, int(j[-1])] ) while True: if nvertex[ validroute[i][-1][-1]-1 ] [dp-1] != dp: validroute[i][-1].append(nvertex[ validroute[i][-1][-1]-1 ] [dp-1]) else: validroute[i][-1].append(dp) break validroute[i][-1].append([(a[int(j[-1])-1][dp-1]+a[sp-1][int(j[-1])-1])]) return validroute #计算流入率 from numpy import* def pk(validroute): for i in validroute.values(): length=[] summary=[] index=[] for j in i: length.append(j[-1][-1]) for k in length: ex=exp(-3.3*k/mean(length)) summary.append(ex) for l in summary: pk=round(l/sum(summary),3) index.append(pk) for m in range(len(index)): i[m][-1].append(index[m]) return validroute #创建路段流量矩阵 allflow = [[], [0,0,Q12,Q13], [0,Q21,0,0,Q24], [0,Q31,0,0,Q34,Q35], [0,0,Q42,Q43,0,0,Q46], [0,0,0,Q53,0,0,Q56,Q57], [0,0,0,0,Q64,Q65,0,Q67], [0,0,0,0,0,Q75,Q76]] #2次循环分配 time=1 flows=[flow1,flow2] for flow in flows: #出行时间输入 time13 = 5 time35 = 4 time57 = 3 time24 = 2 time67 = 1.5 time12 = 3 + round(0.02 * (allflow[1][2]+allflow[2][1]),1) time46 = 3 + round(0.02 * (allflow[4][6]+allflow[6][4]),1) time34 = 1.5 + round(0.06 * (allflow[4][3]+allflow[3][4]),1) time56 = 0.5 + round(0.06 * (allflow[5][6]+allflow[6][5]),1) #图输入 graph = {'1': [(time12, '1', '2'), (time13, '1', '3')], '2': [(time12, '2', '1'), (time24, '2', '4')], '3': [(time13, '3', '1'), (time34, '3', '4'), (time35, '3', '5')], '4': [(time24, '4', '2'), (time34, '4', '3'), (time46,'4','6')], '5': [(time35, '5', '3'), (time56, '5', '6'), (time57, '5', '7')], '6': [(time46, '6', '4'), (time56, '6', '5'), (time67, '6', '7')], '7': [(time57, '7', '5'), (time67, '7', '6')]} adjacent_matrix = graph2adjacent_matrix(graph) nvertex, a = floyd(adjacent_matrix) validroute = {'route1-4':[], 'route1-5':[], 'route1-7':[], 'route4-5':[], 'route4-7':[], 'route5-7':[], 'route7-5':[], 'route5-4':[], 'route7-4':[], 'route4-1':[], 'route5-1':[], 'route7-1':[]} #输出有效路径 for i in range(len(nvertex)): for j in range(len(nvertex[i])): nvertex[i][j] += 1 route(nvertex,a,graph,validroute) pk(validroute) print('第' + str(time) + '次分配确定的OD点对间的有效路径如下:\n') for i in validroute.items(): print(i) print() #分配流量 for i in validroute.values(): for j in i: for k in range(len(j)-2): allflow[j[k]][j[k+1]] += int(round(flow[j[0]][j[-2]]*j[-1][-1],0)) #输出各路段流量 print('第' + str(time) + '次分配后各路段的流量如下:\n') x = 0 for i in range(len(allflow)): for j in range(len(allflow[i])): if allflow[i][j] !=0: st='Q'+str(i)+'-'+str(j)+'='+str(int(allflow[i][j])) print('{:<15}'.format(st),end='') x += 1 if x%2 == 0: print() print('\n'+'-'*80) time+=1 print('注:\n routei-j表示点i与点j间的有效路径\n'+ ' 例:(\'route1-4\', [[1, 2, 4, [25.5, 0.374]], [1, 3, 4, [21.8, 0.626]]])\n'+ ' 表示点1到点4的有效路径有两条,分别为1-2-4,1-3-4\n'+ ' 1-2-4路径长度为25.5,流入率为0.374\n'+ ' 1-3-4路径长度为21.8,流入率为0.626\n\n'+ ' Qi-j表示连接点i与点j的路段上所分配的流量,具有方向性\n'+ ' 没有出现的路段分配流量为0\n'+ ' 例:Q1-2=547 表示此路段点1到点2方向的流量为516\n'+ ' Q2-1=558 表示此路段点2到点1方向的流量为558') ``` # 2.c逐次平均法.py ```python #OD分布流量矩阵输入 from numpy import * flowm = mat([[0,0,0,0,0,0,0,0], [0,0,0,0,350,400,0,500], [0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0], [0,300,0,0,0,100,0,350], [0,400,0,0,200,0,0,700], [0,0,0,0,0,0,0,0], [0,500,0,0,350,700,0,0]]) flow=flowm.tolist() Q12 = Q13 = Q24 = Q34 = Q35 = Q46 = Q56 = Q57 = Q67 = 0 Q21 = Q31 = Q42 = Q43 = Q53 = Q64 = Q65 = Q75 = Q76 = 0 #图矩阵化 def graph2adjacent_matrix(graph): vnum = len(graph) dict = {'1':0,'2':1,'3':2,'4':3,'5':4,'6':5,'7':6} adjacent_matrix = [[0 if row==col else float('inf') for col in range(vnum)] for row in range(vnum)] vertices = graph.keys() for vertex in vertices: for edge in graph[vertex]: w,u,v = edge adjacent_matrix[dict.get(u)][dict.get(v)]=w return adjacent_matrix #Floyd算法 def floyd(adjacent_matrix): vnum = len(adjacent_matrix) a = [[adjacent_matrix[row][col] for col in range(vnum)] for row in range(vnum)] nvertex = [[-1 if adjacent_matrix[row][col]==float('inf') else col for col in range(vnum)] for row in range(vnum)] for k in range(vnum): for i in range(vnum): for j in range(vnum): if a[i][j]>a[i][k]+a[k][j]: a[i][j]=a[i][k]+a[k][j] nvertex[i][j] = nvertex[i][k] return nvertex, a #判断最短路径 def route(allroute,nvertex): for i in allroute.keys(): sp = int(i[5:6]) dp = int(i[:-2:-1]) allroute[i].append(sp) while True: if nvertex[allroute[i][-1]-1][dp-1] != dp: allroute[i].append(nvertex[allroute[i][-1]-1][dp-1]) else: allroute[i].append(dp) break return allroute #创建路段流量矩阵 x = [[], [0,0,Q12,Q13], [0,Q21,0,0,Q24], [0,Q31,0,0,Q34,Q35], [0,0,Q42,Q43,0,0,Q46], [0,0,0,Q53,0,0,Q56,Q57], [0,0,0,0,Q64,Q65,0,Q67], [0,0,0,0,0,Q75,Q76]] nx = [[], [0,0,Q12,Q13], [0,Q21,0,0,Q24], [0,Q31,0,0,Q34,Q35], [0,0,Q42,Q43,0,0,Q46], [0,0,0,Q53,0,0,Q56,Q57], [0,0,0,0,Q64,Q65,0,Q67], [0,0,0,0,0,Q75,Q76]] n=1 #Step-初始化 #出行时间输入 time13 = 5 time35 = 4 time57 = 3 time24 = 2 time67 = 1.5 time12 = 3 time46 = 3 time34 = 1.5 time56 = 0.5 #图输入 graph = {'1': [(time12, '1', '2'), (time13, '1', '3')], '2': [(time12, '2', '1'), (time24, '2', '4')], '3': [(time13, '3', '1'), (time34, '3', '4'), (time35, '3', '5')], '4': [(time24, '4', '2'), (time34, '4', '3'), (time46,'4','6')], '5': [(time35, '5', '3'), (time56, '5', '6'), (time57, '5', '7')], '6': [(time46, '6', '4'), (time56, '6', '5'), (time67, '6', '7')], '7': [(time57, '7', '5'), (time67, '7', '6')]} adjacent_matrix = graph2adjacent_matrix(graph) nvertex, a = floyd(adjacent_matrix) xroute = {'route1-4':[], 'route1-5':[], 'route1-7':[], 'route4-5':[], 'route4-7':[], 'route5-7':[], 'route7-5':[], 'route5-4':[], 'route7-4':[], 'route4-1':[], 'route5-1':[], 'route7-1':[]} #判断初始流量最短路径 for i in range(len(nvertex)): for j in range(len(nvertex[i])): nvertex[i][j] += 1 route(xroute,nvertex) #分配初始流量 for i in xroute.values(): for j in range(len(i)-1): x[i[j]][i[j+1]] = flow[i[0]][i[-1]] print('初始分配的各路段的流量(x0)如下:\n') p=0 for i in range(len(x)): for j in range(len(x[i])): if x[i][j] != 0: st='Q'+str(i)+'-'+str(j)+'='+str(int(x[i][j])) print('{:<15}'.format(st),end='') p += 1 if p%2 == 0: print() print('-'*40) while True: #Step1-更新 time12 = 3 + 0.02 * (x[1][2]+x[2][1]) time46 = 3 + 0.02 * (x[4][6]+x[6][4]) time34 = 1.5 + 0.06 * (x[4][3]+x[3][4]) time56 = 0.5 + 0.06 * (x[5][6]+x[6][5]) #Step2-网络加载 graph = {'1': [(time12, '1', '2'), (time13, '1', '3')], '2': [(time12, '2', '1'), (time24, '2', '4')], '3': [(time13, '3', '1'), (time34, '3', '4'), (time35, '3', '5')], '4': [(time24, '4', '2'), (time34, '4', '3'), (time46,'4','6')], '5': [(time35, '5', '3'), (time56, '5', '6'), (time57, '5', '7')], '6': [(time46, '6', '4'), (time56, '6', '5'), (time67, '6', '7')], '7': [(time57, '7', '5'), (time67, '7', '6')]} yroute = {'route1-4':[], 'route1-5':[], 'route1-7':[], 'route4-5':[], 'route4-7':[], 'route5-7':[], 'route7-5':[], 'route5-4':[], 'route7-4':[], 'route4-1':[], 'route5-1':[], 'route7-1':[]} adjacent_matrix = graph2adjacent_matrix(graph) nvertex, a = floyd(adjacent_matrix) #判断附加流量最短路径 for i in range(len(nvertex)): for j in range(len(nvertex[i])): nvertex[i][j] += 1 route(yroute,nvertex) y = [[], [0,0,Q12,Q13], [0,Q21,0,0,Q24], [0,Q31,0,0,Q34,Q35], [0,0,Q42,Q43,0,0,Q46], [0,0,0,Q53,0,0,Q56,Q57], [0,0,0,0,Q64,Q65,0,Q67], [0,0,0,0,0,Q75,Q76]] #分配附加流量 for i in yroute.values(): for j in range(len(i)-1): y[i[j]][i[j+1]] += flow[i[0]][i[-1]] #Step3-逐次平均 dif=[] for i in range(len(x)): for j in range(len(x[i])): nx[i][j]=(1-1/n)*x[i][j]+1/n*y[i][j] dif.append(abs(nx[i][j]-x[i][j])) print('第' + str(n) + '次分配的各路段的流量(x' + str(n) + ')如下:\n') p=0 for i in range(len(nx)): for j in range(len(nx[i])): if nx[i][j] != 0: st='Q'+str(i)+'-'+str(j)+'='+str(int(nx[i][j])) print('{:<15}'.format(st),end='') p += 1 if p%2 == 0: print() print() #Step4-收敛性检查 if max(dif)<=5: print('满足收敛条件\n'+'-'*40) break else: for i in range(len(x)): for j in range(len(x[i])): x[i][j] = nx[i][j] n += 1 print('不满足收敛条件\n'+'-'*40) print('注:\n '+ 'Qi-j表示连接点i与点j的路段上所分配的流量,具有方向性\n'+ ' 没有出现的路段分配流量为0\n'+ ' 例:Q1-2=377 表示此路段点1到点2方向的流量为380\n'+ ' Q2-1=330 表示此路段点2到点1方向的流量为333') ``` # 优化改进后的代码 ## 2.a 面向对象优化 ```python import numpy as np class TrafficFlowDistribution: def __init__(self): self.flowm = np.mat([[0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 350, 400, 0, 500], [0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0], [0, 300, 0, 0, 0, 100, 0, 350], [0, 400, 0, 0, 200, 0, 0, 700], [0, 0, 0, 0, 0, 0, 0, 0], [0, 500, 0, 0, 350, 700, 0, 0]]) self.flow1m = 0.6 * self.flowm self.flow2m = 0.3 * self.flowm self.flow3m = 0.1 * self.flowm self.flow1, self.flow2, self.flow3 = ( self.flow1m.astype(int).tolist(), self.flow2m.astype(int).tolist(), self.flow3m.astype(int).tolist() ) #图矩阵化 def graph2adjacent_matrix(self,graph): vnum = len(graph) dict = {'1':0,'2':1,'3':2,'4':3,'5':4,'6':5,'7':6} adjacent_matrix = [[0 if row==col else float('inf') for col in range(vnum)] for row in range(vnum)] vertices = graph.keys() for vertex in vertices: for edge in graph[vertex]: w,u,v = edge adjacent_matrix[dict.get(u)][dict.get(v)]=w return adjacent_matrix #floyd算法 def floyd(self,adjacent_matrix): vnum = len(adjacent_matrix) a = [[adjacent_matrix[row][col] for col in range(vnum)] for row in range(vnum)] nvertex = [[-1 if adjacent_matrix[row][col]==float('inf') else col for col in range(vnum)] for row in range(vnum)] for k in range(vnum): for i in range(vnum): for j in range(vnum): if a[i][j]>a[i][k]+a[k][j]: a[i][j]=a[i][k]+a[k][j] nvertex[i][j] = nvertex[i][k] return nvertex, a #判断最短路径 def route(self,allroute,nvertex): for i in allroute.keys(): sp = int(i[5:6]) dp = int(i[:-2:-1]) allroute[i].append(sp) while True: if nvertex[allroute[i][-1]-1][dp-1] != dp: allroute[i].append(nvertex[allroute[i][-1]-1][dp-1]) else: allroute[i].append(dp) break return allroute def distribute_traffic_flow(self): Q12 = Q13 = Q24 = Q34 = Q35 = Q46 = Q56 = Q57 = Q67 = 0 Q21 = Q31 = Q42 = Q43 = Q53 = Q64 = Q65 = Q75 = Q76 = 0 #创建路段流量矩阵 self.allflow = [[], [0,0,Q12,Q13], [0,Q21,0,0,Q24], [0,Q31,0,0,Q34,Q35], [0,0,Q42,Q43,0,0,Q46], [0,0,0,Q53,0,0,Q56,Q57], [0,0,0,0,Q64,Q65,0,Q67], [0,0,0,0,0,Q75,Q76]] #3次循环分配 time=1 flows=[self.flow1,self.flow2,self.flow3] for flow in flows: #出行时间输入 time13 = 5 time35 = 4 time57 = 3 time24 = 2 time67 = 1.5 time12 = 3 + 0.02 * (self.allflow[1][2]+self.allflow[2][1]) time46 = 3 + 0.02 * (self.allflow[4][6]+self.allflow[6][4]) time34 = 1.5 + 0.06 * (self.allflow[4][3]+self.allflow[3][4]) time56 = 0.5 + 0.06 * (self.allflow[5][6]+self.allflow[6][5]) #图输入 graph = {'1': [(time12, '1', '2'), (time13, '1', '3')], '2': [(time12, '2', '1'), (time24, '2', '4')], '3': [(time13, '3', '1'), (time34, '3', '4'), (time35, '3', '5')], '4': [(time24, '4', '2'), (time34, '4', '3'), (time46,'4','6')], '5': [(time35, '5', '3'), (time56, '5', '6'), (time57, '5', '7')], '6': [(time46, '6', '4'), (time56, '6', '5'), (time67, '6', '7')], '7': [(time57, '7', '5'), (time67, '7', '6')]} adjacent_matrix = self.graph2adjacent_matrix(graph) nvertex, a = self.floyd(adjacent_matrix) allroute = {'route1-4':[], 'route1-5':[], 'route1-7':[], 'route4-5':[], 'route4-7':[], 'route5-7':[], 'route7-5':[], 'route5-4':[], 'route7-4':[], 'route4-1':[], 'route5-1':[], 'route7-1':[]} #输出最短路径 for i in range(len(nvertex)): for j in range(len(nvertex[i])): nvertex[i][j] += 1 self.route(allroute,nvertex) print('第' + str(time) + '次分配确定的OD点对间的最短路径如下:\n') for i in allroute.items(): print(i) print() #分配流量 for i in allroute.values(): for j in range(len(i)-1): self.allflow[i[j]][i[j+1]] += flow[i[0]][i[-1]] #输出各路段流量 print('第' + str(time) + '次分配后各路段的流量如下:\n') x = 0 for i in range(len(self.allflow)): for j in range(len(self.allflow[i])): if self.allflow[i][j] !=0: st='Q'+str(i)+'-'+str(j)+'='+str(int(self.allflow[i][j])) print('{:<15}'.format(st),end='') x += 1 if x%2 == 0: print() print('-'*50) time+=1 if __name__ == "__main__": traffic_distribution = TrafficFlowDistribution() traffic_distribution.distribute_traffic_flow() print('注:\n routei-j表示点i与点j间的最短路径,两个方向均输出\n'+ ' 但因本题中各路段均为双向,也可视为不具有方向性\n'+ ' 例:(\'route1-4\', [1, 2, 4])表示点1到点4的最短路径为1-2-4\n'+ ' 则点4到点1的最短路径为4-2-1\n\n' ' Qi-j表示连接点i与点j的路段上所分配的流量,具有方向性\n'+ ' 没有出现的路段分配流量为0\n'+ ' 例:Q1-2=791 表示此路段点1到点2方向的流量为785\n'+ ' Q2-1=750 表示此路段点2到点1方向的流量为750') ``` ## 2.b while循环替换for ```python import numpy as np class TrafficFlowDistribution: def __init__(self): self.flowm = np.mat([[0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 350, 400, 0, 500], [0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0], [0, 300, 0, 0, 0, 100, 0, 350], [0, 400, 0, 0, 200, 0, 0, 700], [0, 0, 0, 0, 0, 0, 0, 0], [0, 500, 0, 0, 350, 700, 0, 0]]) self.flow1m = 0.6 * self.flowm self.flow2m = 0.4 * self.flowm self.flow1, self.flow2 = ( self.flow1m.astype(int).tolist(), self.flow2m.astype(int).tolist() ) #图矩阵化 def graph2adjacent_matrix(self, graph): vnum = len(graph) dict_mapping = {'1': 0, '2': 1, '3': 2, '4': 3, '5': 4, '6': 5, '7': 6} adjacent_matrix = [[0 if row == col else float('inf') for col in range(vnum)] for row in range(vnum)] vertices = graph.keys() vertices_iter = iter(vertices) while True: try: vertex = next(vertices_iter) edges_iter = iter(graph[vertex]) while True: try: edge = next(edges_iter) w, u, v = edge adjacent_matrix[dict_mapping[u]][dict_mapping[v]] = w except StopIteration: break except StopIteration: break return adjacent_matrix #floyd算法 def floyd(self, adjacent_matrix): vnum = len(adjacent_matrix) a = [[adjacent_matrix[row][col] for col in range(vnum)] for row in range(vnum)] nvertex = [[-1 if adjacent_matrix[row][col] == float('inf') else col for col in range(vnum)] for row in range(vnum)] k = 0 while k < vnum: i = 0 while i < vnum: j = 0 while j < vnum: if a[i][j] > a[i][k] + a[k][j]: a[i][j] = a[i][k] + a[k][j] nvertex[i][j] = nvertex[i][k] j += 1 i += 1 k += 1 return nvertex, a #判断有效路径 def route(self,nvertex,a,graph,validroute): for i in validroute.keys(): sp = int(i[5:6]) dp = int(i[:-2:-1]) for j in graph[str(sp)]: if a[sp-1][dp-1] >= a[int(j[-1])-1][dp-1]: if dp != int(j[-1]): validroute[i].append( [sp, int(j[-1])] ) while True: if nvertex[ validroute[i][-1][-1]-1 ] [dp-1] != dp: validroute[i][-1].append(nvertex[ validroute[i][-1][-1]-1 ] [dp-1]) else: validroute[i][-1].append(dp) break validroute[i][-1].append([(a[int(j[-1])-1][dp-1]+a[sp-1][int(j[-1])-1])]) return validroute #计算流入率 def pk(self, validroute): validroute_values = list(validroute.values()) i = 0 while i < len(validroute_values): i_values = validroute_values[i] length = [] summary = [] index = [] j = 0 while j < len(i_values): length.append(i_values[j][-1][-1]) j += 1 k = 0 while k < len(length): ex = np.exp(-3.3 * length[k] / np.mean(length)) summary.append(ex) k += 1 l = 0 while l < len(summary): pk = round(summary[l] / sum(summary), 3) index.append(pk) l += 1 m = 0 while m < len(index): i_values[m][-1].append(index[m]) m += 1 i += 1 return validroute def distribute_traffic_flow(self): Q12 = Q13 = Q24 = Q34 = Q35 = Q46 = Q56 = Q57 = Q67 = Q21 = Q31 = Q42 = Q43 = Q53 = Q64 = Q65 = Q75 = Q76 = 0 #创建路段流量矩阵 self.allflow = [[], [0,0,Q12,Q13], [0,Q21,0,0,Q24], [0,Q31,0,0,Q34,Q35], [0,0,Q42,Q43,0,0,Q46], [0,0,0,Q53,0,0,Q56,Q57], [0,0,0,0,Q64,Q65,0,Q67], [0,0,0,0,0,Q75,Q76]] #2次循环分配 time=1 flows=[self.flow1,self.flow2] for flow in flows: #出行时间输入 time13 = 5 time35 = 4 time57 = 3 time24 = 2 time67 = 1.5 time12 = 3 + round(0.02 * (self.allflow[1][2]+self.allflow[2][1])) time46 = 3 + round(0.02 * (self.allflow[4][6]+self.allflow[6][4])) time34 = 1.5 + round(0.06 * (self.allflow[4][3]+self.allflow[3][4])) time56 = 0.5 + round(0.06 * (self.allflow[5][6]+self.allflow[6][5])) #图输入 graph = {'1': [(time12, '1', '2'), (time13, '1', '3')], '2': [(time12, '2', '1'), (time24, '2', '4')], '3': [(time13, '3', '1'), (time34, '3', '4'), (time35, '3', '5')], '4': [(time24, '4', '2'), (time34, '4', '3'), (time46,'4','6')], '5': [(time35, '5', '3'), (time56, '5', '6'), (time57, '5', '7')], '6': [(time46, '6', '4'), (time56, '6', '5'), (time67, '6', '7')], '7': [(time57, '7', '5'), (time67, '7', '6')]} adjacent_matrix = self.graph2adjacent_matrix(graph) nvertex, a = self.floyd(adjacent_matrix) validroute = {'route1-4':[], 'route1-5':[], 'route1-7':[], 'route4-5':[], 'route4-7':[], 'route5-7':[], 'route7-5':[], 'route5-4':[], 'route7-4':[], 'route4-1':[], 'route5-1':[], 'route7-1':[]} #输出有效路径 for i in range(len(nvertex)): for j in range(len(nvertex[i])): nvertex[i][j] += 1 self.route(nvertex,a,graph,validroute) self.pk(validroute) print('第' + str(time) + '次分配确定的OD点对间的有效路径如下:\n') for i in validroute.items(): print(i) print() #分配流量 for i in validroute.values(): for j in i: for k in range(len(j)-2): self.allflow[j[k]][j[k+1]] += int(round(flow[j[0]][j[-2]]*j[-1][-1],0)) #输出各路段流量 print('第' + str(time) + '次分配后各路段的流量如下:\n') x = 0 i = 0 while i < len(self.allflow): j = 0 while j < len(self.allflow[i]): if self.allflow[i][j] != 0: st = 'Q' + str(i) + '-' + str(j) + '=' + str(int(self.allflow[i][j])) print('{:<15}'.format(st), end='') x += 1 if x % 2 == 0: print() j += 1 i += 1 print('\n'+'-'*80) time+=1 if __name__ == "__main__": traffic_distribution = TrafficFlowDistribution() traffic_distribution.distribute_traffic_flow() print('注:\n routei-j表示点i与点j间的有效路径\n'+ ' 例:(\'route1-4\', [[1, 2, 4, [25.5, 0.374]], [1, 3, 4, [21.8, 0.626]]])\n'+ ' 表示点1到点4的有效路径有两条,分别为1-2-4,1-3-4\n'+ ' 1-2-4路径长度为25.5,流入率为0.374\n'+ ' 1-3-4路径长度为21.8,流入率为0.626\n\n'+ ' Qi-j表示连接点i与点j的路段上所分配的流量,具有方向性\n'+ ' 没有出现的路段分配流量为0\n'+ ' 例:Q1-2=547 表示此路段点1到点2方向的流量为516\n'+ ' Q2-1=558 表示此路段点2到点1方向的流量为558') ``` ## 2.c while循环替换for ```python import numpy as np class TrafficFlowDistribution: def __init__(self): self.flowm = np.mat([[0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 350, 400, 0, 500], [0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0], [0, 300, 0, 0, 0, 100, 0, 350], [0, 400, 0, 0, 200, 0, 0, 700], [0, 0, 0, 0, 0, 0, 0, 0], [0, 500, 0, 0, 350, 700, 0, 0]]) self.flow=self.flowm.tolist() #图矩阵化 def graph2adjacent_matrix(self, graph): vnum = len(graph) dict_mapping = {'1': 0, '2': 1, '3': 2, '4': 3, '5': 4, '6': 5, '7': 6} adjacent_matrix = [[0 if row == col else float('inf') for col in range(vnum)] for row in range(vnum)] vertices = graph.keys() vertices_iter = iter(vertices) while True: try: vertex = next(vertices_iter) edges_iter = iter(graph[vertex]) while True: try: edge = next(edges_iter) w, u, v = edge adjacent_matrix[dict_mapping[u]][dict_mapping[v]] = w except StopIteration: break except StopIteration: break return adjacent_matrix #floyd算法 def floyd(self, adjacent_matrix): vnum = len(adjacent_matrix) a = [[adjacent_matrix[row][col] for col in range(vnum)] for row in range(vnum)] nvertex = [[-1 if adjacent_matrix[row][col] == float('inf') else col for col in range(vnum)] for row in range(vnum)] k = 0 while k < vnum: i = 0 while i < vnum: j = 0 while j < vnum: if a[i][j] > a[i][k] + a[k][j]: a[i][j] = a[i][k] + a[k][j] nvertex[i][j] = nvertex[i][k] j += 1 i += 1 k += 1 return nvertex, a #判断最短路径 def route(self, allroute, nvertex): keys = list(allroute.keys()) i = 0 while i < len(keys): i_key = keys[i] sp = int(i_key[5:6]) dp = int(i_key[:-2:-1]) allroute[i_key].append(sp) while nvertex[allroute[i_key][-1] - 1][dp - 1] != dp: allroute[i_key].append(nvertex[allroute[i_key][-1] - 1][dp - 1]) allroute[i_key].append(dp) i += 1 return allroute def distribute_traffic_flow(self): Q12 = Q13 = Q24 = Q34 = Q35 = Q46 = Q56 = Q57 = Q67 = 0 Q21 = Q31 = Q42 = Q43 = Q53 = Q64 = Q65 = Q75 = Q76 = 0 #创建路段流量矩阵 x = [[], [0,0,Q12,Q13], [0,Q21,0,0,Q24], [0,Q31,0,0,Q34,Q35], [0,0,Q42,Q43,0,0,Q46], [0,0,0,Q53,0,0,Q56,Q57], [0,0,0,0,Q64,Q65,0,Q67], [0,0,0,0,0,Q75,Q76]] nx = [[], [0,0,Q12,Q13], [0,Q21,0,0,Q24], [0,Q31,0,0,Q34,Q35], [0,0,Q42,Q43,0,0,Q46], [0,0,0,Q53,0,0,Q56,Q57], [0,0,0,0,Q64,Q65,0,Q67], [0,0,0,0,0,Q75,Q76]] n=1 #Step-初始化 #出行时间输入 time13 = 5 time35 = 4 time57 = 3 time24 = 2 time67 = 1.5 time12 = 3 time46 = 3 time34 = 1.5 time56 = 0.5 #图输入 graph = {'1': [(time12, '1', '2'), (time13, '1', '3')], '2': [(time12, '2', '1'), (time24, '2', '4')], '3': [(time13, '3', '1'), (time34, '3', '4'), (time35, '3', '5')], '4': [(time24, '4', '2'), (time34, '4', '3'), (time46,'4','6')], '5': [(time35, '5', '3'), (time56, '5', '6'), (time57, '5', '7')], '6': [(time46, '6', '4'), (time56, '6', '5'), (time67, '6', '7')], '7': [(time57, '7', '5'), (time67, '7', '6')]} adjacent_matrix = self.graph2adjacent_matrix(graph) nvertex, a = self.floyd(adjacent_matrix) xroute = {'route1-4':[], 'route1-5':[], 'route1-7':[], 'route4-5':[], 'route4-7':[], 'route5-7':[], 'route7-5':[], 'route5-4':[], 'route7-4':[], 'route4-1':[], 'route5-1':[], 'route7-1':[]} #判断初始流量最短路径 for i in range(len(nvertex)): for j in range(len(nvertex[i])): nvertex[i][j] += 1 self.route(xroute,nvertex) #分配初始流量 for i in xroute.values(): for j in range(len(i)-1): x[i[j]][i[j+1]] = self.flow[i[0]][i[-1]] print('初始分配的各路段的流量(x0)如下:\n') p=0 for i in range(len(x)): for j in range(len(x[i])): if x[i][j] != 0: st='Q'+str(i)+'-'+str(j)+'='+str(int(x[i][j])) print('{:<15}'.format(st),end='') p += 1 if p%2 == 0: print() print('-'*40) while True: #Step1-更新 time12 = 3 + 0.02 * (x[1][2]+x[2][1]) time46 = 3 + 0.02 * (x[4][6]+x[6][4]) time34 = 1.5 + 0.06 * (x[4][3]+x[3][4]) time56 = 0.5 + 0.06 * (x[5][6]+x[6][5]) #Step2-网络加载 graph = {'1': [(time12, '1', '2'), (time13, '1', '3')], '2': [(time12, '2', '1'), (time24, '2', '4')], '3': [(time13, '3', '1'), (time34, '3', '4'), (time35, '3', '5')], '4': [(time24, '4', '2'), (time34, '4', '3'), (time46,'4','6')], '5': [(time35, '5', '3'), (time56, '5', '6'), (time57, '5', '7')], '6': [(time46, '6', '4'), (time56, '6', '5'), (time67, '6', '7')], '7': [(time57, '7', '5'), (time67, '7', '6')]} yroute = {'route1-4':[], 'route1-5':[], 'route1-7':[], 'route4-5':[], 'route4-7':[], 'route5-7':[], 'route7-5':[], 'route5-4':[], 'route7-4':[], 'route4-1':[], 'route5-1':[], 'route7-1':[]} adjacent_matrix = self.graph2adjacent_matrix(graph) nvertex, a = self.floyd(adjacent_matrix) #判断附加流量最短路径 for i in range(len(nvertex)): for j in range(len(nvertex[i])): nvertex[i][j] += 1 self.route(yroute,nvertex) y = [[], [0,0,Q12,Q13], [0,Q21,0,0,Q24], [0,Q31,0,0,Q34,Q35], [0,0,Q42,Q43,0,0,Q46], [0,0,0,Q53,0,0,Q56,Q57], [0,0,0,0,Q64,Q65,0,Q67], [0,0,0,0,0,Q75,Q76]] #分配附加流量 i = 0 while i < len(yroute.values()): j = 0 i_values = list(yroute.values())[i] while j < len(i_values) - 1: y[i_values[j]][i_values[j + 1]] += self.flow[i_values[0]][i_values[-1]] j += 1 i += 1 #Step3-逐次平均 dif=[] for i in range(len(x)): for j in range(len(x[i])): nx[i][j]=(1-1/n)*x[i][j]+1/n*y[i][j] dif.append(abs(nx[i][j]-x[i][j])) print('第' + str(n) + '次分配的各路段的流量(x' + str(n) + ')如下:\n') p=0 for i in range(len(nx)): for j in range(len(nx[i])): if nx[i][j] != 0: st='Q'+str(i)+'-'+str(j)+'='+str(int(nx[i][j])) print('{:<15}'.format(st),end='') p += 1 if p%2 == 0: print() print() #Step4-收敛性检查 if max(dif)<=5: print('满足收敛条件\n'+'-'*40) break else: i = 0 while i < len(x): j = 0 while j < len(x[i]): x[i][j] = nx[i][j] j += 1 i += 1 n += 1 print('不满足收敛条件\n'+'-'*40) if __name__ == "__main__": traffic_distribution = TrafficFlowDistribution() traffic_distribution.distribute_traffic_flow() print('注:\n '+ 'Qi-j表示连接点i与点j的路段上所分配的流量,具有方向性\n'+ ' 没有出现的路段分配流量为0\n'+ ' 例:Q1-2=377 表示此路段点1到点2方向的流量为380\n'+ ' Q2-1=330 表示此路段点2到点1方向的流量为333') ``` 最后修改:2025 年 01 月 15 日 © 允许规范转载 打赏 赞赏作者 支付宝微信 赞 8 如果觉得我的文章对你有用,请随意赞赏