Ejemplo n.º 1
0
def test_dcop_add_agents_from_list():
    dcop = DCOP()
    a1 = AgentDef('a1')
    a2 = AgentDef('a2')
    dcop.add_agents([a1, a2])
    assert dcop.agent('a1').name == 'a1'
    assert dcop.agent('a2').name == 'a2'
Ejemplo n.º 2
0
def generate_ising(args):
    domain_size = args.range
    size = args.size
    d = VariableDomain('d', 'dummy', range(domain_size))
    variables = {}
    constraints = {}
    for i in range(size):
        for j in range(size):
            v = Variable('v{}_{}'.format(i, j), d,
                         floor(domain_size * random.random()))
            variables[(i, j)] = v

    for i, j in variables:
        c = _create_ising_constraint(i, j, i, (j + 1) % size, domain_size,
                                     variables)
        constraints[(i, j, i, (j + 1) % size)] = c

        c = _create_ising_constraint(i, j, (i + 1) % size, j, domain_size,
                                     variables)
        constraints[(i, j, (i + 1) % size), j] = c

    dcop = DCOP('radom ising', 'min')
    #dcop.domains = {'d': d}
    #dcop.variables = variables
    dcop._agents_def = {}
    for c in constraints.values():
        dcop.add_constraint(c)

    if args.output:
        outputfile = args.output[0]
        write_in_file(outputfile, dcop_yaml(dcop))
    else:
        print(dcop_yaml(dcop))
    def test_build_single_var(self):

        v1 = Variable('v1', [1, 2, 3])
        dcop = DCOP('test', 'min')
        dcop.variables = {'v1': v1}

        cg = build_computation_graph(dcop)

        self.assertEqual(len(cg.nodes), 1)
        self.assertEqual(cg.computation('v1').variable, v1)
        self.assertEqual(len(cg.links), 0)
    def test_density_two_var_one_factor(self):
        dcop = DCOP('test', 'min')
        d1 = VariableDomain('d1', '--', [1, 2, 3])
        v1 = Variable('v1', d1)
        v2 = Variable('v2', d1)
        c1 = relation_from_str('c1', '0.5 * v1 + v2', [v1, v2])

        dcop.add_constraint(c1)

        g = build_computation_graph(dcop)

        self.assertEqual(g.density(), 2 / 2)
Ejemplo n.º 5
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}
Ejemplo n.º 6
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
Ejemplo n.º 7
0
def test_filter_dcop():
    dcop = DCOP()

    d = VariableDomain('test', 'test', values=range(10))

    v1 = Variable('v1', d)
    v2 = Variable('v2', d)
    v3 = Variable('v3', d)

    dcop += 'c1', '0 if v1 != v2 else 1000', [v1, v2]
    dcop.add_variable(v3)
    assert dcop.variables == {'v1': v1, 'v2': v2, "v3": v3}

    filtered = filter_dcop(dcop)

    assert filtered.variables == {'v1': v1, 'v2': v2}
Ejemplo n.º 8
0
def test_api_dcop_graph_coloring():

    # Graph coloring with 3 variables and color preferences

    dcop = DCOP('test')

    # Domain and variables
    d = Domain('color', '', ['R', 'G'])
    variables = create_variables('v', [1, 2, 3], d)

    # Creating constraints using the convenience += notation
    # We could also use the more verbose dcop.add_constraint method.
    # Variable(s) and domain(s) involved in the constraint are automatically
    # added to the dcop.
    # unary constraints for preferences
    dcop += 'cost_1', '-0.1 if v1 == "R" else 0.1 ', variables
    dcop += 'cost_2', '-0.1 if v2 == "G" else 0.1 ', variables
    dcop += 'cost_3', '-0.1 if v3 == "G" else 0.1 ', variables
    # coloring constraints : v1 != v2 != v3
    dcop += 'c1', '1 if v1 == v2 else 0', variables
    dcop += 'c2', '1 if v3 == v2 else 0', variables

    # let's check the dcop really has all required domain, variables and
    # constraints
    assert len(dcop.variables) == 3
    assert 'v1' in dcop.variables

    assert len(dcop.domains) == 1
    assert 'color' in dcop.domains

    assert len(dcop.constraints) == 5
    assert 'cost_3' in dcop.constraints
    assert 'c2' in dcop.constraints
Ejemplo n.º 9
0
def test_solve_max(toy_pb):

    variables, constraints = toy_pb

    dcop = DCOP(name="toy",
                variables={v.name: v
                           for v in variables},
                constraints={c.name: c
                             for c in constraints},
                objective="max")
    dcop.add_agents(create_agents("a", [1, 2, 3, 4]))

    assignment = solve(dcop, "syncbb", "oneagent")

    # Note: this is supposed to be exactly the same pb as bellow
    assert assignment == {"vA": "G", "vB": "R", "vC": "R", "vD": "G"}
    def test_build_two_var(self):

        v1 = Variable('v1', [1, 2, 3])
        v2 = Variable('v2', [1, 2, 3])
        c1 = relation_from_str('c1', 'v1 + v2 ', [v1, v2])
        dcop = DCOP('test', 'min')
        dcop.add_constraint(c1)

        cg = build_computation_graph(dcop)

        self.assertEqual(len(cg.nodes), 2)
        self.assertEqual(cg.computation('v1').variable, v1)
        self.assertEqual(cg.computation('v2').variable, v2)

        # one parent link, one children link
        self.assertEqual(len(cg.links), 2)
