def get_fbvs_max_size(self, g: MultiGraph, k: int) -> set:
        if len(g) <= k + 2:
            return set(g.nodes()[:k])

        # Construct a trivial FVS of size k + 1 on the first k + 3 vertices of G.
        nodes = g.nodes()

        # The set of nodes currently under consideration.
        node_set = set(nodes[:(k + 2)])

        # The current best solution, of size (k + 1) before each compression step,
        # and size <= k at the end.
        soln = set(nodes[:k])

        for i in range(k + 2, len(nodes)):
            soln.add(nodes[i])
            node_set.add(nodes[i])

            if len(soln) < k + 1:
                continue

            assert (len(soln) == (k + 1))
            assert (len(node_set) == (i + 1))

            new_soln = self.ic_compression(g.subgraph(node_set), soln, k)

            if new_soln is None:
                return None

            soln = new_soln
            assert (len(soln) <= k)

        return soln
예제 #2
0
def simplify(streckennetz: nx.MultiGraph) -> nx.MultiGraph:
    print('simplifying...')

    # Remove the shorter edge of two parallel edges
    edges_to_remove = []
    for edges_index in streckennetz.edges():
        edges = streckennetz[edges_index[0]][edges_index[1]]
        if len(edges) > 1:
            min_length = edges[0]['length']
            min_length_index = 0
            for i in edges:
                if edges[i]['length'] < min_length:
                    min_length = edges[i]['length']
                    min_length_index = i
            edges_to_remove.append(list(edges_index) + [min_length_index])
    print('found', len(edges_to_remove), 'parallel edges')
    streckennetz.remove_edges_from(edges_to_remove)

    # Remove nodes, that only have a single edge
    while True:
        nodes_to_remove = []
        for node in streckennetz.nodes():
            if streckennetz.degree(
                    node) < 2 and 'type' not in streckennetz.nodes[node]:
                nodes_to_remove.append(node)
        if nodes_to_remove:
            print('found', len(nodes_to_remove), 'deadend nodes')
            streckennetz.remove_nodes_from(nodes_to_remove)
            nodes_to_remove = []
        else:
            break
    return streckennetz
예제 #3
0
def get_graph_extents(
        networkX_multigraph: nx.MultiGraph
) -> Tuple[float, float, float, float]:
    """
    Parameters
    ----------
    networkX_multigraph
        A `NetworkX` `MultiGraph` with `x` and `y` node parameters.

    Returns
    -------
    Tuple
        A tuple of `min_x`, `min_y`, `max_x`, `max_y` values.
    """
    # get min and maxes for x and y
    min_x = np.inf
    max_x = -np.inf
    min_y = np.inf
    max_y = -np.inf

    for n, d in networkX_multigraph.nodes(data=True):
        if d['x'] < min_x:
            min_x = d['x']
        if d['x'] > max_x:
            max_x = d['x']
        if d['y'] < min_y:
            min_y = d['y']
        if d['y'] > max_y:
            max_y = d['y']

    return min_x, min_y, max_x, max_y
예제 #4
0
def reduction2(g: MultiGraph, w: set, h: MultiGraph, k: int) -> (int, int, bool):
	for v in h.nodes():
		# Check if G[W ∪ {v}] contains a cycle.
		if not is_forest(g.subgraph(w.union({v}))):
			g.remove_node(v)
			h.remove_nodes_from([v])
			return (k - 1, v, True)
	return (k, None, False)
예제 #5
0
def reduction1(g: MultiGraph, w: set, h: MultiGraph, k: int) -> (int, int, bool):
	changed = False
	for v in g.nodes():
		if g.degree(v) <= 1:
			g.remove_node(v)
			h.remove_nodes_from([v])
			changed = True
	return (k, None, changed)
예제 #6
0
def test_relabel_nodes_multigraph():
    """failed after switching to dg.relabel_nodes"""
    G = MultiGraph([('a', 'b'), ('a', 'b')])
    mapping = {'a': 'aardvark', 'b': 'bear'}
    G = relabel_nodes(G, mapping, copy=False)
    assert sorted(G.nodes()) == ['aardvark', 'bear']
    assert_edges_equal(sorted(G.edges()), [('aardvark', 'bear'),
                                           ('aardvark', 'bear')])
