Constrained optimization with scipy.optimize

Einblick Content Team - February 28th, 2023

Optimization problems often come with constraints, such as a limit on the amount of resources that can be used or the range of acceptable solutions. In these cases, it's important to consider the constraints when finding the optimal solution. In this tutorial, we'll be discussing how to perform constrained optimization using the scipy.optimize.minimize() function. If you haven't used the scipy.optimize.minimize() function before, check out our first post about the function, which goes through relevant arguments and results.

All the code from this post is in the red data zone on the below Python canvas. Open and fork the canvas to follow-along as we dive into the tutorial:

1. Imports

import numpy as np
import scipy.optimize as opt

2. Define the function to minimize

In this case, we are turning the below function into Python:

f(x)=(x03)2+(x1+2)2f(x) = (x_0-3)^2+(x_1+2)^2
# Define the function to be minimized
def f(x):
   return (x[0] - 3)**2 + (x[1] + 2)**2

3. Define the constraints, as a function, g(x)

x02+x12=50x_0^2+x_1^2=50

Given the function and the constraints, we can imagine a real-world scenario similar to this, in which we are trying to determine the point on a circle closest to a particular foci.

NOTE: The minimize() function can take two kinds of restraints--equalities ('type': 'eq') and inequalities ('type': 'ineq'), with respect to 0. Our above constraint is an equality, but we have to rewrite it as:

x02+x1250=0x_0^2+x_1^2-50=0

Now we can translate this into Python, and we define the constraint as a dictionary called cons.

# Define the constraints
def g(x):
   return (x[0]**2 + x[1]**2 - 50)

# Define the constraints in the form required by the minimize function
cons = ({'type': 'eq', 'fun': g})

3. Minimize the function

# Set the initial guess for the optimization
x0 = np.array([3, -5])

# Minimize the objective function subject to the constraints
result = opt.minimize(f, x0, constraints=cons)

We created an initial guess saved as x0, and set the constraints equal to the variable we defined earlier.

4. Print and check results

# Print message indicating why the process terminated
print(result.message)

# Print the relevant x-value that results in constrained minimum
print(result.x)

Output:

Optimization terminated successfully
[ 5.88348397 -3.92232284]

From the results, we can see that the minimum was successful found where:

x0=5.883x1=3.922x_0 = 5.883 \newline x_1 = -3.922

Then we can input the x-values back into the constraints function, g, and if the result is close to 0, then we have confirmed this is a minimum.

# Use the result to validate the solution to the optimization problem (should be close to 0)
print(g(result.x))

Output:

1.4210854715202004e-14 # Success!

About

Einblick is an AI-native data science platform that provides data teams with an agile workflow to swiftly explore data, build predictive models, and deploy data apps. Founded in 2020, Einblick was developed based on six years of research at MIT and Brown University. Einblick is funded by Amplify Partners, Flybridge, Samsung Next, Dell Technologies Capital, and Intel Capital. For more information, please visit www.einblick.ai and follow us on LinkedIn and Twitter.

Start using Einblick

Pull all your data sources together, and build actionable insights on a single unified platform.

  • All connectors
  • Unlimited teammates
  • All operators