View difference between Paste ID: ABQ3x0PG and 1UWZDUJq
SHOW: | | - or go back to the newest paste.
1
##############################################<START OF PROGRAM>##############################################
2
def setUpCanvas(root): # These are the REQUIRED magic lines to enter graphics mode.
3
    root.title("THE TRAVELING SALESMAN PROBLEM by (your name here).")
4
    canvas = Canvas(root, width  = root.winfo_screenwidth(), height = root.winfo_screenheight(), bg = 'black')
5
    canvas.pack(expand = YES, fill = BOTH)
6
    return canvas
7
#---------------------------------------------------------------------------------Traveling Salesman Problem--
8
9
def script(x, y, msg = '', kolor = 'WHITE'):
10
    canvas.create_text(x, y, text = msg, fill = kolor,  font = ('Helvetica', 10, 'bold'))
11
#---------------------------------------------------------------------------------Traveling Salesman Problem-
12
13
def plot(city): # Plots 5x5 "points" on video screen
14
    x = city[1]+5; y = city[2]+5 # The +5 is to push away from the side bars.
15
    if city[0] == -1:
16
        kolor = 'WHITE'
17
    else: kolor = 'YELLOW'
18
    canvas.create_rectangle(x-2, y-2, x+2, y+2, width = 1, fill = kolor)
19
#---------------------------------------------------------------------------------Traveling Salesman Problem--
20
21
def line(city1, city2, kolor = 'RED'):
22
    canvas.create_line(city1[1]+5, city1[2]+5, city2[1]+5, city2[2]+5, width = 1, fill = kolor)
23
#---------------------------------------------------------------------------------Traveling Salesman Problem--
24
25
def displayDataInConsole(AlgorithmResults, baseCity, city):
26
    print('===<Traveling Salesman Path Statistics>===')
27
    print ('   algorithm         path length ')
28
    for element in AlgorithmResults:
29
           print ('---%-20s'%element[0], int(element[2]))
30
    city.sort()
31
    baseCity.sort()
32
    if city == baseCity:
33
        print("---Data verified as unchanged.")
34
    else:
35
        print ('ERROR: City data has been corrupted!')
36
    print('   Run time =', round(clock()-START_TIME, 2), ' seconds.')
37
#---------------------------------------------------------------------------------Traveling Salesman Problem--
38
39
def printCity(city): # Used for debugging.
40
    count = 0
41
    for (id,x,y) in city:
42
        print( '%3d: id =%2d, (%5d, %5d)'%(count,id, int(x), int(y)))
43
        count += 1
44
#---------------------------------------------------------------------------------Traveling Salesman Problem--
45
46
def displayPathOnScreen(city, statistics):
47
#=---Normalize data
48
    (minX, maxX, minY, maxY, meanX, meanY, medianX, medianY, size, m, b) = statistics
49
    canvas.delete('all')
50
    cityNorm, (p,q,r,s) = normalizeCityDataToFitScreen(city[:], statistics)
51
52
#---Plot points and lines
53
    cityNorm.append(cityNorm[0])
54
    plot(cityNorm[0])
55
    for n in range(1, len(cityNorm)):
56
        plot(cityNorm[n])
57
        line(cityNorm[n], cityNorm[n-1])
58
    script(650,  20, 'path length = ' + str(pathLength(city)))
59
    canvas.create_rectangle(530,10, 770, 30, width = 1, outline = 'WHITE')
60
    canvas.update()
61
    root.mainloop() # Required for graphics.
62
#---------------------------------------------------------------------------------Traveling Salesman Problem--
63
64
def normalizeCityDataToFitScreen(city, statistics):
65
    """ Coordinates are all assumed to be non-negative."""
66
    (minX, maxX, minY, maxY, meanX, meanY, medianX, medianY, size, m, b) = statistics
67
    newCity = []
68
69
#---Step 1a. Shift city points to the x- and y-axes.
70
    for (id, x,y) in city:
71
        newCity.append ( (id, x-minX, y-minY))
72
73
#---Step 1b. Shift line-of-best-fit to the x- and y-axes.
74
    (x0,y0) = (maxX-minX, m*maxX+b - minY) # = x-intercept of line-of-best-fit.
75
    (x1,y1) = (minX-minX, m*minX+b - minY) # = y-intercept of line-of-best-fit.
76
77
78
#---Step 1c. Shift max-values to x- and y-axes.
79
    maxX = maxX-minX
80
    maxY = maxY-minY
81
82
#---Step 2a. # Re-scale city points to fit the screen.
83
    cityNorm = []
84
    for (id, x, y) in newCity:
85
        cityNorm.append ((id, x*SCREEN_WIDTH/maxX, y*SCREEN_HEIGHT/maxY))
86
87
#---Step 2b. # Re-scale the x-axis and y-axis intercepts for the line-of-best-fit.
88
    (x0,y0) = x0/maxX*SCREEN_WIDTH, y0/maxY*SCREEN_HEIGHT # a point on the x-axis
89
    (x1,y1) = x1/maxX*SCREEN_WIDTH, y1/maxY*SCREEN_HEIGHT # a point on the y-axis
90
91
    return cityNorm, (x1,y1,x0,y0) # = the adjusted city xy-values and 2 points on the line-of-best-fit.
92
#---------------------------------------------------------------------------------Traveling Salesman Problem--
93
94
def readDataFromFileAndAppendId(fileName):
95
    file1 = open(fileName, 'r')
96
    fileLength = int(file1.readline()) # removes heading
97
    city = []
98
    for elt in range(fileLength):
99
       x, y = file1.readline().split()
100
       city.append( [0, float(x), float(y)] ) # A place for an id (0, here) is appended.
