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;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import org.insa.graphs.algorithm.AbstractAlgorithm;
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.Label;
import org.insa.graphs.algorithm.shortestpath.ShortestPathAlgorithm;
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.utils.BinaryHeap;
import org.insa.graphs.model.Arc;
import org.insa.graphs.model.Graph;
import org.insa.graphs.model.Node;
import org.insa.graphs.model.Path;
import java.util.Random;
@ -44,49 +38,34 @@ public class MarathonAlgorithm extends ShortestPathAlgorithm {
@Override
protected ShortestPathSolution doRun() {
final ShortestPathData data = getInputData();
ShortestPathSolution solution = null;
final Graph graph = data.getGraph();
final int nbNodes = graph.size();
DijkstraAlgorithm dijkstra = new DijkstraAlgorithm(data);
ShortestPathSolution path = dijkstra.run();
final ShortestPathSolution solution = (new DijkstraAlgorithm(data)).run();
final Path path = solution.getPath();
while (path.getPath().getLength() < getDistance()) {
// 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;
}
}
// Recuperation Arc à supprimer
Arc arcToRemove = path.getPath().getArcs().get(indiceArcToRemove);
Node originArcToRemove = arcToRemove.getOrigin();
Node destinationArcToRemove = arcToRemove.getDestination();
if (!solution.isFeasible())
return solution;
while (path.getLength() < distanceMarathon) {
// Recuperation Arc à supprimer (cacher) et extremites
final Arc arcToRemove = getRandomArc(path);
final Node originArcToRemove = arcToRemove.getOrigin();
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é
ArcInspector arcInspector = ArcInspectorFactory.getAllFilters().get(0);
ShortestPathData newData = new ShortestPathData(graph, originArcToRemove, destinationArcToRemove, arcInspector);
DijkstraAlgorithm newDijkstra = new DijkstraAlgorithm(newData);
ShortestPathSolution newPath = newDijkstra.run();
final ArcInspector arcInspector = new MarathonArcInspector(path, arcToRemove); // filters out cycles and current arc
final ShortestPathData newData = new ShortestPathData(graph, originArcToRemove, destinationArcToRemove, arcInspector);
final Path newPath = (new DijkstraAlgorithm(newData)).run().getPath();
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é
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() {
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.Arc;
import org.insa.graphs.algorithm.AbstractInputData.Mode;
public class Label implements Comparable<Label> {
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.Point;
import org.insa.graphs.algorithm.AbstractInputData.Mode;
import org.insa.graphs.model.RoadInformation;
public class LabelStar extends Label {
private double distanceToDestination;

View file

@ -11,8 +11,6 @@ import java.util.ArrayList;
import java.util.Arrays;
import java.util.Random;
import javax.print.attribute.standard.Destination;
import org.insa.graphs.algorithm.AbstractInputData.Mode;
import org.insa.graphs.algorithm.ArcInspector;
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.junit.BeforeClass;
import org.junit.Test;
import org.junit.runner.Description;
import org.junit.runners.Parameterized.Parameter;
public abstract class ShortestPathAlgorithmTest {

View file

@ -207,8 +207,17 @@ public class Path {
* @return List of arcs in the path.
*/
public List<Arc> getArcs() {
// return Collections.unmodifiableList(arcs);
return arcs;
return Collections.unmodifiableList(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.RoadType;
import org.junit.BeforeClass;
import org.junit.Ignore;
import org.junit.Test;
public class PathTest {
@ -84,7 +83,6 @@ public class PathTest {
}
@Test(expected = UnsupportedOperationException.class)
@Ignore // Mutability required for marathon path-finding algo
public void testImmutability() {
emptyPath.getArcs().add(a2b);
}