编程scratch如何实现背包功能

编程scratch如何实现背包功能,第1张

书包功能是MIT Scratch官方团队开发的功能。Kittenblock现在就立即打通

平时我们编程,难免会遇到程序之间,有一部分程序是复用的。对于代码编程,很简单我们可以直接复制粘贴到另外的代码上。但是对于Scratch来说,它就不图形块代码复制粘贴到另外一个程序里面。

所以MIT推出了这个书包功能。

所谓的书包功能就是,当你需要复制这段程序代码积木块,你可以“塞”到书包里,等你打开另外的程序是,再把需要的代码从书包里面取出来。

首先,将背包倒扣放在桌子上,找到背包底部的转子(通常是一个圆形盘)。然后,在转子周围找到一圈小钮,每个钮下面都有一个小扣环。

接下来,使用细尖钳或其他合适的工具,轻轻地将这些小锁扣开,把扣环拉出来。然后,可以将转子轻轻地从背包中拿出来,注意不要拉扯或损坏其他部分。

当需要重新安装转子时,按照相反的步骤重新安装并锁定小扣环,确保转子能够旋转自如。如果你不熟悉这个过程,建议在 *** 作之前查找相关资料或者咨询专业人士来帮助您完成。

用改锥拆。

r魂自由是万代的robot魂系列中的一款玩具。r魂自由以还原动画为基准的形象再现除了加了一些分色涂装以及机体标识,其他与动画没有差别。

1)登山算法

用登山算法求解背包问题 function []=DengShan(n,G,P,W) %n是背包的个数,G是背包的总容量,P是价值向量,W是物体的重量向量 %n=3;G=20;P=[25,24,15];W2=[18,15,10];%输入量 W2=W; [Y,I]=sort(-P/W2);W1=[];X=[];X1=[]; for i=1:length(I) W1(i)=W2(I(i)); end W=W1; for i=1:n X(i)=0; RES=G;%背包的剩余容量 j=1; while W(j)<=RES X(j)=1; RES=RES-W(j); j=j+1; end X(j)=RES/W(j); end for i=1:length(I) X1(I(i))=X(i); end X=X1; disp('装包的方法是');disp(X);disp(XW2);disp('总的价值是:');disp(PX');

时间复杂度是非指数的

2)递归法

先看完全背包问题

一个旅行者有一个最多能用m公斤的背包,现在有n种物品,每件的重量分别是W1,W2,,Wn,

每件的价值分别为C1,C2,,Cn若的每种物品的件数足够多

求旅行者能获得的最大总价值。

本问题的数学模型如下:

设 f(x)表示重量不超过x公斤的最大价值,

则 f(x)=max{f(x-i)+c[i]} 当x>=w[i] 1<=i<=n

可使用递归法解决问题程序如下:

program knapsack04;

const maxm=200;maxn=30;

type ar=array[0maxn] of integer;

var m,n,j,i,t:integer;

c,w:ar;

function f(x:integer):integer;

var i,t,m:integer;

begin

if x=0 then f:=0 else

begin

t:=-1;

for i:=1 to n do

begin

if x>=w[i] then m:=f(x-i)+c[i];

if m>t then t:=m;

end;

f:=t;

end;

end;

begin

readln(m,n);

for i:= 1 to n do

readln(w[i],c[i]);

writeln(f(m));

end

说明:当m不大时,编程很简单,但当m较大时,容易超时

42 改进的递归法

改进的的递归法的思想还是以空间换时间,这只要将递归函数计算过程中的各个子函数的值保存起来,开辟一个

一维数组即可

程序如下:

program knapsack04;

const maxm=2000;maxn=30;

type ar=array[0maxn] of integer;

var m,n,j,i,t:integer;

c,w:ar;

p:array[0maxm] of integer;

function f(x:integer):integer;

var i,t,m:integer;

begin

if p[x]<>-1 then f:=p[x]

else

begin

if x=0 then p[x]:=0 else

begin

t:=-1;

for i:=1 to n do

begin

if x>=w[i] then m:=f(i-w[i])+c[i];

if m>t then t:=m;

end;

