Jak działają algorytmy
Chapter 10 Intractable Problems and Approximation Algorithms

Rozdział 10: Nierozwiązywalne problemy i algorytmy aproksymacyjne

W poprzednich rozdziałach zbadaliśmy różnorodne algorytmy służące do efektywnego rozwiązywania problemów. Jednak istnieje wiele problemów, dla których nie znamy wydajnych algorytmów. W tym rozdziale omówimy teorię NP-zupełności, która dostarcza sposobu na wykazanie, że dany problem prawdopodobnie jest nierozwiązywalny, czyli że prawdopodobnie nie istnieje wydajny algorytm do jego rozwiązania. Zbadamy również techniki radzenia sobie z problemami NP-zupełnymi, w tym algorytmy aproksymacyjne i algorytmy przeszukiwania lokalnego.

Klasy P i NP

Aby zrozumieć NP-zupełność, musimy najpierw zdefiniować dwie ważne klasy problemów: P i NP.

Klasa P (czas wielomianowy) składa się ze wszystkich problemów decyzyjnych, które mogą być rozwiązane przez algorytm działający w czasie wielomianowym. Problem decyzyjny to problem, który ma odpowiedź tak lub nie. Na przykład problem określenia, czy graf ma cykl Hamiltona (cykl odwiedzający każdy wierzchołek dokładnie raz) jest problemem decyzyjnym. Jeśli problem decyzyjny należy do klasy P, to istnieje algorytm, który może rozwiązać dowolny przypadek tego problemu w liczbie kroków ograniczonej wielomianem rozmiaru danych wejściowych.

Klasa NP (niedeterministyczny czas wielomianowy) składa się ze wszystkich problemów decyzyjnych, dla których rozwiązanie można zweryfikować w czasie wielomianowym. Na przykład problem cyklu Hamiltona należy do klasy NP, ponieważ, mając graf i proponowany cykl Hamiltona, możemy łatwo sprawdzić w czasie wielomianowym, czy proponowany cykl jest rzeczywiście cyklem Hamiltona.

Oczywiste jest, że P jest podzbiorem NP, ponieważ każdy problem, który może być rozwiązany w czasie wielomianowym, może również być zweryfikowany w czasie wielomianowym. Jednak pozostaje otwartym pytaniem, czy P = NP. Większość ekspertów uważa, że P ≠ NP, co oznacza, że istnieją problemy w NP, które nie należą do P. Jednak udowodnienie tego byłoby przełomem w teoretycznej informatyce.

NP-zupełność

Problem decyzyjny X jest NP-zupełny, jeśli:

1Oto polski przekład pliku Markdown:

. X znajduje się w NP, a 2. Każdy problem w NP można zredukować do X w czasie wielomianowym.

Problem Y można zredukować do problemu X, jeśli każdy przypadek Y można przekształcić w przypadek X w czasie wielomianowym, tak że odpowiedź na przypadek Y jest "tak" wtedy i tylko wtedy, gdy odpowiedź na przekształcony przypadek X jest "tak".

Koncepcję NP-zupełności wprowadzili niezależnie Stephen Cook i Leonid Levin w 1971 roku. Pierwszym problemem, który okazał się NP-zupełny, był problem spełnialności formuł logicznych (SAT). Od tego czasu wiele innych problemów wykazano jako NP-zupełne, redukując SAT lub inne znane problemy NP-zupełne do nich.

Niektóre dobrze znane problemy NP-zupełne to:

  • Problem Komiwojażera (TSP): Mając zestaw miast i odległości między nimi, znajdź najkrótszą trasę, która odwiedza każde miasto dokładnie raz.
  • Problem Plecakowy: Mając zestaw przedmiotów z wagami i wartościami oraz plecak z ograniczeniem wagowym, znajdź podzbiór przedmiotów o maksymalnej łącznej wartości, który mieści się w plecaku.
  • Problem Kolorowania Grafu: Mając graf, znajdź minimalną liczbę kolorów potrzebnych do pokolorowania wierzchołków tak, aby żadne dwa sąsiednie wierzchołki nie miały tego samego koloru.

