I have a binary/integer program that I am trying to solve using milp in Python. Below the image and below is the code I have so far. When I run it, I get
`bounds.lb` and `bounds.ub` must contain reals and be broadcastable to `c.shape`.
I believed I accounted for the upper and lower bounds in the "bounds" variable. But apparently not. What is missing?
from scipy.optimize import linprog
import numpy as np
from scipy.optimize import milp, LinearConstraint, Bounds
c = [3, 5, 7, 9, 2, 8, 6, 4, 1] # x1 to x9 (office setup cost multipliers)
c = c + [0]*36
A = [
[1700, 3600, 2100, 2500, 3100, 2700, 4100, 3400, 4100] + [24.3]*9 + [32.4]*9 + [28.9]*9+[26]*9, # Setup and transfer costs
[0, 0, 0, -1, 0, -1, 1, 0, 0] + [0]*36, # x7 <= x4 + x6
[1, 0, 0, 0, 0, 1, 0, 0, 0] + [0]*36, # x1 + x6 <= 1
[0]*9 + [1]*9 + [0]*27, # Chicago
[0]*18 + [1]*9 + [0]*18, # Charlotte
[0]*27 + [1]*9 + [0]*9, # Pittsburgh
[0]*36 + [1]*9 # Houston
]
b = [
14000,
0,
1,
29,
22,
19,
27,
]
# Define bounds for each variable (0 <= xi <= 1 for binary variables, 0 <= yij)
x_bounds = [(0, 1)] * 9 # Bounds for the x variables
y_bounds = [(0, None)] * 36 # Bounds for the y variables (unbounded upper limit)
# Combine bounds
bounds = x_bounds + y_bounds
integrality = ([1]) * 45
milp(c, integrality = integrality,
bounds = Bounds(bounds),
constraints = LinearConstraint(A, b))

There are two issues with your code. First, to disable bounds or define "unbounded bounds", one should use
np.infor-np.infinstead ofNone.Second, you are currently giving a list of tuples to
scipy.optimize.Boundswhich does not work. Instead you should provide a list of the lower bounds and a list for the upper bounds.To resolve these issues, you can change the last part of your code to:
Instead of the list comprehension you could also use the
zipfunction for a more concise solution:or directly
Personally, I prefer the solution using list comprehension as it is clearer to the reader what is happening and with lists of this length, performance is not really an issue.