如何在不保存结构中的状态信息的情况下重写Scheme中的代码?

时间:2016-06-17 15:27:10

标签: graph scheme racket

我正在使用Scheme,我正在尝试创建一个谓词,告诉我,如果给定图形中的两个顶点之间存在路径。我的程序基本上使用队列来解决它。我使用BFS遍历图形并将所有相邻顶点添加到队列中,如果我的搜索值在所述队列中,则返回#t。但是这个解决方案需要使用数据结构来存储所有信息,我知道,在多个函数之间传递队列并不理想。如何在不使用队列的情况下更改代码并使其更干净?你可以在下面看到我的代码。

我使用了这个方法: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)

1 个答案:

答案 0 :(得分:0)

我不确定你为什么不想通过队列。

但是,避免传递队列的一种方法是使队列和辅助函数对bfs-graph都是本地的。

(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:一个顶点,两个顶点