0

我当前的代码旨在对给定数据库中的一些值求和,并选择早餐、午餐和晚餐食物的组合。在用于测试的小数据库下,您可以找到我正在运行的代码,并在给定的时间间隔内找到 42 个答案。然后我还想计算其他列(蛋白质、脂肪、碳水化合物),如下所示。但我遇到了一些巨大的性能问题。代码只是没有运行(我等了一个小时,但没有显示结果)是否有可能简化 sum-chain sum_prot_fat_carb_bf /+lu /+di ?这样我的程序才能最终运行......我用这种编程语言没有想法了。如果你能帮助我,我会很高兴。此致

sum_prot_fat_carb_bf(BFPROT,BFFAT,BFCARB) :- BFPROT = #sum{ PROT : food_bf(_,_,PROT,_,_,_), selected_bf(NAME,CAL,PROT,FAT,CARB,VEGN) },
                                             BFFAT  = #sum{ FAT  : food_bf(_,_,_,FAT,_,_) , selected_bf(NAME,CAL,PROT,FAT,CARB,VEGN) },
                                             BFCARB = #sum{ CARB : food_bf(_,_,_,_,CARB,_), selected_bf(NAME,CAL,PROT,FAT,CARB,VEGN) }.

sum_prot_fat_carb_lu(LUPROT,LUFAT,LUCARB) :- LUPROT = #sum{ PROT : food_lu(_,_,PROT,_,_,_), selected_lu(NAME,CAL,PROT,FAT,CARB,VEGN) },
                                             LUFAT  = #sum{ FAT  : food_lu(_,_,_,FAT,_,_) , selected_lu(NAME,CAL,PROT,FAT,CARB,VEGN) },
                                             LUCARB = #sum{ CARB : food_lu(_,_,_,_,CARB,_), selected_lu(NAME,CAL,PROT,FAT,CARB,VEGN) }.

sum_prot_fat_carb_di(DIPROT,DIFAT,DICARB) :- DIPROT = #sum{ PROT : food_di(_,_,PROT,_,_,_), selected_di(NAME,CAL,PROT,FAT,CARB,VEGN) },
                                             DIFAT  = #sum{ FAT  : food_di(_,_,_,FAT,_,_) , selected_di(NAME,CAL,PROT,FAT,CARB,VEGN) },
                                             DICARB = #sum{ CARB : food_di(_,_,_,_,CARB,_), selected_di(NAME,CAL,PROT,FAT,CARB,VEGN) }.

rate_prot_fat_carb(TOTALPROT,TOTALFAT,TOTALCARB)     :- sum_prot_fat_carb_bf(BFPROT,BFFAT,BFCARB),
                                                        sum_prot_fat_carb_lu(LUPROT,LUFAT,LUCARB),
                                                        sum_prot_fat_carb_di(DIPROT,DIFAT,DICARB),
                                                        TOTALPROT = BFPROT+LUPROT+DIPROT,
                                                        TOTALFAT = BFFAT+LUFAT+DIFAT,
                                                        TOTALCARB = BFCARB+LUCARB+DICARB.

#show sum_cal_total/1.
#show rate_prot_fat_carb/3. 

%database - (different reciepes for each breakfast(bf), lunch(lu), and dinner(di)) 
%    name                           cal     prot    fat     carb    veg/~veg  
food_bf(haferflocken_milch,         116,    5,      4,      15,     v).
food_bf(kaesebrot,                  260,    11,     16,     17,     v).
food_bf(wurstbrot,                  270,    6,      14,     20,     n).
food_bf(omelett,                    154,    11,     12,     1,      v).
food_bf(obstsalat,                  53,     1,      0,      12,     v).
food_bf(studentenfutter,            485,    3,      27,     45,     v).
food_bf(nutellabrot,                199,    3,      6,      32,     v).

food_lu(codfish_with_vegetables,    380,    31,     16,     24,     n).
food_lu(chicken_with_rice,          393,    52,     13,     15,     n).
food_lu(rice_with_tofu,             397,    15,     9,      61,     v).
food_lu(mustard_eggs_with_potatos,  360,    19,     17,     31,     v).
food_lu(linguine_with_pumpkin_sauce,334,    10,     9,      51,     v).
food_lu(pork_filet_with_beans,      392,    34,     15,     27,     n).
food_lu(bulgur_salad,               400,    14,     11,     58,     v).

food_di(filled_eggplant,            372,    11,     17,     37,     v).
food_di(chickpea_curry,             419,    13,     25,     32,     v).
food_di(pork_filets_with_carrots,   400,    36,     16,     25,     n).
food_di(kale_hotpot,                222,    7,      10,     24,     v).
food_di(tarte_flambee,              320,    12,     12,     38,     n).
food_di(fish_meatball,              375,    30,     23,     9,      n).
food_di(caper_spaghetti,            346,    14,     7,      54,     v).

