算法设计与分析

第一章        算法概述

1.算法渐进性态:当问题规模(n)趋近无穷大,称为O(n)=  表达式,取表达式的最高阶无穷大,这个就是运行时间的上界。

问题的上界

问题准确界

问题的下界

问题一:知问题复杂度,求计算机速度提升一定倍数,求同样时间内处理问题规模变为原来多少?

问题:解决某问题有三种算法,复杂性分别为1000N、10N的2次方、2的N次方,在一台机器上可处理问题的规模分别为S1、S2、S3 。若机器速度提高到原来的10倍,问在同样时间内可处理问题的大小如何?

解:设计算机原来速度为v,则提升速度后10v,

问题规模/速度=时间,利用两次处理时间相等但问题规模不同列方程。

原问题规模/原速度 = 新问题规模 / 新速度

则,1000S1 / v  = 1000n / ( 10v)

问题二:知问题复杂度,改进复杂度,求提升后,原来问题解决时间。

问题:例2:问题P的算法复杂度为T(n)=n的3次方(毫秒),现改善为T(n)=n的2次方(毫秒)。问原来运行1小时的问题实例,现在要运行多少时间?

解:设计算机速度为v,原来用时为t, 问题规模为n,新用时为t1。

问题规模/速度=时间,利用两次处理速度相等、问题规模相同列方程。

同时利用原来的用时求出问题规模n的大小。

n^3 / t = n^2 / t1

n^3 = 1 hour

n=153

t1 = t / n = 23.5

第二章        递归与分治

阶乘函数

 int Factorial(int n)
        {
             if(n==0) return 1;
             return n*Factorial(n-1);   
        }

Fibonacci数列

无穷数列1,1,2,3,5,8,13,21,34,55,……。

int fibonacci(int n)
   {
       if (n <= 1) return 1;
       return fibonacci(n-1)+fibonacci(n-2);
   }

 

 

排列问题

整数划分问题

一般递归问题会用非递归方法代替:

1. 可化为非递归方法。

2. 栈模拟。

 分治法的基本思想

分治法的设计思想:

1) 将一个难以直接解决的大问题,分割成一些规模较小的子问题;这些子问题互相独立且与原问题相同

2)递归地解子问题

3) 将各个子问题的解合并得到原问题的解

  Divide-and-Conquer(P)
{
     if ( |P|<=n0)   Adhoc(P); 
     divide P into smaller subinstances  P1 ,P2,... ,Pk;
     for (i = 1;i <= k; i++)
       yi=Divide-and-Conquer(Pi);
    return Merge( yl ,..., yk); 
}

算法时间复杂度

 

主方法

 

 

 

二分搜索技术

int BinarySearch(Type a[ ], const Type &x,int n)
{
	int left=0;	int right=n-1;
	while(left<=right){
		int middle=(left+right)/2;
		if(x==a[middle])
			return middle;
		else if(x>a[middle])
			left=middle+1;
		else
			right=middle-1;
	}
	return -1; 
}

棋盘覆盖问题

 

 合并排序

temlplate  <class type>
void MergeSort(Type a[], int left, int right)
  {   if (1eft < right) //至少有2个元素
       {  
           int i = (left + right ) /2; //取中点
           MergeSort(a, left, i);
           MergeSort(a, i+1, right);
           Merge(a, b, left, i, right);//从a合并到数组b
           copy(a, b, left, right);//复制回数组a
     }
 }    

快速排序算法

 //将>=x的元素交换到右边区域
 //将<=x的元素交换到左边区域
int Partition(Type a[ ],int p , int r )
{  
    int i=p;  
    j=r+1;
    type x=a[p];
    while(true) 
    { 
         while(a[++i] < x&&i<r);
         while(a[--j] > x);
         if (i>=j )  break;
         swap(a[i],a[j]);  
    }
    a[p] = a[j];
    a[ j] = x;
    return j  }



    template <class Type>
    void QuickSoft(Type a[], int p, int r)
    {  
        if(p<r){
        int q=Partition(a, p, r)
        QuickSort(a, p, q-1); //对左半段排序
        QuickSoft(a, q+1, r); //对右半段排序
        }
     }
    


//随机选择基准点、
template <class Type>
void randomizedQuickSoft(Type a[], int p, int r)
{         
    if (p<r) {
        int q=randomizedPartition(a, p, r)
        randomizedQuickSort(a, p, q-1); //对左半段排序
        randomizedQuickSoft(a, q+1, r); //对右半段排序
    }
}
    
template <class Type>
int randomizedPartition(Type a[], int p, int r)
{ 
    int i=random( p, r)
    swap( a[i], a[p] )
    return Partition (a,p,r)
}

最接近点对问题

给定平面上n个点,找其中的一对点,使得

n个点组成的所有点对中,该点对间的距离最小。

线性时间选择

大整数的乘法

 Strassen矩阵乘法

第三章        动态规划

矩阵连乘

 

最大子段和

 

int MaxSum(int n, int * a)
{
     int sum=0, b=0;
     for (int i=1; i<=n; i++) {
        if(b>0) b+=a[i];
        else b=a[i];
        if (b>sum) sum=b;
     }
   return sum
}    //时间和空间复杂度:O(n)

 0-1背包

最长公共子序列

最大子段和

int MaxSum(int n, int * a)
   {
     int sum=0, b=0;
     for (int i=1; i<=n; i++) {
        if(b>0) b+=a[i];
        else b=a[i];
        if (b>sum) sum=b;
     }
   return sum
}    //时间和空间复杂度:O(n)

 流水作业调度

图像压缩

 

第四章        贪心算法

贪心算法的基本要素:

(1) 最优子结构

问题的最优解包含子问题的最优解

(2) 贪心选择性质

问题的整体最优解可以通过一系列局部最优选择达到

 

背包问题

最优装载

哈夫曼编码

哈夫曼树和哈夫曼编码_哔哩哔哩_bilibili

构成赫夫曼树的步骤:

1)从小到大进行排序, 将每一个数据,每个数据都是一个节点 , 每个节点可以看成是一颗最简单的二叉树

2)取出根节点权值最小的两颗二叉树

3)组成一颗新的二叉树, 该新的二叉树的根节点的权值是前面两颗二叉树根节点权值的和

4)再将这颗新的二叉树,以根节点的权值大小 再次排序, 不断重复 1-2-3-4 的步骤,直到数列中,所有的数据都被处理,就得到一颗赫夫曼树

哈夫曼编码就是根节点到树叶的编码,左子树为0,右子树为1

 

 

第五章        回溯法

背包问题

 

图的着色:

        已知无向图G=(V,E)和m种不同的颜色,如果只允许使用这m种颜色对图G的结点着色,每个结点着一种颜色。问是否存在一种着色方案,使得图中任意相邻的两个结点都有不同的颜色。整数m称为图G的着色数。

 

 

 

 

 

 

 

 

 

 

 

第六章        分支限界法概述

 背包问题

优先级队列

优先级定义:当前价值+剩余能装的最大价值(上界函数)

分支限界法求解0/1背包问题动画演示(Implementation of 0/1 Knapsack using Branch and Bound)_哔哩哔哩_bilibili

单源最短路径

约束函数:c[i][j]<inf        dist[i]+c[i][j] <dist[j]     

优先级:节点所对应的当前路长

 装载问题

 

 

 

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值