zoukankan      html  css  js  c++  java
  • 背包问题填表法

    假设背包容量为W,物体数目为n,填表法得到的时间复杂度和空间复杂度均为O(nW)。

    #include <iostream>
    #include <ctime>
    #include <string>
    #include <vector>
    #include <fstream>
    #include <sstream>
    using namespace std;
    //迭代的方法,时间复杂度(nW)
    /***************物体属性******************/
    class item
    {
    public:
        long value;
        int weight;
        item() : value(0), weight(0){}
    };
    
    class Knapsack
    {
    public:
    /***************构造函数读取数据*********************/
        Knapsack()
        {
            ifstream fin("4.txt");
            string line;
            stringstream stream;
            if(getline(fin, line))
            {
                stream.clear();
                stream << line;
                stream >> knapsack_size;
                stream >> num_of_items;
            }
            int cnt = 1;
            init_items();
            while(getline(fin, line))
            {
                long _value;
                int _weight;
                stream.clear();
                stream << line;
                stream >> _value;
                stream >> _weight;
                items[cnt].value = _value;
                items[cnt].weight = _weight;
                cnt++;
            }
        }
    
        void init_items()
        {
            items.resize(num_of_items+1);
            Avalue.resize(num_of_items+1);
            for(int i = 0; i <= num_of_items; i++)
            {    
                Avalue[i].resize(knapsack_size+1);
            }
        }
        /***************返回最大值**************/
        long max(long a, long b)
        {
            return a > b ? a : b;        
        }
    /***************遍历填表*****************/
        void sack()
        {    
            for(int k = 0; k <= knapsack_size; k++)        
            {
                Avalue[0][k] = 0;  //初始化边界
                
            }
            for(int i = 1; i <= num_of_items; i++)  //填表
            {
                for(int x = 0; x <= knapsack_size; x++)
                {
                    if(x-items[i].weight >= 0)
                    {
                        Avalue[i][x] = max(Avalue[i-1][x], Avalue[i-1][x-items[i].weight] + items[i].value);
                    } else {
                        Avalue[i][x] = Avalue[i-1][x];
                    }
                }
            }
        }
    /****************根据填好的表重构最优解的组成元素*************/
        void reconstruct()
        {
            int temp = Avalue[num_of_items][knapsack_size];
            int i = num_of_items;
            int x = knapsack_size;
            while( i > 0)
            {
    //            temp = Avalue[i][x];
                if( (temp > Avalue[i-1][x]) )
                {
                    cout << "(" << x << "," << i << ")" << temp <<  endl;
                    set.push_back(i);
                    x = x - items[i].weight;
                    i = i-1;
                } else  {
                    //set.push_back(i-1);
                    i = i - 1;
                }
                temp = Avalue[i][x]; 
                cout << "(" << x << "," << i << ")" << temp  << endl;
            }
            
        }
    
    /**********打印看输出*********/
        void print()
        {
            ofstream fout;
            fout.open("out1.txt");
            for(int j = knapsack_size; j >= 0; j--)
            {
                for(int i = 0; i <= num_of_items; i++)        
                {
                    fout << "[w,i] [" << j << "," << i << "]" << Avalue[i][j] << " ;";
                }
                fout << endl;
            }
        }
        
        void write()
        {
            ofstream fout;
            fout.open("out2.txt");
            for(int i = 0; i < set.size(); i++)
            {
                fout << set[i] << " ";    
            }
            cout << endl;
        }
        
    public:
        int knapsack_size;   //背包容量
        int num_of_items;    //物体数目
        vector<item> items;  //物体集合
        vector< vector<long> > Avalue; //表的数据
        vector<int> set; //存储最优解
    };
    
    int main()
    {
        clock_t start, end;
        start = clock();
        Knapsack knapsack;
        knapsack.sack();
        knapsack.print();
        knapsack.reconstruct();
        knapsack.print();
        knapsack.write();
        end = clock();
        cout << "running time:" << (double)(end-start)/CLOCKS_PER_SEC << "s" << endl;
        return 0;
    }
    The Safest Way to Get what you Want is to Try and Deserve What you Want.
  • 相关阅读:
    Caliburn micro 学习笔记...
    First steps with Caliburn Micro in Windows Phone 8 系列文章
    WPF and Silverlight.ComboBox 如何通过 Binding IsDropDownOpen 实现下拉菜单展开
    http各个状态码的详解
    点阵字库产生的原理
    Windows 服务调试方法(基于.net framwork4.6)
    关于.net Core 笔记
    JS+ google.maps.api 实现基本的导航功能
    C# 遍历控件检查是否有被选中的项(通用)
    C#编程习惯
  • 原文地址:https://www.cnblogs.com/Shinered/p/9195895.html
Copyright © 2011-2022 走看看