コード例 #1
0
def optimizedBestSearch(fname, max_iter=100, pop_size=50, percentToSwitch=5):
    city_locs = tsp.load_city_locs(fname)
    n = len(city_locs)
    curr_gen = [tsp.rand_perm(n) for i in range(pop_size)]
    curr_gen = [(tsp.total_dist(p, city_locs), p) for p in curr_gen]
    curr_gen.sort()

    bestScore = curr_gen[0][0]
    bestPermuation = curr_gen[0][1]
    useMutateSearch = False

    print(
        f'Optimized bestEdges("{fname}", max_iter={max_iter}, pop_size={pop_size}) ...'
    )
    for i in range(max_iter):
        print("iteration: ", i)
        top_half = [p[1] for p in curr_gen[:int(pop_size / 2)]]
        next_gen = top_half[:]
        while len(next_gen) < pop_size:
            parentA = random.choice(top_half)
            parentB = random.choice(top_half)
            while parentA == parentB:
                parentA = random.choice(top_half)
                parentB = random.choice(top_half)
            if (useMutateSearch):
                first = parentA[:]
                second = parentB[:]
            else:
                first, second = bestEdgesSearch(parentA, parentB, city_locs)

            tsp.do_rand_swap(first)
            tsp.do_rand_swap(second)
            next_gen.append(first)
            next_gen.append(second)

        next_gen = next_gen[:pop_size]
        assert len(next_gen) == pop_size
        curr_gen = [(tsp.total_dist(p, city_locs), p) for p in next_gen]
        curr_gen.sort()

        useMutateSearch = ifSwitchToMutate(bestScore, curr_gen[0][0],
                                           percentToSwitch)

        if (curr_gen[0][0] < bestScore):
            bestScore = curr_gen[0][0]
            bestPermuation = curr_gen[0][1]

    print(
        f'... Optimized bestEdges("{fname}", max_iter={max_iter}, pop_size={pop_size})'
    )
    print()
    print(
        f'After {max_iter} generations of {pop_size} permutations, the best is:'
    )
    print(f'score = {bestScore}')
    print(bestPermuation)
    assert tsp.is_good_perm(bestPermuation)
コード例 #2
0
def compareCrossovers():
    cities = tsp.load_city_locs("cities1000.txt")
    permutationA = tsp.rand_perm(1000)
    permutationB = tsp.rand_perm(1000)

    print("Original A: ", tsp.total_dist(permutationA, cities))
    print("Original B: ", tsp.total_dist(permutationB, cities))

    # Order Crossover
    offSpringA, offSpringB = crossovers.orderCrossover(permutationA,
                                                       permutationB)
    print("OffspringB Order: ", tsp.total_dist(offSpringA, cities))
    print("OffspringB Order: ", tsp.total_dist(offSpringB, cities))

    # Partially Mapped Crossover
    offSpringA, offSpringB = crossovers.partiallyMappedCrossover(
        permutationA, permutationB)
    print("OffspringB Partially Mapped: ", tsp.total_dist(offSpringA, cities))
    print("OffspringB Partially Mapped: ", tsp.total_dist(offSpringB, cities))

    # Best Edges Crossover
    offSpringA, offSpringB = bestEdgesSearch(permutationA, permutationB,
                                             cities)
    print("OffspringB Best Edges: ", tsp.total_dist(offSpringA, cities))
    print("OffspringB Best Edges: ", tsp.total_dist(offSpringB, cities))
