Optimization Problem in Python - Like Goal Seek

Optimization Problem in Python - Like Goal Seek

I've just started using Python and have run into a challenge that I think should be straightforward but i can't seem to figure it out. In Excel there is a Goal Seek option where you can optimize a value by changing another value. I'm wondering if a similar optimization problem can be solved efficiently in Python, but with the ability to chaneg multiple values at once.

A minimal example :

I have two arrays

x = np.array([2, 3, 5, 6, 2, 2])
y = np.array([3, 2, 1, 4, 4, 2])

I'm trying to find the values in y that will set the result of the below formula to 5 using only values [1, 2, 3]/

np.sqrt(sum((x-y)**2))

I know the correct values should be :

[1, 1, 2, 3, 1, 1]

I realize there may be multiple solutions so being able to set some constraints around this would be good.

Are there any particular packages that would allow me to do this ? The above is just a toy example and in this case I could just try all possilbe combinations of [1, 2, 3] but I'm really looking for something that would scale to much bigger datasets.

1

2 Answers

Getting closer with root. But cannot figure out how to select only 1,2, and 3.

import numpy as np
import scipy.optimize as opt

x = np.array([2, 3, 5, 6, 2, 2])
y = np.array([1, 1, 1, 1, 1, 1])

def func(y):
    x = np.array([2, 3, 5, 6, 2, 2])
    z = np.sqrt(np.sum((x-y)**2)) - 5
    return  np.zeros(x.shape[0],) + z

r = opt.root(func, x0=y, method='hybr')
print(r.x)
# array([1.51287563, 2.93792864, 2.41974376, 1.82313836, 1.49719936, 1.36584456])

print(np.sqrt(np.sum((x-r.x)**2)))
# 5.0

This is a working progress. I have to figure out how to constrain it to 1, 2, and 3. I will update my answer when I hit a breakthrough.

Update

To use any given array,

X = np.array([3, 4, 5, 6, 7])
y = np.array([1, 1, 1, 1, 1])

def func(y, given=X):

    z = np.sqrt(np.sum((given-y)**2)) - 5
    return  np.zeros(given.shape[0],) + z

r = opt.root(func, x0=y, method='hybr')
print(r.x)
# array([1.97522498 3.47287981 5.1943792  2.10120135 4.09593969])

print(np.sqrt(np.sum((X-r.x)**2)))
# 5.0
4

Use fsolve from the scipy.optimization package.

You should define 6 parameters like that:

# z = [ z1, z2, z3, z4, z5, z6]
z = x - y
roots = fsolve(func, z)
def func(z):
    return [np.sqrt(sum(z**2))-5, 0, 0, 0, 0, 0]
2
Marcus Vance
Author

Marcus Vance

Marcus Vance is a cybersecurity auditor and technology writer dedicated to educating the public about online safety, data privacy regulations, enterprise security, and emerging cyber threats.