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

Diff for /acm/acm2.cpp between version 1.3 and 1.14

version 1.3, 2005/02/16 07:19:57 version 1.14, 2005/02/16 21:17:10
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>
   // yes I could use just one i/o lib
   using namespace std;
   
  
 // As per specification, the project has to be able to grow to an // As per specification, the project has to be able to grow to an
 // arbitrary amount of items. MAX_ITEMS describes the size of the // arbitrary amount of items. MAX_ITEMS describes the size of the
Line 8 
Line 17 
 // their parent object was in the priority queue, so static sized // their parent object was in the priority queue, so static sized
 // arrays were used // arrays were used
  
 #define MAX_ITEMS 55  #define MAX_ITEMS 65536
   //the above bound comes from the fixed value for the boolean array TODO REMOVE LIMITATION
   
   #define EARLYSKIP
   
   typedef long ITEM_MASS;
   typedef long INDEX_TYPE;
   
  
 using namespace std; using namespace std;
  
Line 18 
Line 34 
 // ****************************************************************** // ******************************************************************
 class item { class item {
 public: public:
         float getRatio();  //      float getRatio();
         unsigned short getWeight();          ITEM_MASS getWeight();
     unsigned short getCost();  //      ITEM_MASS getNumber();
         unsigned short getNumber();          void setData(ITEM_MASS);
         void setData(unsigned short,unsigned short,unsigned short);  
 private: private:
         unsigned short weight;          ITEM_MASS weight;
         unsigned short cost;  //      float ratio;
         float ratio;  //      ITEM_MASS number;
         unsigned short number;  
 }; };
  
 // ****************************************************************** // ******************************************************************
Line 53 
Line 67 
         void addCurItem();         void addCurItem();
         bool doneItems();         bool doneItems();
         float getBound();         float getBound();
         bool checkItem(unsigned short);          bool checkItem(INDEX_TYPE);
         unsigned short getWeight();          ITEM_MASS getWeight();
         unsigned short getValue();          void makeDone();
 private: private:
         void calcBound();         void calcBound();
         bool inserted[MAX_ITEMS];         bool inserted[MAX_ITEMS];
         unsigned short nextitem;          INDEX_TYPE nextitem;
         unsigned short cur_weight;          ITEM_MASS cur_weight;
         unsigned short cur_value;  
         float upper_bound;         float upper_bound;
         backpack *myBackpack;         backpack *myBackpack;
 }; };
Line 72 
Line 85 
 // ****************************************************************** // ******************************************************************
 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 0 ; }  //same ratio to all, don't actually do a compare!
 } ; } ;
  
 // ****************************************************************** // ******************************************************************
Line 90 
Line 104 
 // ****************************************************************** // ******************************************************************
 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 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 131 
         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();
           for ( int i = 0; MAX_ITEMS > i; i++) {
                   this->inserted[i] = 0;
           }
 } }
  
 // ****************************************************************** // ******************************************************************
Line 140 
Line 156 
 void key::addCurItem(){ void key::addCurItem(){
         nextitem--;         nextitem--;
         this->inserted[this->nextitem]=1;         this->inserted[this->nextitem]=1;
         this->cur_value  += (this->myBackpack->get_Item(this->nextitem)).getCost();  
         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 154 
Line 169 
         return ( this->myBackpack->get_totalItems() == this->nextitem );         return ( this->myBackpack->get_totalItems() == this->nextitem );
 } }
  
   void key::makeDone(){
           this->nextitem = this->myBackpack->get_totalItems();
   }
   
 // ****************************************************************** // ******************************************************************
 // * FUNCTION : getBound                IN : CLASS key                                          * // * FUNCTION : getBound                IN : CLASS key                                          *
 // * Returns the bound.                                                                                         * // * Returns the bound.                                                                                         *
Line 169 
Line 188 
 // * 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();  //              temp = temp * (this->myBackpack->get_Item(this->nextitem)).getRatio(); (ratio = 1!)
         }         }
         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 209 
 // * 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]);
 } }
  
