|
version 1.13, 2005/02/16 10:44:24
|
version 1.14, 2005/02/16 21:17:10
|
|
|
|
| #define MAX_ITEMS 65536 | #define MAX_ITEMS 65536 |
| //the above bound comes from the fixed value for the boolean array TODO REMOVE LIMITATION | //the above bound comes from the fixed value for the boolean array TODO REMOVE LIMITATION |
| | |
| |
#define EARLYSKIP |
| |
|
| typedef long ITEM_MASS; | typedef long ITEM_MASS; |
| typedef long INDEX_TYPE; | typedef long INDEX_TYPE; |
| | |
|
|
|
| public: | public: |
| // float getRatio(); | // float getRatio(); |
| ITEM_MASS getWeight(); | ITEM_MASS getWeight(); |
| ITEM_MASS getCost(); |
|
| // ITEM_MASS getNumber(); | // ITEM_MASS getNumber(); |
| void setData(ITEM_MASS); | void setData(ITEM_MASS); |
| private: | private: |
| ITEM_MASS weight; | ITEM_MASS weight; |
| ITEM_MASS cost; |
|
| // float ratio; | // float ratio; |
| // ITEM_MASS number; | // ITEM_MASS number; |
| }; | }; |
|
|
|
| float getBound(); | float getBound(); |
| bool checkItem(INDEX_TYPE); | bool checkItem(INDEX_TYPE); |
| ITEM_MASS getWeight(); | ITEM_MASS getWeight(); |
| ITEM_MASS getValue(); |
void makeDone(); |
| private: | private: |
| void calcBound(); | void calcBound(); |
| bool inserted[MAX_ITEMS]; | bool inserted[MAX_ITEMS]; |
| INDEX_TYPE nextitem; | INDEX_TYPE nextitem; |
| ITEM_MASS cur_weight; | ITEM_MASS cur_weight; |
| ITEM_MASS cur_value; |
|
| float upper_bound; | float upper_bound; |
| backpack *myBackpack; | backpack *myBackpack; |
| }; | }; |
|
|
|
| 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; |
| |
} |
| } | } |
| | |
| // ****************************************************************** | // ****************************************************************** |
|
|
|
| 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(); |
|
|
|
| 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. * |
|
|
|
| // * 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(); (ratio = 1!) | // 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()){ |
|
|
|
| // * FUNCTION : getValue IN : CLASS key * | // * FUNCTION : getValue IN : CLASS key * |
| // * Gets the Value of the current key. * | // * Gets the Value of the current key. * |
| // ****************************************************************** | // ****************************************************************** |
| ITEM_MASS key::getValue(){ |
//ITEM_MASS key::getValue(){ |
| return this->cur_value; |
// return this->cur_value; |
| } |
//} |
| | |
| // ****************************************************************** | // ****************************************************************** |
| // * FUNCTION : getWeight IN : CLASS key * | // * FUNCTION : getWeight IN : CLASS key * |
|
|
|
| // * FUNCTION : getCost IN : CLASS item * | // * FUNCTION : getCost IN : CLASS item * |
| // * Gets the Value of the current item. * | // * Gets the Value of the current item. * |
| // ****************************************************************** | // ****************************************************************** |
| ITEM_MASS item::getCost(){ |
///ITEM_MASS item::getCost(){ |
| return this->cost; |
/// return this->cost; |
| } |
///} |
| | |
| // ****************************************************************** | // ****************************************************************** |
| // * FUNCTION : getNumber IN : CLASS item * | // * FUNCTION : getNumber IN : CLASS item * |
|
|
|
| // * Sets all the data for an item. * | // * Sets all the data for an item. * |
| // ****************************************************************** | // ****************************************************************** |
| void item::setData(ITEM_MASS weightage){ //, ITEM_MASS costage, ITEM_MASS numerage){ | void item::setData(ITEM_MASS weightage){ //, ITEM_MASS costage, ITEM_MASS numerage){ |
| this->cost = weightage; //costage; |
// this->cost = weightage; //costage; |
| this->weight = weightage; | this->weight = weightage; |
| // this->ratio = ( (float)(cost)/(float)(weight) ); | // this->ratio = ( (float)(cost)/(float)(weight) ); |
| // this->ratio = 1; //ratio = 1 | // this->ratio = 1; //ratio = 1 |
|
|
|
| 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; |
| } | } |
|
|
|
| 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) { |
| 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); |
|
|
|
| return; | 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. * |
|
|
|
| // could use stack instead of array --- doesn't require malloc, more 'safe' avoids overflows, esp if | // 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 | // 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! | // 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); | inputfs.getline (read_buffer, length-1); |
| | |
| char * theToken; INDEX_TYPE index = 0; | char * theToken; INDEX_TYPE index = 0; |
|
|
|
| if (SUPER_MODE) printf("Working in Superincreasing mode!\n"); | if (SUPER_MODE) printf("Working in Superincreasing mode!\n"); |
| } | } |
| | |
| // qsort ( inventory, size_inventory, sizeof(int), intcomp); // we now have a sorted list |
// 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 | // NEED TRY/CATCH error handling for possible segfault locations |
| inputfs.getline (read_buffer, length-1); | inputfs.getline (read_buffer, length-1); |
| ITEM_MASS palette_size=atoi(read_buffer); | ITEM_MASS palette_size=atoi(read_buffer); |
|
|
|
| goal 1 - lets remove the double call to the creator function, weight=value ratio=1 | 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 |
| |
|
| */ | */ |
| | |