• 最小生成树算法求解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()
    
  • 相关阅读:
    MFC中注释含义
    数字时钟
    布线问题分支限界法
    精度计算大数阶乘ACM常用算法
    C++库大全
    简单文本编辑器制作windows程序设计雏形
    使用计时器方法2
    MFC常用基本数据类型
    Xcode 代码格式化/自动排版
    android的color值
  • 原文地址:https://www.cnblogs.com/Martrix-revolution/p/15412430.html
Copyright © 2020-2023  润新知