% check all combinations of food
{ selected_bf(NAME,CAL,PROT,FAT,CARB,VEGN) } :- food_bf(NAME,CAL,PROT,FAT,CARB,VEGN).
{ selected_lu(NAME,CAL,PROT,FAT,CARB,VEGN) } :- food_lu(NAME,CAL,PROT,FAT,CARB,VEGN).
{ selected_di(NAME,CAL,PROT,FAT,CARB,VEGN) } :- food_di(NAME,CAL,PROT,FAT,CARB,VEGN).

% sum the calories of breakfast, lunch and dinner
sum_cal_bf(BFCAL) :- BFCAL = #sum{ CAL : food_bf(_,CAL,_,_,_,_), selected_bf(NAME,CAL,PROT,FAT,CARB,VEGN) }.
sum_cal_lu(LUCAL) :- LUCAL = #sum{ CAL : food_lu(_,CAL,_,_,_,_), selected_lu(NAME,CAL,PROT,FAT,CARB,VEGN) }.
sum_cal_di(DICAL) :- DICAL = #sum{ CAL : food_di(_,CAL,_,_,_,_), selected_di(NAME,CAL,PROT,FAT,CARB,VEGN) }.
sum_cal_total(TOTALCAL) :- sum_cal_bf(BFCAL), sum_cal_lu(LUCAL), sum_cal_di(DICAL), TOTALCAL = BFCAL+LUCAL+DICAL.

:- sum_cal_bf(BFCAL), BFCAL>=575. 
:- sum_cal_bf(BFCAL), BFCAL<375.
:- sum_cal_lu(LUCAL), LUCAL>=1075.
:- sum_cal_lu(LUCAL), LUCAL<875.
:- sum_cal_di(DICAL), DICAL>=975.
:- sum_cal_di(DICAL), DICAL<775.
:- sum_cal_total(TOTALCAL), TOTALCAL>=2350.
:- sum_cal_total(TOTALCAL), TOTALCAL<2250.

#show sum_cal_total/1. ```

**clingo 0 fp.lp**
clingo version 5.4.0
Reading from fp.lp
Solving...
Answer: 1
sum_cal_total(2348)
Answer: 2
sum_cal_total(2338)
Answer: 3
sum_cal_total(2279)
Answer: 4
sum_cal_total(2334)
Answer: 5
sum_cal_total(2289)
Answer: 6
sum_cal_total(2332)
Answer: 7
sum_cal_total(2271)
Answer: 8
sum_cal_total(2342)
Answer: 9
sum_cal_total(2334)
Answer: 10
sum_cal_total(2251)
Answer: 11
sum_cal_total(2304)
Answer: 12
sum_cal_total(2324)
Answer: 13
sum_cal_total(2294)
Answer: 14
sum_cal_total(2337)
Answer: 15
sum_cal_total(2254)
Answer: 16
sum_cal_total(2327)
Answer: 17
sum_cal_total(2307)
Answer: 18
sum_cal_total(2297)
Answer: 19
sum_cal_total(2292)
Answer: 20
sum_cal_total(2345)
Answer: 21
sum_cal_total(2282)
Answer: 22
sum_cal_total(2337)
Answer: 23
sum_cal_total(2335)
Answer: 24
sum_cal_total(2274)
Answer: 25
sum_cal_total(2279)
Answer: 26
sum_cal_total(2317)
Answer: 27
sum_cal_total(2332)
Answer: 28
sum_cal_total(2269)
Answer: 29
sum_cal_total(2322)
Answer: 30
sum_cal_total(2307)
Answer: 31
sum_cal_total(2299)
Answer: 32
sum_cal_total(2318)
Answer: 33
sum_cal_total(2273)
Answer: 34
sum_cal_total(2308)
Answer: 35
sum_cal_total(2334)
Answer: 36
sum_cal_total(2263)
Answer: 37
sum_cal_total(2318)
Answer: 38
sum_cal_total(2288)
Answer: 39
sum_cal_total(2326)
Answer: 40
sum_cal_total(2278)
Answer: 41
sum_cal_total(2316)
Answer: 42
sum_cal_total(2255)
SATISFIABLE

Models       : 42
Calls        : 1
Time         : 2.500s (Solving: 0.04s 1st Model: 0.00s Unsat: 0.00s)
CPU Time     : 2.469s
4

1 回答 1

0

程序结束时的约束是什么?它们是用于测试还是真正用于问题?对 PROT、FAT 和 CARB 的限制呢?由于你可以得到 42 个对 CAL 有约束的答案,我建议使用这 42 个答案作为求解 PROT、FAT 和 CAB 的输入。您不妨#show selected_bf/lu/di, 并将它们用作输入。例如:

selected_di(fill_eggplant) selected_di(鹰嘴豆咖喱) selected_lu(codfish_with_vegetables) selected_lu(mustard_eggs_with_potatos) selected_lu(linguine_with_pumpkin_sauce) selected_bf(煎蛋卷) selected_bf(obstsalat) selected_bf(nutellabrot) sum_cal_total(2271)

