├── PCLDebug.props
├── PCLRelease.props
├── README.md
├── Teaser.cpp
├── Teaser.props
├── example_data
├── bunny
│ ├── bun000.pcd
│ └── bun090.pcd
└── kitti
│ ├── raw_000000.pcd
│ └── raw_001100.pcd
├── linux_lib
├── getopt.c
├── getopt.h
├── sys
│ └── time.h
└── unistd.h
├── pmc
├── LICENSE.md
├── Makefile
├── README.md
├── libpmc.h
├── libpmc_test.cpp
├── pmc.h
├── pmc.jl
├── pmc.m
├── pmc.py
├── pmc_clique_utils.cpp
├── pmc_cores.cpp
├── pmc_driver.cpp
├── pmc_graph.cpp
├── pmc_graph.h
├── pmc_headers.h
├── pmc_heu.cpp
├── pmc_heu.h
├── pmc_input.h
├── pmc_lib.cpp
├── pmc_maxclique.cpp
├── pmc_maxclique.h
├── pmc_neigh_coloring.h
├── pmc_neigh_cores.h
├── pmc_utils.cpp
├── pmc_utils.h
├── pmc_vertex.h
├── pmcx_maxclique.cpp
├── pmcx_maxclique.h
├── pmcx_maxclique_basic.cpp
└── pmcx_maxclique_basic.h
├── reg
├── RegBase.h
├── TRO_Utilities.h
└── stdafx.h
├── teaser
├── CMakeLists.txt
├── include
│ └── teaser
│ │ ├── CTeaser.h
│ │ ├── no_use
│ │ └── ply_io.h
│ │ ├── teaser_fpfh.h
│ │ ├── teaser_geometry.h
│ │ ├── teaser_graph.h
│ │ ├── teaser_macros.h
│ │ ├── teaser_matcher.h
│ │ ├── teaser_registration.h
│ │ ├── teaser_utility.h
│ │ └── teaser_utils.h
└── src
│ ├── no_use
│ ├── ply_io.cc
│ └── teaser_fpfh.cc
│ ├── teaser_graph.cc
│ ├── teaser_matcher.cc
│ └── teaser_registration.cc
└── visResult.m
/PCLDebug.props:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | D:\Program Files\PCL 1.8.1\include\pcl-1.8;D:\Program Files\PCL 1.8.1\3rdParty\Boost\include\boost-1_64;D:\Program Files\PCL 1.8.1\3rdParty\Qhull\include;D:\Program Files\PCL 1.8.1\3rdParty\FLANN\include;D:\Program Files\PCL 1.8.1\3rdParty\Eigen\eigen3;D:\Program Files\PCL 1.8.1\3rdParty\VTK\include\vtk-8.0;D:\Program Files\OpenNI2\Include;$(IncludePath)
7 | D:\Program Files\PCL 1.8.1\3rdParty\VTK\lib;D:\Program Files\PCL 1.8.1\3rdParty\FLANN\lib;D:\Program Files\PCL 1.8.1\3rdParty\Qhull\lib;D:\Program Files\PCL 1.8.1\3rdParty\Boost\lib;D:\Program Files\OpenNI2\Lib;D:\Program Files\PCL 1.8.1\lib;$(LibraryPath)
8 |
9 |
10 |
11 | pcl_common_debug.lib;pcl_features_debug.lib;pcl_filters_debug.lib;pcl_io_debug.lib;pcl_io_ply_debug.lib;pcl_kdtree_debug.lib;pcl_keypoints_debug.lib;pcl_ml_debug.lib;pcl_octree_debug.lib;pcl_outofcore_debug.lib;pcl_people_debug.lib;pcl_recognition_debug.lib;pcl_registration_debug.lib;pcl_sample_consensus_debug.lib;pcl_search_debug.lib;pcl_segmentation_debug.lib;pcl_stereo_debug.lib;pcl_surface_debug.lib;pcl_tracking_debug.lib;pcl_visualization_debug.lib;flann_cpp_s-gd.lib;flann_s-gd.lib;flann-gd.lib;libboost_atomic-vc140-mt-gd-1_64.lib;libboost_chrono-vc140-mt-gd-1_64.lib;libboost_container-vc140-mt-gd-1_64.lib;libboost_context-vc140-mt-gd-1_64.lib;libboost_coroutine-vc140-mt-gd-1_64.lib;libboost_date_time-vc140-mt-gd-1_64.lib;libboost_exception-vc140-mt-gd-1_64.lib;libboost_filesystem-vc140-mt-gd-1_64.lib;libboost_graph-vc140-mt-gd-1_64.lib;libboost_iostreams-vc140-mt-gd-1_64.lib;libboost_locale-vc140-mt-gd-1_64.lib;libboost_log-vc140-mt-gd-1_64.lib;libboost_log_setup-vc140-mt-gd-1_64.lib;libboost_math_c99-vc140-mt-gd-1_64.lib;libboost_math_c99f-vc140-mt-gd-1_64.lib;libboost_math_c99l-vc140-mt-gd-1_64.lib;libboost_math_tr1-vc140-mt-gd-1_64.lib;libboost_math_tr1f-vc140-mt-gd-1_64.lib;libboost_math_tr1l-vc140-mt-gd-1_64.lib;libboost_mpi-vc140-mt-gd-1_64.lib;libboost_prg_exec_monitor-vc140-mt-gd-1_64.lib;libboost_program_options-vc140-mt-gd-1_64.lib;libboost_random-vc140-mt-gd-1_64.lib;libboost_regex-vc140-mt-gd-1_64.lib;libboost_serialization-vc140-mt-gd-1_64.lib;libboost_signals-vc140-mt-gd-1_64.lib;libboost_system-vc140-mt-gd-1_64.lib;libboost_test_exec_monitor-vc140-mt-gd-1_64.lib;libboost_thread-vc140-mt-gd-1_64.lib;libboost_timer-vc140-mt-gd-1_64.lib;libboost_unit_test_framework-vc140-mt-gd-1_64.lib;libboost_wave-vc140-mt-gd-1_64.lib;libboost_wserialization-vc140-mt-gd-1_64.lib;qhull_d.lib;qhull_p_d.lib;qhull_r_d.lib;qhullcpp_d.lib;qhullstatic_d.lib;qhullstatic_r_d.lib;vtkalglib-8.0-gd.lib;vtkChartsCore-8.0-gd.lib;vtkCommonColor-8.0-gd.lib;vtkCommonComputationalGeometry-8.0-gd.lib;vtkCommonCore-8.0-gd.lib;vtkCommonDataModel-8.0-gd.lib;vtkCommonExecutionModel-8.0-gd.lib;vtkCommonMath-8.0-gd.lib;vtkCommonMisc-8.0-gd.lib;vtkCommonSystem-8.0-gd.lib;vtkCommonTransforms-8.0-gd.lib;vtkDICOMParser-8.0-gd.lib;vtkDomainsChemistry-8.0-gd.lib;vtkexoIIc-8.0-gd.lib;vtkexpat-8.0-gd.lib;vtkFiltersAMR-8.0-gd.lib;vtkFiltersCore-8.0-gd.lib;vtkFiltersExtraction-8.0-gd.lib;vtkFiltersFlowPaths-8.0-gd.lib;vtkFiltersGeneral-8.0-gd.lib;vtkFiltersGeneric-8.0-gd.lib;vtkFiltersGeometry-8.0-gd.lib;vtkFiltersHybrid-8.0-gd.lib;vtkFiltersHyperTree-8.0-gd.lib;vtkFiltersImaging-8.0-gd.lib;vtkFiltersModeling-8.0-gd.lib;vtkFiltersParallel-8.0-gd.lib;vtkFiltersParallelImaging-8.0-gd.lib;vtkFiltersProgrammable-8.0-gd.lib;vtkFiltersSelection-8.0-gd.lib;vtkFiltersSMP-8.0-gd.lib;vtkFiltersSources-8.0-gd.lib;vtkFiltersStatistics-8.0-gd.lib;vtkFiltersTexture-8.0-gd.lib;vtkFiltersVerdict-8.0-gd.lib;vtkfreetype-8.0-gd.lib;vtkGeovisCore-8.0-gd.lib;vtkhdf5-8.0-gd.lib;vtkhdf5_hl-8.0-gd.lib;vtkImagingColor-8.0-gd.lib;vtkImagingCore-8.0-gd.lib;vtkImagingFourier-8.0-gd.lib;vtkImagingGeneral-8.0-gd.lib;vtkImagingHybrid-8.0-gd.lib;vtkImagingMath-8.0-gd.lib;vtkImagingMorphological-8.0-gd.lib;vtkImagingSources-8.0-gd.lib;vtkImagingStatistics-8.0-gd.lib;vtkImagingStencil-8.0-gd.lib;vtkInfovisCore-8.0-gd.lib;vtkInfovisLayout-8.0-gd.lib;vtkInteractionImage-8.0-gd.lib;vtkInteractionStyle-8.0-gd.lib;vtkInteractionWidgets-8.0-gd.lib;vtkIOAMR-8.0-gd.lib;vtkIOCore-8.0-gd.lib;vtkIOEnSight-8.0-gd.lib;vtkIOExodus-8.0-gd.lib;vtkIOExport-8.0-gd.lib;vtkIOGeometry-8.0-gd.lib;vtkIOImage-8.0-gd.lib;vtkIOImport-8.0-gd.lib;vtkIOInfovis-8.0-gd.lib;vtkIOLegacy-8.0-gd.lib;vtkIOLSDyna-8.0-gd.lib;vtkIOMINC-8.0-gd.lib;vtkIOMovie-8.0-gd.lib;vtkIONetCDF-8.0-gd.lib;vtkIOParallel-8.0-gd.lib;vtkIOPLY-8.0-gd.lib;vtkIOSQL-8.0-gd.lib;vtkIOVideo-8.0-gd.lib;vtkIOXML-8.0-gd.lib;vtkIOXMLParser-8.0-gd.lib;vtkjpeg-8.0-gd.lib;vtkjsoncpp-8.0-gd.lib;vtklibxml2-8.0-gd.lib;vtkmetaio-8.0-gd.lib;vtkNetCDF-8.0-gd.lib;vtknetcdf_c++-gd.lib;vtkoggtheora-8.0-gd.lib;vtkParallelCore-8.0-gd.lib;vtkpng-8.0-gd.lib;vtkproj4-8.0-gd.lib;vtkRenderingAnnotation-8.0-gd.lib;vtkRenderingContext2D-8.0-gd.lib;vtkRenderingCore-8.0-gd.lib;vtkRenderingFreeType-8.0-gd.lib;vtkRenderingImage-8.0-gd.lib;vtkRenderingLabel-8.0-gd.lib;vtkRenderingLOD-8.0-gd.lib;vtkRenderingVolume-8.0-gd.lib;vtksqlite-8.0-gd.lib;vtksys-8.0-gd.lib;vtktiff-8.0-gd.lib;vtkverdict-8.0-gd.lib;vtkViewsContext2D-8.0-gd.lib;vtkViewsCore-8.0-gd.lib;vtkViewsInfovis-8.0-gd.lib;vtkzlib-8.0-gd.lib;OpenNI2.lib;%(AdditionalDependencies)
12 |
13 |
14 | false
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/PCLRelease.props:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | D:\Program Files\PCL 1.8.1\include\pcl-1.8;D:\Program Files\PCL 1.8.1\3rdParty\Boost\include\boost-1_64;D:\Program Files\PCL 1.8.1\3rdParty\Qhull\include;D:\Program Files\PCL 1.8.1\3rdParty\FLANN\include;D:\Program Files\PCL 1.8.1\3rdParty\Eigen\eigen3;D:\Program Files\PCL 1.8.1\3rdParty\VTK\include\vtk-8.0;D:\Program Files\OpenNI2\Include;$(IncludePath)
7 | D:\Program Files\PCL 1.8.1\3rdParty\VTK\lib;D:\Program Files\PCL 1.8.1\3rdParty\FLANN\lib;D:\Program Files\PCL 1.8.1\3rdParty\Qhull\lib;D:\Program Files\PCL 1.8.1\3rdParty\Boost\lib;D:\Program Files\OpenNI2\Lib;D:\Program Files\PCL 1.8.1\lib;$(LibraryPath)
8 |
9 |
10 |
11 | pcl_common_release.lib;pcl_features_release.lib;pcl_filters_release.lib;pcl_io_release.lib;pcl_io_ply_release.lib;pcl_kdtree_release.lib;pcl_keypoints_release.lib;pcl_ml_release.lib;pcl_octree_release.lib;pcl_outofcore_release.lib;pcl_people_release.lib;pcl_recognition_release.lib;pcl_registration_release.lib;pcl_sample_consensus_release.lib;pcl_search_release.lib;pcl_segmentation_release.lib;pcl_stereo_release.lib;pcl_surface_release.lib;pcl_tracking_release.lib;pcl_visualization_release.lib;flann_cpp_s.lib;flann_s.lib;flann.lib;libboost_atomic-vc140-mt-1_64.lib;libboost_chrono-vc140-mt-1_64.lib;libboost_container-vc140-mt-1_64.lib;libboost_context-vc140-mt-1_64.lib;libboost_coroutine-vc140-mt-1_64.lib;libboost_date_time-vc140-mt-1_64.lib;libboost_exception-vc140-mt-1_64.lib;libboost_filesystem-vc140-mt-1_64.lib;libboost_graph-vc140-mt-1_64.lib;libboost_iostreams-vc140-mt-1_64.lib;libboost_locale-vc140-mt-1_64.lib;libboost_log-vc140-mt-1_64.lib;libboost_log_setup-vc140-mt-1_64.lib;libboost_math_c99-vc140-mt-1_64.lib;libboost_math_c99f-vc140-mt-1_64.lib;libboost_math_c99l-vc140-mt-1_64.lib;libboost_math_tr1-vc140-mt-1_64.lib;libboost_math_tr1f-vc140-mt-1_64.lib;libboost_math_tr1l-vc140-mt-1_64.lib;libboost_mpi-vc140-mt-1_64.lib;libboost_prg_exec_monitor-vc140-mt-1_64.lib;libboost_program_options-vc140-mt-1_64.lib;libboost_random-vc140-mt-1_64.lib;libboost_regex-vc140-mt-1_64.lib;libboost_serialization-vc140-mt-1_64.lib;libboost_signals-vc140-mt-1_64.lib;libboost_system-vc140-mt-1_64.lib;libboost_test_exec_monitor-vc140-mt-1_64.lib;libboost_thread-vc140-mt-1_64.lib;libboost_timer-vc140-mt-1_64.lib;libboost_unit_test_framework-vc140-mt-1_64.lib;libboost_wave-vc140-mt-1_64.lib;libboost_wserialization-vc140-mt-1_64.lib;qhullstatic.lib;qhull.lib;qhull_p.lib;qhull_r.lib;qhullcpp.lib;qhullstatic_r.lib;vtkalglib-8.0.lib;vtkChartsCore-8.0.lib;vtkCommonColor-8.0.lib;vtkCommonComputationalGeometry-8.0.lib;vtkCommonCore-8.0.lib;vtkCommonDataModel-8.0.lib;vtkCommonExecutionModel-8.0.lib;vtkCommonMath-8.0.lib;vtkCommonMisc-8.0.lib;vtkCommonSystem-8.0.lib;vtkCommonTransforms-8.0.lib;vtkDICOMParser-8.0.lib;vtkDomainsChemistry-8.0.lib;vtkexoIIc-8.0.lib;vtkexpat-8.0.lib;vtkFiltersAMR-8.0.lib;vtkFiltersCore-8.0.lib;vtkFiltersExtraction-8.0.lib;vtkFiltersFlowPaths-8.0.lib;vtkFiltersGeneral-8.0.lib;vtkFiltersGeneric-8.0.lib;vtkFiltersGeometry-8.0.lib;vtkFiltersHybrid-8.0.lib;vtkFiltersHyperTree-8.0.lib;vtkFiltersImaging-8.0.lib;vtkFiltersModeling-8.0.lib;vtkFiltersParallel-8.0.lib;vtkFiltersParallelImaging-8.0.lib;vtkFiltersProgrammable-8.0.lib;vtkFiltersSelection-8.0.lib;vtkFiltersSMP-8.0.lib;vtkFiltersSources-8.0.lib;vtkFiltersStatistics-8.0.lib;vtkFiltersTexture-8.0.lib;vtkFiltersVerdict-8.0.lib;vtkfreetype-8.0.lib;vtkGeovisCore-8.0.lib;vtkhdf5-8.0.lib;vtkhdf5_hl-8.0.lib;vtkImagingColor-8.0.lib;vtkImagingCore-8.0.lib;vtkImagingFourier-8.0.lib;vtkImagingGeneral-8.0.lib;vtkImagingHybrid-8.0.lib;vtkImagingMath-8.0.lib;vtkImagingMorphological-8.0.lib;vtkImagingSources-8.0.lib;vtkImagingStatistics-8.0.lib;vtkImagingStencil-8.0.lib;vtkInfovisCore-8.0.lib;vtkInfovisLayout-8.0.lib;vtkInteractionImage-8.0.lib;vtkInteractionStyle-8.0.lib;vtkInteractionWidgets-8.0.lib;vtkIOAMR-8.0.lib;vtkIOCore-8.0.lib;vtkIOEnSight-8.0.lib;vtkIOExodus-8.0.lib;vtkIOExport-8.0.lib;vtkIOGeometry-8.0.lib;vtkIOImage-8.0.lib;vtkIOImport-8.0.lib;vtkIOInfovis-8.0.lib;vtkIOLegacy-8.0.lib;vtkIOLSDyna-8.0.lib;vtkIOMINC-8.0.lib;vtkIOMovie-8.0.lib;vtkIONetCDF-8.0.lib;vtkIOParallel-8.0.lib;vtkIOPLY-8.0.lib;vtkIOSQL-8.0.lib;vtkIOVideo-8.0.lib;vtkIOXML-8.0.lib;vtkIOXMLParser-8.0.lib;vtkjpeg-8.0.lib;vtkjsoncpp-8.0.lib;vtklibxml2-8.0.lib;vtkmetaio-8.0.lib;vtkNetCDF-8.0.lib;vtknetcdf_c++.lib;vtkoggtheora-8.0.lib;vtkParallelCore-8.0.lib;vtkpng-8.0.lib;vtkproj4-8.0.lib;vtkRenderingAnnotation-8.0.lib;vtkRenderingContext2D-8.0.lib;vtkRenderingCore-8.0.lib;vtkRenderingFreeType-8.0.lib;vtkRenderingImage-8.0.lib;vtkRenderingLabel-8.0.lib;vtkRenderingLOD-8.0.lib;vtkRenderingVolume-8.0.lib;vtksqlite-8.0.lib;vtksys-8.0.lib;vtktiff-8.0.lib;vtkverdict-8.0.lib;vtkViewsContext2D-8.0.lib;vtkViewsCore-8.0.lib;vtkViewsInfovis-8.0.lib;vtkzlib-8.0.lib;OpenNI2.lib;%(AdditionalDependencies)
12 |
13 |
14 | false
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # WinTeaser
2 | Teaser++[1] is a well-performed point cloud registration algorithm which can be used in computer vision and robotics. However, the original Teaser++ operates in Linux (https://github.com/MIT-SPARK/TEASER-plusplus). This reporsitory configures Teaser++ in Windows with the help of Visual Studio 2015. The linux_lib contains , , and which not exist in Windows OS. If you want to explore more linux libaries, please check https://github.com/robinrowe/libunistd.
3 |
4 | The main procedures are as follows:
5 |
6 | 1. Install PCL-all-in-one-installer_1.8.1.
7 |
8 | 2. Configure PCLRelease/PCLDebug.props and Teaser.props in VS 2015.
9 |
10 | 3. Compile the whole project. The main() lies in Teaser.cpp.
11 |
12 | 4. run visResult.m using MATLAB to see the quality of registration.
13 |
14 | Enjoy it!
15 |
16 | PS: One of the major difference between WinTeaser and Teaser++ lies in the way of computing the FPFH descriptors. Teaser++ computes one FPFH descriptor for each point in point cloud. which is quite computationally inefficiency. Therefore in WinTeaser, the raw cloud is firstly subsampled into cloud_key_points, which is sparse than original cloud. Subsequently, FPFH descriptor is computed for each point in cloud_key_point. Notice that when computing FPFH, the input surface of FPFH_Estimator is still cloud instead of sub-sampled cloud_key_point, which ensures the accuracy of FPFH descriptor has no difference with Teaser++. The modified FPFH computation is in teaser/include/teaser_fpfh.h.
17 |
18 | PPS: There are some other issues worthy to be mentioned. Firstly, the pmc library seems to be wrong when the number of point pairs is too large. This is because pmc uses omp library. If you meet this issue, just use ordinary for loop instead of omp for loop. Secondly, the running time of teaser can be hours since the maximum clique searching in pmc library. To save the time, you can change the configuration of Teaser. There is a maximum pmc search time
19 | in the constructor of Teaser. Both of the above issues may be occurred when the number of input point pairs is large (I think it is around 10000). Therefore, you can enlarge the feature_radius to reduce the point pair number.
20 |
21 | Disclaimer: I strongly recommend to use the original TEASER++ in Linux since it is well maintained and has detailed document. WinTeaser is mainly used for users which are unfamilar with Linux OS and want to quickly test TEASER++ on their own dataset.
22 |
23 | [1] Yang, H., Shi, J., & Carlone, L. (2020). TEASER: Fast and Certifiable Point Cloud Registration. IEEE Transactions on Robotics.
24 |
--------------------------------------------------------------------------------
/Teaser.cpp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DrGabor/WinTeaser/2b216e86b7286de678722a2d1ca75b2fbd194deb/Teaser.cpp
--------------------------------------------------------------------------------
/Teaser.props:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | D:\Projects\TEASER-plusplus\teaser\include;D:\Projects\TEASER-plusplus\teaser\src;D:\Projects\TEASER-plusplus;D:\Projects\TEASER-plusplus\wingetopt\src;$(IncludePath)
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/example_data/bunny/bun000.pcd:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DrGabor/WinTeaser/2b216e86b7286de678722a2d1ca75b2fbd194deb/example_data/bunny/bun000.pcd
--------------------------------------------------------------------------------
/example_data/bunny/bun090.pcd:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DrGabor/WinTeaser/2b216e86b7286de678722a2d1ca75b2fbd194deb/example_data/bunny/bun090.pcd
--------------------------------------------------------------------------------
/example_data/kitti/raw_000000.pcd:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DrGabor/WinTeaser/2b216e86b7286de678722a2d1ca75b2fbd194deb/example_data/kitti/raw_000000.pcd
--------------------------------------------------------------------------------
/example_data/kitti/raw_001100.pcd:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DrGabor/WinTeaser/2b216e86b7286de678722a2d1ca75b2fbd194deb/example_data/kitti/raw_001100.pcd
--------------------------------------------------------------------------------
/linux_lib/getopt.h:
--------------------------------------------------------------------------------
1 | #ifndef __GETOPT_H__
2 | /**
3 | * DISCLAIMER
4 | * This file has no copyright assigned and is placed in the Public Domain.
5 | * This file is a part of the w64 mingw-runtime package.
6 | *
7 | * The w64 mingw-runtime package and its code is distributed in the hope that it
8 | * will be useful but WITHOUT ANY WARRANTY. ALL WARRANTIES, EXPRESSED OR
9 | * IMPLIED ARE HEREBY DISCLAIMED. This includes but is not limited to
10 | * warranties of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
11 | */
12 |
13 | #define __GETOPT_H__
14 |
15 | /* All the headers include this file. */
16 | #include
17 |
18 | #if defined( WINGETOPT_SHARED_LIB )
19 | # if defined( BUILDING_WINGETOPT_DLL )
20 | # define WINGETOPT_API __declspec(dllexport)
21 | # else
22 | # define WINGETOPT_API __declspec(dllimport)
23 | # endif
24 | #else
25 | # define WINGETOPT_API
26 | #endif
27 |
28 | #ifdef __cplusplus
29 | extern "C" {
30 | #endif
31 |
32 | WINGETOPT_API extern int optind; /* index of first non-option in argv */
33 | WINGETOPT_API extern int optopt; /* single option character, as parsed */
34 | WINGETOPT_API extern int opterr; /* flag to enable built-in diagnostics... */
35 | /* (user may set to zero, to suppress) */
36 |
37 | WINGETOPT_API extern char *optarg; /* pointer to argument of current option */
38 |
39 | extern int getopt(int nargc, char * const *nargv, const char *options);
40 |
41 | #ifdef _BSD_SOURCE
42 | /*
43 | * BSD adds the non-standard `optreset' feature, for reinitialisation
44 | * of `getopt' parsing. We support this feature, for applications which
45 | * proclaim their BSD heritage, before including this header; however,
46 | * to maintain portability, developers are advised to avoid it.
47 | */
48 | # define optreset __mingw_optreset
49 | extern int optreset;
50 | #endif
51 | #ifdef __cplusplus
52 | }
53 | #endif
54 | /*
55 | * POSIX requires the `getopt' API to be specified in `unistd.h';
56 | * thus, `unistd.h' includes this header. However, we do not want
57 | * to expose the `getopt_long' or `getopt_long_only' APIs, when
58 | * included in this manner. Thus, close the standard __GETOPT_H__
59 | * declarations block, and open an additional __GETOPT_LONG_H__
60 | * specific block, only when *not* __UNISTD_H_SOURCED__, in which
61 | * to declare the extended API.
62 | */
63 | #endif /* !defined(__GETOPT_H__) */
64 |
65 | #if !defined(__UNISTD_H_SOURCED__) && !defined(__GETOPT_LONG_H__)
66 | #define __GETOPT_LONG_H__
67 |
68 | #ifdef __cplusplus
69 | extern "C" {
70 | #endif
71 |
72 | struct option /* specification for a long form option... */
73 | {
74 | const char *name; /* option name, without leading hyphens */
75 | int has_arg; /* does it take an argument? */
76 | int *flag; /* where to save its status, or NULL */
77 | int val; /* its associated status value */
78 | };
79 |
80 | enum /* permitted values for its `has_arg' field... */
81 | {
82 | no_argument = 0, /* option never takes an argument */
83 | required_argument, /* option always requires an argument */
84 | optional_argument /* option may take an argument */
85 | };
86 |
87 | extern int getopt_long(int nargc, char * const *nargv, const char *options,
88 | const struct option *long_options, int *idx);
89 | extern int getopt_long_only(int nargc, char * const *nargv, const char *options,
90 | const struct option *long_options, int *idx);
91 | /*
92 | * Previous MinGW implementation had...
93 | */
94 | #ifndef HAVE_DECL_GETOPT
95 | /*
96 | * ...for the long form API only; keep this for compatibility.
97 | */
98 | # define HAVE_DECL_GETOPT 1
99 | #endif
100 |
101 | #ifdef __cplusplus
102 | }
103 | #endif
104 |
105 | #endif /* !defined(__UNISTD_H_SOURCED__) && !defined(__GETOPT_LONG_H__) */
106 |
--------------------------------------------------------------------------------
/linux_lib/sys/time.h:
--------------------------------------------------------------------------------
1 | #include
--------------------------------------------------------------------------------
/linux_lib/unistd.h:
--------------------------------------------------------------------------------
1 | #ifndef _UNISTD_H
2 | #define _UNISTD_H
3 | #include
4 | #include
5 |
6 | #endif
--------------------------------------------------------------------------------
/pmc/LICENSE.md:
--------------------------------------------------------------------------------
1 | License
2 | -------
3 | **Parallel Maximum Clique (PMC) Library**,
4 | Copyright (C) 2012-2013: Ryan A. Rossi, All rights reserved.
5 |
6 | >This program is free software: you can redistribute it and/or modify
7 | it under the terms of the GNU General Public License as published by
8 | the Free Software Foundation, either version 3 of the License, or
9 | (at your option) any later version.
10 |
11 | >This program is distributed in the hope that it will be useful,
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | GNU General Public License for more details.
15 |
16 | >You should have received a copy of the GNU General Public License
17 | along with this program. If not, see .
18 |
19 | If used, please cite the following manuscript:
20 |
21 | Ryan A. Rossi, David F. Gleich, Assefaw H. Gebremedhin, Md. Mostofa
22 | Patwary, A Fast Parallel Maximum Clique Algorithm for Large Sparse Graphs
23 | and Temporal Strong Components, arXiv 2013
24 |
--------------------------------------------------------------------------------
/pmc/Makefile:
--------------------------------------------------------------------------------
1 | #
2 | # Makefile for PMC
3 | #
4 | # Ryan A. Rossi
5 | # Copyright, 2012-2016
6 | #
7 |
8 | .KEEP_STATE:
9 |
10 | all: pmc
11 |
12 | #OPTFLAGS = -g -D _GLIBCXX_DEBUG
13 | OPTFLAGS = -O3
14 | CFLAGS = $(OPTFLAGS) -fPIC
15 | #CFLAGS += -D_GLIBCXX_PARALLEL
16 | #CFLAGS += -floop-parallelize-all -ftree-loop-distribution
17 |
18 |
19 | CXX = g++
20 | H_FILES = pmc.h
21 |
22 |
23 | .cpp.o:
24 | $(CXX) $(CFLAGS) -c $<
25 |
26 | IO_SRC = pmc_utils.cpp \
27 | pmc_graph.cpp \
28 | pmc_clique_utils.cpp
29 |
30 | PMC_SRC = pmc_heu.cpp \
31 | pmc_maxclique.cpp \
32 | pmcx_maxclique.cpp \
33 | pmcx_maxclique_basic.cpp
34 |
35 | BOUND_LIB_SRC = pmc_cores.cpp
36 |
37 | PMC_MAIN = pmc_driver.cpp
38 |
39 | OBJ_PMC = $(PMC_MAIN:%.cpp=%.o) $(IO_SRC) $(PMC_SRC) $(BOUND_LIB_SRC)
40 | $(OBJ_PMC): $(H_FILES) Makefile
41 | pmc: $(OBJ_PMC) $(H_FILES)
42 | $(CXX) $(CFLAGS) -o pmc $(OBJ_PMC) -fopenmp
43 |
44 | libpmc.so: $(IO_SRC) $(PMC_SRC) $(BOUND_LIB_SRC) $(H_FILES) pmc_lib.cpp
45 | $(CXX) -static-libstdc++ $(CFLAGS) -shared -o libpmc.so \
46 | $(IO_SRC) $(PMC_SRC) $(BOUND_LIB_SRC) pmc_lib.cpp -fopenmp
47 |
48 | libpmc_test: libpmc.so libpmc_test.cpp
49 | $(CXX) libpmc_test.cpp ./libpmc.so -o libpmc_test
50 | ./libpmc_test
51 |
52 | clean:
53 | rm -rf *.o pmc libpmc.so
54 |
--------------------------------------------------------------------------------
/pmc/README.md:
--------------------------------------------------------------------------------
1 | Parallel Maximum Clique (PMC) Library
2 | =====================================
3 |
4 | In short, a parameterized high performance library for computing maximum cliques in large sparse graphs.
5 |
6 | Finding maximum cliques, k-cliques, and temporal strong components are in general NP-hard.
7 | Yet, these can be computed fast in most social and information networks.
8 | The PMC library is designed to be fast for solving these problems.
9 | Algorithms in the PMC library are easily adaptable for use with a variety of orderings, heuristic strategies, and bounds.
10 |
11 | * **Maximum clique:** Given a simple undirected graph G and a number k, output the clique of largest size.
12 | * **K-clique:** In k-clique, the problem is to find a clique of size k if one exists.
13 | * **Largest temporal-scc:** Given a temporal graph G, a temporal strong component is a set of vertices where all temporal paths exist between the vertices in that set. The Largest TSCC problem is to find the largest among all the temporal strong components.
14 |
15 |
16 |
17 | Features
18 | --------
19 | 0. General framework for parallel maximum clique algorithms
20 | 1. Optimized to be fast for large sparse graphs
21 | + Algorithms tested on networks of 1.8 billion edges
22 | 2. Set of fast heuristics shown to give accurate approximations
23 | 3. Algorithms for computing Temporal Strongly Connected Components (TSCC) of large dynamic networks
24 | 4. Parameterized for computing k-cliques as fast as possible
25 | 5. Includes a variety of tight linear time bounds for the maximum clique problem
26 | 6. Ordering of vertices for each algorithm can be selected at runtime
27 | 7. Dynamically reduces the graph representation periodically as vertices are pruned or searched
28 | + Lowers memory-requirements for massive graphs, increases speed, and has caching benefits
29 |
30 |
31 | Synopsis
32 | ---------
33 |
34 | ### Setup
35 | First, you'll need to compile the parallel maximum clique library.
36 |
37 | $ cd path/to/pmc/
38 | $ make
39 |
40 | Afterwards, the following should work:
41 |
42 | # compute maximum clique using the full algorithm `-a 0`
43 | ./pmc -f data/socfb-Texas84.mtx -a 0
44 |
45 |
46 | *PMC* has been tested on Ubuntu linux (10.10 tested) and Mac OSX (Lion tested) with gcc-mp-4.7 and gcc-mp-4.5.4
47 |
48 | Please let me know if you run into any issues.
49 |
50 |
51 |
52 | ### Input file format
53 | + Matrix Market Coordinate Format (symmetric)
54 | For details see:
55 |
56 | %%MatrixMarket matrix coordinate pattern symmetric
57 | 4 4 6
58 | 2 1
59 | 3 1
60 | 3 2
61 | 4 1
62 | 4 2
63 | 4 3
64 |
65 |
66 | + Edge list (symmetric and unweighted):
67 | Codes for transforming the graph into the correct format are provided in the experiments directory.
68 |
69 |
70 | Overview
71 | ---------
72 |
73 | The parallel maximum clique algorithms use tight bounds that are fast to compute.
74 | A few of those are listed below.
75 |
76 | * K-cores
77 | * Degree
78 | * Neighborhood cores
79 | * Greedy coloring
80 |
81 | All bounds are dynamically updated.
82 |
83 | Examples of the three main maximum clique algorithms are given below.
84 | Each essentially builds on the other.
85 |
86 | # uses the four basic k-core pruning steps
87 | ./pmc -f ../pmc/data/output/socfb-Stanford3.mtx -a 2
88 |
89 | # k-core pruning and greedy coloring
90 | ./pmc -f ../pmc/data/output/socfb-Stanford3.mtx -a 1
91 |
92 | # neighborhood core pruning (and ordering for greedy coloring)
93 | ./pmc -f ../pmc/data/output/socfb-Stanford3.mtx -a 0
94 |
95 |
96 |
97 |
98 |
99 | ### Dynamic graph reduction
100 |
101 | The reduction wait parameter `-r` below is set to be 1 second (default = 4 seconds).
102 |
103 | ./pmc -f data/sanr200-0-9.mtx -a 0 -t 2 -r 1
104 |
105 | In some cases, it may make sense to turn off the explicit graph reduction.
106 | This is done by setting the reduction wait time '-r' to be very large.
107 |
108 | # Set the reduction wait parameter
109 | ./pmc -f data/socfb-Stanford3.mtx -a 0 -t 2 -r 999
110 |
111 |
112 |
113 |
114 |
115 |
116 | ### Orderings
117 |
118 | The PMC algorithms are easily adapted to use various ordering strategies.
119 | To prescribe a vertex ordering, use the -o option with one of the following:
120 | + `deg`
121 | + `kcore`
122 | + `dual_deg` orders vertices by the sum of degrees from neighbors
123 | + `dual_kcore` orders vertices by the sum of core numbers from neighbors
124 | + `kcore_deg` vertices are ordered by the weight k(v)d(v)
125 | + `rand` randomized ordering of vertices
126 |
127 |
128 |
129 | ##### Direction of ordering
130 |
131 | Vertices are searched by default in increasing order, to search vertices in decreasing order, use the `d` option:
132 |
133 | ./pmc -f data/p-hat700-2.mtx -a 0 -d
134 |
135 |
136 |
137 |
138 | ### Heuristic
139 | The fast heuristic may also be customized to use various greedy selection strategies.
140 | This is done by using `-h` with one of the following:
141 |
142 | + `deg`
143 | + `kcore`
144 | + `kcore_deg` select vertex that maximizes k(v)d(v)
145 | + `rand` randomly select vertices
146 |
147 |
148 | #### Terminate after applying the heuristic
149 | Approximate the maximum clique using _ONLY_ the heuristic by not setting the exact algorithm via the `-a [num]` option.
150 | For example:
151 |
152 | ./pmc -f data/sanr200-0-9.mtx -h deg
153 |
154 | #### Turning the heuristic off
155 |
156 | # heuristic is turned off by setting `-h 0`.
157 | ./pmc -f data/tscc_enron-only.mtx -h 0 -a 0
158 |
159 |
160 |
161 | ### K-clique
162 |
163 | The parallel maximum clique algorithms have also been parameterized to find cliques of size k.
164 | This routine is useful for many tasks in network analysis such as mining graphs and community detection.
165 |
166 | # Computes a clique of size 50 from the Stanford facebook network
167 | ./pmc -f data/socfb-Stanford3.mtx -a 0 -k 50
168 |
169 |
170 | using `-o rand` to find potentially different cliques of a certain size
171 |
172 | # Computes a clique of size 36 from sanr200-0-9
173 | ./pmc -f data/sanr200-0-9.mtx -a 0 -k 36 -o rand
174 |
175 |
176 |
177 | Terms and conditions
178 | --------------------
179 | Please feel free to use these codes. We only ask that you cite:
180 |
181 | Ryan A. Rossi, David F. Gleich, Assefaw H. Gebremedhin, Md. Mostofa Patwary,
182 | A Fast Parallel Maximum Clique Algorithm for Large Sparse Graphs and Temporal
183 | Strong Components, arXiv preprint 1302.6256, 2013.
184 |
185 | _These codes are research prototypes and may not work for you. No promises. But do email if you run into problems._
186 |
187 |
188 | Copyright 2011-2013, Ryan A. Rossi. All rights reserved.
189 |
--------------------------------------------------------------------------------
/pmc/libpmc.h:
--------------------------------------------------------------------------------
1 | int max_clique(long long nedges, int *ei, int *ej, int index_offset,
2 | int outsize, int *clique);
3 |
--------------------------------------------------------------------------------
/pmc/libpmc_test.cpp:
--------------------------------------------------------------------------------
1 |
2 | #include
3 | #include
4 | #include
5 |
6 | extern "C" {
7 |
8 | // a list of edges, where index_offset is the starting index
9 | int max_clique(long long nedges, int *ei, int *ej, int index_offset,
10 | int outsize, int *clique);
11 |
12 | };
13 |
14 | void test1() {
15 | // test a triangle
16 | int ei[] = {0, 0, 1};
17 | int ej[] = {1, 2, 2};
18 | int output[3] = {0, 0, 0};
19 |
20 | int C = max_clique(3, ej, ei, 0, 3, output);
21 | if (C != 3) {
22 | fprintf(stderr, "Test failed");
23 | exit(-1);
24 | }
25 | }
26 |
27 | int main(int argc, char **argv) {
28 | test1();
29 | };
30 |
--------------------------------------------------------------------------------
/pmc/pmc.h:
--------------------------------------------------------------------------------
1 | /**
2 | ============================================================================
3 | Name : Parallel Maximum Clique (PMC) Library
4 | Author : Ryan A. Rossi (rrossi@purdue.edu)
5 | Description : A general high-performance parallel framework for computing
6 | maximum cliques. The library is designed to be fast for large
7 | sparse graphs.
8 |
9 | Copyright (C) 2012-2013, Ryan A. Rossi, All rights reserved.
10 |
11 | Please cite the following paper if used:
12 | Ryan A. Rossi, David F. Gleich, Assefaw H. Gebremedhin, Md. Mostofa
13 | Patwary, A Fast Parallel Maximum Clique Algorithm for Large Sparse Graphs
14 | and Temporal Strong Components, arXiv preprint 1302.6256, 2013.
15 |
16 | See http://ryanrossi.com/pmc for more information.
17 | ============================================================================
18 | */
19 |
20 | #ifndef __PMC_H__
21 | #define __PMC_H__
22 |
23 | #include "pmc_headers.h"
24 | #include "pmc_input.h"
25 | #include "pmc_utils.h"
26 |
27 | #include "pmc_heu.h"
28 | #include "pmc_maxclique.h"
29 | #include "pmcx_maxclique.h"
30 | #include "pmcx_maxclique_basic.h"
31 |
32 | #endif
33 |
--------------------------------------------------------------------------------
/pmc/pmc.jl:
--------------------------------------------------------------------------------
1 | module PMC
2 |
3 | #=
4 | int max_clique(long long nedges, int *ei, int *ej, int index_offset,
5 | int outsize, int *clique);
6 | =#
7 |
8 | const libpmc = joinpath(dirname(@Base.__FILE__),"libpmc")
9 |
10 | function pmc(A::SparseMatrixCSC)
11 | maxd = Int(maximum(sum(spones(A),1)))
12 | ei,ej = findnz(tril(A,1))
13 |
14 | ei = map(Int32,ei)
15 | ej = map(Int32,ej)
16 |
17 | offset = Cint(1)
18 |
19 | outsize = maxd
20 | output = zeros(Int32,maxd)
21 |
22 | clique_size = ccall(
23 | (:max_clique, libpmc), Cint,
24 | (Clonglong, Ptr{Cint}, Ptr{Cint}, Cint, Cint, Ptr{Cint}),
25 | length(ei), ei, ej, offset, outsize, output)
26 |
27 | return map(Int64, output[1:clique_size])
28 | end
29 |
30 | end
31 |
32 | #@show PMC.pmc(sprandn(10000,10000,10/10000))
33 |
34 |
--------------------------------------------------------------------------------
/pmc/pmc.m:
--------------------------------------------------------------------------------
1 | function max_clique = pmc(A)
2 | maxd = int32(full(max(sum(spones(A),1))));
3 | [ei,ej] = find(tril(A,1));
4 | ei = int32(ei);
5 | ej = int32(ej);
6 | loadlibrary('libpmc');
7 | offset = 1;
8 | outsize = maxd;
9 | output = int32(zeros(maxd,1));
10 | eiPtr = libpointer('int32Ptr',ei);
11 | ejPtr = libpointer('int32Ptr',ej);
12 | outputPtr = libpointer('int32Ptr',output);
13 | clique_size = calllib('libpmc','max_clique',size(ei,1),eiPtr,ejPtr,offset,...
14 | outsize,outputPtr);
15 | output = get(outputPtr,'Value');
16 | max_clique = output(1:clique_size);
17 | unloadlibrary libpmc;
--------------------------------------------------------------------------------
/pmc/pmc.py:
--------------------------------------------------------------------------------
1 | import numpy as np
2 | from numpy.ctypeslib import ndpointer
3 | import ctypes
4 |
5 | def pmc(ei,ej,nnodes,nnedges): #ei, ej is edge list whose index starts from 0
6 | degrees = np.zeros(nnodes,dtype = np.int32)
7 | new_ei = []
8 | new_ej = []
9 | for i in range(nnedges):
10 | degrees[ei[i]] += 1
11 | if ej[i] <= ei[i] + 1:
12 | new_ei.append(ei[i])
13 | new_ej.append(ej[i])
14 | maxd = max(degrees)
15 | offset = 0
16 | new_ei = np.array(new_ei,dtype = np.int32)
17 | new_ej = np.array(new_ej,dtype = np.int32)
18 | outsize = maxd
19 | output = np.zeros(maxd,dtype = np.int32)
20 | lib = ctypes.cdll.LoadLibrary("libpmc.dylib")
21 | fun = lib.max_clique
22 | #call C function
23 | fun.restype = np.int32
24 | fun.argtypes = [ctypes.c_int32,ndpointer(ctypes.c_int32, flags="C_CONTIGUOUS"),
25 | ndpointer(ctypes.c_int32, flags="C_CONTIGUOUS"),ctypes.c_int32,
26 | ctypes.c_int32,ndpointer(ctypes.c_int32, flags="C_CONTIGUOUS")]
27 | clique_size = fun(len(new_ei),new_ei,new_ej,offset,outsize,output)
28 | max_clique = np.empty(clique_size,dtype = np.int32)
29 | max_clique[:]=[output[i] for i in range(clique_size)]
30 |
31 | return max_clique
32 |
--------------------------------------------------------------------------------
/pmc/pmc_clique_utils.cpp:
--------------------------------------------------------------------------------
1 | /**
2 | ============================================================================
3 | Name : Parallel Maximum Clique (PMC) Library
4 | Author : Ryan A. Rossi (rrossi@purdue.edu)
5 | Description : A general high-performance parallel framework for computing
6 | maximum cliques. The library is designed to be fast for large
7 | sparse graphs.
8 |
9 | Copyright (C) 2012-2013, Ryan A. Rossi, All rights reserved.
10 |
11 | Please cite the following paper if used:
12 | Ryan A. Rossi, David F. Gleich, Assefaw H. Gebremedhin, Md. Mostofa
13 | Patwary, A Fast Parallel Maximum Clique Algorithm for Large Sparse Graphs
14 | and Temporal Strong Components, arXiv preprint 1302.6256, 2013.
15 |
16 | See http://ryanrossi.com/pmc for more information.
17 | ============================================================================
18 | */
19 |
20 | #include "pmc_graph.h"
21 | #include
22 |
23 | using namespace std;
24 | using namespace pmc;
25 |
26 | int pmc_graph::initial_pruning(pmc_graph& G, int* &pruned, int lb) {
27 | int lb_idx = 0;
28 | for (int i = G.num_vertices()-1; i >= 0; i--) {
29 | if (kcore[kcore_order[i]] == lb) lb_idx = i;
30 | if (kcore[kcore_order[i]] <= lb) pruned[kcore_order[i]] = 1;
31 | }
32 |
33 | double sec = get_time();
34 | cout << "[pmc: initial k-core pruning] before pruning: |V| = " << G.num_vertices();
35 | cout << ", |E| = " << G.num_edges() <= 0; i--) {
51 | if (kcore[kcore_order[i]] == lb) lb_idx = i;
52 | if (kcore[kcore_order[i]] <= lb) {
53 | pruned[kcore_order[i]] = 1;
54 | for (long long j = vertices[kcore_order[i]]; j < vertices[kcore_order[i] + 1]; j++) {
55 | adj[kcore_order[i]][edges[j]] = false;
56 | adj[edges[j]][kcore_order[i]] = false;
57 | }
58 | }
59 | }
60 |
61 | double sec = get_time();
62 | cout << "[pmc: initial k-core pruning] before pruning: |V| = " << G.num_vertices() << ", |E| = " << G.num_edges() < &V, pmc_graph &G,
75 | int &lb_idx, int &lb, string vertex_ordering, bool decr_order) {
76 |
77 | srand (time(NULL));
78 | int u = 0, val = 0;
79 | for (int k = lb_idx; k < G.num_vertices(); k++) {
80 | if (degree[kcore_order[k]] >= lb - 1) {
81 | u = kcore_order[k];
82 |
83 | if (vertex_ordering == "deg")
84 | val = vertices[u + 1] - vertices[u];
85 | else if (vertex_ordering == "kcore")
86 | val = kcore[u];
87 | else if (vertex_ordering == "kcore_deg")
88 | val = degree[u] * kcore[u];
89 | else if (vertex_ordering == "rand")
90 | val = rand() % vertices.size();
91 | // neighbor degrees
92 | else if (vertex_ordering == "dual_deg") {
93 | val = 0;
94 | for (long long j = vertices[u]; j < vertices[u + 1]; j++) {
95 | val = val + G.vertex_degree(edges[j]);
96 | }
97 | }
98 | // neighbor degrees
99 | else if (vertex_ordering == "dual_kcore") {
100 | val = 0;
101 | for (long long j = vertices[u]; j < vertices[u + 1]; j++) {
102 | val = val + kcore[edges[j]];
103 | }
104 | }
105 | else val = vertices[u + 1] - vertices[u];
106 | V.push_back(Vertex(u,val));
107 | }
108 | }
109 | if (decr_order)
110 | std::sort(V.begin(), V.end(), decr_bound);
111 | else
112 | std::sort(V.begin(), V.end(), incr_bound);
113 | }
114 |
115 |
116 | /**
117 | * Reduce the graph by removing the pruned vertices
118 | * + Systematically speeds algorithm up by reducing the neighbors as more vertices are searched
119 | *
120 | * The algorithm below is for parallel maximum clique finders and has the following features:
121 | * + Thread-safe, since local copy of vertices/edges are passed in..
122 | * + Pruned is a shared variable, but it is safe, since only reads/writes can occur, no deletion
123 | */
124 | void pmc_graph::reduce_graph(
125 | vector& vs,
126 | vector& es,
127 | int* &pruned,
128 | pmc_graph& G,
129 | int id,
130 | int& mc) {
131 |
132 | int num_vs = vs.size();
133 |
134 | vector V(num_vs,0);
135 | vector E;
136 | E.reserve(es.size());
137 |
138 | int start = 0;
139 | for (int i = 0; i < num_vs - 1; i++) {
140 | start = E.size();
141 | if (!pruned[i]) { //skip these V_local...
142 | for (long long j = vs[i]; j < vs[i + 1]; j++ ) {
143 | if (!pruned[es[j]])
144 | E.push_back(es[j]);
145 | }
146 | }
147 | V[i] = start;
148 | V[i + 1] = E.size();
149 | }
150 | vs = V;
151 | es = E;
152 |
153 | // compute k-cores and share bounds: ensure operation completed by single process
154 | #pragma omp single nowait
155 | {
156 | cout << ">>> [pmc: thread " << omp_get_thread_num() + 1 << "]" < &C_max, double &sec) {
165 | cout << "*** [pmc: thread " << omp_get_thread_num() + 1;
166 | cout << "] current max clique = " << C_max.size();
167 | cout << ", time = " << get_time() - sec << " sec" < &C_max, double sec, double time_limit, bool &time_expired_msg) {
176 | if ((get_time() - sec) > time_limit) {
177 | if (time_expired_msg) {
178 | cout << "\n### Time limit expired, terminating search. ###" <& V,
26 | vector& E,
27 | int* &pruned) {
28 |
29 | long long n, d, i, j, start, num, md;
30 | long long v, u, w, du, pu, pw, md_end;
31 | n = vertices.size();
32 |
33 | vector pos_tmp(n);
34 | vector core_tmp(n);
35 | vector order_tmp(n);
36 |
37 | md = 0;
38 | for(v=1; v md) md = core_tmp[v];
41 | }
42 |
43 | md_end = md+1;
44 | vector < int > bin(md_end,0);
45 |
46 | for (v=1; v < n; v++) bin[core_tmp[v]]++;
47 |
48 | start = 1;
49 | for (d=0; d < md_end; d++) {
50 | num = bin[d];
51 | bin[d] = start;
52 | start = start + num;
53 | }
54 |
55 | for (v=1; v 1; d--) bin[d] = bin[d-1];
62 | bin[0] = 1;
63 |
64 | for (i = 1; i < n; i++) {
65 | v=order_tmp[i];
66 | for (j = V[v-1]; j < V[v]; j++) {
67 | u = E[j] + 1;
68 | if (core_tmp[u] > core_tmp[v]) {
69 | du = core_tmp[u]; pu = pos_tmp[u];
70 | pw = bin[du]; w = order_tmp[pw];
71 | if (u != w) {
72 | pos_tmp[u] = pw; order_tmp[pu] = w;
73 | pos_tmp[w] = pu; order_tmp[pw] = u;
74 | }
75 | bin[du]++; core_tmp[u]--;
76 | }
77 | }
78 | }
79 |
80 | for (v=0; v pos(n);
100 | if (kcore_order.size() > 0) {
101 | vector tmp(n,0);
102 | kcore = tmp;
103 | kcore_order = tmp;
104 | }
105 | else {
106 | kcore_order.resize(n);
107 | kcore.resize(n);
108 | }
109 |
110 | md = 0;
111 | for (v=1; v md) md = kcore[v];
114 | }
115 |
116 | md_end = md+1;
117 | vector < int > bin(md_end,0);
118 |
119 | for (v=1; v < n; v++) bin[kcore[v]]++;
120 |
121 | start = 1;
122 | for (d=0; d < md_end; d++) {
123 | num = bin[d];
124 | bin[d] = start;
125 | start = start + num;
126 | }
127 |
128 | // bucket sort
129 | for (v=1; v 1; d--) bin[d] = bin[d-1];
136 | bin[0] = 1;
137 |
138 | // kcores
139 | for (i=1; i kcore[v]) {
144 | du = kcore[u]; pu = pos[u];
145 | pw = bin[du]; w = kcore_order[pw];
146 | if (u != w) {
147 | pos[u] = pw; kcore_order[pu] = w;
148 | pos[w] = pu; kcore_order[pw] = u;
149 | }
150 | bin[du]++; kcore[u]--;
151 | }
152 | }
153 | }
154 |
155 | for (v = 0; v < n-1; v++) {
156 | kcore[v] = kcore[v+1] + 1; // K + 1
157 | kcore_order[v] = kcore_order[v+1]-1;
158 | }
159 | max_core = kcore[kcore_order[num_vertices()-1]] - 1;
160 |
161 | bin.clear();
162 | pos.clear();
163 | }
164 |
--------------------------------------------------------------------------------
/pmc/pmc_driver.cpp:
--------------------------------------------------------------------------------
1 | /**
2 | ============================================================================
3 | Name : Parallel Maximum Clique (PMC) Library
4 | Author : Ryan A. Rossi (rrossi@purdue.edu)
5 | Description : A general high-performance parallel framework for computing
6 | maximum cliques. The library is designed to be fast for large
7 | sparse graphs.
8 |
9 | Copyright (C) 2012-2013, Ryan A. Rossi, All rights reserved.
10 |
11 | Please cite the following paper if used:
12 | Ryan A. Rossi, David F. Gleich, Assefaw H. Gebremedhin, Md. Mostofa
13 | Patwary, A Fast Parallel Maximum Clique Algorithm for Large Sparse Graphs
14 | and Temporal Strong Components, arXiv preprint 1302.6256, 2013.
15 |
16 | See http://ryanrossi.com/pmc for more information.
17 | ============================================================================
18 | */
19 |
20 | #include "pmc.h"
21 |
22 | using namespace std;
23 | using namespace pmc;
24 |
25 | int main(int argc, char *argv[]) {
26 |
27 | //! parse command args
28 | input in(argc, argv);
29 | if (in.help) {
30 | usage(argv[0]);
31 | return 0;
32 | }
33 |
34 | //! read graph
35 | pmc_graph G(in.graph_stats,in.graph);
36 | if (in.graph_stats) { G.bound_stats(in.algorithm, in.lb, G); }
37 |
38 | //! ensure wait time is greater than the time to recompute the graph data structures
39 | if (G.num_edges() > 1000000000 && in.remove_time < 120) in.remove_time = 120;
40 | else if (G.num_edges() > 250000000 && in.remove_time < 10) in.remove_time = 10;
41 | cout << "explicit reduce is set to " << in.remove_time << " seconds" < C;
54 | if (in.lb == 0 && in.heu_strat != "0") { // skip if given as input
55 | pmc_heu maxclique(G,in);
56 | in.lb = maxclique.search(G, C);
57 | cout << "Heuristic found clique of size " << in.lb;
58 | cout << " in " << get_time() - seconds << " seconds" <= 0) {
68 | switch(in.algorithm) {
69 | case 0: {
70 | //! k-core pruning, neigh-core pruning/ordering, dynamic coloring bounds/sort
71 | if (G.num_vertices() < in.adj_limit) {
72 | G.create_adj();
73 | pmcx_maxclique finder(G,in);
74 | finder.search_dense(G,C);
75 | break;
76 | }
77 | else {
78 | pmcx_maxclique finder(G,in);
79 | finder.search(G,C);
80 | break;
81 | }
82 | }
83 | case 1: {
84 | //! k-core pruning, dynamic coloring bounds/sort
85 | if (G.num_vertices() < in.adj_limit) {
86 | G.create_adj();
87 | pmcx_maxclique_basic finder(G,in);
88 | finder.search_dense(G,C);
89 | break;
90 | }
91 | else {
92 | pmcx_maxclique_basic finder(G,in);
93 | finder.search(G,C);
94 | break;
95 | }
96 | }
97 | case 2: {
98 | //! simple k-core pruning (four new pruning steps)
99 | pmc_maxclique finder(G,in);
100 | finder.search(G,C);
101 | break;
102 | }
103 | default:
104 | cout << "algorithm " << in.algorithm << " not found." <
24 | #include
25 | #include
26 | #include
27 | #include
28 | #include
29 | #include "math.h"
30 | #include "pmc_headers.h"
31 | #include "pmc_utils.h"
32 | #include "pmc_vertex.h"
33 |
34 |
35 | namespace pmc {
36 | class pmc_graph {
37 | private:
38 | // helper functions
39 | void read_mtx(const string& filename);
40 | void read_edges(const string& filename);
41 | void read_metis(const string& filename);
42 |
43 | public:
44 | vector edges;
45 | vector vertices;
46 | vector degree;
47 | int min_degree;
48 | int max_degree;
49 | double avg_degree;
50 | bool is_gstats;
51 | string fn;
52 | bool** adj;
53 |
54 | // constructor
55 | pmc_graph(const string& filename);
56 | pmc_graph(bool graph_stats, const string& filename);
57 | pmc_graph(const string& filename, bool make_adj);
58 | pmc_graph(vector vs, vector es) {
59 | edges = es;
60 | vertices = vs;
61 | vertex_degrees();
62 | }
63 | pmc_graph(long long nedges, int *ei, int *ej, int offset);
64 |
65 | // destructor
66 | ~pmc_graph();
67 |
68 | void read_graph(const string& filename);
69 | void create_adj();
70 | void reduce_graph(int* &pruned);
71 | void reduce_graph(
72 | vector& vs,
73 | vector& es,
74 | int* &pruned,
75 | int id,
76 | int& mc);
77 |
78 | int num_vertices() { return vertices.size() - 1; }
79 | int num_edges() { return edges.size()/2; }
80 | vector * get_vertices(){ return &vertices; }
81 | vector* get_edges(){ return &edges; }
82 | vector* get_degree(){ return °ree; }
83 | vector get_edges_array() { return edges; }
84 | vector get_vertices_array() { return vertices; };
85 | vector e_v, e_u, eid;
86 |
87 | int vertex_degree(int v) { return vertices[v] - vertices[v+1]; }
88 | long long first_neigh(int v) { return vertices[v]; }
89 | long long last_neigh(int v) { return vertices[v+1]; }
90 |
91 | void sum_vertex_degrees();
92 | void vertex_degrees();
93 | void update_degrees();
94 | void update_degrees(bool flag);
95 | void update_degrees(int* &pruned, int& mc);
96 | double density() { return (double)num_edges() / (num_vertices() * (num_vertices() - 1.0) / 2.0); }
97 | int get_max_degree() { return max_degree; }
98 | int get_min_degree() { return min_degree; }
99 | double get_avg_degree() { return avg_degree; }
100 |
101 | void initialize();
102 | string get_file_extension(const string& filename);
103 | void basic_stats(double sec);
104 | void bound_stats(int alg, int lb, pmc_graph& G);
105 |
106 | // vertex sorter
107 | void compute_ordering(vector& bound, vector& order);
108 | void compute_ordering(string degree, vector& order);
109 | // edge sorters
110 | void degree_bucket_sort();
111 | void degree_bucket_sort(bool desc);
112 |
113 | int max_core;
114 | vector kcore;
115 | vector kcore_order;
116 | vector* get_kcores() { return &kcore; }
117 | vector* get_kcore_ordering() { return &kcore_order; }
118 | int get_max_core() { return max_core; }
119 | void update_kcores(int* &pruned);
120 |
121 | void compute_cores();
122 | void induced_cores_ordering(
123 | vector& V,
124 | vector& E,
125 | int* &pruned);
126 |
127 | // clique utils
128 | int initial_pruning(pmc_graph& G, int* &pruned, int lb);
129 | int initial_pruning(pmc_graph& G, int* &pruned, int lb, bool** &adj);
130 | void order_vertices(vector &V, pmc_graph &G,
131 | int &lb_idx, int &lb, string vertex_ordering, bool decr_order);
132 |
133 | void print_info(vector &C_max, double &sec);
134 | void print_break();
135 | bool time_left(vector &C_max, double sec,
136 | double time_limit, bool &time_expired_msg);
137 | void graph_stats(pmc_graph& G, int& mc, int id, double &sec);
138 |
139 | void reduce_graph(
140 | vector& vs,
141 | vector& es,
142 | int* &pruned,
143 | pmc_graph& G,
144 | int id,
145 | int& mc);
146 |
147 | bool clique_test(pmc_graph& G, vector C);
148 | };
149 |
150 | }
151 | #endif
152 |
--------------------------------------------------------------------------------
/pmc/pmc_headers.h:
--------------------------------------------------------------------------------
1 | /**
2 | ============================================================================
3 | Name : Parallel Maximum Clique (PMC) Library
4 | Author : Ryan A. Rossi (rrossi@purdue.edu)
5 | Description : A general high-performance parallel framework for computing
6 | maximum cliques. The library is designed to be fast for large
7 | sparse graphs.
8 |
9 | Copyright (C) 2012-2013, Ryan A. Rossi, All rights reserved.
10 |
11 | Please cite the following paper if used:
12 | Ryan A. Rossi, David F. Gleich, Assefaw H. Gebremedhin, Md. Mostofa
13 | Patwary, A Fast Parallel Maximum Clique Algorithm for Large Sparse Graphs
14 | and Temporal Strong Components, arXiv preprint 1302.6256, 2013.
15 |
16 | See http://ryanrossi.com/pmc for more information.
17 | ============================================================================
18 | */
19 |
20 | #ifndef PMC_HEADERS_H_
21 | #define PMC_HEADERS_H_
22 |
23 | #define NOMINMAX // disable std::max and std::min
24 | #include
25 | #include
26 | #include
27 | #include
28 | #include
29 | #include
30 | #include