Creo que el mejor enfoque es la dualidad. En primer lugar, tenga en cuenta que $\log_2$ $\ln$ se diferencian por un multiplicativo constante $\ln(2)$. Por lo tanto, se puede minimizar con $\ln$ y obtener el mismo valor óptimo, y voy a utilizar $\ln$ en lugar de $\log_2$ en mi derivaciones. Segundo, voy a tratar como un problema de minimización, y por lo tanto escribir $-\ln$ en lugar de $\ln$.
Dando un multiplicador de Lagrange sólo a la igualdad de restricción, se puede obtener el Lagrangiano
$$
\begin{aligned}
L(x, \lambda)
&= -\sum_{i=1}^n \ln(1+a_i x_i) + \lambda \left[ \sum_{i=1}^n (c_i - x_i) a_i - b \right] \\
&= \sum_{i=1}^n \left[-\ln(1+a_i x_i) - \lambda a_i x_i \right] + \lambda \Bigl[\underbrace{-b + \sum_{i=1}^n a_i c_i}_{C} \Bigr]
\end{aligned}
$$
Desde el Lagrangiano y las limitaciones de la $0 \leq x_i \leq c_i$ ambos son separables en $x_i$, el doble objetivo es:
$$
q(\lambda) = \sum_{i=1}^n \min_{x_i} \biggl\{ -\ln(1+a_i x_i) - \lambda a_i x_i :~ 0 \leq x_i \leq c_i \biggr\} + \lambda C
$$
Tenga en cuenta, que cada uno de los elementos en la suma anterior es una minimización de una función convexa de la forma $-\ln(1+ax) -bx$ a un intervalo de tiempo, y es bastante fácil encontrar una solución de forma cerrada (si usted necesita ayuda, por favor decirlo). A partir de esta solución se debe también obtener una fórmula a partir de la recuperación de la óptima $x_i$ a partir de la óptima $\lambda$.
Ahora, su dual es el problema unidimensional problema de optimización $\max_{\lambda} q(\lambda)$, que puede ser fácilmente resuelto por un método numérico, tales como la Sección de Oro de búsqueda. Después de encontrar el óptimo $\lambda^*$ puede recuperarse $x^*$.
P. S. Si usted realmente desea un muy confiable método en términos de la aproximación de la óptima en términos de valor objetivo, se puede calcular un aproximado de $x_i$ después de cada iteración de la Sección de Oro de búsqueda, y se detiene cuando el primal-dual de la brecha está por debajo de un cierto umbral.
Actualización
Ya que hay muchas preguntas acerca de la computación en la $q(\lambda)$, aquí están los detalles. En primer lugar, voy a denotar por $g_i(x_i, \lambda)$ el objetivo en el mínimo. Es decir, que debemos resolver
$$
\min_{x_i} \biggl\{g_i(x_i, \lambda) = -\ln(1+a_i x_i) - \lambda a_i x_i :~ 0 \leq x_i \leq c_i \biggr\}
$$
El mínimo es un punto fijo en el interior del intervalo de $I = [0, c_i]$ o uno de sus extremos. En primer lugar, tenga en cuenta que si $\lambda \geq 0$ $g_i$ es una función decreciente, y en este caso no hay puntos estacionarios. Así, para cualquier punto fijo debemos tener $\lambda < 0$.
Para encontrar un punto fijo, se resuelve:
$$
\frac{d g_i}{d x_i} = -\frac{a_i}{1+a_i x_i} - \lambda a_i = 0.
$$
Desde $a_i > 0$ podemos dividir ambos lados por $a_i$, y obtener la ecuación
$$
\frac{1}{1+a_i x_i} = -\lambda
$$
Desde $\lambda \neq 0$, tomamos la inversa en ambos lados, multiplicar por $a_i$, y obtener
$$
1+a_i x_i = -\frac{1}{\lambda},
$$
que es equivalente a
$$
a_i x_i = -1-\frac{1}{\lambda},
$$
o
$$
x_i = -\frac{1+\lambda}{a_i \lambda}.
$$
Utilizando el hecho de que $\lambda < 0$, podemos concluir que el punto anterior es en el interior de $I$ si y sólo si
$$
-1 < \lambda < -\frac{1}{1 + c_i a_i},
$$
en ese caso la expresión de la $x_i$ arriba es el minimizer, y el mínimo es de
$$
g_i\left(-\frac{1+\lambda}{a_i \lambda}, \lambda\right) = \ln(-\lambda) + \lambda + 1
$$
De lo contrario, el extremo izquierdo $x_i=0$ o el extremo derecho $x_i=c_i$ es el minimizer. Para resumir,
$$
q_i(\lambda) = \min_{x_i} \biggl\{g_i(x_i, \lambda) :~ 0 \leq x_i \leq c_i \biggr\} = \begin{cases}
\ln(-\lambda) + \lambda + 1 & -1 < \lambda < -\frac{1}{1 + c_i a_i} \\
\min(0, -\ln(1+a_i c_i)-\lambda a_i c_i) & \text{otherwise}
\end{casos}
$$
El doble objetivo es
$$
q(\lambda) = \sum_{i=1}^n q_i(\lambda) + \lambda C
$$
Es posible simplificar las expresiones anteriores, pero no es necesario hacerlo con el fin de escribir el código que evalúa $q(\lambda)$ a fin de resolver numéricamente.