Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ruby/21.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ruby 根据营养需求制作菜单_Ruby_Algorithm_Knapsack Problem - Fatal编程技术网

Ruby 根据营养需求制作菜单

Ruby 根据营养需求制作菜单,ruby,algorithm,knapsack-problem,Ruby,Algorithm,Knapsack Problem,我需要生成七个每日菜单。菜单包括早餐、午餐、晚餐和三种小吃。我从fatsecret.com上取了几百份食谱。每个食谱都包含营养信息,如:卡路里、脂肪、钠、纤维。每个每日菜单仅限于: Calories: 1500 Sodium: 200g Fiber: 32g Fat: 30g 我正在计算早餐、午餐、晚餐和零食的所有可能组合,然后迭代它们并总结它们的营养信息。一旦我找到了七种符合营养要求的组合,我就停下来。但我需要一个更有效的方法 我在想一种树状结构,每当做出错误的菜单选择并尝试不同的分支时,它

我需要生成七个每日菜单。菜单包括早餐、午餐、晚餐和三种小吃。我从fatsecret.com上取了几百份食谱。每个食谱都包含营养信息,如:卡路里、脂肪、钠、纤维。每个每日菜单仅限于:

Calories: 1500
Sodium: 200g
Fiber: 32g
Fat: 30g
我正在计算早餐、午餐、晚餐和零食的所有可能组合,然后迭代它们并总结它们的营养信息。一旦我找到了七种符合营养要求的组合,我就停下来。但我需要一个更有效的方法


我在想一种树状结构,每当做出错误的菜单选择并尝试不同的分支时,它都会进行备份,但我仍然坚持使用这种结构。非常感谢您的帮助。

您可以用类似a的方式对食谱进行索引-这将允许您有效地删除无法与当前菜单选择组合的食谱,并允许您应用启发式方法来提高找到有效组合的机会(例如。“晚餐所含热量不能超过每日热量的50”)

我将建议几种可能的方法

样本组合

第一种方法更容易实施,即随机选择每顿饭的食谱,并将所有配料加在一起。如果它满足营养限制,就保留它。如果你取样,比如说,一亿种组合,你很可能会得到一些合格的组合。试一下很容易

使用受动态规划启发的方法

我说“受”动态规划(“DP”)的启发,因为我认为DP仅仅是一种优化技术。读者没有必要了解DP,但对于那些了解DP的人来说,“阶段”将是膳食和“状态”“在每个阶段,将是配方提供的营养价值的组合,包括与给定阶段相关的所有膳食

对于每个饮食项目,假设我们可以四舍五入:

  • 卡路里精确到20
  • 钠精确到5 gms
  • 纤维和脂肪各精确到克
考虑到营养成分会有所不同,这似乎并不不合理

这为我们提供了76*41*33*31=>3187668四种营养素的可接受组合

共有六顿饭,从
0
5
。对于每个可能的配方,我们都有四种营养成分的散列量,例如:

{ calories: 460, sodium: 55, fibre: 4, fat: 6 }
r[0]
成为元素
k=>v
的散列,其中键是数组
[卡路里、钠、纤维、脂肪]
,每种元素组合一个:

  • 卡路里
    ,介于
    0
    1500
    之间,以20的倍数表示
  • ,介于
    0
    200
    之间,以
    5
    的倍数表示
  • 光纤
    ,介于
    0
    32
    之间;及
  • fat
    ,介于
    0
    30
    之间
对于给定的键
[卡路里、钠、纤维、脂肪]
,相关值是一组提供给定成分组合的膳食食谱
0

我们只需浏览零点餐的所有食谱即可。如果给定的配方对应于键
k
给出的营养成分,我们可以查看相关值
r[0][k]
,是否已经包含足够数量的配方(例如,7)。如果没有,我们将该配方添加到值(数组)中

假设现在我们已经执行了我将要描述的关于膳食的计算
0,1,2,…,I
。我们将在第一顿饭后的五顿饭中计算出这些操作中的
r[j]
0 318766800。这里需要注意的重要一点是,计算的次数(仅)随着用餐次数的增加而线性增加。我希望从计算的角度来看是可以管理的


r[5]
中的所有值表示满足最大每日营养值的所有六餐食谱集。如果未找到任何组合,则不存在任何组合

如果限制不太严格,则可能有用。(否则,你将需要Cary的动态程序或整数规划。)采样引入的偏差应将菜单推向可行性,同时确保随机性

通过随机均匀地选择每个课程来初始化菜单。重复执行以下步骤,直到菜单可接受。从当前菜单开始,随机均匀地选择一道菜,随机均匀地选择一个菜谱,然后使用该菜谱为该课程生成建议的菜单。定义菜单的分数如下

    max(calories - 1500, 0)     max(sodium - 200, 0)    max(32 - fiber, 0)    max(fat - 30, 0)
0.99                        0.95                     0.7                   0.7

(指数的基础值得进行一些实验。我假设过多的卡路里、钠和脂肪是有害的,纤维不足也是有害的。)当且仅当
rand
(在[0.0,1.0]中均匀浮动)保留建议的菜单)小于建议菜单的分数除以当前菜单的分数。

当然有更复杂的算法,但如果你尝试均匀随机组合直到成功,会发生什么?我尝试过选择随机组合。我发现,由于营养要求非常严格,这是一个很好的选择非常缓慢。我允许营养值在200个单位的要求范围内,但仍然觉得缓慢。
[r_calories, r_sodium, r_fibre, r_fat]    
k' = [calories+r_calories, sodium+r_sodium, fibre+r_fibre, fat+r_fat]
    max(calories - 1500, 0)     max(sodium - 200, 0)    max(32 - fiber, 0)    max(fat - 30, 0)
0.99                        0.95                     0.7                   0.7