Programação em Lógica com Restrições utilizando o SICStus Prolog Luís Paulo Reis Docente da FEUP Investigador do LIACC NIAD&R lpreis@fe.up.pt Gab. I121 / I131 Estrutura da Apresentação PLR Domínios Interface do solver CLP(FD) do SICStus Resolução de CSPs (Domínios Finitos) Restrições Disponíveis no SICStus : Enumeração e Optimização 2 PLR Domínios Booleanos e Reais PLR Domínios Domínios Finitos 3 Boleanos: Esquema clp(b) use_module(library(clpb)). Reais e Racionais Esquema clp(q,r) use_module(library(clpq)). use_module(library(clpr)). Não são abordados na disciplina de PL! 4 Esquema clp(fd). Solver clp(fd) é um instância do esquema geral de PLR( CLP) introduzido em [Jafar & Michaylov87]. Útil para modelizar problemas de optimização discreta: Escalonamento, planeamento, alocação de recursos, empacotamento, geração de horários, etc. Características do solver clp(fd): Duas classes de restrições: primitivas e globais. Restrições são automaticamente traduzidas para conjunções de restrições primitivas e globais Valor lógico de uma restrição pode ser reflectido numa variável binária (0/1) reificação. Novas restrições primitivas podem ser adicionadas escrevendo indexicais Novas restrições globais podem ser escritas em Prolog. Algumas questões abordadas Interface do Solver CLP(FD) Como chamar o Solver clp(fd)? Como escrever programas simples? Restrições disponibilizadas pelo Sictsus? Predicados para pesquisa da solução? Predicados para estatísticas de execução? Como adicionar novas restrições globais? Como criar novas restrições primitivas? O solver clp(fd) está disponível como uma biblioteca :- use_module(library(clpfd)). Contém predicados para testar a consistência e o entailment de restrições FD e para resolver o problema, atribuindo valores às variáveis do problema. Um domínio finito é um subconjunto de inteiros pequenos e um restrição FD é uma relação entre um túplode pequenos inteiros. Só pequenos inteiros são admitidos como variáveis unbound neste domínio. 5 6
Interface do Solver CLP(FD) Colocação de Restrições 7 Todas a variáveis de domínio têm um domínio FD com valores associados (explicitamente ou implicitamente). Temporariamente estes domínios podem ser infinitos (sem valores mínimo lower bound e máximo upper bound ). O domínio das variáveis vai-se reduzindo sucessivamente conforme mais restrições são adicionadas. Se o domínio ficar vazio então as restrições não são, em conjunto, satisfazíveis, e o ramo corrente de computação falha. No final da computação é usual que cada variável tenha o seu domínio restringido a um único valor ( singleton ). Para tal é usual necessária alguma pesquisa (da responsabilidade do programador). 8 Uma restrição é chamada como qualquer outro predicado Prolog Exemplos:?- X in 1..5, Y in 2..8, X+Y #= T. X in 1..5, Y in 2..8, T in 3..13? yes?- X in 1..5, T in 3..13, X+Y #= T. X in 1..5, T in 3..13, Y in -2..12? yes A resposta mostra a existência de domínios válidos para as variáveis. Resolução de CSPs Constraint Satisfaction Problems Resolução de CSPs Exemplo: SEND+MORE=MONEY CSP Constraint Satisfaction Problem ou PSR Problema de Satisfação de Restrições: Classe de problemas para que o solver clp(fd) é mais adequado Objectivo num CSP: Escolher valores (de domínios pré-definidos) para algumas variáveis de forma a que as restrições entre essas variáveis sejam todas satisfeitas. Criptograma - Send More Money Puzzle : Variáveis: letras S, E, N, D, M, O, R, Y Cada letra representa um dígito entre 0 e 9 Problema: Atribuir um valor distinto a cada dígito tal que: SEND + MORE = MONEY 9 10 Resolução de CSPs Constraint Satisfaction Problems Resolução de CSPs Exemplo: SEND+MORE=MONEY 11 Passos típicos na escrita de programa clp(fd): 1. Declarar variáveis e seus domínios 2. Colocar as restrições do problema 3. r por uma solução admissível através de pesquisa com backtracking ou uma solução óptima utilizando branch-and-bound. 12 :- use_module(library(clpfd)). puzzle([s,e,n,d,m,o,r,y]) :- domain([s,e,n,d,m,o,r,y], 0, 9), % passo 1 S#>0, M#>0, all_different([s,e,n,d,m,o,r,y]), % passo 2 sum(s,e,n,d,m,o,r,y ), labeling([], [S,E,N,D,M,O,R,Y]). % passo 3 sum(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*N + 10*E + Y.?- puzzle([s,e,n,d,m,o,r,y]). D = 7, E = 5, M = 1, N = 6, O = 0, R = 8, S = 9, Y = 2?
Resolução de CSPs Exemplo: SEND+MORE=MONEY Resolução de CSPs Exemplo: SEND+MORE=MONEY 13 Por vezes um passo extra corresponde à colocação de restrições redundantes de forma a eliminar simetrias e reduzir o espaço de pesquisa Os domínios são definidos através do predicado domain/3 Restrições simples: S#>0 e M#>0 Predicado sum/8 coloca a restrição essencial Predicado all_different/1 garante que os valores atribuídos às variáveis serão distintos. com backtrack realizada por labeling/2. Estratégias de pesquisa distintas podem ser definidas (segundo parâmetro de labeling) No exemplo é usada a estratégia por defeito: seleccionar a variável à esquerda e atribuir-lhe o valores em ordem crescente. 14 E se invertermos? Primeiro labeling, depois restringir? :- use_module(library(clpfd)). puzzle([s,e,n,d,m,o,r,y]) :- domain([s,e,n,d,m,o,r,y], 0, 9), labeling([], [S,E,N,D,M,O,R,Y]), S#>0, M#>0, all_different([s,e,n,d,m,o,r,y]), sum(s,e,n,d,m,o,r,y ). sum(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*N + 10*E + Y. Resulta no mecanismo GENERATE and TEST tradicional! Restrições Disponíveis Restrições Materializáveis Reified 15 Restrições Aritméticas Restrições de Pertença a Grupo Restrições Proposicionais Restrições definidas pelo Utilizador 16 Em vez de simplesmente colocar as restrições é útil reflectir o seu valor de verdade numa variável booleana (0/1) tal que: A restrição é colocada se B for colocado a 1 A negação da restrição é colocada se B for colocado a 0 B é colocado a 1 se a restrição se tornar entailed. B é colocado a 0 se a restrição se tornar disentailed. Este mecanismo é conhecido como reificação. Uma restrição reifiavél é escrita como:?- Constraint #<=> B. Exemplo: exactly(x,l,n) - Verdadeira se X ocorre exactamente N vezes na lista L. Pode ser defina como: exactly(_, [], 0). exactly(x, [Y L], N) :- X #= Y #<=> B, N #= M+B, exactly(x, L, M). Restrições Aritméticas Introdução Restrições Aritméticas Restrições Aritméticas Dedicadas 17 Definição:?Expr RelOp?Expr Expressões podem ou não ser lineares. Expressões lineares conduzem a maior propagação. Por exemplo: X/Y e X mod Y bloqueiam até Y estar ground (definido). Restrições Aritméticas podem ser reificadas:?- X in1..2, Y in3..5, X#=<Y #<=> B. B = 1, X in 1..2, Y in 3..5? Restrições lineares mantêm (pelo menos) consistência de intervalos e as suas versões reificadas detectam (pelo menos) entailment e desentailment de intervalos 18 As restrições seguintes expressam relações de entre a soma ou ou produto escalar e um valor: sum(+xs, +RelOp,?Value ) scalar_product(+coefs, +Xs, +RelOp,?Value ) knapsack(+coefs, +Xs,?Value) Utilizam algoritmos dedicados e são muito mais eficientes do que a colocação de uma série de restrições simples Estas restrições não podem ser reified
Restrições Aritméticas Soma e Produto Escalar Restrições Aritméticas Knapsack 19 sum(+xs, +RelOp,?Value) Onde: Xs é uma lista de inteiros ou variáveis de domínio, RelOp é um operador relacional e Value é um inteiro ou variável de domínio Verdadeira se a soma dos elementos de Xs tem a relação RelOp com Value scalar_product(+coefs,+xs, +RelOp,?Value) Onde Coefs é uma lista de comprimento n de inteiros, Xsé uma lista de comprimento n de inteiros ou variáveis de domínio, RelOp é um operador relacional e Value é um inteiro ou variável de domínio Verdadeiro se a soma de Coefs*Xstem a relação RelOp com Value 20 Caso especial de scalar_product/4 com RelOp #=: knapsack(+coefs, +Xs,?Value) Onde Coefs é uma lista de comprimento n de inteiros não negativos, Xsé uma lista de comprimento n de inteiros não negativos ou variáveis de domínio e Value é um inteiro ou variável de domínio. As variáveis de domínio devem ter limites finitos. Verdadeiro se a soma de Coefs*Xs é igual a Value Restrições de Pertença - Membership Restrições Proposicionais 21 domain(+variables, +Min, +Max) Onde Variables é uma lista de variáveis de domínio ou inteiros, Min é um inteiro ou o átomo inf ( minus infinity ), e Max é um inteiro ou o átomo sup (plus infinity). Verdadeiro se as variáveis são todas elementos do intervalo Min..Max. Não pode ser reified?x in +Range Define uma restrição de pertença ( membership ) X é um inteiro ou variável de domínio e Range é um ConstantRange Veradeiro de X é um elemento do intervalo?x in_set +FDSet Define uma restrição de pertença ( membership ) X é um inteiro ou variável de domínio e FDSet é um conjunto FD Verdadeiro de X é um elemento do FD set Restrições in/2 e in_set/2 podem ser materializadas (reified ) Mantêm consistência do domínio e as versões reified detectam domain - entailment e disentailment 22 Podem ser utilizadas como restrições reificáveis em fórmulas proposicionais sobre essas restrições Estas fórmulas são expandidas como sequências de restrições reificadas e restrições aritméticas. Exemplo: X #= 4 #\/ Y #= 6 expressa a disjunção de duas restrições de igualdade As folhas das fórmulas proposicionais podem ser restrições reificáveis, as constantes 0 ou 1 ou variáveis binárias (0/1) Novas restrições reificáveis podem ser definidas com indexicais Restrições Proposicionais Count 23 #\ :Q Verdadeiro se a restrição Q for falsa :P #/\ :Q Verdadeiro se as restrições P e Q são ambas verdadeiras :P #\ :Q Verdadeiro se exactamente uma das restrições P e Q é verdadeira :P #\/ :Q Verdadeiro se pelo menos uma das restrições P e Q é verdadeira :P #=> :Q :Q #<= :P Verdadeiro se a restrição Q é verdadeira ou se a restrição P é falsa :P #<=> :Q Verdadeiro se P e Q são ambas verdadeiras ou ambas falsas Note-se que o esquema de materialização (reification) é um caso particular das restrições preposicionais. 24 Também designadas restrições simbólicas Não são reificáveis. Mantém consistência de intervalos nos seus argumentos count(+val,+list,+relop,?count) Onde Val é um inteiro, List é uma lista de inteiros ou variáveis de domínio, Count é um inteiro ou variável de domínio, e RelOp é um operador relacional Verdadeiro se N é o número de elementos de List que são iguais a Val e N RelOp Count Ou seja: count/4 é uma generalização de exactly/3 count/4 mantém consistência de domínio, mas em geral global_cardinality( +Vars,+ Vals) é uma alternativa melhor
Global Cardinality global_cardinality(+vars,+vals) Onde: Varsé uma lista de inteiros ou variáveis de domínio e Vals é uma lista de termos V-K, onde V é um inteiro e K é uma variável de domínio ou um inteiro. Cada V deve ser único Verdadeiro se cada elemento de Vars é igual a um V e para cada par V-K, exactamente K elementos de Vars são iguais a V Se ou Vars ou Vals estão ground, e noutros casos especiais, global_cardinality/2 mantém a consistência de domínio, mas geralmente a consistência de intervalos não pode ser garantida Element element(?x,+list,?y) Onde: X e Ysão inteiros ou variáveis de domínio e List é uma lista de inteiros ou variáveis de domínio. Verdadeiro se o X-ésimo elemento de List é Y Operacionalmente os domínios de X e Y são restringidos de forma a que para cada elemento no domínio de X, existe um elemento compatível no domínio de Y, e vice versa Esta restrição usa um algoritmo optimizado para o caso especial em que List está ground element/3 mantém consistência de domínio em X e consistência de intervalos em List e Y 25 26 All Different Descrição All Different Opções 27 all_different(+variables) all_distinct(+variables) all_different(+variables, +Options ) all_distinct(+variables, +Options) onde Variables é uma lista de variáveis de domínio ou inteiros Cada variável é restringida a tomar um valor único Equivalente a uma restrição \= para cada par de variáveis Options é uma lista de zero ou mais opções 28 on(on) - Quando acordar a restrição: dom (defeito para all_distinct/[1,2]), ou seja acordar quando o domínio de uma variável é alterado min acordar quando a lower bound é mudada max acordar quando a upper bound é mudada minmax acordar quando uma bound é mudada val (defeito para all_different/[1,2]) - acordar quando uma variável fica ground consistency(cons) Que algoritmo utilizar: global (defeito para all_distinct/[1,2]) Algoritmo de consistência de domínios - aproximadamente linear na dimensão dos domínios Local (defeito para all_different/[1,2]) Algoritmo idêntico ao conjunto de restrições binárias \=, aproximadamente linear no numero de variáveis bound Algoritmo de consistência de intervalos, quase linear no número de variáveis e valores All Different - Exemplo Restrição Ordenação 29 alldifferent([]). alldifferent([a L]) :- diff(a,l), alldifferent(l ). diff(_,[]). diff(a,[b L]) :- A #\= B, diff(a,l). alldifferent([s,e,n,d,m,o,r,y]) resulta em: S #\= E, S #\= N, S #\= D, S #\= M, S #\= O, S #\= R, S #\= Y, E #\= N, E #\= D, E #\= M, E #\=O, E #\= R, E #\= Y, N #\= D, N #\= M, N #\=O, N #\= R, N #\= Y, D #\= M, D #\=O, D #\= R, D #\= Y Idêntico ao all_different(list)! 30 Esta restrição captura a relação entre uma lista de valores, uma lista de valores ordenada de forma ascendente e as suas posições na lista original: sorting(+xs,+is,+ys) Os argumentos são listas de igual comprimento (N) de variáveis de domínio ou inteiros. Os elementos de Is estão no intervalo: 1..N. A restrição verifica-se se: Ys está em ordenação ascendente Is é uma permutação de 1..N. Para cada i em 1..N, Xs[i] é igual a Ys[Is[i]]
Relation Case 31 relation(?x,+maplist,?y) Onde X e Ysão inteiros ou variáveis de domínio e MapList é uma lista de pares: Inteiro-ConstantRange, onde cada chave Inteiro ocorre só uma vez Verdadeiro se MapList contém um par X-R e Y está no intervalo denotado por R. Os domínios de X e Y são restringidos de forma a que, para cada elemento no domínio de X, existe um elemento compatível no domínio de Y, e vice versa 32 case(+template, +Tuples, +Dag) case(+template, +Tuples, +Dag, +Options) Templateé um termo arbitrário non- ground Prolog (moldura) Tuples é uma lista de termos da mesma forma que Template (não devem partilhar variáveis com Template) Dag é uma lista de nós na forma node(id,x,successors), onde X é uma variável placeholder. O conjunto de todos os X deve ser igual ao conjunto de variáveis em Template O primeiro nó da lista é a raiz (rootid) Os nós ou são nós internos ou folhas, caso em que Successors é uma lista de termos (Min..Max)-ID2, onde ID2 refere-se ao nó filho. Para as folhas, Successors é uma lista de termos (Min..Max). Cada caminho da raiz a uma folha corresponde a um conjunto de tuplos admitido pela relação expressa pela restrição. Cada variável em Templatedeve ocorrer exactamente uma vez em cada caminho e não devem ocorrer ciclos. Options é uma lista de opções utilizada para controlar a restrição: leaves, on, prune. Restrição Assignment Restrição Circuit 33 Restrição sobre duas listas de dimensão n de variáveis. Cada variável é restringida a tomar um valor entre 1,...,n que é único para a sua lista. As listas são duais. assignment(+xs, +Ys) assignment(+xs, +Ys, +Options) onde Xs e Ys são listas de variáveis de domínio ou inteiros de dimensão n Options é uma lista idêntica à de all_different/2 com valor por defeito: [on(domain),complete(true)]. Verdadeiro se todos Xi, Yi no intervalo: 1,...,n e Xi=j se e só se: Yj=i. 34 Restringir n nós num grafo a formar um circuito Hamiltoniano. Os nós estão numerados de 1 a n e o circuito começa no nó 1 e visita cada um dos nós regressando à origem: circuit(+succ) circuit(+succ, +Pred) Succ é uma lista de comprimento n de variáveis de domínio ou inteiros. O i-ésimo elemento de Succ (Pred) é o sucessor (predecessor) de i no grafo. Verdadeiro se os valores formam um circuito Hamiltoniano Restrição Serialized - Introdução Restrição Serialized - Opções 35 Restringir n tarefas, cada qual com início Sj e duração Dj, de forma a que as tarefas não se sobreponham. As tarefas podem ser vistas como competindo por recursos exclusivos serialized(+starts,+durations) serialized(+starts,+durations,+options) Starts = [S1,...,Sn] e Durations = [D1,...,Dn] são listas de variáveis de domínio com limites finitos ou inteiros. Durations tem de ser nãonegativa. Verdadeiro se Starts e Durations denotam um conjunto de tarefas que não se sobrepõem, i.e.: Para todos 1 =< i<j =< n: Si+Di =< Sj OU Sj+Dj =< Si OU Di = 0 OU Dj = 0 A restrição serialized/[2,3] é um caso especial de cumulative /[4,5] Options é uma lista de zero ou mais das seguintes: 36 precedences(ps) restrições de precedência como lista de termos na forma: d(i,j,d), onde i e j devem ser números de tarefas e d um inteiro positivo ou sup, denotando: Si+d =< Sj OU Sj =< Si, se d for um inteiro Sj =< Si, se d for sup resource(r) R é unificado com um termo passado a order_resource/2 de forma a procurar uma ordenação consistente para as tarefas path_consistency(boolean) Se for verdadeiro um algoritmo redundante de consistência nos caminhos é utilizado na restrição para melhorar o corte no espaço de pesquisa static_sets(boolean) Se for veradeiro, um algoritmo redundante é utilizado que raciocina sobre o conjunto de tarefas que devem preceder (ou ser precedidas por) uma dada tarefa Outras opções: edge_finder(boolean), decomposition(boolean), bounds_only(boolean)
Restrição Serialized/3 Restrição Cumulativa A 37 serialized/3 pode modelizar um conjunto de tarefas que têm de ser serializadas (escalonadas) com tempos de setup dependentes da sequência Por exemplo, com 3 tarefas todas com duração 5, onde a tarefa 1 deve preceder a 2 e a tarefa 3 deve acabar antes da 2 ou começar 10 unidades de tempo depois da 2 começar:?- domain([s1,s2,s3], 0, 20), serialized([s1,s2,s3], [5,5,5], [precedences([d(2,1,sup),d(2,3,10)])]). S1 in 0..15, S2 in 5..20, S3 in 0..20? Os limites de S1 e S2 mudaram devido às restrições de precedência. Colocando S2 a 5 propaga S1=0 e S3 em 15..20. 38 Restringir n tarefas a ser realizadas no tempo em m máquinas. Cada máquina tem um limite de recursos. As tarefas são representadas por um termo O,D,E,H,M onde: O é o starttime, D a duração, E o end time, H o consumo de recursos e M o identificador da máquina As máquinas são representadas por termos: machine(m,l) onde M é um identificador e L é o limite de recursos da máquina Todos os campos são variáveis de domínio ou inteiros. L é um inteiro D deve ser não -negativo, mas H pode ser positivo ou negativo (interpretado como um consumo negativo, ou seja uma oferta de recurso) cumulatives(+tasks,+machines) cumulatives(+tasks,+machines,+options) Options é uma lista de: bound(b ), prune(p), generalization(boolean) e task_intervals(boolean) Restrição Cumulativa B Restrição Disjoint 39 Restringir n tarefas com início (start time) Sj, e duração Dj, e recursos Rj, de forma que o consumo de recursos não exceda Limit em qualquer altura: cumulative(+starts,+durations,+resources,?limit) cumulative(+starts,+durations,+resources,?limit,+options) Starts = [S1,...,Sn], Durations = [D1,...,Dn], Resource = [R1,...,Rn] são listas de variáveis de domínio ou inteiros, e Limit é uma variável de domínio ou um inteiro. Durations, Resources e Limit devem ser nãonegativas. Sendo: a = min(s1,...,sn), b = max(s1+d1,...,sn+dn) Rij = Rj, se Sj =< i < Sj+Dj Rij = 0 caso contrário A restrição não é violada se: Ri1+...+Rin =< Limit, para todos: a =< i < b Options tem a mesma forma de serialized/3, excepto resource(r ) 40 Conjunto de rectângulos ou linhas que não se devem sobrepor: disjoint1(+lines) disjoint1(+lines,+options) OndeLines é umalista de termos F(Sj,Dj) ou F(Sj,Dj,Tj), Sj e Dj são variáveis de domínio ou inteiros denotandoa origem e comprimentodalinha j respectivamente, F é um qualquer functor, e Tj é um termo atómicoopcional denotando o tipo de linha Options é uma lista de: decomposition(boolean), global(boolean), wrap(min,max), margin(t1,t2,d) Predicados de Enumeração Predicados de Optimização 41 Usualmente os solvers de restrições em domínios finitos não são completos, ou seja, não garantem que o conjunto de restrições é satisfazível! É necessário pesquisa (enumeração) para verificar a satisfabilidade e conseguir soluções concretas! Predicados para efectuar a pesquisa: labeling(:options, +Variables) Onde Variables é uma lista de variáveis de domínio ou inteiros e Options é uma lista de opções de pesquisa. Verdadeiro se uma atribuição de valores às variáveis que satisfaça todas as restrições pode ser encontrada indomain(?x) Onde X é uma variável de domínio ou um inteiro. Atribui numa ordem ascendente com backtracking valor admissíveis a X 42 Predicados de Optimização (Minimização/Maximização) de um Custo/Lucro: minimize(:goal,?x) maximize(:goal,?x) Utiliza o algoritmo branch-and-bound, com recomeço, para procurar uma atribuição que minimize/maximize a variável de domínio X. Goal deve ser um predicado Prolog que restrinja X a ficar com um valor, podendo ser um predicado labeling/2. O algoritmo chama Goal repetidamente com uma upper (lower) bound de X progressivamente mais restringida até a prova de optimalidade ser obtida (o que por vezes é demasiado demorado ) O argumento Options de labeling/2 controla a ordem de selecção de variáveis e valores e o tipo de solução a encontrar (única, óptima, etc.)
Opções de Ordenação de Variáveis 43 Options do labeling estão divididas em quatro grupos: Ordenação de variáveis: leftmost, min, max, ff, ffc ou variable(sel) Forma de Selecção de valores: step, enum, bisect, value(enum) Ordenação de valores: up, down Soluções a encontrar: all, minimize, maximize 44 Opções de Ordenação de variáveis: leftmost variável à esquerda (por defeito) min variável com menor lower bound max variável com maior upper bound ff - first-fail principle é usado variável com o menor domínio ffc - most constrained heuristic variável com o menor domínio, quebrando empates seleccionando a variável envolvida em mais restrições suspendidas variable(sel) Em que Sel é um predicado para seleccionar a próxima variável, chamado como: Sel(Vars, Selected, Rest) Sel deve suceder deterministicamente unificando Selected e Rest com a variável seleccionada e a lista restante Ordenação de Valores Ordenação de Valores 45 Opções de selecção de valores para uma variável: step - escolha binária entre X #= B e X #\= B, onde B é a lower ou upper bound de X. (opção por defeito) enum - Escolha múltipla para X correspondendo a valores no seu domínio bisect Escolha binária entre X #=< M e X #> M, onde M é o ponto médio do domínio de X (Divisão de domínio) value(enum) Enum é um predicado que deve reduzir o domínio de X, chamado como: Enum(X, Rest, BB0, BB) onde Rest é a lista de variáveis que necessitam de labeling excepto X, e BB0 e BB são: (ver slide seguinte) 46 Enum deve suceder de forma não-determinística reduzindo o domínio de X e efectuar backtrack, providenciando formas de redução de domínio alternativas Para assegurar que a pesquisa branch-and-boundfunciona correctamente deve chamar o predicado auxiliar: first_bound(bb0,bb) na sua primeira solução e later_bound(bb0,bb) em qualquer solução alternativa Enum deve ser um termo executável Opções na ordenação de valores (sem utilidade com a opção value(enum)): up ordenação ascendente (por defeito) down ordenação descendente Maximização e Minimização Maximização e Minimização 47 As opções seguintes controlam se todas as soluções devem ser enumeradas por backtracking ou se uma única solução que maximize(minimize) X deve ser encontrada: all - Todas as soluções são encontradas (por defeito) minimize(x) solução de custo mínimo maximize(x) solução de lucro máximo Utiliza o algoritmo branch-and-bound com recomeço para procurar uma atribuição que minimize ou maximize a variável de domínio X. O mecanismo de labeling deve restringir X a ficar com um valor para todas as atribuições de Variables. Opção: assumptions(k) Quando uma solução é encontrada, K é unificada com o número de escolhas feito 48 Exemplo 1: Enumerar soluções com ordenação de variáveis estática:?- constraints(variables), labeling([ ], Variables). [ ] é o mesmo que: [leftmost,step,up,all ] Exemplo 2: Minimizar uma função de custo utilizando pesquisa branchand-bounde ordenação dinâmica de variáveis usando o first-fail principle, e divisão de domínio explorando a parte superior dos domínios primeiro:?- constraints(variables, Cost), labeling([ff,bisect,down,minimize(cost)], Variables).
Maximização e Minimização Estatísticas Predicados de Estatísticas 49 de ordenação consistente de tarefas competindo por recursos exclusivos (em vez de atribuição de valores a variáveis de domínio): order_resource(+options, +Resource) Options é uma lista de opções de pesquisa e Resource representa um recurso como em serialized/3 no qual as tarefas devem ser serializadas. Verdadeiro se a ordenação total pode ser imposta nas tarefas, enumerando utilizando backtracking Opções de pesquisa: first, last selecção de tarefas para serem colocadas antes(depois) de todas as outras est Tarefas ordenadas por earliest start time. ist - Tarefas ordenadas por latest start time. ect - Tarefas ordenadas por earliest completion time. ict - Tarefas ordenadas por latest completion time. [first,est] (por defeito) e [last,lct] podem ser boas heurísticas. 50 Estatísticas de execução: fd_statistics(?key,?value) Estatísticas específicas do solver CLP(FD) Outras estatísticas (por exemplo tempo e consumo de memória): statistics/2 (normal) Para cada chave possível (Key), Value é unificado com o valor da estatística: Resumptions Número de vezes que uma restrição foi reatada Entailments Número de vezes que um (dis)entailment foi detectado por uma restrição Prunings Número de vezes que o domínio foi reduzido ( pruned ) Backtracks Número de vezes que foi encontrada uma contradição num domínio e falha foi detectada Constraints Número de restrições criadas fd_statistics Mostra um resumo das estatísticas a cima Conclusões Metodologia de resolução em PLR: Definição de variáveis e domínios, colocação de restrições, pesquisa da solução) SICStus Prolog providencia um grande número de restrições globais com aplicações distintas (all_distinct, sum, scalar_product, global_cardinality, element, cumulative, circuit, etc.) Possibilidade de definição de métodos de ordenação de variáveis e valores alternativos Possibilidade de resolução de problemas de optimização (maximização/minimização) 51