-
Notifications
You must be signed in to change notification settings - Fork 0
/
basketball_puzzle.py
105 lines (90 loc) · 2.91 KB
/
basketball_puzzle.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
from pulp import *
# define data
players = ["Bill", "Ernie", "Oscar", "Sammy", "Tony"]
nicknames = ["Slats", "Stretch", "Tiny", "Tower", "Tree"]
heights = [6, 6.1, 6.3, 6.5, 6.6]
# create problem
prob = LpProblem("B_Balls", LpMinimize)
# define variables
x = LpVariable.dicts("x", (players, nicknames, heights), cat=LpBinary)
# add dummy objective function
prob += 0
# each player has a unique nickame and height
for p in players:
prob += lpSum(x[p][n][h] for n in nicknames for h in heights) == 1
# each nickname has a unique player and height
for n in nicknames:
prob += lpSum(x[p][n][h] for p in players for h in heights) == 1
# each height has a unique player and nickname
for h in heights:
prob += lpSum(x[p][n][h] for n in nicknames for p in players) == 1
# Oscar is taller than Tree
for n in nicknames:
for h in heights:
prob += x["Oscar"][n][h] <= lpSum(
x[p]["Tree"][k] for p in players for k in heights if k < h
)
# Tree is taller than Tony
for p in players:
for h in heights:
prob += x[p]["Tree"][h] <= lpSum(
x["Tony"][n][k] for n in nicknames for k in heights if k < h
)
# Bill is taller than Sammy
for n in nicknames:
for h in heights:
prob += x["Bill"][n][h] <= lpSum(
x["Sammy"][m][k] for m in nicknames for k in heights if k < h
)
# Bill is shorter than Slats
for n in nicknames:
for h in heights:
prob += x["Bill"][n][h] <= lpSum(
x[p]["Slats"][k] for p in players for k in heights if k > h
)
# Tony is not Tiny
for h in heights:
prob += x["Tony"]["Tiny"][h] == 0
# Stretch is taller than Oscar
for p in players:
for h in heights:
prob += x[p]["Stretch"][h] <= lpSum(
x["Oscar"][n][k] for n in nicknames for k in heights if k < h
)
# Stretch is not the tallest
for p in players:
prob += x[p]["Stretch"][6.6] == 0
# solve problem
# prob.writeLP("basketball.lp")
k = 1
while True:
print()
print("solution %s" % k)
k += 1
# prob.solve(pulp.PULP_CBC_CMD(msg=0))
prob.solve(CPLEX_CMD(msg=1))
print("Status:", LpStatus[prob.status])
# The solution is printed if it was deemed "optimal" i.e met the constraints
if LpStatus[prob.status] == "Optimal":
# print solution
for p in players:
for n in nicknames:
for h in heights:
if value(x[p][n][h]) > 0.1:
print(p, n, h)
# The constraint is added that the same solution cannot be returned again
prob += (
lpSum(
[
x[p][n][h]
for p in players
for n in nicknames
for h in heights
if value(x[p][n][h]) > 0.1
]
)
<= 5 - 1
)
# If a new optimal solution cannot be found, we end the program
else:
break