0

I'm trying to create a model for a hybrid public transportation network. but i'm unable to run it correctly

The idea is that i have a number of buses working on 15 bus lines that have a departure station on which buses stay inline waiting for their turn to start picking up clients, and then start circulating. The main condition here is that for every bus line, only one bus at a time can be picking-up clients at departure station, and that the bus only leaves if his occupation rate gets over 80% or if he's being picking up clients for at least 500 ticks.

The code below is not working properly and i couldn't find a way out.. when the model is running, buses are just waiting until ticks = 500 to start picking up clients and circulating.. and even there, the chain is not fonctionning correctly.

to go.hybrid.bus
 if ticks = ((patterns * nb_ticks_patterns) - 1)
  [
    ifelse station? = true
    [create.clients.station]
    [create.clients.zone]
    update.stations.potential
    choose.clients.final.destination
    set patterns (patterns + 1)
  ]
  ask clients [ set waiting_time waiting_time + 1 ]
  if station? = false [move.clients]
  count.clients.waiting
  go.hybrid.buses
  plotting
  tick
end

to go.hybrid.buses  ;
  ask buses with [bus_lines_stations_buses < 200]
  [
    ifelse state = 0
    [
      drop.clients.bus
      ifelse bus_lines_stations_buses = 1
      [choose.station.bus.1]
      [ifelse bus_lines_stations_buses = 2
        [choose.station.bus.2]
        [ifelse bus_lines_stations_buses = 3
          [choose.station.bus.3]
          [ifelse bus_lines_stations_buses = 4
            [choose.station.bus.4]
            [ifelse bus_lines_stations_buses = 5
              [choose.station.bus.5]
              [ifelse bus_lines_stations_buses = 6
                [choose.station.bus.6]
                [ifelse bus_lines_stations_buses = 7
                  [choose.station.bus.7]
                  [ifelse bus_lines_stations_buses = 8
                    [choose.station.bus.8]
                    [ifelse bus_lines_stations_buses = 9
                      [choose.station.bus.9]
                      [ifelse bus_lines_stations_buses = 101
                        [choose.station.bus.101]
                        [ifelse bus_lines_stations_buses = 102
                          [choose.station.bus.102]
                          [ifelse bus_lines_stations_buses = 103
                            [choose.station.bus.103]
                            [ifelse bus_lines_stations_buses = 104
                              [choose.station.bus.104]
                              [ifelse bus_lines_stations_buses = 105
                                [choose.station.bus.105]
                                [choose.station.bus.106]
                              ]
                            ]
                          ]
                        ]
                      ]
                    ]
                  ]
                ]
              ]
            ]
          ]
        ]
      ]
      pick.up.clients.hybrid.bus
      set timer_hybrid_buses 0
    ]
    [
      ifelse first-station = [who] of current_node and (occupation_rate_vehicle < 80 or timer_hybrid_buses <= 500)
      [
        set waiting? 1
        set timer_hybrid_buses timer_hybrid_buses + 1
        let target one-of other buses-here with [nb_clients_picked_up > 0 and started? = 0 and bus_lines_stations_buses = [bus_lines_stations_buses] of myself]
        if target = nobody
        [pick.up.clients.hybrid.bus]
      ]
      [
        circulate.bus
        set waiting? 0
      ]
    ]
  ]
end
htmdz
  • 1
  • 1

1 Answers1

0

I will try help a bit, but without the full model it's quite difficult.

First, you can use NetLogo's multi-case ifelse to simplify go.hybrid.buses procedure:

to go.hybrid.buses  ;
  ask buses with [bus_lines_stations_buses < 200]
  [
    ifelse state = 0
    [
      drop.clients.bus
      (ifelse 
        bus_lines_stations_buses = 1 [
          choose.station.bus.1
        ] 
        bus_lines_stations_buses = 2 [
          choose.station.bus.2
        ] 
        bus_lines_stations_buses = 3 [
          choose.station.bus.3
        ] 
        bus_lines_stations_buses = 4 [
          choose.station.bus.4
        ] 
        bus_lines_stations_buses = 5 [
          choose.station.bus.5
        ] 
        bus_lines_stations_buses = 6 [
          choose.station.bus.6
        ] 
        bus_lines_stations_buses = 7 [
          choose.station.bus.7
        ] 
        bus_lines_stations_buses = 8 [
          choose.station.bus.8
        ] 
        bus_lines_stations_buses = 9 [
          choose.station.bus.9
        ] 
        bus_lines_stations_buses = 101 [
          choose.station.bus.101
        ] 
        bus_lines_stations_buses = 102 [
          choose.station.bus.102
        ] 
        bus_lines_stations_buses = 103 [
          choose.station.bus.103
        ] 
        bus_lines_stations_buses = 104 [
          choose.station.bus.104
        ] 
        bus_lines_stations_buses = 105 [
          choose.station.bus.105
        ] [
          choose.station.bus.106
        ]
      )
      pick.up.clients.hybrid.bus
      set timer_hybrid_buses 0
    ]
    [
      ifelse first-station = [who] of current_node and (occupation_rate_vehicle < 80 or timer_hybrid_buses <= 500)
      [
        set waiting? 1
        set timer_hybrid_buses timer_hybrid_buses + 1
        let target one-of other buses-here with [nb_clients_picked_up > 0 and started? = 0 and bus_lines_stations_buses = [bus_lines_stations_buses] of myself]
        if target = nobody
        [pick.up.clients.hybrid.bus]
      ]
      [
        circulate.bus
        set waiting? 0
      ]
    ]
  ]
end

That's not going to fix anything, but it's much easier to read. I would also personally refactor your choose.station.bus.* method to take an argument with the bus_lines_stations_buses. I cannot see that procedure to know how easy that would be, but you can change things like so as a first step:

to choose.station.bus [number]
  ; do whatever choosing the station bus is here, based on the number given
end

to go.hybrid.buses  ;
  ask buses with [bus_lines_stations_buses < 200]
  [
    ifelse state = 0
    [
      drop.clients.bus
      choose.station.bus bus_lines_stations_buses
      pick.up.clients.hybrid.bus
      set timer_hybrid_buses 0
    ]
    [
      ifelse first-station = [who] of current_node and (occupation_rate_vehicle < 80 or timer_hybrid_buses <= 500)
      [
        set waiting? 1
        set timer_hybrid_buses timer_hybrid_buses + 1
        let target one-of other buses-here with [nb_clients_picked_up > 0 and started? = 0 and bus_lines_stations_buses = [bus_lines_stations_buses] of myself]
        if target = nobody
        [pick.up.clients.hybrid.bus]
      ]
      [
        circulate.bus
        set waiting? 0
      ]
    ]
  ]
end

Again, we've not fixed anything, but still a little clearer for me to try to understand to help.

What I see here is that we have three variables, state, waiting? and started? that all seem to be meant to do similar things; it's hard to tell from the context and the code given. What I can tell is that neither waiting? or started? are being used to make decisions in this code. state and started? are never set in this code, they never change. If you're expecting changing waiting? to 1 or 0 to kick off some behavior, it's not going to happen according to this code. My best guess based on what I see is the failure to change one of state or started? or the failure to check waiting? are involved in the code not working as you'd like it to.

If that doesn't point you in the right direction, posting a working but simplified version of your code with the bare minimum that demonstrates the problem would help.

Jasper
  • 2,610
  • 14
  • 19