1 domínios finitos em muitas problemas de interesse, não é possível aceditar soluções...

Post on 17-Apr-2015

104 Views

Category:

Documents

0 Downloads

Preview:

Click to see full reader

TRANSCRIPT

1

Domínios Finitos

Em muitas problemas de interesse, não é possível aceditar soluções fraccionárias ou reais, mas apenas soluções inteiras.

Exemplos destas aplicações incluem:• Planeamento de testes em circuitos digitais

– Para detecção/distinção de avarias• Gestão da Produção

– quantidades inteiras• Sequenciação de Tarefas (Scheduling)• Geração de Horários• Caixeiro Viajante

– Simples ou Multiplo

2

Domínios Finitos

De uma forma mais geral, as soluções não necessitam sequer ser numéricas.

Por exemplo, num problema de coloração de grafos (ou mapas) pretende-se escolher cores que não constituem um conjunto numérico (nem sequer ordenado, na interpretação habitual).

Para estes domínios, não existem resolvedores simbólicos completos, isto é, não existem procedimentos algébricos que permitam decidir se um problema é possível ou não, sendo necessário recorrer, em geral, à pesquisa de um espaço finito de soluções potenciais.

3

Satisfação Booleana - SAT

Um caso particular de domínios finitos, é o caso do domínio composto pelos valores booleanos, em que as variáveis podem tomar o valor 0/1.

No domínio da informática, a importância deste domínio é óbvia: em última análise todos os problemas são compilados para especificações codificadas em bits numa linguagem máquina a executar por um processador.

Mais praticamente, um grande número de problemas pode ser especificado através de um conjunto de expressões booleanas.

Essas expressões booleanas podem ser colocadas na forma clausal (conversão para CNF - forma normal conjuntiva).

4

Satisfação Booleana - SAT

Exemplo_1: n-rainhas

Este problema já foi analisado anteriormente. Associando-se a ausência/presença de uma rainha numa das n2 casas de um tabuleiro com n casas de lado, com uma variável 0/1, o problema é modelado através de um conjunto de dois tipos de restrições:

• Deve haver pelo menos, uma rainha num conjunto de casas (linhas e colunas)

• Deve haver no máximo uma rainha num conjunto de casas (linhas, colunas e diagonais).

Estas restrições podem ser modeladas facilmente na forma clausal.

5

Satisfação Booleana - SATR1: Deve haver pelo menos uma rainha num conjunto Q1 a Qn de casas

• 1 só cláusula:

Q1 Q2 Qn

R2: Deve haver no máximo uma rainha num conjunto Q1 a Qn de casas

• Várias (no total de n*(n-1)/2) claúsulas do tipo:

Q1 Q2 Q1 Q3 .. Q1 Qn

...

Qn-1 Qn

6

Satisfação Booleana - SAT

Exemplo_2: Coloração de Grafos

Dado um grafo não dirigido, garantir que dois nós adjacentes (ligados por um arco) têm cores diferentes.

Em primeiro lugar há que modelar a cor de um nó do grafo.

Em geral, k cores requerem ceiling(log2(k)) variáveis booleanas, ou bits, para serem representadas.

Para simplificar, assumamos a existência de 4 cores. Neste caso, como ceiling(log2(4)) = 2, são necessárias duas variáveis booleanas para representar 4 cores distintas.

Assim a cor do nó i é codificada com as variáveis booleanas Ci,1 e Ci,2.

7

Satisfação Booleana - SAT

Exemplo_2: Coloração de Grafos

Em segundo lugar há que modelar as restrições de que nós adjacentes têm cores diferentes. Considerando os nós i e j, esta restrição é modelada como

(Ci,1 Cj,1 )(Ci,2 Cj,2 )

Mas a b (a b) (a b) (a b) (a b)

Assim a restrição

[(Ci,1 Cj,1 ) (Ci,1 Cj,1 )] [(Ci,2 Cj,2 ) (Ci,2 Cj,2 )]

É equivalente às 4 cláusulas

Ci,1 Cj,1 Ci,2 Cj,2 Ci,1 Cj,1 Ci,2 Cj,2

Ci,1 Cj,1 Ci,2 Cj,2 Ci,1 Cj,1 Ci,2 Cj,2

8

Satisfação Booleana - SAT

Exemplo_3: Saco Mochila (Decisão)

Dado um conjunto de n objectos, cada um com um volume (inteiro) vi e um valor zi, verificar se numa mochila com capacidade (em volume) V podem ser colocado um conjunto de objectos com valor total não inferior a Z.

Este problema pode ser modelado através de n variáveis booleanas, Xi, em que cada uma modela a selecção (1) ou não(0) do objecto para ser colocado na mochila.

Assim, a restrição de não exceder o peso pode ser expressa como

v1 X1 + v2 X2 + ... + vn Xn =< V

9

Satisfação Booleana - SAT

Exemplo_3: Saco Mochila (Decisão)

v1 X1 + v2 X2 + ... + vn Xn =< V

Para modelar esta restrição em cláusulas, há que modelar a

• a multiplicação de um inteiro por um bit (0/1)

• a soma de valores inteiros

• a comparação (=<) de dois inteiros

Apesar de “trabalhosa”, esta modelação para a forma clausal é facilmente efectuada.

10

Satisfação Booleana - SAT

Exemplo_3: Saco Mochila (Decisão)

• a multiplicação de um inteiro por um bit (0/1)

Dado o inteiro B representado em binário pelos bits Bk a B0, a multiplicação desse inteiro pelo bit X origina o inteiro representado pelos bits Mk a M0, tais que Mi = X Bi. Esta igualdade pode ser imposta através das cláusulas

(X=0 Mi=0) ( X=1 Mi=Bi)

(X=0X=1)(X=0Mi=Bi)(Mi=0X=1)(Mi=0Mi = Bi)

(XMi= Bi) (Mi=Bi) (MiX)

MiBi)MiBi)(MiX)

(MiBi) (MiBi) MiX)

11

Satisfação Booleana - SAT

Exemplo_3: Saco Mochila (Decisão)

• a soma de valores inteiros

Dados os inteiros A e B representados em binário pelos bits ak/bk a ak/b0, a sua soma S pode ser obtida através das restrições

Primeiro bit S0 = A0 B0 C1 = A0 B0

Último bit Sn+1 = Cn+1

Outros bits Si = Ai Bi Ci

Ci+1 = (AiBi) (AiCi) (BiCi)

que se colocam na forma clausal de uma forma semelhante.

12

Satisfação Booleana - SAT

Primeiro bit

• S0 = A0 B0

(S0 (A0 B0)) (S0 (A0 B0))

(S0((A0B0)(A0 B0))) ( S0 ((A0B0)(A0B0)))

(S0A0B0 ) (S0A0B0) (S0A0B0) (S0A0B0)

• C1 = A0 B0

(C1 (A0 B0)) (C1 (A0 B0))

(C1 A0 B0) (C1 A0 ) (C1 B)

Último bit

• Sn+1 = Cn+1

(Sn+1 Cn+1) ( Sn+1 Cn+1)

13

Satisfação Booleana - SAT

Outros bits

• Si = Ai Bi Ci

(Si (Ai Bi Ci)) (Si (Ai Bi Ci))...

(Si Ai Bi Ci) (Si Ai Bi Ci)

(Si Ai Bi Ci) (Si Ai Bi Ci)

(Si Ai Bi Ci) (Si Ai Bi Ci)

(Si Ai Bi Ci) (Si Ai Bi Ci)

• Ci+1 = (AiBi) (AiCi) (BiCi)...

(Ai Bi Ci+1) (Ai Bi Ci+1)

(Ai Ci Ci+1) (Ai Ci Ci+1)

(Bi Ci Ci+1) (Bi Ci Ci+1)

14

Satisfação Booleana - SAT

Exemplo_3: Saco Mochila (Decisão)

• a comparação (=<) de dois inteiros

Dados os inteiros A e B representados em binário pelos bits Ak/Bk a A0/B0, a sua comparação (A =< B) pode ser feita através das variáveis booleanas X0 a Xk, em que Xi indica que Ai ... A0 =< Bi ... B0. Assim deveremos ter

• X0 = (A0 =< B0)

(A0 B0 X0) (A0 X0) (B0 X0)

