540 likes | 701 Views
Modelowanie za pomocą więzów w dziedzinach skończonych. Modelling wth Finite Domains. Domains and Labelling Complex Constraints Labelling Different Problem Modellings Example: Scheduling. Dziedziny i wyliczanie. Musimy definiować dziedziny zmiennych
E N D
Modelling wth Finite Domains • Domains and Labelling • Complex Constraints • Labelling • Different Problem Modellings • Example: Scheduling
Dziedziny i wyliczanie • Musimy definiować dziedziny zmiennych • arytmetyczne X :: [1,2,3,4] or X :: [1..4] • niearytmetyczneX :: [red, blue, yellow] • wiele zmiennych[X,Y,Z] :: [0..10] • Gdy dziedzina nieokreślona wybieramy pewien zasięg (np [-10000..10000]
Przykłady dziedzin Zapytanie dla problemu plecakowego: [W,P,C] :: [0..9], 4*W + 3*P + 2*C <= 9, 15*W + 10*P + 7*C >= 30. CLP(FD) odpowiada unknown. Jak znaleźć rozwiązanie? Utworzyć zupełny (nawracający) solwer
Wyliczanie • Wbudowany predykat labelingdaje możliwość utworzenia zupełnego solwera • labeling(Vs) bierze listę zmiennych FD Vs i znajduje rozwiązanie [W,P,C] :: [0..9], 4*W + 3*P + 2*C <= 9, 15*W + 10*P + 7*C >= 30, labeling([W,P,C]). Ma rozwiązanie:
Ogranicz i generuj • Typowa postać programu FD • defininiujemy zmienne i dziedziny • podane są więzy modelujące program • ,,uzupełnianie’’ za pomocą wyliczania • Można zastosować minimalizację do predykatu labelling [W,P,C] :: [0..9], 4*W + 3*P + 2*C <= 9, 15*W + 10*P + 7*C >= 30, minimize(labeling([W,P,C]), -15*W-10*P-7*C).
Send+More=Money. Przykład Problem kryptoarytmetyczny, każda cyfra inna i zachodzi równanie smm(S,E,N,D,M,O,R,Y) :- [S,E,N,D,M,O,R,Y] :: [0..9], constrain(S,E,N,D,M,O,R,Y), labeling([S,E,N,D,M,O,R,Y]). constrain(S,E,N,D,M,O,R,Y) :- S != 0, M != 0, alldifferent_neq([S,E,N,D,M,O,R,Y]), 1000*S + 100*E + 10*N + D + 1000*M + 100*O + 10*R + E = 10000*M + 1000*O + 100*R + 10*E + Y.
Send+More=Money. Przykład Po deklaracji dziedzin: Po mamy alldifferent_neq dodaje nierówn. (bez zmian) ostatecznie: (jedna reguła propagacji) Dla bieżącej dziedziny:
Send+More=Money. Przykład Zatem D(M) = [1..1] Propagacja trwa dalej dając 3 zmienne ustalone, wszyskie dziedziny zmniejszone labelling próbuje S=0, S=1, ..., S=8 (zawodzą) następnie S=9. Potem E=0, E=1, E=2, E=3 (zawodzą) i E=4 (w końcu też zawodzi), następnie E=5 daje
Generuj i testuj Metodologia bez więzów: generuj rozwiązanie i sprawdź je smm(S,E,N,D,M,O,R,Y) :- [S,E,N,D,M,O,R,Y] :: [0..9], labeling([S,E,N,D,M,O,R,Y]), constrain(S,E,N,D,M,O,R,Y). Ten program wymaga 95671082 wyborów przed znalezieniem rozwiązania, poprzedni jedynie 35 (z tego dwa nie dawały bezpośredniego nawrotu)
Złożone więzy • Złożone więzy: alldifferent, cumulative i element • Bardziej zwięzłe modele • Lepsza propagacja = większa efektywność • Zamieńmy w przykładzie • alldifferent_neq([S,E,N,D,M,O,R,Y]) • alldifferent([S,E,N,D,M,O,R,Y])
Złożone więzy 10 stopowa huśtawka, Liz, Fi i Sarah chcą usiąść w równowadze, w odległości co najmniej 3 stóp. Ważą 9,8,4 czegoś tam. apart(X,Y,N) :- X >= Y + N. apart(X,Y,N) :- Y >= X + N. [L,F,S] :: [-5..5], 9*L + 8*F + 4*S = 0, apart(L,F,3), apart(L,S,3), apart(F,S,3), labeling([L,F,S)]
Złożone więzy Każda dziewczynka to pudełko o szerokości 3 wkładana do pudełka o szer 13 Pasuje do więzu cumulative [L,F,S] :: [-5..5], 9*L + 8*F + 4*S = 0, cumulative([L,F,S],[3,3,3],[1,1,1],1) labeling([L,F,S)]
Wyliczanie • Labelling może być zaprogramowany w CLP(FD) za pomocą wbudowanych predykatów • dom(V,D) lista wartości D w bieżącej dziedzinie V • maxdomain(V,M) maksymalna wartośćM zm V • mindomain(V,M) bieżca minimalna wartośćM zm V labeling([]). labeling([V|Vs]) :- indomain(V), labeling(Vs). indomain(V) :- dom(V,D), member(V,D).
Wyliczanie • Wykorzystuje bierzące wartości dziedziny • Przykład (Send-More-Money) Labelling próbuje S=9. potem E=4 (zawodzi w końcu), potem E=5 co daje Labelling dodadje N=6, D=7, M=1, O=0, R=9 i Y=2, i kończy z sukcesem
Wyliczanie • Dwa wybory w labelling • którą zmienną wyliczamy na początku • kolejność próbowanych wartości • Domyślny labelling • sprawdza zmienne w kolejności z listy • wartości od min do max • Możemy zaprogramować inne strategie
Wybór zmiennych • Wybór zmiennych wpływa na wielkość drz. wypr. • Wybieramy zmienną o najmniejszej bieżącej dziedzinie • Przykład Labelling najpierw bierze S, M, O (nic nie trzeba robić), potem E lub N. Lepiej niż Y jako pierwsza
Wyliczanie First-Fail labelingff([]). labelingff(Vs) :- deleteff(Vs,V,R), indomain(V), labelingff(R). deleteff([V0|Vs],V,R) :- getsize(V0,S), minsize(Vs,S,V0,V,R)). minsize([],_,V,V,[]). minsize([V1|Vs],S0,V0,V,[V0|R]) :- getsize(V1,S1), S1 < S0, minsize(Vs,S1,V1,V,R). minsize([V1|Vs],S0,V0,V,[V1|R]) :- getsize(V1,S1), S1 >= S0, minsize(Vs,S0,V0,V,R).
Wyliczanie First-Fail • labellingffwylicza najpierw wartości zmiennej o najmniejszej dziedzinie • minsize(Vs,S0,V0,V,R) znajduje wśród zmiennych Vs zmiennąr V o mnajmniejszej dziedzinie z najmniejzzą var V0 i rozmiarzeS0, R to reszta zmiennych. • Zastosowanie zasady first-fail • Aby wygrać, próbuj najpierw to, gdzie najłatwiej przegrać”
Wybór wartości zmiennych • Wybór wartości wpływa na porządek eksploracji gałęzi drzewa • Stosując wiedzę specyficzną problemowi można szybciej dojść do rozw. • Ważne dla optymalizacji • dobre rozwiązanie szybko redukuje potem przestrzeń przeszukiwań
Q1 Q2 Q3 Q4 1 2 3 4 N-hetmanów Problem umieszczenia N hetmanów na szachownicy NxN Dla dużych N w rozwiązaniach wartości bardziej ,,środkowe’’
Porządek Middle-Out indomain_mid(V) :- ordervalues(V,L), member(V,L). ordervalues(V,L) :- dom(V,D), length(D,N), H = N//2, halvelist(H,D,[],F,S), merge(S,F,L). halvelist(0,L2,L1,L1,L2). halvelist(N,[E|R],L0,L1,L2) :- N >= 1, N1 = N - 1, halvelist(N1,R,[E|L0],L1,L2). merge([],L,L). merge([X|L1],L2,[X|L3]) :- merge(L2,L1,L3).
Porządek Middle-Out • indomain_mid(V) próbuje wartości z dziedziny poczynając od środka • ordervalues tworzy uporządkowaną listę wartości • halvelist dzieli listę na dwie części, pierwszą odwraca • merge(L1,L2,L3) przeplata listy L1, L2 aby otrzymać L3
Efektywność wyliczania • Możemy jednocześnie użyć porządkowania zmiennych i wartości Rożna liczba wyborów w różnych zasięgach
Dzielenie dziedzin • Labelling to nie musi być przypisywanie zmiennym wartości • Należy zmniejszać dziedziny zmiennych • Domain splitting rozdwaja dziedzinę bieżącej zmiennej
Dzielenie dziedzin labelingsplt([]). labelingsplt([V|Vs]) :- mindomain(V,Min), maxdomain(V,Max), (Min = Max -> NVs = Vs ; Mid = (Min+Max)//2, labelsplt(V,Mid) append(Vs,[V],NVs) ), labelingsplt(NVs). labelsplt(V,M) :- V <= M,. labelsplt(V,M) :- V >= M+1.
Dzielenie dziedzin • labelingsplt rekurencyjnie dzieli dziedziny zmiennych na połówki, aż każda stanie się jednopunktowa. Gdy Min=Max the zmienną usuwa się z listy, w przeciwnym wypadku dzieli się ją i daje na koniec listy zmiennych do podziałut. • labelsplt(V,M) zdecydyj, czy V ma bycr <= czy => od M
Jeden problem - różne modele • Różne spojrzenia na problem dają różne modele • Inny modell = inne zbiory zmiennych • W zależności od właściwości solwera modele mogą dawać szybciej wynik • Być może trzeba sprawdzić empirycznie
Rożne modele Problem optymalizacyjny: 4 robotników w1,w2,w3,w4 i 4 produkty p1,p2,p3,p4. Przypisz robotników produktom aby zysk był >= 19 Macierz zysków:
Model z badań operacyjnych 16 zmiennych logicznych Bij, każda mówi, że robotnik i jest przypisany do produktu j B23 11 więzów baz. 28 wyborów, by znaleźć 4 rozwiązania
Lepszy model 1 2 3 4 Używamy więzów złożonych. Zmienne W1,W2,W3,W4 odpowiadają robotnikom W1 W2 W3 W4 7 więzów bazowych 14 wyborów
Inny model T1 T2 T3 T4 Zmienne T1,T2,T3,T4 odpowiadające produktom. 1 2 3 4 7 więzów bazowych 7 wyborów
Porównywanie modeli • Różnice w efektywności pochodzą z • bardziej bezpośredniego użycia więzów bazowych • mniejszej ilości zmiennych • zwykle wymaga sprawdzenia • Inne kryteria: łatwość wprowadzania dod. ogr. • np.. Robotnik 3 pracuje nad produktem > niż rob. 2
Łączenie modeli • Można łączyć modele wyrażając relację pomiędzy zmiennymi z różnych modeli • np. B13 = 1 oznacza W1 = 3, co oznacza T3 = 1 • potencjalnie lepsza propagacja dla łączonych modeli • założymy istnienie więzu bazowego iff(V1,D1,V2,D2), który oznacza V1=D1 iff V2=D2
Modele łączone 39 prim. constraints. 5 choices to find all solutions
Przykład: przydzielanie • Dany zbiór zadań • zależności czasowe (koniec jednego przed pocz. Innego) • i dzielone zasoby (zadania na tej samej maszynie) • zaplanuj zadania, aby • więzy były spełnione • czas pracy był minimalny • Na początku pytamy, czy się da w zadanym czasie
Przykładowe dane Dane to lista zadań: task(name,duration,[names],machine) [task(j1,3,[],m1), task(j2,8,[],m1), task(j3,8,[j4,j5],m1), task(j4,6,[],m2), task(j5,3,[j1],m2), task(j6,4,[j1],m2)]
Program • Plan programu • Definicja zmiennych: makejobs • Variables: początek każdego zadania • association list: job(name,duration,StartVar) • Zależności czasowe: precedences • Więzy maszynowe: machines • Wyliczanie: labeltasks • bierze zmienne z job list oraz label
Program schedule(Data,End,Jobs) :- makejobs(Data, Jobs, End), precedences(Data, Jobs), machines(Data, Jobs), labeltasks(Jobs). makejobs([],[],_). makejobs([task(N,D,_,_)|Ts], [job(N,D,TS)|Js], End) :- TS :: [0..1000], TS + D <= End, makejobs(Ts,Js,End). getjob(JL,N,D,TS) :- member(job(N,D,TS),JL).
Zależności czasowe precedences([],_). precedences([task(N,_,P,_)|Ts],JL) :- getjob(JL,N,_,TS), prectask(P,TS,JL), prececedences(Ts,JL). prectask([],_,_). prectask([N|Ns],TS0,JL), getjob(JL,N,D,TS1), TS1 + D <= TS0, prectask(Ns,TS0,JL).
Maszyny machines([],_). machines([task(N,_,_,M)|Ts],JL) :- getjob(JL,N,D,TS), machtask(Ts,M,D,TS,JL), machines(Ts,JL). machtask([],_,_,_,_). machtask([task(N,_,_,M1)|Ts],M0,D0,TS0,JL):- (M1 = M0 -> getjob(JL,N,D1,TS1), exclude(D0,TS0,D1,TS1) ; true), machtask(Ts,M0,D0,TS0,JL). exclude(_,TS0,D1,TS1) :- D1 + TS1 <= TS0. exclude(D0,TS0,_,TS1) :- D0 + TS0 <= TS1.
Wykonywanie programu End=20, schedule(problem, End, JL). makejobs: tworzy listę zadań i więzy [job(j1,3,TS1),job(j2,8,TS2),job(j3,8,TS3), job(j4,6,TS4),job(j5,3,TS5),job(j6,4,TS6)] Początkowe dziedziny:
Wykonywanie programu precedences: dodaje więzy, zmienia dziedziny machines: dodaje punkty wyboru, zmienia dziedziny
Wyliczanie Pierwsza z brzegu wartość dla każdej zmiennej. Znalezione rozwiązanie!
Poprawianie programu • Informacja nadmiarowa • Przypuśćmy, że t1, ..., tn to zadania do wykonania na tej samej maszynie, które muszą być skończone przed t0 • t0 must start after the sum of the durations added to the earliest start time • Oblicz poprzedników każdego zadania i dodaj extra więzy • Zmniejszona przestrzeń poszukiwań
Poprawianie programu • wiez cumulative może śłużyć do wyrażenia ograniczeń ,,maszynowych’’ • cumulative([TS1,TS2,TS3],[3,8,8],[1,1,1],1) • cumulative([TS4,TS5,TS6],[6,3,4],[1,1,1],1) • Nowa wersja machines • Nie ma punktów wyboru. Wynik:
Metody wyliczania • Oryginalne sformułowanie: • Picking the minimum value for each value must be a solution. (default labelling is fine) • Dla cumulative • Znajdź zadanie z minimalnym czasem startu • albo umieść zadanie w tym momencie • albo zabroń umieszczać w tej pozycji • Powtarzaj (jakie zadanie teraz ma najmniejszy czas)
Labelling the Earliest label_earliest([]). label_earliest([TS0|Ts]) :- mindomain(TS0,M0), find_min(Ts,TS0,M0,TS,M,RTs), (TS = M, Rs=RTs ; TS != M, Rs=[TS0|Ts]), label_earliest(Rs). find_min([],TS,M,TS,M,[]). find_min([TS1|Ts],TS0,M0,TS,M,RTs) :- mindomain(TS1,M1), (M1 < M0 -> M2=M1, TS2=TS1, RTs=[TS0|Rs] ; M2=M0, TS2=TS0, RTs=[TS1|Rs]), find_min(Ts,TS2,M2,TS,M,Rs).
Labelling the Earliest Label TS1 = 0 Label TS4 = 0 Label TS2 = 3 Label TS5 = 6 Label TS6 = 9 Label TS3 = 11 Rozwiązanie (minimalne)
Więzy reifikowane • Więz reifikowanyc <=> B zmienną boolowską B z więzem bazowym c • Jeśli c to B = 1 • Jeśli c nie zachodzi to B= 0 • Propagacja w obu kierunkach • Używane do budowania złożonych więzów