Compare commits

..

10 commits

7 changed files with 113 additions and 49 deletions

View file

@ -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 on l'a enlevé // Ajout du path trouvé à l'indice 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())));
}
} }

View file

@ -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;
}
}

View file

@ -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;

View file

@ -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;

View file

@ -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 {

View file

@ -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);
} }
/** /**

View file

@ -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);
} }