use new matrix functionality
This commit is contained in:
parent
b64965f22c
commit
e19b58cf53
129
library/gecode/clp_examples/3jugs.yap
Normal file
129
library/gecode/clp_examples/3jugs.yap
Normal file
@ -0,0 +1,129 @@
|
|||||||
|
% Example with matrices,based on:
|
||||||
|
%
|
||||||
|
% Three jugs problem in Minzinc modelled as a shortest path problem.
|
||||||
|
%
|
||||||
|
% Problem from Taha "Introduction to Operations Research", page 245
|
||||||
|
%
|
||||||
|
% Model created by Hakan Kjellerstrand, hakank@bonetmail.com
|
||||||
|
% See also my MiniZinc page: http://www.hakank.org/minizinc
|
||||||
|
|
||||||
|
%
|
||||||
|
% VSC: had to transpose the matrix, and change the constraints....
|
||||||
|
%
|
||||||
|
|
||||||
|
:- style_check( all ).
|
||||||
|
|
||||||
|
:- use_module(library(gecode/clpfd)).
|
||||||
|
:- use_module(library(maplist)).
|
||||||
|
:- use_module(library(lists)).
|
||||||
|
|
||||||
|
main :-
|
||||||
|
problem(Z, X, InFlow, OutFlow, N),
|
||||||
|
out(Z, X, InFlow, OutFlow, N),
|
||||||
|
fail.
|
||||||
|
main.
|
||||||
|
|
||||||
|
problem(Z, X, InFlow, OutFlow, N) :-
|
||||||
|
N = 15,
|
||||||
|
Start = 1,
|
||||||
|
End = 15,
|
||||||
|
M = 999,
|
||||||
|
d( M, DD ),
|
||||||
|
D = array[1..N,1..N] of DD, % distance
|
||||||
|
RHS = array[1..N] of _, % requirements (right hand statement)
|
||||||
|
X = array[1..N, 1..N] of 0..1, % the resulting matrix, 1 if connected, 0 else
|
||||||
|
OutFlow = array[1..N] of 0..1,
|
||||||
|
InFlow = array[1..N] of 0..1,
|
||||||
|
|
||||||
|
% objective to minimize
|
||||||
|
Z in 0..M,
|
||||||
|
Z #= sum( [I in 1..N, J in 1..N] where D[I,J]<M,
|
||||||
|
D[I,J]*X[I,J]),
|
||||||
|
|
||||||
|
% solve minimize z;
|
||||||
|
% alternative solve statements which may give faster solution
|
||||||
|
%solve :: int_search([ x[i,j] | i,j in 1..n], first_fail, indomain_min, complete) minimize z;
|
||||||
|
% solve minimize z;
|
||||||
|
minimize(Z),
|
||||||
|
|
||||||
|
|
||||||
|
% constraint
|
||||||
|
for(I in 1..N,
|
||||||
|
( I == Start ->
|
||||||
|
RHS[I] <== 1 ;
|
||||||
|
I == End ->
|
||||||
|
RHS[I] <== -1 ;
|
||||||
|
RHS[I] <== 0 )
|
||||||
|
),
|
||||||
|
|
||||||
|
|
||||||
|
% must be larger than 0??
|
||||||
|
for( [I in 1..N, J in 1..N],
|
||||||
|
( D[J,I] = M ->
|
||||||
|
X[J,I] #= 0 ;
|
||||||
|
true )
|
||||||
|
),
|
||||||
|
% outflow constraint
|
||||||
|
for(I in 1..N,
|
||||||
|
OutFlow[I] #= sum(J in 1..N where D[J,I]<M, X[J,I])
|
||||||
|
),
|
||||||
|
% inflow constraint
|
||||||
|
for(J in 1..N,
|
||||||
|
InFlow[J] #= sum(I in 1..N where D[J,I]<M, X[J,I])
|
||||||
|
),
|
||||||
|
% inflow = outflow
|
||||||
|
for(I in 1..N, OutFlow[I]-InFlow[I]#=RHS[I]),
|
||||||
|
|
||||||
|
% labeling
|
||||||
|
labeling( [], X).
|
||||||
|
|
||||||
|
% data
|
||||||
|
d(M, [
|
||||||
|
M, 1, M, M, M, M, M, M, 1, M, M, M, M, M, M,
|
||||||
|
M, M, 1, M, M, M, M, M, M, M, M, M, M, M, M,
|
||||||
|
M, M, M, 1, M, M, M, M, 1, M, M, M, M, M, M,
|
||||||
|
M, M, M, M, 1, M, M, M, M, M, M, M, M, M, M,
|
||||||
|
M, M, M, M, M, 1, M, M, 1, M, M, M, M, M, M,
|
||||||
|
M, M, M, M, M, M, 1, M, M, M, M, M, M, M, M,
|
||||||
|
M, M, M, M, M, M, M, 1, 1, M, M, M, M, M, M,
|
||||||
|
M, M, M, M, M, M, M, M, M, M, M, M, M, M, 1,
|
||||||
|
M, M, M, M, M, M, M, M, M, 1, M, M, M, M, M,
|
||||||
|
M, 1, M, M, M, M, M, M, M, M, 1, M, M, M, M,
|
||||||
|
M, M, M, M, M, M, M, M, M, M, M, 1, M, M, M,
|
||||||
|
M, 1, M, M, M, M, M, M, M, M, M, M, 1, M, M,
|
||||||
|
M, M, M, M, M, M, M, M, M, M, M, M, M, 1, M,
|
||||||
|
M, 1, M, M, M, M, M, M, M, M, M, M, M, M, 1,
|
||||||
|
M, M, M, M, M, M, M, M, M, M, M, M, M, M, M
|
||||||
|
]).
|
||||||
|
|
||||||
|
/*
|
||||||
|
% shows the result matrix
|
||||||
|
output [
|
||||||
|
if i = 1 /\ j = 1 then
|
||||||
|
"z: " ++ show(z) ++ "\n" ++
|
||||||
|
"inFlow: " ++ show(inFlow) ++ "\n" ++ "outFlow: " ++ show(outFlow) ++ "\n" ++
|
||||||
|
" 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5\n"
|
||||||
|
else "" endif ++
|
||||||
|
if j = 1 then show(i) ++ " : " else "" endif ++
|
||||||
|
show(x[i,j]) ++ if j = n then "\n" else " " endif
|
||||||
|
| i in 1..n, j in 1..n
|
||||||
|
];
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
out(Cost, Ts, Ins, Out, N) :-
|
||||||
|
format('cost = ~d~n', [Cost]),
|
||||||
|
InsL <== list(Ins),
|
||||||
|
OutL <== list(Out),
|
||||||
|
format('Inputs =', []), maplist(out, InsL), nl,
|
||||||
|
format('Outputs =', []), maplist(out, OutL), nl,
|
||||||
|
format('transitions =~n', []),
|
||||||
|
for(I in 1..N, outl(Ts[_,I]) ).
|
||||||
|
|
||||||
|
outl( X ) :-
|
||||||
|
L <== X, % evaluate matrix notation to Prolog lists.
|
||||||
|
format(' ', []),
|
||||||
|
maplist(out, L), nl.
|
||||||
|
|
||||||
|
out(0) :- format(' .', []).
|
||||||
|
out(1) :- format(' 1', []).
|
Binary file not shown.
@ -7,6 +7,7 @@
|
|||||||
op(730, yfx, #\),
|
op(730, yfx, #\),
|
||||||
op(720, yfx, #/\),
|
op(720, yfx, #/\),
|
||||||
op(710, fy, #\),
|
op(710, fy, #\),
|
||||||
|
op(705, xfx, where),
|
||||||
op(700, xfx, #>),
|
op(700, xfx, #>),
|
||||||
op(700, xfx, #<),
|
op(700, xfx, #<),
|
||||||
op(700, xfx, #>=),
|
op(700, xfx, #>=),
|
||||||
@ -34,6 +35,7 @@
|
|||||||
all_distinct/1,
|
all_distinct/1,
|
||||||
all_distinct/2,
|
all_distinct/2,
|
||||||
maximize/1,
|
maximize/1,
|
||||||
|
minimize/1,
|
||||||
sum/3,
|
sum/3,
|
||||||
lex_chain/1,
|
lex_chain/1,
|
||||||
minimum/2,
|
minimum/2,
|
||||||
@ -69,7 +71,17 @@
|
|||||||
|
|
||||||
:- use_module(library(gecode)).
|
:- use_module(library(gecode)).
|
||||||
:- use_module(library(maplist)).
|
:- use_module(library(maplist)).
|
||||||
:- reexport(library(matrix), [(<==)/2, for/2, for/4]).
|
:- reexport(library(matrix), [(<==)/2, for/2, for/4, of/2]).
|
||||||
|
|
||||||
|
% build array of constraints
|
||||||
|
%
|
||||||
|
matrix:array_extension(_.._ , clpfd:build).
|
||||||
|
|
||||||
|
build( I..J, _, Size, L) :-
|
||||||
|
length( L, Size ),
|
||||||
|
L ins I..J.
|
||||||
|
|
||||||
|
matrix:rhs_opaque(X) :- constraint(X).
|
||||||
|
|
||||||
constraint( (_ #> _) ).
|
constraint( (_ #> _) ).
|
||||||
constraint( (_ #< _) ).
|
constraint( (_ #< _) ).
|
||||||
@ -119,7 +131,6 @@ constraint( fd_size(_, _) ). %2,
|
|||||||
constraint( fd_dom(_, _) ). %2
|
constraint( fd_dom(_, _) ). %2
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
process_constraints((B0,B1), (NB0, NB1), Env) :-
|
process_constraints((B0,B1), (NB0, NB1), Env) :-
|
||||||
process_constraints(B0, NB0, Env),
|
process_constraints(B0, NB0, Env),
|
||||||
process_constraints(B1, NB1, Env).
|
process_constraints(B1, NB1, Env).
|
||||||
@ -284,14 +295,21 @@ in_dfa( Xs, S0, Ts, Fs ) :-
|
|||||||
|
|
||||||
labeling(_Opts, Xs) :-
|
labeling(_Opts, Xs) :-
|
||||||
get_home(Space-Map),
|
get_home(Space-Map),
|
||||||
maplist(ll(Map), Xs, NXs),
|
check( Xs, X1s ),
|
||||||
Space += branch(NXs, 'INT_VAR_SIZE_MIN', 'INT_VAL_MIN').
|
( X1s == [] -> true ;
|
||||||
|
maplist(ll(Map), X1s, NXs),
|
||||||
|
Space += branch(NXs, 'INT_VAR_SIZE_MIN', 'INT_VAL_MIN') ).
|
||||||
|
|
||||||
maximize(V) :-
|
maximize(V) :-
|
||||||
get_home(Space-Map),
|
get_home(Space-Map),
|
||||||
l(V, I, Map),
|
l(V, I, Map),
|
||||||
Space += maximize(I).
|
Space += maximize(I).
|
||||||
|
|
||||||
|
minimize(V) :-
|
||||||
|
get_home(Space-Map),
|
||||||
|
l(V, I, Map),
|
||||||
|
Space += minimize(I).
|
||||||
|
|
||||||
extensional_constraint( Tuples, TupleSet) :-
|
extensional_constraint( Tuples, TupleSet) :-
|
||||||
TupleSet := tupleset( Tuples ).
|
TupleSet := tupleset( Tuples ).
|
||||||
|
|
||||||
@ -303,7 +321,11 @@ check(V, NV) :-
|
|||||||
( var(V) -> V = NV ;
|
( var(V) -> V = NV ;
|
||||||
number(V) -> V = NV ;
|
number(V) -> V = NV ;
|
||||||
is_list(V) -> maplist(check, V, NV) ;
|
is_list(V) -> maplist(check, V, NV) ;
|
||||||
|
V = sum(_,_) -> V = NV ;
|
||||||
V = '[]'(Indx, Mat) -> NV <== '[]'(Indx, Mat) ;
|
V = '[]'(Indx, Mat) -> NV <== '[]'(Indx, Mat) ;
|
||||||
|
V = '$matrix'(_, _, _, _, C) -> C =.. [_|L], maplist(check, L, NV) ;
|
||||||
|
V = A+B -> check(A,NA), check(B, NB), NV = NB+NA ;
|
||||||
|
V = A-B -> check(A,NA), check(B, NB), NV = NB-NA ;
|
||||||
arith(V, _) -> V =.. [C|L], maplist(check, L, NL), NV =.. [C|NL] ).
|
arith(V, _) -> V =.. [C|L], maplist(check, L, NL), NV =.. [C|NL] ).
|
||||||
|
|
||||||
post( ( A #= B), Env, Reify) :-
|
post( ( A #= B), Env, Reify) :-
|
||||||
@ -318,6 +340,12 @@ post( ( A #>= B), Env, Reify) :-
|
|||||||
post( rel( A, (#>=), B), Env, Reify).
|
post( rel( A, (#>=), B), Env, Reify).
|
||||||
post( ( A #=< B), Env, Reify) :-
|
post( ( A #=< B), Env, Reify) :-
|
||||||
post( rel( A, (#=<), B), Env, Reify).
|
post( rel( A, (#=<), B), Env, Reify).
|
||||||
|
% [X,Y,Z] #<
|
||||||
|
post( rel( A, Op), Space-Map, Reify):-
|
||||||
|
( var( A ) -> l(A, IA, Map) ; checklist( var, A ) -> maplist(ll(Map), A, IA ) ),
|
||||||
|
gecode_arith_op( Op, GOP ),
|
||||||
|
(var(Reify) -> Space += rel(IA, GOP) ;
|
||||||
|
Space += rel(IA, GOP, Reify) ).
|
||||||
% X #< Y
|
% X #< Y
|
||||||
% X #< 2
|
% X #< 2
|
||||||
post( rel( A, Op, B), Space-Map, Reify):-
|
post( rel( A, Op, B), Space-Map, Reify):-
|
||||||
@ -328,11 +356,6 @@ post( rel( A, Op, B), Space-Map, Reify):-
|
|||||||
(var(Reify) -> Space += rel(IA, GOP, IB) ;
|
(var(Reify) -> Space += rel(IA, GOP, IB) ;
|
||||||
Space += rel(IA, GOP, IB, Reify) ).
|
Space += rel(IA, GOP, IB, Reify) ).
|
||||||
|
|
||||||
post( rel( A, Op), Space-Map, Reify):-
|
|
||||||
( var( A ) -> l(A, IA, Map) ; checklist( var, A ) -> maplist(ll(Map), A, IA ) ),
|
|
||||||
gecode_arith_op( Op, GOP ),
|
|
||||||
(var(Reify) -> Space += rel(IA, GOP) ;
|
|
||||||
Space += rel(IA, GOP, Reify) ).
|
|
||||||
% 2 #\= B
|
% 2 #\= B
|
||||||
post( rel( A, Op, B), Space-Map, Reify):-
|
post( rel( A, Op, B), Space-Map, Reify):-
|
||||||
var(B), integer(A), !,
|
var(B), integer(A), !,
|
||||||
@ -340,6 +363,7 @@ post( rel( A, Op, B), Space-Map, Reify):-
|
|||||||
gecode_arith_op( Op, GOP ),
|
gecode_arith_op( Op, GOP ),
|
||||||
(var(Reify) -> Space += rel(A, GOP, IB) ;
|
(var(Reify) -> Space += rel(A, GOP, IB) ;
|
||||||
Space += rel(A, GOP, IB, Reify) ).
|
Space += rel(A, GOP, IB, Reify) ).
|
||||||
|
|
||||||
% sum([A,B,C]) #= X
|
% sum([A,B,C]) #= X
|
||||||
post( rel( sum(L), Op, Out), Space-Map, Reify):-
|
post( rel( sum(L), Op, Out), Space-Map, Reify):-
|
||||||
checklist( var, L ),
|
checklist( var, L ),
|
||||||
@ -351,6 +375,40 @@ post( rel( sum(L), Op, Out), Space-Map, Reify):-
|
|||||||
Space += linear(IL, GOP, IOut);
|
Space += linear(IL, GOP, IOut);
|
||||||
Space += linear(IL, GOP, IOut, Reify)
|
Space += linear(IL, GOP, IOut, Reify)
|
||||||
).
|
).
|
||||||
|
% X #= sum([A,B,C])
|
||||||
|
post( rel( Out, Op, sum(L)), Space-Map, Reify):-
|
||||||
|
checklist( var, L ),
|
||||||
|
( var(Out) -> l(Out, IOut, Map) ; integer(Out) -> IOut = Out ), !,
|
||||||
|
var(Out), !,
|
||||||
|
maplist(ll(Map), [Out|L], [IOut|IL] ),
|
||||||
|
gecode_arith_op( Op, GOP ),
|
||||||
|
(var(Reify) ->
|
||||||
|
Space += linear(IL, GOP, IOut);
|
||||||
|
Space += linear(IL, GOP, IOut, Reify)
|
||||||
|
).
|
||||||
|
|
||||||
|
|
||||||
|
% sum([I in 0..N-1, M[I]]) #= X
|
||||||
|
post( rel( sum(For, Cond), Op, Out), Space-Map, Reify):-
|
||||||
|
( var(Out) -> l(Out, IOut, Map) ; integer(Out) -> IOut = Out ), !,
|
||||||
|
cond2list( For, Cond, Cs, L),
|
||||||
|
maplist(ll(Map), [Out|L], [IOut|IL] ),
|
||||||
|
gecode_arith_op( Op, GOP ),
|
||||||
|
(L = [] -> true ;
|
||||||
|
var(Reify) ->
|
||||||
|
Space += linear(Cs, IL, GOP, IOut);
|
||||||
|
Space += linear(Cs, IL, GOP, IOut, Reify)
|
||||||
|
).
|
||||||
|
post( rel( Out, Op, sum(For, Cond)), Space-Map, Reify):-
|
||||||
|
( var(Out) -> l(Out, IOut, Map) ; integer(Out) -> IOut = Out ), !,
|
||||||
|
cond2list( For, Cond, Cs, L),
|
||||||
|
maplist(ll(Map), [Out|L], [IOut|IL] ),
|
||||||
|
gecode_arith_op( Op, GOP ),
|
||||||
|
(L = [] -> true ;
|
||||||
|
var(Reify) ->
|
||||||
|
Space += linear(Cs, IL, GOP, IOut);
|
||||||
|
Space += linear(Cs, IL, GOP, IOut, Reify)
|
||||||
|
).
|
||||||
% [A,B,C,D] #< 3
|
% [A,B,C,D] #< 3
|
||||||
post( rel( A, Op, B ), Space-Map, Reify):-
|
post( rel( A, Op, B ), Space-Map, Reify):-
|
||||||
checklist( var, A ), !,
|
checklist( var, A ), !,
|
||||||
@ -374,7 +432,7 @@ post( rel( A, Op, B), Space-Map, Reify):-
|
|||||||
(var(Reify) -> Space += rel(IL, GOP, IB) ;
|
(var(Reify) -> Space += rel(IL, GOP, IB) ;
|
||||||
Space += rel(IL, GOP, IB, Reify) ).
|
Space += rel(IL, GOP, IB, Reify) ).
|
||||||
post( rel(A, Op, B), Space-Map, Reify):-
|
post( rel(A, Op, B), Space-Map, Reify):-
|
||||||
( nonvar(A), ( A = _+_ ; A = _-_ ) ;
|
( nonvar(A), ( A = _+_ ; A = _-_ ) ;
|
||||||
nonvar(B), ( B = _ + _ ; B = _-_) ), !,
|
nonvar(B), ( B = _ + _ ; B = _-_) ), !,
|
||||||
linearize(A, 1, As, Bs, CAs, CBs, 0, A0, Space-Map),
|
linearize(A, 1, As, Bs, CAs, CBs, 0, A0, Space-Map),
|
||||||
linearize(B, -1, Bs, [], CBs, [], A0, B0, Space-Map),
|
linearize(B, -1, Bs, [], CBs, [], A0, B0, Space-Map),
|
||||||
@ -532,7 +590,6 @@ arith(min(_,_), min).
|
|||||||
arith(max(_,_), max).
|
arith(max(_,_), max).
|
||||||
arith((_ * _), times).
|
arith((_ * _), times).
|
||||||
arith((_ / _), div).
|
arith((_ / _), div).
|
||||||
arith((_ mod _), mod).
|
|
||||||
|
|
||||||
% replace abs(min(A,B)-max(A,B)) by
|
% replace abs(min(A,B)-max(A,B)) by
|
||||||
% min(A,B,A1), max(A,B,A2), linear([1,-1],[A1,B1],=,A3), abs(A3,AN)
|
% min(A,B,A1), max(A,B,A2), linear([1,-1],[A1,B1],=,A3), abs(A3,AN)
|
||||||
@ -809,6 +866,17 @@ intvar(Map, V) :-
|
|||||||
get_home(Home) :-
|
get_home(Home) :-
|
||||||
b_getval(gecode_space, Home).
|
b_getval(gecode_space, Home).
|
||||||
|
|
||||||
|
cond2list((List where Goal), El, Cs, Vs) :- !,
|
||||||
|
for( List, add_el(Goal, El), ([])-([]), Cs-Vs ).
|
||||||
|
cond2list(List, El, Cs, Vs) :- !,
|
||||||
|
for( List, add_el(true, El), ([])-([]), Cs-Vs ).
|
||||||
|
|
||||||
|
add_el(G0, El, Cs-Vs, [C|Cs]-[V|Vs]) :-
|
||||||
|
call(G0), !,
|
||||||
|
E <== El,
|
||||||
|
( var(E) -> C = 1, E = V ; E = C*V, integer(C), var(V) -> true ; E = V*C, integer(C), var(V) ).
|
||||||
|
add_el(_G0, _El, Cs-Vs, Cs-Vs).
|
||||||
|
|
||||||
m(NV, OV, NA, NB, Vs) :-
|
m(NV, OV, NA, NB, Vs) :-
|
||||||
var(Vs), !,
|
var(Vs), !,
|
||||||
Vs = [v(NV,OV,NA,NB)|_].
|
Vs = [v(NV,OV,NA,NB)|_].
|
||||||
|
Reference in New Issue
Block a user