Znaczenie NP-zupełności polega na tym, że jeśli jakikolwiek problem NP-zupełny mógłby być rozwiązany w czasie wielomianowym, to wszystkie problemy w NP mogłyby być rozwiązane w czasie wielomianowym (tj. P = NP). Jednak pomimo dziesięcioleci wysiłków, nie znaleziono wielomianowego algorytmu dla żadnego problemu NP-zupełnego. Sugeruje to (ale nie dowodzi), że problemy NP-zupełne są inherentnie trudne i mało prawdopodobne, aby miały wydajne algorytmy.

Algorytmy Przybliżone

Ponieważ problemy NP-zupełne uważa się za nierozwiązywalne, często uciekamy się do algorytmów przybliżonych, gdy stajemy w obliczu takich problemów w praktyce. Algorytm przybliżony to algorytm, który znajduje rozwiązanie gwarantowane do bycia w określonym współczynniku od optymalnego rozwiązania.

Na przykład, rozważmy problem Pokrycia Wierzchołków: mając graf, znajdź najmniejszy zbiór wierzchołków, który pokrywa wszystkie krawędzie.Proszę o polskie tłumaczenie tego pliku Markdown. W przypadku kodu, nie tłumacz kodu, tylko komentarze:

Najmniejszy zbiór wierzchołków, taki że każda krawędź jest incydentna do co najmniej jednego wierzchołka w tym zbiorze. Ten problem jest NP-zupełny. Jednak istnieje prosty algorytm aproksymacyjny, który znajduje pokrycie wierzchołkowe o wielkości co najwyżej dwukrotnie większej niż wielkość optymalnego pokrycia wierzchołkowego:

  1. Zainicjuj pusty zbiór C.
  2. Dopóki istnieją niepokryte krawędzie w grafie:
    • Wybierz dowolną niepokrytą krawędź (u, v).
    • Dodaj zarówno u, jak i v do C.
    • Usuń wszystkie krawędzie incydentne do u lub v z grafu.
  3. Zwróć C.

Ten algorytm działa w czasie wielomianowym i zawsze znajduje pokrycie wierzchołkowe, które jest co najwyżej dwukrotnie większe niż optymalne pokrycie wierzchołkowe. Aby to zobaczyć, należy zauważyć, że w każdej iteracji algorytm wybiera dwa wierzchołki, aby pokryć krawędź, podczas gdy optymalne rozwiązanie musi wybrać co najmniej jeden z tych wierzchołków. Zatem algorytm wybiera co najwyżej dwa razy więcej wierzchołków niż optymalne rozwiązanie.

Algorytmy aproksymacyjne są często używane w praktyce, ponieważ zapewniają gwarantowany poziom jakości, działając w czasie wielomianowym. Współczynnik aproksymacji algorytmu to najgorszy przypadek stosunku wielkości rozwiązania znalezionego przez algorytm do wielkości optymalnego rozwiązania.

Algorytmy przeszukiwania lokalnego

Innym podejściem do radzenia sobie z problemami NP-zupełnymi jest użycie algorytmów przeszukiwania lokalnego. Algorytm przeszukiwania lokalnego rozpoczyna od początkowego rozwiązania i iteracyjnie je ulepsza, dokonując małych lokalnych zmian, aż nie można już dokonać dalszych ulepszeń.

Na przykład, rozważmy problem komiwojażera (TSP). Prosty algorytm przeszukiwania lokalnego dla TSP działa w następujący sposób:

  1. Rozpocznij od dowolnej trasy.
  2. Dopóki możliwe są ulepszenia:
    • Rozważ wszystkie możliwe zamiany dwóch miast w bieżącej trasie.
    • Jeśli jakakolwiek zamiana poprawia długość trasy, dokonaj tej zamiany.
  3. Zwróć bieżącą trasę.

