Python纸浆约束-将贡献最大的任何一个变量的权重加倍

时间:2018-11-14 13:45:17

标签: python optimization linear-programming constraint-programming pulp

我正在尝试使用http://www.philipkalinda.com/ds9.html来设置约束优化。

prob = pulp.LpProblem('FantasyTeam', pulp.LpMaximize)

        decision_variables = []

        res = self.team_df
        # Set up the LP

        for rownum, row in res.iterrows():
            variable = str('x' + str(rownum))
            variable = pulp.LpVariable(str(variable), lowBound = 0, upBound = 1, cat= 'Integer') #make variables binary
            decision_variables.append(variable)

        print ("Total number of decision_variables: " + str(len(decision_variables)))


        total_points = ""


        for rownum, row in res.iterrows():
            for i, player in enumerate(decision_variables):
                if rownum == i:
                    formula = row['TotalPoint']* player
            total_points += formula

        prob += total_points
        print ("Optimization function: " + str(total_points))

但是,上面的方法创建了一个优化,如果x1 = X1,x2 = X2 ....和xn = Xn所获得的积分,它将最大化 x1 * X1 + x2 * X2 + ..... + xn * XN。 xi是XI变量赢得的积分。但是,就我而言,我需要将获得最高积分的变量的积分加倍。我该如何设置?

最大化 OBJ:38.1 x0 + 52.5 x1 + 31.3 x10 + 7.8 x11 + 42.7 x12 + 42.3 x13 + 4.7 x14  + 49.5 x15 + 21.2 x16 + 11.8 x17 + 1.4 x18 + 3.2 x2 + 20.8 x3 + 1.2 x4  + 24 x5 + 25.9 x6 + 27.8 x7 + 6.2 x8 + 41 x9

当我最大化总和x1时会掉线,但是当我最大化并获得最高得分的人时,它应该在那里

以下是我使用的限制条件:-

Subject To
_C1: 10.5 x0 + 21.5 x1 + 17 x10 + 7.5 x11 + 11.5 x12 + 12 x13 + 7 x14 + 19 x15
 + 10.5 x16 + 5.5 x17 + 6.5 x18 + 6.5 x2 + 9.5 x3 + 9 x4 + 12 x5 + 12 x6
 + 9.5 x7 + 7 x8 + 14 x9 <= 100
_C10: x12 + x2 + x6 >= 1
_C11: x10 + x11 + x17 + x3 <= 4
_C12: x10 + x11 + x17 + x3 >= 1
_C13: x0 + x10 + x11 + x12 + x13 + x14 + x15 + x18 + x2 <= 5
_C14: x0 + x10 + x11 + x12 + x13 + x14 + x15 + x18 + x2 >= 3
_C15: x1 + x16 + x17 + x3 + x4 + x5 + x6 + x7 + x8 + x9 <= 5
_C16: x1 + x16 + x17 + x3 + x4 + x5 + x6 + x7 + x8 + x9 >= 3
_C2: x0 + x1 + x10 + x11 + x12 + x13 + x14 + x15 + x16 + x17 + x18 + x2 + x3
 + x4 + x5 + x6 + x7 + x8 + x9 = 8
_C3: x0 + x14 + x16 + x5 <= 4
_C4: x0 + x14 + x16 + x5 >= 1
_C5: x15 + x18 + x4 + x7 + x8 <= 4
_C6: x15 + x18 + x4 + x7 + x8 >= 1
_C7: x1 + x13 + x9 <= 4
_C8: x1 + x13 + x9 >= 1
_C9: x12 + x2 + x6 <= 4

自然地,最大化A + B + C + D不会最大化max(2A + B + C + D,A + 2B + C + D,A + B + 2C + D,A + B + C + 2D )

1 个答案:

答案 0 :(得分:0)

我将回答我认为您要提出的问题,如果我错了,您可以纠正我。我对您的问题的理解是:

  • 我有一系列二进制变量x0...xN,如果包含一个变量,它将获得一些分数。如果不包括在内,则不会获得任何积分。
  • 有一些约束适用于选择
  • 如果(且仅当)选择了一个变量,并且(仅当且仅当)选择的变量获得了最高分时,该特定变量才获得了双分。
  • 目标是使总分最大化,包括得分最高的得分翻倍。

假设这是您的问题,这是一个虚拟的示例。基本上,我们为每个变量添加一个辅助二进制变量,当变量得分最高时(如果且仅当),该变量为true:

from pulp import *

n_vars = 4
idxs = range(n_vars)
points = [2.0, 3.0, 4.0, 5.0]

prob = pulp.LpProblem('FantasyTeam', pulp.LpMaximize)

# Variables
x = LpVariable.dicts('x', idxs, cat='Binary')
x_highest_score = LpVariable.dicts('x_highest_score', idxs, cat='Binary')

# Objective
prob += lpSum([points[i]*(x[i] + x_highest_score[i]) for i in idxs])

# Constraints
# Exactly one item has highest score:
prob += lpSum([x_highest_score[i] for i in idxs]) == 1

# If a score is to be highest, it has to be chosen
for i in idxs:
    prob += x_highest_score[i] <= x[i]

# And some selection constraints:
prob += x[0] + x[1] + x[2] + 1.5*x[3] <= 3
prob += x[0] + x[2] + 3*x[3] <= 3
prob += x[0] + x[1] + x[2] + 2*x[3] <= 3
# etc...

# Solve problem
prob.solve()

# Get soln
x_soln = [x[i].varValue for i in idxs]
x_highest_soln = [x_highest_score[i].varValue for i in idxs]

# And print the outputs
print (("Status: "), LpStatus[prob.status])
print ("Total points: ", value(prob.objective))
print ("x = ", x_soln)
print ("x_highest_soln = ", x_highest_soln)

这应该返回以下内容:

Status:  Optimal
Total points:  13.0
x =  [0.0, 1.0, 0.0, 1.0]
x_highest_soln =  [0.0, 0.0, 0.0, 1.0]

如果关闭双点选项,则将约束更改为以下内容:

prob += lpSum([x_highest_score[i] for i in idxs]) == 1

I.E。没有一个分数最高,您会发现做出了不同的选择。