def test_matching_with_drivers(self):
     scenarios = []
     scenarios.append([(1, 2), (2, 1), (2, 3), (4, 3), (5, 4), (5, 6),
                       (6, 5), (7, 6), (7, 7), (7, 5)])
     for scenario in scenarios:
         print scenario
         G = lightnx.DiGraph()
         G.add_edges_from(scenario)
         m = matchings.matching_with_driver(G, 3)
         assert_equals(len(m), 5)
         for el in m:
             if 3 == el[1]:
                 assert_equals(True, False)
     for scenario in scenarios:
         print scenario
         G = lightnx.DiGraph()
         G.add_edges_from(scenario)
         m = matchings.matching_with_drivers(G, [3])
         assert_equals(len(m), 5)
         for el in m:
             if 3 == el[1]:
                 assert_equals(True, False)
     for scenario in scenarios:
         print scenario
         G = lightnx.DiGraph()
         G.add_edges_from(scenario)
         m = matchings.matching_with_drivers(G, [3, 5])
         assert_equals(len(m), 4)
         for el in m:
             if 3 == el[1] or 5 == el[1]:
                 assert_equals(True, False)
 def test_is_perfect_matchable(self):
     G1 = lightnx.DiGraph()
     G1.add_edges_from([('A', 'B'), ('B', 'A')])
     G2 = lightnx.DiGraph()
     G2.add_edges_from([('A', 'B'), ('B', 'A'), ('A', 'C')])
     G3 = lightnx.DiGraph()
     G3.add_edges_from([('C', 'C')])
     assert_equal(matchings.is_perfect_matchable(G1), True)
     assert_equal(matchings.is_perfect_matchable(G2), False)
     assert_equal(matchings.is_perfect_matchable(G3), True)
 def test_is_perfect_matchable(self):
     G = lightnx.DiGraph()
     G.add_edges_from([(1, 2), (2, 1), (2, 3), (3, 2)])
     sccs = matchings.strongly_connected_components(G)
     is_p_m = matchings.is_perfect_matchable(G, sccs[0])
     assert_equal(is_p_m, False)
     G = lightnx.DiGraph()
     G.add_edges_from([(1, 2), (2, 1), (2, 3), (3, 4), (4, 3), (5, 4),
                       (5, 6), (6, 5)])
     sccs = matchings.strongly_connected_components(G)
     for scc in sccs:
         is_p_m = matchings.is_perfect_matchable(G, scc)
         assert_equal(is_p_m, True)
 def test_controllers_dilation(self):
     G = lightnx.DiGraph()
     G.add_edges_from([(1, 2), (2, 1), (2, 3), (3, 4), (4, 3), (5, 4),
                       (5, 6), (6, 5), (7, 6)])
     mm = matchings.matching(G)
     contr = matchings.controllers_dilation(mm, G.nodes())
     assert_equal(contr, set(['7']))
示例#5
0
 def test_subgraph(self):
     G=lightnx.DiGraph()
     G.add_edges_from([('A', 'B'), ('A', 'C'), ('B', 'D'),
                       ('C', 'B'), ('C', 'D')])
     SG=G.subgraph(['A','B','D'])
     assert_equal(sorted(SG.nodes()),sorted(['A', 'B', 'D']))
     assert_equal(sorted(SG.edges()),sorted([('A', 'B'), ('B', 'D')]))
示例#6
0
 def test_neighbors(self):
     G=lightnx.DiGraph()
     G.add_edges_from([('A', 'B'), ('A', 'C'), ('B', 'D'),
                       ('C', 'B'), ('C', 'D')])
     G.add_nodes('GJK')
     assert_equal(sorted(G.neighbors('A')),['B', 'C'])
     assert_equal(sorted(G.neighbors('G')),[])
 def test_matching_self_loop(self):
     G = lightnx.DiGraph()
     G.add_edges_from([(1, 1), (1, 2), (2, 2)])
     matching = matchings.matching(G)
     assert_equal(self.isMatching(matching), True)
     assert_equal(2, len(matching))
     assert_equal(sorted(matching), sorted([('2', '2'), ('1', '1')]))
