2015-05-07 4 views
5

Hier ist ein Überblick über mein SWI-Prolog-Programm:Verwendungsbeschränkungen verdinglichten 3 Nummern machen in Folge

:- use_module(library(clpfd)). 

consec1(L) :- 
    L=[L1,L2,L3,L4,L5,L6,L7,L8,L9], 
    L ins 1..9, 
    ..., 
    abs(L5-L4)#=1, 
    all_different(L), 
    labeling([],L) 

abs(L5-L4)#=1 macht L5 und L4 nebeneinander. Wenn ich drei Zahlen nebeneinander machen möchte, z.B. L3, L4 und L5, wie könnte ich dazu komprimierte Einschränkungen verwenden?

z. L3=4, L5=5, L4=6 oder L4=7, L5=8, L3=9

+0

Mit "konsekutiv" meinen Sie z. '(L2 # = L1 + 1 #/\ L3 # = L2 + 1) # \/(L2 # = L1-1 #/\ L3 # = L2-1)'? – repeat

+0

Sollte diese Beziehung auch für alle 3 benachbarten Mitglieder von L gelten --- oder nur für einige/irgendwelche? – repeat

Antwort

3

Dies implementiert in Folge in dem Sinne, Sie in den Kommentaren gab. Für eine Liste der N Werte benötigen wir genügend Platz, damit alle Werte zueinander passen und alle Werte müssen unterschiedlich sein.

consecutive([]). % debatable case 
consecutive(Xs) :- 
    Xs = [_|_], 
    length(Xs, N), 
    all_different(Xs), 
    max_of(Max, Xs), 
    min_of(Min, Xs), 
    Max-Min #= N-1. 

max_of(Max, [Max]). 
max_of(Max0, [E|Es]) :- 
    Max0 #= max(E,Max1), 
    max_of(Max1, Es). 

min_of(Min, [Min]). 
min_of(Min0, [E|Es]) :- 
    Min0 #= min(E, Min1), 
    min_of(Min1, Es). 
+1

Das funktioniert - vielen Dank! – mmgro27

2

TL; DR: zu lang für einen Kommentar: Spielzeit mit spezialisierten Einschränkungen


Diese Antwort folgt auf this previous answer; Aktuelle Versionen von SICStus Prolog bieten spezialisierte clpfd-Bedingungen maximum/2 und minimum/2 als Alternativen zu min_of/2 und max_of/2.

Verwendung des folgenden Codes für das Benchmarking 1,2 ...

 
:- use_module (library(clpfd)). 
:- use_module(library(between)). 

bench_(How, N, Ub) :- 
    \+ \+ ( length (Xs, N), 
      domain (Xs, 1, Ub), 
      all_different (Xs), 
      Max-Min  #= N-1, 
      ( How = 0 
      ; How = min_of , max_of(Max, Xs), min_of(Min, Xs) 
      ; How = minimum, maximum(Max, Xs), minimum(Min, Xs) 
      ), 
      labeling ([enum], Xs)). 

... wir folgende Tests durchgeführt:

  1. Um Worst-Case-Overhead von min Schätzung/max Einschränkung:

     
    ?- member (How, [0,v1,v2]), call_time (bench_(How,10,10), T_ms). 
        How = 0 , T_ms = 5910 
    ; How = v1, T_ms = 19560 
    ; How = v2, T_ms = 7190. 
    
  2. die Laufzeit messen Kosten von min/max Einschränkungen in typischen Fällen Vermehrungs

     
    ?- between (6, 8, N), NN #= N+N, call_time(bench_(v1,N,NN),T_ms). 
        N = 6, NN = 12, T_ms = 50 
    ; N = 7, NN = 14, T_ms = 300 
    ; N = 8, NN = 16, T_ms = 2790. 
    
    ?- between(6, 8, N), NN #= N+N, call_time(bench_(v2,N,NN),T_ms). 
        N = 6, NN = 12, T_ms = 20 
    ; N = 7, NN = 14, T_ms = 100 
    ; N = 8, NN = 16, T_ms = 830. 
    

In den beide "Use Cases", geben die spezialisierten Zwänge beeindruckende Beschleunigung.


Fußnote 1: Mit SICStus Prolog Version 4.3.2 (64-Bit).
Fußnote 2: Antwortsequenzen wurden nachbearbeitet, um das Aussehen zu verbessern.