Implement constraints correctly
AnsweredHi,
I am struggling to implement constraints correctly into my model.
I am looking into carbon capture and storage as shipboard application. As a vessel sails it will capture its own emission and store it in tanks onboard. Related to this I want to create a simple model that will choose at which nodes the ship will stop to unload its stored CO2 in order to minimize the cost of the system. The size of the CO2 tank onboard the vessel generates a cost to the system that increase linearly with the distance sailed since last reception point. It will however only be the largest distance traveled that will define this cost contribution. There is also a cost related to establishing reception points/infrastructure in given ports and and nodes, these will be different for different nodes.
I have a set of nodes that are ports, that has to be visited, and a set of nodes that are reception points for CO2, that can be visited if this generates a cheaper route.
The error code that appears is KeyError (0,0) for 'Constraint5'. But I am also a bit unsure about the rest of my constraints as well.
Let me know if anything needs clarification in my model!
import pandas as pd
from pandas import ExcelFile
import numpy as np
import matplotlib.pyplot as plt
import gurobipy as gp
from gurobipy import *
#Generating coordinates for nodes
xc = np.array([1,3,5,8,13,3,6,7,8,9,10])
yc = np.array([1,8,4,9,5,5,8,3,6,8,6])
#Sets
P = [0]+[1]+[2]+[3]+[4]
RP = [5]+[6]+[7]+[8]+[9]+[10]
N = P + RP
#Set of arcs for all nodes:
A = [(i,j) for i in N for j in N if i!=j]
#Distance between nodes
D = {(i,j): np.hypot(xc[i]xc[j],yc[i]yc[j]) for i,j in A if j!=0 and np.hypot(xc[i]xc[j],yc[i]yc[j])<=10}
#Making the data easier to work with
data = []
for i,j in D:
data.append((i,j,D[i,j]))
#Arcs beginning at source node
startres=[]
for i in data:
ifi[0] == 0:
startres.append(i)
#Arcs ending in sink node
ends=[]
for i in data:
ifi[1] == len(P)1:
ends.append(i)
#Parameters
#Cost of generating reception point in each node, including ports
cost = [70,70,70,70,70,90,150,70,500,150,90]
#Lost opportunity cost of reduced cargo capacity of the vessel, is to be multiplied by the longest arc. This will define the tank size on the vessel, and related cost
costCCS = 1500
f = gp.Model(name = "SimpleModel")
#Creating decision variables
#x = 1 if RP in 1, = 0 otherwise
x = f.addVars(N, name = 'x', vtype = GRB.BINARY)
#y = 1 if vessel sails between i and j, = 0 otherwise
y = f.addVars(D, name = 'y', vtype = GRB.BINARY)
#Auxiliary variable to help model the minimum of a max funtion
aux = f.addVar(name = 'aux', vtype = GRB.CONTINUOUS)
#Constraints:
#Two constraints that define that if an arc (eks: from node 1 to port node 2) is chosen, there has to be an established RP in node 1. And vice versa.
c1 = f.addConstrs((y[i,j]<=x[i] for i,j in D), name='Constraint1')
c2 = f.addConstrs((y[i,j]<=x[j] for i,j in D), name='Constraint2')
#Constraints that force vessel to travel from port 1 and end in port 5
c3 = f.addConstr((sum(y[i[0],i[1]] for i in startres)==1), name='Constraint3')
c4 = f.addConstr((sum(y[i[0],i[1]] for i in ends)==1), name='Constraint4')
#Constraint that force vessel to visit all Ports
for i in N:
f.addConstr(
(sum(y[i,j] for j in P) == 1), 'Constraint5')
#Flow conservation constraint, excluding arcs with start node in port 1 and end node in port 5
c6 = f.addConstrs((y.sum('*',j)  y.sum(j,'*') >= 0 for j in N if j != 0 and j != len(P)1), name = 'Constraint6')
#Max constraint that holds the maximum distance we want to minimize.
c7 = f.addConstrs((y[i]*D[i] <= aux for i in D), name='MaxConstraint')
##Objective funtion
obj = sum(x[i] * cost[i] for i in N) + (costCCS * aux)
f.setObjective(obj, GRB.MINIMIZE)
f.optimize()

You define your \(y\) variables over \(D\). However, the set \(D\) does not contain the keys \((0,0),(0,3)\) and more. The error occurs, because you build constraint 5 over the sets \(N\) and \(P\) of which, the combinations \((0,0),(0,3)\) and other are not present in \(D\). The probably easiest way to fix this would be to add an additional \(\texttt{if}\) check when constructing constraint 5
#Constraint that force vessel to visit all Ports
for i in N:
f.addConstr(
(sum(y[i,j] for j in P if (i,j) in D) == 1), 'Constraint5')Best regards,
Jaromił0
Please sign in to leave a comment.
Comments
1 comment