Tuesday, January 23, 2018

Non-sequential 5-opt moves – part 3 of 7

Extending crossed bridge or double bridge 'from d3'

If we take a closer look at diagram for AdebC move type, we can notice that it cannot be made by extending double bridge or crossed bridge from the last city (d4) in move, if the second submove starts from d1-d2:

c1 c2 c3 c4 d1 d2 d4

On the other hand, if we denoted the city we want to extend move from as d3, then there would be no consistency in the numbering:

c1 c2 c3 c4 d1 d2 d3 d4 d5 d6

Note that so far we used only d1-d2 ordering. Instead we can use the first two cities in the reverse order:

proc LK_Bridge_A1(...) =
...
      improved = LK_Bridge_A2(cF1, cF2, cF3, cF4, d1, d2, Ga)
      if not improved:
        improved = LK_Bridge_A2(cF1, cF2, cF3, cF4, d2, d1, Ga) # NOTE

and get

c1 c2 c3 c4 d2 d1 d4 d3 d1 d4 d5 d6 d1 d4 d5 d6

Using the same approach we obtain:

proc LK_Bridge_A3(...) = 
...
  fwd = (d2 == t_succ(d1))
...
      # choose d6
      case tourOrderPrev
      of TO_ADBC:
        if fwd:
          d6 = t_pred(d5)
          if inOrder(d3, d5, c1, true):
            tourOrder = TO_AxdECB_1   # AdECB
          elif inOrder(c4, d5, d4, true):
            tourOrder = TO_AxcxeDB_1  # AceDB
          elif inOrder(d2, d5, c3, true):
            tourOrder = TO_AxbxdxeC_1 # AbdeC
          else:
            tourOrder = TO_AxbEDC_1   # AbEDC
        else:  # not fwd
          d6 = t_succ(d5)
          if inOrder(d3, d5, c1, true):
            tourOrder = TO_ADxcxeB_3  # ADceB
          elif inOrder(c4, d5, d4, true):
            tourOrder = TO_AECxdB_3   # AECdB
          elif inOrder(d1, d5, c3, true):
            tourOrder = TO_AEDxbC_3   # AEDbC
          else:
            tourOrder = TO_AxdxexbC_3 # AdebC
        #end_if fwd
      of TO_AxcxdB:
        if fwd:
          if inOrder(d3, d5, c1, true):
            d6 = t_succ(d5)
            tourOrder = TO_AECxdB_2   # AECdB
          elif inOrder(c4, d5, d4, true):
            d6 = t_succ(d5)
            tourOrder = TO_ADxcxeB_2  # ADceB
          elif inOrder(d2, d5, c3, true):
            d6 = t_pred(d5)
            tourOrder = TO_AxbEDC_2   # AbEDC
          else:
            d6 = t_pred(d5)
            tourOrder = TO_AxbxdxeC_2 # AbdeC
        else:  # not fwd
          if inOrder(d4, d5, c1, true):
            d6 = t_pred(d5)
            tourOrder = TO_AEDxbC_4   # AEDbC
          elif inOrder(c4, d5, d3, true):
            d6 = t_pred(d5)
            tourOrder = TO_AxdxexbC_4 # AdebC
          elif inOrder(d1, d5, c3, true):
            d6 = t_succ(d5)
            tourOrder = TO_AxdECB_4   # AdECB
          else:
            d6 = t_succ(d5)
            tourOrder = TO_AxcxeDB_4  # AceDB
        #end_if fwd
...

and

proc Make_5opt_NS_Move(...) =
  case tourOrder
  of TO_AxbEDC_1, TO_AxbxdxeC_1, TO_AxcxeDB_1, TO_AxdECB_1:
    Exchange_Links(d1, d2, d4, d3)
    Exchange_Links(c1, c2, c4, c3)
    Exchange_Links(d1, d3, d4, d2)
    Exchange_Links(d1, d4, d6, d5)
  of TO_AxbxdxeC_2, TO_AxbEDC_2, TO_ADxcxeB_2, TO_AECxdB_2:
    Exchange_Links(d1, d2, d4, d3)
    Exchange_Links(c1, c2, c4, c3)
    Exchange_Links(d1, d4, d6, d5)

  of TO_ADxcxeB_3, TO_AECxdB_3, TO_AEDxbC_3, TO_AxdxexbC_3:
    Exchange_Links(d2, d1, d4, d3)
    Exchange_Links(c1, c2, c4, c3)
    Exchange_Links(d2, d3, d4, d1)
    Exchange_Links(d1, d4, d6, d5)
  of TO_AEDxbC_4, TO_AxdxexbC_4, TO_AxdECB_4, TO_AxcxeDB_4:
    Exchange_Links(d2, d1, d4, d3)
    Exchange_Links(c1, c2, c4, c3)
    Exchange_Links(d1, d4, d6, d5)
  ...

Adding these additional types for "backward" second submove requires more code, as can be seen above, slightly changes running times, but makes resulting tours less than 0.1% better, so it may or may be not worth introducing.

No comments:

Post a Comment