与 Clingo 中的选择规则作斗争(答案集编程)
Struggles with the choice rule in Clingo (Answer-Set-Programming)
我目前正在努力解决以下问题:
让我们假设这个伪代码:
% Animal: ID, Type, Cost
animal (id1, dog, 300).
animal (id2, dog, 400).
animal (id3, dog, 600).
animal (id1, cat, 200).
animal (id2, cat, 400).
animal (id3, cat, 400).
animal (id1, fish, 20).
animal (id2, fish, 20).
animal (id3, fish, 20).
% Search the most expensive animals of each animal-type
most_expensive_animals(ID, Type, Cost) :- animal(ID, Type, Cost),
#max {X:animal(_, Type, X)} = Cost.
#show most_expensive_animals/3.
答案集为:
most_expensive_animals(id3,dog,600)
most_expensive_animals(id2,cat,400)
most_expensive_animals(id3,cat,400)
most_expensive_animals(id1,fish,20)
most_expensive_animals(id2,fish,20)
most_expensive_animals(id3,fish,20)
我想要实现的是一个规则,它只选择一种与 id 无关的动物类型(它也可以随机发生)。目标是,答案集如下:
most_expensive_animals(id3,dog,600)
most_expensive_animals(id2,cat,400)
most_expensive_animals(id1,fish,20)
此外,被踢出的答案应该保存在替代答案集中,如下所示:
alternative_most_expensive_animals(id3,cat,400)
alternative_most_expensive_animals(id2,fish,20)
alternative_most_expensive_animals(id3,fish,20)
我遵循了一些选择规则的方法,但没有成功。谁能进一步帮助我?
提前致谢!
您的程序是确定性的,无法做出选择:
most_expensive_animals(ID, Type, Cost) :- ...
您可以通过声明
来更改它
{ most_expensive_animals(ID, Type, Cost) } :- ...
所以每一种最昂贵的动物都可以被列为最昂贵的或不是最昂贵的。您还想涵盖非案例。我个人会这样写:
1 { most_expensive_animals(ID, Type, Cost) ; alt_most_expensive_animals(ID, Type, Cost) } 1 :- ...
意味着每一种最昂贵的动物都可以这样列出或作为替代品列出 - 如果 body 触发,则这些谓词中的一个必须为真。但这里仍然存在一个问题:可以列出多个或根本没有动物。我个人会写 2 个约束来防止这两种情况。
:- most_expensive_animals(ID, Type, Cost), most_expensive_animals(ID2, Type, Cost), ID != ID2.
% it is not possible that 2 or more IDs for the same Type and Cost appear
:- animal(_, Type, _), not most_expensive_animals(_, Type, _).
% it is not possible for every type of animal to not have a most expensive listed animal.
可以只使用一个约束:
:- animal(ID, Type, Cost), #max {X:animal(_, Type, X)} = Cost, {most_expensive_animals(IDtmp, Type, Cost)} != 1.
% for every Type/Cost pair where Cost is maxuimum for this Type, it can not be the the number of most expensive animals is different to 1.
这是输出(使用 clingo 的 web version 测试):
clingo version 5.5.0
Reading from stdin
Solving...
Answer: 1
most_expensive_animals(id3,dog,600) most_expensive_animals(id3,cat,400) most_expensive_animals(id1,fish,20)
Answer: 2
most_expensive_animals(id3,dog,600) most_expensive_animals(id3,cat,400) most_expensive_animals(id3,fish,20)
Answer: 3
most_expensive_animals(id3,dog,600) most_expensive_animals(id3,cat,400) most_expensive_animals(id2,fish,20)
Answer: 4
most_expensive_animals(id3,dog,600) most_expensive_animals(id2,cat,400) most_expensive_animals(id1,fish,20)
Answer: 5
most_expensive_animals(id3,dog,600) most_expensive_animals(id2,cat,400) most_expensive_animals(id3,fish,20)
Answer: 6
most_expensive_animals(id3,dog,600) most_expensive_animals(id2,cat,400) most_expensive_animals(id2,fish,20)
SATISFIABLE
我目前正在努力解决以下问题: 让我们假设这个伪代码:
% Animal: ID, Type, Cost
animal (id1, dog, 300).
animal (id2, dog, 400).
animal (id3, dog, 600).
animal (id1, cat, 200).
animal (id2, cat, 400).
animal (id3, cat, 400).
animal (id1, fish, 20).
animal (id2, fish, 20).
animal (id3, fish, 20).
% Search the most expensive animals of each animal-type
most_expensive_animals(ID, Type, Cost) :- animal(ID, Type, Cost),
#max {X:animal(_, Type, X)} = Cost.
#show most_expensive_animals/3.
答案集为:
most_expensive_animals(id3,dog,600)
most_expensive_animals(id2,cat,400)
most_expensive_animals(id3,cat,400)
most_expensive_animals(id1,fish,20)
most_expensive_animals(id2,fish,20)
most_expensive_animals(id3,fish,20)
我想要实现的是一个规则,它只选择一种与 id 无关的动物类型(它也可以随机发生)。目标是,答案集如下:
most_expensive_animals(id3,dog,600)
most_expensive_animals(id2,cat,400)
most_expensive_animals(id1,fish,20)
此外,被踢出的答案应该保存在替代答案集中,如下所示:
alternative_most_expensive_animals(id3,cat,400)
alternative_most_expensive_animals(id2,fish,20)
alternative_most_expensive_animals(id3,fish,20)
我遵循了一些选择规则的方法,但没有成功。谁能进一步帮助我?
提前致谢!
您的程序是确定性的,无法做出选择:
most_expensive_animals(ID, Type, Cost) :- ...
您可以通过声明
来更改它{ most_expensive_animals(ID, Type, Cost) } :- ...
所以每一种最昂贵的动物都可以被列为最昂贵的或不是最昂贵的。您还想涵盖非案例。我个人会这样写:
1 { most_expensive_animals(ID, Type, Cost) ; alt_most_expensive_animals(ID, Type, Cost) } 1 :- ...
意味着每一种最昂贵的动物都可以这样列出或作为替代品列出 - 如果 body 触发,则这些谓词中的一个必须为真。但这里仍然存在一个问题:可以列出多个或根本没有动物。我个人会写 2 个约束来防止这两种情况。
:- most_expensive_animals(ID, Type, Cost), most_expensive_animals(ID2, Type, Cost), ID != ID2.
% it is not possible that 2 or more IDs for the same Type and Cost appear
:- animal(_, Type, _), not most_expensive_animals(_, Type, _).
% it is not possible for every type of animal to not have a most expensive listed animal.
可以只使用一个约束:
:- animal(ID, Type, Cost), #max {X:animal(_, Type, X)} = Cost, {most_expensive_animals(IDtmp, Type, Cost)} != 1.
% for every Type/Cost pair where Cost is maxuimum for this Type, it can not be the the number of most expensive animals is different to 1.
这是输出(使用 clingo 的 web version 测试):
clingo version 5.5.0
Reading from stdin
Solving...
Answer: 1
most_expensive_animals(id3,dog,600) most_expensive_animals(id3,cat,400) most_expensive_animals(id1,fish,20)
Answer: 2
most_expensive_animals(id3,dog,600) most_expensive_animals(id3,cat,400) most_expensive_animals(id3,fish,20)
Answer: 3
most_expensive_animals(id3,dog,600) most_expensive_animals(id3,cat,400) most_expensive_animals(id2,fish,20)
Answer: 4
most_expensive_animals(id3,dog,600) most_expensive_animals(id2,cat,400) most_expensive_animals(id1,fish,20)
Answer: 5
most_expensive_animals(id3,dog,600) most_expensive_animals(id2,cat,400) most_expensive_animals(id3,fish,20)
Answer: 6
most_expensive_animals(id3,dog,600) most_expensive_animals(id2,cat,400) most_expensive_animals(id2,fish,20)
SATISFIABLE