2016-06-17 20 views
1

Ich spielte in Scheme und ich versuchte ein Prädikat zu erstellen, das mir sagen würde, ob es einen Pfad zwischen zwei Scheitelpunkten in einem gegebenen Graph gibt. Mein Programm verwendet grundsätzlich die Warteschlange, um es herauszufinden. Ich benutze BFS, um durch den Graphen zu gehen, und ich füge alle angrenzenden Scheitelpunkte der Queue hinzu und wenn mein gesuchter Wert in der Queue ist, gebe ich #t zurück. Aber diese Lösung erfordert die Verwendung der Datenstruktur, um alle Informationen zu speichern, und mir ist bewusst, dass das Übergeben der Warteschlange zwischen mehreren Funktionen nicht ideal ist. Wie kann ich meinen Code ändern, ohne die Warteschlange zu verwenden und sie sauberer zu machen? Sie können meinen Code unten sehen.Wie schreibe ich meinen Code in Scheme ohne Speichern von Statusinformationen in Strukturen?

habe ich diese aproach: http://www.geeksforgeeks.org/find-if-there-is-a-path-between-two-vertices-in-a-given-graph/

(require data/queue) 
(define-struct graph (vertices edges)) 
(define-struct vertice (name visited)) 
(define-struct edge (start-vertice end-vertice length)) 

;I create data for testing here 
(define vertices-list2 
    (list (make-vertice 0 0) 
     (make-vertice 1 0) 
     (make-vertice 2 0) 
     ) 
) 

(define edges-list2 
    (list (make-edge 0 1 0) 
     (make-edge 1 2 0) 
     ) 
) 

;Const for marking a vertice as visited 
(define VISITED 99999) 

(define (reachable? X Y G) 
    (let ((q (make-queue))) 
    (cond 
     [(empty? (graph-edges G)) #f] 
     [(= X Y) #t] 
     [else (bfs-graph X Y G q) ] 
    ) 
    ) 
) 

(define (bfs-graph X Y G q) 
    (cond 
    [(not(eq? (vertice-visited (find-vertice X (graph-vertices G))) VISITED)) 
    (begin 
     (set-vertice-visited! (find-vertice X (graph-vertices G)) VISITED) 
     (find-adj X (graph-edges G) q) 
     (cond 
     [(queue-empty? q) #f] 
     [(memq Y (queue->list q)) #t] 
     [else (bfs-graph (dequeue! q) Y G q)] 
     ) 
     ) 
    ] 
    [(queue-empty? q) #f] 
    [else (bfs-graph (dequeue! q) Y G q)] 
    ) 
) 

(define (find-vertice V vertice-list) 
    (cond 
    [(empty? vertice-list) (error 'find-vertice "Graph does not contain given vertice")] 
    [(eq? V (vertice-name (car vertice-list))) (car vertice-list)] 
    [else (find-vertice V (cdr vertice-list))] 
    ) 
) 

(define (find-adj V edge-list q) 
    (cond 
    [(empty? edge-list) q] 
    [(eq? V (edge-start-vertice (car edge-list))) 
    (begin 
     (enqueue! q (edge-end-vertice (car edge-list))) 
     (find-adj V (cdr edge-list) q)) 
    ] 
    [else (find-adj V (cdr edge-list) q)] 
    ) 
) 

;Run 
(define G (make-graph vertices-list2 edges-list2)) 
;Predicate call 
(reachable? 0 1 G) 

Antwort

0

Ich bin nicht sicher, warum Sie nicht wollen, entlang der Warteschlange zu übergeben.

Eine Möglichkeit, die Warteschlange zu umgehen, besteht jedoch darin, die Warteschlange und die Hilfsfunktionen für bfs-graph lokal zu machen.

(define (bfs-graph X Y G) 
    (define q (make-queue)) 
    (define (find-vertice V vertice-list) ...) 
    (define (find-adj V edge-list) ...) 
    (cond 
    [(not(eq? (vertice-visited (find-vertice X (graph-vertices G))) VISITED)) 
    ...] 
    ... as-before ...)) 

PS: Ein Eckpunkt, zwei Ecken

+0

Ich wurde gesagt, dass meine aproach keinen funktionellen aproach verwendet, und dass es ein viel sauberer Weg, um dieses Problem zu lösen, ohne in der Warteschlange all Daten zu speichern. Also meine Frage ist eher wie "Wie kann ich die gleiche Funktionalität haben, aber mit Listen statt Warteschlangen?". – Arcane

+0

Sie können zwei Listen (Stapel) verwenden, um eine Warteschlange zu implementieren. Siehe https://programmingpraxis.com/2013/11/08/tow-stacks-make-a-queue/ oder den Originalartikel: http://www.westpoint.edu/eecs/SiteAssets/SitePages/Faculty%20Publication% 20Dokumente/Okasaki/jfp95queue.pdf – soegaard

+0

Vielen Dank für den Link, es ist definitiv nützlich. Wenn ich jedoch die Warteschlangenimplementierung in meinen Code einfüge, macht es das nicht sauberer, oder? Ich frage mich, ob es eine andere Herangehensweise an meine Lösung ohne Warteschlangen gibt. – Arcane