贪心方法 greedy method:
逐步构造最有解(其实是近似最优的解)。每一步,我们都在一定的标准(这个标准叫贪婪准则 greedy criterion)下作出一个最优决策。
最优化问题 optimization problem:包含一组限制条件(constraint)和一个优化函数(optimization function)。符合限制条件的问题求解方案称为可行解(feasible solution)。使优化函数可能取得最佳值的可行解称为最优解(optimal solution)。
1.货箱装载问题
有一艘大船要装载货物。货物要装载货箱中,所有货箱的大小都一样,但货箱的重量各不相同。设第i个货箱的重量为Wi,(1 <= i <= n), 货船的最大载重量为c。我们的目的是在货船上装入最多的货物。
note:这个问题可以精确地描述为最优化问题:设存在一组变量xi (表示 i 号箱装船与否),xi的值是0或1。如 xi 为 0,则货箱 i 不装船; 如 xi 为 1 ,则货箱 i 装船。我们要找到一组 xi,使它满足限制条件ΣWixi<=c. 优化函数是 Σxi。每一组满足限制条件的xi都是一个可行解。使得Σxi最大的可行解就是最优解。
贪婪求解:把货箱分步装载到货船上,一步装载一个货箱。每一步决定装载哪一个货箱。做决定所依据的贪婪准则是:从剩下的货箱中,选择重量最小的货箱。这样可以保证所选的货箱总重量最小,从而使得货船改用最大的容量来装载更多的货箱。根据这种贪婪策略,首先选择最轻的货箱,然后选择次轻的货箱,如此下去,直到所有货箱均装上床,或船上不能再容纳一个货箱的空间。
我们最终的程序流程是:重量从小到大排序,然后挨个往船上装。——好朴素啊。
void continerLoading(container* c, int capacity, int numberOfContainers, int* x)
{//货箱装载的贪婪方法
//令 x[i] = 1, 当且仅当货箱 i (i >= 1)已装载
//按照重量递增排列 O(nlogn)
heapSort(c, numberOfContainers);
int n = numberOfContainers;
//初始化x
for(int i = 1; i <= n; i++)
x[i] = 0;
//按照重量顺序选择货箱
for(int i = 1; i <= n && c[i].weight <= capacity; i++)
{//对货箱c[i].id有足够的容量 id表示货箱的范围,从1到货箱数量。
x[c[i].id] = 1;
capacity -= c[i].weight; //剩余容量
}
}
程序首先使用堆排序法按照重量对货箱排序。然后按照重量递增顺序,把货箱装上船。排序O(nlogn), 算法其他部分用时O(n).所以程序总的复杂性是O(nlogn)。
2.单源最短路径