You are on page 1of 27

Shri Vaishnav Vidyapeeth Vishwavidyalaya ,Indore

Shri Vaishnav Institute of Technology and Science

Department of Electrical & Electronic Engineering

(Session: - July-2022)

LAB FILE
Subject: - Artificial Intelligence for Robotics
Enrollment No: 19010BTRA05886

Course Code: BTRA701


IV-Year/VII-Semester

Submitted By: Submitted To: -


Yogesh Prajapat Dr. Gaurav Makwana Sir
Shri Vaishnav Vidyapeeth Vishwavidyalaya ,Indore

Shri Vaishnav Institute Technology of Science

Department of Electrical & Elctronic Engineering

(Session: - July-2022)
INDEX
Batch:- B3 Roll no:- 20100BTCSE07611 Name:-Pranav Mathur
S.no. Date of Code of Title Remarks
performing Experiment
01 Write a Program To Implement Depth First Search
1 09/09/2022.
.

2 23/09/2022 02 Write A Program To Implement Breadth First


search.
Write A Program To Implement Best First search.
3 30/09/2022 03

Write a Program To Implement A*Search


4 14/10/2022 04 Algorithm.

Write a Program To Implement Alpha Beta Pruning


5 21/10/2022 05 for Game Search .

Write a Program To Implement Mini-Max


Algorithm for Game Search .
6 04/11/2022 06

07 Write a Program To Implement 8-puzzle Informed


7 14/11/2022 Search.
Experiment: 01

Write a Program To Implement Depth First Search.

• CODE: -

#include <bits/stdc++.h> using


namespace std;

// Graph class represents a directed graph


// using adjacency list representation class Graph
public:
map<int, bool> visited;
map<int, list<int> > adj;

// function to add an edge to graph void addEdge(int v,


int w);

// DFS traversal of the vertices


// reachable from v
void DFS(int v);
};

void Graph::addEdge(int v, int w)


{
adj[v].push_back(w); // Add w to v’s list.
}

void Graph::DFS(int v)
{
// Mark the current node as visited and

// print it
visited[v] =
true; cout << v
<< " ";

// Recur for all the vertices adjacent


// to this vertex
list<int>::iterator i;
for (i = adj[v].begin(); i != adj[v].end(); ++i) if (!visited[*i])
DFS(*i);
}

// Driver's
code int
main()
{
// Create a graph given in the above diagram Graph g;
g.addEdge(0, 1);
g.addEdge(0, 2);

g.addEdge(1, 2);
g.addEdge(2, 0);
g.addEdge(2, 3);
g.addEdge(3, 3);
cout << "Following is Depth First Traversal" " (starting from vertex 2) \n";
// Function
call
g.DFS(2);
return 0;
}

• Output:

Experiment:02

Write A Program To Implement Breadth First Search. CODE: -

#include<bits/stdc++.h> using
namespace std;

// This class represents a directed graph using


// adjacency list representation class Graph
{
int V; // No. of vertices

public:

};
// Pointer to an array containing adjacency
// lists vector<list<int>> adj;

Graph(int V); // Constructor


// function to add an edge to graph void addEdge(int v, int w);
// prints BFS traversal from a given source s void BFS(int s);
Graph::Graph(int V)
{
this->V
= V;
adj.resiz
e(V);

void Graph::addEdge(int v, int w)


{
adj[v].push_back(w); // Add w to v’s list.
}

void Graph::BFS(int s)
{
// Mark all the vertices as not visited vector<bool> visited;
visited.resize(V,false);

// Create a queue for BFS list<int>


queue;

// Mark the current node as visited and enqueue it visited[s] = true;


queue.push_back(s);

while(!queue.empty())
{
// Dequeue a vertex from queue and print it s = queue.front();
cout << s << " ";
queue.pop_front();

// Get all adjacent vertices of the dequeued


// vertex s. If a adjacent has not been visited,
// then mark it visited and enqueue it for (auto adjecent:
adj[s])

{
if (!visited[adjecent])
{
visited[adjecent] = true; queue.push_back(adjecent);
}
}
}
}

// Driver program to test methods of graph class int main()


{
// Create a graph given in the above diagram Graph g(4);
g.addEdge(0, 1);
g.addEdge(0, 2);
g.addEdge(1, 2);
g.addEdge(2, 0);
g.addEdge(2, 3);
g.addEdge(3, 3);
cout << "Following is Breadth First Traversal "
<< "(starting from vertex 2) \n"; g.BFS(2);
return 0;
}

• Output

Experiment 03

Write a Program To Implement Best First Search.

• CODE: -

// C++ program to implement Best First Search using priority


// queue
#include <bits/stdc++.h> using
namespace std; typedef pair<int,
int> pi;
vector<vector<pi> > graph;

// Function for adding edges to graph void addedge(int x, int


y, int cost)
{
graph[x].push_back(make_pair(cost, y));
graph[y].push_back(make_pair(cost, x));
// Function For Implementing Best First Search
// Gives output path having lowest cost
void best_first_search(int actual_Src, int target, int n)
{
vector<bool> visited(n, false);
// MIN HEAP priority queue
priority_queue<pi, vector<pi>, greater<pi> > pq;
// sorting in pq gets done by first value of pair pq.push(make_pair(0,
actual_Src));
int s = actual_Src;
visited[s] = true; while
(!pq.empty()) {
int x = pq.top().second;
// Displaying the path having lowest cost cout << x << " ";
pq.pop();
if (x == target)
break;
for (int i = 0; i < graph[x].size(); i++) { if
(!visited[graph[x][i].second]) {
visited[graph[x][i].second] = true;

econd));

}
pq.push(make_pair(graph[x][i].first,graph[x][i].s

}
}
}

// Driver code to test above methods int main()


{
// No. of
Nodes int v
= 14;
graph.resize(
v);

alphabets) are

// The nodes shown in above example(by

// implemented using integers addedge(x,y,cost); addedge(0, 1, 3);

addedge(0, 2, 6);
addedge(0, 3, 5);
addedge(1, 4, 9);
addedge(1, 5, 8);
addedge(2, 6, 12);
addedge(2, 7, 14);
addedge(3, 8, 7);
addedge(8, 9, 5);
addedge(8, 10, 6);
addedge(9, 11, 1);
addedge(9, 12, 10);
addedge(9, 13, 2);

int source
= 0; int
target = 9;

// Function call best_first_search(source, target, v);

return 0;
}

• Output

Experiment 04

Write a Program To Implement A* Search

• CODE: -

// A C++ Program to implement A* Search Algorithm #include <bits/stdc++.h>


using namespace std;
#define ROW 9
#define COL 10
// Creating a shortcut for int, int pair type typedef pair<int, int> Pair;
// Creating a shortcut for pair<int, pair<int, int>> type typedef pair<double, pair<int, int> > pPair;
// A structure to hold the necessary parameters struct cell {
// Row and Column index of its parent
// Note that 0 <= i <= ROW-1 & 0 <= j <= COL-1 int parent_i, parent_j;
// f = g +
h double
f, g, h;
};
// A Utility Function to check whether given cell (row, col)
// is a valid cell or not.
bool isValid(int row, int col)

{
// Returns true if row number and column number
// is in range
return (row >= 0) && (row < ROW) && (col >= 0) && (col < COL);
}

// A Utility Function to check whether the given cell is


// blocked or not
bool isUnBlocked(int grid[][COL], int row, int col)
{
// Returns true if the cell is not blocked else false if (grid[row][col] == 1)
return
(true); else
return (false);
}

// A Utility Function to check whether destination cell has


// been reached or not
bool isDestination(int row, int col, Pair dest)
{
if (row == dest.first && col == dest.second) return (true);
else
return (false);
}

// A Utility Function to calculate the 'h' heuristics. double calculateHValue(int row, int col, Pair
dest)
{

// Return using the distance formula return ((double)sqrt(


(row - dest.first) * (row - dest.first)
+ (col - dest.second) * (col - dest.second)));
}
// A Utility Function to trace the path from the source
// to destination
void tracePath(cell cellDetails[][COL], Pair dest)
{
printf("\nThe Path is "); int
row = dest.first;
int col = dest.second;

stack<Pair> Path;

while (!(cellDetails[row][col].parent_i == row


&& cellDetails[row][col].parent_j == col)) { Path.push(make_pair(row, col));
int temp_row = cellDetails[row][col].parent_i; int temp_col =
cellDetails[row][col].parent_j; row = temp_row;
col = temp_col;
}

Path.push(make_pair(row, col)); while


(!Path.empty()) {
pair<int, int> p = Path.top(); Path.pop();
printf("-> (%d,%d) ", p.first, p.second);
}

return;
}

