Shorthand 用于 clingo 中的多项选择谓词

Shorthand for multiple choice predicates in clingo

现在我有一个单一的选择谓词来定义我的搜索space。

#const nRounds = 3.
#const nPlayers = 17.
#const nSeats = nRounds * nPlayers.
#const nRooms = 3.
#const nDecks = 6.

nSeats { seat(1..nPlayers, 1..nRooms, 1..nDecks) } nSeats.

我想限制此搜索 space,因为我开始 运行 遇到性能问题。在我的设置中,每个玩家只能出现在 4 个“座位”谓词中,所以我想要一些类似的东西:

#for i in 1..nPlayers
nRounds { seat(i, 1..nRooms, 1..nDecks) } nRounds.
#endfor

在内部基本上会变成这样的东西:

nRounds { seat(1, 1..nRooms, 1..nDecks) } nRounds.
nRounds { seat(2, 1..nRooms, 1..nDecks) } nRounds.
nRounds { seat(3, 1..nRooms, 1..nDecks) } nRounds.
...

当然,我可以“自己拼写出来”,即使用另一种语言来生成这些行,但我不明白为什么 clingo 中不存在这种方法。

我首先要寻找一种方法的原因是因为我预计 (nRooms*nDecks choose nRounds) * nPlayers 会比 (nRooms*nDecks*nPlayers) choose nRounds*nPlayers 小得多,而 (nRooms*nDecks*nPlayers) choose nRounds*nPlayers 又比 {seat(P, R, D)} 及其 2^(nRooms*nDecks*nPlayers) 这是我开始的。

即使我的代码中有限制我最终可能得到的实际可能集的约束,以便所有这三种表示都是等价的,但仍然可以从这种手动搜索中获得性能优势 space p运行对吗?

您正在寻找的“for 循环”是一个简单的规则:

nRounds { seat(S, 1..nRooms, 1..nDecks) } nRounds :- S = 1..nPlayers.

检查您的代码与 clingo --text

的区别

我还建议您将 seat(P,R,D) 谓词分成几个较小的谓词(取决于您的问题。 就像每个玩家都分配了一个房间 p2r(P,R),每个房间都分配给了一个甲板 r2d(R,D)。这样你以后就可以在你的约束中保存很多不必要的组合。当然,我的两个谓词可能对你的问题没有意义,但我相信你会找到一个组合来分割你的座位谓词。