Defining Set of Set in OPL (or indexed set) - set

I try to define set of set in OPL. The problem is:
I have several Computing Platforms, for example: {"DC1", "DC2", "MP1"}
Each Computing Platforms can have several configuration, for example: DC1 may have {"conf1", "conf3"}, DC2 may have {"conf1", "conf2", "conf3"} and MP1 may have {"conf1", "conf3"}
each Computing Platforms have several attributes like capacity (vcpu)
the set of set in AMPL, and the parameter could be easily written as the following:
set COMPPLATFORMS;
set CONFCP{COMPPLATFORMS}
param vcpu {d in COMPPLATFORMS, CONFCP[d]};
However, in OPL we do not have a straightforward way of declaring an indexed set. I notice that we could use either tuple or maybe some preprocessing. But now I am not sure how to declare the parameter "vcpu" for the indexed set?
I know that we could have an array of sets, or sets of array. But could we have a set of set?
Is there any example in OPL that follow the similar structure?
Thank you

See sets of sets in the example power sets in how to with OPL
{string} s={"A","B","C","D"};
range r=1.. ftoi(pow(2,card(s)));
{string} s2 [k in r] = {i | i in s: ((k div (ftoi(pow(2,(ord(s,i))))) mod 2) == 1)};
execute
{
writeln(s2);
}

Related

Julia type instability: Array of LinearInterpolations

I am trying to improve the performance of my code by removing any sources of type instability.
For example, I have several instances of Array{Any} declarations, which I know generally destroy performance. Here is a minimal example (greatly simplified compared to my code) of a 2D Array of LinearInterpolation objects, i.e
n,m=5,5
abstract_arr=Array{Any}(undef,n+1,m+1)
arr_x=LinRange(1,10,100)
for l in 1:n
for alpha in 1:m
abstract_arr[l,alpha]=LinearInterpolation(arr_x,alpha.*arr_x.^n)
end
end
so that typeof(abstract_arr) gives Array{Any,2}.
How can I initialize abstract_arr to avoid using Array{Any} here?
And how can I do this in general for Arrays whose entries are structures like Dicts() where the Dicts() are dictionaries of 2-tuples of Float64?
If you make a comprehension, the type will be figured out for you:
arr = [LinearInterpolation(arr_x, ;alpha.*arr_x.^n) for l in 1:n, alpha in 1:m]
isconcretetype(eltype(arr)) # true
When it can predict the type & length, it will make the right array the first time. When it cannot, it will widen or extend it as necessary. So probably some of these will be Vector{Int}, and some Vector{Union{Nothing, Int}}:
[rand()>0.8 ? nothing : 0 for i in 1:3]
[rand()>0.8 ? nothing : 0 for i in 1:3]
[rand()>0.8 ? nothing : 0 for i in 1:10]
The main trick is that you just need to know the type of the object that is returned by LinearInterpolation, and then you can specify that instead of Any when constructing the array. To determine that, let's look at the typeof one of these objects
julia> typeof(LinearInterpolation(arr_x,arr_x.^2))
Interpolations.Extrapolation{Float64, 1, ScaledInterpolation{Float64, 1, Interpolations.BSplineInterpolation{Float64, 1, Vector{Float64}, BSpline{Linear{Throw{OnGrid}}}, Tuple{Base.OneTo{Int64}}}, BSpline{Linear{Throw{OnGrid}}}, Tuple{LinRange{Float64}}}, BSpline{Linear{Throw{OnGrid}}}, Throw{Nothing}}
This gives a fairly complicated type, but we don't necessarily need to use the whole thing (though in some cases it might be more efficient to). So for instance, we can say
using Interpolations
n,m=5,5
abstract_arr=Array{Interpolations.Extrapolation}(undef,n+1,m+1)
arr_x=LinRange(1,10,100)
for l in 1:n
for alpha in 1:m
abstract_arr[l,alpha]=LinearInterpolation(arr_x,alpha.*arr_x.^n)
end
end
which gives us a result of type
julia> typeof(abstract_arr)
Matrix{Interpolations.Extrapolation} (alias for Array{Interpolations.Extrapolation, 2})
Since the return type of this LinearInterpolation does not seem to be of known size, and
julia> isbitstype(typeof(LinearInterpolation(arr_x,arr_x.^2)))
false
each assignment to this array will still trigger allocations, and consequently there actually may not be much or any performance gain from the added type stability when it comes to filling the array. Nonetheless, there may still be performance gains down the line when it comes to using values stored in this array (depending on what is subsequently done with them).

Is it possible to pre-assign values to decision variables in CPLEX OPL

