算法之路-------贪心算法

本文介绍了贪心算法的基本思想、算法过程及其存在的问题。贪心算法每次选择局部最优解,试图通过子问题的最优解来求得原问题的最优解。然而,这种方法并不保证能得到全局最优解。文中举例说明了贪心算法在买股票最佳时机问题和跳跃游戏中如何应用,阐述了如何通过贪心策略找到问题的可行解。

算法思想

贪心算法,顾名思义做到贪心那就要让算法实现的每一步都是最好的一步。

  • 贪心算法(又称贪婪算法)是指,在对问题求解时,总是做出在当前看来是最好的选择。也就是说,不从整体最优上加以考虑,他所做出的是在某种意义上的局部最优解。
  • 贪心选择是指所求问题的整体最优解可以通过一系列局部最优的选择,即贪心选择来达到。这是贪心算法可行的第一个基本要素。
  • 当一个问题的最优解包含其子问题的最优解时,称此问题具有最优子结构性质。运用贪心策略在每一次转化时都取得了最优解。问题的最优子结构性质是该问题可用贪心算法求解的关键特征。贪心算法的每一次操作都对结果产生直接影响。贪心算法对每个子问题的解决方案都做出选择,不能回退。
  • 贪心算法的基本思路是从问题的某一个初始解出发一步一步地进行,根据某个优化测度,每一步都要确保能获得局部最优解。每一步只考虑一个数据,他的选取应该满足局部优化的条件。若下一个数据和部分最优解连在一起不再是可行解时,就不把该数据添加到部分解中,直到把所有数据枚举完,或者不能再添加算法停止。
  • 实际上,贪心算法适用的情况很少。一般对一个问题分析是否适用于贪心算法,可以先选择该问题下的几个实际数据进行分析,就可以做出判断。

所以,贪心算法其实就是将整个算法分为很多子算法,而贪心算法就是分成的那些子算法全部最优的解的集合。

算法的过程及存在的问题

1.算法的过程

  1. 建立数学模型来描述问题。
  2. 把求解的问题分成若干个子问题。
  3. 对每一子问题求解,得到子问题的局部最优解。
  4. 把子问题的局部最优解合成原来解问题的一个解。

其实也就是即假设一个问题比较复杂,暂时找不到全局最优解,那么我们可以考虑把原问题拆成几个小问题(分而治之思想),分别求每个小问题的最优解,再把这些“局部最优解”叠起来,就“当作”整个问题的最优解了。

2.算法存在的问题

  • 不能保证求得的最后解是最佳的。
  • 不能用来求最大值或最小值的问题。
  • 只能求满足某些约束条件的可行解的范围。

经典例题

1.买股票的最佳时机Ⅱ(取自力扣)
在这里插入图片描述
解法:
①:对于这道题的解法,我们肯定是要有贪心的思想,也就是应该是在股票价格最低的时候我们把它买了,然后在股票价格最高的时候把他卖了,然后依次如此。

②:因为股票的价格是起伏的,所以我们找到最低点买入,最高点卖出,而我们可以通过看这个股票的价格是否是在继续涨价而判断我们是否要卖这个股票,但是这样的算法实现起来会很困难,所以我们使用的是如果当前的股票的价格比我们买股票的时股票的价格大,就直接卖出。

③:通过②了解到,我们卖股票的时候只要当前股票价格比我们买入的股票价格大,我们就卖出,然后将买入的股票定位为当前卖出时的股

一、实验目的: 掌握分页式存储管理的基本概念和实现方法。要求编写一个模拟的分页式管理程序, 并能对分页式存储的页面置换算法进行编写和计算各个算法的缺页率。 二、程序设计: 假定一个能够存放M个页面的内存,当发生缺页时,调入一个页面, 通过LRU算法求出应该置换出的页面号。输入一连串的页面号, 程序自动选择调出的页面并计算缺页率。 设计页面置换算法,这里采用最近最久未使用置换算法LRU。 LRU算法的实现要归功于一个8位的寄存器的实现。 三、算法说明: 执行程序时,当主存没有可用页面时,为了选择淘汰主存中的哪一页面, 腾出1个空闲块以便存放新调入的页面。淘汰哪个页面的首要问题是选择何种置换算法。 该程序采用LRU方法选择,依置换策略选择一个可置换的页面并计算它们的缺页率以便比较。 */ #include using namespace std; #define M 3 #include int reg[2][M]; int count; int num; int N; /********初始化函数,数组reg[0][i]存放页面号,初始化为-1,reg[1][i]当作寄存器, 初始化为0*********/ void init() { int i,count=0;num=0; N=(int)pow(2,7); /********二进制数10000000**********/ for(i=0;i<M;i++) { reg[0][i]=-1; reg[1][i]=0; } } /*********寻找数组a中的最小值,返回最小值对应的下标***********/ int min(int a[]) { int i,index=0; int min=a[0]; for(i=1;ia[i]) { min=a[i]; index=i; } } return index; } /***判断页面号x是否在数组中,如果在,返回对应的下标;否则返回-1***/ int isIn(int x,int a[]){ int i; int index=-1; for(i=0;i<M;i++) { if(a[i]==x) { index=i; break; } } return index; } /**********判断虚拟的内存中是否已经存满了页面,如果满了,则返回-1, 没有满则返回找到空的对应的第一个下标**************/ int isFull(int a[]) { int i,index=-1; for(i=0;i<M;i++) { if(a[i]==-1) { index=i; break; } } return index; } /*************页面置换方法*****************/ void swap(int x) { int i,k,temp,temp0,count; int index=isIn(x,reg[0]); /****判断x是否在reg[0]数组中*******/ if(index!=-1) { reg[1][index]=reg[1][index]^N; }/**reg[1][index]异或二进制数10000000**/ else{ temp=isFull(reg[0]); if(temp!=-1) /*******内存没有满,直接调入页面************/ { reg[0][temp]=x; reg[1][temp]=reg[1][temp]^N; } else if(temp==-1) { k=min(reg[1]); /**置换出寄存器中数值最小的对应的下标的页面***/ temp0=reg[0][k]; /*********临时保留要换出的页面号*****/ reg[0][k]=x; reg[1][k]=reg[1][k]^N; printf("the page %d is exchanged out!\n",temp0); /******打印要置换出的页号**************/ count++; /*********置换次数加1**************/ } } for(i=0;i>1; }/********寄存器中的所有数右移一位*****/ /***************打印缺页数和缺页率**********************/ printf("the count of Exchanged is: %d \n",count); printf("the rate of exchanged is: %f\n",count*1.0/num); }
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值