Example #1
0
def merge_double_bridge(xy, best_order, start_point):
    original_length = len(best_order)
    trial_order = double_bridge.perturbed_climb(xy, best_order, 1)
    trial_length = basic.tour_length(xy, trial_order)
    print("trial tour length: " + str(trial_length))

    old_edges, new_edges = tour_diff(best_order, trial_order)
    basic.write_edges(old_edges, "output/old_edges_test.txt")
    basic.write_edges(new_edges, "output/new_edges_test.txt")

    best_order = merge(xy, best_order, trial_order)
    new_length = basic.tour_length(xy, best_order)
    print("new length: " + str(new_length))
    assert (trial_length >= new_length)
    assert (len(best_order) == original_length)
    return best_order
Example #2
0
def perturbed_climb(xy, order, iterations):
    best_order = order[:]
    best_length = basic.tour_length(xy, best_order)
    climber = TwoOpt(xy)
    climber.tour.reset(best_order)
    for i in range(iterations):
        climber.tour.double_bridge_perturbation()
        climber.optimize()
        new_length = climber.tour.tour_length()
        if new_length < best_length:
            best_order = climber.tour.node_ids
            best_length = new_length
        else:
            climber.tour.reset(best_order)
    return climber.tour.node_ids
Example #3
0
def perturbed_hill_climb(xy, tour):
    tries = 0
    success = 0
    best_length = tour_util.length(xy, tour)
    while True:
        new_tour, naive_new_length = two_opt.optimize(xy, tour_util.double_bridge(tour)) # double bridge
        #test_tour = tour[:]
        #random.shuffle(test_tour)
        #new_tour, naive_new_length = two_opt.optimize(xy, test_tour) # random restart
        segments = Splitter(tour, new_tour).get_segments()
        kmoves = segments_to_beneficial_kmoves(xy, segments, tour)
        max_gain = 0
        if kmoves:
            max_gain = sum([k[0] for k in kmoves])
        naive_gain = best_length - naive_new_length
        # There may be cases where naive gain is more than decomposed gains:
        # decomposed gains currently only return moves that can be independently performed.
        # Infeasible moves that are improvements but only can be combined with other moves to become feasible
        # (a potentially computationally expensive search) wil be excluded from the decomposed moves.
        dd_gain = 0 # gain due to decomposed kmoves.
        if kmoves:
            for k in kmoves:
                print('    trying {}-opt move with gain {}'.format(len(k[1]['adds']), k[0]))
                test_tour = perform_kmove(tour, k[1])
                if len(test_tour) == len(tour):
                    tour = test_tour
                    best_length -= k[0]
                    dd_gain += k[0]
        if naive_gain > dd_gain:
            print('naive_gain ({}) greater than dd_gain ({})'.format(naive_gain, dd_gain))
            tour = new_tour
            best_length = naive_new_length
        if naive_gain > 0 or dd_gain > 0:
            success += 1
        if dd_gain > 0 and dd_gain > naive_gain:
            print('    dd gain {} greater than naive gain {}'.format(dd_gain, naive_gain))
        tries += 1
        current_length = basic.tour_length(xy, tour)
        assert(best_length == current_length)
        if current_length <= TARGET_LENGTH:
            break
        print('current best: {} (iteration {}), improvement rate: {}'.format(best_length, tries, success / tries))
Example #4
0
def perturbed_hill_climb_naive(xy, tour):
    tries = 0
    success = 0
    best_length = tour_util.length(xy, tour)
    while True:
        new_tour, naive_new_length = two_opt.optimize(xy, tour_util.double_bridge(tour)) # double bridge
        #test_tour = tour[:]
        #random.shuffle(test_tour)
        #new_tour, naive_new_length = two_opt.optimize(xy, test_tour) # random restart
        naive_gain = best_length - naive_new_length
        if naive_gain > 0:
            tour = new_tour
            best_length = naive_new_length
            success += 1
        tries += 1
        current_length = basic.tour_length(xy, tour)
        assert(best_length == current_length)
        if current_length <= TARGET_LENGTH:
            break
        print('current best: {} (iteration {}), improvement rate: {}'.format(best_length, tries, success / tries))
Example #5
0
    basic.write_edges(old_edges, "output/old_edges_test.txt")
    basic.write_edges(new_edges, "output/new_edges_test.txt")

    best_order = merge(xy, best_order, trial_order)
    new_length = basic.tour_length(xy, best_order)
    print("new length: " + str(new_length))
    assert (trial_length >= new_length)
    assert (len(best_order) == original_length)
    return best_order


if __name__ == "__main__":
    xy = reader.read_xy("../data/xqf131.tsp")

    order = [i for i in range(len(xy))]
    random.shuffle(order)
    order = opt2(order)
    print("initial tour length: " + str(basic.tour_length(xy, order)))
    for i in range(1000):
        basic.write_edges_from_order(order, "output/order_test.txt")
        print("merge iteration: " + str(i))
        premerge_length = basic.tour_length(xy, order)
        #order = merge_nn(xy, order, i)
        order = merge_double_bridge(xy, order, i)
        postmerge_length = basic.tour_length(xy, order)
        if postmerge_length != premerge_length:
            order = opt2(order)
            postmerge_climb_length = basic.tour_length(xy, order)
            if postmerge_climb_length != postmerge_length:
                print("post-merge hill climb: " + str(postmerge_climb_length))
Example #6
0
 def tour_length(self):
     return basic.tour_length(self.xy, self.node_ids)