101
    file1.close()
102
    return city
103
#---------------------------------------------------------------------------------Traveling Salesman Problem--
104
105
def getFileLength(fileName):
106
    file1 = open(fileName, 'r')
107
    fileLength = int(file1.readline()) # removes heading
108
    return fileLength
109
#---------------------------------------------------------------------------------Traveling Salesman Problem--
110
111
def pathLength(city):
112
    totalPath = 0
113
    for n in range(1, len(city)):
114
        totalPath += dist( city[n-1], city[n] )
115
    totalPath += dist( city[n], city[0] )
116
    return int(totalPath)
117
#---------------------------------------------------------------------------------Traveling Salesman Problem--
118
119
def dataStatistics(city):
120
    xValues = []
121
    yValues = []
122
    size = len(city)
123
    for (id, x,y) in city:
124
        xValues.append(x)
125
        yValues.append(y)
126
    minX = min(xValues)
127
    maxX = max(xValues)
128
    minY = min(yValues)
129
    maxY = max(yValues)
130
131
    assert (minX >= 0 or maxX >= 0 or minY >= 0 or maxY >= 0)
132
133
    meanX = sum(xValues)/size
134
    meanY = sum(yValues)/size
135
    medianX = city[len(city)//2][0]
136
    medianY = city[len(city)//2][1]
137
138
#---Derive the line of best fit: y = mx+b
139
    xyDiff   = 0
140
    xDiffSqr = 0
141
    for (id, x,y) in city:
142
        xyDiff  += (meanX - x)*(meanY - y)
143
        xDiffSqr+= (meanX - x)**2
144
145
    m = xyDiff/xDiffSqr
146
    b = meanY - m*meanX
147
148
    return minX, maxX, minY, maxY, meanX, meanY, medianX, medianY, size, m, b
149
#---------------------------------------------------------------------------------Traveling Salesman Problem--
150
151
def dist(cityA, cityB):
152
    return hypot(cityA[1]-cityB[1], cityA[2] - cityB[2])
153
#---------------------------------------------------------------------------------Traveling Salesman Problem--
154
155
def chunks(l, n):
156
    n = max(1, n)
157
    l.pop()
158
    return [l[i:i + n] for i in range(0, len(l), n)]
159
#---------------------------------------------------------------------------------Traveling Salesman Problem--
160
161
def printToFile(distances, myfile):
162
    for item in distances:
163
        myfile.write("%s\n" % item)
164
        myfile.write("\n")
165
#---------------------------------------------------------------------------------Traveling Salesman Problem--
166
167
def myAlgorithm(distances,city,fileLength):
168
    for x in range(len(city)):
169
        for y in range(len(city)):
170
            if x+y+1<len(city):
171
                distances.append(dist(city[x],city[x+y+1]))
172
            elif city[x] !=city[(x+y)%(fileLength-1)]:
173
                distances.append(dist(city[x],city[(x+y)%(fileLength-1)]))
174
#---------------------------------------------------------------------------------Traveling Salesman Problem--
175
176
def ySort(city):
177
    for item in city:
178
        item[1],item[2]=item[2],item[1]
179
    city.sort()
180
    for item in city:
181
        item[1],item[2]=item[2],item[1]
182
#---------------------------------------------------------------------------------Traveling Salesman Problem--
183
184
def xSort(city):
185
    city.sort()
186
#====================================<GLOBAL CONSTANTS and GLOBAL IMPORTS>========Traveling Salesman Problem==
187
188
from tkinter      import Tk, Canvas, YES, BOTH
189
from operator     import itemgetter
190
from itertools    import permutations
191
from copy         import deepcopy
192
from random       import shuffle
193
from time         import clock
194
from math         import hypot
195
from operator     import itemgetter
196
from collections import OrderedDict
197
root           = Tk()
198
canvas         = setUpCanvas(root)
199
START_TIME     = clock()
200
SCREEN_WIDTH   = root.winfo_screenwidth() //5*5 - 15 # adjusted to exclude task bars on my PC.
201
SCREEN_HEIGHT  = root.winfo_screenheight()//5*5 - 90 # adjusted to exclude task bars on my PC.
202
fileName       = "tsp0038.txt" # My file name will be different from yours
203
#==================================================< MAIN >=======================Traveling Salesman Problem==
204
205
def main():
206
#---0. Read in data, append an id to every pair, and store results in a variable called "city".
207
208
    fileLength = getFileLength(fileName)
209
    city  = readDataFromFileAndAppendId(fileName)
210
211
#---1. Extract statistics.
212
213
    statistics = (minX, maxX, minY, maxY, meanX, meanY, medianX, medianY, size, m, b) = dataStatistics(city)
214
215
#---2. Create a random path.
216
217
    shuffle(city)
218
219
#---3. Sort on y-coordinate and connect sequentially by y.
220
221
    ySort(city)
222
223
#---4. Sort on x-coordinate and connect sequentially by x.
224
225
    xSort(city)
226
227
#---5. Greedy Algorithm
228-
#---5. Your algorithm(s). Can you do better than the sorting algorithms above?
228+
229
    for x in range(len(city)-1):
230
        print(x)
231
        if x==0:
232
            z.append(city[x])
233
        temp=dist(city[x],city[x+1])
234
        for y in range(len(city)-1):
235
            if dist(city[x],city[y+1])<temp:
236
                z.append(city[y+1])
237
                break
238
    city=z
239-
    print(temp)
239+
240-
    print(len(z))
240+
241-
    print(len(city))
241+
242
#---------------------------------------------------------------------------------Traveling Salesman Problem--
243
if __name__ == '__main__': main()
244
###############################################<END OF PROGRAM>###############################################