示例#8
0
def create_consident_digraph(n, p):
    graph = digraph.DiGraph(n)
    graph.random_graph(p)
    while not graph.is_consident():
        graph.random_graph(p)

    return graph
 def test_non_top(self):
     G = lightnx.DiGraph()
     G.add_edges_from([(1, 2), (2, 1), (2, 3), (3, 4), (4, 3), (5, 4),
                       (5, 6), (6, 5), (7, 6)])
     sccs = matchings.strongly_connected_components(G)
     for scc in sccs:
         if matchings.is_non_top_linked(G, scc):
             assert_equal(sorted(scc) in [[1, 2], [7]], True)
 def test_matchings2(self):
     G = lightnx.DiGraph()
     G.add_edges_from([(1, 2), (2, 1), (2, 3), (3, 4), (4, 5), (5, 3),
                       (5, 6)])
     G.add_node(7)
     matching = matchings.matching(G)
     assert_equal(self.isMatching(matching), True)
     assert_equal(5, len(matching))
示例#11
0
 def test_read_from_nx(self):
     import networkx as nx
     gnx = nx.DiGraph(nx.scale_free_graph(1000))
     glnx = lightnx.DiGraph()
     glnx.add_edges_from(gnx.edges())
     assert_equals(set(glnx.edges()), set(gnx.edges()))
     assert_equals(set(glnx.successors(786)), set(gnx.successors(786)))
     assert_equals(set(glnx.successors(0)), set(gnx.successors(0)))
     assert_equals(set(glnx.predecessors(678)), set(gnx.predecessors(678)))
 def test_is_compatible(self):
     scenarios = []
     scenarios.append([[(1, 2), (2, 1), (2, 3), (3, 4), (4, 3), (5, 4),
                        (5, 6), (6, 5), (3, 7), (4, 7)], [[1, 2]], [5, 6],
                       False])
     scenarios.append([[(1, 2), (2, 1), (2, 3), (3, 4), (4, 3), (5, 4),
                        (5, 6), (6, 5), (3, 7), (4, 7), (3, 8), (4, 8)],
                       [[1, 2]], [5, 6], True])
     scenarios.append([[(1, 2), (2, 1), (2, 3), (3, 4), (4, 3), (5, 4),
                        (5, 6), (6, 5), (3, 7), (4, 7), (3, 8)], [[1, 2]],
                       [5, 6], True])
     scenarios.append([[(1, 2), (2, 1), (2, 3), (3, 4), (4, 3), (5, 4),
                        (5, 6), (6, 5), (3, 7), (4, 8)], [[1, 2]], [5, 6],
                       True])
     scenarios.append([[(1, 2), (2, 1), (2, 3), (3, 4), (4, 3), (5, 4),
                        (5, 6), (6, 5), (3, 7), (4, 8), (10, 9), (9, 10),
                        (9, 3), (9, 4)], [[9, 10]], [5, 6], True])
     scenarios.append([[(1, 2), (2, 1), (2, 3), (3, 4), (4, 3), (5, 4),
                        (5, 6), (6, 5), (3, 7), (4, 8), (10, 9), (9, 10),
                        (9, 3), (9, 4)], [[1, 2]], [9, 10], True])
     scenarios.append([[(1, 2), (2, 1), (2, 3), (3, 4), (4, 3), (5, 4),
                        (5, 6), (6, 5), (3, 7), (4, 8), (10, 9), (9, 10),
                        (9, 3), (9, 4)], [[1, 2]], [5, 6], True])
     scenarios.append([[(1, 2), (2, 1), (2, 3), (3, 4), (4, 3), (5, 4),
                        (5, 6), (6, 5), (3, 7), (4, 8), (10, 9), (9, 10),
                        (9, 3), (9, 4)], [[1, 2], [6, 5]], [10, 9], False])
     for scenario in scenarios:
         print 30 * "="
         print scenario[0]
         G = lightnx.DiGraph()
         G.add_edges_from(scenario[0])
         scc_pm_nt, Gprime = matchings.get_S_nt_rm_Gprime(G)
         msize = len(matchings.matching(Gprime))
         assign = []
         for scc in scc_pm_nt:
             if matchings.is_assignable(scc, Gprime, msize):
                 assign.append(scc)
         compatibles = []
         scc_test = None
         for scc in assign:
             if sorted(scc.graph.nodes()) in map(sorted, scenario[1]):
                 compatibles.append(scc)
             if sorted(scc.graph.nodes()) == sorted(scenario[2]):
                 scc_test = scc
         print[com.graph.nodes() for com in compatibles]
         print scc.graph.nodes()
         assert_equals(len(scenario[1]), len(compatibles))
         assert_equals(scc_test == None, False)
         compatible, compatibleSCCs = matchings.isCompatible(
             compatibles, scc_test, Gprime, msize)
         print compatible
         assert_equals(compatible, scenario[3])
         if compatible:
             outnodes = [scc.comp_node for scc in compatibleSCCs]
             assert_equals(len(outnodes), len(set(outnodes)))
             for scc in compatibleSCCs:
                 print scc.comp_node, scc.graph.nodes()
