I'm trying to write a constraint in the from of the following (also attached):
sum([s,i], x[i,j,s,p] ) = sum([s,k], x[j,k,s,p] ) for all j in N\{0,n}, p in P
I already have all possible combinations of (i,j,s,p) stored in a set Xs and X0nswhich a vector of such 4-tuples.
Thus I tried to write it down as
#constraint( model, [p in P, jj in X0ns],
sum(x[(i, j, s, p)] for (i, j, s, p) in Xs if j == jj)
== sum(x[(j, k, s, p)] for (i, j, s, p) in Xs if j == jj)
This gives me an Error. On top of that I think this is not correct way of writing. Because I did not include a summation on S anywhere. Is it needed?
How can I build this kind of constraint?
Here is what I think that you mean (this is the exact implementation of your LaTeX equation).
Normally you should not have used tuples for array indexing.
m = Model();
S=1:3
N=1:4
K=1:4
P=1:5
#variable(m, x[N,N,S,P] >= 0);
#constraint(m, [j in N[2:end-1], p in P], sum(x[i,j,s,p] for i in N, s in S)
== sum(x[j,k,s,p] for k in K, s in S))
Related
I would like to use the optimization model in a code. But processing and preparation time of the objective function (f) is too long. Is there any way to reduce the time of these kinds of large models?
using JuMP,CPLEX
Tsp=Model(solver=CplexSolver());
#Parameters-----------------------------------------------------------------
V, T, K = 1:100, 1:5, 1:5
totalV=100
d=1 .+ 99 .*rand(V,V);
#variables---------------------------------------------------------------------
#variable(Tsp,x[V,V,K,T],Bin);
#variable(Tsp,u[V,V,K,T]>=0);
#constrains---------------------------------------------------------------------
#constraint(Tsp,c1[i in V, k in K,t in T ], sum(x[i,j,k,t] for j in V )==1);
#constraint(Tsp,c2[j in V, k in K,t in T], sum(x[i,j,k,t] for i in V )==1);
#constraint(Tsp,c3[i in U,j in V,k in K, t in T; i!=j],u[i,k,t]-u[j,k,t]+totalV*x[i,j,k,t]<=totalV-1);
# objective function---------------------------------------------------------
f=sum(d[i,j]*x[i,j,k,t] for i in V,j in V, k in K, t in T);
#objective(Tsp, Min, f);
solve(Tsp);
Thanks very much.
I'll assume you're using JuMP due to the tag.
Always provide a reproducible example: https://stackoverflow.com/help/minimal-reproducible-example. It's hard to offer advice without it.
Do not build JuMP expressions outside of the macros: https://jump.dev/JuMP.jl/stable/tutorials/getting_started/performance_tips/#Use-macros-to-build-expressions
Your code is wrong. If V = 100, then for i in V will only have one element, and that is i = 100. Perhaps you meant for i in 1:V?
Think about what the if statement is doing. It only uses i and j, but it needs to be evaluated for every t and every k.
Putting it all together, I would do something like:
V, H, K = 1:100, 1:5, 1:5
using JuMP
model = Model()
#variable(model, x[V, V, K, H])
d = 1 .+ 99 .* rand(V, V)
#expression(
model,
f,
sum(d[i, j] * sum(x[i,j,k,t] for t in H, k in K) for for i in V, j in V if i!=j)
)
Hope that helps.
I'm trying to solve the exercise from book "Prolog Programming In Depth".
Define a recursive predicate sum(J,K,N) that instantiates N to the sum of the integers from J to K inclusive:
?- sum(-1,1,What).
What = 0
?- sum(1,3,What).
What = 6
?- sum(6,7,What).
What = 13
My predicate is below.
sum(J, K, N) :- sum_iter(J, K, N, J, 0). % clause_1
sum_iter(J, K, N, I, S) :- % clause_2
Kn is K+1, % clause_X
I = Kn,
N = S,!.
sum_iter(J, K, N, I, S) :- % clause_2, I - index, S - SumTmp
I =< K,
NewI is I+1,
NewS is S+I,
sum_iter(J, K, N, NewI, NewS).
It works correctly but I don't understand:
why I should use clause_X (why +1)
and why I can't replace clause_2 by
sum_iter(J, K, N, K, N) :- !.
In this case predicate stops work on previous step.
For example, expect:
?- sum(1,3,What).
What = 6
BUT Prolog output:
?- sum(1,3,What).
What = 3
Printing out some of the state:
sum(J, K, N) :- sum_iter(J, K, N, J, 0).
% the rule at the end of the recursion
sum_iter(J, K, N, I, S) :-
format("rule 1: J=~w K=~w N=~w I=~w S=~w\n", [J, K, N, I, S]),
Kn is K+1,
I = Kn,
format("...pos 1 passed\n"),
N = S,
format("...pos 2 passed\n"),
!.
% the rule perfoming the recursion
sum_iter(J, K, N, I, S) :-
format("rule 2: J=~w K=~w N=~w I=~w S=~w\n", [J, K, N, I, S]),
I =< K,
format("...pos 3 passed\n"),
NewI is I+1,
NewS is S+I,
sum_iter(J, K, N, NewI, NewS).
?- sum(1,3,What).
rule 1: J=1 K=3 N=_11338 I=1 S=0
rule 2: J=1 K=3 N=_11338 I=1 S=0
...pos 3 passed
rule 1: J=1 K=3 N=_11338 I=2 S=1
rule 2: J=1 K=3 N=_11338 I=2 S=1
...pos 3 passed
rule 1: J=1 K=3 N=_11338 I=3 S=3
rule 2: J=1 K=3 N=_11338 I=3 S=3
...pos 3 passed
rule 1: J=1 K=3 N=_11338 I=4 S=6
...pos 1 passed
...pos 2 passed
What = 6.
At the end, the I = Kn becomes a test: both I and Kn are
set to actual values, with I one "past the end".
You could do this, using an I > K "guard":
sum_iter(_, K, Res, I, Res) :- I > K,!.
But what you also want to do this:
Call the recursive rule by default, if it is applicable.
If it is not, call the "end of recursion rule".
So a rearrangement is best:
sum(J, K, N) :- sum_iter(J, K, N, J, 0).
% the rule perfoming the recursion, with a guard "I =< K", which, once
% successful, commits the computation to this one rule, so we add "!"
sum_iter(J, K, N, I, S) :-
format("rule 2: J=~w K=~w N=~w I=~w S=~w\n", [J, K, N, I, S]),
I =< K,!,
format("...pos 3 passed\n"),
NewI is I+1,
NewS is S+I,
sum_iter(J, K, N, NewI, NewS).
% the rule at the end of the recursion, also with guard:
sum_iter(J, K, Res, I, Res) :-
format("end: J=~w K=~w I=~w Res=~w\n", [J, K, I, Res]),
I > K,!.
Actually, there is no need for the "cut" in the second
rule, because it is the last rule. There is no need for the
guard in this case either, it is just the negation of the guard in
the first rule. But let's leave both for clarity.
?- sum(1,3,What).
rule 2: J=1 K=3 N=_15630 I=1 S=0
...pos 3 passed
rule 2: J=1 K=3 N=_15630 I=2 S=1
...pos 3 passed
rule 2: J=1 K=3 N=_15630 I=3 S=3
...pos 3 passed
rule 2: J=1 K=3 N=_15630 I=4 S=6
end: J=1 K=3 I=4 Res=6
What = 6.
I am using Julia 0.6.2 and JuMP 0.18.5 (I can't use a more recent version since I need to use an old package).
Creating JuMP variables with conditions on the index lead to a JuMPDict instead of an Array.
For example:
m = Model(solver = CplexSolver())
# type of x: JuMP.JuMPDict{JuMP.Variable,2}
#variable(m, x[i in 1:3, j in 1:3; i < j] >= 0)
# type of y: JuMP.JuMPDict{JuMP.Variable,3}
#variable(m, y[i in 1:3, j in 1:3, k in 1:3; i < j] >= 0)
I would like to apply a function f to x and to y[:, :, k] for all k in 1:3. However, I don't know how to define such a generic function.
I tried to set the argument type of f to JuMP.JuMPDict{JuMP.Variable,2}:
function f(input::JuMP.JuMPDict{JuMP.Variable,2})
...
end
I can use the function on x but not on y:
f(x) # Works
for k in 1:3
f(y[:, :, k]) # does not work as y is not an array
end
My last idea was to convert y into several JuMP.JuMPDict{JuMP.Variable,2}:
function convertTo2D(dict3D::JuMP.JuMPDict{JuMP.Variable,3}, k::Int)
dict2D = JuMP.JuMPDict{JuMP.Variable,2}() # This line returns "ERROR: KeyError: key :model not found"
for (key, value) in keys(dict3D)
if key[3] == k
dict2D[(key[1], key[2])] = value # Not sure if it will work
end
end
return dict2D
end
If this was working I could use:
for k in 1:3
f(convertTd2D(y, k))
end
Do you know how I could fix convertTo2D or do what I want another way?
Anonymous variables solved my problem. Thanks to them I can successively create the variables of y in a for loop. Variable y is now an array of "2D dictionaries" rather than a "3D dictionaries":
y = Array{JuMP.JuMPDict{JuMP.Variable,2}, 1}([])
for k in 1:3
yk = #variable(m, [i in 1:3, j in 1:3; i < j] >= 0)
f(yk)
push!(y, yk)
end
Is it safe to replace a/(b*c) with a/b/c when using integer-division on positive integers a,b,c, or am I at risk losing information?
I did some random tests and couldn't find an example of a/(b*c) != a/b/c, so I'm pretty sure it's safe but not quite sure how to prove it.
Thank you.
Mathematics
As mathematical expressions, ⌊a/(bc)⌋ and ⌊⌊a/b⌋/c⌋ are equivalent whenever b is nonzero and c is a positive integer (and in particular for positive integers a, b, c). The standard reference for these sorts of things is the delightful book Concrete Mathematics: A Foundation for Computer Science by Graham, Knuth and Patashnik. In it, Chapter 3 is mostly on floors and ceilings, and this is proved on page 71 as a part of a far more general result:
In the 3.10 above, you can define x = a/b (mathematical, i.e. real division), and f(x) = x/c (exact division again), and plug those into the result on the left ⌊f(x)⌋ = ⌊f(⌊x⌋)⌋ (after verifying that the conditions on f hold here) to get ⌊a/(bc)⌋ on the LHS equal to ⌊⌊a/b⌋/c⌋ on the RHS.
If we don't want to rely on a reference in a book, we can prove ⌊a/(bc)⌋ = ⌊⌊a/b⌋/c⌋ directly using their methods. Note that with x = a/b (the real number), what we're trying to prove is that ⌊x/c⌋ = ⌊⌊x⌋/c⌋. So:
if x is an integer, then there is nothing to prove, as x = ⌊x⌋.
Otherwise, ⌊x⌋ < x, so ⌊x⌋/c < x/c which means that ⌊⌊x⌋/c⌋ ≤ ⌊x/c⌋. (We want to show it's equal.) Suppose, for the sake of contradiction, that ⌊⌊x⌋/c⌋ < ⌊x/c⌋ then there must be a number y such that ⌊x⌋ < y ≤ x and y/c = ⌊x/c⌋. (As we increase a number from ⌊x⌋ to x and consider division by c, somewhere we must hit the exact value ⌊x/c⌋.) But this means that y = c*⌊x/c⌋ is an integer between ⌊x⌋ and x, which is a contradiction!
This proves the result.
Programming
#include <stdio.h>
int main() {
unsigned int a = 142857;
unsigned int b = 65537;
unsigned int c = 65537;
printf("a/(b*c) = %d\n", a/(b*c));
printf("a/b/c = %d\n", a/b/c);
}
prints (with 32-bit integers),
a/(b*c) = 1
a/b/c = 0
(I used unsigned integers as overflow behaviour for them is well-defined, so the above output is guaranteed. With signed integers, overflow is undefined behaviour, so the program can in fact print (or do) anything, which only reinforces the point that the results can be different.)
But if you don't have overflow, then the values you get in your program are equal to their mathematical values (that is, a/(b*c) in your code is equal to the mathematical value ⌊a/(bc)⌋, and a/b/c in code is equal to the mathematical value ⌊⌊a/b⌋/c⌋), which we've proved are equal. So it is safe to replace a/(b*c) in code by a/b/c when b*c is small enough not to overflow.
While b*c could overflow (in C) for the original computation, a/b/c can't overflow, so we don't need to worry about overflow for the forward replacement a/(b*c) -> a/b/c. We would need to worry about it the other way around, though.
Let x = a/b/c. Then a/b == x*c + y for some y < c, and a == (x*c + y)*b + z for some z < b.
Thus, a == x*b*c + y*b + z. y*b + z is at most b*c-1, so x*b*c <= a <= (x+1)*b*c, and a/(b*c) == x.
Thus, a/b/c == a/(b*c), and replacing a/(b*c) by a/b/c is safe.
Nested floor division can be reordered as long as you keep track of your divisors and dividends.
#python3.x
x // m // n = x // (m * n)
#python2.x
x / m / n = x / (m * n)
Proof (sucks without LaTeX :( ) in python3.x:
Let k = x // m
then k - 1 < x / m <= k
and (k - 1) / n < x / (m * n) <= k / n
In addition, (x // m) // n = k // n
and because x // m <= x / m and (x // m) // n <= (x / m) // n
k // n <= x // (m * n)
Now, if k // n < x // (m * n)
then k / n < x / (m * n)
and this contradicts the above statement that x / (m * n) <= k / n
so if k // n <= x // (m * n) and k // n !< x // (m * n)
then k // n = x // (m * n)
and (x // m) // n = x // (m * n)
https://en.wikipedia.org/wiki/Floor_and_ceiling_functions#Nested_divisions
I have a predicate that get a bst T in input and return a list S of the values contained in the bst that belong to a specific range [R1,R2] and this works fine. When I try to count the iteration done in order to get the list in output I receive Always false. This is my predicate's code:
findExamsInRange(R1, R2, T, S, N) :-
find(R1, R2, T, S, N),
N > 0.
find(R1, R2, nil, [], N).
find(R1, R2, t(V,L,R), S, N) :-
V >= R1,
V =< R2,
find(R1,R2, L, L,NL),
find(R1,R2, R, LR,NR),
append([V|LL], LR, S),
N is NL+NR+1.
find(R1, R2, t(V,L,R), S, N) :-
V < R1,
find(R1, R2, R, S, N).
find(R1, R2, t(V,L,R), S, N) :-
V > R2,
find(R1, R2, L, S, N).
Can anyone help me why I cannot get the value of N?
Shouldn't the first clause of the find/5 predicate:
find(R1, R2, nil, [], N).
be instead:
find(_R1, _R2, nil, [], 0).
When reaching the leaves of the tree, you have to return a value for N that allows the N is NL+NR+1 goal to succeed without errors.
You need to use assert and retract to define a global counter :
inc_counter:- % normal case
retract(counter(X)), !,
Y is X+1,
assert(counter(Y)).
inc_counter:- % if counter is not defined yet
assert(counter(1)).
You then place inc_counter in the clauses whose iterations you want to count, and query the end result using counter(X).