Example #1
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
Example #2
0
def __reduce_assignment_constraints_domains(constraint_problem: ConstraintProblem,
                                            i_subsets_consistent_assignments:
                                            Dict[Tuple[Tuple[Variable, ...], Variable], set]) -> None:
    constraints = constraint_problem.get_constraints()
    for subset, ith_variable in i_subsets_consistent_assignments:
        i_variables = frozenset(subset + (ith_variable,))
        found = False
        for constraint in constraints:
            if i_variables.issubset(constraint.variables):
                found = True
                constraint.update_i_consistent_assignments(i_subsets_consistent_assignments[(subset, ith_variable)])
        if not found:
            i_constraint = OnlyiConsistentAssignment((i_subsets_consistent_assignments[(subset, ith_variable)]))
            new_constraint = Constraint(i_variables, i_constraint)
            constraint_problem.add_constraint(new_constraint)
Example #3
0
def ac4(constraint_problem: ConstraintProblem) -> bool:
    support_counter = collections.Counter()
    variable_value_pairs_supported_by = collections.defaultdict(set)
    unsupported_variable_value_pairs = collections.deque()
    __initialize_ac4(constraint_problem.get_constraints(), support_counter, variable_value_pairs_supported_by,
                     unsupported_variable_value_pairs)

    while unsupported_variable_value_pairs:
        second_variable, second_value = unsupported_variable_value_pairs.popleft()
        for first_variable, first_value in variable_value_pairs_supported_by[(second_variable, second_value)]:
            if first_value in first_variable.domain:
                support_counter[(first_variable, first_value, second_variable)] -= 1
                if support_counter[(first_variable, first_value, second_variable)] == 0:
                    first_variable.remove_from_domain(first_value)
                    unsupported_variable_value_pairs.append((first_variable, first_value))

    for var in constraint_problem.get_variables():
        if not var.domain or not constraint_problem.get_consistent_domain(var):
            return False
    return True
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