示例#13
0
 def test_self_loop(self):
     G=lightnx.DiGraph()
     G.add_edge('A','A') # test self loops
     assert_true(G.has_edge('A','A'))
     G.remove_edge('A','A')
     G.add_edge('X','X')
     assert_true(G.has_node('X'))
     G.remove_node('X')
     G.add_edge('A','Z') # should add the node silently
     assert_true(G.has_node('Z'))
 def setUp(self):
     assert not self.is_setup
     self.is_setup = True
     #self.null=nx.null_graph()
     #self.P1=cnlti(nx.path_graph(1), first_label=1)
     #self.P3=cnlti(nx.path_graph(3), first_label=1)
     #self.P10=cnlti(nx.path_graph(10), first_label=1)
     #self.K1=cnlti(nx.complete_graph(1), first_label=1)
     self.K3 = lightnx.DiGraph()
     self.K3.add_edges_from([(0, 1), (1, 2), (0, 2)])
def runOnce(files, parmsDict, nameDict):
    '''Runs through the entire shortest path procedure,from
    dijkstra to reporting the results.
    files: list of directories/file names for file retrieval
    parmsDict: csv file dictionary with directory specifications/flags
    nameDict: csv file dictionary with user specifications/flags
    
    returns: 
    graph: final graph used
    path: list of all nodes in shortest path
    ex: list of extremes in the form [startID, targetID]
    '''

    if parmsDict['VISIRbenchmark_flag'][0] == '1':
        outLFilename = files[4]
        outPFilename = files[5]
        loadGraphName = files[8]
        #fix loading graph for VISIR graphs

    if parmsDict['VISIRbenchmark_flag'][0] == '2':
        outLFilename = files[2]
        outPFilename = files[3]
        loadGraphName = files[5]
        mshName = files[0]

    outLog = open(outLFilename, 'w')
    outPath = open(outPFilename, 'w')

    if nameDict['need_previous_graph'][0] == '0':
        graph = cg.makeAGraph(files, parmsDict, nameDict)

    if nameDict['need_previous_graph'][0] == '1':
        t0 = time.time()
        graph = ed.read_edgelist(loadGraphName,
                                 create_using=d.DiGraph(),
                                 nodetype=int,
                                 edgetype=float)
        mesh = open(mshName, 'r')
        nodeID = rg.getNodes(mesh)
        mesh.close()
        cg.gmshNodeProps(graph, nodeID)
        tf = time.time() - t0
        print "time to read in and add properties to graph: " + str(tf)

    t0 = time.time()
    path, ex = findPath(files, outLog, outPath, parmsDict, nameDict, graph)
    tf = time.time() - t0

    outLog.write("TOTAL JOB COMPUTATION TIME: " + str(tf) + "\n")

    outLog.close()
    outPath.close()

    return graph, path, ex
