Advertisement
Guest User

Untitled

a guest
Mar 28th, 2015
247
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
F# 7.69 KB | None | 0 0
  1. open System
  2. open NUnit.Framework
  3.  
  4. (*20*)
  5. type IGraph =
  6.     abstract AddEdge : int -> int -> unit
  7.     abstract RemoveEdge : int -> int -> unit
  8.     abstract HasEdge : int -> int -> bool
  9.     abstract OutByEdge : int -> int list
  10.     abstract Size : int
  11.  
  12. let range k =
  13.     [0..k]
  14.  
  15. (*21*)
  16. type MatrixGraph(n : int) =
  17.     let size = n
  18.     let mutable matrix = Array2D.zeroCreate<bool> n n
  19.  
  20.     interface IGraph with
  21.         member g.AddEdge s t =
  22.             matrix.[s, t] <- true
  23.         member g.RemoveEdge s t =
  24.             matrix.[s, t] <- false
  25.         member g.HasEdge s t =
  26.             matrix.[s, t]
  27.         member g.OutByEdge v =
  28.             List.fold (fun s i ->
  29.                         if matrix.[v, i] then i :: s else s)
  30.                         [] (range (size - 1))
  31.         member g.Size =
  32.             size
  33.  
  34. (*22*)
  35. type ListGraph(n : int) =
  36.     let size = n
  37.     let mutable l = Array.create<int list> n []
  38.  
  39.     interface IGraph with
  40.         member g.AddEdge s t =
  41.             l.[s] <- t :: l.[s]
  42.         member g.RemoveEdge s t =
  43.             l.[s] <- List.filter (fun x -> x <> t) l.[s]
  44.         member g.HasEdge s t =
  45.             List.exists (fun x -> x = t) l.[s]
  46.         member g.OutByEdge v =
  47.             l.[v]
  48.         member g.Size =
  49.             size
  50.  
  51. let isVertice v x =
  52.     v = x
  53.  
  54. (*23*)
  55. let fromVertice (g : IGraph) v =
  56.     let byEdgeFromSet r =
  57.         List.concat (List.map g.OutByEdge r)
  58.     let exclude exclusionPredicate list =
  59.         List.filter (fun u -> not (exclusionPredicate u)) list
  60.     let excludeAll exclusionList list =
  61.         exclude (fun u -> List.exists (isVertice u) exclusionList) list
  62.     let rec fromVerticeSet r =
  63.         let p = excludeAll r (byEdgeFromSet r)
  64.         if p = [] then r else fromVerticeSet (p @ r)
  65.     fromVerticeSet [v]
  66.  
  67. (*24*)
  68. let toVertice (g : IGraph) v =
  69.     let destReachableFrom x =
  70.         List.exists (isVertice v) (fromVertice g x)
  71.     let accumulateVertice acc x =
  72.         if destReachableFrom x then x :: acc else acc
  73.     List.fold accumulateVertice [] (range (g.Size - 1))
  74.  
  75. [<TestFixture>]
  76. type TestGraph () =
  77.     let mutable g = ListGraph (10) :> IGraph
  78.     do
  79.         g.AddEdge 0 1
  80.         g.AddEdge 2 3
  81.         g.AddEdge 1 2
  82.         g.AddEdge 4 5
  83.         g.AddEdge 6 7
  84.         g.AddEdge 7 8
  85.         g.AddEdge 8 6
  86.  
  87.     [<Test>]
  88.     member t.``From vertex`` () =
  89.         let f = fromVertice g 9
  90.         Assert.AreEqual (List.sort f, [9])
  91.         let f = fromVertice g 4
  92.         Assert.AreEqual (List.sort f, [4;5])
  93.         let f = fromVertice g 0
  94.         Assert.AreEqual (List.sort f, [0;1;2;3])
  95.         let f = fromVertice g 6
  96.         Assert.AreEqual (List.sort f, [6;7;8])
  97.  
  98.     [<Test>]
  99.     member t.``To vertex`` () =
  100.         let f = toVertice g 9
  101.         Assert.AreEqual (List.sort f, [9])
  102.         let f = toVertice g 5
  103.         Assert.AreEqual (List.sort f, [4;5])
  104.         let f = toVertice g 3
  105.         Assert.AreEqual (List.sort f, [0;1;2;3])
  106.         let f = toVertice g 6
  107.         Assert.AreEqual (List.sort f, [6;7;8])
  108.  
  109. (*25*)
  110. type IMarkedGraph<'T> =
  111.    inherit IGraph
  112.    abstract SetMark : int -> 'T -> unit
  113.     abstract GetMark : int -> 'T
  114.  
  115. (*26*)
  116. type MarkedGraph<'T>(graph : IGraph) =
  117.     let mutable g = graph
  118.     let mutable mx = Array.zeroCreate<'T> g.Size
  119.  
  120.    interface IMarkedGraph<'T> with
  121.         member p.AddEdge s t =
  122.             g.AddEdge s t
  123.         member p.RemoveEdge s t =
  124.             g.RemoveEdge s t
  125.         member p.HasEdge s t =
  126.             g.HasEdge s t
  127.         member p.OutByEdge v =
  128.             g.OutByEdge v
  129.         member p.Size =
  130.             g.Size
  131.         member p.SetMark v m =
  132.             mx.[v] <- m
  133.         member p.GetMark v =
  134.             mx.[v]
  135.  
  136. type Network (g : IMarkedGraph<string * bool>) =
  137.     let r = System.Random()
  138.  
  139.     let probability os =
  140.         match os with
  141.         | "Windows" -> 0.9
  142.         | "MacOS" -> 0.4
  143.         | "Linux" -> 0.01
  144.         | _ -> 1.0
  145.  
  146.     member s.All =
  147.         (range (g.Size - 1))
  148.    
  149.     member s.NameOf v =
  150.         fst (g.GetMark v)
  151.  
  152.     member s.IsInfected v =
  153.         snd (g.GetMark v)
  154.    
  155.     member s.Infect v =
  156.         g.SetMark v (s.NameOf v, true)
  157.  
  158.     member s.ProbabilisticInfect v p =
  159.         if r.NextDouble() < p then s.Infect v
  160.  
  161.     member s.InfectByOS v =
  162.         s.ProbabilisticInfect v (s.NameOf v |> probability)
  163.  
  164.     member s.OneOfIsInfected l =
  165.         List.fold (fun a i -> s.IsInfected i || a) false l
  166.  
  167.     member s.AllOfAreInfected l =
  168.         List.fold (fun a i -> s.IsInfected i && a) true l
  169.  
  170.     member s.NeighbourIsInfected v =
  171.         s.OneOfIsInfected (g.OutByEdge v)
  172.  
  173.     member s.AllAreInfected =
  174.         s.AllOfAreInfected s.All
  175.  
  176.     member s.MayInfect v =
  177.         (not (s.IsInfected v)) && (s.NeighbourIsInfected v)
  178.  
  179.     member s.DoStep () =
  180.         let mayInfect = List.filter s.MayInfect s.All
  181.         List.iter s.InfectByOS mayInfect
  182.    
  183.     member s.Render =
  184.         let side = g.Size |> float |> Math.Sqrt |> Math.Ceiling |> int
  185.         let concatStrings =
  186.             List.reduce (+)
  187.         let addNewline s =
  188.             s + "\n"
  189.         let mapTail m l =
  190.             match l with
  191.             | x :: xs -> x :: (List.map m xs)
  192.             | _ -> l
  193.         let evenLine i =
  194.             let lineList = List.init side (fun j -> if g.HasEdge (i * side + j) ((i - 1) * side + j) then "." else " ")
  195.             concatStrings (mapTail (fun i -> "   " + i) lineList)
  196.         let renderVertex i =
  197.             let name, v = g.GetMark i
  198.             let sub = if i % side > 0 then (if g.HasEdge i (i - 1) then ".." else "  ") else ""
  199.             sub + name.Substring(0, 1) + (if v then "-" else "+")
  200.         let lineIndex i =
  201.             [i * side..(i+1) * side - 1]
  202.         let renderLine i =
  203.             let lineList = List.map renderVertex (lineIndex i)
  204.             concatStrings lineList
  205.         let renderWithEven i =
  206.             if i > 0 then
  207.                 (evenLine i) + "\n" + (renderLine i)
  208.             else
  209.                 renderLine i
  210.         if side * side <> g.Size then
  211.             ""
  212.         else
  213.             let table = List.init side renderWithEven
  214.             concatStrings (List.map addNewline table)
  215.  
  216. let generateSquareNetwork (size : int) =
  217.     let r = System.Random()
  218.     let g = MarkedGraph(ListGraph(size * size)) :> IMarkedGraph<string * bool>
  219.     let names = ["Windows"; "MacOS"; "Linux"]
  220.     let randomName () =
  221.         names.[r.Next(0, names.Length)]
  222.     let randomBool () =
  223.         r.Next(0, 100) < 60
  224.     let graphMarks = List.init (size * size) (fun i -> (randomName(), false))
  225.     let allVertices = (range (size * size - 1))
  226.     let allFrom x =
  227.         List.map (fun i -> (x, i)) [x + 1..size*size-1]
  228.     let allEdges = List.concat (List.map allFrom allVertices)
  229.     let correctEdge (u, v) =
  230.         (u + 1    = v && u / size = v / size) ||
  231.         (u + size = v && u % size = v % size)
  232.     let test = correctEdge (15,20)
  233.     let correctEdges = List.filter correctEdge allEdges
  234.     let selectedEdges = List.filter (fun i -> randomBool ()) correctEdges
  235.     List.iter (fun i -> g.SetMark i graphMarks.[i]) allVertices
  236.     List.iter (fun (u, v) -> g.AddEdge u v; g.AddEdge v u) selectedEdges
  237.     let net = Network g
  238.     net.Infect 0
  239.     net
  240.  
  241. let simulateNet size steps =
  242.     let net = generateSquareNetwork size
  243.     for i in range steps do
  244.         net.DoStep()
  245.         if i % 10 = 0 then
  246.             let r = net.Render
  247.             printfn "State %d:\n%s" i r
  248.  
  249. [<EntryPoint>]
  250. let main argv =
  251.     let g = MatrixGraph(10) :> IGraph
  252.     g.AddEdge 3 0
  253.     g.AddEdge 5 4
  254.     g.AddEdge 3 2
  255.     g.AddEdge 4 3
  256.     printfn "%A" (toVertice g 0)
  257.     printfn "%A" (fromVertice g 4)
  258.  
  259.     simulateNet 5 100
  260.  
  261.     0
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement