7.5 Geometric Programming¶
Geometric programs (GP) are a particular class of optimization problems which can be expressed in special polynomial form as positive sums of generalized monomials. More precisely, a geometric problem in canonical form is
where each \(f_0,\ldots,f_m\) is a posynomial, that is a function of the form
with arbitrary real \(\alpha_{ki}\) and \(c_k>0\). The standard way to formulate GPs in convex form is to introduce a variable substitution
Under this substitution all constraints in a GP can be reduced to the form
involving a log-sum-exp bound. Moreover, constraints involving only a single monomial in \(x\) can be even more simply written as a linear inequality:
We refer to the MOSEK Modeling Cookbook and to [BKVH07] for more details on this reformulation. A geometric problem formulated in convex form can be entered into MOSEK with the help of exponential cones.
7.5.1 Example GP1¶
The following problem comes from [BKVH07]. Consider maximizing the volume of a \(h\times w\times d\) box subject to upper bounds on the area of the floor and of the walls and bounds on the ratios \(h/w\) and \(d/w\):
The decision variables in the problem are \(h,w,d\). We make a substitution
after which (7.10) becomes
Next, we demonstrate how to implement a log-sum-exp constraint (7.9). It can be written as:
This presentation requires one extra variable \(u_k\) for each monomial appearing in the original posynomial constraint.
// Models log(sum(exp(Ax+b))) <= 0.
// Each row of [A b] describes one of the exp-terms
public static void logsumexp(Model M,
double[][] A,
Variable x,
double[] b)
{
int k = A.length;
Variable u = M.variable(k);
M.constraint(Expr.sum(u), Domain.equalsTo(1.0));
M.constraint(Expr.hstack(u,
Expr.constTerm(k, 1.0),
Expr.add(Expr.mul(A, x), b)), Domain.inPExpCone());
}
We can now use this function to assemble all constraints in the model. The linear part of the problem is entered as in Sec. 7.1 (Linear Optimization).
public static double[] max_volume_box(double Aw, double Af,
double alpha, double beta, double gamma, double delta)
throws SolutionError
{
Model M = new Model("max_vol_box");
try {
Variable xyz = M.variable(3);
M.objective("Objective", ObjectiveSense.Maximize, Expr.sum(xyz));
logsumexp(M,
new double[][] {{1,1,0}, {1,0,1}},
xyz,
new double[] {Math.log(2.0/Aw), Math.log(2.0/Aw)});
M.constraint(Expr.dot(new double[] {0,1,1}, xyz), Domain.lessThan(Math.log(Af)));
M.constraint(Expr.dot(new double[] {1,-1,0}, xyz), Domain.inRange(Math.log(alpha),Math.log(beta)));
M.constraint(Expr.dot(new double[] {0,-1,1}, xyz), Domain.inRange(Math.log(gamma),Math.log(delta)));
M.setLogHandler(new java.io.PrintWriter(System.out));
M.solve();
double[] xyzVal = xyz.level();
double[] hwdVal = new double[3];
for(int i=0; i<3; i++) hwdVal[i] = Math.exp(xyzVal[i]);
return hwdVal;
} finally {
M.dispose();
}
}
Given sample data we obtain the solution \(h,w,d\) as follows:
public static void main(String[] args)
throws SolutionError
{
double Aw = 200.0;
double Af = 50.0;
double alpha = 2.0;
double beta = 10.0;
double gamma = 2.0;
double delta = 10.0;
double[] hwd = max_volume_box(Aw, Af, alpha, beta, gamma, delta);
System.out.format("h=%.4f w=%.4f d=%.4f\n", hwd[0], hwd[1], hwd[2]);
}