Tabu Search

来源:互联网 发布:淘宝店家培训 编辑:程序博客网 时间:2024/06/05 11:02

Tabu Search     

        Tabu search, created by Fred W. Glover in 1986 and formalized in 1989 is a meta-heuristic search method employing local search methods used for mathematical optimization. Tabu search is the enhanced version of local searches by relaxing its basic rules. Local searches always refuse any solution that is no better than the history best one, so local search algorithm can easily get trapped in the local optimal solution. Instead, tabu search can accept the worsening moves at each step if no improving move is available. In addition, prohibitions are introduced to discourage the search from coming back to previously-visited solutions. 

# -*- coding: utf-8 -*-"""Created on 2017/3/15 12:15 2017@author: Randolph.Lee"""import numpy as npimport randomimport copyclass TabuSearch:    def __init__(self, max_len, graph, total_nodes):        self.max_len = max_len        self.graph_mat = graph        self.node_num = total_nodes        self.current_solution = range(total_nodes)        random.shuffle(self.current_solution)        self.best_solution = []        self.aspiration = 0.0        self.candidates = []        self.fit_list = []        self.tabu_record = []        self.tabu_list = []    def cal_aspiration(self, solution):        current_aspiration = 0.0        for i in solution[:-1]:            for j in solution[1:]:                current_aspiration += self.graph_mat[i, j]        return current_aspiration    def initialize_aspiration(self):        self.aspiration = self.cal_aspiration(self.current_solution)        self.best_solution = copy.deepcopy(self.current_solution)    # generate candidate set based on the current solution    def generate_candidates(self):        random_num = random.randint(0, self.node_num - 1)        neighbor_base = copy.deepcopy(self.current_solution)        element = self.current_solution[random_num]        del neighbor_base[random_num]        temp_candidates = [neighbor_base[:i] + [element] + neighbor_base[i:] for i in range(self.node_num)]        self.candidates = filter(lambda x: x != self.current_solution, temp_candidates)        self.tabu_record = [(item[item.index(element)-1], element) if item.index(element) == self.node_num-1 else (element, item[item.index(element)+1]) for item in self.candidates]        self.fit_list = [self.cal_aspiration(item) for item in self.candidates]    def update_tabulist(self, selected_record):        if len(self.tabu_list) == self.max_len:            del self.tabu_list[0]        self.tabu_list.append(selected_record)    def relieve_ban(self, fitness):        if fitness < self.aspiration:            sign = True            self.aspiration = fitness        else:            sign = False        return signif __name__ == "__main__":    max_len = 4    max_iteration = 20    total_nodes = 8    graph_mat = abs(np.random.randn(8, 8))    tabu_search = TabuSearch(max_len, graph_mat, total_nodes)    tabu_search.initialize_aspiration()    res = []    i = 0    while i < max_iteration:        # produce the candidates        tabu_search.generate_candidates()        # rank the fitness        fit_rank = np.array(tabu_search.fit_list).argsort().tolist()        move_times = 0        if tabu_search.relieve_ban(tabu_search.fit_list[fit_rank[0]]):            tabu_search.update_tabulist(tabu_search.candidates[fit_rank[0]])            tabu_search.best_solution = copy.deepcopy(tabu_search.candidates[fit_rank[0]])        else:            while tabu_search.tabu_record[fit_rank[move_times]] in tabu_search.tabu_list:                move_times += 1        if move_times > len(tabu_search.candidates):            break        else:            tabu_move = tabu_search.tabu_record[fit_rank[move_times]]            tabu_search.update_tabulist(tabu_move)        res.append((i, tabu_search.aspiration))        print "iteration ", i        i += 1    print tabu_search.best_solution
                                             
0 0