算法导论第三、四、五章读书笔记


前言

本笔记为仅为本人读《算法导论(第三版)》时的个人理解与感想,非教程解读。如有疏漏错误,还望海涵。

第三章 函数的增长

当输入规模足够大,使得只有运行时间的增长量级有关时,提出我们要研究渐近效率

渐近记号

Θ记号,运行时间函数的上下界;
Ο记号,渐近上界,被Θ记号包涵,不一定是确界,多指最坏运行时间;
Ω记号,渐近下界,被Θ记号包涵,不一定是确界,多指最好运行时间;

渐近上/下界用于确定函数的渐近确界(高等数学-夹逼定理);

ο记号,类似于等价无穷小,非渐近上界;
ω记号,类似于等价无穷大,非渐近下界;

以上函数记号具有:

  • 传递性
  • 自反性
  • 对称性
  • 转置对称性
  • 三分性

常用数学概念

第四章 分治策略

该策略下,递归地求解一个问题,分为:分解(Divide)、解决(Conquer)、合并(Combine)三步。
递归式 为分策略的基础
递归式求法:

  • 代入法
  • 递归树法
  • 主方法T(n) = aT(n / b) + f(n)其中a >= 1, b > 1

最大子数组问题

暴力求解方法: 每对下标的组合Ω(n²)

问题变换为——第 i 个的数值变化为第 i 个和第 i - 1 个的数值差;
重新组织计算方式为——利用之前计算出的子数组的来计算当前子数组的

使用分治策略的求解方法:

int[] netWorth(int[] A) {
	int[] B = new int[A.length - 1];
	for(int i=0;i<A.length-1;i++){
           B[i]=A[i+1]-A[i];
       }
	return B;
}
//处理中间情况
int[] findMaxCrossingSubarray(int[] A, int low, int mid, int high) {
	int sum = 0;
	//先处理左侧
	float sumL = Float.NEGATIVE_INFINITY;
	
	int maxL = mid;
	for(int i = mid; i >= low; --i) {
		sum += A[i];
		if(sum > sumL) {
			sumL = sum;
			maxL = i;
		}
	}
	sumL = (int)sumL;
	//再处理右侧
	sum = 0;
	float sumR = Float.NEGATIVE_INFINITY;
	int maxR = mid;
	for(int i = mid + 1; i <= high; ++i) {
		sum += A[i];
		if(sum > sumR) {
			sumR = sum;
			maxR = i;
		}
	}
	sumR = (int)sumR;
	
	int[] res = {maxL, maxR, (int)(sumL + sumR)};
	return res;
}
int[] findMaxSubarray(int[] A, int low, int high) {
	int[] res;
	if(high == low) {
		res = new int[] {low, high, A[low]};
		return res;
	}
	else {
		int mid = (low + high) / 2;
		int[] L = findMaxSubarray(A, low, mid);
		int[] R = findMaxSubarray(A, mid + 1, high);
		int[] C = findMaxCrossingSubarray(A, low, mid, high);
		
		if(L[2] >= R[2] && L[2] >= C[2]) {
			res = L;
		}
		else if(R[2] >= L[2] && R[2] >= C[2]) {
			res = R;
		}
		else {
			res = C;
		}
		return res;
	}
}

输入数组需经过netWorth()函数转换为净值,然后使用findMaxSubarray()得出结果;

矩阵乘法的Strassen算法

数学思想:
代码如下:

int[][] squareMatrixMultiplication(int[][] A, int[][] B){
	int[][] C = new int[A.length][B[0].length];
	for(int i = 0; i < A.length; ++i) {
		for(int j = 0; j < B[0].length; ++j) {
			for(int k = 0; k  < B.length; ++k) {
				C[i][j] += A[i][k] * B[k][j];
			}
		}
	}
	return C;
}

时间复杂度为Θ(n³)
分治思想:
书中提到关键问题为分解矩阵,入社划分子矩阵,复制元素会花费Θ(n²)时间复制元素,但对总渐近运行时间Θ(n³)并无影响;
可以使用下标计算来分解矩阵;
将矩阵划分为四个规模相同的单元,进行最简单矩阵乘法,然后合并,仅适用于方阵;
书中伪代码过于抽象;
论坛中给出的是想方式,非常复杂;
综上,非必要使用正常方法即可;


时间复杂度为Θ(n³)
Strassen方法:
神仙数学家使用某种奇妙数字组合使矩阵运算由8次乘法变为7次乘法,时间复杂度下降,即:
矩阵
正常递归方法:
r = ae + bg
s = af + bh
t = ce + dh
u = cf + dg
共8次乘法;
大佬改进方法:
P1 = a * (f - h)
P2 = (a + b) * h
P3 = (c + d) *e
P4 = d * (g - e)
P5 = (a + d) * (e + h)
P6 = (b - d) * (g + h)
P7 = (a -c) * (e + f)

r = P5 + P4 - P2 + P6
s = P1 + P2
t = P3 + P4
u = P5 + P1 - P3 - P7
实现:


参考:https://blog.csdn.net/dawn_after_dark/article/details/78686488

递归式求法及递归树画法

暂时没有需求,略;

第五章 概率分析和随机算法

雇佣问题:

  • 生日悖论
  • 球与箱子
  • 特征序列
  • 在线雇佣问题

总结&心得

1、怀疑我看了盗版书,这翻译怎么感觉像机翻的;
2、简单的线性代数骗我说是解方程的我信了,那一些高级的概念呢?太抽象了哇,数学家都是神仙;
3、了解了概率分析在计算机学科上的应用,猜测可能与数据分析有关;

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值