3月30日学习汇总
C语言(感觉没啥好写的,因为是学python入门,现在还在学c的基本语法,感觉差不太多)
穷举
break | goto | |
---|---|---|
使用区别 | 跳出一层循环 | 直接跳转至指定处,适用于:1.跳出多重循环;2.跳向共同的出口位置,进行退出前的处理工作。 |
python
- python中表示无穷大的量 num = float(“inf”)
狄克斯特拉算法
- 找出当前未处理的最便宜节点
- 计算前往该节点的各邻居的开销(等于起点到此点的开销加上此点到邻居点的开销)
- 将该点视为已处理点,回头处理此时未处理的最便宜的节点
- 对比后续点的新旧开销,更新数据。
python实现狄克斯特拉算法
题目来自《算法图解》练习
以第一题为例:
List item
一:程序目标:找出加权有向图从起点到终点的最短路径的总权重。
二:设计方案:
处理算法:
- 使用狄克斯特拉算法;
数据
- 我们需要存储各节点的邻居以及到他们的开销,适合用散列表(字典)neighbours来实现,;
- 我们还需要存储各点的开销,我们建立相应的散列表costs来实现,其中我们以给点名为key,再建立一个散列表,其中存储从起点到此点的最小开销,对此数据我们会在不断对比中更新,最后保留终点的最短路径的开销;
- 最后为了明确我们最后得来的权重到底是经过怎样的路线得来的,我们得记录好最短路径下每一节点的上一节点是谁,我们把他们称为父级节点,对此我们同样可以用散列表parents来实现同样这里我们始终保持更新父级为最短路径的情况;
- 一个列表,用来存储已经被处理里的节点,使之不再被二次处理。
三:代码实现:
# 定义处理邻居们时寻找最便宜的函数
operated_nodes = [] # 用于存放已经被处理过的节点
neighbours = {
'start':{'a':5, 'b':2},
'a':{'c':4, 'd':2},
'b':{'a': 8, 'd':7},
'c':{'d':6, 'e':3},
'd':{'e':1},
'e':{}
}
costs = {
'a':5,
'b':2,
'c':float("inf"),
'd':float("inf"),
'e':float("inf")
}
parents = {
'a':'start',
'b':'start'
}
def find_lowest_cost_node(costs):
lowest_cost = float("inf")
lowest_cost_node = None # 此处None用于当costs遍历完之后,无节点可遍历时作为标识停止循环
for node in costs.keys():
cost = costs[node]
if cost < lowest_cost and node not in operated_nodes:
lowest_cost = costs[node]
lowest_cost_node = node
return lowest_cost_node
def main():
node = find_lowest_cost_node(costs)
while node is not None:
cost = costs[node]
neighbour = neighbours[node]
for theneighbour in neighbour.keys():
new_cost = cost + neighbour[theneighbour]
if new_cost < costs[theneighbour]:
costs[theneighbour] = new_cost
parents[theneighbour] = node # 更新该节点的父级节点
operated_nodes.append(node)
if node == 'e':
return costs['e']
node = find_lowest_cost_node(costs)
if __name__ == "__main__":
num = main()
print(num)
这段代码花了我很长时间去调试,问题在于执行到最后,我原来并没有写被调出的node与‘e’判等,使程序陷入了死循环。