LUNDS TEKNISKA HÖGSKOLA 1(3) Institutionen för datavetenskap Tentamen, EDA501 Programmering M L TM W K V 2010 04 13, 8.00 13.00 Anvisningar: Denna tentamen består av 4 uppgifter. Preliminärt ger uppgifterna 11 + 13 + 7 + 9 = 40 poäng. Tillåtna hjälpmedel: Java-snabbreferens. Lösningsförslag kommer att finnas på kursens hemsida senast dagen efter tentamen. När rättningen är klar meddelas detta på kursens hemsida. Tentamensvillkor: Om du tenterar utan att vara tentamensberättigad annulleras din skrivning. För att undvika att någon skrivning annulleras av misstag anslås vilka som, enligt institutionens noteringar, tenterat utan att vara tentamensberättigade. Namnen anslås (lätt krypterade) senast en vecka efter tentamen på kursens hemsida. Felaktigheter i institutionens noteringar kan därefter påtalas fram till nästa tentamenstillfälle då resterande skrivningar annulleras. Uppgift 1 4 handlar om schemaläggning av maskiner. Vi har följande förutsättningar: Vi har m identiska maskiner. Vi har n jobb att utföra. Tiden för att utföra jobb nummer i är t i. En maskin kan bara göra ett jobb i taget. Ett jobb kan inte delas mellan olika maskiner. Ett jobb som en maskin börjat utföra görs färdigt utan avbrott. Vårt problem är att schemalägga de n jobben på de m maskinerna på ett sådant sätt att allt kan bli klart på så kort tid som möjligt. Tyvärr känner man inte till någon effektiv algoritm som löser detta problem. (Man kan i och för sig prova alla möjligheter, men det tar alldeles för lång tid om man har många jobb.) Istället ska vi använda en algoritm som ger oss en nästan lika bra lösning som den optimala men som snabbare löser problemet. Om vi antar att de n jobben är sorterade efter avtagande tidsåtgång kan vi göra så här: för varje jobb fördela jobbet till den maskin som har minst schemalagd tid Denna algoritm kallas LPT-algoritmen eller Longest Processing Time first. Exempel: Om vi har 3 maskiner M 1..M 3 och 7 jobb j 1..j 7 med tidsåtgång 16, 14, 6, 5, 4, 3, 2 ska jobben fördelas enligt följande: M 1 16 ( j 1 ) M 2 M 3 14 ( j ) 2 3 ( j ) 6 6 ( j 3 ) 5 ( j 4 ) 4 ( j 5 ) 2 ( j 7 ) Den totala tidsåtgången för att avsluta alla jobb är 17 minuter.
2(3) 1. Jobben och maskinerna beskrivs av följande klasser: Job (OBS! Ska ej implementeras.) /** Skapar ett jobb med med nummer nbr som tar tiden time minuter. */ Job(int nbr, int time) ; /** Tar reda på jobbets nummer. */ int getnbr(); /** Tar reda på hur lång tid (i minuter) jobbet tar att utföra. */ int gettime(); Machine /** Skapar en maskin med nummer nbr. */ Machine(int nbr); /** Tar reda på hur många minuter maskinen är schemalagd. */ int getscheduledtime(); /** Tar bort alla jobb från maskinen och nollställer schemalagd tid. */ void reset(); /** Schemalägger jobbet job till maskinen. */ void addjob(job job); /** Returnerar en sträng som representerar maskinen. Exempel: Om maskinens nr är 3 och den har schemalagts med jobben med nr 3 4 5 7 som tillsammans skulle ta 17 minuter att slutföra ska följande sträng returneras: "Maskin nr 3 har tilldelats jobb nr: 3 4 5 7 och är klar efter 17 min." */ String tostring(); Implementera klassen Machine. 2. Man måste hålla reda på alla maskinerna under schemaläggningen. Detta görs i klassen MachineList: MachineList /** Skapar nbrmachines st maskiner att fördela jobb på. Maskinerna ska numreras 1, 2, 3,... */ MachineList(int nbrmachines); /** Nollställer maskinerna och schemalägger jobben i vektorn jobs på de olika maskinerna enligt LPT-algoritmen. Jobben förutsätts vara sorterade efter avtagande tidsåtgång. */ void schedule(job[] jobs); /** Skriver ut information om alla maskiner. För varje maskin ska en rad med en sträng som representerar maskinen skrivas ut. */ void print(); Implementera klassen MachineList. Ledning och anvisningar: Förutom metoderna i specifikationen ska följande privata hjälpmetod läggas till i klassen: /** Returnerar den maskin som har minst schemalagd tid. */ Machine findnexttobeready();
3(3) 3. Skriv en klass med en main-metod där antal maskiner, antal jobb och jobbens tidsåtgång läses in varefter jobben schemaläggs på de olika maskinerna och resultatet skrivs ut. Du får anta att användaren av programmet matar in jobben sorterade efter avtagande tidsåtgång. 4. I uppgift 3 förutsätts jobben vara sorterade efter avtagande tidsåtgång. Om så ej är fallet måste jobben sorteras. a) Implementera metoden sort i klassen JobHandler som sorterar jobben i vektorn jobs efter avtagande tidsåtgång. public class JobHandler { public static void sort(job[] jobs) {... Följande algoritm ska användas för att sortera: för varje position pos i vektorn (utom den sista) sök upp jobbet med störst tidsåtgång bland de ännu ej sorterade jobben (dvs. de jobb som finns på position pos och framåt i vektorn) byt plats på jobbet på plats pos och jobbet med störst tidsåtgång b) Vilken/vilka av metod-anropen nedan är korrekta? Motivera ditt svar. 1. JobHandler.sort(jobs); 2. new JobHandler().sort(jobs); c) Lägg till en statisk metod i klassen JobHandler som undersöker om en vektor av typen Job[] är sorterad efter avtagande tidsåtgång. Metoden ska returnera true om vektorn är sorterad, annars false.
LUNDS TEKNISKA HÖGSKOLA 1(3) Institutionen för datavetenskap Lösningsförslag till tentamen i EDA501 Programmering 2010 04 13 1. public class Machine { private int nbr; private int scheduledtime; private ArrayList<Job> jobs; // maskinens nummer // maskinens schemalagda tid // de jobb som givits till maskinen /** Skapar en maskin med nummer nbr. */ public Machine(int nbr) { this.nbr = nbr; scheduledtime = 0; jobs = new ArrayList<Job>(); /** Tar reda på hur många minuter maskinen är schemalagd. */ public int getscheduledtime() { return scheduledtime; /** Tar bort alla jobb från maskinen och nollställer schemalagd tid. */ public void reset() { scheduledtime = 0; jobs.clear(); /** Schemalägger jobbet job till maskinen. */ public void addjob(job job) { scheduledtime = scheduledtime + job.gettime(); jobs.add(job); /** Returnerar en sträng som representerar maskinen. Exempel: Om maskinens nr är 3 och den har schemalagts med jobben med nr 3 4 5 7 som tillsammans skulle ta 17 minuter att slutföra ska följande sträng returneras: "Maskin nr 3 har tilldelats jobb nr: 3 4 5 7 och är klar efter 17 min." */ public String tostring() { StringBuilder sb = new StringBuilder(); sb.append("maskin nr " ); sb.append(nbr); sb.append(" har tilldelats jobb nr: "); for (int i = 0; i < jobs.size(); i++) { sb.append(jobs.get(i).getnbr()); sb.append( ); sb.append("och är klar efter "); sb.append(scheduledtime); sb.append(" min."); return sb.tostring();
2(3) 2. public class MachineList { private Machine[] machines; /** Skapar nbrmachines st maskiner att fördela jobb på. Maskinerna ska numreras 1, 2, 3,... */ public MachineList(int nbrmachines) { machines = new Machine[nbrMachines]; for (int i = 0; i < nbrmachines; i++) { machines[i] = new Machine(i + 1); /* Returnerar den maskin som har minst schemalagd tid. */ private Machine findnexttobeready() { Machine min = machines[0]; for (int i = 1; i < machines.length; i++) { if (machines[i].getscheduledtime() < min.getscheduledtime()) { min = machines[i]; return min; /** Nollställer maskinerna och schemalägger jobben i vektorn jobs på de olika maskinerna enligt LPT-algoritmen. Jobben förutsätts vara sorterade efter avtagande tidsåtgång. */ public void schedule(job[] jobs) { for (int i = 0; i < machines.length; i++) { machines[i].reset(); for (int i = 0; i < jobs.length; i++) { Machine m = findnexttobeready(); m.addjob(jobs[i]); /** Skriver ut information om alla maskiner. För varje maskin ska en rad med en sträng som representerar maskinen skrivas ut. **/ public void print() { for (int i = 0; i < machines.length; i++) { System.out.println(machines[i]); // Alternativ: System.out.println(machines[i].toString());
3(3) 3. public class Main { public static void main(string[] args) { Scanner scan = new Scanner(System.in); System.out.println("Antal maskiner:"); int nbrmachines = scan.nextint(); System.out.println("Antal jobb:"); int nbrjobs = scan.nextint(); Job[] jobs = new Job[nbrJobs]; System.out.println("Jobbens tidsåtång (sorterade i avtagande tidsåtgång):"); for (int i = 0; i < nbrjobs; i++) { jobs[i] = new Job(i + 1, scan.nextint()); MachineList m = new MachineList(nbrMachines); m.schedule(jobs); m.print(); 4. a) /** Sorterar vektorn jobs efter avtagande tidsåtgång. */ public static void sort(job[] jobs) { for (int pos = 0; pos < jobs.length - 1; pos++) { int maxtime = Integer.MIN_VALUE; int maxindex = -1; for (int k = pos; k < jobs.length; k++) { if (jobs[k].gettime() > maxtime) { maxtime = jobs[k].gettime(); maxindex = k; Job temp = jobs[maxindex]; jobs[maxindex] = jobs[pos]; jobs[pos] = temp; b) I det första fallet använder man klassnamnet (JobHandler) för att anropa den statiska metoden. I det andra fallet skapar man ett JobHandler-objekt och anropar metoden på vanligt sätt. Båda sätten är korrekta för statiska metoder, men man brukar föredra att använda den första varianten. c) /** Undersöker om vektorn jobs är sorterad efter avtagande tidsåtgång. */ public static boolean issorted(job[] jobs) { for (int i = 1; i < jobs.length; i++) { if (jobs[i - 1].getTime() < jobs[i].gettime()) { return false; return true;