Update code.

This commit is contained in:
Mikael Capelle
2018-02-20 11:27:12 +01:00
parent a6e8a22081
commit 71accfe13b
18 changed files with 436 additions and 266 deletions

View File

@@ -1,24 +1,22 @@
package org.insa.algo ;
import java.time.Duration;
import java.time.Instant;
import java.util.ArrayList;
public abstract class AbstractAlgorithm implements Runnable {
public abstract class AbstractAlgorithm<Observer> {
protected AbstractInstance instance;
protected AbstractSolution solution;
protected ArrayList<AbstractObserver> observers;
protected ArrayList<Observer> observers;
protected AbstractAlgorithm(AbstractInstance instance) {
this.instance = instance;
this.observers = new ArrayList<AbstractObserver>();
this.solution = null;
this.observers = new ArrayList<Observer>();
}
protected AbstractAlgorithm(AbstractInstance instance, ArrayList<AbstractObserver> observers) {
protected AbstractAlgorithm(AbstractInstance instance, ArrayList<Observer> observers) {
this.instance = instance;
this.observers = observers;;
this.solution = null;
}
/**
@@ -26,44 +24,32 @@ public abstract class AbstractAlgorithm implements Runnable {
*
* @param observer
*/
public void addObserver(AbstractObserver observer) {
public void addObserver(Observer observer) {
observers.add(observer);
}
/**
* @return The list of observers for this algorithm.
*/
public ArrayList<AbstractObserver> getObservers() {
public ArrayList<Observer> getObservers() {
return observers;
}
/**
* Update the current solution.
*
* @param solution New solution, or null to unset the current solution.
*
*/
protected void updateLastSolution(AbstractSolution solution) {
this.solution = solution;
}
/**
* @return Instance corresponding to this algorithm.
*/
public AbstractInstance getInstance() { return instance; }
/**
* @return Last solution, or null if no solution was stored.
*/
public AbstractSolution getLastSolution() { return solution; }
/**
* Run the algorithm and update the current solution.
*
* @return true if a feasible solution was found (even non-optimal).
*/
public void run() {
this.solution = this.doRun();
public AbstractSolution run() {
Instant start = Instant.now();
AbstractSolution solution = this.doRun();
solution.setSolvingTime(Duration.between(start, Instant.now()));
return solution;
}
/**

View File

@@ -1,20 +0,0 @@
package org.insa.algo;
public abstract class AbstractObserver {
// Specify if the observer is graphic or not.
private final boolean isgraphic;
protected AbstractObserver(boolean isGraphic) {
this.isgraphic = isGraphic;
}
/**
* @return true if this observer is graphic (use drawing to display
* information).
*/
public boolean isGraphic() {
return isgraphic;
}
}

View File

@@ -35,10 +35,8 @@ public abstract class AbstractSolution {
this.status = Status.UNKNOWN;
}
protected AbstractSolution(AbstractInstance instance,
Duration solvingTime, Status status) {
protected AbstractSolution(AbstractInstance instance, Status status) {
this.instance = instance;
this.solvingTime = solvingTime;
this.status = status;
}
@@ -57,6 +55,15 @@ public abstract class AbstractSolution {
*/
public Duration getSolvingTime() { return solvingTime; }
/**
* Set the solving time of this solution.
*
* @param solvingTime Solving time for the solution.
*/
protected void setSolvingTime(Duration solvingTime) {
this.solvingTime = solvingTime;
}
/**
* @return true if the solution is feasible or optimal.
*/

View File

@@ -0,0 +1,30 @@
package org.insa.algo.strongconnectivity;
import java.util.ArrayList;
import org.insa.graph.Node;
public interface StronglyConnectedComponentObserver {
/**
* Notify that the algorithm is entering a new component.
*
* @param curNode Starting node for the component.
*/
public void notifyStartComponent(Node curNode);
/**
* Notify that a new node has been found for the current component.
*
* @param node New node found for the current component.
*/
public void notifyNewNodeInComponent(Node node);
/**
* Notify that the algorithm has computed a new component.
*
* @param nodes List of nodes in the component.
*/
public void notifyEndComponent(ArrayList<Node> nodes);
}

View File

@@ -2,7 +2,7 @@ package org.insa.algo.strongconnectivity ;
import org.insa.algo.AbstractAlgorithm;
public abstract class StronglyConnectedComponentsAlgorithm extends AbstractAlgorithm {
public abstract class StronglyConnectedComponentsAlgorithm extends AbstractAlgorithm<StronglyConnectedComponentObserver> {
/**
*
@@ -12,5 +12,15 @@ public abstract class StronglyConnectedComponentsAlgorithm extends AbstractAlgor
public StronglyConnectedComponentsAlgorithm(StronglyConnectedComponentsInstance instance) {
super(instance);
}
@Override
public StronglyConnectedComponentsSolution run() {
return (StronglyConnectedComponentsSolution)super.run();
}
@Override
public StronglyConnectedComponentsInstance getInstance() {
return (StronglyConnectedComponentsInstance)super.getInstance();
}
}

View File

@@ -1,6 +1,5 @@
package org.insa.algo.strongconnectivity;
import java.time.Duration;
import java.util.ArrayList;
import org.insa.algo.AbstractSolution;
@@ -16,8 +15,8 @@ public class StronglyConnectedComponentsSolution extends AbstractSolution {
}
protected StronglyConnectedComponentsSolution(StronglyConnectedComponentsInstance instance,
Duration solvingTime, Status status, ArrayList<ArrayList<Node>> components) {
super(instance, solvingTime, status);
Status status, ArrayList<ArrayList<Node>> components) {
super(instance, status);
this.components = components;
}

View File

@@ -1,12 +1,9 @@
package org.insa.algo.strongconnectivity;
import java.time.Duration;
import java.time.Instant;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Stack;
import org.insa.algo.AbstractSolution;
import org.insa.algo.AbstractSolution.Status;
import org.insa.graph.Arc;
import org.insa.graph.Graph;
@@ -74,7 +71,6 @@ public class TarjanAlgorithm extends StronglyConnectedComponentsAlgorithm {
* @return The strong component containing the given node.
*/
protected void findAndAddStrongComponent(Node v) {
Graph graph = getInstance().getGraph();
// Update node info, index and push the node.
indexes[v.getId()] = index;
@@ -117,14 +113,11 @@ public class TarjanAlgorithm extends StronglyConnectedComponentsAlgorithm {
}
@Override
protected AbstractSolution doRun() {
protected StronglyConnectedComponentsSolution doRun() {
Graph graph = getInstance().getGraph();
components = new ArrayList<ArrayList<Node>>();
// Starting time...
Instant start = Instant.now();
// Initialize everything
final int nbNodes = graph.getNodes().size();
stack = new Stack<Node>();
@@ -144,12 +137,8 @@ public class TarjanAlgorithm extends StronglyConnectedComponentsAlgorithm {
findAndAddStrongComponent(node);
}
}
// Duration...
Duration solvingTime = Duration.between(start, Instant.now());
return new StronglyConnectedComponentsSolution((StronglyConnectedComponentsInstance)getInstance(),
solvingTime, Status.OPTIMAL, components);
return new StronglyConnectedComponentsSolution(getInstance(), Status.OPTIMAL, components);
}
}

View File

@@ -7,7 +7,7 @@ import org.insa.drawing.Drawing;
import org.insa.drawing.graph.GraphDrawing;
import org.insa.graph.Node;
public class WeaklyConnectedComponentGraphicObserver extends WeaklyConnectedComponentObserver {
public class WeaklyConnectedComponentGraphicObserver implements WeaklyConnectedComponentObserver {
private static final Color[] COLORS = {
Color.BLUE, Color.ORANGE, Color.GREEN, Color.YELLOW, Color.RED
@@ -21,7 +21,6 @@ public class WeaklyConnectedComponentGraphicObserver extends WeaklyConnectedComp
private int cindex = 0;
public WeaklyConnectedComponentGraphicObserver(Drawing drawing) {
super(true);
this.drawing = drawing;
this.gdrawing = new GraphDrawing(drawing);
this.drawing.setAutoRepaint(true);

View File

@@ -2,37 +2,29 @@ package org.insa.algo.weakconnectivity;
import java.util.ArrayList;
import org.insa.algo.AbstractObserver;
import org.insa.graph.Node;
public abstract class WeaklyConnectedComponentObserver extends AbstractObserver {
public interface WeaklyConnectedComponentObserver {
/**
* {@inheritDoc}
*/
protected WeaklyConnectedComponentObserver(boolean isGraphic) {
super(isGraphic);
}
/**
* Notify that the algorithm is entering a new component.
*
* @param curNode Starting node for the component.
*/
public abstract void notifyStartComponent(Node curNode);
public void notifyStartComponent(Node curNode);
/**
* Notify that a new node has been found for the current component.
*
* @param node New node found for the current component.
*/
public abstract void notifyNewNodeInComponent(Node node);
public void notifyNewNodeInComponent(Node node);
/**
* Notify that the algorithm has computed a new component.
*
* @param nodes List of nodes in the component.
*/
public abstract void notifyEndComponent(ArrayList<Node> nodes);
public void notifyEndComponent(ArrayList<Node> nodes);
}

View File

@@ -5,7 +5,7 @@ import java.util.ArrayList;
import org.insa.graph.Node;
public class WeaklyConnectedComponentTextObserver extends WeaklyConnectedComponentObserver {
public class WeaklyConnectedComponentTextObserver implements WeaklyConnectedComponentObserver {
// Number of the current component.
private int numComponent = 1;
@@ -14,7 +14,6 @@ public class WeaklyConnectedComponentTextObserver extends WeaklyConnectedCompone
PrintStream stream;
public WeaklyConnectedComponentTextObserver(PrintStream stream) {
super(false);
this.stream = stream;
}

View File

@@ -1,23 +1,18 @@
package org.insa.algo.weakconnectivity;
import java.time.Duration;
import java.time.Instant;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.LinkedList;
import java.util.Queue;
import java.util.HashSet;
import org.insa.algo.AbstractAlgorithm;
import org.insa.algo.AbstractObserver;
import org.insa.algo.AbstractSolution;
import org.insa.algo.AbstractSolution.Status;
import org.insa.graph.Arc;
import org.insa.graph.Graph;
import org.insa.graph.Node;
public class WeaklyConnectedComponentsAlgorithm extends AbstractAlgorithm {
public class WeaklyConnectedComponentsAlgorithm extends AbstractAlgorithm<WeaklyConnectedComponentObserver>{
/**
*
@@ -28,6 +23,49 @@ public class WeaklyConnectedComponentsAlgorithm extends AbstractAlgorithm {
super(instance);
}
@Override
public WeaklyConnectedComponentsSolution run() {
return (WeaklyConnectedComponentsSolution)super.run();
}
@Override
public WeaklyConnectedComponentsInstance getInstance() {
return (WeaklyConnectedComponentsInstance)super.getInstance();
}
/**
* Notify all observers that the algorithm is entering a new component.
*
* @param curNode Starting node for the component.
*/
protected void notifyStartComponent(Node curNode) {
for (WeaklyConnectedComponentObserver obs: getObservers()) {
obs.notifyStartComponent(curNode);
}
}
/**
* Notify all observers that a new node has been found for the current component.
*
* @param node New node found for the current component.
*/
protected void notifyNewNodeInComponent(Node node) {
for (WeaklyConnectedComponentObserver obs: getObservers()) {
obs.notifyNewNodeInComponent(node);
}
}
/**
* Notify all observers that the algorithm has computed a new component.
*
* @param nodes List of nodes in the component.
*/
protected void notifyEndComponent(ArrayList<Node> nodes) {
for (WeaklyConnectedComponentObserver obs: getObservers()) {
obs.notifyEndComponent(nodes);
}
}
/**
* @return An adjacency list for the undirected graph equivalent to the stored graph.
*/
@@ -66,9 +104,8 @@ public class WeaklyConnectedComponentsAlgorithm extends AbstractAlgorithm {
// Using a queue because we are doing a BFS
Queue<Integer> queue = new LinkedList<Integer>();
for (AbstractObserver obs: getObservers()) {
((WeaklyConnectedComponentObserver)obs).notifyStartComponent(nodes.get(cur));
}
// Notify observers about the current component.
notifyStartComponent(nodes.get(cur));
// Add original node and loop until the queue is empty.
queue.add(cur);
@@ -77,8 +114,8 @@ public class WeaklyConnectedComponentsAlgorithm extends AbstractAlgorithm {
Node node = nodes.get(queue.remove());
component.add(node);
// notify observers
for (AbstractObserver obs: getObservers()) ((WeaklyConnectedComponentObserver)obs).notifyNewNodeInComponent(node);
// Notify observers
notifyNewNodeInComponent(node);
for (Integer destId: ugraph.get(node.getId())) {
Node dest = nodes.get(destId);
@@ -89,18 +126,14 @@ public class WeaklyConnectedComponentsAlgorithm extends AbstractAlgorithm {
}
}
for (AbstractObserver obs: getObservers()) {
((WeaklyConnectedComponentObserver)obs).notifyEndComponent(component);
}
notifyEndComponent(component);
return component;
}
@Override
protected AbstractSolution doRun() {
protected WeaklyConnectedComponentsSolution doRun() {
Instant start = Instant.now();
Graph graph = getInstance().getGraph();
ArrayList<HashSet<Integer>> ugraph = createUndirectedGraph();
boolean[] marked = new boolean[graph.getNodes().size()];
@@ -117,11 +150,8 @@ public class WeaklyConnectedComponentsAlgorithm extends AbstractAlgorithm {
// Find next non-marked
for (; cur < marked.length && marked[cur]; ++cur);
}
Duration solvingTime = Duration.between(start, Instant.now());
return new WeaklyConnectedComponentsSolution((WeaklyConnectedComponentsInstance)getInstance(),
solvingTime, Status.OPTIMAL, components);
return new WeaklyConnectedComponentsSolution(getInstance(), Status.OPTIMAL, components);
}
}

View File

@@ -1,6 +1,5 @@
package org.insa.algo.weakconnectivity;
import java.time.Duration;
import java.util.ArrayList;
import org.insa.algo.AbstractSolution;
@@ -16,8 +15,8 @@ public class WeaklyConnectedComponentsSolution extends AbstractSolution {
}
protected WeaklyConnectedComponentsSolution(WeaklyConnectedComponentsInstance instance,
Duration solvingTime, Status status, ArrayList<ArrayList<Node>> components) {
super(instance, solvingTime, status);
Status status, ArrayList<ArrayList<Node>> components) {
super(instance, status);
this.components = components;
}