예제 #7
0
def graph_minus(g: MultiGraph, w: set) -> MultiGraph:
	gx = MultiGraph()
	for (n1, n2) in g.edges():
		if n1 not in w and n2 not in w:
			gx.add_edge(n1, n2)
	for n in g.nodes():
		if n not in w:
			gx.add_node(n)
	return gx
예제 #8
0
 def reduction3(self, g: MultiGraph, k: int) -> (int, List[int], bool):
     """
     If there is a vertex v of degree at most 1, delete v.
     """
     changed = False
     for v in g.nodes():
         if g.degree(v) <= 1:
             g.remove_node(v)
             changed = True
     return k, None, changed
예제 #9
0
 def reduction3(self, g: MultiGraph, k: int) -> (int, List[int], bool):
     """
     If there is a vertex v of degree at most 1, delete v.
     """
     changed = False
     for v in g.nodes():
         if g.degree(v) <= 1:
             g.remove_node(v)
             changed = True
     return k, None, changed
 def reduction1(self, g: MultiGraph, w: set, h: MultiGraph, k: int) -> (int, int, bool):
     """
     Delete all nodes of degree 0 or 1 as they can't be part of any cycles.
     """
     changed = False
     for v in g.nodes():
         if g.degree(v) <= 1:
             g.remove_node(v)
             h.remove_nodes_from([v])
             changed = True
     return k, None, changed
예제 #11
0
    def get_node_feature_matrix(self, G:nx.MultiGraph, doc, embd_dim=96,
                                embedding_type=None, as_torch=True, is_padding_pos=True, **kwargs):
        """
        Returns X with shape [num_nodes, node_feat_dim]
        """
        assert G is not None
        NDV = G.nodes(data=True); NV = G.nodes(data=False)
        _is_head_node = lambda x: 'obj' in x
        head_nodes = list(filter(_is_head_node, NV))
        objs = self.clevr_parser.filter_clevr_objs(doc.ents)
        N, M = len(NDV), (embd_dim+3) if is_padding_pos else embd_dim
        feat_mats = []
        for i, entity in enumerate(objs):
            if entity.label_ not in ('CLEVR_OBJS', 'CLEVR_OBJ'):
                continue
            ent_mat = self.clevr_parser.get_clevr_entity_matrix_embedding(entity, dim=embd_dim,
                                                                          include_obj_node_emd=True,
                                                                          is_padding_pos=is_padding_pos)
            ent_mat = ent_mat.reshape((-1, embd_dim))
            if is_padding_pos:
                head_node = G.nodes.get(head_nodes[i])
                pos = head_node.get('pos')  # pos = (x,y,z): Tuple[float]
                if not pos:
                    pos = (0.0, 0.0, 0.0)
                pos = np.tile(np.asarray(pos, dtype=float), ent_mat.shape[0]).reshape(-1, 3)
                # np.pad(ent_mat, ((0,0), (0, 3)), 'constant', constant_values=(0, 0.0) )
                ent_mat = np.concatenate((ent_mat, pos), axis=1)        # [n, embd_dim+3]
            feat_mats.append(ent_mat)
        if len(feat_mats) > 1:
            feat_mats = reduce(lambda a, b: np.vstack((a, b)), feat_mats)
        else:
            feat_mats = feat_mats[0]

        assert feat_mats.shape == (N, M)
        if as_torch:
            feat_mats = torch.from_numpy(feat_mats).float()
            if kwargs.get('is_cuda'):
                device = 'cuda' if torch.cuda.is_available() else 'cpu'
                feat_mats = feat_mats.to(device)

        return feat_mats
예제 #12
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)
예제 #13
0
def subgraph_by_timestamp(mg: nx.MultiGraph, start: int, end: int) -> nx.Graph:
    edges = filter(
        lambda edge: start <= edge[2]["timestamp"] and edge[2]["timestamp"] <
        end,
        mg.edges(data=True),
    )
    g = nx.Graph()
    for node in mg.nodes():
        g.add_node(node)
    for u, v, data in edges:
        if g.has_edge(u, v):
            g[u][v]["weight"] += data["weight"]
        else:
            g.add_edge(u, v, weight=data["weight"])
    return g
    def reduction2(self, g: MultiGraph, w: set, h: MultiGraph, k: int) -> (int, int, bool):
        """
        If there exists a node v in H such that G[W ∪ {v}]
        contains a cycle, then include v in the solution, delete v and decrease the
        parameter by 1. That is, the new instance is (G - {v}, W, k - 1).

        If v introduces a cycle, it must be part of X as none of the vertices in W
        will be available to neutralise this cycle.
        """
        for v in h.nodes():
            # Check if G[W ∪ {v}] contains a cycle.
            if not is_acyclic(g.subgraph(w.union({v}))):
                g.remove_node(v)
                h.remove_nodes_from([v])
                return k - 1, v, True
        return k, None, False
예제 #15
0
    def update_graph_with_spatial_re(cls, G: nx.MultiGraph, doc,
                                     **kwargs) -> nx.MultiGraph:
        spatial_res = cls.filter_spatial_re(doc.ents)
        if spatial_res is None:
            return G
        NV = G.nodes(data=False)
        _is_head_node = lambda x: 'obj' in x
        head_nodes = list(filter(_is_head_node, NV))
        objs = cls.filter_clevr_objs(doc.ents)
        relations = cls.extract_spatial_relations(doc)
        assert len(objs) == len(head_nodes)
        assert len(relations) == len(spatial_res)
        o2n_map = dict(zip(objs, head_nodes))
        sr2r_map = dict(zip(spatial_res, relations))

        def add_nodes(n0, n1, r):
            if not G.has_edge(*(n0, n1, 'spatial_re')):
                #G.add_edge(n0, n1, **{'label':'spatial_re', 'val': r})
                G.add_edge(n0, n1, spatial_re=r)
                # G.add_edge(n0, n1,key=r)

        has_and = 'and' in doc.text
        # has_or = 'or' in doc.text
        # is_logical_re = has_and or has_or
        for i, ent in enumerate(doc.ents):
            if ent in objs:
                continue
            if ent in spatial_res:
                _r = sr2r_map[ent]
                try:
                    if i > 1:
                        if has_and:
                            n1 = o2n_map[doc.ents[i + 1]]
                            n0 = o2n_map[doc.ents[0]]
                        else:
                            n0 = o2n_map[doc.ents[i - 1]]
                            n1 = o2n_map[doc.ents[i + 1]]
                    else:
                        n0 = o2n_map[doc.ents[i - 1]]
                        n1 = o2n_map[doc.ents[i + 1]]
                    add_nodes(n0, n1, _r)
                except IndexError as ie:
                    print(ie)
                except UnboundLocalError as lr:
                    print(lr)

        return G
예제 #16
0
    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 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
예제 #18
0
def build_node(g: nx.MultiGraph, new_node: int, n: int, const_amt: int, fee_type: str) -> List:

    selected = []

    # 2 initial edges so routes can pass through new node
    while len(selected) < n:
        max_reward = 0
        best_channel = None

        # try all channels
        for node in g.nodes():
            if node == new_node or node in g[new_node]:
                continue

            # create new channel
            g.add_edge_with_init(new_node, node, default=True)
            # calculate max reward
            reward, fee = maximise_fee(
                g, (new_node, node), const_amt, fee_type)

            # select channel if highest reward
            if max_reward <= reward:
                max_reward = reward
                best_channel = (node, fee)

            # reset graph for next channel
            g.remove_edge(new_node, node)

        if best_channel is None:
            raise Exception('Profit not possible.')

        # add selected channel and redo for next channel
        selected.append((new_node, best_channel[0], best_channel[1]))

        g.add_edge_with_init(new_node, best_channel[0], default=True)
        g.update_fee(new_node, best_channel[0], best_channel[1], fee_type)

    # return node with selected channels
    return selected
