Exemple #1
0
'''
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')
Exemple #2
0
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()
Exemple #3
0
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())
Exemple #4
0
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'
Exemple #5
0
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()
Exemple #6
0
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"
Exemple #7
0
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()
Exemple #9
0
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")
Exemple #10
0
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())
Exemple #11
0
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())
Exemple #12
0
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())
Exemple #13
0
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')
Exemple #14
0
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)
Exemple #15
0
 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))
Exemple #16
0
 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([
Exemple #18
0
 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)
Exemple #19
0
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
Exemple #20
0
 def test_size_1_var(self):
     solver = pywrapcp.Solver('test_size_1_var')
     x = solver.IntVar([0], 'x')
Exemple #21
0
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'
Exemple #22
0
 def test_demon(self):
     print('test_demon')
     solver = pywrapcp.Solver('test export')
     x = solver.IntVar(1, 10, 'x')
     demon = CustomDemon(x)
     demon.Run(solver)
Exemple #23
0
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())
Exemple #24
0
 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)
Exemple #25
0
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")
Exemple #26
0
 def test_custom_decision(self):
     solver = pywrapcp.Solver('test_custom_decision')
     db = CustomDecisionBuilderCustomDecision()
     print(str(db))
     solver.Solve(db)
Exemple #27
0
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())
Exemple #28
0
 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