SetNoneScaleMutableGraph
生活随笔
收集整理的這篇文章主要介紹了
SetNoneScaleMutableGraph
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
WebGraph中的圖,基本都會在刪除結點后,進行向前移動的操作,其實在很多是侯,這是沒有必要的,甚至是有副作用的。SetNoneScaleMutableGraph就是我實現的一個沒有進行前移操作的類,還沒有做深入的測試,理論上來說,基本沒有什么問題。
?
廢話少說,直接上碼:
package cn.edu.dlut.wisdom; /* * Copyright (C) 2006-2007 Sebastiano Vigna * * This program 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 2 of the License, or (at your option) * any later version. * * 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. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * */ import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap; import it.unimi.dsi.fastutil.ints.IntAVLTreeSet; import it.unimi.dsi.fastutil.ints.IntIterator; import it.unimi.dsi.lang.MutableString; import it.unimi.dsi.webgraph.ImmutableGraph; import it.unimi.dsi.webgraph.LazyIntIterator; import it.unimi.dsi.webgraph.LazyIntIterators; import it.unimi.dsi.webgraph.NodeIterator; import it.unimi.dsi.webgraph.Transform; import java.io.*; /** A very simple mutable graph class based on {@link it.unimi.dsi.fastutil.ints.IntArrayList}s. * * <p>When creating examples for test cases or everyday usage, this class offers practical constructors. * For instance, a 3-cycle is easily built as * <pre> * new ArrayListMutableGraph( 3, new int[][] { { 0, 1 }, { 1, 2 }, { 2, 0 } } ) * </pre> * * <p>Moreover, methods like {@link #addNodes(int)} and {@link #addArc(int, int)} allow to change * the graph structure after construction, and several static factory methods provides ready-made * common graphs (see, e.g., {@link #newCompleteBinaryIntree(int)}). * * <p>A mutable graph is <em>not</em> an {@link it.unimi.dsi.webgraph.ImmutableGraph}. However, * it is possible to obtain an {@linkplain #immutableView() immutable view} of a mutable graph. * The view is valid until the exposed mutable graph is modified. A modification counter is used * to cause a <em>fail-fast</em> behaviour in case the immutable view is used after modifications. * * <p><strong>Warning</strong>: obtaining a {@link it.unimi.dsi.webgraph.NodeIterator} and using it * while modifying the graph will lead to unpredictable results. */ public class SetNoneScaleMutableGraph extends ImmutableGraph implements Serializable { /** Current number of nodes. */ protected int n; /** Current number of arcs. */ protected long m; /** Current list of successor lists. The backing array might be longer than {@link #n}. */ protected Int2ObjectOpenHashMap<IntAVLTreeSet> successors; /** Guarantees that a node index is valid. * * @param x a node index. */ protected void ensureNode(final int x) { if (!successors.containsKey(x)) { throw new IllegalArgumentException("No node " + x); } } /** Creates a new empty mutable graph. */ public SetNoneScaleMutableGraph() { successors = new Int2ObjectOpenHashMap<IntAVLTreeSet>(); } /** Creates a new mutable graph using a given number of nodes and a given list of arcs. * * @param numNodes the number of nodes in the graph. * @param arc an array of arrays of length 2, specifying the arcs; no sanity checks are performed.. */ public SetNoneScaleMutableGraph(final int numNodes, final int[][] arc) { n = numNodes; m = arc.length; // Sanitize for (int i = arc.length; i-- != 0;) { if (arc[i].length != 2) { throw new IllegalArgumentException("The arc of index " + i + " has length " + arc[i].length); } if (arc[i][ 0] < 0 || arc[i][ 1] < 0 || arc[i][ 0] >= numNodes || arc[i][ 1] >= numNodes) { throw new IllegalArgumentException("The arc of index " + i + " (" + arc[i][ 0] + ", " + arc[i][ 1] + ") is illegal"); } } successors = new Int2ObjectOpenHashMap<IntAVLTreeSet>(); for (int i = 0; i < n; i++) { successors.put(i, new IntAVLTreeSet()); } for (int i = 0; i < arc.length; i++) { successors.get(arc[i][ 0]).add(arc[i][ 1]); } } public SetNoneScaleMutableGraph(final int numNodes) { this(numNodes, new int[][]{}); } /** Creates a new mutable graph copying a given immutable graph. * * @param g an immutable graph. */ public SetNoneScaleMutableGraph(final ImmutableGraph g) { successors = new Int2ObjectOpenHashMap<IntAVLTreeSet>(); int d, s = -1; long numArcs = 0; for (NodeIterator nodeIterator = g.nodeIterator(); nodeIterator.hasNext();) { s = nodeIterator.nextInt(); d = nodeIterator.outdegree(); numArcs += d; successors.put(s, new IntAVLTreeSet(nodeIterator.successorArray(), 0, d)); } n = s + 1; m = numArcs; } /** Creates a new mutable graph using a given number of nodes and a given arc filter. * * @param numNodes the number of nodes in the graph. * @param arcFilter an arc filter which will specify which arcs go into the graph. */ public SetNoneScaleMutableGraph(final int numNodes, final Transform.ArcFilter arcFilter) { n = numNodes; successors = new Int2ObjectOpenHashMap<IntAVLTreeSet>(); for (int i = n; i-- != 0;) { successors.put(i, new IntAVLTreeSet()); for (int j = 0; j < n; j++) { if (arcFilter.accept(i, j)) { successors.get(i).add(j); m++; } } } } /** Returns a new mutable graph containing a directed cycle. * * @param numNodes the number of nodes in the cycle. */ public static SetNoneScaleMutableGraph newDirectedCycle(final int numNodes) { return new SetNoneScaleMutableGraph(numNodes, new Transform.ArcFilter() { public boolean accept(final int i, final int j) { return (i + 1) % numNodes == j; } }); } /** Returns a new mutable graph containing a bidirectional cycle. * * @param numNodes the number of nodes in the cycle. */ public static SetNoneScaleMutableGraph newBidirectionalCycle(final int numNodes) { return new SetNoneScaleMutableGraph(numNodes, new Transform.ArcFilter() { public boolean accept(final int i, final int j) { return (i + 1) % numNodes == j || (j + 1) % numNodes == i; } }); } /** Returns a new mutable graph containing a complete graph. * * @param numNodes the number of nodes in the graph. * @param loops true if you want loops, too. */ public static SetNoneScaleMutableGraph newCompleteGraph(final int numNodes, final boolean loops) { return new SetNoneScaleMutableGraph(numNodes, new Transform.ArcFilter() { public boolean accept(final int i, final int j) { return i != j || loops; } }); } /** Returns a new mutable graph containing a complete binary in-tree of given height. * * <strong>Warning</strong>: starting from version 1.7, the spurious loop * at the root has been removed. * * @param height the height of the tree (0 for the root only). */ public static SetNoneScaleMutableGraph newCompleteBinaryIntree(final int height) { return new SetNoneScaleMutableGraph((1 << (height + 1)) - 1, new Transform.ArcFilter() { public boolean accept(final int i, final int j) { return i != j && i / 2 == j; } }); } /** Returns a new mutable graph containing a complete binary out-tree of given height. * * <strong>Warning</strong>: starting from version 1.7, the spurious loop * at the root has been removed. * * @param height the height of the tree (0 for the root only). */ public static SetNoneScaleMutableGraph newCompleteBinaryOuttree(final int height) { return new SetNoneScaleMutableGraph((1 << (height + 1)) - 1, new Transform.ArcFilter() { public boolean accept(final int i, final int j) { return i != j && j / 2 == i; } }); } @Override public int numNodes() { return n; } @Override public int outdegree(final int x) { ensureNode(x); return successors.get(x).size(); } @Override public long numArcs() { return m; } @Override public int[] successorArray(final int x) { ensureNode(x); return successors.get(x).toIntArray(); } @Override public LazyIntIterator successors(final int x) { ensureNode(x); return LazyIntIterators.lazy(successors.get(x).iterator()); } @Override public NodeIterator nodeIterator() { final IntIterator it = successors.keySet().iterator(); return new NodeIterator() { int x; @Override public int outdegree() { throw new UnsupportedOperationException("Not supported yet."); } @Override public LazyIntIterator successors() { return LazyIntIterators.lazy(successors.get(x).iterator()); } @Override public int[] successorArray() { return successors.get(x).toIntArray(); } @Override public boolean hasNext() { return it.hasNext(); } @Override public Integer next() { return x = it.next(); } @Override public int nextInt() { return x = it.nextInt(); } @Override @SuppressWarnings("empty-statement") public int skip(int n) { int i; for (i = 0; i < n && hasNext(); i++, next()); return i; } @Override public void remove() throws UnsupportedOperationException { SetNoneScaleMutableGraph.this.removeNode(x); } }; } /** Adds the given number of nodes, numbering them from {@link #numNodes()} onwards. The new nodes have no successors. * * @param numNewNodes the number of new nodes. */ public void addNodes(final int x) { ensureNoneNode(x); successors.put(x, new IntAVLTreeSet()); n++; } public void ensureNoneNode(final int x) { if (successors.containsKey(x)) { throw new IllegalArgumentException("Node " + x + "is already in the Graph"); } } /** Removes the given node. All arcs incident on the node are removed, too. * * @param x the node to be removed. */ public void removeNode(final int x) { ensureNode(x); m -= successors.get(x).size(); successors.remove(x); n--; for (IntAVLTreeSet i : successors.values()) { if (i.contains(x)) { i.remove(x); m--; } } } /** Adds the given arc. * * @param x the start of the arc. * @param y the end of the arc. */ public void addArc(final int x, final int y) { ensureNode(x); ensureNode(y); if (successors.get(x).contains(y)) { return; } successors.get(x).add(y); m++; } /** Removes the given arc. * * @param x the start of the arc. * @param y the end of the arc. */ public void removeArc(final int x, final int y) { ensureNode(x); ensureNode(y); if (!successors.get(x).contains(y)) { return; } successors.get(x).remove(y); m--; } /** Compare this mutable graph to another object. * * @return true iff the given object is a mutable graph the same size, and * the successor list of every node of this graph is equal to the successor list of the corresponding node of <code>o</code>. */ @Override public boolean equals(final Object o) { if (!(o instanceof SetNoneScaleMutableGraph)) { return false; } final SetNoneScaleMutableGraph g = (SetNoneScaleMutableGraph) o; int n = numNodes(); if (n != g.numNodes()) { return false; } int[] s, t; int d; while (n-- != 0) { if ((d = outdegree(n)) != g.outdegree(n)) { return false; } s = successorArray(n); t = g.successorArray(n); while (d-- != 0) { if (s[d] != t[d]) { return false; } } } return true; } /** Returns a hash code for this mutable graph. * * @return a hash code for this mutable graph. */ @Override public int hashCode() { int n = numNodes(), h = -1; int[] s; int d; for (int i = 0; i < n; i++) { h = h * 31 + i; s = successorArray(i); d = outdegree(i); while (d-- != 0) { h = h * 31 + s[d]; } } return h; } @Override public String toString() { MutableString ms = new MutableString(); IntIterator ii; ms.append("Nodes: " + numNodes() + " Arcs: " + numArcs() + " "); for (int i = 0; i < numNodes(); i++) { ms.append("Successors of " + i + " (degree " + outdegree(i) + "):"); ii = successors.get(i).iterator(); while (ii.hasNext()) { ms.append(" " + ii.nextInt()); } ms.append(" "); } return ms.toString(); } @Override public ImmutableGraph copy() { return this; } @Override public boolean randomAccess() { return true; } /** * @param basename end with .sg * @return * @throws IOException */ public static SetNoneScaleMutableGraph load(CharSequence basename) throws IOException { ObjectInputStream oi = new ObjectInputStream(new FileInputStream(basename + ".sg")); SetNoneScaleMutableGraph sg; try { sg = (SetNoneScaleMutableGraph) oi.readObject(); } catch (ClassNotFoundException ex) { sg = null; } oi.close(); return sg; } public static void store(SetNoneScaleMutableGraph sg, CharSequence basename) throws IOException { ObjectOutputStream oo = new ObjectOutputStream(new FileOutputStream(basename + ".sg")); oo.writeObject(sg); oo.flush(); oo.close(); } }轉載于:https://www.cnblogs.com/youwang/archive/2010/04/06/2310671.html
總結
以上是生活随笔為你收集整理的SetNoneScaleMutableGraph的全部內容,希望文章能夠幫你解決所遇到的問題。