如何在python纸浆目标函数中使用绝对值? [英] How to use absolute value in python pulp objective function?

查看:409
本文介绍了如何在python纸浆目标函数中使用绝对值?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

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

我尝试了以下

 from纸浆进口 LpVariable, LpProblem, lpSum, LpMinimize, LpStatus, value将 numpy 导入为 np将熊猫导入为 pddf = 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 = 列表(df.index)a1 = dict(zip(date_index, df.iloc[:,1]))a2 = dict(zip(date_index, df.iloc[:,2]))a3 = dict(zip(date_index, df.iloc[:,3]))m = dict(zip(date_index, df.iloc[:, 0]))index_var = LpVariable.dict(日期", date_index, lowBound = 0, upBound = 1, cat = 'Continuous')x1 = LpVariable('x1', lowBound = 0, upBound = 1, cat = 'Continuous')x2 = LpVariable('x2', lowBound = 0, upBound = 1, cat = 'Continuous')x3 = LpVariable('x3', lowBound = 0, upBound = 1, cat = 'Continuous')prob += np.abs(lpSum((m[i] - (x1 * a1[i] + x2 * a2[i] + x3 * a3[i])) for i in date_index))极限 = x1 + x2 + x3概率 +=(限制 == 1)问题.解决()打印(LpStatus[prob.status])对于 prob.variables() 中的 v:打印(v.name,=",v.varValue)价值(概率.目标)

并得到以下错误

 prob += np.abs(lpSum((m[i] - (x1 * a1[i] + x2 * a2[i] + x3 * a3[i])) for i in date_index))类型错误:abs() 的操作数类型错误:'LpAffineExpression'

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

解决方案

一种方法是定义一个变量来表示您的总和,然后定义另一个变量来表示您可以约束为该总和的绝对值大于总和的正负值.

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

 from纸浆进口 LpVariable, LpProblem, lpSum, LpMinimize, LpStatus, value将 numpy 导入为 np将熊猫导入为 pddf = 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 = 列表(df.index)a1 = df['a1']a2 = df['a2']a3 = df['a3']m = df['m']index_var = LpVariable.dict(日期", date_index, lowBound = 0, upBound = 1, cat = 'Continuous')x1 = LpVariable('x1', lowBound = 0, upBound = 1, cat = 'Continuous')x2 = LpVariable('x2', lowBound = 0, upBound = 1, cat = 'Continuous')x3 = LpVariable('x3', lowBound = 0, upBound = 1, cat = 'Continuous')# 保存总和的变量sum_var = LpVariable('sum_var')abs_sum_var = LpVariable('abs_sum_var')# 客观的概率 += abs_sum_var# 定义 sum_var 和 abs_sum_var 的约束prob += sum_var == lpSum([(m[i] - (x1 * a1[i] + x2 * a2[i] + x3 * a3[i])) for i in date_index])概率 += abs_sum_var >= sum_var概率 += abs_sum_var >= -sum_var# 约束概率 += (x1 + x2 + x3 == 1)问题.解决()打印(LpStatus[prob.status])对于 prob.variables() 中的 v:打印(v.name,=",v.varValue)价值(概率.目标)

返回:

abs_sum_var = 0.0sum_var = -1.7462298e-10x1 = 0.94766587x2 = 0.052334135x3 = 0.0

abs_sum_var 和它应该是 1.7462298e-10 之间的小差异,我怀疑与求解器的约束容差有关 - 您可能是能够修改 - 请参阅更改 PuLP(对于 Python)的约束容限..>

I am trying to use absolute value in the objective function. I want to minimize the absolute value of the following equation

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

I tried the following

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, df.iloc[:,2]))
a3 = dict(zip(date_index, df.iloc[:,3]))
m = dict(zip(date_index, df.iloc[:, 0]))

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

x1 = LpVariable('x1', lowBound = 0, upBound = 1, cat = 'Continuous')
x2 = LpVariable('x2', lowBound = 0, upBound = 1, cat = 'Continuous')
x3 = LpVariable('x3', lowBound = 0, upBound = 1, 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)

and get the following error

    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'

How do I use the absolute value of the difference in the objective function?

解决方案

One way to do it is to define a variable to represent your sum, and then another variable to represent the absolute value of that sum which you can constrain to be larger than both the positive and negative value of the sum.

This constrains the absolute value varaible to be 'at least as large as the magnitude of the sum variable'. Note that it could be larger but this isn't a problem as the problem is set up to minimize this absolute-value-of-sum variable.

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', lowBound = 0, upBound = 1, cat = 'Continuous')
x2 = LpVariable('x2', lowBound = 0, upBound = 1, cat = 'Continuous')
x3 = LpVariable('x3', lowBound = 0, upBound = 1, 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)

Returns:

abs_sum_var = 0.0
sum_var = -1.7462298e-10
x1 = 0.94766587
x2 = 0.052334135
x3 = 0.0 

The small discrepency between the abs_sum_var and what it should be 1.7462298e-10, I suspect is to do with the constraint tolerance of the solver - which you might be able to modify - see change PuLP's (for Python) constraint tolerance.

这篇关于如何在python纸浆目标函数中使用绝对值?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