Ejemplo n.º 11
0
def generate_ising(
    row_count: int,
    col_count: int,
    bin_range: float,
    un_range: float,
    extensive: bool,
    no_agents: bool,
    fg_dist: bool,
    var_dist: bool,
) -> Tuple[DCOP, Dict, Dict]:

    grid_graph = nx.grid_2d_graph(row_count, col_count, periodic=True)
    domain = Domain("var_domain", "binary", [0, 1])

    variables = generate_binary_variables(grid_graph, domain)

    constraints = {}
    unary_constraints = generate_unary_constraints(variables, un_range, extensive)
    constraints.update(unary_constraints)
    binary_constraints = generate_binary_constraints(
        grid_graph, variables, bin_range, extensive
    )
    constraints.update(binary_constraints)

    agents = {}
    fg_mapping = defaultdict(lambda: [])
    var_mapping = defaultdict(lambda: [])
    for (row, col) in grid_graph.nodes:
        agent = AgentDef(f"a_{row}_{col}")
        agents[agent.name] = agent
        left = (row - 1) % row_count
        down = (col + 1) % col_count

        if var_dist:
            var_mapping[agent.name].append(f"v_{row}_{col}")

        if fg_dist:
            fg_mapping[agent.name].append(f"v_{row}_{col}")
            fg_mapping[agent.name].append(f"cu_v_{row}_{col}")
            # Sort coordinate to make sure we build the name in the same order as when
            # creating the constraints:
            (r1, c1), (r2, c2) = sorted([(row, col), (left, col)])
            fg_mapping[agent.name].append(f"cb_v_{r1}_{c1}_v_{r2}_{c2}")
            (r1, c1), (r2, c2) = sorted([(row, col), (row, down)])
            fg_mapping[agent.name].append(f"cb_v_{r1}_{c1}_v_{r2}_{c2}")

    name = f"Ising_{row_count}_{col_count}_{bin_range}_{un_range}"
    if no_agents:
        agents = {}
    dcop = DCOP(
        name,
        domains={"var_domain": domain},
        variables={v.name: v for v in variables.values()},
        agents=agents,
        constraints=constraints,
    )

    return dcop, dict(var_mapping), dict(fg_mapping)
Ejemplo n.º 12
0
def test_solve_min(toy_pb):

    variables, constraints = toy_pb

    dcop = DCOP(name="toy",
                variables={v.name: v
                           for v in variables},
                constraints={c.name: c
                             for c in constraints},
                objective="min")
    dcop.add_agents(create_agents("a", [1, 2, 3, 4]))

    assignment = solve(dcop, "syncbb", "oneagent")

    # Note: this is exactly the same pb as in the file bellow
    # dcop = load_dcop_from_file(["/pyDcop/tests/instances/graph_coloring_tuto.yaml"])

    assert assignment == {"vA": "G", "vB": "G", "vC": "G", "vD": "G"}
def test_density_two_var_one_factor():
    dcop = DCOP('test', 'min')
    d1 = Domain('d1', '--', [1, 2, 3])
    v1 = Variable('v1', d1)
    v2 = Variable('v2', d1)
    dcop += 'c1', '0.5 * v1 + v2', [v1, v2]

    g = build_computation_graph(dcop)

    assert g.density() == 4 / 6
def test_one_var_one_factor():
    dcop = DCOP('test', 'min')
    d1 = Domain('d1', '--', [1, 2, 3])
    v1 = Variable('v1', d1)
    dcop += 'c1', '0.5 * v1', [v1]

    g = build_computation_graph(dcop)

    assert len(g.links) == 1
    assert len(g.nodes) == 2
Ejemplo n.º 15
0
def test_filter_dcop_unary_constraint_accepted():
    dcop = DCOP()

    d = VariableDomain('test', 'test', values=range(10))

    v1 = Variable('v1', d)
    v2 = Variable('v2', d)
    v3 = Variable('v3', d)
    v4 = Variable('v4', d)

    dcop += 'c1', '0 if v1 != v2 else 1000', [v1, v2]
    # unary constraint on V3
    dcop += 'c2', 'v3 * 0.5', [v3]
    dcop.add_variable(v4)

    filtered = filter_dcop(dcop, accept_unary=False)

    # c2 and v3 must stay here, as we accept unary constraints, but v4 must be gone
    assert "v3" in filtered.variables
    assert "c2" in filtered.constraints
    assert "v4" not in filtered.variables