// A Function to find the shortest path between


// a given source cell to a destination cell according
// to A* Search Algorithm

void aStarSearch(int grid[][COL], Pair src, Pair dest)


{
// If the source is out of range
if (isValid(src.first, src.second) == false) { printf("Source is invalid\n");
return;
}

// If the destination is out of range


if (isValid(dest.first, dest.second) == false) { printf("Destination is
invalid\n");
return;
}

// Either the source or the destination is blocked


if (isUnBlocked(grid, src.first, src.second) == false

|| isUnBlocked(grid, dest.first, dest.second)


== false) {
printf("Source or the destination is blocked\n"); return;
}

// If the destination cell is the same as source cell if (isDestination(src.first, src.second,


dest)

== true) {
printf("We are already at the destination\n"); return;
}

// Create a closed list and initialise it to false which


// means that no cell has been included yet This closed
// list is implemented as a boolean 2D array bool closedList[ROW][COL];
memset(closedList, false, sizeof(closedList));
// Declare a 2D array of structure to hold the details
// of that cell
cell cellDetails[ROW][COL]; int i, j;

for (i = 0; i < ROW; i++) { for (j = 0; j <


COL; j++) {
cellDetails[i][j].f = FLT_MAX; cellDetails[i][j].g
= FLT_MAX; cellDetails[i][j].h = FLT_MAX;
cellDetails[i][j].parent_i = -1;
cellDetails[i][j].parent_j = -1;
}
}

// Initialising the parameters of the starting node i = src.first, j = src.second;


cellDetails[i][j].f = 0.0;
cellDetails[i][j].g = 0.0;

cellDetails[i][j].h = 0.0;
cellDetails[i][j].parent_i = i;
cellDetails[i][j].parent_j = j;
/*
Create an open list having information as-
<f, <i, j>>
where f = g
+ h,
and i, j are the row and column index of that cell Note that 0 <= i <= ROW-1 & 0 <= j
<= COL-1 This open list is implemented as a set of pair of pair.*/
set<pPair> openList;

// Put the starting cell on the open list and set its
// 'f' as 0
openList.insert(make_pair(0.0, make_pair(i, j)));

// We set this boolean value as false as initially


// the destination is not reached. bool foundDest
= false;

while (!openList.empty()) { pPair p =


*openList.begin();

// Remove this vertex from the open list openList.erase(openList.begin());

// Add this vertex to the closed list i = p.second.first;


j = p.second.second;

closedList[i][j] = true;

/*
Generating all the 8 successor of this cell

N.W N N.E
\|/

\|/
W----Cell--- E
/|\
/|\
S.W S S.E

Cell-->Popped Cell (i, j) N -->


North

(i-1, j)
S --> South (i+1, j)
E --> East (i, j+1)
W --> West (i, j-1)
N.E--> North-East (i-1, j+1)
N.W--> North-West (i-1, j-1) S.E--> South-East
(i+1, j+1) S.W--> South-West (i+1, j-1)*/

// To store the 'g', 'h' and 'f' of the 8 successors double gNew, hNew, fNew;

//----------- 1st Successor (North) ------------

// Only process this cell if this is a valid one if (isValid(i - 1, j) == true) {


// If the destination cell is the same as the

// current successor
if (isDestination(i - 1, j, dest) == true) {
// Set the Parent of the destination cell cellDetails[i - 1][j].parent_i =
i; cellDetails[i - 1][j].parent_j = j; printf("The destination cell is
found\n"); tracePath(cellDetails, dest);
foundDest =
true; return;
}
// If the successor is already on the closed

// list or if it is blocked, then ignore it.


// Else do the following
else if (closedList[i - 1][j] == false
&& isUnBlocked(grid, i - 1, j)
== true) {
gNew = cellDetails[i][j].g + 1.0; hNew = calculateHValue(i - 1,
j, dest); fNew = gNew + hNew;

// If it isn’t on the open list, add it to


// the open list. Make the current square
// the parent of this square. Record the
// f, g, and h costs of the square cell
// OR
// If it is on the open list already, check
// to see if this path to that square is
// better, using 'f' cost as the measure. if (cellDetails[i - 1][j].f ==
FLT_MAX
|| cellDetails[i - 1][j].f > fNew) {
openList.insert(make_pair(

fNew, make_pair(i - 1, j)));

// Update the details of this cell cellDetails[i -


1][j].f = fNew; cellDetails[i - 1][j].g = gNew;
cellDetails[i - 1][j].h = hNew; cellDetails[i -
1][j].parent_i = i; cellDetails[i - 1][j].parent_j =
j;
}
}
}

