算法设计与分析 课程期末复习简记

目录

网络流

 线性规划

回溯算法

分支限界

 贪心算法

动态规划

分治算法

算法复杂度分析

 相关概念


 

网络流

下面是本章需要掌握的知识

• 流量⽹络的相关概念

• 最⼤流的概念

• 最⼩割集合的概念

• Dinic有效算法的步骤

• 会⼿推⼀个流量⽹络的最⼤流

下面对此依次进行复习

首先看流量网络的相关概念


 

上面是课程PPT中的定义,真是抽象

  

实际上,我们直接将某个流量网络进行建模出来就是上图这样,其中每一条弧上的第一个数字代表该条弧的最大流量,第二个数字代表该条弧的实际通过流量,并且定义一个发点V1、收点V6,其余的就是中间点了

那么上图所说的可行流又是什么?

实际上可行流即从发点到收点的流量都是合法的

  • 即每一条弧的实际流量f>=0且f<=c
  • 并且每个中间点的接收流量之和=发出流量之和
  • 发点发出流量之和=收点接收流量之和

下面看前向弧、后向弧的概念

假设有一条链u,它链接了发点与收点,且定义链的方向是从发点到收点(注意链的方向与弧的方向无关)

那么链上的弧分为了


下面看增广链的概念

假设有一条从发点到收点的链,当该链满足如下条件时为增广链

  • 如果链上的某条弧是前向弧,则必须满足0<=f<c,即是非饱和弧
  • 如果链上的某条弧是后向弧,则必须满足0<f<=c,即是非零流弧

下面看割集的相关概念

割量也称为割集的容量

还是看一个例子

如上图所示,我们在流量网络上将发点和收点分开了

那么现在的割集为(v1,v2),(v1,v3)

现在的割量为5+6=11

这是一个割集与一个割量,但是我们将发点与收点分开的方式有多种,将它们都求出来,找到最小割量,就是找到最小割集了 

 定理:最小割量的大小就等于网络的最大流量


下面是Dinic的算法步骤

1. 从0流𝑓开始

2. 构造分层辅助网络

3. 如果𝐴𝑁 𝑓 存在s-t最短路径

① 求得𝐴𝑁 𝑓 上的极大流𝑔

② 叠加流𝑓 = 𝑓 + 𝑔;

GOTO 2

4. 否则, 𝑓为所求最大流

注意这里的分层网络是为了方便我们判断是否某条弧是否还有残余流量

并且在增广链的构建过程中则会判断是否找到的顶点的层数是当前顶点的层数+1(即还有残余流量)


下面演示标号法求一个流量网络的最大流

 首先给发点初始化为(0,正无穷)

如上图所示,我们找到一条增广链V1 V3 V4 V7

接着对当前增广链上找到一个最小流量即3,之后对链上的弧都加上该流量即可

 然后将点上的标号都取消,重复上述步骤

 

如上图所示,我们再次找到一条增广链,注意这次的增广链中存在一个后向弧,注意后向弧的标号与前向弧的标号是不同的

发现链上最小流量为1,那么链上的前向弧流量+1,后向弧流量-1

  再次重复上述步骤

这次我们发现不管怎样,我们都没办法使得增广链到达收点

因此我们就已经得到了最大流量为f12+f13=7+13=20

不难发现最小割集的容量即6+3+3+8=20,也印证了最小割量=最大流量的结论 

 总结

 线性规划

重点掌握以下内容(针对min类型的)

  • 将数学模型化为标准型
  • 手写单纯形法
  • 化为对偶线性规划

先看如何化成标准型

 例题

首先将目标函数变为min型,其中变量的系数也要变为相反数

再看约束条件中右边是否存在<0的数,如果有也需要将该式子化为正的

接着补充松弛变量和剩余变量,即对于<=的式子我们需要在该式子的左边+松弛变量

对于>=的式子我们需要在式子的左边-剩余变量,记得在最下面补充上松弛变量与剩余变量都>=0的条件

 

 最后将自由变量x3在式子中的位置都替换为x3'-x3''

同样的需要在最下面补充x3'>=0与x3''>=0


接下来看如何使用单纯形法

看一个例子

 首先先化为标准型

画出单纯型表的大致模样

取第0行的一个<0的列作为换入变量,接着在这一列中,计算出每一行的检验数,即第0列的每一行去除刚刚选出的那一列的每一个数,注意当其中存在<=0的数时得到的检验书无效

 

 然后得到最小的检验数的那一行作为换出变量

此时我们确定了一个位置的点,我们需要利用矩阵的行变换将除了选出的那一行外其余全部变为0

接着重复上述过程

 

直到第0行全部为>=0时则确定我们得到了最优解 

下面是判断解的情况的方法


下面看如何化为对偶线性规划

首先我们需要清楚的是对偶线性规划有什么用

我们前面所学的线性规划只能用于解决约束条件都为<=的情况

但是实际应用中,我们不可能保证约束条件都为<=,而对偶线性规划就补充了这点

因为其可以允许约束条件的右边存在<0的数

那么我们就还是可以保证约束条件都<=的情况了

对偶的性质:如果原始规划(P)有最优解, 则对偶规划(D)也有最优解, 且它们的最 优值相等。反之亦然

还是看一个例子

 首先原先是max对偶就是min,反之类似的

然后原问题目标函数的系数对应着对偶问题约束条件的右边

原问题约束条件的右边对应着对偶问题的目标函数系数

原问题变量的符号对应着对偶问题约束条件的符号(即原问题x1x2x3都>=0,因此对偶问题三个约束条件都是>=的)

原问题约束条件的符号对应着对偶问题的变量符号(即原问题约束条件都是<=的,因此对偶问题的4个变量都是>=0的!注意这是相反的)

此外还需要注意 如果存在任意与等于的情况,那么任意的相反是等于,等于的相反是任意

例题

  

回溯算法

本章需要掌握的内容如下:

  • N皇后问题
  • 0-1背包问题
  • 装载问题
  • 图着色问题

首先介绍N皇后问题

首先我们认为每个皇后会被放在第i行,其次我们需要搜索的是每个需要被放在第i行的哪一列上

因此我们先构建一个数组sol[]用于存储下标为i的皇后被放在了sol[i]列上,接着使用DFS,搜索每个皇后是否能够被放在第i列上,判断条件是是否当前的位置(i,j)与sol数组内的皇后在同一行/在同一列/在同一条45度斜线上

具体代码实现如下


 接着看背包问题

有 n 种物品,每种物品只有 1 个. 第 i 种物品价值为 vi , 重量为 wi , i =1, 2, … , n. 问如何选择放⼊背包的物品,使得总重量不超过 B, ⽽价值达到最⼤?

首先对问题进行建模

 那么搜索的过程中,我们只需对每一个物品遍历0或1,即遍历是否该物品要选择

 补充搜索空间的概念,这里每一个物品代表了搜索树中的一个层数,而每个物品都有两种选择即选或不选,那么每个节点就有两个分支,那么搜索树的叶子共有2^n(其中n为物品数)


下面是装载问题

我们假设第一艘船的装入量为W1(W1<=c1)

那么我们使用DFS搜索使得c1-W1最小的装载方案

那么如果所有集装箱重量之和-W1<=c2,则找到一种解决方案,反之找不到

该问题的算法实现实际上与01背包类似的,这里不再给出代码

下面是一个例子


下面是图着色问题

 对问题建模

搜索空间为n^m

具体代码实现如下


分支限界

实际上,上面所讲的回溯问题,对于NP问题,搜索空间会指数级增长,而这里的分支限界就是对回溯问题的一种优化,提高回溯的效率(剪枝)

下面是两个分支限界的概念

 根据上述概念

我们可以确定停止当前分支进行回溯的依据

  • 不满足约束条件了
  • 对于最大化问题,代价函数的值小于当前的界

 贪心算法

本章需要掌握的有:

• 活动选择问题

• 最优装载问题

• 最⼩延迟调度问题

• 找零钱问题


一般来说,使用贪心算法之前都会对数据进行排序,再配合约束条件进行决策

  • 如果贪心策略可以得到最优解,需进行正确性证明
  • 反之,需要举反例

首先看活动选择问题

 决策过程是多步判断,每步依据某种“短视”的策略进⾏活动选择,选择时注意满 ⾜相容性条件

 

 对于上述三种策略我们需要一一检验

  对策略1而言

很明显如果一个最早开始的活动持续时间很长,那么期间所有活动都被阻塞了

   对于策略2

如果一个活动时间很短但是它刚好位于两个活动之间,那么它就阻塞了两个活动

 对策略3,是正确的

证明正确性这里忽略


最优装载问题

该问题比较简单,容易想到,每次选择最小的集装箱装载即可


 最小延迟调度问题

 

