贪心算法背包问题

合集下载

贪心算法之背包问题

贪心算法之背包问题

贪⼼算法之背包问题问题描述:给定n种物品,1个背包,背包容量为c,每个物品i的价值为vi,重量为wi,如何选择装⼊物品能使背包的总价值最⼤?注意:与0-1背包问题不同,在选择物品i装⼊背包时,可以选择物品i的⼀部分,⽽不⼀定要全部装⼊背包,1<=i<=n形式化描述:给定c >0, wi >0, vi >0 , 1≤i≤n.要求找⼀n元向量A=(x1,x2,…,xn), 0<=xi<=1【0~1表⽰取物品的某⼀部分】,1<=i<=n,使得 ∑wixi≤c【物品的重量和⼩于背包总容量】⽽且∑ vixi达到最⼤。

算法思路:将物品按照单位重量价值进⾏排序(从⼤到⼩),将尽可能多的单位重量价值最⾼的物品装⼊背包,若将这种物品全部装⼊背包后,背包还有多余容量,则选择单位重量价值次⾼的并尽可能多地装⼊背包。

如果最后⼀件物品⽆法全部装⼊,则计算可以装⼊的⽐例,然后按⽐例装⼊。

代码实现:数据结构:结构体1 #include <iostream>2 #include <algorithm>3using namespace std;4struct item{5int weight;//物品的重量6int value;//物品的价值7float bi;//物品单位重量的价值8float rate;//使⽤率:1代表物品完整放⼊,⼩于1代表被分割后放⼊9 }items[100];10bool cmp(const item &a,const item &b){11return a.bi>b.bi;12 }13int main(){14int n;//n件物品15float c;//背包容量为c16 cout<<"输⼊物品件数和背包容量:"<<endl;17 cin>>n>>c;18 cout<<"依次输⼊每件物品的价值和重量:"<<endl;19float v[n],w[n];//v[n]:n件物品的价值,w[n]:n件商品的重量20for(int i=0;i<n;i++){21 cin>>items[i].value>>items[i].weight;22 items[i].bi=items[i].value/items[i].weight;//计算单位重量价值23 items[i].rate=0;//初始化每件物品的使⽤率24 }25 sort(items,items+n,cmp);//按照单位重量的价值排序26int sum=0,j=0;27for(j=0;j<n;j++){28if(items[j].weight<=c){//选择单位价值重量最⼤的并且不超过背包容量的29 items[j].rate=1;30 sum+=items[j].weight;31 c-=items[j].weight;32 cout<<"重:"<<items[j].weight<<"、价值:"<<items[j].value<<"的物品被放⼊了背包"<<endl<<"放⼊⽐例:"<<items[j].rate<<endl;33 }34else break;35 }36if(j<n){//物品未装完37 items[j].rate=c/items[j].weight;//背包容量还剩c,计算出未装⼊的物品能装多少的⽐例38 sum+=items[j].rate*items[j].weight;//加上装⼊部分⽐例物品的重量39 cout<<"重:"<<items[j].weight<<"、价值:"<<items[j].value<<"被放⼊了背包"<<endl<<"放⼊⽐例:"<<items[j].rate<<endl;40 }41return0;424344 }。

贪心算法-01背包问题

贪心算法-01背包问题

贪⼼算法-01背包问题1、问题描述:给定n种物品和⼀背包。

物品i的重量是wi,其价值为vi,背包的容量为C。

问:应如何选择装⼊背包的物品,使得装⼊背包中物品的总价值最⼤?形式化描述:给定c >0, wi >0, vi >0 , 1≤i≤n.要求找⼀n元向量(x1,x2,…,xn,), xi∈{0,1}, ∋ ∑ wi xi≤c,且∑ vi xi达最⼤.即⼀个特殊的整数规划问题。

2、最优性原理:设(y1,y2,…,yn)是 (3.4.1)的⼀个最优解.则(y2,…,yn)是下⾯相应⼦问题的⼀个最优解:证明:使⽤反证法。

若不然,设(z2,z3,…,zn)是上述⼦问题的⼀个最优解,⽽(y2,y3,…,yn)不是它的最优解。