예제 #19
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
    def preprocess_2(self, g: MultiGraph, f: set, active_v) -> set:
        mif_set = set()
        while not is_independent_set(g, f):
            mif_set = mif_set.union(f)
            for component in connected_components(g.subgraph(f)):
                if len(component) > 1:
                    if active_v in component:
                        active_v = component.pop()
                        compressed_node = active_v
                    else:
                        compressed_node = component.pop()
                    g = self.compress(g, component, compressed_node, False)
                    f = f.intersection(g.nodes())
                    # Maybe faster with
                    # f = f.difference(component)
                    # f.add(compressed_node)
                    mif_set = mif_set.union(component)
                    break
        mif_set2 = self.mif_main(g, f, active_v)
        if mif_set2:
            mif_set = mif_set2.union(mif_set)

        return mif_set
예제 #21
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
예제 #22
0
def mif_preprocess_2(g: MultiGraph, f: set, active_v, k: int) -> set:
	mif_set = set()
	while not is_independent_set(g, f):
		mif_set = mif_set.union(f)
		for component in nxc.connected_components(g.subgraph(f)):
			if len(component) > 1:
				if active_v in component:
					active_v = component.pop()
					compressed_node = active_v
				else:
					compressed_node = component.pop()
				g = compress(g, component, compressed_node, True)
				f = f.intersection(g.nodes())
				# Maybe faster with
				# f = f.difference(component)
				# f.add(compressed_node)
				mif_set = mif_set.union(component)
				break
	mif_set2 = mif_main(g, f, active_v, k)
	if mif_set2:
		mif_set = mif_set2.union(mif_set)
	if k == None or len(mif_set) >= k:
		return mif_set
	return None
