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 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);
        }