Uso de não determinismo
Exemplo
Problema dos casamentos estáveis
• Existe um conjunto de N homens e um conjunto de N
mulheres que querem casar.
• Cada homem tem associada uma lista com todas as
mulheres por ordem decrescente das suas preferências
para casamento.
– Idem para cada mulher (que tem uma lista de todos os
homens por ordem decrescente das suas preferências).
• O problema é encontrar um conjunto de casamentos
que sejam todos estáveis.
• Os casamentos são instáveis se existe um homem e
uma mulher que se preferem mais entre eles que aos
seus esposos.
Instabilidade
•
•
Existe um conjunto de N homens e um conjunto de N mulheres que
querem casar.
Cada homem tem associada uma lista com todas as mulheres por ordem
decrescente das suas preferências para casamento.
– Idem para cada mulher (que tem uma lista de todos os homens por ordem
decrescente das suas preferências).
•
•
O problema é encontrar um conjunto de casamentos que sejam todos
estáveis.
Os casamentos são instáveis se existe um homem e uma mulher que se
preferem mais entre eles que aos seus esposos.
• Exemplo de par de casamentos instáveis:
Manuel : Paula (Manuel preferia a Maria)
Pedro : Maria (Maria preferia o Manuel)
N=3
Homens
Preferências
Mulheres
Preferências
Zé
Ana, Rita, Inês
Ana
Rui, Zé, Ivo
Rui
Inês, Ana, Rita
Rita
Zé, Rui, Ivo
Ivo
Ana, Inês, Rita
Inês
Zé, Ivo, Rui
Conjuntos estáveis ?
Zé : Ana
Rui : Inês
Ivo : Rita
Zé : Ana
Ivo : Inês
Rui : Rita
Rui : Ana
Ivo : Inês
Zé : Rita
X
X

