├── .vscode └── settings.json ├── DFS.py ├── DTA.py ├── OD_details.py ├── __pycache__ ├── DFS.cpython-37.pyc ├── DTA.cpython-37.pyc ├── OD_details.cpython-37.pyc ├── edge_details.cpython-37.pyc ├── generateGraph.cpython-37.pyc ├── imports.cpython-37.pyc ├── initialize.cpython-37.pyc └── start_simulation.cpython-37.pyc ├── demand.txt ├── edge_details.py ├── generateGraph.py ├── imports.py ├── initialize.py ├── main.py ├── node_modelling.py ├── start_simulation.py └── unnecessary.py /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "python.pythonPath": "c:\\Users\\rkgup\\kivy_venv\\Scripts\\python.exe", 3 | "python.linting.pylintEnabled": true, 4 | "python.linting.enabled": true 5 | } -------------------------------------------------------------------------------- /DFS.py: -------------------------------------------------------------------------------- 1 | from imports import * 2 | from initialize import * 3 | 4 | '''------------------------------------------------------------------------- 5 | ----------------FINDING THE PATHS(DEPTH FIRST SEARCH ALGORITHM)-------------- 6 | -----------------------------------------------------------------------------''' 7 | 8 | 9 | def paths(u,v,visited,path): 10 | 11 | visited[u] = True 12 | path.append(u) 13 | total_path = path[:] 14 | if(u==v): 15 | all_paths.append(total_path) 16 | else: 17 | for i in edges[u].keys(): 18 | if(visited[i]==False): 19 | paths(i,v,visited,path) 20 | path.pop() 21 | visited[u] = False 22 | 23 | def OD_dictionary(): 24 | 25 | global all_paths 26 | for i in range(1, node_count + 1): 27 | for j in range(1, node_count + 1): 28 | if (i != j and j in destination): 29 | visited = [False for i in range(0, node_count + 1)] 30 | path = [] 31 | paths(i, j, visited, path) 32 | OD_dict[i][j] = all_paths 33 | all_paths = [] 34 | 35 | '''----------------------------------------------------------- 36 | -----------------------LINK PATHS CALCULATION----------------- 37 | --------------------------------------------------------------''' 38 | 39 | def linkpath_calculation(): 40 | 41 | global link_paths,OD_dict,link_history 42 | for i in OD_dict: 43 | for j in OD_dict[i]: 44 | OD_dict[i][j].append([1 / len(OD_dict[i]), 1 / len(OD_dict[i]), 1 / len(OD_dict[i]), 1 / len(OD_dict[i])]) 45 | for i in OD_dict: 46 | for j in OD_dict[i]: 47 | index = 0 48 | for k in OD_dict[i][j]: 49 | res_list = [] 50 | if (k == [0, 0, 0, 0]): 51 | continue 52 | for f in range(0, len(k) - 1): 53 | y = k[f:f + 2] 54 | res_list.append([i for i, value in enumerate(edge_pairs) if value == y]) 55 | for element in itertools.product(*res_list): 56 | link_paths[tuple(k)] = element 57 | 58 | # Storing all the destination nodes that the vehicles in a particular link has to go in link history link 59 | for i in OD_dict: 60 | for j in OD_dict[i]: 61 | if([i,j] in OD): 62 | for k in range(len(OD_dict[i][j]) - 1): 63 | path = OD_dict[i][j][k] 64 | edge = link_paths[tuple(path)] 65 | for m in edge: 66 | if (j not in link_history[m]): 67 | link_history[m].append(j) -------------------------------------------------------------------------------- /DTA.py: -------------------------------------------------------------------------------- 1 | from initialize import * 2 | from imports import * 3 | from node_modelling import * 4 | from start_simulation import visualize 5 | 6 | 7 | '''-------------------------------------------------------------------------- 8 | ---------------------DYNAMIC TRAFFIC ASSIGNMENT---------------------------- 9 | -----------------------------------------------------------------------------''' 10 | cla = [5000,2500,1000,500] 11 | row=1 12 | def dynamic_traffic_assignment(): 13 | 14 | global density, AOnot, equi_speed, speed, flow, AO, average_speed, link_density, average_time, edge_cost, visual,row,sheet #values are made global so that it can be updated inside the function 15 | for n in range(1, 5000): # Number of iterations 16 | print("Iteration " + str(n) + " started") #Printing the corresponding iteration 17 | li = 0 # link_index 18 | for i in edge_pairs: #Iterating for each link in the network 19 | # Iterating for each cell in the corresponding link 20 | for x in range(edges[i[0]][i[1]][3] + 1): # Here edges[i[0]][i[1]][3] gives the number of cells in the corresponding link 21 | density[li][0][x], density[li][1][x], density[li][2][x], density[li][3][x] = 100,40,200,20 # Allocating initial density to the cells 22 | # Calculating area_occupancy for all the cells belonging to a particular index 23 | AO[li][x] = (area[0] * density[li][0][x] + area[1] * density[li][1][x] + area[2] * density[li][2][x] + area[3] * density[li][3][x]) / edges[i[0]][i[1]][1] 24 | 25 | if (AO[li][x] < 0.0019): #Checking if the area_occupancy is less than 0.0019 which is the lower bound 26 | AO[li][x] = 0.0019 27 | if (AO[li][x] > AOmax[0]): #Checking if the area occupancy is greater than 0.89 which is the upper bound 28 | AO[li][x] = AOmax[0] 29 | 30 | # Calculating area occupancy excluding the area occupancy for a particular class of vehicle 31 | # Here edges[i[0]][i[1]][1] gives the corresponding width of the link 32 | AOnot[li][0][x] = (area[1] * density[li][1][x] + area[2] * density[li][2][x] + area[3] *density[li][3][x]) / edges[i[0]][i[1]][1] 33 | AOnot[li][1][x] = (area[0] * density[li][0][x] + area[2] * density[li][2][x] + area[3] *density[li][3][x]) / edges[i[0]][i[1]][1] 34 | AOnot[li][2][x] = (area[1] * density[li][1][x] + area[0] * density[li][0][x] + area[3] *density[li][3][x]) / edges[i[0]][i[1]][1] 35 | AOnot[li][3][x] = (area[1] * density[li][1][x] + area[2] * density[li][2][x] + area[0] *density[li][0][x]) / edges[i[0]][i[1]][1] 36 | 37 | for c in range(4): #Iterating for all the classes of vehicles 38 | # Calculating the equilibrium speed according to the formula given 39 | equi_speed[li][c][x] = min(free_flow_speed[c], max(3.0, (free_flow_speed[c] * (1.0 - math.exp(1.0 - math.exp(jam_density[c] * (AOmax[c] / AO[li][x] - 1.0))))))) 40 | speed[li][c][x] = equi_speed[li][c][x] # Equating the speed to the quilibrium speed as the initial condition 41 | flow[li][c][x] = density[li][c][x] * speed[li][c][x] #Calculating the flow 42 | li += 1 #Updating the link_index that is the counter variable for repeating the same process for the next link 43 | 44 | current_density = [[0 for i in range(edges[i[0]][i[1]][3] + 1)] for j in range(4)] #This is to store the updated density based on the equation 45 | current_speed = [[0 for i in range(edges[i[0]][i[1]][3] + 1)] for j in range(4)] #This is to store the updated speed based on the equation 46 | for t in range(1, simtime): # Loop for iterating through the simulation time (180 in our case) 47 | li = 0 # Counter to iterate over each link 48 | for i in edge_pairs: #Iterating through each link 49 | for vclass in range(4): #Iterating for each class of vehicle 50 | if(t==1): #For 1st time interval assigning some random flows to the origin nodes toward the outgoing links to avoid math errors 51 | if i in origin: 52 | for j in outgoing_links[i]: 53 | flow[j][vclass][0] = (1/n)*cla[c] + ((n-1)/n)*cla[c] 54 | else: 55 | node_modelling(t,n,vclass) #Referring the node_modelling function and passing the time,iteration number and class of vehicle 56 | speed[li][c][0] = free_flow_speed[c] 57 | density[li][c][0] = flow[li][c][0]/speed[li][c][0] 58 | equi_speed[li][c][0] = free_flow_speed[c] 59 | 60 | # ALL CODE BELOW THIS ARE THE SAME LOGIC AS YOUR CODE 61 | for c in range(4): 62 | for x in range(1, edges[i[0]][i[1]][3]): 63 | param1 = math.exp(jam_density[c] * (AOmax[c] / AO[li][x] - 1)) 64 | param2 = math.exp(1 - param1) 65 | diffuk = -1 * (AOmax[c] * area[c] * jam_density[c] * free_flow_speed[c] * param1 * param2) / (edges[i[0]][i[1]][1] * pow(AO[li][x], 2)) 66 | diffuao = -1 * (AOmax[c] * jam_density[c] * free_flow_speed[c] * param1 * param2) / pow(AO[li][x], 2) 67 | diffuaok = ((AOmax[c] ** 2) * area[c] * (jam_density[c] ** 2) * free_flow_speed[c] * param1 * param2)/(edges[i[0]][i[1]][1] * (AO[li][x] ** 4)) - ((AOmax[c] ** 2) * area[c] * (jam_density[c] ** 2) * free_flow_speed[c] * math.exp(jam_density[c] * (AOmax[c] / AO[li][x] - 1) * 2) * param2) / (edges[i[0]][i[1]][1] * (AO[li][x] ** 5)) + (AOmax[c] * area[c] * jam_density[c] * free_flow_speed[c] * param1 * param2 * 2) / (edges[i[0]][i[1]][1] * (AO[li][x] ** 3)) 68 | propagation_speed = min(speed[li][c][x], (speed[li][c][x] + diffuao + density[li][c][x] * (diffuk + diffuaok))) 69 | current_density[c][x] = density[li][c][x] - (dt / 0.225) * (density[li][c][x] * speed[li][c][x + 1] - density[li][c][x - 1] * speed[li][c][x]) 70 | if (propagation_speed >= 0): 71 | current_speed[c][x] = speed[li][c][x] - (dt / 0.225) * speed[li][c][x] * ( 72 | speed[li][c][x] - speed[li][c][x - 1]) - (propagation_speed - speed[li][c][x]) * (diffuao * ( 73 | AOnot[li][c][x] - AOnot[li][c][x - 1]) + diffuk * (density[li][c][x] - density[li][c][x - 1])) + (dt / relaxation_time[c]) * ( 74 | equi_speed[li][c][x] - speed[li][c][x]) 75 | else: 76 | current_speed[c][x] = speed[li][c][x] - (dt / 0.225) * speed[li][c][x] * ( 77 | speed[li][c][x + 1] - speed[li][c][x]) - (propagation_speed - speed[li][c][x]) * (diffuao * ( 78 | AOnot[li][c][x + 1] - AOnot[li][c][x]) + diffuk * (density[li][c][x + 1] - density[li][c][x])) + ( 79 | dt / relaxation_time[c]) * (equi_speed[li][c][x] - speed[li][c][x]) 80 | 81 | for c in range(4): 82 | for x in range(1, edges[i[0]][i[1]][3]): 83 | 84 | density[li][c][x] = max(0, current_density[c][x]) 85 | if (current_speed[c][x] < 0): 86 | speed[li][c][x] = equi_speed[li][c][x] 87 | else: 88 | speed[li][c][x] = min(free_flow_speed[c], max(1.0, current_speed[c][x])) 89 | flow[li][c][x] = density[li][c][x] * speed[li][c][x] 90 | 91 | density[li][c][edges[i[0]][i[1]][3]] = density[li][c][edges[i[0]][i[1]][3] - 1] 92 | speed[li][c][edges[i[0]][i[1]][3]] = speed[li][c][edges[i[0]][i[1]][3] - 1] 93 | flow[li][c][edges[i[0]][i[1]][3]] = density[li][c][edges[i[0]][i[1]][3]] *speed[li][c][edges[i[0]][i[1]][3]] 94 | for x in range(1, edges[i[0]][i[1]][3] + 1): 95 | AO[li][x] = (area[0] * density[li][0][x] + area[1] * density[li][1][x] + area[2] *density[li][2][x] + area[3] * density[li][3][x]) / edges[i[0]][i[1]][1] 96 | AOnot[li][0][x] = min(AOmax[0] - area[0] * density[li][0][x] / edges[i[0]][i[1]][1], (area[1] * density[li][1][x] + area[2] * density[li][2][x] + area[3] *density[li][3][x]) / edges[i[0]][i[1]][1]) 97 | AOnot[li][1][x] = min(AOmax[0] - area[1] * density[li][1][x] / edges[i[0]][i[1]][1], (area[0] * density[li][0][x] + area[2] * density[li][2][x] + area[3] *density[li][3][x]) / edges[i[0]][i[1]][1]) 98 | AOnot[li][2][x] = min(AOmax[0] - area[2] * density[li][2][x] / edges[i[0]][i[1]][1], (area[1] * density[li][1][x] + area[0] * density[li][0][x] + area[3] *density[li][3][x]) / edges[i[0]][i[1]][1]) 99 | AOnot[li][3][x] = min(AOmax[0] - area[3] * density[li][3][x] / edges[i[0]][i[1]][1], (area[1] * density[li][1][x] + area[2] * density[li][2][x] + area[0] *density[li][0][x]) / edges[i[0]][i[1]][1]) 100 | if (AO[li][x] < 0.0019): 101 | AO[li][x] = 0.0019 102 | for c in range(4): 103 | speed[li][c][x] = free_flow_speed[c] 104 | 105 | if (AO[li][x] >= AOmax[0]): 106 | for c in range(4): 107 | speed[li][c][x] = 0 108 | AO[li][x] = AOmax[0] 109 | 110 | for c in range(4): 111 | if (AO[li][x] >= AOmax[c]): 112 | speed[li][c][x] = 0 113 | if (AO[li][x] <= 0.0019): 114 | speed[li][c][x], equi_speed[li][c][x], AO[li][x] = free_flow_speed[c], free_flow_speed[c], 0.0019 115 | else: 116 | equi_speed[li][c][x] = min(free_flow_speed[c], max(0.0, (free_flow_speed[c] * (1.0 - math.exp(1.0 - math.exp(jam_density[c] * (AOmax[c] / AO[li][x] - 1.0))))))) 117 | 118 | #Calculating the average_time for each of the links 119 | for c in range(4): 120 | for x in range(1, edges[i[0]][i[1]][3]): 121 | average_speed[li][t][c] += speed[li][c][x] 122 | link_density[li][c] += density[li][c][x] 123 | average_speed[li][t][c] = average_speed[li][t][c] / 8 124 | 125 | # If average speed of the link is greater than 1 we calculate average time dividing the length by the average speed 126 | if(average_speed[li][t][c]>1): 127 | average_time[li][t][c] = edges[i[0]][i[1]][0] / average_speed[li][t][c] 128 | # Else to avoid overflow error average time is set to infinity 129 | else: 130 | average_time[li][t][c] = sys.maxsize 131 | 132 | # FOR PRINTING THE DATA INTO EXCEL SHEET CURRENTLY ONLY FLOW IS GETTING PRINTED 133 | column = 1 134 | for j in range(1, edges[i[0]][i[1]][3]): 135 | for c in range(4): 136 | sheet.cell(row=row,column =column).value = flow[li][c][j] 137 | column+=1 138 | column+=1 139 | row+=1 140 | li+=1 141 | 142 | # FOR CALCULTING THE PATH COSTS (SUM OF COSTS OF ALL THE EDGES BELONGING TO THAT PATH) 143 | for i in link_paths: 144 | for c in range(4): 145 | cost = 0 146 | for j in range(len(link_paths[i])): 147 | cost += average_time[link_paths[i][j]][t][c] 148 | edge_cost[link_paths[i]].append(cost) 149 | visualize(visual) #GUI related 150 | root.update() #GUI related 151 | time.sleep(0.2) #Time interval for every update of the GUI in seconds..can be adjusted for visualizing slower or faster 152 | wb.save('D:\\Node_practice\\result.xlsx') #Saving the data to the excel file 153 | 154 | 155 | -------------------------------------------------------------------------------- /OD_details.py: -------------------------------------------------------------------------------- 1 | from imports import * 2 | from initialize import * 3 | from generateGraph import generate_graph 4 | 5 | ''' ------------------------------------------------------------------------------- 6 | -------------------FUNCTION TO TAKE OD DETAILS FROM THE USER----------------------- 7 | -----------------------------------------------------------------------------------''' 8 | #GUI related 9 | def OD_details(OD_,links,nodes): 10 | count = 0 11 | global param,OD_pairs,label2,flag,node_count,edge_count,average_speed,link_density,average_time 12 | x = int(links.get()) 13 | for i in OD_pairs: 14 | for j in i: 15 | j.destroy() 16 | for k in label2: 17 | k.destroy() 18 | lab1 = Label(root, text="ORIGIN") 19 | lab1.grid(row=x+8, column=5, sticky='NSEW') 20 | lab2 = Label(root, text="DESTINATION") 21 | lab2.grid(row=x+8, column=6, sticky='NSEW') 22 | label2 = [lab1,lab2] 23 | for j in range(int(OD_.get())): 24 | lab = Label(root, text = 'OD Pair '+str(j+1)) 25 | lab.grid(row = x+9+j,column = 4,sticky = 'NSEW') 26 | label2.append(lab) 27 | origin = Entry(root) 28 | origin.grid(row = x+9+j, column = 5, sticky = 'NSEW') 29 | destination = Entry(root) 30 | destination.grid(row = x+9+j, column = 6, sticky = 'NSEW') 31 | OD_pairs.append([origin,destination]) 32 | count = x+9+j 33 | edge_count = int(links.get()) 34 | node_count = int(nodes.get()) 35 | average_speed = [[[0 for i in range(classes)] for j in range(simtime)] for k in range(edge_count)] 36 | link_density = [[0 for i in range(classes)] for j in range(edge_count)] 37 | average_time = [[[0 for i in range(classes)] for j in range(simtime)] for k in range(edge_count)] 38 | submit = Button(root, text='Generate Network', fg='blue', bg='white', font=("Times New Roman", 20, "bold"),command=lambda: generate_graph(param, count)) 39 | if(flag==0): 40 | flag+=1 41 | submit.grid(row= max(count + 1,16), column=1, pady='50') -------------------------------------------------------------------------------- /__pycache__/DFS.cpython-37.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/skyrahul/DTA2020/a200cc2c88d32cd9a4d0b7a9b0d8b6a2c2975deb/__pycache__/DFS.cpython-37.pyc -------------------------------------------------------------------------------- /__pycache__/DTA.cpython-37.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/skyrahul/DTA2020/a200cc2c88d32cd9a4d0b7a9b0d8b6a2c2975deb/__pycache__/DTA.cpython-37.pyc -------------------------------------------------------------------------------- /__pycache__/OD_details.cpython-37.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/skyrahul/DTA2020/a200cc2c88d32cd9a4d0b7a9b0d8b6a2c2975deb/__pycache__/OD_details.cpython-37.pyc -------------------------------------------------------------------------------- /__pycache__/edge_details.cpython-37.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/skyrahul/DTA2020/a200cc2c88d32cd9a4d0b7a9b0d8b6a2c2975deb/__pycache__/edge_details.cpython-37.pyc -------------------------------------------------------------------------------- /__pycache__/generateGraph.cpython-37.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/skyrahul/DTA2020/a200cc2c88d32cd9a4d0b7a9b0d8b6a2c2975deb/__pycache__/generateGraph.cpython-37.pyc -------------------------------------------------------------------------------- /__pycache__/imports.cpython-37.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/skyrahul/DTA2020/a200cc2c88d32cd9a4d0b7a9b0d8b6a2c2975deb/__pycache__/imports.cpython-37.pyc -------------------------------------------------------------------------------- /__pycache__/initialize.cpython-37.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/skyrahul/DTA2020/a200cc2c88d32cd9a4d0b7a9b0d8b6a2c2975deb/__pycache__/initialize.cpython-37.pyc -------------------------------------------------------------------------------- /__pycache__/start_simulation.cpython-37.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/skyrahul/DTA2020/a200cc2c88d32cd9a4d0b7a9b0d8b6a2c2975deb/__pycache__/start_simulation.cpython-37.pyc -------------------------------------------------------------------------------- /demand.txt: -------------------------------------------------------------------------------- 1 | 972 347 810 185 2 | 972 347 810 185 3 | 972 347 810 185 4 | 972 347 810 185 5 | 972 347 810 185 6 | 972 347 810 185 7 | 972 347 810 185 8 | 972 347 810 185 9 | 972 347 810 185 10 | 972 347 810 185 11 | 972 347 810 185 12 | 972 347 810 185 13 | 972 347 810 185 14 | 972 347 810 185 15 | 972 347 810 185 16 | 1361 486 1134 259 17 | 1361 486 1134 259 18 | 1361 486 1134 259 19 | 1361 486 1134 259 20 | 1361 486 1134 259 21 | 1361 486 1134 259 22 | 1361 486 1134 259 23 | 1361 486 1134 259 24 | 1361 486 1134 259 25 | 1361 486 1134 259 26 | 1361 486 1134 259 27 | 1361 486 1134 259 28 | 1361 486 1134 259 29 | 1361 486 1134 259 30 | 1361 486 1134 259 31 | 1653 590 1377 315 32 | 1653 590 1377 315 33 | 1653 590 1377 315 34 | 1653 590 1377 315 35 | 1653 590 1377 315 36 | 1653 590 1377 315 37 | 1653 590 1377 315 38 | 1653 590 1377 315 39 | 1653 590 1377 315 40 | 1653 590 1377 315 41 | 1653 590 1377 315 42 | 1653 590 1377 315 43 | 1653 590 1377 315 44 | 1653 590 1377 315 45 | 1653 590 1377 315 46 | 1789 639 1491 341 47 | 1789 639 1491 341 48 | 1789 639 1491 341 49 | 1789 639 1491 341 50 | 1789 639 1491 341 51 | 1789 639 1491 341 52 | 1789 639 1491 341 53 | 1789 639 1491 341 54 | 1789 639 1491 341 55 | 1789 639 1491 341 56 | 1789 639 1491 341 57 | 1789 639 1491 341 58 | 1789 639 1491 341 59 | 1789 639 1491 341 60 | 1789 639 1491 341 61 | 1555 555 1296 296 62 | 1555 555 1296 296 63 | 1555 555 1296 296 64 | 1555 555 1296 296 65 | 1555 555 1296 296 66 | 1555 555 1296 296 67 | 1555 555 1296 296 68 | 1555 555 1296 296 69 | 1555 555 1296 296 70 | 1555 555 1296 296 71 | 1555 555 1296 296 72 | 1555 555 1296 296 73 | 1555 555 1296 296 74 | 1555 555 1296 296 75 | 1555 555 1296 296 76 | 1361 486 1134 259 77 | 1361 486 1134 259 78 | 1361 486 1134 259 79 | 1361 486 1134 259 80 | 1361 486 1134 259 81 | 1361 486 1134 259 82 | 1361 486 1134 259 83 | 1361 486 1134 259 84 | 1361 486 1134 259 85 | 1361 486 1134 259 86 | 1361 486 1134 259 87 | 1361 486 1134 259 88 | 1361 486 1134 259 89 | 1361 486 1134 259 90 | 1361 486 1134 259 91 | 0 0 0 0 92 | 0 0 0 0 93 | 0 0 0 0 94 | 0 0 0 0 95 | 0 0 0 0 96 | 0 0 0 0 97 | 0 0 0 0 98 | 0 0 0 0 99 | 0 0 0 0 100 | 0 0 0 0 101 | 0 0 0 0 102 | 0 0 0 0 103 | 0 0 0 0 104 | 0 0 0 0 105 | 0 0 0 0 106 | 0 0 0 0 107 | 0 0 0 0 108 | 0 0 0 0 109 | 0 0 0 0 110 | 0 0 0 0 111 | 0 0 0 0 112 | 0 0 0 0 113 | 0 0 0 0 114 | 0 0 0 0 115 | 0 0 0 0 116 | 0 0 0 0 117 | 0 0 0 0 118 | 0 0 0 0 119 | 0 0 0 0 120 | 0 0 0 0 121 | 0 0 0 0 122 | 0 0 0 0 123 | 0 0 0 0 124 | 0 0 0 0 125 | 0 0 0 0 126 | 0 0 0 0 127 | 0 0 0 0 128 | 0 0 0 0 129 | 0 0 0 0 130 | 0 0 0 0 131 | 0 0 0 0 132 | 0 0 0 0 133 | 0 0 0 0 134 | 0 0 0 0 135 | 0 0 0 0 136 | 0 0 0 0 137 | 0 0 0 0 138 | 0 0 0 0 139 | 0 0 0 0 140 | 0 0 0 0 141 | 0 0 0 0 142 | 0 0 0 0 143 | 0 0 0 0 144 | 0 0 0 0 145 | 0 0 0 0 146 | 0 0 0 0 147 | 0 0 0 0 148 | 0 0 0 0 149 | 0 0 0 0 150 | 0 0 0 0 151 | 0 0 0 0 152 | 0 0 0 0 153 | 0 0 0 0 154 | 0 0 0 0 155 | 0 0 0 0 156 | 0 0 0 0 157 | 0 0 0 0 158 | 0 0 0 0 159 | 0 0 0 0 160 | 0 0 0 0 161 | 0 0 0 0 162 | 0 0 0 0 163 | 0 0 0 0 164 | 0 0 0 0 165 | 0 0 0 0 166 | 0 0 0 0 167 | 0 0 0 0 168 | 0 0 0 0 169 | 0 0 0 0 170 | 0 0 0 0 171 | 0 0 0 0 172 | 0 0 0 0 173 | 0 0 0 0 174 | 0 0 0 0 175 | 0 0 0 0 176 | 0 0 0 0 177 | 0 0 0 0 178 | 0 0 0 0 179 | 0 0 0 0 180 | 0 0 0 0 181 | -------------------------------------------------------------------------------- /edge_details.py: -------------------------------------------------------------------------------- 1 | from imports import *; 2 | from initialize import *; 3 | 4 | ''' ------------------------------------------------------------------------------- 5 | -------------------FUNCTION TO TAKE EDGE DETAILS FROM THE USER--------------------- 6 | -----------------------------------------------------------------------------------''' 7 | # GUI related 8 | def edge_details(links): 9 | global param,label 10 | if(len(param)!=0): 11 | for i in param: 12 | for j in i: 13 | j.destroy() 14 | for i in label: 15 | i.destroy() 16 | label = [] 17 | param = [] 18 | lab1 = Label(root, text="Start Node") 19 | lab1.grid(row=3, column=4, sticky='NSEW') 20 | lab2 = Label(root, text="End Node") 21 | lab2.grid(row=3, column=5, sticky='NSEW') 22 | lab3 = Label(root, text="Length (m)") 23 | lab3.grid(row=3, column=6, sticky='NSEW') 24 | lab4 = Label(root, text="Width (m)") 25 | lab4.grid(row=3, column=7, sticky='NSEW') 26 | lab5 = Label(root, text="Density") 27 | lab5.grid(row=3, column=8, sticky='NSEW') 28 | label = [lab1,lab2,lab3,lab4,lab5] 29 | for j in range(int(links.get())): 30 | lab = Label(root, text='Link ' + str(j + 1)) 31 | lab.grid(row=j+4, column=3, sticky='NSEW') 32 | label.append(lab) 33 | n1 = Entry(root) 34 | n1.grid(row=j + 4, column=4, sticky='NSEW') 35 | n2 = Entry(root) 36 | n2.grid(row=j + 4, column=5, sticky='NSEW') 37 | l = Entry(root) 38 | l.grid(row=j+4, column=6, sticky='NSEW') 39 | w = Entry(root) 40 | w.grid(row=j + 4, column=7, sticky='NSEW') 41 | d = Entry(root) 42 | d.grid(row=j + 4, column=8, sticky='NSEW') 43 | param.append([n1,n2,l,w,d]) -------------------------------------------------------------------------------- /generateGraph.py: -------------------------------------------------------------------------------- 1 | from imports import * 2 | from initialize import * 3 | from start_simulation import start_simulation 4 | 5 | ''' ------------------------------------------------------------------------------- 6 | -------------------FUNCTION TO GENERATE GRAPH BASED ON INPUT DATA------------------ 7 | -----------------------------------------------------------------------------------''' 8 | #GUI related 9 | def generate_graph(param,count): 10 | global node_count,edge_count 11 | G = nx.Graph() 12 | graph_edges = [] 13 | node = [i+1 for i in range(node_count)] 14 | start, end, length, width, density = zip(*param) 15 | for i in range(edge_count): 16 | graph_edges.append([int(start[i].get()),int(end[i].get())]) 17 | G.add_nodes_from(node) 18 | G.add_edges_from(graph_edges) 19 | edge_label = defaultdict(int) 20 | node_label = defaultdict(int) 21 | for i in range(len(graph_edges)): 22 | edge_label[tuple(graph_edges[i])] = i+1 23 | for i in range(len(node)): 24 | node_label[i+1] = i+1 25 | pos = nx.random_layout(G) 26 | nx.draw_networkx_nodes(G,pos,nodelist = node) 27 | nx.draw_networkx_edges(G,pos,edgelist= graph_edges,edge_color='r') 28 | nx.draw_networkx_labels(G,pos,labels = node_label,font_size=16) 29 | nx.draw_networkx_edge_labels(G,pos,edge_labels= edge_label) 30 | Button(root, text='Start Simulation', fg='blue', bg='white', font=("Times New Roman", 20, "bold"),command= start_simulation).grid(row= max(count + 2,17), column=1, pady='20') 31 | plt.show() -------------------------------------------------------------------------------- /imports.py: -------------------------------------------------------------------------------- 1 | '''------------------------------------------------------------------------ 2 | -----------------------------LIBRARIES IMPORT------------------------------ 3 | ---------------------------------------------------------------------------''' 4 | 5 | import math #math library to use math function like power and square root 6 | import time # time library to update the simulation animation after a fixed interval of time 7 | import itertools #itertools library to use some of the functions 8 | import tkinter #tkinter library for building the entire GUI 9 | import random # not used but can be used to have a random demand input at a node 10 | from tkinter import * #importing all the classes from tkinter library 11 | import networkx as nx #For making the graphic visualization of the network 12 | import matplotlib.pyplot as plt #For drawing the charts and statistics associated with the results 13 | # from PIL import Image, ImageTk #For displaying the car animation during the program run 14 | # from itertools import count, cycle #For iterating through the frames of the GIF 15 | from functools import partial #Use of a method from this library for computation 16 | from collections import defaultdict #dictionaries to store key-value pairs 17 | import openpyxl #openpyxl library to print data into the excel files 18 | import pandas as pd #not used but can be used in place of openpyxl 19 | wb = openpyxl.load_workbook('G:\\result.xlsx') #Loading the excel file for writing the calculated data 20 | sheet = wb.active #Taking a particular sheet from the workbook -------------------------------------------------------------------------------- /initialize.py: -------------------------------------------------------------------------------- 1 | from imports import defaultdict 2 | 3 | ''' --------------------------------------------------------------------- 4 | --------------------------------GLOBAL PARAMETERS------------------------ 5 | -------------------------------------------------------------------------''' 6 | 7 | root = None # root tkinter element 8 | classes = 4 # Number of classes of vehicles 9 | node_count = 0 # Stores the number of nodes in the network 10 | edge_count = 0 # Stores the number of links in the network 11 | edges = defaultdict(lambda: defaultdict(list)) # Dictionary to store length,width,density and corresponding links 12 | edge_pairs = [] # Edge pairs corresponding to the network 13 | OD = [] # Stores the OD pairs corresponding to the network 14 | param = [] # Stores the parameters input through the GUI, once the simulation starts no use 15 | label = [] # Stores the labels of the GUI, once the simulation starts all label gets destroyed except visualization window 16 | OD_pairs = [] # Input from the GUI related to OD pairs 17 | labelvis = [] # Another list to store the labels of the GUI 18 | label2 = [] # Another list to store the labels of the GUI 19 | flag = 0 # To check if generate network button comes only once 20 | incoming_links = defaultdict(list) # Stores the incoming links corresponding to each node 21 | outgoing_links = defaultdict(list) # Stores the outgoing links corresponding to each node 22 | incoming_flows = defaultdict(list) # incoming flows to nodes 23 | zipped = [] # Not of use 24 | origin = [] # contains all the origins of O-D pairs 25 | destination = [] # contains all the destinations of O-D pairs 26 | OD_dict = defaultdict(lambda: defaultdict(list)) # O-D dict to store all paths from every node to every possible destination 27 | all_paths = [] #temporary variable 28 | b = [0.695,0.625,0.40,0.748] # Parameter for calculation of flow_max in the first cell 29 | area = [0.00000108,0.00000364,0.0000064,0.00001430] # area of each vehicle class 30 | AO_critical = [0.59,0.5,0.5,0.23] # critical area occupancy for each class 31 | AOmax = [0.89,0.83,0.83,0.5] # maximum area occupancy for each class 32 | free_flow_speed = [45.0,42.0,52.0,47.0] # free_flow_speed for each class 33 | jam_density = [0.89,0.78,0.74,0.5] # jam_density for each class 34 | relaxation_time = [0.00057,0.0007,0.001,0.006] #Relaxation_time for each class 35 | simtime = 180 # Simulation time in 10 seconds time interval #have to increase 36 | dt = 10/3600 # time element in hours 37 | density,AOnot,equi_speed,speed,flow,AO = [],[],[],[],[],[] #density, area occupancy excluding a particular vehicle class, equilibrium speed, normal speed, flow, Area_occupancy 38 | average_speed = [] #average speed for each vehicle class,for each link,for every instant of time 39 | link_density = [] # link density for each vehicle class for every link 40 | average_time = [] #average time for each vehicle class,for each link,for every instant of time 41 | edge_cost = defaultdict(list) #Stores the travel time cost of each path 42 | link_paths = defaultdict(list) #Stores the edges corresponding to a particular path 43 | link_history = defaultdict(list) #Stores the destination nodes which a particular link vehicle is entitled to go 44 | c = 0 #temporary variable 45 | visual = 0 #temporary variable 46 | demand_input = defaultdict(lambda: defaultdict(list)) # dictionary of dictionary to store the demand input for each O-D pair from the file 47 | destination_data = defaultdict(list) #To store the flow accumulating in all the destination nodes and going out of the network 48 | demand_data = defaultdict(list) #To store the class wise flow corresponding to 49 | msa_flow = defaultdict(list) #To store the previous flow alotted for calcualting the flow acording to msa algorithm 50 | 51 | 52 | ''' ------------------------------------------------------------------------------------------ 53 | Initializing all the parameters like density, AOnot, equi_speed, speed, flow and area occupancy 54 | -----------------------------------------------------------------------------------------------''' 55 | 56 | def initialize(): 57 | global density,AOnot,equi_speed,speed,flow,AO,origin,destination,zipped 58 | zipped = list(zip(*OD)) 59 | origin = zipped[0] 60 | destination = zipped[1] 61 | for i in edge_pairs: 62 | density.append([[0 for j in range(edges[i[0]][i[1]][3] + 1)] for k in range(4)]) 63 | AOnot.append([[0 for j in range(edges[i[0]][i[1]][3] + 1)] for k in range(4)]) 64 | equi_speed.append([[0 for j in range(edges[i[0]][i[1]][3] + 1)] for k in range(4)]) 65 | speed.append([[0 for j in range(edges[i[0]][i[1]][3] + 1)] for k in range(4)]) 66 | flow.append([[0 for j in range(edges[i[0]][i[1]][3] + 1)] for k in range(4)]) 67 | AO.append([0 for j in range(edges[i[0]][i[1]][3] + 1)]) -------------------------------------------------------------------------------- /main.py: -------------------------------------------------------------------------------- 1 | from edge_details import * 2 | from imports import * 3 | from initialize import * 4 | from OD_details import * 5 | 6 | ''' ---------------------------------------------------------------------------------- 7 | Entire section below is related to the GUI development using tkinter library functions 8 | -------------------------------------------------------------------------------------''' 9 | 10 | if __name__ == '__main__': 11 | root = tkinter.Tk() #GUI related 12 | root.geometry('1366x768') #GUI related 13 | root.configure(background='powderblue') #GUI related 14 | root.title('Dynamic Traffic Assignment Simulator') #GUI related 15 | Label(root, text="DYNAMIC TRAFFIC ASSIGNMENT SIMULATOR", fg='orange', bg='black', 16 | font=("Times New Roman", 20, "bold")).grid(row=0, columnspan=10, sticky='NSEW', ipady='10', 17 | ipadx='380') #GUI related 18 | 19 | Label(root, text=" ", bg='powderblue').grid(row=1, column=0, sticky='W') #GUI related 20 | Label(root, text=" ", bg='powderblue').grid(row=2, column=0, sticky='W') #GUI related 21 | Label(root, text="Enter the number of nodes").grid(row=3, column=0, sticky='NSEW') #GUI related 22 | nodes = Entry(root) #GUI related 23 | nodes.grid(row=3, column=1, sticky='W') #GUI related 24 | 25 | # For code check purpose 26 | nodes = 4 27 | 28 | Label(root, text=" ", bg='powderblue').grid(row=4, column=0, sticky='W') #GUI related 29 | Label(root, text=" ", bg='powderblue').grid(row=5, column=0, sticky='W') #GUI related 30 | Label(root, text="Enter the number of links").grid(row=6, column=0, sticky='NSEW') #GUI related 31 | links = Entry(root) #GUI related 32 | links.grid(row=6, column=1, sticky='W') #GUI related 33 | 34 | # For code check purpose 35 | 36 | 37 | Label(root, text=" ", bg='powderblue').grid(row=7, column=0, sticky='W') #GUI related 38 | Label(root, text=" ", bg='powderblue').grid(row=8, column=0, sticky='W') #GUI related 39 | Button(root, text="Enter the link details", fg='blue', bg='white', font=("Times New Roman", 10, "bold"), 40 | command=lambda: edge_details(links)).grid(row=9, column=0, sticky='E', ipadx='20') #GUI related 41 | 42 | Label(root, text=" ", bg='powderblue').grid(row=10, column=0, sticky='W') #GUI related 43 | Label(root, text=" ", bg='powderblue').grid(row=11, column=0, sticky='W') #GUI related 44 | Label(root, text="Enter the number of O-D pairs").grid(row=12, column=0, sticky='NSEW') #GUI related 45 | OD_ = Entry(root) # GUI related 46 | OD_.grid(row=12, column=1, sticky='W') #GUI related 47 | 48 | Label(root, text=" ", bg='powderblue').grid(row=13, column=0, sticky='W') #GUI related 49 | Label(root, text=" ", bg='powderblue').grid(row=14, column=0, sticky='W') #GUI related 50 | Button(root, text="Enter the O-D details", fg='blue', bg='white', font=("Times New Roman", 10, "bold"),command=lambda: OD_details(OD_, links,nodes)).grid(row=15, column=0, sticky='E', ipadx='20') 51 | root.mainloop()#GUI related 52 | 53 | '''------------------------------------------------------------------------------------------------------------- 54 | ------------------------------------------------END OF THE PROJECT---------------------------------------------- 55 | ----------------------------------------------------------------------------------------------------------------''' -------------------------------------------------------------------------------- /node_modelling.py: -------------------------------------------------------------------------------- 1 | from imports import * 2 | from initialize import * 3 | 4 | '''----------------------------------------------------- 5 | ----------------NODE MODELLING FOR NODES ------------ 6 | --------------------------------------------------------''' 7 | 8 | 9 | 10 | def node_modelling(t,n,vclass): 11 | 12 | global demand_input,destination_data #global variables so that update gets reflected in the original variables 13 | tfraction = defaultdict(list) # Turning flow for node modelling 14 | space_coeff = defaultdict(list) # Space coefficient for node modelling 15 | for i in range(1,node_count+1): # Loop to allocate flow to the first cell of the origin nodes 16 | 17 | # For every O-D pair taking the demand_input according to the msa algorithm 18 | if i in origin: 19 | for j in destination: 20 | if([i,j] in OD): 21 | for c in range(4): #Iterating for each class of vehicles 22 | demand_input[i][j][c] += (1/n)*demand_data[(i,j)][t][c] + ((n-1)/n)*msa_flow[(i,j)][t][c] # MSA Algorithm 23 | 24 | for c in range(4): 25 | temp = travel_cost(i, c) #For every class of vehicles for a particular node function to return turning fraction 26 | for j in incoming_links[i]: #Iterating for each incoming link to the ith node 27 | x = edge_pairs[j] 28 | last_cell = flow[j][c][edges[x[0]][x[1]][3]] # Here last cell is the flow corresponding to the last cell 29 | for k in outgoing_links[i]: # For each outgoing link from the ith node multiplying the flow in the last cell of the incoming link to the turning fraction 30 | tfraction[(j,k)].append(last_cell*temp[(j,k)]) # Appending the class wise turning flow corresponding to (j,k) link pair 31 | 32 | # If i is the origin taking one more virtual link into account and calculating the turning flow for that link also 33 | if i in origin: 34 | for k in outgoing_links[i]: 35 | tot=0 36 | for j in link_history[k]: 37 | tot+=demand_input[i][j][c] 38 | tfraction[('o',k)].append(tot*temp[('o',k)]) # o stand for origin 39 | 40 | # If i is the destination one more virtual link is taken into acount and turning fraction is calculated 41 | if i in destination: 42 | for j in incoming_links[i]: 43 | x = edge_pairs[j] 44 | last_cell = flow[j][c][edges[x[0]][x[1]][3]] 45 | if i in link_history[j]: 46 | tfraction[(j,'d')].append(last_cell * temp[(j,'d')]) # d stands for destination 47 | 48 | for c in range(4): 49 | for j in outgoing_links[i]: 50 | total = 0 51 | for k in incoming_links[i]: 52 | total += tfraction[(k,j)][c] 53 | total+=tfraction[('o',j)][c] if(('o',j) in tfraction) else 0 54 | for k in incoming_links[i]: 55 | if(total!=0): 56 | space_coeff[(j,k)].append(tfraction[(k,j)][c]/total) 57 | else: 58 | space_coeff[(j,k)].append(1) 59 | if (total != 0): 60 | space_coeff[(j,'o')].append(tfraction[('o', j)][c] / total) # Calcualting the space coefficient 61 | else: 62 | space_coeff[(j, 'o')].append(1) 63 | 64 | # If i is in destination calculating space coefficient for that virtual link also 65 | if i in destination: 66 | total=0 67 | for k in incoming_links[i]: 68 | total += tfraction[(k, 'd')][c] 69 | for k in incoming_links[i]: 70 | if (total != 0): 71 | space_coeff[('d', k)].append(tfraction[(k, 'd')][c] / total) 72 | else: 73 | space_coeff[('d', k)].append(1 / 2) 74 | 75 | # For restricting the flow according to the AO critial based on the formula given by you 76 | max_flow = defaultdict(list) 77 | for c in range(4): 78 | for j in outgoing_links[i]: 79 | temp = 0 80 | if(AO[j][0]>=AO_critical[c]): 81 | temp = density[j][c][0] * free_flow_speed[c] * math.exp((-1/b[c])*pow((AO[j][0]/AO_critical[c]),b[c])) 82 | else: 83 | temp = density[j][c][0] * free_flow_speed[c] * math.exp((-1 / b[c])) 84 | max_flow[j].append(temp) 85 | 86 | # Assigning the flows 87 | for j in incoming_links[i]: 88 | for k in outgoing_links[i]: 89 | for c in range(4): 90 | x = edge_pairs[j] 91 | last_cell = flow[j][c][edges[x[0]][x[1]][3]] 92 | first_cell = max_flow[k][c] 93 | demand = tfraction[(j,k)][c] 94 | supply = first_cell * space_coeff[(k,j)][c] 95 | if(demand