Improve the code.
- Add a docstring. - Add type hinting. - Change algorithm from steepest ascent to simple hill climbing.
This commit is contained in:
parent
667c19ecc3
commit
a060f93554
@ -1,53 +1,66 @@
|
|||||||
|
import copy
|
||||||
from typing import Tuple
|
from typing import Tuple
|
||||||
|
|
||||||
import numpy as np
|
import numpy as np
|
||||||
import numpy.typing as npt
|
import numpy.typing as npt
|
||||||
import copy
|
|
||||||
|
|
||||||
from common import plot_plan, read_data
|
from common import indexes_to_cities, plot_plan, read_data
|
||||||
|
|
||||||
original_perm = None
|
|
||||||
|
|
||||||
def hill_climbing(distances: npt.NDArray) -> Tuple[float, npt.NDArray]:
|
def hill_climbing(distances: npt.NDArray) -> Tuple[float, npt.NDArray]:
|
||||||
size = len(distances)
|
"""A simple hill climbing algorithm.
|
||||||
perm = np.arange(size)
|
|
||||||
np.random.shuffle(perm)
|
|
||||||
|
|
||||||
print(perm)
|
The algorithm starts on a random permutation and attempts to improve
|
||||||
global original_perm
|
the circuit by trying to switch neighboring elements. Each iteration
|
||||||
original_perm = copy.deepcopy(perm)
|
tries to switch adjacent neighbors and sees which one yields the largest
|
||||||
current_route: float = np.sum([distances[perm[i - 1], perm[i]] for i in range(size)])
|
improvement.
|
||||||
found_improvement = True
|
|
||||||
while found_improvement:
|
|
||||||
found_improvement = False
|
|
||||||
tmp_improvement: float = current_route
|
|
||||||
improvement_index: int = -1
|
|
||||||
for i in range(size):
|
|
||||||
perm[i - 1], perm[i] = perm[i], perm[i - 1]
|
|
||||||
tmp_route: float = np.sum([distances[perm[i - 1], perm[i]] for i in range(size)])
|
|
||||||
if tmp_route < tmp_improvement:
|
|
||||||
tmp_improvement = tmp_route
|
|
||||||
improvement_index = i
|
|
||||||
found_improvement = True
|
|
||||||
|
|
||||||
perm[i - 1], perm[i] = perm[i], perm[i - 1]
|
Args:
|
||||||
|
distances npt.NDArray: A matrix containing the distances between cities.
|
||||||
|
|
||||||
if found_improvement:
|
Returns:
|
||||||
current_route = tmp_improvement
|
Tuple[float, npt.NDArray] A tuple containing the distance of the
|
||||||
perm[improvement_index - 1], perm[improvement_index] = (
|
solution and the solution itself.
|
||||||
perm[improvement_index],
|
|
||||||
perm[improvement_index - 1],
|
"""
|
||||||
|
|
||||||
|
size: int = len(distances) # The size of the permutation array
|
||||||
|
perm: npt.NDArray = np.arange(size) # Create an array from 0..size
|
||||||
|
|
||||||
|
np.random.shuffle(perm) # Get random permutation
|
||||||
|
|
||||||
|
# Get the distance of the random permutation
|
||||||
|
current_distance: float = np.sum(
|
||||||
|
[distances[perm[i - 1], perm[i]] for i in range(size)]
|
||||||
)
|
)
|
||||||
|
|
||||||
print(perm)
|
found_improvement: bool = True
|
||||||
|
|
||||||
return (current_route, perm)
|
while found_improvement:
|
||||||
|
|
||||||
|
found_improvement = False # Assume we haven't found an improvement
|
||||||
|
tmp_distance: float = current_distance
|
||||||
|
|
||||||
|
# Try to find an improvement
|
||||||
|
for i in range(size):
|
||||||
|
perm[[i - 1, i]] = perm[[i, i - 1]] # Swap i - 1 and i
|
||||||
|
|
||||||
|
tmp_distance: float = np.sum(
|
||||||
|
[distances[perm[i - 1], perm[i]] for i in range(size)]
|
||||||
|
)
|
||||||
|
|
||||||
|
if tmp_distance < current_distance:
|
||||||
|
current_distance = tmp_distance
|
||||||
|
found_improvement = True
|
||||||
|
break
|
||||||
|
|
||||||
|
perm[[i - 1, i]] = perm[[i, i - 1]] # Swap back i - 1 and i
|
||||||
|
|
||||||
|
return (current_distance, perm)
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
cities, data = read_data("./european_cities.csv")
|
cities, data = read_data("./european_cities.csv")
|
||||||
distance, perm = hill_climbing(data[:10,:10])
|
distance, perm = hill_climbing(data[:10, :10])
|
||||||
|
|
||||||
plot_plan(list(map(lambda i: cities[i], list(perm))))
|
|
||||||
plot_plan(list(map(lambda i: cities[i], list(original_perm))))
|
|
||||||
|
|
||||||
|
plot_plan(indexes_to_cities(perm, cities))
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user