p[x]:=t;

end;

f:=p[x];

end;

end;

begin

readln(m,n);

for i:= 1 to n do

readln(w[i],c[i]);

fillchar(p,sizeof(p),-1);

writeln(f(m));

end

3)贪婪算法

改进的背包问题:给定一个超递增序列和一个背包的容量,然后在超递增序列中选(只能选一次)或不选每一个数值,使得选中的数值的和正好等于背包的容量。

代码思路:从最大的元素开始遍历超递增序列中的每个元素,若背包还有大于或等于当前元素值的空间,则放入,然后继续判断下一个元素;若背包剩余空间小于当前元素值,则判断下一个元素

简单模拟如下:

#define K 10

#define N 10

#i nclude <stdlibh>

#i nclude <conioh>

void create(long array[],int n,int k)

{/产生超递增序列/

int i,j;

array[0]=1;

for(i=1;i<n;i++)

{

long t=0;

for(j=0;j<i;j++)

t=t+array[j];

array[i]=t+random(k)+1;

}

}

void output(long array[],int n)

{/输出当前的超递增序列/

int i;

for(i=0;i<n;i++)

{

if(i%5==0)

printf("\n");

printf("%14ld",array[i]);

}

}

void beibao(long array[],int cankao[],long value,int count)

{/背包问题求解/

int i;

long r=value;

for(i=count-1;i>=0;i--)/遍历超递增序列中的每个元素/

{

if(r>=array[i])/如果当前元素还可以放入背包,即背包剩余空间还大于当前元素/

{

r=r-array[i];

cankao[i]=1;

}

else/背包剩余空间小于当前元素值/

cankao[i]=0;

}

}

void main()

{

long array[N];

int cankao[N]={0};

int i;

long value,value1=0;

clrscr();

create(array,N,K);

output(array,N);

printf("\nInput the value of beibao:\n");

scanf("%ld",&value);

beibao(array,cankao,value,N);

for(i=0;i<N;i++)/所有已经选中的元素之和/

if(cankao[i]==1)

value1+=array[i];

if(value==value1)

{

printf("\nWe have got a solution,that is:\n");

for(i=0;i<N;i++)

if(cankao[i]==1)

{

if(i%5==0)

printf("\n");

printf("%13ld",array[i]);

}

}

else

printf("\nSorryWe have not got a solution\n");

}

贪婪算法的另一种写法,beibao函数是以前的代码,用来比较两种算法:

#define K 10

#define N 10

#i nclude <stdlibh>

#i nclude <conioh>

void create(long array[],int n,int k)

{

int i,j;

array[0]=1;

for(i=1;i<n;i++)

{

long t=0;

for(j=0;j<i;j++)

t=t+array[j];

array[i]=t+random(k)+1;

}

}

void output(long array[],int n)

{

int i;

for(i=0;i<n;i++)

{

if(i%5==0)

printf("\n");

printf("%14ld",array[i]);

}

}

void beibao(long array[],int cankao[],long value,int count)

{

int i;

long r=value;

for(i=count-1;i>=0;i--)

{

if(r>=array[i])

{

r=r-array[i];

cankao[i]=1;

}

else

cankao[i]=0;

}

}

int beibao1(long array[],int cankao[],long value,int n)

{/贪婪算法/

int i;

long value1=0;

for(i=n-1;i>=0;i--)/先放大的物体,再考虑小的物体/

if((value1+array[i])<=value)/如果当前物体可以放入/

{

cankao[i]=1;/1表示放入/

value1+=array[i];/背包剩余容量减少/

}

else

cankao[i]=0;

if(value1==value)

return 1;

return 0;

}

void main()

{

long array[N];

int cankao[N]={0};

int cankao1[N]={0};

int i;

long value,value1=0;

clrscr();

create(array,N,K);

output(array,N);

printf("\nInput the value of beibao:\n");

scanf("%ld",&value);

beibao(array,cankao,value,N);

for(i=0;i<N;i++)

if(cankao[i]==1)

value1+=array[i];

if(value==value1)

{

printf("\nWe have got a solution,that is:\n");

for(i=0;i<N;i++)

if(cankao[i]==1)

{

if(i%5==0)

printf("\n");

printf("%13ld",array[i]);

}

}

else

printf("\nSorryWe have not got a solution\n");

printf("\nSecond method:\n");

if(beibao1(array,cankao1,value,N)==1)

{

for(i=0;i<N;i++)

if(cankao1[i]==1)

{

if(i%5==0)

printf("\n");

printf("%13ld",array[i]);

}

}

else

printf("\nSorryWe have not got a solution\n");

}

4)动态规划算法

解决0/1背包问题的方法有多种,最常用的有贪婪法和动态规划法。其中贪婪法无法得到问题的最优解,而动态规划法都可以得到最优解,下面是用动态规划法来解决0/1背包问题。

动态规划算法与分治法类似,其基本思想是将待求解问题分解成若干个子问题,然后从这些子问题的解得到原问题的解。与分治法不同的是,适合于用动态规划法求解的问题,经分解得到的子问题往往不是互相独立的,若用分治法解这类问题,则分解得到的子问题数目太多,以至于最后解决原问题需要耗费过多的时间。动态规划法又和贪婪算法有些一样,在动态规划中,可将一个问题的解决方案视为一系列决策的结果。不同的是,在贪婪算法中,每采用一次贪婪准则便做出一个不可撤回的决策,而在动态规划中,还要考察每个最优决策序列中是否包含一个最优子序列。

0/1背包问题

在0 / 1背包问题中,需对容量为c 的背包进行装载。从n 个物品中选取装入背包的物品,每件物品i 的重量为wi ,价值为pi 。对于可行的背包装载,背包中物品的总重量不能超过背包的容量,最佳装载是指所装入的物品价值最高,即p1x1+p2x1++pixi(其1<=i<=n,x取0或1,取1表示选取物品i) 取得最大值。

在该问题中需要决定x1 xn的值。假设按i = 1,2,,n 的次序来确定xi 的值。如果置x1 = 0,则问题转变为相对于其余物品(即物品2,3,,n),背包容量仍为c 的背包问题。若置x1 = 1,问题就变为关于最大背包容量为c-w1 的问题。现设r{c,c-w1 } 为剩余的背包容量。

在第一次决策之后,剩下的问题便是考虑背包容量为r 时的决策。不管x1 是0或是1,[x2 ,,xn ] 必须是第一次决策之后的一个最优方案,如果不是,则会有一个更好的方案[y2,,yn ],因而[x1,y2,,yn ]是一个更好的方案。

假设n=3, w=[100,14,10], p=[20,18,15], c= 116。若设x1 = 1,则在本次决策之后,可用的背包容量为r= 116-100=16 。[x2,x3 ]=[0,1] 符合容量限制的条件,所得值为1 5,但因为[x2,x3 ]= [1,0] 同样符合容量条件且所得值为1 8,因此[x2,x3 ] = [ 0,1] 并非最优策略。即x= [ 1,0,1] 可改进为x= [ 1,1,0 ]。若设x1 = 0,则对于剩下的两种物品而言,容量限制条件为116。总之,如果子问题的结果[x2,x3 ]不是剩余情况下的一个最优解,则[x1,x2,x3 ]也不会是总体的最优解。在此问题中,最优决策序列由最优决策子序列组成。假设f (i,y) 表示剩余容量为y,剩余物品为i,i + 1,,n 时的最优解的值,即:利用最优序列由最优子序列构成的结论,可得到f 的递归式为:

当j>=wi时: f(i,j)=max{f(i+1,j),f(i+1,j-wi)+vi} ①式

当0<=j<wi时:f(i,j)=f(i+1,j) ②式

fn( 1 ,c) 是初始时背包问题的最优解。

以本题为例:若0≤y<1 0,则f ( 3 ,y) = 0;若y≥1 0,f ( 3 ,y) = 1 5。利用②式,可得f (2, y) = 0 ( 0≤y<10 );f(2,y)= 1 5(1 0≤y<1 4);f(2,y)= 1 8(1 4≤y<2 4)和f(2,y)= 3 3(y≥2 4)。因此最优解f ( 1 , 11 6 ) = m a x {f(2,11 6),f(2,11 6 - w1)+ p1} = m a x {f(2,11 6),f(2,1 6)+ 2 0 } = m a x { 3 3,3 8 } = 3 8。