显然有∑vizi > ∑viyi (i=2,…,n)且 w1y1+ ∑wizi<= c因此 v1y1+ ∑vizi (i=2,…,n) > ∑ viyi, (i=1,…,n)说明(y1,z2, z3,…,zn)是(3.4.1)0-1背包问题的⼀个更优解,导出(y1,y2,…,yn)不是背包问题的最优解,⽭盾。

3、递推关系:设所给0-1背包问题的⼦问题的最优值为m(i,j),即m(i,j)是背包容量为j,可选择物品为i,i+1,…,n时0-1背包问题的最优值。

由0-1背包问题的最优⼦结构性质,可以建⽴计算m(i,j)的递归式:注:(3.4.3)式此时背包容量为j,可选择物品为i。

此时在对xi作出决策之后,问题处于两种状态之⼀:(1)背包剩余容量是j,没产⽣任何效益;(2)剩余容量j-wi,效益值增长了vi ;使⽤递归C++代码如下:#include<iostream>using namespace std;const int N=3;const int W=50;int weights[N+1]={0,10,20,30};int values[N+1]={0,60,100,120};int V[N+1][W+1]={0};int knapsack(int i,int j){int value;if(V[i][j]<0){if(j<weights[i]){value=knapsack(i-1,j);}else{value=max(knapsack(i-1,j),values[i]+knapsack(i-1,j-weights[i]));}V[i][j]=value;}return V[i][j];}int main(){int i,j;for(i=1;i<=N;i++)for(j=1;j<=W;j++)V[i][j]=-1;cout<<knapsack(3,50)<<endl;cout<<endl;}不使⽤递归的C++代码:简单⼀点的修改//3d10-1 动态规划背包问题#include <iostream>using namespace std;const int N = 4;void Knapsack(int v[],int w[],int c,int n,int m[][10]);void Traceback(int m[][10],int w[],int c,int n,int x[]);int main(){int c=8;int v[]={0,2,1,4,3},w[]={0,1,4,2,3};//下标从1开始int x[N+1];int m[10][10];cout<<"待装物品重量分别为:"<<endl;for(int i=1; i<=N; i++){cout<<w[i]<<" ";}cout<<endl;cout<<"待装物品价值分别为:"<<endl;for(int i=1; i<=N; i++){cout<<v[i]<<" ";}cout<<endl;Knapsack(v,w,c,N,m);cout<<"背包能装的最⼤价值为:"<<m[1][c]<<endl;Traceback(m,w,c,N,x);cout<<"背包装下的物品编号为:"<<endl;for(int i=1; i<=N; i++){if(x[i]==1){cout<<i<<" ";}}cout<<endl;return 0;}void Knapsack(int v[],int w[],int c,int n,int m[][10]){int jMax = min(w[n]-1,c);//背包剩余容量上限范围[0~w[n]-1] for(int j=0; j<=jMax;j++){m[n][j]=0;}for(int j=w[n]; j<=c; j++)//限制范围[w[n]~c]{m[n][j] = v[n];}for(int i=n-1; i>1; i--){jMax = min(w[i]-1,c);for(int j=0; j<=jMax; j++)//背包不同剩余容量j<=jMax<c{m[i][j] = m[i+1][j];//没产⽣任何效益}for(int j=w[i]; j<=c; j++) //背包不同剩余容量j-wi >c{m[i][j] = max(m[i+1][j],m[i+1][j-w[i]]+v[i]);//效益值增长vi }}m[1][c] = m[2][c];if(c>=w[1]){m[1][c] = max(m[1][c],m[2][c-w[1]]+v[1]);}}//x[]数组存储对应物品0-1向量,0不装⼊背包,1表⽰装⼊背包void Traceback(int m[][10],int w[],int c,int n,int x[]){for(int i=1; i<n; i++){if(m[i][c] == m[i+1][c]){x[i]=0;}else{x[i]=1;c-=w[i];}}x[n]=(m[n][c])?1:0;}运⾏结果:算法执⾏过程对m[][]填表及Traceback回溯过程如图所⽰:从m(i,j)的递归式容易看出,算法Knapsack需要O(nc)计算时间; Traceback需O(n)计算时间;算法总体需要O(nc)计算时间。

