Merge pull request #15 from eugenp/master

Update from master
This commit is contained in:
Donato Rimenti
2020-07-02 17:33:17 +02:00
committed by GitHub
4939 changed files with 56471 additions and 490917 deletions
-4
View File
@@ -85,7 +85,3 @@ transaction.log
*-shell.log
apache-cxf/cxf-aegis/baeldung.xml
apache-fop/src/test/resources/input.xml
apache-fop/src/test/resources/output_herold.pdf
apache-fop/src/test/resources/output_html2fo.pdf
apache-fop/src/test/resources/output_jtidy.pdf
-1
View File
@@ -13,6 +13,5 @@ This module contains articles about algorithms. Some classes of algorithms, e.g.
- [Checking if a Java Graph has a Cycle](https://www.baeldung.com/java-graph-has-a-cycle)
- [A Guide to the Folding Technique in Java](https://www.baeldung.com/folding-hashing-technique)
- [Creating a Triangle with for Loops in Java](https://www.baeldung.com/java-print-triangle)
- [Efficient Word Frequency Calculator in Java](https://www.baeldung.com/java-word-frequency)
- [The K-Means Clustering Algorithm in Java](https://www.baeldung.com/java-k-means-clustering-algorithm)
- More articles: [[<-- prev]](/algorithms-miscellaneous-2) [[next -->]](/algorithms-miscellaneous-4)
+2 -5
View File
@@ -15,8 +15,5 @@ This module contains articles about algorithms. Some classes of algorithms, e.g.
- [Maximum Subarray Problem](https://www.baeldung.com/java-maximum-subarray)
- [How to Merge Two Sorted Arrays](https://www.baeldung.com/java-merge-sorted-arrays)
- [Median of Stream of Integers using Heap](https://www.baeldung.com/java-stream-integers-median-using-heap)
- [Kruskal’s Algorithm for Spanning Trees](https://www.baeldung.com/java-spanning-trees-kruskal)
- [Balanced Brackets Algorithm in Java](https://www.baeldung.com/java-balanced-brackets-algorithm)
- [Efficiently Merge Sorted Java Sequences](https://www.baeldung.com/java-merge-sorted-sequences)
- [Introduction to Greedy Algorithms with Java](https://www.baeldung.com/java-greedy-algorithms)
- More articles: [[<-- prev]](/../algorithms-miscellaneous-4)
- More articles: [[<-- prev]](/../algorithms-miscellaneous-4) [[next -->]](/../algorithms-miscellaneous-6)
-12
View File
@@ -25,12 +25,6 @@
<artifactId>commons-math3</artifactId>
<version>${commons-math3.version}</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>${lombok.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>pl.allegro.finance</groupId>
<artifactId>tradukisto</artifactId>
@@ -41,11 +35,6 @@
<artifactId>guava</artifactId>
<version>${guava.version}</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>${jackson.version}</version>
</dependency>
<dependency>
<groupId>org.junit.platform</groupId>
<artifactId>junit-platform-commons</artifactId>
@@ -78,7 +67,6 @@
<commons-codec.version>1.11</commons-codec.version>
<commons-math3.version>3.6.1</commons-math3.version>
<guava.version>28.1-jre</guava.version>
<jackson.version>2.10.2</jackson.version>
<junit.platform.version>1.6.0</junit.platform.version>
</properties>
@@ -1,61 +0,0 @@
package com.baeldung.algorithms.boruvka;
public class BoruvkaMST {
private static Tree mst = new Tree();
private static int totalWeight;
public BoruvkaMST(Graph graph) {
DisjointSet dSet = new DisjointSet(graph.getNodes());
// repeat at most log N times or until we have N-1 edges
for (int t = 1; t < graph.getNodes() && mst.getEdgeCount() < graph.getNodes() - 1; t = t + t) {
// foreach tree in forest, find closest edge
Edge[] closestEdgeArray = new Edge[graph.getNodes()];
for (Edge edge : graph.getAllEdges()) {
int first = edge.getFirst();
int second = edge.getSecond();
int firstParent = dSet.getParent(first);
int secondParent = dSet.getParent(second);
if (firstParent == secondParent) {
continue; // same tree
}
if (closestEdgeArray[firstParent] == null || edge.getWeight() < closestEdgeArray[firstParent].getWeight()) {
closestEdgeArray[firstParent] = edge;
}
if (closestEdgeArray[secondParent] == null || edge.getWeight() < closestEdgeArray[secondParent].getWeight()) {
closestEdgeArray[secondParent] = edge;
}
}
// add newly discovered edges to MST
for (int i = 0; i < graph.getNodes(); i++) {
Edge edge = closestEdgeArray[i];
if (edge != null) {
int first = edge.getFirst();
int second = edge.getSecond();
// don't add the same edge twice
if (dSet.getParent(first) != dSet.getParent(second)) {
mst.addEdge(edge);
totalWeight += edge.getWeight();
dSet.union(first, second);
}
}
}
}
}
public Iterable<Edge> getMST() {
return mst;
}
public int getTotalWeight() {
return totalWeight;
}
public String toString() {
return "MST: " + mst.toString() + " | Total Weight: " + totalWeight;
}
}
@@ -1,49 +0,0 @@
package com.baeldung.algorithms.boruvka;
import java.util.Arrays;
public class DisjointSet {
private int[] nodeParents;
private int[] nodeRanks;
public DisjointSet(int n) {
nodeParents = new int[n];
nodeRanks = new int[n];
for (int i = 0; i < n; i++) {
nodeParents[i] = i;
nodeRanks[i] = 0;
}
}
public int getParent(int node) {
while (node != nodeParents[node]) {
node = nodeParents[node];
}
return node;
}
public void union(int node1, int node2) {
int node1Parent = getParent(node1);
int node2Parent = getParent(node2);
if (node1Parent == node2Parent) {
return;
}
if (nodeRanks[node1Parent] < nodeRanks[node2Parent]) {
nodeParents[node1Parent] = node2Parent;
}
else if (nodeRanks[node1Parent] > nodeRanks[node2Parent]) {
nodeParents[node2Parent] = node1Parent;
}
else {
nodeParents[node2Parent] = node1Parent;
nodeRanks[node1Parent]++;
}
}
public String toString() {
return "Parent: " + Arrays.toString(nodeParents) + "Rank: " + Arrays.toString(nodeRanks);
}
}
@@ -1,40 +0,0 @@
package com.baeldung.algorithms.boruvka;
public class Edge {
private final int first;
private final int second;
private final int weight;
public Edge(int first, int second, int weight) {
this.first = first;
this.second = second;
this.weight = weight;
}
public double getWeight() {
return weight;
}
public int getFirst() {
return first;
}
public int getSecond() {
return second;
}
public int getOtherNode(int firstNode) {
int secondNode = 0;
if (firstNode == first)
secondNode = second;
else if (firstNode == second)
secondNode = first;
return secondNode;
}
public String toString() {
return String.format("%d-%d %d", first, second, weight);
}
}
@@ -1,64 +0,0 @@
package com.baeldung.algorithms.boruvka;
import java.io.IOException;
import com.fasterxml.jackson.core.JsonParseException;
import com.fasterxml.jackson.databind.JsonMappingException;
public class Graph {
private int nodes;
private int edges;
private Tree[] trees;
public Graph(Input jsonGraph) throws JsonParseException, JsonMappingException, IOException {
nodes = jsonGraph.getNodes();
trees = (Tree[]) new Tree[nodes];
for (int i = 0; i < nodes; i++) {
trees[i] = new Tree();
}
int edgesFromInput = jsonGraph.getEdges();
for (int i = 0; i < edgesFromInput; i++) {
int first = jsonGraph.getEdgeList()
.get(i)
.getFirst();
int second = jsonGraph.getEdgeList()
.get(i)
.getSecond();
int weight = jsonGraph.getEdgeList()
.get(i)
.getWeight();
Edge edge = new Edge(first, second, weight);
trees[first].addEdge(edge);
trees[second].addEdge(edge);
edges++;
}
}
public int getNodes() {
return nodes;
}
public int getEdges() {
return edges;
}
public Iterable<Edge> iterableTree(int i) {
return trees[i];
}
public Iterable<Edge> getAllEdges() {
Iterable<Edge> list = new Tree();
for (int i = 0; i < nodes; i++) {
for (Edge edge : iterableTree(i)) {
if (edge.getOtherNode(i) > i) {
((Tree) list).addEdge(edge);
}
}
}
return list;
}
}
@@ -1,65 +0,0 @@
package com.baeldung.algorithms.boruvka;
import java.util.List;
public class Input {
private int nodes;
private int edges;
private List<E> edgeList;
public int getNodes() {
return nodes;
}
public void setNodes(int nodes) {
this.nodes = nodes;
}
public int getEdges() {
return edges;
}
public void setEdges(int edges) {
this.edges = edges;
}
public List<E> getEdgeList() {
return edgeList;
}
public void setEdgeList(List<E> edgeList) {
this.edgeList = edgeList;
}
static class E {
private int first;
private int second;
private int weight;
public int getFirst() {
return first;
}
public void setFirst(int first) {
this.first = first;
}
public int getSecond() {
return second;
}
public void setSecond(int second) {
this.second = second;
}
public int getWeight() {
return weight;
}
public void setWeight(int weight) {
this.weight = weight;
}
}
}
@@ -1,63 +0,0 @@
package com.baeldung.algorithms.boruvka;
import java.util.Iterator;
public class Tree implements Iterable<Edge> {
private Node root;
private int edgeCount;
private static class Node {
private Edge edge;
private Node next;
public String toString() {
String nextStr = next != null ? next.toString() : "";
return edge.toString() + " | " + nextStr;
}
}
public Tree() {
root = null;
edgeCount = 0;
}
public int getEdgeCount() {
return edgeCount;
}
public void addEdge(Edge edge) {
Node oldRoot = root;
root = new Node();
root.edge = edge;
root.next = oldRoot;
edgeCount++;
}
public String toString() {
String rootStr = root != null ? root.toString() : "";
return "Tree: " + rootStr + "Size: " + edgeCount;
}
public Iterator<Edge> iterator() {
return new LinkedIterator(root);
}
private class LinkedIterator implements Iterator<Edge> {
private Node current;
public LinkedIterator(Node root) {
current = root;
}
public boolean hasNext() {
return current != null;
}
public Edge next() {
Edge edge = current.edge;
current = current.next;
return edge;
}
}
}
@@ -1,48 +0,0 @@
package com.baeldung.algorithms.boruvka;
import static org.junit.jupiter.api.Assertions.assertEquals;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import org.junit.Before;
import org.junit.Test;
import com.fasterxml.jackson.core.JsonParseException;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.ObjectMapper;
public class BoruvkaUnitTest {
private Input input;
private static String INPUT_JSON = "/input.json";
@Before
public void convertInputJsonToObject() throws JsonParseException, JsonMappingException, IOException {
ObjectMapper mapper = new ObjectMapper();
StringBuilder jsonStr = new StringBuilder();
try (BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(BoruvkaMST.class.getResourceAsStream(INPUT_JSON)))) {
String line;
while ((line = bufferedReader.readLine()) != null) {
jsonStr.append(line)
.append("\n");
}
}
input = mapper.readValue(jsonStr.toString(), Input.class);
}
@Test
public void givenInputGraph_whenBoruvkaPerformed_thenMinimumSpanningTree() throws JsonParseException, JsonMappingException, IOException {
Graph graph = new Graph(input);
BoruvkaMST boruvkaMST = new BoruvkaMST(graph);
Tree mst = (Tree) boruvkaMST.getMST();
assertEquals(30, boruvkaMST.getTotalWeight());
assertEquals(4, mst.getEdgeCount());
}
}
+10
View File
@@ -0,0 +1,10 @@
### Relevant Articles:
- [Boruvka’s Algorithm for Minimum Spanning Trees](https://www.baeldung.com/java-boruvka-algorithm)
- [Gradient Descent in Java](https://www.baeldung.com/java-gradient-descent)
- [Kruskal’s Algorithm for Spanning Trees](https://www.baeldung.com/java-spanning-trees-kruskal)
- [Balanced Brackets Algorithm in Java](https://www.baeldung.com/java-balanced-brackets-algorithm)
- [Efficiently Merge Sorted Java Sequences](https://www.baeldung.com/java-merge-sorted-sequences)
- [Introduction to Greedy Algorithms with Java](https://www.baeldung.com/java-greedy-algorithms)
- [The Caesar Cipher in Java](https://www.baeldung.com/java-caesar-cipher)
- More articles: [[<-- prev]](/../algorithms-miscellaneous-5)
+52
View File
@@ -0,0 +1,52 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<artifactId>algorithms-miscellaneous-6</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>algorithms-miscellaneous-6</name>
<parent>
<groupId>com.baeldung</groupId>
<artifactId>parent-modules</artifactId>
<version>1.0.0-SNAPSHOT</version>
</parent>
<dependencies>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>${guava.version}</version>
</dependency>
<dependency>
<groupId>org.junit.platform</groupId>
<artifactId>junit-platform-commons</artifactId>
<version>${junit.platform.version}</version>
</dependency>
<dependency>
<groupId>org.assertj</groupId>
<artifactId>assertj-core</artifactId>
<version>${org.assertj.core.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>${lombok.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-math3</artifactId>
<version>${commons-math3.version}</version>
</dependency>
</dependencies>
<properties>
<guava.version>28.1-jre</guava.version>
<org.assertj.core.version>3.9.0</org.assertj.core.version>
<junit.platform.version>1.6.0</junit.platform.version>
<commons-math3.version>3.6.1</commons-math3.version>
</properties>
</project>
@@ -0,0 +1,84 @@
package com.baeldung.algorithms.boruvka;
import com.google.common.graph.EndpointPair;
import com.google.common.graph.MutableValueGraph;
import com.google.common.graph.ValueGraphBuilder;
public class BoruvkaMST {
private static MutableValueGraph<Integer, Integer> mst = ValueGraphBuilder.undirected()
.build();
private static int totalWeight;
public BoruvkaMST(MutableValueGraph<Integer, Integer> graph) {
int size = graph.nodes().size();
UnionFind uf = new UnionFind(size);
// repeat at most log N times or until we have N-1 edges
for (int t = 1; t < size && mst.edges().size() < size - 1; t = t + t) {
EndpointPair<Integer>[] closestEdgeArray = new EndpointPair[size];
// foreach tree in graph, find closest edge
for (EndpointPair<Integer> edge : graph.edges()) {
int u = edge.nodeU();
int v = edge.nodeV();
int uParent = uf.find(u);
int vParent = uf.find(v);
if (uParent == vParent) {
continue; // same tree
}
int weight = graph.edgeValueOrDefault(u, v, 0);
if (closestEdgeArray[uParent] == null) {
closestEdgeArray[uParent] = edge;
}
if (closestEdgeArray[vParent] == null) {
closestEdgeArray[vParent] = edge;
}
int uParentWeight = graph.edgeValueOrDefault(closestEdgeArray[uParent].nodeU(), closestEdgeArray[uParent].nodeV(), 0);
int vParentWeight = graph.edgeValueOrDefault(closestEdgeArray[vParent].nodeU(), closestEdgeArray[vParent].nodeV(), 0);
if (weight < uParentWeight) {
closestEdgeArray[uParent] = edge;
}
if (weight < vParentWeight) {
closestEdgeArray[vParent] = edge;
}
}
// add newly discovered edges to MST
for (int i = 0; i < size; i++) {
EndpointPair<Integer> edge = closestEdgeArray[i];
if (edge != null) {
int u = edge.nodeU();
int v = edge.nodeV();
int weight = graph.edgeValueOrDefault(u, v, 0);
// don't add the same edge twice
if (uf.find(u) != uf.find(v)) {
mst.putEdgeValue(u, v, weight);
totalWeight += weight;
uf.union(u, v);
}
}
}
}
}
public MutableValueGraph<Integer, Integer> getMST() {
return mst;
}
public int getTotalWeight() {
return totalWeight;
}
public String toString() {
return "MST: " + mst.toString() + " | Total Weight: " + totalWeight;
}
}
@@ -0,0 +1,39 @@
package com.baeldung.algorithms.boruvka;
public class UnionFind {
private int[] parents;
private int[] ranks;
public UnionFind(int n) {
parents = new int[n];
ranks = new int[n];
for (int i = 0; i < n; i++) {
parents[i] = i;
ranks[i] = 0;
}
}
public int find(int u) {
while (u != parents[u]) {
u = parents[u];
}
return u;
}
public void union(int u, int v) {
int uParent = find(u);
int vParent = find(v);
if (uParent == vParent) {
return;
}
if (ranks[uParent] < ranks[vParent]) {
parents[uParent] = vParent;
} else if (ranks[uParent] > ranks[vParent]) {
parents[vParent] = uParent;
} else {
parents[vParent] = uParent;
ranks[uParent]++;
}
}
}
@@ -0,0 +1,33 @@
package com.baeldung.algorithms.gradientdescent;
import java.util.function.Function;
public class GradientDescent {
private final double precision = 0.000001;
public double findLocalMinimum(Function<Double, Double> f, double initialX) {
double stepCoefficient = 0.1;
double previousStep = 1.0;
double currentX = initialX;
double previousX = initialX;
double previousY = f.apply(previousX);
int iter = 100;
currentX += stepCoefficient * previousY;
while (previousStep > precision && iter > 0) {
iter--;
double currentY = f.apply(currentX);
if (currentY > previousY) {
stepCoefficient = -stepCoefficient / 2;
}
previousX = currentX;
currentX += stepCoefficient * previousY;
previousY = currentY;
previousStep = StrictMath.abs(currentX - previousX);
}
return currentX;
}
}
@@ -1,13 +1,13 @@
package com.baeldung.algorithms.minheapmerge;
public class HeapNode {
int element;
int arrayIndex;
int nextElementIndex = 1;
public HeapNode(int element, int arrayIndex) {
this.element = element;
this.arrayIndex = arrayIndex;
}
}
package com.baeldung.algorithms.minheapmerge;
public class HeapNode {
int element;
int arrayIndex;
int nextElementIndex = 1;
public HeapNode(int element, int arrayIndex) {
this.element = element;
this.arrayIndex = arrayIndex;
}
}
@@ -1,88 +1,88 @@
package com.baeldung.algorithms.minheapmerge;
public class MinHeap {
HeapNode[] heapNodes;
public MinHeap(HeapNode heapNodes[]) {
this.heapNodes = heapNodes;
heapifyFromLastLeafsParent();
}
void heapifyFromLastLeafsParent() {
int lastLeafsParentIndex = getParentNodeIndex(heapNodes.length);
while (lastLeafsParentIndex >= 0) {
heapify(lastLeafsParentIndex);
lastLeafsParentIndex--;
}
}
void heapify(int index) {
int leftNodeIndex = getLeftNodeIndex(index);
int rightNodeIndex = getRightNodeIndex(index);
int smallestElementIndex = index;
if (leftNodeIndex < heapNodes.length && heapNodes[leftNodeIndex].element < heapNodes[index].element) {
smallestElementIndex = leftNodeIndex;
}
if (rightNodeIndex < heapNodes.length && heapNodes[rightNodeIndex].element < heapNodes[smallestElementIndex].element) {
smallestElementIndex = rightNodeIndex;
}
if (smallestElementIndex != index) {
swap(index, smallestElementIndex);
heapify(smallestElementIndex);
}
}
int getParentNodeIndex(int index) {
return (index - 1) / 2;
}
int getLeftNodeIndex(int index) {
return (2 * index + 1);
}
int getRightNodeIndex(int index) {
return (2 * index + 2);
}
HeapNode getRootNode() {
return heapNodes[0];
}
void heapifyFromRoot() {
heapify(0);
}
void swap(int i, int j) {
HeapNode temp = heapNodes[i];
heapNodes[i] = heapNodes[j];
heapNodes[j] = temp;
}
static int[] merge(int[][] array) {
HeapNode[] heapNodes = new HeapNode[array.length];
int resultingArraySize = 0;
for (int i = 0; i < array.length; i++) {
HeapNode node = new HeapNode(array[i][0], i);
heapNodes[i] = node;
resultingArraySize += array[i].length;
}
MinHeap minHeap = new MinHeap(heapNodes);
int[] resultingArray = new int[resultingArraySize];
for (int i = 0; i < resultingArraySize; i++) {
HeapNode root = minHeap.getRootNode();
resultingArray[i] = root.element;
if (root.nextElementIndex < array[root.arrayIndex].length) {
root.element = array[root.arrayIndex][root.nextElementIndex++];
} else {
root.element = Integer.MAX_VALUE;
}
minHeap.heapifyFromRoot();
}
return resultingArray;
}
}
package com.baeldung.algorithms.minheapmerge;
public class MinHeap {
HeapNode[] heapNodes;
public MinHeap(HeapNode heapNodes[]) {
this.heapNodes = heapNodes;
heapifyFromLastLeafsParent();
}
void heapifyFromLastLeafsParent() {
int lastLeafsParentIndex = getParentNodeIndex(heapNodes.length);
while (lastLeafsParentIndex >= 0) {
heapify(lastLeafsParentIndex);
lastLeafsParentIndex--;
}
}
void heapify(int index) {
int leftNodeIndex = getLeftNodeIndex(index);
int rightNodeIndex = getRightNodeIndex(index);
int smallestElementIndex = index;
if (leftNodeIndex < heapNodes.length && heapNodes[leftNodeIndex].element < heapNodes[index].element) {
smallestElementIndex = leftNodeIndex;
}
if (rightNodeIndex < heapNodes.length && heapNodes[rightNodeIndex].element < heapNodes[smallestElementIndex].element) {
smallestElementIndex = rightNodeIndex;
}
if (smallestElementIndex != index) {
swap(index, smallestElementIndex);
heapify(smallestElementIndex);
}
}
int getParentNodeIndex(int index) {
return (index - 1) / 2;
}
int getLeftNodeIndex(int index) {
return (2 * index + 1);
}
int getRightNodeIndex(int index) {
return (2 * index + 2);
}
HeapNode getRootNode() {
return heapNodes[0];
}
void heapifyFromRoot() {
heapify(0);
}
void swap(int i, int j) {
HeapNode temp = heapNodes[i];
heapNodes[i] = heapNodes[j];
heapNodes[j] = temp;
}
static int[] merge(int[][] array) {
HeapNode[] heapNodes = new HeapNode[array.length];
int resultingArraySize = 0;
for (int i = 0; i < array.length; i++) {
HeapNode node = new HeapNode(array[i][0], i);
heapNodes[i] = node;
resultingArraySize += array[i].length;
}
MinHeap minHeap = new MinHeap(heapNodes);
int[] resultingArray = new int[resultingArraySize];
for (int i = 0; i < resultingArraySize; i++) {
HeapNode root = minHeap.getRootNode();
resultingArray[i] = root.element;
if (root.nextElementIndex < array[root.arrayIndex].length) {
root.element = array[root.arrayIndex][root.nextElementIndex++];
} else {
root.element = Integer.MAX_VALUE;
}
minHeap.heapifyFromRoot();
}
return resultingArray;
}
}

Some files were not shown because too many files have changed in this diff Show More