You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python PuLP优化问题:如何正确编写最小化Aisle销售额与平均值绝对偏差总和的目标函数

Fixing Your PuLP Aisle Optimization Problem

Let's walk through the problems in your code and fix them to get a working optimization model. The core issues are with how you've defined variables, structured constraints, and handled the absolute deviation in the objective function—linear programming can't directly use absolute values, so we need a workaround for that.

Key Issues in Your Original Code

  • Incorrect Variable Definition: Your AislePick variable assigns each product an integer (0 or 1) for the aisle, but you can't use conditional checks like ais == aisle in constraints because PuLP variables aren't evaluated until solving. We need binary variables to track product-aisle assignments explicitly.
  • Absolute Deviation Handling: You can't directly use |x - avg| in a linear objective. Instead, we introduce auxiliary variables to represent positive and negative deviations, then minimize their sum.
  • Invalid Objective Function: Using value() and itertools.groupby in the objective is wrong—these operate on actual values, but PuLP needs linear expressions of variables to build the model.

Corrected Code

import pulp

# Product data
products = ['Fruit Loops', 'Frosted Flakes', 'Cocoa Pebbles', 'Fruitty Pebbles', 'Corn Flakes', 'Cheerios']
sales = {'Fruit Loops': 20, 'Frosted Flakes': 15, 'Cocoa Pebbles': 8, 'Fruitty Pebbles': 9, 'Corn Flakes': 12, 'Cheerios': 6}
shelves = {'Fruit Loops': 2, 'Frosted Flakes': 1, 'Cocoa Pebbles': 1, 'Fruitty Pebbles': 1, 'Corn Flakes': 2, 'Cheerios': 1}

# Problem setup
Num_of_Aisles = 2
Max_Shelves_Aisle = 4
total_sales = sum(sales.values())
avg_sales = total_sales / Num_of_Aisles

# Initialize problem
problem = pulp.LpProblem('AisleOptimization', pulp.LpMinimize)

# Binary variables: AislePick[prod][aisle] = 1 if product is assigned to aisle, 0 otherwise
AislePick = pulp.LpVariable.dicts(
    "AisleAssignment",
    [(prod, aisle) for prod in products for aisle in range(Num_of_Aisles)],
    cat='Binary'
)

# Auxiliary variables for absolute deviation: d_plus[aisle] = positive deviation, d_minus[aisle] = negative deviation
d_plus = pulp.LpVariable.dicts("PositiveDeviation", range(Num_of_Aisles), lowBound=0)
d_minus = pulp.LpVariable.dicts("NegativeDeviation", range(Num_of_Aisles), lowBound=0)

# Objective: Minimize sum of absolute deviations (sum of d_plus + d_minus)
problem += pulp.lpSum([d_plus[aisle] + d_minus[aisle] for aisle in range(Num_of_Aisles)]), "TotalAbsoluteDeviation"

# Constraints
# 1. Each product is assigned to exactly one aisle
for prod in products:
    problem += pulp.lpSum([AislePick[(prod, aisle)] for aisle in range(Num_of_Aisles)]) == 1, f"Assign_{prod}"

# 2. Each aisle's total shelf usage doesn't exceed max
for aisle in range(Num_of_Aisles):
    problem += pulp.lpSum([shelves[prod] * AislePick[(prod, aisle)] for prod in products]) <= Max_Shelves_Aisle, f"ShelfLimit_Aisle{aisle}"

# 3. Link aisle sales to average and deviation variables
for aisle in range(Num_of_Aisles):
    aisle_sales = pulp.lpSum([sales[prod] * AislePick[(prod, aisle)] for prod in products])
    # aisle_sales - avg_sales = d_plus[aisle] - d_minus[aisle]
    problem += aisle_sales - avg_sales == d_plus[aisle] - d_minus[aisle], f"DeviationLink_Aisle{aisle}"

# Solve the problem
problem.solve()

# Print results
print(f"Status: {pulp.LpStatus[problem.status]}")
print(f"Total Absolute Deviation: {pulp.value(problem.objective)}")

# Print assignments
for aisle in range(Num_of_Aisles):
    assigned_products = [prod for prod in products if pulp.value(AislePick[(prod, aisle)]) == 1]
    aisle_total_sales = sum(sales[prod] for prod in assigned_products)
    aisle_total_shelves = sum(shelves[prod] for prod in assigned_products)
    print(f"\nAisle {aisle}:")
    print(f"  Products: {', '.join(assigned_products)}")
    print(f"  Total Sales: {aisle_total_sales}")
    print(f"  Total Shelves Used: {aisle_total_shelves}")

Explanation of Changes

  • Binary Assignment Variables: AislePick[(prod, aisle)] makes it clear which product goes to which aisle, and lets us build linear constraints without conditional logic.
  • Deviation Variables: By splitting the absolute deviation into d_plus (how much an aisle's sales exceed the average) and d_minus (how much they fall short), we convert the non-linear absolute value into a linear expression the solver can handle.
  • Proper Constraints: We ensure each product is assigned exactly once, and each aisle's shelf limit is respected using linear sums of variables multiplied by their shelf counts.

Expected Output

When you run this code, you should get an optimal solution with a total absolute deviation of 6 (matching your example), and the assignment you described:

  • Aisle 0: Fruit Loops, Corn Flakes (sales 32, shelves 4)
  • Aisle 1: Frosted Flakes, Cocoa Pebbles, Fruitty Pebbles, Cheerios (sales 38, shelves 4)

内容的提问来源于stack exchange,提问作者Bo Anderson

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.30 19:07:31