def gmshExtraEdges(graph, nameDict):
    '''Adds extra edges to graph based on user-specified degree.
    graph: graph to add edges to
    nameDict: csv file dictionary with user specifications/flags.
    
    returns: graph with added edges
    '''
    print "# g nodes: " + str(len(graph.nodes()))
    print "# g edges: " + str(len(graph.edges()))
    gTot = d.DiGraph()
    i = 0
    nProcessed = 0
    sp = {}
    t0 = time.time()
    deg = int(nameDict['con_deg'][0])
    for node in graph.nodes():
        nhbrs = []

        for node1st in graph.neighbors(node):
            nhbrs.append(node1st)  #1st order
            if deg > 1:
                for node2nd in graph.neighbors(node1st):
                    nhbrs.append(node2nd)  #2nd order
                    if deg > 2:
                        for node3rd in graph.neighbors(node2nd):
                            nhbrs.append(node3rd)  #3rd order
                            if deg > 3:
                                for node4th in graph.neighbors(node3rd):
                                    nhbrs.append(node4th)  #4th order
                                    if deg > 4:
                                        for node5th in graph.neighbors(
                                                node4th):
                                            nhbrs.append(node5th)  #5th order
                                            if deg > 5:
                                                for node6th in graph.neighbors(
                                                        node5th):
                                                    nhbrs.append(
                                                        node6th)  #6th order

        for nde in nhbrs:
            if node != nde:  # GM: comment out
                gTot.add_edge(node, nde)

        i = i + 1  # GM check if i++1
        nProcessed = nProcessed + 1  # GM check if nProcessed++1

    print "gTot nodes: " + str(len(gTot.nodes()))
    print "gTot edges: " + str(len(gTot.edges()))
    print "Nodes processed: " + str(nProcessed)
    tf = time.time() - t0
    print "time to go through " + str(nProcessed) + " nodes: " + str(tf)

    return gTot
def remGraph(eList, nodeID):
    '''Creates a graph of all removed edges
    eList: list of removed edges, where each element is a tuple edge, (node1, node2)
    nodeID: dictionary of nodes in mesh. key = node ID, value = tuple, (x_coord, y_coord, z_coord)
    
    returns: graph of all removed edges    
    '''
    gRem = d.DiGraph()
    for edge in eList:
        gRem.add_edge(*edge)
    gmshNodeProps(gRem, nodeID)
    return gRem
def coastGraph(coastList, nodeID):
    '''Creates a graph of all coastal nodes
    coastList: list of all coastal nodes
    nodeID: dictionary of nodes in mesh. key = node ID, value = tuple, (x_coord, y_coord, z_coord)
    
    returns: graph of all coastal nodes
    '''
    gCoast = d.DiGraph()
    for i in range(len(coastList)):
        gCoast.add_node(coastList[i],
                        lon=calcLon(nodeID[coastList[i]][0],
                                    nodeID[coastList[i]][1]),
                        lat=calcLat(nodeID[coastList[i]][2]))
    return gCoast
def coastGraphGEODAS(shoreline):
    '''Creates coastal graph based on shoreline data from GEODAS
    shoreline: shoreline database (.a00 file)
    
    returns: graph of all coastal nodes    
    '''
    gCoast = d.DiGraph()
    coastFile = open(shoreline, 'r')
    nodeID = 0
    for line in coastFile.readlines():
        gCoast.add_node(nodeID,
                        lon=float(line.split()[0]),
                        lat=float(line.split()[1]))
        nodeID = nodeID + 1
    coastFile.close()
    return gCoast
def VISIRGraph(
    startList, endList, wList, lonList, latList, nameDict
):  #TO DO: make it add interpolation properties (similar to what gmshEdgeProps() does)
    '''Creates graph using input data from VISIR. Adds relevant properties
    startList: list of start nodes for each edge
    endList: list of end nodes for each edges
    wList: list of weights for each edge
    lonList: list of longitudes for each node
    latList: list of latitudes for each node
    nameDict: csv file dictionary of user specifications/flags
    
    returns: graph
    '''

    g = d.DiGraph()
    for i in range(len(startList)):
        if nameDict['is_tdep'][0] == '0':
            if i < len(lonList):
                g.add_node(i + 1, lon=lonList[i], lat=latList[i], use=-1)
                g.add_edge(
                    startList[i], endList[i], weight=wList[i][0]
                )  # to generalize for multiple keys (assuming new key file structure is the same as for the weights), simply add: keyname = keyDict[i]
                #dictLoop(g, i+1, startList[i], endList[i], wDict)
            else:
                g.add_edge(
                    startList[i], endList[i], weight=wList[i][0]
                )  # to generalize for multiple keys (assuming new key file structure is the same as for the weights), simply add: keyname = keyDict[i]
                #dictLoop(g, i+1, startList[i], endList[i], wDict)
        if nameDict['is_tdep'][1] == '1':
            if i < len(lonList):
                g.add_node(i + 1, lon=lonList[i], lat=latList[i], use=-1)
                g.add_edge(
                    startList[i], endList[i], weight=wList[i]
                )  # to generalize for multiple keys (assuming new key file structure is the same as for the weights), simply add: keyname = keyDict[i]
                #dictLoop(g, i+1, startList[i], endList[i], wDict)
            else:
                g.add_edge(
                    startList[i], endList[i], weight=wList[i]
                )  # to generalize for multiple keys (assuming new key file structure is the same as for the weights), simply add: keyname = keyDict[i]
                #dictLoop(g, i+1, startList[i], endList[i], wDict)
    for edge in g.edges():
        g.edge[edge[0]][edge[1]]['cog'] = cwts.calcEdgeBearing(
            g, edge[0], edge[1])
        g.edge[edge[0]][edge[1]]['dist'] = cwts.calcDist(g, edge[0], edge[1])
    return g
