Tuesday, August 29, 2017

LK – subsequent 3-opt move

Subsequent move in Lin-Kernighan optimization does not need to be 2-opt as in original algorithm. We can use 3-opt as well, or any other sequential type of move:

proc LK_Subsequent3Move(c1, c2: City_Number;
                        G1a: var Length_Gain;
                        cLast: var City_Number): bool =
  # cLast is set to last city in sequential move when promising move
  # has been found and applied
  var
    improved: bool
    c3, c4, c5, c6: City_Number
    c2_pred, c2_succ: City_Number
    c3_pred, c3_succ: City_Number
    c4_pred, c4_succ: City_Number
    c5_pred, c5_succ: City_Number
    fwd: bool
    c4_A, c4_B:  City_Number
    G1, Ga, G2a, G2, G3a, gainFromCloseUp: Length_Gain
    tried_c3, tried_c5: int
    tourOrder2, tourOrder3: int
    c3_BG, c4_BG, c5_BG, c6_BG: City_Number
    Ga_BG: Length_Gain
    tourOrder_BG: int

  improved = false
  fwd = (c2 == t_succ(c1))
  c2_succ = t_succ(c2)
  c2_pred = t_pred(c2)

  block find_promising_moves:
    tried_c3 = 0
    Ga_BG = 0
    for c3 in neighbors(c2):
      if tried_c3 >= Max_Breadth_S:
        break
      if (c3 == c2_succ) or (c3 == c2_pred):
        continue
      if isLinkAdded(c2, c3):
        continue
      G1 = G1a - distance(c2, c3)
      if G1 <= 0:
        break
      c3_succ = t_succ(c3)
      c3_pred = t_pred(c3)
      if fwd:
        c4_A = t_pred(c3)
        c4_B = t_succ(c3)
      else:
        c4_A = t_succ(c3)
        c4_B = t_pred(c3)
      for c4 in [c4_A, c4_B]:
        if isLinkAdded(c4, c1):
          continue
        tried_c3 = tried_c3 + 1
        G2a = G1 + distance(c3, c4)
        if (c4 == c4_B):
          tourOrder2 = TO_1234
        else:
          tourOrder2 = TO_1243
          gainFromCloseUp = G2a - distance(c4, c1)
          if gainFromCloseUp > 0:  # improving move found
            improved = true
            Make_2opt_Move(c1, c2, c3, c4)
            tourLen = tourLen - gainFromCloseUp
            G1a = G2a
            cLast = c4
            # don't look bits for c1, c2 should be set at previous level
            Set_DLB_off(DontLook, [c3, c4])
            break find_promising_moves
        # 3-opt
        c4_succ = t_succ(c4)
        c4_pred = t_pred(c4)
        tried_c5 = 0
        for c5 in neighbors(c4):
          if tried_c5 >= Max_Breadth_S:
            break
          if (c5 == c4_succ) or (c5 == c4_pred):
            continue
          if isLinkAdded(c4, c5):
            continue
          G2 = G2a - distance(c4, c5)
          if G2  <= 0:
            break
          c5_succ = t_succ(c5)
          c5_pred = t_pred(c5)
          for c6 in [c5_succ, c5_pred]:
            if (c6 == c1):
              continue
            if isLinkAdded(c6, c1):
              continue
            tourOrder3 = TO_00
            case tourOrder2
            of TO_1234:
              if inOrder(c2, c5, c3, fwd):
                if inOrder(c2, c6, c5, fwd):
                  tourOrder3 = TO_126534
                else:
                  tourOrder3 = TO_125634
            of TO_1243:
              if inOrder(c2, c5, c4, fwd):
                if inOrder(c2, c6, c5, fwd):
                  continue
                else:
                  tourOrder3 = TO_125643
              else:
                if inOrder(c3, c6, c5, fwd):
                  tourOrder3 = TO_124365
            else:
              continue
            #end_case tourOrder2
            if tourOrder3 == TO_00:
              continue
            tried_c5 = tried_c5 + 1
            G3a = G2 + distance(c5, c6)
            gainFromCloseUp = G3a - distance(c6, c1)
            if gainFromCloseUp > 0:
              improved = true
              Make_3opt_Move(c1, c2, c3, c4, c5, c6, tourOrder3)
              tourLen = tourLen - gainFromCloseUp
              G1a = G3a
              cLast = c6
              Set_DLB_off(DontLook, [c3, c4, c5, c6])
              break find_promising_moves
            if G3a > Ga_BG:
              Ga_BG = G3a
              c3_BG  = c3
              c4_BG  = c4
              c5_BG  = c5
              c6_BG  = c6
              tourOrder_BG = tourOrder3
    #end loop for c3
  #end block find_promising_moves

  block make_best_3move:
    if improved:
      break make_best_3move
    if Ga_BG <= 0:
      break make_best_3move
    Make_3opt_Move(c1, c2,
                   c3_BG, c4_BG, c5_BG, c6_BG, tourOrder_BG)
    G1a = Ga_BG
    cLast = c6_BG
    AddtoLinksAdded(c3_BG, c4_BG)
    AddtoLinksAdded(c5_BG, c6_BG)
    Set_DLB_off(DontLook, [c3_BG, c4_BG, c5_BG, c6_BG])
  #end block make_best_3move

  result = improved

