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

Search Algorithm Assignment !

The document contains code to solve various search and optimization problems using algorithms like depth-first search, hill climbing, genetic algorithms, and iterative deepening. These include finding a mother vertex in a graph, solving the 8 puzzle problem, implementing different types of hill climbing, using a genetic algorithm to solve the traveling salesman problem, processing large graph data incrementally, and performing iterative deepening search on a graph.

Uploaded by

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

Search Algorithm Assignment !

The document contains code to solve various search and optimization problems using algorithms like depth-first search, hill climbing, genetic algorithms, and iterative deepening. These include finding a mother vertex in a graph, solving the 8 puzzle problem, implementing different types of hill climbing, using a genetic algorithm to solve the traveling salesman problem, processing large graph data incrementally, and performing iterative deepening search on a graph.

Uploaded by

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

Assignment 1

Name - Anurag Kumar Q id - 20030197


Subject - Search Algorithm Branch/ Semester - CSE AIML / 7th

# Write a code to find the mother vertex

graph = {
'A': ['B', 'C', 'D', 'F'],
'B': ['C', 'D'],
'C': ['F'],
'D': [],
'F': []
# 0:[],
# 1:[0,4],
# 2:[5],
# 3:[1,2,6],
# 4:[3],
# 5:[0],
# 6:[]
}

def is_mother_vertex(graph, v):

visited = set()
dfs(graph, v, visited)

for vertex in graph:


if vertex not in visited:
return False

return True

def dfs(graph, v, visited):

visited.add(v)
for neighbor in graph[v]:
if neighbor not in visited:
dfs(graph, neighbor, visited)

mother_vertex = None
for vertex in list(graph.keys()):
if is_mother_vertex(graph, vertex):
mother_vertex = vertex
break

if mother_vertex is not None:


print("The mother vertex is", mother_vertex)
else:
print("There is no mother vertex.")

Output -
The mother vertex is A
# Write a code to implement eight puzzle algorithm

import heapq

class PuzzleNode:
def __init__(self, state, parent=None, move=None, cost=0):
self.state = state
self.parent = parent
self.move = move
self.cost = cost
self.heuristic = self.calculate_heuristic()

def calculate_heuristic(self):
total_distance = 0
for i in range(3):
for j in range(3):
if self.state[i][j] != 0:
goal_row, goal_col = divmod(self.state[i][j] - 1, 3)
total_distance += abs(i - goal_row) + abs(j - goal_col)
return total_distance

def __lt__(self, other):


return (self.cost + self.heuristic) < (other.cost + other.heuristic)

def get_neighbors(node):
neighbors = []
empty_row, empty_col = find_empty_space(node.state)

moves = [(0, 1), (0, -1), (1, 0), (-1, 0)]


for move in moves:
new_row, new_col = empty_row + move[0], empty_col + move[1]
if 0 <= new_row < 3 and 0 <= new_col < 3:
new_state = [list(row) for row in node.state]
new_state[empty_row][empty_col], new_state[new_row][new_col] = new_state[new_row]
[new_col], 0
neighbors.append(PuzzleNode(tuple(map(tuple, new_state)), parent=node, move=(new_row,
new_col), cost=node.cost + 1))

return neighbors

def find_empty_space(state):
for i in range(3):
for j in range(3):
if state[i][j] == 0:
return i, j

def is_goal(state):
return state == ((1, 2, 3), (4, 5, 6), (7, 8, 0))

def solve_puzzle(initial_state):
initial_node = PuzzleNode(tuple(map(tuple, initial_state)))
priority_queue = [initial_node]
visited = set()

while priority_queue:
current_node = heapq.heappop(priority_queue)

if current_node.state in visited:
continue

visited.add(current_node.state)

if is_goal(current_node.state):
path = []
while current_node:
path.append(current_node.state)
current_node = current_node.parent
return reversed(path)

neighbors = get_neighbors(current_node)
for neighbor in neighbors:
heapq.heappush(priority_queue, neighbor)

return None

initial_state = [[1, 2, 3], [4, 0, 5], [7, 8, 6]]


solution = solve_puzzle(initial_state)

if solution:
print("Solution found:")
for step, state in enumerate(solution):
print(f"Step {step + 1}:")
for row in state:
print(row)
print()
else:
print("No solution found.")

Output -
Solution found:
Step 1:
(1, 2, 3)
(4, 0, 5)
(7, 8, 6)

Step 2:
(1, 2, 3)
(4, 5, 0)
(7, 8, 6)

Step 3:
(1, 2, 3)
(4, 5, 6)
(7, 8, 0)
# Write a code to implement types of hill climbing

import random

def simple_hill_climbing(initial_state, max_iterations):


current_state = initial_state

for _ in range(max_iterations):
neighbors = get_neighbors(current_state)
best_neighbor = max(neighbors, key=evaluate_fitness)

if evaluate_fitness(best_neighbor) <= evaluate_fitness(current_state):


break

current_state = best_neighbor

return current_state

def steepest_ascent_hill_climbing(initial_state, max_iterations):


current_state = initial_state

for _ in range(max_iterations):
neighbors = get_neighbors(current_state)
best_neighbor = max(neighbors, key=evaluate_fitness)

if evaluate_fitness(best_neighbor) <= evaluate_fitness(current_state):


break

current_state = best_neighbor

return current_state

def get_neighbors(state):
return [state + 1, state - 1]

def evaluate_fitness(state):
return -abs(state - 5)

initial_state = random.randint(0, 10)


max_iterations = 100

print("Simple Hill Climbing:")


result_simple = simple_hill_climbing(initial_state, max_iterations)
print("Final State:", result_simple)
print("Fitness:", evaluate_fitness(result_simple))
print()

print("Steepest-Ascent Hill Climbing:")


result_steepest = steepest_ascent_hill_climbing(initial_state, max_iterations)
print("Final State:", result_steepest)
print("Fitness:", evaluate_fitness(result_steepest))

Output -

Simple Hill Climbing:


Final State: 5
Fitness: 0

Steepest-Ascent Hill Climbing:


Final State: 5
Fitness: 0
# Write generative algorithm to solve traveling salesman problem

import random
import numpy as np

class TSPGeneticAlgorithm:
def __init__(self, num_cities, population_size, generations, mutation_rate):
self.num_cities = num_cities
self.population_size = population_size
self.generations = generations
self.mutation_rate = mutation_rate
self.distances = np.zeros((num_cities, num_cities))
self.generate_random_distances()
self.population = self.initialize_population()

def generate_random_distances(self):
for i in range(self.num_cities):
for j in range(i + 1, self.num_cities):
self.distances[i][j] = self.distances[j][i] = random.randint(1, 100)

def initialize_population(self):
return [np.random.permutation(self.num_cities) for _ in range(self.population_size)]

def evaluate_fitness(self, route):


total_distance = sum(self.distances[route[i]][route[i + 1]] for i in range(self.num_cities - 1))
total_distance += self.distances[route[-1]][route[0]]
return 1 / total_distance

def crossover(self, parent1, parent2):


crossover_point = random.randint(1, self.num_cities - 1)
child = np.zeros(self.num_cities, dtype=int)
child[:crossover_point] = parent1[:crossover_point]
idx = crossover_point
for gene in parent2:
if gene not in child:
child[idx] = gene
idx += 1
if idx == self.num_cities:
break
return child

def mutate(self, route):


if random.random() < self.mutation_rate:
idx1, idx2 = random.sample(range(self.num_cities), 2)
route[idx1], route[idx2] = route[idx2], route[idx1]

def evolve_population(self):
new_population = []
best_route = max(self.population, key=self.evaluate_fitness)
new_population.append(best_route)
while len(new_population) < self.population_size:
parent1, parent2 = random.sample(self.population, 2)
child = self.crossover(parent1, parent2)
self.mutate(child)
new_population.append(child)
self.population = new_population

def find_best_route(self):
for _ in range(self.generations):
self.evolve_population()
return max(self.population, key=self.evaluate_fitness)

num_cities = 10
population_size = 100
generations = 1000
mutation_rate = 0.01

tsp_genetic_algorithm = TSPGeneticAlgorithm(num_cities, population_size, generations,


mutation_rate)
best_route = tsp_genetic_algorithm.find_best_route()

print("Best Route:", best_route)


print("Best Fitness:", tsp_genetic_algorithm.evaluate_fitness(best_route))

Output -

Best Route: [8 7 5 9 6 2 4 3 1 0]
Best Fitness: 0.004016064257028112
# Web spidering / Scrolling

class Node:
def __init__(self, node_id, data_size):
self.node_id = node_id
self.data = bytearray(data_size)

def process_large_graph(nodes):
for node in nodes:
process_data(node.data)

def process_data(data):
pass

def main():
num_nodes = 5
data_size_per_node = 100 * 1024 * 1024

nodes = [Node(node_id=i, data_size=data_size_per_node) for i in range(num_nodes)]

process_large_graph(nodes)

if __name__ == "__main__":
main()
# Perform Iterative_deepening on a graph

graph = {
1: [2, 3, 4],
2: [5, 6, 7],
3: [8],
4: [9, 10],
5: [11, 12],
6: [13],
7: [14],
8: [15],
9: [15, 16],
10: [17]
}

def iterative_deepening_dfs(start, goal):


for depth_limit in range(1, len(graph)):
visited = set()
path = []
if depth_limited_dfs(start, goal, depth_limit, visited, path):
return path
return None

def depth_limited_dfs(current, goal, depth_limit, visited, path):


if current == goal:
path.append(current)
return True

if depth_limit <= 0:
return False

visited.add(current)
path.append(current)

for neighbor in graph.get(current, []):


if neighbor not in visited:
if depth_limited_dfs(neighbor, goal, depth_limit - 1, visited, path):
return True

path.pop()
return False

start_node = 1
goal_node = 15
result = iterative_deepening_dfs(start_node, goal_node)

if result:
print(f"Path from {start_node} to {goal_node}: {result}")
else:
print(f"No path found from {start_node} to {goal_node} within depth limit.")
Output -

Path from 1 to 15: [1, 3, 8, 15]

You might also like