@ladybugmem/icebug 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +14 -0
- package/binding.gyp +54 -0
- package/build/Release/.deps/Release/icebug.node.d +1 -0
- package/build/Release/.deps/Release/obj.target/icebug/src/addon.o.d +291 -0
- package/build/Release/icebug.node +0 -0
- package/build/Release/obj.target/icebug/src/addon.o +0 -0
- package/lib/index.d.ts +361 -0
- package/lib/index.js +102 -0
- package/package.json +42 -0
- package/src/addon.cpp +1253 -0
- package/vendor/include/networkit/GlobalState.hpp +86 -0
- package/vendor/include/networkit/Globals.hpp +41 -0
- package/vendor/include/networkit/algebraic/AlgebraicGlobals.hpp +27 -0
- package/vendor/include/networkit/algebraic/CSRGeneralMatrix.hpp +1292 -0
- package/vendor/include/networkit/algebraic/CSRMatrix.hpp +11 -0
- package/vendor/include/networkit/algebraic/DenseMatrix.hpp +537 -0
- package/vendor/include/networkit/algebraic/DynamicMatrix.hpp +514 -0
- package/vendor/include/networkit/algebraic/GraphBLAS.hpp +323 -0
- package/vendor/include/networkit/algebraic/MatrixTools.hpp +156 -0
- package/vendor/include/networkit/algebraic/Semirings.hpp +171 -0
- package/vendor/include/networkit/algebraic/SparseAccumulator.hpp +111 -0
- package/vendor/include/networkit/algebraic/Vector.hpp +371 -0
- package/vendor/include/networkit/algebraic/algorithms/AlgebraicBFS.hpp +72 -0
- package/vendor/include/networkit/algebraic/algorithms/AlgebraicBellmanFord.hpp +88 -0
- package/vendor/include/networkit/algebraic/algorithms/AlgebraicMatchingCoarsening.hpp +96 -0
- package/vendor/include/networkit/algebraic/algorithms/AlgebraicPageRank.hpp +145 -0
- package/vendor/include/networkit/algebraic/algorithms/AlgebraicSpanningEdgeCentrality.hpp +122 -0
- package/vendor/include/networkit/algebraic/algorithms/AlgebraicTriangleCounting.hpp +76 -0
- package/vendor/include/networkit/auxiliary/AlignedAllocator.hpp +113 -0
- package/vendor/include/networkit/auxiliary/ArrayTools.hpp +85 -0
- package/vendor/include/networkit/auxiliary/BloomFilter.hpp +70 -0
- package/vendor/include/networkit/auxiliary/BucketPQ.hpp +142 -0
- package/vendor/include/networkit/auxiliary/Enforce.hpp +117 -0
- package/vendor/include/networkit/auxiliary/FunctionTraits.hpp +74 -0
- package/vendor/include/networkit/auxiliary/HashUtils.hpp +28 -0
- package/vendor/include/networkit/auxiliary/IncrementalUniformRandomSelector.hpp +52 -0
- package/vendor/include/networkit/auxiliary/Log.hpp +119 -0
- package/vendor/include/networkit/auxiliary/MissingMath.hpp +48 -0
- package/vendor/include/networkit/auxiliary/Multiprecision.hpp +17 -0
- package/vendor/include/networkit/auxiliary/NumberParsing.hpp +307 -0
- package/vendor/include/networkit/auxiliary/NumericTools.hpp +57 -0
- package/vendor/include/networkit/auxiliary/Parallel.hpp +56 -0
- package/vendor/include/networkit/auxiliary/Parallelism.hpp +33 -0
- package/vendor/include/networkit/auxiliary/PrioQueue.hpp +252 -0
- package/vendor/include/networkit/auxiliary/Random.hpp +122 -0
- package/vendor/include/networkit/auxiliary/SetIntersector.hpp +72 -0
- package/vendor/include/networkit/auxiliary/SignalHandling.hpp +39 -0
- package/vendor/include/networkit/auxiliary/SortedList.hpp +128 -0
- package/vendor/include/networkit/auxiliary/SparseVector.hpp +215 -0
- package/vendor/include/networkit/auxiliary/SpinLock.hpp +23 -0
- package/vendor/include/networkit/auxiliary/StringBuilder.hpp +322 -0
- package/vendor/include/networkit/auxiliary/StringTools.hpp +76 -0
- package/vendor/include/networkit/auxiliary/TemplateUtils.hpp +76 -0
- package/vendor/include/networkit/auxiliary/Timer.hpp +145 -0
- package/vendor/include/networkit/auxiliary/VectorComparator.hpp +32 -0
- package/vendor/include/networkit/base/Algorithm.hpp +41 -0
- package/vendor/include/networkit/base/DynAlgorithm.hpp +31 -0
- package/vendor/include/networkit/centrality/ApproxBetweenness.hpp +62 -0
- package/vendor/include/networkit/centrality/ApproxCloseness.hpp +136 -0
- package/vendor/include/networkit/centrality/ApproxElectricalCloseness.hpp +156 -0
- package/vendor/include/networkit/centrality/ApproxGroupBetweenness.hpp +124 -0
- package/vendor/include/networkit/centrality/ApproxSpanningEdge.hpp +84 -0
- package/vendor/include/networkit/centrality/Betweenness.hpp +47 -0
- package/vendor/include/networkit/centrality/Centrality.hpp +98 -0
- package/vendor/include/networkit/centrality/Closeness.hpp +107 -0
- package/vendor/include/networkit/centrality/ComplexPaths.hpp +113 -0
- package/vendor/include/networkit/centrality/CoreDecomposition.hpp +161 -0
- package/vendor/include/networkit/centrality/DegreeCentrality.hpp +55 -0
- package/vendor/include/networkit/centrality/DynApproxBetweenness.hpp +95 -0
- package/vendor/include/networkit/centrality/DynBetweenness.hpp +99 -0
- package/vendor/include/networkit/centrality/DynBetweennessOneNode.hpp +98 -0
- package/vendor/include/networkit/centrality/DynKatzCentrality.hpp +115 -0
- package/vendor/include/networkit/centrality/DynTopHarmonicCloseness.hpp +223 -0
- package/vendor/include/networkit/centrality/EigenvectorCentrality.hpp +41 -0
- package/vendor/include/networkit/centrality/EstimateBetweenness.hpp +51 -0
- package/vendor/include/networkit/centrality/ForestCentrality.hpp +112 -0
- package/vendor/include/networkit/centrality/GedWalk.hpp +225 -0
- package/vendor/include/networkit/centrality/GroupCloseness.hpp +115 -0
- package/vendor/include/networkit/centrality/GroupClosenessGrowShrink.hpp +78 -0
- package/vendor/include/networkit/centrality/GroupClosenessLocalSearch.hpp +77 -0
- package/vendor/include/networkit/centrality/GroupClosenessLocalSwaps.hpp +106 -0
- package/vendor/include/networkit/centrality/GroupDegree.hpp +155 -0
- package/vendor/include/networkit/centrality/GroupHarmonicCloseness.hpp +83 -0
- package/vendor/include/networkit/centrality/HarmonicCloseness.hpp +48 -0
- package/vendor/include/networkit/centrality/KPathCentrality.hpp +52 -0
- package/vendor/include/networkit/centrality/KadabraBetweenness.hpp +242 -0
- package/vendor/include/networkit/centrality/KatzCentrality.hpp +62 -0
- package/vendor/include/networkit/centrality/LaplacianCentrality.hpp +44 -0
- package/vendor/include/networkit/centrality/LocalClusteringCoefficient.hpp +60 -0
- package/vendor/include/networkit/centrality/LocalPartitionCoverage.hpp +43 -0
- package/vendor/include/networkit/centrality/LocalSquareClusteringCoefficient.hpp +42 -0
- package/vendor/include/networkit/centrality/PageRank.hpp +101 -0
- package/vendor/include/networkit/centrality/PermanenceCentrality.hpp +48 -0
- package/vendor/include/networkit/centrality/Sfigality.hpp +45 -0
- package/vendor/include/networkit/centrality/SpanningEdgeCentrality.hpp +86 -0
- package/vendor/include/networkit/centrality/TopCloseness.hpp +136 -0
- package/vendor/include/networkit/centrality/TopHarmonicCloseness.hpp +151 -0
- package/vendor/include/networkit/clique/MaximalCliques.hpp +83 -0
- package/vendor/include/networkit/coarsening/ClusteringProjector.hpp +59 -0
- package/vendor/include/networkit/coarsening/CoarsenedGraphView.hpp +156 -0
- package/vendor/include/networkit/coarsening/GraphCoarsening.hpp +57 -0
- package/vendor/include/networkit/coarsening/MatchingCoarsening.hpp +43 -0
- package/vendor/include/networkit/coarsening/ParallelPartitionCoarsening.hpp +33 -0
- package/vendor/include/networkit/coarsening/ParallelPartitionCoarseningView.hpp +62 -0
- package/vendor/include/networkit/community/AdjustedRandMeasure.hpp +31 -0
- package/vendor/include/networkit/community/ClusteringGenerator.hpp +75 -0
- package/vendor/include/networkit/community/CommunityDetectionAlgorithm.hpp +58 -0
- package/vendor/include/networkit/community/Conductance.hpp +32 -0
- package/vendor/include/networkit/community/CoverF1Similarity.hpp +53 -0
- package/vendor/include/networkit/community/CoverHubDominance.hpp +38 -0
- package/vendor/include/networkit/community/Coverage.hpp +25 -0
- package/vendor/include/networkit/community/CutClustering.hpp +62 -0
- package/vendor/include/networkit/community/DissimilarityMeasure.hpp +31 -0
- package/vendor/include/networkit/community/DynamicNMIDistance.hpp +44 -0
- package/vendor/include/networkit/community/EdgeCut.hpp +24 -0
- package/vendor/include/networkit/community/GraphClusteringTools.hpp +103 -0
- package/vendor/include/networkit/community/GraphStructuralRandMeasure.hpp +28 -0
- package/vendor/include/networkit/community/HubDominance.hpp +46 -0
- package/vendor/include/networkit/community/IntrapartitionDensity.hpp +44 -0
- package/vendor/include/networkit/community/IsolatedInterpartitionConductance.hpp +40 -0
- package/vendor/include/networkit/community/IsolatedInterpartitionExpansion.hpp +40 -0
- package/vendor/include/networkit/community/JaccardMeasure.hpp +25 -0
- package/vendor/include/networkit/community/LFM.hpp +49 -0
- package/vendor/include/networkit/community/LPDegreeOrdered.hpp +48 -0
- package/vendor/include/networkit/community/LocalCommunityEvaluation.hpp +100 -0
- package/vendor/include/networkit/community/LocalCoverEvaluation.hpp +31 -0
- package/vendor/include/networkit/community/LocalPartitionEvaluation.hpp +31 -0
- package/vendor/include/networkit/community/LouvainMapEquation.hpp +135 -0
- package/vendor/include/networkit/community/Modularity.hpp +54 -0
- package/vendor/include/networkit/community/NMIDistance.hpp +28 -0
- package/vendor/include/networkit/community/NodeStructuralRandMeasure.hpp +27 -0
- package/vendor/include/networkit/community/OverlappingCommunityDetectionAlgorithm.hpp +51 -0
- package/vendor/include/networkit/community/OverlappingNMIDistance.hpp +175 -0
- package/vendor/include/networkit/community/PLM.hpp +89 -0
- package/vendor/include/networkit/community/PLP.hpp +83 -0
- package/vendor/include/networkit/community/ParallelAgglomerativeClusterer.hpp +37 -0
- package/vendor/include/networkit/community/ParallelLeiden.hpp +96 -0
- package/vendor/include/networkit/community/ParallelLeidenView.hpp +138 -0
- package/vendor/include/networkit/community/PartitionFragmentation.hpp +30 -0
- package/vendor/include/networkit/community/PartitionHubDominance.hpp +37 -0
- package/vendor/include/networkit/community/PartitionIntersection.hpp +25 -0
- package/vendor/include/networkit/community/QualityMeasure.hpp +27 -0
- package/vendor/include/networkit/community/SampledGraphStructuralRandMeasure.hpp +40 -0
- package/vendor/include/networkit/community/SampledNodeStructuralRandMeasure.hpp +40 -0
- package/vendor/include/networkit/community/StablePartitionNodes.hpp +48 -0
- package/vendor/include/networkit/components/BiconnectedComponents.hpp +116 -0
- package/vendor/include/networkit/components/ComponentDecomposition.hpp +72 -0
- package/vendor/include/networkit/components/ConnectedComponents.hpp +55 -0
- package/vendor/include/networkit/components/DynConnectedComponents.hpp +71 -0
- package/vendor/include/networkit/components/DynWeaklyConnectedComponents.hpp +73 -0
- package/vendor/include/networkit/components/ParallelConnectedComponents.hpp +44 -0
- package/vendor/include/networkit/components/RandomSpanningForest.hpp +36 -0
- package/vendor/include/networkit/components/StronglyConnectedComponents.hpp +50 -0
- package/vendor/include/networkit/components/WeaklyConnectedComponents.hpp +59 -0
- package/vendor/include/networkit/correlation/Assortativity.hpp +64 -0
- package/vendor/include/networkit/distance/APSP.hpp +70 -0
- package/vendor/include/networkit/distance/AStar.hpp +68 -0
- package/vendor/include/networkit/distance/AStarGeneral.hpp +110 -0
- package/vendor/include/networkit/distance/AdamicAdarDistance.hpp +52 -0
- package/vendor/include/networkit/distance/AffectedNodes.hpp +130 -0
- package/vendor/include/networkit/distance/AlgebraicDistance.hpp +63 -0
- package/vendor/include/networkit/distance/BFS.hpp +43 -0
- package/vendor/include/networkit/distance/BidirectionalBFS.hpp +51 -0
- package/vendor/include/networkit/distance/BidirectionalDijkstra.hpp +69 -0
- package/vendor/include/networkit/distance/CommuteTimeDistance.hpp +89 -0
- package/vendor/include/networkit/distance/Diameter.hpp +97 -0
- package/vendor/include/networkit/distance/Dijkstra.hpp +50 -0
- package/vendor/include/networkit/distance/DynAPSP.hpp +67 -0
- package/vendor/include/networkit/distance/DynBFS.hpp +56 -0
- package/vendor/include/networkit/distance/DynDijkstra.hpp +57 -0
- package/vendor/include/networkit/distance/DynPrunedLandmarkLabeling.hpp +67 -0
- package/vendor/include/networkit/distance/DynSSSP.hpp +87 -0
- package/vendor/include/networkit/distance/Eccentricity.hpp +32 -0
- package/vendor/include/networkit/distance/EffectiveDiameter.hpp +47 -0
- package/vendor/include/networkit/distance/EffectiveDiameterApproximation.hpp +57 -0
- package/vendor/include/networkit/distance/FloydWarshall.hpp +93 -0
- package/vendor/include/networkit/distance/GraphDistance.hpp +49 -0
- package/vendor/include/networkit/distance/HopPlotApproximation.hpp +62 -0
- package/vendor/include/networkit/distance/IncompleteDijkstra.hpp +66 -0
- package/vendor/include/networkit/distance/IncompleteSSSP.hpp +41 -0
- package/vendor/include/networkit/distance/JaccardDistance.hpp +57 -0
- package/vendor/include/networkit/distance/MultiTargetBFS.hpp +32 -0
- package/vendor/include/networkit/distance/MultiTargetDijkstra.hpp +40 -0
- package/vendor/include/networkit/distance/NeighborhoodFunction.hpp +47 -0
- package/vendor/include/networkit/distance/NeighborhoodFunctionApproximation.hpp +56 -0
- package/vendor/include/networkit/distance/NeighborhoodFunctionHeuristic.hpp +56 -0
- package/vendor/include/networkit/distance/NodeDistance.hpp +54 -0
- package/vendor/include/networkit/distance/PrunedLandmarkLabeling.hpp +76 -0
- package/vendor/include/networkit/distance/ReverseBFS.hpp +46 -0
- package/vendor/include/networkit/distance/SPSP.hpp +143 -0
- package/vendor/include/networkit/distance/SSSP.hpp +216 -0
- package/vendor/include/networkit/distance/STSP.hpp +193 -0
- package/vendor/include/networkit/distance/Volume.hpp +66 -0
- package/vendor/include/networkit/dynamics/DGSStreamParser.hpp +40 -0
- package/vendor/include/networkit/dynamics/DGSWriter.hpp +30 -0
- package/vendor/include/networkit/dynamics/GraphDifference.hpp +110 -0
- package/vendor/include/networkit/dynamics/GraphEvent.hpp +55 -0
- package/vendor/include/networkit/dynamics/GraphEventHandler.hpp +39 -0
- package/vendor/include/networkit/dynamics/GraphEventProxy.hpp +55 -0
- package/vendor/include/networkit/dynamics/GraphUpdater.hpp +38 -0
- package/vendor/include/networkit/edgescores/ChibaNishizekiQuadrangleEdgeScore.hpp +26 -0
- package/vendor/include/networkit/edgescores/ChibaNishizekiTriangleEdgeScore.hpp +33 -0
- package/vendor/include/networkit/edgescores/EdgeScore.hpp +50 -0
- package/vendor/include/networkit/edgescores/EdgeScoreAsWeight.hpp +33 -0
- package/vendor/include/networkit/edgescores/EdgeScoreBlender.hpp +33 -0
- package/vendor/include/networkit/edgescores/EdgeScoreLinearizer.hpp +32 -0
- package/vendor/include/networkit/edgescores/EdgeScoreNormalizer.hpp +35 -0
- package/vendor/include/networkit/edgescores/GeometricMeanScore.hpp +29 -0
- package/vendor/include/networkit/edgescores/PrefixJaccardScore.hpp +23 -0
- package/vendor/include/networkit/edgescores/TriangleEdgeScore.hpp +39 -0
- package/vendor/include/networkit/embedding/Node2Vec.hpp +83 -0
- package/vendor/include/networkit/flow/EdmondsKarp.hpp +112 -0
- package/vendor/include/networkit/generators/BarabasiAlbertGenerator.hpp +87 -0
- package/vendor/include/networkit/generators/ChungLuGenerator.hpp +46 -0
- package/vendor/include/networkit/generators/ChungLuGeneratorAlamEtAl.hpp +63 -0
- package/vendor/include/networkit/generators/ClusteredRandomGraphGenerator.hpp +56 -0
- package/vendor/include/networkit/generators/ConfigurationModel.hpp +36 -0
- package/vendor/include/networkit/generators/DorogovtsevMendesGenerator.hpp +33 -0
- package/vendor/include/networkit/generators/DynamicBarabasiAlbertGenerator.hpp +33 -0
- package/vendor/include/networkit/generators/DynamicDGSParser.hpp +51 -0
- package/vendor/include/networkit/generators/DynamicDorogovtsevMendesGenerator.hpp +34 -0
- package/vendor/include/networkit/generators/DynamicForestFireGenerator.hpp +55 -0
- package/vendor/include/networkit/generators/DynamicGraphGenerator.hpp +40 -0
- package/vendor/include/networkit/generators/DynamicGraphSource.hpp +79 -0
- package/vendor/include/networkit/generators/DynamicHyperbolicGenerator.hpp +143 -0
- package/vendor/include/networkit/generators/DynamicPathGenerator.hpp +26 -0
- package/vendor/include/networkit/generators/DynamicPubWebGenerator.hpp +54 -0
- package/vendor/include/networkit/generators/EdgeSwitchingMarkovChainGenerator.hpp +65 -0
- package/vendor/include/networkit/generators/ErdosRenyiEnumerator.hpp +318 -0
- package/vendor/include/networkit/generators/ErdosRenyiGenerator.hpp +56 -0
- package/vendor/include/networkit/generators/HavelHakimiGenerator.hpp +48 -0
- package/vendor/include/networkit/generators/HyperbolicGenerator.hpp +236 -0
- package/vendor/include/networkit/generators/LFRGenerator.hpp +175 -0
- package/vendor/include/networkit/generators/MocnikGenerator.hpp +147 -0
- package/vendor/include/networkit/generators/MocnikGeneratorBasic.hpp +58 -0
- package/vendor/include/networkit/generators/PowerlawDegreeSequence.hpp +128 -0
- package/vendor/include/networkit/generators/PubWebGenerator.hpp +94 -0
- package/vendor/include/networkit/generators/RegularRingLatticeGenerator.hpp +37 -0
- package/vendor/include/networkit/generators/RmatGenerator.hpp +67 -0
- package/vendor/include/networkit/generators/StaticDegreeSequenceGenerator.hpp +42 -0
- package/vendor/include/networkit/generators/StaticGraphGenerator.hpp +30 -0
- package/vendor/include/networkit/generators/StochasticBlockmodel.hpp +41 -0
- package/vendor/include/networkit/generators/WattsStrogatzGenerator.hpp +43 -0
- package/vendor/include/networkit/generators/quadtree/QuadNode.hpp +857 -0
- package/vendor/include/networkit/generators/quadtree/QuadNodeCartesianEuclid.hpp +587 -0
- package/vendor/include/networkit/generators/quadtree/QuadNodePolarEuclid.hpp +726 -0
- package/vendor/include/networkit/generators/quadtree/Quadtree.hpp +232 -0
- package/vendor/include/networkit/generators/quadtree/QuadtreeCartesianEuclid.hpp +149 -0
- package/vendor/include/networkit/generators/quadtree/QuadtreePolarEuclid.hpp +143 -0
- package/vendor/include/networkit/geometric/HyperbolicSpace.hpp +248 -0
- package/vendor/include/networkit/geometric/Point2DWithIndex.hpp +145 -0
- package/vendor/include/networkit/global/ClusteringCoefficient.hpp +42 -0
- package/vendor/include/networkit/global/GlobalClusteringCoefficient.hpp +24 -0
- package/vendor/include/networkit/graph/Attributes.hpp +568 -0
- package/vendor/include/networkit/graph/BFS.hpp +111 -0
- package/vendor/include/networkit/graph/DFS.hpp +71 -0
- package/vendor/include/networkit/graph/Dijkstra.hpp +83 -0
- package/vendor/include/networkit/graph/EdgeIterators.hpp +171 -0
- package/vendor/include/networkit/graph/Graph.hpp +2083 -0
- package/vendor/include/networkit/graph/GraphBuilder.hpp +289 -0
- package/vendor/include/networkit/graph/GraphR.hpp +133 -0
- package/vendor/include/networkit/graph/GraphTools.hpp +589 -0
- package/vendor/include/networkit/graph/GraphW.hpp +1236 -0
- package/vendor/include/networkit/graph/KruskalMSF.hpp +50 -0
- package/vendor/include/networkit/graph/NeighborIterators.hpp +163 -0
- package/vendor/include/networkit/graph/NodeIterators.hpp +127 -0
- package/vendor/include/networkit/graph/PrimMSF.hpp +66 -0
- package/vendor/include/networkit/graph/RandomMaximumSpanningForest.hpp +133 -0
- package/vendor/include/networkit/graph/SpanningForest.hpp +41 -0
- package/vendor/include/networkit/graph/TopologicalSort.hpp +87 -0
- package/vendor/include/networkit/graph/UnionMaximumSpanningForest.hpp +126 -0
- package/vendor/include/networkit/graph/test/GraphBuilderBenchmark.hpp +68 -0
- package/vendor/include/networkit/independentset/IndependentSetFinder.hpp +44 -0
- package/vendor/include/networkit/independentset/Luby.hpp +27 -0
- package/vendor/include/networkit/io/BinaryEdgeListPartitionReader.hpp +45 -0
- package/vendor/include/networkit/io/BinaryEdgeListPartitionWriter.hpp +47 -0
- package/vendor/include/networkit/io/BinaryPartitionReader.hpp +41 -0
- package/vendor/include/networkit/io/BinaryPartitionWriter.hpp +44 -0
- package/vendor/include/networkit/io/CoverReader.hpp +27 -0
- package/vendor/include/networkit/io/CoverWriter.hpp +21 -0
- package/vendor/include/networkit/io/DGSReader.hpp +39 -0
- package/vendor/include/networkit/io/DibapGraphReader.hpp +43 -0
- package/vendor/include/networkit/io/DotGraphWriter.hpp +39 -0
- package/vendor/include/networkit/io/DotPartitionWriter.hpp +23 -0
- package/vendor/include/networkit/io/DynamicGraphReader.hpp +29 -0
- package/vendor/include/networkit/io/EdgeListCoverReader.hpp +35 -0
- package/vendor/include/networkit/io/EdgeListPartitionReader.hpp +43 -0
- package/vendor/include/networkit/io/EdgeListReader.hpp +61 -0
- package/vendor/include/networkit/io/EdgeListWriter.hpp +48 -0
- package/vendor/include/networkit/io/GMLGraphReader.hpp +33 -0
- package/vendor/include/networkit/io/GMLGraphWriter.hpp +33 -0
- package/vendor/include/networkit/io/GraphIO.hpp +52 -0
- package/vendor/include/networkit/io/GraphReader.hpp +40 -0
- package/vendor/include/networkit/io/GraphToolBinaryReader.hpp +71 -0
- package/vendor/include/networkit/io/GraphToolBinaryWriter.hpp +61 -0
- package/vendor/include/networkit/io/GraphWriter.hpp +27 -0
- package/vendor/include/networkit/io/KONECTGraphReader.hpp +44 -0
- package/vendor/include/networkit/io/LineFileReader.hpp +42 -0
- package/vendor/include/networkit/io/METISGraphReader.hpp +36 -0
- package/vendor/include/networkit/io/METISGraphWriter.hpp +29 -0
- package/vendor/include/networkit/io/METISParser.hpp +63 -0
- package/vendor/include/networkit/io/MTXGraphReader.hpp +31 -0
- package/vendor/include/networkit/io/MTXParser.hpp +87 -0
- package/vendor/include/networkit/io/MatrixMarketReader.hpp +33 -0
- package/vendor/include/networkit/io/MatrixReader.hpp +33 -0
- package/vendor/include/networkit/io/MemoryMappedFile.hpp +80 -0
- package/vendor/include/networkit/io/NetworkitBinaryGraph.hpp +144 -0
- package/vendor/include/networkit/io/NetworkitBinaryReader.hpp +50 -0
- package/vendor/include/networkit/io/NetworkitBinaryWriter.hpp +71 -0
- package/vendor/include/networkit/io/PartitionReader.hpp +34 -0
- package/vendor/include/networkit/io/PartitionWriter.hpp +31 -0
- package/vendor/include/networkit/io/RBGraphReader.hpp +37 -0
- package/vendor/include/networkit/io/RBMatrixReader.hpp +49 -0
- package/vendor/include/networkit/io/RasterReader.hpp +40 -0
- package/vendor/include/networkit/io/SNAPEdgeListPartitionReader.hpp +28 -0
- package/vendor/include/networkit/io/SNAPGraphReader.hpp +53 -0
- package/vendor/include/networkit/io/SNAPGraphWriter.hpp +53 -0
- package/vendor/include/networkit/io/ThrillGraphBinaryReader.hpp +44 -0
- package/vendor/include/networkit/io/ThrillGraphBinaryWriter.hpp +27 -0
- package/vendor/include/networkit/layout/LayoutAlgorithm.hpp +39 -0
- package/vendor/include/networkit/linkprediction/AdamicAdarIndex.hpp +37 -0
- package/vendor/include/networkit/linkprediction/AdjustedRandIndex.hpp +36 -0
- package/vendor/include/networkit/linkprediction/AlgebraicDistanceIndex.hpp +70 -0
- package/vendor/include/networkit/linkprediction/CommonNeighborsIndex.hpp +39 -0
- package/vendor/include/networkit/linkprediction/EvaluationMetric.hpp +135 -0
- package/vendor/include/networkit/linkprediction/JaccardIndex.hpp +44 -0
- package/vendor/include/networkit/linkprediction/KatzIndex.hpp +84 -0
- package/vendor/include/networkit/linkprediction/LinkPredictor.hpp +98 -0
- package/vendor/include/networkit/linkprediction/LinkThresholder.hpp +56 -0
- package/vendor/include/networkit/linkprediction/MissingLinksFinder.hpp +60 -0
- package/vendor/include/networkit/linkprediction/NeighborhoodDistanceIndex.hpp +42 -0
- package/vendor/include/networkit/linkprediction/NeighborhoodUtility.hpp +54 -0
- package/vendor/include/networkit/linkprediction/NeighborsMeasureIndex.hpp +48 -0
- package/vendor/include/networkit/linkprediction/PrecisionRecallMetric.hpp +40 -0
- package/vendor/include/networkit/linkprediction/PredictionsSorter.hpp +66 -0
- package/vendor/include/networkit/linkprediction/PreferentialAttachmentIndex.hpp +37 -0
- package/vendor/include/networkit/linkprediction/ROCMetric.hpp +39 -0
- package/vendor/include/networkit/linkprediction/RandomLinkSampler.hpp +47 -0
- package/vendor/include/networkit/linkprediction/ResourceAllocationIndex.hpp +38 -0
- package/vendor/include/networkit/linkprediction/SameCommunityIndex.hpp +50 -0
- package/vendor/include/networkit/linkprediction/TotalNeighborsIndex.hpp +39 -0
- package/vendor/include/networkit/linkprediction/UDegreeIndex.hpp +35 -0
- package/vendor/include/networkit/linkprediction/VDegreeIndex.hpp +35 -0
- package/vendor/include/networkit/matching/BMatcher.hpp +52 -0
- package/vendor/include/networkit/matching/BMatching.hpp +115 -0
- package/vendor/include/networkit/matching/BSuitorMatcher.hpp +170 -0
- package/vendor/include/networkit/matching/DynamicBSuitorMatcher.hpp +78 -0
- package/vendor/include/networkit/matching/LocalMaxMatcher.hpp +35 -0
- package/vendor/include/networkit/matching/Matcher.hpp +55 -0
- package/vendor/include/networkit/matching/Matching.hpp +111 -0
- package/vendor/include/networkit/matching/PathGrowingMatcher.hpp +46 -0
- package/vendor/include/networkit/matching/SuitorMatcher.hpp +62 -0
- package/vendor/include/networkit/numerics/ConjugateGradient.hpp +163 -0
- package/vendor/include/networkit/numerics/GaussSeidelRelaxation.hpp +99 -0
- package/vendor/include/networkit/numerics/LAMG/LAMGSettings.hpp +70 -0
- package/vendor/include/networkit/numerics/LAMG/Lamg.hpp +460 -0
- package/vendor/include/networkit/numerics/LAMG/Level/EliminationStage.hpp +47 -0
- package/vendor/include/networkit/numerics/LAMG/Level/Level.hpp +56 -0
- package/vendor/include/networkit/numerics/LAMG/Level/LevelAggregation.hpp +52 -0
- package/vendor/include/networkit/numerics/LAMG/Level/LevelElimination.hpp +133 -0
- package/vendor/include/networkit/numerics/LAMG/Level/LevelFinest.hpp +28 -0
- package/vendor/include/networkit/numerics/LAMG/LevelHierarchy.hpp +165 -0
- package/vendor/include/networkit/numerics/LAMG/MultiLevelSetup.hpp +1090 -0
- package/vendor/include/networkit/numerics/LAMG/SolverLamg.hpp +316 -0
- package/vendor/include/networkit/numerics/LinearSolver.hpp +151 -0
- package/vendor/include/networkit/numerics/Preconditioner/DiagonalPreconditioner.hpp +61 -0
- package/vendor/include/networkit/numerics/Preconditioner/IdentityPreconditioner.hpp +36 -0
- package/vendor/include/networkit/numerics/Smoother.hpp +37 -0
- package/vendor/include/networkit/overlap/HashingOverlapper.hpp +28 -0
- package/vendor/include/networkit/overlap/Overlapper.hpp +27 -0
- package/vendor/include/networkit/planarity/LeftRightPlanarityCheck.hpp +113 -0
- package/vendor/include/networkit/randomization/Curveball.hpp +49 -0
- package/vendor/include/networkit/randomization/CurveballGlobalTradeGenerator.hpp +39 -0
- package/vendor/include/networkit/randomization/CurveballUniformTradeGenerator.hpp +39 -0
- package/vendor/include/networkit/randomization/DegreePreservingShuffle.hpp +82 -0
- package/vendor/include/networkit/randomization/EdgeSwitching.hpp +157 -0
- package/vendor/include/networkit/randomization/GlobalCurveball.hpp +69 -0
- package/vendor/include/networkit/randomization/GlobalTradeSequence.hpp +303 -0
- package/vendor/include/networkit/reachability/AllSimplePaths.hpp +122 -0
- package/vendor/include/networkit/reachability/ReachableNodes.hpp +83 -0
- package/vendor/include/networkit/scd/ApproximatePageRank.hpp +51 -0
- package/vendor/include/networkit/scd/CliqueDetect.hpp +55 -0
- package/vendor/include/networkit/scd/CombinedSCD.hpp +51 -0
- package/vendor/include/networkit/scd/GCE.hpp +42 -0
- package/vendor/include/networkit/scd/LFMLocal.hpp +54 -0
- package/vendor/include/networkit/scd/LocalT.hpp +40 -0
- package/vendor/include/networkit/scd/LocalTightnessExpansion.hpp +46 -0
- package/vendor/include/networkit/scd/PageRankNibble.hpp +55 -0
- package/vendor/include/networkit/scd/RandomBFS.hpp +33 -0
- package/vendor/include/networkit/scd/SCDGroundTruthComparison.hpp +121 -0
- package/vendor/include/networkit/scd/SelectiveCommunityDetector.hpp +76 -0
- package/vendor/include/networkit/scd/SetConductance.hpp +47 -0
- package/vendor/include/networkit/scd/TCE.hpp +41 -0
- package/vendor/include/networkit/scd/TwoPhaseL.hpp +40 -0
- package/vendor/include/networkit/scoring/EdgeScoring.hpp +44 -0
- package/vendor/include/networkit/scoring/ModularityScoring.hpp +79 -0
- package/vendor/include/networkit/simulation/EpidemicSimulationSEIR.hpp +59 -0
- package/vendor/include/networkit/sparsification/ChanceCorrectedTriangleScore.hpp +28 -0
- package/vendor/include/networkit/sparsification/ForestFireScore.hpp +34 -0
- package/vendor/include/networkit/sparsification/GlobalThresholdFilter.hpp +40 -0
- package/vendor/include/networkit/sparsification/LocalDegreeScore.hpp +30 -0
- package/vendor/include/networkit/sparsification/LocalFilterScore.hpp +124 -0
- package/vendor/include/networkit/sparsification/LocalSimilarityScore.hpp +63 -0
- package/vendor/include/networkit/sparsification/MultiscaleScore.hpp +38 -0
- package/vendor/include/networkit/sparsification/RandomEdgeScore.hpp +33 -0
- package/vendor/include/networkit/sparsification/RandomNodeEdgeScore.hpp +29 -0
- package/vendor/include/networkit/sparsification/SCANStructuralSimilarityScore.hpp +23 -0
- package/vendor/include/networkit/sparsification/SimmelianOverlapScore.hpp +35 -0
- package/vendor/include/networkit/sparsification/SimmelianScore.hpp +92 -0
- package/vendor/include/networkit/sparsification/Sparsifiers.hpp +166 -0
- package/vendor/include/networkit/structures/Cover.hpp +248 -0
- package/vendor/include/networkit/structures/LocalCommunity.hpp +363 -0
- package/vendor/include/networkit/structures/Partition.hpp +335 -0
- package/vendor/include/networkit/structures/UnionFind.hpp +66 -0
- package/vendor/include/networkit/viz/GraphLayoutAlgorithm.hpp +157 -0
- package/vendor/include/networkit/viz/MaxentStress.hpp +346 -0
- package/vendor/include/networkit/viz/Octree.hpp +428 -0
- package/vendor/include/networkit/viz/PivotMDS.hpp +63 -0
- package/vendor/include/networkit/viz/Point.hpp +415 -0
- package/vendor/include/networkit/viz/PostscriptWriter.hpp +78 -0
- package/vendor/include/tlx/algorithm/exclusive_scan.hpp +56 -0
- package/vendor/include/tlx/algorithm/is_sorted_cmp.hpp +56 -0
- package/vendor/include/tlx/algorithm/merge_advance.hpp +177 -0
- package/vendor/include/tlx/algorithm/merge_combine.hpp +76 -0
- package/vendor/include/tlx/algorithm/multisequence_partition.hpp +346 -0
- package/vendor/include/tlx/algorithm/multisequence_selection.hpp +351 -0
- package/vendor/include/tlx/algorithm/multiway_merge.hpp +1385 -0
- package/vendor/include/tlx/algorithm/multiway_merge_splitting.hpp +257 -0
- package/vendor/include/tlx/algorithm/parallel_multiway_merge.hpp +408 -0
- package/vendor/include/tlx/algorithm/random_bipartition_shuffle.hpp +116 -0
- package/vendor/include/tlx/algorithm.hpp +36 -0
- package/vendor/include/tlx/allocator_base.hpp +100 -0
- package/vendor/include/tlx/backtrace.hpp +54 -0
- package/vendor/include/tlx/cmdline_parser.hpp +498 -0
- package/vendor/include/tlx/container/btree.hpp +3977 -0
- package/vendor/include/tlx/container/btree_map.hpp +634 -0
- package/vendor/include/tlx/container/btree_multimap.hpp +627 -0
- package/vendor/include/tlx/container/btree_multiset.hpp +612 -0
- package/vendor/include/tlx/container/btree_set.hpp +612 -0
- package/vendor/include/tlx/container/d_ary_addressable_int_heap.hpp +416 -0
- package/vendor/include/tlx/container/d_ary_heap.hpp +311 -0
- package/vendor/include/tlx/container/loser_tree.hpp +1009 -0
- package/vendor/include/tlx/container/lru_cache.hpp +319 -0
- package/vendor/include/tlx/container/radix_heap.hpp +735 -0
- package/vendor/include/tlx/container/ring_buffer.hpp +428 -0
- package/vendor/include/tlx/container/simple_vector.hpp +304 -0
- package/vendor/include/tlx/container/splay_tree.hpp +399 -0
- package/vendor/include/tlx/container/string_view.hpp +805 -0
- package/vendor/include/tlx/container.hpp +40 -0
- package/vendor/include/tlx/counting_ptr.hpp +522 -0
- package/vendor/include/tlx/define/attribute_always_inline.hpp +34 -0
- package/vendor/include/tlx/define/attribute_fallthrough.hpp +36 -0
- package/vendor/include/tlx/define/attribute_format_printf.hpp +34 -0
- package/vendor/include/tlx/define/attribute_packed.hpp +34 -0
- package/vendor/include/tlx/define/attribute_warn_unused_result.hpp +34 -0
- package/vendor/include/tlx/define/constexpr.hpp +31 -0
- package/vendor/include/tlx/define/deprecated.hpp +39 -0
- package/vendor/include/tlx/define/endian.hpp +49 -0
- package/vendor/include/tlx/define/likely.hpp +33 -0
- package/vendor/include/tlx/define/visibility_hidden.hpp +34 -0
- package/vendor/include/tlx/define.hpp +36 -0
- package/vendor/include/tlx/delegate.hpp +524 -0
- package/vendor/include/tlx/die/core.hpp +311 -0
- package/vendor/include/tlx/die.hpp +106 -0
- package/vendor/include/tlx/digest/md5.hpp +81 -0
- package/vendor/include/tlx/digest/sha1.hpp +81 -0
- package/vendor/include/tlx/digest/sha256.hpp +81 -0
- package/vendor/include/tlx/digest/sha512.hpp +81 -0
- package/vendor/include/tlx/digest.hpp +30 -0
- package/vendor/include/tlx/logger/all.hpp +33 -0
- package/vendor/include/tlx/logger/array.hpp +43 -0
- package/vendor/include/tlx/logger/core.hpp +287 -0
- package/vendor/include/tlx/logger/deque.hpp +42 -0
- package/vendor/include/tlx/logger/map.hpp +65 -0
- package/vendor/include/tlx/logger/set.hpp +60 -0
- package/vendor/include/tlx/logger/tuple.hpp +66 -0
- package/vendor/include/tlx/logger/unordered_map.hpp +68 -0
- package/vendor/include/tlx/logger/unordered_set.hpp +64 -0
- package/vendor/include/tlx/logger/wrap_unprintable.hpp +75 -0
- package/vendor/include/tlx/logger.hpp +44 -0
- package/vendor/include/tlx/math/abs_diff.hpp +35 -0
- package/vendor/include/tlx/math/aggregate.hpp +231 -0
- package/vendor/include/tlx/math/aggregate_min_max.hpp +116 -0
- package/vendor/include/tlx/math/bswap.hpp +148 -0
- package/vendor/include/tlx/math/bswap_be.hpp +79 -0
- package/vendor/include/tlx/math/bswap_le.hpp +79 -0
- package/vendor/include/tlx/math/clz.hpp +174 -0
- package/vendor/include/tlx/math/ctz.hpp +174 -0
- package/vendor/include/tlx/math/div_ceil.hpp +36 -0
- package/vendor/include/tlx/math/ffs.hpp +123 -0
- package/vendor/include/tlx/math/integer_log2.hpp +189 -0
- package/vendor/include/tlx/math/is_power_of_two.hpp +74 -0
- package/vendor/include/tlx/math/polynomial_regression.hpp +243 -0
- package/vendor/include/tlx/math/popcount.hpp +173 -0
- package/vendor/include/tlx/math/power_to_the.hpp +44 -0
- package/vendor/include/tlx/math/rol.hpp +112 -0
- package/vendor/include/tlx/math/ror.hpp +112 -0
- package/vendor/include/tlx/math/round_to_power_of_two.hpp +121 -0
- package/vendor/include/tlx/math/round_up.hpp +36 -0
- package/vendor/include/tlx/math/sgn.hpp +38 -0
- package/vendor/include/tlx/math.hpp +46 -0
- package/vendor/include/tlx/meta/apply_tuple.hpp +55 -0
- package/vendor/include/tlx/meta/call_for_range.hpp +78 -0
- package/vendor/include/tlx/meta/call_foreach.hpp +60 -0
- package/vendor/include/tlx/meta/call_foreach_tuple.hpp +60 -0
- package/vendor/include/tlx/meta/call_foreach_tuple_with_index.hpp +61 -0
- package/vendor/include/tlx/meta/call_foreach_with_index.hpp +64 -0
- package/vendor/include/tlx/meta/enable_if.hpp +37 -0
- package/vendor/include/tlx/meta/fold_left.hpp +63 -0
- package/vendor/include/tlx/meta/fold_left_tuple.hpp +60 -0
- package/vendor/include/tlx/meta/fold_right.hpp +63 -0
- package/vendor/include/tlx/meta/fold_right_tuple.hpp +60 -0
- package/vendor/include/tlx/meta/function_chain.hpp +197 -0
- package/vendor/include/tlx/meta/function_stack.hpp +189 -0
- package/vendor/include/tlx/meta/has_member.hpp +80 -0
- package/vendor/include/tlx/meta/has_method.hpp +117 -0
- package/vendor/include/tlx/meta/index_sequence.hpp +66 -0
- package/vendor/include/tlx/meta/is_std_array.hpp +40 -0
- package/vendor/include/tlx/meta/is_std_pair.hpp +39 -0
- package/vendor/include/tlx/meta/is_std_tuple.hpp +39 -0
- package/vendor/include/tlx/meta/is_std_vector.hpp +39 -0
- package/vendor/include/tlx/meta/log2.hpp +101 -0
- package/vendor/include/tlx/meta/no_operation.hpp +55 -0
- package/vendor/include/tlx/meta/static_index.hpp +42 -0
- package/vendor/include/tlx/meta/vexpand.hpp +34 -0
- package/vendor/include/tlx/meta/vmap_for_range.hpp +84 -0
- package/vendor/include/tlx/meta/vmap_foreach.hpp +63 -0
- package/vendor/include/tlx/meta/vmap_foreach_tuple.hpp +59 -0
- package/vendor/include/tlx/meta/vmap_foreach_tuple_with_index.hpp +62 -0
- package/vendor/include/tlx/meta/vmap_foreach_with_index.hpp +70 -0
- package/vendor/include/tlx/meta.hpp +55 -0
- package/vendor/include/tlx/multi_timer.hpp +148 -0
- package/vendor/include/tlx/port/setenv.hpp +31 -0
- package/vendor/include/tlx/port.hpp +27 -0
- package/vendor/include/tlx/semaphore.hpp +119 -0
- package/vendor/include/tlx/simple_vector.hpp +20 -0
- package/vendor/include/tlx/siphash.hpp +282 -0
- package/vendor/include/tlx/sort/networks/best.hpp +611 -0
- package/vendor/include/tlx/sort/networks/bose_nelson.hpp +412 -0
- package/vendor/include/tlx/sort/networks/bose_nelson_parameter.hpp +507 -0
- package/vendor/include/tlx/sort/networks/cswap.hpp +60 -0
- package/vendor/include/tlx/sort/parallel_mergesort.hpp +398 -0
- package/vendor/include/tlx/sort/strings/insertion_sort.hpp +232 -0
- package/vendor/include/tlx/sort/strings/multikey_quicksort.hpp +185 -0
- package/vendor/include/tlx/sort/strings/parallel_sample_sort.hpp +1647 -0
- package/vendor/include/tlx/sort/strings/radix_sort.hpp +934 -0
- package/vendor/include/tlx/sort/strings/sample_sort_tools.hpp +756 -0
- package/vendor/include/tlx/sort/strings/string_ptr.hpp +426 -0
- package/vendor/include/tlx/sort/strings/string_set.hpp +800 -0
- package/vendor/include/tlx/sort/strings.hpp +329 -0
- package/vendor/include/tlx/sort/strings_parallel.hpp +325 -0
- package/vendor/include/tlx/sort.hpp +29 -0
- package/vendor/include/tlx/stack_allocator.hpp +226 -0
- package/vendor/include/tlx/string/appendline.hpp +35 -0
- package/vendor/include/tlx/string/base64.hpp +87 -0
- package/vendor/include/tlx/string/bitdump.hpp +139 -0
- package/vendor/include/tlx/string/compare_icase.hpp +42 -0
- package/vendor/include/tlx/string/contains.hpp +36 -0
- package/vendor/include/tlx/string/contains_word.hpp +42 -0
- package/vendor/include/tlx/string/ends_with.hpp +79 -0
- package/vendor/include/tlx/string/equal_icase.hpp +42 -0
- package/vendor/include/tlx/string/erase_all.hpp +70 -0
- package/vendor/include/tlx/string/escape_html.hpp +34 -0
- package/vendor/include/tlx/string/escape_uri.hpp +34 -0
- package/vendor/include/tlx/string/expand_environment_variables.hpp +49 -0
- package/vendor/include/tlx/string/extract_between.hpp +40 -0
- package/vendor/include/tlx/string/format_iec_units.hpp +32 -0
- package/vendor/include/tlx/string/format_si_iec_units.hpp +19 -0
- package/vendor/include/tlx/string/format_si_units.hpp +32 -0
- package/vendor/include/tlx/string/hash_djb2.hpp +87 -0
- package/vendor/include/tlx/string/hash_sdbm.hpp +86 -0
- package/vendor/include/tlx/string/hexdump.hpp +154 -0
- package/vendor/include/tlx/string/index_of.hpp +56 -0
- package/vendor/include/tlx/string/join.hpp +65 -0
- package/vendor/include/tlx/string/join_generic.hpp +89 -0
- package/vendor/include/tlx/string/join_quoted.hpp +46 -0
- package/vendor/include/tlx/string/less_icase.hpp +64 -0
- package/vendor/include/tlx/string/levenshtein.hpp +193 -0
- package/vendor/include/tlx/string/pad.hpp +39 -0
- package/vendor/include/tlx/string/parse_si_iec_units.hpp +46 -0
- package/vendor/include/tlx/string/parse_uri.hpp +66 -0
- package/vendor/include/tlx/string/parse_uri_form_data.hpp +136 -0
- package/vendor/include/tlx/string/replace.hpp +141 -0
- package/vendor/include/tlx/string/split.hpp +170 -0
- package/vendor/include/tlx/string/split_quoted.hpp +49 -0
- package/vendor/include/tlx/string/split_view.hpp +218 -0
- package/vendor/include/tlx/string/split_words.hpp +53 -0
- package/vendor/include/tlx/string/ssprintf.hpp +45 -0
- package/vendor/include/tlx/string/ssprintf_generic.hpp +95 -0
- package/vendor/include/tlx/string/starts_with.hpp +44 -0
- package/vendor/include/tlx/string/to_lower.hpp +47 -0
- package/vendor/include/tlx/string/to_upper.hpp +47 -0
- package/vendor/include/tlx/string/trim.hpp +298 -0
- package/vendor/include/tlx/string/union_words.hpp +33 -0
- package/vendor/include/tlx/string/word_wrap.hpp +35 -0
- package/vendor/include/tlx/string.hpp +68 -0
- package/vendor/include/tlx/thread_barrier_mutex.hpp +109 -0
- package/vendor/include/tlx/thread_barrier_spin.hpp +127 -0
- package/vendor/include/tlx/thread_pool.hpp +151 -0
- package/vendor/include/tlx/timestamp.hpp +23 -0
- package/vendor/include/tlx/unused.hpp +28 -0
- package/vendor/include/tlx/vector_free.hpp +30 -0
- package/vendor/include/tlx/version.hpp +49 -0
- package/vendor/include/ttmath/ttmath.h +2881 -0
- package/vendor/include/ttmath/ttmathbig.h +6111 -0
- package/vendor/include/ttmath/ttmathdec.h +419 -0
- package/vendor/include/ttmath/ttmathint.h +1923 -0
- package/vendor/include/ttmath/ttmathmisc.h +250 -0
- package/vendor/include/ttmath/ttmathobjects.h +812 -0
- package/vendor/include/ttmath/ttmathparser.h +2791 -0
- package/vendor/include/ttmath/ttmaththreads.h +252 -0
- package/vendor/include/ttmath/ttmathtypes.h +707 -0
- package/vendor/include/ttmath/ttmathuint.h +4190 -0
- package/vendor/include/ttmath/ttmathuint_noasm.h +1038 -0
- package/vendor/include/ttmath/ttmathuint_x86.h +1620 -0
- package/vendor/include/ttmath/ttmathuint_x86_64.h +1177 -0
- package/vendor/lib/cmake/tlx/tlx-config.cmake +51 -0
- package/vendor/lib/cmake/tlx/tlx-targets-release.cmake +19 -0
- package/vendor/lib/cmake/tlx/tlx-targets.cmake +106 -0
- package/vendor/lib/cmake/tlx/tlx-version.cmake +11 -0
- package/vendor/lib/libnetworkit.dylib +0 -0
- package/vendor/lib/libtlx.a +0 -0
- package/vendor/lib/pkgconfig/networkit.pc +11 -0
- package/vendor/lib/pkgconfig/tlx.pc +11 -0
|
@@ -0,0 +1,2083 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Graph.hpp
|
|
3
|
+
*
|
|
4
|
+
* Created on: 01.06.2014
|
|
5
|
+
* Author: Christian Staudt
|
|
6
|
+
* Klara Reichard <klara.reichard@gmail.com>
|
|
7
|
+
* Marvin Ritter <marvin.ritter@gmail.com>
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
#ifndef NETWORKIT_GRAPH_GRAPH_HPP_
|
|
11
|
+
#define NETWORKIT_GRAPH_GRAPH_HPP_
|
|
12
|
+
|
|
13
|
+
#include <algorithm>
|
|
14
|
+
#include <fstream>
|
|
15
|
+
#include <functional>
|
|
16
|
+
#include <memory>
|
|
17
|
+
#include <numeric>
|
|
18
|
+
#include <omp.h>
|
|
19
|
+
#include <queue>
|
|
20
|
+
#include <ranges>
|
|
21
|
+
#include <sstream>
|
|
22
|
+
#include <stack>
|
|
23
|
+
#include <stdexcept>
|
|
24
|
+
#include <typeindex>
|
|
25
|
+
#include <unordered_map>
|
|
26
|
+
#include <unordered_set>
|
|
27
|
+
#include <utility>
|
|
28
|
+
#include <vector>
|
|
29
|
+
|
|
30
|
+
#include <networkit/Globals.hpp>
|
|
31
|
+
#include <networkit/auxiliary/ArrayTools.hpp>
|
|
32
|
+
#include <networkit/auxiliary/FunctionTraits.hpp>
|
|
33
|
+
#include <networkit/auxiliary/Log.hpp>
|
|
34
|
+
#include <networkit/auxiliary/Random.hpp>
|
|
35
|
+
#include <networkit/graph/Attributes.hpp>
|
|
36
|
+
#include <networkit/graph/EdgeIterators.hpp>
|
|
37
|
+
#include <networkit/graph/NeighborIterators.hpp>
|
|
38
|
+
#include <networkit/graph/NodeIterators.hpp>
|
|
39
|
+
|
|
40
|
+
#include <tlx/define/deprecated.hpp>
|
|
41
|
+
|
|
42
|
+
#include <arrow/api.h>
|
|
43
|
+
#include <arrow/compute/api.h>
|
|
44
|
+
|
|
45
|
+
namespace NetworKit {
|
|
46
|
+
|
|
47
|
+
struct Edge {
|
|
48
|
+
node u, v;
|
|
49
|
+
|
|
50
|
+
Edge() : u(none), v(none) {}
|
|
51
|
+
|
|
52
|
+
Edge(node _u, node _v, bool sorted = false) {
|
|
53
|
+
u = sorted ? std::min(_u, _v) : _u;
|
|
54
|
+
v = sorted ? std::max(_u, _v) : _v;
|
|
55
|
+
}
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* A weighted edge used for the graph constructor with
|
|
60
|
+
* initializer list syntax.
|
|
61
|
+
*/
|
|
62
|
+
struct WeightedEdge : Edge {
|
|
63
|
+
edgeweight weight;
|
|
64
|
+
|
|
65
|
+
// Needed by cython
|
|
66
|
+
WeightedEdge() : Edge(), weight(std::numeric_limits<edgeweight>::max()) {}
|
|
67
|
+
|
|
68
|
+
WeightedEdge(node u, node v, edgeweight w) : Edge(u, v), weight(w) {}
|
|
69
|
+
};
|
|
70
|
+
|
|
71
|
+
struct WeightedEdgeWithId : WeightedEdge {
|
|
72
|
+
edgeid eid;
|
|
73
|
+
|
|
74
|
+
WeightedEdgeWithId(node u, node v, edgeweight w, edgeid eid)
|
|
75
|
+
: WeightedEdge(u, v, w), eid(eid) {}
|
|
76
|
+
};
|
|
77
|
+
|
|
78
|
+
inline bool operator==(const Edge &e1, const Edge &e2) {
|
|
79
|
+
return e1.u == e2.u && e1.v == e2.v;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
inline bool operator<(const WeightedEdge &e1, const WeightedEdge &e2) {
|
|
83
|
+
return e1.weight < e2.weight;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
struct Unsafe {};
|
|
87
|
+
static constexpr Unsafe unsafe{};
|
|
88
|
+
} // namespace NetworKit
|
|
89
|
+
|
|
90
|
+
namespace std {
|
|
91
|
+
template <>
|
|
92
|
+
struct hash<NetworKit::Edge> {
|
|
93
|
+
size_t operator()(const NetworKit::Edge &e) const { return hash_node(e.u) ^ hash_node(e.v); }
|
|
94
|
+
|
|
95
|
+
hash<NetworKit::node> hash_node;
|
|
96
|
+
};
|
|
97
|
+
} // namespace std
|
|
98
|
+
|
|
99
|
+
namespace NetworKit {
|
|
100
|
+
|
|
101
|
+
// forward declaration to randomization/CurveballImpl.hpp
|
|
102
|
+
namespace CurveballDetails {
|
|
103
|
+
class CurveballMaterialization;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
* @ingroup graph
|
|
108
|
+
* A graph (with optional weights) and parallel iterator methods.
|
|
109
|
+
*/
|
|
110
|
+
class Graph {
|
|
111
|
+
|
|
112
|
+
protected:
|
|
113
|
+
// graph attributes
|
|
114
|
+
//!< current number of nodes
|
|
115
|
+
count n;
|
|
116
|
+
//!< current number of edges
|
|
117
|
+
count m;
|
|
118
|
+
|
|
119
|
+
//!< current number of self loops, edges which have the same origin and
|
|
120
|
+
//!< target
|
|
121
|
+
count storedNumberOfSelfLoops;
|
|
122
|
+
|
|
123
|
+
//!< current upper bound of node ids, z will be the id of the next node
|
|
124
|
+
node z;
|
|
125
|
+
//!< current upper bound of edge ids, will be the id of the next edge
|
|
126
|
+
edgeid omega;
|
|
127
|
+
//!< current time step
|
|
128
|
+
count t;
|
|
129
|
+
|
|
130
|
+
//!< true if the graph is weighted, false otherwise
|
|
131
|
+
bool weighted;
|
|
132
|
+
//!< true if the graph is directed, false otherwise
|
|
133
|
+
bool directed;
|
|
134
|
+
//!< true if edge ids have been assigned
|
|
135
|
+
bool edgesIndexed;
|
|
136
|
+
|
|
137
|
+
//!< true if edge removals should maintain compact edge ids
|
|
138
|
+
bool maintainCompactEdges = false;
|
|
139
|
+
//!< true if edge removals should maintain sorted edge ids
|
|
140
|
+
bool maintainSortedEdges = false;
|
|
141
|
+
|
|
142
|
+
//!< saves the ID of the most recently removed edge (if exists)
|
|
143
|
+
edgeid deletedID;
|
|
144
|
+
|
|
145
|
+
// per node data
|
|
146
|
+
//!< exists[v] is true if node v has not been removed from the graph
|
|
147
|
+
std::vector<bool> exists;
|
|
148
|
+
|
|
149
|
+
// CSR arrays for memory-efficient graph storage (zero-copy from Arrow)
|
|
150
|
+
//!< Arrow array for CSR indices (neighbor node IDs) for outgoing edges
|
|
151
|
+
std::shared_ptr<arrow::UInt64Array> outEdgesCSRIndices;
|
|
152
|
+
//!< Arrow array for CSR indptr (offsets into indices array) for outgoing edges
|
|
153
|
+
std::shared_ptr<arrow::UInt64Array> outEdgesCSRIndptr;
|
|
154
|
+
//!< Arrow array for CSR indices (neighbor node IDs) for incoming edges - only for directed
|
|
155
|
+
//!< graphs
|
|
156
|
+
std::shared_ptr<arrow::UInt64Array> inEdgesCSRIndices;
|
|
157
|
+
//!< Arrow array for CSR indptr (offsets into indices array) for incoming edges - only for
|
|
158
|
+
//!< directed graphs
|
|
159
|
+
std::shared_ptr<arrow::UInt64Array> inEdgesCSRIndptr;
|
|
160
|
+
//!< Arrow array for CSR edge weights for outgoing edges
|
|
161
|
+
std::shared_ptr<arrow::DoubleArray> outEdgesCSRWeights;
|
|
162
|
+
//!< Arrow array for CSR edge weights for incoming edges - only for directed graphs
|
|
163
|
+
std::shared_ptr<arrow::DoubleArray> inEdgesCSRWeights;
|
|
164
|
+
//!< flag to indicate if CSR arrays are being used instead of vectors
|
|
165
|
+
bool usingCSR;
|
|
166
|
+
|
|
167
|
+
private:
|
|
168
|
+
AttributeMap<PerNode, Graph> nodeAttributeMap;
|
|
169
|
+
AttributeMap<PerEdge, Graph> edgeAttributeMap;
|
|
170
|
+
|
|
171
|
+
public:
|
|
172
|
+
auto &nodeAttributes() noexcept { return nodeAttributeMap; }
|
|
173
|
+
const auto &nodeAttributes() const noexcept { return nodeAttributeMap; }
|
|
174
|
+
auto &edgeAttributes() noexcept { return edgeAttributeMap; }
|
|
175
|
+
const auto &edgeAttributes() const noexcept { return edgeAttributeMap; }
|
|
176
|
+
|
|
177
|
+
// wrap up some typed attributes for the cython interface:
|
|
178
|
+
//
|
|
179
|
+
|
|
180
|
+
auto attachNodeIntAttribute(const std::string &name) {
|
|
181
|
+
nodeAttributes().theGraph = this;
|
|
182
|
+
return nodeAttributes().attach<int>(name);
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
auto attachEdgeIntAttribute(const std::string &name) {
|
|
186
|
+
edgeAttributes().theGraph = this;
|
|
187
|
+
return edgeAttributes().attach<int>(name);
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
auto attachNodeDoubleAttribute(const std::string &name) {
|
|
191
|
+
nodeAttributes().theGraph = this;
|
|
192
|
+
return nodeAttributes().attach<double>(name);
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
auto attachEdgeDoubleAttribute(const std::string &name) {
|
|
196
|
+
edgeAttributes().theGraph = this;
|
|
197
|
+
return edgeAttributes().attach<double>(name);
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
auto attachNodeStringAttribute(const std::string &name) {
|
|
201
|
+
nodeAttributes().theGraph = this;
|
|
202
|
+
return nodeAttributes().attach<std::string>(name);
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
auto attachEdgeStringAttribute(const std::string &name) {
|
|
206
|
+
edgeAttributes().theGraph = this;
|
|
207
|
+
return edgeAttributes().attach<std::string>(name);
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
auto getNodeIntAttribute(const std::string &name) {
|
|
211
|
+
nodeAttributes().theGraph = this;
|
|
212
|
+
return nodeAttributes().get<int>(name);
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
auto getEdgeIntAttribute(const std::string &name) {
|
|
216
|
+
edgeAttributes().theGraph = this;
|
|
217
|
+
return edgeAttributes().get<int>(name);
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
auto getNodeDoubleAttribute(const std::string &name) {
|
|
221
|
+
nodeAttributes().theGraph = this;
|
|
222
|
+
return nodeAttributes().get<double>(name);
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
auto getEdgeDoubleAttribute(const std::string &name) {
|
|
226
|
+
edgeAttributes().theGraph = this;
|
|
227
|
+
return edgeAttributes().get<double>(name);
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
auto getNodeStringAttribute(const std::string &name) {
|
|
231
|
+
nodeAttributes().theGraph = this;
|
|
232
|
+
return nodeAttributes().get<std::string>(name);
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
auto getEdgeStringAttribute(const std::string &name) {
|
|
236
|
+
edgeAttributes().theGraph = this;
|
|
237
|
+
return edgeAttributes().get<std::string>(name);
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
void detachNodeAttribute(std::string const &name) {
|
|
241
|
+
nodeAttributes().theGraph = this;
|
|
242
|
+
nodeAttributes().detach(name);
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
void detachEdgeAttribute(std::string const &name) {
|
|
246
|
+
edgeAttributes().theGraph = this;
|
|
247
|
+
edgeAttributes().detach(name);
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
using NodeIntAttribute = Attribute<PerNode, Graph, int, false>;
|
|
251
|
+
using NodeDoubleAttribute = Attribute<PerNode, Graph, double, false>;
|
|
252
|
+
using NodeStringAttribute = Attribute<PerNode, Graph, std::string, false>;
|
|
253
|
+
|
|
254
|
+
using EdgeIntAttribute = Attribute<PerEdge, Graph, int, false>;
|
|
255
|
+
using EdgeDoubleAttribute = Attribute<PerEdge, Graph, double, false>;
|
|
256
|
+
using EdgeStringAttribute = Attribute<PerEdge, Graph, std::string, false>;
|
|
257
|
+
|
|
258
|
+
/**
|
|
259
|
+
* Copy all attributes from another graph. This is useful when creating
|
|
260
|
+
* a new graph with different properties (weighted/unweighted) but wanting
|
|
261
|
+
* to preserve attributes.
|
|
262
|
+
* @param other The source graph to copy attributes from.
|
|
263
|
+
*/
|
|
264
|
+
void copyAttributesFrom(const Graph &other) {
|
|
265
|
+
nodeAttributeMap = AttributeMap<PerNode, Graph>(other.nodeAttributes(), this);
|
|
266
|
+
// Only copy edge attributes if both graphs have indexed edges
|
|
267
|
+
if (other.hasEdgeIds() && this->hasEdgeIds()) {
|
|
268
|
+
edgeAttributeMap = AttributeMap<PerEdge, Graph>(other.edgeAttributes(), this);
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
protected:
|
|
273
|
+
/**
|
|
274
|
+
* Returns the index of node u in the array of incoming edges of node v.
|
|
275
|
+
* (for directed graphs inEdges is searched, while for indirected outEdges
|
|
276
|
+
* is searched, which gives the same result as indexInOutEdgeArray).
|
|
277
|
+
*/
|
|
278
|
+
virtual index indexInInEdgeArray(node v, node u) const = 0;
|
|
279
|
+
|
|
280
|
+
/**
|
|
281
|
+
* Returns the index of node v in the array of outgoing edges of node u.
|
|
282
|
+
*/
|
|
283
|
+
virtual index indexInOutEdgeArray(node u, node v) const = 0;
|
|
284
|
+
|
|
285
|
+
// CSR helper methods
|
|
286
|
+
/**
|
|
287
|
+
* Get neighbors of node u using CSR format for outgoing edges
|
|
288
|
+
*/
|
|
289
|
+
std::pair<const node *, count> getCSROutNeighbors(node u) const;
|
|
290
|
+
|
|
291
|
+
/**
|
|
292
|
+
* Get neighbors of node u using CSR format for incoming edges
|
|
293
|
+
*/
|
|
294
|
+
std::pair<const node *, count> getCSRInNeighbors(node u) const;
|
|
295
|
+
|
|
296
|
+
/**
|
|
297
|
+
* Check if edge (u,v) exists using CSR format
|
|
298
|
+
*/
|
|
299
|
+
bool hasEdgeCSR(node u, node v) const;
|
|
300
|
+
|
|
301
|
+
/**
|
|
302
|
+
* Get degree of node using CSR format
|
|
303
|
+
*/
|
|
304
|
+
count degreeCSR(node u, bool incoming = false) const;
|
|
305
|
+
|
|
306
|
+
/**
|
|
307
|
+
* Virtual method to get neighbors as a vector.
|
|
308
|
+
* This enables polymorphic iteration over neighbors regardless of storage format.
|
|
309
|
+
*
|
|
310
|
+
* @param u Node.
|
|
311
|
+
* @param inEdges If true, get incoming neighbors; otherwise outgoing.
|
|
312
|
+
* @return Vector of neighbor nodes (filtered to only existing nodes).
|
|
313
|
+
*/
|
|
314
|
+
virtual std::vector<node> getNeighborsVector(node u, bool inEdges = false) const = 0;
|
|
315
|
+
|
|
316
|
+
/**
|
|
317
|
+
* Virtual method to get neighbors with weights as vectors.
|
|
318
|
+
* This enables polymorphic iteration over weighted neighbors regardless of storage format.
|
|
319
|
+
*
|
|
320
|
+
* @param u Node.
|
|
321
|
+
* @param inEdges If true, get incoming neighbors; otherwise outgoing.
|
|
322
|
+
* @return Pair of vectors: neighbors and corresponding weights (filtered to only existing
|
|
323
|
+
* nodes).
|
|
324
|
+
*/
|
|
325
|
+
virtual std::pair<std::vector<node>, std::vector<edgeweight>>
|
|
326
|
+
getNeighborsWithWeightsVector(node u, bool inEdges = false) const = 0;
|
|
327
|
+
|
|
328
|
+
private:
|
|
329
|
+
/**
|
|
330
|
+
* Computes the weighted in/out degree of node @a u.
|
|
331
|
+
*
|
|
332
|
+
* @param u Node.
|
|
333
|
+
* @param inDegree whether to compute the in degree or the out degree.
|
|
334
|
+
* @param countSelfLoopsTwice If set to true, self-loops will be counted twice.
|
|
335
|
+
*
|
|
336
|
+
* @return Weighted in/out degree of node @a u.
|
|
337
|
+
*/
|
|
338
|
+
edgeweight computeWeightedDegree(node u, bool inDegree = false,
|
|
339
|
+
bool countSelfLoopsTwice = false) const;
|
|
340
|
+
|
|
341
|
+
/**
|
|
342
|
+
* Returns the edge weight of the outgoing edge of index i in the outgoing
|
|
343
|
+
* edges of node u
|
|
344
|
+
* @param u The node
|
|
345
|
+
* @param i The index
|
|
346
|
+
* @return The weight of the outgoing edge or defaultEdgeWeight if the graph
|
|
347
|
+
* is unweighted
|
|
348
|
+
*/
|
|
349
|
+
template <bool hasWeights>
|
|
350
|
+
inline edgeweight getOutEdgeWeight(node u, index i) const;
|
|
351
|
+
|
|
352
|
+
/**
|
|
353
|
+
* Returns the edge weight of the incoming edge of index i in the incoming
|
|
354
|
+
* edges of node u
|
|
355
|
+
*
|
|
356
|
+
* @param u The node
|
|
357
|
+
* @param i The index in the incoming edge array
|
|
358
|
+
* @return The weight of the incoming edge
|
|
359
|
+
*/
|
|
360
|
+
template <bool hasWeights>
|
|
361
|
+
inline edgeweight getInEdgeWeight(node u, index i) const;
|
|
362
|
+
|
|
363
|
+
/**
|
|
364
|
+
* Returns the edge id of the edge of index i in the outgoing edges of node
|
|
365
|
+
* u
|
|
366
|
+
*
|
|
367
|
+
* @param u The node
|
|
368
|
+
* @param i The index in the outgoing edges
|
|
369
|
+
* @return The edge id
|
|
370
|
+
*/
|
|
371
|
+
template <bool graphHasEdgeIds>
|
|
372
|
+
inline edgeid getOutEdgeId(node u, index i) const;
|
|
373
|
+
|
|
374
|
+
/**
|
|
375
|
+
* Returns the edge id of the edge of index i in the incoming edges of node
|
|
376
|
+
* u
|
|
377
|
+
*
|
|
378
|
+
* @param u The node
|
|
379
|
+
* @param i The index in the incoming edges of u
|
|
380
|
+
* @return The edge id
|
|
381
|
+
*/
|
|
382
|
+
template <bool graphHasEdgeIds>
|
|
383
|
+
inline edgeid getInEdgeId(node u, index i) const;
|
|
384
|
+
|
|
385
|
+
/**
|
|
386
|
+
* @brief Returns if the edge (u, v) shall be used in the iteration of all
|
|
387
|
+
* edgesIndexed
|
|
388
|
+
*
|
|
389
|
+
* @param u The source node of the edge
|
|
390
|
+
* @param v The target node of the edge
|
|
391
|
+
* @return If the node shall be used, i.e. if v is not none and in the
|
|
392
|
+
* undirected case if u >= v
|
|
393
|
+
*/
|
|
394
|
+
template <bool graphIsDirected>
|
|
395
|
+
inline bool useEdgeInIteration(node u, node v) const;
|
|
396
|
+
|
|
397
|
+
/**
|
|
398
|
+
* @brief Implementation of the for loop for outgoing edges of u
|
|
399
|
+
*
|
|
400
|
+
* Note: If all (valid) outgoing edges shall be considered, graphIsDirected
|
|
401
|
+
* needs to be set to true
|
|
402
|
+
*
|
|
403
|
+
* @param u The node
|
|
404
|
+
* @param handle The handle that shall be executed for each edge
|
|
405
|
+
* @return void
|
|
406
|
+
*/
|
|
407
|
+
// applyUndirectedFilter=true deduplicates edges (u>=v) for full-graph traversal.
|
|
408
|
+
// forEdgesOf / forNeighborsOf use the default false so all neighbors are returned.
|
|
409
|
+
template <bool graphIsDirected, bool hasWeights, bool graphHasEdgeIds, typename L,
|
|
410
|
+
bool applyUndirectedFilter = false>
|
|
411
|
+
inline void forOutEdgesOfImpl(node u, L handle) const;
|
|
412
|
+
|
|
413
|
+
/**
|
|
414
|
+
* @brief Implementation of the for loop for incoming edges of u
|
|
415
|
+
*
|
|
416
|
+
* For undirected graphs, this is the same as forOutEdgesOfImpl but u and v
|
|
417
|
+
* are changed in the handle
|
|
418
|
+
*
|
|
419
|
+
* @param u The node
|
|
420
|
+
* @param handle The handle that shall be executed for each edge
|
|
421
|
+
* @return void
|
|
422
|
+
*/
|
|
423
|
+
template <bool graphIsDirected, bool hasWeights, bool graphHasEdgeIds, typename L>
|
|
424
|
+
inline void forInEdgesOfImpl(node u, L handle) const;
|
|
425
|
+
|
|
426
|
+
/**
|
|
427
|
+
* @brief Implementation of the for loop for all edges, @see forEdges
|
|
428
|
+
*
|
|
429
|
+
* @param handle The handle that shall be executed for all edges
|
|
430
|
+
* @return void
|
|
431
|
+
*/
|
|
432
|
+
template <bool graphIsDirected, bool hasWeights, bool graphHasEdgeIds, typename L>
|
|
433
|
+
inline void forEdgeImpl(L handle) const;
|
|
434
|
+
|
|
435
|
+
/**
|
|
436
|
+
* @brief Parallel implementation of the for loop for all edges, @see
|
|
437
|
+
* parallelForEdges
|
|
438
|
+
*
|
|
439
|
+
* @param handle The handle that shall be executed for all edges
|
|
440
|
+
* @return void
|
|
441
|
+
*/
|
|
442
|
+
template <bool graphIsDirected, bool hasWeights, bool graphHasEdgeIds, typename L>
|
|
443
|
+
inline void parallelForEdgesImpl(L handle) const;
|
|
444
|
+
|
|
445
|
+
/**
|
|
446
|
+
* @brief Summation variant of the parallel for loop for all edges, @see
|
|
447
|
+
* parallelSumForEdges
|
|
448
|
+
*
|
|
449
|
+
* @param handle The handle that shall be executed for all edges
|
|
450
|
+
* @return void
|
|
451
|
+
*/
|
|
452
|
+
template <bool graphIsDirected, bool hasWeights, bool graphHasEdgeIds, typename L>
|
|
453
|
+
inline double parallelSumForEdgesImpl(L handle) const;
|
|
454
|
+
|
|
455
|
+
/**
|
|
456
|
+
* @brief Virtual method for edge iteration - overridden by GraphW for vector-based iteration
|
|
457
|
+
*/
|
|
458
|
+
virtual void
|
|
459
|
+
forEdgesVirtualImpl(bool directed, bool weighted, bool hasEdgeIds,
|
|
460
|
+
std::function<void(node, node, edgeweight, edgeid)> handle) const;
|
|
461
|
+
|
|
462
|
+
/**
|
|
463
|
+
* @brief Virtual method for forEdgesOf - overridden by GraphW for vector-based iteration
|
|
464
|
+
*/
|
|
465
|
+
virtual void
|
|
466
|
+
forEdgesOfVirtualImpl(node u, bool directed, bool weighted, bool hasEdgeIds,
|
|
467
|
+
std::function<void(node, node, edgeweight, edgeid)> handle) const;
|
|
468
|
+
|
|
469
|
+
/**
|
|
470
|
+
* @brief Virtual method for forInEdgesOf - overridden by GraphW for vector-based iteration
|
|
471
|
+
*/
|
|
472
|
+
virtual void
|
|
473
|
+
forInEdgesVirtualImpl(node u, bool directed, bool weighted, bool hasEdgeIds,
|
|
474
|
+
std::function<void(node, node, edgeweight, edgeid)> handle) const;
|
|
475
|
+
|
|
476
|
+
/**
|
|
477
|
+
* @brief Virtual method for parallelSumForEdges - overridden by GraphW for vector-based
|
|
478
|
+
* iteration
|
|
479
|
+
*/
|
|
480
|
+
virtual double parallelSumForEdgesVirtualImpl(
|
|
481
|
+
bool directed, bool weighted, bool hasEdgeIds,
|
|
482
|
+
std::function<double(node, node, edgeweight, edgeid)> handle) const;
|
|
483
|
+
|
|
484
|
+
/*
|
|
485
|
+
* In the following definition, Aux::FunctionTraits is used in order to only
|
|
486
|
+
* execute lambda functions with the appropriate parameters. The
|
|
487
|
+
* decltype-return type is used for determining the return type of the
|
|
488
|
+
* lambda (needed for summation) but also determines if the lambda accepts
|
|
489
|
+
* the correct number of parameters. Otherwise the return type declaration
|
|
490
|
+
* fails and the function is excluded from overload resolution. Then there
|
|
491
|
+
* are multiple possible lambdas with three (third parameter id or weight)
|
|
492
|
+
* and two (second parameter can be second node id or edge weight for
|
|
493
|
+
* neighbor iterators). This is checked using Aux::FunctionTraits and
|
|
494
|
+
* std::enable_if. std::enable_if only defines the type member when the
|
|
495
|
+
* given bool is true, this bool comes from std::is_same which compares two
|
|
496
|
+
* types. The function traits give either the parameter type or if it is out
|
|
497
|
+
* of bounds they define type as void.
|
|
498
|
+
*/
|
|
499
|
+
|
|
500
|
+
/**
|
|
501
|
+
* Triggers a static assert error when no other method is chosen. Because of
|
|
502
|
+
* the use of "..." as arguments, the priority of this method is lower than
|
|
503
|
+
* the priority of the other methods. This method avoids ugly and unreadable
|
|
504
|
+
* template substitution error messages from the other declarations.
|
|
505
|
+
*/
|
|
506
|
+
template <class F, void * = (void *)0>
|
|
507
|
+
typename Aux::FunctionTraits<F>::result_type edgeLambda(F &, ...) const {
|
|
508
|
+
// the strange condition is used in order to delay the evaluation of the
|
|
509
|
+
// static assert to the moment when this function is actually used
|
|
510
|
+
static_assert(!std::is_same<F, F>::value,
|
|
511
|
+
"Your lambda does not support the required parameters or the "
|
|
512
|
+
"parameters have the wrong type.");
|
|
513
|
+
return std::declval<typename Aux::FunctionTraits<F>::result_type>(); // use the correct
|
|
514
|
+
// return type (this
|
|
515
|
+
// won't compile)
|
|
516
|
+
}
|
|
517
|
+
|
|
518
|
+
/**
|
|
519
|
+
* Calls the given function f if its fourth argument is of the type edgeid
|
|
520
|
+
* and third of type edgeweight Note that the decltype check is not enough
|
|
521
|
+
* as edgeweight can be casted to node and we want to assure that .
|
|
522
|
+
*/
|
|
523
|
+
template <class F,
|
|
524
|
+
typename std::enable_if<
|
|
525
|
+
(Aux::FunctionTraits<F>::arity >= 3)
|
|
526
|
+
&& std::is_same<edgeweight,
|
|
527
|
+
typename Aux::FunctionTraits<F>::template arg<2>::type>::value
|
|
528
|
+
&& std::is_same<edgeid, typename Aux::FunctionTraits<F>::template arg<3>::type>::
|
|
529
|
+
value>::type * = (void *)0>
|
|
530
|
+
auto edgeLambda(F &f, node u, node v, edgeweight ew, edgeid id) const
|
|
531
|
+
-> decltype(f(u, v, ew, id)) {
|
|
532
|
+
return f(u, v, ew, id);
|
|
533
|
+
}
|
|
534
|
+
|
|
535
|
+
/**
|
|
536
|
+
* Calls the given function f if its third argument is of the type edgeid,
|
|
537
|
+
* discards the edge weight Note that the decltype check is not enough as
|
|
538
|
+
* edgeweight can be casted to node.
|
|
539
|
+
*/
|
|
540
|
+
template <
|
|
541
|
+
class F,
|
|
542
|
+
typename std::enable_if<
|
|
543
|
+
(Aux::FunctionTraits<F>::arity >= 2)
|
|
544
|
+
&& std::is_same<edgeid, typename Aux::FunctionTraits<F>::template arg<2>::type>::value
|
|
545
|
+
&& std::is_same<node, typename Aux::FunctionTraits<F>::template arg<1>::type>::
|
|
546
|
+
value /* prevent f(v, weight, eid)
|
|
547
|
+
*/
|
|
548
|
+
>::type * = (void *)0>
|
|
549
|
+
auto edgeLambda(F &f, node u, node v, edgeweight, edgeid id) const -> decltype(f(u, v, id)) {
|
|
550
|
+
return f(u, v, id);
|
|
551
|
+
}
|
|
552
|
+
|
|
553
|
+
/**
|
|
554
|
+
* Calls the given function f if its third argument is of type edgeweight,
|
|
555
|
+
* discards the edge id Note that the decltype check is not enough as node
|
|
556
|
+
* can be casted to edgeweight.
|
|
557
|
+
*/
|
|
558
|
+
template <class F,
|
|
559
|
+
typename std::enable_if<
|
|
560
|
+
(Aux::FunctionTraits<F>::arity >= 2)
|
|
561
|
+
&& std::is_same<edgeweight, typename Aux::FunctionTraits<F>::template arg<
|
|
562
|
+
2>::type>::value>::type * = (void *)0>
|
|
563
|
+
auto edgeLambda(F &f, node u, node v, edgeweight ew, edgeid /*id*/) const
|
|
564
|
+
-> decltype(f(u, v, ew)) {
|
|
565
|
+
return f(u, v, ew);
|
|
566
|
+
}
|
|
567
|
+
|
|
568
|
+
/**
|
|
569
|
+
* Calls the given function f if it has only two arguments and the second
|
|
570
|
+
* argument is of type node, discards edge weight and id Note that the
|
|
571
|
+
* decltype check is not enough as edgeweight can be casted to node.
|
|
572
|
+
*/
|
|
573
|
+
template <class F, typename std::enable_if<
|
|
574
|
+
(Aux::FunctionTraits<F>::arity >= 1)
|
|
575
|
+
&& std::is_same<node, typename Aux::FunctionTraits<F>::template arg<
|
|
576
|
+
1>::type>::value>::type * = (void *)0>
|
|
577
|
+
auto edgeLambda(F &f, node u, node v, edgeweight /*ew*/, edgeid /*id*/) const
|
|
578
|
+
-> decltype(f(u, v)) {
|
|
579
|
+
return f(u, v);
|
|
580
|
+
}
|
|
581
|
+
|
|
582
|
+
/**
|
|
583
|
+
* Calls the given function f if it has only two arguments and the second
|
|
584
|
+
* argument is of type edgeweight, discards the first node and the edge id
|
|
585
|
+
* Note that the decltype check is not enough as edgeweight can be casted to
|
|
586
|
+
* node.
|
|
587
|
+
*/
|
|
588
|
+
template <class F,
|
|
589
|
+
typename std::enable_if<
|
|
590
|
+
(Aux::FunctionTraits<F>::arity >= 1)
|
|
591
|
+
&& std::is_same<edgeweight, typename Aux::FunctionTraits<F>::template arg<
|
|
592
|
+
1>::type>::value>::type * = (void *)0>
|
|
593
|
+
auto edgeLambda(F &f, node, node v, edgeweight ew, edgeid /*id*/) const -> decltype(f(v, ew)) {
|
|
594
|
+
return f(v, ew);
|
|
595
|
+
}
|
|
596
|
+
|
|
597
|
+
/**
|
|
598
|
+
* Calls the given function f if it has only one argument, discards the
|
|
599
|
+
* first node id, the edge weight and the edge id
|
|
600
|
+
*/
|
|
601
|
+
template <class F, void * = (void *)0>
|
|
602
|
+
auto edgeLambda(F &f, node, node v, edgeweight, edgeid) const -> decltype(f(v)) {
|
|
603
|
+
return f(v);
|
|
604
|
+
}
|
|
605
|
+
|
|
606
|
+
/**
|
|
607
|
+
* Calls the given BFS handle with distance parameter
|
|
608
|
+
*/
|
|
609
|
+
template <class F>
|
|
610
|
+
auto callBFSHandle(F &f, node u, count dist) const -> decltype(f(u, dist)) {
|
|
611
|
+
return f(u, dist);
|
|
612
|
+
}
|
|
613
|
+
|
|
614
|
+
/**
|
|
615
|
+
* Calls the given BFS handle without distance parameter
|
|
616
|
+
*/
|
|
617
|
+
template <class F>
|
|
618
|
+
auto callBFSHandle(F &f, node u, count) const -> decltype(f(u)) {
|
|
619
|
+
return f(u);
|
|
620
|
+
}
|
|
621
|
+
|
|
622
|
+
public:
|
|
623
|
+
// For support of API: NetworKit::Graph::NodeIterator
|
|
624
|
+
using NodeIterator = NodeIteratorBase<Graph>;
|
|
625
|
+
// For support of API: NetworKit::Graph::NodeRange
|
|
626
|
+
using NodeRange = NodeRangeBase<Graph>;
|
|
627
|
+
|
|
628
|
+
// For support of API: NetworKit::Graph:EdgeIterator
|
|
629
|
+
using EdgeIterator = EdgeTypeIterator<Graph, Edge>;
|
|
630
|
+
// For support of API: NetworKit::Graph:EdgeWeightIterator
|
|
631
|
+
using EdgeWeightIterator = EdgeTypeIterator<Graph, WeightedEdge>;
|
|
632
|
+
// For support of API: NetworKit::Graph:EdgeRange
|
|
633
|
+
using EdgeRange = EdgeTypeRange<Graph, Edge>;
|
|
634
|
+
// For support of API: NetworKit::Graph:EdgeWeightRange
|
|
635
|
+
using EdgeWeightRange = EdgeTypeRange<Graph, WeightedEdge>;
|
|
636
|
+
|
|
637
|
+
// For support of API: NetworKit::Graph::NeighborIterator;
|
|
638
|
+
using NeighborIterator = NeighborIteratorBase<std::vector<node>>;
|
|
639
|
+
// For support of API: NetworKit::Graph::NeighborIterator;
|
|
640
|
+
using NeighborWeightIterator =
|
|
641
|
+
NeighborWeightIteratorBase<std::vector<node>, std::vector<edgeweight>>;
|
|
642
|
+
|
|
643
|
+
/**
|
|
644
|
+
* Wrapper class to iterate over a range of the neighbors of a node within
|
|
645
|
+
* a for loop.
|
|
646
|
+
*/
|
|
647
|
+
template <bool InEdges = false>
|
|
648
|
+
class NeighborRange {
|
|
649
|
+
std::shared_ptr<std::vector<node>> neighborBuffer;
|
|
650
|
+
|
|
651
|
+
public:
|
|
652
|
+
NeighborRange(const Graph &G, node u)
|
|
653
|
+
: neighborBuffer(
|
|
654
|
+
std::make_shared<std::vector<node>>(G.getNeighborsVector(u, InEdges))) {}
|
|
655
|
+
NeighborRange() : neighborBuffer(std::make_shared<std::vector<node>>()) {}
|
|
656
|
+
|
|
657
|
+
NeighborIterator begin() const { return NeighborIterator(neighborBuffer->begin()); }
|
|
658
|
+
|
|
659
|
+
NeighborIterator end() const { return NeighborIterator(neighborBuffer->end()); }
|
|
660
|
+
};
|
|
661
|
+
|
|
662
|
+
using OutNeighborRange = NeighborRange<false>;
|
|
663
|
+
|
|
664
|
+
using InNeighborRange = NeighborRange<true>;
|
|
665
|
+
/**
|
|
666
|
+
* Wrapper class to iterate over a range of the neighbors of a node
|
|
667
|
+
* including the edge weights within a for loop.
|
|
668
|
+
* Values are std::pair<node, edgeweight>.
|
|
669
|
+
*/
|
|
670
|
+
template <bool InEdges = false>
|
|
671
|
+
class NeighborWeightRange {
|
|
672
|
+
std::shared_ptr<std::vector<node>> neighborBuffer;
|
|
673
|
+
std::shared_ptr<std::vector<edgeweight>> weightBuffer;
|
|
674
|
+
|
|
675
|
+
public:
|
|
676
|
+
NeighborWeightRange(const Graph &G, node u) {
|
|
677
|
+
auto [neighbors, weights] = G.getNeighborsWithWeightsVector(u, InEdges);
|
|
678
|
+
neighborBuffer = std::make_shared<std::vector<node>>(std::move(neighbors));
|
|
679
|
+
weightBuffer = std::make_shared<std::vector<edgeweight>>(std::move(weights));
|
|
680
|
+
}
|
|
681
|
+
NeighborWeightRange()
|
|
682
|
+
: neighborBuffer(std::make_shared<std::vector<node>>()),
|
|
683
|
+
weightBuffer(std::make_shared<std::vector<edgeweight>>()) {}
|
|
684
|
+
|
|
685
|
+
NeighborWeightIterator begin() const {
|
|
686
|
+
return NeighborWeightIterator(
|
|
687
|
+
typename std::vector<node>::const_iterator(neighborBuffer->begin()),
|
|
688
|
+
typename std::vector<edgeweight>::const_iterator(weightBuffer->begin()));
|
|
689
|
+
}
|
|
690
|
+
|
|
691
|
+
NeighborWeightIterator end() const {
|
|
692
|
+
return NeighborWeightIterator(
|
|
693
|
+
typename std::vector<node>::const_iterator(neighborBuffer->end()),
|
|
694
|
+
typename std::vector<edgeweight>::const_iterator(weightBuffer->end()));
|
|
695
|
+
}
|
|
696
|
+
};
|
|
697
|
+
|
|
698
|
+
using OutNeighborWeightRange = NeighborWeightRange<false>;
|
|
699
|
+
|
|
700
|
+
using InNeighborWeightRange = NeighborWeightRange<true>;
|
|
701
|
+
|
|
702
|
+
/**
|
|
703
|
+
* Create a graph of @a n nodes. The graph has assignable edge weights if @a
|
|
704
|
+
* weighted is set to <code>true</code>. If @a weighted is set to
|
|
705
|
+
* <code>false</code> each edge has edge weight 1.0 and any other weight
|
|
706
|
+
* assignment will be ignored.
|
|
707
|
+
* @param n Number of nodes.
|
|
708
|
+
* @param weighted If set to <code>true</code>, the graph has edge weights.
|
|
709
|
+
* @param directed If set to @c true, the graph will be directed.
|
|
710
|
+
*/
|
|
711
|
+
Graph(count n = 0, bool weighted = false, bool directed = false, bool edgesIndexed = false);
|
|
712
|
+
|
|
713
|
+
template <class EdgeMerger = std::plus<edgeweight>>
|
|
714
|
+
Graph(const Graph &G, bool weighted, bool directed, bool edgesIndexed = false,
|
|
715
|
+
[[maybe_unused]] EdgeMerger edgeMerger = std::plus<edgeweight>())
|
|
716
|
+
: n(G.n), m(G.m), storedNumberOfSelfLoops(G.storedNumberOfSelfLoops), z(G.z),
|
|
717
|
+
omega(edgesIndexed ? G.omega : 0), t(G.t), weighted(weighted), directed(directed),
|
|
718
|
+
edgesIndexed(edgesIndexed), // edges are not indexed by default
|
|
719
|
+
exists(G.exists), usingCSR(false), // Base Graph doesn't use CSR by default
|
|
720
|
+
|
|
721
|
+
// copy node attribute map
|
|
722
|
+
nodeAttributeMap(G.nodeAttributeMap, this),
|
|
723
|
+
// fill this later
|
|
724
|
+
edgeAttributeMap(this) {
|
|
725
|
+
|
|
726
|
+
// Base Graph class only supports CSR format and is immutable
|
|
727
|
+
throw std::runtime_error("Graph template copy constructor not supported in base Graph "
|
|
728
|
+
"class - use GraphW for conversions and mutable operations");
|
|
729
|
+
}
|
|
730
|
+
|
|
731
|
+
/**
|
|
732
|
+
* Generate a weighted graph from a list of edges. (Useful for small
|
|
733
|
+
* graphs in unit tests that you do not want to read from a file.)
|
|
734
|
+
*
|
|
735
|
+
* @param[in] edges list of weighted edges
|
|
736
|
+
*/
|
|
737
|
+
Graph(std::initializer_list<WeightedEdge> edges);
|
|
738
|
+
|
|
739
|
+
/**
|
|
740
|
+
* Create a graph from CSR arrays for memory-efficient storage.
|
|
741
|
+
*
|
|
742
|
+
* @param n Number of nodes.
|
|
743
|
+
* @param directed If set to @c true, the graph will be directed.
|
|
744
|
+
* @param outIndices CSR indices array containing neighbor node IDs for outgoing edges
|
|
745
|
+
* @param outIndptr CSR indptr array containing offsets into outIndices for each node
|
|
746
|
+
* @param inIndices CSR indices array containing neighbor node IDs for incoming edges (directed
|
|
747
|
+
* only)
|
|
748
|
+
* @param inIndptr CSR indptr array containing offsets into inIndices for each node (directed
|
|
749
|
+
* only)
|
|
750
|
+
*/
|
|
751
|
+
Graph(count n, bool directed, std::vector<node> outIndices, std::vector<index> outIndptr,
|
|
752
|
+
std::vector<node> inIndices = {}, std::vector<index> inIndptr = {});
|
|
753
|
+
|
|
754
|
+
/**
|
|
755
|
+
* Create a graph as copy of @a other.
|
|
756
|
+
* @param other The graph to copy.
|
|
757
|
+
*/
|
|
758
|
+
Graph(const Graph &other)
|
|
759
|
+
: n(other.n), m(other.m), storedNumberOfSelfLoops(other.storedNumberOfSelfLoops),
|
|
760
|
+
z(other.z), omega(other.omega), t(other.t), weighted(other.weighted),
|
|
761
|
+
directed(other.directed), edgesIndexed(other.edgesIndexed), deletedID(other.deletedID),
|
|
762
|
+
exists(other.exists), outEdgesCSRIndices(other.outEdgesCSRIndices),
|
|
763
|
+
outEdgesCSRIndptr(other.outEdgesCSRIndptr), inEdgesCSRIndices(other.inEdgesCSRIndices),
|
|
764
|
+
inEdgesCSRIndptr(other.inEdgesCSRIndptr), outEdgesCSRWeights(other.outEdgesCSRWeights),
|
|
765
|
+
inEdgesCSRWeights(other.inEdgesCSRWeights), usingCSR(other.usingCSR),
|
|
766
|
+
// call special constructors to copy attribute maps
|
|
767
|
+
nodeAttributeMap(other.nodeAttributeMap, this),
|
|
768
|
+
edgeAttributeMap(other.edgeAttributeMap, this) {
|
|
769
|
+
|
|
770
|
+
// Only support copying CSR-based graphs
|
|
771
|
+
if (!other.usingCSR) {
|
|
772
|
+
throw std::runtime_error("Graph copy constructor only supports CSR-based graphs. Use "
|
|
773
|
+
"GraphW for vector-based graphs.");
|
|
774
|
+
}
|
|
775
|
+
}
|
|
776
|
+
|
|
777
|
+
protected:
|
|
778
|
+
/**
|
|
779
|
+
* Protected copy constructor for subclasses (like GraphW) that use vector-based storage.
|
|
780
|
+
* This constructor copies the graph without requiring CSR format.
|
|
781
|
+
* @param other The graph to copy.
|
|
782
|
+
* @param subclassCopy Flag to indicate this is a subclass copy (bypass CSR check).
|
|
783
|
+
*/
|
|
784
|
+
Graph(const Graph &other, bool subclassCopy)
|
|
785
|
+
: n(other.n), m(other.m), storedNumberOfSelfLoops(other.storedNumberOfSelfLoops),
|
|
786
|
+
z(other.z), omega(other.omega), t(other.t), weighted(other.weighted),
|
|
787
|
+
directed(other.directed), edgesIndexed(other.edgesIndexed), deletedID(other.deletedID),
|
|
788
|
+
exists(other.exists), outEdgesCSRIndices(other.outEdgesCSRIndices),
|
|
789
|
+
outEdgesCSRIndptr(other.outEdgesCSRIndptr), inEdgesCSRIndices(other.inEdgesCSRIndices),
|
|
790
|
+
inEdgesCSRIndptr(other.inEdgesCSRIndptr), outEdgesCSRWeights(other.outEdgesCSRWeights),
|
|
791
|
+
inEdgesCSRWeights(other.inEdgesCSRWeights), usingCSR(other.usingCSR),
|
|
792
|
+
// call special constructors to copy attribute maps
|
|
793
|
+
nodeAttributeMap(other.nodeAttributeMap, this),
|
|
794
|
+
edgeAttributeMap(other.edgeAttributeMap, this) {
|
|
795
|
+
// This constructor is for subclasses only - no CSR check
|
|
796
|
+
(void)subclassCopy; // Suppress unused parameter warning
|
|
797
|
+
}
|
|
798
|
+
|
|
799
|
+
public:
|
|
800
|
+
/** move constructor */
|
|
801
|
+
Graph(Graph &&other) noexcept
|
|
802
|
+
: n(other.n), m(other.m), storedNumberOfSelfLoops(other.storedNumberOfSelfLoops),
|
|
803
|
+
z(other.z), omega(other.omega), t(other.t), weighted(other.weighted),
|
|
804
|
+
directed(other.directed), edgesIndexed(other.edgesIndexed), deletedID(other.deletedID),
|
|
805
|
+
exists(std::move(other.exists)), outEdgesCSRIndices(std::move(other.outEdgesCSRIndices)),
|
|
806
|
+
outEdgesCSRIndptr(std::move(other.outEdgesCSRIndptr)),
|
|
807
|
+
inEdgesCSRIndices(std::move(other.inEdgesCSRIndices)),
|
|
808
|
+
inEdgesCSRIndptr(std::move(other.inEdgesCSRIndptr)),
|
|
809
|
+
outEdgesCSRWeights(std::move(other.outEdgesCSRWeights)),
|
|
810
|
+
inEdgesCSRWeights(std::move(other.inEdgesCSRWeights)), usingCSR(other.usingCSR),
|
|
811
|
+
nodeAttributeMap(std::move(other.nodeAttributeMap)),
|
|
812
|
+
edgeAttributeMap(std::move(other.edgeAttributeMap)) {
|
|
813
|
+
// attributes: set graph pointer to this new graph
|
|
814
|
+
nodeAttributeMap.theGraph = this;
|
|
815
|
+
edgeAttributeMap.theGraph = this;
|
|
816
|
+
};
|
|
817
|
+
|
|
818
|
+
virtual ~Graph() = default;
|
|
819
|
+
|
|
820
|
+
/**
|
|
821
|
+
* Constructor that creates a graph from Arrow CSR arrays for zero-copy memory efficiency.
|
|
822
|
+
* @param n Number of nodes.
|
|
823
|
+
* @param directed If set to @c true, the graph will be directed.
|
|
824
|
+
* @param outIndices Arrow array containing neighbor node IDs for outgoing edges (CSR indices).
|
|
825
|
+
* @param outIndptr Arrow array containing offsets into outIndices for each node (CSR indptr).
|
|
826
|
+
* @param inIndices Arrow array containing neighbor node IDs for incoming edges (only for
|
|
827
|
+
* directed graphs).
|
|
828
|
+
* @param inIndptr Arrow array containing offsets into inIndices for each node (only for
|
|
829
|
+
* directed graphs).
|
|
830
|
+
* @param outWeights Arrow array containing edge weights for outgoing edges (optional).
|
|
831
|
+
* @param inWeights Arrow array containing edge weights for incoming edges (optional, only for
|
|
832
|
+
* directed graphs).
|
|
833
|
+
*/
|
|
834
|
+
Graph(count n, bool directed, std::shared_ptr<arrow::UInt64Array> outIndices,
|
|
835
|
+
std::shared_ptr<arrow::UInt64Array> outIndptr,
|
|
836
|
+
std::shared_ptr<arrow::UInt64Array> inIndices = nullptr,
|
|
837
|
+
std::shared_ptr<arrow::UInt64Array> inIndptr = nullptr,
|
|
838
|
+
std::shared_ptr<arrow::DoubleArray> outWeights = nullptr,
|
|
839
|
+
std::shared_ptr<arrow::DoubleArray> inWeights = nullptr);
|
|
840
|
+
|
|
841
|
+
/** move assignment operator */
|
|
842
|
+
Graph &operator=(Graph &&other) noexcept {
|
|
843
|
+
std::swap(n, other.n);
|
|
844
|
+
std::swap(m, other.m);
|
|
845
|
+
std::swap(storedNumberOfSelfLoops, other.storedNumberOfSelfLoops);
|
|
846
|
+
std::swap(z, other.z);
|
|
847
|
+
std::swap(omega, other.omega);
|
|
848
|
+
std::swap(t, other.t);
|
|
849
|
+
std::swap(weighted, other.weighted);
|
|
850
|
+
std::swap(directed, other.directed);
|
|
851
|
+
std::swap(edgesIndexed, other.edgesIndexed);
|
|
852
|
+
std::swap(exists, other.exists);
|
|
853
|
+
std::swap(usingCSR, other.usingCSR);
|
|
854
|
+
std::swap(outEdgesCSRIndices, other.outEdgesCSRIndices);
|
|
855
|
+
std::swap(outEdgesCSRIndptr, other.outEdgesCSRIndptr);
|
|
856
|
+
std::swap(inEdgesCSRIndices, other.inEdgesCSRIndices);
|
|
857
|
+
std::swap(inEdgesCSRIndptr, other.inEdgesCSRIndptr);
|
|
858
|
+
std::swap(outEdgesCSRWeights, other.outEdgesCSRWeights);
|
|
859
|
+
std::swap(inEdgesCSRWeights, other.inEdgesCSRWeights);
|
|
860
|
+
std::swap(deletedID, other.deletedID);
|
|
861
|
+
|
|
862
|
+
// attributes: set graph pointer to this new graph
|
|
863
|
+
std::swap(nodeAttributeMap, other.nodeAttributeMap);
|
|
864
|
+
std::swap(edgeAttributeMap, other.edgeAttributeMap);
|
|
865
|
+
nodeAttributeMap.theGraph = this;
|
|
866
|
+
edgeAttributeMap.theGraph = this;
|
|
867
|
+
|
|
868
|
+
return *this;
|
|
869
|
+
};
|
|
870
|
+
|
|
871
|
+
/** copy assignment operator */
|
|
872
|
+
Graph &operator=(const Graph &other) {
|
|
873
|
+
n = other.n;
|
|
874
|
+
m = other.m;
|
|
875
|
+
storedNumberOfSelfLoops = other.storedNumberOfSelfLoops;
|
|
876
|
+
z = other.z;
|
|
877
|
+
omega = other.omega;
|
|
878
|
+
t = other.t;
|
|
879
|
+
weighted = other.weighted;
|
|
880
|
+
directed = other.directed;
|
|
881
|
+
edgesIndexed = other.edgesIndexed;
|
|
882
|
+
exists = other.exists;
|
|
883
|
+
deletedID = other.deletedID;
|
|
884
|
+
|
|
885
|
+
// call special constructors to copy attribute maps
|
|
886
|
+
nodeAttributeMap = AttributeMap(other.nodeAttributeMap, this);
|
|
887
|
+
edgeAttributeMap = AttributeMap(other.edgeAttributeMap, this);
|
|
888
|
+
|
|
889
|
+
return *this;
|
|
890
|
+
};
|
|
891
|
+
|
|
892
|
+
/** EDGE IDS **/
|
|
893
|
+
|
|
894
|
+
/**
|
|
895
|
+
* Checks if edges have been indexed
|
|
896
|
+
*
|
|
897
|
+
* @return bool if edges have been indexed
|
|
898
|
+
*/
|
|
899
|
+
bool hasEdgeIds() const noexcept { return edgesIndexed; }
|
|
900
|
+
|
|
901
|
+
/**
|
|
902
|
+
* Get the id of the given edge.
|
|
903
|
+
*/
|
|
904
|
+
virtual edgeid edgeId(node u, node v) const = 0;
|
|
905
|
+
|
|
906
|
+
/**
|
|
907
|
+
* Get the Edge (u,v) of the given id. (inverse to edgeId)
|
|
908
|
+
* @note Time complexity of this function is O(n).
|
|
909
|
+
*/
|
|
910
|
+
std::pair<node, node> edgeById(index id) const {
|
|
911
|
+
std::pair<node, node> result{none, none};
|
|
912
|
+
bool found = false;
|
|
913
|
+
|
|
914
|
+
forNodesWhile([&] { return !found; },
|
|
915
|
+
[&](node u) {
|
|
916
|
+
forNeighborsOf(u, [&](node v) {
|
|
917
|
+
if (!this->isDirected() && v < u)
|
|
918
|
+
return;
|
|
919
|
+
auto uvId = edgeId(u, v);
|
|
920
|
+
if (uvId == id) {
|
|
921
|
+
found = true;
|
|
922
|
+
result = std::make_pair(u, v);
|
|
923
|
+
}
|
|
924
|
+
});
|
|
925
|
+
});
|
|
926
|
+
|
|
927
|
+
return result;
|
|
928
|
+
}
|
|
929
|
+
|
|
930
|
+
/**
|
|
931
|
+
* Get an upper bound for the edge ids in the graph.
|
|
932
|
+
* @return An upper bound for the edge ids.
|
|
933
|
+
*/
|
|
934
|
+
index upperEdgeIdBound() const noexcept { return omega; }
|
|
935
|
+
|
|
936
|
+
/** GRAPH INFORMATION **/
|
|
937
|
+
|
|
938
|
+
/**
|
|
939
|
+
* DEPRECATED: this function will no longer be supported in later releases.
|
|
940
|
+
* Compacts the adjacency arrays by re-using no longer needed slots from
|
|
941
|
+
* deleted edges.
|
|
942
|
+
*/
|
|
943
|
+
|
|
944
|
+
/**
|
|
945
|
+
* Check if node @a v exists in the graph.
|
|
946
|
+
*
|
|
947
|
+
* @param v Node.
|
|
948
|
+
* @return @c true if @a v exists, @c false otherwise.
|
|
949
|
+
*/
|
|
950
|
+
|
|
951
|
+
bool hasNode(node v) const noexcept { return (v < z) && this->exists[v]; }
|
|
952
|
+
|
|
953
|
+
/**
|
|
954
|
+
* Check if edge (u, v) exists in the graph.
|
|
955
|
+
*
|
|
956
|
+
* @param u First endpoint of edge.
|
|
957
|
+
* @param v Second endpoint of edge.
|
|
958
|
+
* @return @c true if edge exists, @c false otherwise.
|
|
959
|
+
*/
|
|
960
|
+
bool hasEdge(node u, node v) const;
|
|
961
|
+
|
|
962
|
+
/**
|
|
963
|
+
* @brief Virtual method for hasEdge - overridden by GraphW for vector-based graphs
|
|
964
|
+
*/
|
|
965
|
+
virtual bool hasEdgeImpl(node u, node v) const;
|
|
966
|
+
|
|
967
|
+
/**
|
|
968
|
+
* Remove adjacent edges satisfying a condition.
|
|
969
|
+
*
|
|
970
|
+
* @param u Node.
|
|
971
|
+
* @param condition A function that takes a node and returns true if the edge should be removed.
|
|
972
|
+
* @param edgesIn Whether to consider incoming edges.
|
|
973
|
+
* @return A pair of (number of removed edges, number of checked edges).
|
|
974
|
+
*/
|
|
975
|
+
template <typename Condition>
|
|
976
|
+
std::pair<count, count> removeAdjacentEdges(node u, Condition condition, bool edgesIn = false);
|
|
977
|
+
|
|
978
|
+
/** NODE PROPERTIES **/
|
|
979
|
+
/**
|
|
980
|
+
* Returns the number of outgoing neighbors of @a v.
|
|
981
|
+
*
|
|
982
|
+
* @param v Node.
|
|
983
|
+
* @return The number of outgoing neighbors.
|
|
984
|
+
* @note The existence of the node is not checked. Calling this function with a non-existing
|
|
985
|
+
* node results in a segmentation fault. Node existence can be checked by calling hasNode(u).
|
|
986
|
+
*/
|
|
987
|
+
virtual count degree(node v) const = 0;
|
|
988
|
+
|
|
989
|
+
/**
|
|
990
|
+
* Get the number of incoming neighbors of @a v.
|
|
991
|
+
*
|
|
992
|
+
* @param v Node.
|
|
993
|
+
* @return The number of incoming neighbors.
|
|
994
|
+
* @note If the graph is not directed, the outgoing degree is returned.
|
|
995
|
+
* @note The existence of the node is not checked. Calling this function with a non-existing
|
|
996
|
+
* node results in a segmentation fault. Node existence can be checked by calling hasNode(u).
|
|
997
|
+
*/
|
|
998
|
+
virtual count degreeIn(node v) const = 0;
|
|
999
|
+
|
|
1000
|
+
/**
|
|
1001
|
+
* Get the number of outgoing neighbors of @a v.
|
|
1002
|
+
*
|
|
1003
|
+
* @param v Node.
|
|
1004
|
+
* @return The number of outgoing neighbors.
|
|
1005
|
+
* @note The existence of the node is not checked. Calling this function with a non-existing
|
|
1006
|
+
* node results in a segmentation fault. Node existence can be checked by calling hasNode(u).
|
|
1007
|
+
*/
|
|
1008
|
+
count degreeOut(node v) const { return degree(v); }
|
|
1009
|
+
|
|
1010
|
+
/**
|
|
1011
|
+
* Check whether @a v is isolated, i.e. degree is 0.
|
|
1012
|
+
* @param v Node.
|
|
1013
|
+
* @return @c true if the node is isolated (= degree is 0)
|
|
1014
|
+
*/
|
|
1015
|
+
virtual bool isIsolated(node v) const = 0;
|
|
1016
|
+
|
|
1017
|
+
/**
|
|
1018
|
+
* Returns the weighted degree of @a u.
|
|
1019
|
+
*
|
|
1020
|
+
* @param u Node.
|
|
1021
|
+
* @param countSelfLoopsTwice If set to true, self-loops will be counted twice.
|
|
1022
|
+
*
|
|
1023
|
+
* @return Weighted degree of @a u.
|
|
1024
|
+
*/
|
|
1025
|
+
edgeweight weightedDegree(node u, bool countSelfLoopsTwice = false) const;
|
|
1026
|
+
|
|
1027
|
+
/**
|
|
1028
|
+
* Returns the weighted in-degree of @a u.
|
|
1029
|
+
*
|
|
1030
|
+
* @param u Node.
|
|
1031
|
+
* @param countSelfLoopsTwice If set to true, self-loops will be counted twice.
|
|
1032
|
+
*
|
|
1033
|
+
* @return Weighted in-degree of @a v.
|
|
1034
|
+
*/
|
|
1035
|
+
edgeweight weightedDegreeIn(node u, bool countSelfLoopsTwice = false) const;
|
|
1036
|
+
|
|
1037
|
+
/**
|
|
1038
|
+
* Returns <code>true</code> if this graph supports edge weights other
|
|
1039
|
+
* than 1.0.
|
|
1040
|
+
* @return <code>true</code> if this graph supports edge weights other
|
|
1041
|
+
* than 1.0.
|
|
1042
|
+
*/
|
|
1043
|
+
bool isWeighted() const noexcept { return weighted; }
|
|
1044
|
+
|
|
1045
|
+
/**
|
|
1046
|
+
* Return @c true if this graph supports directed edges.
|
|
1047
|
+
* @return @c true if this graph supports directed edges.
|
|
1048
|
+
*/
|
|
1049
|
+
bool isDirected() const noexcept { return directed; }
|
|
1050
|
+
|
|
1051
|
+
/**
|
|
1052
|
+
* Return <code>true</code> if graph contains no nodes.
|
|
1053
|
+
* @return <code>true</code> if graph contains no nodes.
|
|
1054
|
+
*/
|
|
1055
|
+
bool isEmpty() const noexcept { return !n; }
|
|
1056
|
+
|
|
1057
|
+
/**
|
|
1058
|
+
* Return the number of nodes in the graph.
|
|
1059
|
+
* @return The number of nodes.
|
|
1060
|
+
*/
|
|
1061
|
+
count numberOfNodes() const noexcept { return n; }
|
|
1062
|
+
|
|
1063
|
+
/**
|
|
1064
|
+
* Return the number of edges in the graph.
|
|
1065
|
+
* @return The number of edges.
|
|
1066
|
+
*/
|
|
1067
|
+
count numberOfEdges() const noexcept { return m; }
|
|
1068
|
+
|
|
1069
|
+
/**
|
|
1070
|
+
* Return the number of loops {v,v} in the graph.
|
|
1071
|
+
* @return The number of loops.
|
|
1072
|
+
*/
|
|
1073
|
+
count numberOfSelfLoops() const noexcept { return storedNumberOfSelfLoops; }
|
|
1074
|
+
|
|
1075
|
+
/**
|
|
1076
|
+
* Get an upper bound for the node ids in the graph.
|
|
1077
|
+
* @return An upper bound for the node ids.
|
|
1078
|
+
*/
|
|
1079
|
+
index upperNodeIdBound() const noexcept { return z; }
|
|
1080
|
+
|
|
1081
|
+
/**
|
|
1082
|
+
* Returns true if edges are currently being sorted when removeEdge() is called.
|
|
1083
|
+
*/
|
|
1084
|
+
bool getKeepEdgesSorted() const noexcept { return maintainSortedEdges; }
|
|
1085
|
+
|
|
1086
|
+
/**
|
|
1087
|
+
* Returns true if edges are currently being compacted when removeEdge() is called.
|
|
1088
|
+
*/
|
|
1089
|
+
bool getMaintainCompactEdges() const noexcept { return maintainCompactEdges; }
|
|
1090
|
+
|
|
1091
|
+
/**
|
|
1092
|
+
* Check for invalid graph states, such as multi-edges.
|
|
1093
|
+
* @return False if the graph is in invalid state.
|
|
1094
|
+
*/
|
|
1095
|
+
virtual bool checkConsistency() const;
|
|
1096
|
+
|
|
1097
|
+
/* DYNAMICS */
|
|
1098
|
+
|
|
1099
|
+
/**
|
|
1100
|
+
* Trigger a time step - increments counter.
|
|
1101
|
+
*
|
|
1102
|
+
* This method is deprecated and will not be supported in future releases.
|
|
1103
|
+
*/
|
|
1104
|
+
void timeStep() {
|
|
1105
|
+
WARN("Graph::timeStep should not be used and will be deprecated in the future.");
|
|
1106
|
+
t++;
|
|
1107
|
+
}
|
|
1108
|
+
|
|
1109
|
+
/**
|
|
1110
|
+
* Get time step counter.
|
|
1111
|
+
* @return Time step counter.
|
|
1112
|
+
*
|
|
1113
|
+
* This method is deprecated and will not be supported in future releases.
|
|
1114
|
+
*/
|
|
1115
|
+
count time() {
|
|
1116
|
+
WARN("Graph::time should not be used and will be deprecated in the future.");
|
|
1117
|
+
return t;
|
|
1118
|
+
}
|
|
1119
|
+
|
|
1120
|
+
/**
|
|
1121
|
+
* Return edge weight of edge {@a u,@a v}. Returns 0 if edge does not
|
|
1122
|
+
* exist. BEWARE: Running time is \Theta(deg(u))!
|
|
1123
|
+
*
|
|
1124
|
+
* @param u Endpoint of edge.
|
|
1125
|
+
* @param v Endpoint of edge.
|
|
1126
|
+
* @return Edge weight of edge {@a u,@a v} or 0 if edge does not exist.
|
|
1127
|
+
*/
|
|
1128
|
+
virtual edgeweight weight(node u, node v) const;
|
|
1129
|
+
|
|
1130
|
+
/**
|
|
1131
|
+
* Set the weight to the i-th neighbour of u.
|
|
1132
|
+
*
|
|
1133
|
+
* @param[in] u endpoint of edge
|
|
1134
|
+
* @param[in] i index of the nexight
|
|
1135
|
+
* @param[in] ew edge weight
|
|
1136
|
+
*/
|
|
1137
|
+
virtual void setWeightAtIthNeighbor(Unsafe, node u, index i, edgeweight ew);
|
|
1138
|
+
|
|
1139
|
+
/**
|
|
1140
|
+
* Set the weight to the i-th incoming neighbour of u.
|
|
1141
|
+
*
|
|
1142
|
+
* @param[in] u endpoint of edge
|
|
1143
|
+
* @param[in] i index of the nexight
|
|
1144
|
+
* @param[in] ew edge weight
|
|
1145
|
+
*/
|
|
1146
|
+
virtual void setWeightAtIthInNeighbor(Unsafe, node u, index i, edgeweight ew);
|
|
1147
|
+
|
|
1148
|
+
/* SUMS */
|
|
1149
|
+
|
|
1150
|
+
/**
|
|
1151
|
+
* Returns the sum of all edge weights.
|
|
1152
|
+
* @return The sum of all edge weights.
|
|
1153
|
+
*/
|
|
1154
|
+
edgeweight totalEdgeWeight() const noexcept;
|
|
1155
|
+
|
|
1156
|
+
/**
|
|
1157
|
+
* Return the i-th (outgoing) neighbor of @a u.
|
|
1158
|
+
*
|
|
1159
|
+
* @param u Node.
|
|
1160
|
+
* @param i index; should be in [0, degreeOut(u))
|
|
1161
|
+
* @return @a i-th (outgoing) neighbor of @a u, or @c none if no such
|
|
1162
|
+
* neighbor exists.
|
|
1163
|
+
*/
|
|
1164
|
+
virtual node getIthNeighbor(Unsafe, node u, index i) const = 0;
|
|
1165
|
+
|
|
1166
|
+
/**
|
|
1167
|
+
* Return the weight to the i-th (outgoing) neighbor of @a u.
|
|
1168
|
+
*
|
|
1169
|
+
* @param u Node.
|
|
1170
|
+
* @param i index; should be in [0, degreeOut(u))
|
|
1171
|
+
* @return @a edge weight to the i-th (outgoing) neighbor of @a u, or @c +inf if no such
|
|
1172
|
+
* neighbor exists.
|
|
1173
|
+
*/
|
|
1174
|
+
virtual edgeweight getIthNeighborWeight(node u, index i) const = 0;
|
|
1175
|
+
|
|
1176
|
+
/**
|
|
1177
|
+
* Return the weight to the i-th (outgoing) neighbor of @a u - unsafe version
|
|
1178
|
+
* that assumes valid indices.
|
|
1179
|
+
*
|
|
1180
|
+
* @param u Node.
|
|
1181
|
+
* @param i index.
|
|
1182
|
+
* @return @a edge weight to the i-th (outgoing) neighbor of @a u.
|
|
1183
|
+
*/
|
|
1184
|
+
edgeweight getIthNeighborWeight(Unsafe, node u, index i) const {
|
|
1185
|
+
return getIthNeighborWeight(u, i);
|
|
1186
|
+
}
|
|
1187
|
+
|
|
1188
|
+
/**
|
|
1189
|
+
* Get an iterable range over the nodes of the graph.
|
|
1190
|
+
*
|
|
1191
|
+
* @return Iterator range over the nodes of the graph.
|
|
1192
|
+
*/
|
|
1193
|
+
NodeRange nodeRange() const noexcept { return NodeRange(*this); }
|
|
1194
|
+
|
|
1195
|
+
/**
|
|
1196
|
+
* Get an iterable range over the edges of the graph.
|
|
1197
|
+
*
|
|
1198
|
+
* @return Iterator range over the edges of the graph.
|
|
1199
|
+
*/
|
|
1200
|
+
EdgeRange edgeRange() const noexcept { return EdgeRange(*this); }
|
|
1201
|
+
|
|
1202
|
+
/**
|
|
1203
|
+
* Get an iterable range over the edges of the graph and their weights.
|
|
1204
|
+
*
|
|
1205
|
+
* @return Iterator range over the edges of the graph and their weights.
|
|
1206
|
+
*/
|
|
1207
|
+
EdgeWeightRange edgeWeightRange() const noexcept { return EdgeWeightRange(*this); }
|
|
1208
|
+
|
|
1209
|
+
/**
|
|
1210
|
+
* Get an iterable range over the neighbors of @a.
|
|
1211
|
+
*
|
|
1212
|
+
* @param u Node.
|
|
1213
|
+
* @return Iterator range over the neighbors of @a u.
|
|
1214
|
+
*/
|
|
1215
|
+
NeighborRange<false> neighborRange(node u) const {
|
|
1216
|
+
assert(exists[u]);
|
|
1217
|
+
return NeighborRange<false>(*this, u);
|
|
1218
|
+
}
|
|
1219
|
+
|
|
1220
|
+
/**
|
|
1221
|
+
* Get an iterable range over the neighbors of @a u including the edge
|
|
1222
|
+
* weights.
|
|
1223
|
+
*
|
|
1224
|
+
* @param u Node.
|
|
1225
|
+
* @return Iterator range over pairs of neighbors of @a u and corresponding
|
|
1226
|
+
* edge weights.
|
|
1227
|
+
*/
|
|
1228
|
+
NeighborWeightRange<false> weightNeighborRange(node u) const {
|
|
1229
|
+
assert(isWeighted());
|
|
1230
|
+
assert(exists[u]);
|
|
1231
|
+
return NeighborWeightRange<false>(*this, u);
|
|
1232
|
+
}
|
|
1233
|
+
|
|
1234
|
+
/**
|
|
1235
|
+
* Get an iterable range over the in-neighbors of @a.
|
|
1236
|
+
*
|
|
1237
|
+
* @param u Node.
|
|
1238
|
+
* @return Iterator range over pairs of in-neighbors of @a u.
|
|
1239
|
+
*/
|
|
1240
|
+
NeighborRange<true> inNeighborRange(node u) const {
|
|
1241
|
+
assert(isDirected());
|
|
1242
|
+
assert(exists[u]);
|
|
1243
|
+
return NeighborRange<true>(*this, u);
|
|
1244
|
+
}
|
|
1245
|
+
|
|
1246
|
+
/**
|
|
1247
|
+
* Get an iterable range over the in-neighbors of @a u including the
|
|
1248
|
+
* edge weights.
|
|
1249
|
+
*
|
|
1250
|
+
* @param u Node.
|
|
1251
|
+
* @return Iterator range over pairs of in-neighbors of @a u and corresponding
|
|
1252
|
+
* edge weights.
|
|
1253
|
+
*/
|
|
1254
|
+
NeighborWeightRange<true> weightInNeighborRange(node u) const {
|
|
1255
|
+
assert(isDirected() && isWeighted());
|
|
1256
|
+
assert(exists[u]);
|
|
1257
|
+
return NeighborWeightRange<true>(*this, u);
|
|
1258
|
+
}
|
|
1259
|
+
|
|
1260
|
+
/**
|
|
1261
|
+
* Returns the index of node v in the array of outgoing edges of node u.
|
|
1262
|
+
*
|
|
1263
|
+
* @param u Node
|
|
1264
|
+
* @param v Node
|
|
1265
|
+
* @return index of node v in the array of outgoing edges of node u.
|
|
1266
|
+
*/
|
|
1267
|
+
index indexOfNeighbor(node u, node v) const { return indexInOutEdgeArray(u, v); }
|
|
1268
|
+
|
|
1269
|
+
/**
|
|
1270
|
+
* Return the i-th (outgoing) neighbor of @a u.
|
|
1271
|
+
*
|
|
1272
|
+
* @param u Node.
|
|
1273
|
+
* @param i index; should be in [0, degreeOut(u))
|
|
1274
|
+
* @return @a i-th (outgoing) neighbor of @a u, or @c none if no such
|
|
1275
|
+
* neighbor exists.
|
|
1276
|
+
*/
|
|
1277
|
+
virtual node getIthNeighbor(node u, index i) const = 0;
|
|
1278
|
+
|
|
1279
|
+
/**
|
|
1280
|
+
* Return the i-th (incoming) neighbor of @a u.
|
|
1281
|
+
*
|
|
1282
|
+
* @param u Node.
|
|
1283
|
+
* @param i index; should be in [0, degreeIn(u))
|
|
1284
|
+
* @return @a i-th (incoming) neighbor of @a u, or @c none if no such
|
|
1285
|
+
* neighbor exists.
|
|
1286
|
+
*/
|
|
1287
|
+
virtual node getIthInNeighbor(node u, index i) const = 0;
|
|
1288
|
+
|
|
1289
|
+
/**
|
|
1290
|
+
* Return the weight to the i-th (outgoing) neighbor of @a u.
|
|
1291
|
+
*
|
|
1292
|
+
* @param u Node.
|
|
1293
|
+
* @param i index; should be in [0, degreeOut(u))
|
|
1294
|
+
* @return @a edge weight to the i-th (outgoing) neighbor of @a u, or @c +inf if no such
|
|
1295
|
+
* neighbor exists.
|
|
1296
|
+
*/
|
|
1297
|
+
|
|
1298
|
+
/**
|
|
1299
|
+
* Get i-th (outgoing) neighbor of @a u and the corresponding edge weight.
|
|
1300
|
+
*
|
|
1301
|
+
* @param u Node.
|
|
1302
|
+
* @param i index; should be in [0, degreeOut(u))
|
|
1303
|
+
* @return pair: i-th (outgoing) neighbor of @a u and the corresponding
|
|
1304
|
+
* edge weight, or @c defaultEdgeWeight if unweighted.
|
|
1305
|
+
*/
|
|
1306
|
+
virtual std::pair<node, edgeweight> getIthNeighborWithWeight(node u, index i) const = 0;
|
|
1307
|
+
|
|
1308
|
+
/**
|
|
1309
|
+
* Get i-th (outgoing) neighbor of @a u and the corresponding edge weight - unsafe version.
|
|
1310
|
+
*
|
|
1311
|
+
* @param u Node.
|
|
1312
|
+
* @param i index.
|
|
1313
|
+
* @return pair: i-th (outgoing) neighbor of @a u and the corresponding edge weight.
|
|
1314
|
+
*/
|
|
1315
|
+
std::pair<node, edgeweight> getIthNeighborWithWeight(Unsafe, node u, index i) const {
|
|
1316
|
+
return getIthNeighborWithWeight(u, i);
|
|
1317
|
+
}
|
|
1318
|
+
|
|
1319
|
+
/**
|
|
1320
|
+
* Get i-th (outgoing) neighbor of @a u and the corresponding edge id.
|
|
1321
|
+
*
|
|
1322
|
+
* @param u Node.
|
|
1323
|
+
* @param i index; should be in [0, degreeOut(u))
|
|
1324
|
+
* @return pair: i-th (outgoing) neighbor of @a u and the corresponding
|
|
1325
|
+
* edge id, or @c none if no such neighbor exists.
|
|
1326
|
+
*/
|
|
1327
|
+
virtual std::pair<node, edgeid> getIthNeighborWithId(node u, index i) const = 0;
|
|
1328
|
+
|
|
1329
|
+
/* NODE ITERATORS */
|
|
1330
|
+
|
|
1331
|
+
/**
|
|
1332
|
+
* Iterate over all nodes of the graph and call @a handle (lambda
|
|
1333
|
+
* closure).
|
|
1334
|
+
*
|
|
1335
|
+
* @param handle Takes parameter <code>(node)</code>.
|
|
1336
|
+
*/
|
|
1337
|
+
template <typename L>
|
|
1338
|
+
void forNodes(L handle) const;
|
|
1339
|
+
|
|
1340
|
+
/**
|
|
1341
|
+
* Iterate randomly over all nodes of the graph and call @a handle (lambda
|
|
1342
|
+
* closure).
|
|
1343
|
+
*
|
|
1344
|
+
* @param handle Takes parameter <code>(node)</code>.
|
|
1345
|
+
*/
|
|
1346
|
+
template <typename L>
|
|
1347
|
+
void parallelForNodes(L handle) const;
|
|
1348
|
+
|
|
1349
|
+
/** Iterate over all nodes of the graph and call @a handle (lambda
|
|
1350
|
+
* closure) as long as @a condition remains true. This allows for breaking
|
|
1351
|
+
* from a node loop.
|
|
1352
|
+
*
|
|
1353
|
+
* @param condition Returning <code>false</code> breaks the loop.
|
|
1354
|
+
* @param handle Takes parameter <code>(node)</code>.
|
|
1355
|
+
*/
|
|
1356
|
+
template <typename C, typename L>
|
|
1357
|
+
void forNodesWhile(C condition, L handle) const;
|
|
1358
|
+
|
|
1359
|
+
/**
|
|
1360
|
+
* Iterate randomly over all nodes of the graph and call @a handle (lambda
|
|
1361
|
+
* closure).
|
|
1362
|
+
*
|
|
1363
|
+
* @param handle Takes parameter <code>(node)</code>.
|
|
1364
|
+
*/
|
|
1365
|
+
template <typename L>
|
|
1366
|
+
void forNodesInRandomOrder(L handle) const;
|
|
1367
|
+
|
|
1368
|
+
/**
|
|
1369
|
+
* Iterate in parallel over all nodes of the graph and call handler
|
|
1370
|
+
* (lambda closure). Using schedule(guided) to remedy load-imbalances due
|
|
1371
|
+
* to e.g. unequal degree distribution.
|
|
1372
|
+
*
|
|
1373
|
+
* @param handle Takes parameter <code>(node)</code>.
|
|
1374
|
+
*/
|
|
1375
|
+
template <typename L>
|
|
1376
|
+
void balancedParallelForNodes(L handle) const;
|
|
1377
|
+
|
|
1378
|
+
/**
|
|
1379
|
+
* Iterate over all undirected pairs of nodes and call @a handle (lambda
|
|
1380
|
+
* closure).
|
|
1381
|
+
*
|
|
1382
|
+
* @param handle Takes parameters <code>(node, node)</code>.
|
|
1383
|
+
*/
|
|
1384
|
+
template <typename L>
|
|
1385
|
+
void forNodePairs(L handle) const;
|
|
1386
|
+
|
|
1387
|
+
/**
|
|
1388
|
+
* Iterate over all undirected pairs of nodes in parallel and call @a
|
|
1389
|
+
* handle (lambda closure).
|
|
1390
|
+
*
|
|
1391
|
+
* @param handle Takes parameters <code>(node, node)</code>.
|
|
1392
|
+
*/
|
|
1393
|
+
template <typename L>
|
|
1394
|
+
void parallelForNodePairs(L handle) const;
|
|
1395
|
+
|
|
1396
|
+
/* EDGE ITERATORS */
|
|
1397
|
+
|
|
1398
|
+
/**
|
|
1399
|
+
* Iterate over all edges of the const graph and call @a handle (lambda
|
|
1400
|
+
* closure).
|
|
1401
|
+
*
|
|
1402
|
+
* @param handle Takes parameters <code>(node, node)</code>, <code>(node,
|
|
1403
|
+
* node, edgweight)</code>, <code>(node, node, edgeid)</code> or
|
|
1404
|
+
* <code>(node, node, edgeweight, edgeid)</code>.
|
|
1405
|
+
*/
|
|
1406
|
+
template <typename L>
|
|
1407
|
+
void forEdges(L handle) const;
|
|
1408
|
+
|
|
1409
|
+
/**
|
|
1410
|
+
* Iterate in parallel over all edges of the const graph and call @a
|
|
1411
|
+
* handle (lambda closure).
|
|
1412
|
+
*
|
|
1413
|
+
* @param handle Takes parameters <code>(node, node)</code> or
|
|
1414
|
+
* <code>(node, node, edgweight)</code>, <code>(node, node, edgeid)</code>
|
|
1415
|
+
* or <code>(node, node, edgeweight, edgeid)</code>.
|
|
1416
|
+
*/
|
|
1417
|
+
template <typename L>
|
|
1418
|
+
void parallelForEdges(L handle) const;
|
|
1419
|
+
|
|
1420
|
+
/* NEIGHBORHOOD ITERATORS */
|
|
1421
|
+
|
|
1422
|
+
/**
|
|
1423
|
+
* Iterate over all neighbors of a node and call @a handle (lamdba
|
|
1424
|
+
* closure).
|
|
1425
|
+
*
|
|
1426
|
+
* @param u Node.
|
|
1427
|
+
* @param handle Takes parameter <code>(node)</code> or <code>(node,
|
|
1428
|
+
* edgeweight)</code> which is a neighbor of @a u.
|
|
1429
|
+
* @note For directed graphs only outgoing edges from @a u are considered.
|
|
1430
|
+
* A node is its own neighbor if there is a self-loop.
|
|
1431
|
+
*
|
|
1432
|
+
*/
|
|
1433
|
+
template <typename L>
|
|
1434
|
+
void forNeighborsOf(node u, L handle) const;
|
|
1435
|
+
|
|
1436
|
+
/**
|
|
1437
|
+
* Iterate over all incident edges of a node and call @a handle (lamdba
|
|
1438
|
+
* closure).
|
|
1439
|
+
*
|
|
1440
|
+
* @param u Node.
|
|
1441
|
+
* @param handle Takes parameters <code>(node, node)</code>, <code>(node,
|
|
1442
|
+
* node, edgeweight)</code>, <code>(node, node, edgeid)</code> or
|
|
1443
|
+
* <code>(node, node, edgeweight, edgeid)</code> where the first node is
|
|
1444
|
+
* @a u and the second is a neighbor of @a u.
|
|
1445
|
+
* @note For undirected graphs all edges incident to @a u are also
|
|
1446
|
+
* outgoing edges.
|
|
1447
|
+
*/
|
|
1448
|
+
template <typename L>
|
|
1449
|
+
void forEdgesOf(node u, L handle) const;
|
|
1450
|
+
|
|
1451
|
+
/**
|
|
1452
|
+
* Iterate over all neighbors of a node and call handler (lamdba closure).
|
|
1453
|
+
* For directed graphs only incoming edges from u are considered.
|
|
1454
|
+
*/
|
|
1455
|
+
template <typename L>
|
|
1456
|
+
void forInNeighborsOf(node u, L handle) const;
|
|
1457
|
+
|
|
1458
|
+
/**
|
|
1459
|
+
* Iterate over all incoming edges of a node and call handler (lamdba
|
|
1460
|
+
* closure).
|
|
1461
|
+
* @note For undirected graphs all edges incident to u are also incoming
|
|
1462
|
+
* edges.
|
|
1463
|
+
*
|
|
1464
|
+
* Handle takes parameters (u, v) or (u, v, w) where w is the edge weight.
|
|
1465
|
+
*/
|
|
1466
|
+
template <typename L>
|
|
1467
|
+
void forInEdgesOf(node u, L handle) const;
|
|
1468
|
+
|
|
1469
|
+
/* REDUCTION ITERATORS */
|
|
1470
|
+
|
|
1471
|
+
/**
|
|
1472
|
+
* Iterate in parallel over all nodes and sum (reduce +) the values
|
|
1473
|
+
* returned by the handler
|
|
1474
|
+
*/
|
|
1475
|
+
template <typename L>
|
|
1476
|
+
double parallelSumForNodes(L handle) const;
|
|
1477
|
+
|
|
1478
|
+
/**
|
|
1479
|
+
* Iterate in parallel over all edges and sum (reduce +) the values
|
|
1480
|
+
* returned by the handler
|
|
1481
|
+
*/
|
|
1482
|
+
template <typename L>
|
|
1483
|
+
double parallelSumForEdges(L handle) const;
|
|
1484
|
+
};
|
|
1485
|
+
|
|
1486
|
+
/* NODE ITERATORS */
|
|
1487
|
+
|
|
1488
|
+
template <typename L>
|
|
1489
|
+
void Graph::forNodes(L handle) const {
|
|
1490
|
+
for (node v = 0; v < z; ++v) {
|
|
1491
|
+
if (exists[v]) {
|
|
1492
|
+
handle(v);
|
|
1493
|
+
}
|
|
1494
|
+
}
|
|
1495
|
+
}
|
|
1496
|
+
|
|
1497
|
+
template <typename L>
|
|
1498
|
+
void Graph::parallelForNodes(L handle) const {
|
|
1499
|
+
if (usingCSR) {
|
|
1500
|
+
// For immutable CSR graphs, all nodes exist - skip exists check for thread safety
|
|
1501
|
+
#pragma omp parallel for
|
|
1502
|
+
for (omp_index v = 0; v < static_cast<omp_index>(z); ++v) {
|
|
1503
|
+
handle(v);
|
|
1504
|
+
}
|
|
1505
|
+
} else {
|
|
1506
|
+
// For mutable graphs, check exists
|
|
1507
|
+
#pragma omp parallel for
|
|
1508
|
+
for (omp_index v = 0; v < static_cast<omp_index>(z); ++v) {
|
|
1509
|
+
if (exists[v]) {
|
|
1510
|
+
handle(v);
|
|
1511
|
+
}
|
|
1512
|
+
}
|
|
1513
|
+
}
|
|
1514
|
+
}
|
|
1515
|
+
|
|
1516
|
+
template <typename C, typename L>
|
|
1517
|
+
void Graph::forNodesWhile(C condition, L handle) const {
|
|
1518
|
+
for (node v = 0; v < z; ++v) {
|
|
1519
|
+
if (exists[v]) {
|
|
1520
|
+
if (!condition()) {
|
|
1521
|
+
break;
|
|
1522
|
+
}
|
|
1523
|
+
handle(v);
|
|
1524
|
+
}
|
|
1525
|
+
}
|
|
1526
|
+
}
|
|
1527
|
+
|
|
1528
|
+
template <typename L>
|
|
1529
|
+
void Graph::forNodesInRandomOrder(L handle) const {
|
|
1530
|
+
std::vector<node> randVec;
|
|
1531
|
+
randVec.reserve(numberOfNodes());
|
|
1532
|
+
forNodes([&](node u) { randVec.push_back(u); });
|
|
1533
|
+
std::ranges::shuffle(randVec, Aux::Random::getURNG());
|
|
1534
|
+
for (node v : randVec) {
|
|
1535
|
+
handle(v);
|
|
1536
|
+
}
|
|
1537
|
+
}
|
|
1538
|
+
|
|
1539
|
+
template <typename L>
|
|
1540
|
+
void Graph::balancedParallelForNodes(L handle) const {
|
|
1541
|
+
// TODO: define min block size (and test it!)
|
|
1542
|
+
if (usingCSR) {
|
|
1543
|
+
// For immutable CSR graphs, all nodes exist - skip exists check for thread safety
|
|
1544
|
+
#pragma omp parallel for schedule(guided)
|
|
1545
|
+
for (omp_index v = 0; v < static_cast<omp_index>(z); ++v) {
|
|
1546
|
+
handle(v);
|
|
1547
|
+
}
|
|
1548
|
+
} else {
|
|
1549
|
+
// For mutable graphs, check exists
|
|
1550
|
+
#pragma omp parallel for schedule(guided)
|
|
1551
|
+
for (omp_index v = 0; v < static_cast<omp_index>(z); ++v) {
|
|
1552
|
+
if (exists[v]) {
|
|
1553
|
+
handle(v);
|
|
1554
|
+
}
|
|
1555
|
+
}
|
|
1556
|
+
}
|
|
1557
|
+
}
|
|
1558
|
+
|
|
1559
|
+
template <typename L>
|
|
1560
|
+
void Graph::forNodePairs(L handle) const {
|
|
1561
|
+
for (node u = 0; u < z; ++u) {
|
|
1562
|
+
if (exists[u]) {
|
|
1563
|
+
for (node v = u + 1; v < z; ++v) {
|
|
1564
|
+
if (exists[v]) {
|
|
1565
|
+
handle(u, v);
|
|
1566
|
+
}
|
|
1567
|
+
}
|
|
1568
|
+
}
|
|
1569
|
+
}
|
|
1570
|
+
}
|
|
1571
|
+
|
|
1572
|
+
template <typename L>
|
|
1573
|
+
void Graph::parallelForNodePairs(L handle) const {
|
|
1574
|
+
if (usingCSR) {
|
|
1575
|
+
// For immutable CSR graphs, all nodes exist - skip exists check for thread safety
|
|
1576
|
+
#pragma omp parallel for schedule(guided)
|
|
1577
|
+
for (omp_index u = 0; u < static_cast<omp_index>(z); ++u) {
|
|
1578
|
+
for (node v = u + 1; v < z; ++v) {
|
|
1579
|
+
handle(u, v);
|
|
1580
|
+
}
|
|
1581
|
+
}
|
|
1582
|
+
} else {
|
|
1583
|
+
// For mutable graphs, check exists
|
|
1584
|
+
#pragma omp parallel for schedule(guided)
|
|
1585
|
+
for (omp_index u = 0; u < static_cast<omp_index>(z); ++u) {
|
|
1586
|
+
if (exists[u]) {
|
|
1587
|
+
for (node v = u + 1; v < z; ++v) {
|
|
1588
|
+
if (exists[v]) {
|
|
1589
|
+
handle(u, v);
|
|
1590
|
+
}
|
|
1591
|
+
}
|
|
1592
|
+
}
|
|
1593
|
+
}
|
|
1594
|
+
}
|
|
1595
|
+
}
|
|
1596
|
+
|
|
1597
|
+
/* EDGE ITERATORS */
|
|
1598
|
+
|
|
1599
|
+
/* HELPERS */
|
|
1600
|
+
|
|
1601
|
+
template <typename T>
|
|
1602
|
+
void erase(node u, index idx, std::vector<std::vector<T>> &vec);
|
|
1603
|
+
// implementation for weighted == true
|
|
1604
|
+
template <bool hasWeights>
|
|
1605
|
+
inline edgeweight Graph::getOutEdgeWeight([[maybe_unused]] node u, [[maybe_unused]] index i) const {
|
|
1606
|
+
// Base Graph class only supports CSR format
|
|
1607
|
+
throw std::runtime_error(
|
|
1608
|
+
"getOutEdgeWeight not supported in base Graph class - use GraphW for mutable operations");
|
|
1609
|
+
}
|
|
1610
|
+
|
|
1611
|
+
// implementation for weighted == false
|
|
1612
|
+
template <>
|
|
1613
|
+
inline edgeweight Graph::getOutEdgeWeight<false>(node, index) const {
|
|
1614
|
+
return defaultEdgeWeight;
|
|
1615
|
+
}
|
|
1616
|
+
|
|
1617
|
+
// implementation for weighted == true
|
|
1618
|
+
template <bool hasWeights>
|
|
1619
|
+
inline edgeweight Graph::getInEdgeWeight([[maybe_unused]] node u, [[maybe_unused]] index i) const {
|
|
1620
|
+
// Base Graph class only supports CSR format
|
|
1621
|
+
throw std::runtime_error(
|
|
1622
|
+
"getInEdgeWeight not supported in base Graph class - use GraphW for mutable operations");
|
|
1623
|
+
}
|
|
1624
|
+
|
|
1625
|
+
// implementation for weighted == false
|
|
1626
|
+
template <>
|
|
1627
|
+
inline edgeweight Graph::getInEdgeWeight<false>(node, index) const {
|
|
1628
|
+
return defaultEdgeWeight;
|
|
1629
|
+
}
|
|
1630
|
+
|
|
1631
|
+
// implementation for hasEdgeIds == true
|
|
1632
|
+
template <bool graphHasEdgeIds>
|
|
1633
|
+
inline edgeid Graph::getOutEdgeId([[maybe_unused]] node u, [[maybe_unused]] index i) const {
|
|
1634
|
+
// Base Graph class only supports CSR format
|
|
1635
|
+
throw std::runtime_error(
|
|
1636
|
+
"getOutEdgeId not supported in base Graph class - use GraphW for mutable operations");
|
|
1637
|
+
}
|
|
1638
|
+
|
|
1639
|
+
// implementation for hasEdgeIds == false
|
|
1640
|
+
template <>
|
|
1641
|
+
inline edgeid Graph::getOutEdgeId<false>(node, index) const {
|
|
1642
|
+
return none;
|
|
1643
|
+
}
|
|
1644
|
+
|
|
1645
|
+
// implementation for hasEdgeIds == true
|
|
1646
|
+
template <bool graphHasEdgeIds>
|
|
1647
|
+
inline edgeid Graph::getInEdgeId([[maybe_unused]] node u, [[maybe_unused]] index i) const {
|
|
1648
|
+
// Base Graph class only supports CSR format
|
|
1649
|
+
throw std::runtime_error(
|
|
1650
|
+
"getInEdgeId not supported in base Graph class - use GraphW for mutable operations");
|
|
1651
|
+
}
|
|
1652
|
+
|
|
1653
|
+
// implementation for hasEdgeIds == false
|
|
1654
|
+
template <>
|
|
1655
|
+
inline edgeid Graph::getInEdgeId<false>(node, index) const {
|
|
1656
|
+
return none;
|
|
1657
|
+
}
|
|
1658
|
+
|
|
1659
|
+
// implementation for graphIsDirected == true
|
|
1660
|
+
template <bool graphIsDirected>
|
|
1661
|
+
inline bool Graph::useEdgeInIteration(node /* u */, node /* v */) const {
|
|
1662
|
+
return true;
|
|
1663
|
+
}
|
|
1664
|
+
|
|
1665
|
+
// implementation for graphIsDirected == false
|
|
1666
|
+
template <>
|
|
1667
|
+
inline bool Graph::useEdgeInIteration<false>(node u, node v) const {
|
|
1668
|
+
return u >= v;
|
|
1669
|
+
}
|
|
1670
|
+
|
|
1671
|
+
template <bool graphIsDirected, bool hasWeights, bool graphHasEdgeIds, typename L,
|
|
1672
|
+
bool applyUndirectedFilter>
|
|
1673
|
+
inline void Graph::forOutEdgesOfImpl(node u, L handle) const {
|
|
1674
|
+
if (usingCSR) {
|
|
1675
|
+
// CSR-based implementation
|
|
1676
|
+
auto [neighbors, degree] = getCSROutNeighbors(u);
|
|
1677
|
+
if (neighbors == nullptr || degree == 0)
|
|
1678
|
+
return;
|
|
1679
|
+
|
|
1680
|
+
for (count i = 0; i < degree; ++i) {
|
|
1681
|
+
node v = neighbors[i];
|
|
1682
|
+
|
|
1683
|
+
// Apply u>=v deduplication only for full-graph traversals, not forNeighborsOf.
|
|
1684
|
+
if constexpr (!graphIsDirected && applyUndirectedFilter) {
|
|
1685
|
+
if (!useEdgeInIteration<graphIsDirected>(u, v))
|
|
1686
|
+
continue;
|
|
1687
|
+
}
|
|
1688
|
+
|
|
1689
|
+
edgeweight weight = defaultEdgeWeight;
|
|
1690
|
+
edgeid eid = graphHasEdgeIds ? none : none;
|
|
1691
|
+
edgeLambda(handle, u, v, weight, eid);
|
|
1692
|
+
}
|
|
1693
|
+
} else {
|
|
1694
|
+
// Vector-based graphs should use GraphW
|
|
1695
|
+
// Check exists for mutable graphs
|
|
1696
|
+
if (!exists[u])
|
|
1697
|
+
return;
|
|
1698
|
+
throw std::runtime_error("forOutEdgesOfImpl not supported for vector-based graphs in base "
|
|
1699
|
+
"Graph class - use GraphW");
|
|
1700
|
+
}
|
|
1701
|
+
}
|
|
1702
|
+
|
|
1703
|
+
template <bool graphIsDirected, bool hasWeights, bool graphHasEdgeIds, typename L>
|
|
1704
|
+
inline void Graph::forInEdgesOfImpl(node u, L handle) const {
|
|
1705
|
+
if (usingCSR) {
|
|
1706
|
+
// Note: For immutable CSR graphs, all nodes exist so we skip exists check to avoid
|
|
1707
|
+
// thread-safety issues with std::vector<bool> in parallel contexts
|
|
1708
|
+
if constexpr (graphIsDirected) {
|
|
1709
|
+
// For directed graphs, use incoming edges
|
|
1710
|
+
auto [neighbors, degree] = getCSRInNeighbors(u);
|
|
1711
|
+
if (neighbors == nullptr || degree == 0)
|
|
1712
|
+
return;
|
|
1713
|
+
|
|
1714
|
+
for (count i = 0; i < degree; ++i) {
|
|
1715
|
+
node v = neighbors[i];
|
|
1716
|
+
// Skip exists[v] check for CSR graphs - all nodes always exist
|
|
1717
|
+
|
|
1718
|
+
// Get edge weight (currently CSR graphs are unweighted)
|
|
1719
|
+
edgeweight weight = hasWeights ? defaultEdgeWeight : defaultEdgeWeight;
|
|
1720
|
+
|
|
1721
|
+
// Get edge ID (CSR graphs don't currently support edge IDs)
|
|
1722
|
+
edgeid eid = graphHasEdgeIds ? none : none;
|
|
1723
|
+
|
|
1724
|
+
// For incoming edges: u is current node (target), v is neighbor (source)
|
|
1725
|
+
edgeLambda(handle, u, v, weight, eid);
|
|
1726
|
+
}
|
|
1727
|
+
} else {
|
|
1728
|
+
// For undirected graphs, incoming edges are the same as outgoing edges
|
|
1729
|
+
auto [neighbors, degree] = getCSROutNeighbors(u);
|
|
1730
|
+
if (neighbors == nullptr || degree == 0)
|
|
1731
|
+
return;
|
|
1732
|
+
|
|
1733
|
+
for (count i = 0; i < degree; ++i) {
|
|
1734
|
+
node v = neighbors[i];
|
|
1735
|
+
// Skip exists[v] check for CSR graphs - all nodes always exist
|
|
1736
|
+
|
|
1737
|
+
// Get edge weight (currently CSR graphs are unweighted)
|
|
1738
|
+
edgeweight weight = hasWeights ? defaultEdgeWeight : defaultEdgeWeight;
|
|
1739
|
+
|
|
1740
|
+
// Get edge ID (CSR graphs don't currently support edge IDs)
|
|
1741
|
+
edgeid eid = graphHasEdgeIds ? none : none;
|
|
1742
|
+
|
|
1743
|
+
// For undirected graphs, pass (u, v) where u is current node and v is neighbor
|
|
1744
|
+
edgeLambda(handle, u, v, weight, eid);
|
|
1745
|
+
}
|
|
1746
|
+
}
|
|
1747
|
+
} else {
|
|
1748
|
+
// For vector-based graphs (GraphW), use the virtual dispatch
|
|
1749
|
+
// Check exists for mutable graphs
|
|
1750
|
+
if (!exists[u])
|
|
1751
|
+
return;
|
|
1752
|
+
// GraphW's forInEdgesVirtualImpl calls handle(v, u, ...) where v is neighbor and u is
|
|
1753
|
+
// current node We need to swap so that edgeLambda receives (current, neighbor, ...) and
|
|
1754
|
+
// passes neighbor to f
|
|
1755
|
+
forInEdgesVirtualImpl(
|
|
1756
|
+
u, graphIsDirected, hasWeights, graphHasEdgeIds,
|
|
1757
|
+
[&](node v, node u, edgeweight w, edgeid e) { edgeLambda(handle, u, v, w, e); });
|
|
1758
|
+
}
|
|
1759
|
+
}
|
|
1760
|
+
|
|
1761
|
+
template <bool graphIsDirected, bool hasWeights, bool graphHasEdgeIds, typename L>
|
|
1762
|
+
inline void Graph::forEdgeImpl(L handle) const {
|
|
1763
|
+
if (usingCSR) {
|
|
1764
|
+
for (node u = 0; u < z; ++u) {
|
|
1765
|
+
forOutEdgesOfImpl<graphIsDirected, hasWeights, graphHasEdgeIds, L, true>(u, handle);
|
|
1766
|
+
}
|
|
1767
|
+
} else {
|
|
1768
|
+
// For vector-based graphs (GraphW), use the virtual dispatch
|
|
1769
|
+
forEdgesVirtualImpl(
|
|
1770
|
+
graphIsDirected, hasWeights, graphHasEdgeIds,
|
|
1771
|
+
[&](node u, node v, edgeweight w, edgeid e) { edgeLambda(handle, u, v, w, e); });
|
|
1772
|
+
}
|
|
1773
|
+
}
|
|
1774
|
+
|
|
1775
|
+
template <bool graphIsDirected, bool hasWeights, bool graphHasEdgeIds, typename L>
|
|
1776
|
+
inline void Graph::parallelForEdgesImpl(L handle) const {
|
|
1777
|
+
if (usingCSR) {
|
|
1778
|
+
#pragma omp parallel for schedule(guided)
|
|
1779
|
+
for (omp_index u = 0; u < static_cast<omp_index>(z); ++u) {
|
|
1780
|
+
forOutEdgesOfImpl<graphIsDirected, hasWeights, graphHasEdgeIds, L, true>(u, handle);
|
|
1781
|
+
}
|
|
1782
|
+
} else {
|
|
1783
|
+
// For vector-based graphs, use the virtual dispatch
|
|
1784
|
+
forEdgesVirtualImpl(
|
|
1785
|
+
graphIsDirected, hasWeights, graphHasEdgeIds,
|
|
1786
|
+
[&](node u, node v, edgeweight w, edgeid e) { edgeLambda(handle, u, v, w, e); });
|
|
1787
|
+
}
|
|
1788
|
+
}
|
|
1789
|
+
|
|
1790
|
+
template <bool graphIsDirected, bool hasWeights, bool graphHasEdgeIds, typename L>
|
|
1791
|
+
inline double Graph::parallelSumForEdgesImpl(L handle) const {
|
|
1792
|
+
double sum = 0.0;
|
|
1793
|
+
|
|
1794
|
+
if (usingCSR) {
|
|
1795
|
+
// CSR-based parallel implementation
|
|
1796
|
+
// Note: For immutable CSR graphs, all nodes exist so we skip exists check to avoid
|
|
1797
|
+
// thread-safety issues with std::vector<bool> in parallel contexts
|
|
1798
|
+
#pragma omp parallel for schedule(guided) reduction(+ : sum)
|
|
1799
|
+
for (omp_index u = 0; u < static_cast<omp_index>(z); ++u) {
|
|
1800
|
+
auto [neighbors, degree] = getCSROutNeighbors(u);
|
|
1801
|
+
if (neighbors == nullptr || degree == 0)
|
|
1802
|
+
continue;
|
|
1803
|
+
|
|
1804
|
+
for (count i = 0; i < degree; ++i) {
|
|
1805
|
+
node v = neighbors[i];
|
|
1806
|
+
// Skip exists[v] check for CSR graphs - all nodes always exist
|
|
1807
|
+
|
|
1808
|
+
// For undirected graphs, only process edge if u >= v to avoid duplicates
|
|
1809
|
+
if constexpr (!graphIsDirected) {
|
|
1810
|
+
if (!useEdgeInIteration<graphIsDirected>(u, v))
|
|
1811
|
+
continue;
|
|
1812
|
+
}
|
|
1813
|
+
|
|
1814
|
+
edgeweight w = hasWeights ? defaultEdgeWeight : defaultEdgeWeight;
|
|
1815
|
+
edgeid eid = graphHasEdgeIds ? none : none;
|
|
1816
|
+
|
|
1817
|
+
sum += edgeLambda(handle, u, v, w, eid);
|
|
1818
|
+
}
|
|
1819
|
+
}
|
|
1820
|
+
} else {
|
|
1821
|
+
// For vector-based graphs (GraphW), use the virtual dispatch
|
|
1822
|
+
auto wrapper = [&](node u, node v, edgeweight w, edgeid e) -> double {
|
|
1823
|
+
return edgeLambda(handle, u, v, w, e);
|
|
1824
|
+
};
|
|
1825
|
+
return parallelSumForEdgesVirtualImpl(graphIsDirected, hasWeights, graphHasEdgeIds,
|
|
1826
|
+
wrapper);
|
|
1827
|
+
}
|
|
1828
|
+
|
|
1829
|
+
return sum;
|
|
1830
|
+
}
|
|
1831
|
+
|
|
1832
|
+
template <typename L>
|
|
1833
|
+
void Graph::forEdges(L handle) const {
|
|
1834
|
+
switch (weighted + 2 * directed + 4 * edgesIndexed) {
|
|
1835
|
+
case 0: // unweighted, undirected, no edgeIds
|
|
1836
|
+
forEdgeImpl<false, false, false, L>(handle);
|
|
1837
|
+
break;
|
|
1838
|
+
|
|
1839
|
+
case 1: // weighted, undirected, no edgeIds
|
|
1840
|
+
forEdgeImpl<false, true, false, L>(handle);
|
|
1841
|
+
break;
|
|
1842
|
+
|
|
1843
|
+
case 2: // unweighted, directed, no edgeIds
|
|
1844
|
+
forEdgeImpl<true, false, false, L>(handle);
|
|
1845
|
+
break;
|
|
1846
|
+
|
|
1847
|
+
case 3: // weighted, directed, no edgeIds
|
|
1848
|
+
forEdgeImpl<true, true, false, L>(handle);
|
|
1849
|
+
break;
|
|
1850
|
+
|
|
1851
|
+
case 4: // unweighted, undirected, with edgeIds
|
|
1852
|
+
forEdgeImpl<false, false, true, L>(handle);
|
|
1853
|
+
break;
|
|
1854
|
+
|
|
1855
|
+
case 5: // weighted, undirected, with edgeIds
|
|
1856
|
+
forEdgeImpl<false, true, true, L>(handle);
|
|
1857
|
+
break;
|
|
1858
|
+
|
|
1859
|
+
case 6: // unweighted, directed, with edgeIds
|
|
1860
|
+
forEdgeImpl<true, false, true, L>(handle);
|
|
1861
|
+
break;
|
|
1862
|
+
|
|
1863
|
+
case 7: // weighted, directed, with edgeIds
|
|
1864
|
+
forEdgeImpl<true, true, true, L>(handle);
|
|
1865
|
+
break;
|
|
1866
|
+
}
|
|
1867
|
+
}
|
|
1868
|
+
|
|
1869
|
+
template <typename L>
|
|
1870
|
+
void Graph::parallelForEdges(L handle) const {
|
|
1871
|
+
switch (weighted + 2 * directed + 4 * edgesIndexed) {
|
|
1872
|
+
case 0: // unweighted, undirected, no edgeIds
|
|
1873
|
+
parallelForEdgesImpl<false, false, false, L>(handle);
|
|
1874
|
+
break;
|
|
1875
|
+
|
|
1876
|
+
case 1: // weighted, undirected, no edgeIds
|
|
1877
|
+
parallelForEdgesImpl<false, true, false, L>(handle);
|
|
1878
|
+
break;
|
|
1879
|
+
|
|
1880
|
+
case 2: // unweighted, directed, no edgeIds
|
|
1881
|
+
parallelForEdgesImpl<true, false, false, L>(handle);
|
|
1882
|
+
break;
|
|
1883
|
+
|
|
1884
|
+
case 3: // weighted, directed, no edgeIds
|
|
1885
|
+
parallelForEdgesImpl<true, true, false, L>(handle);
|
|
1886
|
+
break;
|
|
1887
|
+
|
|
1888
|
+
case 4: // unweighted, undirected, with edgeIds
|
|
1889
|
+
parallelForEdgesImpl<false, false, true, L>(handle);
|
|
1890
|
+
break;
|
|
1891
|
+
|
|
1892
|
+
case 5: // weighted, undirected, with edgeIds
|
|
1893
|
+
parallelForEdgesImpl<false, true, true, L>(handle);
|
|
1894
|
+
break;
|
|
1895
|
+
|
|
1896
|
+
case 6: // unweighted, directed, with edgeIds
|
|
1897
|
+
parallelForEdgesImpl<true, false, true, L>(handle);
|
|
1898
|
+
break;
|
|
1899
|
+
|
|
1900
|
+
case 7: // weighted, directed, with edgeIds
|
|
1901
|
+
parallelForEdgesImpl<true, true, true, L>(handle);
|
|
1902
|
+
break;
|
|
1903
|
+
}
|
|
1904
|
+
}
|
|
1905
|
+
|
|
1906
|
+
/* NEIGHBORHOOD ITERATORS */
|
|
1907
|
+
|
|
1908
|
+
template <typename L>
|
|
1909
|
+
void Graph::forNeighborsOf(node u, L handle) const {
|
|
1910
|
+
forEdgesOf(u, handle);
|
|
1911
|
+
}
|
|
1912
|
+
|
|
1913
|
+
template <typename L>
|
|
1914
|
+
void Graph::forEdgesOf(node u, L handle) const {
|
|
1915
|
+
if (usingCSR) {
|
|
1916
|
+
if (directed) {
|
|
1917
|
+
switch (weighted + 2 * edgesIndexed) {
|
|
1918
|
+
case 0: // not weighted, no edge ids
|
|
1919
|
+
forOutEdgesOfImpl<true, false, false, L>(u, handle);
|
|
1920
|
+
break;
|
|
1921
|
+
|
|
1922
|
+
case 1: // weighted, no edge ids
|
|
1923
|
+
forOutEdgesOfImpl<true, true, false, L>(u, handle);
|
|
1924
|
+
break;
|
|
1925
|
+
|
|
1926
|
+
case 2: // not weighted, with edge ids
|
|
1927
|
+
forOutEdgesOfImpl<true, false, true, L>(u, handle);
|
|
1928
|
+
break;
|
|
1929
|
+
|
|
1930
|
+
case 3: // weighted, with edge ids
|
|
1931
|
+
forOutEdgesOfImpl<true, true, true, L>(u, handle);
|
|
1932
|
+
break;
|
|
1933
|
+
}
|
|
1934
|
+
} else {
|
|
1935
|
+
switch (weighted + 2 * edgesIndexed) {
|
|
1936
|
+
case 0: // not weighted, no edge ids
|
|
1937
|
+
forOutEdgesOfImpl<false, false, false, L>(u, handle);
|
|
1938
|
+
break;
|
|
1939
|
+
|
|
1940
|
+
case 1: // weighted, no edge ids
|
|
1941
|
+
forOutEdgesOfImpl<false, true, false, L>(u, handle);
|
|
1942
|
+
break;
|
|
1943
|
+
|
|
1944
|
+
case 2: // not weighted, with edge ids
|
|
1945
|
+
forOutEdgesOfImpl<false, false, true, L>(u, handle);
|
|
1946
|
+
break;
|
|
1947
|
+
|
|
1948
|
+
case 3: // weighted, with edge ids
|
|
1949
|
+
forOutEdgesOfImpl<false, true, true, L>(u, handle);
|
|
1950
|
+
break;
|
|
1951
|
+
}
|
|
1952
|
+
}
|
|
1953
|
+
} else {
|
|
1954
|
+
// For vector-based graphs, use virtual dispatch
|
|
1955
|
+
forEdgesOfVirtualImpl(u, directed, weighted, edgesIndexed,
|
|
1956
|
+
[&](node uu, node vv, edgeweight ww, edgeid ee) {
|
|
1957
|
+
edgeLambda(handle, uu, vv, ww, ee);
|
|
1958
|
+
});
|
|
1959
|
+
}
|
|
1960
|
+
}
|
|
1961
|
+
|
|
1962
|
+
template <typename L>
|
|
1963
|
+
void Graph::forInNeighborsOf(node u, L handle) const {
|
|
1964
|
+
forInEdgesOf(u, handle);
|
|
1965
|
+
}
|
|
1966
|
+
|
|
1967
|
+
template <typename L>
|
|
1968
|
+
void Graph::forInEdgesOf(node u, L handle) const {
|
|
1969
|
+
switch (weighted + 2 * directed + 4 * edgesIndexed) {
|
|
1970
|
+
case 0: // unweighted, undirected, no edge ids
|
|
1971
|
+
forInEdgesOfImpl<false, false, false, L>(u, handle);
|
|
1972
|
+
break;
|
|
1973
|
+
|
|
1974
|
+
case 1: // weighted, undirected, no edge ids
|
|
1975
|
+
forInEdgesOfImpl<false, true, false, L>(u, handle);
|
|
1976
|
+
break;
|
|
1977
|
+
|
|
1978
|
+
case 2: // unweighted, directed, no edge ids
|
|
1979
|
+
forInEdgesOfImpl<true, false, false, L>(u, handle);
|
|
1980
|
+
break;
|
|
1981
|
+
|
|
1982
|
+
case 3: // weighted, directed, no edge ids
|
|
1983
|
+
forInEdgesOfImpl<true, true, false, L>(u, handle);
|
|
1984
|
+
break;
|
|
1985
|
+
|
|
1986
|
+
case 4: // unweighted, undirected, with edge ids
|
|
1987
|
+
forInEdgesOfImpl<false, false, true, L>(u, handle);
|
|
1988
|
+
break;
|
|
1989
|
+
|
|
1990
|
+
case 5: // weighted, undirected, with edge ids
|
|
1991
|
+
forInEdgesOfImpl<false, true, true, L>(u, handle);
|
|
1992
|
+
break;
|
|
1993
|
+
|
|
1994
|
+
case 6: // unweighted, directed, with edge ids
|
|
1995
|
+
forInEdgesOfImpl<true, false, true, L>(u, handle);
|
|
1996
|
+
break;
|
|
1997
|
+
|
|
1998
|
+
case 7: // weighted, directed, with edge ids
|
|
1999
|
+
forInEdgesOfImpl<true, true, true, L>(u, handle);
|
|
2000
|
+
break;
|
|
2001
|
+
}
|
|
2002
|
+
}
|
|
2003
|
+
|
|
2004
|
+
/* REDUCTION ITERATORS */
|
|
2005
|
+
|
|
2006
|
+
template <typename L>
|
|
2007
|
+
double Graph::parallelSumForNodes(L handle) const {
|
|
2008
|
+
double sum = 0.0;
|
|
2009
|
+
|
|
2010
|
+
if (usingCSR) {
|
|
2011
|
+
// For immutable CSR graphs, all nodes exist - skip exists check for thread safety
|
|
2012
|
+
#pragma omp parallel for reduction(+ : sum)
|
|
2013
|
+
for (omp_index v = 0; v < static_cast<omp_index>(z); ++v) {
|
|
2014
|
+
sum += handle(v);
|
|
2015
|
+
}
|
|
2016
|
+
} else {
|
|
2017
|
+
// For mutable graphs, check exists
|
|
2018
|
+
#pragma omp parallel for reduction(+ : sum)
|
|
2019
|
+
for (omp_index v = 0; v < static_cast<omp_index>(z); ++v) {
|
|
2020
|
+
if (exists[v]) {
|
|
2021
|
+
sum += handle(v);
|
|
2022
|
+
}
|
|
2023
|
+
}
|
|
2024
|
+
}
|
|
2025
|
+
|
|
2026
|
+
return sum;
|
|
2027
|
+
}
|
|
2028
|
+
|
|
2029
|
+
template <typename L>
|
|
2030
|
+
double Graph::parallelSumForEdges(L handle) const {
|
|
2031
|
+
double sum = 0.0;
|
|
2032
|
+
|
|
2033
|
+
switch (weighted + 2 * directed + 4 * edgesIndexed) {
|
|
2034
|
+
case 0: // unweighted, undirected, no edge ids
|
|
2035
|
+
sum = parallelSumForEdgesImpl<false, false, false, L>(handle);
|
|
2036
|
+
break;
|
|
2037
|
+
|
|
2038
|
+
case 1: // weighted, undirected, no edge ids
|
|
2039
|
+
sum = parallelSumForEdgesImpl<false, true, false, L>(handle);
|
|
2040
|
+
break;
|
|
2041
|
+
|
|
2042
|
+
case 2: // unweighted, directed, no edge ids
|
|
2043
|
+
sum = parallelSumForEdgesImpl<true, false, false, L>(handle);
|
|
2044
|
+
break;
|
|
2045
|
+
|
|
2046
|
+
case 3: // weighted, directed, no edge ids
|
|
2047
|
+
sum = parallelSumForEdgesImpl<true, true, false, L>(handle);
|
|
2048
|
+
break;
|
|
2049
|
+
|
|
2050
|
+
case 4: // unweighted, undirected, with edge ids
|
|
2051
|
+
sum = parallelSumForEdgesImpl<false, false, true, L>(handle);
|
|
2052
|
+
break;
|
|
2053
|
+
|
|
2054
|
+
case 5: // weighted, undirected, with edge ids
|
|
2055
|
+
sum = parallelSumForEdgesImpl<false, true, true, L>(handle);
|
|
2056
|
+
break;
|
|
2057
|
+
|
|
2058
|
+
case 6: // unweighted, directed, with edge ids
|
|
2059
|
+
sum = parallelSumForEdgesImpl<true, false, true, L>(handle);
|
|
2060
|
+
break;
|
|
2061
|
+
|
|
2062
|
+
case 7: // weighted, directed, with edge ids
|
|
2063
|
+
sum = parallelSumForEdgesImpl<true, true, true, L>(handle);
|
|
2064
|
+
break;
|
|
2065
|
+
}
|
|
2066
|
+
|
|
2067
|
+
return sum;
|
|
2068
|
+
}
|
|
2069
|
+
|
|
2070
|
+
/* EDGE MODIFIERS */
|
|
2071
|
+
|
|
2072
|
+
template <typename Condition>
|
|
2073
|
+
std::pair<count, count> Graph::removeAdjacentEdges([[maybe_unused]] node u,
|
|
2074
|
+
[[maybe_unused]] Condition condition,
|
|
2075
|
+
[[maybe_unused]] bool edgesIn) {
|
|
2076
|
+
// Base Graph class only supports CSR format and is immutable
|
|
2077
|
+
throw std::runtime_error("removeAdjacentEdges not supported in base Graph class - use GraphW "
|
|
2078
|
+
"for mutable operations");
|
|
2079
|
+
}
|
|
2080
|
+
|
|
2081
|
+
} /* namespace NetworKit */
|
|
2082
|
+
|
|
2083
|
+
#endif // NETWORKIT_GRAPH_GRAPH_HPP_
|