예제 #1
0
        //Final Evaluation
        public void FinalEvaluation(Node nodeToEvaluate, List <Condition> conditions, bool trackViolations)
        {
            for (int iConditions = 0; iConditions != numberOfConditions; iConditions++)
            {
                int       lastPosition = numTimeUnits - 1;
                Condition curCondition = conditions[iConditions];
                if (total[iConditions] > curCondition.max_total)
                {
                    int cost = curCondition.cost_max_total;
                    if (cost > 0)
                    {
                        int val = total[iConditions] - curCondition.max_total;
                        int pen = (cost * val);
                        curCondition.penalty_max_total += pen;
                        // create and add violation
                        Violation violation = new Violation(nodeToEvaluate.NurseId, nodeToEvaluate.Index, "MAX_TOTAL", val, curCondition, lastPosition, pen);
                        if (trackViolations)
                        {
                            nodeToEvaluate.Violations.Add(violation.ToString());
                        }
                        int day = nrOfDaysInPeriod - 1;//?same value every time?
                        this.constraintViolationsOnDay[day] += pen;
                        this.penalty += pen;
                    }
                }
                if (total[iConditions] < curCondition.min_total)
                {
                    int cost = curCondition.cost_min_total;
                    if (cost > 0)
                    {
                        int val = curCondition.min_total - total[iConditions];
                        int pen = (cost * val);
                        curCondition.penalty_min_total += pen;
                        // create and add violation
                        Violation violation = new Violation(nodeToEvaluate.NurseId, nodeToEvaluate.Index, "MIN_TOTAL", val, curCondition, lastPosition, pen);
                        if (trackViolations)
                        {
                            nodeToEvaluate.Violations.Add(violation.ToString());
                        }
                        int day = nrOfDaysInPeriod - 1;
                        this.constraintViolationsOnDay[day] += pen;
                        this.penalty += pen;
                    }
                }
                if (curCondition.future_nr != Condition.Undefined)
                {
                    if (lastNr[iConditions] == curCondition.future_nr - 1)
                    {
                        consecutive[iConditions] += 1;
                    }
                }
                if (shiftPatternEvent[iConditions])
                {
                    if (consecutive[iConditions] > curCondition.max_consecutive)
                    {
                        int cost = curCondition.cost_max_consecutive;
                        if (cost > 0)
                        {
                            int val = consecutive[iConditions] - curCondition.max_consecutive;
                            int pen = (cost * val);
                            curCondition.penalty_max_consecutive += pen;
                            // create and add violation
                            Violation violation = new Violation(nodeToEvaluate.NurseId, nodeToEvaluate.Index, "MAX_CONSECUTIVE", val, curCondition, lastPosition, pen);
                            if (trackViolations)
                            {
                                nodeToEvaluate.Violations.Add(violation.ToString());
                            }
                            int day = nrOfDaysInPeriod - 1;
                            this.constraintViolationsOnDay[day] += pen;
                            this.penalty += pen;
                        }
                    }
                }
                if (lastNr[iConditions] != Condition.Undefined && consecutive[iConditions] < curCondition.min_consecutive)
                {
                    int cost = curCondition.cost_min_consecutive;
                    if (cost > 0)
                    {
                        int val = curCondition.min_consecutive - consecutive[iConditions];
                        int pen = (cost * val);
                        curCondition.penalty_min_consecutive += pen;
                        // create and add violation
                        Violation violation = new Violation(nodeToEvaluate.NurseId, nodeToEvaluate.Index, "MIN_CONSECUTIVE", val, curCondition, lastPosition, pen);
                        if (trackViolations)
                        {
                            nodeToEvaluate.Violations.Add(violation.ToString());
                        }
                        int day = nrOfDaysInPeriod - 1;
                        this.constraintViolationsOnDay[day] += pen;
                        this.penalty += pen;
                    }
                }
                // max_between
                if (lastNr[iConditions] != Condition.Undefined && curCondition.future_nr != Condition.Undefined)
                {
                    int cost = curCondition.cost_max_between;

                    if (cost > 0)
                    {
                        int val = curCondition.future_nr - lastNr[iConditions] - 1;

                        if (val > curCondition.max_between)
                        {
                            val = val - curCondition.max_between;

                            int pen = (cost * val);
                            curCondition.penalty_max_between += pen;

                            // create and add violation
                            Violation violation = new Violation(nodeToEvaluate.NurseId, nodeToEvaluate.Index, "MAX_BETWEEN", val, curCondition, lastPosition, pen);
                            if (trackViolations)
                            {
                                nodeToEvaluate.Violations.Add(violation.ToString());
                            }
                            int day = nrOfDaysInPeriod - 1;
                            this.constraintViolationsOnDay[day] += pen;
                            this.penalty += pen;
                        }
                    }
                }
                // min_between
                if (lastNr[iConditions] != Condition.Undefined && curCondition.future_nr != Condition.Undefined)
                {
                    int cost = curCondition.cost_min_between;

                    if (cost > 0)
                    {
                        int val = curCondition.future_nr - lastNr[iConditions] - 1;

                        // if zero then no between!
                        if (val > 0 && val < curCondition.min_between)
                        {
                            val = curCondition.min_between - val;

                            int pen = (cost * val);
                            curCondition.penalty_min_between += pen;

                            // create and add violation
                            Violation violation = new Violation(nodeToEvaluate.NurseId, nodeToEvaluate.Index, "MIN_BETWEEN", val, curCondition, lastPosition, pen);
                            if (trackViolations)
                            {
                                nodeToEvaluate.Violations.Add(violation.ToString());
                            }
                            int day = nrOfDaysInPeriod - 1;
                            this.constraintViolationsOnDay[day] += pen;
                            this.penalty += pen;
                        }
                    }
                }
                for (int iNum = 0; iNum != curCondition.max_pert_nr.Length; iNum++)
                {
                    if (pertNr[iConditions][iNum] != 0 && pertNr[iConditions][iNum] > curCondition.max_pert_nr[iNum])
                    {
                        int cost = curCondition.cost_max_pert_nr[iNum];

                        if (cost > 0)
                        {
                            int val = pertNr[iConditions][iNum] - curCondition.max_pert_nr[iNum];
                            int pen = (cost * val);
                            curCondition.penalty_max_pert_nr += pen;

                            // create and add violation
                            Violation violation = new Violation(nodeToEvaluate.NurseId, nodeToEvaluate.Index, "MAX_PERT", val, curCondition, iNum, pen);
                            if (trackViolations)
                            {
                                nodeToEvaluate.Violations.Add(violation.ToString());
                            }
                            int day = nrOfDaysInPeriod - 1;
                            this.constraintViolationsOnDay[day] += pen;
                            this.penalty += pen;
                        }
                    }

                    if (pertNr[iConditions][iNum] != 0 && pertNr[iConditions][iNum] < curCondition.min_pert_nr[iNum])
                    {
                        int cost = curCondition.cost_min_pert_nr[iNum];

                        if (cost > 0)
                        {
                            int val = curCondition.min_pert_nr[iNum] - pertNr[iConditions][iNum];
                            int pen = (cost * val);
                            curCondition.penalty_min_pert_nr += pen;

                            // create and add violation
                            Violation violation = new Violation(nodeToEvaluate.NurseId, nodeToEvaluate.Index, "MIN_PERT", val, curCondition, iNum, pen);
                            if (trackViolations)
                            {
                                nodeToEvaluate.Violations.Add(violation.ToString());
                            }
                            int day = nrOfDaysInPeriod - 1;
                            this.constraintViolationsOnDay[day] += pen;
                            this.penalty += pen;
                        }
                    }
                }
                nodeToEvaluate.Penalty += (this.penalty - this.origPenalty);
            }
        }
