分治算法(用C++、lua实现)

蜗牛慢爬的李成广 2019-11-09

目录




本文为 分治算法 的代码实现。
作者水平比较差,有错误的地方请见谅。

1、算法

分治策略是:对于一个规模为n的问题,若该问题可以容易地解决(比如说规模n较小)则直接解决,否则将其分解为k个规模较小的子问题,这些子问题互相独立且与原问题形式相同,递归地解这些子问题,然后将各子问题的解合并得到原问题的解。这种算法设计策略叫做分治法。

可使用分治法求解的一些经典问题
(1)二分搜索
(2)大整数乘法
(3)Strassen矩阵乘法
(4)棋盘覆盖
(5)合并排序
(6)快速排序
(7)线性时间选择
(8)最接近点对问题
(9)循环赛日程表
(10)汉诺塔

此例子为使用分治法,来求一个数组中的最大连续子段。
分治算法(用C++、lua实现)
连续子段为:-23,18,20,-7,12
最大值为:-23+18+20-7+12 = 43

2、C++实现

暴力求解

#include <iostream>
using namespace std;

int main()
{
    //求最大的连续子段和
    int sumArray[] = {13,-3,-25,20,-3,-16,-23,18,20,-7,12,-5,-22,15,-4,7};
    int length = sizeof(sumArray)/sizeof(sumArray[0]);
    int startIndex = 0;
    int endIndex = 0;
    int maxArray = sumArray[0];

    for(int i=0;i<length;i++){
        int tempPrice = 0;
        for(int j=i;j<length;j++){
            tempPrice += sumArray[j];

            if(tempPrice>maxArray)
            {
                maxArray = tempPrice;
                startIndex = i;
                endIndex = j;
            }
        }
    }

    cout<<"最大数组首index:"<<startIndex<<endl;
    cout<<"最大数组尾index:"<<endIndex<<endl;
    cout<<"最大值"<<maxArray<<endl;

    return 0;
}

分治算法

#include <iostream>

using namespace std;

int startIndex;
int endIndex;
int maxArray;

int GetMaxArray(int arr[],int low,int high);

int main()
{
    int sumArray[] = {13,-3,-25,20,-3,-16,-23,18,20,-7,12,-5,-22,15,-4,7};
    int length = sizeof(sumArray)/sizeof(sumArray[0]);
    startIndex = 0;
    endIndex = 0;
    maxArray = sumArray[0];


    GetMaxArray(sumArray,0, length-1);
    cout<<"首index:"<<startIndex<<endl;
    cout<<"尾index:"<<endIndex<<endl;
    cout<<"最大值"<<maxArray<<endl;

    return 0;
}

int GetMaxArray(int arr[],int low,int high)
{
    if (low == high)
    {
        startIndex = low;
        endIndex = high;
        return maxArray;
    }


    int mid = (low + high) / 2;
    //左区间的最大子段
    int leftMax = GetMaxArray(arr,low, mid);
    //右区间的最大子段
    int rightMax = GetMaxArray(arr,mid + 1, high);

    //左下标在左区间右下标在右区间的最大字段
    int allMax = 0;

    //计算allMax的左半最大部分
    int allMaxLeft = arr[mid] ;
    int leftIndex = mid;
    int tempNum = 0;
    for (int i = mid; i >= low; i--)
    {
        tempNum += arr[i];
        if (tempNum > allMaxLeft)
        {
            allMaxLeft = tempNum;
            leftIndex = i;
        }
    }

    //计算allMax的右半最大部分
    int allMaxRight = arr[mid + 1];
    int rightIndex = mid + 1;
    tempNum = 0;
    for (int j = mid + 1; j <= high; j++)
    {
        tempNum += arr[j];
        if (tempNum > allMaxRight)
        {
            allMaxRight = tempNum;
            rightIndex = j;
        }
    }

    //三者比较,谁的值最大
    allMax = allMaxLeft + allMaxRight;
    startIndex = leftIndex;
    endIndex = rightIndex;

    return max(max(leftMax, rightMax), allMax);
}

3、lua实现

sumArray = {13,-3,-25,20,-3,-16,-23,18,20,-7,12,-5,-22,15,-4,7}
length = #sumArray
startIndex = 1
endIndex = 1
maxArray = sumArray[1]

function GetMaxArray(arr,low,high)
    if(low == high) then
        startIndex = low;
        endIndex = high;
        return maxArray;
    end

    --mid不能为浮点数,向下取整
    local mid = math.floor((low+high)/2)
    --左区间最大值
    local leftMax = GetMaxArray(arr,low,mid)
    --右区间最大值
    local rightMax = GetMaxArray(arr,mid+1,high)

    --左下标在左区间右下标在右区间的最大字段
    local allMax = 0
    --计算allMax的左半最大部分
    local allMaxLeft = arr[mid]
    local leftIndex = mid
    local tempNum = 0
    for i=mid,low,-1 do
        tempNum = tempNum + arr[i]
        if(tempNum > allMaxLeft) then
            allMaxLeft = tempNum
            leftIndex = i
        end
    end
    --计算allMax的右半最大部分
    local allMaxRight = arr[mid+1]
    local rightIndex = mid+1
    tempNum = 0
    for i=mid+1,high,1 do
        tempNum = tempNum + arr[i]
        if(tempNum > allMaxRight) then
            allMaxRight = tempNum
            rightIndex = i
        end
    end
    allMax = allMaxLeft + allMaxRight

    --使用lua的多返回值
    return leftIndex,rightIndex,MaxNum(MaxNum(leftMax,rightMax),allMax)
end

--自定义比较两个整数函数
function MaxNum(num1,num2)
    if(num1>num2) then
        return num1
    end
    return num2
end


startIndex,endIndex,maxArray = GetMaxArray(sumArray,1,length)

print("首index:" .. startIndex)
print("尾index:" .. endIndex)
print("最大值:" .. maxArray)

相关推荐

优化算法 / 0评论 2020-11-13