protected static void DisplaySolution(CSP.ShiftsPlanner sp, Dictionary <CSP.Models.Shift, Decision> shiftsN, Dictionary <CSP.Models.Shift, Decision> shiftsO, Solution solution)
        {
            List <CSP.Models.ShiftForce> shiftsForce = new List <CSP.Models.ShiftForce>();

            foreach (var shift in shiftsN)
            {
                var force = shift.Value.ToDouble();
                shiftsForce.Add(new CSP.Models.ShiftForce(shift: shift.Key, force: (int)force));
            }
            foreach (var shift in shiftsO)
            {
                var force = shift.Value.ToDouble();
                shiftsForce.Add(new CSP.Models.ShiftForce(shift: shift.Key, force: (int)force));
            }
            sp.ShowSolution(1, shiftsForce, showAgents: true, showSlots: true);
        }
        protected static void CCN_CSP()
        {
            int param1 = ReadSelectionInt("Max agents", 100, min: 1, max: 1000);
            var param2 = ReadSelectionInt("Max solutions", 100, min: 1, max: 5000);
            var param3 = ReadSelectionInt("Max time\"", 120, min: 10, max: 1200);

            //Set agent shifts
            var      solveShifts = new CSP.ShiftsPlanner(param1);
            TimeSpan ts8h        = GetTimeSpanHours(8);
            TimeSpan ts9h        = GetTimeSpanHours(9);
            TimeSpan ts10h       = GetTimeSpanHours(10);
            TimeSpan ts30mi      = GetTimeSpanMinutes(30);

            var shifts = new List <CSP.Models.Shift>();

            shifts.Add(new CSP.Models.Shift(name: "A", start: GetTimeSpanHours(7), duration: ts8h));
            shifts.Add(new CSP.Models.Shift(name: "B", start: GetTimeSpanHours(9), duration: ts8h));
            shifts.Add(new CSP.Models.Shift(name: "E", start: GetTimeSpanHours(11), duration: ts8h));
            shifts.Add(new CSP.Models.Shift(name: "D", start: GetTimeSpanHours(13), duration: ts8h));
            shifts.Add(new CSP.Models.Shift(name: "C", start: GetTimeSpanHours(15), duration: ts8h));
            shifts.Add(new CSP.Models.Shift(name: "H", start: GetTimeSpanHours(17), duration: ts8h));
            solveShifts.Shifts = shifts;

            //Set requirements per shift
            int[]    liveData     = new int[] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 5, 10, 20, 29, 45, 51, 57, 61, 61, 61, 58, 58, 56, 54, 51, 48, 50, 43, 43, 41, 38, 37, 37, 35, 31, 27, 29, 24, 23, 18, 14, 13, 9, 6, 4 };
            var      requirements = new List <CSP.Models.HalfHourRequirement>();
            TimeSpan ts           = GetTimeSpanHours(0);

            for (int i = 0; i < liveData.Length; i++)
            {
                requirements.Add(new CSP.Models.HalfHourRequirement(start: ts, requiredForce: liveData[i]));
                ts = ts.Add(ts30mi);
            }
            solveShifts.HalfHourRequirements = requirements;

            var S = solveShifts.PrepareCspSolver();
            //S.Parameters.EnumerateInterimSolutions = false;
            //S.Parameters.Algorithm = ConstraintSolverParams.CspSearchAlgorithm.TreeSearch;
            //S.Parameters.Solving = () => { Console.WriteLine("Solving"); } ;
            //S.Parameters.TimeLimitMilliSec = (param3.Value - 5) * 1000;
            ConstraintSolverSolution solution = null;

            Task taskSolve = new Task(() =>
            {
                solution = S.Solve();
            });
            Stopwatch timer = new Stopwatch();

            timer.Start();
            taskSolve.Start();

            TimeSpan limit = new TimeSpan(hours: 0, minutes: 0, seconds: param3);

            while (!taskSolve.IsCompleted)
            {
                if (!S.Parameters.Abort)
                {
                    Console.SetCursorPosition(0, Console.CursorTop);
                    Console.Write("  {0:hh}:{0:mm}:{0:ss}", timer.Elapsed);
                    Thread.Sleep(millisecondsTimeout: 500);
                }
                if (timer.Elapsed > limit && !S.Parameters.Abort)
                {
                    S.Parameters.Abort = true;
                    Console.WriteLine("\n  time limit - aborting...");
                }
            }
            Console.WriteLine("\n");

            //solveShifts.Solve(maxSolutions: param2.GetValueOrDefault());
            timer.Stop();

            solveShifts.GetSolutionsAll(solution: solution, maxSolutions: param2);

            if (solveShifts.ShiftsForce != null && solveShifts.ShiftsForce.Count > 0)
            {
                //solveShifts.ShowSolution(no: 1, shiftsForce: solveShifts.ShiftsForce.First().Value, showAgents: true, showSlots: false);
                foreach (var shift in solveShifts.ShiftsForce)
                {
                    solveShifts.ShowSolution(shift.Key, shift.Value, showAgents: true, showSlots: true);
                }
                Console.WriteLine(" solved in {0}", timer.Elapsed);
            }
            else
            {
                Console.WriteLine(" no solution found", timer.Elapsed);
            }
        }
        protected static void alternative_solution()
        {
            int max_available = ReadSelectionInt("Max agents", 100, min: 1, max: 1000);

            //Set agent shifts
            var solveShifts = new CSP.ShiftsPlanner(max_available);

            TimeSpan ts8h   = GetTimeSpanHours(8);
            TimeSpan ts9h   = GetTimeSpanHours(9);
            TimeSpan ts10h  = GetTimeSpanHours(10);
            TimeSpan ts30mi = GetTimeSpanMinutes(30);

            var shifts = new List <CSP.Models.Shift>
            {
                new CSP.Models.Shift(name: "A", start: GetTimeSpanHours(7), duration: ts8h),
                new CSP.Models.Shift(name: "G", start: GetTimeSpanHours(8), duration: ts8h),
                new CSP.Models.Shift(name: "B", start: GetTimeSpanHours(9), duration: ts8h),
                new CSP.Models.Shift(name: "I", start: GetTimeSpanHours(10), duration: ts8h),
                new CSP.Models.Shift(name: "E", start: GetTimeSpanHours(11), duration: ts8h),
                new CSP.Models.Shift(name: "D", start: GetTimeSpanHours(13), duration: ts8h),
                new CSP.Models.Shift(name: "C", start: GetTimeSpanHours(15), duration: ts8h),
                new CSP.Models.Shift(name: "CL", start: GetTimeSpanHours(16), duration: ts8h),
                new CSP.Models.Shift(name: "H", start: GetTimeSpanHours(17), duration: ts8h)
            };

            var OvertimeShifts = new List <CSP.Models.Shift>
            {
                new CSP.Models.Shift(name: "Aoo", start: GetTimeSpanHours(7), duration: ts10h),
                new CSP.Models.Shift(name: "Bo", start: GetTimeSpanHours(9), duration: ts9h),
                new CSP.Models.Shift(name: "Boo", start: GetTimeSpanHours(9), duration: ts10h),
                new CSP.Models.Shift(name: "Io", start: GetTimeSpanHours(10), duration: ts9h),
                new CSP.Models.Shift(name: "Ioo", start: GetTimeSpanHours(10), duration: ts10h),
                new CSP.Models.Shift(name: "Eo", start: GetTimeSpanHours(11), duration: ts9h),
                new CSP.Models.Shift(name: "Eoo", start: GetTimeSpanHours(11), duration: ts10h),
                new CSP.Models.Shift(name: "Do", start: GetTimeSpanHours(12), duration: ts9h),
                new CSP.Models.Shift(name: "Doo", start: GetTimeSpanHours(13), duration: ts10h),
                new CSP.Models.Shift(name: "Co", start: GetTimeSpanHours(15), duration: ts9h),
                new CSP.Models.Shift(name: "CLo", start: GetTimeSpanHours(16), duration: ts9h),
                new CSP.Models.Shift(name: "Hoo", start: GetTimeSpanHours(15), duration: ts10h)
            };

            solveShifts.Shifts         = shifts;
            solveShifts.OvertimeShifts = OvertimeShifts;

            //Set requirements per shift
            int[]    liveData     = new int[] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 6, 7, 9, 11, 22, 25, 21, 32, 44, 38, 33, 48, 41, 54, 50, 42, 43, 45, 60, 62, 56, 44, 33, 22, 11, 18, 16, 24, 28, 6, 12, 15, 8, 6 };
            var      requirements = new List <CSP.Models.HalfHourRequirement>();
            TimeSpan ts           = GetTimeSpanHours(0);

            for (int i = 0; i < liveData.Length; i++)
            {
                requirements.Add(new CSP.Models.HalfHourRequirement(start: ts, requiredForce: liveData[i]));
                ts = ts.Add(ts30mi);
            }
            solveShifts.HalfHourRequirements = requirements;

            Dictionary <CSP.Models.Shift, Decision> shiftsN, shiftsO;

            var solution = solveShifts.alternative_solve(shiftsN: out shiftsN, shiftsO: out shiftsO);

            Array.ForEach(solution.Goals.ToArray(), g => Console.WriteLine("Goal: {0}", g.ToDouble()));

            /*foreach (var shift in shiftsN)
             *  Console.WriteLine("{0,5} {2:hh}:{2:mm}-{3:hh}:{3:mm}: {1,3} agents", shift.Key.Name, shift.Value.ToDouble(), shift.Key.Start, shift.Key.End);
             * foreach (var shift in shiftsO)
             *  Console.WriteLine("{0,5} {2:hh}:{2:mm}-{3:hh}:{3:mm}: {1,3} agents", shift.Key.Name, shift.Value.ToDouble(), shift.Key.Start, shift.Key.End);
             *
             * Console.WriteLine(solution.GetReport());*/
            DisplaySolution(solveShifts, shiftsN, shiftsO, solution);
            Console.ReadLine();
        }
        protected static void CCN_Simplex()
        {
            int param1 = ReadSelectionInt("Max agents", 100, min: 1, max: 1000);
            var param3 = ReadSelectionInt("Max time\"", 120, min: 10, max: 1200);

            //Set agent shifts
            var      solveShifts = new CSP.ShiftsPlanner(param1);
            TimeSpan ts8h        = GetTimeSpanHours(8);
            TimeSpan ts9h        = GetTimeSpanHours(9);
            TimeSpan ts10h       = GetTimeSpanHours(10);
            TimeSpan ts30mi      = GetTimeSpanMinutes(30);

            var shifts = new List <CSP.Models.Shift>();

            shifts.Add(new CSP.Models.Shift(name: "A", start: GetTimeSpanHours(7), duration: ts8h));
            shifts.Add(new CSP.Models.Shift(name: "G", start: GetTimeSpanHours(8), duration: ts8h));
            shifts.Add(new CSP.Models.Shift(name: "B", start: GetTimeSpanHours(9), duration: ts8h));
            shifts.Add(new CSP.Models.Shift(name: "I", start: GetTimeSpanHours(10), duration: ts8h));
            shifts.Add(new CSP.Models.Shift(name: "E", start: GetTimeSpanHours(11), duration: ts8h));
            shifts.Add(new CSP.Models.Shift(name: "D", start: GetTimeSpanHours(13), duration: ts8h));
            shifts.Add(new CSP.Models.Shift(name: "C", start: GetTimeSpanHours(15), duration: ts8h));
            shifts.Add(new CSP.Models.Shift(name: "CL", start: GetTimeSpanHours(16), duration: ts8h));
            shifts.Add(new CSP.Models.Shift(name: "H", start: GetTimeSpanHours(17), duration: ts8h));

            shifts.Add(new CSP.Models.Shift(name: "A++", start: GetTimeSpanHours(7), duration: ts10h));
            shifts.Add(new CSP.Models.Shift(name: "B+", start: GetTimeSpanHours(9), duration: ts9h));
            shifts.Add(new CSP.Models.Shift(name: "B++", start: GetTimeSpanHours(9), duration: ts10h));
            shifts.Add(new CSP.Models.Shift(name: "I+", start: GetTimeSpanHours(10), duration: ts9h));
            shifts.Add(new CSP.Models.Shift(name: "I++", start: GetTimeSpanHours(10), duration: ts10h));
            shifts.Add(new CSP.Models.Shift(name: "E+", start: GetTimeSpanHours(11), duration: ts9h));
            shifts.Add(new CSP.Models.Shift(name: "E++", start: GetTimeSpanHours(11), duration: ts10h));
            shifts.Add(new CSP.Models.Shift(name: "+D", start: GetTimeSpanHours(12), duration: ts9h));
            shifts.Add(new CSP.Models.Shift(name: "D++", start: GetTimeSpanHours(13), duration: ts10h));
            shifts.Add(new CSP.Models.Shift(name: "C+", start: GetTimeSpanHours(15), duration: ts9h));
            shifts.Add(new CSP.Models.Shift(name: "CL+", start: GetTimeSpanHours(16), duration: ts9h));
            shifts.Add(new CSP.Models.Shift(name: "++H", start: GetTimeSpanHours(15), duration: ts10h));
            solveShifts.Shifts = shifts;

            //Set requirements per shift
            int[]    liveData     = new int[] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 6, 7, 9, 11, 22, 25, 21, 32, 44, 38, 33, 48, 41, 54, 50, 42, 43, 45, 60, 62, 56, 44, 33, 22, 11, 18, 16, 24, 28, 6, 12, 15, 8, 6 };
            var      requirements = new List <CSP.Models.HalfHourRequirement>();
            TimeSpan ts           = GetTimeSpanHours(0);

            for (int i = 0; i < liveData.Length; i++)
            {
                requirements.Add(new CSP.Models.HalfHourRequirement(start: ts, requiredForce: liveData[i]));
                ts = ts.Add(ts30mi);
            }
            solveShifts.HalfHourRequirements = requirements;

            //pair shifts with vids
            Dictionary <CSP.Models.Shift, int> shiftsX;
            int             vidGoal;
            var             SX       = solveShifts.PrepareSimplexSolver(maxAgents: param1, shiftsExt: out shiftsX, vidGoal: out vidGoal);
            var             sxParams = new SimplexSolverParams();
            ILinearSolution solution = null;

            Task taskSolve = new Task(() =>
            {
                solution = SX.Solve(sxParams);
            });
            Stopwatch timer = new Stopwatch();

            timer.Start();
            taskSolve.Start();

            TimeSpan limit = new TimeSpan(hours: 0, minutes: 0, seconds: param3);

            while (!taskSolve.IsCompleted)
            {
                Console.SetCursorPosition(0, Console.CursorTop);
                Console.Write("  {0:hh}:{0:mm}:{0:ss}", timer.Elapsed);
                Thread.Sleep(millisecondsTimeout: 500);
            }
            Console.WriteLine("\n");

            timer.Stop();

            if (solution.Result == LinearResult.Feasible || solution.Result == LinearResult.Optimal)
            {
                Console.WriteLine(" solved as {1} after {0}", timer.Elapsed, solution.Result);
                Console.WriteLine("Goal: {0}", solution.GetValue(vidGoal).ToDouble());
                List <CSP.Models.ShiftForce> shiftsForce = new List <CSP.Models.ShiftForce>();
                foreach (var shift in shiftsX)
                {
                    var force = solution.GetValue(shift.Value).ToDouble();
                    shiftsForce.Add(new CSP.Models.ShiftForce(shift: shift.Key, force: (int)force));
                }
                solveShifts.ShowSolution(1, shiftsForce, showAgents: true, showSlots: true);
            }
            else
            {
                Console.WriteLine(" no solved :: {1} after {0}", timer.Elapsed, solution.Result);
            }
        }