def test_hash(self): d1 = Domain("d", "foo", [1, 2, 3]) h1 = hash(d1) self.assertIsNotNone(h1) d2 = Domain("d", "foo", [1, 2, 4]) h2 = hash(d2) self.assertIsNotNone(h2) self.assertNotEqual(h1, h2) d3 = Domain("d", "foo", [1, 2, 3]) h3 = hash(d3) self.assertEqual(h1, h3)
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
def test_create_several_variables_from_list(self): d = Domain('color', '', ['R', 'G', 'B']) vars = create_variables('x_', ['a1', 'a2', 'a3'], d) self.assertIn('x_a1', vars) self.assertTrue(isinstance(vars['x_a2'], Variable)) self.assertEqual(vars['x_a3'].name, 'x_a3')
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"]
def test_create_several_variables_from_range(self): d = Domain("color", "", ["R", "G", "B"]) variables = create_variables("x_", range(10), d) self.assertIn("x_1", variables) self.assertTrue(isinstance(variables["x_2"], Variable)) self.assertEqual(variables["x_3"].name, "x_3")
def test_create_several_variables_from_list(self): d = Domain("color", "", ["R", "G", "B"]) variables = create_variables("x_", ["a1", "a2", "a3"], d) self.assertIn("x_a1", variables) self.assertTrue(isinstance(variables["x_a2"], Variable)) self.assertEqual(variables["x_a3"].name, "x_a3")
def test_create_several_variables_from_several_lists(self): d = Domain('color', '', ['R', 'G', 'B']) vars = create_variables('m_', (['x1', 'x2'], ['a1', 'a2', 'a3']), d) self.assertEqual(len(vars), 6) self.assertIn(('x1', 'a2'), vars) self.assertTrue(isinstance(vars[('x2', 'a3')], Variable)) self.assertEqual(vars[('x2', 'a3')].name, 'm_x2_a3')
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])
def test_create_several_variables_from_several_lists(self): d = Domain("color", "", ["R", "G", "B"]) variables = create_variables("m_", (["x1", "x2"], ["a1", "a2", "a3"]), d) self.assertEqual(len(variables), 6) self.assertIn(("x1", "a2"), variables) self.assertTrue(isinstance(variables[("x2", "a3")], Variable)) self.assertEqual(variables[("x2", "a3")].name, "m_x2_a3")
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])
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)
def test_simple_repr(self): d = Domain("d", "foo", [1, 2, 3]) r = simple_repr(d) print(r) self.assertEqual(r["__qualname__"], "Domain") self.assertEqual(r["__module__"], "pydcop.dcop.objects") self.assertEqual(r["name"], "d") self.assertEqual(r["domain_type"], "foo")
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_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'
def generate_powerlaw_var_constraints( num_var: int, domain_size: int, constraint_range: int ) -> Tuple[Dict[str, Variable], Dict[str, Constraint], Domain]: """ Generate variables and constraints for a power-law based constraints graph. All constraints are binary and the graph is generated using the Barabasi Albert method. Parameters ---------- num_var: int number of variables domain_size: int size of the domain of the variables constraint_range: int range in which constraints take their value (uniform random value of ech possible assignment). Returns ------- A tuple with variables, constraints and domain. """ # Use a barabasi powerlaw based constraints graph graph = nx.barabasi_albert_graph(num_var, 2) # import matplotlib.pyplot as plt # plt.subplot(121) # nx.draw(graph) # default spring_layout # plt.show() domain = Domain("d", "d", range(domain_size)) variables = {} 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(constraint_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 logger.info( "Generates %s variables and %s constraints in a powerlaw" "network", len(variables), len(constraints), ) return variables, constraints, domain
def test_simple_repr(self): d = Domain('d', 'foo', [1, 2, 3]) r = simple_repr(d) print(r) self.assertEqual(r['__qualname__'], 'Domain') self.assertEqual(r['__module__'], 'pydcop.dcop.objects') self.assertEqual(r['name'], 'd') self.assertEqual(r['domain_type'], 'foo') self.assertEqual(r['values'], [1, 2, 3])
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
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
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_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
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
def test_get_candidate_value_selected(): d = Domain("d", "vals", ["vB", "vD", "vA", "vE"]) v = Variable("v", d) obtained = get_value_candidates(v, "vB") assert obtained == ["vD", "vA", "vE"] obtained = get_value_candidates(v, "vA") assert obtained == ["vE"] obtained = get_value_candidates(v, "vE") assert obtained == []
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
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
def test_select_value_no_cost_var(): d = Domain("d", "", ["R", "G", "B"]) v1 = Variable("v1", d) selected, cost = select_value(v1, {}, "min") assert selected in {"R", "G", "B"} assert cost == 0 v1 = VariableWithCostFunc("v1", [1, 2, 3], lambda v: (4 - v) / 10) selected, cost = select_value(v1, {}, "min") assert selected == 3 assert cost == 0.1
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
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')]
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))
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