#
Inledning #
Välkommen till användarhandboken för vårt API för ruttplanering och schemaläggning!
v1.1: Stöd för ruttmallar har lagts till
v1.2 lade till stöd för flexibel konfiguration av fordonskapacitet
Vårt API är utformat för att förbättra ruttplanering och schemaläggning för fordonsflottor, och tar hänsyn till viktiga begränsningar såsom tidsfönster för tjänster, kapacitetsbegränsningar och trafikförhållanden. Genom att använda vårt API kan företag avsevärt förbättra leveranseffektiviteten, minska driftskostnaderna och spara värdefull tid tack vare optimerade lösningar för ruttplanering och schemaläggning.
I grund och botten löser API:et problemet med fordonsruttplanering (VRP) för upphämtning och leverans. Detta problem handlar om att beräkna de mest effektiva rutterna för en fordonsflotta som ska besöka flera platser för att utföra upphämtnings- och leveransuppdrag, samtidigt som begränsningar som tidsfönster, fordonskapacitet och tillgänglighet måste beaktas.
Dessutom stöder vårt API dynamiska schemaläggningsjusteringar eller omoptimering. Om du behöver ändra ett befintligt schema – till exempel på grund av nya beställningar, avbokningar eller andra förändringar – kan du skapa en uppdaterad bild av ditt schema genom att ange uppdragens status och fordonens positioner. API:et omoptimerar då schemat för att återspegla dessa förändringar, vilket säkerställer en kontinuerlig effektivitet i din verksamhet.
För information om hur du snabbt kommer igång och börjar använda API:et, se Kom igång. I avsnittet ”Handledningar” finns också flera korta handledningar.
Kom igång #
API:et erbjuder två viktiga metoder för att hantera optimering av ruttplanering och schemaläggning:
Optimering POST – Använd denna metod för att skicka in ett optimeringsproblem avseende ruttplanering och schemaläggning. Efter att du har skickat in en POST-begäran får du ett unikt referens-ID.
Optimering GET – Använd denna metod för att hämta status för ett inskickat problem med hjälp av det unika referens-ID som du fick från POST-begäran. Om optimeringslösningen är klar kan du hämta lösningen på optimeringsproblemet.
Optimering av POST-metoden #
INLÄGG: https://iq.ui.scheduledroutes.ddswireless.net
Använd den här metoden för att skicka in ditt optimeringsproblem för rutt- och schemaläggning till API:et. När en POST-begäran om optimering har skickats in returnerar API:et ett unikt referens-ID i bekräftelsemeddelandet. Använd detta unika ID för att hämta den faktiska lösningen med hjälp av GET-metoden för optimering ( se nästa avsnitt).
Ett exempel på hur man skickar in ett optimeringsproblem med POST-metoden, med hjälp av ett exempel på token och nyttolast:
curl -X POST "https://iq.scheduledroutes.ddswireless.net/raas/optimization"
-H "Content-Type: application/json"
-H "Authorization: Bearer fgJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VySWQiOiJhZWU2MDQyZC0zN2E3LTQxNDYtODRlYy04YWU3M2ViODQ4YTgiLCJmaXJzdE5hbWUiOiJUZWMiLCJsYXN0TmFtZSI6IlRyYW5zaXQiLCJzZXF1ZW5jZU51bWJlciI6MSwicm9sZU5hbWVzIjpbImFkbWluIl0sInByb3ZpZGVyTmFtZXMiOlsiQUxMIl0sInVzZXJUZW5hbnRzIjpbMl0sInBlcm1pc3Npb25zIjpbMCwxNjYsMTcwLDE4MSwxODYsMTkxLDIwMCwxLDIsMyw0LDUsNiw3LDgsOSwxMCwxMSwxMiwxMywxNCwxNSwxNiwxNywxOCwxOSwyMCwyMSwyMiwyMywyNCwyNSwyNiwyNywyOCwxNTgsMTU5LDE2MywxNjgsMTgyLDE4OSwxNTcsMTE4LDExOSwxMjAsMTIxLDEyMiwxMjMsMTc1LDE3NiwxOTcsMTk1LDIwNSwyMDIsMjAzLDIwNiwyMTcsMjE5LDE5NiwyMDcsMTk0LDIxNCwyMTgsMjIwLDI5LDMwLDMxLDMyLDMzLDM0LDM1LDM2LDM3LDM4LDM5LDQwLDQxLDQyLDQzLDQ0LDQ1LDQ2LDQ3LDQ4LDQ5LDUwLDUxLDUyLDUzLDU0LDU1LDU2LDU3LDU4LDU5LDYwLDYxLDYzLDY0LDY1LDY2LDY3LDY4LDY5LDcwLDcxLDcyLDczLDc0LDc1LDc2LDc3LDgyLDgzLDg2LDg3LDg4LDg5LDkxLDkyLDkzLDk0LDk1LDk2LDEwMCwxMDEsMTAyLDEwMywxMDQsMTA1LDEwNiwxMDcsMTA4LDEwOSwxMTAsMTExLDExMiwxMTMsMTE0LDExNSwxMTYsMTE3LDEyNCwxMjUsMTI2LDEyNywxMjgsMTI5LDEzMCwxMzEsMTMyLDEzMywxMzQsMTM1LDEzNiwxMzcsMTM4LDEzOSwxNDAsMTQxLDE0MiwxNDMsMTQ0LDE0NSwxNDYsMTQ3LDE0OCwxNDksMTUwLDE1MSwxNTIsMTUzLDE1NCwxNTUsMTU2LDE2MiwxNjUsMTcxLDE4NCwxODcsMTkyLDE5OSwxNzMsMTk4LDE2MCwxNjEsMTY5LDE4MywxODgsODQsOTcsOTgsOTksMTY3LDE3MiwxODAsMTg1LDE5MCwxOTMsMTc0LDE2NCwyMDQsMjE1XSwicGFzc3dvcmRVcGRhdGVkQXQiOiIiLCJ0ZW5hbnQiOnsiaWQiOjIsIm5hbWUiOiJ0ZWNUcmFuc2l0Iiwic2l0ZUlkIjoiOTQiLCJ0aW1lem9uZSI6IkFtZXJpY2EvTG9zX0FuZ2VsZXMiLCJ0eXBlIjoiUmFhUyIsInNlc1VybCI6Imh0dHA6Ly9zdHJhdGVneS1lbmdpbmUtbXVsdGktdGVuYW50LTM6MTYwMDAiLCJkaXNwbGF5TmFtZSI6IlRlYyBUcmFuc2l0In0sInJvbGVzIjpbMjBdLCJpYXQiOjE3NDE5MDU2ODIsImV4cCI6MTc0NDQ5NzY4MiwiaXNzIjoiaXEuc2NoZWR1bGVkcm91dGVzLmRkc3dpcmVsZXNzLm5ldCJ9.fmdXyIylp604DCewvtuKCqLGhh-GFPfJNC9p2v4D-kHxhN2ZmRkHfknpTjiWZOZnB7AnWTUAh6BfZztNR_KLpQDPXcEpNL01lrw7ypIuwIf6CwA3Kwh916mNX-kgvPsyRQvAnvkyd-YO8M6zd_lsVD8oRnb-g07Vta3s3U-Y5uyWnQzv9PEeRf2IizflzlMkM7f1q472_3FQAEmomqMrSreK-YwUP9YxzD-QOW4GaaIUK5pgnzFYgEH2DFNU8KtDPeRdEk1cXL8aACFeawZnYzndvNcuv5fxd-9r-Y4-Tr8NiUwerdhRX3CuD5L5E6JVQdYOUJMFtSVpCbV7smaOJa"
-d @payload.json
I exemplet ovan antog vi att ingångsproblemet finns i en fil som heter payload.json. Du måste byta ut provtokenet <strong>fgJhbGciOiJSUzI1N</strong>..... med din egen token. Schemat för inmatningsuppgiften definieras i avsnittet ”Problem”.
När du har skickat in POST-metoden får du ett svarsmeddelande med följande format:
Svarformat för POST-metoden:
{
"id": "string",
"message": "string",
"status": "string",
"error" : "string"
}
Om inlämningen går igenom, kommer status kommer att vara ”202”, med message med texten ”godkänd” och id som representerar det unika referensnumret för den asynkrona operationen. Detta ID används för att spåra operationens status och hämta resultaten senare. Om ett fel uppstår, status visar en felkod, den id kommer att vara noll eller tom, den message kommer att vara ”misslyckande” och error beskriver felet. Mer information finns i POST-statuskoderna nedan.
Exempel på POST (Windows PowerShell):
Skriptet nedan visar hur man skapar en POST-förfrågan med hjälp av ett exempel på en datamängd i Windows PowerShell. Det förutsätter att datamängden finns lagrad i en fil med namnet payload.json, och API-åtkomsttoken sparas i token.txt. Vid körning skrivs det genererade ID:t till id.txt. För att starta PowerShell skriver du bara in ”PowerShell” i Start-menyn eller i kommandoraden.
$token = Get-Content token.txt -Raw
$headers = @{
Authorization = "Bearer $token"
"Content-Type" = "application/json"
}
$body = Get-Content payload.json -Raw
$response = Invoke-RestMethod -Uri "https://iq.scheduledroutes.ddswireless.net/raas/optimization" -Method Post -Headers $headers -Body $body
$response.id | Out-File -Encoding utf8 id.txt
Write-Output $response
POST-statuskoder #
| Svarskod | Beskrivning | Ytterligare anmärkningar |
|---|---|---|
| 202 | Begäran har godkänts för behandling. | Ett referens-ID returneras som du kan använda i en GET-förfrågan för att hämta lösningen när den är klar. |
| 400 | Valideringen av inmatade uppgifter misslyckades (ogiltig begäran). | Parameter saknas eller är ogiltig, eller så är värdetypen felaktig. Kontrollera indata och försök igen. |
| 403 | Obehörig begäran. | Detta inträffar när autentiseringen misslyckas. |
| 404 | Den begärda sökvägen hittades inte. | Detta inträffar när en felaktig sökväg används. |
| 429 | För många förfrågningar. | Begränsningen har överskridits (antal förfrågningar per minut eller kvoten har nåtts). |
| 500 | Internt tjänstefel. | Det är ett problem hos oss. Kontakta support@ddswireless.com. |
Optimering av GET-metoden #
GET: https://iq.ui.scheduledroutes.ddswireless.net/{id}
Använd den här metoden för att hämta den optimerade lösningen för de optimeringsuppgifter som skapats med hjälp av POST-metoden för optimering. För detta ändamål måste du ange det referens-ID som du fick från POST-metoden.
Ett exempel på hur man hämtar ett svar från API:et med GET-metoden och ett ID:
curl -X GET "https://iq.scheduledroutes.ddswireless.net/raas/optimization/ID"
-H "Content-Type: application/json"
-H "Authorization: Bearer fgkhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VySWQiOiJhZWU2MDQyZC0zN2E3LTQxNDYtODRlYy04YWU3M2ViODQ4YTgiLCJmaXJzdE5hbWUiOiJUZWMiLCJsYXN0TmFtZSI6IlRyYW5zaXQiLCJzZXF1ZW5jZU51bWJlciI6MSwicm9sZU5hbWVzIjpbImFkbWluIl0sInByb3ZpZGVyTmFtZXMiOlsiQUxMIl0sInVzZXJUZW5hbnRzIjpbMl0sInBlcm1pc3Npb25zIjpbMCwxNjYsMTcwLDE4MSwxODYsMTkxLDIwMCwxLDIsMyw0LDUsNiw3LDgsOSwxMCwxMSwxMiwxMywxNCwxNSwxNiwxNywxOCwxOSwyMCwyMSwyMiwyMywyNCwyNSwyNiwyNywyOCwxNTgsMTU5LDE2MywxNjgsMTgyLDE4OSwxNTcsMTE4LDExOSwxMjAsMTIxLDEyMiwxMjMsMTc1LDE3NiwxOTcsMTk1LDIwNSwyMDIsMjAzLDIwNiwyMTcsMjE5LDE5NiwyMDcsMTk0LDIxNCwyMTgsMjIwLDI5LDMwLDMxLDMyLDMzLDM0LDM1LDM2LDM3LDM4LDM5LDQwLDQxLDQyLDQzLDQ0LDQ1LDQ2LDQ3LDQ4LDQ5LDUwLDUxLDUyLDUzLDU0LDU1LDU2LDU3LDU4LDU5LDYwLDYxLDYzLDY0LDY1LDY2LDY3LDY4LDY5LDcwLDcxLDcyLDczLDc0LDc1LDc2LDc3LDgyLDgzLDg2LDg3LDg4LDg5LDkxLDkyLDkzLDk0LDk1LDk2LDEwMCwxMDEsMTAyLDEwMywxMDQsMTA1LDEwNiwxMDcsMTA4LDEwOSwxMTAsMTExLDExMiwxMTMsMTE0LDExNSwxMTYsMTE3LDEyNCwxMjUsMTI2LDEyNywxMjgsMTI5LDEzMCwxMzEsMTMyLDEzMywxMzQsMTM1LDEzNiwxMzcsMTM4LDEzOSwxNDAsMTQxLDE0MiwxNDMsMTQ0LDE0NSwxNDYsMTQ3LDE0OCwxNDksMTUwLDE1MSwxNTIsMTUzLDE1NCwxNTUsMTU2LDE2MiwxNjUsMTcxLDE4NCwxODcsMTkyLDE5OSwxNzMsMTk4LDE2MCwxNjEsMTY5LDE4MywxODgsODQsOTcsOTgsOTksMTY3LDE3MiwxODAsMTg1LDE5MCwxOTMsMTc0LDE2NCwyMDQsMjE1XSwicGFzc3dvcmRVcGRhdGVkQXQiOiIiLCJ0ZW5hbnQiOnsiaWQiOjIsIm5hbWUiOiJ0ZWNUcmFuc2l0Iiwic2l0ZUlkIjoiOTQiLCJ0aW1lem9uZSI6IkFtZXJpY2EvTG9zX0FuZ2VsZXMiLCJ0eXBlIjoiUmFhUyIsInNlc1VybCI6Imh0dHA6Ly9zdHJhdGVneS1lbmdpbmUtbXVsdGktdGVuYW50LTM6MTYwMDAiLCJkaXNwbGF5TmFtZSI6IlRlYyBUcmFuc2l0In0sInJvbGVzIjpbMjBdLCJpYXQiOjE3NDE5MDU2ODIsImV4cCI6MTc0NDQ5NzY4MiwiaXNzIjoiaXEuc2NoZWR1bGVkcm91dGVzLmRkc3dpcmVsZXNzLm5ldCJ9.fmdXyIylp604DCewvtuKCqLGhh-GFPfJNC9p2v4D-kHxhN2ZmRkHfknpTjiWZOZnB7AnWTUAh6BfZztNR_KLpQDPXcEpNL01lrw7ypIuwIf6CwA3Kwh916mNX-kgvPsyRQvAnvkyd-YO8M6zd_lsVD8oRnb-g07Vta3s3U-Y5uyWnQzv9PEeRf2IizflzlMkM7f1q472_3FQAEmomqMrSreK-YwUP9YxzD-QOW4GaaIUK5pgnzFYgEH2DFNU8KtDPeRdEk1cXL8aACFeawZnYzndvNcuv5fxd-9r-Y4-Tr8NiUwerdhRX3CuD5L5E6JVQdYOUJMFtSVpCbV7smaOJs"
I exemplet ovan ersätter du ID i URL:en med den URL du fick från POST-metoden. Till exempel, om ID är lika med 5, använd detta:
curl -X GET "https://iq.scheduledroutes.ddswireless.net/raas/optimization/5"
-H "Content-Type: application/json"
-H "Authorization: Bearer fgkhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VySWQiOiJhZWU2MDQyZC0zN2E3LTQxNDYtODRlYy04YWU3M2ViODQ4YTgiLCJmaXJzdE5hbWUiOiJUZWMiLCJsYXN0TmFtZSI6IlRyYW5zaXQiLCJzZXF1ZW5jZU51bWJlciI6MSwicm9sZU5hbWVzIjpbImFkbWluIl0sInByb3ZpZGVyTmFtZXMiOlsiQUxMIl0sInVzZXJUZW5hbnRzIjpbMl0sInBlcm1pc3Npb25zIjpbMCwxNjYsMTcwLDE4MSwxODYsMTkxLDIwMCwxLDIsMyw0LDUsNiw3LDgsOSwxMCwxMSwxMiwxMywxNCwxNSwxNiwxNywxOCwxOSwyMCwyMSwyMiwyMywyNCwyNSwyNiwyNywyOCwxNTgsMTU5LDE2MywxNjgsMTgyLDE4OSwxNTcsMTE4LDExOSwxMjAsMTIxLDEyMiwxMjMsMTc1LDE3NiwxOTcsMTk1LDIwNSwyMDIsMjAzLDIwNiwyMTcsMjE5LDE5NiwyMDcsMTk0LDIxNCwyMTgsMjIwLDI5LDMwLDMxLDMyLDMzLDM0LDM1LDM2LDM3LDM4LDM5LDQwLDQxLDQyLDQzLDQ0LDQ1LDQ2LDQ3LDQ4LDQ5LDUwLDUxLDUyLDUzLDU0LDU1LDU2LDU3LDU4LDU5LDYwLDYxLDYzLDY0LDY1LDY2LDY3LDY4LDY5LDcwLDcxLDcyLDczLDc0LDc1LDc2LDc3LDgyLDgzLDg2LDg3LDg4LDg5LDkxLDkyLDkzLDk0LDk1LDk2LDEwMCwxMDEsMTAyLDEwMywxMDQsMTA1LDEwNiwxMDcsMTA4LDEwOSwxMTAsMTExLDExMiwxMTMsMTE0LDExNSwxMTYsMTE3LDEyNCwxMjUsMTI2LDEyNywxMjgsMTI5LDEzMCwxMzEsMTMyLDEzMywxMzQsMTM1LDEzNiwxMzcsMTM4LDEzOSwxNDAsMTQxLDE0MiwxNDMsMTQ0LDE0NSwxNDYsMTQ3LDE0OCwxNDksMTUwLDE1MSwxNTIsMTUzLDE1NCwxNTUsMTU2LDE2MiwxNjUsMTcxLDE4NCwxODcsMTkyLDE5OSwxNzMsMTk4LDE2MCwxNjEsMTY5LDE4MywxODgsODQsOTcsOTgsOTksMTY3LDE3MiwxODAsMTg1LDE5MCwxOTMsMTc0LDE2NCwyMDQsMjE1XSwicGFzc3dvcmRVcGRhdGVkQXQiOiIiLCJ0ZW5hbnQiOnsiaWQiOjIsIm5hbWUiOiJ0ZWNUcmFuc2l0Iiwic2l0ZUlkIjoiOTQiLCJ0aW1lem9uZSI6IkFtZXJpY2EvTG9zX0FuZ2VsZXMiLCJ0eXBlIjoiUmFhUyIsInNlc1VybCI6Imh0dHA6Ly9zdHJhdGVneS1lbmdpbmUtbXVsdGktdGVuYW50LTM6MTYwMDAiLCJkaXNwbGF5TmFtZSI6IlRlYyBUcmFuc2l0In0sInJvbGVzIjpbMjBdLCJpYXQiOjE3NDE5MDU2ODIsImV4cCI6MTc0NDQ5NzY4MiwiaXNzIjoiaXEuc2NoZWR1bGVkcm91dGVzLmRkc3dpcmVsZXNzLm5ldCJ9.fmdXyIylp604DCewvtuKCqLGhh-GFPfJNC9p2v4D-kHxhN2ZmRkHfknpTjiWZOZnB7AnWTUAh6BfZztNR_KLpQDPXcEpNL01lrw7ypIuwIf6CwA3Kwh916mNX-kgvPsyRQvAnvkyd-YO8M6zd_lsVD8oRnb-g07Vta3s3U-Y5uyWnQzv9PEeRf2IizflzlMkM7f1q472_3FQAEmomqMrSreK-YwUP9YxzD-QOW4GaaIUK5pgnzFYgEH2DFNU8KtDPeRdEk1cXL8aACFeawZnYzndvNcuv5fxd-9r-Y4-Tr8NiUwerdhRX3CuD5L5E6JVQdYOUJMFtSVpCbV7smaOJs"
Kom också ihåg att använda din egen API-åtkomsttoken.
Svarformat för GET-metoden:
{
status: "string",
message: "string",
error: "string",
"solution": {
"statistics": {},
"routes": []
"unassigned": [],
}
}
Om lösningen är klar, statistics, routes, och unassignedkommer att fyllas i utifrån den erhållna lösningen. I övrigt gäller samma sak som för POST-metoden, status, message, och errorvisar status eller fel. Schemat för utdataslösningen definieras i avsnittet ”Lösning”.
GET-exempel (Windows PowerShell):
Skriptet nedan visar hur man skapar en GET-förfrågan med hjälp av ett ID som genererats med POST-metoden i Windows PowerShell. Det förutsätter att ID:t är lagrat i en fil med namnet id.txt, och API-åtkomsttoken sparas i token.txt. Vid körning skrivs det genererade svaret till response.txt. För att starta PowerShell skriver du bara in ”PowerShell” i Start-menyn eller i kommandoraden.
$token = Get-Content token.txt -Raw
$id = Get-Content id.txt -Raw
$headers = @{
Authorization = "Bearer $token"
"Content-Type" = "application/json"
}
$url = "https://iq.scheduledroutes.ddswireless.net/raas/optimization/$id"
$response = Invoke-RestMethod -Uri $url -Method Get -Headers $headers
$response | ConvertTo-Json -Depth 10 | Out-File -Encoding utf8 response.txt
Hämta statuskoder #
| Svarskod | Beskrivning | Ytterligare anmärkningar |
|---|---|---|
| 200 | Begäran har genomförts. | Svaret returneras via statistics, routes, och unassigned. |
| 202 | Begäran har godkänts men är ännu inte slutförd. | Statusen är "Väntar". Kom tillbaka senare för att se om en lösning finns tillgänglig. |
| 400 | Det gick inte att behandla begäran (ogiltig begäran). | Det gick inte att generera en genomförbar lösning på grund av ogiltiga indata eller parametrar. |
| 401 | Obehörig begäran. | Användarautentisering krävs. Inga giltiga inloggningsuppgifter har mottagits. |
| 500 | Internt tjänstefel. | Det uppstod ett problem hos oss. Kontakta oss support@ddswireless.com. Fält som statistics, routes, och unassigned kommer att vara tom. |
Begrepp #
Gör så här för att lösa ett optimeringsproblem gällande ruttplanering och schemaläggning för en fordonsflotta:
-
Definiera problemet: Börja med att beskriva ditt problem enligt det format som anges i avsnittet ”Problem”.
-
Skicka in problemet: Använd POST-metoden, enligt beskrivningen i avsnittet ”Kom igång”, för att skicka ditt problem till API:et.
-
Hämta lösningen: Hämta lösningen på ditt optimeringsproblem genom att använda GET-metoden som beskrivs i avsnittet ”Kom igång”. Lösningens format beskrivs i avsnittet ”Lösning”.
För mer information om olika termer som används i API:et, se avsnittet ”Ordlista”. För en lista över vanliga frågor, se avsnittet ”Vanliga frågor”.
Problem nr
Den Problem Enheten utgör ett problem inom ruttplanering och schemaläggning. Som framgår av följande figur består den av fyra huvudkomponenter: fleet, jobs, objective, och configuration. Av dessa fyra komponenter, fleet och jobs, är obligatoriska medan objective och configuration är valfria.

