int runSim(int a1, int a2, int a3){
	BinaryHeap<Soldier> test;
	test.buildSoldiers(a2, a3);
	return test.events();
	test.makeEmpty();

}
Exemple #2
0
	void execute_new_sell_order(MarketInstruction * mi) {
		MarketInstruction * mostImportantBuyOrder = NULL;

		while(buyOrders->size() > 0) {
			if(mi->quantity == 0) break;

			mostImportantBuyOrder = buyOrders->rootElem();

			if(mi->price <= mostImportantBuyOrder->price) {

				unsigned int quantity = min(mi->quantity, mostImportantBuyOrder->quantity);

				mi->quantity -= quantity;
				mostImportantBuyOrder->quantity -= quantity;

				double price = mostImportantBuyOrder->price;

				fill(quantity, price, mostImportantBuyOrder->id, mi->id, mi->targetAssetName);

				if(mostImportantBuyOrder->quantity == 0) {
					buyOrders->deleteRootElem();
					free(mostImportantBuyOrder);
				}
			}
			else 
				break;
		}

		if(mi->quantity > 0) {
			rest_order(mi);
		}
	}
Exemple #3
0
void removeElement(BinaryHeap<int> & h, int index){
	cout<< "Removing the number a position " << index << " from the heap." <<endl;
	int x = h.remove(index);
	cout<< x << " was successfully removed."<<endl;
	int size = h.size();
	cout<<"The size of the heap is now: "<<size<<endl;
}
////////////////////////////////////////////////////////////////
//            FINDING MINIMUM UNKNOWN DISTANCE                //
////////////////////////////////////////////////////////////////
HeapObj Router::FindMinUnknown(BinaryHeap<HeapObj> &heap){

      while(vArray[(heap.findMin()).index]->known)
      {   //while the min vertex is unknown, we ignore it and keep popping
            heap.deleteMin();
      }      
      return heap.findMin();
}
Exemple #5
0
	void execute_new_cancel_instruction(MarketInstruction * mi) {
		if(mi->typeOfOrder == MarketInstruction::Buy) {
			buyOrders->deleteElemWithId(mi->id);
		}
		else {
			sellOrders->deleteElemWithId(mi->id);
		}
	}
void Encoder::generateHuffmanTree(){
  BinaryHeap<node<int> > heap;
  node<int> nodes[256];
  int numNodes = 0;
  for(int i = 0; i < 256; i++)
   if(freq[i] > 0 && i!= 10)
    cout << i << " " << freq[i] <<  endl;
  
  for(int i = 0; i < 256; i++){
    if(freq[i]>0 && i!=10){
      nodes[numNodes].probability = freq[i];
      nodes[numNodes].internal = 0;
      nodes[numNodes].value = i;
      heap.insert(nodes[numNodes]);
      numNodes++;
    }
  }
  // nodes disappear after this...
  for(int i = 0; i < numNodes; i++){
    cout << nodes[i].probability << " " << (char)nodes[i].value << endl;
  }

  node<int> lnode, rnode;
  node<int> parentNodes[300];
  
  int treeNumber = 0;
  
  while(heap.currentSize > 1) //while 2 or more elements in heap
  {
      heap.deleteMin(lnode);
      heap.deleteMin(rnode);

      cout << "Lnode = " << lnode.probability << " " << lnode.value <<  endl;
      cout << "Rnode = " << rnode.probability << " " << rnode.value <<  endl;

      parentNodes[treeNumber].internal = 1;
      parentNodes[treeNumber].probability = lnode.probability + rnode.probability;
      parentNodes[treeNumber].left = &lnode;
      parentNodes[treeNumber].right = &rnode;
      parentNodes[treeNumber].value = treeNumber;
      cout << "Tree " << treeNumber+1 << " has weight: " << lnode.probability + rnode.probability << endl;
      cout << "Left child: " << parentNodes[treeNumber].left->probability << " " << parentNodes[treeNumber].left->value << " Right child: " << parentNodes[treeNumber].right->probability << " " << parentNodes[treeNumber].right->value << endl << endl;
      heap.insert(parentNodes[treeNumber]);
      parentNodes[treeNumber].value = treeNumber++;
      
  }
  treeNumber--; // to take away last unneeded ++
  //parentNodes[treeNumber--].returnCodes(parentNodes[treeNumber--]);
  //returnCodes(&parentNodes[treeNumber--]);

  returnCodes(&parentNodes[0]);
  returnCodes(&parentNodes[1]);
  returnCodes(&parentNodes[2]);
  returnCodes(&parentNodes[3]);

}
Exemple #7
0
	void rest_order(MarketInstruction * mi) {
		if(mi->type == MarketInstruction::Order) {
			if(mi->typeOfOrder == MarketInstruction::Sell) {
				sellOrders->insert(mi, mi->id);
			}
			else if(mi->typeOfOrder == MarketInstruction::Buy) {
				buyOrders->insert(mi, mi->id);
			}
		}
	}
int find_min_dist_id(BinaryHeap<HeapVt> & heap_vt, const vector<Vertex> & vt_path) {
    HeapVt tmp_vt(-1, -1);
    do{
        if(heap_vt.isEmpty()) {
            return -1;
        }
        heap_vt.deleteMin(tmp_vt);
    }while(true == vt_path[tmp_vt.id].known);
    return tmp_vt.id;
}
Exemple #9
0
void addValuesInHeap(BinaryHeap<int> &h){
	cout<<"Adding 3, 17, 92, 44, 2, and 13 to the binary heap"<<endl;
	h.add(3);
	h.add(17);
	h.add(92);
	h.add(44);
	h.add(2);
	h.add(13);

}
//getAlpha uses a binaryHeap to get the word I want alphabetized.
string getAlpha(string letters) {
  BinaryHeap<char,char> getInOrder;
  for (int i = 0; i < letters.length(); i++) {
    getInOrder.insert(letters[i], letters[i]);
  }
  string alphaWord = "";
  for (int j = 0; j < letters.length(); j++) {
    alphaWord += getInOrder.removeMin();
  }
  return alphaWord;
}
Exemple #11
0
//need this to compare two BinaryTreePtr Objects
//bool BinaryTreePtr::operator<(const BinaryTreePtr& b) const
//{
//	return frequency < b.frequency;
//}
int main(int argc, char** argv)
{
	ifstream inf(argv[1]);
	char character;
	//BinaryTreePtr p;
	int ascii[256] = {};
	int temp[256];
	int counter = 0;
	BinaryHeap <BinaryTreePtr> heap; //not sure what size

	while (inf.get(character)) //reads each character as char
	{
		
		int num_char = (int)character; //casts char into int
		
		ascii[num_char]++; //increments array based on asci

	}

	for (int j = 0; j < 256; j++)
	{
		if (ascii[j] != 0)
		{
			
			int freq = ascii[j];
			heap.insert(BinaryTreePtr((char)j,ascii[j]));
		}
	}

	while(!heap.isEmpty())
	{
		BinaryTreePtr min_1;
		heap.deleteMin(min_1);
		//cout << (char)min_1.asci_value << min_1.frequency << endl;
		if (heap.isEmpty())
		{
			heap.insert(min_1);
			break;
		}
		else
		{
			
			BinaryTreePtr min_2;
			heap.deleteMin(min_2);
		//	cout << (char)min_2.asci_value << min_2.frequency << endl;
			BinaryTreePtr parent;
			int temp_freq = min_1.Node->getInfo() + min_2.Node->getInfo();
			char temp_char = 'Y';
			BinaryTreePtr Parent(temp_char, temp_freq, min_1.Node, min_2.Node);
			heap.insert(Parent);
		}
	}
	char* random = new char[500]();
	int i = 0;
	BinaryTreePtr last;
	heap.deleteMin(last);
	last.Node->print(random, i);
}
void Encoder::writeHeap(stringstream &out, BinaryHeap<HuffmanNode *> heap, int elements) const
{
  out << elements;	// store how many heap elements at beginning

  HuffmanNode *node;	// to store temporary node
  while(!heap.isEmpty())
  {
    heap.deleteMin(node);
    out << node->data;
    out << node->frequency;
  }  // traverse the entire heap

  return;
}  // writeHeap()
Exemple #13
0
void main(int argc, char* argv[])
{
	Dijkstra* sPath = new Dijkstra();

	Vertex* head = new Vertex(0,"v1");

	//BUG: the comparison on the Vertex* will fail during insert/remove
	BinaryHeap<Vertex*>* pQ = new BinaryHeap<Vertex*>();
	pQ->Insert(head);

	Vertex* current = pQ->RemoveMin();
	sPath->ShortestPath(current, pQ);

	getchar();
}
void Pathfinder::search()
{
	init();

	BinaryHeap openHeap;

	mStart->g = 0;
	mStart->h = manhattan(mStart, mGoal);
	mStart->opened = true;

	openHeap.push(mStart);

	while (openHeap.size() > 0)
	{
		// Pop the node with the smallest f value
		Node* currentNode = openHeap.pop();

		// Check if we hit the target
		if (currentNode == mGoal)
		{
			// Compute the path and exit
			generatePath(currentNode);
			return;
		}

		currentNode->closed = true;

		std::vector<Node*> neighbors = getNeighborsAdjacentTo(currentNode);
		for (int i = 0; i < neighbors.size(); i++)
		{
			Node* neighbor = neighbors[i];
			if (neighbor->closed || neighbor->worldRef->getMaterial()->isCollidable())
				continue;

			int gScore = currentNode->g + 1;

			if(!neighbor->opened || gScore < neighbor->g)
			{
				neighbor->g = currentNode->g + 1;
				neighbor->h = manhattan(currentNode, neighbor);
				neighbor->parent = currentNode;
				neighbor->opened = true;
				openHeap.push(neighbor);
			}
		}
	}
}
Exemple #15
0
int main() {

	BinaryHeap<int> H;
 

	cout << endl;

	vector<int> list = {30,17,20,15,10,12,5,7,8,5,2,9};

	for (int i : list)
	{
		H.insert(i);

	}

	H.printHeap();

	cout << " .....Inserting 1,10,6,4...." << endl;

	vector<int> list2 = {1,10,6,4};
	
	for (int i : list2)
	{
		H.insert(i);

	}

	H.printHeap();

	cout << " ......Performing 3 DeleteMin() ......" << endl;



	for (int i = 0 ; i<3; i++ )
	{
	H.deleteMin();
	}

	H.printHeap(); 

	cout << endl << H.HeapHeight();







//{30,17,20,15,10,12,5,7,8,5,2,9};



return 0;
}
Exemple #16
0
void generate_Soldiers(BinaryHeap<soldier>& heap, int number_of_Spartans, int number_of_Persians, vector<int>& spartans, vector<int>& persians)
{
	soldier newSoldier, minimum;
	int faction_Selection, current_Spartans, current_Persians;
	current_Spartans = 0, current_Persians = number_of_Spartans;
	int timeValue = 0;

	while((number_of_Spartans > 0 || number_of_Persians > 0) )
	{
		faction_Selection = rand() % 2;//Select from 1 to 0 for the faction

		if(faction_Selection == 1 && (number_of_Spartans > 0)){

 			newSoldier.set_Faction(true);//Set the faction of our new soldier.
			timeValue = rand() % 51 + 1;
			newSoldier.set_actionTime(timeValue);

			newSoldier.set_iD(current_Spartans);//Sets the iD to the current value of i. We will step through this i times, creating i soldiers.

			spartans.push_back(current_Spartans);//The ID is pushed into the vector of soldiers.
			current_Spartans++;
			number_of_Spartans--;

			heap.insert(newSoldier);//Insert our newly created soldier

		}
		else if(faction_Selection == 0 && (number_of_Persians > 0)){

			newSoldier.set_Faction(false);


			timeValue = rand() % 900 + 51;
			newSoldier.set_actionTime( timeValue );
			newSoldier.set_iD(current_Persians);//Sets the iD to the current value of i. We will step through this i times, creating i soldiers.
			persians.push_back(current_Persians);
			current_Persians++;
			number_of_Persians--;

			heap.insert(newSoldier);//Insert our newly created soldier

		}
	}
}
Exemple #17
0
//Will pick a soldier from our remaining soldiers alive.
//
void processTurn(BinaryHeap<soldier>& heap, vector<int>& soldiers, int& remaining_Soldiers)
{
	int position_of_Soldier;
	if(remaining_Soldiers == 1) position_of_Soldier = 0;//A condition to ensure kill a soldier is not called when only one soldier is left
	else position_of_Soldier = rand() % remaining_Soldiers;

	bool target_Condition;
	
	soldier nextUp = heap.findMin(); //Return the smallest value; our next up.

	target_Condition = heap.interact_with_Soldier(nextUp.return_Faction(), soldiers[position_of_Soldier]);//False if alive, true if killed
	if(target_Condition && nextUp.return_Faction() ) kill_a_Soldier(soldiers, remaining_Soldiers, position_of_Soldier);//Will removed the soldier if dead.
	else if(target_Condition && !(nextUp.return_Faction()) ) {//Will invigorate if a soldier is killed, AND the soldier target was a Persian

		kill_a_Soldier(soldiers, remaining_Soldiers, position_of_Soldier);//Remove the soldier as per usual
		invigorate(heap, soldiers, remaining_Soldiers);//function invigorate will go through the entire array to invigorate soldiers.
	}

}
Exemple #18
0
void invigorate(BinaryHeap<soldier>& heap, vector<int>& soldiers, int remaining_Soldiers)
//Stepping through all remaining soldiers, we randomly subtract a small value to allow them to act faster.
{
	int currentSoldier, delta;

	if(remaining_Soldiers == 0){//We cannot invigorate an array of dead soldiers. 
		 return;
	}
	
	for(int i = 0; i < remaining_Soldiers; i++)
	{
		soldier current = heap.find_by_ID(i);

		currentSoldier = soldiers[i];
		delta = (rand() % 2 + 1);//determine a random amount to decrease by
		heap.decrease_by_iD(currentSoldier, delta);//Manipulate our current heap so that spartans act a little quicker.
		
	}

}
bool SetCoveringSolution::greedyCover() {
	if(coveredRows == SetCoveringDecoder::nrows) { return false; }

	// Initialize heap with columnCount values:
	BinaryHeap< double >* heap = new BinaryHeap< double >(SetCoveringDecoder::ncolumns);
	for(unsigned j = 0; j < SetCoveringDecoder::ncolumns; ++j) {
		if(rowsCoveredByCol[j] > 0) {
			heap->insert(j, - double(rowsCoveredByCol[j] / SetCoveringDecoder::columnCosts[j]));
		}
	}

	while(coveredRows < SetCoveringDecoder::nrows) {
		const unsigned greedyCol = heap->extractMin();	// Get best column from heap

		openColumn(greedyCol, &heap);	// Open it
	}

	delete heap;
	return isFeasible();
}
Exemple #20
0
int main(int argc, char **argv) {

    BinaryHeap<int> testHeap;
    std::string input;
    std::string numbers = "0123456789";
    
    std::cout << "Input vals to add to BinaryHeap (val1 val2 val3 val4 ... end)\n";

    while (std::cin >> input)
    {
	// if 'std::String::find_first_not_of' doesnt find anything, then it outputs max_int (long int)
	// since any num higher than 1 will be set to true, add 1 to max int to start at 0(false)
	 if (input.find_first_not_of(numbers)+1 ) {
		if (input == "end")
		{
		    break;
		}
		else 
		{
		    std::cerr << input << " not recognized\n";
		    continue;
		}
	     
	} // end if 	
	int num = std::atoi(input.c_str()); // transform string into number, would have normally use boost::lexical_cast though
	testHeap.insert(num);
    }
 
    std::cout << "Input vals to remove from BinaryHeap (val1 val2 val3 val4 ... end)\n";

    while (std::cin >> input)
    {
	// if 'std::String::find_first_not_of' doesnt find anything, then it outputs max_int (long int)
	    // since any num higher than 1 will be set to true, add 1 to max int to start at 0(false)
	 if (input.find_first_not_of(numbers)+1 ) {
		if (input == "end")
		    break;
		else 
		{
		    std::cerr << input << " not recognized\n";
		    continue;
		}
	     
	} // end if 	
	int num = std::atoi(input.c_str());
	testHeap.removeKey(num);
    }
    
    std::cerr << "\n";
    
    
    while (!testHeap.isEmpty())
    {
	std::cerr << testHeap.findMin() << " ";
	testHeap.deleteMin();
	
    }
    std::cerr << "\n";
        return 0;
}
Exemple #21
0
int main() {
	srand(time(NULL));
	BinaryHeap<int> heap;
	ArrayStack<int> randList;

	for(int i = 0; i <= 1000; i++){
		int rando = rand() % 10000 + 1;
		randList.add(rando);
	}
	for(int i = 0; i < 1000; i++){
		heap.add(randList.get(i));
		if(heap.checkHeap()){
		  //cout << "Heap Conditions Met..." << endl;
		}
		else{
		  cout << "Heap Conditions NOT Met!" << endl;
		  cout << randList.get(i) << endl;
		  cout << i;
		  return 0;
		}
	}

	int n = 1000;
  for(int i = 0; i <= 100; i++){
  	int rando = rand() % n + 1;
  	heap.remove(rando);

  	if(heap.checkHeap()){
  		cout << "Heap Conditions Met..." << endl;
  	}
  	else{
  		cout << "Heap Conditions NOT Met!" << endl;
  		return 0;
  	}
  	n--;
  }
  cout << "Heap Conditions Were Met On All Removes. Great Success!" << endl;
	return 0;
}
Exemple #22
0
void insertFromFile (BinaryHeap<Comparable> & bh, string fileName = string("input.txt"))
{
	ifstream ifs(fileName.c_str());
	string temp, word;

	if (ifs)                        // make sure file is open
		while (getline(ifs, temp))
		{
			stringstream ss(temp);
			while (ss >> word)
				bh.insert(word);       // insert every word in file
		}
	else
int main(int argc, char *argv[]) {
    
    std::vector<int> v { 10, 22, 32, 11, 23, 23, 100, 1, 0 };
    
    BinaryHeap<double> *binaryHeap = new BinaryHeap<double>(15);
    binaryHeap->insert(10);
    binaryHeap->insert(1);
    binaryHeap->insert(3);
    binaryHeap->insert(1);
    binaryHeap->insert(2);
    binaryHeap->insert(3);
    binaryHeap->insert(33);
    binaryHeap->insert(0);
    binaryHeap->display();

    return 0;
}
Exemple #24
0
/**
 * Main function
 */
int main(int argc, char** argv){
	BinaryHeap <char> bheap;
	bheap.insert('X');
	bheap.insert('Y');
	bheap.insert('A');
	bheap.insert('R');
	bheap.insert('Z');

	bheap.delete_top();
	bheap.print_heap();
	
	return 0;
}
Exemple #25
0
/*
 * Main Contains Menu
 */
int main()
{
    BinaryHeap h;
    while (1)
    {
        cout<<"------------------"<<endl;
        cout<<"Operations on Heap"<<endl;
        cout<<"------------------"<<endl;
        cout<<"1.Insert Element"<<endl;
        cout<<"2.Delete Minimum Element"<<endl;
        cout<<"3.Extract Minimum Element"<<endl;
        cout<<"4.Print Heap"<<endl;
        cout<<"5.Exit"<<endl;
        int choice, element;
        cout<<"Enter your choice: ";
        cin>>choice;
        switch(choice)
        {
        case 1:
            cout<<"Enter the element to be inserted: ";
            cin>>element;
            h.Insert(element);
            break;
        case 2:
            h.DeleteMin();
            break;
        case 3:
            cout<<"Minimum Element: ";
            if (h.ExtractMin() == -1)
            {
                cout<<"Heap is Empty"<<endl;
            }
            else
                cout<<"Minimum Element:  "<<h.ExtractMin()<<endl;
            break;
        case 4:
            cout<<"Displaying elements of Hwap:  ";
            h.DisplayHeap();
            break;
        case 5:
            exit(1);
        default:
            cout<<"Enter Correct Choice"<<endl;
        }
    }
    return 0;
}
void Encoder::getHeap(const unsigned char *message, const int size,
                      BinaryHeap<HuffmanNode *> &heap, int &elements) const
{
  unsigned int frequency[256] = {0};

  for (int i = 0; i < size; i++)
  {
    frequency[message[i]]++;
  }  // for each character

  for (int chars = 0; chars < 256; chars++)
  {
    if (frequency[chars] != 0)
    {
      elements++;		// to keep track of how large BHeap is
      HuffmanNode *ins = new HuffmanNode((unsigned char)chars, frequency[chars]);
      heap.insert(ins);
    }  // if character is in file, add to heap
  }  // for freqlist

  return;
}  // getHeap()
void repeatedBackwardAStar(bool** maze, int size, State* start, State* goal){
	int counter = 0;
	State** S = new State*[size];
	for (int i = 0; i < size; i++){
		S[i] = new State[size];
	}
	for (int r = 0; r < size; r++){
		for (int c = 0; c < size; c++){
			S[r][c].row = r;
			S[r][c].col = c;
			S[r][c].search = 0;
		}
	}

	while (!compareStatePos(start, goal)){
		counter = counter + 1;

		S[start->row][start->col].g = INF;
		S[start->row][start->col].search = counter;

	
		S[goal->row][goal->col].g = 0;
		S[goal->row][goal->col].h = manhattanDistance(start, goal);
		S[goal->row][goal->col].f = goal->g + goal->h;
		S[goal->row][goal->col].search = counter;

		BinaryHeap OPEN;
		list<State> CLOSED;

		// watch 4 states around the start state to update cost, if any 
		if (start->row > 0 && !maze[start->row - 1][start->col]){
			updateCostToInf(S, size, start->row - 1, start->col);
		}
		if (start->row< size - 1 && !maze[start->row + 1][start->col]){
			updateCostToInf(S, size, start->row + 1, start->col);
		}
		if (start->col > 0 && !maze[start->row][start->col - 1]){
			updateCostToInf(S, size, start->row, start->col - 1);
		}
		if (start->col < size - 1 && !maze[start->row][start->col + 1]){
			updateCostToInf(S, size, start->row, start->col + 1);
		}

		OPEN.insert(S[goal->row][goal->col]);
		computePath(S, maze, start, &OPEN, &CLOSED, counter, size, false);

		if (OPEN.size() == 0){
			cout << "I cannot reach the target\n";

			// clean up 
			for (int i = 0; i < size; i++){
				delete[] S[i];
			}
			delete[] S;

			return;
		}

		// follow the tree-pointers from sstart to sgoal 
		//stack<coord> path;
		coord current;
		current.row = start->row;
		current.col = start->col;
		//path.push(curCoord);

		while (current.row != goal->row || current.col != goal->col){
			int curRow = current.row;
			int curCol = current.col;
			
			// watch 4 states around this current state to update cost, if any 
			if (current.row > 0 && !maze[current.row - 1][current.col]){
				updateCostToInf(S, size, current.row - 1, current.col);
			}
			if (current.row < size - 1 && !maze[current.row + 1][current.col]){
				updateCostToInf(S, size, current.row + 1, current.col);
			}
			if (current.col > 0 && !maze[current.row][current.col - 1]){
				updateCostToInf(S, size, current.row, current.col - 1);
			}
			if (current.col < size - 1 && !maze[current.row][current.col + 1]){
				updateCostToInf(S, size, current.row, current.col + 1);
			}

			coord next; 

			next.row = S[curRow][curCol].treeRow;
			next.col = S[curRow][curCol].treeCol;
			int dir = direction(&current, &next);
			cout << "\tTried to move to: (" << next.row << ", " << next.col << ")... ";
			if (S[current.row][current.col].cost[dir] > 1){
				cout << "BLOCKED" << endl;
				start = &S[current.row][current.col];
				break;
			}
			cout << "OK! Moved start to: (" << next.row << ", " << next.col << ")" << endl;
			current = next;
		}
		start = &S[current.row][current.col];
	}

	cout << "I reached the target" << endl;


	// clean up 
	for (int i = 0; i < size; i++){
		delete[] S[i];
	}
	delete[] S;
}
float FindBestScore ( int iCountdown, float fCurrentScore, float fInputBestSoFar, 
					 //WORD *pwIndices,
					 ScoreTri **ppstCurTris,		// Pointer to a list of pointers to ScoreTris
					 int iNumTris, WORD *pwResult )


{
	int iLookahead = iCountdown;
	if ( iLookahead > LOOKAHEAD )
	{
		iLookahead = LOOKAHEAD;
	}

	//VERIFY ( fCurrentScore < 1e9 );


	// At the start, limit the lookahead, or it takes ages.
	if ( ( iNumTris > 100 ) && ( fCurrentScore < 50.0f ) && ( iLookahead > 2 ) )
	{
		iLookahead = 2;
	}


	float fBestSoFar = fInputBestSoFar;

	// Given the BestSoFar score, what is the average cost of each lookahead tri?
	float fAverageCost = ( fBestSoFar - fCurrentScore ) / (int)iLookahead;
	// And now allow tris that are a bit worse.
	float fExpensiveCutoff = fAverageCost * fExpensiveFactor;



	VERIFY ( iCountdown > 0 );
	VERIFY ( iNumTris > 0 );

	int j;



	if ( iNumTris == 1 )
	{
		// Well, that's an easy decision then.

		// Find score after removal.
		//float fTriScore = CacheAddTri ( pwIndices[0], pwIndices[1], pwIndices[2], TRUE );
		ScoreTri *pstCur = ppstCurTris[0];
		float fTriScore = CacheAddTri ( pstCur->wIndex[0], pstCur->wIndex[1], pstCur->wIndex[2], TRUE );
		for ( j = 0; j < 3; j++ )
		{
			// Use the valence score after the tri has been removed.
			//int iValence = (*(iValenceCounts.item(pwIndices[j]))) - 1;
			int iValence = (svVertex.item(pstCur->wIndex[j])->iCurrentValence) - 1;
			VERIFY ( iValence >= 0 );
			if ( iValence < c_iMaxValenceBoost )
			{
				fTriScore += fValenceBoost[iValence];
			}
			else
			{
				fTriScore += fValenceBoost[c_iMaxValenceBoost-1];
			}
		}

		fTriScore += fCurrentScore;

		//pwResult[0] = pwIndices[0];
		//pwResult[1] = pwIndices[1];
		//pwResult[2] = pwIndices[2];
		pwResult[0] = pstCur->wIndex[0];
		pwResult[1] = pstCur->wIndex[1];
		pwResult[2] = pstCur->wIndex[2];

		if ( fTriScore > fBestSoFar )
		{
			// Oh well.
			// (actually, not sure this ever happens).
			return fInputBestSoFar;




		}
		else
		{
			return fTriScore;
		}
	}



#ifdef _DEBUG
	for ( int k = 0; k < iNumTris; k++ )
	{
		VERIFY ( !ppstCurTris[k]->bAllowed );
		VERIFY ( !ppstCurTris[k]->bUsed );
	}
#endif


	// Should we limit ourselves to tris that share at least one vert with the previous one?
	bool bNoMadJumps = FALSE;
	WORD wPrevIndices[3];
	//if ( ( fBestSoFar - fCurrentScore ) < (float)iCountdown )
	// The lookahead score is lower than the countdown, so doing mad jumps
	// is not going to do sensible things.
	if ( iCountdown == iLookahead )
	{
		// Ah - this is probably a lookahead, not assembling the real list.
		// Find the previous indices from the cache (a bit of a roundabout method).
		int iNumAllowed = 0;
		if ( CacheGetLastTri ( wPrevIndices ) )
		{
			bNoMadJumps = TRUE;
			// And mark all the tris that these used as "allowed"
			for ( int i = 0; i < 3; i++ )
			{
				ScoreVertex *psv = svVertex.item(wPrevIndices[i]);
				for ( int j = 0; j < psv->stri.size(); j++ )
				{
					ScoreTri *pst = (*(psv->stri.item(j)));
					if ( ( !pst->bUsed ) && ( !pst->bAllowed ) )
					{
						pst->bAllowed = TRUE;
						iNumAllowed++;
					}
				}
			}
			if ( iNumAllowed < 1 )
			{
				// Oops - we've probably gone into a dead-end, so that very few tris
				// are allowed. So open the selection up again.
				bNoMadJumps = FALSE;
				for ( int i = 0; i < 3; i++ )
				{
					ScoreVertex *psv = svVertex.item(wPrevIndices[i]);
					for ( int j = 0; j < psv->stri.size(); j++ )
					{
						ScoreTri *pst = (*(psv->stri.item(j)));
						if ( !pst->bUsed )
						{
							pst->bAllowed = FALSE;
						}
					}
				}
			}
		}
	}


	// Add the tris to a new priority queue, sorting by score.
	//BinaryHeap<WORD, float> NewHeap;
	BinaryHeap<ScoreTri*, float> NewHeap;

	int i;
	//WORD *pwCurIndex = pwIndices;
	for ( i = 0; i < iNumTris; i++ )
	{
		ScoreTri *pstCurTri = ppstCurTris[i];
		float fTriScore = 0.0f;
		if ( bNoMadJumps )
		{
			if ( !pstCurTri->bAllowed )
			{
				continue;
			}

#if IGNORE_VALENCE_FOR_LOOKAHEADS
			// Only use the valence stuff on non-lookaheads.
			// To make the scores comparable, add the maximum valence boost all the time.
			fTriScore += 3.0f * fValenceBoost[c_iMaxValenceBoost-1];
#endif
		}
#if IGNORE_VALENCE_FOR_LOOKAHEADS
		else
#endif
		{
			// Only use the valence stuff on non-lookaheads.
			for ( j = 0; j < 3; j++ )
			{
				// Use the valence score after the tri has been removed.
				//int iValence = (*(iValenceCounts.item(pwCurIndex[j]))) - 1;
				int iValence = (svVertex.item(pstCurTri->wIndex[j])->iCurrentValence) - 1;
				VERIFY ( iValence >= 0 );
				if ( iValence < c_iMaxValenceBoost )
				{
					fTriScore += fValenceBoost[iValence];
				}
				else
				{
					fTriScore += fValenceBoost[c_iMaxValenceBoost-1];
				}
			}
		}

		if ( fTriScore > fExpensiveCutoff )
		{
			// This tri is a lot more expensive than the average cost of the BestSoFar tris.
			// It's very unlikely to give us a good result.
			continue;
		}

		if ( fCurrentScore + fTriScore >= fBestSoFar )
		{
			// We've already gone more than the best score.
			//pwCurIndex += 3;
			continue;
		}


		// And the vertex cost.
		fTriScore += CacheAddTri ( pstCurTri->wIndex[0], pstCurTri->wIndex[1], pstCurTri->wIndex[2], TRUE );

		if ( fTriScore > fExpensiveCutoff )
		{
			// This tri is a lot more expensive than the average cost of the BestSoFar tris.
			// It's very unlikely to give us a good result.
			continue;
		}

		if ( fCurrentScore + fTriScore >= fBestSoFar )
		{
			// We've already gone more than the best score.
			//pwCurIndex += 3;
			continue;
		}

		// And bung it in the heap.
		// We -ve the score so that the first in the heap is the one with the _least_ score.
		NewHeap.Add ( &(ppstCurTris[i]), -fTriScore );
		//pwCurIndex += 3;
	}



	// Undo the "allowed" flags.
	if ( bNoMadJumps )
	{
		for ( int i = 0; i < 3; i++ )
		{
			ScoreVertex *psv = svVertex.item(wPrevIndices[i]);
			for ( int j = 0; j < psv->stri.size(); j++ )
			{
				(*(psv->stri.item(j)))->bAllowed = FALSE;
			}
		}
	}

#ifdef _DEBUG
	for ( k = 0; k < iNumTris; k++ )
	{
		VERIFY ( !ppstCurTris[k]->bAllowed );
		VERIFY ( !ppstCurTris[k]->bUsed );
	}
#endif



	// Now extract from the heap, best score to worst.
	// This attempts to get early-outs very quickly and prevent too much recursion.
	//WORD *pwBest = NULL;
	//WORD *pwCur = NewHeap.FindFirst();
	ScoreTri **ppstBest = NULL;
	ScoreTri **ppstCur = NewHeap.FindFirst();

	//if ( pwCur == NULL )
	if ( ppstCur == NULL )
	{
		// Found nothing that was better.
		return fBestSoFar;
	}

	// Above this score, just don't bother.
	float fCutoffScore = fCutoffFactor * NewHeap.GetCurrentSort();

#ifdef _DEBUG
	float fPrevScore = 1.0f;
#endif

	int iTried = 0;
	//while ( pwCur != NULL )
	while ( ppstCur != NULL )
	{
		ScoreTri *pstCur = *ppstCur;

		float fThisTriNegScore = NewHeap.GetCurrentSort();
		NewHeap.RemoveFirst();

#ifdef _DEBUG
		// Check this heap actually works!
		VERIFY ( fThisTriNegScore <= fPrevScore );
		fPrevScore = fThisTriNegScore;
#endif


		if ( fThisTriNegScore < fCutoffScore )
		{
			// Reached the cutoff for this tri - don't bother continuing.
			break;
		}

		float fScore = fCurrentScore - fThisTriNegScore;

		if ( fScore >= fBestSoFar )
		{
			// We've already gone more than the best score.
			// The reast of the heap is bound to be greater, so don't bother continuing.
			break;
		}

		if ( bNoMadJumps )
		{
			iTried++;
			if ( iTried > iLookaheadCutoff )
			{
				// Tried enough tris - don't want to cause a combinatorial explosion.
				break;
			}
		}

		// Do the valencies.
#ifdef _DEBUG
		float fValenceScore = 0.0f;
#endif
#if IGNORE_VALENCE_FOR_LOOKAHEADS
		if ( bNoMadJumps )
		{
			// Only use the valence stuff on non-lookaheads.
			// To make the scores comparable, add the maximum valence boost all the time.
			fValenceScore = 3.0f * fValenceBoost[c_iMaxValenceBoost-1];
		}
		else
#endif
		{
			for ( j = 0; j < 3; j++ )
			{
				//int iValence = --(*(iValenceCounts.item(pwCur[j])));
				int iValence = --(svVertex.item(pstCur->wIndex[j])->iCurrentValence);
#ifdef _DEBUG
				VERIFY ( iValence >= 0 );
				if ( iValence < c_iMaxValenceBoost )
				{
					fValenceScore += fValenceBoost[iValence];
				}
				else
				{
					fValenceScore += fValenceBoost[c_iMaxValenceBoost-1];
				}
#endif
			}
		}

		// Add it to the cache.
		float fScoreTemp = CacheAddTri ( pstCur->wIndex[0], pstCur->wIndex[1], pstCur->wIndex[2] );

		VERIFY ( !pstCur->bUsed );
		pstCur->bUsed = TRUE;


#ifdef _DEBUG
		fScoreTemp += fValenceScore;
		VERIFY ( fabs ( fScoreTemp + fThisTriNegScore ) < 0.0001f );
#endif

		if ( iLookahead > 1 )
		{
			// Swap pwCur to the start of the list.
#if 0
			WORD wTemp0 = pwCur[0];
			WORD wTemp1 = pwCur[1];
			WORD wTemp2 = pwCur[2];
			pwCur[0] = pwIndices[0];
			pwCur[1] = pwIndices[1];
			pwCur[2] = pwIndices[2];
			//pwIndices[0] = wTemp0;
			//pwIndices[1] = wTemp1;
			//pwIndices[2] = wTemp2;
#else
			ScoreTri *pstTemp = *ppstCur;
			*ppstCur = *ppstCurTris;
			//*ppstCurTris = pstTemp;
#endif

			//VERIFY ( fScore < 1e9 );

			// And look ahead a bit more.
			//fScore = FindBestScoreLookahead ( iLookahead - 1, fScore, fBestSoFar, pwIndices + 3, iNumTris - 1, pwResult + 3 );
			float fNewScore = FindBestScoreLookahead ( iLookahead - 1, fScore, fBestSoFar, iNumTris - 1, pwResult + 3 );
			//VERIFY ( fNewScore < 1e9 );
			fScore = fNewScore;

#if 0
			// And swap it back.
			//wTemp0 = pwIndices[0];
			//wTemp1 = pwIndices[1];
			//wTemp2 = pwIndices[2];
			pwIndices[0] = pwCur[0];
			pwIndices[1] = pwCur[1];
			pwIndices[2] = pwCur[2];
			pwCur[0] = wTemp0;
			pwCur[1] = wTemp1;
			pwCur[2] = wTemp2;
#else
			//pstTemp = *ppstCurTris;
			*ppstCurTris = *ppstCur;
			*ppstCur = pstTemp;
#endif
		}
		//VERIFY ( fScore < 1e9 );
		if ( fScore < fBestSoFar )
		{
			fBestSoFar = fScore;
			//pwBest = pwCur;
			ppstBest = ppstCur;
		}

		CacheRemoveTri();
		VERIFY ( pstCur->bUsed );
		pstCur->bUsed = FALSE;

#if IGNORE_VALENCE_FOR_LOOKAHEADS
		if ( !bNoMadJumps )
#endif
		{
			// Restore the valencies.
			for ( j = 0; j < 3; j++ )
			{
				//++(*(iValenceCounts.item(pwCur[j])));
				++(svVertex.item(pstCur->wIndex[j])->iCurrentValence);
			}
		}

		//pwCur = NewHeap.FindFirst();
		ppstCur = NewHeap.FindFirst();
	}


















	VERIFY ( ppstBest != NULL );
	{
		// Found a better solution.











		// Swap the best tri to the start of the list.
		float fNewBestScore = fBestSoFar;


		// Dump the tri to the result buffer.
		ScoreTri *pstBest = *ppstBest;
		//pwResult[0] = pwBest[0];
		//pwResult[1] = pwBest[1];
		//pwResult[2] = pwBest[2];
		pwResult[0] = pstBest->wIndex[0];
		pwResult[1] = pstBest->wIndex[1];
		pwResult[2] = pstBest->wIndex[2];
		if ( iCountdown > 1 )
		{
#if 0
			WORD wTemp[3];
			wTemp[0] = pwBest[0];
			wTemp[1] = pwBest[1];
			wTemp[2] = pwBest[2];
			pwBest[0] = pwIndices[0];
			pwBest[1] = pwIndices[1];
			pwBest[2] = pwIndices[2];		
#else
			ScoreTri *pTemp;
			pTemp = *ppstBest;
			*ppstBest = *ppstCurTris;
#endif

			//float fScore = CacheAddTri ( wTemp[0], wTemp[1], wTemp[2] );
			float fScore = CacheAddTri ( pstBest->wIndex[0], pstBest->wIndex[1], pstBest->wIndex[2] );
			VERIFY ( !pstBest->bUsed );
			pstBest->bUsed = TRUE;

			// And the valence.
			float fValenceScore = 0.0f;
#if IGNORE_VALENCE_FOR_LOOKAHEADS
			//if ( !bNoMadJumps )
#endif
			{
				for ( j = 0; j < 3; j++ )
				{
					//int iValence = --(*(iValenceCounts.item(wTemp[j])));
					int iValence = --(svVertex.item(pstBest->wIndex[j])->iCurrentValence);
					VERIFY ( iValence >= 0 );
					if ( iValence < c_iMaxValenceBoost )
					{
						fValenceScore += fValenceBoost[iValence];
					}
					else
					{
						fValenceScore += fValenceBoost[c_iMaxValenceBoost-1];
					}
				}
			}

			fScore += fValenceScore + fCurrentScore;

#ifdef DEBUG
			//.			TRACE ( "Countdown %i\n", iCountdown );
#endif


#if ALLOW_PROGRESS_BARS
			if ( g_hProgress2 != NULL )
			{
				// Step one.
				SendMessage ( g_hProgress2, PBM_STEPIT, 0, 0 );
			}
#endif


			//VERIFY ( fScore < 1e9 );

			//fNewBestScore = FindBestScore ( iCountdown - 1, fScore, 1e10, pwIndices + 3, iNumTris - 1, pwResult + 3 );
			fNewBestScore = FindBestScore ( iCountdown - 1, fScore, 1e10, ppstCurTris + 1, iNumTris - 1, pwResult + 3 );

			//VERIFY ( fNewBestScore < 1e9 );



			CacheRemoveTri();
			VERIFY ( pstBest->bUsed );
			pstBest->bUsed = FALSE;

			// Restore the valencies.
#if IGNORE_VALENCE_FOR_LOOKAHEADS
			//if ( !bNoMadJumps )
#endif
			{
				for ( j = 0; j < 3; j++ )
				{
					//++(*(iValenceCounts.item(wTemp[j])));
					++(svVertex.item(pstBest->wIndex[j])->iCurrentValence);
				}
			}

			// And swap it back.
#if 0
			pwIndices[0] = pwBest[0];
			pwIndices[1] = pwBest[1];
			pwIndices[2] = pwBest[2];
			pwBest[0] = wTemp[0];
			pwBest[1] = wTemp[1];
			pwBest[2] = wTemp[2];
#else
			*ppstCurTris = *ppstBest;
			*ppstBest = pTemp;
#endif



		}

		return fNewBestScore;


	}


}
Exemple #29
0
static void test_heap(const T* data, unsigned data_size, const T* sorted_data,
                      const T* to_remove, unsigned removed_size, const T* sorted_after_remove,
                      const T& not_in_heap) {
    BinaryHeap<T, Compare> heap;
    const size_t initial_capacity = data_size / 2, grow_capacity = (data_size * 3) / 2, alignment = 4;
    UAllocTraits_t traits = {0};
    TEST_ASSERT_TRUE(heap.init(initial_capacity, grow_capacity, traits, alignment));

    // Fill the heap with data
    for (unsigned i = 0; i < data_size; i++) {
        heap.insert(data[i]);
        TEST_ASSERT_TRUE(heap.is_consistent());
    }
    TEST_ASSERT_EQUAL(data_size, heap.get_num_elements());

    // Remove and check root at each step
    for (unsigned i = 0; i < data_size; i ++) {
        T root = heap.get_root();
        TEST_ASSERT_TRUE(root == sorted_data[i]);
        heap.remove_root();
        TEST_ASSERT_TRUE(heap.is_consistent());
    }
    TEST_ASSERT_TRUE(heap.is_empty());

    // Put everything back again
    for (unsigned i = 0; i < data_size; i++) {
        heap.insert(data[i]);
        TEST_ASSERT_TRUE(heap.is_consistent());
    }
    TEST_ASSERT_EQUAL(data_size, heap.get_num_elements());

    // And check removing
    for (unsigned i = 0; i < removed_size; i ++) {
        TEST_ASSERT_TRUE(heap.remove(to_remove[i]));
        TEST_ASSERT_TRUE(heap.is_consistent());
    }
    TEST_ASSERT_TRUE(!heap.remove(not_in_heap)); // this element is not in the heap
    TEST_ASSERT_EQUAL(data_size - removed_size, heap.get_num_elements());
    // Remove and check root at each step
    for (unsigned i = 0; i < data_size - removed_size; i ++) {
        T root = heap.pop_root();
        TEST_ASSERT_TRUE(root == sorted_after_remove[i]);
        TEST_ASSERT_TRUE(heap.is_consistent());
    }
    TEST_ASSERT_TRUE(heap.is_empty());
    TEST_ASSERT_EQUAL(0, heap.get_num_elements());
}
Exemple #30
0
void getSize(BinaryHeap<int> &h){
	int size = h.size();
	cout<<"The size of the heap is: " << size<< endl;
}