Problema del viajero: solución del algoritmo del vecino más cercano de TSP

1. Descripción

        El problema del viajante (TSP) es un conocido problema de optimización que intenta encontrar el camino más corto que visita un conjunto determinado de ciudades y regresa a la ciudad inicial.

        TSP es un problema NP-difícil (polinomial no determinista de tiempo duro). No existe ningún algoritmo conocido que pueda resolver todas las entradas posibles en tiempo polinómico. A medida que aumenta el número de ciudades, el número de recorridos posibles crece exponencialmente, por lo que una búsqueda exhaustiva de soluciones óptimas es computacionalmente inviable para casos de problemas grandes.

2. Discusión de soluciones

        Existen varias soluciones que son efectivas para encontrar una solución casi óptima. Una forma es utilizar algoritmos de aproximación. Estos algoritmos proporcionan soluciones cercanas a las óptimas, pero no necesariamente óptimas. Cambian la optimización por la eficiencia, lo que permite que las soluciones se calculen más rápido. Un algoritmo de aproximación bien conocido es el algoritmo del vecino más cercano.

        Este es un enfoque codicioso. El criterio codicioso es elegir la ciudad más cercana.

        El algoritmo del vecino más cercano es una aproximación simple e intuitiva de TSP. Comienza con una ciudad arbitraria y selecciona iterativamente la ciudad no visitada más cercana hasta que se hayan visitado todas las ciudades.

        Escojamos 5 ciudades de Alemania: Berlín, Colonia, Frankfurt, Hamburgo y Munich.

# coordinates of cities

berlin = {"lat":52.5200, "lon": 13.4050}
hamburg = {"lat":53.5511, "lon": 9.9937}
munich = {"lat":48.1351, "lon": 11.5820}
cologne = {"lat":50.9375, "lon": 6.9603}
frankfurt = {"lat":50.1109, "lon": 8.6821}
cities = [berlin, hamburg, munich, cologne, frankfurt]

Podemos calcular la diferencia entre cada ciudad y completar una matriz de distancias.

import math

def calculate_distance(city1, city2):
    """distance between two cities"""
    lat1, lon1 = city1["lat"], city1["lon"]
    lat2, lon2 = city2["lat"], city2["lon"]
    radius = 6371  # Radius of the Earth in kilometers
    dlat = math.radians(lat2 - lat1)
    dlon = math.radians(lon2 - lon1)
    a = math.sin(dlat / 2) ** 2 + math.cos(math.radians(lat1)) * math.cos(math.radians(lat2)) * math.sin(dlon / 2) ** 2
    c = 2 * math.atan2(math.sqrt(a), math.sqrt(1 - a))
    distance = radius * c
    return distance
def get_distance_matrix(cities):
    """populate distance matrix"""
    num_cities = len(cities)
    distances = [[0] * num_cities for _ in range(num_cities)]
    for i in range(num_cities):
        for j in range(i + 1, num_cities):
            dist = distance_between(cities[i], cities[j])
            distances[i][j] = int(dist)
            distances[j][i] = int(dist)
    return distances

distances = get_distance_matrix(cities)
for row in distances:
    print(row)

"""
[0, 255, 504, 477, 423]
[255, 0, 612, 356, 392]
[504, 612, 0, 456, 304]
[477, 356, 456, 0, 152]
[423, 392, 304, 152, 0]
"""

matriz de distancias.

3. Algoritmo

  1. Comience con cualquier ciudad como ciudad actual. Berlina
  2. Marca la ciudad actual como visitada.
  3. Repita los siguientes pasos hasta que se hayan visitado todas las ciudades:

uno. Encuentra la ciudad no visitada más cercana. Hamburguesa

b. Mudarse a la ciudad no visitada más cercana.

c.Marque la ciudad no visitada más recientemente como visitada.

d. Sume la distancia entre la ciudad actual y la ciudad no visitada más cercana a la duración total del recorrido.

4. Después de visitar todas las ciudades, regrese a la ciudad de inicio para completar el recorrido.

Cuarto, implementación de Python

def solve_tsp_nearest(distances):
    num_cities = len(distances)
    visited = [False] * num_cities
    tour = []
    total_distance = 0
    
    # Start at the first city
    current_city = 0
    tour.append(current_city)
    visited[current_city] = True
    
    
    # Repeat until all cities have been visited
    while len(tour) < num_cities:
        nearest_city = None
        nearest_distance = math.inf

        # Find the nearest unvisited city
        for city in range(num_cities):
            if not visited[city]:
                distance = distances[current_city][city]
                if distance < nearest_distance:
                    nearest_city = city
                    nearest_distance = distance

        # Move to the nearest city
        current_city = nearest_city
        tour.append(current_city)
        visited[current_city] = True
        total_distance += nearest_distance

    # Complete the tour by returning to the starting city
    tour.append(0)
    total_distance += distances[current_city][0]

    return tour, total_distance

tour, total_distance = solve_tsp_nearest(distances)

print("Tour:", tour)
print("Total distance:", total_distance)

"""
Tour: [0, 1, 3, 4, 2, 0]
Total distance: 1571
"""

Tracémoslo en un mapa real.

import folium
m = folium.Map(location=[52.52, 13.405], zoom_start=6)

cities = [(52.5200, 13.4050), (53.5511, 9.9937), (48.1351, 11.5820), (50.9375, 6.9603), (50.1109, 8.6821)]
for i in range(len(cities)):
    folium.Marker(location=cities[i], tooltip=f"City {i}").add_to(m)

paths = [[0, 1], [0, 2], [0, 3], [0, 4], [1, 2], [1, 3], [1, 4], [2, 3], [2, 4], [3, 4]]
for path in paths:
    start_city = cities[path[0]]
    end_city = cities[path[1]]
    folium.PolyLine(locations=[start_city, end_city], color='red').add_to(m)

min_cost_path = [0, 1, 3, 4, 2, 0]
for i in range(len(min_cost_path)-1):
    start_city = cities[min_cost_path[i]]
    end_city = cities[min_cost_path[i+1]]
    folium.PolyLine(locations=[start_city, end_city], color='green').add_to(m)

TSP en el mapa. Imagen proporcionada por el autor.

5. Posdata

        El problema del viajero es un problema basado en la teoría de grafos, cuyo propósito es encontrar una ruta en un gráfico determinado de modo que la ruta pase por el peso total mínimo de todos los nodos. La solución a este problema puede utilizar algoritmos de colonias de hormigas, algoritmos genéticos, algoritmos codiciosos, etc.

        Entre ellos, el algoritmo de colonia de hormigas es un algoritmo que simula el comportamiento de búsqueda de alimento de las hormigas para resolver problemas de optimización. Cuando las hormigas buscan comida, liberan feromonas para marcar sus caminos, y otras hormigas elegirán caminos basándose en las feromonas. Al simular este comportamiento, se puede permitir que las hormigas encuentren el camino óptimo en un gráfico determinado.

        El algoritmo genético es un algoritmo que simula el proceso de evolución biológica para resolver problemas. En el algoritmo genético, los individuos de la población inicial desarrollarán gradualmente una solución más adecuada al problema mediante operaciones como selección, cruce y mutación. Al establecer adecuadamente los parámetros y operaciones del algoritmo genético, se puede obtener una mejor solución al problema del viajero.

        El algoritmo codicioso es un algoritmo que utiliza soluciones óptimas locales para obtener la solución óptima global. En el problema del viajero, se puede utilizar una estrategia codiciosa para seleccionar el nodo no visitado más cercano al nodo actual como el siguiente punto de acceso. Aunque el algoritmo codicioso no necesariamente obtiene la solución óptima, su velocidad de cálculo es rápida y puede obtener soluciones más prácticas en la práctica.

        Además de los tres algoritmos anteriores, también se pueden utilizar programación dinámica, búsqueda en profundidad, bifurcación y límite y otros algoritmos para resolver el problema del viajero. El algoritmo específico a utilizar debe seleccionarse en función de las características del problema real. Okan Jernigan

Supongo que te gusta

Origin blog.csdn.net/gongdiwudu/article/details/132689846
Recomendado
Clasificación