Guest User

Untitled

a guest
Sep 15th, 2018
88
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
F# 4.16 KB | None | 0 0
  1. module GraphStuff.Graph
  2. open System
  3. open System.Collections.Generic
  4. type Cost = float
  5. type Node (name : 'a) =
  6.    let neighbors = Dictionary<Node, Cost> ()
  7.    member this.Name = name
  8.    member this.Neighbors = List.ofSeq neighbors.Keys
  9.    member this.NeighborCostPairs = [for i in neighbors do yield (i.Key, i.Value)]
  10.    member this.IsNeighborsWith (node : Node) = neighbors.ContainsKey (node)
  11.    member this.CostOfTravel (target : Node) =
  12.        let _, cost = neighbors.TryGetValue target
  13.        cost
  14.    member this.AddNeighbor (newNeighbor : Node, cost : Cost) = neighbors.Add(newNeighbor, cost)
  15.    member this.RemoveNeighbor (node : Node) =
  16.        if this.IsNeighborsWith node then neighbors.Remove node |> ignore
  17.    override this.ToString () = "Node (" + this.Name.ToString () + ")"
  18. type Graph (nodeList : Node list) =
  19.    let nodes = List<Node> ()
  20.    do for node in nodeList do nodes.Add node
  21.    member this.Nodes = nodes.AsReadOnly ()
  22.    member this.AddNode (node : Node) = nodes.Add node
  23.    member this.RemoveNode (node : Node) =
  24.        if this.ContainsNode node then
  25.            for i in node.Neighbors do i.RemoveNeighbor node
  26.            nodes.Remove node |> ignore
  27.    member this.ContainsNode (node : Node) = nodes.Contains node
  28.    member this.OneWayPath (startNode : Node, endNode : Node, cost : Cost) =
  29.        if this.ContainsNode startNode && this.ContainsNode endNode then
  30.            startNode.AddNeighbor (endNode, cost)
  31.    member this.TwoWayPath (a : Node, b : Node, cost : Cost) =
  32.        if this.ContainsNode a && this.ContainsNode b then
  33.            a.AddNeighbor (b, cost)
  34.            b.AddNeighbor (a, cost)
  35. let dijkstra (graph : Graph, startNode : Node, endNode : Node) =
  36.    let infinity = Double.PositiveInfinity
  37.    let unvisited = HashSet<Node> ()
  38.    let nodeDistances = Dictionary<Node, float> ()
  39.    for node in graph.Nodes do
  40.        if node = startNode then nodeDistances.Add (node, 0.0)
  41.        else nodeDistances.Add (node, infinity)
  42.        unvisited.Add (node) |> ignore
  43.    let getStoredDist node =
  44.        match nodeDistances.TryGetValue node with
  45.        | true, x -> Some x
  46.        | false, _ -> None
  47.    let minDist () = unvisited |> Seq.minBy (getStoredDist)
  48.    let evalNeighbors (currentNode : Node) =
  49.        printf "Evaluating node %s\n" (currentNode.ToString ())
  50.        let currentNeighbors = HashSet<Node> ()
  51.        for node in currentNode.Neighbors do currentNeighbors.Add(node) |> ignore
  52.        let validNeighbors = new HashSet<Node> ()
  53.        for node in unvisited do validNeighbors.Add node |> ignore
  54.        validNeighbors.IntersectWith currentNeighbors
  55.        for neighbor in validNeighbors do
  56.            let neighborDist = currentNode.CostOfTravel neighbor
  57.            if ((getStoredDist currentNode).Value + neighborDist) < (getStoredDist (neighbor)).Value then
  58.                nodeDistances.Remove (neighbor) |> ignore
  59.                nodeDistances.Add (neighbor, neighborDist + (getStoredDist currentNode).Value)
  60.        unvisited.Remove currentNode |> ignore
  61.    let rec loop (currentNode : Node) =
  62.        evalNeighbors currentNode
  63.        if (unvisited.Contains endNode) = false then (getStoredDist endNode)
  64.        elif (getStoredDist (minDist ())).Value = infinity then None
  65.        else loop (minDist ())
  66.    loop startNode
  67. let run () =
  68.    let nodeList = List<Node> ()
  69.    let graph = Graph []
  70.    for i in [1 .. 6] do graph.AddNode (Node i)
  71.    graph.TwoWayPath (graph.Nodes.Item 0, graph.Nodes.Item 1, 7.0)
  72.    graph.TwoWayPath (graph.Nodes.Item 0, graph.Nodes.Item 2, 9.0)
  73.    graph.TwoWayPath (graph.Nodes.Item 0, graph.Nodes.Item 5, 14.0)
  74.    graph.TwoWayPath (graph.Nodes.Item 1, graph.Nodes.Item 2, 10.0)
  75.    graph.TwoWayPath (graph.Nodes.Item 1, graph.Nodes.Item 3, 15.0)
  76.    graph.TwoWayPath (graph.Nodes.Item 2, graph.Nodes.Item 3, 11.0)
  77.    graph.TwoWayPath (graph.Nodes.Item 2, graph.Nodes.Item 5, 2.0)
  78.    graph.TwoWayPath (graph.Nodes.Item 3, graph.Nodes.Item 4, 6.0)
  79.    graph.TwoWayPath (graph.Nodes.Item 4, graph.Nodes.Item 5, 9.0)
  80.    let a = dijkstra (graph, graph.Nodes.Item 0, graph.Nodes.Item 4)
  81.    printf "Cost: %f" a.Value
  82.    Console.ReadKey true |> ignore
Add Comment
Please, Sign In to add comment