Page 1 of 1
USECASE service technicians
Posted: Wed Jun 28, 2017 5:16 pm
by Bernd Welter
Hi there,
I have a challenge for the community - maybe someone of you can see an approach I don't see so far.
It is about a tour optimization of service technicians under the following constraints (I'll use xTour terms if possible)
- We have several thousand basic areas, e.g. all postcode areas in a country
- We have several hundred VEHICLES. For each one we know the basic areas it is allowed to serve, e.g.
Vehicle 1: {76131, 76133, 76185...}
Vehicle 2: {76133, 76185, 76351...}
and so on
- We want to serve several hundred or even thousand ORDERs, for each one we know the unique postcode:
ORDER 1: {76131}
ORDER 2: {76133}
...
ORDER ... : {PLZ??}
Now as you can already see from my approach of displaying this it is possible to design this via SKILLS from a logical perspective: Each ORDER has exactly ONE SKILL, VEHICLES might have several skills.
But: according to the documentation the number of SKILLS is limited:
Available equipment of the vehicle to satisfy transport order requirements (1 <= x <= 512, optional). There are up to 512 different equipment flags possible. Omitting this attribute means that the vehicle has no equipment flags.
Question that arise:
- does this simply mean that the array length for equipment is restricted to not exceed 512 but if needed the number of used skill entities could exceed 512? (e.g. VEHICLE 1 = {1,2,3,....511}, VEHICLE 2: {512, 513, ...1023})
- what other approaches could you imagine to use to solve this challenge?
Best regards
Bernd
Re: USECASE service technicians
Posted: Wed Jun 28, 2017 5:38 pm
by Bernd Welter
OK, just tested: skill accepts only the int values 1...512.
So it is not only the array length - it is even worse... Even the entities themselves are regulated ;-(
Code: Select all
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<soap:Body>
<planBasicTours xmlns="http://types.xtour.xserver.ptvag.com">
<ArrayOfTransportOrder_1>
<TransportOrder xsi:type="TransportDepot" id="1" trailerLoadingForbidden="false" xmlns="http://xtour.xserver.ptvag.com">
<maxLoadingArea xsi:nil="true" />
<minLoadingArea xsi:nil="true" />
<wrappedVehicleCategories xsi:nil="true" />
<wrappedVehicleExclusions xsi:nil="true" />
<wrappedVehicleRequirements>
<Int xmlns="http://wrappertypes.service.jabba.ptvag.com">1</Int>
</wrappedVehicleRequirements>
<deliveryQuantities xsi:nil="true" />
<wrappedDepotIds xsi:nil="true" />
<pickupQuantities xsi:nil="true" />
<transportPoint id="1" allowServiceSplit="false" coDriverRequired="false" openingIntervalConstraint="START_OF_SERVICE" servicePeriod="0" tourSection="0" useServicePeriodForRecreation="false">
<location wkt="POINT(123456 6560000)">
<kml xsi:nil="true" xmlns="http://common.xserver.ptvag.com" />
<point xsi:nil="true" xmlns="http://common.xserver.ptvag.com" />
</location>
<wrappedOpeningIntervals xsi:nil="true" />
</transportPoint>
</TransportOrder>
<TransportOrder xsi:type="TransportDepot" id="2" trailerLoadingForbidden="false" xmlns="http://xtour.xserver.ptvag.com">
<maxLoadingArea xsi:nil="true" />
<minLoadingArea xsi:nil="true" />
<wrappedVehicleCategories xsi:nil="true" />
<wrappedVehicleExclusions xsi:nil="true" />
<wrappedVehicleRequirements>
<Int xmlns="http://wrappertypes.service.jabba.ptvag.com">2</Int>
</wrappedVehicleRequirements>
<deliveryQuantities xsi:nil="true" />
<wrappedDepotIds xsi:nil="true" />
<pickupQuantities xsi:nil="true" />
<transportPoint id="2" allowServiceSplit="false" coDriverRequired="false" openingIntervalConstraint="START_OF_SERVICE" servicePeriod="0" tourSection="0" useServicePeriodForRecreation="false">
<location wkt="POINT(123456 6560000)">
<kml xsi:nil="true" xmlns="http://common.xserver.ptvag.com" />
<point xsi:nil="true" xmlns="http://common.xserver.ptvag.com" />
</location>
<wrappedOpeningIntervals xsi:nil="true" />
</transportPoint>
</TransportOrder>
</ArrayOfTransportOrder_1>
<ArrayOfDepot_2>
<Depot id="666" xmlns="http://xtour.xserver.ptvag.com">
<location wkt="POINT(123456 6560000)">
<kml xsi:nil="true" xmlns="http://common.xserver.ptvag.com" />
<point xsi:nil="true" xmlns="http://common.xserver.ptvag.com" />
</location>
<wrappedOpeningIntervals xsi:nil="true" />
</Depot>
</ArrayOfDepot_2>
<Fleet_3>
<wrappedTrailers xsi:nil="true" xmlns="http://xtour.xserver.ptvag.com" />
<wrappedTrains xsi:nil="true" xmlns="http://xtour.xserver.ptvag.com" />
<wrappedVehicles xmlns="http://xtour.xserver.ptvag.com">
<Vehicle depotIdEnd="666" depotIdStart="666" coDriverStatus="NEVER" ignoreTransportPointServicePeriod="false" isPreloaded="false" toursMustFitIntoSingleOperatingInterval="false" id="1" ignoreIntermediatePeriodBeforeFirstTour="false">
<wrappedOperatingIntervals xsi:nil="true" />
<capacities xsi:nil="true" />
<costs xsi:nil="true" />
<driverSettings xsi:nil="true" />
<wrappedAreaNumbers xsi:nil="true" />
<endLocation xsi:nil="true" />
<maxLoadingArea xsi:nil="true" />
<minLoadingArea xsi:nil="true" />
<restrictions xsi:nil="true" />
<startLocation xsi:nil="true" />
<wrappedTransportEquipments xsi:nil="true" />
</Vehicle>
<Vehicle depotIdEnd="666" depotIdStart="666" coDriverStatus="NEVER" ignoreTransportPointServicePeriod="false" isPreloaded="false" toursMustFitIntoSingleOperatingInterval="false" id="2" ignoreIntermediatePeriodBeforeFirstTour="false">
<wrappedOperatingIntervals xsi:nil="true" />
<capacities xsi:nil="true" />
<costs xsi:nil="true" />
<driverSettings xsi:nil="true" />
<wrappedAreaNumbers xsi:nil="true" />
<endLocation xsi:nil="true" />
<maxLoadingArea xsi:nil="true" />
<minLoadingArea xsi:nil="true" />
<restrictions xsi:nil="true" />
<startLocation xsi:nil="true" />
<wrappedTransportEquipments>
<Int xmlns="http://wrappertypes.service.jabba.ptvag.com">1</Int>
<Int xmlns="http://wrappertypes.service.jabba.ptvag.com">512</Int>
<Int xmlns="http://wrappertypes.service.jabba.ptvag.com">513</Int>
</wrappedTransportEquipments>
</Vehicle>
</wrappedVehicles>
</Fleet_3>
<PlanningParams_4 xmlns:q1="http://xtour.xserver.ptvag.com" xsi:type="q1:StandardParams" coDriverTransportPointsInSeparateTours="false" directDistanceFactor="1.5" directVelocity="60" useDirectDistanceFallback="false">
<q1:wrappedDistanceMatrixCalculation xsi:nil="true" />
<q1:wrappedLoadingFunctions xsi:nil="true" />
<q1:wrappedProductIncompatibilities xsi:nil="true" />
<q1:wrappedRegulations xsi:nil="true" />
<q1:restrictions xsi:nil="true" />
<q1:goalImportance xsi:nil="true" />
</PlanningParams_4>
<Plan_5 xsi:nil="true" />
<CallerContext_6 xsi:nil="true" />
</planBasicTours>
</soap:Body>
</soap:Envelope>
Re: USECASE service technicians
Posted: Thu Jun 29, 2017 1:36 pm
by Joost
If the amount of vehicles doe not exceed 255 you can use the category approach. Assign each vehicle it's own category and tell the order which categories are allowed to service them.
But i would look deeper into this use case. Why is this approach ever constructed? 9 out of 10 times when I see such an approach is there it is to make manual planning doable. But with an algoritme this is not needed. Or maybey the customer doe not want their engineers to spend to much time on the road. In that case restriction like maxDistance or maxDistanceBetweenTransportPoints could be more useful.
Re: USECASE service technicians
Posted: Thu Jun 29, 2017 2:09 pm
by columbs
Hello Bernd,
I would tend to similar solution as proposed by Joost. Instead of assigning a single post code (PLZ) I would define post code areas for each vehicle.
Are the vehicle areas overlapping?
If not: you can assigne for each order exacly one area number,
if yes: you can use the category approach as proposed by joost. Or maybe vehicleExclusions property in a tricky way, but i'm not sure about that. In that case you could have up to 512 different areas and vehicle.
Example: you have 500 vehicles and for each vehicle you can create an equipment. Order 1 is in the area of vehicle 1 --> you can exclude vehicle 2, 3, ... 500.
If Order 2 is in a overlapping area where vehicles 2 and 3 are allowed: you can exclude vehicle 1, 4, 5, ... 500.
I hope it helps.
Best,
Sebastiano
Re: USECASE service technicians
Posted: Tue Jul 04, 2017 9:49 am
by Bernd Welter
Hi there,
thanks for your feedback but I don't think the categories can help here as a RESOURCE would belong to exactly one category but in our usecase the RESOURCE is allowed to serve one or more areas.
Better to visualize it this way?
Regards
Bernd
Re: USECASE service technicians
Posted: Wed Jul 19, 2017 1:28 pm
by Bernd Welter
Getting back to this topic Clement and I are evaluating whether each service technician could be handeled as his own depot...
Technician 1 : Located at Depot 1, responsible for {76131, 76133, 76135,76138}
Technician 2 : Located at Depot 2, responsible for {76131, 76133}
Technician 3 : Located at Depot 3, responsible for {76131, 76135}
...
Then we determine for each order "who are the service technicians that are allowed to serve him" (SQL query).
e.g.
Customer 666 is located in the postcode area 76131 and therefore can be handeled by Technician 1,2,3: depotIds={1,2,3}
Customer 777 is located in the postcode area 76133 and therefore can be handeled by Technician 1,2: depotIds={1,2}
How about this? From my perspective this models the usecase and there is no limit in the API dealing with "maximum number of depots".
Any doubts? Counter-arguments?
Regards Bernd
Re: USECASE service technicians
Posted: Fri Jul 21, 2017 8:30 am
by Bernd Welter
We approached this via the depots now:
Each ServiceTechnician is modelled as his own depot and then we specify a list of potential depots that could serve customer xy.
- Codesamplescreen
Looks promising - have to check this with bigger values...
- Each order is served by one or more depots (=service technicians).
- Looks good...!