public void testGrowReplaceShrink() { Random r = new Random(); int k = 10000; String s = "A"; double t = 0; FibonacciHeap<String> h = new FibonacciHeap<>(); for (int i = 0; i < (k * 3); ++i) { // during first two-thirds, insert if (i < (k * 2)) { double d = r.nextDouble(); t += d; FibonacciHeapNode<String> n = new FibonacciHeapNode<>(s); h.insert(n, d); } // during last two-thirds, delete (so during middle // third, we'll do both insert and delete, interleaved) if (i >= k) { FibonacciHeapNode<String> n2 = h.removeMin(); t -= n2.getKey(); } } assertTrue(h.isEmpty()); // tally should come back down to zero, or thereabouts (due to roundoff) assertEquals(0.0, t, 0.00001); }
public static FibonacciHeap<NodeInfoHelper> initialStartSet( long startNode, long endNode, HashMap<Long, FibonacciHeapNode<NodeInfoHelper>> nodeHelperCache) { FibonacciHeap<NodeInfoHelper> openSet = new FibonacciHeap<NodeInfoHelper>(); NodeInfo start = OSMData.nodeHashMap.get(startNode); NodeInfoHelper initial; FibonacciHeapNode<NodeInfoHelper> fInitial; // initial start end set if (start.isIntersect()) { // initial initial = new NodeInfoHelper(startNode); initial.setCost(0); initial.setHeuristic(estimateHeuristic(startNode, endNode)); fInitial = new FibonacciHeapNode<NodeInfoHelper>(initial); openSet.insert(fInitial, initial.getTotalCost()); // push the start node nodeHelperCache.put(initial.getNodeId(), fInitial); // add cache } else { EdgeInfo edge = start.getOnEdgeList().getFirst(); double speed = edge.getTravelSpeed(); int travelTime = 1; // second int distance; if (!edge.isOneway()) { // distance from start to middle distance = edge.getStartDistance(startNode); travelTime = (int) Math.round(distance / speed * OSMParam.MILLI_PER_SECOND); initial = new NodeInfoHelper(edge.getStartNode()); initial.setCost(travelTime); initial.setHeuristic(estimateHeuristic(edge.getStartNode(), endNode)); fInitial = new FibonacciHeapNode<NodeInfoHelper>(initial); openSet.insert(fInitial, initial.getTotalCost()); // push the start node nodeHelperCache.put(initial.getNodeId(), fInitial); // add cache } distance = edge.getEndDistance(startNode); travelTime = (int) Math.round(distance / speed * OSMParam.MILLI_PER_SECOND); initial = new NodeInfoHelper(edge.getEndNode()); initial.setCost(travelTime); initial.setHeuristic(estimateHeuristic(edge.getEndNode(), endNode)); fInitial = new FibonacciHeapNode<NodeInfoHelper>(initial); openSet.insert(fInitial, initial.getTotalCost()); // push the start node nodeHelperCache.put(initial.getNodeId(), fInitial); // add cache } return openSet; }
public void relaxEdges(FibonacciHeap<Vertex> unvisited) { Vertex[] vertices = Graph.this.vertices; for (Edge edge : edges) { Vertex to = vertices[edge.to]; int newDistance = distance + edge.cost; if (newDistance < to.distance) { to.distance = newDistance; unvisited.decreaseKey(to.heapEntry, newDistance); } } }
public int getDistance(int from, int to) { FibonacciHeap<Vertex> unvisited = new FibonacciHeap<Vertex>(); for (int i = 1; i <= vertexCount; i++) { vertices[i].distance = vertexCount + 1; vertices[i].visited = false; } vertices[from].distance = 0; for (int i = 1; i <= vertexCount; i++) vertices[i].heapEntry = unvisited.enqueue(vertices[i], vertices[i].distance); while (unvisited.size() > 0) { Vertex v = unvisited.dequeueMin().getValue(); if (v.index == to || v.distance > vertexCount) return v.distance; v.relaxEdges(unvisited); } return vertices[to].distance; }
private void generateShortestPathsFrom(GraphNode source) throws NegativeEdgeException { Iterator<GraphNode> l = g.getNodeIterator(); ListIterator<GraphEdge> m; FibonacciHeap<GraphNode> h = new FibonacciHeap<GraphNode>(); GraphNode t, v; GraphEdge e; h.insert(source, 0); data(source).setPrev(null); data(source).setIncidentEdge(null); this.source = source; while (l.hasNext()) { t = l.next(); if (t == source) continue; data(t).setPrev(null); data(t).setIncidentEdge(null); h.insert(t, Integer.MAX_VALUE); } while (!h.isEmpty()) { t = h.extractMin(); m = t.getEdgeIterator(); while (m.hasNext()) { e = m.next(); if (g.getNodeById(e.getTarget().getId()) == null) { m.remove(); continue; } if (e.getWeight() < 0) { throw new NegativeEdgeException( "Dijkstra's algorithm won't work on graphs with negative edge weights!"); } v = e.getTarget(); if (h.getKey(v) > h.getKey(t) + e.getWeight()) { try { h.decreaseKey(v, h.getKey(t) + e.getWeight()); } catch (KeyNotLessException x) { // can't happen! } data(v).setPrev(t); data(v).setIncidentEdge(e); } } } }
// in honor of sf.net bug #1845376 public void testAddRemoveOne() { String s = "A"; FibonacciHeapNode<String> n = new FibonacciHeapNode<>(s); FibonacciHeap<String> h = new FibonacciHeap<>(); assertTrue(h.isEmpty()); h.insert(n, 1.0); assertFalse(h.isEmpty()); FibonacciHeapNode<String> n2 = h.removeMin(); assertEquals(s, n2.getData()); assertTrue(h.isEmpty()); }
/** * Given two Fibonacci heaps, returns a new Fibonacci heap that contains all of the elements of * the two heaps. Each of the input heaps is destructively modified by having all its elements * removed. You can continue to use those heaps, but be aware that they will be empty after this * call completes. * * @param one The first Fibonacci heap to merge. * @param two The second Fibonacci heap to merge. * @return A new FibonacciHeap containing all of the elements of both heaps. */ public static <T> FibonacciHeap<T> merge(FibonacciHeap<T> one, FibonacciHeap<T> two) { /* Create a new FibonacciHeap to hold the result. */ FibonacciHeap<T> result = new FibonacciHeap<T>(); /* Merge the two Fibonacci heap root lists together. This helper function * also computes the min of the two lists, so we can store the result in * the mMin field of the new heap. */ result.mMin = mergeLists(one.mMin, two.mMin); /* The size of the new heap is the sum of the sizes of the input heaps. */ result.mSize = one.mSize + two.mSize; /* Clear the old heaps. */ one.mSize = two.mSize = 0; one.mMin = null; two.mMin = null; /* Return the newly-merged heap. */ return result; }
/** * routing using A* algorithm with fibonacci heap basically same as routingAStar function * * @param startNode * @param endNode * @param startTime * @param pathNodeList return path * @return */ public static double routingAStarFibonacci( long startNode, long endNode, int startTime, int dayIndex, ArrayList<Long> pathNodeList) { System.out.println("start finding the path..."); int debug = 0; double totalCost = -1; try { // test store transversal nodes // HashSet<Long> transversalSet = new HashSet<Long>(); if (!OSMData.nodeHashMap.containsKey(startNode) || !OSMData.nodeHashMap.containsKey(endNode)) { System.err.println("cannot find start or end node!"); return -1; } if (startNode == endNode) { System.out.println("start node is the same as end node."); return 0; } HashSet<Long> closedSet = new HashSet<Long>(); HashMap<Long, FibonacciHeapNode<NodeInfoHelper>> nodeHelperCache = new HashMap<Long, FibonacciHeapNode<NodeInfoHelper>>(); FibonacciHeap<NodeInfoHelper> openSet = initialStartSet(startNode, endNode, nodeHelperCache); HashSet<Long> endSet = initialEndSet(endNode); NodeInfoHelper current = null; FibonacciHeapNode<NodeInfoHelper> fCurrent = null; while (!openSet.isEmpty()) { // remove current from openset fCurrent = openSet.min(); openSet.removeMin(); current = fCurrent.getData(); // if(!transversalSet.contains(current.getNodeId())) // transversalSet.add(current.getNodeId()); long nodeId = current.getNodeId(); // add current to closedset closedSet.add(nodeId); if (endSet.contains(nodeId)) { // find the destination current = current.getEndNodeHelper(endNode); totalCost = current.getCost(); break; } // for time dependent routing int timeIndex = startTime + (int) (current.getCost() / OSMParam.SECOND_PER_MINUTE / OSMRouteParam.TIME_INTERVAL); if (timeIndex > OSMRouteParam.TIME_RANGE - 1) // time [6am - 9 pm], we regard times after 9pm as constant edge weights timeIndex = OSMRouteParam.TIME_RANGE - 1; LinkedList<ToNodeInfo> adjNodeList = OSMData.adjListHashMap.get(nodeId); if (adjNodeList == null) continue; // this node cannot go anywhere double arriveTime = current.getCost(); // for each neighbor in neighbor_nodes(current) for (ToNodeInfo toNode : adjNodeList) { debug++; long toNodeId = toNode.getNodeId(); int travelTime; if (toNode.isFix()) // fix time travelTime = toNode.getTravelTime(); else // fetch from time array travelTime = toNode.getSpecificTravelTime(dayIndex, timeIndex); // tentative_g_score := g_score[current] + dist_between(current,neighbor) double costTime = arriveTime + (double) travelTime / OSMParam.MILLI_PER_SECOND; // tentative_f_score := tentative_g_score + heuristic_cost_estimate(neighbor, goal) double heuristicTime = estimateHeuristic(toNodeId, endNode); double totalCostTime = costTime + heuristicTime; // if neighbor in closedset and tentative_f_score >= f_score[neighbor] if (closedSet.contains(toNodeId) && nodeHelperCache.get(toNodeId).getData().getTotalCost() <= totalCostTime) { continue; } NodeInfoHelper node = null; FibonacciHeapNode<NodeInfoHelper> fNode = null; // if neighbor not in openset or tentative_f_score < f_score[neighbor] if (!nodeHelperCache.containsKey(toNodeId)) { // neighbor not in openset // create new one node = new NodeInfoHelper(toNodeId); node.setCost(costTime); node.setHeuristic(heuristicTime); node.setParentId(nodeId); fNode = new FibonacciHeapNode<NodeInfoHelper>(node); openSet.insert(fNode, node.getTotalCost()); nodeHelperCache.put(node.getNodeId(), fNode); } else if (nodeHelperCache.get(toNodeId).getData().getTotalCost() > totalCostTime) { // neighbor in openset fNode = nodeHelperCache.get(toNodeId); node = fNode.getData(); // update information node.setCost(costTime); node.setHeuristic(heuristicTime); node.setParentId(nodeId); if (closedSet.contains(toNodeId)) { // neighbor in closeset closedSet.remove(toNodeId); // remove neighbor form colseset openSet.insert(fNode, node.getTotalCost()); } else { // neighbor in openset, decreaseKey openSet.decreaseKey(fNode, node.getTotalCost()); } } } } if (totalCost != -1) { long traceNodeId = current.getNodeId(); pathNodeList.add(traceNodeId); // add end node traceNodeId = current.getParentId(); while (traceNodeId != 0) { pathNodeList.add(traceNodeId); // add node fCurrent = nodeHelperCache.get(traceNodeId); current = fCurrent.getData(); traceNodeId = current.getParentId(); } Collections.reverse(pathNodeList); // reverse the path list System.out.println("find the path successful!"); } else { System.out.println("can not find the path!"); } // OSMOutput.generateTransversalNodeKML(transversalSet, nodeHashMap); } catch (Exception e) { e.printStackTrace(); System.err.println( "tdsp: debug code " + debug + ", start node " + startNode + ", end node " + endNode); } return totalCost; }
private void runPrimsMST(int heapSizeCapacity, LinkedList<Float>[] forrest, int treeCount) { LinkedList<Float>[] tempMST = new LinkedList[treeCount]; for (int i = 0; i < treeCount; i++) { tempMST[i] = new LinkedList<>(); } int[] treeLabel = new int[treeCount]; for (int i = 0; i < treeCount; i++) { treeLabel[i] = -1; } for (int i = 0; i < treeCount; i++) { if (tempMST[i].size() == 0) { try { treeLabel[i] = i; FibonacciHeap heap = new FibonacciHeap(heapSizeCapacity); boolean isJoinedToOther = false; for (Iterator iter = forrest[i].listIterator(); iter.hasNext(); ) { int val1 = (int) ((float) iter.next()); float val2 = (float) iter.next(); int val3 = (int) ((float) iter.next()); int val4 = (int) ((float) iter.next()); FBHeapNode node = new FBHeapNode(); node.forrestNode1 = i; node.forrestNode2 = val1; node.value = val2; node.graphNode1 = val3; node.graphNode2 = val4; node.degree = 0; node.childHead = node.childTail = null; node.next = node.previous = null; node.parent = null; heap.insert(node, node, node, 1); } while (heap.getSize() > 0) { FBHeapNode node = heap.min(); heap.removeMin(); int temp = 0; if (node.forrestNode1 != i && tempMST[node.forrestNode1].size() == 0) { temp = node.forrestNode1; } else if (node.forrestNode2 != i && tempMST[node.forrestNode2].size() == 0) { temp = node.forrestNode2; } else if (treeLabel[node.forrestNode1] != i) { if (!isJoinedToOther) { temp = node.forrestNode1; isJoinedToOther = true; } else { heap.destroyHeap(); throw new Exception(); } } else if (treeLabel[node.forrestNode2] != i) { if (!isJoinedToOther) { temp = node.forrestNode1; isJoinedToOther = true; } else { heap.destroyHeap(); throw new Exception(); } } else { continue; } tempMST[node.forrestNode1].add((float) node.forrestNode2); tempMST[node.forrestNode2].add((float) node.forrestNode1); treeLabel[node.forrestNode1] = i; treeLabel[node.forrestNode2] = i; this.MST[node.graphNode1].add((float) node.graphNode2); this.MST[node.graphNode1].add(node.value); this.MST[node.graphNode2].add((float) node.graphNode1); this.MST[node.graphNode2].add((float) node.value); for (Iterator iter = forrest[temp].listIterator(); iter.hasNext(); ) { int val1 = (int) ((float) iter.next()); float val2 = (float) iter.next(); int val3 = (int) ((float) iter.next()); int val4 = (int) ((float) iter.next()); if (tempMST[val1].size() != 0 && treeLabel[val1] == i) { } else { FBHeapNode node2 = new FBHeapNode(); node2.degree = 0; node2.forrestNode1 = temp; node2.forrestNode2 = val1; node2.value = val2; node2.graphNode1 = val3; node2.graphNode2 = val4; node2.childHead = node2.childTail = null; node2.next = node2.previous = null; node2.parent = null; heap.insert(node2, node2, node2, 1); } } } } catch (Exception e) { continue; } } } }