是 42 个答案之一。那么 PROT/FAT/CAB 的程序可以是:

sum_prot_fat_carb_bf(BFPROT,BFFAT,BFCARB) :- BFPROT = #sum{ PROT : food_bf(NAME,_,PROT,_,_,_), selected_bf(NAME) },
                                            BFFAT  = #sum{ FAT  : food_bf(NAME,_,_,FAT,_,_) , selected_bf(NAME) },
                                            BFCARB = #sum{ CARB : food_bf(NAME,_,_,_,CARB,_), selected_bf(NAME) }.

sum_prot_fat_carb_lu(LUPROT,LUFAT,LUCARB) :- LUPROT = #sum{ PROT : food_lu(NAME,_,PROT,_,_,_), selected_lu(NAME) },
                                            LUFAT  = #sum{ FAT  : food_lu(NAME,_,_,FAT,_,_) , selected_lu(NAME) },
                                            LUCARB = #sum{ CARB : food_lu(NAME,_,_,_,CARB,_), selected_lu(NAME) }.

sum_prot_fat_carb_di(DIPROT,DIFAT,DICARB) :- DIPROT = #sum{ PROT : food_di(NAME,_,PROT,_,_,_), selected_di(NAME) },
                                            DIFAT  = #sum{ FAT  : food_di(NAME,_,_,FAT,_,_) , selected_di(NAME) },
                                            DICARB = #sum{ CARB : food_di(NAME,_,_,_,CARB,_), selected_di(NAME) }.

rate_prot_fat_carb(TOTALPROT,TOTALFAT,TOTALCARB)     :- sum_prot_fat_carb_bf(BFPROT,BFFAT,BFCARB),
                                                        sum_prot_fat_carb_lu(LUPROT,LUFAT,LUCARB),
                                                        sum_prot_fat_carb_di(DIPROT,DIFAT,DICARB),
                                                        TOTALPROT = BFPROT+LUPROT+DIPROT,
                                                        TOTALFAT = BFFAT+LUFAT+DIFAT,
                                                        TOTALCARB = BFCARB+LUCARB+DICARB.


%database - (different reciepes for each breakfast(bf), lunch(lu), and dinner(di)) 
%    name                           cal     prot    fat     carb    veg/~veg  
food_bf(haferflocken_milch,         116,    5,      4,      15,     v).
food_bf(kaesebrot,                  260,    11,     16,     17,     v).
food_bf(wurstbrot,                  270,    6,      14,     20,     n).
food_bf(omelett,                    154,    11,     12,     1,      v).
food_bf(obstsalat,                  53,     1,      0,      12,     v).
food_bf(studentenfutter,            485,    3,      27,     45,     v).
food_bf(nutellabrot,                199,    3,      6,      32,     v).

food_lu(codfish_with_vegetables,    380,    31,     16,     24,     n).
food_lu(chicken_with_rice,          393,    52,     13,     15,     n).
food_lu(rice_with_tofu,             397,    15,     9,      61,     v).
food_lu(mustard_eggs_with_potatos,  360,    19,     17,     31,     v).
food_lu(linguine_with_pumpkin_sauce,334,    10,     9,      51,     v).
food_lu(pork_filet_with_beans,      392,    34,     15,     27,     n).
food_lu(bulgur_salad,               400,    14,     11,     58,     v).

food_di(filled_eggplant,            372,    11,     17,     37,     v).
food_di(chickpea_curry,             419,    13,     25,     32,     v).
food_di(pork_filets_with_carrots,   400,    36,     16,     25,     n).
food_di(kale_hotpot,                222,    7,      10,     24,     v).
food_di(tarte_flambee,              320,    12,     12,     38,     n).
food_di(fish_meatball,              375,    30,     23,     9,      n).
food_di(caper_spaghetti,            346,    14,     7,      54,     v).

%fact base
selected_di(filled_eggplant). 
selected_di(chickpea_curry). 
selected_lu(codfish_with_vegetables). 
selected_lu(mustard_eggs_with_potatos). 
selected_lu(linguine_with_pumpkin_sauce). 
selected_bf(omelett).
selected_bf(obstsalat). 
selected_bf(nutellabrot). 

我们得到:

答案:1

rate_prot_fat_carb(99,102,220)

满意

您可以尝试使用 python 之类的脚本文件并使用 for 循环来获取 42 个答案的结果,并将它们作为事实库写入第二个程序文件。

在这里我建议删除其他变量,selected_bf(NAME,CAL,PROT,FAT,CARB,VEGN)因为如果 NAME 被确保,CAL,PROT,FAT,CARB,VEGN可以从数据库中读取food_bf(NAME,...),这也可能需要 cligo 的时间来进行磨合。

为了在单个程序中获得答案,我建议您对 PORT/FAT/CAB 给予更多限制。

于 2020-01-16T17:22:04.497 回答