Piotr Czajkowski 6 months ago
parent
commit
b1259e27a6
2 changed files with 226 additions and 0 deletions
  1. 82 0
      20171221/BellmanFord.cs
  2. 144 0
      20171221/Djikstra.cs

+ 82 - 0
20171221/BellmanFord.cs

@@ -0,0 +1,82 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+
+// Adapted from JavaScript example in The Imposter's Handbook by Rob Conery
+
+namespace BellmanFord
+{
+    class Path
+    {
+        public string From;
+        public string To;
+        public int Cost;
+
+        public Path(string from, string to, int cost)
+        {
+            From = from;
+            To = to;
+            Cost = cost;
+        }
+    }
+    class Program
+    {
+        static string[] vertices = { "S", "A", "B", "C", "D", "E" };
+
+        static List<Path> graph = new List<Path>()
+        {
+            new Path("S", "A", 4),
+            new Path("S", "E", -5),
+            new Path("A", "C", 6),
+            new Path("B", "A", 3),
+            new Path("C", "B", -2),
+            new Path("D", "C", 3),
+            new Path("D", "A", 10),
+            new Path("E", "D", 8)
+        };
+
+        static Dictionary<string, int> memo = new Dictionary<string, int>()
+        {
+            { "S", 0 },
+            { "A", int.MaxValue },
+            { "B", int.MaxValue },
+            { "C", int.MaxValue },
+            { "D", int.MaxValue },
+            { "E", int.MaxValue }
+        };
+
+        static bool Iterate()
+        {
+            bool doItAgain = false;
+
+            foreach (var fromVertex in vertices)
+            {
+                Path[] edges = graph.Where(x => x.From == fromVertex).ToArray();
+                foreach (var edge in edges)
+                {
+                    int potentialCost = memo[edge.From] == int.MaxValue ? int.MaxValue : memo[edge.From] + edge.Cost;
+                    if (potentialCost < memo[edge.To])
+                    {
+                        memo[edge.To] = potentialCost;
+                        doItAgain = true;
+                    }
+                }
+            }
+            return doItAgain;
+        }
+
+        static void Main()
+        {
+            for (int i = 0; i < vertices.Length; i++)
+            {
+                if (!Iterate())
+                    break;
+            }
+
+            foreach (var keyValue in memo)
+            {
+                Console.WriteLine($"{keyValue.Key}: {keyValue.Value}");
+            }
+        }
+    }
+}

+ 144 - 0
20171221/Djikstra.cs

@@ -0,0 +1,144 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+// Adapted from JavaScript example in The Imposter's Hanbook by Rob Conery
+// Doesn't support negative edges!
+
+namespace Djikstra
+{
+    class Path
+    {
+        public string Name;
+        public int Cost;
+        public bool Visited;
+
+        public Path(string name, int cost, bool visited)
+        {
+            Name = name;
+            Cost = cost;
+            Visited = visited;
+        }
+    }
+
+    class MemoTable
+    {
+        private List<Path> Table;
+        public Path S;
+
+        public MemoTable(string[] vertices)
+        {
+            S = new Path("S", 0, false);
+            Table = new List<Path>() {S};
+
+            foreach (var vertex in vertices)
+            {
+                Table.Add(new Path(vertex, int.MaxValue, false));
+            }
+        }
+
+        private List<Path> GetCandidateVertices()
+        {
+            return Table.Where(x => !x.Visited).ToList();
+        }
+
+        public Path NextVertex()
+        {
+            List<Path> candidates = GetCandidateVertices();
+
+            if (candidates.Any())
+            {
+                return candidates.OrderBy(x => x.Cost).First();
+            }
+            return null;
+        }
+
+        private Path GetEntry(string vertex) => Table.First(x => x.Name == vertex);
+
+        private void SetCurrentCost(string vertex, int cost)
+        {
+            GetEntry(vertex).Cost = cost;
+        }
+
+        private void SetAsVisited(string vertex)
+        {
+            GetEntry(vertex).Visited = true;
+        }
+
+        private int GetCost(string vertex)
+        {
+            return GetEntry(vertex).Cost;
+        }
+
+        public void Evaluate(List<GraphItem> graph, Path vertex)
+        {
+            GraphItem[] edges = graph.Where(x => x.From == vertex.Name).ToArray();
+            foreach (var edge in edges)
+            {
+                int currentVertexCost = GetCost(edge.From);
+                int toVertexCost = GetCost(edge.To);
+                int tentativeCost = currentVertexCost == int.MaxValue ? int.MaxValue : currentVertexCost + edge.Cost;
+                if (tentativeCost < toVertexCost)
+                    SetCurrentCost(edge.To, tentativeCost);
+            }
+            SetAsVisited(vertex.Name);
+
+            Path next = NextVertex();
+            if (next != null)
+                Evaluate(graph, next);
+        }
+
+        public override string ToString()
+        {
+            StringBuilder buffer = new StringBuilder();
+            foreach (var element in Table)
+            {
+                buffer.AppendLine($"name: {element.Name}, cost: {element.Cost}, visited: {element.Visited}");
+            }
+            return buffer.ToString();
+        }
+    }
+
+    class GraphItem
+    {
+        public string From;
+        public string To;
+        public int Cost;
+
+        public GraphItem(string from, string to, int cost)
+        {
+            From = from;
+            To = to;
+            Cost = cost;
+        }
+    }
+
+    class Program
+    {
+        static string[] vertices = { "A", "B", "C", "D", "E" };
+
+        static List<GraphItem> graph = new List<GraphItem>()
+        {
+            new GraphItem("S", "A", 4),
+            new GraphItem("S", "E", 2),
+            new GraphItem("A", "D", 3),
+            new GraphItem("A", "C", 6),
+            new GraphItem("A", "B", 5),
+            new GraphItem("B", "A", 3),
+            new GraphItem("C", "B", 1),
+            new GraphItem("D", "C", 3),
+            new GraphItem("D", "A", 1),
+            new GraphItem("E", "D", 1)
+        };
+
+        static void Main()
+        {
+            MemoTable memo = new MemoTable(vertices);
+
+            memo.Evaluate(graph, memo.S);
+
+            Console.WriteLine(memo.ToString());
+        }
+    }
+}