Godus algoritmas su pavyzdžiais: godus metodas & metodas

Kas yra godus algoritmas?

Be Greedy-ąjį algoritmą iš išteklių rinkinys rekursyviai skirstomi remiantis daugiau, nedelsiant prieinamumą tos išteklių bet kuriuo konkrečiu etapu vykdymą.

Norint išspręsti problemą remiantis godžiu požiūriu, yra du etapai

  1. Elementų sąrašo nuskaitymas
  2. Optimizavimas

Šie „Godžių“ algoritmų pamokymai yra aptariami lygiagrečiai masyvo padalijimo eigoje.

Norėdami suprasti godų požiūrį, turėsite turėti žinių apie rekursiją ir konteksto keitimą. Tai padės suprasti, kaip atsekti kodą. Gėrią paradigmą galite apibrėžti atsižvelgdami į savo būtinus ir pakankamus teiginius.

Dvi sąlygos apibrėžia godžią paradigmą.

  • Kiekvienas nuoseklus sprendimas turi struktūrizuoti problemą link jos geriausiai priimto sprendimo.
  • Pakanka, jei problemos struktūrizavimas gali sustoti baigtiniu godžių žingsnių skaičiumi.

Tęsdami teoretizavimą, apibūdinkime istoriją, susijusią su godų paieškos metodu.

Šioje godžiojo algoritmo pamokoje sužinosite:

  • Godžių algoritmų istorija
  • Gobšios strategijos ir sprendimai
  • Gobšaus požiūrio charakteristikos
  • Kodėl verta naudoti godų požiūrį?
  • Kaip išspręsti veiklos pasirinkimo problemą
  • Gobšaus požiūrio architektūra
  • Gobšių algoritmų trūkumai

Godžių algoritmų istorija

Čia yra svarbus godžių algoritmų orientyras:

  • Praėjusio amžiaus aštuntajame dešimtmetyje daugeliui grafikų ėjimo algoritmų buvo konceptualizuoti godūs algoritmai.
  • Esdgeris Djikstra konceptualizavo algoritmą, kad generuotų kuo mažiau medžių. Jis siekė sutrumpinti maršrutų trukmę Nyderlandų sostinėje Amsterdame.
  • Tą patį dešimtmetį „Prim“ ir „Kruskal“ pasiekė optimizavimo strategijas, pagrįstas kelio sąnaudų sumažinimu pasvertais maršrutais.
  • Aštuntajame dešimtmetyje amerikiečių mokslininkai Cormenas, Rivestas ir Steinas savo klasikiniame įvade į algoritmų knygą pasiūlė rekursinį godžių sprendimų pertvarkymą.
  • „Godus“ paieškos paradigma NIST įrašuose buvo įregistruota kaip kitokio tipo optimizavimo strategija 2005 m.
  • Iki datos protokolai, valdantys žiniatinklį, pvz., „Open-shortest-path-first“ (OSPF) ir daugelis kitų tinklo paketų perjungimo protokolų, naudoja godžią strategiją, kad sumažintų tinkle praleistą laiką.

Gobšios strategijos ir sprendimai

Lengviausia logika virto „godžiu“ arba „ne godžiu“. Šiuos teiginius apibrėžė metodas, kurio buvo imtasi siekiant pažangos kiekviename algoritmo etape.

Pavyzdžiui, „Djikstra“ algoritmas naudojo laipsnišką godžią strategiją, nustatančią kompiuterius internete, apskaičiuojant išlaidų funkciją. Išlaidų funkcijos grąžinta vertė nustatė, ar kitas kelias yra „godus“, ar „negobus“.

Trumpai tariant, algoritmas nustoja būti godus, jei bet kuriame etape jis imasi žingsnio, kuris nėra vietinis godus. Gobšuolių problemos sustoja ir nebelieka gobšumo.

Gobšaus požiūrio charakteristikos

Svarbios „Greedy“ metodo algoritmo charakteristikos yra šios:

  • Yra sutvarkytas išteklių sąrašas su sąnaudomis ar vertės priskyrimu. Tai kiekybiškai įvertina sistemos apribojimus.
  • Per tam tikrą laiką, kai bus taikomas apribojimas, sunaudosite maksimalų išteklių kiekį.
  • Pavyzdžiui, iškilus veiklos planavimo problemai, išteklių sąnaudos nurodomos valandomis, o veiklą reikia atlikti eilės tvarka.

Kodėl verta naudoti godų požiūrį?

Čia yra godaus požiūrio taikymo priežastys:

  • Gobšus požiūris turi keletą kompromisų, dėl kurių jis gali būti tinkamas optimizavimui.
  • Viena svarbiausių priežasčių yra nedelsiant pasiekti kuo veiksmingesnį sprendimą. Veiklos pasirinkimo problemoje (Paaiškinta žemiau), jei daugiau veiksmų galima atlikti prieš baigiant dabartinę veiklą, šias veiklas galima atlikti per tą patį laiką.
  • Kita priežastis - rekursyviai padalinti problemą pagal sąlygą, nereikia derinti visų sprendimų.
  • Esant veiklos atrankos problemai, „rekursinis padalijimas“ žingsnis pasiekiamas nuskaitant elementų sąrašą tik vieną kartą ir atsižvelgiant į tam tikras veiklas.

