实验五 背包问题和带时限的作业排序
一、实验名称:背包问题和带时限的作业排序
二、实验目的:掌握贪心算法解决问题的思想和一般过程,学会使用贪心算法解决实际问题。
三、实验内容
实验问题和程序运行结果:
第一部分 背包问题
完善下列程序,并回答问题。
1 #include<iostream.h> 2 #define KSIZE 30 3 4 template<class T> 5 class Knapsack 6 { 7 public: 8 Knapsack(int mSize, float cap, float *wei, T *prof); 9 void GreedyKnapsack(float *x); 10 void print(); 11 private: 12 float m, *w; 13 T *p; 14 int n; 15 }; 16 17 template<class T> 18 Knapsack<T>::Knapsack(int mSize, float cap, float *wei, T *prof) 19 { 20 m = cap; 21 n = mSize; 22 w = new float[KSIZE]; 23 p = new T[KSIZE]; 24 for(int i = 0; i<n;i++){ 25 w[i] = wei[i]; 26 p[i] = prof[i]; 27 } 28 }; 29 30 template<class T> 31 void Knapsack<T>::print(){ 32 cout<<"--背包--"<<endl; 33 cout<<"重量数组:"; 34 for(int i = 0; i < n ; i ++){ cout<<" "<<w[i];} 35 cout<<endl<<"收益数组:"; 36 for( i = 0; i < n ; i ++){ cout<<" "<<p[i];} 37 cout<<endl; 38 }; 39 40 template<class T> 41 void Knapsack<T>::GreedyKnapsack(float *x){ 42 //学生自己完成, 43 //注意:需要自己编写前置条件,即:w[i]已按p[i]/w[i]的非增次序排列。 44 } 45 46 47 void main() 48 { 49 int size = 3; 50 float wei[KSIZE] = {18,15,10}; 51 float prof[KSIZE] = {25,24,15}; 52 float M =20; 53 Knapsack<float> k(size,M,wei,prof); 54 float x [KSIZE]; 55 k.print(); 56 k.GreedyKnapsack(x); 57 cout<<"最终的解数组"<<endl; 58 for(int i = 0; i < size; i++) cout<<" "<<x[i]; 59 cout<<endl; 60 }
补充后的程序:
1 #include<iostream.h> 2 #define KSIZE 30 3 4 template<class T> 5 class Knapsack 6 { 7 public: 8 Knapsack(int mSize, float cap, float *wei, T *prof); 9 void GreedyKnapsack(float *x); 10 void print(); 11 private: 12 float m, *w; 13 T *p; 14 int n; 15 }; 16 17 template<class T> 18 Knapsack<T>::Knapsack(int mSize, float cap, float *wei, T *prof) 19 { 20 m = cap; 21 n = mSize; 22 w = new float[KSIZE]; 23 p = new T[KSIZE]; 24 for(int i = 0; i<n;i++){ 25 w[i] = wei[i]; 26 p[i] = prof[i]; 27 } 28 }; 29 30 template<class T> 31 void Knapsack<T>::print(){ 32 cout<<"--背包--"<<endl; 33 cout<<"重量数组:"; 34 for(int i = 0; i < n ; i ++){ cout<<" "<<w[i];} 35 cout<<endl<<"收益数组:"; 36 for(int i = 0; i < n ; i ++){ cout<<" "<<p[i];} 37 cout<<endl; 38 }; 39 40 template<class T> 41 void Knapsack<T>::GreedyKnapsack(float *x){ 42 //学生自己完成, 43 //注意:需要自己编写前置条件,即:w[i]已按p[i]/w[i]的非增次序排列。 44 float u=m; 45 for(int i=0;i<n;i++){ 46 x[i]=0; 47 } 48 49 for(int i=0;i<n;i++){ 50 if(w[i]>u){ 51 break; 52 } 53 x[i]=1.0; 54 u=u-w[i]; 55 } 56 int i=0; 57 if(i<n){ 58 x[i]=u/w[i]; 59 } 60 } 61 62 63 int main() 64 { 65 int size = 3; 66 float wei[KSIZE] = {18,15,10}; 67 float prof[KSIZE] = {25,24,15}; 68 float M =20; 69 Knapsack<float> k(size,M,wei,prof); 70 float x [KSIZE]; 71 k.print(); 72 k.GreedyKnapsack(x); 73 cout<<"最终的解数组"<<endl; 74 for(int i = 0; i < size; i++) cout<<" "<<x[i]; 75 cout<<endl; 76 }
1. 分析103页程序6-1,画出流程图。
2. 分析Knapsack类,私有变量,分别表示的含义为:
3. 分析greedyKnapsack程序,画出该算法的流程图。
4. 当背包为:
W |
18 |
15 |
10 |
P |
25 |
24 |
15 |
M = 20 时:
解数组的输出为:
5. 完善greedyKnapsack程序,使得输出解数组与原顺序相同。当背包的值为:
W |
8 |
2 |
25 |
7 |
4 |
7 |
4 |
P |
10 |
5 |
11 |
15 |
3 |
13 |
1 |
M = 45时,解数组的输出为:
第二部分 带时限的作业排序算法
完善下列程序,并回答问题。
1 #include<iostream.h> 2 3 int JS(int *d,int *x,int n){ 4 //学生完成部分 5 } 6 7 void main(){ 8 int n = 5; 9 int *x = new int[n]; 10 int d[] = {2,1,2,4,3}; 11 int p[] = {100,10,15,27,9}; 12 13 cout<<endl<<"输入数据:"; 14 for(int i = 0; i<n ;i++) {cout<<" "<<i<<".<"<<d[i]<<","<<p[i]<<">";} 15 16 int result; 17 for( i=0;i<n;i++) 18 for(int j=i+1;j<n;j++) 19 { 20 if(p[i]<p[j]) 21 { 22 int t = p[i]; p[i]=p[j]; p[j]=t; 23 t = d[i]; d[i]=d[j]; d[j]=t; 24 } 25 } 26 cout<<endl<<"排序以后的结果:"; 27 for(i = 0; i<n ;i++) {cout<<" "<<i<<".<"<<d[i]<<","<<p[i]<<">";} 28 29 result = JS(d,x,n); 30 cout<<endl<<"输出结果:"; 31 for(i = 0; i<result+1 ;i++) {cout<<" "<<x[i];} 32 }
分析程序6-4,画出该算法的流程图。
- 分析程序6-4,分别说明变量d、x、n、k、r的含义。
- 当作业序列为:
时限 |
2 |
1 |
2 |
4 |
3 |
价值 |
100 |
10 |
15 |
27 |
9 |
贪心算法的最终结果为:
- 通过分析,或者在程序中增加适当的输入语句。以上题为例,给出在贪心算法的每一步解空间X的状态,以及j、r、k的值。
四、实验小结和心得: