Python pulp constraint - Doubling the weight of any one variable which contributes the most
I am trying to use http://www.philipkalinda.com/ds9.html to set up a constrained optimisation.
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))
The above, however, creates an optimisation where if points earned by x1 = X1, x2=X2.... and xn=Xn, it maximises
x1*X1 + x2*X2 +..... + xn*XN. Here xi is the points earned by the XI variable. However, in my case, I need to double the points for the variable that earns the most points. How do I set this up?
Maximize
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
When I maximise the sum x1 gets dropped but when I maximise with the top guy taking double points, it should be there
Here are the constraints I am using:-
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
Naturally, maximising A + B + C + D doesn't maximise max(2A+B+C+D, A+2B+C+D, A+B+2C+D, A+B+C+2D)
python optimization linear-programming constraint-programming pulp
|
show 3 more comments
I am trying to use http://www.philipkalinda.com/ds9.html to set up a constrained optimisation.
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))
The above, however, creates an optimisation where if points earned by x1 = X1, x2=X2.... and xn=Xn, it maximises
x1*X1 + x2*X2 +..... + xn*XN. Here xi is the points earned by the XI variable. However, in my case, I need to double the points for the variable that earns the most points. How do I set this up?
Maximize
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
When I maximise the sum x1 gets dropped but when I maximise with the top guy taking double points, it should be there
Here are the constraints I am using:-
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
Naturally, maximising A + B + C + D doesn't maximise max(2A+B+C+D, A+2B+C+D, A+B+2C+D, A+B+C+2D)
python optimization linear-programming constraint-programming pulp
where are the constraints you are using? Maybe you can force x1 to be the one that earns most points
– juvian
Nov 14 '18 at 14:26
Have put in the constraints
– Arc
Nov 14 '18 at 14:40
I don´t see where <= 100 comes from your code
– juvian
Nov 14 '18 at 15:42
That part is further down in the code. All those constraints have been created later in the code.
– Arc
Nov 14 '18 at 15:44
Is x1 is not the one that earns most points as it gets multiplied by 21.5? or the points is the result of 21.5 * x1 ?
– juvian
Nov 14 '18 at 15:50
|
show 3 more comments
I am trying to use http://www.philipkalinda.com/ds9.html to set up a constrained optimisation.
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))
The above, however, creates an optimisation where if points earned by x1 = X1, x2=X2.... and xn=Xn, it maximises
x1*X1 + x2*X2 +..... + xn*XN. Here xi is the points earned by the XI variable. However, in my case, I need to double the points for the variable that earns the most points. How do I set this up?
Maximize
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
When I maximise the sum x1 gets dropped but when I maximise with the top guy taking double points, it should be there
Here are the constraints I am using:-
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
Naturally, maximising A + B + C + D doesn't maximise max(2A+B+C+D, A+2B+C+D, A+B+2C+D, A+B+C+2D)
python optimization linear-programming constraint-programming pulp
I am trying to use http://www.philipkalinda.com/ds9.html to set up a constrained optimisation.
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))
The above, however, creates an optimisation where if points earned by x1 = X1, x2=X2.... and xn=Xn, it maximises
x1*X1 + x2*X2 +..... + xn*XN. Here xi is the points earned by the XI variable. However, in my case, I need to double the points for the variable that earns the most points. How do I set this up?
Maximize
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
When I maximise the sum x1 gets dropped but when I maximise with the top guy taking double points, it should be there
Here are the constraints I am using:-
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
Naturally, maximising A + B + C + D doesn't maximise max(2A+B+C+D, A+2B+C+D, A+B+2C+D, A+B+C+2D)
python optimization linear-programming constraint-programming pulp
python optimization linear-programming constraint-programming pulp
edited Nov 14 '18 at 15:57
Arc
asked Nov 14 '18 at 13:45
ArcArc
77442247
77442247
where are the constraints you are using? Maybe you can force x1 to be the one that earns most points
– juvian
Nov 14 '18 at 14:26
Have put in the constraints
– Arc
Nov 14 '18 at 14:40
I don´t see where <= 100 comes from your code
– juvian
Nov 14 '18 at 15:42
That part is further down in the code. All those constraints have been created later in the code.
– Arc
Nov 14 '18 at 15:44
Is x1 is not the one that earns most points as it gets multiplied by 21.5? or the points is the result of 21.5 * x1 ?
– juvian
Nov 14 '18 at 15:50
|
show 3 more comments
where are the constraints you are using? Maybe you can force x1 to be the one that earns most points
– juvian
Nov 14 '18 at 14:26
Have put in the constraints
– Arc
Nov 14 '18 at 14:40
I don´t see where <= 100 comes from your code
– juvian
Nov 14 '18 at 15:42
That part is further down in the code. All those constraints have been created later in the code.
– Arc
Nov 14 '18 at 15:44
Is x1 is not the one that earns most points as it gets multiplied by 21.5? or the points is the result of 21.5 * x1 ?
– juvian
Nov 14 '18 at 15:50
where are the constraints you are using? Maybe you can force x1 to be the one that earns most points
– juvian
Nov 14 '18 at 14:26
where are the constraints you are using? Maybe you can force x1 to be the one that earns most points
– juvian
Nov 14 '18 at 14:26
Have put in the constraints
– Arc
Nov 14 '18 at 14:40
Have put in the constraints
– Arc
Nov 14 '18 at 14:40
I don´t see where <= 100 comes from your code
– juvian
Nov 14 '18 at 15:42
I don´t see where <= 100 comes from your code
– juvian
Nov 14 '18 at 15:42
That part is further down in the code. All those constraints have been created later in the code.
– Arc
Nov 14 '18 at 15:44
That part is further down in the code. All those constraints have been created later in the code.
– Arc
Nov 14 '18 at 15:44
Is x1 is not the one that earns most points as it gets multiplied by 21.5? or the points is the result of 21.5 * x1 ?
– juvian
Nov 14 '18 at 15:50
Is x1 is not the one that earns most points as it gets multiplied by 21.5? or the points is the result of 21.5 * x1 ?
– juvian
Nov 14 '18 at 15:50
|
show 3 more comments
1 Answer
1
active
oldest
votes
I'm going to answer the question I think you're asking and you can correct me if I'm wrong. My understanding of your question is:
- I have a series of binary variables
x0...xN
, and if a variable is included is receives some points. If it is not included it receives no points. - There are some constraints which apply to the selection
- If (and only if) a variable is selected and if (and only if) it is the chosen variable which receives the highest number of points, then that particular variable gets double points
- The objective is to maximize the total points including the doubling of the highest scoring one.
Assuming that's your question here is a dummy example that does that. Basically we add an auxiliary binary variable for each variable which is true iff (if and only if) that variable scores the most number of points:
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)
This should return the following:
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]
If you turn off the double-points option, by changing the constraint to the following:
prob += lpSum([x_highest_score[i] for i in idxs]) == 1
I.E. none scores highest, you'll find a different set of choices is made.
add a comment |
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53301689%2fpython-pulp-constraint-doubling-the-weight-of-any-one-variable-which-contribut%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
I'm going to answer the question I think you're asking and you can correct me if I'm wrong. My understanding of your question is:
- I have a series of binary variables
x0...xN
, and if a variable is included is receives some points. If it is not included it receives no points. - There are some constraints which apply to the selection
- If (and only if) a variable is selected and if (and only if) it is the chosen variable which receives the highest number of points, then that particular variable gets double points
- The objective is to maximize the total points including the doubling of the highest scoring one.
Assuming that's your question here is a dummy example that does that. Basically we add an auxiliary binary variable for each variable which is true iff (if and only if) that variable scores the most number of points:
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)
This should return the following:
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]
If you turn off the double-points option, by changing the constraint to the following:
prob += lpSum([x_highest_score[i] for i in idxs]) == 1
I.E. none scores highest, you'll find a different set of choices is made.
add a comment |
I'm going to answer the question I think you're asking and you can correct me if I'm wrong. My understanding of your question is:
- I have a series of binary variables
x0...xN
, and if a variable is included is receives some points. If it is not included it receives no points. - There are some constraints which apply to the selection
- If (and only if) a variable is selected and if (and only if) it is the chosen variable which receives the highest number of points, then that particular variable gets double points
- The objective is to maximize the total points including the doubling of the highest scoring one.
Assuming that's your question here is a dummy example that does that. Basically we add an auxiliary binary variable for each variable which is true iff (if and only if) that variable scores the most number of points:
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)
This should return the following:
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]
If you turn off the double-points option, by changing the constraint to the following:
prob += lpSum([x_highest_score[i] for i in idxs]) == 1
I.E. none scores highest, you'll find a different set of choices is made.
add a comment |
I'm going to answer the question I think you're asking and you can correct me if I'm wrong. My understanding of your question is:
- I have a series of binary variables
x0...xN
, and if a variable is included is receives some points. If it is not included it receives no points. - There are some constraints which apply to the selection
- If (and only if) a variable is selected and if (and only if) it is the chosen variable which receives the highest number of points, then that particular variable gets double points
- The objective is to maximize the total points including the doubling of the highest scoring one.
Assuming that's your question here is a dummy example that does that. Basically we add an auxiliary binary variable for each variable which is true iff (if and only if) that variable scores the most number of points:
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)
This should return the following:
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]
If you turn off the double-points option, by changing the constraint to the following:
prob += lpSum([x_highest_score[i] for i in idxs]) == 1
I.E. none scores highest, you'll find a different set of choices is made.
I'm going to answer the question I think you're asking and you can correct me if I'm wrong. My understanding of your question is:
- I have a series of binary variables
x0...xN
, and if a variable is included is receives some points. If it is not included it receives no points. - There are some constraints which apply to the selection
- If (and only if) a variable is selected and if (and only if) it is the chosen variable which receives the highest number of points, then that particular variable gets double points
- The objective is to maximize the total points including the doubling of the highest scoring one.
Assuming that's your question here is a dummy example that does that. Basically we add an auxiliary binary variable for each variable which is true iff (if and only if) that variable scores the most number of points:
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)
This should return the following:
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]
If you turn off the double-points option, by changing the constraint to the following:
prob += lpSum([x_highest_score[i] for i in idxs]) == 1
I.E. none scores highest, you'll find a different set of choices is made.
answered Nov 19 '18 at 20:58
kabdullakabdulla
2,1071724
2,1071724
add a comment |
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53301689%2fpython-pulp-constraint-doubling-the-weight-of-any-one-variable-which-contribut%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
where are the constraints you are using? Maybe you can force x1 to be the one that earns most points
– juvian
Nov 14 '18 at 14:26
Have put in the constraints
– Arc
Nov 14 '18 at 14:40
I don´t see where <= 100 comes from your code
– juvian
Nov 14 '18 at 15:42
That part is further down in the code. All those constraints have been created later in the code.
– Arc
Nov 14 '18 at 15:44
Is x1 is not the one that earns most points as it gets multiplied by 21.5? or the points is the result of 21.5 * x1 ?
– juvian
Nov 14 '18 at 15:50