예제 #1
0
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
예제 #2
0
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
예제 #3
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
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)