使用 Apache Commons Math 在 Java 中进行优化

Optimisation in Java Using Apache Commons Math

我正在尝试使用 commons-math 最小化 Java 中的值。我看过他们的 documentation 但我真的不知道如何实现它。

基本上,在我下面的代码中,我有一个 Double,它具有足球比赛中的预期进球,我想将一场比赛中出现 3 个以下进球的概率值优化为 0.5。


import org.apache.commons.math3.distribution.PoissonDistribution;

public class Solver {

    public static void main(String[] args) {

        final Double expectedGoals = 2.9d;
        final PoissonDistribution poissonGoals = new PoissonDistribution(expectedGoals);

        Double probabilityUnderThreeGoals = 0d;

        for (int score = 0; score < 15; score++) {
            final Double probability =
                    poissonGoals.probability(score);
            if (score < 3) {
                probabilityUnderThreeGoals = probabilityUnderThreeGoals + probability;
            }
        }

        System.out.println(probabilityUnderThreeGoals); //prints 0.44596319855718064, I want to optimise this to 0.5
    }
}

泊松随机变量的累积概率 (<= x) 可以通过以下公式计算:

在你的例子中,x 是 2,你想要找到 lambda(均值)使得它是 0.5。你可以 type this into WolframAlpha 让它帮你解决。因此,这不是一个优化问题,而只是一个寻根问题(尽管有人可能会争辩说优化问题 只是寻根。)

您也可以使用 Apache Commons Maths 执行此操作,使用 root finders.

之一
int maximumGoals = 2;
double expectedProbability = 0.5;
UnivariateFunction f = x -> {
  double sum = 0;
  for (int i = 0; i <= maximumGoals; i++) {
    sum += Math.pow(x, i) / CombinatoricsUtils.factorialDouble(i);
  }
  return sum * Math.exp(-x) - expectedProbability;
};

// the four parameters that "solve" takes are:
// the number of iterations, the function to solve, min and max of the root
// I've put some somewhat sensible values as an example. Feel free to change them
double answer = new BisectionSolver().solve(Integer.MAX_VALUE, f, 0, maximumGoals / expectedProbability);
System.out.println("Solved: " + answer);
System.out.println("Cumulative Probability: " + new PoissonDistribution(answer).cumulativeProbability(maximumGoals));

这会打印:

Solved: 2.674060344696045
Cumulative Probability: 0.4999999923623868