Skip to content
This repository was archived by the owner on Apr 22, 2020. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 9 additions & 3 deletions algo/src/main/java/org/neo4j/graphalgo/impl/Prim.java
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@
*/
public class Prim extends Algorithm<Prim> {

public static final int UNUSED = 42;
private final RelationshipIterator relationshipIterator;
private final RelationshipWeights weights;
private final int nodeCount;
Expand Down Expand Up @@ -90,11 +91,16 @@ private SpanningTree prim(int startNode, boolean max) {
if (visited.contains(t)) {
return true;
}
// invert weight to calculate maximum
// inverting the weight calculates maximum- instead of minimum spanning tree
final double w = max ? -weights.weightOf(s, t) : weights.weightOf(s, t);
if (w < cost.getOrDefault(t, Double.MAX_VALUE)) {
cost.put(t, w);
queue.add(t, -1.0);
if (cost.containsKey(t)) {
cost.put(t, w);
queue.update(t);
} else {
cost.put(t, w);
queue.add(t, w);
}
spanningTree.parent[t] = s;
}
return true;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ public class ShortestPathDijkstra extends Algorithm<ShortestPathDijkstra> {

private static final int PATH_END = -1;
public static final double NO_PATH_FOUND = -1.0;
public static final int UNUSED = 42;

private Graph graph;

Expand Down Expand Up @@ -152,28 +153,28 @@ private void run(int goal, Direction direction) {
graph.forEachRelationship(
node,
direction, (source, target, relId, weight) -> {
boolean oldCostChanged = updateCosts(source, target, weight + costs);
if (!visited.get(target)) {
if (oldCostChanged) {
queue.update(target);
} else {
queue.add(target, 0);
}
}
updateCosts(source, target, weight + costs);
return true;
});
progressLogger.logProgress((double) node / (nodeCount - 1));
}
}

private boolean updateCosts(int source, int target, double newCosts) {
double oldCosts = costs.getOrDefault(target, Double.MAX_VALUE);
if (newCosts < oldCosts) {
costs.put(target, newCosts);
path.put(target, source);
return oldCosts < Double.MAX_VALUE;
private void updateCosts(int source, int target, double newCosts) {

if (costs.containsKey(target)) {
if (newCosts < costs.getOrDefault(target, Double.MAX_VALUE)) {
costs.put(target, newCosts);
path.put(target, source);
queue.update(target);
}
} else {
if (newCosts < costs.getOrDefault(target, Double.MAX_VALUE)) {
costs.put(target, newCosts);
path.put(target, source);
queue.add(target, newCosts);
}
}
return false;
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ private void run() {
final double targetCosts = this.costs.getOrDefault(target, Double.POSITIVE_INFINITY);
if (weight + sourceCosts < targetCosts) {
costs.put(target, weight + sourceCosts);
queue.set(target, targetCosts);
queue.set(target, weight + sourceCosts);
}
return true;
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,6 @@
import org.neo4j.graphalgo.results.AbstractResultBuilder;

/**
* Sequential Single-Source minimum weight spanning tree algorithm (PRIM).
* <p>
* The algorithm computes the MST by traversing all nodes from a given
* startNodeId. It aggregates all transitions into a MinPriorityQueue
* and visits each (unvisited) connected node by following only the
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -86,8 +86,13 @@ private SpanningTree prim(int startNode, boolean max) {
// invert weight to calculate maximum
final double w = max ? -weights.weightOf(s, t) : weights.weightOf(s, t);
if (w < cost.getOrDefault(t, Double.MAX_VALUE)) {
cost.put(t, w);
queue.add(t, -1.0);
if (cost.containsKey(t)) {
cost.put(t, w);
queue.update(t);
} else {
cost.put(t, w);
queue.add(t, -1.0);
}
parent[t] = s;
}
return true;
Expand Down
44 changes: 31 additions & 13 deletions algo/src/main/java/org/neo4j/graphalgo/impl/yens/Dijkstra.java
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@
import org.neo4j.graphalgo.core.utils.TerminationFlag;
import org.neo4j.graphalgo.core.utils.queue.IntPriorityQueue;
import org.neo4j.graphalgo.core.utils.queue.SharedIntPriorityQueue;
import org.neo4j.graphalgo.core.utils.traverse.SimpleBitSet;
import org.neo4j.graphdb.Direction;

import java.util.Arrays;
Expand All @@ -38,18 +37,19 @@
public class Dijkstra {

// initial weighted path capacity

public static final int INITIAL_CAPACITY = 64;

private static final int PATH_END = -1;

private final Graph graph;

private final int nodeCount;

private TerminationFlag terminationFlag = TerminationFlag.RUNNING_TRUE;

// node to cost map
private final IntDoubleMap costs;
// next node priority queue

private final IntPriorityQueue queue;
// auxiliary path map
private final IntIntMap path;
Expand Down Expand Up @@ -157,7 +157,8 @@ private boolean dijkstra(int source, int target, Direction direction, int maxDep
visited.clear();
costs.put(source, 0.0);
queue.add(source, 0.0);
Arrays.fill(depth, 1);
Arrays.fill(depth, 0);
depth[source] = 1;
while (!queue.isEmpty() && terminationFlag.running()) {
int node = queue.pop();
final int d = depth[node];
Expand All @@ -176,32 +177,49 @@ private boolean dijkstra(int source, int target, Direction direction, int maxDep
return true;
}
final double w = graph.weightOf(s, t);
final boolean updateCosts = updateCosts(s, t, w + costs);
final UpdateResult updateCosts = updateCosts(s, t, w + costs);
if (!visited.get(t)) {
depth[t] = d + 1;
if (updateCosts) {
queue.update(t);
} else {
queue.add(t, w);
switch (updateCosts) {
case NO_PREVIOUS_COSTS:
queue.add(t, w);
break;
case UPDATED_COST:
queue.update(t);
break;
default:
break;
}
depth[t] = depth[s] + 1;
}
return terminationFlag.running();
});
}
return false;
}


/**
* update cost map
*/
private boolean updateCosts(int source, int target, double newCosts) {
private UpdateResult updateCosts(int source, int target, double newCosts) {
double oldCosts = costs.getOrDefault(target, Double.MAX_VALUE);
if (oldCosts == Double.MAX_VALUE) {
if (!costs.containsKey(target)) {
costs.put(target, newCosts);
path.put(target, source);
return UpdateResult.NO_PREVIOUS_COSTS;
}
}
if (newCosts < oldCosts) {
costs.put(target, newCosts);
path.put(target, source);
return oldCosts < Double.MAX_VALUE;
return UpdateResult.UPDATED_COST;
}
return false;
return UpdateResult.COST_NOT_COMPETITIVE;
}

private enum UpdateResult {
NO_PREVIOUS_COSTS, UPDATED_COST, COST_NOT_COMPETITIVE;
}

}
Original file line number Diff line number Diff line change
@@ -1,56 +1,37 @@
/**
* Copyright (c) 2017 "Neo4j, Inc." <http://neo4j.com>
*
* <p>
* This file is part of Neo4j Graph Algorithms <http://github.com/neo4j-contrib/neo4j-graph-algorithms>.
*
* <p>
* Neo4j Graph Algorithms is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* <p>
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* <p>
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.neo4j.graphalgo.bench;

import org.neo4j.graphalgo.ShortestPathDeltaSteppingProc;
import org.neo4j.graphalgo.ShortestPathsProc;
import org.neo4j.graphalgo.api.Graph;
import org.neo4j.graphalgo.api.HugeGraph;
import org.neo4j.graphalgo.core.GraphLoader;
import org.neo4j.graphalgo.core.heavyweight.HeavyGraphFactory;
import org.neo4j.graphalgo.core.huge.HugeGraphFactory;
import org.neo4j.graphalgo.core.utils.Pools;
import org.neo4j.graphalgo.core.utils.paged.AllocationTracker;
import org.neo4j.graphalgo.impl.AllShortestPaths;
import org.neo4j.graphalgo.impl.HugeMSBFSAllShortestPaths;
import org.neo4j.graphalgo.impl.MSBFSAllShortestPaths;
import org.neo4j.graphdb.Node;
import org.neo4j.graphdb.Relationship;
import org.neo4j.graphdb.RelationshipType;
import org.neo4j.graphdb.Transaction;
import org.neo4j.graphdb.Direction;
import org.neo4j.graphdb.*;
import org.neo4j.internal.kernel.api.exceptions.KernelException;
import org.neo4j.kernel.impl.proc.Procedures;
import org.neo4j.kernel.internal.GraphDatabaseAPI;
import org.neo4j.test.TestGraphDatabaseFactory;
import org.openjdk.jmh.annotations.Benchmark;
import org.openjdk.jmh.annotations.BenchmarkMode;
import org.openjdk.jmh.annotations.Fork;
import org.openjdk.jmh.annotations.Measurement;
import org.openjdk.jmh.annotations.Mode;
import org.openjdk.jmh.annotations.OutputTimeUnit;
import org.openjdk.jmh.annotations.Scope;
import org.openjdk.jmh.annotations.Setup;
import org.openjdk.jmh.annotations.State;
import org.openjdk.jmh.annotations.TearDown;
import org.openjdk.jmh.annotations.Threads;
import org.openjdk.jmh.annotations.Warmup;
import org.openjdk.jmh.annotations.*;

import java.util.ArrayList;
import java.util.HashMap;
Expand Down Expand Up @@ -143,7 +124,7 @@ private static Relationship createRelation(Node from, Node to) {

@Benchmark
public long _01_benchmark_ASP() {
return new AllShortestPaths(graph, Pools.DEFAULT, 8, Direction.OUTGOING)
return new AllShortestPaths(graph, Pools.DEFAULT, 8, Direction.OUTGOING)
.resultStream()
.count();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -239,9 +239,10 @@ private void downHeap(int i) {

private void ensureCapacityForInsert() {
if (size >= heap.length) {
final int oversize = ArrayUtil.oversize(size + 1, Integer.BYTES);
heap = Arrays.copyOf(
heap,
ArrayUtil.oversize(size + 1, Integer.BYTES));
oversize);
}
}

Expand Down