痛定思痛,开启算法之路(七)

8.4.1背包问题

将不同重量Wi和不同价值Vi的物品放进承重为j的背包中,再背包能装下重量的前提下,求所能装物品的最大价值。

这里写图片描述
这里写图片描述
根据动态规划表,可以看出来其时间、空间复杂度均为O(nW);

8.4.2记忆功能

记忆功能技术试图把自顶向下和自底向上方法的优势结合起来;
该方法用自顶向下的方式对给定的问题求解,但还需要维护一个类似自底向上动态规划算法使用的表格。
它只对必要的子问题求解并只解一次,并用表格记录下来;

这里写图片描述

这里还有些不是十分清晰,需要再次探讨研究学习!

第九章 贪婪技术

技术的核心是,所做的每一步选择都必须满足:
1)可行的:即它必须满足问题的约束;
2)局部最优:它是当前不周中所有可行选择中最佳的就不选择;
3)不可取消:即选择一旦做出,在算法的后面步骤中就无法改变了;

9.1Prim算法(构造最小生成树)

这个算法在数据结构中也有详细的介绍,且算法思想较简单,在这再简单介绍学习一下:

以第一个顶点出发,找与其相连的最小的边
(以已有连接的任一节点为出发点,找其距离最短的边相连,且不构成回路直到包含所有的点)

这里写图片描述

9.2 Kruskal算法

此算法同样在数据结构中具有详细讲解,在这里我们简单学习回顾一下:

    作为同样计算最小生成树的算法,它不局限于以已经连接的点为出发点,而是对于所有的扁的权值进行简单非递减排序,
    每次选择相对最小的边加入最小生成树(在添加的过程中保证不产生回路,如有则简单舍弃继续往下取边),其仍然以最终的n-1个点为边界结束:

这里写图片描述
这里写图片描述

此算法基本思想理解起来比较简单,但具体实现细节有2点需要具体学习深化一下:
1)Find(x): 对于最新寻找到的最小边能否加入原最小集(即是否形成回路):其判断方法是,分别寻找两颗子树的根元素,若为同一根则两者合并必形成回路;在这里还有一个优化措施即路径压缩法:在寻找最终根元素的过程中,令查找路径上的每个节点都直接指向其共同根元素,在以后再次寻找根元素的时候可以直接获得其根元素的值进行比较;

这里写图片描述

这里写图片描述

2)Union(int R1,int R2):对于两个不同集合合为同一集合,形成最终最小树:
这里合并的时候,具体那棵树合到那棵树(可以根据树高:矮树合到高树/点少的树合到点多的树);确定之后,比如R1合到R2,则令R1的根再次指向R2并此时将R1的根置空(相当于删除此树)
这里写图片描述

9.3 Dijkstra算法(求单源最短路径问题:即一个点到其余各点的最短路径)

此算法同样在数据结构中具有详细介绍,且其核心思想比较简单易懂:以当前含有的已连接的任一点考虑,找到优先级最低(即总和距离最短的点)的元素以此为中心向未连接的点扩展;这里用到了优先级队列(其总能保证头部元素最小)

这里写图片描述
这里写图片描述

    背包问题,利用贪心算法可以得到价值最高的、性价比最高的(价值/质量)等等各个特定方面的解法;
    贪心每一步都是基于上一步的结果,只考虑当前最优而不考虑全局,其效率更高但不保证最优;Dijstra综合考虑各个子问题一定可以得出最终最优结果;

    贪心和动归不是互斥的,而是包含的,贪心更快,但约束更强,适应范围更小。
    贪心属于动态规划的一个特定方向、特定问题解法,不一定最优但是在一定情况下速度却是非常快的;
    因而综合两种算法的优缺点便得到了相对最优的A*算法(在之后文章我会专门介绍)

猜你喜欢

转载自blog.csdn.net/enjoy_endless/article/details/79067897