Compare commits
No commits in common. "0d9b2e450cac6fe1d8d520605c383aa977dba082" and "d0e970b2ab9b8d7bc6aee2b99e3e0906174f3c97" have entirely different histories.
0d9b2e450c
...
d0e970b2ab
7 changed files with 49 additions and 113 deletions
|
@ -1,18 +1,24 @@
|
||||||
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;
|
||||||
|
|
||||||
|
|
||||||
|
@ -38,34 +44,49 @@ 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();
|
||||||
|
|
||||||
final ShortestPathSolution solution = (new DijkstraAlgorithm(data)).run();
|
DijkstraAlgorithm dijkstra = new DijkstraAlgorithm(data);
|
||||||
final Path path = solution.getPath();
|
ShortestPathSolution path = dijkstra.run();
|
||||||
|
|
||||||
if (!solution.isFeasible())
|
while (path.getPath().getLength() < getDistance()) {
|
||||||
return solution;
|
// Recuperation indices
|
||||||
|
// TODO : A MODIFIER POUR AMELIORER LA COHERENCE DU CHEMIN
|
||||||
|
int longueurPath = path.getPath().size();
|
||||||
|
List<Arc> pathMax = path.getPath().getArcs();
|
||||||
|
float max = 0;
|
||||||
|
int indiceArcToRemove = 0; //Math.abs(rand.nextInt() % (longueurPath - 1));
|
||||||
|
for (int i = 0; i < pathMax.size(); i++) {
|
||||||
|
if (pathMax.get(i).getLength() > max) {
|
||||||
|
max = pathMax.get(i).getLength();
|
||||||
|
indiceArcToRemove = i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
while (path.getLength() < distanceMarathon) {
|
// Recuperation Arc à supprimer
|
||||||
// Recuperation Arc à supprimer (cacher) et extremites
|
Arc arcToRemove = path.getPath().getArcs().get(indiceArcToRemove);
|
||||||
final Arc arcToRemove = getRandomArc(path);
|
Node originArcToRemove = arcToRemove.getOrigin();
|
||||||
final Node originArcToRemove = arcToRemove.getOrigin();
|
Node destinationArcToRemove = arcToRemove.getDestination();
|
||||||
final 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é
|
||||||
final ArcInspector arcInspector = new MarathonArcInspector(path, arcToRemove); // filters out cycles and current arc
|
ArcInspector arcInspector = ArcInspectorFactory.getAllFilters().get(0);
|
||||||
final ShortestPathData newData = new ShortestPathData(graph, originArcToRemove, destinationArcToRemove, arcInspector);
|
ShortestPathData newData = new ShortestPathData(graph, originArcToRemove, destinationArcToRemove, arcInspector);
|
||||||
final Path newPath = (new DijkstraAlgorithm(newData)).run().getPath();
|
DijkstraAlgorithm newDijkstra = new DijkstraAlgorithm(newData);
|
||||||
|
ShortestPathSolution newPath = newDijkstra.run();
|
||||||
|
|
||||||
// could get stuck in a loop if no path is found, given the current arcToRemove strategy
|
if (newPath.getPath() != null) {
|
||||||
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.replaceArc(arcToRemove, newPath.getArcs());
|
path.getPath().getArcs().addAll(newPath.getPath().getArcs());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return solution;
|
return path;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -77,31 +98,5 @@ 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())));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,58 +0,0 @@
|
||||||
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,6 +2,7 @@ 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,6 +2,8 @@ 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,6 +11,8 @@ 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;
|
||||||
|
@ -23,6 +25,7 @@ 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,17 +207,8 @@ 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,6 +15,7 @@ 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 {
|
||||||
|
@ -83,6 +84,7 @@ 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