我正在使用算法开发移动应用程序。是关于食物的。
所以我有一个包含一些饭菜的数据库。一顿饭包含几种食物。食物就像苹果一样,含有苹果的营养价值。 例如,一顿饭可能是一个苹果派,其中包含苹果,糖等。
一餐中的每种食物都具有最小和最大量,以使其更加灵活。因此,当我用酱汁制作意大利面时,可以放入150-250克的意大利面和50-75毫升的酱汁。
目标:该算法应采用某些每日总糖,蛋白质和脂肪摄入量的值。然后,它应该执行某种算法以找出膳食的良好组合,从而最符合日常碳水化合物,蛋白质和脂肪的期望。
在找到解决方案的同时,该算法可以交换餐食,更改餐食中食物的比例,并且每天有n餐,每餐n种食物,这是很多变量。
我已经尝试了一种遗传算法方法,但是我找不到合适的配对两个解决方案来生孩子的方法,也找不到解决突变的好方法。
感谢任何帮助,我不需要任何代码,只是我应该看的一些启发,我不怕阅读某些东西(如果不是书^^)。
或者,如果有人对如何解决此问题有办法,那也将非常好!
答案 0 :(得分:1)
您可以使用Mixed Integer Programming (MIP/MILP)解决此问题。
一个方便的教程是here。
想法是为每顿饭引入一个二进制变量,指示是否使用该饭。对于餐中的每种食物,都会有一个变量,指示使用该食物的哪一部分。
这些部分受用户指定的值以及健康值的约束。
因此,对于两餐m1
和m2
,使得m1
拥有食物1的f1
部分和食物2和{{1 }}具有食物3的f2
和食物4的m2
,如果我们将f3
和f4
作为上述二进制变量,则我们具有如下约束:
m1
我们还可以限制每天的用餐次数:
m2
由于将变量乘以变量会产生潜在的非凸,非线性结果,因此,我们参考MIP tutorial来将这些约束转换为可用形式。
最后,我们使用disciplined convex programming来构建模型,并使用cvxpy传递给求解器。 GLPK是免费的MIP求解器。诸如Gurobi之类的商业求解器通常速度更快,允许更大的问题,更稳定并且非常昂贵,尽管可能对学生免费。
完成所有这些操作后,将问题放入代码中并不太可怕。由于我不确定要使用什么值或哪种食物数据库是合理的,因此我基本上使用了随机输入(垃圾输入,垃圾输出!)。
daily_protein_min<=m1*(f1*protein_f1+f2*protein_f2)+m2*(f3*protein_f3+f4*protein_f4)<=daily_protein_max
f1_min<=f1<=f1_max
f2_min<=f2<=f2_max
f3_min<=f3<=f3_max
f4_min<=f4<=f4_max
结果如下:
m1+m2=1
由于我不清楚的原因,GLPK经常失败,尽管它确实找到了20次中的大约1次的解决方案。令人失望的是,未能找到解决方案看起来就像证明没有解决方案一样。
目前,我想我建议运行它多次,然后再排除解决方案的可能性。
请注意,添加更多的食物和食物应使求解器更容易找到解决方案,并减少出现上述问题的频率。
解决此问题的另一种方法是枚举膳食的子集,例如每天三餐的所有子集。然后,确定给定的膳食子集是否满足份量和营养约束是可以快速,轻松解决的线性规划。不利的一面是,可能有大量的膳食组合需要列举。 MIP求解器可能具有减少需要搜索的组合数量的技术。
答案 1 :(得分:0)
这听起来像是Diet Problem主题的变体,并且Richard明确指出,数学编程是一种有效的方法。但是,这在您的情况下可能不可行,因为在移动设备上没有太多用于数学编程的库(也许可以找到here),但是我不知道有任何用于线性编程的DART库。>
作为替代方案,metaheuristic方法可能会很好用,并且您有很多替代方案,包括Genetic Algorithms。
与要采用的算法无关,需要做出的一个选择是如何对解决方案进行编码。最自然的选择是使用非负连续(即实数)决策变量:我们称它们为x fm ,代表进餐m时食物f的量(m是否为第2周第5天的第3顿饭:将其逐步编号)。两个下标,因此它们形成F行乘M列的值的矩阵。编码它们的一种自然方法是将矩阵展开为向量x i ,即,将矩阵的每一行一个接一个地写在数组中,以便每个下标i标识一个特定的对(调频)。
接下来,您需要清楚地定义目标函数是什么,并有一个从编码解中计算目标函数的过程。
接下来,您需要一个过程来生成要评估的新解决方案(有关一些想法,请参见第2点here)。
如果您希望使用遗传算法,这里是some ideas for mutation and crossover,只需确保保留非负数即可。