//----------- 2nd Successor (South) ------------


// Only process this cell if this is a valid one if (isValid(i + 1, j) == true) {
// If the destination cell is the same as the
// current successor
if (isDestination(i + 1, j, dest) == true) {
// Set the Parent of the destination cell cellDetails[i + 1][j].parent_i
= i; cellDetails[i + 1][j].parent_j = j; printf("The destination cell is
found\n"); tracePath(cellDetails, dest);
foundDest =
true; return;
}
// If the successor is already on the closed
// list or if it is blocked, then ignore it.
// Else do the following
else if (closedList[i + 1][j] == false

&& isUnBlocked(grid, i + 1, j)
== true) {
gNew = cellDetails[i][j].g + 1.0;
hNew = calculateHValue(i + 1, j, dest); fNew = gNew + hNew;

// If it isn’t on the open list, add it to


// the open list. Make the current square
// the parent of this square. Record the
// f, g, and h costs of the square cell
// OR
// If it is on the open list already, check
// to see if this path to that square is
// better, using 'f' cost as the measure. if (cellDetails[i + 1][j].f ==
FLT_MAX
|| cellDetails[i + 1][j].f > fNew) {
openList.insert(make_pair(
fNew, make_pair(i + 1, j)));
// Update the details of this cell cellDetails[i +
1][j].f = fNew; cellDetails[i + 1][j].g = gNew;
cellDetails[i + 1][j].h = hNew; cellDetails[i +
1][j].parent_i = i; cellDetails[i + 1][j].parent_j =
j;
}
}
}

//----------- 3rd Successor (East) ------------

// Only process this cell if this is a valid one


if (isValid(i, j + 1) == true) {
// If the destination cell is the same as the
// current successor
if (isDestination(i, j + 1, dest) == true) {
// Set the Parent of the destination cell cellDetails[i][j + 1].parent_i
= i; cellDetails[i][j + 1].parent_j = j; printf("The destination cell is
found\n"); tracePath(cellDetails, dest);
foundDest =
true; return;
}
// If the successor is already on the closed
// list or if it is blocked, then ignore it.

// Else do the following


else if (closedList[i][j + 1] == false
&& isUnBlocked(grid, i, j + 1)
== true) {
gNew = cellDetails[i][j].g + 1.0;
hNew = calculateHValue(i, j + 1, dest); fNew = gNew + hNew;

// If it isn’t on the open list, add it to


// the open list. Make the current square
// the parent of this square. Record the
// f, g, and h costs of the square cell
// OR
// If it is on the open list already, check
// to see if this path to that square is
// better, using 'f' cost as the measure.

if (cellDetails[i][j + 1].f == FLT_MAX


|| cellDetails[i][j + 1].f > fNew) {
openList.insert(make_pair(
fNew, make_pair(i, j + 1)));

// Update the details of this cell cellDetails[i][j +


1].f = fNew; cellDetails[i][j + 1].g = gNew;
cellDetails[i][j + 1].h = hNew; cellDetails[i][j +
1].parent_i = i; cellDetails[i][j + 1].parent_j = j;
}
}
}

//----------- 4th Successor (West) ------------

// Only process this cell if this is a valid one if (isValid(i, j - 1) == true) {


// If the destination cell is the same as the
// current successor
if (isDestination(i, j - 1, dest) == true) {
// Set the Parent of the destination cell cellDetails[i][j - 1].parent_i =
i; cellDetails[i][j - 1].parent_j = j; printf("The destination cell is
found\n"); tracePath(cellDetails, dest);
foundDest =
true; return;
}

// If the successor is already on the closed


// list or if it is blocked, then ignore it.
// Else do the following
else if (closedList[i][j - 1] == false
&& isUnBlocked(grid, i, j - 1)
== true) {
gNew = cellDetails[i][j].g + 1.0; hNew = calculateHValue(i, j -
1, dest); fNew = gNew + hNew;
// If it isn’t on the open list, add it to
// the open list. Make the current square
// the parent of this square. Record the
// f, g, and h costs of the square cell
// OR

// If it is on the open list already, check


// to see if this path to that square is
// better, using 'f' cost as the measure. if (cellDetails[i][j - 1].f ==
FLT_MAX
|| cellDetails[i][j - 1].f > fNew) {
openList.insert(make_pair(
fNew, make_pair(i, j - 1)));

// Update the details of this cell cellDetails[i][j -


1].f = fNew; cellDetails[i][j - 1].g = gNew;
cellDetails[i][j - 1].h = hNew; cellDetails[i][j -
1].parent_i = i; cellDetails[i][j - 1].parent_j = j;
}
}

//----------- 5th Successor (North-East)


//
// Only process this cell if this is a valid one if (isValid(i - 1, j + 1) == true)
{
// If the destination cell is the same as the
// current successor
if (isDestination(i - 1, j + 1, dest) == true) {
// Set the Parent of the destination cell cellDetails[i - 1][j +
1].parent_i = i; cellDetails[i - 1][j + 1].parent_j = j; printf("The
destination cell is found\n"); tracePath(cellDetails, dest);
foundDest =
true; return;
}

// If the successor is already on the closed


// list or if it is blocked, then ignore it.
// Else do the following
else if (closedList[i - 1][j + 1] == false
&& isUnBlocked(grid, i - 1, j + 1)
== true) {
gNew = cellDetails[i][j].g + 1.414;
hNew = calculateHValue(i - 1, j + 1, dest); fNew = gNew + hNew;

// If it isn’t on the open list, add it to


// the open list. Make the current square

// the parent of this square. Record the


// f, g, and h costs of the square cell
// OR
// If it is on the open list already, check
// to see if this path to that square is
// better, using 'f' cost as the measure.
if (cellDetails[i - 1][j + 1].f == FLT_MAX
|| cellDetails[i - 1][j + 1].f > fNew) {
openList.insert(make_pair(
fNew, make_pair(i - 1, j + 1)));

// Update the details of this cell cellDetails[i - 1][j + 1].f


= fNew; cellDetails[i - 1][j + 1].g = gNew; cellDetails[i -
1][j + 1].h = hNew; cellDetails[i - 1][j + 1].parent_i = i;
cellDetails[i - 1][j + 1].parent_j = j;
}
}
}

//----------- 6th Successor (North-West)


//

// Only process this cell if this is a valid one if (isValid(i - 1, j - 1) == true) {


// If the destination cell is the same as the
// current successor
if (isDestination(i - 1, j - 1, dest) == true) {
// Set the Parent of the destination cell cellDetails[i - 1][j -
1].parent_i = i;

cellDetails[i - 1][j - 1].parent_j = j; printf("The destination cell is


found\n"); tracePath(cellDetails, dest);
foundDest =
true; return;
}

// If the successor is already on the closed


// list or if it is blocked, then ignore it.
// Else do the following
else if (closedList[i - 1][j - 1] == false
&& isUnBlocked(grid, i - 1, j - 1)
== true) {
gNew = cellDetails[i][j].g + 1.414;
hNew = calculateHValue(i - 1, j - 1, dest); fNew = gNew + hNew;

// If it isn’t on the open list, add it to


// the open list. Make the current square

// the parent of this square. Record the


// f, g, and h costs of the square cell
// OR
// If it is on the open list already, check
// to see if this path to that square is
// better, using 'f' cost as the measure.
if (cellDetails[i - 1][j - 1].f == FLT_MAX
|| cellDetails[i - 1][j - 1].f > fNew) {
openList.insert(make_pair(
fNew, make_pair(i - 1, j - 1)));
// Update the details of this cell cellDetails[i - 1][j
- 1].f = fNew;
cellDetails[i - 1][j - 1].g = gNew; cellDetails[i - 1][j -
1].h = hNew; cellDetails[i - 1][j - 1].parent_i = i;
cellDetails[i - 1][j - 1].parent_j = j;
}
}
}

