1. 程式人生 > >遊戲開發常用演算法之分治演算法

遊戲開發常用演算法之分治演算法

    最近給自己定了個小目標,打算把幾大常用演算法吃到自己肚子裡。我覺得程式設計的核心是思想。所以,一切能讓程式設計變得容易的想法我都要學習。好了,下面就是分治演算法。

0x00分治演算法:

 分治策略是:對於一個規模為n的問題,若該問題可以容易地解決(比如說規模n較小)則直接解決,否則將其分解為k個規模較小的子問題,這些子問題互相獨立且與原問題形式相同,遞迴地解這些子問題,然後將各子問題的解合併得到原問題的解。這種演算法設計策略叫做分治法。

0x01分治演算法可以解決的經典問題:

可使用分治法求解的一些經典問題
(1)二分搜尋
(2)大整數乘法
(3)Strassen矩陣乘法
(4)棋盤覆蓋
(5)合併排序
(6)快速排序
(7)線性時間選擇
(8)最接近點對問題
(9)迴圈賽日程表

(10)漢諾塔

0x02程式碼實現:

下面是股票的最近幾天價格表,求出最佳買入時間賣出時間以及最大收益。


namespace 最大分治演算法
{
    class Program
    {
        struct SubArray
        {
            public int startIndex;
            public int endIndex;
            public int total;
        }
        static void Main(string[] args)
        {
            int[] priceArray = { 100, 113, 110, 85, 105, 102, 86, 63, 81, 101, 94, 106, 101, 79, 94, 90, 97 };
            int[] pf = new int[priceArray.Length - 1];//價格波動的陣列
            for (int i = 1; i < priceArray.Length; i++)
            {
                pf[i - 1] = priceArray[i] - priceArray[i - 1];
            }

            SubArray subArray = GetMaxSubArray(0, pf.Length - 1, pf);
            Console.WriteLine(subArray.startIndex);
            Console.WriteLine(subArray.endIndex);
            Console.WriteLine("我們在第" + subArray.startIndex + "天買入, 在第" + (subArray.endIndex + 1) + "天賣出");
            Console.ReadKey();
        }

        static SubArray GetMaxSubArray(int low, int high, int[] array)//這個方法是用來取得array 這個陣列 從low到high之間的最大子陣列
        {

            if (low == high)
            {
                SubArray subarray;
                subarray.startIndex = low;
                subarray.endIndex = high;
                subarray.total = array[low];
                return subarray;
            }

            int mid = (low + high) / 2; // 低區間 [low,mid]  高區間[mid=1,high]

            SubArray subArray1 = GetMaxSubArray(low, mid, array);

            SubArray subArray2 = GetMaxSubArray(mid + 1, high, array);

            //從【low,mid】找到最大子陣列[i,mid]
            int total1 = array[mid];
            int startIndex = mid;
            int totalTemp = 0;
            for (int i = mid; i >= low; i--)
            {
                totalTemp += array[i];
                if (totalTemp > total1)
                {
                    total1 = totalTemp;
                    startIndex = i;
                }
            }
            //從【mid+1,high】找到最大子陣列[mid+1,j]
            int total2 = array[mid + 1];
            int endIndex = mid + 1;
            totalTemp = 0;
            for (int j = mid + 1; j <= high; j++)
            {
                totalTemp += array[j];
                if (totalTemp > total2)
                {
                    total2 = totalTemp;
                    endIndex = j;
                }
            }
            SubArray subArray3;
            subArray3.startIndex = startIndex;
            subArray3.endIndex = endIndex;
            subArray3.total = total1 + total2;
            if (subArray1.total >= subArray2.total && subArray1.total >= subArray3.total)
            {
                return subArray1;
            }
            else if (subArray2.total >= subArray1.total && subArray2.total >= subArray3.total)
            {
                return subArray2;
            }
            else
            {
                return subArray3;
            }
        }
    }
}