En este documento, se muestra cómo realizar tu primera solicitud a la API de Route Optimization con una situación de caso de uso real.
Para simplificar, en el ejemplo se usan HTTP y JSON para demostrar la API de REST. Sin embargo, para tu entorno de producción, la recomendación general es usar gRPC por sus beneficios de rendimiento. Sin embargo, gRPC requiere cierta instalación. Para obtener más información, consulta las bibliotecas cliente de la API de Route Optimization.
Situación
Tienes una guardería para perros en San Francisco que funciona de 7 a.m. a 7 p.m. Esta mañana, quieres recoger a tres perros de diferentes ubicaciones de la ciudad y llevarlos a tu guardería.
El boyero de Berna y el chihuahua son clientes habituales que reservaron sus citas la semana pasada. El pastor alemán es una solicitud nueva de último momento. Quieres hacerle un lugar al pastor alemán si es posible, pero no a expensas de tus clientes habituales.
Tienes una camioneta para el trabajo y le pagas al conductor $27 por hora. El conductor y la camioneta comienzan el día en tu guardería a las 7:00 a.m. y deben regresar de las recogidas de la mañana antes del mediodía para tomar un descanso para almorzar.
Hoy es 13 de febrero de 2024. Todas las horas de esta situación corresponden a la hora local de San Francisco, que es la hora estándar del Pacífico (UTC-8) en febrero. El conductor tiene las siguientes tareas:
- Recoge al boyero de Berna cerca de la Torre Coit. El propietario solicitó un intervalo de retiro acotado entre las 8:00 a.m. y las 8:20 a.m.
- Recoge al chihuahua en el South Sunset Playground Park. El propietario ofreció un horario de retiro más flexible, entre las 7:30 a.m. y las 9:30 a.m.
- Recoge al pastor alemán en Land's End. El propietario también solicitó un período de retiro estricto entre las 8:00 a.m. y las 8:20 a.m.
- Deja a los perros en la guardería del parque Mission Dolores. La guardería requiere que se deje a los niños entre las 9:30 a.m. y las 11:30 a.m.
Cada visita de retiro y entrega tarda 5 minutos en cargar o descargar al perro.
Debido a que Land's End está lejos de Coit Tower y sus ventanas de retiro entran en conflicto, el conductor no puede realizar los tres retiros. El optimizador debe elegir qué perro omitir para minimizar el costo total (salarios de los conductores y cualquier penalización por omisión).
Antes de comenzar
Para ejecutar el código de esta situación de ejemplo, primero debes completar las instrucciones que se indican en Configura la API de Route Optimization.
1. Elige tu enfoque de optimización de rutas
La API de Route Optimization tiene varios métodos para que elijas según la complejidad de tu problema de optimización.
Debido a que esta situación de guardería para perros es una solicitud pequeña y directa, usa
un método de bloqueo, como optimizeTours, que entrega resultados con rapidez
para solicitudes pequeñas. Para obtener más información sobre los endpoints de la API de Route Optimization, consulta Elige un endpoint.
Usa la siguiente URL para realizar una solicitud POST HTTP al método optimizeTours:
https://routeoptimization.googleapis.com/v1/projects/PROJECT_OR_ID:optimizeTours
También debes configurar los parámetros de configuración de tiempo de espera y fecha límite para que sean cortos y, así, reducir cualquier tiempo de espera innecesario. Para esta situación de guardería de perros, el optimizador no necesita mucho tiempo para responder a tu solicitud, por lo que debes usar la siguiente configuración:
- Establece el parámetro
timeouten 2 segundos. - Deja la configuración del plazo en el valor predeterminado, que es de 60 segundos para las solicitudes de REST.
2. Crea el cuerpo del mensaje de solicitud
Después de elegir el método optimizeTours de bloqueo y definir la configuración de tiempo de espera y plazo, el siguiente paso es construir el cuerpo del mensaje de solicitud.
En este caso, la solicitud es un mensaje OptimizeToursRequest
codificado como JSON en la API de REST.
Para construir el mensaje de solicitud, sigue estos pasos:
Comienza con la estructura básica de la solicitud, que es la siguiente:
{ "timeout": ..., "model": { "shipments": [...], "vehicles": [...], "globalStartTime": "...", "globalEndTime": "..." } }Para obtener más información sobre la estructura, consulta la guía de conceptos clave de la estructura base (ShipmentModel, Shipment y Vehicle).
Define los envíos. En el campo
shipments, agrega un mensajeShipmentpara cada perro que se deba recoger y dejar por la mañana. Aquí es donde defines la ubicación y los horarios de retiro preferidos de cada propietario de perro, y la ubicación y los horarios de la guardería para dejar a los perros.Para cada perro, crea un
VisitRequestpara las recogidas y otro para las entregas, que, en este caso, se denomina entrega en la guardería.En las recogidas, establece el
arrivalWaypointen la ubicación de recogida del perro (Coit Tower para el boyero de Berna, South Sunset Playground Park para el chihuahua o Land's End para el pastor alemán). Establece eltimeWindowsen la hora de partida solicitada por el propietario (de 8:00 a.m. a 8:20 a.m. para el boyero de Berna y el pastor alemán, y de 7:30 a.m. a 9:30 a.m. para el chihuahua).En las entregas, establece el
arrivalWaypointen la guardería y eltimeWindowspara la hora de llegada requerida (de 9:30 a.m. a 11:30 a.m.).Para todas las recogidas y entregas, establece el
durationen 5 minutos (300s) para tener en cuenta la carga y descarga de los perros.
Para obtener más información sobre las ventanas de tiempo, consulta Ventanas de tiempo.
Para priorizar a los clientes habituales, establece el
penaltyCosten1000para el boyero de Berna y el chihuahua, y en100para el pastor alemán. Con los costos de penalización establecidos, el optimizador puede omitir cualquiera de los perros, pero considera omitir primero al pastor alemán (que tiene una penalización más baja) si las restricciones imposibilitan realizar todas las recogidas.Puedes usar el campo
labelpara agregar un identificador para cada envío, como "Boyero de Berna", "Chihuahua" y "Pastor alemán". Esto puede ayudarte a identificar los envíos en la respuesta.
Para obtener más información sobre cómo definir los envíos, consulta Envío.
Define los vehículos. En el campo
vehicles, agrega un mensajeVehiclepara tu camioneta con la guardería como punto de partida y de llegada, el costo del salario del conductor y el horario de atención de la camioneta.Establece
startWaypointyendWaypointpara la camioneta en las ubicaciones de inicio y finalización del día, que es la guardería cerca de Mission Dolores Park.Para minimizar los costos de operación, debes definir las restricciones de costos de tu empresa. Establece el parámetro de costo
costPerHouren27, que es el importe que le pagas al conductor por conducir la camioneta de la guardería para perros. Para obtener más información sobre los parámetros de costo, consulta Modelo de costos.Para asegurarte de que el optimizador cree una ruta dentro del horario de atención de la camioneta, define un período de operación para el vehículo. Esta ventana establece las restricciones de hora de inicio y finalización de la ruta. Si defines solo una mitad de cada ventana de tiempo, le darás flexibilidad al optimizador para comenzar la ruta más tarde o finalizarla antes:
Establecer
startTimeenstartTimeWindowsen las 7 a.m. significa que el conductor puede comenzar su turno a partir de las 7 a.m. También puede comenzar más tarde si no hay retiros temprano por la mañana.Si configuras
endTimeenendTimeWindowspara el mediodía, el conductor debe finalizar su turno antes del mediodía. También pueden finalizar su turno en cuanto completen la última entrega.
Omitir la otra mitad de las ventanas minimiza los tiempos de espera y desvío del conductor. Para obtener más información sobre las ventanas de tiempo, consulta Ventanas de tiempo.
Para obtener más información sobre cómo definir vehículos, consulta Vehículo.
Establece un período global. La ventana de tiempo global representa el período en el que la camioneta puede realizar retiros y entregas para tu guardería durante el día. En esta situación, establece
globalStartTimeen las 7 a.m. yglobalEndTimeen las 7 p.m. para el 13 de febrero de 2024, que representan el horario de atención de la guardería para perros.
3. Envía la solicitud
A continuación, se muestra una solicitud curl simple basada en la situación de la guardería de perros y
usa el método optimizeTours de bloqueo.
Antes de enviar la solicitud, reemplaza PROJECT_NUMBER_OR_ID en el código de muestra por tu ID del proyecto de Google Cloud.
curl -X POST 'https://routeoptimization.googleapis.com/v1/projects/PROJECT_NUMBER_OR_ID:optimizeTours' \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $(gcloud auth application-default print-access-token)" \
--data @- << EOM
{
"timeout": "2s",
"model": {
"shipments": [
{
"pickups": [
{
"arrivalWaypoint": {
"location": {
"latLng": {
"latitude": 37.802395,
"longitude": -122.405822
}
}
},
"timeWindows": [
{
"startTime": "2024-02-13T08:00:00-08:00",
"endTime": "2024-02-13T08:20:00-08:00"
}
],
"duration": "300s"
}
],
"deliveries": [
{
"arrivalWaypoint": {
"location": {
"latLng": {
"latitude": 37.759719,
"longitude": -122.42798
}
}
},
"timeWindows": [
{
"startTime": "2024-02-13T09:30:00-08:00",
"endTime": "2024-02-13T11:30:00-08:00"
}
],
"duration": "300s"
}
],
"label": "Bernese mountain dog",
"penaltyCost": 1000
},
{
"pickups": [
{
"arrivalWaypoint": {
"location": {
"latLng": {
"latitude": 37.738067,
"longitude": -122.498593
}
}
},
"timeWindows": [
{
"startTime": "2024-02-13T07:30:00-08:00",
"endTime": "2024-02-13T09:30:00-08:00"
}
],
"duration": "300s"
}
],
"deliveries": [
{
"arrivalWaypoint": {
"location": {
"latLng": {
"latitude": 37.759719,
"longitude": -122.42798
}
}
},
"timeWindows": [
{
"startTime": "2024-02-13T09:30:00-08:00",
"endTime": "2024-02-13T11:30:00-08:00"
}
],
"duration": "300s"
}
],
"label": "Chihuahua",
"penaltyCost": 1000
},
{
"pickups": [
{
"arrivalWaypoint": {
"location": {
"latLng": {
"latitude": 37.78018,
"longitude": -122.51194
}
}
},
"timeWindows": [
{
"startTime": "2024-02-13T08:00:00-08:00",
"endTime": "2024-02-13T08:20:00-08:00"
}
],
"duration": "300s"
}
],
"deliveries": [
{
"arrivalWaypoint": {
"location": {
"latLng": {
"latitude": 37.759719,
"longitude": -122.42798
}
}
},
"timeWindows": [
{
"startTime": "2024-02-13T09:30:00-08:00",
"endTime": "2024-02-13T11:30:00-08:00"
}
],
"duration": "300s"
}
],
"label": "German shepherd",
"penaltyCost": 100
}
],
"vehicles": [
{
"startWaypoint": {
"location": {
"latLng": {
"latitude": 37.759719,
"longitude": -122.42798
}
}
},
"endWaypoint": {
"location": {
"latLng": {
"latitude": 37.759719,
"longitude": -122.42798
}
}
},
"costPerHour": 27,
"startTimeWindows": [
{
"startTime": "2024-02-13T07:00:00-08:00"
}
],
"endTimeWindows": [
{
"endTime": "2024-02-13T12:00:00-08:00"
}
]
}
],
"globalStartTime": "2024-02-13T07:00:00-08:00",
"globalEndTime": "2024-02-13T19:00:00-08:00"
}
}
EOM
Parámetros de solicitud que se usan en la solicitud
En la siguiente tabla, se describen los parámetros de solicitud que se usan en el cuerpo de la solicitud del caso de ejemplo. Puedes filtrar el contenido por elemento superior o por búsqueda de texto.
| Padres | Parámetro | Tipo de propiedad | Descripción |
|---|---|---|---|
OptimizeToursRequest |
model |
objeto (ShipmentModel) |
Esta es la parte central de tu solicitud. Es un objeto único en el que
defines todo el problema, incluidos todos los perros que debes recoger y
dejar (shipments)
y la camioneta de tu flota
(vehicles).
Piensa en él como el plano completo del problema que necesitas optimizar. |
timeout |
Duración | Este parámetro especifica el tiempo máximo que el servidor trabaja en una solicitud antes de devolver una respuesta. Usa este parámetro para acortar el tiempo de espera. Para solicitudes pequeñas y rápidas, como en este caso de la guardería de perros, establece este valor en 2s. | |
ShipmentModel |
shipments[] |
array de objetos (Shipment) |
Este es un array de objetos en el que cada objeto representa un perro que se debe recoger o dejar. |
vehicles[] |
array de objetos (Vehicle) |
Este es un array de objetos en el que cada objeto define un vehículo de tu flota. Aquí es donde describes tus recursos, como la camioneta que realiza las recogidas y entregas. Debes definir al menos un vehículo para obtener una ruta optimizada. | |
globalStartTime |
Marca de tiempo | Esta es la hora más temprana posible para que ocurra cualquier evento en todo tu modelo. Este parámetro reduce el problema de optimización en el tiempo, lo que es fundamental para realizar cálculos precisos de tráfico y rutas. En este caso de guardería para perros, establece este valor en la hora más temprana en la que el conductor puede operar la camioneta durante el día, que es a las 7 a.m. del 13 de febrero de 2024. | |
globalEndTime |
Marca de tiempo | Esta es la hora más tardía posible para que ocurra cualquier evento en todo el modelo. En este caso de guardería para perros, configúrala para cuando se espera que la camioneta finalice su operación, que es a las 7 p.m. del 13 de febrero de 2024. | |
Shipment |
pickups[] |
array de objetos (VisitRequest) |
Esta es una lista de todas las opciones de retiro posibles para el envío. El optimizador elige el mejor para resolver tu problema. Para esta situación de guardería de perros, enumera las ubicaciones de retiro y los períodos que cada propietario proporcionó para cada perro. |
deliveries[] |
array de objetos (VisitRequest) |
Esta es una lista de todas las opciones de entrega posibles para el envío. El optimizador elige el mejor para resolver tu problema. En este caso de guardería para perros, indica la ubicación de la guardería y el período en el que el conductor debe regresar para almorzar para cada perro. | |
label |
string | Es un identificador de un envío específico de tu solicitud. Puedes especificar etiquetas en tu solicitud para que sea más fácil leer la respuesta. Para este caso de guardería de perros, usa una cadena descriptiva como "Chihuahua", "Boyero de Berna" o el nombre del perro para que la solución coincida con tu entrada cuando recibas la respuesta de la API. | |
penaltyCost |
doble | Este es el costo de penalización en el que se incurre si el optimizador omite este envío. De forma predeterminada, los envíos son obligatorios: el optimizador prioriza minimizar los envíos obligatorios omitidos y los omite solo cuando no hay otra opción. Establecer un costo de penalización permite que el optimizador omita un envío si no es factible o es demasiado costoso realizarlo, y te permite sopesar las prioridades entre los envíos. En esta situación, estableces un costo de penalización más alto (1000) para tus clientes habituales (boyero de Berna y chihuahua) y un costo de penalización más bajo (100) para la solicitud de último momento del pastor alemán. Esto le indica al optimizador que priorice a los clientes habituales, por lo que considera omitir al pastor alemán primero cuando no puede realizar todas las recogidas. |
|
VisitRequest |
arrivalWaypoint |
objeto (Waypoint) |
Esta es la ubicación de una visita específica en la ruta. Puedes definirla con coordenadas de latitud y longitud, un ID de lugar o un rumbo. En
este caso de la guardería para perros, establece este valor en la ubicación que proporcionó el propietario para
pickups
y en la dirección de la guardería para
deliveries. |
timeWindows[] |
array de objetos (TimeWindow) |
Es un array de objetos que definen las restricciones de tiempo para un retiro o una entrega. En este caso, usa este parámetro para definir el período de retiro de cada perro y el período aceptable para dejarlos en la guardería. | |
duration |
Duración | Este parámetro especifica la duración de la visita (p.ej., el tiempo de carga o descarga). En esta situación, estableces un margen de 5 minutos (300s) para todas las recogidas y entregas, de modo que se tenga en cuenta el tiempo que tarda el conductor en subir y bajar a los perros. |
|
Vehicle |
startWaypoint |
objeto (Waypoint) |
Es la ubicación de partida de la ruta del vehículo, definida con coordenadas de latitud y longitud, o un ID de lugar. Este parámetro le indica al optimizador dónde debe comenzar la ruta el vehículo. Si no defines este punto de referencia, el optimizador elegirá uno de los puntos de retiro o entrega como ubicación de partida. En este caso de guardería para perros, como el conductor comienza el día en la guardería, usa las coordenadas del parque Mission Dolores. |
endWaypoint |
objeto (Waypoint) |
Es el destino final de la ruta del vehículo, definido con coordenadas de latitud y longitud, o un ID de lugar. Este parámetro le indica al optimizador dónde debe finalizar la ruta el vehículo. Si no defines este punto de referencia, el optimizador elegirá una de las recogidas o entregas como el final de la ruta. En este caso de la guardería para perros, como el conductor debe terminar el día en la guardería, usa las coordenadas de Mission Dolores Park. | |
costPerHour |
número | Es el costo que se genera por cada hora que se usa un vehículo, sin importar si está en movimiento o detenido. Para este caso de guardería de perros, usa esto para modelar el salario por hora de un conductor. | |
startTimeWindows[] |
array de objetos (TimeWindow) |
Este es el período aceptable para que el conductor comience su
turno. Para este caso de guardería de perros, define startTime como las 7 a.m., pero omite endTime. Esto permite que el optimizador retrase el inicio del turno si la primera recolección es más tarde en la mañana. Ten en cuenta que, incluso si no proporcionas un endTime para startTimeWindows, la hora de inicio está limitada de forma implícita por el endTimeWindows. El vehículo debe
comenzar la ruta antes de que esta finalice. |
|
endTimeWindows[] |
array de objetos (TimeWindow) |
Este es el período aceptable para que el conductor finalice la ruta.
Para este caso de uso de guardería de perros, define el endTime como el mediodía, pero omite el startTime. Esto permite que el conductor regrese a la guardería
inmediatamente después de la última parada. |