För att ange en plats eller adress i API:et ska du använda WGS84-geokoordinater med minst fem decimaler för att säkerställa noggrannheten.
Om du till exempel har en adress som ”1600 Amphitheatre Parkway, Mountain View, Kalifornien”, skulle dess motsvarande geografiska koordinat vara latitud
37.423021 och longitud -122.083739. Därför anger du det antingen som:
"location": {"lat": 37.423021, "lng": -122.083739} eller [37.423021, -122.083739].
Obs!
API:et använder ISO 8601-formatet för tidsstämplar, inklusive tidszonsinformation, för att ange lokal tid för det område där du behöver optimerad ruttplanering och schemaläggning.
Exempel:
2024-07-31T14:45:30-08:00 avser den 31 juli 2024 kl. 14:45:30 PST, vilket är 8 timmar efter koordinated universal tid (UTC).
Dessutom måste du konsekvent använda samma lokala tidszon i API-innehållet. Om flera tidszoner upptäcks kommer API:et att returnera ett fel. Tiderna för schemalagda stopp i svaret kommer att anges i samma format som det som specificerats i API-innehållet.
Exempel:
Om du anger 2024-07-31T14:45:30-08:00 i din indata kommer de optimerade restiderna i utdata också att finnas i 2024-07-31T14:45:30-08:00 format.
Om du använder 2024-07-31T14:45:30+05:30 om indata är, blir utdata 2024-07-31T14:45:30+05:30.
Obs!
Alla valfria attribut kan utelämnas i datan. Tomma arrayer (t.ex. []) kan även användas för valfria attribut som accepterar en array.
Obs!
Se till att inga konfidentiella eller personuppgifter ingår i de data som skickas till API:et. Undvik till exempel att använda verkliga identifierare, såsom registreringsnummer, som fordon-ID eller jobb-/uppgifts-ID.
Vi kommer nu att ge en detaljerad beskrivning av var och en av dessa komponenter:
fleet: [obligatoriskt] Den innehåller en förteckning över fordon tillsammans med tillhörande information, såsom arbetsscheman, start- och slutplatser, raster, kapacitet och kompetens.
För varje fordon kan du definiera ett eller flera arbetsscheman genom att ange start- och sluttider samt motsvarande platser. För att identifiera dessa platser måste du ange deras geografiska koordinater, som består av latitud och longitud.
Varje fordon kan ha en eller flera raster. För varje rast kan du definiera ett tidsfönster under vilket den kan tas, samt rastens plats och varaktighet.
För varje fordon kan du definiera en eller flera kapacitetstyper tillsammans med de tillgängliga enheterna för varje typ. Fordonskapacitet kan representeras med hjälp av flerdimensionella måttenheter, såsom volym, massa eller storlek.
För varje fordon kan du ange en eller flera färdigheter som gör det möjligt att utföra vissa uppdrag. Du kan till exempel tilldela ”svetsmaskin” och ”syretank” som färdigheter för ett fordon, och ”lyft” som en färdighet för ett annat fordon. Om ett jobb kräver en lyft kommer endast det fordon som är utrustat med denna färdighet att kunna utföra det. Du kan också ställa in gränser för varje fordon, såsom maximalt antal stopp och maximal körsträcka (i mil).
jobs: [obligatoriskt] anger en lista över uppdrag som ska utföras av de fordon som anges i fleet Objekt. Varje uppdrag kan bestå av en rad deluppgifter, som kan vara enbart upphämtningar, enbart leveranser eller både upphämtningar och leveranser. För ”besöksjobb” där vi behöver besöka en plats för att utföra ett jobb (t.ex. reparationer, installation av modem etc.) kan du betrakta dem som en leveransuppgift med eller utan kapacitetskrav. För varje uppgift kan du definiera olika attribut såsom plats, tidsfönster, varaktighet, kapacitetskrav och nödvändiga färdigheter.
För att ange platsen för en uppgift måste du ange dess geografiska koordinater, som omfattar latitud och longitud.
Om du anger ett tidsfönster för en uppgift kommer optimeringsverktyget att schemalägga uppgiften så att den utförs inom det tidsfönstret. Med andra ord kommer den beräknade ankomsttiden (ETA) för uppgiften i API-svaret att ligga inom det angivna tidsfönstret. Om optimeringsverktyget inte kan hitta en lämplig ETA för en uppgift inom det angivna tidsfönstret kommer uppgiften att förbli otilldelad. För uppgifter som är flexibla eller inte tidsberoende kan du ange ett bredare tidsfönster, med en maximal spännvidd på 24 timmar. API:et använder ISO-tidsstämplar enligt beskrivningen ovan.
Du kan ange en varaktighet (i sekunder) för varje uppgift. Detta är den tid som tillbringas på en given plats antingen för att lasta eller lossa ett föremål eller för att utföra uppgiften.
Du kan ange kapacitetskraven för varje uppgift med hjälp av flerdimensionella måttenheter, såsom volym, massa eller storlek. Dessutom kan du skapa anpassade namn för dina kapacitetstyper, såsom ”säte”, ”container”, ”pall” eller ”låda”. För varje kapacitetstyp kan du också definiera den exakta mängd som behövs för att utföra uppgiften.
Du kan också definiera en lista över nödvändiga färdigheter för varje uppgift. Endast fordon med en matchande uppsättning färdigheter kommer att vara berättigade att utföra den uppgiften. Om du till exempel anger ”svetsmaskin” och ”syretank” som nödvändiga färdigheter för en uppgift, kommer endast fordon utrustade med dessa färdigheter att väljas ut för att slutföra uppgiften.
objective: [valfritt] här anges optimeringsmålet eller strategin. För närvarande stöder API:et följande tre mål:
Minimera total körtid: Detta är standardoptimeringsstrategin, som syftar till att minimera flottans totala körtid samtidigt som de angivna uppdragen utförs.
Minimera antalet rutter: Denna optimeringsstrategi fokuserar på att minska antalet fordon som behövs för att slutföra de angivna uppdragen. Detta kan dock leda till ökad total restid för flottan eller större arbetsbelastning på enskilda fordon som en avvägning.
Balansera arbetsbelastningen mellan rutterna: Denna optimeringsstrategi syftar till att fördela arbetsbelastningen jämnt mellan alla fordon i flottan. Denna balans kan dock resultera i ökad total restid för flottan.
configuration: [valfritt] Genom konfigurationen kan du justera API-inställningarna eller ändra standardalternativen. Du kan till exempel ange om API-svaret ska innehålla en sammanfattning av optimeringsstatistik (t.ex. total restid och sträcka) eller en lista över icke tilldelade uppgifter.
Schema för inmatningsförfrågan: #
Uppbyggnaden av den inmatade förfrågan för att lösa ett ruttoptimeringsproblem ser ut enligt följande:
"problem": {
"fleet": required
[
"shifts": [optional]
"capacities": [required]
"limits": {optional}
"skills" : [optional]
"id": required
"routeTemplateId" : optional
"maxInstances": optional
],
"jobs": required
[
"pickups": [...]
"deliveries": [...]
"id" : required
]
"objective": optional
"configuration": {optional}
"version": optional
}
För att skicka in ett problem via API:et måste denna begäran inkluderas i POST-metoden enligt beskrivningen i avsnittet ”Kom igång”.
I ett ruttoptimeringsproblem är målet att en fordonsflotta ska utföra en uppsättning uppdrag på ett effektivt sätt. Med hjälp av schemat ovan kan användarna definiera sin fordonsflotta och sina uppdrag. I den aktuella versionen av API:et kan varje uppdrag vara:
-
Endast upphämtningsuppdrag: Dessa uppdrag innebär att man hämtar varor längs rutten och levererar dem till rutten slutdestination.
-
Endast leveransuppdrag: Dessa uppdrag innebär att man ska leverera varor som lastas på fordonet i början av rutten.
-
Upphämtnings- och leveransuppdrag (P/D): Dessa uppdrag omfattar både upphämtning och leverans. De innebär att man hämtar något på en plats och levererar det till en annan plats.
Minst ett uppdrag och ett fordon måste anges för uppgiften.
Uppdrag av typen ”besök” som kräver att man åker till en plats (t.ex. reparationer, modeminstallationer osv.) ska betraktas som leveransuppdrag – med eller utan kapacitetskrav.
Dessutom:
-
Om endast objektet ”upphämtningar” anges för ett uppdrag betraktas det som ett uppdrag som endast omfattar upphämtning.
-
Om endast objektet ”leveranser” anges för ett jobb betraktas det som ett rent leveransjobb.
-
När både ”upphämtning” och ”leverans” ingår i ett uppdrag klassificeras det som ett upphämtnings- och leveransuppdrag.
API:et gör inte hantera uppdrag med flera upphämtningar och flera leveranser.
Med andra ord, om du vill definiera ett ”hämtnings- och leveransuppdrag”:
- Den
"pickups"matrisen får endast innehålla en hämtningsuppdrag. - Den
"deliveries"matrisen får endast innehålla en leveransuppdrag.
API:et stöder inte heller uppdrag utan upphämtningar och utan leveranser.
Klassificeringsregler:
- Om bara
"pickups"är definierad klassificeras jobbet som en förankrad i pickupen jobb. - Om bara
"deliveries"är definierad klassificeras jobbet som en leveransbaserad jobb. - Om både upphämtning och leverans har angetts är det den som har ett tidsfönster som gäller.
- Om både upphämtning och leverans har tidsfönster betraktas uppdraget som upphämtningsbaserat.
För varje uppdrag kan olika attribut och begränsningar definieras, till exempel kapacitetskrav, tidsfönster för utförandet och nödvändiga kompetenser. Besöksuppgifter, där vi behöver besöka specifika platser för att utföra uppgifter (t.ex. reparationer), kan faktiskt ses som en specialiserad form av leveransuppgifter (med eller utan kapacitetskrav). Uppgifter tilldelas fordon vars kapacitet eller kompetens stämmer överens med uppgiftens krav. Om en uppgift till exempel kräver en lyft eller stege, kommer endast fordon utrustade med en lyft eller stege att användas för att utföra den uppgiften.
Nu ska vi titta närmare på detaljerna för varje element i datapaketet i inmatnings-API:et.
problem [obligatoriskt]: anger det optimeringsproblem för routning och schemaläggning som du vill lösa. Det består av följande attribut:
flotta [obligatoriskt]: definierar flottinformation. Det är en matris av flottor. Varje flottor består av följande attribut:
id: [obligatoriskt] en unik identifierare (heltal) för fordonet.
shifts: [valfritt] en matris med skift-objekt, där varje skift-objekt innehåller uppgifter om start- och slutplats samt start- och sluttid för skiftet, liksom en matris med paus-objekt som var och en innehåller start- och slutplats samt start- och sluttid för pausen. Flera skift-objekt kan definieras, men de får inte överlappa varandra. Element i varje skift-objekt:
start: tidpunkt och plats för skiftets början
time: [valfritt]. Anger starttiden för skiftet. Om ingen tid anges används standardvärdet 00:00:00 (midnatt) samma dag.
location: [valfritt]. Här anges startplatsens geografiska koordinater (latitud och longitud). Du kan ange dem som en matris, till exempel [A,B] där A står för latituden och B står för longituden. Alternativt kan du ange den som {"lat": A,"lng": B}.
end: skiftets sluttid och slutplats
time: [valfritt]. Anger tidpunkten då skiftet slutar. Om ingen tid anges används standardvärdet 23:59:00 samma dag.
location: [valfritt]. Här anges geografiska koordinater (latitud och longitud) för slutplatsen. Du kan ange dem som en matris, till exempel [A,B] där A står för latituden och B står för longituden. Alternativt kan du ange den som {"lat": A,"lng": B}.
breaks: [valfritt] en matris med break-objekt
serviceWindow: [krävs om "breaks" används]: den tidsperiod under vilken pausen kan inträffa
duration: [krävs om breaks används]: ett heltal som anger pausens längd i sekunder
location: [valfritt]: avbrottets position. Du kan ange den som en matris, till exempel [A,B] där A står för latituden och B står för longituden. Alternativt kan du ange den som {"lat": A,"lng": B}.Platsangivelsen är valfri. Om platsen utelämnas är rasten ”flexibel”, vilket innebär att den kan tas när som helst efter förarens önskemål.
Exempel:
"shifts": [{
"start": {
"time": "2020-07-04T09:00:00-08:00",
"location": {"lat": 52.46642, "lng": 13.28124}
},
"end": {
"time": "2020-07-04T18:00:00-08:00",
"location": [54.21981, 14.01237]
},
"breaks": [
{
"serviceWindow": ["2020-07-04T12:00:05-08:00","2020-07-04T14:05:05-08:00"],
"duration": 1200,
"location": {"lat": 53.70645, "lng": 12.34156}
},
{
"serviceWindow": ["2020-07-04T16:00:00-08:00","2020-07-04T16:45:00-08:00"],
"duration": 600,
"location": {"lat": 51.46642, "lng": 12.28124}
}
]
}]
kapaciteter: [obligatoriskt] en array av kapacitetsobjekt. Varje kapacitetsobjekt är ett nyckel-värde-objekt definierat med följande nycklar:
name: [obligatoriskt] en sträng som anger namnet på kapacitetstypen (t.ex. ”rullstol”, ”förvaringslåda”, ”säte”, ”soptunna”)
units: [obligatoriskt] ett heltal som anger antalet tillgängliga enheter av kapacitetstypen
Om ett fordon till exempel har plats för 2 passagerare och 20 paket kan du ange dess kapacitet på följande sätt:
"capacities": [
{
"name": "seat",
"units": 2,
},
{
"name": "package",
"units": 20,
}
]
färdigheter: [valfritt] en lista över fordonets färdigheter eller utrustning, där varje post representeras av en godtycklig sträng som är specifik för din applikation. Detta gör det möjligt för dig att anpassa fordonets funktioner så att de motsvarar kraven för de uppdrag de ska utföra. Exempel:
"skills": ["lift","fridge","oxygen tank"]
begränsningar: [valfritt] anger vilka begränsningar som gäller för fordonet
maxDistance: [valfritt] ett heltal som anger det maximala avståndet för fordonet i mil
maxStops: [valfritt] ett heltal som anger det maximala antalet stopp (upphämtnings- eller leveransuppdrag) som fordonet kan utföra under ett skift
lifoDepth: [valfritt] ett heltal som anger fordonets LIFO-djup (Last In First Out)
"limits": {
"lifoDepth" : 1,
"maxDistance": 3000,
"maxStops" : 20,
}
lastKnownLocation: [valfritt, används endast för omoptimering] Anger fordonets senast kända position vid den angivna tidpunkten. Denna information är avgörande för att omoptimera en pågående rutt så att nya förändringar beaktas, till exempel fordon som gått sönder, försenade uppdrag, nya uppdrag eller inställda uppdrag. API:et använder dessa uppgifter för att omoptimera planen på ett effektivt sätt. Därför måste du ange positionen för alla berörda fordon när du omoptimerar ett befintligt schema.
Exempel:
"lastKnownLocation": {
"location": {"lat":53.45612, "lng":12.65421},
"time" : "2020-07-04T12:00:05-08:00"
}
routeTemplateId: [valfritt] Detta är en unik identifierare som används för att definiera en rutmall. API:et stöder begreppet ”rutmallar”, vilket gör det möjligt att definiera specifikationer för en viss fordonstyp och begära att API:et genererar ett visst antal sådana fordon för optimering av ruttplanering och schemaläggning. En ruttmall innehåller samma information som en rutt eller ett fordon, men du kan ange en ”storleksparameter” som kallas maxInstances för den. Anta till exempel att du har 100 fordon. Du kan definiera 2 eller 3 ruttmallar:
- Skift kl. 06.00–18.00, kapacitet 4, storlek=60
- Skift kl. 13.00–01.00, kapacitet 4, storlek = 50
- Skift kl. 06.00–20.00, kapacitet 10, storlek=35
Det innebär att API:et automatiskt kan skapa upp till 60 fordon med mall 1 efter behov, 5 med mall 2 och 35 med mall 3.
maxInstances: [valfritt] Om routeTemplateId tillhandahålls, maxInstances anger hur många ruttmallar som ska genereras utifrån den angivna ruttmallen.
Följande regler gäller vid konfigurering av rutter med hjälp av
id, routeTemplateId, och maxInstances:
Exakt ett av id eller routeTemplateId måste användas – aldrig båda.
id och maxInstances kan inte användas tillsammans.
Om båda routeTemplateId och maxInstances om dessa finns tillgängliga, använder API:et ruttmall för att skapa rutter.
jobb: en matris med jobobjekt [minst ett jobb krävs]:
id: [obligatoriskt] en unik identifierare (heltal) för jobbet
pickups: [ valfritt] en matris med Task-objekt, där varje objekt definierar en upphämtningsuppgift
deliveries: [valfritt] en matris med Task-objekt, där varje objekt definierar en leveransuppgift (eller avlämningsuppgift)
API:et har strikta regler för konfigurationen av hämtning och leverans av jobb:
- API:et stöder inte uppdrag med flera upphämtningar och flera leveranser.
- API:et stöder inte uppdrag utan upphämtningar och utan leveranser.
- Om bara
"pickups"om detta anges klassificeras jobbet som ett uppdragsbaserat arbete. - Om bara
"deliveries"om detta anges klassificeras jobbet som ett leveransbaserat arbete. - Om ett uppdrag omfattar både upphämtning och leverans bestäms utgångspunkten av den uppgift som anger ett tidsfönster.
- Om båda uppgifterna har tidsfönster behandlas jobbet som ett hämtningsbaserat jobb.
Varje uppgiftsobjekt består av följande attribut:
id: [obligatoriskt] en unik identifierare (heltal) för uppgiften
plats: [obligatoriskt] Det är ett nyckel-värde-objekt som anger geografiska koordinater (latitud och longitud) för den plats där uppgiften ska utföras. Du kan ange det som en matris, till exempel [A,B] där A står för latituden och B står för longituden. Alternativt kan du ange den som {"lat": A,"lng": B}.
Exempel:
"location": {"lat": 52.46642, "lng": 13.28124}
"location": [52.46642, 13.28124]
serviceWindows: [valfritt eller obligatoriskt beroende på användningsfall, se definitionen av upphämtningar och leveranser ovan] Här anges det tidsfönster inom vilket uppgiften ska utföras. Tidsfönstret är en matris med följande format: [A, B] där A och B är start- respektive sluttid för tjänstens tidsfönster. API:et försöker beräkna en beräknad ankomsttid (ETA) inom det angivna tidsfönstret för den aktuella uppgiften. Om detta inte är möjligt kommer uppgiften att visas som icke tilldelad. Med andra ord definierar tiderna ”A” och ”B” den tidigaste och senaste tidpunkten då en uppgift måste vara slutförd av ett fordon. För uppgifter som är flexibla eller inte tidskänsliga, använd ett godtyckligt stort fönster (max 24 timmar) för att ge API:et större flexibilitet vid schemaläggning av andra uppgifter. Den aktuella versionen av API:et stöder endast ett servicefönster för varje uppgift.
För uppdrag som endast avser avhämtning eller endast leverans krävs ett tidsfönster. Exempel:
"serviceWindows": ["2024-08-30T09:00:00-08:00",
"2024-08-30T21:00:00-08:00"]
varaktighet: [obligatoriskt] Anger uppgiftens varaktighet i sekunder. Det kan vara antingen ett heltal eller ett nyckel-värde-objekt med följande nycklar:
"fixed": den fasta varaktigheten (i sekunder) för uppgiften (t.ex. för att hitta en parkeringsplats, köra ner hissen osv.)
"service": den tid (i sekunder) som krävs för att utföra uppgiften.
Exempel:
"duration": 1950
OR
"duration": {"fixed":150, "service": 1800}
efterfrågan: [ valfritt] en matris med kapacitetsbehov för uppgiften. Strukturen för varje efterfrågeobjekt är identisk med den för kapacitetsobjektet i den ovan definierade flottentiteten. Varje kapacitetspost består av ett namn (sträng) och dess tillgängliga enheter (heltal). De angivna namnen måste stämma överens med de som definierats i kapacitetsobjektet för flottentiteten. Om ett jobb till exempel kräver kapacitet för två sittplatser och 20 paket, definierar du efterfrågan enligt följande:
"demand": [
{
"name": "seat",
"units": 2,
},
{
"name": "package",
"units": 20,
}
]
färdigheter: [valfritt] en uppsättning färdigheter eller utrustning som krävs för att utföra uppgiften, där varje färdighet representeras av en godtycklig sträng som är specifik för din applikation. Endast fordon vars färdighetsuppsättning stämmer överens med uppgiftens färdighetsuppsättning kommer att beaktas för att utföra uppgiften. Dessa färdigheter matchas mot de färdigheter som definierats i den ovan definierade flottentiteten. Exempel:
"skills": ["lift", "ladder", "welding machine"]
status: [valfritt, används endast vid omoptimering] Det är en sträng som anger uppgiftens status och kan vara något av följande: "pending", "in_progress", "performed". Denna information är avgörande för att kunna omoptimera en pågående rutt så att den tar hänsyn till nya förändringar, såsom trasiga fordon, försenade uppdrag, nya uppdrag eller inställda uppdrag. API:et använder dessa data för att omoptimera planen på ett effektivt sätt. När du omoptimerar ett befintligt schema måste du därför ange värdet för detta attribut. För nya uppdrag eller uppdrag som ännu inte har utförts ska du ställa in det till "pending". Om uppgiften redan har utförts, ställ in den på "performed". Om fordonet redan har anlänt till platsen där uppgiften ska utföras och uppgiften pågår, ställ in den på "in_progress". Standardvärdet är "pending".
Exempel: "status": "pending"
vehicleId: [valfritt, används endast för omoptimering], anger det tilldelade fordons-ID:t (heltal) för de redan schemalagda uppdragen. Denna information är avgörande för att omoptimera en pågående rutt så att nya förändringar beaktas, såsom fordon som gått sönder, försenade uppdrag, nya uppdrag eller inställda uppdrag. API:et använder dessa uppgifter för att omoptimera planen på ett effektivt sätt. Därför måste du ange värdet för detta attribut när du omoptimerar ett befintligt schema. Standardvärdet är noll. För nya uppgifter ska du ställa in det på noll. För befintliga uppgifter som redan är tilldelade ett fordon ska du ställa in detta attribut på det tilldelade fordons-ID:t.
Exempel: "vehicleId": 12
ETA: [valfritt, används endast vid omoptimering], anger den aktuella ETA (beräknad ankomsttid) för de redan schemalagda uppdragen. Denna information är avgörande för att omoptimera en pågående rutt och ta hänsyn till nya förändringar, såsom fordon som gått sönder, försenade uppdrag, nya uppdrag eller inställda uppdrag. API:et använder dessa data för att omoptimera planen på ett effektivt sätt. Därför måste du ange värdet för detta attribut när du omoptimerar ett befintligt schema. Standardvärdet är 0. För nya eller utförda uppgifter ska du ställa in det på 0, men för befintliga väntande uppgifter ska du ställa in det på den befintliga ETA.
Exempel: "eta": "2021-07-04T12:13:00-08:00"
mål: [ valfritt] ett heltal som anger optimeringsmålet (strategi): (standardvärde = 1)
1: Minimera total restid [standard]
2: Minimera antalet rutter
3: Fördela arbetsbelastningen mellan rutterna
Exempel: "objective": 1
konfiguration: [ valfritt] kan användas för att ange ytterligare inställningar eller konfigurationer:
polylinetyp: [valfritt] anger vilken typ av utgående polylinje som kan returneras för varje planerad rutt. Det är en sträng som består av följande alternativ: "none", "plain", "encoded". Om "none"är valt kommer inga polylinjer att inkluderas i API-svaret. Om "plain" anges, returneras en ordnad lista över korsningar som vi måste passera mellan varje par på varandra följande hållplatser som en polylinje. Om "encoded" används komprimeras polylinjen till ett strängformat som användarna kan skicka till navigations-API:er från tredje part, till exempel Google Maps, för att få steg-för-steg-vägbeskrivningar. Standardvärdet är "none".
unassignedTasks: [valfritt] En flagga som avgör om de icke tilldelade uppgifterna ska inkluderas i svaret eller inte. Standardvärdet är False. Om API:et av någon anledning inte kan tilldela en uppgift till en rutt kommer den att listas som icke tilldelad.
statistik: [ valfritt] en flagga som avgör om optimeringsstatistiken ska inkluderas i den slutliga lösningen eller inte. Standardvärdet är True.
enheter: [valfritt] här anges enheterna för utdatastatistiken samt enheterna för flottans gränsvärden. Det kan vara antingen "metric" eller "imperial". Standardvärdet är "metric".
maxRideTable: [valfritt] Det anger den maximala restiden för alla uppdrag. Den definieras av en statisk tabell där varje rad är en matris som innehåller tre tidsvärden (i minuter): [A, B, C]. Det innebär att om den direkta restiden för ett uppdrag ligger mellan A och B, är den maximala restiden lika med ”rideTime+C”. Här är till exempel en enkel tabell med två rader: "maxRideTable":[[0, 10, 30], [11, 20, 40]]. Standardinställningen är [[0, 300, 720]]. Överlappningar och luckor är inte tillåtna i denna tabell. Dessutom anges tiden i minuter.
Fordonskapacitet: [valfritt] Definitioner av fordonets kapacitet kan namnges och sedan användas i avsnittet om fordonsparken. Detta är särskilt användbart vid komplexa definitioner där ett fordon kan ha flera olika konfigurationer. Om ett fordon till exempel kan rymma antingen (10 ”gående” passagerare och 0 ”rullstolsburna” passagerare) ELLER (8 ”gående” passagerare och 1 ”rullstolsburen” passagerare) kan du definiera "vehicleCapacities":{"flexBus": [[{"name": "ambulatory", "units": 10}], [{"name": "ambulatory", "units": 8},{"name":"wheelchair", "units": 1}]]}. Och sedan kan du i flottans egenskaper använda fleet[<index>].capacities: "flexBus" för varje flexBus i fordonsflottan. Namngivna fordonskapaciteter kan också sparas i din personliga kundprofil, där de blir tillgängliga för användning utan att du behöver ange dem i konfigurationsavsnittet. Om en namngiven fordonskapacitet finns både i din personliga profil och i lastkapaciteten, har definitionen i lastkapaciteten företräde.
freezeWindowLength: [valfritt] Frysfönstrets längd i minuter. Ett frysfönster är ett begrepp som endast gäller optimering samma dag och är användbart vid omoptimering av ett problem. Om du till exempel redan har optimerat ett problem men vill göra ändringar mitt på dagen kan du skicka problemet på nytt (med lämplig task.status för att återspegla vad som redan har gjorts) och ställa in ett frysfönster på 60 minuter. Detta instruerar optimeringsverktyget att tidsperioden som sträcker sig 60 minuter från ”nu” är förbjuden. Inga uppgifter kan läggas till eller tas bort från någon rutt inom frysfönstret.
lifo-begränsade kapaciteter: [valfritt] En matris med kapacitetstyper som omfattas av LIFO-principen (Last In, First Out). Exempel: "lifoConstrainedCapacities": ['wheelchair', 'scooter']
Exempel:
"configuration":
{
"polylineType": "plain",
"unassignedTasks": False,
"statistics": True,
}
version: [ valfritt]: anger API:ets version. Standardvärdet är 1.0.
För att se olika exempel på en
Problem och lär dig hur du använder API:et i olika användningsfall (t.ex. omoptimering), se Handledningar.Obs!
1. Unika identifierare
-
- Alla jobb måste ha unika ID-nummer.
- Alla uppgifter måste ha unika ID-nummer.
- Alla fordon måste ha unika ID-nummer.
- Ett jobb kan ha samma ID som en uppgift eller ett fordon – detta är tillåtet.
2. Tidsbegränsningar
Varje problem kan innehålla flera tidsrelaterade faktorer, till exempel tidsfönster för uppgifter och fordonsskift.
API:et fastställer den kortaste tiden bland alla värden. Om den kortaste tiden till exempel är:
2024-09-18T04:32:00-08:00Maxvärdet beräknas enligt följande:
- Att fastställa midnatt den dag då minimivärdet inträffar.
- Lägg till 33 timmar till den tidsstämpeln.
I det här exemplet är alltså den maximalt tillåtna tiden:
2024-09-19T09:00:00-08:00Om någon del av uppgiften (t.ex. fordonets skift eller arbetsperiod) överskrider denna tid, kommer API:et att returnera ett 400 fel.
Lösning nr
Som förklaras i avsnittet ”Kom igång” får du ett unikt referens-ID när du skickar in ett problem med POST-metoden. Du kan använda detta referens-ID med GET-metoden för att hämta status för det inskickade problemet. Om optimeringslösningen är klar kan du komma åt den i "solution" enheten i det mottagna svaret. Som framgår av följande figur, "solution" Enheten består av tre huvuddelar:
"statistics": Den innehåller olika statistiska uppgifter (mätvärden) som ger en översikt över hela lösningen för alla rutter, vilket gör att du kan utvärdera dess effektivitet. Dessa mätvärden omfattar till exempel den totala körsträckan för alla optimerade rutter. Genom att analysera dessa statistiska uppgifter kan du mäta kvaliteten och effektiviteten hos den framtagna lösningen. Dessa insikter hjälper dig att förstå optimeringsprocessens prestanda och effekter.
"routes": den innehåller de optimerade rutterna tillsammans med deras hållplatser och beräknade ankomsttid (ETA). Den kan även innehålla en linje som visar varje rutt.
"unassigned": den innehåller en lista över icke tilldelade uppgifter. Om API:et inte kan tilldela en uppgift till en rutt under optimeringsprocessen kommer den att listas som icke tilldelad. Dessutom kan den innehålla orsaker till varför varje uppgift förblir icke tilldelad, vilket ger en inblick i eventuella begränsningar eller problem som hindrade tilldelningen.

Schema för utdatalösning: #
Mallen för lösningen på optimeringsproblemet som tillhandahålls i API:ets utdatasvar ser ut enligt följande:
"solution": {
"statistics": {},
"routes": []
"unassigned": [],
}
Den "solution" Objektet representerar lösningen på problemet med ruttoptimering och består av följande attribut:
statistik: den innehåller statistik för hela lösningen och består av följande egenskaper:
”avstånd”:
”totalDistance”: den totala sträckan som hela fordonsflottan har tillryggalagt. Detta mått omfattar sträckan från varje fordons startplats till dess slutdestination.
”revenueDistance”:den totala intäktssträckan som hela fordonsflottan har tillryggalagt. Detta mått omfattar sträckan från det första stoppet till det sista stoppet för varje fordon. Det omfattar inte sträckan från fordonets startplats till det första stoppet eller sträckan från det sista stoppet till fordonets slutplats.
”fordon”:
”begagnade”: Antalet begagnade fordon som används i lösningen för att utföra de schemalagda jobben/uppgifterna.
”outnyttjade”: Antalet outnyttjade fordon
”jobb”:
”scheduledTasks”: Antalet schemalagda uppgifter
”unassignedTasks”: Antalet icke tilldelade uppgifter
”tider”:
”totalHours”:det totala antalet körtimmar för hela fordonsflottan. Detta mått omfattar den tid som går åt för att köra från varje fordons startplats till dess slutdestination.
”intäktsstimmar”:den totala antalet intäktsstimmar som hela fordonsflottan har kört. Detta mått omfattar tiden från det första stoppet till det sista stoppet för varje fordon. Det omfattar inte tiden som går åt för att köra från fordonets startplats till det första stoppet eller från det sista stoppet till fordonets slutdestination.
Exempel:
"statistics": {
"distance": {
"totalDistance": 42,
"revenueDistance": 25
},
"vehicles": {
"used": 2,
"unused": 0
},
"jobs": {
"scheduledTasks": 3,
"unassignedTasks": 0
},
"times": {
"totalHours": 11.6,
"revenueHours": 10.8
}
}
rutter: den tillhandahåller en matris med den schemalagda rutten för varje fordon. Varje schemalagd rutt innehåller följande data:
”vehicleId”: ett heltal som anger ID-numret för det tilldelade fordonet
”skift”: en matris med skift-objekt. Observera att API:et stöder flera skift för varje fordon. Varje skift-objekt består av följande element:
”index”: skiftets index (heltal)
”hållplatser”: här anges en lista över alla hållplatser som fordonet ska stanna vid under detta skift. Varje hållplats har följande egenskaper:
”ordinal”: Hållplatsens position i tidtabellen, angiven med ett index (heltal).
”jobId”: Jobb-ID för denna hållplats (heltal)
”taskId”: Uppgifts-ID för detta stopp (heltal)
”typ”: Typen (sträng) av det uppdrag som ska utföras vid detta stopp (”upphämtning” eller ”leverans”)
”plats”: Geokoordinaterna för hållplatsens läge
”eta”: Beräknad ankomsttid (ETA) för stoppet (i samma tidszon som den inmatade nyttolasten)
”timeToNext”: Dettaär körtiden till nästa stopp. Om du till exempel släpper av en passagerare kl. 09.00 och ditt nästa uppdrag är kl. 10.00, visar denna uppgift att körtiden från det aktuella stoppet till nästa stopp är 20 minuter.
”distanceToNext”: Detta är körsträckan till nästa hållplats. Beroende på vilka enheter som valts under ”konfiguration” kan detta anges i mil eller meter.
”waitTime”: väntetiden anger hur länge föraren bör vänta vid nästa hållplats om han börjar köra nu.
”polyline”:Den polylinje som förbinder hållplatsen med den föregående hållplatsen. Om ”plain” anges i ”configuration” är polylinjen en ordnad lista över korsningar som vi måste passera mellan den föregående hållplatsen och den aktuella hållplatsen. Om ”encoded” anges i ”configuration” kodas den vanliga polylinjen och returneras som en kodad sträng.
”break”: om det schemalagda stoppet avser en paus, anger detta pausens ID. Övriga stopp har inte detta element. API:et kräver inte att pauserna (eller jobben) listas i kronologisk ordning.
Exempel:
"routes": [
{
"vehicleId": 1,
"shifts": [
{
"index": 1,
"stops": [
{
"break": 1,
"start": "2023-10-01T10:00:00-08:00",
"end": "2023-10-01T10:15:00-08:00",
"timeToNext": 15,
"distanceToNext": 7.3,
"waitTime": 0,
"polyline": null,
"ordinal": 1
},
{
"jobId": 4,
"taskId": 5,
"type": "pickup",
"location": [
50.70816,
-120.37796
],
"eta": "2023-10-01T10:30:00-08:00",
"timeToNext": 13,
"distanceToNext": 5.6,
"waitTime": 112,
"polyline": null,
"ordinal": 2
},
{
"jobId": 4,
"taskId": 6,
"type": "delivery",
"location": [
50.66559,
-120.36924
],
"eta": "2023-10-01T12:45:00-08:00",
"timeToNext": 4,
"distanceToNext": 1.7,
"waitTime": 71,
"polyline": null,
"ordinal": 3
},
{
"break": 2,
"start": "2023-10-01T14:00:00-08:00",
"end": "2023-10-01T14:15:00-08:00",
"timeToNext": 7,
"distanceToNext": 3.2,
"waitTime": 217,
"polyline": null,
"ordinal": 4
}
]
}
]
},
{
"vehicleId": 2,
"shifts": [
{
"index": 1,
"stops": [
{
"break": 1,
"start": "2023-10-01T11:00:00-08:00",
"end": "2023-10-01T11:15:00-08:00",
"timeToNext": 3,
"distanceToNext": 1.2,
"waitTime": 267,
"polyline": null,
"ordinal": 1
},
{
"jobId": 10,
"taskId": 11,
"type": "pickup",
"location": [
50.65187,
-120.40052
],
"eta": "2023-10-01T15:45:00-08:00",
"timeToNext": 12,
"distanceToNext": 6.4,
"waitTime": 0,
"polyline": null,
"ordinal": 2
},
{
"jobId": 10,
"taskId": 12,
"type": "delivery",
"location": [
50.69262,
-120.35412
],
"eta": "2023-10-01T16:22:00-08:00",
"timeToNext": 6,
"distanceToNext": 2.7,
"waitTime": 91,
"polyline": null,
"ordinal": 3
}
]
}
]
}
]
ej tilldelade: Den valfria listan över ej tilldelade uppgifter innehåller uppgifter som inte kan tilldelas på grund av särskilda begränsningar. Varje post består av ett jobb-id, ett uppgifts-id och eventuella skäl till att uppgiften inte tilldelats (en kod samt en beskrivning):
”id”:
”job”: jobb-ID (heltal) för den icke tilldelade uppgiften
”uppgift”: ID-numret (heltal) för den icke tilldelade uppgiften
”anledning”: en lista över möjliga orsaker till de icke tilldelade uppgifterna
”kod”: koden (heltal) för den möjliga orsaken
”description”: beskrivningen (sträng) av den möjliga orsaken
{
"unassigned": [
{
"id": {
"job": 2,
"task": 1
},
"reason": [
{
"code": 2,
"description": "Not enough capacity for this job"
}
]
},
{
"id": {
"job": "31",
"task": "2"
},
"reason": [
{
"code": 5,
"description": "The service time of the job is out of the shift hours"
}
]
}
]
}
Ordlista #
|
|---|
Handledningar #
På den här sidan hittar du olika exempel som visar hur API:et kan användas i olika situationer. API:et stöder främst två huvudsakliga användningsfall:
-
Planering och schemaläggning: Skapar ett optimerat schema för en fordonsparks körningar, med hänsyn till begränsningar som rör uppdrag och fordon.
-
Omoptimering: Ändrar ett befintligt eller pågående schema för att ta hänsyn till förändringar som nya uppdrag, avbokningar eller fordon som gått sönder.
Ta en titt på exemplen nedan för att se hur dessa användningsfall har implementerats:
Exempel 1: Planering av ett enkelt scenario för upphämtning och leverans
Exempel 2: Ett enkelt scenario för omoptimering vid tillägg av nya jobb till ett befintligt schema
Exempel 3: Omoptimering med avbrutna jobb
Exempel 4: Omoptimering med trasiga fordon
De platser som nämns i följande exempel är fiktiva och slumpmässigt genererade och motsvarar inga verkliga platser.
Exempel 1: Planera ett enkelt scenario för upphämtning och leverans #
I det här exemplet består vår fordonsflotta av två fordon, och vi har tre upphämtnings- och leveransuppdrag som måste utföras av dessa två fordon. Här är uppgifterna för varje fordon:
Fordonsnummer 1:
Arbetstidsuppgifter: Skiftet börjar den 1 oktober 2024 kl. 08:00 PST på platsen (50.67293, -120.34195) och slutar kl. 18:00 på samma plats. Observera att tidszonen är PST, så starttiden registreras som 2024-10-01T08:00:00-08:00, och sluttiden kommer att vara 2024-10-01T18:00:00-08:00.
Pauser: Fordonet har två pauser, som var och en varar i 15 minuter:
Första pausen: Mellan kl. 10.00 och 10.30 på platsen (50.6531, -120.38393).
Andra pausen: Mellan kl. 14.00 och 14.30 på platsen (50.6531, -120.38393).
Kapacitet: 15 passagerare och 5 lastplatser.
Utrustning: Utrustad med hiss och luftkonditionering.
Fordonsnummer 2:
Arbetstidsuppgifter: Arbetstiden börjar den 1 oktober 2024 kl. 08:00 PST vid koordinaterna (50.7117, -120.39286) och slutar kl. 18:00 vid koordinaterna (50.67698, -120.32012).
Raster: Fordonet har en rast på 15 minuter:
Paus: Mellan kl. 11.00 och 11.30 på platsen (50.6531, -120.38393).
Kapacitet: 10 passagerare och 8 bagageplatser.
Utrustning: Endast utrustad med hiss.
Vi har även tre uppdrag av typen ”hämtning och leverans” i Kamloops, BC, Kanada. Här är detaljerna för varje uppdrag:
Jobb 1:
Upphämtningsplats: Koordinater (50.65391, -120.37365)
Tjänstetidsfönster: 09:00–09:30 (uppdraget är kopplat till en upphämtning, och upphämtningen måste ske inom detta tidsfönster)
Varaktighet: 10 minuter
Krav: 1 sittplats, 2 lastplatser, fordon utrustat med lyftanordning
Leverans: Plats (50.69409, -120.35425)
Längd: 5 minuter
Job 2:
Upphämtningsplats: Koordinater (50.70816, -120.37796)
Varaktighet: 5 minuter
Krav: 1 plats, fordon utrustat med både hiss och luftkonditionering
Leverans: Plats (50.66559, -120.36924)
Tidsfönster: 12:45–13:30 (uppdraget är leveransbundet och leveransen måste ske inom detta tidsfönster)
Varaktighet: 5 minuter
Job 3:
Upphämtningsplats: Koordinater (50.70393, -120.37263)
Tidsfönster: 14:00–14:30 (uppdraget är kopplat till en upphämtning, och upphämtningen måste ske inom detta tidsfönster)
Varaktighet: 10 minuter
Krav: 1 passagerarplats, 3 lastplatser, ingen särskild utrustning krävs
Leverans: Plats (50.69028, -120.39028)
Längd: 5 minuter
Vårt mål är att fördela dessa uppdrag på de angivna fordonen så att den totala restiden minimeras. Med andra ord kommer vårt optimeringsmål att vara lika med 1. Låt oss nu formulera vårt ingångsproblem enligt följande:
Indata (nyttolast):
{
"problem": {
"fleet": [
{
"id": 1,
"shifts": [
{
"start": {
"time": "2023-10-01T08:00:00-08:00",
"location": {
"lat": 50.67293,
"lng": -120.34195
}
},
"end": {
"time": "2023-10-01T18:00:00-08:00",
"location": {
"lat": 50.67293,
"lng": -120.34195
}
},
"breaks": [
{
"serviceWindow": [
"2023-10-01T10:00:00-08:00",
"2023-10-01T10:30:00-08:00"
],
"duration": 900,
"location": {
"lat": 50.6531,
"lng": -120.38393
}
},
{
"serviceWindow": [
"2023-10-01T14:00:00-08:00",
"2023-10-01T14:30:00-08:00"
],
"duration": 900,
"location": {
"lat": 50.6531,
"lng": -120.38393
}
}
]
}
],
"capacities": [
{
"name": "seat",
"units": 15
},
{
"name": "cargo",
"units": 5
}
],
"skills": [
"lift",
"air_conditioner"
]
},
{
"id": 2,
"shifts": [
{
"start": {
"time": "2023-10-01T08:00:00-08:00",
"location": {
"lat": 50.7117,
"lng": -120.39286
}
},
"end": {
"time": "2023-10-01T18:00:00-08:00",
"location": {
"lat": 50.67698,
"lng": -120.32012
}
},
"breaks": [
{
"serviceWindow": [
"2023-10-01T11:00:00-08:00",
"2023-10-01T11:30:00-08:00"
],
"duration": 900,
"location": {
"lat": 50.6531,
"lng": -120.38393
}
}
]
}
],
"capacities": [
{
"name": "seat",
"units": 10
},
{
"name": "cargo",
"units": 8
}
],
"skills": [
"lift"
]
}
],
"jobs": [
{
"id": 1,
"pickups": [
{
"id": 2,
"location": [
50.65391,
-120.37365
],
"serviceWindows": [
[
"2023-10-01T09:00:00-08:00",
"2023-10-01T09:30:00-08:00"
]
],
"duration": 600,
"demand": [
{
"name": "seat",
"units": 1
},
{
"name": "cargo",
"units": 2
}
],
"skills": [
"lift"
]
}
],
"deliveries": [
{
"id": 3,
"location": [
50.69409,
-120.35425
],
"duration": 300,
"demand": [
{
"name": "seat",
"units": 1
},
{
"name": "cargo",
"units": 2
}
],
"skills": [
"lift"
]
}
]
},
{
"id": 4,
"pickups": [
{
"id": 5,
"location": [
50.70816,
-120.37796
],
"duration": 300,
"demand": [
{
"name": "seat",
"units": 1
}
],
"skills": [
"lift",
"air_conditioner"
]
}
],
"deliveries": [
{
"id": 6,
"location": [
50.66559,
-120.36924
],
"serviceWindows": [
[
"2023-10-01T12:45:00-08:00",
"2023-10-01T13:30:00-08:00"
]
],
"duration": 300,
"demand": [
{
"name": "seat",
"units": 1
}
],
"skills": [
"lift",
"air_conditioner"
]
}
]
},
{
"id": 7,
"pickups": [
{
"id": 8,
"location": [
50.70393,
-120.37263
],
"serviceWindows": [
[
"2023-10-01T14:00:00-08:00",
"2023-10-01T14:30:00-08:00"
]
],
"duration": 600,
"demand": [
{
"name": "seat",
"units": 1
},
{
"name": "cargo",
"units": 3
}
]
}
],
"deliveries": [
{
"id": 9,
"location": [
50.69028,
-120.39028
],
"duration": 300,
"demand": [
{
"name": "seat",
"units": 1
},
{
"name": "cargo",
"units": 3
}
]
}
]
}
],
"objective": 1,
"configuration": {
"polylineType": "none",
"unassignedTasks": true,
"units": "imperial",
"statistics": true
}
}
}
Efter att ha skickat in detta problem med POST-metoden (enligt beskrivningen i ”Kom igång”) får vi följande lösning med GET-metoden:
Lösning:
{
"id": 8193,
"status": 200,
"solution": {
"statistics": {
"distance": {
"totalDistance": 54,
"revenueDistance": 36
},
"vehicles": {
"used": 2,
"unused": 0
},
"jobs": {
"scheduledTasks": 3,
"unassignedTasks": 0
},
"times": {
"totalHours": 9.4,
"revenueHours": 8.7
}
},
"routes": [
{
"vehicleId": 1,
"shifts": [
{
"index": 1,
"stops": [
{
"jobId": 1,
"taskId": 2,
"type": "pickup",
"location": [
50.65391,
-120.37365
],
"eta": "2023-10-01T09:00:00-08:00",
"timeToNext": 10,
"distanceToNext": 4.9,
"waitTime": 0,
"polyline": null,
"ordinal": 1
},
{
"jobId": 1,
"taskId": 3,
"type": "delivery",
"location": [
50.69409,
-120.35425
],
"eta": "2023-10-01T09:25:00-08:00",
"timeToNext": 10,
"distanceToNext": 5.4,
"waitTime": 25,
"polyline": null,
"ordinal": 2
},
{
"break": 1,
"start": "2023-10-01T10:00:00-08:00",
"end": "2023-10-01T10:15:00-08:00",
"timeToNext": 15,
"distanceToNext": 7.3,
"waitTime": 0,
"polyline": null,
"ordinal": 3
},
{
"jobId": 4,
"taskId": 5,
"type": "pickup",
"location": [
50.70816,
-120.37796
],
"eta": "2023-10-01T10:30:00-08:00",
"timeToNext": 13,
"distanceToNext": 5.6,
"waitTime": 112,
"polyline": null,
"ordinal": 4
},
{
"jobId": 4,
"taskId": 6,
"type": "delivery",
"location": [
50.66559,
-120.36924
],
"eta": "2023-10-01T12:45:00-08:00",
"timeToNext": 4,
"distanceToNext": 1.7,
"waitTime": 71,
"polyline": null,
"ordinal": 5
},
{
"break": 2,
"start": "2023-10-01T14:00:00-08:00",
"end": "2023-10-01T14:15:00-08:00",
"timeToNext": 7,
"distanceToNext": 3.2,
"waitTime": 217,
"polyline": null,
"ordinal": 6
}
]
}
]
},
{
"vehicleId": 2,
"shifts": [
{
"index": 1,
"stops": [
{
"break": 1,
"start": "2023-10-01T11:00:00-08:00",
"end": "2023-10-01T11:15:00-08:00",
"timeToNext": 13,
"distanceToNext": 6.6,
"waitTime": 152,
"polyline": null,
"ordinal": 1
},
{
"jobId": 7,
"taskId": 8,
"type": "pickup",
"location": [
50.70393,
-120.37263
],
"eta": "2023-10-01T14:00:00-08:00",
"timeToNext": 14,
"distanceToNext": 4.6,
"waitTime": 0,
"polyline": null,
"ordinal": 2
},
{
"jobId": 7,
"taskId": 9,
"type": "delivery",
"location": [
50.69028,
-120.39028
],
"eta": "2023-10-01T14:29:00-08:00",
"timeToNext": 13,
"distanceToNext": 3.9,
"waitTime": 197,
"polyline": null,
"ordinal": 3
}
]
}
]
}
],
"unassigned": []
},
"message": "success"
}
Exempel 2: Ett enkelt scenario för omoptimering vid tillägg av nya jobb till ett befintligt schema #
Tänk nu på det föregående exemplet. Anta att du har börjat följa det framtagna schemat sedan i morse, och att klockan nu är 11:36:34, och att du får en ny arbetsorder som lyder enligt följande:
Jobb 4: ( ett nytt jobb)
Upphämtningsplats: Koordinater (50.65187, -120.40052)
Tjänstetid: 15:45–16:15 (uppdraget utgår från en upphämtningsplats)
Varaktighet: 15 minuter
Krav: 1 sittplats, 1 last
Leverans: Plats (50.69262, -120.35412)
Längd: 10 minuter
Förresten, du har redan slutfört uppdrag 1, men uppdrag 2 och uppdrag 3 pågår fortfarande med följande detaljer:
Uppgift 1: (utförd)
Job 2: (pågår)
Upphämtning:
Aktuellt fordons-ID: 1
Beräknad ankomsttid: 10 :30
Leverans:
Aktuellt fordons-ID: 1
Beräknad ankomsttid: 12:45
Job 3: (pågår)
Upphämtning:
Aktuellt fordons-ID: 2
Beräknad ankomsttid: 14 :00
Leverans:
Aktuellt fordon-ID: 2
Beräknad ankomsttid: 14:29
Observera att eftersom uppdrag 2 och uppdrag 3 pågår har de ett tillhörande fordons-ID och en beräknad ankomsttid. För att omoptimera ditt schema så att det inkluderar det nya uppdraget (dvs. uppdrag 4) måste du skicka en uppdaterad översikt över ditt aktuella schema via API:et. Denna bör innehålla följande uppgifter om dina uppdrag:
Jobb 1: Eftersom detta uppdrag redan har utförts kan du ändra statusen för hämtnings- och leveransuppgifterna för detta uppdrag till "status":"performed" Observera att du inte behöver ange det aktuella fordons-ID:t och den beräknade ankomsttiden för dessa uppgifter, eftersom de redan har utförts och du inte längre kan ändra dem.
Uppdrag 2: Detta uppdrag pågår fortfarande och är tilldelat fordon 2 med beräknad ankomsttid för upphämtning kl. 10:30 och beräknad ankomsttid för leverans kl. 12:45. Du måste därför inkludera följande objekt för upphämtningsuppgiften:
"status": "in_progress",
"vehicleId": 1,
"eta": "2024-10-01T10:30:00-08:00"
Du måste dessutom inkludera följande objekt för dess leveransuppgift:
"status": "in_progress",
"vehicleId": 1,
"eta": "2024-10-01T12:45:00-08:00"
"status": "in_progress",
"vehicleId": 2,
"eta": "2024-10-01T14:00:00-08:00"
Du måste dessutom inkludera följande objekt för dess leveransuppgift:
"status": "in_progress",
"vehicleId": 2,
"eta": "2024-10-01T14:29:00-08:00"
Job 4: Eftersom det här är ett nytt jobb som ännu inte har schemalagts, anger du helt enkelt dess status till "status":"pending". Du behöver inte ange något fordons-ID eller någon beräknad ankomsttid för detta uppdrag, eftersom det ännu inte har schemalagts och du inte har tillgång till dessa uppgifter. När du har genomfört omoptimeringen kommer du att få ett fordons-ID och en beräknad ankomsttid för varje uppgift i detta uppdrag.
Dessutom måste du ange fordonens senast kända positioner så att API:et kan få en uppdaterad bild av ditt aktuella schema och därmed kunna utföra optimeringen på ett effektivt sätt. Anta att fordonens senast kända positioner klockan 11:36:34 (dvs. den tidpunkt då vi vill göra en ny optimering) är följande:
- Fordon 1: ( 50.66692,-120.35293)
- Fordon 2: ( 50.65324, -120.37398)
För detta ändamål måste du lägga till följande objekt för fordon 1:
"lastKnownLocation":{
"location":[50.66692,-120.35293],
"time":"2024-10-01T11:36:34-08:00"
}
På samma sätt måste du lägga till följande objekt för fordon 2:
"lastKnownLocation":{
"location":[50.65324,-120.37398],
"time":"2024-10-01T11:36:34-08:00"
}
För att göra en ny optimering kan du nu skicka in ditt nya optimeringsproblem på följande sätt:
{
"problem": {
"fleet": [
{
"id": 1,
"shifts": [
{
"start": {
"time": "2023-10-01T08:00:00-08:00",
"location": {
"lat": 50.67293,
"lng": -120.34195
}
},
"end": {
"time": "2023-10-01T18:00:00-08:00",
"location": {
"lat": 50.67293,
"lng": -120.34195
}
},
"breaks": [
{
"serviceWindow": [
"2023-10-01T10:00:00-08:00",
"2023-10-01T10:30:00-08:00"
],
"duration": 900,
"location": {
"lat": 50.6531,
"lng": -120.38393
}
},
{
"serviceWindow": [
"2023-10-01T14:00:00-08:00",
"2023-10-01T14:30:00-08:00"
],
"duration": 900,
"location": {
"lat": 50.6531,
"lng": -120.38393
}
}
]
}
],
"capacities": [
{
"name": "seat",
"units": 15
},
{
"name": "cargo",
"units": 5
}
],
"skills": [
"lift",
"air_conditioner"
],
"lastKnownLocation":{
"location":[50.66692,-120.35293],
"time":"2024-10-01T11:36:34-08:00"
}
},
{
"id": 2,
"shifts": [
{
"start": {
"time": "2023-10-01T08:00:00-08:00",
"location": {
"lat": 50.7117,
"lng": -120.39286
}
},
"end": {
"time": "2023-10-01T18:00:00-08:00",
"location": {
"lat": 50.67698,
"lng": -120.32012
}
},
"breaks": [
{
"serviceWindow": [
"2023-10-01T11:00:00-08:00",
"2023-10-01T11:30:00-08:00"
],
"duration": 900,
"location": {
"lat": 50.6531,
"lng": -120.38393
}
}
]
}
],
"capacities": [
{
"name": "seat",
"units": 10
},
{
"name": "cargo",
"units": 8
}
],
"skills": [
"lift"
],
"lastKnownLocation":{
"location":[50.65324,-120.37398],
"time":"2024-10-01T11:36:34-08:00"
}
}
],
"jobs": [
{
"id": 1,
"pickups": [
{
"id": 2,
"location": [
50.65391,
-120.37365
],
"serviceWindows": [
[
"2023-10-01T09:00:00-08:00",
"2023-10-01T09:30:00-08:00"
]
],
"duration": 600,
"demand": [
{
"name": "seat",
"units": 1
},
{
"name": "cargo",
"units": 2
}
],
"skills": [
"lift"
],
"status": "performed"
}
],
"deliveries": [
{
"id": 3,
"location": [
50.69409,
-120.35425
],
"duration": 300,
"demand": [
{
"name": "seat",
"units": 1
},
{
"name": "cargo",
"units": 2
}
],
"skills": [
"lift"
],
"status": "performed"
}
]
},
{
"id": 4,
"pickups": [
{
"id": 5,
"location": [
50.70816,
-120.37796
],
"duration": 300,
"demand": [
{
"name": "seat",
"units": 1
}
],
"skills": [
"lift",
"air_conditioner"
],
"status": "in_progress",
"vehicleId": 1,
"eta": "2023-10-01T10:30:00-08:00"
}
],
"deliveries": [
{
"id": 6,
"location": [
50.66559,
-120.36924
],
"serviceWindows": [
[
"2023-10-01T12:45:00-08:00",
"2023-10-01T13:30:00-08:00"
]
],
"duration": 300,
"demand": [
{
"name": "seat",
"units": 1
}
],
"skills": [
"lift",
"air_conditioner"
],
"status": "in_progress",
"vehicleId": 1,
"eta": "2023-10-01T12:45:00-08:00"
}
]
},
{
"id": 7,
"pickups": [
{
"id": 8,
"location": [
50.70393,
-120.37263
],
"serviceWindows": [
[
"2023-10-01T14:00:00-08:00",
"2023-10-01T14:30:00-08:00"
]
],
"duration": 600,
"demand": [
{
"name": "seat",
"units": 1
},
{
"name": "cargo",
"units": 3
}
],
"status": "in_progress",
"vehicleId": 2,
"eta": "2023-10-01T14:00:00-08:00"
}
],
"deliveries": [
{
"id": 9,
"location": [
50.69028,
-120.39028
],
"duration": 300,
"demand": [
{
"name": "seat",
"units": 1
},
{
"name": "cargo",
"units": 3
}
],
"status": "in_progress",
"vehicleId": 2,
"eta": "2023-10-01T14:29:00-08:00"
}
]
},
{
"id": 10,
"pickups": [
{
"id": 11,
"location": [
50.65187,
-120.40052
],
"serviceWindows": [
[
"2023-10-01T15:45:00-08:00",
"2023-10-01T16:15:00-08:00"
]
],
"duration": 900,
"demand": [
{
"name": "seat",
"units": 1
},
{
"name": "cargo",
"units": 1
}
],
"status": "pending"
}
],
"deliveries": [
{
"id": 12,
"location": [
50.69262,
-120.35412
],
"duration": 600,
"demand": [
{
"name": "seat",
"units": 1
},
{
"name": "cargo",
"units": 1
}
],
"status": "pending"
}
]
}
],
"objective": 1,
"configuration": {
"polylineType": "none",
"unassignedTasks": true,
"units": "imperial",
"statistics": true
}
}
}
Exempel 3: Omoptimering med avbrutna jobb #
Om du har skickat in ett optimeringsproblem för en uppsättning jobb och redan har ett schema på plats, men vissa jobb har avbokats, kan du optimera schemat på nytt genom att ta bort de avbokade jobben från problemet. För att göra detta måste du:
- Ge en aktuell översikt över dina återstående uppdrag och fordonens senast kända positioner, på samma sätt som i exempel 2.
- Skapa och skicka in en reviderad uppgift som återspeglar dessa ändringar.
När du har skickat in uppgifterna kommer du att få ett nytt schema som tar hänsyn till de uppdaterade uppdragen och fordonsflottans status.
Exempel 4: Omoptimering med trasiga fordon #
Anta att klockan är 08.00 och att du använder API:et för att skapa ett optimerat körschema för dina uppdrag med 10 fordon. Du börjar köra schemat, men klockan 09.14 får du reda på att ett av fordonen har gått sönder och inte längre kan utföra sina tilldelade uppdrag.
Gör så här för att optimera schemat på nytt:
-
Uppdatera flottinformation: Ta bort det trasiga fordonet från ditt flottobjekt.
-
Ange fordonens positioner: Ange de senast kända positionerna för de återstående fordonen, på samma sätt som i exempel 2.
-
Uppdatera uppgiftsstatus:
-
Ange status för alla uppgifter. Du måste ange vilka uppgifter som redan är utförda, vilka som är pågående och vilka som är nya eller väntande (ännu inte schemalagda).
-
För pågående uppdrag ska du ange det tillhörande fordons-ID:t och den beräknade ankomsttiden (ETA).
-
-
Åtgärder vid motorstopp:
-
Ändra statusen för alla uppdrag som tidigare tilldelats det havererade fordonet till ”väntande”. På så sätt kan API:et omfördela dem till andra tillgängliga fordon och beräkna deras beräknade ankomsttider på nytt.
-
-
Skicka för omoptimering: Skicka det uppdaterade problemet till API:et för en ny schemaläggningsoptimering.
Hur testar man schemalagda rutter? #
Steg 1: Skapa en åtkomsttoken
Skicka först en POST-förfrågan till följande URL för att hämta en åtkomsttoken för Vancouver (Tenant 2) med följande inloggningsuppgifter:
Länk till inlägget: https://iq.aiqwhite.ddsdeploytest.com/sso/auth-token
POST-begäran – Innehåll för Vancouver (Tenant2):
{
"plugin": "internal;basic",
"internal": {
"email": "tenant2@ddswireless.com",
"password": "AdM5I0N09ToS$IlJ",
"tenantId": 2
},
"basic": {
"username": "tenant2@ddswireless.com",
"password": "AdM5I0N09ToS$IlJ",
"tenantId": 2
}
}
POST-förfrågan – Body för Finland (Tenant3):
{
"plugin": "internal;basic",
"internal": {
"email": "tenant3@ddswireless.com",
"password": "AdM5I0N09ToS$IlJ",
"tenantId": 3
},
"basic": {
"username": "tenant3@ddswireless.com",
"password": "AdM5I0N09ToS$IlJ",
"tenantId": 3
}
}
Kopiera sedan den genererade koden. Här är en skärmdump av detta steg:

