Local Search Algorithm in Artificial Intelligence (original) (raw)

Last Updated : 25 May, 2026

Local Search Algorithms in Artificial Intelligence are optimization techniques that improve a solution by repeatedly moving to a better neighbouring state. Instead of exploring every possible path, they focus on finding efficient and practical solutions for complex problems.

Basic Terminologies

Working

**1. Pick a starting point: Start with a possible solution which is often random but sometimes based on rule.

**2. Find the Neighbours:

**3. Compare: Look around at all neighbors to see if any are better.

**4. Move: If a better neighbor exists, move to it, making it our new “current” solution.

**5. Repeat: Keep searching from the new point, following the same steps.

**6. Stop: When none of the neighbors are better or after enough tries.

2056958058

Working of Beam Search Algorithm

Types of Local Search Algorithms

1. Hill-Climbing Search Algorithm

Hill-Climbing search algorithm is a simple local search algorithm that continuously moves toward a better neighboring solution until no improvement is possible.

**Process:

**Pros:

**Cons:

import random

def f(x): return - (x - 3)**2 + 5

def hill_climb(): current_x = random.uniform(0, 6) step_size = 0.1 max_iterations = 100 for i in range(max_iterations): neighbors = [current_x + step_size, current_x - step_size] neighbors = [x for x in neighbors if 0 <= x <= 6] neighbor_scores = [f(x) for x in neighbors] best_neighbor_idx = neighbor_scores.index(max(neighbor_scores)) best_neighbor = neighbors[best_neighbor_idx] if f(best_neighbor) > f(current_x): current_x = best_neighbor else: break return current_x, f(current_x)

result_x, result_value = hill_climb() print(f"Found maximum at x = {result_x:.2f}, value = {result_value:.2f}")

`

**Output: Found maximum at x = 3.02, value = 5.00

2. Simulated Annealing

Simulated Annealing is a local search algorithm inspired by the heating and cooling process in metallurgy. It occasionally accepts worse solutions to escape local optima, with the acceptance probability decreasing over time.

**Process:

**Pros:

**Cons:

import math import random

def f(x): return - (x - 3)**2 + 5

def get_neighbor(x, step_size=0.1): return x + random.uniform(-step_size, step_size)

def simulated_annealing(): current_x = random.uniform(0, 6) best_x = current_x best_eval = f(current_x) temp = 10 max_iterations = 1000 for i in range(max_iterations): t = temp / float(i + 1) candidate = get_neighbor(current_x) candidate = max(0, min(6, candidate)) candidate_eval = f(candidate) if candidate_eval > best_eval or random.random() < math.exp((candidate_eval - best_eval) / t): current_x = candidate best_eval = candidate_eval best_x = current_x return best_x, f(best_x)

result_x, result_value = simulated_annealing() print(f"Best found x = {result_x:.2f}, value = {result_value:.2f}")

`

**Output: Best found x = 3.02, value = 4.96

3. Genetic Algorithms

Genetic Algorithms (GAs) are inspired by the process of natural selection and evolution. They work with a population of solutions and evolve them over time using genetic operators like selection, crossover and mutation.

**Process:

**Pros:

**Cons:

import random

def f(x): return - (x - 3)**2 + 5

def genetic_algorithm(): population = [random.uniform(0, 6) for _ in range(20)] max_generations = 50 for _ in range(max_generations): scores = [f(x) for x in population] best = population[scores.index(max(scores))] new_population = [best] # keep best while len(new_population) < len(population): parents = random.sample(population, 2) child = (parents[0] + parents[1]) / 2 # mutation: small random step if random.random() < 0.3: child += random.uniform(-0.2, 0.2) child = max(0, min(6, child)) new_population.append(child) population = new_population scores = [f(x) for x in population] best = population[scores.index(max(scores))] return best, f(best)

result_x, result_value = genetic_algorithm() print(f"Best found x = {result_x:.2f}, value = {result_value:.2f}")

`

**Output: Best found x = 3.00, value = 5.00

Tabu Search enhances local search by using a memory structure called the tabu list to avoid revisiting previously explored solutions. This helps to prevent cycling back to local optima and encourages exploration of new areas.

**Process:

**Pros:

**Cons:

import random

def f(x): return - (x - 3)**2 + 5

def tabu_search(): current_x = random.uniform(0, 6) tabu_list = [] tabu_size = 5 step_size = 0.1 max_iterations = 100 best_x = current_x best_eval = f(current_x) for _ in range(max_iterations): neighbors = [current_x + step_size, current_x - step_size] neighbors = [x for x in neighbors if 0 <= x <= 6 and x not in tabu_list] if not neighbors: break neighbor_scores = [f(x) for x in neighbors] best_neighbor_idx = neighbor_scores.index(max(neighbor_scores)) best_neighbor = neighbors[best_neighbor_idx] if f(best_neighbor) > best_eval: best_x, best_eval = best_neighbor, f(best_neighbor) tabu_list.append(current_x) if len(tabu_list) > tabu_size: tabu_list.pop(0) current_x = best_neighbor return best_x, f(best_x)

result_x, result_value = tabu_search() print(f"Best found x = {result_x:.2f}, value = {result_value:.2f}")

`

**Output: Best found x = 3.02, value = 5.00

Comparison of Local Search Algorithms

Feature Hill-Climbing Simulated Annealing Genetic Algorithm Tabu Search
Search Style Local search Probabilistic search Population-based search Memory-based search
Moves to Worse Solutions No Yes Yes Rarely
Avoids Local Optima No Yes Yes Yes
Speed Fast Moderate Slower Moderate
Best Use Case Small problems Problems with many local optima Complex optimization problems Problems with repeated states

Applications

Advantages

Limitations