Exemplo n.º 1
0
    def shortest_path(self, origin, destination, weighted_poly):
        """Find and return shortest path between origin and destination.

        Will return in-order list of Points of the shortest path found. If
        origin or destination are not in the visibility graph, their respective
        visibility edges will be found, but only kept temporarily for finding
        the shortest path. 
        """

        origin_exists = origin in self.visgraph
        dest_exists = destination in self.visgraph
        if origin_exists and dest_exists:
            return shortest_path(self.visgraph, origin, destination,
                                 weighted_poly)
        orgn = None if origin_exists else origin
        dest = None if dest_exists else destination
        add_to_visg = Graph([])
        if not origin_exists:
            for v in visible_vertices(origin, self.graph, destination=dest):
                add_to_visg.add_edge(Edge(origin, v))
        if not dest_exists:
            for v in visible_vertices(destination, self.graph, origin=orgn):
                add_to_visg.add_edge(Edge(destination, v))
        return shortest_path(self.visgraph, origin, destination, weighted_poly,
                             add_to_visg)
def test_repr_edge():
    v1 = Vertex()
    v2 = Vertex(a=1, b=2)
    e1 = Edge(v1, v2)
    e2 = Edge(v1, v2, weight=1, c=3, d=4)
    assert re.match(r'^V#\d+\s->\sV#\d+\sa=1\sb=2$', repr(e1))
    assert re.match(r'^V#\d+\s->\sV#\d+\sa=1\sb=2\s-\sweight=1\sc=3\sd=4$', repr(e2))
Exemplo n.º 3
0
def main():
    source = 'Chicago'
    destination = 'Phoenix'
    g = Digraph()
    for name in ('Boston', 'Providence', 'New York', 'Chicago', 'Denver',
                 'Phoenix', 'Los Angeles'):  #Create 7 nodes
        g.addNode(Node(name))
    g.addEdge(Edge(g.getNode('Boston'), g.getNode('Providence')))
    g.addEdge(Edge(g.getNode('Boston'), g.getNode('New York')))
    g.addEdge(Edge(g.getNode('Providence'), g.getNode('Boston')))
    g.addEdge(Edge(g.getNode('Providence'), g.getNode('New York')))
    g.addEdge(Edge(g.getNode('New York'), g.getNode('Chicago')))
    g.addEdge(Edge(g.getNode('Chicago'), g.getNode('Denver')))
    g.addEdge(Edge(g.getNode('Chicago'), g.getNode('Phoenix')))
    g.addEdge(Edge(g.getNode('Denver'), g.getNode('Phoenix')))
    g.addEdge(Edge(g.getNode('Denver'), g.getNode('New York')))
    g.addEdge(Edge(g.getNode('Los Angeles'), g.getNode('Boston')))

    sp = DFS(g,
             g.getNode(source),
             g.getNode(destination), [],
             None,
             toPrint=True)

    if sp != None:
        print('Shortest path from', source, 'to', destination, 'is',
              printPath(sp))
    else:
        print('There is no path from', source, 'to', destination)
Exemplo n.º 4
0
def convertDHCtoUHC(inString):
    # G is the original instance
    G = Graph(inString, weighted=False, directed=True)
    # newG is the converted instance -- create an empty graph using empty string
    newG = Graph('', weighted=False, directed=False)
    # Create all of the nodes of newG -- a triplet of A, B, and C
    # nodes in newG for every node in G.  Also create an A-B edge and
    # a B-C edge within each triplet.
    for node in G:
        # Create triplet.
        nodeA = node + 'A'
        nodeB = node + 'B'
        nodeC = node + 'C'
        newNodes = (nodeA, nodeB, nodeC)
        for newNode in newNodes:
            newG.addNode(newNode)
        # Create A-B and B-C edges within the triplet.
        newG.addEdge(Edge([nodeA, nodeB]))
        newG.addEdge(Edge([nodeB, nodeC]))
    # Create all the remaining edges of newG, i.e., create an undirected
    # A-C edge corresponding to each directed edge in G.
    for edge in G.edges():
        (node1, node2) = edge.nodes
        newEdge = Edge([node1 + 'A', node2 + 'C'])
        newG.addEdge(newEdge)

    return str(newG)
Exemplo n.º 5
0
def build_city_graph(graph_type):
    providence = Node('providence')
    boston = Node('boston')
    new_york = Node('new york')
    denver = Node('denver')
    phoenix = Node('phoenix')
    chicago = Node('chicago')
    los_angeles = Node('los angeles')

    edges = []
    edges.append(Edge(providence, boston))
    edges.append(Edge(providence, new_york))
    edges.append(Edge(denver, phoenix))
    edges.append(Edge(denver, new_york))
    edges.append(Edge(new_york, chicago))
    edges.append(Edge(chicago, denver))
    edges.append(Edge(chicago, phoenix))
    edges.append(Edge(boston, providence))
    edges.append(Edge(boston, new_york))
    edges.append(Edge(los_angeles, boston))

    graph = graph_type()
    graph.add_node(providence)
    graph.add_node(boston)
    graph.add_node(new_york)
    graph.add_node(denver)
    graph.add_node(phoenix)
    graph.add_node(chicago)
    graph.add_node(los_angeles)

    for edge in edges:
        graph.add_edge(edge)

    return graph
 def test_apply_remove_connection_from_edge(self):
     mother_graph = Graph()
     m_n1 = Vertex()
     m_e1 = Edge(m_n1)
     mother_graph.add_elements([m_n1, m_e1])
     daughter_graph = Graph()
     d_e1 = Edge()
     daughter_graph.add_elements([d_e1])
     mother_daughter_mapping = Mapping()
     mother_daughter_mapping[m_e1] = d_e1
     prod_option = ProductionOption(mother_graph, mother_daughter_mapping,
                                    daughter_graph)
     production = Production(mother_graph, [prod_option])
     host_graph = Graph()
     h_n1 = Vertex()
     h_e1 = Edge(None, h_n1)
     host_graph.add_elements([h_n1, h_e1])
     mother_host_mapping = Mapping()
     mother_host_mapping[m_n1] = h_n1
     mother_host_mapping[m_e1] = h_e1
     result = production.apply(host_graph, mother_host_mapping)
     # Test if the vertex was deleted
     assert len(result.vertices) == 0
     assert len(result.edges) == 1
     # Test if the vertex was removed from the edges connection field
     assert result.edges[0].vertex2 is None
def main():
    # Two sources and single distination
    v_in = Vertex("x")  # one source
    v1 = Edge(name="e0")(v_in)
    v2 = Edge(name="e1")(v1)
    v3 = Edge(name="e2")(v2, v1)  # fork and concate
    v4 = Edge(name="e3")(v3)
    v5 = Edge(name="e4")(v4)
    y = Vertex("y")  # second source
    y.value = np.random.rand(4, 3)
    v_out = SquareLoss(name="square-loss")(v5, y)  # single distination

    print "----- Vertices and Edges in Graph -----"
    print len(cg.vertices)
    print len(cg.edges)

    print "----- Forward pass (Inference) -----"
    inputs = np.random.rand(4, 3)
    v_in.forward(inputs)
    labels = np.random.rand(4, 3)
    y.forward(labels)
    print v1.value
    print v5.value

    print "----- Compute Loss -----"
    v_out.backward(1)
    print v1.grad
 def test_apply_vertex_new_connection(self):
     mother_graph = Graph()
     m_n1 = Vertex()
     m_e1 = Edge(m_n1)
     mother_graph.add_elements([m_n1, m_e1])
     daughter_graph = Graph()
     d_n1 = Vertex()
     d_e1 = Edge(d_n1)
     daughter_graph.add_elements([d_n1, d_e1])
     mother_daughter_mapping = Mapping()
     mother_daughter_mapping[m_n1] = d_n1
     prod_option = ProductionOption(mother_graph, mother_daughter_mapping,
                                    daughter_graph)
     production = Production(mother_graph, [prod_option])
     host_graph = Graph()
     h_n1 = Vertex()
     h_e1 = Edge(h_n1)
     host_graph.add_elements([h_n1, h_e1])
     mother_host_mapping = Mapping()
     mother_host_mapping[m_n1] = h_n1
     mother_host_mapping[m_e1] = h_e1
     result = production.apply(host_graph, mother_host_mapping)
     # Test if there are no superfluous elements in the graph
     assert len(result.vertices) == 1
     assert len(result.edges) == 1
     # Test if graph has the correct connections and element count
     assert result.is_isomorph(daughter_graph)
     # Test if there are no extra neighbours introduced to the vertex.
     assert len(result.vertices[0].edges) == 1
     assert result.edges[0] in result.vertices[0].edges
     # Test if the new edge was correctly connected to the vertex.
     assert result.edges[0].vertex1 == result.vertices[0]
Exemplo n.º 9
0
def test_case_2():
    vertex_to_name = {x: str(x + 1) for x in range(4)}
    edge_list = [
        Edge(0, 2, -2),
        Edge(1, 0, 4),
        Edge(1, 2, 3),
        Edge(2, 3, 2),
        Edge(3, 1, -1)
    ]
    g = Graph(Graph.GRAPH_TYPE_DIRECTED_WEIGHT, vertex_to_name, edge_list)
    node_text_map, edges, directed = g.get_show_info()
    GraphVisualization.show(node_text_map,
                            edges,
                            is_directed=directed,
                            view_graph=True,
                            rank_dir="LR")
    distances, paths = shortest_path_floyd_warshall(g)
    print("shortest path from and weight sum as:")
    for i in range(g.get_vertices_count()):
        for j in range(g.get_vertices_count()):
            path_str = "-".join(
                [g.get_vertex_name(vertex) for vertex in paths[i][j]])
            print("%s to %s: %s%s %d" %
                  (g.get_vertex_name(i), g.get_vertex_name(j), path_str, '*' *
                   (15 - len(path_str)), distances[i][j]))
Exemplo n.º 10
0
    def test_weighted_edge(self):
        graph = Graph()
        graph.add_edge("A", "B", 3)

        self.assertEqual(graph.as_adjency_list(values_only=False), {
            "A": [Edge("B", 3)],
            "B": [Edge("A", 3)],
        })
Exemplo n.º 11
0
def test_case_2():
    vertex_to_name = {x: str(x) for x in range(4)}
    edge_list = [Edge(0, 1, 1), Edge(0, 2, 4), Edge(0, 3, 3), Edge(1, 3, 2), Edge(2, 3, 5)]
    g = Graph(Graph.GRAPH_TYPE_UNDIRECTED_WEIGHT, vertex_to_name, edge_list)
    node_text_map, edges, directed = g.get_show_info()
    GraphVisualization.show(node_text_map, edges, is_directed=directed, view_graph=True, rank_dir="LR")
    weight_sum, edges = prim_algorithm(g)
    print('minimum span tree weight sum= ', weight_sum, ' select edges: ', edges)
Exemplo n.º 12
0
def test_strongly_connected_components_fail_on_undirected_graph():
    vertices = [Vertex() for i in range(3)]
    edges = [
        Edge(head=vertices[0], tail=vertices[1]),
        Edge(head=vertices[1], tail=vertices[2]),
    ]
    graph = Graph(vertices=vertices, edges=edges, directed=False)
    with pytest.raises(GraphDirectionTypeError):
        find_strongly_connected_components(graph)
Exemplo n.º 13
0
    def __init__(self, size, l0=20.):
        super(PeriodicGraph, self).__init__()
        self.mutable_edges = []

        self.verts = [[
            Vertex(coords=i * SquareGraph.X_DIR + j * SquareGraph.Y_DIR)
            for i in range(size)
        ] for j in range(size)]

        self.l0 = l0

        for i in range(size):
            for j in range(size):

                vertex = self.verts[i][j]
                self.register_vertex(vertex)

                # from this vertex we construct the edges of the triangle of which this vertex is the bottom left
                vUp = self.verts[(i + 1) % size][j]
                vRight = self.verts[i][(j + 1) % size]

                # edges that are not on the side are immutable
                edge = Edge.make_edge(vertex, vUp)
                self.register_edge(edge)
                if not (j == 0):
                    self.mutable_edges.append(edge)

                edge = Edge.make_edge(vertex, vRight)
                self.register_edge(edge)
                if not (i == 0):
                    self.mutable_edges.append(edge)

                edge = Edge.make_edge(vUp, vRight)
                self.register_edge(edge)
                self.mutable_edges.append(edge)

                # From this vertex, we construct the triangle of which it is the bottom left  corner
                self.register_area(Area.make_area(vertex, vUp, vRight))

        # When all edges are complete, we create the triangles that point down,
        # each vertex constructs the triangle of which it is the upper left corner
        for i in range(size):
            for j in range(size):
                vertex = self.verts[i][j]
                vDown = self.verts[(i - 1) % size][(j + 1) % size]
                vRight = self.verts[i][(j + 1) % size]
                self.register_area(Area.make_area(vertex, vDown, vRight))

        for vert in self.vertices:
            vert.coords = vert.coords * l0

        self.summary()
        assert (self.is_complete())

        self.periodX = size * l0 * SquareGraph.X_DIR
        self.periodY = size * l0 * SquareGraph.Y_DIR
        self.toSq = np.array([self.periodX, self.periodY]).T
Exemplo n.º 14
0
def test_topological_sorting_fail_on_undirected_graph():
    vertices = [Vertex() for i in range(3)]
    edges = [
        Edge(head=vertices[0], tail=vertices[1]),
        Edge(head=vertices[1], tail=vertices[2]),
    ]
    graph = Graph(vertices=vertices, edges=edges, directed=False)
    with pytest.raises(GraphDirectionTypeError):
        topological_sort(graph)
Exemplo n.º 15
0
 def test_graph_create(self):
     node_list = [Node(1), Node(2), Node(3)]
     edge_list = [
         Edge('2 miles', node_list[0], node_list[1]),
         Edge('6 miles', node_list[1], node_list[2])
     ]
     graph = Graph(node_list, edge_list)
     self.assertEqual(node_list, graph.nodes)
     self.assertEqual(edge_list, graph.edges)
Exemplo n.º 16
0
 def test_Edge(self):
     jack = Node(0)
     jill = Node(1)
     e = Edge(0, jack, "loves", jill)
     e.label = "hates"
     e.intensity = 99
     self.assertEqual(e.label, "hates")
     self.assertTrue("label" not in e.properties)
     self.assertTrue(e.properties["intensity"] == 99)
Exemplo n.º 17
0
def test_all_paths():
    vertices = [Vertex() for i in range(6)]
    edges = [
        Edge(head=vertices[0], tail=vertices[1]),
        Edge(head=vertices[0], tail=vertices[2]),
        Edge(head=vertices[0], tail=vertices[3]),
        Edge(head=vertices[0], tail=vertices[4]),
        Edge(head=vertices[1], tail=vertices[5]),
        Edge(head=vertices[2], tail=vertices[3]),
        Edge(head=vertices[2], tail=vertices[5]),
        Edge(head=vertices[3], tail=vertices[5]),
        Edge(head=vertices[4], tail=vertices[5]),
    ]
    graph = Graph(vertices=vertices, edges=edges, directed=False)
    edge_paths = list(construct_all_paths(graph=graph,
                                     start=vertices[0],
                                     end=vertices[2]))
    paths = []
    for edge_path in edge_paths:
        path = [vertices[0]] + [edge.tail for edge in edge_path]
        paths.append(path)
    assert len(paths) == 7
    actual_paths = [
        [vertices[0], vertices[1], vertices[5], vertices[2]],
        [vertices[0], vertices[1], vertices[5], vertices[3], vertices[2]],
        [vertices[0], vertices[2]],
        [vertices[0], vertices[3], vertices[2]],
        [vertices[0], vertices[3], vertices[5], vertices[2]],
        [vertices[0], vertices[4], vertices[5], vertices[2]],
        [vertices[0], vertices[4], vertices[5], vertices[3], vertices[2]],
    ]
Exemplo n.º 18
0
def test_case_1():
    vertex_to_name = {
        0: 'S',
        1: 'A',
        2: 'B',
        3: 'C',
        4: 'D',
        5: 'E',
        6: 'F',
        7: 'G'
    }
    g = Graph(Graph.GRAPH_TYPE_UNDIRECTED, vertex_to_name, None)
    g.add_edges([
        Edge(0, 1),
        Edge(0, 2),
        Edge(0, 3),
        Edge(1, 4),
        Edge(2, 5),
        Edge(3, 6),
        Edge(4, 7),
        Edge(5, 7),
        Edge(6, 7)
    ])
    node_text_map, edges, directed = g.get_show_info()
    GraphVisualization.show(node_text_map,
                            edges,
                            is_directed=directed,
                            view_graph=True,
                            rank_dir="LR")
    print('depth first traverse by iteration: ',
          [g.get_vertex_name(x) for x in depth_first_traverse_by_iteration(g)])
    print('depth first traverse by recursion: ',
          [g.get_vertex_name(x) for x in depth_first_traverse_by_recursion(g)])
    print('breadth first traverse: ',
          [g.get_vertex_name(x) for x in breadth_first_traverse(g)])
Exemplo n.º 19
0
    def test_basic_bfs_alternate(self):
        """
        Graph

        [1]-----[2]
                /|   [5]
               / |  /
              /  | /
           [4]--[3]

        :return:
        """
        edges = [
            Edge('one', 'two'),
            Edge('two', 'four'),
            Edge('two', 'three'),
            Edge('three', 'two'),
            Edge('three', 'four'),
            Edge('three', 'five'),
            Edge('four', 'two'),
            Edge('four', 'three'),
            Edge('five', 'three')
        ]

        g = Graph(edges)
        bfs_graph = BreadthFirstPaths(g, 'five')

        expected = ['five', 'three', 'four']
        actual = bfs_graph.path_to('four')
        self.assertEqual(expected, actual)
