CLP: Ограничения на структурированные переменные?

Возьмем следующий гипотетический сценарий... сетка 5x5 и, скажем, 3 фигуры. Мы хотим определить ограничение на позиции. В CLP мы обычно определяем ограничения целыми числами, так что это один из способов сделать это:

  ... Fig1X #\= 2, Fig1Y #\= 3, ....

то есть у нас есть отдельная переменная для каждой позиции X и Y. Есть ли способ определить ограничение на структурированную переменную, которая построена поверх целых чисел. Ради примера:

 .... Fig1 #\= (2,4) ...

Сценарий только для иллюстрации.

Меня в основном интересует, как вы обрабатываете структурированные переменные, есть ли стандартные практики.


person sten    schedule 22.02.2018    source источник
comment
dif(Fig1, (2,4)). Но гораздо слабее в распространении   -  person false    schedule 23.02.2018


Ответы (2)


Особенно в связи с геометрическими задачами, как в вашем примере, существуют как минимум следующие совершенно разные концептуальные подходы:

  1. geost/N: Эти ограничения обеспечивают специальный мини-язык для рассуждений о многомерных объектах. Это очень мощный и гибкий подход, доступный в SICStus Prolog, а также в некоторых других системах ограничений.
  2. овеществленные ограничения. Например, вы можете указать X #= 2 #==> Y #\= 4, чтобы показать, что Y не должно быть 4, если X равно 2. Таким образом, (X,Y) автоматически отличается от (2,4).
  3. расширяющие ограничения ( доступны как table/2, fd_relation/2 и т. д. во многих системах Prolog) позволяют явно перечислить допустимый набор кортежей или его дополнение.
  4. переделка вашей задачи в виде выбора между допустимыми позициями по булевым индикаторам. Пример такого подхода см. в разделе Packing Squares.

Эти подходы имеют разные последствия и компромиссы. Мои личные предпочтения и рекомендации примерно отражены в приведенном выше порядке. Однако, в зависимости от конкретной ситуации, у одного подхода могут быть значительные преимущества перед другими.

Моделирование в CSP иногда называют скорее искусством, чем наукой, потому что есть так много разных возможностей для выбора, и априори не ясно, какая модель лучше, а также потому, что есть так много компромиссов, таких как удобство, портативность, масштабируемость, скорость, объем памяти и т.д.

person mat    schedule 25.02.2018

В таких случаях, как ваш, когда «структурированные переменные» имеют фиксированную структуру, содержащую только числовые поля, вам не нужно понятие «структурированная переменная». Концептуально вы просто работаете с кортежами чисел (или числовыми переменными).

Иногда эти кортежи лучше всего представлять в виде списков, потому что тогда вы можете напрямую применять глобальные ограничения, которые принимают списки в качестве аргументов. Например, чтобы точка [X,Y] не находилась на диагонали, вы можете написать

alldifferent([X,Y])

или используйте табличное ограничение, чтобы ограничить его заданным набором координат:

table([[X,Y]], [[1,2],[2,4],[3,1],[4,3]])

В других случаях лучше использовать структуры с описательными функторами, такими как point(X,Y) или rect(X1,Y1,X2,Y2), а затем написать соответствующие обертки ограничений, такие как

points_differ(point(X,Y), point(V,W)) :-
    X#\=V or Y#\=W.

or

rect_contains_point(rect(I,J,K,L), point(PI,PJ)) :-
    I #=< PI, PI #=< K,
    J #=< PJ, PJ #=< L.

(Последний пример взят из http://eclipseclp.org/examples/shikaku.ecl.txt. )

person jschimpf    schedule 23.02.2018
comment
Вы случайно не знаете, есть ли в swi-prolog что-то похожее на table/2 - person sten; 24.02.2018
comment
В библиотеке SWI (clpfd) есть tuples_in/2. - person jschimpf; 24.02.2018
comment
У меня есть вопрос к jschimpf. В вашем коде есть локальные переменные Height и Width в rect_size/2, и они также ограничены. В SWI я использовал такие локальные переменные с ограничениями и не возвращал их вызывающей стороне, они были собраны и я не мог получить ответ. Похоже, ваш код написан на ECLiPSe. Меня интересует, что вам не нужно заботиться о том, чтобы локальные переменные clp собирались в ECLiPSe. - person Taku Koyahata; 24.02.2018
comment
@Taku: правильно, ECLiPSe не потеряет нерешенных ограничений, даже если вы потеряете доступ к его переменным. Худшее, что может случиться, это то, что ваш запрос верхнего уровня завершится с неразрешенными ограничениями (= отложенными целями в терминологии ECLiPSe). В примере этого не происходит, потому что маркировка переменных прямоугольника приводит через распространение к созданию экземпляров этих вспомогательных переменных высоты/ширины. Если бы это было не так, вам пришлось бы передать эти переменные процедуре маркировки. - person jschimpf; 24.02.2018
comment
Понимаю. Спасибо за ответ! - person Taku Koyahata; 25.02.2018