• 算法分析与设计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)

  • 相关阅读:
    【kafka】 | 03 | kafka、zk和cmak开机自启动
    Java之线程相关应用实现
    NNG pair 异步通信
    Maven
    快手如何快速的进行引流,并且推荐几款我正在用的工具。
    vue3+ele-plus+sortableJs对el-table使用sortableJs插件对表格拖拽时限定某列或某行不允许拖拽
    dubbo 问题整理
    【Unity】苹果(IOS)开发证书保姆级申请教程
    Ubuntu 安装 CUDA 与 CUDNN GPU加速引擎
    Rust机器学习之ndarray
  • 原文地址:https://blog.csdn.net/weixin_45745854/article/details/126166618