Logística da ação para coleta seletiva de materiais recicláveis

Em vez de se juntar


Quando os processos de coleta e processamento de resíduos estão totalmente ajustados na Rússia, não é fácil dizer, mas quero não participar da reposição de aterros sanitários agora. Portanto, em muitas cidades grandes, de uma maneira ou de outra, existem movimentos voluntários envolvidos em uma coleta separada particular.

Em Novosibirsk, essa atividade é formada em torno da campanha Esquilo Verde, na qual uma vez por mês as pessoas da cidade ambiental trazem lixo doméstico reciclável acumulado para locais predeterminados em um determinado momento. Ao mesmo tempo, chega um caminhão alugado, que leva os materiais recicláveis ​​coletados e classificados para o local, de onde é redistribuído entre várias empresas de processamento. A ação existe desde 2014 e, desde então, o número de pontos de coleta de recicláveis, bem como seus volumes, aumentou significativamente. Para o roteamento de caminhões, apenas um olhar não era suficiente e começamos a desenvolver modelos de otimização para minimizar os custos de transporte. O primeiro desses modelos é o assunto deste artigo.

Na seção 1, descreverei em detalhes e com ilustrações o esquema para organizar a ação. Além disso, na Seção 2, a tarefa de minimizar os custos de transporte será formalizada como a tarefa de rotear veículos heterogêneos com problemas de roteamento de veículos da frota com janelas de tempo. A Seção 3 é dedicada à solução desse problema usando um pacote distribuído gratuitamente para solucionar problemas de programação matemática linear inteira mista GLPK.

1. A ação "esquilo verde"


Desde 2014, o grupo de iniciativa Living Earth realiza uma campanha mensal para separar a coleção de esquilo verde reciclado em Novosibirsk. No momento da redação deste artigo, a reciclagem com várias reservas é aceita como lixo plástico rotulado como PET, PE, PP, PS, vidro, alumínio, ferro, eletrodomésticos, papel usado e muito mais. Mais de 50 voluntários participam da preparação e condução da ação. A ação não é comercial, a participação é gratuita e não implica recompensa monetária.

Pontos

A ação é realizada em 17 pontos da cidade, localizados entre si a distâncias percorridas pelo carro em um período de 15 a 90 minutos. Um desses pontos na foto: bolsas à esquerda ao longo da parede para coletar várias frações de plástico, à direita - um caminhão, no qual tudo será carregado no futuro, e no centro - um voluntário com ouvidos.

imagem

Todas as atividades no momento são organizadas por curadores que têm restrições no horário em que estão prontos para cumprir suas funções. Ao planejar uma ação, os curadores relatam o intervalo de tempo dentro do qual a ação deve passar no momento.

Há também dados sobre os volumes médios de recicláveis ​​coletados em cada ponto.

Rotas

Os pontos são organizados em rotas que são conduzidas sucessivamente por um caminhão. Os movimentos do caminhão são monitorados pelos supervisores de rota que monitoram o ambiente operacional e tomam decisões sobre o manuseio de eventos especiais.

imagem

Caminhões

São alugados de maneira comum no âmbito de propostas de aluguel por hora de veículos de carga. Não é possível compactar o plástico no local, portanto, o principal parâmetro que caracteriza o caminhão é o volume da carroceria. A capacidade de carga no nosso caso não é um fator limitante.

Os principais gastos da ação estão relacionados ao pagamento do aluguel de caminhões, portanto, sua redução é fundamental para a existência e desenvolvimento de nossa participação, que adquire importância institucional no sentido de formar idéias sobre consumo responsável. A seguir, será descrita uma abordagem para resolver esse problema, com base na aplicação de métodos discretos de otimização, a saber, programação matemática.

2. Formalização


Ao construir o modelo matemático, permaneceremos dentro da estrutura de programas lineares inteiros mistos, para os quais é suficiente o conhecimento da álgebra da classe 7.

A única dificuldade pode ser associada ao uso de sinais abstratos de notação e soma em fórmulas. Espero que isso não afaste os leitores que têm encontros pouco frequentes com textos matemáticos.

