Capítulo 5 (disponível online) - fenix.tecnico.ulisboa.pt · e.g., restrições para...

60
Satisfação de Restrições Capítulo 5 (disponível online )

Transcript of Capítulo 5 (disponível online) - fenix.tecnico.ulisboa.pt · e.g., restrições para...

Satisfação de Restrições

Capítulo 5 (disponível online)

Sumário

  Problemas de Satisfação de Restrições (CSPs, do Inglês “Constraint Satisfaction Problems”)

  Procura com Retrocesso para CSPs   Procura Local para CSPs   Estrutura dos CSPs

Problemas de Satisfação de Restrições

  Problema de Procura Tradicional:   estado é uma “caixa preta” – qualquer estrutura de

dados que suporte função sucessores, função heurística, e teste objectivo

  CSP:   estado é definido por variáveis Xi com valores do

domínio Di   Teste objectivo é um conjunto de restrições que

especificam combinações possíveis de valores para subconjuntos de variáveis

  Possível utilização de algoritmos genéricos para CSPs que são mais poderosos do que os tradicionais algoritmos de procura

Exemplo: Coloração de Mapa

  Variáveis WA, NT, Q, NSW, V, SA, T   Domínios Di = {vermelho, verde, azul}   Restrições: regiões adjacentes com cores diferentes   e.g., WA ≠ NT, ou (WA,NT) ∈ {(vermelho,verde),

(vermelho,azul), (verde,vermelho), (verde,azul), (azul,vermelho), (azul,verde)}

Exemplo: Coloração de Mapa

  Soluções são atribuições completas e consistentes, e.g., WA = vermelho, NT = verde, Q = vermelho, NSW = verde, V = vermelho, SA = azul, T = verde

Grafo de Restrições

  CSP binário: cada restrição relaciona duas variáveis   Grafo de restrições: nós são variáveis, arcos são restrições

Variáveis em CSPs

  Variáveis discretas   Domínios finitos:

  n variáveis, domínio dimensão d O(dn) atribuições completas   e.g., CSPs Booleanos, incluindo satisfação Booleana - SAT (NP-

completo)   Domínios infinitos:

  inteiros, strings, etc.   e.g., escalonamento de tarefas, variáveis têm datas de início/fim para

cada tarefa   necessidade de uma linguagem de restrições,

e.g., InícioTarefa1 + 5 ≤ InícioTarefa3

  Variáveis contínuas   e.g., datas de início/fim para observações do telescópio espacial

Hubble   restrições lineares solúveis em tempo linear usando programação

linear

Tipos de restrições

  Restrições unárias referem-se a uma variável,   e.g., SA ≠ verde

  Restrições binárias referem-se a pares de variáveis,   e.g., SA ≠ WA

  Restrições de ordem superior envolvem 3 ou mais variáveis,   e.g., restrições para cripto-aritmética

Exemplo: Cripto-aritmética

  Variáveis: F T U W R O X1 X2 X3

  Domínios: {0,1,2,3,4,5,6,7,8,9}   Restrições: Alldiff (F,T,U,W,R,O)

  O + O = R + 10 · X1   X1 + W + W = U + 10 · X2   X2 + T + T = O + 10 · X3

  X3 = F, T ≠ 0, F ≠ 0

CSPs: exemplos reais

  Problemas de atribuição   e.g., quem ensina o quê?

  Problemas de horários   e.g., que aulas são oferecidas, quando e onde?

  Escalonamento de transportes   Escalonamento do processo de fabrico

Procura Básica

  Estados são caracterizados pelas atribuições feitas até ao momento

  Estado inicial: atribuição vazia { }   Função sucessores: atribui um valor a uma variável

não atribuída que não entra em conflito com a atribuição actual falha se não existem atribuições possíveis

  Teste objectivo: atribuição actual é completa

Procura Básica

1.  Esta formulação é comum a todos os CSPs 2.  Todas as soluções para n variáveis estão à

profundidade n usar procura em profundidade primeiro

3.  Caminho é irrelevante estado final tem a solução

4.  Factor de ramificação r = (n - l ) · d para n variáveis, profundidade l e d=#D logo temos n! · dn folhas (d=#D) mas só há dn

atribuições completas!!!

Procura com Retrocesso

  Atribuições a variáveis são comutativas, i.e., [ WA = vermelho, NT = verde ] é o mesmo que [ NT

= verde, WA = vermelho ]   Só é necessário considerar atribuições a uma única

variável em cada nó r = d e existem dn folhas

  Procura em profundidade para CSPs com atribuição a uma única variável em cada nível é denominada procura com retrocesso

  Procura com retrocesso é o algoritmo básico (não informado) para CSPs

  Consegue resolver n-rainhas para n ≈ 25

Procura com Retrocesso

Função ProcuraRetrocesso (csp) devolve solução ou falha devolve ProcuraRetrocessoRecursiva({},csp)

Função ProcuraRetrocessoRecursiva(atrib,csp) devolve solução ou falha

se atrib está completa então devolve atrib var ← SeleccionaVariávelNãoAtribuída(Variáveis[csp],atrib,csp) paracada valor em OrdenaValores(var,atrib,csp) se valor consistente com atrib dadas Restricões[csp] então adiciona {var=valor} a atrib resultado ← ProcuraRetrocessoRecursiva(atrib,csp) se resultado≠falha então devolve resultado remove {var=valor} de atrib devolve falha

Retrocesso: exemplo

Retrocesso: exemplo

Retrocesso: exemplo

Retrocesso: exemplo

Melhorias ao Retrocesso

  Métodos genéricos podem trazer grandes ganhos em eficiência:   Que variável deve ser atribuída de seguida?

  Heurística do maior grau   Heurística dos valores remanescentes mínimos

  Por que ordem devem ser atribuídos os valores?   Heurística do valor menos restritivo

  Podemos detectar falhas inevitáveis com antecedência?

  Forward checking   Propagação de restrições (consistência de arcos)

Variável em mais restrições

  Heurística do maior grau (Degree Heuristic)   Escolhe a variável que está envolvida no maior número

de restrições com variáveis ainda não atribuídas   South Australia é adjacente a todas as outras regiões!

Variável com mais restrições

  Heurística dos valores remanescentes mínimos   Escolher a variável com o menor número de valores

possíveis no domínio

Valor com menos restrições

  Heurística do valor menos restritivo   Dada uma variável, escolher o valor que tem

menos restrições:   Valor que elimina menos valores no domínio das outras

variáveis

  A combinação destas heurísticas permite resolver o problema das 1000-rainhas

Forward checking

  Ideia:   Manter um registo dos valores que podem ser atribuídos

a variáveis ainda não atribuídas   Terminar a procura quando existe pelo menos uma

variável à qual não pode ser atribuído nenhum valor

  Forward checking = verificação posterior/olhar em frente

Forward checking

Forward checking

Propagação de restrições

  Forward checking propaga informação das variáveis atribuídas para as variáveis não atribuídas, mas não tem um mecanismo para detectar falhas antecipadamente:

  NT e SA não podem ser ambos azuis!   Propagação de restrições verifica restrições localmente

Consistência de Arcos

  Do Inglês “arc consistency”   Forma mais simples de propagação: assegura

consistência de arcos – e.g. arco entre X e Y   X Y é consistente sse

para todos os valores x em X existe algum valor possível y em Y

  Y X é consistente sse para todos os valores y em Y existe algum valor possível x em X

  Se uma variável V perde um valor, então os vizinhos de V têm de ser revistos

Consistência de Arcos

Consistência de Arcos

  Se X perde um valor, então os vizinhos de X têm de ser revistos

Consistência de Arcos

  Consistência de arcos detecta conflitos mais cedo do que o mecanismo de forward checking

  Pode ser usado como pré-processador ou depois de cada atribuição

  Complexidade temporal para AC-3: O(n2d3)   CSP binário tem no máximo O(n2) arcos   Cada arco pode ser inserido na fila até d vezes (uma por

cada valor de d)   Consistência de um arco é verificada em O(d2)

Algoritmo AC-3

Função AC-3(csp) devolve csp, possivelmente com domínios reduzidos variável local: fila, uma fila ao início com todos os arcos do csp

enquanto fila não está vazia (Xi,Xj) ← RemovePrimeiro(fila) se RemoveValoresInconsistentes(Xi,Xj) então paracada Xk em Vizinhos[Xi] – {Xj} adiciona (Xk,Xi) à fila

Função RemoveValoresInconsistentes(Xi,Xj) devolve verdadeiro sse remove um valor

paracada x em Domínio[Xi] se não existe nenhum valor em Domínio[Xj] que satisfaça a

restrição entre Xi e Xj então remove x de Domínio[Xi]; removido ← verdadeiro devolve removido

Retrocesso + Forward Checking

1

3

2

4

3 2 4 1

X1 {1,2,3,4}

X3 {1,2,3,4}

X4 {1,2,3,4}

X2 {1,2,3,4}

Variáveis {X1,X2,X3,X4} Domínio X1 = Dom X2 = Dom X3 = Dom X4 = {1,2,3,4} Xj = i significa que rainha j está na posição (i,j)

[Slides de B.J. Dorr - CMSC 421 course on AI]

Exemplo: 4-Rainhas

1

3

2

4

3 2 4 1

X1 {1,2,3,4}

X3 {1,2,3,4}

X4 {1,2,3,4}

X2 {1,2,3,4}

Exemplo: 4-Rainhas

1

3

2

4

3 2 4 1

X1 {1,2,3,4}

X3 { ,2, ,4}

X4 { ,2,3, }

X2 { , ,3,4}

Exemplo: 4-Rainhas

1

3

2

4

3 2 4 1

X1 {1,2,3,4}

X3 { ,2, ,4}

X4 { ,2,3, }

X2 { , ,3,4}

Exemplo: 4-Rainhas

1

3

2

4

3 2 4 1

X1 {1,2,3,4}

X3 { , , , }

X4 { ,2,3, }

X2 { , ,3,4}

Exemplo: 4-Rainhas

1

3

2

4

3 2 4 1

X1 {1,2,3,4}

X3 { ,2, ,4}

X4 { ,2,3, }

X2 { , , ,4}

Exemplo: 4-Rainhas

1

3

2

4

3 2 4 1

X1 {1,2,3,4}

X3 { ,2, , }

X4 { , ,3, }

X2 { , , ,4}

Consistência de arcos já teria detectado inconsistência!

Exemplo: 4-Rainhas

1

3

2

4

3 2 4 1

X1 {1,2,3,4}

X3 { ,2, , }

X4 { , , , }

X2 { , , ,4}

Exemplo: 4-Rainhas

1

3

2

4

3 2 4 1

X1 { ,2,3,4}

X3 {1,2,3,4}

X4 {1,2,3,4}

X2 {1,2,3,4}

Exemplo: 4-Rainhas

1

3

2

4

3 2 4 1

X1 { ,2,3,4}

X3 {1, ,3, }

X4 {1, ,3,4}

X2 { , , ,4}

Exemplo: 4-Rainhas

1

3

2

4

3 2 4 1

X1 { ,2,3,4}

X3 {1, ,3, }

X4 {1, ,3,4}

X2 { , , ,4}

Exemplo: 4-Rainhas

1

3

2

4

3 2 4 1

X1 { ,2,3,4}

X3 {1, , , }

X4 {1, ,3, }

X2 { , , ,4}

Consistência de arcos já teria identificado a solução!

Exemplo: 4-Rainhas

1

3

2

4

3 2 4 1

X1 { ,2,3,4}

X3 {1, , , }

X4 {1, ,3, }

X2 { , , ,4}

Exemplo: 4-Rainhas

1

3

2

4

3 2 4 1

X1 { ,2,3,4}

X3 {1, , , }

X4 { , ,3, }

X2 { , , ,4}

Exemplo: 4-Rainhas

1

3

2

4

3 2 4 1

X1 { ,2,3,4}

X3 {1, , , }

X4 { , ,3, }

X2 { , , ,4}

Retrocesso inteligente (I)

Retrocesso com salto:   Q = vermelho, NSW = verde, V = azul, T = vermelho, SA = … conflito!

  Retrocesso alterar valor de T   Mas T não foi responsável pelo conflito!

  Conjunto de conflito {Q,NSW,V}   Conjunto de variáveis previamente atribuídas que esvaziaram

domínio da variável que deu origem ao conflito   Retroceder “inteligentemente” para a variável que consta no

conjunto de conflito e foi atribuída mais recentemente, i.e. V   Forward checking faz o mesmo!

Retrocesso inteligente (II)

Retrocesso com salto dirigido ao conflito:

  WA = vermelho, NSW = vermelho, T = vermelho

  Atribuir NT, Q, V, SA não existe nenhuma atribuição consistente   Conjunto de conflito não resolve o

problema porque NT não fica com domínio vazio após atribuição de WA e NSW

  Logo conjunto de conflito é vazio

  Conjunto de conflito tem de ir para além de relações directas...

Retrocesso inteligente (III)

Retrocesso com salto dirigido ao conflito:   Conjunto de conflito alterado quando há retrocesso de Xj para Xi

  conf(Xi) conf(Xi) U conf(Xj) – {Xj}

  e.g. WA, NSW, T, NT, Q, V, SA   SA falha – considere-se conj. conflito {WA,NT,Q}   Retrocesso inteligente para Q – conj. conflito {WA,NT,NSW}   Retrocesso inteligente para NT – conj. conflito {WA,NSW}   Retrocesso para NSW!

