贪心算法-最优装载问题

贪心算法-最优装载问题

学习贪心算法,我们要先了解一下贪心的本质是什么

贪心本质
一个贪心算法总是做出当前最好的选泽,也就是通过局部最优选择从而得到全局最优选择,从而实现自己的目标。

贪心算法的注意事项
1.贪心算法只能向前走而不能后退

2.局部的最优解可能不是最终的最优解,而是最优解的近似解

3.在面对一个问题时,往往具有多种贪心选择策略,而选择什么样的策略则直接决定设计算法的好坏

贪心算法的两个重要特性
1>贪心选择性质
2>最优子结构性质

1>贪心选择性质
是指原问题的整体最优解是可以通过一系列局部最优解得到的。往往可以将原问题转化为一个相似的但是规模却更小的子问题。使得在解决问题的每一步中都是其最佳选择。而一旦这个方法开始了就无法进行回溯(回头重找)

2>最优子结构性质
当一个问题的最优解包含其子问题的最优解时,称此问题具有最优子结构性质
(就是说将原问题转化为相同性质的子问题)
如果原问题的最优解包含子问题的最优解,则说明该问题满足最优子结构的性质

贪心算法实施策略
1.贪心策略:首先确定贪心策略
例如你挑选苹果,如果你认为越大的苹果越好,那么你每次挑苹果的时候总是会选择一堆当中最大的,直到你将袋子装满为止
但是如果你认为越硬的或者越红的越好吃,那么你自然就会选最红的或者最硬的吃。所以说你在求解目标不同时,选择的贪心策略也会不同

2.局部最优解
根据之前选择的贪心测量策略,一步一步得到局部最优解
比如第一次拿了一堆苹果里最大的,那么下一次就会拿剩下堆里最大的,以此类推…

3.全局最优解
把你每一步选择的最优解联系起来,合成原问题的最优解

  • 最优装载问题
    海盗们截获了一艘装满各种各样古董的船,虽然每件古董都价值连城,但是一旦打碎就失去了价值,海盗们船的最大载重量为C,每件古董的重量都不尽相同。海盗们如何把尽可能多数量的宝贝运送到自己的船呢?

分析:该问题其实就是一个可以用贪心算法求解的最优装载问题,要求装在物品的数量要尽可能的多,而船的数量是固定的,所以优先把重量小的物品装进去,在容量固定的情况下,装的物品最多。

采用重量最轻先装的策略,从局部最优解达到整体最优,从而产生最优装载问题的最优解。

图解:
贪心算法-最优装载问题_第1张图片
上面是古董的重量表,下面是排序过的
所以算法策略就是将其从小到大进行排序然后进行累加,知道装入的总重量大于等于船的最大载重量时,循环结束

算法演示:

*输入重量c以及古董个数n*
c:30
n:8


*输入每个古董的重量*
4   10   7   11   3   5   14   2


*输入每个古董的重量*
4   10   7   11   3   5   14   2


*求出最大载重数量为*:5


项目 Value
1. 定义古董个数,以及船的最大承载量和控制台输入值
2. 用数组装古董的个数利用for循环进行输入
3. 快排将古董重量由小到大进行排序
4. 定义临时变量
5. for循环进行填装古董,if else语句进行判断是否超重

代码如下:


#include
#include "algorithm"
using namespace std;
int main(){
    int n;//定义古董个数
    double c;//定义船的最大承载量
    cout<<"输入古董个数以及船的最大承载量"<<endl;
    cin>>c>>n;
    cout<<"输入每件古董的重量,用空格分开"<<endl;
    double w[n];//用数组填装古董的个数
    for(int i=0;i<n;i++){
        cin>>w[i];
    }

    sort(w,w+n);//快排将古董的重量由小到大进行排序
    double temp=0.0;//中间值(相当于一个箱子将宝物装进去,然后将箱子装到船上)
    int count=0;//计数器
    for(int i=0;i<n;i++) {
        temp+=w[i];
        if(temp<=c){
            count++;

        }
        else{
            break;
        }
    }

    cout<<"能装入古董最大数量为count"<<count<<endl;
    return 0;
}

算法时间复杂度为O(nlogn)
算法空间复杂度为O(1)

你可能感兴趣的:(#,算法,算法,贪心算法)