0

I am trying to optimize layout of a set of boxes w.r.t. their hanger locations s.t. the boxes are most aligned with their hangers and do not crowd out each other. Using quadprog.

Givens:

1.  box hanger x-locations (P). =710  850  990 1130
2.  box-sizes (W). =690 550 690 130 
3.  usable x-spread tuple (S). =-150 2090
4.  number of boxes (K). =4
5.  minimum interbox spread (G). =50
6.  box x-locations (X). =objective

We can see that the total required x-spread is sum(W) + 3G = 2060 + 150 = 2210 whereas the available x-spread is S[2] - S1 = 2240. So, a solution should exist.

Min:

sumof (P[i] – X[i])^2

s.t.: 

(1) X[i+i] – X[i] >= G + ½ ( W[i+1] + W[i] ); i = 1..(K-1), i.e. the boxes do not crowd out each other

        -X[i] + X[i+1] >= -( -G – ½ (W[i+1] + W[i]) )

(2) X1 >= S[left] + ½ W1, and (3) X[K] <= S[right] – ½ W[K], i.e. the boxes are within the given x-spread

        X[1] >= - ( S[left] + ½ W[1] )
        -X[K] >= - ( S[right] – ½ W[K] )

for a total of 5 constraints - 3 for the inter-box spread, and 2 for extremities.

in R:

> Dmat = matrix(0,4,4)
> diag(Dmat) = 1
> dvec = P, the hanger locations
[1]  710  850  990 1130
> bvec 
[1] -670 -670 -460 -195 2025
> t(Amat)
     [,1] [,2] [,3] [,4]
[1,]   -1    1    0    0
[2,]    0   -1    1    0
[3,]    0    0   -1    1
[4,]    1    0    0    0
[5,]    0    0    0   -1
> solve.QP(Dmat, dvec, Amat, bvec)
Error in solve.QP(Dmat, dvec, Amat, bvec) : 
  constraints are inconsistent, no solution!

Quite obviously I have missed or mis-specified the problem (Package 'quadprog')! I am using quadprog as I found a JavaScript port of it.

Thanks a lot.

Dinesh
  • 4,437
  • 5
  • 40
  • 77
  • 1
    Your statement that S[2] - S1 = 2240 isn't correct for the given values of S[1] and S[2]. However, if you change of the sign of S[1] so that S[1] = -150 then your math works and solve.QP returns a solution. – WaltS Jul 12 '15 at 23:46
  • You are right, it should have been -150. – Dinesh Jul 13 '15 at 00:41

2 Answers2

1

The problem lies with the setup of Amat, bvec or both. solve.QP tries to find a solution, b, of the quadratic programming problem subject to the constraint that

t(Amat)*b >= bvec

Expanding out this constraint in your example, we want to find a vector b := c(b[1], b[2], b[3], b[4]) that satisfies the conditions:

  • -b[1] + b[2] >= -670,

  • -b[2] + b[3] >= -670,

  • -b[3] + b[4] >= -460,

  • b[1] >= -195

  • and -b[4] >= 2025 (i.e., b[4] <= -2025).

However, by adding the first four inequalities together, we have b[4] >= -670-670-460-195 = -1995. In other words, b[4] must be greater than -1995 and less than -2025. This is a contradiction and therefore solve.QP fails to find a solution.

Trying this example with the constraint -b[4] >= -2025, by setting bvec = c(-670, -670, -460, -195, -2025) yields a solution. Without going too much into your formulation above, perhaps this was intended (or another one of these values should have been positive)?

N McWilliams
  • 62
  • 2
  • 6
  • Thanks, I made the correction. I get a result of (710 850 990 1130) but that causes the boxes to overlap, so I guess I need to get back to the drawing board - may be more constraints are needed – Dinesh Jul 13 '15 at 00:43
  • BTW, the quadprog doc states it is solving `t(Amat)*b >= -bvec` which is not what you wrote. Clarification, please? – Dinesh Jul 13 '15 at 00:45
  • It doesn't say that. It states that it's finding the vector `b` that minimises `-t(dvec)*b + 0.5*t(b)*Dmat*b`, or in other words from `?solve.QP`, "solving quadratic programming problems of the form min(-d^T b + 1/2 b^T D b)", but "with the constraints A^T b >= b_0." That is, any `b` found must also satisfy `t(Amat)*b >= bvec`, which is what I had originally written. – N McWilliams Jul 13 '15 at 07:25
1

I'm not sure that this solves your physical problem but the code below seems to solve the optimization problem as you stated it. I've generalized it to a variable number of boxes and included a plot to check the solution.

  library(quadprog)
  p  <- c(710,  850,  990, 1130)   # hanger positions
  w  <- c(690, 550, 690, 130)      # box widths
  g <- 50                          # min box separation
  s <- c(-150, 2390)               # min and max postions of box edges

  k <- length(w)                   # number of boxes
  Dmat <- 2*diag(nrow=k)
  dvec <- p
# separation constraints
  Amat <- -diag(nrow=k,ncol=(k-1))
  Amat[lower.tri(Amat)] <- unlist(lapply((k-1):1, function(n) c(1,numeric(n-1))))
  bvec <- sapply(1:(k-1), function(n) g + (w[n+1]+w[n])/2)
# x-spread constraints
  Amat <- cbind(Amat, c(1,numeric(k-1)), c(numeric(k-1),-1))
  bvec <- c(bvec, s[1] + w[1]/2, -(s[2] - w[k]/2))

  sol <- solve.QP(Dmat, dvec, Amat, bvec)
  plot(x=s, y=c(0,0), type="l", ylim=c(-2.5,0))
  points(x=p, y=numeric(k), pch=19)
  segments(x0=sol$solution, y0=-1, x1=p, y1=0)
  rect(xleft=sol$solution-w/2, xright=sol$solution+w/2, ytop=-1.0, ybottom=-2, density=8)

enter image description here

WaltS
  • 5,410
  • 2
  • 18
  • 24