最新贪婪算法-装箱问题等练习

合集下载

贪心算法之装箱问题

贪心算法之装箱问题

贪⼼算法之装箱问题问题描述装箱问题可简述如下:设有编号为 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)方法⑻和基于动态规划的启发式方法⑼进行求解。

用贪心法求解船舶装卸问题。

用贪心法求解船舶装卸问题。
srand((unsigned)time(NULL)); CString *t=new CString[m_amount]; for(int i=0;i<m_amount;i++) {
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版)

贪心法解船舶装卸问题(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. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 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;贪婪算法并不一定能得到最优解,但可以得到一个较好的解。

相关文档
最新文档