Restriction to sort an array in Minizinc - constraint-programming

I am trying to build a model with a parameter n = 5 which represent the length of an array. The model also have a decision variable that takes the range 0..9 and involves two constraints. The first of all is that the sum of the values of the array must be equal to the product of values of this array and the last one must be that the order of the values should be sorted increasing.
I attach the code:
int: n = 5; % Array length
var 0..9: x;
array[1..n] of var 1..n: V;
% Constraints
constraint sum(V) = product(V);
constraint increasing(array[1..n] of var 1..n: V); % Sort problem
solve satisfy;
output[show(V)];

If you want to add the constraint that the array V is ordered, you can use the increasing constraint from the library
include "globals.mzn";
% ...
constraint increasing(V);
You must also include the file "globals.mzn" which includes the definition of increasing.
The complete model is thus:
include "globals.mzn";
int: n = 5; % Array length
var 0..9: x;
array[1..n] of var 1..n: V;
% Constraints
constraint sum(V) = product(V);
constraint increasing(V);
solve satisfy;
output[show(V)];

When possible, using an existing constraint as indicated in the accepted answer is great. If there is no available constraint, it can be good to also know how to specify your own predicate.
A complete model including your own specification of increasing could look like the following.
int: n = 5; % Array length
var 0..9: x;
array[1..n] of var 1..n: V;
predicate increasing(array[1..n] of var 1..n: V) =
forall(i in 1..n-1) (
V[i] <= V[i+1]
);
% Constraints
constraint sum(V) = product(V);
constraint increasing(V);
solve satisfy;
output[show(V)];

Related

Can't evaluate at compile time - NIM

Hi I'm starting to play around with NIM
I get a "can't evaluate at compile time" error on this code:
import strutils
type
Matrix[x, y: static[int], T] = object
data: array[x * y, T]
var n,m: int = 0
proc readFile() =
let f = open("matrix.txt")
defer: f.close()
var graph_size = parseInt(f.readline)
var whole_graph: Matrix[graph_size, graph_size, int]
for line in f.lines:
for field in line.splitWhitespace:
var cell = parseInt(field)
whole_graph[n][m] = cell
m = m + 1
n = n + 1
readFile()
Any help appreciated.
Unless you absolutely positively need array in this scenario while not knowing its size at compile-time, you may want to rather swap to the seq type, whose size does not need to be known at compile-time.
Together with std/enumerate you can even save yourself the hassle of tracking the index with n and m:
import std/[strutils, enumerate]
type Matrix[T] = seq[seq[T]]
proc newZeroIntMatrix(x: int, y: int): Matrix[int] =
result = newSeqOfCap[seq[int]](x)
for i in 0..x-1:
result.add(newSeqOfCap[int](y))
for j in 0..y-1:
result[i].add(0)
proc readFile(): Matrix[int] =
let f = open("matrix.txt")
defer: f.close()
let graph_size = parseInt(f.readline)
var whole_graph = newZeroIntMatrix(graph_size, graph_size)
for rowIndex, line in enumerate(f.lines):
for columnIndex, field in enumerate(line.split):
let cell = parseInt(field)
whole_graph[rowIndex][columnIndex] = cell
result = whole_graph
let myMatrix = readFile()
echo myMatrix.repr
Further things I'd like to point out though are:
array[x * y, T] will not give you a 2D array, but a single array of length x*y. If you want a 2D array, you would most likely want to store this as array[x, array[y, T]]. That is assuming that you know x and y at compile-time, so your variable declaration would look roughly like this: var myMatrix: array[4, array[5, int]]
Your Matrix type has the array in its data field, so trying to access the array with that Matrix type needs to be done accordingly (myMatrix.data[n][m]). That is, unless you define proper []and []= procs for the Matrix type that do exactly that under the hood.

getting result from doopl in python

Hi I'm using doOPL in python.
The following is part of my code.
with create_opl_model(model="phase0.mod",data="prob1.dat") as opl:
# tuple can be a list of tuples, a pandas dataframe...
# Generate the problem and solve it.
start_time = time.time()
opl.mute()
opl.run()
print("obj:",opl.objective_value,", time:",(time.time() - start_time))
After running it, I would like to check the result of decision variable x
opl.get_table('x')
But it doesn't work saying expecting tupleset x was passed.
I'm looking forward your help.
I think get_table() will only work for tables (aka tuple sets) that you created explicitly in post-processing. So you have to create this table in post processing.
Consider this example definition of x:
range I = 1..2;
range J = 1..4;
dvar float+ x[I][J];
In post-processing, you can do
tuple R {
int i;
int j;
float val;
}
{R} xResult = { <i,j,x[i][j]> | i in I, j in J };
With that you should be able to to opl.get_table('xResult') and in this table you should have all the triplets (i, j, x[i][j]).

number as an object, or storing properties of a number

