All Downloads are FREE. Search and download functionalities are using the official Maven repository.

io.github.ericmedvet.jgea.experimenter.builders.Problems Maven / Gradle / Ivy

The newest version!
/*-
 * ========================LICENSE_START=================================
 * jgea-experimenter
 * %%
 * Copyright (C) 2018 - 2024 Eric Medvet
 * %%
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 * =========================LICENSE_END==================================
 */

package io.github.ericmedvet.jgea.experimenter.builders;

import io.github.ericmedvet.jgea.core.order.PartialComparator;
import io.github.ericmedvet.jgea.core.problem.MultiHomogeneousObjectiveProblem;
import io.github.ericmedvet.jgea.core.problem.MultiTargetProblem;
import io.github.ericmedvet.jgea.core.problem.ProblemWithExampleSolution;
import io.github.ericmedvet.jgea.core.problem.TotalOrderQualityBasedProblem;
import io.github.ericmedvet.jgea.problem.simulation.SimulationBasedProblem;
import io.github.ericmedvet.jgea.problem.simulation.SimulationBasedTotalOrderProblem;
import io.github.ericmedvet.jnb.core.*;
import io.github.ericmedvet.jnb.datastructure.DoubleRange;
import io.github.ericmedvet.jsdynsym.control.Environment;
import io.github.ericmedvet.jsdynsym.control.Simulation;
import io.github.ericmedvet.jsdynsym.control.SimulationWithExample;
import io.github.ericmedvet.jsdynsym.control.SingleAgentTask;
import io.github.ericmedvet.jsdynsym.core.numerical.NumericalDynamicalSystem;
import io.github.ericmedvet.jsdynsym.core.numerical.NumericalStatelessSystem;
import java.util.Comparator;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.function.Supplier;

@Discoverable(prefixTemplate = "ea.problem|p")
public class Problems {

  private Problems() {}

  public enum OptimizationType {
    @SuppressWarnings("unused")
    MINIMIZE,
    MAXIMIZE
  }

  private interface SimulationBasedProblemWithExample, Q>
      extends SimulationBasedProblem, ProblemWithExampleSolution {
    static , Q> SimulationBasedProblemWithExample from(
        Function behaviorQualityFunction,
        Simulation simulation,
        PartialComparator> qualityComparator,
        S example) {
      return new SimulationBasedProblemWithExample<>() {
        @Override
        public S example() {
          return example;
        }

        @Override
        public Function outcomeQualityFunction() {
          return behaviorQualityFunction;
        }

        @Override
        public Simulation simulation() {
          return simulation;
        }

        @Override
        public PartialComparator> qualityComparator() {
          return qualityComparator;
        }
      };
    }
  }

  private interface SimulationBasedTotalOrderProblemWithExample<
          S, B, O extends Simulation.Outcome, Q extends Comparable>
      extends SimulationBasedTotalOrderProblem, ProblemWithExampleSolution {
    static , Q extends Comparable>
        SimulationBasedTotalOrderProblemWithExample from(
            Function behaviorQualityFunction,
            Simulation simulation,
            S example,
            OptimizationType type) {
      return new SimulationBasedTotalOrderProblemWithExample<>() {
        @Override
        public S example() {
          return example;
        }

        @Override
        public Function outcomeQualityFunction() {
          return behaviorQualityFunction;
        }

        @Override
        public Simulation simulation() {
          return simulation;
        }

        @Override
        public Comparator> totalOrderComparator() {
          return switch (type) {
            case MINIMIZE -> Comparator.comparing(QualityOutcome::quality);
            case MAXIMIZE -> ((o1, o2) -> o2.quality().compareTo(o1.quality()));
          };
        }
      };
    }
  }

  @SuppressWarnings("unused")
  public static >
      SimulationBasedTotalOrderProblem<
              NumericalDynamicalSystem,
              SingleAgentTask.Step,
              Simulation.Outcome>,
              Q>
          numEnvTo(
              @Param(value = "name", iS = "{environment.name}") String name,
              @Param(value = "dT", dD = 0.1) double dT,
              @Param(value = "initialT", dD = 0) double initialT,
              @Param(value = "finalT", dD = 60) double finalT,
              @Param("environment") Environment environment,
              @Param(value = "stopCondition", dNPM = "predicate.not(condition = predicate.always())")
                  Predicate stopCondition,
              @Param("f")
                  Function>, Q>
                      outcomeQualityFunction,
              @Param(value = "type", dS = "minimize") OptimizationType type,
              @Param(value = "", injection = Param.Injection.BUILDER) NamedBuilder nb,
              @Param(value = "", injection = Param.Injection.MAP) ParamMap map) {
    int nOfOutputs = environment.defaultAgentAction().length;
    int nOfInputs = environment.step(0, environment.defaultAgentAction()).length;
    @SuppressWarnings("unchecked")
    Supplier> envSupplier = () -> (Environment)
        nb.build((NamedParamMap) map.value("environment", ParamMap.Type.NAMED_PARAM_MAP));
    return SimulationBasedTotalOrderProblemWithExample.from(
        outcomeQualityFunction,
        SingleAgentTask.fromEnvironment(envSupplier, stopCondition, new DoubleRange(initialT, finalT), dT),
        NumericalStatelessSystem.from(nOfInputs, nOfOutputs, (t, in) -> new double[nOfOutputs]),
        type);
  }

  @SuppressWarnings("unused")
  public static , Q extends Comparable>
      SimulationBasedTotalOrderProblem simTo(
          @Param(value = "name", iS = "{simulation.name}") String name,
          @Param("simulation") Simulation simulation,
          @Param("f") Function outcomeQualityFunction,
          @Param(value = "type", dS = "minimize") OptimizationType type) {
    Comparator> comparator =
        switch (type) {
          case MINIMIZE -> Comparator.comparing(
              (SimulationBasedProblem.QualityOutcome qo) -> qo.quality());
          case MAXIMIZE -> (qo1, qo2) -> qo2.quality().compareTo(qo1.quality());
        };
    if (simulation instanceof SimulationWithExample simulationWithExample) {
      return new SimulationBasedTotalOrderProblemWithExample<>() {
        @Override
        public S example() {
          return simulationWithExample.example();
        }

        @Override
        public Function outcomeQualityFunction() {
          return outcomeQualityFunction;
        }

        @Override
        public Simulation simulation() {
          return simulation;
        }
      };
    }
    return new SimulationBasedTotalOrderProblem<>() {
      @Override
      public Function outcomeQualityFunction() {
        return outcomeQualityFunction;
      }

      @Override
      public Simulation simulation() {
        return simulation;
      }

      @Override
      public Comparator> totalOrderComparator() {
        return comparator;
      }
    };
  }

  @SuppressWarnings("unused")
  public static  MultiHomogeneousObjectiveProblem toMho(
      @Param(value = "name", iS = "mt2mo({mtProblem.name})") String name,
      @Param("mtProblem") MultiTargetProblem mtProblem) {
    return mtProblem.toMHOProblem();
  }

  @SuppressWarnings("unused")
  public static > TotalOrderQualityBasedProblem totalOrder(
      @Param(value = "name", dS = "{qFunction}") String name,
      @Param("qFunction") Function qualityFunction,
      @Param(value = "cFunction", dNPM = "f.identity()") Function comparableFunction,
      @Param(value = "type", dS = "minimize") OptimizationType type) {
    return new TotalOrderQualityBasedProblem<>() {
      @Override
      public Function qualityFunction() {
        return qualityFunction;
      }

      @Override
      public Comparator totalOrderComparator() {
        if (type.equals(OptimizationType.MAXIMIZE)) {
          return Comparator.comparing(comparableFunction).reversed();
        }
        return Comparator.comparing(comparableFunction);
      }
    };
  }
}