Exemplo n.º 1
0
        /// <summary>
        /// ONLY works for MeanBasedCmax
        /// </summary>
        private static bool MoveAndInsertIsImprovement(Schedule ScheduleBeforeMove, Job MoveJob, double ESSv_withoutMachinePred, double Tailtimev_withoutMachinePred, Machine NewMachine, int NewPosIndex, double Currentfitness)
        {
            // note Cmax >= Sx + Px + Tx
            if (Settings.MLS_HF != "DetCmax")
            {
                throw new Exception("MoveAndInsertIsImprovement in NeighborhoodFunctions.cs ONLY works for DetCmax");
            }
            double Sv, Tv;

            if (NewPosIndex == 0)
            {
                Sv = ESSv_withoutMachinePred;
            }
            else
            {
                Job Mpred = NewMachine.AssignedJobs[NewPosIndex - 1];
                Sv = Math.Max(ESSv_withoutMachinePred, ScheduleBeforeMove.GetEarliestStart(Mpred) + Mpred.MeanProcessingTime);
            }
            if (NewPosIndex == NewMachine.AssignedJobs.Count - 1)
            {
                Tv = Tailtimev_withoutMachinePred;
            }
            else
            {
                Job Msucc = NewMachine.AssignedJobs[NewPosIndex]; // V has not been inserted yet, so this job will be its successor
                Tv = Math.Min(Tailtimev_withoutMachinePred, ScheduleBeforeMove.CalcTailTime(Msucc) + Msucc.MeanProcessingTime);
            }

            if (-(Sv + MoveJob.MeanProcessingTime + Tv) <= Currentfitness + 0.0000001)
            {
                //Console.WriteLine("Rejected by bound.. no improvement (no swapping needed)");
                return(false);
            }
            else
            {
                // Do it the hard way.
                Machine OldMachine  = ScheduleBeforeMove.AssignedMachine(MoveJob);
                int     OldPosition = ScheduleBeforeMove.GetIndexOnMachine(MoveJob);
                ScheduleBeforeMove.DeleteJobFromMachine(MoveJob);
                ScheduleBeforeMove.AssignJatIndex(MoveJob, NewMachine, NewPosIndex);
                double NewFitness = FitnessFunctions.MeanBasedCmax(ScheduleBeforeMove);

                if (NewFitness > Currentfitness)
                {
                    //improvement
                    return(true);
                }
                else
                {
                    //no improvement
                    //undo swap
                    //reset start times.
                    ScheduleBeforeMove.DeleteJobFromMachine(MoveJob);
                    ScheduleBeforeMove.AssignJatIndex(MoveJob, OldMachine, OldPosition);
                    ScheduleBeforeMove.EstimateCmax();
                    return(false);
                }
            }
        }
Exemplo n.º 2
0
        static private bool SwapJobPair(Job J1, Job J2, Machine M, Schedule Sched)
        {
            Console.WriteLine("S W A P   S T A R T I N G !");
            Console.WriteLine("Schedule BEFORE Swap:");
            Sched.Print();
            Console.WriteLine("Fitness BEFORE swap: {0}", FitnessFunctions.MeanBasedCmax(Sched));
            //The bug is that Arrayindex is not the correct position of the job.
            //Give each job a dictionary of all its transitive descendants. Check in almost O(1) if swap is feasible. (MUCH BETTER THAN BFS).
            int OldJ1Index = Sched.GetIndexOnMachine(J1);// Sched.MachineArcPointers[J1.ID].ArrayIndex;

            if (M.AssignedJobs[OldJ1Index] != J1)
            {
                throw new Exception("Indexing wrong. J1 index not pointing to J1");
            }
            int OldJ2Index = Sched.GetIndexOnMachine(J2);// Sched.MachineArcPointers[J2.ID].ArrayIndex;

            if (M.AssignedJobs[OldJ2Index] != J2)
            {
                throw new Exception("Indexing wrong. J2 index not pointing to J2");
            }
            int LeftIndex  = OldJ1Index;
            int RightIndex = OldJ2Index;

            if (OldJ2Index < OldJ1Index)
            {
                LeftIndex = OldJ2Index; RightIndex = OldJ1Index;
            }
            // check feasibility of the swap, Assuming an already feasible setup.
            for (int i = LeftIndex; i <= RightIndex - 1; i++)
            {
                for (int j = i + 1; j <= RightIndex; j++)
                {
                    // Between [J1 and J2] (inlusive) the arcs get reversed. Check all combos.
                    //Do they though? TODO BUG!
                    if (Sched.PrecedenceDAG.PrecPathExists(M.AssignedJobs[i], M.AssignedJobs[j]))
                    {
                        // Console.WriteLine("BUG?");
                        Console.WriteLine("Swap J{0},J{1} on M{2} denied due to cycle from J{3} to J{4}", J1.ID, J2.ID, M.MachineID, M.AssignedJobs[i].ID, M.AssignedJobs[j].ID);
                        return(false);
                    } // infeasible.
                }
            }
            Console.WriteLine("Swapping J{0}, J{1} on M{2}", J1.ID, J2.ID, M.MachineID);

            UNSAFE_SwapOnMachine(J1, J2, M, Sched);

            Console.WriteLine("Schedule AFTER Swap:");
            Sched.Print();
            Console.WriteLine("Fitness AFTER swap: {0}", FitnessFunctions.MeanBasedCmax(Sched));
            return(true);
        }