【问题标题】:Split variables into groups, each constrained to hold a specific number of variables, while optimizing group sums towards specific values将变量分成组,每个组都限制为包含特定数量的变量,同时针对特定值优化组总和
【发布时间】:2022-11-16 04:40:34
【问题描述】:

我有许多变量,每个变量都分配了一个整数值。我需要将这些变量分成三组,每组预定义数量的变量,同时针对每组中预定义的值总和进行优化。每组总和应尽可能接近预定义值,但可以高于或低于预定义值。所有变量都应该使用,每个变量只能使用一次。

例如,我可能有 10 个变量...

Variable Value
A1 98
A2 20
A3 30
A4 50
A5 18
A6 34
A7 43
A8 21
A9 32
A10 54

...目标可能是创建三个组:

Group #Variables Sum optimized towards
X 6 200
Y 2 100
Z 2 100

所以 X 组应该包含 6 个变量,它们的总和应该尽可能接近 200 - 但我需要同时优化每个组。

我尝试设置PuLP 来执行此任务。我似乎找到了创建单个组的解决方案,但我无法弄清楚如何将变量分成组并根据每个组的总和优化分配。有没有办法做到这一点?

下面是我使用提供的变量生成第一组的代码。

from pulp import LpMaximize, LpMinimize, LpProblem, lpSum, LpVariable, PULP_CBC_CMD, value, LpStatus

keys = ["A1", "A2", "A3", "A4", "A5", "A6", "A7", "A8", "A9", "A10"]
data = [98,20,30,50,20,34,43,21,32,54]

problem_name = 'repex'

prob = LpProblem(problem_name, LpMaximize)

optiSum = 200 # Optimize towards this sum
variableCount = 6 # Number of variables that should be in the group

# Create decision variables
decision_variables = []
for i,n in enumerate(data):
    variable = i
    variable = LpVariable(str(variable), lowBound = 0, upBound = 1, cat= 'Binary')
    decision_variables.append(variable)


# Add constraints
sumConstraint = "" # Constraint on sum of data elements
for i, n in enumerate(decision_variables):
    formula = data[i]*n
    sumConstraint += formula

countConstraint = "" # Constrain on number of elements used
for i, n in enumerate(decision_variables):
        formula = n
        countConstraint += formula

prob += (sumConstraint <= optiSum)
prob += (countConstraint == variableCount)
prob += sumConstraint

# Solve
optimization_result = prob.solve(PULP_CBC_CMD(msg=0))
prob.writeLP(problem_name + ".lp" )
print("Status:", LpStatus[prob.status])
print("Optimal Solution to the problem: ", value(prob.objective))
print ("Individual decision_variables: ")
for v in prob.variables():
    print(v.name, "=", v.varValue)

产生以下输出:

Status: Optimal
Optimal Solution to the problem:  200.0
Individual decision_variables:
0 = 0.0
1 = 1.0
2 = 0.0
3 = 1.0
4 = 0.0
5 = 1.0
6 = 1.0
7 = 1.0
8 = 1.0
9 = 0.0

【问题讨论】:

  • 在您的示例中,A1 到 A10 是“变量”,还是它们为给定的问题实例定义了固定值?

标签: python mathematical-optimization modeling pulp


【解决方案1】:

这似乎是一个相当标准的“作业”问题。

z_ij 是一组二进制变量,表示对象i 是否分配给组j

然后,您的目标是最小化组总和与其目标值的偏差的绝对值 - 类似于(全部在伪代码中):

lpSum([abs_dev_j for j in groups])

然后您可以设置约束,以便正确设置绝对偏差变量:

for j in groups:
    abs_dev_j >= lpSum([z_ij*obj_i_val for all i in objects]) - target_j
    abs_dev_j >= target_j - lpSum([z_ij*obj_i_val for all i in objects])

然后您需要设置约束以确保每个组都选择了正确数量的成员:

for j in groups:
    lpSum([z_ij for all i in objects]) == n_objects_j

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-03-07
    • 1970-01-01
    • 2015-12-11
    • 1970-01-01
    相关资源
    最近更新 更多