现在计算xi 值,步骤如下:若f ( 1 ,c) =f ( 2 ,c),则x1 = 0,否则x1 = 1。接下来需从剩余容量c-w1中寻求最优解,用f (2, c-w1) 表示最优解。依此类推,可得到所有的xi (i= 1n) 值。

在该例中,可得出f ( 2 , 116 ) = 3 3≠f ( 1 , 11 6 ),所以x1 = 1。接着利用返回值3 8 -p1=18 计算x2 及x3,此时r = 11 6 -w1 = 1 6,又由f ( 2 , 1 6 ) = 1 8,得f ( 3 , 1 6 ) = 1 4≠f ( 2 , 1 6 ),因此x2 = 1,此时r= 1 6 -w2 = 2,所以f (3,2) =0,即得x3 = 0。

是编程里的背包问题么

这里有dd大神的 背包九讲的一部分 LZ先凑合看下吧

P01: 01背包问题

题目

有N件物品和一个容量为V的背包。第i件物品的费用是c[i],价值是w[i]。求解将哪些物品装入背包可使价值总和最大。

基本思路

这是最基础的背包问题,特点是:每种物品仅有一件,可以选择放或不放。

用子问题定义状态:即f[i][v]表示前i件物品恰放入一个容量为v的背包可以获得的最大价值。则其状态转移方程便是:

f[i][v]=max{f[i-1][v],f[i-1][v-c[i]]+w[i]}

这个方程非常重要,基本上所有跟背包相关的问题的方程都是由它衍生出来的。所以有必要将它详细解释一下:“将前i件物品放入容量为v的背包中”这个子问题,若只考虑第i件物品的策略(放或不放),那么就可以转化为一个只牵扯前i-1件物品的问题。如果不放第i件物品,那么问题就转化为“前i-1件物品放入容量为v的背包中”,价值为f[i-1][v];如果放第i件物品,那么问题就转化为“前i-1件物品放入剩下的容量为v-c[i]的背包中”,此时能获得的最大价值就是f[i-1][v-c[i]]再加上通过放入第i件物品获得的价值w[i]。

优化空间复杂度

以上方法的时间和空间复杂度均为O(NV),其中时间复杂度基本已经不能再优化了,但空间复杂度却可以优化到O(V)。

先考虑上面讲的基本思路如何实现,肯定是有一个主循环i=1N,每次算出来二维数组f[i][0V]的所有值。那么,如果只用一个数组f[0V],能不能保证第i次循环结束后f[v]中表示的就是我们定义的状态f[i][v]呢?f[i][v]是由f[i-1][v]和f[i-1][v-c[i]]两个子问题递推而来,能否保证在推f[i][v]时(也即在第i次主循环中推f[v]时)能够得到f[i-1][v]和f[i-1][v-c[i]]的值呢?事实上,这要求在每次主循环中我们以v=V0的顺序推f[v],这样才能保证推f[v]时f[v-c[i]]保存的是状态f[i-1][v-c[i]]的值。伪代码如下:

for i=1N

for v=V0

f[v]=max{f[v],f[v-c[i]]+w[i]};

其中的f[v]=max{f[v],f[v-c[i]]}一句恰就相当于我们的转移方程f[i][v]=max{f[i-1][v],f[i-1][v-c[i]]},因为现在的f[v-c[i]]就相当于原来的f[i-1][v-c[i]]。如果将v的循环顺序从上面的逆序改成顺序的话,那么则成了f[i][v]由f[i][v-c[i]]推知,与本题意不符,但它却是另一个重要的背包问题P02最简捷的解决方案,故学习只用一维数组解01背包问题是十分必要的。

事实上,使用一维数组解01背包的程序在后面会被多次用到,所以这里抽象出一个处理一件01背包中的物品过程,以后的代码中直接调用不加说明。

