예제 #1
0
 public static INumExpr EarlinessCost(IIntervalVar task, int rd, double weight, int useFunction)
 {
     if (useFunction != 0)
     {
         double[] arrX = { rd };
         double[] arrV = { -weight, 0.0 };
         INumToNumSegmentFunction f = cp.PiecewiseLinearFunction(arrX, arrV, rd, 0.0);
         return(cp.StartEval(task, f));
     }
     else
     {
         return(cp.Prod(weight, cp.Max(0, cp.Diff(rd, cp.StartOf(task)))));
     }
 }
예제 #2
0
 public static INumExpr TardinessCost(IIntervalVar task, int dd, double weight, int useFunction)
 {
     if (useFunction != 0)
     {
         double[] arrX = { dd };
         double[] arrV = { 0.0, weight };
         INumToNumSegmentFunction f = cp.PiecewiseLinearFunction(arrX, arrV, dd, 0.0);
         return(cp.EndEval(task, f));
     }
     else
     {
         return(cp.Prod(weight, cp.Max(0, cp.Diff(cp.EndOf(task), dd))));
     }
 }
예제 #3
0
        static void Main(string[] args)
        {
            int D = 5;
            int W = 5;
            int H = 3;
            int G = 2;
            int T = 12;

            int[] k_g  = new int[] { 2, 2 };
            int   ALLK = 4;

            int[] cc_d     = new int[] { 2, 1, 2, 1, 2 };
            int[] ave      = new int[] { 1, 0, 0, 1, 0, 0, 1, 1, 1, 1, 1, 1 };
            int[] dur      = new int[] { 1, 2, 1, 1, 2 };
            int[] prf_D    = new int[] { 2, 1, 1, 1, 100 };
            int[] indexg_d = new int[] { 0, 1, 1, 1, 0 };

            CP roster = new CP();

            // intern availbility
            INumToNumStepFunction resource_AveIntern = roster.NumToNumStepFunction(0, T, 100, "AvailibilityOfIntern");

            for (int t = 0; t < T; t++)
            {
                if (ave[t] == 0)
                {
                    resource_AveIntern.SetValue(t, t + 1, 0);
                }
            }



            // discipline
            IIntervalVar[]     discipline_d  = new IIntervalVar[D];
            ICumulFunctionExpr hospitalNotRR = roster.CumulFunctionExpr();

            for (int d = 0; d < D; d++)
            {
                discipline_d[d]           = roster.IntervalVar();
                discipline_d[d].EndMax    = T;
                discipline_d[d].EndMin    = dur[d];
                discipline_d[d].LengthMax = dur[d];
                discipline_d[d].LengthMin = dur[d];
                discipline_d[d].SizeMax   = dur[d];
                discipline_d[d].SizeMin   = dur[d];
                discipline_d[d].StartMax  = T;
                discipline_d[d].StartMin  = 0;
                discipline_d[d].SetIntensity(resource_AveIntern, 100);
                hospitalNotRR.Add(roster.Pulse(discipline_d[d], 1));
                discipline_d[d].SetOptional();
            }
            IIntervalSequenceVar dis = roster.IntervalSequenceVar(discipline_d);

            roster.Add(roster.Ge(roster.PresenceOf(discipline_d[1]), roster.PresenceOf(discipline_d[4])));
            roster.Add(roster.Before(dis, discipline_d[1], discipline_d[4]));

            roster.Add(roster.NoOverlap(discipline_d));
            // desciplien  for not renewable resources
            IIntVar[] height_t = new IIntVar[T];
            for (int t = 0; t < T; t++)
            {
                height_t[t] = roster.IntVar(0, 1);
            }

            INumToNumSegmentFunction piecewise = roster.NumToNumSegmentFunction(new double[] { 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11 },
                                                                                new double[] { 10, 0, 10, 1, 10, 2, 10, 3, 10, 4, 10, 5, 10, 6, 10, 7, 10, 8, 10, 9, 10, 10, 10, 11 });



            INumExpr rc = roster.NumExpr();

            for (int d = 0; d < D; d++)
            {
                rc = roster.Sum(rc, roster.StartEval(discipline_d[d], piecewise, 0));
            }


            for (int t = 0; t < T; t++)
            {
            }

            IIntervalVar[] disciplineNR_d = new IIntervalVar[D];

            for (int d = 0; d < D; d++)
            {
                disciplineNR_d[d]           = roster.IntervalVar();
                disciplineNR_d[d].EndMax    = T;
                disciplineNR_d[d].EndMin    = T;
                disciplineNR_d[d].LengthMax = T;
                disciplineNR_d[d].LengthMin = T;
                disciplineNR_d[d].SizeMax   = T;
                disciplineNR_d[d].SizeMin   = T;
                disciplineNR_d[d].StartMax  = T;
                disciplineNR_d[d].StartMin  = 0;
                disciplineNR_d[d].SetOptional();
                roster.IfThen(roster.PresenceOf(discipline_d[d]), roster.PresenceOf(disciplineNR_d[d]));
            }
            //roster.Add(roster.IfThen(roster.PresenceOf(discipline_d[4]), roster.And(roster.Le(roster.EndOf(discipline_d[4]), roster.StartOf(discipline_d[0])),roster.PresenceOf(discipline_d[0]))));
            //roster.Add(roster.StartBeforeEnd(discipline_d[4],discipline_d[0]));
            // hospital changes
            //ICumulFunctionExpr[] hospital

            //for (int d = 0; d < D; d++)
            //{
            //    roster.IfThen(roster.PresenceOf(disciplineNR_d[d]),);
            //}



            // hospital assignment
            IIntervalVar[][] Hospital_dh = new IIntervalVar[D][];
            for (int d = 0; d < D; d++)
            {
                Hospital_dh[d] = new IIntervalVar[H];
                for (int h = 0; h < H; h++)
                {
                    Hospital_dh[d][h]           = roster.IntervalVar();
                    Hospital_dh[d][h].EndMax    = T;
                    Hospital_dh[d][h].EndMin    = dur[d];
                    Hospital_dh[d][h].LengthMax = dur[d];
                    Hospital_dh[d][h].LengthMin = dur[d];
                    Hospital_dh[d][h].SizeMax   = dur[d];
                    Hospital_dh[d][h].SizeMin   = dur[d];
                    Hospital_dh[d][h].StartMax  = T;
                    Hospital_dh[d][h].StartMin  = 0;

                    Hospital_dh[d][h].SetOptional();
                    if (h == 0 && (d != 4))
                    {
                        Hospital_dh[d][h].SetAbsent();
                    }
                    if (h == 1 && (d == 4))
                    {
                        Hospital_dh[d][h].SetAbsent();
                    }
                    if (h == 2 && (d == 4))
                    {
                        Hospital_dh[d][h].SetAbsent();
                    }
                }
                roster.Add(roster.Alternative(discipline_d[d], Hospital_dh[d]));
            }

            IIntervalVar[] disHospSetUp_dh = new IIntervalVar[D * H];
            int[]          type            = new int[D * H];
            for (int dh = 0; dh < D * H; dh++)
            {
                int dIndex = dh % D;
                int hIndex = dh / D;
                disHospSetUp_dh[dh] = roster.IntervalVar("DsiHosp" + "[" + dIndex + "][" + hIndex + "]");
                type[dh]            = hIndex;
                disHospSetUp_dh[dh].SetOptional();
                disHospSetUp_dh[dh] = Hospital_dh[dIndex][hIndex];
            }
            // changes
            IIntervalSequenceVar cc = roster.IntervalSequenceVar(disHospSetUp_dh, type);

            roster.NoOverlap(cc);
            IIntVar[][] change_dD = new IIntVar[D][];
            for (int d = 0; d < D; d++)
            {
                change_dD[d] = new IIntVar[D];
                for (int dd = 0; dd < D; dd++)
                {
                    change_dD[d][dd] = roster.IntVar(0, 1, "change_dD[" + d + "][" + dd + "]");
                }
            }
            IIntVar[] change_d = new IIntVar[D];
            for (int d = 0; d < D; d++)
            {
                change_d[d] = roster.IntVar(0, 1, "change_d[" + d + "]");
            }
            for (int dh = 0; dh < D * H; dh++)
            {
                int      dIndex = dh % D;
                int      hIndex = dh / D;
                IIntExpr chngD  = roster.IntExpr();
                chngD = roster.Sum(chngD, change_d[dIndex]);
                roster.Add(roster.IfThen(roster.And(roster.PresenceOf(disHospSetUp_dh[dh]), roster.Neq(roster.TypeOfNext(cc, disHospSetUp_dh[dh], hIndex, hIndex), hIndex)), roster.Eq(chngD, 1)));
                for (int ddh = 0; ddh < D * H; ddh++)
                {
                    int ddIndex = ddh % D;
                    int hhIndex = ddh / D;
                    if (hhIndex == hIndex || dIndex == ddIndex)
                    {
                        continue;
                    }
                }
            }



            //IIntVar[][] y_dD = new IIntVar[D][];
            //for (int d = 0; d < D; d++)
            //{
            //    y_dD[d] = new IIntVar[D];
            //    for (int dd= 0; dd < D; dd++)
            //    {
            //        y_dD[d][dd] = roster.IntVar(0,1);
            //        if (d == dd)
            //        {
            //            y_dD[d][dd] = roster.IntVar(0, 0);
            //        }
            //    }
            //}
            //for (int d = 0; d < D; d++)
            //{
            //    for (int dd = 0; dd < D; dd++)
            //    {
            //        if (d != dd)
            //        {
            //            for (int h = 0; h < H; h++)
            //            {
            //                for (int hh = 0; hh < H; hh++)
            //                {
            //                    if (d != dd && h != hh && true)
            //                    {
            //                        IIntExpr yyy = roster.IntExpr();
            //                        yyy = roster.Sum(yyy,roster.Prod(T,y_dD[d][dd]));
            //                        yyy = roster.Sum(yyy, roster.Prod(1, roster.EndOf(Hospital_dh[dd][hh])));
            //                        yyy = roster.Sum(yyy, roster.Prod(-1, roster.StartOf(Hospital_dh[d][h])));
            //                        roster.Add( roster.IfThen(roster.And(roster.PresenceOf(Hospital_dh[d][h]), roster.PresenceOf(Hospital_dh[dd][hh])), roster.AddGe(yyy, 0)));
            //                    }
            //                }
            //            }
            //        }
            //    }
            //}
            //for (int d = 0; d < D; d++)
            //{
            //    for (int dd = 0; dd < D; dd++)
            //    {
            //        if (d == dd)
            //        {
            //            continue;
            //        }
            //        IIntExpr change = roster.IntExpr();
            //        change = roster.Sum(change, change_dD[dd][d]);
            //        change = roster.Sum(change, roster.Prod(-1, y_dD[dd][d]));
            //        for (int ddd = 0; ddd < D; ddd++)
            //        {
            //            if (ddd == d || ddd == dd)
            //            {
            //                continue;
            //            }
            //            change = roster.Sum(change, change_dD[dd][ddd]);
            //        }
            //        roster.Add(roster.IfThen(roster.And(roster.PresenceOf(discipline_d[d]), roster.PresenceOf(discipline_d[dd])), roster.AddEq(change, 0)));


            //    }

            //}

            // all group assignment
            IIntExpr allPossibleCourses = roster.IntExpr();

            for (int d = 0; d < D; d++)
            {
                allPossibleCourses = roster.Sum(allPossibleCourses, roster.Prod(cc_d[d], roster.PresenceOf(discipline_d[d])));
            }
            roster.AddEq(allPossibleCourses, ALLK);

            // group assignment
            for (int g = 0; g < G; g++)
            {
                IIntExpr groupedCours_g = roster.IntExpr();
                for (int d = 0; d < D; d++)
                {
                    if (indexg_d[d] == g)
                    {
                        groupedCours_g = roster.Sum(groupedCours_g, roster.Prod(cc_d[d], roster.PresenceOf(discipline_d[d])));
                    }
                }
                roster.AddGe(groupedCours_g, k_g[g]);
            }


            // stay in one hospital



            // objective function
            INumExpr objExp = roster.NumExpr();

            // discipline desire
            for (int d = 0; d < D; d++)
            {
                objExp = roster.Sum(objExp, roster.Prod(prf_D[d], roster.PresenceOf(discipline_d[d])));
                for (int dd = 0; dd < D; dd++)
                {
                    objExp = roster.Sum(objExp, roster.Prod(-1, change_d[d]));
                }
            }
            objExp = roster.Sum(objExp, rc);
            IIntExpr makespan = roster.IntExpr();

            for (int d = 0; d < D; d++)
            {
                makespan = roster.Max(makespan, roster.EndOf(discipline_d[d]));
            }

            IIntVar  wait      = roster.IntVar(0, T);
            IIntExpr waitConst = roster.IntExpr();

            waitConst = roster.Sum(waitConst, wait);
            waitConst = roster.Sum(waitConst, roster.Prod(-1, makespan));
            for (int d = 0; d < D; d++)
            {
                waitConst = roster.Sum(waitConst, roster.Prod(dur[d], roster.PresenceOf(discipline_d[d])));
            }
            roster.AddEq(waitConst, 0);
            roster.AddMaximize(objExp);

            roster.ExportModel("Roster.cpo");
            roster.SetParameter(CP.IntParam.TimeMode, CP.ParameterValues.ElapsedTime);
            roster.SetParameter(CP.IntParam.LogVerbosity, CP.ParameterValues.Quiet);
            roster.SetParameter(CP.IntParam.SolutionLimit, 10);


            // solve it now
            if (roster.Solve())
            {
                Console.WriteLine("this is the cost of the CP column {0}", roster.ObjValue);
                for (int d = 0; d < D; d++)
                {
                    if (roster.IsPresent(discipline_d[d]))
                    {
                        Console.WriteLine("Discipline {0} with CC {1} and Dur {2} and Prf {3} started at time {4} and finished at time {5}", d, cc_d[d], dur[d], prf_D[d], roster.GetStart(discipline_d[d]), roster.GetEnd(discipline_d[d]));
                    }
                }

                for (int d = 0; d < D; d++)
                {
                    for (int h = 0; h < H; h++)
                    {
                        if (roster.IsPresent(Hospital_dh[d][h]))
                        {
                            Console.WriteLine("Discipline {0} with CC {1} and Dur {2} and Prf {3} started at time {4} and finished at time {5} at Hospitail {6}", d, cc_d[d], dur[d], prf_D[d], roster.GetStart(Hospital_dh[d][h]), roster.GetEnd(Hospital_dh[d][h]), h);
                        }
                    }
                }
                for (int d = 0; d < D * H; d++)
                {
                    int dIndex = d % D;
                    int hIndex = d / D;
                    if (roster.IsPresent(disHospSetUp_dh[d]))
                    {
                        Console.WriteLine("discpline " + dIndex + " in hospital " + hIndex);
                    }
                }

                for (int d = 0; d < D; d++)
                {
                    if (roster.GetValue(change_d[d]) > 0.5)
                    {
                        Console.WriteLine("We have change for discipline {0}", d);
                    }
                    for (int dd = 0; dd < D; dd++)
                    {
                        if (d == dd)
                        {
                            continue;
                        }
                    }
                }

                Console.WriteLine("=========================================");
                Console.WriteLine("Wainting time {0}", roster.GetValue(wait));
            }
        }