Algorytm komiwojażera w Pythonie.



Na tym etapie udostępniam kod, który z czasem opiszę w szczegółach.

import pygame
import time
import random
import sys
import os

pygame.init()
os.environ["SDL_VIDEO_CENTERED"]='1'

width,height =800,1000
black=[0,0,0]
white=[255,255,255]
green=[0,255,24]
red=[255,0,0]

screen = pygame.display.set_mode((1080,800))
pygame.display.set_caption("Algorytm komiwojazera")
czcionka = pygame.font.SysFont("monospace", 30)

points=[]
offset_screen=100
smallest_path=[]
record_distance=0
number_of_points=15
licznik = 0
licznik2=0
class Point:
            def __init__(self, x, y):
                        self.x = x
                        self.y = y

for i in range(number_of_points):
            x=random.randint(offset_screen, width-offset_screen)
            y=random.randint(offset_screen, height-3*offset_screen)
            print("i ",i," x ",x," y ",y)

            point=Point(x,y)
            points.append(point)
            
def shuffle(a,b,c):
            temp=a[b]
            a[b]=a[c]
            a[c]=temp
def calculate_distance(points_list):
            total=0
            for n in range(len(points)-1):
                        distance=((points[n].x-points[n+1].x)**2+(points[n].y-points[n+1].y)**2)**.5
                        total +=distance
                        print('n = ',n+1,' dystans = ',distance,' total = ',total)
            return total
dist = calculate_distance(points)
record_distance = dist
smallest_path = points.copy()

run =True
while run:
            for event in pygame.event.get():
                        if event.type == pygame.KEYDOWN:
                                    if event.key == pygame.K_1:
                                                run=False
                                                pygame.quit()
                                                sys.exit()

            for n in range (len(points)):
                        pygame.draw.circle(screen,white, (points[n].x,points[n].y),10)
                        pygame.display.update()
            time.sleep(.2)
           
            a=random.randint(0,len(points)-1)
            b=random.randint(0,len(points)-1)
            shuffle(points, a,b)
            dist=calculate_distance(points)
            if dist< record_distance:
                        screen.fill(black)
                        licznik=licznik+1
                        label = czcionka.render("licznik sukcesów = %.f " %(licznik), 1, red,white)
                        screen.blit(label, (10, 50))
                        pygame.display.update()
                        record_distance = dist
                        smallest_path =points.copy()
                        licznik2=0
            licznik2=licznik2+1
            label = czcionka.render("licznik porażek = %.f " %(licznik2), 1, green,white)
            screen.blit(label, (10, 10))
            pygame.display.update()

                       
            for m in range(len(points)-1):
                        pygame.draw.line(screen,white,(points[m].x, points[m].y),(points[m+1].x,points[m+1].y),1)
                        pygame.display.update()
                        

            for m in range(len(smallest_path)-1):
                        pygame.draw.line(screen,green,(smallest_path[m].x, smallest_path[m].y),(smallest_path[m+1].x,smallest_path[m+1].y),3)
			pygame.draw.line(screen, (150,150,150), (offset_screen,offset_screen),(width-offset_screen,offset_screen),4)
			pygame.draw.line(screen, (150,150,150), (offset_screen,offset_screen),(offset_screen,height-3*offset_screen),4)
			pygame.draw.line(screen, (150,150,150), (width-offset_screen,offset_screen),(width-offset_screen,height-3*offset_screen),4)
			pygame.draw.line(screen, (150,150,150), (offset_screen,height-3*offset_screen),(width-offset_screen,height-3*offset_screen),4)
                     
                             
            pygame.display.update()
            label = czcionka.render("dystans= %.2f " %(record_distance), 1, green,white)
            screen.blit(label, (750, 10))

	


Na poniższym rysunku mozna zobaczyć efekt działania programu. W jednym oknie drukuje współrzędne wylosowanych punktów, oraz nadliczanie kolenych fragmentów drogi.
Na prawym oknie mozna zobaczyć wizuaizację pracy programu. Zielona linia to najlepsza zdefiniowana trasa. Białe linie to wyniki gorsze od najlepszego.



:)