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

  1 rizwank 1.11 #include<stdlib.h>
  2              #include<iostream>
  3              #include<fstream>
  4              #include<string>
  5 rizwank 1.1  #include <queue>
  6 rizwank 1.12 #include <stack>
  7 rizwank 1.13 #include <vector>
  8 rizwank 1.1  #include <stdio.h>
  9 rizwank 1.11 // yes I could use just one i/o lib
 10              using namespace std;
 11              
 12 rizwank 1.1  
 13              // As per specification, the project has to be able to grow to an 
 14              // arbitrary amount of items. MAX_ITEMS describes the size of the
 15              // appropriate arrays and must be changed at compile time.
 16              // (dynamically created arrays had their pointers corrupted when 
 17              // their parent object was in the priority queue, so static sized
 18              // arrays were used
 19              
 20 rizwank 1.12 #define MAX_ITEMS 65536		
 21              //the above bound comes from the fixed value for the boolean array TODO REMOVE LIMITATION
 22 rizwank 1.1  
 23 rizwank 1.11 typedef long ITEM_MASS;
 24 rizwank 1.9  typedef long INDEX_TYPE;
 25              
 26              
 27 rizwank 1.1  using namespace std;
 28              
 29              // ******************************************************************
 30              // * CLASS : item													*
 31              // * Container object with all the data for a particular item		*
 32              // ******************************************************************
 33              class item {
 34              public:
 35 rizwank 1.8  //	float getRatio();
 36 rizwank 1.9  	ITEM_MASS getWeight();
 37                  ITEM_MASS getCost();
 38              //	ITEM_MASS getNumber();
 39 rizwank 1.10 	void setData(ITEM_MASS);
 40 rizwank 1.1  private:
 41 rizwank 1.9  	ITEM_MASS weight;
 42              	ITEM_MASS cost;
 43 rizwank 1.8  //	float ratio;
 44 rizwank 1.9  //	ITEM_MASS number;
 45 rizwank 1.1  };
 46              
 47              // ******************************************************************
 48              // * CLASS : backpack												*
 49              // * Container object with all the data for an entire knapsack		*
 50              // * Full declaration follows, partial declare here for key			*
 51              // ******************************************************************
 52              class backpack;
 53              
 54              // ******************************************************************
 55              // * CLASS : key													*
 56              // * Container object with all the data for the equivalent of a node*
 57              // * on the state space tree										*
 58              // * To allow data to remain private (and decrease the need of data *
 59              // * such as max_weight and total_items to be passed along with		*
 60              // * every function call, a pointer to the containing backpack is	*
 61              // * instead implemented.											*
 62              // ******************************************************************
 63              class key {
 64              public:
 65              	void initKey( backpack *);
 66 rizwank 1.1  	void flagNext();
 67              	void addCurItem();
 68              	bool doneItems();
 69              	float getBound();
 70 rizwank 1.9  	bool checkItem(INDEX_TYPE);
 71              	ITEM_MASS getWeight();
 72              	ITEM_MASS getValue();
 73 rizwank 1.1  private:
 74              	void calcBound();
 75              	bool inserted[MAX_ITEMS];
 76 rizwank 1.9  	INDEX_TYPE nextitem;
 77              	ITEM_MASS cur_weight;
 78              	ITEM_MASS cur_value;
 79 rizwank 1.1  	float upper_bound;
 80              	backpack *myBackpack;
 81              };
 82              
 83              // ******************************************************************
 84              // * STRUCT : item_comparator										*
 85              // * Functor for comparing the ratio between items					*
 86              // ******************************************************************
 87              struct item_comparator {
 88              	bool operator()( item left, item right ) const 
 89 rizwank 1.8  //	{ return ( left.getRatio() < right.getRatio() ) ; }  
 90              	{ return 0 ; }  //same ratio to all, don't actually do a compare!
 91 rizwank 1.1  } ;
 92              
 93              // ******************************************************************
 94              // * STRUCT : key_comparator										*
 95              // * Functor for comparing the bound between items					*
 96              // ******************************************************************
 97              struct key_comparator {
 98              	bool operator()( key left, key right ) const 
 99              	{ return ( left.getBound() < right.getBound() ) ; } 
100              } ;
101              
102              // ******************************************************************
103              // * CLASS : backpack												*
104              // * Container object with all the data for an entire knapsack		*
105              // ******************************************************************
106              class backpack {
107              public:
108 rizwank 1.9  	void initBackpack(INDEX_TYPE, ITEM_MASS);
109 rizwank 1.10 	void putItem(ITEM_MASS);//, ITEM_MASS);
110 rizwank 1.1  	void store_item_array();
111 rizwank 1.11 	void branch_and_bound(int,ITEM_MASS);
112 rizwank 1.9  	ITEM_MASS get_totalItems();
113              	ITEM_MASS get_maxWeight();
114              	item get_Item(INDEX_TYPE);
115 rizwank 1.1  private:
116              	priority_queue< item, vector<item> , item_comparator> item_queue;
117              	item *item_array;
118              	priority_queue< key, vector<key>, key_comparator> key_queue;
119 rizwank 1.9  	INDEX_TYPE totalItems;
120              	ITEM_MASS maxWeight;
121 rizwank 1.1  	long addnodeCount, worknodeCount;
122              };
123              
124              
125              
126              // ******************************************************************
127              // * FUNCTION : initKey		IN : CLASS key							*
128              // * Initalizes a key, setting the backpack pointer and inital		*
129              // * values then calculating the bound.								*
130              // ******************************************************************
131              void key::initKey(backpack *theCaller){
132              	this->myBackpack = theCaller;
133              	this->nextitem=0;
134              	this->cur_weight=0;
135              	this->cur_value=0;
136              	this->calcBound();
137              }
138              
139              // ******************************************************************
140              // * FUNCTION : flagNext		IN : CLASS key						*
141              // * Modifies the key by setting the next item as not inserted but	*
142 rizwank 1.1  // * as processed, then updates the bound.							*
143              // ******************************************************************
144              void key::flagNext(){
145              	this->inserted[this->nextitem]=0;
146              	nextitem++;
147              	this->calcBound();
148              }
149              
150              // ******************************************************************
151              // * FUNCTION : addCurItem		IN : CLASS key						*
152              // * Follows up flagNext by actually marking the last item as		*
153              // * inserted, adding values and weights, then recalcing the bound.	*
154              // ******************************************************************
155              void key::addCurItem(){
156              	nextitem--;
157              	this->inserted[this->nextitem]=1;
158              	this->cur_value  += (this->myBackpack->get_Item(this->nextitem)).getCost();
159              	this->cur_weight += (this->myBackpack->get_Item(this->nextitem)).getWeight();
160              	nextitem++;
161              	this->calcBound();
162              }
163 rizwank 1.1  
164              // ******************************************************************
165              // * FUNCTION : doneItems		IN : CLASS key						*
166              // * Returns TRUE if all the items have been processed				*
167              // ******************************************************************
168              bool key::doneItems(){
169              	return ( this->myBackpack->get_totalItems() == this->nextitem );
170              }
171              
172              // ******************************************************************
173              // * FUNCTION : getBound		IN : CLASS key						*
174              // * Returns the bound.												*
175              // ******************************************************************
176              float key::getBound(){
177              	return this->upper_bound;
178              }
179              
180              // ******************************************************************
181              // * FUNCTION : calcBound		IN : CLASS key						*
182              // * Calculates the bound. If there are no more items, the bound	*
183              // * remains unchanged. Else, perform the calcuations.				*
184 rizwank 1.1  // * If the weight is over max_weight, set the bound to 0			*
185              // ******************************************************************
186              void key::calcBound(){
187              	float temp;
188              	if (this->doneItems()) {
189              		temp = 0;
190              	}
191              	else {
192              		temp = (float)((this->myBackpack->get_maxWeight()) - cur_weight);
193 rizwank 1.7  //		temp = temp * (this->myBackpack->get_Item(this->nextitem)).getRatio(); (ratio = 1!)
194 rizwank 1.1  	}
195              	this->upper_bound = cur_value + temp;
196              
197              	// What about if the bag is overloaded?
198              	if (this->cur_weight > this->myBackpack->get_maxWeight()){
199              		this->upper_bound = 0;		// invalidate it, will never reach 0 in bound
200              	}
201              }
202              
203              
204              // ******************************************************************
205              // * FUNCTION : checkItem		IN : CLASS key						*
206              // * Checks if a given item is listed as inserted.					*
207              // ******************************************************************
208 rizwank 1.9  bool key::checkItem(INDEX_TYPE num) {
209 rizwank 1.1  	return (this->inserted[num]);
210              }
211              
212              // ******************************************************************
213              // * FUNCTION : getValue		IN : CLASS key						*
214              // * Gets the Value of the current key.								*
215              // ******************************************************************
216 rizwank 1.9  ITEM_MASS key::getValue(){
217 rizwank 1.1  	return this->cur_value;
218              }
219              
220              // ******************************************************************
221              // * FUNCTION : getWeight		IN : CLASS key						*
222              // * Gets the Weight of the current key.							*
223              // ******************************************************************
224 rizwank 1.9  ITEM_MASS key::getWeight(){
225 rizwank 1.1  	return this->cur_weight;
226              }
227              
228              // ******************************************************************
229              // * FUNCTION : getRatio		IN : CLASS item						*
230              // * Gets the Ratio for the current item.							*
231              // ******************************************************************
232 rizwank 1.8  //float item::getRatio(){
233              //	return ratio;
234              //}
235 rizwank 1.1  
236              // ******************************************************************
237              // * FUNCTION : getWeight		IN : CLASS item						*
238              // * Gets the Weight of the current item.							*
239              // ******************************************************************
240 rizwank 1.9  ITEM_MASS item::getWeight(){
241 rizwank 1.1  	return this->weight;
242              }
243              
244              // ******************************************************************
245              // * FUNCTION : getCost			IN : CLASS item						*
246              // * Gets the Value of the current item.							*
247              // ******************************************************************
248 rizwank 1.9  ITEM_MASS item::getCost(){
249 rizwank 1.1  	return this->cost;
250              }
251              
252              // ******************************************************************
253              // * FUNCTION : getNumber		IN : CLASS item						*
254              // * Gets the Index of the current item.							*
255              // ******************************************************************
256 rizwank 1.9  //ITEM_MASS item::getNumber(){
257              //	return this->number;
258              //}
259 rizwank 1.1  
260              // ******************************************************************
261              // * FUNCTION : setData			IN : CLASS item						*
262              // * Sets all the data for an item.									*
263              // ******************************************************************
264 rizwank 1.10 void item::setData(ITEM_MASS weightage){ //, ITEM_MASS costage, ITEM_MASS numerage){
265              	this->cost = weightage; //costage;
266 rizwank 1.1  	this->weight = weightage;
267 rizwank 1.7  //	this->ratio = ( (float)(cost)/(float)(weight) );
268 rizwank 1.8  //	this->ratio = 1; //ratio = 1
269 rizwank 1.9  //	this->number = numerage;
270 rizwank 1.1  }
271              
272              
273              // ******************************************************************
274              // * FUNCTION : initBackpack	IN : CLASS backpack					*
275              // * Initalizes the backpack values and creates the item array		*
276              // ******************************************************************
277 rizwank 1.9  void backpack::initBackpack(INDEX_TYPE total, ITEM_MASS max){
278 rizwank 1.1  	this->totalItems = total;
279              	this->maxWeight = max;
280              	item_array = new item[total];
281              	worknodeCount = 0;
282              	addnodeCount = 0;
283              }
284              
285              // ******************************************************************
286              // * FUNCTION : putItem			IN : CLASS backpack					*
287              // * Creates an item and places it into the priority queue			*
288              // ******************************************************************
289 rizwank 1.10 void backpack::putItem(ITEM_MASS weight){  //,  ITEM_MASS cost){
290 rizwank 1.1  	item temp_item;
291 rizwank 1.10 	temp_item.setData(weight);//,cost);//,(int)(this->item_queue.size())+1); // sometimes this starts at 2000?
292 rizwank 1.1  	this->item_queue.push(temp_item);
293              }
294              
295              // ******************************************************************
296              // * FUNCTION : store_item_array IN : CLASS backpack				*
297              // * Dumps the Item Queue in order into an Array for Rand. Access	*
298              // ******************************************************************
299              void backpack::store_item_array(){
300              	this->item_array = new item[this->totalItems];
301              	for ( int i = 0; this->totalItems > i; i++){
302              		this->item_array[i] = this->item_queue.top();
303              		this->item_queue.pop();
304              	}
305              }
306              
307              // ******************************************************************
308              // * FUNCTION : get_totalItems	IN : CLASS backpack					*
309              // * Returns the number of items for consideration.					*
310              // ******************************************************************
311 rizwank 1.9  ITEM_MASS backpack::get_totalItems(){
312 rizwank 1.1  	return this->totalItems;
313              }
314              
315              // ******************************************************************
316              // * FUNCTION : get_maxWeight	IN : CLASS backpack					*
317              // * Returns the maximum weight for this backpack.					*
318              // ******************************************************************
319 rizwank 1.9  ITEM_MASS backpack::get_maxWeight(){
320 rizwank 1.1  	return this->maxWeight;
321              }
322              
323              // ******************************************************************
324              // * FUNCTION : get_Item		IN : CLASS backpack					*
325              // * Returns a particular item from the item array					*
326              // ******************************************************************
327 rizwank 1.9  item backpack::get_Item(INDEX_TYPE index){
328 rizwank 1.1  	return ( this->item_array[index] );
329              }
330              
331              // ******************************************************************
332              // * FUNCTION : branch_and_bound IN : CLASS backpack				*
333              // * Performs Best-First-Fit Branch and Bound on this backpack		*
334              // * while keeping track of the nodecounts.							*
335              // * Create a template key with the best possible bound.			*
336              // * Place that key into the queue and start a loop					*
337              // * As long as the 'onwards' flag is TRUE, repeat:					*
338              // *	Take the topmost (highest bound) key out of the queue.		*
339              // *	If that bound has all of its items processed, clear ownards	*
340              // *	Else, create two keys from the original key					*
341              // *	One without the next item and one with.						*
342              // *	Place the new keys into the queue and discard the current	*
343              // *	Repeat														*
344              // * If the loop is ended, the top item on the queue is the best	*
345              // * possible solution for this knapsack.							*
346              // * Fetch all the information and print it out.					*
347              // ******************************************************************
348 rizwank 1.11 void backpack::branch_and_bound(int DEBUG_MODE, ITEM_MASS targetvalue){
349 rizwank 1.1  	key temp_key;
350              	
351              	temp_key.initKey(this);
352              	this->key_queue.push(temp_key);
353              	this->addnodeCount++;
354              
355              	bool onwards = 1;
356              
357              	do
358              	{
359              		temp_key = key_queue.top();
360              		this->key_queue.pop();
361              		if ( temp_key.doneItems() ) {
362              			onwards = 0;
363              		}
364              		else {
365              			this->worknodeCount++;
366                          temp_key.flagNext();
367                              this->key_queue.push(temp_key);
368              				this->addnodeCount++;
369              			temp_key.addCurItem();
370 rizwank 1.1  			if (temp_key.getBound() != 0){
371              				this->key_queue.push(temp_key);
372              				this->addnodeCount++;
373              			}
374              		}
375              	}
376              	while (onwards);
377              	
378              
379 rizwank 1.11 	if (DEBUG_MODE) {
380              		printf("Case n=%2d Total possible nodes in thie state space tree is 2^%2d-1\n",this->totalItems,this->totalItems);
381              		printf("          Number of nodes placed in the priority queue: %6d\n",this->addnodeCount);
382              		printf("          Number of nodes examined/split:               %6d\n",this->worknodeCount);
383              /*		printf("\nObjects Chosen \n");
384              
385              		printf("\t\tWeights\tValues\n");
386              		int totalitemsinserted = 0;
387              		for (int i = 0; this->totalItems > i; i++) {
388              			if ( temp_key.checkItem(i) ) {
389              				printf("\t\t%4.2f\t%4.2f\n", this->item_array[i].getWeight(), this->item_array[i].getCost());
390              				totalitemsinserted++; // this->item_array[i].getNumber(),   removed
391              			}
392              		}
393              		printf("======================================================\n");
394              		printf("Totals:\t%3d\t%4.2f\t%4.2f\n",totalitemsinserted, temp_key.getWeight(),  temp_key.getValue());
395              	//	printf("Ratio :     %2.5f\n", ((float)temp_key.getValue()/(float)temp_key.getWeight())); */
396              	}
397              
398              	
399 rizwank 1.12 	if ( temp_key.getWeight() == targetvalue ) {
400 rizwank 1.11 		int totalitemsinserted = 0;
401              		int first=1;
402              		for (int i = 0; this->totalItems > i; i++) {
403              			if ( temp_key.checkItem(i) ) {
404              				if (first==0) { printf(","); } 
405              				else {first = 0;}                     // there has GOT to be a better way!
406              				printf("%d", this->item_array[i].getWeight());
407              			}
408              		}
409 rizwank 1.12 	}
410              	else { printf("CANNOT FILL PALLET\n"); }
411 rizwank 1.11 }
412 rizwank 1.1  
413 rizwank 1.11 // have to deal with non int #s
414 rizwank 1.13 	
415              void super_increase_algo ( vector<ITEM_MASS> inventory, ITEM_MASS target_value , INDEX_TYPE size_inventory, int DEBUG_MODE ) {
416              	stack<ITEM_MASS> packages_to_load;
417 rizwank 1.1  
418 rizwank 1.13 	if (DEBUG_MODE) {
419              		printf("Extracting values, highest to lowest, doing reduction from index %d\n",size_inventory);
420              	}
421              	for ( INDEX_TYPE store_index=size_inventory-1; store_index>=0;store_index-- ) {
422              		if (DEBUG_MODE) {
423              			printf("value %d, is it smaller than %d? If so, subtract and store.\n",inventory[store_index],target_value);
424              		}
425              		if ( inventory[store_index] <= target_value ) {
426              			target_value = target_value - inventory[store_index];
427              			packages_to_load.push(inventory[store_index]);
428              		}
429              	}
430              	if ( target_value == 0 ) {
431              		int first = 1;
432              		while ( ! packages_to_load.empty() ) {
433              			if (first==0) { printf(","); } 
434              			else {first = 0;}                     // there has GOT to be a better way!			
435              			printf("%d",packages_to_load.top());
436              			packages_to_load.pop();
437              		}
438              		printf("\n");
439 rizwank 1.13 	}
440              	else { printf("CANNOT FILL PALLET\n"); }
441              }
442              		
443              		
444 rizwank 1.11 void syntaxmsg(){
445              	printf("Usage:\n");
446              	printf("<program name> <input filename> <D/d>\n");
447              	printf("input contains a series of integers [A], comma delimited,\n\t followed by a CR and an int [B]\n");
448              	printf("program outputs a comma delimited list of elements of A that sum to B,\n\t or CANNOT FILL PALLET\n");
449              	printf("Program written for the UCLA ACM Feb 2005 Coding Competition\n");
450              	printf("Dervied from previous academic work written by the author\n(C) 2002-2005 Rizwan Kassim\n");
451              	printf("If the second argument is a D or d, verbose debugging mode will be enabled\n\n");
452              	return;
453 rizwank 1.1  }
454              
455              // ******************************************************************
456              // * FUNCTION : main												*
457              // * Initalizes the backpack and the items inside.					*
458              // * Copies those items into an array, prints out the items.		*
459              // * Run the branch_and_bound method.								*
460              // ******************************************************************
461              int main(int argc, char *argv[])
462              {
463              	item temp_item;
464 rizwank 1.11 	int DEBUG_MODE = 0;
465 rizwank 1.1  
466 rizwank 1.11 	if ( argc < 2 ) { syntaxmsg(); return 2;}
467              	if ( argc > 4 ) { syntaxmsg(); return 3;}
468              	if ( argc == 3 ) {
469              		if ( argv[2][0] == 'D' || argv[2][0] == 'd' ) {
470              		printf("Debug switch caught, outputing debug messages\n");
471              		DEBUG_MODE =1; 
472              		} else { syntaxmsg(); return 4;}
473              	}
474              		
475              	if (DEBUG_MODE) {
476              		printf("Entry into UCLA ACM Feb. 2005 Coding Competition\n");
477              		printf("Based on code developed (myself) for CS331 Project 4 at CSU Pomona\n"); 
478              		printf("Version 4\n");
479              		printf("All compiled / source code are (C) Rizwan Kassim 2005\n\n");
480              	}
481              	
482              		
483              	INDEX_TYPE max_inventory;
484              	
485              	ifstream inputfs;
486              	inputfs.open (argv[1]);
487 rizwank 1.11 	if (!inputfs.is_open())
488              	  { printf("File open of %s failed!\n", argv[1]);
489              		syntaxmsg(); 
490              		return 1; }
491              	if (DEBUG_MODE) {
492              		printf("File %s Open!\n",argv[1]);
493              	}
494              	
495              	INDEX_TYPE length;
496              	inputfs.seekg (0, ios::end);
497              	length = inputfs.tellg();
498              	inputfs.seekg (0, ios::beg);
499              	
500              	char * read_buffer = (char *) malloc (length);
501 rizwank 1.13 	vector<ITEM_MASS> inventory;
502 rizwank 1.12 		// could use stack instead of array --- doesn't require malloc, more 'safe' avoids overflows, esp if 
503              		// input file is funky --- its better software engineering, but its slower. Given that this is a pretty
504 rizwank 1.13 		// small system, I'll stick with the array --- oh even better -- a vector!
505 rizwank 1.11 	inputfs.getline (read_buffer, length-1);
506              
507              	char * theToken; INDEX_TYPE index = 0;
508              	theToken=strtok(read_buffer,",");
509              	// assume 1+ items
510              	while ( theToken != NULL ) {
511              		//printf("tokendebug %d %f\n",theToken,theToken);
512 rizwank 1.13 		inventory.push_back(atol(theToken));
513 rizwank 1.11 		//printf("index %d, token %s, value %d\n",index,theToken,inventory[index]);
514              		index++;
515              		theToken = strtok (NULL,",");
516              		}
517 rizwank 1.1  
518 rizwank 1.13 	INDEX_TYPE size_inventory = inventory.size(); //remember this is 1 based, not 0
519 rizwank 1.12 	
520              	int SUPER_MODE = 0;
521 rizwank 1.13 	if (inventory[0]==1) { SUPER_MODE=1;}
522 rizwank 1.1  
523 rizwank 1.11 	if (DEBUG_MODE) {
524              		printf("Line 1 read - %d products from warehouse\n", size_inventory);
525 rizwank 1.12 		if (SUPER_MODE) printf("Working in Superincreasing mode!\n");
526 rizwank 1.11 	}
527              	
528              //	qsort ( inventory, size_inventory, sizeof(int), intcomp);	// we now have a sorted list
529              	// NEED TRY/CATCH error handling for possible segfault locations
530              	inputfs.getline (read_buffer, length-1);	
531              	ITEM_MASS palette_size=atoi(read_buffer);
532              	
533              	if (DEBUG_MODE) {
534              		printf("Line 2 read - %d weight units can fit onto palette\n",palette_size);
535              	}
536              	
537 rizwank 1.13 	if (SUPER_MODE) {
538              		 super_increase_algo (inventory, palette_size , size_inventory, DEBUG_MODE );
539              		 return 0;
540              	 }
541              	
542 rizwank 1.11 	inputfs.close();
543 rizwank 1.12 	free(read_buffer);
544              	
545 rizwank 1.11 // I could use a class to extrapolate out the file loading function like my 499 project....	
546              	
547              	backpack knapsackOne;
548 rizwank 1.9  
549 rizwank 1.11 	knapsackOne.initBackpack(size_inventory,palette_size);
550              	if (DEBUG_MODE) {
551              		printf("init %d, %d\n",size_inventory,palette_size);
552              	}
553              	for ( INDEX_TYPE store_index=0; size_inventory>store_index;store_index++ ) {
554              		knapsackOne.putItem(inventory[store_index]);
555              
556              		if (DEBUG_MODE) {
557              			printf("insert %d\n",inventory[store_index]);
558              		}
559              		
560              	}
561 rizwank 1.1  	knapsackOne.store_item_array();
562 rizwank 1.13 	inventory.clear();
563 rizwank 1.11 	knapsackOne.branch_and_bound(DEBUG_MODE,palette_size);
564 rizwank 1.1  
565              	printf("\n");
566              }
567              
568              
569 rizwank 1.12 
570              
571              
572              
573              
574              
575 rizwank 1.1  /* 
576              Modifications to the original branch-and-bound algorithim/approach
577              
578              This program was to compute the maximum value that can be fit into a bag --- Using Levitin p380 for reference
579              right now. As our problem is actually a SUBSET of the given problem ,we can simplify some of the functions.
580              We also don't want any packs too small, but we'll let this compute, see how big the state tree is versus
581              an alternative algorithm.
582              
583              	knapsackOne.initBackpack(5,17); // 5 total items, 17 total weight
584              	knapsackOne.putItem(4,1);
585              	knapsackOne.putItem(7,1);
586              	knapsackOne.putItem(5,1);
587              	knapsackOne.putItem(9,1);
588              	knapsackOne.putItem(1,1);
589              
590              For given same, 2^5-1 possible nodes in tree, 14 nodes placed, 7 split.
591              
592              Lets try something larger. n=10 1,2,3,4,5,6,7,8,9,10 => 18
593              
594              Oooh, we can vary the max backpack item count to only use a certain amount of the items!
595              
596 rizwank 1.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
597              We just equate weight and value later on! (Or set a fixed ratio of 1)		
598 rizwank 1.2  		knapsack insert (value,value)
599              		
600              		This was max 2^10-1 with only 47 nodes and 33 splits.
601 rizwank 1.1  		
602 rizwank 1.2  And lets try with a random set of 25 numbers!
603              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
604 rizwank 1.5  Chose:
605                            1           70           70
606                            3           55           55
607                           24           26           26
608                           23           37           37
609                           17            1            1
610                            9           11           11
611              2^25-1 worst case, 142 nodes, 115 split!
612              real    0m0.036s
613              user    0m0.030s
614              sys     0m0.030s
615              
616 rizwank 1.2  
617              
618              
619              then 50:
620              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
621 rizwank 1.5  2^50 worst case, 1826 nodes, 1443 splits
622              real    0m0.044s
623              user    0m0.062s
624              sys     0m0.000s
625              
626 rizwank 1.7  
627 rizwank 1.5  Now, lets really ramp it up so that we can see optimzation effects
628              n=2500! won't even care to list the numbers, no point!
629              
630              Wait, we exceeded 3 minutes there (our weight size was just a guess, btw, might not actually ahve a value)
631              Oh, our memory bound was maxed out so it hit a loop ... it actually completed in less than a sec! God bless my processor :)
632 rizwank 1.6  Lets bump it up to 5k, 
633              
634              Case n=5000 Total possible nodes in thie state space tree is 2^5000-1
635                        Number of nodes placed in the priority queue:  35037
636                        Number of nodes examined/split:                34942
637              
638              real    0m2.810s
639              user    0m1.843s
640              sys     0m0.062s
641              
642              
643              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!
644 rizwank 1.2  
645 rizwank 1.7  must do 1 - 
646 rizwank 1.9  move all the ITEM_MASSs to (other)
647              the ITEM_MASSs are now ITEM_TYPE, a def earlier on (we could have done typedef here too, of course)
648 rizwank 1.7  real    0m2.928s
649              user    0m1.999s
650              sys     0m0.061s
651              Slight increase.
652              
653              Bad things happen when we try to make it into floats, I just tired. floats can't be [] contents for an array ;p
654              Doing unsigned long for now.
655              goal 1 = stop ratio calculation and comparisons if at all possible!
656              real time shot up!
657              real    0m3.994s
658              user    0m2.390s
659              sys     0m0.046s
660              
661 rizwank 1.8  (that being said, timse don't seem to be consistent. CVS is storing our versions, lets plow on)
662              
663              remove the comparator in the structcomparator
664              real    0m2.830s
665              user    0m2.030s
666              sys     0m0.015s
667              
668              remove the printout of the items as inserted
669              real    0m1.423s
670              user    0m1.436s
671              sys     0m0.015s
672              
673 rizwank 1.9  remove the tracking of the item "number", we don't need to deal with it with this project.
674              
675              after moved all unsigned ints to typedefs, 
676              typedef float ITEM_MASS;
677              typedef long INDEX_TYPE;
678              
679              and modified the printfs to handle floating !
680              
681              real    0m1.591s
682              user    0m1.562s
683              sys     0m0.000s
684              		
685              inserting a float does :
686              				
687              acm2.cpp: In function `int main(int, char**)':
688              acm2.cpp:410: error: no matching function for call to `backpack::putItem(
689                 double, int, int)'
690              acm2.cpp:279: error: candidates are: void backpack::putItem(float, float)
691              make: *** [acm2] Error 1
692 rizwank 1.8  
693 rizwank 1.9  (and it locks up if we have a decimal in seeked value)
694 rizwank 1.8  
695 rizwank 1.10 ok we move onwards to remove weight,value calls and replace them with just weight
696              we also use notepad/sed to remove half the sample knapsack calls
697              we realize in doing this that we've actually got 7009 elements! modifiying appropraite values!
698              
699              real    0m2.627s
700              user    0m2.624s
701              sys     0m0.000s
702              
703              but now it uses all 17.
704              
705              
706              Lets try an appropriately high value instead of the 50000ish we're using now. Lets say, we want ... 
707              600 elements of 7000, at avg value of 5000 3000000ish?
708              
709              Case n=6998 Total possible nodes in thie state space tree is 2^6998-1
710                        Number of nodes placed in the priority queue:  70797
711                        Number of nodes examined/split:                69811
712              
713              Totals: 114     509283.00       509283.00
714              
715              then...
716 rizwank 1.10 
717              ============================ KNAPSACK ONE ================================
718              Case n=6998 Total possible nodes in thie state space tree is 2^6998-1
719                        Number of nodes placed in the priority queue: 108848
720                        Number of nodes examined/split:                96391
721              
722              Totals: 1002    5091283.00      5091283.00
723              
724              
725              real    0m9.526s
726              user    0m9.249s
727              sys     0m0.203s
728              
729              
730              I'm actually pretty happy with this. We havent tested a few conditions, but its time we got the file loading routine in
731              
732              
733              todo 
734              1) when it doesnt work
735              2) when its already reached stop
736              3) float
737 rizwank 1.10 
738 rizwank 1.11 For superincreasing sets, its INCREDIBLY easy to do
739              Sort it.
740              if (current value < pallete size), palletsize-current value, current_value on board.
741              repeat until end
742              
743              
744              
745              === loading file now
746              make input float ok
747              
748              reverted to base type of non float --- making the stored value float did badthings to atoi / atof (they didnt work)
749 rizwank 1.10 
750 rizwank 1.8  
751              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?
752 rizwank 1.7  
753              goal 1 - lets remove the double call to the creator function, weight=value ratio=1		
754 rizwank 1.2  
755 rizwank 1.1  		
756              		*/
757              

Rizwan Kassim
Powered by
ViewCVS 0.9.2