from __future__ import print_function
from ortools.sat.python import cp_model
model = cp_model.CpModel()
boo_x_i_j = {}
for i in range(100):
for j in range(10):
boo_x_i_j[(i, j)] = model.NewBoolVar('x%d belongs to group %d' % (i, j))
e = model.NewIntVar(0, 5, 'epsilon')
values = [i + 1 for i in range(100)]
sum_of_values = sum(values)
average_value = sum_of_values / 10
for j in range(10):
model.Add(sum(boo_x_i_j[(i, j)] for i in range(100)) == 10)
for i in range(100):
model.Add(sum(boo_x_i_j[(i, j)] for j in range(10)) == 1)
for j in range(10):
model.Add(-e <= sum(boo_x_i_j[(i, j)]*values[i] for i in range(100)) -
average_value <= e)
model.Minimize(e)
solver = cp_model.CpSolver()
status = solver.Solve(model)
print('Optimal epsilon: %i' % solver.ObjectiveValue())
print('Statistics')
print(' - conflicts : %i' % solver.NumConflicts())
print(' - branches : %i' % solver.NumBranches())
print(' - wall time : %f s' % solver.WallTime())
groups = {}
for j in range(10):
groups[j] = []
for i in range(100):
for j in range(10):
if solver.Value(boo_x_i_j[(i, j)]):
groups[j].append(values[i])
for j in range(10):
print ('group %i: average = %0.2f [' % (j, sum(groups[j]) / 10.0), end='')
for v in groups[j]:
print(' %i' % v, end='')
print(' ]')
Displays:
Optimal epsilon: 0
Statistics
- conflicts : 2230
- branches : 13847
- wall time : 1.077324 s
group 0: average = 50.50 [ 5 6 19 26 27 77 83 84 87 91 ]
group 1: average = 50.50 [ 1 30 42 43 52 58 59 65 76 79 ]
group 2: average = 50.50 [ 7 13 38 51 53 55 56 63 81 88 ]
group 3: average = 50.50 [ 2 8 11 12 62 72 80 82 86 90 ]
group 4: average = 50.50 [ 3 4 9 17 18 69 94 95 97 99 ]
group 5: average = 50.50 [ 28 33 34 35 44 47 66 71 73 74 ]
group 6: average = 50.50 [ 14 20 21 23 25 46 68 92 96 100 ]
group 7: average = 50.50 [ 31 36 39 41 48 49 50 54 64 93 ]
group 8: average = 50.50 [ 22 32 37 40 45 57 60 67 70 75 ]
group 9: average = 50.50 [ 10 15 16 24 29 61 78 85 89 98 ]