def min_conflicts( constraint_problem: ConstraintProblem, max_steps: int, tabu_size: int = -1, with_history: bool = False) -> Optional[Deque[Tuple[Variable, Any]]]: __tabu_queue.clear() read_only_variables = constraint_problem.get_assigned_variables() if tabu_size == -1: tabu_size = 0 assert tabu_size + len(read_only_variables) < len(constraint_problem.get_variables()), \ "tabu_size + len(read_only_variables) is equal or bigger than constraint_problem's variables amount." if tabu_size == 0: tabu_size = -1 actions_history = None if with_history: actions_history = deque() rand_assignmt_history = constraint_problem.assign_variables_with_random_values( read_only_variables, actions_history) if with_history: actions_history.extend(rand_assignmt_history) best_min_conflicts = len(constraint_problem.get_unsatisfied_constraints()) best_min_conflicts_assignment = constraint_problem.get_current_assignment() for i in range(max_steps): if constraint_problem.is_completely_consistently_assigned(): return actions_history conflicted_variable = __get_random_conflicted_variable( constraint_problem, read_only_variables, tabu_size) conflicted_variable.unassign() if with_history: actions_history.append((conflicted_variable, None)) min_conflicts_value = __get_min_conflicts_value( constraint_problem, conflicted_variable) conflicted_variable.assign(min_conflicts_value) if with_history: actions_history.append((conflicted_variable, min_conflicts_value)) if len(__tabu_queue) == tabu_size: __tabu_queue.popleft() if __tabu_queue: __tabu_queue.append(conflicted_variable) curr_conflicts_count = len( constraint_problem.get_unsatisfied_constraints()) if curr_conflicts_count < best_min_conflicts: best_min_conflicts = curr_conflicts_count best_min_conflicts_assignment = constraint_problem.get_current_assignment( ) constraint_problem.unassign_all_variables() constraint_problem.assign_variables_from_assignment( best_min_conflicts_assignment) return actions_history
def naive_cycle_cutset(constraint_problem: ConstraintProblem, with_history: bool = False) \ -> Optional[Deque[Tuple[Variable, Any]]]: actions_history = None if with_history: actions_history = deque() variables = constraint_problem.get_variables() read_only_variables = constraint_problem.get_assigned_variables() constraints = list(constraint_problem.get_constraints()) constraints.sort(key=lambda constraint: len(constraint.variables), reverse=True) constraint_graph = constraint_problem.get_constraint_graph_as_adjacency_list() for i in range(1, len(constraints)): cutset_constraints = constraints[:i] cutset_variables = set() for cutset_const in cutset_constraints: cutset_variables.update(cutset_const.variables) reduced_graph = {var: neighbors for var, neighbors in constraint_graph.items() if var not in cutset_variables} for var in reduced_graph: reduced_graph[var] -= cutset_variables if __is_tree(reduced_graph): consistent_assignments_list = __get_consistent_assignments(cutset_variables, cutset_constraints, read_only_variables) non_cutset_variables = variables - cutset_variables non_cutset_vars_to_original_domains_map = {var: var.domain for var in non_cutset_variables} for consist_assignment in consistent_assignments_list: for var, value in zip(cutset_variables, consist_assignment): if var not in read_only_variables: var.assign(value) if with_history: actions_history.append((var, value)) for non_cutset_var in non_cutset_variables: if non_cutset_var not in read_only_variables: non_cutset_var.domain = list(constraint_problem.get_consistent_domain(non_cutset_var)) tree_csp_action_history = tree_csp_solver(constraint_problem, with_history) if with_history: actions_history.extend(tree_csp_action_history) if constraint_problem.is_completely_consistently_assigned(): return actions_history for var in variables: if var not in read_only_variables: var.unassign() if with_history: actions_history.append((var, None)) for var in non_cutset_vars_to_original_domains_map: if var not in read_only_variables: var.domain = non_cutset_vars_to_original_domains_map[var] return actions_history
def constraints_weighting(constraint_problem: ConstraintProblem, max_tries: int, with_history: bool = False) \ -> Optional[Deque[Tuple[Variable, Any]]]: actions_history = None if with_history: actions_history = deque() constraints_weights = { constraint: 1 for constraint in constraint_problem.get_constraints() } read_only_variables = constraint_problem.get_assigned_variables() for i in range(max_tries): constraint_problem.assign_variables_with_random_values( read_only_variables) last_reduction = float("inf") while 0 < last_reduction: if constraint_problem.is_completely_consistently_assigned(): return actions_history reduction, variable, value = __get_best_reduction_variable_value( constraint_problem, constraints_weights, read_only_variables) variable.unassign() if with_history: actions_history.append((variable, None)) variable.assign(value) if with_history: actions_history.append((variable, value)) last_reduction = reduction for unsatisfied_constraint in constraint_problem.get_unsatisfied_constraints( ): constraints_weights[unsatisfied_constraint] += 1 if i != max_tries - 1: constraint_problem.unassign_all_variables(read_only_variables) return actions_history