复习提纲 算法设计与分析

1、 试阐述回溯法和分支限界法在算法原理、搜索策略、剪枝、求解以及性能方面的异同:

					回溯法							分支限界法

算法原理 都是搜索问题的解空间树找到问题的解
搜索策略 深度优先搜索(堆栈) 广度优先搜索(优先队列)
剪枝 按约束条件剪枝 按目标函数剪枝
求解 求出问题的所有可能解 求出特定意义下的最优解(使目标函数取极值的解)
性能 搜索的盲目性 目的性更强,能在更高层次上进行剪枝
(两种方法都可以看成对蛮力法的改进。其中回溯法对解空间树按照深度优先搜索策略遍历,在搜索过程中采用约束条件和目标函数实行剪枝;分支限界法按照广度优先的顺序搜索解空间树,在遍历过程中根据限界函数估算目标函数的可能值,从中选择使目标函数取极值的结点优先扩展对于超出目标函数界的结点,则直接丢弃。因分支限界法搜索的目标性更强,且能在更高的层次上施行剪枝,因此一般情况下其时间性能较回溯法要好。)

2、阐述动态规划法的基本思想,它与分治法有哪些异同:

动态规划法将问题划分成若干个重叠子问题,子问题的重叠关系表现在对给定问题求解的递推关系,先对子问题进行求解中,将子问题的解求解一次并填入表中,当需要再次求解该子问题时,只需从表中取出对应值,从而避免大量的重叠运算。
动态规划法分为三步:
(1)划分子问题:
(2)确定动态规划函数:根据子问题间的重叠关系找到满足条件的递推关系式(动态规划函数)
(3)填写表格:自底向上的方式计算各子问题的解并填表,实现动态规划过程
同:都具有最优子结构,都是将待解问题分解成若干个子问题进行求解,先求解子问题,再通过子问题求出原问题。所以,两者的求解步骤其实很相似。
异:
动态规划法 分治法
重叠子问题 子问题相互独立
自底向上计算 自顶向下计算

3、贪心法设计思想:

贪心法把一个问题分继承一系列较为简单的局部最优选择,每一步选择都是对当前解的一个扩展,直到获得问题的完整解。并不是从整体最优来考虑的,局部最优选择。因此,并不能保证获得整体最优解,但通常能获得近似最优解。(自顶向下进行计算的)
用贪心法求解做优化问题所需性质:贪心选择性质,最优子结构

设计分治算法,求一个数组中第二大的数:

int Partition(int a[], int low, int high){
    int i=low, j=high;
    while( i<j ){
        while( i<j&&a[i]>=a[j] )
            j--;
        if( i<j ){
            int temp = a[i];
            a[i] = a[j];
            a[j] = temp;
            i++;
        }
        while( i<j&&a[i]>=a[j] )
            i++;
        if( i<j ){
            int temp = a[i];
            a[i] = a[j];
            a[j] = temp;
            j--;
        }
    }
    for(int i=0;i<=9;i++)
        cout<<a[i]<<" ";
    cout<<endl;
    return i;
}

int SelectMink(int a[], int low, int high, int k){
    int s;
    s = Partition(a, low, high);
    cout<<s<<"-->"<<a[s]<<endl;
    if( s==k ){
        return a[k];
    }
    if( s>k ){
        return SelectMink(a, low, s+1, k);
    }
    if( s<k ){
        return SelectMink(a, s-1, high, k);
    }
}

减治法求解选择问题(求序列中第k大的数的索引,借助快速排序中的划分进行求解):

时间复杂度:
最好:O(n)
最坏:O(n2) 相当于冒泡
平均:O(n)

动态规划法例题

例题1多源点最短路径(Floyd算法):
d(vi, vj, {}) = cij
d(vi, vj, {v1,v2…vk}) = min{ d(vi, vj, {v1,v2…vk-1}), d(vi, vk, {v1,v2…vk-1})+d(vk, vj, {v1,v2…vk-1}) }

例题2最长递增子序列O(n^2):
L(i) = 1 i=1或不存在a[j]<a[i] 1=<j<i
L(i) = max( L(j)+1 ) 对所有a[j]<a[i]的j 1=<j<i

例题3 0/1背包:
V(i, j) = V(i-1, j) j<w[i] 无法装下物品i
V(i, j) = max{ V(i-1, j-w[i])+v[i], V(i-1, j) } j>=w[i]
(可以装的下,但到底装不装要比较哪种好)

最小生成树两种算法

prim算法:
随机挑选一个节点作为新图的初始状态,开始选择节点,加入新图,每次选择最小边且不产生回路,直到所有的点都挑进来了。

kruskal算法:
设一个图只有节点,没有边,不断加入最小的边,不产生回路,直到变为连通。

贪心法 活动安排问题:

时间复杂度O(nlogn) 主要用在排序上
算法:

  1. 按 活动结束时间 升序排列
  2. 最优解一定包含第一个活动,即ans = {1}
  3. j = 集合B中最晚结束的活动, 初始化为j=1
  4. 循环变量i从 2-n 依次考察每个活动
    4.1 若s[i] > f[j]:
    B = B+{i};
    j = i;
    4.2 i++;

渐进符号

O(n) 渐进上界 最差也就这么差 o(n) T(n)<O( f(n) 没有等号
Ω(n) 渐进下界 最好最快是这种情况
θ(n) c1f(n)<=T(n)<=c2f(n)

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值