Exemplo n.º 20
0
def test_dijkstra_algorithm():
    vertices = [Vertex() for i in range(6)]
    edges = [
        Edge(head=vertices[0], tail=vertices[1], weight=4),
        Edge(head=vertices[0], tail=vertices[2], weight=2),
        Edge(head=vertices[1], tail=vertices[2], weight=1),
        Edge(head=vertices[1], tail=vertices[3], weight=5),
        Edge(head=vertices[2], tail=vertices[3], weight=8),
        Edge(head=vertices[2], tail=vertices[4], weight=10),
        Edge(head=vertices[3], tail=vertices[4], weight=2),
        Edge(head=vertices[3], tail=vertices[5], weight=6),
        Edge(head=vertices[4], tail=vertices[5], weight=5),
    ]
    graph = Graph(vertices=vertices, edges=edges, directed=False)
    shortest_paths = run_dijkstra_algorithm(graph=graph, source=vertices[0])
    for i in range(6):
        assert shortest_paths[vertices[i]].source is vertices[0]
        assert shortest_paths[vertices[i]].destination is vertices[i]
    assert shortest_paths[vertices[0]].last_hop is None
    assert shortest_paths[vertices[0]].distance == 0
    assert shortest_paths[vertices[1]].last_hop.head is vertices[2]
    assert shortest_paths[vertices[1]].distance == 3
    assert shortest_paths[vertices[2]].last_hop.head is vertices[0]
    assert shortest_paths[vertices[2]].distance == 2
    assert shortest_paths[vertices[3]].last_hop.head is vertices[1]
    assert shortest_paths[vertices[3]].distance == 8
    assert shortest_paths[vertices[4]].last_hop.head is vertices[3]
    assert shortest_paths[vertices[4]].distance == 10
    assert shortest_paths[vertices[5]].last_hop.head is vertices[3]
    assert shortest_paths[vertices[5]].distance == 14
Exemplo n.º 21
0
def test_prim_algorithm_fail_on_directed_graph():
    vertices = [Vertex() for i in range(6)]
    edges = [
        Edge(head=vertices[0], tail=vertices[1]),
        Edge(head=vertices[1], tail=vertices[2]),
        Edge(head=vertices[2], tail=vertices[0]),
        Edge(head=vertices[3], tail=vertices[4]),
    ]
    graph = Graph(vertices=vertices, edges=edges, directed=True)
    with pytest.raises(GraphDirectionTypeError):
        run_prim_algorithm(graph=graph, start=vertices[0])
Exemplo n.º 22
0
    def test_dfs_int_vertices_negaitve(self):

        graph = Graph()

        graph.add_edge(Edge(Vertex(1), Vertex(2), 1))
        graph.add_edge(Edge(Vertex(1), Vertex(4), 1))
        graph.add_edge(Edge(Vertex(3), Vertex(4), 1))
        graph.add_edge(Edge(Vertex(4), Vertex(2), 1))

        self.assertEqual(dfs(graph, Vertex(5), Vertex(0)), float("inf"))
        self.assertEqual(dfs(graph, Vertex(1), Vertex(5)), float("inf"))
    def find_lower_adjacent(self, triangle):
        edges = []
        edges.append(Edge(triangle[0], triangle[1]))
        edges.append(Edge(triangle[1], triangle[2]))
        edges.append(Edge(triangle[0], triangle[2]))

        num_of_lower_adjacent = 0
        neighbours = set()
        for edge in edges:
            num_of_lower_adjacent += len(self.edge_triangle_map[edge])
            neighbours |= (self.edge_triangle_map[edge])
        return num_of_lower_adjacent, list(neighbours)
def test_path_finder_fail():
    vertices = [Vertex() for i in range(4)]
    edges = [
        Edge(vertices[0], vertices[1]),
        Edge(vertices[1], vertices[2]),
        Edge(vertices[2], vertices[0]),
        Edge(vertices[2], vertices[3]),
    ]
    graph = Graph(vertices=vertices, edges=edges, directed=True)
    graph.bfs(start=vertices[0])
    with pytest.raises(Exception):
        graph.find_path(start=vertices[3], end=vertices[1])
    def find_upper_adjacent(self, triangle):
        edges = []
        edges.append(Edge(triangle[0], triangle[1]))
        edges.append(Edge(triangle[1], triangle[2]))
        edges.append(Edge(triangle[0], triangle[2]))

        num_of_upper_adjacent = 0
        for edge in edges:
            triangles_edge_is_partof = self.edge_triangle_map[edge]
            for tr in triangles_edge_is_partof:
                if self.is_partof_k_plus_one_simplex(triangle, tr):
                    num_of_upper_adjacent += 1
        return num_of_upper_adjacent
Exemplo n.º 26
0
    def test_edge(self):

        edge = Edge('A', 'B')

        self.assertEqual(edge.u, 'A')
        self.assertEqual(edge.v, 'B')
        self.assertEqual(edge.weight, 1)

        edge = Edge('X', 'Y', 15)

        self.assertEqual(edge.u, 'X')
        self.assertEqual(edge.v, 'Y')
        self.assertEqual(edge.weight, 15)
Exemplo n.º 27
0
def test_degree():
    g = Graph()

    edges = [
        (Edge('A', 'B'), 12),
        (Edge('A', 'C'), 8),
        (Edge('A', 'D'), 2),
    ]

    for tpl in edges:
        g.add_edge(tpl[0], tpl[1])

    assert g.degree('A') is 3
Exemplo n.º 28
0
class InitGraph:

    ## set up all the film/actor nodes as Dictionary:
    ## key: url, value: film/actor node
    ## store the edges as a list with starting node of actor and ending node as movie
    filmNodes = []
    actorNodes = []
    filmNameDict = {}
    actorNameDict = {}
    edges = []
    nodes = {}
    hub = {}

    #parse a json file
    with open(
            '/Users/Jenny/Desktop/cs242/Assignment2.0/Scraper/Scraper/quotes.json',
            'r') as content_file:
        content = content_file.read()
    data = json.loads(content)

    for i in range(len(data)):
        temp = data[i]
        name = None
        edge = None

        ## when we discover the current index of the json file is an actor
        if temp['isActor'] == True:
            node = ActorNode(temp['actorName'], temp['url'], temp['year'])
            nodes[temp['url']] = node
            actorNodes.append(node)
            actorNameDict[temp['actorName']] = []
            for cast in temp['castings']:
                for ch in cast:
                    actorNameDict[temp['actorName']].append(ch)
            for url in temp['films']:
                if nodes.get(url) is not None:
                    edge = Edge(node, nodes.get(url))

        ## when we discover the current index of the json file is a film
        elif temp['isFilm'] == True:
            node = FilmNode(temp['filmName'], temp['url'], temp['year'],
                            temp['filmValue'])
            nodes[temp['url']] = node
            filmNodes.append(node)
            filmNameDict[temp['filmName']] = temp['starrings']
            for url in temp['actors']:
                if nodes.get(url) is not None:
                    edge = Edge(nodes.get(url), node)

        if edge is not None:
            edges.append(edge)
Exemplo n.º 29
0
def test_connected_components():
    vertices = [Vertex() for i in range(6)]
    edges = [
        Edge(head=vertices[0], tail=vertices[1]),
        Edge(head=vertices[1], tail=vertices[2]),
        Edge(head=vertices[2], tail=vertices[0]),
        Edge(head=vertices[3], tail=vertices[4]),
    ]
    graph = Graph(vertices=vertices, edges=edges, directed=False)
    connected_components = find_connected_components(graph)
    assert len(connected_components) == 3
    assert {v for v in connected_components[0].adjacency_lists} == {v for v in vertices[:3]}
    assert {v for v in connected_components[1].adjacency_lists} == {v for v in vertices[3:5]}
    assert {v for v in connected_components[2].adjacency_lists} == {vertices[5]}
Exemplo n.º 30
0
 def setUp(self):
     self.nodes = [
         Node('v1'),
         Node('v2'),
         Node('v3'),
         Node('v4'),
     ]
     self.edges = [
         Edge('edge 1', node_from='v1', node_to='v2'),
         Edge('edge 2', node_from='v1', node_to='v3'),
         Edge('edge 3', node_from='v3', node_to='v2'),
         Edge('edge 4', node_from='v3', node_to='v4'),
         Edge('edge 5', node_from='v4', node_to='v3'),
     ]
     self.graph = Graph(self.nodes, self.edges)
Exemplo n.º 31
0
    def test_large_graph(self):

        graph = Graph()

        for i in range(0, 1000):
            graph.add_edge(Edge(str(i), str(i + 1), 5))

            graph.add_edge(Edge(str(i), str(500), 5))
        graph.add_edge(Edge(str(1000), str(250), 5))

        self.assertEqual(graph.get_distance_for_path(['0', '1', '2']), 10)
        self.assertEqual(graph.get_num_paths(start='0', end='500', restriction={'max_distance': 50}), 1023)
        self.assertEqual(graph.get_min_distance(start='50', end='51'), 5)
        self.assertEqual(graph.get_min_distance(start='1000', end='250'), 5)
        self.assertEqual(graph.get_min_distance(start='0', end='1000'), 2505)
Exemplo n.º 32
0
    def __init__(self, start_node, end_node, distance=0, augmenting_flow=-1, residual_flow=0):
        Edge.__init__(self, start_node, end_node)

        self.residual_flow = residual_flow
        self.distance = distance
        if augmenting_flow >= 0:
            self.augmenting_flow = augmenting_flow
        else:
            self.augmenting_flow = distance


# class Worker:
#     """
#     :type edges :
#     """
#     def __init__(self, edges):
#         self.edges = edges
#         pass
	    node.group = i
	    node.id = i
	    nodes.append(node) 
    else:
        n_total = input()
	for i in range(n_total):
	    n = A_Node(random.randint(0,1000),random.randint(0,1000))
	    n.group = i
	    n.id = i
	    nodes.append(n)
	   
    graph = Graph()
    graph.nodes = nodes
    for i in range(len(graph.nodes)):
        for j in range(i):
	    e = Edge(graph.nodes[i],graph.nodes[j])
	    e.calcPeso()
	    graph.edges.append(e)

    mst = mst_kruskal(graph)
    adj_list = create_adj_list(mst,len(graph.nodes))
    cycle = []
    HC_dfs(mst[0].n1,adj_list,cycle,graph.nodes)

    a = Gen_TSP(100,cycle)
    a.finish_him(10,10000)
    a.population.sort()
    p = a.population[0]
    for i in range(len(p.nodes)):
        if i+1 < len(p.nodes):
	    print "%s %s %s %s" % (p.nodes[i].X,p.nodes[i].Y,p.nodes[i+1].X,p.nodes[i+1].Y)
Exemplo n.º 34
0
 def __init__(self, order=1):
     Edge.__init__(self)
     self.order = order
Exemplo n.º 35
0
 def __init__(self, order=None):
     Edge.__init__(self)
     self.order = order or []
Exemplo n.º 36
0
	def __str__(self):
        return  Edge.__str__(self) + " (" + str(self.weight1),str(self.weight2) + ")"
Exemplo n.º 37
0
	def __init__(self, src, dest, weight1, weight2):
		Edge.__init__(self, src, dest)
		self.weight1 = weight1
		self.weight2 = weight2
Exemplo n.º 38
0
def load(graph, fobj, queryCallback=None, warningCallback=None):
    """ Load a TLP file and create a graph from it

    Arguments:
    graph -- the graph to be created from the loaded file
    fobj -- a file object of the TLP file to be read
    queryCallback -- function to display a default query dialog (default None)
    warningCallback -- function to display a default warning dialog
                       (default None)
    
    """

    try:
        tlpgraph = TLPGraph(Stream(fobj))
    except Unbalanced:
        raise ImportError, "Unbalanced delimiters in file"
    except TypeMismatch:
        raise ImportError, "Unintelligible value in file"
    except EOF:
        raise ImportError, "Premature end of file"

    # Boolean variables to control if the rest of the import errors are handled
    # automatically
    yestoall = False
    yesall_duplicate_edge = False
    yesall_degenerate_edge = False
    yesall_nonexist_vert = False

    # Make vertices and apply properties
    for vertex, properties in tlpgraph.nodes.items():
        v = Vertex(vertex)
        if "viewLabel" in properties:
            v.name = properties["viewLabel"]
        if "viewLayout" in properties:
            pos = string_to_tuple(properties["viewLayout"])
            v.pos = tuple([float(x) for x in pos])
        if "viewSize" in properties:
            v.radius = float(string_to_tuple(properties["viewSize"])[0])
        if "viewColor" in properties:
            color = string_to_tuple(properties["viewColor"])[:3]
            v.color = tuple([float(x) / 255 for x in color])
        graph.addVertex(v)

    # Make edges and apply properties
    edges = tlpgraph.edges.values()
    edges.extend(tlpgraph.lost_edges)
    for properties in edges:

        source = properties["source"]
        target = properties["target"]

        # Raise an error if edge is degenerate, or source or target vertices
        # are non existent. Automatically handle errors if yes all is selected
        if source == target:
            # Degenerate Edge
            if yesall_degenerate_edge or yestoall:
                continue
            if queryCallback:
                result = queryCallback("Degenerate edge detected: %s -> %s" % (source, target))
                if result == CustomButtonDialog.ID["Yes"]:
                    continue
                elif result == CustomButtonDialog.ID["Yes to similar errors"]:
                    yesall_degenerate_edge = True
                    continue
                elif result == CustomButtonDialog.ID["Yes to all errors"]:
                    yestoall = True
                    continue
                else:
                    raise ImportError, "Import aborted."
            else:
                raise ImportError("Degenerate edge detected: %s -> %s" % (source, target))
        if source not in tlpgraph.nodes.keys():
            # Nonexistent vertex
            if yesall_nonexist_vert or yestoall:
                continue
            if queryCallback:
                result = queryCallback("Edge specifies nonexistent " "source vertex %s" % (source))
                if result == CustomButtonDialog.ID["Yes"]:
                    continue
                elif result == CustomButtonDialog.ID["Yes to similar errors"]:
                    yesall_nonexist_vert = True
                    continue
                elif result == CustomButtonDialog.ID["Yes to all errors"]:
                    yestoall = True
                    continue
                else:
                    raise ImportError, "Import aborted."
            else:
                raise ImportError, ("Edge specifies nonexistent source vertex" " %s" % (source))
        if target not in tlpgraph.nodes.keys():
            # Nonexistent vertex
            if yesall_nonexist_vert or yestoall:
                continue
            if queryCallback:
                result = queryCallback("Edge specifies nonexistent " "target vertex %s" % (target))
                if result == CustomButtonDialog.ID["Yes"]:
                    continue
                elif result == CustomButtonDialog.ID["Yes to similar errors"]:
                    yesall_nonexist_vert = True
                    continue
                elif result == CustomButtonDialog.ID["Yes to all errors"]:
                    yestoall = True
                    continue
                else:
                    raise ImportError, "Import aborted."
            else:
                raise ImportError, ("Edge specifies nonexistent target vertex" " %s" % (target))
        source = graph.findVertexByID(source)
        target = graph.findVertexByID(target)
        found_edges = graph.findEdgeBetween(source, target)
        if len(found_edges) == 0:
            e = Edge(source, target)
        else:
            # Raise error for duplicate edges
            if source.id == found_edges[0].source.id:
                if yesall_duplicate_edge or yestoall:
                    continue
                if queryCallback:
                    result = queryCallback("Duplicate edge detected: %s -> %s" % (source.id, target.id))
                    if result == CustomButtonDialog.ID["Yes"]:
                        continue
                    elif result == CustomButtonDialog.ID["Yes to " "similar errors"]:
                        yesall_duplicate_edge = True
                        continue
                    elif result == CustomButtonDialog.ID["Yes to all errors"]:
                        yestoall = True
                        continue
                    else:
                        raise ImportError, "Import aborted."
                else:
                    raise ImportError, ("Duplicate edge detected: %s -> %s" % (source.id, target.id))
            # Raise error for reversed duplicate edge
            elif source.id == found_edges[0].target.id:
                if yesall_duplicate_edge or yestoall:
                    continue
                if queryCallback:
                    result = queryCallback("Duplicate edge detected " "(reversed): %s -> %s" % (target.id, source.id))
                    if result == CustomButtonDialog.ID["Yes"]:
                        continue
                    elif result == CustomButtonDialog.ID["Yes to " "similar errors"]:
                        yesall_duplicate_edge = True
                        continue
                    elif result == CustomButtonDialog.ID["Yes to all errors"]:
                        yestoall = True
                        continue
                    else:
                        raise ImportError, "Import aborted."
                else:
                    raise ImportError, ("Duplicate edge detected (reversed): " "%s -> %s" % (target.id, source.id))

        if "viewColor" in properties:
            color = string_to_tuple(properties["viewColor"])[:3]
            e.color = tuple([float(x) / 255 for x in color])
        if "viewSize" in properties:
            radius = string_to_tuple(properties["viewSize"])
            e.radius = (float(radius[0]) + float(radius[1])) / 2
        graph.addEdge(e)
        if "viewLayout" in properties and properties["viewLayout"] != "()":
            # Convert the string of bendpoint tuples to a tuple of strings
            # By removing whitespace and inserting a pipe between
            # each tuple, then splitting at each pipe
            bends = properties["viewLayout"]
            bends = bends.replace(" ", "").replace(")(", ");(")
            bends = bends.replace("),(", ");(")
            bends = tuple(bends[1:-1].split(";"))
            # Create bends
            for bend in bends:
                bend = string_to_tuple(bend)
                bend = tuple([float(x) for x in bend])
                graph.bendEdge(e, bend)
