diff --git a/graph.rkt b/graph.rkt index 2bf59c1..f7ab76e 100644 --- a/graph.rkt +++ b/graph.rkt @@ -20,13 +20,17 @@ (module graph-wrapper racket (require (prefix-in g: graph)) - (provide graph? has-vertex? has-edge? vertex=? add-vertex! remove-vertex! + (provide (struct-out graph) has-vertex? has-edge? vertex=? add-vertex! remove-vertex! rename-vertex! add-edge! add-directed-edge! remove-edge! remove-directed-edge! get-vertices in-vertices get-neighbors in-neighbors get-edges in-edges edge-weight transpose graph-copy graph-union! - directed-graph + unweighted-graph? unweighted-graph/undirected + unweighted-graph/directed unweighted-graph/adj + weighted-graph? weighted-graph/undirected weighted-graph/directed + undirected-graph directed-graph + matrix-graph? graphviz) @@ -78,10 +82,32 @@ (g:graph-union! (gg g) (gg other))) ;; 2 Graph constructors - ;; 2.2 Weighted graphs + ;; 2.1 Unweighted Graphs + (define (unweighted-graph? g) + (g:unweighted-graph? (gg g))) + (define (unweighted-graph/undirected edges) + (graph (g:unweighted-graph/undirected edges))) + (define (unweighted-graph/directed edges) + (graph (g:unweighted-graph/directed edges))) + (define (unweighted-graph/adj edges) + (graph (g:unweighted-graph/adj edges))) + + ;; 2.2 Weighted Graphs + (define (weighted-graph? g) + (g:weighted-graph? (gg g))) + (define (weighted-graph/undirected edges) + (graph (g:weighted-graph/undirected edges))) + (define (weighted-graph/directed edges) + (graph (g:weighted-graph/directed edges))) + (define (undirected-graph es [ws #f]) + (graph (g:undirected-graph es ws))) (define (directed-graph es [ws #f]) (graph (g:directed-graph es ws))) + ;; 2.3 Matrix Graphs + (define (matrix-graph? g) + (g:matrix-graph? (gg g))) + ;; 10 Graphviz (define (graphviz g #:output [output #f] #:colors [colors #f]) (g:graphviz (gg g) #:output output #:colors colors))) @@ -113,9 +139,22 @@ [graph-union! (-> Graph Graph Void)] ;; 2 Graph constructors - ;; 2.2 Weighted graphs + ;; 2.1 Unweighted Graphs + [unweighted-graph? (-> Graph Boolean)] + [unweighted-graph/undirected (-> (Listof (List Any Any)) Graph)] + [unweighted-graph/directed (-> (Listof (List Any Any)) Graph)] + [unweighted-graph/adj (-> (Listof (Listof Any)) Graph)] + + ;; 2.2 Weighted Graphs + [weighted-graph? (-> Graph Boolean)] + [weighted-graph/undirected (-> (Listof (List Any Any Any)) Graph)] + [weighted-graph/directed (-> (Listof (List Any Any Any)) Graph)] + [undirected-graph (->* ((Listof (List Any Any))) ((Listof Any)) Graph)] [directed-graph (->* ((Listof (List Any Any))) ((Listof Any)) Graph)] + ;; 2.3 Matrix Graphs + [matrix-graph? (-> Graph Boolean)] + ;; 10 Graphviz [graphviz (->* (Graph) (#:output Output-Port @@ -157,6 +196,34 @@ "digraph G {\n\tnode0 [label=\"c\"];\n\tnode1 [label=\"a\"];\n\tnode2 [label=\"b\"];\n\tsubgraph U {\n\t\tedge [dir=none];\n\t}\n\tsubgraph D {\n\t\tnode2 -> node0;\n\t}\n}\n") (graph-union! g (transpose g))) + (test-case "2 Graph Constructors" + ;; 2.1 Unweighted Graphs + (check-true (unweighted-graph? (directed-graph '((a b) (b c))))) + (check-equal? (graphviz (unweighted-graph/undirected '((a b) (b c)))) + "digraph G {\n\tnode0 [label=\"c\"];\n\tnode1 [label=\"a\"];\n\tnode2 [label=\"b\"];\n\tsubgraph U {\n\t\tedge [dir=none];\n\t\tnode0 -> node2;\n\t\tnode1 -> node2;\n\t}\n\tsubgraph D {\n\t}\n}\n") + (check-equal? (graphviz (unweighted-graph/directed '((a b) (b c)))) + "digraph G {\n\tnode0 [label=\"c\"];\n\tnode1 [label=\"a\"];\n\tnode2 [label=\"b\"];\n\tsubgraph U {\n\t\tedge [dir=none];\n\t}\n\tsubgraph D {\n\t\tnode1 -> node2;\n\t\tnode2 -> node0;\n\t}\n}\n") + (check-equal? (graphviz (unweighted-graph/adj '((a b c) (b c d)))) + "digraph G {\n\tnode0 [label=\"c\"];\n\tnode1 [label=\"a\"];\n\tnode2 [label=\"d\"];\n\tnode3 [label=\"b\"];\n\tsubgraph U {\n\t\tedge [dir=none];\n\t}\n\tsubgraph D {\n\t\tnode1 -> node0;\n\t\tnode1 -> node3;\n\t\tnode3 -> node0;\n\t\tnode3 -> node2;\n\t}\n}\n") + + ;; 2.2 Weighted Graphs + (check-false (weighted-graph? (directed-graph '((a b) (b c))))) + (check-equal? (graphviz (weighted-graph/undirected '((10 a b) (20 b c)))) + "digraph G {\n\tnode0 [label=\"c\"];\n\tnode1 [label=\"a\"];\n\tnode2 [label=\"b\"];\n\tsubgraph U {\n\t\tedge [dir=none];\n\t\tnode0 -> node2 [label=\"20\"];\n\t\tnode1 -> node2 [label=\"10\"];\n\t}\n\tsubgraph D {\n\t}\n}\n") + (check-equal? (graphviz (weighted-graph/directed '((10 a b) (20 b c)))) + "digraph G {\n\tnode0 [label=\"c\"];\n\tnode1 [label=\"a\"];\n\tnode2 [label=\"b\"];\n\tsubgraph U {\n\t\tedge [dir=none];\n\t}\n\tsubgraph D {\n\t\tnode1 -> node2 [label=\"10\"];\n\t\tnode2 -> node0 [label=\"20\"];\n\t}\n}\n") + (check-equal? (graphviz (undirected-graph '((a b) (b c)))) + "digraph G {\n\tnode0 [label=\"c\"];\n\tnode1 [label=\"a\"];\n\tnode2 [label=\"b\"];\n\tsubgraph U {\n\t\tedge [dir=none];\n\t\tnode0 -> node2;\n\t\tnode1 -> node2;\n\t}\n\tsubgraph D {\n\t}\n}\n") + (check-equal? (graphviz (undirected-graph '((a b) (b c)) '(1 "hello"))) + "digraph G {\n\tnode0 [label=\"c\"];\n\tnode1 [label=\"a\"];\n\tnode2 [label=\"b\"];\n\tsubgraph U {\n\t\tedge [dir=none];\n\t\tnode0 -> node2 [label=\"hello\"];\n\t\tnode1 -> node2 [label=\"1\"];\n\t}\n\tsubgraph D {\n\t}\n}\n") + (check-equal? (graphviz (directed-graph '((a b) (b c)))) + "digraph G {\n\tnode0 [label=\"c\"];\n\tnode1 [label=\"a\"];\n\tnode2 [label=\"b\"];\n\tsubgraph U {\n\t\tedge [dir=none];\n\t}\n\tsubgraph D {\n\t\tnode1 -> node2;\n\t\tnode2 -> node0;\n\t}\n}\n") + (check-equal? (graphviz (directed-graph '((a b) (b c)) '(1 "hello"))) + "digraph G {\n\tnode0 [label=\"c\"];\n\tnode1 [label=\"a\"];\n\tnode2 [label=\"b\"];\n\tsubgraph U {\n\t\tedge [dir=none];\n\t}\n\tsubgraph D {\n\t\tnode1 -> node2 [label=\"1\"];\n\t\tnode2 -> node0 [label=\"hello\"];\n\t}\n}\n") + + ;; 2.3 Matrix Graphs + (check-false (matrix-graph? (directed-graph '((a b) (b c)))))) + (test-case "10 Graphviz" (define g (directed-graph '((a b) (b c)))) (check-equal? (graphviz g)