遊戲開發常用演算法之分治演算法
阿新 • • 發佈:2019-02-08
最近給自己定了個小目標,打算把幾大常用演算法吃到自己肚子裡。我覺得程式設計的核心是思想。所以,一切能讓程式設計變得容易的想法我都要學習。好了,下面就是分治演算法。
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; } } } }