Both sides previous revision
Poprzednia wersja
Nowa wersja
|
Poprzednia wersja
|
pl:dydaktyka:csp:intro [2014/05/14 01:05] msl [Uruchomienie programu] |
pl:dydaktyka:csp:intro [2019/06/27 15:50] (aktualna) |
====== Constraint Programming ====== | ====== Constraint Programming: Wprowadzenie ====== |
| |
Programowanie z ograniczeniami (ang. //Constraint Programming//, dalej nazywane CSP) jest deklaratywnym paradygmatem programowania, skupionym na modelowaniu problemu i wskazaniu wymagań (ograniczeń) stawianych jego rozwiązaniom. Do obowiązków programisty należy: | Programowanie z ograniczeniami (ang. //Constraint Programming//, dalej nazywane CSP) jest deklaratywnym paradygmatem programowania, skupionym na modelowaniu problemu i wskazaniu wymagań (ograniczeń) stawianych jego rozwiązaniom. Do obowiązków programisty należy: |
| |
* zamodelowanie problemu poprzez zdefiniowanie zmiennych o odpowiedniych dziedzinach, | * zamodelowanie problemu poprzez zdefiniowanie zmiennych o odpowiedniych dziedzinach, |
* zdefiniowanie ograniczenia, które określają dozwolone wartości zmiennych w rozwiązaniu | * zdefiniowanie ograniczeń, które określają dozwolone wartości zmiennych w rozwiązaniu |
* [opcjonalne] podanie kryterium oceny rozwiązania, np. minimalizacja długości trasy w problemie komiwojażera | * [opcjonalne] podanie kryterium oceny rozwiązania, np. minimalizacja długości trasy w problemie komiwojażera |
* [opcjonalne] sprecyzowanie procesu przeszukiwania przestrzeni możliwych rozwiązań. | * [opcjonalne] sprecyzowanie procesu przeszukiwania przestrzeni możliwych rozwiązań. |
| |
== Do ściągnięcia: == | == Do ściągnięcia: == |
* [[http://www.minizinc.org/downloads/release-1.6/minizinc-1.6-x86_64-unknown-linux-gnu.tar.gz|MiniZinc (CSP solver)]] | <WRAP center round tip 60%> |
* [[http://www.minizinc.org/downloads/MiniZincIDE/MiniZincIDE-0.9.3-linux-x86_64.tgz|MiniZinc IDE]] | Sala 316 ma już zainstalowane wszystkie potrzebne narzędzia. Jeżeli właśnie w niej siedzisz, możesz pominąć tę sekcję :) |
| </WRAP> |
| |
| * [[http://www.minizinc.org/downloads/release-1.6/minizinc-1.6-x86_64-unknown-linux-gnu.tar.gz|MiniZinc (CSP solver) w wersji 1.6]] lub [[http://www.minizinc.org/downloads/release-2.0.1/minizinc-2.0.1-linux64.tar.gz|nowsza wersja]] |
| * [[http://www.minizinc.org/downloads/MiniZincIDE/MiniZincIDE-0.9.3-linux-x86_64.tgz|MiniZinc IDE w wersji 0.9.3]] lub [[http://www.minizinc.org/downloads/MiniZincIDE/MiniZincIDE-0.9.6-linux-x86_64.tgz|nowsza wersja]] |
| |
| Wybór wersji nowszej ma wady: |
| * nie testowana na borgu (możesz być pierwsz(-y/-a), który tego dokona) |
| * nie powstała jeszcze oficjalna dokumentacja dla tej wersji |
| i zalety: |
| * zostało usuniętych wiele ograniczeń, który w duży stopniu utrudniały modelowanie |
| * ma nowe funkcjonalności, użyteczne, gdyby ktoś się chciał zając tematem bardziej poważnie |
| * IDE stało się bardziej profesjonalne |
| |
== Instalacja: == | == Instalacja: == |
Ściągnięte archiwa zawierają skompilowane już pliki binarne. Instalacja sprowadza się do rozpakowania plików. W przypadku paczki zawierającej solver rozsądne jest wywołanie skryptu ''SETUP'', który przygotowuje środowisko do działania. W przypadku paczki zawierającej IDE, uruchamia się ono poprzez uruchomienie skryptu ''MiniZincIDE.sh''. Po pierwszym uruchomieniu może być konieczne wskazanie ściezki do katalogu z solverem. | Ściągnięte archiwa zawierają skompilowane już pliki binarne. Instalacja sprowadza się do rozpakowania plików. W przypadku paczki zawierającej solver rozsądne jest wywołanie skryptu ''SETUP'', który przygotowuje środowisko do działania. W przypadku paczki zawierającej IDE, uruchamia się ono poprzez uruchomienie skryptu ''MiniZincIDE.sh''. Po pierwszym uruchomieniu może być konieczne wskazanie ściezki do katalogu z solverem. |
| |
| <WRAP center round important 60%> |
| Aby IDE zadziałało na serwerze borg, należy do katalogu ''lib'' skopiować bibliotekę z archiwum: {{:pl:dydaktyka:csp:libqt5network.so.5.zip}} |
| </WRAP> |
| |
| |
===== Rozwiązanie problemu ===== | ===== Rozwiązanie problemu ===== |
=== 1. Krok pierwszy: zmienne decyzyjne === | === 1. Krok pierwszy: zmienne decyzyjne === |
| |
Chcemy ustalić z czego ma składać się zamówienie, zatem potrzebujemy wiedzieć, ile razy ma zostać zamówione każde danie z osobna. Każda zmienna ma opisywać ile egzemplarzy danego dania zamówiono, powinna być więc typu liczby całkowitej (zakładamy, że nie można zamówić połowy dania). W MiniZinc zapiszemy to następująco: | Chcemy ustalić z czego ma składać się zamówienie, zatem potrzebujemy wiedzieć, ile razy ma zostać zamówione każde danie z osobna. Każda zmienna ma opisywać ile egzemplarzy danego dania zamówiono, powinna być więc typu liczby całkowitej (zakładamy, że nie można zamówić połowy dania). W MiniZinc zapiszemy to następująco (słowo kluczowe ''var''wskazuje na zmienne decyzyjne): |
| |
<code> | <code> |
==== Uruchomienie programu ==== | ==== Uruchomienie programu ==== |
| |
Wszystkie powyższe linijki należy skopiować w danej kolejności do pliku z rozszerzeniem ''.mzn''. Następnie w katalogu z plikiem, należy wykonać: | Wszystkie powyższe linijki należy skopiować w danej kolejności do pliku z rozszerzeniem :!:''.mzn'':!:. Następnie w katalogu z plikiem, należy wykonać: |
<code> | <code> |
mzn-g12fd <nazwa_pliku> | mzn-g12fd <nazwa_pliku> |
mzn-g12fd --all-solutions <nazwa_pliku> | mzn-g12fd --all-solutions <nazwa_pliku> |
</code> | </code> |
jeżeli nie chcemy, by solver zatrzymał się pierwszym możliwym rozwiązaniu. W IDE można to wszystko "wyklikać" we względnie intuicyjny sposób. | jeżeli nie chcemy, by solver zatrzymał się pierwszym możliwym rozwiązaniu. W IDE można to wszystko "wyklikać" we względnie intuicyjny sposób (menu na górze -> run, configuration -> print all solutions). |
| |
<WRAP center round tip 60%> | <WRAP center round tip 60%> |
output [menu_names[i] ++ ": " ++ show(order[i]) ++ "\n" | i in 1..menu_length]; | output [menu_names[i] ++ ": " ++ show(order[i]) ++ "\n" | i in 1..menu_length]; |
</code> | </code> |
==== Dodanie karty menu ==== | |
| ==== Uruchomienie kodu ==== |
| |
| Przebiega bez zmian. Proszę uruchomić program i zainkasować 50% z wyimaginowanej sumy pieniędzy. |
| ===== Dodanie karty menu ===== |
| |
| Słabym elementem naszej dotychczasowej pracy jest zapisywanie wszystkich parametrów wewnątrz programu --- przy zmianie menu musielibyśmy zmieniać program, co nie jest szczególnie ogólne i być może ten napiwek to nam się jeszcze do końca nie należy. Aby poradzić sobie z tym problemem, MiniZinc może wczytywać problemy z zewnętrznych plików. Proszę stworzyć plik o rozszerzeniu ''.dzn'' i zawartości: |
| |
| <code> |
| menu_length = 6; |
| money_limit = 1505; |
| menu_prices = [215, 275, 335, 355, 420,580]; |
| menu_names = ["fruit", "fries", "salad", "wings", "sticks", "sampler"]; |
| </code> |
| |
| Następnie proszę usunąć z programu wartości parametrów, zostawiając jedynie ich deklaracje, np. w miejsce linijki ''int: menu_length = 6;'' ma się znaleźć jedynie ''int: menu_length;''. |
| |
| ==== Uruchamianie programu ==== |
| |
| Z poziomu konsoli należy wpisać: |
| <code> |
| mzn-g12fd -d <plik.dzn> <plik.mzn> |
| </code> |
| W IDE należy mieć otwarty plik ''.dzn'' i należy go wybrać jako ''Data file'' w zakładce ''Configuration''. |
| ===== Problem portfelowy ===== |
| |
| Dotychczas nasz cel był zdefiniowany jedynie jako ''satisfy'' --- istnieją jeszcze dwa inne rodzaje celów: ''maximize <wyrażenie>'' oraz ''minimize wyrażenie'', które odpowiednio poszukują rozwiązań, które maksymalizują/minimalizują wartość wyrażenia, np. |
| <code> |
| solve minimize sum(order); |
| </code> |
| znajdzie takie zamówienie, które spełnia wymagane ograniczenia i zawiera jak najmniej dań. |
| |
| === Ćwiczenie === |
| |
| - Proszę dodać do programu kolejny parametr o nazwie ''yumyum_factors''. Będzie to tablica liczb całkowitych, które wskazują jak bardzo dana pozycja w menu jest smaczna (im większy współczynnik yumyum, tym smaczniejsze danie). |
| - Poszukujemy takiego rozwiązania, który maksymalizuję sumę wartości yumyum zamiówionych dań, |
| - Należy zadbać, aby koszt zamówienia nie musiał być równy wartości ''money_limit'', ale mógł być również od niego mniejszy. |
| |
| |
| |
==== Menu na miarę XXI wieku ==== | |
| |