-2

Here is the original table:

       Column1   Column2
Row1    4 (x1)    6(x3)
Row2    5 (x2)    4(x4)

x1, x2, x3, x4 mean the new values after swapping

Originally the variance of each column is:

Var(column1)= var(c(4,5))=0.5
Var(column2)= var(c(6,4))=2

After swapping the values lesser than 10 in the original table, the new variances of two columns respectively are:

New_Var(column1)=(x1-(x1+x2)/2)^2+(x2-(x1+x2)/2)^2
New_Var(column2)=(x3-(x3+x4)/2)^2+(x4-(x3+x4)/2)^2

My objective is to

Minimize  | New_Var(column1) – 0.5 | + | New_Var(column2) – 2 |

Here the notation ‘| |’ means absolute.

The constrains are that x1, x2, x3, x4 can only get a value respectively from a fixed domain, here say {4, 5, 4, 6}. And all the four variables need be swapped to a different value, say that x1 cannot be 4, x3 cannot be 6 so on so forth.

Note that all values in the original table here are larger than 10 because I just want to make the question look like simple.

In realistic, the table is 6000*10 which is very large. So outputting all the unique permutations and testing is not a suitable method.

I have read the task view of optimization in R. There are a lot of optimization packages there. So I need more specific guidance.

Below is the function that can swap values lesser than 10 to a different values lesser than 10 respectively. Hope it helps.

derangement <- function(x){
  if(max(table(x)) > length(x)/2) return(NA)
  while(TRUE){
    y <- sample(x)
    if(all(y != x)) return(y)
  }
}

swapFun <- function(x, n = 10){
  inx <- which(x < n)
  y <- derangement(x[inx])
  if(length(y) == 1) return(NA) 
  x[inx] <- y
  x
}

set.seed(10)
swapFun(c(1,2,3,10,4,11,2,12))
#[1]  2  4 10  2 11  1 12

How can I solve it? Thanks.

Tom
  • 31
  • 7
  • I do not understand why this question is regarded as too broad. It is surely just a optimization problem. Could you tell me what is wrong with this question? – Tom Aug 07 '18 at 08:37
  • I edit it again in another question. – Tom Aug 07 '18 at 08:47

2 Answers2

0

For problems this size you can easily use brute force.

In R:

library(combinat)
pp <- permn(c(1,2,2,3)) ## construct list of permutations
pp <- unique(pp)        ## unique permutations only

Apply your (new) constraint "x1 cannot be 1, x2 cannot be 2, x3 cannot be 2, x4 cannot be 3":

ok <- function(X) {
   !(X[1]==1 | X[2]==2 | X[3]==2 | X[4]==3)
}
pp <- pp[sapply(pp,ok)]

There are length(pp) == 2 non-identical, valid combinations (you can test whether length(pp)>0 to see if there are any valid combinations left).

## define objective function
f <- function(X) { (X[1]-X[2])^2 + (X[1]-X[3])^2+ 
        (X[2]-X[3]-X[4])^2+X[4]^2+X[3]^2 }
## compute obj function for all permutations
vals <- sapply(pp,f)
## identify minima
pp[which(vals==min(vals))]
## [[1]]
## [1] 2 3 1 2 

This will break down as the domain grows and the size of (n!) gets large ... at which point you may need to start doing research in the domain of integer programming (e.g. see the Optimization Task View)

In Python you would first generate the list of permutations with itertools.permutations (see this question) and then use a comprehension to apply the objective function across the iterator.

Ben Bolker
  • 211,554
  • 25
  • 370
  • 453
  • Yes. Thanks a lot. I forget to add another condition, say variables x1 cannot be 1, x2 cannot be 2, x3 cannot be 2, x4 cannot be 3. I know sometimes there will no feasible solution. so first I will use another function to test whether there is a feasible solution. Then I will use the optimization package to get the optimal solution. – Tom Aug 06 '18 at 22:43
  • by the way, I hope this isn't homework ... I probably should have asked for more context, and more evidence of effort on your part, before answering ... – Ben Bolker Aug 06 '18 at 22:49
  • Thanks. It is definitely not my homework. Actually I have written this kind of funtion to deal with the problem. But when the length of the domain becomes very large., this approach need a lot computing time......So I come here to ask whether there are some good solvers in R can tackle with this problem quickly. I am not familiar with this kind of packages. – Tom Aug 06 '18 at 22:57
  • OK: in your question should try to give a better sense of a realistic context: how big are the problems you are trying to solve? And what have you already done? Otherwise, people (like me) will waste time repeating what you've done ... As a start, try following the "task view" link in my answer. Also, you're supposed to frame problems as "how do I solve?" and not "is there a package" (even if "use package XX" turns out to be the answer ...) – Ben Bolker Aug 06 '18 at 23:07
  • Yes. Thanks a lot. I also know the 'task view' in the previous time. There are really a lot packages there, I gave up reading it in the previous time because I think my problem is very special and it is difficulty for me to find the suitable package. So I come here to ask some more specific guidances....... But now I will read the 'task view' carefully.... – Tom Aug 06 '18 at 23:15
  • Yes. I see. Thanks a lot. – Tom Aug 07 '18 at 07:10
0

I write this sometimes as a set of linear assignment constraints:

 sum(i, δ[i,j]) = 1  forall j
 sum(j, δ[i,j]) = 1  forall i
 x[i] = sum(j, δ[i,j] * v[j])
 δ[i,j] ∈ {0,1}     (binary variables)
 v = [1, 2, 2, 3]   (constants)  
 i,j ∈ {1..4}       (indices} 

Here δ is a binary variable that performs like a permutation matrix.

Erwin Kalvelagen
  • 15,677
  • 2
  • 14
  • 39
  • Could you please show me which optimization package you use for this problem? – Tom Aug 06 '18 at 23:31
  • 1
    There is no good support for general MINLP models in R I believe. If the model was linear OMPR is interesting. If the model is quadratic, Cplex or Gurobi are good candidates. – Erwin Kalvelagen Aug 06 '18 at 23:35
  • Thanks. I will tell you the result later. – Tom Aug 07 '18 at 07:11
  • I have reedited this question. I think it is not a MINLP model but a integer nonlinear model. Could you please give me some specific guidance of how to write the code of this example in R? – Tom Aug 07 '18 at 11:06
  • I still need `x1` !=1, `x2`!=2, `x3`!=2, `x4'!=3. It seems the set of constraints cannot indicate this. .... – Tom Aug 07 '18 at 11:18
  • This is so trivial. E.g. `x1 != 1` means `δ[1,1]=0`. – Erwin Kalvelagen Aug 07 '18 at 11:25
  • Yes, I got it. Could you please send me the link that show the similar problem solved by the written R codes. The example will be very helpfully because I have no experience of written this kind of code. Many thanks. – Tom Aug 07 '18 at 11:27