词梯问题是这样的:
考虑一个任务:将单词FOOL转换成SAGE,在解决词梯问题时,必须每次只替换一个字母,并且每一步的结果都必须时一个单词,而不能是不存在的单词
为了解决这个问题,我们将分两部完成:1.为词梯问题构建单词关系图。2.宽度优先级算法解决问题。
1.为词梯问题构建单词关系图。
为了构建关系图,我们首先将单词放入类似如下规则的词桶,然后构建关系图
具体实现代码如下:
#可根据自己的文件路径导入图类的实现
from 数据结构与算法.图及其算法.图类的实现 import Graph
def buildGraph(wordFile):
d={}
g=Graph()
wfile=open(wordFile,'r')
# 创建词桶
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)
return g
构建好词图之后就可以使用宽度优先级算法(BFS)了
2.宽度优先级算法解决问题。
本例中宽度优先级算法的思路如下:
(1)给定图G和起点s,BFS通过边来访问在G中与s之间存在路径的顶点,BFS的一个重要特征是,它会在访问完所有与s相距为k的顶点之后再去访问与s相距为k+1的顶点。为了理解这种搜索行为,可以想象BFS以每次生成一层的方式构建一颗树。它会在访问任意一个孙节点之前将所有子节点都添加出来。
(2)为了记录进度,BFS会将顶点标记成白色,灰色,或黑色。在构建时,所有顶点都被初始化成白色,白色代表该顶点没有被访问过。当顶点第一次被访问时,它就会被标记为灰色,当BFS完成对该顶点的访问之后,它就会被标记成黑色。这意味着一旦顶点变为黑色,就没有白色顶点与之相连,灰色顶点仍然可能与一些白色顶点相连,这意味着还有额外的顶点可以访问
具体代码和图示如下
代码:
#可根据自己的文件路径导入Queue类和Vertex类的实现
from 数据结构与算法.队列 import Queue
from 数据结构与算法.图及其算法.顶点的实现扩展版本 import Vertex
# 宽度优先级算法
def bfs(g,start):
start=Vertex()
start.setDistance(0)
start.setPred(None)
vertQueue=Queue()
vertQueue.enqueue(start)
while(vertQueue.size()>0):
currentVert=vertQueue.dequeue()
for nbr in currentVert.getConnections():
nbr=Vertex()
if (nbr.getColor()=='white'):
nbr.setColor('gray')
nbr.setDistance(currentVert.getDistance()+1)
nbr.setPred(currentVert)
vertQueue.enqueue(nbr)
currentVert.setColor('black')
同时可以借助下图理解以上代码
如果想要回溯宽度优先级算法如何找到目标词可以用如下方法,代码如下:
def traverse(y):
x=y
while(x.getPred()):
print(x.getPred())
x=x.getPred()
print(x.getId())
traverse(g.getVertx('sage'))