• Xk = (Ak< Bk) ((Ak=Bk) Xk-1) para k 1...

(Ai Xi Xi-1) (Ai Xi Xi-1)

(Ai Bi Xi ) (Ai Bi Xi )

(Bi Xi Xi-1) (Bi Xi Xi-1)

15

SAT e 3SAT

Apesar de algumas cláusulas conterem mais de 3 variáveis, a satisfação de uma cláusula com mais de 3 variáveis pode ser sempre convertida, com introdução de variáveis extra, na satisfação de várias cláusulas com apenas 3 variáveis.

Exemplo: A satisfação de uma cláusula

P: A B C D

é equivalente à satisfação das cláusulas Q e R abaixo

Q: A B X e R: C D X

Para provar este resultado temos de provar que:

• P Q,R: sempre que P puder ser satisfeita Q e R tambem podem

• Q,R P: sempre que Q e R puderem ser satisfeitas P também pode

16

SAT e 3SAT

P: A B C D Q: A B X e R: C D X

Se P pode ser satisfeito, então pelo menos uma variável A a D toma o valor 1. Sem perda de generalidade consideremos que é A(C). Então a cláusula Q já está satisfeita. A outra cláusula, R, é satisfeita com X = 0(1).

Q: A B X e R: C D X P: A B C D

Como X = 0 ou X=1, se Q e R são satisfeitas, então uma das cláusulas A B (se X=0) ou C D (se X=1) é satisfeita.

Mas desta forma uma das variáveis A a D toma o valor 1, garantindo a satisfação da cláusula P: A B C D.

17

Importância de SAT

Como se pode constatar, vários problemas de decisão podem ser modelados na forma de problemas SAT.

Na realidade, qualquer problema de decisão pode ser modelado como um problema de satisfação booleana.

Desta forma, um algoritmo genérico para resolver este tipo de problemas, resolve qualquer problema de decisão.

A questão que se pode colocar é a de saber se existe um algoritmo “eficiente” para a resolução do problema de satisfação booleana (SAT).

Problema de Decisão

Problema SAT

18

Importância de SAT

Um problema SAT com n variáveis (mais rigorosamente, que se pode descrever com uma cadeia de entrada de comprimento proporcional a n) pode ser resolvido em tempo polinomial numa máquina não-determinística (isto é, que adivinha os valores correctos a atribuir às n variáveis de decisão).

Tais problemas de decisão, de que SAT é um exemplo, pertencem à classe NP.

Mais concretamente, uma máquina determinística (as que há!) pode verificar as restrições para uma solução de um problema de decisão em tempo polinomial, isto é O(nk).

19

Importância de SAT

Considerando-se n variáveis booleanas, existem 2n combinações possíveis dos seus valores.

A verificação da satisfazibilidade de um conjunto de cláusulas com n variáveis pode pois ser feita através de um procedimento de geração e teste:

• Gera-se cada uma das 2n combinações de valores;

• Testa-se cada uma dessas combinações.

Naturalmente este procedimento é muito ineficiente. No pior caso tem uma complexidade exponencial O(2n).

Naturalmente nem todos os problemas de decisão são tão complexos.

20

Importância de SAT

Para certos problemas existem algoritmos polinomiais (em n) que permitem decidir sobre a satisfação do problema.

Alguns problemas, que constituem a classe de problemas P, são claramente polinomiais.

•Por exemplo, decidir se uma lista corresponde à ordenação de outra lista com n inteiros pode ser feito com uma complexidade quadrática O(n2).

Noutros problemas não claramente polinomiais, existem instâncias particularmente simples.

•Por exemplo, o saco mochila torna-se trivial se todos os objectos tiverem o mesmo peso (não o mesmo valor!). Basta escolher primeiro os mais valiosos!

21

Importância de SAT

Naturalmente, todos os problemas P pertencem à classe NP já que se uma máquina determinística os resolve em tempo polinomial, por mais forte razão uma máquina não determinística os consegue resolver nesse tempo.

O que ainda não está demonstrado é que a classe NP contenha problemas que não são P. Este resultado é, por ora, uma simples conjectura: P ≠ NP.