Ejemplo n.º 16
0
def test_dcop_add_constraint_easy_api():
    dcop = DCOP()
    d = VariableDomain('test', 'test', values=range(10))

    v1 = Variable('v1', d)
    v2 = Variable('v2', d)

    dcop += 'c1', '0 if v1 != v2 else 1000', [v1, v2]

    assert 'c1' in dcop.constraints
    assert dcop.variables == {'v1': v1, 'v2': v2}
    assert dcop.domains == {'test': d}
    def test_3nodes_tree_cycle(self):
        domain = ['a', 'b', 'c']
        x1 = Variable('x1', domain)
        x2 = Variable('x2', domain)
        x3 = Variable('x3', domain)
        variables = [x1, x2, x3]

        r1 = NAryFunctionRelation(lambda x, y: x + y, [x1, x2], name='r1')
        r2 = NAryFunctionRelation(lambda x, y: x + y, [x1, x3], name='r2')
        r3 = NAryFunctionRelation(lambda x, y: x + y, [x2, x3], name='r3')
        relations = [r1, r2, r3]

        dcop = DCOP('test', 'min')
        dcop.add_constraint(r1)
        dcop.add_constraint(r2)
        dcop.add_constraint(r3)

        cg = build_computation_graph(dcop)
        self.assertEqual(len(cg.nodes), len(variables))

        self.assertEqual(len(cg.roots), 1)
        # All variables have the same number of neighbors, they could all be
        #  root
        self.assertIn(cg.roots[0].variable, [x1, x2, x3])
        self.assertEqual(cg.roots[0].parent, None)

        root = _generate_dfs_tree(variables, relations, root=x1)
        self.assertEqual(root.variable, x1)
        self.assertEqual(root.parent, None)
Ejemplo n.º 18
0
def test_dcop_add_agents_from_dict():
    dcop = DCOP()
    agts = create_agents('a', [1, 2, 3])
    dcop.add_agents(agts)

    assert dcop.agent('a1').name == 'a1'
    assert dcop.agent('a2').name == 'a2'
    assert dcop.agent('a3').name == 'a3'
def create_dcop():
    dcop = DCOP('test')
    # Domain and vraibales
    d = Domain('color', '', ['R', 'G'])
    variables = create_variables('v', [1, 2, 3], d)
    # unary constraints for preferences
    dcop += 'cost_1', '-0.1 if v1 == "R" else 0.1 ', variables
    dcop += 'cost_2', '-0.1 if v2 == "G" else 0.1 ', variables
    dcop += 'cost_3', '-0.1 if v3 == "G" else 0.1 ', variables
    # coloring constraints : v1 != v2 != v3
    dcop += 'c1', '1 if v1 == v2 else 0', variables
    dcop += 'c2', '1 if v3 == v2 else 0', variables

    return dcop
Ejemplo n.º 20
0
def load_dcop(dcop_str: str) -> DCOP:
    loaded = yaml.load(dcop_str)

    if 'name' not in loaded:
        raise ValueError('Missing name in dcop string')
    if 'objective' not in loaded or loaded['objective'] not in ['min', 'max']:
        raise ValueError('Objective is mandatory and must be min or max')

    dcop = DCOP(loaded['name'], loaded['objective'],
                loaded['description'] if 'description' in loaded else '')

    dcop.domains = _build_domains(loaded)
    dcop.variables = _build_variables(loaded, dcop)
    dcop.external_variables = _build_external_variables(loaded, dcop)
    dcop._constraints = _build_constraints(loaded, dcop)
    dcop._agents_def = _build_agents(loaded)
    dcop.dist_hints = _build_dist_hints(loaded, dcop)
    return dcop
Ejemplo n.º 21
0
def generate_secp(args):
    logger.info("Generate SECP %s", args)
    light_count = args.lights
    model_count = args.models
    rule_count = args.rules
    capacity = args.capacity
    max_model_size = args.max_model_size
    max_rule_size = args.max_rule_size

    light_domain = Domain("light", "light", range(0, 5))

    lights_var, lights_cost = build_lights(light_count, light_domain)

    models_var, models_constraints = build_models(
        light_domain, lights_var, max_model_size, model_count
    )

    rules_constraints = build_rules(rule_count, lights_var, models_var, max_rule_size)

    # Agents : one for each light
    agents = build_agents(lights_var, lights_cost, capacity)

    # Force
    # * each light variable to be hosted on the corresponding agent
    # * model constraint and var are preferred on the same agent

    variables = lights_var.copy()
    variables.update(models_var)

    constraints = models_constraints.copy()
    constraints.update(lights_cost)
    constraints.update(rules_constraints)

    dcop = DCOP(
        "graph coloring",
        "min",
        domains={"light_domain": light_domain},
        variables=variables,
        agents=agents,
        constraints=constraints,
    )

    if args.output:
        outputfile = args.output
        write_in_file(outputfile, dcop_yaml(dcop))
    else:
        print(dcop_yaml(dcop))
