简体   繁体   中英

Read a file with an edge list for a graph and create adjacency list in Python

My program creates a complete graph, prints the edges, and then creates an adjacency list. However, it's not efficient. I would like for the program to:

  1. print the edges list into a text file and then
  2. have the Create Adjacency List portion of the program to read that edge list file and print the adjacency list. Currently, I hard code the edge list into the program which is not efficient because I need to have the ability to change V to test different runtimes.
import networkx as nx
import matplotlib.pyplot as plt

#Create complete graph
complete_graph = nx.complete_graph(10)
plt.subplot(121)
nx.draw(complete_graph, with_labels=True, font_weight='bold')

#list edges -----I want this to output to a file instead
list(complete_graph.edges)

# A class to represent the adjacency list of the node 
class AdjNode: 
    def __init__(self, data): 
        self.vertex = data 
        self.next = None
  
# A class to represent a graph. A graph 
# is the list of the adjacency lists. 
# Size of the array will be the no. of the 
# vertices "V" 

class Graph: 
    def __init__(self, vertices): 
        self.V = vertices 
        self.graph = [None] * self.V 
  
    # Function to add an edge in an undirected graph 
    def add_edge(self, src, dest): 
        # Adding the node to the source node 
        node = AdjNode(dest) 
        node.next = self.graph[src] 
        self.graph[src] = node 
  
        # Adding the source node to the destination as 
        # it is the undirected graph 
        node = AdjNode(src) 
        node.next = self.graph[dest] 
        self.graph[dest] = node 
  
    # Function to print the graph 
    def print_graph(self): 
        for i in range(self.V): 
            print("Adjacency list of vertex {}\n head".format(i), end="") 
            temp = self.graph[i] 
            while temp: 
                print(" -> {}".format(temp.vertex), end="") 
                temp = temp.next
            print(" \n") 
  
  
# Driver program to the above graph class. -----> instead of coding each edge, I'd like for main to 
# read the edge text file created earlier to create the Adjacency List. 
if __name__ == "__main__": 
    V = 10
    graph = Graph(V) 
    graph.add_edge(0, 1) 
    graph.add_edge(0, 2) 
    graph.add_edge(0, 3) 
    graph.add_edge(0, 4) 
    graph.add_edge(0, 5) 
    graph.add_edge(0, 6) 
    graph.add_edge(0, 7) 
    graph.add_edge(0, 8)
    graph.add_edge(0, 9)
    graph.add_edge(1, 2)
    graph.add_edge(1, 3)
    graph.add_edge(1, 4)
    graph.add_edge(1, 5)
    graph.add_edge(1, 6)
    graph.add_edge(1, 7)
    graph.add_edge(1, 8)
    graph.add_edge(1, 9)
    graph.add_edge(2, 3)
    graph.add_edge(2, 4)
    graph.add_edge(2, 5)
    graph.add_edge(2, 6)
    graph.add_edge(2, 7)
    graph.add_edge(2, 8)
    graph.add_edge(2, 9)
    graph.add_edge(3, 4)
    graph.add_edge(3, 5)
    graph.add_edge(3, 6)
    graph.add_edge(3, 7)
    graph.add_edge(3, 8)
    graph.add_edge(3, 9)
    graph.add_edge(4, 5)
    graph.add_edge(4, 6)
    graph.add_edge(4, 7)
    graph.add_edge(4, 8)
    graph.add_edge(4, 9)
    graph.add_edge(5, 6)
    graph.add_edge(5, 7)
    graph.add_edge(5, 8)
    graph.add_edge(5, 9)
    graph.add_edge(6, 7)
    graph.add_edge(6, 8)
    graph.add_edge(6, 9)
    graph.add_edge(7, 8)
    graph.add_edge(7, 9)
    graph.add_edge(8, 9)
    
    graph.print_graph() 

Output:

Adjacency list of vertex 0
 head -> 9 -> 8 -> 7 -> 6 -> 5 -> 4 -> 3 -> 2 -> 1 

Adjacency list of vertex 1
 head -> 9 -> 8 -> 7 -> 6 -> 5 -> 4 -> 3 -> 2 -> 0 

Adjacency list of vertex 2
 head -> 9 -> 8 -> 7 -> 6 -> 5 -> 4 -> 3 -> 1 -> 0 

Adjacency list of vertex 3
 head -> 9 -> 8 -> 7 -> 6 -> 5 -> 4 -> 2 -> 1 -> 0 

Adjacency list of vertex 4
 head -> 9 -> 8 -> 7 -> 6 -> 5 -> 3 -> 2 -> 1 -> 0 

Adjacency list of vertex 5
 head -> 9 -> 8 -> 7 -> 6 -> 4 -> 3 -> 2 -> 1 -> 0 

Adjacency list of vertex 6
 head -> 9 -> 8 -> 7 -> 5 -> 4 -> 3 -> 2 -> 1 -> 0 

Adjacency list of vertex 7
 head -> 9 -> 8 -> 6 -> 5 -> 4 -> 3 -> 2 -> 1 -> 0 

Adjacency list of vertex 8
 head -> 9 -> 7 -> 6 -> 5 -> 4 -> 3 -> 2 -> 1 -> 0 

Adjacency list of vertex 9
 head -> 8 -> 7 -> 6 -> 5 -> 4 -> 3 -> 2 -> 1 -> 0 

The easiest way to complete what you want will be serializing and deserializing it with json.

You will have a method in Graph like this:

import json

def serialize(self) -> str:
    graph = {}
    for i in range(self.V): 
        temp = self.graph[i]
        tmp_list = []
        while temp:
            tmp_list.append(temp)
            temp = temp.next
        graph[i] = json.dumps(tmp_list).replace(",", "->")
    return json.dumps(graph, indent=4)

It will return strings formatted like the following one:

{
    "3": "[1->2->3]",
    "5": "[1->2->3]"
}

You can save it to the file or do whatever you want.

For the deserialization we will need another method:

@staticmethod
def deserialize(serialized: str) -> "Graph":
    serialized = serialized.replace("->", ",")
    graph_dict = json.loads(serialized)
    V = len(graph_dict)
    graph = Graph(V) 
    for src in graph_dict.keys():
        for dest in  graph_dict[src]:
            graph.add_edge(src, dest)
    return graph

The more authentic way to do it would be to write your own serialization format and to parse it back in deserialization with the Interpreter Pattern or to write a grammar and parse with lark .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM