Beispiel #1
0
    def sa_algorithm(self):
        ga = Greedy(self.cities_matrix, self.number_of_cities)
        solution = ga.greedy_algorithm()
        starting_temp = 100
        current_temperature = starting_temp
        min_length = self.tour_length(solution)
        best_solution = []
        i = 0
        coolingRate = 0.00015  #this is the best I've found: 0.0002
        cool_count = 0

        lengths = []
        loop_count = []
        lo = 0
        average_distance = self.cities_matrix.sum() / self.number_of_cities**3
        print(average_distance)
        diff_frac = 0.01 * average_distance**0.5
        print('Diff_frac' + str(diff_frac))
        while current_temperature > 0.05:
            i += 1
            solution = self.optimise(self.cities_matrix, solution,
                                     self.number_of_cities,
                                     current_temperature, diff_frac)
            if i >= 150:
                i = 0  #reset i
                cool_count += 1
                currentLength = self.tour_length(solution)
                #Exponential multiplicative cooling:
                current_temperature = starting_temp * (
                    1 - coolingRate)**cool_count  #t *= 1 - coolingRate

                #current_temperature = starting_temp*math.exp( -( 0.001*1.2*cool_count**1.15 ) )
                #            current_temperature = starting_temp/(1+1.8*math.log(1+0.001*cool_count))
                lo += 1
                loop_count.append(lo)
                lengths.append(currentLength)
                if currentLength < min_length:
                    min_length = currentLength
                    best_solution = solution[:]
    #    plt.plot(loop_count, lengths, 'b.')
    #    filename = 'city'+str(number_of_cities)
    #    plt.savefig(filename, format='svg', dpi=1200)
    #    plt.show()
        return best_solution
Beispiel #2
0
    def genetic(self):
        #init
        ga = Greedy(self.cities_matrix, self.tourlength)
        initial = ga.greedy_algorithm()
        current_pop = []
        for i in range(100):
            baby = initial[:]
            #swap a few in initial
            if random.random() < 0.95:
                baby = self.rnd_swap(baby)
                if random.random() < 0.7:
                    baby = self.rnd_swap(baby)
                    if random.random() < 0.4:
                        baby = self.rnd_swap(baby)
            #current.shuffle()#shuffle to a certain degree
    #        current = random.sample(range(1, tourlength + 1), tourlength)

            current_pop.append((baby, self.tour_length(baby)))

    #    print("currentpopppppp"+str(len(current_pop)))

        min_length = min(list(map(lambda x: x[1], current_pop)))
        curr_best = list(filter(lambda x: x[1] == min_length, current_pop))[0]
        #    print(curr_best)
        ########################

        new_best = curr_best[:]
        checker = 0
        new_pop = []
        while checker < 20:  #while not(max fitness hasn't improved in x generations)
            for i in range(100):
                parents = self.select_parents(current_pop)
                dad, mum = parents[0], parents[1]
                #SPLICE
                rand_index = random.randint(0, self.tourlength - 1)
                #take the prefix of dad and add the suffix of mum
                child_with_duplicates = dad[0][:rand_index] + mum[0][
                    rand_index:]

                #MUTATE
                for j in range(len(child_with_duplicates)):
                    #for city in child_with_duplicates:
                    if random.random(
                    ) < 0.01:  #with a 1% chance randomly mutate each city
                        #city = random.sample(range(1, tourlength + 1), tourlength)[0]
                        child_with_duplicates[j] = random.randint(
                            1, self.tourlength)
                #make a set of all the cities not included
                not_included = [x for x in range(1, self.tourlength + 1)]
                for c in child_with_duplicates:
                    if c in not_included:
                        not_included.remove(c)

                random.shuffle(not_included)
                #check over for repetitions, if there is: add the first from the set
                child = []
                for c in child_with_duplicates:
                    if c in child:
                        child.append(not_included[0])
                        not_included.pop(0)
                    else:
                        child.append(c)
                #add child to current_pop[i]
                new_pop.append((child, self.tour_length(child)))
            current_pop = new_pop
            new_pop = []

            min_length = min(list(map(lambda x: x[1], current_pop)))
            new_best = list(filter(lambda x: x[1] == min_length,
                                   current_pop))[0]

            #        print("new_best: " + str(new_best[1]) + "curr_best: " + str(curr_best[1]))
            #        print("curr_best[1] > new_best[1] : " + str(curr_best[1] > new_best[1]))
            ########################

            if curr_best[1] > new_best[1]:
                curr_best = new_best
                checker == 0
            elif curr_best[1] == new_best[1]:
                checker += 1

    #            else :
    #                checker == 0
    #        print("new_best: " + str(new_best[1]))
    #        print("Fittest in generation: " + str(curr_best[0]))
    #        print("Length: " + str(curr_best[1]))
    #        print("checker:" + str(checker))

        return curr_best[0]