正确的策略是按照Deadline的大小从小到大进行调度


找零钱问题

 这个比较容易想到每次使用面值最大的钱进行支付即可

动态规划

本章节需要掌握的有:

• 矩阵链相乘问题

• 投资问题

• 背包问题

• 最⼤⼦数组和


动态规划算法的使⽤必须保证问题满⾜以下性质:

⼀个最优决策序列的任何⼦序列本⾝⼀定是相对于⼦序列的初始和结束状态的 最优决策序列

即问题的子问题的结构一定是与原问题结构相同的

动态规划的设计步骤

• 1. 刻画⼀个最优解的结构特征(参数、维度等);

• 2. 递归地定义最优解的值(递推⽅程);

• 3. 采⽤⾃底向上/带备忘的⾃顶向下办法计算最优解的值(⼀个标量);

• 4. 利⽤计算过程中的信息构建⼀个最优解(⼀个选择序列)。 • ** 如果仅需要计算最优解的值,可以忽略第4步。如果确实需要做第4步,应在 求解过程中维护⼀个或多个备忘录,采⽤回溯的办法构造最优解。


先看矩阵链相乘问题

 

 这里主要是需要我们学会手写完成动态规划表

例如上图中的m[1,2]=30*35*15,其余的以此类推

m[1,3]=min{15750+30*15*5,2625+30*35*5},其余的以此类推 


投资问题

 注意这里的m万元钱为整数分配

首先对问题进行建模

接着定义子问题

得到递推方程

 当k=1,即只有一个项目时,那么对于的F(x)也就等于投入钱数x之后的收益直接查表即可

 解释上图计算的过程F2(2)即计算对于前两个项目,拥有资金为2万元时的最大收益,那么即等于max{当前项目投入0元+前面的项目投入2-0元的收益,当前项目投1万元+前面项目投入2-1万元的收益,当前项目投入2万元+前面项目偷人2-2万元的收益}

其余的依次类推即可

 同样的这里要学会填表


背包问题

对问题进行建模

 定义子问题为更小的背包容量以及更少的物品种类

建立递推方程

 如果每种物品存在多个的话


最大子数组和

 定义子问题为左边界为1,右边界为i的数组的最大子数组和是多少

接着寻找子问题之间的关系

不难发现

如果opt(i-1)<0,即opt(i)+A[i]<A[i],那么opt[i]=A[i]

反之,即opt(i)+A[i]>=A[i],那么opt(i)=opt(i-1)+A[i]

分治算法

本章需要掌握的要点如下

• ⼆分检索

• 归并排序

• 幂乘算法的应⽤

• 改进分治算法的两个⽅法

• 增加预处理

• 减少⼦问题个数(整数位乘、矩阵乘法。只需知道算法原理和复杂度)


首先认识分治算法


 二分查找

该算法比较简单直接给出代码

#define _CRT_SECURE_NO_WARNINGS
#include<cstdio>
using namespace std;
const int MAX = 1e7+10;
int n, m;
long long arr[MAX];
int bin_search(int q) {
    int l = 1, r = n, mid=0;
    while(l<r){//终止时l=r 
    	mid=(l+r)/2;
    	if(arr[mid]>=q){
    		r=mid;
		}else{
			l=mid+1;
		}
	}
	return l;
}

int main() {
    scanf("%d%d", &n, &m);
    for (int i = 1; i <= n; i++) {
        scanf("%lld", &arr[i]);
    }
    while (m--) {
        long long q;
        scanf("%lld", &q);
        long long ans=bin_search(q);
        printf("%lld\n", ans);
    }
    return 0;
}

归并排序


 幂乘问题

 这也是快速幂的思路来源

给出代码

#include<iostream>

using namespace std;

int t,a,b,p;

int main(){
	cin>>t;
	while(t--){
		int res=1;
		cin>>a>>b>>p;
		//求a的b次方 
		int base=a;
		int index=b;
		while(index>0){
			if(index%2==1){//指数为奇数 
				//将奇数变偶数
				index--;				
				res=res*base%p;//抽离出多余的一个底数 
			}else{//指数为偶数 
				index/=2;//指数缩小一半
				//底数变为原来的平方 
				base=base*base%p; 
			}
		}
		printf("%d\n",res);
	} 
	return 0;
}

改进分支算法的两个方法

预处理即在算法实验题整数位乘中的补零操作

减小子问题个数即 整数位乘中我们不一定在小规模问题使用分治,即小规模问题使用正常解法即可

算法复杂度分析

 相关概念

对于相同输入规模的不同实例,算法的基本运算次数也不⼀样,可定义两种时间复杂度

• 最坏情况下的时间复杂度W(n)

        • 算法求解输入规模为n 的实例所需要的最⻓时间

• 平均情况下的时间复杂度A(n)

         • 在给定同样规模为n 的输入实例的概率分布下,算法求解这些实例所需要的 平均时间

其中A(n)的计算公式如下

即使用概率论中的均值计算公式

下面是上述两种时间复杂度的计算例子

 

 


函数的渐近表示

 

 


下面介绍递推方程

首先认识递推方程

下面介绍两种求解递推方程的方法

1、迭代法

步骤如下

 例题

补充知识

 2、递归树

 例题


 主定理

 例1

 观察可知a=9,b=3,因此logba=2,因此

又f(n)=n,即f(n)=o(n^2)

符合上述主定理的第一种情况

因此递推方程

 例2

因此递推方程为

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/34786.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

数据结构--串的定义和基本操作

数据结构–串的定义和基本操作 注:数据结构三要素――逻辑结构、数据的运算、存储结构&#xff08;物理结构) 存储结构不同&#xff0c;运算的实现方式不同 \color{pink}存储结构不同&#xff0c;运算的实现方式不同 存储结构不同&#xff0c;运算的实现方式不同 串的定义 串 …

suse ha for sap scale-up性能优化场景安装配置

1. 安装SUSE操作系统 在官网下载SUSE Linux Enterprise Server for SAP Applications安装介质&#xff0c;在安装操作系统过程中&#xff0c;选择SUSE Linux Enterprise Server for SAP Applications操作系统。 在软件选择界面&#xff0c;根据需要选择SAP HANA Server Base…

Pytorch--模型微调finetune--迁移学习 (待继续学习)

https://www.bilibili.com/video/BV1Z84y1T7Zh/?spm_id_from333.788&vd_source3fd64243313f29b58861eb492f248b34 主要方法 torchvision 微调timm 微调半精度训练 背景&#xff08;问题来源&#xff09; 解决方案 大模型无法避免过拟合&#xff0c;

CSS 自定义提示(重写 title 属性)

前言 CSS 原生 title 属性太丑&#xff0c;需要重写 效果 改造 HTML 代码第2行&#xff0c;tip-label 自定义属性 <div class"tools"><div class"btn tip" v-for"item of list" :key"item.icon" :tip-label"item.l…

Linux内核代码中常用的数据结构

Linux内核代码中广泛使用了数据结构和算法&#xff0c;其中最常用的两个是链表和红黑树。 链表 Linux内核代码大量使用了链表这种数据结构。链表是在解决数组不能动态扩展这个缺陷而产生的一种数据结构。链表所包含的元素可以动态创建并插入和删除。 链表的每个元素都是离散…

【电商API接口系列】关键词搜索商品列表,品牌监控场景

API接口允许不同应用程序之间共享数据&#xff0c;在系统之间传输、读取和更新数据。例如&#xff0c;一个电商网站可以通过API接口获取支付系统的支付状态。API接口允许开发人员使用他人开发的功能来扩展自己的应用程序。通过调用第三方API接口&#xff0c;开发人员无需重新实…

Jenkins全栈体系(一)

Jenkins Jenkins&#xff0c;原名 Hudson&#xff0c;2011年改为现在的名字。它是一个开源的实现持续集成的软件工具。 第一章 GitLab安装使用 官方网站&#xff1a;https://about.gitlab.com/ 安装所需最小配置 内存至少4G https://docs.gitlab.cn/jh/install/requireme…

大禹智库:下一代向量数据库————具备在线化,协作化,可视化,自动化和安全互信的向量数据库

目录 一、在线化 二、协作化 三、可视化 四、自动化 五、安全互信 结论&#xff1a; 行业分析报告&#xff1a;下一代向量数据库的特征 摘要&#xff1a; 向量数据库是一种用于存储和处理向量数据的数据库系统。随着人工智能和大数据技术的快速发展&#xff0c;向量数据…

(css)在网页上添加Live 2D网页二次元可动小人

(css)在网页上添加Live 2D网页二次元可动小人 效果&#xff1a; 代码&#xff1a; <script src"js/L2Dwidget.min.js"></script> <script src"js/L2Dwidget.0.min.js"></script> <script>L2Dwidget.init({"model&quo…

