예제 #1
0
def rem(g: nx.MultiGraph) -> None:
    node_attributes = nx.get_node_attributes(G, 'elderly')
    nodes = list(g.nodes)
    for node in nodes:
        neigh = list(g.neighbors(node))

        if len(neigh) == 2 and (g.degree(node) % 2) == 0:
            try:
                set1 = {
                    edge['label']
                    for edge in g.get_edge_data(node, neigh[0]).values()
                }
            except:
                print(g.get_edge_data(node, neigh[0]))
            set2 = {
                edge['label']
                for edge in g.get_edge_data(node, neigh[1]).values()
            }
            if set1 == set2:
                #prec=node_attributes[neigh[0]]+0.001
                succ = node_attributes[neigh[1]] + 0.001
                node_attr = node_attributes[node] + 0.001
                # if (abs((node_attr-prec))<1000) and (abs((node_attr-succ))<1000):
                if (abs((node_attr - succ)) < 1000):
                    g.remove_node(node)
                    for edge_label in set1:
                        g.add_edge(neigh[0], neigh[1], label=edge_label)
    def get_channels(self, graph: nx.MultiGraph) -> List[Dict]:
        """
        This function gets the graph as and return the channels the agent wants to create.

        :param graph: The graph where the agent operates in.
        :return: A list containing the channels the agent wishes to create.
                 Each channel is a dictionary containing the relevant attributes.
        """
        channels = list()

        funds = self.initial_funds

        # get more nodes to surround than possible with the given funds and costs: try to fully utilize initial funds
        # Also some nodes may not have self.n_channels_per_node neighbors
        number_of_nodes_to_surround = funds // (
            self.n_channels_per_node * (self.channel_cost + self.new_channel_balance)) + 5
        assert number_of_nodes_to_surround > 0, "Consider subtracting self.n_channels_per_node or the channel cost "
        nodes_to_surround = find_best_k_nodes(graph, k=number_of_nodes_to_surround,
                                              agent_public_key=self.pub_key, alpha=self.alpha, visualize=False,
                                              use_node_degree=self.use_node_degree,
                                              use_node_routeness=self.use_node_routeness,
                                              use_node_distance=self.use_nodes_distance, minimize=self.minimize)

        nodes_in_already_chosen_edges = set()

        for node in nodes_to_surround:
            agent_policy = get_agent_policy(graph, node, True, self.fee)
            if self.use_node_routeness:
                nodes_to_connect_with = nodes_to_surround
            else:
                node_neighbors = [n for n in graph.neighbors(node) if n not in nodes_in_already_chosen_edges]
                if len(node_neighbors) > self.n_channels_per_node:
                    nodes_to_connect_with = random.sample(node_neighbors, k=self.n_channels_per_node)
                else:
                    nodes_to_connect_with = node_neighbors

            for node_to_connect in nodes_to_connect_with:
                if funds < self.channel_cost:
                    return channels
                channel_balance = min(self.new_channel_balance, funds - self.channel_cost)  # Allows using all the funds

                funds -= channel_balance + self.channel_cost

                channel_details = {'node1_pub': self.pub_key,
                                   'node2_pub': node_to_connect,
                                   'node1_policy': agent_policy,
                                   'node1_balance': channel_balance}

                channels.append(channel_details)

            nodes_in_already_chosen_edges = nodes_in_already_chosen_edges.union(nodes_to_connect_with)

        return channels
    def generalized_degree(self, g: MultiGraph, f: set, active_node, node) -> (int, set):
        assert g.has_node(node), "Calculating gd for node which is not in g!"

        k = set(g.neighbors(node))
        k.remove(active_node)
        k = k.intersection(f)

        gx = self.compress(g, k, node)

        neighbors = list(gx.neighbors(node))
        neighbors.remove(active_node)

        return len(neighbors), neighbors
예제 #4
0
def generalized_degree(g: MultiGraph, f: set, active_node, node) -> (int, set):
	assert g.has_node(node), "Calculating gd for node which is not in g!"

	k = set(g.neighbors(node))
	k.remove(active_node)
	k = k.intersection(f)

	gx = compress(g, k, node)

	neighbors = gx.neighbors(node)
	neighbors.remove(active_node)

	return (len(neighbors), neighbors)
