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.GetLength(0);
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)
{
using (Model M = new Model("max_vol_box"))
{
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[] {System.Math.Log(2.0/Aw), System.Math.Log(2.0/Aw)});
M.Constraint(Expr.Dot(new double[] {0,1,1}, xyz), Domain.LessThan(System.Math.Log(Af)));
M.Constraint(Expr.Dot(new double[] {1,-1,0}, xyz), Domain.InRange(System.Math.Log(alpha),System.Math.Log(beta)));
M.Constraint(Expr.Dot(new double[] {0,-1,1}, xyz), Domain.InRange(System.Math.Log(gamma),System.Math.Log(delta)));
M.SetLogHandler(Console.Out);
M.Solve();
double[] xyzVal = xyz.Level();
double[] hwdVal = new double[3];
for(int i=0; i<3; i++) hwdVal[i] = System.Math.Exp(xyzVal[i]);
return hwdVal;
}
}
Given sample data we obtain the solution \(h,w,d\) as follows:
public static void Main(String[] args)
{
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);
Console.WriteLine("h={0:f4} w={1:f4} d={2:f4}", hwd[0], hwd[1], hwd[2]);
}