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
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))
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))