예제 #23
0
class ShuttlingGraph(list):
    def __init__(self, shuttlingEdges=list() ):
        super(ShuttlingGraph, self).__init__(shuttlingEdges) 
        self.currentPosition = None
        self.currentPositionName = None
        self.nodeLookup = dict()
        self.currentPositionObservable = Observable()
        self.graphChangedObservable = Observable()
        self.initGraph()
        self._hasChanged = True
        
    def initGraph(self):
        self.shuttlingGraph = MultiGraph()
        for edge in self:
            self.shuttlingGraph.add_node(edge.startName)
            self.shuttlingGraph.add_node(edge.stopName)
            self.shuttlingGraph.add_edge(edge.startName, edge.stopName, key=hash(edge), edge=edge,
                                         weight=abs(edge.stopLine-edge.startLine))
            self.nodeLookup[edge.startLine] = edge.startName
            self.nodeLookup[edge.stopLine] = edge.stopName

    def rgenerateNodeLookup(self):
        self.nodeLookup.clear()
        for edge in self:
            self.nodeLookup[edge.startLine] = edge.startName
            self.nodeLookup[edge.stopLine] = edge.stopName

    @property
    def hasChanged(self):
        return self._hasChanged
    
    @hasChanged.setter
    def hasChanged(self, value):
        self._hasChanged = value
            
    def position(self, line):
        return self.nodeLookup.get(line)
    
    def setPosition(self, line):
        if self.currentPosition!=line:
            self.currentPosition = line
            self.currentPositionName = self.position(line)
            self.currentPositionObservable.fire( line=line, text=firstNotNone(self.currentPositionName, "") )

    def getMatchingPosition(self,graph):
        """Try to match node name/position to the current settings in the provided ShuttlingGraph."""
        if not graph:
            return self.currentPosition # no change
        # Matching node name. Need to set the corresponding position
        for edge in self:
            if edge.startName == graph.currentPositionName:
                return edge.startLine
            if edge.stopName == graph.currentPositionName:
                return edge.stopLine
        #if graph.currentPosition:
        #    return graph.currentPosition #just use the graph's position
        return self.currentPosition

    def addEdge(self, edge):
        self._hasChanged = True
        self.append(edge)
        self.shuttlingGraph.add_edge(edge.startName, edge.stopName, key=hash(edge), edge=edge, weight=abs(edge.stopLine-edge.startLine))
        self.nodeLookup[edge.startLine] = edge.startName
        self.nodeLookup[edge.stopLine] = edge.stopName
        self.graphChangedObservable.firebare()
        self.setPosition(self.currentPosition)
            
    def isValidEdge(self, edge):
        return ((edge.startLine not in self.nodeLookup or self.nodeLookup[edge.startLine] == edge.startName)
                and (edge.stopLine not in self.nodeLookup or self.nodeLookup[edge.stopLine] == edge.stopName))
        
    def getValidEdge(self):
        index = 0
        while self.shuttlingGraph.has_node("Start_{0}".format(index)):
            index += 1
        startName = "Start_{0}".format(index)
        index = 0
        while self.shuttlingGraph.has_node("Stop_{0}".format(index)):
            index += 1
        stopName = "Stop_{0}".format(index)
        index = 0
        startLine = (max( self.nodeLookup.keys() )+1) if self.nodeLookup else 1
        stopLine = startLine + 1
        return ShuttleEdge(startName, stopName, startLine, stopLine, 0, 0, 0, 0)
    
    def removeEdge(self, edgeno):
        self._hasChanged = True
        edge = self.pop(edgeno)
        self.shuttlingGraph.remove_edge(edge.startName, edge.stopName, hash(edge))
        if self.shuttlingGraph.degree(edge.startName) == 0:
            self.shuttlingGraph.remove_node(edge.startName)
        if self.shuttlingGraph.degree(edge.stopName) == 0:
            self.shuttlingGraph.remove_node(edge.stopName)
        self.graphChangedObservable.firebare()
        self.rgenerateNodeLookup()
        self.setPosition(self.currentPosition)
    
    def setStartName(self, edgeno, startName):
        self._hasChanged = True
        startName = str(startName)
        edge = self[edgeno]
        if edge.startName != startName:
            self.shuttlingGraph.remove_edge(edge.startName, edge.stopName, key=hash(edge))
            if self.shuttlingGraph.degree(edge.startName) == 0:
                self.shuttlingGraph.remove_node(edge.startName)
            edge.startName = startName
            self.shuttlingGraph.add_edge(edge.startName, edge.stopName, key=hash(edge), edge=edge,
                                         weight=abs(edge.stopLine-edge.startLine) )
            self.graphChangedObservable.firebare()
            self.setPosition(self.currentPosition)
            self.rgenerateNodeLookup()
        return True
    
    def setStopName(self, edgeno, stopName):
        self._hasChanged = True
        stopName = str(stopName)
        edge = self[edgeno]
        if edge.stopName != stopName:
            self.shuttlingGraph.remove_edge(edge.startName, edge.stopName, key=hash(edge))
            if self.shuttlingGraph.degree(edge.stopName) == 0:
                self.shuttlingGraph.remove_node(edge.stopName)
            edge.stopName = stopName
            self.shuttlingGraph.add_edge(edge.startName, edge.stopName, key=hash(edge), edge=edge,
                                         weight=abs(edge.stopLine-edge.startLine) )
            self.graphChangedObservable.firebare()
            self.rgenerateNodeLookup()
            self.setPosition(self.currentPosition)
        return True
    
    def setStartLine(self, edgeno, startLine):
        self._hasChanged = True
        edge = self[edgeno]
        if startLine != edge.startLine and (startLine not in self.nodeLookup or self.nodeLookup[startLine] == edge.startName):
            self.nodeLookup.pop(edge.startLine)
            edge.startLine = startLine
            self.shuttlingGraph.edge[edge.startName][edge.stopName][hash(edge)]['weight'] = abs(edge.stopLine-edge.startLine)
            self.rgenerateNodeLookup()
            self.graphChangedObservable.firebare()
            self.setPosition(self.currentPosition)
            return True    
        return False  
    
    def setStopLine(self, edgeno, stopLine):
        self._hasChanged = True
        edge = self[edgeno]
        if stopLine != edge.stopLine and (stopLine not in self.nodeLookup or self.nodeLookup[stopLine] == edge.stopName):
            self.nodeLookup.pop(edge.stopLine)
            edge.stopLine = stopLine
            self.shuttlingGraph.edge[edge.startName][edge.stopName][hash(edge)]['weight'] = abs(edge.stopLine-edge.startLine)
            self.rgenerateNodeLookup()
            self.graphChangedObservable.firebare()
            self.setPosition(self.currentPosition)
            return True  
        return False
    
    def setIdleCount(self, edgeno, idleCount):
        self._hasChanged = True
        self[edgeno].idleCount = idleCount
        return True      

    def setSteps(self, edgeno, steps):
        self._hasChanged = True
        self[edgeno].steps = steps
        return True      
    
    def shuttlePath(self, fromName, toName ):
        fromName = firstNotNone(fromName, self.currentPositionName)
        fromName = fromName if fromName else self.position(float(self.currentPosition))
        if fromName not in self.shuttlingGraph:
            raise ShuttlingGraphException("Shuttling failed, origin '{0}' is not a valid shuttling node".format(fromName))
        if toName not in self.shuttlingGraph:
            raise ShuttlingGraphException("Shuttling failed, target '{0}' is not a valid shuttling node".format(toName))
        sp = shortest_path(self.shuttlingGraph, fromName, toName)
        path = list()
        for a, b in pairs_iter(sp):
            edge = sorted(self.shuttlingGraph.edge[a][b].values(), key=itemgetter('weight'))[0]['edge']
            path.append((a, b, edge, self.index(edge)))
        return path
    
    def nodes(self):
        return self.shuttlingGraph.nodes()
    
    def toXmlElement(self, root):
        mydict = dict( ( (key, str(getattr(self, key))) for key in ('currentPosition', 'currentPositionName') if getattr(self, key) is not None  ) ) 
        myElement = ElementTree.SubElement(root, "ShuttlingGraph", attrib=mydict )
        for edge in self:
            edge.toXmlElement( myElement )
        return myElement
    
    def setStartType(self, edgeno, Type):
        self._hasChanged = True
        self[edgeno].startType = str(Type)
        return True
    
    def setStopType(self, edgeno, Type):
        self._hasChanged = True
        self[edgeno].stopType = str(Type)
        return True
    
    def setStartLength(self, edgeno, length):
        edge = self[edgeno]
        if length!=edge.startLength:
            if length+edge.stopLength<edge.sampleCount:
                self._hasChanged = True
                edge.startLength = int(length)
            else:
                return False
        return True
    
    def setStopLength(self, edgeno, length):
        edge = self[edgeno]
        if length!=edge.stopLength:
            if edge.startLength+length<edge.sampleCount:
                self._hasChanged = True
                edge.stopLength = int(length)
            else:
                return False
        return True
    
    @staticmethod
    def fromXmlElement( element ):
        edgeElementList = element.findall("ShuttleEdge")
        edgeList = [ ShuttleEdge.fromXmlElement(e) for e in edgeElementList ]
        return ShuttlingGraph(edgeList)
