Advertisement
Guest User

Untitled

a guest
Jul 7th, 2017
161
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1.  
  2. load "Intset";
  3.  
  4. type node = int;
  5.  
  6. type nodes = Intset.intset;
  7.  
  8. datatype edge = EDGE of node * node;
  9.  
  10. datatype graph = GRAPH of nodes * nodes * nodes * edge list;
  11.  
  12. datatype pathTestResult = SUCCESS | NOENTRY | NOEXIT | NOEDGE;
  13.  
  14. fun getNodes(GRAPH(nodes, _, _, _)) = nodes;
  15.  
  16. fun getStarts(GRAPH(_, starts, _, _)) = starts;
  17.  
  18. fun getFins(GRAPH(_, _, fins, _)) = fins;
  19.  
  20. fun getEdges(GRAPH(_, _, _, edges)) = edges;
  21.  
  22. fun checkStarts(GRAPH(nodes, starts, _, _)) = Intset.isSubset(starts, nodes);
  23.  
  24. fun checkFins(GRAPH(nodes, _, fins, _)) = Intset.isSubset(fins, nodes);
  25.  
  26. fun checkSelfEdges(GRAPH(_, _, _, edges)) =
  27.     not (List.exists (fn EDGE(a, b) => (a = b)) edges);
  28.  
  29. fun checkImpossibleEdges(GRAPH(nodes, _, _, edges)) =
  30.     List.all (fn EDGE(a, b) => (Intset.member(nodes, a) andalso
  31.                                          Intset.member(nodes, b))) edges;
  32.  
  33. fun  count([], _) = 0
  34.     | count(x::xs, e) =
  35.         if (e = x) then 1 + count(xs, e)
  36.         else count(xs, e);
  37.  
  38. fun checkDupEdges(GRAPH(_, _, _, edges)) =
  39.     List.all (fn e => (count(edges, e) = 1)) edges;
  40.  
  41. fun checkEdges(g) =
  42.     checkSelfEdges(g) andalso checkDupEdges(g) andalso checkImpossibleEdges(g);
  43.  
  44. fun checkNodes(g) = checkStarts(g) andalso checkFins(g);
  45.  
  46. fun checkGraph(g) = checkEdges(g) andalso checkNodes(g);
  47.  
  48. fun addNode(GRAPH(nodes, starts, fins, edges), n) =
  49.     GRAPH(Intset.add(nodes, n), starts, fins, edges);
  50.  
  51. fun addStartNode(GRAPH(nodes, starts, fins, edges), n) =
  52.     GRAPH(Intset.add(nodes, n), Intset.add(starts, n), fins, edges);
  53.  
  54. fun addFinNode(GRAPH(nodes, starts, fins, edges), n) =
  55.     GRAPH(Intset.add(nodes, n), starts, Intset.add(fins, n), edges);
  56.  
  57. fun addStartFinNode(GRAPH(nodes, starts, fins, edges), n) =
  58.     GRAPH(Intset.add(nodes, n), Intset.add(starts, n), Intset.add(fins, n), edges);
  59.  
  60. fun addEdge(g as GRAPH(nodes, starts, fins, edges), e) =
  61.     let
  62.         val testResult = GRAPH(nodes, starts, fins, e::edges)
  63.         val OK = checkEdges(testResult)
  64.     in
  65.         if OK then testResult else g
  66.     end;
  67.  
  68. fun  testPath'(g as GRAPH(_, _, fins, _), [n]) =
  69.         if Intset.member(fins, n) then SUCCESS else NOEXIT
  70.     | testPath'(g as GRAPH(_, _, _, edges), n::ns) =
  71.         if (List.exists (fn EDGE(a, b) => ((a = n) andalso (b = hd(ns)))) edges) then
  72.             testPath'(g, ns)
  73.         else NOEDGE;
  74.  
  75. fun  testPath(_, []) = NOENTRY
  76.     | testPath(g as GRAPH(_, starts, _, _), n::ns) =
  77.         if (Intset.member(starts, n)) then testPath'(g, n::ns) else NOENTRY;
  78.  
  79. fun  getNextNodes'([]) = []
  80.     | getNextNodes'(EDGE(_, e)::es) = e::getNextNodes'(es);
  81.  
  82. fun getNextNodes(GRAPH(_, _, _, edges), n) =
  83.     getNextNodes'(List.filter (fn EDGE(a, _) => (n = a)) edges);
  84.    
  85. fun reach'(g, n, s, d) =
  86.     let
  87.         val nextNodesList = getNextNodes(g, n)
  88.         val nextNodes = Intset.addList(Intset.empty, nextNodesList)
  89.     in
  90.         Intset.member(nextNodes, s) orelse
  91.         List.exists (fn m => ((not (Intset.member(d, m))) andalso
  92.                                      reach'(g, m, s, Intset.add(d, n)))) nextNodesList
  93.     end;
  94.  
  95. fun reach(g, n, s) = reach'(g, n, s, Intset.empty);
  96.  
  97. fun hasCycleOnNode(g, n) = reach(g, n, n);
  98.  
  99. fun hasCycle(g as GRAPH(nodes, _, _, _)) =
  100.     List.exists (fn n => hasCycleOnNode(g, n)) (Intset.listItems(nodes));
  101.  
  102. fun  shortestPath'(x::[]) = x
  103.     | shortestPath'(x::xs) =
  104.     let val shortest = shortestPath'(xs)
  105.     in
  106.         if (List.length(x) < List.length(shortest)) then x
  107.         else shortest
  108.     end;
  109.  
  110. fun  removeEdges([], _) = []
  111.     | removeEdges((e as EDGE(a, b))::es, n) =
  112.         if ((n = a) orelse (n = b)) then removeEdges(es, n)
  113.         else e::removeEdges(es, n);
  114.  
  115. fun removeNode(GRAPH(nodes, starts, fins, edges), n) =
  116.     GRAPH(Intset.delete(nodes, n),
  117.             (if (Intset.member(starts, n)) then Intset.delete(starts, n) else starts),
  118.             (if (Intset.member(fins, n)) then Intset.delete(fins, n) else fins),
  119.             removeEdges(edges, n));
  120.  
  121. fun shortestPath(g, n, s) =
  122.     let
  123.         val g' = removeNode(g, n)
  124.         val nextNodesList = getNextNodes(g, n)
  125.         val nextNodes = Intset.addList(Intset.empty, nextNodesList)
  126.         val candList =  List.filter (fn c => reach(g', c, s)) nextNodesList
  127.         val candPaths = List.map (fn c => shortestPath(g', c, s)) candList
  128.     in
  129.         if (Intset.member(nextNodes, s)) then [n, s]
  130.         else n::shortestPath'(candPaths)
  131.     end;
  132.  
  133. val g = GRAPH(Intset.empty, Intset.empty, Intset.empty, []);
  134.  
  135. val g = addNode(g, 2);
  136. val g = addNode(g, 3);
  137. val g = addNode(g, 4);
  138.  
  139. val g = addStartNode(g, 1);
  140. val g = addFinNode(g, 5);
  141.  
  142. val g = addEdge(g, EDGE(1, 2));
  143. val g = addEdge(g, EDGE(1, 3));
  144. val g = addEdge(g, EDGE(2, 3));
  145. val g = addEdge(g, EDGE(2, 4));
  146. val g = addEdge(g, EDGE(3, 1));
  147. val g = addEdge(g, EDGE(3, 4));
  148. val g = addEdge(g, EDGE(4, 5));
  149.  
  150. (1, shortestPath(g, 1, 5));
  151. (2, shortestPath(g, 2, 5));
  152. (3, shortestPath(g, 3, 5));
  153. (4, shortestPath(g, 4, 5));
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement