Documente Academic
Documente Profesional
Documente Cultură
Laborator 4
Descriere: Metoda Greedy –2
1. Decriere formala
Un algoritm greedy construieste solutia pas cu pas. Initial, multimea candidatilor selectati este vida.
La fiecare pas, ıncercam sa adaugam la aceasta multime pe cel mai promitator candidat, conform
functiei de selectie. Daca, dupa o astfel de adaugare, multimea de candidati selectati nu mai este
fezabila, eliminam ultimul candidat adaugat;acesta nu va mai fi niciodata considerat. Daca, dupa
adaugare, multimea de candidati selectati este fezabila, ultimul candidat adaugat va ramane de
acum incolo ın ea. De fiecare data cand largim multimea candidatilor selectati, verificam daca
aceasta multime nu constituie o solutie posibila a problemei. Daca algoritmul greedy functioneaza
corect, prima solutie gasita va fi totodata o solutie optima a problemei.
Solutia optima nu este ın mod necesar unica: se poate ca functia obiectiv sa aiba aceeasi valoare
optima pentru mai multe solutii posibile.
Un comis voiajor trebuie sa viziteze mai multe sedii aflate in orase diferite cu un efort minim.
Datele de intrare vor fi salvate intr-un fisier DateComisVoiajor.in cu urmatoarea structura: pe
prima linie numarul total de orase, iar pe urmatoarele linii indexul orasului urmat de perechi de
valori reprezentand legaturile cu celalalte orase si costurile acestor legaturi.
5
0 1 5 2 1 3 9 4 3
1 2 3 3 7 4 2
2 3 8 4 4
3 4 2
Initial el se va afla in orasul notat cu 1. El nu doreste sa treaca de doua ori prin acelasi oras, iar la
intoarcere vrea sa revina in orasul 1. Cunoscand legaturile existente intre orase, sa se gaseasca cel
mai scurt drum care ii permite comis voiajorului viziteze toate orasele cu un efort minim.
Pentru datele de intrare de mai sus, solutia este (1,3) (3,2) (2,5) (5,4) (4,1), iar lungimea drumului
este 17.
ASD
import java.util.*;
import java.io.*;
try{
br = new BufferedReader(new FileReader(numeFisier));
if(linia1){
nrSedii = Integer.parseInt(st.nextToken());
valori = new int[nrSedii][nrSedii];
solutie = new int[nrSedii][nrSedii];
ni = 0;
drum[ni][ni] = cost = i = p = 0;
solutie[i][p] = valori[i][p];
cost += valori[i][p];
drum[i][p] = drum[p][i] = 1;
i = p;
}
cost += valori[p][ni];
solutie[p][ni] = valori[p][ni];
}
System.out.println(sir);
}
3. Problema spectacolelor
Într-o sală, într-o zi, trebuie planificate n spectacole. Pentru fiecare spectacol se ştie intervalul în
care se desfăşoară: [oraInceput, oraSfarsit]. Se cere să se planifice un număr maxim de spectacole
astfel încât să nu se suprapună. Datele de intrare sunt salvate intr-un fisier si au urmatoare structura:
pe prima linie numarul de spectacole ce trebuie programate, pe a doua linie intervalul orar in care
se pot programa spectacole, iar pe urmatoarele n linii intervalul in care se desfasoara fiecare
spectacol.
9
10 22
11 12
11 13
11 14
12 15
16 17
13 18
16 20
18 20
19 22
ASD
import java.io.*;
import java.util.*;
try{
bf = new BufferedReader(new FileReader(numeFisier));
if(!linia1){
nrSpec = Integer.parseInt(st.nextToken());
oraInceput = new int[nrSpec];
oraSfarsit = new int[nrSpec];
linia1 = true;
continue;
}
if(!linia2){
ora1 = Integer.parseInt(st.nextToken());
ora2 = Integer.parseInt(st.nextToken());
linia2 = true;
continue;
}
while(st.hasMoreTokens())
{
oraInceput[i++] = Integer.parseInt(st.nextToken());
oraSfarsit[i-1] = Integer.parseInt(st.nextToken());
}
}
}catch(Exception e)
{
System.out.println("Eroare " + e.getMessage());
}
}
boolean sortat;
int tempI;
int tempS;
do{
sortat = true;
for(int i = 0; i < nrSpec - 1; i++)
if(oraSfarsit[i] > oraSfarsit[i+1]){
tempI = oraInceput[i];
tempS = oraSfarsit[i];
oraInceput[i] = oraInceput[i+1];
oraSfarsit[i] = oraSfarsit[i+1];
ASD
oraInceput[i+1] = tempI;
oraSfarsit[i+1] = tempS;
sortat = false;
}
}while(!sortat);
}
sir = "Cea mai buna solutie (intre orele " + ora1 + " si " + ora2 + "):\n";
int i = 1;
int ultimaOra = oraSfarsit[0];
System.out.println(sir);
}
s.citireFisier("DateSpectacole.in");
s.sortare();
s.greedy();
}
}
Fiind date n obiecte, fiecare cu greutatea g[i] si valoarea v[i] si un rucsac cu capacitatea totala gt, sa
se determine ce obiecte trebuie selectate pentru a fi luate in rucsac astfel incat greutatea lor totala sa
nu depaseasca gt si valoarea lor sa fie maxima. Datele de intrare vor fi preluate dintr-un fisier
rucsac.in. Fisierul are urmatoarea structura: pe prima linie numarul de obiecte, pe a doua linie
greutatea totala a rucsacului si pe urmatoarele linii perechi de valori reprezentand greutatea si
valoarea fiecarui obiect in parte.
5
22
7 13
10 5
8 8
2 12
9 7
import java.util.*;
import java.io.*;
try{
br = new BufferedReader(new FileReader(numeFisier));
if(!linia1){
nrObiecte = Integer.parseInt(st.nextToken());
valoriVolum = new int[nrObiecte];
valoriCost = new int[nrObiecte];
profit = new double[nrObiecte];
linia1 = true;
continue;
}
if(!linia2){
volumTotal = Integer.parseInt(st.nextToken());
linia2 = true;
continue;
}
while(st.hasMoreTokens()){
valoriVolum[i++] = Integer.parseInt(st.nextToken());
valoriCost[i-1] = Integer.parseInt(st.nextToken());
profit[i-1] = (double)valoriCost[i-1]/(double)valoriVolum[i-1];
}
}
}catch(Exception e){
System.out.println("Eroare " + e.getMessage());
}
}
boolean sortat;
int tempV;
int tempC;
double tempProfit;
do{
sortat = true;
for(int i = 0; i < nrObiecte - 1; i++)
if(profit[i] < profit[i+1]){
tempProfit = profit[i];
tempV = valoriVolum[i];
tempC = valoriCost[i];
profit[i] = profit[i+1];
valoriVolum[i] = valoriVolum[i+1];
valoriCost[i] = valoriCost[i+1];
profit[i+1] = tempProfit;
valoriVolum[i+1] = tempV;
valoriCost[i+1] = tempC;
ASD
sortat = false;
}
}while(!sortat);
}
volumTotal -= valoriVolum[i];
cost += valoriCost[i];
}
}
sir += "Volumul umplut: " + (copieV - volumTotal) + " Cost: " + cost;
System.out.println(sir);
}
pr.citireFisier("DateRucsacDiscret.in");
pr.sortare();
pr.greedy();
}
}
5. Plate sumei
7
3827
50 10
100 5
200 2
500 50
50 2
10 17
1 100
import java.io.*;
import java.util.*;
StringTokenizer st;
String linie;
boolean linia1 = false, linia2 = false;
int i = 0;
try{
bf = new BufferedReader(new FileReader(numeFisier));
if(!linia1){
nrValori = Integer.parseInt(st.nextToken());
valori = new int[nrValori];
numarBancnote = new int[nrValori];
linia1 = true;
continue;
}
if(!linia2){
sumaTotala = Integer.parseInt(st.nextToken());
linia2 = true;
continue;
}
while(st.hasMoreTokens()){
valori[i++] = Integer.parseInt(st.nextToken());
numarBancnote[i-1] = Integer.parseInt(st.nextToken());
}
}
}catch(Exception e)
{
System.out.println("Eroare " + e.getMessage());
}
}
do{
sortat = true;
for(int i = 0; i < nrValori - 1; i++)
if(valori[i] < valori[i+1]){
tempV = valori[i];
tempN = numarBancnote[i];
valori[i] = valori[i+1];
numarBancnote[i] = numarBancnote[i+1];
valori[i+1] = tempV;
numarBancnote[i+1] = tempN;
sortat = false;
}
}while(!sortat);
}
sumaTotala -= nr*valori[i];
}
}
System.out.println(sir);
}
ps.citireFisier("DatePlataSuma.in");
ps.sortare();
ps.greedy();
}
}
6. Exercitii
6.1 Insulele unui arhipelag sunt conectate prin poduri. Un turist isi propune sa viziteze aceste
insule, o singura data , pornind de la o anumita insula . Pozitia podurilor este data sub forma unei
matrici care este salvata intr-un fisier aflat pe disc. Fiecare pod are de asemenea asociata o anumita
lungime. Sa se afiseze solutia optima de vizitare a tuturor insulelor arhipelagului.