Retrocesso Inteligente (IV)

  O retrocesso inteligente não evita que o mesmo conflito venha a aparecer novamente noutro ramo da árvore, e.g.   NT = vermelho, WA = vermelho, NSW = vermelho   NT = azul, WA = vermelho, NSW = vermelho

  Repetição de erros pode ser evitada com aprendizagem!   Adicionar uma restrição que não permita que volte a

acontecer WA = vermelho ∧ NSW = vermelho   WA ≠ vermelho ∨ NSW ≠ vermelho

Procura Local para CSPs

  Usar algoritmos que usam estados “completos”, i.e. todas as variáveis atribuídas

  Para aplicar procura local a CSPs:   Permitir estados em que não são satisfeitas todas as

restrições   Transições entre estados consiste na re-atribuição de

valores a variáveis   Ordenação de variáveis: seleccionar aleatoriamente

qualquer variável para a qual exista um conflito   Selecção de valores com a heurística menor

número de conflitos (min-conflicts):   Escolher valor que viola o menor número de restrições   Se existirem vários valores nestas condições escolher um

deles aleatoriamente

Exemplo: 4-Rainhas

  Estado: 4 rainhas em 4 colunas (44 = 256 estados)   Acções: mover rainhas nas colunas   Teste objectivo: não há ataques   Função de Avaliação: h(n) = número de ataques

  Dado um estado inicial aleatório, existe uma grande probabilidade de resolver o problema das n-rainhas em tempo quase constante para n arbitrário (e.g., n = 10.000.000)

Exemplo: 8-Rainhas

  Duas iterações são suficientes para resolver o problema   Em cada iteração é escolhida uma rainha que esteja em

conflito para mudar de posição   Nova posição minimiza o número de ataques (local e

globalmente)   Escolha aleatória entre posições que minimizam de igual

modo o número de ataques

Procura Local vs. Retrocesso

  Vantagens   Encontra soluções para problemas de grandes dimensões

(10.000.000 rainhas)   Tempo de execução da heurística do menor número de

conflitos está pouco dependente da dimensão do domínio

  Desvantagens   Não permite provar que não há solução porque não

mantém um registo dos estados já visitados

Comparação

  Nº de testes de consistência

Algoritmo/Problema 50-rainhas Zebra

Retrocesso >40.000 mil 3.859 mil

Retrocesso + Valores mínimos remanescentes

13.500 mil 1 mil

Forward Checking (FC) >40.000 mil 35 mil

FC + Valores mínimos remanescentes

817 mil 0.5 mil

Min-Conflitos 4 mil 2 mil

Estrutura de Problemas

  A estrutura de um problema, obtida através da representação em grafo, pode ser usada para facilitar a resolução do problema

  É importante detectar sub-problemas: melhorias no desempenho   Que decisões afectam outras decisões?   E.g. não existe nenhuma relação entre Tasmânia e as

outras regiões

Estrutura em árvore

  Teorema: se um CSP não tem ciclos, então pode ser resolvido em tempo O(nd 2) em vez de O(d n)

  Tipicamente um CSP que tem uma estrutura em árvore pode ser resolvido em tempo linear no número de variáveis

Aproximação para Árvore

  Podemos transformar um CSP numa estrutura em árvore adaptando o problema: remoção e colapsagem de nós

  Remoção de nós: atribuir valores a algumas variáveis t.q. variáveis não atribuídas formem uma árvore   Compensa se o número de variáveis a atribuir é pequeno   Identificar estas variáveis é NP-difícil! uso de aproximações   E.g. atribuir SA

Aproximação para Árvore

  Colapsagem de nós   Problema resultante

é uma árvore cujos nós são sub-problemas

  Cada sub-problema é resolvido separadamente

  Soluções resultantes são combinadas

Conclusões

  CSPs são um tipo especial de problemas:   Estados definidos por valores atribuídos a um conjunto específico de

variáveis   Teste objectivo definido a partir de restrições nos valores das

variáveis   Retrocesso = procura em profundidade primeiro com uma

variável atribuída por cada nível de profundidade   Ordenação de variáveis e selecção de valores é importante   Forward checking evita atribuições que garantidamente

levarão a conflitos no futuro   Propagação de restrições (e.g. consistência de arcos)

detecta inconsistências adicionais   Retrocesso inteligente identifica fonte do conflito   Procura local + h. menor número de conflitos é eficiente   Conhecimento da estrutura do problema pode melhorar

desempenho