Ejemplo n.º 22
0
def load_dcop(dcop_str: str) -> DCOP:
    loaded = yaml.load(dcop_str, Loader=yaml.FullLoader)

    if "name" not in loaded:
        raise ValueError("Missing name in dcop string")
    if "objective" not in loaded or loaded["objective"] not in ["min", "max"]:
        raise ValueError("Objective is mandatory and must be min or max")

    dcop = DCOP(
        loaded["name"],
        loaded["objective"],
        loaded["description"] if "description" in loaded else "",
    )

    dcop.domains = _build_domains(loaded)
    dcop.variables = _build_variables(loaded, dcop)
    dcop.external_variables = _build_external_variables(loaded, dcop)
    dcop._constraints = _build_constraints(loaded, dcop)
    dcop._agents_def = _build_agents(loaded)
    dcop.dist_hints = _build_dist_hints(loaded, dcop)
    return dcop
Ejemplo n.º 23
0
def test_filter_dcop_unary_constraint():
    dcop = DCOP()

    d = VariableDomain('test', 'test', values=range(10))

    v1 = Variable('v1', d)
    v2 = Variable('v2', d)
    v3 = Variable('v3', d)

    dcop += 'c1', '0 if v1 != v2 else 1000', [v1, v2]
    # unary constraint on V3
    dcop += 'c2', 'v3 * 0.5', [v3]
    assert dcop.variables == {'v1': v1, 'v2': v2, "v3": v3}

    filtered = filter_dcop(dcop)

    # v3 is only involved in unary constraints c2 => v3 and c2 should be gone
    assert filtered.variables == {'v1': v1, 'v2': v2}
    assert "c2" not in filtered.constraints
Ejemplo n.º 24
0
def test_build_graph_from_dcop():
    d = Domain('d', 'test', [1, 2, 3])
    v1 = Variable('v1', d)
    v2 = Variable('v2', d)
    v3 = Variable('v3', d)
    dcop = DCOP('dcop_test', 'min')
    dcop += 'c1', 'v1 * 0.5 + v2 - v3', [v1, v2, v3]
    c1 = dcop.constraints['c1']

    graph = build_computation_graph(dcop)

    links = list(graph.links)
    assert 1 == len(links)
    assert ConstraintLink(c1.name, {'v1', 'v2', 'v3'}) in links

    nodes = list(graph.nodes)
    assert 3 == len(nodes)
    assert VariableComputationNode(v1, [c1]) in nodes
    assert VariableComputationNode(v2, [c1]) in nodes
    assert VariableComputationNode(v3, [c1]) in nodes
Ejemplo n.º 25
0
def dcop_graphcoloring_3():
    """
    Build a simple 3-variable graph coloring problem.

    v1--v2--v3

    Each variable has a cost function which makes it prefer one color:
    v1 prefers R
    v2 prefers G
    v3 prefers G

    Of course, the preferences of v2 and v3 conflict.
    The best affectation is
    v1 - R
    v2 - G
    v3 - R

    Returns
    -------

    """
    dcop = DCOP('graphcoloring_3')
    # Domain and variables
    d = Domain('color', '', ['R', 'G'])
    variables = create_variables('v', ['1', '2', '3'], d)
    # unary constraints for preferences
    dcop += 'cost_1', '-0.1 if v1 == "R" else 0.1 ', variables
    dcop += 'cost_2', '-0.1 if v2 == "G" else 0.1 ', variables
    dcop += 'cost_3', '-0.1 if v3 == "G" else 0.1 ', variables
    # coloring constraints : v1 != v2 != v3
    dcop += 'c1', '1 if v1 == v2 else 0', variables
    dcop += 'c2', '1 if v3 == v2 else 0', variables

    # Note that we do not define the agents for this dcop here,
    # as the number of agents depends on the test case we will use the dcop for.

    return dcop
