1. 程式人生 > >圖論演算法初步-圖的python實現

圖論演算法初步-圖的python實現

圖的基本性質

圖的分類:圖可以分為有向圖和無向圖,如圖為無向圖:
這裡寫圖片描述

另外,還可以將圖分為有權圖和無權圖,權表示兩個節點之間的某種關係,比如交通運輸網路中兩個地點的權值可以代表交通費用,如圖為有向圖:
這裡寫圖片描述

連通性:有時候,可能有兩個區域的交通路線是沒有相連的,這就會產生很多不連通的區域,如圖就是不完全連通的:
這裡寫圖片描述

簡單圖
這裡寫圖片描述

圖的表示方法

鄰接矩陣
如圖為一個無向圖,要用具體的數值表示節點之間的關係,可以使用鄰接矩陣,假設這個矩陣是A,Aij就表示第i個節點和第j個節點是否相連,為1表示相連,0表示不相連。
這裡寫圖片描述
除此之外,還可以使用鄰接矩陣表示有向圖:
這裡寫圖片描述

鄰接表
用鄰接矩陣來表示,每一行表示一個節點與其他所有節點是否相連,但對於鄰接表來說,一行只代表和他相連的節點:
這裡寫圖片描述


可見鄰接表在空間上是更省資源的。
鄰接表適合表示稀疏圖,鄰接矩陣適合表示稠密圖。

圖的python實現

鄰接矩陣

class DenseGraph:
    def __init__(self,n,directed = False):
        self.n = n # number of vertex
        self.m = 0 #number of edge
        self.directed = directed
        self.matrix = [[0 for i in  range(n)] for i in range(n)]

    def
__str__(self):
for line in self.matrix: print(str(line)) return '' # must return string def getNumberOfEdge(self): return self.m def getNumberOfVertex(self): return self.n def hasEdge(self,v,w): if 0 <= v <= self.n and 0 <= w <= self.n: return
self.matrix[v][w] else: raise Exception("vertex not in the Graph") def addEdge(self,v,w): if 0 <= v <= self.n and 0 <= w <= self.n: if self.hasEdge(v,w): return self.matrix[v][w]= 1 if self.directed is False: self.matrix[w][v] = 1 self.m += 1 else: raise Exception("vertex not in the Graph")

鄰接表

lass Vertex(object):
    def __init__(self,key):
        self.id = key
        self.connectedTo = {} #the key is vertex,value is weight

    def addNeighbor(self, nbr, weight=0):
        self.connectedTo[nbr] = weight

    def __str__(self):
        return str(self.id) + ' connectedTo: ' + str([x.id for x in self.connectedTo])

    def getConnections(self):
        return self.connectedTo.keys()

    def getConnectionsId(self):
        idList = []
        for k in self.connectedTo.keys():
            idList.append(k.getId())
        return sorted(idList)

    def getConnectionsIdAndWeight(self):
        idList = []
        for k in self.connectedTo.keys():
            idList.append(k.getId())
        weightList = list(self.connectedTo.values())
        return {idList[i]: weightList[i] for i in range(len(idList))}

    def getWeight(self, nbr):
        return self.connectedTo[nbr]

    def getId(self):
        return self.id


class SparseGraph(object):
    def __init__(self,directed=False,weighted=False):
        self.vertDict = {} #key is the id of vertex,value is vertex
        self.numVertices = 0
        self.directed=directed
        self.weighted=weighted

    def addVertex(self,key):
        self.numVertices = self.numVertices + 1
        newVertex = Vertex(key)
        self.vertDict[key] = newVertex
        return newVertex

    def getVertex(self,n):
        if n in self.vertDict:
            return self.vertDict[n]
        else:
            return None

    def __contains__(self,n):
        return n in self.vertDict

    def addEdge(self,f,t,weight=0):
        if f not in self.vertDict:
            self.addVertex(f)
        if t not in self.vertDict:
            self.addVertex(t)
        self.vertDict[f].addNeighbor(self.vertDict[t], weight)
        if self.directed is False:
            self.vertDict[t].addNeighbor(self.vertDict[f], weight)

    def getVertices(self):
        return list(self.vertDict.keys())

    def getVertNum(self):
        return self.numVertices

    def __iter__(self):
        return iter(self.vertDict.values())

    def getAllInfo(self):
        verticesList=[int(x) for x in list(self.getVertices())]
        verticesList.sort()
        if self.weighted:
            for i in range(len(verticesList)):
                print('vertex %s : %s' % (i, self.getVertex(i).getConnectionsIdAndWeight()))
        else:
            for i in range(len(verticesList)):
                print('vertex %s : %s' %(i,self.getVertex(i).getConnectionsId()))

打印出來看一下:

def buildGraphFromFile(aGraph,filePath):
    graphList=[]
    with open(filePath,'r',encoding='utf-8') as f:
        for line in f:
            graphList.append([int(x) for x in re.split(r'\s+',line.strip())])
    for i in range(len(graphList)):
        aGraph.addEdge(graphList[i][0],graphList[i][1])


# g1=DenseGraph(13)  #必須填入正確的結點個數。。。我真的覺得鄰接矩陣不好用
# buildGraphFromFile(g1,'/Users/huanghuaixian/desktop/testG1.txt')
# print(g1)


g2=SparseGraph()
buildGraphFromFile(g2,'/Users/huanghuaixian/desktop/testG2.txt')
g2.getAllInfo()