Ejemplo n.º 1
0
 def pclone(self, cities, particle, a):
     target = self.path[a]
     b = particle.maping[target]
     #        assert b == list(particle.path).index(target)
     if abs(a - b) < 2 or abs(a - b) == len(self.path) - 1:
         return
     src, dst = [a, b], [b, a]
     cost_src = cost(cities, self.path, src, src)
     cost_dst = cost(cities, self.path, src, dst)
     return self.mutate(cities, src, dst, cost_src, cost_dst)
Ejemplo n.º 2
0
    def generate_paretos(self):
        already_visited = []
        CURRENT = self.evaluator.get_paretos_instances()
        PREVIOUS = []
        while self.ratio[0] <= 1.0:
            print 'Looking for ratios: %s' % (' '.join(map(str, self.ratio)))
            PREVIOUS = deepcopy(CURRENT)

            cnt = 0
            n = len(self.evaluator.get_paretos_instances())
            to_copy = random.choice(self.evaluator.get_paretos_instances())
            while to_copy in already_visited:
                cnt += 1
                if cnt > n:
                    break
                to_copy = random.choice(self.evaluator.get_paretos_instances())
            already_visited.append(to_copy)
            ct = tsp.cost(to_copy, self.objectives)

            stop = False
            while not stop:
                best_neighbor = None
                best_cost = float('inf')

                # best neighbor
                for i in xrange(len(self.instance)):
                    for j in xrange(i+1, len(self.instance)):
                        neighbor = deepcopy(to_copy)
                        neighborhood.swap(neighbor, i, j)
                        c = tsp.cost(neighbor, self.objectives)
                        cr = self.proportional_score(c)
                        if cr < best_cost:
                            best_neighbor = neighbor
                            best_cost = cr

                if best_cost < self.proportional_score(ct):
                    to_copy = best_neighbor
                    ct = tsp.cost(to_copy, self.objectives)
                else:
                    stop = True
            self.evaluator.update(to_copy, tuple(ct.values()))
            CURRENT = self.evaluator.get_paretos_instances()
            with open('results.txt', 'w') as f:
                for res in CURRENT:
                    if res:
                        f.write(';'.join(map(str, res)))
                        f.write('\n')
            self.update_ratios()
            yield self.evaluator.get_paretos_costs()
Ejemplo n.º 3
0
def mutation(cities, population, a):
    pop_m = population[a].copy()
    idx = mutate(pop_m, degree=random.randint(2, MUT_DEGREE))
    mutation = idx.copy()
    np.random.shuffle(mutation)

    cost_x = cost(cities, pop_m, idx, idx)
    cost_y = cost(cities, pop_m, idx, mutation)

    cost_m = fitness[a] - (cost_x - cost_y)
    pop_m[idx] = pop_m[mutation]
    #    cost_w = cost(cities, pop_m, *[range(0, len(pop_m), 2)]*2)
    #    print(cost_m, cost_w)
    #    assert cost_m.round() == cost_w.round()
    return pop_m, cost_m
Ejemplo n.º 4
0
    def run(self, instance, objectives, budget=100, best=None, plot=False):
        self.N = 0
        self.budget = budget
        self.best = best
        self.instance = instance
        self.objectives = objectives
        c = tsp.cost(self.instance, self.objectives)
        self.evaluator.update(self.instance, tuple(c.values()))

        if plot:
            fig, ax = plt.subplots()
            if self.best:
                line, = ax.plot([o for o,_ in self.best], [o for _,o in self.best], 'g.')
            self.line, = ax.plot([], [], 'r.')
            ani = animation.FuncAnimation(fig, self.update, self.generate_paretos)
            plt.show()
        else:
            gen = self.generate_paretos()
            try:
                while True:
                    gen.next()
            except StopIteration:
                pass

        return self.evaluator
