Sie sind auf Seite 1von 12

#include <cstdlib>

#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;
}
}
}
}

int mTiles(Matrix &mat)


//Find Total No. Of Misplaced Tiles
{
Matrix fMat(1);
int count=15;
for (int nRow=0; nRow<4; nRow++)
{
for (int nCol=0; nCol<4; nCol++)
{
if((mat(nCol,nRow)==fMat(nCol,nRow)) && (fMat(nCol,nRow)!=0))
{
count--;
}
}
}
return count;
}
bool checkGoalReached(Matrix &mat)
//Check If the matrix is the Goal State
{
int count=0;
Matrix fMat(1);

for (int nRow=0; nRow<4; nRow++)


{
for (int nCol=0; nCol<4; nCol++)
{
if((mat(nCol,nRow)==fMat(nCol,nRow)))
{
count++;
}
}
}
if(count==16)
{
return 1;
}
else
{
return 0;
}
}
/********************************************NODE STATE AND DEFIN
ITIONS****************************/
class Node
{
public:
Matrix nMat;
static int expanded;
int misplacedTiles;
//Heuristic
int TpathCost;
//Path Cost
int stateCost;
//Total Cost
Node *child[4]; /
/ child pointers to nodes
int visited[4]; /
/ blank can visit this nodes kind of boolean
bool goalState;
Node()
//Constructor for root node
{
int bRow,bCol;
//keep blank coordinates
Matrix cMat(0);
//take user input
CopyMat(cMat,nMat);
//copy user input to node matrix
goalState=checkGoalReached(nMat);
//check final goal alread reached
FindBlank(nMat,bRow,bCol);
//find blank coordinates
visit(bRow,bCol);
//setting available movements for blanks
stateCost=0;
//Initial Total Cost
TpathCost=0;
//Intial Path Cost
misplacedTiles=mTiles(nMat);
//Find No. of Misplaced Tiles in the Intial Node
}
Node(Matrix &Mat,int pathCost)
//Constructor for child node
{
int bRow,bCol;
//keep blank coordinates
CopyMat(Mat,nMat);
//after moving blank the next matrix copy to node matrix
FindBlank(Mat,bRow,bCol);
//find blank coordinates
visit(bRow,bCol);
//setting available movements for blanks
misplacedTiles=mTiles(nMat);
//Find No. of Misplaced Tiles in the Intial Node
TpathCost=pathCost;
stateCost=misplacedTiles+TpathCost;
//total cost till that node
goalState=checkGoalReached(nMat);
//check if goal reached
for(int i=0;i<4;i++)
//setting childs as 0
{
child[i]=0;
}
}
Node(int a)
//0 parameter node all assigned to 0
{
if(a==0)
{
stateCost=0;
misplacedTiles=0;
TpathCost=0;
stateCost=0;
for(int i=0;i<4;i++)
{
child[i]=0;
visited[i]=0;
}
}
}
bool operator<(const Node&) const; //overloaded < operato
r
void visit(int row,int col)
//fixing the blank where he can visit
{
if(row==0)
{
visited[2]=0;
//cout<<"Cannot Visit Up"<<endl;
}
else
{
visited[2]=1;
//cout<<"Can Visit Up"<<endl;
}
if(col==0)
{
visited[0]=0;
//cout<<"Cannot Visit Left"<<end
l;
}
else
{
visited[0]=1;
//cout<<"Can Visit Left"<<endl;
}
if(col==3)
{
visited[1]=0;
//cout<<"Cannot Visit Right"<<en
dl;
}
else
{
visited[1]=1;
//cout<<"Can Visit Right"<<endl;
}
if(row==3)
{
visited[3]=0;
//cout<<"Cannot Visit Down"<<end
l;
}
else
{
visited[3]=1;
//cout<<"Can Visit Down"<<endl;
}
}
Node& Node::operator= (const Node &cSource);
Node::Node(const Node &cSource);
};
int Node::expanded;
Node::Node(const Node &cSource)
//copy constructor
{
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];
}
}
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;
}

int main(int argc, char *argv[])


{
Matrix nMat(3);
Node root(nMat,0);
Astar(root);
system("PAUSE");
return EXIT_SUCCESS;
}

Das könnte Ihnen auch gefallen