/**
   * Internal method for the iteration of the swarm.
   *
   * @param init true if this is an initialisation iteration.
   */
  protected void iterationPSO(boolean init) {
    final TaskGroup group = EngineConcurrency.getInstance().createTaskGroup();

    for (int i = 0; i < m_populationSize; i++) {
      NeuralPSOWorker worker = new NeuralPSOWorker(this, i, init);
      if (!init && this.isMultiThreaded()) {
        EngineConcurrency.getInstance().processTask(worker, group);
      } else {
        worker.run();
      }
    }
    if (this.isMultiThreaded()) {
      group.waitForComplete();
    }
    updateGlobalBestPosition();
  }
  /**
   * Modify the weight matrix and bias values based on the last call to calcError.
   *
   * @throws NeuralNetworkException
   */
  @Override
  public final void iteration() {

    if (this.first) {
      EngineConcurrency.getInstance().setThreadCount(getThreadCount());
      getPopulation().claim(this);
      this.first = false;
    }

    final int countToMate = (int) (getPopulation().getPopulationSize() * getPercentToMate());
    final int offspringCount = countToMate * 2;
    int offspringIndex = getPopulation().getPopulationSize() - offspringCount;
    final int matingPopulationSize =
        (int) (getPopulation().getPopulationSize() * getMatingPopulation());

    final TaskGroup group = EngineConcurrency.getInstance().createTaskGroup();

    // mate and form the next generation
    for (int i = 0; i < countToMate; i++) {
      final Genome mother = getPopulation().getGenomes().get(i);
      final int fatherInt = (int) (Math.random() * matingPopulationSize);
      final Genome father = getPopulation().getGenomes().get(fatherInt);
      final Genome child1 = getPopulation().getGenomes().get(offspringIndex);
      final Genome child2 = getPopulation().getGenomes().get(offspringIndex + 1);

      final MateWorker worker = new MateWorker(mother, father, child1, child2);

      EngineConcurrency.getInstance().processTask(worker, group);

      offspringIndex += 2;
    }

    group.waitForComplete();

    // sort the next generation
    getPopulation().sort();
  }
  /** Process the job. */
  public void process() {
    Object task;
    EngineConcurrency.getInstance().setThreadCount(this.threadCount);

    this.running = true;
    this.totalTasks = loadWorkload();
    int currentTask = 0;
    TaskGroup group = EngineConcurrency.getInstance().createTaskGroup();

    while (((task = requestNextTask()) != null) && !shouldStop) {
      currentTask++;
      final JobUnitContext context = new JobUnitContext();
      context.setJobUnit(task);
      context.setOwner(this);
      context.setTaskNumber(currentTask);

      final JobUnitWorker worker = new JobUnitWorker(context);
      EngineConcurrency.getInstance().processTask(worker, group);
    }

    group.waitForComplete();
    this.running = false;
    EngineConcurrency.getInstance().checkError();
  }
 /** Provides any shutdown that Encog may need. Currently this shuts down the thread pool. */
 public void shutdown() {
   EngineConcurrency.getInstance().shutdown(10000);
 }