0

I am new to R solver and I want to have a simple example in R for the below problem:

I have four columns which I calculate the individual sums as the illustrated sample example below:

enter image description here

The problem I want to solve in R:

Find the optimal lines that satisfies, simultaneously, the below statements:

  1. For the first two columns (a, b) the individual summations to be more close to 0
  2. The sums of (c, d) to be more close to 5

I do not have restrictions of which package solver to use. It could be helpful to have an example of R code for this!

EDIT

For the same solution I would like to apply some rules:

  1. I want the sum(c) > sum(d) AND sum(d) < (static number, like 5)
  2. Also, if I want the sums to fall into a range of numbers and not just static numbers, how the solution could it be written?
4
  • 1
    I've found NlcOptim nice to use. Very flexible once you get the hang of it and is quick. cran.r-project.org/web/packages/NlcOptim/NlcOptim.pdf Commented Nov 23, 2018 at 11:30
  • 1
    Please do not use images to show your data. It means that anyone who answers has to retype all the data to run their code. Use text instead. I have done it this time for you in my answer. Commented Nov 23, 2018 at 14:26
  • @G.Grothendieck Thanks for the advice!
    – Vamkos
    Commented Nov 24, 2018 at 12:23
  • Very helpful! Thank you @JonnyPhelps
    – Vamkos
    Commented Nov 24, 2018 at 13:04

1 Answer 1

2

Using M defined reproducibly in the Note at the end we find the b which minimizes the following objective where b is a 0/1 vector:

sum((b %*% M - c(0, 0, 5, 5))^2)

1) CVXR Using the CVXR package we get a solution c(1, 0, 0, 1, 1) which means choose rows 1, 4 and 5.

library(CVXR)

n <- nrow(M)
b <- Variable(n, boolean = TRUE)

pred <- t(b) %*% M
y <- c(0, 0, 5, 5)

objective <- Minimize(sum((t(y) - pred)^2))
problem <- Problem(objective)
soln <- solve(problem)

bval <- soln$getValue(b)
zapsmall(c(bval))
## [1] 1 0 0 1 1

2) Brute Force Alternately since there are only 5 rows there are only 2^5 possible solutions so we can try them all and pick the one which minimizes the objective. First we compute a matrix solns with 2^5 columns such that each column is one possible solution. Then we compute the objective function for each column and take the one which minimizes it.

n <- nrow(M)

inverse.which <- function(ix, n) replace(integer(n), ix, 1)
L <- lapply(0:n, function(i) apply(combn(n, i), 2, inverse.which, n))
solns <- do.call(cbind, L)
pred <- t(t(solns) %*% M)
obj <- colSums((pred - c(0, 0, 5, 5))^2)
solns[, which.min(obj)]
## [1] 1 0 0 1 1

Note

M <- matrix(c(.38, -.25, .78, .83, -.65,
.24, -.35, .44, -.88, .15,
3, 5, 13, -15, 18,
18, -7, 23, -19, 7), 5)
2
  • Thank you for your answer!! Two additional questions. If I want to have some rules for the same results, for example the sum of column c to be bigger than sum of column d, how could it be written? Second: If for the sum i do not want to have a static number like 3, 5 etc but a wide range like (5 - 8), how could it be written?
    – Vamkos
    Commented Nov 24, 2018 at 12:44
  • 1
    CVXR will continue to work provided your revised objective and added constraints maintain the convexity of the problem. See the CVXR documentation. For the brute force method you can modify the objective as desired and you can simply remove any column in pred and the corresponding column in solns that violates the constraint. Commented Nov 24, 2018 at 13:03

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.