Exemplo n.º 39
0
def load(graph, fobj, queryCallback=None, warningCallback=None):
    """ Load a GraphML file and create a graph from it

    Arguments:
    graph -- the graph to be created from the loaded file
    fobj -- a file object of the GraphML file to be read
    queryCallback -- function to display a default query dialog (default None)
    warningCallback -- function to display a default warning dialog
                       (default None)
    """

    from xml.dom.minidom import parse

    grml_dom = parse(fobj)
    GraphML = grml_dom.documentElement

    typeTable = {
    'int': int,
    'long': long,
    'float': float,
    'double': float,
    'string': str,
    'boolean': bool,
    }
    #
    # Read the keys part of the GraphML file
    #
    keyInfo = {}
    defaults = {}

    # Boolean variables to control if the rest of the import errors are handled
    # automatically
    yestoall = False
    yesall_duplicate_vert = False
    yesall_duplicate_edge = False
    yesall_degenerate_edge = False
    yesall_color = False
    yesall_nonexist_vert = False

    # Store the graph attributes in a dictionary named keyInfo,
    # and storing any defaults in the dictionary named defaults
    for keyNode in GraphML.getElementsByTagName("key"):
        attrs = dict(
            [(str(a), str(b)) for a, b in keyNode.attributes.items()]
        )
        id = attrs.pop('id')

        if 'for' in attrs and attrs['for'] not in defaults:
            defaults[attrs['for']] = {}

        # Add the desc to the info for this key
        desc = keyNode.getElementsByTagName("desc")
        if len(desc) > 0:
            attrs['desc'] = str(desc[0].childNodes[0].wholeText).strip()

        # Convert the type to a python native type
        if 'attr.type' in attrs.keys():
            attrs['attr.type'] = typeTable[attrs['attr.type']]

        # If there's a default, store it
        default = keyNode.getElementsByTagName("default")
        if len(default) > 0:
            defaults[attrs['for']][id] = attrs['attr.type'](default[0].childNodes[0].wholeText.strip())

        # Dupicate id's are mapped depending on 'for' type
        if id not in keyInfo:
            keyInfo[id] = {}
        if 'for' in attrs:
            keyInfo[id][attrs['for']] = attrs
        else:
            keyInfo[id]['forNotSpecified'] = attrs

    # We read only the first graph in a GraphML file.
    graphs = GraphML.getElementsByTagName('graph')
    if len(graphs) < 1:
        raise ImportError, "No graphs in this file!"

    if len(graphs) > 1 and warningCallback:
        warningCallback("Multiple graphs per file are not supported. "
                        "The first graph in the file will be processed.")

    graphNode = graphs[0]
    attrs = dict(
        [(str(a), str(b)) for a, b in graphNode.attributes.items()]
    )

    if 'edgedefault' not in attrs:
        raise ImportError, "No edge default directedness found!"

    if attrs['edgedefault'] != 'undirected' and warningCallback:
        warningCallback("Directed graphs are not supported. "
                        "Directed edges will be converted.")

    #
    # Set up an index of vertex IDs and edge tuples - this allows
    # us to check uniqueness and also eliminates costly
    # findVertexByID calls.
    #
    vertexIndex = {}
    edgeIndex = {}

    # Read vertices (aka nodes)
    for vertNode in graphNode.getElementsByTagName('node'):
        vertAttrs = dict(
            [(str(a), str(b)) for a, b in vertNode.attributes.items()]
        )
        # Create a dict that maps vertex attribute names to their values
        for dataNode in vertNode.getElementsByTagName('data'):
            dataAttrs = dict(
                [(str(a), str(b)) for a, b in dataNode.attributes.items()]
            )
            if 'node' in keyInfo[dataAttrs['key']]:
                key = keyInfo[dataAttrs['key']]['node']
            else:
                key = keyInfo[dataAttrs['key']]['forNotSpecified']
            if dataNode.childNodes != []:
                if 'attr.type' in key.keys():
                    value = key['attr.type'](dataNode.childNodes[0].wholeText.strip())
                else:
                    value = str(dataNode.childNodes[0].wholeText.strip())
                if 'attr.name' in key.keys():
                    vertAttrs[key['attr.name']] = value

        # Assign defaults
        if len(defaults) > 0 and defaults['node']:
            for prop, value in defaults['node'].items():
                if prop not in vertAttrs:
                    vertAttrs[prop] = value

        # Raise ImportError if vertex is a duplicate
        if vertAttrs['id'] in vertexIndex:
            if yesall_duplicate_vert or yestoall:
                continue
            if queryCallback:
                result = queryCallback("Duplicate vertex detected: id %s" %
                                       (vertAttrs['id']))
                if result == CustomButtonDialog.ID['Yes']:
                    continue
                elif result == CustomButtonDialog.ID['Yes to similar errors']:
                    yesall_duplicate_vert = True
                    continue
                elif result == CustomButtonDialog.ID['Yes to all errors']:
                    yestoall = True
                    continue
                else:
                    raise ImportError, "Import aborted."
            else:
                raise ImportError, ("Duplicate vertex detected: id %s" %
                                    (vertAttrs['id']))

        v = Vertex(id=vertAttrs['id'])

        # Determine the color of the vertex, accepting either
        # r,g,b or red,green,blue for the names of the color attributes
        if ('red' in vertAttrs or 'blue' in vertAttrs or 'green' in vertAttrs or
                    'r' in vertAttrs or 'b' in vertAttrs or 'g' in vertAttrs):
            color = [0.0, 0.0, 0.0]
            if 'red' in vertAttrs:
                color[0] = color[0] + vertAttrs['red']
            elif 'r' in vertAttrs:
                color[0] = color[0] + vertAttrs['r']
            if 'green' in vertAttrs:
                color[1] = color[1] + vertAttrs['green']
            elif 'g' in vertAttrs:
                color[1] = color[1] + vertAttrs['g']
            if 'blue' in vertAttrs:
                color[2] = color[2] + vertAttrs['blue']
            elif 'b' in vertAttrs:
                color[2] = color[2] + vertAttrs['b']
            # If color uses 0 to 255 for colors instead of 0.0 to 1.0, convert
            if color[0] > 1.0 or color[1] > 1.0 or color[2] > 1.0:
                color[0] /= 255
                color[1] /= 255
                color[2] /= 255
            v.color = tuple(color)
        # Determine the color of the vertex if using 'fill' and hex
        elif 'fill' in vertAttrs:
            fail = False
            fillstr = vertAttrs['fill']
            if len(fillstr) == 7:
                r = fillstr[1:3]
                g = fillstr[3:5]
                b = fillstr[5:7]
            elif len(fillstr) == 4:
                r = fillstr[1]
                g = fillstr[2]
                b = fillstr[3]
            else:
                fail = "fill must be of form '#fff' or '#ffffff'"
            if not fail:
                color = [x / 255.0 for x in (int(r, 16), int(g, 16), int(b, 16))]
                v.color = tuple(color)
            elif fail and not yesall_color and not yestoall:
                if queryCallback:
                    result = queryCallback("Invalid vertex fill color (%s): id "
                                           "%s, fill '%s' \n\nUse default color"
                                           "and continue?" %
                                           (fail, id, fillstr), override=True)
                    if result == CustomButtonDialog.ID['Yes']:
                        pass
                    elif result == CustomButtonDialog.ID['Yes to similar errors']:
                        yesall_color = True
                    elif result == CustomButtonDialog.ID['Yes to all errors']:
                        yestoall = True
                    else:
                        raise ImportError, "Import aborted."
                else:
                    raise ImportError, ("Invalid vertex fill color (%s): id %s, "
                                        "fill '%s'" % (fail, id, fillstr))

        # Determine the position of each vertex
        if 'x' in vertAttrs or 'y' in vertAttrs or 'z' in vertAttrs:
            pos = [0.0, 0.0, 0.0]
            if 'x' in vertAttrs and (isinstance(vertAttrs['x'], float) or
                                         isinstance(vertAttrs['x'], int)):
                pos[0] = pos[0] + vertAttrs['x']
            if 'y' in vertAttrs and (isinstance(vertAttrs['y'], float) or
                                         isinstance(vertAttrs['y'], int)):
                pos[1] = pos[1] + vertAttrs['y']
            if 'z' in vertAttrs and (isinstance(vertAttrs['z'], float) or
                                         isinstance(vertAttrs['z'], int)):
                pos[2] = pos[2] + vertAttrs['z']

            v.pos = tuple(pos)

        # Accept either radius or size for the radius of a vertex
        if 'radius' in vertAttrs:
            v.radius = vertAttrs['radius']
        elif 'size' in vertAttrs:
            v.radius = vertAttrs['size']
        # Accept either name or label for the label of a vertex
        if 'name' in vertAttrs:
            v.name = vertAttrs['name']
        elif 'label' in vertAttrs:
            v.name = vertAttrs['label']
        graph.addVertex(v)
        vertexIndex[v.id] = v

    # Read edges
    for edgeNode in graphNode.getElementsByTagName('edge'):
        edgeAttrs = dict(
            [(str(a), str(b)) for a, b in edgeNode.attributes.items()]
        )
        # Create a dict edgeAttrs that maps edge attributes to their values
        for dataNode in edgeNode.getElementsByTagName('data'):
            dataAttrs = dict(
                [(str(a), str(b)) for a, b in dataNode.attributes.items()]
            )
            if 'edge' in keyInfo[dataAttrs['key']]:
                key = keyInfo[dataAttrs['key']]['edge']
            else:
                key = keyInfo[dataAttrs['key']]['forNotSpecified']
            if dataNode.childNodes != []:
                if 'attr.type' in key.keys():
                    value = key['attr.type'](dataNode.childNodes[0].wholeText.strip())
                else:
                    value = str(dataNode.childNodes[0].wholeText.strip())
                if 'attr.name' in key.keys():
                    edgeAttrs[key['attr.name']] = value

        # Assign defaults
        if len(defaults) > 0 and defaults['edge']:
            for prop, value in defaults['edge'].items():
                if prop not in edgeAttrs:
                    edgeAttrs[prop] = value

        # Raise ImportError if edge references a nonexistent vertex, or if
        # it is a duplicate edge, or if source is the same as the target
        if edgeAttrs['source'] not in vertexIndex:
            if yesall_nonexist_vert or yestoall:
                continue
            if queryCallback:
                result = queryCallback("Edge specifies nonexistent source "
                                       "vertex %s" % (edgeAttrs['source']))
                if result == CustomButtonDialog.ID['Yes']:
                    continue
                elif result == CustomButtonDialog.ID['Yes to similar errors']:
                    yesall_nonexist_vert = True
                    continue
                elif result == CustomButtonDialog.ID['Yes to all errors']:
                    yestoall = True
                    continue
                else:
                    raise ImportError, "Import aborted."
            else:
                raise ImportError, ("Edge specifies nonexistent source vertex "
                                    "%s" % (edgeAttrs['source']))
        if edgeAttrs['target'] not in vertexIndex:
            if yesall_nonexist_vert or yestoall:
                continue
            if queryCallback:
                result = queryCallback("Edge specifies nonexistent target "
                                       "vertex %s" % (edgeAttrs['target']))
                if result == CustomButtonDialog.ID['Yes']:
                    continue
                elif result == CustomButtonDialog.ID['Yes to similar errors']:
                    yesall_nonexist_vert = True
                    continue
                elif result == CustomButtonDialog.ID['Yes to all errors']:
                    yestoall = True
                    continue
                else:
                    raise ImportError, "Import aborted."
            else:
                raise ImportError, ("Edge specifies nonexistent target vertex "
                                    "%s" % (edgeAttrs['target']))
        if (edgeAttrs['source'], edgeAttrs['target']) in edgeIndex:
            if yesall_duplicate_edge or yestoall:
                continue
            if queryCallback:
                result = queryCallback("Duplicate edge detected: %s -> %s" %
                                       (edgeAttrs['source'], edgeAttrs['target']))
                if result == CustomButtonDialog.ID['Yes']:
                    continue
                elif result == CustomButtonDialog.ID['Yes to similar errors']:
                    yesall_duplicate_edge = True
                    continue
                elif result == CustomButtonDialog.ID['Yes to all errors']:
                    yestoall = True
                    continue
                else:
                    raise ImportError, "Import aborted."
            else:
                raise ImportError, ("Duplicate edge detected: %s -> %s" %
                                    (edgeAttrs['source'], edgeAttrs['target']))
        if (edgeAttrs['target'], edgeAttrs['source']) in edgeIndex:
            if yesall_duplicate_edge or yestoall:
                continue
            if queryCallback:
                result = queryCallback("Duplicate (reversed) edge detected: "
                                       "%s -> %s" %
                                       (edgeAttrs['source'], edgeAttrs['target']))
                if result == CustomButtonDialog.ID['Yes']:
                    continue
                elif result == CustomButtonDialog.ID['Yes to similar errors']:
                    yesall_duplicate_edge = True
                    continue
                elif result == CustomButtonDialog.ID['Yes to all errors']:
                    yestoall = True
                    continue
                else:
                    raise ImportError, "Import aborted."
            else:
                raise ImportError, ("Duplicate (reversed) edge detected: %s -> %s" %
                                    (edgeAttrs['source'], edgeAttrs['target']))
        if edgeAttrs['source'] == edgeAttrs['target']:
            if yesall_degenerate_edge or yestoall:
                continue
            if queryCallback:
                result = queryCallback("Degenerate edge detected: %s -> %s" %
                                       (edgeAttrs['source'], edgeAttrs['target']))
                if result == CustomButtonDialog.ID['Yes']:
                    continue
                elif result == CustomButtonDialog.ID['Yes to similar errors']:
                    yesall_degenerate_edge = True
                    continue
                elif result == CustomButtonDialog.ID['Yes to all errors']:
                    yestoall = True
                    continue
                else:
                    raise ImportError, "Import aborted."
            else:
                raise ImportError("Degenerate edge detected: %s -> %s" %
                                  (edgeAttrs['source'], edgeAttrs['target']))

        e = Edge(source=vertexIndex[edgeAttrs['source']], \
                 target=vertexIndex[edgeAttrs['target']])

        # Determine the color of the vertex, accepting either
        # r,g,b or red,green,blue for the names of the color attributes
        if ('red' in edgeAttrs or 'blue' in edgeAttrs or 'green' in edgeAttrs or
                    'r' in edgeAttrs or 'b' in edgeAttrs or 'g' in edgeAttrs):
            color = [0.0, 0.0, 0.0]
            if 'red' in edgeAttrs:
                color[0] = color[0] + edgeAttrs['red']
            elif 'r' in edgeAttrs:
                color[0] = color[0] + edgeAttrs['r']
            if 'green' in edgeAttrs:
                color[1] = color[1] + edgeAttrs['green']
            elif 'g' in edgeAttrs:
                color[1] = color[1] + edgeAttrs['g']
            if 'blue' in edgeAttrs:
                color[2] = color[2] + edgeAttrs['blue']
            elif 'b' in edgeAttrs:
                color[2] = color[2] + edgeAttrs['b']
            # If color uses 0 to 255 for colors instead of 0.0 to 1.0, convert
            if color[0] > 1.0 or color[1] > 1.0 or color[2] > 1.0:
                color[0] /= 255
                color[1] /= 255
                color[2] /= 255
            e.color = tuple(color)
        # Determine the color of the edge if using 'fill' and hex
        elif 'fill' in edgeAttrs:
            fail = False
            fillstr = edgeAttrs['fill']
            if len(fillstr) == 7:
                r = fillstr[1:3]
                g = fillstr[3:5]
                b = fillstr[5:7]
            elif len(fillstr) == 4:
                r = fillstr[1]
                g = fillstr[2]
                b = fillstr[3]
            else:
                fail = "fill must be of form '#fff' or '#ffffff'"
            if not fail:
                color = [x / 255.0 for x in (int(r, 16), int(g, 16), int(b, 16))]
                e.color = tuple(color)
            if fail and not yesall_color and not yestoall:
                if queryCallback:
                    result = queryCallback("Invalid edge fill color (%s): "
                                           "%s -> %s, fill '%s' "
                                           "\n\nUse default color and continue?" %
                                           (fail, edgeAttrs['source'],
                                            edgeAttrs['target'], fillstr),
                                           override=True)
                    if result == CustomButtonDialog.ID['Yes']:
                        pass
                    elif result == CustomButtonDialog.ID['Yes to similar errors']:
                        yesall_color = True
                    elif result == CustomButtonDialog.ID['Yes to all errors']:
                        yestoall = True
                    else:
                        raise ImportError, "Import aborted."
                else:
                    raise ImportError, ("Invalid edge fill color (%s): "
                                        "%s -> %s, fill '%s'" %
                                        (fail, edgeAttrs['source'],
                                         edgeAttrs['target'], fillstr))

                # Accept radius, size, or weight for the name of edge radius
        if 'radius' in edgeAttrs:
            e.radius = edgeAttrs['radius']
        elif 'size' in edgeAttrs:
            e.radius = edgeAttrs['size']
        elif 'weight' in edgeAttrs:
            e.radius = edgeAttrs['weight']
        if 'attribute' in edgeAttrs:
            e.attribute = edgeAttrs['attribute']

        graph.addEdge(e)
        edgeIndex[(edgeAttrs['source'], edgeAttrs['target'])] = e