Em termos práticos, não foi ainda descoberto um qualquer algoritmo que resolva qualquer problema SAT em tempo polinomial (no número de variáveis).

De um ponto de vista teórico, se tal acontecer, o que é extremamente improvável, então P=NP.

22

Importância de SAT

De um ponto de vista mais prático, se tal improvável algoritmo fôr descoberto, então todos os problemas de decisão “interessantes” passarão a ser resolvidos em tempo polinomial.

Com efeito, basta garantir que para cada problema existe um algoritmo que o transforme, em tempo polinomial, numa instância de um problema SAT.

Estas transformações podem normalmente ser feitas de uma forma semelhante À usada nos exemplos anteriores (rainhas, coloração de grafos, saco-mochila, etc.).

Este resultado é uma das razões pelas quais o problema SAT (ou 3SAT) tem sido tão estudado.

23

Importância de SAT

A generalidade da abordagem SAT, na qual qualquer problemas de decisão pode ser modelado, constitui outra das razões pelas quais o problema SAT (ou 3SAT) tem sido tão estudado.

Apesar de ser pouco provável a existência de um algoritmo que resolva qualquer instância de SAT em tempo polinomial, existem algoritmos que resolvem muito satisfatoriamente um grande número de instâncias de problemas SAT.

Em particular, existem resolvedores de SAT que já conseguem lidar com instâncias de problemas com cerca de um milhão de variáveis e dez milhões de cláusulas.

24

Resolução de 3SAT

A geração de todas as soluções pode ser obtida pelo mecanismo de retrocesso de uma linguagem de programação em lógica.

Exemplo:

teste([Q1, Q2, Q3, ..., Q16]):-

um_ou_menos([Q1,Q2,Q3,Q4]),

um_ou_mais([Q1,Q2,Q3,Q4]),

...

um_ou_menos([Q9,Q14]).

rainhas_4(L):-

geração(L),

teste(L),

report(L).

geração([]).

geração([H|T]):-

membro(H,[1,0]),

geração(T).

25

Resolução de 3SAT

Para simplicidade, no programa rainhas_sat_1gt os testes foram programados explicitamente.

1ª linha

% um_ou_menos([Q1,Q2,Q3,Q4])

~Q1 # ~Q2,

~Q1 # ~Q3, ~Q2 # ~Q3,

~Q1 # ~Q4, ~Q2 # ~Q4,

~Q3 # ~Q4

% um_ou_mais([Q1,Q2,Q3,Q4]),

Q1 # Q2 # Q3 # Q4,

26

Resolução de 3SAT

Nesse programa rainhas_sat_1gt utilizam-se as facilidades sintáticas disponíbilizadas pela Pprogramação em Lógica, nomeadamente a definição de operadores.

% declaração dos operadores booleanos

:- op(300,fy,~).