예제 #24
0
def mif_main(g: MultiGraph, f: set, t, k: int) -> set:
	k_set = k != None
	new_k1 = new_k2 = None
	if k_set and k > g.order():
		return None
	if f == g.nodes() or (k_set and k <= 0):
		return f
	if (not f):
		g_degree = g.degree()
		g_max_degree_node = max(g_degree, key=lambda n: g_degree[n])
		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)
			if k_set:
				new_k1 = k-1
				new_k2 = k
			mif_set1 = mif_preprocess_1(g, fx, t, new_k1)
			mif_set2 = mif_preprocess_1(gx, f, t, new_k2)
			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 == None or not t in f:
		t = next(iter(f))

	gd_over_3 = None
	gd_2 = None
	for v in g.neighbors_iter(t):
		(gd_v, gn_v) = generalized_degree(g, f, t, v)
		if gd_v <= 1:
			f.add(v)
			if k_set:
				new_k1 = k-1
			return mif_preprocess_1(g, f, t, new_k1)
		elif gd_v >= 3:
			gd_over_3 = v
		else:
			gd_2 = (v, gn_v)
	if gd_over_3 != 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)
		if k_set:
			new_k1 = k-1
			new_k2 = k
		mif_set1 = mif_preprocess_1(g, fx, t, new_k1)
		mif_set2 = mif_preprocess_1(gx, f, t, new_k2)
		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 != 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)
		if k_set:
			new_k1 = k-2
			new_k2 = k-1
		try:
			cyc.find_cycle(gx.subgraph(fx2))
			mif_set1 = None
		except:
			mif_set1 = mif_preprocess_1(gx, fx2, t, new_k1)
		mif_set2 = mif_preprocess_1(g, fx1, t, new_k2)
		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
