In [1] a somewhat abstract non-convex problem is given:
\[\begin{align}\min_x & - x_1^2 - x_2^2 - x_3^2 - x_4^2\\ & Ax \le b \end{align}\]
My conclusions:
This is a nonconvex objective with some linear constraints. Of course, the best way to attack a problem like this is to do some quick and dirty tests with global solvers designed to handle this type of model. As the constraints are linear, a solver like Cplex or Gurobi may be a good starting point (pun intended).
If you have access to a local NLP solver, it may not always be easy to find a good starting point. One possible approach is to use a multistart algorithm (some NLP solvers, like Baron and Knitro, have this built-in). This will not guarantee to produce a global solution (and often it doesn't), but at least we can prevent really bad solutions. There are some ways to construct a confidence interval, so we can say something probabilistic about the quality of the solution found this way.
It is very difficult to say much in the abstract. So let's create an example to put our teeth in. Here we have a transportation problem with a similar concave objective as in the original problem: \[\begin{align}\max&\sum_{(i,j)\in S}\color{darkred}x^2_{i,j} \\ & \sum_j \color{darkred}x_{i,j} \le \color{darkblue}{\mathit{supply}}_i \\ & -\sum_i \color{darkred}x_{i,j} \le -\color{darkblue}{\mathit{demand}}_j \\ & \color{darkred}x_{i,j}\ge 0 \end{align}\] Here \(S\) is some subset of all \(\color{darkred}x_{i,j}\).
Using random supply and demand data, I generate a model with 50 demand nodes and 50 supply nodes and 2500 arcs (i.e. 2500 variables). I used Conopt (an excellent large-scale local NLP solver) with a few trials with different starting points. I have no clue about constructing good initial points, so I just generate random starting points. (In the answers to [1] it is suggested that finding good initial points is very easy -- I totally fail to see how that would or even could work.) The global QP solver I used is Cplex. My results are:
---- 88 PARAMETER resresults status obj time conopt.trial1 localopt 9572.3570.031 conopt.trial2 localopt 0.016 conopt.trial3 localopt 4711.8330.016 conopt.trial4 localopt 8382.3240.015 conopt.trial5 localopt 9600.2430.016 conopt.trial6 localopt 3029.1300.016 conopt.trial7 localopt 0.015 conopt.trial8 localopt 8035.9340.031 conopt.trial9 localopt 0.016 conopt.trial10 localopt 9466.1080.015 conopt.best 9600.2430.187 cplex .- globalopt 9600.2430.437
Note that the blank entries mean that the objective was zero!
Cplex is doing an excellent job here:
Nodes Cuts/ Node Left Objective IInf Best Integer Best Bound ItCnt Gap 009939.762409939.76247 * 0+ 09600.24329939.76243.54% Found incumbent of value 9600.243195 after 0.02 sec. (23.55 ticks) 029939.762409600.24329939.762473.54% Elapsed time = 0.38 sec. (2003.49 ticks, tree = 0.02 MB)
Data set
---- 32 PARAMETER supply supply1 17.175, supply2 84.327, supply3 55.038, supply4 30.114, supply5 29.221, supply6 22.405 supply7 34.983, supply8 85.627, supply9 6.711, supply10 50.021, supply11 99.812, supply12 57.873 supply13 99.113, supply14 76.225, supply15 13.069, supply16 63.972, supply17 15.952, supply18 25.008 supply19 66.893, supply20 43.536, supply21 35.970, supply22 35.144, supply23 13.149, supply24 15.010 supply25 58.911, supply26 83.089, supply27 23.082, supply28 66.573, supply29 77.586, supply30 30.366 supply31 11.049, supply32 50.238, supply33 16.017, supply34 87.246, supply35 26.511, supply36 28.581 supply37 59.396, supply38 72.272, supply39 62.825, supply40 46.380, supply41 41.331, supply42 11.770 supply43 31.421, supply44 4.655, supply45 33.855, supply46 18.210, supply47 64.573, supply48 56.075 supply49 76.996, supply50 29.781 ---- 32 PARAMETER demand demand1 69.574, demand2 79.046, demand3 66.208, demand4 31.850, demand5 12.106, demand6 13.715 demand7 67.589, demand8 57.995, demand9 6.616, demand10 82.700, demand11 10.740, demand12 21.030 demand13 56.027, demand14 78.485, demand15 21.276, demand16 6.878, demand17 61.977, demand18 65.587 demand19 42.400, demand20 39.335, demand21 27.767, demand22 28.106, demand23 16.514, demand24 96.809 demand25 41.458, demand26 81.804, demand27 33.467, demand28 16.012, demand29 78.351, demand30 10.387 demand31 23.665, demand32 3.970, demand33 30.425, demand34 53.449, demand35 18.592, demand36 20.881 demand37 36.528, demand38 35.154, demand39 35.672, demand40 99.861, demand41 102.824, demand42 40.454 demand43 40.753, demand44 80.662, demand45 43.132, demand46 94.773, demand47 15.422, demand48 77.012 demand49 9.006, demand50 61.094 ---- 32 PARAMETER totsup = 2245.137total supply PARAMETER totdem = 2245.137total demand ---- 32 SET subijsubset to construct objective demand1 demand2 demand3 supply1 YES YES YES supply2 YES YES YES supply3 YES YES YES
Solution
---- 90 VARIABLE z.L = 9600.243objective ---- 90 VARIABLE x.L flow from supply to demand nodes demand1 demand2 demand3 demand4 demand5 demand6 demand7 demand8 demand9 demand10 supply1 17.175 supply2 5.28179.046 supply3 55.038 supply5 12.106 supply8 13.715 supply14 76.225 supply15 6.616 supply16 11.282 supply18 2.664 supply20 25.248 supply22 35.144 supply23 13.149 supply33 0.579 supply34 8.67743.415 supply37 43.157 supply38 5.6192.2516.475 supply43 4.351 supply49 18.185 supply50 2.002 + demand11 demand12 demand13 demand14 demand15 demand16 demand17 demand18 demand19 demand20 supply4 16.730 supply8 37.15411.917 supply12 19.299 supply19 24.911 supply24 6.005 supply28 50.059 supply30 21.2769.090 supply32 48.857 supply36 25.111 supply38 39.335 supply39 1.731 supply41 41.331 supply47 33.310 supply50 10.7406.878 + demand21 demand22 demand23 demand24 demand25 demand26 demand27 demand28 demand29 demand30 supply6 22.405 supply8 22.841 supply12 37.997 supply13 75.351 supply15 6.453 supply16 27.767 supply17 15.952 supply21 35.970 supply25 18.159 supply26 12.154 supply28 16.514 supply29 16.012 supply32 1.382 supply37 11.0625.176 supply48 41.458 supply49 58.812 supply50 5.210 + demand31 demand32 demand33 demand34 demand35 demand36 demand37 demand38 demand39 demand40 supply5 1.693 supply10 23.665 supply11 35.16111.028 supply13 23.763 supply20 18.287 supply26 70.935 supply34 35.154 supply36 3.470 supply38 18.592 supply40 9.85236.528 supply45 3.43030.425 supply47 31.263 supply50 0.5404.410 + demand41 demand42 demand43 demand44 demand45 demand46 demand47 demand48 demand49 demand50 supply4 13.384 supply5 15.422 supply7 34.983 supply9 6.711 supply10 26.356 supply11 53.622 supply12 0.578 supply16 24.922 supply18 22.344 supply19 41.982 supply24 9.006 supply25 40.753 supply27 23.082 supply29 61.574 supply31 11.049 supply33 15.438 supply35 0.68425.828 supply39 61.094 supply42 11.770 supply43 27.070 supply44 4.655 supply46 18.210 supply48 14.617
GAMS model
set
i 'supply nodes' /supply1*supply50/
j 'demand nodes' /demand1*demand50/
;
parameters
supply(i)
demand(j)
totsup,totdem;
;
supply(i) = uniform(0,100);
demand(j) = uniform(0,100);
totsup = sum(i,supply(i));
totdem = sum(j,demand(j));
if (totsup>totdem,
demand(j) = demand(j) + (totsup-totdem)/card(j);
else
supply(i) = supply(i) + (totdem-totsup)/card(i);
);
totsup = sum(i,supply(i));
totdem = sum(j,demand(j));
display supply,demand,totsup,totdem;
Variables
z 'objective'
;
positive variables
x(i,j) 'flow from supply to demand nodes'
;
equations
obj
esupply
edemand
;
set subij(i,j);
subij(i,j) = ord(i)<=3 andord(j)<=3;
obj.. z =e= sum(subij,sqr(x(subij)));
esupply(i)..sum(j, x(i,j)) =l= supply(i);
edemand(j).. -sum(i, x(i,j)) =l= -demand(j);
model m /all/;
parameter startx(i,j);
optionqcp = conopt;
set trial /trial1*trial10/;
m.solprint = %solPrint.silent%;
m.solvelink = %solveLink.loadLibrary%;
parameter
res 'results'
best /-INF/
time /0/
;
acronym localopt,nonopt,globalopt;
loop(trial,
x.l(i,j) = uniform(1,100);
solve m maximizing z usingqcp;
res('conopt',trial,'status') = nonopt;
res('conopt',trial,'status')$(m.solvestat=%modelStat.Optimal%or m.solvestat=%modelStat.locallyOptimal%)=localopt;
res('conopt',trial,'obj') = z.l;
res('conopt',trial,'time') = m.resusd;
best$(z.l>best and (m.solvestat=%modelStat.Optimal%or m.solvestat=%modelStat.locallyOptimal%)) = z.l;
time = time + m.resusd;
);
res('conopt','best','obj') = best;
res('conopt','best','time') = time;
optionqcp = cplex;
m.optfile=1;
solve m maximizing z usingqcp;
res('cplex','-','status') = nonopt;
res('cplex','-','status')$(m.solvestat=%modelStat.Optimal%)=globalopt;
res('cplex','-','obj') = z.l;
res('cplex','-','time') = m.resusd;
display res;
display z.l,x.l;
$onecho> cplex.opt
OptimalityTarget 3
$offecho
Conclusions
- I don't know how to generate a good starting point.
- A single run with a local NLP solver is not very useful: there is not much we can say about a solution found this way. It could be very bad or very good.
- A multistart algorithm with random initial points works quite well.
- Cplex finds a proven global solution very quickly.
References
- Efficient Approaches for Separable Concave Quadratic Minimization over Linear Constraints?, https://or.stackexchange.com/questions/13081/efficient-approaches-for-separable-concave-quadratic-minimization-over-linear-co