コード例 #3
0
def orderCrossoverTest(fname, max_iter, pop_size):
    city_locs = tsp.load_city_locs(fname)
    n = len(city_locs)
    # generate permutations for a specific population size
    curr_gen = [tsp.rand_perm(n) for i in range(pop_size)]
    # per population calculate total distance
    curr_gen = [(tsp.total_dist(p, city_locs), p) for p in curr_gen]
    curr_gen.sort()
    assert len(curr_gen) == pop_size

    print(
        f'orderCrossover("{fname}", max_iter={max_iter}, pop_size={pop_size}) ...'
    )
    for i in range(max_iter):
        # copy the top 50% of the population to the next generation, and for the rest randomly
        # cross-breed pairs
        top_half = [p[1] for p in curr_gen[:int(pop_size / 2)]]
        next_gen = top_half[:]
        while len(next_gen) < pop_size:
            parentA = random.choice(top_half)
            parentB = random.choice(top_half)
            while parentA == parentB:
                parentA = random.choice(top_half)
                parentB = random.choice(top_half)
            first, second = orderCrossover(parentA, parentB)
            tsp.do_rand_swap(first)
            tsp.do_rand_swap(second)

            next_gen.append(first)
            next_gen.append(second)

        next_gen = next_gen[:pop_size]

        # create the next generation of (score, permutations) pairs
        assert len(next_gen) == pop_size
        curr_gen = [(tsp.total_dist(p, city_locs), p) for p in next_gen]
        curr_gen.sort()

    print(
        f'... orderCrossover("{fname}", max_iter={max_iter}, pop_size={pop_size})'
    )
    print()
    print(
        f'After {max_iter} generations of {pop_size} permutations, the best is:'
    )
    print(f'score = {curr_gen[0][0]}')
    # print(curr_gen[0][1])
    assert tsp.is_good_perm(curr_gen[0][1])
コード例 #4
0
def GA_top_NWOX(fname, max_iter, prev_pop):
    pop_size = len(prev_pop)
    city_locs = tsp.load_city_locs(fname)
    curr_gen = prev_pop

    scores = []
    print(f'top_NWOX("{fname}", max_iter={max_iter}, pop_size={pop_size}) ...')
    for i in range(max_iter):

        #record historic scores
        scores.append(curr_gen[0][0])

        #select parents
        parents = selection_top(curr_gen)

        #gen childern -> next_gen
        next_gen = []
        for pair in parents:
            #print(pair)
            first, second = crossover_NWOX(pair)
            next_gen.append(first)
            next_gen.append(second)

        #mutate childern
        next_gen = single_mutation(next_gen)
        #next_gen[-1] = curr_gen[0][1]

        #score childern
        assert len(next_gen) == pop_size
        curr_gen = [(tsp.total_dist(p, city_locs), p) for p in next_gen]
        curr_gen.sort()

    return curr_gen, scores
コード例 #5
0
def gen_rand_pop(fname, n_pop):

    city_locs = tsp.load_city_locs(fname)
    n = len(city_locs)
    curr_gen = [tsp.rand_perm(n) for i in range(n_pop)]
    curr_gen = [(tsp.total_dist(p, city_locs), p) for p in curr_gen]
    curr_gen.sort()
    assert len(curr_gen) == n_pop

    return curr_gen
コード例 #6
0
def GA_rw_pmx(fname, max_iter, prev_pop):

    pop_size = len(prev_pop)
    city_locs = tsp.load_city_locs(fname)
    curr_gen = prev_pop
    keep = math.floor(pop_size / 5)
    keep = 0
    assert keep <= pop_size

    scores = []
    print(f'rw_pmx("{fname}", max_iter={max_iter}, pop_size={pop_size}) ...')
    for i in range(max_iter):

        #record historic scores
        scores.append(curr_gen[0][0])

        #select parents
        parents = []
        for i in range(0, keep, 2):
            parents.append((curr_gen[i][1], curr_gen[i + 1][1]))

        parents.extend(selection_rw(curr_gen, 1))

        #gen childern -> next_gen
        next_gen = []
        with concurrent.futures.ThreadPoolExecutor(
                max_workers=200) as executor:
            futures = {
                executor.submit(tsp.pmx, pair[0], pair[1]): pair
                for pair in parents[:pop_size]
            }
            for future in concurrent.futures.as_completed(futures):
                first, second = future.result()
                next_gen.append(first)
                next_gen.append(second)

        next_gen = next_gen[:pop_size]
        # next_gen = []
        # for pair in parents:
        #     #print(pair)
        #     first, second = tsp.pmx(pair[0], pair[1])
        #     next_gen.append(first)
        #     next_gen.append(second)

        #mutate childern
        next_gen = single_mutation(next_gen)
        #next_gen[-1] = curr_gen[0][1]

        #score childern
        assert len(next_gen) == pop_size
        curr_gen = [(tsp.total_dist(p, city_locs), p) for p in next_gen]
        curr_gen.sort()

    return curr_gen, scores