I have a large number of variables ( both Binary and Continuous). Therefore I have determined a logic to assign some variables set to 0 so that they do not become part of the optimisation process.
For example I have a binary decision variable y[b][t]:
where b varies from 1 to 100
and t from 1 to 5.
I could determine using some logic that y[20][2] onwards to y[100][2] would be 0. I want to assign the fixed value of 0 to these variables y[20][2] onwards to y[100][2] thereby reducing the number of variables in my optimisation problem. While y is a binary decision variable I have other continuous variable as well which I would like to similarly set to 0 in advance.
Is there a way how this can be achieved ? I haven't used Python with CPEX but hear that this can be probably be achieved by setting a lower and upper bound of the variables. Is there a similar method in OPL.
----Added 13th Aug
May be I was not very clear or I could not understand the solution suggested.
What I wanted is say I have the following decision variable Xbmt ...(I have a few of them)
Originally declared as :
dvar float+ Xbmt[PitBlocks][Plants][TimePeriods];
But for some of the PitBlocks and some time periods I want to define this decision variable as 0. Those time periods for which I want to set the decision variable as 0 are defined in a tuple nullVariables. It has block id same as PitBlocks, and it has time_period same as TimePeriod. Hence I want something like below. But I cannot declare the decision variable twice. I need it 0 only for those ids in the nullVariable set.
dvar float+ Xbmt[NullVariablesSet.block_id][Plants][NullVariablesSet.time_period] in 0..0;
How can this be achieved where some of Xbmt remain as decision variables where as some are removed by setting as 0
see https://github.com/AlexFleischerParis/zooopl/blob/master/zoopreassign.mod
within
Making Decision Optimization Simple
int nbKids=300;
{int} seats={40,30}; // how many seats, {} means this is a set
float costBus[seats]=[500,400];
// Now let s see how preassign some decision variables
// Suppose we know that we have exactly 6 buses 40 seats
{int} preassignedseats={40};
int preassignedvalues[preassignedseats]=[6];
dvar int+ nbBus[s in seats]
in
((s in preassignedseats)?preassignedvalues[s]:0)
..
((s in preassignedseats)?preassignedvalues[s]:maxint);
minimize sum(b in seats) costBus[b]*nbBus[b];
subject to
{
sum(b in seats) b*nbBus[b]>=nbKids;
}

Programming and data structures

Suggest a data structure for representing a subset S of integers from 1 to n. Following operations on the set S are to be performed in constant time (independent of cardinality of S).
You may assume that the data structure has been suitable initialized.
(i). MEMBER (X):
Check whether X is in the set S or not
(ii). FIND-ONE(S): If S is not empty, return one element of the set S (any arbitrary element will do)
(iii). ADD (X): Add integer X to set S
(iv). DELETE (X): Delete integer X from S.
My analysis:-
I think hash table will work fine here ,but how will hash table work for FIND-ONES(S) operation.Because i might need to scan the entire has table to look for the present element.
You can just use a regular hashset for this in java. In the case of the FIND-ONE(S) what you would do is, call isEmpty(). If that returns false, use the built in iterator, and just get the first value the iterator returns.
A hash table would work, but you need to think about the specific implementation. If you use the compact version from Python 3.6, you can perform FIND-ONEs in constant time by inspecting the entries list.
For example, the dictionary:
d = {'timmy': 'red', 'barry': 'green', 'guido': 'blue'}
is represented as follows:
indices = [None, 1, None, None, None, 0, None, 2]
entries = [[-9092791511155847987, 'timmy', 'red'],
[-8522787127447073495, 'barry', 'green'],
[-6480567542315338377, 'guido', 'blue']]

Alloy constraint specification

I wrote the following code block in Alloy:
one h: Human | h in s.start => {
s'.currentCall = h.from
}
I want to pick one 'human' from a set of humans (s.start) and set a variable (s'.currentCall) equal to h.from.
However I think this code is saying: There is only one human in s.start, where
s'.currentCall = h.from
is true.
Is my assumption correct? And how should I fix this?
You are absolutely correct, the meaning of the one quantifier is that there is exactly one element in the given domain (set) such that the quantifier body holds true.
Regarding your original goal of picking one element from a set and setting its field value to something: that sounds like an imperative update, and you can't really do that directly in Alloy; Alloy is fully declarative, so you can only assert logical statements about the sets and relations for a bounded universe of discourse.
If you just change one to some and also change the implication to conjunction, and then run the analysis (a simple run command to find a valid instance), the Alloy Analyzer will find a model in which the value s'.currentCall is equal to h.from for some (arbitrary) h from s.start:
pred p[s, s': S] {
some h: s.start | s'.currentCall = h.from
}
run p
I hope this is what you want to achieve.

USing AddExpression / MathExpression in Weka

I am working on a very basic WEKA assignment, and I'm trying to use WEKA to preprocess data from the GUI (most current version). I am trying to do very basic if statements and mathematical statements in the expression box when double clicking on MathExpression and I haven't had any success. For example I want to do
if (a5 == 2 || a5 == 0) then y = 1; else y = 0
Many different variations of this haven't worked for me and I'm also unclear on how to refer to "y" or if it needs a reference within the line.
Another example is -abs(log(a7)–3) which I wasn't able to work out either. Any ideas about how to make these statements work?
From javadoc of MathExpression
The 'A'
letter refers to the value of the attribute being processed.
Other attribute values (numeric only) can be accessed through
the variables A1, A2, A3, ...
Your filter applies to all attributes of your dataset. If I load iris dataset and apply following filter.
weka.filters.unsupervised.attribute.MathExpression -E log(A).
your attribute ,sepallength values change as following.
Before Filter After Filter
Minimum 4.3 Minimum 1.459
Maximum 7.9 Maximum 2.067
Mean 5.843 Mean 1.755
StdDev 0.828 StdDev 0.141
Also if you look to javadoc, there is no if else function but ifelse function. Therefore you should write something like
ifelse ( (A == 2 || A == 0), 1,0 )
Also this filter applies to all attributes. If you want to change only one attribute and according to other attribute values ; then you need to use "Ignore range option" and use A1,A2 to refer to other attribute values.
if you need to add new attribute use AddExpression.
An instance filter that creates a new attribute by applying a mathematical expression to existing attributes.

Resources