{"action":"opened","issue":{"url":"https://api.github.com/repos/dirkschumacher/ompr/issues/259","repository_url":"https://api.github.com/repos/dirkschumacher/ompr","labels_url":"https://api.github.com/repos/dirkschumacher/ompr/issues/259/labels{/name}","comments_url":"https://api.github.com/repos/dirkschumacher/ompr/issues/259/comments","events_url":"https://api.github.com/repos/dirkschumacher/ompr/issues/259/events","html_url":"https://github.com/dirkschumacher/ompr/issues/259","id":445883878,"node_id":"MDU6SXNzdWU0NDU4ODM4Nzg=","number":259,"title":"colwise() did not work for assigning coefficients to one-dimension variable with MILP constraints","user":{"login":"LDD66","id":19365847,"node_id":"MDQ6VXNlcjE5MzY1ODQ3","avatar_url":"https://avatars2.githubusercontent.com/u/19365847?v=4","gravatar_id":"","url":"https://api.github.com/users/LDD66","html_url":"https://github.com/LDD66","followers_url":"https://api.github.com/users/LDD66/followers","following_url":"https://api.github.com/users/LDD66/following{/other_user}","gists_url":"https://api.github.com/users/LDD66/gists{/gist_id}","starred_url":"https://api.github.com/users/LDD66/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/LDD66/subscriptions","organizations_url":"https://api.github.com/users/LDD66/orgs","repos_url":"https://api.github.com/users/LDD66/repos","events_url":"https://api.github.com/users/LDD66/events{/privacy}","received_events_url":"https://api.github.com/users/LDD66/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"assignees":[],"milestone":null,"comments":0,"created_at":"2019-05-20T00:42:01Z","updated_at":"2019-05-20T00:42:01Z","closed_at":null,"author_association":"NONE","body":"Hello, \r\nI do really like this package for solving mixed integer problem. When I was using `MILPModel()` to construct my problem, I thought that there might exist bugs in `colwise()` function for  the developing version (0.8.0.9000). I will give the following examples to illustrate this. \r\n\r\nAssume that I want to formulate the following constraints\r\n\r\ng[1] <= 2*x[1] + 2*x[2] + 2*x[3]\r\n\r\ng[2] <= -2*x[1] - 2*x[2] - 2*x[3]\r\n\r\nThen, the expected code is following. I was expecting that `colwise(afunc(i ,t))` for `i = 1:3` and `t = 1:2` could \"partition\" the vector (2 2 2 -2 -2 -2) to be (2 2 2)  and (-2 -2 -2).  \r\n\r\n```{r}\r\n# the coefficients\r\na <- matrix(c(2, 2, 2, -2,  -2, -2),\r\n            nrow = 3,\r\n            ncol = 2)\r\n\r\n# the coefficients function \r\nafunc <- function(i,t){\r\n  a_sub <- a[i, t] # get the `a` matrix accroding to i range and t range\r\n  a_vec <- as.vector(a_sub) # convert `a_sub` matrix to be vector (2 2 2 -2 -2 -2)\r\n  return(a_vec)\r\n}\r\n\r\nmodel2 <- MILPModel() %>%\r\n  add_variable(x[i], i=1:3, type=\"binary\") %>%\r\n  add_variable(g[t], t=1:2, type=\"binary\") %>%\r\n# ==== Bug ==== \r\n add_constraint(g[t] <= sum_expr(colwise(afunc(i, t)) * x[i], i=1:3), t = 1:2)\r\n```\r\n\r\nAfter running the above code, I got an error message: \"Error in `[[<-.data.frame`(`*tmp*`, \"coef\", value = c(1, 1, 1, -1, -1, : replacement has 6 rows, data has 3\". \r\n\r\nThe \"data has 3\" means that `x[i]` for `i = 1:3` has 3 elements. The \"replacement has 6 rows\" means that `colwise(afunc(i, t))` for `i = 1:3` and `t = 1:2` has 6 elements. It seems that `colwise()` did not \"smartly partition\" the  vector (2 2 2 -2 -2 -2) when iterating `t = 1:2`. \r\n\r\nI guess the reason is that `colwise()` is not be able to assign the correct coefficients for variables with only one dimension. In addition, I will later present  another example that `colwise()` works good for variables with two dimensions. \r\n\r\nTherefore, the alternative way of constructing such constraints is to write a loop for iterating `t`.  The following code works. \r\n\r\n```{r}\r\n# the coefficients\r\na <- matrix(c(2, 2, 2, -2,  -2, -2),\r\n            nrow = 3,\r\n            ncol = 2)\r\n\r\n# the coefficients function \r\nafunc <- function(i,t){\r\n  a_sub <- a[i, t] # get the `a` matrix accroding to i range and t range\r\n  a_vec <- as.vector(a_sub) # convert `a_sub` matrix to be vector (2 2 2 -2 -2 -2)\r\n  return(a_vec)\r\n}\r\n\r\nmodel2 <- MILPModel() %>%\r\n  add_variable(x[i], i=1:3, type=\"binary\") %>%\r\n  add_variable(g[t], t=1:2, type=\"binary\") \r\n\r\n# the revised version \r\nfor (t in 1:2){\r\n  model2 <- add_constraint(model2, g[t] <= sum_expr(colwise(afunc(i, t)) * x[i], i=1:3), t = t)\r\n }\r\n```\r\nAs discussed before, I also found out that `colwise()` works good, for example, when variables have two dimension. Let's introduce a new variable `y[i, j]` for `i = 1:3` and `j = 1:5`. I want to construct the constraints with the same coefficients: \r\n\r\ng[1] <= 2*y[1, j] + 2*y[2, j] + 2*y[3, j]     for j = 1:5\r\n\r\ng[2] <= -2*y[1, j] - 2*y[2, j] - 2*y[3, j]    for j = 1:5\r\n\r\nThe following code works good and `colwise(acfunc(i, t))` smartly and repeatedly assigned the correct coefficients to the variable `y[i, j]`. \r\n```{r}\r\na <- matrix(c(2, 2, 2, -2,  -2, -2),\r\n            nrow = 3,\r\n            ncol = 2)\r\n\r\nafunc <- function(i,t){\r\n  a_sub <- a[i, t] # get the `a` matrix accroding to i range and t range\r\n  a_vec <- as.vector(a_sub) # convert `a_sub` matrix to be vector (1 1 1 -1 -1 -1)\r\n  return(a_vec)\r\n}\r\n\r\nmodel2 <- MILPModel() %>%\r\n  add_variable(x[i], i=1:3, type=\"binary\") %>%\r\n  add_variable(g[t], t=1:2, type=\"binary\") %>%\r\n  add_variable(y[i,j], i = 1:3, j = 1:5)%>%\r\n  add_constraint(g[t] <= sum_expr(colwise(afunc(i, t)) * y[i,j], i=1:3), t = 1:2, j =1:5)\r\n\r\n#check constraint\r\nmodel2$constraints\r\n```\r\n\r\n In sum, `colwise( coefficient vector)` might not be able to \"smartly partition\" the coefficients vector for variables with only one dimension. I'm not sure whether or not this statement is strictly correct. Yet, according to the above comparison, I guess there might exist some bugs in the `colwise()` function in the current version (0.8.0.9000).  \r\n\r\n\r\n\r\n\r\n\r\n"}}
{"actor":{"display_login":"LDD66"}}