def dpop_petcu():
    comm = infrastructure.communication.InProcessCommunicationLayer()

    # Variables definition:

    x0 = Variable('x0', ['a', 'b', 'c'])
    x1 = Variable('x1', ['a', 'b', 'c'])
    x2 = Variable('x2', ['a', 'b', 'c'])
    x3 = Variable('x3', ['a', 'b', 'c'])

    # relation between variables

    r1_0 = relations.NAryMatrixRelation([x1, x0],
                                        [[2, 2, 3], [5, 3, 7], [6, 3, 1]])
    r2_1 = relations.NAryMatrixRelation([x2, x1],
                                        [[0, 2, 1], [3, 4, 6], [5, 2, 5]])
    r3_1 = relations.NAryMatrixRelation([x3, x1],
                                        [[6, 2, 3], [3, 3, 2], [4, 4, 1]])

    al0 = DpopAlgo(x0)
    al1 = DpopAlgo(x1)
    al2 = DpopAlgo(x2)
    al3 = DpopAlgo(x3)

    al0.add_child(x1)
    al1.add_child(x2)
    al1.add_child(x3)

    al2.set_parent(x1)
    al2.add_relation(r2_1)
    al3.set_parent(x1)
    al3.add_relation(r3_1)
    al1.set_parent(x0)
    al1.add_relation(r1_0)

    a0 = Agent('a0', comm)
    a0.add_computation(al0)
    a1 = Agent('a1', comm)
    a1.add_computation(al1)
    a2 = Agent('a2', comm)
    a2.add_computation(al2)
    a3 = Agent('a3', comm)
    a3.add_computation(al3)

    results, _, _ = infrastructure.synchronous_single_run([a0, a1, a2, a3])

    if results == {'x0': 'a', 'x1': 'c', 'x2': 'b', 'x3': 'a'}:
        logging.info('SUCCESS !! ')
        return 0
    else:
        logging.info('invalid result found, needs some debugging ...' +
                     str(results))
        return 1
예제 #2
0
def graph_coloring_no_prefs():

    # Extremely simple graph coloring problem
    # Three variables, 2 constraints, no cycle
    # modelled as 3 variables and two factors, each variable and each factor
    # has its own agent.

    # This problem has a strong symmetry and several optimal solutions:
    # applying maxsum does not allow to make a choice and each variable keeps
    # its full domain available, which means that for any value di from
    # domain Di of variable xi, there exists an optimal assignment in which
    # xi take di.
    #
    # To select a solution, an extra step would be needed : select a value
    # for one variable and walk the tree to get the value for other variables
    # induced by this first choice.

    d = ['R', 'G']
    v1 = Variable('v1', d)
    v2 = Variable('v2', d)
    v3 = Variable('v3', d)

    # cost table for the factor, simply reflects the fact that neighbor
    # variables shoud not have the same value
    BIN_DIFF_TABLE_2 = [[1, 0], [0, 1]]
    # Factor between v1 and v2
    f12 = relations.NAryMatrixRelation([v1, v2],
                                       name='f12',
                                       matrix=BIN_DIFF_TABLE_2)

    # Factor between v2 and v3
    f23 = relations.NAryMatrixRelation([v2, v3],
                                       name='f23',
                                       matrix=BIN_DIFF_TABLE_2)

    # Map the factor graph to agents and solve it
    node_agents = distribue_agent_for_all([v1, v2, v3], [f12, f23])
    # this sample does not work with our standard run method :
    # no factor is a leaf, which means that no start message is sent !
    # We need to initiate messages manually
    for n in node_agents:
        for a in n.computations:
            if hasattr(a, '_init_msg'):
                a._init_msg()
    res, _, _ = infrastructure.synchronous_single_run(node_agents)

    print("FINISHED ! " + str(res))