背包问题解析(一)-贪心算法

背包问题解析(一)-贪心算法

背包问题解析(⼀)-贪⼼算法⼀、题⽬:有N件物品和⼀个容量为V的背包。

第i件物品的重量是w[i],价值是v[i]。

求解将哪些物品装⼊背包可使这些物品的重量总和不超过背包容量,且价值总和最⼤。

⼆、解决思路:本题刚开始的解题的时候,想采取贪⼼算法来解决,也就是将放⼊的物品的性价⽐按照从⾼到低进⾏排序,然后优先放优先级⾼的,其次优先级低的。

三、代码实现(python)1# 重量w=[5,4,3,2]2# 价值v=[6,5,4,3]3 b=[]4 m=int(input("请输⼊背包的最⼤重量:"))5 n=int(input("请输⼊商品的数量:"))6for i in range(n):7 a=input("请分别输⼊重量和价值,以空格隔开:")8 a=a.split("")9for i in range(len(a)):10 a[i]=int(a[i])11 b.append(a)12print("加载初始化:",b)13for i in range(len(b)):14for j in range(i+1,len(b)):15if b[i][1]/b[i][0]<b[j][1]/b[j][0]:16 b[i],b[j]=b[j],b[i]17print("性价⽐排序:",b)18 v=019 c=[]20for i in range(len(b)):21if m-b[i][0]>0:22 m=m-b[i][0]23 c.append(b[i])24 v+=b[i][1]25print("放⼊背包:",c)26print("最⼤价值为:",v)打印结果:四、算法分析:贪⼼选择是指所求问题的整体最优解可以通过⼀系列局部最优的选择,即贪⼼选择来达到。

贪心算法求连续背包问题

贪心算法求连续背包问题

实验项目名称:贪心算法求连续背包问题一、实验目的:明确连续背包问题的概念;利用贪心算法解决连连续续背包问题;并通过本例熟悉贪心算法在程序设计中的应用方法。

二、实验原理: 贪心算法原理:在贪婪算法(greedy method )中采用逐步构造最优解的方法。

在每个阶段,都作出一个看上去最优的决策(在一定的标准下)。

决策一旦作出,就不可再更改。

作出贪婪决策的依据称为贪婪准则(greedy criterion )。

三、实验内容与步骤:贪心算法求连续背包问题问题描述:已知n 个物体和1个背包,其中物体i 有重量w i 和价值v i ,背包承重量为W 。

求一装载方案,要求在不超过背包负重的前提下,背包中装入的物品价值最大。

很明显,如果1ni i w W =≤∑,则最优解就是装入全部物体,因此下面假设1n i i w W =>∑。

注:连续背包问题中的物体可以任意分割,即部分装入背包。

分析:连续背包问题可形式化为如下模型:{}11max ..[0,1],1,,ni ii ni ii i x v x w W s t x i n ==⎧≤⎪⎨∈∈⎪⎩∑∑对于连续背包问题,可用贪心技术求得最优解。

贪心策略是单位重量价值高者优先。

例如:所给物体的重量和价值如下,则,程序可以得到如下结果:最大价值为163.0;所选各物体的数量为:1.0 1.0 1.0 0.8参考程序段如下//连续背包问题的贪心算法,最大单位重量价值优先//输入:各物体重量w 、价值v 和背包重量W ,已按v/w 降序排列#include<stdio.h>int knapsack(int n1,float w1[],float v1[],float W1){ int i; float weight; float x[10],s=0; for(i=1;i<=n1;i++) x[i]=0; weight=0; i=1;while(weight<W1) {if(weight+w1[i]<W1){x[i]=1;weight=weight+w1[i];}else{x[i]=(W1-weight)/w1[i];weight=W1;}i++;}for(i=1;i<=n1;i++) s=s+x[i]*v1[i];printf("背包所能容纳商品的最大价值为:%f\n",s);printf("所选择的商品的一个序列为:\n");for(i=1;i<=n1;i++)printf("%8.3f",x[i]);}void main(){int n,i,j;float w[10],v[10],W;clrscr();printf("输入商品数量n 和背包容量W:\n");scanf("%d,%f",&n,&W);printf("输入每件商品的重量,价值:\n");for(i=1;i<=n;i++)scanf("%f,%f",&w[i],&v[i]);knapsack(n,w,v,W);printf("\n");system("pause");}。

