001 /*
002 * Copyright 2011 Christian Kumpe http://kumpe.de/christian/java
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 * http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016 package de.kumpe.hadooptimizer.examples.functions;
017
018 import java.awt.Color;
019 import java.awt.Graphics2D;
020 import java.util.ArrayList;
021 import java.util.Collection;
022 import java.util.Collections;
023 import java.util.Iterator;
024 import java.util.List;
025
026 import de.kumpe.hadooptimizer.EvaluationResult;
027 import de.kumpe.hadooptimizer.Evaluator;
028
029 /**
030 * A Panel which draws the graph of the evaluation-function (in the usual
031 * coordinate-system) renders the current population on top of the graph every
032 * {@link #refreshMillis} milliseconds.
033 *
034 * @author Christian Kumpe <christian@kumpe.de>
035 */
036 public class LiveHistoryPanelReporter extends HistoryPanelReporter {
037 private static final long serialVersionUID = 1L;
038 private final int refreshMillis;
039 private volatile List<double[]> currentPopulation;
040 private volatile long iteration;
041 private long lastRepaint;
042
043 public LiveHistoryPanelReporter(final Evaluator<double[]> evaluator,
044 final int refreshMillis) {
045 super(evaluator);
046 this.refreshMillis = refreshMillis;
047 }
048
049 @Override
050 public void report(
051 final Collection<EvaluationResult<double[]>> evaluationResults) {
052 iteration++;
053 final ArrayList<double[]> list = new ArrayList<double[]>();
054 for (final EvaluationResult<double[]> evaluationResult : evaluationResults) {
055 list.add(evaluationResult.getIndividual());
056 }
057 currentPopulation = Collections.unmodifiableList(list);
058 final long currentTime = System.currentTimeMillis();
059 if (currentTime - lastRepaint > refreshMillis) {
060 repaint();
061 lastRepaint = currentTime;
062 }
063 }
064
065 @Override
066 protected void drawPopulations(final Graphics2D graphics) {
067 final int width = getWidth();
068 final int height = getHeight();
069 final int centerX = width / 2;
070 final int centerY = height / 2;
071
072 if (null == currentPopulation) {
073 return;
074 }
075 final Iterator<double[]> individuals = currentPopulation.iterator();
076 if (!individuals.hasNext()) {
077 return;
078 }
079 double[] individual = individuals.next();
080 double x = individual[0];
081 double y = evaluator.evaluate(individual);
082 int pixelX = (int) (x * SCALE_FACTOR);
083 int pixelY = -(int) (y * SCALE_FACTOR);
084 graphics.setColor(Color.LIGHT_GRAY);
085 graphics.drawLine(-centerX, pixelY, centerX, pixelY);
086 graphics.drawLine(pixelX, -centerY, pixelX, centerY);
087
088 graphics.setColor(Color.BLACK);
089 graphics.setFont(HistoryPanelReporter.MEDIUM_FONT);
090 graphics.drawString(String.format("x=%10.5f y=%10.5f", x, y),
091 pixelX + 3, pixelY + 15);
092
093 graphics.setFont(HistoryPanelReporter.LARGE_FONT);
094 graphics.drawString(String.format("Iteration %d: x=%10.5f y=%10.5f",
095 iteration, x, y), -centerX, -centerY + 20);
096
097 graphics.setColor(Color.BLUE);
098 graphics.fillOval(pixelX - 3, pixelY - 3, 6, 6);
099
100 while (individuals.hasNext()) {
101 individual = individuals.next();
102 x = individual[0];
103 y = evaluator.evaluate(individual);
104 pixelX = (int) (x * SCALE_FACTOR);
105 pixelY = -(int) (y * SCALE_FACTOR);
106 graphics.drawOval(pixelX - 1, pixelY - 1, 2, 2);
107 }
108 }
109 }