Ejemplo n.º 5
0
    def generate_paretos(self):
        already_visited = []
        CURRENT = self.evaluator.get_paretos_instances()
        PREVIOUS = []
        while self.N < self.budget:
            self.N += 1
            PREVIOUS = deepcopy(CURRENT)

            to_copy = random.choice(self.evaluator.get_paretos_instances())
            while to_copy in already_visited:
                to_copy = random.choice(self.evaluator.get_paretos_instances())
            already_visited.append(to_copy)
            for i in xrange(len(self.instance)):
                for j in xrange(i+1, len(self.instance)):
                    neighbor = deepcopy(to_copy)
                    neighborhood.swap(neighbor, i, j)
                    c = tsp.cost(neighbor, self.objectives)
                    self.evaluator.update(neighbor, tuple(c.values()))
            self.evaluator.clean_dominated()
            CURRENT = self.evaluator.get_paretos_instances()
            with open('results.txt', 'w') as f:
                for res in CURRENT:
                    if res:
                        f.write(';'.join(map(str, res)))
                        f.write('\n')
            yield self.evaluator.get_paretos_costs()
Ejemplo n.º 6
0
    def run(self, instance, objectives, step=0.1, best=None, plot=False):
        self.step = step
        self.best = best
        self.instance = instance
        self.objectives = objectives
        c = tsp.cost(self.instance, self.objectives)
        self.evaluator.update(self.instance, tuple(c.values()))

        n = len(objectives)
        for i in xrange(n):
            self.ratio.append(i / (n - 1.0))

        if plot:
            fig, ax = plt.subplots()
            if self.best:
                line, = ax.plot([o for o,_ in self.best], [o for _,o in self.best], 'g.')
            self.line, = ax.plot([], [], 'r.')
            ani = animation.FuncAnimation(fig, self.update, self.generate_paretos)
            plt.show()
        else:
            gen = self.generate_paretos()
            try:
                while True:
                    gen.next()
            except StopIteration:
                pass

        return self.evaluator
Ejemplo n.º 7
0
def pclone(cities, population, a, b):
    for _ in range(len(cities) * 2):
        a_i = random.randint(0, len(cities) - 1)
        if population[a][a_i] == population[b][a_i]:
            continue
        pop_c = population[a].copy()
        target = pop_c[a_i]
        b_i = list(population[b]).index(target)
        if abs(a_i - b_i) < 2 or abs(a_i - b_i) == len(pop_c) - 1:
            continue
        src, dst = [a_i, b_i], [b_i, a_i]
        cost_src = cost(cities, pop_c, src, src)
        cost_dst = cost(cities, pop_c, src, dst)

        cost_c = fitness[a] - (cost_src - cost_dst)
        pop_c[src] = pop_c[dst]
        return pop_c, cost_c
    return None, None
Ejemplo n.º 8
0
    def _backprop(self):
        self.particles.sort(key=lambda p: p.error)
        # skip outliers
        e_min, e_max = self.particles[3].error, self.particles[-4].error
        for i, p in enumerate(self.particles):
            # velocity like NN momentum
            velocity = self._proportional_distance_velocity(
                e_min, e_max, p.error, i)
            p.error_degree = int(p.optimizer.step(velocity * (e_max - e_min)))
            error_degree = 1 + p.error_degree  #min(len(p.path)**2, p.error_degree)

            leader = random.randint(
                0,
                0 if i < ELITE else ELITE)  #i // 4)#random.randint(0, ELITE)#

            for j in range(error_degree):
                self.total += 1

                # backprop
                idx = random.randint(0, len(p.path) - 1)
                if self.lrg * velocity > random.random():
                    if self.particles[0].best.path[idx] != p.path[idx]:
                        p.pclone(self.cities, self.particles[leader], idx)

                idx = random.randint(0, len(p.path) - 1)
                if self.lrp * velocity > random.random():
                    if p.best.path[idx] != p.path[idx]:
                        p.pclone(self.cities, p.best, idx)

                exploration = 2 > random.randint(0, error_degree)
                if not exploration:
                    continue  # best we want less to improvize

                src = mutate(p.path, degree=2)
                dst = [src[1], src[0]]

                # noise -> out of local minima
                t = self.temperature[p.cooldown()]
                cost_src = cost(self.cities, p.path, src, src)
                cost_dst = cost(self.cities, p.path, src, dst)
                if np.exp((cost_src - cost_dst) / t) > random.random():
                    p.mutate(self.cities, src, dst, cost_src, cost_dst)

        return np.mean([p.error for p in self.particles])