コード例 #7
0
def GA_mutate_search(fname, max_iter, prev_pop):

    pop_size = len(prev_pop)
    city_locs = tsp.load_city_locs(fname)
    n = len(city_locs)

    curr_gen = prev_pop
    curr_gen.sort()

    scores = []
    print(
        f'mutate_search("{fname}", max_iter={max_iter}, pop_size={pop_size}) ...'
    )
    for i in range(max_iter):
        # put best permutation from curr_gen into next generation unchanged
        scores.append(curr_gen[0][0])
        best_curr_gen = curr_gen[0][1]
        next_gen = [best_curr_gen]

        # the rest of the next generation is filled with random swap-mutations
        # of best_curr_gen
        # for j in range(pop_size-1):
        #     perm = best_curr_gen[:]  # make a copy of best_curr_gen
        #     tsp.do_rand_swap(perm)       # randomly swap two cities
        #     next_gen.append(perm)    # add it to next_gen

        with concurrent.futures.ThreadPoolExecutor(max_workers=n) as executor:
            futures = {
                executor.submit(mutate_thread_full, best_curr_gen): j
                for j in range(pop_size - 1)
            }
            for future in concurrent.futures.as_completed(futures):
                next_gen.append(future.result())

        # create the next generation of (score, permutations) pairs
        assert len(next_gen) == pop_size
        curr_gen = [(tsp.total_dist(p, city_locs), p) for p in next_gen]
        curr_gen.sort()

    # print(f'... mutate_search("{fname}", max_iter={max_iter}, pop_size={pop_size})')
    # print()
    # print(f'After {max_iter} generations of {pop_size} permutations, the best is:')
    # print(f'score = {curr_gen[0][0]}')
    # print(curr_gen[0][1])
    assert tsp.is_good_perm(curr_gen[0][1])

    return curr_gen, scores
コード例 #8
0
def GA_sq_NWOX(fname, max_iter, prev_pop):
    pop_size = len(prev_pop)
    city_locs = tsp.load_city_locs(fname)
    curr_gen = prev_pop

    scores = []
    print(f'sq_NWOX("{fname}", max_iter={max_iter}, pop_size={pop_size}) ...')
    for i in range(max_iter):

        #record historic scores
        scores.append(curr_gen[0][0])

        #select parents
        parents = selection_sq(curr_gen)

        #gen childern -> next_gen
        next_gen = []
        with concurrent.futures.ThreadPoolExecutor(
                max_workers=200) as executor:
            futures = {
                executor.submit(crossover_NWOX, pair): pair
                for pair in parents
            }
            for future in concurrent.futures.as_completed(futures):
                first, second = future.result()
                next_gen.append(first)
                next_gen.append(second)

        # for pair in parents:
        #     first, second = crossover_NWOX(pair)
        #     next_gen.append(first)
        #     next_gen.append(second)

        #mutate childern
        next_gen = single_mutation(next_gen)
        #next_gen[-1] = curr_gen[0][1]

        #score childern
        assert len(next_gen) == pop_size
        curr_gen = [(tsp.total_dist(p, city_locs), p) for p in next_gen]
        curr_gen.sort()

    return curr_gen, scores
コード例 #9
0
def GA_crossover_search(fname, max_iter, prev_pop):

    pop_size = len(prev_pop)
    city_locs = tsp.load_city_locs(fname)
    n = len(city_locs)

    curr_gen = prev_pop

    scores = []
    print(
        f'crossover_search("{fname}", max_iter={max_iter}, pop_size={pop_size}) ...'
    )
    for i in range(max_iter):
        # copy the top 50% of the population to the next generation, and for the rest randomly
        # cross-breed pairs
        scores.append(curr_gen[0][0])
        top_half = [p[1] for p in curr_gen[:int(n / 2)]]
        next_gen = top_half[:]
        while len(next_gen) < pop_size:
            s = random.choice(top_half)
            t = random.choice(top_half)
            first, second = tsp.pmx(s, t)
            next_gen.append(first)
            next_gen.append(second)

        next_gen = next_gen[:pop_size]

        # create the next generation of (score, permutations) pairs
        assert len(next_gen) == pop_size
        curr_gen = [(tsp.total_dist(p, city_locs), p) for p in next_gen]
        curr_gen.sort()

    # print(f'... crossover_search("{fname}", max_iter={max_iter}, pop_size={pop_size})')
    # print()
    # print(f'After {max_iter} generations of {pop_size} permutations, the best is:')
    # print(f'score = {curr_gen[0][0]}')
    # print(curr_gen[0][1])
    assert tsp.is_good_perm(curr_gen[0][1])

    return curr_gen, scores
コード例 #10
0
def GA_tabo(fname, max_iter, prev_pop):
    pop_size = len(prev_pop)
    city_locs = tsp.load_city_locs(fname)
    n = len(city_locs)
    curr_gen = prev_pop
    keep = math.floor(pop_size / 5)
    keep = 0
    stalled = 0
    assert keep <= pop_size

    scores = []
    scores.append(curr_gen[0][0])
    print(f'tabo("{fname}", max_iter={max_iter}, pop_size={pop_size}) ...')

    #generate tabo data
    print("Generating Tabo crossover data...", end='')
    d_map = []
    dc = []
    closest = []
    B = 2

    for i in range(0, n):
        d_i_to_js = []
        for j in range(0, n):
            d_i_to_js.append(tsp.city_dist(i + 1, j + 1, city_locs))
        d_map.append(d_i_to_js)

    for i in range(0, n):
        dc.append(sum(d_map[i]) / (B * (n - 1)))

    for i in range(0, n):
        d_js = d_map[i][:]
        order = [x + 1 for x in numpy.argsort(d_js)]
        closest.append(order)

    print("...Done")
    delta = 100
    delta_lim = .1

    for i in range(max_iter):
        best = curr_gen[0]

        #select parents
        parents = selection_rw(curr_gen, 2, True)

        #gen childern -> next_gen
        next_gen = []
        for i in range(keep):
            next_gen.append(curr_gen[i][1])

        with concurrent.futures.ThreadPoolExecutor(
                max_workers=200) as executor:
            futures = {
                executor.submit(crossover_tabo, pair, d_map, dc, closest): pair
                for pair in parents
            }
            for future in concurrent.futures.as_completed(futures):
                first = future.result()
                next_gen.append(first)

        next_gen = next_gen[:pop_size]

        #mutate childern
        next_gen = chuck_mutation(next_gen)
        next_gen = single_mutation(next_gen)

        #score childern
        assert len(next_gen) == pop_size
        curr_gen = [(tsp.total_dist(p, city_locs), p) for p in next_gen]
        curr_gen[-1] = best
        curr_gen.sort()

        #record historic scores
        scores.append(curr_gen[0][0])

        if len(scores) > 2:
            delta = scores[-2] - scores[-1]
        if delta < delta_lim:
            stalled += 1
        else:
            stalled = 0
        if stalled > 25:
            print("delta limit at itteration:", i)
            break

    return curr_gen, scores