public void GenerateOutputs()
        {
            // Arrange, Act
            int size = 4;

            IComparatorNetwork.Inputs = size;
            var c1 = new Comparator[3] {
                new Comparator(0, 1), new Comparator(0, 2), new Comparator(2, 3)
            };
            var c2 = new Comparator[3] {
                new Comparator(0, 1), new Comparator(0, 3), new Comparator(1, 3)
            };
            var c3 = new Comparator[3] {
                new Comparator(1, 2), new Comparator(2, 3), new Comparator(0, 3)
            };

            Console.WriteLine("c1 outputs");
            var n1 = new ComparatorNetwork(c1);

            Console.WriteLine("c2 outputs");
            var n2 = new ComparatorNetwork(c2);

            Console.WriteLine("c3 outputs");
            var n3 = new ComparatorNetwork(c3);

            Assert.IsTrue(true);
        }
        private bool GetAllPerfectMatchingsIter(IReadOnlyList <int> adjacency, IReadOnlyList <int> match, int[] output1, int[] output2, int[] output2Dual)
        {
            var newMatch = GetNextMatching(adjacency, match);

            if (newMatch == null)
            {
                return(false);
            }

            var queue = new Queue <Tuple <IReadOnlyList <int>, IReadOnlyList <int> > >();

            AddSubproblemsToQueue(adjacency, match, newMatch, ref queue);

            while (queue.TryDequeue(out Tuple <IReadOnlyList <int>, IReadOnlyList <int> > subproblem))
            {
                var subAdj   = subproblem.Item1;
                var subMatch = subproblem.Item2;
                newMatch = this.GetNextMatching(subAdj, subMatch);

                if (newMatch != null)
                {
                    //if (ComparatorNetwork.OutputIsSubset(newMatch, output1, output2) ||
                    //    ComparatorNetwork.OutputIsSubset(newMatch, output2Dual, output1))
                    //Trace.WriteLine($"Found match {string.Join(", ", newMatch)}");
                    if (ComparatorNetwork.OutputIsSubsetBipartite(newMatch, output1, output2))
                    {
                        return(true);
                    }

                    AddSubproblemsToQueue(subAdj, subMatch, newMatch, ref queue);
                }
            }

            return(false);
        }
        public void IsSortingNetwork_WithSize3And1Comparator_ReturnsFalse()
        {
            // Arrange, Act
            int size = 3;

            IComparatorNetwork.Inputs = size;
            var comparators = new Comparator[1] {
                new Comparator(0, 1)
            };
            var s1 = new ComparatorNetwork(comparators);

            // Assert
            Assert.IsFalse(s1.IsSortingNetwork());
        }
        public void IsSortingNetwork_WithSize3And3Comparators_ReturnsTrue()
        {
            // Arrange, Act
            int size = 3;

            IComparatorNetwork.Inputs = size;
            var comparators = new Comparator[3] {
                new Comparator(0, 2), new Comparator(0, 1), new Comparator(1, 2)
            };
            var s1 = new ComparatorNetwork(comparators);

            // Assert
            Assert.IsTrue(s1.IsSortingNetwork());
        }
        public void Output_When3Inputs1Comparator_HasExpectedResult()
        {
            // Arrange, Act
            int size = 3;

            IComparatorNetwork.Inputs = size;
            var c1 = new Comparator[1] {
                new Comparator(0, 1)
            };
            var n = new ComparatorNetwork(c1);

            // Assert
            //Assert.AreEqual(4, n.Outputs.Count);
            //Assert.IsTrue(n.Outputs.SetEquals(new HashSet<int> { 1, 4, 5, 6 }));
        }
        public void CloneWithNewComparator_When0Comparator_Contains1Comparator()
        {
            // Arrange
            int size = 3;

            IComparatorNetwork.Inputs = size;
            var comparators = new Comparator[0];
            var s1          = new ComparatorNetwork(comparators);

            // Act
            var s2 = s1.CloneWithNewComparator(new Comparator(1, 2));

            // Assert
            Assert.AreEqual(1, s2.Comparators.Length);
            Assert.AreEqual(1, s2.Comparators[0].X);
            Assert.AreEqual(2, s2.Comparators[0].Y);
        }
        public void SubsumePositiveTest()
        {
            // Arrange, Act
            int size = 4;

            IComparatorNetwork.Inputs = size;
            var c1 = new Comparator[3] {
                new Comparator(0, 1), new Comparator(0, 3), new Comparator(1, 2)
            };
            var c2 = new Comparator[3] {
                new Comparator(0, 1), new Comparator(0, 3), new Comparator(2, 3)
            };

            var n1 = new ComparatorNetwork(c1);
            var n2 = new ComparatorNetwork(c2);

            var result = n1.IsSubsumed(n2);

            Assert.IsTrue(result);
        }
        public void IsRedundant_WhenAreNotRedundant_IsMarkedIsFalse()
        {
            // Arrange
            int size = 3;

            IComparatorNetwork.Inputs = size;
            var c1 = new Comparator[1] {
                new Comparator(0, 1)
            };
            var c2 = new Comparator[1] {
                new Comparator(0, 2)
            };
            var s1 = new ComparatorNetwork(c1);
            var s2 = new ComparatorNetwork(c2);

            // Act
            var result = s2.IsRedundant(s1);

            // Assert
            Assert.IsFalse(result);
        }
        public void PrintWhereMatrix()
        {
            // Arrange, Act
            int size = 4;

            IComparatorNetwork.Inputs = size;
            var c1 = new Comparator[3] {
                new Comparator(2, 4), new Comparator(2, 3), new Comparator(1, 3)
            };
            var c2 = new Comparator[3] {
                new Comparator(1, 4), new Comparator(3, 4), new Comparator(1, 3)
            };

            Trace.WriteLine("c1 outputs");
            var n1 = new ComparatorNetwork(c1);

            Trace.WriteLine("c2 outputs");
            var n2 = new ComparatorNetwork(c2);

            n1.PrintWhereMatrix(n2);
            n2.PrintWhereMatrix(n1);

            Assert.IsTrue(true);
        }
        public bool GetAllPerfectMatchings(IReadOnlyList <int> adjacency, int[] output1, int[] output2, int[] output2Dual)
        {
            var match = GetHopcroftKarpMatching(adjacency);

            if (match == null)
            {
                //Trace.WriteLine($"Result: False");
                return(false);
            }

            //if (ComparatorNetwork.OutputIsSubset(match, output1, output2) ||
            //    ComparatorNetwork.OutputIsSubset(match, output2Dual, output1))
            //Trace.WriteLine($"Found match {string.Join(", ", match)}");
            if (ComparatorNetwork.OutputIsSubsetBipartite(match, output1, output2))
            {
                //Trace.WriteLine($"Result: True");
                return(true);
            }

            var result = this.GetAllPerfectMatchingsIter(adjacency, match, output1, output2, output2Dual);

            //Trace.WriteLine($"Result: {result}");
            return(result);
        }