• 算法分析与设计CH11:关于分治的其他算法——矩阵乘法的分治、最大子数组和的分治求解


    CH11:Divide and Conquer:More Algorithms

    在这里插入图片描述

    10.1 Square matrix multiplication 矩阵相乘

    10.1.1 分治算法

    A = ( a i j ) , B = ( b i j ) A = (a_{ij}),B = (b_{ij}) A=(aij)B=(bij),都是n×n的矩阵

    定义: C = A × B , c i j = ∑ k = 1 n a i , k b k , j C = A\times B, c_{ij} = \sum_{k=1}^{n}a_{i,k}b_{k,j} C=A×B,cij=k=1nai,kbk,j

    矩阵相乘的算法:

    image-20220608143746675

    分治:partition

    矩阵相乘符合标量乘法

    image-20220608143901862

    矩阵乘法的分治:Square-Matrix-Multiply-Recursive(A,B)

    image-20220608145329966
    T(n)=8T(n/2)+(n2)2f(n)=Θ(n2)nlog28=n3T(n)=O(n3)" role="presentation" style="position: relative;">T(n)=8T(n/2)+(n2)2f(n)=Θ(n2)nlog28=n3T(n)=O(n3)
    image-20220608150309071

    10.1.2 Strassen’s method

    image-20220608150547235

    10.2 The Maximum - subarray problem

    10.2.1 问题背景

    要求最低点买入?最高点卖出?

    image-20220608150949929

    建模为最和子数组和问题:

    image-20220608151033159

    10.2.2 暴力解法

    暴力解法:穷举所有的子数组——穷举所有的下标可能情况,找出最大值的子数组.

    暴力解法程序如下:

    // 暴力穷举子数组 
    int maxSum_brute(vector<int>& vec) {
    	int maxSum = -1;
    	int besti = -1, bestj = -1;
    	for (int i = 0; i < vec.size(); i++) {
    		int tempSum = vec[i];
    		for (int j = i+1; j < vec.size(); j++) {
    			tempSum += vec[j];
    			if (tempSum > maxSum) {
    				maxSum = tempSum;
    				besti = i;
    				bestj = j;
    			}
    		}
    	}
    	return maxSum;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    时间复杂度是 O ( n 2 ) O(n^2) O(n2)

    10.2.3 分治法

    分治法需要额外考虑一个cross的情况:最优解可能是在两个子数组的中间得到。
    { 二分 n 推 n − 1

    {nn1" role="presentation" style="position: relative;">{nn1
    {二分nn1

    • Divide:把数组分成两个数组
    • Conquer:递归求解子问题,并额外求解跨越中间的情况
    • Combine:三挑一,找到最大和子数组
    image-20220608153148962

    算法实现如下:

    // 分治法,含有cross
    int getMidMax(vector<int>& vec, int start, int end, int mid) {
    	int maxsum = vec[mid];
    	int maxNum = vec[mid];
    	for (int i = mid - 1; i >= start; i--) {
    		maxsum += vec[i];
    		if (maxsum > maxNum) {
    			maxNum = maxsum;
    		} 
    	}
    	maxsum = maxNum;
    	for (int i = mid + 1; i <= end; i++) {
    		maxsum += vec[i];
    		if (maxsum > maxNum) {
    			maxNum = maxsum;
    		}
    	} 
    	return maxNum;
    }
    
    int maxSum(vector<int>& vec, int start, int end) {
    	if (start == end) 
    		return vec[start];
    	// 分 
    	int mid = (start + end) / 2;
    	// 治 
    	int maxSumLeft = maxSum(vec, start, mid);
    	int maxSumRight = maxSum(vec, mid + 1, end);
    	int maxSumCross = getMidMax(vec, start, end, mid);
    	// 合并 
    	int maxNum = max(maxSumLeft, maxSumRight);
    	maxNum = max(maxNum, maxSumCross);
    	return maxNum;
    } 
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34

    时间复杂度: n l g n nlgn nlgn

    T ( n ) = 2 T ( n / 2 ) + Θ ( n ) T(n) = 2T(n/2) + \Theta(n) T(n)=2T(n/2)+Θ(n)

    f ( n ) = n l o g 2 2 = n = Θ ( n l g 0 k ) f(n) = n^{log_2^2} = n = \Theta(nlg^0k) f(n)=nlog22=n=Θ(nlg0k)

  • 相关阅读:
    配置git在Linux服务器上
    flutter run可以运行,但是Android sync同步一直报错
    UE5报错及解决办法
    骑马钉 根据列行页数 生成 排序规则 java版 JavaScript版 python版
    计算机竞赛 深度学习实现行人重识别 - python opencv yolo Reid
    433-C++基础语法(51-60)
    单阶段目标检测--NMS
    【杂记-浅谈XSS跨站脚本攻击】
    【小程序 - 加强】自定义组件、使用npm包、全局数据共享、分包_05
    磁盘、内存和硬盘的区别
  • 原文地址:https://blog.csdn.net/weixin_45745854/article/details/126166618