MOSEK can handle large-scale problems of a wide variety, including conic and Mixed-Integer programming problems. The Fusion API provided by MOSEK makes it straightforward to utilize the MOSEK solver in a structured manner.
In the problem that you state, one can rephrase the quadratic objective function by introducing an auxiliary scalar variable $H$, as follows: \begin{align}\text{min}&\quad H\\\text{s.t.}&\quad H \geq \sqrt{\sum_{i=1}^k \bigg( \frac{h_i}{n} - p_i\bigg)^{2}}\end{align}
while the other constraints are unchanged. I have expressed the objective in terms of the epigraph of the Euclidean norm of the vector $\vec{d} = \vec{(h/n)} - \vec{p}$ that can be implemented exactly in Fusion as a $k+1$ dimensional quadratic cone, i.e. $(H,\vec{d})\in Q^{k+1}$.
The Fusion implementation for your problem could be as follows:
import numpy as np
from mosek.fusion import *
#n is the number of objects and p is the vector of ratios (size k)
def quad_int_prog(n,p):
#Number of groups
k = len(p)
#Making a Mosek model
with Model('k_groups') as M:
#h (vector of size k): Integer and h>=5
h = M.variable('h',k,Domain.integral(Domain.greaterThan(5)))
#Auxiliary Variable (epigraph)
H = M.variable('H',Domain.greaterThan(0))
#Linear Constraint: sum(h_i)=n
M.constraint('h_sum_constraint',Expr.sum(h),Domain.equalsTo(n))
#Conic Constraint: (H,d) belongs to Quadratic cone domain of size k+1
H_d_vector = Expr.vstack(H,Expr.sub(Expr.mul(1/n,h),p))
M.constraint('Percentage_constraint',H_d_vector,Domain.inQCone(k+1))
#Objective: Minimize H
M.objective('Objective',ObjectiveSense.Minimize,H)
#Solving... (To enable log output, use M.setLogHandler(sys.stdout))
M.solve()
#Optimal value for h
h_optimal = h.level()
return(h_optimal)
Being a large-scale solver, MOSEK can easily handle scaled up versions of the discussed model. For instance, on my desktop (with i7-6700HQ and 16 GB of RAM) I could solve a problem of the above-stated structure with $k=3000$ and $n=20000$ (with a randomly generated $p$) in about 4.23 seconds with a relative tolerance gap of less than $2 \%$. Remember, it can be crucial to set a termination criteria when dealing with Mixed-Integer problems, such as setting a tolerance gap or providing a maximum number of iterations. Moreover, I highly recommend enabling the log-output in MOSEK (using the command M.setLogHandler(sys.stdout)
) because it not only tells you the progress the solver has made, but can also provide key insights into the model and the structure of your problem.
If you need a quick reference guide for mathematical optimization and general model building (like the rephrasing presented above using the Euclidean norm), check out the MOSEK modelling cookbook. For a comprehensive guide to using Fusion and/or other products that MOSEK offers, see here. It is possible to acquire a free trial license (valid for 30 days), and a free academic license (valid for 1 year) is also provided.