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 __get_best_reduction_variable_value( constraint_problem: ConstraintProblem, constraints_weights: Dict[Constraint, int], read_only_variables: FrozenSet[Variable]) -> Tuple[int, Variable, Any]: pairs_to_weight_reduction = dict() weight = __calculate_weight(constraint_problem, constraints_weights) original_assignment = constraint_problem.get_current_assignment() constraint_problem.unassign_all_variables() for variable in constraint_problem.get_variables() - read_only_variables: for value in variable.domain: variable.assign(value) curr_weight = __calculate_weight(constraint_problem, constraints_weights) pairs_to_weight_reduction[(variable, value)] = weight - curr_weight variable.unassign() constraint_problem.unassign_all_variables() constraint_problem.assign_variables_from_assignment(original_assignment) max_variable, max_value = max(pairs_to_weight_reduction, key=pairs_to_weight_reduction.get) return pairs_to_weight_reduction[(max_variable, max_value)], max_variable, max_value
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
def generate_start_state_randomly( constraint_problem: ConstraintProblem) -> None: constraint_problem.unassign_all_variables() for var in constraint_problem.get_variables(): var.assign(choice(var.domain))