Prolog
• O predicado deverá receber uma lista de homens com as
suas preferências e uma lista de mulheres com as suas
preferências e devolver uma lista de pares
homem/mulher com os casamentos.
• Um exemplo duma chamada deste predicado poderá ser:
?- casamentos(
[h(pedro,[maria,paula]), h(manuel,[paula,maria])],
[m(maria,[pedro,manuel]), m(paula,[pedro,manuel])],
C).
C = [c(pedro,maria), c(manuel,paula)] ;
no
Aproveitar o não determinismo
• Ir (não deterministicamente) gerando casais
– Testando estabilidade com os já gerados
• Gerar casais:
– Para cada homem, escolher uma mulher solteira
casamentos(Homens,Mulheres, Casais) :acasala(Homens,Mulheres, [], Casais).
acasala([],[],_,[]).
acasala([h(Homem,PrefsH)|HRest],Ms, Casados,[c(Homem,Mulher)|Cs]) :% escolher Mulher
% testar estabilidade
acasala(HRest,MRest, [c(Homem:PrefsH,Mulher:PrefsM)|Casados],Cs).
Escolher uma mulher…
• member/2 ?
– É preciso memorizar as que ainda ficam solteiras
• Solução: select/3
my_select(X, [X|R], R).
my_select(X, [H|T], [H|R]):- my_select(X, T, R).
• Ficaria: my_select(m(Mulher,_), Ms, MRest)
• Com heurística (tentar 1º as mais preferidas):
member(Mulher, PrefsH),
my_select(m(Mulher,PrefsM), Ms, MRest)
Acasalar…
acasala([],[],_,[]).
acasala([h(Homem,PrefsH)|HRest],Ms, Casados,[c(Homem,Mulher)|Cs]) :member(Mulher,PrefsH),
%Heurística: tenta 1º as + preferidas
my_select(m(Mulher,PrefsM), Ms, MRest),
% testar estabilidade
acasala(HRest,MRest, [c(Homem:PrefsH,Mulher:PrefsM)|Casados],Cs).
• Teste de estabilidade
\+ instavel(c(Homem:PrefsH,Mulher:PrefsM), Casados)
Instabilidade
𝑖𝑛𝑠𝑡á𝑣𝑒𝑖𝑠 𝐶𝑠, 𝑃𝑟𝑒𝑓𝑠 ↔
∃<ℎ1,𝑚1>,<ℎ2,𝑚2>∈𝐶𝑠 (𝑝𝑟𝑒𝑓𝑇𝑟𝑜𝑐𝑎𝑟(ℎ1, 𝑚2, 𝑃𝑟𝑒𝑓𝑠) ∨ 𝑝𝑟𝑒𝑓𝑇𝑟𝑜𝑐𝑎𝑟(ℎ2, 𝑚1, 𝑃𝑟𝑒𝑓𝑠))
𝑝𝑟𝑒𝑓𝑇𝑟𝑜𝑐𝑎𝑟 ℎ, 𝑚, 𝑃𝑟𝑒𝑓𝑠 ↔
(𝑝𝑟𝑒𝑓𝑒𝑟𝑒(ℎ, 𝑚, 𝑐𝑜𝑛𝑗𝑢𝑔𝑒 ℎ , 𝑃𝑟𝑒𝑓𝑠) ∧ 𝑝𝑟𝑒𝑓𝑒𝑟𝑒(𝑚, ℎ, 𝑐𝑜𝑛𝑗𝑢𝑔𝑒(𝑚), 𝑃𝑟𝑒𝑓𝑠))
instavel(c(H1:PrefsH1,M1:PrefsM1), [c(H2:PrefsH2,M2:PrefsM2)|_]):preferem_trocar(H1,M1, H2,M2, PrefsH1,PrefsM2)
;
preferem_trocar(H2,M2, H1,M1, PrefsH2,PrefsM1).
instavel(Casal, [_|Cs]):- instavel(Casal, Cs).
Preferir trocar
𝑝𝑟𝑒𝑓𝑇𝑟𝑜𝑐𝑎𝑟 ℎ, 𝑚, 𝑃𝑟𝑒𝑓𝑠 ↔
(𝑝𝑟𝑒𝑓𝑒𝑟𝑒(ℎ, 𝑚, 𝑐𝑜𝑛𝑗𝑢𝑔𝑒 ℎ , 𝑃𝑟𝑒𝑓𝑠) ∧ 𝑝𝑟𝑒𝑓𝑒𝑟𝑒(𝑚, ℎ, 𝑐𝑜𝑛𝑗𝑢𝑔𝑒(𝑚), 𝑃𝑟𝑒𝑓𝑠))
%H1 (casado com M1) e M2 (casada com H2)
%preferem trocar entre eles
preferem_trocar(H1,M1, H2,M2, PrefsH1,PrefsM2):antes(PrefsH1, M2,M1),
antes(PrefsM2, H1,H2).
%antes(Prefs, X,Y) :- X está antes de Y em Prefs.
antes([X|_], X,_):- !.
antes([Y|_], _,Y):- !, fail.
antes([_|L], X,Y):- antes(L, X,Y).
casamentos(Homens,Mulheres, Casais) :- acasala(Homens,Mulheres, [], Casais).
acasala([],[],_,[]).
acasala([h(Homem,PrefsH)|HRest],Ms, Casados,[c(Homem,Mulher)|Cs]) :member(Mulher,PrefsH),
%Heurística: tenta 1º as + preferidas
my_select(m(Mulher,PrefsM), Ms, MRest),
\+ instavel(c(Homem:PrefsH,Mulher:PrefsM), Casados),
acasala(HRest,MRest, [c(Homem:PrefsH,Mulher:PrefsM)|Casados],Cs).
instavel(c(H1:PrefsH1,M1:PrefsM1), [c(H2:PrefsH2,M2:PrefsM2)|_]):preferem_trocar(H1,M1, H2,M2, PrefsH1,PrefsM2)
;
preferem_trocar(H2,M2, H1,M1, PrefsH2,PrefsM1).
instavel(Casal, [_|Cs]):- instavel(Casal, Cs).
%H1 (casado com M1) e M2 (casada com H2) preferem trocar entre eles
preferem_trocar(H1,M1, H2,M2, PrefsH1,PrefsM2):antes(PrefsH1, M2,M1),
antes(PrefsM2, H1,H2).
%antes(Prefs, X,Y) :- X está antes de Y em Prefs.
antes([X|_], X,_):- !.
antes([Y|_], _,Y):- !, fail.
antes([_|L], X,Y):- antes(L, X,Y).
my_select(X, [X|R], R).
my_select(X, [H|T], [H|R]):- my_select(X, T, R).
Download

casamentos estáveis