0% found this document useful (0 votes)
6 views

Solution Uniform Cost Search in C++ Language Complete Code

The document contains implementations of various graph search algorithms including Uniform Cost Search, Breadth First Search, Bi-Directional Cost Search, and Depth First Search. Each algorithm is presented with C++ code that demonstrates how to create a graph, add edges, and perform the respective search. The document provides a clear structure for each algorithm, showcasing their functionality through example graphs and outputs.

Uploaded by

Dubstep Dance
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
6 views

Solution Uniform Cost Search in C++ Language Complete Code

The document contains implementations of various graph search algorithms including Uniform Cost Search, Breadth First Search, Bi-Directional Cost Search, and Depth First Search. Each algorithm is presented with C++ code that demonstrates how to create a graph, add edges, and perform the respective search. The document provides a clear structure for each algorithm, showcasing their functionality through example graphs and outputs.

Uploaded by

Dubstep Dance
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
You are on page 1/ 14

Uniform Cost Search

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

// graph
vector<vector<int> > graph;

// map to store cost of edges


map<pair<int, int>, int> cost;

// returns the minimum cost in a vector( if


// there are multiple goal states)
vector<int> uniform_cost_search(vector<int> goal, int start)
{
// minimum cost upto
// goal state from starting
// state
vector<int> answer;

// create a priority queue


priority_queue<pair<int, int> > queue;

// set the answer vector to max value


for (int i = 0; i < goal.size(); i++)
answer.push_back(INT_MAX);

// insert the starting index


queue.push(make_pair(0, start));

// map to store visited node


map<int, int> visited;

// count
int count = 0;

// while the queue is not empty


while (queue.size() > 0) {

// get the top element of the


// priority queue
pair<int, int> p = queue.top();
// pop the element
queue.pop();

// get the original value


p.first *= -1;

// check if the element is part of


// the goal list
if (find(goal.begin(), goal.end(), p.second) != goal.end()) {

// get the position


int index = find(goal.begin(), goal.end(),
p.second) - goal.begin();

// if a new goal is reached


if (answer[index] == INT_MAX)
count++;

// if the cost is less


if (answer[index] > p.first)
answer[index] = p.first;

// pop the element


queue.pop();

// if all goals are reached


if (count == goal.size())
return answer;
}

// check for the non visited nodes


// which are adjacent to present node
if (visited[p.second] == 0)
for (int i = 0; i < graph[p.second].size(); i++) {

// value is multiplied by -1 so that


// least priority is at the top
queue.push(make_pair((p.first +
cost[make_pair(p.second, graph[p.second][i])]) * -1,
graph[p.second][i]));
}

// mark as visited
visited[p.second] = 1;
}

return answer;
}

// main function
int main()
{
// create the graph
graph.resize(7);

// add edge
graph[0].push_back(1);
graph[0].push_back(3);
graph[3].push_back(1);
graph[3].push_back(6);
graph[3].push_back(4);
graph[1].push_back(6);
graph[4].push_back(2);
graph[4].push_back(5);
graph[2].push_back(1);
graph[5].push_back(2);
graph[5].push_back(6);
graph[6].push_back(4);

// add the cost


cost[make_pair(0, 1)] = 2;
cost[make_pair(0, 3)] = 5;
cost[make_pair(1, 6)] = 1;
cost[make_pair(3, 1)] = 5;
cost[make_pair(3, 6)] = 6;
cost[make_pair(3, 4)] = 2;
cost[make_pair(2, 1)] = 4;
cost[make_pair(4, 2)] = 4;
cost[make_pair(4, 5)] = 3;
cost[make_pair(5, 2)] = 6;
cost[make_pair(5, 6)] = 3;
cost[make_pair(6, 4)] = 7;

// goal state
vector<int> goal;

// set the goal


// there can be multiple goal states
goal.push_back(6);

// get the answer


vector<int> answer = uniform_cost_search(goal, 0);

// print the answer


cout << "Minimum cost from 0 to 6 is = "
<< answer[0] << endl;

return 0;
}

Breath First Search


#include<iostream>
#include <list>

using namespace std;

// This class represents a directed graph using


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

// Pointer to an array containing adjacency


// lists
list<int> *adj;
public:
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 = new list<int>[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
bool *visited = new bool[V];
for(int i = 0; i < V; i++)
visited[i] = 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);

// 'i' will be used to get all adjacent


// vertices of a vertex
list<int>::iterator i;

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 (i = adj[s].begin(); i != adj[s].end(); ++i)
{
if (!visited[*i])
{
visited[*i] = true;
queue.push_back(*i);
}
}
}
}

// 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;
}
Bi-Directional Cost Search
#include <bits/stdc++.h>
using namespace std;

// class representing undirected graph


// using adjacency list
class Graph
{
//number of nodes in graph
int V;

// Adjacency list
list<int> *adj;
public:
Graph(int V);
int isIntersecting(bool *s_visited, bool *t_visited);
void addEdge(int u, int v);
void printPath(int *s_parent, int *t_parent, int s,
int t, int intersectNode);
void BFS(list<int> *queue, bool *visited, int *parent);
int biDirSearch(int s, int t);
};

Graph::Graph(int V)
{
this->V = V;
adj = new list<int>[V];
};

// Method for adding undirected edge


void Graph::addEdge(int u, int v)
{
this->adj[u].push_back(v);
this->adj[v].push_back(u);
};

// Method for Breadth First Search


void Graph::BFS(list<int> *queue, bool *visited,
int *parent)
{
int current = queue->front();
queue->pop_front();
list<int>::iterator i;
for (i=adj[current].begin();i != adj[current].end();i++)
{
// If adjacent vertex is not visited earlier
// mark it visited by assigning true value
if (!visited[*i])
{
// set current as parent of this vertex
parent[*i] = current;

// Mark this vertex visited


visited[*i] = true;

// Push to the end of queue


queue->push_back(*i);
}
}
};

// check for intersecting vertex


int Graph::isIntersecting(bool *s_visited, bool *t_visited)
{
int intersectNode = -1;
for(int i=0;i<V;i++)
{
// if a vertex is visited by both front
// and back BFS search return that node
// else return -1
if(s_visited[i] && t_visited[i])
return i;
}
return -1;
};

// Print the path from source to target


void Graph::printPath(int *s_parent, int *t_parent,
int s, int t, int intersectNode)
{
vector<int> path;
path.push_back(intersectNode);
int i = intersectNode;
while (i != s)
{
path.push_back(s_parent[i]);
i = s_parent[i];
}
reverse(path.begin(), path.end());
i = intersectNode;
while(i != t)
{
path.push_back(t_parent[i]);
i = t_parent[i];
}

vector<int>::iterator it;
cout<<"*****Path*****\n";
for(it = path.begin();it != path.end();it++)
cout<<*it<<" ";
cout<<"\n";
};

// Method for bidirectional searching


int Graph::biDirSearch(int s, int t)
{
// boolean array for BFS started from
// source and target(front and backward BFS)
// for keeping track on visited nodes
bool s_visited[V], t_visited[V];

// Keep track on parents of nodes


// for front and backward search
int s_parent[V], t_parent[V];

// queue for front and backward search


list<int> s_queue, t_queue;

int intersectNode = -1;

// necessary initialization
for(int i=0; i<V; i++)
{
s_visited[i] = false;
t_visited[i] = false;
}

s_queue.push_back(s);
s_visited[s] = true;

// parent of source is set to -1


s_parent[s]=-1;

t_queue.push_back(t);
t_visited[t] = true;

// parent of target is set to -1


t_parent[t] = -1;

while (!s_queue.empty() && !t_queue.empty())


{
// Do BFS from source and target vertices
BFS(&s_queue, s_visited, s_parent);
BFS(&t_queue, t_visited, t_parent);

// check for intersecting vertex


intersectNode = isIntersecting(s_visited, t_visited);

// If intersecting vertex is found


// that means there exist a path
if(intersectNode != -1)
{
cout << "Path exist between " << s << " and "
<< t << "\n";
cout << "Intersection at: " << intersectNode << "\n";

// print the path and exit the program


printPath(s_parent, t_parent, s, t, intersectNode);
exit(0);
}
}
return -1;
}

// Driver code
int main()
{
// no of vertices in graph
int n=15;

// source vertex
int s=0;

// target vertex
int t=14;

// create a graph given in above diagram


Graph g(n);
g.addEdge(0, 4);
g.addEdge(1, 4);
g.addEdge(2, 5);
g.addEdge(3, 5);
g.addEdge(4, 6);
g.addEdge(5, 6);
g.addEdge(6, 7);
g.addEdge(7, 8);
g.addEdge(8, 9);
g.addEdge(8, 10);
g.addEdge(9, 11);
g.addEdge(9, 12);
g.addEdge(10, 13);
g.addEdge(10, 14);
if (g.biDirSearch(s, t) == -1)
cout << "Path don't exist between "
<< s << " and " << t << "\n";

return 0;
}
Depth First Search
#include<bits/stdc++.h>
using namespace std;

class Graph
{
int V; // No. of vertices
list<int> *adj; // Pointer to an array containing adjacency lists
void DFSUtil(int v, bool visited[]); // A function used by DFS
public:
Graph(int V); // Constructor
void addEdge(int v, int w); // function to add an edge to graph
void DFS(); // prints DFS traversal of the complete graph
};

Graph::Graph(int V)
{
this->V = V;
adj = new list<int>[V];
}

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


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

void Graph::DFSUtil(int v, bool visited[])


{
// 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])
DFSUtil(*i, visited);
}
// The function to do DFS traversal. It uses recursive DFSUtil()
void Graph::DFS()
{
// Mark all the vertices as not visited
bool *visited = new bool[V];
for (int i = 0; i < V; i++)
visited[i] = false;

// Call the recursive helper function to print DFS traversal


// starting from all vertices one by one
for (int i = 0; i < V; i++)
if (visited[i] == false)
DFSUtil(i, visited);
}

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 Depth First Traversaln";


g.DFS();

return 0;
}

You might also like