Exemplo n.º 40
0
def load(graph, fobj, queryCallback=None, warningCallback=None):
    """Load .gv or .dot file

    Arguments:
    graph -- the graph to be created from the loaded file
    fobj -- a file object of the DOT file to be read
    queryCallback -- function to display a default query dialog (default None)
    warningCallback -- function to display a default warning dialog
                       (default None)

    """

    # Set global variables to in DOTGraph for automatically replacing
    # attributes of duplicate nodes and edges
    global _yestoall_nodes
    global _yestoall_edges
    _yestoall_nodes = None
    _yestoall_edges = None

    try:
        dotgraph = DOTGraph(Stream(fobj), queryCallback=queryCallback,
                            warningCallback=warningCallback)
    except EOF:
        raise ImportError, "Premature end of file"
    except Unbalanced:
        raise ImportError, "Unbalanced delimiters in file"

    # Boolean variables to control if the rest of the import errors are handled
    # automatically
    yestoall = False
    yesall_color = False
    yesall_degenerate_edge = False

    def getColor(color):
        """Retun an RGB float triple of a color string. Return False if invalid

        Arguments:
        color -- a string representing a color
        """

        # Hex color
        if color[0] == '#' and len(color) == 7:
            fillstr = color
            r = fillstr[1:3]
            g = fillstr[3:5]
            b = fillstr[5:7]
            try:
                color = [x / 255.0 for x in (int(r, 16), int(g, 16), int(b, 16))]
                return color
            except:
                return False

        # HSV float triple
        elif ',' in color or ' ' in color:
            color = color.replace(" ", "").split(',', 3)
            try:
                color = [float(x) for x in color]
                color = colorsys.hsv_to_rgb(color[0], color[1], color[2])
                return color
            except:
                return False
        # X11 Color Name
        else:
            try:
                color = colorByName(color)
                return color
            except UnknownColor:
                return False

    # Add all the vertices in the dotgraph to the context graph
    for vertex, attributes in dotgraph.nodes.items():
        v = Vertex(id=vertex)
        if 'label' in attributes:
            v.name = attributes['label']
        if 'width' in attributes:
            v.radius = float(attributes['width'])
        if 'pos' in attributes:
            # remove ! and spaces, then split numbers
            pos = attributes['pos'][:-1].replace(" ", "").split(',', 3)
            if len(pos) < 3:
                pos.append(0.0)
            v.pos = (float(pos[0]), float(pos[1]), float(pos[2]))
        if 'color' in attributes:
            color = getColor(attributes['color'])
            if color != False:
                v.color = tuple(color)
            elif not yesall_color and not yestoall:
                # Invalid color
                if queryCallback:
                    result = queryCallback("Invalid vertex color %s for %s. "
                                           "Assign default color?" %
                                           (attributes['color'], vertex), True)
                    if result == CustomButtonDialog.ID['Yes']:
                        pass
                    elif result == CustomButtonDialog.ID['Yes to similar errors']:
                        yesall_color = True
                    elif result == CustomButtonDialog.ID['Yes to all errors']:
                        yestoall = True
                    else:
                        raise ImportError, "Import aborted."
                else:
                    raise ImportError("Invalid vertex color %s for %s" %
                                      (attributes['color'], vertex))

        graph.addVertex(v)

    # Add all the edges in the dotgraph to the context grpah
    for edge, attributes in dotgraph.edges.items():
        source = graph.findVertexByID(edge[0])
        target = graph.findVertexByID(edge[1])

        if source == target:
            # Degenerate edge
            if yesall_degenerate_edge or yestoall:
                continue
            if queryCallback:
                result = queryCallback("Degenerate edge detected: %s -> %s" %
                                       (source.id, target.id))
                if result == CustomButtonDialog.ID['Yes']:
                    continue
                elif result == CustomButtonDialog.ID['Yes to similar errors']:
                    yesall_degenerate_edge = True
                    continue
                elif result == CustomButtonDialog.ID['Yes to all errors']:
                    yestoall = True
                    continue
                else:
                    raise ImportError, "Import aborted."
            else:
                raise ImportError("Degenerate edge detected: %s -> %s" %
                                  (source.id, target.id))

        e = Edge(source, target)

        if 'penwidth' in attributes:
            e.radius = float(attributes['penwidth'])
        if 'color' in attributes:
            color = getColor(attributes['color'])
            if color != False:
                e.color = tuple(color)
            elif not yesall_color and not yestoall:
                # Invalid color
                if queryCallback:
                    result = queryCallback("Invalid edge color %s for (%s,%s) "
                                           "Assign default color?" %
                                           (attributes['color'],
                                            edge[0], edge[1]), True)
                    if result == CustomButtonDialog.ID['Yes']:
                        pass
                    elif result == CustomButtonDialog.ID['Yes to similar errors']:
                        yesall_color = True
                    elif result == CustomButtonDialog.ID['Yes to all errors']:
                        yestoall = True
                    else:
                        raise ImportError, "Import aborted."
                else:
                    raise ImportError("Invalid edge color %s for (%s,%s)" %
                                      (attributes['color'], edge[0], edge[1]))
        graph.addEdge(e)
Exemplo n.º 41
0
def load(graph, fobj, queryCallback=None, warningCallback=None):
    """Load .gml file

    Arguments:
    graph -- the graph to be created from the loaded file
    fobj -- a file object of the GML file to be read
    queryCallback -- function to display a default query dialog (default None)
    warningCallback -- function to display a default warning dialog
                       (default None)

    """

    try:
        root = GMLList(Stream(fobj))
    except EOF:
        raise ImportError, "Premature end of file"
    except Unbalanced:
        raise ImportError, "Unbalanced delimiters in file"
    except TypeMismatch:
        raise ImportError, "Unintelligible value in file"
    except EOList:
        #!!! shouldn't happen
        raise ImportError, "Internal error"

    #XXX#
    #XXX# Debugging print the tree
    #XXX#
    def traverse(a, i=0):
        if i <= 0:
            print ""
            print ""

        if isinstance(a, GMLList):
            print ("    " * i) + repr(a)
            for k, v in a.data.items():
                print "    " * i + "  " + repr(k)
                for x in v:
                    traverse(x.data, i=i + 1)
        else:
            print ("    " * i) + repr(a)

    #XXX#
    #XXX#
    #XXX#

    if 'graph' not in root.data:
        raise ImportError, "No graphs in file." % str(root.data)

    # We only load the first graph in the file.
    if len(root.data['graph']) > 1 and warningCallback:
        warningCallback("GLuskap does not support multiple graphs per file. "
                        "The first graph in the file will be processed.")

    # Check GML version if it is supported
    if 'version' in root.data and root.data['version'][0].data != 1:
        if queryCallback:
            result = queryCallback("Unsupported GML version %s."
                                   "\n\nWould you like to continue?" % str(root.data['version'][0].data),
                                   override=True,
                                   buttons=['Yes', 'No'])
            if result == CustomButtonDialog.ID['Yes']:
                pass
            else:
                raise ImportError, "Import aborted."
        else:
            raise ImportError, "Unsupported GML version %s." % str(root.data['version'][0].data)

    graphbranch = root.data['graph'][0].data
    if not isinstance(graphbranch, GMLList):
        raise ImportError, "GML format error: graph is not a List"

    if 'directed' in graphbranch.data and graphbranch.data['directed'] != 0 and warningCallback:
        warningCallback("GLuskap does not support directed graphs. "
                        "All edges will be processed as undirected.")

    # Boolean variables to control if the rest of the import errors are handled
    # automatically
    yestoall = False
    yesall_duplicate_vert = False
    yesall_duplicate_edge = False
    yesall_degenerate_edge = False
    yesall_color = False
    yesall_nonexist_vert = False
    yesall_invalid_bends = False

    #
    # Vertices (Nodes)
    #
    vertexIndex = {}

    for vxb in graphbranch.data['node']:
        vxbranch = vxb.data
        if not isinstance(vxbranch, GMLList):
            raise ImportError, ("GML format error: node '%s' is not a List" %
                                (str(vxbranch)))
        if 'id' not in vxbranch.data:
            raise ImportError, "GML format error: node without ID"
        #
        # Extension - we allow node IDs of type String as well as
        # integer.
        #
        if not isinstance(vxbranch.data['id'][0].data, (int, GMLString)):
            raise ImportError, ("GML format error: node ID '%s' of "
                                "unsupportedtype" % (vxbranch.data['id'][0].data))

        id = str(vxbranch.data['id'][0].data)
        if id in vertexIndex:
            # Duplicate vertex
            if yesall_duplicate_vert or yestoall:
                continue
            if queryCallback:
                result = queryCallback("Duplicate vertex detected: id %s" % (id))
                if result == CustomButtonDialog.ID['Yes']:
                    continue
                elif result == CustomButtonDialog.ID['Yes to similar errors']:
                    yesall_duplicate_vert = True
                    continue
                elif result == CustomButtonDialog.ID['Yes to all errors']:
                    yestoall = True
                    continue
                else:
                    raise ImportError, "Import aborted."
            else:
                raise ImportError, "Duplicate vertex detected: id %s" % (id)

        v = Vertex(id=id)

        if 'label' in vxbranch.data:
            v.name = str(vxbranch.data['label'][0].data)
        if 'graphics' in vxbranch.data:
            pos = list(v.pos)
            rad = v.radius
            color = list(v.color)
            grbranch = vxbranch.data['graphics'][0].data

            if 'x' in grbranch.data:
                pos[X_AXIS] = float(grbranch.data['x'][0].data)
            if 'y' in grbranch.data:
                pos[Y_AXIS] = float(grbranch.data['y'][0].data)
            if 'z' in grbranch.data:
                pos[Z_AXIS] = float(grbranch.data['z'][0].data)
            if 'w' in grbranch.data:
                radius = float(grbranch.data['w'][0].data)
            if 'h' in grbranch.data:
                radius = max(radius, float(grbranch.data['h'][0].data))
            if 'd' in grbranch.data:
                radius = max(radius, float(grbranch.data['d'][0].data))
            if 'fill' in grbranch.data:
                fail = False
                fillstr = grbranch.data['fill'][0].data
                if not isinstance(fillstr, GMLString):
                    fail = True
                    fail = "fill must be a String"
                elif not len(str(fillstr)) > 0:
                    fail = "fill string too short"
                elif str(fillstr)[0] != '#':
                    # Named color
                    try:
                        color = colorByName(str(fillstr))
                    except UnknownColor:
                        fail = "unrecognized named color"
                else:
                    # Hex color
                    fillstr = str(fillstr)
                    if len(fillstr) == 7:
                        r = fillstr[1:3]
                        g = fillstr[3:5]
                        b = fillstr[5:7]
                    elif len(fillstr) == 4:
                        r = fillstr[1]
                        g = fillstr[2]
                        b = fillstr[3]
                    else:
                        fail = "fill must be of form '#fff' or '#ffffff'"

                    if not fail:
                        color = [x / 255.0 for x in (int(r, 16), int(g, 16), int(b, 16))]
                if fail and not yesall_color and not yestoall:
                    # Invalid vertex color
                    if queryCallback:
                        result = queryCallback("Invalid vertex fill color (%s): "
                                               "id %s, fill '%s' "
                                               "\n\nUse default color and continue?" %
                                               (fail, id, fillstr),
                                               override=True)
                        if result == CustomButtonDialog.ID['Yes']:
                            pass
                        elif result == CustomButtonDialog.ID['Yes to similar errors']:
                            yesall_color = True
                        elif result == CustomButtonDialog.ID['Yes to all errors']:
                            yestoall = True
                        else:
                            raise ImportError, "Import aborted."
                    else:
                        raise ImportError, ("Invalid vertex fill color (%s): "
                                            "id %s, fill '%s'" %
                                            (fail, id, fillstr))
            #
            # Apply attributes
            #
            v.pos = tuple(pos)
            v.radius = radius
            v.color = tuple(color)

        graph.addVertex(v)
        vertexIndex[v.id] = v

    #
    # Edges
    #
    edgeIndex = {}

    for edgeb in graphbranch.data['edge']:
        edgebranch = edgeb.data
        if not isinstance(edgebranch, GMLList):
            raise ImportError, ("GML format error: edge '%s' is not a List" %
                                (str(edgebranch)))
        if 'source' not in edgebranch.data:
            raise ImportError, "GML format error: edge without source"
        if 'target' not in edgebranch.data:
            raise ImportError, "GML format error: edge without target"
        #
        # Extension - we allow node IDs of type String as well as
        # integer.
        #
        if not isinstance(edgebranch.data['source'][0].data, (int, GMLString)):
            raise ImportError, ("GML format error: edge source ID '%s' "
                                "of unsupported type" %
                                (edgebranch.data['source'][0].data))
        if not isinstance(edgebranch.data['target'][0].data, (int, GMLString)):
            raise ImportError, ("GML format error: edge target ID '%s' "
                                "of unsupported type" %
                                (edgebranch.data['target'][0].data))

        src = str(edgebranch.data['source'][0].data)
        tgt = str(edgebranch.data['target'][0].data)
        if src not in vertexIndex:
            # Nonexistent source vertex
            if yesall_nonexist_vert or yestoall:
                continue
            if queryCallback:
                result = queryCallback("Edge specifies nonexistent "
                                       "source vertex %s" % (src))
                if result == CustomButtonDialog.ID['Yes']:
                    continue
                elif result == CustomButtonDialog.ID['Yes to similar errors']:
                    yesall_nonexist_vert = True
                    continue
                elif result == CustomButtonDialog.ID['Yes to all errors']:
                    yestoall = True
                    continue
                else:
                    raise ImportError, "Import aborted."
            else:
                raise ImportError, ("Edge specifies nonexistent "
                                    "source vertex %s" % (src))
        if tgt not in vertexIndex:
            # Nonexistent target vertex
            if yesall_nonexist_vert or yestoall:
                continue
            if queryCallback:
                result = queryCallback("Edge specifies nonexistent target "
                                       "vertex %s" % (tgt))
                if result == CustomButtonDialog.ID['Yes']:
                    continue
                elif result == CustomButtonDialog.ID['Yes to similar errors']:
                    yesall_nonexist_vert = True
                    continue
                elif result == CustomButtonDialog.ID['Yes to all errors']:
                    yestoall = True
                    continue
                else:
                    raise ImportError, "Import aborted."
            else:
                raise ImportError, ("Edge specifies nonexistent "
                                    "target vertex %s" % (tgt))

        e = Edge(source=vertexIndex[src], target=vertexIndex[tgt])

        if (src, tgt) in edgeIndex:
            # Duplicate edge
            if yesall_duplicate_edge or yestoall:
                continue
            if queryCallback:
                result = queryCallback("Duplicate edge detected: "
                                       "%s -> %s" % (src, tgt))
                if result == CustomButtonDialog.ID['Yes']:
                    continue
                elif result == CustomButtonDialog.ID['Yes to similar errors']:
                    yesall_duplicate_edge = True
                    continue
                elif result == CustomButtonDialog.ID['Yes to all errors']:
                    yestoall = True
                    continue
                else:
                    raise ImportError, "Import aborted."
            else:
                raise ImportError, ("Duplicate edge detected:"
                                    "%s -> %s" % (src, tgt))
        if (tgt, src) in edgeIndex:
            # Reversed Duplicate edge
            if yesall_duplicate_edge or yestoall:
                continue
            if queryCallback:
                result = queryCallback("Duplicate (reversed) edge detected: "
                                       "%s -> %s" % (src, tgt))
                if result == CustomButtonDialog.ID['Yes']:
                    continue
                elif result == CustomButtonDialog.ID['Yes to similar errors']:
                    yesall_duplicate_edge = True
                    continue
                elif result == CustomButtonDialog.ID['Yes to all errors']:
                    yestoall = True
                    continue
                else:
                    raise ImportError, "Import aborted."
            else:
                raise ImportError, ("Duplicate (reversed) edge detected: "
                                    "%s -> %s" % (src, tgt))
        if src == tgt:
            # Degenerate edge
            if yesall_degenerate_edge or yestoall:
                continue
            if queryCallback:
                result = queryCallback("Degenerate edge detected: %s -> %s" %
                                       (src, tgt))
                if result == CustomButtonDialog.ID['Yes']:
                    continue
                elif result == CustomButtonDialog.ID['Yes to similar errors']:
                    yesall_degenerate_edge = True
                    continue
                elif result == CustomButtonDialog.ID['Yes to all errors']:
                    yestoall = True
                    continue
                else:
                    raise ImportError, "Import aborted."
            else:
                raise ImportError, ("Degenerate edge detected: %s -> %s" %
                                    (src, tgt))

        if 'label' in edgebranch.data:
            e.attribute = str(edgebranch.data['label'][0].data)

        grbranch = None
        if 'graphics' in edgebranch.data:
            rad = e.radius
            color = list(e.color)
            grbranch = edgebranch.data['graphics'][0].data

            if 'width' in grbranch.data:
                e.radius = float(grbranch.data['width'][0].data)
            if ('type' in grbranch.data and
                        str(grbranch.data['type'][0].data) != "line" and
                    warningCallback):
                warningCallback("Edge of graphic type '%s' converted to line."
                                % str(grbranch.data['type'][0].data))

            if 'fill' in grbranch.data:
                fail = False
                fillstr = grbranch.data['fill'][0].data
                if not isinstance(fillstr, GMLString):
                    fail = True
                    fail = "fill must be a String"
                elif not len(str(fillstr)) > 0:
                    fail = "fill string too short"
                elif str(fillstr)[0] != '#':
                    # Named color
                    try:
                        color = colorByName(str(fillstr))
                    except UnknownColor:
                        fail = "unrecognized named color"
                else:
                    # Hex color
                    fillstr = str(fillstr)
                    if len(fillstr) == 7:
                        r = fillstr[1:3]
                        g = fillstr[3:5]
                        b = fillstr[5:7]
                    elif len(fillstr) == 4:
                        r = fillstr[1]
                        g = fillstr[2]
                        b = fillstr[3]
                    else:
                        fail = "fill must be of form '#fff' or '#ffffff'"

                    if not fail:
                        color = [x / 255.0 for x in (int(r, 16), int(g, 16), int(b, 16))]
                if fail and not yesall_color and not yestoall:
                    # Invalid edge fill color
                    if queryCallback:
                        result = queryCallback("Invalid edge fill color (%s): "
                                               "%s -> %s, fill '%s'"
                                               "\n\nUse default color and continue?" %
                                               (fail, src, tgt, fillstr),
                                               override=True)
                        if result == CustomButtonDialog.ID['Yes']:
                            pass
                        elif result == CustomButtonDialog.ID['Yes to similar errors']:
                            yesall_color = True
                        elif result == CustomButtonDialog.ID['Yes to all errors']:
                            yestoall = True
                        else:
                            raise ImportError, "Import aborted."
                    else:
                        raise ImportError, ("Invalid edge fill color (%s): "
                                            "%s -> %s, fill '%s'" %
                                            (fail, src, tgt, fillstr))


            #
            # Apply attributes
            #
            e.color = tuple(color)

        graph.addEdge(e)
        edgeIndex[(src, tgt)] = e

        #
        # Handle bending edges here
        #
        if grbranch != None and 'line' in grbranch.data:
            linebranch = grbranch.data['line'][0].data
            if 'point' in linebranch.data:
                if len(linebranch.data['point']) < 2:
                    if yestoall or yesall_invalid_bends:
                        continue
                    # Insufficient number of bendpoints
                    if queryCallback:
                        result = queryCallback("Insufficient number of points"
                                               " for edge %s -> %s" % (src, tgt))
                        if result == CustomButtonDialog.ID['Yes']:
                            pass
                        elif result == CustomButtonDialog.ID['Yes to similar errors']:
                            yesall_invalid_bends = True
                        elif result == CustomButtonDialog.ID['Yes to all errors']:
                            yestoall = True
                        else:
                            raise ImportError, "Import aborted."
                    else:
                        raise ImportError, ("Insufficient number of points"
                                            "for edge %s -> %s" % (src, tgt))
                else:
                    # Delete the first and last points - those are the src and tgt
                    del linebranch.data['point'][0]
                    del linebranch.data['point'][-1]
                    tmpEdge = e
                    tgtVx = e.target
                    for ptb in linebranch.data['point']:
                        ptbranch = ptb.data
                        pos = [0.0, 0.0, 0.0]
                        if 'x' in ptbranch.data:
                            pos[X_AXIS] = float(ptbranch.data['x'][0].data)
                        if 'y' in ptbranch.data:
                            pos[Y_AXIS] = float(ptbranch.data['y'][0].data)
                        if 'z' in ptbranch.data:
                            pos[Z_AXIS] = float(ptbranch.data['z'][0].data)
                        bendVx = graph.bendEdge(tmpEdge, tuple(pos))

                        tmpEdge = graph.findEdgeBetween(bendVx, tgtVx)[0]