programming search. overview u preliminary: eliminating general disjunctions u classification of...
Post on 23-Jan-2016
216 views
TRANSCRIPT
Programming Search
Overview
Preliminary: eliminating general disjunctions Classification of search methods Heuristic tree search Incomplete tree search Optimization The Repair Library
Search
Search is the default mechanism to deal with
disjunctions
The simplest form of disjunction is a domain
declaration: X::1..3
Other disjunctions:neighbour(X,Y) :- X #= Y+1.neighbour(X,Y) :- X #= Y-1.
It would be nice to have all disjunctions in the form of
domain variables: more uniform and flexible!
Eliminating general disjunctions Eliminate choice points from constraint model
Introduce decision variables for choices (often Boolean) Defer choice-making until search phase
General delay method in ECLiPSeneighbour(X,Y,0) :- X #= Y+1.
neighbour(X,Y,1) :- X #= Y-1.
?- suspend(neighbour(X,Y,B),3,B->inst).
Arithmetic methodneighbour(X,Y,B) :-
X #>= Y-1, X #=< Y+1,
B :: 0..1,
X #>= Y-1 + 2*B, X #=< Y-1 + 2*B.
Now all disjunctions correspond to domain variables!
Search Spaces
We assume Problem formulated in terms of variables and constraints
Variables have domains (capturing the choices)
An assignment assigns values (from the domain) to variables
Total assignment: every variable has a (fixed) value
A solution is a total assignment that satisfies all constraints
The search space is the set of all possible total assignments
Overview
Preliminary: eliminating general disjunctions Classification of search methods Heuristic tree search Incomplete tree search Optimization The Repair Library
Exploring Search Spaces
Search Methods:
Complete vs Incomplete
Constructive vs Move-based
Random vs Systematic
solution no solution
Exploring search spaces
Tree search:• constructive (partial/total assignments)• systematic• complete or incomplete
“Local” search:• move-based (only total assignments)• random or systematic• incomplete
partial assignments
Search tree All disjunctions correspond to domain variables Search tree: X
Y
Z
We restrict ourselves to depth-first search
Depth-first search is done by backtrackinglimited flexibility in visiting the nodesbut the only(?) memory-efficient general complete search
method
Some of these leaf nodes are our solutions!
Backtracking: Degrees of Freedom Variable selection
X
Y X
Y
Value selection
1
2
3
4
2
4
3
1
1,1 1,2 1,3 1,4 2,1 2,2 2,3 2,4 1,1 2,1 1,2 2,2 1,3 2,3 1,4 2,4
X::1..2, Y::1..4
Basic search code (built-in)
labeling(AllVars) :-
( fromto(AllVars, [X|RestVars], RestVars, []) do
indomain(X) % choice here
).
indomain(X) :-
get_ic_domain_as_list(X, Values),
member(Value, Values),
X = Value.
Advanced search code (template)
labeling(AllVars) :-
static_preorder(AllVars, OrderedVars),
( fromto(OrderedVars, Vars, RestVars, [])
do
select_variable(X, Vars, RestVars),
get_domain_as_list(X, Values),
select_value(Value, Values), % choice here
X = Value
).
Example: N-Queens
Our model:
queens(N, Board) :- length(Board, N), Board :: 1..N, ( fromto(Board, [Q1|Cols], Cols, []) do ( foreach(Q2, Cols),
count(Dist,1,_), param(Q1) do noattack(Q1, Q2, Dist) ) ).
noattack(Q1,Q2,Dist) :-Q2 #\= Q1,Q1 - Q2 #\= Dist,Q2 – Q1 #\= Dist.
N-Queens: Propagation and search
Constraint Propagation• eliminates choices• e.g. instantiates 6th
queen
Naive search• Alright for 8 queens• 0.01s first solution• 0.2s all 92 solutions
Forward Checking 32-Queens
Naive search > 100 secsdespite propagation...
Overview
Preliminary: eliminating general disjunctions Classification of search methods Heuristic tree search Incomplete tree search Optimization The Repair Library
Improving Search using Heuristics
General-purpose heuristic: “first-fail” Focus on Bottleneck Label variable with smallest domain first Forward-checking enhances first-fail Quite general, works almost always
Queens-specific heuristic Start in the middle
Improving search for Queens
:- lib(ic_search).
labeling_a(AllVars) :-
( fromto(AllVars, Vars, RestVars, []) do
Vars = [Var|RestVars],
indomain(Var)
).
labeling_b(AllVars) :-
( fromto(AllVars, Vars, RestVars, []) do
delete(Var, Vars, RestVars, 0, first_fail),
indomain(Var)
).
Improving search for Queens
labeling_d(AllVars) :-
middle_first(AllVars, AllVarsPreOrdered),
( fromto(AllVarsPreOrdered, Vars, VarsRem, []) do
delete(Var, Vars, VarsRem, 0, first_fail),
indomain(Var)
).
labeling_e(AllVars) :-
middle_first(AllVars, AllVarsPreOrdered),
( fromto(AllVarsPreOrdered, Vars, VarsRem, []) do
delete(Var, Vars, VarsRem, 0, first_fail),
indomain(Var, middle)
).
N-Queens - Comparison of Heuristics
Number of backtracks
N = 8 12 14 16 32 64 128 256
labeling_a 10 15 103 542 - - - -
labeling_b 10 16 11 3 4 148 - -
labeling_d 0 0 1 0 1 1 3 - -
labeling_e 3 3 38 3 7 1 0 0 0
- = timeout
Vars = [Var|VarsRest] delete(Var, Vars, VarsRest, 0, input_order)
select first variable in the list. delete(Var, Vars, VarsRest, 0, first_fail)
select variable with smallest domain. delete(Var, Vars, VarsRest, most_constrained)
select variable with smallest domain which is involved in the largest number of constraints.
delete(Var, Vars, VarsRest, 0, smallest) select the variable which has the smallest value in its domain.
Useful for scheduling.
Variable selection primitives
Binary choiceX=0 ; X=1
EnumerateX=1 ; X=2 ; X=3 ; X=4
indomain(X)
indomain(X, Order)Order is one of: min, max, middle, split, random, …
Value selection ...
Any disjunction that partitions the search space:split_domain(X) :-
get_ic_bounds(X, Low, High),Split is (High+Low)//2,( X #<= Split ; X #> Split ).
A la MIP:( X #<= floor(LpSol) ; X #>= ceiling(LpSol)).
Heuristics:( X = SuggestedX ; X #\= SuggestedX ).
Caution: eventually all variables need to be
instantiated!
... and other choices
Why is search strategy so important?
Benefits in optimization context good early cost bounds cut the search
Early decomposition into subproblems if problem is exponential, solving and recombining subproblems is
always cheaper than solving the whole
Breaking cycles in the constraint network cycles make constraint propagation expensive
Overview
Preliminary: eliminating general disjunctions Classification of search methods Heuristic tree search Incomplete tree search Optimization The Repair Library
Incomplete Tree Search Tree search is normally complete
needs only a stack for systematic, complete traversal tree can be reshaped by variable and value selection but possible traversal orders are restricted
Incompleteness by ignoring sub-trees, e.g.
first solution only time-out bounded backtracks
limited credit limited discrepancy
Predefined incomplete strategies (1)
search/6 in lib(ic)
Bounded-backtrack search:
Depth-bounded, then bounded-backtrack search:
Predefined incomplete strategies (2)
Credit-based search:
Limited Discrepancy Search:
Predefined Search Routine search/6 in lib(ic)
search(List, VarIndex, VarSelect, ValSelect, Method, Options)
List of variables (or structures containing variables) 0 (or variable index within the structures) Variable selection strategy: input_order, first_fail, … Value selection strategy: indomain, indomain_middle, split, … Tree search method: complete, bbs, credit, dbs, lds, … Options, e.g. counting backtracks
search/6 in lib(ic)
search(List, 0, first_fail, choose(In,Out), complete, [])
List of variables 0 Variable selection strategy: first_fail Value selection strategy: choose(In,Out) Tree search method: complete Options: []
Pattern using Predefined Search Routine
A Pattern for Incomplete Search
search(List, Type, Credit) :- search(List,0,first_fail, choose(Type-Credit,_), complete,[]).
choose(Var, Type-Credit, Type-NCredit) :- get_domain_as_list(Var,Dom), share(Type, Dom, Credit, DomCredList), member(Var-NCredit, DomCredList).
First N Values
Select a variable Allocate credit to each value in the variable’s domain Choose a value
Incoming Credit:
Allocated credit:
3
3 3 3 0 0 0
Best N
First N Values
share(firstN,DomList,N,BestList) :- ( fromto(N, TCred, NCred, 0), fromto(DomList, [Val|Tail], Tail, _), foreach(Val-N, BestList), param(N) do ( Tail = [] -> NCred is 0 ; NCred is TCred-1 ) ).
Credit-Based Search – Binary Chop
Select a variable Allocate credit to each value in the variable’s domain Choose a value
Credit Based Search
Incoming Credit:
Allocated credit:
16
8 4 2 1 1 0
Credit-Based Search - Binary Chop
share(cbs, DomList, InCredit, DomCredList) :- ( fromto(InCredit, TCredit, NCredit, 0), fromto(DomList, [Val|Tail], Tail, _), foreach(Val-Credit, DomCredList) do Credit is fix(ceiling(TCredit/2)), ( Tail = [] -> NCredit = 0 ; NCredit is TCredit - Credit ) ).
Limited Discrepancy Search
Select a variable Allocate credit to each value in the variable’s domain Choose a value, and take its credit
Incoming Credit:
Allocated credit:
2
2 1 0 0 0 0
Limited Discrepancy Search
Limited Discrepancy Search
share(lds,DomList,InCredit,DomCredList) :- ( fromto(InCredit,TCred,NCred,0), fromto(DomList,[Val|Tail],Tail,_), foreach(Val-TCred,DomCredList) do ( Tail = [] -> NCred is 0 ; NCred is TCred - 1 ) ).
Overview
Preliminary: eliminating general disjunctions Classification of search methods Heuristic tree search Incomplete tree search Optimization The Repair Library
First Solution, All Solutions
first(Vars) :-
setup_constraints(Vars),
once labeling(Vars).
all(AllSolutions) :-
setup_constraints(Vars),
findall(Vars, labeling(Vars), AllSolutions).
write_all :-
setup_constraints(Vars),
(
labeling(Vars),
writeln(Vars),
fail
;
true
).
Best Solution: Optimization
Branch-and-bound method finding the best of many solutions without checking them all :- lib(branch_and_bound).
Search code for all-solutions can simply be wrapped into the optimisation primitive: minimize(labeling(Vars), Cost) bb_min(labeling(Vars), Cost, Options)
Options: Strategy: continue, restart, dichotomic Initial cost bounds (if known) Minimum improvement (absolute/percentage) between
solutions Timeout
Branch-and-bound (incremental)
Lower bound(relaxed solution)
Cost
1
First solution
Better solution
2Iterations:
Solu-tions
3
Optimal solution
4
No solution
Search space size 5, unlucky ?- X::1..5, Cost #= 6-X, minimize(labeling([X]), Cost).Found a solution with cost 5Found a solution with cost 4Found a solution with cost 3Found a solution with cost 2Found a solution with cost 1X=5Cost=1
Search space size 5, lucky?- X::1..5, Cost #= X, minimize(labeling([X]), Cost).Found a solution with cost 1X=1Cost=1
Impact of search strategy on b&b
Branch-and-bound (dichotomic strategy)
2
No solution
5Iterations:
Solu-tions
Cost
First solution
1
Better solution
3 4
Lower bound(relaxed solution)
6
Optimal solution
Using dichotomic b&b strategy Part of search space (solution 4) skipped:
?- X::1..5, Cost #= 6-X, bb_min(labeling([X]), Cost,
bb_options with strategy:dichotomic).
Found a solution with cost 5
Found a solution with cost 3
Found a solution with cost 2
Found a solution with cost 1
X = 5
Cost = 1
All solutions, timing and counting
all :-
setup_constraints(Vars),
Tstart is cputime,
setval(solutions, 0), % a non-logical counter
(
labeling(Vars), % search
incval(solutions), % solution found
fail % backtrack
;
true
),
getval(solutions, Sols),
Time is cputime - Tstart,
printf("%w solutions found in %w seconds\n", [Sols,Time]).
Computing the remaining search space
labeling(AllVars) :-
( fromto(OrderedVars, [X|RestVars], RestVars, []) do
indomain(X),
search_space_size(RestVars, Size),
printf("Remaining search space: %d\n", Size)
).
search_space_size(List, Size) :-
( foreach(X, List), fromto(1,Size0,Size1,Size) do
get_ic_domain_size(X, SizeX),
Size1 is Size0*SizeX
).
Counting backtrackslabeling(AllVars) :-
setval(backtracks, 0),
( fromto(AllVars, [X|RestVars], RestVars, []) do
count_backtracks,
indomain(X)
),
getval(backtracks, BT),
printf("Solution found after %d backtracks.\n", BT).
count_backtracks :-
setval(deep_fail,false).
count_backtracks :-
getval(deep_fail,false),
setval(deep_fail,true),
incval(backtracks),
fail.
There are different ways of counting.This method has these properties:• immediate failure due to propagation
does not count as a backtrack• the optimal value for N solutions is N
You don’t have to understand this !
Counting Backtracks for all Solutions
count_backs(Vars,VarCh,ValCh,Method,Backtracks) :- findall(B, search(Vars,0,VarCh,ValCh,Method,[backtrack(B)]), List), last(List,Backtracks).
last([H],H) :- !.last([_H|T],L) :- last(T,L).
Overview
Preliminary: eliminating general disjunctions Classification of search methods Heuristic tree search Incomplete tree search Optimization The Repair Library
58
Overview
Context and Motivation
Tentative Values, and Conflicts
Tree Search and Local Search for an Example Problem
Combining Local Search and Tree Search
Conclusion
Constraint Logic Programming
[X,Y]::0..1,
X + Y >= 1,X = Y,
label([X,Y]).
Define Decision Variables
Constrain Decision Variables
Search for a Solution
X=0
Y=0 Y=1
X=1
Y=0 Y=1
60
Algorithms using Inconsistent States
One Basic Technique Start with “good” inconsistent solution Increase consistency incrementally
Applications Repair Problems
“good” inconsistent solution: the previous solution Repair-Based Constraint Satisfaction
“good” inconsistent solution: the partially consistent soln. found by heuristics Repair-Based Constraint Optimization
“good” inconsistent solution: a good soln. with respect to optimization function Hybridization
“good” inconsistent solution: a good soln. produced by a partial solver
61
Overview
Context and Motivation
Tentative Values, and Conflicts
Tree Search and Local Search for an Example Problem
Combining Local Search and Tree Search
Conclusion
Tentative Assignments
Define Decision Variables
Constrain Decision Variables
Search for a Solution
X::1..10
X=4
LogicalAssignment
TentativeAssignment
X tent_set 8
X tent_set 4
Fail Record Conflict
“X>=5”
Problem Modelling and Solving
Initialise Decision Variables
Constrain Decision Variables
Search for a Solution
Tree Search Local Search
Vars::Domain Vars tent_set Vals
ic: <Cons> <Cons> r_conflict Store
ic: labeling(Vars) repair(Store)
Tentative Invariants
Initialise Decision Variables
Constrain Decision Variables
During Search …
[X,Y] tent_set [1,2]
Either: Y =:= X+1 r_conflict a
X tent_set 3
Or: Y tent_is X+1
Record Conflict
Y{4}
65
Overview
Context and Motivation
Tentative Values, and Conflicts
Tree Search and Local Search for an Example Problem
Combining Local Search and Tree Search
Conclusion
Knapsack Problem
N - the number of items (integer)
Profits - a list of N integers (profit per item)
Sizes - a list of N integers (size per item)
Capacity - the capacity of the knapsack (integer)
Opt - the optimal result (output)
knapsack(N, Profits, Weights,Capacity, Opt)
8 12
615
1020
:- lib(repair).
Local Search
r_conflict cap,
tent_is
local_search_opt(cap, Vars, Opt).
knapsack(N, Profits, Weights, Capacity, Opt) :-
length(Vars, N), % N boolean variables
Capacity >= Weights*Vars % constraint
Opt Profits*Vars, % the objective
% search minimize(labeling(Vars), -Opt).
ic:
ic: =:=
:- lib(ic), lib(branch_and_bound).
Tree Search
Vars :: 0..1,
Knapsack Problem
=
69
Local Search - algorithm template
local_search: set starting state while global_condition while local_condition select a move if acceptable do the move if new optimum remember it endwhile set restart state endwhile
70
Local Search instances
Algorithm parameters: starting (and restarting) state
global and local condition
possible moves and how to select one
when is a move accepted Different parameters yield different algorithms:
random walk hill climbing simulated annealing tabu search ... and many variants
72
Techniques used here
Move operation and acceptance test: They are within the condition part of the if-then-else construct, so: If the acceptance test fails (no solution or objective not improved)
the move is automatically undone by backtracking!
Detecting solutions: Constraint satisfaction is checked by checking whether the conflict
constraint set is empty
Monitoring cost/profit: Retrieve tentative value of Profit-variable before and after the move
to check whether it is uphill Since the move changes the tentative values of some variable(s),
tent_is/2 will automatically update the Profit variable!
77
Overview
Context and Motivation
Tentative Values, and Conflicts
Tree Search and Local Search for an Example Problem
Combining Local Search and Tree Search
Conclusion
78
A Tentative Assignment
The Conflict Region
Changed Variables
Remaining Variables
Conflict Regionof Violated Constraints
Tree Search Employing Tentative Assignments
a
c
c
a
b
c
b
c
c
a
Search with Tentative Assignments
Initialise Decision Variables
Constrain Decision Variables
Search for a Solution
Vars tent_set Vals
<Cons> r_conflict a
search(a) :-( find_conflict( a, Var) ->
search(a) ; true ).
change_tent_val(Var),
Local
Vars::Domain,
ic: <Cons>
ic:indomain(Var),
Tree
And with Finite Domains
81
Tutorial Example: Bridge Scheduling
Schedule tasks to build a bridge Schedule consists of different tasks that share several resources
(eg. excavator, pile-driver)
Some tasks depend on others
Temporal Constraints e.g time for concrete to set
Disjunctive resource constraints pile-driver can only be used in one task at a time
82
T2 T3 T4 T5
The Bridge Scheduling ProblemT1
M1 M2 M3 M4 M5 M6
B1S1
B2S2
B3S3
B4S4
B5S5
B6S6
P1 P2
A1
A2A3 A4 A5
A6
83
Bridge Scheduling ProblemNo. Name Description Duration Resource1 PA Beginning of project 0 -2 A1 Excavation (abutment 1) 4 excavator3 A2 Excavation (pillar 1) 2 excavator…8 P1 Foundation Piles 1 20 pile-driver9 P2 Foundation Piles 2 13 pile-driver10 U1 Erection of temporary housing 10 -11 S1 Formwork (abutment 1) 8 carpentry…17 B1 Concrete Foundation (abut. 1) 1 concrete-mixer…23 AB1 Concrete Setting Time (abut 1) 1 -…29 M1 Masonry work (abutment 1) 16 bricklaying…35 L Delivery of preformed Bearers 2 crane36 T1 Positioning (preformed bearer 1) 12 crane…42 V1 Filling 1 15 caterpillar…46 PE End of Project 0 -
Temporal constraints on the Schedule
Precedence before(Start1,Duration1,Start2)
Maximal delay before(Start2,-Delay,Start1)
before(Start1,Duration1,Start2) :- Start1 + Duration1 #=< Start2
85
Resource Constraints
Start End
Machine
Tasks
D1
D2
D3
D4
D5
noclash(S1,D1,S2,D2) :- S1#>=S2+D2.noclash(S1,D1,S2,D2) :- S2#>=S1+D1.
86
Disjunctive Resource Constraints
noclash(Si,Di,Sj,_Dj) :-incval(nodes),Sj #>= Si+Di.
noclash(Si,_Di,Sj,Dj) :-incval(nodes),Si #>= Sj+Dj
this clauseis tried 1st
this clauseis tried 2nd
just addsanother
temporal constraint
88
Repair Search: Probe Backtracking
Probe: Tentative Values are Earliest Possible Start times
Probe satisfies temporal constraints
Probe violates resource constraints
tent_set_to_min(Vars) :-( foreach(Var,Vars), foreach(Min,Mins)do mindomain(Var,Min)),Vars tent_set Mins.
noclash(S0,D0,S1,D1) r_conflict cs
89
A disjunctive constraint is in conflict
Probe can cause violation (overlap)
repair_label :-conflict_vars(CVs),tent_set_to_min(CVs),conflict_constraints(cs,CCs),( CCs == [] ->
true;
CCs = [Constraint|_],call(Constraint), %% Fix the constraint
%% create choice point%% affect probe
repair_label).
90
Repair Search: Top level
Fix to tentative values after all conflicts resolved
min_max((repair_label,Starts tent_get Starts,writeq(Starts),nl,print_nodes
), End_date),
91
A repair heuristic
Pick a constraint according to a heuristic
disjunctive(S0,D0,S1,D1) r_conflict cs - tasks(Task0,Task1)
select_constraint(TaskPairs,SelectedPair) :- ( foreach(TaskPair,TaskPairs), foreach(Key-TaskPair,KeyedCCs) do TaskPair = tasks(
task with [duration:D0] ,task with [duration:D1]),
Key is min(D0,D1) ), sort(1,>,KeyedCCs,[_- SelectedPair|_]).
92
Repair library - Quick Reference
Tentative Values Vars tent_set Vals Vars tent_get Vals
Conflict Sets
conflict_constraints(Cset,CCs)
Constraint AnnotationsConstraint r_conflict CsetVar tent_is Expression
Interleaved Search Methods
Interleaved Construction and repair 1) Construct a partial solution till no consistent extension 2) Make this partial solution “tentative” 3) Choose a value for the “next” variable 4) Repair the tentative solution
Instances Greedy construction + local search repair Weak commitment – repair by constructive search Iterated search – retain completeness by distinguishing instantiated
and repairable variables
From Local to Global
Local search on small set of “driving” variables Constructive search to complete solution and cost
Move by unfixing part of solution Create move by constructive search Pesant – best neighbour Large neighbourhood search Linear optimisation (Le Pape)
95
Current Frameworkpartial assignments
Limitations of diagram:Should go to ancestor node Should rearrange tree after move
Move between (consistent) partial solutionsMove “upwards” by unfixing a variableMove “downwards” by fixing a variable
Current Framework
Unfix Which variable? What dependency information should be kept?
Fix Which variable? What propagation?
Move by unfixing and fixing Can this successfully encompass complex moves, e.g.2-
swaps? Is there a “viewpoint” that makes this equivalent to unfix+fix?