'scipy.minimize messes up my constraint function
I am trying to run a minimization problem in python with scipy. The goal is to minimize the distance in meters between different coordinates.
#dependencies
pip install haversine
import scipy.optimize as spo
import haversine as hs
from haversine import Unit
hs.haversine returns the distance in meters between two pairs of coordinates (latitude, longitude). For example:
a = (41.160716, -8.582416)
b = (41.150537, -8.586245)
hs.haversine(a, b, unit = Unit.METERS)
1176.3758242489466 (meters)
hs.haversine is then used in my objective function and constraint like this:
def objFunction(X, M):
sum = 0
for i in X:
for j in M:
sum += hs.haversine(i, j, unit = Unit.METERS)
return sum
def constraint1(X):
for i in range(len(X)-1):
for j in range(i + 1, len(X)):
return hs.haversine(X[i], X[j], unit = Unit.METERS) - 40
The objective and constraint function both work fine on their own, but when I try to use minimize() it gives me an error.
I give my minimize() the following initial input x0 ('x_init') and a tuple of coordinates ('metro_stops') that I want to minimize the distance to:
x_init = ((41, -8), (41.5, -8.5))
metro_stops = ((41.160716, -8.582416), (41.150537, -8.586245))
con1 = {'type': 'ineq', 'fun': constraint1}
cons = [con1]
sol = spo.minimize(fun = objFunction, x0 = x_init, args = (metro_stops), method = 'SLSQP', constraints = (cons))
I get an error saying that the constraint function "cannot unpack a non-iterable numpy object". I can't understand why since the constraint function works fine when used outside of minimize().
Full error:
TypeError Traceback (most recent call last)
<ipython-input-61-b414e685be2c> in <module>
----> 1 sol = spo.minimize(fun = objFunction, x0 = x_init, args = (metro_stops,), method = 'SLSQP', constraints = (cons))
~\anaconda3\lib\site-packages\scipy\optimize\_minimize.py in minimize(fun, x0, args, method, jac, hess, hessp, bounds, constraints, tol, callback, options)
625 return _minimize_cobyla(fun, x0, args, constraints, **options)
626 elif meth == 'slsqp':
--> 627 return _minimize_slsqp(fun, x0, args, jac, bounds,
628 constraints, callback=callback, **options)
629 elif meth == 'trust-constr':
~\anaconda3\lib\site-packages\scipy\optimize\slsqp.py in _minimize_slsqp(func, x0, args, jac, bounds, constraints, maxiter, ftol, iprint, disp, eps, callback, finite_diff_rel_step, **unknown_options)
328 meq = sum(map(len, [atleast_1d(c['fun'](x, *c['args']))
329 for c in cons['eq']]))
--> 330 mieq = sum(map(len, [atleast_1d(c['fun'](x, *c['args']))
331 for c in cons['ineq']]))
332 # m = The total number of constraints
~\anaconda3\lib\site-packages\scipy\optimize\slsqp.py in <listcomp>(.0)
328 meq = sum(map(len, [atleast_1d(c['fun'](x, *c['args']))
329 for c in cons['eq']]))
--> 330 mieq = sum(map(len, [atleast_1d(c['fun'](x, *c['args']))
331 for c in cons['ineq']]))
332 # m = The total number of constraints
<ipython-input-57-127f2f6960a1> in constraint1(X)
2 for i in range(len(X)-1):
3 for j in range(i + 1, len(X)):
----> 4 return hs.haversine(X[i], X[j], unit = Unit.METERS) - 40
~\anaconda3\lib\site-packages\haversine\haversine.py in haversine(point1, point2, unit)
86
87 # unpack latitude/longitude
---> 88 lat1, lng1 = point1
89 lat2, lng2 = point2
90
TypeError: cannot unpack non-iterable numpy.float64 object
Thankful for any tips
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|
