用docplex和遺傳算法解決0-1規劃問題

1、什麼是0-1規劃問題

0-1規劃問題是決策變量僅取值0或1的一類特殊的整數規劃。0-1變量能夠數量化地描述諸如開與關、取與棄、有與無等現象所反映的離散變量間的邏輯關係、順序關係以及互斥的約束條件,所以0-1規劃問題很是適合描述和解決如線路設計、工廠選址、生產計劃安排、旅行購物、揹包問題、人員安排等問題。html

2、經典0-1規劃問題

某公司擬在市東、西、南區創建門市部。備選有7個位$A_{i}$(${i}=1,2,...,7$)可供選擇。規定$A_{1}$、$A_{2}$、$A_{3}$三個點中至多選兩個,$A_{4}$、$A_{5}$兩個點中至少選一個,$A_{6}$、$A_{7}$兩個點中至少選一個。如選用$A_{i}$點,設備投資爲$b_{i}$萬元,每一年可獲利潤爲$c_{i}$萬元,但投資總額不能超過60萬元,具體數值以下表,問選擇哪幾個點可以使年利潤最大? python

首先對該問題進行建模,引入0-1變量$x_{i}$(${i}=1,2,...,7$),$x_{i}=1$,表示該點被選中,$x_{i}=0$,表示該點未被選中。模型以下: Alt算法

3、Docplex求解0-1規劃問題

docplex ( IBM Decision Optimization CPLEX Modeling for Python ) 是IBM爲建模和求解優化問題而開發的Python API,其能使用本地的Cplex求解器,也可用帳號登陸使用雲端求解。編程

from docplex.mp.model import Model  #導出庫,只用這一個就夠了
model = Model() #建立模型
var_list = [i for i in range(0, 7)] #建立列表
X = model.binary_var_list(var_list, lb=0, name='X') #建立變量列表
#設定目標函數
model.maximize(11* X[0] + 9 * X[1] + 29 * X[2]+9* X[3]+21*X[4]+31*X[5]+22*X[6])  
#添加約束條件
model.add_constraint(X[0]+X[1]+X[2] <= 2)
model.add_constraint(X[3] + X[4] >=1)
model.add_constraint(X[5] + X[6] >=1)
model.add_constraint(10* X[0] + 8* X[1] + 20 * X[2]+5* X[3]+13*X[4]+22*X[5]+10*X[6] <=60)
sol = model.solve() #求解模型
print(sol)  #打印結果

求解結果以下: Alt函數

4、用遺傳算法求解0-1規劃問題

遺傳算法(Genetic Algorithm, GA)是模擬生物在天然環境中的遺傳和進化的過程而造成的自適應全局優化搜索算法。它借用了生物遺傳學的觀點,經過天然選擇、遺傳和變異等做用機制,實現各個個體適應性的提升。遺傳算法因能有效求解NP-hard問題及非線性、多峯函數優化和多目標優化問題,獲得了衆多學者的高度重視。遺傳算法借鑑了達爾文的進化論和孟德爾的遺傳學說。其本質是一種並行、高效、全局搜索的方法,它能在搜索過程當中自動獲取和積累有關搜索空間的知識,並自適應地控制搜索過程以求得最優解。同傳統的優化算法相比,遺傳算法具備對參數的編碼進行操做、不須要推導和附加信息、尋優規則非肯定性、自組織、自適應和自學習等特色。學習

Geatpy 是一個Python 進化算法庫,由華南理工大學、華南農業大學、德州奧斯汀公立大學學生聯合團隊開發。它提供了許多已實現的遺傳算法各項操做的函數,如初始化種羣、選擇、交叉、變異、重插入、多種羣遷移等。你能夠清晰地看到其基本結構及相關算法的實現,並利用Geatpy 函數方便地進行自由組合,實現多種改進的遺傳算法、多目標優化、並行遺傳算法等,解決傳統優化算法難以解決的問題。優化

編寫目標函數以下:編碼

"""函數接口aimfuc.py"""
import numpy as np
def aimfuc(Phen, LegV):
	x1 = Phen[:, [0]]
	x2 = Phen[:, [1]]
	x3 = Phen[:, [2]]
	x4 = Phen[:, [3]]
	x5 = Phen[:, [4]]
	x6 = Phen[:, [5]]
	x7 = Phen[:, [6]]
	f =11*x1+9*x2 +29*x3+9*x4+21*x5+31*x6+22*x7
	# 約束條件
	idx1 = np.where(10*x1+8*x2+20*x3+5*x4+13*x5+22*x6+10*x7 > 60)[0]
	idx2 = np.where(x1 + x2+ x3 > 2)[0]
	idx3 = np.where(-x4 -x5 > -1)[0]
	idx4 = np.where(-x6 -x7 > -1)[0]
	# 採用懲罰方法1
	f[idx1] = -1
	f[idx2] = -1
	f[idx3] = -1
	f[idx4] = -1
	return [f, LegV]

編寫執行腳本以下:spa

"""執行腳本main.py"""
import numpy as np
import geatpy as ga
from aimfuc import aimfuc
# 獲取函數接口地址
AIM_M = __import__('aimfuc')
# ================變量設置==================
# 生成自變量的範圍矩陣
ranges = np.vstack([np.zeros((1, 7)), np.ones((1, 7))])
# 生成自變量的邊界矩陣
borders = np.vstack([np.ones((1, 7)), np.ones((1, 7))])
FieldDR = ga.crtfld(ranges, borders) # 生成區域描述器
# ==============調用編程模板================
[pop_trace, var_trace, times] = ga.sga_real_templet(AIM_M, 'aimfuc',
None, None, FieldDR, problem = 'I', maxormin = -1, MAXGEN = 300,
NIND = 10, SUBPOP = 1, GGAP = 0.9, selectStyle = 'sus',
recombinStyle = 'xovdp', recopt = 0.9, pm = 0.1, distribute =True, drawing = 1)

求解結果與種羣水平圖像以下: 求解結果 求解結果 得出的結果與用docplex求解結果一致,即選擇第一、四、五、六、7個點。設計

原文出處:https://www.cnblogs.com/zhonghouyue/p/10581337.html

相關文章
相關標籤/搜索