Optimization Issues and Infinite Loop When Adding Constraints
ユーザーの入力を待っています。Hello everyone,
I am working on an optimization model with Gurobi to plan drone routes, and I've encountered a problem. My code is designed to extract routes and, if the solution does not meet certain criteria, add constraints and re-optimize. However, instead of converging, it gets stuck in an infinite loop of iterations and does not provide a viable solution.
I managed to obtain an initial solution of 438, but I haven't been able to replicate it, and I suspect there might be a better solution available. Below is a snippet of my code that illustrates the optimization process and the addition of constraints:Import math
from gurobipy import *
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import networkx as nx
archive = './droneinfo.xls'
drones = pd.read_excel(io=archive, sheet_name = 'Drones')
# SETS
C = drones['Places'].tolist()
A = {(i,j) for i in C for j in C if i!= j}
#PARAM
#Pictures to take
f = {c:drones.loc[drones['Location'] == c, 'Pictures to take'].values[0] for c in C}
#X coordinate
q = {c: drones.loc[drones['Location'] == c, 'X'].values[0] for c in C}
#Y coordinate
l = {c: drones.loc[drones['Location'] == c, 'Y'].values[0] for c in C}
#Manhattan distance between nodes
d = {(i,j): abs(q[i]-q[j]) + abs(l[i]-l[j]) for i,j in A}
#Drone speed
v = 600
#Obligatory stay in the location
e = 1.5
#Max autonomy time
t = 12
#Max photo capacity
k = 300
m = Model('Drones')
#Decision Variable
x = m.addVars(C,C, vtype = GRB.BINARY, name = 'x')
#Restrictions
for i in C
if i != 'Hangar':
#Every location has to be visited
m.addConstr(quicksum(x[i,j] for j in C if (i,j) in A) == 1)
#Every drone has to be used
if i == 'Hangar':
m.addConstr(quicksum(x[i,j] for j in C if (i,j) in A) == 5)
for j in C:
if j != 'Hangar':
#Every location has to be visited
m.addConstr(quicksum(x[i,j] for i in C if (i,j) in A) == 1)
#Every drone has to be used
if i == 'Hangar':
m.addConstr(quicksum(x[i,j] for i in C if (i,j) in A) == 5)
for (i,j) in A:
m.addConstr(x[i,j]+x[j,i] <= 1)
#FO
m.setObjective(quicksum(d[i,j]*x[i,j] for i,j in A), GRB.MINIMIZE
#Solve problem
m.update()
m.setParam('OutputFlag', False)
m.optimize()
print({m.getObjective().getValue()}
routes = [(i,j) for i in C for j in C if x[i,j].X > 0.5]
def extract_routes(routes):
rut = []
remaining_rut = routes.copy()
while remaining_routes:
current_route = []
current_location = remaining_route[0][0]
while True:
found_arc = False
for arc in remaining_routes:
current_route.append(arc)
current_location = arc[1]
remaining_routes.remove(arc)
found_arc = True
break
if not found_arc or current_location == current_route[0][0]:
break
rut.append(current_route)
return rut
def calcular_tiempo_y_fotos_rutas_completas(rutas_completas, distancia, velocidad, permanencia, fotos_por_cultivo):
fotosTomadas= {}
tiempoRutas= {}
nodos= {}
for idx, ruta in enumerate(rutas_completas, 1):
tiempo_ruta=0
fotos_totales=0
nodos[idx] =set()
pasoHangar=False
for origen, destino in ruta:
nodos[idx].update([origen, destino])
if origen == 'Hangar' or destino == 'Hangar':
pasoHangar = True
if origen!= 'Hangar' and destino!='Hangar':
tiempo_viaje = distancia[(origen, destino)] /velocidad
tiempo_ruta += tiempo_viaje+permanencia
fotos_totales += fotos_por_cultivo[origen]
else:
tiempo_viaje=distancia[(origen, destino)] /velocidad
if destino == 'Hangar':
tiempo_ruta += permanencia
fotos_totales += fotos_por_cultivo[origen]
tiempo_ruta += tiempo_viaje
fotosTomadas[idx] = fotos_totales
tiempoRutas[idx] = tiempo_ruta
if not pasoHangar:
tiempoRutas[idx] -= permanencia
return fotosTomadas, tiempoRutas, nodos
valores_objetivo = []
iteracion = 0
while True:
m.optimize()
nuevasRestricciones=False
# Extraer las rutas
routes= [(i, j) for i in C for j in C if x[i, j].X > 0.5]
paths=extract_routes(routes)
fotos, tiempo, nodes=calcular_tiempo_y_fotos_rutas_completas(paths, d, v, e, f)
# Crear una lista para almacenar la información de las rutas
ruta_info= []
print(f"Iteración {iteracion+1}:")
print(F'\n* El valor de la funcion objetivo es: {m.getObjective().getValue()}\n')
valores_objetivo.append(m.getObjective().getValue())
for u in fotos.keys():
fotos_totales=fotos[u]
tiempo_ruta=tiempo[u]
ruta=paths[u-1]
delta_SOut= [(i, j) for i in nodes[u] for j in C if i!='Hangar' and j not in nodes[u]]
excesoT = math.ceil(tiempo_ruta/t)
excesoF=math.ceil(fotos_totales/k)
if 'Hangar' not in nodes[u]:
if delta_SOut:
print(f"La ruta {u} no comienza y termina en el Hangar.")
m.addConstr(quicksum(x[i, j] for i, j in delta_SOut) >= 1)
nuevasRestricciones=True
if excesoT > 1 or excesoF>1:
if excesoT >= excesoF:
if delta_SOut:
print(f"Ruta {u} excede el tiempo máximo permitido. Tiempo total: {tiempo_ruta}")
m.addConstr(quicksum(x[i, j] for i, j in delta_SOut) >= excesoT)
nuevasRestricciones=True
else:
if delta_SOut:
print(f"Ruta {u} excede la capacidad de fotos. Fotos totales: {fotos_totales}")
m.addConstr(quicksum(x[i, j] for i, j in delta_SOut) >=excesoF)
nuevasRestricciones = True
if not nuevasRestricciones:
print("No se encontraron más cortes. Proceso finalizado.")
break
m.update()
iteracion+=1
Thank you in advance for your help
-
Hi Natalia,
It's hard to see what is going on, but can I suggest you save the solution vector (m.X) in each iteration. I would verify the solution is different at each iteration and check that the constraint being added in each iteration cuts off the solution. It seems impossible that this could truly be an infinite loop if solutions are being cut off each at iteration.
- Riley
0
サインインしてコメントを残してください。
コメント
1件のコメント