Beware

Note that while 2-opt move is just single exchange of two pairs of links, 3-opt move constists of two or three such exchanges. Therefore we should modify the way we count levels for subsequent moves (needed to restrict their number). Instead of incrementing local SubseqLvl variable inside LK_5Move or LK_scheme, we should make it a global variable and increment it while actually performing the basic tour transformation, that is: inside Exchange_Links.

Thursday, August 10, 2017

LK – alternative calling subsequent moves

Used with bigger values for breadths (eg. 24, 24, 24, 24, 24, Max_Breadth_K=3) gives similar results, but is up to two times faster than the code showed previously. Some people find this approach also simpler and more convincing.

type
  PromisingMove = object
    c1, c2, c3, c4, c5, c6, c7, c8, c9, c10: City_Number
    Ga: Length_Gain
    moveType: int
    tourOrder: int
const
  HalfListSize = 20
var
  promisingMoves: array[0..2*HalfListSize, PromisingMove]
  emptyListPos: int

proc ClearPromisingMoves() =
  for i in 0 .. len(promisingMoves)-1:
    promisingMoves[i].Ga = 0
  emptyListPos = 0

proc SortPromisingMoves() =
  sort(promisingMoves) do (x,y: PromisingMove) -> int:
       result = cmp(y.Ga, x.Ga)

proc AddToPromisingMoves(move: PromisingMove) =
  promisingMoves[emptyListPos] = move
  emptyListPos = emptyListPos + 1
  if emptyListPos > 2*HalfListSize:
    # sort list by gain, then treat worse half as not filled
    SortPromisingMoves()
    emptyListPos = HalfListSize + 1

proc GetAllPromisigMoves(): seq[PromisingMove] =
  var
    allMoves: seq[PromisingMove]
  allMoves = @[]  # empty list (sequence)
  SortPromisingMoves()
  for i in 0 .. min(emptyListPos, HalfListSize)-1:
    allMoves.add(promisingMoves[i])
  result = allMoves
proc LK_5Move(c1, c2, c3, c4, c5, c6, c7, c8: City_Number;
              G4a: Length_Gain;
              tourOrderPrev: int): bool =
  var
    ...
    move: PromisingMove
...    
  move.c1 = c1
  move.c2 = c2
  move.c3 = c3
  move.c4 = c4
  move.c5 = c5
  move.c6 = c6
  move.c7 = c7
  move.c8 = c8
...
  block find_promising_moves:
    ...
  #end_block find_promising_moves
    
  block evaluate_promising_moves:
    ...
      if moveType != move_type_0: # connecting move
        gainFromCloseUp = Ga - distance(c10, c1)
        if gainFromCloseUp > 0:
          # improving move found
          improved = true
          Make_5opt_Move(c1, c2, c3, c4, c5, c6, c7, c8, c9, c10,
                         tourOrder)
          tourLen = tourLen - gainFromCloseUp
          Set_DLB_off(DontLook,
                      [c1, c2, c3, c4, c5, c6, c7, c8, c9, c10])
          break evaluate_promising_moves
          
      when true: # not OPT_6_IMPLEMENTED
        move.c9  = c9 
        move.c10 = c10
        move.Ga  = Ga
        move.moveType  = moveType
        move.tourOrder = tourOrder
        AddToPromisingMoves(move)
    #end_loop for mve
  #end_block evaluate_promising_moves
  result = improved
proc LK_1SubsequentMoves():bool =
  var
    improved: bool
    promisingMovesList: seq[PromisingMove]
    breadth: int
    c1, c2, c3, c4, c5, c6, c7, c8, c9, c10:  City_Number
    Ga: Length_Gain
    tourOrder: int
    moveType: int
    searching: bool
    c2subseq, cLast:  City_Number

  improved = false
  block evaluate_promising_moves:
    # here we should try to use general subsequent move
    # after temporary applying 5-opt move
    promisingMovesList = GetAllPromisigMoves()
    breadth = min(len(promisingMovesList), Max_Breadth_K)  ## NOTE
    if breadth == 0:
      break evaluate_promising_moves

    Save_Tour()
    Save_DLB()
    for mve in 0 .. breadth-1:
      c1  = promisingMovesList[mve].c1
      c2  = promisingMovesList[mve].c2
      c3  = promisingMovesList[mve].c3
      c4  = promisingMovesList[mve].c4
      c5  = promisingMovesList[mve].c5
      c6  = promisingMovesList[mve].c6
      c7  = promisingMovesList[mve].c7
      c8  = promisingMovesList[mve].c8
      c9  = promisingMovesList[mve].c9
      c10 = promisingMovesList[mve].c10
      Ga  = promisingMovesList[mve].Ga
      #moveType = promisingMovesList[mve].moveType
      tourOrder = promisingMovesList[mve].tourOrder

      c2subseq = c10
      cLast = c10
      LinksAddedClear()
      AddtoLinksAdded(c2, c3)
      AddtoLinksAdded(c4, c5)
      AddtoLinksAdded(c6, c7)
      AddtoLinksAdded(c8, c9)
      Make_5opt_Move(c1, c2, c3, c4, c5, c6, c7, c8, c9, c10,
                     tourOrder)
      Set_DLB_off(DontLook,
                  [c1, c2, c3, c4, c5, c6, c7, c8, c9, c10])
      searching = true
      SubseqLvl = 0
      while searching:
        improved = LK_Subsequent3Move(c1, c2subseq, Ga, cLast)
        if improved:
          break evaluate_promising_moves
        else:
          if c2subseq == cLast: # end of promising moves
            Restore_Tour()
            Restore_DLB()
            searching = false
          else:
            c2subseq = cLast
        if SubseqLvl >= Max_Depth:
          searching = false
          Restore_Tour()
          Restore_DLB()
    #end_loop log mve
  #end_block evaluate_promising_moves
  result = improved
proc LK_scheme() =
  var
    locallyOptimal: bool = false
    improved: bool
    baseCity: City_Number

  position = Create_Position_In_Tour(tour)
  Set_DLB_off(DontLook, tour)

  while not locallyOptimal:
    locallyOptimal = true
    for baseCity in 0 .. N-1:
      if isDLB_on(DontLook, baseCity):
        continue 

      ClearPromisingMoves()
      # first move:
      improved = LK_1Move(baseCity)
      # subsequent moves:
      if not improved:
        improved = LK_1SubsequentMoves()

      if improved:
        locallyOptimal = false
      else:
        Set_DLB_on(DontLook, baseCity)

    #end_loop for baseCity
  #end_while not locallyOptimal

Friday, July 21, 2017

Extending LK: 5-opt move, part 3/3

