如何在python纸浆目标函数中使用绝对值?

问题描述

我正在尝试在目标函数中使用绝对值。我想最小化以下等式的绝对值

    |(m[i] - (x1 * a1[i] + x2 * a2[i] + x3 * a3[i])|

我尝试了以下

from pulp import LpVariable,LpProblem,lpSum,LpMinimize,LpStatus,value
import numpy as np
import pandas as pd

df = pd.DataFrame({
                    'm':[375575.583,367790.9166,353404.7496],'a1':[351170.56,359097.94,321573.44],'a2':[785612.241849173,762821.6656155427,724076.4664063533],'a3':[410363.40625,378311.78125,397014.53125]
                    },index = ['2020-01-01','2020-01-02','2020-01-03' ])

prob = LpProblem('Ensemble',LpMinimize)

date_index = list(df.index)
a1 = dict(zip(date_index,df.iloc[:,1]))
a2 = dict(zip(date_index,2]))
a3 = dict(zip(date_index,3]))
m = dict(zip(date_index,0]))

index_var = LpVariable.dict("Date",date_index,lowBound = 0,upBound = 1,cat = 'Continuous')

x1 = LpVariable('x1',cat = 'Continuous')
x2 = LpVariable('x2',cat = 'Continuous')
x3 = LpVariable('x3',cat = 'Continuous')

prob += np.abs(lpSum((m[i] - (x1 * a1[i] + x2 * a2[i] + x3 * a3[i])) for i in date_index))

limit = x1 + x2 + x3
prob += (limit == 1)

prob.solve()
print(LpStatus[prob.status])

for v in prob.variables():
    print(v.name,"=",v.varValue)
value(prob.objective)

并出现以下错误

    prob += np.abs(lpSum((m[i] - (x1 * a1[i] + x2 * a2[i] + x3 * a3[i])) for i in date_index))

    TypeError: bad operand type for abs(): 'LpAffineExpression'

如何在目标函数中使用差异的绝对值?

解决方法

一种实现方法是定义一个变量来表示您的和,然后定义另一个变量来表示该和的绝对值,您可以将其限制为大于和的正负值。

这将可变的绝对值限制为“至少与和变量的大小一样大”。请注意,它可能更大,但这不是问题,因为该问题是为了使该绝对和值变量最小而设置的。

range_set = [range(1,6),range(6,16),range(16,36)]
random.choice(*random.choices(range_set,[0.5,0.25,0.25]))

返回:

from pulp import LpVariable,LpProblem,lpSum,LpMinimize,LpStatus,value
import numpy as np
import pandas as pd

df = pd.DataFrame({
                    'm':[375575.583,367790.9166,353404.7496],'a1':[351170.56,359097.94,321573.44],'a2':[785612.241849173,762821.6656155427,724076.4664063533],'a3':[410363.40625,378311.78125,397014.53125]
                    },index = ['2020-01-01','2020-01-02','2020-01-03' ])

prob = LpProblem('Ensemble',LpMinimize)

date_index = list(df.index)
a1 = df['a1']
a2 = df['a2']
a3 = df['a3']
m = df['m']

index_var = LpVariable.dict("Date",date_index,lowBound = 0,upBound = 1,cat = 'Continuous')

x1 = LpVariable('x1',cat = 'Continuous')
x2 = LpVariable('x2',cat = 'Continuous')
x3 = LpVariable('x3',cat = 'Continuous')

# Variable to hold sum
sum_var = LpVariable('sum_var')
abs_sum_var = LpVariable('abs_sum_var')

# Objective
prob += abs_sum_var

# Constraints which define sum_var and abs_sum_var
prob += sum_var == lpSum([(m[i] - (x1 * a1[i] + x2 * a2[i] + x3 * a3[i])) for i in date_index])
prob += abs_sum_var >= sum_var
prob += abs_sum_var >= -sum_var

# Constraint
prob += (x1 + x2 + x3 == 1)

prob.solve()
print(LpStatus[prob.status])

for v in prob.variables():
    print(v.name,"=",v.varValue)
value(prob.objective)

abs_sum_var = 0.0 sum_var = -1.7462298e-10 x1 = 0.94766587 x2 = 0.052334135 x3 = 0.0 与应该abs_sum_var之间的微小差异,我怀疑与求解器的约束公差有关,您可以修改约束的公差,请参见{{3} }。