For the example provided one might proceed as follows.
u = 1/2;
a[i_] := 0.6*PDF[BinomialDistribution[20, 0.3], i]
b[i_] := 1.5*PDF[BinomialDistribution[20, 0.3], i]
c[i_] := 0.4*PDF[BinomialDistribution[20, 0.7], i]
d[i_] := 2*PDF[BinomialDistribution[20, 0.7], i]
n = 14;
Check the constraints on the totals.
In[415]:= Map[Total, {Array[a, n], Array[b, n], Array[c, n],
Array[d, n]}]
(* Out[415]= {0.599495482389, 1.49873870597, 0.233451668207, \
1.16725834104} *)
Create the x
and y
vectors and the set of constraints.
xvec = Array[x, n];
yvec = Array[y, n];
c1 = {Total[xvec] >= 1, Total[yvec] >= 1};
c2 = Thread[Array[a, n] <= xvec <= Array[b, n]];
c3 = Thread[Array[c, n] <= yvec <= Array[d, n]];
obj = xvec^u.yvec^(1 - u);
constraints = Join[c1, c2, c3];
vars = Join[xvec, yvec];
Notice that I constrain the x
and y
sums to be >= unity rather than strictly equal. This is to work around a problem NMinimize
seems to have with imposing the equality constraint and still finding viable initial search points. Alternatively one can use FindMinimum
and avoid the issue. Notice that >= suffices because any "minimum" value found that satisfies the strong inequality can be further reduced by making it satisfy the equality instead.
Now we minimize.
{min, vals} = NMinimize[{obj, constraints}, regions]
(* Out[600]= {0.113052286045, {x[1] -> 0.0102589870128,
x[2] -> 0.0417687898593, x[3] -> 0.107405488744,
x[4] -> 0.195631440342, x[5] -> 0.268294549424,
x[6] -> 0.141472396852, x[7] -> 0.0985572027817,
x[8] -> 0.0686380474937, x[9] -> 0.0392217407402,
x[10] -> 0.0184902491202, x[11] -> 0.00720399313413,
x[12] -> 0.00231556920486, x[13] -> 0.000610699578119,
x[14] -> 0.000130864199554, y[1] -> 6.50982441109*10^-10,
y[2] -> 1.44278086865*10^-8, y[3] -> 2.01986175439*10^-7,
y[4] -> 2.00302480394*10^-6, y[5] -> 0.0000149559109898,
y[6] -> 0.0000872428055708, y[7] -> 0.000407133069209,
y[8] -> 0.00154371284591, y[9] -> 0.00480266214711,
y[10] -> 0.012326832933, y[11] -> 0.0402198296988,
y[12] -> 0.228793477986, y[13] -> 0.328523969226,
y[14] -> 0.383277964372}} *)
Check constraints:
{c1, c2, c3} /. vals
(* Out[601]= {{True, True}, {True, True, True, True, True, True, True,
True, True, True, True, True, True, True}, {True, True, True, True,
True, True, True, True, True, True, True, True, True, True}} *)
FindMinimum
gives a comparable result.
{min, vals} = FindMinimum[{obj, constraints}, vars]
(* Out[602]= {0.113052279616, {x[1] -> 0.0102590056662,
x[2] -> 0.0417688087857, x[3] -> 0.107405508307,
x[4] -> 0.19563146156, x[5] -> 0.268294575854,
x[6] -> 0.141472291161, x[7] -> 0.0985571911308,
x[8] -> 0.068638043823, x[9] -> 0.0392217393274,
x[10] -> 0.0184902485401, x[11] -> 0.00720399293769,
x[12] -> 0.00231556915854, x[13] -> 0.000610699558297,
x[14] -> 0.000130864191064, y[1] -> 6.50866427519*10^-10,
y[2] -> 1.4427539019*10^-8, y[3] -> 2.01985546167*10^-7,
y[4] -> 2.00302333266*10^-6, y[5] -> 0.0000149559075502,
y[6] -> 0.0000872427940428, y[7] -> 0.000407133038865,
y[8] -> 0.00154371277236, y[9] -> 0.00480266195846,
y[10] -> 0.0123268323601, y[11] -> 0.0402198257305,
y[12] -> 0.22879347941, y[13] -> 0.328523970434,
y[14] -> 0.383277965507}} *)
--- edit ---
Here is the n=20
case. I use equality constraints and FindMaximum
.
u = 1/2;
a[i_] := 0.6*PDF[BinomialDistribution[20, 0.3], i]
b[i_] := 1.5*PDF[BinomialDistribution[20, 0.3], i]
c[i_] := 0.4*PDF[BinomialDistribution[20, 0.7], i]
d[i_] := 2*PDF[BinomialDistribution[20, 0.7], i]
n = 20;
Map[Total, {Array[a, n], Array[b, n], Array[c, n], Array[d, n]}]
(* Out[678]= {0.599521246402, 1.49880311601, 0.399999999986, \
1.99999999993} *)
xvec = Array[x, n];
yvec = Array[y, n];
c1 = {Total[xvec] == 1, Total[yvec] == 1};
c2 = Thread[Array[a, n] <= xvec <= Array[b, n]];
c3 = Thread[Array[c, n] <= yvec <= Array[d, n]];
obj = xvec^u.yvec^(1 - u);
constraints = Join[c1, c2, c3];
vars = Join[xvec, yvec];
{min, vals} = FindMaximum[{obj, constraints}, vars]
(* Out[688]= {0.287179170249, {x[1] -> 0.00420039062101,
x[2] -> 0.0168068363863, x[3] -> 0.0430675097985,
x[4] -> 0.0783747301246, x[5] -> 0.107512002157,
x[6] -> 0.162230688536, x[7] -> 0.246265726493,
x[8] -> 0.17156411577, x[9] -> 0.0980431454055,
x[10] -> 0.0462211272314, x[11] -> 0.0180081125686,
x[12] -> 0.00578813622943, x[13] -> 0.00152640343632,
x[14] -> 0.000326847202309, x[15] -> 0.0000559562031744,
x[16] -> 7.46270969759*10^-6, x[17] -> 7.43504383666*10^-7,
x[18] -> 5.41032712888*10^-8, x[19] -> 2.4407490807*10^-9,
x[20] -> 5.2301766015*10^-11, y[1] -> 3.2543321076*10^-9,
y[2] -> 7.21376950518*10^-8, y[3] -> 9.96710077075*10^-7,
y[4] -> 9.96943298*10^-6, y[5] -> 0.000074658665243,
y[6] -> 0.000435965674377, y[7] -> 0.00203522075526,
y[8] -> 0.00771750424298, y[9] -> 0.0240107719009,
y[10] -> 0.0616279225931, y[11] -> 0.130722583872,
y[12] -> 0.228736998482, y[13] -> 0.30013881215,
y[14] -> 0.0774548114721, y[15] -> 0.0716601191227,
y[16] -> 0.0522522505167, y[17] -> 0.0287165994173,
y[18] -> 0.0112102849437, y[19] -> 0.0028066714826,
y[20] -> 0.000387777172855}} *)
In[691]:= Map[Total, {xvec, yvec} /. vals]
(* Out[691]= {0.999999990973, 0.999999993999} *)
Also works fine with FindMinimum
.
--- end edit ---
n
to some small value (say 2, 3, or 4) and set up theMaximize
function. Maybe from trying a few values ofn
you might see a pattern for a general answer. $\endgroup$