Ten artykuł opisuje algorytm zachłanny rozwiązujący problem wydawania reszty. Algorytm ten polega na wybieraniu zawsze największej dostępnej monety, tzn. takiej, która nie jest większa od kwoty pozostałej do wydania.
Algorytm nie zawsze znajduje rozwiązanie optymalne. Przykładowo, dla zbioru nominałów {1, 3, 4} i kwoty 6 algorytm użyje najpierw monety o nominale 4 (pozostaje do wydania kwota 2), potem monety o nominale 1 (pozostaje kwota 1) i jeszcze raz monety o nominale 1. Łącznie algorytm użyje więc trzech monet, podczas gdy rozwiązanie optymalne wymaga użycia tylko dwóch (dwie monety o nominale 3).
Dany jest posortowany rosnąco ciąg nominałów A=(c1, c2, …, cn) oraz kwota do wydania r. Algorytm działa następująco:
Choć w przypadku ogólnym algorytm zachłanny nie daje rozwiązania optymalnego, to istnieją takie zbiory nominałów, dla których algorytm tę gwarancję daje. W pracy Combinatorics of the change-making problem (link w bibliografii) zaprezentowano metodę pozwalającą sprawdzić, czy dla danego ciągu nominałów algorytm zachłanny daje gwarancję znalezienia rozwiązania optymalnego niezależnie od wydawanej kwoty (takie ciągi nominałów w dalszej części artykułu będziemy określać jako „zachłanne”). Posortowany ciąg nominałów A=(c1, c2, …, cn) jest „zachłanny”, jeśli są spełnione następujące warunki:
Dowód tego twierdzenia jest dostępny we wspomnianej pracy Combinatorics of the change-making problem. Znając powyższe warunki możemy sprawdzić kolejno zachłanność podciągów (c1, c2), (c1, c2, c3) aż do (c1, c2, …, cn).
Dla przykładu sprawdźmy, czy „zachłanny” jest ciąg nominałów (1, 2, 5, 10):
Z tego twierdzenia wynikają też pewne bardziej ogólne wnioski. Zastanówmy się nad ciągami, w których każdy element ciągu jest wielokrotnością poprzedniego (kcn-1=cn, k > 0). Wówczas iloraz cn/cn-1 wynosi dokładnie k. Kwota mcn-1-cn wynosi wówczas 0. Do wydania kwoty 0 potrzeba 0 monet. 0 zawsze jest mniejsze bądź równe k-1. Podsumowując, jeśli w ciągu nominałów każdy element (poza pierwszym) jest wielokrotnością poprzedniego, to algorytm zachłanny będzie dawał rozwiązania optymalne.
Dla kwoty 1 i n nominałów główna pętla programu wykona się n razy. Dla zbioru nominałów (1) i kwoty r pętla wykona się r razy. Można zatem powiedzieć, że złożoność czasowa algorytmu to O(n+r). Warto jednak zauważyć, że w praktyce algorytm może działać jeszcze szybciej – dla ustalonego r liczba wykonań pętli może wręcz maleć wraz ze wzrostem n, dopóki cn<r. Złożoność pamięciowa algorytmu jest stała (nie zależy od n ani r).
Dodano: 6 października 2016 12:33, ostatnia edycja: 24 kwietnia 2020 20:24.
Algorytm heurystyczny, heurystyka – algorytm niedający (w ogólnym przypadku) gwarancji znalezienia rozwiązania optymalnego, umożliwiający jednak znalezienie rozwiązania dość dobrego w rozsądnym czasie. Algorytmy tego typu używane są w takich problemach obliczeniowych, gdzie znalezienie rozwiązania optymalnego ma zbyt dużą złożoność obliczeniową (w szczególności są to problemy NP-trudne) lub w ogóle nie jest możliwe. Metody heurystyczne zaliczają się do sztucznej inteligencji.
Pojęcie algorytmów heurystycznych jest bardzo szerokie, dotyczy ono różnych technik projektowania algorytmów. Wiele heurystyk wykorzystuje losowość, inne zaś są deterministyczne (wówczas dla takich samych danych wejściowych algorytm zawsze zwróci ten sam wynik).
Ogólny algorytm heurystyczny (opisujący samą ideę poszukiwań) bywa określany w literaturze jako metaheurystyka. Zgodnie z tym nazewnictwem, metaheurystyką jest np. algorytm zachłanny (jako ogólna idea), zaś heurystyką jest np. algorytm najbliższego sąsiada (jako zastosowanie idei algorytmu zachłannego do konkretnego problemu).
Przykładowe techniki konstruowania algorytmów heurystycznych to:
Wyznaczanie maksymalnego przepływu – problem obliczeniowy polegający na wyznaczeniu maksymalnego przepływu w sieci przepływowej.
Sieć przepływowa jest skierowanym grafem prostym. Każdy łuk (krawędź skierowana w grafie) ma swoją nieujemną wagę, która oznacza maksymalny dopuszczalny przepływ w tym łuku. Na potrzeby tego artykułu nazwijmy rzeczy przepływające przez sieć danymi. Jeden z wierzchołków sieci jest źródłem, z którego wypływają przesyłane dane. Inny z wierzchołków to ujście, do którego te dane wpływają. Zakłada się ponadto, że dla każdego z pozostałych wierzchołków istnieje ścieżka ze źródła do ujścia przechodząca przez ten wierzchołek.
Przepływem w sieci nazywamy przyporządkowanie każdemu łukowi pewnej wartości, która oznacza liczbę danych aktualnie przesyłanych przez ten łuk. Wartości te muszą spełniać następujące warunki:
Omawiany problem polega na dobraniu takiego przepływu, aby liczba danych wypływających ze źródła (i zarazem wpływających do ujścia) była jak największa.
Metoda Otsu – algorytm służący do binaryzacji obrazu, czyli przekształcenia obrazu w odcieniach szarości do obrazu binarnego. Metoda ta realizuje progowanie globalne – dla całego obrazu wyznaczany jest jeden próg jasności, a następnie wszystkim pikselom jaśniejszym od tego progu przypisywana jest jedna wartość, a ciemniejszym druga.
Algorytm jest oparty na analizie histogramu. Przygotowanie histogramu polega na zliczeniu pikseli w każdym możliwym odcieniu (zazwyczaj liczba odcieni wynosi 256, gdyż tyle da się zakodować w jednym bajcie). Następnie należy sprawdzić każdy możliwy próg jasności i wybrać ten, dla którego wariancja międzyklasowa jest największa (lub suma ważona wariancji wewnątrzklasowych jest najmniejsza).
Jeśli obrazem wejściowym jest obraz kolorowy, można go łatwo sprowadzić do odcieni szarości. W przypadku kolorów zakodowanych w RGB najprostszym rozwiązaniem jest uśrednienie dla każdego piksela wartości wszystkich trzech kanałów.