예제 #2
0
        //Intermediate Evaluation
        public void IntermediateEvaluation(Node nodeToEvaluate, List <Condition> conditions, bool trackViolations)
        {
            //Swap from Matrix data structure to simple array data structure
            bool[] rooster = new bool[numTimeUnits];

            if (nodeToEvaluate.ShiftPatternArray != null)
            {
                rooster = nodeToEvaluate.ShiftPatternArray;
            }
            else
            {
                MatrixToArrayConverter(nodeToEvaluate.ShiftPatternMatrix, rooster);
            }

            for (int iConditions = 0; iConditions != numberOfConditions; iConditions++)
            {
                for (int iRooster = 0; iRooster != rooster.Length; iRooster++)
                {
                    if (rooster[iRooster])
                    {
                        int nr = conditions[iConditions].GetNumbering()[iRooster]; //Returns the numbering of the iRooster day associated to the current condition
                        if (nr != Condition.Undefined)
                        {
                            shiftPatternEvent[iConditions] = true;
                            total[iConditions]             = total[iConditions] + 1;
                            if (nr == lastNr[iConditions] + 1)
                            {
                                consecutive[iConditions] += 1;
                            }
                            else if (nr > lastNr[iConditions] + 1)
                            {
                                // 4 CASES
                                Condition curCondition = conditions[iConditions];
                                if (consecutive[iConditions] > 0 && consecutive[iConditions] < curCondition.min_consecutive)
                                {
                                    int cost = curCondition.cost_min_consecutive;
                                    if (cost > 0)
                                    {
                                        int val = curCondition.min_consecutive - consecutive[iConditions];
                                        int pen = (cost * val);
                                        curCondition.penalty_min_consecutive += pen;
                                        Violation violation = new Violation(nodeToEvaluate.NurseId, nodeToEvaluate.Index, "MIN_CONSECUTIVE", val, curCondition, lastNrPos[iConditions], pen);
                                        if (trackViolations)
                                        {
                                            nodeToEvaluate.Violations.Add(violation.ToString());
                                        }
                                        int day = iRooster / nrShiftTypes;
                                        constraintViolationsOnDay[day] += pen;
                                        penalty += pen;
                                    }
                                }
                                if (consecutive[iConditions] > curCondition.max_consecutive)
                                {
                                    int cost = curCondition.cost_max_consecutive;
                                    if (cost > 0)
                                    {
                                        int val = consecutive[iConditions] - curCondition.max_consecutive;
                                        int pen = (cost * val);
                                        curCondition.penalty_max_consecutive += pen;
                                        // create and add violation
                                        Violation violation = new Violation(nodeToEvaluate.NurseId, nodeToEvaluate.Index, "MAX_CONSECUTIVE", val, curCondition, lastNrPos[iConditions], pen);
                                        if (trackViolations)
                                        {
                                            nodeToEvaluate.Violations.Add(violation.ToString());
                                        }
                                        int day = iRooster / nrShiftTypes;
                                        this.constraintViolationsOnDay[day] += pen;
                                        this.penalty += pen;
                                    }
                                }
                                if (nr - lastNr[iConditions] - 1 < curCondition.min_between)
                                {
                                    int cost = curCondition.cost_min_between;
                                    if (cost > 0)
                                    {
                                        int val = curCondition.min_between - (nr - lastNr[iConditions] - 1);
                                        int pen = (cost * val);
                                        curCondition.penalty_min_between += pen;
                                        // create and add violation
                                        Violation violation = new Violation(nodeToEvaluate.NurseId, nodeToEvaluate.Index, "MIN_BETWEEN", val, curCondition, lastNrPos[iConditions], pen);
                                        if (trackViolations)
                                        {
                                            nodeToEvaluate.Violations.Add(violation.ToString());
                                        }
                                        int day = iRooster / nrShiftTypes;
                                        this.constraintViolationsOnDay[day] += pen;
                                        this.penalty += pen;
                                    }
                                }
                                if (nr - lastNr[iConditions] - 1 > curCondition.max_between)
                                {
                                    int cost = curCondition.cost_max_between;
                                    if (cost > 0)
                                    {
                                        int val = (nr - lastNr[iConditions] - 1) - curCondition.max_between;
                                        int pen = (cost * val);
                                        curCondition.penalty_max_between += pen;
                                        Violation violation = new Violation(nodeToEvaluate.NurseId, nodeToEvaluate.Index, "MAX_BETWEEN", val, curCondition, iRooster, pen);
                                        if (trackViolations)
                                        {
                                            nodeToEvaluate.Violations.Add(violation.ToString());
                                        }
                                        int day = iRooster / nrShiftTypes;
                                        this.constraintViolationsOnDay[day] += pen;
                                        this.penalty += pen;
                                    }
                                }
                                consecutive[iConditions] = 1;
                            }
                            pertNr[iConditions][nr] += 1;
                            lastNr[iConditions]      = nr;
                            lastNrPos[iConditions]   = iRooster;
                        }
                    }
                }
            }
        }