예제 #5
0
def reduction3(g: MultiGraph, w: set, h: MultiGraph, k: int) -> (int, int, bool):
	for v in h.nodes():
		if g.degree(v) == 2:
			# If v has a neighbour in H, short-curcuit it.
			if len(h[v]) >= 1:
				# Delete v and make its neighbors adjacent.
				[n1, n2] = g.neighbors(v)
				g.remove_node(v)
				g.add_edge(n1, n2)
				# Update H accordingly.
				h.remove_nodes_from([v])
				if n1 not in w and n2 not in w:
					h.add_edge(n1, n2)
				return (k, None, True)
	return (k, None, False)
 def reduction3(self, g: MultiGraph, w: set, h: MultiGraph, k: int) -> (int, int, bool):
     """
     If there is a node v ∈ V(H) of degree 2 in G such
     that at least one neighbor of v in G is from V (H), then delete this node
     and make its neighbors adjacent (even if they were adjacent before; the graph
     could become a multigraph now).
     """
     for v in h.nodes():
         if g.degree(v) == 2:
             # If v has a neighbour in H, short-curcuit it.
             if len(h[v]) >= 1:
                 # Delete v and make its neighbors adjacent.
                 [n1, n2] = g.neighbors(v)
                 g.remove_node(v)
                 g.add_edge(n1, n2)
                 # Update H accordingly.
                 h.remove_nodes_from([v])
                 if n1 not in w and n2 not in w:
                     h.add_edge(n1, n2)
                 return k, None, True
     return k, None, False
예제 #7
0
    def reduction4(self, g: MultiGraph, k: int) -> (int, List[int], bool):
        """
         If there is a vertex v of degree 2, delete v and connect its two neighbors by a new edge.
        """
        for v in g.nodes():
            if g.degree(v) == 2:
                # Delete v and make its neighbors adjacent.
                ne = g.neighbors(v)

                # We must check whether v has 2 neighbors, or just one but connected to v by multiple edges
                if len(ne) == 2:
                    [n1, n2] = ne
                else:
                    [n1] = ne
                    n2 = n1
                g.remove_node(v)

                # Only add the edge if there are currently less than 2 edges between these two nodes
                es = g[n1].get(n2, {})
                if len(es) < 2:
                    g.add_edge(n1, n2)
                return k, None, True
        return k, None, False
예제 #8
0
    def reduction4(self, g: MultiGraph, k: int) -> (int, List[int], bool):
        """
         If there is a vertex v of degree 2, delete v and connect its two neighbors by a new edge.
        """
        for v in g.nodes():
            if g.degree(v) == 2:
                # Delete v and make its neighbors adjacent.
                ne = g.neighbors(v)

                # We must check whether v has 2 neighbors, or just one but connected to v by multiple edges
                if len(ne) == 2:
                    [n1, n2] = ne
                else:
                    [n1] = ne
                    n2 = n1
                g.remove_node(v)

                # Only add the edge if there are currently less than 2 edges between these two nodes
                es = g[n1].get(n2, {})
                if len(es) < 2:
                    g.add_edge(n1, n2)
                return k, None, True
        return k, None, False
예제 #9
0
def get_all_related_people(g: nx.MultiGraph, person):
    return g.neighbors(person)
    def mif_main(self, g: MultiGraph, f: set, t) -> set:
        if f == g.nodes():
            return f
        if not f:
            g_degree = g.degree()
            g_max_degree_node = max(g_degree, key=lambda n: n[1])[0]
            if g_degree[g_max_degree_node] <= 1:
                return set(g.nodes())
            else:
                fx = f.copy()
                fx.add(g_max_degree_node)
                gx = g.copy()
                gx.remove_node(g_max_degree_node)
                mif_set1 = self.preprocess_1(g, fx, t)
                mif_set2 = self.preprocess_1(gx, f, t)
                if not mif_set1:
                    return mif_set2
                elif not mif_set2:
                    return mif_set1
                else:
                    return max(mif_set1, mif_set2, key=len)

        # Set t as active vertex
        if t is None or t not in f:
            t = next(iter(f))

        gd_over_3 = None
        gd_2 = None
        for v in g.neighbors(t):
            (gd_v, gn_v) = self.generalized_degree(g, f, t, v)
            if gd_v <= 1:
                f.add(v)
                return self.preprocess_1(g, f, t)
            elif gd_v >= 3:
                gd_over_3 = v
            else:
                gd_2 = (v, gn_v)
        if gd_over_3 is not None:
            # Cannot simply use "if gd_over_3" because v might be 0
            fx = f.copy()
            fx.add(gd_over_3)
            gx = g.copy()
            gx.remove_node(gd_over_3)
            mif_set1 = self.preprocess_1(g, fx, t)
            mif_set2 = self.preprocess_1(gx, f, t)
            if not mif_set1:
                return mif_set2
            elif not mif_set2:
                return mif_set1
            else:
                return max(mif_set1, mif_set2, key=len)
        elif gd_2 is not None:
            (v, gn) = gd_2
            fx1 = f.copy()
            fx2 = f.copy()
            fx1.add(v)
            for n in gn:
                fx2.add(n)
            gx = g.copy()
            gx.remove_node(v)
            try:
                find_cycle(gx.subgraph(fx2))
                mif_set1 = None
            except:
                mif_set1 = self.preprocess_1(gx, fx2, t)
            mif_set2 = self.preprocess_1(g, fx1, t)
            if not mif_set1:
                return mif_set2
            elif not mif_set2:
                return mif_set1
            else:
                return max(mif_set1, mif_set2, key=len)
        return None