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