最優化理論實踐——遺傳算法解組合最優化

全局優化算法實踐

全局優化算法概述

我們討論的無約束優化方法僅限於凸優化,這些方法的使用很依賴函數的性質和初始迭代點的選取,在很多情況下只能收斂到局部最小點。爲了在更大尺度,更復雜的函數中搜索,我們需要一些不被局部最優侷限的方法。一般來說,隨機優化方法將能夠實現這個目標,但因爲隨機算法的可行種類非常多,這些算法的理論甚至可以單獨拿出來作爲一門課講解。(可以參考《智能優化算法及其MATLAB實例》),我這裏就把它們作爲一種算法概念進行敘述,至於算法的具體實現和應用則按照興趣來。
各類智能算法的核心思想其實是類似的,都是用隨機優化來擺脫局部最優解。
1
2
3
4
5

旅行商問題

1
2

Python實現

解10城市的旅行商問題,給定城市的初始座標,城市之間的距離是歐拉距離

cood = [(41, 94),(37, 84),(54, 67),(25, 62),(7, 64),
(2, 99),(68, 58),(71, 44),(54, 62),(83, 69)]
graph = [[0 for _ in range(10)]for _ in range(10)]

for i in range(10):
    for j in range(10):
        graph[i][j] = ((cood[i][0]-cood[j][0])**2+\
        (cood[i][1]-cood[j][1])**2)**0.5
#爲了避免字符串旋轉相等,我們固定起點(兼終點)爲0
def distance(code):
    res = graph[0][code[0]]
    for i in range(len(code)-1):
        res+=graph[code[i]][code[i+1]]
    res += graph[code[-1]][0]
    return res
import random

def getCode(n):
    res = [i for i in range(1,n+1)]
    random.shuffle(res)
    return res
def exchange(code1,code2):
    n = len(code1)
    s = random.randint(0,n-1)
    e = random.randint(0,n-1)
    s,e = min(s,e),max(s,e)
    segment1 = code1[s:e]
    segment2 = code2[s:e]
    dic1 = {}
    dic2 = {}
    for i in range(s,e):
        dic1[code2[i]] = code1[i]
        dic2[code1[i]] = code2[i]
    code1[s:e] = segment2
    code2[s:e] = segment1
    
    
    for i in range(n):
        if s<=i<e:
            continue
        while(code1[i] in dic1):
            code1[i] = dic1[code1[i]]
    
    for i in range(n):
        if s<=i<e:
            continue
        while(code2[i] in dic2):
            code2[i] = dic2[code2[i]]
    
    
    return code1,code2
def mutate(code):
    #使用隨機交換實現變異
    n = len(code)
    s = random.randint(0,n-1)
    e = random.randint(0,n-1)
    code[s],code[e] = code[e],code[s]
    return code
from copy import deepcopy

N = 100
#建立一個100數量的種羣
population = [getCode(9) for _ in range(N)]
bests = []

for iteration in range(100):
    new_population = []
    best_code = None
    best_dist = 10000
    
    #找到種羣中表現最好的個體
    for code in population:
        dist = distance(code)
        if dist<best_dist:
            best_code = deepcopy(code)
            best_dist = dist
        #print(best_code)
        #print(best_dist)
    bests.append((best_dist,best_code))
    
    
    #自然選擇,錦標賽模式,隨機選出兩個個體競爭
    for _ in range(len(population)):
        i1,i2 = random.sample([i for i in range(N)],k=2)
        code = None;
        code1,code2 = population[i1],population[i2]
        if distance(code1)<distance(code2):
            code = code1
        else:
            code = code2
        c = deepcopy(code)
        new_population.append(c)
        
    population = new_population
    
    #交換進化,我們交換其中的6%
    for i in range(3):
        population[2*i],population[2*i+1] = \
        exchange(population[2*i],population[2*i+1])
    
    #變異進化,我們變異其中的2%
    mutated_index = random.sample([i for i in range(N)],k=2)
    for i in mutated_index:
        population[i] = mutate(population[i])
from matplotlib import pyplot as plt

x = [i for i in range(1,101)]
y = [ele[0] for ele in bests]
plt.title("Genetic Algorithm") 
plt.xlabel("Iteration times") 
plt.ylabel("Cost") 
plt.plot(x,y) 
plt.show()
print("Solution:",bests[-1][1])

種羣迭代
Solution: [5, 4, 3, 7, 6, 9, 8, 2, 1]

總結

其實我們找到的解並不是最優解,最優的路徑長度cost是242左右。但是我們找到的解已經是一個相當接近最優解的方案了,從本實驗我們可以看出隨機優化算法的廣泛應用;不只是書上學到的函數最大最小值求解,而且可以實際地應用到各種情景中。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章