Line 198 
Line 217 
 // * FUNCTION : getValue                IN : CLASS key                                          * // * FUNCTION : getValue                IN : CLASS key                                          *
 // * Gets the Value of the current key.                                                         * // * Gets the Value of the current key.                                                         *
 // ****************************************************************** // ******************************************************************
 unsigned short key::getValue(){  //ITEM_MASS key::getValue(){
         return this->cur_value;  //      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;
 } }
  
Line 214 
Line 233 
 // * FUNCTION : getRatio                IN : CLASS item                                         * // * FUNCTION : getRatio                IN : CLASS item                                         *
 // * Gets the Ratio for the current item.                                                       * // * Gets the Ratio for the current item.                                                       *
 // ****************************************************************** // ******************************************************************
 float item::getRatio(){  //float item::getRatio(){
         return ratio;  //      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;
 } }
  
Line 230 
Line 249 
 // * FUNCTION : getCost                 IN : CLASS item                                         * // * FUNCTION : getCost                 IN : CLASS item                                         *
 // * Gets the Value of the current item.                                                        * // * Gets the Value of the current item.                                                        *
 // ****************************************************************** // ******************************************************************
 unsigned short item::getCost(){  ///ITEM_MASS item::getCost(){
         return this->cost;  ///     return this->cost;
 }  ///}
  
 // ****************************************************************** // ******************************************************************
 // * FUNCTION : getNumber               IN : CLASS item                                         * // * FUNCTION : getNumber               IN : CLASS item                                         *
 // * Gets the Index of the current item.                                                        * // * Gets the Index of the current item.                                                        *
 // ****************************************************************** // ******************************************************************
 unsigned short item::getNumber(){  //ITEM_MASS item::getNumber(){
         return this->number;  //      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 278 
 // * 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->totalItems = total;
         this->maxWeight = max;         this->maxWeight = max;
         item_array = new item[total];         item_array = new item[total];
Line 270 
Line 290 
 // * 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;
         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 292 
Line 312 
 // * 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 320 
 // * 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 328 
 // * 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 349 
 // * 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 357 
         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
                   }
                 if ( temp_key.doneItems() ) {                 if ( temp_key.doneItems() ) {
                         onwards = 0;                         onwards = 0;
                 }                 }