예제 #25
0
def fvs_via_mif(g: MultiGraph, k: int) -> set:
	mif_set = mif(g, g.order()-k)
	if mif_set:
		nodes = set(g.nodes())
		mif_set = nodes.difference(mif_set)
	return mif_set
    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
예제 #27
0
    def get_matching_pairs_in_bipartite_graph(self, Gu: nx.MultiGraph, ls, rs, obj_node_id='obj') -> (
    List[Tuple], List):
        """
        Compares source and target nodes by labels and values and returns the matching pairs, or unmatched pairs
        if there are source nodes that can't be matched.
        N.b. the presence of a single unmatched Gs node suffices to deem the Gu as unmatched
        :param Gu:
        :param ls:
        :param rs:
        :param obj_node_id: identifier for the head node
        :return:
        """
        NDV = Gu.nodes(data=True)
        # Compare and connect nodes in left partition and right partition
        # N.b. there could be zero connections in case of mismatch (False Caption for e.g.)
        is_head_node = lambda x: obj_node_id in x
        Gs_head_nodes = sorted(list(filter(is_head_node, ls)))
        Gt_head_nodes = sorted(list(filter(is_head_node, rs)))
        logger.debug(f'Number of head nodes in Gs (text graph) = {len(Gs_head_nodes)}')
        logger.debug(f'Number of head nodes in Gt (image graph) = {len(Gt_head_nodes)}')
        matching_pairs = []  # Holds the (s,t) matching pairs
        unmatched_pairs = []  # Holds the (s) source nodes that did not match
        for gs_head_node in Gs_head_nodes:
            print(f'Matching source head node: {NDV[gs_head_node]}')
            gs_hn_val = NDV[gs_head_node]['val']
            gs_hn_graph, gs_hn_doc = self.clevr_parser.parse(gs_hn_val)
            gs_hn_span = gs_hn_doc.ents[0]
            matching_grounding_node = None
            # Try matching the src head node to one of the available grounding objects
            for gt_head_node in Gt_head_nodes:
                # gt = nx.subgraph(Gt, gt_head_node)
                # is_equal = __is_equal_head_nodes(gs, gt)
                gt_hn_val = NDV[gt_head_node]['val']
                if gs_hn_val == gt_hn_val:
                    matching_grounding_node = gt_head_node
                    break
                gt_hn_graph, gt_hn_doc = self.clevr_parser.parse(gt_hn_val)
                gt_hn_span = gt_hn_doc.ents[0]
                # Compare <Z>
                attr1 = gs_hn_span._.size if gs_hn_span._.has_size else None
                attr2 = gt_hn_span._.size
                if attr1 is not None and len(attr1) > 0:
                    _is_equal_attr = self.clevr_parser.entity_recognizer.is_equal_size(attr1, attr2)
                    if not _is_equal_attr:
                        continue
                # Compare <C>
                attr1 = gs_hn_span._.color if gs_hn_span._.has_color else None
                attr2 = gt_hn_span._.color
                if attr1 and (attr1.text != attr2.text):
                    # Color is stipulated for source, but doesn't match target
                    continue
                # Compare <M>
                attr1 = gs_hn_span._.material if gs_hn_span._.has_material else None
                attr2 = gt_hn_span._.material
                if attr1 is not None and len(attr1) > 0:
                    _is_equal_attr = self.clevr_parser.entity_recognizer.is_equal_material(attr1, attr2)
                    if not _is_equal_attr:
                        continue
                # Compare <S>
                attr1 = gs_hn_span._.shape if gs_hn_span._.has_shape else None
                attr2 = gt_hn_span._.shape
                if attr1 is not None and len(attr1) > 0:
                    _is_equal_attr = self.clevr_parser.entity_recognizer.is_equal_shape(attr1, attr2)
                    if not _is_equal_attr:
                        continue
                # Found Grounding Node Match
                matching_grounding_node = gt_head_node
                break

            if matching_grounding_node:
                matching_pairs.append((gs_head_node, matching_grounding_node))
            else:
                unmatched_pairs.append(gs_head_node)

        logger.info(f'\tNumber of matching pairs (gs,gt) found = {len(matching_pairs)}'
                    f'\n\tNumber of unmatched pairs (gs) found = {len(unmatched_pairs)}')
        logger.info(f'matching_pairs = {matching_pairs}')

        return matching_pairs, unmatched_pairs
