-
Notifications
You must be signed in to change notification settings - Fork 0
/
Demand_Study_HeterogeneouS.py
executable file
·154 lines (124 loc) · 6.43 KB
/
Demand_Study_HeterogeneouS.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
__author__ = "Jerome Thai, Nicolas Laurent-Brouty, Juliette Ugirumurera, Hippolyte Signargout"
'''
This is a modified version of Demand_Study_Hetergogeneous
Instead of outputting only one file, there is a 'for' loop on the ratio of routed users
This file's goal is to be modified to have the right 'for' loops and output a bunch of results in one go
Right now the arguments are the name of the network, the demand ratio, and the size of the step for the percentage
The for loop will go from 0 to 100%, with this step
'''
###Libraries
import numpy as np
import argparse
from math import ceil
#Functions
from process_data import process_net, process_trips, extract_features, process_links, process_node, \
geojson_link, construct_igraph, construct_od, join_node_demand, geojson_link_Scenario_Study, process_node_to_GPS_Coord
from frank_wolfe_heterogeneous import fw_heterogeneous_1,fw_heterogeneous_2
from Social_Optimum import solver_social_optimum
from AoN_igraph import all_or_nothing
from frank_wolfe_2 import total_free_flow_cost, search_direction, line_search, solver_3
from process_data import construct_igraph, construct_od
from utils import multiply_cognitive_cost, heterogeneous_demand
from heterogeneous_construct import toy_heterogeneous, LAfix_heterogeneous
#Profiling the code
import timeit
#Funtion to calculate the total travel time
def total_cost(graph, f):
x = np.power(f.reshape((f.shape[0],1)), np.array([1,2,3,4,5])) # x is a matrix containing f,f^2, f^3, f^4, f^5
tCost = np.sum(np.einsum('ij,ij->i', x, graph[:,3:])) # Multply matrix x with coefficients a0, a1, a2, a3 and a4
return tCost
#load the network data:
def load_network_data(name):
#import pdb; pdb.set_trace()
#The folder locations of all the input files
graphLocation = 'data/' + name + '_net.csv'
demandLocation = 'data/' + name + '_od.csv'
nodeLocation = 'data/' + name + '_node.csv'
featureLocation = 'data/' + name + '_net.txt'
graph = np.loadtxt(graphLocation, delimiter=',', skiprows=1)
demand = np.loadtxt(demandLocation, delimiter=',', skiprows=1)
features = extract_features(featureLocation)
#import pdb; pdb.set_trace()
#LA network has a different way of processing the nodes file
if(name == "LA"):
node = np.loadtxt(nodeLocation, delimiter=',')
print features.shape
features[10787,0] = features[10787,0] * 1.5
graph[10787,-1] = graph[10787,-1] / (1.5**4)
features[3348,:] = features[3348,:] * 1.2
graph[3348,-1] = graph[3348,-1] / (1.2**4)
else:
node = np.loadtxt(nodeLocation, delimiter=',', skiprows=1)
return graph, demand, node, features
#This function runs frank-wolfe algorithm on a particular network with demand modified as ratio X demand
def frank_wolfe_ratio_study_h(network_name, ratio, perc):
#g1, g2, dm1, dm2 = toy_heterogeneous(perc)
print network_name
print ratio
if network_name == "LAfix": #Note that right now it only works with LAfix
g1,g2,dm1,dm2=LAfix_heterogeneous(perc, 3900) #Have a look at Demand_Study_Hetergogeneous to tune it for other networks
d1 = np.copy(dm1)
d2 = np.copy(dm2)
else:
g2, demand, node, features = load_network_data(network_name)
g1= np.loadtxt('data/' + network_name + '_net_nr.csv', delimiter=',', skiprows=1) #1 is for non-routed, 2 is for routed
#demand[:,2] =ratio* demand[:,2] / 4000
d1 = np.copy(demand)
d2 = np.copy(demand)
#makes a copy of the demand array
d1[:,2] = (1-perc) * d1[:,2] /4000
d2[:,2] = perc * d2[:,2] /4000
#print "dnr=", d1, "dr=",d2
#start timer for frank-wolfe
start_time1 = timeit.default_timer()
#Run Frank-Wolfe
f = fw_heterogeneous_1([g1,g2], [d1,d2], max_iter=10000, q=50, display=0, stop=1e-5)
#end of timer
elapsed1 = timeit.default_timer() - start_time1
#print ("Frank-Wolfe took %s seconds" % elapsed1)
#total_travel_time = total_cost(graph, f)
#avg_travel_time = total_travel_time/np.sum(d[:,2])
#print ("Average travel time %3f " % avg_travel_time)
fileName = 'data/output/'+ network_name + '_output_ratio_' + str(ratio) + '_perc_'+ str(perc) + '.csv'
print(fileName)
np.savetxt(fileName, f, delimiter=',')
#Call visualize with filename where output is
#visualize_result_ratio_study(fileName, ratio, network_name, mode)
#Visualize the results from the scenario study
def visualize_result_ratio_study(fileName, ratio, name, mode):
net, demand, node, features = load_network_data(name)
#Loading the flow per link resulting from frank-wolfe
f = np.loadtxt(fileName, delimiter=',', skiprows=0)
#Location of the features
featureLocation = 'data/' + name + '_net.txt'
features = np.zeros((f.shape[0], 4))
features[:,:3] = extract_features(featureLocation)
#Multiply the flow obtained by 4000 since we initially divided by 4000 before frank-wolfs
f = np.divide(f*4000, features[:,0])
features[:,3] = f
links = process_links(net, node, features, in_order=True)
#creates color array used to visulized the links
#values useful in differenciating links based of flow on links
color = 2.0*f + 1.0
#Keeping track of the percentage of congestion
links_congested = len(color[np.where(color >= 3)])
percentage_of_congestion = float(links_congested) / float(len(color))
print("congestion is at %3f " % percentage_of_congestion)
geojson_link_Scenario_Study(ratio,links, ['capacity', 'length', 'fftt', 'flow_over_capacity'], color, name, mode)
def main():
pass
parser = argparse.ArgumentParser(description='Process network name and demand ratio')
parser.add_argument("name", type = str, help = "name of network")
parser.add_argument("ratio", type = float, help = "demand ratio")
parser.add_argument("routed", type = float, help = "percentage of routed users")
#frank-wolfe algorithm can operate in two modes: User Equilibrium (UE) or Social Optimum (SO)
#parser.add_argument("mode", type = str, help = "frank wolfe mode")
args = parser.parse_args()
#for i in range (0,int(ceil(1.5/args.ratio)+1)): #Another loop for demand ratio that you can uncomment
for j in range (0,int(ceil(1/args.routed))):
#for j in range (0,1):
print j
frank_wolfe_ratio_study_h(args.name, args.ratio, args.routed*j)
if __name__ == '__main__':
main()