Closed fbaierl closed 1 year ago
I've never encountered this constraint before but it definitely makes sense in a situation when dealing with passengers.
This would indeed require to adjust TWRoute::is_valid_addition_for_tw
to discard invalid break positions when adding jobs/breaks along a modified route segment. The tricky part is that I think some validity checks should happen directly in the body of is_valid_addition_for_tw
while others should take place in order_choice
, which is called here from is_valid_addition_for_tw
and embeds the whole logic of job vs break insertion decision.
In particular, this would require to make sure that the adjustments to order_choice
do not result in ruling out valid break insertions down the line.
Feature-wise, we could see the concept of "only possible with empty vehicle" as a special case of "only possible under X
load" with X=[0...]
. The latter constraint would not be harder since both require checking against the current vehicle load. The more generic version could prove useful in other situations, something along the line of "wait until the truck is half-empty before doing the break".
The more general approach would of course be great! Another possible use-case might be if some goods need to be transported as-fast-as-possible (e.g. Pizza) while other goods that are transported at the same time (normal parcels) don't mind waiting during the break.
I will try to assemble some examples of instances that should not happen (break with load > 0) in our case. Here is a first, small, example set:
{
"vehicles": [
{
"id": 0,
"description": "0",
"start": [
12.304373066846503,
51.62270653765847
],
"end": [
12.304373066846503,
51.62270653765847
],
"capacity": [7],
"skills": [
2,
3
],
"time_window": [
1663711200,
1663797540
],
"breaks": [
{
"id": 0,
"time_windows": [
[
1663714800,
1663793940
]
],
"service": 1800
}
]
}
],
"jobs": [],
"shipments": [
{
"amount": [1],
"skills": [2],
"priority": 0,
"pickup": {
"id": 0,
"setup": 120,
"service": 0,
"location": [
12.175563,
51.694164
],
"time_windows": [
[
1663724940,
1663726260
]
],
"description": "pickup|2"
},
"delivery": {
"id": 1,
"setup": 120,
"service": 0,
"location": [
12.053810331066584,
51.69962364678002
],
"time_windows": [
[
1663728300,
1663729500
]
],
"description": "delivery|2"
}
},
{
"amount": [1],
"skills": [2],
"priority": 0,
"pickup": {
"id": 2,
"setup": 120,
"service": 0,
"location": [
12.219437,
51.715622
],
"time_windows": [
[
1663720440,
1663722240
]
],
"description": "pickup|1"
},
"delivery": {
"id": 3,
"setup": 120,
"service": 0,
"location": [
12.175563,
51.694164
],
"time_windows": [
[
1663722240,
1663723560
]
],
"description": "delivery|1"
}
}
]
}
{
"code": 0,
"summary": {
"cost": 3824,
"routes": 1,
"unassigned": 0,
"delivery": [
2
],
"amount": [
2
],
"pickup": [
2
],
"setup": 360,
"service": 1800,
"duration": 3824,
"waiting_time": 2613,
"priority": 0,
"distance": 53560,
"violations": [],
"computing_times": {
"loading": 5,
"solving": 1,
"routing": 2
}
},
"unassigned": [],
"routes": [
{
"vehicle": 0,
"cost": 3824,
"description": "0",
"delivery": [
2
],
"amount": [
2
],
"pickup": [
2
],
"setup": 360,
"service": 1800,
"duration": 3824,
"waiting_time": 2613,
"priority": 0,
"distance": 53560,
"steps": [
{
"type": "start",
"location": [
12.304373066846503,
51.62270653765847
],
"setup": 0,
"service": 0,
"waiting_time": 0,
"load": [
0
],
"arrival": 1663721245,
"duration": 0,
"violations": [],
"distance": 0
},
{
"type": "pickup",
"description": "pickup|1",
"location": [
12.219437,
51.715622
],
"id": 2,
"setup": 120,
"service": 0,
"waiting_time": 0,
"job": 2,
"load": [
1
],
"arrival": 1663722240,
"duration": 995,
"violations": [],
"distance": 13548
},
{
"type": "delivery",
"description": "delivery|1",
"location": [
12.175563,
51.694164
],
"id": 3,
"setup": 120,
"service": 0,
"waiting_time": 0,
"job": 3,
"load": [
0
],
"arrival": 1663722831,
"duration": 1466,
"violations": [],
"distance": 20119
},
{
"type": "pickup",
"description": "pickup|2",
"location": [
12.175563,
51.694164
],
"id": 0,
"setup": 0,
"service": 0,
"waiting_time": 1989,
"job": 0,
"load": [
1
],
"arrival": 1663722951,
"duration": 1466,
"violations": [],
"distance": 20119
},
{
"type": "break",
"location_index": 0,
"id": 0,
"setup": 0,
"service": 1800,
"waiting_time": 0,
"load": [
1
],
"arrival": 1663724940,
"duration": 1466,
"violations": [],
"distance": 20119
},
{
"type": "delivery",
"description": "delivery|2",
"location": [
12.053810331066584,
51.69962364678002
],
"id": 1,
"setup": 120,
"service": 0,
"waiting_time": 624,
"job": 1,
"load": [
0
],
"arrival": 1663727676,
"duration": 2402,
"violations": [],
"distance": 29211
},
{
"type": "end",
"location": [
12.304373066846503,
51.62270653765847
],
"setup": 0,
"service": 0,
"waiting_time": 0,
"load": [
0
],
"arrival": 1663729842,
"duration": 3824,
"violations": [],
"distance": 53560
}
],
"violations": [],
"geometry": "_razH{dbjAk@_GCS_A\\s@XMDSPMDKByAXSBe@Bk@HWHFl@LpAZtC@LDh@QFgBp@_EvA}@\\mE`B_@Li@T{EdBkFnBeBn@sG`C_AZeAb@_@N_@N]NIBUJ}@\\yNpFqG`Cu@Ne@NuAb@_@LaA^]PIHKFkE|C_Av@qBzAo@b@aEtCwClBiAx@w@~@[`@W`@m@xA}@jBYj@KTUl@Ud@Uf@_@p@_@r@y@|@oErEiFrFUTwU~V]b@y@`Bm@pAo@rAuAjCi@dA]v@OXeBjDg@jA_HfOEJWl@ABQ~@CJi@rEQtACRq@]{Au@i@W}@a@]Q[M[IGCe@MkAWaAKaE]c@GqD[g@GyAK_@?_ABgANOBeBb@iCt@_Bl@_@NIB]P_@Tq@f@iAr@KHa@VYHc@JuBJSCgCWgDc@SKcA_@UOYSg@g@Y]aAmAIIMKOIOGMEOEOCaBUuAQ_@E]Aq@Bg@JUFYL_@Rm@^sC|Ao@T[Fa@BE@]BuBRyAJM@mAHaAFqAE_@C}AG_AE{@Eq@Aq@?iAJ]D{@N{@PyB`@e@HSBcANu@B}AHkAHq@DSBsARcAT[HeAVo@NcCj@UF]H{Bh@IB_B\\a@HmDt@eDz@qBb@uBf@]LYJUJMBKJEFCBUh@Yt@I\\G\\EZGn@Ap@WvOCl@GxBEv@Iv@Kj@IXIVOZMNOLMFKDgAZe@NYNk@\\{BjAc@R}FlCmCnAeAd@c@Ra@Pg@X]Tq@d@[XIFCBKHYT}AlAs@h@u@n@kStPoTrQkB~AaEdDqAdAcEjDmMnKyM|KsDzCO~AqExi@oFjo@iB|Te@dFs@|GOn@e@`Ac@l@sBhDVv@FrCNvGSb@SdJAl@DfAZdD[eDEgAsEz@qARSGQQYbBW~AUzAQtAQbBStBS`COfCGnBGlBATQfF?BEfBA|@?vA?bADfBDlAHrAJxALtAN|APhCNzD@pBUpMcDfcBWxNIdDIbFCh@L\\^NTDj@Hl@?fEMfGo@vAQ|@Kt@KRApAM~DQnAEvAEl@?b@FjBb@`ARb@Bn@Ex@MpNgDb@OTOVKXAn@?b@E`LaCzFmAzG{AbRyDfAfQLtBBjA?zAGhP?fC@nADbADx@Hf@J`ARdATbA`@pAf@jAd@v@p@dAn@bAp@jAf@bA^lAf@|BVhBRbCJ~@jDy@fBe@rDeAXAGuG?oB???nBFtG@dAKxAYvECv@?lA@d@LdE@L@pA?|APvANv@TvAJj@bAxJNbAJp@R`ADX@^Cl@Ir@i@lDa@lCiC|PsCtRQvAkFlh@uAlMKrACbA?^?f@DlAHdECjD?nCBdADbAPjBRpBZdDzCl_@pCnc@|Cnf@dDxj@HpAn@lJDn@TrEPxEh@xILjBcAf@[h@Ap@Z|FXvGDdACr@s@lB}@`CsE|LkAbD{DdKg@~@i@ZqEnC]PB\\B`AbD`iA@X@n@JTDBHv@RhAFl@Bn@J`K?FGpD?DI~EFzIA^G\\_@l@GTCTFzIFvBH|CdBzl@l@vSb@vOHtAm@r@o@r@uCrCk@t@e@|@gA|Ce@lAKVOZUd@KPYh@a@v@O\\Ib@Gb@AP?Z?LBRJp@Dd@AZCJGJKNa@Rm@FoDf@WDVEnDg@l@G`@SJOFKBK@[Ee@Kq@CS?M?[@QFc@Hc@N]`@w@Xi@JQTe@N[JWd@mAfA}Cd@}@j@u@tCsCn@s@l@s@t@qA|D}IHQ`AuAdAkAl@k@r@e@NGxAo@vAo@jAm@~@s@ZYxE{D~EuDdBkAbAm@bAo@fAo@fBeA|@i@ZOhAq@nAm@t@g@p@g@dAaAbGaFlAaAXWNKh@e@v@s@n@U|@Sd@MVIPKTY|@cAj@u@PUPSRWV[VQTKFEFClBm@l@Sr@S^MTIVMVQf@o@Xo@V}@Hi@Fc@@]@_@?_@?c@?_@EoDCeBEoA?mA@}@Dy@Dq@Jo@Ju@Nk@^qAVu@Tc@P[HOBCX_@\\a@TSTOTQVKrB}@vD_BrCuA~BsAr@a@hBeAfAo@p@_@pIaFjGoD~A_AlDsBjLuG^Ql@Yf@S\\Kd@Kd@GdAGtA?\\BZDTBVFj@JjAd@d@Tx@f@vA~@lIjGvKdIjBdAd@Rj@P\\J|@LZBZ@V?|@Ct@I`@IPGREb@Q~@a@j@a@t@m@r@u@`@i@`@k@Vc@Te@Xm@`@eAX}@r@sC@G@GRkAp@yFx@qHXmCd@iDn@{Cr@mCn@kBJ[Ri@b@}@`@s@d@w@nAeBt@{@x@q@NM`@YHErPiM`KqH`As@xAqAhBiBhBeCpBiDfA}Bx@yBL[b@wAv@yC`@_Bl@eDf@kDXyCf@_GNeCPqCFqABc@Dy@D{@NoCNoCHoA|AeYh@qJr@gMXgFZeGLaCHgAP_DJgAHaAL{@^eCTgA\\}ATq@j@eBz@wBr@sA^q@Zc@`@m@dBuBjEcFzAmBzAiChBmEhAwDt@{DV{AFm@JkAHiADy@FqBDgB@wAAeACiBE{@IeBSeCm@aGgBcRoBqS{BwUiA{L}Dsa@q@aHiAqL{@yIq@iHw@}H]mD_@iEi@}FQ{BQuDGoCE_CA{BBeEJ{DH{AJ}BRmCH{@L}AL{A\\oDHmAN{AZmD\\sDd@cF`@uER_CTsCNoBNsBFuAFaBPoEBiA@iABeB?e@DsG?[?iB?qB?aBAiAEiBA[EmBIuCK_D[cGMcBk@{HoF{j@m@qGMmAe@qFKcAEc@OyAk@mGi@yEo@{GCWyN}zAo@eFm@_Ec@oCe@oCWyAg@kCIa@[}AI[ScAc@yBg@eCYuAcA{E_@oBWkBQeAKeAU{CeAca@CwC@uBLqGn@_SXuIPeDPuCZiDZyC`@}Cf@yCr@kDv@cDz@aD`AwC`CiGfCiGdS_f@hC_F`BqCh@w@^i@l@}@h@s@`AiAnAsApAmAbDoChCcBhCyAXQ`DqAdDmAdEwA~DeAnKoCl@Ij@Dn@Jh@Nd@XlC~A~@h@PJ^RLHFo@H{@F_@J{@He@dAwGh@eD^uBZiBBKBUF]L}@X_CH{@F{@DsAAe@CmAKqBSuBOgBKw@g@eFGq@S_CK_As@cIw@eIWaCCQs@iHO}AKgAy@cIGm@e@sEEi@AM[uCMqAGm@VIj@Id@CRCxAYJCLET?bC{@j@~F"
}
]
}
We encountered another example:
{
"vehicles": [
{
"id": 0,
"description": "144",
"start": [
12.12023,
51.62729
],
"end": [
12.12023,
51.62729
],
"capacity": [
5
],
"skills": [
2,
3
],
"time_window": [
1664946000,
1665007140
],
"breaks": [
{
"id": 0,
"time_windows": [
[
1664949600,
1665003540
]
],
"service": 1800
}
]
}
],
"jobs": [],
"shipments": [
{
"amount": [
1
],
"skills": [
2
],
"priority": 0,
"pickup": {
"id": 0,
"setup": 120,
"service": 0,
"location": [
12.040338,
51.855626
],
"time_windows": [
[
1664967840,
1664967960
]
],
"description": "pickup|168"
},
"delivery": {
"id": 1,
"setup": 120,
"service": 0,
"location": [
12.236515,
51.839965
],
"time_windows": [
[
1664969280,
1664969400
]
],
"description": "delivery|168"
}
},
{
"amount": [
1
],
"skills": [
2
],
"priority": 0,
"pickup": {
"id": 2,
"setup": 120,
"service": 0,
"location": [
11.877072,
51.685026
],
"time_windows": [
[
1664963460,
1664963580
]
],
"description": "pickup|169"
},
"delivery": {
"id": 3,
"setup": 120,
"service": 0,
"location": [
12.043737,
51.851779
],
"time_windows": [
[
1664967420,
1664967540
]
],
"description": "delivery|169"
}
},
{
"amount": [
2
],
"skills": [
2
],
"priority": 0,
"pickup": {
"id": 4,
"setup": 120,
"service": 0,
"location": [
11.877072,
51.685026
],
"time_windows": [
[
1664963460,
1664963580
]
],
"description": "pickup|170"
},
"delivery": {
"id": 5,
"setup": 120,
"service": 0,
"location": [
12.036454,
51.853146
],
"time_windows": [
[
1664967540,
1664967660
]
],
"description": "delivery|170"
}
},
{
"amount": [
2
],
"skills": [
2
],
"priority": 0,
"pickup": {
"id": 6,
"setup": 120,
"service": 0,
"location": [
12.036454,
51.853146
],
"time_windows": [
[
1664967720,
1664967840
]
],
"description": "pickup|171"
},
"delivery": {
"id": 7,
"setup": 120,
"service": 0,
"location": [
12.04465,
51.854543
],
"time_windows": [
[
1664967960,
1664968080
]
],
"description": "delivery|171"
}
},
{
"amount": [
1
],
"skills": [
2
],
"priority": 0,
"pickup": {
"id": 8,
"setup": 120,
"service": 0,
"location": [
11.988443,
51.750608
],
"time_windows": [
[
1664973120,
1664973240
]
],
"description": "pickup|172"
},
"delivery": {
"id": 9,
"setup": 120,
"service": 0,
"location": [
12.043737,
51.851779
],
"time_windows": [
[
1664974620,
1664974740
]
],
"description": "delivery|172"
}
},
{
"amount": [
1
],
"skills": [
2
],
"priority": 0,
"pickup": {
"id": 10,
"setup": 120,
"service": 0,
"location": [
12.04465,
51.854543
],
"time_windows": [
[
1664967960,
1664968080
]
],
"description": "pickup|173"
},
"delivery": {
"id": 11,
"setup": 120,
"service": 0,
"location": [
11.988111,
51.752378
],
"time_windows": [
[
1664969580,
1664969700
]
],
"description": "delivery|173"
}
}
]
}
{
"code": 0,
"summary": {
"cost": 7608,
"routes": 1,
"unassigned": 2,
"delivery": [
7
],
"amount": [
7
],
"pickup": [
7
],
"setup": 840,
"service": 1800,
"duration": 7608,
"waiting_time": 4838,
"priority": 0,
"violations": [],
"computing_times": {
"loading": 23,
"solving": 3
}
},
"unassigned": [
{
"id": 1,
"location": [
12.236515,
51.839965
],
"type": "delivery"
},
{
"id": 0,
"location": [
12.040338,
51.855626
],
"type": "pickup"
}
],
"routes": [
{
"vehicle": 0,
"cost": 7608,
"description": "144",
"delivery": [
7
],
"amount": [
7
],
"pickup": [
7
],
"setup": 840,
"service": 1800,
"duration": 7608,
"waiting_time": 4838,
"priority": 0,
"steps": [
{
"type": "start",
"location": [
12.12023,
51.62729
],
"setup": 0,
"service": 0,
"waiting_time": 0,
"load": [
0
],
"arrival": 1664961707,
"duration": 0,
"violations": []
},
{
"type": "pickup",
"description": "pickup|169",
"location": [
11.877072,
51.685026
],
"id": 2,
"setup": 120,
"service": 0,
"waiting_time": 0,
"job": 2,
"load": [
1
],
"arrival": 1664963460,
"duration": 1753,
"violations": []
},
{
"type": "pickup",
"description": "pickup|170",
"location": [
11.877072,
51.685026
],
"id": 4,
"setup": 0,
"service": 0,
"waiting_time": 0,
"job": 4,
"load": [
3
],
"arrival": 1664963580,
"duration": 1753,
"violations": []
},
{
"type": "break",
"id": 0,
"setup": 0,
"service": 1800,
"waiting_time": 0,
"load": [
3
],
"arrival": 1664963580,
"duration": 1753,
"violations": []
},
{
"type": "delivery",
"description": "delivery|169",
"location": [
12.043737,
51.851779
],
"id": 3,
"setup": 120,
"service": 0,
"waiting_time": 267,
"job": 3,
"load": [
2
],
"arrival": 1664967153,
"duration": 3526,
"violations": []
},
{
"type": "delivery",
"description": "delivery|170",
"location": [
12.036454,
51.853146
],
"id": 5,
"setup": 120,
"service": 0,
"waiting_time": 0,
"job": 5,
"load": [
0
],
"arrival": 1664967627,
"duration": 3613,
"violations": []
},
{
"type": "pickup",
"description": "pickup|171",
"location": [
12.036454,
51.853146
],
"id": 6,
"setup": 0,
"service": 0,
"waiting_time": 0,
"job": 6,
"load": [
2
],
"arrival": 1664967747,
"duration": 3613,
"violations": []
},
{
"type": "pickup",
"description": "pickup|173",
"location": [
12.04465,
51.854543
],
"id": 10,
"setup": 120,
"service": 0,
"waiting_time": 101,
"job": 10,
"load": [
3
],
"arrival": 1664967859,
"duration": 3725,
"violations": []
},
{
"type": "delivery",
"description": "delivery|171",
"location": [
12.04465,
51.854543
],
"id": 7,
"setup": 0,
"service": 0,
"waiting_time": 0,
"job": 7,
"load": [
1
],
"arrival": 1664968080,
"duration": 3725,
"violations": []
},
{
"type": "delivery",
"description": "delivery|173",
"location": [
11.988111,
51.752378
],
"id": 11,
"setup": 120,
"service": 0,
"waiting_time": 581,
"job": 11,
"load": [
0
],
"arrival": 1664968999,
"duration": 4644,
"violations": []
},
{
"type": "pickup",
"description": "pickup|172",
"location": [
11.988443,
51.750608
],
"id": 8,
"setup": 120,
"service": 0,
"waiting_time": 3354,
"job": 8,
"load": [
1
],
"arrival": 1664969766,
"duration": 4710,
"violations": []
},
{
"type": "delivery",
"description": "delivery|172",
"location": [
12.043737,
51.851779
],
"id": 9,
"setup": 120,
"service": 0,
"waiting_time": 535,
"job": 9,
"load": [
0
],
"arrival": 1664974085,
"duration": 5555,
"violations": []
},
{
"type": "end",
"location": [
12.12023,
51.62729
],
"setup": 0,
"service": 0,
"waiting_time": 0,
"load": [
0
],
"arrival": 1664976793,
"duration": 7608,
"violations": []
}
],
"violations": []
}
]
}
Here is one more example combined with how we use jobs (as discussed here):
{
"vehicles": [
{
"id": 0,
"description": "1",
"start": [
12.304373066846503,
51.62270653765847
],
"end": [
12.304373066846503,
51.62270653765847
],
"capacity": [
6,
0
],
"skills": [
1000,
2,
5
],
"time_window": [
1667960100,
1668034799
],
"breaks": [
{
"id": 0,
"time_windows": [
[
1667962800,
1668029399
]
],
"service": 1800
}
]
},
{
"id": 1,
"description": "2",
"start": [
12.304373066846503,
51.62270653765847
],
"end": [
12.304373066846503,
51.62270653765847
],
"capacity": [
6,
0
],
"skills": [
1001,
2,
5
],
"time_window": [
1667960100,
1668034799
],
"breaks": [
{
"id": 0,
"time_windows": [
[
1667962800,
1668029399
]
],
"service": 1800
}
]
}
],
"jobs": [
{
"id": 0,
"pickup": [
0,
0
],
"delivery": [
0,
0
],
"description": "filler job|shift start",
"skills": [
1000
],
"location": [
12.304373066846503,
51.62270653765847
],
"time_windows": [
[
1667959200,
1667966561
]
],
"priority": 100
},
{
"id": 1,
"pickup": [
0,
0
],
"delivery": [
0,
0
],
"description": "empty_sl|start|2",
"skills": [
1000
],
"location": [
12.304373066846503,
51.62270653765847
],
"time_windows": [
[
1667966562,
1667966562
]
],
"priority": 100
},
{
"id": 2,
"pickup": [
0,
0
],
"delivery": [
0,
0
],
"description": "empty_sl|goal|2",
"skills": [
1000
],
"location": [
12.339628298893272,
51.616508956851234
],
"time_windows": [
[
1667967004,
1667967004
]
],
"priority": 100
},
{
"id": 3,
"pickup": [
0,
0
],
"delivery": [
0,
0
],
"description": "filler job|shift start",
"skills": [
1001
],
"location": [
12.304373066846503,
51.62270653765847
],
"time_windows": [
[
1667959200,
1667966921
]
],
"priority": 100
},
{
"id": 4,
"pickup": [
0,
0
],
"delivery": [
0,
0
],
"description": "filler job|between",
"skills": [
1001
],
"location": [
12.256255557036216,
51.66321226116415
],
"time_windows": [
[
1667967480,
1667967599
]
],
"priority": 100
},
{
"id": 5,
"pickup": [
0,
0
],
"delivery": [
0,
0
],
"description": "empty_sl|start|5",
"skills": [
1001
],
"location": [
12.304373066846503,
51.62270653765847
],
"time_windows": [
[
1667966922,
1667966922
]
],
"priority": 100
}
],
"shipments": [
{
"amount": [
1,
0
],
"skills": [
1001,
5
],
"priority": 100,
"pickup": {
"id": 6,
"setup": 0,
"service": 0,
"location": [
12.256255557036216,
51.66321226116415
],
"time_windows": [
[
1667967600,
1667967600
]
],
"description": "pickup|5"
},
"delivery": {
"id": 7,
"setup": 0,
"service": 0,
"location": [
12.389050580844362,
51.631333450834106
],
"time_windows": [
[
1667971020,
1667971020
]
],
"description": "delivery|5"
}
},
{
"amount": [
2,
0
],
"skills": [
1001,
5
],
"priority": 100,
"pickup": {
"id": 8,
"setup": 120,
"service": 0,
"location": [
12.256255557036216,
51.66321226116415
],
"time_windows": [
[
1667967480,
1667967480
]
],
"description": "pickup|4"
},
"delivery": {
"id": 9,
"setup": 120,
"service": 0,
"location": [
12.339628298893272,
51.616508956851234
],
"time_windows": [
[
1667971717,
1667971717
]
],
"description": "delivery|4"
}
},
{
"amount": [
2,
0
],
"skills": [
2,
5
],
"priority": 0,
"pickup": {
"id": 10,
"setup": 120,
"service": 0,
"location": [
12.33964753530686,
51.66711418531879
],
"time_windows": [
[
1667969160,
1667970240
]
],
"description": "pickup|3"
},
"delivery": {
"id": 11,
"setup": 120,
"service": 0,
"location": [
12.339628298893272,
51.616508956851234
],
"time_windows": [
[
1667975220,
1667976420
]
],
"description": "delivery|3"
}
},
{
"amount": [
2,
0
],
"skills": [
2,
5
],
"priority": 0,
"pickup": {
"id": 12,
"setup": 120,
"service": 0,
"location": [
12.339628298893272,
51.616508956851234
],
"time_windows": [
[
1667965980,
1667967300
]
],
"description": "pickup|6"
},
"delivery": {
"id": 13,
"setup": 120,
"service": 0,
"location": [
12.33964753530686,
51.66711418531879
],
"time_windows": [
[
1667971620,
1667972820
]
],
"description": "delivery|6"
}
},
{
"amount": [
2,
0
],
"skills": [
2,
5
],
"priority": 0,
"pickup": {
"id": 14,
"setup": 120,
"service": 0,
"location": [
12.33964753530686,
51.66711418531879
],
"time_windows": [
[
1667969160,
1667970240
]
],
"description": "pickup|8"
},
"delivery": {
"id": 15,
"setup": 120,
"service": 0,
"location": [
12.339628298893272,
51.616508956851234
],
"time_windows": [
[
1667975220,
1667976420
]
],
"description": "delivery|8"
}
}
]
}
{
"code": 0,
"summary": {
"cost": 4983,
"routes": 2,
"unassigned": 0,
"delivery": [
9,
0
],
"amount": [
9,
0
],
"pickup": [
9,
0
],
"setup": 360,
"service": 3600,
"duration": 4983,
"waiting_time": 5568,
"priority": 1000,
"violations": [],
"computing_times": {
"loading": 11,
"solving": 6
}
},
"unassigned": [],
"routes": [
{
"vehicle": 0,
"cost": 2461,
"description": "1",
"delivery": [
6,
0
],
"amount": [
6,
0
],
"pickup": [
6,
0
],
"setup": 240,
"service": 1800,
"duration": 2461,
"waiting_time": 4686,
"priority": 300,
"steps": [
{
"type": "start",
"location": [
12.304373066846503,
51.62270653765847
],
"setup": 0,
"service": 0,
"waiting_time": 0,
"load": [
0,
0
],
"arrival": 1667966561,
"duration": 0,
"violations": []
},
{
"type": "job",
"description": "filler job|shift start",
"location": [
12.304373066846503,
51.62270653765847
],
"id": 0,
"setup": 0,
"service": 0,
"waiting_time": 0,
"job": 0,
"load": [
0,
0
],
"arrival": 1667966561,
"duration": 0,
"violations": []
},
{
"type": "job",
"description": "empty_sl|start|2",
"location": [
12.304373066846503,
51.62270653765847
],
"id": 1,
"setup": 0,
"service": 0,
"waiting_time": 1,
"job": 1,
"load": [
0,
0
],
"arrival": 1667966561,
"duration": 0,
"violations": []
},
{
"type": "job",
"description": "empty_sl|goal|2",
"location": [
12.339628298893272,
51.616508956851234
],
"id": 2,
"setup": 0,
"service": 0,
"waiting_time": 0,
"job": 2,
"load": [
0,
0
],
"arrival": 1667967004,
"duration": 442,
"violations": []
},
{
"type": "pickup",
"description": "pickup|6",
"location": [
12.339628298893272,
51.616508956851234
],
"id": 12,
"setup": 0,
"service": 0,
"waiting_time": 0,
"job": 12,
"load": [
2,
0
],
"arrival": 1667967004,
"duration": 442,
"violations": []
},
{
"type": "pickup",
"description": "pickup|8",
"location": [
12.33964753530686,
51.66711418531879
],
"id": 14,
"setup": 120,
"service": 0,
"waiting_time": 1358,
"job": 14,
"load": [
4,
0
],
"arrival": 1667967802,
"duration": 1240,
"violations": []
},
{
"type": "pickup",
"description": "pickup|3",
"location": [
12.33964753530686,
51.66711418531879
],
"id": 10,
"setup": 0,
"service": 0,
"waiting_time": 0,
"job": 10,
"load": [
6,
0
],
"arrival": 1667969280,
"duration": 1240,
"violations": []
},
{
"type": "break",
"id": 0,
"setup": 0,
"service": 1800,
"waiting_time": 0,
"load": [
6,
0
],
"arrival": 1667969280,
"duration": 1240,
"violations": []
},
{
"type": "delivery",
"description": "delivery|6",
"location": [
12.33964753530686,
51.66711418531879
],
"id": 13,
"setup": 0,
"service": 0,
"waiting_time": 540,
"job": 13,
"load": [
4,
0
],
"arrival": 1667971080,
"duration": 1240,
"violations": []
},
{
"type": "delivery",
"description": "delivery|8",
"location": [
12.339628298893272,
51.616508956851234
],
"id": 15,
"setup": 120,
"service": 0,
"waiting_time": 2787,
"job": 15,
"load": [
2,
0
],
"arrival": 1667972433,
"duration": 2053,
"violations": []
},
{
"type": "delivery",
"description": "delivery|3",
"location": [
12.339628298893272,
51.616508956851234
],
"id": 11,
"setup": 0,
"service": 0,
"waiting_time": 0,
"job": 11,
"load": [
0,
0
],
"arrival": 1667975340,
"duration": 2053,
"violations": []
},
{
"type": "end",
"location": [
12.304373066846503,
51.62270653765847
],
"setup": 0,
"service": 0,
"waiting_time": 0,
"load": [
0,
0
],
"arrival": 1667975748,
"duration": 2461,
"violations": []
}
],
"violations": []
},
{
"vehicle": 1,
"cost": 2522,
"description": "2",
"delivery": [
3,
0
],
"amount": [
3,
0
],
"pickup": [
3,
0
],
"setup": 120,
"service": 1800,
"duration": 2522,
"waiting_time": 882,
"priority": 700,
"steps": [
{
"type": "start",
"location": [
12.304373066846503,
51.62270653765847
],
"setup": 0,
"service": 0,
"waiting_time": 0,
"load": [
0,
0
],
"arrival": 1667966921,
"duration": 0,
"violations": []
},
{
"type": "job",
"description": "filler job|shift start",
"location": [
12.304373066846503,
51.62270653765847
],
"id": 3,
"setup": 0,
"service": 0,
"waiting_time": 0,
"job": 3,
"load": [
0,
0
],
"arrival": 1667966921,
"duration": 0,
"violations": []
},
{
"type": "job",
"description": "empty_sl|start|5",
"location": [
12.304373066846503,
51.62270653765847
],
"id": 5,
"setup": 0,
"service": 0,
"waiting_time": 1,
"job": 5,
"load": [
0,
0
],
"arrival": 1667966921,
"duration": 0,
"violations": []
},
{
"type": "job",
"description": "filler job|between",
"location": [
12.256255557036216,
51.66321226116415
],
"id": 4,
"setup": 0,
"service": 0,
"waiting_time": 0,
"job": 4,
"load": [
0,
0
],
"arrival": 1667967480,
"duration": 558,
"violations": []
},
{
"type": "pickup",
"description": "pickup|4",
"location": [
12.256255557036216,
51.66321226116415
],
"id": 8,
"setup": 0,
"service": 0,
"waiting_time": 0,
"job": 8,
"load": [
2,
0
],
"arrival": 1667967480,
"duration": 558,
"violations": []
},
{
"type": "pickup",
"description": "pickup|5",
"location": [
12.256255557036216,
51.66321226116415
],
"id": 6,
"setup": 0,
"service": 0,
"waiting_time": 120,
"job": 6,
"load": [
3,
0
],
"arrival": 1667967480,
"duration": 558,
"violations": []
},
{
"type": "break",
"id": 0,
"setup": 0,
"service": 1800,
"waiting_time": 0,
"load": [
3,
0
],
"arrival": 1667967600,
"duration": 558,
"violations": []
},
{
"type": "delivery",
"description": "delivery|5",
"location": [
12.389050580844362,
51.631333450834106
],
"id": 7,
"setup": 0,
"service": 0,
"waiting_time": 581,
"job": 7,
"load": [
2,
0
],
"arrival": 1667970439,
"duration": 1597,
"violations": []
},
{
"type": "delivery",
"description": "delivery|4",
"location": [
12.339628298893272,
51.616508956851234
],
"id": 9,
"setup": 120,
"service": 0,
"waiting_time": 180,
"job": 9,
"load": [
0,
0
],
"arrival": 1667971537,
"duration": 2114,
"violations": []
},
{
"type": "end",
"location": [
12.304373066846503,
51.62270653765847
],
"setup": 0,
"service": 0,
"waiting_time": 0,
"load": [
0,
0
],
"arrival": 1667972245,
"duration": 2522,
"violations": []
}
],
"violations": []
}
]
}
Landed with #794.
Feature
I would like to request a feature to only schedule breaks at a time, where the respective vehicle is empty (load is empty).
Motivation
We work with public transport so we transport people. For obvious reasons, we cannot schedule a break at a time, where customers are still inside the vehicle, so this would be an essential feature for all use-cases, where people are transported (with time-windows).
API
For the API, this could be achieved by setting an additional parameter (e.g.
while_transport
) to the break input definition:id
time_windows
time_window
objects describing valid slots for break startwhile_transport
]service
]description
]Implementation
As we previously discussed here, this might be possible with adapting
TWRoute::is_valid_addition_for_tw
.Support
We would be willing to fund the implementation of this feature. Would it be possible to get a quote for this?