2012-04-09 4 views
2

Für mein Programm muss ich eine Liste von Listen machen, wobei jede Unterliste 2 Zahlen, X und Y zusammen mit der Summe und dem Produkt dieser 2 Zahlen enthält. Bisher habe ich folgende:Listenaufbauprobleme

genList(95, X,[]):-!. 
genList(N, X,[[X,Y,Sum,Product]|Xs]):- 
    Y is N+1, 
    Sum is X+Y, 
    Sum<101, 
    Product is X*Y, 
    N1 is N+1, 
    genList(N1, X,Xs). 

Dies funktioniert für meinen Testfall genList ganz gut (5,5, Q). Allerdings habe ich Probleme, es für jede Startnummer arbeiten zu lassen.

Das Ziel ist es, jedes Paar von Zahlen zu finden, wo Summe < = 100. Also für einen Startwert durch die oben ausgeführt wird, würde X jedes Paar 1 < X < Y, wo Summe < = 100, und die durch sie mit allen Zahlen würde 2-N eine vollständige Liste möglicher Paare geben.

Für Interessenten, das Problem durch arbeite ich die Summe/Produktproblem ist, beschrieben here (Zweite auf der Seite)

Wenn jemand dabei helfen könnte es wäre sehr dankbar!

Auch keine eingebauten Prolog-Prädikate können verwendet werden, daher die komplizierte Art, dies zu tun, anstatt mit einem Fund.

Ein kleiner Ausschnitt des Ausgangs von diesem ist ausgesagt wie folgt hergestellt:

[[5,6,11,30], [5,7,12,35], [5,8,13, 40], [5,9,14,45], [5,10,15,50], [5,11,16,55], [5,12,17,60], [5,13,18, 65], [5,14,19,70], [5,15,20,75], [5,16,21,80], [5,17,22,85], [5,18,23, 90], [5,19,24,95], [5,20,25,100], [5,21,26,105], [5,22,27,110], ...

EDIT:

Ok, nach ein wenig Bearbeitung, hier ist die neueste Version meines Codes.

Ich denke, es ist sehr nahe, aber es gibt immer noch etwas nicht ganz richtig.

Es durchläuft Nummernpaare, erfordert aber die Verwendung von ";" um alle Antworten zu sehen, was ich nicht will. Darüber hinaus gibt es false zurück, nachdem alle Antworten erschöpft sind. Ich kann es einfach nicht herausfinden.

Auch gibt es eine vollständige Antwort in der Mitte, aber dann entfernt eine Unterliste jedes Mal, bis ich nur mit dem letzten Satz von Paaren übrig bin.

z. genList (0,48,48, Q). gibt mir:

[[48,49,97,2352],[48,50,98,2400],[48,51,99,2448],[48,52,100,2496]] 
[[48,49,97,2352],[48,50,98,2400],[48,51,99,2448],[48,52,100,2496],[49,50,99,2450],[49,51,100,2499]] 
[[48,49,97,2352],[48,50,98,2400],[48,51,99,2448],[49,50,99,2450],[49,51,100,2499]] 
[[48,49,97,2352],[48,50,98,2400],[49,50,99,2450],[49,51,100,2499]] 
[[48,49,97,2352],[49,50,99,2450],[49,51,100,2499]] 
[[49,50,99,2450],[49,51,100,2499]] 
false. 

Wie Sie sehen können, wird eine Unterliste jedes Mal entfernt, ich kann einfach nicht sehen, warum!

Antwort

1

können Sie ausnutzen Prolog Rückzieher hier. Gib einfach an, was du willst. Zum Beispiel könnten Sie sagen:

  • Ich möchte X zwischen 1 und 100 sein.
  • Ich möchte Y zwischen 1 und min(100 - X, X) sein.
  • dann will ich ihr Paar

das an, was ein validPair/1 Prädikat aussehen würde aussehen lassen:

validPair(X-Y) :- 
    between(1, 100, X), 
    Limit is min(100 - X, X), 
    between(1, Limit, Y). 

Sie können es mit ; mit

?- validPair(X). 

und durchsuchen Ergebnisse rufen Sie einfach oder erstellen Sie eine Liste aller übereinstimmenden Paare mit findall/3.

Edit: auch mit Rekursion, können wir unsere Aussagen halten:

  • Ich möchte X zwischen 1 und 100 sein.
  • Ich möchte Y zwischen 1 und min(100 - X, X) sein.
  • dann will ich ihr Paar

So eine Idee, es zu tun einen Arbeiter Prädikat einzurichten wäre:

validPair(Result) :- 
    validPair(0, 0, Result). 
validPair(X, Y, R) :- 
    ... 

dann eingerichtet, um den Basisfall:

validPair(101, _Y, []) :- !. 

und in dem Arbeiter Prädikat, die Aussagen implementieren wir mit einigen Bedingungen hergestellt:

validPair(X, Y, [SomeStuff|R]) :- 
    X =< 100, 
    Limit is min(100 - X, X), 
    Y =< Limit, 
    !, 
    % we can go on and increment Y once we're finished 
    validPair(X, NextY, R). 
validPair(X, Y, R) :- 
    % if we come here that means that Y is finished growing and 
    % we have to increment X 
    NextX is X + 1, 
    validPair(NextX, 0, R). 
+0

Ah ja, ist die Sache für dieses Programm sind wir keinen Prolog Einbauten andere als Arithmetik und die cut- verwendet nicht erlaubt Wahrscheinlich, dass erwähnt haben soll! – XavierNuquos

+0

Danke Mog. Das ist fast da, aber der limitierende Faktor ist hier die Summe <= 100, nicht x <= 100. Ich entschuldige mich, da ich in meinem ursprünglichen Beitrag bemerkt, dass ein großes Stück weggelassen wurde: „Das Ziel ist es, jedes Paar von Zahlen zu finden, wo Summe <= 100. Also für einen Startwert durch die oben ausgeführt wird, würde X jedes Paar 1 XavierNuquos

+0

Haha, ich vermute nicht, es ist nur, dass ich in meinen Versuchen endete, dass "falsch" wieder zurückgegeben wurde, wie ich in meiner anderen Frage hatte :(Es ist ärgerlich, weil es so nah ist, was ich brauche, aber ich kann ' Hmm, ich werde noch ein paar Dinge versuchen und hier posten, wenn es immer noch nicht passiert ... – XavierNuquos

1

Ich habe das Gefühl, dass Sie das Problem falsch angehen; Ich muss zugeben, dass ich nicht wirklich verstehe, was dein Prädikat tut.

Das Ziel ist es, jedes Zahlenpaar zu finden, in dem die Summe < = 100 ist.

Angenommen, Sie ungeordnete Paare von nicht-negativen ganzen Zahlen bedeuten, das ist

between(0, 100, Sum), 
between(0, Sum, X), 
Y is Sum - X, 
X =< Y. 

Die Menge aller solcher Paare (als Liste) können dann mit findall/3 konstruiert werden.

Sie können auch diese mit CLP (fd) tun:

use_module(library(clpfd)). 
[X, Y, Sum] ins 0..100, 
X #=< Y, 
X + Y #= Sum, 
label([X,Y,Sum]).