Refactoring
* rewritten marks (more performance for multiple vertices) * fixed a bunch of instructions * added a starting point for save/load graph instructions
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -129,3 +129,4 @@ local.properties
|
||||
.project
|
||||
*.iml
|
||||
.classpath
|
||||
/.gradle/
|
||||
|
||||
15
build.gradle
Normal file
15
build.gradle
Normal file
@@ -0,0 +1,15 @@
|
||||
apply plugin: 'java'
|
||||
apply plugin: 'eclipse'
|
||||
|
||||
version='1.0-SNAPSHOT'
|
||||
|
||||
repositories {
|
||||
mavenCentral()
|
||||
}
|
||||
|
||||
dependencies {
|
||||
compile group: 'com.google.code.gson', name: 'gson', version: '2.8.5'
|
||||
|
||||
compile group: 'commons-collections', name: 'commons-collections', version: '3.2'
|
||||
testCompile group: 'junit', name: 'junit', version: '4.+'
|
||||
}
|
||||
@@ -1,13 +1,19 @@
|
||||
package berack96.sim.util.graph;
|
||||
|
||||
import berack96.sim.util.graph.visit.VisitInfo;
|
||||
import berack96.sim.util.graph.visit.VisitStrategy;
|
||||
|
||||
import java.io.FileReader;
|
||||
import java.io.FileWriter;
|
||||
import java.io.IOException;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
|
||||
import berack96.sim.util.graph.visit.VisitInfo;
|
||||
import berack96.sim.util.graph.visit.VisitStrategy;
|
||||
|
||||
/**
|
||||
* An interface for the graphs.<br>
|
||||
* This interface is used for the graphs with Directed edges.<br>
|
||||
@@ -508,15 +514,15 @@ public interface Graph<V, W extends Number> extends Iterable<V> {
|
||||
Graph<V, W> subGraph(V source, int depth) throws NullPointerException, IllegalArgumentException;
|
||||
|
||||
/**
|
||||
* Get a sub-graph of the current one with only the vertex marked with the selected marker.<br>
|
||||
* Get a sub-graph of the current one with only the vertex marked with the selected markers.<br>
|
||||
* Each vertex will have all his edges, but only the ones with the destination marked with the same marker.<br>
|
||||
* If the marker is null then the returning graph will have all the vertices that are not marked by any marker.<br>
|
||||
* If the graph doesn't contain any vertex with that marker then an empty graph is returned.
|
||||
*
|
||||
* @param marker the marker
|
||||
* @param marker one or more markers
|
||||
* @return a sub-graph of the current graph
|
||||
*/
|
||||
Graph<V, W> subGraph(Object marker);
|
||||
Graph<V, W> subGraph(Object...marker);
|
||||
|
||||
/**
|
||||
* Get the minimum path from the source vertex to the destination vertex.<br>
|
||||
@@ -541,6 +547,35 @@ public interface Graph<V, W extends Number> extends Iterable<V> {
|
||||
*/
|
||||
Map<V, List<Edge<V, W>>> distance(V source) throws NullPointerException, IllegalArgumentException;
|
||||
|
||||
/*
|
||||
static void save(Graph<?, ?> graph, String file) throws IOException {
|
||||
Map<String, Object> map = new HashMap<>();
|
||||
map.put("vertices", graph.vertices());
|
||||
map.put("edges", graph.edges());
|
||||
|
||||
Gson gson = new Gson();
|
||||
FileWriter writer = new FileWriter(file);
|
||||
writer.write(gson.toJson(map));
|
||||
writer.close();
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
static void load(Graph<Object, Number> graph, String file) throws IOException {
|
||||
Gson gson = new Gson();
|
||||
FileReader reader = new FileReader(file);
|
||||
StringBuilder fileContent = new StringBuilder();
|
||||
int c;
|
||||
|
||||
while((c = reader.read()) != -1)
|
||||
fileContent.append(c);
|
||||
reader.close();
|
||||
|
||||
Map<String, Object> map = gson.fromJson(fileContent.toString(), Map.class);
|
||||
graph.addAllVertices((Collection<Object>)map.get("vertices"));
|
||||
graph.addAllEdges((Collection<Edge<Object, Number>>)map.get("edges"));
|
||||
}
|
||||
*/
|
||||
|
||||
// TODO maybe -> STATIC saveOnFile(orString) INSTANCE loadFromFile(orString), but need JSON parser
|
||||
// TODO maybe, but i don't think so... STATIC DISTANCE V* -> V*
|
||||
}
|
||||
|
||||
@@ -30,9 +30,11 @@ public class MapGraph<V, W extends Number> implements Graph<V, W> {
|
||||
private final Map<V, Map<V, W>> edges = new HashMap<>();
|
||||
|
||||
/**
|
||||
* Map that contains the vertex as key and all the marker as the value associated with that vertex.
|
||||
* Map that contains the marker as key and a set of all the vertices that has it as the value.<br>
|
||||
* This map is build like this for performance in creating the marker for multiple vertices.<br>
|
||||
* If you flip the parameters (object and set) then has more performance over the single vertex.
|
||||
*/
|
||||
private final Map<V, Set<Object>> marked = new HashMap<>();
|
||||
private final Map<Object, Set<V>> markers = new HashMap<>();
|
||||
|
||||
/**
|
||||
* Need this variable for not calculating each time the SCC or the cyclic part if the graph doesn't change
|
||||
@@ -42,7 +44,7 @@ public class MapGraph<V, W extends Number> implements Graph<V, W> {
|
||||
/**
|
||||
* Need this variable for not calculating each time the distance from a vertex to all his destinations if the graph doesn't change
|
||||
*/
|
||||
private Map<V, Dijkstra<V, W>> dijkstra = null;
|
||||
private Map<V, Dijkstra<V, W>> dijkstra = new HashMap<>();
|
||||
|
||||
@Override
|
||||
public boolean isCyclic() {
|
||||
@@ -63,8 +65,8 @@ public class MapGraph<V, W extends Number> implements Graph<V, W> {
|
||||
@Override
|
||||
public void addVertex(V vertex) throws NullPointerException {
|
||||
checkNull(vertex);
|
||||
graphChanged();
|
||||
edges.put(vertex, new HashMap<>());
|
||||
graphChanged();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -84,16 +86,18 @@ public class MapGraph<V, W extends Number> implements Graph<V, W> {
|
||||
@Override
|
||||
public void removeVertex(V vertex) throws NullPointerException {
|
||||
if (contains(vertex)) {
|
||||
graphChanged();
|
||||
edges.remove(vertex);
|
||||
edges.forEach((v, map) -> map.remove(vertex));
|
||||
markers.forEach((mark, set) -> set.remove(vertex));
|
||||
graphChanged();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeAllVertex() {
|
||||
graphChanged();
|
||||
edges.clear();
|
||||
markers.clear();
|
||||
graphChanged();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -107,50 +111,51 @@ public class MapGraph<V, W extends Number> implements Graph<V, W> {
|
||||
checkNullAndExist(vertex);
|
||||
checkNull(mark);
|
||||
|
||||
Set<Object> set = marked.computeIfAbsent(vertex, (m) -> new HashSet<>());
|
||||
set.add(mark);
|
||||
Set<V> set = markers.computeIfAbsent(mark, (v) -> new HashSet<>());
|
||||
set.add(vertex);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void unMark(V vertex, Object mark) throws NullPointerException, IllegalArgumentException {
|
||||
checkNullAndExist(vertex);
|
||||
checkNull(mark);
|
||||
marked.get(vertex).remove(mark);
|
||||
markers.get(mark).remove(vertex);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void unMark(V vertex) throws NullPointerException, IllegalArgumentException {
|
||||
checkNullAndExist(vertex);
|
||||
marked.get(vertex).clear();
|
||||
markers.forEach( (mark, set) -> set.remove(vertex) );
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<V> getMarkedWith(Object mark) throws NullPointerException {
|
||||
checkNull(mark);
|
||||
Collection<V> ret = new HashSet<V>();
|
||||
marked.forEach((v, set) -> {
|
||||
if(set.contains(mark))
|
||||
ret.add(v);
|
||||
});
|
||||
|
||||
return ret;
|
||||
return markers.computeIfAbsent(mark, (v) -> new HashSet<>());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<Object> getMarks(V vertex) throws NullPointerException, IllegalArgumentException {
|
||||
public Collection<Object> getMarks(V vertex) throws NullPointerException, IllegalArgumentException {
|
||||
checkNullAndExist(vertex);
|
||||
return marked.computeIfAbsent(vertex, (m) -> new HashSet<>());
|
||||
|
||||
Collection<Object> marks = new HashSet<>();
|
||||
markers.forEach( (mark, set) -> {
|
||||
if (set.contains(vertex))
|
||||
marks.add(mark);
|
||||
});
|
||||
|
||||
return marks;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void unMarkAll(Object mark) {
|
||||
checkNull(mark);
|
||||
marked.forEach((v, m) -> m.remove(mark));
|
||||
markers.remove(mark);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void unMarkAll() {
|
||||
marked.clear();
|
||||
markers.clear();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -159,8 +164,9 @@ public class MapGraph<V, W extends Number> implements Graph<V, W> {
|
||||
checkNullAndExist(vertex2);
|
||||
checkNull(weight);
|
||||
|
||||
W old = edges.get(vertex1).put(vertex2, weight);
|
||||
graphChanged();
|
||||
return edges.get(vertex1).put(vertex2, weight);
|
||||
return old;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -198,24 +204,24 @@ public class MapGraph<V, W extends Number> implements Graph<V, W> {
|
||||
checkNullAndExist(vertex1);
|
||||
checkNullAndExist(vertex2);
|
||||
|
||||
graphChanged();
|
||||
edges.get(vertex1).remove(vertex2);
|
||||
graphChanged();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeAllInEdge(V vertex) throws NullPointerException, IllegalArgumentException {
|
||||
checkNullAndExist(vertex);
|
||||
|
||||
graphChanged();
|
||||
edges.forEach((v, map) -> map.remove(vertex));
|
||||
graphChanged();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeAllOutEdge(V vertex) throws NullPointerException, IllegalArgumentException {
|
||||
checkNullAndExist(vertex);
|
||||
|
||||
graphChanged();
|
||||
edges.put(vertex, new HashMap<>());
|
||||
graphChanged();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -227,8 +233,8 @@ public class MapGraph<V, W extends Number> implements Graph<V, W> {
|
||||
|
||||
@Override
|
||||
public void removeAllEdge() {
|
||||
graphChanged();
|
||||
edges.forEach((v, map) -> map.clear());
|
||||
graphChanged();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -237,19 +243,19 @@ public class MapGraph<V, W extends Number> implements Graph<V, W> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<V> vertices() {
|
||||
public Collection<V> vertices() {
|
||||
return new HashSet<>(edges.keySet());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<Edge<V, W>> edges() {
|
||||
public Collection<Edge<V, W>> edges() {
|
||||
Set<Edge<V, W>> allEdges = new HashSet<>();
|
||||
edges.forEach((source, map) -> map.forEach((destination, weight) -> allEdges.add(new Edge<>(source, destination, weight))));
|
||||
return allEdges;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<Edge<V, W>> edgesOf(V vertex) throws NullPointerException, IllegalArgumentException {
|
||||
public Collection<Edge<V, W>> edgesOf(V vertex) throws NullPointerException, IllegalArgumentException {
|
||||
checkNullAndExist(vertex);
|
||||
|
||||
Set<Edge<V, W>> set = new HashSet<>();
|
||||
@@ -282,14 +288,14 @@ public class MapGraph<V, W extends Number> implements Graph<V, W> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<V> getChildren(V vertex) throws NullPointerException, IllegalArgumentException {
|
||||
public Collection<V> getChildren(V vertex) throws NullPointerException, IllegalArgumentException {
|
||||
checkNullAndExist(vertex);
|
||||
|
||||
return new HashSet<>(edges.get(vertex).keySet());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<V> getAncestors(V vertex) throws NullPointerException, IllegalArgumentException {
|
||||
public Collection<V> getAncestors(V vertex) throws NullPointerException, IllegalArgumentException {
|
||||
checkNullAndExist(vertex);
|
||||
|
||||
Set<V> set = new HashSet<>();
|
||||
@@ -406,32 +412,36 @@ public class MapGraph<V, W extends Number> implements Graph<V, W> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Graph<V, W> subGraph(final Object marker) {
|
||||
final Graph<V, W> graph = new MapGraph<>();
|
||||
public Graph<V, W> subGraph(final Object...marker) {
|
||||
final Graph<V, W> sub = new MapGraph<>();
|
||||
final Set<V> allVertices = new HashSet<>();
|
||||
final Set<Object> allMarkers = new HashSet<>();
|
||||
|
||||
if (marker != null)
|
||||
for (Object mark: marker)
|
||||
allMarkers.add(mark);
|
||||
|
||||
marked.forEach((vertex, mark) -> {
|
||||
if (mark.contains(marker) || (marker == null && !mark.isEmpty()))
|
||||
allVertices.add(vertex);
|
||||
markers.forEach( (mark, set) -> {
|
||||
if (marker == null || allMarkers.contains(mark))
|
||||
allVertices.addAll(set);
|
||||
});
|
||||
|
||||
|
||||
if (marker == null) {
|
||||
Collection<V> toAdd = graph.vertices();
|
||||
Collection<V> toAdd = vertices();
|
||||
toAdd.removeAll(allVertices);
|
||||
allVertices.clear();
|
||||
allVertices.addAll(toAdd);
|
||||
}
|
||||
|
||||
graph.addAllVertices(allVertices);
|
||||
for (V vertex : graph.vertices())
|
||||
getEdgesOut(vertex).forEach((edge) -> {
|
||||
sub.addAllVertices(allVertices);
|
||||
for (V vertex : sub.vertices())
|
||||
edges.get(vertex).forEach( (dest, weight) -> {
|
||||
try {
|
||||
graph.addEdge(edge);
|
||||
} catch (Exception ignored) {
|
||||
}
|
||||
sub.addEdge(vertex, dest, weight);
|
||||
} catch (Exception ignored) {}
|
||||
});
|
||||
|
||||
return graph;
|
||||
return sub;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -439,7 +449,7 @@ public class MapGraph<V, W extends Number> implements Graph<V, W> {
|
||||
checkNullAndExist(source);
|
||||
checkNullAndExist(destination);
|
||||
|
||||
Dijkstra<V, W> dijkstra = getDijkstra(source);
|
||||
Dijkstra<V, W> dijkstra = getDijkstra(source); /* Cached */
|
||||
List<Edge<V, W>> path = dijkstra.getLastDistance().get(destination);
|
||||
if (path == null)
|
||||
throw new UnsupportedOperationException(NOT_CONNECTED);
|
||||
@@ -449,7 +459,7 @@ public class MapGraph<V, W extends Number> implements Graph<V, W> {
|
||||
@Override
|
||||
public Map<V, List<Edge<V, W>>> distance(V source) throws NullPointerException, IllegalArgumentException {
|
||||
checkNullAndExist(source);
|
||||
return new HashMap<>(getDijkstra(source).getLastDistance());
|
||||
return new HashMap<>(getDijkstra(source).getLastDistance()); /* Cached */
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -459,16 +469,20 @@ public class MapGraph<V, W extends Number> implements Graph<V, W> {
|
||||
|
||||
|
||||
/**
|
||||
* Simple function that set all the memory vars at null if the graph changed
|
||||
* Simple function that reset all the caching variables if the graph changed
|
||||
*/
|
||||
private void graphChanged() {
|
||||
tarjan = null;
|
||||
dijkstra = null;
|
||||
dijkstra.clear();
|
||||
}
|
||||
|
||||
/**
|
||||
* Simple function that return the result of the Dijkstra visit, with the starting point as source.<br>
|
||||
* It also cache it, so multiple call will return always the same value unless the graph has changed.
|
||||
* @param source the source of the visit
|
||||
* @return the complete visit
|
||||
*/
|
||||
private Dijkstra<V, W> getDijkstra(V source) {
|
||||
if (dijkstra == null)
|
||||
dijkstra = new HashMap<>();
|
||||
if (dijkstra.get(source) == null) {
|
||||
Dijkstra<V, W> newDijkstra = new Dijkstra<>();
|
||||
newDijkstra.visit(this, source, null);
|
||||
@@ -478,6 +492,11 @@ public class MapGraph<V, W extends Number> implements Graph<V, W> {
|
||||
return dijkstra.get(source);
|
||||
}
|
||||
|
||||
/**
|
||||
* Simple function that return the result of the Tarjan visit.<br>
|
||||
* It also cache it, so multiple call will return always the same value unless the graph has changed.
|
||||
* @return the tarjan visit
|
||||
*/
|
||||
private Tarjan<V, W> getTarjan() {
|
||||
if (tarjan == null) {
|
||||
tarjan = new Tarjan<>();
|
||||
@@ -487,11 +506,21 @@ public class MapGraph<V, W extends Number> implements Graph<V, W> {
|
||||
return tarjan;
|
||||
}
|
||||
|
||||
/**
|
||||
* Test if the object passed is null.
|
||||
* If it is throw an exception.
|
||||
* @param object the object to test
|
||||
*/
|
||||
private void checkNull(Object object) {
|
||||
if (object == null)
|
||||
throw new NullPointerException(PARAM_NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the vertex passed is null and if exist in the graph.
|
||||
* If not then throws eventual exception
|
||||
* @param vertex the vertex to test
|
||||
*/
|
||||
private void checkNullAndExist(V vertex) {
|
||||
checkNull(vertex);
|
||||
if (!edges.containsKey(vertex))
|
||||
|
||||
@@ -1,17 +1,34 @@
|
||||
package berack96.sim.util.graph.view;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.Component;
|
||||
import java.awt.GridLayout;
|
||||
import java.awt.event.ItemEvent;
|
||||
import java.io.File;
|
||||
import java.io.FileWriter;
|
||||
import java.io.IOException;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.swing.BorderFactory;
|
||||
import javax.swing.BoxLayout;
|
||||
import javax.swing.JButton;
|
||||
import javax.swing.JComboBox;
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.JTextField;
|
||||
import javax.swing.border.BevelBorder;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
|
||||
import berack96.sim.util.graph.Graph;
|
||||
import berack96.sim.util.graph.view.edge.EdgeListener;
|
||||
import berack96.sim.util.graph.view.vertex.VertexListener;
|
||||
import berack96.sim.util.graph.visit.VisitStrategy;
|
||||
|
||||
import javax.swing.*;
|
||||
import javax.swing.border.BevelBorder;
|
||||
import java.awt.*;
|
||||
import java.awt.event.ItemEvent;
|
||||
import java.util.*;
|
||||
import java.util.List;
|
||||
|
||||
public class GraphInfo<V, W extends Number> extends JPanel {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
@@ -122,10 +139,40 @@ public class GraphInfo<V, W extends Number> extends JPanel {
|
||||
panelVertex.setOpaque(false);
|
||||
panelVertex.setLayout(new GridLayout(components.size()/2, 2, 2*2, 2*2));
|
||||
components.forEach(panelVertex::add);
|
||||
components.clear();
|
||||
|
||||
/* Save/Load
|
||||
JPanel panelSave = new JPanel(); */
|
||||
|
||||
/* SAVE/LOAD */
|
||||
/*
|
||||
JTextField fileText = new JTextField();
|
||||
JButton saveB = new JButton("Save");
|
||||
saveB.addActionListener(a -> {
|
||||
try {
|
||||
Graph.save(graphPanel.getGraph(), fileText.getText());
|
||||
} catch (IOException e1) {
|
||||
e1.printStackTrace();
|
||||
}
|
||||
});
|
||||
JButton loadB = new JButton("Load");
|
||||
loadB.addActionListener(a -> {
|
||||
try {
|
||||
Graph<V, W> graph = graphPanel.getGraph();
|
||||
Graph.load((Graph<Object, Number>) graph, fileText.getText());
|
||||
} catch (IOException e1) {
|
||||
e1.printStackTrace();
|
||||
}
|
||||
});
|
||||
components.add(new JLabel("File to save/load: "));
|
||||
components.add(fileText);
|
||||
components.add(saveB);
|
||||
components.add(loadB);
|
||||
|
||||
JPanel panelSave = new JPanel();
|
||||
panelSave.setOpaque(false);
|
||||
panelSave.setBorder(BorderFactory.createLineBorder(Color.RED));
|
||||
panelSave.setLayout(new GridLayout(components.size()/2, 2, 2*2, 2*2));
|
||||
components.forEach(panelSave::add);
|
||||
components.clear();
|
||||
*/
|
||||
|
||||
/* ADDING COMPONENTS */
|
||||
this.setBackground(Color.LIGHT_GRAY);
|
||||
@@ -135,7 +182,7 @@ public class GraphInfo<V, W extends Number> extends JPanel {
|
||||
this.add(panelDescription);
|
||||
this.add(panelInfo);
|
||||
this.add(panelVertex);
|
||||
this.add(Box.createVerticalGlue());
|
||||
/*this.add(panelSave);*/
|
||||
|
||||
modVertex.doClick();
|
||||
|
||||
|
||||
@@ -50,7 +50,6 @@ public class GraphWindow<V, W extends Number> extends JFrame {
|
||||
|
||||
this.infoPanel = new GraphInfo<>(graphPanel, vListener, eListener, strats);
|
||||
this.graphPanel = graphPanel;
|
||||
|
||||
this.add(infoPanel, BorderLayout.EAST);
|
||||
this.add(graphPanel);
|
||||
}
|
||||
|
||||
@@ -1022,11 +1022,11 @@ public class TestGraph {
|
||||
/*
|
||||
* This graph should be like this
|
||||
*
|
||||
* 1 -> 2 <- 6
|
||||
* ^
|
||||
* | | |
|
||||
* 1 -> 2 <- 6 7
|
||||
* ^ ^
|
||||
* | | | |
|
||||
* v v
|
||||
* 3 <- 5 -> 4
|
||||
* 3 <- 5 -> 4 8
|
||||
*/
|
||||
|
||||
graph.addVertexIfAbsent("1");
|
||||
@@ -1035,6 +1035,8 @@ public class TestGraph {
|
||||
graph.addVertexIfAbsent("4");
|
||||
graph.addVertexIfAbsent("5");
|
||||
graph.addVertexIfAbsent("6");
|
||||
graph.addVertexIfAbsent("7");
|
||||
graph.addVertexIfAbsent("8");
|
||||
|
||||
graph.addEdge("1", "2", 1);
|
||||
graph.addEdge("1", "3", 1);
|
||||
@@ -1043,6 +1045,7 @@ public class TestGraph {
|
||||
graph.addEdge("5", "3", 2);
|
||||
graph.addEdge("5", "4", 5);
|
||||
graph.addEdge("6", "2", 2);
|
||||
graph.addEdge("8", "7", 9);
|
||||
|
||||
graph.mark("1", "blue");
|
||||
graph.mark("3", "blue");
|
||||
@@ -1104,14 +1107,14 @@ public class TestGraph {
|
||||
|
||||
/* MARKED */
|
||||
sub = graph.subGraph("z");
|
||||
shouldContain(sub.vertices(), "1", "2", "5", "4");
|
||||
shouldContain(sub.vertices(), "1", "2", "4", "5");
|
||||
shouldContain(sub.edges(),
|
||||
new Edge<>("1", "2", 1),
|
||||
new Edge<>("2", "5", 4),
|
||||
new Edge<>("5", "4", 5));
|
||||
|
||||
sub = graph.subGraph("circle");
|
||||
shouldContain(sub.vertices(), "2", "5", "4", "6");
|
||||
shouldContain(sub.vertices(), "2", "4", "5", "6");
|
||||
shouldContain(sub.edges(),
|
||||
new Edge<>("2", "5", 4),
|
||||
new Edge<>("4", "6", 6),
|
||||
@@ -1129,6 +1132,21 @@ public class TestGraph {
|
||||
shouldContain(sub.edges(),
|
||||
new Edge<>("4", "6", 6),
|
||||
new Edge<>("6", "2", 2));
|
||||
|
||||
sub = graph.subGraph("blue", "circle");
|
||||
shouldContain(sub.vertices(), "1", "2", "3", "4", "5", "6");
|
||||
shouldContain(sub.edges(),
|
||||
new Edge<>("1", "2", 1),
|
||||
new Edge<>("1", "3", 1),
|
||||
new Edge<>("2", "5", 4),
|
||||
new Edge<>("4", "6", 6),
|
||||
new Edge<>("5", "3", 2),
|
||||
new Edge<>("5", "4", 5),
|
||||
new Edge<>("6", "2", 2));
|
||||
|
||||
sub = graph.subGraph(null);
|
||||
shouldContain(sub.vertices(), "7", "8");
|
||||
shouldContain(sub.edges(), new Edge<>("8", "7", 9));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
Reference in New Issue
Block a user