分治法

乘方问题

输入一个实数x,一个整数n >= 0,计算xn

朴素算法即时对n个x连乘。

分治法:

  xn = xn/2 · xn/2           如果n为偶数

  xn = x(n-1)/2 · x(n+1)/2    如果n为奇数

T(n) = T(n/2) + θ(1) = θ(lg n)

#include<stdio.h>

double Power_Divide(double x, int n);

int main()
{
    int n;
    double x;
    scanf("%d%lf", &n, &x);
    printf("%.3f", Power_Divide(x, n));
    return 0;
}

double Power_Divide(double x, int n)
{
    if(n == 1)
        return x;
    else if(n % 2 == 0)
        return Power_Divide(x, n / 2) * Power_Divide(x, n / 2);
    else if(n % 2 != 0)
        return Power_Divide(x, (n + 1) / 2) * Power_Divide(x, (n - 1) / 2);
}

 

 

Bottom-up algorithm

自下而上递归解决的算法

 

在理论上,根据斐波那契数列的性质

可采用朴素平方递归式求第n项的斐波那契数列

Fn = Φn / √5   并取整至最接近的整数。可以用平方递归在 log n 的时间内计算出。

但是在现实的计算中无法实现。

根据斐波那契数列的一个定理:

通过计算矩阵的n次幂来得到Fn。

这时候是一个log n 的时间算法。

#include<stdio.h>
#include<stdlib.h>

int **Matrix(int **a1, int **a2);
int **Power_Divide(int **a, int n);
 
int main()
{
    int **a = (int **)malloc(2 * sizeof(int *)), **a2;
    int n;
    scanf("%d", &n);
    for(int i = 0; i < 2; i++)
        a[i] = (int *)malloc(2 * sizeof(int));
    a[0][0] = 1;a[0][1] = 1;a[1][0] = 1;a[1][1] = 0;
    a2 = Power_Divide(a, n);
    printf("Fn = %d ",a2[0][1]);
}

int **Matrix(int **a1, int **a2)
{
    int **result;
    result = (int **)malloc(2 * sizeof(int *));
    for(int i = 0; i < 2; i++)
        result[i] = (int *)malloc(2 * sizeof(int));
    result[0][0] = a1[0][0] * a2[0][0] + a1[0][1] * a2[1][0];
    result[0][1] = a1[0][0] * a2[0][1] + a1[0][1] * a2[1][1];
    result[1][0] = a1[1][0] * a2[0][0] + a1[1][1] * a2[1][0];
    result[1][1] = a1[1][0] * a2[0][1] + a1[0][1] * a2[1][1];
    return result;
}

int **Power_Divide(int **a, int n)
{
    if(n == 1)
        return a;
    else if(n % 2 == 0)
        return Matrix(Power_Divide(a, n / 2), Power_Divide(a, n / 2));
    else if(n % 2 != 0)
        return Matrix(Power_Divide(a, (n + 1) / 2), Power_Divide(a, (n - 1) / 2));
}

 

 

矩阵的乘法问题

Input: 两个 n × n 的矩阵

Output: 矩阵乘法的结果

设A和B是两个n × n的矩阵,其中n可以写成2的幂。将A和B分别等分成4个小矩阵,此时如果把A和B都当成2×2矩阵来看,每个元素

就是一个(n /2) × (n /2) 矩阵,而A 和 B乘积就可以写成

常规的分块矩阵乘法计算

这时需要8次矩阵乘法,四次矩阵加法,则所需时间T(n) = 8T(n / 2) + Θ(n2) = Θ(n3)(用主定理可以得出)

这与常规的矩阵乘法算法一样复杂。

可利用斯特拉森算法得到7个小矩阵,分别定义为:

矩阵M1~M7可以通过7次矩阵乘法、6次矩阵加法和4次矩阵减法计算得出,C1~C4可以用矩阵M1~M7

通过6次矩阵加法和2次矩阵减法得出,方法如下:

即可得到T(n) = 7 T(n / 2) + Θ(n2) = Θ(nlg 7) = O(n2.81)

 

posted @ 2018-03-26 23:36  乐高先生  阅读(231)  评论(0编辑  收藏  举报