liveBook · Manning

Hillclimbing

As explained in Optimization Algorithms: AI techniques for design, planning, and control problems

A local search algorithm that repeatedly moves from a candidate solution to an improving neighboring solution.

Hill climbing is a local greedy search algorithm that repeatedly replaces a candidate solution with a better neighboring solution. For maximization it increases the objective; for minimization it decreases it. The process stops when no neighbor improves the current state. section 4.1 section 4.3.1

A basic minimization procedure is:

  • Start with an initial state or route. section 4.3.1
  • Generate neighboring states or successor routes. section 4.3.1
  • Evaluate the neighbors with a cost or heuristic function and select the best one. section 4.3.1
  • Move to that neighbor only when it improves the current solution; otherwise terminate. section 4.3.1

Hill climbing uses little memory and avoids examining an entire search tree, so it can be fast. It is non-exhaustive, however: local optima can prevent a global optimum, while plateaus can stop progress. Larger search spaces create more opportunities for these failures. section 4.3.1 section 4.4.1

Solving the 8-puzzle

Each puzzle state expands to neighboring states, and the algorithm chooses the state with the fewest misplaced tiles. The implementation checks solvability, records costs, plots search progress with Matplotlib, and visualizes the resulting solution. section 4.3.1

Routing between points of interest

A route begins randomly, then generates up to n child routes and selects the shortest. Increasing n from 20 to 100 requires more processing but produces better and more consistent results; one run reaches 806.892 m. section 4.4.1

Listing 4.7 U of T routing using the hill climbing algorithm
def Hill_Climbing(G, origin, destination, n=20):
    time_start = process_time()                                        #1
    costs = []                                                         #1
  
    current = randomized_search(G, origin.osmid, destination.osmid)    #2
    costs.append(cost(G, current))
  
    neighbours = list(islice(get_child(G, current), n))                #3
    space_required = getsizeof(neighbours)
    shortest = min(neighbours, key=lambda route: cost(G, route))
  
    while cost(G, shortest) < cost(G, current):
        current = shortest
        neighbours = list(islice(get_child(G, current), n))
        shortest = min(neighbours, key=lambda route: cost(G, route))
        costs.append(cost(G, current))
  
    route = current
    time_end = process_time()
    return Solution(route, time_end - time_start, space_required, costs)

Inspect the routing implementation to see randomized initialization, bounded neighbor generation, cost comparison, and the processing-time trade-off. section 4.4.1

How Optimization Algorithms: AI techniques for design, planning, and control problems covers it

How deep it goes
Defines neighbor-based improvement, gives pseudocode and implementations, then stops short of guaranteed global optimality.
Examples
Demonstrates route finding, an eight-puzzle solver, misplaced-tile costs, randomized routes, and neighborhood-size tuning.
What it assumes
Assumes basic graph or state-space search and heuristic evaluation while demonstrating these ideas through concrete examples.
What you can do after
Apply hill climbing by defining states, neighbors, and a cost function, then tuning neighborhood size for routing.
How it connects
Connects local search with informed search, greedy search, heuristics, graph search, routing, and optimization.

Also explained in

Compare how 2 books explain hillclimbing →

Related concepts

This explainer was generated by Manning's knowledge graph from the text of Optimization Algorithms: AI techniques for design, planning, and control problems. The section links point to the parts of the book it draws on.