예제 #3
0
def graph_coloring_with_prefs():

    # In this setup, we introduce preferences for each variable
    # as we are minimizing, we express preferences as cost (with lower cost
    # for preferred value)
    # v1 prefers 'R' p(v1) = [ -0.1, +0.1]
    # v2 and v3 prefer 'G'  p(v2) = p(v3) = [ +0.1, -0.1]

    # With This preferences, MaxSum now correctly selects the optimal assignment
    # v1 = R, v2 = G , v3 = R

    d = ['R', 'G']
    v1 = Variable('v1', d)
    v2 = Variable('v2', d)
    v3 = Variable('v3', d)

    # Factor (cost) between v1 and v2
    # f12 = (x1 == x2) + p(x1) + p(x2)
    # where (x1 == x2) is 1 if x1 equals x2 and 0 otherwise
    BIN_DIFF_TABLE_PREFS_12 = [[1, 0.2], [-0.1, 1]]

    f12 = relations.NAryMatrixRelation([v1, v2],
                                       name='f12',
                                       matrix=BIN_DIFF_TABLE_PREFS_12)
    # f12 = maxsum.BinaryValueTable('f12', v1, v2, BIN_DIFF_TABLE_PREFS_12)

    # Factor between v2 and v3
    BIN_DIFF_TABLE_PREFS_23 = [[1.2, 0], [0, 0.8]]
    f23 = relations.NAryMatrixRelation([v2, v3],
                                       name='f23',
                                       matrix=BIN_DIFF_TABLE_PREFS_23)
    # f23 = maxsum.BinaryValueTable('f23', v2, v3, BIN_DIFF_TABLE_PREFS_23)

    # Map the factor graph to agents and solve it
    node_agents = distribue_agent_for_all([v1, v2, v3], [f12, f23])
    # this sample does not work with our standard run method :
    # no factor is a leaf, which means that no start message is sent !
    # We need to initiate messages manually
    for n in node_agents:
        for a in n.computations:
            if hasattr(a, '_init_msg'):
                a._init_msg()
    res, _, _ = infrastructure.synchronous_single_run(node_agents)

    print("FINISHED ! " + str(res))
def maxsum_smartlights_multiplecomputationagent_costvariable():
    """

    This sample use variable with integrated cost.


     * 3 lights l1, l2 & l3
       each light can have a luminosity level in the  0-9 range
       The energy cost is a linear function of the luminosity level, with l1
       more efficient than l2 and l3

     * one scene action y1, the room luminosity level
       y1 = (l1 + l2 + l3 )/3
       y1 domain is also between 0-9

     * one rule :
       l3 must be off AND y1 Must be 5


    """
    # building the Factor Graph
    # Lights :

    l1 = VariableWithCostFunc('l1', list(range(10)), lambda x: x * 0.5)
    l2 = VariableWithCostFunc('l2', list(range(10)), lambda x: x)
    l3 = VariableWithCostFunc('l3', list(range(10)), lambda x: x)

    # Scene action
    y1 = Variable('y1', list(range(10)))

    @relations.AsNAryFunctionRelation(l1, l2, l3, y1)
    def scene_rel(l1, l2, l3, y1):
        if y1 == round(l1 / 3.0 + l2 / 3.0 + l3 / 3.0):
            return 0
        return INFNT

    # Rule
    @relations.AsNAryFunctionRelation(l3, y1)
    def rule_rel(l3, y1):
        """
        This rule means : target luminosity if 5, and x3 is off.

        :param x3:
        :param y1:
        :return:
        """
        return 10 * (abs(y1 - 5) + l3)

    # Create computation for factors and variables
    # Light 1
    algo_l1 = amaxsum.VariableAlgo(l1, [scene_rel.name])

    # Light 2
    algo_l2 = amaxsum.VariableAlgo(l2, [scene_rel.name])

    # Light 3
    algo_l3 = amaxsum.VariableAlgo(l3, [scene_rel.name, rule_rel.name])

    # Scene
    algo_y1 = amaxsum.VariableAlgo(y1, [rule_rel.name, scene_rel.name])
    algo_scene = amaxsum.FactorAlgo(scene_rel)

    # Rule
    algo_rule = amaxsum.FactorAlgo(rule_rel)

    # Distribution of the computation on the three physical light-bulb nodes.
    # We have 9 computations to distribute on 3 agents, mapping the 3 light
    # bulbs.
    comm = infrastructure.communication.InProcessCommunicationLayer()

    a1 = infrastructure.Agent('Bulb1', comm)
    a1.add_computation(algo_l1)
    a1.add_computation(algo_scene)
    a1.add_computation(algo_y1)

    a2 = infrastructure.Agent('Bulb2', comm)
    a2.add_computation(algo_l2)

    a3 = infrastructure.Agent('Bulb3', comm)
    a3.add_computation(algo_l3)
    a3.add_computation(algo_rule)

    dcop_agents = [a1, a2, a3]

    results, _, _ = infrastructure.synchronous_single_run(dcop_agents, 5)

    print(results)

    if results == {'l1': 9, 'y1': 5, 'l3': 0, 'l2': 5}:
        logging.info('SUCCESS !! ')
        return 0
    else:
        logging.info('invalid result found, needs some debugging ...' +
                     str(results))
        return 1
    type: intention
    function: 1 if v1 == v2 else 0
  diff_2_3: 
    type: intention
    function: 1 if v3 == v2 else 0

agents:
  a1:
    capacity: 100
  a2:
    capacity: 100
  a3:
    capacity: 100
  a4:
    capacity: 100
  a5:
    capacity: 100
    
"""

dcop = load_dcop(dcop_yaml)

cg = build_computation_graph(dcop)

mapping = distribute(cg, dcop.agents)

agents = deploy_on_local_agents(cg, mapping)

results, _, _ = synchronous_single_run(agents)

print("FINISHED ! " + str(results))