Richieste e limiti di carico

Questa guida descrive loadDemands e loadLimits e la loro relazione e l'altro.

Come accennato in Vincoli per le finestre di tempo di ritiro e consegna, Il messaggio OptimizeToursRequest (REST, gRPC) contiene un certo numero di che specificano i vincoli al problema da ottimizzare. Diversi Le proprietà OptimizeToursRequest rappresentano i vincoli di caricamento.

I veicoli e le spedizioni hanno proprietà fisiche che devono essere prese in considerazione quando pianificare un percorso.

  • Veicoli: la proprietà loadLimits specifica il carico massimo che che il veicolo possa sostenere. Vedi la documentazione del messaggio Vehicle (REST, gRPC) documentazione.
  • Spedizioni: la proprietà loadDemands specifica la quantità di carico di un determinato durante la spedizione. Vedi la documentazione del messaggio Shipment (REST, gRPC) documentazione.

Insieme, questi due vincoli consentono all'ottimizzatore di assegnare in modo appropriato le spedizioni ai veicoli in un modo che corrisponda meglio della capacità della flotta e delle esigenze di spedizione.

Questa parte del documento illustra in dettaglio loadLimits e loadDemands.

Carica richieste e limiti: tipi

Puoi esprimere ogni vincolo di carico e limite in termini di tipo.

Puoi fornire il tuo insieme di tipi di carico, come nei seguenti esempi:

  • peso
  • volume
  • misurazioni lineari
  • nomi di oggetti o attrezzature trasportati

Questa guida utilizza weightKg come tipo di esempio.

Sia Shipment.loadDemands che Vehicle.loadLimits utilizzano i buffer di protocollo Tipo map, con chiavi string che rappresentano i tipi di carico.

I valori Shipment.loadDemands utilizzano il messaggio Load (REST, gRPC). Il messaggio Load ha una singola proprietà amount che rappresenta la quantità di capacità per completare la spedizione nel tipo specificato.

I valori Vehicle.loadLimits usano il messaggio LoadLimit (REST, gRPC). Il messaggio LoadLimit ha diverse proprietà, con maxLoad che rappresenta la capacità di carico massima del veicolo nel tipo specificato.

Il loadDemands di una spedizione consuma il loadLimits del veicolo assegnato solo se i due hanno chiavi per il tipo di caricamento corrispondenti. Ad esempio, una spedizione con loadDemands di:

"loadDemands": {
  "weightKg": {
    "amount": 50
  }
}

richiede 50 unità di caricamento nel tipo weightKg affinché la spedizione completata. Un veicolo con loadLimits di:

"loadLimits": {
  "weightKg": {
    "maxLoad": 100
  }
}

potrebbe essere in grado di completare la spedizione, come maxLoad del veicolo in Il tipo di weightKg è superiore o uguale al valore di loadDemands della spedizione in il tipo weightKg. Tuttavia, un veicolo con loadLimits di:

"loadLimits": {
  "equipmentRackStorage": {
    "maxLoad": 10
  }
}

ha implicitamente una capacità illimitata di weightKg a causa dell'assenza di una weightKg in modo che il veicolo non sia vincolato dall'entità della spedizione della domanda di peso.

Trasferimento del carico tra le spedizioni e i veicoli

Poiché le spedizioni vengono ritirate e consegnate dai veicoli, loadDemand vengono trasferiti tra la spedizione e il veicolo. Puoi vedere carichi del veicolo nel messaggio OptimizeToursResponse (REST, gRPC)routes.transitions per un determinato veicolo. La sequenza è come che segue:

  1. La capacità di carico richiesta è definita per la spedizione come loadDemand.
  2. La spedizione viene ritirata dal veicolo assegnato e dalla vehicleLoads aumenta dell'importo di loadDemand della spedizione. Questo il trasferimento è rappresentato da un visits.loadDemands positivo nella risposta per creare un nuovo messaggio email.
  3. Il veicolo consegna la spedizione e il numero di vehicleLoads del veicolo diminuisce per l'importo di loadDemand della spedizione consegnata. Questo trasferimento è rappresentato da visits.loadDemands negativo nel messaggio di risposta.

Il valore vehicleLoads di un veicolo non può superare il valore loadLimits specificato in nessun momento lungo il suo percorso.

Un esempio completo con richieste e limiti di carico

Visualizza un esempio di richiesta con esigenze di carico e limiti

