Python 使用邻接列表实现图形表示时要使用哪种数据结构
我有一个非常大的图,大约1000000个节点和许多边。这就是我想要知道的,在实现邻接列表时,哪种数据结构最适合。以下是我一直跟踪的对象Python 使用邻接列表实现图形表示时要使用哪种数据结构,python,data-structures,graph,adjacency-list,Python,Data Structures,Graph,Adjacency List,我有一个非常大的图,大约1000000个节点和许多边。这就是我想要知道的,在实现邻接列表时,哪种数据结构最适合。以下是我一直跟踪的对象 边缘列表 节点到节点连接列表 我使用python进行编码,所以我使用了一个集合(因为根据它,平均插入时间为o(1))作为边缘列表,使用了一个字典作为节点到节点的连接列表(通过使它完全可根据上下文进行散列)。这是我的密码 class node: def __init__(self, name = ""): self.__name = n
- 边缘列表
- 节点到节点连接列表
class node:
def __init__(self, name = ""):
self.__name = name
def getName(self):
return self.__name
def __str__(self):
return self.__name
def __hash__(self):
return hash(self.__name)
def __lt__(self, other):
if(type(self) != type(other)):
return NotImplemented
return self.__name.__lt__(other.__name)
def __eq__(self, other):
if(type(self)) != type(other):
return NotImplemented
return self.__name == other.__name
class Edge:
def __init__(self, name = "", node1 = None, node2 = None, weight = 0):
self.__name = name
self.__firstNode = node1
self.__secondNode = node2
self.__weight = weight
def getName(self):
return self.__name
def getFirstNode(self):
return self.__firstNode
def getSecondNode(self):
return self.__secondNode
def getWeight(self):
return self.__weight
def __lt__(self, other):
if(type(self) != type(other)):
return NotImplemented
return self.__name.__lt__(other.__name) and self.__firstNode.__lt__(other.__firstNode) and self.__secondNode.__lt__(other.__secondNode) and self.__weight.__lt__(other.__weight)
def __eq__(self, other):
if(type(self) != type(other)):
return NotImplemented
return self.__name == other.__name and self.__firstNode == other.__firstNode and self.__secondNode == other.__secondNode and self.__weight == other.__weight
def __str__(self):
return self.__name + " " + str(self.__firstNode) + " " + str(self.__secondNode) + " " + str(self.__weight)
def __hash__(self):
return hash(hash(self.__name) + hash(self.__firstNode) + hash(self.__secondNode) + hash(self.__weight))
class graph:
def __init__(self):
self.__nodeToNode = {}
self.__edgeList = set()
def addEdge(self, edge):
if(type(edge) != type(Edge())):
return False
self.__edgeList.add(edge)
if(not edge.getFirstNode() in self.__nodeToNode):
self.__nodeToNode[edge.getFirstNode()] = set()
self.__nodeToNode[edge.getFirstNode()].add(edge.getSecondNode())
if(not edge.getSecondNode() in self.__nodeToNode):
self.__nodeToNode[edge.getSecondNode()] = set()
self.__nodeToNode[edge.getSecondNode()].add(edge.getSecondNode())
return True
def getNodes(self):
return dict(self.__nodeToNode)
def getEdges(self):
return set(self.__edgeList)
import string
import random
import time
grp = graph()
nodes = [None] * 20000
for i in range(20000):
st = ''.join(random.SystemRandom().choice(string.ascii_letters) for i in range(10))
node1 = node(st)
nodes[i] = node1
current = time.time()
for i in range(3000000):
rdm = random.randint(0, 199)
rdm2 = random.randint(0, 199)
st = ''.join(random.SystemRandom().choice(string.ascii_letters) for i in range(10))
eg = Edge(st, nodes[rdm], nodes[rdm2])
grp.addEdge(eg)
last = time.time()
print((last - current))
nodes = grp.getNodes()
edges = grp.getEdges()
但是这段代码运行得很慢,我能让它更快吗?如果是,请使用什么数据结构?让我介绍一种创建邻接列表的方法: 假设您有如下输入:
4 4
1 2
3 2
4 3
1 4
4 4
1 2 3 # edge(1, 2) has the weight of 3
3 2 1
4 3 1
1 4 2
input = sys.stdin.read()
data = list(map(int, input.split()))
n, m = data[0:2]
data = data[2:]
edges = list(zip(zip(data[0:(3 * m):3], data[1:(3 * m):3]), data[2:(3 * m):3]))
data = data[3 * m:]
adj = [[] for _ in range(n)]
cost = [[] for _ in range(n)]
for ((a, b), w) in edges:
adj[a - 1].append(b - 1)
cost[a - 1].append(w)
第一行包含两个数字V
和E
,下一行E
定义了两个顶点之间的边
您可以创建一个.txt文件并读取输入,也可以通过sys.stdin.read()
直接键入:
让我们输出邻接列表adj
:
>>> print(adj)
[[1, 3], [0, 2], [1, 3], [2, 0]]
adj[0]
有两个adj节点:1和3。这意味着节点1有两个adj节点:2和4
现在,如果您想要一个有向加权图,只需修改如下输入:
4 4
1 2
3 2
4 3
1 4
4 4
1 2 3 # edge(1, 2) has the weight of 3
3 2 1
4 3 1
1 4 2
input = sys.stdin.read()
data = list(map(int, input.split()))
n, m = data[0:2]
data = data[2:]
edges = list(zip(zip(data[0:(3 * m):3], data[1:(3 * m):3]), data[2:(3 * m):3]))
data = data[3 * m:]
adj = [[] for _ in range(n)]
cost = [[] for _ in range(n)]
for ((a, b), w) in edges:
adj[a - 1].append(b - 1)
cost[a - 1].append(w)
将权重存储在成本中,例如,成本[0][1]
=3,成本[0][3]
=2
希望这有帮助 您是想自己编写代码,还是对第三方解决方案感到满意?如果是,您可能需要查看图形数据库Neo4j(),或者python图形包。@Jaco我会检查它,但这是学校项目,我必须自己使用networkx库对其进行编码。(). 存在添加节点、边和权重的简单函数。另外,绘制节点和边也很容易。谢谢,但我不想使用任何库