Объясни как работает следующий код
import numpy as np

def initialize_pheromone_matrix(num_cities, initial_pheromone):
    # Инициализация матрицы феромонов начальным значениями
    return np.full((num_cities, num_cities), initial_pheromone)

def pick_next_city(probabilities):
    # Выбор следующего города на основе вероятностей (взвешенный случайный выбор)
    return np.random.choice(len(probabilities), 1, p=probabilities)[0]

def update_pheromone(pheromone_matrix, ants, decay_rate, additional_pheromone):
    # Уменьшение всех феромонов в матрице на коэффициент испарения
    for i in range(len(pheromone_matrix)):
        for j in range(len(pheromone_matrix[i])):
            pheromone_matrix[i][j] *= (1 - decay_rate)
    # Увеличение феромонов на пути, пройденном каждым муравьем
    for ant in ants:
        for i in range(1, len(ant['tour'])):
            city_i = ant['tour'][i - 1]
            city_j = ant['tour'][i]
            pheromone_matrix[city_i][city_j] += additional_pheromone / ant['length']
            pheromone_matrix[city_j][city_i] += additional_pheromone / ant['length']

def calculate_probabilities(current_city, visited, distances, pheromones, alpha, beta):
    probabilities = []
    denominator = 0
    # Вычисление знаменателя для нормализации вероятностей
    for city in range(len(distances)):
        if not visited[city]:
            pheromone = pheromones[current_city][city] ** alpha
            heuristic = (1 / distances[current_city][city]) ** beta
            denominator += pheromone * heuristic
    # Вычисление вероятностей для каждого непосещенного города
    for city in range(len(distances)):
        if not visited[city]:
            pheromone = pheromones[current_city][city] ** alpha
            heuristic = (1 / distances[current_city][city]) ** beta
            probability = (pheromone * heuristic) / denominator
            probabilities.append(probability)
        else:
            probabilities.append(0)

    return probabilities

def ant_colony_optimization(distances, num_ants, num_iterations, decay_rate, alpha, beta, initial_pheromone, additional_pheromone):
    num_cities = len(distances)
    pheromone_matrix = initialize_pheromone_matrix(num_cities, initial_pheromone)

    best_tour = None
    best_length = float('inf')
    for iteration in range(num_iterations):
        ants = [{'tour': [np.random.randint(num_cities)], 'length': 0} for _ in range(num_ants)]
        # Сформировать маршрут для каждого муравья
        for _ in range(num_cities - 1):
            for ant in ants:
                current_city = ant['tour'][-1]
                visited = [False] * num_cities
                for city in ant['tour']:
                    visited[city] = True

                probabilities = calculate_probabilities(current_city, visited, distances, pheromone_matrix, alpha, beta)
                next_city = pick_next_city(probabilities)
                ant['tour'].append(next_city)
                ant['length'] += distances[current_city][next_city]

        # Завершение маршрута возвращением в начальный город
        for ant in ants:
            start_city = ant['tour'][0]
            last_city = ant['tour'][-1]
            ant['tour'].append(start_city)
            ant['length'] += distances[last_city][start_city]
            # Обновление лучшего найденного маршрута
            if ant['length'] < best_length:
                best_tour = ant['tour']
                best_length = ant['length']
        # Обновление феромонов на основе пройденных путей
        update_pheromone(pheromone_matrix, ants, decay_rate, additional_pheromone)

    return best_tour, best_length