Problema do viajante: solução de algoritmo do vizinho mais próximo TSP

1. Descrição

        O Problema do Caixeiro Viajante (TSP) é um problema de otimização bem conhecido que tenta encontrar o caminho mais curto que visita um determinado conjunto de cidades e retorna à cidade inicial.

        TSP é um problema NP-difícil (tempo polinomial não determinístico difícil). Não existe nenhum algoritmo conhecido que possa resolver todas as entradas possíveis em tempo polinomial. À medida que o número de cidades aumenta, o número de passeios possíveis cresce exponencialmente, de modo que uma busca exaustiva por soluções ótimas é computacionalmente inviável para grandes instâncias de problemas.

2. Discussão sobre a solução

        Existem várias soluções que são eficazes para encontrar uma solução quase ideal. Uma maneira é usar algoritmos de aproximação. Esses algoritmos fornecem soluções próximas do ideal, mas não necessariamente ideais. Eles trocam otimização por eficiência, permitindo que as soluções sejam computadas mais rapidamente. Um algoritmo de aproximação bem conhecido é o algoritmo do vizinho mais próximo.

        Esta é uma abordagem gananciosa. O critério ganancioso é escolher a cidade mais próxima.

        O algoritmo do vizinho mais próximo é uma aproximação simples e intuitiva do TSP. Ele começa com uma cidade arbitrária e seleciona iterativamente a cidade não visitada mais próxima até que todas as cidades tenham sido visitadas.

        Vamos escolher 5 cidades da Alemanha: Berlim, Colônia, Frankfurt, Hamburgo e Munique.

# 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 a diferença entre cada cidade e completar uma matriz de distâncias.

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 distância.

3. Algoritmo

  1. Comece com qualquer cidade como a cidade atual. Berlim
  2. Marcar a cidade atual como visitada.
  3. Repita os seguintes passos até que todas as cidades tenham sido visitadas:

um. Encontre a cidade não visitada mais próxima. Hamburger

b. Vá para a cidade não visitada mais próxima.

c. Marque a cidade não visitada mais recentemente como visitada.

d. Adicione a distância entre a cidade atual e a cidade não visitada mais próxima à duração total do passeio.

4. Após visitar todas as cidades, retorne à cidade inicial para finalizar o passeio.

4. implementação 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
"""

Vamos plotá-lo em um 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 no mapa. Imagem fornecida pelo autor.

5. Pós-escrito

        O problema do Traveler é um problema baseado na teoria dos grafos, cujo objetivo é encontrar um caminho em um determinado grafo tal que o caminho passe pelo peso total mínimo de todos os nós. A solução para este problema pode usar algoritmo de colônia de formigas, algoritmo genético, algoritmo ganancioso e assim por diante.

        Entre eles, o algoritmo de colônia de formigas é um algoritmo que simula o comportamento de busca de alimento das formigas para resolver problemas de otimização. Quando as formigas procuram comida, elas liberam feromônios para marcar seus caminhos, e outras formigas escolhem caminhos com base nos feromônios. Ao simular esse comportamento, as formigas podem encontrar o caminho ideal em um determinado gráfico.

        Algoritmo genético é um algoritmo que simula o processo de evolução biológica para resolver problemas. No algoritmo genético, os indivíduos da população inicial evoluirão gradualmente para uma solução mais adequada para o problema por meio de operações como seleção, cruzamento e mutação. Ao definir adequadamente os parâmetros e operações do algoritmo genético, uma solução melhor pode ser obtida no problema do viajante.

        O algoritmo ganancioso é um algoritmo que usa soluções ótimas locais para obter a solução ótima global. No problema do viajante, uma estratégia gananciosa pode ser usada para selecionar o nó não visitado mais próximo do nó atual como o próximo ponto de acesso. Embora o algoritmo ganancioso possa não obter necessariamente a solução ótima, sua velocidade de cálculo é rápida e pode obter soluções mais práticas na prática.

        Além dos três algoritmos acima, programação dinâmica, pesquisa em profundidade, ramificação e limite e outros algoritmos também podem ser usados ​​para resolver o problema do viajante. O algoritmo específico a ser usado precisa ser selecionado com base nas características do problema real. Okan Jernigan

Acho que você gosta

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