I have the following problem I want to solve:
We have N items with a price and ID, and M categories, where each category has a total balance / limit on the sum of prices of items with that category. In the end, we want each item to be assigned to ONLY ONE category, and each category doesn't exceed its total balance / limit.
Let:
- xij be a binary decision variable where xij = 1 if item i is assigned to category j, and xij = 0 otherwise.
- pi be the price of item i.
- cj be the price limit of category j.
The constraints are as follows:
Each item must be assigned to exactly one category.
The total price sum of items assigned to each category must not exceed the category limit.
I have created the linear programming code using PuLP python module:
def assign_items_to_categories(items, categories, category_limits):
n = len(items)
m = len(categories)
model = pulp.LpProblem("Assign_Items_to_Categories")
# Define decision variables
x = pulp.LpVariable.dicts("x", ((i, j) for i in range(n) for j in range(m)), cat='Binary')
# Constraints
# 1st constraint
for i in range(n):
model += pulp.lpSum(x[(i, j)] for j in range(m)) == 1
# 2nd constraint
for j in range(m):
model += pulp.lpSum(items[i]["price"] * x[(i, j)] for i in range(n)) <= category_limits[categories[j]]
# Solve the problem
model.solve()
model.writeLP('model.lp')
# Extract the solution
assignment_result = {category: [] for category in categories}
for i in range(n):
for j in range(m):
if pulp.value(x[(i, j)]) == 1:
valid = True
assignment_result[categories[j]].append(items[i])
return assignment_result
items = [{
"id": "0892ADA75MH1-00",
"price": 0.0
},
{
"id": "3WR21137BHJ81",
"price": 2616023.02
},
{
"id": "3137344ABHEX1",
"price": 367419.34
},
{
"id": "2312312AAWW31-1",
"price": 676545.32
},
{
"id": "313243A8WTQV1",
"price": 228518.29
}]
categories = ['APPLE', 'META', 'TESLA', 'NETFLIX', 'GOOGLE']
cateogory_limit =
{
"APPLE": 2754707.42,
"META": 43002.21,
"TESLA": 240301.31,
"NETFLIX": 500432.54,
"GOOGLE": 3100233.41,
},
However, the result always indicated that the problem is infeasible. I believe that the constraint I coded reflected to the constraint that was mentioned in the instructions. Any suggestions to improve this code will be very helpful!
Edit: I have added some sample data for better reference.
One crude but fast objective minimizing difference between category allocations is to minimize the maximum category subtotal. For very few items it doesn't work very well; for many items it works fine: