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



我正在尝试使用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并不能最大化最大值(2A+B+C+D,A+2B+C+D,A+B+2C+D,A+B+C+2D(

我要回答你问的问题,如果我错了,你可以纠正我。我对你的问题的理解是:

  • 我有一系列二进制变量x0...xN,如果包含一个变量,则接收一些点。如果不包括在内,则不得分
  • 有一些约束适用于选择
  • 如果(且仅当(选择了一个变量,并且如果(且只有当(该变量是获得最高点数的所选变量,则该特定变量将获得双倍点数
  • 目标是最大限度地提高总分,包括将得分最高的分数加倍

假设这是你的问题,这里有一个这样做的伪例子。基本上,我们为每个变量添加一个辅助二进制变量,当(如果且仅当(该变量得分最多时,该变量为真:

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

也就是说,没有一个分数最高,你会发现有不同的选择。

最新更新