Ejemplo n.º 26
0
def generate_mixed_problem(args):
    logger.debug('generate_mixed_problem %s ', args)
    variable_count = args.variable_count
    constraint_count = args.constraint_count
    density = args.density
    real_density = density
    domain_range = args.range
    arity = args.arity
    auto_agents = args.agents is None
    capacity = args.capacity
    agents_count = variable_count if auto_agents else args.agents
    nb_max_edges = constraint_count * min(arity, variable_count)
    edges_count = int(nb_max_edges * density)
    hard_count = int(args.hard_constraint * edges_count)
    logger.info(
        'Generating random DCOP graph with %s variables, whose domain '
        'are [0;%s], %s edges, %s agents, %s hard '
        'constraints and %s soft constraints', variable_count,
        domain_range - 1, edges_count, agents_count, hard_count,
        constraint_count - hard_count)

    if arity > variable_count:
        raise ValueError(
            "The arity of a constraint must be at most the "
            "number of variable. Arity: {}, Nb variables: {}".format(
                arity, variable_count))

    if hard_count < 0:
        raise ValueError(
            "The argument '-h' (or '--hard_count') must be "
            "between 0 and 1. Currently set to: {}".format(hard_count))
    # Create sets for the bipartite graph
    if constraint_count <= 0:
        raise ValueError(
            "The argument '-c' (or '--constraint_count') must be "
            "strictly positive. Currently set to: {}".format(constraint_count))
    if variable_count < 0:
        raise ValueError(
            "The argument '-v' (or '--variable_count') must be "
            "at least 1. Currently set to: {}".format(variable_count))
    if arity <= 0:
        raise ValueError("The argument '-a' (or '--arity') must be "
                         "at least 1. Currently set to: {}".format(arity))

    d = VariableDomain('levels', 'level', range(domain_range))
    variables = {}
    agents = {}
    constraints = {}

    if arity == 1:
        if constraint_count != variable_count:
            raise ValueError("For max arity 1 you need the same number of "
                             "variables, constraints and edges. You asked "
                             "for {} variables and {} constraints.".format(
                                 variable_count, constraint_count))
        nodes = [i + 1 for i in range(variable_count)]
        constraints_list = [("c{}".format(i + 1),
                             'hard') if i < hard_count else
                            ("c{}".format(i + 1), 'soft')
                            for i in range(constraint_count)]
        variables = {}
        constraints = {}
        while len(nodes) != 0:
            n = nodes.pop()
            c = constraints_list.pop(
                random.randint(0,
                               len(constraints_list) - 1))
            w = choose_weight()
            hard = c[1] == 'hard'
            objective = find_objective([w], domain_range - 1, hard)
            if hard:
                expression = "float('inf') if " + str(w) + "*v" + str(n) +\
                             " != " + str(objective) + " else 0"
            else:
                expression = str(w) + "*v" + str(n) + " - " + str(objective)

            v = Variable("v" + str(n), d)
            variables["v" + str(n)] = v
            constraints[c[0]] = relation_from_str(c[0], expression, [v])

            if auto_agents:
                a_name = 'a' + str(n)
                agents[a_name] = AgentDef(a_name, capacity)

        if not auto_agents:
            for i in range(agents_count):
                a_name = 'a' + str(i)
                agents[a_name] = AgentDef(a_name, capacity)

    elif arity == 2:
        edges_count = int(variable_count * (variable_count - 1) * density / 2)
        if constraint_count != edges_count:
            logger.warning("edges count is different of constraint count ({} "
                           "!= {}) but for arity 2, constraints are the deges"
                           "of the graph. We use the density ({}) to determine"
                           " the number of edges".format(
                               edges_count, constraint_count, density))
        is_connected = False
        while not is_connected:
            graph = nx.gnp_random_graph(variable_count, density)
            is_connected = nx.is_connected(graph)

        # Compute nb of hard constraints regarding the true density
        real_density = nx.density(graph)
        hard_count = args.hard_constraint * real_density * args.variable_count\
                     * (args.variable_count + 1) / 2

        for i, node in enumerate(graph.nodes_iter()):
            logger.debug('node %s - %s', node, i)
            name = 'v' + str(i)
            variables[name] = Variable(name, d)
            if auto_agents:
                a_name = 'a' + str(i)
                agents[a_name] = AgentDef(a_name, capacity)

        if not auto_agents:
            for i in range(agents_count):
                a_name = 'a' + str(i)
                agents[a_name] = AgentDef(a_name, capacity)

        constraints = {}
        for i, edge in enumerate(graph.edges_iter()):
            logger.debug('edge %s - %s', edge, i)
            name = 'c' + str(i)
            u, v = edge
            weights = [round(choose_weight(), 2), round(choose_weight(), 2)]

            # Create hard_constraints
            if i < hard_count:
                objective = round(find_objective(weights, domain_range, True),
                                  2)
                expression = "0 if v{} != v{} else float(" \
                             "'inf')".format(u, v)
            else:
                max_val = (weights[0] + weights[1]) * domain_range
                expression = 'abs(v{} + v{} - {})'\
                    .format(u, v, round(random.uniform(0, max_val), 2))

            constraints[name] = relation_from_str(name, expression,
                                                  variables.values())
            logger.debug(repr(constraints[name]))

    else:
        if edges_count < constraint_count and arity != 1:
            raise ValueError(
                "The number of edges must be greater or equal to the "
                "number of constraints. Otherwise you have unused "
                "constraints. Edges: {}, Constraints: {}".format(
                    edges_count, constraint_count))
        nodes = [i for i in list(range(variable_count))]
        constraints = [("c{}".format(i), "hard") if i < hard_count else
                       ("c{}".format(i), "soft")
                       for i in list(range(constraint_count))]
        # Randomly add edges
        edges = defaultdict(lambda: [])  # final set of edges

        # Available edges at a given run
        available_edges = {n: constraints.copy() for n in nodes}
        # First, make sure each variable has one constraint
        for n in nodes:
            if constraints:
                node = n
                c = constraints.pop(random.randint(0, len(constraints) - 1))
            else:
                node, c = choose_in_available_edges(available_edges, n)
            add_edge(node, c, available_edges, edges, arity)
            logger.debug('Add edge (%s, %s)', n, c)
        edges_count -= variable_count

        # Second, make sure each constraint is used
        for c in constraints:
            n = random.choice(nodes)
            add_edge(n, c, available_edges, edges, arity)
            edges_count -= 1
            logger.debug('Add edge (%s, %s)', n, c)

        # Third, randomly add remaining constraints
        while edges_count != 0:
            n, c = choose_in_available_edges(available_edges)
            if (n, c) == (None, None):
                # If more edges than possible are asked, returns just the maximum
                # edges (regarding nodes number and constraints arity)
                logger.warning(
                    '%s edges were not added because you asked for too'
                    ' many edges regarding the number of constraints ('
                    '%s) and their maximum arity (%s)',
                    edges_count - len(edges), constraint_count, args.arity)
                break
            else:
                add_edge(n, c, available_edges, edges, arity)
                edges_count -= 1

        # Now create a DCOP from the graph
        for i in nodes:
            name = 'v' + str(i)
            variables[name] = Variable(name, d)
            if auto_agents:
                a_name = 'a' + str(i)
                agents[a_name] = AgentDef(a_name, capacity)

        if not auto_agents:
            for i in range(agents_count):
                a_name = 'a' + str(i)
                agents[a_name] = AgentDef(a_name, capacity)

        constraints = {}
        for c, neighbors in edges.items():
            logger.debug('Constraint %s, variables: %s', c, neighbors)
            name, is_hard = c[0], c[1] == 'hard'
            c_variables = [variables["v" + str(name)] for name in neighbors]
            addition_string = ""
            first = True
            weights = []
            max_val = 0
            for i in neighbors:
                # Add random weights in constraints
                m = round(choose_weight(), 2)
                weights.append(m)
                max_val += m * (domain_range - 1)
                if not first:
                    addition_string += ' + '
                else:
                    first = False
                if m != 1:
                    addition_string += str(m) + '*'
                addition_string += 'v' + str(i) + ' '

            # To ensure that our hard constraints are achievable, we use
            # the value obtained for a set of random values (in the domain)
            # as the objective.

            objective = round(find_objective(weights, domain_range, is_hard),
                              2)

            if is_hard:
                expression = "0 if " + addition_string + " == " + \
                             str(objective) + " else float('inf')"
            else:
                const_function = "abs(" + addition_string
                if objective:
                    expression = const_function + " - " + str(objective) + ")"
                else:
                    expression = addition_string

            constraints[name] = relation_from_str(name, expression,
                                                  c_variables)
            logger.debug(repr(constraints[name]))

    dcop = DCOP('mixed constraints problem',
                'min',
                domains={'levels': d},
                variables=variables,
                constraints=constraints,
                agents=agents)

    if args.output is not None:
        outputfile = args.output[0]
        if args.correct_density:
            outputfile = correct_density(outputfile, real_density)
        write_in_file(outputfile, dcop_yaml(dcop))
    else:
        print(dcop_yaml(dcop))
Ejemplo n.º 27
0
def generate_graph_coloring(args):
    logger.debug('generate_graph_coloring %s ', args)
    node_count = args.node_count
    density = args.density
    color_count = args.color_count
    auto_agents = args.agents is None
    agents_count = node_count if auto_agents else args.agents
    capacity = args.capacity
    logger.info(
        'Generating random graph coloring with %s variables, '
        '%s colors, target density %s and %s agents', node_count, color_count,
        args.density, agents_count)

    # First a random graph
    is_connected = False
    if not args.allow_subgraph:
        while not is_connected:
            graph = nx.gnp_random_graph(args.node_count, density)
            is_connected = nx.is_connected(graph)
    else:
        graph = nx.gnp_random_graph(args.node_count, density)
        is_connected = nx.is_connected(graph)

    real_density = nx.density(graph)
    logger.info(nx.info(graph))
    logger.info('Connected : %s', nx.is_connected(graph))
    logger.info('Density %s', nx.density(graph))

    # Now create a DCOP from the graph
    d = VariableDomain('colors', 'color', range(color_count))
    variables = {}
    agents = {}
    for i, node in enumerate(graph.nodes_iter()):
        logger.debug('node %s - %s', node, i)
        name = 'v' + str(i)
        variables[name] = Variable(name, d)
        if auto_agents:
            a_name = 'a' + str(i)
            agents[a_name] = AgentDef(a_name, capacity)

    if not auto_agents:
        for i in range(agents_count):
            a_name = 'a' + str(i)
            agents[a_name] = AgentDef(a_name, capacity)

    constraints = {}
    for i, edge in enumerate(graph.edges_iter()):
        logger.debug('edge %s - %s', edge, i)
        name = 'c' + str(i)
        u, v = edge
        expression = '1000 if v{} == v{} else 0'.format(u, v)
        constraints[name] = relation_from_str(name, expression,
                                              variables.values())
        logger.debug(repr(constraints[name]))

    dcop = DCOP('graph coloring',
                'min',
                domains={'colors': d},
                variables=variables,
                agents=agents,
                constraints=constraints)

    if args.output:
        outputfile = args.output[0]
        if args.correct_density:
            outputfile = correct_density(outputfile, real_density)
        write_in_file(outputfile, dcop_yaml(dcop))
    else:
        print(dcop_yaml(dcop))