Line 350 
Line 374 
             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){
                                 this->key_queue.push(temp_key);                                 this->key_queue.push(temp_key);
                                 this->addnodeCount++;                                 this->addnodeCount++;
                         }                         }
                 }                 }
   //              if ((this->addnodeCount % 1000) == 0) {printf("10000!");}
         }         }
         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("          Number of nodes placed in the priority queue: %6d\n",this->addnodeCount);
         printf("          Number of nodes examined/split:               %6d\n",this->worknodeCount);         printf("          Number of nodes examined/split:               %6d\n",this->worknodeCount);
   /*              printf("\nObjects Chosen \n");
  
                   printf("\t\tWeights\tValues\n");
                   int totalitemsinserted = 0;
                   for (int i = 0; this->totalItems > i; i++) {
                           if ( temp_key.checkItem(i) ) {
                                   printf("\t\t%4.2f\t%4.2f\n", this->item_array[i].getWeight(), this->item_array[i].getCost());
                                   totalitemsinserted++; // this->item_array[i].getNumber(),   removed
                           }
                   }
                   printf("======================================================\n");
                   printf("Totals:\t%3d\t%4.2f\t%4.2f\n",totalitemsinserted, temp_key.getWeight(),  temp_key.getValue());
           //      printf("Ratio :     %2.5f\n", ((float)temp_key.getValue()/(float)temp_key.getWeight())); */
           }
  
         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");  
         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()));  
 } }
           else { printf("CANNOT FILL PALLET\n"); }
   }
   
   // have to deal with non int #s
   
   void super_increase_algo ( vector<ITEM_MASS> inventory, ITEM_MASS target_value , INDEX_TYPE size_inventory, int DEBUG_MODE ) {
           stack<ITEM_MASS> packages_to_load;
   
           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                                                                                            *
Line 390 
Line 484 
 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(25,200); // 5 total items, 17 total weight  
  
 knapsackOne.putitem(70,70);          INDEX_TYPE max_inventory;
 knapsackOne.putitem(76,76);  
 knapsackOne.putitem(55,55);  
 knapsackOne.putitem(17,17);  
 knapsackOne.putitem(70,70);  
 knapsackOne.putitem(77,77);  
 knapsackOne.putitem(52,52);  
 knapsackOne.putitem(81,81);  
 knapsackOne.putitem(11,11);  
 knapsackOne.putitem(31,31);  
 knapsackOne.putitem(57,57);  
 knapsackOne.putitem(47,47);  
 knapsackOne.putitem(93,93);  
 knapsackOne.putitem(53,53);  
 knapsackOne.putitem(83,83);  
 knapsackOne.putitem(33,33);  
 knapsackOne.putitem(1,1);  
 knapsackOne.putitem(59,59);  
 knapsackOne.putitem(29,29);  
 knapsackOne.putitem(33,33);  
 knapsackOne.putitem(78,78);  
 knapsackOne.putitem(79,79);  
 knapsackOne.putitem(37,37);  
 knapsackOne.putitem(26,26);  
 knapsackOne.putitem(83,83);  
  
           ifstream inputfs;
           inputfs.open (argv[1]);
           if (!inputfs.is_open())
             { printf("File open of %s failed!\n", argv[1]);
                   syntaxmsg();
                   return 1; }
           if (DEBUG_MODE) {
                   printf("File %s Open!\n",argv[1]);
           }
  
         knapsackOne.store_item_array();          INDEX_TYPE length;
           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,",");
         }         }
         printf("\n");  
  
         knapsackOne.branch_and_bound();          INDEX_TYPE size_inventory = inventory.size(); //remember this is 1 based, not 0
   
           int SUPER_MODE = 0;
           if (inventory[0]==1) { SUPER_MODE=1;}
   
           if (DEBUG_MODE) {
                   printf("Line 1 read - %d products from warehouse\n", size_inventory);
                   if (SUPER_MODE) printf("Working in Superincreasing mode!\n");
           }
   
   //      qsort ( inventory, size_inventory, sizeof(ITEM_MASS), masscomp);        // we now have a sorted list
   //      sort (inventory.begin(), inventory.end(),std::greater<ITEM_MASS>() );
           sort (inventory.begin(), inventory.end());
                   // sorts array in reverse order, biggest elements first (
           // NEED TRY/CATCH error handling for possible segfault locations
           inputfs.getline (read_buffer, length-1);
           ITEM_MASS palette_size=atoi(read_buffer);
   
           if (DEBUG_MODE) {
                   printf("Line 2 read - %d weight units can fit onto palette\n",palette_size);
           }
   
           if (SUPER_MODE) {
                    super_increase_algo (inventory, palette_size , size_inventory, DEBUG_MODE );
                    return 0;
            }
   
           inputfs.close();
           free(read_buffer);
   
   // I could use a class to extrapolate out the file loading function like my 499 project....
   
           backpack knapsackOne;
   
           knapsackOne.initBackpack(size_inventory,palette_size);
           if (DEBUG_MODE) {
                   printf("init %d, %d\n",size_inventory,palette_size);
           }
           for ( INDEX_TYPE store_index=0; size_inventory>store_index;store_index++ ) {
                   knapsackOne.putItem(inventory[store_index]);
   
                   if (DEBUG_MODE) {
                           printf("insert %d\n",inventory[store_index]);
                   }
   
           }
           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 471 
Line 628 
  
 And lets try with a random set of 25 numbers! 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 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: 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 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
  
                 */                 */
  


Legend:
Removed from v.1.3  
changed lines
  Added in v.1.14

Rizwan Kassim
Powered by
ViewCVS 0.9.2