예제 #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)
예제 #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 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)
예제 #4
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
예제 #5
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
예제 #7
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
예제 #9
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
예제 #10
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
예제 #11
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)
    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
예제 #13
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