using System.Collections.Generic;
using Accord.Math.Optimization;
static void Main(string[] args)
double[] d1 = { -3.99, -3.82, -0.74, 4.15, -4.18, -0.26, 0.12, -2.06, 5.91, 3.40, -0.52, 1.99, 0.00 };
double[] b = { 57.90, 6.86, 17.32, 6.84, 2.58, 4.02, 0.29, 0.79, 0.00, 0.00, 0.63, 0.72, 2.02 };
double[] thresholds = { 0.05, 0.05, 0.05, 0.05, 0.05, 0.05, 0.05, 0.05, 0.05, 0.05, 0.05, 0.05, 0.05 };
double[] minValues = { -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, 0 };
double[] maxValues = { 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 0 };
var solver = new OptimizationSolver(d1, b, thresholds, minValues, maxValues);
var (d2, minValue) = solver.Minimize();
Console.WriteLine("Optimized D2:");
Console.WriteLine(string.Join(", ", d2.Select(x => x.ToString("F4"))));
Console.WriteLine($"Minimum Value: {minValue:F6}");
Console.WriteLine($"Sum of D2 (should be 0): {d2.Sum():F6}");
for (int i = 0; i < d2.Length; i++)
double check1 = d2[i] + b[i];
if (check1 < thresholds[i])
Console.WriteLine($"Threshold constraint violated at index {i}: d2 + b = {check1}");
if (check2 < minValues[i])
Console.WriteLine($"Min constraint violated at index {i}: d2 = {check2} < {minValues[i]}");
if (check2 > maxValues[i])
Console.WriteLine($"Max constraint violated at index {i}: d2 = {check2} > {maxValues[i]}");
Console.WriteLine("All constraints checked.");
public class OptimizationSolver
private readonly double[] D1;
private readonly double[] Bmk;
private readonly double[] Thresholds;
private readonly double[] MinValues;
private readonly double[] MaxValues;
public OptimizationSolver(double[] d1, double[] bmk, double[] thresholds, double[] minValues, double[] maxValues)
if (d1.Length != bmk.Length || d1.Length != thresholds.Length || d1.Length != minValues.Length || d1.Length != maxValues.Length)
throw new ArgumentException("All arrays must have the same length.");
public (double[] optimizedD2, double minValue) Minimize()
var objective = new NonlinearObjectiveFunction(N, d2 =>
for (int i = 0; i < N; i++)
sum += Math.Pow(D1[i] - d2[i], 2);
var constraints = new List<NonlinearConstraint>();
for (int i = 0; i < N; i++)
constraints.Add(new NonlinearConstraint(N, x => x[index] + Bmk[index] - Thresholds[index]));
for (int i = 0; i < N; i++)
constraints.Add(new NonlinearConstraint(N, x => x[index] - MinValues[index]));
for (int i = 0; i < N; i++)
constraints.Add(new NonlinearConstraint(N, x => MaxValues[index] - x[index]));
constraints.Add(new NonlinearConstraint(N, x => x.Sum()));
constraints.Add(new NonlinearConstraint(N, x => -x.Sum()));
var solver = new Cobyla(objective, constraints.ToArray());
solver.Solution = (double[])D1.Clone();
solver.MaxIterations = 10000;
bool success = solver.Minimize();
throw new Exception("Cobyla failed to converge.");
return (solver.Solution, solver.Value);