MultiStartMultivariateOptimizer.java

  1. /*
  2.  * Licensed to the Apache Software Foundation (ASF) under one or more
  3.  * contributor license agreements.  See the NOTICE file distributed with
  4.  * this work for additional information regarding copyright ownership.
  5.  * The ASF licenses this file to You under the Apache License, Version 2.0
  6.  * (the "License"); you may not use this file except in compliance with
  7.  * the License.  You may obtain a copy of the License at
  8.  *
  9.  *      http://www.apache.org/licenses/LICENSE-2.0
  10.  *
  11.  * Unless required by applicable law or agreed to in writing, software
  12.  * distributed under the License is distributed on an "AS IS" BASIS,
  13.  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14.  * See the License for the specific language governing permissions and
  15.  * limitations under the License.
  16.  */
  17. package org.apache.commons.math4.legacy.optim.nonlinear.scalar;

  18. import java.util.ArrayList;
  19. import java.util.Collections;
  20. import java.util.Comparator;
  21. import java.util.List;
  22. import java.util.function.Supplier;

  23. import org.apache.commons.math4.legacy.optim.BaseMultiStartMultivariateOptimizer;
  24. import org.apache.commons.math4.legacy.optim.PointValuePair;

  25. /**
  26.  * Multi-start optimizer.
  27.  *
  28.  * This class wraps an optimizer in order to use it several times in
  29.  * turn with different starting points (trying to avoid being trapped
  30.  * in a local extremum when looking for a global one).
  31.  *
  32.  * @since 3.0
  33.  */
  34. public class MultiStartMultivariateOptimizer
  35.     extends BaseMultiStartMultivariateOptimizer<PointValuePair> {
  36.     /** Underlying optimizer. */
  37.     private final MultivariateOptimizer optimizer;
  38.     /** Found optima. */
  39.     private final List<PointValuePair> optima = new ArrayList<>();

  40.     /**
  41.      * Create a multi-start optimizer from a single-start optimizer.
  42.      *
  43.      * @param optimizer Single-start optimizer to wrap.
  44.      * @param starts Number of starts to perform.
  45.      * If {@code starts == 1}, the result will be same as if {@code optimizer}
  46.      * is called directly.
  47.      * @param generator Generator to use for restarts.
  48.      * @throws org.apache.commons.math4.legacy.exception.NullArgumentException NullArgumentException if {@code optimizer} or {@code generator}
  49.      * is {@code null}.
  50.      * @throws org.apache.commons.math4.legacy.exception.NotStrictlyPositiveException NotStrictlyPositiveException if {@code starts < 1}.
  51.      */
  52.     public MultiStartMultivariateOptimizer(final MultivariateOptimizer optimizer,
  53.                                            final int starts,
  54.                                            final Supplier<double[]> generator) {
  55.         super(optimizer, starts, generator);
  56.         this.optimizer = optimizer;
  57.     }

  58.     /**
  59.      * {@inheritDoc}
  60.      */
  61.     @Override
  62.     public PointValuePair[] getOptima() {
  63.         Collections.sort(optima, getPairComparator());
  64.         return optima.toArray(new PointValuePair[0]);
  65.     }

  66.     /**
  67.      * {@inheritDoc}
  68.      */
  69.     @Override
  70.     protected void store(PointValuePair optimum) {
  71.         optima.add(optimum);
  72.     }

  73.     /**
  74.      * {@inheritDoc}
  75.      */
  76.     @Override
  77.     protected void clear() {
  78.         optima.clear();
  79.     }

  80.     /**
  81.      * @return a comparator for sorting the optima.
  82.      */
  83.     private Comparator<PointValuePair> getPairComparator() {
  84.         return new Comparator<PointValuePair>() {
  85.             /** {@inheritDoc} */
  86.             @Override
  87.             public int compare(final PointValuePair o1,
  88.                                final PointValuePair o2) {
  89.                 if (o1 == null) {
  90.                     return (o2 == null) ? 0 : 1;
  91.                 } else if (o2 == null) {
  92.                     return -1;
  93.                 }
  94.                 final double v1 = o1.getValue();
  95.                 final double v2 = o2.getValue();
  96.                 return (optimizer.getGoalType() == GoalType.MINIMIZE) ?
  97.                     Double.compare(v1, v2) : Double.compare(v2, v1);
  98.             }
  99.         };
  100.     }
  101. }