def test_computation_memory_two_constraints():
    v1 = Variable("v1", list(range(10)))
    v2 = Variable("v2", list(range(10)))
    v3 = Variable("v3", list(range(10)))
    v4 = Variable("v4", list(range(10)))
    c1 = constraint_from_str("c1", " v1 == v2", [v1, v2])
    c2 = constraint_from_str("c2", " v1 == v3", [v1, v3])
    c3 = constraint_from_str("c3", " v1 == v4", [v1, v4])
    v1_node = VariableComputationNode(v1, [c1, c2, c3])

    # here, we have 3 edges , one for each constraint
    assert mgm2.computation_memory(v1_node) == mgm2.UNIT_SIZE * 3 * 2
def three_variables_pb():
    # a very simple problem with 3 variables
    x1 = Variable("x1", ["R", "B"])
    x2 = Variable("x2", ["R", "B"])
    x3 = Variable("x3", ["R", "B"])
    diff_x1_x2 = constraint_from_str("c1", "1 if x1 == x2 else 0", [x1, x2])
    diff_x1_x3 = constraint_from_str("c2", "1 if x1 == x3 else 0", [x1, x3])
    # build the pseudo-tree for this problem
    g = build_computation_graph(None,
                                constraints=[diff_x1_x2, diff_x1_x3],
                                variables=[x1, x2, x3])
    return g
def test_communication_load():
    v1 = Variable('v1', list(range(10)))
    v2 = Variable('v2', list(range(10)))
    v3 = Variable('v3', list(range(10)))
    v4 = Variable('v4', list(range(10)))
    c1 = constraint_from_str('c1', ' v1 == v2', [v1, v2])
    c2 = constraint_from_str('c2', ' v1 == v3', [v1, v3])
    c3 = constraint_from_str('c3', ' v1 == v4', [v1, v4])
    v1_node = VariableComputationNode(v1, [c1, c2, c3])

    assert mgm2.UNIT_SIZE * 10 * 10 * 3 + mgm2.HEADER_SIZE \
           == mgm2.communication_load(v1_node, 'v2')
예제 #4
0
def test_computation_memory_two_constraints():
    v1 = Variable('v1', list(range(10)))
    v2 = Variable('v2', list(range(10)))
    v3 = Variable('v3', list(range(10)))
    v4 = Variable('v4', list(range(10)))
    c1 = constraint_from_str('c1', ' v1 == v2', [v1, v2])
    c2 = constraint_from_str('c2', ' v1 == v3', [v1, v3])
    c3 = constraint_from_str('c3', ' v1 == v4', [v1, v4])
    v1_node = VariableComputationNode(v1, [c1, c2, c3])

    # here, we have 3 edges , one for each constraint
    assert dsa.computation_memory(v1_node) == dsa.UNIT_SIZE * 3
def test_communication_load():
    v1 = Variable("v1", list(range(10)))
    v2 = Variable("v2", list(range(10)))
    v3 = Variable("v3", list(range(10)))
    v4 = Variable("v4", list(range(10)))
    c1 = constraint_from_str("c1", " v1 == v2", [v1, v2])
    c2 = constraint_from_str("c2", " v1 == v3", [v1, v3])
    c3 = constraint_from_str("c3", " v1 == v4", [v1, v4])
    v1_node = VariableComputationNode(v1, [c1, c2, c3])

    assert mgm2.UNIT_SIZE * 10 * 10 * 3 + mgm2.HEADER_SIZE == mgm2.communication_load(
        v1_node, "v2")
def test_comp_creation_with_factory_method():
    d = Domain("d", "", ["R", "G"])
    v1 = Variable("v1", d)
    v2 = Variable("v2", d)
    c1 = constraint_from_str("c1", "10 if v1 == v2 else 0", [v1, v2])
    graph = build_computation_graph(None, constraints=[c1], variables=[v1, v2])

    comp_node = graph.computation("c1")
    algo_def = AlgorithmDef.build_with_default_param("maxsum")
    comp_def = ComputationDef(comp_node, algo_def)

    comp = build_computation(comp_def)
    assert comp is not None
    assert comp.name == "c1"
    assert comp.factor == c1

    comp_node = graph.computation("v1")
    algo_def = AlgorithmDef.build_with_default_param("maxsum")
    comp_def = ComputationDef(comp_node, algo_def)

    comp = build_computation(comp_def)
    assert comp is not None
    assert comp.name == "v1"
    assert comp.variable.name == "v1"
    assert comp.factors == ["c1"]
예제 #7
0
def build_models(light_domain, lights, max_model_size, model_count):
    # Models: for each model
    #  * one constraint depends on 2 =< k =<max_model_size lights
    #  * one variable ,
    # Example:
    #   function: 0 if 0.7 * l_d1 + 0.5 * l_d2 + 0.3 * l_lv3 == mv_desk else
    #             1000
    # function: '0 if 10 * abs(m0 - ( 0.2 * l1 + 0.5 * l2 + 0.8 * l3 )) < 3 else 1000'

    models = {}
    models_var = {}
    for j in range(model_count):
        model_var = Variable("m{}".format(j), domain=light_domain)
        models_var[model_var.name] = model_var

        model_size = randint(2, max_model_size)
        model_lights = ()
        light_expression_parts = []
        for k, model_light in enumerate(sample(list(lights), model_size)):
            impact = randint(1, 7) / 10
            light_expression_parts.append(" {} * {}".format(model_light, impact))
            # model_lights.append((model_light, impact))
            # model_light.
        light_expression = " + ".join(light_expression_parts)
        model_expression = f"0 if 10* abs({model_var.name} - ({light_expression})) < 5 else 10000 ".format(
            light_expression, model_var.name
        )
        model = constraint_from_str(
            "c_m{}".format(j),
            expression=model_expression,
            all_variables=list(lights.values()) + [model_var],
        )
        models[model.name] = model

    return models_var, models
    def test_create_ok(self):
        d1 = Domain('d1', '', [1, 2, 3, 5])
        v1 = Variable('v1', d1)
        f1 = constraint_from_str('f1', 'v1 * 0.5', [v1])

        cv1 = VariableComputationNode(v1, [f1])
        cf1 = FactorComputationNode(f1)
        cg = ComputationsFactorGraph([cv1], [cf1])
예제 #9
0
def test_build_graph_from_variables_constraints():
    d = Domain('d', 'test', [1, 2, 3])
    v1 = Variable('v1', d)
    v2 = Variable('v2', d)
    v3 = Variable('v3', d)
    c1 = constraint_from_str('c1', 'v1 * 0.5 + v2 - v3', [v1, v2, v3])

    graph = build_computation_graph(variables=[v1, v2, v3], constraints=[c1])
예제 #10
0
def generate_unary_intentional_constraint(variable: Variable, un_range: float):
    value = random.uniform(-un_range, un_range)
    constraint = constraint_from_str(
        name=f"cu_{variable.name}",
        expression=f" -{value} if {variable.name} == 1 else {value}",
        all_variables=[variable],
    )
    return constraint
예제 #11
0
def build_pb():
    # A toy problem with 5 variables and 5 constraints.
    # The objective here is to have a problem that is simple enough to be solved
    # manually and used in test, but that is representative enough to be meaningful.

    v_a = Variable("vA", ["R", "G"])
    v_b = Variable("vB", ["R", "G"])
    v_c = Variable("vC", ["R", "G"])
    v_d = Variable("vD", ["R", "G"])
    c1 = constraint_from_str(
        "c1",
        "{('R', 'G'): 8, "
        " ('R', 'R'): 5, "
        " ('G', 'G'): 3, "
        " ('G', 'R'): 20 "
        "}[(vA, vB)]",
        [v_a, v_b],
    )
    c2 = constraint_from_str(
        "c2",
        "{('R', 'G'): 10, "
        " ('R', 'R'): 5, "
        " ('G', 'G'): 3, "
        " ('G', 'R'): 20 "
        "}[(vA, vC)]",
        [v_a, v_c],
    )
    c3 = constraint_from_str(
        "c3",
        "{('R', 'G'): 4, "
        " ('R', 'R'): 5, "
        " ('G', 'G'): 3, "
        " ('G', 'R'): 3 "
        "}[(vB, vC)]",
        [v_b, v_c],
    )
    c4 = constraint_from_str(
        "c4",
        "{('R', 'G'): 8, "
        " ('R', 'R'): 3, "
        " ('G', 'G'): 3, "
        " ('G', 'R'): 10 "
        "}[(vB, vD)]",
        [v_b, v_d],
    )
    return [v_a, v_b, v_c, v_d], [c1, c2, c3, c4]
