Issue in accomodating DRT request (config/model issue)

41 views
Skip to first unread message

Antonio Francescon

unread,
May 4, 2026, 1:04:23 AM (9 days ago) May 4
to or-tools-discuss
Hi, All,

I am working on an OR-Tools-based DRT solution.

The system works by receiving pickup-dropoff requests, evaluating a solution (if any) and then sending it back to the requester.
New solutions can only marginally affect the previously evaluated solution, since only a
little drift of the previously evaluated assignment is allowed.
To achieve this behavior, the system keeps track of all previously received, successfully
answered requests and narrows their original pickup/dropoff windows to force the OR-Tools algorithms to almost recreate the previous solution. Thus, when a request arrives, the previous successful requests (now with cropped time windows) are processed together with the new request to see if a new solution can be found.

The issue I am facing is that after properly "framing" some requests, the system
systematically fails to accept new ones — even ones that clearly could be accommodated in wide intervals between previous and following requests (e.g., a 20-minute trip in the middle of an empty time interval spanning over 4 hours).
It seems like a configuration issue, so I am asking for your support.

Operative service turns are 12 hours long. To leave maximum freedom in managing request allocation, I set max_slack to 24 hours.
Then I set:

- Time intervals for pickups and dropoffs:
    time_dimension.CumulVar(rvindex).SetRange(time_window[0], time_window[1])

- Maximum trip length based on the minimum duration satisfying the related request
  (enlarged by 66% to allow space for accommodating later requests):
    self._routing.solver().Add(dropoff_time - pickup_time <= max_trip_time)

- Single vehicle pickup & dropoff rules:
    # Set pickup-dropoff relationship
    self._routing.AddPickupAndDelivery(pickup_rvindex, dropoff_rvindex)
   
    # Set single vehicle pickup-dropoff
    self._routing.solver().Add(
        self._routing.VehicleVar(pickup_rvindex) == self._routing.VehicleVar(dropoff_rvindex)
    )

- Optimization rule to minimize on-the-road time for each vehicle:
    self._routing.AddVariableMinimizedByFinalizer(
        time_dimension.CumulVar(self._routing.End(vehicle_index)) -
        time_dimension.CumulVar(self._routing.Start(vehicle_index))
    )

As mentioned, after fewer than 10 requests, the system fails to accommodate new ones,
even when they target very wide intervals free from other requests.

**Additional info:**
- **Number of vehicles:** 1 (currently, but it will be larger)
- **First solution strategy:** [
            "AUTOMATIC",
            "PARALLEL_CHEAPEST_INSERTION",
            "SEQUENTIAL_CHEAPEST_INSERTION"
            "LOCAL_CHEAPEST_INSERTION"
            "PATH_CHEAPEST_ARC"
        ]
- **Search metaheuristic:** GUIDED_LOCAL_SEARCH
- **Solver return value:** 3 (ROUTING_FAIL) I tried to increase the time for evaluating solution between 1-4 seconds, with no benefit

Any suggestion is welcome and appreciated. Thank you!

Best regards

blind.line

unread,
May 4, 2026, 1:24:26 AM (8 days ago) May 4
to or-tools...@googlegroups.com
It is really hard to guess without seeing more details. 

Do you have disjunctions turned on for all nodes?

Are you sure the new rides can be served?

Maybe the objective is better with dropping the new rides?  How large is the disjunction penalty? What does the  objective fn look like?  Is time in milliseconds or minutes or hours? 


Finally, why do you suppose 4s is long enough? How exactly is the solver failing? Did you turn on logging to see what it is doing?


Regards,


James


On May 4, 2026, at 07:04, Antonio Francescon <antonio.f...@openmove.com> wrote:

Hi, All,
--
You received this message because you are subscribed to the Google Groups "or-tools-discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email to or-tools-discu...@googlegroups.com.
To view this discussion visit https://groups.google.com/d/msgid/or-tools-discuss/07c6a49a-d4d2-4cb3-b5fc-9f6e3a3dfe75n%40googlegroups.com.

Antonio Francescon

unread,
May 4, 2026, 5:01:30 AM (8 days ago) May 4
to or-tools-discuss
Hi James,

Thank you for your prompt reply.

I provide here more context about the problem.

We have 1 single vehicle with a capacity of 9 passengers.
Trip times are in minutes and max_slack value is set to 1440 minutes (24 hours).

The system processes requests in sequence: all previous answered requests are included in the solution.
I need to have the previous solution timings to be "almost" preserved, thus when a new request is accomodated, all the pickup and dropoff time windows of the previous requests are adjusted to force ortools to fall into the previous solution.
I know it is a very restrictive condition, but that's the service we want to implement: it is not optimizing for the overall best solution, but for serving the requests in sequence with a conservative best-effort approach toward already accepted requests
If a new request fails in being accomodated, the system will drop it and keep the previous solution.
So there's no need to define Disjunctions: it is an all-or-nothing approach. A solution that drops previous solution is not acceptable.


As an example, here is a sequence of 7 successful requests:
req_id  route_date  creation_time   pickup_id   dropoff_id  pickup_time_window   dropoff_time_window  passengers
REQ_1   2026-04-29  1777826102921   A           B           [15:30, 15:50]       [15:30, 23:59]       1
REQ_2   2026-04-29  1777826246713   C           A           [14:38, 14:58]       [14:38, 23:59]       1
REQ_3   2026-04-29  1777826631687   D           E           [15:07, 15:27]       [15:07, 23:59]       1
REQ_4   2026-04-29  1777826779455   F           G           [08:30, 08:50]       [08:30, 23:59]       1
REQ_5   2026-04-29  1777826886173   H           I           [08:30, 08:50]       [08:30, 23:59]       1
REQ_6   2026-04-29  1777826993489   H           J           [08:30, 08:50]       [08:30, 23:59]       1
REQ_7   2026-04-29  1777853799733   G           H           [19:10, 19:30]       [19:10, 23:59]       1


They have been processed one after the other in the table order .
After a solution for the requests has been found, the pickup and dropff timewindow have been changed to force the system to generate the same solution for the old request when a new one is added.
After REQ_7 has been accomodated,the following are the adjusted values actually used for the next requests:

id      route_date   new_pickup_time_window     new_dropoff_time_window
REQ_1   2026-04-29   [15:30, 15:50]             [15:42, 16:02]
REQ_2   2026-04-29   [14:58, 14:58]             [15:08, 15:28]
REQ_3   2026-04-29   [15:07, 15:27]             [15:19, 15:39]
REQ_4   2026-04-29   [08:50, 08:50]             [09:02, 09:22]
REQ_5   2026-04-29   [08:44, 08:50]             [09:04, 09:24]
REQ_6   2026-04-29   [08:44, 08:50]             [09:07, 09:27]
REQ_7   2026-04-29   [19:10, 19:30]             [19:24, 19:44]


Please note that the those "collapsed" pickup tw for REQ_2 and REQ_4 have been reduced to a single point in time before REQ_7 has been accomodated

Here is the sequence of legs after having evaluated the solution for all the 7 requests:
step      ride_date   leg_type    departureT  arrivalT   max_travel_time  id_source  source_req_id  id_destination  destination_req_id  passenger_flow  passenger_onboard_during_trip  estimated_source_destination_distance
0         2026-04-29  pickup      08:39       08:44      5                ""         ""             H               REQ_6               1               0                              1.794
1         2026-04-29  pickup      08:44       08:44      0                H          REQ_6          H               REQ_5               1               1                              0
2         2026-04-29  pickup      08:44       08:50      6                H          REQ_5          F               REQ_4               1               2                              3.515
3         2026-04-29  dropoff     08:50       09:02      12               F          REQ_4          G               REQ_4               -1              3                              7.918
4         2026-04-29  dropoff     09:02       09:04      2                G          REQ_4          I               REQ_5               -1              2                              0.396
5         2026-04-29  dropoff     09:04       09:07      3                I          REQ_5          J               REQ_6               -1              1                              1.132
6         2026-04-29  pickup      09:07       14:58      351              J          REQ_6          C               REQ_2               1               0                              3.222
7         2026-04-29  pickup      14:58       15:07      9                C          REQ_2          D               REQ_3               1               1                              2.376
8         2026-04-29  dropoff     15:07       15:13      6                D          REQ_3          A               REQ_2               -1              2                              2.7
9         2026-04-29  dropoff     15:13       15:19      6                A          REQ_2          E               REQ_3               -1              1                              3.795
10        2026-04-29  pickup      15:19       15:30      11               E          REQ_3          A               REQ_1               1               0                              3.904
11        2026-04-29  dropoff     15:30       15:42      12               A          REQ_1          B               REQ_1               -1              1                              8.45
12        2026-04-29  pickup      15:42       19:10      208              B          REQ_1          G               REQ_7               1               0                              12.777
13        2026-04-29  dropoff     19:10       19:24      14               G          REQ_7          H               REQ_7               -1              1                              9.129
14        2026-04-29  depot_end   19:24       19:27      3                H          REQ_7          ""              ""                  0               0                              1.539