//----------- 7th Successor (South-East)


//

// Only process this cell if this is a valid one if (isValid(i + 1, j + 1) == true)


{
// If the destination cell is the same as the
// current successor
if (isDestination(i + 1, j + 1, dest) == true) {
// Set the Parent of the destination cell cellDetails[i + 1][j +
1].parent_i = i; cellDetails[i + 1][j + 1].parent_j = j; printf("The
destination cell is found\n"); tracePath(cellDetails, dest);
foundDest =
true; return;
}

// If the successor is already on the closed


// list or if it is blocked, then ignore it.
// Else do the following
else if (closedList[i + 1][j + 1] == false
&& isUnBlocked(grid, i + 1, j + 1)
== true) {

gNew = cellDetails[i][j].g + 1.414;


hNew = calculateHValue(i + 1, j + 1, dest); fNew = gNew + hNew;

// If it isn’t on the open list, add it to


// the open list. Make the current square
// the parent of this square. Record the
// f, g, and h costs of the square cell
// OR
// If it is on the open list already, check
// to see if this path to that square is
// better, using 'f' cost as the measure.
if (cellDetails[i + 1][j + 1].f == FLT_MAX
|| cellDetails[i + 1][j + 1].f > fNew) {
openList.insert(make_pair(
fNew, make_pair(i + 1, j + 1)));

// Update the details of this cell cellDetails[i + 1][j + 1].f =


fNew; cellDetails[i + 1][j + 1].g = gNew; cellDetails[i +
1][j + 1].h = hNew; cellDetails[i + 1][j + 1].parent_i = i;
cellDetails[i + 1][j + 1].parent_j = j;
}
}
}

//----------- 8th Successor (South-West)


//
// Only process this cell if this is a valid one
if (isValid(i + 1, j - 1) == true) {
// If the destination cell is the same as the
// current successor
if (isDestination(i + 1, j - 1, dest) == true) {
// Set the Parent of the destination cell cellDetails[i + 1][j -
1].parent_i = i; cellDetails[i + 1][j - 1].parent_j = j; printf("The
destination cell is found\n"); tracePath(cellDetails, dest);
foundDest =
true; return;
}

// If the successor is already on the closed


// list or if it is blocked, then ignore it.

// Else do the following


else if (closedList[i + 1][j - 1] == false && isUnBlocked(grid, i + 1, j - 1)== true) {
gNew = cellDetails[i][j].g + 1.414;
hNew = calculateHValue(i + 1, j - 1, dest); fNew = gNew + hNew;

// If it isn’t on the open list, add it to


// the open list. Make the current square
// the parent of this square. Record the
// f, g, and h costs of the square cell
// OR
// If it is on the open list already, check
// to see if this path to that square is
// better, using 'f' cost as the measure.

if (cellDetails[i + 1][j - 1].f == FLT_MAX


|| cellDetails[i + 1][j - 1].f > fNew) {
openList.insert(make_pair(
fNew, make_pair(i + 1, j - 1)));

// Update the details of this cell cellDetails[i + 1][j - 1].f


= fNew; cellDetails[i + 1][j - 1].g = gNew; cellDetails[i +
1][j - 1].h = hNew; cellDetails[i + 1][j - 1].parent_i = i;
cellDetails[i + 1][j - 1].parent_j = j;
}
}
}
}

// When the destination cell is not found and the open


// list is empty, then we conclude that we failed to
// reach the destination cell. This may happen when the

// there is no way to destination cell (due to


// blockages)
if (foundDest == false)
printf("Failed to find the Destination Cell\n");

return;
}
// Driver program to test above function int main()
{
/* Description of the Grid-

1--> The cell is not blocked 0--> The


cell is blocked */ int grid[ROW][COL]
= { { 1, 0, 1, 1, 1, 1, 0, 1, 1, 1 },
{ 1, 1, 1, 0, 1, 1, 1, 0, 1, 1 },
{ 1, 1, 1, 0, 1, 1, 0, 1, 0, 1 },
{ 0, 0, 1, 0, 1, 0, 0, 0, 0, 1 },
{ 1, 1, 1, 0, 1, 1, 1, 0, 1, 0 },
{ 1, 0, 1, 1, 1, 1, 0, 1, 0, 0 },
{ 1, 0, 0, 0, 0, 1, 0, 0, 0, 1 },
{ 1, 0, 1, 1, 1, 1, 0, 1, 1, 1 },
{ 1, 1, 1, 0, 0, 0, 1, 0, 0, 1 } };

// Source is the left-most bottom-most corner Pair src = make_pair(8, 0);

// Destination is the left-most top-most corner Pair dest = make_pair(0, 0);

aStarSearch(grid, src, dest);

return (0);
}

• Output: -
Experiment 05

Write a Program To Implement Alpha Beta Pruning for Game Search .

• CODE: -
// C++ program to demonstrate
// working of Alpha-Beta Pruning
#include<bits/stdc++.h>
using namespace std;

// Initial values of
// Alpha and Beta const
int MAX = 1000; const
int MIN = -1000;

// Returns optimal value for


// current player(Initially called
// for root and maximizer)
int minimax(int depth, int nodeIndex,
bool maximizingPlayer,
int values[], int alpha, int
beta)
{

// Terminating condition. i.e


// leaf node is
reached if (depth ==
3)
return values[nodeIndex];

if (maximizingPlayer)
{
int best = MIN;

// Recur for left and


// right children
for (int i = 0; i < 2; i++)
{

int val = minimax(depth + 1, nodeIndex * 2 + i,


false, values, alpha, beta);
best = max(best, val); alpha
= max(alpha, best);

// Alpha Beta
Pruning if (beta <=
alpha)
break;
}
}
else
{
return best;
int best = MAX;
// Recur for left and
// right children
for (int i = 0; i < 2; i++)
{
int val = minimax(depth + 1, nodeIndex * 2 + i,
true, values, alpha, beta);
best = min(best, val); beta = min(beta, best);

// Alpha Beta Pruning if (beta <= alpha)


break;
}
return best;
}

}
// Driver Code
int main()
{
int values[8] = { 3, 5, 6, 9, 1, 2, 0, -1 };
cout <<"The optimal value is : "<< minimax(0, 0, true, values, MIN, MAX);;
return 0;
}

OUTPUT:
Experiment: 06

Write a Program To Implement Mini-Max Algorithm for Game Search .

• CODE: -
// A simple C++ program to find
// maximum score that
// maximizing player can get.
#include<bits/stdc++.h> using
namespace std;

// Returns the optimal value a maximizer can obtain.


// depth is current depth in game tree.
// nodeIndex is index of current node in scores[].
// isMax is true if current move is
// of maximizer, else false
// scores[] stores leaves of Game tree.
// h is maximum height of Game tree
int minimax(int depth, int nodeIndex, bool isMax,
int scores[], int h)
{
// Terminating condition. i.e
// leaf node is
reached if (depth ==
h)
return scores[nodeIndex];

// If current move is maximizer,


// find the maximum attainable
// value
if (isMax)
return max(minimax(depth+1, nodeIndex*2, false, scores, h), minimax(depth+1, nodeIndex*2 + 1, false,
scores, h));

// Else (If current move is Minimizer), find the minimum


// attainable
value else
return min(minimax(depth+1, nodeIndex*2, true, scores, h), minimax(depth+1, nodeIndex*2 + 1, true, scores,
h));
}

// A utility function to find Log n in base 2 int log2(int n)


{
return (n==1)? 0 : 1 + log2(n/2);
}

//
Driv
er
code
int
main
()
{
// The number of elements in scores must be
// a power of 2.
int scores[] = {3, 5, 2, 9, 12, 5, 23, 23};
int n = sizeof(scores)/sizeof(scores[0]); int h = log2(n);
int res = minimax(0, 0, true, scores, h);
cout << "The optimal value is : " << res << endl; return 0;
}
OUTPUT:

Experiment: 07

Write a Program To Implement 8-puzzle Informed Search .

• CODE: -
#include <bits/stdc++.h>
using namespace std;
#define N 3

// state space tree nodes


struct Node
{
// stores the parent node of the current node
// helps in tracing path when the answer is found Node* parent;

//
stores
matrix
int
mat[N]
[N];

// stores blank tile coordinates int x,


y;
// stores the number of misplaced
tiles int cost;

// stores the number of moves so far int level;


};

// Function to print N x N matrix int


printMatrix(int mat[N][N])
{
for (int i = 0; i < N; i++)
{

for (int j = 0; j < N; j++) printf("%d


", mat[i][j]);
printf("\n");
}
}

// Function to allocate a new node


Node* newNode(int mat[N][N], int x, int y, int newX,
int newY, int level, Node* parent)
{
Node* node = new Node;

// set pointer for path to root


node->parent = parent;

// copy data from parent node to current node memcpy(node->mat,


mat, sizeof node->mat);

// move tile by 1 position


swap(node->mat[x][y], node->mat[newX][newY]);

// set number of misplaced tiles


node->cost = INT_MAX;

// set number of moves so far


node->level = level;

// update new blank tile coordinates node->x =


newX;
node->y = newY;

return node;
}

// bottom, left, top, right

int row[] = { 1, 0, -1, 0 };


int col[] = { 0, -1, 0, 1 };

// Function to calculate the number of misplaced tiles


// ie. number of non-blank tiles not in their goal position int calculateCost(int
initial[N][N], int final[N][N])
{
int count = 0;
for (int i = 0; i < N; i++)
for (int j = 0; j < N; j++)
if (initial[i][j] && initial[i][j] != final[i][j]) count++;
return count;
}

// Function to check if (x, y) is a valid matrix coordinate int isSafe(int x, int y)


{
return (x >= 0 && x < N && y >= 0 && y < N);
}

// print path from root node to destination node void printPath(Node* root)
{
if (root ==
N
U
L
L)
ret
ur
n;
printPath(root->parent);
printMatrix(root->mat);

printf("\n");
}

// Comparison object to be used to order the heap struct comp


{

bool operator()(const Node* lhs, const Node* rhs) const


{
return (lhs->cost + lhs->level) > (rhs->cost + rhs->level);
}
};

// Function to solve N*N - 1 puzzle algorithm using


// Branch and Bound. x and y are blank tile coordinates
// in initial state
void solve(int initial[N][N], int x, int y, int final[N][N])
{
// Create a priority queue to store live nodes of
// search tree;
priority_queue<Node*, std::vector<Node*>, comp> pq;

// create a root node and calculate its cost


Node* root = newNode(initial, x, y, x, y, 0, NULL); root->cost =
calculateCost(initial, final);

// Add root to list of live nodes;


pq.push(root);

// Finds a live node with least cost,


// add its childrens to list of live nodes and
// finally deletes it from the list. while
(!pq.empty())
{
// Find a live node with least estimated cost Node* min =
pq.top();
// The found node is deleted from the list of
//
li
v
e
n
o
d
e
s
p
q.
p
o
p
()
;

// if min is an answer node if


(min->cost == 0)
{
// print the path from root to destination; printPath(min);
return;
}

// do for each child of min


// max 4 children for a node for
(int i = 0; i < 4; i++)
{
if (isSafe(min->x + row[i], min->y + col[i]))
{
// create a child node and calculate
// its cost
Node* child = newNode(min->mat, min->x,
min->y, min->x + row[i],
min->y + col[i],
min->level + 1, min);
child->cost = calculateCost(child->mat, final);

// Add child to list of live nodes


pq.push(child);
}
}
}
}

//
Driv
er
code
int
main
()
{
// Initial configuration
// Value 0 is used for empty space int
initial[N][N] =

{
{1, 2, 3},
{5, 6, 0},
{7, 8, 4}
};

// Solvable Final configuration


// Value 0 is used for empty space int
final[N][N] =
{
{1, 2, 3},
{5, 8, 6},
{0, 7, 4}
};

// Blank tile coordinates in initial


//
configur
ation int
x = 1, y
= 2;

solve(initial, x, y, final);

return 0;
}

OUTPUT

You might also like