Ten algorytm rozpoczyna od losowej trasy i wielokrotnie ją ulepsza, zamieniając pary miast, aż nie można już dokonać dalszych ulepszeń. Otrzymana trasa jest optimum lokalnym, co oznacza, że nie można jej już ulepszyć poprzez zamianę par miast.Lokalne algorytmy wyszukiwania często mogą szybko znaleźć dobre rozwiązania, ale nie jest gwarantowane, że znajdą globalny optimum. Mogą one utknąć w lokalnych optimach, które są daleko od globalnego optimum. Aby temu zapobiec, można zastosować różne techniki, takie jak:

  • Uruchomienie lokalnego wyszukiwania wielokrotnie z różnymi początkowymi rozwiązaniami.
  • Pozwolenie lokalnemu wyszukiwaniu na wykonywanie ruchów, które tymczasowo pogarszają rozwiązanie, aby pomóc wydostać się z lokalnych optimów.
  • Używanie bardziej złożonych struktur sąsiedztwa, które rozważają większe zmiany w bieżącym rozwiązaniu.

Lokalne algorytmy wyszukiwania są szeroko stosowane w praktyce do rozwiązywania dużych instancji problemów NP-zupełnych, często w połączeniu z innymi technikami, takimi jak algorytmy aproksymacyjne i heurystyki.

Wniosek

Teoria NP-zupełności dostarcza ram do zrozumienia wewnętrznej trudności niektórych problemów obliczeniowych. Problemy NP-zupełne uważa się za nierozwiązywalne, co oznacza, że mało prawdopodobne jest, aby miały one wydajne algorytmy.

Gdy w praktyce mamy do czynienia z problemami NP-zupełnymi, często uciekamy się do algorytmów aproksymacyjnych i lokalnych algorytmów wyszukiwania. Algorytmy aproksymacyjne zapewniają gwarantowany poziom jakości rozwiązania, działając w czasie wielomianowym. Lokalne algorytmy wyszukiwania często mogą szybko znaleźć dobre rozwiązania poprzez iteracyjne ulepszanie początkowego rozwiązania.

Zrozumienie teorii NP-zupełności i technik radzenia sobie z problemami NP-zupełnymi jest niezbędne dla każdego, kto pracuje nad rzeczywistymi problemami optymalizacyjnymi. Chociaż nie możemy rozwiązywać problemów NP-zupełnych optymalnie, często możemy znaleźć wystarczająco dobre rozwiązania, korzystając z algorytmów aproksymacyjnych i lokalnych algorytmów wyszukiwania.

Wraz ze wzrostem wielkości i złożoności problemów, z którymi się mierzymy, znaczenie zrozumienia i radzenia sobie z NP-zupełnością będzie tylko rosło. Opanowując techniki omówione w tym rozdziale, będziesz dobrze przygotowany do podjęcia się niektórych z najbardziej wymagających i ważnych problemów w informatyce.Here is the Polish translation of the provided Markdown file, with the code comments translated:

Nauka i poza nią

Wprowadzenie

Nauka to fascynujący świat, który nieustannie odkrywa nowe horyzonty. Jednak nauka to nie tylko badania i eksperymenty - to również sposób na zrozumienie otaczającego nas świata i naszego miejsca w nim.

Podstawy naukowe

Podstawą nauki są trzy kluczowe elementy:

  1. Obserwacja
  2. Hipoteza
  3. Weryfikacja
# Przykładowy kod w Pythonie
def calculate_area(length, width):
    """
    Funkcja oblicza pole powierzchni prostokąta.
    
    Args:
        length (float): długość prostokąta
        width (float): szerokość prostokąta
    
    Returns:
        float: pole powierzchni prostokąta
    """
    return length * width

Zastosowania nauki

Nauka znajduje zastosowanie w wielu dziedzinach życia, takich jak:

  • Medycyna
  • Technologia
  • Ochrona środowiska
  • Astronomia

Podsumowanie

Nauka to niesamowite narzędzie, które pozwala nam lepiej zrozumieć otaczający nas świat. Poprzez ciągłe badania i odkrycia, nauka otwiera przed nami nowe możliwości i perspektywy.