:- op(400,xfy,#).

X # Y :- exp(X # Y, Exp), Exp >= 1.

exp(X, X):- atomic(X), !.

exp(~X, 1-ExpX):- !,

exp(X, ExpX).

exp(X # Y, ExpX + ExpY):- !,

exp(X, ExpX), exp(Y, ExpY).

% verificação/teste de uma cláusula

27

Resolução de 3SAT - Retrocesso

Muitas potenciais soluções podem ser descartadas apenas por análise de uma solução parcial. Por exemplo, qualquer solução com Q1=Q2=1 pode ser descartada, já que não pode haver 2 rainhas na mesma linha.

Uma forma mais eficiente de verificar a satisfação de um problema é a utilização de um método construtivo, em que soluções parciais (em que apenas algumas variáveis têm valores atribuídos), vão sendo “completadas”, desde que não violem, por si só, nenhuma restrição.

Se a solução parcial violar restrições, ela não é completada, explorando-se, por retrocesso (backtracking), alternativas.

28

Resolução de 3SAT - Retrocesso

Se a combinação a=b=1 não satisfizer uma das restrições, não são testadas nenhumas combinações que incluam a=b=1.

A “primeira” solução <a,b,c,d>= <1,0,0,1> é encontrada evitando-se o teste de 6 folhas.

a a

b b b b

c cc c c cc c

d dd dd dd d d dd dd dd d

X

X

29

Resolução de 3SAT

A completação das soluções parciais pode ser facilmente obtida pelo mecanismo de retrocesso de uma linguagem de programação em lógica.

A questão que se coloca aqui é a de garantir que os testes sejam feitos tão cedo quanto possível. Assim,

• após instanciar as variáveis Q1 e Q2, da mesma linha, deverá ser verificado que elas não tomam ambas o valor 1.

• ...

• após instanciar a variável Q4 deve ser verificado que uma de Q1 a Q4 toma o valor 1.

30

Resolução de 3SAT

Para simplificar a exposição, esta verificação é feita de uma forma explícita no programa rainhas_sat_1bk.

lrainhas_4(_):- label(Q1), % 1ª linha label(Q2), ~Q1 # ~Q2, label(Q3), ~Q1 # ~Q3, ~Q2 # ~Q3, label(Q4), Q1 # Q2 # Q3 # Q4, ~Q1 # ~Q4, ~Q2 # ~Q4, ~Q3 # ~Q4, ...

% onde a atribuição de valor é feita através de label(Q):- mb(Q,[0,1]).

31

Resolução de 3SAT

Como é fácilmente compreensível, a programação por retrocesso é muito mais eficiente.

A contabilização quer dos testes feitos quer das atribuições efectuadas pode ser medida pela inserção de contadores.

% contagem das atribuições feitas

mb(X,[X|_]):- inc(l).

mb(X,[_|T]):- mb(X,T).

% contagem das testes feitosX # Y :- exp(X # Y, Exp), inc(t), Exp >= 1.

32

Propagação de Restrições

Uma alternativa à verificação por backtracking da compatibilidade entre cada variável e as variáveis passadas (com valor já atribuído), é geralmente muito vantajoso eliminar do domínio das variáveis futuras (com valor ainda por atribuir), os valores incompatíveis com os actualmente atribuídos.

Esta filosofia permite, em muitos casos:

• Perceber mais rapidamente a impossibilidade de completar a solução parcial

• Retroceder para as causas relevantes da falha

33

Retrocesso

Testes 0 Retrocessos 0

34

Retrocesso

Testes 0 + 1 = 1 Retrocessos 0

Q1 \= Q2, L1+Q1 \= L2+Q2, L1+Q2 \= L2+Q1.

35

Retrocesso

Testes 1 + 1 = 2 Retrocessos 0

Q1 \= Q2, L1+Q1 \= L2+Q2, L1+Q2 \= L2+Q1.

36

Retrocesso

Testes 2 + 1 = 3 Retrocessos 0

Q1 \= Q2, L1+Q1 \= L2+Q2, L1+Q2 \= L2+Q1.

37

Retrocesso

Testes 3 + 1 = 4 Retrocessos 0

38

Retrocesso

Testes 4 + 2 = 6 Retrocessos 0

39

Retrocesso

Testes 6 + 1 = 7 Retrocessos 0

40

Retrocesso

Testes 7 + 2 = 9 Retrocessos 0

41

Retrocesso

Testes 9 + 2 = 11 Retrocessos 0

42

Retrocesso

Testes 11 + 1 + 3 = 15 Retrocessos 0

43

Retrocesso

Testes 15 + 1 + 4 + 2 + 4 = 26 Retrocessos 0

44

Retrocesso

Testes 26 + 1 = 27 Retrocessos 0

45

Retrocesso

Testes 27 + 3 = 30 Retrocessos 0

46

Retrocesso

Testes 30 + 2 = 32 Retrocessos 0

47

Retrocesso

Testes 32 + 4 = 36 Retrocessos 0

48

Retrocesso

Testes 36 + 3 = 39 Retrocessos 0

49

Retrocesso

Testes 39 + 1 = 40 Retrocessos 0

50

Retrocesso

Testes 40 + 2 = 42 Retrocessos 0

51

Retrocesso

Testes 42 + 3 = 45 Retrocessos 0

52

Retrocesso

Testes 45 Retrocessos 0

Falha

6

Retrocede

5

53

Retrocesso

Testes 45 Retrocessos 1

54

Retrocesso

Testes 45 + 1 = 46 Retrocessos 1

55

Retrocesso

Testes 46 + 2 = 48 Retrocessos 1

56

Retrocesso

Testes 48 + 3 = 51 Retrocessos 1

57

Retrocesso

Testes 51 + 4 = 55 Retrocessos 1

58

Retrocesso

Testes 55+1+3+2+4+3+1+2+3 = 74 Retrocessos 1

Falha

6

Retrocede

5 e 4

59

Retrocesso

Testes 74+2+1+2+3+3= 85 Retrocessos 1+2 = 3

60

Retrocesso

Testes 85 + 1 + 4 = 90 Retrocessos 3

61

Retrocesso

Testes 90 +1+3+2+5 = 101 Retrocessos 3

62

Retrocesso

Testes 101+1+5+2+4+3+6= 122 Retrocessos 3

63

Retrocesso

Testes 122+1+5+2+6+3+6+4+1= 150 Retrocessos 3+1=4

Falha

8

Retrocede

7

64

Retrocesso

Testes 150+1+2= 153 Retrocessos 4+1=5

Falha

7

Retrocede

6

65

Retrocesso

Testes 153+3+1+2+3= 162 Retrocessos 5+1=6

Falha

6

Retrocede

5

66

Retrocesso

Testes 162+2+4= 168 Retrocessos 6+1=7

67

Retrocesso

Testes 168+1+3+2+5+3+1+2+3= 188 Retrocessos 7

Falha

6

Retrocede

5

68

Retrocesso

Testes 188+1+2+3+4= 198 Retrocessos 7+1=8

Falha

5

Retrocede

4

69

Retrocesso

Testes 198 + 3 = 201 Retrocessos 8+1=9

70

Retrocesso

Testes 201+1+4 = 206 Retrocessos 9

71

Retrocesso

Testes 206+1+3+2+5 = 217 Retrocessos 9

72

Retrocesso

Testes 217+1+5+2+5+3+6 = 239 Retrocessos 9

73

Retrocesso

Testes 239+1+5+2+4+3+6+7+7= 274 Retrocessos 9+1=10

Falha

8

Retrocede

7

74

Retrocesso

Testes 274+1+2= 277 Retrocessos 10+1=11

Falha

7

Retrocede

6

75

Retrocesso

Testes 277+3+1+2+3= 286 Retrocessos 11+1=12

Falha

6

Retrocede

5

76

Retrocesso

Testes 286+2+4= 292 Retrocessos 12

77

Retrocesso

Testes 292+1+3+2+5+3+1+2+3= 312 Retrocessos 12+1=13

Falha

6

Retrocede

5

78

Retrocesso

Testes 312+1+2+3+4= 322 Retrocessos 13+2=15

Falha

5

Retrocede

4 e 3

79

Retrocesso

Testes 322 + 2 = 324 Retrocessos 15

X1=1

X2=3

X3=5

Impossível

80

Propagação

Testes 0 Retrocessos 0

81

Propagação

1 1

1

1

1

1

11

1

1

1

1

1

1

Testes 8 * 7 = 56 Retrocessos 0

Q1 #\= Q2, L1+Q1 #\= L2+Q2, L1+Q2 #\= L2+Q1.

82

Propagação

1 1

1

1

1

1

11

1

1

1

1

1

12

2

2

2

2

2

2

2

2

2

2

Testes 56 + 6 * 6 = 92 Retrocessos 0

83

Propagação

1 1

1

1

1

1

11

1

1

1

1

1

12

2

2

2

2

2

2

2

2

2

2

3

3

3

3

3

33

Testes 92 + 4 * 5 = 112 Retrocessos 0

84

Propagação 2

1 1

1

1

1

1

11

1

1

1

1

1

12

2

2

2

2

2

2

2

2

2

2

3

3

3

3

3

33

Testes 92 + 4 * 5 = 112 Retrocessos 0

X6 só pode tomar o valor 4

85

Propagação 2

1 1

1

1

1

1

11

1

1

1

1

1

12

2

2

2

2

2

2

2

2

2

2

3

3

3

3

3

33

6

6

6

6

6 6

Testes 112+3+3+3+4 = 125 Retrocessos 0

86

Propagação 2

1 1

1

1

1

1

11

1

1

1

1

1

12

2

2

2

2

2

2

2

2

2

2

3

3

3

3

3

33

6

6

2

6

6 6

Testes 125 Retrocessos 0

X8 só pode tomar o valor 7

87

Propagação 2

1 1

1

1

1

1

11

1

1

1

1

1

12

2

2

2

2

2

2

2

2

2

2

3

3

3

3

3

33

6

6

2

6

6 6

Testes 125 Retrocessos 0

88

Propagação 2

1 1

1

1

1

1

11

1

1

1

1

1

12

2

2

2

2

2

2

2

2

2

2

3

3

3

3

3

33

6

6

2

6

6 6

8

8

Testes 125+2+2+2=131 Retrocessos 0

89

Propagação 2

1 1

1

1

1

1

11

1

1

1

1

1

12

2

2

2

2

2

2

2

2

2

2

3

3

3

3

3

33

6

6

2

6

6 6

8

8

Testes 131 Retrocessos 0

X4 só pode tomar o valor 8

90

Propagação 2

1 1

1

1

1

1

11

1

1

1

1

1

12

2

2

2

2

2

2

2

2

2

2

3

3

3

3

3

33

6

6

2

6

6 6

8

8

Testes 131 Retrocessos 0

91

Propagação 2

1 1

1

1

1

1

11

1

1

1

1

1

12

2

2

2

2

2

2

2

2

2

2

3

3

3

3

3

33

6

6

2

6

6 6

8

8

4

Testes 131+2+2=135 Retrocessos 0

92

Propagação 2

1 1

1

1

1

1

11

1

1

1

1

1

12

2

2

2

2

2

2

2

2

2

2

3

3

3

3

3

33

6

6

2

6

6 6

8

8

4

Testes 135 Retrocessos 0

X5 só pode tomar o valor 2

93

Propagação 2

1 1

1

1

1

1

11

1

1

1

1

1

12

2

2

2

2

2

2

2

2

2

2

3

3

3

3

3

33

6

6

2

6

6 6

8

8

4

Testes 135 Retrocessos 0

94

Propagação 2

1 1

1

1

1

1

11

1

1

1

1

1

12

2

2

2

2

2

2

2

2

2

2

3

3

3

3

3

33

6

6

2

6

6 6

8

8

4

5

Testes 135+1=136 Retrocessos 0

95

Propagação 2

1 1

1

1

1

1

11

1

1

1

1

1

12

2

2

2

2

2

2

2

2

2

2

3

3

3

3

3

33

6

6

2

6

6 6

8

8

4

5

Testes 136 Retrocessos 0

96

Propagação 2

1 1

1

1

1

1

11

1

1

1

1

1

12

2

2

2

2

2

2

2

2

2

2

3

3

3

3

3

33

6

6

2

6

6 6

8

8

4

5

Testes 136 Retrocessos 0+1=1

Falha

7

Retrocede

3 !

97

Propagação 2

1 1

1

1

1

1

11

1

1

1

1

1

12

2

2

2

2

2

2

2

2

2

2

3

33

3

3

3

3

3

Testes 136 Retrocessos 1

3

X1=1

X2=3

X3=5

Impossível

Testes

136

(324)

Retrocessos

1

(15)

98

Propagação de Restrições

A programação deste tipo de mecanismo num sistema de Programação em Lógica com Restrições segue o seguinte esquema.

Problema ( Vars):-

Declaração de Variáveis e Domínios,

Lançamento das Restrições,

Enumeração das Variáveis.

Desta forma sempre que fôr enumerada uma variável, os efeitos dessa enumeração são propagados automáticamente para as restrições relevantes, diminuindo os domínios possíveis para as outras variáveis.

Caso um domínio fique vazio, a pesquisa falha e é executado o retrocesso.

99

Propagação de Restrições

Este é o estilo de programação adoptado no programa rainhas_sat_1fd.

% Declaração de Domínios

domain([Q1,Q2,Q3,Q4,...,Q13,Q14,Q15,Q16],0,1)

% Lançamento de Restrições (1ª linha)

~Q1 # ~Q2, ~Q1 # ~Q3, ~Q2 # ~Q3,

~Q1 # ~Q4, ~Q2 # ~Q4, ~Q3 # ~Q4,

Q1 # Q2 # Q3 # Q4,

% Enumeração das Variáveis

labeling([], [Q1,Q2,Q3,Q4,...,Q13,Q14,Q15,Q16])

100

Propagação de Restrições

O lançamento de restrições é tratado de uma forma semelhante à anterior, mas usando operadores de relação específicos (antecedidos de #).

Desta forma, a avaliação tem em vista a redução do domínio das variáveis.

X # Y :-

exp(X # Y, Exp), Exp #>= 1.

exp(X, X):- var(X), !.

exp(X, X):- atom(X), !.

exp(~X, Exp):- !, exp(X, ExpX), Exp #= 1-ExpX.

exp(X # Y, Exp):- !,

exp(X, ExpX), exp(Y, ExpY), Exp #= ExpX + ExpY.

101

Propagação de Restrições

Por exemplo,

X | ?- domain([X,Y], 0,1), X # Y.

X in 0..1,Y in 0..1 ? ; % não pode propagar

no

?- domain([X,Y], 0,1), X # Y, X #= 1.

X = 1,Y in 0..1 ? ; % não pode propagar

no

?- domain([X,Y], 0,1), X # Y, X #= 0.

X = 0,Y = 1 ? ; % propaga de X para Y

no

?- domain([X,Y], 0,1), X + Y #> 1.

X = 1,Y = 1 ? ; % propaga para X e Y

no

102

Propagação de Restrições

Em geral a solução de um problema usando propagação de restrições é bastante mais eficiente que a alternativa de retrocesso puro.

A medição da eficiência pode ser feita pela invocação dos predicados pré-definido fd_statistics/0 e fd_statistics/2

| ?- fd_statistics. Resumptions: 28 Entailments: 2 Prunings: 23 Backtracks: 0 Constraints created: 4 yes

103

Propagação de Restrições

Para um problema tão pequeno como as 4 rainhas, as diferenças na eficiência das duas versões não são significativas.

No entanto tal não é o caso com instâncias maiores do problema.

Esta diferença pode ser verificada na execução dos programas

rainhas_sat_2bk e rainhas_sat_2fd

que são parametrizados pela dimensão do problema.

104

Domínios Finitos

Em muitas situações, e não obstante o interesse teórico e prático do problema SAT, os problemas são mais naturalmente especificados com variáveis cujo domínio não se restringe aos valores 0/1, podendo tomar outros valores (inteiros, no caso do SICStus).

Em particular, o problema das N rainhas é mais naturalmente programado com N variáveis, uma para cada linha, cujo valor denota a coluna que uma rainha deve tomar nessa linha.

Esta especificação, não só é mais natural como pode conduzir a uma substancial melhoria de eficiência.

105

Domínios Finitos

Com efeito, estas codificações representam um espaço de pesquisa de dimensão substancialmente diferente.

Domínios Booleanosk*n variáveis de valores 0/1.

Espaço de pesquisa = 2k*n.

Domínios Finitosn variáveis de valores 1..k.

Espaço de pesquisa = kn = 2log2(k)*n

Razão dos espaços de pesquisar= 2k*n / 2log2(k)*n = 2 (k-log2(k))*n

Por exemplo, com k=8 e n=8, vem r=2(8-3)*8 =240

106

Domínios Finitos

Em geral, a variação do espaço a pesquisar não é tão substancial, nomeadamente se existir uma propagação eficiente no caso dos booleanos.

Por exemplo, no caso das rainhas pode garantir-se que só uma em cada grupo de k variáveis (numa linha, coluna ou diagonal) pode tomar o valor 1. Quando isto se verificar, a propagação impõe que todas as outras tomem o valor 0, sem escolha.

No entanto, as diferenças ainda são normalmente bastante substanciais, como se pode ver nos exemplos codificados directamente em domínios finitos

rainhas_bk e rainhas_fd

107

Domínios Finitos

A eficiência das programas em domínios finitos (incluindo booleanos) podem ainda ser melhoradas pelo uso de

• Algoritmos de Propagação mais adequados

• Heurísticas para escolha

• da variável

• do valor

Estas variações podem ser verificadas na versão do programa das rainhas em domínios finitos

rainhas_fd

top related