Showing posts with label Priority Queue. Show all posts
Showing posts with label Priority Queue. Show all posts

Tuesday, 24 March 2009

Simulating FIFO behaviour with priority queues for equal priorities

In priority queue, the C++ specifications does not define the behaviour of the algorithms when equal-priority items are involved. It is assumed that the ordering is not important in case of a priority queue as long as the same priority items are in correct order as compared to other priorities. For a programmer though this can be important as he expects FIFO ordering for same priority items. To overcome the problem I mentioned in earlier program, we can add another item to get correct FIFO ordering for same priority items.

This is just one approach and there may be other approaches. Also notice that I have used a local variable which requires the order to be input. You can also use the static variable approach for this.


//Program tested on Microsoft Visual Studio 2008 - Zahid Ghadialy
//Example of slightly advanced priority queue making sure that
//along with priorities, queue functionality of FIFO is maintained
#include <iostream>
#include <string>
#include <vector>
#include <queue>

using namespace
std;

class
PrioritizedWord
{

private
:
int
m_prio;
string m_word;
int
m_order; //To set FIFO operation

public
:
explicit
PrioritizedWord()
{ }

explicit
PrioritizedWord(const std::string& word, const int priority = 0, const int order = 0):
m_word(word), m_prio(priority), m_order(order)
{ }

//Operator overloading for priority comparison
const bool operator <(const PrioritizedWord& pW) const
{

if
(m_prio == pW.m_prio)
return
(m_order > pW.m_order);
else
return
(m_prio < pW.m_prio);
}

//Operator overloading to print output
friend ostream& operator <<(ostream& out, const PrioritizedWord& pW)
{

out<<pW.m_word;
return
out;
}

int
getPrio(void)
{
return m_prio;}
string getWord(void)
{
return m_word;}
};


int
main()
{

priority_queue<PrioritizedWord> zahidQueue;

//Note the final order will not be the same as the specs do not
//define behaviour in case two numbers with equal priority exist
zahidQueue.push(PrioritizedWord("First", 23, 1));
zahidQueue.push(PrioritizedWord("Second", 23, 2));
zahidQueue.push(PrioritizedWord("Third", 23, 3));
zahidQueue.push(PrioritizedWord("Fourth", 51, 4));
zahidQueue.push(PrioritizedWord("Fifth", -1, 5));

cout<<"\n\nZahid Queue elements :"<<endl;
while
(!zahidQueue.empty())
{

cout<<zahidQueue.top()<<" "<<endl;
zahidQueue.pop();
}


return
0;
}



The output is as follows:

Monday, 9 March 2009

Simple example of Priority Queue

Here is a simple example of priority queue:



//Program tested on Microsoft Visual Studio 2008 - Zahid Ghadialy

//Example showing how simple priority queues work using C++

#include <iostream>

#include <string>

#include <vector>

#include <queue>



using namespace
std;



class
PrioritizedWord

{


private
:

int
m_prio;

string m_word;



public
:

explicit
PrioritizedWord()

{ }


explicit
PrioritizedWord(const std::string& word, const int priority = 0):

m_word(word), m_prio(priority)

{ }


//Operator overloading for priority comparison

const bool operator <(const PrioritizedWord& pW) const

{


return
(m_prio < pW.m_prio);

}


//Operator overloading to print output

friend ostream& operator <<(ostream& out, const PrioritizedWord& pW)

{


out<<pW.m_word;

return
out;

}


int
getPrio(void)

{
return m_prio;}

string getWord(void)

{
return m_word;}

};




int
main()

{


int
somenum = 2;

while
(somenum > 0)

{


priority_queue<PrioritizedWord> wordQueue, zahidQueue, *temp=NULL;

//Word Queue first time, Zahid Queue second time

if(somenum%2==0)

{


temp = &wordQueue;

}


else


{


temp = &zahidQueue;

}




//Note the final order will not be the same as the specs do not

//define behaviour in case two numbers with equal priority exist

temp->push(PrioritizedWord("First", 23));

temp->push(PrioritizedWord("Second", 23));

temp->push(PrioritizedWord("Third", 23));

temp->push(PrioritizedWord("Fourth", 51));

temp->push(PrioritizedWord("Fifth", -1));



cout<<"\n\nWord Queue elements (All elements lost):"<<endl;

while
(!wordQueue.empty())

{


cout<<wordQueue.top()<<" "<<endl;

wordQueue.pop();

}




cout<<"\n\nZahid Queue elements (Elements preserved):"<<endl;

if
(!zahidQueue.empty())

{


priority_queue<PrioritizedWord> tempQueue;

while
(!zahidQueue.empty())

{


PrioritizedWord &temppW = zahidQueue.top();

cout<<temppW<<" "<<endl;

tempQueue.push(PrioritizedWord(temppW.getWord(), temppW.getPrio()));

zahidQueue.pop();

}


while
(!tempQueue.empty())

{


PrioritizedWord &temppW = tempQueue.top();

zahidQueue.push(PrioritizedWord(temppW.getWord(), temppW.getPrio()));

tempQueue.pop();

}

}




cout<<"\n\nZahid Queue - Removing an element and leaving the rest"<<endl;

{


priority_queue<PrioritizedWord> tempQueue;

while
(!zahidQueue.empty())

{


PrioritizedWord &temppW = zahidQueue.top();



if
(temppW.getWord() != "Second")

{


tempQueue.push(PrioritizedWord(temppW.getWord(), temppW.getPrio()));

zahidQueue.pop();

}


else


{


zahidQueue.pop();

break
;

}

}


while
(!tempQueue.empty())

{


PrioritizedWord &temppW = tempQueue.top();

zahidQueue.push(PrioritizedWord(temppW.getWord(), temppW.getPrio()));

tempQueue.pop();

}

}




cout<<"\n\nZahid Queue elements after removal of element"<<endl;

while
(!zahidQueue.empty())

{


cout<<zahidQueue.top()<<" "<<endl;

zahidQueue.pop();

}


somenum--;

}




return
0;

}


The output is as follows:

Wednesday, 4 March 2009

Simple Function Pointers example

This example shows how function pointers work. There is also an example of how priority queues work.



//Program tested on Microsoft Visual Studio 2008 - Zahid Ghadialy
//This program intents to show the use of function pointers
//This program also uses priority queues
#include<iostream>
#include<queue>

using namespace
std;

typedef
int (*fpRegCb)(int* i_p, int index);

int
funcA(int *val, int index)
{

cout<<"Func A: index = "<<index<<" val = "<<*val<<endl;
return
(*val + 10);
}


int
funcB(int *val, int index)
{

cout<<"Func B: index = "<<index<<" val = "<<*val<<endl;
return
(*val + 15);
}


class
someSimpleListType
{

private
:
someSimpleListType(); //This cant be used
public:
int
index;
int
*value;
fpRegCb callback;
someSimpleListType(fpRegCb cb, int *val, int idx):value(val),index(idx)
{

callback = cb;
};

//< operator is overloaded for use with priority queues. This will
//decide the priority of the new element, where it should be placed
const bool operator <(const someSimpleListType& sLT) const
{

return
(index < sLT.index);
}
};


priority_queue <someSimpleListType> someSimpleList;

int
main()
{

int
index=0;
int
*a=new int(22);
int
*b=new int(37);
int
*c=new int(62);

//The higher the priority, higher it is in the queue
someSimpleList.push(someSimpleListType(funcA, a, index++));
someSimpleList.push(someSimpleListType(funcB, b, index++));
someSimpleList.push(someSimpleListType(funcB, c, index++));
//The last push will end up top of queue as index(priority) is greatest

//Lets get all the elements from the list and process them
cout<<"Test 1"<<endl;
while
(!someSimpleList.empty())
{

someSimpleListType &sLT = someSimpleList.top();
cout<<"Callback["<<sLT.index<<"] = "<<sLT.callback(sLT.value,sLT.index)<<endl;
someSimpleList.pop();
}


//Since the priority queue is now empty, push some more elements
someSimpleList.push(someSimpleListType(funcA, a, index++));
someSimpleList.push(someSimpleListType(funcB, b, index++));
someSimpleList.push(someSimpleListType(funcB, c, index++));

//This time we will only process funcB and ignore funcA
cout<<endl<<"Test 2"<<endl;
while
(!someSimpleList.empty())
{

someSimpleListType &sLT = someSimpleList.top();
if
(sLT.callback == funcB)
{

cout<<"Callback["<<sLT.index<<"] = "<<sLT.callback(sLT.value,sLT.index)<<endl;
}

someSimpleList.pop();
}


return
0;
}