C++贪心算法实现部分背包问题

C++贪心算法实现部分背包问题

C++贪⼼算法实现部分背包问题问题描述:在部分背包问题中,可以不必拿⾛整个⼀件物品,⽽是可以拿⾛该物品的任意部分。

以此求得在限定背包总重量,从给定的物品中进⾏选择的情况下的最佳(总价值最⾼)的选择⽅案。

细节须知:分别输出到同⽂件夹下两个⽂本⽂件中,名称分别是:“backpack-object.txt”和“backpack-weight.txt”。

算法原理:先求出所有物品的单位重量价值并进⾏由⼤到⼩的排序。

其次从排序处于⾸位的物品开始选择直到⽆法完整装⼊背包的物品,将其部分装⼊背包以填满背包的总重量,从⽽求得价值最⾼的选择⽅案。

1 #include <cstdio>2 #include <iostream>3 #include <ctime>4 #include <windows.h>5 #include <algorithm>6 #include <fstream>7using namespace std;8struct object9{10int no;11double weight;12double value;13double average;14};15bool cmp(const object &x, const object &y)16{17return x.average > y.average;//从⼩到⼤排<,若要从⼤到⼩排则>18}19void greedySelector(int m,int W,int solution[],struct object object[]){20int i = 0,V = 0,j = 0;21while(object[i].weight < W)22 {23 solution[i] = 1;24 W = W - object[i].weight;25 V = V + object[i].value;26 i++;27 }28 V = V + (W/object[i].weight)*object[i].value;29 solution[i] = 1;30 cout << "The corresponding value of the optimal option is:" << V << endl;31/*for( i = 0; i < m; i++)32 {33 if(solution[i] == 1)34 {35 cout << object[i].no << endl;36 }37 }*/38}39int main(void)40{41 LARGE_INTEGER nFreq;42 LARGE_INTEGER nBeginTime;43 LARGE_INTEGER nEndTime;44 ofstream fout1;45 ofstream fout2;46 srand((unsigned int)time(NULL));47int m,i,j,t;48double W;49double cost;50 cout << "Please enter the number of times you want to run the program:";51 cin >> t;52 fout1.open("backpack-object.txt",ios::app);53if(!fout1){54 cerr<<"Can not open file 'backpack-object.txt' "<<endl;55return -1;56 }57 fout1.setf(ios_base::fixed,ios_base::floatfield); //防⽌输出的数字使⽤科学计数法58 fout2.open("backpack-weight.txt",ios::app);59if(!fout2){60 cerr<<"Can not open file 'backpack-weight.txt' "<<endl;61return -1;62 }63 fout2.setf(ios_base::fixed,ios_base::floatfield); //防⽌输出的数字使⽤科学计数法64for (j = 0;j < t;j++)65 {66 cout << "——————————————————The "<< j + 1 << "th test —————————————————"<<endl;67 m = 1 + rand()%100000; //物品个数68 W = 10 + rand()%100000; //背包总重量69 fout1 << m << ",";70 fout2 << (int)W << ",";71int solution[m];72object object[m];73for( i = 0;i < m;i++)74 {75object[i].no = i + 1;76object[i].value = 1 + rand()%10000;77object[i].weight = 1 + rand()%10000;78object[i].average = object[i].value/object[i].weight;79 }80 QueryPerformanceFrequency(&nFreq);81 QueryPerformanceCounter(&nBeginTime);82 sort(object,object + m,cmp);83 greedySelector(m,W,solution,object);84 QueryPerformanceCounter(&nEndTime);85 cost=(double)(nEndTime.QuadPart - nBeginTime.QuadPart) / (double)nFreq.QuadPart;86 fout1 << cost << endl;87 fout2 << cost << endl;88 cout << "The running time is:" << cost << " s" << endl;89 }90 fout1.close();91 fout2.close();92 cout << endl;93 cout << "Success!" << endl;94return0;95 }程序设计思路:① 数据结构:结构体中存储物品序号、物品的重量、物品的价值、物品的单位重量价值;② 利⽤C++⾃带的sort函数对结构体按照物品的单位重量价值进⾏降序排列;③ 从排序处于⾸位的物品开始选择直到⽆法完整装⼊背包的物品,将其部分装⼊背包以填满背包的总重量,从⽽求得价值最⾼的选择⽅案。