Ejemplo n.º 28
0
def generate_iot(args):
    print("generate iot ", args.output)

    # Constraints and variables with a power-law constraint graph:
    variables, constraints, domain = generate_powerlaw_var_constraints(
        args.num, args.domain, args.range
    )

    # Build a dcop and computation graph with no agents, just to be able to
    # compute the footprint of computations:
    dcop = DCOP(
        "graph coloring",
        "min",
        domains={"d": domain},
        variables=variables,
        agents={},
        constraints=constraints,
    )
    graph_module = import_module("pydcop.computations_graph.factor_graph")
    cg = graph_module.build_computation_graph(dcop)
    algo_module = load_algorithm_module("maxsum")

    footprints = {c.name: algo_module.computation_memory(c) for c in cg.nodes}

    # Generate an agent for each variable computation and assign the
    # computation to that agent.
    agents = {}  # type: Dict[str, AgentDef]
    mapping = defaultdict(lambda: [])  # type: Dict[str, List[str]]
    for comp in cg.nodes:
        if isinstance(comp, VariableComputationNode):
            a_name = agt_name(comp.name)
            agt = AgentDef(
                a_name,
                capacity=footprints[comp.name] * 100,
                default_hosting_cost=10,
                hosting_costs=agt_hosting_costs(comp, cg),
                default_route=1,
                routes=agt_route_costs(comp, cg),
            )
            logger.debug(
                "Create agent %s for computation %s with capacity %s",
                agt.name,
                comp.name,
                agt.capacity,
            )
            agents[agt.name] = agt
            mapping[agt.name].append(comp.name)

    # Now, we have created all the agents and distributed all the variables
    # let's distribute the factor computations.
    msg_load = msg_load_func(cg, algo_module.communication_load)
    factor_mapping = distribute_factors(agents, cg, footprints, mapping, msg_load)
    for a in mapping:
        mapping[a].extend(factor_mapping[a])

    dcop = DCOP(
        "graph coloring",
        "min",
        domains={"d": domain},
        variables=variables,
        agents=agents,
        constraints=constraints,
    )

    distribution = Distribution(mapping)

    if args.output:
        outputfile = args.output
        write_in_file(outputfile, dcop_yaml(dcop))

        dist = distribution.mapping()
        cost = ilp_compref.distribution_cost(
            distribution,
            cg,
            dcop.agents.values(),
            computation_memory=algo_module.computation_memory,
            communication_load=algo_module.communication_load,
        )

        result = {
            "inputs": {
                "dist_algo": "io_problem",
                "dcop": args.output,
                "graph": "factor_graph",
                "algo": "maxsum",
            },
            "distribution": dist,
            "cost": cost,
        }
        outputfile = "dist_" + args.output
        write_in_file(outputfile, yaml.dump(result))
    else:
        print(dcop_yaml(dcop))
Ejemplo n.º 29
0
def generate(args):
    slots, events, resources = generate_problem_definition(
        args.slots_count,
        args.resources_count,
        args.max_resource_value,
        args.events_count,
        args.max_length_event,
        args.max_resources_event,
    )

    penalty = args.max_resource_value * args.slots_count * args.resources_count
    variables, constraints, agents = peav_model(slots, events, resources,
                                                penalty)

    domains = {
        variable.domain.name: variable.domain
        for variable in variables.values()
    }
    variables = {variable.name: variable for variable in variables.values()}
    # agents_defs = {agent.name: agent for agent, _ in agents.values()}
    # Generate agents hosting and route costs
    agents_defs = {}
    if not args.no_agents:
        for agent, agt_variables in agents.items():
            kw = {}
            kw["hosting_costs"] = {v.name: 0 for v in agt_variables}
            if args.hosting_default:
                kw["default_hosting_cost"] = args.hosting_default
            if args.capacity:
                kw["capacity"] = args.capacity
            if args.routes_default:
                kw["default_route"] = args.routes_default
            agents_defs[agent] = AgentDef(agent, **kw)

    dcop = DCOP(
        "MeetingSceduling",
        objective="max",
        domains=domains,
        variables=variables,
        constraints=constraints,
        agents=agents_defs,
    )

    if not args.no_agents:
        distribution = Distribution({
            agent.name: [v.name for v in agents[agent.name]]
            for agent in agents_defs.values()
        })

    if args.output:
        output_file = args.output
        with open(output_file, encoding="utf-8", mode="w") as fo:
            fo.write(dcop_yaml(dcop))

        if not args.no_agents:
            dist_result = {
                "inputs": {
                    "dist_algo": "peav",
                    "dcop": output_file,
                    "graph": "constraints_graph",
                    "algo": "NA",
                },
                "distribution": distribution.mapping(),
                "cost": None,
            }
            path, ext = splitext(output_file)
            dist_output_file = f"{path}_dist{ext}"
            with open(dist_output_file, encoding="utf-8", mode="w") as fo:
                fo.write(yaml.dump(dist_result))

    else:
        print(dcop_yaml(dcop))

        if not args.no_agents:
            dist_result = {
                "inputs": {
                    "dist_algo": "peav",
                    "dcop": "NA",
                    "graph": "constraints_graph",
                    "algo": "NA",
                },
                "distribution": distribution.mapping(),
                "cost": None,
            }
            # FIXME proper serialization of the distribution:
            print(yaml.dump(dist_result))
