def computeChannels(self, n, k=2): from constraint import Problem from constraint import SomeInSetConstraint found = False nodes = tuple(self.nodes()) p = Problem() p.addVariables(list(self.nodes()), range(n,0,-1)) # reverse ordering the domain biases the constraint solver towards smaller numbers p.addConstraint(SomeInSetConstraint([1])) def addConstraint(node1, node2, dist, diff): if(node1 in node2.neighbors(dist)): p.addConstraint(lambda x, y: abs(x - y) >= diff,(node1, node2)) return True return False for i in xrange(len(nodes)-1): n1 = nodes[i] for j in xrange(i+1,len(nodes)): n2 = nodes[j] if(not addConstraint(n1, n2, 2, k)): # each node pair needs no more than 1 constraint addConstraint(n1, n2, 4, 1) for rowIter in self.rows(): row = tuple(rowIter) for i in xrange(len(row)-1): p.addConstraint(lambda x, y: y == (x + k) % n + 1,(row[i], row[i+1])) for colIter in self.columns(): col = tuple(colIter) for i in xrange(len(col)-1): p.addConstraint(lambda x, y: y == (x + k - 1) % n + 1,(col[i], col[i+1])) solution = p.getSolution() if(solution == None): return found found = True for node,channel in p.getSolution().iteritems(): node.channel = channel return True
def find_mapping(signal_patterns: Set[FrozenSet[str]]) -> Dict[str, str]: # Let’s express this as a constraint satisfaction problem problem = Problem() for signal in "abcdefg": problem.addVariable(signal, "abcdefg") # Each signal wire goes to a different segment problem.addConstraint(AllDifferentConstraint()) # Unambiguous digits based on count of lit segments for digit in {1, 4, 7, 8}: for wire in find_possible_signals_for(signal_patterns, digit): segments = DIGIT_TO_SEGMENTS[digit] problem.addConstraint(InSetConstraint(segments), wire) # Unambiguous segments based on how many times they appear in patterns for signal_wire in {"a", "b", "c", "d", "e", "f", "g"}: count = sum(1 for pattern in signal_patterns if signal_wire in pattern) if count == 4: problem.addConstraint(InSetConstraint(["e"]), signal_wire) elif count == 6: problem.addConstraint(InSetConstraint(["b"]), signal_wire) elif count == 7: problem.addConstraint(InSetConstraint(["d", "g"]), signal_wire) elif count == 8: problem.addConstraint(InSetConstraint(["a", "c"]), signal_wire) elif count == 9: problem.addConstraint(InSetConstraint(["f"]), signal_wire) else: raise ValueError return problem.getSolution()
def solution(dimension, solver=None): """Generate binary puzzle solution.""" problem = Problem() if solver is not None: problem.setSolver(solver) else: problem.setSolver(BacktrackingSolver()) problem.addVariables(range(dimension**2), [0, 1]) for i in range(dimension): row_positions = range(i * dimension, (i + 1) * dimension) column_positions = range(i, dimension**2, dimension) # same number of zeros and ones in each row problem.addConstraint(ExactSumConstraint(dimension / 2), row_positions) problem.addConstraint(ExactSumConstraint(dimension / 2), column_positions) # maximum two of the same next to each other for triplet in _nwise(row_positions, 3): problem.addConstraint(MaxSumConstraint(2), triplet) problem.addConstraint(MinSumConstraint(1), triplet) for triplet in _nwise(column_positions, 3): problem.addConstraint(MaxSumConstraint(2), triplet) problem.addConstraint(MinSumConstraint(1), triplet) # unique rows and columns problem.addConstraint( FunctionConstraint(partial(_test_uniqueness, dimension=dimension)), range(dimension**2)) if isinstance(solver, RecursiveBacktrackingSolver): return problem.getSolutions() if isinstance(solver, MinConflictsSolver): return (problem.getSolution(), ) return problem.getSolutionIter()
def test_min_conflicts_solver(): problem = Problem(MinConflictsSolver()) problem.addVariable("x", [0, 1]) problem.addVariable("y", [0, 1]) solution = problem.getSolution() possible_solutions = [ { "x": 0, "y": 0 }, { "x": 0, "y": 1 }, { "x": 1, "y": 0 }, { "x": 1, "y": 1 }, ] assert solution in possible_solutions
def get_solution(genome_index: pd.Index, genome_constraints: pd.DataFrame, i: int) -> dict: solutions = {} final_solution = {} while solutions is not None: problem = Problem(MinConflictsSolver()) problem.addVariables(list(genome_index), range(1, i)) unmatched_regions = genome_constraints[ genome_constraints.constraint == 0] # todo extract to method unmatched_regions.apply(lambda row: problem.addConstraint( lambda row1, row2: row1 != row2, (row['index_x'], row['index_y'])), axis=1) print("generating a solution for", i - 1, "groups") solutions = problem.getSolution() if solutions is not None: print("solution found for", i - 1, "groups") i -= 1 final_solution = solutions else: print("no solution for", i - 1, "groups, therefore optimal solution is", i, "groups") return final_solution
def run(self, dag): """run the layout method""" qubits = dag.qubits cxs = set() from constraint import Problem, AllDifferentConstraint, RecursiveBacktrackingSolver from qiskit.transpiler.passes.layout._csp_custom_solver import CustomSolver for gate in dag.two_qubit_ops(): cxs.add((qubits.index(gate.qargs[0]), qubits.index(gate.qargs[1]))) edges = set(self.coupling_map.get_edges()) if self.time_limit is None and self.call_limit is None: solver = RecursiveBacktrackingSolver() else: solver = CustomSolver(call_limit=self.call_limit, time_limit=self.time_limit) variables = list(range(len(qubits))) variable_domains = list(self.coupling_map.physical_qubits) random.Random(self.seed).shuffle(variable_domains) problem = Problem(solver) problem.addVariables(variables, variable_domains) problem.addConstraint( AllDifferentConstraint()) # each wire is map to a single qubit if self.strict_direction: def constraint(control, target): return (control, target) in edges else: def constraint(control, target): return (control, target) in edges or (target, control) in edges for pair in cxs: problem.addConstraint(constraint, [pair[0], pair[1]]) solution = problem.getSolution() if solution is None: stop_reason = "nonexistent solution" if isinstance(solver, CustomSolver): if solver.time_current is not None and solver.time_current >= self.time_limit: stop_reason = "time limit reached" elif solver.call_current is not None and solver.call_current >= self.call_limit: stop_reason = "call limit reached" else: stop_reason = "solution found" self.property_set["layout"] = Layout( {v: qubits[k] for k, v in solution.items()}) for reg in dag.qregs.values(): self.property_set["layout"].add_register(reg) self.property_set["CSPLayout_stop_reason"] = stop_reason
def solver(domain, appointments): problem = Problem() ConstraintGraphCost = nx.Graph() variablesName = [] # for each appointment (iterate on the numerical key of the appointments) for x in appointments: dom = [] # check which elements of the generic domain are necessary for this appointment for y in domain: hour, minutes = y[1].split(".") hour = int(hour) #print(appointments[x]) #print(appointments[x]["Day"]) for a in appointments[x]["Day"]: if "Morning" == a[1] and hour < 12 and y[0] in a[0] and y[ 2] in appointments[x]["House"]: dom.append(y) if "Afternoon" == a[1] and hour > 12 and y[0] in a[0] and y[ 2] in appointments[x]["House"]: dom.append(y) #Aggiungo la variabile corrente con il domain aggiustato # print(dom) variablesName.append(x) ConstraintGraphCost.add_node(x, domain=dom) problem.addVariable(x, dom) a = itertools.combinations(variablesName, 2) for i in a: #print("Considero ", i) stop = False for domItem1 in ConstraintGraphCost.nodes[i[0]]['domain']: if (stop): break else: for domItem2 in ConstraintGraphCost.nodes[i[1]]['domain']: if domItem1[0] == domItem2[0] and domItem1[1] == domItem2[ 1] and domItem1 != "notScheduled": #print("creo edge") ConstraintGraphCost.add_edge(i[0], i[1]) problem.addConstraint(constraintFunction(), (i[0], i[1])) stop = True break start = current_milli_time() solution = problem.getSolution() end = current_milli_time() print("\n\n###########Time spent to find the first solution = ", end - start, " ms.\n\n") # pp.pprint(solution) return solution
def computeChannels(self, n, k=2): from constraint import Problem from constraint import SomeInSetConstraint found = False nodes = tuple(self.nodes()) p = Problem() p.addVariables( list(self.nodes()), range(n, 0, -1) ) # reverse ordering the domain biases the constraint solver towards smaller numbers p.addConstraint(SomeInSetConstraint([1])) def addConstraint(node1, node2, dist, diff): if (node1 in node2.neighbors(dist)): p.addConstraint(lambda x, y: abs(x - y) >= diff, (node1, node2)) return True return False for i in xrange(len(nodes) - 1): n1 = nodes[i] for j in xrange(i + 1, len(nodes)): n2 = nodes[j] if (not addConstraint( n1, n2, 2, k)): # each node pair needs no more than 1 constraint addConstraint(n1, n2, 4, 1) for rowIter in self.rows(): row = tuple(rowIter) for i in xrange(len(row) - 1): p.addConstraint(lambda x, y: y == (x + k) % n + 1, (row[i], row[i + 1])) for colIter in self.columns(): col = tuple(colIter) for i in xrange(len(col) - 1): p.addConstraint(lambda x, y: y == (x + k - 1) % n + 1, (col[i], col[i + 1])) solution = p.getSolution() if (solution == None): return found found = True for node, channel in p.getSolution().iteritems(): node.channel = channel return True
def solve_board(overlays, verify_just_one=False): problem = Problem() spot_constraints = defaultdict(list) overlay_constraints = [] for overlay in overlays: # the simplest case is a fully 3x3 grid if len(overlay) == 3 and len(overlay[0]) == 3: for x in range(3): for y in range(3): if overlay[x][y] is None: continue spot_constraints[(x, y)].extend( get_constraints(overlay[x][y])) else: # dealing with a grid that is smaller than 3x3 so we # need to make relative constraints - we add those # after the all different constraint so it only needs # to look at possible boards overlay_constraints.append( (FunctionConstraint(floating_overlay(overlay)), locations)) # the unspecified spots could be any piece for x in range(3): for y in range(3): if (x, y) not in spot_constraints: spot_constraints[(x, y)] = pieces for spot, values in spot_constraints.iteritems(): problem.addVariable(spot, values) problem.addConstraint(AllDifferentConstraint()) for overlay_constraint in overlay_constraints: problem.addConstraint(*overlay_constraint) solution = None if verify_just_one: solutions = problem.getSolutions() assert len(solutions) == 1, ('%d solutions but there should be 1' % len(solutions)) solution = solutions[0] else: solution = problem.getSolution() answer = [[None] * 3 for x in range(3)] for x in range(3): for y in range(3): answer[x][y] = solution[(x, y)] print('\n'.join(' '.join(_) for _ in answer)) print('') return answer
def color(map, colors=['red', 'green', 'blue']): (vars, adjoins) = parse_map(map) p = Problem() p.addVariables(vars, colors) for (v1, v2) in adjoins: p.addConstraint(NEQ, [v1, v2]) solution = p.getSolution() if solution: for v in sorted(vars): print("{}:{} ".format(v, solution[v]), end='') print() else: print('No solution found :-(')
def run(self, dag): qubits = dag.qubits cxs = set() for gate in dag.two_qubit_ops(): cxs.add((qubits.index(gate.qargs[0]), qubits.index(gate.qargs[1]))) edges = set(self.coupling_map.get_edges()) if self.time_limit is None and self.call_limit is None: solver = RecursiveBacktrackingSolver() else: solver = CustomSolver(call_limit=self.call_limit, time_limit=self.time_limit) problem = Problem(solver) problem.addVariables(list(range(len(qubits))), self.coupling_map.physical_qubits) problem.addConstraint( AllDifferentConstraint()) # each wire is map to a single qubit if self.strict_direction: def constraint(control, target): return (control, target) in edges else: def constraint(control, target): return (control, target) in edges or (target, control) in edges for pair in cxs: problem.addConstraint(constraint, [pair[0], pair[1]]) random.seed(self.seed) solution = problem.getSolution() if solution is None: stop_reason = 'nonexistent solution' if isinstance(solver, CustomSolver): if solver.time_current is not None and solver.time_current >= self.time_limit: stop_reason = 'time limit reached' elif solver.call_current is not None and solver.call_current >= self.call_limit: stop_reason = 'call limit reached' else: stop_reason = 'solution found' self.property_set['layout'] = Layout( {v: qubits[k] for k, v in solution.items()}) self.property_set['CSPLayout_stop_reason'] = stop_reason
def sudoku(initValue): p = Problem() # Define a variable for each cell: 11,12,13...21,22,23...98,99 for i in range(1, 10): p.addVariables(range(i * 10 + 1, i * 10 + 10), range(1, 10)) # Each row has different values for i in range(1, 10): p.addConstraint(AllDifferentConstraint(), range(i * 10 + 1, i * 10 + 10)) # Each colum has different values for i in range(1, 10): p.addConstraint(AllDifferentConstraint(), range(10 + i, 100 + i, 10)) # Each 3x3 box has different values p.addConstraint(AllDifferentConstraint(), [11, 12, 13, 21, 22, 23, 31, 32, 33]) p.addConstraint(AllDifferentConstraint(), [41, 42, 43, 51, 52, 53, 61, 62, 63]) p.addConstraint(AllDifferentConstraint(), [71, 72, 73, 81, 82, 83, 91, 92, 93]) p.addConstraint(AllDifferentConstraint(), [14, 15, 16, 24, 25, 26, 34, 35, 36]) p.addConstraint(AllDifferentConstraint(), [44, 45, 46, 54, 55, 56, 64, 65, 66]) p.addConstraint(AllDifferentConstraint(), [74, 75, 76, 84, 85, 86, 94, 95, 96]) p.addConstraint(AllDifferentConstraint(), [17, 18, 19, 27, 28, 29, 37, 38, 39]) p.addConstraint(AllDifferentConstraint(), [47, 48, 49, 57, 58, 59, 67, 68, 69]) p.addConstraint(AllDifferentConstraint(), [77, 78, 79, 87, 88, 89, 97, 98, 99]) # add unary constraints for cells with initial non-zero values for i in range(1, 10): for j in range(1, 10): value = initValue[i - 1][j - 1] if value: p.addConstraint(lambda var, val=value: var == val, (i * 10 + j, )) return p.getSolution()
def solve(): problem = Problem() problem.addVariables(range(1, 21), ["A", "B", "C", "D", "E"]) problem.addConstraint(SomeInSetConstraint(["A"], 4, True)) problem.addConstraint(SomeInSetConstraint(["B"], 4, True)) problem.addConstraint(SomeInSetConstraint(["C"], 4, True)) problem.addConstraint(SomeInSetConstraint(["D"], 4, True)) problem.addConstraint(SomeInSetConstraint(["E"], 4, True)) for row in range(len(STUDENTDESKS) - 1): for col in range(len(STUDENTDESKS[row]) - 1): lst = [STUDENTDESKS[row][col], STUDENTDESKS[row][col + 1], STUDENTDESKS[row + 1][col], STUDENTDESKS[row + 1][col + 1]] lst = [x for x in lst if x] problem.addConstraint(AllDifferentConstraint(), lst) solutions = problem.getSolution() return solutions
def test_least_conflicts_solver(): # another test for LeastConflictsSolver problem = Problem(LeastConflictsSolver()) result = [[('a', 1), ('b', 2), ('c', 1)], [('a', 2), ('b', 1), ('c', 1)], [('a', 2), ('b', 2), ('c', 1)]] problem.addVariables(["a", "b"], [1, 2]) problem.addVariable("c", [1]) problem.addConstraint(lambda a, b: b != a, ["a", "b"]) problem.addConstraint(lambda a, b: b != a, ["a", "c"]) problem.addConstraint(lambda a, b: b != a, ["b", "c"]) solution = problem.getSolution() assert sorted(solution.items()) in result
def solver(domain, appointments): problem = Problem() # for each appointment (iterate on the numerical key of the appointments) for x in appointments: dom = [] # check which elements of the generic domain are necessary for this appointment for y in domain: hour, minutes = y[1].split(".") hour = int(hour) if "Morning" in appointments[x]["Pref"] and hour < 12 and y[ 0] in appointments[x]["Day"] and y[2] in appointments[x][ "House"]: dom.append(y) if "Afternoon" in appointments[x]["Pref"] and hour > 12 and y[ 0] in appointments[x]["Day"] and y[2] in appointments[x][ "House"]: dom.append(y) # print("FOR APPOINTMENT:\n") # pp.pprint(x) # print("The domain is:\n") # pp.pprint(dom) # add a variable to the CSP problem with the appointment *x* and the just computed domain *dom* problem.addVariable(x, dom) # add constraints for x in appointments: for y in appointments: if (x != y): problem.addConstraint(constraintFunction(), (x, y)) start = current_milli_time() solution = problem.getSolution() end = current_milli_time() print("\n\n###########Time spent to find the first solution = ", end - start, " ms.\n\n") # pp.pprint(solution) return solution
def solve(): problem = Problem() problem.addVariables(range(1, 21), ["A", "B", "C", "D", "E"]) problem.addConstraint(SomeInSetConstraint(["A"], 4, True)) problem.addConstraint(SomeInSetConstraint(["B"], 4, True)) problem.addConstraint(SomeInSetConstraint(["C"], 4, True)) problem.addConstraint(SomeInSetConstraint(["D"], 4, True)) problem.addConstraint(SomeInSetConstraint(["E"], 4, True)) for row in range(len(STUDENTDESKS) - 1): for col in range(len(STUDENTDESKS[row]) - 1): lst = [ STUDENTDESKS[row][col], STUDENTDESKS[row][col + 1], STUDENTDESKS[row + 1][col], STUDENTDESKS[row + 1][col + 1] ] lst = [x for x in lst if x] problem.addConstraint(AllDifferentConstraint(), lst) solutions = problem.getSolution() return solutions
def solve_puzzles(puzzles, solver): """ Solves an array of sudoku puzzles, recording runtime. :param puzzles: an array of 2D array boards :param solver: the CSP solver to be used :return: none """ fail_count = 0 start_time = datetime.now() # start timer (for runtime) for puzzle in puzzles: # initialize Board b = Board(puzzle) sudoku = Problem(solver) # initialize CSP with custom solver # add variables for each square, indexed 1...size^2 for index in range(b.board_size ** 2): value = b.get_value(index) if value == 0: sudoku.addVariable(index, range(1, b.board_size + 1)) else: sudoku.addVariable(index, [value]) # add uniqueness constraints to each row, column, and subsquare for i in range(b.board_size): sudoku.addConstraint(AllDifferentConstraint(), [el[0] for el in b.row(i)]) sudoku.addConstraint(AllDifferentConstraint(), [el[0] for el in b.col(i)]) sudoku.addConstraint(AllDifferentConstraint(), [el[0] for el in b.subsquare(i)]) sln = sudoku.getSolution() # solve CSP if sln: # assign solved values for index, value in sln.items(): b.set_value(index, value) else: fail_count += 1 # perform/display runtime calculation runtime = datetime.now() - start_time print("Runtime: {} seconds ({} failed)".format(runtime.total_seconds(), fail_count))
def gen_disjunct_intervals_CSP(ints): p = Problem() size = len(ints) sizeL = range(size) for intnum, key in enumerate(ints): values = [[]] for i in sizeL: values += [ item for item in it.combinations(ints, i + 1) if key in item ] p.addVariable(intnum, values) for i in sizeL: p.addConstraint(check_continuity, (i, )) for i1, i2 in it.product(sizeL, sizeL): if i1 < i2: p.addConstraint(check_all, (i1, i2)) p.addConstraint(all_interval, sizeL) return p.getSolution()
def gen_disjunct_intervals_CSP(ints): p = Problem() size = len(ints) sizeL = range(size) for intnum, key in enumerate(ints): values = [[]] for i in sizeL: values += [ item for item in it.combinations(ints, i + 1) if key in item ] p.addVariable(intnum, values) for i in sizeL: p.addConstraint(check_continuity, (i,)) for i1, i2 in it.product(sizeL, sizeL): if i1 < i2: p.addConstraint(check_all, (i1, i2)) p.addConstraint(all_interval, sizeL) return p.getSolution()
def solve_board(board, cages): problem = Problem() height = len(board) width = len(board[0]) assert width == height, 'Grid must be a square' cage_name_to_locations = defaultdict(list) for x in range(height): row_variables = [(x, ry) for ry in range(width)] column_variables = [(cx, x) for cx in range(height)] problem.addConstraint(AllDifferentConstraint(), row_variables) problem.addConstraint(AllDifferentConstraint(), column_variables) for y in range(width): if isinstance(board[x][y], basestring): # we are dealing with a function cage_name_to_locations[board[x][y]].append((x, y)) else: # we are dealing with a pre-assigned number problem.addVariable((x, y), [board[x][y]]) for cage_name, cage_locations in cage_name_to_locations.iteritems(): cage_function = cages[cage_name] all_values = product(range(1, width + 1), repeat=len(cage_locations)) possible_values = set(chain(*[values for values in all_values if cage_function(*values)])) for location in cage_locations: problem.addVariable(location, list(possible_values)) problem.addConstraint(FunctionConstraint(cage_function), cage_locations) solution = problem.getSolution() answer = [row[:] for row in board] for x in range(height): for y in range(width): answer[x][y] = solution[(x, y)] return answer
def test_addVariable_support_domain_subclasses(): class MyCustomDomain(Domain): pass class MyConstraint(Constraint): def __call__(self, variables, domains, assignments, forwardcheck=False): assert isinstance(domains['x'], Domain) assert isinstance(domains['y'], MyCustomDomain) return True problem = Problem() problem.addVariable("x", [0, 1]) problem.addVariable("y", MyCustomDomain([0, 1])) problem.addConstraint(MyConstraint()) solution = problem.getSolution() possible_solutions = [ { "x": 0, "y": 0 }, { "x": 0, "y": 1 }, { "x": 1, "y": 0 }, { "x": 1, "y": 1 }, ] assert solution in possible_solutions
def determine(state): card_played_this_round = [ card is not None and 1 or 0 for card in state.cards_played_by_player ] remaining_hand_size = 5 - sum(state.tricks_won_by_team) hand_size_by_player = [ remaining_hand_size - played for played in card_played_this_round ] cards = list( set(deal()) - set(list(chain(*state.hands))) - set(state.cards_played)) shuffle(cards) problem = Problem() for player in range(4): if state.hands[player]: for card_index, card in enumerate(state.hands[player]): problem.addVariable((player, card_index), [card]) else: voids_by_player = state.voids_by_player[player] for card_index in range(hand_size_by_player[player]): if voids_by_player: potential_cards = potential_cards_given_voids( state.trump, voids_by_player, cards) shuffle(potential_cards) problem.addVariable((player, card_index), potential_cards) else: problem.addVariable((player, card_index), cards) problem.addConstraint(AllDifferentConstraint()) cards = sorted(iteritems(problem.getSolution())) hands = [[], [], [], []] for player in range(4): hands[player] = [c[1] for c in cards[:hand_size_by_player[player]]] del cards[:hand_size_by_player[player]] state = state._replace(hands=hands) return state
def determine(state): card_played_this_round = [card is not None and 1 or 0 for card in state.cards_played_by_player] remaining_hand_size = 5 - sum(state.tricks_won_by_team) hand_size_by_player = [remaining_hand_size - played for played in card_played_this_round] cards = list(set(deal()) - set(list(chain(*state.hands))) - set(state.cards_played)) shuffle(cards) problem = Problem() for player in range(4): if state.hands[player]: for card_index, card in enumerate(state.hands[player]): problem.addVariable((player, card_index), [card]) else: voids_by_player = state.voids_by_player[player] for card_index in range(hand_size_by_player[player]): if voids_by_player: potential_cards = potential_cards_given_voids( state.trump, voids_by_player, cards) shuffle(potential_cards) problem.addVariable((player, card_index), potential_cards) else: problem.addVariable((player, card_index), cards) problem.addConstraint(AllDifferentConstraint()) cards = sorted(iteritems(problem.getSolution())) hands = [[], [], [], []] for player in range(4): hands[player] = [c[1] for c in cards[:hand_size_by_player[player]]] del cards[:hand_size_by_player[player]] state = state._replace(hands=hands) return state
def run(self, dag): try: from constraint import Problem, RecursiveBacktrackingSolver, AllDifferentConstraint except ImportError: raise TranspilerError('CSPLayout requires python-constraint to run. ' 'Run pip install python-constraint') qubits = dag.qubits() cxs = set() for gate in dag.twoQ_gates(): cxs.add((qubits.index(gate.qargs[0]), qubits.index(gate.qargs[1]))) edges = self.coupling_map.get_edges() problem = Problem(RecursiveBacktrackingSolver()) problem.addVariables(list(range(len(qubits))), self.coupling_map.physical_qubits) problem.addConstraint(AllDifferentConstraint()) # each wire is map to a single qbit if self.strict_direction: def constraint(control, target): return (control, target) in edges else: def constraint(control, target): return (control, target) in edges or (target, control) in edges for pair in cxs: problem.addConstraint(constraint, [pair[0], pair[1]]) random.seed(self.seed) solution = problem.getSolution() if solution is None: return self.property_set['layout'] = Layout({v: qubits[k] for k, v in solution.items()})
class GraphletsConstraints(X86AnalyzerBase): #__registers32Bit = ["eax","ebx","ecx","edx","esi","edi","ebp","esp"] __dictNames = ['ref', 'tar'] __printConds = False def __init__(self, nodeGradesInfos=[]): X86AnalyzerBase.__init__(self, nodeGradesInfos) self.problem = Problem(MinConflictsSolver()) # this is to make it human readable .. # we will generator the solution only when we need it and then cache it # TODO make __ self.sol = None for key in self.rewriteDict.keys(): self.rewriteDict[key]['symbolCache'] = {} self.rewriteDict[key]['curLine'] = 1 self.rewriteDict[key]['curPos'] = 1 self.createRewrite() def getEmptyDict(self): d = X86AnalyzerBase.getEmptyDict(self) for key in d.keys(): d[key]['transitions'] = [] d[key]['valuesTrackDict'] = {} #if key != self.REGISTER: d[key]['domain'] = set() #self.rewriteDict[key]['inCmdCounter'] = 1 return d # this will add recorded value to dict, even if there is a conflict it will be recorded... # def insertToDictWithType(self, tarCmdNum, fromStr, refCmdNum, toStr, typeStr, dict2insert=None): assert (dict2insert != None) dict2insert[typeStr]['transitions'].append((tarCmdNum, fromStr, toStr)) #if typeStr != self.REGISTER: dict2insert[typeStr]['domain'].add(toStr) def commitChanges(self, tmpDict): for key in self.rewriteDict.keys(): self.rewriteDict[key]['transitions'].extend( tmpDict[key]['transitions']) #if key != self.REGISTER: self.rewriteDict[key]['domain'].update(tmpDict[key]['domain']) # black list has no generation:) , we can use the rwdict type as they are the same.. def getRewriteWithType(self, tarCmdNum, fromStr, typeStr, FoundBlacklistElement): if self.sol == None: self.callSol() if self.rewriteDict[typeStr]['curLine'] < tarCmdNum: self.rewriteDict[typeStr]['curLine'] = tarCmdNum self.rewriteDict[typeStr]['curPos'] = 1 varName = self.getVarName(self.getShort(typeStr), tarCmdNum, self.rewriteDict[typeStr]['curPos']) self.rewriteDict[typeStr]['curPos'] += 1 if self.sol != None and varName in self.sol: # we have a value! update cache and return it newVal = self.sol[varName] self.rewriteDict[typeStr]['symbolCache'][fromStr] = newVal return newVal elif fromStr in self.rewriteDict[typeStr]['symbolCache']: return self.rewriteDict[typeStr]['symbolCache'][fromStr] else: #not found in this type's map in this generation, return original return fromStr def getShort(self, name): if name == self.FUNCNAME: return "f" elif name == self.VAR: return "m" elif name == self.REGISTER: return "r" else: raise hell def getVarName(self, preFix, curLine, curPos): return preFix + str(curLine) + "-" + str(curPos) + "_TAR" # TODO - make this __ def callSol(self): # we need to go over each dict that is useable, and feed vars and constraints for typeDict in [ x for x in self.rewriteDict.keys() if self.rewriteDict[x]['useAble'] == True ]: curLine = 1 curPos = 1 preFix = self.getShort(typeDict) #if typeDict != self.REGISTER: domain = list(self.rewriteDict[typeDict]['domain']) #else: # domain =self.__registers32Bit for (line, tarStr, refStr) in self.rewriteDict[typeDict]['transitions']: if curLine < line: curPos = 1 curLine = line tarName = self.getVarName(preFix, curLine, curPos) self.problem.addVariables([tarName], domain) if (self.__printConds): print "CONS(text) -> " + tarName + " == " + refStr self.problem.addConstraint(self.checkInputVsTarget(refStr), [tarName]) if tarStr in self.rewriteDict[typeDict][ 'valuesTrackDict'] != None: if (self.__printConds): print "CONS(bag) -> " + self.rewriteDict[typeDict][ 'valuesTrackDict'][tarStr] + " == " + tarName self.problem.addConstraint(self.varsEqual, [ tarName, self.rewriteDict[typeDict]['valuesTrackDict'][tarStr] ]) self.rewriteDict[typeDict]['valuesTrackDict'][tarStr] = tarName curPos += 1 self.sol = self.problem.getSolution() if traceHack: print "(Number of broken - " + str( self.problem.getSolver().getHack()) + ")", def varsEqual(self, v1, v2): return v1 == v2 def checkInputVsTarget(self, target): def retFunc(inputVal): return inputVal == target return retFunc def getSolution(self): if self.sol == None: self.callSol() return self.sol def printSol(self, sol): #better call sol! if sol == None: print "NO SOL!" return last = 1 for key in sorted(sol.iterkeys()): if int(key[1:2]) != last: last = int(key[1:2]) print "" print key + ": " + sol[key] + " ", def getBrokenNumber(self): return self.problem.getSolver().getHack()
class GraphletsConstraints(RWEngineBase): __printConds = False def __init__(self, nodeGradesInfos): self.nodeGradesInfos = nodeGradesInfos self.sol = None # a field is somthing seperated by " " , an argument is a list of params seperated by "," ; a member is a param seperated by "+" def breakCommand(self, cmd): cmdFields = seperateCmd(cmd) if len(cmdFields) == 0: print "asd" assert (len(cmdFields) > 0) if len(cmdFields) == 1: return { 'nemonic': cmdFields[0], 'nemonicWithDecoretors': " ".join(cmdFields[0:-1]), 'ParamsList': [] } else: return { 'nemonic': cmdFields[0], 'nemonicWithDecoretors': " ".join(cmdFields[0:-1]), 'ParamsList': cmdFields[-1].split(",") } #TODO - add to this.. lvalCmdsStarts = ["mov", "sub", "add", "xor"] def getNemonicType(self, nemonic): if any( map(lambda startString: nemonic.startswith(startString), self.lvalCmdsStarts)): return "WriteThenRead" else: return "Read" FuncPrefix = "f" VARPrefix = "s" RegisterPrefix = "r" OffsetPrefix = "o" OtherPrefix = "X" def getPrefix(self, Str): if isVarStr(Str): return self.VARPrefix elif isRegisterStr(Str): return self.RegisterPrefix elif isOffset(Str): return self.OffsetPrefix else: return self.OtherPrefix def varsEqual(self, v1, v2): return v1 == v2 def checkInputVsTarget(self, target): def retFunc(inputVal): return inputVal == target return retFunc def getVarName(self, prefix, lineNumber, varsInThisLine): return prefix + str(lineNumber) + "-" + str(varsInThisLine) + "_TAR" def getMembers(self, param): refMembers = param.split("+") refMembers[0] = refMembers[0][1:] #remove [ from first refMembers[-1] = refMembers[-1][ 0:-1] # remove ] from last (they can be the same one!) return refMembers def getDomains(self): domains = { self.FuncPrefix: set(), self.VARPrefix: set(), self.RegisterPrefix: set(), self.OffsetPrefix: set() } def getCmdSymbols(cmd): cmdBasicInfo = self.breakCommand(cmd) for param in cmdBasicInfo['ParamsList']: if param.startswith("["): for member in self.getMembers(param): yield member else: yield param def getCmds(cmdsDelimited): return filter(None, cmdsDelimited.split(";")) for cmdList in itertools.imap( lambda nodeGradesInfo: getCmds(nodeGradesInfo['refCode']), self.nodeGradesInfos): for cmd in cmdList: if isCall(cmd): prefix = self.FuncPrefix domains[prefix].add(list(getCmdSymbols(cmd))[0]) else: for symbol in getCmdSymbols(cmd): prefix = self.getPrefix(symbol) if prefix != self.OtherPrefix: domains[prefix].add(symbol) for domainName in domains.keys(): domains[domainName] = list(domains[domainName]) return domains def callSol(self): domains = self.getDomains() #domains[refPrefix].add(refVal) self.problem = Problem(MinConflictsSolver()) tarSymbolsCache = {} self.varsInThisLine = 0 def addInTraceletCons(tarVal, newVarName): if (self.__printConds): print "CONS(IN) -> " + tarSymbolsCache[ tarVal] + " == " + newVarName self.problem.addConstraint(self.varsEqual, [newVarName, tarSymbolsCache[tarVal]]) def addCrossTraceletCons(refVal, newVarName, refPrefix): if (self.__printConds): print "CONS(CROSS) -> " + newVarName + " == " + refVal self.problem.addConstraint(self.checkInputVsTarget(refVal), [newVarName]) def addVarWithPrefix(prefix, lineNumber): newVarName = self.getVarName(prefix, lineNumber, self.varsInThisLine) if len(domains[prefix]) == 0: print "EMP" self.problem.addVariables([newVarName], domains[prefix]) self.varsInThisLine += 1 return newVarName # mode can be - WRITE or NORMAL def doDF(refSymbol, tarSymbol, lineNumber, refPrefix, tarPrefix, nemonicType): if refPrefix == self.OtherPrefix or tarPrefix == self.OtherPrefix: return newVarName = addVarWithPrefix(tarPrefix, lineNumber) if (refPrefix == tarPrefix): addCrossTraceletCons(refSymbol, newVarName, refPrefix) if tarSymbol in tarSymbolsCache: addInTraceletCons(tarSymbol, newVarName) if tarPrefix != self.RegisterPrefix or nemonicType == "WriteThenRead": tarSymbolsCache[tarSymbol] = newVarName #for matchedCmd in itertools.chain(map(lambda nodeInfo:nodeInfo['matchedCmds'],self.nodeGradesInfos)): tarBase = 0 refBase = 0 for nodeInfo in self.nodeGradesInfos: for matchedCmd in nodeInfo['matchedCmds']: self.varsInThisLine = 1 # if these cmds are not an operational match, we cannot cross tracelet match them. if matchedCmd['operationMatch'] == True: currentLineNumber = tarBase + matchedCmd[ 'tarCmdNum'] # matchedCmd['tarCmdNum'] is 1 based so we are ok if matchedCmd['tar'] == "" or matchedCmd['ref'] == "": continue tarCmdBasicInfo = self.breakCommand(matchedCmd['tar']) refCmdBasicInfo = self.breakCommand(matchedCmd['ref']) if len(tarCmdBasicInfo['ParamsList']) > 0 and len( refCmdBasicInfo['ParamsList']) > 0: if tarCmdBasicInfo['nemonic'] == 'call': assert (len(refCmdBasicInfo['ParamsList']) == 1) assert (len(tarCmdBasicInfo['ParamsList']) == 1) doDF(refCmdBasicInfo['ParamsList'][0], tarCmdBasicInfo['ParamsList'][0], currentLineNumber, self.FuncPrefix, self.FuncPrefix, "Read") else: nemonicType = self.getNemonicType( tarCmdBasicInfo['nemonic']) for (refParam, tarParam) in zip( refCmdBasicInfo['ParamsList'], tarCmdBasicInfo['ParamsList']): tarIsMem = "[" in tarParam if tarIsMem != ("[" in refParam): continue print matchedCmd print "BOY" assert tarIsMem == ("[" in refParam) if not tarIsMem: tarPreFix = self.getPrefix(tarParam) refPreFix = self.getPrefix(refParam) doDF(refParam, tarParam, currentLineNumber, tarPreFix, refPreFix, nemonicType) # TODO - return this to find more classes when we have time... """ if nemonicType == "WriteThenRead": if tarPreFix != self.RegisterPrefix: print matchedCmd assert (tarPreFix == self.RegisterPrefix) # the write is only to the left most param, rest are normal """ else: # this is memory! , first remove '[',']' for (refMember, tarMember) in zip( self.getMembers(refParam), self.getMembers(tarParam)): tarPreFix = self.getPrefix(tarMember) refPreFix = self.getPrefix(refMember) doDF(refMember, tarMember, currentLineNumber, tarPreFix, refPreFix, nemonicType) nemonicType = "Read" #TODO handle the False clause ? tarBase += nodeInfo['tarCode'].count(";") refBase += nodeInfo['refCode'].count(";") self.sol = self.problem.getSolution() #print self.sol def getBrokenNumber(self): return self.problem.getSolver().getHack() # TODO - make this __ def getRW(self): sol = self.getSolution() tarBase = 0 symbolsCache = {} self.varsInThisLine = 0 TotalLineNumber = 0 def getRewrittenSymbolUpdateCache(prefix, symbol): varName = self.getVarName(prefix, TotalLineNumber, self.varsInThisLine) if sol != None and varName in sol: symbolsCache[symbol] = sol[varName] return sol[varName] else: return symbol def rewrittenParam(param): if param.startswith("["): rewrittenMembers = [] for member in self.getMembers(param): rewrittenMembers.append( getRewrittenSymbolUpdateCache(self.getPrefix(member), member)) self.varsInThisLine += 1 return "[" + "+".join(rewrittenMembers) + "]" else: newParam = getRewrittenSymbolUpdateCache( self.getPrefix(param), param) self.varsInThisLine += 1 return newParam for nodeInfo in self.nodeGradesInfos: cmdsStr = nodeInfo['tarCode'] rewrittenCmds = [] lastLineNumber = 0 #filter(None,) for (lineNumber, cmd) in enumerate(cmdsStr.split(";")): TotalLineNumber = tarBase + lineNumber + 1 # we are one based lastLineNumber = lineNumber + 1 # we are one based self.varsInThisLine = 1 if cmd != "": tarCmdBasicInfo = self.breakCommand(cmd) if len(tarCmdBasicInfo['ParamsList']) > 0: if tarCmdBasicInfo['nemonic'] == 'call': rewrittenCmds.append( "call " + getRewrittenSymbolUpdateCache( self.FuncPrefix, tarCmdBasicInfo['ParamsList'][0])) else: rewrittenCmds.append( tarCmdBasicInfo['nemonicWithDecoretors'] + " " + ",".join( map(rewrittenParam, tarCmdBasicInfo['ParamsList']))) else: rewrittenCmds.append(cmd) else: # this mostly cuz of bugs, but if i wont accumidate them it will cause a bad grade for nothing..(everything else wont be aligned) rewrittenCmds.append(cmd) tarBase += lastLineNumber - 1 yield ";".join(rewrittenCmds) def getSolution(self): if self.sol == None: self.callSol() return self.sol def printSol(self, sol): #better call sol! if sol == None: print "NO SOL!" return last = 1 for key in sorted(sol.iterkeys()): if int(key[1:2]) != last: last = int(key[1:2]) print "" print key + ": " + sol[key] + " ",
def run(self, dag): try: from constraint import Problem, RecursiveBacktrackingSolver, AllDifferentConstraint except ImportError: raise TranspilerError( 'CSPLayout requires python-constraint to run. ' 'Run pip install python-constraint') qubits = dag.qubits() cxs = set() for gate in dag.twoQ_gates(): cxs.add((qubits.index(gate.qargs[0]), qubits.index(gate.qargs[1]))) edges = self.coupling_map.get_edges() class CustomSolver(RecursiveBacktrackingSolver): """A wrap to RecursiveBacktrackingSolver to support ``call_limit``""" def __init__(self, call_limit=None, time_limit=None): self.call_limit = call_limit self.time_limit = time_limit self.call_current = None self.time_start = None self.time_current = None super().__init__() def limit_reached(self): """Checks if a limit is reached.""" if self.call_current is not None: self.call_current += 1 if self.call_current > self.call_limit: return True if self.time_start is not None: self.time_current = time() - self.time_start if self.time_current > self.time_limit: return True return False def getSolution( self, # pylint: disable=invalid-name domains, constraints, vconstraints): """Wrap RecursiveBacktrackingSolver.getSolution to add the limits.""" if self.call_limit is not None: self.call_current = 0 if self.time_limit is not None: self.time_start = time() return super().getSolution(domains, constraints, vconstraints) def recursiveBacktracking( self, # pylint: disable=invalid-name solutions, domains, vconstraints, assignments, single): """Like ``constraint.RecursiveBacktrackingSolver.recursiveBacktracking`` but limited in the amount of calls by ``self.call_limit`` """ if self.limit_reached(): return None return super().recursiveBacktracking(solutions, domains, vconstraints, assignments, single) if self.time_limit is None and self.call_limit is None: solver = RecursiveBacktrackingSolver() else: solver = CustomSolver(call_limit=self.call_limit, time_limit=self.time_limit) problem = Problem(solver) problem.addVariables(list(range(len(qubits))), self.coupling_map.physical_qubits) problem.addConstraint( AllDifferentConstraint()) # each wire is map to a single qbit if self.strict_direction: def constraint(control, target): return (control, target) in edges else: def constraint(control, target): return (control, target) in edges or (target, control) in edges for pair in cxs: problem.addConstraint(constraint, [pair[0], pair[1]]) random.seed(self.seed) solution = problem.getSolution() if solution is None: stop_reason = 'nonexistent solution' if isinstance(solver, CustomSolver): if solver.time_limit is not None and solver.time_current >= self.time_limit: stop_reason = 'time limit reached' elif solver.call_limit is not None and solver.call_current >= self.call_limit: stop_reason = 'call limit reached' else: stop_reason = 'solution found' self.property_set['layout'] = Layout( {v: qubits[k] for k, v in solution.items()}) self.property_set['CSPLayout_stop_reason'] = stop_reason
class Solver(object): problem = None pilots, missions, pilot_prefs = None, None, None uas_max = None # variables pilot_vars, mission_vars = [], [] max_obj = 0 def __init__(self, pilot_map=None, mission_map=None, uas_max=None, pilot_prefs=None): self.problem = Problem(MinConflictsSolver()) self.pilots = pilot_map self.missions = mission_map self.uas_max = uas_max self.pilot_prefs = pilot_prefs def build_variables(self): # pilot-uas variable for key, val in self.pilots.iteritems(): self.problem.addVariable(key, val) self.pilot_vars.append(key) # mission-uas variable for key, val in self.missions.iteritems(): self.problem.addVariable(key, val) self.mission_vars.append(key) def build_constraints(self): # all pilots assigned to different self.problem.addConstraint(AllDifferentConstraint(), self.pilot_vars) # missions must be assigned uas only if a pilot has been assigned to it for mission in self.mission_vars: mission_and_all_pilots = [mission] + self.pilot_vars self.problem.addConstraint( self.__assign__mission_from_assigned_pilots_only, mission_and_all_pilots) # no uas can be assigned to more than 3 missions self.problem.addConstraint(self.__limit_mission_uas, self.mission_vars) def __assign__mission_from_assigned_pilots_only(self, *mission_and_all_pilots): mission = mission_and_all_pilots[0] i = 1 for i in range(1, len(mission_and_all_pilots)): if mission == mission_and_all_pilots[i]: return True return False def __limit_mission_uas(self, *missions): mission_count = {} for i in range(0, self.uas_max + 1): mission_count[i] = 0 for mission in missions: mission_count[mission] += 1 for val in mission_count.itervalues(): if val > 3: return False return True def get_solution(self): return self.problem.getSolution()
class GraphletsConstraints(X86AnalyzerBase): #__registers32Bit = ["eax","ebx","ecx","edx","esi","edi","ebp","esp"] __dictNames = ['ref','tar'] __printConds = False def __init__(self,nodeGradesInfos=[]): X86AnalyzerBase.__init__(self,nodeGradesInfos) self.problem = Problem(MinConflictsSolver()) # this is to make it human readable .. # we will generator the solution only when we need it and then cache it # TODO make __ self.sol = None for key in self.rewriteDict.keys(): self.rewriteDict[key]['symbolCache'] = {} self.rewriteDict[key]['curLine'] = 1 self.rewriteDict[key]['curPos'] = 1 self.createRewrite() def getEmptyDict(self): d = X86AnalyzerBase.getEmptyDict(self) for key in d.keys(): d[key]['transitions'] = [] d[key]['valuesTrackDict'] = {} #if key != self.REGISTER: d[key]['domain'] = set() #self.rewriteDict[key]['inCmdCounter'] = 1 return d # this will add recorded value to dict, even if there is a conflict it will be recorded... # def insertToDictWithType(self,tarCmdNum,fromStr,refCmdNum,toStr,typeStr,dict2insert=None): assert(dict2insert != None) dict2insert[typeStr]['transitions'].append((tarCmdNum,fromStr,toStr)) #if typeStr != self.REGISTER: dict2insert[typeStr]['domain'].add(toStr) def commitChanges(self,tmpDict): for key in self.rewriteDict.keys(): self.rewriteDict[key]['transitions'].extend(tmpDict[key]['transitions']) #if key != self.REGISTER: self.rewriteDict[key]['domain'].update(tmpDict[key]['domain']) # black list has no generation:) , we can use the rwdict type as they are the same.. def getRewriteWithType(self,tarCmdNum,fromStr,typeStr,FoundBlacklistElement): if self.sol == None: self.callSol() if self.rewriteDict[typeStr]['curLine'] < tarCmdNum : self.rewriteDict[typeStr]['curLine'] = tarCmdNum self.rewriteDict[typeStr]['curPos'] = 1 varName = self.getVarName(self.getShort(typeStr), tarCmdNum, self.rewriteDict[typeStr]['curPos']) self.rewriteDict[typeStr]['curPos'] += 1 if self.sol != None and varName in self.sol: # we have a value! update cache and return it newVal = self.sol[varName] self.rewriteDict[typeStr]['symbolCache'][fromStr] = newVal return newVal elif fromStr in self.rewriteDict[typeStr]['symbolCache']: return self.rewriteDict[typeStr]['symbolCache'][fromStr] else: #not found in this type's map in this generation, return original return fromStr def getShort(self,name): if name == self.FUNCNAME: return "f" elif name == self.VAR: return "m" elif name == self.REGISTER: return "r" else : raise hell def getVarName(self,preFix,curLine,curPos): return preFix + str(curLine) + "-" + str(curPos) + "_TAR" # TODO - make this __ def callSol(self): # we need to go over each dict that is useable, and feed vars and constraints for typeDict in [x for x in self.rewriteDict.keys() if self.rewriteDict[x]['useAble']==True ]: curLine = 1 curPos = 1 preFix = self.getShort(typeDict) #if typeDict != self.REGISTER: domain = list(self.rewriteDict[typeDict]['domain']) #else: # domain =self.__registers32Bit for (line,tarStr,refStr) in self.rewriteDict[typeDict]['transitions']: if curLine < line: curPos = 1 curLine = line tarName = self.getVarName(preFix, curLine, curPos) self.problem.addVariables([tarName],domain) if (self.__printConds): print "CONS(text) -> " + tarName + " == " + refStr self.problem.addConstraint(self.checkInputVsTarget(refStr),[tarName]) if tarStr in self.rewriteDict[typeDict]['valuesTrackDict'] != None: if (self.__printConds): print "CONS(bag) -> " + self.rewriteDict[typeDict]['valuesTrackDict'][tarStr] + " == " + tarName self.problem.addConstraint(self.varsEqual,[tarName,self.rewriteDict[typeDict]['valuesTrackDict'][tarStr]]) self.rewriteDict[typeDict]['valuesTrackDict'][tarStr] = tarName curPos+=1 self.sol = self.problem.getSolution() if traceHack: print "(Number of broken - " + str(self.problem.getSolver().getHack()) + ")", def varsEqual(self,v1, v2): return v1==v2 def checkInputVsTarget(self,target): def retFunc(inputVal): return inputVal == target return retFunc def getSolution(self): if self.sol == None: self.callSol() return self.sol def printSol(self,sol): #better call sol! if sol == None: print "NO SOL!" return last = 1 for key in sorted(sol.iterkeys()): if int(key[1:2]) != last: last = int(key[1:2]) print "" print key + ": " + sol[key] + " ", def getBrokenNumber(self): return self.problem.getSolver().getHack()
def rank(tree): @extend(node.number) def _rank(self): problem.addVariable(id(self),[0]) @extend(node.let) def _rank(self): if isinstance(self.ret,node.ident): # plain assignment -- not a field, lhs indexing vars = [id(self.ret), id(self.args)] try: problem.addVariables(vars,list(range(4))) problem.addConstraint(operator.__eq__,vars) except ValueError: pass else: # lhs indexing or field pass @extend(node.for_stmt) def _rank(self): vars = [id(self.ident), id(self.expr)] problem.addVariables(vars,list(range(4))) problem.addConstraint((lambda u,v: u+1==v),vars) @extend(node.if_stmt) def _rank(self): # could use operator.__not__ instead of lambda expression problem.addVariable(id(self.cond_expr),list(range(4))) problem.addConstraint(lambda t: t==0, [id(self.cond_expr)]) @extend(node.ident) def _rank(self): try: x = id(self) problem.addVariable(x,list(range(4))) for other in self.defs: y = id(other) try: problem.addVariable(y,list(range(4))) except ValueError: pass problem.addConstraint(operator.__eq__, [x,y]) except: print("Ignored ",self) """ @extend(funcall) def rank(self,problem): if not isinstance(self.func_expr,ident): # In MATLAB, chaining subscripts, such as size(a)(1) # is not allowed, so only fields and dot expressions # go here. In Octave, chaining subscripts is allowed, # and such expressions go here. return try: if defs.degree(self.func_expr): # If a variable is defined, it is not a function, # except function handle usages, such as # foo=@size; foo(17) # which is not handled properly yet. x = id(self.func_expr) n = len(self.args) problem.addVariable(x,range(4)) problem.addConstraint((lambda u: u>=n),[x]) return except TypeError: # func_expr is unhashable # For example [10 20 30](2) return except KeyError: # See tests/clear_margins.m return assert getattr(self.func_expr,"name",None) # So func_expr is an undefined variable, and we understand # it's a function call -- either builtin or user-defined. name = self.func_expr.name # if name not in builtins: # # User-defined function # return # builtins[name](self,problem) # #@extend(expr) #def rank(self,problem): # try: # builtins[self.op](self,problem) # except: # pass """ problem = Problem(RecursiveBacktrackingSolver()) for v in node.postorder(tree): for u in v: try: u._rank() except AttributeError: pass s = problem.getSolution() if not s: print("No solutions") else: d = set() #for k in sorted(G.nodes(), key=lambda t: (t.name,t.lexpos)): for k in node.postorder(tree): if isinstance(k,node.ident): print(k.name,k.lineno, s.get(id(k),-1))
def main(puzzle, lines): puzzle = puzzle.rstrip().splitlines() while puzzle and not puzzle[0]: del puzzle[0] # Extract horizontal words horizontal = [] word = [] predefined = {} for row in range(len(puzzle)): for col in range(len(puzzle[row])): char = puzzle[row][col] if not char.isspace(): word.append((row, col)) if char != "#": predefined[row, col] = char elif word: if len(word) > MINLEN: horizontal.append(word[:]) del word[:] if word: if len(word) > MINLEN: horizontal.append(word[:]) del word[:] # Extract vertical words vertical = [] validcol = True col = 0 while validcol: validcol = False for row in range(len(puzzle)): if col >= len(puzzle[row]): if word: if len(word) > MINLEN: vertical.append(word[:]) del word[:] else: validcol = True char = puzzle[row][col] if not char.isspace(): word.append((row, col)) if char != "#": predefined[row, col] = char elif word: if len(word) > MINLEN: vertical.append(word[:]) del word[:] if word: if len(word) > MINLEN: vertical.append(word[:]) del word[:] col += 1 # hnames = ["h%d" % i for i in range(len(horizontal))] # vnames = ["v%d" % i for i in range(len(vertical))] # problem = Problem(MinConflictsSolver()) problem = Problem() for hi, hword in enumerate(horizontal): for vi, vword in enumerate(vertical): for hchar in hword: if hchar in vword: hci = hword.index(hchar) vci = vword.index(hchar) problem.addConstraint( lambda hw, vw, hci=hci, vci=vci: hw[hci] == vw[vci], ("h%d" % hi, "v%d" % vi)) for char, letter in predefined.items(): for hi, hword in enumerate(horizontal): if char in hword: hci = hword.index(char) problem.addConstraint( lambda hw, hci=hci, letter=letter: hw[hci] == letter, ("h%d" % hi, )) for vi, vword in enumerate(vertical): if char in vword: vci = vword.index(char) problem.addConstraint( lambda vw, vci=vci, letter=letter: vw[vci] == letter, ("v%d" % vi, )) wordsbylen = {} for hword in horizontal: wordsbylen[len(hword)] = [] for vword in vertical: wordsbylen[len(vword)] = [] for line in lines: line = line.strip() l = len(line) if l in wordsbylen: wordsbylen[l].append(line.upper()) for hi, hword in enumerate(horizontal): words = wordsbylen[len(hword)] random.shuffle(words) problem.addVariable("h%d" % hi, words) for vi, vword in enumerate(vertical): words = wordsbylen[len(vword)] random.shuffle(words) problem.addVariable("v%d" % vi, words) problem.addConstraint(AllDifferentConstraint()) solution = problem.getSolution() if not solution: print("No solution found!") maxcol = 0 maxrow = 0 for hword in horizontal: for row, col in hword: if row > maxrow: maxrow = row if col > maxcol: maxcol = col for vword in vertical: for row, col in vword: if row > maxrow: maxrow = row if col > maxcol: maxcol = col matrix = [] for row in range(maxrow + 1): matrix.append([" "] * (maxcol + 1)) for variable in solution: if variable[0] == "v": word = vertical[int(variable[1:])] else: word = horizontal[int(variable[1:])] for (row, col), char in zip(word, solution[variable]): matrix[row][col] = char for row in range(maxrow + 1): for col in range(maxcol + 1): sys.stdout.write(matrix[row][col]) sys.stdout.write("\n")
class GraphletsConstraints(RWEngineBase): __printConds = False def __init__(self,nodeGradesInfos): self.nodeGradesInfos = nodeGradesInfos self.sol = None # a field is somthing seperated by " " , an argument is a list of params seperated by "," ; a member is a param seperated by "+" def breakCommand(self,cmd): cmdFields = seperateCmd(cmd) if len(cmdFields) ==0: print "asd" assert (len(cmdFields) >0) if len(cmdFields) == 1 : return {'nemonic':cmdFields[0],'nemonicWithDecoretors':" ".join(cmdFields[0:-1]),'ParamsList':[]} else: return {'nemonic':cmdFields[0],'nemonicWithDecoretors':" ".join(cmdFields[0:-1]),'ParamsList':cmdFields[-1].split(",")} #TODO - add to this.. lvalCmdsStarts = ["mov","sub","add","xor"] def getNemonicType(self,nemonic): if any(map(lambda startString: nemonic.startswith(startString),self.lvalCmdsStarts)): return "WriteThenRead" else: return "Read" FuncPrefix = "f" VARPrefix = "s" RegisterPrefix = "r" OffsetPrefix = "o" OtherPrefix = "X" def getPrefix(self,Str): if isVarStr(Str): return self.VARPrefix elif isRegisterStr(Str): return self.RegisterPrefix elif isOffset(Str): return self.OffsetPrefix else: return self.OtherPrefix def varsEqual(self,v1, v2): return v1==v2 def checkInputVsTarget(self,target): def retFunc(inputVal): return inputVal == target return retFunc def getVarName(self,prefix,lineNumber,varsInThisLine): return prefix + str(lineNumber) + "-" + str(varsInThisLine) + "_TAR" def getMembers(self,param): refMembers = param.split("+") refMembers[0] = refMembers[0][1:] #remove [ from first refMembers[-1] = refMembers[-1][0:-1] # remove ] from last (they can be the same one!) return refMembers def getDomains(self): domains = {self.FuncPrefix:set(),self.VARPrefix:set(),self.RegisterPrefix:set(),self.OffsetPrefix:set()} def getCmdSymbols(cmd): cmdBasicInfo = self.breakCommand(cmd) for param in cmdBasicInfo['ParamsList']: if param.startswith("["): for member in self.getMembers(param): yield member else: yield param def getCmds(cmdsDelimited): return filter(None,cmdsDelimited.split(";")) for cmdList in itertools.imap(lambda nodeGradesInfo:getCmds(nodeGradesInfo['refCode']),self.nodeGradesInfos): for cmd in cmdList: if isCall(cmd): prefix = self.FuncPrefix domains[prefix].add(list(getCmdSymbols(cmd))[0]) else: for symbol in getCmdSymbols(cmd): prefix = self.getPrefix(symbol) if prefix != self.OtherPrefix: domains[prefix].add(symbol) for domainName in domains.keys(): domains[domainName] = list(domains[domainName]) return domains def callSol(self): domains = self.getDomains() #domains[refPrefix].add(refVal) self.problem = Problem(MinConflictsSolver()) tarSymbolsCache = {} self.varsInThisLine = 0 def addInTraceletCons(tarVal,newVarName): if (self.__printConds): print "CONS(IN) -> " + tarSymbolsCache[tarVal] + " == " + newVarName self.problem.addConstraint(self.varsEqual,[newVarName,tarSymbolsCache[tarVal]]) def addCrossTraceletCons(refVal,newVarName,refPrefix): if (self.__printConds): print "CONS(CROSS) -> " + newVarName + " == " + refVal self.problem.addConstraint(self.checkInputVsTarget(refVal),[newVarName]) def addVarWithPrefix(prefix,lineNumber): newVarName = self.getVarName(prefix,lineNumber,self.varsInThisLine) if len(domains[prefix]) == 0: print "EMP" self.problem.addVariables([newVarName],domains[prefix]) self.varsInThisLine+=1 return newVarName # mode can be - WRITE or NORMAL def doDF(refSymbol,tarSymbol,lineNumber,refPrefix,tarPrefix,nemonicType): if refPrefix == self.OtherPrefix or tarPrefix == self.OtherPrefix: return newVarName = addVarWithPrefix(tarPrefix,lineNumber) if (refPrefix == tarPrefix): addCrossTraceletCons(refSymbol,newVarName,refPrefix) if tarSymbol in tarSymbolsCache: addInTraceletCons(tarSymbol,newVarName) if tarPrefix != self.RegisterPrefix or nemonicType=="WriteThenRead": tarSymbolsCache[tarSymbol] = newVarName #for matchedCmd in itertools.chain(map(lambda nodeInfo:nodeInfo['matchedCmds'],self.nodeGradesInfos)): tarBase = 0 refBase = 0 for nodeInfo in self.nodeGradesInfos: for matchedCmd in nodeInfo['matchedCmds']: self.varsInThisLine = 1 # if these cmds are not an operational match, we cannot cross tracelet match them. if matchedCmd['operationMatch'] == True: currentLineNumber = tarBase + matchedCmd['tarCmdNum'] # matchedCmd['tarCmdNum'] is 1 based so we are ok if matchedCmd['tar'] =="" or matchedCmd['ref'] =="": continue tarCmdBasicInfo = self.breakCommand(matchedCmd['tar']) refCmdBasicInfo = self.breakCommand(matchedCmd['ref']) if len(tarCmdBasicInfo['ParamsList'])>0 and len(refCmdBasicInfo['ParamsList'])>0: if tarCmdBasicInfo['nemonic'] == 'call': assert(len(refCmdBasicInfo['ParamsList'])==1) assert(len(tarCmdBasicInfo['ParamsList'])==1) doDF(refCmdBasicInfo['ParamsList'][0], tarCmdBasicInfo['ParamsList'][0], currentLineNumber, self.FuncPrefix,self.FuncPrefix, "Read") else: nemonicType = self.getNemonicType(tarCmdBasicInfo['nemonic']) for (refParam,tarParam) in zip(refCmdBasicInfo['ParamsList'],tarCmdBasicInfo['ParamsList']): tarIsMem = "[" in tarParam if tarIsMem != ("[" in refParam): continue print matchedCmd print "BOY" assert tarIsMem == ("[" in refParam) if not tarIsMem: tarPreFix = self.getPrefix(tarParam) refPreFix = self.getPrefix(refParam) doDF(refParam, tarParam, currentLineNumber, tarPreFix,refPreFix, nemonicType) # TODO - return this to find more classes when we have time... """ if nemonicType == "WriteThenRead": if tarPreFix != self.RegisterPrefix: print matchedCmd assert (tarPreFix == self.RegisterPrefix) # the write is only to the left most param, rest are normal """ else: # this is memory! , first remove '[',']' for (refMember,tarMember) in zip(self.getMembers(refParam),self.getMembers(tarParam)): tarPreFix = self.getPrefix(tarMember) refPreFix = self.getPrefix(refMember) doDF(refMember, tarMember, currentLineNumber, tarPreFix,refPreFix, nemonicType) nemonicType = "Read" #TODO handle the False clause ? tarBase += nodeInfo['tarCode'].count(";") refBase += nodeInfo['refCode'].count(";") self.sol = self.problem.getSolution() #print self.sol def getBrokenNumber(self): return self.problem.getSolver().getHack() # TODO - make this __ def getRW(self): sol = self.getSolution() tarBase = 0 symbolsCache = {} self.varsInThisLine = 0 TotalLineNumber = 0 def getRewrittenSymbolUpdateCache(prefix,symbol): varName = self.getVarName(prefix, TotalLineNumber, self.varsInThisLine) if sol != None and varName in sol: symbolsCache[symbol] = sol[varName] return sol[varName] else: return symbol def rewrittenParam(param): if param.startswith("["): rewrittenMembers = [] for member in self.getMembers(param): rewrittenMembers.append(getRewrittenSymbolUpdateCache(self.getPrefix(member), member)) self.varsInThisLine+=1 return "[" + "+".join(rewrittenMembers) + "]" else: newParam = getRewrittenSymbolUpdateCache(self.getPrefix(param), param) self.varsInThisLine+=1 return newParam for nodeInfo in self.nodeGradesInfos: cmdsStr = nodeInfo['tarCode'] rewrittenCmds = [] lastLineNumber = 0 #filter(None,) for (lineNumber,cmd) in enumerate(cmdsStr.split(";")): TotalLineNumber = tarBase + lineNumber + 1 # we are one based lastLineNumber = lineNumber +1 # we are one based self.varsInThisLine = 1 if cmd != "": tarCmdBasicInfo = self.breakCommand(cmd) if len(tarCmdBasicInfo['ParamsList'])>0: if tarCmdBasicInfo['nemonic'] == 'call': rewrittenCmds.append("call " + getRewrittenSymbolUpdateCache(self.FuncPrefix,tarCmdBasicInfo['ParamsList'][0])) else: rewrittenCmds.append(tarCmdBasicInfo['nemonicWithDecoretors'] + " " + ",".join(map(rewrittenParam,tarCmdBasicInfo['ParamsList']))) else: rewrittenCmds.append(cmd) else: # this mostly cuz of bugs, but if i wont accumidate them it will cause a bad grade for nothing..(everything else wont be aligned) rewrittenCmds.append(cmd) tarBase += lastLineNumber-1 yield ";".join(rewrittenCmds) def getSolution(self): if self.sol == None: self.callSol() return self.sol def printSol(self,sol): #better call sol! if sol == None: print "NO SOL!" return last = 1 for key in sorted(sol.iterkeys()): if int(key[1:2]) != last: last = int(key[1:2]) print "" print key + ": " + sol[key] + " ",
def rank(tree): @extend(node.number) def _rank(self): problem.addVariable(id(self), [0]) @extend(node.let) def _rank(self): if isinstance(self.ret, node.ident): # plain assignment -- not a field, lhs indexing vars = [id(self.ret), id(self.args)] try: problem.addVariables(vars, range(4)) problem.addConstraint(operator.__eq__, vars) except ValueError: pass else: # lhs indexing or field pass @extend(node.for_stmt) def _rank(self): vars = [id(self.ident), id(self.expr)] problem.addVariables(vars, range(4)) problem.addConstraint((lambda u, v: u + 1 == v), vars) @extend(node.if_stmt) def _rank(self): # could use operator.__not__ instead of lambda expression problem.addVariable(id(self.cond_expr), range(4)) problem.addConstraint(lambda t: t == 0, [id(self.cond_expr)]) @extend(node.ident) def _rank(self): try: x = id(self) problem.addVariable(x, range(4)) for other in self.defs: y = id(other) try: problem.addVariable(y, range(4)) except ValueError: pass problem.addConstraint(operator.__eq__, [x, y]) except: print "Ignored ", self """ @extend(funcall) def rank(self,problem): if not isinstance(self.func_expr,ident): # In MATLAB, chaining subscripts, such as size(a)(1) # is not allowed, so only fields and dot expressions # go here. In Octave, chaining subscripts is allowed, # and such expressions go here. return try: if defs.degree(self.func_expr): # If a variable is defined, it is not a function, # except function handle usages, such as # foo=@size; foo(17) # which is not handled properly yet. x = id(self.func_expr) n = len(self.args) problem.addVariable(x,range(4)) problem.addConstraint((lambda u: u>=n),[x]) return except TypeError: # func_expr is unhashable # For example [10 20 30](2) return except KeyError: # See tests/clear_margins.m return assert getattr(self.func_expr,"name",None) # So func_expr is an undefined variable, and we understand # it's a function call -- either builtin or user-defined. name = self.func_expr.name # if name not in builtins: # # User-defined function # return # builtins[name](self,problem) # #@extend(expr) #def rank(self,problem): # try: # builtins[self.op](self,problem) # except: # pass """ problem = Problem(RecursiveBacktrackingSolver()) for v in node.postorder(tree): for u in v: try: u._rank() except AttributeError: pass s = problem.getSolution() if not s: print "No solutions" else: d = set() #for k in sorted(G.nodes(), key=lambda t: (t.name,t.lexpos)): for k in node.postorder(tree): if isinstance(k, node.ident): print k.name, k.lineno, s.get(id(k), -1)
return "\n".join([ " ".join(self.formatday(d, wd, width) for (d, wd) in theweek), " ".join(self.formathours(d, wd, width) for (d, wd) in theweek), ]) CALENDAR = MCalendar() days = [d for d in CALENDAR.itermonthdates(YEAR, MONTH) if d.month == MONTH] def all_assigned(assignments, variables): return [assignments.get(v, Unassigned) for v in variables].count(Unassigned) == 0 problem = Problem() problem.addVariables(days, list(range(0, 17))) for d in days: if d.day in special: problem.addConstraint(InSetConstraint([special[d.day]]), [d]) elif d.weekday() in regular: problem.addConstraint(InSetConstraint([regular[d.weekday()]]), [d]) problem.addConstraint(MaxSumConstraint(HOURS)) soln = problem.getSolution() CALENDAR.sched = {k.day: v for k, v in soln.items()} CALENDAR.prmonth(YEAR, MONTH)
while end - start < max_time: # The program would wait upto 5 minutes for solving a problem problem = Problem() cols = range(N) # Number of Columns rows = range(N) # Number of Rows problem.addVariables(cols, rows) for col1 in cols: for col2 in cols: if col1 < col2: problem.addConstraint( lambda row1, row2, col1=col1, col2=col2: abs(row1 - row2) != abs(col1 - col2) and row1 != row2, (col1, col2), ) problem.setSolver(MinConflictsSolver()) start = perf_counter() # Starting Counter solution = problem.getSolution( ) # Minimum Conflict Solver only returns one solution end = perf_counter() # Ending Counter times.append( (N, end - start)) # Stores Number of Queens and Time Taken to Solve the Puzzle N += 1 print('Total Time Taken to Solve The Puzzles using Iterative Approach:') print('N\t Time') for time in times: print(time[0], '\t', str(time[1]) + ' seconds')
def main(puzzle, lines): puzzle = puzzle.rstrip().splitlines() while puzzle and not puzzle[0]: del puzzle[0] # Extract horizontal words horizontal = [] word = [] predefined = {} for row in range(len(puzzle)): for col in range(len(puzzle[row])): char = puzzle[row][col] if not char.isspace(): word.append((row, col)) if char != "#": predefined[row, col] = char elif word: if len(word) > MINLEN: horizontal.append(word[:]) del word[:] if word: if len(word) > MINLEN: horizontal.append(word[:]) del word[:] # Extract vertical words vertical = [] validcol = True col = 0 while validcol: validcol = False for row in range(len(puzzle)): if col >= len(puzzle[row]): if word: if len(word) > MINLEN: vertical.append(word[:]) del word[:] else: validcol = True char = puzzle[row][col] if not char.isspace(): word.append((row, col)) if char != "#": predefined[row, col] = char elif word: if len(word) > MINLEN: vertical.append(word[:]) del word[:] if word: if len(word) > MINLEN: vertical.append(word[:]) del word[:] col += 1 # hnames = ["h%d" % i for i in range(len(horizontal))] # vnames = ["v%d" % i for i in range(len(vertical))] # problem = Problem(MinConflictsSolver()) problem = Problem() for hi, hword in enumerate(horizontal): for vi, vword in enumerate(vertical): for hchar in hword: if hchar in vword: hci = hword.index(hchar) vci = vword.index(hchar) problem.addConstraint(lambda hw, vw, hci=hci, vci=vci: hw[hci] == vw[vci], ("h%d" % hi, "v%d" % vi)) for char, letter in predefined.items(): for hi, hword in enumerate(horizontal): if char in hword: hci = hword.index(char) problem.addConstraint(lambda hw, hci=hci, letter=letter: hw[hci] == letter, ("h%d" % hi,)) for vi, vword in enumerate(vertical): if char in vword: vci = vword.index(char) problem.addConstraint(lambda vw, vci=vci, letter=letter: vw[vci] == letter, ("v%d" % vi,)) wordsbylen = {} for hword in horizontal: wordsbylen[len(hword)] = [] for vword in vertical: wordsbylen[len(vword)] = [] for line in lines: line = line.strip() l = len(line) if l in wordsbylen: wordsbylen[l].append(line.upper()) for hi, hword in enumerate(horizontal): words = wordsbylen[len(hword)] random.shuffle(words) problem.addVariable("h%d" % hi, words) for vi, vword in enumerate(vertical): words = wordsbylen[len(vword)] random.shuffle(words) problem.addVariable("v%d" % vi, words) problem.addConstraint(AllDifferentConstraint()) solution = problem.getSolution() if not solution: print("No solution found!") maxcol = 0 maxrow = 0 for hword in horizontal: for row, col in hword: if row > maxrow: maxrow = row if col > maxcol: maxcol = col for vword in vertical: for row, col in vword: if row > maxrow: maxrow = row if col > maxcol: maxcol = col matrix = [] for row in range(maxrow + 1): matrix.append([" "] * (maxcol + 1)) for variable in solution: if variable[0] == "v": word = vertical[int(variable[1:])] else: word = horizontal[int(variable[1:])] for (row, col), char in zip(word, solution[variable]): matrix[row][col] = char for row in range(maxrow + 1): for col in range(maxcol + 1): sys.stdout.write(matrix[row][col]) sys.stdout.write("\n")