Advertisement
cat_baxter

ATSP 25x25

Oct 11th, 2013
87
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 5.06 KB | None | 0 0
  1. '''
  2.  
  3. Branch and bound Algorithm for Travelling Salesman Problem
  4.  
  5. based on
  6.  
  7. http://www.cs.sunysb.edu/~algorith/implement/syslo/distrib/processed/babtsp.p
  8.  
  9. '''
  10.  
  11. import time
  12. import random
  13.  
  14. INF = 100000000
  15.  
  16. best_cost = 0
  17.  
  18. def reduce(size, w, row, col, rowred, colred):
  19.     rvalue = 0
  20.     for i in xrange(size):
  21.         temp = INF
  22.         for j in xrange(size):
  23.             temp = min(temp, w[row[i]][col[j]])
  24.         if temp > 0:
  25.             for j in xrange(size):
  26.                 if w[row[i]][col[j]] < INF:
  27.                     w[row[i]][col[j]] -= temp
  28.             rvalue += temp
  29.         rowred[i] = temp
  30.     for j in xrange(size):
  31.         temp = INF
  32.         for i in xrange(size):
  33.             temp = min(temp, w[row[i]][col[j]])
  34.         if temp > 0:
  35.             for i in xrange(size):
  36.                 if w[row[i]][col[j]] < INF:
  37.                     w[row[i]][col[j]] -= temp
  38.             rvalue += temp
  39.         colred[j] = temp
  40.     return rvalue
  41.  
  42.  
  43. def bestEdge(size, w, row, col):
  44.     mosti = -INF
  45.     ri = 0
  46.     ci = 0
  47.     for i in xrange(size):
  48.         for j in xrange(size):
  49.             if not w[row[i]][col[j]]:
  50.                 minrowwelt = INF
  51.                 zeroes = 0
  52.                 for k in xrange(size):
  53.                     if not w[row[i]][col[k]]:
  54.                         zeroes += 1
  55.                     else:
  56.                         minrowwelt = min(minrowwelt, w[row[i]][col[k]])
  57.                 if zeroes > 1: minrowwelt = 0
  58.                 mincolwelt = INF
  59.                 zeroes = 0
  60.                 for k in xrange(size):
  61.                     if not w[row[k]][col[j]]:
  62.                         zeroes += 1
  63.                     else:
  64.                         mincolwelt = min(mincolwelt, w[row[k]][col[j]])
  65.                 if zeroes > 1: mincolwelt = 0
  66.                 if minrowwelt + mincolwelt > mosti:
  67.                     mosti = minrowwelt + mincolwelt
  68.                     ri = i
  69.                     ci = j
  70.     return mosti, ri, ci
  71.  
  72.  
  73. def explore(n, w, edges, cost, row, col, best, fwdptr, backptr):
  74.     global best_cost
  75.  
  76.     colred = [0 for _ in xrange(n)]
  77.     rowred = [0 for _ in xrange(n)]
  78.     size = n - edges
  79.     cost += reduce(size, w, row, col, rowred, colred)
  80.     if cost < best_cost:
  81.         if edges == n - 2:
  82.             for i in xrange(n): best[i] = fwdptr[i]
  83.             if w[row[0]][col[0]] >= INF:
  84.                 avoid = 0
  85.             else:
  86.                 avoid = 1
  87.             best[row[0]] = col[1 - avoid]
  88.             best[row[1]] = col[avoid]
  89.             best_cost = cost
  90.         else:
  91.             mostv, rv, cv = bestEdge(size, w, row, col)
  92.             lowerbound = cost + mostv
  93.             fwdptr[row[rv]] = col[cv]
  94.             backptr[col[cv]] = row[rv]
  95.             last = col[cv]
  96.             while fwdptr[last] != INF: last = fwdptr[last]
  97.             first = row[rv]
  98.             while backptr[first] != INF: first = backptr[first]
  99.             colrowval = w[last][first]
  100.             w[last][first] = INF
  101.             newcol = [INF for _ in xrange(size)]
  102.             newrow = [INF for _ in xrange(size)]
  103.             for i in xrange(rv): newrow[i] = row[i]
  104.             for i in xrange(rv, size - 1): newrow[i] = row[i + 1]
  105.             for i in xrange(cv): newcol[i] = col[i]
  106.             for i in xrange(cv, size - 1): newcol[i] = col[i + 1]
  107.             explore(n, w, edges + 1, cost, newrow, newcol, best, fwdptr, backptr)
  108.             w[last][first] = colrowval
  109.             backptr[col[cv]] = INF
  110.             fwdptr[row[rv]] = INF
  111.             if lowerbound < best_cost:
  112.                 w[row[rv]][col[cv]] = INF
  113.                 explore(n, w, edges, cost, row, col, best, fwdptr, backptr)
  114.                 w[row[rv]][col[cv]] = 0
  115.  
  116.     for i in xrange(size):
  117.         for j in xrange(size):
  118.             w[row[i]][col[j]] = w[row[i]][col[j]] + rowred[i] + colred[j]
  119.  
  120.  
  121. def atsp(w):
  122.     global best_cost
  123.     size = len(w)
  124.     col = [i for i in xrange(size)]
  125.     row = [i for i in xrange(size)]
  126.     best = [0 for _ in xrange(size)]
  127.     route = [0 for _ in xrange(size)]
  128.     fwdptr = [INF for _ in xrange(size)]
  129.     backptr = [INF for _ in xrange(size)]
  130.     best_cost = INF
  131.  
  132.     explore(size, w, 0, 0, row, col, best, fwdptr, backptr)
  133.  
  134.     index = 0
  135.     for i in xrange(size):
  136.         route[i] = index
  137.         index = best[index]
  138.     index = []
  139.     cost = 0
  140.  
  141.     for i in xrange(size):
  142.         if i != size - 1:
  143.             src = route[i]
  144.             dst = route[i + 1]
  145.         else:
  146.             src = route[i]
  147.             dst = 0
  148.         cost += w[src][dst]
  149.         index.append([src, dst])
  150.     return cost, index
  151.  
  152.  
  153. def main():
  154.     # adjasted matrix
  155.  
  156.     N = 25
  157.     m = [[0 for i in range(N)] for j in range(N)]
  158.     for row in range(N):
  159.         for pos in range(N):
  160.             m[row][pos] = INF if row == pos else random.randint(1,6000)
  161.  
  162.     print('Size = %d' % N)
  163.     for r in m:
  164.         print r
  165.  
  166.     start_time = time.time()
  167.     cost, path = atsp(m)
  168.     print "Cost = ", cost
  169.     print "Path = ", path
  170.     print "Time (s)", time.time() - start_time
  171.  
  172. if __name__ == "__main__":
  173.     main()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement