Problem with decision variabile when there are more choices - variables

I have a series of jobs. For each job I have a series of operations and each operation requires a machine. But there are some operations that have the ability to choose multiple machines.
Ex:
job 1: operation 1 machine 4
operation 2 machine 2
operation 3 (machine 2 or machine 3)
I have a binary decision variable Y (ijm) where i is the operation, j the job and m the machine.
What must happen is that Y(114) = 1, Y (212) = 1 but for operation 3 we have two choices Y(312) = 0 and Y(313) = 1 or the opposite.
How can I implement it on Cplex? I can't find a way.

You could use a logical constraint like this in OPL:
((x==2) && (y==1)) || ((x==1) && (y==2));
But you could also have a look at CPOptimizer within CPLEX because your model looks like a scheduling problem.

A simple way to model your requirement that Y(312) = 0 and Y(313) = 1 or the opposite would be to add a constraint that the sum of the alternatives must be 1, i.e. in your case add a constraint:
Y(312) + Y(313) = 1
Then if the variables are binary or integer then this will achieve your aim.

Related

Can PICT handle independent parameters

Can PICT (=Pairwise Independent Combinatorial Testing) handle/model independent parameters.
For example in following input a and b are independent, so they should not be combined.
Input in PICT:
a: 1, 2, 3, 4
b: 5, 6, 7, 8
//some line which models the independence: a independent of b
Output, that I would expect:
a b
1 5
2 6
3 7
4 8
This example, with only 2 parameters, of course normally would not make much sense, but it's illustrative.
The same could be applied to 3 parameters (a,b,c), where a is independent of b, but not c.
The main goal of declaring parameters as independent would be the reduce the number of tests.
I read the paper/user guide to PICT, but I didn't found any useful information.
I will answer my question by myself:
The solution is to define submodels and set the default order from 2 (=pairwise) to 1 (= no combination).
For example parameter a = {a_1, a_2, a_3} should be independent of
b = {b_1, b_2, b_3} and
c = {c_1, ..., c_4}.
Therefor I would expect 12 tests ((b x c) + a).
Resulting in the following input file:
a: 1,2,3
b: 1,2,3
c: 1,2,3,4
{b,c}#2
{b,c}#2 defines a submodel, consisting of b and c, which uses pairwise combination.
And running pict with the option: "/o:1".
In PICT you can define conditions and achieve your goal to not combine them with the rest. You can add additional option as N/A and have something like this;
If [A] = '1' Then [B] = 'N/A';
This is one possible option to handle this case.

Pyomo scheduling

I am trying to formulate a flowshop scheduling problem in Pyomo. This is an Abstract model
Problem description
There are 3 jobs (chest, door and chair) and 3 machines (cutting, welding, packing in that order). Objective is to minimise the makespan. The python code and the data are as follows.
## flowshop.py ##
from pyomo.environ import *
flowshop = AbstractModel()
flowshop.jobs = Set()
flowshop.machines = Set()
flowshop.machinesN = Param()
flowshop.jobsN = Param()
flowshop.proc_T = Param(flowshop.jobs,
flowshop.machines,
within=NonNegativeReals)
flowshop.start_T = Var(flowshop.jobs,
flowshop.machines,
within=NonNegativeReals)
flowshop.makespan = Var(within=NonNegativeReals)
def makespan_rule(flowshop,i,j):
return flowshop.makespan >= flowshop.start_T[i,j]+flowshop.proc_T[i,j]
flowshop.makespan_cons = Constraint(flowshop.jobs,
flowshop.machines,
rule=makespan_rule)
def objective_rule(flowshop):
return flowshop.makespan
flowshop.objc = Objective(rule=objective_rule,sense=minimize)
## data.dat ##
set jobs := chest door chair ;
set machines := cutting welding packing ;
param: machinesN := 3 ;
param: jobsN := 3 ;
param proc_T:
cutting welding packing :=
chest 10 40 45
door 30 20 25
chair 05 30 15
;
I havent added all the constraints yet, I plan to add them after this issue gets fixed. In the code (flowhop.py) above, for the makespan_rule, I want the makespan to be more that the completion time of only the last machine.
Currently, it is set to be more than completion times of all the machines.
For that, I believe, I have to get the last index of the machines set.
For that, I tried flowshop.machines[-1], but it gives an error saying:
Cannot index unordered set machines
How do I solve this issue?
Thanks for the help.
PS - I am also struggling to model the binary variables used to define the precedence of a job. If you have any ideas regarding that, that would also be helpful.
As the error says Cannot index unordered sets, the set flowshop.machines is not ordered. One needs to provide ordered=True argument in the while declaring the set -
flowshop.machines = Set(ordered=True)
After this, one can access any element by normal indexing - flowshop.machines[i]
For the binary variables, one can declare them as -
c = flowshop.jobsN*(flowshop.jobsN-1)/2
flowshop.prec = Var(RangeSet(1,c),within=Binary)
Then, this variable can be used to decide the precedence between 2 jobs and to formulate the assignment constraints. The precedence variable corresponding to a pair of jobs can be found out using the indices of the jobs (for which the flowshop.jobs has to be an ordered set - flowshop.jobs = Set(ordered=True))

Pandas: aggregation on multi-level groups