No modelo de otimização, quatro componentes podem ser distinguidos:

  • a formação de grupos de pontos que compõem uma rota separada;
  • definição de um circuito para cada um dos grupos;
  • atender aos requisitos para a hora de chegada do caminhão em cada ponto;
  • determinação do tipo de caminhão necessário para atender a cada uma das rotas.

Consideramos cada uma das partes, introduzindo a notação necessária conforme necessário.

Agrupamento de pontos

Vamos V = \ {1, \ pontos, n \} existem muitos índices de pontos de coleta de materiais recicláveis, e o local onde os materiais recicláveis ​​são transportados - vamos chamá-lo de depósito - tem um índice de 0. Coloque \ bar {V} = V \ xícara \ {0 \}

Cada grupo de pontos forma uma rota separada. Através de Rdenotar o conjunto de números de rota.

Deixe a quantidade zir,i inI,r inRé igual a um se o ponto iincluído na rota com o número re zero caso contrário. Então a exigência de que o ponto i emVdeve entrar em uma das rotas pode ser escrito como

 sumr inRzir=zi1+zi2+ pontos+zin=1.


O depósito deve inserir todas as rotas: z0r=1,r emR

Sutilezas
Infelizmente, esse registro cria problemas computacionais associados à simetria da região admissível. Isso pode ser eliminado com a adição de várias restrições, garantindo a escolha da decomposição lexicograficamente mínima. Você pode ler mais sobre isso em russo, por exemplo, aqui .

1zir leq sumj=1i1 left(1 sumk=1r1zjk right)+ sumk=1r1zik, quadi emI,r emR,r leqi.



Definição de desvio

As rotas são uma sequência alternada de pontos e cruzamentos entre elas. Formalmente, todos começam em um dos pontos do conjunto Ve terminar no depósito, no entanto, será mais fácil assumir que todas as rotas são cíclicas. Essa suposição não muda a essência, mas torna todos os vértices iguais: nesse caso, não há vértices finais, todos são de trânsito.

Por pontos i,j in barVe rota R $ em R $ configurar uma variável xijrigual a um se na rota com número rcaminhão se movendo do ponto idireto ao ponto je zero caso contrário.

Então exigimos, em primeiro lugar, que o caminhão se mova ao longo da rota R $ em R $ visitou o ponto i emVse ela, depois de se dividir em grupos, pertencer ao grupo com o número r:

 sumj in barVxjir=zir, quadi in barV,r emR.


Em segundo lugar, o caminhão depois de chegar ao ponto i in barVdeve deixá-la.

 sumj in barVxjir= sumj in barVxijr, quadi in barV,r emR.



Você pode perceber que essas restrições permitem que as quantidades xijrDefina rotas que são um conjunto de loops disjuntos. É claro que rotas desse tipo não fazem sentido e são necessárias várias restrições para evitar isso.

Sobre como eliminar sub-motocicletas
Uma maneira poderia ser a introdução de quantidades não negativas auxiliares fijr,i,j in barV,r emRO conjunto de relações registradas usando essas quantidades elimina combinações de valores xijrdefinindo rotas que não são um loop conectado.

 sumi inVf0jr= sumi inVzir, quadr inR,


fijr leqnxijr, quadi in barV,j in barV,r inR,


 sumj in barVfjir= sumj in barVfijr+zir, quadi inV,r inR.


Essas proporções especificam o fluxo do depósito para o restante dos pontos da rota. Em cada ponto intermediário, uma unidade de fluxo é absorvida; portanto, para que a rede tenha um fluxo de energia igual ao número de pontos menos um, é necessário que a rota seja conectada.

Satisfazer os requisitos no momento da chegada do caminhão em cada ponto

Em outras palavras, você precisa visitar pontos apenas dentro das janelas de tempo indicadas pelos curadores. Através de Bie Eidenotam, respectivamente, o início e o fim do intervalo de tempo em que o curador do ponto ipode participar.

Para acompanhar a implementação dessas restrições, precisamos de informações sobre o tempo gasto pelo caminhão durante paradas e travessias na rota. Através de Li,i inVdenotar a duração do carregamento no ponto ie através Dij,i,j in barV- tempo de mudança de um ponto idireto ao ponto jFazemos uma reserva que D0i=0para todos i in barVe geralmente pode ser executado Dij neqDjipara qualquer i neqj

