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)
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()
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())
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())
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())