@propertydefagents(self)->list[Agent]:"""Return all agents controlled by the topology after the neighborhood were injected. :return: the list of agents :rtype: list[Agent] """return_flatten_list([self.graph.nodes[node][AGENT_NODE_KEY].agentsfornodeinself.graph.nodes])
[docs]definject(self):# 2nd pass, build the neighborhoods and add it to agentsfornodeinself.graph.nodes:agent_node=self.graph.nodes[node][AGENT_NODE_KEY]state_to_neighbors:dict[State,list[AgentAddress]]=dict()forneighborinself.graph.neighbors(node):state=self.graph.edges[node,neighbor][STATE_EDGE_KEY]neighbor_addresses=state_to_neighbors.setdefault(state,[])neighbor_addresses.extend([lambda:agent.addrforagentinself.graph.nodes[neighbor][AGENT_NODE_KEY].agents])foragentinagent_node.agents:topology_service=agent.service_of_type(TopologyService,TopologyService())topology_service.state_to_neighbors=state_to_neighbors
[docs]defcomplete_topology(number_of_nodes:int)->Topology:""" Create a fully-connected topology. """graph=nx.complete_graph(number_of_nodes)returnTopology(graph)
[docs]defcustom_topology(graph:nx.Graph)->Topology:""" Create an already created custom topology base on a nx Graph. """returnTopology(graph)
[docs]@contextmanagerdefcreate_topology(directed:bool=False):"""Create a topology, which will automatically inject the neighbors to the participating agents. Example: .. code-block:: python agents = [TopAgent(), TopAgent(), TopAgent()] with create_topology() as topology: id_1 = topology.add_node(agents[0]) id_2 = topology.add_node(agents[1]) id_3 = topology.add_node(agents[2]) topology.add_edge(id_1, id_2) topology.add_edge(id_1, id_3) :param directed: _description_, defaults to False :type directed: bool, optional :yield: _description_ :rtype: _type_ """topology=Topology(nx.DiGraph()ifdirectedelsenx.Graph())try:yieldtopologyfinally:topology.inject()
[docs]defper_node(topology:Topology):"""Assign agents per node of the already created topology. This method shall be used as iterator in a for in construct. The iterator will return nodes, which can be used to add (with node.add()) agents to the node. .. code-block:: python topology = complete_topology(3) for node in per_node(topology): node.add(TopAgent()) :param topology: the topology :type topology: Topology :yield: AgentNode :rtype: _type_ """fornodeintopology.graph.nodes:agent_node=topology.graph.nodes[node][AGENT_NODE_KEY]yieldagent_nodetopology.inject()