Introduzimos variáveis ​​não negativas ai,i in barVe wir,i in barV,r emRigual aos tempos de chegada e de espera no ponto iao dirigir por uma rota r, respectivamente. Para os valores inseridos, as seguintes relações devem ser satisfeitas.

O tempo de espera não pode ser menor que o tempo necessário para carregar

wir geqLizir, quadi in barV,r emR,


e igual a zero se o ponto não pertencer à rota r

wir leqMzir, quadi in barV,r emR,


Hora de chegada ao ponto jcalculado em momentos apropriados para o ponto anterior iAqui está uma constante bastante grande Musado para eliminar dependências desnecessárias ao mover-se entre ie jnão feito.

ai+ sumr inRwir+Dij leqaj+M(1 sumr inRxijr), quadi inI,j emV,


A chegada e partida do caminhão deve estar dentro do intervalo indicado pelo curador.

ai geqBi, quadi emV,


ai+ sumr inRwir leqEi, quadi emV.


Determinando o tipo de caminhão necessário para atender a cada rota
Indique os vários tipos de caminhões disponíveis para aluguel por TTipo de caminhão t emTcaracterizado pelo volume corporal Cte o custo do aluguel de uma hora PtTempo mínimo de aluguel de caminhão tdenotado por Ut0A quantidade de recicláveis ​​coletados no ponto i emVdenotado por Gi

Introduzimos variáveis ytr,t emT,r emRigual a um se tipo de caminhão tatribuído à rota de serviço com o número re zero caso contrário.

Variáveis ​​inteiras utr,t emT,r emRdefinir a hora de alugar um tipo de caminhão tservindo a rota com número r
Para cada rota, R $ em R $ , você deve atribuir o tipo de caminhão:

 sumt inTytr=1, quadr emR


De acordo com a divisão dos pontos entre as rotas, algumas rotas podem se tornar triviais, ou seja, conter apenas depósitos. Se a rota rnão trivial, o caminhão atribuído a ele é alugado pelo menos Ut0horas.

utr geqUt0(ytr sumi inVzir), quadt emT,r emR.


Ao mesmo tempo, a duração do contrato também deve exceder a duração total do estacionamento e da movimentação ao longo da rota.

utr geq sumi inV sumj in barVDijxijr+ sumi in barVwirM(1ytr), quadr emR,t emT.


Adicione restrições ao fornecimento da propriedade: se o caminhão for do tipo tnão atribuído a uma rota r, seu tempo de aluguel é zero.

utr leqMytr.


Todos os materiais recicláveis ​​coletados nos pontos de rota devem caber na parte traseira do caminhão.

 sumi inVGizir leq sumt inTCtytr, quadr emR.


Finalmente, nosso objetivo é minimizar o custo do aluguel de caminhões, que, usando as designações introduzidas, é escrito como  sumt inT sumr inRPtutr

Procure uma solução


É fácil verificar se todas as expressões envolvidas no modelo de otimização são funções lineares das variáveis; portanto, para encontrar soluções exatas e aproximadas, você pode usar pacotes padrão para resolver problemas de programação inteira mista, como Gurobi , CPLEX , Xpress , ORtools , SCIP , BLIS , etc.
Escrevemos um modelo para minimizar os custos de transporte na linguagem GMPL. Isso nos permitirá usar o pacote GLPK gratuito para nossos propósitos. Para escrever código e depurar o modelo, será conveniente fazer o download do ambiente de desenvolvimento do GUSEK , que já contém GLPK em sua composição.

O GUSEK fica assim:

imagem

À esquerda, vemos uma descrição do modelo e à direita há uma janela para exibir informações sobre o progresso do cálculo, que o solucionador fornecerá após o lançamento.