Kaip išspręsti veiklos pasirinkimo problemą

Veiklos planavimo pavyzdyje kiekvienai veiklai nurodomas „pradžios“ ir „pabaigos“ laikas. Kiekviena veikla yra indeksuojama skaičiumi, kad būtų pateikta nuoroda. Yra dvi veiklos kategorijos.

  1. laikoma veikla : yra veikla, kuri yra nuoroda, iš kurios analizuojamas gebėjimas atlikti daugiau nei vieną likusią veiklą.
  2. likusi veikla: veikla pagal vieną ar daugiau indeksų prieš numatomą veiklą.

Bendra trukmė nurodo veiklos vykdymo kainą. Tai reiškia, kad „finišas - pradžia“ nurodo trukmę kaip veiklos kainą.

Sužinosite, kad godus mastas yra likusių veiklų, kurias galite atlikti svarstomos veiklos metu, skaičius.

Gobšaus požiūrio architektūra

1 ŽINGSNIS)

Nuskaitykite veiklos išlaidų sąrašą, pradėdami nuo indekso 0 kaip laikomo indekso.

2 ŽINGSNIS)

Kai iki to laiko galima baigti daugiau veiklų, svarstoma veikla bus baigta, pradėkite ieškoti vienos ar kelių likusių veiklų.

3 ŽINGSNIS

Jei nebėra likusių veiklų, dabartinė likusi veikla tampa kita svarstoma veikla. Pakartokite 1 ir 2 veiksmus su nauja svarstoma veikla. Jei neliko likusios veiklos, pereikite prie 4 žingsnio.

4 ŽINGSNIS)

Grąžinkite svarstomų indeksų sąjungą. Tai yra veiklos indeksai, kurie bus naudojami maksimaliam pralaidumui padidinti.

Gobšaus požiūrio architektūra

Kodo paaiškinimas

#include#include#include#define MAX_ACTIVITIES 12

Kodo paaiškinimas:

  1. Įtraukti antraštės failai / klasės
  2. Maksimalus vartotojo teikiamų veiklų skaičius.
using namespace std;class TIME{public:int hours;public: TIME(){hours = 0;}};

Kodo paaiškinimas:

  1. Srautinių operacijų vardų sritis.
  2. TIME klasės apibrėžimas
  3. Valandos laiko žyma.
  4. Numatytasis TIME konstruktorius
  5. Valandų kintamasis.
class Activity{public:int index;TIME start;TIME finish;public: Activity(){start = finish = TIME();}};

Kodo paaiškinimas:

  1. Klasės apibrėžimas iš veiklos
  2. Laiko žymos, apibrėžiančios trukmę
  3. Numatytame konstruktoriuje visos laiko žymos inicijuojamos iki 0
class Scheduler{public:int considered_index,init_index;Activity *current_activities = new Activity[MAX_ACTIVITIES];Activity *scheduled;

Kodo paaiškinimas:

  1. 1 dalis suplanuotojo klasės apibrėžime.
  2. Laikomas indeksas yra masyvo nuskaitymo pradinis taškas.
  3. Inicializavimo indeksas naudojamas atsitiktinėms laiko žymėms priskirti.
  4. Veiklos objektų masyvas dinamiškai paskirstomas naudojant naują operatorių.
  5. Suplanuotas rodyklė apibrėžia dabartinę godumo bazės vietą.
Scheduler(){considered_index = 0;scheduled = NULL;… … 

Kodo paaiškinimas:

  1. Planuotojo konstruktorius - 2 planuotojo klasės apibrėžimo dalis.
  2. Nagrinėjamas indeksas apibrėžia dabartinę dabartinio nuskaitymo pradžią.
  3. Dabartinis godus mastas pradžioje nėra apibrėžtas.
for(init_index = 0; init_index < MAX_ACTIVITIES; init_index++){current_activities[init_index].start.hours =rand() % 12;current_activities[init_index].finish.hours =current_activities[init_index].start.hours +(rand() % 2);printf("\nSTART:%d END %d\n",current_activities[init_index].start.hours,current_activities[init_index].finish.hours);}… … 

Kodo paaiškinimas:

  1. „A for loop“, kad būtų galima inicijuoti kiekvienos šiuo metu suplanuotos veiklos pradžios ir pabaigos valandas.
  2. Pradžios laiko inicijavimas.
  3. Pabaigos laiko inicijavimas visada po pradžios valandos arba tiksliai.
  4. Derinimo ataskaita, skirta atsispausdinti paskirtas trukmes.
public:Activity * activity_select(int);};

Kodo paaiškinimas:

