Пример #1
0
        /// <summary>
        /// Algorytm schrage bez podziału, korzystający z kolejek priorytetowych
        /// Wylicza permutacje zadań na maszynie
        /// </summary>
        /// <returns>Maksymalny czas dostarczenia zadań</returns>
        public int Schrage()
        {
            int t = 0;                           // chwila czasowa
            int k = 0;                           // pozycja w permutacji pi
            var G = new MaxPriorityQueue();      // zbiór zadań gotowych do realizacji
            var N = new MinPriorityQueue(tasks); // zbiór zadań nieuszeregowanych

            //Szukane
            var cmax = 0;           // maksymalny z terminów dostarczenia zadań
            var pi   = new Task[n]; // permutacja wykonania zadań na maszynie


            while (!G.IsEmpty() || !N.IsEmpty())
            {
                Task taskReady;                         // zadanie gotowe do wykonania
                while (!N.IsEmpty() && N.Peek().r <= t) // dopóki są jakieś nieuszeregowane zadania i jest dostępne zadanie w chwili czasowej t
                {
                    taskReady = N.Poll();               // weź zadanie z najmniejszym możliwym r, usuń je ze zbioru zadań nieuszeregowanych
                    G.Add(taskReady);                   // dodaj to zadanie do zbioru zadań uszeregowanych
                }

                if (G.IsEmpty())    // jeśli nie ma żadnych zadań gotowych do realizacji
                {
                    t = N.Peek().r; // przesuń chwilę czasową do najmniejszego dostępnego terminu dostępności zadania ze zbioru zadań nieuszeregowanych
                    continue;
                }
                // jeżeli są jakieś zadania gotowe do realizacji
                taskReady = G.Poll();                        // weź zadanie z największym możliwym q, usuń je ze zbioru zadań gotowych do realizacji i "wstaw je na maszynę" - do permutacji pi
                pi[k]     = taskReady;                       // dodaj to zadanie do permutacji zadań wykonywanych na maszynie
                k        += 1;                               // zwiększ pozycję w permutacji
                t        += taskReady.p;                     // zwiększ chwilę czasową o czas wykonania zadania - p
                cmax      = Math.Max(cmax, t + taskReady.q); // oblicz najpóźniejszy moment dostarczenia
            }
            return(cmax);
        }
Пример #2
0
        /// <summary>
        /// Algorytm schrage z podziałem korzystający z kolejek priorytetowych
        /// Nie wylicza permutacji zadań na maszynie
        /// </summary>
        /// <returns>Maksymalny termin dostarczenia zadań</returns>
        public int SchrageWithDivision()
        {
            var  t = 0;                           // chwila czasowa
            var  G = new MaxPriorityQueue();      // kolejka zadań gotowych do wykonania
            var  N = new MinPriorityQueue(tasks); // kolejka zadań nieuszeregowanych
            Task taskReady;                       // zadanie gotowe do wykonania
            Task taskOnMachine = new Task {
                q = int.MaxValue
            };                                             // aktualnie wykonywane zadanie na maszynie

            //szukane
            var cmax = 0; // maksymalny termin dostarczenia


            while (!G.IsEmpty() || !N.IsEmpty())
            {
                while (!N.IsEmpty() && N.Peek().r <= t)
                {
                    taskReady = N.Poll(); // zadanie gotowe do wykonania
                    G.Add(taskReady);     // dodaj to zadanie do kolejki zadań gotowych do wykonania

                    //wprowadzenie podziału
                    //jeśli czas dostarczenia zadania gotowego do realizacji jest dłuższy
                    //od zadania aktualnie znajdującego się na maszynie
                    if (taskReady.q > taskOnMachine.q)
                    {
                        taskOnMachine.p = t - taskReady.r; // wykonuj do zadanie do momentu, gdy następne zadanie jest gotowe
                        t = taskReady.r;
                        //  jeżeli do momentu aż zadanie będzie gotowe poprzednie się nie skończy
                        // to dodaj to zadanie do kolejki zadań gotowych do realizacji
                        // z p -> czasem wykonania, krótszym o tyle ile się zdążyło wykonać
                        if (taskOnMachine.p > 0)
                        {
                            G.Add(taskOnMachine);
                        }
                    }
                }

                if (G.IsEmpty())
                {
                    t = N.Peek().r;
                }
                else
                {
                    taskReady     = G.Poll();
                    taskOnMachine = taskReady;
                    t             = t + taskReady.p;
                    cmax          = Math.Max(cmax, t + taskReady.q);
                }
            }
            return(cmax);
        }