flopt是国外一小哥开发的一个求解器,底层建模框架是pulp,在该框架基础上增加了多种启发式算法,本文介绍该求解器的基本原理及使用。
安装
与其他包一样,使用pip安装。
pip install flopt
在安装完flopt的时候,同时会安装许多依赖包,这些依赖包首先是pulp的建模框架,然后是实现多种启发式算法的依赖包。
初步试用
import flopt
# variables
a = flopt.Variable(name="a", lowBound=0, upBound=1, cat="Integer")
b = flopt.Variable(name="b", lowBound=1, upBound=2, cat="Continuous")
# problem
prob = flopt.Problem(name="Test")
# set objective function
prob += 2*(3*a+b)*b**2+3
# set constraint
prob += a*b >= 2
# run solver
prob.solve(timelimit=0.5, msg=True)
# get best solution
print("obj value", prob.getObjectiveValue())
print("a", a.value()) # or flopt.Value(a)
print("b", b.value())
TSP问题
这里我选择用2-opt算法解决tsp问题。
import flopt
# We have the distance matrix D, and the number of city is N
N = 4
D = [
[0.0, 3.0, 2.0, 1.0],
[2.0, 0.0, 1.0, 1.0],
[1.0, 3.0, 0.0, 4.0],
[1.0, 1.0, 2.0, 1.0],
]
# Variables
perm = flopt.Variable("perm", lowBound=0, upBound=N-1, cat="Permutation")
# Problem
prob = flopt.Problem(name="TSP")
# Object
def tsp_dist(perm):
distance = 0
for head, tail in zip(perm, perm[1:]+[perm[0]]):
distance += D[head][tail] # D is the distance matrix
return distance
tsp_obj = flopt.CustomExpression(func=tsp_dist, args=[perm])
prob += tsp_obj
# run solver
prob.solve(solver="2-Opt", timelimit=3, msg=True)
# Result
print("result", perm.value())
求解速度还是不错,并且给出了相应的求解过程。
求解器的选择
flopt封装了这许多求解的方法。这里给大家介绍几个。更多详细内容大家可以查询它的官方文档。
Shuffled Frog Learping Algorighm
从官网文档介绍来看,这个求解方法和遗传算法类似,可以直接用函数调用该算法求解。(该算法源代码文档中也有提供。)
import flopt
x = flopt.Variable("x", lowBound=-1, upBound=1, cat="Continuous")
y = flopt.Variable("y", lowBound=-1, upBound=1, cat="Continuous")
prob = flopt.Problem()
prob += 2*x*x + x*y + y*y + x + y
status, log = prob.solve(solver="SFLA", msg=True, timelimit=20)
print("obj =", flopt.Value(prob.obj))
print("x =", flopt.Value(x))
print("y =", flopt.Value(y))
同样的问题,换一个算法试试看。
HyperoptSearch
import flopt
x = flopt.Variable("x", lowBound=-1, upBound=1, cat="Continuous")
y = flopt.Variable("y", lowBound=-1, upBound=1, cat="Continuous")
prob = flopt.Problem()
prob += 2*x*x + x*y + y*y + x + y
status, log = prob.solve(solver="Hyperopt", msg=True, timelimit=20)
print("obj =", flopt.Value(prob.obj))
print("x =", flopt.Value(x))
print("y =", flopt.Value(y))
两个算法的目标值obj=-0.286是一样的,但是x,y不一样,这是官方的案例,可能输出结果数据展示调用函数出错了。
总结
flopt是一个融合了多种启发式算法的求解器。但是其在封装启发式算法及调用算法的过程并不是很成熟,因此受众比较少。但其采用的封装、融合多个启发式算法包的思路值得借鉴。这类包有一个更为成熟的Feloopy,前文有介绍。
实际上在开展项目时候,我们也需要把多个不同类型的算法包融合成一个整体,方便主模型调用。我们可以不造轮子,但我们得组合和使用这些轮子,因此,对多个优化算法包融合在一起,后续方便项目调用,是一个比较好的方向。
微信公众号后台回复
加群:加入全球华人OR|AI|DS社区硕博微信学术群
资料:免费获得大量运筹学相关学习资料
人才库:加入运筹精英人才库,获得独家职位推荐
电子书:免费获取平台小编独家创作的优化理论、运筹实践和数据科学电子书,持续更新中ing...
加入我们:加入「运筹OR帷幄」,参与内容创作平台运营
知识星球:加入「运筹OR帷幄」数据算法社区,免费参与每周「领读计划」、「行业inTalk」、「OR会客厅」等直播活动,与数百位签约大V进行在线交流
文章须知
文章作者:用户007
微信编辑:疑疑
文章转载自『Python学习杂记』公众号,原文链接:flopt,融合了多种启发式算法的Python求解器
关注我们
FOLLOW US