列表中相同数字的 Prolog Max 2
Prolog Max 2 of the same numbers in a list
让我们进入正题。
我正在尝试自己制作一个数独构造求解器(与学校无关)。我一直在寻找一些方法来让它发挥作用,但我遇到了一个问题,也许更多人遇到过。
因为在一行或一列中可能有相同数字的倍数,例如,如果数独是 10 x 10,而您必须填写 1 到 5 之间的数字,则固解将为 1,2 ,1,3,2,3,4,5,4,5。由于所有数字都已使用并且最小值和最大值为 2。现在问题仍然存在,我如何编写一个接受列表的谓词和 returns 基于列表中的数字的真或假。
因为不可能使用内置谓词 all_distinct 但可能看起来像它,因为如果有 2 个相同的数字,现在而不是所有不同的都是不同的,如果你跟着我.
我试图做一些丑陋的固定谓词,但它并没有引导我到任何地方。
例如。
distinct_but_2(A,B,C,D) :-
( A = B
-> A \= C,
A \= D),
( A = C
-> A \= B,
A \= D),
( A = D
-> A \= B,
A \= C),
( B = A
-> B \= C,
B \= D),
( B = C
-> B \= A,
B \= D),
( B = D
-> B \= A,
B \= C),
( C = A
-> C \= B,
C \= D),
( C = B
-> C \= A,
C \= D),
( C = D
-> C \= A,
C \= B),
( D = A
-> D \= B,
D \= C),
( D = B
-> D \= A,
D \= C),
( D = C
-> D \= A,
D \= B).
其中我只是想说如果 A = B 那么它不等于所有其他元素,但我仍然缺乏它需要让所有元素都具有相同的另一个元素.
这是我试过的另一个例子
distinct_but_2(A,B,C,D) :-
(isEqual(A,B), isEqual(C,D), notIsEqual(A,C), notIsEqual(A,D));
(isEqual(A,C), isEqual(B,D), notIsEqual(A,B), notIsEqual(A,D));
(isEqual(A,D), isEqual(B,C), notIsEqual(A,B), notIsEqual(A,C)).
isEqual(A,B) :-
A = B.
notIsEqual(A,B) :-
A \= B.
查询结果distinct_but_2(1,1,2,2)。
会是真的,但它说它还有其他解决方案。那是假的。我完全不明白为什么。
所以最后一个问题是,如果所有元素的最小值和最大值都相同,是否可以创建一个谓词来检查列表。
*请注意,由于我试图使其适用于 4 个元素,因此我没有制作接受列表的谓词,但我应该接受一个列表。
你没有说你使用的是哪个 Prolog 系统,但你似乎在寻找类似 global_cardinality/{2,3}
的东西,因为 SWI 有它:http://www.swi-prolog.org/pldoc/man?predicate=global_cardinality/3
这是一个如何使用它的例子:
:- use_module(library(clpfd)).
two_each(Numbers, Vars) :-
length(Numbers, Len),
Len2 #= 2*Len,
length(Vars, Len2),
bagof(X-2, member(X, Numbers), Pairs),
global_cardinality(Vars, Pairs).
查询:
?- two_each([1,2,3], Vars), label(Vars).
Vars = [1, 1, 2, 2, 3, 3] ;
Vars = [1, 1, 2, 3, 2, 3] ;
Vars = [1, 1, 2, 3, 3, 2]
带数独提示的查询:
?- two_each([1,2,3], Vars), Vars=[_,3,_,1,1,_], label(Vars).
Vars = [2, 3, 2, 1, 1, 3] ;
Vars = [2, 3, 3, 1, 1, 2] ;
Vars = [3, 3, 2, 1, 1, 2].
让我们进入正题。 我正在尝试自己制作一个数独构造求解器(与学校无关)。我一直在寻找一些方法来让它发挥作用,但我遇到了一个问题,也许更多人遇到过。
因为在一行或一列中可能有相同数字的倍数,例如,如果数独是 10 x 10,而您必须填写 1 到 5 之间的数字,则固解将为 1,2 ,1,3,2,3,4,5,4,5。由于所有数字都已使用并且最小值和最大值为 2。现在问题仍然存在,我如何编写一个接受列表的谓词和 returns 基于列表中的数字的真或假。
因为不可能使用内置谓词 all_distinct 但可能看起来像它,因为如果有 2 个相同的数字,现在而不是所有不同的都是不同的,如果你跟着我.
我试图做一些丑陋的固定谓词,但它并没有引导我到任何地方。 例如。
distinct_but_2(A,B,C,D) :-
( A = B
-> A \= C,
A \= D),
( A = C
-> A \= B,
A \= D),
( A = D
-> A \= B,
A \= C),
( B = A
-> B \= C,
B \= D),
( B = C
-> B \= A,
B \= D),
( B = D
-> B \= A,
B \= C),
( C = A
-> C \= B,
C \= D),
( C = B
-> C \= A,
C \= D),
( C = D
-> C \= A,
C \= B),
( D = A
-> D \= B,
D \= C),
( D = B
-> D \= A,
D \= C),
( D = C
-> D \= A,
D \= B).
其中我只是想说如果 A = B 那么它不等于所有其他元素,但我仍然缺乏它需要让所有元素都具有相同的另一个元素.
这是我试过的另一个例子
distinct_but_2(A,B,C,D) :-
(isEqual(A,B), isEqual(C,D), notIsEqual(A,C), notIsEqual(A,D));
(isEqual(A,C), isEqual(B,D), notIsEqual(A,B), notIsEqual(A,D));
(isEqual(A,D), isEqual(B,C), notIsEqual(A,B), notIsEqual(A,C)).
isEqual(A,B) :- A = B.
notIsEqual(A,B) :- A \= B.
查询结果distinct_but_2(1,1,2,2)。 会是真的,但它说它还有其他解决方案。那是假的。我完全不明白为什么。
所以最后一个问题是,如果所有元素的最小值和最大值都相同,是否可以创建一个谓词来检查列表。
*请注意,由于我试图使其适用于 4 个元素,因此我没有制作接受列表的谓词,但我应该接受一个列表。
你没有说你使用的是哪个 Prolog 系统,但你似乎在寻找类似 global_cardinality/{2,3}
的东西,因为 SWI 有它:http://www.swi-prolog.org/pldoc/man?predicate=global_cardinality/3
这是一个如何使用它的例子:
:- use_module(library(clpfd)).
two_each(Numbers, Vars) :-
length(Numbers, Len),
Len2 #= 2*Len,
length(Vars, Len2),
bagof(X-2, member(X, Numbers), Pairs),
global_cardinality(Vars, Pairs).
查询:
?- two_each([1,2,3], Vars), label(Vars).
Vars = [1, 1, 2, 2, 3, 3] ;
Vars = [1, 1, 2, 3, 2, 3] ;
Vars = [1, 1, 2, 3, 3, 2]
带数独提示的查询:
?- two_each([1,2,3], Vars), Vars=[_,3,_,1,1,_], label(Vars).
Vars = [2, 3, 2, 1, 1, 3] ;
Vars = [2, 3, 3, 1, 1, 2] ;
Vars = [3, 3, 2, 1, 1, 2].