flopt,融合了多种启发式算法的Python求解器

科技   2024-10-27 20:02   德国  

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,前文有介绍。

FelooPy,一个Python的算法建模集成库介绍

实际上在开展项目时候,我们也需要把多个不同类型的算法包融合成一个整体,方便主模型调用。我们可以不造轮子,但我们得组合和使用这些轮子,因此,对多个优化算法包融合在一起,后续方便项目调用,是一个比较好的方向。


微信公众号后台回复

加群:加入全球华人OR|AI|DS社区硕博微信学术群

资料:免费获得大量运筹学相关学习资料

人才库:加入运筹精英人才库,获得独家职位推荐

电子书:免费获取平台小编独家创作的优化理论、运筹实践和数据科学电子书,持续更新中ing...

加入我们:加入「运筹OR帷幄」,参与内容创作平台运营

知识星球:加入「运筹OR帷幄」数据算法社区,免费参与每周「领读计划」、「行业inTalk」、「OR会客厅」等直播活动,与数百位签约大V进行在线交流



                    


        




文章须知

文章作者:用户007

微信编辑:疑疑

文章转载自『Python学习杂记』公众号,原文链接:flopt,融合了多种启发式算法的Python求解器





关注我们 

       FOLLOW US




































运筹OR帷幄
致力于成为全球最大的运筹学中文线上社区
 最新文章