1. 程式人生 > 其它 >二進位制蟻群演算法【原始碼實現】

二進位制蟻群演算法【原始碼實現】

蟻群演算法
之前講解了蟻群演算法,見連結。萬字長文帶你瞭解蟻群演算法及求解複雜約束問題【原始碼實現】
今天講解下二進位制的蟻群演算法。
直接上算例。

算例

愛小玉,愛學習。

假設一個數PD=210,它可以看成下列中的數,某幾個組合而成來的P_state=np.array([1700,2600,180,2200,1400,60,85,290,4100,3000,1590,200,1300,50,100,30,90]),即PD=sum(xiP_statei)其中的xi表示狀態,只能取0或1。
限制條件:【180,2200】,序號[2,3]不能共存;【60,85,300】,序號[5,6,7]不能共存;【50,100】 序號[13,14]不能共存;【25,90】序號[15,16]不能共存。

這題的意思假設某刻時刻。家用總負荷為210W
家用總負荷是由各個電器的功率疊加的。其中【180,2200】,序號[2,3]不能共存,表示【180,2200】對應的是同一個電器,這個電器的功率可以是180或者2200.當一個時刻只能是一個值。其它同理。
算例實現
python 版程式碼。

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# @Author: yudengwu(餘登武)
# @Date  : 2021/5/28
#@email:[email protected]

import numpy as np
from tqdm import tqdm#進度條設定
import
matplotlib.pyplot as plt import matplotlib as mpl import matplotlib; matplotlib.use('TkAgg') mpl.rcParams['font.sans-serif'] = ['SimHei'] # 指定預設字型 mpl.rcParams['axes.unicode_minus'] = False # 解決儲存影象是負號'-'顯示為方塊的問題 import math #以一個負荷為例講解優化演算法 P_state=np.array([1700,2600,180,2200,1400,60,85,290,4100,3000,1590,200,1300
,50,100,30,90])#17個狀態 state_num=17 #狀態數 #【180,2200】,序號[2,3]不能共存 #【60,85,300】,序號[5,6,7]不能共存 #【50,100】 序號[13,14]不能共存 #【25,90】序號[15,16]不能共存 #總負荷 Pload=446.0 #這個值可以設定的 ########適應度函式 def calc_f(xi): """ :param xi 為個體 即電器的工作狀態,01二二進位制,0表示當前狀態關,1表示開: xi 為np.array(資料) :return 返回 np.abs(XiP_state-pload) P_state為電器"額定功率": """ xi=np.array(xi) xi=xi.reshape(state_num,) return np.abs(np.sum(xi*P_state)-Pload) #=================初始化引數================ m=20 #螞蟻個數 G_max=300 #最大迭代次數 Rho=0.9 #資訊素蒸發係數 P0=0.2 #轉移概率常數 Tau=np.zeros(shape=(m,)) #資訊素 P=np.zeros(shape=(G_max,m)) #狀態轉移矩陣 fitneess_value_list=[] #迭代記錄最優目標函式值 #########初始化群體 f=np.random.randint(0,2,(m,state_num)) #在[0,2)之前隨機取整數,取state_num(17)個 f.shape=(20, 17) for j in tqdm(range(m)): while f[j, 2] + f[j, 3] == 2: f[j, 2] = np.random.randint(0, 2, 1) f[j, 3] = np.random.randint(0, 2, 1) # 【60,85,300】,序號[5,6,7]不能共存 while f[j, 5] + f[j, 6] + f[j, 7] == 2 or f[j, 5] + f[j, 6] + f[j, 7] == 3: f[j, 5] = np.random.randint(0, 2, 1) f[j, 6] = np.random.randint(0, 2, 1) f[j, 7] = np.random.randint(0, 2, 1) # 【50,100】 序號[13,14]不能共存 while f[j, 13] + f[j, 14] == 2: f[j, 13] = np.random.randint(0, 2, 1) f[j, 14] = np.random.randint(0, 2, 1) # 【25,90】序號[15,16]不能共存 while f[j, 15] + f[j, 16] == 2: f[j, 15] = np.random.randint(0, 2, 1) f[j, 16] = np.random.randint(0, 2, 1) for i in range(m):#遍歷每一個螞蟻 Tau[i] = calc_f(f[i])#資訊素 step=0.3; #區域性搜尋步長 for NC in range(G_max):#遍歷每一代 lamda=1/(NC+1) BestIndex=np.argmin(Tau) #最優索引 Tau_best=Tau[BestIndex] #最優資訊素 #計算狀態轉移概率 for i in range(m):#遍歷每一個螞蟻 P[NC,i]=np.abs((Tau_best-Tau[i]))/np.abs(Tau_best)+0.01 #即例最優資訊素的距離.越近越好 # =======位置更新========== for i in range(m): # 遍歷每一個螞蟻 #當前螞蟻 bf=f[i].copy() # ===區域性搜尋=== if P[NC, i] < P0: #每隻螞蟻 的元素隨機選擇 np.int(state_num*(step*lamda))個 取反 sizeaca=np.int(state_num*(step*lamda))#取反的個數 index=np.random.choice(np.arange(0,state_num,1),size=sizeaca,replace=False)#取反的序號 bf[index]=1-bf[index] #元素取反 # ===全域性搜尋=== else: #選擇4分之一元素取反 index = np.random.choice(np.arange(0, state_num, 1), size=np.int(state_num/4), replace=False) # 取反的序號 bf[index] = 1 - bf[index] # 元素取反 # =====位置限制===== # 【180,2200】,序號[2,3]不能共存 while bf[2] + bf[3] == 2: bf[2] = np.random.randint(0, 2, 1) bf[3]= np.random.randint(0, 2, 1) # 【60,85,300】,序號[5,6,7]不能共存 while bf[5] + bf[6] + bf[7] == 2 or bf[5] + bf[6] + bf[7] == 3: bf[5] = np.random.randint(0, 2, 1) bf[6] = np.random.randint(0, 2, 1) bf[7] = np.random.randint(0, 2, 1) # 【50,100】 序號[13,14]不能共存 while bf[13] + bf[14] == 2: bf[13] = np.random.randint(0, 2, 1) bf[14] = np.random.randint(0, 2, 1) # 【25,90】序號[15,16]不能共存 while bf[15] + bf[16] == 2: bf[15] = np.random.randint(0, 2, 1) bf[16] = np.random.randint(0, 2, 1) ##判斷螞蟻是否移動(選更優) if calc_f(bf) < calc_f(f[i]): f[i]=bf # =====更新資訊素======== for i in range(m): # 遍歷每一個螞蟻 Tau[i] = (1 - Rho) * Tau[i] + calc_f(f[i]) # (1 - Rho) * Tau[i] 資訊蒸發後保留的 index = np.argmin(Tau) # 最小值索引 value = Tau[index] # 最小值 fitneess_value_list.append(calc_f(f[i])) # 記錄最優目標函式值 #列印結果 min_index=np.argmin(Tau)#最優值索引 minf=f[min_index] #最優變數 \最優螞蟻 minValue=calc_f(minf) #最優目標函式值 print('最優變數',minf) print('最優變數對應的功率',minf*P_state) print('最優誤差',minValue) plt.plot(fitneess_value_list,label='迭代曲線') plt.legend() plt.show()

在這裡插入圖片描述
作者:電氣-餘登武。 一個電氣專業的計算機選手
原創不易,禁止轉載。