最近使っていないうちに 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); } } }