计算机算法设计与分析(1-6章 复习笔记)

简介: 计算机算法设计与分析(1-6章 复习笔记)

计算机算法设计与分析

最近发现一些刷题的网站,牛客、力扣,很适合用来熟悉算法和语言知识点。

第1章 算法概述

1.1 算法与程序

算法 是解决问题的一种方法或一个过程。

    严格地说,算法是由若干条指令组成的有穷序列,且满足下述4条性质。

  1. 输入
  2. 输出:至少产生一个量作为输出。
  3. 确定性:每条指令清晰、无歧义。
  4. 有限性:执行次数、时间有限

程序和算法不同。程序不一定满足上述4条性质。

1.2 算法复杂性分析

最坏时间复杂度:O;时间上界;

1.3 NP完全性理论

可在多项式时间内求解的判断问题构成    P类问题。

第2章 递归与分治策略

 分治法的思想:将一个难以直接解决的大问题分解为一些规模较小的相同问题,以便各个击破,分而治之。

2.1 递归的概念

直接或间接调用自身的算法称为递归算法。

【例2-1】阶乘函数。

阶乘函数可递归的定义为:

n!  = 1            ,n=0

   = n(n-1)!   ,  n>0

递归式的第一式给出了这个函数的 初始值,是非递归定义的(直接给出)。每个递归函数都必须有非递归定义的初始值,否则会一直递归下去。

递归式的第二式用较小的自变量的函数值来表示较大自变量的函数值的方法来定义n的阶乘。

用代码表示:

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

【例2-6】Hanoi塔问题

问题略。

可用递归方法解决:

当n=1时,只要将当前盘子从当前位置塔a放在目标塔b即可。

当n>1时,需要利用塔c作为辅助塔,将n-1个圆盘移动到c上,然后将剩下的最大圆盘移动到b上。即n个圆盘的问题变成两次n-1个圆盘的问题。

用代码表示:

//4个参数依次是剩余数量,起点,终点,中间点
 
void hanoi(int n, char a, char b, char c){
 
    if (n==1)
 
        move(a,b);
 
    else
 
    {
 
       hanoi(n-1,a,c,b);
 
       move(a,b);
 
       hanoi(n-1,c,b,a);
 
    }
 
       
 
}
 
void move(char begin,char end){
 
cout<<begin<<"--->"<<end<<"\n";
 
}


2.2 分治法的基本思想

分治法的基本思想是将一个规模为n的问题分解为k个规模较小的子问题,子问题之间相互独立且与原问题类型相同。

2.3二分搜索技术

二分搜索是分治的典型例子。

给定已排好序(为了简便,设为升序排序)的n个元素a[0,n-1],要在其中找到一特定元素x。

如果用顺序搜索(从头开始依次往后比较),最坏情况需要n次比较;

分搜索采用分治策略,最坏情况用O(logn) 时间完成。

二分搜索的基本思想:将n个元素分成数量基本相同的两份,取a[n/2]与x比较,如果x 等于a[n/2],则找到,算法终止;如果x<a[n/2],则x较小,只要在数组a的左半部继续搜索;

如果x>a[n/2],则x较大,只要在数组a的右半边继续搜索。

/*二分搜索 */
 
template<class Type>
 
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;
 
        if (x>a[middle])
 
            left = middle+1;
 
        if (x<a[middle])
 
            right = middle-1;
 
    }
 
    return -1;
 
}
 
 
 
//递归形式
 
int  BinarySearch(int a[],int x,int left,int right){
 
    if(left>right)
 
        return -1;
 
    int middle = (left+right)/2;
 
    if (x==a[middle])
 
        return middle;
 
    if(x<a[middle])
 
        return BinarySearch(a,x,left,middle-1);
 
    if(x>a[middle])
 
        return BinarySearch(a,x,middle+1,right);
 
}

2.4 大整数的乘法

有二进制整数X和Y,要计算X * Y,

将X分成两份:A、B,

Y分解两份:C、D

XY = (A*2n/2 +B)(C*2n/2 +D)

=AC*2n +((A-B)(D-C)+AC+BD)* 2n/2 +BD  //利用数学变形,减少乘法次数

2.5 Strassen矩阵乘法

(直接分解再乘并不能减少乘法次数,通过一些变形增加加减法次数,减少乘法次数)。

2.7 合并序。

用分治策略对N个元素进行排序。

基本思想:将待排序的n个元素分成大小大致相同的两个子集,分别对两个子集进行排序,然后再合并两个子集。

template<class Type>
 
void MergeSort(Type a[],Type b[], int left, int right) {
 
    if (left < right) {
 
        int i = (left + right) / 2;
 
        MergeSort(a, b,left, i);
 
        MergeSort(a, b,i + 1, right);
 
        Merge(a, b, left, i, right); //合并到b数组
 
        Copy(a, b, left, right);   //复制回a数组
 
    }
 
 
 
template<class Type>
 
void Merge(Type c[], Type d[], int l, int m, int r) {  //合并c[l:m]和c[m+1:r]到d[l:r]
 
    int i = l, j = m + 1;
 
    int pos = l;
 
    while ((i <= m) && (j <= r)) {
 
        if (c[i] <= c[j])
 
            d[pos++] = c[i++];
 
        else
 
            d[pos++] = c[j++];
 
        if (i > m) {    //第1个数组放完了,直接把第2个数组剩下的放到d
 
            for (int q = j; q <= r; q++)
 
                d[pos++] = c[q];
 
        }
 
        if (j > r) {      //第2个数组放完了,直接把第1个数组剩下的放到d
 
            for (int q = i; q <= m; q++)
 
                d[pos++] = c[q];
 
        }
 
    }
 
}
 
 
 
template<class Type>
 
void Copy(Type a[], Type b[], int left, int right) {
 
    for (int i = left; i <= right; i++)
 
        a[i] = b[i];
 
}

2.8 快速排序

对于数组a[p:r]按三个 步骤排序:

1. 分解(Divide):以a[p]为基准元素,a[p:r]分解为3段:a[p:q-1].a[q]]和a[q+1:r]

