Example #1
0
def simulated_annealing(constraint_problem: ConstraintProblem, max_steps: int, temperature: float, cooling_rate: float,
                        generate_start_state: StartStateGenerator = generate_start_state_randomly,
                        generate_successor: SuccessorGenerator = alter_random_variable_value_pair,
                        calculate_score: ScoreCalculator = consistent_constraints_amount) -> ConstraintProblem:
    generate_start_state(constraint_problem)
    if constraint_problem.is_completely_consistently_assigned():
        return constraint_problem
    max_steps -= 1

    best_score = calculate_score(constraint_problem)
    best_score_problem = deepcopy(constraint_problem)
    for i in range(max_steps):
        if constraint_problem.is_completely_consistently_assigned():
            return constraint_problem

        curr_score = calculate_score(constraint_problem)
        if best_score < curr_score:
            best_score = curr_score
            best_score_problem = deepcopy(constraint_problem)

        successor = generate_successor(constraint_problem)
        successor_score = calculate_score(successor)
        delta = successor_score - curr_score
        if delta > 0 or uniform(0, 1) < exp(delta / temperature):
            constraint_problem = successor
        temperature *= cooling_rate

    return best_score_problem
def random_restart_first_choice_hill_climbing(
    constraint_problem: ConstraintProblem,
    max_restarts: int,
    max_steps: int,
    max_successors: int,
    generate_start_state: StartStateGenerator = generate_start_state_randomly,
    generate_successor: SuccessorGenerator = alter_random_variable_value_pair,
    calculate_score: ScoreCalculator = consistent_constraints_amount
) -> ConstraintProblem:
    generate_start_state(constraint_problem)
    if constraint_problem.is_completely_consistently_assigned():
        return constraint_problem
    max_restarts -= 1

    best_score = calculate_score(constraint_problem)
    best_score_problem = deepcopy(constraint_problem)
    for i in range(max_restarts):
        generate_start_state(constraint_problem)
        for j in range(max_steps):
            if constraint_problem.is_completely_consistently_assigned():
                return constraint_problem

            current_score = calculate_score(constraint_problem)
            if best_score < current_score:
                best_score = current_score
                best_score_problem = deepcopy(constraint_problem)

            for k in range(max_successors):
                successor = generate_successor(constraint_problem)
                successor_score = calculate_score(successor)
                if current_score < successor_score:
                    constraint_problem = successor
                    break

    return best_score_problem
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
Example #4
0
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