Monday, April 3, 2017

2-opt with Neighbor Lists and Best from given City

proc One_City_2_Opt_N_Best_From_City(tour: var Tour_Array;
                                     basePos: Tour_Index;
                                     neighbor: Neighbor_Matrix;
                                     position: var City_Position_In_Tour;
                                     numberOfNeigbors: int): bool =
  ## Makes the best of improving moves starting from given city
  type
    Move2 = object
      i, j: Tour_Index
      gain: Length_Gain
  var
    improved: bool
    pos_Y2, i, j: Tour_Index
    X1, X2, Y1, Y2: City_Number
    gainExpected: Length_Gain
    bestMove: Move2

  improved = false
  bestMove.gain = 0
  block two_loops:
    for direction in [forward, backward]:
      if direction == forward:
        i  = basePos
        X1 = tour[i]
        X2 = tour[(i+1) mod N]
      else:
        i  = (N + basePos - 1) mod N
        X2 = tour[i]
        X1 = tour[(i+1) mod N]  # == tour[basePos]

      for neighbor_number in 0 .. numberOfNeigbors-1:
        Y1 = neighbor[X1][neighbor_number]
        if direction == forward:
          j = position[Y1]
          Y2 = tour[(j+1) mod N]
        else:
          j  = (N + position[Y1] - 1) mod N  # pos[Y1] == j+1
          Y2 = tour[j]

        if (X2 == Y1) or (Y2 == X1):
          continue

        gainExpected = Gain_From_2_Opt(X1, X2, Y1, Y2)
        if  gainExpected > bestMove.gain:
          bestMove = Move2(i: i,  j: j,  gain: gainExpected)
          improved = true
  if improved:
    Make_2_Opt_Move(tour, bestMove.i, bestMove.j, position)
  result = improved
proc LS_2_Opt_N_BC(tour: var Tour_Array;
                   neighbor: Neighbor_Matrix;
                   neighborListLen: int = N-1) =
  ## Optimizes tour using 2-opt with neighbor lists and fixed radius,
  ## for each city makes the best of improving moves that starts from it
  var
    locallyOptimal: bool = false
    improved: bool
    position: City_Position_In_Tour

  let numberOfNeigbors = min(neighborListLen, len(neighbor[0]))
  position = Create_Position_In_Tour(tour)

  while not locallyOptimal:
    locallyOptimal = true
    for basePos in 0 .. N-1:
      improved = One_City_2_Opt_N_Best_From_City(tour, basePos,
                                                 neighbor, position,
                                                 numberOfNeigbors)
      if improved:
        locallyOptimal = false

Some simple statistics

Relative time, best length, average length and worst length for all tours created by NN heuristic and improved by some 2-opt algorithms. Random planar problems, N=200.
Problem # Method Time Best Avg Worst
1NN100100.00109.58116.87
NN + 2opt442189.6692.5096.98
NN + 2opt Take Best495387.9390.7792.79
NN + 2opt-NR(24)26588.9491.3295.01
NN + 2opt-ND(24)23188.7292.7796.39
NN + 2opt-NDR(24)13489.3692.0595.94
NN + 2opt-N-BC(24)49789.2092.1896.75
NN + 2opt-NR-BC(24)23488.4290.9095.06
2NN100100.00106.22113.13
NN + 2opt428988.2791.2095.07
NN + 2opt Take Best505388.5390.1292.64
NN + 2opt-NR(24)26587.7890.2693.83
NN + 2opt-ND(24)26588.9691.5194.93
NN + 2opt-NDR(24)13187.8390.7993.90
NN + 2opt-N-BC(24)49987.8390.7493.97
NN + 2opt-NR-BC(24)23187.1189.9193.20
3NN100100.00110.81122.10
NN + 2opt350390.5894.0999.85
NN + 2opt Take Best425990.3193.0196.21
NN + 2opt-NR(24)20190.7693.9297.50
NN + 2opt-ND(24)17590.5094.74100.37
NN + 2opt-NDR(24)12591.1094.4799.50
NN + 2opt-N-BC(24)40390.6994.0999.06
NN + 2opt-NR-BC(24)17790.2693.5497.36
4NN100100.00108.19115.51
NN + 2opt415589.1692.4897.91
NN + 2opt Take Best482188.6391.1394.83
NN + 2opt-NR(24)33188.1891.5796.27
NN + 2opt-ND(24)23489.3693.0896.79
NN + 2opt-NDR(24)13188.7491.8296.09
NN + 2opt-N-BC(24)59788.4492.3396.40
NN + 2opt-NR-BC(24)19988.2391.6695.12
5NN100100.00105.47111.66
NN + 2opt310088.4491.2094.82
NN + 2opt Take Best312587.9390.8393.19
NN + 2opt-NR(24)19887.5590.3393.73
NN + 2opt-ND(24)19888.0491.8095.37
NN + 2opt-NDR(24)12388.0790.9895.03
NN + 2opt-N-BC(24)32288.0691.2194.08
NN + 2opt-NR-BC(24)17387.4590.1194.13
6NN100100.00106.99115.27
NN + 2opt511988.6191.7095.36
NN + 2opt Take Best555386.7489.3692.40
NN + 2opt-NR(24)29787.6790.3993.91
NN + 2opt-ND(24)23487.9991.1494.90
NN + 2opt-NDR(24)13187.6390.7593.93
NN + 2opt-N-BC(24)50087.4990.5593.80
NN + 2opt-NR-BC(24)23186.6989.7091.95
7NN100100.00109.06119.98
NN + 2opt485387.4390.8695.27
NN + 2opt Take Best475386.1489.4194.34
NN + 2opt-NR(24)26585.7489.6695.14
NN + 2opt-ND(24)26587.5891.1296.98
NN + 2opt-NDR(24)13486.6490.1596.67
NN + 2opt-N-BC(24)56586.8390.7495.90
NN + 2opt-NR-BC(24)33185.8389.6895.53
8NN100100.00106.79113.15
NN + 2opt495387.2691.3095.33
NN + 2opt Take Best565187.6589.5392.11
NN + 2opt-NR(24)23188.0790.2793.96
NN + 2opt-ND(24)23488.3191.6095.67
NN + 2opt-NDR(24)13188.1390.9995.28
NN + 2opt-N-BC(24)50087.8190.1194.61
NN + 2opt-NR-BC(24)23187.3689.2092.07
9NN100100.00104.58109.98
NN + 2opt408987.8691.8095.52
NN + 2opt Take Best501987.1889.6691.63
NN + 2opt-NR(24)39987.9690.7394.13
NN + 2opt-ND(24)23188.5391.9494.86
NN + 2opt-NDR(24)36588.2491.0694.24
NN + 2opt-N-BC(24)92988.0391.0094.26
NN + 2opt-NR-BC(24)53187.7390.2993.77
10NN100100.00106.10113.14
NN + 2opt668288.4690.9094.87
NN + 2opt Take Best558587.8289.7291.80
NN + 2opt-NR(24)29787.9490.7395.79
NN + 2opt-ND(24)23487.7091.5194.74
NN + 2opt-NDR(24)16587.9691.1896.28
NN + 2opt-N-BC(24)56387.8890.5693.03
NN + 2opt-NR-BC(24)23486.4489.7992.67

No comments:

Post a Comment