正则表达式中的 贪婪算法可以求解的经典问题包括货箱装船问题、背包问题、拓扑排序问题、二分覆盖问题、最短路径问题、最小代价生成树等问题。
这里面涉及到的一些基本概念有
1:最优化问题:每个最优化问题都包含一组限制条件和一个优化函数,符合限制条件的问题求解方案称为可行解,这样就有了一个满足解条件的函数组,在数学领域称之为线性规划,线性规划函数取得最佳值的可行解称为最优解。
2:贪婪算法:采用逐步构造最优解的方法。在每个阶段,都作出一个看上去最优的决策(在一定的标准下)。决策一旦作出,就不可再更改。作出贪婪决策的依据称为贪婪准则。
3:贪婪准则:1)每步贪婪;2)不回溯;3)选择的规则非常重要,不正确的规则可能得不到结果、不优化或者不能作为贪婪的求解对象;4)必定有解,但是可能不会得到最优解。
实例分析:一个小孩买了价值少于1美元的糖,并将1美元的钱交给售货员。售货员希望用数目最少的硬币找给小孩。假设提供了数目不限的面值为2 5美分、1 0美分、5美分、及1美分的硬币。售货员分步骤组成要找的零钱数,每次加入一个硬币。选择硬币时所采用的贪婪准则如下:每一次选择应使零钱数尽量增大。为保证解法的可行性(即:所给的零钱等于要找的零钱数),所选择的硬币不应使零钱总数超过最终所需的数目。
const int SIZE = 15; int coins[SIZE] = {10, 25, 5, 5, 10, 25, 25, 5, 1,1,1, 5, 10,5,10}; // compare used in qsort() for coins[] int _cdecl comp(const void* left, const void* right ) { if (*(int*)left < *(int*)right ) return 1; else if (*(int*)left == *(int*)right ) return 0; else return -1; } // greedy for coin-change. returns the total used coins int change(int problem, int result[]) { int i = 0; int j = 0; while ( (problem > 0) && ( i < SIZE )) { while ( i < SIZE ) // coins can not be re-used { if (problem >= coins[i]) { result[j] = coins[i]; problem -= result[j]; j++; i++; break; } i++; } } if ( problem > 0) return 0; return j; } // for test int main(int argc, char* argv[]) { // sort the input qsort(coins, sizeof(coins)/sizeof(int),sizeof(int), comp); for ( int i = 0; i < 10; i++) { int problem = 0; printf("Problem:>>>/n"); scanf("%d", &problem); int result[SIZE] = {0}; int numbers = change(problem, result); printf("Solution:>>>/n"); if ( numbers > 0) { numbers--; for ( ; numbers >= 0; numbers-- ) printf("%d,", result[numbers]); } else printf("no solution!"); printf("/n"); } return 0; }