过程ZeroOnePack,表示处理一件01背包中的物品,两个参数cost、weight分别表明这件物品的费用和价值。

procedure ZeroOnePack(cost,weight)

for v=Vcost

f[v]=max{f[v],f[v-cost]+weight}

注意这个过程里的处理与前面给出的伪代码有所不同。前面的示例程序写成v=V0是为了在程序中体现每个状态都按照方程求解了,避免不必要的思维复杂度。而这里既然已经抽象成看作黑箱的过程了,就可以加入优化。费用为cost的物品不会影响状态f[0cost-1],这是显然的。

有了这个过程以后,01背包问题的伪代码就可以这样写:

for i=1N

ZeroOnePack(c[i],w[i]);

初始化的细节问题

我们看到的求最优解的背包问题题目中,事实上有两种不太相同的问法。有的题目要求“恰好装满背包”时的最优解,有的题目则并没有要求必须把背包装满。一种区别这两种问法的实现方法是在初始化的时候有所不同。

如果是第一种问法,要求恰好装满背包,那么在初始化时除了f[0]为0其它f[1V]均设为-∞,这样就可以保证最终得到的f[N]是一种恰好装满背包的最优解。

如果并没有要求必须把背包装满,而是只希望价格尽量大,初始化时应该将f[0V]全部设为0。

为什么呢?可以这样理解:初始化的f数组事实上就是在没有任何物品可以放入背包时的合法状态。如果要求背包恰好装满,那么此时只有容量为0的背包可能被价值为0的nothing“恰好装满”,其它容量的背包均没有合法的解,属于未定义的状态,它们的值就都应该是-∞了。如果背包并非必须被装满,那么任何容量的背包都有一个合法解“什么都不装”,这个解的价值为0,所以初始时状态的值也就全部为0了。

这个小技巧完全可以推广到其它类型的背包问题,后面也就不再对进行状态转移之前的初始化进行讲解。

小结

01背包问题是最基本的背包问题,它包含了背包问题中设计状态、方程的最基本思想,另外,别的类型的背包问题往往也可以转换成01背包问题求解。故一定要仔细体会上面基本思路的得出方法,状态转移方程的意义,以及最后怎样优化的空间复杂度。

首页

P02: 完全背包问题

题目

有N种物品和一个容量为V的背包,每种物品都有无限件可用。第i种物品的费用是c[i],价值是w[i]。求解将哪些物品装入背包可使这些物品的费用总和不超过背包容量,且价值总和最大。

基本思路

这个问题非常类似于01背包问题,所不同的是每种物品有无限件。也就是从每种物品的角度考虑,与它相关的策略已并非取或不取两种,而是有取0件、取1件、取2件……等很多种。如果仍然按照解01背包时的思路,令f[i][v]表示前i种物品恰放入一个容量为v的背包的最大权值。仍然可以按照每种物品不同的策略写出状态转移方程,像这样:

f[i][v]=max{f[i-1][v-kc[i]]+kw[i]|0<=kc[i]<=v}

这跟01背包问题一样有O(NV)个状态需要求解,但求解每个状态的时间已经不是常数了,求解状态f[i][v]的时间是O(v/c[i]),总的复杂度是超过O(VN)的。

将01背包问题的基本思路加以改进,得到了这样一个清晰的方法。这说明01背包问题的方程的确是很重要,可以推及其它类型的背包问题。但我们还是试图改进这个复杂度。

一个简单有效的优化

完全背包问题有一个很简单有效的优化,是这样的:若两件物品i、j满足c[i]<=c[j]且w[i]>=w[j],则将物品j去掉,不用考虑。这个优化的正确性显然:任何情况下都可将价值小费用高得j换成物美价廉的i,得到至少不会更差的方案。对于随机生成的数据,这个方法往往会大大减少物品的件数,从而加快速度。然而这个并不能改善最坏情况的复杂度,因为有可能特别设计的数据可以一件物品也去不掉。

这个优化可以简单的O(N^2)地实现,一般都可以承受。另外,针对背包问题而言,比较不错的一种方法是:首先将费用大于V的物品去掉,然后使用类似计数排序的做法,计算出费用相同的物品中价值最高的是哪个,可以O(V+N)地完成这个优化。这个不太重要的过程就不给出伪代码了,希望你能独立思考写出伪代码或程序。

转化为01背包问题求解

既然01背包问题是最基本的背包问题,那么我们可以考虑把完全背包问题转化为01背包问题来解。最简单的想法是,考虑到第i种物品最多选V/c[i]件,于是可以把第i种物品转化为V/c[i]件费用及价值均不变的物品,然后求解这个01背包问题。这样完全没有改进基本思路的时间复杂度,但这毕竟给了我们将完全背包问题转化为01背包问题的思路:将一种物品拆成多件物品。

更高效的转化方法是:把第i种物品拆成费用为c[i]2^k、价值为w[i]2^k的若干件物品,其中k满足c[i]2^k<=V。这是二进制的思想,因为不管最优策略选几件第i种物品,总可以表示成若干个2^k件物品的和。这样把每种物品拆成O(log(V/c[i]))件物品,是一个很大的改进。

但我们有更优的O(VN)的算法。

O(VN)的算法

这个算法使用一维数组,先看伪代码:

for i=1N

for v=0V

f[v]=max{f[v],f[v-cost]+weight}

你会发现,这个伪代码与P01的伪代码只有v的循环次序不同而已。为什么这样一改就可行呢?首先想想为什么P01中要按照v=V0的逆序来循环。这是因为要保证第i次循环中的状态f[i][v]是由状态f[i-1][v-c[i]]递推而来。换句话说,这正是为了保证每件物品只选一次,保证在考虑“选入第i件物品”这件策略时,依据的是一个绝无已经选入第i件物品的子结果f[i-1][v-c[i]]。而现在完全背包的特点恰是每种物品可选无限件,所以在考虑“加选一件第i种物品”这种策略时,却正需要一个可能已选入第i种物品的子结果f[i][v-c[i]],所以就可以并且必须采用v=0V的顺序循环。这就是这个简单的程序为何成立的道理。

这个算法也可以以另外的思路得出。例如,基本思路中的状态转移方程可以等价地变形成这种形式:

f[i][v]=max{f[i-1][v],f[i][v-c[i]]+w[i]}

将这个方程用一维数组实现,便得到了上面的伪代码。

最后抽象出处理一件完全背包类物品的过程伪代码,以后会用到:

procedure CompletePack(cost,weight)

for v=costV

f[v]=max{f[v],f[v-c[i]]+w[i]}

总结

完全背包问题也是一个相当基础的背包问题,它有两个状态转移方程,分别在“基本思路”以及“O(VN)的算法“的小节中给出。希望你能够对这两个状态转移方程都仔细地体会,不仅记住,也要弄明白它们是怎么得出来的,最好能够自己想一种得到这些方程的方法。事实上,对每一道动态规划题目都思考其方程的意义以及如何得来,是加深对动态规划的理解、提高动态规划功力的好方法。

以上是《背包九讲》的原话

可以算是最好的背包教程了 全文可以去百度文库查一下

背包带的钩头能拆。

双面虎头包肩带里面连接处有调节拆卸的地方,如果在使用过程中需要调节一下或者拆卸就从那个地拆开就可以了。

背包指外出或行军时背在背上的包的统称。

点击要更换的武器直接跳转。

在游戏《全民q神》卸下背包配刀只需要,在背包中点击需要更换的武器,然后就自动跳转到武器库,背包上的配套就会自动更换下来了。

《全民q神》使q战,双端游戏巅峰大,游戏双端数据互通,体验更丰富,公平绿色的竞技环境,紧张刺激的游戏节奏,完美流畅的 *** 作手感,全3D酣畅体验,玩家可以体验到真实的血腥战场,在q林d雨里展开生死狙击。

以上就是关于编程scratch如何实现背包功能全部的内容,包括:编程scratch如何实现背包功能、背包过滤器转子怎么拆、r魂自由背包怎么拆等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zz/10119529.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-05
下一篇 2023-05-05

发表评论

登录后才能评论

评论列表(0条)

保存