Ilovepdf Merged
Ilovepdf Merged
PROBLEM DESCRIPTION: A standard BFS implementation puts each vertex of the graph into one
of two categories: Visited and Not Visited.The purpose of the
algorithm is to mark each vertex as visited while avoiding cycles.
ALGORITHM:
1. Define a sample graph as a dictionary, where keys are vertices, and values are lists of
adjacent vertices.
2. Call the bfs function with the graph and starting vertex (0).
3. Define two containers:
visited: A set to keep track of visited vertices to avoid revisiting them.
queue: A deque (double-ended queue) to implement the BFS exploration.
4. Add the root vertex to both visited and queue.
5. Create a loop that continues as long as the queue is not empty
i. Dequeue a vertex from the front of the queue.
ii. Print the vertex to show the traversal order.
iii. Iterate through all neighbors of the dequeued vertex in the graph.
▪ If a neighbor is not yet in the visited set, Add the neighbor to both visited and queue.
PROGRAM:
import
collections #
BFS algorithm
while queue:
# Dequeue a vertex from queue
vertex = queue.popleft()
print(str(vertex) + " ", end="")
OUTPUT:
PROBLEM DESCRIPTION: A* Search algorithm is one of the best and popular technique used in
path-finding and graph traversals.
ALGORITHM:
#parameters
#open_set (set) : Set of nodes to be explored
#closed_set (set): Set of explored nodes.
#g (dict): Store distances from the starting node to each explored node.
#parents (dict): Store parent nodes for each explored node, used for path reconstruction.
1. Define a graph ‘Graph_nodes’ as a dictionary, where Keys are nodes, and values are lists of
tuples containing neighboring nodes and their weights.
2. Call function ‘aStarAlgo’ with start_node and stop_node
3. Define set closed_set and dictionaries g and parents, Initialize open_set with the starting node
4. Set g value for the starting node to 0 (distance to itself) and its parent to itself.
5. Create a loop that continues as long as open_set is not empty:
i. The most promising node to explore next is the node with the lowest f-score. Use heuristic
function to explore the node with lowest f-score. Heuristic function returns the heuristic
estimates from given node to stop_node.
ii. If the current node is the stop_node or has no neighbors, it might be the end, pass
iii. Otherwise, iterates through all neighbors of the current node, get_neighbors function
retrieves the neighbors and their weights (distances) for a given node.
If the neighbor is not in open_set or closed_set, it's a new node to explore, so it's
added to open_set and its parent is set to the current node
Otherwise, neighbor already encountered:
➢ If the tentative distance from the start node to the neighbor is less than
the current distance stored for the neighbor, update the distance and set
the parent of the neighbor to the current node.
➢ If the neighbor is in closed_set, remove it from closed_set and add it back
to open_set for re-evaluation, considering the potentially better path.
6. If open_set becomes empty then no more nodes to explore, so print no path exists.
7. If the current node is the stop_node, then reconstruct the path by following the parent pointers
from the stop_node back to the start_node. Since traversal was backward, reverse and print the
path.
8. Remove the current node from open_set and add it to closed_set to mark it as explored.
PROGRAM:
def aStarAlgo(start_node, stop_node):
open_set = set(start_node)
closed_set = set()
g = {} #store distance from starting node
parents = {}# parents contains an adjacency map of all nodes
#distance of starting node from itself is zero
g[start_node] = 0
#start_node is root node i.e it has no parent nodes
#so start_node is set to its own parent node
parents[start_node] = start_node
#for each node m,compare its distance from start i.e g(m)
#from start through n node
else:
if g[m] > g[n] + weight:
#update g(m)
g[m] = g[n] + weight
#change parent of m to n
parents[m] = n
aStarAlgo('A', 'G')
OUTPUT:
PROBLEM DESCRIPTION: A standard DFS implementation puts each vertex of the graph into one
of two categories: Visited and Not Visited.The purpose of the
algorithmis to mark each vertex as visited while avoiding cycles.
ALGORITHM:
1. Define a sample graph as a dictionary, where keys are vertices, and values are sets of
adjacentvertices.
2. Call the dfs function with the graph and starting vertex ('0').
3. Checks if visited set is provided. If not, initialize an empty set visited.
4. Add the start vertex to the visited set to avoid revisiting it.
5. Print the current vertex.
6. Iterate through all unvisited neighbors of the current vertex in graph.
For each unvisited neighbor, Recursively call dfs with the neighbor as the new
startingvertex and the updated visited set.
PROGRAM:
# DFS algorithm
def dfs(graph, start,
visited=None):if visited is
None:
visited = set()
if start not in
visited:
visited.add(start)
print(start, end='
')
for next in graph[start]:
dfs(graph, next, visited)
PROBLEM DESCRIPTION: The Min-Max algorithm is used to choose the optimal move at any
point in a game (Game Theory)
ALGORITHM:
# Parameters:
# curDepth (int): Current depth in the recursion tree.
# nodeIndex (int): Index of the current node in the score array.
# maxTurn (bool): Indicates whether it's the maximizing player's
turn.# scores (list[int]): List containing scores for each leaf node.
# targetDepth (int): Maximum depth allowed for exploration.
1. Define a sample list ‘scores’ representing the potential values at the leaf nodes
2. Calculate the maximum depth (treeDepth) of the tree based on the number of scores in the
list,assuming a balanced binary tree.
3. Start with maximizing player by calling the minimax function with starting
parameterscurDepth=0, nodeIndex=0, maxTurn=True, scores, and treeDepth
i. If curDepth reaches the targetDepth, it means we've reached a leaf
nodereturn the score at that node.
ii. If it's the maximizing player's turn:
To ensure that maximizing player chooses the move that leads to the highest possible
score. Recursively explore both child nodes and return the maximum of their scores.
iii. If it's the minimizing player's turn:
To ensure that the minimizing player chooses the move that leads to the lowest
possiblescore for the maximizing player, Recursively explore both child nodes and
return the minimum of their scores.
4. Print the score returned by minimax function as the optimal value.
PROGRAM:
import math
# This function implements the MiniMax algorithm.
# Parameters:
# curDepth (int): Current depth in the recursion tree.
# nodeIndex (int): Index of the current node in the score array.
# maxTurn (bool): Indicates whether it's the maximizing player's
turn.# scores (list[int]): List containing scores for each leaf node.
# targetDepth (int): Maximum depth allowed for exploration.
def minimax(curDepth, nodeIndex, maxTurn, scores, targetDepth):
# Driver code
# Calculate the maximum depth of the tree based on the number of scores
# (assuming a balanced binary tree representation)
treeDepth = math.log(len(scores), 2)
# Print the optimal value (the score maximizing player can achieve)
print("The optimal value is : ", end="")
print(minimax(0, 0, True, scores, treeDepth))
OUTPUT:
PROBLEM DESCRIPTION: The n-queen puzzle is the problem of placing n queens on an nxn
chess
board such that no queen can attack another queen. The problem is
implemented without recursion.
ALGORITHM:
1. Create a QueenChessboard object with size n.
2. Initialize variables:
i. number_of_solutions: Counts the number of valid solutions found.
ii. row: Tracks the current row (starts at 0).
iii. column: Tracks the current column (starts at 0).
3. Create an iterative loop to keep searching for solutions until all possibilities are exhausted.
4. For placing the queens create an inner loop which iterates through columns in the current
row, For each column, Check if placing a queen in this column (next row) is safe using
is_this_column_safe_in_next_row.
i. If safe:
Place the queen by calling board.place_in_next_row(column).
Move to the next row (row += 1).
Reset column to 0 to start placing queens in the new row.
Break out of the inner loop since a safe queen placement was found.
ii. If not safe, move to the next column (column += 1)
5. If the inner loop finishes without finding a safe placement, For Backtracking check if all
rows have been filled.
i. if yes, a solution is found:
Print the chessboard using board.display().
Increment number_of_solutions.
Implements a small optimization to avoid unnecessary backtracking in the
last row Remove the queen from the current row using
board.remove_in_current_row() and Move back to previous row (row -= 1)
ii. If not all rows have been filled (row!= size)
Try to remove the queen from the previous row using
board.remove_in_current_row().
Move back to the previous row (row -= 1) and set the column to the next
position to try after removing the queen (1 + previous column)
6. Print the total number of solutions found.
PROGRAM:
class QueenChessBoard:
def init (self, size):
# board has dimensions size x size
self.size = size
# columns[r] is a number c if a queen is placed at row r and column c.
# columns[r] is out of range if no queen is place in row r.
# Thus after all queens are placed, they will be at positions
# (columns[0], 0), (columns[1], 1), ... (columns[size - 1], size - 1)
self.columns = []
def remove_in_current_row(self):
return self.columns.pop()
# check column
for queen_column in self.columns:
if column == queen_column:
return False
# check diagonal
for queen_row, queen_column in enumerate(self.columns):
if queen_column - queen_row == column - row:
return False
def solve_queen(size):
"""Display a chessboard for each possible configuration of placing n queens
on an n x n chessboard and print the number of such configurations.""" board
= QueenChessBoard(size)
number_of_solutions = 0
row = 0
column = 0
# iterate over rows of board
while True:
# place queen in next row
while column < size:
if board.is_this_column_safe_in_next_row(column):
board.place_in_next_row(column)
row += 1
column = 0 break
else:
column += 1
# small optimization:
# In a board that already has queens placed in all rows except #
the last, we know there can only be at most one position in #
the last row where a queen can be placed. In this case, there
# is a valid position in the last row. Thus we can backtrack two #
times to reach the second last row.
board.remove_in_current_row()
row -= 1
n = int(input('Enter n: '))
solve_queen(n)
OUTPUT:
PROBLEM DESCRIPTION: The n-queen puzzle is the problem of placing n queens on an nxn chess
board such that no queen can attack another queen. The problem is
implemented with back-tracking approach.
ALGORITHM:
1. Ask the user to input the value of 'n', the size of the chessboard
2. Create a chessboard list, ‘board’ and initialize it with zeroes.
3. Call the solve_n_queens function with the board and starting column (0).
If function returns True:
print ‘solution exist’ and print the solution
Else: print solution does not exist
4. Solve_n_queens takes ‘board’ and the current column ‘col’ as input and recursively searches for
solution.
i. If col is equal to the board size (N), all queens are placed successfully, so
return True.
ii. Iterate through all rows (i) in the current column.
▪ For each row, call is_safe to check if it's a valid position for the queen. is_safe checks
whether there is already a queen in same row, upper and lower diagonals of a specific
row and col position on board.
▪ If safe, place the queen in the board (board[i][col] = 1)
▪ Then, recursively call solve_n_queens with the next column (col + 1) to place the
remaining queens
▪ If placing the queen in the current row doesn't lead to a solution, backtrack by
removing the queen (board[i][col] = 0).
iii. If no valid row is found in the current column for placing the queen
return False
PROGRAM:
def is_safe(board, row, col):
N=len(board)
# Check this row on left side
for i in range(col):
if board[row][i] == 1:
return False
# Check upper diagonal on left side
for i, j in zip(range(row, -1, -1), range(col, -1, -1)):
if board[i][j] == 1:
return False
# Check lower diagonal on left side
for i, j in zip(range(row, N, 1), range(col, -1, -1)):
if board[i][j] == 1:
return False
return True
# Consider this column and try placing the queen in all rows one by onefor i
in range(N):
if is_safe(board, i, col):
# Place this queen in board[i][col]
board[i][col] = 1
# If placing queen in board[i][col] doesn't lead to a solution, then remove queen from board
board[i][col] = 0
# If queen can not be placed in any row in this column col then return false
return False
n = int(input('Enter n: '))
board = [[0 for _ in range(n)] for _ in range(n)]if
solve_n_queens(board, 0) == True:
print("solution exist")
for row in (board):
for column in (row):if
column == 1:
print('Q', end=' ')
else:
print('.', end=' ')
print()
else:
print("Solution does not exist")
OUTPUT: