Math.NET Numericsに機能が増えている
最近使っていないうちに Math.NET Numericsの機能が増えている.数値最小化問題を解けるようになっている.
MathNet.Numerics.Optimizationには数値最小化問題を解ける機能が備わっている.
最小化問題だが,符号を変えれば最大化問題も最小化問題になる.また,目的関数最小化(最適化)問題と呼ぶこともある.例えば以下のように使用できる.
最近の.NETには
var f1 = new Func<double, double>(x => sample(x));
というFuncという汎用のデリゲートがあるのが面白い.
using MathNet.Numerics.Optimization;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleApp1
{
class Program
{
static void Main(string[] args)
{
// 一次元探索
var f1 = new Func<double, double>(x => sample(x));
var obj = ObjectiveFunction.ScalarValue(f1);
var r1 = GoldenSectionMinimizer.Minimum(obj, -100, 100, 1e-8, 1000, 10, 4, 4);
Console.WriteLine($"{r1.FunctionInfoAtMinimum.Point:G16}");
Console.WriteLine($"{r1.FunctionInfoAtMinimum.Value:G16}");
// 多次元探索
var f2 = new Func<MathNet.Numerics.LinearAlgebra.Vector<double>, double>(x => sample2(x));
var obj2 = ObjectiveFunction.Value(f2);
var init = MathNet.Numerics.LinearAlgebra.Vector<double>.Build;
var r2 = NelderMeadSimplex.Minimum(obj2, init.Dense(new double[] { 0.0, 0.0 }));
Console.WriteLine($"{r2.FunctionInfoAtMinimum.Point[0]:G16},{r2.FunctionInfoAtMinimum.Point[1]:G16}");
Console.WriteLine($"{r2.FunctionInfoAtMinimum.Value:G16}");
}
static double sample(double x)
{
return (x - 3000) * (x - 3000);
}
static double sample2(MathNet.Numerics.LinearAlgebra.Vector<double> x)
{
return (x[0] - 1000) * (x[0] - 1000) + (x[1] - 3000) * (x[1] - 3000);
}
}
}