const
  # descendants of TO_12345678
  TO_123456789A = 59
  TO_12345678A9 = 60
  TO_1234569A78 = 61
  TO_123456A978 = 62
  TO_12349A5678 = 63
  TO_1234A95678 = 64
  TO_129A345678 = 65
  TO_12A9345678 = 66
  # descendants of TO_12345687
  TO_123456879A = 67
  TO_12345687A9 = 68
  TO_1234569A87 = 69
  TO_123456A987 = 70
  TO_12349A5687 = 71
  TO_1234A95687 = 72
  TO_129A345687 = 73
  TO_12A9345687 = 74
  # descendants of TO_12347856
  TO_123478569A = 75
  TO_12347856A9 = 76
  TO_1234789A56 = 77
  TO_123478A956 = 78
  TO_12349A7856 = 79
  TO_1234A97856 = 80
  TO_129A347856 = 81  # 5-opt
  TO_12A9347856 = 82  # 5-opt
  # descendants of TO_12348756
  TO_123487569A = 83
  TO_12348756A9 = 84
  TO_1234879A56 = 85
  TO_123487A956 = 86
  TO_12349A8756 = 87
  TO_1234A98756 = 88
  TO_129A348756 = 89  # 5-opt
  TO_12A9348756 = 90  # 5-opt
  # descendants of TO_12783456
  TO_127834569A = 91
  TO_12783456A9 = 92
  TO_1278349A56 = 93  # 5-opt
  TO_127834A956 = 94  # 5-opt
  TO_12789A3456 = 95
  TO_1278A93456 = 96
  TO_129A783456 = 97
  TO_12A9783456 = 98
  # descendants of TO_12873456
  TO_128734569A = 99
  TO_12873456A9 = 100
  TO_1287349A56 = 101  # 5-opt
  TO_128734A956 = 102  # 5-opt
  TO_12879A3456 = 103
  TO_1287A93456 = 104
  TO_129A873456 = 105
  TO_12A9873456 = 106
  # descendants of TO_12346578
  TO_123465789A = 107
  TO_12346578A9 = 108
  TO_1234659A78 = 109
  TO_123465A978 = 110
  TO_12349A6578 = 111
  TO_1234A96578 = 112
  TO_129A346578 = 113
  TO_12A9346578 = 114
  # descendants of TO_12346587
  TO_123465879A = 115
  TO_12346587A9 = 116
  TO_1234659A87 = 117
  TO_123465A987 = 118
  TO_12349A6587 = 119
  TO_1234A96587 = 120
  TO_129A346587 = 121  # 5-opt
  TO_12A9346587 = 122  # 5-opt
  # descendants of TO_12347865
  TO_123478659A = 123
  TO_12347865A9 = 124
  TO_1234789A65 = 125
  TO_123478A965 = 126
  TO_12349A7865 = 127
  TO_1234A97865 = 128
  TO_129A347865 = 129  # 5-opt
  TO_12A9347865 = 130  # 5-opt
  # descendants of TO_12348765
  TO_123487659A = 131
  TO_12348765A9 = 132
  TO_1234879A65 = 133
  TO_123487A965 = 134
  TO_12349A8765 = 135
  TO_1234A98765 = 136
  TO_129A348765 = 137
  TO_12A9348765 = 138
  # descendants of TO_12783465
  TO_127834659A = 139
  TO_12783465A9 = 140  # 5-opt
  TO_1278349A65 = 141  # 5-opt
  TO_127834A965 = 142
  TO_12789A3465 = 143
  TO_1278A93465 = 144  # 5-opt
  TO_129A783465 = 145
  TO_12A9783465 = 146  # 5-opt
  # descendants of TO_12873465
  TO_128734659A = 147
  TO_12873465A9 = 148  # 5-opt
  TO_1287349A65 = 149  # 5-opt
  TO_128734A965 = 150
  TO_12879A3465 = 151  # 5-opt
  TO_1287A93465 = 152
  TO_129A873465 = 153  # 5-opt
  TO_12A9873465 = 154
  # descendants of TO_12563478
  TO_125634789A = 155
  TO_12563478A9 = 156
  TO_1256349A78 = 157  # 5-opt
  TO_125634A978 = 158  # 5-opt
  TO_12569A3478 = 159  # 5-opt
  TO_1256A93478 = 160  # 5-opt
  TO_129A563478 = 161  # 5-opt
  TO_12A9563478 = 162  # 5-opt
  # descendants of TO_12563487
  TO_125634879A = 163
  TO_12563487A9 = 164  # 5-opt
  TO_1256349A87 = 165  # 5-opt
  TO_125634A987 = 166
  TO_12569A3487 = 167  # 5-opt
  TO_1256A93487 = 168
  TO_129A563487 = 169  # 5-opt
  TO_12A9563487 = 170
  # descendants of TO_12785634
  TO_127856349A = 171
  TO_12785634A9 = 172
  TO_1278569A34 = 173  # 5-opt
  TO_127856A934 = 174  # 5-opt
  TO_12789A5634 = 175
  TO_1278A95634 = 176
  TO_129A785634 = 177  # 5-opt
  TO_12A9785634 = 178  # 5-opt
  # descendants of TO_12875634
  TO_128756349A = 179
  TO_12875634A9 = 180  # 5-opt
  TO_1287569A34 = 181  # 5-opt
  TO_128756A934 = 182
  TO_12879A5634 = 183
  TO_1287A95634 = 184  # 5-opt
  TO_129A875634 = 185  # 5-opt
  TO_12A9875634 = 186
  # descendants of TO_12567834
  TO_125678349A = 187
  TO_12567834A9 = 188
  TO_1256789A34 = 189
  TO_125678A934 = 190
  TO_12569A7834 = 191  # 5-opt
  TO_1256A97834 = 192  # 5-opt
  TO_129A567834 = 193
  TO_12A9567834 = 194
  # descendants of TO_12568734
  TO_125687349A = 195
  TO_12568734A9 = 196  # 5-opt
  TO_1256879A34 = 197
  TO_125687A934 = 198  # 5-opt
  TO_12569A8734 = 199  # 5-opt
  TO_1256A98734 = 200
  TO_129A568734 = 201
  TO_12A9568734 = 202  # 5-opt
  # descendants of TO_12653478
  TO_126534789A = 203
  TO_12653478A9 = 204
  TO_1265349A78 = 205  # 5-opt
  TO_126534A978 = 206  # 5-opt
  TO_12659A3478 = 207  # 5-opt
  TO_1265A93478 = 208  # 5-opt
  TO_129A653478 = 209  # 5-opt
  TO_12A9653478 = 210  # 5-opt
  # descendants of TO_12653487
  TO_126534879A = 211
  TO_12653487A9 = 212  # 5-opt
  TO_1265349A87 = 213  # 5-opt
  TO_126534A987 = 214
  TO_12659A3487 = 215
  TO_1265A93487 = 216  # 5-opt
  TO_129A653487 = 217
  TO_12A9653487 = 218  # 5-opt
  # descendants of TO_12657834
  TO_126578349A = 219
  TO_12657834A9 = 220  # 5-opt
  TO_1265789A34 = 221
  TO_126578A934 = 222  # 5-opt
  TO_12659A7834 = 223  # 5-opt
  TO_1265A97834 = 224
  TO_129A657834 = 225
  TO_12A9657834 = 226  # 5-opt
  # descendants of TO_12658734
  TO_126587349A = 227
  TO_12658734A9 = 228
  TO_1265879A34 = 229  # 5-opt
  TO_126587A934 = 230  # 5-opt
  TO_12659A8734 = 231
  TO_1265A98734 = 232
  TO_129A658734 = 233  # 5-opt
  TO_12A9658734 = 234  # 5-opt
  # descendants of TO_12786534
  TO_127865349A = 235
  TO_12786534A9 = 236  # 5-opt
  TO_1278659A34 = 237  # 5-opt
  TO_127865A934 = 238
  TO_12789A6534 = 239
  TO_1278A96534 = 240  # 5-opt
  TO_129A786534 = 241  # 5-opt
  TO_12A9786534 = 242
  # descendants of TO_12876534
  TO_128765349A = 243
  TO_12876534A9 = 244
  TO_1287659A34 = 245
  TO_128765A934 = 246
  TO_12879A6534 = 247  # 5-opt
  TO_1287A96534 = 248  # 5-opt
  TO_129A876534 = 249
  TO_12A9876534 = 250
  # descendants of TO_12435678
  TO_124356789A = 251
  TO_12435678A9 = 252
  TO_1243569A78 = 253
  TO_124356A978 = 254
  TO_12439A5678 = 255
  TO_1243A95678 = 256
  TO_129A435678 = 257
  TO_12A9435678 = 258
  # descendants of TO_12435687
  TO_124356879A = 259
  TO_12435687A9 = 260
  TO_1243569A87 = 261
  TO_124356A987 = 262
  TO_12439A5687 = 263  # 5-opt
  TO_1243A95687 = 264  # 5-opt
  TO_129A435687 = 265  # 5-opt
  TO_12A9435687 = 266  # 5-opt
  # descendants of TO_12437856
  TO_124378569A = 267
  TO_12437856A9 = 268  # 5-opt
  TO_1243789A56 = 269
  TO_124378A956 = 270  # 5-opt
  TO_12439A7856 = 271
  TO_1243A97856 = 272  # 5-opt
  TO_129A437856 = 273  # 5-opt
  TO_12A9437856 = 274
  # descendants of TO_12438756
  TO_124387569A = 275
  TO_12438756A9 = 276  # 5-opt
  TO_1243879A56 = 277  # 5-opt
  TO_124387A956 = 278
  TO_12439A8756 = 279  # 5-opt
  TO_1243A98756 = 280
  TO_129A438756 = 281
  TO_12A9438756 = 282  # 5-opt
  # descendants of TO_12784356
  TO_127843569A = 283
  TO_12784356A9 = 284  # 5-opt
  TO_1278439A56 = 285  # 5-opt
  TO_127843A956 = 286
  TO_12789A4356 = 287
  TO_1278A94356 = 288  # 5-opt
  TO_129A784356 = 289
  TO_12A9784356 = 290  # 5-opt
  # descendants of TO_12874356
  TO_128743569A = 291
  TO_12874356A9 = 292  # 5-opt
  TO_1287439A56 = 293
  TO_128743A956 = 294  # 5-opt
  TO_12879A4356 = 295  # 5-opt
  TO_1287A94356 = 296
  TO_129A874356 = 297  # 5-opt
  TO_12A9874356 = 298
  # descendants of TO_12436578
  TO_124365789A = 299
  TO_12436578A9 = 300
  TO_1243659A78 = 301  # 5-opt
  TO_124365A978 = 302  # 5-opt
  TO_12439A6578 = 303  # 5-opt
  TO_1243A96578 = 304  # 5-opt
  TO_129A436578 = 305  # 5-opt
  TO_12A9436578 = 306  # 5-opt
  # descendants of TO_12436587
  TO_124365879A = 307
  TO_12436587A9 = 308  # 5-opt
  TO_1243659A87 = 309  # 5-opt
  TO_124365A987 = 310
  TO_12439A6587 = 311
  TO_1243A96587 = 312  # 5-opt
  TO_129A436587 = 313  # 5-opt
  TO_12A9436587 = 314
  # descendants of TO_12437865
  TO_124378659A = 315
  TO_12437865A9 = 316  # 5-opt
  TO_1243789A65 = 317
  TO_124378A965 = 318  # 5-opt
  TO_12439A7865 = 319  # 5-opt
  TO_1243A97865 = 320
  TO_129A437865 = 321
  TO_12A9437865 = 322  # 5-opt
  # descendants of TO_12438765
  TO_124387659A = 323
  TO_12438765A9 = 324
  TO_1243879A65 = 325  # 5-opt
  TO_124387A965 = 326  # 5-opt
  TO_12439A8765 = 327
  TO_1243A98765 = 328
  TO_129A438765 = 329
  TO_12A9438765 = 330
  # descendants of TO_12784365
  TO_127843659A = 331
  TO_12784365A9 = 332
  TO_1278439A65 = 333  # 5-opt
  TO_127843A965 = 334  # 5-opt
  TO_12789A4365 = 335
  TO_1278A94365 = 336
  TO_129A784365 = 337  # 5-opt
  TO_12A9784365 = 338  # 5-opt
  # descendants of TO_12874365
  TO_128743659A = 339
  TO_12874365A9 = 340  # 5-opt
  TO_1287439A65 = 341
  TO_128743A965 = 342  # 5-opt
  TO_12879A4365 = 343
  TO_1287A94365 = 344  # 5-opt
  TO_129A874365 = 345  # 5-opt
  TO_12A9874365 = 346
  # descendants of TO_12564378
  TO_125643789A = 347
  TO_12564378A9 = 348
  TO_1256439A78 = 349  # 5-opt
  TO_125643A978 = 350  # 5-opt
  TO_12569A4378 = 351  # 5-opt
  TO_1256A94378 = 352  # 5-opt
  TO_129A564378 = 353  # 5-opt
  TO_12A9564378 = 354  # 5-opt
  # descendants of TO_12564387
  TO_125643879A = 355
  TO_12564387A9 = 356  # 5-opt
  TO_1256439A87 = 357  # 5-opt
  TO_125643A987 = 358
  TO_12569A4387 = 359  # 5-opt
  TO_1256A94387 = 360
  TO_129A564387 = 361
  TO_12A9564387 = 362  # 5-opt
  # descendants of TO_12567843
  TO_125678439A = 363
  TO_12567843A9 = 364
  TO_1256789A43 = 365
  TO_125678A943 = 366
  TO_12569A7843 = 367  # 5-opt
  TO_1256A97843 = 368  # 5-opt
  TO_129A567843 = 369
  TO_12A9567843 = 370
  # descendants of TO_12568743
  TO_125687439A = 371
  TO_12568743A9 = 372  # 5-opt
  TO_1256879A43 = 373
  TO_125687A943 = 374  # 5-opt
  TO_12569A8743 = 375  # 5-opt
  TO_1256A98743 = 376
  TO_129A568743 = 377  # 5-opt
  TO_12A9568743 = 378
  # descendants of TO_12785643
  TO_127856439A = 379
  TO_12785643A9 = 380  # 5-opt
  TO_1278569A43 = 381  # 5-opt
  TO_127856A943 = 382
  TO_12789A5643 = 383
  TO_1278A95643 = 384  # 5-opt
  TO_129A785643 = 385  # 5-opt
  TO_12A9785643 = 386
  # descendants of TO_12875643
  TO_128756439A = 387
  TO_12875643A9 = 388
  TO_1287569A43 = 389  # 5-opt
  TO_128756A943 = 390  # 5-opt
  TO_12879A5643 = 391  # 5-opt
  TO_1287A95643 = 392  # 5-opt
  TO_129A875643 = 393
  TO_12A9875643 = 394
  # descendants of TO_12654378
  TO_126543789A = 395
  TO_12654378A9 = 396
  TO_1265439A78 = 397
  TO_126543A978 = 398
  TO_12659A4378 = 399
  TO_1265A94378 = 400
  TO_129A654378 = 401
  TO_12A9654378 = 402
  # descendants of TO_12654387
  TO_126543879A = 403
  TO_12654387A9 = 404
  TO_1265439A87 = 405
  TO_126543A987 = 406
  TO_12659A4387 = 407  # 5-opt
  TO_1265A94387 = 408  # 5-opt
  TO_129A654387 = 409
  TO_12A9654387 = 410
  # descendants of TO_12657843
  TO_126578439A = 411
  TO_12657843A9 = 412  # 5-opt
  TO_1265789A43 = 413
  TO_126578A943 = 414  # 5-opt
  TO_12659A7843 = 415
  TO_1265A97843 = 416  # 5-opt
  TO_129A657843 = 417  # 5-opt
  TO_12A9657843 = 418
  # descendants of TO_12658743
  TO_126587439A = 419
  TO_12658743A9 = 420  # 5-opt
  TO_1265879A43 = 421  # 5-opt
  TO_126587A943 = 422
  TO_12659A8743 = 423  # 5-opt
  TO_1265A98743 = 424
  TO_129A658743 = 425  # 5-opt
  TO_12A9658743 = 426
  # descendants of TO_12786543
  TO_127865439A = 427
  TO_12786543A9 = 428
  TO_1278659A43 = 429  # 5-opt
  TO_127865A943 = 430  # 5-opt
  TO_12789A6543 = 431
  TO_1278A96543 = 432
  TO_129A786543 = 433
  TO_12A9786543 = 434
  # descendants of TO_12876543
  TO_128765439A = 435
  TO_12876543A9 = 436
  TO_1287659A43 = 437
  TO_128765A943 = 438
  TO_12879A6543 = 439
  TO_1287A96543 = 440
  TO_129A876543 = 441
  TO_12A9876543 = 442