I am testing to see if my network is balanced as part of a larger protection-interdiction-restoration problem. To do this, I'm solving the problem as a minimum cost network flow problem to see if the network is balanced initially. I'm returning that the network is infeasible when I run it, but I'm not sure if it's because I formulated the constraints wrong or because it's genuinely unfeasible. Here's my code:
import gurobipy as gp
from gurobipy import GRB
import csv
import csv
from math import *
import numpy as np
from gurobipy import quicksum
# input arcs names
arccap = open('C:/Users/Emma/Documents/2021-2022/Thesis/Data/poweronly/arcs-smallp.csv', 'r', encoding='utf-8-sig')
csv_arccap = csv.reader(arccap)
mydict_arccap = {}
for row in csv_arccap:
mydict_arccap[(row[0],row[1])] = float(row[2])
arcs, capacity = gp.multidict(mydict_arccap)
#import nodes
# input arcs names
inflow = open('C:/Users/Emma/Documents/2021-2022/Thesis/Data/poweronly/inflow.csv', 'r', encoding='utf-8-sig')
csv_inflow = csv.reader(inflow)
mydict_inflow = {}
for row in csv_inflow:
mydict_inflow[(row[0])] = float(row[1])
nodes, inflow = gp.multidict(mydict_inflow)
# set cost of all arcs = 1
arccost = open('C:/Users/Emma/Documents/2021-2022/Thesis/Data/poweronly/arcs-smallp.csv', 'r', encoding='utf-8-sig')
csv_arccost = csv.reader(arccost)
mydict_arccost = {}
for row in csv_arccost:
mydict_arccost[(row[0],row[1])] = float(row[3])
arcs, cost = gp.multidict(mydict_arccost)
# Create optimization model
m = gp.Model('netflow')
# Create variables
flow = m.addVars(arcs, obj=cost, name="flow")
# flow on single arc cannot exceed capacity
m.addConstrs(
(flow.sum(i, j) <= capacity[i, j] for i, j in arcs), "cap")
# flow into/out of node must equal supply, demand, or zero for transshipment
m.addConstrs(
(gp.quicksum(flow[i, j] for i, j in arcs.select('*', j)) + inflow[j] ==
gp.quicksum(flow[j, k] for j, k in arcs.select(j, '*')) for j in nodes), "node")
# Compute optimal solution
m.optimize()
# Print solution
if m.status == GRB.OPTIMAL:
solution = m.getAttr('x', flow)
for i, j in arcs:
if solution[i, j] > 0:
print('%s -> %s: %g' % (i, j, solution[i, j]))
And my output:
Gurobi Optimizer version 9.5.1 build v9.5.1rc2 (win64)
Thread count: 4 physical cores, 8 logical processors, using up to 8 threads
Optimize a model with 298 rows, 179 columns and 537 nonzeros
Model fingerprint: 0x93312151
Coefficient statistics:
Matrix range [1e+00, 1e+00]
Objective range [1e+00, 1e+00]
Bounds range [0e+00, 0e+00]
RHS range [9e-01, 2e+04]
Presolve removed 0 rows and 2 columns
Presolve time: 0.01s
Solved in 0 iterations and 0.01 seconds (0.00 work units)
Infeasible model
Two questions : is this model set up correctly, and if it is genuinely unfeasible, how do I see in what way it's infeasible? Right not the "inflow" parameter has negative values for demand nodes, positive values for supply, and zero values for transshipment nodes.