简体   繁体   中英

Optimizing for deviation from target in Pulp

I am using pulp in an attempt to minimize the deviation from a target. In the MRE below, assume that items 1-50 have features A, B, C, D. The optimizer should apportion a "budget" equal to 100%, while attempting to get the average value of feature "A" equal to tgt_a . It would be fairly easy to just tell pulp to force a to be equal to the target, but in real life, it may not be possible to get exactly to the target. In addition, I ultimately want to have the system balance all the various features using a sum of squared deviation method, which makes it even less likely that a perfect solution even exists.

The code below runs fine, but simply minimizes the difference between the actual "A" feature value and the target. I need to square the difference in order to make it useful. However if you add a **2 to the appropriate line of code, you get:

TypeError: unsupported operand type(s) for ** or pow(): 'LpAffineExpression' and 'int'

What I'm looking for is a way to square a_dev and then set the solver to optimize the variables to minimize that squared difference.

import pandas as pd
import numpy as np
import pulp

def contrib(p, col):
    c = df.loc[p, col]
    return c

df_data = {'A':np.random.randint(20, 50, 50),
            'B':np.random.randint(0, 50, 50),
            'C':np.random.randint(20, 50, 50),
            'D':np.random.randint(20, 100, 50)}

df = pd.DataFrame(data=df_data)
picks = df.index

#Set up variable
pct = pulp.LpVariable.dicts('Pct', (p for p in picks), 0, 0.05)

#Create problem
ideal = pulp.LpProblem('Sq_dev', pulp.LpMinimize)

tgt_a = 35

a = [pct[p] * contrib(p, 'A') for p in picks]
a_tgt = [pct[p] * tgt_a for p in picks]
a_dev = (pulp.lpSum(a) - pulp.lpSum(a_tgt))
#I need a_dev to be squared in order to be useful!
ideal += a_dev

ideal += pulp.lpSum([pct[p] for p in picks]) == 1
ideal.solve()

for p in picks:
    if pct[p].value() > 0:
        print(p, pct[p].value())

The problem is just what the error message tells you: pulp does not define these operations on affine expressions. This is somewhat like multiplying polynomials, or functions: you have to define the operation and write the implementation.

Very simply, you have to look up the basic definition of an affine function, research the operations that are supported, and write a function to perform the desired operation given those building blocks.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM