code: protected ResultEntry optimize(ObjectiveProblem objectiveProblem, Algorithm algorithm) {
          PreciseTimestamp startPreciseTimestamp = null;
          Exception algorithmException = null;
          Configuration bestConfiguration = null;
          int optimizeCounter = 0;
  
          try {
              startPreciseTimestamp = new PreciseTimestamp();
  
              algorithm.init(objectiveProblem);
              this.sendMessage(new MessageSolverStart(algorithm, objectiveProblem));
              logger.info("Started optimize, {} on {}.", algorithm,  objectiveProblem);
  
              do {
                  algorithm.optimize();
                  this.sendMessage(new MessageOptimize());
                  optimizeCounter++;
  
                  if (algorithm.getBestConfiguration() != null
                          && (bestConfiguration == null || !bestConfiguration.equals(algorithm.getBestConfiguration()))) {
                      logger.debug("Better solution {}, {}, {}",
                              algorithm.getBestFitness(), optimizeCounter, algorithm.getBestConfiguration());
  
                      bestConfiguration = algorithm.getBestConfiguration();
  
                      this.sendMessage(new MessageBetterConfigurationFound(bestConfiguration, algorithm.getBestFitness()));
  
                      if (objectiveProblem.isSolution(bestConfiguration))
                          this.sendMessage(new MessageSolutionFound(bestConfiguration, algorithm.getBestFitness()));
                  }
  
                  if (this.isConditionMet()) break;
              } while (true);
          } catch (Exception e) {
              logger.warn("Got exception {}.", e.getClass().getSimpleName());
              algorithmException = e;
          }
  
          this.sendMessage(new MessageSolverStop(algorithm, objectiveProblem));
          logger.info("Stopped optimize.");
  
          algorithm.cleanUp();
  
          return new ResultEntry(algorithm, objectiveProblem, bestConfiguration, algorithm.getBestFitness(),
                  optimizeCounter, algorithmException, startPreciseTimestamp);
      }
docs: Applies one algorithm on one problem until any condition is met or exception is raised.
  <p/>
  This method just removes code duplicities since most solvers has identical this part of solving. It is not
  obligatory to use this method however, change it if necessary (for example algorithm switching on simple
  problem).
  
  @param objectiveProblem problem to be solved
  @param algorithm        algorithm to be used during solving
  @return result entry for this optimization