【趣学算法】Day2 贪心算法——最优装载问题

简介: 【趣学算法】Day2 贪心算法——最优装载问题

一、贪心算法


(1)介绍


贪心算法总是做出当前最好的选择,期望通过局部最优解选择,从而得到全局最优的解决方案。


(2)注意事项


1)一旦做出选择,就不可以回溯。

2)有可能得不到最优解,而是得到最优解的近似值。

3)选择什么样的贪心策略直接决定了算法的好坏。

(3)性质

人们通过实践发现,利用贪心算法求解的问题往往具有两个重要的性质:贪心选择和最优子结构。只要满足这两个性质,就可以使用贪心算法。

1)贪心选择

贪心选择是指原问题的整体最优解可以通过一系列局部最优的选择得到:先做出当前最优的选择,将原问题变为一个相似却规模更小的子问题,而后的每一步都是当前最优的选择。这种选择依赖于已做出的选择,但不依赖于未做出的选择。

2)最优子结构

       最优子结构是指原问题的最优解包含子问题的最优解。贪心算法通过一系列的局部最优解(子问题的最优解)得到全局最优解(原问题的最优解),如果原问题的最优解和子问题的最优解没有关系,则求解子问题没有任何意义,无法采用贪心算法。


二、最优装载问题

       海盗们截获一艘装满各种各样古董的货船,每一件古董都价值连城,但一旦打碎就会失去其原有的价值。海盗船虽然足够大,但载重量是有限的。海盗船的载重量为W,每件古董的重量为wi,如何才能把尽可能多的古董装上海盗船呢。


(1)古董重量排序

海盗船的载重量w为30。

排序前的古董重量为:

w[i] = {4, 10, 7, 11, 3, 5, 14, 2};

排序后的古董重量为:

w[i] = {2, 3, 4, 5, 7, 10, 11, 14};


(2)贪心策略选择

按照贪心策略,每次选择重量最小的古董装入海盗船(tmp代表已装入的古董重量,ans代表已装入的古董重量)。

1)选择排序后的第1个古董,装入重量tmp = 2,没有超出载重量,ans = 1;

2)选择排序后的第2个古董,装入重量tmp = 2 + 3 = 5,没有超出载重量,ans = 2;


3)选择排序后的第3个古董,装入重量tmp = 5 + 4 = 9,没有超出载重量,ans = 3;


4)选择排序后的第4个古董,装入重量tmp = 9 + 5 = 14,没有超出载重量,ans = 4;


5)选择排序后的第5个古董,装入重量tmp = 14 + 7 = 21,没有超出载重量,ans = 5;


6)选择排序后的第6个古董,装入重量tmp = 21 + 10 =31,没有超出载重量,ans = 6;


当第六次装入古董时可以发现已经超出了船的载重量,所以古董最多装ans = 5个

模板代码

(1)分析

       首先使用变量ans记录装入海盗船的古董数量,并使用变量tmp暂存装入海盗船的古董重量。然后依次检查每个古董,对tmp加上改古董的重量,如果小于或的等于载重w,责令ans++,否则退出。

(2)伪代码


int solve1(int n,double W){
  double tmp=0.0;//tmp为已装载到船上的古董重量
    int ans=0; //ans为已装载的古董个数,初始化为0
    for(int i=0;i<n;i++){
        tmp+=w[i];
        if(tmp<=W)
            ans++;
        else
            break;
    }
    return ans;
} 

代码优化

(1)分析


实际上,不需要在每次判断是否超出载重时执行ans++,而是可以初始化ans = n。如果已装入海盗船的古董重量tmp大于或等于载重量w,则判断是否刚好等于载重量w并令ans = i + 1,否则令ans = i并退出。这样就只有最后一次才满足条件,ans只需要赋值一次即可,或者所有古董都被装入(初始值n)。


(2)伪代码

int solve2(int n,double w){//优化算法 
  double tmp=0.0;//tmp为已装载到船上的古董重量
  int ans=n; //ans为已装载的古董个数,初始化为n
    for(int i=0;i<n;i++){
        tmp+=w[i];
        if(tmp>=w){//最后一次才满足条件 
          if(tmp==w)
            ans=i+1;
          else
            ans=i;
          break;
    }     
    }
    return ans;
}


三、 程序实现

注:程序由Java语言实现

public class algorithm02 {
    public static void main(String[] args) {
        int[] w = {4, 10, 7, 11, 3, 5, 14, 2};
        int W = 30; // 船的载重量
        int temp;
        for (int i = 0; i < w.length-1; i++) {
            for (int j = 0; j < w.length - i - 1; j++) {
                if (w[j] > w[j + 1]) {
                    temp = w[j];
                    w[j] = w[j + 1];
                    w[j + 1] = temp;
                }
            }
        }
        System.out.println("古董重量排序后为:");
        for (int j = 0; j < w.length; j++) {
            System.out.print(w[j] + " ");
        }
            add02 a2 = new add02();
            int ans = a2.solve2(8 , W , w);
            System.out.println("\n总共装入了" + ans + "个古董");
    }
}
// add02类
public class add02 {
    public int solve2(int n , int W ,int w[]){//优化算法
        double tmp = 0.0;//tmp为已装载到船上的古董重量
        int ans = 0; //ans为已装载的古董个数,初始化为n
        for(int i = 0; i < n; i++){
            tmp += w[i];
            if(tmp >= W){//最后一次才满足条件
                if(tmp == W)
                    ans = i+1;
                else
                    ans = i;
                break;
            }
        }
        return ans;
    }
}


得到结果为:


0a09a4149e75402ca3f7e38f61463aee.png


因为船的载重量为30,所以在装入第五个古董后就无法装入第六个了。

相关文章
|
8天前
|
算法 Python
在Python编程中,分治法、贪心算法和动态规划是三种重要的算法。分治法通过将大问题分解为小问题,递归解决后合并结果
在Python编程中,分治法、贪心算法和动态规划是三种重要的算法。分治法通过将大问题分解为小问题,递归解决后合并结果;贪心算法在每一步选择局部最优解,追求全局最优;动态规划通过保存子问题的解,避免重复计算,确保全局最优。这三种算法各具特色,适用于不同类型的问题,合理选择能显著提升编程效率。
25 2
|
1月前
|
算法 Java C++
【贪心算法】算法训练 ALGO-1003 礼物(C/C++)
【贪心算法】算法训练 ALGO-1003 礼物(C/C++)
【贪心算法】算法训练 ALGO-1003 礼物(C/C++)
|
5月前
|
算法 C++ Python
数据结构与算法===贪心算法
数据结构与算法===贪心算法
|
2月前
|
算法 前端开发
一文了解贪心算法和回溯算法在前端中的应用
该文章深入讲解了贪心算法与回溯算法的原理及其在前端开发中的具体应用,并通过分析LeetCode题目来展示这两种算法的解题思路与实现方法。
|
3月前
|
算法
【算法】贪心算法——柠檬水找零
【算法】贪心算法——柠檬水找零
|
3月前
|
算法
【算法】贪心算法简介
【算法】贪心算法简介
|
4月前
|
机器学习/深度学习 数据采集 算法
Python实现GBDT(梯度提升树)分类模型(GradientBoostingClassifier算法)并应用网格搜索算法寻找最优参数项目实战
Python实现GBDT(梯度提升树)分类模型(GradientBoostingClassifier算法)并应用网格搜索算法寻找最优参数项目实战
171 3
|
4月前
|
算法 Python
Python算法高手进阶指南:分治法、贪心算法、动态规划,掌握它们,算法难题迎刃而解!
【7月更文挑战第10天】探索Python算法的精华:分治法(如归并排序)、贪心策略(如找零钱问题)和动态规划(解复杂问题)。通过示例代码揭示它们如何优化问题解决,提升编程技能。掌握这些策略,攀登技术巅峰。
120 2
|
4月前
|
存储 算法 Python
Python算法界的秘密武器:分治法巧解难题,贪心算法快速决策,动态规划优化未来!
【7月更文挑战第9天】Python中的分治、贪心和动态规划是三大关键算法。分治法将大问题分解为小问题求解,如归并排序;贪心算法每步选局部最优解,不保证全局最优,如找零钱;动态规划存储子问题解求全局最优,如斐波那契数列。选择合适算法能提升编程效率。
67 1
|
4月前
|
存储 算法 大数据
Python算法高手的必修课:深入理解分治法、贪心算法、动态规划,让你的代码更智能!
【7月更文挑战第9天】在Python算法学习中,分治法(如归并排序)将大问题分解为小部分递归解决;贪心算法(如货币找零)在每步选择局部最优解尝试达到全局最优;动态规划(如斐波那契数列)通过存储子问题解避免重复计算,解决重叠子问题。掌握这三种方法能提升代码效率,解决复杂问题。
48 1