Как просмотреть несколько ограничений вместе в библиотеке ограничений 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 элемента, а ограничение передает только «стейк» и «пиццу», но я, очевидно, не знаю, какие дни выбрать для «вчера» и «сегодня».

0 ответов

Другие вопросы по тегам