Modelar a lógica de negócios com atributos de transição

Este guia mostra os possíveis usos dos atributos de transição. Ele ensina como modelar cenários reais em dois exemplos: incorporar o tempo para estacionar o veículo nas rotas otimizadas e garantir que cada rota termine com uma visita a um local específico.

Antes de começar

Use atributos de transição para adicionar custos e atrasos específicos do modelo a determinadas transições nas rotas otimizadas. Esses custos e atrasos são adicionados às durações e aos custos de transição calculados com base nos dados do mapa e nos parâmetros do veículo usado.

Uma transição é o segmento da rota que conecta um local ao próximo.

Um local se refere a qualquer um dos seguintes pontos no trajeto de um veículo:

  • O ponto de partida do trajeto.
  • Uma parada em que uma retirada ou entrega é feita.
  • O ponto final do trajeto.

Para definir todos os atributos de transição do modelo, adicione-os à lista ShipmentModel.transition_attributes. Cada elemento da lista define um conjunto de atributos de transição e é combinado com transições nas rotas usando tags no local de início e no local de término da transição. Para saber mais sobre os atributos de transição, consulte a documentação de referência para TransitionAttributes.

Modelar cenários reais

Esta seção mostra dois pequenos exemplos de como implementar restrições de negócios reais usando atributos de transição.

Reservar horário para estacionamento

Nesse cenário, o motorista precisa estacionar o veículo antes de visitar o local A. O local B fica próximo, e o motorista pode usar a mesma vaga de estacionamento para as duas visitas. Se o motorista visitar B logo após A, ele vai economizar tempo porque não precisará sair da vaga de estacionamento e estacionar o veículo novamente. Na API Route Optimization, é possível usar atributos de transição para adicionar tempo extra para estacionar o veículo somente quando o motorista se move de uma vaga de estacionamento para outra.

Ao modelar o tempo de estacionamento separadamente das durações das visitas, você faz com que as rotas em que as visitas que usam o mesmo estacionamento são agrupadas levem menos tempo. Você torna o modelo mais preciso e também faz com que o otimizador prefira rotas em que as visitas são agrupadas.

Siga estas etapas para fazer isso em uma solicitação da API Route Optimization:

  1. Use VisitRequest.duration apenas pelo tempo necessário para realizar a visita. Por exemplo, para entregar o pacote e coletar uma assinatura do cliente.

  2. Para cada vaga de estacionamento distinta usada no modelo, use uma nova tag que não seja usada para mais nada no modelo, por exemplo, PARKING_123.

  3. Adicione esta tag ao seguinte:

    1. VisitRequest.tags em todas as solicitações de visita que usam essa vaga de estacionamento.

    2. Vehicle.start_tags se o veículo iniciar o trajeto nessa vaga de estacionamento.

    3. Vehicle.end_tags se o veículo iniciar ou encerrar o trajeto nessa vaga de estacionamento.

  4. Para cada nova tag de estacionamento, adicione uma entrada a ShipmentModel.transition_attributes que adicione um atraso para estacionar ao vir de uma vaga diferente. Para isso, faça o seguinte:

    1. Defina TransitionAttributes.excluded_src_tag e TransitionAttributes.dst_tag como PARKING_123.

    2. Defina TransitionAttributes.delay como o tempo necessário para estacionar o veículo.

    Por exemplo, quando a tag de um local é PARKING_123 e leva 150 segundos para estacionar o veículo, adicione a seguinte entrada a ShipmentModel.transition_attributes:

    {
      "excluded_src_tag": "PARKING_123",
      "dst_tag": "PARKING_123",
      "delay": "150s"
    }
    

Limpeza obrigatória no final do trajeto

Nesse cenário, o veículo precisa ser limpo no final do trajeto, com as seguintes restrições adicionais:

  • A limpeza é feita em uma instalação especializada antes de retornar ao depósito de veículos. A rota otimizada usa a melhor instalação de limpeza com base na localização dela e nos locais das coletas e entregas feitas pelo veículo.
  • Após a limpeza, o veículo não pode realizar outras retiradas ou entregas.
  • O tempo para dirigir até lá e limpar o veículo conta como horas de trabalho do motorista e precisa se encaixar na duração máxima do trajeto.

