Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Migrating from PuLP to Scipy

Im using PuLP to solve some minimization problems with constraints, uper and low bounds. It is very easy and clean.

But im needing to use only the Scipy and Numpy modules.

I was reading: http://docs.scipy.org/doc/scipy/reference/tutorial/optimize.html

Constrained minimization of multivariate scalar functions

But im a bit lost... some good soul can post a small example like this PuLP one in Scipy?

Thanks in advance. MM

from pulp import *

'''
Minimize        1.800A + 0.433B + 0.180C
Constraint      1A + 1B + 1C = 100
Constraint      0.480A + 0.080B + 0.020C >= 24
Constraint      0.744A + 0.800B + 0.142C >= 76
Constraint                            1C <= 2
'''

...
like image 291
Martha Morrigan Avatar asked Mar 22 '23 20:03

Martha Morrigan


1 Answers

Consider the following:

import numpy as np
import scipy.optimize as opt

#Some variables
cost = np.array([1.800, 0.433, 0.180])
p = np.array([0.480, 0.080, 0.020])
e = np.array([0.744, 0.800, 0.142])

#Our function
fun = lambda x: np.sum(x*cost)

#Our conditions
cond = ({'type': 'eq', 'fun': lambda x: np.sum(x) - 100},
        {'type': 'ineq', 'fun': lambda x: np.sum(p*x) - 24},
        {'type': 'ineq', 'fun': lambda x: np.sum(e*x) - 76},
        {'type': 'ineq', 'fun': lambda x: -1*x[2] + 2})


bnds = ((0,100),(0,100),(0,100))
guess = [20,30,50]
opt.minimize(fun, guess, method='SLSQP', bounds=bnds, constraints = cond)

It should be noted that eq conditions should be equal to zero, while ineq functions will return true for any values greater then zero.

We obtain:

  status: 0
 success: True
    njev: 4
    nfev: 21
     fun: 97.884100000000345
       x: array([ 40.3,  57.7,   2. ])
 message: 'Optimization terminated successfully.'
     jac: array([ 1.80000019,  0.43300056,  0.18000031,  0.        ])
     nit: 4

Double check the equalities:

output = np.array([ 40.3,  57.7,   2. ])

np.sum(output) == 100
True
round(np.sum(p*output),8) >= 24
True
round(np.sum(e*output),8) >= 76
True

The rounding comes from double point precision errors:

np.sum(p*output)
23.999999999999996
like image 60
Daniel Avatar answered Apr 02 '23 11:04

Daniel