最新贪婪算法-装箱问题等练习
贪心算法之装箱问题
贪⼼算法之装箱问题问题描述装箱问题可简述如下:设有编号为 0、1、…、n - 1 的 n 种物品,体积分别为v0、v1、…、vn-1。
将这 n 种物品装到容量都为 V 的若⼲箱⼦⾥。
约定这 n 种物品的体积均不超过 V,即对于 0≤ i<n,有 0<vi ≤ v。
不同的装箱⽅案所需要的箱⼦数⽬可能不同。
装箱问题要求使装尽这 n 种物品的箱⼦数要少。
贪⼼求解使⽤⼀种贪⼼策略:每次都想将当前体积最⼤的物品装⼊箱中,在这块类似于这个问题 ->>>其实在⽣活中这也是很常见的⼀种做法,在没有充⾜时间去考虑如何最优解决这类问题时直觉(第六感狗头保命)告诉我们可以这么去试试。
更直接的⼀个例⼦,⼒扣上有这么⼀道题:在柠檬⽔摊上,每⼀杯柠檬⽔的售价为 5 美元。
顾客排队购买你的产品,(按账单 bills ⽀付的顺序)⼀次购买⼀杯。
每位顾客只买⼀杯柠檬⽔,然后向你付 5 美元、10 美元或20美元。
你必须给每个顾客正确找零,也就是说净交易是每位顾客向你⽀付 5 美元。
注意,⼀开始你⼿头没有任何零钱。
注:上⾯⿊体部分内容引⾃很明显,当客户给我们$20进⾏找零时,⾃然⽽然地就给ta找了⼀张$10加上⼀张$5,为什么这么做?⾯对$20,我们有两种⽅案可以使⽤:找三张$5给顾客找⼀张$10 以及⼀张 $5 给顾客选择第⼆种⽅案的原因对于做⽣意的⽼板应该不陌⽣,营业过程中我们需要备上⼀部分零钱在交易时⽅便找零,不⾄于出现⽆法找零的尴尬局⾯,这是商⼈们所想的,在上题中也同样适⽤。
但贪⼼算法的弊端也很明显:不考虑之前解带来的影响,仅仅为了达到当前最优解,这样”⼀根筋“的策略也不能在任何情况下得到最优解。
如只有⾯值分别为 1、5 和 11 单位的硬币,⽽希望找回总额为 15 单位的硬币。
按贪婪算法,应找 1 个 11 单位⾯值的硬币和 4 个 1 单位⾯值的硬币,共找回 5 个硬币。
但最优的解应是 3 个 5 单位⾯值的硬币。
变尺寸装箱问题的迭代贪婪动态规划算法
第38卷第1期2021年2月江苏船舶JIANGSU SHIPVol.33No.1Feb.3221变尺寸装箱问题的迭代/贪婪动态规划算法姚汝林1,尹石军2,郭蕴华3(1.上海交通大学船舶海洋与建筑工程学院,上海202242;2.招商局重工(江苏)有限公司,江苏海门226116;3.武汉理工大学能源与动力工程学院,湖北武汉430263)摘要:针对船舶建造中管材切割规划这一类特殊的变尺寸装箱问题,提出了一种迭代贪婪/动态规划算法(IGDP)并对其进行求解。
首先,提出了求解子集和问题的贪婪操作与动态规划的组合解法。
然后,基于贪婪操作与动态规划的组合解法实现对整个问题的构造启发式求解,并且通过迭代的拆箱/再分配操作提高了算法的局部搜索能力。
最后,通过8个算例的仿真实验,对所提算法与现有算法进行了性能比较。
结果表明:IGDP的性能优于现有算法,且具有可以接受的计算耗费。
关键词:变尺寸装箱;动态规划;启发式;船舶建造;管材切割中图分类号:U671.963文献标志码:ADOI:12.19646/ld.32-1232.3221.363210引言管材切割是船舶建造过程中的一个重要的生产步骤,新近研究将船厂管材切割问题描述为一维下料问题I One-dimensiooal cntting stock problem,1D-CSP)⑴。
但是,由于船舶建造的复杂性,某些场合零件管和原料管都具有随机长度。
在此情况下,应将船舶建造的管材切割问题描述为变尺寸装箱问题(Variabln-sizeb bin pacnOg problem,VSBPP),而非1D-CSP2。
对于VSBPP问题,研究人员先后提出了近似算法⑶、分支定界算法⑷、分组遗传算法(Grouped genetic algorittm,GGA)⑸、迭代递减首次适合算法(Iterative first-Ct decreasing,IAFD);、迭代MBS启发式算法(Iterative minimal bin slack,IM BS)⑺、可变邻域搜索(Vaeablc neighborOoob search, VNS)方法⑻和基于动态规划的启发式方法⑼进行求解。
用贪心法求解船舶装卸问题。
t[i].Format("%d : %d",i+1,a[i] ); m_CSum+="\tBoat " +t[i]; } delete []t; //显示船只初始顺序及其装卸时间 m_set.SetWindowText("Set: "+m_CSum); } } 图中的 Order 按钮: void CNiceBoatDlg::OnButton2() { Boat *b=new Boat[m_amount];//动态分配内存空间 for(int i=0;i<m_amount;i++) { b[i].time=a[i][1]+……+t[n-1] 因为 t[1]在这里用的次数是最多的,所以它应该是较小的一个值才对,否则 不能达到总的等待时间最优这一条件。那么以此类推可以得出这样的一个结论: t[1]<=t[2]<=……<=t[n] 3.出错处理需求 我的程序是采用 MFC 编程,通过在对话框上添加控件来传递消息响应, IDC_EDIT 这种控件可以设置错误检测的条件,例如变量的类型和范围,这样就 很方便的进行了错误的处理。 4.接口需求 这里我来介绍一下用到了哪些函数接口和控件,所用到的函数有每次取最小 装卸时间的函数 Min,船舶的数据类型 Boat 类,求每艘船的等待时间的函数 Sum。 控件方面包括一个文本控件和与它进行消息响应的按钮,用来设置船只数量;一 个 Static 控件和一个按钮用来根据船只数量设置每艘船的装卸时间然后 在 Static 控件中显示出来;三个 Static 控件和一个按钮用来根据每艘船的装卸时 间对它们进行处理,使得总的等待时间最短,然后将船的装卸顺序、各自的等待 时间和总的等待时间分别显示出来,最后一个按钮式退出按钮,用来终止运行退 出程序。
贪心法解船舶装卸问题(python版)
#-*-coding:gbk-*-from random import randint#给出船舶总数NUM=10#预定一个最大卸货时间MAXTIME=20#总等待时间初始值为零timeSum=0#----------------------------------初始化船舶信息----------------------------------##定义Boat类,它有三个成员变量,分别为:船舶编号boatNum,卸货需要的时间timeNeed,#卸货前需要等待的时间timeWaitclass Boat(object):def__init__(self,bNum,tNeed,tWait):self.boatNum=bNumself.timeNeed=tNeedself.timeWait=tWait#定义正在正待的船舶列表boatWaitList=[]#定义已经完成卸货的船舶列表boatFinishList=[]print"\n全部%s艘船需要的时间分别为:"%NUM#初始化所有船舶的信息,编号从0到NUM-1,需要时间从1到MAXTIME中间随机,等待时间设为0for i in range(NUM):boatWaitList.append(Boat(i,randint(1,MAXTIME),0))print"第%s艘船需要%s分钟."%(boatWaitList[i].boatNum+1,boatWaitList[i].timeNeed)#-------------------------------------开始卸货-------------------------------------#print"\n船舶卸货的顺序为:"#遍历NUM次等待船舶列表boatWaitListfor i in range(NUM):#temp值为记录当前等待船舶列表boatWaitList中卸货需要的时间最短的船舶在当前boatWaitList中的位置temp=NUM+1#minTime记录当前boatWaitList列表中,卸货所需的最短时间minTime=MAXTIME#遍历当前第i次遍历的等待船舶列表boatWaitListfor j in range(len(boatWaitList)):#从0号船舶开始,如果当前船舶卸货所需的时间小于minTime,则把它的时间值赋给minTime#同时记录下此船在当前boatWait中的位置到tempif boatWaitList[j].timeNeed<minTime:minTime=boatWaitList[j].timeNeedtemp=j#第i次遍历boatWaitList后,把卸货时间最短的船舶boatWaitList[temp]加到完成卸货船舶列表boatFinishList中boatFinishList.append(boatWaitList[temp])#在第i次遍历的bootWaitList列表中删除上面找出的最短时间船舶del boatWaitList[temp]#对等待船舶列表中的所有船舶,加上上面找出的最短等待时间minTimefor k in range(len(boatWaitList)):boatWaitList[k].timeWait+=minTime#-------------------------------------卸货完成-------------------------------------##遍历卸货完成船舶列表boatFinishList,求出船舶总等待时间for i in range(NUM):timeSum+=boatFinishList[i].timeWaitprint"第%s艘船,它等待了%s分钟."%(boatFinishList[i].boatNum+1,boatFinishList[i].timeWait)print"\n所有船舶的总等待时间为:%s分钟,平均等待时间为%s分钟"%(timeSum,timeSum/NUM)。
实验报告:贪心算法--最优装载
XXXX 大学计算机学院实验报告计算机学院2017级软件工程专业 5 班指导教师
学号姓名2019年10 月28 日成绩
实验内容、上机调试程序、程序运行结果
System.out.print(weight[i]+" ");
}
System.out.println();
//从控制台获取集装箱的最大重量
System.out.println("请输入集装箱的最大重量:");
Scanner s = new Scanner(System.in);
maxWeight=s.nextInt();
System.out.print("可装入的集装箱有:");
//将一批集装箱装上一艘重量为80的轮船。
在装载体积不受限制的情况下,将尽可能多的集装箱装上轮船。
(重量从小到大装)
for(int k=0;k<weight.length;k++){
sumWeight += weight[k];
if(sumWeight<=maxWeight){
System.out.print(weight[k]+"kg ");
}
}
}
}
②完成效果。
贪心算法之最优装载问题
贪⼼算法之最优装载问题贪⼼算法之最优装载问题1. 问题描述有⼀批集装箱要装上⼀艘重量为c的轮船,其中集装箱i的重量为W i。
最优装载问题要求确定在装载体积不受限制的情况下,将尽可能多的集装箱装上轮船。
2. 问题分析2.1确定贪⼼策略采⽤重量最轻者先装的贪⼼选择策略,可产⽣该问题的最优解。
2.2代码求解/*** x[] 保存最优解路径数组* w[] 集装箱重量数组* c 船的载重量* n 集装箱的数量**/void Loading(int x[], int w[], int c, int n) {// 按照集装箱重量从⼩到⼤排序sort(w, n);for (int i = 1; i <= n; i++)x[i] = 0;for (int i = 1; i <= n && w[i] <= c; i++) {x[i] = 1;c -= w[i];}}2.3贪⼼选择性质设集装箱依其重量从⼩到⼤排序,(x1,x2,…,x n)是其最优解,x i={0,1},设x k是第⼀个等于1的。
(1) 如k=1,则满⾜贪⼼选择性质(2) 如k≠1,⽤x1替换x k,构造的新解同原解最优值相同,故也是最优解,满⾜贪⼼选择性质该证明⽅法只证明了任何⼀个最优解都可以转换为第⼀个集装箱上船的最优解(满⾜贪⼼策略)。
此⽅法对⼦问题同样有效,因此可以将⼀个普通最优解转化为满⾜贪⼼策略的最优解。
如(0101)⇒(1100)2.4.最优⼦结构性质最优装载问题具有最优⼦结构性质,设1⾄n个集装箱装上船的最⼤数量为T(1,n,w),则T(1,n,w)=1+T(2,n,w−w1);因T(1,n,w)是最优值,则T(2,n,w−w i)⼀定是最优值,反证法证明之反证法:如果T(2,n,w−w1)不是该问题的最优解,则存在最优值T′(2,n,w−w1)>T(2,n,w−w1),则1+T′(2,n,w−w1)=T′(1,n,w)>T(1,n,w),这与⼤前提T(1,n,w)是最优值相⽭盾,故T(2,n,w−w1)⼀定是最优值。
贪婪法
贪婪法是一种不追求最优解,只希望得到较为满意解的方法。贪婪法一般可以快速 得到满意的解,因为它省去了为找最优解要穷尽所有可能而必须耗费的大量时间。贪婪 法常以当前情况为基础作最优选择,而不考虑各种可能的整体情况,所以贪婪法不要回 溯。
例如平时购物找钱时,为使找回的零钱的硬币数最少,不考虑找零钱的所有各种发 表方案,而是从最大面值的币种开始,按递减的顺序考虑各币种,先尽量用大面值的币 种,当不足大面值币种的金额时才去考虑下一种较小面值的币种。这就是在使用贪婪法。 这种方法在这里总是最优,是因为银行对其发行的硬币种类和硬币面值的巧妙安排。如 只有面值分别为 1、5 和 11 单位的硬币,而希望找回总额为 15 单位的硬币。按贪婪算法, 应找 1 个 11 单位面值的硬币和 4 个 1 单位面值的硬币,共找回 5 个硬币。但最优的解应 是 3 个 5 单位面值的硬币。
void main() { int sx,sy,i,j,step,no,start;
for (sx=0;sx<8;sx++) for (sy=0;sy<8;sy++) { start=0; do { for (i=0;i<8;i++) for (j=0;j<8;j++) board[i][j]=0; board[sx][sy]=1;
【程序】 # include int delta_i[ ]={2,1,-1,-2,-2,-1,1,2}; int delta_j[ ]={1,2,2,1,-1,-2,-2,-1}; int board[8][8]; int exitn(int i,int j,int s,int a[ ]) { int i1,j1,k,count;
二维装箱问题的算法
二维装箱问题(2D Bin Packing Problem)是一个经典的组合优化问题,它的目标是将一系列的矩形物品放入最小数量的容器中,同时满足每个容器的尺寸限制。
这个问题在实际应用中有很多场景,如物流、仓储、广告排版等。
解决二维装箱问题的算法有很多,以下是一些常见的算法:1. 贪心算法(Greedy Algorithm):贪心算法是一种简单且易于实现的算法。
它的基本思想是在每一步都选择当前最优的解决方案。
对于二维装箱问题,贪心算法可以选择每次放入面积最大的矩形,直到无法再放入为止。
然后开始新的一行,重复这个过程。
贪心算法的缺点是可能得不到最优解,因为它没有考虑到后续的放置情况。
2. 启发式算法(Heuristic Algorithm):启发式算法是一种基于经验的算法,它通过一定的规则来指导搜索过程。
对于二维装箱问题,启发式算法可以根据矩形的长宽比、面积等因素来确定放置的顺序和位置。
启发式算法通常能够得到较好的解,但不一定是最优解。
3. 遗传算法(Genetic Algorithm):遗传算法是一种模拟自然选择和遗传机制的全局搜索算法。
它通过不断地进行交叉、变异和选择操作,来生成新的解决方案。
对于二维装箱问题,遗传算法可以用于优化矩形的放置顺序和位置,以找到更优的解。
4. 模拟退火算法(Simulated Annealing):模拟退火算法是一种基于概率的全局优化算法。
它通过在一定的温度下随机搜索解空间,并在温度降低时逐渐收敛到最优解。
对于二维装箱问题,模拟退火算法可以用于优化矩形的放置顺序和位置,以找到更优的解。
5. 粒子群优化算法(Particle Swarm Optimization):粒子群优化算法是一种基于群体智能的全局优化算法。
它通过模拟鸟群觅食行为,来寻找最优解。
对于二维装箱问题,粒子群优化算法可以用于优化矩形的放置顺序和位置,以找到更优的解。
6. 线性规划(Linear Programming):线性规划是一种数学优化方法,它可以用于求解具有线性约束和目标函数的问题。
用贪心算法来解决沙袋装箱问题
⽤贪⼼算法来解决沙袋装箱问题这是⼀个百度知道上的。
我解决这个问题的基本思路是使⽤贪⼼算法,也叫做贪婪算法。
贪⼼算法的原则是找出当前看来是最优的解决⽅案。
问题描述如下:有⼀堆沙袋,每个沙袋中都转有从1到100不等的沙⼦。
现在要求把这堆沙袋装⼊容积为100的箱⼦中。
问题是,如何⽤最少的箱⼦装这些沙袋?我的思路是这样的:如果想⽤最少的箱⼦,那么,箱⼦就要尽可能的装满。
为了实现这个⽬标,就需要考虑组合的策略了。
数量⽐较⼤的沙袋,和其他沙袋组合起来⽐较困难,所以要优先放⼊箱⼦中,然后再和其他沙袋组合。
所以算法应该是这样的:⾸先从⼤到⼩排序,得到序列A,然后取出第⼀个元素(最⼤的元素),并把这个元素从序列A中删除。
然后取出第下⼀个元素,把这个元素和第⼀个元素相加,如果⼩于100,则把此元素从序列A中删除,然后继续取下⼀个元素做本步骤操作。
如果⼤于100,则跳过此元素,继续执⾏本步骤,直到所有元素遍历完成。
然后把上述序列记录下来,按照上述步骤计算序列A,直到序列A中没有元素为⽌。
代码如下:1class Program2 {3static void Main(string[] args)4 {5try6 {7int[] sandPackages = new int[] { 23, 42, 63, 66, 23, 42, 65, 23, 5, 32, 65, 20 };89int tankSize = 100;1011 List<int> sandLst = new List<int>();12 sandLst.AddRange(sandPackages);1314// 排序15 sandLst.Sort();16// 翻转,翻转后,内部排序为从⼤到⼩17 sandLst.Reverse();1819 List<List<int>> tankLst = new List<List<int>>();2021// 循环,处理数组,直到所有数据均被取出22while (sandLst.Count != 0)23 {24// 找出⼀个数据相加最接近100的序列25 tankLst.Add(Add2Tank(sandLst, tankSize));26 }2728// 显⽰29foreach (List<int> sands in tankLst)30 {31int temp = 0;32foreach (int sand in sands)33 {34 temp += sand;35 Console.Write(sand);36 Console.Write("");37 }38 Console.Write("total:" + temp);39 Console.WriteLine();40 }4142 }43catch (Exception ex)44 {45throw ex;46 }47 }4849private static List<int> Add2Tank(List<int> sandLst, int tankSize)50 {51 List<int> sandLst2Tank = new List<int>();52int nowPos = 0; // 当前位置53int nowSize = 0; // 当前合计54// 遍历数组55while (nowPos < sandLst.Count)56 {57// 把当前位置的数值加到当前合计58if ((nowSize + sandLst[nowPos]) <= 100)59 {60// 如果计算后的当前合计⼩于等于100 ,则把当前位置的数据放⼊到待输出列表(即装箱)61// 并从原始数组中移除62 sandLst2Tank.Add(sandLst[nowPos]);63 nowSize += sandLst[nowPos];64 sandLst.RemoveAt(nowPos);65 }66else67 {68 nowPos++;69 }70 }7172return sandLst2Tank;73 }74 }。
贪婪算法之装箱问题
}//if
else q->link=p;//尾接
j->remainder-=g[i].gv;
}//for
printf("共用了%d个箱子,",count);
printf("各箱子装物情况如下:\n");
struct gnode *link;
} HGOODS; //物品链表信息
typedef struct Bnode
{
int remainder;
HGOODS *hg;
struct Bnode *next;
} BOX;
int main(void)
{
#include<stdio.h>
#include<stdlib.h>
#define V 10
typedef struct
{ //物品体积
} GOODS; //物品数组信息
typedef struct gnode
{
int lno;//物品编号
for(j=HBOX,i=1;j;j=j->next,i++){
printf("\n");
printf("第%d个箱子,还剩体积为%d,所装物体有:",i,j->remainder);
for(HGOODS *p=j->hg;p;p=p->link)
printf("编号%d",p->lno);
}
return 0;
}//main
int n; //物品个数
贪婪算法(例题及相关解答)
第 1 章贪婪算法虽然设计一个好的求解算法更像是一门艺术,而不像是技术,但仍然存在一些行之有效的能够用于解决许多问题的算法设计方法,你可以使用这些方法来设计算法,并观察这些算法是如何工作的。
一般情况下,为了获得较好的性能,必须对算法进行细致的调整。
但是在某些情况下,算法经过调整之后性能仍无法达到要求,这时就必须寻求另外的方法来求解该问题。
本章首先引入最优化的概念,然后介绍一种直观的问题求解方法:贪婪算法。
最后,应用该算法给出货箱装船问题、背包问题、拓扑排序问题、二分覆盖问题、最短路径问题、最小代价生成树等问题的求解方案。
1.1 最优化问题本章及后续章节中的许多例子都是最优化问题( optimization problem),每个最优化问题都包含一组限制条件( c o n s t r a i n t)和一个优化函数( optimization function),符合限制条件的问题求解方案称为可行解(feasible solution),使优化函数取得最佳值的可行解称为最优解(optimal solution)。
例1-1 [ 渴婴问题] 有一个非常渴的、聪明的小婴儿,她可能得到的东西包括一杯水、一桶牛奶、多罐不同种类的果汁、许多不同的装在瓶子或罐子中的苏打水,即婴儿可得到n 种不同的饮料。
根据以前关于这n 种饮料的不同体验,此婴儿知道这其中某些饮料更合自己的胃口,因此,婴儿采取如下方法为每一种饮料赋予一个满意度值:饮用1盎司第i 种饮料,对它作出相对评价,将一个数值s i 作为满意度赋予第i 种饮料。
通常,这个婴儿都会尽量饮用具有最大满意度值的饮料来最大限度地满足她解渴的需要,但是不幸的是:具有最大满意度值的饮料有时并没有足够的量来满足此婴儿解渴的需要。
设a i是第i 种饮料的总量(以盎司为单位),而此婴儿需要t 盎司的饮料来解渴,那么,需要饮用n种不同的饮料各多少量才能满足婴儿解渴的需求呢?设各种饮料的满意度已知。
总复习
• 动态规划算法:已知A={x,y,x,z,y,x,y,z,z,y}, B={x,z,y,z,x,y,z,x,y,z,x,y},求2个序列的最 长公共子序列
考试题目类型举例4 考试题目类型举例
分治算法---最大字段和 分治算法 最大字段和
实例:求序列 的最大子段和。 实例:求序列-6,2,4,-7,5,3,2,-1,6,-9,10,-2的最大子段和。 的最大子段和 1) {-6,2,4 ,-7,5,3},{2,-1,6,-9,10,-2} , 2) {-6,2,4}, {-7,5,3}, {2,-1,6},{-9,10,-2} , , , 3) 6 8 7 10
考试题目类型举例1 考试题目类型举例
贪心法实例: 贪心法实例:装船问题 第一步: 第一步:写出贪心准则 第二步: 第二步:写出装船步骤 即xi=1---装船的货物 装船的货物 例如:货物装箱问题:设有一艘货船装物品。共有 件物品, 例如:货物装箱问题:设有一艘货船装物品。共有n=6件物品,它们的重量如下 件物品 表示: 表示:[w1,..., w6] = [100, 200, 50, 90, 50, 20],船的限载重量是 ,船的限载重量是c=300。 。 试用贪心算法装船,要求物品装得最多。 试用贪心算法装船,要求物品装得最多。 解:贪心准则:从剩下的货箱中选择重量最小的货箱。 贪心准则:从剩下的货箱中选择重量最小的货箱。 表示第i件物品装船 表示第i件物品不装船:(-----2分) 设xi=1表示第 件物品装船,xi=0表示第 件物品不装船:( 表示第 件物品装船, 表示第 件物品不装船:( 分 则贪心算法步骤如下
考试题目类型举例6 分治 分治快速排序 考试题目类型举例 ---分治快速排序
例如:要求从小到大排序。 例如:要求从小到大排序。 {6, 7, 51, 2, 5, 8} 初始序列 {6, 7, 51, 2, 5, 8} --j ↑i ↑i ↑i ↑j ↑i ↑j {5, 2, 51}6{7, 8} --------------一次完成 一次完成 ↑j ↑j {5, 7, 51, 2, 6, 8}++i {5, 6, 51, 2, 7, 8} --j {5, 2, 51, 6, 7, 8}++i
贪心算法练习题
贪心算法练习题贪心算法是一种常用的解决问题的思想和方法,它通常用于求解优化问题。
贪心算法的核心思想是:在每一步选择中都采取当前状态下最优的选择,从而希望最终能够达到全局最优。
在实际应用中,贪心算法常用于解决一些分类问题,如最小生成树、最短路径、背包问题等。
下面,将给出一些贪心算法的练习题,帮助读者更好地理解和掌握贪心算法的应用。
1. 零钱兑换问题假设我们有不同面额的硬币,如 1 美元、2 美元、5 美元等,我们希望找零 n 美元的时候,最少需要多少个硬币。
请用贪心算法解决此问题,并给出相应的代码实现。
2. 区间覆盖问题给定一个区间集合,选择尽可能少的区间,使得这些区间的并集能够覆盖全部的区间。
请使用贪心算法解决此问题,并给出相应的代码实现。
3. 活动选择问题给定 n 个活动的开始时间和结束时间,选择尽可能多的不相交的活动。
请使用贪心算法解决此问题,并给出相应的代码实现。
4. 任务调度问题假设我们有 n 个任务和 m 台执行任务的机器,每个任务需要一个单位的时间,在每台机器上只能执行一个任务。
如何安排任务,使得所有任务都能够被执行,并且时间最短。
请使用贪心算法解决此问题,并给出相应的代码实现。
以上是一些常见的贪心算法练习题,通过解决这些问题,读者可以更加深入地理解和掌握贪心算法的应用。
当然,在实际应用中,贪心算法并不是万能的,它只能求解一些特定类型的优化问题,对于其他类型问题的求解可能并不适用。
因此,在使用贪心算法时,需要仔细分析问题的特性,判断是否适用贪心算法,并注意贪心选择的合理性。
通过不断练习和实践,读者可以逐渐掌握贪心算法的应用技巧,提高问题求解的效率和准确性。
最后,希望读者能够善于思考,灵活运用贪心算法解决实际问题,并在实践中不断学习和进步。
贪心算法作为一种常用的解决问题的思想和方法,对于提高算法设计和分析能力具有重要意义。
三维装箱问题的算法
三维装箱问题的算法
三维装箱问题是一种经典的组合优化问题,它要求将一组物品(物品的尺寸由长、宽、高表示)装入一些箱子(箱子的尺寸也由长、宽、高表示),使得物品能够尽可能紧密地装入箱子中,并且所需要的箱子数量要尽量少。
下面是一个基于贪心算法的解决方案:
步骤1:将所有物品按照体积从大到小进行排序。
步骤2:创建一个空的箱子列表,将第一个物品放入第一个箱子。
步骤3:遍历剩下的物品,按照如下的方式尝试将每个物品放
入已有的箱子中:
- 对于每个箱子,计算将该物品放入箱子后箱子的剩余容量。
- 如果该剩余容量大于等于该物品的体积,则将该物品放入
该箱子中,并更新箱子的剩余容量。
- 如果该物品无法放入任何已有的箱子中,则将该物品放入
一个新的箱子,并加入到箱子列表中。
步骤4:重复步骤3,直到将所有物品放入箱子中。
这个贪心算法的思想是每次选择最大的物品尝试放入已有的箱
子中,以便尽可能地利用空间。
但是,这个算法并不能保证得到最优解,因为在选择某个物品放入箱子时,并没有考虑到后续物品的放置情况。
解决三维装箱问题的最优算法是NP-hard问题,可以采用启发
式算法或者近似算法来求解,例如基于遗传算法、模拟退火算法、禁忌搜索等。
这些算法的思想是通过搜索空间的不同方案,寻求某一个局部最优解或者近似最优解。
具体选择哪种算法需要根据实际问题的规模和要求进行评估。
算法设计与分析-贪心算法-最优装载
计算机算法与设计实验内容:贪心算法-最优装载问题描述:有一批集装箱要装上一艘载重量为c 的轮船。
其中集装箱i 的重量为Wi ,最优装载问题要求在装载体积不受限制的情况下,将尽可能多的集装箱装上轮船。
问题分析:该问题可形式化描述为:∑=n i ix 1maxc x w n i ii ≤∑=1 {}n i x i ≤≤∈1,1,0算法描述:最优装载问题可用贪心算法求解。
采用重量最轻者先装的贪心选择策略,可产生最优装载问题的最优解。
具体算法描述如下:Template<class Type>Void Loading(int x[],Type w[],Type c ,int n){int *t = new int [n+1];Sort(w,t,n);for(int i =1;i<+n;i++){x[i] = 0;}for (int i = 1;i<=n&&w[t[i]]<=c;i++){x[t[i]] = 1;c-= w[t[i]];}}所需计算时间为O(nlogn)运行结果:另选一组数据输入:详细设计:#include <iostream>using namespace std;const int N = 100;template<class Type>void Loading(int x[],Type w[], Type c, int n) {int *t = new int [n+1];//Sort(w, t, n); //调用SelectSort函数for(int k=1; k<=n; k++)x[k] = 0;//初始化数组x[]}for(int i=1; i<=n && w[t[i]]<=c; i++){x[t[i]] = 1; //经判断该集装箱可以装入c -= w[t[i]]; //轮船可栽重相应减少}}template<class Type>void Sort(Type w[],int *t,int n){Type tempArray[N+1],temp;int min;memcpy(tempArray,w,(n+1)*sizeof(Type));//将w数组数据拷贝到数组tempArray中for(int e=1;e<=n;e++){t[e] = e;for(int i=1;i<n;i++) //类冒泡算法,将集装箱按重量从小到大排列{min=i;for(int j=i+1;j<=n;j++){if(tempArray[min]>tempArray[j]){min=j;}}Swap(tempArray[i],tempArray[min]);Swap(t[i],t[min]);}}template <class Type>void Swap(Type &x,Type &y) //swap函数{Type temp = x;x = y;y = temp;}int main(){float c ; //l轮船总载重int x[N+1]; //装载结果(0与1分别表示是否装入int a ;//集装箱数量cout <<"/////////////贪心算法求解最优装载问题////////////////////"<<endl;cout<<"轮船载重为:";cin>>c;cout<<"集装箱数量:";cin>>a;float *m = new float [a];cout<<"待装物品的重量分别为:"<<endl;for(int i = 1;i<=a;i++){cout<<"请输入第"<<i<<"个集装箱的重量:";cin>>m[i];}cout<<endl;cout<<"集装箱列表:"<<endl;for(int j=1; j<=a; j++){cout<<m[j]<<"\t";}cout<<endl;Loading(x,m,c,a);cout<<"对应的贪心选择结果为:"<<endl;for(int f=1; f<=a; f++){ if(x[f]==0||x[f]==1)cout<<x[f]<<"\t";}cout<<endl;cout<<"集装箱最优装载情况:"<<endl;for(int b=1; b<=a; b++){if (x[b]==0||x[b]==1){if (x[b]==0){cout <<"第"<<b<<"个集装箱不装入"<<endl;}else{cout<<"第"<<b<<"个集装箱装入"<<endl;}}}cout<<"///////////////////////结束////////////////////////////"<<endl;system("pause");return 0;}。
matlab求贪婪算法 装箱问题的练习
利用matlab编程FFD算法完成装箱问题:设有6种物品,它们的体积分别为:60、45、35、20、20和20单位体积,箱子的容积为100个单位体积。
建立box_main.mfunction[box_count,b]=box_main(v) vmax=100;sort(v,'descend');n=length(v);b=zeros(1,n);for i=1:nb(i)=vmax;endbox_count=1;for i=1:nfor j=1:box_countif v(i)<=b(j) %可以放入 b(j)=b(j)-v(i);break;else%不可放入时continue;endendif j==box_countbox_count=box_count+1;endendbox_count=box_count-1;end主程序为:v=[60 45 35 20 20 20];[box_count,b]=box_main(v)结果:box_count =3 b =5 15 80 100 100 100所以,使用的箱子数为3, 使用的箱子的剩余空间为5,15 ,80。
“超市大赢家”提供了50种商品作为奖品供中奖顾客选择,车的容量为1000dm3 , 奖品i 占用的空间为wi dm3 ,价值为vi 元, 具体的数据如下:vi = { 220, 208, 198, 192, 180, 180, 165, 162, 160, 158,155, 130, 125, 122, 120, 118, 115, 110, 105, 101, 100, 100, 98,96, 95, 90, 88, 82, 80, 77, 75, 73, 72, 70, 69, 66, 65, 63, 60, 58,56, 50, 30, 20, 15, 10, 8, 5, 3, 1}wi = {80, 82, 85, 70, 72, 70, 66, 50, 55, 25, 50, 55, 40, 48,50, 32, 22, 60, 30, 32, 40, 38, 35, 32, 25, 28, 30, 22, 50, 30, 45,30, 60, 50, 20, 65, 20, 25, 30, 10, 20, 25, 15, 10, 10, 10, 4, 4, 2,1}。
第4章贪心算法1例子
4.7 多机调度问题
特别地,对m=1时, 1)若n个作业都必须完成,如何调度? 2)若在时间t内,使得尽可能多的任务
完成,如何调度?
解答:
1)n个作业都必须完成,完成时间是确 定的,无所谓调度,谁先谁后都可 以。
2)若在时间t内,使得尽可能多的任务
完成,应短作业优先。
36
贪心法小结
37
贪心法 正确性证明
4.3 最优装载
有一批集装箱要装上一艘载重量为c的轮船。其 中集装箱i的重量为Wi。最优装载问题要求确定在 装载体积不受限制的情况下,将尽可能多的集装箱 装上轮船。
1、算法描述 最优装载问题可用贪心算法求解。采用重量最
轻者先装的贪心选择策略,可产生最优装载问题的 最优解。具体算法描述如下页。
1
4.3 最优装载
33
4.7 多机调度问题
例如,设7个独立作业{1,2,3,4,5,6,7}由3台 机器M1,M2和M3加工处理。各作业所需的处理时 间分别为{2,14,4,16,6,5,3}。按算法greedy产生 的作业调度如下图所示,所需的加工时间为17。
34
4.7 多机调度问题
再看一例:: N={10, 10, 10, 10, 10, 7, 7, 7, 7, 7, 5, 5, 5, 5}, m=3
并”运算后产生最终所要求的树T。
10
4.4 哈夫曼编码
11
4.4 哈夫曼编码
12
4.4 哈夫曼编码
在书上给出的算法huffmanTree中: 每一字符c的频率是f(c); 以f为键值的优先队列Q采用最小堆实现; 用贪心选择当前要合并的2棵具有最小频率的树; 一旦2棵具有最小频率的树合并后,产生一棵新的树,
C语言基于贪心算法解决装箱问题的方法
C语⾔基于贪⼼算法解决装箱问题的⽅法本⽂实例讲述了C语⾔基于贪⼼算法解决装箱问题的⽅法。
分享给⼤家供⼤家参考,具体如下:问题描述:有⼀些箱⼦,容量为V,同时有n个物品,每个物品有⼀个体积(⼩于等于箱⼦容量),要求将物品全部装⼊箱⼦中,使占⽤的箱⼦数尽量少。
贪⼼算法中要求每⼀步的解都是当前步骤中的最优解。
原问题的解可以通过⼀系列局部最优的选择来达到,这种选择并不依赖于⼦问题的解。
算法思想:1、数据结构要求求解箱⼦数⽬,也就是说不能确定会占⽤多少个箱⼦,因此采⽤链表的形式来存储箱⼦及其信息。
同时,每个箱⼦中物品的数⽬也⽆法确定,同理采⽤链表来存储每个箱⼦中的物品信息。
由此得出数据节点的定义:typedef struct{int gno;int gv;}Goods;typedef struct node{int gno;struct node *link;}GNode;typedef struct node1{int remainder;GNode * head;struct node1 * next;}GBox;2、求解思路使打开的箱⼦数尽量少,也就是说每个箱⼦容积被尽可能多地占⽤。
将物品按照体积降序排列后,再从第⼀个物品开始,挨个寻找能放下它的箱⼦,这样可以保证局部最优。
void GoodsSort(Goods goods[], int n){int i, j;Goods t;for (i = 0; i<n - 1; i++){for (j = i + 1; j<n; j++){if (goods[i].gv<goods[j].gv){t = goods[i];goods[i] = goods[j];goods[j] = t;}}}for (i = 0; i<n; i++)printf("%d %d\n", goods[i].gno, goods[i].gv);排序完成,就可以正式开始装箱⼦了。
流水货车问题应用题
流水货车问题应用题问题描述有一辆货车需要将一批货物从起点A运送到目的地B,货车上的货物数量有限。
每个货物有其重量和价值,货车有一定的承载能力。
货车每次只能装一件货物,并且一旦装上货物就无法卸下,只能运输到目的地。
在给定的货物列表和承载能力下,如何安排货物的装载顺序,以使得货车能够运送的货物总价值最高?解决方案可以使用贪心算法来解决这个问题。
贪心算法是一种策略算法,在每一步选择中都选择当前最优的解决方法,以期望最终可以得到全局最优解。
具体的贪心算法步骤如下:1. 首先,按照货物的价值重量比进行降序排序,计算每个货物的价值重量比并排序。
2. 然后,从排序后的货物列表中依次选择最高价值重量比的货物进行装载,直到达到货车的承载能力上限或所有货物都已装载完毕。
3. 最后,返回已装载货物的列表及其总价值作为最优解。
代码示例输入货物列表,每个货物包括重量和价值goods = [{"weight": 2, "value": 10},{"weight": 3, "value": 15},{"weight": 5, "value": 20},{"weight": 7, "value": 30},{"weight": 1, "value": 5}]货车的承载能力capacity = 10计算价值重量比并排序for good in goods:good["value_weight_ratio"] = good["value"] / good["weight"] goods.sort(key=lambda x: x["value_weight_ratio"], reverse=True)贪心装载货物loaded_goods = []total_value = 0current_weight = 0for good in goods:if current_weight + good["weight"] <= capacity:loaded_goods.append(good)total_value += good["value"]current_weight += good["weight"]输出装载结果print("已装载货物列表:", loaded_goods)print("总价值:", total_value)以上代码示例展示了如何使用贪心算法求解流水货车问题。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
贪婪算法练习
练习题1:考虑1、8、9、11这四种面值的硬币,要找出币值24的零钱,怎么找能使硬币数最少? 利用matlab 编程求解。
解:设x j 为二进制变量,如果硬币j 被选中,则,x j =1,否则x j
=0, 则找硬币问题的数学模型如下:
min
∑=n j j x 1
; m n j j j x v =∑=1;
用贪婪算法求解,其MA TLAB 程序如下:
function [n,x]=payback(v,y,m)
[m,n]=size(y);
for i=1:n
for j=1:n
练习题2:利用matlab 编程FFD 算法完成下题:
设有6种物品,它们的体积分别为:60、45、35、20、20和20单位体积,箱子的容积为100个单位体积。
function [nbox,p]=sjy(n,v,limitv)
[m,n]=size(v);
w=limitv*ones(m,n);
p=zeros(n);
nbox=0;
for i=1:n
for j=1:i
if v(i)<w(j)
w(j)=w(j)-v(i);p(i,j)=1;break;
else
continue;
end
w(j+1)=w(j+1)-v(i);p(i,j+1)=1; nbox=nbox+1;
end
end
运行结果:
p =
1 0 0 0 0 0
0 1 0 0 0 0
1 0 0 0 0 0
0 1 0 0 0 0
0 1 0 0 0 0
0 0 1 0 0 0
练习题3:如果把选择策略从“选出一个下标最小的箱子并把物品ai 放入该箱子中”(FF 算法)改为选择最佳的箱子(已装载物品大小和最大的-这个称为best fit-BF 最佳适应算法),再计算一次上题。
比较两次求解的结果。
练习题4:背包问题:c=[10,5,15,7,6,18,3];w=[2,3,5,7,1,4,1];limitw=15;n=7;求最优解。
练习题5:“超市大赢家”提供了50种商品作为奖品供中奖顾客选择,车的容量为1000dm 3 , 奖品i 占用的空间为w i dm 3 ,价值为v i 元, 具体的数据如下:
v i = { 220, 208, 198, 192, 180, 180, 165, 162, 160, 158,155, 130, 125, 122, 120, 118, 115, 110, 105, 101, 100, 100, 98,96, 95, 90, 88, 82, 80, 77, 75, 73, 72, 70, 69, 66, 65, 63, 60, 58,56, 50, 30, 20, 15, 10, 8, 5, 3, 1}
w i = {80, 82, 85, 70, 72, 70, 66, 50, 55, 25, 50, 55, 40, 48,50, 32, 22, 60, 30, 32, 40, 38, 35, 32, 25, 28, 30, 22, 50, 30, 45,30, 60, 50, 20, 65, 20, 25, 30, 10, 20, 25, 15, 10, 10, 10, 4, 4, 2,1}。
模型的建立:
设x j 为二进制变量,如果物品j 被选中,则x j =1,否则,x j
=0,如此可将本题转化为如下优化模型:
max
∑=n j j j x v 1;
s.t. n
j W x x w j n j j j
,,2,1},1,0{;1 =∈≤∑= 模型的解决:对此优化问题,我们可以选用价值密度贪婪准则,从剩下的物品中选择可装入购物车的单位价值w v j j
,最大的物品,即按w v j j 非递增的次序装入物品,只要正被考虑的物
品装的进就装入小车。
其MA TLAB 编程代码如下:
function [a1,b1]=sort1(n,a,b)%按单位价值排序
[m,n]=size(a);
d=zeros(m,n);
for k=1:n
d(k)=a(k)/b(k);
end%单位价值
for h=1:n-1
for j=1:n-h%向后排序
if d(j)<d(j+1)
t1=a(j);a(j)=a(j+1);a(j+1)=t1;
t2=b(j);b(j)=b(j+1);b(j+1)=t2;
t3=d(j);d(j)=d(j+1);d(j+1)=t3;%
end
end
end
a1=a;
b1=b;
function [p,c,w]=goodsinknapsack(n,limitw,v,w,x)%计算背包中物品数cl=limitw;%cl为背包剩余可装载重量
p=0;
[m,z]=size(c);
x=zeros(m,z);
[v,t]=sort1(n,c,w);%物品按单位价值排序
c=v;w=t;
for i=1:n
if w(i)>cl break%待放入包的物品重量大于包的重量,跳出循环
else
x(i)=1;%x(i)为1时,物品i在包中
cl=cl-w(i);
p=p+1;%p记录放入背包物品的个数
end
end
function knapsack(n,limitw,w,v)
totalc=0;totalw=0;
[m,n]=size(w); %m 是w 的行数n 是w 的列数
x=zeros(m,n);
t=w;%记录原数组
k=c;
y=x;
[p,c,w]=goodsinknapsack(n,limitw,v,w,x);%排序及计算装箱物品数for j=1:p%装包的p件物品
for i=1:n%原n件物品
if (w(j)==t(i))&&(c(j)==k(i))%被选择的物品装箱
y(i)=1;
end
end
end
y
for i=1:n
totalc=totalc+k(i)*y(i);%背包的总价值
if y(i)==1
totalw=totalw+t(i);%背包所装载总体积
end
end
totalw
totalc
v=[220,208,198,192,180,180,165,162,160,158,155,130,125,122,120,118,115,110,105,101,100,100 ,98,96,95,90,88,82,80,77,75,73,72,70,69,66,65,63,60,58,56,50,30,20,15,10,8,5,3,1];
w=[80,82,85,70,72,70,66,50,55,25,50,55,40,48,50,32,22,60,30,32,40,38,35,32,25,28,30,22,50,30, 45,30,60,50,20,65,20,25,30,10,20,25,15,10,10,10,4,4,2,1];
limitw=1000;n=50;
knapsack(n,limitw,w,v);
运行结果为:y =
Columns 1 through 16
1 1 0 1 0 1 0 1 1 1 1 0 1 1 0 1
Columns 17 through 32
1 0 1 1 0 1 1 1 1 1 1 1 0 1 0 0
Columns 33 through 48
0 0 1 0 1 0 0 1 1 0 0 0 0 0 0 0
Columns 49 through 50
0 0
totalw =
996
totalc =
3095
结果分析:由运行结果可知,被选中的物品编号为向量y中的1,其所选物品总价值为3095,总体积为996;贪婪算法并不一定能得到最优解,但可以得到一个较好的解。