Para modelar esse requisito, permita apenas rotas vazias ou em que a última visita seja a uma instalação de limpeza. Na API Route Optimization, você faz isso proibindo transições para o ponto de passagem final do trajeto de qualquer local, exceto da instalação de limpeza ou do ponto de partida do trajeto:

  1. Escolha duas novas tags que não sejam usadas em nenhum lugar do modelo, por exemplo, CLEANED e ROUTE_END. O primeiro é para locais em que o veículo está ou fica limpo, e o segundo é para o fim do trajeto.
  2. Para cada veículo, adicione uma nova remessa somente de entrega que represente a visita a uma instalação de limpeza com os seguintes atributos:
    1. Cada local de instalação de limpeza precisa ser representado como uma solicitação de visita de entrega dessa remessa.
    2. Adicione CLEANED ao VisitRequest.tags de cada solicitação de visita da remessa da instalação de limpeza. Isso indica que um veículo que sai desse local está limpo. Outras solicitações de visita no modelo não devem usar essa tag para que o veículo seja considerado "não limpo" ao sair delas.
    3. Permita que o otimizador pule essa remessa quando o veículo não estiver sendo usado, definindo o penalty_cost como um número pequeno.
  3. Para cada veículo, adicione CLEANED a Vehicle.start_tags. Isso é usado para marcar o veículo como limpo antes de realizar coletas ou entregas, supondo que ele tenha sido limpo no final do dia de trabalho anterior, e permitir que ele vá do ponto de passagem inicial diretamente para o ponto de passagem final. Mesmo que essas rotas não aconteçam na prática, permitir esse cenário ajuda o otimizador a procurar rotas otimizadas com mais eficiência.

  4. Para cada veículo, adicione ROUTE_END a Vehicle.end_tags.

  5. Adicione uma nova entrada a ShipmentModel.transition_attributes que proíba os veículos de chegar ao waypoint final quando eles não estiverem limpos, com as seguintes propriedades:

    1. Defina TransitionAttributes.excluded_src_tag como CLEANED.

    2. Defina TransitionAttributes.dst_tag como ROUTE_END.

    3. Defina TransitionAttributes.delay como um valor grande. Quando você define um atraso maior que a duração máxima da rota, o otimizador é proibido de usar essa transição em uma rota.

    Por exemplo, quando a escala de tempo do modelo é de um dia útil, é possível usar um atraso de 24 horas (86.400 segundos) para proibir a transição para o fim do trajeto de qualquer lugar, exceto de uma instalação de limpeza e do início do trajeto:

    {
      "excluded_src_tag": "CLEANED",
      "dst_tag": "ROUTE_END",
      "delay": "86400s"
    }
    

Como escolher entre atrasos e custos

A escolha entre atrasos e custos depende da natureza da lógica de negócios e das restrições implementadas. Definir TransitionAttributes.delay é melhor para implementar restrições rígidas ou expressar uma compensação em termos de tempo gasto. TransitionAttributes.cost é mais adequado ao implementar preferências flexíveis ou compensações expressas como um custo adicional. É possível combinar atrasos e custos de forma arbitrária quando o tempo gasto e o custo são importantes.

O exemplo de limpeza de veículo usa um atraso muito longo, porque limpar o veículo no final do trajeto é um requisito rígido, e o atraso longo impede que o otimizador ignore o requisito. Se você definir apenas um custo, o otimizador poderá optar por pular a limpeza se encontrar uma maneira de compensar o custo em outro lugar, por exemplo, entregando mais remessas no tempo "economizado" por não limpar o veículo.

O exemplo de estacionamento usa um pequeno atraso que corresponde ao tempo extra necessário para estacionar o veículo. Também é possível usar custos em combinação com atrasos, se o motorista parar em um estacionamento pago.

Como adicionar um atributo de transição que corresponda a todas as solicitações de visita

Os exemplos acima usam atributos de transição que correspondem a locais que têm uma determinada tag ou que não têm a tag. Mas e se você precisar adicionar atributos de transição que se aplicam a todas as transições?

Não é possível omitir as tags, porque cada mensagem TransitionAttributes precisa ter um de TransitionAttributes.src_tag e TransitionAttributes.excluded_src_tag e um de TransitionAttributes.dst_tag e TransitionAttributes.excluded_dst_tag.

No entanto, é possível corresponder todas as tags definindo TransitionAttributes.excluded_src_tag ou TransitionAttributes.excluded_dst_tag como uma tag que não é usada em nenhum lugar do modelo. Isso vai corresponder a todos os locais que não têm essa tag, mas como você escolheu intencionalmente uma tag que não é usada por nenhum local, esses atributos de transição vão corresponder a todos os locais.

Leitura adicional