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>
 7 using namespace std;
 8 struct object
 9 {
10     int no;
11     double weight;
12     double value;
13     double average;
14 };
15 bool cmp(const object &x, const object &y)
16 {
17     return x.average > y.average;//从小到大排<,若要从大到小排则>
18 }
19 void greedySelector(int m,int W,int solution[],struct object object[]){
20     int i = 0,V = 0,j = 0;
21     while(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 }
39 int 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));
47     int m,i,j,t;
48     double W;
49     double 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);
53     if(!fout1){
54         cerr<<"Can not open file 'backpack-object.txt' "<<endl;
55         return -1;
56     }
57     fout1.setf(ios_base::fixed,ios_base::floatfield);       //防止输出的数字使用科学计数法
58     fout2.open("backpack-weight.txt",ios::app);
59     if(!fout2){
60         cerr<<"Can not open file 'backpack-weight.txt' "<<endl;
61         return -1;
62     }
63     fout2.setf(ios_base::fixed,ios_base::floatfield);       //防止输出的数字使用科学计数法
64     for (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 << ",";
71         int solution[m];
72         object object[m];
73         for( i = 0;i < m;i++)
74         {
75             object[i].no = i + 1;
76             object[i].value = 1 + rand()%10000;
77             object[i].weight = 1 + rand()%10000;
78             object[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;
94     return 0;
95 }

 程序设计思路:

① 数据结构:结构体中存储物品序号、物品的重量、物品的价值、物品的单位重量价值;

② 利用C++自带的sort函数对结构体按照物品的单位重量价值进行降序排列;

③ 从排序处于首位的物品开始选择直到无法完整装入背包的物品,将其部分装入背包以填满背包的总重量,从而求得价值最高的选择方案。

时间复杂性分析:

首先,需要对输入的物品单位重量价值进行非减序排序,需要用O(nlogn)的时间。其次,当输入的物品已按物品单位重量价值非减序排列,算法只需θ(n)的时间选择n个物品,使算法可以求得价值最高的选择方案。

生成的数据可导入EXCEL中进行数据分析生成分析图表。

posted @ 2019-11-04 11:05  Weisswire  阅读(1644)  评论(0编辑  收藏  举报