start with an initial solution evaluate its score while stopping condition is not met: generate candidate solutions compare scores choose whether to move update the current solution return the best solution found