how can i use the absolute value in a python pulp 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.

CLICK HERE to find out more related problems solutions.

Leave a Comment

Your email address will not be published.

Scroll to Top