2014-01-13 3 views
0

목록 목록의 한 요소에서 다른 요소로의 전환에 대한 관계를 표현하려고합니다. 내가 할 수 있기를 원하는 것은 두 가지 임의의 요소 사이에 일정한 차이가 있어야한다고 말하는 것입니다.매트릭스 열과 all_different 사용의 차이점

우리는 목록의 모든 요소가

내가 지금 표현 할 길이 Y.의 목록입니다

X=[X1,X2,X3,...Xn] 

이있는 경우 그 XA 거기에해야 Xa-> XB에서 차이가 어디에서 모든 요소 Xa 및 Xb는 임의의 소정의 요소 인 X (a! = b)

예 : Xa = [1,1,1,1]이면 Xb는 [1,1, 1,2] 모든 요소가 같거나 작아지기를 기대하기 때문에, 마지막은 1-> 2로 간다. 나는이 작업을 수행하려면 다음 조건을 작성한

는 :

ensure_atleast_n_patterns(ListOfLists, DiffPattern, NoOfAtLeastEqualPatterns) :- 
    ( 
    %Loop through the list to set up the constraint between first 
    %element and the rest, move on to next element and and set 
    %up constraint from second element on on etc. 
    %Ex: if ListOfLists=[X1,X2,X3,X4], the following 'loops' will run: 
    %X1-X2, X1-X3,X1-4,X2-X3,X2-X4,X3,X4 
    fromto(ListOfLists, [This | Rest], Rest,[_]), 
    fromto(0,In1,Out1,PatternCount), 
    param([DiffPattern]) 
    do 
     (
      %Compare the difference between two elements: 
      foreach(X, Rest), 
      fromto(0,In2,Out2,Sum2), 
      param([DiffPattern,This]) 
      do 
       This=[X1,X2,X3,X4,X5], 
       X=[Y1,Y2,Y3,Y4,Y5], 
       DiffPattern=[P1,P2,P3,P4,P5], 
       X1 #< Y1 #<=> R1, 
       X2 #< Y2 #<=> R2, 
       X3 #< Y3 #<=> R3, 
       X4 #< Y4 #<=> R4, 
       X5 #< Y5 #<=> R5, 
       Result in 0..1, 
       (R1 #= P1) #/\ (R2 #= P2) #/\ (R3 #= P3) #/\ (R4 #= P4) #/\ (R5 #= P5) #<=> (Result #=1), 
       Out2 #= In2 + Result 
     ), 
     Out1 #= In1 + Sum2 
    ), 
    %Count up, and require that this pattern should at least be present 
    %NoOfAtLeastEqualPatterns times 
    PatternCount #>= NoOfAtLeastEqualPatterns. 

이 확인 작업을 솔기. 행에 all_different()를 사용하려고하면 문제가 발생합니다. 예 : 나는 해결책이 될 수 있다고 생각합니다 :

0,0,0,0,0 
2,2,2,2,1 
1,1,1,1,2 
4,4,4,3,4 
3,3,3,4,3 
etc... 

그러나 라벨 중단 '영원히'

내 접근 방식이 잘못인가? 이 문제를 해결하는 더 좋은 방법은 무엇입니까?

테스트 코드 :

mytest(X):- 
    Tlen = 10, 
    Mind = 0, 
    Maxd = 20, 
    length(X1,Tlen), 
    length(X2,Tlen), 
    length(X3,Tlen), 
    length(X4,Tlen), 
    length(X5,Tlen), 
    domain(X1, Mind, Maxd), 
    domain(X2, Mind, Maxd), 
    domain(X3, Mind, Maxd), 
    domain(X4, Mind, Maxd), 
    domain(X5, Mind, Maxd), 

    all_different(X1), 
    all_different(X2), 
    all_different(X3), 
    all_different(X4), 
    all_different(X5), 

    X=[X1,X2,X3,X4,X5], 

    transpose(X, XT), 

    ensure_atleast_n_patterns(XT, [0,0,0,0,1],1), 
    ensure_atleast_n_patterns(XT, [0,0,0,1,0],1), 
    ensure_atleast_n_patterns(XT, [0,0,1,0,0],1), 
    ensure_atleast_n_patterns(XT, [0,1,0,0,0],1), 
    ensure_atleast_n_patterns(XT, [1,0,0,0,0],1). 

과 내가 같이 실행 : 나 코드가 당신이 마음에 무엇을 표현하지 않는 것을 의심하게 한 가지가있다

mytest(X),append(X, X_1), labeling([], X_1).      

답변

4

. 당신은 말합니다 : "이제는 Xa와 Xa의 차이가 같아야하지만 Xa와 Xb는 X의 어떤 원소 (a! = b)"와 다른 점을 표현하고 싶습니다. 그러나 코드에서 모든 요소 쌍을 고려하지는 않습니다. Xb가 Xa의 오른쪽 어딘가에있는 쌍 (Xb는 Rest의 요소 임) 만 고려하십시오. 이러한 비대칭 성으로 인해 솔루션을 찾기가 어려울 수 있습니다. 그럼에도 불구하고

, 여기있는 솔루션입니다 TLEN = Maxd = 5 : 그것은 모두 고려하도록

| ?- mytest([[0,1,2,3,4],[1,0,3,2,4],[1,0,3,4,2],[3,2,0,1,4],[3,2,0,4,1]]). 
no 

당신은 당신의 코드를 수정하는 경우 :

| ?- mytest([[0,3,4,1,2],[1,2,4,0,3],[1,4,2,0,3],[3,1,4,2,0],[3,4,1,2,0]]). 
yes 

그러나 비대칭 성으로 인해, 다음과 같은 오류가 발생

쌍 (Xa, Xb)을 추가하면 다른 솔루션에서 ListOfLists (XT 행)의 요소를 대체하여 다른 솔루션을 얻을 수 있습니다. 이러한 종류의 솔루션 대칭성을 깨서 검색 공간을 줄이는 것이 좋습니다. 그런데

lex_chain(XT), 

, 내가 all_different/1 대신 all_distinct/1 추천 : 당신은에 그렇게 할 수 있습니다.