I have a df that looks something like this:
batch group reading temp test block delay
0 9551 Control 340 22.9 1 X 35
1 9551 Control 345 22.9 1 Y 35
I need to group by 'group' and 'block', e.g. my means would look like so:
df.groupby(['block', 'group']).reading.mean().unstack().transpose()
block X Y
group
Control 347.339450 350.427273
Trial 347.790909 350.668182
What would be the best way to call a 2 argument function like scipy.stats.ttest_ind on data sliced this way so I end up with a table of t tests for
control vs trial in x
control vs trial in y
x vs y in control
x vs y in trial
Do you want to group and aggregate the data before applying the t-test? I think you want to select subsets of the data. Grouping can do that, but masking might get the job done more simply.
Offhand, I'd say you want something like
scipy.stats.ttest_ind(df[(df.group == 'Control') & (df.block == 'X')].reading,
df[(df.group == 'Trial') & (df.block == 'X')].reading)

Comparing vectors

I am new to R and am trying to find a better solution for accomplishing this fairly simple task efficiently.
I have a data.frame M with 100,000 lines (and many columns, out of which 2 columns are relevant to this problem, I'll call it M1, M2). I have another data.frame where column V1 with about 10,000 elements is essential to this task. My task is this:
For each of the element in V1, find where does it occur in M2 and pull out the corresponding M1. I am able to do this using for-loop and it is terribly slow! I am used to Matlab and Perl and this is taking for EVER in R! Surely there's a better way. I would appreciate any valuable suggestions in accomplishing this task...
for (x in c(1:length(V$V1)) {
start[x] = M$M1[M$M2 == V$V1[x]]
}
There is only 1 element that will match, and so I can use the logical statement to directly get the element in start vector. How can I vectorize this?
Thank you!
Here is another solution using the same example by #aix.
M[match(V$V1, M$M2),]
To benchmark performance, we can use the R package rbenchmark.
library(rbenchmark)
f_ramnath = function() M[match(V$V1, M$M2),]
f_aix = function() merge(V, M, by.x='V1', by.y='M2', sort=F)
f_chase = function() M[M$M2 %in% V$V1,] # modified to return full data frame
benchmark(f_ramnath(), f_aix(), f_chase(), replications = 10000)
test replications elapsed relative
2 f_aix() 10000 12.907 7.068456
3 f_chase() 10000 2.010 1.100767
1 f_ramnath() 10000 1.826 1.000000
Another option is to use the %in% operator:
> set.seed(1)
> M <- data.frame(M1 = sample(1:20, 15, FALSE), M2 = sample(1:20, 15, FALSE))
> V <- data.frame(V1 = sample(1:20, 10, FALSE))
> M$M1[M$M2 %in% V$V1]
[1] 6 8 11 9 19 1 3 5
Sounds like you're looking for merge:
> M <- data.frame(M1=c(1,2,3,4,10,3,15), M2=c(15,6,7,8,-1,12,5))
> V <- data.frame(V1=c(-1,12,5,7))
> merge(V, M, by.x='V1', by.y='M2', sort=F)
V1 M1
1 -1 10
2 12 3
3 5 15
4 7 3
If V$V1 might contain values not present in M$M2, you may want to specify all.x=T. This will fill in the missing values with NAs instead of omitting them from the result.

Deterministic/non-deterministic state system mapping

I read in a book on non-deterministic mapping there is mapping from Q*∑ to 2Q for M=(Q,∑,trans,q0,F)
where Q is a set of states.
But I am not able to understand how it's 2Q;
if there are 3 states a, b, c, how does it map to 8 states?
I always found that the easiest way to think about these (since the set of states is finite) is as having each of those subsets be an encoding of a base-2 number that ranges from 0 (all bits zero) to 2|Q|-1 (all bits one), where there are as many bits in the number as there are members in the state set, Q. Then, you can just take one of these numbers and map it into a subset by using whether a particular bit in the number is set. Easy!
Here's a worked example where Q = {a,b,c}. In this case, |Q| is 3 (there are three elements) and so 23 is 8. That means we get this if we say that the leading bit is for element a, the next bit is for b, and the trailing bit for c:
0 = 000 = {}
1 = 001 = {c}
2 = 010 = {b}
3 = 011 = {b,c}
4 = 100 = {a}
5 = 101 = {a,c}
6 = 110 = {a,b}
7 = 111 = {a,b,c}
See? That initial three states has been transformed into 8, and we have a natural numbering of them that we could use to create the labels of those states if we chose.
Now, to the interpretations of this within a non-deterministic context. Basically, the non-determinism means that we're uncertain about what state we're in. We represent this by using a pseudo-state that is the set of “real” states that we might be in; if we have total non-determinism then we are in the pseudo-state where all real-states are possible (i.e., {a,b,c}) whereas the pseudo-state where no real-states are possible (i.e., {}) is the converse (and really ought to be impossible to reach in the transition system). In a real system, you're usually not dealing with either of those extremes.
The logic of how you convert the deterministic transition system into a non-deterministic one is rather more complex than I want to go into here. (I had to read a substantial PhD thesis to learn it so it's definitely more than an SO answer's worth!)
2Q means the set of all subsets of Q. For each state q and each letter x from sigma, there is a subset of Q states to which you can go from q with letter x. So yeah, if there are three states abc the set 2Q consists of 8 elements {{}, {a}, {b}, {c}, {a,b}, {a,c}, {b,c}, {a,b,c}}. It doesn't map to 8 states, it maps to one of these 8 sets. HTH