Search code examples
pythonoptimizationconstraints

python values optimization with constraints


So I have

M = [0.06,0.22,0.32,0.15,0.19]
wanted = 0.21
-0.05 <= -0.273*ln((new_M-M)/(M)+1) +0.0024 <= 0.05

New_M values are created by optimizing M values as close as possible to the wanted value(0.21), with bounds:

M - 0.1<=new_M<= M + 0.1

In other words M cannot be changed by more than 0.1, from both sides, in order to get as close as possible to wanted value 0.21, but also there is that constraint on the top as well.

Any suggestions on how to solve this problem?I've tried some optimization libraries(pulp, mip, scipy) but it didn't work for me, because I don't how to describe constraints and bounds for this problem. How should I optimize for specific target value with constraints and how should I use that value for new constraint(if it's possible)?


Solution

  • First some observations.

    1. We have new_M and new in your formulas. I'll assume they are the same.
    2. Wanted is probably part of an objective: make M as close as possible to Wanted. It is not a constraint.
    3. M is a vector, but it seems all the optimization problems are independent. So we can solve for a scalar M (and repeat for all elements in the list).
    4. There is confusion about M and new_M. "Optimizing M" seems to indicate M is a decision variable. But I think you mean: "Optimizing New_M" with M being a constant.
    5. You have one element M=0. Note that you divide by M in: (new_M-M)/(M). You must explain what that means. (Maybe you meant 0.32 instead of 0,32).
    6. What is the reason for using parentheses (M) in ln((new_M-M)/(M)+1)?
    7. I'll assume M>0 in the following.

    So let me try to use more "traditional" mathematical notation:

     min |x-wanted|   
     subject to
        M - 0.1 ≤ x ≤ M + 0.1
       -0.05 ≤ -0.273*ln(1+(x-M)/M)+0.0024 ≤ 0.05  
        x > 0 (implicit from the ln(.) calculation)
    

    Here x is the decision variable and M,wanted are constants.

    Using high-school math, we can rewrite the second constraint as:

       0.84*M ≤ x ≤ 1.2116*M
       assumption: M > 0  
    

    So let:

     L := max(M-0.1, 0.84*M, 0.0001)
     U := min(M+0.1, 1.2116*M)
    

    Now we just need to solve:

     min |x-wanted|
     subject to L ≤ x ≤ U
    

    This can be solved with the "algorithm":

     if wanted > U then x := U
     else if wanted < L then x := L 
     else x := wanted 
     
             
    

    Or in Python:

    M = [0.06,0.22,0,32,0.15,0.19]
    wanted = 0.21
    
    for m in M:
       if m<=0: raise Exception("M<=0 not allowed")
       L = max(m-0.1, 0.84*m, 0.0001) 
       U = min(m+0.1, 1.2116*m)
       if wanted>U: x=U
       elif wanted<L: x=L
       else: x=wanted
       print(f"M:{m}, x:{x}")
    

    In conclusion:

    1. The question needs a bit more careful editing.
    2. This can be solved with high-school-level math instead of formal optimization tools.