贪心法求解01背包问题

贪心法求解01背包问题

贪心法的关键是度量标准,这个程序的度量标准有三个占用空间最小物品效益最大物品效益/占用空间最大程序实现如下:至于文件的操作不加论述。

#include <stdio.h>#include <stdlib.h>typedef struct{char name[10];int weight;int price;}Project;Project *Input(Project *wp,int TotalNum,int TotalWeight) {int i,j,Way,GoBack,RealWeight,RealPrice,TotalPrice;Project temp;do{printf("请选择:\n");printf(" 1.空间最优\n");printf(" 2.价格最优\n");printf(" 3.价格空间比最优\n");scanf("%d",&Way);switch(Way){case 1:for(i=0;i<TotalNum;i++)for(j=0;j<TotalNum-i-1;j++){if(wp[j].weight>wp[j+1].weight){temp=wp[j];wp[j]=wp[j+1];wp[j+1]=temp;}}break;case 2:for(i=0;i<TotalNum;i++)for(j=0;j<TotalNum-i-1;j++){if(wp[j].price<wp[j+1].price){temp=wp[j];wp[j]=wp[j+1];wp[j+1]=temp;}}break;case 3:for(i=0;i<TotalNum;i++)for(j=0;j<TotalNum-i-1;j++){if((float)wp[j].price/(float)wp[j].weight<(float)wp[j+1].price/(float)wp[j+1].weight){temp=wp[j];wp[j]=wp[j+1];wp[j+1]=temp;}}break;default:{printf("输入错误!\n");exit(1);}}i=0;RealWeight=wp[0].weight;TotalPrice=wp[0].price;printf("被装入背包的物品是:\n(物品名价格重量)\n");while(RealWeight<TotalWeight&&i<TotalNum){printf("%s %d %d\n",wp[i].name,wp[i].price,wp[i].weight);i++;RealWeight+=wp[i].weight;TotalPrice+=wp[i].price;}RealWeight-=wp[i].weight;TotalPrice-=wp[i].price;printf("求解结束!背包所装物品总重量:%d,总价值:%d\n",RealWeight,TotalPrice);printf("退出本次测试请按0!\n");scanf("%d",&GoBack);}while(GoBack!=0);return wp;}void main(){int InputWay,TotalNum,i,TotalWeight,RealWeight,Goon,TotalPrice;Project *Array;FILE *fp;do{printf("请选择数据录入方式!\n");printf(" 1.文件读入\n");printf(" 2.键盘输入\n");scanf("%d",&InputWay);switch(InputWay){case 1:printf("请输入背包最大容量:");scanf("%d",&TotalWeight);fp=fopen("data.txt","r");fscanf(fp,"%d\n",&TotalNum);if((Array=(Project*)malloc(TotalNum*sizeof(Project)))==NULL){printf("内存已满,申请空间失败!\n");exit(1);}else{for(i=0;i<TotalNum;i++){fscanf(fp,"%s %d %d\n",&Array[i].name,&Array[i].price,&Array[i].weight);}}fclose(fp);Array=Input(Array,TotalNum,TotalWeight);break;case 2:printf("请输入物品数量及背包容量\n");scanf("%d%d",&TotalNum,&TotalWeight);if((Array=(Project*)malloc(TotalNum*sizeof(Project)))==NULL){printf("内存已满,申请空间失败!\n");exit(1);}else{printf("请输入:物品名价格重量\n");for(i=0;i<TotalNum;i++)scanf("%s%d%d",&Array[i].name,&Array[i].price,&Array[i].weight);}Array=Input(Array,TotalNum,TotalWeight);break;default:{printf("输入错误!\n");exit(1);}}printf("继续其他数据测试请按1\n");scanf("%d",&Goon);}while(Goon==1);delete Array;}。