{
  "populatePolylines": false,
  "populateTransitionPolylines": false,
  "model": {
    "globalStartTime": "2023-01-13T16:00:00Z",
    "globalEndTime": "2023-01-14T16:00:00Z",
    "shipments": [
      {
        "deliveries": [
          {
            "arrivalLocation": {
              "latitude": 37.789456,
              "longitude": -122.390192
            },
            "duration": "250s"
          }
        ],
        "pickups": [
          {
            "arrivalLocation": {
              "latitude": 37.794465,
              "longitude": -122.394839
            },
            "duration": "150s"
          }
        ],
        "penaltyCost": 100.0,
        "loadDemands": {
          "weightKg": {
            "amount": 50
          }
        }
      },
      {
        "deliveries": [
          {
            "arrivalLocation": {
              "latitude": 37.789116,
              "longitude": -122.395080
            },
            "duration": "250s"
          }
        ],
        "pickups": [
          {
            "arrivalLocation": {
              "latitude": 37.794465,
              "longitude": -122.394839
            },
            "duration": "150s"
          }
        ],
        "penaltyCost": 15.0,
        "loadDemands": {
          "weightKg": {
            "amount": 10
          }
        }
      },
      {
        "deliveries": [
          {
            "arrivalLocation": {
              "latitude": 37.795242,
              "longitude": -122.399347
            },
            "duration": "250s"
          }
        ],
        "pickups": [
          {
            "arrivalLocation": {
              "latitude": 37.794465,
              "longitude": -122.394839
            },
            "duration": "150s"
          }
        ],
        "penaltyCost": 50.0,
        "loadDemands": {
          "weightKg": {
            "amount": 80
          }
        }
      }
    ],
    "vehicles": [
      {
        "endLocation": {
          "latitude": 37.794465,
          "longitude": -122.394839
        },
        "startLocation": {
          "latitude": 37.794465,
          "longitude": -122.394839
        },
        "costPerHour": 40.0,
        "costPerKilometer": 10.0,
        "loadLimits": {
          "weightKg": {
            "maxLoad": 100
          }
        }
      }
    ]
  }
}
    

La richiesta di esempio contiene diversi parametri relativi al carico:

  • shipments[0] ha una domanda di carico di 50 weightKg.
  • shipments[1] ha una domanda di carico di 10 weightKg.
  • shipments[2] ha una domanda di carico di 80 weightKg.
  • vehicles[0] ha un limite di carico di 100 weightKg.

Visualizza una risposta alla richiesta con richieste di carico e limiti

{
  "routes": [
    {
      "vehicleStartTime": "2023-01-13T16:00:00Z",
      "vehicleEndTime": "2023-01-13T16:43:27Z",
      "visits": [
        {
          "isPickup": true,
          "startTime": "2023-01-13T16:00:00Z",
          "detour": "0s",
          "loadDemands": {
            "weightKg": {
              "amount": "50"
            }
          }
        },
        {
          "shipmentIndex": 1,
          "isPickup": true,
          "startTime": "2023-01-13T16:02:30Z",
          "detour": "150s",
          "loadDemands": {
            "weightKg": {
              "amount": "10"
            }
          }
        },
        {
          "startTime": "2023-01-13T16:08:55Z",
          "detour": "150s",
          "loadDemands": {
            "weightKg": {
              "amount": "-50"
            }
          }
        },
        {
          "shipmentIndex": 1,
          "startTime": "2023-01-13T16:16:37Z",
          "detour": "343s",
          "loadDemands": {
            "weightKg": {
              "amount": "-10"
            }
          }
        },
        {
          "shipmentIndex": 2,
          "isPickup": true,
          "startTime": "2023-01-13T16:27:07Z",
          "detour": "1627s",
          "loadDemands": {
            "weightKg": {
              "amount": "80"
            }
          }
        },
        {
          "shipmentIndex": 2,
          "startTime": "2023-01-13T16:36:26Z",
          "detour": "0s",
          "loadDemands": {
            "weightKg": {
              "amount": "-80"
            }
          }
        }
      ],
      "transitions": [
        {
          "travelDuration": "0s",
          "waitDuration": "0s",
          "totalDuration": "0s",
          "startTime": "2023-01-13T16:00:00Z",
          "vehicleLoads": {
            "weightKg": {}
          }
        },
        {
          "travelDuration": "0s",
          "waitDuration": "0s",
          "totalDuration": "0s",
          "startTime": "2023-01-13T16:02:30Z",
          "vehicleLoads": {
            "weightKg": {
              "amount": "50"
            }
          }
        },
        {
          "travelDuration": "235s",
          "travelDistanceMeters": 795,
          "waitDuration": "0s",
          "totalDuration": "235s",
          "startTime": "2023-01-13T16:05:00Z",
          "vehicleLoads": {
            "weightKg": {
              "amount": "60"
            }
          }
        },
        {
          "travelDuration": "212s",
          "travelDistanceMeters": 791,
          "waitDuration": "0s",
          "totalDuration": "212s",
          "startTime": "2023-01-13T16:13:05Z",
          "vehicleLoads": {
            "weightKg": {
              "amount": "10"
            }
          }
        },
        {
          "travelDuration": "380s",
          "travelDistanceMeters": 1190,
          "waitDuration": "0s",
          "totalDuration": "380s",
          "startTime": "2023-01-13T16:20:47Z",
          "vehicleLoads": {
            "weightKg": {}
          }
        },
        {
          "travelDuration": "409s",
          "travelDistanceMeters": 1371,
          "waitDuration": "0s",
          "totalDuration": "409s",
          "startTime": "2023-01-13T16:29:37Z",
          "vehicleLoads": {
            "weightKg": {
              "amount": "80"
            }
          }
        },
        {
          "travelDuration": "171s",
          "travelDistanceMeters": 665,
          "waitDuration": "0s",
          "totalDuration": "171s",
          "startTime": "2023-01-13T16:40:36Z",
          "vehicleLoads": {
            "weightKg": {}
          }
        }
      ],
      "metrics": {
        "performedShipmentCount": 3,
        "travelDuration": "1407s",
        "waitDuration": "0s",
        "delayDuration": "0s",
        "breakDuration": "0s",
        "visitDuration": "1200s",
        "totalDuration": "2607s",
        "travelDistanceMeters": 4812,
        "maxLoads": {
          "weightKg": {
            "amount": "80"
          }
        }
      },
      "routeCosts": {
        "model.vehicles.cost_per_kilometer": 48.12,
        "model.vehicles.cost_per_hour": 28.966666666666665
      },
      "routeTotalCost": 77.086666666666659
    }
  ],
  "metrics": {
    "aggregatedRouteMetrics": {
      "performedShipmentCount": 3,
      "travelDuration": "1407s",
      "waitDuration": "0s",
      "delayDuration": "0s",
      "breakDuration": "0s",
      "visitDuration": "1200s",
      "totalDuration": "2607s",
      "travelDistanceMeters": 4812,
      "maxLoads": {
        "weightKg": {
          "amount": "80"
        }
      }
    },
    "usedVehicleCount": 1,
    "earliestVehicleStartTime": "2023-01-13T16:00:00Z",
    "latestVehicleEndTime": "2023-01-13T16:43:27Z",
    "totalCost": 77.086666666666659,
    "costs": {
      "model.vehicles.cost_per_hour": 28.966666666666665,
      "model.vehicles.cost_per_kilometer": 48.12
    }
  }
}
    

