Informatika gyűjtemény

Egy szinttel feljebb Megoldás

2004050607080910

NézetNyomtat

1. megoldás: Mohó algoritmus (nem mindig jó)

A feladatokat (süteményeket) hossz (sütési idő) szerint csökkenően rendezzük, majd sorra vesszük, és mindig abba a sütőbe tesszük, ahol a minimális az eddigi össz-idő.

Ellenpélda

A "12 5 5 2 2 2 2 2 2 2 2 2 2" bemenetre a mohó algoritmus a
11 1: 5 2 2 2 2: 5 2 2 3: 2 2 2 2 2
megoldást adja, az optimális
10 1: 5 5 2: 2 2 2 2 2 3: 2 2 2 2 2
helyett.
A következő két (optimális megoldást adó) algoritmus alapötlete, hogy ha két sütő munkaidejét kiszámoltuk ($t_a, t_b$), akkor a harmadik sütő ideje $t_c = \sum t_i -t_a - t_b$, és a teljes munkaidő $ t = max (t_a, t_b, t_c) $.

2. megoldás: Rekurzió

Egy opt() függvényt írunk, ami paraméterül azt kapja, hogy hányadik feladatot akarjuk elvégezni, és a három sütőben eddig mennyi a betervezett sütések összideje. Az előző megjegyzés szerint a harmadik sütési idő számítható, de az érthetőség kedvéért azt is beleírjuk az algoritmusba. A feladat megoldását az opt(1,0,0,0) adja, ami azt jelenti, hogy az első feladat jön, és még semelyik sütőben nem sütöttünk.

 függvény opt(i,a,b,c)
    Ha i > n akkor 
        vissza( max(a,b,c) )
    különben
        ra := opt(i+1,a+t[i],b,c)
        rb := opt(i+1,a,b+t[i],c)
        rc := opt(i+1,a,b,c+t[i])   
        vissza( min(ra,rb,rc) )
    Elágazás vége
 függvény vége
Optimalizálás: c = t - a - b, illetve az "opt" értékei táblázatolhatók, és egyszerre elég két i indexre tárolni az értékeket.

3. megoldás: Okos táblázatolás

Jelentse lehet[j,k] azt, hogy a lehetséges a sütési feladatok olyan beosztása, hogy az első sütő j, a második pedig k ideig sütött. (Ekkor a harmadik sütő ideje l = összidő - j - k, és a munkaidő max(j,k,l).
Ha a lehet[] tömb értékeit kiszámoltuk, akkor az optimum egy kétdimenziós minimumkiválasztással határozható meg.

 lehet[] := hamis;lehet[0,0] := igaz; s := 0

 // megvalósítható ütemezések
 Ciklus i :=1-tól n-ig
    s := s + t[i]
    t := t[i]
    Ciklus j := 1200-tól 0-ig
    Ciklus k := 1200-tól 0-ig
        Ha j>=és lehet[j-t,k] akkor 
            lehet[j,k] := igaz 
        Elágazás vége
        Ha k>=és lehet[j,k-t] akkor 
            lehet[j,k] := igaz 
        Elágazás vége
    Ciklus vége
    Ciklus vége
 Ciklus vége    

 // minimumkiválasztás
 opt := 1200
 Ciklus j := 0-tól 1200-ig
 Ciklus k := 0-tól 1200-ig
    Ha lehet[j,k] akkor
        opt := min(opt, max(j,k,s-j-k))
    Elágazás vége
 Ciklus vége
 Ciklus vége

Kódok

Mezei Tamás (C#): cake.cs