コード例 #1
0
def check_rule(model, rules, y, regular_method):
    """
  Check each rule by creating an automaton
  and then run the regular constraint.
  """

    # r_len = sum([1 for i in range(len(rules)) if rules[i] > 0])
    rules_tmp = []
    for i in range(len(rules)):
        if rules[i] > 0:
            rules_tmp.append(rules[i])

    transition_fn = make_transition_matrix(rules_tmp)
    n_states = len(transition_fn)
    input_max = 2

    # Note: we cannot use 0 since it's the failing state
    initial_state = 1
    accepting_states = [n_states]  # This is the last state

    if regular_method == "regular_element":
        regular_element(model, y, n_states, input_max, transition_fn,
                        initial_state, accepting_states)
    else:
        regular_table(model, y, n_states, input_max, transition_fn,
                      initial_state, accepting_states)
コード例 #2
0
ファイル: regexp_sat.py プロジェクト: hakank/hakank
def main(n, res):

    model = cp.CpModel()

    #
    # data
    #
    # the DFA (for regular)
    n_states = 11
    input_max = 12
    initial_state = 1  # 0 is for the failing state
    accepting_states = [12]

    # The DFA
    transition_fn = [
        # 1 2 3 4 5 6 7 8 9 0 1 2     #
        [0, 2, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0],  #  1 k 
        [0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0],  #  2 je
        [0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0],  #  3 ä
        [0, 0, 0, 0, 5, 6, 7, 8, 0, 0, 0, 0],  #  4 ll
        [0, 0, 0, 0, 0, 0, 7, 8, 0, 0, 0, 0],  #  5 er
        [0, 0, 0, 0, 0, 0, 7, 8, 0, 0, 0, 0],  #  6 ar
        [0, 0, 0, 0, 0, 0, 0, 0, 9, 10, 0, 0],  #  7 st 
        [0, 0, 0, 0, 0, 0, 0, 0, 9, 10, 0, 0],  #  8 b
        [0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0],  #  9 r
        [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 12],  # 10 a
        [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12],  # 11 n
        # 12 d
    ]

    s = ['k', 'je', 'ä', 'll', 'er', 'ar', 'st', 'b', 'r', 'a', 'n', 'd']
    print('n:', n)

    #
    # declare variables
    #

    x = [model.NewIntVar(1, 12, 'x[%i]' % i) for i in range(n)]

    #
    # constraints
    #
    regular_table(model, x, n_states, input_max, transition_fn, initial_state,
                  accepting_states)

    #
    # solution and search
    #
    solver = cp.CpSolver()
    solution_printer = SolutionPrinter(n, s, x, res)
    _status = solver.SearchForAllSolutions(model, solution_printer)

    print('NumConflicts:', solver.NumConflicts())
    print('NumBranches:', solver.NumBranches())
    print('wall_time:', solver.WallTime())
    print()
コード例 #3
0
def main(n=7):

  model = cp.CpModel()

  #
  # data
  #
  # the DFA (for regular)
  n_states = 3
  input_max = 2
  initial_state = 1  # 0 is for the failing state

  # all states are accepting states
  accepting_states = [1, 2, 3]

  # The regular expression 0*1*0*
  transition_fn = [
      [1, 2],  # state 1 (start): input 0 -> state 1, input 1 -> state 2 i.e. 0*
      [3, 2],  # state 2: 1*
      [3, 0],  # state 3: 0*
  ]

  #
  # declare variables
  #

  # We use 1..2 and subtract 1 in the solution
  reg_input = [model.NewIntVar(1, 2, 'x[%i]' % i) for i in range(n)]

  #
  # constraints
  #

  # regular_element(model, reg_input, n_states, input_max, transition_fn, initial_state,
  #        accepting_states)
  # Much faster:
  regular_table(model, reg_input, n_states, input_max, transition_fn, initial_state,
          accepting_states)

  #
  # solution and search
  #
  solver = cp.CpSolver()
  solution_printer = SolutionPrinter(reg_input)
  status = solver.SearchForAllSolutions(model, solution_printer)
  
  if not (status == cp.OPTIMAL or status == cp.FEASIBLE):
    print("No solution!")

  print()
  print('NumSolutions:', solution_printer.SolutionCount())
  print('NumConflicts:', solver.NumConflicts())
  print('NumBranches:', solver.NumBranches())
  print('WallTime:', solver.WallTime())
コード例 #4
0
ファイル: regular_sat.py プロジェクト: zdddddx/hakank
def main(pp=[3, 2, 1], this_len=10, use_regular_table=True):

    model = cp.CpModel()

    #
    # data
    #

    # this_len = 10
    # pp = [3, 2, 1]
    print("pp:", pp, "this_len:", this_len)

    transition_fn = make_transition_matrix(pp)
    n_states = len(transition_fn)
    input_max = 2

    # Note: we use '1' and '2' (rather than 0 and 1)
    # since 0 represents the failing state.
    initial_state = 1

    accepting_states = [n_states]

    # declare variables
    reg_input = [
        model.NewIntVar(1, input_max, 'reg_input[%i]' % i)
        for i in range(this_len)
    ]

    #
    # constraints
    #
    if use_regular_table:
        regular_table(model, reg_input, n_states, input_max, transition_fn,
                      initial_state, accepting_states)
    else:
        regular_element(model, reg_input, n_states, input_max, transition_fn,
                        initial_state, accepting_states)

    #
    # solution and search
    #
    solver = cp.CpSolver()
    solution_printer = SolutionPrinter(reg_input)
    status = solver.SearchForAllSolutions(model, solution_printer)

    if status != cp.OPTIMAL:
        print("No solution!")

    print()
    print('NumSolutions:', solution_printer.SolutionCount())
    print('NumConflicts:', solver.NumConflicts())
    print('NumBranches:', solver.NumBranches())
    print('WallTime:', solver.WallTime())
コード例 #5
0
ファイル: nurse_rostering_sat.py プロジェクト: zdddddx/hakank
def main():

  model = cp.CpModel()

  #
  # data
  #

  # Note: If you change num_nurses or num_days,
  #       please also change the constraints
  #       on nurse_stat and/or day_stat.
  num_nurses = 7
  num_days = 14

  day_shift = 1
  night_shift = 2
  off_shift = 3
  shifts = [day_shift, night_shift, off_shift]

  # the DFA (for regular)
  n_states = 6
  input_max = 3
  initial_state = 1  # 0 is for the failing state
  accepting_states = [1, 2, 3, 4, 5, 6]

  transition_fn = [
      # d,n,o
      [2, 3, 1],  # state 1
      [4, 4, 1],  # state 2
      [4, 5, 1],  # state 3
      [6, 6, 1],  # state 4
      [6, 0, 1],  # state 5
      [0, 0, 1]  # state 6
  ]

  days = ['d', 'n', 'o']  # for presentation

  #
  # declare variables
  #
  x = {}
  for i in range(num_nurses):
    for j in range(num_days):
      x[i, j] = model.NewIntVar(day_shift, off_shift, 'x[%i,%i]' % (i, j))

  # summary of the nurses
  nurse_stat = [
      model.NewIntVar(0, num_days, 'nurse_stat[%i]' % i)
      for i in range(num_nurses)
  ]

  # summary of the shifts per day
  day_stat = {}
  for i in range(num_days):
    for j in shifts:
      day_stat[i, j] = model.NewIntVar(0, num_nurses, 'day_stat[%i,%i]' % (i, j))

  #
  # constraints
  #
  for i in range(num_nurses):
    reg_input = [x[i, j] for j in range(num_days)]

    # regular_table is much faster than regular
    # regular_element(model, reg_input, n_states, input_max, transition_fn, initial_state,
    #        accepting_states)
    regular_table(model, reg_input, n_states, input_max, transition_fn, initial_state,
                  accepting_states)

  #
  # Statistics and constraints for each nurse
  #
  for i in range(num_nurses):
    # number of worked days (day or night shift)
    b_ds = [model.NewBoolVar("") for j in range(num_days)] # day shift
    b_ns = [model.NewBoolVar("") for j in range(num_days)] # night shift
    for j in range(num_days):
        model.Add(x[i,j]==day_shift).OnlyEnforceIf(b_ds[j]) 
        model.Add(x[i,j]!=day_shift).OnlyEnforceIf(b_ds[j].Not()) 
        
        model.Add(x[i,j]==night_shift).OnlyEnforceIf(b_ns[j]) 
        model.Add(x[i,j]!=night_shift).OnlyEnforceIf(b_ns[j].Not()) 
    model.Add(nurse_stat[i] == sum(b_ds + b_ns))

    # Each nurse must work between 7 and 10
    # days during this period
    model.Add(nurse_stat[i] >= 7)
    model.Add(nurse_stat[i] <= 10)

  #
  # Statistics and constraints for each day
  #
  for j in range(num_days):
    for t in shifts:
      # b = [model.IsEqualCstVar(x[i, j], t) for i in range(num_nurses)]
      b = [model.NewBoolVar("") for i in range(num_nurses)]
      for i in range(num_nurses):
        model.Add(x[i,j] == t).OnlyEnforceIf(b[i])
        model.Add(x[i,j] != t).OnlyEnforceIf(b[i].Not())
      model.Add(day_stat[j, t] == sum(b))

    #
    # Some constraints for this day:
    #
    # Note: We have a strict requirements of
    #       the number of shifts.
    #       Using atleast constraints is much harder
    #       in this model.
    #
    if j % 7 == 5 or j % 7 == 6:
      # special constraints for the weekends
      model.Add(day_stat[j, day_shift] == 2)
      model.Add(day_stat[j, night_shift] == 1)
      model.Add(day_stat[j, off_shift] == 4)
    else:
      # workdays:

      # - exactly 3 on day shift
      model.Add(day_stat[j, day_shift] == 3)
      # - exactly 2 on night
      model.Add(day_stat[j, night_shift] == 2)
      # - exactly 1 off duty
      model.Add(day_stat[j, off_shift] == 2)

  #
  # solution and search
  #
  solver = cp.CpSolver() 
  solution_printer = SolutionPrinter(num_nurses, num_days, days, shifts, x, nurse_stat, day_stat)
  status = solver.SearchForAllSolutions(model, solution_printer)

  if status == cp.OPTIMAL:

    for i in range(num_nurses):
      print('Nurse%i: ' % i, end=' ')
      this_day_stat = defaultdict(int)
      for j in range(num_days):
        d = days[solver.Value(x[i, j]) - 1]
        this_day_stat[d] += 1
        print(d, end=' ')
      print(
          ' day_stat:', [(d, this_day_stat[d]) for d in this_day_stat], end=' ')
      print('total:', solver.Value(nurse_stat[i]), 'workdays')
    print()

    print('Statistics per day:')
    for j in range(num_days):
      print('Day%2i: ' % j, end=' ')
      for t in shifts:
        print(solver.Value(day_stat[j, t]), end=' ')
      print()
    print()

    # We just show 2 solutions
    # if num_solutions >= 2:
    #  break

  print()
  # print('num_solutions:', num_solutions)
  print('NumConflicts:', solver.NumConflicts())
  print('NumBranches:', solver.NumBranches())
  print('WallTime:', solver.WallTime())