Issues with multi-class traffic assignment

41 views
Skip to first unread message

Raisul Islam

unread,
Jan 23, 2024, 2:21:27 PM1/23/24
to AequilibraE
Dear Pedro (and Everyone),
I hope you are doing well. My name is Mir Raisul Islam. I am working as a Research Assistant at a Economic Research Institute in Germany. I am facing two issues while doing multi-class traffic assignment by using AequilibraE python pacakge. 

1. I have three traffic classes OD matrices and for these three traffic classes I created three different graphs of the networks. Some trific classes are not supposed to use some routes/links. That's why the graphs are different in shapes for different traffic classes, but I am getting this error, 

ValueError Traceback (most recent call last) File <timed exec>:36 File c:\\Users\\Raisul\\anaconda3\\envs\\my_env\\Lib\\site-packages\\aequilibrae\\paths\\traffic_assignment.py:432, in TrafficAssignment.execute(self, log_specification) 430 if log_specification: 431 self.log_specification() --> 432 self.assignment.execute() 

File c:\\Users\\Raisul\\anaconda3\\envs\\my_env\\Lib\\site-packages\\aequilibrae\\paths\\linear_approximation.py:388, in LinearApproximation.execute(self) 384 self.__maybe_create_path_file_directories() 386 for c in self.traffic_classes: # type: TrafficClass 387 # cost = c.fixed_cost / c.vot + self.congested_time # now only once --> 388 cost = c.fixed_cost + self.congested_time 389 aggregate_link_costs(cost, c.graph.compact_cost, c.results.crosswalk) 391 aon = allOrNothing(c.matrix, c.graph, c._aon_results) 
 ValueError: operands could not be broadcast together with shapes (11202,) (9184,) "

I am not sure if it happending because of my using different set of links for each graph.

2. To solve this error, I have used the same set of links for each graphs. But, I just increased the cost of few different links for different graphs of corresponding classes. In this case, there is no error and I get result. 
According to the documentation, the results should not depend on the order the classes are put in. Unfortunately, in my case I am getting different results for different order of the classes in the  set_classes() function. 

Would you please help me to get these two problems better? How can I actually sove these issues?

Thank you so much in advance for your kind help. 

Best,
Mir Raisul Islam.





Pedro Camargo

unread,
Jan 23, 2024, 2:30:31 PM1/23/24
to AequilibraE
Hi,

Graphs in AequilibraE can obviously be different for different classes, but the consolidation of flows in the "main network" must be possible, and AequilibraE uses a simple trick to do that, but that is built into AequilibraE's default graph building from a project (line 347 in the file https://github.com/AequilibraE/aequilibrae/blob/develop/aequilibrae/project/network/network.py).

I suspect that you are not starting from an AequilibraE project, which means that your network (graph.network) has different sizes for different traffic classes.

Finally, please note that I was required to make the assumption that you are not using an AequilibraE project in order to answer your question, which takes time and adds unnecessary noise to the communication.  In the future, please consider being more thorough on your messages and provide all relevant information (i.e. code, data samples, etc).

Cheers,
Pedro




---- On Wed, 24 Jan 2024 05:19:33 +1000 Raisul Islam <rock...@gmail.com> wrote ---

--
You received this message because you are subscribed to the Google Groups "AequilibraE" group.
To unsubscribe from this group and stop receiving emails from it, send an email to aequilibrae...@googlegroups.com.


Raisul Islam

unread,
Jan 23, 2024, 5:49:47 PM1/23/24
to AequilibraE
Hi Pedro, 
Thank you so much for your feedback. I am extremely sorry for not providing all the relevant info earlier.

Yes, I did not start from an AequilibraE project. I have created the dataframe of network on my own. I hope I have all the relevant fields in my dataframe. I am actually doing traffic assignment of submarine cable data. So, each node represents different countries. The modes are data flowing from one country to another country by using these submarine cables. So, I want to use two modes, one is data flowing from the USA to other countries and vice-versa. Another mode is data flowing from China to other countries and vice-versa. 

So, when I use data of the USA as demand matrix, I want to filter the cables owned by China from the network out to get a graph for it. Again, while using the flow of China as a demand matrix, I want to filter the cables owned by the USA from the network dataframe out to get a graph. I am trying to keep it simple, so I am not using any loop to create graphs for each of the classes. I am trying to create graphs for each classes separately.

I have attached an image of the dataframe of network. Here I am pasting the codes relevant to the problem. 
network= link.copy(deep= True)
network_usa= link[link["ownership_indicator"]!="C"] #C means China
network_china= link[link["ownership_indicator"]!="U"] #U means USA

#create graph for USA flow
g_usa = Graph()
g_usa.cost = network_usa['free_flow_time'].values #?
g_usa.capacity = network_usa['capacity'].values
g_usa.free_flow_time = network_usa['free_flow_time'].values

g_usa.network = network_usa
g_usa.network_ok = True #?
g_usa.status = 'OK' #?
g_usa.prepare_graph(index) #?
g_usa.set_graph("free_flow_time")
g_usa.cost = np.array(g_usa.cost, copy=True)
g_usa.set_skimming(["free_flow_time"]) #?
g_usa.set_blocked_centroid_flows(False) #?
g_usa.network["id"] = g_usa.network.link_id
#create graph for China flow
g_china = Graph()
g_china.cost = network_china['free_flow_time'].values #?
g_china.capacity = network_china['capacity'].values
g_china.free_flow_time = network_china['free_flow_time'].values

g_china.network = network_china
g_china.network_ok = True #?
g_china.status = 'OK' #?
g_china.prepare_graph(index) #?
g_china.set_graph("free_flow_time")
g_china.cost = np.array(g_china.cost, copy=True)
g_china.set_skimming(["free_flow_time"]) #?
g_china.set_blocked_centroid_flows(False) #?
g_china.network["id"] = g_china.network.link_id

#Now doing the multiclass traffic assignment

aem_usa = AequilibraeMatrix()
aem_china = AequilibraeMatrix()

os.chdir("D:/Professional/0_Internship_Kiel_IfW/mir_cable_analsis/Mir/1_multi_class_analysis/7_matrix_bin/") #setting directory

#load aem file
aem_usa.load("Demand_usa.aem")
aem_usa.computational_view(["matrix_usa"])

aem_china.load("Demand_china.aem")
aem_china.computational_view(["matrix_china"])

aem_neutral.load("Demand_neutral.aem")
aem_neutral.computational_view(["matrix_neutral"])

#now assign classes
tc_usa= TrafficClass("usa_flow", g_usa, aem_usa)
tc_china=TrafficClass("china_flow", g_china, aem_china)
tc_neutral= TrafficClass("neutral_flow", g_neutral, aem_neutral)
#set classes
assig= TrafficAssignment()
assig.set_classes([tc_usa, tc_china])
assig.set_vdf("BPR")
assig.set_vdf_parameters({"alpha":0, "beta":1})
assig.set_capacity_field("capacity")
assig.set_algorithm("all-or-nothing")
assig.max_iter = 100
assig.rgap_target = 1e-3
assig.execute()


Would you please help me to find out which changes I should make to execute this mult-class traffic assignment? I am really sorry if I am asking about any minor issue. 

network.PNG

Pedro Camargo

unread,
Jan 23, 2024, 6:18:50 PM1/23/24
to AequilibraE
Hi Raisul,

Following that piece of code I sent you would be the correct way of proceeding here (eliminating the links that do not belong to each class by making, for that class, a_node = b_node). HOWEVER, you are performing an all-or-nothing assignment, so it is MUCH easier just to run all of them in separate and combine the results with a Pandas join at the end.

Cheers,
Pedro



---- On Wed, 24 Jan 2024 08:49:47 +1000 Raisul Islam <rock...@gmail.com> wrote ---

Reply all
Reply to author
Forward
0 new messages