Почему я не получаю результата, когда добавляю больше вершин к своей проблеме Коммивояжера?

#python #python-3.x #return-value #traveling-salesman

Вопрос:

Я пытаюсь протестировать свой код для решения задачи коммивояжера с помощью 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. Не могли бы вы привести пример кода, показывающий, как вы добавляете еще одну вершину?

2. Да, извините, я так и сделаю

Ответ №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   
 

Комментарии:

1. Я отредактировал свой код, сработало ли у вас редактирование?

2. Это также не работает для меня с учетом затрат на вершину, которые вы указали.

3. что вы предлагаете делать вместо того, чтобы «если я»? weightTraveled == Первоначальное сопротивление: возврат ?