如何解决如何找到图形的所有路径
更新 感谢一些社区成员的评论,我意识到存在一些类似的问题,但它们可能有点不同,请允许我进一步解释。 我其实希望在一个实际问题中使用相同的方法,所以简单地说:
- 完全允许重复使用不同路径中的边
- 从 A 到 B 的唯一(或新)路径被定义为具有任何不同顶点的顶点集合。
让我使用 Bradley .N Miller 和 David L. Ranum 来自 Python 数据结构和算法分析的测验来解释我的问题。
问题: 考虑将单词 FOOL 转换为 SAGE 的任务,也称为单词阶梯问题。在解决 在单词阶梯问题中,一次只能替换一个字母,每一步的结果必须是一个单词,不能不存在。
输入:
FOUL
FOOL
FOIL
FAIL
COOL
FALL
POOL
PALL
POLL
POLE
PALE
PAGE
SALE
POPE
POPE
SAGE
我们可以很容易地找到从 FOOL 到 SAGE 的路径,正如 Bradley 所示: enter image description here
class Vertex:
def __init__(self,key,value = None):
self.id = key
self.connectedTo = {}
self.color = 'white'
self.dist = sys.maxsize
self.pred = []
self.disc = 0
self.fin = 0
self.value = value,#self.GraphBulided = False
self.traverseIndex = 0
self.prednum = 0
def addNeighbor(self,nbr,weight=0):
self.connectedTo[nbr] = weight
def __str__(self):
return '{} connectedTo: {}'.format(self.id,\
str([x.id for x in self.connectedTo]))
def setColor(self,color):
self.color = color
def setdistance(self,d):
self.dist = d
#I want store all Pred for next traverse so I use a list to do it
def setPred(self,p,list = False):
if not list:
self.pred = p
else:
self.pred.append(p)
self.prednum += 1
def setdiscovery(self,dtime):
self.disc = dtime
def setFinish(self,ftime):
self.fin = ftime
#def setGraphBulided(self,tag = True):
# self.GraphBulided = tag
def getFinish(self):
return self.fin
def getdiscovery(self):
return self.disc
def getPred(self):
if isinstance(self.pred,list):
if self.traverseIndex < self.prednum:
return self.pred[self.traverseIndex]
else:
return self.pred[-1]
else:
return self.pred
def __hash__(self):
return hash(self.id)
def getPredById(self):
if self.traverseIndex < self.prednum and isinstance(self.pred,list):
pred = self.pred[self.traverseIndex]
self.traverseIndex += 1
print("vertix {}: {} of {} preds".format(self.id,self.traverseIndex,self.prednum))
return [pred,self.traverseIndex]
else:
pred = None
return [pred,None]
def getCurrPredStaus(self):
#if not self.pred:
# return None
return self.prednum - self.traverseIndex
def getdistance(self):
return self.dist
def getColor(self):
return self.color
def getConnections(self):
return self.connectedTo.keys()
def getId(self):
return self.id
def getWeight(self,nbr):
return self.connectedTo[nbr]
def getValue(self):
return self.value
def findpath(self,dest):
pass
class Graph:
def __init__(self):
self.vertList = {}
self.numVertics = 0
self.verticsInSerach = set()
self.GraphBulided = False
def addVertex(self,value = None):
self.numVertics = self.numVertics + 1
newVertex = Vertex(key,value=value)
self.vertList[key] = newVertex
return newVertex
def getVertex(self,n):
if n in self.vertList:
return self.vertList[n]
else:
return None
def __contains__(self,n):
return n in self.vertList
def addEdge(self,f,t,cost = 0,fvalue = None,tvalue = None):
if f not in self.vertList:
nv = self.addVertex(f,fvalue)
if t not in self.vertList:
nv = self.addVertex(t,tvalue)
self.vertList[f].addNeighbor(self.vertList[t],cost)
def setGraphBulided(self,tag = True):
self.GraphBulided = tag
def getVertices(self):
return self.vertList.keys()
def setGraphBulided(self,tag = True):
self.GraphBulided = tag
def setSerachedVertixs(self,vertix):
self.verticsInSerach.add(vertix)
def getGraphBulided(self):
return self.GraphBulided
def getSerachedVertixs(self):
return self.verticsInSerach
def __iter__(self):
return iter(self.vertList.values())
def __hash__(self):
hashids = [x for x in self.getVertices()]
if len(hashids) > 0 and hashids[0]:
return hash(','.join(hashids))
else:
return None
这里有一些用于构建图表的附加功能
def buildGraph(wordFile,DFSgraph = False):
d = {}
g = Graph()
if DFSgraph:
g = DFSGraph()
wfile = open(wordFile)
for line in wfile:
word = line[:-1]
for i in range(len(word)):
bucket = word[:i] + '_' + word[i+1:]
if bucket in d:
d[bucket].append(word)
else:
d[bucket] = [word]
for bucket in d.keys():
for word1 in d[bucket]:
for word2 in d[bucket]:
if word1 != word2:
g.addEdge(word1,word2)
wfile.close()
return g
class Queue:
def __init__(self):
self.items = []
def isEmpty(self):
return self.items == []
def enqueue(self,item):
self.items.insert(0,item)
def dequeue(self):
return self.items.pop()
def size(self):
return len(self.items)
def bfs(g,start,listpred = False):
start.setdistance(0)
start.setPred(None)
vertQueue = Queue()
vertQueue.enqueue(start)
while (vertQueue.size() > 0):
currentVert = vertQueue.dequeue()
if currentVert.getConnections():
g.setSerachedVertixs(currentVert)
for nbr in currentVert.getConnections():
#print('sreach {}'.format(currentVert.getId()))
if (nbr.getColor() == 'white' or nbr.getColor() == 'gray'):
nbr.setColor('gray')
nbr.setdistance(currentVert.getdistance() + 1)
if nbr.prednum > 0 and currentVert.getId() not in [x.getId() for x in nbr.pred]:
nbr.setPred(currentVert,listpred)
elif nbr.prednum == 0:
nbr.setPred(currentVert,listpred)
vertQueue.enqueue(nbr)
currentVert.setColor('black')
因此,我们可以轻松找到所需的最短路径(如果我们只为一个顶点存储一个 pred)。
wordGraph = buildGraph('fourletterwords1.txt',DFSgraph=False)
bfs(wordGraph,wordGraph.getVertex('FOOL'),listpred=True)
def traverse(y):
x=y
while(x.getPred()):
print(x.getPred())
x = x.getPred()
print(x.getId())
traverse(wordGraph.getVertex('SAGE'))
但是,我仍然不知道如何正确跟踪所有路径,您能给我一些建议吗?
解决方法
FIND path from src to dst ( Dijkstra algorithm )
ADD path to list of paths
LOOP P over list of paths
LOOP V over vertices in P
IF V == src OR V == dst
CONTINUE to next V
COPY graph to working graph
REMOVE V from working graph
FIND path from src to dst in working graph( Dijkstra algorithm )
IF path found
IF path not in list of paths
ADD path to list of paths
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。