如何在 Clingo 中求和?
How to sum in Clingo?
我有以下数据集:
food_a(bagel, 245).
food_a(sandwich, 200).
food_a(salad,300).
food(bagel).
food(sandwich).
food(salad).
我想满足以下限制条件:给定总卡路里数,我想 return 满足该要求的食物。例如。总卡路里计数 = 500,程序应 return 'bagel+sandwich' 作为解决方案。我按照 clingo 代码对他进行了编码:
food_a(bagel, 245).
food_a(sandwich, 200).
food_a(salad,300).
food(bagel).
food(sandwich).
food(salad).
has(bagel, wheat).
has(sandwich, bread).
has(sandwich, tomatoes).
has(sandwich, onion).
has(sandwich, cheese).
%calories(food,amount):-food_a(food,amount).
%food(F):-food_a(F,C).
%limits(calories,200).
%sol(F) :- food_a(F,C1),food_a(F,C2), C1+C2<500.
%:- {food(F,C) : food_a(F,C1),food_a(F,C2)} , C1+C2 >500.
%food_diet(F) :- food(F,C), C<250.
%:- food(F1) ,food_a(F2,C2), C1+C2=445.
totals(P, S) :- S = #sum{ I : food_a(P,I)}, food(P), S<500.
我得到的输出在屏幕截图中:
显然,该程序 return 只考虑单一食品,而不是同时考虑 2 种或 3 种食品的组合。谁能建议我必须遵循的更改或步骤才能实现相同目标。
您目前正在分别计算每种食物的总和。如果您对同一种食物有多个值,例如food_a(bagel, 100)
和 food_a(bagel, 200)
那么结果就是 total(bagel, 300)
。本质上,由于每种食物只有一个 food_a/2
,因此您的 totals/2
定义等同于
totals(P, S) :- food_a(P, S), food(P), S<500.
你想要的是这样的
food_a(bagel, 245).
food_a(sandwich, 200).
food_a(salad,300).
food(bagel).
food(sandwich).
food(salad).
% allow any combination of foods to be selected
{ selected(P) } :- food(P).
% sum calories on selected foods
total(S) :- S = #sum{ I : food_a(P,I), selected(P) }.
% limit total calories
:- total(S), S>=500.
#show selected/1.
#show total/1.
产生
> clingo how-to-sum-clingo.asp 0
clingo version 4.5.4
Reading from how-to-sum-clingo.asp
Solving...
Answer: 1
total(0)
Answer: 2
selected(sandwich) total(200)
Answer: 3
selected(bagel) total(245)
Answer: 4
selected(bagel) selected(sandwich) total(445)
Answer: 5
selected(salad) total(300)
SATISFIABLE
Models : 5
Calls : 1
Time : 0.002s (Solving: 0.00s 1st Model: 0.00s Unsat: 0.00s)
CPU Time : 0.000s
我有以下数据集:
food_a(bagel, 245).
food_a(sandwich, 200).
food_a(salad,300).
food(bagel).
food(sandwich).
food(salad).
我想满足以下限制条件:给定总卡路里数,我想 return 满足该要求的食物。例如。总卡路里计数 = 500,程序应 return 'bagel+sandwich' 作为解决方案。我按照 clingo 代码对他进行了编码:
food_a(bagel, 245).
food_a(sandwich, 200).
food_a(salad,300).
food(bagel).
food(sandwich).
food(salad).
has(bagel, wheat).
has(sandwich, bread).
has(sandwich, tomatoes).
has(sandwich, onion).
has(sandwich, cheese).
%calories(food,amount):-food_a(food,amount).
%food(F):-food_a(F,C).
%limits(calories,200).
%sol(F) :- food_a(F,C1),food_a(F,C2), C1+C2<500.
%:- {food(F,C) : food_a(F,C1),food_a(F,C2)} , C1+C2 >500.
%food_diet(F) :- food(F,C), C<250.
%:- food(F1) ,food_a(F2,C2), C1+C2=445.
totals(P, S) :- S = #sum{ I : food_a(P,I)}, food(P), S<500.
我得到的输出在屏幕截图中:
显然,该程序 return 只考虑单一食品,而不是同时考虑 2 种或 3 种食品的组合。谁能建议我必须遵循的更改或步骤才能实现相同目标。
您目前正在分别计算每种食物的总和。如果您对同一种食物有多个值,例如food_a(bagel, 100)
和 food_a(bagel, 200)
那么结果就是 total(bagel, 300)
。本质上,由于每种食物只有一个 food_a/2
,因此您的 totals/2
定义等同于
totals(P, S) :- food_a(P, S), food(P), S<500.
你想要的是这样的
food_a(bagel, 245).
food_a(sandwich, 200).
food_a(salad,300).
food(bagel).
food(sandwich).
food(salad).
% allow any combination of foods to be selected
{ selected(P) } :- food(P).
% sum calories on selected foods
total(S) :- S = #sum{ I : food_a(P,I), selected(P) }.
% limit total calories
:- total(S), S>=500.
#show selected/1.
#show total/1.
产生
> clingo how-to-sum-clingo.asp 0
clingo version 4.5.4
Reading from how-to-sum-clingo.asp
Solving...
Answer: 1
total(0)
Answer: 2
selected(sandwich) total(200)
Answer: 3
selected(bagel) total(245)
Answer: 4
selected(bagel) selected(sandwich) total(445)
Answer: 5
selected(salad) total(300)
SATISFIABLE
Models : 5
Calls : 1
Time : 0.002s (Solving: 0.00s 1st Model: 0.00s Unsat: 0.00s)
CPU Time : 0.000s