kotlin - 从 Optimisation,Result - OjAlgo, kotlin 获得超过 1 个结果
问题描述
我有简单的二进制线性编程函数,我想得到不止一个,例如来自 Optimisation.Result = model.minimise() 的 10 个最佳解决方案。这对 OjAlgo 可行吗?
我知道函数的目的是找到一个最佳解决方案,但是有没有机会生成更多解决方案或从求解器迭代中获得解决方案?
fun linearProgrammingSolver(meal: Meal): MutableList<String> {
val mealList = meal.results
val resultList = mutableListOf<String>()
val listOfVariables= makeVariables(meal) as ImmutableList<Variable>
val model = ExpressionsBasedModel()
listOfVariables.forEach{
model.addVariable(it)
}
val calories = model.addExpression("calories")
.lower(1500)
.upper(3000)
listOfVariables.forEach {
val index = listOfVariables.indexOf(it)
calories.set(listOfVariables[index], mealList[index].nutrition.nutrients[0].amount)
}
val protein = model.addExpression("protein")
.lower(60)
listOfVariables.forEach {
val index = listOfVariables.indexOf(it)
protein.set(listOfVariables[index], mealList[index].nutrition.nutrients[1].amount)
}
val meals = model.addExpression("meals")
.level(3)
listOfVariables.forEach {
val index = listOfVariables.indexOf(it)
meals.set(listOfVariables[index], 1)
}
val result: Optimisation.Result = model.minimise()
println("state ${result.state}")
model.variables.forEach{
if(it.value.toInt() == 1){
println("model.var ${it}")
resultList.add(it.name)
}
}
println(model)
println(result)
println("list $resultList")
return resultList
}
解决方案
有两种方法可以解释这个问题。
获得最佳解决方案和 9 个次佳解决方案。这可以通过查看最佳解决方案
x*(i)
并设置和引入禁止再次找到a(i):=x*(i)
的模型的额外约束来实现,然后解决。x*
重复这个。您需要在每个循环中添加的剪切可能如下所示:sum(i, x(i) * a(i)) - sum(i, x(i) * (1-a(i))) <= sum(i, a(i)) - 1
收集算法找到的解决方案并报告其中最好的 10 个。这应该不会太难添加到算法中(只需跟踪最好的 10 个)。这将需要更改算法的源代码。
另一种方法是使用更高级(但可能更昂贵)的求解器,它具有所谓的解决方案池。
推荐阅读
- node.js - 使用 javascript 和 socket.io 从串口显示多个传感器数据
- javascript - 仅删除与第二个表对应的第一个表中没有条目的那些
- unity3d - 在编辑器播放模式下显示从 AssetBundle 加载的 Sprite 的问题
- java - 如何让手机进入睡眠状态?
- python - 在 NixOS 中,如何使用 Python 包 SpaCy、pandas 和 jenks-natural-breaks 安装环境?
- python - Tweepy API 中的“UnicodeDecodeError”
- angular - Google 使用 Angular4 在 localhost 上登录
- php - 验证(如果电子邮件和令牌正确,则更新数据库)
- java - 我想生成一个随机数并在另一个类中使用它来生成随机名称
- assembly - 为什么mov不能设置CS,代码段寄存器,即使它可以设置其他?