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

science.aist.machinelearning.problem.fitness.evaluation.GPEvaluationTimerCachet Maven / Gradle / Ivy

The newest version!
/*
 * Copyright (c) 2021 the original author or authors.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at https://mozilla.org/MPL/2.0/.
 */

package science.aist.machinelearning.problem.fitness.evaluation;

import org.apache.log4j.Logger;
import science.aist.machinelearning.algorithm.gp.FunctionalGPGraphNode;
import science.aist.machinelearning.algorithm.gp.GPGraphNode;
import science.aist.machinelearning.algorithm.gp.nodes.basic.ResultNode;
import science.aist.machinelearning.algorithm.gp.nodes.heuristic.SolutionCreatorNode;
import science.aist.machinelearning.algorithm.gp.util.BasicNodeUtil;
import science.aist.machinelearning.algorithm.gp.util.GPTrim;
import science.aist.machinelearning.core.Problem;
import science.aist.machinelearning.core.Solution;
import science.aist.machinelearning.core.SolutionGene;
import science.aist.machinelearning.core.fitness.Cachet;
import science.aist.machinelearning.core.fitness.CachetEvaluator;
import science.aist.machinelearning.core.fitness.Evaluator;
import science.aist.machinelearning.problem.GPProblem;

import java.util.Collection;
import java.util.List;

/**
 * Checks the quality of the GP-heuristic by running different problems on them. Depending on the settings, will
 * calculate a single problem several times and average the quality out.
 * 

* Will run a timer for each evaluation process. If the evaluation process takes too long, will try to interrupt. * Interrupting like this will result in very bad results for the GP-heuristic. * * @author Daniel Wilfing * @since 1.0 */ public class GPEvaluationTimerCachet implements CachetEvaluator { final static Logger logger = Logger.getLogger(GPEvaluationTimerCachet.class); /** * Time a specific thread waits until it has to check for the current evaluation time again. */ private final long evaluationTimeStep = 50; /** * Defines how often each problem gets solved. */ private int runsPerProblem = 1; /** * Max time an evaluation should take until it gets interrupted */ private long evaluationTime = 1000; private Collection> problems; private Evaluator evaluator; /** * Required to check if we have to interrupt an evaluation process. */ private boolean finishedCalculation = false; /** * To check if we had to interrupt the execution of the graph or not. If we have to interrupt, add some penalty to * the quality. */ private boolean interrupted = false; /** * Contains the runtime of the execution of the last heuristic. */ private long lastRuntimeCalculation = 0L; @Override public double evaluateQuality(Solution solution) { if (solution == null || solution.getSolutionGenes() == null || solution.getSolutionGenes().size() == 0) { solution.getCachets().add(new Cachet(100_000_000.0, "GPEvaluationTimerCachet")); return 100_000_000; //super bad quality } SolutionGene currentGene = solution.getSolutionGenes().get(0); ResultNode trimedGraph = GPTrim.trimGraph(currentGene.getGene()); double quality = 0.0; for (Problem problem : problems) { //find SolutionCreators and give them the problem to solve checkForSolutionCreator(trimedGraph, problem); //solve the problem x times and add the average to the quality double problemQuality = 0.0; long durationPerProblem = 0; int i; for (i = 0; i < runsPerProblem; i++) { finishedCalculation = false; interrupted = false; Thread sleepThread = new Thread(() -> { try { long sleptFor = 0; //sleep for a bit, then check if calculations are done while (sleptFor < evaluationTime && !finishedCalculation) { Thread.sleep(evaluationTimeStep); sleptFor += evaluationTimeStep; } //if we have waited, but the evaluation is not done yet, then try to interrupt the evaluation if (!finishedCalculation) { interrupted = true; BasicNodeUtil.interruptGraph(trimedGraph, true); logger.info("Interrupted execution of a gp-graph."); } } catch (InterruptedException e) { e.printStackTrace(); } }); long duration = System.currentTimeMillis(); sleepThread.start(); Solution newSolution = null; try { newSolution = trimedGraph.execute(); finishedCalculation = true; } catch (Error e) { //the gp-graph created so many solutions, that we either ran into outOfMemory- or GCOverhead-Errors //penalize the solution, then lets try to fix this problem by garbage collecting once more. System.gc(); interrupted = true; logger.info("Had to stop execution because of: " + e.getClass().getName()); } duration = System.currentTimeMillis() - duration; durationPerProblem += Math.min(duration, evaluationTime); //in some gp-graphes, its possible that no solution could be created if (newSolution != null) { problemQuality += evaluator.evaluateQuality(newSolution); } else { //heavily penalize if no solution could be created problemQuality += 100_000; } try { sleepThread.join(); } catch (InterruptedException e) { e.printStackTrace(); } //if we have to interrupt calculation of the graph, then we have to penalize it severely if (interrupted) { problemQuality = 1_000_000; //if we had to interrupt the execution process, its unlikely that it will work on the next run break; } } quality += problemQuality / (i + 1); lastRuntimeCalculation += durationPerProblem / (i + 1); } lastRuntimeCalculation /= problems.size(); quality /= problems.size(); if (quality < 0 || quality > 1_000_000) { quality = 1_000_000; } solution.getCachets().add(new Cachet(quality, "GPEvaluationTimerCachet")); return quality; } @Override public String getName() { return "GPEvaluationTimerCachet"; } public void setRunsPerProblem(int runsPerProblem) { this.runsPerProblem = runsPerProblem; } public void setProblems(Collection> problems) { this.problems = problems; } public void setEvaluator(Evaluator evaluator) { this.evaluator = evaluator; } public void setEvaluationTime(long evaluationTime) { this.evaluationTime = evaluationTime; } public long getLastRuntimeCalculation() { return lastRuntimeCalculation; } /** * Checks where the solutionCreator is and gives him the problem. * * @param currentNode currentNode to check * @param problem problem to hand over to the solutionCreator */ private void checkForSolutionCreator(GPGraphNode currentNode, Problem problem) { //the currentNode is a solutionCreator and we give him the problem if (currentNode instanceof SolutionCreatorNode) { SolutionCreatorNode castedNode = (SolutionCreatorNode) currentNode; castedNode.setProblem(problem); } //the currentNode is a functional node and we have to check its children else if (currentNode instanceof FunctionalGPGraphNode) { FunctionalGPGraphNode castedNode = (FunctionalGPGraphNode) currentNode; for (GPGraphNode nextNode : (List) castedNode.getChildNodes()) { checkForSolutionCreator(nextNode, problem); } } } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy