(file) Return to acm2.cpp CVS log (file) (dir) Up to [RizwankCVS] / acm

Diff for /acm/acm2.cpp between version 1.1 and 1.16

version 1.1, 2005/02/16 07:00:56 version 1.16, 2005/02/17 09:40:09
Line 1 
Line 1 
   #include<stdlib.h>
   #include<iostream>
   #include<fstream>
   #include<string>
 #include <queue> #include <queue>
   #include <stack>
   #include <vector>
 #include <stdio.h> #include <stdio.h>
  
 // As per specification, the project has to be able to grow to an  using namespace std;
 // arbitrary amount of items. MAX_ITEMS describes the size of the  
 // appropriate arrays and must be changed at compile time.  //Rizwan Kassim - rizwank@geekymedia.com (c) rizwan kassim 2005
 // (dynamically created arrays had their pointers corrupted when  //for use exculsively in the UCLA ACM 2005 Feb. Competition.
 // their parent object was in the priority queue, so static sized  
 // arrays were used  //threading might be useful except for the fact that our target machine is likely to have a single processor
   // what about task limiting from SEAS?
   // actually sparc machines on ugrad  are multiple processor -- could I thread/fork the calculations? would overhead > savings
   // also if i was really stingy, I could revert to the arrays I had before, make them dynamic and create a copy ctor for key
   // of course, vector<bool> packs 8 bools in a byte, arrays dont
   
   typedef long ITEM_MASS;
   typedef long INDEX_TYPE;
  
 #define MAX_ITEMS 25  
  
 using namespace std; using namespace std;
  
Line 16 
Line 28 
 // * CLASS : item                                                                                                       * // * CLASS : item                                                                                                       *
 // * Container object with all the data for a particular item           * // * Container object with all the data for a particular item           *
 // ****************************************************************** // ******************************************************************
   
   //since items are no longer special in any way, I could actually just use a vector now!
   // would this be any faster?
   
 class item { class item {
 public: public:
         float getRatio();          ITEM_MASS getWeight();
         unsigned short getWeight();          void setData(ITEM_MASS);
     unsigned short getCost();  
         unsigned short getNumber();  
         void setData(unsigned short,unsigned short,unsigned short);  
 private: private:
         unsigned short weight;          ITEM_MASS weight;
         unsigned short cost;  
         float ratio;  
         unsigned short number;  
 }; };
  
 // ****************************************************************** // ******************************************************************
Line 52 
Line 62 
         void flagNext();         void flagNext();
         void addCurItem();         void addCurItem();
         bool doneItems();         bool doneItems();
         float getBound();          ITEM_MASS getBound();
         bool checkItem(unsigned short);          bool checkItem(INDEX_TYPE);
         unsigned short getWeight();          ITEM_MASS getWeight();
         unsigned short getValue();  
 private: private:
         void calcBound();         void calcBound();
         bool inserted[MAX_ITEMS];          vector<bool> inserted;
         unsigned short nextitem;          // replace with a vector! this allows us to remove MAX_ITEMS without the fussyness of copying the
         unsigned short cur_weight;          // contents of a pointer etc like before!
         unsigned short cur_value;          // bool inserted[MAX_ITEMS];
         float upper_bound;          INDEX_TYPE nextitem;
           ITEM_MASS cur_weight;
           ITEM_MASS upper_bound;
         backpack *myBackpack;         backpack *myBackpack;
 }; };
  
Line 72 
Line 83 
 // ****************************************************************** // ******************************************************************
 struct item_comparator { struct item_comparator {
         bool operator()( item left, item right ) const         bool operator()( item left, item right ) const
         { return ( left.getRatio() < right.getRatio() ) ; }  //      { return ( left.getRatio() < right.getRatio() ) ; }
   //      { return ( left.getWeight() < right.getWeight() ); }
           {return 0;}
           // larger boxes are preferable to smaller boxes
           // removes the need for sort at beginning.
           // this actually massively increases the time cost for my sample set. defaulting to dumb sort
 } ; } ;
  
 // ****************************************************************** // ******************************************************************