Ejemplo n.º 30
0
def generate_small_world(args):
    logger.debug("generate small world problem %s ", args)

    # Erdős-Rényi graph aka binomial graph.
    graph = nx.barabasi_albert_graph(args.num, 2)

    # import matplotlib.pyplot as plt
    # plt.subplot(121)
    # nx.draw(graph)  # default spring_layout
    # plt.show()

    domain = Domain("d", "d", range(args.domain))
    variables = {}
    agents = {}
    for n in graph.nodes:
        v = Variable(var_name(n), domain)
        variables[v.name] = v
        logger.debug("Create var for node %s : %s", n, v)

    constraints = {}
    for i, (n1, n2) in enumerate(graph.edges):
        v1 = variables[var_name(n1)]
        v2 = variables[var_name(n2)]
        values = random_assignment_matrix([v1, v2], range(args.range))
        c = NAryMatrixRelation([v1, v2], values, name=c_name(n1, n2))
        logger.debug("Create constraints for edge (%s, %s) : %s", v1, v2, c)
        constraints[c.name] = c

    dcop = DCOP(
        "graph coloring",
        "min",
        domains={"d": domain},
        variables=variables,
        agents={},
        constraints=constraints,
    )
    graph_module = import_module("pydcop.computations_graph.factor_graph")
    cg = graph_module.build_computation_graph(dcop)
    algo_module = load_algorithm_module("maxsum")

    footprints = {n.name: algo_module.computation_memory(n) for n in cg.nodes}
    f_vals = footprints.values()
    logger.info(
        "%s computations, footprint: \n  sum: %s, avg: %s max: %s, "
        "min: %s",
        len(footprints),
        sum(f_vals),
        sum(f_vals) / len(footprints),
        max(f_vals),
        min(f_vals),
    )

    default_hosting_cost = 2000
    small_agents = [agt_name(i) for i in range(75)]
    small_capa, avg_capa, big_capa = 40, 200, 1000
    avg_agents = [agt_name(i) for i in range(75, 95)]
    big_agents = [agt_name(i) for i in range(95, 100)]
    hosting_factor = 10

    for a in small_agents:
        # communication costs with all other agents
        comm_costs = {other: 6 for other in small_agents if other != a}
        comm_costs.update({other: 8 for other in avg_agents})
        comm_costs.update({other: 10 for other in big_agents})
        # hosting cost for all computations
        hosting_costs = {}
        for n in cg.nodes:
            # hosting_costs[n.name] = hosting_factor * \
            #                         abs(small_capa -footprints[n.name])
            hosting_costs[n.name] = footprints[n.name] / small_capa

        agt = AgentDef(
            a,
            default_hosting_cost=default_hosting_cost,
            hosting_costs=hosting_costs,
            default_route=10,
            routes=comm_costs,
            capacity=small_capa,
        )
        agents[agt.name] = agt
        logger.debug("Create small agt : %s", agt)

    for a in avg_agents:
        # communication costs with all other agents
        comm_costs = {other: 8 for other in small_agents}
        comm_costs.update({other: 2 for other in avg_agents if other != a})
        comm_costs.update({other: 4 for other in big_agents})
        # hosting cost for all computations
        hosting_costs = {}
        for n in cg.nodes:
            # hosting_costs[n.name] = hosting_factor * \
            #                         abs(avg_capa - footprints[n.name])
            hosting_costs[n.name] = footprints[n.name] / avg_capa

        agt = AgentDef(
            a,
            default_hosting_cost=default_hosting_cost,
            hosting_costs=hosting_costs,
            default_route=10,
            routes=comm_costs,
            capacity=avg_capa,
        )
        agents[agt.name] = agt
        logger.debug("Create avg agt : %s", agt)

    for a in big_agents:
        # communication costs with all other agents
        comm_costs = {other: 10 for other in small_agents}
        comm_costs.update({other: 4 for other in avg_agents})
        comm_costs.update({other: 1 for other in big_agents if other != a})
        # hosting cost for all computations
        hosting_costs = {}
        for n in cg.nodes:
            hosting_costs[n.name] = footprints[n.name] / big_capa

        agt = AgentDef(
            a,
            default_hosting_cost=default_hosting_cost,
            hosting_costs=hosting_costs,
            default_route=10,
            routes=comm_costs,
            capacity=big_capa,
        )
        agents[agt.name] = agt
        logger.debug("Create big agt : %s", agt)

    dcop = DCOP(
        "graph coloring",
        "min",
        domains={"d": domain},
        variables=variables,
        agents=agents,
        constraints=constraints,
    )

    if args.output:
        outputfile = args.output[0]
        write_in_file(outputfile, dcop_yaml(dcop))
    else:
        print(dcop_yaml(dcop))