  1. 4 dalis - paskutinė planuotojo klasės apibrėžimo dalis.
  2. Funkcijos „Veiklos pasirinkimas“ pagrindu imamas pradinio taško indeksas ir godus kvestas padalijamas į godžius papročius.
Activity * Scheduler :: activity_select(int considered_index){this->considered_index = considered_index;int greedy_extent = this->considered_index + 1;… … 

  1. Naudojant srities skyros operatorių (: :), pateikiamas funkcijos apibrėžimas.
  2. Nagrinėjamas indeksas yra indeksas, vadinamas vertybe. Greedy_extent yra inicializuotas tik indeksas po svarstomo indekso.
Activity * Scheduler :: activity_select(int considered_index){while( (greedy_extent < MAX_ACTIVITIES ) &&((this->current_activities[greedy_extent]).start.hours <(this->current_activities[considered_index]).finish.hours )){printf("\nSchedule start:%d \nfinish%d\n activity:%d\n",(this->current_activities[greedy_extent]).start.hours,(this->current_activities[greedy_extent]).finish.hours,greedy_extent + 1);greedy_extent++;}… … 

Kodo paaiškinimas:

  1. Pagrindinė logika - godus mastas apsiriboja veiklų skaičiumi.
  2. Dabartinės veiklos pradžios valandos yra patikrinamos kaip suplanuojamos, kol baigsis nagrinėjama veikla (pateikta pagal svarstomą indeksą).
  3. Kol tai įmanoma, spausdinamas pasirinktinis derinimo sakinys.
  4. Eiti į kitą veiklos masyvo indeksą
… if ( greedy_extent <= MAX_ACTIVITIES ){return activity_select(greedy_extent);}else{return NULL;}}

Kodo paaiškinimas:

  1. Sąlyginis patikrinimas, ar buvo vykdoma visa veikla.
  2. Jei ne, galite iš naujo paleisti savo godų, laikydami indeksą kaip dabartinį tašką. Tai yra rekursyvus žingsnis, godžiai padalijantis probleminį teiginį.
  3. Jei taip, jis grįžta skambinančiajam neturėdamas galimybių išplėsti godumo.
int main(){Scheduler *activity_sched = new Scheduler();activity_sched->scheduled = activity_sched->activity_select(activity_sched->considered_index);return 0;}

Kodo paaiškinimas:

  1. Pagrindinė funkcija, naudojama iškviesti planavimo priemonę.
  2. Netrukus sukuriamas naujas tvarkaraštis.
  3. Veiklos pasirinkimo funkcija, kuri grąžina tipo veiklos žymeklį, skambintojui grįžta pasibaigus godžiam ieškojimui.

Išvestis:

START:7 END 7START:9 END 10START:5 END 6START:10 END 10START:9 END 10Schedule start:5finish6activity:3Schedule start:9finish10activity:5

Gobšių algoritmų trūkumai

Jis netinka godžioms problemoms, kai reikia išspręsti kiekvieną problemą, pvz., Rūšiavimą.

Tokiose „Greedy“ algoritmo praktikos problemose „Godumo“ metodas gali būti neteisingas; blogiausiu atveju netgi lemia neoptimalų sprendimą.

Todėl godžių algoritmų trūkumas yra nežinojimas, kas laukia dabartinės godžios būsenos.

Žemiau pavaizduotas godumo metodo trūkumas:

Gobšus nuskaitymas, parodytas čia kaip medis (didesnės vertės didesnis godumas), algoritmo būsena, kai vertė yra 40, greičiausiai ims 29 kaip kitą vertę. Be to, jo užduotis baigiasi 12. Tai reiškia 41 vertę.

Tačiau jei algoritmas pasirinko neoptimalų kelią arba pritaikė užkariavimo strategiją. tada po 25 eitų 40, o bendras išlaidų pagerėjimas būtų 65, o tai yra 24 taškais aukščiau vertinama kaip neoptimalus sprendimas.

Godžių algoritmų pavyzdžiai

Daugumoje tinklo algoritmų naudojamas godus požiūris. Štai keletas godžių algoritmų pavyzdžių sąrašas:

  • „Prim“ minimalus apimantis medžių algoritmas
  • Keliaujančio pardavėjo problema
  • Grafikas - žemėlapio spalva
  • Minimalus Kruskalio apimančių medžių algoritmas
  • Dijkstros minimalus apimantis medžių algoritmas
  • Grafikas - viršūnės viršelis
  • Kuprinės problema
  • Darbo planavimo problema

Santrauka:

Apibendrinant galima pasakyti, kad straipsnyje buvo apibrėžta godi paradigma, parodyta, kaip godus optimizavimas ir rekursija gali padėti jums pasiekti geriausią sprendimą. „Greedy“ algoritmas yra plačiai pritaikytas problemoms spręsti daugeliu kalbų, kaip „Greedy“ algoritmas „Python“, C, C #, PHP, „Java“ ir kt. „Greedy“ algoritmo pavyzdžio veiklos pasirinkimas buvo apibūdinamas kaip strateginė problema, galinti pasiekti maksimalų pralaidumą naudojant godųjį metodas. Galų gale buvo paaiškinti godaus požiūrio naudojimo trūkumai.

Įdomios straipsniai...