动态规划
还是回到贪心算法中的背包问题,使用贪心算法解决背包问题,得到的并不是最优解,而是一个近似算法。那么如何得到最优解呢,那就是动态规划。
动态规划是先解决子问题,在逐步解决大问题
- 动态规划可在给定约束条件下找到最优解
- 在问题可分解为彼此独立且离散的子问题时,可使用动态规划来解决
在动态规划中,每种动态规划解决方案都涉及到网格,每个单元格的值就是要优化的值,每个单元格都是一个子问题
之前在进行最短路径计算时使用了广度优先算法,但是找出的只是换乘最少的路径,每次所用的时间其实是不一样的,如果要找出用时最短的路径,可以使用迪杰斯特拉算法(Dijkstra)
如上述路线,从A到D,如果使用广度优先算法的话会得到A->B->D,花费7分钟。而其实最短时间是A->C->B->D,花费6分钟。
迪杰斯特拉算法包含四个步骤
找出可在最短时间内到达的节点,站在A点,不知道该前往B点还是C点时,此时由于还不知道前往终点需要多长时间,假设是无穷大。此时C点是最近的
第一步算出来C点是距离起点最近的,这一步需要计算出经过C点到其他各邻居节点所需的时间
A->C->B 需要5分钟
A->C->D需要8分钟
OK。此时找到了一条前往B的更短路径。直接前往B需要6分钟,经C之后前往B只需要5分钟。
所以更新一下到各节点的时间开销
重复前两步操作。重复第一步时排除掉第一次选出的C点,所以选出的点是B点。重复第二步更新B点所有邻居节点的开销。
此时发现达到终点的时间变为了6分钟。
最终算出到达终点的最短时间
使用的是贪心算法
之前说过广度优先搜索,是按照度来进行排序的。这里来说一下另外一种图的算法。其中的节点有依赖关系,如果节点A依赖于节点B,则列表中的节点A就必须在节点B后,这就是拓扑排序。
使用拓扑排序来创建一个有序的任务列表
1 | public class TuoPuSort { |
图其实我们在生活中用到的很多,比如我们要从北京西站到望京,打开高德地图,开始进行导航,会有多种方式可供选择。这就是图
要找出换乘最少的路线。这种问题被称为最短路径问题,解决最短路径问题的算法被称为广度优先算法。
图是由节点和边组成的,一个节点可能与众多节点直接相连,这些节点被称为邻居。
顶点关系
没有方向
若一个无向图具有n个顶点,而每个顶点与其他n-1个顶点之间都有边,则称为无向完全图,也就是含有n个顶点的无向完全图有n(n-1)/2条边。类似的,有向图是每两个顶点之间有两条方向相反的边,也就是含有n个顶点的有向完全图有n(n-1)条边
顶点之间的关系,适用稠密图存(边多)