Ejemplo n.º 9
0
def crossover(cities, population, a, b):
    pop_a, pop_b = population[a], population[b]
    a, b = sorted(random.sample(range(len(pop_a)), 2))
    #    a = 0

    gene = list(pop_a[a:b])
    pop_c = list(filter(lambda g: g not in gene, pop_b))

    a = random.randint(0, len(pop_c) - 1)
    pop_c = np.array(pop_c[:a] + gene + pop_c[a:]).reshape(-1)
    cost_c = cost(cities, pop_c, *[range(0, len(pop_c), 2)] * 2)
    return pop_c, cost_c
Ejemplo n.º 10
0
    def __init__(self, cities, optimizer, temperature):
        out_size = len(cities)
        assert 0 == out_size % 2, "current cost function accepts only odd #cities"

        self.optimizer = optimizer
        self.path = np.random.choice(np.arange(out_size),
                                     out_size,
                                     replace=False)
        self.error = cost(cities, self.path,
                          *[range(0, len(self.path), 2)] * 2)

        self.maping = list(np.argsort(self.path))

        self.temp = temperature

        self.best = None
        self.best = copy.copy(self)
        self.error_degree = None
Ejemplo n.º 11
0
# https://ericphanson.com/blog/2016/the-traveling-salesman-and-10-lines-of-python/
# *also 10 lines of code (w/o comments, empty lines + merge 'if' into one line )
#  but with usage of tsp 'library' :) ~ simulated annealing logic is all here.

import random
import numpy as np

from tsp import tsp_map, mutate, cost, plot

cities = tsp_map(n_cities=20, scale=1000)

path = np.random.choice(np.arange(len(cities)), len(cities), replace=False)
# we cut half of logspace as first/second half is bit brutal for temperature
for temperature in reversed(np.logspace(0, 3, 1e5)[:int(1e5 / 2)]):
    a, b = mutate(path, degree=2)
    # interesting trick: we dont need to checkpoint best path !!
    # as if new path better np.exp(-..) is low, best path will survive most likely
    if np.exp(
        (cost(cities, path, [a, b], [a, b]) -
         cost(cities, path, [a, b], [b, a])) / temperature) > random.random():

        path[[a, b]] = path[[b, a]]

plot(cities, path)
Ejemplo n.º 12
0
    ])
    #    for idx in trails[:ELITE_POOL, len(visited)]:
    #        assert diffs[int(mu), int(idx)] == list(neighbours[int(mu)]).index(int(idx))

    # heuristic, if 2 possible soutions we dont want to oscilate
    sigma.sort()
    return sigma[1:len(sigma) // 2 + 1].mean()


scores = []
trails = np.vstack([
    np.random.choice(range(len(cities)), size=len(cities), replace=False)
    for _ in range(EVAPORATION_POOL + COUNT)
])
total_cost = np.array(
    [cost(cities, trail, *[range(0, len(trail), 2)] * 2) for trail in trails])

print("INITIAL SCORE", np.mean(total_cost))

for i in range(200):  # * EVAPORATION_POOL // COUNT):
    var = 0
    for c in range(COUNT):
        score = 0
        visited = []

        stats = []

        trail = trails[random.randint(0, ELITE_POOL - 1)]  #EVAPORATION_POOL)]#
        while len(visited) != len(cities):
            mu = trail[len(visited)]
            # not actually same as learning rate,
Ejemplo n.º 13
0
COUNT = 100
MUT_DEGREE = 3  #8#
BOUT_SIZE = 7
TOURNAMENT_COUNT = 10
ELITE = 10

cities = tsp_map(24, 1000)

population = [
    np.random.choice(np.arange(len(cities)), len(cities), replace=False)
    for _ in range(COUNT)
]

fitness = [
    cost(cities, path, *[range(0, len(path), 2)] * 2) for path in population
]


def crossover(cities, population, a, b):
    pop_a, pop_b = population[a], population[b]
    a, b = sorted(random.sample(range(len(pop_a)), 2))
    #    a = 0

    gene = list(pop_a[a:b])
    pop_c = list(filter(lambda g: g not in gene, pop_b))

    a = random.randint(0, len(pop_c) - 1)
    pop_c = np.array(pop_c[:a] + gene + pop_c[a:]).reshape(-1)
    cost_c = cost(cities, pop_c, *[range(0, len(pop_c), 2)] * 2)
    return pop_c, cost_c