Descrição completa do modelo
param numOfPoints > 0, integer; #  param numOfTypes > 0, integer; #   param numOfRoutes = numOfPoints;#   set V := 1 .. numOfPoints; #  set Vbar := V union {0}; #     () set T := 1 .. numOfTypes; #   set R := 1 .. numOfPoints; #  ############### param WDL >= 0, default 8; #   param B{i in Vbar} >= 0; #   param E{i in Vbar} >= 0; #   param L{i in Vbar} >= 0; #   param D{i in Vbar, j in Vbar} >= 0, <= WDL; #  param G{i in V}, >= 0; # , 3 ########## param C{t in T}, >= 0; #  param P{t in T}, >= 0; #    param U0{t in T}, >= 0; #  ,  /********************************************** *    **********************************************/ var z{Vbar, R} binary; # ,     ,      st pointToGroup 'point to group' {i in V}: sum{r in R} z[i, r] == 1; st depotToGroup 'depot to group' {r in R}: z[0, r] == 1; st lexMinGroups 'lexicographycally minimal division' {i in V, r in R: r <= i}: 1 - z[i, r] <= sum{j in V: j <= i - 1}(1 - sum{k in R: k <= r - 1} z[j, k]) + sum{k in R: k <= r - 1}z[i, k] ; /********************************************** *    **********************************************/ var x{Vbar, Vbar, R} binary; # ,    c  r      i   j,   . st visitPoint 'visit point' {i in Vbar, r in R}: sum{j in Vbar} x[i, j, r] = z[i, r]; st keepMoving 'keep moving' {i in Vbar, r in R}: sum{j in Vbar} x[j, i, r] = sum {j in Vbar} x[i, j, r]; var f{Vbar, Vbar, R} >= 0; #,  . st flowFromDepot 'flow from depot' {r in R}: sum{i in V} f[0, i, r] == sum{i in V} z[i, r]; st flowAlongActiveArcs 'flow along active arcs' {i in Vbar, j in Vbar, r in R}: f[i, j, r] <= numOfPoints * x[i, j, r]; st flowConservation 'flow conservation' {i in V, r in R}: sum{j in Vbar} f[j, i, r] == sum{j in Vbar} f[i, j, r] + z[i, r]; var a{i in V} >= 0; #     var w{i in Vbar, r in R} >= 0; #     st wait 'wait'{i in Vbar, r in R}: w[i, r] >= L[i] * z[i, r]; st dontWait 'dont wait'{i in Vbar, r in R}: w[i, r] <= (E[i] - B[i]) * z[i, r]; st arrivalTime 'arrival time' {i in V, j in V}: a[i] + sum{r in R}w[i, r] + D[i,j] <= a[j] + 3 * WDL * (1 - sum{r in R} x[i, j, r]); st arriveAfter 'arrive after' {i in V}: a[i] >= B[i]; st departBefore 'depart before' {i in V}: a[i] + sum{r in R}w[i, r] <= E[i]; /********************************************** *   ,       **********************************************/ var y{t in T, r in R}, binary; # ,    t       r,   . var u{t in T, r in R}, integer, >= 0; #    t,     rst assignVehicle 'assign vehicle' {r in R}: sum{t in T} y[t,r] == 1; st rentTime 'rent time' {r in R, t in T}: u[t, r] >= sum{i in V, j in Vbar}D[i, j] * x[i, j, r] + sum{i in Vbar}w[i, r] - WDL * (1 - y[t, r]); st minRentTime 'minimal rent time' {r in R, t in T}: u[t, r] >= U0[t] * (y[t, r] - sum{i in V}z[i, r]); st noRent 'no rent' {t in T, r in R}: u[t, r] <= WDL * y[t, r]; st fitCapacity 'fit capacity' {r in R}: sum{i in V} G[i] * z[i, r] <= sum{t in T} C[t] * y[t, r]; minimize rentCost: sum{t in T, r in R} P[t] * u[t, r]; solve; /********************************************** *     **********************************************/ printf{i in V, r in R} (if 0.1 < z[i,r] then "point %s to group %s\n" else ""), i, r, z[i,r]; printf{r in R, i in Vbar, j in Vbar} (if 0.1 < x[i, j, r] then "route %s: %s -> %s\n" else ""), r, i, j; printf{i in V} "point %s arrive between %s and %s (actual = %s)\n", i, B[i], E[i], a[i]; end; 


Para começar rapidamente, também adicionarei dados da minha cabeça preparados para uso no modelo:

