Как просмотреть несколько ограничений вместе в библиотеке ограничений Python
Я практиковался в использовании библиотеки ограничений Python, решая с ее помощью логические головоломки. Мне было очень приятно работать, но я застрял в относительно простой головоломке.
Я могу решить ее программно, но цель состоит в том, чтобы решить ее с помощью этой библиотеки.
Это стандартная головоломка типа «каждый человек принимал других в ресторане определенного типа в определенный день недели», в которой вы выясняете, кто, в какой день, в каком ресторане принимал гостей.
Другие ответы были простыми, но мне трудно сказать: «Дэйв выбрал стейк-хаус на ночь, прежде чем один из следующих пригласил всех в пиццерию». Это комбинация двух разных условий, которую я не могу понять.
Итак, «Билл ненавидит рыбу» легко:
problem.addConstraint(NotInSetConstraint({"bill"}), ["fish"])
И даже мысль о том, что «Дэйв выбрал стейк», проста:
problem.addConstraint(InSetConstraint({"dave"}), ["steak"])
Я борюсь с идеей, что Dave + Steak предшествует Pizza.
Есть ли у кого-нибудь предложение по этому поводу, которое не требует переписывания, чтобы дни были основным числом? Вообще-то, если это ваше предложение, я обязательно его выслушаю, и если у вас есть причина. Но подобные цепочки условий часто встречаются в этих головоломках, поэтому в какой-то момент мне нужно придумать, как сделать подобные вещи.
Вот код на данный момент, он имеет 8 решений, и я хочу свести его к 1 решению, не прибегая к грубой силе (что было бы достаточно легко, заметьте).
from constraint import *
problem = Problem()
hosts = ["andy", "bill", "carl", "dave", "eric"]
foods = ["fish", "pizza", "steak", "tacos", "thai"]
days = ["monday", "tuesday", "wednesday", "thursday", "friday"]
criteria = foods + days
problem.addVariables(criteria, hosts)
problem.addConstraint(AllDifferentConstraint(), foods)
problem.addConstraint(AllDifferentConstraint(), days)
# Eric was not Friday's host
problem.addConstraint(NotInSetConstraint({"eric"}), ["friday"])
# Carl hosted the group on Wednesday
problem.addConstraint(InSetConstraint({"carl"}), ["wednesday"])
# The fellows ate at a Thai place on Friday
problem.addConstraint(lambda f, d: f == d, ["thai", "friday"])
# Bill, who detests fish, volunteered to be the first host
problem.addConstraint(NotInSetConstraint({"bill"}), ["fish"])
problem.addConstraint(InSetConstraint({"bill"}), ["monday"])
# Dave selected a steak house for the night before one of the follows hosted everyone at a pizza parlor
problem.addConstraint(InSetConstraint({"dave"}), ["steak"])
problem.addConstraint(NotInSetConstraint({"dave"}), ["friday"])
problem.addConstraint()
i = 0
sols = problem.getSolutions()
for sol in sols:
i += 1
print(f"-----------{i}-----------")
for host in hosts:
print(f"{host}:")
for fact in sol:
if sol[fact] == host:
print(f" {fact}")
Итак, я попробовал что-то вроде этого:
# problem.addConstraint(lambda steak, pizza, today, yesterday: steak == yesterday and pizza == today and days.index(today) == 1 + days.index(yesterday), ["steak", "pizza"])
Но это не сработает, поскольку лямбда ищет 4 элемента, а ограничение передает только «стейк» и «пиццу», но я, очевидно, не знаю, какие дни выбрать для «вчера» и «сегодня».