pythonscipyconstraintsminimizescipy-optimize-minimize

Python Minimizing a function until it equals a desired value


I need to minimise a input value (x) until the ouput value (y) meets the desired value exactly or it is of by some decimals. I know that I can use the scipy.optimisation.minimize function but I am having troubles to set it up properly.

optimize_fun_test(100)

this is my written function which for a specific value (in this case price) calculates the margin i will have when I sell my product.

Now from my understanding I need to set a constraint which holds the minimum margin which I want to target, as my goal is to sell the product as cheap as possible but I need to have a minimum margin that I have to target, in order to be profitable. So let's say that my function calculates a margin of 25% (0.25) when i sell my product for 100Euro, and my margin that I wish to target is 12.334452% (0.1233452), the price will be lower. So the minimize function should be able to find the exact price for which I would need to sell it in order to meet my desired margin of 0.1233452, or at least very close to it, let's say the price for which I will sell it will generate a margin which is max of by 0.000001 from the desired margin.

optimize_fun_test(price)
s_price = 100
result = minimize(optimize_fun_test, s_price)

so this is what I got right now, I know it's not a lot but I don't know how to continue with the constraints. From youtube videos I learnt that there are equality and inequality constraints, so I guess I want to have an equality constraint right ?

should the constraint look like this ?

cons=({'type','eq','fun' : lambda x_start: x_start-0.1233452})

Solution

  • Minimizing f(x) subject to f(x) = c is the same as just solving the equation f(x) = c which in turn is equivalent to finding the root of the function q(x) = f(x) - c. Long story short, use scipy.optimize.root instead:

    from scipy.optimize import root
    
    def eq_to_solve(x):
        return optimize_fun_test(x) - 0.1233452
    
    x0 = np.array([100.0]) # initial guess (please adapt the dimension for your problem)
    
    sol = root(eq_to_solve, x0=x0)
    

    In case you really want to solve it as a optimization problem (which doesn't make sense from a mathematical point of view)

    from scipy.optimize import minimize
    
    constr = {'type': 'eq', 'fun': lambda x: optimize_fun_test(x) - 0.1233452}
    
    x0 = np.array([100.0]) # your initial guess
    
    res = minimize(optimize_fun_test, x0=x0, constraints=constr)