Dados de entrada
 data; param numOfPoints := 9; #  param numOfTypes := 6; #   ############### param : B E L := 0 0 8 1 1 0 8 1 2 0 8 1 3 0 8 1 4 0 8 1 5 0 8 1 6 0 8 1 7 0 8 1 8 0 8 1 9 0 8 1; param D default 0 : 0 1 2 3 4 5 6 7 8 9 := 0 . . . . . . . . . . 1 0.1 0.3 0.2 0.1 0.2 0.1 0.2 0.1 0.2 0.1 2 0.3 0.2 0.2 0.1 0.2 0.1 0.2 0.1 0.2 0.1 3 0.4 0.3 0.2 0.1 0.2 0.1 0.2 0.1 0.2 0.1 4 0.4 0.4 0.2 0.1 0.2 0.1 0.2 0.1 0.2 0.1 5 0.1 0.2 0.2 0.1 0.2 0.1 0.2 0.1 0.2 0.1 6 0.5 0.5 0.2 0.1 0.2 0.1 0.2 0.1 0.2 0.1 7 0.3 0.2 0.2 0.1 0.2 0.1 0.2 0.1 0.2 0.1 8 0.2 0.1 0.2 0.1 0.2 0.1 0.2 0.1 0.2 0.1 9 0.5 0.2 0.2 0.1 0.2 0.1 0.2 0.1 0.2 0.1; param G := 1 1 2 2 3 1 4 2 5 1 6 2 7 1 8 2 9 1; ########## param : C P := 1 8 500 2 10 500 3 14 600 4 18 650 5 25 700 6 35 800; param U0 default 2; #  ,  end; 


Depois de copiar o código do modelo para um arquivo com o nome, por exemplo, model.mod e os dados de entrada no arquivo data.dat, tudo estará pronto para ser executado. Definimos um limite para o tempo de cálculo de 100 segundos (isso é feito usando a tecla --tmlim [tempo em segundos]), transferimos o caminho para o arquivo com dados de entrada (usando a tecla -d [caminho do arquivo]),

imagem

e pressione F5. Se for bem-sucedida, as mensagens aparecerão na janela à direita e, após cem segundos, teremos a melhor solução que o GLPK conseguiu encontrar no tempo previsto.

imagem

No texto em azul, estamos interessados ​​no significado após a inscrição "mip =". Como você pode ver, diminui de tempos em tempos. Todas as novas soluções estão em processo de trabalho, cujo valor dos custos de transporte, na melhor das hipóteses, é exibido nesta coluna (existem 14700 até o momento). O próximo número é o limite inferior para a melhor solução existente, ou seja, a melhor . Inicialmente, a estimativa é subestimada significativamente, mas é refinada ao longo do tempo, ou seja, aumenta. Os valores à esquerda e à direita estão convergindo e a diferença relativa entre eles no momento da captura de tela é de 54,1%. Assim que esse número se tornar zero, o algoritmo provará que a melhor solução encontrada é a melhor possível. Nem sempre se justifica esperar por esse evento na prática, e não apenas porque é muito tempo, mas é importante fazer uma reserva de que, via de regra, uma boa solução é relativamente rápida, e os principais custos de tempo estão associados ao refinamento da estimativa necessária para provar o melhor possível.

Em vez de uma conclusão


Os problemas de roteamento são extremamente complexos em termos computacionais e, com o aumento do número de pontos que precisam ser visitados, o tempo que leva para um solucionador encontrar uma solução e provar que sua otimização está crescendo rapidamente. No entanto, para exemplos bastante pequenos, em um período de tempo razoável, o solucionador é capaz de construir um conjunto de rotas bem-sucedido e pode ser usado para apoiar a tomada de decisões. A análise das opções de roteamento propostas pelo modelo nos ajudou a descobrir oportunidades significativas de redução de custos, e isso é fundamental para a existência e o desenvolvimento do estoque.

Nossos esforços adicionais foram direcionados ao trabalho com incerteza nos volumes de recicláveis ​​coletados nos pontos. Estamos desenvolvendo vários modelos de programação estocástica para tomar decisões estratégicas e operacionais no roteamento de caminhões. Se o tópico for relevante e despertar interesse, escreverei sobre isso também, porque em breve todos nós teremos que mergulhar significativamente mais profundamente nas questões ambientais, e é nisso que eu desejo sucesso.

Source: https://habr.com/ru/post/pt456310/


All Articles