Line 90 
Line 106 
 // ****************************************************************** // ******************************************************************
 class backpack { class backpack {
 public: public:
         void initBackpack(unsigned short, unsigned short);          void initBackpack(INDEX_TYPE, ITEM_MASS);
         void putItem(unsigned short, unsigned short);          void changeBackpack(INDEX_TYPE);
           void putItem(ITEM_MASS);//, ITEM_MASS);
         void store_item_array();         void store_item_array();
         void branch_and_bound();          void branch_and_bound(int,ITEM_MASS);
         unsigned short get_totalItems();          ITEM_MASS get_totalItems();
         unsigned short get_maxWeight();          ITEM_MASS get_maxWeight();
         item get_Item(unsigned short);          item get_Item(INDEX_TYPE);
 private: private:
         priority_queue< item, vector<item> , item_comparator> item_queue;         priority_queue< item, vector<item> , item_comparator> item_queue;
         item *item_array;         item *item_array;
         priority_queue< key, vector<key>, key_comparator> key_queue;         priority_queue< key, vector<key>, key_comparator> key_queue;
         unsigned short totalItems;          INDEX_TYPE totalItems;
         unsigned short maxWeight;          ITEM_MASS maxWeight;
         long addnodeCount, worknodeCount;         long addnodeCount, worknodeCount;
 }; };
  
Line 117 
Line 134 
         this->myBackpack = theCaller;         this->myBackpack = theCaller;
         this->nextitem=0;         this->nextitem=0;
         this->cur_weight=0;         this->cur_weight=0;
         this->cur_value=0;  
         this->calcBound();         this->calcBound();
 } }
  
Line 127 
Line 143 
 // * as processed, then updates the bound.                                                      * // * as processed, then updates the bound.                                                      *
 // ****************************************************************** // ******************************************************************
 void key::flagNext(){ void key::flagNext(){
         this->inserted[this->nextitem]=0;  //      this->inserted[this->nextitem]= 0;
           this->inserted.push_back(0);
         nextitem++;         nextitem++;
         this->calcBound();         this->calcBound();
 } }
Line 139 
Line 156 
 // ****************************************************************** // ******************************************************************
 void key::addCurItem(){ void key::addCurItem(){
         nextitem--;         nextitem--;
         this->inserted[this->nextitem]=1;          this->inserted.push_back(1);
         this->cur_value  += (this->myBackpack->get_Item(this->nextitem)).getCost();  //      this->inserted[this->nextitem]=1;
         this->cur_weight += (this->myBackpack->get_Item(this->nextitem)).getWeight();         this->cur_weight += (this->myBackpack->get_Item(this->nextitem)).getWeight();
         nextitem++;         nextitem++;
         this->calcBound();         this->calcBound();
Line 158 
Line 175 
 // * FUNCTION : getBound                IN : CLASS key                                          * // * FUNCTION : getBound                IN : CLASS key                                          *
 // * Returns the bound.                                                                                         * // * Returns the bound.                                                                                         *
 // ****************************************************************** // ******************************************************************
 float key::getBound(){  ITEM_MASS key::getBound(){
         return this->upper_bound;         return this->upper_bound;
 } }
  
Line 169 
Line 186 
 // * If the weight is over max_weight, set the bound to 0                       * // * If the weight is over max_weight, set the bound to 0                       *
 // ****************************************************************** // ******************************************************************
 void key::calcBound(){ void key::calcBound(){
         float temp;          ITEM_MASS temp;
         if (this->doneItems()) {         if (this->doneItems()) {
                 temp = 0;                 temp = 0;
         }         }
         else {         else {
                 temp = (float)((this->myBackpack->get_maxWeight()) - cur_weight);                  temp = ((this->myBackpack->get_maxWeight()) - cur_weight);
                 temp = temp * (this->myBackpack->get_Item(this->nextitem)).getRatio();  
         }         }
         this->upper_bound = cur_value + temp;          this->upper_bound = cur_weight + temp;
  
         // What about if the bag is overloaded?         // What about if the bag is overloaded?
         if (this->cur_weight > this->myBackpack->get_maxWeight()){         if (this->cur_weight > this->myBackpack->get_maxWeight()){
Line 190 
Line 206 
 // * FUNCTION : checkItem               IN : CLASS key                                          * // * FUNCTION : checkItem               IN : CLASS key                                          *
 // * Checks if a given item is listed as inserted.                                      * // * Checks if a given item is listed as inserted.                                      *
 // ****************************************************************** // ******************************************************************
 bool key::checkItem(unsigned short num) {  bool key::checkItem(INDEX_TYPE num) {
         return (this->inserted[num]);         return (this->inserted[num]);
 } }
  
 // ****************************************************************** // ******************************************************************
 // * FUNCTION : getValue                IN : CLASS key                                          *  
 // * Gets the Value of the current key.                                                         *  
 // ******************************************************************  
 unsigned short key::getValue(){  
         return this->cur_value;  
 }  
   
 // ******************************************************************  
 // * FUNCTION : getWeight               IN : CLASS key                                          * // * FUNCTION : getWeight               IN : CLASS key                                          *
 // * Gets the Weight of the current key.                                                        * // * Gets the Weight of the current key.                                                        *
 // ****************************************************************** // ******************************************************************
 unsigned short key::getWeight(){  ITEM_MASS key::getWeight(){
         return this->cur_weight;         return this->cur_weight;
 } }
  
 // ****************************************************************** // ******************************************************************
 // * FUNCTION : getRatio                IN : CLASS item                                         *  
 // * Gets the Ratio for the current item.                                                       *  
 // ******************************************************************  
 float item::getRatio(){  
         return ratio;  
 }  
   
 // ******************************************************************  
 // * FUNCTION : getWeight               IN : CLASS item                                         * // * FUNCTION : getWeight               IN : CLASS item                                         *
 // * Gets the Weight of the current item.                                                       * // * Gets the Weight of the current item.                                                       *
 // ****************************************************************** // ******************************************************************
 unsigned short item::getWeight(){  ITEM_MASS item::getWeight(){
         return this->weight;         return this->weight;
 } }
  
 // ******************************************************************  
 // * FUNCTION : getCost                 IN : CLASS item                                         *  
 // * Gets the Value of the current item.                                                        *  
 // ******************************************************************  
 unsigned short item::getCost(){  
         return this->cost;  
 }  
   
 // ******************************************************************  
 // * FUNCTION : getNumber               IN : CLASS item                                         *  
 // * Gets the Index of the current item.                                                        *  
 // ******************************************************************  
 unsigned short item::getNumber(){  
         return this->number;  
 }  
  
 // ****************************************************************** // ******************************************************************
 // * FUNCTION : setData                 IN : CLASS item                                         * // * FUNCTION : setData                 IN : CLASS item                                         *
 // * Sets all the data for an item.                                                                     * // * Sets all the data for an item.                                                                     *
 // ****************************************************************** // ******************************************************************
 void item::setData(unsigned short weightage, unsigned short costage, unsigned short numerage){  void item::setData(ITEM_MASS weightage){ //, ITEM_MASS costage, ITEM_MASS numerage){
         this->cost = costage;  //      this->cost = weightage; //costage;
         this->weight = weightage;         this->weight = weightage;
         this->ratio = ( (float)(cost)/(float)(weight) );  //      this->ratio = ( (float)(cost)/(float)(weight) );
         this->number = numerage;  //      this->ratio = 1; //ratio = 1
   //      this->number = numerage;
 } }
  
  
Line 258 
Line 244 
 // * FUNCTION : initBackpack    IN : CLASS backpack                                     * // * FUNCTION : initBackpack    IN : CLASS backpack                                     *
 // * Initalizes the backpack values and creates the item array          * // * Initalizes the backpack values and creates the item array          *
 // ****************************************************************** // ******************************************************************
 void backpack::initBackpack(unsigned short total, unsigned short max){  void backpack::initBackpack(INDEX_TYPE total, ITEM_MASS max){
         this->totalItems = total;  
         this->maxWeight = max;         this->maxWeight = max;
           this->totalItems = total;
         item_array = new item[total];         item_array = new item[total];
         worknodeCount = 0;         worknodeCount = 0;
         addnodeCount = 0;         addnodeCount = 0;
 } }
  
   
   
 // ****************************************************************** // ******************************************************************
 // * FUNCTION : putItem                 IN : CLASS backpack                                     * // * FUNCTION : putItem                 IN : CLASS backpack                                     *
 // * Creates an item and places it into the priority queue                      * // * Creates an item and places it into the priority queue                      *
 // ****************************************************************** // ******************************************************************
 void backpack::putItem(unsigned short weight, unsigned short cost){  void backpack::putItem(ITEM_MASS weight){  //,  ITEM_MASS cost){
         item temp_item;          item temp_item;//       printf("%d, %d, %d, %d, %d\n",item_array[0],item_array[1],item_array[2],item_array[3],item_array[4]);
         temp_item.setData(weight,cost,(int)(this->item_queue.size())+1);  
           temp_item.setData(weight);//,cost);//,(int)(this->item_queue.size())+1); // sometimes this starts at 2000?
         this->item_queue.push(temp_item);         this->item_queue.push(temp_item);
 } }
  
Line 286 
Line 275 
                 this->item_array[i] = this->item_queue.top();                 this->item_array[i] = this->item_queue.top();
                 this->item_queue.pop();                 this->item_queue.pop();
         }         }
   //      printf("%d, %d, %d, %d, %d\n",item_array[0].getWeight(),item_array[1].getWeight(),item_array[2].getWeight(),item_array[3].getWeight(),item_array[4].getWeight());
   
 } }
  
 // ****************************************************************** // ******************************************************************
 // * FUNCTION : get_totalItems  IN : CLASS backpack                                     * // * FUNCTION : get_totalItems  IN : CLASS backpack                                     *
 // * Returns the number of items for consideration.                                     * // * Returns the number of items for consideration.                                     *
 // ****************************************************************** // ******************************************************************
 unsigned short backpack::get_totalItems(){  ITEM_MASS backpack::get_totalItems(){
         return this->totalItems;         return this->totalItems;
 } }
  
Line 300 
Line 291 
 // * FUNCTION : get_maxWeight   IN : CLASS backpack                                     * // * FUNCTION : get_maxWeight   IN : CLASS backpack                                     *
 // * Returns the maximum weight for this backpack.                                      * // * Returns the maximum weight for this backpack.                                      *
 // ****************************************************************** // ******************************************************************
 unsigned short backpack::get_maxWeight(){  ITEM_MASS backpack::get_maxWeight(){
         return this->maxWeight;         return this->maxWeight;
 } }
  
Line 308 
Line 299 
 // * FUNCTION : get_Item                IN : CLASS backpack                                     * // * FUNCTION : get_Item                IN : CLASS backpack                                     *
 // * Returns a particular item from the item array                                      * // * Returns a particular item from the item array                                      *
 // ****************************************************************** // ******************************************************************
 item backpack::get_Item(unsigned short index){  item backpack::get_Item(INDEX_TYPE index){
         return ( this->item_array[index] );         return ( this->item_array[index] );
 } }
  
Line 329 
Line 320 
 // * possible solution for this knapsack.                                                       * // * possible solution for this knapsack.                                                       *
 // * Fetch all the information and print it out.                                        * // * Fetch all the information and print it out.                                        *
 // ****************************************************************** // ******************************************************************
 void backpack::branch_and_bound(){  void backpack::branch_and_bound(int DEBUG_MODE, ITEM_MASS targetvalue){
         key temp_key;         key temp_key;
  
         temp_key.initKey(this);         temp_key.initKey(this);
Line 337 
Line 328 
         this->addnodeCount++;         this->addnodeCount++;
  
         bool onwards = 1;         bool onwards = 1;
   
         do         do
         {         {
                 temp_key = key_queue.top();                 temp_key = key_queue.top();
                 this->key_queue.pop();                 this->key_queue.pop();
   /*Early skip here -- MASSIVE speed improvements */
                   if ( temp_key.getWeight() == targetvalue ) {
                           //printf("Early value acquired! %d\n",temp_key.getWeight() );
                           goto early; // yes thats a go to. Its the only way to leave and keep the context right. I know its horrible
                   }
   //              printf("reached %d\n",temp_key.getWeight());
                 if ( temp_key.doneItems() ) {                 if ( temp_key.doneItems() ) {
                         onwards = 0;                         onwards = 0;
                 }                 }
Line 350 
Line 346 
             temp_key.flagNext();             temp_key.flagNext();
                 this->key_queue.push(temp_key);                 this->key_queue.push(temp_key);
                                 this->addnodeCount++;                                 this->addnodeCount++;
   
                                   // try this --- compare quicksorted before and after because of greedy grabbing largest
                                   //should find other comparator for weight with sub data like ... pct done
   
                         temp_key.addCurItem();                         temp_key.addCurItem();
                         if (temp_key.getBound() != 0){                          if (temp_key.getBound() != 0){          //insert only if active.
                                 this->key_queue.push(temp_key);                                 this->key_queue.push(temp_key);
                                 this->addnodeCount++;                                 this->addnodeCount++;
                         }                         }
                 }                 }
                   // commenting out worknode trackerincreases speed by 3%
         }         }
         while (onwards);         while (onwards);
  
           early:  if (DEBUG_MODE) {
   
         printf("Case n=%2d Total possible nodes in thie state space tree is 2^%2d-1\n",this->totalItems,this->totalItems);         printf("Case n=%2d Total possible nodes in thie state space tree is 2^%2d-1\n",this->totalItems,this->totalItems);
         printf("          Number of nodes placed in the priority queue: %6d\n",this->addnodeCount);                  printf("          DISABLED Number of nodes placed in the priority queue: %6d\n",this->addnodeCount);
         printf("          Number of nodes examined/split:               %6d\n",this->worknodeCount);                  printf("          DISABLED Number of nodes examined/split:               %6d\n",this->worknodeCount);
           }
   
         printf("\nObjects Chosen \n");  
  
         printf("          Objects      Weights      Values\n");          if ( temp_key.getWeight() == targetvalue ) {
         int totalitemsinserted = 0;         int totalitemsinserted = 0;
                   int first=1;
         for (int i = 0; this->totalItems > i; i++) {         for (int i = 0; this->totalItems > i; i++) {
                 if ( temp_key.checkItem(i) ) {                 if ( temp_key.checkItem(i) ) {
                         printf("             %2d           %2d           %2d\n", this->item_array[i].getNumber(),  this->item_array[i].getWeight(), this->item_array[i].getCost());                                  if (first==0) { printf(","); }
                         totalitemsinserted++;                                  else {first = 0;}                     // there has GOT to be a better way!
                                   printf("%d", this->item_array[i].getWeight());
                           }
                 }                 }
         }         }
         printf("======================================================\n");          else { printf("CANNOT FILL PALLET\n"); }
         printf("Totals:      %2d           %2d           %2d\n",totalitemsinserted, temp_key.getWeight(),  temp_key.getValue());  
         printf("Ratio :     %2.5f\n", ((float)temp_key.getValue()/(float)temp_key.getWeight()));  
 } }
  
   void super_increase_algo ( vector<ITEM_MASS> inventory, ITEM_MASS target_value , int DEBUG_MODE ) {
           stack<ITEM_MASS> packages_to_load;
           INDEX_TYPE size_inventory = inventory.size();
   
           if (DEBUG_MODE) {
                   printf("Extracting values, highest to lowest, doing reduction from index %d\n",size_inventory);
           }
           for ( INDEX_TYPE store_index=size_inventory-1; store_index>=0;store_index-- ) {
                   if (DEBUG_MODE) {
                           printf("value %d, is it smaller than %d? If so, subtract and store.\n",inventory[store_index],target_value);
                   }
                   if ( inventory[store_index] <= target_value ) {
                           target_value = target_value - inventory[store_index];
                           packages_to_load.push(inventory[store_index]);
                   }
           }
           if ( target_value == 0 ) {
                   int first = 1;
                   while ( ! packages_to_load.empty() ) {
                           if (first==0) { printf(","); }
                           else {first = 0;}                     // there has GOT to be a better way!
                           printf("%d",packages_to_load.top());
                           packages_to_load.pop();
                   }
                   printf("\n");
           }
           else { printf("CANNOT FILL PALLET\n"); }
   }
   
   
   void syntaxmsg(){
           printf("Usage:\n");
           printf("<program name> <input filename> <D/d>\n");
           printf("input contains a series of integers [A], comma delimited,\n\t followed by a CR and an int [B]\n");
           printf("program outputs a comma delimited list of elements of A that sum to B,\n\t or CANNOT FILL PALLET\n");
           printf("Program written for the UCLA ACM Feb 2005 Coding Competition\n");
           printf("Dervied from previous academic work written by the author\n(C) 2002-2005 Rizwan Kassim\n");
           printf("If the second argument is a D or d, verbose debugging mode will be enabled\n\n");
           return;
   }
   
   
   ITEM_MASS masscomp (const void * a, const void * b)
   {
     return ( *(ITEM_MASS*)a - *(ITEM_MASS*)b );
   }
   
   
 // ****************************************************************** // ******************************************************************
 // * FUNCTION : main                                                                                            * // * FUNCTION : main                                                                                            *
 // * Initalizes the backpack and the items inside.                                      * // * Initalizes the backpack and the items inside.                                      *
