深度优先搜索算法求解TSP问题(搜索算法)

题目

【问题描述】采用深度优先搜索算法求解TSP问题,并在搜索过程中,使用界限条件(当前结点已经走过的路径长度要小于已求得的最短路径)进行“剪枝”操作(不再对后续结点进行遍历),从而提高搜索效率。采用queue模块中的栈(LifoQueue)来实现深度优先搜索。

【输入形式】在屏幕上输入顶点个数和连接顶点间的边的邻接矩阵,边上的权可能有小数点。

【输出形式】在整个算法过程中的先后搜索路径(最多输出20次最先搜索的路径),最优值和其中一条最优路径。

【样例1输入】

4

0 30 6 4

30 0 5 10

6 5 0 20

4 10 20 0

【样例1输出】

1

1->2

1->2->3

1->2->3->4

1->2->4

1->3

1->3->2

1->3->2->4

1->3->4

1->4

1->4->2

1->4->2->3

1->4->3

25: 1->3->2->4

【样例说明】

 输入:顶点个数为4。连接顶点间边的邻接矩阵大小为4行4列,位置[i,j]上元素值表示第i个顶点到第j个顶点的距离,0表示两个顶点间没有边连接。

 输出:在整个算法过程中的先后搜索路径,最优值为25,最优路径为:1->3->2->4。

【评分标准】根据输入得到准确的输出。

import numpy as np
import queue


class VertexNode(object):
    def __init__(self, path=None, cost=0):
        self.path = path
        self.cost = cost


def depth_first(b, s_index, n):
    best_cost = np.inf
    best_path = None
    m = 20

    start_node = VertexNode(path=[s_index], cost=0)
    open = queue.LifoQueue()
    open.put(start_node)

    while not open.empty():
        cur_node = open.get()
        if m > 0:
            showpath(cur_node)
            m -= 1

        if cur_node.cost >= best_cost:  # 剪枝
            continue

        # 是叶节点
        if len(cur_node.path) == n:
            new_cost = cur_node.cost + b[cur_node.path[-1] - 1, 0]   # 当前加上回到1的费用
            if new_cost < best_cost:
                best_cost = new_cost
                best_path = list(cur_node.path)
                continue

        # 不是叶节点
        for i in range(n, 0, -1):
            if not (i in cur_node.path):
                new_cost = cur_node.cost + b[cur_node.path[-1]-1, i-1]
                if new_cost < best_cost:
                    new_path = list(cur_node.path)
                    new_path.append(i)
                    new_node = VertexNode(path=new_path, cost=new_cost)
                    open.put(new_node)
    return best_cost, best_path


def showpath(cur_node):
    if len(cur_node.path) == 1:
        print(cur_node.path[-1])
    elif len(cur_node.path) > 1:
        for i in range(len(cur_node.path)):
            if i != len(cur_node.path)-1:
                print(f"{cur_node.path[i]}->", end="")
            else:
                print(f"{cur_node.path[i]}")


def main():
    n = int(input())
    a = []
    for i in range(n):
        a.append(list(map(np.double, input().rstrip().split())))
    b = np.array(a).reshape(n, n)
    b[b == 0] = np.inf
    s_index = 1
    best_cost, best_path = depth_first(b, s_index, n)
    if best_cost == int(best_cost):
        print(f"{int(best_cost)}", end=": ")
    else:
        print(f"{best_cost}", end=": ")
    for i in range(len(best_path)):
        if i != len(best_path)-1:
            print(f"{best_path[i]}->", end="")
        else:
            print(f"{best_path[i]}")


if __name__ == '__main__':
    main()

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值