add stylecheck and spotbugs
This commit is contained in:
parent
828cec3f1e
commit
338d172893
6 changed files with 1168 additions and 639 deletions
|
|
@ -12,289 +12,353 @@ import java.util.PriorityQueue;
|
|||
import java.util.Random;
|
||||
import java.util.function.Function;
|
||||
|
||||
/**
|
||||
* Core class for impl graph.
|
||||
*/
|
||||
public class Graph {
|
||||
|
||||
public record EdgeRecord(String node1, String node2, int weight) {
|
||||
private final Map<String, Node> nodes;
|
||||
private Map<Node, Double> pageRanks;
|
||||
|
||||
/**
|
||||
* Initial func of Graph.
|
||||
*
|
||||
* @param input input text
|
||||
* @param d d of page rank
|
||||
*/
|
||||
public Graph(final String input, final double d) {
|
||||
nodes = new HashMap<>();
|
||||
parse(input);
|
||||
initRageRanks(d);
|
||||
}
|
||||
|
||||
/**
|
||||
* Initial func of Graph with default d.
|
||||
*
|
||||
* @param input input text
|
||||
*/
|
||||
public Graph(final String input) {
|
||||
nodes = new HashMap<>();
|
||||
parse(input);
|
||||
initRageRanks(0.85);
|
||||
}
|
||||
|
||||
/**
|
||||
* Find bridge words.
|
||||
*
|
||||
* @param word1 first word
|
||||
* @param word2 second word
|
||||
* @return list of bridge words
|
||||
*/
|
||||
public Optional<List<String>> findBridgeWords(final String word1, final String word2) {
|
||||
final Node node1 = nodes.get(word1.toLowerCase(Locale.ENGLISH));
|
||||
final Node node2 = nodes.get(word2.toLowerCase(Locale.ENGLISH));
|
||||
|
||||
if (node1 == null || node2 == null) {
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
private static class Node {
|
||||
final var bridgeWords = new ArrayList<String>();
|
||||
for (final var node : node1.edges.keySet()) {
|
||||
if (node.edges.containsKey(node2)) {
|
||||
bridgeWords.add(node.id);
|
||||
}
|
||||
}
|
||||
return Optional.of(bridgeWords);
|
||||
}
|
||||
|
||||
String id;
|
||||
Map<Node, Integer> edges;
|
||||
/**
|
||||
* Find the shortest path between two words.
|
||||
*
|
||||
* @param word1 first word
|
||||
* @param word2 second word
|
||||
* @return list of the words in the path
|
||||
*/
|
||||
public Optional<List<String>> findShortestPath(final String word1, final String word2) {
|
||||
final var startWord = word1.toLowerCase(Locale.ENGLISH);
|
||||
final var endWord = word2.toLowerCase(Locale.ENGLISH);
|
||||
final var path = new ArrayList<String>();
|
||||
|
||||
Node(final String id) {
|
||||
this.id = id;
|
||||
this.edges = new HashMap<>();
|
||||
}
|
||||
|
||||
void addEdge(final Node target) {
|
||||
edges.put(target, edges.getOrDefault(target, 0) + 1);
|
||||
}
|
||||
|
||||
List<String> getDOTEdges(final Function<EdgeRecord, String> callback) {
|
||||
final var dotEdges = new ArrayList<String>();
|
||||
for (final var entry : edges.entrySet()) {
|
||||
final Node target = entry.getKey();
|
||||
final int weight = entry.getValue();
|
||||
dotEdges.add(
|
||||
callback.apply(new EdgeRecord(id, target.id, weight)) + ";\n");
|
||||
}
|
||||
return dotEdges;
|
||||
}
|
||||
|
||||
List<String> getDOTEdges() {
|
||||
final var dotEdges = new ArrayList<String>();
|
||||
for (final var entry : edges.entrySet()) {
|
||||
final Node target = entry.getKey();
|
||||
final int weight = entry.getValue();
|
||||
dotEdges.add(
|
||||
String.format("%s -> %s [label=\"%d\"];\n", id, target.id, weight));
|
||||
}
|
||||
return dotEdges;
|
||||
}
|
||||
if (!nodes.containsKey(startWord) || !nodes.containsKey(endWord)) {
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
private final Map<String, Node> nodes;
|
||||
final Node startNode = nodes.get(startWord);
|
||||
final Node endNode = nodes.get(endWord);
|
||||
|
||||
private Map<Node, Double> pageRanks;
|
||||
|
||||
public Graph(final String input, final double d) {
|
||||
nodes = new HashMap<>();
|
||||
parse(input);
|
||||
initRageRanks(d);
|
||||
if (startNode == endNode) {
|
||||
path.add(startNode.id);
|
||||
return Optional.of(path);
|
||||
}
|
||||
|
||||
public Graph(final String input) {
|
||||
nodes = new HashMap<>();
|
||||
parse(input);
|
||||
initRageRanks(0.85);
|
||||
final var distances = new HashMap<Node, Integer>();
|
||||
final var previousNodes = new HashMap<Node, Node>();
|
||||
final var queue = new PriorityQueue<Node>(
|
||||
Comparator.comparingInt(node -> distances.getOrDefault(node, Integer.MAX_VALUE)));
|
||||
|
||||
for (final var node : nodes.values()) {
|
||||
distances.put(node, Integer.MAX_VALUE);
|
||||
}
|
||||
distances.put(startNode, 0);
|
||||
queue.add(startNode);
|
||||
|
||||
while (!queue.isEmpty()) {
|
||||
final Node current = queue.poll();
|
||||
for (final var edge : current.edges.entrySet()) {
|
||||
final Node neighbor = edge.getKey();
|
||||
final int weight = edge.getValue();
|
||||
|
||||
final int newDist = distances.get(current) + weight;
|
||||
if (newDist < distances.get(neighbor)) {
|
||||
distances.put(neighbor, newDist);
|
||||
previousNodes.put(neighbor, current);
|
||||
queue.add(neighbor);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public Optional<List<String>> findBridgeWords(final String word1, final String word2) {
|
||||
final Node node1 = nodes.get(word1.toLowerCase(Locale.ENGLISH));
|
||||
final Node node2 = nodes.get(word2.toLowerCase(Locale.ENGLISH));
|
||||
|
||||
if (node1 == null || node2 == null) {
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
final var bridgeWords = new ArrayList<String>();
|
||||
for (final var node : node1.edges.keySet()) {
|
||||
if (node.edges.containsKey(node2)) {
|
||||
bridgeWords.add(node.id);
|
||||
}
|
||||
}
|
||||
return Optional.of(bridgeWords);
|
||||
if (distances.get(endNode) == Integer.MAX_VALUE) {
|
||||
return Optional.of(path);
|
||||
}
|
||||
|
||||
public Optional<List<String>> findShortestPath(final String word1, final String word2) {
|
||||
final var startWord = word1.toLowerCase(Locale.ENGLISH);
|
||||
final var endWord = word2.toLowerCase(Locale.ENGLISH);
|
||||
final var path = new ArrayList<String>();
|
||||
|
||||
if (!nodes.containsKey(startWord) || !nodes.containsKey(endWord)) {
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
final Node startNode = nodes.get(startWord);
|
||||
final Node endNode = nodes.get(endWord);
|
||||
|
||||
if (startNode == endNode) {
|
||||
path.add(startNode.id);
|
||||
return Optional.of(path);
|
||||
}
|
||||
|
||||
final var distances = new HashMap<Node, Integer>();
|
||||
final var previousNodes = new HashMap<Node, Node>();
|
||||
final var queue = new PriorityQueue<Node>(
|
||||
Comparator.comparingInt(node -> distances.getOrDefault(node, Integer.MAX_VALUE)));
|
||||
|
||||
for (final var node : nodes.values()) {
|
||||
distances.put(node, Integer.MAX_VALUE);
|
||||
}
|
||||
distances.put(startNode, 0);
|
||||
queue.add(startNode);
|
||||
|
||||
while (!queue.isEmpty()) {
|
||||
final Node current = queue.poll();
|
||||
for (final var edge : current.edges.entrySet()) {
|
||||
final Node neighbor = edge.getKey();
|
||||
final int weight = edge.getValue();
|
||||
|
||||
final int newDist = distances.get(current) + weight;
|
||||
if (newDist < distances.get(neighbor)) {
|
||||
distances.put(neighbor, newDist);
|
||||
previousNodes.put(neighbor, current);
|
||||
queue.add(neighbor);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (distances.get(endNode) == Integer.MAX_VALUE) {
|
||||
return Optional.of(path);
|
||||
}
|
||||
|
||||
final var reversePath = new LinkedList<String>();
|
||||
Node current = endNode;
|
||||
while (current != null) {
|
||||
reversePath.addFirst(current.id);
|
||||
current = previousNodes.get(current);
|
||||
}
|
||||
|
||||
return Optional.of(reversePath);
|
||||
final var reversePath = new LinkedList<String>();
|
||||
Node current = endNode;
|
||||
while (current != null) {
|
||||
reversePath.addFirst(current.id);
|
||||
current = previousNodes.get(current);
|
||||
}
|
||||
|
||||
public double computePageRank(final String nodeId) {
|
||||
final Node node = nodes.get(nodeId);
|
||||
if (node == null) {
|
||||
return -1.0;
|
||||
}
|
||||
return Optional.of(reversePath);
|
||||
}
|
||||
|
||||
return pageRanks.getOrDefault(node, -1.0);
|
||||
/**
|
||||
* Calculate rage rank.
|
||||
*
|
||||
* @param nodeId id of node
|
||||
* @return page rank
|
||||
*/
|
||||
public double computePageRank(final String nodeId) {
|
||||
final Node node = nodes.get(nodeId);
|
||||
if (node == null) {
|
||||
return -1.0;
|
||||
}
|
||||
|
||||
public List<String> randomWalk() {
|
||||
final var path = new ArrayList<String>();
|
||||
if (nodes.isEmpty()) {
|
||||
return path;
|
||||
}
|
||||
return pageRanks.getOrDefault(node, -1.0);
|
||||
}
|
||||
|
||||
final var random = new Random();
|
||||
final var nodeIds = new ArrayList<>(nodes.keySet());
|
||||
final String startNodeId = nodeIds.get(random.nextInt(nodeIds.size()));
|
||||
path.add(startNodeId);
|
||||
|
||||
final var usedEdges = new HashMap<String, Integer>();
|
||||
var currentNode = nodes.get(startNodeId);
|
||||
while (true) {
|
||||
final var availableEdge = new ArrayList<Map.Entry<Node, Integer>>();
|
||||
int totalWeight = 0;
|
||||
for (final var entry : currentNode.edges.entrySet()) {
|
||||
final String edgeKey = currentNode.id + " -> " + entry.getKey().id;
|
||||
if (usedEdges.getOrDefault(edgeKey, 0) < 2) {
|
||||
availableEdge.add(entry);
|
||||
totalWeight += entry.getValue();
|
||||
}
|
||||
}
|
||||
|
||||
if (availableEdge.isEmpty()) {
|
||||
break;
|
||||
}
|
||||
|
||||
final double randomValue = random.nextDouble() * totalWeight;
|
||||
double cumulative = 0.0;
|
||||
Node nextNode = null;
|
||||
|
||||
for (final var entry : availableEdge) {
|
||||
cumulative += entry.getValue();
|
||||
if (randomValue < cumulative) {
|
||||
nextNode = entry.getKey();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
assert nextNode != null;
|
||||
final String edgeKey = currentNode.id + " -> " + nextNode.id;
|
||||
final int edgeTimes = usedEdges.getOrDefault(edgeKey, 0) + 1;
|
||||
usedEdges.put(edgeKey, edgeTimes);
|
||||
path.add(nextNode.id);
|
||||
currentNode = nextNode;
|
||||
|
||||
if (edgeTimes >= 2) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return path;
|
||||
/**
|
||||
* Random walk.
|
||||
*
|
||||
* @return list of words in the walk path
|
||||
*/
|
||||
@edu.umd.cs.findbugs.annotations.SuppressFBWarnings("PREDICTABLE_RANDOM")
|
||||
public List<String> randomWalk() {
|
||||
final var path = new ArrayList<String>();
|
||||
if (nodes.isEmpty()) {
|
||||
return path;
|
||||
}
|
||||
|
||||
public String toDOT(final Function<EdgeRecord, String> callback) {
|
||||
final var sb = new StringBuilder();
|
||||
sb.append("digraph G {\n");
|
||||
for (final Node node : nodes.values()) {
|
||||
for (final String edge : node.getDOTEdges(callback)) {
|
||||
sb.append(" ").append(edge);
|
||||
}
|
||||
final var random = new Random();
|
||||
final var nodeIds = new ArrayList<>(nodes.keySet());
|
||||
final String startNodeId = nodeIds.get(random.nextInt(nodeIds.size()));
|
||||
path.add(startNodeId);
|
||||
|
||||
final var usedEdges = new HashMap<String, Integer>();
|
||||
var currentNode = nodes.get(startNodeId);
|
||||
while (true) {
|
||||
final var availableEdge = new ArrayList<Map.Entry<Node, Integer>>();
|
||||
int totalWeight = 0;
|
||||
for (final var entry : currentNode.edges.entrySet()) {
|
||||
final String edgeKey = currentNode.id + " -> " + entry.getKey().id;
|
||||
if (usedEdges.getOrDefault(edgeKey, 0) < 2) {
|
||||
availableEdge.add(entry);
|
||||
totalWeight += entry.getValue();
|
||||
}
|
||||
sb.append("}");
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
if (availableEdge.isEmpty()) {
|
||||
break;
|
||||
}
|
||||
|
||||
final double randomValue = random.nextDouble() * totalWeight;
|
||||
double cumulative = 0.0;
|
||||
Node nextNode = null;
|
||||
|
||||
for (final var entry : availableEdge) {
|
||||
cumulative += entry.getValue();
|
||||
if (randomValue < cumulative) {
|
||||
nextNode = entry.getKey();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
assert nextNode != null;
|
||||
final String edgeKey = currentNode.id + " -> " + nextNode.id;
|
||||
final int edgeTimes = usedEdges.getOrDefault(edgeKey, 0) + 1;
|
||||
usedEdges.put(edgeKey, edgeTimes);
|
||||
path.add(nextNode.id);
|
||||
currentNode = nextNode;
|
||||
|
||||
if (edgeTimes >= 2) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return path;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate DOT lang to describe the graph.
|
||||
*
|
||||
* @param callback function to modify the option of the node
|
||||
* @return string of DOT lang
|
||||
*/
|
||||
@SuppressWarnings("checkstyle:AbbreviationAsWordInName")
|
||||
public String toDOT(final Function<EdgeRecord, String> callback) {
|
||||
final var sb = new StringBuilder();
|
||||
sb.append("digraph G {\n");
|
||||
for (final Node node : nodes.values()) {
|
||||
for (final String edge : node.getDOTEdges(callback)) {
|
||||
sb.append(" ").append(edge);
|
||||
}
|
||||
}
|
||||
sb.append("}");
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate DOT lang to describe the graph without callback lambda function.
|
||||
*
|
||||
* @return string of DOT lang
|
||||
*/
|
||||
@SuppressWarnings("checkstyle:AbbreviationAsWordInName")
|
||||
public String toDOT() {
|
||||
final var sb = new StringBuilder();
|
||||
sb.append("digraph G {\n");
|
||||
for (final Node node : nodes.values()) {
|
||||
for (final String edge : node.getDOTEdges()) {
|
||||
sb.append(" ").append(edge);
|
||||
}
|
||||
}
|
||||
sb.append("}");
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
private void parse(final String input) {
|
||||
final String[] tokens = input.toLowerCase(Locale.ENGLISH).split("[ \n\r]+");
|
||||
final var words = new ArrayList<String>();
|
||||
|
||||
for (final var token : tokens) {
|
||||
final String word = token.replaceAll("[^a-zA-Z]", "");
|
||||
if (!word.isEmpty()) {
|
||||
words.add(word);
|
||||
}
|
||||
}
|
||||
|
||||
public String toDOT() {
|
||||
final var sb = new StringBuilder();
|
||||
sb.append("digraph G {\n");
|
||||
for (final Node node : nodes.values()) {
|
||||
for (final String edge : node.getDOTEdges()) {
|
||||
sb.append(" ").append(edge);
|
||||
}
|
||||
}
|
||||
sb.append("}");
|
||||
return sb.toString();
|
||||
for (int i = 0; i < words.size() - 1; i++) {
|
||||
final String currentWord = words.get(i);
|
||||
final String nextWord = words.get(i + 1);
|
||||
|
||||
final Node currentNode = getOrCreateNode(currentWord);
|
||||
final Node nextNode = getOrCreateNode(nextWord);
|
||||
|
||||
currentNode.addEdge(nextNode);
|
||||
}
|
||||
}
|
||||
|
||||
private Node getOrCreateNode(final String word) {
|
||||
return nodes.computeIfAbsent(word, Node::new);
|
||||
}
|
||||
|
||||
private void initRageRanks(final double d) {
|
||||
final int totalNodes = nodes.size();
|
||||
if (totalNodes == 0) {
|
||||
pageRanks = new HashMap<>();
|
||||
return;
|
||||
}
|
||||
var myPageRanks = new HashMap<Node, Double>();
|
||||
final double initRank = 1.0 / totalNodes;
|
||||
for (final var n : nodes.values()) {
|
||||
myPageRanks.put(n, initRank);
|
||||
}
|
||||
|
||||
private void parse(final String input) {
|
||||
final String[] tokens = input.toLowerCase(Locale.ENGLISH).split("[ \n\r]+");
|
||||
final var words = new ArrayList<String>();
|
||||
final int iterations = 100;
|
||||
for (int i = 0; i < iterations; i++) {
|
||||
final var newPageRanks = new HashMap<Node, Double>();
|
||||
nodes.values().forEach(n -> newPageRanks.put(n, 0.0));
|
||||
for (final var curr : nodes.values()) {
|
||||
final int totalEdges = curr.edges.size();
|
||||
|
||||
for (final var token : tokens) {
|
||||
final String word = token.replaceAll("[^a-zA-Z]", "");
|
||||
if (!word.isEmpty()) {
|
||||
words.add(word);
|
||||
}
|
||||
for (final var entry : curr.edges.entrySet()) {
|
||||
final Node neighbor = entry.getKey();
|
||||
final double contribution = myPageRanks.get(curr) / totalEdges;
|
||||
newPageRanks.put(neighbor, newPageRanks.get(neighbor) + contribution);
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < words.size() - 1; i++) {
|
||||
final String currentWord = words.get(i);
|
||||
final String nextWord = words.get(i + 1);
|
||||
|
||||
final Node currentNode = getOrCreateNode(currentWord);
|
||||
final Node nextNode = getOrCreateNode(nextWord);
|
||||
|
||||
currentNode.addEdge(nextNode);
|
||||
}
|
||||
final double damplingTerm = (1.0 - d) / totalNodes;
|
||||
nodes.values().forEach(n -> newPageRanks.put(n, damplingTerm + d * newPageRanks.get(n)));
|
||||
myPageRanks = newPageRanks;
|
||||
}
|
||||
|
||||
private Node getOrCreateNode(final String word) {
|
||||
return nodes.computeIfAbsent(word, Node::new);
|
||||
pageRanks = myPageRanks;
|
||||
for (final var node : nodes.values()) {
|
||||
if (node.edges.isEmpty()) {
|
||||
nodes.values().stream()
|
||||
.filter(n -> !n.equals(node))
|
||||
.forEach(n -> pageRanks
|
||||
.put(n, pageRanks.get(n) + pageRanks.get(node) / (totalNodes - 1)));
|
||||
pageRanks.put(node, 0.0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Record of edge.
|
||||
*
|
||||
* @param node1 fist node
|
||||
* @param node2 second node
|
||||
* @param weight weight of edge
|
||||
*
|
||||
*/
|
||||
public record EdgeRecord(String node1, String node2, int weight) {
|
||||
}
|
||||
|
||||
private static class Node {
|
||||
|
||||
String id;
|
||||
Map<Node, Integer> edges;
|
||||
|
||||
Node(final String id) {
|
||||
this.id = id;
|
||||
this.edges = new HashMap<>();
|
||||
}
|
||||
|
||||
private void initRageRanks(final double d) {
|
||||
final int totalNodes = nodes.size();
|
||||
if (totalNodes == 0) {
|
||||
pageRanks = new HashMap<>();
|
||||
return;
|
||||
}
|
||||
var myPageRanks = new HashMap<Node, Double>();
|
||||
final double initRank = 1.0 / totalNodes;
|
||||
for (final var n : nodes.values()) {
|
||||
myPageRanks.put(n, initRank);
|
||||
}
|
||||
|
||||
final int iterations = 100;
|
||||
for (int i = 0; i < iterations; i++) {
|
||||
final var newPageRanks = new HashMap<Node, Double>();
|
||||
nodes.values().forEach(n -> newPageRanks.put(n, 0.0));
|
||||
for (final var curr : nodes.values()) {
|
||||
final int totalEdges = curr.edges.size();
|
||||
|
||||
for (final var entry : curr.edges.entrySet()) {
|
||||
final Node neighbor = entry.getKey();
|
||||
final double contribution = myPageRanks.get(curr) / totalEdges;
|
||||
newPageRanks.put(neighbor, newPageRanks.get(neighbor) + contribution);
|
||||
}
|
||||
}
|
||||
|
||||
final double damplingTerm = (1.0 - d) / totalNodes;
|
||||
nodes.values().forEach(n -> newPageRanks.put(n, damplingTerm + d * newPageRanks.get(n)));
|
||||
myPageRanks = newPageRanks;
|
||||
}
|
||||
|
||||
pageRanks = myPageRanks;
|
||||
for (final var node : nodes.values()) {
|
||||
if (node.edges.isEmpty()) {
|
||||
nodes.values().stream().filter(n -> !n.equals(node))
|
||||
.forEach(n -> pageRanks.put(n, pageRanks.get(n) + pageRanks.get(node) / (totalNodes - 1)));
|
||||
pageRanks.put(node, 0.0);
|
||||
}
|
||||
}
|
||||
void addEdge(final Node target) {
|
||||
edges.put(target, edges.getOrDefault(target, 0) + 1);
|
||||
}
|
||||
|
||||
@SuppressWarnings("checkstyle:AbbreviationAsWordInName")
|
||||
List<String> getDOTEdges(final Function<EdgeRecord, String> callback) {
|
||||
final var dotEdges = new ArrayList<String>();
|
||||
for (final var entry : edges.entrySet()) {
|
||||
final Node target = entry.getKey();
|
||||
final int weight = entry.getValue();
|
||||
dotEdges.add(
|
||||
callback.apply(new EdgeRecord(id, target.id, weight)) + ";\n");
|
||||
}
|
||||
return dotEdges;
|
||||
}
|
||||
|
||||
@SuppressWarnings("checkstyle:AbbreviationAsWordInName")
|
||||
List<String> getDOTEdges() {
|
||||
final var dotEdges = new ArrayList<String>();
|
||||
for (final var entry : edges.entrySet()) {
|
||||
final Node target = entry.getKey();
|
||||
final int weight = entry.getValue();
|
||||
dotEdges.add(
|
||||
String.format("%s -> %s [label=\"%d\"];%n", id, target.id, weight));
|
||||
}
|
||||
return dotEdges;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
package fun.youthlic;
|
||||
|
||||
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
|
||||
import java.io.BufferedReader;
|
||||
import java.io.BufferedWriter;
|
||||
import java.io.File;
|
||||
import java.io.FileReader;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
|
|
@ -15,324 +15,333 @@ import java.util.Arrays;
|
|||
import java.util.Random;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.IntStream;
|
||||
|
||||
import org.jline.reader.LineReader;
|
||||
import org.jline.reader.LineReaderBuilder;
|
||||
import org.jline.reader.impl.DefaultParser;
|
||||
import org.jline.terminal.Terminal;
|
||||
import org.jline.terminal.TerminalBuilder;
|
||||
|
||||
/**
|
||||
* Class for running in Commandline.
|
||||
*/
|
||||
@SuppressWarnings("ALL")
|
||||
public class GraphCLI {
|
||||
static String readFile(final String filename) {
|
||||
String text = null;
|
||||
try (BufferedReader inputReader = new BufferedReader(new FileReader(new File(filename)))) {
|
||||
text = inputReader.lines().collect(Collectors.joining(System.lineSeparator()));
|
||||
} catch (final IOException e) {
|
||||
System.out.println("Error reading file: " + e.getMessage());
|
||||
}
|
||||
return text;
|
||||
@SuppressFBWarnings({"DM_DEFAULT_ENCODING", "PATH_TRAVERSAL_IN"})
|
||||
static String readFile(final String filename) {
|
||||
String text = null;
|
||||
try (BufferedReader inputReader = new BufferedReader(new FileReader(filename))) {
|
||||
text = inputReader.lines().collect(Collectors.joining(System.lineSeparator()));
|
||||
} catch (final IOException e) {
|
||||
System.out.println("Error reading file: " + e.getMessage());
|
||||
}
|
||||
return text;
|
||||
}
|
||||
|
||||
public static void main(final String[] args) {
|
||||
GraphCLIHelper helper = null;
|
||||
Terminal terminal = null;
|
||||
try {
|
||||
terminal = TerminalBuilder.builder().system(true).build();
|
||||
} catch (final IOException e) {
|
||||
e.printStackTrace();
|
||||
System.exit(-1);
|
||||
}
|
||||
final LineReader reader = LineReaderBuilder.builder().terminal(terminal).parser(new DefaultParser())
|
||||
.build();
|
||||
while (true) {
|
||||
final String line = reader.readLine("graph> ");
|
||||
final var commands = line.split("[ \\t]+");
|
||||
if (commands.length == 0) {
|
||||
continue;
|
||||
}
|
||||
switch (commands[0]) {
|
||||
case "load":
|
||||
if (commands.length != 2) {
|
||||
System.out.println("Usage: load <filename>");
|
||||
} else {
|
||||
final var text = readFile(commands[1]);
|
||||
if (text == null) {
|
||||
System.out.println("Load file failed; " + commands[1]);
|
||||
continue;
|
||||
}
|
||||
helper = new GraphCLIHelper(text);
|
||||
}
|
||||
break;
|
||||
case "help":
|
||||
System.out.println("Available commands:");
|
||||
System.out.println(" show");
|
||||
System.out.println(" dot");
|
||||
System.out.println(" help");
|
||||
System.out.println(" exit");
|
||||
System.out.println(" random-walk");
|
||||
System.out.println(" load <filename>");
|
||||
System.out.println(" page-rank <word>");
|
||||
System.out.println(" bridge-words <word1> <word2>");
|
||||
System.out.println(" new-text <text...>");
|
||||
System.out.println(" shortest-path <word1> <word2>");
|
||||
break;
|
||||
case "shortest-path":
|
||||
if (commands.length != 3) {
|
||||
System.out.println("Usage: shortest-path <word1> <word2>");
|
||||
} else if (helper == null) {
|
||||
System.out.println("No graph loaded");
|
||||
break;
|
||||
} else {
|
||||
try {
|
||||
System.out.println(helper.calcShortestPath(commands[1], commands[2]));
|
||||
} catch (IOException | InterruptedException e) {
|
||||
System.out.println(e.getMessage());
|
||||
}
|
||||
}
|
||||
break;
|
||||
case "exit":
|
||||
return;
|
||||
case "random-walk":
|
||||
if (commands.length != 1) {
|
||||
System.out.println("Usage: random-walk");
|
||||
} else {
|
||||
if (helper == null) {
|
||||
System.out.println("No graph loaded");
|
||||
break;
|
||||
}
|
||||
System.out.println(helper.randomWalk());
|
||||
}
|
||||
break;
|
||||
case "new-text":
|
||||
if (commands.length < 2) {
|
||||
System.out.println("Usage: new-text <text...>");
|
||||
} else if (helper == null) {
|
||||
System.out.println("No graph loaded");
|
||||
break;
|
||||
} else {
|
||||
System.out.println(helper.generateNewText(
|
||||
String.join(" ", Arrays.asList(commands).subList(1, commands.length))));
|
||||
}
|
||||
break;
|
||||
case "show":
|
||||
if (commands.length != 1) {
|
||||
System.out.println("Usage: show");
|
||||
} else {
|
||||
if (helper == null) {
|
||||
System.out.println("No graph loaded");
|
||||
break;
|
||||
}
|
||||
GraphCLIHelper.showDirectedGraph(helper.graph);
|
||||
}
|
||||
break;
|
||||
case "dot":
|
||||
if (commands.length != 1) {
|
||||
System.out.println("Usage: dot");
|
||||
} else {
|
||||
if (helper == null) {
|
||||
System.out.println("No graph loaded");
|
||||
break;
|
||||
}
|
||||
System.out.println(helper.graph.toDOT());
|
||||
}
|
||||
case "page-rank":
|
||||
if (commands.length != 2) {
|
||||
System.out.println("Usage: page-rank <word>");
|
||||
} else if (helper == null) {
|
||||
System.out.println("No graph loaded");
|
||||
} else {
|
||||
final var pageRank = helper.calPageRank(commands[1]);
|
||||
if (pageRank < 0.0) {
|
||||
System.out.println("Invalid word");
|
||||
} else {
|
||||
System.out.println("PageRank of " + commands[1] + ": " + pageRank);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case "bridge-words":
|
||||
if (commands.length != 3) {
|
||||
System.out.println("Usage: bridge-words <word1> <word2>");
|
||||
} else if (helper == null) {
|
||||
System.out.println("No graph loaded");
|
||||
} else {
|
||||
System.out.println(helper.queryBridgeWords(commands[1], commands[2]));
|
||||
}
|
||||
break;
|
||||
default:
|
||||
System.out.println("Unknown command: " + commands[0]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* CommandLine entry point.
|
||||
*
|
||||
* @param args launch args
|
||||
*/
|
||||
public static void main(final String[] args) {
|
||||
GraphCLIHelper helper = null;
|
||||
Terminal terminal = null;
|
||||
try {
|
||||
terminal = TerminalBuilder.builder().system(true).build();
|
||||
} catch (final IOException e) {
|
||||
e.printStackTrace();
|
||||
System.exit(-1);
|
||||
}
|
||||
final LineReader reader = LineReaderBuilder.builder().terminal(terminal)
|
||||
.parser(new DefaultParser())
|
||||
.build();
|
||||
while (true) {
|
||||
final String line = reader.readLine("graph> ");
|
||||
final var commands = line.split("[ \\t]+");
|
||||
if (commands.length == 0) {
|
||||
continue;
|
||||
}
|
||||
switch (commands[0]) {
|
||||
case "load":
|
||||
if (commands.length != 2) {
|
||||
System.out.println("Usage: load <filename>");
|
||||
} else {
|
||||
final var text = readFile(commands[1]);
|
||||
if (text == null) {
|
||||
System.out.println("Load file failed; " + commands[1]);
|
||||
continue;
|
||||
}
|
||||
helper = new GraphCLIHelper(text);
|
||||
}
|
||||
break;
|
||||
case "help":
|
||||
System.out.println("Available commands:");
|
||||
System.out.println(" show");
|
||||
System.out.println(" dot");
|
||||
System.out.println(" help");
|
||||
System.out.println(" exit");
|
||||
System.out.println(" random-walk");
|
||||
System.out.println(" load <filename>");
|
||||
System.out.println(" page-rank <word>");
|
||||
System.out.println(" bridge-words <word1> <word2>");
|
||||
System.out.println(" new-text <text...>");
|
||||
System.out.println(" shortest-path <word1> <word2>");
|
||||
break;
|
||||
case "shortest-path":
|
||||
if (commands.length != 3) {
|
||||
System.out.println("Usage: shortest-path <word1> <word2>");
|
||||
} else if (helper == null) {
|
||||
System.out.println("No graph loaded");
|
||||
break;
|
||||
} else {
|
||||
try {
|
||||
System.out.println(helper.calcShortestPath(commands[1], commands[2]));
|
||||
} catch (IOException | InterruptedException e) {
|
||||
System.out.println(e.getMessage());
|
||||
}
|
||||
}
|
||||
break;
|
||||
case "exit":
|
||||
return;
|
||||
case "random-walk":
|
||||
if (commands.length != 1) {
|
||||
System.out.println("Usage: random-walk");
|
||||
} else {
|
||||
if (helper == null) {
|
||||
System.out.println("No graph loaded");
|
||||
break;
|
||||
}
|
||||
System.out.println(helper.randomWalk());
|
||||
}
|
||||
break;
|
||||
case "new-text":
|
||||
if (commands.length < 2) {
|
||||
System.out.println("Usage: new-text <text...>");
|
||||
} else if (helper == null) {
|
||||
System.out.println("No graph loaded");
|
||||
break;
|
||||
} else {
|
||||
System.out.println(helper.generateNewText(
|
||||
String.join(" ", Arrays.asList(commands).subList(1, commands.length))));
|
||||
}
|
||||
break;
|
||||
case "show":
|
||||
if (commands.length != 1) {
|
||||
System.out.println("Usage: show");
|
||||
} else {
|
||||
if (helper == null) {
|
||||
System.out.println("No graph loaded");
|
||||
break;
|
||||
}
|
||||
GraphCLIHelper.showDirectedGraph(helper.graph);
|
||||
}
|
||||
break;
|
||||
case "dot":
|
||||
if (commands.length != 1) {
|
||||
System.out.println("Usage: dot");
|
||||
} else {
|
||||
if (helper == null) {
|
||||
System.out.println("No graph loaded");
|
||||
break;
|
||||
}
|
||||
System.out.println(helper.graph.toDOT());
|
||||
}
|
||||
break;
|
||||
case "page-rank":
|
||||
if (commands.length != 2) {
|
||||
System.out.println("Usage: page-rank <word>");
|
||||
} else if (helper == null) {
|
||||
System.out.println("No graph loaded");
|
||||
} else {
|
||||
final var pageRank = helper.calPageRank(commands[1]);
|
||||
if (pageRank < 0.0) {
|
||||
System.out.println("Invalid word");
|
||||
} else {
|
||||
System.out.println("PageRank of " + commands[1] + ": " + pageRank);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case "bridge-words":
|
||||
if (commands.length != 3) {
|
||||
System.out.println("Usage: bridge-words <word1> <word2>");
|
||||
} else if (helper == null) {
|
||||
System.out.println("No graph loaded");
|
||||
} else {
|
||||
System.out.println(helper.queryBridgeWords(commands[1], commands[2]));
|
||||
}
|
||||
break;
|
||||
default:
|
||||
System.out.println("Unknown command: " + commands[0]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper class for CommandLine.
|
||||
*/
|
||||
@SuppressWarnings("ALL")
|
||||
class GraphCLIHelper {
|
||||
Graph graph;
|
||||
Graph graph;
|
||||
|
||||
GraphCLIHelper(final String text) {
|
||||
graph = new Graph(text);
|
||||
GraphCLIHelper(final String text) {
|
||||
graph = new Graph(text);
|
||||
}
|
||||
|
||||
static void showDirectedGraph(final Graph graph) {
|
||||
final ProcessBuilder processBuilder = new ProcessBuilder("graph-easy", "--as", "ascii");
|
||||
processBuilder.redirectErrorStream(true);
|
||||
Process process;
|
||||
try {
|
||||
process = processBuilder.start();
|
||||
} catch (final IOException e) {
|
||||
System.err.println("Failed to start process");
|
||||
e.printStackTrace();
|
||||
return;
|
||||
}
|
||||
|
||||
static void showDirectedGraph(final Graph G) {
|
||||
final ProcessBuilder processBuilder = new ProcessBuilder("graph-easy", "--as", "ascii");
|
||||
processBuilder.redirectErrorStream(true);
|
||||
Process process = null;
|
||||
try {
|
||||
process = processBuilder.start();
|
||||
} catch (final IOException e) {
|
||||
System.err.println("Failed to start process");
|
||||
e.printStackTrace();
|
||||
}
|
||||
try (BufferedWriter writer = new BufferedWriter(
|
||||
new OutputStreamWriter(process.getOutputStream(), StandardCharsets.UTF_8))) {
|
||||
writer.write(G.toDOT());
|
||||
writer.flush();
|
||||
} catch (final IOException e) {
|
||||
System.err.println("Failed to write to process");
|
||||
e.printStackTrace();
|
||||
}
|
||||
final StringBuilder output = new StringBuilder();
|
||||
try (BufferedReader reader = new BufferedReader(
|
||||
new InputStreamReader(process.getInputStream(), StandardCharsets.UTF_8))) {
|
||||
String line;
|
||||
while ((line = reader.readLine()) != null) {
|
||||
output.append(line).append(System.lineSeparator());
|
||||
}
|
||||
} catch (final IOException e) {
|
||||
System.err.println("Failed to read from process");
|
||||
e.printStackTrace();
|
||||
}
|
||||
try {
|
||||
final int exitCode = process.waitFor();
|
||||
if (exitCode != 0) {
|
||||
System.err.println("Process exited with code " + exitCode);
|
||||
} else {
|
||||
System.out.println(output.toString());
|
||||
}
|
||||
} catch (final InterruptedException e) {
|
||||
System.err.println("Process interrupted");
|
||||
e.printStackTrace();
|
||||
}
|
||||
try (BufferedWriter writer = new BufferedWriter(
|
||||
new OutputStreamWriter(process.getOutputStream(), StandardCharsets.UTF_8))) {
|
||||
writer.write(graph.toDOT());
|
||||
writer.flush();
|
||||
} catch (final IOException e) {
|
||||
System.err.println("Failed to write to process");
|
||||
e.printStackTrace();
|
||||
}
|
||||
final StringBuilder output = new StringBuilder();
|
||||
try (BufferedReader reader = new BufferedReader(
|
||||
new InputStreamReader(process.getInputStream(), StandardCharsets.UTF_8))) {
|
||||
String line;
|
||||
while ((line = reader.readLine()) != null) {
|
||||
output.append(line).append(System.lineSeparator());
|
||||
}
|
||||
} catch (final IOException e) {
|
||||
System.err.println("Failed to read from process");
|
||||
e.printStackTrace();
|
||||
}
|
||||
try {
|
||||
final int exitCode = process.waitFor();
|
||||
if (exitCode != 0) {
|
||||
System.err.println("Process exited with code " + exitCode);
|
||||
} else {
|
||||
System.out.println(output.toString());
|
||||
}
|
||||
} catch (final InterruptedException e) {
|
||||
System.err.println("Process interrupted");
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
String queryBridgeWords(final String word1, final String word2) {
|
||||
final var option = graph.findBridgeWords(word1, word2);
|
||||
if (option.isEmpty()) {
|
||||
return "No " + word1 + " or " + word2 + " in the graph!";
|
||||
}
|
||||
final var bridgeWords = option.get();
|
||||
if (bridgeWords.isEmpty()) {
|
||||
return "No bridge words from " + word1 + " to " + word2 + "!";
|
||||
}
|
||||
final var output = new StringBuilder();
|
||||
output.append("The bridge words from ").append(word1).append(" to ").append(word2).append(" are: ");
|
||||
for (int i = 0; i < bridgeWords.size(); i++) {
|
||||
output.append(bridgeWords.get(i));
|
||||
if (i < bridgeWords.size() - 2) {
|
||||
output.append(", ");
|
||||
} else if (i == bridgeWords.size() - 2) {
|
||||
output.append(", and ");
|
||||
} else {
|
||||
output.append(".");
|
||||
}
|
||||
String queryBridgeWords(final String word1, final String word2) {
|
||||
final var option = graph.findBridgeWords(word1, word2);
|
||||
if (option.isEmpty()) {
|
||||
return "No " + word1 + " or " + word2 + " in the graph!";
|
||||
}
|
||||
final var bridgeWords = option.get();
|
||||
if (bridgeWords.isEmpty()) {
|
||||
return "No bridge words from " + word1 + " to " + word2 + "!";
|
||||
}
|
||||
final var output = new StringBuilder();
|
||||
output.append("The bridge words from ").append(word1).append(" to ").append(word2).append(" are: ");
|
||||
for (int i = 0; i < bridgeWords.size(); i++) {
|
||||
output.append(bridgeWords.get(i));
|
||||
if (i < bridgeWords.size() - 2) {
|
||||
output.append(", ");
|
||||
} else if (i == bridgeWords.size() - 2) {
|
||||
output.append(", and ");
|
||||
} else {
|
||||
output.append(".");
|
||||
}
|
||||
}
|
||||
return output.toString();
|
||||
}
|
||||
|
||||
@SuppressFBWarnings({"PREDICTABLE_RANDOM", "DMI_RANDOM_USED_ONLY_ONCE"})
|
||||
String generateNewText(final String inputText) {
|
||||
final var output = new StringBuilder();
|
||||
final var words = inputText.split("\\s+");
|
||||
for (int i = 0; i < words.length; i++) {
|
||||
output.append(words[i]);
|
||||
if (i < words.length - 1) {
|
||||
output.append(" ");
|
||||
final var option = graph.findBridgeWords(words[i], words[i + 1]);
|
||||
if (option.isPresent() && !option.get().isEmpty()) {
|
||||
final var bridgeWords = option.get();
|
||||
final Random random = new Random();
|
||||
final int wordIndex = random.nextInt(bridgeWords.size());
|
||||
output.append(option.get().get(wordIndex)).append(" ");
|
||||
}
|
||||
}
|
||||
}
|
||||
return output.toString();
|
||||
}
|
||||
|
||||
String calcShortestPath(final String word1, final String word2)
|
||||
throws IOException, InterruptedException {
|
||||
final ProcessBuilder processBuilder = new ProcessBuilder("graph-easy", "--as", "ascii");
|
||||
processBuilder.redirectErrorStream(true);
|
||||
Process process = null;
|
||||
process = processBuilder.start();
|
||||
try (BufferedWriter writer = new BufferedWriter(
|
||||
new OutputStreamWriter(process.getOutputStream(), StandardCharsets.UTF_8))) {
|
||||
writer.write(calcShortestPathToDOT(word1, word2));
|
||||
writer.flush();
|
||||
}
|
||||
final StringBuilder output = new StringBuilder();
|
||||
try (BufferedReader reader = new BufferedReader(
|
||||
new InputStreamReader(process.getInputStream(), StandardCharsets.UTF_8))) {
|
||||
String line;
|
||||
while ((line = reader.readLine()) != null) {
|
||||
output.append(line).append(System.lineSeparator());
|
||||
}
|
||||
}
|
||||
try {
|
||||
final int exitCode = process.waitFor();
|
||||
if (exitCode != 0) {
|
||||
throw new IOException("Process exited with code " + exitCode);
|
||||
} else {
|
||||
return output.toString();
|
||||
}
|
||||
} catch (final InterruptedException e) {
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
String generateNewText(final String inputText) {
|
||||
final var output = new StringBuilder();
|
||||
final var words = inputText.split("\\s+");
|
||||
for (int i = 0; i < words.length; i++) {
|
||||
output.append(words[i]);
|
||||
if (i < words.length - 1) {
|
||||
output.append(" ");
|
||||
final var option = graph.findBridgeWords(words[i], words[i + 1]);
|
||||
if (option.isPresent() && !option.get().isEmpty()) {
|
||||
final var bridgeWords = option.get();
|
||||
final Random random = new Random();
|
||||
final int wordIndex = random.nextInt(bridgeWords.size());
|
||||
output.append(option.get().get(wordIndex)).append(" ");
|
||||
}
|
||||
}
|
||||
}
|
||||
return output.toString();
|
||||
String calcShortestPathToDOT(final String word1, final String word2) {
|
||||
var option = graph.findShortestPath(word1, word2);
|
||||
if (option.isEmpty()) {
|
||||
return "No " + word1 + " or " + word2 + " in the graph";
|
||||
} else {
|
||||
final var path = option.get();
|
||||
if (path.isEmpty()) {
|
||||
return "No path from " + word1 + " to " + word2;
|
||||
}
|
||||
return graph.toDOT(r -> String.format(
|
||||
"\"%s\" -> \"%s\" [label=\"%d\"%s]",
|
||||
r.node1() + (path.contains(r.node1()) ? "~" : ""),
|
||||
r.node2() + (path.contains(r.node2()) ? "~" : ""),
|
||||
r.weight(),
|
||||
(path.contains(r.node1()) && path.contains(r.node2())
|
||||
&& IntStream.range(0, path.size() - 1).anyMatch(
|
||||
i -> path.get(i).equals(r.node1()) && path.get(i + 1).equals(r.node2())))
|
||||
? ",color=\"red\""
|
||||
: ""));
|
||||
}
|
||||
}
|
||||
|
||||
String calcShortestPath(final String word1, final String word2)
|
||||
throws IOException, InterruptedException {
|
||||
final ProcessBuilder processBuilder = new ProcessBuilder("graph-easy", "--as", "ascii");
|
||||
processBuilder.redirectErrorStream(true);
|
||||
Process process = null;
|
||||
try {
|
||||
process = processBuilder.start();
|
||||
} catch (final IOException e) {
|
||||
throw e;
|
||||
}
|
||||
try (BufferedWriter writer = new BufferedWriter(
|
||||
new OutputStreamWriter(process.getOutputStream(), StandardCharsets.UTF_8))) {
|
||||
writer.write(calcShortestPathToDOT(word1, word2));
|
||||
writer.flush();
|
||||
} catch (final IOException e) {
|
||||
throw e;
|
||||
}
|
||||
final StringBuilder output = new StringBuilder();
|
||||
try (BufferedReader reader = new BufferedReader(
|
||||
new InputStreamReader(process.getInputStream(), StandardCharsets.UTF_8))) {
|
||||
String line;
|
||||
while ((line = reader.readLine()) != null) {
|
||||
output.append(line).append(System.lineSeparator());
|
||||
}
|
||||
} catch (final IOException e) {
|
||||
throw e;
|
||||
}
|
||||
try {
|
||||
final int exitCode = process.waitFor();
|
||||
if (exitCode != 0) {
|
||||
throw new IOException("Process exited with code " + exitCode);
|
||||
} else {
|
||||
return output.toString();
|
||||
}
|
||||
} catch (final InterruptedException e) {
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
Double calPageRank(final String word) {
|
||||
return graph.computePageRank(word);
|
||||
}
|
||||
|
||||
String calcShortestPathToDOT(final String word1, final String word2) {
|
||||
var option = graph.findShortestPath(word1, word2);
|
||||
if (option.isEmpty()) {
|
||||
return "No " + word1 + " or " + word2 + " in the graph";
|
||||
} else {
|
||||
final var path = option.get();
|
||||
if (path.isEmpty()) {
|
||||
return "No path from " + word1 + " to " + word2;
|
||||
}
|
||||
return graph.toDOT(r -> String.format(
|
||||
"\"%s\" -> \"%s\" [label=\"%d\"%s]",
|
||||
r.node1() + (path.contains(r.node1()) ? "~" : ""),
|
||||
r.node2() + (path.contains(r.node2()) ? "~" : ""),
|
||||
r.weight(),
|
||||
(path.contains(r.node1()) && path.contains(r.node2()) &&
|
||||
IntStream.range(0, path.size() - 1).anyMatch(
|
||||
i -> path.get(i).equals(r.node1()) && path.get(i + 1).equals(r.node2())))
|
||||
? ",color=\"red\""
|
||||
: ""));
|
||||
}
|
||||
}
|
||||
|
||||
Double calPageRank(final String word) {
|
||||
final var pageRank = graph.computePageRank(word);
|
||||
return pageRank;
|
||||
}
|
||||
|
||||
String randomWalk() {
|
||||
final var text = graph.randomWalk().stream().collect(Collectors.joining(" "));
|
||||
final Path path = Paths.get("output.txt");
|
||||
try {
|
||||
Files.write(path, text.getBytes());
|
||||
} catch (final IOException e) {
|
||||
System.err.println("Failed to write to file");
|
||||
e.printStackTrace();
|
||||
}
|
||||
return text;
|
||||
@SuppressFBWarnings("DM_DEFAULT_ENCODING")
|
||||
String randomWalk() {
|
||||
final var text = String.join(" ", graph.randomWalk());
|
||||
final Path path = Paths.get("output.txt");
|
||||
try {
|
||||
Files.write(path, text.getBytes());
|
||||
} catch (final IOException e) {
|
||||
System.err.println("Failed to write to file");
|
||||
e.printStackTrace();
|
||||
}
|
||||
return text;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue