zoukankan      html  css  js  c++  java
  • 最小生成树算法求解TSP

    最小生成树求解TSP问题

    步骤:

    首先根据输入生成TSP地图数据,然后利用克鲁斯卡尔(Kruskal)和普利姆(prim)算法求解这个TSP问题,最后用图画出来。

    算法思想:

    克鲁斯卡尔算法的核心思想是:在带权连通图中,不断地在边集合中找到最小的边,如果该边满足得到最小生成树的条件,就将其构造,直到最后得到一颗最小生成树

    普利姆算法的核心步骤是:在带权连通图中,从图中某一顶点v开始,此时集合U={v},重复执行下述操作:在所有u∈U,w∈V-U的边(u,w)∈E中找到一条权值最小的边,将(u,w)这条边加入到已找到边的集合,并且将点w加入到集合U中,当U=V时,就找到了这颗最小生成树。

    算法代码(python)

    Kruskal

    # kruskal
    edge_count = 0
    for i in range(size):
        for j in range(i):
            if 0 < distance[i][j] < 999998:
                edge_count += 1
    kruskal_list = []
    edge_list = []
    
    for i in range(size):
        for j in range(i+1, size):
            edge_list.append([i, j, distance[i][j]])
    edge_list.sort(key=lambda a: a[2])
    
    group = [[i] for i in range(size)]
    for edge in edge_list:
        for i in range(len(group)):
            if edge[0] in group[i]:
                m = i
            if edge[1] in group[i]:
                n = i
        if m != n:
            kruskal_list.append(edge)
            group[m] = group[m] + group[n]
            group[n] = []
    

    Prim

    # Prim
    prim_list = []
    
    selected_node = [0]
    candidate_node = [i for i in range(1, size)]
    while len(candidate_node) > 0 :
        min_dis = 999998
        for i in selected_node:
            for j in candidate_node:
                if distance[i][j] < min_dis:
                    min_dis = distance[i][j]
                    cur_node = i
                    next_select_node = j
        prim_list.append([cur_node, next_select_node, min_dis])
        selected_node.append(next_select_node)
        candidate_node.remove(next_select_node)
    

    代码测试:

    (1)
    15个城市迅速收敛



    (2)
    100个城市可以快速收敛

    (3)

    1000个城市无法快速收敛

    源代码:

    import numpy as np
    import matplotlib.pyplot as plt
    
    size = int(input("城市个数:"))
    scale = int(input("比例尺:"))
    MAX_ = 999999
    coord = []
    distance = np.zeros((size, size))
    
    i = 0
    while i < size:
        x = np.random.rand() * scale
        y = np.random.rand() * scale
        if [x, y] not in coord:
            coord.append([x, y])
            i = i + 1
    coord = np.array(coord)
    
    for i in range(size):
        for j in range(size):
            if i == j :
                distance[i][j] = MAX_
            else:
                distance[i][j] = distance[j][i] = np.linalg.norm(coord[i] - coord[j])
    
    # kruskal
    edge_count = 0
    for i in range(size):
        for j in range(i):
            if 0 < distance[i][j] < 999998:
                edge_count += 1
    kruskal_list = []
    edge_list = []
    
    for i in range(size):
        for j in range(i+1, size):
            edge_list.append([i, j, distance[i][j]])
    edge_list.sort(key=lambda a: a[2])
    
    group = [[i] for i in range(size)]
    for edge in edge_list:
        for i in range(len(group)):
            if edge[0] in group[i]:
                m = i
            if edge[1] in group[i]:
                n = i
        if m != n:
            kruskal_list.append(edge)
            group[m] = group[m] + group[n]
            group[n] = []
    
    # Prim
    prim_list = []
    
    selected_node = [0]
    candidate_node = [i for i in range(1, size)]
    while len(candidate_node) > 0 :
        min_dis = 999998
        for i in selected_node:
            for j in candidate_node:
                if distance[i][j] < min_dis:
                    min_dis = distance[i][j]
                    cur_node = i
                    next_select_node = j
        prim_list.append([cur_node, next_select_node, min_dis])
        selected_node.append(next_select_node)
        candidate_node.remove(next_select_node)
    
    print(coord)
    print(distance)
    print("----------------------Kruskal-----------------------")
    print(np.array(kruskal_list))
    print("----------------------Prim-----------------------")
    print(np.array(prim_list))
    
    fig = plt.figure(1, (45, 15))
    ax1 = fig.add_subplot(131)
    ax1.set_title("MAP{}".format(size))
    ax1.plot(coord[:, 0], coord[:, 1], 'o')
    
    ax2 = fig.add_subplot(132)
    ax2.set_title("Kruskal")
    x = []
    y = []
    for t_list in kruskal_list:
        ax2.plot([coord[t_list[0], 0], coord[t_list[1], 0]], [coord[t_list[0], 1], coord[t_list[1], 1]])
    
    ax3 = fig.add_subplot(133)
    ax3.set_title("Prim")
    for t_list in prim_list:
        ax3.plot([coord[t_list[0], 0], coord[t_list[1], 0]], [coord[t_list[0], 1], coord[t_list[1], 1]])
    
    plt.show()
    
  • 相关阅读:
    2016"百度之星"
    codeforces 55 div2 C.Title 模拟
    codeforces 98 div2 C.History 水题
    codeforces 97 div2 C.Replacement 水题
    codeforces 200 div2 C. Rational Resistance 思路题
    bzoj 2226 LCMSum 欧拉函数
    hdu 1163 九余数定理
    51nod 1225 余数的和 数学
    bzoj 2818 gcd 线性欧拉函数
    Codeforces Round #332 (Div. 2)D. Spongebob and Squares 数学
  • 原文地址:https://www.cnblogs.com/Martrix-revolution/p/15412430.html
Copyright © 2011-2022 走看看