Is pulp.lpDot(a,n) not equivalent to pulp.lpSum([a[i] * n[i] for i in range(N)])?

Question:

I have a decision variable vector n, and a is a constant vector. What confuses me is why lpDot(a,n) is not equivalent to lpSum([a[i] * n[i] for i in range(N)]) in a constraint?

Here is the code:

import pulp
import numpy as np

# params
N = 2
a = [3.5, 2]
w = [0.6, 0.4]

# lpSum
# Define the problem as a minimization problem
problem = pulp.LpProblem("lpSum", pulp.LpMinimize)

# Define decision variables
t = pulp.LpVariable.dicts('t', range(N), cat='Continuous')
n = pulp.LpVariable.dicts('n', range(N), lowBound=0, cat='Integer')

# Define the objective function
problem += pulp.lpSum(t)

# Define the constraints
problem += t[0] >= a[0] * n[0] - 6
problem += t[0] >= 6 - a[0] * n[0]
problem += t[1] >= a[1] * n[1] - 4
problem += t[1] >= 4 - a[1] * n[1]

problem += pulp.lpSum([a[i] * n[i] for i in range(N)]) <= 10

# Solve the problem
status = problem.solve()

# Convert result to numpy array
n = np.array([n[i].varValue for i in range(N)])

# Print the optimal solution
print("Optimal Solution with lpSum:")
print(n)


# lpDot
# Define the problem as a minimization problem
problem = pulp.LpProblem("lpDot", pulp.LpMinimize)

# Define decision variables
t = pulp.LpVariable.dicts('t', range(N), cat='Continuous')
n = pulp.LpVariable.dicts('n', range(N), lowBound=0, cat='Integer')

# Define the objective function
problem += pulp.lpSum(t)

# Define the constraints
problem += t[0] >= a[0] * n[0] - 6
problem += t[0] >= 6 - a[0] * n[0]
problem += t[1] >= a[1] * n[1] - 4
problem += t[1] >= 4 - a[1] * n[1]

problem += pulp.lpDot(a, n) <= 10

# Solve the problem
status = problem.solve()

# Convert result to numpy array
n = np.array([n[i].varValue for i in range(N)])

# Print the optimal solution
print("Optimal Solution with lpDot:")
print(n)

Both report "Optimal solution found".
With lpSum it correctly yields n = [1, 2], while with lpDot it yields n = [2, 2] which violates the last constraint IMO.

Asked By: Yfiua

||

Answers:

They’re equivalent, you’re just writing your constraint incorrectly. n is a dictionary, so

problem += pulp.lpDot(a, n.values()) <= 10

This produces

Optimal Solution with lpDot:
[1. 2.]
Answered By: Reinderien