Beruflich Dokumente
Kultur Dokumente
#include <iostream>
#include <cassert>
#include <queue>
#include <stack>
using namespace std;
/*************************************MATRIX CLASS AND DEFINITIONS*
****************************/
//Final State 1 2 3 4
// 5 6 7 8
// 9 10 11 12
// 13 14 15 0
class Matrix
{
public:
int tData[4][4];
Matrix()
//Constructor for Input Matrix
{
}
Matrix(int nValue)
//Constructor to Create Final Solution Matrix And Zero Matrix
{
int n=1;
if(nValue==1)
{
for (int nRow=0; nRow<4; nRow++)
{
for (int nCol=0; nCol<4; nCol++)
//Final Matrix
{
tData[nRow][nCol]=n;
n++;
}
}
tData[3][3]=0;
}
else if (nValue==0)
{
for (int nRow=0; nRow<4; nRow++)
{
for (int nCol=0; nCol<4; nCol++)
//Zero Matrix
{
tData[nRow][nCol]=0;
}
}
}
else
{
// Set all elements of the matrix
for (int nRow=0; nRow<4; nRow++)
{
for (int nCol=0; nCol<4; nCol++)
{
cout<<"Row No :"<<nRow<<"\t"<<"Col No :"<<nCol<<"\tTileValue
: "; //User Input Matrix Creation
cin>>tData[nRow][nCol];
cout<<endl;
}
}
}
}
void printmatrix()
//Printing Any Type Of Matrix
{
for (int nRow=0; nRow<4; nRow++)
{
for (int nCol=0; nCol<4; nCol++)
{
cout<<tData[nRow][nCol];
cout<<"\t";
}
cout<<endl;
}
}
Matrix(const Matrix &cSource)
//Copy Constructor
{
for (int nRow=0; nRow<4; nRow++)
{
for (int nCol=0; nCol<4; nCol++)
{
tData[nRow][nCol]=cSource.tData[nRow][nCol];
}
}
}
int& operator()(const int nCol, const int nRow);
//Assignment Operator Overloaded
Matrix& operator= (const Matrix &cSource);
//Get Address to any spot on Matrix
bool operator==(const Matrix&);
};
bool Matrix::operator==(const Matrix &amat)
//checking if two matrixs are equal or not
{
int count=0;
for (int nRow=0; nRow<4; nRow++)
{
for (int nCol=0; nCol<4; nCol++)
{
if((tData[nRow][nCol])==(amat.tData[nRow][nCol]))
{
count++;
}
}
}
if(count==16)
{
return 1;
}
else
{
return 0;
}
}
Matrix& Matrix::operator= (const Matrix &cSource)
//Assignment Operator Overloaded
{
for (int nRow=0; nRow<4; nRow++)
{
for (int nCol=0; nCol<4; nCol++)
{
tData[nRow][nCol]=cSource.tData[nRow][nCol];
}
}
}
int& Matrix::operator()(const int nCol, const int nRow)
//Get Address to any spot on Matrix
{
assert(nCol >= 0 && nCol < 4);
assert(nRow >= 0 && nRow < 4);
return tData[nRow][nCol];
}
void CopyMat(Matrix &mat, Matrix &cMat)
//Copy From one Matrix To Another
{
for (int nRow=0; nRow<4; nRow++)
{
for (int nCol=0; nCol<4; nCol++)
{
cMat(nCol,nRow)=mat(nCol,nRow);
}
}
}
void FindBlank(Matrix &Mat,int &row,int &col)
//Find Blank's Row & Col
{
for (int nRow=0; nRow<4; nRow++)
{
for (int nCol=0; nCol<4; nCol++)
{
if(Mat(nCol,nRow)==0)
{
row=nRow;
col=nCol;
}
}
}
}
TpathCost=cSource.TpathCost;
goalState=cSource.goalState;
for(int i=0;i<4;i++)
{
child[i]=cSource.child[i];
visited[i]=cSource.visited[i];
}
}
Node& Node::operator= (const Node &cSource)
//assignment operator
{
stateCost=cSource.stateCost;
nMat=cSource.nMat;
misplacedTiles=cSource.misplacedTiles;
TpathCost=cSource.TpathCost;
goalState=cSource.goalState;
for(int i=0;i<4;i++)
{
child[i]=cSource.child[i];
visited[i]=cSource.visited[i];
}
}
bool Node::operator<(const Node& right) const
//For priority queue operator < overloading
{
return stateCost< right.stateCost;
}
Node* createNode(Matrix &Mat,int pathCost,int i)
//Create Node N return itz address
{
Node *N;
N= new Node(Mat,pathCost);
switch(i)
//Direction
{
case 0:
//Left
N->visited[1]=0;
break;
case 1:
//Right
N->visited[0]=0;
break;
case 2:
//Up
N->visited[2]=0;
break;
case 3:
//Down
N->visited[3]=0;
break;
}
return N;
}
Matrix MoveBlank(Node root,int moveDir)
//Moving Blank and Giving new
{
int bRow;
int bCol;
int temp;
int cordtemp;
FindBlank(root.nMat,bRow,bCol);
Matrix Next;
CopyMat(root.nMat,Next);
switch(moveDir)
//Direction
{
case 0:
//Left
cordtemp=bCol-1;
temp=Next(bCol,bRow);
Next(bCol,bRow)=Next(cordtemp,bRow);
Next(cordtemp,bRow)=temp;
break;
case 1:
//Right
cordtemp=bCol+1;
temp=Next(bCol,bRow);
Next(bCol,bRow)=Next(cordtemp,bRow);
Next(bCol+1,bRow)=temp;
break;
case 2:
//Up
cordtemp=bRow-1;
temp=Next(bCol,bRow);
Next(bCol,bRow)=Next(bCol,cordtemp);
Next(bCol,cordtemp)=temp;
break;
case 3:
//Down
cordtemp=bRow+1;
temp=Next(bCol,bRow);
Next(bCol,bRow)=Next(bCol,cordtemp);
Next(bCol,cordtemp)=temp;
break;
}
return Next;
}
/*****************************PRIORITY QUEUE CLASS DEFINITION*****
***************************/
//store the fringe list and
find the next smallest statecost state
class prq
{
private:
struct nt{
int priority;
Node State;
struct nt *next;
};
struct nt *hdr;
public:
prq()
{
hdr=0;
}
~prq()
{
struct nt *n,*nn;
n=hdr;
while(n)
{
nn=n->next;
delete n;
n=nn;
}
hdr=0;
}
void push(Node N)
{
struct nt *p,*s,*prev;
p=new struct nt;
p->State=N;
p->next=0;
p->priority=N.stateCost;
if(hdr==0)
{
hdr=p;
return;
}
s=hdr;prev=0;
if((N.stateCost)<=(s->priority))
{
p->next=s;
hdr=p;
return;
}
while((s!=0)&&((N.stateCost)>(s->priority)))
{
prev=s;
s=s->next;
}
if(prev==0)
{
p->next=s;
hdr=p;
return;
}
prev->next=p;
p->next=s;
}
void pop()
{
struct nt *s;
s=hdr;
hdr=s->next;
delete s;
}
Node top()
{
struct nt *s;
s=hdr;
hdr=s->next;
return s->State;
}
int empty()
{
if(hdr==0)
return 1;
else
return 0;
}
};
/********************************************A - STAR*********************
************************/
void Astar(Node &root)
{
prq pq;
vector <Node> parent;
bool goalCheck;
bool alreadyVisited;
root.TpathCost++;
Node::expanded=0;
goalCheck=0;
//pq.push(root);
cout<<endl<<"/***********Initial State - Given by User***********/"<<endl<<
endl;
root.nMat.printmatrix();
cout<<endl<<"/***Runing A Star***/"<<endl<<endl;
Matrix fMat(1);
while(!goalCheck)
{
for(int i=0;i<4;i++)
{
if(root.visited[i]==1)
{
Matrix nextMat;
nextMat=MoveBlank(root,i);
if(!parent.empty())
{
// cout<<endl<<"Parent Size :"<<parent.size()<<endl;
//Checking with child with all parents if itz already present
for(int j=0;j<parent.size();j++)
{
//cout<<endl<<"Parent Matrix :"<<endl;
// parent[j].nMat.printmatrix();
//cout<<endl<<"Checking With :"<<endl;
// nextMat.printmatrix();
if(parent[j].nMat == nextMat)
{
// cout<<"Found Match";
alreadyVisited=1;
break;
}
else
{
alreadyVisited=0;
}
}
}
// cout<<endl<<"Already Visited :"<<alreadyVisited<<endl<<endl
;
root.child[i]=createNode(nextMat,root.TpathCost,i);
goalCheck=root.child[i]->goalState;
if(!goalCheck)
//if not reached goal inserting child to fringe list
{
if(!alreadyVisited)
//if not visited or not present in parent matrix adding child to fringe
list
{
pq.push(*root.child[i]);
//parent.push_back(*root.child[i]);
root.expanded++;
//root.child[i]->nMat.printmatrix();
}
}
else
{
break;
}
}
}
if(!goalCheck)
{
int m;
m=pq.empty();
if(m==0)
{
root=pq.top();
}else
{
cout<<"Fringe List is Empty"<<endl<<endl;
return;
}
int k;
k=pq.empty();
if(k==0)
{
pq.pop();
}
cout<<"/**********Next State**********/"<<endl<<endl;
root.nMat.printmatrix();
cout<<endl<<endl;
cout<<endl<<"State Cost :"<<root.stateCost<<endl;
cout<<endl<<"Total Path Cost :"<<root.TpathCost<<endl;
cout<<endl<<"Total Expanded :"<<root.expanded<<endl<<endl;
parent.push_back(root);
root.TpathCost++;
//system("PAUSE");
cout<<endl<<endl;
}
else
{
parent.push_back(root);
}
}
cout<<endl<<"/*********Final State Reached**********/"<<endl<<endl;
fMat.printmatrix();
root.expanded++;
cout<<endl<<"Final Path Cost :"<<root.TpathCost<<endl;
cout<<endl<<endl<<"Total Number of Nodes Expanded :"<<root.expanded<<endl<<
endl<<endl;
}