使得a[p:q-1]中的元素都<=a[q] , a[q+1:r]>=a[q],下标q在划分过程中确定。

2.递归求解(Conquer):使用递归对a[p:q-1]和a[q+1:r]进行排序。

3.合并(Merge):a[p:q-1]和a[q+1:r]排序好后,不需要进行操作就已经排好序了。

template<class Type>
 
void QuickSort(Type a[],int p,int r){
 
    if(p<r){
 
        int q = Partition(a,p,r);
 
        QuickSort(a,p,q-1);
 
        QuickSort(a,q+1,r);
 
    }
 
}
 
 
 
template<class Type>
 
int Partition(Type a[],int p, int r){
 
    int i=p+1, j =r;
 
    Type x = a[p];
 
    while(true){
 
        while(a[i]<x && i<r)   //直到找到a[i]>=x
 
            i++;
 
        while(a[j]>x)           //直到找到a[j]<=x
 
            j--;
 
        if(i>=j)
 
            break;
 
        swap(a[i],a[j]);    //交换a[i],a[j],使得左边都小于x,右边>x
 
    }
 
   swap(a[p],a[j]);
 
    return j;
 
}
相关文章
|
1天前
|
机器学习/深度学习 人工智能 自然语言处理
【机器学习】贝叶斯算法在机器学习中的应用与实例分析
【机器学习】贝叶斯算法在机器学习中的应用与实例分析
7 1
|
3天前
|
算法 Java Go
斐波那契数列是一个非常经典的数学问题,在计算机科学中也经常被用作算法设计和分析的例子。
斐波那契数列是一个非常经典的数学问题,在计算机科学中也经常被用作算法设计和分析的例子。
|
7天前
|
算法 Java 索引
12.12_黑马数据结构与算法笔记Java
12.12_黑马数据结构与算法笔记Java
16 1
|
6天前
|
搜索推荐 算法 前端开发
计算机Java项目|基于协同过滤算法的体育商品推荐系统
计算机Java项目|基于协同过滤算法的体育商品推荐系统
|
7天前
|
人工智能 算法
计算机算法设计与分析 第3章 动态规划 (笔记)
计算机算法设计与分析 第3章 动态规划 (笔记)
|
1天前
|
机器学习/深度学习 算法 数据可视化
m基于PSO-LSTM粒子群优化长短记忆网络的电力负荷数据预测算法matlab仿真
在MATLAB 2022a中,应用PSO优化的LSTM模型提升了电力负荷预测效果。优化前预测波动大,优化后预测更稳定。PSO借鉴群体智能,寻找LSTM超参数(如学习率、隐藏层大小)的最优组合,以最小化误差。LSTM通过门控机制处理序列数据。代码显示了模型训练、预测及误差可视化过程。经过优化,模型性能得到改善。
15 6
|
1天前
|
算法 调度
基于变异混合蛙跳算法的车间调度最优化matlab仿真,可以任意调整工件数和机器数,输出甘特图
**摘要:** 实现变异混合蛙跳算法的MATLAB2022a版车间调度优化程序,支持动态调整工件和机器数,输出甘特图。核心算法结合SFLA与变异策略,解决Job-Shop Scheduling Problem,最小化总完成时间。SFLA模拟蛙群行为,分组进行局部搜索和全局信息交换。变异策略增强全局探索,避免局部最优。程序初始化随机解,按规则更新,经多次迭代和信息交换后终止。
|
12天前
|
算法
基于GA-PSO遗传粒子群混合优化算法的VRPTW问题求解matlab仿真
摘要: 本文介绍了考虑时间窗的车辆路径问题(VRPTW),在MATLAB2022a中进行测试。VRPTW涉及车辆从配送中心出发,服务客户并返回,需在指定时间窗内完成且满足车辆容量限制,目标是最小化总行驶成本。文章探讨了遗传算法(GA)和粒子群优化(PSO)的基本原理及其在VRPTW中的应用,包括编码、适应度函数、选择、交叉、变异等步骤。同时,提出了动态惯性权重、精英策略、邻域搜索、多种群和启发式信息等优化策略,以应对时间窗限制并提升算法性能。
|
6天前
|
算法 JavaScript 决策智能
基于禁忌搜索算法的TSP路径规划matlab仿真
**摘要:** 使用禁忌搜索算法解决旅行商问题(TSP),在MATLAB2022a中实现路径规划,显示优化曲线与路线图。TSP寻找最短城市访问路径,算法通过避免局部最优,利用禁忌列表不断调整顺序。关键步骤包括初始路径选择、邻域搜索、解评估、选择及禁忌列表更新。过程示意图展示搜索效果。
|
6天前
|
机器学习/深度学习 算法
基于BP神经网络和小波变换特征提取的烟草香型分类算法matlab仿真,分为浓香型,清香型和中间香型
```markdown 探索烟草香型分类:使用Matlab2022a中的BP神经网络结合小波变换。小波分析揭示香气成分的局部特征,降低维度,PCA等用于特征选择。BP网络随后处理这些特征,以区分浓香、清香和中间香型。 ```

热门文章

最新文章