toruseo / UXsim

Vehicular traffic flow simulator in road network, written in pure Python
https://toruseo.jp/UXsim/docs/
MIT License
122 stars 56 forks source link

Optimize multi-lane implementation (by handeling it as a single lane) #141

Open EwoutH opened 1 day ago

EwoutH commented 1 day ago

UXsim is a mesoscopic traffic simulation package, which typically operates at a higher level of abstraction than microscopic models. However, the current multi-lane implementation seems more detailed than necessary for mesoscopic simulation, potentially impacting performance without proportional benefits to accuracy.

Issue

The current multi-lane model in UXsim may be unnecessarily complex for a mesoscopic simulation, leading to increased computational overhead and memory usage. This complexity might not provide significant benefits in simulation accuracy at the mesoscopic level.

Currently, the Node transfer() method takes up >20% of runtime in large simulations. Much of this overhead originates between tracking and choosing between lanes. I don't think this whole exercise is necessary for a mesoscopic traffic simulation package like UXsim.

Examples of current complexity

  1. Vehicles have a lane attribute and follow leaders in the same lane:
    class Vehicle:
       def __init__(s, ...):
           s.lane = 0
           s.leader = None
  2. Links maintain lane-specific information:
    class Link:
       def __init__(s, ..., number_of_lanes=1, ...):
           s.number_of_lanes = int(number_of_lanes)
  3. Lane-based outlink generation:
    for outlink in outlink_candidates.keys():
       for i in range(outlink.number_of_lanes):  # Iterate over each lane
           outlinks.append(outlink)
  4. Complex condition for vehicle transfer:
    if (len(outlink.vehicles) < outlink.number_of_lanes or 
       outlink.vehicles[-outlink.number_of_lanes].x > outlink.delta_per_lane*s.W.DELTAN) and \
      outlink.capacity_in_remain >= s.W.DELTAN and s.flow_capacity_remain >= s.W.DELTAN:
  5. Lane-specific leader-follower assignment:
    if len(outlink.vehicles) >= outlink.number_of_lanes:
       veh.leader = outlink.vehicles[-outlink.number_of_lanes]
       veh.leader.follower = veh
       assert veh.leader.lane == veh.lane
  6. Lane-by-lane trip ending checks:
    for link in s.inlinks.values():
       for lane in range(link.number_of_lanes):
           if len(link.vehicles) and link.vehicles[0].flag_waiting_for_trip_end:
               link.vehicles[0].end_trip()
           else:
               break

Proposed solution

Simplify the multi-lane model to align better with mesoscopic simulation principles:

  1. Remove lane-specific attributes from vehicles.
  2. Represent lanes as a capacity multiplier for links rather than discrete entities.
  3. Simplify merging and diverging logic at nodes.

Example of simplified Link class:

class Link:
    def __init__(s, ..., number_of_lanes=1, ...):
        s.capacity_multiplier = int(number_of_lanes)
        s.capacity = s.base_capacity * s.capacity_multiplier

Benefits

Potential Concerns

Next Steps

Reimplement multi-lane behavior in a simpler way (partly revert https://github.com/toruseo/UXsim/pull/68).

toruseo commented 1 day ago

unfortunately, that doesnt work. it is not that simple. this is related to fundamental nature of traffic flow theory (LWR PDE)

2024年9月23日(月) 18:49 Ewout ter Hoeven @.***>:

UXsim is a mesoscopic traffic simulation package, which typically operates at a higher level of abstraction than microscopic models. However, the current multi-lane implementation seems more detailed than necessary for mesoscopic simulation, potentially impacting performance without proportional benefits to accuracy. Issue

The current multi-lane model in UXsim may be unnecessarily complex for a mesoscopic simulation, leading to increased computational overhead and memory usage. This complexity might not provide significant benefits in simulation accuracy at the mesoscopic level.

Currently, the Node transfer() method takes up >20% of runtime in large simulations. Much of this overhead originates between tracking and choosing between lanes. I don't think this whole exercise is necessary for a mesoscopic traffic simulation package like UXsim. Examples of current complexity

  1. Vehicles have a lane attribute and follow leaders in the same lane:

    class Vehicle: def init(s, ...): s.lane = 0 s.leader = None

  2. Links maintain lane-specific information:

    class Link: def init(s, ..., number_of_lanes=1, ...): s.number_of_lanes = int(number_of_lanes)

Proposed solution

Simplify the multi-lane model to align better with mesoscopic simulation principles:

  1. Remove lane-specific attributes from vehicles.
  2. Represent lanes as a capacity multiplier for links rather than discrete entities.
  3. Simplify merging and diverging logic at nodes.

Example of simplified Link class:

class Link: def init(s, ..., number_of_lanes=1, ...): s.capacity_multiplier = int(number_of_lanes) s.capacity = s.base_capacity * s.capacity_multiplier

Benefits

  • Reduced computational complexity
  • Lower memory usage
  • Faster simulation execution, especially for large networks
  • Better alignment with mesoscopic simulation principles

Potential Concerns

  • Slight reduction in detail for merge/diverge behavior
  • May affect some existing scenarios that rely on lane-specific logic

Next Steps

Reimplement multi-lane behavior in a simpler way (partly revert #68 https://github.com/toruseo/UXsim/pull/68).

— Reply to this email directly, view it on GitHub https://github.com/toruseo/UXsim/issues/141, or unsubscribe https://github.com/notifications/unsubscribe-auth/AIJLHOIVKECXC4Y33SIFMXLZX7PZRAVCNFSM6AAAAABOVV5L6CVHI2DSMVQWIX3LMV43ASLTON2WKOZSGU2DEMJRGY2DQNQ . You are receiving this because you are subscribed to this thread.Message ID: @.***>

EwoutH commented 1 day ago

Interesting. Can't you work around that by also compensating for density/lengths/shockwave speeds?

If we assume densities, speeds, and flow characteristics are identical across all lanes, we can safely aggregate them without violating the LWR traffic flow theory, right? In this case, the total flow, density, and speed can be scaled by the number of lanes.

Since traffic dynamics (e.g., shockwave propagation) are uniform across lanes, the multi-lane behavior effectively becomes a single-pipe model.

toruseo commented 1 day ago

There are no known simple workaround. There could be complicated tricks (e.g., model vehicle like train where passengers are actual vehicle, or LTM-like approach), but I dont want to go there for simplicity and generality

EwoutH commented 1 day ago

Okay, thanks for getting back anyways!

Then there are two functions that would benefit a lot from a speedup: The Node transfer and the Vehicle route_next_link_choice. Both take up 15% to 20% of simulation time in a large-scale simulation.