背包问题的目标函数和贪心算法最优化量度标准

背包问题的目标函数和贪心算法最优化量度标准

背包问题的目标函数和贪心算法最优化量度标准
贪心算法是一种较为简单的解决给定问题的优化方法,其具有从利益最优点出发搜索解决方案,实现最优化的优点。

常用在求解最大化或最小化某固定目标函数的问题上。

利用贪心算法可以轻松求解背包问题。

背包问题是指在满足总重量不超过某一给定值的条件下,背包问题最多能容纳多少物体,以及如何选择这些物体,使满足给定总重量的情况下的总价值最大化。

背包问题的目标函数一般可以设计成最大化总价值函数和最大化总重量函数。

在背包问题中,贪心算法最优化量度标准一般是以价值/重量比作为最佳选择标准,从而让计算机可以快速地预测出价值/重量比最大的物品,以达到最优化的效果。

贪心算法的最优化量度标准的例子是在背包问题中,我们可以把所有物品按其价值/重量比从大到小排列,然后依次将相应的物品装入背包,直至背包满或剩余的物品的价值/重量比不高于已经放入背包中的物品的价值/重量比。

因此,贪心算法在背包问题中的优化量度标准一般是以价值/重量比作为最佳选择标准,从而让计算机可以快速地预测并实现最优化的效果。

而该目标函数则是在满足总重量不超过某一给定值的条件下,最多能容纳多少物体,以及如何选择这些物体,使满足给定总重量的情况下的总价值最大化。

背包问题的贪心算法

背包问题的贪心算法

Wi Xi
16.5 20 20 20
Vi X i
24.25 28.2 31 31.5
先检验这四个为可行解*,即满足约束条件(4.2.2),(4.2.3).再比 较目标函数值,∑vixi .知④组解效益值最大.该组解是背包问题的最 优解。(见定理4.2)
6
例4.4 n=3,c=20, (V1,V2,V3) (25, 24,15) (W1,W2,W3) (18,15,10)
7
,且物品2的24/15 = v2/w2 较物品3的15/10= v3/w3效益值高。按 此选择策略,得②即(1, 2/15, 0),∑vixi=28.2 .此解是一个次优解。 显然,按物品效益值的非增次序装包不能得最优解。
原因:背包可用容量消耗过快。
(2)以容量作为量度。即按物品重量的非降次序将物
—选取最优的量度标准实为用贪心方法求解问题的核心.
16
4.3 贪心算法的基本要素
1.贪心选择性质
所谓贪心选择性质是指所求问题的整体最优解可以 通过一系列局部最优的选择,即贪心选择来达到。这 是贪心算法可行的第一个基本要素,也是贪心算法与 动态规划算法的主要区别。
动态规划算法通常以自底向上的方式解各子问 题,而贪心算法则通常以自顶向下的方式进行,以迭 代的方式作出相继的贪心选择,每作一次贪心选择就 将所求问题简化为规模更小的子问题。
品装包。如例4.4中的解③(让背包尽可能慢被消耗)
排序 : (w3,w2,w1)= (10,15,18)
(V3,V2,V1) (15, 24, 25)
V3=15,x3=1,w3=10,背包剩余C-10=10;物品2有次大重量(w2=15), 但包装不下。使用x2=2/3,刚好装满背包且物品2装入2/3与物品1 装入5/9的容量均为10个单位。但前者的效益值24×2/3=16 >后者
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

算法设计与分析实验报告题目:贪心算法背包问题专业:JA V A技术xx——xxx班学号:姓名:指导老师:实验三:贪心算法背包问题一、实验目的与要求1、掌握背包问题的算法2、初步掌握贪心算法二、实验题:问题描述:与0-1背包问题相似,给定n种物品和一个背包。

物品i的重量是wi,其价值为vi,背包的容量为c。

与0-1背包问题不同的是,在选择物品i装入背包时,背包问题的解决可以选择物品i的一部分,而不一定要全部装入背包,1< i < n。

三、实验代码import java.awt.*;import java.awt.event.*;import javax.swing.*;public class er extends JFrame {private static final long serialVersionUID = -1508220487443708466L;private static final int width = 360;// 面板的宽度private static final int height = 300;// 面板的高度public int M;public int[] w;public int[] p;public int length;er() {// 初始Frame参数设置this.setTitle("贪心算法");setDefaultCloseOperation(EXIT_ON_CLOSE);setSize(width, height);Container c = getContentPane();c.setLayout(new BoxLayout(c, BoxLayout.Y_AXIS));setLocation(350, 150);// 声明一些字体样式Font topF1 = new Font("宋体", Font.BOLD, 28);Font black15 = new Font("宋体", Font.PLAIN, 20);Font bold10 = new Font("宋体", Font.BOLD, 15);// 声明工具栏及属性设置JPanel barPanel = new JPanel();JMenuBar topBar = new JMenuBar();topBar.setLocation(1, 1);barPanel.add(topBar);// 面板1和顶部标签属性设置JPanel p1 = new JPanel();JLabel topLabel = new JLabel("背包问题");topLabel.setForeground(Color.blue);topLabel.setFont(topF1);p1.add(topLabel);// 中间面板和标签及输入框属性设置JPanel p2 = new JPanel();p2.setLayout(new BoxLayout(p2, BoxLayout.Y_AXIS)); JLabel wLabel = new JLabel("请输入重量:");JLabel pLabel = new JLabel("请输入效益:");wLabel.setFont(black15);pLabel.setFont(black15);//final JTextField wText = new JTextField(8);final JTextField pText = new JTextField(8);// wText.setText("10,8,7,5,9,6");// pText.setText("15,14,7,10,17,7");p2.add(wLabel);p2.add(wText);p2.add(pLabel);p2.add(pText);//// 中下部面板和标签属性设置JPanel p3 = new JPanel();JLabel bottomLabel = new JLabel(" 注意:数据输入时请添加分割符','"); bottomLabel.setFont(bold10);bottomLabel.setForeground(Color.red);bottomLabel.setHorizontalAlignment(SwingConstants.RIGHT); p3.add(bottomLabel);//JPanel p5 = new JPanel();p5.setLayout(new BoxLayout(p5, BoxLayout.Y_AXIS)); JLabel mLabel = new JLabel("请输入背包总重量:"); mLabel.setFont(black15);final JTextField mText = new JTextField(8);p5.add(mLabel);p5.add(mText);// 面板和按钮的设置JPanel p4 = new JPanel();JButton submit = new JButton("确定");submit.addActionListener(new ActionListener() {public void actionPerformed(ActionEvent e) {String s1 = pText.getText(); //效益String s2 = wText.getText(); //重量String s3 = mText.getText(); //背包System.out.println(s1);System.out.println(s2);System.out.println(s3);String s1Copy,s2Copy,s3Copy;s1Copy = s1;s2Copy = s2;s3Copy = s3;s1Copy = s1Copy.replaceAll(",","");s2Copy = s2Copy.replaceAll(",","");s3Copy = s3Copy.replaceAll(",","");System.out.println(s1Copy);System.out.println(s2Copy);System.out.println(s3Copy);try{String[] temp = s1.split(",");// 按照','分割字符串p = new int[temp.length];for (int i = 0; i < temp.length; i++)p[i] = Integer.parseInt(temp[i]);//temp = s2.split(",");w = new int[temp.length];for (int i = 0; i < temp.length; i++) w[i] = Integer.parseInt(temp[i]);//if (w.length == p.length){length = w.length;}else {JOptionPane.showMessageDialog(null, "长度不等,请检查后重新输入!"); }M = Integer.parseInt(s3);}catch(NumberFormatException e2){e2.printStackTrace();try {if (s2.equals("")){JOptionPane.showMessageDialog(null, "重量不能为空!");return;}else{if (s1.equals("")){JOptionPane.showMessageDialog(null, "效益值不能为空!");return;}else{if (s3.equals(""))JOptionPane.showMessageDialog(null, "总重量不能为空!");return;}}} catch (Exception e3) {// TODO: handle exception}}//可以执行贪心算法了int [] wCopy = new int [w.length];int [] pCopy = new int [w.length];float temp2;int temp1;float totalx=0;float [] x = new float [w.length];//效益和重量的比值float [] n =new float[w.length];//记录个数float [] nCopy = new float[w.length];for(int i=0;i<w.length;i++){wCopy [i] = w[i];pCopy [i] = p[i];}for (int i=0;i<w.length;i++)x[i] = (float) ((p[i]*1.0)/w[i]);for(int i= 0;i<w.length;i++)for(int j=i+1;j<w.length;j++){if(x[i] < x[j]){temp2 = x[j];x[j] = x[i];x[i] =temp2;temp1 = p[j];p[j] = p[i];p[i] = temp1;temp1 = w[j];w[j] = w[i];w[i] = temp1;}}//效益重量比值排序Backpack b = new Backpack(M,w,p,n);for(int i=0;i<w.length;i++)for(int j=0;j<w.length;j++){if(wCopy[i]==w[j] && pCopy[i]==p[j]){nCopy[i] = b.n[i];}}for(int j = 0;j<w.length;j++)totalx=totalx+n[j]*p[j];ShowResult s = new ShowResult(p,w,length,n,totalx);}//actionPerformed});p4.add(submit);// p4.add(eButton);//JPanel topPanel = new JPanel();topPanel.setLayout(new BoxLayout(topPanel, BoxLayout.Y_AXIS));topPanel.add(p1);topPanel.add(p2);topPanel.add(p5);topPanel.add(p3);topPanel.add(p4);c.add(barPanel);c.add(topPanel);setVisible(true);}// 构造方法public static void main(String [] args){er g = new er();}//end main}class Backpack{private int capacity;int length ;//数组元素个数float [] n;public Backpack(int M,int [] w,int [] p,float [] n){ this.capacity = M;this.length = w.length;this.n = n;int i;for(i = 0;i<length;i++){if(w[i]>capacity) break;else {n[i] = 1;capacity = capacity-w[i];}}//end forif(i<length)n[i] = (float) ((capacity*1.0)/w[i]);}//构造方法}class ShowResult extends JFrame{private static final long serialVersionUID = 6592095135353992914L; ShowResult(int [] p,int [] w,int length,float [] n,float totalx){ setDefaultCloseOperation(DISPOSE_ON_CLOSE);Container c = getContentPane();c.setLayout(new BoxLayout(c,BoxLayout.Y_AXIS));setSize(360,300);setLocation(400,200);setTitle("最后结果");java.text.DecimalFormat df=new java.text.DecimalFormat("#.##");String ps = null;String ws = null;String ns = null;ps = Integer.toString(p[0])+",";ws = Integer.toString(w[0])+",";ns = Float.toString(n[0])+"个,";//格式化小数部分for(int j =0;j<n.length;j++){n[j] = Float.parseFloat(df.format(n[j]));}for(int i =1;i<w.length;i++){ps = ps+Integer.toString(p[i])+",";ws = ws+Integer.toString(w[i])+",";ns = ns+Float.toString(n[i])+"个,";}JPanel p1 = new JPanel();p1.setLayout(new BoxLayout(p1,BoxLayout.Y_AXIS));JLabel wLabel = new JLabel("重量值分别是:");JLabel pLabel = new JLabel("效益值分别是:");JLabel nLabel = new JLabel("个数分别是:");JLabel tLabel = new JLabel("总效益是:");JTextField pt = new JTextField(8);pt.setText(ps);pt.setEditable(false);JTextField wt = new JTextField(8);wt.setEditable(false);wt.setText(ws);JTextField nt = new JTextField(8);nt.setEditable(false);nt.setText(ns);JTextField tt = new JTextField(8);tt.setEditable(false);tt.setText(Float.toString(totalx));p1.add(pLabel);p1.add(pt);p1.add(wLabel);p1.add(wt);p1.add(nLabel);p1.add(nt);p1.add(tLabel);p1.add(tt);c.add(p1);setVisible(true);}}四、实验结果。

相关文档
最新文档