def GMSHGraph(msh, nameDict, files):
    '''Creates a graph based on GMSH mesh. Adds relevant graph properties.
    msh: GMSH mesh file to be used to create graph (.msh file)
    nameDict: csv file dictionary of user specifications/flags
    files: list of directories/file names for file retrieval
    
    returns: graph    
    '''
    mesh = open(msh, 'r')
    graph = d.DiGraph()
    nodeID = rg.getNodes(mesh)
    mesh.seek(0)
    start, end, coast = rg.getEdges(mesh)
    mesh.close()
    keys = nodeID.keys()
    for i in range(len(keys)):
        graph.add_node(keys[i])
    for i in range(len(start) - 1):
        graph.add_edge(start[i], end[i])

    gTot = gmshExtraEdges(graph, nameDict)

    nProps = gmshNodeProps(gTot, nodeID)
    '''Code for checking for intersections and removing nodes'''
    #t0i = time.time()
    #eList = inter.intCheck(gTot, gCoast)
    #tfi = time.time() - t0i
    #print "time to check for intersections: " + str(tfi)
    #print "new number of edges: " + str(len(gTot.edges()))
    '''Code for interpolating current magnitudes and creating dictionaries that can then be used to calculate weights based on current magnitudes'''
    #flowArrays = cwts.getFlowArrays(nameDict)
    #vesselSpeedMax = float(nameDict['vessel_speed_max'][0])
    #iModule = flowArrays[4]
    #if vesselSpeedMax < iModule.max():
    #print "ERROR: Maximum vessel speed does not exceed maximum current speed within domain"
    #sys.exit()
    #t0funct = time.time()
    #fuDict, fvDict = cwts.interpField(nProps, flowArrays, files)
    #tffunct = time.time() - t0funct
    #print "function time: " + str(tffunct)
    '''Adds edge properties. Right now current interpolation is not properly functioning so it will not be an input, but once interpolation is up and running all relevant information will need to be an input for adding graph properties '''
    gmshEdgeProps(gTot, nodeID,
                  nameDict)  #, flowArrays, fuDict, fvDict, vesselSpeedMax)

    return gTot
    def test_is_assignable_std(self):
        scenarios = []
        scenarios.append([[(1, 2), (2, 1), (2, 3), (4, 3), (5, 4), (5, 6),
                           (6, 5), (7, 6), (7, 7), (7, 5)], [[7]], [[6]]])
        scenarios.append([[(1, 2), (2, 1), (2, 3), (3, 4), (5, 4), (5, 6),
                           (6, 5), (7, 6), (7, 7), (7, 5)], [[1, 2]], [[3]]])
        scenarios.append([[(1, 2), (2, 1), (2, 3), (5, 3), (5, 6), (6, 5),
                           (7, 6), (7, 7), (7, 5)], [[1, 2], [7]], [[3], [6]]])
        #2nd batch
        scenarios.append([[(1, 2), (2, 1), (3, 3), (2, 4), (3, 4), (3, 5)],
                          [[1, 2], [3]], [[4], [4, 5]]])

        scenarios.append([[(1, 2), (2, 1), (3, 3), (2, 4), (3, 4), (3, 5),
                           (5, 4)], [[3]], [[5]]])

        scenarios.append([[(1, 2), (2, 1), (1, 3), (2, 4), (3, 4), (4, 3),
                           (6, 6), (6, 3)], [], []])

        for scenario in scenarios:
            print scenario[0]
            G = lightnx.DiGraph()
            G.add_edges_from(scenario[0])
            scc_pm_nt, Gprime = matchings.get_S_nt_rm_Gprime(G)
            assignable_sorted = map(sorted, scenario[1])
            msize = len(matchings.matching(Gprime))
            assign = []
            for scc in scc_pm_nt:
                back_edges = Gprime.edges()[:]
                if matchings.is_assignable(scc, Gprime, msize):
                    assign.append(scc)
                    #print "asig"
                    try:
                        idx = assignable_sorted.index(sorted(
                            scc.graph.nodes()))
                    except:
                        idx = None
                    assert_equals(sorted(back_edges), sorted(Gprime.edges()))
                    assert_equals(idx is None, False)
                    assert_equals(scc.assignable_points, set(scenario[2][idx]))
            assert_equals(len(assign), len(assignable_sorted))
    def test_get_S_nt_rm_Gprime(self):
        G = lightnx.DiGraph()
        G.add_edges_from([(1, 2), (2, 1), (2, 3), (3, 4), (4, 3), (5, 4),
                          (5, 6), (6, 5), (7, 6), (7, 7), (7, 5)])
        scc_pm_nt, gprime = matchings.get_S_nt_rm_Gprime(G)
        assert_equals(len(scc_pm_nt), 2)

        def check_results(scc_pm_nt):
            assert_equals(set(scc_pm_nt[0].graph.nodes()), set([1, 2]))
            assert_equals(set(scc_pm_nt[1].graph.nodes()), set([7]))
            assert_equals(scc_pm_nt[0].outnodes, set([3]))
            assert_equals(set(scc_pm_nt[0].outlinks), set([(2, 3)]))
            assert_equals(scc_pm_nt[1].outnodes, set([6, 5]))
            assert_equals(set(scc_pm_nt[1].outlinks), set([(7, 6), (7, 5)]))

        if len(scc_pm_nt[0].graph.nodes()) == 2:
            check_results(scc_pm_nt)
        else:
            check_results(scc_pm_nt[1:0])
        assert_equals(set(gprime.nodes()), set([3, 4, 5, 6]))
        assert_equals(set(gprime.predecessors(3)), set([4]))
        assert_equals(set(gprime.successors(3)), set([4]))
示例#24
0
    def test_add_edge(self):
        G=lightnx.DiGraph()
        assert_raises(TypeError,G.add_edge,'A')

        G.add_edge('A','B')     # testing add_edge()
        G.add_edge('A','B') # should fail silently
        assert_true(G.has_edge('A','B'))
        assert_false(G.has_edge('A','C'))
        assert_true(G.has_edge( *('A','B') ))
        if G.is_directed():
            assert_false(G.has_edge('B','A'))
        else:
            # G is undirected, so B->A is an edge
            assert_true(G.has_edge('B','A'))


        G.add_edge('A','C')  # test directedness
        G.add_edge('C','A')
        G.remove_edge('C','A')
        if G.is_directed():
            assert_true(G.has_edge('A','C'))
        else:
            assert_false(G.has_edge('A','C'))
        assert_false(G.has_edge('C','A'))
 def test_control_set(self):
     G = lightnx.DiGraph()
     G.add_edges_from([(1, 2), (2, 1), (2, 3), (3, 4), (4, 3), (5, 4),
                       (5, 6), (6, 5), (7, 6)])
     drivers = matchings.controller_set(G)
     assert_equal(set(['1', '7']), drivers)
示例#26
0
文件: main.py 项目: Ada1248/Grafy
import digraph
import random_digraph
import plot

if __name__ == '__main__':
    random_graph = random_digraph.RandomDiGraph(9, 0.2)
    random_graph.print()
    graph = digraph.DiGraph(9)
    graph.create_with_adj_matrix(random_graph.adj_matrix)
    graph.Kosaraju()
    plot.digraph_plot(graph.adj_matrix)
    ##
    # graph = digraph.DiGraph(7)
    # graph.create_from_file('test.in')
    # graph.print()
    # print("")
    # graph.Kosaraju()
    # plot.digraph_plot(graph.adj_matrix)
 def test_matching(self):
     G = lightnx.DiGraph()
     G.add_edges_from([(1, 2), (2, 3), (3, 1), (1, 4), (1, 5), (1, 6)])
     matching = matchings.matching(G)
     assert_equal(self.isMatching(matching), True)
     assert_equal(3, len(matching))
示例#28
0
 def test_add_remove_node(self):
     G=lightnx.DiGraph()
     G.add_node('A')
     assert_true('A' in G.nodes())
     G.remove_node('A')
     assert_false('A' in G.nodes())