Now, if I try to accommodate a new request, even one in between step 6 (with an almost 6 hour-long time window) or step 12 (with an almost 3.5 hour-long time window), the system will fail to find a solution.
And I cannot understand why: there's plenty of space there to accomodate those requests.

Here is the log of one of that failing attempts: most of them fails far before reaching the 1 sec limit. Only PATH_CHEAPEST_ARC reached it, but when I tried it with 4 s, it failed anyway.
The point is that all previous solutions were found before that 1 second limit, thus I do not understand why now it should take much more time

I0000 00:00:1777853959.503672      12 search.cc:310] Start search (memory used = 75.70 MB)
I0000 00:00:1777853959.503894      12 search.cc:310] Root node processed (time = 0 ms, constraints = 138, memory used = 75.70 MB)
I0000 00:00:1777853959.548249      12 search.cc:310] Finished search tree (time = 44 ms, branches = 140, failures = 83, memory used = 75.70 MB)
I0000 00:00:1777853959.548377      12 search.cc:310] End search (time = 44 ms, branches = 140, failures = 83, memory used = 75.70 MB, speed = 3181 branches/s)
2026-05-04 00:19:19.662814 | INFO     | ort_evaluator | OR-Tools status: 3 (ROUTING_FAIL)
2026-05-04 00:19:19.663449 | INFO     | ort_evaluator | OR-Tools euristic time_limit: 1 s
2026-05-04 00:19:19.663664 | INFO     | ort_evaluator | NO SOLUTION FOUND FOR STRATEGY AUTOMATIC.
I0000 00:00:1777853959.664590      12 search.cc:310] Start search (memory used = 75.70 MB)
I0000 00:00:1777853959.664771      12 search.cc:310] Root node processed (time = 0 ms, constraints = 138, memory used = 75.70 MB)
I0000 00:00:1777853959.750398      12 search.cc:310] Finished search tree (time = 85 ms, branches = 280, failures = 167, memory used = 75.70 MB)
I0000 00:00:1777853959.750500      12 search.cc:310] End search (time = 85 ms, branches = 280, failures = 167, memory used = 75.70 MB, speed = 3294 branches/s)
2026-05-04 00:19:19.756954 | INFO     | ort_evaluator | OR-Tools status: 3 (ROUTING_FAIL)
2026-05-04 00:19:19.757512 | INFO     | ort_evaluator | OR-Tools euristic time_limit: 1 s
2026-05-04 00:19:19.757752 | INFO     | ort_evaluator | NO SOLUTION FOUND FOR STRATEGY PARALLEL_CHEAPEST_INSERTION.
I0000 00:00:1777853959.758630      12 search.cc:310] Start search (memory used = 75.70 MB)
I0000 00:00:1777853959.758811      12 search.cc:310] Root node processed (time = 0 ms, constraints = 138, memory used = 75.70 MB)
I0000 00:00:1777853959.847166      12 search.cc:310] Finished search tree (time = 88 ms, branches = 420, failures = 258, memory used = 75.70 MB)
I0000 00:00:1777853959.847324      12 search.cc:310] End search (time = 88 ms, branches = 420, failures = 258, memory used = 75.70 MB, speed = 4772 branches/s)
2026-05-04 00:19:19.854708 | INFO     | ort_evaluator | OR-Tools status: 3 (ROUTING_FAIL)
2026-05-04 00:19:19.855256 | INFO     | ort_evaluator | OR-Tools euristic time_limit: 1 s
2026-05-04 00:19:19.855482 | INFO     | ort_evaluator | NO SOLUTION FOUND FOR STRATEGY SEQUENTIAL_CHEAPEST_INSERTION.
I0000 00:00:1777853959.856344      12 search.cc:310] Start search (memory used = 75.70 MB)
I0000 00:00:1777853959.856487      12 search.cc:310] Root node processed (time = 0 ms, constraints = 138, memory used = 75.70 MB)
I0000 00:00:1777853959.861326      12 search.cc:310] Finished search tree (time = 4 ms, branches = 560, failures = 341, memory used = 75.70 MB)
I0000 00:00:1777853959.861422      12 search.cc:310] End search (time = 5 ms, branches = 560, failures = 341, memory used = 75.70 MB, speed = 112000 branches/s)
2026-05-04 00:19:19.942909 | INFO     | ort_evaluator | OR-Tools status: 3 (ROUTING_FAIL)
2026-05-04 00:19:19.943615 | INFO     | ort_evaluator | OR-Tools euristic time_limit: 1 s
2026-05-04 00:19:19.943868 | INFO     | ort_evaluator | NO SOLUTION FOUND FOR STRATEGY LOCAL_CHEAPEST_INSERTION.
I0000 00:00:1777853959.944908      12 search.cc:310] Start search (memory used = 75.70 MB)
I0000 00:00:1777853959.945135      12 search.cc:310] Root node processed (time = 0 ms, constraints = 138, memory used = 75.70 MB)
I0000 00:00:1777853960.943955      12 search.cc:310] Finished search tree (time = 998 ms, branches = 13759, failures = 6964, memory used = 75.70 MB)
I0000 00:00:1777853960.944118      12 search.cc:310] End search (time = 999 ms, branches = 13759, failures = 6964, memory used = 75.70 MB, speed = 13772 branches/s)
2026-05-04 00:19:20.947908 | INFO     | ort_evaluator | OR-Tools status: 4 (ROUTING_FAIL_TIMEOUT)
2026-05-04 00:19:20.948456 | INFO     | ort_evaluator | OR-Tools euristic time_limit: 1 s
2026-05-04 00:19:20.948696 | INFO     | ort_evaluator | NO SOLUTION FOUND FOR STRATEGY PATH_CHEAPEST_ARC.
2026-05-04 00:19:20.948918 | INFO     | ort_evaluator | NO SOLUTION FOUND FOR ANY STRATEGY.

I hope it will help in finding/hinting the cause his undesired behaviour. Thank you!

blind.line

unread,
May 4, 2026, 9:18:47 AM (8 days ago) May 4
to or-tools...@googlegroups.com
The disjunctions are needed. 

The preliminary heuristics often need to drop nodes. 

Put in a very high disjunction penalty and the solver will add them back in. And if it doesn't, you can reject the solution yourself. 

Regards,

James

On May 4, 2026, at 11:01, Antonio Francescon <antonio.f...@openmove.com> wrote:

Hi James,

Antonio Francescon

unread,
May 4, 2026, 5:27:10 PM (8 days ago) May 4
to or-tools-discuss
Thanks James,

your suggestion fixed the issue: now it works as expected.
Thank you again.

Best regards,
Antonio

blind.line

unread,
May 5, 2026, 8:13:18 AM (7 days ago) May 5
to or-tools...@googlegroups.com
Great glad to hear it. 

For sure when you have really large problems you can expect difficulties fitting new rides in an existing schedule, but not for this size problem. 

Regards,

James

On May 4, 2026, at 23:27, Antonio Francescon <antonio.f...@openmove.com> wrote:

Thanks James,
Reply all
Reply to author
Forward
0 new messages