/// <summary>
        /// Prunes the individual agent MDDs and, if possible, matches them to return a non-conflicting configuration of
        /// paths of the given costs.
        /// </summary>
        /// <param name="CAT"></param>
        /// <returns>
        /// null if no solution is found.
        /// </returns>
        public override SinglePlan[] Solve(ConflictAvoidanceTable CAT)
        {
            if (this.Prune()) // Everything was pruned
            {
                return(null);
            }

            this.solver.survivedPruningHL++;
            A_Star_MDDs findSolution = new A_Star_MDDs(allMDDs, runner, CAT);

            SinglePlan[] ans = findSolution.Solve();
            this.generated           = findSolution.generated;
            this.expanded            = findSolution.expanded;
            this.conflictsNotAvoided = findSolution.conflictCount;
            this.conflictCounts      = findSolution.GetExternalConflictCounts();
            this.conflictTimes       = findSolution.GetConflictTimes();
            return(ans);
        }
        public override SinglePlan[] Solve(ConflictAvoidanceTable CAT)
        {
            for (int i = 0; i < allMDDs.Length; i++)
            {
                if (allMDDs[i].levels == null)
                {
                    return(null);
                }
            }
            A_Star_MDDs findSolution = new A_Star_MDDs(allMDDs, runner, CAT);

            SinglePlan[] ans = findSolution.Solve();
            generated           = findSolution.generated;
            expanded            = findSolution.expanded;
            conflictsNotAvoided = findSolution.conflictCount;
            conflictCounts      = findSolution.GetExternalConflictCounts();
            conflictTimes       = findSolution.GetConflictTimes();
            return(ans);
        }
        public override SinglePlan[] Solve(ConflictAvoidanceTable CAT)
        {
            MDD[] match      = new MDD[2];
            bool  Converging = true;

            int[] changed          = new int[allMDDs.Length];
            int   currentIteration = 0;

            MDD.PruningDone conflictStatus = MDD.PruningDone.NOTHING;

            while (Converging)
            {
                currentIteration++;
                Converging = false;

                for (int i = allMDDs.Length - 1; i >= 0; i--)
                {
                    for (int j = i + 1; j < allMDDs.Length; j++)
                    {
                        if (changed[i] >= currentIteration - 1 || changed[j] >= currentIteration - 1) // If at least one of the two MDDs was changed during the last iteration
                        {
                            int matchCounterIncrement;
                            (conflictStatus, matchCounterIncrement) = allMDDs[i].SyncMDDs(allMDDs[j], this.syncSize == 3);
                            this.matchCounter += matchCounterIncrement;

                            if (conflictStatus == MDD.PruningDone.EVERYTHING)
                            {
                                return(null);
                            }

                            else if (conflictStatus == MDD.PruningDone.SOME)
                            {
                                changed[i] = currentIteration;
                                Converging = true;
                            }

                            (conflictStatus, matchCounterIncrement) = allMDDs[i].SyncMDDs(allMDDs[j], this.syncSize == 3);
                            this.matchCounter += matchCounterIncrement;

                            if (conflictStatus == MDD.PruningDone.EVERYTHING)
                            {
                                return(null);
                            }

                            else if (conflictStatus == MDD.PruningDone.SOME)
                            {
                                changed[i] = currentIteration;
                                Converging = true;
                            }
                        }
                    }
                }
            }
            this.solver.survivedPruningHL++;
            if (allMDDs[0].levels == null)
            {
                return(null);
            }
            A_Star_MDDs findSolution = new A_Star_MDDs(allMDDs, runner, CAT);

            SinglePlan[] ans = findSolution.Solve();
            generated           = findSolution.generated;
            expanded            = findSolution.expanded;
            conflictsNotAvoided = findSolution.conflictCount;
            return(ans);
        }
        public override SinglePlan[] Solve(ConflictAvoidanceTable CAT)
        {
            A_Star_MDDs findSolution;

            SinglePlan[]     subCheck;
            MDD[]            match;
            MddMatchAndPrune matcher = new MddMatchAndPrune(runner, this);

            foreach (MDD checkValid in allMDDs)
            {
                if (checkValid.levels == null)
                {
                    return(null);
                }
            }

            if (maxGroupChecked >= 2)
            {
                match = new MDD[2];
                for (int i = allMDDs.Length - 1; i >= 0; i--)
                {
                    for (int j = i + 1; j < allMDDs.Length; j++)
                    {
                        match[0] = allMDDs[i];
                        match[1] = allMDDs[j];
                        //matcher.initialize(match);

                        //if (matcher.pruneMDDs() == false)
                        findSolution = new A_Star_MDDs(match, runner, CAT);

                        subCheck = findSolution.Solve();
                        if (subCheck == null || subCheck[0] == null)
                        {
                            return(null);
                        }
                    }
                }
            }
            if (maxGroupChecked >= 3)
            {
                match = new MDD[3];
                for (int i = allMDDs.Length - 2; i >= 0; i--)
                {
                    for (int j = i + 1; j < allMDDs.Length - 1; j++)
                    {
                        for (int t = j + 1; t < allMDDs.Length; t++)
                        {
                            match[0] = allMDDs[i];
                            match[1] = allMDDs[j];
                            match[2] = allMDDs[t];
                            //matcher.initialize(match);

                            //if (matcher.pruneMDDs() == false)
                            findSolution = new A_Star_MDDs(match, runner, CAT);

                            subCheck = findSolution.Solve();
                            if (subCheck == null || subCheck[0] == null)
                            {
                                return(null);
                            }
                        }
                    }
                }
            }
            if (maxGroupChecked >= 4)
            {
                match = new MDD[4];
                for (int i = allMDDs.Length - 3; i >= 0; i--)
                {
                    for (int j = i + 1; j < allMDDs.Length - 2; j++)
                    {
                        for (int t = j + 1; t < allMDDs.Length - 1; t++)
                        {
                            for (int m = t + 1; m < allMDDs.Length; m++)
                            {
                                match[0] = allMDDs[i];
                                match[1] = allMDDs[j];
                                match[2] = allMDDs[t];
                                match[3] = allMDDs[m];
                                //matcher.initialize(match);

                                //if (matcher.pruneMDDs() == false)
                                findSolution = new A_Star_MDDs(match, runner, CAT);

                                subCheck = findSolution.Solve();
                                if (subCheck == null || subCheck[0] == null)
                                {
                                    return(null);
                                }
                            }
                        }
                    }
                }
            }
            this.solver.survivedPruningHL++;
            if (allMDDs[0].levels == null)
            {
                return(null);
            }
            findSolution = new A_Star_MDDs(allMDDs, runner, CAT);
            SinglePlan[] ans = findSolution.Solve();
            generated           = findSolution.generated;
            expanded            = findSolution.expanded;
            conflictsNotAvoided = findSolution.conflictCount;
            conflictCounts      = findSolution.GetExternalConflictCounts();
            conflictTimes       = findSolution.GetConflictTimes();
            return(ans);
        }