Steg 2: Skicka en indata (optimeringsproblem) till API:et
För att skicka en indata till API:et och få ett referens-ID ska du ange det genererade tokenet i fältet ”Authorization” i följande POST-förfrågan och ange indata i fältet ”Body” i förfrågan:
Länk till inlägget: https://iq.aiqwhite.ddsdeploytest.com/raas/optimization
Ett exempel på en datapaket:
{
"problem": {
"fleet": [
{
"id": 1,
"shifts": [
{
"start": {
"time": "2023-10-01T08:00:00-08:00",
"location": { "lat": 50.67293, "lng": -120.34195 }
},
"end": {
"time": "2023-10-01T18:00:00-08:00",
"location": { "lat": 50.67293, "lng": -120.34195 }
},
"breaks": [
{
"serviceWindow": ["2023-10-01T10:00:00-08:00", "2023-10-01T10:30:00-08:00"],
"duration": 900,
"location": { "lat": 50.6531, "lng": -120.38393 }
},
{
"serviceWindow": ["2023-10-01T14:00:00-08:00", "2023-10-01T14:30:00-08:00"],
"duration": 900,
"location": { "lat": 50.6531, "lng": -120.38393 }
}
]
}
],
"capacities": [
{
"name": "seat",
"units": 15
},
{
"name": "baggage",
"units": 5
}
],
"skills": ["lift", "air_conditioner"]
},
{
"id": 2,
"shifts": [
{
"start": {
"time": "2023-10-01T08:00:00-08:00",
"location": { "lat": 50.7117, "lng": -120.39286 }
},
"end": {
"time": "2023-10-01T18:00:00-08:00",
"location": { "lat": 50.67698, "lng": -120.32012 }
},
"breaks": [
{
"serviceWindow": ["2023-10-01T11:00:00-08:00", "2023-10-01T11:30:00-08:00"],
"duration": 900,
"location": { "lat": 50.6531, "lng": -120.38393 }
}
]
}
],
"capacities": [
{
"name": "seat",
"units": 10
},
{
"name": "baggage",
"units": 8
}
],
"skills": ["lift"]
}
],
"jobs": [
{
"id": 1,
"pickups": [
{
"id": 2,
"location": [50.65391, -120.37365],
"serviceWindows": [["2023-10-01T09:00:00-08:00", "2023-10-01T09:30:00-08:00"]],
"duration": 600,
"demand": [
{
"name": "seat",
"units": 1
},
{
"name": "baggage",
"units": 2
}
],
"skills": ["lift"]
}
],
"deliveries": [
{
"id": 3,
"location": [50.69409, -120.35425],
"duration": 300,
"demand": [
{
"name": "seat",
"units": 1
},
{
"name": "baggage",
"units": 2
}
],
"skills": ["lift"]
}
]
},
{
"id": 4,
"pickups": [
{
"id": 5,
"location": [50.70816, -120.37796],
"duration": 300,
"demand": [
{
"name": "seat",
"units": 1
}
],
"skills": ["lift", "air_conditioner"]
}
],
"deliveries": [
{
"id": 6,
"location": [50.66559, -120.36924],
"serviceWindows": [["2023-10-01T12:45:00-08:00", "2023-10-01T13:30:00-08:00"]],
"duration": 300,
"demand": [
{
"name": "seat",
"units": 1
}
],
"skills": ["lift", "air_conditioner"]
}
]
},
{
"id": 7,
"pickups": [
{
"id": 8,
"location": [50.70393, -120.37263],
"serviceWindows": [["2023-10-01T14:00:00-08:00", "2023-10-01T14:30:00-08:00"]],
"duration": 600,
"demand": [
{
"name": "seat",
"units": 1
},
{
"name": "baggage",
"units": 3
}
]
}
],
"deliveries": [
{
"id": 9,
"location": [50.69028, -120.39028],
"duration": 300,
"demand": [
{
"name": "seat",
"units": 1
},
{
"name": "baggage",
"units": 3
}
]
}
]
}
],
"objective": 1,
"configuration": {
"polylineType": "none",
"unassignedTasks": true,
"units" : "imperial",
"statistics" : true
}
}
}
Om POST-metoden lyckas får du ett referens-ID som du kan använda för att hämta svaret från API-anropet med hjälp av GET-metoden. Nedan visas en skärmdump av detta steg:

Steg 3: Hämta svaret från API-anropet
För att hämta svaret på API-anropet med hjälp av det mottagna referens-ID:t ska du ange åtkomsttokenet i avsnittet ”Authorization” i följande GET-förfrågan och inkludera referens-ID:t i URL:en enligt följande:
GET URL: https://iq.aiqwhite.ddsdeploytest.com/raas/optimization/{ID}
Här är en skärmdump av det här steget:

API-fel #
Som beskrivs i avsnittet ”Kom igång” stöder API:et både POST- och GET-metoder. Beroende på vilken metod som används returneras en statuskod i svaret. Här hittar du beskrivningar av de olika statuskoderna för dessa två metoder.
POST-statuskoder #
|
|---|
Hämta statuskoder #
|
|---|
Vanliga frågor #
|