Compare commits
10 commits
d0e970b2ab
...
0d9b2e450c
Author | SHA1 | Date | |
---|---|---|---|
0d9b2e450c | |||
eaa80d87fa | |||
51c2c8b29e | |||
9c47703bc4 | |||
7cc3c39211 | |||
b7012ee892 | |||
f45f0027f0 | |||
de340c65dd | |||
63da86ab0f | |||
26a662bb1b |
7 changed files with 113 additions and 49 deletions
|
@ -1,24 +1,18 @@
|
||||||
package org.insa.graphs.algorithm.marathon;
|
package org.insa.graphs.algorithm.marathon;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import org.insa.graphs.algorithm.AbstractAlgorithm;
|
|
||||||
import org.insa.graphs.algorithm.ArcInspector;
|
import org.insa.graphs.algorithm.ArcInspector;
|
||||||
import org.insa.graphs.algorithm.ArcInspectorFactory;
|
|
||||||
import org.insa.graphs.algorithm.AbstractSolution.Status;
|
|
||||||
import org.insa.graphs.algorithm.shortestpath.DijkstraAlgorithm;
|
import org.insa.graphs.algorithm.shortestpath.DijkstraAlgorithm;
|
||||||
import org.insa.graphs.algorithm.shortestpath.Label;
|
import org.insa.graphs.algorithm.shortestpath.Label;
|
||||||
import org.insa.graphs.algorithm.shortestpath.ShortestPathAlgorithm;
|
import org.insa.graphs.algorithm.shortestpath.ShortestPathAlgorithm;
|
||||||
import org.insa.graphs.algorithm.shortestpath.ShortestPathData;
|
import org.insa.graphs.algorithm.shortestpath.ShortestPathData;
|
||||||
import org.insa.graphs.algorithm.shortestpath.ShortestPathObserver;
|
|
||||||
import org.insa.graphs.algorithm.shortestpath.ShortestPathSolution;
|
import org.insa.graphs.algorithm.shortestpath.ShortestPathSolution;
|
||||||
import org.insa.graphs.algorithm.utils.BinaryHeap;
|
|
||||||
import org.insa.graphs.model.Arc;
|
import org.insa.graphs.model.Arc;
|
||||||
import org.insa.graphs.model.Graph;
|
import org.insa.graphs.model.Graph;
|
||||||
import org.insa.graphs.model.Node;
|
import org.insa.graphs.model.Node;
|
||||||
import org.insa.graphs.model.Path;
|
import org.insa.graphs.model.Path;
|
||||||
|
|
||||||
import java.util.Random;
|
import java.util.Random;
|
||||||
|
|
||||||
|
|
||||||
|
@ -44,49 +38,34 @@ public class MarathonAlgorithm extends ShortestPathAlgorithm {
|
||||||
@Override
|
@Override
|
||||||
protected ShortestPathSolution doRun() {
|
protected ShortestPathSolution doRun() {
|
||||||
final ShortestPathData data = getInputData();
|
final ShortestPathData data = getInputData();
|
||||||
ShortestPathSolution solution = null;
|
|
||||||
final Graph graph = data.getGraph();
|
final Graph graph = data.getGraph();
|
||||||
final int nbNodes = graph.size();
|
|
||||||
|
|
||||||
DijkstraAlgorithm dijkstra = new DijkstraAlgorithm(data);
|
final ShortestPathSolution solution = (new DijkstraAlgorithm(data)).run();
|
||||||
ShortestPathSolution path = dijkstra.run();
|
final Path path = solution.getPath();
|
||||||
|
|
||||||
while (path.getPath().getLength() < getDistance()) {
|
if (!solution.isFeasible())
|
||||||
// Recuperation indices
|
return solution;
|
||||||
// TODO : A MODIFIER POUR AMELIORER LA COHERENCE DU CHEMIN
|
|
||||||
int longueurPath = path.getPath().size();
|
while (path.getLength() < distanceMarathon) {
|
||||||
List<Arc> pathMax = path.getPath().getArcs();
|
// Recuperation Arc à supprimer (cacher) et extremites
|
||||||
float max = 0;
|
final Arc arcToRemove = getRandomArc(path);
|
||||||
int indiceArcToRemove = 0; //Math.abs(rand.nextInt() % (longueurPath - 1));
|
final Node originArcToRemove = arcToRemove.getOrigin();
|
||||||
for (int i = 0; i < pathMax.size(); i++) {
|
final Node destinationArcToRemove = arcToRemove.getDestination();
|
||||||
if (pathMax.get(i).getLength() > max) {
|
|
||||||
max = pathMax.get(i).getLength();
|
|
||||||
indiceArcToRemove = i;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Recuperation Arc à supprimer
|
|
||||||
Arc arcToRemove = path.getPath().getArcs().get(indiceArcToRemove);
|
|
||||||
Node originArcToRemove = arcToRemove.getOrigin();
|
|
||||||
Node destinationArcToRemove = arcToRemove.getDestination();
|
|
||||||
|
|
||||||
// On le supprime dans une copie du tableau (getter Collections.unmodifiable dans Path.java)
|
|
||||||
path.getPath().getArcs().remove(indiceArcToRemove);
|
|
||||||
originArcToRemove.removeArc(arcToRemove);
|
|
||||||
|
|
||||||
// Creations du chemin entre les 2 noeuds dont l'arc a été supprimé
|
// Creations du chemin entre les 2 noeuds dont l'arc a été supprimé
|
||||||
ArcInspector arcInspector = ArcInspectorFactory.getAllFilters().get(0);
|
final ArcInspector arcInspector = new MarathonArcInspector(path, arcToRemove); // filters out cycles and current arc
|
||||||
ShortestPathData newData = new ShortestPathData(graph, originArcToRemove, destinationArcToRemove, arcInspector);
|
final ShortestPathData newData = new ShortestPathData(graph, originArcToRemove, destinationArcToRemove, arcInspector);
|
||||||
DijkstraAlgorithm newDijkstra = new DijkstraAlgorithm(newData);
|
final Path newPath = (new DijkstraAlgorithm(newData)).run().getPath();
|
||||||
ShortestPathSolution newPath = newDijkstra.run();
|
|
||||||
|
|
||||||
if (newPath.getPath() != null) {
|
// could get stuck in a loop if no path is found, given the current arcToRemove strategy
|
||||||
|
if (newPath != null) {
|
||||||
// Ajout du path trouvé à l'indice où on l'a enlevé
|
// Ajout du path trouvé à l'indice où on l'a enlevé
|
||||||
path.getPath().getArcs().addAll(newPath.getPath().getArcs());
|
path.replaceArc(arcToRemove, newPath.getArcs());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return path;
|
return solution;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -98,5 +77,31 @@ public class MarathonAlgorithm extends ShortestPathAlgorithm {
|
||||||
public static int getDistance() {
|
public static int getDistance() {
|
||||||
return distanceMarathon;
|
return distanceMarathon;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private Arc getLongestArc(Path path) {
|
||||||
|
// TODO : A MODIFIER POUR AMELIORER LA COHERENCE DU CHEMIN
|
||||||
|
final List<Arc> arcs = path.getArcs();
|
||||||
|
// we checked that the path is feasible in run
|
||||||
|
// so there should be at least one Arc (unless start = destination ?)
|
||||||
|
if (arcs.size() == 0)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
Arc longestArc = arcs.get(0);
|
||||||
|
for (Arc arc : arcs) {
|
||||||
|
if (arc.getLength() > longestArc.getLength()) {
|
||||||
|
longestArc = arc;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return longestArc;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Arc getRandomArc(Path path) {
|
||||||
|
final List<Arc> arcs = path.getArcs();
|
||||||
|
if (arcs.size() == 0)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
return arcs.get(Math.abs(rand.nextInt() % (arcs.size())));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,58 @@
|
||||||
|
package org.insa.graphs.algorithm.marathon;
|
||||||
|
|
||||||
|
import org.insa.graphs.algorithm.AbstractInputData.Mode;
|
||||||
|
import org.insa.graphs.algorithm.ArcInspector;
|
||||||
|
import org.insa.graphs.model.Arc;
|
||||||
|
import org.insa.graphs.model.Path;
|
||||||
|
|
||||||
|
public class MarathonArcInspector implements ArcInspector{
|
||||||
|
static final int maxPedestrianSpeed = 10 ; // ie a 4:13 time
|
||||||
|
|
||||||
|
private Path path;
|
||||||
|
private Arc currentArc;
|
||||||
|
|
||||||
|
public MarathonArcInspector(Path path, Arc currentArc) {
|
||||||
|
this.path = path;
|
||||||
|
this.currentArc = currentArc;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Checks whether the arc is accessible and whether it would create a cycle,
|
||||||
|
* leading to unhappy marathoners.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public boolean isAllowed(Arc arc) {
|
||||||
|
/*final boolean runnersCanAccess = arc.getRoadInformation().getAccessRestrictions()
|
||||||
|
.isAllowedForAny(AccessMode.FOOT, EnumSet.complementOf(EnumSet
|
||||||
|
.of(AccessRestriction.FORBIDDEN, AccessRestriction.PRIVATE)));*/
|
||||||
|
final boolean runnersCanAccess = true;
|
||||||
|
final boolean isCurrentArc = arc.getOrigin().equals(currentArc.getOrigin())
|
||||||
|
&& arc.getDestination().equals(currentArc.getDestination());
|
||||||
|
final boolean passesThroughOrigin = arc.getDestination().equals(path.getArcs().get(0).getOrigin());
|
||||||
|
|
||||||
|
boolean createsCycle = false;
|
||||||
|
for (Arc pathArc : this.path.getArcs()) {
|
||||||
|
if (arc.getDestination().equals(pathArc.getDestination())
|
||||||
|
&& !arc.getDestination().equals(currentArc.getDestination()))
|
||||||
|
createsCycle = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return runnersCanAccess && !isCurrentArc && !passesThroughOrigin && !createsCycle;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public double getCost(Arc arc) {
|
||||||
|
return arc.getLength();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "MarathonArcInspector";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Mode getMode() {
|
||||||
|
return Mode.LENGTH;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -2,7 +2,6 @@ package org.insa.graphs.algorithm.shortestpath;
|
||||||
|
|
||||||
import org.insa.graphs.model.Node;
|
import org.insa.graphs.model.Node;
|
||||||
import org.insa.graphs.model.Arc;
|
import org.insa.graphs.model.Arc;
|
||||||
import org.insa.graphs.algorithm.AbstractInputData.Mode;
|
|
||||||
|
|
||||||
public class Label implements Comparable<Label> {
|
public class Label implements Comparable<Label> {
|
||||||
Node node;
|
Node node;
|
||||||
|
|
|
@ -2,8 +2,6 @@ package org.insa.graphs.algorithm.shortestpath;
|
||||||
|
|
||||||
import org.insa.graphs.model.Node;
|
import org.insa.graphs.model.Node;
|
||||||
import org.insa.graphs.model.Point;
|
import org.insa.graphs.model.Point;
|
||||||
import org.insa.graphs.algorithm.AbstractInputData.Mode;
|
|
||||||
import org.insa.graphs.model.RoadInformation;
|
|
||||||
|
|
||||||
public class LabelStar extends Label {
|
public class LabelStar extends Label {
|
||||||
private double distanceToDestination;
|
private double distanceToDestination;
|
||||||
|
|
|
@ -11,8 +11,6 @@ import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Random;
|
import java.util.Random;
|
||||||
|
|
||||||
import javax.print.attribute.standard.Destination;
|
|
||||||
|
|
||||||
import org.insa.graphs.algorithm.AbstractInputData.Mode;
|
import org.insa.graphs.algorithm.AbstractInputData.Mode;
|
||||||
import org.insa.graphs.algorithm.ArcInspector;
|
import org.insa.graphs.algorithm.ArcInspector;
|
||||||
import org.insa.graphs.algorithm.ArcInspectorFactory;
|
import org.insa.graphs.algorithm.ArcInspectorFactory;
|
||||||
|
@ -25,7 +23,6 @@ import org.insa.graphs.model.io.GraphReader;
|
||||||
import org.insa.graphs.model.io.PathReader;
|
import org.insa.graphs.model.io.PathReader;
|
||||||
import org.junit.BeforeClass;
|
import org.junit.BeforeClass;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.junit.runner.Description;
|
|
||||||
import org.junit.runners.Parameterized.Parameter;
|
import org.junit.runners.Parameterized.Parameter;
|
||||||
|
|
||||||
public abstract class ShortestPathAlgorithmTest {
|
public abstract class ShortestPathAlgorithmTest {
|
||||||
|
|
|
@ -207,8 +207,17 @@ public class Path {
|
||||||
* @return List of arcs in the path.
|
* @return List of arcs in the path.
|
||||||
*/
|
*/
|
||||||
public List<Arc> getArcs() {
|
public List<Arc> getArcs() {
|
||||||
// return Collections.unmodifiableList(arcs);
|
return Collections.unmodifiableList(arcs);
|
||||||
return arcs;
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Replace arc with an array of arcs
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public void replaceArc(Arc arc, List<Arc> newArcs) {
|
||||||
|
final int index = this.arcs.indexOf(arc);
|
||||||
|
this.arcs.remove(index);
|
||||||
|
this.arcs.addAll(index, newArcs);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -15,7 +15,6 @@ import org.insa.graphs.model.Path;
|
||||||
import org.insa.graphs.model.RoadInformation;
|
import org.insa.graphs.model.RoadInformation;
|
||||||
import org.insa.graphs.model.RoadInformation.RoadType;
|
import org.insa.graphs.model.RoadInformation.RoadType;
|
||||||
import org.junit.BeforeClass;
|
import org.junit.BeforeClass;
|
||||||
import org.junit.Ignore;
|
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
public class PathTest {
|
public class PathTest {
|
||||||
|
@ -84,7 +83,6 @@ public class PathTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expected = UnsupportedOperationException.class)
|
@Test(expected = UnsupportedOperationException.class)
|
||||||
@Ignore // Mutability required for marathon path-finding algo
|
|
||||||
public void testImmutability() {
|
public void testImmutability() {
|
||||||
emptyPath.getArcs().add(a2b);
|
emptyPath.getArcs().add(a2b);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue