第06讲_装箱问题
- 格式:ppt
- 大小:386.50 KB
- 文档页数:27
贪⼼算法之装箱问题问题描述装箱问题可简述如下:设有编号为 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 单位⾯值的硬币。
装箱问题{2001p4--穷举法}问题描述有一个箱子容量为V(正整数,0<=V<=20000),同时有N个物品(0<n<=30),每个物品的体积值为正整数。
要求从n个物品中,选取若干个装入箱内,使箱子的剩余空间最小。
输入:1行整数,第一个数表示箱子的容量,第二个数表示有n个物品,后面n个数分别表示这n个物品各自的体积。
输出:1个整数,表示箱子的剩余空间。
输入输出样例:输入:24 6 8 3 12 7 9 7输出:简单穷举varv,n,I,j:integer;w: array[1 .. 30] of integer; {存储N件物品的体积}a: array[0 .. 30] of integer; {存储N件物品的选取状态,1表示选取,0表示不选取} min,:Integer; {统计最小剩余量}s:integer; {累加器,统计物品体积和}beginread(v);min:=v; {初始时设定空间最小剩余量为箱子总容量}read(n);for i:=1 to n do read(w[i]);for i:=0 to n do a[i]:=0;while a[0]=0 do { a[0]作为循环控制开关}beginj:=n;while a[j]=1 do j:=j-1; {逢一进位}a[j]:=1; {设定新的状态}for i:=j+1 to n do a[i]:=0;s:=0;for i:=1 to n do s:=s+a[i]*w[i]; {计算物品的体积和}if (v-s>=0) and (v-s<min) then min:=v-s; { min存储目前的最小剩余量}end;writeln(min);end.穷举改进varv,n:integer;w: array[1 .. 30] of integer;a: array[0 .. 30] of integer;i,j,min,s,temp:Integer;beginread(v);min:=v;read(n);for i:=1 to n do read(w[i]);for i:=1 to n-1 do {排序}for j:=i+1 to n doif w[i]>w[j] thenbegintemp:=w[i]; w[i]:=w[j]; w[j]:=temp;end;for i:=0 to n do a[i]:=0;while a[0]=0 dobeginj:=n;while a[j]=1 do j:=j-1;a[j]:=1;for i:=j+1 to n do a[i]:=0;s:=0;for i:=1 to n do s:=s+a[i]*w[i];if v<s then for i:=j+1 to n do a[i]:=1 {体积总和超过容量,不再继续穷举} else if v-s<min then min:=v-s; {更正min }end;writeln(min);end.。
装箱问题问题描述 有⼀个箱⼦容量为V(正整数,0<=V<=20000),同时有n个物品(0<n<=30),每个物品有⼀个体积(正整数)。
要求n个物品中,任取若⼲个装⼊箱内,使箱⼦的剩余空间为最⼩。
输⼊格式 第⼀⾏为⼀个整数,表⽰箱⼦容量; 第⼆⾏为⼀个整数,表⽰有n个物品; 接下来n⾏,每⾏⼀个整数表⽰这n个物品的各⾃体积。
输出格式 ⼀个整数,表⽰箱⼦剩余空间。
样例输⼊2468312797样例输出这题读完之后多思考思考,其实就能发现就是0-1背包问题每个物品的体积就是花费同时也是价值,也就是说这题可以转化为在总体积为v下,可以得到最⼤的价值最后⽤总体积减去最⼤的价值就是剩下最少的空间状态转移⽅程dp[j] = max(dp[j], dp[j - a[i]] + a[i]);java:import java.util.Scanner;public class Box {public static void main(String[] args) {Scanner sc = new Scanner(System.in);int v = sc.nextInt();//箱⼦的最⼤体积int n = sc.nextInt();//物品的最⼤数量int a[] = new int[n];//存放物品的体积int dp[] = new int[v+1];//存放体积为i时的最⼤容量for (int i = 0; i < a.length; i++) {a[i] = sc.nextInt();}for (int i = 0; i < n; i++) {for (int j = v; j >= a[i]; j--) {dp[j] = Math.max(dp[j], dp[j-a[i]]+a[i]);}}System.out.println(v-dp[v]);//箱⼦容量减去⽤掉的体积}}c:#include <stdio.h>#include <string.h>#include <algorithm>using namespace std;int n;int d[20005];int a[35];int main(){int w;scanf("%d%d", &w, &n);int i, j;for (i = 0; i < n; i++){scanf("%d", &a[i]);}memset(d, 0, sizeof(d));for (i = 0; i < n; i++){for (j = w; j >= a[i]; j--)d[j] = max(d[j], d[j - a[i]] + a[i]); }printf("%d\n", w - d[w]);return 0;}。
装箱问题
装箱问题是NP问题,即在多项式时间内⽆法精确求解,⼀般采⽤近似,即启发式算法,这样可以迅速得到满意解,⽽不⼀定是最优解。
常见的算法:NF(Next Fit)近似算法,FF(First Fit)近似算法,FFD(First Fit Decreasing)近似算法,BF(best Fit),BFD(Best Fit Deceasing)等。
下次适应算法(NF):NF算法是最简单也是最早研究的⼀个算法,它的处理⽅法是始终维持⼀个当前打开的箱⼦,对于每⼀个要装⼊的物品,检查该物品是否可以放⼊当前打开的箱⼦,如果⽆法装⼊,则打开⼀个空箱⼦,装⼊该物品,以该箱⼦作为当前的箱⼦,由于每个物品在装⼊时,只有当前打开的箱⼦和空箱可以选择,这必然造成装箱的效率低下。
⾸次适应算法(FF):针对下次适应算法的缺陷,⾸次适应算法处理当前物品的时候,检查所有⾮空箱⼦,找到第⼀个能够放下当前物品的箱⼦并将该物品放⼊,否则则开启新的箱⼦。
最佳适应算法(BF):与⾸次适应算法类似,唯⼀的区别时当物品装箱时,不是直接装在第⼀个可装⼊的箱⼦中,⽽是装⼊在最适合该物体的箱⼦中,如果没有该箱⼦,则开启空箱。
⾸次适应算法和最佳适应算法有⼀个缺陷,即由于物品没有实现排序,则可能由于先装⼊⼩的物品,使⼤的物品在后来放⼊时⽆法装⼊,只得开启新的箱⼦,造成了空间的浪费,因此才有了这两种算法的改进算法。
降序⾸次适应算法(FFD):先对物品按降序排序,再按照⾸次适应算法进⾏装箱。
降序最佳适应算法(BFD):先对物品按降序排序,再按照最佳适应算法进⾏装箱。
三年级乘除混合应用题装箱问题摘要:1.问题背景和意义2.乘除混合应用题的基本类型3.装箱问题的解决方法4.实际应用与练习5.总结与建议正文:随着年龄的增长,孩子们的数学能力也在不断提高。
乘除混合应用题是三年级数学学习中的一项重要内容,不仅能够检验学生对乘法和除法运算的掌握程度,还能培养他们的逻辑思维能力。
本文将以乘除混合应用题的装箱问题为例,详细介绍这类问题的解决方法,以帮助孩子们更好地应对这类题目。
一、问题背景和意义在现实生活中,装箱问题是一种非常常见的情况。
例如,在物流运输、商品销售等领域,我们需要将不同尺寸的物品装入容器中,以求最大限度地利用空间。
乘除混合应用题的装箱问题就是在此基础上提出的,它要求学生在解答过程中运用乘法和除法运算。
二、乘除混合应用题的基本类型乘除混合应用题的装箱问题主要包括以下几种类型:1.给定容器体积和物品体积,求最多可以装多少个物品。
2.给定物品体积和容器数量,求每个容器最多可以装多少个物品。
3.给定容器体积和物品数量,求最少需要多少个容器。
4.给定物品体积、容器数量和每个容器的装载量,求最多可以装多少个物品。
三、装箱问题的解决方法1.理解题意,确定解题目标。
首先要明确题目要求求解的是最多可以装多少个物品、每个容器最多可以装多少个物品、最少需要多少个容器等问题。
2.分析数据关系。
根据题目给出的数据,找出物品体积、容器体积和装载量之间的关系。
3.运用乘除法运算。
根据分析得出的关系,将数据代入相应的公式进行计算。
4.结合实际情境,进行合理推断。
在计算过程中,要结合实际情境进行合理推断,例如:当物品体积大于容器体积时,无法装入;当物品体积小于容器体积时,可以装入一个容器;当物品体积等于容器体积时,最多可以装入一个容器。
四、实际应用与练习为了更好地掌握乘除混合应用题的装箱问题,我们可以通过以下实际应用和练习进行巩固:1.妈妈买了5斤苹果,每斤10元,一共需要支付多少钱?2.一个集装箱长10米,宽6米,高4米,另一个集装箱长8米,宽4米,高2米。
装箱问题算法实现讲解有一个箱子容量为V(正整数,0≤V≤20000),同时有n个物品(0≤n≤30),每个物品有一个体积(正整数)。
要求从n个物品中,任取若干个装入箱内,使箱子的剩余空间为最小。
[样例]输入:24 一个整数,表示箱子容量6 一个整数,表示有n个物品8 接下来n行,分别表示这n个物品的各自体积。
312797输出:0 一个整数,表示箱子剩余空间算法分析:本题是经典问题:0-1背包的特殊例子(加强了已知条件)。
用整形数组volume存储各件物品的体积,用布尔型函数h(i,k)表示前i个物品通过组合能否恰好装满容量k的空间,则考虑第i件物品,如果没有被选中,则问题转化为h(i-1,k);如果第i件物品被选中了,则问题转化为h(i-1,k-volume[i]),因此有如下的表达式:h(i,k)=h(i-1,k-volume[i]) || h(i-1,k);k从V开始递减,判断h(n,k)是否为真,第一个符号要求的k即为剩余空间最小时消耗的体积。
如果此时直接编写程序,就要定义一个二维数组,空间复杂度时n*v,注意到了n,v的取值范围很大,所以用二维数组存储就会有问题。
我们注意到,h(i,k)的取值仅与h(i-1,0)~h(i-1,k)有关,且如果h(i-1,k)=true,必然有h(i,k)=true,h(i,k)的值存在继承性,而程序结束时,我们也只关心h(n,k),因此,我们可以用一维数组h(k)来存储中间信息。
为了避免重复计算,可以让k从大到小变化,为了避免出现负数,k的变化范围为v~volume[i].示例程序:#include<iostream>#include<cstring>using namespace std;int v,n;int volume[31];//存储n件物品的体积int h[20001];//h[i]=1,表示n件物品通过某种组合,所构成的体积和正和等于i;//h[i]=0,表示n件物品无论如何组合,体积和都无法等于iint main(){freopen(\"in.txt\",\"r\",stdin);freopen(\"out.txt\",\"w\",stdout);int v,n,i,j,k;while(cin>>v>>n){for(i=1;i<=n;i++)cin>>volume[i];memset(h,0,sizeof(h));h[0]=1;for(i=1;i<=n;i++)for(k=v;k>=volume[i];k--)h[k]=h[k]||h[k-volume[i]];[Page]j=v;while(j>0&&h[j]==0)j--;cout<<v-j<<endl;}return 0;。
物流装箱问题数学建模
物流装箱问题是指将一批物品放置到有限的几个箱子中,使得每个箱子的利用率最高且所使用的箱子数量最少。
这是一个经典的数学优化问题,可以通过以下步骤进行建模:
1. 定义变量:假设有 n 个物品需要装箱,第 i 个物品的体积为 vi,第 j 个箱子的容积为 cj,定义决策变量 xi,j 表示将第 i 个物品放入第 j 个箱子中(取值为0或1)。
2. 约束条件:每个物品只能被放入一个箱子中,即∑j xi,j = 1,同时每个箱子的容积不能超过其限制,即∑i vi xi,j ≤ cj。
3. 目标函数:目标是最小化使用的箱子数量,因此可以定义目标函数为∑j ∑i xi,j。
4. 模型求解:该问题可以转化为混合整数线性规划问题,可以使用商业软件(如Gurobi、CPLEX等)求解,也可以使用启发式算法(如遗传算法、模拟退火等)进行求解。
需要注意的是,该问题存在多项式时间内可解的算法,但是在实际应用中,由于数据规模较大,通常需要使用近似算法或者启发式算法进行求解。