add java examples
This commit is contained in:
parent
624c92e934
commit
d345f67212
19 changed files with 1208 additions and 0 deletions
94
java/Point.java
Normal file
94
java/Point.java
Normal file
|
|
@ -0,0 +1,94 @@
|
||||||
|
package patterns;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author pouyllau
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class Point {
|
||||||
|
|
||||||
|
public double x;
|
||||||
|
public double y;
|
||||||
|
|
||||||
|
public Point(double x, double y) {
|
||||||
|
super();
|
||||||
|
this.x = x;
|
||||||
|
this.y = y;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static double distance(Point u, Point v) {
|
||||||
|
return Math.sqrt( (u.x - v.x)*(u.x - v.x) + (u.y - v.y)*(u.y - v.y));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compute and set the coordinates of the neighbors of the given point,
|
||||||
|
* according to grid parameters and directions. Directions are supposed to
|
||||||
|
* be given in a specific order (in this project, the transit_in_simplex
|
||||||
|
* functions will necessitate clockwise order).
|
||||||
|
*
|
||||||
|
* @param step
|
||||||
|
* Length of an orthogonal edge of the grid.
|
||||||
|
* @param pMin
|
||||||
|
* Corner point of the grid, with minimal coordinates.
|
||||||
|
* @param pMax
|
||||||
|
* Corner point of the grid, with maximal coordinates.
|
||||||
|
* @param directions
|
||||||
|
* The given direction
|
||||||
|
*/
|
||||||
|
public static List<Point> neighbors_grid(Point p, double step, Point pMin, Point pMax, List<Point> directions) {
|
||||||
|
|
||||||
|
List<Point> neighbors = new ArrayList<Point>(directions.size());
|
||||||
|
for (Point d : directions) {
|
||||||
|
double nx = p.x + d.x * step;
|
||||||
|
double ny = p.y + d.y * step;
|
||||||
|
if ( pMin.x <= nx && nx <= pMax.x && pMin.y <= ny && ny <= pMax.y) {
|
||||||
|
neighbors.add(new Point(nx, ny));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
assert (neighbors.size() >= 2);
|
||||||
|
|
||||||
|
return neighbors;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
final int prime = 7919;
|
||||||
|
int result = 1;
|
||||||
|
long temp;
|
||||||
|
temp = Double.doubleToLongBits(x);
|
||||||
|
result = prime * result + (int) (temp ^ (temp >>> 7920));
|
||||||
|
temp = Double.doubleToLongBits(y);
|
||||||
|
result = prime * result + (int) (temp ^ (temp >>> 7920));
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object obj) {
|
||||||
|
if (this == obj)
|
||||||
|
return true;
|
||||||
|
if (obj == null)
|
||||||
|
return false;
|
||||||
|
if (getClass() != obj.getClass())
|
||||||
|
return false;
|
||||||
|
Point other = (Point) obj;
|
||||||
|
if (Double.doubleToLongBits(x) != Double.doubleToLongBits(other.x))
|
||||||
|
return false;
|
||||||
|
if (Double.doubleToLongBits(y) != Double.doubleToLongBits(other.y))
|
||||||
|
return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "Point [x=" + x + ", y=" + y+ "]";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
170
java/crtp/Algo.java
Normal file
170
java/crtp/Algo.java
Normal file
|
|
@ -0,0 +1,170 @@
|
||||||
|
package patterns.crtp;
|
||||||
|
|
||||||
|
import java.text.DecimalFormat;
|
||||||
|
import java.util.Comparator;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Locale;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.PriorityQueue;
|
||||||
|
|
||||||
|
import patterns.Point;
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author pouyllau
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class Algo {
|
||||||
|
|
||||||
|
private static boolean DEBUG = false;
|
||||||
|
|
||||||
|
public static Map<Point, Double> run(Point seed, int iterations, Neighborhood neighborhood, Transit transit) {
|
||||||
|
Map<Point, Double> costs = new HashMap<Point, Double>();
|
||||||
|
|
||||||
|
PriorityQueue<Point> front = new PriorityQueue<Point>(new Comparator<Point>() {
|
||||||
|
public int compare(Point lhs, Point rhs) {
|
||||||
|
if (costs.get(lhs) >= costs.get(rhs))
|
||||||
|
return +1;
|
||||||
|
if (costs.get(lhs) < costs.get(rhs))
|
||||||
|
return -1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
costs.put(seed, 0.);
|
||||||
|
front.add(seed);
|
||||||
|
|
||||||
|
for (int i = 0; i < iterations && !front.isEmpty(); i++) {
|
||||||
|
if (DEBUG)
|
||||||
|
System.out.println(i + "/" + iterations);
|
||||||
|
|
||||||
|
// Accept the node with the min cost and update neighbors.
|
||||||
|
// Accept the considered node with the min cost.
|
||||||
|
Point accepted = front.poll();
|
||||||
|
|
||||||
|
// Consider neighbors of the accepted node.
|
||||||
|
List<Point> around = neighborhood.get(accepted);
|
||||||
|
assert (around.size() > 0);
|
||||||
|
|
||||||
|
for (Point n : around) {
|
||||||
|
// If no cost has been computed (i.e. the node is "open").
|
||||||
|
if (!Transit.hasCost(n, costs)) {
|
||||||
|
|
||||||
|
double ncost = transit.transit(n, neighborhood.get(n), costs);
|
||||||
|
if (DEBUG)
|
||||||
|
System.out.println(n + " cost=" + ncost);
|
||||||
|
costs.put(n, ncost);
|
||||||
|
front.add(n);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return costs;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void printGrid(Map<Point, Double> grid, Point pMin, Point pMax, double step, String sep) {
|
||||||
|
if (sep == null)
|
||||||
|
sep = "\t";
|
||||||
|
String width = " ";
|
||||||
|
System.out.print(" x:"+sep);
|
||||||
|
|
||||||
|
for (double px = pMin.x; px <= pMax.x; px += step) {
|
||||||
|
System.out.print(sep + (int)px+ " "+ width );
|
||||||
|
}
|
||||||
|
|
||||||
|
System.out.print("\n");
|
||||||
|
System.out.print(" y\n");
|
||||||
|
|
||||||
|
for (double py = pMax.y; py >= pMin.y; py -= step) {
|
||||||
|
System.out.print(sep + (int)py + ":");
|
||||||
|
for (double px = pMin.x; px <= pMax.x; px += step) {
|
||||||
|
Point p = new Point(px, py);
|
||||||
|
if (Transit.hasCost(p, grid)) {
|
||||||
|
System.out.format(sep + "%.2f" + width, grid.get(p));
|
||||||
|
} else {
|
||||||
|
System.out.print(sep + " . " + width);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
System.out.print("\n");
|
||||||
|
}
|
||||||
|
System.out.print("\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void performEvaluations(Point seed, int iterations, Neighborhood neighborhood, Transit transit, int T) {
|
||||||
|
double mean = 0;
|
||||||
|
double m2 = 0;
|
||||||
|
for (int t = 0; t < T; t++) {
|
||||||
|
long startTime = System.nanoTime();
|
||||||
|
run(seed, iterations, neighborhood, transit);
|
||||||
|
startTime = System.nanoTime() - startTime;
|
||||||
|
double delta = (double)startTime - mean;
|
||||||
|
mean += delta / (double) T;
|
||||||
|
m2 += delta * delta;
|
||||||
|
}
|
||||||
|
m2 = m2 / (double)(T-1.);
|
||||||
|
m2 = Math.sqrt(m2);
|
||||||
|
System.out.println("Mean time : " + new DecimalFormat("#.##########").format((mean / 1000000000)) + " s"
|
||||||
|
+ " sd : " + new DecimalFormat("#.##########").format((m2 / 1000000000)));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
Locale.setDefault(Locale.US);
|
||||||
|
Point seed = new Point(0, 0);
|
||||||
|
Point pMin = new Point(-5, -5);
|
||||||
|
Point pMax = new Point(15, 15);
|
||||||
|
double step = 1.;
|
||||||
|
int maxit = 300;
|
||||||
|
double eps = 1. / 100.0;
|
||||||
|
int eval = 100;
|
||||||
|
|
||||||
|
Neighborhood quad= new QuadGrid(step, pMin, pMax);
|
||||||
|
Neighborhood octo = new OctoGrid(step, pMin, pMax);
|
||||||
|
|
||||||
|
Transit graph = new TransitOnEdge();
|
||||||
|
Transit mesh = new TransitInSimplex(eps);
|
||||||
|
|
||||||
|
|
||||||
|
System.out.println("Dijkstra, 4 neighbors");
|
||||||
|
performEvaluations(seed, maxit, quad, graph, eval);
|
||||||
|
System.out.println("Dijkstra, 8 neighbors");
|
||||||
|
performEvaluations(seed, maxit, octo, graph, eval);
|
||||||
|
System.out.println("Fast marching, 4 neighbors");
|
||||||
|
performEvaluations(seed, maxit, quad, mesh, eval);
|
||||||
|
System.out.println("Fast marching, 8 neighbors");
|
||||||
|
performEvaluations(seed, maxit, octo, mesh, eval);
|
||||||
|
|
||||||
|
/*System.out.println("Dijkstra, 4 neighbors");
|
||||||
|
long startTime = System.nanoTime();
|
||||||
|
Map<Point, Double> dijkstra4 = run(seed, maxit, quad, graph);
|
||||||
|
startTime = System.nanoTime() - startTime;
|
||||||
|
double duration = ((double)startTime / 1000000000);
|
||||||
|
System.out.println("solution Time : " + new DecimalFormat("#.##########").format(duration) + " Seconds");
|
||||||
|
printGrid(dijkstra4, pMin, pMax, step, null);
|
||||||
|
|
||||||
|
System.out.println("Dijkstra, 8 neighbors");
|
||||||
|
startTime = System.nanoTime();
|
||||||
|
Map<Point, Double> dijkstra8 = run(seed, maxit, octo, graph);
|
||||||
|
startTime = System.nanoTime() - startTime;
|
||||||
|
duration = ((double)startTime / 1000000000);
|
||||||
|
System.out.println("solution Time : " + new DecimalFormat("#.##########").format(duration) + " Seconds");
|
||||||
|
printGrid(dijkstra8, pMin, pMax, step, null);
|
||||||
|
|
||||||
|
System.out.println("Fast marching, 4 neighbors");
|
||||||
|
startTime = System.nanoTime();
|
||||||
|
Map<Point, Double> fast_marching4 = run(seed, maxit, quad, mesh);
|
||||||
|
startTime = System.nanoTime() - startTime;
|
||||||
|
duration = ((double)startTime / 1000000000);
|
||||||
|
System.out.println("solution Time : " + new DecimalFormat("#.##########").format(duration) + " Seconds");
|
||||||
|
printGrid(fast_marching4, pMin, pMax, step, null);
|
||||||
|
|
||||||
|
|
||||||
|
System.out.println("Fast marching, 8 neighbors");
|
||||||
|
startTime = System.nanoTime();
|
||||||
|
Map<Point, Double> fast_marching8 = run(seed, maxit, octo, mesh);
|
||||||
|
startTime = System.nanoTime() - startTime;
|
||||||
|
duration = ((double)startTime / 1000000000);
|
||||||
|
System.out.println("solution Time : " + new DecimalFormat("#.##########").format(duration) + " Seconds");
|
||||||
|
printGrid(fast_marching8, pMin, pMax, step, null);*/
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
35
java/crtp/Neighborhood.java
Normal file
35
java/crtp/Neighborhood.java
Normal file
|
|
@ -0,0 +1,35 @@
|
||||||
|
package patterns.crtp;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.concurrent.Callable;
|
||||||
|
import java.util.function.Function;
|
||||||
|
|
||||||
|
import patterns.Point;
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author pouyllau
|
||||||
|
*
|
||||||
|
* @param <T>
|
||||||
|
*/
|
||||||
|
public class Neighborhood<T extends Neighborhood<T>> {
|
||||||
|
|
||||||
|
protected static double step;
|
||||||
|
protected static Point pMin;
|
||||||
|
protected static Point pMax;
|
||||||
|
T t;
|
||||||
|
|
||||||
|
public Neighborhood(double step, Point pMin, Point pMax) {
|
||||||
|
super();
|
||||||
|
this.step = step;
|
||||||
|
this.pMin = pMin;
|
||||||
|
this.pMax = pMax;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<Point> get(Point p) {
|
||||||
|
return t.get(p);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
25
java/crtp/OctoGrid.java
Normal file
25
java/crtp/OctoGrid.java
Normal file
|
|
@ -0,0 +1,25 @@
|
||||||
|
package patterns.crtp;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import patterns.Point;
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author pouyllau
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class OctoGrid extends Neighborhood<OctoGrid> {
|
||||||
|
|
||||||
|
public OctoGrid(double step, Point pMin, Point pMax) {
|
||||||
|
super(step, pMin, pMax);
|
||||||
|
this.t = this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<Point> get(Point p) {
|
||||||
|
return Point.neighbors_grid(p, step, pMin, pMax,
|
||||||
|
Arrays.asList(new Point(1, 0), new Point(1, -1), new Point(0, -1), new Point(-1, -1), new Point(-1, 0),
|
||||||
|
new Point(-1, 1), new Point(0, 1), new Point(1, 1)));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
25
java/crtp/QuadGrid.java
Normal file
25
java/crtp/QuadGrid.java
Normal file
|
|
@ -0,0 +1,25 @@
|
||||||
|
package patterns.crtp;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import patterns.Point;
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author pouyllau
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class QuadGrid extends Neighborhood<QuadGrid> {
|
||||||
|
|
||||||
|
public QuadGrid(double step, Point pMin, Point pMax) {
|
||||||
|
super(step, pMin, pMax);
|
||||||
|
this.t = this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<Point> get(Point p) {
|
||||||
|
return Point.neighbors_grid(p, step, pMin, pMax,
|
||||||
|
Arrays.asList(new Point(1, 0), new Point(0, -1), new Point(-1, 0), new Point(0, 1)));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
25
java/crtp/Transit.java
Normal file
25
java/crtp/Transit.java
Normal file
|
|
@ -0,0 +1,25 @@
|
||||||
|
package patterns.crtp;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import patterns.Point;
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author pouyllau
|
||||||
|
*
|
||||||
|
* @param <T>
|
||||||
|
*/
|
||||||
|
public class Transit<T extends Transit<T>> {
|
||||||
|
|
||||||
|
T t;
|
||||||
|
|
||||||
|
|
||||||
|
public double transit(Point p, List<Point> neighbors, Map<Point, Double> costs) {
|
||||||
|
return t.transit(p, neighbors, costs);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean hasCost(Point p ,Map<Point, Double> costs) {
|
||||||
|
return (costs.get(p) != null && costs.get(p) != Double.POSITIVE_INFINITY);
|
||||||
|
}
|
||||||
|
}
|
||||||
83
java/crtp/TransitInSimplex.java
Normal file
83
java/crtp/TransitInSimplex.java
Normal file
|
|
@ -0,0 +1,83 @@
|
||||||
|
package patterns.crtp;
|
||||||
|
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
import patterns.Point;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Find the transit in minimal cost within the given simplexes.
|
||||||
|
*
|
||||||
|
* That is, find the minimal distance between the given point and one of the
|
||||||
|
* edges formed by the sequence of pairs of neighbors. Neighbors should thus be
|
||||||
|
* given in clockwise order. The minimal transit is searched across 1/eps
|
||||||
|
* distances, regularly spaced on each edge.
|
||||||
|
*
|
||||||
|
* @author pouyllau
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class TransitInSimplex extends Transit<TransitInSimplex> {
|
||||||
|
|
||||||
|
protected double eps;
|
||||||
|
|
||||||
|
|
||||||
|
public TransitInSimplex(double eps) {
|
||||||
|
super();
|
||||||
|
this.t = this;
|
||||||
|
this.eps = eps;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public double transit(Point p, List<Point> neighbors, Map<Point, Double> costs) {
|
||||||
|
|
||||||
|
double mincost = Double.MAX_VALUE;
|
||||||
|
List<Point> list = neighbors.stream().filter(n -> hasCost(n, costs)).collect(Collectors.toList());
|
||||||
|
int k = list.size();
|
||||||
|
if (k == 1) {
|
||||||
|
mincost = costs.get(list.get(0))+ Point.distance(list.get(0), p);
|
||||||
|
} else {
|
||||||
|
for (int i = 0; i < neighbors.size(); i++) {
|
||||||
|
Point pj = neighbors.get(i);
|
||||||
|
Point pk = (i+1 < neighbors.size() ? neighbors.get(i+1) : neighbors.get(0));
|
||||||
|
double c = 0;
|
||||||
|
|
||||||
|
if (hasCost(pj, costs) && hasCost(pk, costs)) {
|
||||||
|
// Cost of the transition from/to p from/to edge e.
|
||||||
|
// This is the simplest way to minimize the transit, even if
|
||||||
|
// not the most efficient.
|
||||||
|
for (double z = 0; z <= 1; z += eps) {
|
||||||
|
double zx = z * pj.x + (1 - z) * pk.x;
|
||||||
|
double zy = z * pj.y + (1 - z) * pk.y;
|
||||||
|
|
||||||
|
// Linear interpolation of costs.
|
||||||
|
c = z *costs.get(pj) + (1 - z) * costs.get(pk)+ Point.distance(p, new Point(zx, zy));
|
||||||
|
if (c < mincost) {
|
||||||
|
mincost = c;
|
||||||
|
}
|
||||||
|
} // for z
|
||||||
|
|
||||||
|
// If the front is reached on a single point.
|
||||||
|
} else if (hasCost(pj, costs) && !hasCost(pk, costs)) {
|
||||||
|
c = costs.get(pj)+ Point.distance(p, pj);
|
||||||
|
if (c < mincost) {
|
||||||
|
mincost = c;
|
||||||
|
}
|
||||||
|
} else if (!hasCost(pj, costs) && hasCost(pk, costs)) {
|
||||||
|
c = costs.get(pk) + Point.distance(p, pk);
|
||||||
|
if (c < mincost) {
|
||||||
|
mincost = c;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
assert (mincost < Double.POSITIVE_INFINITY);
|
||||||
|
return mincost;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
35
java/crtp/TransitOnEdge.java
Normal file
35
java/crtp/TransitOnEdge.java
Normal file
|
|
@ -0,0 +1,35 @@
|
||||||
|
package patterns.crtp;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import patterns.Point;
|
||||||
|
|
||||||
|
/** Find the transit of minimal cost among the given edges.
|
||||||
|
|
||||||
|
Edges are given as the considered point and the sequence of neighbors points.
|
||||||
|
* @author pouyllau
|
||||||
|
*
|
||||||
|
* */
|
||||||
|
public class TransitOnEdge extends Transit<TransitOnEdge>{
|
||||||
|
|
||||||
|
public TransitOnEdge() {
|
||||||
|
super();
|
||||||
|
this.t = this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public double transit(Point p, List<Point> neighbors, Map<Point, Double> costs) {
|
||||||
|
double mincost = Double.POSITIVE_INFINITY;
|
||||||
|
|
||||||
|
for (Point n : neighbors) {
|
||||||
|
if (hasCost(n, costs)) {
|
||||||
|
double c = costs.get(n) + Point.distance(p, n);
|
||||||
|
if (c < mincost) {
|
||||||
|
mincost = c;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
assert (mincost != Double.POSITIVE_INFINITY);
|
||||||
|
return mincost;
|
||||||
|
}
|
||||||
|
}
|
||||||
171
java/functionnal/Algo.java
Normal file
171
java/functionnal/Algo.java
Normal file
|
|
@ -0,0 +1,171 @@
|
||||||
|
package patterns.functionnal;
|
||||||
|
|
||||||
|
import java.text.DecimalFormat;
|
||||||
|
import java.text.SimpleDateFormat;
|
||||||
|
import java.util.Comparator;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Locale;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.PriorityQueue;
|
||||||
|
|
||||||
|
import patterns.Point;
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author pouyllau
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class Algo {
|
||||||
|
|
||||||
|
private static boolean DEBUG = false;
|
||||||
|
|
||||||
|
public static Map<Point, Double> run(Point seed, int iterations, Neighborhood neighborhood, Transit transit) {
|
||||||
|
Map<Point, Double> costs = new HashMap<Point, Double>();
|
||||||
|
|
||||||
|
PriorityQueue<Point> front = new PriorityQueue<Point>(new Comparator<Point>() {
|
||||||
|
public int compare(Point lhs, Point rhs) {
|
||||||
|
if (costs.get(lhs) >= costs.get(rhs))
|
||||||
|
return +1;
|
||||||
|
if (costs.get(lhs) < costs.get(rhs))
|
||||||
|
return -1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
costs.put(seed, 0.);
|
||||||
|
front.add(seed);
|
||||||
|
|
||||||
|
for (int i = 0; i < iterations && !front.isEmpty(); i++) {
|
||||||
|
if (DEBUG)
|
||||||
|
System.out.println(i + "/" + iterations);
|
||||||
|
|
||||||
|
// Accept the node with the min cost and update neighbors.
|
||||||
|
// Accept the considered node with the min cost.
|
||||||
|
Point accepted = front.poll();
|
||||||
|
|
||||||
|
// Consider neighbors of the accepted node.
|
||||||
|
List<Point> around = neighborhood.get(accepted);
|
||||||
|
assert (around.size() > 0);
|
||||||
|
|
||||||
|
for (Point n : around) {
|
||||||
|
// If no cost has been computed (i.e. the node is "open").
|
||||||
|
if (!Transit.hasCost(n, costs)) {
|
||||||
|
|
||||||
|
double ncost = transit.transit(n, neighborhood.get(n), costs);
|
||||||
|
if (DEBUG)
|
||||||
|
System.out.println(n + " cost=" + ncost);
|
||||||
|
costs.put(n, ncost);
|
||||||
|
front.add(n);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return costs;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void printGrid(Map<Point, Double> grid, Point pMin, Point pMax, double step, String sep) {
|
||||||
|
if (sep == null)
|
||||||
|
sep = "\t";
|
||||||
|
String width = " ";
|
||||||
|
System.out.print(" x:"+sep);
|
||||||
|
|
||||||
|
for (double px = pMin.x; px <= pMax.x; px += step) {
|
||||||
|
System.out.print(sep + (int)px+ " "+ width );
|
||||||
|
}
|
||||||
|
|
||||||
|
System.out.print("\n");
|
||||||
|
System.out.print(" y\n");
|
||||||
|
|
||||||
|
for (double py = pMax.y; py >= pMin.y; py -= step) {
|
||||||
|
System.out.print(sep + (int)py + ":");
|
||||||
|
for (double px = pMin.x; px <= pMax.x; px += step) {
|
||||||
|
Point p = new Point(px, py);
|
||||||
|
if (Transit.hasCost(p, grid)) {
|
||||||
|
System.out.format(sep + "%.2f" + width, grid.get(p));
|
||||||
|
} else {
|
||||||
|
System.out.print(sep + " . " + width);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
System.out.print("\n");
|
||||||
|
}
|
||||||
|
System.out.print("\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void performEvaluations(Point seed, int iterations, Neighborhood neighborhood, Transit transit, int T) {
|
||||||
|
double mean = 0;
|
||||||
|
double m2 = 0;
|
||||||
|
for (int t = 0; t < T; t++) {
|
||||||
|
long startTime = System.nanoTime();
|
||||||
|
run(seed, iterations, neighborhood, transit);
|
||||||
|
startTime = System.nanoTime() - startTime;
|
||||||
|
double delta = (double)startTime - mean;
|
||||||
|
mean += delta / (double) T;
|
||||||
|
m2 += delta * delta;
|
||||||
|
}
|
||||||
|
m2 = m2 / (double)(T-1.);
|
||||||
|
m2 = Math.sqrt(m2);
|
||||||
|
System.out.println("Mean time : " + new DecimalFormat("#.##########").format((mean / 1000000000)) + " s"
|
||||||
|
+ " sd : " + new DecimalFormat("#.##########").format((m2 / 1000000000)));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
Locale.setDefault(Locale.US);
|
||||||
|
Point seed = new Point(0, 0);
|
||||||
|
Point pMin = new Point(-5, -5);
|
||||||
|
Point pMax = new Point(15, 15);
|
||||||
|
double step = 1.;
|
||||||
|
int maxit = 300;
|
||||||
|
double eps = 1. / 100.0;
|
||||||
|
int eval = 100;
|
||||||
|
|
||||||
|
Neighborhood quad= new Neighborhood(Neighborhood.quad(), step, pMin, pMax);
|
||||||
|
Neighborhood octo = new Neighborhood(Neighborhood.octo(), step, pMin, pMax);
|
||||||
|
|
||||||
|
Transit graph = new Transit(Transit.edge());
|
||||||
|
Transit mesh = new Transit(Transit.simplex(eps));
|
||||||
|
|
||||||
|
|
||||||
|
System.out.println("Dijkstra, 4 neighbors");
|
||||||
|
performEvaluations(seed, maxit, quad, graph, eval);
|
||||||
|
System.out.println("Dijkstra, 8 neighbors");
|
||||||
|
performEvaluations(seed, maxit, octo, graph, eval);
|
||||||
|
System.out.println("Fast marching, 4 neighbors");
|
||||||
|
performEvaluations(seed, maxit, quad, mesh, eval);
|
||||||
|
System.out.println("Fast marching, 8 neighbors");
|
||||||
|
performEvaluations(seed, maxit, octo, mesh, eval);
|
||||||
|
/*
|
||||||
|
System.out.println("Dijkstra, 4 neighbors");
|
||||||
|
long startTime = System.nanoTime();
|
||||||
|
Map<Point, Double> dijkstra4 = run(seed, maxit, quadCrtp, graph);
|
||||||
|
startTime = System.nanoTime() - startTime;
|
||||||
|
double duration = ((double)startTime / 1000000000);
|
||||||
|
System.out.println("solution Time : " + new DecimalFormat("#.##########").format(duration) + " Seconds");
|
||||||
|
printGrid(dijkstra4, pMin, pMax, step, null);
|
||||||
|
|
||||||
|
System.out.println("Dijkstra, 8 neighbors");
|
||||||
|
startTime = System.nanoTime();
|
||||||
|
Map<Point, Double> dijkstra8 = run(seed, maxit, octoCrtp, graph);
|
||||||
|
startTime = System.nanoTime() - startTime;
|
||||||
|
duration = ((double)startTime / 1000000000);
|
||||||
|
System.out.println("solution Time : " + new DecimalFormat("#.##########").format(duration) + " Seconds");
|
||||||
|
printGrid(dijkstra8, pMin, pMax, step, null);
|
||||||
|
|
||||||
|
System.out.println("Fast marching, 4 neighbors");
|
||||||
|
startTime = System.nanoTime();
|
||||||
|
Map<Point, Double> fast_marching4 = run(seed, maxit, quadCrtp, mesh);
|
||||||
|
startTime = System.nanoTime() - startTime;
|
||||||
|
duration = ((double)startTime / 1000000000);
|
||||||
|
System.out.println("solution Time : " + new DecimalFormat("#.##########").format(duration) + " Seconds");
|
||||||
|
printGrid(fast_marching4, pMin, pMax, step, null);
|
||||||
|
|
||||||
|
|
||||||
|
System.out.println("Fast marching, 8 neighbors");
|
||||||
|
startTime = System.nanoTime();
|
||||||
|
Map<Point, Double> fast_marching8 = run(seed, maxit, octoCrtp, mesh);
|
||||||
|
startTime = System.nanoTime() - startTime;
|
||||||
|
duration = ((double)startTime / 1000000000);
|
||||||
|
System.out.println("solution Time : " + new DecimalFormat("#.##########").format(duration) + " Seconds");
|
||||||
|
printGrid(fast_marching8, pMin, pMax, step, null);*/
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
43
java/functionnal/Neighborhood.java
Normal file
43
java/functionnal/Neighborhood.java
Normal file
|
|
@ -0,0 +1,43 @@
|
||||||
|
package patterns.functionnal;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.concurrent.Callable;
|
||||||
|
import java.util.function.Function;
|
||||||
|
|
||||||
|
import patterns.Point;
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author pouyllau
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class Neighborhood {
|
||||||
|
|
||||||
|
protected static double step;
|
||||||
|
protected static Point pMin;
|
||||||
|
protected static Point pMax;
|
||||||
|
Function<Point, List<Point>> f;
|
||||||
|
|
||||||
|
public Neighborhood(Function<Point, List<Point>> f,double step, Point pMin, Point pMax) {
|
||||||
|
super();
|
||||||
|
this.f = f;
|
||||||
|
this.step = step;
|
||||||
|
this.pMin = pMin;
|
||||||
|
this.pMax = pMax;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<Point> get( Point p) {
|
||||||
|
return f.apply(p);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Function<Point, List<Point>> quad() {
|
||||||
|
return x -> Point.neighbors_grid(x, step, pMin, pMax,
|
||||||
|
Arrays.asList(new Point(1, 0), new Point(0, -1), new Point(-1, 0), new Point(0, 1)));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Function<Point, List<Point>> octo() {
|
||||||
|
return x -> Point.neighbors_grid(x, step, pMin, pMax,Arrays.asList(new Point(1, 0), new Point(1, -1), new Point(0, -1), new Point(-1, -1),
|
||||||
|
new Point(-1, 0), new Point(-1, 1), new Point(0, 1), new Point(1, 1)));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
104
java/functionnal/Transit.java
Normal file
104
java/functionnal/Transit.java
Normal file
|
|
@ -0,0 +1,104 @@
|
||||||
|
package patterns.functionnal;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.function.Function;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
import patterns.Point;
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author pouyllau
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class Transit {
|
||||||
|
|
||||||
|
public static boolean hasCost(Point p ,Map<Point, Double> costs) {
|
||||||
|
return (costs.get(p) != null && costs.get(p) != Double.POSITIVE_INFINITY);
|
||||||
|
}
|
||||||
|
|
||||||
|
TriFunction<Point, List<Point>, Map<Point, Double>, Double> f;
|
||||||
|
|
||||||
|
|
||||||
|
public Transit(TriFunction<Point, List<Point>, Map<Point, Double>, Double> f) {
|
||||||
|
super();
|
||||||
|
this.f = f;
|
||||||
|
}
|
||||||
|
|
||||||
|
public double transit(Point p, List<Point> neighbors, Map<Point, Double> costs) {
|
||||||
|
return f.apply(p,neighbors,costs);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static TriFunction<Point, List<Point>, Map<Point, Double>, Double> simplex(double eps) {
|
||||||
|
return (x, y, z) -> transitInSimplex(x,y,z, eps);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static TriFunction<Point, List<Point>, Map<Point, Double>, Double> edge() {
|
||||||
|
return (x, y, z) -> transitOnEdge(x,y,z);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static double transitOnEdge(Point p, List<Point> neighbors, Map<Point, Double> costs) {
|
||||||
|
double mincost = Double.POSITIVE_INFINITY;
|
||||||
|
|
||||||
|
for (Point n : neighbors) {
|
||||||
|
if (hasCost(n, costs)) {
|
||||||
|
double c = costs.get(n) + Point.distance(p, n);
|
||||||
|
if (c < mincost) {
|
||||||
|
mincost = c;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
assert (mincost != Double.POSITIVE_INFINITY);
|
||||||
|
return mincost;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static double transitInSimplex(Point p, List<Point> neighbors, Map<Point, Double> costs, double eps) {
|
||||||
|
|
||||||
|
double mincost = Double.MAX_VALUE;
|
||||||
|
List<Point> list = neighbors.stream().filter(n -> hasCost(n, costs)).collect(Collectors.toList());
|
||||||
|
int k = list.size();
|
||||||
|
if (k == 1) {
|
||||||
|
mincost = costs.get(list.get(0))+ Point.distance(list.get(0), p);
|
||||||
|
} else {
|
||||||
|
for (int i = 0; i < neighbors.size(); i++) {
|
||||||
|
Point pj = neighbors.get(i);
|
||||||
|
Point pk = (i+1 < neighbors.size() ? neighbors.get(i+1) : neighbors.get(0));
|
||||||
|
double c = 0;
|
||||||
|
|
||||||
|
if (hasCost(pj, costs) && hasCost(pk, costs)) {
|
||||||
|
// Cost of the transition from/to p from/to edge e.
|
||||||
|
// This is the simplest way to minimize the transit, even if
|
||||||
|
// not the most efficient.
|
||||||
|
for (double z = 0; z <= 1; z += eps) {
|
||||||
|
double zx = z * pj.x + (1 - z) * pk.x;
|
||||||
|
double zy = z * pj.y + (1 - z) * pk.y;
|
||||||
|
|
||||||
|
// Linear interpolation of costs.
|
||||||
|
c = z *costs.get(pj) + (1 - z) * costs.get(pk)+ Point.distance(p, new Point(zx, zy));
|
||||||
|
if (c < mincost) {
|
||||||
|
mincost = c;
|
||||||
|
}
|
||||||
|
} // for z
|
||||||
|
|
||||||
|
// If the front is reached on a single point.
|
||||||
|
} else if (hasCost(pj, costs) && !hasCost(pk, costs)) {
|
||||||
|
c = costs.get(pj)+ Point.distance(p, pj);
|
||||||
|
if (c < mincost) {
|
||||||
|
mincost = c;
|
||||||
|
}
|
||||||
|
} else if (!hasCost(pj, costs) && hasCost(pk, costs)) {
|
||||||
|
c = costs.get(pk) + Point.distance(p, pk);
|
||||||
|
if (c < mincost) {
|
||||||
|
mincost = c;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
assert (mincost < Double.POSITIVE_INFINITY);
|
||||||
|
return mincost;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
20
java/functionnal/TriFunction.java
Normal file
20
java/functionnal/TriFunction.java
Normal file
|
|
@ -0,0 +1,20 @@
|
||||||
|
package patterns.functionnal;
|
||||||
|
|
||||||
|
import java.util.Objects;
|
||||||
|
import java.util.function.Function;
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author pouyllau
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
@FunctionalInterface
|
||||||
|
public interface TriFunction<A,B,C,R> {
|
||||||
|
|
||||||
|
R apply(A a, B b, C c);
|
||||||
|
|
||||||
|
default <V> TriFunction<A, B, C, V> andThen(
|
||||||
|
Function<? super R, ? extends V> after) {
|
||||||
|
Objects.requireNonNull(after);
|
||||||
|
return (A a, B b, C c) -> after.apply(apply(a, b, c));
|
||||||
|
}
|
||||||
|
}
|
||||||
172
java/strategy/Algo.java
Normal file
172
java/strategy/Algo.java
Normal file
|
|
@ -0,0 +1,172 @@
|
||||||
|
package patterns.strategy;
|
||||||
|
|
||||||
|
import java.io.StreamTokenizer;
|
||||||
|
import java.text.DecimalFormat;
|
||||||
|
import java.text.SimpleDateFormat;
|
||||||
|
import java.util.Comparator;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Locale;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.PriorityQueue;
|
||||||
|
|
||||||
|
import patterns.Point;
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author pouyllau
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class Algo {
|
||||||
|
|
||||||
|
private static boolean DEBUG = false;
|
||||||
|
|
||||||
|
public static Map<Point, Double> run(Point seed, int iterations, Neighborhood neighborhood, Transit transit) {
|
||||||
|
Map<Point, Double> costs = new HashMap<Point, Double>();
|
||||||
|
|
||||||
|
PriorityQueue<Point> front = new PriorityQueue<Point>(new Comparator<Point>() {
|
||||||
|
public int compare(Point lhs, Point rhs) {
|
||||||
|
if (costs.get(lhs) >= costs.get(rhs))
|
||||||
|
return +1;
|
||||||
|
if (costs.get(lhs) < costs.get(rhs))
|
||||||
|
return -1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
costs.put(seed, 0.);
|
||||||
|
front.add(seed);
|
||||||
|
|
||||||
|
for (int i = 0; i < iterations && !front.isEmpty(); i++) {
|
||||||
|
if (DEBUG)
|
||||||
|
System.out.println(i + "/" + iterations);
|
||||||
|
|
||||||
|
// Accept the node with the min cost and update neighbors.
|
||||||
|
// Accept the considered node with the min cost.
|
||||||
|
Point accepted = front.poll();
|
||||||
|
|
||||||
|
// Consider neighbors of the accepted node.
|
||||||
|
List<Point> around = neighborhood.get(accepted);
|
||||||
|
assert (around.size() > 0);
|
||||||
|
|
||||||
|
for (Point n : around) {
|
||||||
|
// If no cost has been computed (i.e. the node is "open").
|
||||||
|
if (!Transit.hasCost(n, costs)) {
|
||||||
|
|
||||||
|
double ncost = transit.transit(n, neighborhood.get(n), costs);
|
||||||
|
if (DEBUG)
|
||||||
|
System.out.println(n + " cost=" + ncost);
|
||||||
|
costs.put(n, ncost);
|
||||||
|
front.add(n);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return costs;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void printGrid(Map<Point, Double> grid, Point pMin, Point pMax, double step, String sep) {
|
||||||
|
if (sep == null)
|
||||||
|
sep = "\t";
|
||||||
|
String width = " ";
|
||||||
|
System.out.print(" x:" + sep);
|
||||||
|
|
||||||
|
for (double px = pMin.x; px <= pMax.x; px += step) {
|
||||||
|
System.out.print(sep + (int) px + " " + width);
|
||||||
|
}
|
||||||
|
|
||||||
|
System.out.print("\n");
|
||||||
|
System.out.print(" y\n");
|
||||||
|
|
||||||
|
for (double py = pMax.y; py >= pMin.y; py -= step) {
|
||||||
|
System.out.print(sep + (int) py + ":");
|
||||||
|
for (double px = pMin.x; px <= pMax.x; px += step) {
|
||||||
|
Point p = new Point(px, py);
|
||||||
|
if (Transit.hasCost(p, grid)) {
|
||||||
|
System.out.format(sep + "%.2f" + width, grid.get(p));
|
||||||
|
} else {
|
||||||
|
System.out.print(sep + " . " + width);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
System.out.print("\n");
|
||||||
|
}
|
||||||
|
System.out.print("\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void performEvaluations(Point seed, int iterations, Neighborhood neighborhood, Transit transit,
|
||||||
|
int T) {
|
||||||
|
double mean = 0;
|
||||||
|
double m2 = 0;
|
||||||
|
for (int t = 0; t < T; t++) {
|
||||||
|
long startTime = System.nanoTime();
|
||||||
|
run(seed, iterations, neighborhood, transit);
|
||||||
|
startTime = System.nanoTime() - startTime;
|
||||||
|
double delta = (double)startTime - mean;
|
||||||
|
mean += delta / (double) T;
|
||||||
|
m2 += delta * delta;
|
||||||
|
}
|
||||||
|
m2 = m2 / (double)(T-1.);
|
||||||
|
m2 = Math.sqrt(m2);
|
||||||
|
System.out.println("Mean time : " + new DecimalFormat("#.##########").format((mean / 1000000000)) + " s"
|
||||||
|
+ " sd : " + new DecimalFormat("#.##########").format((m2 / 1000000000)));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
Locale.setDefault(Locale.US);
|
||||||
|
Point seed = new Point(0, 0);
|
||||||
|
Point pMin = new Point(-5, -5);
|
||||||
|
Point pMax = new Point(15, 15);
|
||||||
|
double step = 1.;
|
||||||
|
int maxit = 300;
|
||||||
|
double eps = 1. / 100.0;
|
||||||
|
int eval = 100;
|
||||||
|
|
||||||
|
Neighborhood quad = new patterns.strategy.QuadGrid(step, pMin, pMax);
|
||||||
|
Neighborhood octo = new patterns.strategy.OctoGrid(step, pMin, pMax);
|
||||||
|
|
||||||
|
Transit graph = new TransitOnEdge();
|
||||||
|
Transit mesh = new TransitInSimplex(eps);
|
||||||
|
|
||||||
|
System.out.println("Dijkstra, 4 neighbors");
|
||||||
|
performEvaluations(seed, maxit, quad, graph, eval);
|
||||||
|
System.out.println("Dijkstra, 8 neighbors");
|
||||||
|
performEvaluations(seed, maxit, octo, graph, eval);
|
||||||
|
System.out.println("Fast marching, 4 neighbors");
|
||||||
|
performEvaluations(seed, maxit, quad, mesh, eval);
|
||||||
|
System.out.println("Fast marching, 8 neighbors");
|
||||||
|
performEvaluations(seed, maxit, octo, mesh, eval);
|
||||||
|
/*
|
||||||
|
System.out.println("Dijkstra, 4 neighbors");
|
||||||
|
long startTime = System.nanoTime();
|
||||||
|
Map<Point, Double> dijkstra4 = run(seed, maxit, quad, graph);
|
||||||
|
startTime = System.nanoTime() - startTime;
|
||||||
|
double duration = ((double)startTime / 1000000000);
|
||||||
|
System.out.println("solution Time : " + new DecimalFormat("#.##########").format(duration) + " Seconds");
|
||||||
|
printGrid(dijkstra4, pMin, pMax, step, null);
|
||||||
|
|
||||||
|
System.out.println("Dijkstra, 8 neighbors");
|
||||||
|
startTime = System.nanoTime();
|
||||||
|
Map<Point, Double> dijkstra8 = run(seed, maxit, octo, graph);
|
||||||
|
startTime = System.nanoTime() - startTime;
|
||||||
|
duration = ((double)startTime / 1000000000);
|
||||||
|
System.out.println("solution Time : " + new DecimalFormat("#.##########").format(duration) + " Seconds");
|
||||||
|
printGrid(dijkstra8, pMin, pMax, step, null);
|
||||||
|
|
||||||
|
System.out.println("Fast marching, 4 neighbors");
|
||||||
|
startTime = System.nanoTime();
|
||||||
|
Map<Point, Double> fast_marching4 = run(seed, maxit, quad, mesh);
|
||||||
|
startTime = System.nanoTime() - startTime;
|
||||||
|
duration = ((double)startTime / 1000000000);
|
||||||
|
System.out.println("solution Time : " + new DecimalFormat("#.##########").format(duration) + " Seconds");
|
||||||
|
printGrid(fast_marching4, pMin, pMax, step, null);
|
||||||
|
|
||||||
|
|
||||||
|
System.out.println("Fast marching, 8 neighbors");
|
||||||
|
startTime = System.nanoTime();
|
||||||
|
Map<Point, Double> fast_marching8 = run(seed, maxit, octo, mesh);
|
||||||
|
startTime = System.nanoTime() - startTime;
|
||||||
|
duration = ((double)startTime / 1000000000);
|
||||||
|
System.out.println("solution Time : " + new DecimalFormat("#.##########").format(duration) + " Seconds");
|
||||||
|
printGrid(fast_marching8, pMin, pMax, step, null);
|
||||||
|
*/
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
27
java/strategy/Neighborhood.java
Normal file
27
java/strategy/Neighborhood.java
Normal file
|
|
@ -0,0 +1,27 @@
|
||||||
|
package patterns.strategy;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import patterns.Point;
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author pouyllau
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public abstract class Neighborhood {
|
||||||
|
protected double step;
|
||||||
|
protected Point pMin;
|
||||||
|
protected Point pMax;
|
||||||
|
protected List<Point> directions;
|
||||||
|
|
||||||
|
|
||||||
|
public Neighborhood(double step, Point pMin, Point pMax) {
|
||||||
|
super();
|
||||||
|
this.step = step;
|
||||||
|
this.pMin = pMin;
|
||||||
|
this.pMax = pMax;
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract List<Point> get(Point p);
|
||||||
|
|
||||||
|
}
|
||||||
24
java/strategy/OctoGrid.java
Normal file
24
java/strategy/OctoGrid.java
Normal file
|
|
@ -0,0 +1,24 @@
|
||||||
|
package patterns.strategy;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import patterns.Point;
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author pouyllau
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class OctoGrid extends Neighborhood {
|
||||||
|
|
||||||
|
public OctoGrid(double step, Point pMin, Point pMax) {
|
||||||
|
super(step, pMin, pMax);
|
||||||
|
this.directions = Arrays.asList(new Point(1, 0), new Point(1, -1), new Point(0, -1), new Point(-1, -1),
|
||||||
|
new Point(-1, 0), new Point(-1, 1), new Point(0, 1), new Point(1, 1));
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<Point> get(Point p) {
|
||||||
|
|
||||||
|
return Point.neighbors_grid(p, step,pMin, pMax, directions);
|
||||||
|
}
|
||||||
|
}
|
||||||
24
java/strategy/QuadGrid.java
Normal file
24
java/strategy/QuadGrid.java
Normal file
|
|
@ -0,0 +1,24 @@
|
||||||
|
package patterns.strategy;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import patterns.Point;
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author pouyllau
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class QuadGrid extends Neighborhood {
|
||||||
|
|
||||||
|
public QuadGrid(double step, Point pMin, Point pMax) {
|
||||||
|
super(step, pMin, pMax);
|
||||||
|
this.directions = Arrays.asList(new Point(1,0), new Point (0,-1), new Point(-1,0), new Point(0,1));
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<Point> get(Point p) {
|
||||||
|
return Point.neighbors_grid(p, step,pMin, pMax, directions);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
19
java/strategy/Transit.java
Normal file
19
java/strategy/Transit.java
Normal file
|
|
@ -0,0 +1,19 @@
|
||||||
|
package patterns.strategy;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import patterns.Point;
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author pouyllau
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public abstract class Transit {
|
||||||
|
|
||||||
|
public abstract double transit(Point p, List<Point> neighbors, Map<Point, Double> costs);
|
||||||
|
|
||||||
|
public static boolean hasCost(Point p ,Map<Point, Double> costs) {
|
||||||
|
return (costs.get(p) != null && costs.get(p) != Double.POSITIVE_INFINITY);
|
||||||
|
}
|
||||||
|
}
|
||||||
80
java/strategy/TransitInSimplex.java
Normal file
80
java/strategy/TransitInSimplex.java
Normal file
|
|
@ -0,0 +1,80 @@
|
||||||
|
package patterns.strategy;
|
||||||
|
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
import patterns.Point;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Find the transit in minimal cost within the given simplexes.
|
||||||
|
*
|
||||||
|
* That is, find the minimal distance between the given point and one of the
|
||||||
|
* edges formed by the sequence of pairs of neighbors. Neighbors should thus be
|
||||||
|
* given in clockwise order. The minimal transit is searched across 1/eps
|
||||||
|
* distances, regularly spaced on each edge.
|
||||||
|
* @author pouyllau
|
||||||
|
*/
|
||||||
|
public class TransitInSimplex extends Transit {
|
||||||
|
|
||||||
|
protected double eps;
|
||||||
|
|
||||||
|
|
||||||
|
public TransitInSimplex(double eps) {
|
||||||
|
super();
|
||||||
|
this.eps = eps;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public double transit(Point p, List<Point> neighbors, Map<Point, Double> costs) {
|
||||||
|
|
||||||
|
double mincost = Double.MAX_VALUE;
|
||||||
|
List<Point> list = neighbors.stream().filter(n -> hasCost(n, costs)).collect(Collectors.toList());
|
||||||
|
int k = list.size();
|
||||||
|
if (k == 1) {
|
||||||
|
mincost = costs.get(list.get(0))+ Point.distance(list.get(0), p);
|
||||||
|
} else {
|
||||||
|
for (int i = 0; i < neighbors.size(); i++) {
|
||||||
|
Point pj = neighbors.get(i);
|
||||||
|
Point pk = (i+1 < neighbors.size() ? neighbors.get(i+1) : neighbors.get(0));
|
||||||
|
double c = 0;
|
||||||
|
|
||||||
|
if (hasCost(pj, costs) && hasCost(pk, costs)) {
|
||||||
|
// Cost of the transition from/to p from/to edge e.
|
||||||
|
// This is the simplest way to minimize the transit, even if
|
||||||
|
// not the most efficient.
|
||||||
|
for (double z = 0; z <= 1; z += eps) {
|
||||||
|
double zx = z * pj.x + (1 - z) * pk.x;
|
||||||
|
double zy = z * pj.y + (1 - z) * pk.y;
|
||||||
|
|
||||||
|
// Linear interpolation of costs.
|
||||||
|
c = z *costs.get(pj) + (1 - z) * costs.get(pk)+ Point.distance(p, new Point(zx, zy));
|
||||||
|
if (c < mincost) {
|
||||||
|
mincost = c;
|
||||||
|
}
|
||||||
|
} // for z
|
||||||
|
|
||||||
|
// If the front is reached on a single point.
|
||||||
|
} else if (hasCost(pj, costs) && !hasCost(pk, costs)) {
|
||||||
|
c = costs.get(pj)+ Point.distance(p, pj);
|
||||||
|
if (c < mincost) {
|
||||||
|
mincost = c;
|
||||||
|
}
|
||||||
|
} else if (!hasCost(pj, costs) && hasCost(pk, costs)) {
|
||||||
|
c = costs.get(pk) + Point.distance(p, pk);
|
||||||
|
if (c < mincost) {
|
||||||
|
mincost = c;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
assert (mincost < Double.POSITIVE_INFINITY);
|
||||||
|
return mincost;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
32
java/strategy/TransitOnEdge.java
Normal file
32
java/strategy/TransitOnEdge.java
Normal file
|
|
@ -0,0 +1,32 @@
|
||||||
|
package patterns.strategy;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import patterns.Point;
|
||||||
|
/**
|
||||||
|
* Find the transit of minimal cost among the given edges.
|
||||||
|
|
||||||
|
Edges are given as the considered point and the sequence of neighbors points.
|
||||||
|
|
||||||
|
* @author pouyllau
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
public class TransitOnEdge extends Transit {
|
||||||
|
|
||||||
|
public double transit(Point p, List<Point> neighbors, Map<Point, Double> costs) {
|
||||||
|
double mincost = Double.POSITIVE_INFINITY;
|
||||||
|
|
||||||
|
for (Point n : neighbors) {
|
||||||
|
if (hasCost(n, costs)) {
|
||||||
|
double c = costs.get(n) + Point.distance(p, n);
|
||||||
|
if (c < mincost) {
|
||||||
|
mincost = c;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
assert (mincost != Double.POSITIVE_INFINITY);
|
||||||
|
return mincost;
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue