C++ C+中的装箱实现+;使用STL

C++ C+中的装箱实现+;使用STL,c++,stl,bin-packing,C++,Stl,Bin Packing,这是我第一次使用这个网站,所以很抱歉任何格式错误或奇怪的公式,我会尽力遵守这个网站上的规则,但我可能会做一些错误的开始 我现在正在使用STL容器在C++中实现一些不同的装箱算法。在当前的代码中,我仍然有一些需要修复的逻辑错误,但是这个问题更多的是关于程序的结构。对于如何构造程序,以尽量减少逻辑错误的数量,并使其尽可能易于阅读,我不想再有任何意见。在它的当前状态下,我只是觉得这不是最好的方法,但我现在真的看不到任何其他方法来编写代码 该问题是一个动态在线装箱问题。这是动态的,因为物品在离开指定的垃

这是我第一次使用这个网站,所以很抱歉任何格式错误或奇怪的公式,我会尽力遵守这个网站上的规则,但我可能会做一些错误的开始

我现在正在使用STL容器在C++中实现一些不同的装箱算法。在当前的代码中,我仍然有一些需要修复的逻辑错误,但是这个问题更多的是关于程序的结构。对于如何构造程序,以尽量减少逻辑错误的数量,并使其尽可能易于阅读,我不想再有任何意见。在它的当前状态下,我只是觉得这不是最好的方法,但我现在真的看不到任何其他方法来编写代码

该问题是一个动态在线装箱问题。这是动态的,因为物品在离开指定的垃圾箱之前有一段任意的时间。

简而言之,我的问题是:
一个装箱算法的结构如何在C++中找到? STL容器是使实现能够处理任意长度输入的好工具吗?
我应该如何以良好、易于阅读和实现的方式处理容器

关于我自己的代码的一些想法:
使用类可以很好地区分处理不同箱子的列表和这些箱子中的项目列表。
使实施尽可能有效。
易于使用大量不同的数据长度和文件进行基准测试

#include <iostream>
#include <fstream>
#include <list>
#include <queue>
#include <string>
#include <vector>

using namespace std;

struct type_item {
    int size;
    int life;
    bool operator < (const type_item& input)
    {
        return size < input.size;
    }
};

class Class_bin {
    double load;
    list<type_item> contents;
    list<type_item>::iterator i;
public:
    Class_bin ();
    bool operator < (Class_bin);
    bool full (type_item);
    void push_bin (type_item);
    double check_load ();
    void check_dead ();
    void print_bin ();
};

Class_bin::Class_bin () {
    load=0.0;
}

bool Class_bin::operator < (Class_bin input){
    return load < input.load;
}

bool Class_bin::full (type_item input) {
    if (load+(1.0/(double) input.size)>1) {
        return false;
    }
    else {
        return true;
    }
}

void Class_bin::push_bin (type_item input) {
    int sum=0;

    contents.push_back(input);
    for (i=contents.begin(); i!=contents.end(); ++i) {
        sum+=i->size;
    }
    load+=1.0/(double) sum;
}

double Class_bin::check_load () {
    return load;
}

void Class_bin::check_dead () {
    for (i=contents.begin(); i!=contents.end(); ++i) {
        i->life--;
        if (i->life==0) {
            contents.erase(i);
        }
    }
}

void Class_bin::print_bin () {
    for (i=contents.begin (); i!=contents.end (); ++i) {
        cout << i->size << "  ";
    }
}


class Class_list_of_bins {
    list<Class_bin> list_of_bins;
    list<Class_bin>::iterator i;
public:

    void push_list (type_item);
    void sort_list ();
    void check_dead ();
    void print_list ();
private:
    Class_bin new_bin (type_item);
    bool comparator (type_item, type_item);
};

Class_bin Class_list_of_bins::new_bin (type_item input) {
    Class_bin temp;

    temp.push_bin (input);

    return temp;
}

void Class_list_of_bins::push_list (type_item input) {
    if (list_of_bins.empty ()) {
        list_of_bins.push_front (new_bin(input));
        return;
    }
    for (i=list_of_bins.begin (); i!=list_of_bins.end (); ++i) {
        if (!i->full (input)) {
            i->push_bin (input);
            return;
        }
    }
    list_of_bins.push_front (new_bin(input));
}

