Instance -> Data.

This commit is contained in:
Mikael Capelle 2018-03-02 15:30:55 +01:00
parent e111b5f0e6
commit 4017577269
12 changed files with 288 additions and 276 deletions

View File

@ -1,4 +1,4 @@
package org.insa.algo ; package org.insa.algo;
import java.time.Duration; import java.time.Duration;
import java.time.Instant; import java.time.Instant;
@ -6,17 +6,25 @@ import java.util.ArrayList;
public abstract class AbstractAlgorithm<Observer> { public abstract class AbstractAlgorithm<Observer> {
protected AbstractData instance; protected AbstractInputData data;
protected ArrayList<Observer> observers; protected ArrayList<Observer> observers;
protected AbstractAlgorithm(AbstractData instance) { /**
this.instance = instance; * @param data
this.observers = new ArrayList<Observer>(); */
protected AbstractAlgorithm(AbstractInputData data) {
this.data = data;
this.observers = new ArrayList<Observer>();
} }
protected AbstractAlgorithm(AbstractData instance, ArrayList<Observer> observers) { /**
this.instance = instance; * @param data
this.observers = observers;; * @param observers
*/
protected AbstractAlgorithm(AbstractInputData data, ArrayList<Observer> observers) {
this.data = data;
this.observers = observers;
;
} }
/** /**
@ -25,20 +33,22 @@ public abstract class AbstractAlgorithm<Observer> {
* @param observer * @param observer
*/ */
public void addObserver(Observer observer) { public void addObserver(Observer observer) {
observers.add(observer); observers.add(observer);
} }
/** /**
* @return The list of observers for this algorithm. * @return The list of observers for this algorithm.
*/ */
public ArrayList<Observer> getObservers() { public ArrayList<Observer> getObservers() {
return observers; return observers;
} }
/** /**
* @return Instance corresponding to this algorithm. * @return Instance corresponding to this algorithm.
*/ */
public AbstractData getInputData() { return instance; } public AbstractInputData getInputData() {
return data;
}
/** /**
* Run the algorithm and update the current solution. * Run the algorithm and update the current solution.
@ -46,10 +56,10 @@ public abstract class AbstractAlgorithm<Observer> {
* @return true if a feasible solution was found (even non-optimal). * @return true if a feasible solution was found (even non-optimal).
*/ */
public AbstractSolution run() { public AbstractSolution run() {
Instant start = Instant.now(); Instant start = Instant.now();
AbstractSolution solution = this.doRun(); AbstractSolution solution = this.doRun();
solution.setSolvingTime(Duration.between(start, Instant.now())); solution.setSolvingTime(Duration.between(start, Instant.now()));
return solution; return solution;
} }
/** /**

View File

@ -1,20 +0,0 @@
package org.insa.algo;
import org.insa.graph.Graph;
public abstract class AbstractData {
protected Graph graph;
/**
* Create a new abstract instance with the given graph.
*
* @param graph
*/
protected AbstractData(Graph graph) {
this.graph = graph;
}
public Graph getGraph() { return graph; }
}

View File

@ -0,0 +1,22 @@
package org.insa.algo;
import org.insa.graph.Graph;
public abstract class AbstractInputData {
protected Graph graph;
/**
* Create a new AbstractInputData instance with the given graph.
*
* @param graph
*/
protected AbstractInputData(Graph graph) {
this.graph = graph;
}
public Graph getGraph() {
return graph;
}
}

View File

@ -4,71 +4,74 @@ import java.time.Duration;
public abstract class AbstractSolution { public abstract class AbstractSolution {
/** /**
* Possible status for a solution. * Possible status for a solution.
* *
*/ */
public enum Status { public enum Status {
UNKNOWN, UNKNOWN, INFEASIBLE, FEASIBLE, OPTIMAL,
INFEASIBLE, };
FEASIBLE,
OPTIMAL,
};
// Status of the solution. // Status of the solution.
Status status; Status status;
// Solving time for the solution // Solving time for the solution.
Duration solvingTime; Duration solvingTime;
// Original instance of the solution // Original input of the solution.
AbstractData instance; AbstractInputData data;
/** /**
* Create a new abstract solution with unknown status. * Create a new abstract solution with unknown status.
* *
* @param instance * @param data
*/ */
protected AbstractSolution(AbstractData instance) { protected AbstractSolution(AbstractInputData data) {
this.instance = instance; this.data = data;
this.solvingTime = Duration.ZERO; this.solvingTime = Duration.ZERO;
this.status = Status.UNKNOWN; this.status = Status.UNKNOWN;
} }
protected AbstractSolution(AbstractData instance, Status status) { protected AbstractSolution(AbstractInputData data, Status status) {
this.instance = instance; this.data = data;
this.status = status; this.status = status;
} }
/** /**
* @return Original instance for this solution. * @return Original input for this solution.
*/ */
public AbstractData getInputData() { return instance; } public AbstractInputData getInputData() {
return data;
}
/** /**
* @return Status of this solution. * @return Status of this solution.
*/ */
public Status getStatus() { return status; } public Status getStatus() {
return status;
}
/** /**
* @return Solving time of this solution. * @return Solving time of this solution.
*/ */
public Duration getSolvingTime() { return solvingTime; } public Duration getSolvingTime() {
return solvingTime;
}
/** /**
* Set the solving time of this solution. * Set the solving time of this solution.
* *
* @param solvingTime Solving time for the solution. * @param solvingTime Solving time for the solution.
*/ */
protected void setSolvingTime(Duration solvingTime) { protected void setSolvingTime(Duration solvingTime) {
this.solvingTime = solvingTime; this.solvingTime = solvingTime;
} }
/** /**
* @return true if the solution is feasible or optimal. * @return true if the solution is feasible or optimal.
*/ */
public boolean isFeasible() { public boolean isFeasible() {
return status == Status.FEASIBLE || status == Status.OPTIMAL; return status == Status.FEASIBLE || status == Status.OPTIMAL;
} }
} }

View File

@ -1,26 +1,25 @@
package org.insa.algo.strongconnectivity ; package org.insa.algo.strongconnectivity;
import org.insa.algo.AbstractAlgorithm; import org.insa.algo.AbstractAlgorithm;
public abstract class StronglyConnectedComponentsAlgorithm extends AbstractAlgorithm<StronglyConnectedComponentObserver> { public abstract class StronglyConnectedComponentsAlgorithm
extends AbstractAlgorithm<StronglyConnectedComponentObserver> {
/** /**
* * @param data
* @param instance */
* @param logOutput public StronglyConnectedComponentsAlgorithm(StronglyConnectedComponentsData data) {
*/ super(data);
public StronglyConnectedComponentsAlgorithm(StronglyConnectedComponentsData instance) { }
super(instance);
}
@Override @Override
public StronglyConnectedComponentsSolution run() { public StronglyConnectedComponentsSolution run() {
return (StronglyConnectedComponentsSolution)super.run(); return (StronglyConnectedComponentsSolution) super.run();
} }
@Override @Override
public StronglyConnectedComponentsData getInputData() { public StronglyConnectedComponentsData getInputData() {
return (StronglyConnectedComponentsData)super.getInputData(); return (StronglyConnectedComponentsData) super.getInputData();
} }
} }

View File

@ -1,9 +1,9 @@
package org.insa.algo.strongconnectivity; package org.insa.algo.strongconnectivity;
import org.insa.algo.AbstractData; import org.insa.algo.AbstractInputData;
import org.insa.graph.Graph; import org.insa.graph.Graph;
public class StronglyConnectedComponentsData extends AbstractData { public class StronglyConnectedComponentsData extends AbstractInputData {
/** /**
* *

View File

@ -10,13 +10,13 @@ public class StronglyConnectedComponentsSolution extends AbstractSolution {
// Components // Components
private ArrayList<ArrayList<Node>> components; private ArrayList<ArrayList<Node>> components;
protected StronglyConnectedComponentsSolution(StronglyConnectedComponentsData instance) { protected StronglyConnectedComponentsSolution(StronglyConnectedComponentsData data) {
super(instance); super(data);
} }
protected StronglyConnectedComponentsSolution(StronglyConnectedComponentsData instance, Status status, protected StronglyConnectedComponentsSolution(StronglyConnectedComponentsData data,
ArrayList<ArrayList<Node>> components) { Status status, ArrayList<ArrayList<Node>> components) {
super(instance, status); super(data, status);
this.components = components; this.components = components;
} }

View File

@ -11,134 +11,134 @@ import org.insa.graph.Node;
public class TarjanAlgorithm extends StronglyConnectedComponentsAlgorithm { public class TarjanAlgorithm extends StronglyConnectedComponentsAlgorithm {
private final static int UNDEFINED = -1; private final static int UNDEFINED = -1;
// Stack of nodes and flags. // Stack of nodes and flags.
private Stack<Node> stack; private Stack<Node> stack;
private boolean[] inStack; private boolean[] inStack;
// Current index. // Current index.
private int index; private int index;
// Information of nodes // Information of nodes
private int[] indexes; private int[] indexes;
private int[] lowlink; private int[] lowlink;
// Array of strongly connected components // Array of strongly connected components
ArrayList<ArrayList<Node>> components; ArrayList<ArrayList<Node>> components;
public TarjanAlgorithm(StronglyConnectedComponentsData instance) { public TarjanAlgorithm(StronglyConnectedComponentsData data) {
super(instance); super(data);
} }
/** /**
* Push the given node to the stack. * Push the given node to the stack.
* *
* @param node * @param node
*/ */
protected void pushNode(Node node) { protected void pushNode(Node node) {
stack.push(node); stack.push(node);
inStack[node.getId()] = true; inStack[node.getId()] = true;
} }
/** /**
* Pop and return a node from the stack. * Pop and return a node from the stack.
* *
* @return Node popped from the stack * @return Node popped from the stack
*/ */
protected Node popNode() { protected Node popNode() {
Node top = stack.pop(); Node top = stack.pop();
inStack[top.getId()] = false; inStack[top.getId()] = false;
return top; return top;
} }
/** /**
* Check if the given node is in the stack. * Check if the given node is in the stack.
* *
* @param node * @param node
* *
* @return true if the given node is in the stack, false otherwize. * @return true if the given node is in the stack, false otherwize.
*/ */
protected boolean isInStack(Node node) { protected boolean isInStack(Node node) {
return inStack[node.getId()]; return inStack[node.getId()];
} }
/** /**
* Find the strong component containing the given node. * Find the strong component containing the given node.
* *
* @param node * @param node
* *
* @return The strong component containing the given node. * @return The strong component containing the given node.
*/ */
protected void findAndAddStrongComponent(Node v) { protected void findAndAddStrongComponent(Node v) {
// Update node info, index and push the node. // Update node info, index and push the node.
indexes[v.getId()] = index; indexes[v.getId()] = index;
lowlink[v.getId()] = index; lowlink[v.getId()] = index;
index += 1; index += 1;
pushNode(v); pushNode(v);
for (Arc a: v.getSuccessors()) { for (Arc a: v.getSuccessors()) {
Node w = a.getDestination(); Node w = a.getDestination();
if (!hasBeenVisited(w)) { if (!hasBeenVisited(w)) {
findAndAddStrongComponent(w); findAndAddStrongComponent(w);
lowlink[v.getId()] = Math.min(lowlink[v.getId()], lowlink[w.getId()]); lowlink[v.getId()] = Math.min(lowlink[v.getId()], lowlink[w.getId()]);
} }
else if (isInStack(w)) { else if (isInStack(w)) {
lowlink[v.getId()] = Math.min(lowlink[v.getId()], indexes[w.getId()]); lowlink[v.getId()] = Math.min(lowlink[v.getId()], indexes[w.getId()]);
} }
} }
// Compute the component (if any) // Compute the component (if any)
if (lowlink[v.getId()] == indexes[v.getId()]) { if (lowlink[v.getId()] == indexes[v.getId()]) {
ArrayList<Node> component = new ArrayList<Node>(); ArrayList<Node> component = new ArrayList<Node>();
Node w; Node w;
do { do {
w = popNode(); w = popNode();
component.add(w); component.add(w);
} while (!w.equals(v)); } while (!w.equals(v));
components.add(component); components.add(component);
System.out.println("Size of the stack: " + stack.size()); System.out.println("Size of the stack: " + stack.size());
} }
} }
/** /**
* Check if the given node has not been visited yet. * Check if the given node has not been visited yet.
* *
* @return true if the node has been visited. * @return true if the node has been visited.
*/ */
protected boolean hasBeenVisited(Node node) { protected boolean hasBeenVisited(Node node) {
return this.indexes[node.getId()] != UNDEFINED; return this.indexes[node.getId()] != UNDEFINED;
} }
@Override @Override
protected StronglyConnectedComponentsSolution doRun() { protected StronglyConnectedComponentsSolution doRun() {
Graph graph = getInputData().getGraph(); Graph graph = getInputData().getGraph();
components = new ArrayList<ArrayList<Node>>(); components = new ArrayList<ArrayList<Node>>();
// Initialize everything // Initialize everything
final int nbNodes = graph.getNodes().size(); final int nbNodes = graph.getNodes().size();
stack = new Stack<Node>(); stack = new Stack<Node>();
inStack = new boolean[nbNodes]; inStack = new boolean[nbNodes];
// Current index. // Current index.
index = 0; index = 0;
// Information of nodes // Information of nodes
indexes = new int[nbNodes]; indexes = new int[nbNodes];
Arrays.fill(indexes, UNDEFINED); Arrays.fill(indexes, UNDEFINED);
lowlink = new int[nbNodes]; lowlink = new int[nbNodes];
// Find components // Find components
for (Node node: graph.getNodes()) { for (Node node: graph.getNodes()) {
if (!hasBeenVisited(node)) { if (!hasBeenVisited(node)) {
findAndAddStrongComponent(node); findAndAddStrongComponent(node);
} }
} }
return new StronglyConnectedComponentsSolution(getInputData(), Status.OPTIMAL, components); return new StronglyConnectedComponentsSolution(getInputData(), Status.OPTIMAL, components);
} }
} }

View File

@ -13,15 +13,14 @@ import org.insa.graph.Arc;
import org.insa.graph.Graph; import org.insa.graph.Graph;
import org.insa.graph.Node; import org.insa.graph.Node;
public class WeaklyConnectedComponentsAlgorithm extends AbstractAlgorithm<WeaklyConnectedComponentObserver> { public class WeaklyConnectedComponentsAlgorithm
extends AbstractAlgorithm<WeaklyConnectedComponentObserver> {
/** /**
* * @param data
* @param instance
* @param logOutput
*/ */
public WeaklyConnectedComponentsAlgorithm(WeaklyConnectedComponentsData instance) { public WeaklyConnectedComponentsAlgorithm(WeaklyConnectedComponentsData data) {
super(instance); super(data);
} }
@Override @Override
@ -70,7 +69,7 @@ public class WeaklyConnectedComponentsAlgorithm extends AbstractAlgorithm<Weakly
/** /**
* @return An adjacency list for the undirected graph equivalent to the stored * @return An adjacency list for the undirected graph equivalent to the stored
* graph. * graph.
*/ */
protected ArrayList<HashSet<Integer>> createUndirectedGraph() { protected ArrayList<HashSet<Integer>> createUndirectedGraph() {
int nNodes = getInputData().getGraph().getNodes().size(); int nNodes = getInputData().getGraph().getNodes().size();

View File

@ -1,9 +1,9 @@
package org.insa.algo.weakconnectivity; package org.insa.algo.weakconnectivity;
import org.insa.algo.AbstractData; import org.insa.algo.AbstractInputData;
import org.insa.graph.Graph; import org.insa.graph.Graph;
public class WeaklyConnectedComponentsData extends AbstractData { public class WeaklyConnectedComponentsData extends AbstractInputData {
/** /**
* *

View File

@ -10,13 +10,13 @@ public class WeaklyConnectedComponentsSolution extends AbstractSolution {
// Components // Components
private ArrayList<ArrayList<Node>> components; private ArrayList<ArrayList<Node>> components;
protected WeaklyConnectedComponentsSolution(WeaklyConnectedComponentsData instance) { protected WeaklyConnectedComponentsSolution(WeaklyConnectedComponentsData data) {
super(instance); super(data);
} }
protected WeaklyConnectedComponentsSolution(WeaklyConnectedComponentsData instance, Status status, protected WeaklyConnectedComponentsSolution(WeaklyConnectedComponentsData data, Status status,
ArrayList<ArrayList<Node>> components) { ArrayList<ArrayList<Node>> components) {
super(instance, status); super(data, status);
this.components = components; this.components = components;
} }

View File

@ -617,9 +617,8 @@ public class MainWindow extends JFrame {
wccItem.addActionListener(baf.createBlockingAction(new ActionListener() { wccItem.addActionListener(baf.createBlockingAction(new ActionListener() {
@Override @Override
public void actionPerformed(ActionEvent e) { public void actionPerformed(ActionEvent e) {
WeaklyConnectedComponentsData instance = new WeaklyConnectedComponentsData(graph);
WeaklyConnectedComponentsAlgorithm algo = new WeaklyConnectedComponentsAlgorithm( WeaklyConnectedComponentsAlgorithm algo = new WeaklyConnectedComponentsAlgorithm(
instance); new WeaklyConnectedComponentsData(graph));
algo.addObserver(new WeaklyConnectedComponentGraphicObserver(drawing)); algo.addObserver(new WeaklyConnectedComponentGraphicObserver(drawing));
algo.addObserver(new WeaklyConnectedComponentTextObserver(printStream)); algo.addObserver(new WeaklyConnectedComponentTextObserver(printStream));
launchThread(new Runnable() { launchThread(new Runnable() {