Esempio n. 1
0
        private void BFS(GraphNode <T> start, LinkedList <GraphNode <T> > visited)
        {
            var searching = new GPrep.Queue <GraphNode <T> >();

            searching.Enqueue(start);
            while (searching.Count > 0)
            {
                var node     = searching.Dequeue();
                var neighbor = node.Neighbors.Head;
                var cost     = node.Costs.Head;
                while (neighbor != null)
                {
                    if (visited.Find(neighbor.Value) == null)                     // TODO could be faster
                    {
                        searching.Enqueue(neighbor.Value);
                    }
                    neighbor = neighbor.Next;
                }

                if (visited.Find(node) == null)                 // TODO improve, last node is repeated w/o guard
                {
                    visited.InsertBack(node);
                }
            }
        }
        static void Init()
        {
            // Insertion Sort O(n^2)
            runners["is"] = () =>
            {
                var numbers = Utility.GenInts(-100, 100, 100);
                Console.WriteLine(string.Join(", ", numbers) + "\n");

                var _is = new InsertionSort();
                _is.Sort(numbers);
                Console.WriteLine(string.Join(", ", numbers));

                for (var i = 0; i < numbers.Length - 1; i++)
                {
                    Debug.Assert(numbers[i] <= numbers[i + 1]);
                }
            };

            // Quick Sort O(nlgn)
            runners["qs"] = () =>
            {
                var numbers = Utility.GenInts(-100, 100, 100);
                Console.WriteLine(string.Join(", ", numbers) + "\n");

                var qs = new QuickSort();
                qs.Sort(numbers);
                Console.WriteLine(string.Join(", ", numbers));

                for (var i = 0; i < numbers.Length - 1; i++)
                {
                    Debug.Assert(numbers[i] <= numbers[i + 1]);
                }
            };

            // Stack with O(1) Push/Pop
            runners["s"] = () =>
            {
                var numbers = Utility.GenInts(-100, 100, 100);
                //Console.WriteLine(string.Join(", ", numbers) + "\n");

                var s = new GPrep.Stack <int>();
                foreach (var n in numbers)
                {
                    s.Push(n);
                }

                Debug.Assert(numbers.Length == s.Count);

                for (var i = numbers.Length - 1; i >= 0; i--)
                {
                    var n  = numbers[i];
                    var sn = s.Pop();
                    Debug.Assert(n == sn);
                }

                try
                {
                    s.Pop();
                }
                catch (InvalidOperationException e)
                {
                    Debug.Assert(e != null);
                }

                Debug.Assert(s.Count == 0);

                s.Push(2);
                Debug.Assert(s.Count == 1 && s.Pop() == 2);
            };

            // Queue with O(1) Enqueue/Dequeue
            runners["q"] = () =>
            {
                var numbers = Utility.GenInts(-100, 100, 100);
                //Console.WriteLine(string.Join(", ", numbers) + "\n");

                var q = new GPrep.Queue <int>();
                foreach (var n in numbers)
                {
                    q.Enqueue(n);
                }

                Debug.Assert(numbers.Length == q.Count);

                for (var i = 0; i < numbers.Length; i++)
                {
                    var n  = numbers[i];
                    var sn = q.Dequeue();
                    Debug.Assert(n == sn);
                }

                try
                {
                    q.Dequeue();
                }
                catch (InvalidOperationException e)
                {
                    Debug.Assert(e != null);
                }

                Debug.Assert(q.Count == 0);

                q.Enqueue(2);
                Debug.Assert(q.Count == 1 && q.Dequeue() == 2);
            };

            // Binary Search Tree, Search avg O(lgn)
            runners["bst"] = () =>
            {
                var numbers = Utility.GenInts(-100, 100, 100);
                //Console.WriteLine(string.Join(", ", numbers) + "\n");

                var bst = new BinarySearchTree <int>();
                foreach (var n in numbers)
                {
                    bst.Insert(n);
                }

                Debug.Assert(bst.Count == numbers.Length);

                var inOrderValues = bst.GetInOrder();
                Debug.Assert(inOrderValues.Length == numbers.Length);

                new QuickSort().Sort(numbers);
                for (var i = 0; i < numbers.Length; i++)
                {
                    var bstv = inOrderValues[i];
                    var n    = numbers[i];
                    Debug.Assert(bstv == n);

                    var node = bst.Find(n);
                    Debug.Assert(node != null && node.Value == n);

                    bst.Remove(node.Value);
                }

                bst.Remove(0);
                Debug.Assert(bst.Count == 0);

                bst.Insert(2);
                Debug.Assert(bst.Count == 1 && bst.Find(2) != null && bst.Find(2).Value == 2);
            };

            // Red Black Tree, Search O(lgn)
            runners["rbt"] = () =>
            {
                var numbers = Utility.GenInts(-100, 100, 100);
                //Console.WriteLine(string.Join(", ", numbers) + "\n");

                var rbt = new RedBlackTree <int>();
                foreach (var n in numbers)
                {
                    rbt.Insert(n);
                }

                Debug.Assert(rbt.Count == numbers.Length);

                var inOrderValues = rbt.GetInOrder();
                Debug.Assert(inOrderValues.Length == numbers.Length);

                new QuickSort().Sort(numbers);
                for (var i = 0; i < numbers.Length; i++)
                {
                    var rbtv = inOrderValues[i];
                    var n    = numbers[i];
                    Debug.Assert(rbtv == n);

                    var node = rbt.Find(n);
                    Debug.Assert(node != null && node.Value == n);

                    rbt.Remove(node.Value);
                }

                rbt.Remove(0);
                Debug.Assert(rbt.Count == 0);

                rbt.Insert(2);
                Debug.Assert(rbt.Count == 1 && rbt.Find(2) != null && rbt.Find(2).Value == 2);
            };

            // Graph, adjacency list
            runners["g"] = () =>
            {
                var numbers = Utility.GenInts(-100, 100, 100);
                //Console.WriteLine(string.Join(", ", numbers) + "\n");

                var graph  = new Graph <int>();
                var _nodes = new List <GraphNode <int> >();
                foreach (var n in numbers)
                {
                    Console.WriteLine("Add");
                    var node = graph.AddNode(n, n);
                    _nodes.Add(node);
                }

                Debug.Assert(graph.Nodes.Count == numbers.Length);

                foreach (var node in _nodes)
                {
                    // Utility.GenInt impl is weird

                    // single edge, multi edge, self reference, ...
                    var a = _nodes[Utility.GenInt(0, _nodes.Count - 2)];
                    var b = _nodes[Utility.GenInt(0, _nodes.Count - 2)];

                    var cost = Utility.GenInt(0, 99);
                    Console.WriteLine("AddUndirectedEdge");
                    graph.AddUndirectedEdge(a, b, cost);

                    Console.WriteLine("a.Neighbors.Find(b)");
                    Debug.Assert(a.Neighbors.Find(b).Value == b);
                    Console.WriteLine("b.Neighbors.Find(a)");
                    Debug.Assert(b.Neighbors.Find(a).Value == a);

                    Console.WriteLine("a.Costs.Find(cost)");
                    Debug.Assert(a.Costs.Find(cost).Value == cost);
                    Console.WriteLine("b.Costs.Find(cost)");
                    Debug.Assert(b.Costs.Find(cost).Value == cost);
                }

                foreach (var node in _nodes)
                {
                    Console.WriteLine("RemoveNode");
                    graph.RemoveNode(node);
                }

                graph.RemoveNode(_nodes[0]);
                graph.RemoveNode(null);
                Debug.Assert(graph.Nodes.Count == 0);
            };

            // Depth First Search, O(V + E), when used vs DFS?
            runners["ga"] = () =>
            {
                Console.WriteLine("DFS");
                var graph = new Graph <int>();
                var _1    = graph.AddNode(0, 1);
                var _2    = graph.AddNode(1, 2);
                var _3    = graph.AddNode(2, 3);

                graph.AddUndirectedEdge(_1, _2, 1);
                graph.AddUndirectedEdge(_2, _3, 1);
                graph.AddUndirectedEdge(_3, _1, 1);

                var nodes = graph.DFS(_1);
                Debug.Assert(nodes.Count == 3);
                PrintList <int>(nodes);

                nodes = graph.DFS(_2);
                Debug.Assert(nodes.Count == 3);
                PrintList <int>(nodes);

                nodes = graph.DFS(_3);
                Debug.Assert(nodes.Count == 3);
                PrintList <int>(nodes);

                var _4 = graph.AddNode(3, 4);
                var _5 = graph.AddNode(4, 5);
                var _6 = graph.AddNode(5, 6);

                graph.AddDirectedEdge(_4, _5, 1);
                graph.AddDirectedEdge(_5, _6, 1);
                graph.AddDirectedEdge(_6, _4, 1);

                var components = graph.FindComponents();
                Debug.Assert(components.Count == 2);

                Console.WriteLine("Components");
                PrintList <int>(components.Head.Value);
                PrintList <int>(components.Tail.Value);

                Console.WriteLine("BFS");
                nodes = graph.BFS(_1);
                Debug.Assert(nodes.Count == 3);
                PrintList <int>(nodes);

                nodes = graph.BFS(_4);
                Debug.Assert(nodes.Count == 3);
                PrintList <int>(nodes);

                Console.WriteLine("DFS 2");
                nodes = _DFS <int>(_1);
                Debug.Assert(nodes.Count == 3);
                PrintList <int>(nodes);

                Console.WriteLine("BFS 2");
                nodes = _DFS <int>(_4);
                Debug.Assert(nodes.Count == 3);
                PrintList <int>(nodes);
            };

            // Hash Table
            runners["h"] = () =>
            {
                var table = new HashTable <int, GraphNode <double> >();
                for (var i = -10; i <= 10; i++)
                {
                    table.Add(i, new GraphNode <double>(i, i + 0.3));
                }

                Debug.Assert(table.Count == 21);

                for (var i = 10; i >= -10; i--)
                {
                    var node = table.Find(i);
                    Debug.Assert((i + 0.3) == node.Value);
                    Console.WriteLine($"K: {i} V: {node.Value}");
                }
            };

            // Trie Tree
            runners["t"] = () =>
            {
                var trie = new TrieTree();
                trie.Insert("Tomato");
                trie.Insert("Potato");
                trie.Insert("Tom");
                trie.Insert("Tomboy");
                trie.Insert("Tommy");
                trie.Insert("Tomato2");

                Debug.Assert(trie.Find("Tomato"));
                Debug.Assert(trie.Find("Potato"));
                Debug.Assert(trie.Find("Tom"));
                Debug.Assert(trie.Find("Tomboy"));
                Debug.Assert(trie.Find("Tommy"));
                Debug.Assert(trie.Find("Tomato2"));
                Debug.Assert(trie.Find("To") == false);
                Debug.Assert(trie.Find("Tomat") == false);
                Debug.Assert(trie.Find("") == false);
            };

            // Merge Sort O(nlgn)
            runners["m"] = () =>
            {
                var numbers = Utility.GenInts(-100, 100, 100);
                Console.WriteLine(string.Join(", ", numbers) + "\n");

                var ms = new MergeSort();
                ms.Sort(numbers);
                Console.WriteLine(string.Join(", ", numbers));

                for (var i = 0; i < numbers.Length - 1; i++)
                {
                    Debug.Assert(numbers[i] <= numbers[i + 1]);
                }
            };

            runners["d"] = () =>
            {
                var graph = new Graph <int>();
                var _1    = graph.AddNode(1, 1);
                var _2    = graph.AddNode(2, 2);
                var _3    = graph.AddNode(3, 3);

                graph.AddDirectedEdge(_1, _2, 100);
                graph.AddDirectedEdge(_1, _3, 8);
                graph.AddDirectedEdge(_2, _3, 1);

                var cost = Dijkstras(graph.Nodes, _1, _3);
                Console.WriteLine($"Cost: {cost}");
            };
        }