''' Problem at hand: Suppose we are in a farm and in a pen we see 56 legs and 20 heads of cows and chickens. Then, how many cows and how many chickens are we seeing? ''' from ortools.constraint_solver import pywrapcp solver = pywrapcp.Solver('Farm') # this constraints restrict the amount of heads cows = solver.IntVar(0, 20, 'Cows') chicks = solver.IntVar(0, 20, 'Chickens') # with this, we can start adding relationships between variables solver.Add((cows * 4) + (chicks * 2) == 56) solver.Add((cows * 1) + (chicks * 1) == 20) # configure solver decision_builder = solver.Phase([cows, chicks], solver.CHOOSE_FIRST_UNBOUND, solver.ASSIGN_MIN_VALUE) # Solve the problem! solver.Solve(decision_builder) # Problem solved, we hope solution_count = 0 while solver.NextSolution(): solution_count += 1 print(f'Solution #{solution_count}') print(f'I see {cows.Value()} cows and {chicks.Value()} chickens') print(f'There are {cows.Value() + chicks.Value()} heads in total')
def main(): # Create the solver. solver = pywrapcp.Solver('Problem') # # data # N = 5 # the items for each bid items = [ [0, 1], # A,B [0, 2], # A, C [1, 3], # B,D [1, 2, 3], # B,C,D [0] # A ] # collect the bids for each item items_t = defaultdict(list) # [items_t.setdefault(j,[]).append(i) for i in range(N) for j in items[i] ] # nicer: [items_t[j].append(i) for i in range(N) for j in items[i]] bid_amount = [10, 20, 30, 40, 14] # # declare variables # X = [solver.BoolVar("x%i" % i) for i in range(N)] obj = solver.IntVar(0, 100, 'obj') # # constraints # solver.Add(obj == solver.ScalProd(X, bid_amount)) for item in items_t: solver.Add(solver.Sum([X[bid] for bid in items_t[item]]) <= 1) # objective objective = solver.Maximize(obj, 1) # # solution and search # solution = solver.Assignment() solution.Add(X) solution.Add(obj) # db: DecisionBuilder db = solver.Phase(X, solver.CHOOSE_FIRST_UNBOUND, solver.ASSIGN_MIN_VALUE) solver.NewSearch(db, [objective]) num_solutions = 0 while solver.NextSolution(): print "X:", [X[i].Value() for i in range(N)] print "obj:", obj.Value() print num_solutions += 1 solver.EndSearch() print print "num_solutions:", num_solutions print "failures:", solver.Failures() print "branches:", solver.Branches() print "WallTime:", solver.WallTime()
def main(n=16, num_sets=2): # Create the solver. solver = pywrapcp.Solver("Set partition") # # data # print("n:", n) print("num_sets:", num_sets) print() # Check sizes assert n % num_sets == 0, "Equal sets is not possible." # # variables # # the set a = {} for i in range(num_sets): for j in range(n): a[i, j] = solver.IntVar(0, 1, "a[%i,%i]" % (i, j)) a_flat = [a[i, j] for i in range(num_sets) for j in range(n)] # # constraints # # partition set partition_sets(a, num_sets, n) for i in range(num_sets): for j in range(i, num_sets): # same cardinality solver.Add( solver.Sum([a[i, k] for k in range(n)]) == solver.Sum( [a[j, k] for k in range(n)])) # same sum solver.Add( solver.Sum([k * a[i, k] for k in range(n)]) == solver.Sum( [k * a[j, k] for k in range(n)])) # same sum squared solver.Add( solver.Sum([(k * a[i, k]) * (k * a[i, k]) for k in range(n)]) == solver.Sum([(k * a[j, k]) * (k * a[j, k]) for k in range(n)])) # symmetry breaking for num_sets == 2 if num_sets == 2: solver.Add(a[0, 0] == 1) # # search and result # db = solver.Phase(a_flat, solver.INT_VAR_DEFAULT, solver.INT_VALUE_DEFAULT) solver.NewSearch(db) num_solutions = 0 while solver.NextSolution(): a_val = {} for i in range(num_sets): for j in range(n): a_val[i, j] = a[i, j].Value() sq = sum([(j + 1) * a_val[0, j] for j in range(n)]) print("sums:", sq) sq2 = sum([((j + 1) * a_val[0, j])**2 for j in range(n)]) print("sums squared:", sq2) for i in range(num_sets): if sum([a_val[i, j] for j in range(n)]): print(i + 1, ":", end=' ') for j in range(n): if a_val[i, j] == 1: print(j + 1, end=' ') print() print() num_solutions += 1 solver.EndSearch() print() print("num_solutions:", num_solutions) print("failures:", solver.Failures()) print("branches:", solver.Branches()) print("WallTime:", solver.WallTime())
def main(): # Create the solver. solver = pywrapcp.Solver('Marathon') # # data # n = 6 runners_str = [ 'Dominique', 'Ignace', 'Naren', 'Olivier', 'Philippe', 'Pascal' ] # # declare variables # runners = [solver.IntVar(1, n, 'runners[%i]' % i) for i in range(n)] Dominique, Ignace, Naren, Olivier, Philippe, Pascal = runners # # constraints # solver.Add(solver.AllDifferent(runners)) # a: Olivier not last solver.Add(Olivier != n) # b: Dominique, Pascal and Ignace before Naren and Olivier solver.Add(Dominique < Naren) solver.Add(Dominique < Olivier) solver.Add(Pascal < Naren) solver.Add(Pascal < Olivier) solver.Add(Ignace < Naren) solver.Add(Ignace < Olivier) # c: Dominique better than third solver.Add(Dominique < 3) # d: Philippe is among the first four solver.Add(Philippe <= 4) # e: Ignace neither second nor third solver.Add(Ignace != 2) solver.Add(Ignace != 3) # f: Pascal three places earlier than Naren solver.Add(Pascal + 3 == Naren) # g: Neither Ignace nor Dominique on fourth position solver.Add(Ignace != 4) solver.Add(Dominique != 4) # # solution and search # db = solver.Phase(runners, solver.CHOOSE_MIN_SIZE_LOWEST_MIN, solver.ASSIGN_CENTER_VALUE) solver.NewSearch(db) num_solutions = 0 while solver.NextSolution(): num_solutions += 1 runners_val = [runners[i].Value() for i in range(n)] print 'runners:', runners_val print "Places:" for i in range(1, n + 1): for j in range(n): if runners_val[j] == i: print "%i: %s" % (i, runners_str[j]) print print 'num_solutions:', num_solutions print 'failures:', solver.Failures() print 'branches:', solver.Branches() print 'WallTime:', solver.WallTime(), 'ms'
def main(n=8): # Create the solver. solver = pywrapcp.Solver('n-queens') # # data # # n = 8 # size of board (n x n) # declare variables q = [solver.IntVar(0, n - 1, 'x%i' % i) for i in range(n)] # # constraints # solver.Add(solver.AllDifferent(q)) for i in range(n): for j in range(i): solver.Add(q[i] != q[j]) solver.Add(q[i] + i != q[j] + j) solver.Add(q[i] - i != q[j] - j) # for i in range(n): # for j in range(i): # solver.Add(abs(q[i]-q[j]) != abs(i-j)) # symmetry breaking # solver.Add(q[0] == 0) # # solution and search # solution = solver.Assignment() solution.Add([q[i] for i in range(n)]) # db: DecisionBuilder db = solver.Phase( [q[i] for i in range(n)], # solver.CHOOSE_FIRST_UNBOUND, solver.CHOOSE_MIN_SIZE_LOWEST_MAX, solver.ASSIGN_CENTER_VALUE) solver.NewSearch(db) num_solutions = 0 while solver.NextSolution(): qval = [q[i].Value() for i in range(n)] print "q:", qval for i in range(n): for j in range(n): if qval[i] == j: print "Q", else: print "_", print print num_solutions += 1 solver.EndSearch() print print "num_solutions:", num_solutions print "failures:", solver.Failures() print "branches:", solver.Branches() print "WallTime:", solver.WallTime()
def main(r=0, c=0, rowsums=[], colsums=[], game=[]): # Create the solver. solver = pywrapcp.Solver("Survo puzzle") # # data # if r == 0: r = 3 c = 4 rowsums = [30, 18, 30] colsums = [27, 16, 10, 25] game = [[0, 6, 0, 0], [8, 0, 0, 0], [0, 0, 3, 0]] print "r:", r, "c:", c # declare variables x = {} for i in range(r): for j in range(c): x[(i, j)] = solver.IntVar(1, r * c, "x %i %i" % (i, j)) # # constraints # # # set the clues # for i in range(r): for j in range(c): if game[i][j] > 0: solver.Add(x[i, j] == game[i][j]) xflat = [x[(i, j)] for i in range(r) for j in range(c)] solver.Add(solver.AllDifferent(xflat)) # # calculate rowsums and colsums # for i in range(r): solver.Add(rowsums[i] == solver.Sum([x[i, j] for j in range(c)])) for j in range(c): solver.Add(colsums[j] == solver.Sum([x[i, j] for i in range(r)])) # # solution and search # solution = solver.Assignment() solution.Add([x[(i, j)] for i in range(r) for j in range(c)]) collector = solver.AllSolutionCollector(solution) solver.Solve(solver.Phase(xflat, solver.CHOOSE_FIRST_UNBOUND, solver.ASSIGN_MIN_VALUE), [collector]) num_solutions = collector.SolutionCount() print "\nnum_solutions: ", num_solutions if num_solutions > 0: for s in range(num_solutions): xval = [collector.Value(s, x[(i, j)]) for i in range(r) for j in range(c)] for i in range(r): for j in range(c): print "%2i" % (xval[i * c + j]), print print print print "num_solutions:", num_solutions print "failures:", solver.Failures() print "branches:", solver.Branches() print "WallTime:", solver.WallTime() else: print "No solutions found"
def main(words, word_len, num_answers=20): # Create the solver. solver = pywrapcp.Solver("Problem") # # data # num_words = len(words) n = word_len d, rev = get_dict() # # declare variables # A = {} for i in range(num_words): for j in range(word_len): A[(i, j)] = solver.IntVar(0, 29, "A(%i,%i)" % (i, j)) A_flat = [A[(i, j)] for i in range(num_words) for j in range(word_len)] E = [solver.IntVar(0, num_words, "E%i" % i) for i in range(n)] # # constraints # solver.Add(solver.AllDifferent(E)) # copy the words to a Matrix for I in range(num_words): for J in range(word_len): solver.Add(A[(I, J)] == d[words[I][J]]) for i in range(word_len): for j in range(word_len): # This is what I would like to do: # solver.Add(A[(E[i],j)] == A[(E[j],i)]) # We must use Element explicitly solver.Add( solver.Element(A_flat, E[i] * word_len + j) == solver.Element(A_flat, E[j] * word_len + i)) # # solution and search # solution = solver.Assignment() solution.Add(E) # db: DecisionBuilder db = solver.Phase(E + A_flat, solver.CHOOSE_FIRST_UNBOUND, solver.ASSIGN_MIN_VALUE) solver.NewSearch(db) num_solutions = 0 while solver.NextSolution(): # print E print_solution(E, words) num_solutions += 1 if num_solutions > num_answers: break solver.EndSearch() print() print("num_solutions:", num_solutions) print("failures:", solver.Failures()) print("branches:", solver.Branches()) print("WallTime:", solver.WallTime())
def main(base=10, start=1, len1=1, len2=4): # Create the solver. solver = pywrapcp.Solver("Pandigital numbers") # # data # max_d = base - 1 x_len = max_d + 1 - start max_num = base**4 - 1 # # declare variables # num1 = solver.IntVar(0, max_num, "num1") num2 = solver.IntVar(0, max_num, "num2") res = solver.IntVar(0, max_num, "res") x = [solver.IntVar(start, max_d, "x[%i]" % i) for i in range(x_len)] # # constraints # solver.Add(solver.AllDifferent(x)) toNum(solver, [x[i] for i in range(len1)], num1, base) toNum(solver, [x[i] for i in range(len1, len1 + len2)], num2, base) toNum(solver, [x[i] for i in range(len1 + len2, x_len)], res, base) solver.Add(num1 * num2 == res) # no number must start with 0 solver.Add(x[0] > 0) solver.Add(x[len1] > 0) solver.Add(x[len1 + len2] > 0) # symmetry breaking solver.Add(num1 < num2) # # solution and search # solution = solver.Assignment() solution.Add(x) solution.Add(num1) solution.Add(num2) solution.Add(res) db = solver.Phase(x, solver.INT_VAR_SIMPLE, solver.INT_VALUE_DEFAULT) solver.NewSearch(db) num_solutions = 0 solutions = [] while solver.NextSolution(): print_solution([x[i].Value() for i in range(x_len)], len1, len2, x_len) num_solutions += 1 solver.EndSearch() if 0 and num_solutions > 0: print() print("num_solutions:", num_solutions) print("failures:", solver.Failures()) print("branches:", solver.Branches()) print("WallTime:", solver.WallTime()) print()
def main(n=8): # Create the solver. solver = pywrapcp.Solver("n-queens") # # data # # n = 8 # size of board (n x n) # declare variables q = [solver.IntVar(0, n - 1, "x%i" % i) for i in range(n)] # # constraints # solver.Add(solver.AllDifferent(q)) for i in range(n): for j in range(i): solver.Add(q[i] != q[j]) solver.Add(q[i] + i != q[j] + j) solver.Add(q[i] - i != q[j] - j) # for i in range(n): # for j in range(i): # solver.Add(abs(q[i]-q[j]) != abs(i-j)) # symmetry breaking # solver.Add(q[0] == 0) # # solution and search # solution = solver.Assignment() solution.Add([q[i] for i in range(n)]) collector = solver.AllSolutionCollector(solution) # collector = solver.FirstSolutionCollector(solution) # search_log = solver.SearchLog(100, x[0]) solver.Solve( solver.Phase([q[i] for i in range(n)], solver.INT_VAR_SIMPLE, solver.ASSIGN_MIN_VALUE), [collector]) num_solutions = collector.SolutionCount() print("num_solutions: ", num_solutions) if num_solutions > 0: for s in range(num_solutions): qval = [collector.Value(s, q[i]) for i in range(n)] print("q:", qval) for i in range(n): for j in range(n): if qval[i] == j: print("Q", end=' ') else: print("_", end=' ') print() print() print() print("num_solutions:", num_solutions) print("failures:", solver.Failures()) print("branches:", solver.Branches()) print("WallTime:", solver.WallTime()) else: print("No solutions found")
def main(show_all_max=0): # Create the solver. solver = pywrapcp.Solver("Photo problem") # # data # persons = ["Betty", "Chris", "Donald", "Fred", "Gary", "Mary", "Paul"] n = len(persons) preferences = [ # 0 1 2 3 4 5 6 # B C D F G M P [0, 0, 0, 0, 1, 1, 0], # Betty 0 [1, 0, 0, 0, 1, 0, 0], # Chris 1 [0, 0, 0, 0, 0, 0, 0], # Donald 2 [0, 0, 1, 0, 0, 1, 0], # Fred 3 [0, 0, 0, 0, 0, 0, 0], # Gary 4 [0, 0, 0, 0, 0, 0, 0], # Mary 5 [0, 0, 1, 1, 0, 0, 0] # Paul 6 ] print("""Preferences: 1. Betty wants to stand next to Gary and Mary. 2. Chris wants to stand next to Betty and Gary. 3. Fred wants to stand next to Mary and Donald. 4. Paul wants to stand next to Fred and Donald. """) # # declare variables # positions = [solver.IntVar(0, n - 1, "positions[%i]" % i) for i in range(n)] # successful preferences z = solver.IntVar(0, n * n, "z") # # constraints # solver.Add(solver.AllDifferent(positions)) # calculate all the successful preferences b = [solver.IsEqualCstVar(abs(positions[i] - positions[j]), 1) for i in range(n) for j in range(n) if preferences[i][j] == 1] solver.Add(z == solver.Sum(b)) # # Symmetry breaking (from the Oz page): # Fred is somewhere left of Betty solver.Add(positions[3] < positions[0]) # objective objective = solver.Maximize(z, 1) if show_all_max != 0: print("Showing all maximum solutions (z == 6).\n") solver.Add(z == 6) # # search and result # db = solver.Phase(positions, solver.CHOOSE_FIRST_UNBOUND, solver.ASSIGN_MAX_VALUE) if show_all_max == 0: solver.NewSearch(db, [objective]) else: solver.NewSearch(db) num_solutions = 0 while solver.NextSolution(): print("z:", z.Value()) p = [positions[i].Value() for i in range(n)] print(" ".join([persons[j] for i in range(n) for j in range(n) if p[j] == i])) print("Successful preferences:") for i in range(n): for j in range(n): if preferences[i][j] == 1 and abs(p[i] - p[j]) == 1: print("\t", persons[i], persons[j]) print() num_solutions += 1 solver.EndSearch() print() print("num_solutions:", num_solutions) print("failures:", solver.Failures()) print("branches:", solver.Branches()) print("WallTime:", solver.WallTime())
def Solve(model): """Solve the given model.""" # Create the solver. solver = pywrapcp.Solver('hidato-table') # # models, a 0 indicates an open cell which number is not yet known. # # puzzle = None if model == 1: # Simple problem puzzle = [[6, 0, 9], [0, 2, 8], [1, 0, 0]] elif model == 2: puzzle = [[0, 44, 41, 0, 0, 0, 0], [0, 43, 0, 28, 29, 0, 0], [0, 1, 0, 0, 0, 33, 0], [0, 2, 25, 4, 34, 0, 36], [49, 16, 0, 23, 0, 0, 0], [0, 19, 0, 0, 12, 7, 0], [0, 0, 0, 14, 0, 0, 0]] elif model == 3: # Problems from the book: # Gyora Bededek: "Hidato: 2000 Pure Logic Puzzles" # Problem 1 (Practice) puzzle = [[0, 0, 20, 0, 0], [0, 0, 0, 16, 18], [22, 0, 15, 0, 0], [23, 0, 1, 14, 11], [0, 25, 0, 0, 12]] elif model == 4: # problem 2 (Practice) puzzle = [[0, 0, 0, 0, 14], [0, 18, 12, 0, 0], [0, 0, 17, 4, 5], [0, 0, 7, 0, 0], [9, 8, 25, 1, 0]] elif model == 5: # problem 3 (Beginner) puzzle = [[0, 26, 0, 0, 0, 18], [0, 0, 27, 0, 0, 19], [31, 23, 0, 0, 14, 0], [0, 33, 8, 0, 15, 1], [0, 0, 0, 5, 0, 0], [35, 36, 0, 10, 0, 0]] elif model == 6: # Problem 15 (Intermediate) puzzle = [[64, 0, 0, 0, 0, 0, 0, 0], [1, 63, 0, 59, 15, 57, 53, 0], [0, 4, 0, 14, 0, 0, 0, 0], [3, 0, 11, 0, 20, 19, 0, 50], [0, 0, 0, 0, 22, 0, 48, 40], [9, 0, 0, 32, 23, 0, 0, 41], [27, 0, 0, 0, 36, 0, 46, 0], [28, 30, 0, 35, 0, 0, 0, 0]] r = len(puzzle) c = len(puzzle[0]) print('Initial game (%i x %i)' % (r, c)) PrintMatrix(puzzle) # # declare variables # positions = [solver.IntVar(0, r * c - 1, 'p of %i' % i) for i in range(r * c)] # # constraints # solver.Add(solver.AllDifferent(positions)) # # Fill in the clues # for i in range(r): for j in range(c): if puzzle[i][j] > 0: solver.Add(positions[puzzle[i][j] - 1] == i * c + j) # Consecutive numbers much touch each other in the grid. # We use an allowed assignment constraint to model it. close_tuples = BuildPairs(r, c) for k in range(1, r * c - 1): solver.Add(solver.AllowedAssignments((positions[k], positions[k + 1]), close_tuples)) # # solution and search # # db: DecisionBuilder db = solver.Phase(positions, solver.CHOOSE_MIN_SIZE_LOWEST_MIN, solver.ASSIGN_MIN_VALUE) solver.NewSearch(db) num_solutions = 0 while solver.NextSolution(): num_solutions += 1 PrintOneSolution(positions, r, c, num_solutions) solver.EndSearch() print('solutions : %i' % num_solutions) print('failures : %i' % solver.Failures()) print('branches : %i' % solver.Branches()) print('wall time : %i' % solver.WallTime())
def main(): # Create the solver. solver = pywrapcp.Solver("KenKen") # # data # # size of matrix n = 6 # For a better view of the problem, see # http://en.wikipedia.org/wiki/File:KenKenProblem.svg # hints # [sum, [segments]] # Note: 1-based problem = [[11, [[1, 1], [2, 1]]], [2, [[1, 2], [1, 3]]], [20, [[1, 4], [2, 4]]], [6, [[1, 5], [1, 6], [2, 6], [3, 6]]], [3, [[2, 2], [2, 3]]], [3, [[2, 5], [3, 5]]], [240, [[3, 1], [3, 2], [4, 1], [4, 2]]], [6, [[3, 3], [3, 4]]], [6, [[4, 3], [5, 3]]], [7, [[4, 4], [5, 4], [5, 5]]], [30, [[4, 5], [4, 6]]], [6, [[5, 1], [5, 2]]], [9, [[5, 6], [6, 6]]], [8, [[6, 1], [6, 2], [6, 3]]], [2, [[6, 4], [6, 5]]]] num_p = len(problem) # # variables # # the set x = {} for i in range(n): for j in range(n): x[i, j] = solver.IntVar(1, n, "x[%i,%i]" % (i, j)) x_flat = [x[i, j] for i in range(n) for j in range(n)] # # constraints # # all rows and columns must be unique for i in range(n): row = [x[i, j] for j in range(n)] solver.Add(solver.AllDifferent(row)) col = [x[j, i] for j in range(n)] solver.Add(solver.AllDifferent(col)) # calculate the segments for (res, segment) in problem: calc(segment, x, res) # # search and solution # db = solver.Phase(x_flat, solver.INT_VAR_DEFAULT, solver.INT_VALUE_DEFAULT) solver.NewSearch(db) num_solutions = 0 while solver.NextSolution(): for i in range(n): for j in range(n): print(x[i, j].Value(), end=" ") print() print() num_solutions += 1 solver.EndSearch() print() print("num_solutions:", num_solutions) print("failures:", solver.Failures()) print("branches:", solver.Branches()) print("WallTime:", solver.WallTime())
def main(): # Create the solver. solver = pywrapcp.Solver('Einav puzzle') # # data # # small problem # data = [ # [ 33, 30, -10], # [-16, 19, 9], # [-17, -12, -14] # ] data = [[33, 30, 10, -6, 18, -7, -11, 23, -6], [16, -19, 9, -26, -8, -19, -8, -21, -14], [17, 12, -14, 31, -30, 13, -13, 19, 16], [-6, -11, 1, 17, -12, -4, -7, 14, -21], [18, -31, 34, -22, 17, -19, 20, 24, 6], [33, -18, 17, -15, 31, -5, 3, 27, -3], [-18, -20, -18, 31, 6, 4, -2, -12, 24], [27, 14, 4, -29, -3, 5, -29, 8, -12], [-15, -7, -23, 23, -9, -8, 6, 8, -12], [33, -23, -19, -4, -8, -7, 11, -12, 31], [-20, 19, -15, -30, 11, 32, 7, 14, -5], [-23, 18, -32, -2, -31, -7, 8, 24, 16], [32, -4, -10, -14, -6, -1, 0, 23, 23], [25, 0, -23, 22, 12, 28, -27, 15, 4], [-30, -13, -16, -3, -3, -32, -3, 27, -31], [22, 1, 26, 4, -2, -13, 26, 17, 14], [-9, -18, 3, -20, -27, -32, -11, 27, 13], [-17, 33, -7, 19, -32, 13, -31, -2, -24], [-31, 27, -31, -29, 15, 2, 29, -15, 33], [-18, -23, 15, 28, 0, 30, -4, 12, -32], [-3, 34, 27, -25, -18, 26, 1, 34, 26], [-21, -31, -10, -13, -30, -17, -12, -26, 31], [23, -31, -19, 21, -17, -10, 2, -23, 23], [-3, 6, 0, -3, -32, 0, -10, -25, 14], [-19, 9, 14, -27, 20, 15, -5, -27, 18], [11, -6, 24, 7, -17, 26, 20, -31, -25], [-25, 4, -16, 30, 33, 23, -4, -4, 23]] rows = len(data) cols = len(data[0]) # # variables # x = {} for i in range(rows): for j in range(cols): x[i, j] = solver.IntVar(-100, 100, 'x[%i,%i]' % (i, j)) row_signs = [ solver.IntVar([-1, 1], 'row_signs(%i)' % i) for i in range(rows) ] col_signs = [ solver.IntVar([-1, 1], 'col_signs(%i)' % j) for j in range(cols) ] # # constraints # for i in range(rows): for j in range(cols): solver.Add(x[i, j] == data[i][j] * row_signs[i] * col_signs[j]) total_sum = solver.Sum([x[i, j] for i in range(rows) for j in range(cols)]) # row sums row_sums = [ solver.Sum([x[i, j] for j in range(cols)]).Var() for i in range(rows) ] # >= 0 for i in range(rows): row_sums[i].SetMin(0) # column sums col_sums = [ solver.Sum([x[i, j] for i in range(rows)]).Var() for j in range(cols) ] for j in range(cols): col_sums[j].SetMin(0) # objective objective = solver.Minimize(total_sum, 1) # # search and result # db = solver.Phase(col_signs + row_signs, solver.CHOOSE_FIRST_UNBOUND, solver.ASSIGN_MIN_VALUE) search_log = solver.SearchLog(100000, total_sum) solver.NewSearch(db, [objective, search_log]) num_solutions = 0 while solver.NextSolution(): num_solutions += 1 print('Sum =', objective.Best()) print('row_sums:', [row_sums[i].Value() for i in range(rows)]) print('col_sums:', [col_sums[j].Value() for j in range(cols)]) for i in range(rows): for j in range(cols): print(x[i, j].Value(), ', ') print('\n') print('\n') solver.EndSearch() print('num_solutions:', num_solutions) print('failures:', solver.Failures()) print('branches:', solver.Branches()) print('wall_time:', solver.WallTime(), 'ms')
def index(): results = [] form = CoursesForm() if form.validate_on_submit(): course_list = form.courses.data.splitlines() courses = [] sections = [] for c in course_list: search = c.split(': ') courses.extend(Course.query.filter_by(code=search[0])) sections.extend( Section.query.with_parent( Course.query.filter_by(code=search[0]).first()).filter( Section.term.any(search[1])).all()) # create the constraint solver solver = pywrapcp.Solver('scheduler') # create the variables solver_sections = {} for s in sections: solver_sections[s.code] = solver.BoolVar('{}'.format(s.code)) solver_sections_flat = [solver_sections[s.code] for s in sections] # create the constraints term_day_time = {} for t in terms: for d in days: for h in hours: term_day_time[(t, d, h)] = solver.IntVar( 0, len(sections), 'term {0}, {1}, {2}'.format(t, d, h)) sections_to_sum = [ s for s in sections if t in s.term and d in s.days and dt.strptime(h, '%H:%M').time() >= s.start and dt.strptime(h, '%H:%M').time() < s.end ] solver.Add(term_day_time[(t, d, h)] == solver.Sum( [solver_sections[s.code] for s in sections_to_sum])) solver.Add(term_day_time[(t, d, h)] >= 0) solver.Add(term_day_time[(t, d, h)] <= 1) solver.Add( solver.Sum([term_day_time[(t, d, h)] for h in hours]) >= 0) solver.Add( solver.Sum([term_day_time[(t, d, h)] for h in hours]) <= len(hours)) for h in hours: solver.Add( solver.Sum([term_day_time[(t, d, h)] for d in days]) >= 0) solver.Add( solver.Sum([term_day_time[(t, d, h)] for d in days]) <= len(days)) course_activity = {} for c in courses: for a in c.activities: course_activity[(c, a)] = solver.IntVar(0, len(sections), '{0}, {1}'.format(c, a)) sections_to_sum = [ s for s in sections if c == s.course and a == s.activity ] solver.Add(course_activity[(c, a)] == solver.Sum( [solver_sections[s.code] for s in sections_to_sum])) solver.Add(course_activity[(c, a)] >= 0) solver.Add(course_activity[(c, a)] <= 1) solver.Add( solver.Sum([course_activity[(c, a)] for a in c.activities]) == len(c.activities)) # create the decision builder db = solver.Phase(solver_sections_flat, solver.CHOOSE_FIRST_UNBOUND, solver.ASSIGN_MIN_VALUE) # create the solution collector solution = solver.Assignment() solution.Add(solver_sections_flat) collector = solver.AllSolutionCollector(solution) # limit the number of solutions to 100 solutions_limit = solver.SolutionsLimit(100) # call the solver solver.Solve(db, [solutions_limit, collector]) # return solutions for sol in range(collector.SolutionCount()): solution = [] for s in sections: if collector.Value(sol, solver_sections[s.code]) == 1: solution.append(s.code) results.append(solution) return render_template('index.html', form=form, results=results)
def test_sparse_var(self): solver = pywrapcp.Solver('test sparse') x = solver.IntVar([1, 3, 5], 'x') self.assertTrue(x.Contains(1)) self.assertFalse(x.Contains(2))
def test_modulo(self): solver = pywrapcp.Solver('test modulo') x = solver.IntVar(0, 10, 'x') y = solver.IntVar(2, 4, 'y') print(x % 3) print(x % y)
from ortools.constraint_solver import pywrapcp if __name__ == '__main__': solver = pywrapcp.Solver('logic_riddle') a = solver.IntVar(0, 1, 'A') # All of the below b = solver.IntVar(0, 1, 'B') # None of the below c = solver.IntVar(0, 1, 'C') # All of the above d = solver.IntVar(0, 1, 'D') # One of the above e = solver.IntVar(0, 1, 'E') # None of the above f = solver.IntVar(0, 1, 'F') # None of the above solver.Add(a == 1 and b == 1 and c == 1 and d == 1 and e == 1 and f == 1) solver.Add(b == 1 and b == 0 and c == 0 and d == 0 and e == 0 and f == 0) solver.Add(c == 1 and a == 1 and b == 1) solver.Add(d == 1 and (a == 1 or b == 1 or c == 1)) solver.Add(e == 1 and a == 0 and b == 0 and c == 0 and d == 0) solver.Add(f == 1 and a == 0 and b == 0 and c == 0 and d == 0 and e == 0) # in this case the int_var_default is the lexycographic order db = solver.Phase([a, b, c, d, e, f], solver.INT_VAR_DEFAULT, solver.INT_VALUE_DEFAULT) vars = [a, b, c, d, e, f] solution = solver.AllSolutionCollector() solution.Add(vars) solved = solver.Solve(db, [solution]) if solved: for i in range(solution.SolutionCount()): print([
def test_export(self): solver = pywrapcp.Solver('test export') x = solver.IntVar(1, 10, 'x') ct = x.Member([1, 2, 3, 5]) solver.Add(ct)
from __future__ import print_function import sys from ortools.constraint_solver import pywrapcp solver = pywrapcp.Solver('schedule_shifts') # Number of classes and slots n_classes = 200 n_slots = 220 # Assignment of classes to slot indices assignment = [] for i in range(n_classes): assignment.append(solver.IntVar(0,n_slots-1,"Class %i"%i)) # A slot is only occupied once solver.Add(solver.AllDifferent(assignment)) # Running the Solver db = solver.Phase(assignment,solver.CHOOSE_FIRST_UNBOUND,solver.ASSIGN_MIN_VALUE) solution = solver.Assignment() solution.Add(assignment) #collector = solver.AllSolutionCollector(solution) solver.Solve(db) #print("Solutions found: ", collector.SolutionCount()) print("Time taken: ", solver.WallTime(), "ms") #solver.NextSolution() myvar = 0
def test_size_1_var(self): solver = pywrapcp.Solver('test_size_1_var') x = solver.IntVar([0], 'x')
def main(rows, row_rule_len, row_rules, cols, col_rule_len, col_rules): # Create the solver. solver = pywrapcp.Solver('Nonogram') # # variables # board = {} for i in range(rows): for j in range(cols): board[i, j] = solver.IntVar(0, 1, 'board[%i, %i]' % (i, j)) board_flat = [board[i, j] for i in range(rows) for j in range(cols)] # Flattened board for labeling. # This labeling was inspired by a suggestion from # Pascal Van Hentenryck about my (hakank's) Comet # nonogram model. board_label = [] if rows * row_rule_len < cols * col_rule_len: for i in range(rows): for j in range(cols): board_label.append(board[i, j]) else: for j in range(cols): for i in range(rows): board_label.append(board[i, j]) # # constraints # for i in range(rows): check_rule(row_rules[i], [board[i, j] for j in range(cols)]) for j in range(cols): check_rule(col_rules[j], [board[i, j] for i in range(rows)]) # # solution and search # parameters = pywrapcp.DefaultPhaseParameters() parameters.heuristic_period = 200000 db = solver.DefaultPhase(board_label, parameters) print 'before solver, wall time = ', solver.WallTime(), 'ms' solver.NewSearch(db) num_solutions = 0 while solver.NextSolution(): print num_solutions += 1 for i in range(rows): row = [board[i, j].Value() for j in range(cols)] row_pres = [] for j in row: if j == 1: row_pres.append('#') else: row_pres.append(' ') print ' ', ''.join(row_pres) print print ' ', '-' * cols if num_solutions >= 2: print '2 solutions is enough...' break solver.EndSearch() print print 'num_solutions:', num_solutions print 'failures:', solver.Failures() print 'branches:', solver.Branches() print 'WallTime:', solver.WallTime(), 'ms'
def test_demon(self): print('test_demon') solver = pywrapcp.Solver('test export') x = solver.IntVar(1, 10, 'x') demon = CustomDemon(x) demon.Run(solver)
def main(): # Create the solver. solver = pywrapcp.Solver("Kakuro") # # data # # size of matrix n = 7 # segments # [sum, [segments]] # Note: 1-based problem = [[16, [1, 1], [1, 2]], [24, [1, 5], [1, 6], [1, 7]], [17, [2, 1], [2, 2]], [29, [2, 4], [2, 5], [2, 6], [2, 7]], [35, [3, 1], [3, 2], [3, 3], [3, 4], [3, 5]], [7, [4, 2], [4, 3]], [8, [4, 5], [4, 6]], [16, [5, 3], [5, 4], [5, 5], [5, 6], [5, 7]], [21, [6, 1], [6, 2], [6, 3], [6, 4]], [5, [6, 6], [6, 7]], [6, [7, 1], [7, 2], [7, 3]], [3, [7, 6], [7, 7]], [23, [1, 1], [2, 1], [3, 1]], [30, [1, 2], [2, 2], [3, 2], [4, 2]], [27, [1, 5], [2, 5], [3, 5], [4, 5], [5, 5]], [12, [1, 6], [2, 6]], [16, [1, 7], [2, 7]], [17, [2, 4], [3, 4]], [15, [3, 3], [4, 3], [5, 3], [6, 3], [7, 3]], [12, [4, 6], [5, 6], [6, 6], [7, 6]], [7, [5, 4], [6, 4]], [7, [5, 7], [6, 7], [7, 7]], [11, [6, 1], [7, 1]], [10, [6, 2], [7, 2]]] num_p = len(problem) # The blanks # Note: 1-based blanks = [[1, 3], [1, 4], [2, 3], [3, 6], [3, 7], [4, 1], [4, 4], [4, 7], [5, 1], [5, 2], [6, 5], [7, 4], [7, 5]] num_blanks = len(blanks) # # variables # # the set x = {} for i in range(n): for j in range(n): x[i, j] = solver.IntVar(0, 9, "x[%i,%i]" % (i, j)) x_flat = [x[i, j] for i in range(n) for j in range(n)] # # constraints # # fill the blanks with 0 for i in range(num_blanks): solver.Add(x[blanks[i][0] - 1, blanks[i][1] - 1] == 0) for i in range(num_p): segment = problem[i][1::] res = problem[i][0] # sum this segment calc(segment, x, res) # all numbers in this segment must be distinct segment = [x[p[0] - 1, p[1] - 1] for p in segment] solver.Add(solver.AllDifferent(segment)) # # search and solution # db = solver.Phase(x_flat, solver.INT_VAR_DEFAULT, solver.INT_VALUE_DEFAULT) solver.NewSearch(db) num_solutions = 0 while solver.NextSolution(): for i in range(n): for j in range(n): val = x[i, j].Value() if val > 0: print(val, end=' ') else: print(" ", end=' ') print() print() num_solutions += 1 solver.EndSearch() print() print("num_solutions:", num_solutions) print("failures:", solver.Failures()) print("branches:", solver.Branches()) print("WallTime:", solver.WallTime())
def test_domain_iterator(self): print('test_domain_iterator') solver = pywrapcp.Solver('test_domain_iterator') x = solver.IntVar([1, 2, 4, 6], 'x') for i in x.DomainIterator(): print(i)
def main(game="", r="", c=""): # Create the solver. solver = pywrapcp.Solver("Minesweeper") # # data # # Set default problem if game == "": game = default_game r = default_r c = default_c else: print("rows:", r, " cols:", c) # # Default problem from "Some Minesweeper Configurations",page 3 # (same as problem instance minesweeper_config3.txt) # It has 4 solutions # # r = 8 # c = 8 # X = -1 # game = [ # [2,3,X,2,2,X,2,1], # [X,X,4,X,X,4,X,2], # [X,X,X,X,X,X,4,X], # [X,5,X,6,X,X,X,2], # [2,X,X,X,5,5,X,2], # [1,3,4,X,X,X,4,X], # [0,1,X,4,X,X,X,3], # [0,1,2,X,2,3,X,2] # ] S = [-1, 0, 1] # for the neighbors of "this" cell # print problem instance print("Problem:") for i in range(r): for j in range(c): if game[i][j] == X: print("X", end=' ') else: print(game[i][j], end=' ') print() print() # declare variables mines = {} for i in range(r): for j in range(c): mines[(i, j)] = solver.IntVar(0, 1, "mines %i %i" % (i, j)) # # constraints # for i in range(r): for j in range(c): if game[i][j] >= 0: solver.Add(mines[i, j] == 0) # this cell is the sum of all the surrounding cells solver.Add(game[i][j] == solver.Sum([ mines[i + a, j + b] for a in S for b in S if i + a >= 0 and j + b >= 0 and i + a < r and j + b < c ])) if game[i][j] > X: # This cell cannot be a mine solver.Add(mines[i, j] == 0) # # solution and search # solution = solver.Assignment() solution.Add([mines[(i, j)] for i in range(r) for j in range(c)]) collector = solver.AllSolutionCollector(solution) solver.Solve( solver.Phase([mines[(i, j)] for i in range(r) for j in range(c)], solver.INT_VAR_SIMPLE, solver.ASSIGN_MIN_VALUE), [collector]) num_solutions = collector.SolutionCount() print("num_solutions: ", num_solutions) if num_solutions > 0: for s in range(num_solutions): minesval = [ collector.Value(s, mines[(i, j)]) for i in range(r) for j in range(c) ] for i in range(r): for j in range(c): print(minesval[i * c + j], end=' ') print() print() print() print("num_solutions:", num_solutions) print("failures:", solver.Failures()) print("branches:", solver.Branches()) print("WallTime:", solver.WallTime()) else: print("No solutions found")
def test_custom_decision(self): solver = pywrapcp.Solver('test_custom_decision') db = CustomDecisionBuilderCustomDecision() print(str(db)) solver.Solve(db)
def main(): # Create the solver. solver = pywrapcp.Solver("Einav puzzle") # # data # # small problem # rows = 3; # cols = 3; # data = [ # [ 33, 30, -10], # [-16, 19, 9], # [-17, -12, -14] # ] # Full problem rows = 27 cols = 9 data = [[33, 30, 10, -6, 18, -7, -11, 23, -6], [16, -19, 9, -26, -8, -19, -8, -21, -14], [17, 12, -14, 31, -30, 13, -13, 19, 16], [-6, -11, 1, 17, -12, -4, -7, 14, -21], [18, -31, 34, -22, 17, -19, 20, 24, 6], [33, -18, 17, -15, 31, -5, 3, 27, -3], [-18, -20, -18, 31, 6, 4, -2, -12, 24], [27, 14, 4, -29, -3, 5, -29, 8, -12], [-15, -7, -23, 23, -9, -8, 6, 8, -12], [33, -23, -19, -4, -8, -7, 11, -12, 31], [-20, 19, -15, -30, 11, 32, 7, 14, -5], [-23, 18, -32, -2, -31, -7, 8, 24, 16], [32, -4, -10, -14, -6, -1, 0, 23, 23], [25, 0, -23, 22, 12, 28, -27, 15, 4], [-30, -13, -16, -3, -3, -32, -3, 27, -31], [22, 1, 26, 4, -2, -13, 26, 17, 14], [-9, -18, 3, -20, -27, -32, -11, 27, 13], [-17, 33, -7, 19, -32, 13, -31, -2, -24], [-31, 27, -31, -29, 15, 2, 29, -15, 33], [-18, -23, 15, 28, 0, 30, -4, 12, -32], [-3, 34, 27, -25, -18, 26, 1, 34, 26], [-21, -31, -10, -13, -30, -17, -12, -26, 31], [23, -31, -19, 21, -17, -10, 2, -23, 23], [-3, 6, 0, -3, -32, 0, -10, -25, 14], [-19, 9, 14, -27, 20, 15, -5, -27, 18], [11, -6, 24, 7, -17, 26, 20, -31, -25], [-25, 4, -16, 30, 33, 23, -4, -4, 23]] # # variables # x = {} for i in range(rows): for j in range(cols): x[i, j] = solver.IntVar(-100, 100, "x[%i,%i]" % (i, j)) x_flat = [x[i, j] for i in range(rows) for j in range(cols)] row_signs = [ solver.IntVar([-1, 1], "row_signs(%i)" % i) for i in range(rows) ] col_signs = [ solver.IntVar([-1, 1], "col_signs(%i)" % j) for j in range(cols) ] # # constraints # for i in range(rows): for j in range(cols): solver.Add(x[i, j] == data[i][j] * row_signs[i] * col_signs[j]) total_sum = solver.Sum([x[i, j] for i in range(rows) for j in range(cols)]) # # Note: In einav_puzzle.py row_sums and col_sums are decision variables. # # row sums row_sums = [ solver.Sum([x[i, j] for j in range(cols)]).Var() for i in range(rows) ] # >= 0 for i in range(rows): row_sums[i].SetMin(0) # column sums col_sums = [ solver.Sum([x[i, j] for i in range(rows)]).Var() for j in range(cols) ] for j in range(cols): col_sums[j].SetMin(0) # objective objective = solver.Minimize(total_sum, 1) # # search and result # db = solver.Phase(col_signs + row_signs, solver.CHOOSE_MIN_SIZE_LOWEST_MIN, solver.ASSIGN_MAX_VALUE) solver.NewSearch(db, [objective]) num_solutions = 0 while solver.NextSolution(): num_solutions += 1 print("Sum =", objective.Best()) print("row_sums:", [row_sums[i].Value() for i in range(rows)]) print("col_sums:", [col_sums[j].Value() for j in range(cols)]) for i in range(rows): for j in range(cols): print("%3i" % x[i, j].Value(), end=" ") print() print() solver.EndSearch() print() print("num_solutions:", num_solutions) print("failures:", solver.Failures()) print("branches:", solver.Branches()) print("WallTime:", solver.WallTime())
def test_member(self): solver = pywrapcp.Solver('test member') x = solver.IntVar(1, 10, 'x') ct = x.Member([1, 2, 3, 5]) print('Constraint: {}'.format(ct))
def main(singe=0): # Create the solver. solver = pywrapcp.Solver('Secret Santa problem II') # # data # # # The matrix version of earlier rounds. # M means that no earlier Santa has been assigned. # Note: Ryan and Mia has the same recipient for years 3 and 4, # and Ella and John has for year 4. # This seems to be caused by modification of # original data. # n_no_single = 8 M = n_no_single + 1 rounds_no_single = [ # N A R M El J L Ev [0, M, 3, M, 1, 4, M, 2], # Noah [M, 0, 4, 2, M, 3, M, 1], # Ava [M, 2, 0, M, 1, M, 3, 4], # Ryan [M, 1, M, 0, 2, M, 3, 4], # Mia [M, 4, M, 3, 0, M, 1, 2], # Ella [1, 4, 3, M, M, 0, 2, M], # John [M, 3, M, 2, 4, 1, 0, M], # Lily [4, M, 3, 1, M, 2, M, 0] # Evan ] # # Rounds with a single person (fake data) # n_with_single = 9 M = n_with_single + 1 rounds_single = [ # N A R M El J L Ev S [0, M, 3, M, 1, 4, M, 2, 2], # Noah [M, 0, 4, 2, M, 3, M, 1, 1], # Ava [M, 2, 0, M, 1, M, 3, 4, 4], # Ryan [M, 1, M, 0, 2, M, 3, 4, 3], # Mia [M, 4, M, 3, 0, M, 1, 2, M], # Ella [1, 4, 3, M, M, 0, 2, M, M], # John [M, 3, M, 2, 4, 1, 0, M, M], # Lily [4, M, 3, 1, M, 2, M, 0, M], # Evan [1, 2, 3, 4, M, 2, M, M, 0] # Single ] if single == 1: n = n_with_single Noah, Ava, Ryan, Mia, Ella, John, Lily, Evan, Single = list(range(n)) rounds = rounds_single else: n = n_no_single Noah, Ava, Ryan, Mia, Ella, John, Lily, Evan = list(range(n)) rounds = rounds_no_single M = n + 1 persons = [ 'Noah', 'Ava', 'Ryan', 'Mia', 'Ella', 'John', 'Lily', 'Evan', 'Single' ] spouses = [ Ava, # Noah Noah, # Ava Mia, # Rya Ryan, # Mia John, # Ella Ella, # John Evan, # Lily Lily, # Evan -1 # Single has no spouse ] # # declare variables # santas = [solver.IntVar(0, n - 1, 'santas[%i]' % i) for i in range(n)] santa_distance = [ solver.IntVar(0, M, 'santa_distance[%i]' % i) for i in range(n) ] # total of 'distance', to maximize z = solver.IntVar(0, n * n * n, 'z') # # constraints # solver.Add(solver.AllDifferent(santas)) solver.Add(z == solver.Sum(santa_distance)) # Can't be one own's Secret Santa # (i.e. ensure that there are no fix-point in the array.) for i in range(n): solver.Add(santas[i] != i) # no Santa for a spouses for i in range(n): if spouses[i] > -1: solver.Add(santas[i] != spouses[i]) # optimize 'distance' to earlier rounds: for i in range(n): solver.Add(santa_distance[i] == solver.Element(rounds[i], santas[i])) # cannot be a Secret Santa for the same person # two years in a row. for i in range(n): for j in range(n): if rounds[i][j] == 1: solver.Add(santas[i] != j) # objective objective = solver.Maximize(z, 1) # # solution and search # db = solver.Phase(santas, solver.CHOOSE_MIN_SIZE_LOWEST_MIN, solver.ASSIGN_CENTER_VALUE) solver.NewSearch(db, [objective]) num_solutions = 0 while solver.NextSolution(): num_solutions += 1 print('total distances:', z.Value()) print('santas:', [santas[i].Value() for i in range(n)]) for i in range(n): print('%s\tis a Santa to %s (distance %i)' % \ (persons[i], persons[santas[i].Value()], santa_distance[i].Value())) # print 'distance:', [santa_distance[i].Value() # for i in range(n)] print() print('num_solutions:', num_solutions) print('failures:', solver.Failures()) print('branches:', solver.Branches()) print('WallTime:', solver.WallTime(), 'ms')
def cp_model(self, decision_jobs, cur_time, cons_qjobs, priorized_jobs, es_dict, resource_types, avl_resources, timelimit=15000, debug=False, prev_sched=[], max_ewt=None): """ Implementation of the CP Model using OR-Tools to generate the schedule plan. @param es: Queued jobs to be scheduled. @param es_dict: Dictionary of the current jobs. @param temp_sched: Storages the scheduled jobs. @param timelimit: Limit of the search process in ms. @param cur_time: Current simulated time @param avl_resources: Availability of the resources @param _debug: Debug flag. @return True is solved, False otherwise. """ parameters = pywrapcp.Solver_DefaultSolverParameters() # parameters.trace_search = True solver = pywrapcp.Solver(self.name, parameters) running_jobs = self.resource_manager.current_allocations job_map = {} wc_makespan = 0 #======================================================================= # Calculate first the remaining makespan of running jobs #======================================================================= for job_id in running_jobs: e = es_dict[job_id] job_map[job_id] = e remaning_duration = e.expected_duration - (cur_time - e.start_time) wc_makespan += remaning_duration #======================================================================= # Add the expected duration of queued jobs to the list of makespans #======================================================================= for job_id, prop in cons_qjobs.items(): job_obj = prop[-1] job_map[job_id] = job_obj expected_duration = job_obj.expected_duration wc_makespan += expected_duration #======================================================================= # The minimum duration value must be 1, since ORTools doesnt accept # duration eq to 0. #======================================================================= dict_vars = {} for job_id in list(running_jobs) + list(cons_qjobs.keys()): job_obj = job_map[job_id] exp_duration = job_obj.expected_duration start_min = 0 if job_obj.start_time: start_max = start_min elapsed_time = (cur_time - job_map[job_id].start_time) else: start_max = wc_makespan elapsed_time = 0 estimated_remaining_time = (exp_duration - elapsed_time) var = solver.FixedDurationIntervalVar(start_min, start_max, estimated_remaining_time, False, job_id) dict_vars[job_id] = var for job_id in prev_sched: cst = dict_vars[job_id].StartExpr().Var() >= 0 solver.AddConstraint(cst) _keys = self.resource_manager.resource_types total_capacity = self.resource_manager.system_capacity('total') total_demand = {} for _key in _keys: # total_capacity[_key] = self.resource_manager.#sum([ resources[_key] for node, resources in avl_resources.items()]) # The resources used by running jobs are loaded into the capacity # total_capacity[_key] += sum(es_dict[job_id].requested_nodes * es_dict[job_id].requested_resources[_key] for job_id in running_jobs) job_ids = list(dict_vars.keys()) total_demand[_key] = [ es_dict[job_id].requested_nodes * es_dict[job_id].requested_resources[_key] for job_id in job_ids ] if sum(total_demand[_key]) == 0: continue _name = 'cum_{}'.format(_key) vars = [dict_vars[job_id] for job_id in job_ids] _cum = solver.Cumulative(vars, total_demand[_key], total_capacity[_key], _name) solver.AddConstraint(_cum) priorized_id_prb_vars = [job_id for job_id in running_jobs ] + [job_id for job_id in priorized_jobs] ewts = [] all_intervals = [] digits = max(self.significant, len(str(wc_makespan))) # max_ewt = max([self.get_ewt(es_dict[job_id].queue) for job_id in priorized_id_prb_vars]) for job_id in priorized_id_prb_vars: job_obj = es_dict[job_id] job_model = dict_vars[job_id] ewt = self.get_ewt(job_obj.queue) wgt = int((max_ewt / ewt) * (10**digits)) jstart = job_model.SafeStartExpr(wc_makespan - expected_duration) qtime = jstart - (job_obj.queued_time - cur_time) prod = (qtime * wgt) ewts.append(prod.Var()) all_intervals.append(job_model) monitors = [] # Minimize the slowdown objective_var = solver.Sum(ewts).Var() objective_monitor = solver.Minimize(objective_var, 1) monitors.append(objective_monitor) db = solver.HeuristicSearch(all_intervals) # Utilities limit_monitor = solver.TimeLimit(timelimit) monitors.append(limit_monitor) best_monitor = solver.BestValueSolutionCollector(False) best_monitor.AddObjective(objective_var) best_monitor.Add(all_intervals) monitors.append(best_monitor) solved = solver.Solve(db, monitors) if solved == True: for job_id in priorized_jobs: job_model = dict_vars[job_id] if best_monitor.Solution(0).StartValue(job_model) == 0: decision_jobs[job_id] = self.dispatching_tuple( job_id, cur_time) else: decision_jobs[job_id] = self.dispatching_tuple(job_id) decision_jobs['best_z'] = best_monitor.ObjectiveValue(0) exec_time = solver.WallTime() decision_jobs[ 'solver_state'] = 4 if exec_time < timelimit and solved else solver.State( ) solver.EndSearch() solver = None decision_jobs[ 'limit_reached'] = exec_time >= timelimit # Should be == but it could take an extra ms to stop the solver. if not solved: for job_id in cons_qjobs: decision_jobs[job_id] = self.dispatching_tuple(job_id) return solved