SpringBoot2+Vue2实战(十)权限管理

一、父子菜单实现 新建数据库表 sys_menu sys_role 实体类 Role import com.baomidou.mybatisplus.annotation.IdType; import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableName;import java.io.Serializable;import l…

博客相关推荐在线排序学习实践

现有固定槽位的填充召回策略在相关线上推荐服务中缺乏有效的相关性排序&#xff0c;存在较硬的排列顺序&#xff0c;各个策略之间互相影响&#xff0c;导致线上基于规则的拓扑图比较复杂&#xff0c;因此设计在线推理服务&#xff0c;通过学习用户行为完成在线排序。 1. 博客相…

【计算机网络】数据链路层之随机接入-CSMA/CD协议(总线局域网)

1.概念 2.信号碰撞&#xff08;冲突&#xff09; 3.解决方案 CSMA/CD 4.争用期&#xff08;端到端往返时延&#xff09; 5.最小帧长 6.最大帧长 7.指数退避算法 8.信道利用率 9.帧发送流程 10.帧接受流程 12.题目1 13.题目2 14.题目3 15 小结

数字IC后端学习笔记:等效性检查和ECO

1.形式验证工具 对于某些电路的移植&#xff0c;一般不需要对新电路进行仿真验证&#xff0c;而可以直接通过EDA工具来分析该电路的功能是否与原电路一致&#xff0c;此种验证方法可以大量减少验证时间&#xff0c;提高电路的效率。 等效性检查&#xff08;Equivalence Check&a…

给LLM装上知识:从LangChain+LLM的本地知识库问答到LLM与知识图谱的结合

第一部分 什么是LangChain&#xff1a;连接本地知识库与LLM的桥梁 作为一个 LLM 应用框架&#xff0c;LangChain 支持调用多种不同模型&#xff0c;提供相对统一、便捷的操作接口&#xff0c;让模型即插即用&#xff0c;这是其GitHub地址&#xff0c;其架构如下图所示 (点此查…

状态检测防火墙

状态检测防火墙原理 对于已经存在会话表的报文的检测过程比没有会话表的报文要短很多。通过对一条连接的首包进行检测并建立会话后,该条连接的绝大部分报文都不再需要重新检测。这就是状态检测防火墙的“状态检测机制”,相对于包过滤防火墙的“逐包检测机制”的改进之处。这种…

ChatLaw:中文法律大模型

论文题目&#xff1a;ChatLaw: Open-Source Legal Large Language Model with Integrated External Knowledge Bases   论文日期&#xff1a;2023/06/28   官网地址&#xff1a;https://www.chatlaw.cloud   论文地址&#xff1a;https://arxiv.org/abs/2306.16092   G…

Compose编排工具应用

补充&#xff1a; Docker Compose 文件&#xff1a;Docker Compose 是一个用于定义和运行多个 Docker 容器的工具。它使用 YAML 文件格式来描述应用程序的各个组件和其配置。以下是一个简单的示例&#xff1a; 在上面的示例中&#xff0c;我们定义了两个服务&#xff1a;web 和…

浅谈金融场景的风控策略

随着互联网垂直电商、消费金融等领域的快速崛起&#xff0c;用户及互联网、金融平台受到欺诈的风险也急剧增加。网络黑灰产已形成完整的、成熟的产业链&#xff0c;每年千亿级别的投入规模&#xff0c;超过1000万的“从业者”&#xff0c;其专业度也高于大多数技术人员&#xf…

Ubuntu 23.10 现在由Linux内核6.3提供支持

对于那些希望在Ubuntu上尝试最新的Linux 6.3内核系列的人来说&#xff0c;今天有一个好消息&#xff0c;因为即将发布的Ubuntu 23.10&#xff08;Mantic Minotaur&#xff09;已经重新基于Linux内核6.3。 Ubuntu 23.10的开发工作于4月底开始&#xff0c;基于目前的临时版本Ubu…

通过ioctl函数选择不同硬件的控制,LED 蜂鸣器 马达 风扇

通过ioctl函数选择不同硬件的控制&#xff0c;LED 蜂鸣器 马达 风扇 实验现象 head.h #ifndef __HEAD_H__ #define __HEAD_H__ typedef struct{volatile unsigned int MODER; // 0x00volatile unsigned int OTYPER; // 0x04volatile unsigned int OSPEEDR; // 0x08volati…