当我向旅行商问题添加更多顶点时,为啥我没有得到结果?

Posted

技术标签:

【中文标题】当我向旅行商问题添加更多顶点时,为啥我没有得到结果?【英文标题】:Why am I not getting a result when I add more vertices to my Traveling Salesman Problem?当我向旅行商问题添加更多顶点时,为什么我没有得到结果? 【发布时间】:2021-10-07 06:45:47 【问题描述】:

我正在尝试通过具有更多顶点的 2 近似来测试我的代码以解决旅行推销员问题,但我没有得到任何结果。对于下面的代码,我得到了正确的结果,但是一旦我添加另一个顶点,我就没有得到结果。我不明白为什么我会遇到这个问题。

下面是我的代码:

import numpy as np
from collections import defaultdict
import heapq

class MinimumSpanningTree: 
  
        def __init__(self, edgeWeights, root):
            self.root = root 
            self.totalWeight = edgeWeights 
            self.minimumSpanningTree = self.PrimsAlgorithm()

        def PrimsAlgorithm(self):
           
            result = defaultdict(set) 
            
            verticesVisited = set([self.root])
          
            
            treeEdges = [(edgeWeight, self.root, secondVertex) for secondVertex, edgeWeight in enumerate(self.totalWeight[self.root])]
            heapq.heapify(treeEdges)
          
            while treeEdges:
                edgeWeights, vertex, nextVertex = heapq.heappop(treeEdges)
               
                if nextVertex not in verticesVisited:
                    verticesVisited.add(nextVertex)
                    result[vertex].add(nextVertex) 
                    #use for loop to declare visitNextVertex and enumerate over totalWeight[nextVertex]
                    for visitNextVertex, edgeWeights in enumerate(self.totalWeight[nextVertex]):
                       
                        if visitNextVertex not in verticesVisited:
                            heapq.heappush(treeEdges, (self.totalWeight[nextVertex][visitNextVertex], nextVertex, visitNextVertex))
            return result

        def mstPreOrder(self, root):
        
            childVertex = self.minimumSpanningTree[root]
        
            result = [root]
             
            for vertex in childVertex:
                
                result = result + self.mstPreOrder(vertex)
            return result 

class TravelingSalesmanProblem:
   
    def __init__(self, edgeWeight, preOrderMST, vertices):
        self.preOrderMST = preOrderMST   
        self.edgeWeight = edgeWeight 
        self.weightTraveled = self.PreOrderWeight(preOrderMST)
        self.vertices = vertices
    

    def PreOrderWeight(self, preOrderMST):
       
            result = 0
      
            for root in range(len(preOrderMST)):
                firstVertex = preOrderMST[root] 
                secondVertex = preOrderMST[(root+1)%len(preOrderMST)]
                result += self.edgeWeight[firstVertex][secondVertex]
            return result

    def findTwoApproxSolution(self):
      
            numberOfVertices = len(self.preOrderMST)
           
            currentMST = self.preOrderMST
       
            originalDistance = self.weightTraveled  
       
            for a in range(numberOfVertices-2):
                for b in range(a+2, numberOfVertices):
                   
                    newpreOrderMST = np.copy(self.preOrderMST)
                    newpreOrderMST[(a+1)%numberOfVertices] = self.preOrderMST[b%numberOfVertices]
                   
                    tempEdge = a+2
                  
                    for c in range(b-1, a, -1):
                        newpreOrderMST[tempEdge%numberOfVertices] = self.preOrderMST[c%numberOfVertices]
                        
                        tempEdge += 1
                
                    inequalityDistance = self.PreOrderWeight(newpreOrderMST)
                  
                    if inequalityDistance < originalDistance:
                        currentMST = np.copy(newpreOrderMST)
                        originalDistance = inequalityDistance
        
            if self.weightTraveled == originalDistance:
                return    
      
            self.preOrderMST = currentMST
          
            self.weightTraveled = originalDistance
            
            tour = list(map(lambda x: self.vertices[x], self.preOrderMST))
           
            print("The 2-Approximation Tour Of Vertices is:",tour)
            
            print("Total Weight For 2-Approximation Tour is:", self.weightTraveled)
            
            self.findTwoApproxSolution() 
            return tour,self.weightTraveled 


listOfVertices=[['A'],['B'],['C'],['D']]

edgeCost = [[0,10,15,20],[10,0,35,25],[15,35,0,30],[20,25,30,0]]

findMST = MinimumSpanningTree(edgeCost, 0) 

findMSTPreOrder = findMST.mstPreOrder(0) 
    

travelingSalesmanPreOrder = TravelingSalesmanProblem(edgeCost, findMSTPreOrder, listOfVertices)

travelingSalesmanPreOrder.findTwoApproxSolution()

添加额外顶点(5 个顶点)时的代码

listOfVertices=[['A'],['B'],['C'],['D'],['E']]

edgeCost = [[0,3,4, 2,7],
[3,0,4,6 ,3],
[4,4,0,5,8],
[2,6,5,0,6],
[7,3,8,6,0],
]

更新: 添加第 5 个顶点的返回值为 None。此外,如果我只将它用于 3 个顶点,则它不会返回。我觉得这很奇怪,不明白为什么它似乎只适用于 4 个顶点

【问题讨论】:

您能否提供一个代码示例来说明如何添加另一个顶点? 是的,对不起,我会的 【参考方案1】:

我添加了一个顶点,得到了一个结果:

listOfVertices=[['A'],['B'],['C'],['D'],['E']]

edgeCost = [[0,10,15,20, 50],[10,0,35,25,50],[15,35,0,30,50],[20,25,30,0,50], [20,25,30,0,50]]

返回

The 2-Approximation Tour Of Vertices is: [['A'], ['B'], ['E'], ['D'], ['C']]
Total Weight For 2-Approximation Tour is: 105

我认为您的代码不打印结果的一种方法是,如果这是在最后一次调用时触发的:

if self.weightTraveled == originalDistance:
    return   

【讨论】:

我编辑了我的代码,它对你有用吗? 您提供的顶点成本对我也不起作用。 如果 self.weightTraveled == originalDistance: return ? 你建议做什么来代替

以上是关于当我向旅行商问题添加更多顶点时,为啥我没有得到结果?的主要内容,如果未能解决你的问题,请参考以下文章

Hamilton回路 旅行商TSP问题 /// dp oj1964

当我向 navigationItem 添加更多按钮时,如何使我的 navigationItem.titleView 居中?

算法笔记_018:旅行商问题(Java)

当入口和出口指向不同的节点时,如何使用 boost::graph (大约)解决旅行商问题?

在 django 搜索中没有得到结果,但个人搜索工作正常

当我向视图中添加连接语句时,Mysql 挂起