in designing an algebraic equation modelling system, I had this dilemma: we cannot associate properties to a number, if I turn the number to a table with a field "value" for example, I can overload arithmetic operators, but not the logic operator since that only works when both operands have same metatable, while my users will compare "x" with numbers frequently.
For example, here is a minimal equation solver system:
x = 0
y = 0
eq1 = {function() return 2*x + 3*y end, rhs = 1 }
eq2 = {function() return 3*x + 2*y end, rhs = 2 }
p = {{x,y},{eq1, eq2}}
solve(p)
The "solve()" will process table "p" to get all coefficients of the equation system and rhs. However, it is essential, a user can associate properties to "x" and "y", for example, lower bound, upper bound. I tries using table,
x = {val=0, lb=0, ub=3}
y = {val=1,lb=3,ub=5}
....
and write metamethods for "x" and "y" such that arithmetic operating will act on x.val and y.val. However, in a scripting environment, we also need to compare "x" with numbers, i.e., "if x>0 then ...". And I stuck here. An ugly solution is to ask users to use x.val, y.val everywhere in modelling the equation and scripting. Does anyone here has similar need to associate properties to a number, and the number can still be used in arithmetic/logic operations?
Something like this could work:
x = {val = 10}
mt = {}
mt.__lt = function (op1, op2)
if (type(op1) == 'table') then a = op1.val else a = op1 end
if (type(op2) == 'table') then b = op2.val else b = op2 end
return a < b
end
setmetatable(x, mt)
print(x < 5) -- prints false
print(x < 15) -- prints true
print(x < x) -- prints false
print(5 < x) -- prints true
Of course, you would write similar methods for the other operators (__add, __mul, __eq and so on).
If you'd rather not use type()/reflection, you can use an even dirtier trick that takes advantage of the fact that unary minus is well, unary:
mt = {}
mt.__unm = function (num) return -(num.val) end
mt.__lt = function (a, b) return -(-a) < -(-b) end
This is rather simple if you have access to the debug library, do you?
debug.setmetatable(0, meta)
meta will be the metatable of ALL numbers. This will solve your logical overloading problem.
However if you would prefer assigning properties to numbers, there is a way you could do this, I wrote a quick example on how one would do so:
local number_props = {
{val="hi"},
{val="hi2"}
}
debug.setmetatable(0,{__index=function(self,k)return number_props[self][k]end})
print((1).val, (2).val)

Max. Product Dynamic Programming

So I was trying to solve the Max. Product Question and came up with the following recursion :
maxProd(n) = max of [k*(n-k),k*maxProd(n-k),maxProd(k)*(n-k),maxProd(k)*maxProd(n-k)]
However in the second solution given on that link they have skipped the maxProd(k)*maxProd(n-k).
int maxProd(int n)
{
// Base cases
if (n == 0 || n == 1) return 0;
// Make a cut at different places and take the maximum of all
int max_val = 0;
for (int i = 1; i < n; i++)
max_val = max(max_val, i*(n-i), maxProd(n-i)*i);
// Return the maximum of all values
return max_val;
}
Is that still right? If so, how? Wouldn't it give wrong answers when the only way to get Max. Product is recursively split both k and n-k?
The formula you wrote here will also work. But they have a smaller one.
Note that you can get any solution from the original formula, since it checks all possible ways to choose the first cut. So if the first cut has to be i, then i will be checked, and recursively continue to the other parts.
If you use memoization, you'll get the same runtime for both formulas.

How do you generate all permutations of n variables, each one taking on 1 or 0?

For example, let's say I want to generate all permutations of two values,each one could be 0 or 1, I would get:
[11,10,01,00]
Note here the first variable varies the slowest, so it stays fixed while the remaining one varies.
In the case of three variables, I would get
[111,110,101,100,011,010,001,000]
I see that there should be a recursive definition for it, but it's not clear enough in my head so that I could express it.
This is not about permutations, but about combinations and you can generate them easily in Haskell:
replicateM 3 "01"
= ["000","001","010","011","100","101","110","111"]
If you need actual integers:
replicateM 3 [0, 1]
= [[0,0,0],[0,0,1],[0,1,0],[0,1,1],
[1,0,0],[1,0,1],[1,1,0],[1,1,1]]
Finally if the values at the various positions are different:
sequence [".x", ".X", "-+"]
= ["..-","..+",".X-",".X+","x.-","x.+","xX-","xX+"]
This too works for integers, of course:
sequence [[0,1], [0,2], [0,4]]
= [[0,0,0],[0,0,4],[0,2,0],[0,2,4],
[1,0,0],[1,0,4],[1,2,0],[1,2,4]]
If you want permuations, as in a list of lists, here's a solution using a list monad.
\n -> mapM (const [0, 1]) [1..n]
ghci> :m +Data.List
ghci> permutations [0,1]
[[0,1],[1,0]]
(Edited based on feedback)
The smallest n-digit binary integer is 000..0 (n times), which is 0.
The largest n-digit binary integer is 111...1 (n times), which is 2^n - 1.
Generate the integers from 0 to 1<<n - 1 and print out the values you have.
Haskell's Int should be safe for <= 28 binary variables.
Hope that helps.
I don't know haskel, but here is a block of psuedo code on how I do permutations.
var positions = [0,0,0];
var max = 1;
done:
while(true){
positions[0]++; //Increment by one
for (var i = 0; i < positions.length; i++) {
if(positions[i] > max){ //If the current position is at max carry over
positions[i] = 0;
if(i+1 >= positions.length){ //no more positions left
break done;
}
positions[i+1]++;
}
}
}

Resources