Algorytm z powrotami - 2
Janusz Sobieraj - 28 LO

Problem 8 hetmanów

Z Wikipedii:
Problem 8 hetmanów - hetman jest figurą szachową, która bije figury znajdujące się w tej samej kolumnie, wierszu lub diagonali co on sam. W jaki sposób rozstawić osiem hetmanów na tradycyjnej szachownicy 8x8 tak, aby wzajemnie się nie atakowały?

[Twoja przeglądarka nie obsługuje apletów Javy]
Widoczny aplet pokazuje znajduje jedno rozwiązanie problemu 8 hetmanówn, w 2-ch wersjach:
statycznej i dynamicznej.
  • Szare linie zaznaczają szachowane wiersze/kolumny/diagonale danego hetmana.
  • W wersji "dynamicznej" kolorem zielonym pokazywane są pola nieszachowane.
  • Myszą możesz wskazać nowy węzeł startowy (tylko w kolumnie pierwszej).
Zastosuję znane z problemu skoczka,rozwiązanie rekurencyjne :algorytm z powrotami.

Stawiamy hetmana w pierwszej kolumnie np wierszu 8 (patrz start apletu w wersji "dynamicznej"). Przechodzimy do drugiej kolumny i szukamy pierwszego, wolnego wiersza - w tym wypadku będzie to wiersz pierwszy.

Podobnie postępujemy z kolejnymi kolumnami. W momencie, gdy któregoś hetmana nie da się postawić, (w każdym z 8 wierszy hetman będzie atakowany) to cofamy się o jedną kolumnę i przesuwamy hetmana na kolejne wolne pole. Jeśli takie nie istnieje, to znowu się cofamy itd.

Proces powtarzmy do skutku wg poniższego pseudokodu (lewy znajduje jedno rozwiązanie, prawy wszystkie):



void próbuj(i); 
 {
 zapoczątkuj wybieranie i-ego hetmana; 
 do 
  {
   wybierz następną pozycję i-ego hetmana
   if(bezpieczna) 
    {
      zapisz pozycję; 
      if(i<8) 
       {
         próbuj(i+1); 
         if(próba nieudana) usuń zapis
       }
     }
   } 
  while (próba udana) lub (brak następnej pozycji)
} 
void próbuj(i)
{
  for(int j=0;j<8;j++)
    {
      if(bezpieczna)
      {
        zapisz pozycję
        if(i<8) próbuj(i+1);
             else drukuj;
        usuń zapis;
      }
    }
}
Niespodziankę stanowi fakt, że wszystkie rozwiązania realizuje w sumie prostszy algorytm.
Na dobrą sprawę, to dokładnie taki sam algoryt jak ten rozwiązujący problem konika szachowego.

Wyjście z labiryntu też by pewnie znalazł. Ze wględu na te właśnie podobieństwa, ograniczę się do wskazówek wstępnych i do wersji "szukam wszystkich rozwiązań".

Zobacz taką wersję dla C++/Dev-C++
A tutaj kompletne źródło.