Line 390 
Line 437 
 int main(int argc, char *argv[]) int main(int argc, char *argv[])
 { {
         item temp_item;         item temp_item;
         printf("CS331_Project 4, by Rizwan Kassim.\n");          int DEBUG_MODE = 0;
         printf("Version 3\n");  
         printf("All compiled / source code are (C) Rizwan Kassim 2003\n\n");  
  
           if ( argc < 2 ) { syntaxmsg(); return 2;}
           if ( argc > 4 ) { syntaxmsg(); return 3;}
           if ( argc == 3 ) {
                   if ( argv[2][0] == 'D' || argv[2][0] == 'd' ) {
                   printf("Debug switch caught, outputing debug messages\n");
                   DEBUG_MODE =1;
                   } else { syntaxmsg(); return 4;}
           }
  
         printf("============================ KNAPSACK ONE ================================\n");          if (DEBUG_MODE) {
         backpack knapsackOne;                  printf("Entry into UCLA ACM Feb. 2005 Coding Competition\n");
                   printf("Based on code developed (myself) for CS331 Project 4 at CSU Pomona\n");
                   printf("Version 4\n");
                   printf("All compiled / source code are (C) Rizwan Kassim 2005\n\n");
           }
  
         knapsackOne.initBackpack(10,18); // 5 total items, 17 total weight          ifstream inputfs;
         knapsackOne.putItem(1,1);          inputfs.open (argv[1]);
         knapsackOne.putItem(2,2);          if (!inputfs.is_open())
         knapsackOne.putItem(3,3);            { printf("File open of %s failed!\n", argv[1]);
         knapsackOne.putItem(4,4);                  syntaxmsg();
         knapsackOne.putItem(5,5);                  return 1; }
         knapsackOne.putItem(7,7);          if (DEBUG_MODE) {
         knapsackOne.putItem(8,8);                  printf("File %s Open!\n",argv[1]);
         knapsackOne.putItem(9,9);          }
         knapsackOne.putItem(10,10);  
         knapsackOne.putItem(6,6);  
  
 // 47591 17          INDEX_TYPE length;
         knapsackOne.store_item_array();          inputfs.seekg (0, ios::end);
           length = inputfs.tellg();
           inputfs.seekg (0, ios::beg);
  
           char * read_buffer = (char *) malloc (length);
           vector<ITEM_MASS> inventory;
                   // could use stack instead of array --- doesn't require malloc, more 'safe' avoids overflows, esp if
                   // input file is funky --- its better software engineering, but its slower. Given that this is a pretty
                   // small system, I'll stick with the array --- oh even better -- a vector!
                   //http://theory.stanford.edu/~amitp/rants/c++-vs-c/ Vector speed sorting is optimized by using vector!
           inputfs.getline (read_buffer, length-1);
  
         for ( int i = 0; knapsackOne.get_totalItems() > i; i++){          char * theToken; INDEX_TYPE index = 0;
                 temp_item=knapsackOne.get_Item(i);          theToken=strtok(read_buffer,",");
                 printf("Item Number %2d : %2d cost for %2d weight at ratio %2.3f\n", temp_item.getNumber(),  temp_item.getCost(), temp_item.getWeight(), temp_item.getRatio());          // assume 1+ items
           while ( theToken != NULL ) {
                   //printf("tokendebug %d %f\n",theToken,theToken);
                   inventory.push_back(atol(theToken));
                   //printf("index %d, token %s, value %d\n",index,theToken,inventory[index]);
                   index++;
                   theToken = strtok (NULL,",");
                   }
   
   
           int SUPER_MODE = 0;
           if (inventory[0]==1) { SUPER_MODE=1;}
   
           if (DEBUG_MODE) {
                   printf("Line 1 read - %d products from warehouse\n", inventory.size());
                   if (SUPER_MODE) printf("Working in Superincreasing mode!\n");
           }
   
   //      sort (inventory.begin(), inventory.end(),std::greater<ITEM_MASS>() );
   //      sort (inventory.begin(), inventory.end()); // most efficient, uses largest boxes inherently
   
           // NEED TRY/CATCH error handling for possible segfault locations
           inputfs.getline (read_buffer, length-1);
           ITEM_MASS palette_size=atol(read_buffer);
   
           if (DEBUG_MODE) {
                   printf("Line 2 read - %d weight units can fit onto palette\n",palette_size);
         }         }
         printf("\n");  
  
         knapsackOne.branch_and_bound();          inputfs.close();
           free(read_buffer);
   
   
   // I could use a class to extrapolate out the file loading function like my 499 project....
   
   
           if (SUPER_MODE) {
                    super_increase_algo (inventory, palette_size , DEBUG_MODE );
                    return 0;
            }
   
   // filter out oversizes BEFORE we insert them above, therefore making life complicated
   
           vector<ITEM_MASS>::iterator itInventory;
           double sum_test = 0;
   
   //      printf("inventory before %d\n",inventory.size());
           for(itInventory = inventory.begin(); itInventory != inventory.end(); itInventory++) {
                   if (*itInventory > palette_size ) {
   //                      printf("%d removing at , left %d!\n",*itInventory,inventory.size());
                           inventory.erase(itInventory);
                           itInventory--;
   //                      printf("%d removed at %d,  left!\n",*itInventory,inventory.size());
                   // remove elements that are too large. its a n increase here, but >>n increase if done later
                   }
                   sum_test = sum_test + *itInventory;
           }
           if (( sum_test < palette_size) || (inventory.size()==0)) {
                    printf("CANNOT FILL PALLET\n"); return 5;}
                   // either all the elements combined would not make a complete crate
                   // or all the elements are too big.
   
           backpack knapsackOne;
   
           knapsackOne.initBackpack(inventory.size(),palette_size);
           if (DEBUG_MODE) {
                   printf("init %d, %d\n",inventory.size(),palette_size);
           }
   
           for(itInventory = inventory.begin(); itInventory != inventory.end(); itInventory++) {
                   knapsackOne.putItem(*itInventory);
   //              if (DEBUG_MODE) {
   //                      printf("insert %d\n",*itInventory);
   //              }
           }
   
           knapsackOne.store_item_array();
           inventory.clear();
   
           knapsackOne.branch_and_bound(DEBUG_MODE,palette_size);
  
         printf("\n");         printf("\n");
 } }
  
  
   
   
   
   
   
   
 /* /*
 Modifications to the original branch-and-bound algorithim/approach Modifications to the original branch-and-bound algorithim/approach
  
Line 449 
Line 594 
  
 Whats interesting is that we can keep the various ratio calculations, as we WOULD rather insert an item of 10 lbs rather than 1 Whats interesting is that we can keep the various ratio calculations, as we WOULD rather insert an item of 10 lbs rather than 1
 We just equate weight and value later on! (Or set a fixed ratio of 1) We just equate weight and value later on! (Or set a fixed ratio of 1)
                   knapsack insert (value,value)
  
                 This was max 2^10-1 with only 47 nodes and 33 splits.                 This was max 2^10-1 with only 47 nodes and 33 splits.
  
   And lets try with a random set of 25 numbers!
   70,76,55,17,70,77,52,81,11,31,57,47,93,53,83,33,1,59,29,33,78,79,37,26,83 ==> 200
   Chose:
                 1           70           70
                 3           55           55
                24           26           26
                23           37           37
                17            1            1
                 9           11           11
   2^25-1 worst case, 142 nodes, 115 split!
   real    0m0.036s
   user    0m0.030s
   sys     0m0.030s
   
   
   
   
   then 50:
   186,130,132,108,112,39,90,88,105,172,50,46,125,79,22,192,139,132,77,195,21,129,134,76,179,89,32,55,61,160,49,191,153,86,45,16,196,109,1,178,51,104,40,88,135,100,108,182,30,48  => 1470
   2^50 worst case, 1826 nodes, 1443 splits
   real    0m0.044s
   user    0m0.062s
   sys     0m0.000s
   
   
   Now, lets really ramp it up so that we can see optimzation effects
   n=2500! won't even care to list the numbers, no point!
   
   Wait, we exceeded 3 minutes there (our weight size was just a guess, btw, might not actually ahve a value)
   Oh, our memory bound was maxed out so it hit a loop ... it actually completed in less than a sec! God bless my processor :)
   Lets bump it up to 5k,
   
   Case n=5000 Total possible nodes in thie state space tree is 2^5000-1
             Number of nodes placed in the priority queue:  35037
             Number of nodes examined/split:                34942
   
   real    0m2.810s
   user    0m1.843s
   sys     0m0.062s
   
   
   Given that this is about the largest we can hope to achieve before INTMAX because a massive issue (we should really typedefine the container class), lets see what optimizations we can make to this code!
   
   must do 1 -
   move all the ITEM_MASSs to (other)
   the ITEM_MASSs are now ITEM_TYPE, a def earlier on (we could have done typedef here too, of course)
   real    0m2.928s
   user    0m1.999s
   sys     0m0.061s
   Slight increase.
   
   Bad things happen when we try to make it into floats, I just tired. floats can't be [] contents for an array ;p
   Doing unsigned long for now.
   goal 1 = stop ratio calculation and comparisons if at all possible!
   real time shot up!
   real    0m3.994s
   user    0m2.390s
   sys     0m0.046s
   
   (that being said, timse don't seem to be consistent. CVS is storing our versions, lets plow on)
   
   remove the comparator in the structcomparator
   real    0m2.830s
   user    0m2.030s
   sys     0m0.015s
   
   remove the printout of the items as inserted
   real    0m1.423s
   user    0m1.436s
   sys     0m0.015s
   
   remove the tracking of the item "number", we don't need to deal with it with this project.
   
   after moved all unsigned ints to typedefs,
   typedef float ITEM_MASS;
   typedef long INDEX_TYPE;
   
   and modified the printfs to handle floating !
   
   real    0m1.591s
   user    0m1.562s
   sys     0m0.000s
   
   inserting a float does :
   
   acm2.cpp: In function `int main(int, char**)':
   acm2.cpp:410: error: no matching function for call to `backpack::putItem(
      double, int, int)'
   acm2.cpp:279: error: candidates are: void backpack::putItem(float, float)
   make: *** [acm2] Error 1
   
   (and it locks up if we have a decimal in seeked value)
   
   ok we move onwards to remove weight,value calls and replace them with just weight
   we also use notepad/sed to remove half the sample knapsack calls
   we realize in doing this that we've actually got 7009 elements! modifiying appropraite values!
   
   real    0m2.627s
   user    0m2.624s
   sys     0m0.000s
   
   but now it uses all 17.
   
   
   Lets try an appropriately high value instead of the 50000ish we're using now. Lets say, we want ...
   600 elements of 7000, at avg value of 5000 3000000ish?
   
   Case n=6998 Total possible nodes in thie state space tree is 2^6998-1
             Number of nodes placed in the priority queue:  70797
             Number of nodes examined/split:                69811
   
   Totals: 114     509283.00       509283.00
   
   then...
   
   ============================ KNAPSACK ONE ================================
   Case n=6998 Total possible nodes in thie state space tree is 2^6998-1
             Number of nodes placed in the priority queue: 108848
             Number of nodes examined/split:                96391
   
   Totals: 1002    5091283.00      5091283.00
   
   
   real    0m9.526s
   user    0m9.249s
   sys     0m0.203s
   
   
   I'm actually pretty happy with this. We havent tested a few conditions, but its time we got the file loading routine in
   
   
   todo
   1) when it doesnt work
   2) when its already reached stop
   3) float
   
   For superincreasing sets, its INCREDIBLY easy to do
   Sort it.
   if (current value < pallete size), palletsize-current value, current_value on board.
   repeat until end
   
   
   
   === loading file now
   make input float ok
   
   reverted to base type of non float --- making the stored value float did badthings to atoi / atof (they didnt work)
   
   
   we could really move the pqueue to a queue --- although don't we want to push bigger items to the top to fill it up faster?
   
   goal 1 - lets remove the double call to the creator function, weight=value ratio=1
   
   
   large set time :
   103,199,67,119,152,119,181,85,74,73,130,82,79,98,99,95,101,81,54,129,157,88,177,97,122,74,46,77,142,39,61,13,86,173,83,180,49,196,144,101,43,28,3,139,127,149,64,194,18,168,75,89,110,113,113,183,124,4,143,61,70,162,161,101,75,47,51,28,4,149,44,58,131,36,53,18,118,89,37,12,99,38,189,98,164,65,109,190,103,113,160,51,113,130,113,50,26,138,153,196,80,193,40,197,52,195,190,97,108,111,141,2,180,5,125,139,38,21,60,148,191,158,169,50,155,167,152,25,154,3,11,1
   
   real    1m14.327s
   user    1m11.530s
   sys     0m0.421s
   
   with goto removed.
   
   
   largeset time with early leave!
   Early value acquired! 13273
   133,103,105,199,33,67,119,119,181,85,74,73,26,130,82,79,98,99,95,101,81,54,129,157,88,177,97,122,74,46,77,142,39,61,13,86,173,83,180,49,196,144,101,43,28,3,139,127,149,64,194,18,168,75,89,110,113,113,183,124,4,143,61,70,162,161,101,75,47,51,28,4,149,44,58,131,36,53,18,118,89,37,12,99,38,189,98,164,65,109,190,103,113,160,51,113,130,113,50,26,138,153,196,80,193,40,197,52,195,190,97,108,111,141,2,180,5,53,125,139,38,21,60,148,191,158,169,50,155,167,25,86,24,3,10
   
   real    0m2.594s
   user    0m2.093s
   sys     0m0.468s
   
   Case n=4555 Total possible nodes in thie state space tree is 2^4555-1
             Number of nodes placed in the priority queue:  45994
             Number of nodes examined/split:                45381
   
   real    1m5.247s
   user    1m3.374s
   sys     0m0.327s
   after a presort. What about decsending sort?
   
   note, removing -g only kills a 1 second or something
   
   real    0m2.446s
   user    0m2.186s
   sys     0m0.203s
   
   with presort and early out
   
   with sort and weight based item compare
   
   
   with item based compare
   real    0m2.676s
   user    0m2.499s
   sys     0m0.108s
   
   item based compare AND sort
   real    0m2.543s
   user    0m2.452s
   sys     0m0.062s
   
   
                 */                 */
  


Legend:
Removed from v.1.1  
changed lines
  Added in v.1.16

Rizwan Kassim
Powered by
ViewCVS 0.9.2