package org.activityinfo.server.report.generator.map;
/*
* #%L
* ActivityInfo Server
* %%
* Copyright (C) 2009 - 2013 UNICEF
* %%
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public
* License along with this program. If not, see
* <http://www.gnu.org/licenses/gpl-3.0.html>.
* #L%
*/
import org.activityinfo.server.report.generator.map.cluster.Cluster;
import org.activityinfo.server.report.generator.map.cluster.genetic.*;
import org.junit.Assert;
import org.junit.Ignore;
import org.junit.Test;
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.util.ArrayList;
import java.util.List;
/**
* @author Alex Bertram
*/
public class ComplexClusterTest extends GraphTest {
private static final double DELTA = 0.0001;
@Test
@Ignore("quite slow")
public void dump2dBruteForce() throws Exception {
ComplexPoints data = new ComplexPoints();
FitnessFunctor fitFtor = new BubbleFitnessFunctor();
GsLogCalculator rCtor = new GsLogCalculator(5, 30);
BufferedWriter csv = new BufferedWriter(new FileWriter(
"target/report-tests/brute.csv"));
List<List<MarkerGraph.Node>> subgraphs = data.getLargestN(2);
// write column headers
for (int j = 0; j != subgraphs.get(0).size(); ++j) {
csv.write("," + (j + 1));
}
csv.newLine();
// write rows
for (int i = 1; i <= subgraphs.get(0).size(); ++i) {
// write row header
csv.write(Integer.toString(i));
// write cell values
for (int j = 1; j <= subgraphs.get(1).size(); ++j) {
List<Cluster> clusters = new ArrayList<Cluster>();
clusters.addAll(KMeans.cluster(subgraphs.get(0), i));
clusters.addAll(KMeans.cluster(subgraphs.get(1), j));
rCtor.calculate(clusters);
csv.write(Double.toString(fitFtor.score(clusters)));
}
csv.newLine();
}
csv.close();
}
@Test
public void testUpperBounds() throws Exception {
ComplexPoints data = new ComplexPoints();
UpperBoundsCalculator.calculate(data.graph,
new FixedRadiiCalculator(5),
new UpperBoundsCalculator.Tracer() {
@Override
public void onSubgraph(int nodeCount) {
System.out
.println("Calculating upperbounds for subgraph with "
+ nodeCount + " node(s)");
}
@Override
public void incremented(int count, List<Cluster> clusters,
double fitness) {
System.out.println(count + " cluster(s) = " + fitness);
}
});
}
@Test
public void testComplexCluster() throws Exception {
ComplexPoints data = new ComplexPoints();
saveGraphImage("ComplexClusterTest-graph", data.graph, 15);
GsLogCalculator radiiCalc = new GsLogCalculator(5, 10);
double sumAfterMerging = 0;
for (MarkerGraph.Node node : data.graph.getNodes()) {
sumAfterMerging += node.getPointValue().getValue();
}
Assert.assertEquals("originalSum==sumAfterMerging", data.originalSum,
sumAfterMerging, DELTA);
// becuase the algorithm is stochiastic, we want need to make sure
// it works consistently
int count = 10;
while (count-- > 0) {
GeneticSolver solver = new GeneticSolver();
solver.setTracer(new GeneticTracer());
List<Cluster> clusters = solver.solve(data.graph, radiiCalc,
new BubbleFitnessFunctor(),
UpperBoundsCalculator.calculate(data.graph,
new FixedRadiiCalculator(5)));
double sumAfterClustering = 0;
for (Cluster cluster : clusters) {
sumAfterClustering += cluster.sumValues();
}
Assert.assertEquals("originalSum==sumAfterClustering",
data.originalSum, sumAfterClustering, DELTA);
if (count == 0) {
saveClusters(data.graph, "ComplexClusterTest-solution",
clusters);
}
System.out.println(String.format("pop size = %d", solver
.getPopulation().size()));
System.out.println(String.format("subgraph count = %d", data.graph
.getSubgraphs().size()));
System.out.println(String.format("cluster count = %d",
clusters.size()));
System.out.println(String.format("fitness = %f",
solver.getSolutionFitness()));
// TODO: this seems to be successful about 75% of the time. We need
// to move that to 100%
// and reduce variation
// Assert.assertTrue("Did not meet success criteria at run "+ count,
// solver.getSolutionFitness() > 5000);
}
}
}