Podstawy współbieżności - Uniwersytet Ekonomiczny w Krakowie

Transkrypt

Podstawy współbieżności - Uniwersytet Ekonomiczny w Krakowie
2011-01-18
Algorytmy z powrotami.
Algorytm minimax
Algorytmy i struktury danych.
Wykład 7.
Rok akademicki: 2010/2011
Algorytm z powrotami
• rozwiązanie problemu budowane jest w kolejnych krokach,
• po stwierdzeniu (w trakcie realizacji i-tego kroku), że
rozwiązanie problemu nie jest możliwe do osiągnięcia
następuje powrót do kroku wcześniejszego i badana jest
możliwośd wykonania innego kroku zapoczątkowującego inną
ścieżkę poszukiwao;
• sposób wyznaczania rozwiązania można przedstawid jako
wędrówkę po drzewie.
Paweł Lula, Katedra Systemów Obliczeniowych, Uniwersytet Ekonomiczny w Krakowie
2
1
2011-01-18
Algorytm z powrotami – schemat działania
Stan
początkowy
Poziom 1
Wariant 1
Poziom 2
Wariant 1.1
Poziom 1
Wariant 3
Poziom 2
Wariant 1.2
Poziom 3
Wariant 1.2.1.
Poziom 2
Wariant 3.1
Poziom 2
Wariant 3.2
Poziom 2
Wariant 3.3
Poziom 3
Wariant 1.2.2.
Paweł Lula, Katedra Systemów Obliczeniowych, Uniwersytet Ekonomiczny w Krakowie
3
Problem ośmiu hetmanów
Ułożyd na szachownicy osiem hetmanów tak, aby się wzajemnie nie szachowały.
Paweł Lula, Katedra Systemów Obliczeniowych, Uniwersytet Ekonomiczny w Krakowie
4
2
2011-01-18
Opis algorytmu problem ośmiu hetmanów
• Figury ustawiane są w kolejnych kolumnach (począwszy od
pierwszej od lewe strony),
• Jeśli ustawienie hetmana w danej kolumnie nie jest możliwe,
to następuje powrót do kolumny wcześniejszej i dokonywana
jest próba zmiany położenia znajdującego się tam hetmana;
po jej dokonaniu poszukiwania są kontynuowane.
Paweł Lula, Katedra Systemów Obliczeniowych, Uniwersytet Ekonomiczny w Krakowie
5
Problem ośmiu hetmanów
class PierwszeUstawienie
{
boolean [][] szachownica = new boolean[8][8];
int ileUstawiono = 0;
void usunWszystko()
{
for (int i = 0; i < 8; i++)
for (int j = 0; j < 8; j++)
szachownica[i][j] = false;
}
Paweł Lula, Katedra Systemów Obliczeniowych, Uniwersytet Ekonomiczny w Krakowie
6
3
2011-01-18
Problem ośmiu hetmanów
void drukujSzachownice()
{
for (int i = 0; i < 8; i++)
{
for (int j = 0; j < 8; j++)
if (szachownica[i][j] == true) System.out.print('*');
else System.out.print('.');
System.out.println();
}
}
Paweł Lula, Katedra Systemów Obliczeniowych, Uniwersytet Ekonomiczny w Krakowie
7
Problem ośmiu hetmanów
boolean czyPoprawne(int x, int y)
{
int i, j;
//czy jest w tym samym wierszu?
for (j = 0; j < 8; j++)
if (szachownica[x][j] == true) return false;
//czy jest w tej samej kolumnie?
for (i = 0; i < 8; i++)
if (szachownica[i][y] == true) return false;
Paweł Lula, Katedra Systemów Obliczeniowych, Uniwersytet Ekonomiczny w Krakowie
8
4
2011-01-18
Problem ośmiu hetmanów
//czy jest na przekatnej prawo-gora ?
for (i = x, j = y; (i >= 0) && (j < 8); i --, j++)
if ((i != x) && (j != y) && (szachownica[i][j] == true))
return false;
//czy jest na przekatnej prawo-dol?
for (i = x, j = y; (i < 8) && (j < 8); i++, j++)
if ((i != x) && (j != y) && (szachownica[i][j] == true))
return false;
//czy jest na przekatnej lewo-gora?
for (i = x, j = y; (i >= 0) && (j >= 0); i--, j--)
if ((i != x) && (j != y) && (szachownica[i][j] == true))
return false;
//czy jest na przekatnej lewo-dol?
for (i = x, j = y; (i < 8) && (j >= 0); i++, j--)
if ((i != x) && (j != y) && (szachownica[i][j] == true))
return false;
}
return true;
Paweł Lula, Katedra Systemów Obliczeniowych, Uniwersytet Ekonomiczny w Krakowie
9
Problem ośmiu hetmanów
boolean ustaw(int kolumna)
{
int wiersz = 0;
do
{
}
if (czyPoprawne(wiersz,kolumna))
{
szachownica[wiersz][kolumna] = true;
ileUstawiono++;
if (kolumna + 1 < 8)
if (ustaw(kolumna + 1)) return true;
else
{
szachownica[wiersz][kolumna] = false;
ileUstawiono--;
}
}
wiersz++;
}
while ((ileUstawiono < 8) && (wiersz < 8));
if (ileUstawiono == 8) return true;
else return false;
Paweł Lula, Katedra Systemów Obliczeniowych, Uniwersytet Ekonomiczny w Krakowie
10
5
2011-01-18
Problem ośmiu hetmanów
void rozwiazZadanie()
{
usunWszystko();
if (ustaw(0)) drukujSzachownice();
else System.out.println("Brak rozwiazaia!!!");
}
}
public class OsiemHetmanow01
{
public static void main(String [] args)
{
PierwszeUstawienie u = new PierwszeUstawienie();
u.rozwiazZadanie();
}
}
Paweł Lula, Katedra Systemów Obliczeniowych, Uniwersytet Ekonomiczny w Krakowie
11
Problem ośmiu hetmanów
Rezultat uruchomienia programu:
*.......
......*.
....*...
.......*
.*......
...*....
.....*..
..*.....
Paweł Lula, Katedra Systemów Obliczeniowych, Uniwersytet Ekonomiczny w Krakowie
12
6
2011-01-18
Algorytm minimax
• Algorytm minimax jest podstawowym algorytmem
wykorzystywanym przy tworzeniu gier dwuosobowych
rozgrywanych w układzie: człowiek - komputer.
Paweł Lula, Katedra Systemów Obliczeniowych, Uniwersytet Ekonomiczny w Krakowie
13
Kółko i krzyżyk jako przykład gry dwuosobowej
Paweł Lula, Katedra Systemów Obliczeniowych, Uniwersytet Ekonomiczny w Krakowie
14
7
2011-01-18
Kółko i krzyżyk – wersja I
class KK01
{
static final int NIKT = 0;
static final int KOMPUTER = 1;
static final int CZLOWIEK = 2;
int n;
int [][] plansza;
KK01(int n)
{
this.n = n;
plansza = new int[n][n];
}
Paweł Lula, Katedra Systemów Obliczeniowych, Uniwersytet Ekonomiczny w Krakowie
15
Kółko i krzyżyk – wersja I
char symbolGracza(int zawodnik)
{
switch(zawodnik)
{
case CZLOWIEK: return 'X';
case KOMPUTER: return 'O';
case NIKT: return '.';
}
return '?';
}
Paweł Lula, Katedra Systemów Obliczeniowych, Uniwersytet Ekonomiczny w Krakowie
16
8
2011-01-18
Kółko i krzyżyk – wersja I
void wyswietl()
{
for (int i = 0; i < n; i++)
{
for (int j = 0; j < n; j++)
System.out.print(symbolGracza(plansza[i][j]));
System.out.println();
}
}
Paweł Lula, Katedra Systemów Obliczeniowych, Uniwersytet Ekonomiczny w Krakowie
17
Kółko i krzyżyk – wersja I
void ruchGracza()
{
int wiersz = 0, kolumna = 0;
System.out.println("RUCH GRACZA:\n");
wyswietl();
System.out.println();
Paweł Lula, Katedra Systemów Obliczeniowych, Uniwersytet Ekonomiczny w Krakowie
18
9
2011-01-18
Kółko i krzyżyk – wersja I
try
{
BufferedReader klawiatura = new BufferedReader(new
InputStreamReader(System.in));
do
{
System.out.print("Podaj numer wiersza (1," + (n) + "): ");
wiersz = Integer.parseInt(klawiatura.readLine());
System.out.print("Podaj numer kolumny (1," + (n) + "): ");
kolumna = Integer.parseInt(klawiatura.readLine());
}
while (plansza[wiersz-1][kolumna-1] != NIKT);
plansza[wiersz-1][kolumna-1] = CZLOWIEK;
System.out.println();
}
catch (Exception e)
{ System.out.println(e.getMessage()); }
}
Paweł Lula, Katedra Systemów Obliczeniowych, Uniwersytet Ekonomiczny w Krakowie
19
Kółko i krzyżyk – wersja I
boolean czyWygral(int zawodnik)
{
int suma;
//czy jest wiersz
for (int i = 0; i < n; i++)
{
suma = 0;
for (int j = 0; j < n; j++)
if (plansza[i][j] == zawodnik) suma++;
if (suma == n) return true;
}
Paweł Lula, Katedra Systemów Obliczeniowych, Uniwersytet Ekonomiczny w Krakowie
20
10
2011-01-18
Kółko i krzyżyk – wersja I
//czy jest kolumna
for (int j = 0; j < n; j++)
{
suma = 0;
for (int i = 0; i < n; i++)
if (plansza[i][j] == zawodnik) suma++;
if (suma == n) return true;
}
//pierwsza przekatna
suma = 0;
for (int i = 0; i < n; i++)
if (plansza[i][i] == zawodnik) suma++;
if (suma == n) return true;
Paweł Lula, Katedra Systemów Obliczeniowych, Uniwersytet Ekonomiczny w Krakowie
21
Kółko i krzyżyk – wersja I
//druga przekatna
suma = 0;
for (int i = 0; i < n; i++)
if (plansza[i][n-1-i] == zawodnik) suma++;
if (suma == n) return true;
return false;
}
Paweł Lula, Katedra Systemów Obliczeniowych, Uniwersytet Ekonomiczny w Krakowie
22
11
2011-01-18
Kółko i krzyżyk – wersja I
int ocenaSytuacji(int ktoWykonalRuch)
{
return czyWygral(ktoWykonalRuch) ? 1000 : 0;
}
Paweł Lula, Katedra Systemów Obliczeniowych, Uniwersytet Ekonomiczny w Krakowie
23
Kółko i krzyżyk – wersja I
int wybierzNajlepszyRuch()
{
int sytuacja = -9999;
int ruch = -1;
int ocena;
for (int i = 0; i < n * n; i++)
if (plansza[i/n][i%n] == NIKT)
{
plansza[i/n][i%n] = KOMPUTER;
if ((ocena = ocenaSytuacji(KOMPUTER)) > sytuacja)
{
sytuacja = ocena;
ruch = i;
}
}
}
plansza[i/n][i%n] = NIKT;
return ruch;
Paweł Lula, Katedra Systemów Obliczeniowych, Uniwersytet Ekonomiczny w Krakowie
24
12
2011-01-18
Kółko i krzyżyk – wersja I
void ruchKomputera()
{
System.out.println("RUCH KOMPUTERA ...\n");
int pozycja = wybierzNajlepszyRuch();
plansza[pozycja/n][pozycja%n] = KOMPUTER;
wyswietl();
System.out.println();
}
Paweł Lula, Katedra Systemów Obliczeniowych, Uniwersytet Ekonomiczny w Krakowie
25
Kółko i krzyżyk – wersja I
boolean czySaPuste()
{
int suma = 0;
for (int i = 0; i < n * n; i++)
if (plansza[i/n][i%n] == NIKT) suma++;
return (suma > 0 ? true: false);
}
int nastepny(int zawodnik)
{
return 3 - zawodnik;
}
Paweł Lula, Katedra Systemów Obliczeniowych, Uniwersytet Ekonomiczny w Krakowie
26
13
2011-01-18
Kółko i krzyżyk – wersja I
void rozgrywka()
{
int nastepnyZawodnik = CZLOWIEK, zawodnik;
do
{
zawodnik = nastepnyZawodnik;
switch (zawodnik)
{
case CZLOWIEK:
ruchGracza();
break;
case KOMPUTER:
ruchKomputera();
break;
}
Paweł Lula, Katedra Systemów Obliczeniowych, Uniwersytet Ekonomiczny w Krakowie
27
Kółko i krzyżyk – wersja I
nastepnyZawodnik = nastepny(zawodnik);
}
while (!czyWygral(zawodnik) && czySaPuste());
System.out.println("\n\nKoniec gry!!!\n");
wyswietl();
System.out.println("\n");
if (czyWygral(CZLOWIEK))
System.out.println("Wygrales z komputerem!!!");
else
if (czyWygral(KOMPUTER))
System.out.println("Wygral KOMPUTER!!!");
else
System.out.println("REMIS!!!");
}
}
Paweł Lula, Katedra Systemów Obliczeniowych, Uniwersytet Ekonomiczny w Krakowie
28
14
2011-01-18
Kółko i krzyżyk – wersja I
class KolkoKrzyzyk02
{
public static void main(String [] args)
{
KK01 kk = new KK01(3);
kk.rozgrywka();
}
}
Paweł Lula, Katedra Systemów Obliczeniowych, Uniwersytet Ekonomiczny w Krakowie
29
Kółko i krzyżyk – wersja I
RUCH GRACZA:
...
...
...
Podaj numer wiersza (1,3): 1
Podaj numer kolumny (1,3): 1
RUCH KOMPUTERA ...
XO.
...
...
RUCH GRACZA:
XO.
...
...
Podaj numer wiersza (1,3): 2
Podaj numer kolumny (1,3): 1
Paweł Lula, Katedra Systemów Obliczeniowych, Uniwersytet Ekonomiczny w Krakowie
30
15
2011-01-18
Kółko i krzyżyk – wersja I
RUCH KOMPUTERA ...
XOO
X..
...
RUCH GRACZA:
XOO
X..
...
Podaj numer wiersza (1,3): 3
Podaj numer kolumny (1,3): 1
Koniec gry!!!
XOO
X..
X..
Wygrales z komputerem!!!
Paweł Lula, Katedra Systemów Obliczeniowych, Uniwersytet Ekonomiczny w Krakowie
31
Wniosek
Zastosowany sposób gry nie jest prawidłowy gdyż realizuje ruch tylko na podstawie oceny bieżącej sytuacji.
Paweł Lula, Katedra Systemów Obliczeniowych, Uniwersytet Ekonomiczny w Krakowie
32
16
2011-01-18
Algorytm minimax
• Algorytm minimax służy do tworzenia gier dwuosobowych.
• Wybiera optymalny ruch na podstawie analizy drzewa gry
(opisującego wszystkie możliwe do zrealizowania ruchy).
• Do oceny sytuacji stosowana jest funkcja płatności oceniająca
sytuację z punktu widzenia komputera - im wyższa jest jej
wartośd, tym lepsza jest pozycja komputera.
• Podstawowa zasada algorytmu: przy wyborze ruchu
komputer maksymalizuje wartośd funkcji płatności, zaś
człowiek wykonuje ruch minimalizujący jej wartośd. Drzewo
gry analizowane jest od dołu.
Paweł Lula, Katedra Systemów Obliczeniowych, Uniwersytet Ekonomiczny w Krakowie
33
Schemat działania algorytmu minimax
Paweł Lula, Katedra Systemów Obliczeniowych, Uniwersytet Ekonomiczny w Krakowie
34
17
2011-01-18
Kółko i krzyżyk – wersja II
class KK02 extends KK01
{
KK02(int n)
{
super(n);
}
Paweł Lula, Katedra Systemów Obliczeniowych, Uniwersytet Ekonomiczny w Krakowie
35
Kółko i krzyżyk – wersja II
int ocenaSytuacji(int ktoWykonalRuch)
{
int wartoscProgowa = 0;
switch(ktoWykonalRuch)
{
case KOMPUTER:
if (czyWygral(KOMPUTER)) return 1000;
if (czySaPuste())
{
wartoscProgowa = 9999;
for (int i = 0; i < n * n; i++)
if (plansza[i/n][i%n] == NIKT)
{
plansza[i/n][i%n] = CZLOWIEK;
wartoscProgowa =
Math.min(wartoscProgowa, ocenaSytuacji(CZLOWIEK));
plansza[i/n][i%n] = NIKT;
}
}
else return 0;
break;
Paweł Lula, Katedra Systemów Obliczeniowych, Uniwersytet Ekonomiczny w Krakowie
36
18
2011-01-18
Kółko i krzyżyk – wersja II
case CZLOWIEK:
if (czyWygral(CZLOWIEK)) return -1000;
if (czySaPuste())
{
wartoscProgowa = -9999;
for (int i = 0; i < n * n; i++)
if (plansza[i/n][i%n] == NIKT)
{
plansza[i/n][i%n] = KOMPUTER;
wartoscProgowa = Math.max(wartoscProgowa,
ocenaSytuacji(KOMPUTER));
plansza[i/n][i%n] = NIKT;
}
}
else return 0;
} // koniec switch
return wartoscProgowa;
} // koniec ocenaSytuacji
} // koniec definicji klasy
Paweł Lula, Katedra Systemów Obliczeniowych, Uniwersytet Ekonomiczny w Krakowie
37
19

Podobne dokumenty