예제 #12
0
def test_computation_memory_one_constraint():
    v1 = Variable("v1", list(range(10)))
    v2 = Variable("v2", list(range(10)))
    v3 = Variable("v3", list(range(10)))
    c1 = constraint_from_str("c1", " v1 + v2 == v3", [v1, v2, v3])
    v1_node = VariableComputationNode(v1, [c1])

    # here, we have an hyper-edges with 3 vertices
    assert mgm2.computation_memory(v1_node) == mgm2.UNIT_SIZE * 2 * 2
예제 #13
0
def test_create_node_with_custom_name():
    d = Domain('d', 'test', [1, 2, 3])
    v1 = Variable('v1', d)
    c1 = constraint_from_str('c1', 'v1 * 0.5', [v1])

    n1 = VariableComputationNode(v1, [c1], name='foo')

    assert v1 == n1.variable
    assert n1.name == 'foo'
예제 #14
0
def test_computation_memory_one_constraint():
    v1 = Variable('v1', list(range(10)))
    v2 = Variable('v2', list(range(10)))
    v3 = Variable('v3', list(range(10)))
    c1 = constraint_from_str('c1', ' v1 + v2 == v3', [v1, v2, v3])
    v1_node = VariableComputationNode(v1, [c1])

    # here, we have an hyper-edges with 3 vertices
    assert dsa.computation_memory(v1_node) == dsa.UNIT_SIZE * 2
    def test_raise_when_duplicate_computation_name(self):
        d1 = Domain('d1', '', [1, 2, 3, 5])
        v1 = Variable('v1', d1)
        # here we create a relation with the same name as the variable
        f1 = constraint_from_str('v1', 'v1 * 0.5', [v1])

        cv1 = VariableComputationNode(v1, ['f1'])
        cf1 = FactorComputationNode(f1)
        self.assertRaises(KeyError, ComputationsFactorGraph, [cv1], [cf1])
def test_compute_factor_cost_at_start():
    d = Domain("d", "", ["R", "G"])
    v1 = Variable("v1", d)
    v2 = Variable("v2", d)
    c1 = constraint_from_str("c1", "10 if v1 == v2 else 0", [v1, v2])

    obtained = factor_costs_for_var(c1, v1, {}, "min")
    assert obtained["R"] == 0
    assert obtained["G"] == 0
    assert len(obtained) == 2
예제 #17
0
def test_create_node_no_neigbors():
    d = Domain('d', 'test', [1, 2, 3])
    v1 = Variable('v1', d)
    c1 = constraint_from_str('c1', 'v1 * 0.5', [v1])

    n1 = VariableComputationNode(v1, [c1])

    assert v1 == n1.variable
    assert c1 in n1.constraints
    assert len(n1.links) == 1  # link to our-self
    assert not n1.neighbors
예제 #18
0
def test_var_node_simple_repr():
    d = Domain('d', 'test', [1, 2, 3])
    v1 = Variable('v1', d)
    c1 = constraint_from_str('c1', 'v1 * 0.5', [v1])

    cv1 = VariableComputationNode(v1, [c1])

    r = simple_repr(cv1)
    cv1_obtained = from_repr(r)

    assert cv1 == cv1_obtained
예제 #19
0
def test_create_node_with_binary_constraint():
    d = Domain('d', 'test', [1, 2, 3])
    v1 = Variable('v1', d)
    v2 = Variable('v2', d)
    c1 = constraint_from_str('c1', 'v1 * 0.5 - v2', [v1, v2])

    n1 = VariableComputationNode(v1, [c1])

    assert v1 == n1.variable
    assert c1 in n1.constraints
    assert list(n1.links)[0].has_node('v2')
    assert 'v2' in n1.neighbors
예제 #20
0
def generate_binary_intentional_constraint(
    variable1: Variable, variable2: Variable, bin_range: float
) -> Constraint:
    value = random.uniform(-bin_range, bin_range)

    constraint = constraint_from_str(
        name=f"cb_{variable1.name}_{variable2.name}",
        expression=f"{value} if {variable1.name} == {variable2.name} else -{value}",
        all_variables=[variable1, variable2],
    )

    return constraint
예제 #21
0
    def __add__(self,
                info: Tuple[str, str, List[Variable]]):
        """Convenience notation for adding a constraint to te dcop.

        Parameters
        ----------
        info: a tuple name, expr_str, variables
            name is the name of the constraint, as a string
            expr_str is a python expression as a string, that return the
            value of the constraint. names used in this expression must be
            names of variables given in te third element of the tuple.
            variable can be an iterable of variable object or a dictionary of
            {name: variables}

        Returns
        -------
        DCOP
            the dcop itself, in order to be able to use the += notation.

        Raises
        ------
        ValueError
            If a domain or variable with the same name, but not the same
            definition, already exist for this dcop.

        Notes
        -----
        Variable(s) and domain(s) involved in the constraint are automatically
        added to the dcop.

        See Also
        --------
        add_constraint

        Examples
        --------
        >>> dcop = DCOP('test')
        >>> v1 = Variable('v1', range(10) )
        >>> dcop += 'c1', '2 if v1 > 5 else 10 ', [v1]
        >>> dcop.constraints['c1'](8)
        2
        >>> dcop.constraints['c1'](1)
        10

        """
        (name, expr_str, variables) = info
        if hasattr(variables, 'values'):
            variables = variables.values()

        c = constraint_from_str(name, expr_str, variables)
        self.add_constraint(c)
        return self
def test_variablenode_simple_repr():
    d1 = Domain('d1', '', [1, 2, 3, 5])
    v1 = Variable('v1', d1)
    f1 = constraint_from_str('f1', 'v1 * 0.5', [v1])

    cv1 = VariableComputationNode(v1, ['f1'])
    cf1 = FactorComputationNode(f1, )

    r = simple_repr(cv1)
    obtained = from_repr(r)

    assert obtained == cv1
    assert cv1.variable == obtained.variable
예제 #23
0
def test_dcop_add_constraint_is_enough():
    dcop = DCOP()

    d = VariableDomain('test', 'test', values=range(10))
    v1 = Variable('v1', d)
    v2 = Variable('v2', d)
    c1 = constraint_from_str('c1', '0 if v1 != v2 else 1000', [v1, v2])

    dcop.add_constraint(c1)

    assert dcop.constraints == {'c1': c1}
    assert dcop.variables == {'v1': v1, 'v2': v2}
    assert dcop.domains == {'test': d}
예제 #24
0
def test_graph_density():
    d = Domain('d', 'test', [1, 2, 3])
    v1 = Variable('v1', d)
    v2 = Variable('v2', d)
    v3 = Variable('v3', d)
    c1 = constraint_from_str('c1', 'v1 * 0.5 + v2 - v3', [v1, v2, v3])

    dcop = DCOP('dcop_test', 'min')
    dcop.add_constraint(c1)

    graph = build_computation_graph(dcop)

    density = graph.density()
    assert density == 1 / 3
    def setUp(self):

        variables = list(
            create_variables('v', ['1', '2', '3'], Domain('d', '',
                                                          [1, 2])).values())
        all_diff = constraint_from_str('all_diff', 'v1 + v2 + v3 ', variables)
        v1, v2, v3 = variables
        c1 = VariableComputationNode(v1, [all_diff])
        c2 = VariableComputationNode(v2, [all_diff])
        c3 = VariableComputationNode(v3, [all_diff])
        nodes = [c1, c2, c3]
        # links = [ConstraintLink('all_diff', ['c1', 'c2', 'c3'])]

        self.cg = ComputationConstraintsHyperGraph(nodes)
        self.agents = [AgentDef('a1'), AgentDef('a2'), AgentDef('a3')]
예제 #26
0
def build_lights(light_count, light_domain):
    # Lights : cost function & variable
    lights = {}
    lights_cost = {}
    for i in range(light_count):
        light = Variable("l{}".format(i), domain=light_domain)
        lights[light.name] = light
        efficiency = randint(0, 90) / 100
        cost = constraint_from_str(
            "c_l{}".format(i),
            expression="{} * {}".format(light.name, efficiency),
            all_variables=[light],
        )
        lights_cost[cost.name] = cost

    return lights, lights_cost
def test_no_neighbors():
    x1 = Variable("x1", list(range(10)))
    cost_x1 = constraint_from_str('cost_x1', 'x1 *2 ', [x1])

    computation = Mgm2Computation(x1, [cost_x1],
                                  mode='max',
                                  comp_def=MagicMock())

    computation.value_selection = MagicMock()
    computation.finished = MagicMock()
    vals, cost = computation._compute_best_value()
    assert cost == 18
    assert set(vals) == {9}

    computation.on_start()
    computation.value_selection.assert_called_once_with(9, 18)
    computation.finished.assert_called_once_with()
예제 #28
0
def test_link_simple_repr():
    d = Domain('d', 'test', [1, 2, 3])
    v1 = Variable('v1', d)
    v2 = Variable('v2', d)
    v3 = Variable('v3', d)
    c1 = constraint_from_str('c1', 'v1 * 0.5 + v2 - v3', [v1, v2, v3])

    cv1 = VariableComputationNode(v1, [c1])
    cv2 = VariableComputationNode(v2, [c1])
    cv3 = VariableComputationNode(v3, [c1])

    link = ConstraintLink(c1.name, ['c1', 'c2', 'c3'])

    r = simple_repr(link)
    link_obtained = from_repr(r)

    assert link == link_obtained
예제 #29
0
def test_problem_with_non_binary_constraints_raises_exception():
    d = Domain("values", "", [1, 0])
    v1 = Variable("v1", d)
    v2 = Variable("v2", d)
    v3 = Variable("v3", d)
    c1 = constraint_from_str("c1", "v1 + v2 + v3 <= 2", [v1, v2, v3])
    g = build_computation_graph(None, constraints=[c1], variables=[v1, v2, v3])
    with pytest.raises(ComputationException) as comp_exc:
        get_computation_instance(g, "v1")
    assert f" with arity {3}" in str(comp_exc.value)

    with pytest.raises(ComputationException) as comp_exc:
        get_computation_instance(g, "v3")
    assert f" with arity {3}" in str(comp_exc.value)

    with pytest.raises(ComputationException) as comp_exc:
        get_computation_instance(g, "v2")
    assert f" with arity {3}" in str(comp_exc.value)
예제 #30
0
def test_no_neighbors():
    x1 = Variable("x1", list(range(10)))
    cost_x1 = constraint_from_str("cost_x1", "x1 *2 ", [x1])

    computation = Mgm2Computation(
        ComputationDef(
            VariableComputationNode(x1, [cost_x1]),
            AlgorithmDef.build_with_default_param("mgm2", mode="max"),
        ))

    computation.value_selection = MagicMock()
    computation.finished = MagicMock()
    vals, cost = computation._compute_best_value()
    assert cost == 18
    assert set(vals) == {9}

    computation.on_start()
    computation.value_selection.assert_called_once_with(9, 18)
    computation.finished.assert_called_once_with()