zoukankan      html  css  js  c++  java
  • 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中进行数据分析生成分析图表。

  • 相关阅读:
    程序员面试笔试宝典学习记录(三)(数据库相关知识)
    程序员面试笔试宝典学习记录(二)(程序设计相关知识)
    程序员面试笔试宝典学习记录(一)(常见面试笔试题目)
    浮点型数据在内存中的存储【转】
    docker compose网络设置
    Docker的Ubuntu16.04容器如何汉化
    Docker的centos7容器中如何安装mongodb
    用Java代码实现拦截区域网数据包
    wireshark 抓包分析 TCPIP协议的握手
    如何通过代理方式访问网络
  • 原文地址:https://www.cnblogs.com/Jesse-Cavendish/p/11791050.html
Copyright © 2011-2022 走看看