Optymalizacja systemów

Transkrypt

Optymalizacja systemów
Optymalizacja systemów
Laboratorium – Sudoku
autor: A. Gonczarek
Cel zadania
Celem zadania jest napisanie programu rozwiązującego Sudoku, formułując problem optymalizacji jako zadanie programowania binarnego. Rozwiązanie należy zaimplementować w środowisku
MATLAB z użyciem funkcji z pakietu do optymalizacji.
Zasady Sudoku
Sudoku jest to łamigłówka polegająca na wypełnieniu kwadratowej planszy o wymiarach 9 × 9
liczbami od 1 do 9, gdzie część liczb została już wpisana. Przy czym w każdej kolumnie, każdym
wierszu oraz w każdej komórce o wymiarach 3 × 3 (patrz rysunek 1) żadna z liczb od 1 do 9
nie może się powtarzać. Poniżej przedstawiono planszę do Sudoku, gdzie ponumerowano kolumny,
wiersze oraz komórki 3 × 3.
Rysunek 1: Plansza do Sudoku.
Problem Sudoku jako programowanie binarne
Niech X oznacza trójwymiarowy tensor o wymiarach 9 × 9 × 9, gdzie każdy jego element przyjmuje
jedynie binarne wartości, tj. xijk ∈ {0, 1}. Przyjmijmy konwencję, że jeśli xijk = 1, to znaczy, że w
i-tym wierszu i j-tej kolumnie na planszy stoi cyfra k.
Ponadto załóżmy, że I oznacza zbiór trójek (i, j, k) informujących o tym, że w i-tym wierszu i
j-tej kolumnie została na stałe wpisana cyfra k.
1
Wtedy problem Sudoku można przedstawić jako następujący problem programowania binarnego:
minimalizuj (po X)
przy ograniczeniach:
0
∀i,k
∀j,k
9
X
j=1
9
X
xijk = 1
xijk = 1
i=1
∀u,v∈{0,3,6} ∀k
3 X
3
X
xi+u,j+v,k = 1
i=1 j=1
∀i,j
9
X
xijk = 1
k=1
∀(i,j,k)∈I xijk = 1
Problem programowania binarnego można rozwiązać z użyciem algorytmu Branch & Bound, który omówiony zostanie w trakcie zajęć. Dla problemu programowania binarnego domyślnie
można go wywołać poprzez użycie komendy:
[x val flag] = bintprog(f,[],[],A,b).
lub
[x val flag] = intlinprog(f,1:numVars,A,b)
Wybór funkcji determinowany jest tutaj wersją środowiska Matlab. Funkcja intlinprog została
wprowadzona w wersji 2014a i wymaga podania dodatkowego argumentu, określającego indeksy
zmiennych optymalizowanych z dziedzinie liczb całkowitych. Wywołanie tego algorytmu należy
zaimplementować w pliku solve sudoku.m.
Ograniczenia równościowe muszą być podane do algorytmu w formie macierzowej Ax = b,
gdzie x jest wektorem zmiennych decyzyjnych utworzonym z trójwymiarowego tensora X. Trójwymiarowy tensor można zamienić na wektor kolumnowy stosując w Matlabie następujące polecenie:
x = X(:).
Każde z ograniczeń (wiersze w macierzy A) złożone jest wyłącznie z zer i jedynek, gdzie jedynka pojawia się wtedy, jeśli odpowiadająca jej zmienna decyzyjna w x jest sumowana w danym
ograniczeniu. Dlatego ograniczenia łatwiej jest tworzyć jako trójwymiarowe tensory analogiczne do
X, a następnie zamieniać je na wiersze macierzy A, stosując wyżej wspomniane polecenie. Poniżej
omówiono wszystkie ograniczenia w modelu.
1. Pierwszy zestaw ograniczeń gwarantuje, że w każdym wierszu każda cyfra stoi dokładnie raz.
Ograniczenia należy zaimplementować w pliku row const.m. Aby automatyczny walidator
2
zadziałał, ograniczenia należy wprowadzić w kolejności numerowania wierszy (rysunek 1),
gdzie dla każdego wiersza należy wprowadzić 9 ograniczeń odpowiadających kolejno cyfrom
od 1 do 9.
2. Drugi zestaw ograniczeń gwarantuje, że w każdej kolumnie każda cyfra stoi dokładnie raz.
Ograniczenia należy zaimplementować w pliku column const.m. Aby automatyczny walidator zadziałał, ograniczenia należy wprowadzić w kolejności numerowania kolumn (rysunek 1),
gdzie dla każdej kolumny należy wprowadzić 9 ograniczeń odpowiadających kolejno cyfrom
od 1 do 9.
3. Trzeci zestaw ograniczeń gwarantuje, że w każdej komórce 3×3 każda cyfra stoi dokładnie raz.
Ograniczenia należy zaimplementować w pliku cell const.m. Aby automatyczny walidator
zadziałał, ograniczenia należy wprowadzić w kolejności numerowania komórek (rysunek 1),
gdzie dla każdej komórki należy wprowadzić 9 ograniczeń odpowiadających kolejno cyfrom
od 1 do 9.
4. Czwarty zestaw ograniczeń gwarantuje, że każdemu polu na planszy przypisana jest dokładnie jedna cyfra. Ograniczenia należy zaimplementować w pliku unique const.m. Aby automatyczny walidator zadziałał, ograniczenia należy wprowadzić w kolejności numerowania
wierszy (rysunek 1), gdzie dla każdego wiersza należy wprowadzić 9 ograniczeń odpowiadających kolejnym polom w tym wierszu zgodnie z numeracją kolumn.
5. Ostatni zestaw ograniczeń gwarantuje, że w początkowo wypełnionych polach będą stały
odpowiednie cyfry. Ograniczenia należy zaimplementować w pliku initial const.m. Aby
automatyczny walidator zadziałał, ograniczenia należy wprowadzić w kolejności ich występowania w macierzy I, która jest argumentem tej funkcji.
Na rysunku 2 przedstawiono przykładowe Sudoku przed i po rozwiązaniu przy pomocy programu.
Zadanie do wykonania (5 pkt.)
Po zaprezentowaniu działającego programu, prowadzący zadaje do kilku pytań kontrolnych mających na celu sprawdzenie poziomu zrozumienia zaimplementowanego w zadaniu kodu. Punkty są
przyznawane wyłącznie na podstawie udzielonych odpowiedzi, co oznacza że samo zaimplementowanie kodu, bez jego zrozumienia, nie gwarantuje uzyskania punktów.
1. Wprowadzić własną macierz I inicjalizującą planszę do Sudoku w pliku my sudoku.m.
2. Zaimplementować wyliczenie ograniczeń na wiersze w pliku row const.m.
3
3. Zaimplementować wyliczenie ograniczeń na kolumny w pliku column const.m.
4. Zaimplementować wyliczenie ograniczeń na komórki w pliku cell const.m.
5. Zaimplementować wyliczenie ograniczeń na unikalność cyfr w polu w pliku unique const.m.
6. Zaimplementować wyliczenie ograniczeń na przypisanie początkowych pól w pliku initial const.m.
7. Zaimplementować rozwiązanie problemu Sudoku z użyciem programowania binarnego w pliku
solve sudoku.m.
UWAGA! Wszelkie nazwy funkcji i zmiennych w plikach *.m muszą pozostać zachowane.
Zmiana jakichkolwiek nazw i dodanie fragmentów kodu poza wskazanymi miejscami skutkować
będzie otrzymaniem 0 pkt.
Rysunek 2: Plansza początkowa i rozwiązane Sudoku.
Pytania kontrolne (5 pkt.)
Prowadzący zadaje do kilku pytań kontrolnych osobie oddającej zadanie. Lista przykładowych
pytań:
1. Co to jest problem programowania binarnego? Czym różni się on od problemu programowania
liniowego?
2. Jaka jest interpretacja tensora zmiennych decyzyjnych X w powyższym zadaniu? Dlaczego
jest on trójwymiarowy?
4
3. Ile jest binarnych zmiennych decyzyjnych w powyższym zadaniu? Oszacuj ile czasu zajęłoby
zastosowanie przeglądu zupełnego (sprawdzenie wszystkich kombinacji zmiennych decyzyjnych) do znalezienia optymalnego rozwiązania.
4. Wytłumacz w jaki sposób zagwarantowane jest, że w każdym wierszu/kolumnie/komórce
znajdą się różne cyfry. Które ograniczenia to zapewniają? Ile jest tych ograniczeń?
5. Wytłumacz do czego służy czwarty zestaw ograniczeń. Co mogłoby się stać z rozwiązaniem
problemu, jeśli usunęlibyśmy te ograniczenia?
6. Wytłumacz w jaki sposób ustawia się początkowe pola tak, by pozostały one niezmienione
w końcowym rozwiązaniu? Które ograniczenia to zapewniają? Ile jest tych ograniczeń?
7. Podaj ogólną ideę działania algorytmu Branch & Bound. Do jakich problemów się go stosuje?
Czy algorytm znajduje zawsze rozwiązanie optymalne?
8. Co to jest relaksacja do problemu programowania liniowego? Po co się ją wykonuje w algorytmie Branch & Bound? Jaka jest relacja pomiędzy optymalnymi wartościami funkcji celu
w problemie wyjściowym i zrelaksowanym?
9. Czy do sformułowanego w zadaniu problemu Sudoku da się bezpośrednio zastosować algorytm
Interior-Point? Odpowiedź uzasadnij.
10. Dlaczego jeśli zmniejszymy liczbę początkowo wprowadzonych wartości do zbioru I, to czas
rozwiązania istotnie się wydłuży?
5