Minizinc: create an array of int pairs - arrays

What is the Minizinc syntax to create an array of n int pairs like this:
{(x1,y1), (x2,y2),....(xn,yn)}
and how can I access to a specific element j to get, for example, its y value?

In MiniZinc you would currently use multi-dimensional arrays for this purpose. If, for example, you want to create n pairs of integer variables you can use:
array [1..n, 1..2] of var int: pairs;
You could then access each pair, but also each element. If, for example, you want to access pair j, then you can use the statement pairs[j]. This is an array of dimensions 1..2; you can access the second element (y), using pairs[j][y].
This approach allows you to use the variables directly, but you can also use pairs for predicates that call for arrays.

Related

Using findmin() in data from array composed of mutable struct elements - Julia

Suppose I have the following struct:
mutable struct Car
load
locale
availability
odometer
end
And I have created an array:
fleet = Vector{Car}(undef, num_cars)
for i in 1:num_cars
a, b, c, d = rand(4)
fleet[i] = Car(a, b, c, d)
end
How can I find the smallest (with findmin or similar) or biggest (with?) value from, for example, the odometer of all the cars in my array?
Basically, I want to be able to use conditional statements with struct arrays, e.g.: For every element in my struct array, get the ones that a data satisfy a condition and, from those, get the minimum value of another data.
Thanks!
Finding the minimum value is pretty straightforward, using the minimum function, with a mapping argument:
julia> minimum(x->x.odometer, fleet)
0.08468003971220694
If you also want the index of the minimum, you can use the findmin function. Unfortunately, this does not, for some reason, support a function argument, so you have to create a temporary array, and apply findmin to that:
julia> findmin(getfield.(fleet, :odometer))
(0.08468003971220694, 1)
You can also use getproperty instead of getfield, they do the same thing for your struct, I'm not certain which is preferable. Probably, the most idiomatic solution would be to define accessor functions instead of using the field values directly. For example:
odometer(car::Car) = car.odometer
minimum(odometer, fleet)
findmin(odometer.(fleet))
For maximum values, use maximum and findmax.
Julia is about performance.
You should avoid using untyped structs hence your type definition should be:
mutable struct Car
load::Float64
locale::Float64
availability::Float64
odometer::Float64
end
The code for creating Vector can be shorter:
cars = [Car(rand(4)...) for _ in 1:5]
The most efficient way to find the index of the minimum element is:
julia> Base.isless(c1::Car,c2::Car) = c1.odometer < c2.odometer
julia> findmin(cs)
(Car(0.7623514815463603, 0.7523019237133661, 0.37422766075278413, 0.49830949323733464), 3)

What is the difference between these two declarations of array?

I want to know the difference between theses two declarations of these arrays, one is defined like this (double array[a][b][c][d]), the other one is different (double array[a*b*c][d])
double weight4_5[LAYER4][LAYER5][LENGTH_KERNEL][LENGTH_KERNEL];
double weight5_6[LAYER5 * LENGTH_FEATURE5 * LENGTH_FEATURE5][OUTPUT];
if i want to load values to these two arrays with for loops, how can i do it ?
The first one is a 4 Dimensional array.
Access is by weight4_5[i][j][k][l]
The second one is a 2 Dimensional array. It is a flattened array.
Access is basically by weight5_6[x][y] But you need to do some calculations to get the value of x based on the 4D original array.
You can organise it multiple ways as you want, (e.g. row wise, column wise etc) One way is to have
x= ((((i*LAYER5)+j)*LENGTH_FEATURE5)+k)
y = l;

Creating an Array based on range from existing array

Say I have a std::array
std::array<int,8> foo = {1,2,3,4,5,6,7,8};
Now Is it possible to create a new array from an existing array using a range say from index to 2 till 5. So my new array will have items {3,4,5,6}.
I am aware that I could accomplish this using the manual for loop copy mechanism but I wanted to know if there was a faster way of doing that
If you are expecting some easy syntax (like Python, Matlab or Fortran), no.
As #Sphinx said you can use copy.
std::array<int,8> foo = {1,2,3,4,5,6,7,8};
std::array<int,3> foo2;
std::copy(&foo[2], &foo[5], foo2.begin());
// or std::copy(foo.begin() + 2, foo.begin() + 5, foo2.begin());
but take into account that std::array sizes are compile time constants.
So you may need std::vector<int> if you want make the range size variable.

How to "invert" an array in linear time functionally rather than procedurally?

Say I have an array of integers A such that A[i] = j, and I want to "invert it"; that is, to create another array of integers B such that B[j] = i.
This is trivial to do procedurally in linear time in any language; here's a Python example:
def invert_procedurally(A):
B = [None] * (max(A) + 1)
for i, j in enumerate(A):
B[j] = i
return B
However, is there any way to do this functionally (as in functional programming, using map, reduce, or functions like those) in linear time?
The code might look something like this:
def invert_functionally(A):
# We can't modify variables in FP; we can only return a value
return map(???, A) # What goes here?
If this is not possible, what is the best (most efficient) alternative when doing functional programming?
In this context are arrays mutable or immutable? Generally I'd expect the mutable case to be about as straightforward as your Python implementation, perhaps aside from a few wrinkles with types. I'll assume you're more interested in the immutable scenario.
This operation inverts the indices and elements, so it's also important to know something about what constitutes valid array indices and impose those same constraints on the elements. Haskell has a class for index constraints called Ix. Any Ix type is ordered and has a range implementation to make an ordered list of indices ranging from one specified index to another. I think this Haskell implementation does what you want.
import Data.Array.IArray
invertArray :: (Ix x) => Array x x -> Array x x
invertArray arr = listArray (low,high) newElems
where oldElems = elems arr
newElems = indices arr
low = minimum oldElems
high = maximum oldElems
Under the hood listArray uses zipWith and range to associate indices in the specified range to the listed elements. That part ought to be linear time, and so is the one-time operation of extracting elements and indices from an array.
Whenever the sets of the input arrays indices and elements differ some elements will be undefined, which for better or worse blow up faster than Python's None. I believe you could overcome the undefined issue by implementing new Ix a instances over the Maybe monad, for instance.
Quick side-note: check out the invPerm example in the Haskell 98 Library Report. It does something similar to invertArray, but assumes up front that input array's elements are a permutation of its indices.
A solution needing mapand 3 operations:
toTuples views an the array as a list of tuples (i,e) where i is the index and e the element in the array at that index.
fromTuples creates and loads an array from a list of tuples.
swap which takes a tuple (a,b) and returns (b,a)
Hence the solution would be (in Haskellish notation):
invert = fromTuples . map swap . toTuples

algorithm to sort elements of three arrays

Here's the stumper:
Start with three arrays A, B and C with a total of 2n+1 entries.
Write an algorithm to sort all of the entries from all of the arrays
using only the following two methods:
X = sort(X) replaces the array X with the sorted version.
(X , Y) = doubleUp(X , Y) does nothing if X has more elements
than Y, otherwise it removes the first length(X) entries from Y
and appends them to the end of X.
Here's what I've tried so far. If two of the arrays are empty, then just use sort on the nonempty array.
If one of the arrays is empty, then I think I can use doubleUp to get one array to have just one thing and the other array to have everything else, and if that singleton array has the smallest (or largest) element, then that works. So I can use sort after I use doubleUp each time to make sure this happens. I coded this up in Maple and it worked for all the cases I checked.
I have no idea how to do it with 3 arrays though. Anyone have any ideas?
Sounds like nonsense. The total number of entries is odd. The only way to increase the length of an array is to make it the smaller first argument of doubleUp, in which case it ends up with an even number of elements. So unless all the elements are in one array to begin with there's no way to make one array contain all the elements, sorted or otherwise.
So, the desired final result is not a single array containing all the elements in order. Or if it is, then the answer to the question is "it cannot be done".

Resources