I vincoli di carico aggiunti influiscono sull'ordine di visits:

  1. shipment[0] è stato ritirato
  2. shipment[1] è stato ritirato
  3. Il numero shipment[0] è stato consegnato
  4. Il numero shipment[1] è stato consegnato
  5. shipment[2] è stato ritirato
  6. Il numero shipment[2] è stato consegnato

Questo ordine indica che il veicolo non può effettuare tre spedizioni al momento contemporaneamente perché il loro totale di loadDemands supera la loadLimits.

Ogni voce visits include la modifica del carico del veicolo risultante dalle completamento di Visit. I valori di caricamento positivi rappresentano il caricamento della spedizione durante I valori negativi rappresentano l'unload della spedizione.

Ogni voce transitions include il carico totale del veicolo durante la Transition. transitions[2], ad esempio, ha un carico weightKg pari a 60, che rappresentano i caricamenti combinati di shipment[0] e shipment[1].

Gli oggetti delle metriche routes[0].metrics e metrics.aggregatedRouteMetrics includono una proprietà maxLoads. Il valore del tipo weightKg è 80, che rappresenta la parte del percorso del veicolo che ha trasportato shipments[2] al suo località di consegna.

Vincoli del limite di carico flessibile

Come per le finestre temporali descritte nella sezione Tempi di ritiro e consegna I vincoli e i limiti di carico hanno varianti fisse e rigide. La La proprietà maxLoad del messaggio LoadLimit esprime un vincolo rigido: il veicolo non deve mai portare un carico superiore al valore maxLoad nel di testo. Le proprietà softMaxLoad e costPerUnitAboveSoftMax esprimono un soft vincolo, in cui ogni unità che supera softMaxLoad comporta Costo di costPerUnitAboveSoftMax.

I vincoli del limite di carico temporaneo hanno diversi utilizzi, ad esempio:

  • bilanciare le spedizioni tra più veicoli rispetto al numero minimo necessario quando ciò è conveniente.
  • manifestare la preferenza del conducente per il numero di oggetti che può facilmente ritiro e consegna lungo un determinato percorso
  • Caricando veicoli al di sotto della loro capacità fisica massima per limitare l'usura e Ridurre i costi di manutenzione

I vincoli dei limiti di carico hard e soft possono essere utilizzati insieme. Ad esempio, un disco può esprimere il peso massimo del carico che un veicolo può trasportare in sicurezza o il numero massimo di articoli che possono trovarsi in un veicolo contemporaneamente, mentre il limite di carico flessibile potrebbe essere il peso o il numero massimo di articoli che la capacità del conducente di inserire tutto nel veicolo.