def connect_matching_pair_edges(self, Gu: nx.MultiGraph, ls, rs, obj_node_id='obj', connect_obj_rel_edges=False) -> nx.Graph: """ Ground truth (_gt_)generator function for a combined graph. Used for training S_0 :param Gu: A (unconnected) composed graph of Gs, Gt. No relational links between head nodes, thus, the number_connected_components(Gs|Gt) = number of object nodes in each graph. :param Gs: The source Graph, i.e., the text graph representation :param Gt: The target Graph, i.e., the grounding (image features) graph representation :param obj_node_id: the identifier determining a obj (or head) node :return: matching_pairs: List of matching pair tuples between Gs, Gt """ matching_pairs, unmatched_pairs = self.get_matching_pairs_in_bipartite_graph(Gu, ls, rs, obj_node_id) NDV = Gu.nodes(data=True) # Connect the matching pairs if not connected # for pair in matching_pairs: s_node, t_node = pair if not Gu.has_edge(s_node, t_node): Gu.add_edge(s_node, t_node, '<gt>') # Connect Attr Nodes # is_head_node = lambda x: obj_node_id in x Ns = nx.neighbors(Gu, s_node) Nt = list(nx.neighbors(Gu, t_node)) for ns in Ns: if is_head_node(ns): continue # Check label equality only, 'val' equality already verified ns_label = NDV[ns]['label'] #logger.debug(f'Source attr node label = {ns_label}') # TODO: potential issue here, Nt should always have a matching attr node for nt in filter(lambda x: NDV[x]['label'] == ns_label, Nt): if not Gu.has_edge(ns, nt): Gu.add_edge(ns, nt, key='<gt>') if connect_obj_rel_edges: # TODO: Add a obj relation edge among all Gs, Gt obj nodes. Actually # should be done earlier in the parse cycle. pass return Gu
def add_weak_gene(gene: EdgeGene, graph: nx.MultiGraph) -> bool: key = gene.A1 + gene.A2 edge = (gene.P1, gene.P2, key) if any(starmap( lambda p, a: p in graph and not any(x == a for x in get_node_space(graph, p)), [(gene.P1, gene.A1), (gene.P2, gene.A2)])): return False if graph.has_edge(gene.P1, gene.P2): keys = graph[gene.P1][gene.P2] if len(keys) > 1: return False graph.remove_edge(gene.P1, gene.P2, next(iter(keys))) graph.add_edge(*edge, gene=gene) return True
def add_strong_gene(gene: EdgeGene, graph: nx.MultiGraph, coupling_threshold: float) -> bool: key = gene.A1 + gene.A2 edge = (gene.P1, gene.P2, key) if not graph.has_edge(gene.P1, gene.P2): graph.add_edge(*edge, gene=gene) return True keys = graph[gene.P1][gene.P2] if key in keys: return False if len(keys) > 1: graph.add_edge(*edge, gene=gene) return True if graph[gene.P1][gene.P2][next(iter(keys))]['gene'].C < coupling_threshold: graph.remove_edge(gene.P1, gene.P2, next(iter(keys))) graph.add_edge(*edge, gene=gene) return True
def is_independent_set(g: MultiGraph, f: set) -> bool: for edge in itertools.combinations(f, 2): if g.has_edge(edge[0], edge[1]): return False return True