예제 #28
0
    def get_embeddings(self, G: nx.MultiGraph, doc, embd_dim=96,
                       embedding_type=None, **kwargs) -> np.ndarray:
        """
        Example:
        Text: "There is a green metal block; the tiny metal thing is to the left of it"
        Gs -> ['obj', '<C>', '<M>', '<S>', 'obj2', '<Z2>', '<M2>', '<S2>']
        doc.ents -> (green metal block, tiny metal thing)

        NodeDataView({'obj': {'label': 'CLEVR_OBJ', 'val': 'green metal block'},
                        '<C>': {'label': 'color', 'val': 'green'},
                        '<M>': {'label': 'material', 'val': 'metal'},
                        '<S>': {'label': 'shape', 'val': 'block'},
                      'obj2': {'label': 'CLEVR_OBJ', 'val': 'tiny metal thing'},
                            '<Z2>': {'label': 'size', 'val': 'tiny'},
                            '<M2>': {'label': 'material', 'val': 'metal'},
                            '<S2>': {'label': 'shape', 'val': 'thing'}})

        :param G: MultiGraph containing all CLEVR nodes
        :param doc: Spacy Doc
        :param embd_dim:
        :param embedding_type:
        :return: A feature vector matrix corresponding to the value of the Graph of size (N * M) where N is the number
        of nodes in the graph and M corresopnds to the embd_sz (default = 96)
        Note: the head_node ('obj' node) will be a mean of all attrs vecs (of embd_sz)
        """
        import warnings
        warnings.warn("Deprecated: use `get_node_feature_matrix` instead",
                DeprecationWarning, stacklevel=2)
        assert G is not None
        NDV = G.nodes(data=True)
        NV = G.nodes(data=False)
        _is_head_node = lambda x: 'obj' in x
        head_nodes = list(filter(_is_head_node, NV))
        objs = self.clevr_parser.filter_clevr_objs(doc.ents)

        N = len(NDV)
        M = embd_dim
        feat_mats = []
        for i, entity in enumerate(objs):
            if entity.label_ not in ('CLEVR_OBJS', 'CLEVR_OBJ'):
                continue
            ent_mat = self.clevr_parser.get_clevr_entity_matrix_embedding(entity, dim=96, include_obj_node_emd=True)
            feat_mats.append(ent_mat)
            head_node = G.nodes.get(head_nodes[i])
            pos = head_node.get('pos')          # pos = (x,y,z): Tuple[float]

        if len(feat_mats) > 1:
            feat_mats = reduce(lambda a, b: np.vstack((a, b)), feat_mats)
        else:
            feat_mats = feat_mats[0]
        assert feat_mats.shape == (N, M)

        spatial_ents = self.clevr_parser.filter_spatial_re(doc.ents)
        for i, entity in enumerate(spatial_ents):
            ent_vec = entity.vector.reshape(1, -1)   #(1, 96)
            feat_mats = np.vstack((feat_mats, ent_vec))
        matching_ents = self.clevr_parser.filter_matching_re(doc.ents)
        for i, entity in enumerate(matching_ents):
            ent_vec = entity.vector.reshape(1, -1)  # (1, 96)
            feat_mats = np.vstack((feat_mats, ent_vec))

        return feat_mats