使用prolog从配料集合生成配方
我可以用我已经知道的语言来解决这个问题,但我希望用prolog(也许还有clpfd)来解决,因为我想学习这些技术。我看到一些关于使用SQL的类似问题的引用,但这不是我感兴趣的 我有一个成分的集合,每个成分都有一些属性,比如卡路里数、蛋白质含量、脂肪含量等等。成分不会超过几十种,可能也不会超过六种。在C中,我会将其建模为一个结构数组 然后,我希望能够生成使用受约束的成分组合的食谱。例如,总热量<1000,脂肪含量低于30%,蛋白质含量超过25克。我可能还想说“不包括白米”,例如,因为我现在没有白米了 答案可能是“125克鸡肉、25克胡萝卜、100克米饭”之类的物品清单 我使用prolog/cplfd做这件事是否正确?是否有特别的困难会使它不适合初学者(尽管我是其他语言的经验丰富的程序员) 我将如何为这个数据库建模?我看到prolog有列表和元组。。我可以把它表示为元组列表吗 我是否能够表达数学上的限制,如“总热量<1000,脂肪热量<总热量的30%,蛋白质>25g” 这类问题有一个我可以搜索的名称吗使用prolog从配料集合生成配方,prolog,constraints,Prolog,Constraints,我可以用我已经知道的语言来解决这个问题,但我希望用prolog(也许还有clpfd)来解决,因为我想学习这些技术。我看到一些关于使用SQL的类似问题的引用,但这不是我感兴趣的 我有一个成分的集合,每个成分都有一些属性,比如卡路里数、蛋白质含量、脂肪含量等等。成分不会超过几十种,可能也不会超过六种。在C中,我会将其建模为一个结构数组 然后,我希望能够生成使用受约束的成分组合的食谱。例如,总热量
有没有现成的prolog示例可以作为指导?这将是一个非常简洁的程序,我希望您能够实现整个过程并撰写相关文章。请让我知道你的想法 我可以很容易地看到如何处理示例约束。代码将如下所示:
% these operator declarations are just guesses!
:- op(500, xfy, and).
:- op(600, xf, grams).
:- op(600, yfx, of).
test(Recipe, X < Y) :-
evaluate(Recipe, X, XV),
evaluate(Recipe, Y, YV),
XV < YV.
test(Recipe, X and Y) :-
test(Recipe, X), test(Recipe, Y).
evaluate(Recipe, total_calories, X) :- total_calories(Recipe, X).
evaluate(Recipe, Const, Const) :- number(Const).
total_calories(Recipe, Total) :-
maplist(calories, Recipe, Calories),
sum(Calories, Total).
calories(X grams of Y, Calories) :-
caloric_content(N grams of Y, C),
Calories is X/N * C.
caloric_content(100 grams of chicken, 195).
meat(chicken).
vegetable(carrots).
recipe([MeatAmount grams of Meat, VegAmount grams of Vegetable]) :-
meat(Meat),
vegetable(Vegetable),
然后你会想通过某种方式来猜测数量来增加它。另一个需要探索的想法是将这两个方面结合起来,以便您添加的每个成分都处理一些约束。这样你就可以保持搜索的方向性,而不是漫无目的地把东西放在一起。我希望这能给你一些想法 您是否希望构建一个“全有或全无”的解决方案(即,一个要么服用成分,要么不服用成分,但从不服用部分成分的解决方案?)。否则,对于学习Prolog来说,这不是一个好的选择,因为这个问题在数学上非常繁重(特别是)。这并不是说Prolog无法解决问题,它将是复杂的,并且具有典型Prolog程序不常见的结构。我需要它取部分量(尽管它们可能被限制为整数域,例如5g到1000g的倍数)。它需要能够选择每种成分的添加量,以满足约束条件。然后还可以用经典的Prolog方法进行回溯。虽然这样的解决方案很可能太慢而不实用,但这将是一个很好(但很难)的学习练习。哇,谢谢。这确实给了我很多思考。我这样做是为了我的妻子,她需要严格控制营养成分。目前,每个食谱都围绕着一个主要的蛋白质选择,例如鸡、鱼、蛋等,所以这已经是一个有用的简化。我对运营商申报设施一无所知,谢谢你的指点。@NeilBaylis这将是一个出色的项目。开始时请给我写信,我很想参与其中。:)