void Class_list_of_bins::sort_list () {
    list_of_bins.sort();
}

void Class_list_of_bins::check_dead () {
    for (i=list_of_bins.begin (); i !=list_of_bins.end (); ++i) {
        i->check_dead ();
    }
}

void Class_list_of_bins::print_list () {
    for (i=list_of_bins.begin (); i!=list_of_bins.end (); ++i) {
        i->print_bin ();
        cout << "\n";
    }
}


int main () {
    int i, number_of_items;

    type_item buffer;
    Class_list_of_bins bins;

    queue<type_item> input;

    string filename;
    fstream file;


    cout << "Input file name: ";
    cin >> filename;
    cout << endl;

    file.open (filename.c_str(), ios::in);

    file >> number_of_items;

    for (i=0; i<number_of_items; ++i) {
        file >> buffer.size;
        file >> buffer.life;
        input.push (buffer);
    }

    file.close ();

    while (!input.empty ()) {
        buffer=input.front ();
        input.pop ();
        bins.push_list (buffer);
    }

    bins.print_list ();

    return 0;
}
#包括
#包括
#包括
#包括
#包括
#包括
使用名称空间std;
结构类型\u项{
整数大小;
智力生活;
布尔运算符<(常数类型\项目和输入)
{
返回大小1){
返回false;
}
否则{
返回true;
}
}
作废类\仓位::推送\仓位(类型\项目输入){
整数和=0;
内容。推回(输入);
for(i=contents.begin();i!=contents.end();+i){
总和+=i->大小;
}
荷载+=1.0/(双)和;
}
双类\u bin::检查\u加载(){
返回载荷;
}
void Class_bin::check_dead(){
for(i=contents.begin();i!=contents.end();+i){
我->生活--;
如果(i->life==0){
内容。删除(i);
}
}
}
void类_-bin::print_-bin(){
对于(i=contents.begin();i!=contents.end();+i){
cout size full(输入)){
i->push_bin(输入);
返回;
}
}
列出所有垃圾箱。向前推(新垃圾箱(输入));
}
void Class\u list\u of\u bin::sort\u list(){
列出所有容器。排序();
}
无效类\u列表\u垃圾箱::检查\u死亡(){
for(i=list_of_bins.begin();i!=list_of_bins.end();++i){
i->check_dead();
}
}
无效类\u列表\u的\u箱::打印\u列表(){
for(i=list_of_bins.begin();i!=list_of_bins.end();++i){
i->print_bin();
cout文件名;
cout>项目的数量;
对于(i=0;i>buffer.size;
文件>>buffer.life;
input.push(缓冲区);
}
file.close();
而(!input.empty()){
buffer=input.front();
input.pop();
箱子推送列表(缓冲区);
}
bins.print_list();
返回0;
}
请注意,这只是我代码的快照,尚未正常运行

不要用不相关的闲聊来搅乱这篇文章,我只想感谢贡献者,我将回顾我的代码,并希望能够更好地构建我的编程

一些想法:

你的名字有点乱

  • 你有很多名为input的参数,这毫无意义
  • 我希望full()检查它是否已满,而不是它是否可以容纳其他内容
  • 我不认为push_bin推垃圾桶
  • check\u dead修改对象(我希望有一个名为check\u*的东西,告诉我有关对象的一些信息)
  • 不要将类和类型之类的东西放在类和类型的名称中
  • 类\u列表\u中的\u容器似乎描述了里面的东西,而不是对象是什么
  • 推送列表不会推送列表
  • 不要将_list之类的东西附加到list类中的每个方法,如果它是list对象,我们已经知道它是list方法
  • 考虑到生命和负载的参数,我对你在做什么感到困惑。我所熟悉的箱子包装问题只是大小不同。我猜有些东西是从箱子里拿出来的,因此就消失了

    关于你的课程的进一步思考

    类\u-list\u-of-u-bin向外部世界暴露了太多的自身。外部世界为什么要检查\u-dead或对\u-list进行排序?这是无人问津的事情,但对象本身。您应该在该类上使用的公共方法应该是 *将项目添加到回收箱集合中 *打印溶液 *迈向未来的第一步

    list<Class_bin>::iterator i;
    
    一些简要说明:

    • 在您的代码中,您反复将int大小转换为float,这不是一个好主意
    • 您将注意到,与单个项相关的逻辑现在包含在项本身中。其他对象只能看到对它们重要的内容、所需的大小以及该对象是否仍处于活动状态
    • 我没有包含任何关于排序的内容,因为我不清楚在第一次拟合算法中这是为了什么
    装箱算法的结构如何在C++中找到? 好吧,你最好
    class Item
    {
         Item(Istream & input)
         {
             read input description of item
         }
    
         double size_needed() { return actual size required (out of 1) for this item)
         bool alive() { return true if object is still alive}
         void do_timestep() { decrement life }
         void print() { print something }
    }
    
    class Bin
    {
        vector of Items
        double remaining_space
    
    
        bool can_add(Item item) { return true if we have enough space}
        void add(Item item) {add item to vector of items, update remaining space}
        void do_timestep() {call do_timestep() and all Items, remove all items which indicate they are dead, updating remaining_space as you go}
        void print { print all the contents }
    }
    
    class BinCollection
    {
       void do_timestep { call do_timestep on all of the bins }
       void add(item item) { find first bin for which can_add return true, then add it, create a new bin if neccessary }
       void print() { print all the bins }
    }
    
    struct type_item {
        int size;
        int life;
        bool operator < (const type_item& input)
        {
            return size < input.size;
        }
    };
    
    struct type_item {
        int size;
        int life;
        struct SizeIsLess {
          // Note this becomes a function object, which makes it easy to use with
          // STL algorithms.
          bool operator() (const type_item& lhs, const type_item& rhs)
          {
              return lhs.size < rhs.size;
          }
        }
    };
    
    vector<type_item> items;
    std::sort(items.begin, items.end(), type_item::SizeIsLess);
    
    class Class_bin {
        double load;
        list<type_item> contents;
        list<type_item>::iterator i;
    public:
        Class_bin ();
        bool operator < (Class_bin);
        bool full (type_item);
        void push_bin (type_item);
        double check_load ();
        void check_dead ();
        void print_bin ();
    };
    
    class Class_list_of_bins {
        list<Class_bin> list_of_bins;
        list<Class_bin>::iterator i;
    public:
    
        void push_list (type_item);
        void sort_list ();
        void check_dead ();
        void print_list ();
    private:
        Class_bin new_bin (type_item);
        bool comparator (type_item, type_item);
    };
    
    struct bin {
      double load;  // sum of item sizes.
      std::list<type_item> items;
    
      bin() : load(0) { }
    };
    
    // Returns true if the bin can fit the item passed to the constructor.
    struct bin_can_fit {
      bin_can_fit(type_item &item) : item_(item) { }
      bool operator()(const bin &b) {
        return item_.size < b.free_space;
      }
     private:
      type_item item_;
    };
    
    // ItemIter is an iterator over the items.
    // BinOutputIter is an output iterator we can use to put bins.
    template <ItemIter, BinOutputIter>
    void bin_pack_first_fit(ItemIter curr, ItemIter end, BinOutputIter output_bins) {
      std::vector<bin> bins;  // Create a local bin container, to simplify life.
      for (; curr != end; ++curr) {
        // Use a helper predicate to check whether the bin can fit this item.
        // This is untested, but just for an idea.
        std::vector<bin>::iterator bin_it =
            std::find_if(bins.begin(), bins.end(), bin_can_fit(*curr));
        if (bin_it == bins.end()) {
          // Did not find a bin with enough space, add a new bin.
          bins.push_back(bin);
          // push_back invalidates iterators, so reassign bin_it to the last item.
          bin_it = std::advance(bins.begin(), bins.size() - 1);
        }
    
        // bin_it now points to the bin to put the item in.
        bin_it->items.push_back(*curr);
        bin_it->load += curr.size();
      }
      std::copy(bins.begin(), bins.end(), output_bins);  // Apply our bins to the destination.
    }
    
    void main(int argc, char** argv) {
      std::vector<type_item> items;
      // ... fill items
      std::vector<bin> bins;
      bin_pack_first_fit(items.begin(), items.end(), std::back_inserter(bins));
    }