diff --git a/.clang-format b/.clang-format index a4ce58c47..e73f6d56b 100644 --- a/.clang-format +++ b/.clang-format @@ -1,5 +1,5 @@ BasedOnStyle: WebKit -Standard: Cpp11 +Standard: Cpp03 AlignAfterOpenBracket: false AlignEscapedNewlinesLeft: true AlwaysBreakAfterDefinitionReturnType: None @@ -13,4 +13,3 @@ SortIncludes: false AlignTrailingComments: false SpacesInAngles: true - diff --git a/.gitignore b/.gitignore index 36e77b53c..ef202911d 100644 --- a/.gitignore +++ b/.gitignore @@ -6,3 +6,12 @@ kevin-bacon2.dat random.dot triangular-fr.dot triangular-kk.dot +ospf-sptree.dot +routing-table.dat +tc-out.dot +test-astar-cities.dot +web-graph.dot +cycle_ratio_s382.90.dot +test/metric_tsp_approx.graph +test/weighted_graph.gr +test/weighted_matching.dat diff --git a/.travis.yml b/.travis.yml index e1cab8619..6bb3ae580 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,298 +1,911 @@ -# Copyright 2016, 2017 Peter Dimov -# Copyright 2018 Joh Maddock -# Distributed under the Boost Software License, Version 1.0. -# (See accompanying file LICENSE_1_0.txt or copy at http://boost.org/LICENSE_1_0.txt) - -language: cpp - -python: "2.7" - -os: - - linux - - osx - -branches: - only: - - master - - develop - - /feature\/.*/ - -env: - matrix: - - BOGUS_JOB=true - -matrix: - - exclude: - - env: BOGUS_JOB=true - - include: - - os: linux - compiler: g++-4.4 - env: TOOLSET=gcc COMPILER=g++-4.4 CXXSTD=98,0x - addons: - apt: - packages: - - g++-4.4 - sources: +--- +addons: + apt: + packages: + - binutils-gold + - gdb + - libc6-dbg +after_script: true +anchors: + clang-38: + apt: + packages: + - clang-3.8 + - gcc-multilib + - libstdc++-6-dev + sources: + - llvm-toolchain-xenial-3.8 + - ubuntu-toolchain-r-test + clang-4: + apt: + packages: + - clang-4.0 + - gcc-multilib + - libstdc++-6-dev + sources: + - llvm-toolchain-xenial-4.0 + - ubuntu-toolchain-r-test + clang-5: + apt: + packages: + - clang-5.0 + - gcc-multilib + - libstdc++-7-dev + sources: + - llvm-toolchain-xenial-5.0 + - ubuntu-toolchain-r-test + clang-6: + apt: + packages: + - clang-6.0 + - gcc-multilib + - libc6-dbg + - libc++-dev + - libstdc++-8-dev + sources: + - llvm-toolchain-xenial-6.0 + - ubuntu-toolchain-r-test + clang-7: + apt: + packages: + - clang-7 + - gcc-multilib + - libc6-dbg + - libc++-dev + - libstdc++-8-dev + sources: + - llvm-toolchain-xenial-7 + - ubuntu-toolchain-r-test + clang-8: + apt: + packages: + - clang-8 + - gcc-multilib + - libc6-dbg + - libc++-dev + - libstdc++-8-dev + sources: + - llvm-toolchain-xenial-8 + - ubuntu-toolchain-r-test + gcc-48: + apt: + packages: + - g++-4.8 + - g++-4.8-multilib + gcc-49: + apt: + packages: + - g++-4.9 + - g++-4.9-multilib + sources: + - ubuntu-toolchain-r-test + gcc-5: + apt: + packages: + - g++-5 + - g++-5-multilib + gcc-6: + apt: + packages: + - g++-6 + - g++-6-multilib + sources: + - ubuntu-toolchain-r-test + gcc-7: + apt: + packages: + - g++-7 + - g++-7-multilib + sources: + - ubuntu-toolchain-r-test + gcc-8: + apt: + packages: + - g++-8 + - g++-8-multilib + sources: + - ubuntu-toolchain-r-test + gcc-9: + apt: + packages: + - g++-9 + - g++-9-multilib + sources: + - ubuntu-toolchain-r-test +before_install: true +before_script: true +dist: bionic +env: + global: + - "B2_ADDRESS_MODEL=address-model=64,32" + - "B2_THREADING=threading=multi,single" + - "B2_VARIANT=variant=release,debug" +install: "source utility/ci/travis/install.sh" +jobs: + include: + - + addons: + apt: + packages: + - g++-4.8 + dist: trusty + env: + - B2_TOOLSET=gcc-4.8 + - "B2_CXXSTD=cxxstd=03,11" + - "COPTS=cxxflags=-Wall -Wextra -Wpedantic -Wredundant-decls -Wcast-align -Wmissing-declarations -Wmissing-include-dirs -Wswitch-enum -Wswitch-default -Werror -Winvalid-pch -Wredundant-decls -Wformat=2 -Wmissing-format-attribute -Wformat-nonliteral -fstack-protector-all -fstack-check-lubsan -Wno-unused-parameter -Wno-missing-declarations -Wno-sign-compare -fPIC -fsanitize=address -fsanitize=pointer-compare -fsanitize=leak -fsanitize-coverage=trace-pc -fsanitize-coverage=trace-cmp -fcf-protection=full -fvtable-verify=std -lasan -llsan -Wodr -fsanitize=undefined -fsanitize-address-use-after-scope -fvtv-debug" + - "LOPTS=linkflags=-fPIC -llsan -lasan" + name: "Unit Tests" + os: linux + stage: test + - + addons: + apt: + packages: + - g++-4.9 + sources: - ubuntu-toolchain-r-test - - - os: linux - compiler: g++-4.6 - env: TOOLSET=gcc COMPILER=g++-4.6 CXXSTD=03,0x - addons: - apt: - packages: - - g++-4.6 - sources: + dist: trusty + env: + - B2_TOOLSET=gcc-4.9 + - "B2_CXXSTD=cxxstd=03,11" + - "COPTS=cxxflags=-Wall -Wextra -Wpedantic -Wredundant-decls -Wcast-align -Wmissing-declarations -Wmissing-include-dirs -Wswitch-enum -Wswitch-default -Werror -Winvalid-pch -Wredundant-decls -Wformat=2 -Wmissing-format-attribute -Wformat-nonliteral -fstack-protector-all -fstack-check-lubsan -Wno-unused-parameter -Wno-missing-declarations -Wno-sign-compare -fPIC -fsanitize=address -fsanitize=pointer-compare -fsanitize=leak -fsanitize-coverage=trace-pc -fsanitize-coverage=trace-cmp -fcf-protection=full -fvtable-verify=std -lasan -llsan -Wodr -fsanitize=undefined -fsanitize-address-use-after-scope -fvtv-debug" + - "LOPTS=linkflags=-lubsan -fPIC -llsan -lasan" + name: "Unit Tests" + os: linux + stage: test + - + addons: + apt: + packages: + - clang-3.8 + - libstdc++-6-dev + sources: + - llvm-toolchain-xenial-3.8 - ubuntu-toolchain-r-test - - - os: linux - env: TOOLSET=gcc COMPILER=g++-4.7 CXXSTD=03,11 - addons: - apt: - packages: - - g++-4.7 - sources: + dist: trusty + env: + - B2_TOOLSET=clang-3.8 + - "B2_CXXSTD=cxxstd=03,11,14" + - "COPTS=cxxflags=-Wall -Wextra -Wpedantic -Wredundant-decls -Wcast-align -Wmissing-declarations -Wmissing-include-dirs -Wswitch-enum -Wswitch-default -Werror -Winvalid-pch -Wredundant-decls -Wformat=2 -Wmissing-format-attribute -Wformat-nonliteral -fstack-protector-all -fstack-check-lubsan -Wno-unused-parameter -Wno-missing-declarations -Wno-sign-compare -fPIC -fsanitize=address -fsanitize=pointer-compare -fsanitize=leak -fsanitize-coverage=trace-pc -fsanitize-coverage=trace-cmp -fcf-protection=full -fvtable-verify=std -lasan -llsan -Wodr -fsanitize=undefined -fsanitize-address-use-after-scope -fvtv-debug" + - "LOPTS=linkflags=-lubsan -fPIC -llsan -lasan" + name: "Unit Tests" + os: linux + stage: test + - + addons: + apt: + packages: + - g++-5 + env: + - B2_TOOLSET=gcc-5 + - B2_CXXSTD=cxxstd=11 + - "COPTS=cxxflags=-Wall -Wextra -Wpedantic -Wredundant-decls -Wcast-align -Wmissing-declarations -Wmissing-include-dirs -Wswitch-enum -Wswitch-default -Werror -Winvalid-pch -Wredundant-decls -Wformat=2 -Wmissing-format-attribute -Wformat-nonliteral -fstack-protector-all -fstack-check-lubsan -Wno-unused-parameter -Wno-missing-declarations -Wno-sign-compare -fPIC -fsanitize=address -fsanitize=pointer-compare -fsanitize=leak -fsanitize-coverage=trace-pc -fsanitize-coverage=trace-cmp -fcf-protection=full -fvtable-verify=std -lasan -llsan -Wodr -fsanitize=undefined -fsanitize-address-use-after-scope -fvtv-debug" + - "LOPTS=linkflags=-lubsan -fPIC -llsan -lasan" + name: "Unit Tests" + os: linux + stage: test + - + addons: + apt: + packages: + - g++-6 + sources: - ubuntu-toolchain-r-test - - - os: linux - env: TOOLSET=gcc COMPILER=g++-4.8 CXXSTD=03,11 - addons: - apt: - packages: - - g++-4.8 - sources: + env: + - B2_TOOLSET=gcc-6 + - "B2_CXXSTD=cxxstd=11,14" + - "COPTS=cxxflags=-Wall -Wextra -Wpedantic -Wredundant-decls -Wcast-align -Wmissing-declarations -Wmissing-include-dirs -Wswitch-enum -Wswitch-default -Werror -Winvalid-pch -Wredundant-decls -Wformat=2 -Wmissing-format-attribute -Wformat-nonliteral -fstack-protector-all -fstack-check-lubsan -Wno-unused-parameter -Wno-missing-declarations -Wno-sign-compare -fPIC -fsanitize=address -fsanitize=pointer-compare -fsanitize=leak -fsanitize-coverage=trace-pc -fsanitize-coverage=trace-cmp -fcf-protection=full -fvtable-verify=std -lasan -llsan -Wodr -fsanitize=undefined -fsanitize-address-use-after-scope -fvtv-debug" + - "LOPTS=linkflags=-lubsan -fPIC -llsan -lasan" + name: "Unit Tests" + os: linux + stage: test + - + addons: + apt: + packages: + - g++-7 + sources: - ubuntu-toolchain-r-test - - - os: linux - env: TOOLSET=gcc COMPILER=g++-4.9 CXXSTD=03,11 - addons: - apt: - packages: - - g++-4.9 - sources: + env: + - B2_TOOLSET=gcc-7 + - "B2_CXXSTD=cxxstd=11,14,17" + - "COPTS=cxxflags=-Wall -Wextra -Wpedantic -Wredundant-decls -Wcast-align -Wmissing-declarations -Wmissing-include-dirs -Wswitch-enum -Wswitch-default -Werror -Winvalid-pch -Wredundant-decls -Wformat=2 -Wmissing-format-attribute -Wformat-nonliteral -fstack-protector-all -fstack-check-lubsan -Wno-unused-parameter -Wno-missing-declarations -Wno-sign-compare -fPIC -fsanitize=address -fsanitize=pointer-compare -fsanitize=leak -fsanitize-coverage=trace-pc -fsanitize-coverage=trace-cmp -fcf-protection=full -fvtable-verify=std -lasan -llsan -Wodr -fsanitize=undefined -fsanitize-address-use-after-scope -fvtv-debug" + - "LOPTS=linkflags=-lubsan -fPIC -llsan -lasan" + name: "Unit Tests" + os: linux + stage: test + - + addons: + apt: + packages: + - g++-8 + sources: - ubuntu-toolchain-r-test - - - os: linux - env: TOOLSET=gcc COMPILER=g++-5 CXXSTD=03,11,14 - addons: - apt: + env: + - B2_TOOLSET=gcc-8 + - "B2_CXXSTD=cxxstd=14,17,2a" + - "COPTS=cxxflags=-Wall -Wextra -Wpedantic -Wredundant-decls -Wcast-align -Wmissing-declarations -Wmissing-include-dirs -Wswitch-enum -Wswitch-default -Werror -Winvalid-pch -Wredundant-decls -Wformat=2 -Wmissing-format-attribute -Wformat-nonliteral -fstack-protector-all -fstack-check-lubsan -Wno-unused-parameter -Wno-missing-declarations -Wno-sign-compare -fPIC -fsanitize=address -fsanitize=pointer-compare -fsanitize=leak -fsanitize-coverage=trace-pc -fsanitize-coverage=trace-cmp -fcf-protection=full -fvtable-verify=std -lasan -llsan -Wodr -fsanitize=undefined -fsanitize-address-use-after-scope -fvtv-debug" + - "LOPTS=linkflags=-lubsan -fPIC -llsan -lasan" + name: "Unit Tests" + os: linux + stage: test + - + addons: + apt: packages: - - g++-5 - sources: + - clang-4.0 + - libstdc++-6-dev + sources: + - llvm-toolchain-xenial-4.0 - ubuntu-toolchain-r-test - - - os: linux - env: TOOLSET=gcc COMPILER=g++-6 CXXSTD=03,11 - addons: - apt: - packages: - - g++-6 - sources: + env: + - B2_TOOLSET=clang-4.0 + - "B2_CXXSTD=cxxstd=11,14" + - "COPTS=cxxflags=-Wall -Wextra -Wpedantic -Wredundant-decls -Wcast-align -Wmissing-declarations -Wmissing-include-dirs -Wswitch-enum -Wswitch-default -Werror -Winvalid-pch -Wredundant-decls -Wformat=2 -Wmissing-format-attribute -Wformat-nonliteral -fstack-protector-all -fstack-check-lubsan -Wno-unused-parameter -Wno-missing-declarations -Wno-sign-compare -fPIC -fsanitize=address -fsanitize=pointer-compare -fsanitize=leak -fsanitize-coverage=trace-pc -fsanitize-coverage=trace-cmp -fcf-protection=full -fvtable-verify=std -lasan -llsan -Wodr -fsanitize=undefined -fsanitize-address-use-after-scope -fvtv-debug" + - "LOPTS=linkflags=-lubsan -fPIC -llsan -lasan" + name: "Unit Tests" + os: linux + stage: test + - + addons: + apt: + packages: + - clang-5.0 + - libstdc++-7-dev + sources: + - llvm-toolchain-xenial-5.0 - ubuntu-toolchain-r-test - - - os: linux - env: TOOLSET=gcc COMPILER=g++-6 CXXSTD=14,1z - addons: - apt: - packages: - - g++-6 - sources: + env: + - B2_TOOLSET=clang-5.0 + - "B2_CXXSTD=cxxstd=11,14,17" + - "COPTS=cxxflags=-Weverything -Werror -fstack-protector-all -fstack-check-lubsan -fPIC -fsanitize=address -fsanitize=pointer-compare -fsanitize=leak -fsanitize-coverage=trace-pc -fsanitize-coverage=trace-cmp -fcf-protection=full -fvtable-verify=std -lasan -llsan -fsanitize=undefined -fsanitize-address-use-after-scope -fvtv-debug" + - "LOPTS=linkflags=-lubsan -fPIC -llsan -lasan" + name: "Unit Tests" + os: linux + stage: test + - + addons: + apt: + packages: + - clang-6.0 + - libc6-dbg + - libc++-dev + - libstdc++-8-dev + sources: + - llvm-toolchain-xenial-6.0 - ubuntu-toolchain-r-test - - - os: linux - dist: trusty - compiler: g++-7 - env: TOOLSET=gcc COMPILER=g++-7 CXXSTD=03,11 - addons: - apt: - packages: - - g++-7 - sources: + env: + - B2_TOOLSET=clang-6.0 + - "B2_CXXSTD=cxxstd=14,17,2a" + - "COPTS=cxxflags=-Weverything -Werror -fstack-protector-all -fstack-check-lubsan -fPIC -fsanitize=address -fsanitize=pointer-compare -fsanitize=leak -fsanitize-coverage=trace-pc -fsanitize-coverage=trace-cmp -fcf-protection=full -fvtable-verify=std -lasan -llsan -fsanitize=undefined -fsanitize-address-use-after-scope -fvtv-debug" + - "LOPTS=linkflags=-lubsan -fPIC -llsan -lasan" + name: "Unit Tests" + os: linux + stage: test + - + addons: + apt: + packages: + - clang-7 + - libc6-dbg + - libc++-dev + - libstdc++-8-dev + sources: + - llvm-toolchain-xenial-7 - ubuntu-toolchain-r-test - - - os: linux - dist: trusty - compiler: g++-7 - env: TOOLSET=gcc COMPILER=g++-7 CXXSTD=14,17 - addons: - apt: + env: + - B2_TOOLSET=clang-7 + - "B2_CXXSTD=cxxstd=14,17,2a" + - "COPTS=cxxflags=-Weverything -Werror -fstack-protector-all -fstack-check-lubsan -fPIC -fsanitize=address -fsanitize=pointer-compare -fsanitize=leak -fsanitize-coverage=trace-pc -fsanitize-coverage=trace-cmp -fcf-protection=full -fvtable-verify=std -lasan -llsan -fsanitize=undefined -fsanitize-address-use-after-scope -fvtv-debug" + - "LOPTS=linkflags=-lubsan -fPIC -llsan -lasan" + name: "Unit Tests" + os: linux + stage: test + - + addons: + apt: + packages: + - clang-8 + - libc6-dbg + - libc++-dev + - libstdc++-8-dev + sources: + - llvm-toolchain-xenial-8 + - ubuntu-toolchain-r-test + env: + - B2_TOOLSET=clang-8 + - "B2_CXXSTD=cxxstd=14,17,2a" + - "COPTS=cxxflags=-Weverything -Werror -fstack-protector-all -fstack-check-lubsan -fPIC -fsanitize=address -fsanitize=pointer-compare -fsanitize=leak -fsanitize-coverage=trace-pc -fsanitize-coverage=trace-cmp -fcf-protection=full -fvtable-verify=std -lasan -llsan -fsanitize=undefined -fsanitize-address-use-after-scope -fvtv-debug" + - "LOPTS=linkflags=-lubsan -fPIC -llsan -lasan" + name: "Unit Tests" + os: linux + stage: test + - + addons: + apt: + packages: + - clang-6.0 + - libc6-dbg + - libc++-dev + - libstdc++-8-dev + sources: + - llvm-toolchain-xenial-6.0 + - ubuntu-toolchain-r-test + env: + - B2_TOOLSET=clang-6.0 + - "B2_CXXSTD=cxxstd=03,11,14,17,2a" + - B2_CXXFLAGS=-stdlib=libc++ + - "COPTS=cxxflags=-Weverything -Werror -fstack-protector-all -fstack-check-lubsan -fPIC -fsanitize=address -fsanitize=pointer-compare -fsanitize=leak -fsanitize-coverage=trace-pc -fsanitize-coverage=trace-cmp -fcf-protection=full -fvtable-verify=std -lasan -llsan -fsanitize=undefined -fsanitize-address-use-after-scope -fvtv-debug" + - "LOPTS=linkflags=-lubsan -fPIC -llsan -lasan" + name: "Unit Tests" + os: linux + stage: test + - + env: + - B2_TOOLSET=clang + - "B2_CXXSTD=cxxstd=03,11,17" + name: "Unit Tests" + os: osx + stage: test + - + addons: + apt: + packages: + - clang-format-8 + sources: + - llvm-toolchain-xenial-8 + - ubuntu-toolchain-r-test + after_script: true + before_install: + - "utility/ci/travis/format-check.sh || exit 1" + before_script: true + dist: bionic + install: true + name: clang-format + os: linux + script: true + stage: Static_QC + - + addons: + apt: packages: - - g++-7 + - cppcheck sources: - ubuntu-toolchain-r-test - - - os: linux - dist: trusty - compiler: g++-8 - env: TOOLSET=gcc COMPILER=g++-8 CXXSTD=03,11 - addons: - apt: - packages: + after_script: true + before_install: + - "utility/ci/travis/cppcheck.sh || exit 1" + before_script: true + dist: bionic + install: true + name: cppcheck + os: linux + script: true + stage: Static_QC + - + addons: + apt: + packages: - g++-8 - sources: + sources: - ubuntu-toolchain-r-test - - - os: linux - dist: trusty - compiler: g++-8 - env: TOOLSET=gcc COMPILER=g++-8 CXXSTD=14,17 - addons: - apt: - packages: + dist: bionic + env: + - B2_TOOLSET=gcc-8 + - "B2_CXXSTD=cxxstd=03,11" + - B2_DEFINES='define=BOOST_NO_STRESS_TEST=1' + name: codecov.io + os: linux + script: + - "pushd /tmp && git clone https://github.com/linux-test-project/lcov.git && export PATH=/tmp/lcov/bin:$PATH && which lcov && lcov --version && popd" + - utility/ci/codecov/coverage.sh + stage: Dynamic_QC + - + addons: + apt: + packages: - g++-8 - sources: + - gcc-8-multilib + - g++-8-multilib + - gcc-multilib + - g++-multilib + sources: - ubuntu-toolchain-r-test - - - os: linux - env: TOOLSET=clang COMPILER=clang++ CXXSTD=03,11 - - - os: linux - env: TOOLSET=clang COMPILER=clang++-3.5 CXXSTD=03,11 - addons: - apt: - packages: - - clang-3.5 - sources: + dist: bionic + env: + - COMMENT=ubsan + - "B2_ADDRESS_MODEL=address-model=32" + - B2_VARIANT=variant=debug + - B2_TOOLSET=gcc-8 + - "B2_CXXSTD=cxxstd=03" + - B2_DEFINES='define=BOOST_NO_STRESS_TEST=1' + - "COPTS=cxxflags=-fno-omit-frame-pointer -fsanitize=undefined -fno-sanitize-recover=all" + - "LOPTS=linkflags=-fsanitize=undefined -fno-sanitize-recover=all -fuse-ld=gold" + - UBSAN_OPTIONS='print_stacktrace=1' + name: "x86 C++03 Undefined behavior sanitizer" + os: linux + stage: Dynamic_QC + - + addons: + apt: + packages: + - g++-8 + - gcc-8-multilib + - g++-8-multilib + - gcc-multilib + - g++-multilib + sources: - ubuntu-toolchain-r-test - - llvm-toolchain-precise-3.5 - - - os: linux - env: TOOLSET=clang COMPILER=clang++-3.6 CXXSTD=03,11 - addons: - apt: - packages: - - clang-3.6 - sources: + dist: bionic + env: + - COMMENT=ubsan + - "B2_ADDRESS_MODEL=address-model=32" + - B2_VARIANT=variant=debug + - B2_TOOLSET=gcc-8 + - "B2_CXXSTD=cxxstd=11" + - B2_DEFINES='define=BOOST_NO_STRESS_TEST=1' + - "COPTS=cxxflags=-fno-omit-frame-pointer -fsanitize=undefined -fno-sanitize-recover=all" + - "LOPTS=linkflags=-fsanitize=undefined -fno-sanitize-recover=all -fuse-ld=gold" + - UBSAN_OPTIONS='print_stacktrace=1' + name: "x86 C++11 Undefined behavior sanitizer" + os: linux + stage: Dynamic_QC + - + addons: + apt: + packages: + - g++-8 + - gcc-8-multilib + - g++-8-multilib + - gcc-multilib + - g++-multilib + sources: - ubuntu-toolchain-r-test - - llvm-toolchain-precise-3.6 - - - os: linux - env: TOOLSET=clang COMPILER=clang++-3.7 CXXSTD=03,11 - addons: - apt: - packages: - - clang-3.7 - sources: + dist: bionic + env: + - COMMENT=ubsan + - "B2_ADDRESS_MODEL=address-model=32" + - B2_VARIANT=variant=debug + - B2_TOOLSET=gcc-8 + - "B2_CXXSTD=cxxstd=14" + - B2_DEFINES='define=BOOST_NO_STRESS_TEST=1' + - "COPTS=cxxflags=-fno-omit-frame-pointer -fsanitize=undefined -fno-sanitize-recover=all" + - "LOPTS=linkflags=-fsanitize=undefined -fno-sanitize-recover=all -fuse-ld=gold" + - UBSAN_OPTIONS='print_stacktrace=1' + name: "x86 C++14 Undefined behavior sanitizer" + os: linux + stage: Dynamic_QC + - + addons: + apt: + packages: + - g++-8 + - gcc-8-multilib + - g++-8-multilib + - gcc-multilib + - g++-multilib + sources: - ubuntu-toolchain-r-test - - llvm-toolchain-precise-3.7 - - # Fails to compile std lib headers (toolset issue): - #- os: linux - # env: TOOLSET=clang COMPILER=clang++-3.8 CXXSTD=03,11,14,1z - # addons: - # apt: - # packages: - # - clang-3.8 - # sources: - # - ubuntu-toolchain-r-test - # - llvm-toolchain-precise-3.8 - # - #- os: linux - # env: TOOLSET=clang COMPILER=clang++-3.9 CXXSTD=03,11,14,1z - # addons: - # apt: - # packages: - # - clang-3.9 - # sources: - # - ubuntu-toolchain-r-test - # - llvm-toolchain-precise-3.9 - - - os: linux - compiler: clang++-4.0 - env: TOOLSET=clang COMPILER=clang++-4.0 CXXSTD=03,11,1z - addons: - apt: - packages: - - clang-4.0 - sources: + dist: bionic + env: + - COMMENT=ubsan + - "B2_ADDRESS_MODEL=address-model=32" + - B2_VARIANT=variant=debug + - B2_TOOLSET=gcc-8 + - "B2_CXXSTD=cxxstd=17" + - B2_DEFINES='define=BOOST_NO_STRESS_TEST=1' + - "COPTS=cxxflags=-fno-omit-frame-pointer -fsanitize=undefined -fno-sanitize-recover=all" + - "LOPTS=linkflags=-fsanitize=undefined -fno-sanitize-recover=all -fuse-ld=gold" + - UBSAN_OPTIONS='print_stacktrace=1' + name: "x86 C++17 Undefined behavior sanitizer" + os: linux + stage: Dynamic_QC + - + addons: + apt: + packages: + - g++-8 + - gcc-8-multilib + - g++-8-multilib + - gcc-multilib + - g++-multilib + sources: - ubuntu-toolchain-r-test - - llvm-toolchain-trusty-4.0 - - - os: linux - compiler: clang++-5.0 - env: TOOLSET=clang COMPILER=clang++-5.0 CXXSTD=03,11 - addons: - apt: - packages: - - clang-5.0 - sources: + dist: bionic + env: + - COMMENT=ubsan + - "B2_ADDRESS_MODEL=address-model=32" + - B2_VARIANT=variant=debug + - B2_TOOLSET=gcc-8 + - "B2_CXXSTD=cxxstd=2a" + - B2_DEFINES='define=BOOST_NO_STRESS_TEST=1' + - "COPTS=cxxflags=-fno-omit-frame-pointer -fsanitize=undefined -fno-sanitize-recover=all" + - "LOPTS=linkflags=-fsanitize=undefined -fno-sanitize-recover=all -fuse-ld=gold" + - UBSAN_OPTIONS='print_stacktrace=1' + name: "x86 C++2a Undefined behavior sanitizer" + os: linux + stage: Dynamic_QC + - + addons: + apt: + packages: + - g++-8 + sources: - ubuntu-toolchain-r-test - - llvm-toolchain-trusty-5.0 - - - os: linux - compiler: clang++-5.0 - env: TOOLSET=clang COMPILER=clang++-5.0 CXXSTD=14,1z - addons: - apt: - packages: - - clang-5.0 - sources: + dist: bionic + env: + - COMMENT=ubsan + - "B2_ADDRESS_MODEL=address-model=64" + - B2_VARIANT=variant=debug + - B2_TOOLSET=gcc-8 + - "B2_CXXSTD=cxxstd=03" + - B2_DEFINES='define=BOOST_NO_STRESS_TEST=1' + - "COPTS=cxxflags=-fno-omit-frame-pointer -fsanitize=undefined -fno-sanitize-recover=all" + - "LOPTS=linkflags=-fsanitize=undefined -fno-sanitize-recover=all -fuse-ld=gold" + - UBSAN_OPTIONS='print_stacktrace=1' + name: "x86_64 C++03 Undefined behavior sanitizer" + os: linux + stage: Dynamic_QC + - + addons: + apt: + packages: + - g++-8 + sources: + - ubuntu-toolchain-r-test + dist: bionic + env: + - COMMENT=ubsan + - "B2_ADDRESS_MODEL=address-model=64" + - B2_VARIANT=variant=debug + - B2_TOOLSET=gcc-8 + - "B2_CXXSTD=cxxstd=11" + - B2_DEFINES='define=BOOST_NO_STRESS_TEST=1' + - "COPTS=cxxflags=-fno-omit-frame-pointer -fsanitize=undefined -fno-sanitize-recover=all" + - "LOPTS=linkflags=-fsanitize=undefined -fno-sanitize-recover=all -fuse-ld=gold" + - UBSAN_OPTIONS='print_stacktrace=1' + name: "x86_64 C++11 Undefined behavior sanitizer" + os: linux + stage: Dynamic_QC + - + addons: + apt: + packages: + - g++-8 + sources: + - ubuntu-toolchain-r-test + dist: bionic + env: + - COMMENT=ubsan + - "B2_ADDRESS_MODEL=address-model=64" + - B2_VARIANT=variant=debug + - B2_TOOLSET=gcc-8 + - "B2_CXXSTD=cxxstd=14" + - B2_DEFINES='define=BOOST_NO_STRESS_TEST=1' + - "COPTS=cxxflags=-fno-omit-frame-pointer -fsanitize=undefined -fno-sanitize-recover=all" + - "LOPTS=linkflags=-fsanitize=undefined -fno-sanitize-recover=all -fuse-ld=gold" + - UBSAN_OPTIONS='print_stacktrace=1' + name: "x86_64 C++14 Undefined behavior sanitizer" + os: linux + stage: Dynamic_QC + - + addons: + apt: + packages: + - g++-8 + sources: - ubuntu-toolchain-r-test - - llvm-toolchain-trusty-5.0 - - - os: osx - env: TOOLSET=clang COMPILER=clang++ CXXSTD=03 - osx_image: xcode7.3 - - - os: osx - env: TOOLSET=clang COMPILER=clang++ CXXSTD=11 - osx_image: xcode7.3 - - - os: osx - env: TOOLSET=clang COMPILER=clang++ CXXSTD=14,1z - osx_image: xcode7.3 - - - os: osx - env: TOOLSET=clang COMPILER=clang++ CXXSTD=03 - osx_image: xcode8.3 - - - os: osx - env: TOOLSET=clang COMPILER=clang++ CXXSTD=11 - osx_image: xcode8.3 - - - os: osx - env: TOOLSET=clang COMPILER=clang++ CXXSTD=14,1z - osx_image: xcode8.3 - - - os: osx - env: TOOLSET=clang COMPILER=clang++ CXXSTD=03 - osx_image: xcode9.4.1 - - - os: osx - env: TOOLSET=clang COMPILER=clang++ CXXSTD=11 - osx_image: xcode9.4.1 - - - os: osx - env: TOOLSET=clang COMPILER=clang++ CXXSTD=14,1z - osx_image: xcode9.4.1 - - -install: - - BOOST_BRANCH=develop && [ "$TRAVIS_BRANCH" == "master" ] && BOOST_BRANCH=master || true - - cd .. - - git clone -b $BOOST_BRANCH --depth 1 https://github.com/boostorg/boost.git boost-root - - cd boost-root - - git submodule update --init tools/boost_install - - git submodule update --init libs/headers - - git submodule update --init tools/build - - git submodule update --init libs/config - - git submodule update --init tools/boostdep - - cp -r $TRAVIS_BUILD_DIR/* libs/graph - - python tools/boostdep/depinst/depinst.py graph - - ./bootstrap.sh - - ./b2 headers - - -script: - - |- - echo "using $TOOLSET : : $COMPILER ;" > ~/user-config.jam - - IFS=',' - - for CXXLOCAL in $CXXSTD; do (cd libs/config/test && ../../../b2 config_info_travis_install toolset=$TOOLSET cxxstd=$CXXLOCAL && ./config_info_travis && rm ./config_info_travis) done - - unset IFS - - ./b2 -j3 libs/graph/test toolset=$TOOLSET cxxstd=$CXXSTD - -notifications: - email: - on_success: always + dist: bionic + env: + - COMMENT=ubsan + - "B2_ADDRESS_MODEL=address-model=64" + - B2_VARIANT=variant=debug + - B2_TOOLSET=gcc-8 + - "B2_CXXSTD=cxxstd=17" + - B2_DEFINES='define=BOOST_NO_STRESS_TEST=1' + - "COPTS=cxxflags=-fno-omit-frame-pointer -fsanitize=undefined -fno-sanitize-recover=all" + - "LOPTS=linkflags=-fsanitize=undefined -fno-sanitize-recover=all -fuse-ld=gold" + - UBSAN_OPTIONS='print_stacktrace=1' + name: "x86_64 C++17 Undefined behavior sanitizer" + os: linux + stage: Dynamic_QC + - + addons: + apt: + packages: + - g++-8 + sources: + - ubuntu-toolchain-r-test + dist: bionic + env: + - COMMENT=ubsan + - "B2_ADDRESS_MODEL=address-model=64" + - B2_VARIANT=variant=debug + - B2_TOOLSET=gcc-8 + - "B2_CXXSTD=cxxstd=2a" + - B2_DEFINES='define=BOOST_NO_STRESS_TEST=1' + - "COPTS=cxxflags=-fno-omit-frame-pointer -fsanitize=undefined -fno-sanitize-recover=all" + - "LOPTS=linkflags=-fsanitize=undefined -fno-sanitize-recover=all -fuse-ld=gold" + - UBSAN_OPTIONS='print_stacktrace=1' + name: "x86_64 C++2a Undefined behavior sanitizer" + os: linux + stage: Dynamic_QC + - + addons: + apt: + packages: + - g++-8 + - gcc-8-multilib + - g++-8-multilib + - gcc-multilib + - g++-multilib + - valgrind + - libc6-dbg:i386 + sources: + - ubuntu-toolchain-r-test + dist: bionic + env: + - COMMENT=valgrind + - "B2_ADDRESS_MODEL=address-model=32" + - B2_VARIANT=variant=debug + - B2_TOOLSET=gcc-8 + - "B2_CXXSTD=cxxstd=03" + - B2_DEFINES='define=BOOST_NO_STRESS_TEST=1' + - B2_TESTFLAGS=testing.launcher=valgrind + - "COPTS=cxxflags=-O2" + - VALGRIND_OPTS=--error-exitcode=1 + name: "x86 C++03 Valgrind" + os: linux + before_install: utility/ci/travis/valgrind.sh + stage: Dynamic_QC + - + addons: + apt: + packages: + - g++-8 + - gcc-8-multilib + - g++-8-multilib + - gcc-multilib + - g++-multilib + - valgrind + - libc6-dbg:i386 + sources: + - ubuntu-toolchain-r-test + dist: bionic + env: + - COMMENT=valgrind + - "B2_ADDRESS_MODEL=address-model=32" + - B2_VARIANT=variant=debug + - B2_TOOLSET=gcc-8 + - "B2_CXXSTD=cxxstd=11" + - B2_DEFINES='define=BOOST_NO_STRESS_TEST=1' + - B2_TESTFLAGS=testing.launcher=valgrind + - "COPTS=cxxflags=-O2" + - VALGRIND_OPTS=--error-exitcode=1 + name: "x86 C++11 Valgrind" + os: linux + before_install: utility/ci/travis/valgrind.sh + stage: Dynamic_QC + - + addons: + apt: + packages: + - g++-8 + - gcc-8-multilib + - g++-8-multilib + - gcc-multilib + - g++-multilib + - valgrind + - libc6-dbg:i386 + sources: + - ubuntu-toolchain-r-test + dist: bionic + env: + - COMMENT=valgrind + - "B2_ADDRESS_MODEL=address-model=32" + - B2_VARIANT=variant=debug + - B2_TOOLSET=gcc-8 + - "B2_CXXSTD=cxxstd=14" + - B2_DEFINES='define=BOOST_NO_STRESS_TEST=1' + - B2_TESTFLAGS=testing.launcher=valgrind + - "COPTS=cxxflags=-O2" + - VALGRIND_OPTS=--error-exitcode=1 + name: "x86 C++14 Valgrind" + os: linux + before_install: utility/ci/travis/valgrind.sh + stage: Dynamic_QC + - + addons: + apt: + packages: + - g++-8 + - gcc-8-multilib + - g++-8-multilib + - gcc-multilib + - g++-multilib + - valgrind + - libc6-dbg:i386 + sources: + - ubuntu-toolchain-r-test + dist: bionic + env: + - COMMENT=valgrind + - "B2_ADDRESS_MODEL=address-model=32" + - B2_VARIANT=variant=debug + - B2_TOOLSET=gcc-8 + - "B2_CXXSTD=cxxstd=17" + - B2_DEFINES='define=BOOST_NO_STRESS_TEST=1' + - B2_TESTFLAGS=testing.launcher=valgrind + - "COPTS=cxxflags=-O2" + - VALGRIND_OPTS=--error-exitcode=1 + name: "x86 C++17 Valgrind" + os: linux + before_install: utility/ci/travis/valgrind.sh + stage: Dynamic_QC + - + addons: + apt: + packages: + - g++-8 + - gcc-8-multilib + - g++-8-multilib + - gcc-multilib + - g++-multilib + - valgrind + - libc6-dbg:i386 + sources: + - ubuntu-toolchain-r-test + dist: bionic + env: + - COMMENT=valgrind + - "B2_ADDRESS_MODEL=address-model=32" + - B2_VARIANT=variant=debug + - B2_TOOLSET=gcc-8 + - "B2_CXXSTD=cxxstd=2a" + - B2_DEFINES='define=BOOST_NO_STRESS_TEST=1' + - B2_TESTFLAGS=testing.launcher=valgrind + - "COPTS=cxxflags=-O2" + - VALGRIND_OPTS=--error-exitcode=1 + name: "x86 C++2a Valgrind" + os: linux + before_install: utility/ci/travis/valgrind.sh + stage: Dynamic_QC + - + addons: + apt: + packages: + - g++-8 + - valgrind + - libc6-dbg + sources: + - ubuntu-toolchain-r-test + dist: bionic + env: + - COMMENT=valgrind + - "B2_ADDRESS_MODEL=address-model=64" + - B2_VARIANT=variant=debug + - B2_TOOLSET=gcc-8 + - "B2_CXXSTD=cxxstd=03" + - B2_DEFINES='define=BOOST_NO_STRESS_TEST=1' + - B2_TESTFLAGS=testing.launcher=valgrind + - "COPTS=cxxflags=-O2" + - VALGRIND_OPTS=--error-exitcode=1 + name: "x86_64 C++03 Valgrind" + os: linux + before_install: utility/ci/travis/valgrind.sh + stage: Dynamic_QC + - + addons: + apt: + packages: + - g++-8 + - valgrind + - libc6-dbg + sources: + - ubuntu-toolchain-r-test + dist: bionic + env: + - COMMENT=valgrind + - "B2_ADDRESS_MODEL=address-model=64" + - B2_VARIANT=variant=debug + - B2_TOOLSET=gcc-8 + - "B2_CXXSTD=cxxstd=11" + - B2_DEFINES='define=BOOST_NO_STRESS_TEST=1' + - B2_TESTFLAGS=testing.launcher=valgrind + - "COPTS=cxxflags=-O2" + - VALGRIND_OPTS=--error-exitcode=1 + name: "x86_64 C++11 Valgrind" + os: linux + before_install: utility/ci/travis/valgrind.sh + stage: Dynamic_QC + - + addons: + apt: + packages: + - g++-8 + - valgrind + - libc6-dbg + sources: + - ubuntu-toolchain-r-test + dist: bionic + env: + - COMMENT=valgrind + - "B2_ADDRESS_MODEL=address-model=64" + - B2_VARIANT=variant=debug + - B2_TOOLSET=gcc-8 + - "B2_CXXSTD=cxxstd=14" + - B2_DEFINES='define=BOOST_NO_STRESS_TEST=1' + - B2_TESTFLAGS=testing.launcher=valgrind + - "COPTS=cxxflags=-O2" + - VALGRIND_OPTS=--error-exitcode=1 + name: "x86_64 C++14 Valgrind" + os: linux + before_install: utility/ci/travis/valgrind.sh + stage: Dynamic_QC + - + addons: + apt: + packages: + - g++-8 + - valgrind + - libc6-dbg + sources: + - ubuntu-toolchain-r-test + dist: bionic + env: + - COMMENT=valgrind + - "B2_ADDRESS_MODEL=address-model=64" + - B2_VARIANT=variant=debug + - B2_TOOLSET=gcc-8 + - "B2_CXXSTD=cxxstd=17" + - B2_DEFINES='define=BOOST_NO_STRESS_TEST=1' + - B2_TESTFLAGS=testing.launcher=valgrind + - "COPTS=cxxflags=-O2" + - VALGRIND_OPTS=--error-exitcode=1 + name: "x86_64 C++17 Valgrind" + os: linux + before_install: utility/ci/travis/valgrind.sh + stage: Dynamic_QC + - + addons: + apt: + packages: + - g++-8 + - valgrind + - libc6-dbg + sources: + - ubuntu-toolchain-r-test + dist: bionic + env: + - COMMENT=valgrind + - "B2_ADDRESS_MODEL=address-model=64" + - B2_VARIANT=variant=debug + - B2_TOOLSET=gcc-8 + - "B2_CXXSTD=cxxstd=2a" + - B2_DEFINES='define=BOOST_NO_STRESS_TEST=1' + - B2_TESTFLAGS=testing.launcher=valgrind + - "COPTS=cxxflags=-O2" + - VALGRIND_OPTS=--error-exitcode=1" + name: "x86_64 C++2a Valgrind" + os: linux + before_install: utility/ci/travis/valgrind.sh + stage: Dynamic_QC + - + dist: bionic + env: + - "COMMENT='Coverity Scan'" + - B2_TOOLSET=clang-6.0 + - "COPTS=cxxflags=-Weverything -Werror -fstack-protector-all -fstack-check-lubsan -fPIC -fsanitize=address -fsanitize=pointer-compare -fsanitize=leak -fsanitize-coverage=trace-pc -fsanitize-coverage=trace-cmp -fcf-protection=full -fvtable-verify=std -lasan -llsan -fsanitize=undefined -fsanitize-address-use-after-scope -fvtv-debug" + - "LOPTS=linkflags=-lubsan -fPIC -llsan -lasan" + name: "Coverty" + os: linux + script: utility/ci/coverty/coverage.sh + stage: Dynamic_QC +language: cpp +notifications: + email: false +script: "source utility/ci/travis/build.sh" +stages: + - Static_QC + - Dynamic_QC + - test diff --git a/README.md b/README.md index 7a4dc7355..d63f5f40b 100644 --- a/README.md +++ b/README.md @@ -18,24 +18,24 @@ There is no mailing-list specific to Boost Graph, although you can use the gener ## Development ## -Clone the whole boost project, which includes the individual Boost projects as submodules ([see boost+git doc](https://github.com/boostorg/boost/wiki/Getting-Started)): +Clone the whole boost project, which includes the individual Boost projects as submodules ([see boost+git doc](https://github.com/boostorg/boost/wiki/Getting-Started)): git clone https://github.com/boostorg/boost cd boost git submodule update --init -The Boost Graph Library is located in `libs/graph/`. +The Boost Graph Library is located in `libs/graph/`. Boost Graph Library is mostly made of headers but also contains some compiled components. Here are the build commands: - - ./bootstrap.sh <- compile b2 + + ./bootstrap.sh <- compile b2 ./b2 headers <- just installs headers ./b2 <- build compiled components **Note:** The Boost Graph Library cannot currently be built outside of Boost itself. ### Running tests ### -First, make sure you are in `libs/graph/test`. +First, make sure you are in `libs/graph/test`. You can either run all the 300+ tests listed in `Jamfile.v2` or run a single test: ../../../b2 <- run all tests diff --git a/doc/AStarHeuristic.html b/doc/AStarHeuristic.html index dbe2132d6..b035a2825 100644 --- a/doc/AStarHeuristic.html +++ b/doc/AStarHeuristic.html @@ -1,17 +1,17 @@ Boost Graph Library: AStarHeuristic - -C++ Boost + +C++ Boost
@@ -135,4 +135,4 @@

Concept Checking Class

- + diff --git a/doc/AStarVisitor.html b/doc/AStarVisitor.html index ba4ac92e7..bf11b9d94 100644 --- a/doc/AStarVisitor.html +++ b/doc/AStarVisitor.html @@ -1,17 +1,17 @@ Boost Graph Library: AStarVisitor - -C++ Boost + +C++ Boost
@@ -210,4 +210,4 @@

See also

- + diff --git a/doc/AddEdgeVisitor.html b/doc/AddEdgeVisitor.html index 7f924d2e0..3cbc48170 100644 --- a/doc/AddEdgeVisitor.html +++ b/doc/AddEdgeVisitor.html @@ -1,21 +1,21 @@ AddEdgeVisitor Concept - + -C++ Boost +C++ Boost
@@ -23,7 +23,7 @@

AddEdgeVisitor Concept

The AddEdgeVisitor concept exists to allow for some indirection in algorithms that modify graphs by adding edges. In such algorithms, it may be convenient -to perform additional operations (such as updating an edge index map) at +to perform additional operations (such as updating an edge index map) at points in the algorithm where an edge addition occurs. Replacing calls to to add_edge with calls to AddEdgeVisitor::visit_vertex_pair allows for such operations to be defined independently from the algorithm. @@ -38,8 +38,8 @@

Notation

is a type that models the AddEdgeVisitor concept - - vis + + vis is an object of type Visitor @@ -48,15 +48,15 @@

Notation

is the type of a graph - - u,v + + u,v are objects of type graph_traits<Graph>::vertex_descriptor - - e - is an object of type graph_traits<Graph>::edge_descriptor + + e + is an object of type graph_traits<Graph>::edge_descriptor @@ -66,7 +66,7 @@

Notation

- + @@ -84,7 +84,7 @@

Valid Expressions

NameExpressionReturn Type Description - + Add an Edge vis.visit_vertex_pair(u, v, g) void @@ -96,26 +96,26 @@

Valid Expressions

Models

-Two models of this concept are defined in the file +Two models of this concept are defined in the file add_edge_visitors.hpp: @@ -125,6 +125,6 @@

Valid Expressions



Copyright © 2007 Aaron Windsor ( -aaron.windsor@gmail.com) +aaron.windsor@gmail.com) diff --git a/doc/AdjacencyGraph.html b/doc/AdjacencyGraph.html index efe6a891f..eb9a2033e 100644 --- a/doc/AdjacencyGraph.html +++ b/doc/AdjacencyGraph.html @@ -1,17 +1,17 @@ AdjacencyGraph - -C++ Boost + +C++ Boost
@@ -164,4 +164,4 @@

Notes

- + diff --git a/doc/AdjacencyMatrix.html b/doc/AdjacencyMatrix.html index e3c182500..a77a0aea5 100644 --- a/doc/AdjacencyMatrix.html +++ b/doc/AdjacencyMatrix.html @@ -1,17 +1,17 @@ AdjacencyMatrix - -C++ Boost + +C++ Boost
@@ -100,4 +100,4 @@

Concept Checking Class

- + diff --git a/doc/BFSVisitor.html b/doc/BFSVisitor.html index 1effc11cb..1f4241f53 100644 --- a/doc/BFSVisitor.html +++ b/doc/BFSVisitor.html @@ -1,17 +1,17 @@ Boost Graph Library: BFSVisitor - -C++ Boost + +C++ Boost
@@ -142,7 +142,7 @@

Valid Expressions

This is invoked on the subset of non-tree edges whose target vertex is colored gray at the time of examination. The color gray indicates -that the vertex is currently in the queue. +that the vertex is currently in the queue. @@ -217,4 +217,4 @@

See also

- + diff --git a/doc/BasicMatrix.html b/doc/BasicMatrix.html index 00ba171e4..589bf5991 100644 --- a/doc/BasicMatrix.html +++ b/doc/BasicMatrix.html @@ -1,17 +1,17 @@ BasicMatrix - -C++ Boost + +C++ Boost
@@ -78,11 +78,11 @@

Concept Checking Class

void constraints() { V& elt = A[i][j]; const_constraints(A); - ignore_unused_variable_warning(elt); + ignore_unused_variable_warning(elt); } void const_constraints(const M& A) { const V& elt = A[i][j]; - ignore_unused_variable_warning(elt); + ignore_unused_variable_warning(elt); } M A; I i, j; @@ -100,4 +100,4 @@

Concept Checking Class

- + diff --git a/doc/BellmanFordVisitor.html b/doc/BellmanFordVisitor.html index 30a896b1f..37188e63c 100644 --- a/doc/BellmanFordVisitor.html +++ b/doc/BellmanFordVisitor.html @@ -1,17 +1,17 @@ Boost Graph Library: Bellman Ford Visitor - -C++ Boost + +C++ Boost
@@ -181,4 +181,4 @@

Python

- + diff --git a/doc/BidirectionalGraph.html b/doc/BidirectionalGraph.html index e5b551e01..f897c4297 100644 --- a/doc/BidirectionalGraph.html +++ b/doc/BidirectionalGraph.html @@ -1,17 +1,17 @@ Bidirectional - -C++ Boost + +C++ Boost
@@ -177,4 +177,4 @@

Concept Checking Class

- + diff --git a/doc/Buffer.html b/doc/Buffer.html index 58dc0e710..cba8b4579 100644 --- a/doc/Buffer.html +++ b/doc/Buffer.html @@ -1,7 +1,7 @@ Boost Graph Library: ColorValue Concept - -C++ Boost + +C++ Boost
@@ -105,4 +105,4 @@

Models

- + diff --git a/doc/DFSVisitor.html b/doc/DFSVisitor.html index fb0bed6d4..54483b9cc 100644 --- a/doc/DFSVisitor.html +++ b/doc/DFSVisitor.html @@ -1,17 +1,17 @@ DFS Visitor - -C++ Boost + +C++ Boost
@@ -150,15 +150,15 @@

Valid Expressions

-Finish Edge -vis.finish_edge(e, g) -void - -This is invoked on each non-tree edge as well as on each tree edge after -finish_vertex has been called on its target vertex. - - - +Finish Edge +vis.finish_edge(e, g) +void + +This is invoked on each non-tree edge as well as on each tree edge after +finish_vertex has been called on its target vertex. + + + Finish Vertex vis.finish_vertex(u, g) void @@ -218,4 +218,4 @@

Python

- + diff --git a/doc/DijkstraVisitor.html b/doc/DijkstraVisitor.html index 43e82803b..90d0fafdb 100644 --- a/doc/DijkstraVisitor.html +++ b/doc/DijkstraVisitor.html @@ -1,17 +1,17 @@ Boost Graph Library: Dijkstra Visitor - -C++ Boost + +C++ Boost
@@ -219,4 +219,4 @@

Python

- + diff --git a/doc/EdgeListGraph.html b/doc/EdgeListGraph.html index fc62539c0..70c33ccdf 100644 --- a/doc/EdgeListGraph.html +++ b/doc/EdgeListGraph.html @@ -1,17 +1,17 @@ EdgeListGraph - -C++ Boost + +C++ Boost
@@ -109,7 +109,7 @@

Valid Expressions

target(e, g) -Returns the vertex descriptor for +Returns the vertex descriptor for v of the edge (u,v) represented by e.
Return type: vertex_descriptor @@ -143,7 +143,7 @@

Concept Checking Class

template <class G> struct EdgeListGraphConcept { - typedef typename boost::graph_traits<G>::edge_iterator + typedef typename boost::graph_traits<G>::edge_iterator edge_iterator; void constraints() { BOOST_CONCEPT_ASSERT(( GraphConcept<G> )); @@ -181,4 +181,4 @@

Concept Checking Class

- + diff --git a/doc/EdgeMutableGraph.html b/doc/EdgeMutableGraph.html index 8429f0c52..594406653 100644 --- a/doc/EdgeMutableGraph.html +++ b/doc/EdgeMutableGraph.html @@ -1,17 +1,17 @@ Edge Mutable Graph - -C++ Boost + +C++ Boost
@@ -35,7 +35,7 @@

Valid Expressions

@@ -54,7 +54,7 @@

parameters is separated by a period, not a comma.
-  bool r = boost::bellman_ford_shortest_paths(g, int(N), 
+  bool r = boost::bellman_ford_shortest_paths(g, int(N),
      boost::weight_map(weight).
      distance_map(&distance[0]).
      predecessor_map(&parent[0]));
@@ -66,7 +66,7 @@ 

the one above.
-  bool r = boost::bellman_ford_shortest_paths(g, int(N), 
+  bool r = boost::bellman_ford_shortest_paths(g, int(N),
      boost::predecessor_map(&parent[0]).
      distance_map(&distance[0]).
      weight_map(weight));
diff --git a/doc/bibliography.html b/doc/bibliography.html
index 4e59de852..b541abf62 100644
--- a/doc/bibliography.html
+++ b/doc/bibliography.html
@@ -1,17 +1,17 @@
 
 
 
 Boost Graph Library: Bibliography
- 
-C++ Boost 
+
+C++ Boost
 
 
@@ -264,7 +264,7 @@

Bibliography

42
David Eppstein, Zvi Galil, and Giuseppe F. Italiano
Dynamic Graph Algorithms.
-Chapter 22, CRC Handbook of Algorithms and Theory of Computation, 1997. +Chapter 22, CRC Handbook of Algorithms and Theory of Computation, 1997.

43
E. Cuthill and J. McKee
@@ -330,7 +330,7 @@

Bibliography

54
Ulrik Brandes
-A +A Faster Algorithm for Betweenness Centrality
Journal of Mathematical Sociology 25 (2):163-177, 2001. @@ -347,7 +347,7 @@

Bibliography

57
T. Kamada and S. Kawai
An algorithm for drawing general undirected graphs.
-Information Processing Letters, 31, pp. 7-15, 1989. +Information Processing Letters, 31, pp. 7-15, 1989.

58
T. Fruchterman and E. Reingold
@@ -454,7 +454,7 @@

Bibliography

Proceedings of the First Annual ACM-SIAM Symposium on Discrete Algorithms, pp. 434-443, 1990. - +

@@ -464,4 +464,4 @@

Bibliography

- + diff --git a/doc/biconnected_components.html b/doc/biconnected_components.html index 298b70089..894e984cc 100644 --- a/doc/biconnected_components.html +++ b/doc/biconnected_components.html @@ -1,21 +1,21 @@ Boost Graph Library: Biconnected Components and Articulation Points - -C++ Boost + +C++ Boost
@@ -25,7 +25,7 @@

biconnected_components -and +and articulation_points

@@ -34,25 +34,25 @@

template <typename Graph, typename ComponentMap, typename OutputIterator, typename P, typename T, typename R> std::pair<std::size_t, OutputIterator> -biconnected_components(const Graph& g, ComponentMap comp, OutputIterator out, +biconnected_components(const Graph& g, ComponentMap comp, OutputIterator out, const bgl_named_params<P, T, R>& params) template <typename Graph, typename ComponentMap, typename P, typename T, typename R> std::size_t -biconnected_components(const Graph& g, ComponentMap comp, +biconnected_components(const Graph& g, ComponentMap comp, const bgl_named_params<P, T, R>& params) -template <typename Graph, typename OutputIterator, +template <typename Graph, typename OutputIterator, typename P, typename T, typename R> -OutputIterator articulation_points(const Graph& g, OutputIterator out, +OutputIterator articulation_points(const Graph& g, OutputIterator out, const bgl_named_params<P, T, R>& params) // non-named parameter version template <typename Graph, typename ComponentMap, typename OutputIterator, typename DiscoverTimeMap, typename LowPointMap> std::pair<std::size_t, OutputIterator> -biconnected_components(const Graph& g, ComponentMap comp, OutputIterator out, +biconnected_components(const Graph& g, ComponentMap comp, OutputIterator out, DiscoverTimeMap discover_time, LowPointMap lowpt); template <typename Graph, typename ComponentMap, typename OutputIterator> @@ -142,10 +142,10 @@

Parameters

Named Parameters

-IN: vertex_index_map(VertexIndexMap i_map) +IN: vertex_index_map(VertexIndexMap i_map)
This maps each vertex to an integer in the range [0, - num_vertices(g)). The type + num_vertices(g)). The type VertexIndexMap must be a model of Readable Property Map. The value type of the map must be an integer type. The vertex descriptor type of the graph needs to be @@ -192,9 +192,9 @@

Named Parameters

Python: Unsupported parameter.
-UTIL/OUT: predecessor_map(PredecessorMap p_map) +UTIL/OUT: predecessor_map(PredecessorMap p_map)
- The predecessor map records the depth first search tree. + The predecessor map records the depth first search tree. The PredecessorMap type must be a Read/Write @@ -241,7 +241,7 @@

Example

Notes

-

[1] +

[1] Since the visitor parameter is passed by value, if your visitor contains state then any changes to the state during the algorithm will be made to a copy of the visitor object, not the visitor object @@ -260,4 +260,4 @@

Notes

- + diff --git a/doc/biconnected_components.w b/doc/biconnected_components.w index d2eb21ffd..df6c3c2b3 100644 --- a/doc/biconnected_components.w +++ b/doc/biconnected_components.w @@ -5,7 +5,7 @@ \usepackage{amsfonts} \usepackage{amssymb} \usepackage{amsthm} -\usepackage{latexsym} +\usepackage{latexsym} \usepackage{jweb} \usepackage{times} \usepackage{graphicx} @@ -358,7 +358,7 @@ int main() -% \paragraph{Definition.} A \emph{palm tree} $P$ is a directed graph that +% \paragraph{Definition.} A \emph{palm tree} $P$ is a directed graph that % consists of two disjoint sets of edges, denoted by $v \rightarrow w$ % and $v \backedge w$ respectively, with the following properties: diff --git a/doc/boyer_myrvold.html b/doc/boyer_myrvold.html index a2792a30c..df4574f7c 100644 --- a/doc/boyer_myrvold.html +++ b/doc/boyer_myrvold.html @@ -1,39 +1,39 @@ Boost Graph Library: Boyer-Myrvold Planarity Testing/Embedding - -C++ Boost + +C++ Boost

Boyer-Myrvold Planarity Testing/Embedding

-A graph is planar if it can -be drawn in two-dimensional space without any of its edges crossing. Such a -drawing of a planar graph is called a -plane drawing. Each +A graph is planar if it can +be drawn in two-dimensional space without any of its edges crossing. Such a +drawing of a planar graph is called a +plane drawing. Each plane drawing belongs to an equivalence class called a planar embedding -[1] that is defined by the clockwise ordering of adjacent -edges around each vertex in the graph. A planar embedding is a convenient -intermediate representation of an actual drawing of a planar graph, and many -planar graph drawing algorithms are formulated as functions mapping a planar +[1] that is defined by the clockwise ordering of adjacent +edges around each vertex in the graph. A planar embedding is a convenient +intermediate representation of an actual drawing of a planar graph, and many +planar graph drawing algorithms are formulated as functions mapping a planar embedding to a plane drawing.

-
A planar graph (top left), along with a planar -embedding of that graph (bottom left) can be used to create a plane drawing -(right) by embedding edges around each vertex in the order in which they +
A planar graph (top left), along with a planar +embedding of that graph (bottom left) can be used to create a plane drawing +(right) by embedding edges around each vertex in the order in which they appear in the planar embedding.
@@ -44,16 +44,16 @@

Boyer-Myrvold Planarity Testing/Embedding


-The function boyer_myrvold_planarity_test implements the planarity -testing/embedding algorithm of Boyer and Myrvold +The function boyer_myrvold_planarity_test implements the planarity +testing/embedding algorithm of Boyer and Myrvold [70]. -boyer_myrvold_planarity_test returns true if the input graph +boyer_myrvold_planarity_test returns true if the input graph is planar and false otherwise. As a side-effect of this test, a planar -embedding can be constructed if the graph is planar or a minimal set of edges -that form a Kuratowski +embedding can be constructed if the graph is planar or a minimal set of edges +that form a Kuratowski subgraph can be found if the graph is not planar. -boyer_myrvold_planarity_test uses named parameter arguments (courtesy -of the Boost.Parameter +boyer_myrvold_planarity_test uses named parameter arguments (courtesy +of the Boost.Parameter library) to specify what the function actually does. Some examples are:

    @@ -65,8 +65,8 @@

    Boyer-Myrvold Planarity Testing/Embedding

  • Computing a planar embedding for a graph if it is planar, otherwise finding a set of edges that forms an obstructing Kuratowski subgraph:
    -if (boyer_myrvold_planarity_test(boyer_myrvold_params::graph = g, 
    -                                 boyer_myrvold_params::embedding = embedding_pmap,  
    +if (boyer_myrvold_planarity_test(boyer_myrvold_params::graph = g,
    +                                 boyer_myrvold_params::embedding = embedding_pmap,
                                      boyer_myrvold_params::kuratowski_subgraph = out_itr
                                      )
         )
    @@ -81,81 +81,81 @@ 

    Boyer-Myrvold Planarity Testing/Embedding

-The parameters passed to boyer_myrvold_planarity_test in the examples -above do more than just carry the data structures used for input and output - -the algorithm is optimized at compile time based on which parameters are -present. A complete list of parameters accepted and their interactions are -described below. +The parameters passed to boyer_myrvold_planarity_test in the examples +above do more than just carry the data structures used for input and output - +the algorithm is optimized at compile time based on which parameters are +present. A complete list of parameters accepted and their interactions are +described below.

boyer_myrvold_planarity_test accepts as input any undirected graph, even those with self-loops and multiple edges. -However, many planar graph drawing algorithms make additional restrictions -on the structure of the input graph - for example, requiring that the input +However, many planar graph drawing algorithms make additional restrictions +on the structure of the input graph - for example, requiring that the input graph is connected, biconnected, or even maximal planar (triangulated.) -Fortunately, any planar graph on n vertices that lacks one of these -properties can be augmented with additional edges so that it satisfies that -property in O(n) time - the functions +Fortunately, any planar graph on n vertices that lacks one of these +properties can be augmented with additional edges so that it satisfies that +property in O(n) time - the functions make_connected, -make_biconnected_planar, -and make_maximal_planar -exist for this purpose. If the graph drawing algorithm you're using requires, -say, a biconnected graph, then you must make your input graph biconnected +make_biconnected_planar, +and make_maximal_planar +exist for this purpose. If the graph drawing algorithm you're using requires, +say, a biconnected graph, then you must make your input graph biconnected before passing it into boyer_myrvold_planarity_test so that the -computed planar embedding includes these additional edges. This may require -more than one call to boyer_myrvold_planarity_test depending on the -structure of the graph you begin with, since both -make_biconnected_planar and make_maximal_planar require a +computed planar embedding includes these additional edges. This may require +more than one call to boyer_myrvold_planarity_test depending on the +structure of the graph you begin with, since both +make_biconnected_planar and make_maximal_planar require a planar embedding of the existing graph as an input parameter.

The named parameters accepted by boyer_myrvold_planarity_test are:

    -
  • graph : The input graph - this is the only required +
  • graph : The input graph - this is the only required parameter. -
  • vertex_index_map : A mapping from vertices of the input -graph to indexes in the range [0..num_vertices(g)). If this parameter +
  • vertex_index_map : A mapping from vertices of the input +graph to indexes in the range [0..num_vertices(g)). If this parameter is not provided, the vertex index map is assumed to be available as an interior property of the graph, accessible by calling get(vertex_index, g).
  • edge_index_map: A mapping from the edges of the input graph -to indexes in the range [0..num_edges(g)). This parameter is only -needed if the kuratowski_subgraph argument is provided. If the +to indexes in the range [0..num_edges(g)). This parameter is only +needed if the kuratowski_subgraph argument is provided. If the kuratowski_subgraph argument is provided and this parameter is not -provided, the EdgeIndexMap is assumed to be available as an interior property +provided, the EdgeIndexMap is assumed to be available as an interior property accessible by calling get(edge_index, g). -
  • embedding : If the graph is planar, this will be populated -with a mapping from vertices to the clockwise order of neighbors in the planar +
  • embedding : If the graph is planar, this will be populated +with a mapping from vertices to the clockwise order of neighbors in the planar embedding.
  • kuratowski_subgraph : If the graph is not planar, a minimal -set of edges that form the obstructing Kuratowski subgraph will be written to +set of edges that form the obstructing Kuratowski subgraph will be written to this iterator.
-These named parameters all belong to the namespace -boyer_myrvold_params. See below for more information on the concepts -required for these arguments. +These named parameters all belong to the namespace +boyer_myrvold_params. See below for more information on the concepts +required for these arguments.

Verifying the output

Whether or not the input graph is planar, boyer_myrvold_planarity_test -can produce a certificate that can be automatically checked to verify that the -function is working properly. +can produce a certificate that can be automatically checked to verify that the +function is working properly.

If the graph is planar, a planar embedding can be produced. The -planar embedding can be verified by passing it to a plane drawing routine +planar embedding can be verified by passing it to a plane drawing routine (such as -chrobak_payne_straight_line_drawing) and using the function -is_straight_line_drawing +chrobak_payne_straight_line_drawing) and using the function +is_straight_line_drawing to verify that the resulting graph is planar.

-If the graph is not planar, a set of edges that forms a Kuratowski subgraph in -the original graph can be produced. This set of edges can be passed to the +If the graph is not planar, a set of edges that forms a Kuratowski subgraph in +the original graph can be produced. This set of edges can be passed to the function is_kuratowski_subgraph - to verify that they can be contracted into a K5 or -K3,3. boyer_myrvold_planarity_test chooses the set -of edges forming the Kuratowski subgraph in such a way that the contraction to -a K5 or K3,3 can be done by a simple -deterministic process which is described in the documentation to + to verify that they can be contracted into a K5 or +K3,3. boyer_myrvold_planarity_test chooses the set +of edges forming the Kuratowski subgraph in such a way that the contraction to +a K5 or K3,3 can be done by a simple +deterministic process which is described in the documentation to is_kuratowski_subgraph.

Where Defined

@@ -170,8 +170,8 @@

Parameters

IN: Graph& g
-Any undirected graph. The graph type must be a model of -VertexAndEdgeListGraph and +Any undirected graph. The graph type must be a model of +VertexAndEdgeListGraph and IncidenceGraph.
@@ -184,7 +184,7 @@

Parameters

IN OutputIterator kuratowski_subgraph
-An OutputIterator which accepts values of the type +An OutputIterator which accepts values of the type graph_traits<Graph>::edge_descriptor
@@ -192,7 +192,7 @@

Parameters

A Readable Property Map - that maps vertices from g to distinct integers in the range + that maps vertices from g to distinct integers in the range [0, num_vertices(g) )
Default: get(vertex_index,g)
@@ -201,21 +201,21 @@

Parameters

A Readable Property Map - that maps edges from g to distinct integers in the range + that maps edges from g to distinct integers in the range [0, num_edges(g) )
-Default: get(edge_index,g), but this parameter is only used if +Default: get(edge_index,g), but this parameter is only used if the kuratowski_subgraph_iterator is provided.

Complexity

-Assuming that both the vertex index and edge index supplied take time -O(1) to return an index and there are O(n) -total self-loops and parallel edges in the graph, most combinations of -arguments given to -boyer_myrvold_planarity_test result in an algorithm that runs in time -O(n) for a graph with n vertices and m edges. The only -exception is when Kuratowski subgraph isolation is requested for a dense graph +Assuming that both the vertex index and edge index supplied take time +O(1) to return an index and there are O(n) +total self-loops and parallel edges in the graph, most combinations of +arguments given to +boyer_myrvold_planarity_test result in an algorithm that runs in time +O(n) for a graph with n vertices and m edges. The only +exception is when Kuratowski subgraph isolation is requested for a dense graph (a graph with n = o(m)) - the running time will be O(n+m) [2]. @@ -224,9 +224,9 @@

Examples

@@ -237,17 +237,17 @@

See Also

Notes

-

[1] A planar embedding is also called a combinatorial +

[1] A planar embedding is also called a combinatorial embedding. -

[2] The algorithm can still be made to run in time O(n) -for this case, if needed. Euler's +

[2] The algorithm can still be made to run in time O(n) +for this case, if needed. Euler's formula implies that a planar graph with n vertices can have no more -than 3n - 6 edges, which means that any non-planar graph on n -vertices has a subgraph of only 3n - 5 edges that contains a Kuratowski -subgraph. So, if you need to find a Kuratowski subgraph of a graph with more -than 3n - 5 edges in time O(n), you can create a subgraph of the -original graph consisting of any arbitrary 3n - 5 edges and pass that +than 3n - 6 edges, which means that any non-planar graph on n +vertices has a subgraph of only 3n - 5 edges that contains a Kuratowski +subgraph. So, if you need to find a Kuratowski subgraph of a graph with more +than 3n - 5 edges in time O(n), you can create a subgraph of the +original graph consisting of any arbitrary 3n - 5 edges and pass that graph to boyer_myrvold_planarity_test. @@ -256,4 +256,4 @@

Notes

Copyright © 2007 Aaron Windsor ( aaron.windsor@gmail.com) - + diff --git a/doc/breadth_first_search.html b/doc/breadth_first_search.html index 000c13a5a..0608fc9ba 100644 --- a/doc/breadth_first_search.html +++ b/doc/breadth_first_search.html @@ -1,17 +1,17 @@ Boost Graph Library: Breadth-First Search - -C++ Boost + +C++ Boost
@@ -24,15 +24,15 @@

 // named parameter version
 template <class Graph, class P, class T, class R>
-void breadth_first_search(Graph& G, 
-  typename graph_traits<Graph>::vertex_descriptor s, 
+void breadth_first_search(Graph& G,
+  typename graph_traits<Graph>::vertex_descriptor s,
   const bgl_named_params<P, T, R>& params);
 
 // non-named parameter version
-template <class Graph, class Buffer, class BFSVisitor, 
+template <class Graph, class Buffer, class BFSVisitor,
 	  class ColorMap>
-void breadth_first_search(const Graph& g, 
-   typename graph_traits<Graph>::vertex_descriptor s, 
+void breadth_first_search(const Graph& g,
+   typename graph_traits<Graph>::vertex_descriptor s,
    Buffer& Q, BFSVisitor vis, ColorMap color);
 
@@ -70,25 +70,25 @@

 BFS(G, s)
   for each vertex u in V[G]
-    color[u] := WHITE 
-    d[u] := infinity 
-    p[u] := u 
+    color[u] := WHITE
+    d[u] := infinity
+    p[u] := u
   end for
-  color[s] := GRAY 
-  d[s] := 0 
+  color[s] := GRAY
+  d[s] := 0
   ENQUEUE(Q, s)
-  while (Q != Ø) 
+  while (Q != Ø)
     u := DEQUEUE(Q)
     for each vertex v in Adj[u]
       if (color[v] = WHITE)
-        color[v] := GRAY 
-        d[v] := d[u] + 1  
-        p[v] := u  
+        color[v] := GRAY
+        d[v] := d[u] + 1
+        p[v] := u
         ENQUEUE(Q, v)
       else
-        if (color[v] = GRAY) 
+        if (color[v] = GRAY)
           ...
-        else 
+        else
           ...
     end for
     color[u] := BLACK
@@ -99,29 +99,29 @@ 

 
-initialize vertex u 
+initialize vertex u
 
 
 
 
 
 
-discover vertex s 
+discover vertex s
 
-examine vertex u 
+examine vertex u
 examine edge (u,v)
-(u,v) is a tree edge 
+(u,v) is a tree edge
 
 
 
-discover vertex v 
+discover vertex v
 (u,v) is a non-tree edge
 
-(u,v) has a gray target 
+(u,v) has a gray target
 
-(u,v) has a black target 
+(u,v) has a black target
 
-finish vertex u 
+finish vertex u
 
@@ -244,7 +244,7 @@

Named Parameters

Python: The buffer must derive from the
Buffer type for the graph. -

+

@@ -252,7 +252,7 @@

-The time complexity is O(E + V). +The time complexity is O(E + V).

@@ -260,13 +260,13 @@

Visitor Event Points

Where Defined

boost/graph/circle_layout.hpp

Description

The distance from the center of the polygon to each point is determined by the radius parameter. The position parameter must be an Lvalue Property Map whose value type is a class type containing x and y members that will be set to the x and y coordinates.

Parameters

IN: const VertexListGraph& g diff --git a/doc/compressed_sparse_row.html b/doc/compressed_sparse_row.html index 9519f9b0c..37ff84930 100644 --- a/doc/compressed_sparse_row.html +++ b/doc/compressed_sparse_row.html @@ -2,7 +2,7 @@ Boost Graph Library: Connected Components - -C++ Boost + +C++ Boost
@@ -154,4 +154,4 @@

Example

- + diff --git a/doc/constructing_algorithms.html b/doc/constructing_algorithms.html index a7b7f4ca4..d173ae197 100644 --- a/doc/constructing_algorithms.html +++ b/doc/constructing_algorithms.html @@ -1,17 +1,17 @@ Boost Graph Library: Constructing Graph Algorithms - -C++ Boost + +C++ Boost
@@ -113,7 +113,7 @@

Constructing graph algorithms with BGL

namespace boost { template <class VertexListGraph, class Order, class Color> typename graph_traits<VertexListGraph>::vertices_size_type - sequential_vertex_color_ting(const VertexListGraph& G, + sequential_vertex_color_ting(const VertexListGraph& G, Order order, Color color) { typedef graph_traits<VertexListGraph> GraphTraits; @@ -127,27 +127,27 @@

Constructing graph algorithms with BGL

BOOST_CONCEPT_ASSERT(( IntegerConcept<ColorType> )); BOOST_CONCEPT_ASSERT(( ReadablePropertyMapConcept<Order, size_type> )); BOOST_STATIC_ASSERT((is_same<OrderType, vertex_descriptor>::value)); - + size_type max_color = 0; const size_type V = num_vertices(G); - std::vector<size_type> + std::vector<size_type> mark(V, numeric_limits_max(max_color)); - + typename GraphTraits::vertex_iterator v, vend; for (boost::tie(v, vend) = vertices(G); v != vend; ++v) color[*v] = V - 1; // which means "not colored" - + for (size_type i = 0; i < V; i++) { vertex_descriptor current = order[i]; // mark all the colors of the adjacent vertices typename GraphTraits::adjacency_iterator ai, aend; for (boost::tie(ai, aend) = adjacent_vertices(current, G); ai != aend; ++ai) - mark[color[*ai]] = i; + mark[color[*ai]] = i; // find the smallest color unused by the adjacent vertices size_type smallest_color = 0; - while (smallest_color < max_color && mark[smallest_color] == i) + while (smallest_color < max_color && mark[smallest_color] == i) ++smallest_color; // if all the colors are used up, increase the number of colors @@ -180,4 +180,4 @@

Constructing graph algorithms with BGL

- + diff --git a/doc/copy_graph.html b/doc/copy_graph.html index 590429a04..76483bb4d 100644 --- a/doc/copy_graph.html +++ b/doc/copy_graph.html @@ -1,24 +1,24 @@ Boost Graph Library: Copy Graph - -C++ Boost + +C++ Boost

copy_graph

-template <class VertexListGraph, class MutableGraph> 
+template <class VertexListGraph, class MutableGraph>
 void copy_graph(const VertexListGraph& G, MutableGraph& G_copy,
     const bgl_named_params<P, T, R>& params = all defaults)
 
@@ -113,4 +113,4 @@

Complexity

- + diff --git a/doc/cuthill_mckee_ordering.html b/doc/cuthill_mckee_ordering.html index 5765c31ce..41c0c734c 100644 --- a/doc/cuthill_mckee_ordering.html +++ b/doc/cuthill_mckee_ordering.html @@ -1,19 +1,19 @@ - + Boost Graph Library: Cuthill-Mckee Ordering - -C++ Boost + +C++ Boost
@@ -46,25 +46,25 @@

OutputIterator cuthill_mckee_ordering(const IncidenceGraph& g, typename graph_traits<IncidenceGraph>::vertex_descriptor s, - OutputIterator inverse_permutation, + OutputIterator inverse_permutation, ColorMap color, DegreeMap degree) (2) template <class VertexListGraph, class OutputIterator> OutputIterator - cuthill_mckee_ordering(const VertexListGraph& g, OutputIterator inverse_permutation); + cuthill_mckee_ordering(const VertexListGraph& g, OutputIterator inverse_permutation); template <class VertexListGraph, class OutputIterator, class VertexIndexMap> OutputIterator - cuthill_mckee_ordering(const VertexListGraph& g, OutputIterator inverse_permutation, - VertexIndexMap index_map); - - template <class VertexListGraph, class OutputIterator, + cuthill_mckee_ordering(const VertexListGraph& g, OutputIterator inverse_permutation, + VertexIndexMap index_map); + + template <class VertexListGraph, class OutputIterator, class ColorMap, class DegreeMap> OutputIterator - cuthill_mckee_ordering(const VertexListGraph& g, OutputIterator inverse_permutation, + cuthill_mckee_ordering(const VertexListGraph& g, OutputIterator inverse_permutation, ColorMap color, DegreeMap degree) - + (3) template <class IncidenceGraph, class OutputIterator, class ColorMap, class DegreeMap> @@ -72,7 +72,7 @@

cuthill_mckee_ordering(const IncidenceGraph& g, std::deque< typename graph_traits<IncidenceGraph>::vertex_descriptor > vertex_queue, - OutputIterator inverse_permutation, + OutputIterator inverse_permutation, ColorMap color, DegreeMap degree)

@@ -92,10 +92,10 @@

Version 1 of the algorithm lets the user choose the ``starting vertex'', version 2 finds a good starting vertex using the -pseudo-peripheral pair heuristic (among each component), while version 3 -contains the starting nodes for each vertex in the deque. The choice of the -``starting vertex'' can have a significant effect on the quality of the -ordering. For versions 2 and 3, find_starting_vertex will be called +pseudo-peripheral pair heuristic (among each component), while version 3 +contains the starting nodes for each vertex in the deque. The choice of the +``starting vertex'' can have a significant effect on the quality of the +ordering. For versions 2 and 3, find_starting_vertex will be called for each component in the graph, increasing run time significantly.

@@ -140,7 +140,7 @@

Parameters

Python: Unsupported parameter. -IN: distance_inf(D inf) +IN: distance_inf(D inf)
The inf object must be the greatest value of any D object. That is, compare(d, inf) == true for any d != inf. @@ -209,7 +209,7 @@

Named Parameters

Python: Unsupported parameter.
-IN: distance_zero(D zero) +IN: distance_zero(D zero)
The zero value must be the identity element for the Monoid formed by the distance values @@ -220,7 +220,7 @@

Named Parameters

Python: Unsupported parameter.
-UTIL/OUT: color_map(ColorMap c_map) +UTIL/OUT: color_map(ColorMap c_map)
This is used during the execution of the algorithm to mark the vertices. The vertices start out white and become gray when they are @@ -242,13 +242,13 @@

Named Parameters

the graph.
- -OUT: visitor(DijkstraVisitor v) + +OUT: visitor(DijkstraVisitor v)
Use this to specify actions that you would like to happen during certain event points within the algorithm. The type DijkstraVisitor must be a model of the - Dijkstra Visitor concept. + Dijkstra Visitor concept. The visitor object is passed by value [1].
Default: dijkstra_visitor<null_visitor>
@@ -272,21 +272,21 @@

Visitor Event Points

is invoked on each vertex in the graph before the start of the algorithm.
  • vis.examine_vertex(u, g) - is invoked on a vertex as it is added to set S. + is invoked on a vertex as it is added to set S. At this point we know that (p[u],u) - is a shortest-paths tree edge so - d[u] = delta(s,u) = d[p[u]] + w(p[u],u). Also, the distances + is a shortest-paths tree edge so + d[u] = delta(s,u) = d[p[u]] + w(p[u],u). Also, the distances of the examined vertices is monotonically increasing - d[u1] <= d[u2] <= d[un]. + d[u1] <= d[u2] <= d[un].
  • vis.examine_edge(e, g) is invoked on each out-edge of a vertex immediately after it has - been added to set S. + been added to set S.
  • vis.edge_relaxed(e, g) is invoked on edge (u,v) if d[u] + w(u,v) < d[v]. The edge (u,v) that participated in the last - relaxation for vertex v is an edge in the shortest paths tree. + relaxation for vertex v is an edge in the shortest paths tree.
  • vis.discover_vertex(v, g) - is invoked on vertex v when the edge + is invoked on vertex v when the edge (u,v) is examined and v is WHITE. Since a vertex is colored GRAY when it is discovered, each reacable vertex is discovered exactly once. @@ -306,7 +306,7 @@

    Example

    Notes

    -

    [1] +

    [1] Since the visitor parameter is passed by value, if your visitor contains state then any changes to the state during the algorithm will be made to a copy of the visitor object, not the visitor object @@ -322,5 +322,5 @@

    Notes

    - + diff --git a/doc/depth_first_search.html b/doc/depth_first_search.html index 547b94e3f..a376de3f1 100644 --- a/doc/depth_first_search.html +++ b/doc/depth_first_search.html @@ -1,17 +1,17 @@ Boost Graph Library: Depth-First Search - -C++ Boost + +C++ Boost
    @@ -31,7 +31,7 @@

    (Python
 void depth_first_search(const Graph& g, DFSVisitor vis, ColorMap color)
 
 template <class Graph, class <a href=DFSVisitor, class ColorMap> -void depth_first_search(const Graph& g, DFSVisitor vis, ColorMap color, +void depth_first_search(const Graph& g, DFSVisitor vis, ColorMap color, typename graph_traits<Graph>::vertex_descriptor start) @@ -84,33 +84,33 @@

    (Python
 <td valign=
     DFS(G)
    -  for each vertex u in V 
    +  for each vertex u in V
         color[u] := WHITE
    -    p[u] = u 
    +    p[u] = u
       end for
       time := 0
       if there is a starting vertex s
         call DFS-VISIT(G, s)
    -  for each vertex u in V 
    +  for each vertex u in V
         if color[u] = WHITE
           call DFS-VISIT(G, u)
       end for
       return (p,d_time,f_time) 
    -DFS-VISIT(G, u) +DFS-VISIT(G, u) color[u] := GRAY - d_time[u] := time := time + 1 - for each v in Adj[u] + d_time[u] := time := time + 1 + for each v in Adj[u] if (color[v] = WHITE) - p[v] = u + p[v] = u call DFS-VISIT(G, v) - else if (color[v] = GRAY) + else if (color[v] = GRAY) ... - else if (color[v] = BLACK) + else if (color[v] = BLACK) ... ... end for color[u] := BLACK - f_time[u] := time := time + 1 + f_time[u] := time := time + 1
     
     
    @@ -252,27 +252,27 @@ 

    Visitor Event Points

  • vis.start_vertex(s, g) is invoked on the source vertex once before the start of the search. - +
  • vis.discover_vertex(u, g) is invoked when a vertex is encountered for the first time. - +
  • vis.examine_edge(e, g) is invoked on every out-edge of each vertex after it is discovered.
  • vis.tree_edge(e, g) is invoked on each edge as it becomes a member of the edges that form the search tree. If you wish to record predecessors, do so at this event point. - +
  • vis.back_edge(e, g) is invoked on the back edges in the graph. - +
  • vis.forward_or_cross_edge(e, g) is invoked on forward or cross edges in the graph. In an undirected graph this method is never called. -
  • vis.finish_edge(e, g) is invoked on the non-tree edges in - the graph as well as on each tree edge after its target vertex is finished. - +
  • vis.finish_edge(e, g) is invoked on the non-tree edges in + the graph as well as on each tree edge after its target vertex is finished. +
  • vis.finish_vertex(u, g) is invoked on a vertex after all of its out edges have been added to the search tree and all of the adjacent vertices have been discovered (but before their @@ -295,7 +295,7 @@

    See Also

    Notes

    -

    [1] +

    [1] Since the visitor parameter is passed by value, if your visitor contains state then any changes to the state during the algorithm will be made to a copy of the visitor object, not the visitor object @@ -317,4 +317,4 @@

    Notes

    - + diff --git a/doc/depth_first_visit.html b/doc/depth_first_visit.html index 95514e088..81f73ba90 100644 --- a/doc/depth_first_visit.html +++ b/doc/depth_first_visit.html @@ -1,17 +1,17 @@ Boost Graph Library: Depth-First Visit - -C++ Boost + +C++ Boost
    @@ -25,13 +25,13 @@

     template <class IncidenceGraph, class DFSVisitor, class ColorMap>
     void depth_first_visit(IncidenceGraph& g,
    -  typename graph_traits<IncidenceGraph>::vertex_descriptor s, 
    +  typename graph_traits<IncidenceGraph>::vertex_descriptor s,
       DFSVisitor& vis, ColorMap color)
     
    -template <class IncidenceGraph, class DFSVisitor, class ColorMap, 
    +template <class IncidenceGraph, class DFSVisitor, class ColorMap,
               class TerminatorFunc>
     void depth_first_visit(IncidenceGraph& g,
    -  typename graph_traits<IncidenceGraph>::vertex_descriptor s, 
    +  typename graph_traits<IncidenceGraph>::vertex_descriptor s,
       DFSVisitor& vis, ColorMap color, TerminatorFunc func = TerminatorFunc())
     
    @@ -41,7 +41,7 @@

    href="./graph_theory_review.html#sec:dfs-algorithm">depth-first pattern. The main purpose of the function is for the implementation of depth_first_search() though sometimes it is -useful on its own. +useful on its own.

    The DFSVisitor supplied by the user determines what @@ -124,7 +124,7 @@

    Complexity

    Notes

    -

    [1] +

    [1] Since the visitor parameter is passed by value, if your visitor contains state then any changes to the state during the algorithm will be made to a copy of the visitor object, not the visitor object @@ -141,4 +141,4 @@

    Notes

    - + diff --git a/doc/dfs_visitor.html b/doc/dfs_visitor.html index c9ee5114d..840acd335 100644 --- a/doc/dfs_visitor.html +++ b/doc/dfs_visitor.html @@ -1,17 +1,17 @@ Boost Graph Library: dfs_visitor - -C++ Boost + +C++ Boost
    @@ -108,4 +108,4 @@

    See Also

    - + diff --git a/doc/dijkstra_shortest_paths.html b/doc/dijkstra_shortest_paths.html index 2f312f8b5..2cd3978f7 100644 --- a/doc/dijkstra_shortest_paths.html +++ b/doc/dijkstra_shortest_paths.html @@ -1,17 +1,17 @@ Boost Graph Library: Dijkstra's Shortest Paths - -C++ Boost + +C++ Boost
    @@ -29,14 +29,14 @@

    (Python) const bgl_named_params<P, T, R>& params); // non-named parameter version -template <typename Graph, typename DijkstraVisitor, +template <typename Graph, typename DijkstraVisitor, typename PredecessorMap, typename DistanceMap, - typename WeightMap, typename VertexIndexMap, typename CompareFunction, typename CombineFunction, + typename WeightMap, typename VertexIndexMap, typename CompareFunction, typename CombineFunction, typename DistInf, typename DistZero, typename ColorMap = default> void dijkstra_shortest_paths (const Graph& g, - typename graph_traits<Graph>::vertex_descriptor s, - PredecessorMap predecessor, DistanceMap distance, WeightMap weight, + typename graph_traits<Graph>::vertex_descriptor s, + PredecessorMap predecessor, DistanceMap distance, WeightMap weight, VertexIndexMap index_map, CompareFunction compare, CombineFunction combine, DistInf inf, DistZero zero, DijkstraVisitor vis, ColorMap color = default) @@ -123,12 +123,12 @@

    (Python)
     DIJKSTRA(G, s, w)
       for each vertex u in V (This loop is not run in dijkstra_shortest_paths_no_init)
    -    d[u] := infinity 
    -    p[u] := u 
    +    d[u] := infinity
    +    p[u] := u
         color[u] := WHITE
       end for
    -  color[s] := GRAY 
    -  d[s] := 0 
    +  color[s] := GRAY
    +  d[s] := 0
       INSERT(Q, s)
       while (Q != Ø)
         u := EXTRACT-MIN(Q)
    @@ -136,10 +136,10 @@ 

    (Python) for each vertex v in Adj[u] if (w(u,v) + d[u] < d[v]) d[v] := w(u,v) + d[u] - p[v] := u - if (color[v] = WHITE) + p[v] := u + if (color[v] = WHITE) color[v] := GRAY - INSERT(Q, v) + INSERT(Q, v) else if (color[v] = GRAY) DECREASE-KEY(Q, v) else @@ -188,17 +188,17 @@

    Where Defined

    Parameters

    -IN: const Graph& g +IN: const Graph& g
    The graph object on which the algorithm will be applied. - The type Graph must be a model of + The type Graph must be a model of Vertex List Graph and Incidence Graph.
    Python: The parameter is named graph.
    -IN: vertex_descriptor s +IN: vertex_descriptor s
    The source vertex. All distance will be calculated from this vertex, and the shortest paths tree will be rooted at this vertex.
    @@ -208,11 +208,11 @@

    Parameters

    Named Parameters

    -IN: weight_map(WeightMap w_map) +IN: weight_map(WeightMap w_map)
    The weight or ``length'' of each edge in the graph. The weights must all be non-negative, and the algorithm will throw a - negative_edge + negative_edge exception is one of the edges is negative. The type WeightMap must be a model of Readable Property Map. The edge descriptor type of @@ -225,13 +225,13 @@

    Named Parameters

    Python default: graph.get_edge_double_map("weight")
    -IN: vertex_index_map(VertexIndexMap i_map) +IN: vertex_index_map(VertexIndexMap i_map)
    This maps each vertex to an integer in the range [0, num_vertices(g)). This is necessary for efficient updates of the heap data structure [61] when an edge is relaxed. - The type + The type VertexIndexMap must be a model of Readable Property Map. The value type of the map must be an integer type. The vertex descriptor type of the graph needs to be @@ -246,10 +246,10 @@

    Named Parameters

    Python: Unsupported parameter.
    -OUT: predecessor_map(PredecessorMap p_map) +OUT: predecessor_map(PredecessorMap p_map)
    The predecessor map records the edges in the shortest path tree, the tree computed - by the traversal of the graph. Upon completion of the algorithm, the edges + by the traversal of the graph. Upon completion of the algorithm, the edges (p[u],u) for all u in V are in the tree. The shortest path from vertex s to each vertex v in the graph consists of the vertices v, p[v], p[p[v]], and so on until s is @@ -266,7 +266,7 @@

    Named Parameters

    Python: Must be a vertex_vertex_map for the graph.
    -UTIL/OUT: distance_map(DistanceMap d_map) +UTIL/OUT: distance_map(DistanceMap d_map)
    The shortest path weight from the source vertex s to each vertex in the graph g is recorded in this property map. The @@ -274,7 +274,7 @@

    Named Parameters

    shortest path. The type DistanceMap must be a model of Read/Write Property Map. The vertex descriptor type of the graph needs to - be usable as the key type of the distance map. + be usable as the key type of the distance map. The value type of the distance map is the element type of a Monoid formed with the combine @@ -293,7 +293,7 @@

    Named Parameters

    Python: Must be a vertex_double_map for the graph.
    -IN: distance_compare(CompareFunction cmp) +IN: distance_compare(CompareFunction cmp)
    This function is use to compare distances to determine which vertex is closer to the source vertex. The CompareFunction type @@ -309,7 +309,7 @@

    Named Parameters

    Python: Unsupported parameter.
    -IN: distance_combine(CombineFunction cmb) +IN: distance_combine(CombineFunction cmb)
    This function is used to combine distances to compute the distance of a path. The CombineFunction type must be a model of Named Parameters

    Python: Unsupported parameter.
  • -IN: distance_inf(D inf) +IN: distance_inf(D inf)
    The inf object must be the greatest value of any D object. That is, compare(d, inf) == true for any d != inf. @@ -338,7 +338,7 @@

    Named Parameters

    Python: Unsupported parameter.
    -IN: distance_zero(D zero) +IN: distance_zero(D zero)
    The zero value must be the identity element for the Monoid formed by the distance values @@ -350,7 +350,7 @@

    Named Parameters

    Python: Unsupported parameter.
    -UTIL/OUT: color_map(ColorMap c_map) +UTIL/OUT: color_map(ColorMap c_map)
    This is used during the execution of the algorithm to mark the vertices. The vertices start out white and become gray when they are @@ -371,13 +371,13 @@

    Named Parameters

    Python: The color map must be a vertex_color_map for the graph.
    - -OUT: visitor(DijkstraVisitor v) + +OUT: visitor(DijkstraVisitor v)
    Use this to specify actions that you would like to happen during certain event points within the algorithm. The type DijkstraVisitor must be a model of the - Dijkstra Visitor concept. + Dijkstra Visitor concept. The visitor object is passed by value [2].
    Default: dijkstra_visitor<null_visitor>
    @@ -404,19 +404,19 @@

    Visitor Event Points

  • vis.examine_vertex(u, g) is invoked on a vertex as it is removed from the priority queue and added to set S. At this point we know that (p[u],u) - is a shortest-paths tree edge so - d[u] = delta(s,u) = d[p[u]] + w(p[u],u). Also, the distances + is a shortest-paths tree edge so + d[u] = delta(s,u) = d[p[u]] + w(p[u],u). Also, the distances of the examined vertices is monotonically increasing - d[u1] <= d[u2] <= d[un]. + d[u1] <= d[u2] <= d[un].
  • vis.examine_edge(e, g) is invoked on each out-edge of a vertex immediately after it has - been added to set S. + been added to set S.
  • vis.edge_relaxed(e, g) is invoked on edge (u,v) if d[u] + w(u,v) < d[v]. The edge (u,v) that participated in the last - relaxation for vertex v is an edge in the shortest paths tree. + relaxation for vertex v is an edge in the shortest paths tree.
  • vis.discover_vertex(v, g) - is invoked on vertex v when the edge + is invoked on vertex v when the edge (u,v) is examined and v is WHITE. Since a vertex is colored GRAY when it is discovered, each reachable vertex is discovered exactly once. This @@ -445,7 +445,7 @@

    Notes

    vertices in V - S that are discovered and therefore have a distance less than infinity. -

    [2] +

    [2] Since the visitor parameter is passed by value, if your visitor contains state then any changes to the state during the algorithm will be made to a copy of the visitor object, not the visitor object @@ -461,4 +461,4 @@

    Notes

    - + diff --git a/doc/dijkstra_shortest_paths_no_color_map.html b/doc/dijkstra_shortest_paths_no_color_map.html index 05c3aec51..07432082d 100644 --- a/doc/dijkstra_shortest_paths_no_color_map.html +++ b/doc/dijkstra_shortest_paths_no_color_map.html @@ -1,17 +1,17 @@ Boost Graph Library: Dijkstra's Shortest Paths (No Color Map) - -C++ Boost + +C++ Boost
    @@ -27,29 +27,29 @@

    (const Graph& graph, typename graph_traits<Graph>::vertex_descriptor start_vertex, const bgl_named_params& params); - + // non-named parameter version -template <typename Graph, typename DijkstraVisitor, +template <typename Graph, typename DijkstraVisitor, typename PredecessorMap, typename DistanceMap, - typename WeightMap, typename VertexIndexMap, typename DistanceCompare, typename DistanceWeightCombine, + typename WeightMap, typename VertexIndexMap, typename DistanceCompare, typename DistanceWeightCombine, typename DistanceInfinity, typename DistanceZero> void dijkstra_shortest_paths_no_color_map (const Graph& graph, - typename graph_traits<Graph>::vertex_descriptor start_vertex, - PredecessorMap predecessor_map, DistanceMap distance_map, WeightMap weight_map, + typename graph_traits<Graph>::vertex_descriptor start_vertex, + PredecessorMap predecessor_map, DistanceMap distance_map, WeightMap weight_map, VertexIndexMap index_map, DistanceCompare distance_compare, DistanceWeightCombine distance_weight_combine, DistanceInfinity distance_infinity, DistanceZero distance_zero); // version that does not initialize the property maps -template <typename Graph, typename DijkstraVisitor, +template <typename Graph, typename DijkstraVisitor, typename PredecessorMap, typename DistanceMap, - typename WeightMap, typename VertexIndexMap, typename DistanceCompare, typename DistanceWeightCombine, + typename WeightMap, typename VertexIndexMap, typename DistanceCompare, typename DistanceWeightCombine, typename DistanceInfinity, typename DistanceZero> void dijkstra_shortest_paths_no_color_map_no_init (const Graph& graph, - typename graph_traits<Graph>::vertex_descriptor start_vertex, - PredecessorMap predecessor_map, DistanceMap distance_map, WeightMap weight_map, + typename graph_traits<Graph>::vertex_descriptor start_vertex, + PredecessorMap predecessor_map, DistanceMap distance_map, WeightMap weight_map, VertexIndexMap index_map, DistanceCompare distance_compare, DistanceWeightCombine distance_weight_combine, DistanceInfinity distance_infinity, DistanceZero distance_zero); @@ -116,16 +116,16 @@

     DIJKSTRA(G, s, w)
    -  d[s] := 0 
    +  d[s] := 0
       INSERT(Q, s)
       while (Q != Ø)
         u := EXTRACT-MIN(Q)
         for each vertex v in Adj[u]
           if (w(u,v) + d[u] < d[v])
             d[v] := w(u,v) + d[u]
    -        p[v] := u 
    -        if (d[v] was originally infinity) 
    -          INSERT(Q, v)   
    +        p[v] := u
    +        if (d[v] was originally infinity)
    +          INSERT(Q, v)
             else
               DECREASE-KEY(Q, v)
           else
    @@ -164,15 +164,15 @@ 

    Where Defined

    Parameters

    -IN: const Graph& graph +IN: const Graph& graph
    The graph object on which the algorithm will be applied. - The type Graph must be a model of + The type Graph must be a model of Vertex List Graph and Incidence Graph.
    -IN: vertex_descriptor start_vertex +IN: vertex_descriptor start_vertex
    The source vertex. All distance will be calculated from this vertex, and the shortest paths tree will be rooted at this vertex.
    @@ -180,11 +180,11 @@

    Parameters

    Named Parameters

    -IN: weight_map(WeightMap weight_map) +IN: weight_map(WeightMap weight_map)
    The weight or ``length'' of each edge in the graph. The weights must all be non-negative and non-infinite [3]. The algorithm will throw a - negative_edge + negative_edge exception is one of the edges is negative. The type WeightMap must be a model of Readable Property Map. The edge descriptor type of @@ -194,13 +194,13 @@

    Named Parameters

    Default: get(edge_weight, graph)
    -IN: index_map(VertexIndexMap index_map) +IN: index_map(VertexIndexMap index_map)
    This maps each vertex to an integer in the range [0, num_vertices(graph)). This is necessary for efficient updates of the heap data structure [61] when an edge is relaxed. - The type + The type VertexIndexMap must be a model of Readable Property Map. The value type of the map must be an integer type. The vertex descriptor type of the graph needs to be @@ -213,7 +213,7 @@

    Named Parameters


    -OUT: predecessor_map(PredecessorMap predecessor_map) +OUT: predecessor_map(PredecessorMap predecessor_map)
    The predecessor map records the edges in the minimum spanning tree. Upon completion of the algorithm, the edges (p[u],u) @@ -229,7 +229,7 @@

    Named Parameters

    Python: Must be a vertex_vertex_map for the graph.
    -UTIL/OUT: distance_map(DistanceMap distance_map) +UTIL/OUT: distance_map(DistanceMap distance_map)
    The shortest path weight from the source vertex start_vertex to each vertex in the graph graph is recorded in this property map. The @@ -237,7 +237,7 @@

    Named Parameters

    shortest path. The type DistanceMap must be a model of Read/Write Property Map. The vertex descriptor type of the graph needs to - be usable as the key type of the distance map. + be usable as the key type of the distance map. The value type of the distance map is the element type of a Monoid formed with the distance_weight_combine @@ -254,7 +254,7 @@

    Named Parameters

    map.
    -IN: distance_compare(CompareFunction distance_compare) +IN: distance_compare(CompareFunction distance_compare)
    This function is use to compare distances to determine which vertex is closer to the source vertex. The DistanceCompareFunction type @@ -268,7 +268,7 @@

    Named Parameters

    property_traits<DistanceMap>::value_type
    -IN: distance_combine(CombineFunction distance_weight_combine) +IN: distance_combine(CombineFunction distance_weight_combine)
    This function is used to combine distances to compute the distance of a path. The DistanceWeightCombineFunction type must be a model of Named Parameters

    D=typename property_traits<DistanceMap>::value_type

  • -IN: distance_inf(D distance_infinity) +IN: distance_inf(D distance_infinity)
    The distance_infinity object must be the greatest value of any D object. That is, distance_compare(d, distance_infinity) == true for any d != distance_infinity. @@ -293,7 +293,7 @@

    Named Parameters

    Default: std::numeric_limits<D>::max()
    -IN: distance_zero(D distance_zero) +IN: distance_zero(D distance_zero)
    The distance_zero value must be the identity element for the Monoid formed by the distance values @@ -302,13 +302,13 @@

    Named Parameters

    Default: D()with D=typename property_traits<DistanceMap>::value_type
    - -OUT: visitor(DijkstraVisitor v) + +OUT: visitor(DijkstraVisitor v)
    Use this to specify actions that you would like to happen during certain event points within the algorithm. The type DijkstraVisitor must be a model of the - Dijkstra Visitor concept. + Dijkstra Visitor concept. The visitor object is passed by value [2].
    Default: dijkstra_visitor<null_visitor>
    @@ -330,19 +330,19 @@

    Visitor Event Points

  • vis.examine_vertex(u, g) is invoked on a vertex as it is removed from the priority queue and added to set S. At this point we know that (p[u],u) - is a shortest-paths tree edge so - d[u] = delta(s,u) = d[p[u]] + w(p[u],u). Also, the distances + is a shortest-paths tree edge so + d[u] = delta(s,u) = d[p[u]] + w(p[u],u). Also, the distances of the examined vertices is monotonically increasing - d[u1] <= d[u2] <= d[un]. + d[u1] <= d[u2] <= d[un].
  • vis.examine_edge(e, g) is invoked on each out-edge of a vertex immediately after it has - been added to set S. + been added to set S.
  • vis.edge_relaxed(e, g) is invoked on edge (u,v) if d[u] + w(u,v) < d[v]. The edge (u,v) that participated in the last - relaxation for vertex v is an edge in the shortest paths tree. + relaxation for vertex v is an edge in the shortest paths tree.
  • vis.discover_vertex(v, g) - is invoked on vertex v when the edge + is invoked on vertex v when the edge (u,v) is examined and v has not yet been discovered (i.e. its distance was infinity before relaxation was attempted on the edge). This is also when the vertex is inserted into the priority queue.
  • vis.edge_not_relaxed(e, g) @@ -370,17 +370,17 @@

    Notes

    vertices in V - S that are discovered and therefore have a distance less than infinity. -

    [2] +

    [2] Since the visitor parameter is passed by value, if your visitor contains state then any changes to the state during the algorithm will be made to a copy of the visitor object, not the visitor object passed in. Therefore you may want the visitor to hold this state by pointer or reference. - -

    [3] + +

    [3] The algorithm will not work correctly if any of the edge weights are equal to infinity since the infinite distance value is used to determine if a vertex has been discovered. - -

    [4] + +

    [4] Calls to the visitor events occur in the same order as dijkstra_shortest_paths (i.e. discover_vertex(u) will always be called after examine_vertex(u) for an undiscovered vertex u). However, the vertices of the graph given to dijkstra_shortest_paths_no_color_map will not necessarily be visited in the same order as dijkstra_shortest_paths.
    @@ -391,4 +391,4 @@

    Notes

    Trustees of Indiana University - + diff --git a/doc/dijkstra_visitor.html b/doc/dijkstra_visitor.html index 5ad9db1de..ac4b3cb3a 100644 --- a/doc/dijkstra_visitor.html +++ b/doc/dijkstra_visitor.html @@ -1,17 +1,17 @@ Boost Graph Library: dijkstra_visitor - -C++ Boost + +C++ Boost
    @@ -37,7 +37,7 @@

    Example

     boost::dijkstra_shortest_paths
    -  (G, vertex(a, G), 
    +  (G, vertex(a, G),
        distance_map(make_iterator_property_map(distance.begin(), vertex_id, distance[0])).
        predecessor_map(make_iterator_property_map(parent.begin(), vertex_id, parent[0])).
        visitor(make_dijkstra_visitor(copy_graph(G_copy, on_examine_edge()))));
    @@ -122,4 +122,4 @@ 

    See Also

    - + diff --git a/doc/directed_graph.html b/doc/directed_graph.html index c20b23830..a410153e8 100644 --- a/doc/directed_graph.html +++ b/doc/directed_graph.html @@ -1,17 +1,17 @@ Boost Graph Library: Directed Graph - -C++ Boost + +C++ Boost
    @@ -93,4 +93,4 @@

    Where Defined

    - + diff --git a/doc/disjoint_sets.html b/doc/disjoint_sets.html index 34cce558d..eaebe45a4 100644 --- a/doc/disjoint_sets.html +++ b/doc/disjoint_sets.html @@ -73,7 +73,7 @@

    Example

       ...
       disjoint_sets<Rank, Parent, FindCompress> dsets(rank, p);
    -  
    +
       for (ui  = vertices(G).first; ui != vertices(G).second; ++ui)
         dsets.make_set(*ui);
       ...
    @@ -282,7 +282,7 @@ 

    -

    Revised +

    Revised 01 December, 2006

    diff --git a/doc/disjoint_sets_biblio.html b/doc/disjoint_sets_biblio.html index ec9e88324..96132347c 100644 --- a/doc/disjoint_sets_biblio.html +++ b/doc/disjoint_sets_biblio.html @@ -37,7 +37,7 @@

    Bibliography

    "../../doc/images/valid-html401.png" alt="Valid HTML 4.01 Transitional" height="31" width="88">

    -

    Revised +

    Revised 01 December, 2006

    diff --git a/doc/distance_recorder.html b/doc/distance_recorder.html index 9786371f4..50daaa447 100644 --- a/doc/distance_recorder.html +++ b/doc/distance_recorder.html @@ -1,17 +1,17 @@ Boost Graph Library: distance_recorder - -C++ Boost + +C++ Boost
    @@ -124,7 +124,7 @@

    Member Functions

    void operator()(Edge e, const Graph& g); -Given edge e = (u,v), this records the distance of v as +Given edge e = (u,v), this records the distance of v as one plus the distance of u. @@ -173,7 +173,7 @@

    See Also

    - + Boost Graph Library: Edge List Class - -C++ Boost + +C++ Boost
    @@ -52,7 +52,7 @@

    Example

    E(x,y), E(x,v), E(y,v), E(y,z), E(z,u), E(z,x) }; - + int weight[] = { -4, 8, 5, -2, 9, -3, @@ -61,16 +61,16 @@

    Example

    typedef boost::edge_list<E*> Graph; Graph g(edges, edges + sizeof(edges) / sizeof(E)); - + std::vector<int> distance(N, std::numeric_limits<short>::max()); std::vector<int> parent(N,-1); - + distance[z] = 0; parent[z] = z; bool r = boost::bellman_ford_shortest_paths(g, int(N), weight, distance.begin(), parent.begin()); - if (r) + if (r) for (int i = 0; i < N; ++i) std::cout << name[i] << ": " << distance[i] << " " << name[parent[i]] << std::endl; @@ -145,7 +145,7 @@

    Associated Types



    The type for the edge descriptors associated with the -edge_list. +edge_list.
    @@ -218,4 +218,4 @@

    Non-Member Functions

    - + diff --git a/doc/edge_predecessor_recorder.html b/doc/edge_predecessor_recorder.html index e9bee01dc..f4b0be765 100644 --- a/doc/edge_predecessor_recorder.html +++ b/doc/edge_predecessor_recorder.html @@ -1,17 +1,17 @@ Boost Graph Library: edge_predecessor_recorder - -C++ Boost + +C++ Boost
    @@ -188,7 +188,7 @@

    See Also

    - + Boost Graph Library: Edmonds-Karp Maximum Flow - -C++ Boost + +C++ Boost
    @@ -23,20 +23,20 @@

    // named parameter version template <class Graph, class P, class T, class R> typename detail::edge_capacity_value<Graph, P, T, R>::value_type -edmonds_karp_max_flow(Graph& g, +edmonds_karp_max_flow(Graph& g, typename graph_traits<Graph>::vertex_descriptor src, typename graph_traits<Graph>::vertex_descriptor sink, const bgl_named_params<P, T, R>& params = all defaults) // non-named parameter version -template <class Graph, +template <class Graph, class CapacityEdgeMap, class ResidualCapacityEdgeMap, class ReverseEdgeMap, class ColorMap, class PredEdgeMap> typename property_traits<CapacityEdgeMap>::value_type -edmonds_karp_max_flow(Graph& g, +edmonds_karp_max_flow(Graph& g, typename graph_traits<Graph>::vertex_descriptor src, typename graph_traits<Graph>::vertex_descriptor sink, - CapacityEdgeMap cap, ResidualCapacityEdgeMap res, ReverseEdgeMap rev, + CapacityEdgeMap cap, ResidualCapacityEdgeMap res, ReverseEdgeMap rev, ColorMap color, PredEdgeMap pred)

    @@ -48,7 +48,7 @@

    maximum flow will be the return value of the function. The function also calculates the flow values f(u,v) for all (u,v) in E, which are returned in the form of the residual capacity -r(u,v) = c(u,v) - f(u,v). +r(u,v) = c(u,v) - f(u,v).

    There are several special requirements on the input graph and property @@ -112,12 +112,12 @@

    Parameters

    The source vertex for the flow network graph.
    - + IN: vertex_descriptor sink
    The sink vertex for the flow network graph.
    - +

    Named Parameters

    @@ -129,7 +129,7 @@

    Named Parameters

    key type of the map must be the graph's edge descriptor type.
    Default: get(edge_capacity, g)

  • - + OUT: residual_capacity_map(ResidualCapacityEdgeMap res)
    This maps edges to their residual capacity. The type must be a model @@ -228,7 +228,7 @@

    See Also

    - + Boost Graph Library: Exceptions - -C++ Boost + +C++ Boost
    diff --git a/doc/faq.html b/doc/faq.html index c77fca5db..53c9c38f6 100644 --- a/doc/faq.html +++ b/doc/faq.html @@ -1,17 +1,17 @@ Boost Graph Library: FAQ - -C++ Boost + +C++ Boost
    @@ -76,8 +76,8 @@

    Frequently Asked Questions

    weren't other strong reasons, it was enough for us to choose free functions.

    - -

    + +

    Our religious reason for choosing free functions is to send the message that BGL is a generic library, and not a traditional object-oriented library. OO was hip in the 80s and 90s, but its time we moved beyond! @@ -124,13 +124,13 @@

    Frequently Asked Questions

    not being found, such as:
     ../../../boost/concept_check.hpp:209: no match for
    -`boost::detail::error_property_not_found & == 
    +`boost::detail::error_property_not_found & ==
      boost::detail::error_property_not_found &'
     
    or a message such as:
     ../../..\boost/graph/depth_first_search.hpp(78) : error C2664: 'white'
    -: cannot convert parameter 1 from 
    +: cannot convert parameter 1 from
      'struct boost::detail::error_property_not_found'
      to 'enum boost::default_color_type'
     
    diff --git a/doc/figs/adj_list.fig b/doc/figs/adj_list.fig index ebe19a3b2..82bd57e47 100644 --- a/doc/figs/adj_list.fig +++ b/doc/figs/adj_list.fig @@ -2,7 +2,7 @@ Landscape Center Inches -Letter +Letter 100.00 Single -2 diff --git a/doc/figs/adj_matrix.fig b/doc/figs/adj_matrix.fig index a0664312e..5f8985e16 100644 --- a/doc/figs/adj_matrix.fig +++ b/doc/figs/adj_matrix.fig @@ -2,7 +2,7 @@ Landscape Center Inches -Letter +Letter 100.00 Single -2 diff --git a/doc/figs/analogy.fig b/doc/figs/analogy.fig index 079ad97bc..dfc0e95fc 100644 --- a/doc/figs/analogy.fig +++ b/doc/figs/analogy.fig @@ -2,7 +2,7 @@ Landscape Center Inches -Letter +Letter 100.00 Single -2 diff --git a/doc/figs/back_edges.fig b/doc/figs/back_edges.fig index f36892e81..842435104 100644 --- a/doc/figs/back_edges.fig +++ b/doc/figs/back_edges.fig @@ -2,7 +2,7 @@ Landscape Center Inches -Letter +Letter 100.00 Single -2 diff --git a/doc/figs/bfs_example.fig b/doc/figs/bfs_example.fig index 4adf2a91f..ad1dec960 100644 --- a/doc/figs/bfs_example.fig +++ b/doc/figs/bfs_example.fig @@ -2,7 +2,7 @@ Portrait Center Inches -Letter +Letter 100.00 Single -2 diff --git a/doc/figs/bfs_family.fig b/doc/figs/bfs_family.fig index f3de67c68..ad40d897f 100644 --- a/doc/figs/bfs_family.fig +++ b/doc/figs/bfs_family.fig @@ -2,7 +2,7 @@ Landscape Center Inches -Letter +Letter 100.00 Single -2 diff --git a/doc/figs/bfs_visitor.fig b/doc/figs/bfs_visitor.fig index cb85d86b1..0996cf83f 100644 --- a/doc/figs/bfs_visitor.fig +++ b/doc/figs/bfs_visitor.fig @@ -2,7 +2,7 @@ Landscape Center Inches -Letter +Letter 100.00 Single -2 diff --git a/doc/figs/concepts.fig b/doc/figs/concepts.fig index d976f733a..97b2f9bd9 100644 --- a/doc/figs/concepts.fig +++ b/doc/figs/concepts.fig @@ -2,7 +2,7 @@ Landscape Center Inches -Letter +Letter 100.00 Single -2 diff --git a/doc/figs/dfs.fig b/doc/figs/dfs.fig index aff4b2b8d..45feb4e9c 100644 --- a/doc/figs/dfs.fig +++ b/doc/figs/dfs.fig @@ -2,7 +2,7 @@ Landscape Center Inches -Letter +Letter 100.00 Single -2 diff --git a/doc/figs/dfs_example.fig b/doc/figs/dfs_example.fig index ebd3cdfcb..021adae9e 100644 --- a/doc/figs/dfs_example.fig +++ b/doc/figs/dfs_example.fig @@ -2,7 +2,7 @@ Landscape Center Inches -Letter +Letter 100.00 Single -2 diff --git a/doc/figs/dfs_family.fig b/doc/figs/dfs_family.fig index aa3958ac1..851eb868c 100644 --- a/doc/figs/dfs_family.fig +++ b/doc/figs/dfs_family.fig @@ -2,7 +2,7 @@ Landscape Center Inches -Letter +Letter 100.00 Single -2 diff --git a/doc/figs/dfs_visitor.fig b/doc/figs/dfs_visitor.fig index d4d351a66..0d2a284c6 100644 --- a/doc/figs/dfs_visitor.fig +++ b/doc/figs/dfs_visitor.fig @@ -2,7 +2,7 @@ Landscape Center Inches -Letter +Letter 100.00 Single -2 diff --git a/doc/figs/digraph.fig b/doc/figs/digraph.fig index d6fc204a5..a56b4cca3 100644 --- a/doc/figs/digraph.fig +++ b/doc/figs/digraph.fig @@ -2,7 +2,7 @@ Landscape Center Inches -Letter +Letter 100.00 Single -2 diff --git a/doc/figs/disjoint_set_family.fig b/doc/figs/disjoint_set_family.fig index 309904282..0a71d0017 100644 --- a/doc/figs/disjoint_set_family.fig +++ b/doc/figs/disjoint_set_family.fig @@ -2,7 +2,7 @@ Landscape Center Inches -Letter +Letter 100.00 Single -2 diff --git a/doc/figs/edge_list.fig b/doc/figs/edge_list.fig index dc3759754..cce549ce0 100644 --- a/doc/figs/edge_list.fig +++ b/doc/figs/edge_list.fig @@ -2,7 +2,7 @@ Landscape Center Inches -Letter +Letter 100.00 Single -2 diff --git a/doc/figs/file_dep.fig b/doc/figs/file_dep.fig index 1259102a8..edd41f1f8 100644 --- a/doc/figs/file_dep.fig +++ b/doc/figs/file_dep.fig @@ -2,7 +2,7 @@ Landscape Center Inches -Letter +Letter 100.00 Single -2 diff --git a/doc/figs/forward_or_cross_edges.fig b/doc/figs/forward_or_cross_edges.fig index d88245a79..b7dc619ee 100644 --- a/doc/figs/forward_or_cross_edges.fig +++ b/doc/figs/forward_or_cross_edges.fig @@ -2,7 +2,7 @@ Landscape Center Inches -Letter +Letter 100.00 Single -2 diff --git a/doc/figs/graph_search.fig b/doc/figs/graph_search.fig index ef66e059a..ffc67b99c 100644 --- a/doc/figs/graph_search.fig +++ b/doc/figs/graph_search.fig @@ -2,7 +2,7 @@ Landscape Center Inches -Letter +Letter 100.00 Single -2 diff --git a/doc/figs/knights_tour.fig b/doc/figs/knights_tour.fig index 5035bcf4a..d9a4e1213 100644 --- a/doc/figs/knights_tour.fig +++ b/doc/figs/knights_tour.fig @@ -2,7 +2,7 @@ Landscape Center Inches -Letter +Letter 100.00 Single -2 diff --git a/doc/figs/quick_start.fig b/doc/figs/quick_start.fig index 23226637f..e71c7aed4 100644 --- a/doc/figs/quick_start.fig +++ b/doc/figs/quick_start.fig @@ -2,7 +2,7 @@ Landscape Center Inches -Letter +Letter 100.00 Single -2 diff --git a/doc/figs/search_states.fig b/doc/figs/search_states.fig index f44776f5f..b3109807a 100644 --- a/doc/figs/search_states.fig +++ b/doc/figs/search_states.fig @@ -2,7 +2,7 @@ Landscape Center Inches -Letter +Letter 100.00 Single -2 diff --git a/doc/figs/tree_edges.fig b/doc/figs/tree_edges.fig index 6143bc8b0..747c91330 100644 --- a/doc/figs/tree_edges.fig +++ b/doc/figs/tree_edges.fig @@ -2,7 +2,7 @@ Landscape Center Inches -Letter +Letter 100.00 Single -2 diff --git a/doc/figs/undigraph.fig b/doc/figs/undigraph.fig index 776037611..d2e0d691b 100644 --- a/doc/figs/undigraph.fig +++ b/doc/figs/undigraph.fig @@ -2,7 +2,7 @@ Landscape Center Inches -Letter +Letter 100.00 Single -2 diff --git a/doc/figs/visitor.fig b/doc/figs/visitor.fig index d4d351a66..0d2a284c6 100644 --- a/doc/figs/visitor.fig +++ b/doc/figs/visitor.fig @@ -2,7 +2,7 @@ Landscape Center Inches -Letter +Letter 100.00 Single -2 diff --git a/doc/file_dependency_example.html b/doc/file_dependency_example.html index f5def38c5..bbf1d03eb 100644 --- a/doc/file_dependency_example.html +++ b/doc/file_dependency_example.html @@ -1,17 +1,17 @@ File Dependency Example - -C++ Boost + +C++ Boost
    @@ -108,9 +108,9 @@

    Graph Setup

    -  enum files_e { dax_h, yow_h, boz_h, zow_h, foo_cpp, 
    +  enum files_e { dax_h, yow_h, boz_h, zow_h, foo_cpp,
                      foo_o, bar_cpp, bar_o, libfoobar_a,
    -                 zig_cpp, zig_o, zag_cpp, zag_o, 
    +                 zig_cpp, zig_o, zag_cpp, zag_o,
                      libzigzag_a, killerapp, N };
       const char* name[] = { "dax.h", "yow.h", "boz.h", "zow.h", "foo.cpp",
                              "foo.o", "bar.cpp", "bar.o", "libfoobar.a",
    @@ -122,7 +122,7 @@ 

    Graph Setup

    Edge(dax_h, foo_cpp), Edge(dax_h, bar_cpp), Edge(dax_h, yow_h), Edge(yow_h, bar_cpp), Edge(yow_h, zag_cpp), Edge(boz_h, bar_cpp), Edge(boz_h, zig_cpp), Edge(boz_h, zag_cpp), - Edge(zow_h, foo_cpp), + Edge(zow_h, foo_cpp), Edge(foo_cpp, foo_o), Edge(foo_o, libfoobar_a), Edge(bar_cpp, bar_o), @@ -136,7 +136,7 @@

    Graph Setup

    }; using namespace boost; - typedef adjacency_list<vecS, vecS, bidirectionalS, + typedef adjacency_list<vecS, vecS, bidirectionalS, property<vertex_color_t, default_color_type> > Graph; Graph g(used_by, used_by + sizeof(used_by) / sizeof(Edge), N); @@ -175,7 +175,7 @@

    Compilation Order (All Files)

    typedef std::list<Vertex> MakeOrder; MakeOrder make_order; boost::topological_sort(g, std::front_inserter(make_order)); - + std::cout << "make ordering: "; for (MakeOrder::iterator i = make_order.begin(); i != make_order.end(); ++i) @@ -229,7 +229,7 @@

    zero.

    -    for (i = make_order.begin(); i != make_order.end(); ++i) {    
    +    for (i = make_order.begin(); i != make_order.end(); ++i) {
           if (in_degree (*i, g) > 0) {
             Graph::in_edge_iterator j, j_end;
             int maxdist = 0;
    @@ -253,8 +253,8 @@ 

    The output is:
    -  parallel make ordering, 
    -    vertices with same group number 
    +  parallel make ordering,
    +    vertices with same group number
         can be made in parallel
       time_slot[dax.h] = 0
       time_slot[yow.h] = 1
    @@ -289,7 +289,7 @@ 

    href="./depth_first_search.html">depth-first search, and if the search runs into an already discovered vertex (of the current search tree), then there is a cycle. The BGL graph search algorithms (which -includes +includes depth_first_search()) are all extensible via the visitor mechanism. A visitor is similar to a function object, but it has several methods instead of just the one @@ -304,7 +304,7 @@

    method, which is the DFSVisitor method that is called when DFS explores an edge to an already discovered vertex. A call to this method indicates the existence of a -cycle. Inheriting from dfs_visitor<> +cycle. Inheriting from dfs_visitor<> provides the visitor with empty versions of the other visitor methods. Once our visitor is created, we can construct and object and pass it to the BGL algorithm. Visitor objects are passed by value inside of @@ -315,7 +315,7 @@

       struct cycle_detector : public dfs_visitor<>
       {
    -    cycle_detector( bool& has_cycle) 
    +    cycle_detector( bool& has_cycle)
           : _has_cycle(has_cycle) { }
     
         template <class Edge, class Graph>
    @@ -360,4 +360,4 @@ 

    - + diff --git a/doc/filtered_graph.html b/doc/filtered_graph.html index 2b4b9675a..66527b0e9 100644 --- a/doc/filtered_graph.html +++ b/doc/filtered_graph.html @@ -1,17 +1,17 @@ Boost Graph Library: Filtered Graph - -C++ Boost + +C++ Boost
    @@ -71,7 +71,7 @@

    Example

    int main() { using namespace boost; - + typedef adjacency_list<vecS, vecS, directedS, no_property, property<edge_weight_t, int> > Graph; typedef property_map<Graph, edge_weight_t>::type EdgeWeightMap; @@ -85,7 +85,7 @@

    Example

    add_edge(C, E, 0, g); add_edge(D, B, 3, g); add_edge(E, C, 0, g); - + positive_edge_weight<EdgeWeightMap> filter(get(edge_weight, g)); filtered_graph<Graph, positive_edge_weight<EdgeWeightMap> > fg(g, filter); @@ -95,19 +95,19 @@

    Example

    std::cout << "filtered out-edges:" << std::endl; print_graph(fg, name); - + return 0; }
    The output is:
    -filtered edge set: (A,B) (C,D) (D,B) 
    +filtered edge set: (A,B) (C,D) (D,B)
     filtered out-edges:
    -A --> B 
    -B --> 
    -C --> D 
    -D --> B 
    -E --> 
    +A --> B
    +B -->
    +C --> D
    +D --> B
    +E -->
     

    @@ -274,7 +274,7 @@

    Associated Types

    and
    property_map<filtered_graph, Property>::const_type

    -The property map type for vertex or edge properties in the graph. +The property map type for vertex or edge properties in the graph. The same property maps from the adapted graph are available in the filtered graph. @@ -405,7 +405,7 @@

    Structure Access

    degree_size_type in_degree(vertex_descriptor u, const filtered_graph& g)
    -Returns the number of edges entering vertex u. +Returns the number of edges entering vertex u.
    @@ -413,7 +413,7 @@

    Structure Access

    vertices_size_type num_vertices(const filtered_graph& g)
    -Returns the number of vertices in the underlying graph [2]. +Returns the number of vertices in the underlying graph [2].
    @@ -514,7 +514,7 @@

    Notes

    calculate, and the second is that it would interact badly with the underlying vertex/edge index mappings. The index mapping would no longer fall in the range [0,num_vertices(g)) (resp. [0, -num_edges(g))) which is assumed in many of the algorithms. +num_edges(g))) which is assumed in many of the algorithms.
    @@ -532,4 +532,4 @@

    Notes

    - + diff --git a/doc/find_flow_cost.html b/doc/find_flow_cost.html index 7f839cf90..63c0274be 100644 --- a/doc/find_flow_cost.html +++ b/doc/find_flow_cost.html @@ -1,17 +1,17 @@ Boost Graph Library: Find Flow Cost - -C++ Boost + +C++ Boost
    @@ -29,19 +29,19 @@

    // non-named parameter version template<class Graph, class Capacity, class ResidualCapacity, class Weight> typename property_traits<typename property_map < Graph, edge_capacity_t >::type>::value_type -find_flow_cost(const Graph & g, Capacity capacity, ResidualCapacity residual_capacity, Weight weight) +find_flow_cost(const Graph & g, Capacity capacity, ResidualCapacity residual_capacity, Weight weight)

    The find_flow_cost() function calculates the minimum cost maximum flow value of a network and given flow. See Section Network -Flow Algorithms for a description of maximum flow. +Flow Algorithms for a description of maximum flow. The function calculates the cost from the flow values f(u,v) for (u,v) in E, which are passed in the form of the residual capacity -r(u,v) = c(u,v) - f(u,v). +r(u,v) = c(u,v) - f(u,v).

    -In order to compute the min cost max flow use : +In order to compute the min cost max flow use : successive_shortest_path_nonnegative_weights() or cycle_canceling(). @@ -73,7 +73,7 @@

    Named Parameters

    key type of the map must be the graph's edge descriptor type.
    Default: get(edge_capacity, g)
    - + IN: residual_capacity_map(ResidualCapacityEdgeMap res)
    This maps edges to their residual capacity. The type must be a model @@ -85,7 +85,7 @@

    Named Parameters

    -IN: weight_map(WeightMap w_map) +IN: weight_map(WeightMap w_map)
    The weight or ``cost'' of each edge in the graph. The type WeightMap must be a model of @@ -98,7 +98,7 @@

    Named Parameters

    Complexity

    -The complexity is O(|E|), +The complexity is O(|E|),

    Example

    @@ -119,7 +119,7 @@

    See Also

    - + Floyd-Warshall All Pairs Shortest Paths - -C++ Boost + +C++ Boost
    @@ -62,7 +62,7 @@

    This algorithm should be used to compute shortest paths between every pair of vertices for dense graphs. For sparse graphs, use johnson_all_pairs_shortest_paths. +href="johnson_all_pairs_shortest.html">johnson_all_pairs_shortest_paths.

    Where Defined

    @@ -81,14 +81,14 @@

    Parameters

    OUT: DistanceMatrix& d
    The length of the shortest path between each pair of vertices -u,v are +u,v are stored in the matrix at location D[u][v]. The -DistanceMatrix must be +DistanceMatrix must be of type {M, I, V} where I is of type vertex_descriptor and V is the type of the weight_map. The set of types must be a model of BasicMatrix, with the exceptions that -it isn't required to +it isn't required to run in constant time, and it must be mutable. The matrix must be properly initialized when it is passed to the function floyd_warshall_initialized_all_pairs_shortest_paths. If the @@ -102,7 +102,7 @@

    Named Parameters

    The weight of length of each edge in the graph. The WeightMap must be a model of Readable Property -Map. The edge descriptor +Map. The edge descriptor type of the graph needs to be usable as the key type for the weight map. The value_type of the weight map must be the type of the DistanceMatrix, and must always either be part of the @@ -164,4 +164,4 @@

    Complexity

    - + diff --git a/doc/fruchterman_reingold.html b/doc/fruchterman_reingold.html index 738d253f5..a47f35cd7 100644 --- a/doc/fruchterman_reingold.html +++ b/doc/fruchterman_reingold.html @@ -1,7 +1,7 @@ Graph Coloring Example - -C++ Boost + +C++ Boost
    @@ -112,11 +112,11 @@

    Graph Coloring

     namespace boost {
    -  template <class VertexListGraph, class Order, class Degree, 
    +  template <class VertexListGraph, class Order, class Degree,
                 class Marker, class BucketSorter>
    -  void 
    -  smallest_last_ordering(const VertexListGraph& G, Order order, 
    -                         Degree degree, Marker marker, 
    +  void
    +  smallest_last_ordering(const VertexListGraph& G, Order order,
    +                         Degree degree, Marker marker,
                              BucketSorter& degree_buckets) {
         typedef typename graph_traits<VertexListGraph> GraphTraits;
     
    @@ -125,43 +125,43 @@ 

    Graph Coloring

    typedef size_t size_type; const size_type num = num_vertices(G); - + typename GraphTraits::vertex_iterator v, vend; for (boost::tie(v, vend) = vertices(G); v != vend; ++v) { put(marker, *v, num); put(degree, *v, out_degree(*v, G)); degree_buckets.push(*v); } - + size_type minimum_degree = 1; size_type current_order = num - 1; - + while ( 1 ) { typedef typename BucketSorter::stack MDStack; MDStack minimum_degree_stack = degree_buckets[minimum_degree]; while (minimum_degree_stack.empty()) minimum_degree_stack = degree_buckets[++minimum_degree]; - + Vertex node = minimum_degree_stack.top(); put(order, current_order, node); - + if ( current_order == 0 ) //find all vertices break; - + minimum_degree_stack.pop(); put(marker, node, 0); //node has been ordered. - + typename GraphTraits::adjacency_iterator v, vend; for (boost::tie(v,vend) = adjacent_vertices(node, G); v != vend; ++v) - + if ( get(marker, *v) > current_order ) { //*v is unordered vertex put(marker, *v, current_order); //mark the columns adjacent to node - + //It is possible minimum degree goes down //Here we keep tracking it. - put(degree, *v, get(degree, *v) - 1); - minimum_degree = std::min(minimum_degree, get(degree, *v)); - + put(degree, *v, get(degree, *v) - 1); + minimum_degree = std::min(minimum_degree, get(degree, *v)); + //update the position of *v in the bucket sorter degree_buckets.update(*v); } @@ -188,4 +188,4 @@

    Graph Coloring

    - + diff --git a/doc/graph_concepts.html b/doc/graph_concepts.html index 64898b24d..413ab5297 100644 --- a/doc/graph_concepts.html +++ b/doc/graph_concepts.html @@ -1,17 +1,17 @@ Boost Graph Concepts - -C++ Boost + +C++ Boost
    @@ -130,30 +130,30 @@

    Notation

    Table 1: Summary of the graph concepts. - + - - - - - @@ -163,201 +163,201 @@

    Notation

    the graph can be visited. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    Expression Return Type or Description
    +
    Graph
    +
    boost::graph_traits<G>::vertex_descriptor The type for vertex representative objects.
    +
    boost::graph_traits<G>::edge_descriptor The type for edge representative objects.
    +
    boost::graph_traits<G>::directed_category Directed or undirected?
    +
    boost::graph_traits<G>::edge_parallel_category Allow parallel edges?
    +
    IncidenceGraph refines Graph
    +
    boost::graph_traits<G>::out_edge_iterator Iterate through the out-edges.
    +
    boost::graph_traits<G>::degree_size_type The integer type for vertex degree.
    +
    out_edges(v, g) std::pair<out_edge_iterator, out_edge_iterator>
    +
    source(e, g) vertex_descriptor
    +
    target(e, g) vertex_descriptor
    +
    out_degree(v, g) degree_size_type
    +
    BidirectionalGraph refines IncidenceGraph
    +
    boost::graph_traits<G>::in_edge_iterator Iterate through the in-edges.
    +
    in_edges(v, g) std::pair<in_edge_iterator, in_edge_iterator>
    +
    in_degree(v, g) degree_size_type
    +
    degree(e, g) degree_size_type
    +
    AdjacencyGraph refines Graph
    +
    boost::graph_traits<G>::adjacency_iterator Iterate through adjacent vertices.
    +
    adjacent_vertices(v, g) std::pair<adjacency_iterator, adjacency_iterator>
    +
    VertexListGraph refines Graph
    +
    boost::graph_traits<G>::vertex_iterator Iterate through the graph's vertex set.
    +
    boost::graph_traits<G>::vertices_size_type The unsigned integer type for number of vertices in the graph.
    +
    vertices(g) std::pair<vertex_iterator, vertex_iterator>
    +
    num_vertices(g) vertices_size_type
    +
    EdgeListGraph refines Graph
    +
    boost::graph_traits<G>::edge_iterator Iterate through the graph's edge set.
    +
    boost::graph_traits<G>::edges_size_type The unsigned integer type for number of edges in the graph.
    +
    edges(g) std::pair<edge_iterator, edge_iterator>
    +
    num_edges(g) edges_size_type
    +
    source(e, g) vertex_descriptor
    +
    target(e, g) vertex_descriptor
    +
    AdjacencyMatrix refines Graph
    +
    edge(u, v, g) std::pair<edge_descriptor, bool>
    +
    MutableGraph refines Graph
    +
    add_vertex(g) vertex_descriptor
    +
    clear_vertex(v, g) void
    +
    remove_vertex(v, g) void
    +
    add_edge(u, v, g) std::pair<edge_descriptor, bool>
    +
    remove_edge(u, v, g) void
    +
    remove_edge(e, g) void
    +
    remove_edge(e_iter, g) void
    +
    MutablePropertyGraph refines Graph
    +
    add_vertex(vp, g) vertex_descriptor
    +
    add_edge(u, v, ep, g) std::pair<edge_descriptor, bool>
    + PropertyGraph refines Graph
    +
    boost::property_map<G, Property>::type Type for a mutable property map.
    +
    boost::property_map<G, Property>::const_type Type for a non-mutable property map.
    +
    get(property, g) Function to get a property map.
    +
    get(property, g, x) Get property value for vertex or edge x.
    +
    put(property, g, x, v) Set property value for vertex or edge @@ -406,10 +406,10 @@

    std::cout << "the edges incident to v: "; boost::graph_traits<UndirectedGraph>::out_edge_iterator e, e_end; - boost::graph_traits<UndirectedGraph>::vertex_descriptor + boost::graph_traits<UndirectedGraph>::vertex_descriptor s = vertex(0, undigraph); for (boost::tie(e, e_end) = out_edges(s, undigraph); e != e_end; ++e) - std::cout << "(" << source(*e, undigraph) + std::cout << "(" << source(*e, undigraph) << "," << target(*e, undigraph) << ")" << endl; @@ -495,4 +495,4 @@

    - + diff --git a/doc/graph_theory_review.html b/doc/graph_theory_review.html index 6fec7b73b..d48957275 100644 --- a/doc/graph_theory_review.html +++ b/doc/graph_theory_review.html @@ -2,17 +2,17 @@ Boost Graph Library: Graph Theory Review - -C++ Boost + +C++ Boost
    @@ -352,7 +352,7 @@

    -  order of discovery: s r w v t x u y 
    +  order of discovery: s r w v t x u y
       order of finish: s r w v t x u y
     
    @@ -452,7 +452,7 @@

    Minimum Spanning Tree Problem

    HREF="bibliography.html#kruskal56">18] for solving the minimum spanning tree problem. This is a greedy algorithm to calculate the minimum spanning tree for an undirected -graph with weighted edges. +graph with weighted edges.

    This is Prim's algorithm [Directed Graphs - + diff --git a/doc/graph_traits.html b/doc/graph_traits.html index 4c336e3ab..ab3fa12dc 100644 --- a/doc/graph_traits.html +++ b/doc/graph_traits.html @@ -1,17 +1,17 @@ Boost Graph Library: Graph Traits - -C++ Boost + +C++ Boost
    @@ -197,12 +197,12 @@

    Members

    The ways in which the vertices in the graph can be traversed. -The traversal category tags are: +The traversal category tags are: incidence_graph_tag, adjacency_graph_tag, bidirectional_graph_tag, vertex_list_graph_tag, edge_list_graph_tag, vertex_and_edge_list_graph_tag, adjacency_matrix_tag. You can also create your own -tag which should inherit from one of the above. +tag which should inherit from one of the above. @@ -253,4 +253,4 @@

    Members

    - + diff --git a/doc/grid_graph.html b/doc/grid_graph.html index 2a7b509de..261dd57cf 100644 --- a/doc/grid_graph.html +++ b/doc/grid_graph.html @@ -1,7 +1,7 @@ @@ -48,7 +48,7 @@

  • Grid Graph Member Functions
  • -

    Overview

    +

    Overview

    A grid_graph represents a multi-dimensional, rectangular grid of vertices with user-defined dimension lengths @@ -130,7 +130,7 @@

    Example


    Figure 2: A 3x3 two-dimensional, wrapped grid graph -

    +


    Indexing

    @@ -243,7 +243,7 @@

    Member Functions

    // dimension is unwrapped, previous will stop at the beginning vertex in the dimension. Traits::vertex_descriptor previous(Traits::vertex_descriptor vertex, std::size_t dimension, - Traits::vertices_size_type distance = 1); + Traits::vertices_size_type distance = 1);

    Example

    @@ -301,4 +301,4 @@

    Example

    Copyright © 2009 Trustees of Indiana University - + diff --git a/doc/gursoy_atun_layout.html b/doc/gursoy_atun_layout.html index f65cf5efd..1c180a35e 100644 --- a/doc/gursoy_atun_layout.html +++ b/doc/gursoy_atun_layout.html @@ -1,7 +1,7 @@ Boost Graph Library: History - -C++ Boost + +C++ Boost
    @@ -121,7 +121,7 @@

    Changes by version

  • Bundled properties now work with adjacency list I/O.
  • floyd_warshall_all_pairs_shortest_paths now properly uses its compare, inf, and zero parameters.
  • johnson_all_pairs_shortest_paths now supports compare, combine, inf, and zero.
  • -
  • Fixed a bug in smallest_last_vertex_ordering.hpp which could cause a vertex to be moved to the wrong bucket during an BucketSorter update. +
  • Fixed a bug in smallest_last_vertex_ordering.hpp which could cause a vertex to be moved to the wrong bucket during an BucketSorter update.
  • @@ -153,7 +153,7 @@

    Changes by version

  • dijkstra_shortest_paths now uses a relaxed heap [61] as its priority queue, improving its complexity to O(V log V) and improving real-world performance for larger graphs.
  • read_graphviz now has a new, Spirit-based parser that works for all graph types and supports arbitrary properties on the graph, from Ron Garcia. The old, Bison-based GraphViz reader has been deprecated and will be removed in a future Boost release.
  • - +
  • write_graphviz now supports output of dynamic properties (as read in through the @@ -164,7 +164,7 @@

    Changes by version

    has been recast as an invocation of breadth_first_search and now supports graphs with multiple components.
  • - +
  • subgraph now supports bundled properties. get_property now refers to the @@ -205,7 +205,7 @@

    Changes by version

    - + Boost Graph Library: incident - -C++ Boost + +C++ Boost
    @@ -76,4 +76,4 @@

    Example

    - + diff --git a/doc/incremental_components.html b/doc/incremental_components.html index a6be2b077..181791be3 100644 --- a/doc/incremental_components.html +++ b/doc/incremental_components.html @@ -1,7 +1,7 @@ - -C++ Boost + +C++ Boost
    @@ -54,22 +54,22 @@

    Incremental Connected Components

      -
    • initialize_incremental_components(g, ds) +
    • initialize_incremental_components(g, ds)
      Basic initialization of the disjoint-sets structure. Each vertex in the graph g is in its own set.
    • -
    • incremental_components(g, ds) +
    • incremental_components(g, ds)
      The connected components are calculated based on the edges in the graph g and the information is embedded in ds.
    • -
    • ds.find_set(v) +
    • ds.find_set(v)
      Extracts the component information for vertex v from the disjoint-sets.
    • -
    • ds.union_set(u, v) +
    • ds.union_set(u, v)
      Update the disjoint-sets structure when edge (u,v) is added to the graph.
    • @@ -103,7 +103,7 @@

      Example

       using namespace boost;
       
      -int main(int argc, char* argv[]) 
      +int main(int argc, char* argv[])
       {
         typedef adjacency_list  Graph;
         typedef graph_traits::vertex_descriptor Vertex;
      @@ -137,11 +137,11 @@ 

      Example

      boost::tie(edge, flag) = add_edge(2, 5, graph); ds.union_set(2,5); - + std::cout << "An undirected graph:" << std::endl; print_graph(graph, get(boost::vertex_index, graph)); std::cout << std::endl; - + BOOST_FOREACH(Vertex current_vertex, vertices(graph)) { std::cout << "representative[" << current_vertex << "] = " << ds.find_set(current_vertex) << std::endl; @@ -199,7 +199,7 @@

      -template <class VertexListGraph, class DisjointSets> 
      +template <class VertexListGraph, class DisjointSets>
       void initialize_incremental_components(VertexListGraph& G, DisjointSets& ds)
       
      @@ -350,7 +350,7 @@

      Where Defined

      Members

      - + @@ -392,7 +392,7 @@

      Members

      Returns an iterator past the end of the component indices (size()). - + -
      std::pair<component_iterator, component_iterator> operator[size_type index] const @@ -400,7 +400,7 @@

      Members

      +


      @@ -417,4 +417,4 @@

      Members

      - + diff --git a/doc/index.html b/doc/index.html index 61bc71b15..3a7b9d89a 100644 --- a/doc/index.html +++ b/doc/index.html @@ -3,7 +3,7 @@ Boost Graph Library: is_kuratowski_subgraph - -C++ Boost + +C++ Boost
      @@ -24,47 +24,47 @@

      is_kuratowski_subgraph

      -is_kuratowski_subgraph(g, begin, end) returns true exactly -when the sequence of edges defined by the range [begin, end) forms a - Kuratowski subgraph in -the graph g. If you need to verify that an arbitrary graph has a -K5 or K3,3 minor, you should use the +is_kuratowski_subgraph(g, begin, end) returns true exactly +when the sequence of edges defined by the range [begin, end) forms a + Kuratowski subgraph in +the graph g. If you need to verify that an arbitrary graph has a +K5 or K3,3 minor, you should use the function boyer_myrvold_planarity_test to isolate such a minor instead of this function. is_kuratowski_subgraph - exists to aid in testing and verification of the function -boyer_myrvold_planarity_test, and for that reason, it expects its -input to be a restricted set of edges forming a Kuratowski subgraph, as + exists to aid in testing and verification of the function +boyer_myrvold_planarity_test, and for that reason, it expects its +input to be a restricted set of edges forming a Kuratowski subgraph, as described in detail below.

      -is_kuratowski_subgraph creates a temporary graph out of the sequence -of edges given and repeatedly contracts edges until it ends up with a graph -with either all edges of degree 3 or all edges of degree 4. The final +is_kuratowski_subgraph creates a temporary graph out of the sequence +of edges given and repeatedly contracts edges until it ends up with a graph +with either all edges of degree 3 or all edges of degree 4. The final contracted graph is then checked against K5 or -K3,3 using the Boost Graph Library's +K3,3 using the Boost Graph Library's isomorphism function. The contraction process starts by choosing edges adjacent to a vertex -of degree 1 and contracting those. When none are left, it moves on to edges +of degree 1 and contracting those. When none are left, it moves on to edges adjacent to a vertex of degree 2. If only degree 3 vertices are left after this -stage, the graph is checked against K3,3. Otherwise, if -there's at least one degree 4 vertex, edges adjacent to degree 3 vertices are +stage, the graph is checked against K3,3. Otherwise, if +there's at least one degree 4 vertex, edges adjacent to degree 3 vertices are contracted as neeeded and the final graph is compared to K5.

      -In order for this process to be deterministic, we make the following two +In order for this process to be deterministic, we make the following two restrictions on the input graph given to is_kuratowski_subgraph:

        -
      1. No edge contraction needed to produce a kuratowski subgraph results in -multiple edges between the same pair of vertices (No edge {a,b} will be -contracted at any point in the contraction process if a and b +
      2. No edge contraction needed to produce a kuratowski subgraph results in +multiple edges between the same pair of vertices (No edge {a,b} will be +contracted at any point in the contraction process if a and b share a common neighbor.) -
      3. If the graph contracts to a K5, once the graph has -been contracted to only vertices of degree at least 3, no cycles exist that +
      4. If the graph contracts to a K5, once the graph has +been contracted to only vertices of degree at least 3, no cycles exist that contain solely degree 3 vertices.
      -The second restriction is needed both to discriminate between targeting a -K5 or a K3,3 and to determinstically -contract the vertices of degree 4 once the K5 has been +The second restriction is needed both to discriminate between targeting a +K5 or a K3,3 and to determinstically +contract the vertices of degree 4 once the K5 has been targeted. The Kuratowski subgraph output by the function -boyer_myrvold_planarity_test is +boyer_myrvold_planarity_test is guaranteed to meet both of the above requirements. @@ -84,14 +84,14 @@

      Where Defined

      IN: Graph& g
      -An undirected graph with no self-loops or parallel edges. The graph type must +An undirected graph with no self-loops or parallel edges. The graph type must be a model of Vertex List Graph.
      -IN: ForwardIterator +IN: ForwardIterator
      -A ForwardIterator with value_type +A ForwardIterator with value_type graph_traits<Graph>::edge_descriptor.
      @@ -99,7 +99,7 @@

      Where Defined

      A Readable Property Map - that maps vertices from g to distinct integers in the range + that maps vertices from g to distinct integers in the range [0, num_vertices(g) )
      Default: get(vertex_index,g)
      @@ -122,5 +122,5 @@

      Example


      Copyright © 2007 Aaron Windsor ( aaron.windsor@gmail.com) - + diff --git a/doc/is_straight_line_drawing.html b/doc/is_straight_line_drawing.html index 8e8321b1c..0df33ac71 100644 --- a/doc/is_straight_line_drawing.html +++ b/doc/is_straight_line_drawing.html @@ -1,17 +1,17 @@ Boost Graph Library: is_straight_line_drawing - -C++ Boost + +C++ Boost
      @@ -24,11 +24,11 @@

      is_straight_line_drawing

      -If drawing is a property map modeling the PositionMap -concept, is_straight_line_drawing returns true exactly when no two of +If drawing is a property map modeling the PositionMap +concept, is_straight_line_drawing returns true exactly when no two of the line segments induced by edges in the graph under drawing intersect. This function works correctly in the presence of self-loops and -parallel edges, and can be used to verify the output of the function +parallel edges, and can be used to verify the output of the function chrobak_payne_straight_line_embedding. @@ -53,15 +53,15 @@

      Parameters

      href="EdgeListGraph.html">Edge List Graph
  • -IN: PositionMap +IN: PositionMap
    -A Readable LValue Property +A Readable LValue Property Map that models the Position Map concept. The Position Map concept requires that the value mapped to be an object that has members x and y. For example, if p models PositionMap and v is a vertex in the graph, p[v].x and p[v].y are valid -expressions. The type of x and y must be implicitly +expressions. The type of x and y must be implicitly convertable to std::size_t.
    @@ -90,4 +90,4 @@

    See Also


    Copyright © 2007 Aaron Windsor (aaron.windsor@gmail.com) - + diff --git a/doc/isomorphism-impl-v2.w b/doc/isomorphism-impl-v2.w index 3cf608789..1fd53b8dd 100644 --- a/doc/isomorphism-impl-v2.w +++ b/doc/isomorphism-impl-v2.w @@ -172,7 +172,7 @@ if (iter != ordered_edges.end()) { } else { @ } -} else +} else return true; return false; } // match() @@ -236,7 +236,7 @@ M\=ATCH($k$, $v$) $\equiv$ \\ \>$in_k \leftarrow \forall (j,k) \in E_1[k] - E_1[k-1] \Big( (f(j),v) \in E_2[S \union \{ v \}] - E_2[S] \Big)$ \\ \>$out_v \leftarrow \forall (v,u) \in E_2[S \union \{ v \}] - E_2[S] \Big( (k,f^{-1}(u)) \in E_1[k] - E_1[k-1] \Big)$ \\ \>$in_v \leftarrow \forall (u,v) \in E_2[S \union \{ v \}] - E_2[S] \Big( (f^{-1}(u),k) \in E_1[k] - E_1[k-1] \Big)$ \\ -\>\textbf{return} $out_k \Land in_k \Land out_v \Land in_v$ +\>\textbf{return} $out_k \Land in_k \Land out_v \Land in_v$ \end{tabbing} The problem with the exhaustive backtracking algorithm is that there @@ -324,11 +324,11 @@ requirements on type template parameters are described below in the @d Isomorphism function interface @{ -template -bool isomorphism(const Graph1& G1, const Graph2& G2, IsoMapping f, - Invariant1 invariant1, Invariant2 invariant2, +bool isomorphism(const Graph1& G1, const Graph2& G2, IsoMapping f, + Invariant1 invariant1, Invariant2 invariant2, std::size_t max_invariant, IndexMap1 index_map1, IndexMap2 index_map2) @} @@ -351,9 +351,9 @@ of global variables (non-reentrant, etc.). { @ @ - detail::isomorphism_algo - algo(G1, G2, f, invariant1, invariant2, max_invariant, + detail::isomorphism_algo + algo(G1, G2, f, invariant1, invariant2, max_invariant, index_map1, index_map2); return algo.test_isomorphism(); } @@ -563,7 +563,7 @@ target&1&2&3&1&2&3&5&6&4 The backtracking algorithm will scan through the edge array from left to right to extend isomorphic subgraphs, and move back to the right -when a match fails. We will want to +when a match fails. We will want to @@ -575,7 +575,7 @@ when a match fails. We will want to For example, suppose we have already matched the vertices -\{0,1,2\}, and +\{0,1,2\}, and @@ -648,7 +648,7 @@ class is as follows. EXPLAIN ficticious edges @{ struct record_dfs_order : default_dfs_visitor { - record_dfs_order(std::vector& v, std::vector& e) + record_dfs_order(std::vector& v, std::vector& e) : vertices(v), edges(e) { } void start_vertex(vertex1_t v, const Graph1&) const { @@ -778,7 +778,7 @@ public: + get(m_in_degree_map, v); } // The largest possible vertex invariant number - size_type max() const { + size_type max() const { return num_vertices(m_g) * num_vertices(m_g) + num_vertices(m_g); } private: @@ -886,7 +886,7 @@ BGL_FORALL_ADJACENT_T(f[u], y, G2, Graph2) bool verify = false; assert(f_assigned[u] == true); BGL_FORALL_ADJACENT_T(f[u], y, G2, Graph2) { - if (y == f[v]) { + if (y == f[v]) { verify = true; break; } @@ -929,7 +929,7 @@ namespace boost { namespace detail { @ - + template void compute_in_degree(const Graph& g, InDegreeMap in_degree_map) { @@ -950,12 +950,12 @@ void compute_in_degree(const Graph& g, InDegreeMap in_degree_map) @ namespace detail { - -template -bool isomorphism_impl(const Graph1& G1, const Graph2& G2, +bool isomorphism_impl(const Graph1& G1, const Graph2& G2, IsoMapping f, IndexMap1 index_map1, IndexMap2 index_map2, const bgl_named_params& params) { @@ -977,9 +977,9 @@ bool isomorphism_impl(const Graph1& G1, const Graph2& G2, choose_param(get_param(params, vertex_invariant2_t()), invariant2), choose_param(get_param(params, vertex_max_invariant_t()), invariant2.max()), index_map1, index_map2 - ); -} - + ); +} + } // namespace detail @@ -993,7 +993,7 @@ bool isomorphism(const Graph1& g1, typename std::vector::size_type n = num_vertices(g1); std::vector f(n); return detail::isomorphism_impl - (g1, g2, + (g1, g2, choose_param(get_param(params, vertex_isomorphism_t()), make_safe_iterator_property_map(f.begin(), f.size(), choose_const_pmap(get_param(params, vertex_index1), @@ -1023,7 +1023,7 @@ inline bool verify_isomorphism(const Graph1& g1, const Graph2& g2, IsoMap iso_ma { if (num_vertices(g1) != num_vertices(g2) || num_edges(g1) != num_edges(g2)) return false; - + for (typename graph_traits::edge_iterator e1 = edges(g1).first; e1 != edges(g1).second; ++e1) { bool found_edge = false; @@ -1034,11 +1034,11 @@ inline bool verify_isomorphism(const Graph1& g1, const Graph2& g2, IsoMap iso_ma found_edge = true; } } - + if (!found_edge) return false; } - + return true; } diff --git a/doc/isomorphism-impl-v3.w b/doc/isomorphism-impl-v3.w index 95e87eac4..16740adce 100644 --- a/doc/isomorphism-impl-v3.w +++ b/doc/isomorphism-impl-v3.w @@ -241,7 +241,7 @@ public: + get(m_in_degree_map, v); } // The largest possible vertex invariant number - size_type max() const { + size_type max() const { return num_vertices(m_g) * num_vertices(m_g) + num_vertices(m_g); } private: @@ -302,7 +302,7 @@ bool match(edge_iter iter, int dfs_num_k) else { @ } - } else + } else return true; return false; } @@ -355,7 +355,7 @@ counting, using \code{boost::bind} to create the predicate functor. @d Count out-edges of $f(k)$ in $G_2[S]$ @{ -num_edges_on_k -= +num_edges_on_k -= count_if(adjacent_vertices(f[k], G2), make_indirect_pmap(in_S)); @} @@ -397,7 +397,7 @@ BGL_FORALL_ADJ_T(f[i], v, G2, Graph2) } @} -\paragraph{Case 3: both $i$ and $j$ are in $G_1[k]$.} +\paragraph{Case 3: both $i$ and $j$ are in $G_1[k]$.} Our goal is to check whether $(f(i),f(j)) \in E_2[S]$. If $f(j)$ is in $Adj[f(i)]$ then we have a match for the edge $(i,j)$, and can increment the counter for the number of edges incident on $k$ in @@ -440,11 +440,11 @@ The requirements on the template parameters are described below in the @d Isomorphism function interface @{ -template -bool isomorphism(const Graph1& G1, const Graph2& G2, IsoMapping f, - Invariant1 invariant1, Invariant2 invariant2, +bool isomorphism(const Graph1& G1, const Graph2& G2, IsoMapping f, + Invariant1 invariant1, Invariant2 invariant2, std::size_t max_invariant, EdgeCompare edge_compare, IndexMap1 index_map1, IndexMap2 index_map2) @} @@ -468,8 +468,8 @@ of global variables (non-reentrant, etc.). @ @ detail::isomorphism_algo - algo(G1, G2, f, invariant1, invariant2, max_invariant, + Invariant2, EdgeCompare, IndexMap1, IndexMap2> + algo(G1, G2, f, invariant1, invariant2, max_invariant, edge_compare, index_map1, index_map2); return algo.test_isomorphism(); @@ -696,7 +696,7 @@ class is as follows. @{ struct record_dfs_order : default_dfs_visitor { - record_dfs_order(std::vector& v, std::vector& e) + record_dfs_order(std::vector& v, std::vector& e) : vertices(v), edges(e) { } void discover_vertex(vertex1_t v, const Graph1&) const { @@ -732,7 +732,7 @@ struct edge_cmp { vertex1_t u2 = dfs_num[source(e2,G1)], v2 = dfs_num[target(e2,G1)]; int m1 = max(u1, v1); int m2 = max(u2, v2); - // lexicographical comparison + // lexicographical comparison return make_pair(m1, make_pair(u1, v1)) < make_pair(m2, make_pair(u2, v2)); } @@ -774,7 +774,7 @@ IndexMap2 index_map2; std::vector dfs_vertices; typedef typename std::vector::iterator vertex_iter; std::vector dfs_num_vec; -typedef safe_iterator_property_map::iterator, +typedef safe_iterator_property_map::iterator, IndexMap1> DFSNumMap; DFSNumMap dfs_num; std::vector ordered_edges; @@ -791,7 +791,7 @@ int num_edges_on_k; @d Isomorphism algorithm constructor @{ isomorphism_algo(const Graph1& G1, const Graph2& G2, IsoMapping f, - Invariant1 invariant1, Invariant2 invariant2, + Invariant1 invariant1, Invariant2 invariant2, std::size_t max_invariant, EdgeCompare edge_compare, IndexMap1 index_map1, IndexMap2 index_map2) @@ -836,7 +836,7 @@ namespace boost { namespace detail { @ - + template void compute_in_degree(const Graph& g, InDegreeMap in_degree_map) { @@ -862,23 +862,23 @@ struct default_edge_compare { template bool operator()(Edge1 e1, Edge2 e2) const { return true; } }; - -template -bool isomorphism_impl(const Graph1& G1, const Graph2& G2, +bool isomorphism_impl(const Graph1& G1, const Graph2& G2, IsoMapping f, IndexMap1 index_map1, IndexMap2 index_map2, const bgl_named_params& params) { std::vector in_degree1_vec(num_vertices(G1)); - typedef safe_iterator_property_map::iterator, + typedef safe_iterator_property_map::iterator, IndexMap1> InDeg1; InDeg1 in_degree1(in_degree1_vec.begin(), in_degree1_vec.size(), index_map1); compute_in_degree(G1, in_degree1); std::vector in_degree2_vec(num_vertices(G2)); - typedef safe_iterator_property_map::iterator, + typedef safe_iterator_property_map::iterator, IndexMap2> InDeg2; InDeg2 in_degree2(in_degree2_vec.begin(), in_degree2_vec.size(), index_map2); compute_in_degree(G2, in_degree2); @@ -890,13 +890,13 @@ bool isomorphism_impl(const Graph1& G1, const Graph2& G2, return isomorphism(G1, G2, f, choose_param(get_param(params, vertex_invariant1_t()), invariant1), choose_param(get_param(params, vertex_invariant2_t()), invariant2), - choose_param(get_param(params, vertex_max_invariant_t()), + choose_param(get_param(params, vertex_max_invariant_t()), invariant2.max()), choose_param(get_param(params, edge_compare_t()), edge_cmp), index_map1, index_map2 - ); -} - + ); +} + } // namespace detail @@ -910,7 +910,7 @@ bool isomorphism(const Graph1& g1, typename std::vector::size_type n = num_vertices(g1); std::vector f(n); return detail::isomorphism_impl - (g1, g2, + (g1, g2, choose_param(get_param(params, vertex_isomorphism_t()), make_safe_iterator_property_map(f.begin(), f.size(), choose_const_pmap(get_param(params, vertex_index1), @@ -943,7 +943,7 @@ inline bool verify_isomorphism(const Graph1& g1, const Graph2& g2, IsoMap iso_ma if (num_vertices(g1) != num_vertices(g2) || num_edges(g1) != num_edges(g2)) return false; #endif - + for (typename graph_traits::edge_iterator e1 = edges(g1).first; e1 != edges(g1).second; ++e1) { bool found_edge = false; @@ -954,11 +954,11 @@ inline bool verify_isomorphism(const Graph1& g1, const Graph2& g2, IsoMap iso_ma found_edge = true; } } - + if (!found_edge) return false; } - + return true; } diff --git a/doc/isomorphism-impl.w b/doc/isomorphism-impl.w index 868760c45..48c086a3e 100644 --- a/doc/isomorphism-impl.w +++ b/doc/isomorphism-impl.w @@ -152,7 +152,7 @@ in-edges $(u,v)$ of $v$ where $u \in S$. M\=ATCH($k$, $v$) $\equiv$ \\ \>$out \leftarrow \forall (k,j) \in E_1[k] - E_1[k-1] \Big( (v,f(j)) \in E_2[S \union \{ v \}] - E_2[S] \Big)$ \\ \>$in \leftarrow \forall (j,k) \in E_1[k] - E_1[k-1] \Big( (f(j),v) \in E_2[S \union \{ v \}] - E_2[S] \Big)$ \\ -\>\textbf{return} $out \Land in$ +\>\textbf{return} $out \Land in$ \end{tabbing} The problem with the exhaustive backtracking algorithm is that there @@ -192,7 +192,7 @@ help rule out vertices. M\=A\=T\=C\=H-INVAR($k$, $v$) $\equiv$ \\ \>$out \leftarrow \forall (k,j) \in E_1[k] - E_1[k-1] \Big( (v,f(j)) \in E_2[S \union \{ v \}] - E_2[S] \Land i(v) = i(k) \Big)$ \\ \>$in \leftarrow \forall (j,k) \in E_1[k] - E_1[k-1] \Big( (f(j),v) \in E_2[S \union \{ v \}] - E_2[S] \Land i(v) = i(k) \Big)$ \\ -\>\textbf{return} $out \Land in$ +\>\textbf{return} $out \Land in$ \end{tabbing} \section{Vertex Order} @@ -240,12 +240,12 @@ below in the section ``Concept checking''. @d Isomorphism Function Interface @{ -template -bool isomorphism(const Graph1& g1, const Graph2& g2, - IndexMapping f, +bool isomorphism(const Graph1& g1, const Graph2& g2, + IndexMapping f, VertexInvariant1 invariant1, VertexInvariant2 invariant2, IndexMap1 index_map1, IndexMap2 index_map2) @} @@ -358,7 +358,7 @@ public: + get(m_in_degree_map, v); } // The largest possible vertex invariant number - result_type max() const { + result_type max() const { return num_vertices(m_g) * num_vertices(m_g) + num_vertices(m_g); } private: @@ -414,7 +414,7 @@ invariants, and then check to see if they are equal. invar_vec2_t invar2_tmp(invar2_vec); std::sort(invar1_tmp.begin(), invar1_tmp.end()); std::sort(invar2_tmp.begin(), invar2_tmp.end()); - if (! std::equal(invar1_tmp.begin(), invar1_tmp.end(), + if (! std::equal(invar1_tmp.begin(), invar1_tmp.end(), invar2_tmp.begin())) return false; } @@ -428,7 +428,7 @@ graph to record the multiplicity. @d Compute invariant multiplicity @{ std::vector invar_mult(invariant1.max(), 0); -for (tie(i1, i1_end) = vertices(g1); i1 != i1_end; ++i1) +for (tie(i1, i1_end) = vertices(g1); i1 != i1_end; ++i1) ++invar_mult[invar1[*i1]]; @} @@ -516,12 +516,12 @@ the order in which DFS discovers the vertices. std::vector color_vec(num_vertices(g1)); for (typename std::vector::iterator ui = g1_vertices.begin(); ui != g1_vertices.end(); ++ui) { - if (color_vec[get(index_map1, *ui)] + if (color_vec[get(index_map1, *ui)] == color_traits::white()) { depth_first_visit - (g1, *ui, detail::record_dfs_order(perm, - index_map1), - make_iterator_property_map(&color_vec[0], index_map1, + (g1, *ui, detail::record_dfs_order(perm, + index_map1), + make_iterator_property_map(&color_vec[0], index_map1, color_vec[0])); } } @@ -540,13 +540,13 @@ namespace detail { typedef typename graph_traits::vertices_size_type size_type; typedef typename graph_traits::vertex_descriptor vertex; - record_dfs_order(std::vector& dfs_order, IndexMap1 index) + record_dfs_order(std::vector& dfs_order, IndexMap1 index) : dfs_order(dfs_order), index(index) { } void discover_vertex(vertex v, const Graph1& g) const { dfs_order.push_back(get(index, v)); } - std::vector& dfs_order; + std::vector& dfs_order; IndexMap1 index; }; } // namespace detail @@ -570,7 +570,7 @@ typedef typename graph_traits::edge_descriptor edge1_t; std::vector edge_set; std::copy(edges(g1).first, edges(g1).second, std::back_inserter(edge_set)); -std::sort(edge_set.begin(), edge_set.end(), +std::sort(edge_set.begin(), edge_set.end(), detail::edge_ordering (make_iterator_property_map(perm.begin(), index_map1, perm[0]), g1)); @} @@ -587,7 +587,7 @@ namespace detail { template std::size_t edge_order(const typename graph_traits::edge_descriptor e, VertexIndexMap index_map, const Graph& g) { - return std::max(get(index_map, source(e, g)), get(index_map, target(e, g))); + return std::max(get(index_map, source(e, g)), get(index_map, target(e, g))); } template @@ -627,7 +627,7 @@ std::vector not_in_S_vec(num_vertices(g2), true); iterator_property_map not_in_S(¬_in_S_vec[0], index_map2); -return detail::isomorph(g1_vertices.begin(), g1_vertices.end(), +return detail::isomorph(g1_vertices.begin(), g1_vertices.end(), edge_set.begin(), edge_set.end(), g1, g2, make_iterator_property_map(perm.begin(), index_map1, perm[0]), index_map2, f, invar1, invar2, not_in_S); @@ -646,7 +646,7 @@ The mapping is recorded in the parameter \code{f}. @d Signature for the recursive isomorph function @{ template bool isomorph(VertexIter k_iter, VertexIter last, EdgeIter edge_iter, EdgeIter edge_iter_end, @@ -686,7 +686,7 @@ vertex1_t k = *k_iter; @d Return true if matching is complete @{ -if (k_iter == last) +if (k_iter == last) return true; @} @@ -720,7 +720,7 @@ bool some_edges = false; for (; edge_iter != edge_iter_end; ++edge_iter) { if (get(index_map1, k) != edge_order(*edge_iter, index_map1, g1)) - break; + break; if (k == source(*edge_iter, g1)) { // (k,j) @ if (some_edges == false) { @@ -807,8 +807,8 @@ digraph G { ratio="fill" subgraph cluster0 { label="G_1" - k -> j_1 - k -> j_2 + k -> j_1 + k -> j_2 k -> j_3 } @@ -952,8 +952,8 @@ mapping into the mapping from the previous calling function. for (std::size_t j = 0; j < potential_matches.size(); ++j) { my_f[k] = potential_matches[j]; @ - if (isomorph(boost::next(k_iter), last, edge_iter, edge_iter_end, g1, g2, - index_map1, index_map2, + if (isomorph(boost::next(k_iter), last, edge_iter, edge_iter_end, g1, g2, + index_map1, index_map2, my_f, invar1, invar2, my_not_in_S)) { for (tie(i1, i1_end) = vertices(g1); i1 != i1_end; ++i1) put(f, *i1, my_f[*i1]); @@ -994,7 +994,7 @@ code parts into namespace \code{boost}. // "as is" without express or implied warranty, and with no claim as // to its suitability for any purpose. -// See http://www.boost.org/libs/graph/doc/isomorphism-impl.pdf +// See http://www.boost.org/libs/graph/doc/isomorphism-impl.pdf // for a description of the implementation of the isomorphism function // defined in this header file. @@ -1061,11 +1061,11 @@ namespace boost { } - template - bool isomorphism_impl(const Graph1& g1, const Graph2& g2, - IndexMapping f, + bool isomorphism_impl(const Graph1& g1, const Graph2& g2, + IndexMapping f, IndexMap1 index_map1, IndexMap2 index_map2, const bgl_named_params& params) { @@ -1073,22 +1073,22 @@ namespace boost { // Compute the in-degrees std::vector in_degree_vec1(num_vertices(g1), 0); - typedef iterator_property_map InDegreeMap1; InDegreeMap1 in_degree_map1(&in_degree_vec1[0], index_map1); detail::compute_in_degree(g1, in_degree_map1); - degree_vertex_invariant + degree_vertex_invariant default_invar1(in_degree_map1, g1); std::vector in_degree_vec2(num_vertices(g2), 0); - typedef iterator_property_map InDegreeMap2; InDegreeMap2 in_degree_map2(&in_degree_vec2[0], index_map2); detail::compute_in_degree(g2, in_degree_map2); degree_vertex_invariant default_invar2(in_degree_map2, g2); - return isomorphism(g1, g2, f, + return isomorphism(g1, g2, f, choose_param(get_param(params, vertex_invariant_t()), default_invar1), choose_param(get_param(params, vertex_invariant_t()), default_invar2), index_map1, index_map2); @@ -1109,9 +1109,9 @@ namespace boost { std::vector f(n); vertex2_t x; return detail::isomorphism_impl - (g1, g2, + (g1, g2, choose_param(get_param(params, vertex_isomorphism_t()), - make_iterator_property_map(f.begin(), + make_iterator_property_map(f.begin(), choose_const_pmap(get_param(params, vertex_index1), g1, vertex_index), x)), choose_const_pmap(get_param(params, vertex_index1), @@ -1132,7 +1132,7 @@ namespace boost { // Compute the in-degrees std::vector in_degree_vec1(num_vertices(g1), 0); typedef typename property_map::const_type IndexMap1; - typedef iterator_property_map InDegreeMap1; InDegreeMap1 in_degree_map1(&in_degree_vec1[0], get(vertex_index, g1)); detail::compute_in_degree(g1, in_degree_map1); @@ -1141,11 +1141,11 @@ namespace boost { std::vector in_degree_vec2(num_vertices(g2), 0); typedef typename property_map::const_type IndexMap2; - typedef iterator_property_map InDegreeMap2; InDegreeMap2 in_degree_map2(&in_degree_vec2[0], get(vertex_index, g2)); detail::compute_in_degree(g2, in_degree_map2); - degree_vertex_invariant + degree_vertex_invariant invariant2(in_degree_map, g2); return isomorphism @@ -1159,7 +1159,7 @@ namespace boost { // concepts modeled, but since we're verifying an O(n^(lg n)) algorithm, // O(n^4) won't hurt us. template - inline bool verify_isomorphism(const Graph1& g1, const Graph2& g2, + inline bool verify_isomorphism(const Graph1& g1, const Graph2& g2, IsoMap iso_map) { if (num_vertices(g1) != num_vertices(g2) || num_edges(g1) != num_edges(g2)) diff --git a/doc/isomorphism.html b/doc/isomorphism.html index c1a2dd2b5..e0a4ca860 100644 --- a/doc/isomorphism.html +++ b/doc/isomorphism.html @@ -1,17 +1,17 @@ Boost Graph Library: Isomorphism - -C++ Boost + +C++ Boost
    @@ -28,8 +28,8 @@

    const bgl_named_params<P,T,R>& params = all defaults) // non-named parameter version -template <typename Graph1, typename Graph2, typename IsoMap, - typename VertexInvariant1, typename VertexInvariant2, +template <typename Graph1, typename Graph2, typename IsoMap, + typename VertexInvariant1, typename VertexInvariant2, typename V1Map, typename V2Map> bool isomorphism(const Graph1& g1, const Graph2& g2, IsoMap f, VertexInvariant1 invariant2, VertexInvariant2 invariant2, @@ -124,13 +124,13 @@

    Named Parameters

    IN: vertex_max_invariant(std::size_t max_invariant)
    -An upper bound on the possible values returned from either +An upper bound on the possible values returned from either vertex_invariant1 or vertex_invariant2.
    Default: vertex_invariant2.max(). The default -vertex_invariant2 parameter, an instance of +vertex_invariant2 parameter, an instance of degree_vertex_invariant, defines this function to -return num_vertices(g2) * (num_vertices(g2)+1).
    +return num_vertices(g2) * (num_vertices(g2)+1).
    Python: Unsupported parameter.
    @@ -190,4 +190,4 @@

    Example

    - + diff --git a/doc/johnson_all_pairs_shortest.html b/doc/johnson_all_pairs_shortest.html index 7303915cf..b78f0f62a 100644 --- a/doc/johnson_all_pairs_shortest.html +++ b/doc/johnson_all_pairs_shortest.html @@ -1,17 +1,17 @@ Johnson All Pairs Shortest Paths - -C++ Boost + +C++ Boost
    @@ -22,12 +22,12 @@

     // named parameter version
       template <class VertexAndEdgeListGraph, class DistanceMatrix,
    -            class VertexID, class Weight, class BinaryPredicate, 
    +            class VertexID, class Weight, class BinaryPredicate,
                 class BinaryFunction, class Infinity, class DistanceZero>
       bool
    -  johnson_all_pairs_shortest_paths(VertexAndEdgeListGraph& g1, 
    +  johnson_all_pairs_shortest_paths(VertexAndEdgeListGraph& g1,
                    DistanceMatrix& D,
    -               VertexID id1, Weight w1, const BinaryPredicate& compare, 
    +               VertexID id1, Weight w1, const BinaryPredicate& compare,
                    const BinaryFunction& combine, const Infinity& inf,
                    DistanceZero zero);
     
    @@ -39,7 +39,7 @@ 

    template <typename Graph, typename DistanceMatrix, typename VertexIndex, typename WeightMap, typename DT> bool -johnson_all_pairs_shortest_paths(VertexAndEdgeListGraph& g1, +johnson_all_pairs_shortest_paths(VertexAndEdgeListGraph& g1, DistanceMatrix& D, VertexIndex i_map, WeightMap w_map, DT zero)

    @@ -86,7 +86,7 @@

    Parameters

    Named Parameters

    -IN: weight_map(WeightMap w_map) +IN: weight_map(WeightMap w_map)
    The weight or "length" of each edge in the graph. The type WeightMap must be a model of @@ -96,12 +96,12 @@

    Named Parameters

    Default: get(edge_weight, g)
    -UTIL: weight_map2(WeightMap2 w2_map) +UTIL: weight_map2(WeightMap2 w2_map)
    This parameter is no longer needed, and will be ignored.
    -IN: vertex_index_map(VertexIndexMap i_map) +IN: vertex_index_map(VertexIndexMap i_map)
    This maps each vertex to an integer in the range [0, num_vertices(g)). This is necessary for efficient updates of the @@ -119,12 +119,12 @@

    Named Parameters

    -UTIL: distance_map(DistanceMap d_map) +UTIL: distance_map(DistanceMap d_map)
    This parameter is no longer needed, and will be ignored.
    -IN: distance_compare(CompareFunction cmp) +IN: distance_compare(CompareFunction cmp)
    This function is use to compare distances to determine which vertex is closer to the source vertex. @@ -136,7 +136,7 @@

    Named Parameters

    DT=typename property_traits<WeightMap>::value_type
    -IN: distance_combine(CombineFunction cmb) +IN: distance_combine(CombineFunction cmb)
    This function is used to combine distances to compute the distance of a path. The CombineFunction type must be a model of Named Parameters DT=typename property_traits<WeightMap>::value_type
    -IN: distance_inf(DT inf) +IN: distance_inf(DT inf)
    This value is used to initialize the distance for each - vertex before the start of the algorithm. + vertex before the start of the algorithm. The type DT must be the value type of the WeightMap.
    Default: std::numeric_limits::max()
    -IN: distance_zero(DT zero) +IN: distance_zero(DT zero)
    This value is used to initialize the distance for the source vertex before the start of the algorithm. The type DT @@ -163,7 +163,7 @@

    Named Parameters

    Default: 0
    -UTIL/OUT: color_map(ColorMap c_map) +UTIL/OUT: color_map(ColorMap c_map)
    This is used during the execution of the algorithm to mark the vertices. The vertices start out white and become gray when they are @@ -208,4 +208,4 @@

    Example

    - + diff --git a/doc/jwebfrob.pl b/doc/jwebfrob.pl index 81006b330..0ad4d2625 100644 --- a/doc/jwebfrob.pl +++ b/doc/jwebfrob.pl @@ -38,7 +38,7 @@ $thispage = $4; if ($thispage ne $lastpage) { - + $counter = 1; print $saved_empty; diff --git a/doc/kamada_kawai_spring_layout.html b/doc/kamada_kawai_spring_layout.html index 60e4ce06b..abc3ce662 100644 --- a/doc/kamada_kawai_spring_layout.html +++ b/doc/kamada_kawai_spring_layout.html @@ -2,7 +2,7 @@ Kevin Bacon Example - -C++ Boost + +C++ Boost
    @@ -91,7 +91,7 @@

    Input File and Graph Setup

       using namespace boost;
    -  typedef adjacency_list<vecS, vecS, undirectedS, 
    +  typedef adjacency_list<vecS, vecS, undirectedS,
         property<vertex_name_t, string>,
         property<edge_name_t, string > >
       > Graph;
    @@ -149,7 +149,7 @@ 

    Input File and Graph Setup

    -  NameVertexMap::iterator pos; 
    +  NameVertexMap::iterator pos;
       bool inserted;
       Vertex u, v;
     
    @@ -173,7 +173,7 @@ 

    Input File and Graph Setup

       std::string movie_name = *i++;
    -      
    +
       boost::tie(pos, inserted) = actors.insert(std::make_pair(*i, Vertex()));
       if (inserted) {
         v = add_vertex(g);
    @@ -185,7 +185,7 @@ 

    Input File and Graph Setup

    The final step is to add an edge connecting the two actors, and record -the name of the connecting movie. +the name of the connecting movie.

    @@ -270,7 +270,7 @@ 

    Apply the Breadth-First Search

       graph_traits<Graph>::vertex_iterator i, end;
       for (boost::tie(i, end) = vertices(g); i != end; ++i)
    -    std::cout << actor_name[*i] << "'s bacon number is " 
    +    std::cout << actor_name[*i] << "'s bacon number is "
                   << bacon_number[*i] << std::endl;
     
    @@ -290,7 +290,7 @@

    Apply the Breadth-First Search

    Denise Richards's bacon number is 1 Kevin Bacon's bacon number is 0 Patrick Stewart's bacon number is 2 -Steve Martin's bacon number is 1 +Steve Martin's bacon number is 1 ...
    @@ -306,7 +306,7 @@

    Apply the Breadth-First Search

    - + - - - + + + Boost Graph Library: King Ordering - -C++ Boost + +C++ Boost
    @@ -46,7 +46,7 @@

    OutputIterator king_ordering(const IncidenceGraph& g, typename graph_traits<Graph>::vertex_descriptor s, - OutputIterator inverse_permutation, + OutputIterator inverse_permutation, ColorMap color, DegreeMap degree, VertexIndexMap index_map); (2) @@ -59,12 +59,12 @@

    king_ordering(const IncidenceGraph& g, OutputIterator inverse_permutation, VertexIndexMap index_map); - template <class VertexListGraph, class OutputIterator, + template <class VertexListGraph, class OutputIterator, class ColorMap, class DegreeMap, class VertexIndexMap> OutputIterator - king_ordering(const VertexListGraph& G, OutputIterator inverse_permutation, + king_ordering(const VertexListGraph& G, OutputIterator inverse_permutation, ColorMap color, DegreeMap degree, VertexIndexMap index_map); - + (3) template <class IncidenceGraph, class OutputIterator, class ColorMap, class DegreeMap, class VertexIndexMap> @@ -72,7 +72,7 @@

    king_ordering(const IncidenceGraph& g, std::deque< typename graph_traits<Graph>::vertex_descriptor > vertex_queue, - OutputIterator permutation, + OutputIterator permutation, ColorMap color, DegreeMap degree, VertexIndexMap index_map);

    @@ -85,13 +85,13 @@

    works by a local minimization of the i-th bandwidths. The vertices are basically assigned a breadth-first search order, except that at each step, the adjacent vertices are placed in the queue in order of -increasing pseudo-degree, where pseudo-degree is defined as the number of +increasing pseudo-degree, where pseudo-degree is defined as the number of outgoing edges with white endpoints (vertices yet to be examined).

    Version 1 of the algorithm lets the user choose the ``starting vertex'', version 2 finds a good starting vertex using the -pseudo-peripheral pair heuristic (among each component), while version 3 +pseudo-peripheral pair heuristic (among each component), while version 3 contains the starting nodes for each vertex in the deque. The choice of the ``starting vertex'' can have a significant effect on the quality of the ordering.

    @@ -124,7 +124,7 @@

    Parameters

    -UTIL: predecessor_map(PredecessorMap p_map) +UTIL: predecessor_map(PredecessorMap p_map)
    This is used by the disjoint sets data structure, and is not used for storing predecessors in the spanning tree. The predecessors @@ -153,7 +153,7 @@

    Named Parameters

    Python: Unsupported parameter.
    -IN: vertex_index_map(VertexIndexMap i_map) +IN: vertex_index_map(VertexIndexMap i_map)
    This maps each vertex to an integer in the range [0, num_vertices(g)). This is only necessary if the default is used @@ -196,4 +196,4 @@

    Example

    - + diff --git a/doc/layout_tolerance.html b/doc/layout_tolerance.html index e0613ab85..5aa5512fd 100644 --- a/doc/layout_tolerance.html +++ b/doc/layout_tolerance.html @@ -1,21 +1,21 @@ -Struct template layout_tolerance
    boost.png (6897 bytes)HomeLibrariesPeopleFAQMore

    Struct template layout_tolerance

    boost::layout_tolerance — Determines when to terminate layout of a particular graph based on a given relative tolerance.

    Synopsis

    template<typename T = double> 
    +Struct template layout_tolerance
    boost.png (6897 bytes)HomeLibrariesPeopleFAQMore

    Struct template layout_tolerance

    boost::layout_tolerance — Determines when to terminate layout of a particular graph based on a given relative tolerance.

    Synopsis

    template<typename T = double>
     struct layout_tolerance {
       // construct/copy/destruct
       layout_tolerance(const T & = T(0.001));
     
       // public member functions
    -  template<typename Graph> 
    -    bool operator()(T, 
    -                    typename boost::graph_traits< Graph >::vertex_descriptor, 
    +  template<typename Graph>
    +    bool operator()(T,
    +                    typename boost::graph_traits< Graph >::vertex_descriptor,
                         const Graph &, bool) ;
    -};

    Where Defined

    boost/graph/kamada_kawai_spring_layout.hpp

    layout_tolerance construct/copy/destruct

    1. layout_tolerance(const T & tolerance = T(0.001));

    layout_tolerance public member functions

    1. template<typename Graph> 
      -  bool operator()(T delta_p, 
      -                  typename boost::graph_traits< Graph >::vertex_descriptor p, 
      +};

    Where Defined

    boost/graph/kamada_kawai_spring_layout.hpp

    layout_tolerance construct/copy/destruct

    1. layout_tolerance(const T & tolerance = T(0.001));

    layout_tolerance public member functions

    1. template<typename Graph>
      +  bool operator()(T delta_p,
      +                  typename boost::graph_traits< Graph >::vertex_descriptor p,
                         const Graph & g, bool global) ;

    diff --git a/doc/leda_conversion.html b/doc/leda_conversion.html index 585260825..c9e0e3254 100644 --- a/doc/leda_conversion.html +++ b/doc/leda_conversion.html @@ -1,17 +1,17 @@ Boost Graph Library: Converting Existing Graphs to BGL - -C++ Boost + +C++ Boost
    @@ -21,7 +21,7 @@

    How to Convert Existing Graphs to BGL

    Though the main goal of BGL is to aid the development of new applications and graph algorithms, there are quite a few existing codes -that could benefit from using BGL algorithms. One way to use the BGL +that could benefit from using BGL algorithms. One way to use the BGL algorithms with existing graph data structures is to copy data from the older graph format into a BGL graph which could then be used in the BGL algorithms. The problem with this approach is that it can be @@ -179,7 +179,7 @@

    How to Convert Existing Graphs to BGL

    struct graph_traits< GRAPH<vtype,etype> > { // ... typedef iterator_adaptor<edge, - out_edge_iterator_policies, + out_edge_iterator_policies, iterator<std::bidirectional_iterator_tag,edge> > out_edge_iterator; // ... @@ -205,9 +205,9 @@

    How to Convert Existing Graphs to BGL

    template <class vtype, class etype> inline std::pair< typename graph_traits< GRAPH<vtype,etype> >::out_edge_iterator, - typename graph_traits< GRAPH<vtype,etype> >::out_edge_iterator > + typename graph_traits< GRAPH<vtype,etype> >::out_edge_iterator > out_edges( - typename graph_traits< GRAPH<vtype,etype> >::vertex_descriptor u, + typename graph_traits< GRAPH<vtype,etype> >::vertex_descriptor u, const GRAPH<vtype,etype>& g) { typedef typename graph_traits< GRAPH<vtype,etype> > @@ -260,4 +260,4 @@

    How to Convert Existing Graphs to BGL

    - + diff --git a/doc/lengauer_tarjan_dominator.htm b/doc/lengauer_tarjan_dominator.htm index 23a009632..2f1e61b5f 100644 --- a/doc/lengauer_tarjan_dominator.htm +++ b/doc/lengauer_tarjan_dominator.htm @@ -1,17 +1,17 @@ Boost Graph Library: Lengauer-Tarjan Dominator Tree Algorithm - -C++ Boost + +C++ Boost
    @@ -131,7 +131,7 @@

    Parameters

    IN: IndexMap indexMap
    This maps each vertex to an integer in the range [0, num_vertices(g)). - The type + The type VertexIndexMap must be a model of Readable Property Map. The value type of the map must be an integer type. The vertex descriptor type of the graph needs to be @@ -179,5 +179,5 @@

    Example

    - + diff --git a/doc/lgrind.sty b/doc/lgrind.sty index b5129527e..3257be4d0 100644 --- a/doc/lgrind.sty +++ b/doc/lgrind.sty @@ -5,14 +5,14 @@ %% The original source files were: %% %% lgrind.dtx (with options: `package') -%% +%% %% LGrind is used to format source code of different programming %% languages for LaTeX. -%% +%% %% LGrind is a major adaptation of Jerry Leichter's tgrind for LaTeX, %% which was a notable improvement upon Van Jacobsen's tgrind for %% plain TeX, which was adapted from vgrind, a troff prettyprinter. -%% +%% %% Author: Michael Piefel, piefel@cs.tu-berlin.de %% Based on Van Jacobson's ``tgrindmac'', a macro package for TeX. %% Modified, 1987 by Jerry Leichter. Put '@' in all internal names. diff --git a/doc/make_biconnected_planar.html b/doc/make_biconnected_planar.html index 99195555d..f86c06bed 100644 --- a/doc/make_biconnected_planar.html +++ b/doc/make_biconnected_planar.html @@ -1,17 +1,17 @@ Boost Graph Library: make_biconnected_planar - -C++ Boost + +C++ Boost
    @@ -26,28 +26,28 @@

    make_biconnected_planar

    -A graph G is biconnected if, for every pair of vertices u,v in -G, there is a cycle containing both u and v. -Alternatively, a graph is biconnected if it is connected and cannot be made -disconnected by removing any single vertex. make_biconnected_planar -takes a connected +A graph G is biconnected if, for every pair of vertices u,v in +G, there is a cycle containing both u and v. +Alternatively, a graph is biconnected if it is connected and cannot be made +disconnected by removing any single vertex. make_biconnected_planar +takes a connected planar graph g as input and adds zero or more edges to make g biconnected while preserving planarity.

    -The default behavior of make_biconnected_planar is to modify the -graph g by calling add_edge(u,v,g) for every pair of -vertices (u,v) where an edge needs to be added to make g -biconnected. This behavior can be overriden by providing a vistor as the -AddEdgeVisitor parameter. The only requirement for an -AddEdgeVisitor is that it define a member function with the +The default behavior of make_biconnected_planar is to modify the +graph g by calling add_edge(u,v,g) for every pair of +vertices (u,v) where an edge needs to be added to make g +biconnected. This behavior can be overriden by providing a vistor as the +AddEdgeVisitor parameter. The only requirement for an +AddEdgeVisitor is that it define a member function with the following signature:

     template <typename Graph, typename Vertex>
     void visit_vertex_pair(Vertex u, Vertex v, Graph& g);
     
    This event point can also be used as a hook to update the underlying edge -index map automatically as edges are added. See the -documentation for the AddEdgeVisitor +index map automatically as edges are added. See the +documentation for the AddEdgeVisitor concept for more information.

    Where Defined

    @@ -78,7 +78,7 @@

    Parameters

    A Readable Property Map - that maps edges from g to distinct integers in the range + that maps edges from g to distinct integers in the range [0, num_edges(g) )
    Default: get(edge_index,g)
    @@ -88,14 +88,14 @@

    Parameters

    A model of AddEdgeVisitor .
    -Default: default_add_edge_visitor, a class defines +Default: default_add_edge_visitor, a class defines visit_vertex_pair to dispatch its calls to add_edge.

    Complexity

    -On a planar graph with n vertices, make_biconnected_planar +On a planar graph with n vertices, make_biconnected_planar runs in time O(n)

    Example

    @@ -114,4 +114,4 @@

    See Also

    Copyright © 2007 Aaron Windsor ( aaron.windsor@gmail.com) - + diff --git a/doc/make_connected.html b/doc/make_connected.html index 24d6f5240..0f18e10ec 100644 --- a/doc/make_connected.html +++ b/doc/make_connected.html @@ -1,17 +1,17 @@ Boost Graph Library: make_connected - -C++ Boost + +C++ Boost
    @@ -26,30 +26,30 @@

    make_connected

    -A undirected graph G is connected if, for every pair of vertices -u,v in G, there is a path from u to v. -make_connected adds the minimum number of edges needed to make the -input graph connected. The algorithm first identifies all of the +A undirected graph G is connected if, for every pair of vertices +u,v in G, there is a path from u to v. +make_connected adds the minimum number of edges needed to make the +input graph connected. The algorithm first identifies all of the connected components in the graph, then adds edges to connect those components together in a path. For example, if -a graph contains three connected components A, B, and C, -make_connected will add two edges. The two edges added might consist -of one connecting a vertex in A with a vertex in B and one +a graph contains three connected components A, B, and C, +make_connected will add two edges. The two edges added might consist +of one connecting a vertex in A with a vertex in B and one connecting a vertex in B with a vertex in C.

    -The default behavior of make_connected is to modify the graph -g by calling add_edge(u,v,g) for every pair of vertices -(u,v) where an edge needs to be added to connect g. This -behavior can be overriden by providing a vistor as the AddEdgeVisitor -parameter. The only requirement for an AddEdgeVisitor is that it +The default behavior of make_connected is to modify the graph +g by calling add_edge(u,v,g) for every pair of vertices +(u,v) where an edge needs to be added to connect g. This +behavior can be overriden by providing a vistor as the AddEdgeVisitor +parameter. The only requirement for an AddEdgeVisitor is that it define a member function with the following signature:

     template <typename Graph, typename Vertex>
     void visit_vertex_pair(Vertex u, Vertex v, Graph& g);
     
    This event point can also be used as a hook to update the underlying edge -index map automatically as edges are added. See the -documentation for the AddEdgeVisitor +index map automatically as edges are added. See the +documentation for the AddEdgeVisitor concept for more information. @@ -75,7 +75,7 @@

    Parameters

    A Readable Property Map - that maps vertices from g to distinct integers in the range + that maps vertices from g to distinct integers in the range [0, num_vertices(g) )
    Default: get(vertex_index,g)
    @@ -85,7 +85,7 @@

    Parameters

    A model of AddEdgeVisitor .
    -Default: default_add_edge_visitor, a class defines +Default: default_add_edge_visitor, a class defines visit_vertex_pair to dispatch its calls to add_edge.
    @@ -94,7 +94,7 @@

    Parameters

    Complexity

    -On a graph with n vertices and m edges, make_connected +On a graph with n vertices and m edges, make_connected runs in time O(n + m)

    Example

    @@ -113,4 +113,4 @@

    See Also

    Copyright © 2007 Aaron Windsor ( aaron.windsor@gmail.com) - + diff --git a/doc/make_maximal_planar.html b/doc/make_maximal_planar.html index 523ce7216..e635e583c 100644 --- a/doc/make_maximal_planar.html +++ b/doc/make_maximal_planar.html @@ -1,17 +1,17 @@ Boost Graph Library: make_maximal_planar - -C++ Boost + +C++ Boost
    @@ -25,30 +25,30 @@

    make_maximal_planar

    -A planar graph G is -maximal planar if no additional edges (except parallel edges and -self-loops) can be added to G without creating a non-planar graph. By +A planar graph G is +maximal planar if no additional edges (except parallel edges and +self-loops) can be added to G without creating a non-planar graph. By Euler's formula, a maximal planar graph on n vertices (n > 2) always has 3n - 6 edges - and -2n - 4 faces. The input graph to make_maximal_planar must be a -biconnected planar graph with at + and +2n - 4 faces. The input graph to make_maximal_planar must be a +biconnected planar graph with at least 3 vertices.

    -The default behavior of make_maximal_planar is to modify the graph -g by calling add_edge(u,v,g) for every pair of vertices +The default behavior of make_maximal_planar is to modify the graph +g by calling add_edge(u,v,g) for every pair of vertices (u,v) where an edge needs to be added to make g maximal planar. -This behavior can be overriden by providing a vistor as the -AddEdgeVisitor parameter. The only requirement for an -AddEdgeVisitor is that it define a member function with the following +This behavior can be overriden by providing a vistor as the +AddEdgeVisitor parameter. The only requirement for an +AddEdgeVisitor is that it define a member function with the following signature:

     template <typename Graph, typename Vertex>
     void visit_vertex_pair(Vertex u, Vertex v, Graph& g);
     
    This event point can also be used as a hook to update the underlying edge -index map automatically as edges are added. See the -documentation for the AddEdgeVisitor +index map automatically as edges are added. See the +documentation for the AddEdgeVisitor concept for more information.

    Where Defined

    @@ -73,7 +73,7 @@

    Parameters

    A Readable Property Map - that models the PlanarEmbedding + that models the PlanarEmbedding concept.
    @@ -81,7 +81,7 @@

    Parameters

    A Readable Property Map - that maps vertices from g to distinct integers in the range + that maps vertices from g to distinct integers in the range [0, num_vertices(g) )
    Default: get(vertex_index,g)
    @@ -90,7 +90,7 @@

    Parameters

    A Readable Property Map - that maps edges from g to distinct integers in the range + that maps edges from g to distinct integers in the range [0, num_edges(g) )
    Default: get(edge_index,g)
    @@ -99,14 +99,14 @@

    Parameters

    A model of AddEdgeVisitor.
    -Default: default_add_edge_visitor, a class defines +Default: default_add_edge_visitor, a class defines visit_vertex_pair to dispatch its calls to add_edge.

    Complexity

    -On a graph with n vertices and m edges, +On a graph with n vertices and m edges, make_maximal_planar runs in time O(n + m)

    Example

    @@ -125,4 +125,4 @@

    See Also

    Copyright © 2007 Aaron Windsor ( aaron.windsor@gmail.com) - + diff --git a/doc/math.sty b/doc/math.sty index f09b29e7f..b5c8c3eb5 100644 --- a/doc/math.sty +++ b/doc/math.sty @@ -49,7 +49,7 @@ \newcommand{\onlyif}{\Rightarrow} \newcommand{\thus}{\Longrightarrow} \newcommand{\contradicts}{\rightarrow\leftarrow} -\newcommand{\Union}{\bigcup} +\newcommand{\Union}{\bigcup} \newcommand{\union}{\cup} \newcommand{\Intersect}{\bigcap} \newcommand{\intersect}{\cap} diff --git a/doc/maximum_adjacency_search.html b/doc/maximum_adjacency_search.html index 4d3d410be..74aedc625 100644 --- a/doc/maximum_adjacency_search.html +++ b/doc/maximum_adjacency_search.html @@ -61,7 +61,7 @@

     MAS(G)
    -  for each vertex u in V 
    +  for each vertex u in V
         reach_count[u] := 0
       end for
       // for the starting vertex s
    @@ -240,9 +240,9 @@ 

    References

    • David Matula (1993). A linear time 2 + epsilon approximation algorightm for edge connectivity
    • -
    • Cai, Weiqing and Matula, David W. -Partitioning by maximum adjacency search of graphs. -Partitioning Data Sets: Dimacs Workshop, April 19-21, 1993. +
    • Cai, Weiqing and Matula, David W. +Partitioning by maximum adjacency search of graphs. +Partitioning Data Sets: Dimacs Workshop, April 19-21, 1993. Vol 19. Page 55. 1995. Amer Mathematical Society
    • }
    @@ -266,7 +266,7 @@

    Visitor Event Points

    Notes

    -

    [1] +

    [1] Since the visitor parameter is passed by value, if your visitor contains state then any changes to the state during the algorithm will be made to a copy of the visitor object, not the visitor object @@ -281,4 +281,4 @@

    Notes

    - + diff --git a/doc/maximum_matching.html b/doc/maximum_matching.html index fa54cb045..d0d3adf49 100644 --- a/doc/maximum_matching.html +++ b/doc/maximum_matching.html @@ -1,10 +1,10 @@ Boost Graph Library: Maximum Cardinality Matching @@ -30,9 +30,9 @@

    A matching is a subset of the edges of a graph such that no two edges share a common vertex. Two different matchings in the same graph are illustrated below (edges in the -matching are colored blue.) The matching on the left is a maximal matching, -meaning that its size can't be increased by adding edges. The matching on the -right is a maximum cardinality matching, meaning that is has maximum size +matching are colored blue.) The matching on the left is a maximal matching, +meaning that its size can't be increased by adding edges. The matching on the +right is a maximum cardinality matching, meaning that is has maximum size over all matchings in the graph.

    @@ -46,28 +46,28 @@

    -Both edmonds_maximum_cardinality_matching and +Both edmonds_maximum_cardinality_matching and checked_edmonds_maximum_cardinality_matching find the maximum cardinality matching in any undirected graph. The matching is returned in a -MateMap, which is a -ReadWritePropertyMap +MateMap, which is a +ReadWritePropertyMap that maps vertices to vertices. In the mapping returned, each vertex is either mapped to the vertex it's matched to, or to graph_traits<Graph>::null_vertex() if it doesn't participate in the matching. If no VertexIndexMap is provided, both functions assume that the VertexIndexMap is provided as an internal graph property accessible -by calling get(vertex_index,g). The only difference between -edmonds_maximum_cardinality_matching and -checked_edmonds_maximum_cardinality_matching is that as a final step, -the latter algorithm runs a simple verification on the matching computed and +by calling get(vertex_index,g). The only difference between +edmonds_maximum_cardinality_matching and +checked_edmonds_maximum_cardinality_matching is that as a final step, +the latter algorithm runs a simple verification on the matching computed and returns true if and only if the matching is indeed a maximum cardinality matching.

    Given a matching M, any vertex that isn't covered by an edge in M is called free. Any -simple path containing exactly 2n + 1 edges that starts and ends at free vertices and contains -n edges from M is called an alternating path. Given an alternating path p, all matching and +simple path containing exactly 2n + 1 edges that starts and ends at free vertices and contains +n edges from M is called an alternating path. Given an alternating path p, all matching and non-matching edges on p can be swapped, resulting in a new matching that's larger than the -original matching by exactly one edge. This method of incrementally increasing the size of matching, along +original matching by exactly one edge. This method of incrementally increasing the size of matching, along with the following fact, forms the basis of Edmonds' matching algorithm:

    @@ -82,16 +82,16 @@

  • Verify that the matching found is a maximum cardinality matching. -If you use checked_edmonds_maximum_cardinality_matching or +If you use checked_edmonds_maximum_cardinality_matching or edmonds_maximum_cardinality_matching, all three of these steps are chosen for you, but it's easy to plug in different algorithms for these three steps -using a generic matching function discussed below - in fact, both checked_edmonds_maximum_cardinality_matching -and edmonds_maximum_cardinality_matching are just inlined specializations of this function. +using a generic matching function discussed below - in fact, both checked_edmonds_maximum_cardinality_matching +and edmonds_maximum_cardinality_matching are just inlined specializations of this function.

    -When quoting time bounds for algorithms, we assume that VertexIndexMap is a property map -that allows for constant-time mapping between vertices and indices (which is easily achieved if, -for instance, the vertices are stored in contiguous memory.) We use n and m to represent the size +When quoting time bounds for algorithms, we assume that VertexIndexMap is a property map +that allows for constant-time mapping between vertices and indices (which is easily achieved if, +for instance, the vertices are stored in contiguous memory.) We use n and m to represent the size of the vertex and edge sets, respectively, of the input graph.

    Algorithms for Creating an Initial Matching

    @@ -103,21 +103,21 @@

    Algorithms for Creating an Initial Matching

    guaranteed to contain at least half of the edges that a maximum matching has. Takes time O(m log n).
  • extra_greedy_matching: Sorts the edges in increasing order of the degree of the vertices contained in each edge, then constructs a greedy matching from those edges. Also a maximal matching, and can -sometimes be much closer to the maximum cardinality matching than a simple greedy_matching. -Takes time O(m log n), but the constants involved make this a slower algorithm than +sometimes be much closer to the maximum cardinality matching than a simple greedy_matching. +Takes time O(m log n), but the constants involved make this a slower algorithm than greedy_matching.

    Algorithms for Finding an Augmenting Path

      -
    • edmonds_augmenting_path_finder: Finds an augmenting path in time O(m alpha(m,n)), -where alpha(m,n) is an inverse of the Ackerman function. alpha(m,n) is one of the slowest -growing functions that occurs naturally in computer science; essentially, alpha(m,n) ≤ 4 for any -graph that we'd ever hope to run this algorithm on. Since we arrive at a maximum cardinality matching after +
    • edmonds_augmenting_path_finder: Finds an augmenting path in time O(m alpha(m,n)), +where alpha(m,n) is an inverse of the Ackerman function. alpha(m,n) is one of the slowest +growing functions that occurs naturally in computer science; essentially, alpha(m,n) ≤ 4 for any +graph that we'd ever hope to run this algorithm on. Since we arrive at a maximum cardinality matching after augmenting O(n) matchings, the entire algorithm takes time O(mn alpha(m,n)). Edmonds' original -algorithm appeared in [64], but our implementation of -Edmonds' algorithm closely follows Tarjan's +algorithm appeared in [64], but our implementation of +Edmonds' algorithm closely follows Tarjan's description of the algorithm from [27].
    • no_augmenting_path_finder: Can be used if no augmentation of the initial matching is desired.
    @@ -125,34 +125,34 @@

    Algorithms for Finding an Augmenting Path

    Verification Algorithms

      -
    • maximum_cardinality_matching_verifier: Returns true if and only if the matching found is a -maximum cardinality matching. Takes time O(m alpha(m,n)), which is on the order of a single iteration +
    • maximum_cardinality_matching_verifier: Returns true if and only if the matching found is a +maximum cardinality matching. Takes time O(m alpha(m,n)), which is on the order of a single iteration of Edmonds' algorithm.
    • no_matching_verifier: Always returns true
    -Why is a verification algorithm needed? Edmonds' algorithm is fairly complex, and it's nearly -impossible for a human without a few days of spare time to figure out if the matching produced by -edmonds_matching on a graph with, say, 100 vertices and 500 edges is indeed a maximum cardinality -matching. A verification algorithm can do this mechanically, and it's much easier to verify by inspection -that the verification algorithm has been implemented correctly than it is to verify by inspection that -Edmonds' algorithm has been implemented correctly. -The Boost Graph library makes it incredibly simple to perform the subroutines needed by the verifier -(such as finding all the connected components of odd cardinality in a graph, or creating the induced graph +Why is a verification algorithm needed? Edmonds' algorithm is fairly complex, and it's nearly +impossible for a human without a few days of spare time to figure out if the matching produced by +edmonds_matching on a graph with, say, 100 vertices and 500 edges is indeed a maximum cardinality +matching. A verification algorithm can do this mechanically, and it's much easier to verify by inspection +that the verification algorithm has been implemented correctly than it is to verify by inspection that +Edmonds' algorithm has been implemented correctly. +The Boost Graph library makes it incredibly simple to perform the subroutines needed by the verifier +(such as finding all the connected components of odd cardinality in a graph, or creating the induced graph on all vertices with a certain label) in just a few lines of code.

    -Understanding how the verifier works requires a few graph-theoretic facts. +Understanding how the verifier works requires a few graph-theoretic facts. Let m(G) be the size of a maximum cardinality matching in the graph G. -Denote by o(G) the number of connected components in G of odd cardinality, and for a set of -vertices X, denote by G - X the induced graph on the vertex set V(G) - X. Then the +Denote by o(G) the number of connected components in G of odd cardinality, and for a set of +vertices X, denote by G - X the induced graph on the vertex set V(G) - X. Then the Tutte-Berge Formula says that

    2 * m(G) = min ( |V(G)| + |X| - o(G-X) )
    -Where the minimum is taken over all subsets X of the vertex set V(G). A side effect of the -Edmonds Blossom-Shrinking algorithm is that it computes what is known as the Edmonds-Gallai decomposition -of a graph: it decomposes the graph into three disjoint sets of vertices, one of which achieves the minimum +Where the minimum is taken over all subsets X of the vertex set V(G). A side effect of the +Edmonds Blossom-Shrinking algorithm is that it computes what is known as the Edmonds-Gallai decomposition +of a graph: it decomposes the graph into three disjoint sets of vertices, one of which achieves the minimum in the Tutte-Berge Formula. An outline of our verification procedure is: @@ -163,7 +163,7 @@

    Verification Algorithms

  • Run edmonds_augmenting_path_finder once on g and mate. If it finds an augmenting path, the matching isn't a maximum cardinality matching. Otherwise, we retrieve a copy of the vertex_state map used by the edmonds_augmenting_path_finder. The Edmonds-Gallai decomposition tells us that the set -of vertices labeled V_ODD by the vertex_state map can be used as the set X to achieve the +of vertices labeled V_ODD by the vertex_state map can be used as the set X to achieve the minimum in the Tutte-Berge Formula.
  • Count the number of vertices labeled V_ODD, store this in num_odd_vertices.
  • Create a filtered_graph @@ -175,7 +175,7 @@

    Verification Algorithms

    Assuming these steps are implemented correctly, the verifier will never return a false positive, and will only return a false negative if edmonds_augmenting_path_finder doesn't compute the vertex_state map correctly, in which case the edmonds_augmenting_path_finder -isn't working correctly. +isn't working correctly.

    Creating Your Own Matching Algorithms

    @@ -183,24 +183,24 @@

    Creating Your Own Matching Algorithms

    Creating a matching algorithm is as simple as plugging the algorithms described above into a generic matching function, which has the following signature:
    -template <typename Graph, 
    +template <typename Graph,
     	  typename MateMap,
     	  typename VertexIndexMap,
    -	  template <typename, typename, typename> class AugmentingPathFinder, 
    +	  template <typename, typename, typename> class AugmentingPathFinder,
     	  template <typename, typename> class InitialMatchingFinder,
     	  template <typename, typename, typename> class MatchingVerifier>
       bool matching(const Graph& g, MateMap mate, VertexIndexMap vm)
     
    The matching functions provided for you are just inlined specializations of this function: -edmonds_maximum_cardinality_matching uses edmonds_augmenting_path_finder -as the AugmentingPathFinder, extra_greedy_matching as the InitialMatchingFinder, -and no_matching_verifier as the MatchingVerifier. +edmonds_maximum_cardinality_matching uses edmonds_augmenting_path_finder +as the AugmentingPathFinder, extra_greedy_matching as the InitialMatchingFinder, +and no_matching_verifier as the MatchingVerifier. checked_edmonds_maximum_cardinality_matching uses the same parameters except that maximum_cardinality_matching_verifier is used for the MatchingVerifier.

    These aren't necessarily the best choices for any situation - for example, it's been claimed in the literature -that for sparse graphs, Edmonds' algorithm converges to the maximum cardinality matching more quickly if it +that for sparse graphs, Edmonds' algorithm converges to the maximum cardinality matching more quickly if it isn't supplied with an intitial matching. Such an algorithm can be easily assembled by calling matching with

    • AugmentingPathFinder = edmonds_augmenting_path_finder @@ -209,16 +209,16 @@

      Creating Your Own Matching Algorithms

      and choosing the MatchingVerifier depending on how careful you're feeling.

      -Suppose instead that you want a relatively large matching quickly, but are not exactly interested in a maximum matching. -Both extra_greedy_matching and greedy_matching find maximal matchings, which means they're guaranteed to be at +Suppose instead that you want a relatively large matching quickly, but are not exactly interested in a maximum matching. +Both extra_greedy_matching and greedy_matching find maximal matchings, which means they're guaranteed to be at least half the size of a maximum cardinality matching, so you could call matching with

      • AugmentingPathFinder = no_augmenting_path_finder
      • InitialMatchingFinder = extra_greedy_matching
      • MatchingVerifier = maximum_cardinality_matching_verifier
      -The resulting algorithm will find an extra greedy matching in time O(m log n) without looking for -augmenting paths. As a bonus, the return value of this function is true if and only if the extra greedy +The resulting algorithm will find an extra greedy matching in time O(m log n) without looking for +augmenting paths. As a bonus, the return value of this function is true if and only if the extra greedy matching happens to be a maximum cardinality matching.

      Where Defined

      @@ -231,7 +231,7 @@

      Creating Your Own Matching Algorithms

      IN: const Graph& g
      -An undirected graph. The graph type must be a model of +An undirected graph. The graph type must be a model of Vertex and Edge List Graph and Incidence Graph.
      @@ -251,9 +251,9 @@

      Creating Your Own Matching Algorithms

      Complexity

      -Let m and n be the number of edges and vertices in the input graph, respectively. Assuming the -VertexIndexMap supplied allows constant-time lookups, the time complexity for both -edmonds_matching and checked_edmonds_matching is O(mn alpha(m,n)). +Let m and n be the number of edges and vertices in the input graph, respectively. Assuming the +VertexIndexMap supplied allows constant-time lookups, the time complexity for both +edmonds_matching and checked_edmonds_matching is O(mn alpha(m,n)). alpha(m,n) is a slow growing function that is at most 4 for any feasible input.

      diff --git a/doc/maximum_weighted_matching.html b/doc/maximum_weighted_matching.html index e617faa91..ab40f1f45 100644 --- a/doc/maximum_weighted_matching.html +++ b/doc/maximum_weighted_matching.html @@ -1,10 +1,10 @@ Boost Graph Library: Maximum Weighted Matching @@ -28,10 +28,10 @@

  • Before you continue, it is recommended to read -about maximal cardinality matching first. +about maximal cardinality matching first. A maximum weighted matching of an edge-weighted graph is a matching -for which the sum of the weights of the edges is maximum. -Two different matchings (edges in the matching are colored blue) in the same graph are illustrated below. +for which the sum of the weights of the edges is maximum. +Two different matchings (edges in the matching are colored blue) in the same graph are illustrated below. The matching on the left is a maximum cardinality matching of size 8 and a maximal weighted matching of weight sum 30, meaning that is has maximum size over all matchings in the graph and its weight sum can't be increased by adding edges. @@ -49,26 +49,26 @@

    -Both maximum_weighted_matching and +Both maximum_weighted_matching and brute_force_maximum_weighted_matching find a maximum weighted matching in any undirected graph. The matching is returned in a -MateMap, which is a -ReadWritePropertyMap +MateMap, which is a +ReadWritePropertyMap that maps vertices to vertices. In the mapping returned, each vertex is either mapped to the vertex it's matched to, or to graph_traits<Graph>::null_vertex() if it doesn't participate in the matching. If no VertexIndexMap is provided, both functions assume that the VertexIndexMap is provided as an internal graph property accessible -by calling get(vertex_index, g). +by calling get(vertex_index, g).

    The maximum weighted matching problem was solved by Edmonds in [74]. The implementation of maximum_weighted_matching followed Chapter 6, Section 10 of [20] and -was written in a consistent style with edmonds_maximum_cardinality_matching because of their algorithmic similarity. +was written in a consistent style with edmonds_maximum_cardinality_matching because of their algorithmic similarity. In addition, a brute-force verifier brute_force_maximum_weighted_matching simply searches all possible matchings in any graph and selects one with the maximum weight sum.

    Algorithm Description

    -Primal-dual method in linear programming is introduced to solve weighted matching problems. Edmonds proved that for any graph, +Primal-dual method in linear programming is introduced to solve weighted matching problems. Edmonds proved that for any graph, the maximum number of edges in a matching is equal to the minimum capacity of an odd-set cover; this further enable us to prove a max-min duality theorem for weighted matching. Let Hk-1 denote any graph obtained from G by contracting odd sets of three or more nodes and deleting single nodes, where the capacity of the family of odd sets (not necessarily a cover of G) is k-1. Let Xk denote any matching containing k edges. @@ -76,7 +76,7 @@

    maxXk min {wij|(i, j) ϵ Xk} = minHk-1 max {wij|(i, j) ϵ Hk-1}. -This matching duality theorem gives an indication of how the matching problem should be formulated as a linear programming problem. That is, +This matching duality theorem gives an indication of how the matching problem should be formulated as a linear programming problem. That is, the theorem suggests a set of linear inequalities which are satisfied by any matching, and it is anticipated that these inequalities describe a convex polyhedron with integer vertices corresponding to feasible matchings. @@ -95,7 +95,7 @@

    If an augmenting path is found, go to step 2. If a blossom is formed, go to step 3. Otherwise, go to step 4.
  • (Augmentation) Find the augmenting path, tracing the path through shrunken blossoms. Augment the matching, correct labels on nodes in the augmenting path, expand blossoms with zero dual variables and remove labels from all base nodes. Go to step 1.
  • -
  • (Blossoming) Determine the membership and base node of the new blossom and supply missing labels for all non-base nodes in the blossom. +
  • (Blossoming) Determine the membership and base node of the new blossom and supply missing labels for all non-base nodes in the blossom. Return to step 1.
  • (Revision of Dual Solution) Adjust the dual variables based on the primal-dual method. Go to step 1 or halt, accordingly.
  • @@ -104,8 +104,8 @@

    Unlike max_cardinality_matching, the initial matching and augmenting path finder are not parameterized, because the algorithm maintains blossoms, dual variables and node labels across all augmentations. -The algorithm's time complexity is reduced from O(V4) (naive implementation of [74]) -to O(V3), by a delicate labeling procedure [75] to avoid re-scanning labels after revision of the dual solution. +The algorithm's time complexity is reduced from O(V4) (naive implementation of [74]) +to O(V3), by a delicate labeling procedure [75] to avoid re-scanning labels after revision of the dual solution. Special variables pi, tau, gamma and two arrays critical_edge, tau_idx are introduced for this purpose. Please refer to [20] and code comments for more implementation details. @@ -118,7 +118,7 @@

    IN: const Graph& g
    -An undirected graph. The graph type must be a model of +An undirected graph. The graph type must be a model of Vertex and Edge List Graph and Incidence Graph. The edge property of the graph property_map<Graph, edge_weight_t> must exist and have numeric value type.
    @@ -139,8 +139,8 @@

    Complexity

    -Let m and n be the number of edges and vertices in the input graph, respectively. Assuming the -VertexIndexMap supplied allows constant-time lookup, the time complexity for +Let m and n be the number of edges and vertices in the input graph, respectively. Assuming the +VertexIndexMap supplied allows constant-time lookup, the time complexity for maximum_weighted_matching is O(n3). For brute_force_maximum_weighted_matching, the time complexity is exponential of m. Note that the best known time complexity for maximum weighted matching in general graph is O(nm+n2log(n)) by [76], but relies on an diff --git a/doc/mcgregor_common_subgraphs.html b/doc/mcgregor_common_subgraphs.html index e545fca22..a38228540 100644 --- a/doc/mcgregor_common_subgraphs.html +++ b/doc/mcgregor_common_subgraphs.html @@ -1,7 +1,7 @@ Boost Graph Library: Minimum Degree Ordering - -C++ Boost + +C++ Boost
    @@ -23,14 +23,14 @@

       template <class AdjacencyGraph, class OutDegreeMap,
    -           class InversePermutationMap, 
    +           class InversePermutationMap,
                class PermutationMap, class SuperNodeSizeMap, class VertexIndexMap>
       void minimum_degree_ordering
         (AdjacencyGraph& G,
          OutDegreeMap outdegree,
          InversePermutationMap inverse_perm,
    -     PermutationMap perm, 
    -     SuperNodeSizeMap supernode_size, int delta, VertexIndexMap id) 
    +     PermutationMap perm,
    +     SuperNodeSizeMap supernode_size, int delta, VertexIndexMap id)
     

    The minimum degree ordering algorithm [

       inverse_perm[new_index[u]] == old_index[u]
     
    -

    and the permutation from the old index to the new index. +

    and the permutation from the old index to the new index.

       perm[old_index[u]] == new_index[u]
     
    @@ -80,7 +80,7 @@

    Parameters

    descriptor type of the graph, and with a value type that is an integer type. -
  • InversePermutationMap inverse_perm  (OUT)
    +
  • InversePermutationMap inverse_perm  (OUT)
    The new vertex ordering, given as the mapping from the new indices to the old indices (an inverse permutation). This must be an
    - LvaluePropertyMap with a value type and key type a signed integer. + LvaluePropertyMap with a value type and key type a signed integer. -
  • PermutationMap perm  (OUT)
    +
  • PermutationMap perm  (OUT)
    The new vertex ordering, given as the mapping from the old indices to the new indices (a permutation). This must be an - LvaluePropertyMap with a value type and key type a signed integer. + LvaluePropertyMap with a value type and key type a signed integer. -
  • SuperNodeSizeMap supernode_size  (WORK/OUT)
    +
  • SuperNodeSizeMap supernode_size  (WORK/OUT)
    This is used internally to record the size of supernodes and is also useful information to have. This is a LvaluePropertyMap with an unsigned integer value type and key type of vertex descriptor. -
  • int delta  (IN)
    +
  • int delta  (IN)
    Multiple elimination control variable. If it is larger than or equal to zero then multiple elimination is enabled. The value of delta specifies the difference between the minimum degree and the degree of vertices that are to be eliminated. - -
  • VertexIndexMap id  (IN)
    + +
  • VertexIndexMap id  (IN)
    Used internally to map vertices to their indices. This must be a Readable Property Map with key type the same as the vertex descriptor of @@ -155,7 +155,7 @@

    Implementation Notes

    graph G by removing vertex v and all of its incident edges and by then adding edges to make all of the vertices adjacent to v into a clique (that is, add an edge between each pair of -adjacent vertices if an edge doesn't already exist). +adjacent vertices if an edge doesn't already exist). Suppose that graph G is the graph representing the nonzero structure of a matrix A. Then performing a step of Guassian @@ -175,4 +175,4 @@

    Implementation Notes

    - + diff --git a/doc/minimum_degree_ordering.w b/doc/minimum_degree_ordering.w index d231799f1..9de5b11de 100644 --- a/doc/minimum_degree_ordering.w +++ b/doc/minimum_degree_ordering.w @@ -53,7 +53,7 @@ complete subgraph. That is, it is a subgraph where each vertex is adjacent to every other vertex in the subgraph}. -quotient graph +quotient graph set of cliques in the graph @@ -81,7 +81,7 @@ external degree @d MMD Algorithm Overview @{ @ - + @} @@ -153,7 +153,7 @@ void eliminate(vertex_t node) tagged or if it is numbered add vertices adjacent to node to the clique put all numbered adjacent vertices into the temporary neighbors stack - + @ } @} @@ -201,7 +201,7 @@ while (!neighbors.empty()) { @d @{ -predicateRemoveEdge1 p(G, marker, numbering, element_neighbor, vertex_index_map); @@ -213,16 +213,16 @@ remove_out_edge_if(node, p, G); @d Interface of the MMD function @{ -template void minimum_degree_ordering - (Graph& G, - DegreeMap degree, - InversePermutationMap inverse_perm, - PermutationMap perm, - SuperNodeMap supernode_size, + (Graph& G, + DegreeMap degree, + InversePermutationMap inverse_perm, + PermutationMap perm, + SuperNodeMap supernode_size, int delta, VertexIndexMap vertex_index_map) @} @@ -253,8 +253,8 @@ public: typedef typename property_traits::key_type value_type; typedef typename property_traits::value_type size_type; - bucket_sorter(size_type length, bucket_type max_bucket, - const BucketMap& bucket = BucketMap(), + bucket_sorter(size_type length, bucket_type max_bucket, + const BucketMap& bucket = BucketMap(), const ValueIndexMap& index_map = ValueIndexMap()); void remove(const value_type& x); void push(const value_type& x); @@ -300,10 +300,10 @@ value object to (the minimum is assumed to be zero). @d Bucket Sorter Constructor @{ bucket_sorter::bucket_sorter (size_type N, bucket_type max_bucket, - const BucketMap& bucket_map = BucketMap(), + const BucketMap& bucket_map = BucketMap(), const ValueIndexMap& index_map = ValueIndexMap()) : head(max_bucket, invalid_value()), - next(N, invalid_value()), + next(N, invalid_value()), prev(N, invalid_value()), id_to_value(N), bucket_map(bucket_map), index_map(index_map) { } diff --git a/doc/null_visitor.html b/doc/null_visitor.html index df73c844a..287283d11 100644 --- a/doc/null_visitor.html +++ b/doc/null_visitor.html @@ -1,17 +1,17 @@ Boost Graph Library: null_visitor - -C++ Boost + +C++ Boost
    @@ -91,4 +91,4 @@

    Member Functions

    - + diff --git a/doc/opposite.html b/doc/opposite.html index cfe102001..e77bbe372 100644 --- a/doc/opposite.html +++ b/doc/opposite.html @@ -1,17 +1,17 @@ Boost Graph Library: opposite - -C++ Boost + +C++ Boost
    @@ -76,4 +76,4 @@

    Example

    - + diff --git a/doc/planar_canonical_ordering.html b/doc/planar_canonical_ordering.html index f79c39e3e..1eabba8f3 100644 --- a/doc/planar_canonical_ordering.html +++ b/doc/planar_canonical_ordering.html @@ -1,17 +1,17 @@ Boost Graph Library: Planar Canonical Ordering - -C++ Boost + +C++ Boost
    @@ -22,25 +22,25 @@

    Planar Canonical Ordering

    -A planar canonical ordering is an ordering v1, -v2, ..., vn of the vertices of a -maximal -planar graph having the property that, for -each k, 3 <= k < n, the graph induced by +A planar canonical ordering is an ordering v1, +v2, ..., vn of the vertices of a +maximal +planar graph having the property that, for +each k, 3 <= k < n, the graph induced by v1, v2, ..., vk

      -
    • is biconnected and contains the edge {v1, v2} +
    • is biconnected and contains the edge {v1, v2} on its outer face. -
    • has any vertices in the range v1, v2, ..., -vk that are adjacent to v(k+1) on its outer +
    • has any vertices in the range v1, v2, ..., +vk that are adjacent to v(k+1) on its outer face, and these vertices form a path along the outer face.
    Let Gk be the graph induced by the first k vertices in -the canonical ordering, along with all edges between any of the first k -vertices. After Gk has been drawn, the (k+1)st vertex -can be drawn easily without edge crossings, since it's adjacent only to a -consecutive sequence of vertices on the outer face of Gk. +the canonical ordering, along with all edges between any of the first k +vertices. After Gk has been drawn, the (k+1)st vertex +can be drawn easily without edge crossings, since it's adjacent only to a +consecutive sequence of vertices on the outer face of Gk.

    @@ -53,21 +53,21 @@

    Planar Canonical Ordering

    to have at least 2 vertices.

    -The planar canonical ordering is used as an input in some planar graph drawing -algorithms, particularly those that create a straight line embedding. -de Fraysseix, Pach, and Pollack -[72] -first proved the -existence of such an ordering and showed how to compute one in time +The planar canonical ordering is used as an input in some planar graph drawing +algorithms, particularly those that create a straight line embedding. +de Fraysseix, Pach, and Pollack +[72] +first proved the +existence of such an ordering and showed how to compute one in time O(n) on a maximal planar graph with n vertices.

    Complexity

    If the vertex index map provides constant-time access to indices, this -function takes time O(n + m) for a planar graph with n vertices -and m edges. Note that -in a simple planar graph with f faces, m edges, and n -vertices, both f and m are O(n). +function takes time O(n + m) for a planar graph with n vertices +and m edges. Note that +in a simple planar graph with f faces, m edges, and n +vertices, both f and m are O(n).

    Where Defined

    @@ -80,7 +80,7 @@

    Where Defined

    IN: Graph& g
    -An undirected graph. The graph type must be a model of +An undirected graph. The graph type must be a model of VertexAndEdgeListGraph. The graph must:
      @@ -89,7 +89,7 @@

      Where Defined

    -IN: PlanarEmbedding +IN: PlanarEmbedding
    A model of PlanarEmbedding. @@ -98,7 +98,7 @@

    Where Defined

    IN: OutputIterator
    -An OutputIterator with value_type equal to +An OutputIterator with value_type equal to graph_traits<Graph>::vertex_descriptor. The canonical ordering will be written to this iterator.
    @@ -107,7 +107,7 @@

    Where Defined

    A Readable Property Map - that maps vertices from g to distinct integers in the range + that maps vertices from g to distinct integers in the range [0, num_vertices(g) )
    Default: get(vertex_index,g)
    @@ -127,5 +127,5 @@

    Example


    Copyright © 2007 Aaron Windsor ( aaron.windsor@gmail.com) - + diff --git a/doc/planar_face_traversal.html b/doc/planar_face_traversal.html index 9a93799d6..24214c366 100644 --- a/doc/planar_face_traversal.html +++ b/doc/planar_face_traversal.html @@ -1,17 +1,17 @@ Boost Graph Library: Planar Face Traversal - -C++ Boost + +C++ Boost
    @@ -23,17 +23,17 @@

    Planar Face Traversal

    -A graph is planar if it can be drawn in two-dimensional space with no -two of its edges crossing. Any embedding of a planar graph separates the plane -into distinct regions that are bounded by sequences of edges in the graph. -These regions are called faces. +A graph is planar if it can be drawn in two-dimensional space with no +two of its edges crossing. Any embedding of a planar graph separates the plane +into distinct regions that are bounded by sequences of edges in the graph. +These regions are called faces.

    @@ -49,27 +49,27 @@
    A plane drawing of a graph (left), and the 8 faces defined by the planar A traversal of the faces of a planar graph involves iterating through all faces of the graph, and on each face, iterating through all vertices and edges of the -face. The iteration through all vertices and edges of each face follows a +face. The iteration through all vertices and edges of each face follows a path around the border of the face.

    -In a biconnected graph, like the one shown above, each face is bounded by a -cycle and each edge belongs to exactly two faces. For this reason, when +In a biconnected graph, like the one shown above, each face is bounded by a +cycle and each edge belongs to exactly two faces. For this reason, when planar_face_traversal is called on a biconnected graph, each edge will -be visited exactly twice: once on each of two distinct faces, and no vertex -will be visited more than once on a particular face. The output of -planar_face_traversal on non-biconnected graphs is less intuitive - -for example, if the graph -consists solely of a path of vertices (and therefore a single face), -planar_face_traversal will iterate around the path, visiting -each edge twice and visiting some vertices more than once. +be visited exactly twice: once on each of two distinct faces, and no vertex +will be visited more than once on a particular face. The output of +planar_face_traversal on non-biconnected graphs is less intuitive - +for example, if the graph +consists solely of a path of vertices (and therefore a single face), +planar_face_traversal will iterate around the path, visiting +each edge twice and visiting some vertices more than once. planar_face_traversal does not visit isolated vertices.

    -Like other graph traversal algorithms in the Boost Graph Library, the planar -face traversal is a generic traversal that can be customized by the +Like other graph traversal algorithms in the Boost Graph Library, the planar +face traversal is a generic traversal that can be customized by the redefinition of certain visitor event points. By defining an appropriate -visitor, this traversal can be -used to enumerate the faces of a planar graph, triangulate a planar graph, or -even construct a dual of a planar graph. +visitor, this traversal can be +used to enumerate the faces of a planar graph, triangulate a planar graph, or +even construct a dual of a planar graph.

    @@ -77,13 +77,13 @@
    A plane drawing of a graph (left), and the 8 faces defined by the planar

    -For example, on the above graph, an instance my_visitor of the +For example, on the above graph, an instance my_visitor of the following visitor:
         struct output_visitor: public planar_face_traversal_visitor
         {
             void begin_face() { std::cout << "New face: "; }
    -        template <typename Vertex> void next_vertex(Vertex v) { std::cout << v << " "; } 
    +        template <typename Vertex> void next_vertex(Vertex v) { std::cout << v << " "; }
             void finish_face() { std::cout << std::endl; }
         };
     
    @@ -100,47 +100,47 @@
    A plane drawing of a graph (left), and the 8 faces defined by the planar New face: 1 0 3 2 -

    Visitor Event Points

    - +

    Visitor Event Points

    +
      -
    • visitor.begin_traversal(): called once before any faces are +
    • visitor.begin_traversal(): called once before any faces are visited. -
    • visitor.begin_face(): called once, for each face, before any +
    • visitor.begin_face(): called once, for each face, before any vertex or edge on that face has been visited.
    • visitor.end_face(): called once, for each face, after all vertices and all edges on that face have been visited. -
    • visitor.next_vertex(Vertex v): called once on each vertex in the -current face (the start and end of which are designated by calls to -begin_face() and end_face(), respectively) in order +
    • visitor.next_vertex(Vertex v): called once on each vertex in the +current face (the start and end of which are designated by calls to +begin_face() and end_face(), respectively) in order according to the order established by the planar embedding.
    • visitor.next_edge(Edge e): called once on each edge in the current -face (the start and end of which are designated by calls to -begin_face() and end_face(), respectively) in order +face (the start and end of which are designated by calls to +begin_face() and end_face(), respectively) in order according to the order established by the planar embedding. -
    • visitor.end_traversal(): called once after all faces have been +
    • visitor.end_traversal(): called once after all faces have been visited.
    Although next_vertex is guaranteed to be called in sequence for each vertex as the traversal moves around a face and next_edge is guaranteed to be called in sequence for each edge as the traversal moves -around a face, there's no guarantee about the order in which -next_vertex and next_edge are called with respect to each -other in between calls to begin_face and end_face. These -calls may be interleaved, all vertex visits may precede all edge visits, or +around a face, there's no guarantee about the order in which +next_vertex and next_edge are called with respect to each +other in between calls to begin_face and end_face. These +calls may be interleaved, all vertex visits may precede all edge visits, or vise-versa.

    -planar_face_traversal iterates over a copy of the edges of the input +planar_face_traversal iterates over a copy of the edges of the input graph, so it is safe to add edges to the graph during visitor event points.

    Complexity

    -If all of the visitor event points run in constant time, the traversal takes +If all of the visitor event points run in constant time, the traversal takes time O(n + m) for a planar graph with n vertices and m -edges. Note that -in a simple planar graph with f faces, m edges, and n -vertices, both f and m are O(n). +edges. Note that +in a simple planar graph with f faces, m edges, and n +vertices, both f and m are O(n).

    Where Defined

    @@ -154,11 +154,11 @@

    Parameters

    IN: Graph& g
    -An undirected graph. The graph type must +An undirected graph. The graph type must be a model of VertexAndEdgeListGraph
    -IN: PlanarEmbedding +IN: PlanarEmbedding
    A model of PlanarEmbedding. @@ -174,7 +174,7 @@

    Parameters

    A Readable Property Map - that maps edges from g to distinct integers in the range + that maps edges from g to distinct integers in the range [0, num_edges(g) )
    Default: get(edge_index,g)
    @@ -199,4 +199,4 @@

    See Also

    Copyright © 2007 Aaron Windsor ( aaron.windsor@gmail.com) - + diff --git a/doc/planar_graphs.html b/doc/planar_graphs.html index 47e66fd6b..1d2f8f791 100644 --- a/doc/planar_graphs.html +++ b/doc/planar_graphs.html @@ -1,35 +1,35 @@ Boost Graph Library: Planar Graphs - -C++ Boost + +C++ Boost

    Planar Graphs

    -A graph is planar if it can be drawn in -two-dimensional space with no two of its edges crossing. Such a drawing of a -planar graph is called a plane drawing. -Every planar graph also admits a straight-line drawing, which is a -plane drawing where each edge is represented by a line segment. +A graph is planar if it can be drawn in +two-dimensional space with no two of its edges crossing. Such a drawing of a +planar graph is called a plane drawing. +Every planar graph also admits a straight-line drawing, which is a +plane drawing where each edge is represented by a line segment.

    -
    A plane drawing of a graph (left), and the 8 faces defined by the planar -embedding (right.) Each connected blue region in the image on the right is a +
    A plane drawing of a graph (left), and the 8 faces defined by the planar +embedding (right.) Each connected blue region in the image on the right is a face. The large blue region surrounding the graph is the outer face.
    @@ -41,17 +41,17 @@
    A planar graph (left), a plane drawing (center), and a straight line
    -
    A planar graph (left), a plane drawing (center), and a straight line +
    A planar graph (left), a plane drawing (center), and a straight line drawing (right), all of the same graph

    -Two examples of non-planar graphs are K5, the complete graph on -five vertices, and K3,3, the complete bipartite graph on six -vertices with three vertices in each bipartition. No matter how the vertices -of either graph are arranged in the plane, at least two edges are forced to +Two examples of non-planar graphs are K5, the complete graph on +five vertices, and K3,3, the complete bipartite graph on six +vertices with three vertices in each bipartition. No matter how the vertices +of either graph are arranged in the plane, at least two edges are forced to cross.

    - @@ -63,33 +63,33 @@
    A planar graph (left), a plane drawing (center), and a straight line
    The above graphs are both minimal examples of non-planarity within -their class of graphs; delete any edge or vertex from either one and the -resulting graph is planar. A theorem of Kuratowski singles these two graphs -out as fundamental obstructions to planarity within any graph: +their class of graphs; delete any edge or vertex from either one and the +resulting graph is planar. A theorem of Kuratowski singles these two graphs +out as fundamental obstructions to planarity within any graph:
    -A graph is planar if and only if it does not contain a subgraph that is an +A graph is planar if and only if it does not contain a subgraph that is an expansion[1] of either K5 or K3,3

    -A subgraph that is an expansion of K5 or K3,3 is called -a Kuratowski subgraph. Because of -the above theorem, given any graph, one can produce either a plane drawing of +A subgraph that is an expansion of K5 or K3,3 is called +a Kuratowski subgraph. Because of +the above theorem, given any graph, one can produce either a plane drawing of a graph, which will certify that the graph is planar, or a minimal set of edges -that forms a Kuratowski subgraph, which will certify that the graph is -non-planar - in both cases, the certificate of planarity or non-planarity is +that forms a Kuratowski subgraph, which will certify that the graph is +non-planar - in both cases, the certificate of planarity or non-planarity is easy to check.

    -Any plane drawing separates the plane into distinct regions bordered by graph -edges called faces. As a simple example, any embedding of a triangle -into the plane separates it into two faces: the region inside the triangle and -the (unbounded) region outside the triangle. The unbounded region outside the +Any plane drawing separates the plane into distinct regions bordered by graph +edges called faces. As a simple example, any embedding of a triangle +into the plane separates it into two faces: the region inside the triangle and +the (unbounded) region outside the triangle. The unbounded region outside the graph's embedding is called the outer face. Every embedding yields -one outer face and zero or more inner faces. A famous result called -Euler's formula states that for any -planar graph with n vertices, e edges, f faces, and +one outer face and zero or more inner faces. A famous result called +Euler's formula states that for any +planar graph with n vertices, e edges, f faces, and c connected components,

    @@ -99,36 +99,36 @@
    A planar graph (left), a plane drawing (center), and a straight line This formula implies that any planar graph with no self-loops or parallel edges has at most 3n - 6 edges and 2n- 4 faces. Because of these bounds, algorithms on planar graphs can run in time O(n) or space -O(n) on an n vertex graph even if they have to traverse all +O(n) on an n vertex graph even if they have to traverse all edges or faces of the graph.

    A convenient way to separate the actual planarity test from algorithms that -accept a planar graph as input is through an intermediate structure called a -planar embedding. Instead of specifying the absolute positions of the -vertices and edges in the plane as a plane drawing would, a planar embedding -specifies their positions relative to one another. A planar embedding consists -of a sequence, for each vertex in the graph, of all of the edges incident on +accept a planar graph as input is through an intermediate structure called a +planar embedding. Instead of specifying the absolute positions of the +vertices and edges in the plane as a plane drawing would, a planar embedding +specifies their positions relative to one another. A planar embedding consists +of a sequence, for each vertex in the graph, of all of the edges incident on that vertex in the order in which they are to be drawn around that vertex. The orderings defined by this sequence can either represent a clockwise or counter-clockwise iteration through the neighbors of each vertex, but the orientation must be -consistent across the entire embedding. +consistent across the entire embedding.

    -In the Boost Graph Library, a planar embedding is a model of the +In the Boost Graph Library, a planar embedding is a model of the PlanarEmbedding concept. A type that -models PlanarEmbedding can be passed into the planarity test and populated if -the input graph is planar. All other "back end" planar graph algorithms accept -this populated PlanarEmbedding as an input. Conceptually, a type that models -PlanarEmbedding is a property +models PlanarEmbedding can be passed into the planarity test and populated if +the input graph is planar. All other "back end" planar graph algorithms accept +this populated PlanarEmbedding as an input. Conceptually, a type that models +PlanarEmbedding is a property map that maps each vertex to a sequence of edges, -where the sequence of edges has a similar interface to a standard C++ +where the sequence of edges has a similar interface to a standard C++ container. The sequence of edges each vertex maps to represents the ordering -of edges adjacent to that vertex. This interface is flexible enough to allow -storage of the planar embedding independent from the graph in, say, a -std::vector of std::vectors, or to allow for graph -implementations that actually store lists of adjacent edges/vertices to +of edges adjacent to that vertex. This interface is flexible enough to allow +storage of the planar embedding independent from the graph in, say, a +std::vector of std::vectors, or to allow for graph +implementations that actually store lists of adjacent edges/vertices to internally re-arrange their storage to represent the planar embedding. -Currently, only the former approach is supported when using the native graph +Currently, only the former approach is supported when using the native graph types (adjacency_list, adjacency_matrix, etc.) of the Boost Graph Library. @@ -141,73 +141,73 @@

    Tools for working with planar graphs in the Boost Graph Library

    The function boyer_myrvold_planarity_test can be used to test whether or not a graph is planar, but it can also produce two important side-effects: in the case the graph is not planar, it can -isolate a Kuratowski subgraph, and in the case the graph is planar, it can +isolate a Kuratowski subgraph, and in the case the graph is planar, it can compute a planar embedding. The Boyer-Myrvold algorithm works on any undirected graph.

    -An undirected graph is connected if, for any two vertices u and -v, there's a path from u to v. An undirected graph is +An undirected graph is connected if, for any two vertices u and +v, there's a path from u to v. An undirected graph is biconnected if it is connected and it remains connected even if any -single vertex is removed. Finally, a planar graph is +single vertex is removed. Finally, a planar graph is maximal planar (also called triangulated) if no additional edge (with the exception of self-loops -and parallel edges) can be added to it without creating -a non-planar graph. Any maximal planar simple graph on n > 2 vertices -has exactly 3n - 6 edges and 2n - 4 faces, a consequence of +and parallel edges) can be added to it without creating +a non-planar graph. Any maximal planar simple graph on n > 2 vertices +has exactly 3n - 6 edges and 2n - 4 faces, a consequence of Euler's formula. If a planar graph isn't connected, isn't biconnected, or isn't -maximal planar, there is some set of edges that can be added to the graph to -make it satisfy any of those three properties while preserving planarity. Many -planar graph drawing algorithms make at least one of these three assumptions -about the input graph, so there are functions in the Boost Graph Library that +maximal planar, there is some set of edges that can be added to the graph to +make it satisfy any of those three properties while preserving planarity. Many +planar graph drawing algorithms make at least one of these three assumptions +about the input graph, so there are functions in the Boost Graph Library that can help:

      -
    • make_connected adds a minimal +
    • make_connected adds a minimal set of edges to an undirected graph to make it connected.
    • make_biconnected_planar -adds a set of edges to a connected, undirected planar graph to make it +adds a set of edges to a connected, undirected planar graph to make it biconnected while preserving planarity. -
    • make_maximal_planar adds a -set of edges to a biconnected, undirected planar graph to make it maximal +
    • make_maximal_planar adds a +set of edges to a biconnected, undirected planar graph to make it maximal planar.

    -Some algorithms involve a traversal of the faces of the graph, and the Boost -Graph Library has the generic traversal function +Some algorithms involve a traversal of the faces of the graph, and the Boost +Graph Library has the generic traversal function planar_face_traversal for this purpose. This traversal, like other traversals in the Boost Graph Library, can be customized by overriding event points in an appropriately defined visitor class.

    -An intermediate step in some drawing algorithms for planar graphs is the -creation of -a canonical ordering of the vertices. A canonical ordering is a -permutation of the vertices of a maximal planar graph. It orders the vertices -in a way that makes it straightforward to draw the ith vertex once the +An intermediate step in some drawing algorithms for planar graphs is the +creation of +a canonical ordering of the vertices. A canonical ordering is a +permutation of the vertices of a maximal planar graph. It orders the vertices +in a way that makes it straightforward to draw the ith vertex once the first (i-1) vertices have been drawn - the only edges connecting the -ith vertex to vertices already drawn will be adjacent to a consecutive -sequence of vertices along the outer face of the partially embedded graph. The -function +ith vertex to vertices already drawn will be adjacent to a consecutive +sequence of vertices along the outer face of the partially embedded graph. The +function planar_canonical_ordering -will create such an ordering, given a maximal planar graph and a planar +will create such an ordering, given a maximal planar graph and a planar embedding of that graph.

    -A straight line drawing can be created using the function +A straight line drawing can be created using the function chrobak_payne_straight_line_drawing, - which takes a maximal planar graph, a planar embedding of that + which takes a maximal planar graph, a planar embedding of that graph, and a canonical ordering as input. The resulting drawing maps all of the -vertices from a graph with n vertices to integer coordinates on a +vertices from a graph with n vertices to integer coordinates on a (2n-4) x (n-2) grid such that when the edges of the graph are drawn -as line segments connecting vertices, no two edges cross. Self-loops and +as line segments connecting vertices, no two edges cross. Self-loops and parallel edges are ignored by this algorithm.

    -Finally, there are two functions that can be used to verify the results of the -boyer_myrvold_planarity_test and +Finally, there are two functions that can be used to verify the results of the +boyer_myrvold_planarity_test and chrobak_payne_straight_line_drawing functions:

      -
    • is_kuratowski_subgraph -takes the output of boyer_myrvold_planarity_test on a nonplanar graph -and verifies that it can be contracted into a graph isomorphic to a Kuratowski +
    • is_kuratowski_subgraph +takes the output of boyer_myrvold_planarity_test on a nonplanar graph +and verifies that it can be contracted into a graph isomorphic to a Kuratowski subgraph.
    • is_straight_line_drawing takes the output of chrobak_payne_straight_line_drawing and uses @@ -216,56 +216,56 @@

      Tools for working with planar graphs in the Boost Graph Library

      Complexity

      -Most of the algorithms in the Boost Graph Library that deal with planar graphs +Most of the algorithms in the Boost Graph Library that deal with planar graphs run in time O(n) on an input graph with n vertices. This achieves -a theoretically optimal bound (you must at least iterate over all n -vertices in order to embed a graph in the plane.) However, some of the work -that goes into achieving these theoretically optimal time bounds may come at -the expense of practical performance. For example, since any comparison-based -sorting algorithm uses at least on the order of n log n comparisons in +a theoretically optimal bound (you must at least iterate over all n +vertices in order to embed a graph in the plane.) However, some of the work +that goes into achieving these theoretically optimal time bounds may come at +the expense of practical performance. For example, since any comparison-based +sorting algorithm uses at least on the order of n log n comparisons in the worst case, any time an algorithm dealing with planar graphs needs to sort, -a bucket sort is used to sort in O(n) time. Also, computing a planar -embedding of a graph involves maintaining an ordered list of edges around a -vertex, and this list of edges needs to support an arbitrary sequence of -concatenations and reversals. A std::list can only guarantee -O(n2) for a mixed sequence of n concatenations and -reversals (since reverse is an O(n) operation.) However, our -implementation achieves O(n) for these operations by using a list data -structure that implements mixed sequences of concatenations and reversals +a bucket sort is used to sort in O(n) time. Also, computing a planar +embedding of a graph involves maintaining an ordered list of edges around a +vertex, and this list of edges needs to support an arbitrary sequence of +concatenations and reversals. A std::list can only guarantee +O(n2) for a mixed sequence of n concatenations and +reversals (since reverse is an O(n) operation.) However, our +implementation achieves O(n) for these operations by using a list data +structure that implements mixed sequences of concatenations and reversals lazily.

      -In both of the above cases, it may be preferable to sacrifice the nice -theoretical upper bound for performance by using the C++ STL. The bucket sort +In both of the above cases, it may be preferable to sacrifice the nice +theoretical upper bound for performance by using the C++ STL. The bucket sort allocates and populates a vector of vectors; because of the overhead in -doing so, std::stable_sort may actually be faster in some cases. -The custom list also uses more space than std::list, and it's not -clear that anything other than carefully constructed pathological examples -could force a std::list to use n2 operations within -the planar embedding algorithm. For these reasons, the macro -BOOST_GRAPH_PREFER_STD_LIB exists, which, when defined, will force -the planar graph algorithms to use std::stable_sort and +doing so, std::stable_sort may actually be faster in some cases. +The custom list also uses more space than std::list, and it's not +clear that anything other than carefully constructed pathological examples +could force a std::list to use n2 operations within +the planar embedding algorithm. For these reasons, the macro +BOOST_GRAPH_PREFER_STD_LIB exists, which, when defined, will force +the planar graph algorithms to use std::stable_sort and std::list in the examples above.

      -See the documentation on individual algorithms for more information about +See the documentation on individual algorithms for more information about complexity guarantees.

      Examples

        -
      1. Testing whether or not a +
      2. Testing whether or not a graph is planar. -
      3. Creating a straight line +
      4. Creating a straight line drawing of a graph in the plane.

      Notes

      [1] A graph G' is an expansion of a graph G if -G' can be created from G by a series of zero or more edge +G' can be created from G by a series of zero or more edge subdivisions: take any edge {x,y} in the graph, remove it, add a new -vertex z, and add the two edges {x,z} and {z,y} to the -graph. For example, a path of any length is an expansion of a single edge and +vertex z, and add the two edges {x,z} and {z,y} to the +graph. For example, a path of any length is an expansion of a single edge and a cycle of any length is an expansion of a triangle.
      @@ -273,4 +273,4 @@

      Notes

      Copyright © 2007 Aaron Windsor ( aaron.windsor@gmail.com) - + diff --git a/doc/plod_generator.html b/doc/plod_generator.html index 9e9f7ade2..1d51e95b9 100644 --- a/doc/plod_generator.html +++ b/doc/plod_generator.html @@ -1,11 +1,11 @@ @@ -23,10 +23,10 @@ - -C++ Boost + +C++ Boost plod_iterator @@ -53,12 +53,12 @@ plod_iterator operator++(int); bool operator==(const plod_iterator& other) const; bool operator!=(const plod_iterator& other) const; -}; +};

      This class template implements a generator for scale-free graphs using the Power Law Out Degree (PLOD) algorithm - [63], suitable for + [63], suitable for initializing an adjacency_list or other graph structure with iterator-based initialization. A scale-free graph @@ -119,7 +119,7 @@

      Example

      int main() { boost::minstd_rand gen; - // Create graph with 100 nodes + // Create graph with 100 nodes Graph g(SFGen(gen, 100, 2.5, 1000), SFGen(), 100); return 0; } @@ -136,4 +136,4 @@

      Example

    K5 (left) and K3,3 (right) - +
    K5 (left) and K3,3 (right) - the two Kuratowski subgraphs
    - + diff --git a/doc/predecessor_recorder.html b/doc/predecessor_recorder.html index c6f169c85..83f72fc74 100644 --- a/doc/predecessor_recorder.html +++ b/doc/predecessor_recorder.html @@ -1,17 +1,17 @@ Boost Graph Library: predecessor_recorder - -C++ Boost + +C++ Boost
    @@ -183,7 +183,7 @@

    See Also

    - + Boost Graph Library: Prim Minimum Spanning Tree - -C++ Boost + +C++ Boost
    @@ -30,12 +30,12 @@

    const bgl_named_params<P, T, R>& params) // non-named parameter version -template <class Graph, class DijkstraVisitor, +template <class Graph, class DijkstraVisitor, class PredecessorMap, class DistanceMap, class WeightMap, class IndexMap> void prim_minimum_spanning_tree(const Graph& g, - typename graph_traits<Graph>::vertex_descriptor s, - PredecessorMap predecessor, DistanceMap distance, WeightMap weight, + typename graph_traits<Graph>::vertex_descriptor s, + PredecessorMap predecessor, DistanceMap distance, WeightMap weight, IndexMap index_map, DijkstraVisitor vis) @@ -64,26 +64,26 @@

     PRIM-MST(G, s, w)
    -  for each vertex u in V[G]  
    +  for each vertex u in V[G]
         color[u] := WHITE
    -    d[u] := infinity  
    +    d[u] := infinity
       end for
       color[s] := GRAY
    -  d[s] := 0 
    -  ENQUEUE(PQ, s)  
    -  p[s] := s 
    -  while (PQ != Ø) 
    +  d[s] := 0
    +  ENQUEUE(PQ, s)
    +  p[s] := s
    +  while (PQ != Ø)
         u := DEQUEUE(PQ)
    -    for each v in Adj[u]  
    +    for each v in Adj[u]
           if (w(u,v) < d[v])
             d[v] := w(u,v)
    -        p[v] := u 
    -        if (color[v] =  WHITE) 
    -          ENQUEUE(PQ, v) 
    -          color[v] := GRAY 
    -        else if (color[v] =  GRAY) 
    -          UPDATE(PQ, v) 
    -      else 
    +        p[v] := u
    +        if (color[v] =  WHITE)
    +          ENQUEUE(PQ, v)
    +          color[v] := GRAY
    +        else if (color[v] =  GRAY)
    +          UPDATE(PQ, v)
    +      else
             do nothing
         end for
         color[u] := BLACK
    @@ -99,11 +99,11 @@ 

    start vertex s -discover vertex s +discover vertex s examine vertex u -examining edge (u,v) +examining edge (u,v) edge (u,v) relaxed @@ -113,7 +113,7 @@

    -edge (u,v) not relaxed +edge (u,v) not relaxed finish u

    @@ -130,7 +130,7 @@

    Where Defined

    Parameters

    -IN: const Graph& g +IN: const Graph& g
    An undirected graph. The type Graph must be a model of Vertex List Graph @@ -143,7 +143,7 @@

    Parameters

    OUT: PredecessorMap p_map
    The predecessor map records the edges in the minimum spanning - tree. Upon completion of the algorithm, the edges + tree. Upon completion of the algorithm, the edges (p[u],u) for all u in V are in the minimum spanning tree. If p[u] = u then u is either the root of the tree or is a vertex that is not reachable from the root. @@ -165,7 +165,7 @@

    Named Parameters

    Default: *vertices(g).first
    -IN: weight_map(WeightMap w_map) +IN: weight_map(WeightMap w_map)
    The weight or ``length'' of each edge in the graph. The type WeightMap must be a model of @@ -180,7 +180,7 @@

    Named Parameters

    Python default: graph.get_edge_double_map("weight")
    -IN: vertex_index_map(VertexIndexMap i_map) +IN: vertex_index_map(VertexIndexMap i_map)
    This maps each vertex to an integer in the range [0, num_vertices(g)). This is necessary for efficient updates of the @@ -198,17 +198,17 @@

    Named Parameters

    Python: Unsupported parameter.
    -UTIL/OUT: distance_map(DistanceMap d_map) +UTIL/OUT: distance_map(DistanceMap d_map)
    The weight of the spanning tree edge into each vertex in the graph g is recorded in this property map, with edges - directed away from the spanning tree root. + directed away from the spanning tree root. The type DistanceMap must be a model of Read/Write Property Map. The vertex descriptor type of the graph needs to be usable as the key type of the distance map, and the value type needs to be the same as the value type of the weight_map - argument.
    + argument.
    Default: iterator_property_map created from a std::vector of the WeightMap's value type of size @@ -218,7 +218,7 @@

    Named Parameters

    Python: Must be a vertex_double_map for the graph.
    -UTIL/OUT: color_map(ColorMap c_map) +UTIL/OUT: color_map(ColorMap c_map)
    This is used during the execution of the algorithm to mark the vertices. The vertices start out white and become gray when they are @@ -239,13 +239,13 @@

    Named Parameters

    Python: The color map must be a vertex_color_map for the graph.
    - -OUT: visitor(DijkstraVisitor v) + +OUT: visitor(DijkstraVisitor v)
    Use this to specify actions that you would like to happen during certain event points within the algorithm. The type DijkstraVisitor must be a model of the - Dijkstra Visitor concept. + Dijkstra Visitor concept. The visitor object is passed by value [1].
    Default: dijkstra_visitor<null_visitor>
    @@ -273,7 +273,7 @@

    Example

    Notes

    -

    [1] +

    [1] Since the visitor parameter is passed by value, if your visitor contains state then any changes to the state during the algorithm will be made to a copy of the visitor object, not the visitor object @@ -289,4 +289,4 @@

    Notes

    - + diff --git a/doc/profile.htm b/doc/profile.htm index 87cb4ad4e..2993b9456 100644 --- a/doc/profile.htm +++ b/doc/profile.htm @@ -10,7 +10,7 @@ --> -C++ Boost

    profile

      (1)
    @@ -23,22 +23,22 @@ 

    profile

    typename graph_traits<Graph>::vertices_size_type profile(const Graph& g, VertexIndexMap index_map)
    -

    The profile is the sum of all the maximum distances between the i-th +

    The profile is the sum of all the maximum distances between the i-th vertex and any of its neighbors with an index j>i.


    B(G) = max { |index[u] - index[v]|  | (u,v) in E }

    Defined in

    -boost/graph/profile.hpp +boost/graph/profile.hpp

    - + -
    Copyright © 2001-2002Marc Wintermantel, ETH Zurich (wintermantel@imes.mavt.ethz.ch) + Marc Wintermantel, ETH Zurich (wintermantel@imes.mavt.ethz.ch)
    diff --git a/doc/property.html b/doc/property.html index 3894a282c..71f2e95ee 100644 --- a/doc/property.html +++ b/doc/property.html @@ -1,17 +1,17 @@ Boost Graph Library: Property - -C++ Boost + +C++ Boost
    @@ -147,21 +147,21 @@

    Property Tags

       namespace boost {
    -    enum edge_name_t { edge_name }; 
    -    enum edge_weight_t { edge_weight }; 
    +    enum edge_name_t { edge_name };
    +    enum edge_weight_t { edge_weight };
         enum edge_index_t { edge_index };
    -    enum edge_capacity_t { edge_capacity }; 
    -    enum edge_residual_capacity_t { edge_residual_capacity }; 
    -    enum edge_reverse_t { edge_reverse }; 
    -    enum vertex_name_t { vertex_name }; 
    -    enum vertex_distance_t { vertex_distance }; 
    +    enum edge_capacity_t { edge_capacity };
    +    enum edge_residual_capacity_t { edge_residual_capacity };
    +    enum edge_reverse_t { edge_reverse };
    +    enum vertex_name_t { vertex_name };
    +    enum vertex_distance_t { vertex_distance };
         enum vertex_index_t { vertex_index };
    -    enum vertex_color_t { vertex_color }; 
    -    enum vertex_degree_t { vertex_degree }; 
    -    enum vertex_out_degree_t { vertex_out_degree }; 
    -    enum vertex_in_degree_t { vertex_in_degree }; 
    -    enum vertex_discover_time_t { vertex_discover_time }; 
    -    enum vertex_finish_time_t { vertex_finish_time }; 
    +    enum vertex_color_t { vertex_color };
    +    enum vertex_degree_t { vertex_degree };
    +    enum vertex_out_degree_t { vertex_out_degree };
    +    enum vertex_in_degree_t { vertex_in_degree };
    +    enum vertex_discover_time_t { vertex_discover_time };
    +    enum vertex_finish_time_t { vertex_finish_time };
         enum graph_name_t { graph_name };
     
         BOOST_INSTALL_PROPERTY(vertex, index);
    diff --git a/doc/property_map.html b/doc/property_map.html
    index 3ed394012..5455bda88 100644
    --- a/doc/property_map.html
    +++ b/doc/property_map.html
    @@ -1,17 +1,17 @@
     
     
     
     Boost Graph Library: Property Map Traits
    - 
    -C++ Boost 
    +
    +C++ Boost
     
     
    @@ -83,4 +83,4 @@

    Associated Types

    - + diff --git a/doc/property_put.html b/doc/property_put.html index 8dd7ecb8a..73dbead0a 100644 --- a/doc/property_put.html +++ b/doc/property_put.html @@ -3,17 +3,17 @@ Copyright (c) Jeremy Siek, Lie-Quan Lee, and Andrew Lumsdaine 2000 Copyright (c) 2010 Matthias Walter (xammy@xammy.homelinux.net) Copyright (c) 2010 Trustees of Indiana University - + Distributed under the Boost Software License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) --> Boost Graph Library: property_put - -C++ Boost + +C++ Boost
    @@ -181,7 +181,7 @@

    See Also

    - + Boost Graph Library: property_writer - -C++ Boost + +C++ Boost
    @@ -45,7 +45,7 @@

    Example

    boost::breadth_first_search (G, vertex(a, G), make_bfs_visitor( std::make_pair(write_property(name, cout_char, on_discover_vertex()), - std::make_pair(write_property(distance.begin(), cout_int, + std::make_pair(write_property(distance.begin(), cout_int, on_discover_vertex()), std::make_pair(print_edge(name, std::cout, on_examine_edge()), print_endl(std::cout, on_finish_vertex() @@ -194,7 +194,7 @@

    See Also

    - + Boost Graph Library: Publications - -C++ Boost + +C++ Boost
    @@ -43,4 +43,4 @@

    Boost Graph Library Related Publications

    - + diff --git a/doc/push_relabel_max_flow.html b/doc/push_relabel_max_flow.html index d70bad3ea..6cb8ad577 100644 --- a/doc/push_relabel_max_flow.html +++ b/doc/push_relabel_max_flow.html @@ -1,17 +1,17 @@ Boost Graph Library: Push-Relabel Maximum Flow - -C++ Boost + +C++ Boost
    @@ -24,17 +24,17 @@

    // named parameter version template <class Graph, class P, class T, class R> typename property_traits<CapacityEdgeMap>::value_type -push_relabel_max_flow(Graph& g, +push_relabel_max_flow(Graph& g, typename graph_traits<Graph>::vertex_descriptor src, typename graph_traits<Graph>::vertex_descriptor sink, const bgl_named_params<P, T, R>& params = all defaults) // non-named parameter version -template <class Graph, +template <class Graph, class CapacityEdgeMap, class ResidualCapacityEdgeMap, class ReverseEdgeMap, class VertexIndexMap> typename property_traits<CapacityEdgeMap>::value_type -push_relabel_max_flow(Graph& g, +push_relabel_max_flow(Graph& g, typename graph_traits<Graph>::vertex_descriptor src, typename graph_traits<Graph>::vertex_descriptor sink, CapacityEdgeMap cap, ResidualCapacityEdgeMap res, @@ -49,7 +49,7 @@

    maximum flow will be the return value of the function. The function also calculates the flow values f(u,v) for all (u,v) in E, which are returned in the form of the residual capacity -r(u,v) = c(u,v) - f(u,v). +r(u,v) = c(u,v) - f(u,v).

    There are several special requirements on the input graph and property @@ -96,14 +96,14 @@

    Parameters

    The source vertex for the flow network graph.
    - + IN: vertex_descriptor sink
    The sink vertex for the flow network graph.

    Named Parameters

    - + IN: capacity_map(EdgeCapacityMap cap)
    The edge capacity property map. The type must be a model of a @@ -112,7 +112,7 @@

    Named Parameters

    key type of the map must be the graph's edge descriptor type.
    Default: get(edge_capacity, g)
    - + OUT: residual_capacity_map(ResidualCapacityEdgeMap res)
    The edge residual capacity property map. The type must be a model of @@ -121,7 +121,7 @@

    Named Parameters

    key type of the map must be the graph's edge descriptor type.
    Default: get(edge_residual_capacity, g)
    - + IN: reverse_edge_map(ReverseEdgeMap rev)
    An edge property map that maps every edge (u,v) in the graph @@ -131,7 +131,7 @@

    Named Parameters

    key type of the map must be the graph's edge descriptor type.
    Default: get(edge_reverse, g)
    - + IN: vertex_index_map(VertexIndexMap index_map)
    Maps each vertex of the graph to a unique integer in the range @@ -168,7 +168,7 @@

    Example

    using namespace boost; typedef adjacency_list_traits<vecS, vecS, directedS> Traits; - typedef adjacency_list<vecS, vecS, directedS, + typedef adjacency_list<vecS, vecS, directedS, property<vertex_name_t, std::string>, property<edge_capacity_t, long, property<edge_residual_capacity_t, long, @@ -178,11 +178,11 @@

    Example

    Graph g; long flow; - property_map<Graph, edge_capacity_t>::type + property_map<Graph, edge_capacity_t>::type capacity = get(edge_capacity, g); - property_map<Graph, edge_reverse_t>::type + property_map<Graph, edge_reverse_t>::type rev = get(edge_reverse, g); - property_map<Graph, edge_residual_capacity_t>::type + property_map<Graph, edge_residual_capacity_t>::type residual_capacity = get(edge_residual_capacity, g); Traits::vertex_descriptor s, t; @@ -199,7 +199,7 @@

    Example

    for (boost::tie(u_iter, u_end) = vertices(g); u_iter != u_end; ++u_iter) for (boost::tie(ei, e_end) = out_edges(*u_iter, g); ei != e_end; ++ei) if (capacity[*ei] > 0) - std::cout << "f " << *u_iter << " " << target(*ei, g) << " " + std::cout << "f " << *u_iter << " " << target(*ei, g) << " " << (capacity[*ei] - residual_capacity[*ei]) << std::endl; return 0; } @@ -237,7 +237,7 @@

    See Also

    - + - - C++ Boost + + C++ Boost

    (Python)Boost Graph Library: Python Bindings (Experimental)

    The Boost Graph Library offers a wealth of graph algorithms and data types for C++. These algorithms are flexible and efficient, diff --git a/doc/quick_tour.html b/doc/quick_tour.html index 6078c6bd1..f6e248311 100644 --- a/doc/quick_tour.html +++ b/doc/quick_tour.html @@ -2,7 +2,7 @@ Boost Graph Library: Resource-Constrained Shortest Paths - -C++ Boost + +C++ Boost
    @@ -443,7 +443,7 @@

    Parameters

    A container for storing the Pareto-optimal resource containers in the overloads where all Pareto-optimal solutions are returned.
    -OUT: std::vector<typename graph_traits<Graph>::edge_descriptor>& +OUT: std::vector<typename graph_traits<Graph>::edge_descriptor>& pareto_optimal_solution
    A container for storing the first Pareto-optimal (undominated) solution (s-t-path) in the overloads where only one Pareto-optimal solution is returned. The path is returned as a sequence of edge descriptors in reverse order (from t to s). This argument is not modified if there are no solutions. diff --git a/doc/random.html b/doc/random.html index 058555060..1799dc554 100644 --- a/doc/random.html +++ b/doc/random.html @@ -1,7 +1,7 @@ Boost Graph Library: Random Graph Layout - -C++ Boost + +C++ Boost
    @@ -37,10 +37,10 @@

    Where Defined

    Parameters

    -IN: const Graph& g +IN: const Graph& g
    The graph object on which the algorithm will be applied. - The type Graph must be a model of + The type Graph must be a model of Vertex And Edge List Graph.
    @@ -75,4 +75,4 @@

    Complexity

    - + diff --git a/doc/random_spanning_tree.html b/doc/random_spanning_tree.html index 474a19ddd..21d5500a9 100644 --- a/doc/random_spanning_tree.html +++ b/doc/random_spanning_tree.html @@ -1,21 +1,21 @@ Boost Graph Library: Random Spanning Tree - -C++ Boost + +C++ Boost
    @@ -157,4 +157,4 @@

    Named Parameters

    - + diff --git a/doc/read_dimacs.html b/doc/read_dimacs.html index 3c50673c0..0269c9d81 100644 --- a/doc/read_dimacs.html +++ b/doc/read_dimacs.html @@ -34,10 +34,10 @@ --> Boost Graph Library: read_dimacs_max_flow and read_dimacs_min_cut - -C++ Boost + +C++ Boost

    @@ -49,7 +49,7 @@

    //reads a graph with attached edge_capacity properties from an std::istream template <class Graph, class CapacityMap, class ReverseEdgeMap> int read_dimacs_max_flow(Graph& g, - CapacityMap capacity, + CapacityMap capacity, ReverseEdgeMap reverse_edge, typename graph_traits::vertex_descriptor& src, typename graph_traits::vertex_descriptor& sink, @@ -58,18 +58,18 @@

    //reads a graph with attached edge_capacity properties from an std::istream template <class Graph, class CapacityMap, class ReverseEdgeMap> int read_dimacs_min_cut(Graph& g, - CapacityMap capacity, + CapacityMap capacity, ReverseEdgeMap reverse_edge, std::istream& in=std::cin)

    -These functions read a BGL graph object from a max-flow or min-cut problem description in extended dimacs format. (see Goldberg's site for more information). For each edge found in the +These functions read a BGL graph object from a max-flow or min-cut problem description in extended dimacs format. (see Goldberg's site for more information). For each edge found in the file an additional reverse_edge is added and set in the reverse_edge map. For max-flow problems, source and sink vertex descriptors are set according to the dimacs file. - +

    Where Defined

    @@ -78,37 +78,37 @@

    Where Defined

    Parameters

    IN: Graph& g
    - A directed or undirected graph. The graph's type must be a model of IncidenceGraph. -
    + A directed or undirected graph. The graph's type must be a model of IncidenceGraph. +
    OUT: CapacityMap capacity
    A property map that models mutable Lvalue Property Map whose key type is the edge descriptor of the graph.
    -
    +
    OUT: ReverseEdgeMap reverse_edge
    A property map that models mutable Lvalue Property Map whose key and value type is the edge descriptor of the graph. This map stores the corresponding reverse edge for each each in Graph g.
    -
    - +
    + OUT: vertex_descriptor& src
    A graph vertex that will be set to the source of a max-flow problem. -
    - +
    + OUT: vertex_descriptor& sink
    A graph vertex that will be set to the sink of a max-flow problem. -
    - +
  • + IN: std::istream& in
    A standard std::istream object.
    Default: std::cin (for backward compatibility) -
    +

    -Example +Example

    A short example which uses read_dimacs and write_dimacs is located in the examples directory. @@ -116,4 +116,4 @@

    See Also

    write_dimacs - + diff --git a/doc/read_graphml.rst b/doc/read_graphml.rst index 1e8bd8182..61323a9fe 100644 --- a/doc/read_graphml.rst +++ b/doc/read_graphml.rst @@ -3,11 +3,11 @@ ============================ .. Copyright (C) 2006 Tiago de Paula Peixoto - + Distributed under the Boost Software License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) - + Authors: Tiago de Paula Peixoto .. |(logo)| image:: ../../../boost.png @@ -21,11 +21,11 @@ __ ../../../index.htm void read_graphml(std::istream& in, MutableGraph& graph, dynamic_properties& dp, size_t graph_index = 0); - + The ``read_graphml`` function interprets a graph described using the GraphML_ format and builds a BGL graph that captures that description. Using this function, you can initialize a graph using -data stored as text. +data stored as text. The GraphML format can specify both directed and undirected graphs, and ``read_graphml`` differentiates between the two. One must pass diff --git a/doc/read_graphviz.rst b/doc/read_graphviz.rst index 92e7c7cc0..95df2ceb6 100644 --- a/doc/read_graphviz.rst +++ b/doc/read_graphviz.rst @@ -15,25 +15,25 @@ __ ../../../index.htm :: namespace boost { - + template bool read_graphviz(std::istream& in, MutableGraph& graph, - dynamic_properties& dp, + dynamic_properties& dp, const std::string& node_id = "node_id"); - + template bool read_graphviz(std::string& str, MutableGraph& graph, - dynamic_properties& dp, + dynamic_properties& dp, const std::string& node_id = "node_id"); - + template bool read_graphviz(InputIterator begin, InputIterator end, - MutableGraph& graph, dynamic_properties& dp, + MutableGraph& graph, dynamic_properties& dp, const std::string& node_id = "node_id"); - + } - + The ``read_graphviz`` function interprets a graph described using the GraphViz_ DOT language and builds a BGL graph that captures that description. Using these functions, you can initialize a graph using @@ -51,7 +51,7 @@ takes a dynamic_properties_ object and operates on its collection of property maps. The reader passes all the properties encountered to this object, using the GraphViz string keys as the property keys. Furthermore, ``read_graphviz`` stores node identifier names under the -vertex property map named ``node_id``. +vertex property map named ``node_id``. Requirements: - The type of the graph must model the `Mutable Graph`_ concept. @@ -140,7 +140,7 @@ GraphViz reader to populate an ``adjacency_list`` graph // Vertex properties typedef property < vertex_name_t, std::string, - property < vertex_color_t, float > > vertex_p; + property < vertex_color_t, float > > vertex_p; // Edge properties typedef property < edge_weight_t, double > edge_p; // Graph properties @@ -166,7 +166,7 @@ GraphViz reader to populate an ``adjacency_list`` graph dp.property("weight",weight); // Use ref_property_map to turn a graph property into a property map - boost::ref_property_map + boost::ref_property_map gname(get_property(graph,graph_name)); dp.property("name",gname); @@ -209,7 +209,7 @@ Notes reflect subgraphs as actual entities in the BGL. Rather, they are used to shorten some edge definitions as well as to give a subset of all nodes or edges certain properties. For example, the - DOT graphs ``digraph { a -> subgraph {b -> c} -> e }`` and + DOT graphs ``digraph { a -> subgraph {b -> c} -> e }`` and ``digraph { a -> b -> e ; a -> c -> e ; b -> c}`` are equivalent. - Subgraph IDs refer to subgraphs defined earlier in the graph diff --git a/doc/reverse_graph.html b/doc/reverse_graph.html index 761b75450..662d4813a 100644 --- a/doc/reverse_graph.html +++ b/doc/reverse_graph.html @@ -1,17 +1,17 @@ Boost Graph Library: Reverse Graph Adaptor - -C++ Boost + +C++ Boost
    @@ -39,10 +39,10 @@

    Example

    int main() { - typedef boost::adjacency_list< + typedef boost::adjacency_list< boost::vecS, boost::vecS, boost::bidirectionalS, > Graph; - + Graph G(5); boost::add_edge(0, 2, G); boost::add_edge(1, 1, G); @@ -60,7 +60,7 @@

    Example

    boost::print_graph(G, boost::get(boost::vertex_index, G)); std::cout << std::endl << "reversed graph:" << std::endl; - boost::print_graph(boost::make_reverse_graph(G), + boost::print_graph(boost::make_reverse_graph(G), boost::get(boost::vertex_index, G)); @@ -70,18 +70,18 @@

    Example

    The output is:
     original graph:
    -0 --> 2 
    -1 --> 1 3 4 
    -2 --> 1 3 4 
    -3 --> 1 4 
    -4 --> 0 1 
    +0 --> 2
    +1 --> 1 3 4
    +2 --> 1 3 4
    +3 --> 1 4
    +4 --> 0 1
     
     reversed graph:
    -0 --> 4 
    -1 --> 1 2 3 4 
    -2 --> 0 
    -3 --> 1 2 
    -4 --> 1 2 3 
    +0 --> 4
    +1 --> 1 2 3 4
    +2 --> 0
    +3 --> 1 2
    +4 --> 1 2 3
     

    Template Parameters

    @@ -443,4 +443,4 @@

    Non-Member Functions

    - + diff --git a/doc/sequential_vertex_coloring.html b/doc/sequential_vertex_coloring.html index 8620be922..6ffa9b561 100644 --- a/doc/sequential_vertex_coloring.html +++ b/doc/sequential_vertex_coloring.html @@ -2,7 +2,7 @@ -C++ Boost

    sloan_ordering

    @@ -26,114 +26,114 @@

    sloan_ordering

    Complexity: - time: O(log(m)|E|) where m = max { degree(v) | v + time: O(log(m)|E|) where m = max { degree(v) | v in V }
      (1)
       template <class Graph, class OutputIterator,
    -                  class ColorMap, class DegreeMap, 
    +                  class ColorMap, class DegreeMap,
                       class PriorityMap, class Weight>
       OutputIterator
       sloan_ordering(Graph& g,
                      typename graph_traits<Graph>::vertex_descriptor s,
                      typename graph_traits<Graph>::vertex_descriptor e,
    -                 OutputIterator permutation, 
    -                 ColorMap color, 
    -                 DegreeMap degree, 
    -                 PriorityMap priority, 
    -                 Weight W1, 
    +                 OutputIterator permutation,
    +                 ColorMap color,
    +                 DegreeMap degree,
    +                 PriorityMap priority,
    +                 Weight W1,
                      Weight W2 )
     
       (2)
        template <class Graph, class OutputIterator,
    -                  class ColorMap, class DegreeMap, 
    +                  class ColorMap, class DegreeMap,
                       class PriorityMap, class Weight>
       OutputIterator
       sloan_ordering(Graph& g,
    -                 OutputIterator permutation, 
    -                 ColorMap color, 
    -                 DegreeMap degree, 
    -                 PriorityMap priority, 
    -                 Weight W1, 
    +                 OutputIterator permutation,
    +                 ColorMap color,
    +                 DegreeMap degree,
    +                 PriorityMap priority,
    +                 Weight W1,
                      Weight W2 )
     
     
     (3)
      template <class Graph, class OutputIterator,
    -                  class ColorMap, class DegreeMap, 
    +                  class ColorMap, class DegreeMap,
                       class PriorityMap>
       OutputIterator
       sloan_ordering(Graph& g,
                      typename graph_traits<Graph>::vertex_descriptor s,
                      typename graph_traits<Graph>::vertex_descriptor e,
    -                 OutputIterator permutation, 
    -                 ColorMap color, 
    -                 DegreeMap degree, 
    +                 OutputIterator permutation,
    +                 ColorMap color,
    +                 DegreeMap degree,
                      PriorityMap priority )
     
     
     (4)
      template <class Graph, class OutputIterator,
    -                  class ColorMap, class DegreeMap, 
    +                  class ColorMap, class DegreeMap,
                       class PriorityMap>
       OutputIterator
       sloan_ordering(Graph& g,
    -                 OutputIterator permutation, 
    -                 ColorMap color, 
    -                 DegreeMap degree, 
    +                 OutputIterator permutation,
    +                 ColorMap color,
    +                 DegreeMap degree,
                      PriorityMap priority )
    -

    The goal of the Sloan ordering algorithm[1, 2] is to reduce the profile and - the wavefront of a graph by reordering the indices assigned to each vertex. - The Sloan algorithm needs a start and an end vertex. These vertices can be asigned - manually. But there is also an algorithm sloan_starting_nodes that provides - usually quite good start and end vertices. Each vertex is asigned with a priority. - This priority is a weighted sum of the distance of the vector to the end vertex - (a global criterion) and is called the current degree of vertex. This current - degree basically reflects the status of the renumbering in the neighborhood - of a vertex (a local criterion). Therefore the Sloan algorithm (in contrast - to-McKee) takes into account local as well as global criteria for the renumbering - sequence. One can play around with the relative weights, but the default values - proposed by Sloan (weight1/weight2=1/2) turn out to be pretty good in most cases. +

    The goal of the Sloan ordering algorithm[1, 2] is to reduce the profile and + the wavefront of a graph by reordering the indices assigned to each vertex. + The Sloan algorithm needs a start and an end vertex. These vertices can be asigned + manually. But there is also an algorithm sloan_starting_nodes that provides + usually quite good start and end vertices. Each vertex is asigned with a priority. + This priority is a weighted sum of the distance of the vector to the end vertex + (a global criterion) and is called the current degree of vertex. This current + degree basically reflects the status of the renumbering in the neighborhood + of a vertex (a local criterion). Therefore the Sloan algorithm (in contrast + to-McKee) takes into account local as well as global criteria for the renumbering + sequence. One can play around with the relative weights, but the default values + proposed by Sloan (weight1/weight2=1/2) turn out to be pretty good in most cases.

    -

    Version 1 of the algorithm lets the user choose the start- and end-vertex whereas - version 2 finds a good starting vertex using the already mentioned sloan_starting_node - algorithm. The choice of these vertices can have a significant effect on the - quality of the ordering. Version 3 and 4 are identical to version 1 and 2 respectively, - except that for the weights the standard weights W1=1 and W2=2 are used. -

    The output of the algorithm are the vertices in the new ordering. Depending - on what kind of output iterator you use, you can get either the Sloan ordering - or the reverse Sloan ordering. For example, if you store the output into a vector - using the vector's reverse iterator, then you get the reverse Sloan ordering. +

    Version 1 of the algorithm lets the user choose the start- and end-vertex whereas + version 2 finds a good starting vertex using the already mentioned sloan_starting_node + algorithm. The choice of these vertices can have a significant effect on the + quality of the ordering. Version 3 and 4 are identical to version 1 and 2 respectively, + except that for the weights the standard weights W1=1 and W2=2 are used. +

    The output of the algorithm are the vertices in the new ordering. Depending + on what kind of output iterator you use, you can get either the Sloan ordering + or the reverse Sloan ordering. For example, if you store the output into a vector + using the vector's reverse iterator, then you get the reverse Sloan ordering.

      std::vector<vertex_descriptor> inv_perm(num_vertices(G));
       sloan_ordering(G, inv_perm.rbegin());
     
    -

    Either way, storing the output into a vector gives you the permutation from +

    Either way, storing the output into a vector gives you the permutation from the new ordering to the old ordering.

      inv_perm[new_index[u]] == u
     
    -

    Sometimes, it is the opposite permutation that you want, the permutation from - the old index to the new index. This can easily be computed in the following - way. +

    Sometimes, it is the opposite permutation that you want, the permutation from + the old index to the new index. This can easily be computed in the following + way.

      for (size_type i = 0; i != inv_perm.size(); ++i)
         perm[old_index[inv_perm[i]]] = i;
     
    -

    Usually you need the reversed ordering with the Cuthill-McKee algorithm and +

    Usually you need the reversed ordering with the Cuthill-McKee algorithm and the direct ordering with the Sloan algorithm.

    Parameters

    -For version 1: +For version 1:
    • Graph& g  (IN)
      - An undirected graph. The graph's type must be a model of IncidenceGraph. + An undirected graph. The graph's type must be a model of IncidenceGraph.
    • vertex_descriptor s  (IN)
      - The starting vertex. + The starting vertex.
    • vertex_descriptor e (IN)
      The ending vertex
    • OutputIterator permutation  (OUT)
      The new vertex ordering. The vertices are written to the output iterator in - their new order. + href="http://www.boost.org/sgi/stl/OutputIterator.html">output iterator in + their new order.
    • ColorMap color_map  (WORK)
      - Used internally to keep track of the progress of the algorithm (to avoid visiting - the same vertex twice). + Used internally to keep track of the progress of the algorithm (to avoid visiting + the same vertex twice).
    • PriorityMap priority_map  (IN)
      Used internally to store the priority for renumbering of each vertex.
    • DegreeMap degree_map  (IN)
      @@ -144,15 +144,15 @@

      Parameters

      For version 2:

      • Graph& g  (IN)
        - An undirected graph. The graph's type must be a model of IncidenceGraph.
      • OutputIterator permutation  (OUT)
        - The new vertex ordering. The vertices are written to the output iterator in - their new order. + The new vertex ordering. The vertices are written to the output iterator in + their new order.
      • ColorMap color_map  (WORK)
        - Used internally to keep track of the progress of the algorithm (to avoid visiting - the same vertex twice). + Used internally to keep track of the progress of the algorithm (to avoid visiting + the same vertex twice).
      • PriorityMap priority_map  (IN)
        Used internally to store the priority for renumbering of each vertex.
      • DegreeMap degree_map  (IN)
        @@ -163,19 +163,19 @@

        Parameters

        For version 3:

        • Graph& g  (IN)
          - An undirected graph. The graph's type must be a model of IncidenceGraph. + An undirected graph. The graph's type must be a model of IncidenceGraph.
        • vertex_descriptor s  (IN)
          - The starting vertex. + The starting vertex.
        • vertex_descriptor e (IN)
          The ending vertex
        • OutputIterator permutation  (OUT)
          - The new vertex ordering. The vertices are written to the output iterator in - their new order. + The new vertex ordering. The vertices are written to the output iterator in + their new order.
        • ColorMap color_map  (WORK)
          - Used internally to keep track of the progress of the algorithm (to avoid visiting - the same vertex twice). + Used internally to keep track of the progress of the algorithm (to avoid visiting + the same vertex twice).
        • PriorityMap priority_map  (IN)
          Used internally to store the priority for renumbering of each vertex.
        • DegreeMap degree_map  (IN)
          @@ -184,15 +184,15 @@

          Parameters

          For version 4:

          • Graph& g  (IN)
            - An undirected graph. The graph's type must be a model of IncidenceGraph.
          • OutputIterator permutation  (OUT)
            - The new vertex ordering. The vertices are written to the output iterator in - their new order. + The new vertex ordering. The vertices are written to the output iterator in + their new order.
          • ColorMap color_map  (WORK)
            - Used internally to keep track of the progress of the algorithm (to avoid visiting - the same vertex twice). + Used internally to keep track of the progress of the algorithm (to avoid visiting + the same vertex twice).
          • PriorityMap priority_map  (IN)
            Used internally to store the priority for renumbering of each vertex.
          • DegreeMap degree_map  (IN)
            @@ -200,25 +200,25 @@

            Parameters

           

          Example

          -See example/sloan_ordering.cpp. +See example/sloan_ordering.cpp.

          See Also

          -

          sloan_start_end_vertices, - bandwidth, profile, wavefront +

          sloan_start_end_vertices, + bandwidth, profile, wavefront and degree_property_map in boost/graph/properties.hpp.

          -

          [1] S. W. Sloan, An algorithm for profile and wavefront reduction of sparse +

          [1] S. W. Sloan, An algorithm for profile and wavefront reduction of sparse matrices, Int. j. numer. methods eng., 23, 239 - 251 (1986)

          -

          [2] S. W. Sloan, A fortran program for profile and wavefront reduction, +

          [2] S. W. Sloan, A fortran program for profile and wavefront reduction, Int. j. numer. methods eng., 28, 2651 - 2679 (1989)


          - + -
          Copyright © 2001-2002Marc Wintermantel, ETH Zurich (wintermantel@imes.mavt.ethz.ch) + Marc Wintermantel, ETH Zurich (wintermantel@imes.mavt.ethz.ch)
          diff --git a/doc/sloan_start_end_vertices.htm b/doc/sloan_start_end_vertices.htm index 1f5ea48f0..6561d5cc5 100644 --- a/doc/sloan_start_end_vertices.htm +++ b/doc/sloan_start_end_vertices.htm @@ -9,9 +9,9 @@ -- http://www.boost.org/LICENSE_1_0.txt) --> -C++ Boost +C++ Boost

          sloan_start_end_vertices

          @@ -34,53 +34,53 @@

          sloan_start_end_vertices

          typename graph_traits<Graph>::vertex_descriptor sloan_start_end_vertices(Graph& G, typename graph_traits<Graph>::vertex_descriptor &s, - ColorMap color, + ColorMap color, DegreeMap degree ) -

          The goal of the sloan_start_end_vertices algorithm[1, 2] is to find good start- - and end-vertices for the profile and wavefront reduction algorithm sloan_ordering. - The algorithm is similar to pseudo_peripheral_pair and also based on breadth_first_search. - With this breadth_first_search function a so-called rooted level structure (RLS) - is formed, where the vertices with the same distance to the starting vertex - are grouped together. The maximum number of vertices in one group is called - the width of the RLS. Sloan_start_end_vertices tries to find a pseudoperipheral +

          The goal of the sloan_start_end_vertices algorithm[1, 2] is to find good start- + and end-vertices for the profile and wavefront reduction algorithm sloan_ordering. + The algorithm is similar to pseudo_peripheral_pair and also based on breadth_first_search. + With this breadth_first_search function a so-called rooted level structure (RLS) + is formed, where the vertices with the same distance to the starting vertex + are grouped together. The maximum number of vertices in one group is called + the width of the RLS. Sloan_start_end_vertices tries to find a pseudoperipheral pair with a minimum RLS-width.

          Parameters

          -For version 1: +For version 1:
          • Graph& g  (IN)
            - An undirected graph. The graph's type must be a model of IncidenceGraph. + An undirected graph. The graph's type must be a model of IncidenceGraph.
          • vertex_descriptor s  (IN)
            - The starting vertex. + The starting vertex.
          • ColorMap color_map  (WORK)
            - Used internally to keep track of the progress of the algorithm (to avoid visiting - the same vertex twice). + Used internally to keep track of the progress of the algorithm (to avoid visiting + the same vertex twice).
          • DegreeMap degree_map  (IN)
            This must map vertices to their degree.

           

          Example

          -See example/sloan_ordering.cpp. +See example/sloan_ordering.cpp.

          See Also

          -

          sloan_start_end_vertices, - bandwidth, profile, - wavefront and +

          sloan_start_end_vertices, + bandwidth, profile, + wavefront and degree_property_map in boost/graph/properties.hpp.

          -

          [1] S. W. Sloan, An algorithm for profile and wavefront reduction of sparse +

          [1] S. W. Sloan, An algorithm for profile and wavefront reduction of sparse matrices, Int. j. numer. methods eng., 23, 239 - 251 (1986)

          -

          [2] S. W. Sloan, A fortran program for profile and wavefront reduction, +

          [2] S. W. Sloan, A fortran program for profile and wavefront reduction, Int. j. numer. methods eng., 28, 2651 - 2679 (1989)


          - + -
          Copyright © 2001-2002Marc Wintermantel, ETH Zurich(wintermantel@imes.mavt.ethz.ch) + Marc Wintermantel, ETH Zurich(wintermantel@imes.mavt.ethz.ch)
          diff --git a/doc/small_world_generator.html b/doc/small_world_generator.html index ed6f10331..e67fd102e 100644 --- a/doc/small_world_generator.html +++ b/doc/small_world_generator.html @@ -1,11 +1,11 @@ @@ -23,10 +23,10 @@ - -C++ Boost + +C++ Boost small_world_iterator @@ -54,7 +54,7 @@ small_world_iterator operator++(int); bool operator==(const small_world_iterator& other) const; bool operator!=(const small_world_iterator& other) const; -}; +};

          This class template implements a generator for small-world graphs, @@ -106,7 +106,7 @@

          Example

          int main() { boost::minstd_rand gen; - // Create graph with 100 nodes + // Create graph with 100 nodes Graph g(SWGen(gen, 100, 6, 0.03), SWGen(), 100); return 0; } @@ -123,4 +123,4 @@

          Example

          - + diff --git a/doc/sorted_erdos_renyi_gen.html b/doc/sorted_erdos_renyi_gen.html index 254d498ca..6fef39795 100644 --- a/doc/sorted_erdos_renyi_gen.html +++ b/doc/sorted_erdos_renyi_gen.html @@ -1,11 +1,11 @@ Sparse Matrix Ordering Example - -C++ Boost + +C++ Boost
          @@ -134,24 +134,24 @@

           namespace boost {
             template <class Graph, class Vertex, class Color, class Degree>
          -  Vertex 
          +  Vertex
             pseudo_peripheral_pair(Graph& G, const Vertex& u, int& ecc,
                                    Color color, Degree degree)
             {
               typename property_traits<Color>::value_type c = get(color, u);
           
               rcm_queue<Vertex, Degree> Q(degree);
          -    
          +
               typename boost::graph_traits<Graph>::vertex_iterator ui, ui_end;
               for (boost::tie(ui, ui_end) = vertices(G); ui != ui_end; ++ui)
                 put(color, *ui, white(c));
               breadth_first_search(G, u, Q, bfs_visitor<>(), color);
           
          -    ecc = Q.eccentricity(); 
          +    ecc = Q.eccentricity();
               return Q.spouse();
             }
          -  
          -  template <class Graph, class Vertex, class Color, class Degree> 
          +
          +  template <class Graph, class Vertex, class Color, class Degree>
             Vertex find_starting_node(Graph& G, Vertex r, Color c, Degree d) {
               int eccen_r, eccen_x;
               Vertex x = pseudo_peripheral_pair(G, r, eccen_r, c, d);
          @@ -196,12 +196,12 @@ 

          -  template < class Graph, class Vertex, class OutputIterator, 
          +  template < class Graph, class Vertex, class OutputIterator,
                        class Color, class Degree >
          -  inline void 
          -  cuthill_mckee_ordering(Graph& G, 
          +  inline void
          +  cuthill_mckee_ordering(Graph& G,
                                    Vertex s,
          -                         OutputIterator inverse_permutation, 
          +                         OutputIterator inverse_permutation,
                                    Color color, Degree degree)
             {
               typedef typename property_traits<Degree>::value_type DS;
          @@ -212,12 +212,12 @@ 

          typedef cuthill_mckee_visitor<OutputIterator> CMVisitor; CMVisitor cm_visitor(inverse_permutation); - + typename boost::graph_traits<Graph>::vertex_iterator ui, ui_end; for (boost::tie(ui, ui_end) = vertices(G); ui != ui_end; ++ui) put(color, *ui, white(c)); breadth_first_search(G, s, Q, cm_visitor, color); - } + }

          @@ -246,18 +246,18 @@

          Minimum Degree Ordering Algorithm

          1. Start: Construct undirected graph G0 corresponding to matrix A - +
          2. -
          3. Iterate: For k = 1, 2, ... until +
          4. Iterate: For k = 1, 2, ... until Gk = { } do: - +
            • Choose a vertex vk from Gk according to some criterion
            • -
            • Eliminate vk from Gk to form +
            • Eliminate vk from Gk to form Gk+1 - +
          5. @@ -374,4 +374,4 @@

            Proper Self-Avoiding Walk

            - + diff --git a/doc/stanford_graph.html b/doc/stanford_graph.html index 6e3a77ea9..ea578cbe2 100644 --- a/doc/stanford_graph.html +++ b/doc/stanford_graph.html @@ -9,10 +9,10 @@ --> Boost Graph Library: Stanford Graph Interface - -C++ Boost + +C++ Boost
            @@ -455,4 +455,4 @@

            Vertex and Edge Properties

            - + diff --git a/doc/stoer_wagner_min_cut.html b/doc/stoer_wagner_min_cut.html index ddd862785..344f488d1 100644 --- a/doc/stoer_wagner_min_cut.html +++ b/doc/stoer_wagner_min_cut.html @@ -10,7 +10,7 @@ Boost Graph Library: Stoer–Wagner Min-Cut -C++ Boost +C++ Boost

            stoer_wagner_min_cut

            @@ -67,7 +67,7 @@

            Named Parameters

            Expert Parameters

            -

            IN: vertex_index_map(VertexIndexMap vertexIndices) +

            IN: vertex_index_map(VertexIndexMap vertexIndices)

            This maps each vertex to an integer in the range [0, num_vertices(g)). This is only necessary if the default is used for the assignment, index-in-heap, or distance maps. @@ -92,7 +92,7 @@

            Expert Parameters

            MaxPriorityQueue must be a model of Keyed Updatable Queue and a max-Updatable Priority Queue. - The value type must be the graph's vertex descriptor and the key type must be + The value type must be the graph's vertex descriptor and the key type must be the weight type. Default: A boost::d_ary_heap_indirect using a default index-in-heap and distance map. diff --git a/doc/straight_line_drawing.html b/doc/straight_line_drawing.html index d54e6e71f..66c87a29d 100644 --- a/doc/straight_line_drawing.html +++ b/doc/straight_line_drawing.html @@ -1,17 +1,17 @@ Boost Graph Library: Chrobak-Payne Straight Line Drawing - -C++ Boost + +C++ Boost
            @@ -19,13 +19,13 @@

            Chrobak-Payne Straight Line Drawing

            -template<typename Graph, 
            -         typename PlanarEmbedding, 
            -         typename ForwardIterator, 
            +template<typename Graph,
            +         typename PlanarEmbedding,
            +         typename ForwardIterator,
                      typename PositionMap,
                      typename VertexIndexMap>
            -void chrobak_payne_straight_line_drawing(const Graph& g, 
            -                                         PlanarEmbedding perm, 
            +void chrobak_payne_straight_line_drawing(const Graph& g,
            +                                         PlanarEmbedding perm,
                                                      ForwardIterator ordering_begin,
                                                      ForwardIterator ordering_end,
                                                      PositionMap drawing,
            @@ -36,14 +36,14 @@ 

            Chrobak-Payne Straight Line Drawing


            A straight line drawing of a -planar graph is a plane -drawing where each edge is drawn using a straight line segment. Since all -edges are line segments, the drawing is completely determined by the placement -of vertices in the plane. chrobak_payne_straight_line_drawing uses an -algorithm of Chrobak and Payne -[71] -to form a straight -line drawing of a planar graph by mapping all n vertices in a planar +planar graph is a plane +drawing where each edge is drawn using a straight line segment. Since all +edges are line segments, the drawing is completely determined by the placement +of vertices in the plane. chrobak_payne_straight_line_drawing uses an +algorithm of Chrobak and Payne +[71] +to form a straight +line drawing of a planar graph by mapping all n vertices in a planar graph to integer coordinates in a (2n - 4) x (n - 2) grid.

            @@ -51,18 +51,18 @@

            Chrobak-Payne Straight Line Drawing

            -The input graph passed to chrobak_payne_straight_line_drawing must -be a maximal planar graph with at least -3 vertices. Self-loops and parallel edges are ignored by this function. Note +The input graph passed to chrobak_payne_straight_line_drawing must +be a maximal planar graph with at least +3 vertices. Self-loops and parallel edges are ignored by this function. Note that the restriction that the graph be maximal planar does not mean that this function can only draw maximal planar graphs (the graph pictured -above is not maximal planar, for example). If you want to -draw a graph g, you can create a copy g' of g, store a -mapping m of vertices in g' to vertices in g, -triangulate g', and then send -g' in as the input to chrobak_payne_straight_line_drawing. The -drawing returned can then be applied to g using m to translate -vertices from one graph to another, since g contains a subset of the +above is not maximal planar, for example). If you want to +draw a graph g, you can create a copy g' of g, store a +mapping m of vertices in g' to vertices in g, +triangulate g', and then send +g' in as the input to chrobak_payne_straight_line_drawing. The +drawing returned can then be applied to g using m to translate +vertices from one graph to another, since g contains a subset of the edges in g'. @@ -70,10 +70,10 @@

            Chrobak-Payne Straight Line Drawing

            Complexity

            If the vertex index map provides constant-time access to indices, this -function takes time O(n + m) for a planar graph with n vertices -and m edges. Note that -in a simple planar graph with f faces, m edges, and n -vertices, both f and m are O(n). +function takes time O(n + m) for a planar graph with n vertices +and m edges. Note that +in a simple planar graph with f faces, m edges, and n +vertices, both f and m are O(n).

            Where Defined

            @@ -96,26 +96,26 @@

            Parameters

            A Readable Property Map - that models the PlanarEmbedding + that models the PlanarEmbedding concept.
            IN ForwardIterator
            -A ForwardIterator that has value_type equal to +A ForwardIterator that has value_type equal to graph_traits<Graph>::vertex_descriptor.
            -OUT: PositionMap +OUT: PositionMap
            -A Writable LValue Property +A Writable LValue Property Map that models the Position Map concept. The Position Map concept requires that the value mapped to be an object that has members x and y. For example, if p models PositionMap and v is a vertex in the graph, p[v].x and p[v].y are valid -expressions. The type of x and y must be implicitly +expressions. The type of x and y must be implicitly convertable to std::size_t.
            @@ -123,7 +123,7 @@

            Parameters

            A Readable Property Map - that maps vertices from g to distinct integers in the range + that maps vertices from g to distinct integers in the range [0, num_vertices(g) )
            Default: get(vertex_index,g)
            @@ -151,4 +151,4 @@

            See Also

            Copyright © 2007 Aaron Windsor ( aaron.windsor@gmail.com) - + diff --git a/doc/strong_components.html b/doc/strong_components.html index 39c0cc52d..b97b78302 100644 --- a/doc/strong_components.html +++ b/doc/strong_components.html @@ -1,17 +1,17 @@ Boost Graph Library: Strongly Connected Components - -C++ Boost + +C++ Boost
            @@ -198,4 +198,4 @@

            Example

            - + diff --git a/doc/strong_components.w b/doc/strong_components.w index 503f4fed1..bc96bb02d 100644 --- a/doc/strong_components.w +++ b/doc/strong_components.w @@ -40,7 +40,7 @@ have a common ancestor in $F$. Also, if $u$ is the common ancestor of $u$ and $v$ with the latest discover time then $w$ is also in the same SCC as $u$ and $v$. -Proof. +Proof. If there is a path from $v$ to $w$ and if they are in different DFS trees, then the discover time for $w$ must be earlier than for $v$. @@ -76,13 +76,13 @@ following cases: $u$ in the DFS tree and therefore we have a cycle and $u$ must be in a SCC with $a$. We then set $root[u] = a$ and continue our way back up the DFS. - + \item If $a = u$ then we know that $u$ must be the topmost vertex of a subtree that defines a SCC. All of the vertices in this subtree are further down on the stack than vertex $u$ so we pop the vertices off of the stack until we reach $u$ and mark each one as being in the same component. - + \item If $d[a] > d[u]$ then the adjacent vertices are in different strongly connected components. We continue our way back up the DFS. diff --git a/doc/successive_shortest_path_nonnegative_weights.html b/doc/successive_shortest_path_nonnegative_weights.html index 434eabbbb..b895018e4 100644 --- a/doc/successive_shortest_path_nonnegative_weights.html +++ b/doc/successive_shortest_path_nonnegative_weights.html @@ -1,17 +1,17 @@ Boost Graph Library: Successive Shortest Path for Min Cost Max Flow - -C++ Boost + +C++ Boost
            @@ -23,34 +23,34 @@

            // named parameter version template <class Graph, class P, class T, class R> void successive_shortest_path_nonnegative_weights( - Graph &g, - typename graph_traits<Graph>::vertex_descriptor s, + Graph &g, + typename graph_traits<Graph>::vertex_descriptor s, typename graph_traits<Graph>::vertex_descriptor t, const bgl_named_params<P, T, R> & params = all defaults) // non-named parameter version template <class Graph, class Capacity, class ResidualCapacity, class Reversed, class Pred, class Weight, class Distance, class Distance2, class VertexIndex> void successive_shortest_path_nonnegative_weights( - const Graph & g, - typename graph_traits<Graph>::vertex_descriptor s, + const Graph & g, + typename graph_traits<Graph>::vertex_descriptor s, typename graph_traits<Graph>::vertex_descriptor t, Capacity capacity, ResidualCapacity residual_capacity, - Weight weight, + Weight weight, Reversed rev, VertexIndex index, - Pred pred, + Pred pred, Distance distance, - Distance2 distance_prev) + Distance2 distance_prev)

          The successive_shortest_path_nonnegative_weights() function calculates the minimum cost maximum flow of a network. See Section Network -Flow Algorithms for a description of maximum flow. +Flow Algorithms for a description of maximum flow. The function calculates the flow values f(u,v) for all (u,v) in E, which are returned in the form of the residual capacity -r(u,v) = c(u,v) - f(u,v). +r(u,v) = c(u,v) - f(u,v).

          There are several special requirements on the input graph and property @@ -72,7 +72,7 @@

          This algorithm starts with empty flow and in each round augments the shortest path (in terms of weight) in the residual graph. -

          +

          In order to find the cost of the result flow use: find_flow_cost(). @@ -98,12 +98,12 @@

          Parameters

          The source vertex for the flow network graph.
          - + IN: vertex_descriptor t
          The sink vertex for the flow network graph.
          - +

          Named Parameters

          @@ -115,7 +115,7 @@

          Named Parameters

          key type of the map must be the graph's edge descriptor type.
          Default: get(edge_capacity, g)
    - + OUT: residual_capacity_map(ResidualCapacityEdgeMap res)
    This maps edges to their residual capacity. The type must be a model @@ -136,11 +136,11 @@

    Named Parameters

    Default: get(edge_reverse, g)
    -IN: weight_map(WeightMap w_map) +IN: weight_map(WeightMap w_map)
    The weight or ``cost'' of each edge in the graph. The weights must all be non-negative, and the algorithm will throw a - negative_edge + negative_edge exception if one of the edges is negative. The type WeightMap must be a model of Readable Property Map. The edge descriptor type of @@ -166,7 +166,7 @@

    Named Parameters

    using the i_map for the index map.
    -UTIL: distance_map(DistanceMap d_map) +UTIL: distance_map(DistanceMap d_map)
    The shortest path weight from the source vertex s to each vertex in the graph g is recorded in this property map. The @@ -174,7 +174,7 @@

    Named Parameters

    shortest path. The type DistanceMap must be a model of Read/Write Property Map. The vertex descriptor type of the graph needs to - be usable as the key type of the distance map. + be usable as the key type of the distance map. Default: @@ -185,13 +185,13 @@

    Named Parameters

    -UTIL: distance_map2(DistanceMap2 d_map2) +UTIL: distance_map2(DistanceMap2 d_map2)
    The shortest path computation in iteration nr k uses distances computed in iteration k. The type DistanceMap2 must be a model of Read/Write Property Map. The vertex descriptor type of the graph needs to - be usable as the key type of the distance map. + be usable as the key type of the distance map. Default: @@ -220,7 +220,7 @@

    Named Parameters

    Complexity

    -In the integer capacity case, if U is the value of the max flow, then the complexity is O(U * (|E| + |V|*log|V|)), +In the integer capacity case, if U is the value of the max flow, then the complexity is O(U * (|E| + |V|*log|V|)), where O(|E| + |V|*log|V|) is the complexity of the dijkstra algorithm and U is upper bound on number of iteration. In many real world cases number of iterations is much smaller than U. @@ -244,7 +244,7 @@

    See Also

    - + Boost Graph Library: time_stamper - -C++ Boost + +C++ Boost
    @@ -193,7 +193,7 @@

    See Also

    - + Boost Graph Library: Topological Sort - -C++ Boost + +C++ Boost
    @@ -153,4 +153,4 @@

    Example

    - + diff --git a/doc/topology.html b/doc/topology.html index 2eefd237d..a2abbd29e 100644 --- a/doc/topology.html +++ b/doc/topology.html @@ -1,7 +1,7 @@ Boost Graph Library: Transitive Closure - -C++ Boost + +C++ Boost
    @@ -66,7 +66,7 @@

    Parameters

    OUT: GraphTC& tc
    A directed graph, where the GraphTC type must model the - Vertex Mutable Graph + Vertex Mutable Graph and Edge Mutable Graph concepts.
    Python: This parameter is not used in Python. Instead, a new @@ -221,4 +221,4 @@

    Implementation Notes

    - + diff --git a/doc/transitive_closure.w b/doc/transitive_closure.w index 136eab681..9e214b3e0 100644 --- a/doc/transitive_closure.w +++ b/doc/transitive_closure.w @@ -97,7 +97,7 @@ void transitive_closure(const Graph& g, GraphTC& tc) typedef typename graph_traits::vertex_descriptor tc_vertex; std::vector to_tc_vec(num_vertices(g)); - iterator_property_map + iterator_property_map g_to_tc_map(&to_tc_vec[0], index_map); transitive_closure(g, tc, g_to_tc_map, index_map); @@ -118,7 +118,7 @@ void transitive_closure(const Graph& g, GraphTC& tc, const bgl_named_params& params) { if (num_vertices(g) == 0) return; - detail::transitive_closure_dispatch(g, tc, + detail::transitive_closure_dispatch(g, tc, get_param(params, orig_to_copy), choose_const_pmap(get_param(params, vertex_index), g, vertex_index) ); @@ -132,7 +132,7 @@ mapping or to use the default, a vector, to map between the two. @d Construct Default G to TC Vertex Mapping @{ namespace detail { - template void transitive_closure_dispatch @@ -141,7 +141,7 @@ namespace detail { VertexIndexMap index_map) { typedef typename graph_traits::vertex_descriptor tc_vertex; - typename std::vector::size_type + typename std::vector::size_type n = is_default_param(g_to_tc_map) ? num_vertices(g) : 1; std::vector to_tc_vec(n); @@ -192,7 +192,7 @@ the same integer type \code{cg\_vertex} for both. @{ typedef size_type cg_vertex; std::vector component_number_vec(num_vertices(g)); -iterator_property_map +iterator_property_map component_number(&component_number_vec[0], index_map); int num_scc = strong_components(g, component_number, @@ -259,7 +259,7 @@ for (cg_vertex s = 0; s < components.size(); ++s) { std::sort(adj.begin(), adj.end()); std::vector::iterator di = std::unique(adj.begin(), adj.end()); if (di != adj.end()) - adj.erase(di, adj.end()); + adj.erase(di, adj.end()); CG[s] = adj; } @} @@ -335,7 +335,7 @@ topological numbers to the vertices. @{ std::vector topo_order; std::vector topo_number(num_vertices(CG)); -topological_sort(CG, std::back_inserter(topo_order), +topological_sort(CG, std::back_inserter(topo_order), vertex_index_map(identity_property_map())); std::reverse(topo_order.begin(), topo_order.end()); size_type n = 0; @@ -354,10 +354,10 @@ returns the topological number of its input argument. @d Sort the out-edge lists by topological number @{ for (size_type i = 0; i < num_vertices(CG); ++i) - std::sort(CG[i].begin(), CG[i].end(), + std::sort(CG[i].begin(), CG[i].end(), compose_f_gx_hy(std::less(), detail::subscript(topo_number), - detail::subscript(topo_number))); + detail::subscript(topo_number))); @} Here is the code that defines the \code{subscript\_t} function object @@ -366,7 +366,7 @@ and its associated helper object generation function. @d Subscript function object @{ namespace detail { - template struct subscript_t : public std::unary_function { subscript_t(Container& c) : container(&c) { } @@ -443,7 +443,7 @@ for (size_type i = 0; i < chains.size(); ++i) cg_vertex v = chains[i][j]; chain_number[v] = i; pos_in_chain[v] = j; - } + } @} Now that we have completed the chain decomposition we are ready to @@ -471,7 +471,7 @@ for (std::vector::reverse_iterator i = topo_order.rbegin(); cg_vertex v = *adj; if (topo_number[v] < successors[u][chain_number[v]]) { // Succ(u) = Succ(u) U Succ(v) - detail::union_successor_sets(successors[u], successors[v], + detail::union_successor_sets(successors[u], successors[v], successors[u]); // Succ(u) = Succ(u) U {v} successors[u][chain_number[v]] = topo_number[v]; @@ -490,7 +490,7 @@ vector. @{ for (size_type i = 0; i < CG.size(); ++i) CG[i].clear(); -for (size_type i = 0; i < CG.size(); ++i) +for (size_type i = 0; i < CG.size(); ++i) for (size_type j = 0; j < chains.size(); ++j) { size_type topo_num = successors[i][j]; if (topo_num < inf) { @@ -539,11 +539,11 @@ for (size_type i = 0; i < components.size(); ++i) add_edge(g_to_tc_map[u], g_to_tc_map[v], tc); } -// Find loopbacks in the original graph. +// Find loopbacks in the original graph. // Need to add it to transitive closure. { vertex_iterator i, i_end; - for (tie(i, i_end) = vertices(g); i != i_end; ++i) + for (tie(i, i_end) = vertices(g); i != i_end; ++i) { adjacency_iterator ab, ae; for (boost::tie(ab, ae) = adjacent_vertices(*i, g); ab != ae; ++ab) @@ -577,14 +577,14 @@ void warshall_transitive_closure(G& g) // A[i,j] = A[i,j] | A[k,j] vertex_iterator ki, ke, ii, ie, ji, je; for (tie(ki, ke) = vertices(g); ki != ke; ++ki) - for (tie(ii, ie) = vertices(g); ii != ie; ++ii) + for (tie(ii, ie) = vertices(g); ii != ie; ++ii) if (edge(*ii, *ki, g).second) for (tie(ji, je) = vertices(g); ji != je; ++ji) if (!edge(*ii, *ji, g).second && edge(*ki, *ji, g).second) { add_edge(*ii, *ji, g); - } + } } @} @@ -600,12 +600,12 @@ void warren_transitive_closure(G& g) BOOST_CONCEPT_ASSERT(( AdjacencyMatrixConcept )); BOOST_CONCEPT_ASSERT(( EdgeMutableGraphConcept )); - // Make sure second loop will work + // Make sure second loop will work if (num_vertices(g) == 0) return; // for i = 2 to n - // for k = 1 to i - 1 + // for k = 1 to i - 1 // if A[i,k] // for j = 1 to n // A[i,j] = A[i,j] | A[k,j] @@ -635,7 +635,7 @@ void warren_transitive_closure(G& g) edge(*kc, *jc, g).second) { add_edge(*ic, *jc, g); - } + } } @} @@ -653,7 +653,7 @@ indent -nut -npcs -i2 -br -cdw -ce transitive_closure.hpp // Copyright (C) 2001 Vladimir Prus // Copyright (C) 2001 Jeremy Siek // Permission to copy, use, modify, sell and distribute this software is -// granted, provided this copyright notice appears in all copies and +// granted, provided this copyright notice appears in all copies and // modified version are clearly marked as such. This software is provided // "as is" without express or implied warranty, and with no claim as to its // suitability for any purpose. diff --git a/doc/transpose_graph.html b/doc/transpose_graph.html index a8fc62ae5..30cf44d4f 100644 --- a/doc/transpose_graph.html +++ b/doc/transpose_graph.html @@ -1,24 +1,24 @@ Boost Graph Library: Transpose Graph - -C++ Boost + +C++ Boost

    transpose_graph

    -template <class VertexListGraph, class MutableGraph> 
    +template <class VertexListGraph, class MutableGraph>
     void transpose_graph(const VertexListGraph& G, MutableGraph& G_T,
         const bgl_named_params<P, T, R>& params = all defaults)
     
    @@ -124,4 +124,4 @@

    Complexity

    - + diff --git a/doc/trouble_shooting.html b/doc/trouble_shooting.html index fe20679c4..b9108ff76 100644 --- a/doc/trouble_shooting.html +++ b/doc/trouble_shooting.html @@ -1,17 +1,17 @@ Boost Graph Library: Trouble Shooting - -C++ Boost + +C++ Boost
    @@ -31,7 +31,7 @@

    Trouble Shooting


    -error C2784: 'T __cdecl source(struct std::pair,const G &)' : 
    +error C2784: 'T __cdecl source(struct std::pair,const G &)' :
     could not deduce template argument for 'struct std::pair<_T1,_T1>' from
      'class boost::detail::bidir_edge'
     
    @@ -44,7 +44,7 @@

    Trouble Shooting

     ../../..\boost/property_map.hpp(283) : error C2678: binary '[' : no operator defined
      which takes a left-hand operand of type 'const struct boost::adj_list_edge_property_map,unsigned int,enum boost::edge_weight_t>' (or there is no acceptable conversion)
     
    @@ -126,4 +126,4 @@

    Trouble Shooting

    - + diff --git a/doc/undirected_dfs.html b/doc/undirected_dfs.html index fe81aced3..5bbda9ded 100644 --- a/doc/undirected_dfs.html +++ b/doc/undirected_dfs.html @@ -1,17 +1,17 @@ Boost Graph Library: Undirected Depth-First Search - -C++ Boost + +C++ Boost
    @@ -90,36 +90,36 @@

     DFS(G)
    -  for each vertex u in V 
    +  for each vertex u in V
         vcolor[u] := WHITE
    -    p[u] := u 
    +    p[u] := u
       end for
    -  for each edge e in E 
    +  for each edge e in E
         ecolor[u] := WHITE
       end for
       time := 0
       if there is a starting vertex s
         call DFS-VISIT(G, s)
    -  for each vertex u in V 
    +  for each vertex u in V
         if vcolor[u] = WHITE
           call DFS-VISIT(G, u)
       end for
       return (p,d_time,f_time) 
    -DFS-VISIT(G, u) +DFS-VISIT(G, u) vcolor[u] := GRAY - d_time[u] := time := time + 1 - for each e in Out[u] + d_time[u] := time := time + 1 + for each e in Out[u] var ec := ecolor[e] ecolor[e] := BLACK if (vcolor[v] = WHITE) - p[v] := u + p[v] := u call DFS-VISIT(G, v) else if (vcolor[v] = GRAY and ec = WHITE) ... ... end for vcolor[u] := BLACK - f_time[u] := time := time + 1 + f_time[u] := time := time + 1
     
     
    @@ -178,7 +178,7 @@ 

    Parameters

    Vertex List Graph, and Edge List Graph.
    - Python: The parameter is named graph. + Python: The parameter is named graph.

    @@ -280,22 +280,22 @@

    Visitor Event Points

  • vis.start_vertex(s, g) is invoked on the source vertex once before the start of the search. - +
  • vis.discover_vertex(u, g) is invoked when a vertex is encountered for the first time. - +
  • vis.examine_edge(e, g) is invoked on every out-edge of each vertex after it is discovered.
  • vis.tree_edge(e, g) is invoked on each edge as it becomes a member of the edges that form the search tree. If you wish to record predecessors, do so at this event point. - +
  • vis.back_edge(e, g) is invoked on the back edges in - the graph. + the graph. -
  • vis.finish_edge(e, g) is invoked on the back edges in - the graph as well as on each tree edge after its target vertex is finished. +
  • vis.finish_edge(e, g) is invoked on the back edges in + the graph as well as on each tree edge after its target vertex is finished.
  • vis.finish_vertex(u, g) is invoked on a vertex after all of its out edges have been added to the search tree and all of @@ -317,7 +317,7 @@

    See Also

    Notes

    -

    [1] +

    [1] Since the visitor parameter is passed by value, if your visitor contains state then any changes to the state during the algorithm will be made to a copy of the visitor object, not the visitor object @@ -339,4 +339,4 @@

    Notes

    - + diff --git a/doc/users.html b/doc/users.html index 5c154f286..7cbdda97d 100644 --- a/doc/users.html +++ b/doc/users.html @@ -1,16 +1,16 @@ Boost Graph Library Users - -C++ Boost + +C++ Boost

    Boost Graph Library Users

    diff --git a/doc/using_adjacency_list.html b/doc/using_adjacency_list.html index 1d3de094a..457721441 100644 --- a/doc/using_adjacency_list.html +++ b/doc/using_adjacency_list.html @@ -1,17 +1,17 @@ Using the Boost Graph Library - -C++ Boost + +C++ Boost
    @@ -134,11 +134,11 @@

    Time Complexity

    vertex() This operation is constant time for vecS and for -listS. +listS. - +

    @@ -163,7 +163,7 @@

    want to represent a multi-graph, or know that you will not be inserting parallel edges into the graph, then choose one of the Sequence -types: vecS, listS, or slistS. +types: vecS, listS, or slistS. You will also want to take into account the differences in time and space complexity for the various graph operations. Below we use V for the total number of vertices in the graph and E for the total @@ -194,7 +194,7 @@

    Time Complexity

    considered a constant.

    - +

    • @@ -312,7 +312,7 @@

      Time Complexity

    - +

    Directed and Undirected Adjacency Lists

    @@ -344,16 +344,16 @@

    adjacency_list class are meant to be filled by these interior properties. -

    NOTE: The Boost Graph Library supports two interchangeable methods for -specifying interior properties: bundled properties -and property lists. The former is easier to use and requires less effort, -whereas the latter is compatible with older, broken compilers and is +

    NOTE: The Boost Graph Library supports two interchangeable methods for +specifying interior properties: bundled properties +and property lists. The former is easier to use and requires less effort, +whereas the latter is compatible with older, broken compilers and is backward-compatible with Boost versions prior to 1.32.0. If you absolutely -require these compatibility features, read on to learn about property lists. +require these compatibility features, read on to learn about property lists. Otherwise, we strongly suggest that you read about the bundled properties mechanism. -

    One may specify internal properties via property lists, which are build from instances of the +

    One may specify internal properties via property lists, which are build from instances of the property class declared as follows.

    @@ -427,11 +427,11 @@

    -  typedef property<vertex_distance_t, float, 
    +  typedef property<vertex_distance_t, float,
                 property<vertex_name_t, std::string> > VertexProperty;
       typedef property<edge_weight_t, float> EdgeProperty;
     
    -  typedef adjacency_list<mapS, vecS, undirectedS, 
    +  typedef adjacency_list<mapS, vecS, undirectedS,
                              VertexProperty, EdgeProperty> Graph;
     
       Graph g(num_vertices); // construct a graph object
    @@ -464,7 +464,7 @@ 

    typedef edge_property_tag kind; }; -struct capacity_t { +struct capacity_t { typedef edge_property_tag kind; };

    @@ -545,28 +545,28 @@

       typedef property<first_name_t, std::string> FirstNameProperty;
    -  typedef adjacency_list<vecS, vecS, directedS, 
    +  typedef adjacency_list<vecS, vecS, directedS,
                              FirstNameProperty> MyGraphType;
     
       typedef pair<int,int> Pair;
    -  Pair edge_array[11] = { Pair(0,1), Pair(0,2), Pair(0,3), 
    -                          Pair(0,4), Pair(2,0), Pair(3,0), 
    -                          Pair(2,4), Pair(3,1), Pair(3,4), 
    +  Pair edge_array[11] = { Pair(0,1), Pair(0,2), Pair(0,3),
    +                          Pair(0,4), Pair(2,0), Pair(3,0),
    +                          Pair(2,4), Pair(3,1), Pair(3,4),
                               Pair(4,0), Pair(4,1) };
    -    
    +
       MyGraphType G(5);
       for (int i = 0; i < 11; ++i)
         add_edge(edge_array[i].first, edge_array[i].second, G);
     
       property_map<MyGraphType, first_name_t>::type
         name = get(first_name_t(), G);
    -    
    +
       boost::put(name, 0, "Jeremy");
       boost::put(name, 1, "Rich");
       boost::put(name, 2, "Andrew");
       boost::put(name, 3, "Jeff");
       name[4] = "Kinis"; // you can use operator[] too
    -    
    +
       who_owes_who(edges(G).first, edges(G).second, G);
     
    @@ -589,7 +589,7 @@

    void who_owes_who(EdgeIter first, EdgeIter last, const Graph& G) { // Access the propety acessor type for this graph - typedef typename property_map<Graph, + typedef typename property_map<Graph, first_name_t>::const_type NameMap; NameMap name = get(first_name, G); @@ -601,7 +601,7 @@

    while (first != last) { src_name = boost::get(name, source(*first, G)); targ_name = boost::get(name, target(*first, G)); - cout << src_name << " owes " + cout << src_name << " owes " << targ_name << " some money" << endl; ++first; } @@ -712,8 +712,8 @@

    }; } - // now you can define a graph using std::list - // and a specific allocator + // now you can define a graph using std::list + // and a specific allocator typedef adjacency_list< list_with_allocatorS< std::allocator<int> >, vecS, directedS> MyGraph; @@ -769,7 +769,7 @@

       template <>
    -  struct parallel_edge_traits<custom_containerS> { 
    +  struct parallel_edge_traits<custom_containerS> {
         typedef allow_parallel_edge_tag type;
       };
     
    @@ -784,4 +784,4 @@

    - + diff --git a/doc/using_property_maps.html b/doc/using_property_maps.html index 661e66e05..80da3e621 100644 --- a/doc/using_property_maps.html +++ b/doc/using_property_maps.html @@ -1,17 +1,17 @@ Boost Graph Library: Using Property Maps - -C++ Boost + +C++ Boost
    @@ -59,10 +59,10 @@

    Property Map Interface

       template <class Edge, class Graph,
    -            class WeightPropertyMap, 
    +            class WeightPropertyMap,
                 class DistancePropertyMap>
    -  bool relax(Edge e, const Graph& g, 
    -             WeightPropertyMap weight, 
    +  bool relax(Edge e, const Graph& g,
    +             WeightPropertyMap weight,
                  DistancePropertyMap distance)
       {
         typedef typename graph_traits<Graph>::vertex_descriptor Vertex;
    @@ -107,14 +107,14 @@ 

    Property Map Interface

    -There are two kinds of graph properties: interior and exterior. +There are two kinds of graph properties: interior and exterior.

    Interior Properties
    are stored ``inside'' the graph object in some way, and the lifetime of the property value objects is the -same as that of the graph object. +same as that of the graph object.

    @@ -174,7 +174,7 @@

    -  dijkstra_shortest_paths(g, src,  
    +  dijkstra_shortest_paths(g, src,
         distance_map(get(vertex_distance, g)).
         weight_map(get(edge_weight, g)).
         color_map(get(vertex_color, g)).
    @@ -240,7 +240,7 @@ 

    -  typedef adjacency_list<vecS, vecS, bidirectionalS, 
    +  typedef adjacency_list<vecS, vecS, bidirectionalS,
         no_property, property<edge_index_t, std::size_t> > Graph;
     
       const int num_vertices = 9;
    @@ -258,8 +258,8 @@ 

    EdgeID_Map edge_id = get(edge_index, G); iterator_property_map - <int*, int, int&, EdgeID_Map> - capacity(capacity_array, edge_id), + <int*, int, int&, EdgeID_Map> + capacity(capacity_array, edge_id), flow(flow_array, edge_id); print_network(G, capacity, flow); @@ -337,7 +337,7 @@

    // An array of vertex name properties std::string names[] = { "San Jose", "San Francisco", "San Jose", - "San Francisco", "Los Angeles", "San Diego", + "San Francisco", "Los Angeles", "San Diego", "Fresno", "Los Vegas", "Reno", "Sacramento", "Salt Lake City", "Pheonix" }; @@ -359,7 +359,7 @@

    cout << endl; // Get the source vertex - boost::graph_traits<Graph>::vertex_descriptor + boost::graph_traits<Graph>::vertex_descriptor s = vertex(SanJose, G); cout << "*** Breadth First ***" << endl; @@ -414,12 +414,12 @@

    class iterator_map { public: - typedef typename boost::property_traits<IDMap>::key_type key_type; + typedef typename boost::property_traits<IDMap>::key_type key_type; typedef typename std::iterator_traits<Iterator>::value_type value_type; typedef boost::lvalue_property_map_tag category; - iterator_map(Iterator i = Iterator(), - const IDMap& id = IDMap()) + iterator_map(Iterator i = Iterator(), + const IDMap& id = IDMap()) : m_iter(i), m_id(id) { } Iterator m_iter; IDMap m_id; @@ -477,4 +477,4 @@

    - + diff --git a/doc/vf2_sub_graph_iso.html b/doc/vf2_sub_graph_iso.html index 41b32e168..66fc766ce 100644 --- a/doc/vf2_sub_graph_iso.html +++ b/doc/vf2_sub_graph_iso.html @@ -1,8 +1,8 @@ Boost Graph Library: Visitor Concepts - -C++ Boost + +C++ Boost
    @@ -60,4 +60,4 @@

    - + diff --git a/doc/wavefront.htm b/doc/wavefront.htm index bfc0928ee..f6a3b651f 100644 --- a/doc/wavefront.htm +++ b/doc/wavefront.htm @@ -10,7 +10,7 @@ --> -C++ Boost

    ith_wavefront

      (1)
    @@ -23,8 +23,8 @@ 

    ith_wavefront


    Defined in

    -boost/graph/wavefront.hpp +boost/graph/wavefront.hpp

    max_wavefront

    @@ -36,8 +36,8 @@

    max_wavefront

    Calculates the maximum wavefront a graph.

    Defined in

    -

    boost/graph/wavefront.hpp +

    boost/graph/wavefront.hpp


    aver_wavefront

    @@ -46,12 +46,12 @@

    aver_wavefront

    (2) template <typename Graph, typename VertexIndexMap>
    typename graph_traits<Graph>::vertices_size_type
    aver_wavefront(const Graph& g, VertexIndexMap index)
    -Calculates the average wavefront of a graph (sum of all wavefronts devided by +Calculates the average wavefront of a graph (sum of all wavefronts devided by the number ob vertices).

    Defined in

    -boost/graph/wavefront.hpp +boost/graph/wavefront.hpp



    @@ -64,15 +64,15 @@

    rms_wavefront

    Calculates the root mean square of all wavefronts.

    Defined in

    -boost/graph/wavefront.hpp +boost/graph/wavefront.hpp

     


    -
    Copyright © 2001-2002Marc Wintermantel, ETH Zurich(wintermantel@imes.mavt.ethz.ch) + Marc Wintermantel, ETH Zurich(wintermantel@imes.mavt.ethz.ch)
    diff --git a/doc/write_dimacs.html b/doc/write_dimacs.html index 9a6e80660..f10af48ac 100644 --- a/doc/write_dimacs.html +++ b/doc/write_dimacs.html @@ -35,10 +35,10 @@ Boost Graph Library: write_dimacs_max_flow - -C++ Boost + +C++ Boost

    @@ -50,7 +50,7 @@

    //outputs a graph with including edge_capacity properties to an std::ostream template < typename Graph, typename CapacityMap, typename IndexMap > void write_dimacs_max_flow(Graph& g, - CapacityMap capacity, + CapacityMap capacity, IndexMap idx, typename graph_traits::vertex_descriptor& src, typename graph_traits::vertex_descriptor& sink, @@ -60,7 +60,7 @@

    This method writes a BGL graph object as an max-flow problem into an output stream in extended dimacs format (see Goldbergs site for more information). -The output can be read in again using the boost/graph/read_dimacs.hpp method. +The output can be read in again using the boost/graph/read_dimacs.hpp method.

    Where Defined

    @@ -72,25 +72,25 @@

    Parameters

    A directed or undirected graph. The graph's type must be a model of VertexListGraph and EdgeListGraph, as num_vertices(Graph) and num_edges(Graph) is used inside. [1] -
    +

  • IN: CapacityMap capacity
    A property map that models Readable Property Map whose key type is the edge descriptor of the graph and whose value type can be written to a stream.
    -
    + IN: IndexMap epw
    A property map that models Readable Property Map whose key type is the vertex descriptor of the graph and whose value type can be written to a stream.
    - + OUT: std::ostream& out
    A standard std::ostream object. -
    +

    -Example +Example

    A short example which uses read_dimacs and write_dimacs is located in the examples directory. @@ -101,4 +101,4 @@

    See Also

    Notes

    [1] As num_edges() and num_vertices() is used inside which returns values for the unfiltered graph (instead of the filtered), this method cannot be used with a filtered_graphSee filtered_graph Note [2] for the reason. - + diff --git a/doc/write_graphml.rst b/doc/write_graphml.rst index 00e68b7d7..ec229ae03 100644 --- a/doc/write_graphml.rst +++ b/doc/write_graphml.rst @@ -3,11 +3,11 @@ ============================ .. Copyright (C) 2006 Tiago de Paula Peixoto - + Distributed under the Boost Software License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) - + Authors: Tiago de Paula Peixoto .. |(logo)| image:: ../../../boost.png @@ -20,7 +20,7 @@ __ ../../../index.htm template void - write_graphml(std::ostream& out, const Graph& g, const dynamic_properties& dp, + write_graphml(std::ostream& out, const Graph& g, const dynamic_properties& dp, bool ordered_vertices=false); template @@ -48,7 +48,7 @@ Parameters OUT: ``std::ostream& out`` A standard ``std::ostream`` object. -IN: ``VertexListGraph& g`` +IN: ``VertexListGraph& g`` A directed or undirected graph. The graph's type must be a model of VertexListGraph_. If the graph doesn't have an internal ``vertex_index`` property map, one @@ -74,7 +74,7 @@ IN: ``bool ordered_vertices`` Example ------- -This example demonstrates using BGL-GraphML interface to write +This example demonstrates using BGL-GraphML interface to write a BGL graph into a GraphML format file. :: diff --git a/example/Jamfile.v2 b/example/Jamfile.v2 index f1bc9d994..42d3bbd5c 100644 --- a/example/Jamfile.v2 +++ b/example/Jamfile.v2 @@ -6,171 +6,182 @@ import ../../config/checks/config : requires ; import modules ; import path ; +import pch ; path-constant TEST_DIR : . ; -run accum-compile-times.cpp : $(TEST_DIR)/makefile-dependencies.dat $(TEST_DIR)/makefile-target-names.dat $(TEST_DIR)/target-compile-costs.dat ; -exe actor_clustering : actor_clustering.cpp ; -run adj_list_ra_edgelist.cpp ; -run adjacency_list.cpp ; -run adjacency_list_io.cpp ; -run adjacency_matrix.cpp ; -run astar-cities.cpp ; -run astar_maze.cpp ; -run bellman-example.cpp ; -run bellman-ford-internet.cpp ; -run bfs.cpp ; -run bfs_neighbor.cpp ; -run bfs-example.cpp ; -run bfs-example2.cpp ; -run bfs-name-printer.cpp ; -run biconnected_components.cpp ; -run bipartite_example.cpp ; -run boost_web_graph.cpp : $(TEST_DIR)/boost_web.dat ; -exe boykov_kolmogorov-eg : boykov_kolmogorov-eg.cpp ; -exe bron_kerbosch_clique_number : bron_kerbosch_clique_number.cpp ; -exe bron_kerbosch_print_cliques : bron_kerbosch_print_cliques.cpp ; -run bucket_sorter.cpp ; -run canonical_ordering.cpp ; -run city_visitor.cpp ; -exe closeness_centrality : closeness_centrality.cpp ; -exe clustering_coefficient : clustering_coefficient.cpp ; -run components_on_edgelist.cpp ; -run connected_components.cpp ; -run connected-components.cpp ; -run container_gen.cpp ; -run copy-example.cpp ; -run csr-example.cpp ; -run cuthill_mckee_ordering.cpp ; -run cycle_canceling_example.cpp ; -run cycle_ratio_example.cpp ; -run cycle-file-dep.cpp : $(TEST_DIR)/makefile-dependencies.dat $(TEST_DIR)/makefile-target-names.dat ; -run cycle-file-dep2.cpp : $(TEST_DIR)/makefile-dependencies.dat $(TEST_DIR)/makefile-target-names.dat ; -run dag_shortest_paths.cpp ; -run dave.cpp ; -run default-constructor.cpp : $(TEST_DIR)/makefile-dependencies.dat ; -run default-constructor2.cpp : $(TEST_DIR)/makefile-dependencies.dat ; -exe degree_centrality : degree_centrality.cpp ; -run dfs.cpp ; -run dfs_parenthesis.cpp ; -run dfs-example.cpp ; -run dijkstra-example.cpp ; -run dijkstra-example-listS.cpp ; -run dijkstra-no-color-map-example.cpp ; -run directed_graph.cpp ; -exe eccentricity : eccentricity.cpp ; -run edge_basics.cpp ; -run edge_coloring.cpp ; -run edge_iterator_constructor.cpp : $(TEST_DIR)/edge_iterator_constructor.dat ; -run edge_property.cpp ; -run edge-function.cpp : $(TEST_DIR)/makefile-dependencies.dat $(TEST_DIR)/makefile-target-names.dat ; -run edge-iter-constructor.cpp : $(TEST_DIR)/makefile-dependencies.dat ; -exe edmonds-karp-eg : edmonds-karp-eg.cpp ; -run exterior_properties.cpp ; -run exterior_property_map.cpp ; -run family_tree.cpp ; -run fibonacci_heap.cpp ; -run file_dependencies.cpp ; -run filtered_graph.cpp ; -run filtered_graph_edge_range.cpp ; -run filtered_vec_as_graph.cpp ; -run filtered-copy-example.cpp ; -exe fr_layout : fr_layout.cpp ; -run gerdemann.cpp ; -run graph.cpp ; -run graph_as_tree.cpp ; -run graph_property.cpp ; -run graph-assoc-types.cpp ; -run graph-property-iter-eg.cpp ; -run graph-thingie.cpp ../build//boost_graph ; -run graphviz.cpp ../build//boost_graph : $(TEST_DIR)/graphviz_example.dot ; -run grid_graph_example.cpp ; -run grid_graph_properties.cpp ; -exe hawick_circuits : hawick_circuits.cpp ; -run implicit_graph.cpp ; -run in_edges.cpp ; -exe inclusive_mean_geodesic : inclusive_mean_geodesic.cpp ; -run incremental_components.cpp ; -run incremental-components-eg.cpp ; -exe influence_prestige : influence_prestige.cpp ; -run interior_pmap_bundled.cpp ; -run interior_property_map.cpp ; -run isomorphism.cpp ; -run iteration_macros.cpp ; -run iterator-property-map-eg.cpp ; -run johnson-eg.cpp ; -run kevin-bacon.cpp : $(TEST_DIR)/kevin-bacon.dat ; -run king_ordering.cpp ; -run knights_tour.cpp ; -run kruskal-example.cpp ; -run kuratowski_subgraph.cpp ; -run make_biconnected_planar.cpp ; -run make_connected.cpp ; -run make_maximal_planar.cpp ; -run matching_example.cpp ; -exe max_flow : max_flow.cpp ; -run mcgregor_subgraphs_example.cpp ; -exe mean_geodesic : mean_geodesic.cpp ; -exe minimum_degree_ordering : minimum_degree_ordering.cpp ; -run modify_graph.cpp ; -run neighbor_bfs.cpp ; -run ospf-example.cpp ../build//boost_graph : $(TEST_DIR)/figs/ospf-graph.dot $(TEST_DIR)/figs/ospf-sptree.dot $(TEST_DIR)/routing-table.dat ; -run parallel-compile-time.cpp : $(TEST_DIR)/makefile-dependencies.dat $(TEST_DIR)/makefile-target-names.dat $(TEST_DIR)/target-compile-costs.dat ; -run planar_face_traversal.cpp ; -run prim-example.cpp ; -run print-adjacent-vertices.cpp : $(TEST_DIR)/makefile-dependencies.dat $(TEST_DIR)/makefile-target-names.dat ; -run print-edges.cpp : $(TEST_DIR)/makefile-dependencies.dat $(TEST_DIR)/makefile-target-names.dat ; -run print-in-edges.cpp : $(TEST_DIR)/makefile-dependencies.dat $(TEST_DIR)/makefile-target-names.dat ; -run print-out-edges.cpp : $(TEST_DIR)/makefile-dependencies.dat $(TEST_DIR)/makefile-target-names.dat ; -exe property_iterator : property_iterator.cpp ; -run property-map-traits-eg.cpp ; -exe push-relable : push-relabel-eg.cpp ; -run put-get-helper-eg.cpp ; -run quick_tour.cpp ; -run quick-tour.cpp ; -run r_c_shortest_paths_example.cpp ; -run read_graphviz.cpp ../build//boost_graph ; -exe read_write_dimacs : read_write_dimacs-eg.cpp ; -run remove_edge_if_bidir.cpp ; -run remove_edge_if_dir.cpp ; -run remove_edge_if_undir.cpp ; -run reverse_graph.cpp ; -exe scaled_closeness_centrality : scaled_closeness_centrality.cpp ; -run simple_planarity_test.cpp ; -run sloan_ordering.cpp ; -run stoer_wagner.cpp ; -run straight_line_drawing.cpp ; -run strong-components.cpp ; -run subgraph.cpp ; -run subgraph_properties.cpp ; -run successive_shortest_path_nonnegative_weights_example.cpp ; -exe tiernan_girth_circumference : tiernan_girth_circumference.cpp ; -exe tiernan_print_cycles : tiernan_print_cycles.cpp ; -run topo_sort.cpp ; -run topo-sort1.cpp ; -run topo-sort2.cpp ; -run topo-sort-file-dep.cpp : $(TEST_DIR)/makefile-dependencies.dat $(TEST_DIR)/makefile-target-names.dat ; -run topo-sort-file-dep2.cpp : $(TEST_DIR)/makefile-dependencies.dat $(TEST_DIR)/makefile-target-names.dat ; -run transitive_closure.cpp ; -run transpose-example.cpp ; -run two_graphs_common_spanning_trees.cpp ; -run undirected_adjacency_list.cpp ; -run undirected_dfs.cpp ; -run undirected_graph.cpp ; -run vector_as_graph.cpp ; -run vertex_basics.cpp ; -run vertex-name-property.cpp : $(TEST_DIR)/makefile-dependencies.dat $(TEST_DIR)/makefile-target-names.dat ; -run vf2_sub_graph_iso_example.cpp ; -run vf2_sub_graph_iso_multi_example.cpp ; -run visitor.cpp ; -run write_graphviz.cpp ; + +local pchs ; + +for local hpp in [ glob-tree *.hpp ] { + cpp-pch $(hpp:B) : $(hpp) : include ; + explicit $(hpp:B) ; + pchs += $(hpp:B) ; +} +alias headers : $(pchs) ; + +run $(headers) accum-compile-times.cpp : $(TEST_DIR)/makefile-dependencies.dat $(TEST_DIR)/makefile-target-names.dat $(TEST_DIR)/target-compile-costs.dat ; +exe $(headers) actor_clustering : actor_clustering.cpp ; +run $(headers) adj_list_ra_edgelist.cpp ; +run $(headers) adjacency_list.cpp ; +run $(headers) adjacency_list_io.cpp ; +run $(headers) adjacency_matrix.cpp ; +run $(headers) astar-cities.cpp ; +run $(headers) astar_maze.cpp ; +run $(headers) bellman-example.cpp ; +run $(headers) bellman-ford-internet.cpp ; +run $(headers) bfs.cpp ; +run $(headers) bfs_neighbor.cpp ; +run $(headers) bfs-example.cpp ; +run $(headers) bfs-example2.cpp ; +run $(headers) bfs-name-printer.cpp ; +run $(headers) biconnected_components.cpp ; +run $(headers) bipartite_example.cpp ; +run $(headers) boost_web_graph.cpp : $(TEST_DIR)/boost_web.dat ; +exe $(headers) boykov_kolmogorov-eg : boykov_kolmogorov-eg.cpp ; +exe $(headers) bron_kerbosch_clique_number : bron_kerbosch_clique_number.cpp ; +exe $(headers) bron_kerbosch_print_cliques : bron_kerbosch_print_cliques.cpp ; +run $(headers) bucket_sorter.cpp ; +run $(headers) canonical_ordering.cpp ; +run $(headers) city_visitor.cpp ; +exe $(headers) closeness_centrality : closeness_centrality.cpp ; +exe $(headers) clustering_coefficient : clustering_coefficient.cpp ; +run $(headers) components_on_edgelist.cpp ; +run $(headers) connected_components.cpp ; +run $(headers) connected-components.cpp ; +run $(headers) container_gen.cpp ; +run $(headers) copy-example.cpp ; +run $(headers) csr-example.cpp ; +run $(headers) cuthill_mckee_ordering.cpp ; +run $(headers) cycle_canceling_example.cpp ; +run $(headers) cycle_ratio_example.cpp ; +run $(headers) cycle-file-dep.cpp : $(TEST_DIR)/makefile-dependencies.dat $(TEST_DIR)/makefile-target-names.dat ; +run $(headers) cycle-file-dep2.cpp : $(TEST_DIR)/makefile-dependencies.dat $(TEST_DIR)/makefile-target-names.dat ; +run $(headers) dag_shortest_paths.cpp ; +run $(headers) dave.cpp ; +run $(headers) default-constructor.cpp : $(TEST_DIR)/makefile-dependencies.dat ; +run $(headers) default-constructor2.cpp : $(TEST_DIR)/makefile-dependencies.dat ; +exe $(headers) degree_centrality : degree_centrality.cpp ; +run $(headers) dfs.cpp ; +run $(headers) dfs_parenthesis.cpp ; +run $(headers) dfs-example.cpp ; +run $(headers) dijkstra-example.cpp ; +run $(headers) dijkstra-example-listS.cpp ; +run $(headers) dijkstra-no-color-map-example.cpp ; +run $(headers) directed_graph.cpp ; +exe $(headers) eccentricity : eccentricity.cpp ; +run $(headers) edge_basics.cpp ; +run $(headers) edge_coloring.cpp ; +run $(headers) edge_iterator_constructor.cpp : $(TEST_DIR)/edge_iterator_constructor.dat ; +run $(headers) edge_property.cpp ; +run $(headers) edge-function.cpp : $(TEST_DIR)/makefile-dependencies.dat $(TEST_DIR)/makefile-target-names.dat ; +run $(headers) edge-iter-constructor.cpp : $(TEST_DIR)/makefile-dependencies.dat ; +exe $(headers) edmonds-karp-eg : edmonds-karp-eg.cpp ; +run $(headers) exterior_properties.cpp ; +run $(headers) exterior_property_map.cpp ; +run $(headers) family_tree.cpp ; +run $(headers) fibonacci_heap.cpp ; +run $(headers) file_dependencies.cpp ; +run $(headers) filtered_graph.cpp ; +run $(headers) filtered_graph_edge_range.cpp ; +run $(headers) filtered_vec_as_graph.cpp ; +run $(headers) filtered-copy-example.cpp ; +exe $(headers) fr_layout : fr_layout.cpp ; +run $(headers) gerdemann.cpp ; +run $(headers) graph.cpp ; +run $(headers) graph_as_tree.cpp ; +run $(headers) graph_property.cpp ; +run $(headers) graph-assoc-types.cpp ; +run $(headers) graph-property-iter-eg.cpp ; +run $(headers) graph-thingie.cpp ../build//boost_graph ; +run $(headers) graphviz.cpp ../build//boost_graph : $(TEST_DIR)/graphviz_example.dot ; +run $(headers) grid_graph_example.cpp ; +run $(headers) grid_graph_properties.cpp ; +exe $(headers) hawick_circuits : hawick_circuits.cpp ; +run $(headers) implicit_graph.cpp ; +run $(headers) in_edges.cpp ; +exe $(headers) inclusive_mean_geodesic : inclusive_mean_geodesic.cpp ; +run $(headers) incremental_components.cpp ; +run $(headers) incremental-components-eg.cpp ; +exe $(headers) influence_prestige : influence_prestige.cpp ; +run $(headers) interior_pmap_bundled.cpp ; +run $(headers) interior_property_map.cpp ; +run $(headers) isomorphism.cpp ; +run $(headers) iteration_macros.cpp ; +run $(headers) iterator-property-map-eg.cpp ; +run $(headers) johnson-eg.cpp ; +run $(headers) kevin-bacon.cpp : $(TEST_DIR)/kevin-bacon.dat ; +run $(headers) king_ordering.cpp ; +run $(headers) knights_tour.cpp ; +run $(headers) kruskal-example.cpp ; +run $(headers) kuratowski_subgraph.cpp ; +run $(headers) make_biconnected_planar.cpp ; +run $(headers) make_connected.cpp ; +run $(headers) make_maximal_planar.cpp ; +run $(headers) matching_example.cpp ; +exe $(headers) max_flow : max_flow.cpp ; +run $(headers) mcgregor_subgraphs_example.cpp ; +exe $(headers) mean_geodesic : mean_geodesic.cpp ; +exe $(headers) minimum_degree_ordering : minimum_degree_ordering.cpp ; +run $(headers) modify_graph.cpp ; +run $(headers) neighbor_bfs.cpp ; +run $(headers) ospf-example.cpp ../build//boost_graph : $(TEST_DIR)/figs/ospf-graph.dot $(TEST_DIR)/figs/ospf-sptree.dot $(TEST_DIR)/routing-table.dat ; +run $(headers) parallel-compile-time.cpp : $(TEST_DIR)/makefile-dependencies.dat $(TEST_DIR)/makefile-target-names.dat $(TEST_DIR)/target-compile-costs.dat ; +run $(headers) planar_face_traversal.cpp ; +run $(headers) prim-example.cpp ; +run $(headers) print-adjacent-vertices.cpp : $(TEST_DIR)/makefile-dependencies.dat $(TEST_DIR)/makefile-target-names.dat ; +run $(headers) print-edges.cpp : $(TEST_DIR)/makefile-dependencies.dat $(TEST_DIR)/makefile-target-names.dat ; +run $(headers) print-in-edges.cpp : $(TEST_DIR)/makefile-dependencies.dat $(TEST_DIR)/makefile-target-names.dat ; +run $(headers) print-out-edges.cpp : $(TEST_DIR)/makefile-dependencies.dat $(TEST_DIR)/makefile-target-names.dat ; +exe $(headers) property_iterator : property_iterator.cpp ; +run $(headers) property-map-traits-eg.cpp ; +exe $(headers) push-relable : push-relabel-eg.cpp ; +run $(headers) put-get-helper-eg.cpp ; +run $(headers) quick_tour.cpp ; +run $(headers) quick-tour.cpp ; +run $(headers) r_c_shortest_paths_example.cpp ; +run $(headers) read_graphviz.cpp ../build//boost_graph ; +exe $(headers) read_write_dimacs : read_write_dimacs-eg.cpp ; +run $(headers) remove_edge_if_bidir.cpp ; +run $(headers) remove_edge_if_dir.cpp ; +run $(headers) remove_edge_if_undir.cpp ; +run $(headers) reverse_graph.cpp ; +exe $(headers) scaled_closeness_centrality : scaled_closeness_centrality.cpp ; +run $(headers) simple_planarity_test.cpp ; +run $(headers) sloan_ordering.cpp ; +run $(headers) stoer_wagner.cpp ; +run $(headers) straight_line_drawing.cpp ; +run $(headers) strong-components.cpp ; +run $(headers) subgraph.cpp ; +run $(headers) subgraph_properties.cpp ; +run $(headers) successive_shortest_path_nonnegative_weights_example.cpp ; +exe $(headers) tiernan_girth_circumference : tiernan_girth_circumference.cpp ; +exe $(headers) tiernan_print_cycles : tiernan_print_cycles.cpp ; +run $(headers) topo_sort.cpp ; +run $(headers) topo-sort1.cpp ; +run $(headers) topo-sort2.cpp ; +run $(headers) topo-sort-file-dep.cpp : $(TEST_DIR)/makefile-dependencies.dat $(TEST_DIR)/makefile-target-names.dat ; +run $(headers) topo-sort-file-dep2.cpp : $(TEST_DIR)/makefile-dependencies.dat $(TEST_DIR)/makefile-target-names.dat ; +run $(headers) transitive_closure.cpp ; +run $(headers) transpose-example.cpp ; +run $(headers) two_graphs_common_spanning_trees.cpp ; +run $(headers) undirected_adjacency_list.cpp ; +run $(headers) undirected_dfs.cpp ; +run $(headers) undirected_graph.cpp ; +run $(headers) vector_as_graph.cpp ; +run $(headers) vertex_basics.cpp ; +run $(headers) vertex-name-property.cpp : $(TEST_DIR)/makefile-dependencies.dat $(TEST_DIR)/makefile-target-names.dat ; +run $(headers) vf2_sub_graph_iso_example.cpp ; +run $(headers) vf2_sub_graph_iso_multi_example.cpp ; +run $(headers) visitor.cpp ; +run $(headers) write_graphviz.cpp ; # # These require LEDA: # -run leda-graph-eg.cpp ; -run leda-concept-check.cpp ; -run topo-sort-with-leda.cpp ; +run $(headers) leda-graph-eg.cpp ; +run $(headers) leda-concept-check.cpp ; +run $(headers) topo-sort-with-leda.cpp ; explicit leda-graph-eg ; explicit leda-concept-check ; explicit topo-sort-with-leda ; @@ -178,13 +189,13 @@ explicit topo-sort-with-leda ; # # These require standford-graph: # -run miles_span.cpp ; +run $(headers) miles_span.cpp ; explicit miles_span ; -run roget_components.cpp ; +run $(headers) roget_components.cpp ; explicit roget_components ; -run topo-sort-with-sgb.cpp ; +run $(headers) topo-sort-with-sgb.cpp ; explicit topo-sort-with-sgb ; -run girth.cpp ; +run $(headers) girth.cpp ; explicit girth ; # diff --git a/example/accum-compile-times.cpp b/example/accum-compile-times.cpp index d4db2cf4f..cc0d48fd8 100644 --- a/example/accum-compile-times.cpp +++ b/example/accum-compile-times.cpp @@ -1,5 +1,5 @@ //======================================================================= -// Copyright 2001 Jeremy G. Siek, Andrew Lumsdaine, Lie-Quan Lee, +// Copyright 2001 Jeremy G. Siek, Andrew Lumsdaine, Lie-Quan Lee, // // Distributed under the Boost Software License, Version 1.0. (See // accompanying file LICENSE_1_0.txt or copy at @@ -16,80 +16,85 @@ namespace std { - template < typename T > - std::istream& operator >> (std::istream& in, std::pair < T, T > &p) - { +template < typename T > +std::istream& operator>>(std::istream& in, std::pair< T, T >& p) +{ in >> p.first >> p.second; return in; - } +} } namespace boost { - enum vertex_compile_cost_t { vertex_compile_cost }; - BOOST_INSTALL_PROPERTY(vertex, compile_cost); +enum vertex_compile_cost_t +{ + vertex_compile_cost +}; +BOOST_INSTALL_PROPERTY(vertex, compile_cost); } using namespace boost; typedef adjacency_list< listS, // Store out-edges of each vertex in a std::list - listS, // Store vertex set in a std::list - directedS, // The file dependency graph is directed - // vertex properties - property < vertex_name_t, std::string, - property < vertex_compile_cost_t, float, - property < vertex_distance_t, float, - property < vertex_color_t, default_color_type > > > >, - // an edge property - property < edge_weight_t, float > > - file_dep_graph2; + listS, // Store vertex set in a std::list + directedS, // The file dependency graph is directed + // vertex properties + property< vertex_name_t, std::string, + property< vertex_compile_cost_t, float, + property< vertex_distance_t, float, + property< vertex_color_t, default_color_type > > > >, + // an edge property + property< edge_weight_t, float > > + file_dep_graph2; -typedef graph_traits::vertex_descriptor vertex_t; -typedef graph_traits::edge_descriptor edge_t; +typedef graph_traits< file_dep_graph2 >::vertex_descriptor vertex_t; +typedef graph_traits< file_dep_graph2 >::edge_descriptor edge_t; -int -main(int argc, const char** argv) +int main(int argc, const char** argv) { - std::ifstream file_in(argc >= 2 ? argv[1] : "makefile-dependencies.dat"); - typedef graph_traits::vertices_size_type size_type; - size_type n_vertices; - file_in >> n_vertices; // read in number of vertices + std::ifstream file_in(argc >= 2 ? argv[1] : "makefile-dependencies.dat"); + typedef graph_traits< file_dep_graph2 >::vertices_size_type size_type; + size_type n_vertices; + file_in >> n_vertices; // read in number of vertices #if defined(BOOST_MSVC) && BOOST_MSVC <= 1300 - // std::istream_iterator causes trouble with VC++ - std::vector id2vertex; - file_dep_graph2 g; - for (std::size_t i = 0; i < n_vertices; ++i) - id2vertex.push_back(add_vertex(g)); - std::pair p; - while (file_in >> p) - add_edge(id2vertex[p.first], id2vertex[p.second], g); + // std::istream_iterator causes trouble with VC++ + std::vector< vertex_t > id2vertex; + file_dep_graph2 g; + for (std::size_t i = 0; i < n_vertices; ++i) + id2vertex.push_back(add_vertex(g)); + std::pair< size_type, size_type > p; + while (file_in >> p) + add_edge(id2vertex[p.first], id2vertex[p.second], g); #else - std::istream_iterator > - input_begin(file_in), input_end; - file_dep_graph2 g(input_begin, input_end, n_vertices); + std::istream_iterator< std::pair< size_type, size_type > > input_begin( + file_in), + input_end; + file_dep_graph2 g(input_begin, input_end, n_vertices); #endif - typedef property_map < file_dep_graph2, vertex_name_t >::type name_map_t; - typedef property_map < file_dep_graph2, vertex_compile_cost_t >::type - compile_cost_map_t; + typedef property_map< file_dep_graph2, vertex_name_t >::type name_map_t; + typedef property_map< file_dep_graph2, vertex_compile_cost_t >::type + compile_cost_map_t; - name_map_t name_map = get(vertex_name, g); - compile_cost_map_t compile_cost_map = get(vertex_compile_cost, g); + name_map_t name_map = get(vertex_name, g); + compile_cost_map_t compile_cost_map = get(vertex_compile_cost, g); - std::ifstream name_in(argc >= 3 ? argv[2] : "makefile-target-names.dat"); - std::ifstream compile_cost_in(argc >= 4 ? argv[3] : "target-compile-costs.dat"); - graph_traits < file_dep_graph2 >::vertex_iterator vi, vi_end; - for (boost::tie(vi, vi_end) = vertices(g); vi != vi_end; ++vi) { - name_in >> name_map[*vi]; - compile_cost_in >> compile_cost_map[*vi]; - } + std::ifstream name_in(argc >= 3 ? argv[2] : "makefile-target-names.dat"); + std::ifstream compile_cost_in( + argc >= 4 ? argv[3] : "target-compile-costs.dat"); + graph_traits< file_dep_graph2 >::vertex_iterator vi, vi_end; + for (boost::tie(vi, vi_end) = vertices(g); vi != vi_end; ++vi) + { + name_in >> name_map[*vi]; + compile_cost_in >> compile_cost_map[*vi]; + } - graph_property_iter_range < file_dep_graph2, - vertex_compile_cost_t >::iterator ci, ci_end; - boost::tie(ci, ci_end) = get_property_iter_range(g, vertex_compile_cost); - std::cout << "total (sequential) compile time: " - << std::accumulate(ci, ci_end, 0.0) << std::endl; + graph_property_iter_range< file_dep_graph2, + vertex_compile_cost_t >::iterator ci, + ci_end; + boost::tie(ci, ci_end) = get_property_iter_range(g, vertex_compile_cost); + std::cout << "total (sequential) compile time: " + << std::accumulate(ci, ci_end, 0.0) << std::endl; - return 0; + return 0; } - diff --git a/example/actor_clustering.cpp b/example/actor_clustering.cpp index 9b1b40221..5564a9e9c 100644 --- a/example/actor_clustering.cpp +++ b/example/actor_clustering.cpp @@ -29,159 +29,191 @@ using namespace boost; struct Actor { - Actor(int id = -1) : id(id) {} + Actor(int id = -1) : id(id) {} - int id; + int id; }; -typedef adjacency_list > ActorGraph; -typedef graph_traits::vertex_descriptor Vertex; -typedef graph_traits::edge_descriptor Edge; +typedef adjacency_list< vecS, vecS, undirectedS, Actor, + property< edge_centrality_t, double > > + ActorGraph; +typedef graph_traits< ActorGraph >::vertex_descriptor Vertex; +typedef graph_traits< ActorGraph >::edge_descriptor Edge; void load_actor_graph(std::istream& in, ActorGraph& g) { - std::map actors; - - std::string line; - while (getline(in, line)) { - std::vector actors_in_movie; - - // Map from the actor numbers on this line to the actor vertices - typedef tokenizer > Tok; - Tok tok(line, char_separator(" ")); - for (Tok::iterator id = tok.begin(); id != tok.end(); ++id) { - int actor_id = lexical_cast(*id); - std::map::iterator v = actors.find(actor_id); - if (v == actors.end()) { - Vertex new_vertex = add_vertex(Actor(actor_id), g); - actors[actor_id] = new_vertex; - actors_in_movie.push_back(new_vertex); - } else { - actors_in_movie.push_back(v->second); - } + std::map< int, Vertex > actors; + + std::string line; + while (getline(in, line)) + { + std::vector< Vertex > actors_in_movie; + + // Map from the actor numbers on this line to the actor vertices + typedef tokenizer< char_separator< char > > Tok; + Tok tok(line, char_separator< char >(" ")); + for (Tok::iterator id = tok.begin(); id != tok.end(); ++id) + { + int actor_id = lexical_cast< int >(*id); + std::map< int, Vertex >::iterator v = actors.find(actor_id); + if (v == actors.end()) + { + Vertex new_vertex = add_vertex(Actor(actor_id), g); + actors[actor_id] = new_vertex; + actors_in_movie.push_back(new_vertex); + } + else + { + actors_in_movie.push_back(v->second); + } + } + + for (std::vector< Vertex >::iterator i = actors_in_movie.begin(); + i != actors_in_movie.end(); ++i) + { + for (std::vector< Vertex >::iterator j = i + 1; + j != actors_in_movie.end(); ++j) + { + if (!edge(*i, *j, g).second) + add_edge(*i, *j, g); + } + } } - - for (std::vector::iterator i = actors_in_movie.begin(); - i != actors_in_movie.end(); ++i) { - for (std::vector::iterator j = i + 1; - j != actors_in_movie.end(); ++j) { - if (!edge(*i, *j, g).second) add_edge(*i, *j, g); - } - } - } } -template -std::ostream& -write_pajek_graph(std::ostream& out, const Graph& g, - VertexIndexMap vertex_index, VertexNameMap vertex_name) +template < typename Graph, typename VertexIndexMap, typename VertexNameMap > +std::ostream& write_pajek_graph(std::ostream& out, const Graph& g, + VertexIndexMap vertex_index, VertexNameMap vertex_name) { - out << "*Vertices " << num_vertices(g) << '\n'; - typedef typename graph_traits::vertex_iterator vertex_iterator; - for (vertex_iterator v = vertices(g).first; v != vertices(g).second; ++v) { - out << get(vertex_index, *v)+1 << " \"" << get(vertex_name, *v) << "\"\n"; - } - - out << "*Edges\n"; - typedef typename graph_traits::edge_iterator edge_iterator; - for (edge_iterator e = edges(g).first; e != edges(g).second; ++e) { - out << get(vertex_index, source(*e, g))+1 << ' ' - << get(vertex_index, target(*e, g))+1 << " 1.0\n"; // HACK! - } - return out; + out << "*Vertices " << num_vertices(g) << '\n'; + typedef typename graph_traits< Graph >::vertex_iterator vertex_iterator; + for (vertex_iterator v = vertices(g).first; v != vertices(g).second; ++v) + { + out << get(vertex_index, *v) + 1 << " \"" << get(vertex_name, *v) + << "\"\n"; + } + + out << "*Edges\n"; + typedef typename graph_traits< Graph >::edge_iterator edge_iterator; + for (edge_iterator e = edges(g).first; e != edges(g).second; ++e) + { + out << get(vertex_index, source(*e, g)) + 1 << ' ' + << get(vertex_index, target(*e, g)) + 1 << " 1.0\n"; // HACK! + } + return out; } -class actor_clustering_threshold : public bc_clustering_threshold +class actor_clustering_threshold : public bc_clustering_threshold< double > { - typedef bc_clustering_threshold inherited; - - public: - actor_clustering_threshold(double threshold, const ActorGraph& g, - bool normalize) - : inherited(threshold, g, normalize), iter(1) { } - - bool operator()(double max_centrality, Edge e, const ActorGraph& g) - { - std::cout << "Iter: " << iter << " Max Centrality: " - << (max_centrality / dividend) << std::endl; - ++iter; - return inherited::operator()(max_centrality, e, g); - } - - private: - unsigned int iter; + typedef bc_clustering_threshold< double > inherited; + +public: + actor_clustering_threshold( + double threshold, const ActorGraph& g, bool normalize) + : inherited(threshold, g, normalize), iter(1) + { + } + + bool operator()(double max_centrality, Edge e, const ActorGraph& g) + { + std::cout << "Iter: " << iter + << " Max Centrality: " << (max_centrality / dividend) + << std::endl; + ++iter; + return inherited::operator()(max_centrality, e, g); + } + +private: + unsigned int iter; }; int main(int argc, char* argv[]) { - std::string in_file; - std::string out_file; - double threshold = -1.0; - bool normalize = false; - - // Parse command-line options - { - int on_arg = 1; - while (on_arg < argc) { - std::string arg(argv[on_arg]); - if (arg == "-in") { - ++on_arg; assert(on_arg < argc); - in_file = argv[on_arg]; - } else if (arg == "-out") { - ++on_arg; assert(on_arg < argc); - out_file = argv[on_arg]; - } else if (arg == "-threshold") { - ++on_arg; assert(on_arg < argc); - threshold = lexical_cast(argv[on_arg]); - } else if (arg == "-normalize") { - normalize = true; - } else { - std::cerr << "Unrecognized parameter \"" << arg << "\".\n"; - return -1; - } - ++on_arg; + std::string in_file; + std::string out_file; + double threshold = -1.0; + bool normalize = false; + + // Parse command-line options + { + int on_arg = 1; + while (on_arg < argc) + { + std::string arg(argv[on_arg]); + if (arg == "-in") + { + ++on_arg; + assert(on_arg < argc); + in_file = argv[on_arg]; + } + else if (arg == "-out") + { + ++on_arg; + assert(on_arg < argc); + out_file = argv[on_arg]; + } + else if (arg == "-threshold") + { + ++on_arg; + assert(on_arg < argc); + threshold = lexical_cast< double >(argv[on_arg]); + } + else if (arg == "-normalize") + { + normalize = true; + } + else + { + std::cerr << "Unrecognized parameter \"" << arg << "\".\n"; + return -1; + } + ++on_arg; + } + + if (in_file.empty() || out_file.empty() || threshold < 0) + { + std::cerr << "error: syntax is actor_clustering [options]\n\n" + << "options are:\n" + << "\t-in \tInput file\n" + << "\t-out \tOutput file\n" + << "\t-threshold \tA threshold value\n" + << "\t-normalize\tNormalize edge centrality scores\n"; + return -1; + } } - if (in_file.empty() || out_file.empty() || threshold < 0) { - std::cerr << "error: syntax is actor_clustering [options]\n\n" - << "options are:\n" - << "\t-in \tInput file\n" - << "\t-out \tOutput file\n" - << "\t-threshold \tA threshold value\n" - << "\t-normalize\tNormalize edge centrality scores\n"; - return -1; + ActorGraph g; + + // Load the actor graph + { + std::cout << "Building graph." << std::endl; + std::ifstream in(in_file.c_str()); + if (!in) + { + std::cerr << "Unable to open file \"" << in_file + << "\" for input.\n"; + return -2; + } + load_actor_graph(in, g); } - } - - ActorGraph g; - // Load the actor graph - { - std::cout << "Building graph." << std::endl; - std::ifstream in(in_file.c_str()); - if (!in) { - std::cerr << "Unable to open file \"" << in_file << "\" for input.\n"; - return -2; - } - load_actor_graph(in, g); - } - - // Run the algorithm - std::cout << "Clusting..." << std::endl; - betweenness_centrality_clustering(g, - actor_clustering_threshold(threshold, g, normalize), - get(edge_centrality, g)); - - // Output the graph - { - std::cout << "Writing graph to file: " << out_file << std::endl; - std::ofstream out(out_file.c_str()); - if (!out) { - std::cerr << "Unable to open file \"" << out_file << "\" for output.\n"; - return -3; + // Run the algorithm + std::cout << "Clusting..." << std::endl; + betweenness_centrality_clustering(g, + actor_clustering_threshold(threshold, g, normalize), + get(edge_centrality, g)); + + // Output the graph + { + std::cout << "Writing graph to file: " << out_file << std::endl; + std::ofstream out(out_file.c_str()); + if (!out) + { + std::cerr << "Unable to open file \"" << out_file + << "\" for output.\n"; + return -3; + } + write_pajek_graph(out, g, get(vertex_index, g), get(&Actor::id, g)); } - write_pajek_graph(out, g, get(vertex_index, g), get(&Actor::id, g)); - } - return 0; + return 0; } diff --git a/example/adj_list_ra_edgelist.cpp b/example/adj_list_ra_edgelist.cpp index d92ecd66e..d6380efae 100644 --- a/example/adj_list_ra_edgelist.cpp +++ b/example/adj_list_ra_edgelist.cpp @@ -11,25 +11,26 @@ #include #include -int -main() +int main() { - using namespace boost; - typedef adjacency_list, no_property, vecS> Graph; + using namespace boost; + typedef adjacency_list< vecS, vecS, bidirectionalS, no_property, + property< int, edge_weight_t >, no_property, vecS > + Graph; - const std::size_t n = 3; - typedef std::pair E; - E edge_array[] = { E(0,1), E(0,2), E(0,1) }; - const std::size_t m = sizeof(edge_array) / sizeof(E); - Graph g(edge_array, edge_array + m, n); + const std::size_t n = 3; + typedef std::pair< std::size_t, std::size_t > E; + E edge_array[] = { E(0, 1), E(0, 2), E(0, 1) }; + const std::size_t m = sizeof(edge_array) / sizeof(E); + Graph g(edge_array, edge_array + m, n); - graph_traits::edge_iterator edge_iterator; - for (std::size_t i = 0; i < m; ++i) { - const graph_traits::edge_iterator e = edges(g).first + i; - std::cout << *e << " "; - } - std::cout << std::endl; - - return 0; + graph_traits< Graph >::edge_iterator edge_iterator; + for (std::size_t i = 0; i < m; ++i) + { + const graph_traits< Graph >::edge_iterator e = edges(g).first + i; + std::cout << *e << " "; + } + std::cout << std::endl; + + return 0; } diff --git a/example/adjacency_list.cpp b/example/adjacency_list.cpp index 6d8053792..916a98c02 100644 --- a/example/adjacency_list.cpp +++ b/example/adjacency_list.cpp @@ -20,88 +20,92 @@ Sample Output graph name: foo - 0 --joe--> 1 - 1 --joe--> 0 --curly--> 2 --dick--> 3 - 2 --curly--> 1 --tom--> 4 - 3 --dick--> 1 --harry--> 4 - 4 --tom--> 2 --harry--> 3 - (0,1) (1,2) (1,3) (2,4) (3,4) - - removing edge (1,3): - 0 --joe--> 1 - 1 --joe--> 0 --curly--> 2 - 2 --curly--> 1 --tom--> 4 - 3 --harry--> 4 - 4 --tom--> 2 --harry--> 3 - (0,1) (1,2) (2,4) (3,4) + 0 --joe--> 1 + 1 --joe--> 0 --curly--> 2 --dick--> 3 + 2 --curly--> 1 --tom--> 4 + 3 --dick--> 1 --harry--> 4 + 4 --tom--> 2 --harry--> 3 + (0,1) (1,2) (1,3) (2,4) (3,4) + + removing edge (1,3): + 0 --joe--> 1 + 1 --joe--> 0 --curly--> 2 + 2 --curly--> 1 --tom--> 4 + 3 --harry--> 4 + 4 --tom--> 2 --harry--> 3 + (0,1) (1,2) (2,4) (3,4) */ -struct EdgeProperties { - EdgeProperties(const std::string& n) : name(n) { } - std::string name; +struct EdgeProperties +{ + EdgeProperties(const std::string& n) : name(n) {} + std::string name; }; -struct VertexProperties { - std::size_t index; - boost::default_color_type color; +struct VertexProperties +{ + std::size_t index; + boost::default_color_type color; }; - -int main(int , char* []) +int main(int, char*[]) { - using namespace boost; - using namespace std; - - typedef adjacency_list Graph; - - const int V = 5; - Graph g(V); - - property_map::type - id = get(&VertexProperties::index, g); - property_map::type - name = get(&EdgeProperties::name, g); - - boost::graph_traits::vertex_iterator vi, viend; - int vnum = 0; - - for (boost::tie(vi,viend) = vertices(g); vi != viend; ++vi) - id[*vi] = vnum++; - - add_edge(vertex(0, g), vertex(1, g), EdgeProperties("joe"), g); - add_edge(vertex(1, g), vertex(2, g), EdgeProperties("curly"), g); - add_edge(vertex(1, g), vertex(3, g), EdgeProperties("dick"), g); - add_edge(vertex(2, g), vertex(4, g), EdgeProperties("tom"), g); - add_edge(vertex(3, g), vertex(4, g), EdgeProperties("harry"), g); - - graph_traits::vertex_iterator i, end; - graph_traits::out_edge_iterator ei, edge_end; - for (boost::tie(i,end) = vertices(g); i != end; ++i) { - cout << id[*i] << " "; - for (boost::tie(ei,edge_end) = out_edges(*i, g); ei != edge_end; ++ei) - cout << " --" << name[*ei] << "--> " << id[target(*ei, g)] << " "; - cout << endl; - } - print_edges(g, id); - - cout << endl << "removing edge (1,3): " << endl; - remove_edge(vertex(1, g), vertex(3, g), g); - - ei = out_edges(vertex(1, g), g).first; - cout << "removing edge (" << id[source(*ei, g)] - << "," << id[target(*ei, g)] << ")" << endl; - remove_edge(ei, g); - - for(boost::tie(i,end) = vertices(g); i != end; ++i) { - cout << id[*i] << " "; - for (boost::tie(ei,edge_end) = out_edges(*i, g); ei != edge_end; ++ei) - cout << " --" << name[*ei] << "--> " << id[target(*ei, g)] << " "; - cout << endl; - } - - print_edges(g, id); - - return 0; + using namespace boost; + using namespace std; + + typedef adjacency_list< vecS, listS, undirectedS, VertexProperties, + EdgeProperties > + Graph; + + const int V = 5; + Graph g(V); + + property_map< Graph, std::size_t VertexProperties::* >::type id + = get(&VertexProperties::index, g); + property_map< Graph, std::string EdgeProperties::* >::type name + = get(&EdgeProperties::name, g); + + boost::graph_traits< Graph >::vertex_iterator vi, viend; + int vnum = 0; + + for (boost::tie(vi, viend) = vertices(g); vi != viend; ++vi) + id[*vi] = vnum++; + + add_edge(vertex(0, g), vertex(1, g), EdgeProperties("joe"), g); + add_edge(vertex(1, g), vertex(2, g), EdgeProperties("curly"), g); + add_edge(vertex(1, g), vertex(3, g), EdgeProperties("dick"), g); + add_edge(vertex(2, g), vertex(4, g), EdgeProperties("tom"), g); + add_edge(vertex(3, g), vertex(4, g), EdgeProperties("harry"), g); + + graph_traits< Graph >::vertex_iterator i, end; + graph_traits< Graph >::out_edge_iterator ei, edge_end; + for (boost::tie(i, end) = vertices(g); i != end; ++i) + { + cout << id[*i] << " "; + for (boost::tie(ei, edge_end) = out_edges(*i, g); ei != edge_end; ++ei) + cout << " --" << name[*ei] << "--> " << id[target(*ei, g)] << " "; + cout << endl; + } + print_edges(g, id); + + cout << endl << "removing edge (1,3): " << endl; + remove_edge(vertex(1, g), vertex(3, g), g); + + ei = out_edges(vertex(1, g), g).first; + cout << "removing edge (" << id[source(*ei, g)] << "," << id[target(*ei, g)] + << ")" << endl; + remove_edge(ei, g); + + for (boost::tie(i, end) = vertices(g); i != end; ++i) + { + cout << id[*i] << " "; + for (boost::tie(ei, edge_end) = out_edges(*i, g); ei != edge_end; ++ei) + cout << " --" << name[*ei] << "--> " << id[target(*ei, g)] << " "; + cout << endl; + } + + print_edges(g, id); + + return 0; } diff --git a/example/adjacency_list.expected b/example/adjacency_list.expected index f85d7549f..8fbdaeaa0 100644 --- a/example/adjacency_list.expected +++ b/example/adjacency_list.expected @@ -1,15 +1,15 @@ -0 --joe--> 1 -1 --joe--> 0 --curly--> 2 --dick--> 3 -2 --curly--> 1 --tom--> 4 -3 --dick--> 1 --harry--> 4 -4 --tom--> 2 --harry--> 3 -(0,1) (1,2) (1,3) (2,4) (3,4) +0 --joe--> 1 +1 --joe--> 0 --curly--> 2 --dick--> 3 +2 --curly--> 1 --tom--> 4 +3 --dick--> 1 --harry--> 4 +4 --tom--> 2 --harry--> 3 +(0,1) (1,2) (1,3) (2,4) (3,4) -removing edge (1,3): +removing edge (1,3): removing edge (1,0) -0 -1 --curly--> 2 -2 --curly--> 1 --tom--> 4 -3 --harry--> 4 -4 --tom--> 2 --harry--> 3 -(1,2) (2,4) (3,4) +0 +1 --curly--> 2 +2 --curly--> 1 --tom--> 4 +3 --harry--> 4 +4 --tom--> 2 --harry--> 3 +(1,2) (2,4) (3,4) diff --git a/example/adjacency_list_io.cpp b/example/adjacency_list_io.cpp index ab626f89c..bfc0280c5 100644 --- a/example/adjacency_list_io.cpp +++ b/example/adjacency_list_io.cpp @@ -15,83 +15,99 @@ using namespace boost; //======== my data structure -struct MyStruct { double value; }; -std::ostream& operator << ( std::ostream& out, const MyStruct& s ) +struct MyStruct { - out << s.value << " "; - return out; + double value; +}; +std::ostream& operator<<(std::ostream& out, const MyStruct& s) +{ + out << s.value << " "; + return out; } -std::istream& operator >> ( std::istream& in, MyStruct& s ) +std::istream& operator>>(std::istream& in, MyStruct& s) { - in >> s.value; - return in; + in >> s.value; + return in; } //======== vertex properties -struct n1_t { enum { num = 23063}; typedef vertex_property_tag kind; }; -struct n2_t { enum { num = 23062}; typedef vertex_property_tag kind; }; -struct n3_t { enum { num = 23061}; typedef vertex_property_tag kind; }; +struct n1_t +{ + enum + { + num = 23063 + }; + typedef vertex_property_tag kind; +}; +struct n2_t +{ + enum + { + num = 23062 + }; + typedef vertex_property_tag kind; +}; +struct n3_t +{ + enum + { + num = 23061 + }; + typedef vertex_property_tag kind; +}; typedef property< n1_t, int, - property< n2_t, double, - property< n3_t, MyStruct > > > VertexProperty; - + property< n2_t, double, property< n3_t, MyStruct > > > + VertexProperty; //====== edge properties -struct e1_t { enum { num = 23064}; typedef edge_property_tag kind; }; -typedef property EdgeProperty; - - +struct e1_t +{ + enum + { + num = 23064 + }; + typedef edge_property_tag kind; +}; +typedef property< e1_t, double > EdgeProperty; //===== graph types -typedef - adjacency_list - Graph1; - -typedef - adjacency_list - Graph2; +typedef adjacency_list< vecS, listS, directedS, no_property, no_property > + Graph1; +typedef adjacency_list< setS, setS, bidirectionalS, VertexProperty, + EdgeProperty > + Graph2; - -int -main() +int main() { - // read Graph1 - Graph1 g1; - std::ifstream readFile1("data1.txt"); - readFile1 >> read( g1 ); - std::cout << "graph g1 from file data1.txt:\n" - << write( g1 ) - << std::endl; - - // read Graph2 and all internal properties - Graph2 g2; - std::ifstream readFile2("data2.txt"); - readFile2 >> read( g2 ); - std::cout << "graph g2 from file data2.txt:\n" - << write( g2 ) - << std::endl; - - // read Graph2, no property given. Write no property. - Graph2 g21; - std::ifstream readFile21("data1.txt"); - readFile21 >> read( g21, no_property(), no_property() ); - std::cout << "graph g21 from file data1.txt:\n" - << write(g21, no_property(), no_property()) - << std::endl; - - // read Graph2, incomplete data in a different order. Write it diffently. - Graph2 g31; - std::ifstream readFile31("data3.txt"); - typedef property< n3_t, MyStruct, property< n1_t, int > > readNodeProp; - readFile31 >> read( g31, readNodeProp() , EdgeProperty() ); - std::cout << "graph g31 from file data3.txt:\n" - << write( g31, property(), EdgeProperty() ) - << std::endl; - - - return 0; + // read Graph1 + Graph1 g1; + std::ifstream readFile1("data1.txt"); + readFile1 >> read(g1); + std::cout << "graph g1 from file data1.txt:\n" << write(g1) << std::endl; + + // read Graph2 and all internal properties + Graph2 g2; + std::ifstream readFile2("data2.txt"); + readFile2 >> read(g2); + std::cout << "graph g2 from file data2.txt:\n" << write(g2) << std::endl; + + // read Graph2, no property given. Write no property. + Graph2 g21; + std::ifstream readFile21("data1.txt"); + readFile21 >> read(g21, no_property(), no_property()); + std::cout << "graph g21 from file data1.txt:\n" + << write(g21, no_property(), no_property()) << std::endl; + + // read Graph2, incomplete data in a different order. Write it diffently. + Graph2 g31; + std::ifstream readFile31("data3.txt"); + typedef property< n3_t, MyStruct, property< n1_t, int > > readNodeProp; + readFile31 >> read(g31, readNodeProp(), EdgeProperty()); + std::cout << "graph g31 from file data3.txt:\n" + << write(g31, property< n3_t, MyStruct >(), EdgeProperty()) + << std::endl; + + return 0; } - - diff --git a/example/adjacency_matrix.cpp b/example/adjacency_matrix.cpp index accbfca1e..4f36ead98 100644 --- a/example/adjacency_matrix.cpp +++ b/example/adjacency_matrix.cpp @@ -11,57 +11,65 @@ #include #include - int main() { - using namespace boost; - enum { A, B, C, D, E, F, N }; - const char* name = "ABCDEF"; + using namespace boost; + enum + { + A, + B, + C, + D, + E, + F, + N + }; + const char* name = "ABCDEF"; + + // A directed graph - // A directed graph - - typedef adjacency_matrix Graph; - Graph g(N); - add_edge(B, C, g); - add_edge(B, F, g); - add_edge(C, A, g); - add_edge(C, C, g); - add_edge(D, E, g); - add_edge(E, D, g); - add_edge(F, A, g); + typedef adjacency_matrix< directedS > Graph; + Graph g(N); + add_edge(B, C, g); + add_edge(B, F, g); + add_edge(C, A, g); + add_edge(C, C, g); + add_edge(D, E, g); + add_edge(E, D, g); + add_edge(F, A, g); - std::cout << "vertex set: "; - print_vertices(g, name); - std::cout << std::endl; + std::cout << "vertex set: "; + print_vertices(g, name); + std::cout << std::endl; - std::cout << "edge set: "; - print_edges(g, name); - std::cout << std::endl; + std::cout << "edge set: "; + print_edges(g, name); + std::cout << std::endl; - std::cout << "out-edges: " << std::endl; - print_graph(g, name); - std::cout << std::endl; + std::cout << "out-edges: " << std::endl; + print_graph(g, name); + std::cout << std::endl; - // An undirected graph + // An undirected graph - typedef adjacency_matrix UGraph; - UGraph ug(N); - add_edge(B, C, ug); - add_edge(B, F, ug); - add_edge(C, A, ug); - add_edge(D, E, ug); - add_edge(F, A, ug); + typedef adjacency_matrix< undirectedS > UGraph; + UGraph ug(N); + add_edge(B, C, ug); + add_edge(B, F, ug); + add_edge(C, A, ug); + add_edge(D, E, ug); + add_edge(F, A, ug); - std::cout << "vertex set: "; - print_vertices(ug, name); - std::cout << std::endl; + std::cout << "vertex set: "; + print_vertices(ug, name); + std::cout << std::endl; - std::cout << "edge set: "; - print_edges(ug, name); - std::cout << std::endl; + std::cout << "edge set: "; + print_edges(ug, name); + std::cout << std::endl; - std::cout << "incident edges: " << std::endl; - print_graph(ug, name); - std::cout << std::endl; - return 0; + std::cout << "incident edges: " << std::endl; + print_graph(ug, name); + std::cout << std::endl; + return 0; } diff --git a/example/astar-cities.cpp b/example/astar-cities.cpp index bca644667..3437e6abd 100644 --- a/example/astar-cities.cpp +++ b/example/astar-cities.cpp @@ -10,7 +10,6 @@ //======================================================================= // - #include #include #include @@ -21,204 +20,218 @@ #include #include #include -#include // for sqrt +#include // for sqrt using namespace boost; using namespace std; - // auxiliary types struct location { - float y, x; // lat, long + float y, x; // lat, long }; typedef float cost; -template -class city_writer { +template < class Name, class LocMap > class city_writer +{ public: - city_writer(Name n, LocMap l, float _minx, float _maxx, - float _miny, float _maxy, - unsigned int _ptx, unsigned int _pty) - : name(n), loc(l), minx(_minx), maxx(_maxx), miny(_miny), - maxy(_maxy), ptx(_ptx), pty(_pty) {} - template - void operator()(ostream& out, const Vertex& v) const { - float px = 1 - (loc[v].x - minx) / (maxx - minx); - float py = (loc[v].y - miny) / (maxy - miny); - out << "[label=\"" << name[v] << "\", pos=\"" - << static_cast(ptx * px) << "," - << static_cast(pty * py) - << "\", fontsize=\"11\"]"; - } + city_writer(Name n, LocMap l, float _minx, float _maxx, float _miny, + float _maxy, unsigned int _ptx, unsigned int _pty) + : name(n) + , loc(l) + , minx(_minx) + , maxx(_maxx) + , miny(_miny) + , maxy(_maxy) + , ptx(_ptx) + , pty(_pty) + { + } + template < class Vertex > + void operator()(ostream& out, const Vertex& v) const + { + float px = 1 - (loc[v].x - minx) / (maxx - minx); + float py = (loc[v].y - miny) / (maxy - miny); + out << "[label=\"" << name[v] << "\", pos=\"" + << static_cast< unsigned int >(ptx * px) << "," + << static_cast< unsigned int >(pty * py) << "\", fontsize=\"11\"]"; + } + private: - Name name; - LocMap loc; - float minx, maxx, miny, maxy; - unsigned int ptx, pty; + Name name; + LocMap loc; + float minx, maxx, miny, maxy; + unsigned int ptx, pty; }; -template -class time_writer { +template < class WeightMap > class time_writer +{ public: - time_writer(WeightMap w) : wm(w) {} - template - void operator()(ostream &out, const Edge& e) const { - out << "[label=\"" << wm[e] << "\", fontsize=\"11\"]"; - } + time_writer(WeightMap w) : wm(w) {} + template < class Edge > void operator()(ostream& out, const Edge& e) const + { + out << "[label=\"" << wm[e] << "\", fontsize=\"11\"]"; + } + private: - WeightMap wm; + WeightMap wm; }; - // euclidean distance heuristic -template -class distance_heuristic : public astar_heuristic +template < class Graph, class CostType, class LocMap > +class distance_heuristic : public astar_heuristic< Graph, CostType > { public: - typedef typename graph_traits::vertex_descriptor Vertex; - distance_heuristic(LocMap l, Vertex goal) - : m_location(l), m_goal(goal) {} - CostType operator()(Vertex u) - { - CostType dx = m_location[m_goal].x - m_location[u].x; - CostType dy = m_location[m_goal].y - m_location[u].y; - return ::sqrt(dx * dx + dy * dy); - } + typedef typename graph_traits< Graph >::vertex_descriptor Vertex; + distance_heuristic(LocMap l, Vertex goal) : m_location(l), m_goal(goal) {} + CostType operator()(Vertex u) + { + CostType dx = m_location[m_goal].x - m_location[u].x; + CostType dy = m_location[m_goal].y - m_location[u].y; + return ::sqrt(dx * dx + dy * dy); + } + private: - LocMap m_location; - Vertex m_goal; + LocMap m_location; + Vertex m_goal; }; - -struct found_goal {}; // exception for termination +struct found_goal +{ +}; // exception for termination // visitor that terminates when we find the goal -template +template < class Vertex > class astar_goal_visitor : public boost::default_astar_visitor { public: - astar_goal_visitor(Vertex goal) : m_goal(goal) {} - template - void examine_vertex(Vertex u, Graph& g) { - if(u == m_goal) - throw found_goal(); - } + astar_goal_visitor(Vertex goal) : m_goal(goal) {} + template < class Graph > void examine_vertex(Vertex u, Graph& g) + { + if (u == m_goal) + throw found_goal(); + } + private: - Vertex m_goal; + Vertex m_goal; }; - -int main(int argc, char **argv) +int main(int argc, char** argv) { - - // specify some types - typedef adjacency_list > mygraph_t; - typedef property_map::type WeightMap; - typedef mygraph_t::vertex_descriptor vertex; - typedef mygraph_t::edge_descriptor edge_descriptor; - typedef std::pair edge; - - // specify data - enum nodes { - Troy, LakePlacid, Plattsburgh, Massena, Watertown, Utica, - Syracuse, Rochester, Buffalo, Ithaca, Binghamton, Woodstock, - NewYork, N - }; - const char *name[] = { - "Troy", "Lake Placid", "Plattsburgh", "Massena", - "Watertown", "Utica", "Syracuse", "Rochester", "Buffalo", - "Ithaca", "Binghamton", "Woodstock", "New York" - }; - location locations[] = { // lat/long - {42.73, 73.68}, {44.28, 73.99}, {44.70, 73.46}, - {44.93, 74.89}, {43.97, 75.91}, {43.10, 75.23}, - {43.04, 76.14}, {43.17, 77.61}, {42.89, 78.86}, - {42.44, 76.50}, {42.10, 75.91}, {42.04, 74.11}, - {40.67, 73.94} - }; - edge edge_array[] = { - edge(Troy,Utica), edge(Troy,LakePlacid), - edge(Troy,Plattsburgh), edge(LakePlacid,Plattsburgh), - edge(Plattsburgh,Massena), edge(LakePlacid,Massena), - edge(Massena,Watertown), edge(Watertown,Utica), - edge(Watertown,Syracuse), edge(Utica,Syracuse), - edge(Syracuse,Rochester), edge(Rochester,Buffalo), - edge(Syracuse,Ithaca), edge(Ithaca,Binghamton), - edge(Ithaca,Rochester), edge(Binghamton,Troy), - edge(Binghamton,Woodstock), edge(Binghamton,NewYork), - edge(Syracuse,Binghamton), edge(Woodstock,Troy), - edge(Woodstock,NewYork) - }; - unsigned int num_edges = sizeof(edge_array) / sizeof(edge); - cost weights[] = { // estimated travel time (mins) - 96, 134, 143, 65, 115, 133, 117, 116, 74, 56, - 84, 73, 69, 70, 116, 147, 173, 183, 74, 71, 124 - }; - - - // create graph - mygraph_t g(N); - WeightMap weightmap = get(edge_weight, g); - for(std::size_t j = 0; j < num_edges; ++j) { - edge_descriptor e; bool inserted; - boost::tie(e, inserted) = add_edge(edge_array[j].first, - edge_array[j].second, g); - weightmap[e] = weights[j]; - } - - - // pick random start/goal - boost::mt19937 gen(std::time(0)); - vertex start = random_vertex(g, gen); - vertex goal = random_vertex(g, gen); - - - cout << "Start vertex: " << name[start] << endl; - cout << "Goal vertex: " << name[goal] << endl; - - ofstream dotfile; - dotfile.open("test-astar-cities.dot"); - write_graphviz(dotfile, g, - city_writer - (name, locations, 73.46, 78.86, 40.67, 44.93, - 480, 400), - time_writer(weightmap)); - - - vector p(num_vertices(g)); - vector d(num_vertices(g)); - try { - // call astar named parameter interface - astar_search_tree - (g, start, - distance_heuristic - (locations, goal), - predecessor_map(make_iterator_property_map(p.begin(), get(vertex_index, g))). - distance_map(make_iterator_property_map(d.begin(), get(vertex_index, g))). - visitor(astar_goal_visitor(goal))); - - - } catch(found_goal fg) { // found a path to the goal - list shortest_path; - for(vertex v = goal;; v = p[v]) { - shortest_path.push_front(v); - if(p[v] == v) - break; + + // specify some types + typedef adjacency_list< listS, vecS, undirectedS, no_property, + property< edge_weight_t, cost > > + mygraph_t; + typedef property_map< mygraph_t, edge_weight_t >::type WeightMap; + typedef mygraph_t::vertex_descriptor vertex; + typedef mygraph_t::edge_descriptor edge_descriptor; + typedef std::pair< int, int > edge; + + // specify data + enum nodes + { + Troy, + LakePlacid, + Plattsburgh, + Massena, + Watertown, + Utica, + Syracuse, + Rochester, + Buffalo, + Ithaca, + Binghamton, + Woodstock, + NewYork, + N + }; + const char* name[] = { "Troy", "Lake Placid", "Plattsburgh", "Massena", + "Watertown", "Utica", "Syracuse", "Rochester", "Buffalo", "Ithaca", + "Binghamton", "Woodstock", "New York" }; + location locations[] = { // lat/long + { 42.73, 73.68 }, { 44.28, 73.99 }, { 44.70, 73.46 }, { 44.93, 74.89 }, + { 43.97, 75.91 }, { 43.10, 75.23 }, { 43.04, 76.14 }, { 43.17, 77.61 }, + { 42.89, 78.86 }, { 42.44, 76.50 }, { 42.10, 75.91 }, { 42.04, 74.11 }, + { 40.67, 73.94 } + }; + edge edge_array[] + = { edge(Troy, Utica), edge(Troy, LakePlacid), edge(Troy, Plattsburgh), + edge(LakePlacid, Plattsburgh), edge(Plattsburgh, Massena), + edge(LakePlacid, Massena), edge(Massena, Watertown), + edge(Watertown, Utica), edge(Watertown, Syracuse), + edge(Utica, Syracuse), edge(Syracuse, Rochester), + edge(Rochester, Buffalo), edge(Syracuse, Ithaca), + edge(Ithaca, Binghamton), edge(Ithaca, Rochester), + edge(Binghamton, Troy), edge(Binghamton, Woodstock), + edge(Binghamton, NewYork), edge(Syracuse, Binghamton), + edge(Woodstock, Troy), edge(Woodstock, NewYork) }; + unsigned int num_edges = sizeof(edge_array) / sizeof(edge); + cost weights[] = { // estimated travel time (mins) + 96, 134, 143, 65, 115, 133, 117, 116, 74, 56, 84, 73, 69, 70, 116, 147, + 173, 183, 74, 71, 124 + }; + + // create graph + mygraph_t g(N); + WeightMap weightmap = get(edge_weight, g); + for (std::size_t j = 0; j < num_edges; ++j) + { + edge_descriptor e; + bool inserted; + boost::tie(e, inserted) + = add_edge(edge_array[j].first, edge_array[j].second, g); + weightmap[e] = weights[j]; + } + + // pick random start/goal + boost::mt19937 gen(std::time(0)); + vertex start = random_vertex(g, gen); + vertex goal = random_vertex(g, gen); + + cout << "Start vertex: " << name[start] << endl; + cout << "Goal vertex: " << name[goal] << endl; + + ofstream dotfile; + dotfile.open("test-astar-cities.dot"); + write_graphviz(dotfile, g, + city_writer< const char**, location* >( + name, locations, 73.46, 78.86, 40.67, 44.93, 480, 400), + time_writer< WeightMap >(weightmap)); + + vector< mygraph_t::vertex_descriptor > p(num_vertices(g)); + vector< cost > d(num_vertices(g)); + try + { + // call astar named parameter interface + astar_search_tree(g, start, + distance_heuristic< mygraph_t, cost, location* >(locations, goal), + predecessor_map( + make_iterator_property_map(p.begin(), get(vertex_index, g))) + .distance_map( + make_iterator_property_map(d.begin(), get(vertex_index, g))) + .visitor(astar_goal_visitor< vertex >(goal))); } - cout << "Shortest path from " << name[start] << " to " - << name[goal] << ": "; - list::iterator spi = shortest_path.begin(); - cout << name[start]; - for(++spi; spi != shortest_path.end(); ++spi) - cout << " -> " << name[*spi]; - cout << endl << "Total travel time: " << d[goal] << endl; + catch (found_goal fg) + { // found a path to the goal + list< vertex > shortest_path; + for (vertex v = goal;; v = p[v]) + { + shortest_path.push_front(v); + if (p[v] == v) + break; + } + cout << "Shortest path from " << name[start] << " to " << name[goal] + << ": "; + list< vertex >::iterator spi = shortest_path.begin(); + cout << name[start]; + for (++spi; spi != shortest_path.end(); ++spi) + cout << " -> " << name[*spi]; + cout << endl << "Total travel time: " << d[goal] << endl; + return 0; + } + + cout << "Didn't find a path from " << name[start] << "to" << name[goal] + << "!" << endl; return 0; - } - - cout << "Didn't find a path from " << name[start] << "to" - << name[goal] << "!" << endl; - return 0; - } diff --git a/example/astar_maze.cpp b/example/astar_maze.cpp index e567a15bf..4c437ee87 100644 --- a/example/astar_maze.cpp +++ b/example/astar_maze.cpp @@ -4,7 +4,6 @@ // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) - // This program uses the A-star search algorithm in the Boost Graph Library to // solve a maze. It is an example of how to apply Boost Graph Library // algorithms to implicit graphs. @@ -26,11 +25,11 @@ IMPORTANT: ~~~~~~~~~~ - This example appears to be broken and crashes at runtime, see https://github.com/boostorg/graph/issues/148 + This example appears to be broken and crashes at runtime, see + https://github.com/boostorg/graph/issues/148 */ - #include #include #include @@ -49,25 +48,27 @@ boost::mt19937 random_generator; typedef double distance; #define GRID_RANK 2 -typedef boost::grid_graph grid; -typedef boost::graph_traits::vertex_descriptor vertex_descriptor; -typedef boost::graph_traits::vertices_size_type vertices_size_type; +typedef boost::grid_graph< GRID_RANK > grid; +typedef boost::graph_traits< grid >::vertex_descriptor vertex_descriptor; +typedef boost::graph_traits< grid >::vertices_size_type vertices_size_type; // A hash function for vertices. -struct vertex_hash { - typedef vertex_descriptor argument_type; - typedef std::size_t result_type; - std::size_t operator()(vertex_descriptor const& u) const { - std::size_t seed = 0; - boost::hash_combine(seed, u[0]); - boost::hash_combine(seed, u[1]); - return seed; - } +struct vertex_hash +{ + typedef vertex_descriptor argument_type; + typedef std::size_t result_type; + std::size_t operator()(vertex_descriptor const& u) const + { + std::size_t seed = 0; + boost::hash_combine(seed, u[0]); + boost::hash_combine(seed, u[1]); + return seed; + } }; -typedef boost::unordered_set vertex_set; -typedef boost::vertex_subset_complement_filter::type - filtered_grid; +typedef boost::unordered_set< vertex_descriptor, vertex_hash > vertex_set; +typedef boost::vertex_subset_complement_filter< grid, vertex_set >::type + filtered_grid; // A searchable maze // @@ -84,235 +85,260 @@ typedef boost::vertex_subset_complement_filter::type // A-star search is used to find a path through the maze. Each edge has a // weight of one, so the total path length is equal to the number of edges // traversed. -class maze { +class maze +{ public: - friend std::ostream& operator<<(std::ostream&, const maze&); - friend void random_maze(maze&); + friend std::ostream& operator<<(std::ostream&, const maze&); + friend void random_maze(maze&); - maze():m_grid(create_grid(0, 0)),m_barrier_grid(create_barrier_grid()) {}; - maze(std::size_t x, std::size_t y):m_grid(create_grid(x, y)), - m_barrier_grid(create_barrier_grid()) {}; + maze() + : m_grid(create_grid(0, 0)), m_barrier_grid(create_barrier_grid()) {}; + maze(std::size_t x, std::size_t y) + : m_grid(create_grid(x, y)), m_barrier_grid(create_barrier_grid()) {}; - // The length of the maze along the specified dimension. - vertices_size_type length(std::size_t d) const {return m_grid.length(d);} + // The length of the maze along the specified dimension. + vertices_size_type length(std::size_t d) const { return m_grid.length(d); } - bool has_barrier(vertex_descriptor u) const { - return m_barriers.find(u) != m_barriers.end(); - } + bool has_barrier(vertex_descriptor u) const + { + return m_barriers.find(u) != m_barriers.end(); + } - // Try to find a path from the lower-left-hand corner source (0,0) to the - // upper-right-hand corner goal (x-1, y-1). - vertex_descriptor source() const {return vertex(0, m_grid);} - vertex_descriptor goal() const { - return vertex(num_vertices(m_grid)-1, m_grid); - } + // Try to find a path from the lower-left-hand corner source (0,0) to the + // upper-right-hand corner goal (x-1, y-1). + vertex_descriptor source() const { return vertex(0, m_grid); } + vertex_descriptor goal() const + { + return vertex(num_vertices(m_grid) - 1, m_grid); + } - bool solve(); - bool solved() const {return !m_solution.empty();} - bool solution_contains(vertex_descriptor u) const { - return m_solution.find(u) != m_solution.end(); - } + bool solve(); + bool solved() const { return !m_solution.empty(); } + bool solution_contains(vertex_descriptor u) const + { + return m_solution.find(u) != m_solution.end(); + } private: - // Create the underlying rank-2 grid with the specified dimensions. - grid create_grid(std::size_t x, std::size_t y) { - boost::array lengths = { {x, y} }; - return grid(lengths); - } - - // Filter the barrier vertices out of the underlying grid. - filtered_grid create_barrier_grid() { - return boost::make_vertex_subset_complement_filter(m_grid, m_barriers); - } - - // The grid underlying the maze - grid m_grid; - // The barriers in the maze - vertex_set m_barriers; - // The underlying maze grid with barrier vertices filtered out - filtered_grid m_barrier_grid; - // The vertices on a solution path through the maze - vertex_set m_solution; - // The length of the solution path - distance m_solution_length; -}; + // Create the underlying rank-2 grid with the specified dimensions. + grid create_grid(std::size_t x, std::size_t y) + { + boost::array< std::size_t, GRID_RANK > lengths = { { x, y } }; + return grid(lengths); + } + // Filter the barrier vertices out of the underlying grid. + filtered_grid create_barrier_grid() + { + return boost::make_vertex_subset_complement_filter(m_grid, m_barriers); + } + + // The grid underlying the maze + grid m_grid; + // The barriers in the maze + vertex_set m_barriers; + // The underlying maze grid with barrier vertices filtered out + filtered_grid m_barrier_grid; + // The vertices on a solution path through the maze + vertex_set m_solution; + // The length of the solution path + distance m_solution_length; +}; // Euclidean heuristic for a grid // // This calculates the Euclidean distance between a vertex and a goal // vertex. -class euclidean_heuristic: - public boost::astar_heuristic +class euclidean_heuristic +: public boost::astar_heuristic< filtered_grid, double > { public: - euclidean_heuristic(vertex_descriptor goal):m_goal(goal) {}; + euclidean_heuristic(vertex_descriptor goal) : m_goal(goal) {}; - double operator()(vertex_descriptor v) { - return sqrt(pow(double(m_goal[0] - v[0]), 2) + pow(double(m_goal[1] - v[1]), 2)); - } + double operator()(vertex_descriptor v) + { + return sqrt(pow(double(m_goal[0] - v[0]), 2) + + pow(double(m_goal[1] - v[1]), 2)); + } private: - vertex_descriptor m_goal; + vertex_descriptor m_goal; }; // Exception thrown when the goal vertex is found -struct found_goal {}; +struct found_goal +{ +}; // Visitor that terminates when we find the goal vertex -struct astar_goal_visitor:public boost::default_astar_visitor { - astar_goal_visitor(vertex_descriptor goal):m_goal(goal) {}; +struct astar_goal_visitor : public boost::default_astar_visitor +{ + astar_goal_visitor(vertex_descriptor goal) : m_goal(goal) {}; - void examine_vertex(vertex_descriptor u, const filtered_grid&) { - if (u == m_goal) - throw found_goal(); - } + void examine_vertex(vertex_descriptor u, const filtered_grid&) + { + if (u == m_goal) + throw found_goal(); + } private: - vertex_descriptor m_goal; + vertex_descriptor m_goal; }; // Solve the maze using A-star search. Return true if a solution was found. -bool maze::solve() { - boost::static_property_map weight(1); - // The predecessor map is a vertex-to-vertex mapping. - typedef boost::unordered_map pred_map; - pred_map predecessor; - boost::associative_property_map pred_pmap(predecessor); - // The distance map is a vertex-to-distance mapping. - typedef boost::unordered_map dist_map; - dist_map distance; - boost::associative_property_map dist_pmap(distance); - - vertex_descriptor s = source(); - vertex_descriptor g = goal(); - euclidean_heuristic heuristic(g); - astar_goal_visitor visitor(g); - - try { - astar_search(m_barrier_grid, s, heuristic, - boost::weight_map(weight). - predecessor_map(pred_pmap). - distance_map(dist_pmap). - visitor(visitor) ); - } catch(found_goal fg) { - // Walk backwards from the goal through the predecessor chain adding - // vertices to the solution path. - for (vertex_descriptor u = g; u != s; u = predecessor[u]) - m_solution.insert(u); - m_solution.insert(s); - m_solution_length = distance[g]; - return true; - } - - return false; -} +bool maze::solve() +{ + boost::static_property_map< distance > weight(1); + // The predecessor map is a vertex-to-vertex mapping. + typedef boost::unordered_map< vertex_descriptor, vertex_descriptor, + vertex_hash > + pred_map; + pred_map predecessor; + boost::associative_property_map< pred_map > pred_pmap(predecessor); + // The distance map is a vertex-to-distance mapping. + typedef boost::unordered_map< vertex_descriptor, distance, vertex_hash > + dist_map; + dist_map distance; + boost::associative_property_map< dist_map > dist_pmap(distance); + + vertex_descriptor s = source(); + vertex_descriptor g = goal(); + euclidean_heuristic heuristic(g); + astar_goal_visitor visitor(g); + + try + { + astar_search(m_barrier_grid, s, heuristic, + boost::weight_map(weight) + .predecessor_map(pred_pmap) + .distance_map(dist_pmap) + .visitor(visitor)); + } + catch (found_goal fg) + { + // Walk backwards from the goal through the predecessor chain adding + // vertices to the solution path. + for (vertex_descriptor u = g; u != s; u = predecessor[u]) + m_solution.insert(u); + m_solution.insert(s); + m_solution_length = distance[g]; + return true; + } + return false; +} #define BARRIER "#" // Print the maze as an ASCII map. -std::ostream& operator<<(std::ostream& output, const maze& m) { - // Header - for (vertices_size_type i = 0; i < m.length(0)+2; i++) - output << BARRIER; - output << std::endl; - // Body - for (int y = m.length(1)-1; y >= 0; y--) { - // Enumerate rows in reverse order and columns in regular order so that - // (0,0) appears in the lower left-hand corner. This requires that y be - // int and not the unsigned vertices_size_type because the loop exit - // condition is y==-1. - for (vertices_size_type x = 0; x < m.length(0); x++) { - // Put a barrier on the left-hand side. - if (x == 0) - output << BARRIER; - // Put the character representing this point in the maze grid. - vertex_descriptor u = {{x, vertices_size_type(y)}}; - if (m.solution_contains(u)) - output << "."; - else if (m.has_barrier(u)) - output << BARRIER; - else - output << " "; - // Put a barrier on the right-hand side. - if (x == m.length(0)-1) +std::ostream& operator<<(std::ostream& output, const maze& m) +{ + // Header + for (vertices_size_type i = 0; i < m.length(0) + 2; i++) output << BARRIER; - } - // Put a newline after every row except the last one. output << std::endl; - } - // Footer - for (vertices_size_type i = 0; i < m.length(0)+2; i++) - output << BARRIER; - if (m.solved()) - output << std::endl << "Solution length " << m.m_solution_length; - return output; + // Body + for (int y = m.length(1) - 1; y >= 0; y--) + { + // Enumerate rows in reverse order and columns in regular order so that + // (0,0) appears in the lower left-hand corner. This requires that y be + // int and not the unsigned vertices_size_type because the loop exit + // condition is y==-1. + for (vertices_size_type x = 0; x < m.length(0); x++) + { + // Put a barrier on the left-hand side. + if (x == 0) + output << BARRIER; + // Put the character representing this point in the maze grid. + vertex_descriptor u = { { x, vertices_size_type(y) } }; + if (m.solution_contains(u)) + output << "."; + else if (m.has_barrier(u)) + output << BARRIER; + else + output << " "; + // Put a barrier on the right-hand side. + if (x == m.length(0) - 1) + output << BARRIER; + } + // Put a newline after every row except the last one. + output << std::endl; + } + // Footer + for (vertices_size_type i = 0; i < m.length(0) + 2; i++) + output << BARRIER; + if (m.solved()) + output << std::endl << "Solution length " << m.m_solution_length; + return output; } // Return a random integer in the interval [a, b]. -std::size_t random_int(std::size_t a, std::size_t b) { - if (b < a) - b = a; - boost::uniform_int<> dist(a, b); - boost::variate_generator > - generate(random_generator, dist); - return generate(); +std::size_t random_int(std::size_t a, std::size_t b) +{ + if (b < a) + b = a; + boost::uniform_int<> dist(a, b); + boost::variate_generator< boost::mt19937&, boost::uniform_int<> > generate( + random_generator, dist); + return generate(); } // Generate a maze with a random assignment of barriers. -void random_maze(maze& m) { - vertices_size_type n = num_vertices(m.m_grid); - vertex_descriptor s = m.source(); - vertex_descriptor g = m.goal(); - // One quarter of the cells in the maze should be barriers. - int barriers = n/4; - while (barriers > 0) { - // Choose horizontal or vertical direction. - std::size_t direction = random_int(0, 1); - // Walls range up to one quarter the dimension length in this direction. - vertices_size_type wall = random_int(1, m.length(direction)/4); - // Create the wall while decrementing the total barrier count. - vertex_descriptor u = vertex(random_int(0, n-1), m.m_grid); - while (wall) { - // Start and goal spaces should never be barriers. - if (u != s && u != g) { - wall--; - if (!m.has_barrier(u)) { - m.m_barriers.insert(u); - barriers--; +void random_maze(maze& m) +{ + vertices_size_type n = num_vertices(m.m_grid); + vertex_descriptor s = m.source(); + vertex_descriptor g = m.goal(); + // One quarter of the cells in the maze should be barriers. + int barriers = n / 4; + while (barriers > 0) + { + // Choose horizontal or vertical direction. + std::size_t direction = random_int(0, 1); + // Walls range up to one quarter the dimension length in this direction. + vertices_size_type wall = random_int(1, m.length(direction) / 4); + // Create the wall while decrementing the total barrier count. + vertex_descriptor u = vertex(random_int(0, n - 1), m.m_grid); + while (wall) + { + // Start and goal spaces should never be barriers. + if (u != s && u != g) + { + wall--; + if (!m.has_barrier(u)) + { + m.m_barriers.insert(u); + barriers--; + } + } + vertex_descriptor v = m.m_grid.next(u, direction); + // Stop creating this wall if we reached the maze's edge. + if (u == v) + break; + u = v; } - } - vertex_descriptor v = m.m_grid.next(u, direction); - // Stop creating this wall if we reached the maze's edge. - if (u == v) - break; - u = v; } - } } -int main (int argc, char const *argv[]) { - // The default maze size is 20x10. A different size may be specified on - // the command line. - std::size_t x = 20; - std::size_t y = 10; - - if (argc == 3) { - x = boost::lexical_cast(argv[1]); - y = boost::lexical_cast(argv[2]); - } - - random_generator.seed(std::time(0)); - maze m(x, y); - random_maze(m); - if (m.solve()) - std::cout << "Solved the maze." << std::endl; - else - std::cout << "The maze is not solvable." << std::endl; - std::cout << m << std::endl; - return 0; +int main(int argc, char const* argv[]) +{ + // The default maze size is 20x10. A different size may be specified on + // the command line. + std::size_t x = 20; + std::size_t y = 10; + + if (argc == 3) + { + x = boost::lexical_cast< std::size_t >(argv[1]); + y = boost::lexical_cast< std::size_t >(argv[2]); + } + + random_generator.seed(std::time(0)); + maze m(x, y); + random_maze(m); + if (m.solve()) + std::cout << "Solved the maze." << std::endl; + else + std::cout << "The maze is not solvable." << std::endl; + std::cout << m << std::endl; + return 0; } diff --git a/example/bcsstk01.rsa b/example/bcsstk01.rsa index 3d420ed47..428488786 100644 --- a/example/bcsstk01.rsa +++ b/example/bcsstk01.rsa @@ -1,11 +1,11 @@ 1SYMMETRIC STIFFNESS MATRIX SMALL GENERALIZED EIGENVALUE PROBLEM BCSSTK01 - 74 4 14 56 0 -RSA 48 48 224 0 -(16I5) (16I5) (4E20.12) + 74 4 14 56 0 +RSA 48 48 224 0 +(16I5) (16I5) (4E20.12) 1 9 17 25 31 37 43 49 55 62 66 70 75 85 95 104 112 120 127 132 136 141 144 146 149 154 158 161 164 167 169 173 178 183 185 188 191 196 201 205 208 211 213 216 219 221 222 224 - 225 + 225 1 5 6 7 11 19 25 30 2 4 6 8 10 20 24 26 3 4 5 9 21 23 27 28 4 8 10 22 27 28 5 7 11 21 23 29 6 12 20 24 25 30 7 11 12 13 31 36 diff --git a/example/bellman-example.cpp b/example/bellman-example.cpp index e6ec87506..69bce6397 100644 --- a/example/bellman-example.cpp +++ b/example/bellman-example.cpp @@ -1,5 +1,5 @@ //======================================================================= -// Copyright 2001 Jeremy G. Siek, Andrew Lumsdaine, Lie-Quan Lee, +// Copyright 2001 Jeremy G. Siek, Andrew Lumsdaine, Lie-Quan Lee, // // Distributed under the Boost Software License, Version 1.0. (See // accompanying file LICENSE_1_0.txt or copy at @@ -15,114 +15,120 @@ using namespace boost; -template < typename Graph, typename ParentMap > -struct edge_writer +template < typename Graph, typename ParentMap > struct edge_writer { - edge_writer(const Graph & g, const ParentMap & p) - : m_g(g), m_parent(p) - { - } + edge_writer(const Graph& g, const ParentMap& p) : m_g(g), m_parent(p) {} - template < typename Edge > - void operator() (std::ostream & out, const Edge & e) const - { - out << "[label=\"" << get(edge_weight, m_g, e) << "\""; - typename graph_traits < Graph >::vertex_descriptor - u = source(e, m_g), v = target(e, m_g); - if (m_parent[v] == u) - out << ", color=\"black\""; - else - out << ", color=\"grey\""; - out << "]"; - } - const Graph & m_g; - ParentMap m_parent; + template < typename Edge > + void operator()(std::ostream& out, const Edge& e) const + { + out << "[label=\"" << get(edge_weight, m_g, e) << "\""; + typename graph_traits< Graph >::vertex_descriptor u = source(e, m_g), + v = target(e, m_g); + if (m_parent[v] == u) + out << ", color=\"black\""; + else + out << ", color=\"grey\""; + out << "]"; + } + const Graph& m_g; + ParentMap m_parent; }; template < typename Graph, typename Parent > -edge_writer < Graph, Parent > -make_edge_writer(const Graph & g, const Parent & p) +edge_writer< Graph, Parent > make_edge_writer(const Graph& g, const Parent& p) { - return edge_writer < Graph, Parent > (g, p); + return edge_writer< Graph, Parent >(g, p); } -struct EdgeProperties { - int weight; +struct EdgeProperties +{ + int weight; }; -int -main() +int main() { - enum { u, v, x, y, z, N }; - char name[] = { 'u', 'v', 'x', 'y', 'z' }; - typedef std::pair < int, int >E; - const int n_edges = 10; - E edge_array[] = { E(u, y), E(u, x), E(u, v), E(v, u), - E(x, y), E(x, v), E(y, v), E(y, z), E(z, u), E(z,x) }; - int weight[n_edges] = { -4, 8, 5, -2, 9, -3, 7, 2, 6, 7 }; + enum + { + u, + v, + x, + y, + z, + N + }; + char name[] = { 'u', 'v', 'x', 'y', 'z' }; + typedef std::pair< int, int > E; + const int n_edges = 10; + E edge_array[] = { E(u, y), E(u, x), E(u, v), E(v, u), E(x, y), E(x, v), + E(y, v), E(y, z), E(z, u), E(z, x) }; + int weight[n_edges] = { -4, 8, 5, -2, 9, -3, 7, 2, 6, 7 }; - typedef adjacency_list < vecS, vecS, directedS, - no_property, EdgeProperties> Graph; + typedef adjacency_list< vecS, vecS, directedS, no_property, EdgeProperties > + Graph; #if defined(BOOST_MSVC) && BOOST_MSVC <= 1300 - // VC++ can't handle the iterator constructor - Graph g(N); - for (std::size_t j = 0; j < n_edges; ++j) - add_edge(edge_array[j].first, edge_array[j].second, g); + // VC++ can't handle the iterator constructor + Graph g(N); + for (std::size_t j = 0; j < n_edges; ++j) + add_edge(edge_array[j].first, edge_array[j].second, g); #else - Graph g(edge_array, edge_array + n_edges, N); + Graph g(edge_array, edge_array + n_edges, N); #endif - graph_traits < Graph >::edge_iterator ei, ei_end; - property_map::type - weight_pmap = get(&EdgeProperties::weight, g); - int i = 0; - for (boost::tie(ei, ei_end) = edges(g); ei != ei_end; ++ei, ++i) - weight_pmap[*ei] = weight[i]; + graph_traits< Graph >::edge_iterator ei, ei_end; + property_map< Graph, int EdgeProperties::* >::type weight_pmap + = get(&EdgeProperties::weight, g); + int i = 0; + for (boost::tie(ei, ei_end) = edges(g); ei != ei_end; ++ei, ++i) + weight_pmap[*ei] = weight[i]; - std::vector distance(N, (std::numeric_limits < short >::max)()); - std::vector parent(N); - for (i = 0; i < N; ++i) - parent[i] = i; - distance[z] = 0; + std::vector< int > distance(N, (std::numeric_limits< short >::max)()); + std::vector< std::size_t > parent(N); + for (i = 0; i < N; ++i) + parent[i] = i; + distance[z] = 0; #if defined(BOOST_MSVC) && BOOST_MSVC <= 1300 - bool r = bellman_ford_shortest_paths - (g, int(N), weight_pmap, &parent[0], &distance[0], - closed_plus(), std::less(), default_bellman_visitor()); + bool r = bellman_ford_shortest_paths(g, int(N), weight_pmap, &parent[0], + &distance[0], closed_plus< int >(), std::less< int >(), + default_bellman_visitor()); #else - bool r = bellman_ford_shortest_paths - (g, int (N), weight_map(weight_pmap).distance_map(&distance[0]). - predecessor_map(&parent[0])); + bool r = bellman_ford_shortest_paths(g, int(N), + weight_map(weight_pmap) + .distance_map(&distance[0]) + .predecessor_map(&parent[0])); #endif - if (r) - for (i = 0; i < N; ++i) - std::cout << name[i] << ": " << std::setw(3) << distance[i] - << " " << name[parent[i]] << std::endl; - else - std::cout << "negative cycle" << std::endl; + if (r) + for (i = 0; i < N; ++i) + std::cout << name[i] << ": " << std::setw(3) << distance[i] << " " + << name[parent[i]] << std::endl; + else + std::cout << "negative cycle" << std::endl; - std::ofstream dot_file("figs/bellman-eg.dot"); - dot_file << "digraph D {\n" - << " rankdir=LR\n" - << " size=\"5,3\"\n" - << " ratio=\"fill\"\n" - << " edge[style=\"bold\"]\n" << " node[shape=\"circle\"]\n"; + std::ofstream dot_file("figs/bellman-eg.dot"); + dot_file << "digraph D {\n" + << " rankdir=LR\n" + << " size=\"5,3\"\n" + << " ratio=\"fill\"\n" + << " edge[style=\"bold\"]\n" + << " node[shape=\"circle\"]\n"; - { - for (boost::tie(ei, ei_end) = edges(g); ei != ei_end; ++ei) { - graph_traits < Graph >::edge_descriptor e = *ei; - graph_traits < Graph >::vertex_descriptor - u = source(e, g), v = target(e, g); - // VC++ doesn't like the 3-argument get function, so here - // we workaround by using 2-nested get()'s. - dot_file << name[u] << " -> " << name[v] - << "[label=\"" << get(get(&EdgeProperties::weight, g), e) << "\""; - if (parent[v] == u) - dot_file << ", color=\"black\""; - else - dot_file << ", color=\"grey\""; - dot_file << "]"; + { + for (boost::tie(ei, ei_end) = edges(g); ei != ei_end; ++ei) + { + graph_traits< Graph >::edge_descriptor e = *ei; + graph_traits< Graph >::vertex_descriptor u = source(e, g), + v = target(e, g); + // VC++ doesn't like the 3-argument get function, so here + // we workaround by using 2-nested get()'s. + dot_file << name[u] << " -> " << name[v] << "[label=\"" + << get(get(&EdgeProperties::weight, g), e) << "\""; + if (parent[v] == u) + dot_file << ", color=\"black\""; + else + dot_file << ", color=\"grey\""; + dot_file << "]"; + } } - } - dot_file << "}"; - return EXIT_SUCCESS; + dot_file << "}"; + return EXIT_SUCCESS; } diff --git a/example/bellman-ford-internet.cpp b/example/bellman-ford-internet.cpp index 24bbfef4f..a761373d3 100644 --- a/example/bellman-ford-internet.cpp +++ b/example/bellman-ford-internet.cpp @@ -1,5 +1,5 @@ //======================================================================= -// Copyright 2001 Jeremy G. Siek, Andrew Lumsdaine, Lie-Quan Lee, +// Copyright 2001 Jeremy G. Siek, Andrew Lumsdaine, Lie-Quan Lee, // // Distributed under the Boost Software License, Version 1.0. (See // accompanying file LICENSE_1_0.txt or copy at @@ -9,55 +9,62 @@ #include #include -int -main() +int main() { - using namespace boost; - // ID numbers for the routers (vertices). - enum - { A, B, C, D, E, F, G, H, n_vertices }; - const int n_edges = 11; - typedef std::pair < int, int >Edge; - - // The list of connections between routers stored in an array. - Edge edges[] = { - Edge(A, B), Edge(A, C), - Edge(B, D), Edge(B, E), Edge(C, E), Edge(C, F), Edge(D, H), - Edge(D, E), Edge(E, H), Edge(F, G), Edge(G, H) - }; - - // Specify the graph type and declare a graph object - typedef edge_list < Edge*, Edge, std::ptrdiff_t, std::random_access_iterator_tag> Graph; - Graph g(edges, edges + n_edges); - - // The transmission delay values for each edge. - float delay[] = - {5.0, 1.0, 1.3, 3.0, 10.0, 2.0, 6.3, 0.4, 1.3, 1.2, 0.5}; - - // Declare some storage for some "external" vertex properties. - char name[] = "ABCDEFGH"; - int parent[n_vertices]; - for (int i = 0; i < n_vertices; ++i) - parent[i] = i; - float distance[n_vertices]; - std::fill(distance, distance + n_vertices, (std::numeric_limits < float >::max)()); - // Specify A as the source vertex - distance[A] = 0; - - bool r = bellman_ford_shortest_paths(g, int (n_vertices), - weight_map(make_iterator_property_map - (&delay[0], - get(edge_index, g), - delay[0])). - distance_map(&distance[0]). - predecessor_map(&parent[0])); - - if (r) + using namespace boost; + // ID numbers for the routers (vertices). + enum + { + A, + B, + C, + D, + E, + F, + G, + H, + n_vertices + }; + const int n_edges = 11; + typedef std::pair< int, int > Edge; + + // The list of connections between routers stored in an array. + Edge edges[] = { Edge(A, B), Edge(A, C), Edge(B, D), Edge(B, E), Edge(C, E), + Edge(C, F), Edge(D, H), Edge(D, E), Edge(E, H), Edge(F, G), + Edge(G, H) }; + + // Specify the graph type and declare a graph object + typedef edge_list< Edge*, Edge, std::ptrdiff_t, + std::random_access_iterator_tag > + Graph; + Graph g(edges, edges + n_edges); + + // The transmission delay values for each edge. + float delay[] = { 5.0, 1.0, 1.3, 3.0, 10.0, 2.0, 6.3, 0.4, 1.3, 1.2, 0.5 }; + + // Declare some storage for some "external" vertex properties. + char name[] = "ABCDEFGH"; + int parent[n_vertices]; for (int i = 0; i < n_vertices; ++i) - std::cout << name[i] << ": " << distance[i] - << " " << name[parent[i]] << std::endl; - else - std::cout << "negative cycle" << std::endl; + parent[i] = i; + float distance[n_vertices]; + std::fill( + distance, distance + n_vertices, (std::numeric_limits< float >::max)()); + // Specify A as the source vertex + distance[A] = 0; + + bool r = bellman_ford_shortest_paths(g, int(n_vertices), + weight_map( + make_iterator_property_map(&delay[0], get(edge_index, g), delay[0])) + .distance_map(&distance[0]) + .predecessor_map(&parent[0])); + + if (r) + for (int i = 0; i < n_vertices; ++i) + std::cout << name[i] << ": " << distance[i] << " " + << name[parent[i]] << std::endl; + else + std::cout << "negative cycle" << std::endl; - return EXIT_SUCCESS; + return EXIT_SUCCESS; } diff --git a/example/bfs-example.cpp b/example/bfs-example.cpp index 0436204ce..c42bef153 100644 --- a/example/bfs-example.cpp +++ b/example/bfs-example.cpp @@ -1,5 +1,5 @@ //======================================================================= -// Copyright 2001 Jeremy G. Siek, Andrew Lumsdaine, Lie-Quan Lee, +// Copyright 2001 Jeremy G. Siek, Andrew Lumsdaine, Lie-Quan Lee, // // Distributed under the Boost Software License, Version 1.0. (See // accompanying file LICENSE_1_0.txt or copy at @@ -13,72 +13,83 @@ #include using namespace boost; -template < typename TimeMap > class bfs_time_visitor:public default_bfs_visitor { - typedef typename property_traits < TimeMap >::value_type T; +template < typename TimeMap > +class bfs_time_visitor : public default_bfs_visitor +{ + typedef typename property_traits< TimeMap >::value_type T; + public: - bfs_time_visitor(TimeMap tmap, T & t):m_timemap(tmap), m_time(t) { } - template < typename Vertex, typename Graph > - void discover_vertex(Vertex u, const Graph & g) const - { - put(m_timemap, u, m_time++); - } - TimeMap m_timemap; - T & m_time; + bfs_time_visitor(TimeMap tmap, T& t) : m_timemap(tmap), m_time(t) {} + template < typename Vertex, typename Graph > + void discover_vertex(Vertex u, const Graph& g) const + { + put(m_timemap, u, m_time++); + } + TimeMap m_timemap; + T& m_time; }; - -int -main() +int main() { - using namespace boost; - // Select the graph type we wish to use - typedef adjacency_list < vecS, vecS, undirectedS > graph_t; - // Set up the vertex IDs and names - enum { r, s, t, u, v, w, x, y, N }; - const char *name = "rstuvwxy"; - // Specify the edges in the graph - typedef std::pair < int, int >E; - E edge_array[] = { E(r, s), E(r, v), E(s, w), E(w, r), E(w, t), - E(w, x), E(x, t), E(t, u), E(x, y), E(u, y) - }; - // Create the graph object - const int n_edges = sizeof(edge_array) / sizeof(E); + using namespace boost; + // Select the graph type we wish to use + typedef adjacency_list< vecS, vecS, undirectedS > graph_t; + // Set up the vertex IDs and names + enum + { + r, + s, + t, + u, + v, + w, + x, + y, + N + }; + const char* name = "rstuvwxy"; + // Specify the edges in the graph + typedef std::pair< int, int > E; + E edge_array[] = { E(r, s), E(r, v), E(s, w), E(w, r), E(w, t), E(w, x), + E(x, t), E(t, u), E(x, y), E(u, y) }; + // Create the graph object + const int n_edges = sizeof(edge_array) / sizeof(E); #if defined(BOOST_MSVC) && BOOST_MSVC <= 1300 - // VC++ has trouble with the edge iterator constructor - graph_t g(N); - for (std::size_t j = 0; j < n_edges; ++j) - add_edge(edge_array[j].first, edge_array[j].second, g); + // VC++ has trouble with the edge iterator constructor + graph_t g(N); + for (std::size_t j = 0; j < n_edges; ++j) + add_edge(edge_array[j].first, edge_array[j].second, g); #else - typedef graph_traits::vertices_size_type v_size_t; - graph_t g(edge_array, edge_array + n_edges, v_size_t(N)); + typedef graph_traits< graph_t >::vertices_size_type v_size_t; + graph_t g(edge_array, edge_array + n_edges, v_size_t(N)); #endif - // Typedefs - typedef graph_traits < graph_t >::vertices_size_type Size; + // Typedefs + typedef graph_traits< graph_t >::vertices_size_type Size; - // a vector to hold the discover time property for each vertex - std::vector < Size > dtime(num_vertices(g)); - typedef - iterator_property_map::iterator, - property_map::const_type> - dtime_pm_type; - dtime_pm_type dtime_pm(dtime.begin(), get(vertex_index, g)); + // a vector to hold the discover time property for each vertex + std::vector< Size > dtime(num_vertices(g)); + typedef iterator_property_map< std::vector< Size >::iterator, + property_map< graph_t, vertex_index_t >::const_type > + dtime_pm_type; + dtime_pm_type dtime_pm(dtime.begin(), get(vertex_index, g)); - Size time = 0; - bfs_time_visitor < dtime_pm_type >vis(dtime_pm, time); - breadth_first_search(g, vertex(s, g), visitor(vis)); + Size time = 0; + bfs_time_visitor< dtime_pm_type > vis(dtime_pm, time); + breadth_first_search(g, vertex(s, g), visitor(vis)); - // Use std::sort to order the vertices by their discover time - std::vector::vertices_size_type > discover_order(N); - integer_range < int >range(0, N); - std::copy(range.begin(), range.end(), discover_order.begin()); - std::sort(discover_order.begin(), discover_order.end(), - indirect_cmp < dtime_pm_type, std::less < Size > >(dtime_pm)); + // Use std::sort to order the vertices by their discover time + std::vector< graph_traits< graph_t >::vertices_size_type > discover_order( + N); + integer_range< int > range(0, N); + std::copy(range.begin(), range.end(), discover_order.begin()); + std::sort(discover_order.begin(), discover_order.end(), + indirect_cmp< dtime_pm_type, std::less< Size > >(dtime_pm)); - std::cout << "order of discovery: "; - for (int i = 0; i < N; ++i) - std::cout << name[discover_order[i]] << " "; - std::cout << std::endl; + std::cout << "order of discovery: "; + for (int i = 0; i < N; ++i) + std::cout << name[discover_order[i]] << " "; + std::cout << std::endl; - return EXIT_SUCCESS; + return EXIT_SUCCESS; } diff --git a/example/bfs-example2.cpp b/example/bfs-example2.cpp index bc5d92abd..564c70313 100644 --- a/example/bfs-example2.cpp +++ b/example/bfs-example2.cpp @@ -1,5 +1,5 @@ //======================================================================= -// Copyright 2001 Jeremy G. Siek, Andrew Lumsdaine, Lie-Quan Lee, +// Copyright 2001 Jeremy G. Siek, Andrew Lumsdaine, Lie-Quan Lee, // // Distributed under the Boost Software License, Version 1.0. (See // accompanying file LICENSE_1_0.txt or copy at @@ -14,95 +14,106 @@ #include using namespace boost; -template < typename TimeMap > class bfs_time_visitor:public default_bfs_visitor { - typedef typename property_traits < TimeMap >::value_type T; +template < typename TimeMap > +class bfs_time_visitor : public default_bfs_visitor +{ + typedef typename property_traits< TimeMap >::value_type T; + public: - bfs_time_visitor(TimeMap tmap, T & t):m_timemap(tmap), m_time(t) { } - template < typename Vertex, typename Graph > - void discover_vertex(Vertex u, const Graph & g) const - { - put(m_timemap, u, m_time++); - } - TimeMap m_timemap; - T & m_time; + bfs_time_visitor(TimeMap tmap, T& t) : m_timemap(tmap), m_time(t) {} + template < typename Vertex, typename Graph > + void discover_vertex(Vertex u, const Graph& g) const + { + put(m_timemap, u, m_time++); + } + TimeMap m_timemap; + T& m_time; }; - -struct VertexProps { - boost::default_color_type color; - std::size_t discover_time; - unsigned int index; +struct VertexProps +{ + boost::default_color_type color; + std::size_t discover_time; + unsigned int index; }; -int -main() +int main() { - using namespace boost; - // Select the graph type we wish to use - typedef adjacency_list < listS, listS, undirectedS, - VertexProps> graph_t; - // Set up the vertex IDs and names - enum { r, s, t, u, v, w, x, y, N }; - const char *name = "rstuvwxy"; - // Specify the edges in the graph - typedef std::pair < int, int >E; - E edge_array[] = { E(r, s), E(r, v), E(s, w), E(w, r), E(w, t), - E(w, x), E(x, t), E(t, u), E(x, y), E(u, y) - }; - // Create the graph object - const int n_edges = sizeof(edge_array) / sizeof(E); + using namespace boost; + // Select the graph type we wish to use + typedef adjacency_list< listS, listS, undirectedS, VertexProps > graph_t; + // Set up the vertex IDs and names + enum + { + r, + s, + t, + u, + v, + w, + x, + y, + N + }; + const char* name = "rstuvwxy"; + // Specify the edges in the graph + typedef std::pair< int, int > E; + E edge_array[] = { E(r, s), E(r, v), E(s, w), E(w, r), E(w, t), E(w, x), + E(x, t), E(t, u), E(x, y), E(u, y) }; + // Create the graph object + const int n_edges = sizeof(edge_array) / sizeof(E); #if defined(BOOST_MSVC) && BOOST_MSVC <= 1300 - // VC++ has trouble with the edge iterator constructor - graph_t g; - std::vector::vertex_descriptor> verts; - for (std::size_t i = 0; i < N; ++i) - verts.push_back(add_vertex(g)); - for (std::size_t j = 0; j < n_edges; ++j) - add_edge(verts[edge_array[j].first], verts[edge_array[j].second], g); + // VC++ has trouble with the edge iterator constructor + graph_t g; + std::vector< graph_traits< graph_t >::vertex_descriptor > verts; + for (std::size_t i = 0; i < N; ++i) + verts.push_back(add_vertex(g)); + for (std::size_t j = 0; j < n_edges; ++j) + add_edge(verts[edge_array[j].first], verts[edge_array[j].second], g); #else - typedef graph_traits::vertices_size_type v_size_t; - graph_t g(edge_array, edge_array + n_edges, v_size_t(N)); + typedef graph_traits< graph_t >::vertices_size_type v_size_t; + graph_t g(edge_array, edge_array + n_edges, v_size_t(N)); #endif - // Typedefs - typedef graph_traits::vertices_size_type Size; + // Typedefs + typedef graph_traits< graph_t >::vertices_size_type Size; - Size time = 0; - typedef property_map::type dtime_map_t; - dtime_map_t dtime_map = get(&VertexProps::discover_time, g); - bfs_time_visitor < dtime_map_t > vis(dtime_map, time); - breadth_first_search(g, vertex(s, g), color_map(get(&VertexProps::color, g)). - visitor(vis)); + Size time = 0; + typedef property_map< graph_t, std::size_t VertexProps::* >::type + dtime_map_t; + dtime_map_t dtime_map = get(&VertexProps::discover_time, g); + bfs_time_visitor< dtime_map_t > vis(dtime_map, time); + breadth_first_search( + g, vertex(s, g), color_map(get(&VertexProps::color, g)).visitor(vis)); - // a vector to hold the discover time property for each vertex - std::vector < Size > dtime(num_vertices(g)); - typedef - iterator_property_map::iterator, - property_map::type> - dtime_pm_type; - graph_traits::vertex_iterator vi, vi_end; - std::size_t c = 0; - for (boost::tie(vi, vi_end) = vertices(g); vi != vi_end; ++vi, ++c) { - dtime[c] = dtime_map[*vi]; - put(&VertexProps::index, g, *vi, c); - } - dtime_pm_type dtime_pm(dtime.begin(), get(&VertexProps::index, g)); + // a vector to hold the discover time property for each vertex + std::vector< Size > dtime(num_vertices(g)); + typedef iterator_property_map< std::vector< Size >::iterator, + property_map< graph_t, unsigned int VertexProps::* >::type > + dtime_pm_type; + graph_traits< graph_t >::vertex_iterator vi, vi_end; + std::size_t c = 0; + for (boost::tie(vi, vi_end) = vertices(g); vi != vi_end; ++vi, ++c) + { + dtime[c] = dtime_map[*vi]; + put(&VertexProps::index, g, *vi, c); + } + dtime_pm_type dtime_pm(dtime.begin(), get(&VertexProps::index, g)); - // Use std::sort to order the vertices by their discover time - std::vector::vertices_size_type > discover_order(N); - integer_range < int >range(0, N); - std::copy(range.begin(), range.end(), discover_order.begin()); - std::sort(discover_order.begin(), discover_order.end(), - make_indirect_cmp( - std::less(), - make_iterator_property_map( - dtime.begin(), - typed_identity_property_map()))); + // Use std::sort to order the vertices by their discover time + std::vector< graph_traits< graph_t >::vertices_size_type > discover_order( + N); + integer_range< int > range(0, N); + std::copy(range.begin(), range.end(), discover_order.begin()); + std::sort(discover_order.begin(), discover_order.end(), + make_indirect_cmp(std::less< Size >(), + make_iterator_property_map( + dtime.begin(), typed_identity_property_map< std::size_t >()))); - std::cout << "order of discovery: "; - for (int i = 0; i < N; ++i) - std::cout << name[discover_order[i]] << " "; - std::cout << std::endl; + std::cout << "order of discovery: "; + for (int i = 0; i < N; ++i) + std::cout << name[discover_order[i]] << " "; + std::cout << std::endl; - return EXIT_SUCCESS; + return EXIT_SUCCESS; } diff --git a/example/bfs-name-printer.cpp b/example/bfs-name-printer.cpp index aab408d90..bc0da3bc3 100644 --- a/example/bfs-name-printer.cpp +++ b/example/bfs-name-printer.cpp @@ -1,5 +1,5 @@ //======================================================================= -// Copyright 2001 Jeremy G. Siek, Andrew Lumsdaine, Lie-Quan Lee, +// Copyright 2001 Jeremy G. Siek, Andrew Lumsdaine, Lie-Quan Lee, // // Distributed under the Boost Software License, Version 1.0. (See // accompanying file LICENSE_1_0.txt or copy at @@ -12,83 +12,81 @@ #include using namespace boost; -template -void -build_router_network(Graph & g, VertexNameMap name_map, - TransDelayMap delay_map) +template < typename Graph, typename VertexNameMap, typename TransDelayMap > +void build_router_network( + Graph& g, VertexNameMap name_map, TransDelayMap delay_map) { - typename graph_traits < Graph >::vertex_descriptor a, b, c, d, e; - a = add_vertex(g); - name_map[a] = 'a'; - b = add_vertex(g); - name_map[b] = 'b'; - c = add_vertex(g); - name_map[c] = 'c'; - d = add_vertex(g); - name_map[d] = 'd'; - e = add_vertex(g); - name_map[e] = 'e'; + typename graph_traits< Graph >::vertex_descriptor a, b, c, d, e; + a = add_vertex(g); + name_map[a] = 'a'; + b = add_vertex(g); + name_map[b] = 'b'; + c = add_vertex(g); + name_map[c] = 'c'; + d = add_vertex(g); + name_map[d] = 'd'; + e = add_vertex(g); + name_map[e] = 'e'; - typename graph_traits::edge_descriptor ed; - bool inserted; + typename graph_traits< Graph >::edge_descriptor ed; + bool inserted; - boost::tie(ed, inserted) = add_edge(a, b, g); - delay_map[ed] = 1.2; - boost::tie(ed, inserted) = add_edge(a, d, g); - delay_map[ed] = 4.5; - boost::tie(ed, inserted) = add_edge(b, d, g); - delay_map[ed] = 1.8; - boost::tie(ed, inserted) = add_edge(c, a, g); - delay_map[ed] = 2.6; - boost::tie(ed, inserted) = add_edge(c, e, g); - delay_map[ed] = 5.2; - boost::tie(ed, inserted) = add_edge(d, c, g); - delay_map[ed] = 0.4; - boost::tie(ed, inserted) = add_edge(d, e, g); - delay_map[ed] = 3.3; + boost::tie(ed, inserted) = add_edge(a, b, g); + delay_map[ed] = 1.2; + boost::tie(ed, inserted) = add_edge(a, d, g); + delay_map[ed] = 4.5; + boost::tie(ed, inserted) = add_edge(b, d, g); + delay_map[ed] = 1.8; + boost::tie(ed, inserted) = add_edge(c, a, g); + delay_map[ed] = 2.6; + boost::tie(ed, inserted) = add_edge(c, e, g); + delay_map[ed] = 5.2; + boost::tie(ed, inserted) = add_edge(d, c, g); + delay_map[ed] = 0.4; + boost::tie(ed, inserted) = add_edge(d, e, g); + delay_map[ed] = 3.3; } - -template -class bfs_name_printer : public default_bfs_visitor { - // inherit default (empty) event point actions +template < typename VertexNameMap > +class bfs_name_printer : public default_bfs_visitor +{ + // inherit default (empty) event point actions public: - bfs_name_printer(VertexNameMap n_map) : m_name_map(n_map) { - } - template - void discover_vertex(Vertex u, const Graph &) const - { - std::cout << get(m_name_map, u) << ' '; - } + bfs_name_printer(VertexNameMap n_map) : m_name_map(n_map) {} + template < typename Vertex, typename Graph > + void discover_vertex(Vertex u, const Graph&) const + { + std::cout << get(m_name_map, u) << ' '; + } + private: - VertexNameMap m_name_map; + VertexNameMap m_name_map; }; -struct VP { - char name; +struct VP +{ + char name; }; -struct EP { - double weight; +struct EP +{ + double weight; }; - -int -main() +int main() { - typedef adjacency_list < listS, vecS, directedS, VP, EP> graph_t; - graph_t g; - - property_map::type name_map = get(&VP::name, g); - property_map::type delay_map = get(&EP::weight, g); + typedef adjacency_list< listS, vecS, directedS, VP, EP > graph_t; + graph_t g; - build_router_network(g, name_map, delay_map); + property_map< graph_t, char VP::* >::type name_map = get(&VP::name, g); + property_map< graph_t, double EP::* >::type delay_map = get(&EP::weight, g); - typedef property_map::type VertexNameMap; - graph_traits::vertex_descriptor a = *vertices(g).first; - bfs_name_printer vis(name_map); - std::cout << "BFS vertex discover order: "; - breadth_first_search(g, a, visitor(vis)); - std::cout << std::endl; + build_router_network(g, name_map, delay_map); + typedef property_map< graph_t, char VP::* >::type VertexNameMap; + graph_traits< graph_t >::vertex_descriptor a = *vertices(g).first; + bfs_name_printer< VertexNameMap > vis(name_map); + std::cout << "BFS vertex discover order: "; + breadth_first_search(g, a, visitor(vis)); + std::cout << std::endl; } diff --git a/example/bfs.cpp b/example/bfs.cpp index 1f34c1552..1c9ddc5d7 100644 --- a/example/bfs.cpp +++ b/example/bfs.cpp @@ -21,7 +21,7 @@ #include /* - + This examples shows how to use the breadth_first_search() GGCL algorithm, specifically the 3 argument variant of bfs that assumes the graph has a color property (property) stored internally. @@ -37,17 +37,17 @@ Sample Output: - 0 --> 2 - 1 --> 1 3 4 - 2 --> 1 3 4 - 3 --> 1 4 - 4 --> 0 1 - 0 --> 2 - 1 --> 1 3 4 - 2 --> 1 3 4 - 3 --> 1 4 - 4 --> 0 1 - distances: 0 2 1 2 2 + 0 --> 2 + 1 --> 1 3 4 + 2 --> 1 3 4 + 3 --> 1 4 + 4 --> 0 1 + 0 --> 2 + 1 --> 1 3 4 + 2 --> 1 3 4 + 3 --> 1 4 + 4 --> 0 1 + distances: 0 2 1 2 2 parent[0] = 0 parent[1] = 2 parent[2] = 0 @@ -56,105 +56,104 @@ */ -template -struct print_parent { - print_parent(const ParentDecorator& p_) : p(p_) { } - template - void operator()(const Vertex& v) const { - std::cout << "parent[" << v << "] = " << p[v] << std::endl; - } - ParentDecorator p; +template < class ParentDecorator > struct print_parent +{ + print_parent(const ParentDecorator& p_) : p(p_) {} + template < class Vertex > void operator()(const Vertex& v) const + { + std::cout << "parent[" << v << "] = " << p[v] << std::endl; + } + ParentDecorator p; }; - -template -struct graph_copier - : public boost::base_visitor > +template < class NewGraph, class Tag > +struct graph_copier +: public boost::base_visitor< graph_copier< NewGraph, Tag > > { - typedef Tag event_filter; + typedef Tag event_filter; - graph_copier(NewGraph& graph) : new_g(graph) { } + graph_copier(NewGraph& graph) : new_g(graph) {} + + template < class Edge, class Graph > void operator()(Edge e, Graph& g) + { + boost::add_edge(boost::source(e, g), boost::target(e, g), new_g); + } - template - void operator()(Edge e, Graph& g) { - boost::add_edge(boost::source(e, g), boost::target(e, g), new_g); - } private: - NewGraph& new_g; + NewGraph& new_g; }; -template -inline graph_copier -copy_graph(NewGraph& g, Tag) { - return graph_copier(g); +template < class NewGraph, class Tag > +inline graph_copier< NewGraph, Tag > copy_graph(NewGraph& g, Tag) +{ + return graph_copier< NewGraph, Tag >(g); } -int main(int , char* []) +int main(int, char*[]) { - typedef boost::adjacency_list< - boost::mapS, boost::vecS, boost::bidirectionalS, - boost::property > > > - > Graph; - - Graph G(5); - boost::add_edge(0, 2, G); - boost::add_edge(1, 1, G); - boost::add_edge(1, 3, G); - boost::add_edge(1, 4, G); - boost::add_edge(2, 1, G); - boost::add_edge(2, 3, G); - boost::add_edge(2, 4, G); - boost::add_edge(3, 1, G); - boost::add_edge(3, 4, G); - boost::add_edge(4, 0, G); - boost::add_edge(4, 1, G); - - typedef Graph::vertex_descriptor Vertex; - - Graph G_copy(5); - // Array to store predecessor (parent) of each vertex. This will be - // used as a Decorator (actually, its iterator will be). - std::vector p(boost::num_vertices(G)); - // VC++ version of std::vector has no ::pointer, so - // I use ::value_type* instead. - typedef std::vector::value_type* Piter; - - // Array to store distances from the source to each vertex . We use - // a built-in array here just for variety. This will also be used as - // a Decorator. - boost::graph_traits::vertices_size_type d[5]; - std::fill_n(d, 5, 0); - - // The source vertex - Vertex s = *(boost::vertices(G).first); - p[s] = s; - boost::breadth_first_search - (G, s, - boost::visitor(boost::make_bfs_visitor - (std::make_pair(boost::record_distances(d, boost::on_tree_edge()), - std::make_pair - (boost::record_predecessors(&p[0], - boost::on_tree_edge()), - copy_graph(G_copy, boost::on_examine_edge())))) )); - - boost::print_graph(G); - boost::print_graph(G_copy); - - if (boost::num_vertices(G) < 11) { - std::cout << "distances: "; + typedef boost::adjacency_list< boost::mapS, boost::vecS, + boost::bidirectionalS, + boost::property< boost::vertex_color_t, boost::default_color_type, + boost::property< boost::vertex_degree_t, int, + boost::property< boost::vertex_in_degree_t, int, + boost::property< boost::vertex_out_degree_t, int > > > > > + Graph; + + Graph G(5); + boost::add_edge(0, 2, G); + boost::add_edge(1, 1, G); + boost::add_edge(1, 3, G); + boost::add_edge(1, 4, G); + boost::add_edge(2, 1, G); + boost::add_edge(2, 3, G); + boost::add_edge(2, 4, G); + boost::add_edge(3, 1, G); + boost::add_edge(3, 4, G); + boost::add_edge(4, 0, G); + boost::add_edge(4, 1, G); + + typedef Graph::vertex_descriptor Vertex; + + Graph G_copy(5); + // Array to store predecessor (parent) of each vertex. This will be + // used as a Decorator (actually, its iterator will be). + std::vector< Vertex > p(boost::num_vertices(G)); + // VC++ version of std::vector has no ::pointer, so + // I use ::value_type* instead. + typedef std::vector< Vertex >::value_type* Piter; + + // Array to store distances from the source to each vertex . We use + // a built-in array here just for variety. This will also be used as + // a Decorator. + boost::graph_traits< Graph >::vertices_size_type d[5]; + std::fill_n(d, 5, 0); + + // The source vertex + Vertex s = *(boost::vertices(G).first); + p[s] = s; + boost::breadth_first_search(G, s, + boost::visitor(boost::make_bfs_visitor( + std::make_pair(boost::record_distances(d, boost::on_tree_edge()), + std::make_pair( + boost::record_predecessors(&p[0], boost::on_tree_edge()), + copy_graph(G_copy, boost::on_examine_edge())))))); + + boost::print_graph(G); + boost::print_graph(G_copy); + + if (boost::num_vertices(G) < 11) + { + std::cout << "distances: "; #ifdef BOOST_OLD_STREAM_ITERATORS - std::copy(d, d + 5, std::ostream_iterator(std::cout, " ")); + std::copy(d, d + 5, std::ostream_iterator< int, char >(std::cout, " ")); #else - std::copy(d, d + 5, std::ostream_iterator(std::cout, " ")); + std::copy(d, d + 5, std::ostream_iterator< int >(std::cout, " ")); #endif - std::cout << std::endl; + std::cout << std::endl; - std::for_each(boost::vertices(G).first, boost::vertices(G).second, - print_parent(&p[0])); - } + std::for_each(boost::vertices(G).first, boost::vertices(G).second, + print_parent< Piter >(&p[0])); + } - return 0; + return 0; } diff --git a/example/bfs.expected b/example/bfs.expected index c58f0fb31..825341197 100644 --- a/example/bfs.expected +++ b/example/bfs.expected @@ -1,14 +1,14 @@ -0 --> 2 -1 --> 1 3 4 -2 --> 1 3 4 -3 --> 1 4 -4 --> 0 1 -0 --> 2 -1 --> 1 3 4 -2 --> 1 3 4 -3 --> 1 4 -4 --> 0 1 -distances: 0 2 1 2 2 +0 --> 2 +1 --> 1 3 4 +2 --> 1 3 4 +3 --> 1 4 +4 --> 0 1 +0 --> 2 +1 --> 1 3 4 +2 --> 1 3 4 +3 --> 1 4 +4 --> 0 1 +distances: 0 2 1 2 2 parent[0] = 0 parent[1] = 2 parent[2] = 0 diff --git a/example/bfs_basics.expected b/example/bfs_basics.expected index 6fc6c2dbd..4a914d1ff 100644 --- a/example/bfs_basics.expected +++ b/example/bfs_basics.expected @@ -1,2 +1,2 @@ -order of discovery: s r w v t x u y -order of finish: s r w v t x u y +order of discovery: s r w v t x u y +order of finish: s r w v t x u y diff --git a/example/bfs_neighbor.cpp b/example/bfs_neighbor.cpp index 050362f60..7beb9fa5d 100644 --- a/example/bfs_neighbor.cpp +++ b/example/bfs_neighbor.cpp @@ -21,7 +21,7 @@ #include /* - + This examples shows how to use the breadth_first_search() GGCL algorithm, specifically the 3 argument variant of bfs that assumes the graph has a color property (property) stored internally. @@ -37,12 +37,12 @@ Sample Output: - 0 --> 2 - 1 --> 1 3 4 - 2 --> 1 3 4 - 3 --> 1 4 - 4 --> 0 1 - distances: 1 2 1 2 0 + 0 --> 2 + 1 --> 1 3 4 + 2 --> 1 3 4 + 3 --> 1 4 + 4 --> 0 1 + distances: 1 2 1 2 0 parent[0] = 4 parent[1] = 2 parent[2] = 0 @@ -51,101 +51,100 @@ */ -template -struct print_parent { - print_parent(const ParentDecorator& p_) : p(p_) { } - template - void operator()(const Vertex& v) const { - std::cout << "parent[" << v << "] = " << p[v] << std::endl; - } - ParentDecorator p; +template < class ParentDecorator > struct print_parent +{ + print_parent(const ParentDecorator& p_) : p(p_) {} + template < class Vertex > void operator()(const Vertex& v) const + { + std::cout << "parent[" << v << "] = " << p[v] << std::endl; + } + ParentDecorator p; }; - -template -struct graph_copier - : public boost::base_visitor > +template < class NewGraph, class Tag > +struct graph_copier +: public boost::base_visitor< graph_copier< NewGraph, Tag > > { - typedef Tag event_filter; + typedef Tag event_filter; - graph_copier(NewGraph& graph) : new_g(graph) { } + graph_copier(NewGraph& graph) : new_g(graph) {} + + template < class Edge, class Graph > void operator()(Edge e, Graph& g) + { + boost::add_edge(boost::source(e, g), boost::target(e, g), new_g); + } - template - void operator()(Edge e, Graph& g) { - boost::add_edge(boost::source(e, g), boost::target(e, g), new_g); - } private: - NewGraph& new_g; + NewGraph& new_g; }; -template -inline graph_copier -copy_graph(NewGraph& g, Tag) { - return graph_copier(g); +template < class NewGraph, class Tag > +inline graph_copier< NewGraph, Tag > copy_graph(NewGraph& g, Tag) +{ + return graph_copier< NewGraph, Tag >(g); } -int main(int , char* []) +int main(int, char*[]) { - typedef boost::adjacency_list< - boost::mapS, boost::vecS, boost::bidirectionalS, - boost::property > > > - > Graph; - - Graph G(5); - boost::add_edge(0, 2, G); - boost::add_edge(1, 1, G); - boost::add_edge(1, 3, G); - boost::add_edge(1, 4, G); - boost::add_edge(2, 1, G); - boost::add_edge(2, 3, G); - boost::add_edge(2, 4, G); - boost::add_edge(3, 1, G); - boost::add_edge(3, 4, G); - boost::add_edge(4, 0, G); - boost::add_edge(4, 1, G); - - typedef Graph::vertex_descriptor Vertex; - - // Array to store predecessor (parent) of each vertex. This will be - // used as a Decorator (actually, its iterator will be). - std::vector p(boost::num_vertices(G)); - // VC++ version of std::vector has no ::pointer, so - // I use ::value_type* instead. - typedef std::vector::value_type* Piter; - - // Array to store distances from the source to each vertex . We use - // a built-in array here just for variety. This will also be used as - // a Decorator. - boost::graph_traits::vertices_size_type d[5]; - std::fill_n(d, 5, 0); - - // The source vertex - Vertex s = *(boost::vertices(G).first); - p[s] = s; - boost::neighbor_breadth_first_search - (G, s, - boost::visitor(boost::make_neighbor_bfs_visitor - (std::make_pair(boost::record_distances(d, boost::on_tree_edge()), - boost::record_predecessors(&p[0], - boost::on_tree_edge()))))); - - boost::print_graph(G); - - if (boost::num_vertices(G) < 11) { - std::cout << "distances: "; + typedef boost::adjacency_list< boost::mapS, boost::vecS, + boost::bidirectionalS, + boost::property< boost::vertex_color_t, boost::default_color_type, + boost::property< boost::vertex_degree_t, int, + boost::property< boost::vertex_in_degree_t, int, + boost::property< boost::vertex_out_degree_t, int > > > > > + Graph; + + Graph G(5); + boost::add_edge(0, 2, G); + boost::add_edge(1, 1, G); + boost::add_edge(1, 3, G); + boost::add_edge(1, 4, G); + boost::add_edge(2, 1, G); + boost::add_edge(2, 3, G); + boost::add_edge(2, 4, G); + boost::add_edge(3, 1, G); + boost::add_edge(3, 4, G); + boost::add_edge(4, 0, G); + boost::add_edge(4, 1, G); + + typedef Graph::vertex_descriptor Vertex; + + // Array to store predecessor (parent) of each vertex. This will be + // used as a Decorator (actually, its iterator will be). + std::vector< Vertex > p(boost::num_vertices(G)); + // VC++ version of std::vector has no ::pointer, so + // I use ::value_type* instead. + typedef std::vector< Vertex >::value_type* Piter; + + // Array to store distances from the source to each vertex . We use + // a built-in array here just for variety. This will also be used as + // a Decorator. + boost::graph_traits< Graph >::vertices_size_type d[5]; + std::fill_n(d, 5, 0); + + // The source vertex + Vertex s = *(boost::vertices(G).first); + p[s] = s; + boost::neighbor_breadth_first_search(G, s, + boost::visitor(boost::make_neighbor_bfs_visitor( + std::make_pair(boost::record_distances(d, boost::on_tree_edge()), + boost::record_predecessors(&p[0], boost::on_tree_edge()))))); + + boost::print_graph(G); + + if (boost::num_vertices(G) < 11) + { + std::cout << "distances: "; #ifdef BOOST_OLD_STREAM_ITERATORS - std::copy(d, d + 5, std::ostream_iterator(std::cout, " ")); + std::copy(d, d + 5, std::ostream_iterator< int, char >(std::cout, " ")); #else - std::copy(d, d + 5, std::ostream_iterator(std::cout, " ")); + std::copy(d, d + 5, std::ostream_iterator< int >(std::cout, " ")); #endif - std::cout << std::endl; + std::cout << std::endl; - std::for_each(boost::vertices(G).first, boost::vertices(G).second, - print_parent(&p[0])); - } + std::for_each(boost::vertices(G).first, boost::vertices(G).second, + print_parent< Piter >(&p[0])); + } - return 0; + return 0; } diff --git a/example/biconnected_components.cpp b/example/biconnected_components.cpp index 0406dcbab..8c1b58946 100644 --- a/example/biconnected_components.cpp +++ b/example/biconnected_components.cpp @@ -1,5 +1,5 @@ //======================================================================= -// Copyright 2001 Jeremy G. Siek, Andrew Lumsdaine, Lie-Quan Lee, +// Copyright 2001 Jeremy G. Siek, Andrew Lumsdaine, Lie-Quan Lee, // // Distributed under the Boost Software License, Version 1.0. (See // accompanying file LICENSE_1_0.txt or copy at @@ -15,59 +15,61 @@ namespace boost { - struct edge_component_t - { +struct edge_component_t +{ enum - { num = 555 }; + { + num = 555 + }; typedef edge_property_tag kind; - } - edge_component; +} edge_component; } -int -main() +int main() { - using namespace boost; - typedef adjacency_list < vecS, vecS, undirectedS, - no_property, property < edge_component_t, std::size_t > >graph_t; - typedef graph_traits < graph_t >::vertex_descriptor vertex_t; - graph_t g(9); - add_edge(0, 5, g); - add_edge(0, 1, g); - add_edge(0, 6, g); - add_edge(1, 2, g); - add_edge(1, 3, g); - add_edge(1, 4, g); - add_edge(2, 3, g); - add_edge(4, 5, g); - add_edge(6, 8, g); - add_edge(6, 7, g); - add_edge(7, 8, g); + using namespace boost; + typedef adjacency_list< vecS, vecS, undirectedS, no_property, + property< edge_component_t, std::size_t > > + graph_t; + typedef graph_traits< graph_t >::vertex_descriptor vertex_t; + graph_t g(9); + add_edge(0, 5, g); + add_edge(0, 1, g); + add_edge(0, 6, g); + add_edge(1, 2, g); + add_edge(1, 3, g); + add_edge(1, 4, g); + add_edge(2, 3, g); + add_edge(4, 5, g); + add_edge(6, 8, g); + add_edge(6, 7, g); + add_edge(7, 8, g); - property_map < graph_t, edge_component_t >::type - component = get(edge_component, g); + property_map< graph_t, edge_component_t >::type component + = get(edge_component, g); - std::size_t num_comps = biconnected_components(g, component); - std::cerr << "Found " << num_comps << " biconnected components.\n"; + std::size_t num_comps = biconnected_components(g, component); + std::cerr << "Found " << num_comps << " biconnected components.\n"; - std::vector art_points; - articulation_points(g, std::back_inserter(art_points)); - std::cerr << "Found " << art_points.size() << " articulation points.\n"; + std::vector< vertex_t > art_points; + articulation_points(g, std::back_inserter(art_points)); + std::cerr << "Found " << art_points.size() << " articulation points.\n"; - std::cout << "graph A {\n" << " node[shape=\"circle\"]\n"; + std::cout << "graph A {\n" + << " node[shape=\"circle\"]\n"; - for (std::size_t i = 0; i < art_points.size(); ++i) { - std::cout << (char)(art_points[i] + 'A') - << " [ style=\"filled\", fillcolor=\"red\" ];" - << std::endl; - } + for (std::size_t i = 0; i < art_points.size(); ++i) + { + std::cout << (char)(art_points[i] + 'A') + << " [ style=\"filled\", fillcolor=\"red\" ];" << std::endl; + } - graph_traits < graph_t >::edge_iterator ei, ei_end; - for (boost::tie(ei, ei_end) = edges(g); ei != ei_end; ++ei) - std::cout << (char)(source(*ei, g) + 'A') << " -- " - << (char)(target(*ei, g) + 'A') - << "[label=\"" << component[*ei] << "\"]\n"; - std::cout << "}\n"; + graph_traits< graph_t >::edge_iterator ei, ei_end; + for (boost::tie(ei, ei_end) = edges(g); ei != ei_end; ++ei) + std::cout << (char)(source(*ei, g) + 'A') << " -- " + << (char)(target(*ei, g) + 'A') << "[label=\"" + << component[*ei] << "\"]\n"; + std::cout << "}\n"; - return 0; + return 0; } diff --git a/example/bipartite_example.cpp b/example/bipartite_example.cpp index c8e62ad26..99ac316ff 100644 --- a/example/bipartite_example.cpp +++ b/example/bipartite_example.cpp @@ -18,98 +18,108 @@ using namespace boost; /// Example to test for bipartiteness and print the certificates. -template -void print_bipartite (const Graph& g) +template < typename Graph > void print_bipartite(const Graph& g) { - typedef graph_traits traits; - typename traits::vertex_iterator vertex_iter, vertex_end; + typedef graph_traits< Graph > traits; + typename traits::vertex_iterator vertex_iter, vertex_end; - /// Most simple interface just tests for bipartiteness. + /// Most simple interface just tests for bipartiteness. - bool bipartite = is_bipartite (g); + bool bipartite = is_bipartite(g); - if (bipartite) - { - typedef std::vector partition_t; - typedef typename property_map ::type index_map_t; - typedef iterator_property_map partition_map_t; - - partition_t partition (num_vertices (g)); - partition_map_t partition_map (partition.begin (), get (vertex_index, g)); - - /// A second interface yields a bipartition in a color map, if the graph is bipartite. - - is_bipartite (g, get (vertex_index, g), partition_map); - - for (boost::tie (vertex_iter, vertex_end) = vertices (g); vertex_iter != vertex_end; ++vertex_iter) + if (bipartite) { - std::cout << "Vertex " << *vertex_iter << " has color " << (get (partition_map, *vertex_iter) == color_traits < - default_color_type>::white () ? "white" : "black") << std::endl; + typedef std::vector< default_color_type > partition_t; + typedef + typename property_map< Graph, vertex_index_t >::type index_map_t; + typedef iterator_property_map< partition_t::iterator, index_map_t > + partition_map_t; + + partition_t partition(num_vertices(g)); + partition_map_t partition_map(partition.begin(), get(vertex_index, g)); + + /// A second interface yields a bipartition in a color map, if the graph + /// is bipartite. + + is_bipartite(g, get(vertex_index, g), partition_map); + + for (boost::tie(vertex_iter, vertex_end) = vertices(g); + vertex_iter != vertex_end; ++vertex_iter) + { + std::cout + << "Vertex " << *vertex_iter << " has color " + << (get(partition_map, *vertex_iter) + == color_traits< default_color_type >::white() + ? "white" + : "black") + << std::endl; + } } - } - else - { - typedef std::vector vertex_vector_t; - vertex_vector_t odd_cycle; + else + { + typedef std::vector< typename traits::vertex_descriptor > + vertex_vector_t; + vertex_vector_t odd_cycle; - /// A third interface yields an odd-cycle if the graph is not bipartite. + /// A third interface yields an odd-cycle if the graph is not bipartite. - find_odd_cycle (g, get (vertex_index, g), std::back_inserter (odd_cycle)); + find_odd_cycle(g, get(vertex_index, g), std::back_inserter(odd_cycle)); - std::cout << "Odd cycle consists of the vertices:"; - for (size_t i = 0; i < odd_cycle.size (); ++i) - { - std::cout << " " << odd_cycle[i]; + std::cout << "Odd cycle consists of the vertices:"; + for (size_t i = 0; i < odd_cycle.size(); ++i) + { + std::cout << " " << odd_cycle[i]; + } + std::cout << std::endl; } - std::cout << std::endl; - } } -int main (int argc, char **argv) +int main(int argc, char** argv) { - typedef adjacency_list vector_graph_t; - typedef std::pair E; - - /** - * Create the graph drawn below. - * - * 0 - 1 - 2 - * | | - * 3 - 4 - 5 - 6 - * / \ / - * | 7 - * | | - * 8 - 9 - 10 - **/ - - E bipartite_edges[] = { E (0, 1), E (0, 4), E (1, 2), E (2, 6), E (3, 4), E (3, 8), E (4, 5), E (4, 7), E (5, 6), E ( - 6, 7), E (7, 10), E (8, 9), E (9, 10) }; - vector_graph_t bipartite_vector_graph (&bipartite_edges[0], - &bipartite_edges[0] + sizeof(bipartite_edges) / sizeof(E), 11); - - /** - * Create the graph drawn below. - * - * 2 - 1 - 0 - * | | - * 3 - 6 - 5 - 4 - * / \ / - * | 7 - * | / - * 8 ---- 9 - * - **/ - - E non_bipartite_edges[] = { E (0, 1), E (0, 4), E (1, 2), E (2, 6), E (3, 6), E (3, 8), E (4, 5), E (4, 7), E (5, 6), - E (6, 7), E (7, 9), E (8, 9) }; - vector_graph_t non_bipartite_vector_graph (&non_bipartite_edges[0], &non_bipartite_edges[0] - + sizeof(non_bipartite_edges) / sizeof(E), 10); - - /// Call test routine for a bipartite and a non-bipartite graph. - - print_bipartite (bipartite_vector_graph); - - print_bipartite (non_bipartite_vector_graph); - - return 0; + typedef adjacency_list< vecS, vecS, undirectedS > vector_graph_t; + typedef std::pair< int, int > E; + + /** + * Create the graph drawn below. + * + * 0 - 1 - 2 + * | | + * 3 - 4 - 5 - 6 + * / \ / + * | 7 + * | | + * 8 - 9 - 10 + **/ + + E bipartite_edges[] + = { E(0, 1), E(0, 4), E(1, 2), E(2, 6), E(3, 4), E(3, 8), E(4, 5), + E(4, 7), E(5, 6), E(6, 7), E(7, 10), E(8, 9), E(9, 10) }; + vector_graph_t bipartite_vector_graph(&bipartite_edges[0], + &bipartite_edges[0] + sizeof(bipartite_edges) / sizeof(E), 11); + + /** + * Create the graph drawn below. + * + * 2 - 1 - 0 + * | | + * 3 - 6 - 5 - 4 + * / \ / + * | 7 + * | / + * 8 ---- 9 + * + **/ + + E non_bipartite_edges[] = { E(0, 1), E(0, 4), E(1, 2), E(2, 6), E(3, 6), + E(3, 8), E(4, 5), E(4, 7), E(5, 6), E(6, 7), E(7, 9), E(8, 9) }; + vector_graph_t non_bipartite_vector_graph(&non_bipartite_edges[0], + &non_bipartite_edges[0] + sizeof(non_bipartite_edges) / sizeof(E), 10); + + /// Call test routine for a bipartite and a non-bipartite graph. + + print_bipartite(bipartite_vector_graph); + + print_bipartite(non_bipartite_vector_graph); + + return 0; } diff --git a/example/boost_web_graph.cpp b/example/boost_web_graph.cpp index 04ef2187f..3d640c8df 100644 --- a/example/boost_web_graph.cpp +++ b/example/boost_web_graph.cpp @@ -19,195 +19,202 @@ #include #include - -template +template < class Distance > class calc_distance_visitor : public boost::bfs_visitor<> { public: - calc_distance_visitor(Distance d) : distance(d) { } - - template - void tree_edge(typename boost::graph_traits::edge_descriptor e, - Graph& g) - { - typename boost::graph_traits::vertex_descriptor u, v; - u = boost::source(e, g); - v = boost::target(e, g); - distance[v] = distance[u] + 1; - } + calc_distance_visitor(Distance d) : distance(d) {} + + template < class Graph > + void tree_edge( + typename boost::graph_traits< Graph >::edge_descriptor e, Graph& g) + { + typename boost::graph_traits< Graph >::vertex_descriptor u, v; + u = boost::source(e, g); + v = boost::target(e, g); + distance[v] = distance[u] + 1; + } + private: - Distance distance; + Distance distance; }; - -template +template < class VertexNameMap, class DistanceMap > class print_tree_visitor : public boost::dfs_visitor<> { public: - print_tree_visitor(VertexNameMap n, DistanceMap d) : name(n), distance(d) { } - template - void - discover_vertex(typename boost::graph_traits::vertex_descriptor v, - Graph&) - { - typedef typename boost::property_traits::value_type Dist; - // indentation based on depth - for (Dist i = 0; i < distance[v]; ++i) - std::cout << " "; - std::cout << name[v] << std::endl; - } - - template - void tree_edge(typename boost::graph_traits::edge_descriptor e, - Graph& g) - { - distance[boost::target(e, g)] = distance[boost::source(e, g)] + 1; - } + print_tree_visitor(VertexNameMap n, DistanceMap d) : name(n), distance(d) {} + template < class Graph > + void discover_vertex( + typename boost::graph_traits< Graph >::vertex_descriptor v, Graph&) + { + typedef typename boost::property_traits< DistanceMap >::value_type Dist; + // indentation based on depth + for (Dist i = 0; i < distance[v]; ++i) + std::cout << " "; + std::cout << name[v] << std::endl; + } + + template < class Graph > + void tree_edge( + typename boost::graph_traits< Graph >::edge_descriptor e, Graph& g) + { + distance[boost::target(e, g)] = distance[boost::source(e, g)] + 1; + } private: - VertexNameMap name; - DistanceMap distance; + VertexNameMap name; + DistanceMap distance; }; -int -main(int argc, const char** argv) +int main(int argc, const char** argv) { - using namespace boost; - - std::ifstream datafile(argc >= 2 ? argv[1] : "./boost_web.dat"); - if (!datafile) { - std::cerr << "No ./boost_web.dat file" << std::endl; - return -1; - } - - //=========================================================================== - // Declare the graph type and object, and some property maps. - - typedef adjacency_list >, - property > - > Graph; - - typedef graph_traits Traits; - typedef Traits::vertex_descriptor Vertex; - typedef Traits::edge_descriptor Edge; - - typedef std::map NameVertexMap; - NameVertexMap name2vertex; - Graph g; - - typedef property_map::type NameMap; - NameMap node_name = get(vertex_name, g); - property_map::type link_name = get(edge_name, g); - - //=========================================================================== - // Read the data file and construct the graph. - - std::string line; - while (std::getline(datafile,line)) { - - std::list line_toks; - boost::stringtok(line_toks, line, "|"); - - NameVertexMap::iterator pos; - bool inserted; - Vertex u, v; - - std::list::iterator i = line_toks.begin(); - - boost::tie(pos, inserted) = name2vertex.insert(std::make_pair(*i, Vertex())); - if (inserted) { - u = add_vertex(g); - put(node_name, u, *i); - pos->second = u; - } else - u = pos->second; - ++i; - - std::string hyperlink_name = *i++; - - boost::tie(pos, inserted) = name2vertex.insert(std::make_pair(*i, Vertex())); - if (inserted) { - v = add_vertex(g); - put(node_name, v, *i); - pos->second = v; - } else - v = pos->second; - - Edge e; - boost::tie(e, inserted) = add_edge(u, v, g); - if (inserted) { - put(link_name, e, hyperlink_name); + using namespace boost; + + std::ifstream datafile(argc >= 2 ? argv[1] : "./boost_web.dat"); + if (!datafile) + { + std::cerr << "No ./boost_web.dat file" << std::endl; + return -1; + } + + //=========================================================================== + // Declare the graph type and object, and some property maps. + + typedef adjacency_list< vecS, vecS, directedS, + property< vertex_name_t, std::string, + property< vertex_color_t, default_color_type > >, + property< edge_name_t, std::string, property< edge_weight_t, int > > > + Graph; + + typedef graph_traits< Graph > Traits; + typedef Traits::vertex_descriptor Vertex; + typedef Traits::edge_descriptor Edge; + + typedef std::map< std::string, Vertex > NameVertexMap; + NameVertexMap name2vertex; + Graph g; + + typedef property_map< Graph, vertex_name_t >::type NameMap; + NameMap node_name = get(vertex_name, g); + property_map< Graph, edge_name_t >::type link_name = get(edge_name, g); + + //=========================================================================== + // Read the data file and construct the graph. + + std::string line; + while (std::getline(datafile, line)) + { + + std::list< std::string > line_toks; + boost::stringtok(line_toks, line, "|"); + + NameVertexMap::iterator pos; + bool inserted; + Vertex u, v; + + std::list< std::string >::iterator i = line_toks.begin(); + + boost::tie(pos, inserted) + = name2vertex.insert(std::make_pair(*i, Vertex())); + if (inserted) + { + u = add_vertex(g); + put(node_name, u, *i); + pos->second = u; + } + else + u = pos->second; + ++i; + + std::string hyperlink_name = *i++; + + boost::tie(pos, inserted) + = name2vertex.insert(std::make_pair(*i, Vertex())); + if (inserted) + { + v = add_vertex(g); + put(node_name, v, *i); + pos->second = v; + } + else + v = pos->second; + + Edge e; + boost::tie(e, inserted) = add_edge(u, v, g); + if (inserted) + { + put(link_name, e, hyperlink_name); + } } - } - - //=========================================================================== - // Calculate the diameter of the graph. - - typedef Traits::vertices_size_type size_type; - typedef std::vector IntVector; - // Create N x N matrix for storing the shortest distances - // between each vertex. Initialize all distances to zero. - std::vector d_matrix(num_vertices(g), - IntVector(num_vertices(g), 0)); - - size_type i; - for (i = 0; i < num_vertices(g); ++i) { - calc_distance_visitor vis(&d_matrix[i][0]); - Traits::vertex_descriptor src = vertices(g).first[i]; - breadth_first_search(g, src, boost::visitor(vis)); - } - - size_type diameter = 0; - BOOST_USING_STD_MAX(); - for (i = 0; i < num_vertices(g); ++i) - diameter = max BOOST_PREVENT_MACRO_SUBSTITUTION(diameter, *std::max_element(d_matrix[i].begin(), - d_matrix[i].end())); - - std::cout << "The diameter of the boost web-site graph is " << diameter - << std::endl << std::endl; - - std::cout << "Number of clicks from the home page: " << std::endl; - Traits::vertex_iterator vi, vi_end; - for (boost::tie(vi, vi_end) = vertices(g); vi != vi_end; ++vi) - std::cout << d_matrix[0][*vi] << "\t" << node_name[*vi] << std::endl; - std::cout << std::endl; - - //=========================================================================== - // Print out the breadth-first search tree starting at the home page - - // Create storage for a mapping from vertices to their parents - std::vector parent(num_vertices(g)); - for (boost::tie(vi, vi_end) = vertices(g); vi != vi_end; ++vi) - parent[*vi] = *vi; - - // Do a BFS starting at the home page, recording the parent of each - // vertex (where parent is with respect to the search tree). - Traits::vertex_descriptor src = vertices(g).first[0]; - breadth_first_search - (g, src, - boost::visitor(make_bfs_visitor(record_predecessors(&parent[0], - on_tree_edge())))); - - // Add all the search tree edges into a new graph - Graph search_tree(num_vertices(g)); - boost::tie(vi, vi_end) = vertices(g); - ++vi; - for (; vi != vi_end; ++vi) - add_edge(parent[*vi], *vi, search_tree); - - std::cout << "The breadth-first search tree:" << std::endl; - - // Print out the search tree. We use DFS because it visits - // the tree nodes in the order that we want to print out: - // a directory-structure like format. - std::vector dfs_distances(num_vertices(g), 0); - print_tree_visitor - tree_printer(node_name, &dfs_distances[0]); - for (boost::tie(vi, vi_end) = vertices(g); vi != vi_end; ++vi) - get(vertex_color, g)[*vi] = white_color; - depth_first_visit(search_tree, src, tree_printer, get(vertex_color, g)); - - return EXIT_SUCCESS; + + //=========================================================================== + // Calculate the diameter of the graph. + + typedef Traits::vertices_size_type size_type; + typedef std::vector< size_type > IntVector; + // Create N x N matrix for storing the shortest distances + // between each vertex. Initialize all distances to zero. + std::vector< IntVector > d_matrix( + num_vertices(g), IntVector(num_vertices(g), 0)); + + size_type i; + for (i = 0; i < num_vertices(g); ++i) + { + calc_distance_visitor< size_type* > vis(&d_matrix[i][0]); + Traits::vertex_descriptor src = vertices(g).first[i]; + breadth_first_search(g, src, boost::visitor(vis)); + } + + size_type diameter = 0; + BOOST_USING_STD_MAX(); + for (i = 0; i < num_vertices(g); ++i) + diameter = max BOOST_PREVENT_MACRO_SUBSTITUTION(diameter, + *std::max_element(d_matrix[i].begin(), d_matrix[i].end())); + + std::cout << "The diameter of the boost web-site graph is " << diameter + << std::endl + << std::endl; + + std::cout << "Number of clicks from the home page: " << std::endl; + Traits::vertex_iterator vi, vi_end; + for (boost::tie(vi, vi_end) = vertices(g); vi != vi_end; ++vi) + std::cout << d_matrix[0][*vi] << "\t" << node_name[*vi] << std::endl; + std::cout << std::endl; + + //=========================================================================== + // Print out the breadth-first search tree starting at the home page + + // Create storage for a mapping from vertices to their parents + std::vector< Traits::vertex_descriptor > parent(num_vertices(g)); + for (boost::tie(vi, vi_end) = vertices(g); vi != vi_end; ++vi) + parent[*vi] = *vi; + + // Do a BFS starting at the home page, recording the parent of each + // vertex (where parent is with respect to the search tree). + Traits::vertex_descriptor src = vertices(g).first[0]; + breadth_first_search(g, src, + boost::visitor( + make_bfs_visitor(record_predecessors(&parent[0], on_tree_edge())))); + + // Add all the search tree edges into a new graph + Graph search_tree(num_vertices(g)); + boost::tie(vi, vi_end) = vertices(g); + ++vi; + for (; vi != vi_end; ++vi) + add_edge(parent[*vi], *vi, search_tree); + + std::cout << "The breadth-first search tree:" << std::endl; + + // Print out the search tree. We use DFS because it visits + // the tree nodes in the order that we want to print out: + // a directory-structure like format. + std::vector< size_type > dfs_distances(num_vertices(g), 0); + print_tree_visitor< NameMap, size_type* > tree_printer( + node_name, &dfs_distances[0]); + for (boost::tie(vi, vi_end) = vertices(g); vi != vi_end; ++vi) + get(vertex_color, g)[*vi] = white_color; + depth_first_visit(search_tree, src, tree_printer, get(vertex_color, g)); + + return EXIT_SUCCESS; } diff --git a/example/boost_web_graph.expected b/example/boost_web_graph.expected index b79bbf47d..5c60774ed 100644 --- a/example/boost_web_graph.expected +++ b/example/boost_web_graph.expected @@ -1,6 +1,6 @@ The diameter of the boost web-site graph is 2 -Number of clicks from the home page: +Number of clicks from the home page: 0 www.boost.org 1 Boost Libraries 1 More Information diff --git a/example/boykov_kolmogorov-eg.cpp b/example/boykov_kolmogorov-eg.cpp index dec3474fb..5dd8d03e4 100644 --- a/example/boykov_kolmogorov-eg.cpp +++ b/example/boykov_kolmogorov-eg.cpp @@ -68,44 +68,47 @@ int main() { - using namespace boost; + using namespace boost; - typedef adjacency_list_traits < vecS, vecS, directedS > Traits; - typedef adjacency_list < vecS, vecS, directedS, - property < vertex_name_t, std::string, - property < vertex_index_t, long, - property < vertex_color_t, boost::default_color_type, - property < vertex_distance_t, long, - property < vertex_predecessor_t, Traits::edge_descriptor > > > > >, + typedef adjacency_list_traits< vecS, vecS, directedS > Traits; + typedef adjacency_list< vecS, vecS, directedS, + property< vertex_name_t, std::string, + property< vertex_index_t, long, + property< vertex_color_t, boost::default_color_type, + property< vertex_distance_t, long, + property< vertex_predecessor_t, + Traits::edge_descriptor > > > > >, - property < edge_capacity_t, long, - property < edge_residual_capacity_t, long, - property < edge_reverse_t, Traits::edge_descriptor > > > > Graph; + property< edge_capacity_t, long, + property< edge_residual_capacity_t, long, + property< edge_reverse_t, Traits::edge_descriptor > > > > + Graph; - Graph g; - property_map < Graph, edge_capacity_t >::type - capacity = get(edge_capacity, g); - property_map < Graph, edge_residual_capacity_t >::type - residual_capacity = get(edge_residual_capacity, g); - property_map < Graph, edge_reverse_t >::type rev = get(edge_reverse, g); - Traits::vertex_descriptor s, t; - read_dimacs_max_flow(g, capacity, rev, s, t); + Graph g; + property_map< Graph, edge_capacity_t >::type capacity + = get(edge_capacity, g); + property_map< Graph, edge_residual_capacity_t >::type residual_capacity + = get(edge_residual_capacity, g); + property_map< Graph, edge_reverse_t >::type rev = get(edge_reverse, g); + Traits::vertex_descriptor s, t; + read_dimacs_max_flow(g, capacity, rev, s, t); - std::vector color(num_vertices(g)); - std::vector distance(num_vertices(g)); - long flow = boykov_kolmogorov_max_flow(g ,s, t); + std::vector< default_color_type > color(num_vertices(g)); + std::vector< long > distance(num_vertices(g)); + long flow = boykov_kolmogorov_max_flow(g, s, t); - std::cout << "c The total flow:" << std::endl; - std::cout << "s " << flow << std::endl << std::endl; + std::cout << "c The total flow:" << std::endl; + std::cout << "s " << flow << std::endl << std::endl; - std::cout << "c flow values:" << std::endl; - graph_traits < Graph >::vertex_iterator u_iter, u_end; - graph_traits < Graph >::out_edge_iterator ei, e_end; - for (boost::tie(u_iter, u_end) = vertices(g); u_iter != u_end; ++u_iter) - for (boost::tie(ei, e_end) = out_edges(*u_iter, g); ei != e_end; ++ei) - if (capacity[*ei] > 0) - std::cout << "f " << *u_iter << " " << target(*ei, g) << " " - << (capacity[*ei] - residual_capacity[*ei]) << std::endl; + std::cout << "c flow values:" << std::endl; + graph_traits< Graph >::vertex_iterator u_iter, u_end; + graph_traits< Graph >::out_edge_iterator ei, e_end; + for (boost::tie(u_iter, u_end) = vertices(g); u_iter != u_end; ++u_iter) + for (boost::tie(ei, e_end) = out_edges(*u_iter, g); ei != e_end; ++ei) + if (capacity[*ei] > 0) + std::cout << "f " << *u_iter << " " << target(*ei, g) << " " + << (capacity[*ei] - residual_capacity[*ei]) + << std::endl; - return EXIT_SUCCESS; + return EXIT_SUCCESS; } diff --git a/example/bron_kerbosch_clique_number.cpp b/example/bron_kerbosch_clique_number.cpp index 99edab92c..bf551867f 100644 --- a/example/bron_kerbosch_clique_number.cpp +++ b/example/bron_kerbosch_clique_number.cpp @@ -19,11 +19,10 @@ using namespace boost; // Declare the graph type and its vertex and edge types. typedef undirected_graph<> Graph; -typedef graph_traits::vertex_descriptor Vertex; -typedef graph_traits::edge_descriptor Edge; +typedef graph_traits< Graph >::vertex_descriptor Vertex; +typedef graph_traits< Graph >::edge_descriptor Edge; -int -main(int argc, char *argv[]) +int main(int argc, char* argv[]) { // Create the graph and read it from standard input. Graph g; diff --git a/example/bron_kerbosch_print_cliques.cpp b/example/bron_kerbosch_print_cliques.cpp index 93030edd1..21c83b690 100644 --- a/example/bron_kerbosch_print_cliques.cpp +++ b/example/bron_kerbosch_print_cliques.cpp @@ -17,19 +17,17 @@ using namespace boost; // The clique_printer is a visitor that will print the vertices that comprise // a clique. Note that the vertices are not given in any specific order. -template -struct clique_printer +template < typename OutputStream > struct clique_printer { - clique_printer(OutputStream& stream) - : os(stream) - { } + clique_printer(OutputStream& stream) : os(stream) {} - template + template < typename Clique, typename Graph > void clique(const Clique& c, const Graph& g) { // Iterate over the clique and print each vertex within it. typename Clique::const_iterator i, end = c.end(); - for(i = c.begin(); i != end; ++i) { + for (i = c.begin(); i != end; ++i) + { os << g[*i].name << " "; } os << endl; @@ -44,16 +42,15 @@ struct Actor }; // Declare the graph type and its vertex and edge types. -typedef undirected_graph Graph; -typedef graph_traits::vertex_descriptor Vertex; -typedef graph_traits::edge_descriptor Edge; +typedef undirected_graph< Actor > Graph; +typedef graph_traits< Graph >::vertex_descriptor Vertex; +typedef graph_traits< Graph >::edge_descriptor Edge; // The name map provides an abstract accessor for the names of // each vertex. This is used during graph creation. -typedef property_map::type NameMap; +typedef property_map< Graph, string Actor::* >::type NameMap; -int -main(int argc, char *argv[]) +int main(int argc, char* argv[]) { // Create the graph and and its name map accessor. Graph g; @@ -63,7 +60,7 @@ main(int argc, char *argv[]) read_graph(g, nm, cin); // Instantiate the visitor for printing cliques - clique_printer vis(cout); + clique_printer< ostream > vis(cout); // Use the Bron-Kerbosch algorithm to find all cliques, printing them // as they are found. diff --git a/example/bucket_sorter.cpp b/example/bucket_sorter.cpp index 981bed18d..4f176a428 100644 --- a/example/bucket_sorter.cpp +++ b/example/bucket_sorter.cpp @@ -14,85 +14,102 @@ #include #include -int main() { - using namespace std; - using boost::bucket_sorter; +int main() +{ + using namespace std; + using boost::bucket_sorter; - const std::size_t N = 10; + const std::size_t N = 10; - vector bucket(N); - for (std::size_t i=0; i bucket(N); + for (std::size_t i = 0; i < N; i++) + { + bucket[i] = rand() % N; + cout.width(6); + cout << "Number " << i << " is in bucket " << bucket[i] << endl; + } - typedef boost::identity_property_map ID; - typedef bucket_sorter::iterator, ID> BS; - BS my_bucket_sorter(N, N, bucket.begin()); + typedef boost::identity_property_map ID; + typedef bucket_sorter< std::size_t, int, vector< std::size_t >::iterator, + ID > + BS; + BS my_bucket_sorter(N, N, bucket.begin()); - for (std::size_t ii=0; ii #include - using namespace boost; - int main(int argc, char** argv) { - typedef adjacency_list - < vecS, - vecS, - undirectedS, - property, - property - > - graph; + typedef adjacency_list< vecS, vecS, undirectedS, + property< vertex_index_t, int >, property< edge_index_t, int > > + graph; + + // Create a maximal planar graph on 6 vertices + graph g(6); - // Create a maximal planar graph on 6 vertices - graph g(6); + add_edge(0, 1, g); + add_edge(1, 2, g); + add_edge(2, 3, g); + add_edge(3, 4, g); + add_edge(4, 5, g); + add_edge(5, 0, g); - add_edge(0,1,g); - add_edge(1,2,g); - add_edge(2,3,g); - add_edge(3,4,g); - add_edge(4,5,g); - add_edge(5,0,g); + add_edge(0, 2, g); + add_edge(0, 3, g); + add_edge(0, 4, g); - add_edge(0,2,g); - add_edge(0,3,g); - add_edge(0,4,g); + add_edge(1, 3, g); + add_edge(1, 4, g); + add_edge(1, 5, g); - add_edge(1,3,g); - add_edge(1,4,g); - add_edge(1,5,g); + // Initialize the interior edge index + property_map< graph, edge_index_t >::type e_index = get(edge_index, g); + graph_traits< graph >::edges_size_type edge_count = 0; + graph_traits< graph >::edge_iterator ei, ei_end; + for (boost::tie(ei, ei_end) = edges(g); ei != ei_end; ++ei) + put(e_index, *ei, edge_count++); - // Initialize the interior edge index - property_map::type e_index = get(edge_index, g); - graph_traits::edges_size_type edge_count = 0; - graph_traits::edge_iterator ei, ei_end; - for(boost::tie(ei, ei_end) = edges(g); ei != ei_end; ++ei) - put(e_index, *ei, edge_count++); - + // Test for planarity - we know it is planar, we just want to + // compute the planar embedding as a side-effect + typedef std::vector< graph_traits< graph >::edge_descriptor > vec_t; + std::vector< vec_t > embedding(num_vertices(g)); + if (boyer_myrvold_planarity_test(boyer_myrvold_params::graph = g, + boyer_myrvold_params::embedding = make_iterator_property_map( + embedding.begin(), get(vertex_index, g)))) + std::cout << "Input graph is planar" << std::endl; + else + std::cout << "Input graph is not planar" << std::endl; - // Test for planarity - we know it is planar, we just want to - // compute the planar embedding as a side-effect - typedef std::vector< graph_traits::edge_descriptor > vec_t; - std::vector embedding(num_vertices(g)); - if (boyer_myrvold_planarity_test(boyer_myrvold_params::graph = g, - boyer_myrvold_params::embedding = - make_iterator_property_map( - embedding.begin(), get(vertex_index, g)) - ) - ) - std::cout << "Input graph is planar" << std::endl; - else - std::cout << "Input graph is not planar" << std::endl; + typedef std::vector< graph_traits< graph >::vertex_descriptor > + ordering_storage_t; - typedef std::vector::vertex_descriptor> - ordering_storage_t; - - ordering_storage_t ordering; - planar_canonical_ordering(g, - make_iterator_property_map( - embedding.begin(), get(vertex_index, g)), - std::back_inserter(ordering)); + ordering_storage_t ordering; + planar_canonical_ordering(g, + make_iterator_property_map(embedding.begin(), get(vertex_index, g)), + std::back_inserter(ordering)); - ordering_storage_t::iterator oi, oi_end; - oi_end = ordering.end(); - std::cout << "The planar canonical ordering is: "; - for(oi = ordering.begin(); oi != oi_end; ++oi) - std::cout << *oi << " "; - std::cout << std::endl; + ordering_storage_t::iterator oi, oi_end; + oi_end = ordering.end(); + std::cout << "The planar canonical ordering is: "; + for (oi = ordering.begin(); oi != oi_end; ++oi) + std::cout << *oi << " "; + std::cout << std::endl; - return 0; + return 0; } diff --git a/example/cc-internet.cpp b/example/cc-internet.cpp index ca3582719..929d5e236 100644 --- a/example/cc-internet.cpp +++ b/example/cc-internet.cpp @@ -1,5 +1,5 @@ //======================================================================= -// Copyright 2001 Jeremy G. Siek, Andrew Lumsdaine, Lie-Quan Lee, +// Copyright 2001 Jeremy G. Siek, Andrew Lumsdaine, Lie-Quan Lee, // // Distributed under the Boost Software License, Version 1.0. (See // accompanying file LICENSE_1_0.txt or copy at @@ -9,8 +9,8 @@ /* IMPORTANT!!! ~~~~~~~~~~~~ - This example uses interfaces that have been deprecated and removed from Boost.Grpah. - Someone needs to update it, as it does NOT compile. + This example uses interfaces that have been deprecated and removed from + Boost.Grpah. Someone needs to update it, as it does NOT compile. */ #include @@ -20,30 +20,28 @@ #include #include -int -main() +int main() { - using namespace boost; - GraphvizGraph g; - read_graphviz("figs/cc-internet.dot", g); + using namespace boost; + GraphvizGraph g; + read_graphviz("figs/cc-internet.dot", g); - std::vector component(num_vertices(g)); + std::vector< int > component(num_vertices(g)); - connected_components - (g, make_iterator_property_map(component.begin(), - get(vertex_index, g), component[0])); - - property_map < GraphvizGraph, vertex_attribute_t >::type - vertex_attr_map = get(vertex_attribute, g); - std::string color[] = { - "white", "gray", "black", "lightgray"}; - graph_traits < GraphvizGraph >::vertex_iterator vi, vi_end; - for (boost::tie(vi, vi_end) = vertices(g); vi != vi_end; ++vi) { - vertex_attr_map[*vi]["color"] = color[component[*vi]]; - vertex_attr_map[*vi]["style"] = "filled"; - if (vertex_attr_map[*vi]["color"] == "black") - vertex_attr_map[*vi]["fontcolor"] = "white"; - } - write_graphviz("figs/cc-internet-out.dot", g); + connected_components(g, + make_iterator_property_map( + component.begin(), get(vertex_index, g), component[0])); + property_map< GraphvizGraph, vertex_attribute_t >::type vertex_attr_map + = get(vertex_attribute, g); + std::string color[] = { "white", "gray", "black", "lightgray" }; + graph_traits< GraphvizGraph >::vertex_iterator vi, vi_end; + for (boost::tie(vi, vi_end) = vertices(g); vi != vi_end; ++vi) + { + vertex_attr_map[*vi]["color"] = color[component[*vi]]; + vertex_attr_map[*vi]["style"] = "filled"; + if (vertex_attr_map[*vi]["color"] == "black") + vertex_attr_map[*vi]["fontcolor"] = "white"; + } + write_graphviz("figs/cc-internet-out.dot", g); } diff --git a/example/city_visitor.cpp b/example/city_visitor.cpp index 85415a6fb..ba98c25e8 100644 --- a/example/city_visitor.cpp +++ b/example/city_visitor.cpp @@ -19,9 +19,8 @@ #include #include // for boost::make_list - /* - Example of using a visitor with the depth first search + Example of using a visitor with the depth first search and breadth first search algorithm Sacramento ---- Reno ---- Salt Lake City @@ -32,11 +31,11 @@ | Los Angeles ---- Las Vegas ---- Phoenix | - San Diego + San Diego + + The visitor has three main functions: - The visitor has three main functions: - discover_vertex(u,g) is invoked when the algorithm first arrives at the vertex u. This will happen in the depth first or breadth first order depending on which algorithm you use. @@ -47,94 +46,103 @@ visit(u). finish_vertex(u,g) is called when after all the vertices reachable from vertex - u have already been visited. + u have already been visited. */ using namespace std; using namespace boost; - -struct city_arrival : public base_visitor +struct city_arrival : public base_visitor< city_arrival > { - city_arrival(string* n) : names(n) { } - typedef on_discover_vertex event_filter; - template - inline void operator()(Vertex u, Graph&) { - cout << endl << "arriving at " << names[u] << endl - << " neighboring cities are: "; - } - string* names; + city_arrival(string* n) : names(n) {} + typedef on_discover_vertex event_filter; + template < class Vertex, class Graph > + inline void operator()(Vertex u, Graph&) + { + cout << endl + << "arriving at " << names[u] << endl + << " neighboring cities are: "; + } + string* names; }; -struct neighbor_cities : public base_visitor +struct neighbor_cities : public base_visitor< neighbor_cities > { - neighbor_cities(string* n) : names(n) { } - typedef on_examine_edge event_filter; - template - inline void operator()(Edge e, Graph& g) { - cout << names[ target(e, g) ] << ", "; - } - string* names; + neighbor_cities(string* n) : names(n) {} + typedef on_examine_edge event_filter; + template < class Edge, class Graph > + inline void operator()(Edge e, Graph& g) + { + cout << names[target(e, g)] << ", "; + } + string* names; }; -struct finish_city : public base_visitor +struct finish_city : public base_visitor< finish_city > { - finish_city(string* n) : names(n) { } - typedef on_finish_vertex event_filter; - template - inline void operator()(Vertex u, Graph&) { - cout << endl << "finished with " << names[u] << endl; - } - string* names; + finish_city(string* n) : names(n) {} + typedef on_finish_vertex event_filter; + template < class Vertex, class Graph > + inline void operator()(Vertex u, Graph&) + { + cout << endl << "finished with " << names[u] << endl; + } + string* names; }; -int main(int, char*[]) +int main(int, char*[]) { - enum { SanJose, SanFran, LA, SanDiego, Fresno, LasVegas, Reno, - Sacramento, SaltLake, Phoenix, N }; - - string names[] = { "San Jose", "San Francisco", "Los Angeles", "San Diego", - "Fresno", "Las Vegas", "Reno", "Sacramento", - "Salt Lake City", "Phoenix" }; - - typedef std::pair E; - E edge_array[] = { E(Sacramento, Reno), E(Sacramento, SanFran), - E(Reno, SaltLake), - E(SanFran, SanJose), - E(SanJose, Fresno), E(SanJose, LA), - E(LA, LasVegas), E(LA, SanDiego), - E(LasVegas, Phoenix) }; - - /* Create the graph type we want. */ - typedef adjacency_list Graph; + enum + { + SanJose, + SanFran, + LA, + SanDiego, + Fresno, + LasVegas, + Reno, + Sacramento, + SaltLake, + Phoenix, + N + }; + + string names[] + = { "San Jose", "San Francisco", "Los Angeles", "San Diego", "Fresno", + "Las Vegas", "Reno", "Sacramento", "Salt Lake City", "Phoenix" }; + + typedef std::pair< int, int > E; + E edge_array[] + = { E(Sacramento, Reno), E(Sacramento, SanFran), E(Reno, SaltLake), + E(SanFran, SanJose), E(SanJose, Fresno), E(SanJose, LA), + E(LA, LasVegas), E(LA, SanDiego), E(LasVegas, Phoenix) }; + + /* Create the graph type we want. */ + typedef adjacency_list< vecS, vecS, undirectedS > Graph; #if defined(BOOST_MSVC) && BOOST_MSVC <= 1300 - // VC++ has trouble with the edge iterator constructor - Graph G(N); - for (std::size_t j = 0; j < sizeof(edge_array)/sizeof(E); ++j) - add_edge(edge_array[j].first, edge_array[j].second, G); + // VC++ has trouble with the edge iterator constructor + Graph G(N); + for (std::size_t j = 0; j < sizeof(edge_array) / sizeof(E); ++j) + add_edge(edge_array[j].first, edge_array[j].second, G); #else - Graph G(edge_array, edge_array + sizeof(edge_array)/sizeof(E), N); + Graph G(edge_array, edge_array + sizeof(edge_array) / sizeof(E), N); #endif - cout << "*** Depth First ***" << endl; - depth_first_search - (G, - visitor(make_dfs_visitor(boost::make_list(city_arrival(names), - neighbor_cities(names), - finish_city(names))))); - cout << endl; - - /* Get the source vertex */ - boost::graph_traits::vertex_descriptor - s = vertex(SanJose,G); - - cout << "*** Breadth First ***" << endl; - breadth_first_search - (G, s, visitor(make_bfs_visitor(boost::make_list(city_arrival(names), - neighbor_cities(names), - finish_city(names))))); - - return 0; + cout << "*** Depth First ***" << endl; + depth_first_search(G, + visitor(make_dfs_visitor(boost::make_list( + city_arrival(names), neighbor_cities(names), finish_city(names))))); + cout << endl; + + /* Get the source vertex */ + boost::graph_traits< Graph >::vertex_descriptor s = vertex(SanJose, G); + + cout << "*** Breadth First ***" << endl; + breadth_first_search(G, s, + visitor(make_bfs_visitor(boost::make_list( + city_arrival(names), neighbor_cities(names), finish_city(names))))); + + return 0; } diff --git a/example/closeness_centrality.cpp b/example/closeness_centrality.cpp index ea921114c..9703bf3d3 100644 --- a/example/closeness_centrality.cpp +++ b/example/closeness_centrality.cpp @@ -25,32 +25,31 @@ struct Actor }; // Declare the graph type and its vertex and edge types. -typedef undirected_graph Graph; -typedef graph_traits::vertex_descriptor Vertex; -typedef graph_traits::edge_descriptor Edge; +typedef undirected_graph< Actor > Graph; +typedef graph_traits< Graph >::vertex_descriptor Vertex; +typedef graph_traits< Graph >::edge_descriptor Edge; // The name map provides an abstract accessor for the names of // each vertex. This is used during graph creation. -typedef property_map::type NameMap; +typedef property_map< Graph, string Actor::* >::type NameMap; // Declare a matrix type and its corresponding property map that // will contain the distances between each pair of vertices. -typedef exterior_vertex_property DistanceProperty; +typedef exterior_vertex_property< Graph, int > DistanceProperty; typedef DistanceProperty::matrix_type DistanceMatrix; typedef DistanceProperty::matrix_map_type DistanceMatrixMap; // Declare the weight map so that each edge returns the same value. -typedef constant_property_map WeightMap; +typedef constant_property_map< Edge, int > WeightMap; // Declare a container and its corresponding property map that // will contain the resulting closeness centralities of each // vertex in the graph. -typedef boost::exterior_vertex_property ClosenessProperty; +typedef boost::exterior_vertex_property< Graph, float > ClosenessProperty; typedef ClosenessProperty::container_type ClosenessContainer; typedef ClosenessProperty::map_type ClosenessMap; -int -main(int argc, char *argv[]) +int main(int argc, char* argv[]) { // Create the graph and a property map that provides access to[ // tha actor names. @@ -74,10 +73,11 @@ main(int argc, char *argv[]) all_closeness_centralities(g, dm, cm); // Print the closeness centrality of each vertex. - graph_traits::vertex_iterator i, end; - for(boost::tie(i, end) = vertices(g); i != end; ++i) { - cout << setw(12) << setiosflags(ios::left) - << g[*i].name << get(cm, *i) << endl; + graph_traits< Graph >::vertex_iterator i, end; + for (boost::tie(i, end) = vertices(g); i != end; ++i) + { + cout << setw(12) << setiosflags(ios::left) << g[*i].name << get(cm, *i) + << endl; } return 0; diff --git a/example/clustering_coefficient.cpp b/example/clustering_coefficient.cpp index c4a451f13..cb2ef39bf 100644 --- a/example/clustering_coefficient.cpp +++ b/example/clustering_coefficient.cpp @@ -4,7 +4,6 @@ // Boost Software License, Version 1.0 (See accompanying file // LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) - //[code_clustering_coefficient #include #include @@ -24,22 +23,21 @@ struct Actor }; // Declare the graph type and its vertex and edge types. -typedef undirected_graph Graph; -typedef graph_traits::vertex_descriptor Vertex; -typedef graph_traits::edge_descriptor Edge; +typedef undirected_graph< Actor > Graph; +typedef graph_traits< Graph >::vertex_descriptor Vertex; +typedef graph_traits< Graph >::edge_descriptor Edge; // The name map provides an abstract accessor for the names of // each vertex. This is used during graph creation. -typedef property_map::type NameMap; +typedef property_map< Graph, string Actor::* >::type NameMap; // The clustering property, container, and map define the containment // and abstract accessor for the clustering coefficients of vertices. -typedef exterior_vertex_property ClusteringProperty; +typedef exterior_vertex_property< Graph, float > ClusteringProperty; typedef ClusteringProperty::container_type ClusteringContainer; typedef ClusteringProperty::map_type ClusteringMap; -int -main(int argc, char *argv[]) +int main(int argc, char* argv[]) { // Create the graph and a name map that provides access to // then actor names. @@ -57,10 +55,11 @@ main(int argc, char *argv[]) float cc = all_clustering_coefficients(g, cm); // Print the clustering coefficient of each vertex. - graph_traits::vertex_iterator i, end; - for(boost::tie(i, end) = vertices(g); i != end; ++i) { - cout << setw(12) << setiosflags(ios::left) - << g[*i].name << get(cm, *i) << endl; + graph_traits< Graph >::vertex_iterator i, end; + for (boost::tie(i, end) = vertices(g); i != end; ++i) + { + cout << setw(12) << setiosflags(ios::left) << g[*i].name << get(cm, *i) + << endl; } cout << "mean clustering coefficient: " << cc << endl; diff --git a/example/components_on_edgelist.cpp b/example/components_on_edgelist.cpp index 685f86ebc..233405148 100644 --- a/example/components_on_edgelist.cpp +++ b/example/components_on_edgelist.cpp @@ -33,7 +33,7 @@ Sample output: An undirected graph (edge list): - (0,1) (1,4) (4,0) (2,5) + (0,1) (1,4) (4,0) (2,5) Total number of components: 3 Vertex 0 is in the component who's representative is 1 Vertex 1 is in the component who's representative is 1 @@ -42,53 +42,52 @@ Vertex 4 is in the component who's representative is 1 Vertex 5 is in the component who's representative is 5 - component 0 contains: 4 1 0 - component 1 contains: 3 - component 2 contains: 5 2 - - */ + component 0 contains: 4 1 0 + component 1 contains: 3 + component 2 contains: 5 2 + */ using namespace std; using boost::tie; -int main(int , char* []) +int main(int, char*[]) { - using namespace boost; - typedef int Index; // ID of a Vertex - typedef pair Edge; - const int N = 6; - const int E = 4; - Edge edgelist[] = { Edge(0, 1), Edge(1, 4), Edge(4, 0), Edge(2, 5) }; - - + using namespace boost; + typedef int Index; // ID of a Vertex + typedef pair< Index, Index > Edge; + const int N = 6; + const int E = 4; + Edge edgelist[] = { Edge(0, 1), Edge(1, 4), Edge(4, 0), Edge(2, 5) }; - edge_list g(edgelist, edgelist + E); - cout << "An undirected graph (edge list):" << endl; - print_edges(g, identity_property_map()); - cout << endl; + edge_list< Edge*, Edge, ptrdiff_t, std::random_access_iterator_tag > g( + edgelist, edgelist + E); + cout << "An undirected graph (edge list):" << endl; + print_edges(g, identity_property_map()); + cout << endl; - disjoint_sets_with_storage<> ds(N); - incremental_components(g, ds); - - component_index components(&ds.parents()[0], - &ds.parents()[0] + ds.parents().size()); + disjoint_sets_with_storage<> ds(N); + incremental_components(g, ds); - cout << "Total number of components: " << components.size() << endl; - for (int k = 0; k != N; ++k) - cout << "Vertex " << k << " is in the component who's representative is " - << ds.find_set(k) << endl; - cout << endl; + component_index< int > components( + &ds.parents()[0], &ds.parents()[0] + ds.parents().size()); - for (std::size_t i = 0; i < components.size(); ++i) { - cout << "component " << i << " contains: "; - component_index::component_iterator - j = components[i].first, - jend = components[i].second; - for ( ; j != jend; ++j) - cout << *j << " "; + cout << "Total number of components: " << components.size() << endl; + for (int k = 0; k != N; ++k) + cout << "Vertex " << k + << " is in the component who's representative is " + << ds.find_set(k) << endl; cout << endl; - } - return 0; + for (std::size_t i = 0; i < components.size(); ++i) + { + cout << "component " << i << " contains: "; + component_index< int >::component_iterator j = components[i].first, + jend = components[i].second; + for (; j != jend; ++j) + cout << *j << " "; + cout << endl; + } + + return 0; } diff --git a/example/components_on_edgelist.expected b/example/components_on_edgelist.expected index bb12dd332..997df1a54 100644 --- a/example/components_on_edgelist.expected +++ b/example/components_on_edgelist.expected @@ -1,5 +1,5 @@ An undirected graph (edge list): -(0,1) (1,4) (4,0) (2,5) +(0,1) (1,4) (4,0) (2,5) Total number of components: 3 Vertex 0 is in the component who's representative is 1 @@ -9,6 +9,6 @@ Vertex 3 is in the component who's representative is 3 Vertex 4 is in the component who's representative is 1 Vertex 5 is in the component who's representative is 5 -component 0 contains: 4 1 0 -component 1 contains: 3 -component 2 contains: 5 2 +component 0 contains: 4 1 0 +component 1 contains: 3 +component 2 contains: 5 2 diff --git a/example/connected-components.cpp b/example/connected-components.cpp index 15a83ca66..034a78807 100644 --- a/example/connected-components.cpp +++ b/example/connected-components.cpp @@ -1,5 +1,5 @@ //======================================================================= -// Copyright 2001 Jeremy G. Siek, Andrew Lumsdaine, Lie-Quan Lee, +// Copyright 2001 Jeremy G. Siek, Andrew Lumsdaine, Lie-Quan Lee, // // Distributed under the Boost Software License, Version 1.0. (See // accompanying file LICENSE_1_0.txt or copy at @@ -11,29 +11,28 @@ #include #include -int -main() +int main() { - using namespace boost; - typedef adjacency_list < vecS, vecS, undirectedS > Graph; + using namespace boost; + typedef adjacency_list< vecS, vecS, undirectedS > Graph; - const int N = 6; - Graph G(N); - add_edge(0, 1, G); - add_edge(1, 4, G); - add_edge(4, 0, G); - add_edge(2, 5, G); + const int N = 6; + Graph G(N); + add_edge(0, 1, G); + add_edge(1, 4, G); + add_edge(4, 0, G); + add_edge(2, 5, G); - std::vector c(num_vertices(G)); - int num = connected_components - (G, make_iterator_property_map(c.begin(), get(vertex_index, G), c[0])); + std::vector< int > c(num_vertices(G)); + int num = connected_components( + G, make_iterator_property_map(c.begin(), get(vertex_index, G), c[0])); - std::cout << std::endl; - std::vector < int >::iterator i; - std::cout << "Total number of components: " << num << std::endl; - for (i = c.begin(); i != c.end(); ++i) - std::cout << "Vertex " << i - c.begin() - << " is in component " << *i << std::endl; - std::cout << std::endl; - return EXIT_SUCCESS; + std::cout << std::endl; + std::vector< int >::iterator i; + std::cout << "Total number of components: " << num << std::endl; + for (i = c.begin(); i != c.end(); ++i) + std::cout << "Vertex " << i - c.begin() << " is in component " << *i + << std::endl; + std::cout << std::endl; + return EXIT_SUCCESS; } diff --git a/example/connected_components.cpp b/example/connected_components.cpp index 0d9102bb9..4af273d23 100644 --- a/example/connected_components.cpp +++ b/example/connected_components.cpp @@ -36,27 +36,27 @@ using namespace std; -int main(int , char* []) +int main(int, char*[]) { - using namespace boost; - { - typedef adjacency_list Graph; - - Graph G; - add_edge(0, 1, G); - add_edge(1, 4, G); - add_edge(4, 0, G); - add_edge(2, 5, G); - - std::vector component(num_vertices(G)); - int num = connected_components(G, &component[0]); - - std::vector::size_type i; - cout << "Total number of components: " << num << endl; - for (i = 0; i != component.size(); ++i) - cout << "Vertex " << i <<" is in component " << component[i] << endl; - cout << endl; - } - return 0; + using namespace boost; + { + typedef adjacency_list< vecS, vecS, undirectedS > Graph; + + Graph G; + add_edge(0, 1, G); + add_edge(1, 4, G); + add_edge(4, 0, G); + add_edge(2, 5, G); + + std::vector< int > component(num_vertices(G)); + int num = connected_components(G, &component[0]); + + std::vector< int >::size_type i; + cout << "Total number of components: " << num << endl; + for (i = 0; i != component.size(); ++i) + cout << "Vertex " << i << " is in component " << component[i] + << endl; + cout << endl; + } + return 0; } - diff --git a/example/container_gen.cpp b/example/container_gen.cpp index 298e3a62f..17fb7f7b3 100644 --- a/example/container_gen.cpp +++ b/example/container_gen.cpp @@ -8,40 +8,43 @@ //======================================================================= #include -#if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) && !defined(BOOST_NO_STD_ALLOCATOR) - -template -struct list_with_allocatorS { }; - -namespace boost { - template - struct container_gen, ValueType> { - typedef typename Alloc::template rebind::other Allocator; - typedef std::list type; - }; - template - struct parallel_edge_traits< list_with_allocatorS > { +#if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) \ + && !defined(BOOST_NO_STD_ALLOCATOR) + +template < class Allocator > struct list_with_allocatorS +{ +}; + +namespace boost +{ +template < class Alloc, class ValueType > +struct container_gen< list_with_allocatorS< Alloc >, ValueType > +{ + typedef typename Alloc::template rebind< ValueType >::other Allocator; + typedef std::list< ValueType, Allocator > type; +}; +template < class Alloc > +struct parallel_edge_traits< list_with_allocatorS< Alloc > > +{ typedef allow_parallel_edge_tag type; - }; +}; } -// now you can define a graph using std::list and a specific allocator -typedef boost::adjacency_list< list_with_allocatorS< std::allocator >, - boost::vecS, boost::directedS> MyGraph; +// now you can define a graph using std::list and a specific allocator +typedef boost::adjacency_list< list_with_allocatorS< std::allocator< int > >, + boost::vecS, boost::directedS > + MyGraph; int main(int, char*[]) { - MyGraph g(5); - - return 0; + MyGraph g(5); + + return 0; } #else -int main(int, char*[]) -{ - return 0; -} +int main(int, char*[]) { return 0; } #endif diff --git a/example/copy-example.cpp b/example/copy-example.cpp index 572bb369a..7b629d479 100644 --- a/example/copy-example.cpp +++ b/example/copy-example.cpp @@ -1,5 +1,5 @@ //======================================================================= -// Copyright 2001 Jeremy G. Siek, Andrew Lumsdaine, Lie-Quan Lee, +// Copyright 2001 Jeremy G. Siek, Andrew Lumsdaine, Lie-Quan Lee, // // Distributed under the Boost Software License, Version 1.0. (See // accompanying file LICENSE_1_0.txt or copy at @@ -11,37 +11,44 @@ #include #include -int -main() +int main() { - using namespace boost; - typedef adjacency_list < vecS, vecS, directedS, - property < vertex_name_t, char > > graph_t; + using namespace boost; + typedef adjacency_list< vecS, vecS, directedS, + property< vertex_name_t, char > > + graph_t; - enum - { a, b, c, d, e, f, g, N }; - graph_t G(N); - property_map < graph_t, vertex_name_t >::type - name_map = get(vertex_name, G); - char name = 'a'; - graph_traits < graph_t >::vertex_iterator v, v_end; - for (boost::tie(v, v_end) = vertices(G); v != v_end; ++v, ++name) - name_map[*v] = name; + enum + { + a, + b, + c, + d, + e, + f, + g, + N + }; + graph_t G(N); + property_map< graph_t, vertex_name_t >::type name_map = get(vertex_name, G); + char name = 'a'; + graph_traits< graph_t >::vertex_iterator v, v_end; + for (boost::tie(v, v_end) = vertices(G); v != v_end; ++v, ++name) + name_map[*v] = name; - typedef std::pair < int, int >E; - E edges[] = { E(a, c), E(a, d), E(b, a), E(b, d), E(c, f), - E(d, c), E(d, e), E(d, f), E(e, b), E(e, g), E(f, e), E(f, g) - }; - for (int i = 0; i < 12; ++i) - add_edge(edges[i].first, edges[i].second, G); + typedef std::pair< int, int > E; + E edges[] = { E(a, c), E(a, d), E(b, a), E(b, d), E(c, f), E(d, c), E(d, e), + E(d, f), E(e, b), E(e, g), E(f, e), E(f, g) }; + for (int i = 0; i < 12; ++i) + add_edge(edges[i].first, edges[i].second, G); - print_graph(G, name_map); - std::cout << std::endl; + print_graph(G, name_map); + std::cout << std::endl; - graph_t G_copy; - copy_graph(G, G_copy); + graph_t G_copy; + copy_graph(G, G_copy); - print_graph(G_copy, name_map); + print_graph(G_copy, name_map); - return 0; + return 0; } diff --git a/example/csr-example.cpp b/example/csr-example.cpp index 942eb3957..a471e6997 100644 --- a/example/csr-example.cpp +++ b/example/csr-example.cpp @@ -18,44 +18,44 @@ using namespace boost; class WebPage { - public: - std::string url; +public: + std::string url; }; int main() { - typedef std::pair E; - const char* urls[6] = { - "http://www.boost.org/libs/graph/doc/index.html", - "http://www.boost.org/libs/graph/doc/table_of_contents.html", - "http://www.boost.org/libs/graph/doc/adjacency_list.html", - "http://www.boost.org/libs/graph/doc/history.html", - "http://www.boost.org/libs/graph/doc/bundles.html", - "http://www.boost.org/libs/graph/doc/using_adjacency_list.html", - }; - - E the_edges[] = { E(0, 1), E(0, 2), E(0, 3), E(1, 0), E(1, 3), E(1, 5), - E(2, 0), E(2, 5), E(3, 1), E(3, 4), E(4, 1), E(5, 0), - E(5, 2) }; - - typedef compressed_sparse_row_graph WebGraph; - WebGraph g(boost::edges_are_sorted, &the_edges[0], &the_edges[0] + sizeof(the_edges)/sizeof(E), 6); - - // Set the URLs of each vertex - int index = 0; - BGL_FORALL_VERTICES(v, g, WebGraph) + typedef std::pair< int, int > E; + const char* urls[6] = { + "http://www.boost.org/libs/graph/doc/index.html", + "http://www.boost.org/libs/graph/doc/table_of_contents.html", + "http://www.boost.org/libs/graph/doc/adjacency_list.html", + "http://www.boost.org/libs/graph/doc/history.html", + "http://www.boost.org/libs/graph/doc/bundles.html", + "http://www.boost.org/libs/graph/doc/using_adjacency_list.html", + }; + + E the_edges[] = { E(0, 1), E(0, 2), E(0, 3), E(1, 0), E(1, 3), E(1, 5), + E(2, 0), E(2, 5), E(3, 1), E(3, 4), E(4, 1), E(5, 0), E(5, 2) }; + + typedef compressed_sparse_row_graph< directedS, WebPage > WebGraph; + WebGraph g(boost::edges_are_sorted, &the_edges[0], + &the_edges[0] + sizeof(the_edges) / sizeof(E), 6); + + // Set the URLs of each vertex + int index = 0; + BGL_FORALL_VERTICES(v, g, WebGraph) g[v].url = urls[index++]; - // Output each of the links - std::cout << "The web graph:" << std::endl; - BGL_FORALL_EDGES(e, g, WebGraph) + // Output each of the links + std::cout << "The web graph:" << std::endl; + BGL_FORALL_EDGES(e, g, WebGraph) std::cout << " " << g[source(e, g)].url << " -> " << g[target(e, g)].url << std::endl; - // Output the graph in DOT format - dynamic_properties dp; - dp.property("label", get(&WebPage::url, g)); - std::ofstream out("web-graph.dot"); - write_graphviz_dp(out, g, dp, std::string(), get(vertex_index, g)); - return 0; + // Output the graph in DOT format + dynamic_properties dp; + dp.property("label", get(&WebPage::url, g)); + std::ofstream out("web-graph.dot"); + write_graphviz_dp(out, g, dp, std::string(), get(vertex_index, g)); + return 0; } diff --git a/example/cuthill_mckee_ordering.cpp b/example/cuthill_mckee_ordering.cpp index 23b0238d6..13a329f2c 100644 --- a/example/cuthill_mckee_ordering.cpp +++ b/example/cuthill_mckee_ordering.cpp @@ -20,112 +20,119 @@ Sample Output original bandwidth: 8 Reverse Cuthill-McKee ordering starting at: 6 - 8 3 0 9 2 5 1 4 7 6 + 8 3 0 9 2 5 1 4 7 6 bandwidth: 4 Reverse Cuthill-McKee ordering starting at: 0 - 9 1 4 6 7 2 8 5 3 0 + 9 1 4 6 7 2 8 5 3 0 bandwidth: 4 Reverse Cuthill-McKee ordering: - 0 8 5 7 3 6 4 2 1 9 + 0 8 5 7 3 6 4 2 1 9 bandwidth: 4 */ -int main(int , char* []) +int main(int, char*[]) { - using namespace boost; - using namespace std; - typedef adjacency_list > > Graph; - typedef graph_traits::vertex_descriptor Vertex; - typedef graph_traits::vertices_size_type size_type; + using namespace boost; + using namespace std; + typedef adjacency_list< vecS, vecS, undirectedS, + property< vertex_color_t, default_color_type, + property< vertex_degree_t, int > > > + Graph; + typedef graph_traits< Graph >::vertex_descriptor Vertex; + typedef graph_traits< Graph >::vertices_size_type size_type; - typedef std::pair Pair; - Pair edges[14] = { Pair(0,3), //a-d - Pair(0,5), //a-f - Pair(1,2), //b-c - Pair(1,4), //b-e - Pair(1,6), //b-g - Pair(1,9), //b-j - Pair(2,3), //c-d - Pair(2,4), //c-e - Pair(3,5), //d-f - Pair(3,8), //d-i - Pair(4,6), //e-g - Pair(5,6), //f-g - Pair(5,7), //f-h - Pair(6,7) }; //g-h - - Graph G(10); - for (int i = 0; i < 14; ++i) - add_edge(edges[i].first, edges[i].second, G); + typedef std::pair< std::size_t, std::size_t > Pair; + Pair edges[14] = { Pair(0, 3), // a-d + Pair(0, 5), // a-f + Pair(1, 2), // b-c + Pair(1, 4), // b-e + Pair(1, 6), // b-g + Pair(1, 9), // b-j + Pair(2, 3), // c-d + Pair(2, 4), // c-e + Pair(3, 5), // d-f + Pair(3, 8), // d-i + Pair(4, 6), // e-g + Pair(5, 6), // f-g + Pair(5, 7), // f-h + Pair(6, 7) }; // g-h - graph_traits::vertex_iterator ui, ui_end; + Graph G(10); + for (int i = 0; i < 14; ++i) + add_edge(edges[i].first, edges[i].second, G); - property_map::type deg = get(vertex_degree, G); - for (boost::tie(ui, ui_end) = vertices(G); ui != ui_end; ++ui) - deg[*ui] = degree(*ui, G); + graph_traits< Graph >::vertex_iterator ui, ui_end; - property_map::type - index_map = get(vertex_index, G); + property_map< Graph, vertex_degree_t >::type deg = get(vertex_degree, G); + for (boost::tie(ui, ui_end) = vertices(G); ui != ui_end; ++ui) + deg[*ui] = degree(*ui, G); - std::cout << "original bandwidth: " << bandwidth(G) << std::endl; + property_map< Graph, vertex_index_t >::type index_map + = get(vertex_index, G); - std::vector inv_perm(num_vertices(G)); - std::vector perm(num_vertices(G)); - { - Vertex s = vertex(6, G); - //reverse cuthill_mckee_ordering - cuthill_mckee_ordering(G, s, inv_perm.rbegin(), get(vertex_color, G), - get(vertex_degree, G)); - cout << "Reverse Cuthill-McKee ordering starting at: " << s << endl; - cout << " "; - for (std::vector::const_iterator i = inv_perm.begin(); - i != inv_perm.end(); ++i) - cout << index_map[*i] << " "; - cout << endl; + std::cout << "original bandwidth: " << bandwidth(G) << std::endl; - for (size_type c = 0; c != inv_perm.size(); ++c) - perm[index_map[inv_perm[c]]] = c; - std::cout << " bandwidth: " - << bandwidth(G, make_iterator_property_map(&perm[0], index_map, perm[0])) - << std::endl; - } - { - Vertex s = vertex(0, G); - //reverse cuthill_mckee_ordering - cuthill_mckee_ordering(G, s, inv_perm.rbegin(), get(vertex_color, G), - get(vertex_degree, G)); - cout << "Reverse Cuthill-McKee ordering starting at: " << s << endl; - cout << " "; - for (std::vector::const_iterator i=inv_perm.begin(); - i != inv_perm.end(); ++i) - cout << index_map[*i] << " "; - cout << endl; + std::vector< Vertex > inv_perm(num_vertices(G)); + std::vector< size_type > perm(num_vertices(G)); + { + Vertex s = vertex(6, G); + // reverse cuthill_mckee_ordering + cuthill_mckee_ordering(G, s, inv_perm.rbegin(), get(vertex_color, G), + get(vertex_degree, G)); + cout << "Reverse Cuthill-McKee ordering starting at: " << s << endl; + cout << " "; + for (std::vector< Vertex >::const_iterator i = inv_perm.begin(); + i != inv_perm.end(); ++i) + cout << index_map[*i] << " "; + cout << endl; - for (size_type c = 0; c != inv_perm.size(); ++c) - perm[index_map[inv_perm[c]]] = c; - std::cout << " bandwidth: " - << bandwidth(G, make_iterator_property_map(&perm[0], index_map, perm[0])) - << std::endl; - } + for (size_type c = 0; c != inv_perm.size(); ++c) + perm[index_map[inv_perm[c]]] = c; + std::cout << " bandwidth: " + << bandwidth(G, + make_iterator_property_map( + &perm[0], index_map, perm[0])) + << std::endl; + } + { + Vertex s = vertex(0, G); + // reverse cuthill_mckee_ordering + cuthill_mckee_ordering(G, s, inv_perm.rbegin(), get(vertex_color, G), + get(vertex_degree, G)); + cout << "Reverse Cuthill-McKee ordering starting at: " << s << endl; + cout << " "; + for (std::vector< Vertex >::const_iterator i = inv_perm.begin(); + i != inv_perm.end(); ++i) + cout << index_map[*i] << " "; + cout << endl; - { - //reverse cuthill_mckee_ordering - cuthill_mckee_ordering(G, inv_perm.rbegin(), get(vertex_color, G), - make_degree_map(G)); - - cout << "Reverse Cuthill-McKee ordering:" << endl; - cout << " "; - for (std::vector::const_iterator i=inv_perm.begin(); - i != inv_perm.end(); ++i) - cout << index_map[*i] << " "; - cout << endl; + for (size_type c = 0; c != inv_perm.size(); ++c) + perm[index_map[inv_perm[c]]] = c; + std::cout << " bandwidth: " + << bandwidth(G, + make_iterator_property_map( + &perm[0], index_map, perm[0])) + << std::endl; + } - for (size_type c = 0; c != inv_perm.size(); ++c) - perm[index_map[inv_perm[c]]] = c; - std::cout << " bandwidth: " - << bandwidth(G, make_iterator_property_map(&perm[0], index_map, perm[0])) - << std::endl; - } - return 0; + { + // reverse cuthill_mckee_ordering + cuthill_mckee_ordering( + G, inv_perm.rbegin(), get(vertex_color, G), make_degree_map(G)); + + cout << "Reverse Cuthill-McKee ordering:" << endl; + cout << " "; + for (std::vector< Vertex >::const_iterator i = inv_perm.begin(); + i != inv_perm.end(); ++i) + cout << index_map[*i] << " "; + cout << endl; + + for (size_type c = 0; c != inv_perm.size(); ++c) + perm[index_map[inv_perm[c]]] = c; + std::cout << " bandwidth: " + << bandwidth(G, + make_iterator_property_map( + &perm[0], index_map, perm[0])) + << std::endl; + } + return 0; } diff --git a/example/cuthill_mckee_ordering.expected b/example/cuthill_mckee_ordering.expected index 42fc655a3..f5103467c 100644 --- a/example/cuthill_mckee_ordering.expected +++ b/example/cuthill_mckee_ordering.expected @@ -1,8 +1,8 @@ -degree: -2 4 3 4 3 4 4 2 1 1 +degree: +2 4 3 4 3 4 4 2 1 1 Reverse Cuthill-McKee ordering starting at :6 -8 3 0 9 2 5 1 4 7 6 +8 3 0 9 2 5 1 4 7 6 Reverse Cuthill-McKee ordering starting at :0 -9 1 4 6 7 2 8 5 3 0 +9 1 4 6 7 2 8 5 3 0 Reverse Cuthill-McKee ordering: -0 8 5 7 3 6 4 2 1 9 +0 8 5 7 3 6 4 2 1 9 diff --git a/example/cycle-file-dep.cpp b/example/cycle-file-dep.cpp index 4e1722439..a1d55ef7b 100644 --- a/example/cycle-file-dep.cpp +++ b/example/cycle-file-dep.cpp @@ -1,5 +1,5 @@ //======================================================================= -// Copyright 2001 Jeremy G. Siek, Andrew Lumsdaine, Lie-Quan Lee, +// Copyright 2001 Jeremy G. Siek, Andrew Lumsdaine, Lie-Quan Lee, // // Distributed under the Boost Software License, Version 1.0. (See // accompanying file LICENSE_1_0.txt or copy at @@ -16,78 +16,79 @@ using namespace boost; namespace std { - template < typename T > - std::istream & operator >> (std::istream & in, std::pair < T, T > &p) - { +template < typename T > +std::istream& operator>>(std::istream& in, std::pair< T, T >& p) +{ in >> p.first >> p.second; return in; - } +} } -typedef adjacency_list < listS, // Store out-edges of each vertex in a std::list - vecS, // Store vertex set in a std::vector - directedS // The file dependency graph is directed -> file_dep_graph; +typedef adjacency_list< listS, // Store out-edges of each vertex in a std::list + vecS, // Store vertex set in a std::vector + directedS // The file dependency graph is directed + > + file_dep_graph; -typedef graph_traits < file_dep_graph >::vertex_descriptor vertex_t; -typedef graph_traits < file_dep_graph >::edge_descriptor edge_t; +typedef graph_traits< file_dep_graph >::vertex_descriptor vertex_t; +typedef graph_traits< file_dep_graph >::edge_descriptor edge_t; -bool -has_cycle_dfs(const file_dep_graph & g, vertex_t u, - default_color_type * color) +bool has_cycle_dfs( + const file_dep_graph& g, vertex_t u, default_color_type* color) { - color[u] = gray_color; - graph_traits < file_dep_graph >::adjacency_iterator vi, vi_end; - for (boost::tie(vi, vi_end) = adjacent_vertices(u, g); vi != vi_end; ++vi) - if (color[*vi] == white_color) { - if (has_cycle_dfs(g, *vi, color)) - return true; // cycle detected, return immediately - } else if (color[*vi] == gray_color) // *vi is an ancestor! - return true; - color[u] = black_color; - return false; + color[u] = gray_color; + graph_traits< file_dep_graph >::adjacency_iterator vi, vi_end; + for (boost::tie(vi, vi_end) = adjacent_vertices(u, g); vi != vi_end; ++vi) + if (color[*vi] == white_color) + { + if (has_cycle_dfs(g, *vi, color)) + return true; // cycle detected, return immediately + } + else if (color[*vi] == gray_color) // *vi is an ancestor! + return true; + color[u] = black_color; + return false; } -bool -has_cycle(const file_dep_graph & g) +bool has_cycle(const file_dep_graph& g) { - std::vector < default_color_type > color(num_vertices(g), white_color); - graph_traits < file_dep_graph >::vertex_iterator vi, vi_end; - for (boost::tie(vi, vi_end) = vertices(g); vi != vi_end; ++vi) - if (color[*vi] == white_color) - if (has_cycle_dfs(g, *vi, &color[0])) - return true; - return false; + std::vector< default_color_type > color(num_vertices(g), white_color); + graph_traits< file_dep_graph >::vertex_iterator vi, vi_end; + for (boost::tie(vi, vi_end) = vertices(g); vi != vi_end; ++vi) + if (color[*vi] == white_color) + if (has_cycle_dfs(g, *vi, &color[0])) + return true; + return false; } - -int -main(int argc, const char** argv) +int main(int argc, const char** argv) { - std::ifstream file_in(argc >= 2 ? argv[1] : "makefile-dependencies.dat"); - typedef graph_traits < file_dep_graph >::vertices_size_type size_type; - size_type n_vertices; - file_in >> n_vertices; // read in number of vertices - std::istream_iterator < std::pair < size_type, - size_type > > input_begin(file_in), input_end; + std::ifstream file_in(argc >= 2 ? argv[1] : "makefile-dependencies.dat"); + typedef graph_traits< file_dep_graph >::vertices_size_type size_type; + size_type n_vertices; + file_in >> n_vertices; // read in number of vertices + std::istream_iterator< std::pair< size_type, size_type > > input_begin( + file_in), + input_end; #if defined(BOOST_MSVC) && BOOST_MSVC <= 1300 - // VC++ has trouble with the edge iterator constructor - file_dep_graph g(n_vertices); - while (input_begin != input_end) { - size_type i, j; - boost::tie(i, j) = *input_begin++; - add_edge(i, j, g); - } + // VC++ has trouble with the edge iterator constructor + file_dep_graph g(n_vertices); + while (input_begin != input_end) + { + size_type i, j; + boost::tie(i, j) = *input_begin++; + add_edge(i, j, g); + } #else - file_dep_graph g(input_begin, input_end, n_vertices); + file_dep_graph g(input_begin, input_end, n_vertices); #endif - std::vector < std::string > name(num_vertices(g)); - std::ifstream name_in(argc >= 3 ? argv[2] : "makefile-target-names.dat"); - graph_traits < file_dep_graph >::vertex_iterator vi, vi_end; - for (boost::tie(vi, vi_end) = vertices(g); vi != vi_end; ++vi) - name_in >> name[*vi]; + std::vector< std::string > name(num_vertices(g)); + std::ifstream name_in(argc >= 3 ? argv[2] : "makefile-target-names.dat"); + graph_traits< file_dep_graph >::vertex_iterator vi, vi_end; + for (boost::tie(vi, vi_end) = vertices(g); vi != vi_end; ++vi) + name_in >> name[*vi]; - assert(has_cycle(g) == false); - return 0; + assert(has_cycle(g) == false); + return 0; } diff --git a/example/cycle-file-dep2.cpp b/example/cycle-file-dep2.cpp index 046470f3f..678727a22 100644 --- a/example/cycle-file-dep2.cpp +++ b/example/cycle-file-dep2.cpp @@ -1,5 +1,5 @@ //======================================================================= -// Copyright 2001 Jeremy G. Siek, Andrew Lumsdaine, Lie-Quan Lee, +// Copyright 2001 Jeremy G. Siek, Andrew Lumsdaine, Lie-Quan Lee, // // Distributed under the Boost Software License, Version 1.0. (See // accompanying file LICENSE_1_0.txt or copy at @@ -16,135 +16,118 @@ // we get conflict with boost::default_dfs_visitor. using namespace boost; -namespace std { - template - std::istream& operator >> (std::istream & in, std::pair < T, T > &p) - { +namespace std +{ +template < typename T > +std::istream& operator>>(std::istream& in, std::pair< T, T >& p) +{ in >> p.first >> p.second; - return - in; - } + return in; +} } -typedef adjacency_list< - listS, // Store out-edges of each vertex in a std::list - vecS, // Store vertex set in a std::vector - directedS // The file dependency graph is directed - > file_dep_graph; +typedef adjacency_list< listS, // Store out-edges of each vertex in a std::list + vecS, // Store vertex set in a std::vector + directedS // The file dependency graph is directed + > + file_dep_graph; -typedef graph_traits::vertex_descriptor vertex_t; -typedef graph_traits::edge_descriptor edge_t; +typedef graph_traits< file_dep_graph >::vertex_descriptor vertex_t; +typedef graph_traits< file_dep_graph >::edge_descriptor edge_t; -template < typename Visitor > void -dfs_v1(const file_dep_graph & g, vertex_t u, default_color_type * color, - Visitor vis) +template < typename Visitor > +void dfs_v1( + const file_dep_graph& g, vertex_t u, default_color_type* color, Visitor vis) { - color[u] = gray_color; - vis.discover_vertex(u, g); - graph_traits < file_dep_graph >::out_edge_iterator ei, ei_end; - for (boost::tie(ei, ei_end) = out_edges(u, g); ei != ei_end; ++ei) { - if (color[target(*ei, g)] == white_color) { - vis.tree_edge(*ei, g); - dfs_v1(g, target(*ei, g), color, vis); - } else if (color[target(*ei, g)] == gray_color) - vis.back_edge(*ei, g); - else - vis.forward_or_cross_edge(*ei, g); - } - color[u] = black_color; - vis.finish_vertex(u, g); + color[u] = gray_color; + vis.discover_vertex(u, g); + graph_traits< file_dep_graph >::out_edge_iterator ei, ei_end; + for (boost::tie(ei, ei_end) = out_edges(u, g); ei != ei_end; ++ei) + { + if (color[target(*ei, g)] == white_color) + { + vis.tree_edge(*ei, g); + dfs_v1(g, target(*ei, g), color, vis); + } + else if (color[target(*ei, g)] == gray_color) + vis.back_edge(*ei, g); + else + vis.forward_or_cross_edge(*ei, g); + } + color[u] = black_color; + vis.finish_vertex(u, g); } -template < typename Visitor > void -generic_dfs_v1(const file_dep_graph & g, Visitor vis) +template < typename Visitor > +void generic_dfs_v1(const file_dep_graph& g, Visitor vis) { - std::vector < default_color_type > color(num_vertices(g), white_color); - graph_traits < file_dep_graph >::vertex_iterator vi, vi_end; - for (boost::tie(vi, vi_end) = vertices(g); vi != vi_end; ++vi) { - if (color[*vi] == white_color) - dfs_v1(g, *vi, &color[0], vis); - } + std::vector< default_color_type > color(num_vertices(g), white_color); + graph_traits< file_dep_graph >::vertex_iterator vi, vi_end; + for (boost::tie(vi, vi_end) = vertices(g); vi != vi_end; ++vi) + { + if (color[*vi] == white_color) + dfs_v1(g, *vi, &color[0], vis); + } } struct dfs_visitor_default { - template void - discover_vertex(V, const G &) - { - } - - template void - tree_edge(E, const G &) - { - } - - template < typename E, typename G > void - back_edge(E, const G &) - { - } - - template < typename E, typename G > void - forward_or_cross_edge(E, const G &) - { - } - - template < typename V, typename G > void - finish_vertex(V, const G &) - { - } + template < typename V, typename G > void discover_vertex(V, const G&) {} + + template < typename E, typename G > void tree_edge(E, const G&) {} + + template < typename E, typename G > void back_edge(E, const G&) {} + + template < typename E, typename G > void forward_or_cross_edge(E, const G&) + { + } + + template < typename V, typename G > void finish_vertex(V, const G&) {} }; struct cycle_detector : public dfs_visitor_default { - cycle_detector(bool & cycle): - has_cycle(cycle) - { - } - void - back_edge(edge_t, const file_dep_graph &) - { - has_cycle = true; - } - bool & has_cycle; + cycle_detector(bool& cycle) : has_cycle(cycle) {} + void back_edge(edge_t, const file_dep_graph&) { has_cycle = true; } + bool& has_cycle; }; -bool -has_cycle(const file_dep_graph & g) +bool has_cycle(const file_dep_graph& g) { - bool has_cycle = false; - cycle_detector vis(has_cycle); - generic_dfs_v1(g, vis); - return has_cycle; + bool has_cycle = false; + cycle_detector vis(has_cycle); + generic_dfs_v1(g, vis); + return has_cycle; } - -int -main(int argc, const char** argv) +int main(int argc, const char** argv) { - std::ifstream file_in(argc >= 2 ? argv[1] : "makefile-dependencies.dat"); - typedef graph_traits ::vertices_size_type size_type; - size_type n_vertices; - file_in >> n_vertices; // read in number of vertices - std::istream_iterator < std::pair < size_type, - size_type > >input_begin(file_in), input_end; + std::ifstream file_in(argc >= 2 ? argv[1] : "makefile-dependencies.dat"); + typedef graph_traits< file_dep_graph >::vertices_size_type size_type; + size_type n_vertices; + file_in >> n_vertices; // read in number of vertices + std::istream_iterator< std::pair< size_type, size_type > > input_begin( + file_in), + input_end; #if defined(BOOST_MSVC) && BOOST_MSVC <= 1300 - // VC++ has trouble with the edge iterator constructor - file_dep_graph g(n_vertices); - while (input_begin != input_end) { - size_type i, j; - boost::tie(i, j) = *input_begin++; - add_edge(i, j, g); - } + // VC++ has trouble with the edge iterator constructor + file_dep_graph g(n_vertices); + while (input_begin != input_end) + { + size_type i, j; + boost::tie(i, j) = *input_begin++; + add_edge(i, j, g); + } #else - file_dep_graph g(input_begin, input_end, n_vertices); + file_dep_graph g(input_begin, input_end, n_vertices); #endif - std::vector < std::string > name(num_vertices(g)); - std::ifstream name_in(argc >= 3 ? argv[2] : "makefile-target-names.dat"); - graph_traits < file_dep_graph >::vertex_iterator vi, vi_end; - for (boost::tie(vi, vi_end) = vertices(g); vi != vi_end; ++vi) - name_in >> name[*vi]; + std::vector< std::string > name(num_vertices(g)); + std::ifstream name_in(argc >= 3 ? argv[2] : "makefile-target-names.dat"); + graph_traits< file_dep_graph >::vertex_iterator vi, vi_end; + for (boost::tie(vi, vi_end) = vertices(g); vi != vi_end; ++vi) + name_in >> name[*vi]; - assert(has_cycle(g) == false); - return 0; + assert(has_cycle(g) == false); + return 0; } diff --git a/example/cycle_canceling_example.cpp b/example/cycle_canceling_example.cpp index 46e85f149..63033848c 100644 --- a/example/cycle_canceling_example.cpp +++ b/example/cycle_canceling_example.cpp @@ -1,6 +1,6 @@ //======================================================================= // Copyright 2013 University of Warsaw. -// Authors: Piotr Wygocki +// Authors: Piotr Wygocki // // Distributed under the Boost Software License, Version 1.0. (See // accompanying file LICENSE_1_0.txt or copy at @@ -12,9 +12,9 @@ #include "../test/min_cost_max_flow_utils.hpp" - -int main() { - boost::SampleGraph::vertex_descriptor s,t; +int main() +{ + boost::SampleGraph::vertex_descriptor s, t; boost::SampleGraph::Graph g; boost::SampleGraph::getSampleGraph(g, s, t); @@ -25,4 +25,3 @@ int main() { assert(cost == 29); return 0; } - diff --git a/example/cycle_ratio_example.cpp b/example/cycle_ratio_example.cpp index d63d62923..1ad9ebc69 100644 --- a/example/cycle_ratio_example.cpp +++ b/example/cycle_ratio_example.cpp @@ -18,27 +18,25 @@ */ using namespace boost; -typedef adjacency_list< - listS, listS, directedS, - property, - property< - edge_weight_t, double, property - > -> grap_real_t; +typedef adjacency_list< listS, listS, directedS, + property< vertex_index_t, int >, + property< edge_weight_t, double, property< edge_weight2_t, double > > > + grap_real_t; -template -void gen_rand_graph(TG &g, size_t nV, size_t nE) +template < typename TG > void gen_rand_graph(TG& g, size_t nV, size_t nE) { g.clear(); mt19937 rng; rng.seed(uint32_t(time(0))); boost::generate_random_graph(g, nV, nE, rng, true, true); - boost::uniform_real<> ur(-1,10); - boost::variate_generator > ew1rg(rng, ur); - randomize_property(g, ew1rg); - boost::uniform_int uint(1,5); - boost::variate_generator > ew2rg(rng, uint); - randomize_property(g, ew2rg); + boost::uniform_real<> ur(-1, 10); + boost::variate_generator< boost::mt19937&, boost::uniform_real<> > ew1rg( + rng, ur); + randomize_property< edge_weight_t >(g, ew1rg); + boost::uniform_int< size_t > uint(1, 5); + boost::variate_generator< boost::mt19937&, boost::uniform_int< size_t > > + ew2rg(rng, uint); + randomize_property< edge_weight2_t >(g, ew2rg); } int main(int argc, char* argv[]) @@ -46,38 +44,42 @@ int main(int argc, char* argv[]) using std::cout; using std::endl; const double epsilon = 0.0000001; - double min_cr, max_cr; ///Minimum and maximum cycle ratio - typedef std::vector::edge_descriptor> ccReal_t; - ccReal_t cc; ///critical cycle + double min_cr, max_cr; /// Minimum and maximum cycle ratio + typedef std::vector< graph_traits< grap_real_t >::edge_descriptor > + ccReal_t; + ccReal_t cc; /// critical cycle grap_real_t tgr; - property_map::type vim = get(vertex_index, tgr); - property_map::type ew1 = get(edge_weight, tgr); - property_map::type ew2 = get(edge_weight2, tgr); + property_map< grap_real_t, vertex_index_t >::type vim + = get(vertex_index, tgr); + property_map< grap_real_t, edge_weight_t >::type ew1 + = get(edge_weight, tgr); + property_map< grap_real_t, edge_weight2_t >::type ew2 + = get(edge_weight2, tgr); gen_rand_graph(tgr, 1000, 30000); cout << "Vertices number: " << num_vertices(tgr) << endl; cout << "Edges number: " << num_edges(tgr) << endl; int i = 0; - graph_traits::vertex_iterator vi, vi_end; - for (boost::tie(vi, vi_end) = vertices(tgr); vi != vi_end; vi++) { - vim[*vi] = i++; ///Initialize vertex index property + graph_traits< grap_real_t >::vertex_iterator vi, vi_end; + for (boost::tie(vi, vi_end) = vertices(tgr); vi != vi_end; vi++) + { + vim[*vi] = i++; /// Initialize vertex index property } max_cr = maximum_cycle_ratio(tgr, vim, ew1, ew2); cout << "Maximum cycle ratio is " << max_cr << endl; min_cr = minimum_cycle_ratio(tgr, vim, ew1, ew2, &cc); cout << "Minimum cycle ratio is " << min_cr << endl; - std::pair cr(.0,.0); + std::pair< double, double > cr(.0, .0); cout << "Critical cycle:\n"; for (ccReal_t::iterator itr = cc.begin(); itr != cc.end(); ++itr) { cr.first += ew1[*itr]; cr.second += ew2[*itr]; - std::cout << "(" << vim[source(*itr, tgr)] << "," << - vim[target(*itr, tgr)] << ") "; + std::cout << "(" << vim[source(*itr, tgr)] << "," + << vim[target(*itr, tgr)] << ") "; } cout << endl; assert(std::abs(cr.first / cr.second - min_cr) < epsilon * 2); return EXIT_SUCCESS; } - diff --git a/example/dag_shortest_paths.cpp b/example/dag_shortest_paths.cpp index 97140c8e4..4e22457dd 100644 --- a/example/dag_shortest_paths.cpp +++ b/example/dag_shortest_paths.cpp @@ -24,46 +24,55 @@ int main() { - using namespace boost; - typedef adjacency_list, property > graph_t; - graph_t g(6); - enum verts { r, s, t, u, v, x }; - char name[] = "rstuvx"; - add_edge(r, s, 5, g); - add_edge(r, t, 3, g); - add_edge(s, t, 2, g); - add_edge(s, u, 6, g); - add_edge(t, u, 7, g); - add_edge(t, v, 4, g); - add_edge(t, x, 2, g); - add_edge(u, v, -1, g); - add_edge(u, x, 1, g); - add_edge(v, x, -2, g); + using namespace boost; + typedef adjacency_list< vecS, vecS, directedS, + property< vertex_distance_t, int >, property< edge_weight_t, int > > + graph_t; + graph_t g(6); + enum verts + { + r, + s, + t, + u, + v, + x + }; + char name[] = "rstuvx"; + add_edge(r, s, 5, g); + add_edge(r, t, 3, g); + add_edge(s, t, 2, g); + add_edge(s, u, 6, g); + add_edge(t, u, 7, g); + add_edge(t, v, 4, g); + add_edge(t, x, 2, g); + add_edge(u, v, -1, g); + add_edge(u, x, 1, g); + add_edge(v, x, -2, g); - property_map::type - d_map = get(vertex_distance, g); + property_map< graph_t, vertex_distance_t >::type d_map + = get(vertex_distance, g); #if defined(BOOST_MSVC) && BOOST_MSVC <= 1300 - // VC++ has trouble with the named-parameter mechanism, so - // we make a direct call to the underlying implementation function. - std::vector color(num_vertices(g)); - std::vector pred(num_vertices(g)); - default_dijkstra_visitor vis; - std::less compare; - closed_plus combine; - property_map::type w_map = get(edge_weight, g); - dag_shortest_paths(g, s, d_map, w_map, &color[0], &pred[0], - vis, compare, combine, (std::numeric_limits::max)(), 0); + // VC++ has trouble with the named-parameter mechanism, so + // we make a direct call to the underlying implementation function. + std::vector< default_color_type > color(num_vertices(g)); + std::vector< std::size_t > pred(num_vertices(g)); + default_dijkstra_visitor vis; + std::less< int > compare; + closed_plus< int > combine; + property_map< graph_t, edge_weight_t >::type w_map = get(edge_weight, g); + dag_shortest_paths(g, s, d_map, w_map, &color[0], &pred[0], vis, compare, + combine, (std::numeric_limits< int >::max)(), 0); #else - dag_shortest_paths(g, s, distance_map(d_map)); + dag_shortest_paths(g, s, distance_map(d_map)); #endif - graph_traits::vertex_iterator vi , vi_end; - for (boost::tie(vi, vi_end) = vertices(g); vi != vi_end; ++vi) - if (d_map[*vi] == (std::numeric_limits::max)()) - std::cout << name[*vi] << ": inifinity\n"; - else - std::cout << name[*vi] << ": " << d_map[*vi] << '\n'; - return 0; + graph_traits< graph_t >::vertex_iterator vi, vi_end; + for (boost::tie(vi, vi_end) = vertices(g); vi != vi_end; ++vi) + if (d_map[*vi] == (std::numeric_limits< int >::max)()) + std::cout << name[*vi] << ": inifinity\n"; + else + std::cout << name[*vi] << ": " << d_map[*vi] << '\n'; + return 0; } diff --git a/example/data1.txt b/example/data1.txt index acf54ecfc..d8db9eb5d 100644 --- a/example/data1.txt +++ b/example/data1.txt @@ -8,5 +8,5 @@ n 5 # the edges e 1 2 -0 1 -2 0 +0 1 +2 0 diff --git a/example/dave.cpp b/example/dave.cpp index 04c69f888..0cf807fb8 100644 --- a/example/dave.cpp +++ b/example/dave.cpp @@ -45,7 +45,7 @@ using namespace boost; a Sample Output: -a --> c d +a --> c d b --> a d c --> f d --> c e f @@ -67,183 +67,172 @@ c(3); f f(9); g e e(4); g b g(7); -b(14); d a +b(14); d a */ -typedef property > VProperty; +typedef property< vertex_color_t, default_color_type, + property< vertex_distance_t, int > > + VProperty; typedef int weight_t; -typedef property EProperty; +typedef property< edge_weight_t, weight_t > EProperty; -typedef adjacency_list Graph; +typedef adjacency_list< vecS, vecS, directedS, VProperty, EProperty > Graph; - - -template -struct endl_printer - : public boost::base_visitor< endl_printer > +template < class Tag > +struct endl_printer : public boost::base_visitor< endl_printer< Tag > > { - typedef Tag event_filter; - endl_printer(std::ostream& os) : m_os(os) { } - template - void operator()(T, Graph&) { m_os << std::endl; } - std::ostream& m_os; + typedef Tag event_filter; + endl_printer(std::ostream& os) : m_os(os) {} + template < class T, class Graph > void operator()(T, Graph&) + { + m_os << std::endl; + } + std::ostream& m_os; }; -template -endl_printer print_endl(std::ostream& os, Tag) { - return endl_printer(os); +template < class Tag > endl_printer< Tag > print_endl(std::ostream& os, Tag) +{ + return endl_printer< Tag >(os); } -template -struct edge_printer - : public boost::base_visitor< edge_printer > +template < class PA, class Tag > +struct edge_printer : public boost::base_visitor< edge_printer< PA, Tag > > { - typedef Tag event_filter; + typedef Tag event_filter; - edge_printer(PA pa, std::ostream& os) : m_pa(pa), m_os(os) { } + edge_printer(PA pa, std::ostream& os) : m_pa(pa), m_os(os) {} - template - void operator()(T x, Graph& g) { - m_os << "(" << get(m_pa, source(x, g)) << "," - << get(m_pa, target(x, g)) << ") "; - } - PA m_pa; - std::ostream& m_os; + template < class T, class Graph > void operator()(T x, Graph& g) + { + m_os << "(" << get(m_pa, source(x, g)) << "," << get(m_pa, target(x, g)) + << ") "; + } + PA m_pa; + std::ostream& m_os; }; -template -edge_printer -print_edge(PA pa, std::ostream& os, Tag) { - return edge_printer(pa, os); +template < class PA, class Tag > +edge_printer< PA, Tag > print_edge(PA pa, std::ostream& os, Tag) +{ + return edge_printer< PA, Tag >(pa, os); } - -template -struct graph_copier - : public boost::base_visitor > +template < class NewGraph, class Tag > +struct graph_copier +: public boost::base_visitor< graph_copier< NewGraph, Tag > > { - typedef Tag event_filter; + typedef Tag event_filter; + + graph_copier(NewGraph& graph) : new_g(graph) {} - graph_copier(NewGraph& graph) : new_g(graph) { } + template < class Edge, class Graph > void operator()(Edge e, Graph& g) + { + add_edge(source(e, g), target(e, g), new_g); + } - template - void operator()(Edge e, Graph& g) { - add_edge(source(e, g), target(e, g), new_g); - } private: - NewGraph& new_g; + NewGraph& new_g; }; -template -inline graph_copier -copy_graph(NewGraph& g, Tag) { - return graph_copier(g); +template < class NewGraph, class Tag > +inline graph_copier< NewGraph, Tag > copy_graph(NewGraph& g, Tag) +{ + return graph_copier< NewGraph, Tag >(g); } -template -void print(Graph& G, Name name) +template < class Graph, class Name > void print(Graph& G, Name name) { - typename boost::graph_traits::vertex_iterator ui, uiend; - for (boost::tie(ui, uiend) = vertices(G); ui != uiend; ++ui) { - cout << name[*ui] << " --> "; - typename boost::graph_traits::adjacency_iterator vi, viend; - for(boost::tie(vi, viend) = adjacent_vertices(*ui, G); vi != viend; ++vi) - cout << name[*vi] << " "; - cout << endl; - } - + typename boost::graph_traits< Graph >::vertex_iterator ui, uiend; + for (boost::tie(ui, uiend) = vertices(G); ui != uiend; ++ui) + { + cout << name[*ui] << " --> "; + typename boost::graph_traits< Graph >::adjacency_iterator vi, viend; + for (boost::tie(vi, viend) = adjacent_vertices(*ui, G); vi != viend; + ++vi) + cout << name[*vi] << " "; + cout << endl; + } } - -int -main(int , char* []) +int main(int, char*[]) { - // Name and ID numbers for the vertices - char name[] = "abcdefg"; - enum { a, b, c, d, e, f, g, N}; - - Graph G(N); - boost::property_map::type - vertex_id = get(vertex_index, G); - - std::vector distance(N, (numeric_limits::max)()); - typedef boost::graph_traits::vertex_descriptor Vertex; - std::vector parent(N); - - typedef std::pair E; - - E edges[] = { E(a,c), E(a,d), - E(b,a), E(b,d), - E(c,f), - E(d,c), E(d,e), E(d,f), - E(e,b), E(e,g), - E(f,e), E(f,g) }; - - int weight[] = { 3, 4, - 6, 8, - 12, - 7, 0, 5, - 10, 3, - 1, 2 }; - - for (int i = 0; i < 12; ++i) - add_edge(edges[i].first, edges[i].second, weight[i], G); - - print(G, name); - - adjacency_list > G_copy(N); - - cout << "Starting graph:" << endl; - - std::ostream_iterator cout_int(std::cout, " "); - std::ostream_iterator cout_char(std::cout, " "); - - boost::queue Q; - boost::breadth_first_search - (G, vertex(a, G), Q, - make_bfs_visitor( - boost::make_list - (write_property(make_iterator_property_map(name, vertex_id, - name[0]), - cout_char, on_examine_vertex()), - write_property(make_iterator_property_map(distance.begin(), - vertex_id, - distance[0]), - cout_int, on_examine_vertex()), - print_edge(make_iterator_property_map(name, vertex_id, - name[0]), - std::cout, on_examine_edge()), - print_endl(std::cout, on_finish_vertex()))), - get(vertex_color, G)); - - std::cout << "about to call dijkstra's" << std::endl; - - parent[vertex(a, G)] = vertex(a, G); - boost::dijkstra_shortest_paths - (G, vertex(a, G), - distance_map(make_iterator_property_map(distance.begin(), vertex_id, - distance[0])). - predecessor_map(make_iterator_property_map(parent.begin(), vertex_id, - parent[0])). - visitor(make_dijkstra_visitor(copy_graph(G_copy, on_examine_edge())))); - - cout << endl; - cout << "Result:" << endl; - boost::breadth_first_search - (G, vertex(a, G), - visitor(make_bfs_visitor( - boost::make_list - (write_property(make_iterator_property_map(name, vertex_id, - name[0]), - cout_char, on_examine_vertex()), - write_property(make_iterator_property_map(distance.begin(), - vertex_id, - distance[0]), - cout_int, on_examine_vertex()), - print_edge(make_iterator_property_map(name, vertex_id, - name[0]), - std::cout, on_examine_edge()), - print_endl(std::cout, on_finish_vertex()))))); - - return 0; + // Name and ID numbers for the vertices + char name[] = "abcdefg"; + enum + { + a, + b, + c, + d, + e, + f, + g, + N + }; + + Graph G(N); + boost::property_map< Graph, vertex_index_t >::type vertex_id + = get(vertex_index, G); + + std::vector< weight_t > distance(N, (numeric_limits< weight_t >::max)()); + typedef boost::graph_traits< Graph >::vertex_descriptor Vertex; + std::vector< Vertex > parent(N); + + typedef std::pair< int, int > E; + + E edges[] = { E(a, c), E(a, d), E(b, a), E(b, d), E(c, f), E(d, c), E(d, e), + E(d, f), E(e, b), E(e, g), E(f, e), E(f, g) }; + + int weight[] = { 3, 4, 6, 8, 12, 7, 0, 5, 10, 3, 1, 2 }; + + for (int i = 0; i < 12; ++i) + add_edge(edges[i].first, edges[i].second, weight[i], G); + + print(G, name); + + adjacency_list< listS, vecS, directedS, + property< vertex_color_t, default_color_type > > + G_copy(N); + + cout << "Starting graph:" << endl; + + std::ostream_iterator< int > cout_int(std::cout, " "); + std::ostream_iterator< char > cout_char(std::cout, " "); + + boost::queue< Vertex > Q; + boost::breadth_first_search(G, vertex(a, G), Q, + make_bfs_visitor(boost::make_list( + write_property(make_iterator_property_map(name, vertex_id, name[0]), + cout_char, on_examine_vertex()), + write_property(make_iterator_property_map( + distance.begin(), vertex_id, distance[0]), + cout_int, on_examine_vertex()), + print_edge(make_iterator_property_map(name, vertex_id, name[0]), + std::cout, on_examine_edge()), + print_endl(std::cout, on_finish_vertex()))), + get(vertex_color, G)); + + std::cout << "about to call dijkstra's" << std::endl; + + parent[vertex(a, G)] = vertex(a, G); + boost::dijkstra_shortest_paths(G, vertex(a, G), + distance_map(make_iterator_property_map( + distance.begin(), vertex_id, distance[0])) + .predecessor_map(make_iterator_property_map( + parent.begin(), vertex_id, parent[0])) + .visitor( + make_dijkstra_visitor(copy_graph(G_copy, on_examine_edge())))); + + cout << endl; + cout << "Result:" << endl; + boost::breadth_first_search(G, vertex(a, G), + visitor(make_bfs_visitor(boost::make_list( + write_property(make_iterator_property_map(name, vertex_id, name[0]), + cout_char, on_examine_vertex()), + write_property(make_iterator_property_map( + distance.begin(), vertex_id, distance[0]), + cout_int, on_examine_vertex()), + print_edge(make_iterator_property_map(name, vertex_id, name[0]), + std::cout, on_examine_edge()), + print_endl(std::cout, on_finish_vertex()))))); + + return 0; } diff --git a/example/dave.expected b/example/dave.expected index 65efe7b4b..3ff1506b1 100644 --- a/example/dave.expected +++ b/example/dave.expected @@ -1,24 +1,24 @@ -a --> c d -b --> a d -c --> f -d --> c e f -e --> b g -f --> e g -g --> +a --> c d +b --> a d +c --> f +d --> c e f +e --> b g +f --> e g +g --> Starting graph: -a 2147483647 (a,c) (a,d) -c 2147483647 (c,f) -d 2147483647 (d,c) (d,e) (d,f) -f 2147483647 (f,e) (f,g) -e 2147483647 (e,b) (e,g) -g 2147483647 -b 2147483647 (b,a) (b,d) +a 2147483647 (a,c) (a,d) +c 2147483647 (c,f) +d 2147483647 (d,c) (d,e) (d,f) +f 2147483647 (f,e) (f,g) +e 2147483647 (e,b) (e,g) +g 2147483647 +b 2147483647 (b,a) (b,d) Result: -a 0 (a,c) (a,d) -c 3 (c,f) -d 4 (d,c) (d,e) (d,f) -f 9 (f,e) (f,g) -e 4 (e,b) (e,g) -g 7 -b 14 (b,a) (b,d) +a 0 (a,c) (a,d) +c 3 (c,f) +d 4 (d,c) (d,e) (d,f) +f 9 (f,e) (f,g) +e 4 (e,b) (e,g) +g 7 +b 14 (b,a) (b,d) diff --git a/example/default-constructor.cpp b/example/default-constructor.cpp index 00e1298cd..71d9b3ef7 100644 --- a/example/default-constructor.cpp +++ b/example/default-constructor.cpp @@ -1,5 +1,5 @@ //======================================================================= -// Copyright 2001 Jeremy G. Siek, Andrew Lumsdaine, Lie-Quan Lee, +// Copyright 2001 Jeremy G. Siek, Andrew Lumsdaine, Lie-Quan Lee, // // Distributed under the Boost Software License, Version 1.0. (See // accompanying file LICENSE_1_0.txt or copy at @@ -11,36 +11,35 @@ using namespace boost; -template < typename Graph > void -read_graph_file(std::istream & in, Graph & g) +template < typename Graph > void read_graph_file(std::istream& in, Graph& g) { - typedef typename graph_traits < Graph >::vertices_size_type size_type; - size_type n_vertices; - in >> n_vertices; // read in number of vertices - for (size_type i = 0; i < n_vertices; ++i) // Add n vertices to the graph - add_vertex(g); - size_type u, v; - while (in >> u) // Read in pairs of integers as edges - if (in >> v) - add_edge(u, v, g); - else - break; + typedef typename graph_traits< Graph >::vertices_size_type size_type; + size_type n_vertices; + in >> n_vertices; // read in number of vertices + for (size_type i = 0; i < n_vertices; ++i) // Add n vertices to the graph + add_vertex(g); + size_type u, v; + while (in >> u) // Read in pairs of integers as edges + if (in >> v) + add_edge(u, v, g); + else + break; } - -int -main(int argc, const char** argv) +int main(int argc, const char** argv) { - typedef adjacency_list < listS, // Store out-edges of each vertex in a std::list - vecS, // Store vertex set in a std::vector - directedS // The graph is directed - > graph_type; + typedef adjacency_list< listS, // Store out-edges of each vertex in a + // std::list + vecS, // Store vertex set in a std::vector + directedS // The graph is directed + > + graph_type; - graph_type g; // use default constructor to create empty graph - std::ifstream file_in(argc >= 2 ? argv[1] : "makefile-dependencies.dat"); - read_graph_file(file_in, g); + graph_type g; // use default constructor to create empty graph + std::ifstream file_in(argc >= 2 ? argv[1] : "makefile-dependencies.dat"); + read_graph_file(file_in, g); - assert(num_vertices(g) == 15); - assert(num_edges(g) == 19); - return 0; + assert(num_vertices(g) == 15); + assert(num_edges(g) == 19); + return 0; } diff --git a/example/default-constructor2.cpp b/example/default-constructor2.cpp index c455bd2f8..18f886057 100644 --- a/example/default-constructor2.cpp +++ b/example/default-constructor2.cpp @@ -1,5 +1,5 @@ //======================================================================= -// Copyright 2001 Jeremy G. Siek, Andrew Lumsdaine, Lie-Quan Lee, +// Copyright 2001 Jeremy G. Siek, Andrew Lumsdaine, Lie-Quan Lee, // // Distributed under the Boost Software License, Version 1.0. (See // accompanying file LICENSE_1_0.txt or copy at @@ -11,39 +11,38 @@ using namespace boost; -template < typename Graph > void -read_graph_file(std::istream & in, Graph & g) +template < typename Graph > void read_graph_file(std::istream& in, Graph& g) { - typedef typename graph_traits < Graph >::vertex_descriptor Vertex; - typedef typename graph_traits < Graph >::vertices_size_type size_type; - size_type n_vertices; - in >> n_vertices; // read in number of vertices - std::vector < Vertex > vertex_set(n_vertices); - for (size_type i = 0; i < n_vertices; ++i) - vertex_set[i] = add_vertex(g); + typedef typename graph_traits< Graph >::vertex_descriptor Vertex; + typedef typename graph_traits< Graph >::vertices_size_type size_type; + size_type n_vertices; + in >> n_vertices; // read in number of vertices + std::vector< Vertex > vertex_set(n_vertices); + for (size_type i = 0; i < n_vertices; ++i) + vertex_set[i] = add_vertex(g); - size_type u, v; - while (in >> u) - if (in >> v) - add_edge(vertex_set[u], vertex_set[v], g); - else - break; + size_type u, v; + while (in >> u) + if (in >> v) + add_edge(vertex_set[u], vertex_set[v], g); + else + break; } - -int -main(int argc, const char** argv) +int main(int argc, const char** argv) { - typedef adjacency_list < listS, // Store out-edges of each vertex in a std::list - vecS, // Store vertex set in a std::vector - directedS // The graph is directed - > graph_type; + typedef adjacency_list< listS, // Store out-edges of each vertex in a + // std::list + vecS, // Store vertex set in a std::vector + directedS // The graph is directed + > + graph_type; - graph_type g; // use default constructor to create empty graph - std::ifstream file_in(argc >= 2 ? argv[1] : "makefile-dependencies.dat"); - read_graph_file(file_in, g); + graph_type g; // use default constructor to create empty graph + std::ifstream file_in(argc >= 2 ? argv[1] : "makefile-dependencies.dat"); + read_graph_file(file_in, g); - assert(num_vertices(g) == 15); - assert(num_edges(g) == 19); - return 0; + assert(num_vertices(g) == 15); + assert(num_edges(g) == 19); + return 0; } diff --git a/example/degree_centrality.cpp b/example/degree_centrality.cpp index a8aae31cb..1dbee79b4 100644 --- a/example/degree_centrality.cpp +++ b/example/degree_centrality.cpp @@ -4,7 +4,6 @@ // Boost Software License, Version 1.0 (See accompanying file // LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) - //[degree_centrality_example #include #include @@ -25,22 +24,21 @@ struct Actor }; // Declare the graph type and its vertex and edge types. -typedef undirected_graph Graph; -typedef graph_traits::vertex_descriptor Vertex; -typedef graph_traits::edge_descriptor Edge; +typedef undirected_graph< Actor > Graph; +typedef graph_traits< Graph >::vertex_descriptor Vertex; +typedef graph_traits< Graph >::edge_descriptor Edge; // The name map provides an abstract accessor for the names of // each vertex. This is used during graph creation. -typedef property_map::type NameMap; +typedef property_map< Graph, string Actor::* >::type NameMap; // Declare a container type for degree centralities and its // corresponding property map. -typedef exterior_vertex_property CentralityProperty; +typedef exterior_vertex_property< Graph, unsigned > CentralityProperty; typedef CentralityProperty::container_type CentralityContainer; typedef CentralityProperty::map_type CentralityMap; -int -main(int argc, char *argv[]) +int main(int argc, char* argv[]) { // Create the graph and a property map that provides access // to the actor names. @@ -56,10 +54,11 @@ main(int argc, char *argv[]) all_degree_centralities(g, cm); // Print the degree centrality of each vertex. - graph_traits::vertex_iterator i, end; - for(boost::tie(i, end) = vertices(g); i != end; ++i) { - cout << setiosflags(ios::left) << setw(12) - << g[*i].name << cm[*i] << endl; + graph_traits< Graph >::vertex_iterator i, end; + for (boost::tie(i, end) = vertices(g); i != end; ++i) + { + cout << setiosflags(ios::left) << setw(12) << g[*i].name << cm[*i] + << endl; } return 0; diff --git a/example/dfs-example.cpp b/example/dfs-example.cpp index 0117b81dc..fff17bfdd 100644 --- a/example/dfs-example.cpp +++ b/example/dfs-example.cpp @@ -1,5 +1,5 @@ //======================================================================= -// Copyright 2001 Jeremy G. Siek, Andrew Lumsdaine, Lie-Quan Lee, +// Copyright 2001 Jeremy G. Siek, Andrew Lumsdaine, Lie-Quan Lee, // // Distributed under the Boost Software License, Version 1.0. (See // accompanying file LICENSE_1_0.txt or copy at @@ -13,84 +13,92 @@ #include using namespace boost; -template < typename TimeMap > class dfs_time_visitor:public default_dfs_visitor { - typedef typename property_traits < TimeMap >::value_type T; +template < typename TimeMap > +class dfs_time_visitor : public default_dfs_visitor +{ + typedef typename property_traits< TimeMap >::value_type T; + public: - dfs_time_visitor(TimeMap dmap, TimeMap fmap, T & t) -: m_dtimemap(dmap), m_ftimemap(fmap), m_time(t) { - } - template < typename Vertex, typename Graph > - void discover_vertex(Vertex u, const Graph & g) const - { - put(m_dtimemap, u, m_time++); - } - template < typename Vertex, typename Graph > - void finish_vertex(Vertex u, const Graph & g) const - { - put(m_ftimemap, u, m_time++); - } - TimeMap m_dtimemap; - TimeMap m_ftimemap; - T & m_time; + dfs_time_visitor(TimeMap dmap, TimeMap fmap, T& t) + : m_dtimemap(dmap), m_ftimemap(fmap), m_time(t) + { + } + template < typename Vertex, typename Graph > + void discover_vertex(Vertex u, const Graph& g) const + { + put(m_dtimemap, u, m_time++); + } + template < typename Vertex, typename Graph > + void finish_vertex(Vertex u, const Graph& g) const + { + put(m_ftimemap, u, m_time++); + } + TimeMap m_dtimemap; + TimeMap m_ftimemap; + T& m_time; }; - -int -main() +int main() { - // Select the graph type we wish to use - typedef adjacency_list < vecS, vecS, directedS > graph_t; - typedef graph_traits < graph_t >::vertices_size_type size_type; - // Set up the vertex names - enum - { u, v, w, x, y, z, N }; - char name[] = { 'u', 'v', 'w', 'x', 'y', 'z' }; - // Specify the edges in the graph - typedef std::pair < int, int >E; - E edge_array[] = { E(u, v), E(u, x), E(x, v), E(y, x), - E(v, y), E(w, y), E(w, z), E(z, z) - }; + // Select the graph type we wish to use + typedef adjacency_list< vecS, vecS, directedS > graph_t; + typedef graph_traits< graph_t >::vertices_size_type size_type; + // Set up the vertex names + enum + { + u, + v, + w, + x, + y, + z, + N + }; + char name[] = { 'u', 'v', 'w', 'x', 'y', 'z' }; + // Specify the edges in the graph + typedef std::pair< int, int > E; + E edge_array[] = { E(u, v), E(u, x), E(x, v), E(y, x), E(v, y), E(w, y), + E(w, z), E(z, z) }; #if defined(BOOST_MSVC) && BOOST_MSVC <= 1300 - graph_t g(N); - for (std::size_t j = 0; j < sizeof(edge_array) / sizeof(E); ++j) - add_edge(edge_array[j].first, edge_array[j].second, g); + graph_t g(N); + for (std::size_t j = 0; j < sizeof(edge_array) / sizeof(E); ++j) + add_edge(edge_array[j].first, edge_array[j].second, g); #else - graph_t g(edge_array, edge_array + sizeof(edge_array) / sizeof(E), N); + graph_t g(edge_array, edge_array + sizeof(edge_array) / sizeof(E), N); #endif - // discover time and finish time properties - std::vector < size_type > dtime(num_vertices(g)); - std::vector < size_type > ftime(num_vertices(g)); - typedef - iterator_property_map::iterator, - property_map::const_type> - time_pm_type; - time_pm_type dtime_pm(dtime.begin(), get(vertex_index, g)); - time_pm_type ftime_pm(ftime.begin(), get(vertex_index, g)); - size_type t = 0; - dfs_time_visitor < time_pm_type >vis(dtime_pm, ftime_pm, t); + // discover time and finish time properties + std::vector< size_type > dtime(num_vertices(g)); + std::vector< size_type > ftime(num_vertices(g)); + typedef iterator_property_map< std::vector< size_type >::iterator, + property_map< graph_t, vertex_index_t >::const_type > + time_pm_type; + time_pm_type dtime_pm(dtime.begin(), get(vertex_index, g)); + time_pm_type ftime_pm(ftime.begin(), get(vertex_index, g)); + size_type t = 0; + dfs_time_visitor< time_pm_type > vis(dtime_pm, ftime_pm, t); - depth_first_search(g, visitor(vis)); + depth_first_search(g, visitor(vis)); - // use std::sort to order the vertices by their discover time - std::vector < size_type > discover_order(N); - integer_range < size_type > r(0, N); - std::copy(r.begin(), r.end(), discover_order.begin()); - std::sort(discover_order.begin(), discover_order.end(), - indirect_cmp < time_pm_type, std::less < size_type > >(dtime_pm)); - std::cout << "order of discovery: "; - int i; - for (i = 0; i < N; ++i) - std::cout << name[discover_order[i]] << " "; + // use std::sort to order the vertices by their discover time + std::vector< size_type > discover_order(N); + integer_range< size_type > r(0, N); + std::copy(r.begin(), r.end(), discover_order.begin()); + std::sort(discover_order.begin(), discover_order.end(), + indirect_cmp< time_pm_type, std::less< size_type > >(dtime_pm)); + std::cout << "order of discovery: "; + int i; + for (i = 0; i < N; ++i) + std::cout << name[discover_order[i]] << " "; - std::vector < size_type > finish_order(N); - std::copy(r.begin(), r.end(), finish_order.begin()); - std::sort(finish_order.begin(), finish_order.end(), - indirect_cmp < time_pm_type, std::less < size_type > >(ftime_pm)); - std::cout << std::endl << "order of finish: "; - for (i = 0; i < N; ++i) - std::cout << name[finish_order[i]] << " "; - std::cout << std::endl; + std::vector< size_type > finish_order(N); + std::copy(r.begin(), r.end(), finish_order.begin()); + std::sort(finish_order.begin(), finish_order.end(), + indirect_cmp< time_pm_type, std::less< size_type > >(ftime_pm)); + std::cout << std::endl << "order of finish: "; + for (i = 0; i < N; ++i) + std::cout << name[finish_order[i]] << " "; + std::cout << std::endl; - return EXIT_SUCCESS; + return EXIT_SUCCESS; } diff --git a/example/dfs-parenthesis.cpp b/example/dfs-parenthesis.cpp index 71b21b28d..a391a64d0 100644 --- a/example/dfs-parenthesis.cpp +++ b/example/dfs-parenthesis.cpp @@ -1,5 +1,5 @@ //======================================================================= -// Copyright 2001 Jeremy G. Siek, Andrew Lumsdaine, Lie-Quan Lee, +// Copyright 2001 Jeremy G. Siek, Andrew Lumsdaine, Lie-Quan Lee, // // Distributed under the Boost Software License, Version 1.0. (See // accompanying file LICENSE_1_0.txt or copy at @@ -9,8 +9,8 @@ /* IMPORTANT!!! ~~~~~~~~~~~~ - This example uses interfaces that have been deprecated and removed from Boost.Grpah. - Someone needs to update it, as it does NOT compile. + This example uses interfaces that have been deprecated and removed from + Boost.Grpah. Someone needs to update it, as it does NOT compile. */ #include @@ -20,36 +20,34 @@ char name[] = "abcdefghij"; struct parenthesis_visitor : public boost::default_dfs_visitor { - template void - start_vertex(Vertex v, const Graph &) - { - std::cout << ' '; - } - template void - discover_vertex(Vertex v, const Graph &) - { - std::cout << "(" << name[v] << ' '; - } - template void - finish_vertex(Vertex v, const Graph &) - { - std::cout << ' ' << name[v] << ")"; - } + template < class Vertex, class Graph > + void start_vertex(Vertex v, const Graph&) + { + std::cout << ' '; + } + template < class Vertex, class Graph > + void discover_vertex(Vertex v, const Graph&) + { + std::cout << "(" << name[v] << ' '; + } + template < class Vertex, class Graph > + void finish_vertex(Vertex v, const Graph&) + { + std::cout << ' ' << name[v] << ")"; + } }; -int -main() +int main() { - using namespace boost; - GraphvizGraph g; - read_graphviz("figs/dfs-example.dot", g); - graph_traits < GraphvizGraph >::edge_iterator e, e_end; - for (boost::tie(e, e_end) = edges(g); e != e_end; ++e) - std::cout << '(' << name[source(*e, g)] << ' ' - << name[target(*e, g)] << ')' << std::endl; - parenthesis_visitor - paren_vis; - depth_first_search(g, visitor(paren_vis)); - std::cout << std::endl; - return 0; + using namespace boost; + GraphvizGraph g; + read_graphviz("figs/dfs-example.dot", g); + graph_traits< GraphvizGraph >::edge_iterator e, e_end; + for (boost::tie(e, e_end) = edges(g); e != e_end; ++e) + std::cout << '(' << name[source(*e, g)] << ' ' << name[target(*e, g)] + << ')' << std::endl; + parenthesis_visitor paren_vis; + depth_first_search(g, visitor(paren_vis)); + std::cout << std::endl; + return 0; } diff --git a/example/dfs.cpp b/example/dfs.cpp index 8d68a09fe..b052a214f 100644 --- a/example/dfs.cpp +++ b/example/dfs.cpp @@ -14,7 +14,6 @@ #include #include - #include #include #include @@ -50,76 +49,76 @@ using namespace boost; using namespace std; - -template -struct edge_categorizer : public dfs_visitor { - typedef dfs_visitor Base; - - edge_categorizer(const VisitorList& v = null_visitor()) : Base(v) { } - - template - void tree_edge(Edge e, Graph& G) { - cout << "Tree edge: " << source(e, G) << - " --> " << target(e, G) << endl; - Base::tree_edge(e, G); - } - template - void back_edge(Edge e, Graph& G) { - cout << "Back edge: " << source(e, G) - << " --> " << target(e, G) << endl; - Base::back_edge(e, G); - } - template - void forward_or_cross_edge(Edge e, Graph& G) { - cout << "Forward or cross edge: " << source(e, G) - << " --> " << target(e, G) << endl; - Base::forward_or_cross_edge(e, G); - } - template - void finish_edge(Edge e, Graph& G) { - cout << "Finish edge: " << source(e, G) << - " --> " << target(e, G) << endl; - Base::finish_edge(e, G); - } +template < class VisitorList > +struct edge_categorizer : public dfs_visitor< VisitorList > +{ + typedef dfs_visitor< VisitorList > Base; + + edge_categorizer(const VisitorList& v = null_visitor()) : Base(v) {} + + template < class Edge, class Graph > void tree_edge(Edge e, Graph& G) + { + cout << "Tree edge: " << source(e, G) << " --> " << target(e, G) + << endl; + Base::tree_edge(e, G); + } + template < class Edge, class Graph > void back_edge(Edge e, Graph& G) + { + cout << "Back edge: " << source(e, G) << " --> " << target(e, G) + << endl; + Base::back_edge(e, G); + } + template < class Edge, class Graph > + void forward_or_cross_edge(Edge e, Graph& G) + { + cout << "Forward or cross edge: " << source(e, G) << " --> " + << target(e, G) << endl; + Base::forward_or_cross_edge(e, G); + } + template < class Edge, class Graph > void finish_edge(Edge e, Graph& G) + { + cout << "Finish edge: " << source(e, G) << " --> " << target(e, G) + << endl; + Base::finish_edge(e, G); + } }; -template -edge_categorizer -categorize_edges(const VisitorList& v) { - return edge_categorizer(v); +template < class VisitorList > +edge_categorizer< VisitorList > categorize_edges(const VisitorList& v) +{ + return edge_categorizer< VisitorList >(v); } -int -main(int , char* []) +int main(int, char*[]) { - using namespace boost; - - typedef adjacency_list<> Graph; - - Graph G(5); - add_edge(0, 2, G); - add_edge(1, 1, G); - add_edge(1, 3, G); - add_edge(2, 1, G); - add_edge(2, 3, G); - add_edge(3, 1, G); - add_edge(3, 4, G); - add_edge(4, 0, G); - add_edge(4, 1, G); - - typedef graph_traits::vertices_size_type size_type; - - std::vector d(num_vertices(G)); - std::vector f(num_vertices(G)); - int t = 0; - depth_first_search(G, visitor(categorize_edges( - make_pair(stamp_times(&d[0], t, on_discover_vertex()), - stamp_times(&f[0], t, on_finish_vertex()))))); - - std::vector::iterator i, j; - for (i = d.begin(), j = f.begin(); i != d.end(); ++i, ++j) - cout << *i << " " << *j << endl; - - return 0; -} + using namespace boost; + + typedef adjacency_list<> Graph; + Graph G(5); + add_edge(0, 2, G); + add_edge(1, 1, G); + add_edge(1, 3, G); + add_edge(2, 1, G); + add_edge(2, 3, G); + add_edge(3, 1, G); + add_edge(3, 4, G); + add_edge(4, 0, G); + add_edge(4, 1, G); + + typedef graph_traits< Graph >::vertices_size_type size_type; + + std::vector< size_type > d(num_vertices(G)); + std::vector< size_type > f(num_vertices(G)); + int t = 0; + depth_first_search(G, + visitor(categorize_edges( + make_pair(stamp_times(&d[0], t, on_discover_vertex()), + stamp_times(&f[0], t, on_finish_vertex()))))); + + std::vector< size_type >::iterator i, j; + for (i = d.begin(), j = f.begin(); i != d.end(); ++i, ++j) + cout << *i << " " << *j << endl; + + return 0; +} diff --git a/example/dfs_basics.expected b/example/dfs_basics.expected index a9e90d700..703f0c818 100644 --- a/example/dfs_basics.expected +++ b/example/dfs_basics.expected @@ -1,2 +1,2 @@ -order of discovery: u v y x w z -order of finish: x y v u z w +order of discovery: u v y x w z +order of finish: x y v u z w diff --git a/example/dfs_parenthesis.cpp b/example/dfs_parenthesis.cpp index 6f03401e6..6a4214451 100644 --- a/example/dfs_parenthesis.cpp +++ b/example/dfs_parenthesis.cpp @@ -27,47 +27,43 @@ using namespace boost; using namespace std; -struct open_paren : public base_visitor { - typedef on_discover_vertex event_filter; - template - void operator()(Vertex v, Graph&) { - std::cout << "(" << v; - } +struct open_paren : public base_visitor< open_paren > +{ + typedef on_discover_vertex event_filter; + template < class Vertex, class Graph > void operator()(Vertex v, Graph&) + { + std::cout << "(" << v; + } }; -struct close_paren : public base_visitor { - typedef on_finish_vertex event_filter; - template - void operator()(Vertex v, Graph&) { - std::cout << v << ")"; - } +struct close_paren : public base_visitor< close_paren > +{ + typedef on_finish_vertex event_filter; + template < class Vertex, class Graph > void operator()(Vertex v, Graph&) + { + std::cout << v << ")"; + } }; - -int -main(int, char*[]) +int main(int, char*[]) { - using namespace boost; - - typedef adjacency_list<> Graph; - typedef std::pair E; - E edge_array[] = { E(0, 2), - E(1, 1), E(1, 3), - E(2, 1), E(2, 3), - E(3, 1), E(3, 4), - E(4, 0), E(4, 1) }; + using namespace boost; + + typedef adjacency_list<> Graph; + typedef std::pair< int, int > E; + E edge_array[] = { E(0, 2), E(1, 1), E(1, 3), E(2, 1), E(2, 3), E(3, 1), + E(3, 4), E(4, 0), E(4, 1) }; #if defined(BOOST_MSVC) && BOOST_MSVC <= 1300 - Graph G(5); - for (std::size_t j = 0; j < sizeof(edge_array) / sizeof(E); ++j) - add_edge(edge_array[j].first, edge_array[j].second, G); + Graph G(5); + for (std::size_t j = 0; j < sizeof(edge_array) / sizeof(E); ++j) + add_edge(edge_array[j].first, edge_array[j].second, G); #else - Graph G(edge_array, edge_array + sizeof(edge_array)/sizeof(E), 5); + Graph G(edge_array, edge_array + sizeof(edge_array) / sizeof(E), 5); #endif - std::cout << "DFS parenthesis:" << std::endl; - depth_first_search(G, visitor(make_dfs_visitor(std::make_pair(open_paren(), - close_paren())))); - std::cout << std::endl; - return 0; + std::cout << "DFS parenthesis:" << std::endl; + depth_first_search(G, + visitor(make_dfs_visitor(std::make_pair(open_paren(), close_paren())))); + std::cout << std::endl; + return 0; } - diff --git a/example/dijkstra-example-listS.cpp b/example/dijkstra-example-listS.cpp index 500f9811b..89bca7b00 100644 --- a/example/dijkstra-example-listS.cpp +++ b/example/dijkstra-example-listS.cpp @@ -1,5 +1,5 @@ //======================================================================= -// Copyright 2001 Jeremy G. Siek, Andrew Lumsdaine, Lie-Quan Lee, +// Copyright 2001 Jeremy G. Siek, Andrew Lumsdaine, Lie-Quan Lee, // // Distributed under the Boost Software License, Version 1.0. (See // accompanying file LICENSE_1_0.txt or copy at @@ -15,77 +15,89 @@ using namespace boost; -int -main(int, char *[]) +int main(int, char*[]) { - typedef adjacency_list_traits::vertex_descriptor vertex_descriptor; - typedef adjacency_list < listS, listS, directedS, - property > > >, - property > graph_t; - typedef std::pair Edge; + typedef adjacency_list_traits< listS, listS, directedS >::vertex_descriptor + vertex_descriptor; + typedef adjacency_list< listS, listS, directedS, + property< vertex_index_t, int, + property< vertex_name_t, char, + property< vertex_distance_t, int, + property< vertex_predecessor_t, vertex_descriptor > > > >, + property< edge_weight_t, int > > + graph_t; + typedef std::pair< int, int > Edge; - const int num_nodes = 5; - enum nodes { A, B, C, D, E }; - Edge edge_array[] = { Edge(A, C), Edge(B, B), Edge(B, D), Edge(B, E), - Edge(C, B), Edge(C, D), Edge(D, E), Edge(E, A), Edge(E, B) - }; - int weights[] = { 1, 2, 1, 2, 7, 3, 1, 1, 1 }; - int num_arcs = sizeof(edge_array) / sizeof(Edge); - graph_traits::vertex_iterator i, iend; + const int num_nodes = 5; + enum nodes + { + A, + B, + C, + D, + E + }; + Edge edge_array[] = { Edge(A, C), Edge(B, B), Edge(B, D), Edge(B, E), + Edge(C, B), Edge(C, D), Edge(D, E), Edge(E, A), Edge(E, B) }; + int weights[] = { 1, 2, 1, 2, 7, 3, 1, 1, 1 }; + int num_arcs = sizeof(edge_array) / sizeof(Edge); + graph_traits< graph_t >::vertex_iterator i, iend; - graph_t g(edge_array, edge_array + num_arcs, weights, num_nodes); - property_map::type weightmap = get(edge_weight, g); + graph_t g(edge_array, edge_array + num_arcs, weights, num_nodes); + property_map< graph_t, edge_weight_t >::type weightmap + = get(edge_weight, g); - // Manually intialize the vertex index and name maps - property_map::type indexmap = get(vertex_index, g); - property_map::type name = get(vertex_name, g); - int c = 0; - for (boost::tie(i, iend) = vertices(g); i != iend; ++i, ++c) { - indexmap[*i] = c; - name[*i] = 'A' + c; - } + // Manually intialize the vertex index and name maps + property_map< graph_t, vertex_index_t >::type indexmap + = get(vertex_index, g); + property_map< graph_t, vertex_name_t >::type name = get(vertex_name, g); + int c = 0; + for (boost::tie(i, iend) = vertices(g); i != iend; ++i, ++c) + { + indexmap[*i] = c; + name[*i] = 'A' + c; + } - vertex_descriptor s = vertex(A, g); + vertex_descriptor s = vertex(A, g); - property_map::type - d = get(vertex_distance, g); - property_map::type - p = get(vertex_predecessor, g); - dijkstra_shortest_paths(g, s, predecessor_map(p).distance_map(d)); + property_map< graph_t, vertex_distance_t >::type d + = get(vertex_distance, g); + property_map< graph_t, vertex_predecessor_t >::type p + = get(vertex_predecessor, g); + dijkstra_shortest_paths(g, s, predecessor_map(p).distance_map(d)); - std::cout << "distances and parents:" << std::endl; - graph_traits < graph_t >::vertex_iterator vi, vend; - for (boost::tie(vi, vend) = vertices(g); vi != vend; ++vi) { - std::cout << "distance(" << name[*vi] << ") = " << d[*vi] << ", "; - std::cout << "parent(" << name[*vi] << ") = " << name[p[*vi]] << std:: - endl; - } - std::cout << std::endl; + std::cout << "distances and parents:" << std::endl; + graph_traits< graph_t >::vertex_iterator vi, vend; + for (boost::tie(vi, vend) = vertices(g); vi != vend; ++vi) + { + std::cout << "distance(" << name[*vi] << ") = " << d[*vi] << ", "; + std::cout << "parent(" << name[*vi] << ") = " << name[p[*vi]] + << std::endl; + } + std::cout << std::endl; - std::ofstream dot_file("figs/dijkstra-eg.dot"); - dot_file << "digraph D {\n" - << " rankdir=LR\n" - << " size=\"4,3\"\n" - << " ratio=\"fill\"\n" - << " edge[style=\"bold\"]\n" << " node[shape=\"circle\"]\n"; + std::ofstream dot_file("figs/dijkstra-eg.dot"); + dot_file << "digraph D {\n" + << " rankdir=LR\n" + << " size=\"4,3\"\n" + << " ratio=\"fill\"\n" + << " edge[style=\"bold\"]\n" + << " node[shape=\"circle\"]\n"; - graph_traits < graph_t >::edge_iterator ei, ei_end; - for (boost::tie(ei, ei_end) = edges(g); ei != ei_end; ++ei) { - graph_traits < graph_t >::edge_descriptor e = *ei; - graph_traits < graph_t >::vertex_descriptor - u = source(e, g), v = target(e, g); - dot_file << name[u] << " -> " << name[v] - << "[label=\"" << get(weightmap, e) << "\""; - if (p[v] == u) - dot_file << ", color=\"black\""; - else - dot_file << ", color=\"grey\""; - dot_file << "]"; - } - dot_file << "}"; - return EXIT_SUCCESS; + graph_traits< graph_t >::edge_iterator ei, ei_end; + for (boost::tie(ei, ei_end) = edges(g); ei != ei_end; ++ei) + { + graph_traits< graph_t >::edge_descriptor e = *ei; + graph_traits< graph_t >::vertex_descriptor u = source(e, g), + v = target(e, g); + dot_file << name[u] << " -> " << name[v] << "[label=\"" + << get(weightmap, e) << "\""; + if (p[v] == u) + dot_file << ", color=\"black\""; + else + dot_file << ", color=\"grey\""; + dot_file << "]"; + } + dot_file << "}"; + return EXIT_SUCCESS; } diff --git a/example/dijkstra-example.cpp b/example/dijkstra-example.cpp index 269d2570c..62b55120a 100644 --- a/example/dijkstra-example.cpp +++ b/example/dijkstra-example.cpp @@ -1,5 +1,5 @@ //======================================================================= -// Copyright 2001 Jeremy G. Siek, Andrew Lumsdaine, Lie-Quan Lee, +// Copyright 2001 Jeremy G. Siek, Andrew Lumsdaine, Lie-Quan Lee, // // Distributed under the Boost Software License, Version 1.0. (See // accompanying file LICENSE_1_0.txt or copy at @@ -16,62 +16,74 @@ using namespace boost; -int -main(int, char *[]) +int main(int, char*[]) { - typedef adjacency_list < listS, vecS, directedS, - no_property, property < edge_weight_t, int > > graph_t; - typedef graph_traits < graph_t >::vertex_descriptor vertex_descriptor; - typedef std::pair Edge; + typedef adjacency_list< listS, vecS, directedS, no_property, + property< edge_weight_t, int > > + graph_t; + typedef graph_traits< graph_t >::vertex_descriptor vertex_descriptor; + typedef std::pair< int, int > Edge; - const int num_nodes = 5; - enum nodes { A, B, C, D, E }; - char name[] = "ABCDE"; - Edge edge_array[] = { Edge(A, C), Edge(B, B), Edge(B, D), Edge(B, E), - Edge(C, B), Edge(C, D), Edge(D, E), Edge(E, A), Edge(E, B) - }; - int weights[] = { 1, 2, 1, 2, 7, 3, 1, 1, 1 }; - int num_arcs = sizeof(edge_array) / sizeof(Edge); - graph_t g(edge_array, edge_array + num_arcs, weights, num_nodes); - property_map::type weightmap = get(edge_weight, g); - std::vector p(num_vertices(g)); - std::vector d(num_vertices(g)); - vertex_descriptor s = vertex(A, g); + const int num_nodes = 5; + enum nodes + { + A, + B, + C, + D, + E + }; + char name[] = "ABCDE"; + Edge edge_array[] = { Edge(A, C), Edge(B, B), Edge(B, D), Edge(B, E), + Edge(C, B), Edge(C, D), Edge(D, E), Edge(E, A), Edge(E, B) }; + int weights[] = { 1, 2, 1, 2, 7, 3, 1, 1, 1 }; + int num_arcs = sizeof(edge_array) / sizeof(Edge); + graph_t g(edge_array, edge_array + num_arcs, weights, num_nodes); + property_map< graph_t, edge_weight_t >::type weightmap + = get(edge_weight, g); + std::vector< vertex_descriptor > p(num_vertices(g)); + std::vector< int > d(num_vertices(g)); + vertex_descriptor s = vertex(A, g); - dijkstra_shortest_paths(g, s, - predecessor_map(boost::make_iterator_property_map(p.begin(), get(boost::vertex_index, g))). - distance_map(boost::make_iterator_property_map(d.begin(), get(boost::vertex_index, g)))); + dijkstra_shortest_paths(g, s, + predecessor_map(boost::make_iterator_property_map( + p.begin(), get(boost::vertex_index, g))) + .distance_map(boost::make_iterator_property_map( + d.begin(), get(boost::vertex_index, g)))); - std::cout << "distances and parents:" << std::endl; - graph_traits < graph_t >::vertex_iterator vi, vend; - for (boost::tie(vi, vend) = vertices(g); vi != vend; ++vi) { - std::cout << "distance(" << name[*vi] << ") = " << d[*vi] << ", "; - std::cout << "parent(" << name[*vi] << ") = " << name[p[*vi]] << std:: - endl; - } - std::cout << std::endl; + std::cout << "distances and parents:" << std::endl; + graph_traits< graph_t >::vertex_iterator vi, vend; + for (boost::tie(vi, vend) = vertices(g); vi != vend; ++vi) + { + std::cout << "distance(" << name[*vi] << ") = " << d[*vi] << ", "; + std::cout << "parent(" << name[*vi] << ") = " << name[p[*vi]] + << std::endl; + } + std::cout << std::endl; - std::ofstream dot_file("figs/dijkstra-eg.dot"); + std::ofstream dot_file("figs/dijkstra-eg.dot"); - dot_file << "digraph D {\n" - << " rankdir=LR\n" - << " size=\"4,3\"\n" - << " ratio=\"fill\"\n" - << " edge[style=\"bold\"]\n" << " node[shape=\"circle\"]\n"; + dot_file << "digraph D {\n" + << " rankdir=LR\n" + << " size=\"4,3\"\n" + << " ratio=\"fill\"\n" + << " edge[style=\"bold\"]\n" + << " node[shape=\"circle\"]\n"; - graph_traits < graph_t >::edge_iterator ei, ei_end; - for (boost::tie(ei, ei_end) = edges(g); ei != ei_end; ++ei) { - graph_traits < graph_t >::edge_descriptor e = *ei; - graph_traits < graph_t >::vertex_descriptor - u = source(e, g), v = target(e, g); - dot_file << name[u] << " -> " << name[v] - << "[label=\"" << get(weightmap, e) << "\""; - if (p[v] == u) - dot_file << ", color=\"black\""; - else - dot_file << ", color=\"grey\""; - dot_file << "]"; - } - dot_file << "}"; - return EXIT_SUCCESS; + graph_traits< graph_t >::edge_iterator ei, ei_end; + for (boost::tie(ei, ei_end) = edges(g); ei != ei_end; ++ei) + { + graph_traits< graph_t >::edge_descriptor e = *ei; + graph_traits< graph_t >::vertex_descriptor u = source(e, g), + v = target(e, g); + dot_file << name[u] << " -> " << name[v] << "[label=\"" + << get(weightmap, e) << "\""; + if (p[v] == u) + dot_file << ", color=\"black\""; + else + dot_file << ", color=\"grey\""; + dot_file << "]"; + } + dot_file << "}"; + return EXIT_SUCCESS; } diff --git a/example/dijkstra-no-color-map-example.cpp b/example/dijkstra-no-color-map-example.cpp index 14d196d9f..b0f072d77 100644 --- a/example/dijkstra-no-color-map-example.cpp +++ b/example/dijkstra-no-color-map-example.cpp @@ -1,7 +1,7 @@ //======================================================================= // Copyright 2001 Jeremy G. Siek, Andrew Lumsdaine, Lie-Quan Lee // Copyright 2009 Trustees of Indiana University. -// Copyright 2001 Jeremy G. Siek, Andrew Lumsdaine, Lie-Quan Lee, +// Copyright 2001 Jeremy G. Siek, Andrew Lumsdaine, Lie-Quan Lee, // // Distributed under the Boost Software License, Version 1.0. (See // accompanying file LICENSE_1_0.txt or copy at @@ -20,62 +20,74 @@ using namespace boost; -int -main(int, char *[]) +int main(int, char*[]) { - typedef adjacency_list < listS, vecS, directedS, - no_property, property < edge_weight_t, int > > graph_t; - typedef graph_traits < graph_t >::vertex_descriptor vertex_descriptor; - typedef std::pair Edge; + typedef adjacency_list< listS, vecS, directedS, no_property, + property< edge_weight_t, int > > + graph_t; + typedef graph_traits< graph_t >::vertex_descriptor vertex_descriptor; + typedef std::pair< int, int > Edge; - const int num_nodes = 5; - enum nodes { A, B, C, D, E }; - char name[] = "ABCDE"; - Edge edge_array[] = { Edge(A, C), Edge(B, B), Edge(B, D), Edge(B, E), - Edge(C, B), Edge(C, D), Edge(D, E), Edge(E, A), Edge(E, B) - }; - int weights[] = { 1, 2, 1, 2, 7, 3, 1, 1, 1 }; - int num_arcs = sizeof(edge_array) / sizeof(Edge); - graph_t g(edge_array, edge_array + num_arcs, weights, num_nodes); - property_map::type weightmap = get(edge_weight, g); - std::vector p(num_vertices(g)); - std::vector d(num_vertices(g)); - vertex_descriptor s = vertex(A, g); + const int num_nodes = 5; + enum nodes + { + A, + B, + C, + D, + E + }; + char name[] = "ABCDE"; + Edge edge_array[] = { Edge(A, C), Edge(B, B), Edge(B, D), Edge(B, E), + Edge(C, B), Edge(C, D), Edge(D, E), Edge(E, A), Edge(E, B) }; + int weights[] = { 1, 2, 1, 2, 7, 3, 1, 1, 1 }; + int num_arcs = sizeof(edge_array) / sizeof(Edge); + graph_t g(edge_array, edge_array + num_arcs, weights, num_nodes); + property_map< graph_t, edge_weight_t >::type weightmap + = get(edge_weight, g); + std::vector< vertex_descriptor > p(num_vertices(g)); + std::vector< int > d(num_vertices(g)); + vertex_descriptor s = vertex(A, g); - dijkstra_shortest_paths_no_color_map(g, s, - predecessor_map(boost::make_iterator_property_map(p.begin(), get(boost::vertex_index, g))). - distance_map(boost::make_iterator_property_map(d.begin(), get(boost::vertex_index, g)))); + dijkstra_shortest_paths_no_color_map(g, s, + predecessor_map(boost::make_iterator_property_map( + p.begin(), get(boost::vertex_index, g))) + .distance_map(boost::make_iterator_property_map( + d.begin(), get(boost::vertex_index, g)))); - std::cout << "distances and parents:" << std::endl; - graph_traits < graph_t >::vertex_iterator vi, vend; - for (boost::tie(vi, vend) = vertices(g); vi != vend; ++vi) { - std::cout << "distance(" << name[*vi] << ") = " << d[*vi] << ", "; - std::cout << "parent(" << name[*vi] << ") = " << name[p[*vi]] << std:: - endl; - } - std::cout << std::endl; + std::cout << "distances and parents:" << std::endl; + graph_traits< graph_t >::vertex_iterator vi, vend; + for (boost::tie(vi, vend) = vertices(g); vi != vend; ++vi) + { + std::cout << "distance(" << name[*vi] << ") = " << d[*vi] << ", "; + std::cout << "parent(" << name[*vi] << ") = " << name[p[*vi]] + << std::endl; + } + std::cout << std::endl; - std::ofstream dot_file("figs/dijkstra-no-color-map-eg.dot"); + std::ofstream dot_file("figs/dijkstra-no-color-map-eg.dot"); - dot_file << "digraph D {\n" - << " rankdir=LR\n" - << " size=\"4,3\"\n" - << " ratio=\"fill\"\n" - << " edge[style=\"bold\"]\n" << " node[shape=\"circle\"]\n"; + dot_file << "digraph D {\n" + << " rankdir=LR\n" + << " size=\"4,3\"\n" + << " ratio=\"fill\"\n" + << " edge[style=\"bold\"]\n" + << " node[shape=\"circle\"]\n"; - graph_traits < graph_t >::edge_iterator ei, ei_end; - for (boost::tie(ei, ei_end) = edges(g); ei != ei_end; ++ei) { - graph_traits < graph_t >::edge_descriptor e = *ei; - graph_traits < graph_t >::vertex_descriptor - u = source(e, g), v = target(e, g); - dot_file << name[u] << " -> " << name[v] - << "[label=\"" << get(weightmap, e) << "\""; - if (p[v] == u) - dot_file << ", color=\"black\""; - else - dot_file << ", color=\"grey\""; - dot_file << "]"; - } - dot_file << "}"; - return EXIT_SUCCESS; + graph_traits< graph_t >::edge_iterator ei, ei_end; + for (boost::tie(ei, ei_end) = edges(g); ei != ei_end; ++ei) + { + graph_traits< graph_t >::edge_descriptor e = *ei; + graph_traits< graph_t >::vertex_descriptor u = source(e, g), + v = target(e, g); + dot_file << name[u] << " -> " << name[v] << "[label=\"" + << get(weightmap, e) << "\""; + if (p[v] == u) + dot_file << ", color=\"black\""; + else + dot_file << ", color=\"grey\""; + dot_file << "]"; + } + dot_file << "}"; + return EXIT_SUCCESS; } diff --git a/example/dijkstra.expected b/example/dijkstra.expected index 0f73cbdf8..a2eb19ee9 100644 --- a/example/dijkstra.expected +++ b/example/dijkstra.expected @@ -6,8 +6,8 @@ distance(3) = 4 distance(4) = 5 shortest paths tree -0 --> 2 -1 --> -2 --> 3 -3 --> 4 -4 --> 1 +0 --> 2 +1 --> +2 --> 3 +3 --> 4 +4 --> 1 diff --git a/example/directed_graph.cpp b/example/directed_graph.cpp index bb308aa59..4eb55ff3f 100644 --- a/example/directed_graph.cpp +++ b/example/directed_graph.cpp @@ -9,18 +9,19 @@ #include // A subclass to provide reasonable arguments to adjacency_list for a typical directed graph -int main(int,char*[]) +int main(int, char*[]) { - // directed_graph is a subclass of adjacency_list which gives you object oriented access to functions - // like add_vertex and add_edge, which makes the code easier to understand. However, it hard codes many - // of the template parameters, so it is much less flexible. + // directed_graph is a subclass of adjacency_list which gives you object + // oriented access to functions like add_vertex and add_edge, which makes + // the code easier to understand. However, it hard codes many of the + // template parameters, so it is much less flexible. - typedef boost::directed_graph<> Graph; - Graph g; - boost::graph_traits::vertex_descriptor v0 = g.add_vertex(); - boost::graph_traits::vertex_descriptor v1 = g.add_vertex(); + typedef boost::directed_graph<> Graph; + Graph g; + boost::graph_traits< Graph >::vertex_descriptor v0 = g.add_vertex(); + boost::graph_traits< Graph >::vertex_descriptor v1 = g.add_vertex(); - g.add_edge(v0, v1); + g.add_edge(v0, v1); - return 0; + return 0; } diff --git a/example/eccentricity.cpp b/example/eccentricity.cpp index 3e16e6f27..58e43ace1 100644 --- a/example/eccentricity.cpp +++ b/example/eccentricity.cpp @@ -4,7 +4,6 @@ // Boost Software License, Version 1.0 (See accompanying file // LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) - //[eccentricity_example #include #include @@ -25,32 +24,31 @@ struct Actor }; // Declare the graph type and its vertex and edge types. -typedef undirected_graph Graph; -typedef graph_traits::vertex_descriptor Vertex; -typedef graph_traits::edge_descriptor Edge; +typedef undirected_graph< Actor > Graph; +typedef graph_traits< Graph >::vertex_descriptor Vertex; +typedef graph_traits< Graph >::edge_descriptor Edge; // The name map provides an abstract accessor for the names of // each vertex. This is used during graph creation. -typedef property_map::type NameMap; +typedef property_map< Graph, string Actor::* >::type NameMap; // Declare a matrix type and its corresponding property map that // will contain the distances between each pair of vertices. -typedef exterior_vertex_property DistanceProperty; +typedef exterior_vertex_property< Graph, int > DistanceProperty; typedef DistanceProperty::matrix_type DistanceMatrix; typedef DistanceProperty::matrix_map_type DistanceMatrixMap; // Declare the weight map so that each edge returns the same value. -typedef constant_property_map WeightMap; +typedef constant_property_map< Edge, int > WeightMap; // Declare a container and its corresponding property map that // will contain the resulting eccentricities of each vertex in // the graph. -typedef boost::exterior_vertex_property EccentricityProperty; +typedef boost::exterior_vertex_property< Graph, int > EccentricityProperty; typedef EccentricityProperty::container_type EccentricityContainer; typedef EccentricityProperty::map_type EccentricityMap; -int -main(int argc, char *argv[]) +int main(int argc, char* argv[]) { // Create the graph and a name map that provides access to // then actor names. @@ -76,10 +74,11 @@ main(int argc, char *argv[]) boost::tie(r, d) = all_eccentricities(g, dm, em); // Print the closeness centrality of each vertex. - graph_traits::vertex_iterator i, end; - for(boost::tie(i, end) = vertices(g); i != end; ++i) { - cout << setw(12) << setiosflags(ios::left) - << g[*i].name << get(em, *i) << endl; + graph_traits< Graph >::vertex_iterator i, end; + for (boost::tie(i, end) = vertices(g); i != end; ++i) + { + cout << setw(12) << setiosflags(ios::left) << g[*i].name << get(em, *i) + << endl; } cout << "radius: " << r << endl; cout << "diamter: " << d << endl; diff --git a/example/edge-connectivity.cpp b/example/edge-connectivity.cpp index 4df4e0e06..54345ae0a 100644 --- a/example/edge-connectivity.cpp +++ b/example/edge-connectivity.cpp @@ -1,5 +1,5 @@ //======================================================================= -// Copyright 2001 Jeremy G. Siek, Andrew Lumsdaine, Lie-Quan Lee, +// Copyright 2001 Jeremy G. Siek, Andrew Lumsdaine, Lie-Quan Lee, // // Distributed under the Boost Software License, Version 1.0. (See // accompanying file LICENSE_1_0.txt or copy at @@ -9,8 +9,8 @@ /* IMPORTANT!!! ~~~~~~~~~~~~ - This example uses interfaces that have been deprecated and removed from Boost.Grpah. - Someone needs to update it, as it does NOT compile. + This example uses interfaces that have been deprecated and removed from + Boost.Grpah. Someone needs to update it, as it does NOT compile. */ #include @@ -23,86 +23,86 @@ namespace boost { - template < typename Graph > - std::pair < typename graph_traits < Graph >::vertex_descriptor, - typename graph_traits < Graph >::degree_size_type > - min_degree_vertex(Graph & g) - { - typename graph_traits < Graph >::vertex_descriptor p; - typedef typename graph_traits < Graph >::degree_size_type size_type; - size_type delta = (std::numeric_limits < size_type >::max)(); - typename graph_traits < Graph >::vertex_iterator i, iend; +template < typename Graph > +std::pair< typename graph_traits< Graph >::vertex_descriptor, + typename graph_traits< Graph >::degree_size_type > +min_degree_vertex(Graph& g) +{ + typename graph_traits< Graph >::vertex_descriptor p; + typedef typename graph_traits< Graph >::degree_size_type size_type; + size_type delta = (std::numeric_limits< size_type >::max)(); + typename graph_traits< Graph >::vertex_iterator i, iend; for (boost::tie(i, iend) = vertices(g); i != iend; ++i) - if (degree(*i, g) < delta) - { - delta = degree(*i, g); - p = *i; - } + if (degree(*i, g) < delta) + { + delta = degree(*i, g); + p = *i; + } return std::make_pair(p, delta); - } - - template < typename Graph, typename OutputIterator > - void neighbors(const Graph & g, - typename graph_traits < Graph >::vertex_descriptor u, - OutputIterator result) - { - typename graph_traits < Graph >::adjacency_iterator ai, aend; +} + +template < typename Graph, typename OutputIterator > +void neighbors(const Graph& g, + typename graph_traits< Graph >::vertex_descriptor u, OutputIterator result) +{ + typename graph_traits< Graph >::adjacency_iterator ai, aend; for (boost::tie(ai, aend) = adjacent_vertices(u, g); ai != aend; ++ai) - *result++ = *ai; - } - template < typename Graph, typename VertexIterator, - typename OutputIterator > void neighbors(const Graph & g, - VertexIterator first, - VertexIterator last, - OutputIterator result) - { + *result++ = *ai; +} +template < typename Graph, typename VertexIterator, typename OutputIterator > +void neighbors(const Graph& g, VertexIterator first, VertexIterator last, + OutputIterator result) +{ for (; first != last; ++first) - neighbors(g, *first, result); - } - - template < typename VertexListGraph, typename OutputIterator > - typename graph_traits < VertexListGraph >::degree_size_type - edge_connectivity(VertexListGraph & g, OutputIterator disconnecting_set) - { - typedef typename graph_traits < - VertexListGraph >::vertex_descriptor vertex_descriptor; - typedef typename graph_traits < - VertexListGraph >::degree_size_type degree_size_type; - typedef color_traits < default_color_type > Color; - typedef typename adjacency_list_traits < vecS, vecS, - directedS >::edge_descriptor edge_descriptor; - typedef adjacency_list < vecS, vecS, directedS, no_property, - property < edge_capacity_t, degree_size_type, - property < edge_residual_capacity_t, degree_size_type, - property < edge_reverse_t, edge_descriptor > > > > FlowGraph; + neighbors(g, *first, result); +} + +template < typename VertexListGraph, typename OutputIterator > +typename graph_traits< VertexListGraph >::degree_size_type edge_connectivity( + VertexListGraph& g, OutputIterator disconnecting_set) +{ + typedef typename graph_traits< VertexListGraph >::vertex_descriptor + vertex_descriptor; + typedef typename graph_traits< VertexListGraph >::degree_size_type + degree_size_type; + typedef color_traits< default_color_type > Color; + typedef + typename adjacency_list_traits< vecS, vecS, directedS >::edge_descriptor + edge_descriptor; + typedef adjacency_list< vecS, vecS, directedS, no_property, + property< edge_capacity_t, degree_size_type, + property< edge_residual_capacity_t, degree_size_type, + property< edge_reverse_t, edge_descriptor > > > > + FlowGraph; vertex_descriptor u, v, p, k; edge_descriptor e1, e2; bool inserted; - typename graph_traits < VertexListGraph >::vertex_iterator vi, vi_end; + typename graph_traits< VertexListGraph >::vertex_iterator vi, vi_end; degree_size_type delta, alpha_star, alpha_S_k; - std::set < vertex_descriptor > S, neighbor_S; - std::vector < vertex_descriptor > S_star, nonneighbor_S; - std::vector < default_color_type > color(num_vertices(g)); - std::vector < edge_descriptor > pred(num_vertices(g)); + std::set< vertex_descriptor > S, neighbor_S; + std::vector< vertex_descriptor > S_star, nonneighbor_S; + std::vector< default_color_type > color(num_vertices(g)); + std::vector< edge_descriptor > pred(num_vertices(g)); FlowGraph flow_g(num_vertices(g)); - typename property_map < FlowGraph, edge_capacity_t >::type - cap = get(edge_capacity, flow_g); - typename property_map < FlowGraph, edge_residual_capacity_t >::type - res_cap = get(edge_residual_capacity, flow_g); - typename property_map < FlowGraph, edge_reverse_t >::type - rev_edge = get(edge_reverse, flow_g); - - typename graph_traits < VertexListGraph >::edge_iterator ei, ei_end; - for (boost::tie(ei, ei_end) = edges(g); ei != ei_end; ++ei) { - u = source(*ei, g), v = target(*ei, g); - boost::tie(e1, inserted) = add_edge(u, v, flow_g); - cap[e1] = 1; - boost::tie(e2, inserted) = add_edge(v, u, flow_g); - cap[e2] = 1; - rev_edge[e1] = e2; - rev_edge[e2] = e1; + typename property_map< FlowGraph, edge_capacity_t >::type cap + = get(edge_capacity, flow_g); + typename property_map< FlowGraph, edge_residual_capacity_t >::type res_cap + = get(edge_residual_capacity, flow_g); + typename property_map< FlowGraph, edge_reverse_t >::type rev_edge + = get(edge_reverse, flow_g); + + typename graph_traits< VertexListGraph >::edge_iterator ei, ei_end; + for (boost::tie(ei, ei_end) = edges(g); ei != ei_end; ++ei) + { + u = source(*ei, g), v = target(*ei, g); + boost::tie(e1, inserted) = add_edge(u, v, flow_g); + cap[e1] = 1; + boost::tie(e2, inserted) = add_edge(v, u, flow_g); + cap[e2] = 1; + rev_edge[e1] = e2; + rev_edge[e2] = e1; } boost::tie(p, delta) = min_degree_vertex(g); @@ -110,75 +110,77 @@ namespace boost alpha_star = delta; S.insert(p); neighbor_S.insert(p); - neighbors(g, S.begin(), S.end(), - std::inserter(neighbor_S, neighbor_S.begin())); + neighbors( + g, S.begin(), S.end(), std::inserter(neighbor_S, neighbor_S.begin())); std::set_difference(vertices(g).first, vertices(g).second, - neighbor_S.begin(), neighbor_S.end(), - std::back_inserter(nonneighbor_S)); - - while (!nonneighbor_S.empty()) { - k = nonneighbor_S.front(); - alpha_S_k = edmonds_karp_max_flow - (flow_g, p, k, cap, res_cap, rev_edge, &color[0], &pred[0]); - if (alpha_S_k < alpha_star) { - alpha_star = alpha_S_k; - S_star.clear(); - for (boost::tie(vi, vi_end) = vertices(flow_g); vi != vi_end; ++vi) - if (color[*vi] != Color::white()) - S_star.push_back(*vi); - } - S.insert(k); - neighbor_S.insert(k); - neighbors(g, k, std::inserter(neighbor_S, neighbor_S.begin())); - nonneighbor_S.clear(); - std::set_difference(vertices(g).first, vertices(g).second, - neighbor_S.begin(), neighbor_S.end(), - std::back_inserter(nonneighbor_S)); + neighbor_S.begin(), neighbor_S.end(), + std::back_inserter(nonneighbor_S)); + + while (!nonneighbor_S.empty()) + { + k = nonneighbor_S.front(); + alpha_S_k = edmonds_karp_max_flow( + flow_g, p, k, cap, res_cap, rev_edge, &color[0], &pred[0]); + if (alpha_S_k < alpha_star) + { + alpha_star = alpha_S_k; + S_star.clear(); + for (boost::tie(vi, vi_end) = vertices(flow_g); vi != vi_end; ++vi) + if (color[*vi] != Color::white()) + S_star.push_back(*vi); + } + S.insert(k); + neighbor_S.insert(k); + neighbors(g, k, std::inserter(neighbor_S, neighbor_S.begin())); + nonneighbor_S.clear(); + std::set_difference(vertices(g).first, vertices(g).second, + neighbor_S.begin(), neighbor_S.end(), + std::back_inserter(nonneighbor_S)); } - std::vector < bool > in_S_star(num_vertices(g), false); - typename std::vector < vertex_descriptor >::iterator si; + std::vector< bool > in_S_star(num_vertices(g), false); + typename std::vector< vertex_descriptor >::iterator si; for (si = S_star.begin(); si != S_star.end(); ++si) - in_S_star[*si] = true; + in_S_star[*si] = true; degree_size_type c = 0; - for (si = S_star.begin(); si != S_star.end(); ++si) { - typename graph_traits < VertexListGraph >::out_edge_iterator ei, ei_end; - for (boost::tie(ei, ei_end) = out_edges(*si, g); ei != ei_end; ++ei) - if (!in_S_star[target(*ei, g)]) { - *disconnecting_set++ = *ei; - ++c; - } + for (si = S_star.begin(); si != S_star.end(); ++si) + { + typename graph_traits< VertexListGraph >::out_edge_iterator ei, ei_end; + for (boost::tie(ei, ei_end) = out_edges(*si, g); ei != ei_end; ++ei) + if (!in_S_star[target(*ei, g)]) + { + *disconnecting_set++ = *ei; + ++c; + } } return c; - } +} } -int -main() +int main() { - using namespace boost; - GraphvizGraph g; - read_graphviz("figs/edge-connectivity.dot", g); - - typedef graph_traits < GraphvizGraph >::edge_descriptor edge_descriptor; - typedef graph_traits < GraphvizGraph >::degree_size_type degree_size_type; - std::vector < edge_descriptor > disconnecting_set; - degree_size_type c = - edge_connectivity(g, std::back_inserter(disconnecting_set)); - - std::cout << "The edge connectivity is " << c << "." << std::endl; - - property_map < GraphvizGraph, vertex_attribute_t >::type - attr_map = get(vertex_attribute, g); - - std::cout << "The disconnecting set is {"; - for (std::vector < edge_descriptor >::iterator i = - disconnecting_set.begin(); i != disconnecting_set.end(); ++i) - std:: - cout << "(" << attr_map[source(*i, g)]["label"] << "," << - attr_map[target(*i, g)]["label"] << ") "; - std::cout << "}." << std::endl; - return EXIT_SUCCESS; + using namespace boost; + GraphvizGraph g; + read_graphviz("figs/edge-connectivity.dot", g); + + typedef graph_traits< GraphvizGraph >::edge_descriptor edge_descriptor; + typedef graph_traits< GraphvizGraph >::degree_size_type degree_size_type; + std::vector< edge_descriptor > disconnecting_set; + degree_size_type c + = edge_connectivity(g, std::back_inserter(disconnecting_set)); + + std::cout << "The edge connectivity is " << c << "." << std::endl; + + property_map< GraphvizGraph, vertex_attribute_t >::type attr_map + = get(vertex_attribute, g); + + std::cout << "The disconnecting set is {"; + for (std::vector< edge_descriptor >::iterator i = disconnecting_set.begin(); + i != disconnecting_set.end(); ++i) + std::cout << "(" << attr_map[source(*i, g)]["label"] << "," + << attr_map[target(*i, g)]["label"] << ") "; + std::cout << "}." << std::endl; + return EXIT_SUCCESS; } diff --git a/example/edge-function.cpp b/example/edge-function.cpp index ef74062ad..e3898afcf 100644 --- a/example/edge-function.cpp +++ b/example/edge-function.cpp @@ -1,5 +1,5 @@ //======================================================================= -// Copyright 2001 Jeremy G. Siek, Andrew Lumsdaine, Lie-Quan Lee, +// Copyright 2001 Jeremy G. Siek, Andrew Lumsdaine, Lie-Quan Lee, // // Distributed under the Boost Software License, Version 1.0. (See // accompanying file LICENSE_1_0.txt or copy at @@ -13,127 +13,134 @@ using namespace boost; -template < typename Graph, typename VertexNamePropertyMap > void -read_graph_file(std::istream & graph_in, std::istream & name_in, - Graph & g, VertexNamePropertyMap name_map) +template < typename Graph, typename VertexNamePropertyMap > +void read_graph_file(std::istream& graph_in, std::istream& name_in, Graph& g, + VertexNamePropertyMap name_map) { - typedef typename graph_traits < Graph >::vertices_size_type size_type; - size_type n_vertices; - typename graph_traits < Graph >::vertex_descriptor u; - typename property_traits < VertexNamePropertyMap >::value_type name; - - graph_in >> n_vertices; // read in number of vertices - for (size_type i = 0; i < n_vertices; ++i) { // Add n vertices to the graph - u = add_vertex(g); - name_in >> name; - put(name_map, u, name); // ** Attach name property to vertex u ** - } - size_type src, targ; - while (graph_in >> src) // Read in edges - if (graph_in >> targ) - add_edge(src, targ, g); // add an edge to the graph - else - break; + typedef typename graph_traits< Graph >::vertices_size_type size_type; + size_type n_vertices; + typename graph_traits< Graph >::vertex_descriptor u; + typename property_traits< VertexNamePropertyMap >::value_type name; + + graph_in >> n_vertices; // read in number of vertices + for (size_type i = 0; i < n_vertices; ++i) + { // Add n vertices to the graph + u = add_vertex(g); + name_in >> name; + put(name_map, u, name); // ** Attach name property to vertex u ** + } + size_type src, targ; + while (graph_in >> src) // Read in edges + if (graph_in >> targ) + add_edge(src, targ, g); // add an edge to the graph + else + break; } -template < typename Graph, typename VertexNameMap > void -output_adjacent_vertices(std::ostream & out, - typename graph_traits < Graph >::vertex_descriptor u, - const Graph & g, VertexNameMap name_map) +template < typename Graph, typename VertexNameMap > +void output_adjacent_vertices(std::ostream& out, + typename graph_traits< Graph >::vertex_descriptor u, const Graph& g, + VertexNameMap name_map) { - typename graph_traits < Graph >::adjacency_iterator vi, vi_end; - out << get(name_map, u) << " -> { "; - for (boost::tie(vi, vi_end) = adjacent_vertices(u, g); vi != vi_end; ++vi) - out << get(name_map, *vi) << " "; - out << "}" << std::endl; + typename graph_traits< Graph >::adjacency_iterator vi, vi_end; + out << get(name_map, u) << " -> { "; + for (boost::tie(vi, vi_end) = adjacent_vertices(u, g); vi != vi_end; ++vi) + out << get(name_map, *vi) << " "; + out << "}" << std::endl; } -template < typename NameMap > class name_equals_t { +template < typename NameMap > class name_equals_t +{ public: - name_equals_t(const std::string & n, NameMap map) - : m_name(n), m_name_map(map) - { - } - template < typename Vertex > bool operator()(Vertex u) const - { - return get(m_name_map, u) == m_name; - } + name_equals_t(const std::string& n, NameMap map) + : m_name(n), m_name_map(map) + { + } + template < typename Vertex > bool operator()(Vertex u) const + { + return get(m_name_map, u) == m_name; + } + private: std::string m_name; - NameMap m_name_map; + NameMap m_name_map; }; // object generator function template < typename NameMap > - inline name_equals_t < NameMap > -name_equals(const std::string & str, NameMap name) +inline name_equals_t< NameMap > name_equals( + const std::string& str, NameMap name) { - return name_equals_t < NameMap > (str, name); + return name_equals_t< NameMap >(str, name); } - -int -main(int argc, const char** argv) +int main(int argc, const char** argv) { - typedef adjacency_list // Add a vertex property - >graph_type; - - graph_type g; // use default constructor to create empty graph - const char* dep_file_name = argc >= 2 ? argv[1] : "makefile-dependencies.dat"; - const char* target_file_name = argc >= 3 ? argv[2] : "makefile-target-names.dat"; - - std::ifstream file_in(dep_file_name), name_in(target_file_name); - if (!file_in) { - std::cerr << "** Error: could not open file " << dep_file_name - << std::endl; - return -1; - } - if (!name_in) { - std::cerr << "** Error: could not open file " << target_file_name - << std::endl; - return -1; - } - - // Obtain internal property map from the graph - property_map < graph_type, vertex_name_t >::type name_map = - get(vertex_name, g); - read_graph_file(file_in, name_in, g, name_map); - - graph_traits < graph_type >::vertex_descriptor yow, zag, bar; - // Get vertex name property map from the graph - typedef property_map < graph_type, vertex_name_t >::type name_map_t; - name_map_t name = get(vertex_name, g); - // Get iterators for the vertex set - graph_traits < graph_type >::vertex_iterator i, end; - boost::tie(i, end) = vertices(g); - // Find yow.h - name_equals_t < name_map_t > predicate1("yow.h", name); - yow = *std::find_if(i, end, predicate1); - // Find zag.o - name_equals_t < name_map_t > predicate2("zag.o", name); - zag = *std::find_if(i, end, predicate2); - // Find bar.o - name_equals_t < name_map_t > predicate3("bar.o", name); - bar = *std::find_if(i, end, predicate3); - - graph_traits < graph_type >::edge_descriptor e1, e2; - bool exists; - - // Get the edge connecting yow.h to zag.o - boost::tie(e1, exists) = edge(yow, zag, g); - assert(exists == true); - assert(source(e1, g) == yow); - assert(target(e1, g) == zag); - - // Discover that there is no edge connecting zag.o to bar.o - boost::tie(e2, exists) = edge(zag, bar, g); - assert(exists == false); - - assert(num_vertices(g) == 15); - assert(num_edges(g) == 19); - - return EXIT_SUCCESS; + typedef adjacency_list< listS, // Store out-edges of each vertex in a + // std::list + vecS, // Store vertex set in a std::vector + directedS, // The graph is directed + property< vertex_name_t, std::string > // Add a vertex property + > + graph_type; + + graph_type g; // use default constructor to create empty graph + const char* dep_file_name + = argc >= 2 ? argv[1] : "makefile-dependencies.dat"; + const char* target_file_name + = argc >= 3 ? argv[2] : "makefile-target-names.dat"; + + std::ifstream file_in(dep_file_name), name_in(target_file_name); + if (!file_in) + { + std::cerr << "** Error: could not open file " << dep_file_name + << std::endl; + return -1; + } + if (!name_in) + { + std::cerr << "** Error: could not open file " << target_file_name + << std::endl; + return -1; + } + + // Obtain internal property map from the graph + property_map< graph_type, vertex_name_t >::type name_map + = get(vertex_name, g); + read_graph_file(file_in, name_in, g, name_map); + + graph_traits< graph_type >::vertex_descriptor yow, zag, bar; + // Get vertex name property map from the graph + typedef property_map< graph_type, vertex_name_t >::type name_map_t; + name_map_t name = get(vertex_name, g); + // Get iterators for the vertex set + graph_traits< graph_type >::vertex_iterator i, end; + boost::tie(i, end) = vertices(g); + // Find yow.h + name_equals_t< name_map_t > predicate1("yow.h", name); + yow = *std::find_if(i, end, predicate1); + // Find zag.o + name_equals_t< name_map_t > predicate2("zag.o", name); + zag = *std::find_if(i, end, predicate2); + // Find bar.o + name_equals_t< name_map_t > predicate3("bar.o", name); + bar = *std::find_if(i, end, predicate3); + + graph_traits< graph_type >::edge_descriptor e1, e2; + bool exists; + + // Get the edge connecting yow.h to zag.o + boost::tie(e1, exists) = edge(yow, zag, g); + assert(exists == true); + assert(source(e1, g) == yow); + assert(target(e1, g) == zag); + + // Discover that there is no edge connecting zag.o to bar.o + boost::tie(e2, exists) = edge(zag, bar, g); + assert(exists == false); + + assert(num_vertices(g) == 15); + assert(num_edges(g) == 19); + + return EXIT_SUCCESS; } diff --git a/example/edge-iter-constructor.cpp b/example/edge-iter-constructor.cpp index ccd18b327..84eb6c2df 100644 --- a/example/edge-iter-constructor.cpp +++ b/example/edge-iter-constructor.cpp @@ -1,5 +1,5 @@ //======================================================================= -// Copyright 2001 Jeremy G. Siek, Andrew Lumsdaine, Lie-Quan Lee, +// Copyright 2001 Jeremy G. Siek, Andrew Lumsdaine, Lie-Quan Lee, // // Distributed under the Boost Software License, Version 1.0. (See // accompanying file LICENSE_1_0.txt or copy at @@ -13,38 +13,37 @@ using namespace boost; template < typename T > - std::istream & operator >> (std::istream & in, std::pair < T, T > &p) { - in >> p.first >> p.second; - return in; +std::istream& operator>>(std::istream& in, std::pair< T, T >& p) +{ + in >> p.first >> p.second; + return in; } - -int -main(int argc, const char** argv) +int main(int argc, const char** argv) { - typedef adjacency_list < - listS, // Store out-edges of each vertex in a std::list - vecS, // Store vertex set in a std::vector - directedS // The graph is directed - > graph_type; - - std::ifstream file_in(argc >= 2 ? argv[1] : "makefile-dependencies.dat"); - typedef graph_traits < graph_type >::vertices_size_type size_type; - size_type n_vertices; - file_in >> n_vertices; // read in number of vertices - - graph_type - g(n_vertices); // create graph with n vertices - - // Read in edges - graph_traits < graph_type >::vertices_size_type u, v; - while (file_in >> u) - if (file_in >> v) - add_edge(u, v, g); - else - break; - - assert(num_vertices(g) == 15); - assert(num_edges(g) == 19); - return 0; + typedef adjacency_list< listS, // Store out-edges of each vertex in a + // std::list + vecS, // Store vertex set in a std::vector + directedS // The graph is directed + > + graph_type; + + std::ifstream file_in(argc >= 2 ? argv[1] : "makefile-dependencies.dat"); + typedef graph_traits< graph_type >::vertices_size_type size_type; + size_type n_vertices; + file_in >> n_vertices; // read in number of vertices + + graph_type g(n_vertices); // create graph with n vertices + + // Read in edges + graph_traits< graph_type >::vertices_size_type u, v; + while (file_in >> u) + if (file_in >> v) + add_edge(u, v, g); + else + break; + + assert(num_vertices(g) == 15); + assert(num_edges(g) == 19); + return 0; } diff --git a/example/edge_basics.cpp b/example/edge_basics.cpp index 0d1d1152d..038ed691b 100644 --- a/example/edge_basics.cpp +++ b/example/edge_basics.cpp @@ -15,7 +15,6 @@ using namespace std; using namespace boost; - /* Edge Basics @@ -23,7 +22,7 @@ using namespace boost; There is not much to the Edge interface. Basically just two functions to access the source and target vertex: - + source(e) target(e) @@ -33,56 +32,52 @@ using namespace boost; Sample output: - (0,1) (0,2) (0,3) (0,4) (2,0) (2,4) (3,0) (3,1) + (0,1) (0,2) (0,3) (0,4) (2,0) (2,4) (3,0) (3,1) */ - - -template -struct exercise_edge { - exercise_edge(Graph& g) : G(g) {} - - typedef typename boost::graph_traits::edge_descriptor Edge; - typedef typename boost::graph_traits::vertex_descriptor Vertex; - void operator()(Edge e) const - { - //begin - // Get the associated vertex type out of the edge using the - // edge_traits class - // Use the source() and target() functions to access the vertices - // that belong to Edge e - Vertex src = source(e, G); - Vertex targ = target(e, G); - - // print out the vertex id's just because - cout << "(" << src << "," << targ << ") "; - //end - } - - Graph& G; +template < class Graph > struct exercise_edge +{ + exercise_edge(Graph& g) : G(g) {} + + typedef typename boost::graph_traits< Graph >::edge_descriptor Edge; + typedef typename boost::graph_traits< Graph >::vertex_descriptor Vertex; + void operator()(Edge e) const + { + // begin + // Get the associated vertex type out of the edge using the + // edge_traits class + // Use the source() and target() functions to access the vertices + // that belong to Edge e + Vertex src = source(e, G); + Vertex targ = target(e, G); + + // print out the vertex id's just because + cout << "(" << src << "," << targ << ") "; + // end + } + + Graph& G; }; - -int -main() +int main() { - typedef adjacency_list<> MyGraph; - - typedef pair Pair; - Pair edge_array[8] = { Pair(0,1), Pair(0,2), Pair(0,3), Pair(0,4), - Pair(2,0), Pair(3,0), Pair(2,4), Pair(3,1) }; - - // Construct a graph using the edge_array (passing in pointers - // (iterators) to the beginning and end of the array), and - // specifying the number of vertices as 5 - MyGraph G(5); - for (int i=0; i<8; ++i) - add_edge(edge_array[i].first, edge_array[i].second, G); - - // Use the STL for_each algorithm to "exercise" all of the edges in - // the graph - for_each(edges(G).first, edges(G).second, exercise_edge(G)); - cout << endl; - return 0; + typedef adjacency_list<> MyGraph; + + typedef pair< int, int > Pair; + Pair edge_array[8] = { Pair(0, 1), Pair(0, 2), Pair(0, 3), Pair(0, 4), + Pair(2, 0), Pair(3, 0), Pair(2, 4), Pair(3, 1) }; + + // Construct a graph using the edge_array (passing in pointers + // (iterators) to the beginning and end of the array), and + // specifying the number of vertices as 5 + MyGraph G(5); + for (int i = 0; i < 8; ++i) + add_edge(edge_array[i].first, edge_array[i].second, G); + + // Use the STL for_each algorithm to "exercise" all of the edges in + // the graph + for_each(edges(G).first, edges(G).second, exercise_edge< MyGraph >(G)); + cout << endl; + return 0; } diff --git a/example/edge_basics.expected b/example/edge_basics.expected index 684dc15f1..ea33f6a4c 100644 --- a/example/edge_basics.expected +++ b/example/edge_basics.expected @@ -1 +1 @@ -(0,1) (0,2) (0,3) (0,4) (2,0) (2,4) (3,0) (3,1) +(0,1) (0,2) (0,3) (0,4) (2,0) (2,4) (3,0) (3,1) diff --git a/example/edge_coloring.cpp b/example/edge_coloring.cpp index 1a752fd19..402337df9 100644 --- a/example/edge_coloring.cpp +++ b/example/edge_coloring.cpp @@ -32,40 +32,44 @@ g-h: 0 */ -int main(int, char *[]) +int main(int, char*[]) { - using namespace boost; - using namespace std; - typedef adjacency_list Graph; + using namespace boost; + using namespace std; + typedef adjacency_list< vecS, vecS, undirectedS, no_property, size_t, + no_property > + Graph; - typedef std::pair Pair; - Pair edges[14] = { Pair(0,3), //a-d - Pair(0,5), //a-f - Pair(1,2), //b-c - Pair(1,4), //b-e - Pair(1,6), //b-g - Pair(1,9), //b-j - Pair(2,3), //c-d - Pair(2,4), //c-e - Pair(3,5), //d-f - Pair(3,8), //d-i - Pair(4,6), //e-g - Pair(5,6), //f-g - Pair(5,7), //f-h - Pair(6,7) }; //g-h + typedef std::pair< std::size_t, std::size_t > Pair; + Pair edges[14] = { Pair(0, 3), // a-d + Pair(0, 5), // a-f + Pair(1, 2), // b-c + Pair(1, 4), // b-e + Pair(1, 6), // b-g + Pair(1, 9), // b-j + Pair(2, 3), // c-d + Pair(2, 4), // c-e + Pair(3, 5), // d-f + Pair(3, 8), // d-i + Pair(4, 6), // e-g + Pair(5, 6), // f-g + Pair(5, 7), // f-h + Pair(6, 7) }; // g-h - Graph G(10); + Graph G(10); - for (size_t i = 0; i < sizeof(edges)/sizeof(edges[0]); i++) - add_edge(edges[i].first, edges[i].second, G); + for (size_t i = 0; i < sizeof(edges) / sizeof(edges[0]); i++) + add_edge(edges[i].first, edges[i].second, G); - size_t colors = edge_coloring(G, get(edge_bundle, G)); + size_t colors = edge_coloring(G, get(edge_bundle, G)); - cout << "Colored using " << colors << " colors" << endl; - for (size_t i = 0; i < sizeof(edges)/sizeof(edges[0]); i++) { - cout << " " << (char)('a' + edges[i].first) << "-" << (char)('a' + edges[i].second) << ": " << G[edge(edges[i].first, edges[i].second, G).first] << endl; - } + cout << "Colored using " << colors << " colors" << endl; + for (size_t i = 0; i < sizeof(edges) / sizeof(edges[0]); i++) + { + cout << " " << (char)('a' + edges[i].first) << "-" + << (char)('a' + edges[i].second) << ": " + << G[edge(edges[i].first, edges[i].second, G).first] << endl; + } - return 0; + return 0; } - diff --git a/example/edge_connectivity.cpp b/example/edge_connectivity.cpp index f0ca14a33..2e05a8b4c 100644 --- a/example/edge_connectivity.cpp +++ b/example/edge_connectivity.cpp @@ -7,12 +7,11 @@ // http://www.boost.org/LICENSE_1_0.txt) //======================================================================= - /* IMPORTANT!!! ~~~~~~~~~~~~ - This example uses interfaces that have been deprecated and removed from Boost.Grpah. - Someone needs to update it, as it does NOT compile. + This example uses interfaces that have been deprecated and removed from + Boost.Grpah. Someone needs to update it, as it does NOT compile. */ #include @@ -25,40 +24,40 @@ using namespace boost; -int -main() +int main() { - const int N = 8; - typedef adjacency_list UndirectedGraph; - UndirectedGraph g(N); - - add_edge(0, 1, g); - add_edge(0, 2, g); - add_edge(0, 3, g); - add_edge(1, 2, g); - add_edge(1, 3, g); - add_edge(2, 3, g); - add_edge(3, 4, g); - add_edge(3, 7, g); - add_edge(4, 5, g); - add_edge(4, 6, g); - add_edge(4, 7, g); - add_edge(5, 6, g); - add_edge(5, 7, g); - add_edge(6, 7, g); - - typedef graph_traits::edge_descriptor edge_descriptor; - typedef graph_traits::degree_size_type degree_size_type; - std::vector disconnecting_set; - - degree_size_type c = edge_connectivity(g, std::back_inserter(disconnecting_set)); - - std::cout << "The edge connectivity is " << c << "." << std::endl; - std::cout << "The disconnecting set is {"; - - std::copy(disconnecting_set.begin(), disconnecting_set.end(), - std::ostream_iterator(std::cout, " ")); - std::cout << "}." << std::endl; - - return 0; + const int N = 8; + typedef adjacency_list< vecS, vecS, undirectedS > UndirectedGraph; + UndirectedGraph g(N); + + add_edge(0, 1, g); + add_edge(0, 2, g); + add_edge(0, 3, g); + add_edge(1, 2, g); + add_edge(1, 3, g); + add_edge(2, 3, g); + add_edge(3, 4, g); + add_edge(3, 7, g); + add_edge(4, 5, g); + add_edge(4, 6, g); + add_edge(4, 7, g); + add_edge(5, 6, g); + add_edge(5, 7, g); + add_edge(6, 7, g); + + typedef graph_traits< UndirectedGraph >::edge_descriptor edge_descriptor; + typedef graph_traits< UndirectedGraph >::degree_size_type degree_size_type; + std::vector< edge_descriptor > disconnecting_set; + + degree_size_type c + = edge_connectivity(g, std::back_inserter(disconnecting_set)); + + std::cout << "The edge connectivity is " << c << "." << std::endl; + std::cout << "The disconnecting set is {"; + + std::copy(disconnecting_set.begin(), disconnecting_set.end(), + std::ostream_iterator< edge_descriptor >(std::cout, " ")); + std::cout << "}." << std::endl; + + return 0; } diff --git a/example/edge_iterator_constructor.cpp b/example/edge_iterator_constructor.cpp index e8fe0a3af..837a2c810 100644 --- a/example/edge_iterator_constructor.cpp +++ b/example/edge_iterator_constructor.cpp @@ -24,11 +24,11 @@ Sample output: - 0 --> 1 - 1 --> 2 3 0 - 2 --> 4 1 - 3 --> 4 1 - 4 --> 2 3 + 0 --> 1 + 1 --> 2 3 0 + 2 --> 4 1 + 3 --> 4 1 + 4 --> 2 3 */ @@ -41,79 +41,80 @@ #include #include -class edge_stream_iterator { +class edge_stream_iterator +{ public: - typedef std::input_iterator_tag iterator_category; - typedef std::pair value_type; - typedef std::ptrdiff_t difference_type; - typedef const value_type* pointer; - typedef const value_type& reference; + typedef std::input_iterator_tag iterator_category; + typedef std::pair< int, int > value_type; + typedef std::ptrdiff_t difference_type; + typedef const value_type* pointer; + typedef const value_type& reference; - edge_stream_iterator() : m_stream(0), m_end_marker(false) {} - edge_stream_iterator(std::istream& s) : m_stream(&s) { m_read(); } - reference operator*() const { return m_edge; } - edge_stream_iterator& operator++() { - m_read(); - return *this; - } - edge_stream_iterator operator++(int) { - edge_stream_iterator tmp = *this; - m_read(); - return tmp; - } -protected: - std::istream* m_stream; - value_type m_edge; - bool m_end_marker; - void m_read() { - m_end_marker = (*m_stream) ? true : false; - if (m_end_marker) { - *m_stream >> m_edge.first >> m_edge.second; + edge_stream_iterator() : m_stream(0), m_end_marker(false) {} + edge_stream_iterator(std::istream& s) : m_stream(&s) { m_read(); } + reference operator*() const { return m_edge; } + edge_stream_iterator& operator++() + { + m_read(); + return *this; + } + edge_stream_iterator operator++(int) + { + edge_stream_iterator tmp = *this; + m_read(); + return tmp; } - m_end_marker = (*m_stream) ? true : false; - } - friend bool operator==(const edge_stream_iterator& x, - const edge_stream_iterator& y); +protected: + std::istream* m_stream; + value_type m_edge; + bool m_end_marker; + void m_read() + { + m_end_marker = (*m_stream) ? true : false; + if (m_end_marker) + { + *m_stream >> m_edge.first >> m_edge.second; + } + m_end_marker = (*m_stream) ? true : false; + } + friend bool operator==( + const edge_stream_iterator& x, const edge_stream_iterator& y); }; -bool operator==(const edge_stream_iterator& x, - const edge_stream_iterator& y) +bool operator==(const edge_stream_iterator& x, const edge_stream_iterator& y) { - return (x.m_stream == y.m_stream && x.m_end_marker == y.m_end_marker) - || (x.m_end_marker == false && y.m_end_marker == false); + return (x.m_stream == y.m_stream && x.m_end_marker == y.m_end_marker) + || (x.m_end_marker == false && y.m_end_marker == false); } -bool operator!=(const edge_stream_iterator& x, - const edge_stream_iterator& y) +bool operator!=(const edge_stream_iterator& x, const edge_stream_iterator& y) { - return !(x == y); + return !(x == y); } - - -int -main(int argc, const char** argv) +int main(int argc, const char** argv) { - typedef boost::adjacency_list<> IteratorConstructibleGraph; - typedef boost::graph_traits Traits; - Traits::vertices_size_type size_V; - Traits::edges_size_type size_E; + typedef boost::adjacency_list<> IteratorConstructibleGraph; + typedef boost::graph_traits< IteratorConstructibleGraph > Traits; + Traits::vertices_size_type size_V; + Traits::edges_size_type size_E; - std::ifstream f(argc >= 2 ? argv[1] : "edge_iterator_constructor.dat"); - f >> size_V >> size_E; + std::ifstream f(argc >= 2 ? argv[1] : "edge_iterator_constructor.dat"); + f >> size_V >> size_E; - edge_stream_iterator edge_iter(f), end; + edge_stream_iterator edge_iter(f), end; #if defined(BOOST_MSVC) && BOOST_MSVC <= 1300 - // VC++ can't handle the iterator constructor - IteratorConstructibleGraph G(size_V); - while (edge_iter != end) { - int i, j; - boost::tie(i, j) = *edge_iter++; - boost::add_edge(i, j, G); - } + // VC++ can't handle the iterator constructor + IteratorConstructibleGraph G(size_V); + while (edge_iter != end) + { + int i, j; + boost::tie(i, j) = *edge_iter++; + boost::add_edge(i, j, G); + } #else - IteratorConstructibleGraph G(edge_iter, end, size_V); + IteratorConstructibleGraph G(edge_iter, end, size_V); #endif - boost::print_graph(G); + boost::print_graph(G); - return 0; + return 0; } diff --git a/example/edge_property.cpp b/example/edge_property.cpp index 879e75704..7da442fd8 100644 --- a/example/edge_property.cpp +++ b/example/edge_property.cpp @@ -9,45 +9,45 @@ // // Sample output: // -// 0 --(8, 10)--> 1 +// 0 --(8, 10)--> 1 // -// 1 --(12, 20)--> 4 --(12, 40)--> 3 -// <--(8,10)-- 0 <--(16,20)-- 2 -// 2 --(16, 20)--> 1 -// <--(16,20)-- 5 -// 3 --(12, 40)--> 6 -// <--(12,40)-- 1 -// 4 --(12, 20)--> 7 -// <--(12,20)-- 1 -// 5 --(16, 20)--> 2 -// <--(16,20)-- 6 -// 6 --(16, 20)--> 5 --(8, 10)--> 8 -// <--(12,20)-- 7 <--(12,40)-- 3 -// 7 --(12, 20)--> 6 -// <--(12,20)-- 4 -// 8 -// <--(8,10)-- 6 +// 1 --(12, 20)--> 4 --(12, 40)--> 3 +// <--(8,10)-- 0 <--(16,20)-- 2 +// 2 --(16, 20)--> 1 +// <--(16,20)-- 5 +// 3 --(12, 40)--> 6 +// <--(12,40)-- 1 +// 4 --(12, 20)--> 7 +// <--(12,20)-- 1 +// 5 --(16, 20)--> 2 +// <--(16,20)-- 6 +// 6 --(16, 20)--> 5 --(8, 10)--> 8 +// <--(12,20)-- 7 <--(12,40)-- 3 +// 7 --(12, 20)--> 6 +// <--(12,20)-- 4 +// 8 +// <--(8,10)-- 6 // // -// 0 --(8, 1)--> 1 +// 0 --(8, 1)--> 1 // -// 1 --(12, 2)--> 4 --(12, 3)--> 3 -// <--(8,1)-- 0 <--(16,4)-- 2 -// 2 --(16, 4)--> 1 -// <--(16,7)-- 5 -// 3 --(12, 5)--> 6 -// <--(12,3)-- 1 -// 4 --(12, 6)--> 7 -// <--(12,2)-- 1 -// 5 --(16, 7)--> 2 -// <--(16,8)-- 6 -// 6 --(16, 8)--> 5 -// <--(12,10)-- 7 <--(12,5)-- 3 -// 7 --(12, 10)--> 6 -// <--(12,6)-- 4 -// 8 +// 1 --(12, 2)--> 4 --(12, 3)--> 3 +// <--(8,1)-- 0 <--(16,4)-- 2 +// 2 --(16, 4)--> 1 +// <--(16,7)-- 5 +// 3 --(12, 5)--> 6 +// <--(12,3)-- 1 +// 4 --(12, 6)--> 7 +// <--(12,2)-- 1 +// 5 --(16, 7)--> 2 +// <--(16,8)-- 6 +// 6 --(16, 8)--> 5 +// <--(12,10)-- 7 <--(12,5)-- 3 +// 7 --(12, 10)--> 6 +// <--(12,6)-- 4 +// 8 // - + #include #include @@ -55,109 +55,111 @@ #include #include - using namespace boost; using namespace std; +enum edge_myflow_t +{ + edge_myflow +}; +enum edge_mycapacity_t +{ + edge_mycapacity +}; -enum edge_myflow_t { edge_myflow }; -enum edge_mycapacity_t { edge_mycapacity }; - -namespace boost { - BOOST_INSTALL_PROPERTY(edge, myflow); - BOOST_INSTALL_PROPERTY(edge, mycapacity); +namespace boost +{ +BOOST_INSTALL_PROPERTY(edge, myflow); +BOOST_INSTALL_PROPERTY(edge, mycapacity); } - -template -void print_network(const Graph& G) +template < class Graph > void print_network(const Graph& G) { - typedef typename boost::graph_traits::vertex_iterator Viter; - typedef typename boost::graph_traits::out_edge_iterator OutEdgeIter; - typedef typename boost::graph_traits::in_edge_iterator InEdgeIter; - - typename property_map::const_type - capacity = get(edge_mycapacity, G); - typename property_map::const_type - flow = get(edge_myflow, G); - - Viter ui, uiend; - boost::tie(ui, uiend) = vertices(G); - - for (; ui != uiend; ++ui) { - OutEdgeIter out, out_end; - cout << *ui << "\t"; - - boost::tie(out, out_end) = out_edges(*ui, G); - for(; out != out_end; ++out) - cout << "--(" << capacity[*out] << ", " << flow[*out] << ")--> " - << target(*out,G) << "\t"; - - InEdgeIter in, in_end; - cout << endl << "\t"; - boost::tie(in, in_end) = in_edges(*ui, G); - for(; in != in_end; ++in) - cout << "<--(" << capacity[*in] << "," << flow[*in] << ")-- " - << source(*in,G) << "\t"; - - cout << endl; - } + typedef typename boost::graph_traits< Graph >::vertex_iterator Viter; + typedef + typename boost::graph_traits< Graph >::out_edge_iterator OutEdgeIter; + typedef typename boost::graph_traits< Graph >::in_edge_iterator InEdgeIter; + + typename property_map< Graph, edge_mycapacity_t >::const_type capacity + = get(edge_mycapacity, G); + typename property_map< Graph, edge_myflow_t >::const_type flow + = get(edge_myflow, G); + + Viter ui, uiend; + boost::tie(ui, uiend) = vertices(G); + + for (; ui != uiend; ++ui) + { + OutEdgeIter out, out_end; + cout << *ui << "\t"; + + boost::tie(out, out_end) = out_edges(*ui, G); + for (; out != out_end; ++out) + cout << "--(" << capacity[*out] << ", " << flow[*out] << ")--> " + << target(*out, G) << "\t"; + + InEdgeIter in, in_end; + cout << endl << "\t"; + boost::tie(in, in_end) = in_edges(*ui, G); + for (; in != in_end; ++in) + cout << "<--(" << capacity[*in] << "," << flow[*in] << ")-- " + << source(*in, G) << "\t"; + + cout << endl; + } } - -int main(int , char* []) +int main(int, char*[]) { - typedef property Cap; - typedef property Flow; - typedef adjacency_list Graph; + typedef property< edge_mycapacity_t, int > Cap; + typedef property< edge_myflow_t, int, Cap > Flow; + typedef adjacency_list< vecS, vecS, bidirectionalS, no_property, Flow > + Graph; - const int num_vertices = 9; - Graph G(num_vertices); + const int num_vertices = 9; + Graph G(num_vertices); - /* 2<----5 - / ^ - / \ - V \ - 0 ---->1---->3----->6--->8 - \ ^ - \ / - V / - 4----->7 - */ + /* 2<----5 + / ^ + / \ + V \ + 0 ---->1---->3----->6--->8 + \ ^ + \ / + V / + 4----->7 + */ - add_edge(0, 1, Flow(10, Cap(8)), G); + add_edge(0, 1, Flow(10, Cap(8)), G); - add_edge(1, 4, Flow(20, Cap(12)), G); - add_edge(4, 7, Flow(20, Cap(12)), G); - add_edge(7, 6, Flow(20, Cap(12)), G); + add_edge(1, 4, Flow(20, Cap(12)), G); + add_edge(4, 7, Flow(20, Cap(12)), G); + add_edge(7, 6, Flow(20, Cap(12)), G); - add_edge(1, 3, Flow(40, Cap(12)), G); - add_edge(3, 6, Flow(40, Cap(12)), G); + add_edge(1, 3, Flow(40, Cap(12)), G); + add_edge(3, 6, Flow(40, Cap(12)), G); - add_edge(6, 5, Flow(20, Cap(16)), G); - add_edge(5, 2, Flow(20, Cap(16)), G); - add_edge(2, 1, Flow(20, Cap(16)), G); + add_edge(6, 5, Flow(20, Cap(16)), G); + add_edge(5, 2, Flow(20, Cap(16)), G); + add_edge(2, 1, Flow(20, Cap(16)), G); - add_edge(6, 8, Flow(10, Cap(8)), G); + add_edge(6, 8, Flow(10, Cap(8)), G); - print_network(G); + print_network(G); - property_map::type - flow = get(edge_myflow, G); + property_map< Graph, edge_myflow_t >::type flow = get(edge_myflow, G); - boost::graph_traits::vertex_iterator v, v_end; - boost::graph_traits::out_edge_iterator e, e_end; - int f = 0; - for (boost::tie(v, v_end) = vertices(G); v != v_end; ++v) - for (boost::tie(e, e_end) = out_edges(*v, G); e != e_end; ++e) - flow[*e] = ++f; - cout << endl << endl; + boost::graph_traits< Graph >::vertex_iterator v, v_end; + boost::graph_traits< Graph >::out_edge_iterator e, e_end; + int f = 0; + for (boost::tie(v, v_end) = vertices(G); v != v_end; ++v) + for (boost::tie(e, e_end) = out_edges(*v, G); e != e_end; ++e) + flow[*e] = ++f; + cout << endl << endl; - remove_edge(6, 8, G); + remove_edge(6, 8, G); - print_network(G); + print_network(G); - - return 0; + return 0; } diff --git a/example/edge_property.expected b/example/edge_property.expected index 6c71be14c..d0d6693a1 100644 --- a/example/edge_property.expected +++ b/example/edge_property.expected @@ -1,38 +1,38 @@ -0 --(8, 10)--> 1 - -1 --(12, 20)--> 4 --(12, 40)--> 3 - <--(8,10)-- 0 <--(16,20)-- 2 -2 --(16, 20)--> 1 - <--(16,20)-- 5 -3 --(12, 40)--> 6 - <--(12,40)-- 1 -4 --(12, 20)--> 7 - <--(12,20)-- 1 -5 --(16, 20)--> 2 - <--(16,20)-- 6 -6 --(16, 20)--> 5 --(8, 10)--> 8 - <--(12,20)-- 7 <--(12,40)-- 3 -7 --(12, 20)--> 6 - <--(12,20)-- 4 -8 - <--(8,10)-- 6 +0 --(8, 10)--> 1 +1 --(12, 20)--> 4 --(12, 40)--> 3 + <--(8,10)-- 0 <--(16,20)-- 2 +2 --(16, 20)--> 1 + <--(16,20)-- 5 +3 --(12, 40)--> 6 + <--(12,40)-- 1 +4 --(12, 20)--> 7 + <--(12,20)-- 1 +5 --(16, 20)--> 2 + <--(16,20)-- 6 +6 --(16, 20)--> 5 --(8, 10)--> 8 + <--(12,20)-- 7 <--(12,40)-- 3 +7 --(12, 20)--> 6 + <--(12,20)-- 4 +8 + <--(8,10)-- 6 + + +0 --(8, 1)--> 1 + +1 --(12, 2)--> 4 --(12, 3)--> 3 + <--(8,1)-- 0 <--(16,4)-- 2 +2 --(16, 4)--> 1 + <--(16,7)-- 5 +3 --(12, 5)--> 6 + <--(12,3)-- 1 +4 --(12, 6)--> 7 + <--(12,2)-- 1 +5 --(16, 7)--> 2 + <--(16,8)-- 6 +6 --(16, 8)--> 5 + <--(12,10)-- 7 <--(12,5)-- 3 +7 --(12, 10)--> 6 + <--(12,6)-- 4 +8 -0 --(8, 1)--> 1 - -1 --(12, 2)--> 4 --(12, 3)--> 3 - <--(8,1)-- 0 <--(16,4)-- 2 -2 --(16, 4)--> 1 - <--(16,7)-- 5 -3 --(12, 5)--> 6 - <--(12,3)-- 1 -4 --(12, 6)--> 7 - <--(12,2)-- 1 -5 --(16, 7)--> 2 - <--(16,8)-- 6 -6 --(16, 8)--> 5 - <--(12,10)-- 7 <--(12,5)-- 3 -7 --(12, 10)--> 6 - <--(12,6)-- 4 -8 - diff --git a/example/edmonds-karp-eg.cpp b/example/edmonds-karp-eg.cpp index 6c38e80b5..a27718b72 100644 --- a/example/edmonds-karp-eg.cpp +++ b/example/edmonds-karp-eg.cpp @@ -1,5 +1,5 @@ //======================================================================= -// Copyright 2001 Jeremy G. Siek, Andrew Lumsdaine, Lie-Quan Lee, +// Copyright 2001 Jeremy G. Siek, Andrew Lumsdaine, Lie-Quan Lee, // // Distributed under the Boost Software License, Version 1.0. (See // accompanying file LICENSE_1_0.txt or copy at @@ -47,49 +47,50 @@ // f 7 6 0 // f 7 5 0 -int -main() +int main() { - using namespace boost; + using namespace boost; - typedef adjacency_list_traits < vecS, vecS, directedS > Traits; - typedef adjacency_list < listS, vecS, directedS, - property < vertex_name_t, std::string >, - property < edge_capacity_t, long, - property < edge_residual_capacity_t, long, - property < edge_reverse_t, Traits::edge_descriptor > > > > Graph; + typedef adjacency_list_traits< vecS, vecS, directedS > Traits; + typedef adjacency_list< listS, vecS, directedS, + property< vertex_name_t, std::string >, + property< edge_capacity_t, long, + property< edge_residual_capacity_t, long, + property< edge_reverse_t, Traits::edge_descriptor > > > > + Graph; - Graph g; + Graph g; - property_map < Graph, edge_capacity_t >::type - capacity = get(edge_capacity, g); - property_map < Graph, edge_reverse_t >::type rev = get(edge_reverse, g); - property_map < Graph, edge_residual_capacity_t >::type - residual_capacity = get(edge_residual_capacity, g); + property_map< Graph, edge_capacity_t >::type capacity + = get(edge_capacity, g); + property_map< Graph, edge_reverse_t >::type rev = get(edge_reverse, g); + property_map< Graph, edge_residual_capacity_t >::type residual_capacity + = get(edge_residual_capacity, g); - Traits::vertex_descriptor s, t; - read_dimacs_max_flow(g, capacity, rev, s, t); + Traits::vertex_descriptor s, t; + read_dimacs_max_flow(g, capacity, rev, s, t); #if defined(BOOST_MSVC) && BOOST_MSVC <= 1300 - std::vector color(num_vertices(g)); - std::vector pred(num_vertices(g)); - long flow = edmonds_karp_max_flow - (g, s, t, capacity, residual_capacity, rev, &color[0], &pred[0]); + std::vector< default_color_type > color(num_vertices(g)); + std::vector< Traits::edge_descriptor > pred(num_vertices(g)); + long flow = edmonds_karp_max_flow( + g, s, t, capacity, residual_capacity, rev, &color[0], &pred[0]); #else - long flow = edmonds_karp_max_flow(g, s, t); + long flow = edmonds_karp_max_flow(g, s, t); #endif - std::cout << "c The total flow:" << std::endl; - std::cout << "s " << flow << std::endl << std::endl; + std::cout << "c The total flow:" << std::endl; + std::cout << "s " << flow << std::endl << std::endl; - std::cout << "c flow values:" << std::endl; - graph_traits < Graph >::vertex_iterator u_iter, u_end; - graph_traits < Graph >::out_edge_iterator ei, e_end; - for (boost::tie(u_iter, u_end) = vertices(g); u_iter != u_end; ++u_iter) - for (boost::tie(ei, e_end) = out_edges(*u_iter, g); ei != e_end; ++ei) - if (capacity[*ei] > 0) - std::cout << "f " << *u_iter << " " << target(*ei, g) << " " - << (capacity[*ei] - residual_capacity[*ei]) << std::endl; + std::cout << "c flow values:" << std::endl; + graph_traits< Graph >::vertex_iterator u_iter, u_end; + graph_traits< Graph >::out_edge_iterator ei, e_end; + for (boost::tie(u_iter, u_end) = vertices(g); u_iter != u_end; ++u_iter) + for (boost::tie(ei, e_end) = out_edges(*u_iter, g); ei != e_end; ++ei) + if (capacity[*ei] > 0) + std::cout << "f " << *u_iter << " " << target(*ei, g) << " " + << (capacity[*ei] - residual_capacity[*ei]) + << std::endl; - return EXIT_SUCCESS; + return EXIT_SUCCESS; } diff --git a/example/exterior_properties.cpp b/example/exterior_properties.cpp index 3ca4edc30..4c2e892f7 100644 --- a/example/exterior_properties.cpp +++ b/example/exterior_properties.cpp @@ -13,103 +13,111 @@ // // Sample output: // -// 0 --(10, 8)--> 1 +// 0 --(10, 8)--> 1 // -// 1 --(20, 12)--> 4 --(40, 12)--> 3 -// <--(10,8)-- 0 <--(20,16)-- 2 -// 2 --(20, 16)--> 1 -// <--(20,16)-- 5 -// 3 --(40, 12)--> 6 -// <--(40,12)-- 1 -// 4 --(20, 12)--> 7 -// <--(20,12)-- 1 -// 5 --(20, 16)--> 2 -// <--(20,16)-- 6 -// 6 --(20, 16)--> 5 --(10, 8)--> 8 -// <--(20,12)-- 7 <--(40,12)-- 3 -// 7 --(20, 12)--> 6 -// <--(20,12)-- 4 -// 8 -// <--(10,8)-- 6 - +// 1 --(20, 12)--> 4 --(40, 12)--> 3 +// <--(10,8)-- 0 <--(20,16)-- 2 +// 2 --(20, 16)--> 1 +// <--(20,16)-- 5 +// 3 --(40, 12)--> 6 +// <--(40,12)-- 1 +// 4 --(20, 12)--> 7 +// <--(20,12)-- 1 +// 5 --(20, 16)--> 2 +// <--(20,16)-- 6 +// 6 --(20, 16)--> 5 --(10, 8)--> 8 +// <--(20,12)-- 7 <--(40,12)-- 3 +// 7 --(20, 12)--> 6 +// <--(20,12)-- 4 +// 8 +// <--(10,8)-- 6 #include #include #include #include -template +template < class Graph, class Capacity, class Flow > void print_network(Graph& G, Capacity capacity, Flow flow) { - typedef typename boost::graph_traits::vertex_iterator Viter; - typedef typename boost::graph_traits::out_edge_iterator OutEdgeIter; - typedef typename boost::graph_traits::in_edge_iterator InEdgeIter; - - Viter ui, uiend; - for (boost::tie(ui, uiend) = boost::vertices(G); ui != uiend; ++ui) { - OutEdgeIter out, out_end; - std::cout << *ui << "\t"; - - for(boost::tie(out, out_end) = boost::out_edges(*ui, G); out != out_end; ++out) - std::cout << "--(" << boost::get(capacity, *out) << ", " - << boost::get(flow, *out) << ")--> " << boost::target(*out,G) << "\t"; - std::cout << std::endl << "\t"; - - InEdgeIter in, in_end; - for(boost::tie(in, in_end) = boost::in_edges(*ui, G); in != in_end; ++in) - std::cout << "<--(" << boost::get(capacity, *in) << "," << boost::get(flow, *in) << ")-- " - << boost::source(*in, G) << "\t"; - std::cout << std::endl; - } + typedef typename boost::graph_traits< Graph >::vertex_iterator Viter; + typedef + typename boost::graph_traits< Graph >::out_edge_iterator OutEdgeIter; + typedef typename boost::graph_traits< Graph >::in_edge_iterator InEdgeIter; + + Viter ui, uiend; + for (boost::tie(ui, uiend) = boost::vertices(G); ui != uiend; ++ui) + { + OutEdgeIter out, out_end; + std::cout << *ui << "\t"; + + for (boost::tie(out, out_end) = boost::out_edges(*ui, G); + out != out_end; ++out) + std::cout << "--(" << boost::get(capacity, *out) << ", " + << boost::get(flow, *out) << ")--> " + << boost::target(*out, G) << "\t"; + std::cout << std::endl << "\t"; + + InEdgeIter in, in_end; + for (boost::tie(in, in_end) = boost::in_edges(*ui, G); in != in_end; + ++in) + std::cout << "<--(" << boost::get(capacity, *in) << "," + << boost::get(flow, *in) << ")-- " + << boost::source(*in, G) << "\t"; + std::cout << std::endl; + } } +int main(int, char*[]) +{ -int main(int , char* []) { + typedef boost::adjacency_list< boost::vecS, boost::vecS, + boost::bidirectionalS, boost::no_property, + boost::property< boost::edge_index_t, std::size_t > > + Graph; - typedef boost::adjacency_list > Graph; + const int num_vertices = 9; + Graph G(num_vertices); - const int num_vertices = 9; - Graph G(num_vertices); + /* 2<----5 + / ^ + / \ + V \ + 0 ---->1---->3----->6--->8 + \ ^ + \ / + V / + 4----->7 + */ - /* 2<----5 - / ^ - / \ - V \ - 0 ---->1---->3----->6--->8 - \ ^ - \ / - V / - 4----->7 - */ + int capacity[] = { 10, 20, 20, 20, 40, 40, 20, 20, 20, 10 }; + int flow[] = { 8, 12, 12, 12, 12, 12, 16, 16, 16, 8 }; - int capacity[] = { 10, 20, 20, 20, 40, 40, 20, 20, 20, 10 }; - int flow[] = { 8, 12, 12, 12, 12, 12, 16, 16, 16, 8 }; + // insert edges into the graph, and assign each edge an ID number + // to index into the property arrays + boost::add_edge(0, 1, 0, G); - // insert edges into the graph, and assign each edge an ID number - // to index into the property arrays - boost::add_edge(0, 1, 0, G); + boost::add_edge(1, 4, 1, G); + boost::add_edge(4, 7, 2, G); + boost::add_edge(7, 6, 3, G); - boost::add_edge(1, 4, 1, G); - boost::add_edge(4, 7, 2, G); - boost::add_edge(7, 6, 3, G); + boost::add_edge(1, 3, 4, G); + boost::add_edge(3, 6, 5, G); - boost::add_edge(1, 3, 4, G); - boost::add_edge(3, 6, 5, G); + boost::add_edge(6, 5, 6, G); + boost::add_edge(5, 2, 7, G); + boost::add_edge(2, 1, 8, G); - boost::add_edge(6, 5, 6, G); - boost::add_edge(5, 2, 7, G); - boost::add_edge(2, 1, 8, G); + boost::add_edge(6, 8, 9, G); - boost::add_edge(6, 8, 9, G); + typedef boost::property_map< Graph, boost::edge_index_t >::type + EdgeIndexMap; + EdgeIndexMap edge_id = boost::get(boost::edge_index, G); - typedef boost::property_map::type EdgeIndexMap; - EdgeIndexMap edge_id = boost::get(boost::edge_index, G); + typedef boost::iterator_property_map< int*, EdgeIndexMap, int, int& > + IterMap; - typedef boost::iterator_property_map IterMap; + print_network(G, IterMap(capacity, edge_id), IterMap(flow, edge_id)); - print_network(G, IterMap(capacity, edge_id), IterMap(flow, edge_id)); - - return 0; + return 0; } diff --git a/example/exterior_properties.expected b/example/exterior_properties.expected index 863e00601..70ff90ddc 100644 --- a/example/exterior_properties.expected +++ b/example/exterior_properties.expected @@ -1,18 +1,18 @@ -0 --(10, 8)--> 1 - -1 --(20, 12)--> 4 --(40, 12)--> 3 - <--(10,8)-- 0 <--(20,16)-- 2 -2 --(20, 16)--> 1 - <--(20,16)-- 5 -3 --(40, 12)--> 6 - <--(40,12)-- 1 -4 --(20, 12)--> 7 - <--(20,12)-- 1 -5 --(20, 16)--> 2 - <--(20,16)-- 6 -6 --(20, 16)--> 5 --(10, 8)--> 8 - <--(20,12)-- 7 <--(40,12)-- 3 -7 --(20, 12)--> 6 - <--(20,12)-- 4 -8 - <--(10,8)-- 6 +0 --(10, 8)--> 1 + +1 --(20, 12)--> 4 --(40, 12)--> 3 + <--(10,8)-- 0 <--(20,16)-- 2 +2 --(20, 16)--> 1 + <--(20,16)-- 5 +3 --(40, 12)--> 6 + <--(40,12)-- 1 +4 --(20, 12)--> 7 + <--(20,12)-- 1 +5 --(20, 16)--> 2 + <--(20,16)-- 6 +6 --(20, 16)--> 5 --(10, 8)--> 8 + <--(20,12)-- 7 <--(40,12)-- 3 +7 --(20, 12)--> 6 + <--(20,12)-- 4 +8 + <--(10,8)-- 6 diff --git a/example/exterior_property_map.cpp b/example/exterior_property_map.cpp index 9b9ac79eb..8aa404757 100644 --- a/example/exterior_property_map.cpp +++ b/example/exterior_property_map.cpp @@ -53,42 +53,41 @@ using namespace boost; */ -template -void who_owes_who(EdgeIter first, EdgeIter last, const Graph& G, - Name name) +template < class EdgeIter, class Graph, class Name > +void who_owes_who(EdgeIter first, EdgeIter last, const Graph& G, Name name) { - while (first != last) { + while (first != last) + { - cout << name[source(*first,G)] << " owes " - << name[target(*first,G)] << " some money" << endl; - ++first; - } + cout << name[source(*first, G)] << " owes " << name[target(*first, G)] + << " some money" << endl; + ++first; + } } -int -main(int, char*[]) +int main(int, char*[]) { - /* The property will be "names" attached to the vertices */ - - string* names = new string[5]; - names[0] = "Jeremy"; - names[1] = "Rich"; - names[2] = "Andrew"; - names[3] = "Jeff"; - names[4] = "Kinis"; - - typedef adjacency_list<> MyGraphType; - - typedef pair Pair; - Pair edge_array[11] = { Pair(0,1), Pair(0,2), Pair(0,3), Pair(0,4), - Pair(2,0), Pair(3,0), Pair(2,4), Pair(3,1), - Pair(3,4), Pair(4,0), Pair(4,1) }; + /* The property will be "names" attached to the vertices */ + + string* names = new string[5]; + names[0] = "Jeremy"; + names[1] = "Rich"; + names[2] = "Andrew"; + names[3] = "Jeff"; + names[4] = "Kinis"; + + typedef adjacency_list<> MyGraphType; + + typedef pair< int, int > Pair; + Pair edge_array[11] = { Pair(0, 1), Pair(0, 2), Pair(0, 3), Pair(0, 4), + Pair(2, 0), Pair(3, 0), Pair(2, 4), Pair(3, 1), Pair(3, 4), Pair(4, 0), + Pair(4, 1) }; MyGraphType G(5); - for (int i=0; i<11; ++i) - add_edge(edge_array[i].first, edge_array[i].second, G); + for (int i = 0; i < 11; ++i) + add_edge(edge_array[i].first, edge_array[i].second, G); - who_owes_who(edges(G).first, edges(G).second, G, names); + who_owes_who(edges(G).first, edges(G).second, G, names); - return 0; + return 0; } diff --git a/example/family_tree.cpp b/example/family_tree.cpp index c36239351..a3db9da9a 100644 --- a/example/family_tree.cpp +++ b/example/family_tree.cpp @@ -1,5 +1,5 @@ //======================================================================= -// Copyright 2001 Jeremy G. Siek, Andrew Lumsdaine, Lie-Quan Lee, +// Copyright 2001 Jeremy G. Siek, Andrew Lumsdaine, Lie-Quan Lee, // // Distributed under the Boost Software License, Version 1.0. (See // accompanying file LICENSE_1_0.txt or copy at @@ -12,41 +12,50 @@ #include #include enum family -{ Jeanie, Debbie, Rick, John, Amanda, Margaret, Benjamin, N }; -int -main() { - using namespace boost; - const char *name[] = { "Jeanie", "Debbie", "Rick", "John", "Amanda", - "Margaret", "Benjamin" - }; + Jeanie, + Debbie, + Rick, + John, + Amanda, + Margaret, + Benjamin, + N +}; +int main() +{ + using namespace boost; + const char* name[] = { "Jeanie", "Debbie", "Rick", "John", "Amanda", + "Margaret", "Benjamin" }; - adjacency_list <> g(N); - add_edge(Jeanie, Debbie, g); - add_edge(Jeanie, Rick, g); - add_edge(Jeanie, John, g); - add_edge(Debbie, Amanda, g); - add_edge(Rick, Margaret, g); - add_edge(John, Benjamin, g); + adjacency_list<> g(N); + add_edge(Jeanie, Debbie, g); + add_edge(Jeanie, Rick, g); + add_edge(Jeanie, John, g); + add_edge(Debbie, Amanda, g); + add_edge(Rick, Margaret, g); + add_edge(John, Benjamin, g); - graph_traits < adjacency_list <> >::vertex_iterator i, end; - graph_traits < adjacency_list <> >::adjacency_iterator ai, a_end; - property_map < adjacency_list <>, vertex_index_t >::type - index_map = get(vertex_index, g); + graph_traits< adjacency_list<> >::vertex_iterator i, end; + graph_traits< adjacency_list<> >::adjacency_iterator ai, a_end; + property_map< adjacency_list<>, vertex_index_t >::type index_map + = get(vertex_index, g); - for (boost::tie(i, end) = vertices(g); i != end; ++i) { - std::cout << name[get(index_map, *i)]; - boost::tie(ai, a_end) = adjacent_vertices(*i, g); - if (ai == a_end) - std::cout << " has no children"; - else - std::cout << " is the parent of "; - for (; ai != a_end; ++ai) { - std::cout << name[get(index_map, *ai)]; - if (boost::next(ai) != a_end) - std::cout << ", "; + for (boost::tie(i, end) = vertices(g); i != end; ++i) + { + std::cout << name[get(index_map, *i)]; + boost::tie(ai, a_end) = adjacent_vertices(*i, g); + if (ai == a_end) + std::cout << " has no children"; + else + std::cout << " is the parent of "; + for (; ai != a_end; ++ai) + { + std::cout << name[get(index_map, *ai)]; + if (boost::next(ai) != a_end) + std::cout << ", "; + } + std::cout << std::endl; } - std::cout << std::endl; - } - return EXIT_SUCCESS; + return EXIT_SUCCESS; } diff --git a/example/family_tree.expected b/example/family_tree.expected index b3e6d61a7..b9afc3f43 100644 --- a/example/family_tree.expected +++ b/example/family_tree.expected @@ -1,7 +1,7 @@ -Jeanie is the parent of Debbie Rick John -Debbie is the parent of Amanda -Rick is the parent of Margaret -John is the parent of Benjamin +Jeanie is the parent of Debbie Rick John +Debbie is the parent of Amanda +Rick is the parent of Margaret +John is the parent of Benjamin Amanda has no children Margaret has no children Benjamin has no children diff --git a/example/fibonacci_heap.cpp b/example/fibonacci_heap.cpp index 6fa76d028..ffa42ab51 100644 --- a/example/fibonacci_heap.cpp +++ b/example/fibonacci_heap.cpp @@ -24,57 +24,63 @@ namespace random_ns = boost; using namespace boost; -int -main() +int main() { - typedef indirect_cmp > ICmp; - int i; - random_ns::mt19937 gen; - for (int N = 2; N < 200; ++N) { - uniform_int<> distrib(0, N-1); - boost::variate_generator > rand_gen(gen, distrib); - for (int t = 0; t < 10; ++t) { - std::vector v, w(N); + typedef indirect_cmp< float*, std::less< float > > ICmp; + int i; + random_ns::mt19937 gen; + for (int N = 2; N < 200; ++N) + { + uniform_int<> distrib(0, N - 1); + boost::variate_generator< random_ns::mt19937&, uniform_int<> > rand_gen( + gen, distrib); + for (int t = 0; t < 10; ++t) + { + std::vector< float > v, w(N); - ICmp cmp(&w[0], std::less()); - fibonacci_heap Q(N, cmp); + ICmp cmp(&w[0], std::less< float >()); + fibonacci_heap< int, ICmp > Q(N, cmp); - for (int c = 0; c < w.size(); ++c) - w[c] = c; + for (int c = 0; c < w.size(); ++c) + w[c] = c; #ifndef BOOST_NO_CXX98_RANDOM_SHUFFLE - std::random_shuffle(w.begin(), w.end()); + std::random_shuffle(w.begin(), w.end()); #else - std::shuffle(w.begin(), w.end(), gen); + std::shuffle(w.begin(), w.end(), gen); #endif - for (i = 0; i < N; ++i) - Q.push(i); + for (i = 0; i < N; ++i) + Q.push(i); - for (i = 0; i < N; ++i) { - int u = rand_gen(); - float r = rand_gen(); r /= 2.0; - w[u] = w[u] - r; - Q.update(u); - } + for (i = 0; i < N; ++i) + { + int u = rand_gen(); + float r = rand_gen(); + r /= 2.0; + w[u] = w[u] - r; + Q.update(u); + } - for (i = 0; i < N; ++i) { - v.push_back(w[Q.top()]); - Q.pop(); - } - std::sort(w.begin(), w.end()); + for (i = 0; i < N; ++i) + { + v.push_back(w[Q.top()]); + Q.pop(); + } + std::sort(w.begin(), w.end()); - if (! std::equal(v.begin(), v.end(), w.begin())) { - std::cout << std::endl << "heap sorted: "; - std::copy(v.begin(), v.end(), - std::ostream_iterator(std::cout," ")); - std::cout << std::endl << "correct: "; - std::copy(w.begin(), w.end(), - std::ostream_iterator(std::cout," ")); - std::cout << std::endl; - return -1; - } + if (!std::equal(v.begin(), v.end(), w.begin())) + { + std::cout << std::endl << "heap sorted: "; + std::copy(v.begin(), v.end(), + std::ostream_iterator< float >(std::cout, " ")); + std::cout << std::endl << "correct: "; + std::copy(w.begin(), w.end(), + std::ostream_iterator< float >(std::cout, " ")); + std::cout << std::endl; + return -1; + } + } } - } - std::cout << "fibonacci heap passed test" << std::endl; - return 0; + std::cout << "fibonacci heap passed test" << std::endl; + return 0; } diff --git a/example/figs/ospf-graph.dot b/example/figs/ospf-graph.dot index d4fcee7ad..c29637bae 100644 --- a/example/figs/ospf-graph.dot +++ b/example/figs/ospf-graph.dot @@ -32,17 +32,17 @@ digraph G { N15 H1 - RT1 -> N1[label="3"] - RT1 -> N3[label="1"] + RT1 -> N1[label="3"] + RT1 -> N3[label="1"] - RT2 -> N2[label="3"] - RT2 -> N3[label="1"] + RT2 -> N2[label="3"] + RT2 -> N3[label="1"] RT3 -> RT6[label="8"] - RT3 -> N3[label="1"] - RT3 -> N4[label="2"] + RT3 -> N3[label="1"] + RT3 -> N4[label="2"] - RT4 -> N3[label="1"] + RT4 -> N3[label="1"] RT4 -> RT5[label="8"] RT5 -> RT4[label="8"] @@ -57,14 +57,14 @@ digraph G { RT6 -> RT10[label="7"] RT7 -> RT5[label="6"] - RT7 -> N6[label="1"] + RT7 -> N6[label="1"] RT7 -> N12[label="2"] RT7 -> N15[label="9"] - RT8 -> N6[label="1"] - RT8 -> N7[label="4"] + RT8 -> N6[label="1"] + RT8 -> N7[label="4"] - RT9 -> N9[label="1"] + RT9 -> N9[label="1"] RT9 -> N11[label="3"] RT10 -> RT6[label="5"] @@ -84,13 +84,13 @@ digraph G { N3 -> RT4[label="0"] N6 -> RT7[label="0"] - N6 -> RT8[label="0"] - N6 -> RT10[label="0"] + N6 -> RT8[label="0"] + N6 -> RT10[label="0"] - N8 -> RT10[label="0"] - N8 -> RT11[label="0"] + N8 -> RT10[label="0"] + N8 -> RT11[label="0"] N9 -> RT9[label="0"] - N9 -> RT11[label="0"] - N9 -> RT12[label="0"] + N9 -> RT11[label="0"] + N9 -> RT12[label="0"] } diff --git a/example/figs/scc.dot b/example/figs/scc.dot index 66d0fc844..7cf6736bf 100644 --- a/example/figs/scc.dot +++ b/example/figs/scc.dot @@ -16,9 +16,9 @@ digraph SCC { "www.boost.org" -> "www.yahoogroups.com" "www.boost.org" -> "sourceforge.net" "www.boost.org" -> "anubis.dkuug.dk" - "www.yahoogroups.com" -> "weather.yahoo.com" + "www.yahoogroups.com" -> "weather.yahoo.com" "www.yahoogroups.com" -> "www.boost.org" - "weather.yahoo.com" -> "nytimes.com" + "weather.yahoo.com" -> "nytimes.com" "weather.yahoo.com" -> "www.yahoogroups.com" "nytimes.com" -> "www.boston.com" "www.boston.com" -> "nytimes.com" diff --git a/example/figs/telephone-network.dot b/example/figs/telephone-network.dot index 4187d5127..382ac7fa4 100644 --- a/example/figs/telephone-network.dot +++ b/example/figs/telephone-network.dot @@ -31,12 +31,12 @@ graph G { Kearny -- Novar[label="8", weight="11"] Novar -- Huntsville[label="5", weight="5"] Huntsville -- Bracebridge[label="30", weight="30"] - Huntsville -- "Bent River"[label="30", weight="30"] - Rosseau -- "Bent River"[label="8", weight="8"] - Rosseau -- "Horseshoe Lake"[label="8", weight="8"] - Mactier -- "Horseshoe Lake"[label="14", weight="14"] - "Parry Sound" -- "Horseshoe Lake"[label="10", weight="10"] - "Parry Sound" -- Dunchurch[label="20", weight="20"] - Mactier -- "Glen Orchard"[label="9", weight="9"] - "Glen Orchard" -- Bracebridge[label="15", weight="15"] + Huntsville -- "Bent River"[label="30", weight="30"] + Rosseau -- "Bent River"[label="8", weight="8"] + Rosseau -- "Horseshoe Lake"[label="8", weight="8"] + Mactier -- "Horseshoe Lake"[label="14", weight="14"] + "Parry Sound" -- "Horseshoe Lake"[label="10", weight="10"] + "Parry Sound" -- Dunchurch[label="20", weight="20"] + Mactier -- "Glen Orchard"[label="9", weight="9"] + "Glen Orchard" -- Bracebridge[label="15", weight="15"] } diff --git a/example/file_dependencies.cpp b/example/file_dependencies.cpp index 9bce73342..d4344b98f 100644 --- a/example/file_dependencies.cpp +++ b/example/file_dependencies.cpp @@ -44,146 +44,155 @@ using namespace std; using namespace boost; -enum files_e { dax_h, yow_h, boz_h, zow_h, foo_cpp, - foo_o, bar_cpp, bar_o, libfoobar_a, - zig_cpp, zig_o, zag_cpp, zag_o, - libzigzag_a, killerapp, N }; -const char* name[] = { "dax.h", "yow.h", "boz.h", "zow.h", "foo.cpp", - "foo.o", "bar.cpp", "bar.o", "libfoobar.a", - "zig.cpp", "zig.o", "zag.cpp", "zag.o", - "libzigzag.a", "killerapp" }; - - -struct print_visitor : public bfs_visitor<> { - template - void discover_vertex(Vertex v, Graph&) { - cout << name[v] << " "; - } +enum files_e +{ + dax_h, + yow_h, + boz_h, + zow_h, + foo_cpp, + foo_o, + bar_cpp, + bar_o, + libfoobar_a, + zig_cpp, + zig_o, + zag_cpp, + zag_o, + libzigzag_a, + killerapp, + N }; +const char* name[] = { "dax.h", "yow.h", "boz.h", "zow.h", "foo.cpp", "foo.o", + "bar.cpp", "bar.o", "libfoobar.a", "zig.cpp", "zig.o", "zag.cpp", "zag.o", + "libzigzag.a", "killerapp" }; +struct print_visitor : public bfs_visitor<> +{ + template < class Vertex, class Graph > + void discover_vertex(Vertex v, Graph&) + { + cout << name[v] << " "; + } +}; struct cycle_detector : public dfs_visitor<> { - cycle_detector(bool& has_cycle) - : m_has_cycle(has_cycle) { } + cycle_detector(bool& has_cycle) : m_has_cycle(has_cycle) {} + + template < class Edge, class Graph > void back_edge(Edge, Graph&) + { + m_has_cycle = true; + } - template - void back_edge(Edge, Graph&) { m_has_cycle = true; } protected: - bool& m_has_cycle; + bool& m_has_cycle; }; - - - -int main(int,char*[]) +int main(int, char*[]) { - typedef pair Edge; - Edge used_by[] = { - Edge(dax_h, foo_cpp), Edge(dax_h, bar_cpp), Edge(dax_h, yow_h), - Edge(yow_h, bar_cpp), Edge(yow_h, zag_cpp), - Edge(boz_h, bar_cpp), Edge(boz_h, zig_cpp), Edge(boz_h, zag_cpp), - Edge(zow_h, foo_cpp), - Edge(foo_cpp, foo_o), - Edge(foo_o, libfoobar_a), - Edge(bar_cpp, bar_o), - Edge(bar_o, libfoobar_a), - Edge(libfoobar_a, libzigzag_a), - Edge(zig_cpp, zig_o), - Edge(zig_o, libzigzag_a), - Edge(zag_cpp, zag_o), - Edge(zag_o, libzigzag_a), - Edge(libzigzag_a, killerapp) - }; - const std::size_t nedges = sizeof(used_by)/sizeof(Edge); - - typedef adjacency_list Graph; + typedef pair< int, int > Edge; + Edge used_by[] = { Edge(dax_h, foo_cpp), Edge(dax_h, bar_cpp), + Edge(dax_h, yow_h), Edge(yow_h, bar_cpp), Edge(yow_h, zag_cpp), + Edge(boz_h, bar_cpp), Edge(boz_h, zig_cpp), Edge(boz_h, zag_cpp), + Edge(zow_h, foo_cpp), Edge(foo_cpp, foo_o), Edge(foo_o, libfoobar_a), + Edge(bar_cpp, bar_o), Edge(bar_o, libfoobar_a), + Edge(libfoobar_a, libzigzag_a), Edge(zig_cpp, zig_o), + Edge(zig_o, libzigzag_a), Edge(zag_cpp, zag_o), + Edge(zag_o, libzigzag_a), Edge(libzigzag_a, killerapp) }; + const std::size_t nedges = sizeof(used_by) / sizeof(Edge); + + typedef adjacency_list< vecS, vecS, bidirectionalS > Graph; #if defined(BOOST_MSVC) && BOOST_MSVC <= 1300 - // VC++ can't handle the iterator constructor - Graph g(N); - for (std::size_t j = 0; j < nedges; ++j) { - graph_traits::edge_descriptor e; bool inserted; - boost::tie(e, inserted) = add_edge(used_by[j].first, used_by[j].second, g); - } + // VC++ can't handle the iterator constructor + Graph g(N); + for (std::size_t j = 0; j < nedges; ++j) + { + graph_traits< Graph >::edge_descriptor e; + bool inserted; + boost::tie(e, inserted) + = add_edge(used_by[j].first, used_by[j].second, g); + } #else - Graph g(used_by, used_by + nedges, N); + Graph g(used_by, used_by + nedges, N); #endif - typedef graph_traits::vertex_descriptor Vertex; - - // Determine ordering for a full recompilation - // and the order with files that can be compiled in parallel - { - typedef list MakeOrder; - MakeOrder::iterator i; - MakeOrder make_order; - - topological_sort(g, std::front_inserter(make_order)); - cout << "make ordering: "; - for (i = make_order.begin(); - i != make_order.end(); ++i) - cout << name[*i] << " "; - - cout << endl << endl; - - // Parallel compilation ordering - std::vector time(N, 0); - for (i = make_order.begin(); i != make_order.end(); ++i) { - // Walk through the in_edges an calculate the maximum time. - if (in_degree (*i, g) > 0) { - Graph::in_edge_iterator j, j_end; - int maxdist=0; - // Through the order from topological sort, we are sure that every - // time we are using here is already initialized. - for (boost::tie(j, j_end) = in_edges(*i, g); j != j_end; ++j) - maxdist=(std::max)(time[source(*j, g)], maxdist); - time[*i]=maxdist+1; - } + typedef graph_traits< Graph >::vertex_descriptor Vertex; + + // Determine ordering for a full recompilation + // and the order with files that can be compiled in parallel + { + typedef list< Vertex > MakeOrder; + MakeOrder::iterator i; + MakeOrder make_order; + + topological_sort(g, std::front_inserter(make_order)); + cout << "make ordering: "; + for (i = make_order.begin(); i != make_order.end(); ++i) + cout << name[*i] << " "; + + cout << endl << endl; + + // Parallel compilation ordering + std::vector< int > time(N, 0); + for (i = make_order.begin(); i != make_order.end(); ++i) + { + // Walk through the in_edges an calculate the maximum time. + if (in_degree(*i, g) > 0) + { + Graph::in_edge_iterator j, j_end; + int maxdist = 0; + // Through the order from topological sort, we are sure that + // every time we are using here is already initialized. + for (boost::tie(j, j_end) = in_edges(*i, g); j != j_end; ++j) + maxdist = (std::max)(time[source(*j, g)], maxdist); + time[*i] = maxdist + 1; + } + } + + cout << "parallel make ordering, " << endl + << "vertices with same group number can be made in parallel" + << endl; + { + graph_traits< Graph >::vertex_iterator i, iend; + for (boost::tie(i, iend) = vertices(g); i != iend; ++i) + cout << "time_slot[" << name[*i] << "] = " << time[*i] << endl; + } } + cout << endl; - cout << "parallel make ordering, " << endl - << "vertices with same group number can be made in parallel" << endl; + // if I change yow.h what files need to be re-made? { - graph_traits::vertex_iterator i, iend; - for (boost::tie(i,iend) = vertices(g); i != iend; ++i) - cout << "time_slot[" << name[*i] << "] = " << time[*i] << endl; + cout << "A change to yow.h will cause what to be re-made?" << endl; + print_visitor vis; + breadth_first_search(g, vertex(yow_h, g), visitor(vis)); + cout << endl; } + cout << endl; - } - cout << endl; + // are there any cycles in the graph? + { + bool has_cycle = false; + cycle_detector vis(has_cycle); + depth_first_search(g, visitor(vis)); + cout << "The graph has a cycle? " << has_cycle << endl; + } + cout << endl; - // if I change yow.h what files need to be re-made? - { - cout << "A change to yow.h will cause what to be re-made?" << endl; - print_visitor vis; - breadth_first_search(g, vertex(yow_h, g), visitor(vis)); + // add a dependency going from bar.cpp to dax.h + { + cout << "adding edge bar_cpp -> dax_h" << endl; + add_edge(bar_cpp, dax_h, g); + } cout << endl; - } - cout << endl; - - // are there any cycles in the graph? - { - bool has_cycle = false; - cycle_detector vis(has_cycle); - depth_first_search(g, visitor(vis)); - cout << "The graph has a cycle? " << has_cycle << endl; - } - cout << endl; - - // add a dependency going from bar.cpp to dax.h - { - cout << "adding edge bar_cpp -> dax_h" << endl; - add_edge(bar_cpp, dax_h, g); - } - cout << endl; - - // are there any cycles in the graph? - { - bool has_cycle = false; - cycle_detector vis(has_cycle); - depth_first_search(g, visitor(vis)); - cout << "The graph has a cycle now? " << has_cycle << endl; - } - - return 0; + + // are there any cycles in the graph? + { + bool has_cycle = false; + cycle_detector vis(has_cycle); + depth_first_search(g, visitor(vis)); + cout << "The graph has a cycle now? " << has_cycle << endl; + } + + return 0; } diff --git a/example/file_dependencies.expected b/example/file_dependencies.expected index 9f004a7ac..ddc9c0be7 100644 --- a/example/file_dependencies.expected +++ b/example/file_dependencies.expected @@ -1,6 +1,6 @@ -make ordering: zow.h boz.h zig.cpp zig.o dax.h yow.h zag.cpp zag.o bar.cpp bar.o foo.cpp foo.o libfoobar.a libzigzag.a killerapp +make ordering: zow.h boz.h zig.cpp zig.o dax.h yow.h zag.cpp zag.o bar.cpp bar.o foo.cpp foo.o libfoobar.a libzigzag.a killerapp -parallel make ordering, +parallel make ordering, vertices with same group number can be made in parallel time_slot[dax.h] = 0 time_slot[yow.h] = 1 @@ -19,7 +19,7 @@ time_slot[libzigzag.a] = 5 time_slot[killerapp] = 6 A change to yow.h will cause what to be re-made? -yow.h bar.cpp zag.cpp bar.o zag.o libfoobar.a libzigzag.a killerapp +yow.h bar.cpp zag.cpp bar.o zag.o libfoobar.a libzigzag.a killerapp The graph has a cycle? 0 diff --git a/example/filtered-copy-example.cpp b/example/filtered-copy-example.cpp index 226dfd29e..7cd7002c9 100644 --- a/example/filtered-copy-example.cpp +++ b/example/filtered-copy-example.cpp @@ -1,5 +1,5 @@ //======================================================================= -// Copyright 2001 Jeremy G. Siek, Andrew Lumsdaine, Lie-Quan Lee, +// Copyright 2001 Jeremy G. Siek, Andrew Lumsdaine, Lie-Quan Lee, // // Distributed under the Boost Software License, Version 1.0. (See // accompanying file LICENSE_1_0.txt or copy at @@ -12,52 +12,63 @@ #include #include -template -struct non_zero_degree { - non_zero_degree() { } // has to have a default constructor! +template < typename Graph > struct non_zero_degree +{ + non_zero_degree() {} // has to have a default constructor! - non_zero_degree(const Graph& g) : g(&g) { } + non_zero_degree(const Graph& g) : g(&g) {} - bool operator()(typename boost::graph_traits::vertex_descriptor v) const - { - return degree(v, *g) != 0; - } - const Graph* g; + bool operator()( + typename boost::graph_traits< Graph >::vertex_descriptor v) const + { + return degree(v, *g) != 0; + } + const Graph* g; }; -int -main() +int main() { - using namespace boost; - typedef adjacency_list < vecS, vecS, bidirectionalS, - property < vertex_name_t, char > > graph_t; - - enum { a, b, c, d, e, f, g, N }; - graph_t G(N); - property_map < graph_t, vertex_name_t >::type - name_map = get(vertex_name, G); - char name = 'a'; - graph_traits < graph_t >::vertex_iterator v, v_end; - for (boost::tie(v, v_end) = vertices(G); v != v_end; ++v, ++name) - name_map[*v] = name; - - typedef std::pair < int, int >E; - E edges[] = { E(a, c), E(a, d), E(b, a), E(b, d), E(c, f), - E(d, c), E(d, e), E(d, f), E(e, b), E(e, g), E(f, e), E(f, g) - }; - for (int i = 0; i < 12; ++i) - add_edge(edges[i].first, edges[i].second, G); - - print_graph(G, name_map); - std::cout << std::endl; - - clear_vertex(b, G); - clear_vertex(d, G); - - graph_t G_copy; - copy_graph(make_filtered_graph(G, keep_all(), non_zero_degree(G)), G_copy); - - print_graph(G_copy, get(vertex_name, G_copy)); - - return 0; + using namespace boost; + typedef adjacency_list< vecS, vecS, bidirectionalS, + property< vertex_name_t, char > > + graph_t; + + enum + { + a, + b, + c, + d, + e, + f, + g, + N + }; + graph_t G(N); + property_map< graph_t, vertex_name_t >::type name_map = get(vertex_name, G); + char name = 'a'; + graph_traits< graph_t >::vertex_iterator v, v_end; + for (boost::tie(v, v_end) = vertices(G); v != v_end; ++v, ++name) + name_map[*v] = name; + + typedef std::pair< int, int > E; + E edges[] = { E(a, c), E(a, d), E(b, a), E(b, d), E(c, f), E(d, c), E(d, e), + E(d, f), E(e, b), E(e, g), E(f, e), E(f, g) }; + for (int i = 0; i < 12; ++i) + add_edge(edges[i].first, edges[i].second, G); + + print_graph(G, name_map); + std::cout << std::endl; + + clear_vertex(b, G); + clear_vertex(d, G); + + graph_t G_copy; + copy_graph( + make_filtered_graph(G, keep_all(), non_zero_degree< graph_t >(G)), + G_copy); + + print_graph(G_copy, get(vertex_name, G_copy)); + + return 0; } diff --git a/example/filtered_graph.cpp b/example/filtered_graph.cpp index e325b5f83..9a89718c9 100644 --- a/example/filtered_graph.cpp +++ b/example/filtered_graph.cpp @@ -7,16 +7,16 @@ // http://www.boost.org/LICENSE_1_0.txt) //======================================================================= -/* +/* Sample output: - filtered edge set: (A,B) (C,D) (D,B) + filtered edge set: (A,B) (C,D) (D,B) filtered out-edges: - A --> B - B --> - C --> D - D --> B - E --> + A --> B + B --> + C --> D + D --> B + E --> */ #include @@ -25,45 +25,53 @@ #include #include -template -struct positive_edge_weight { - positive_edge_weight() { } - positive_edge_weight(EdgeWeightMap weight) : m_weight(weight) { } - template - bool operator()(const Edge& e) const { - return 0 < boost::get(m_weight, e); - } - EdgeWeightMap m_weight; +template < typename EdgeWeightMap > struct positive_edge_weight +{ + positive_edge_weight() {} + positive_edge_weight(EdgeWeightMap weight) : m_weight(weight) {} + template < typename Edge > bool operator()(const Edge& e) const + { + return 0 < boost::get(m_weight, e); + } + EdgeWeightMap m_weight; }; - int main() { - using namespace boost; - - typedef adjacency_list > Graph; - typedef property_map::type EdgeWeightMap; + using namespace boost; + + typedef adjacency_list< vecS, vecS, directedS, no_property, + property< edge_weight_t, int > > + Graph; + typedef property_map< Graph, edge_weight_t >::type EdgeWeightMap; + + enum + { + A, + B, + C, + D, + E, + N + }; + const char* name = "ABCDE"; + Graph g(N); + add_edge(A, B, 2, g); + add_edge(A, C, 0, g); + add_edge(C, D, 1, g); + add_edge(C, E, 0, g); + add_edge(D, B, 3, g); + add_edge(E, C, 0, g); + + positive_edge_weight< EdgeWeightMap > filter(get(edge_weight, g)); + filtered_graph< Graph, positive_edge_weight< EdgeWeightMap > > fg( + g, filter); - enum { A, B, C, D, E, N }; - const char* name = "ABCDE"; - Graph g(N); - add_edge(A, B, 2, g); - add_edge(A, C, 0, g); - add_edge(C, D, 1, g); - add_edge(C, E, 0, g); - add_edge(D, B, 3, g); - add_edge(E, C, 0, g); - - positive_edge_weight filter(get(edge_weight, g)); - filtered_graph > - fg(g, filter); + std::cout << "filtered edge set: "; + print_edges(fg, name); - std::cout << "filtered edge set: "; - print_edges(fg, name); + std::cout << "filtered out-edges:" << std::endl; + print_graph(fg, name); - std::cout << "filtered out-edges:" << std::endl; - print_graph(fg, name); - - return 0; + return 0; } diff --git a/example/filtered_graph.expected b/example/filtered_graph.expected index d2a8e504a..9960b96a3 100644 --- a/example/filtered_graph.expected +++ b/example/filtered_graph.expected @@ -1,7 +1,7 @@ -filtered edge set: (A,B) (C,D) (D,B) +filtered edge set: (A,B) (C,D) (D,B) filtered out-edges: -A --> B -B --> -C --> D -D --> B -E --> +A --> B +B --> +C --> D +D --> B +E --> diff --git a/example/filtered_graph_edge_range.cpp b/example/filtered_graph_edge_range.cpp index eb140f642..ed6b653d7 100644 --- a/example/filtered_graph_edge_range.cpp +++ b/example/filtered_graph_edge_range.cpp @@ -7,16 +7,16 @@ // http://www.boost.org/LICENSE_1_0.txt) //======================================================================= -/* +/* Sample output: - filtered edge set: (A,B) (C,D) (D,B) + filtered edge set: (A,B) (C,D) (D,B) filtered out-edges: - A --> B - B --> - C --> D - D --> B - E --> + A --> B + B --> + C --> D + D --> B + E --> */ #include @@ -25,55 +25,64 @@ #include #include -template -struct positive_edge_weight { - positive_edge_weight() { } - positive_edge_weight(EdgeWeightMap weight) : m_weight(weight) { } - template - bool operator()(const Edge& e) const { - return 0 < boost::get(m_weight, e); - } - EdgeWeightMap m_weight; +template < typename EdgeWeightMap > struct positive_edge_weight +{ + positive_edge_weight() {} + positive_edge_weight(EdgeWeightMap weight) : m_weight(weight) {} + template < typename Edge > bool operator()(const Edge& e) const + { + return 0 < boost::get(m_weight, e); + } + EdgeWeightMap m_weight; }; - int main() { - using namespace boost; - - typedef adjacency_list > Graph; - typedef property_map::type EdgeWeightMap; + using namespace boost; + + typedef adjacency_list< multisetS, vecS, directedS, no_property, + property< edge_weight_t, int > > + Graph; + typedef property_map< Graph, edge_weight_t >::type EdgeWeightMap; + + enum + { + A, + B, + C, + D, + E, + N + }; + const char* name = "ABCDE"; + Graph g(N); + add_edge(A, B, 2, g); + add_edge(A, C, 0, g); + add_edge(C, D, 1, g); + add_edge(C, D, 0, g); + add_edge(C, D, 3, g); + add_edge(C, E, 0, g); + add_edge(D, B, 3, g); + add_edge(E, C, 0, g); - enum { A, B, C, D, E, N }; - const char* name = "ABCDE"; - Graph g(N); - add_edge(A, B, 2, g); - add_edge(A, C, 0, g); - add_edge(C, D, 1, g); - add_edge(C, D, 0, g); - add_edge(C, D, 3, g); - add_edge(C, E, 0, g); - add_edge(D, B, 3, g); - add_edge(E, C, 0, g); + EdgeWeightMap weight = get(edge_weight, g); - EdgeWeightMap weight = get(edge_weight, g); + std::cout << "unfiltered edge_range(C,D)\n"; + graph_traits< Graph >::out_edge_iterator f, l; + for (boost::tie(f, l) = edge_range(C, D, g); f != l; ++f) + std::cout << name[source(*f, g)] << " --" << weight[*f] << "-> " + << name[target(*f, g)] << "\n"; - std::cout << "unfiltered edge_range(C,D)\n"; - graph_traits::out_edge_iterator f, l; - for (boost::tie(f, l) = edge_range(C, D, g); f != l; ++f) - std::cout << name[source(*f, g)] << " --" << weight[*f] - << "-> " << name[target(*f, g)] << "\n"; + positive_edge_weight< EdgeWeightMap > filter(weight); + typedef filtered_graph< Graph, positive_edge_weight< EdgeWeightMap > > + FGraph; + FGraph fg(g, filter); - positive_edge_weight filter(weight); - typedef filtered_graph > FGraph; - FGraph fg(g, filter); + std::cout << "filtered edge_range(C,D)\n"; + graph_traits< FGraph >::out_edge_iterator first, last; + for (boost::tie(first, last) = edge_range(C, D, fg); first != last; ++first) + std::cout << name[source(*first, fg)] << " --" << weight[*first] + << "-> " << name[target(*first, fg)] << "\n"; - std::cout << "filtered edge_range(C,D)\n"; - graph_traits::out_edge_iterator first, last; - for (boost::tie(first, last) = edge_range(C, D, fg); first != last; ++first) - std::cout << name[source(*first, fg)] << " --" << weight[*first] - << "-> " << name[target(*first, fg)] << "\n"; - - return 0; + return 0; } diff --git a/example/filtered_vec_as_graph.cpp b/example/filtered_vec_as_graph.cpp index 2d976a0ef..2ec53a226 100644 --- a/example/filtered_vec_as_graph.cpp +++ b/example/filtered_vec_as_graph.cpp @@ -7,15 +7,15 @@ // http://www.boost.org/LICENSE_1_0.txt) //======================================================================= -/* +/* Sample output: filtered out-edges: - A --> - B --> - C --> E - D --> E - E --> + A --> + B --> + C --> E + D --> E + E --> */ #include @@ -24,36 +24,45 @@ #include #include -struct constant_target { - constant_target() { } - constant_target(int t) : target(t) { } - bool operator()(const std::pair& e) const { - return e.second == target; - } - int target; +struct constant_target +{ + constant_target() {} + constant_target(int t) : target(t) {} + bool operator()(const std::pair< int, int >& e) const + { + return e.second == target; + } + int target; }; - int main() { - using namespace boost; - - enum { A, B, C, D, E, N }; - const char* name = "ABCDE"; - typedef std::vector < std::list < int > > Graph; - Graph g(N); - g[A].push_back(B); - g[A].push_back(C); - g[C].push_back(D); - g[C].push_back(E); - g[D].push_back(E); - g[E].push_back(C); - - constant_target filter(E); - filtered_graph fg(g, filter); - - std::cout << "filtered out-edges:" << std::endl; - print_graph(fg, name); - - return 0; + using namespace boost; + + enum + { + A, + B, + C, + D, + E, + N + }; + const char* name = "ABCDE"; + typedef std::vector< std::list< int > > Graph; + Graph g(N); + g[A].push_back(B); + g[A].push_back(C); + g[C].push_back(D); + g[C].push_back(E); + g[D].push_back(E); + g[E].push_back(C); + + constant_target filter(E); + filtered_graph< Graph, constant_target > fg(g, filter); + + std::cout << "filtered out-edges:" << std::endl; + print_graph(fg, name); + + return 0; } diff --git a/example/fr_layout.cpp b/example/fr_layout.cpp index 2f7e4feae..bc545719d 100644 --- a/example/fr_layout.cpp +++ b/example/fr_layout.cpp @@ -23,114 +23,136 @@ using namespace boost; void usage() { - std::cerr << "Usage: fr_layout [options] \n" - << "Arguments:\n" - << "\t\tWidth of the display area (floating point)\n" - << "\t\tHeight of the display area (floating point)\n\n" - << "Options:\n" - << "\t--iterations n\tNumber of iterations to execute.\n" - << "\t\t\tThe default value is 100.\n" - << "Input:\n" - << " Input is read from standard input as a list of edges, one per line.\n" - << " Each edge contains two string labels (the endpoints) separated by a space.\n\n" - << "Output:\n" - << " Vertices and their positions are written to standard output with the label,\n x-position, and y-position of a vertex on each line, separated by spaces.\n"; + std::cerr << "Usage: fr_layout [options] \n" + << "Arguments:\n" + << "\t\tWidth of the display area (floating point)\n" + << "\t\tHeight of the display area (floating point)\n\n" + << "Options:\n" + << "\t--iterations n\tNumber of iterations to execute.\n" + << "\t\t\tThe default value is 100.\n" + << "Input:\n" + << " Input is read from standard input as a list of edges, one " + "per line.\n" + << " Each edge contains two string labels (the endpoints) " + "separated by a space.\n\n" + << "Output:\n" + << " Vertices and their positions are written to standard " + "output with the label,\n x-position, and y-position of a " + "vertex on each line, separated by spaces.\n"; } typedef boost::rectangle_topology<> topology_type; typedef topology_type::point_type point_type; -typedef adjacency_list > Graph; +typedef adjacency_list< listS, vecS, undirectedS, + property< vertex_name_t, std::string > > + Graph; -typedef graph_traits::vertex_descriptor Vertex; +typedef graph_traits< Graph >::vertex_descriptor Vertex; -typedef std::map NameToVertex; +typedef std::map< std::string, Vertex > NameToVertex; Vertex get_vertex(const std::string& name, Graph& g, NameToVertex& names) { - NameToVertex::iterator i = names.find(name); - if (i == names.end()) - i = names.insert(std::make_pair(name, add_vertex(name, g))).first; - return i->second; + NameToVertex::iterator i = names.find(name); + if (i == names.end()) + i = names.insert(std::make_pair(name, add_vertex(name, g))).first; + return i->second; } -class progress_cooling : public linear_cooling +class progress_cooling : public linear_cooling< double > { - typedef linear_cooling inherited; - - public: - explicit progress_cooling(std::size_t iterations) : inherited(iterations) - { - display.reset(new progress_display(iterations + 1, std::cerr)); - } - - double operator()() - { - ++(*display); - return inherited::operator()(); - } - - private: - shared_ptr display; + typedef linear_cooling< double > inherited; + +public: + explicit progress_cooling(std::size_t iterations) : inherited(iterations) + { + display.reset(new progress_display(iterations + 1, std::cerr)); + } + + double operator()() + { + ++(*display); + return inherited::operator()(); + } + +private: + shared_ptr< boost::progress_display > display; }; int main(int argc, char* argv[]) { - int iterations = 100; - - if (argc < 3) { usage(); return -1; } - - double width = 0; - double height = 0; - - for (int arg_idx = 1; arg_idx < argc; ++arg_idx) { - std::string arg = argv[arg_idx]; - if (arg == "--iterations") { - ++arg_idx; - if (arg_idx >= argc) { usage(); return -1; } - iterations = lexical_cast(argv[arg_idx]); - } else { - if (width == 0.0) width = lexical_cast(arg); - else if (height == 0.0) height = lexical_cast(arg); - else { + int iterations = 100; + + if (argc < 3) + { usage(); return -1; - } } - } - - if (width == 0.0 || height == 0.0) { - usage(); - return -1; - } - - Graph g; - NameToVertex names; - - std::string source, target; - while (std::cin >> source >> target) { - add_edge(get_vertex(source, g, names), get_vertex(target, g, names), g); - } - - typedef std::vector PositionVec; - PositionVec position_vec(num_vertices(g)); - typedef iterator_property_map::type> - PositionMap; - PositionMap position(position_vec.begin(), get(vertex_index, g)); - - minstd_rand gen; - topology_type topo(gen, -width/2, -height/2, width/2, height/2); - random_graph_layout(g, position, topo); - fruchterman_reingold_force_directed_layout - (g, position, topo, - cooling(progress_cooling(iterations))); - - graph_traits::vertex_iterator vi, vi_end; - for (boost::tie(vi, vi_end) = vertices(g); vi != vi_end; ++vi) { - std::cout << get(vertex_name, g, *vi) << '\t' - << position[*vi][0] << '\t' << position[*vi][1] << std::endl; - } - return 0; + + double width = 0; + double height = 0; + + for (int arg_idx = 1; arg_idx < argc; ++arg_idx) + { + std::string arg = argv[arg_idx]; + if (arg == "--iterations") + { + ++arg_idx; + if (arg_idx >= argc) + { + usage(); + return -1; + } + iterations = lexical_cast< int >(argv[arg_idx]); + } + else + { + if (width == 0.0) + width = lexical_cast< double >(arg); + else if (height == 0.0) + height = lexical_cast< double >(arg); + else + { + usage(); + return -1; + } + } + } + + if (width == 0.0 || height == 0.0) + { + usage(); + return -1; + } + + Graph g; + NameToVertex names; + + std::string source, target; + while (std::cin >> source >> target) + { + add_edge(get_vertex(source, g, names), get_vertex(target, g, names), g); + } + + typedef std::vector< point_type > PositionVec; + PositionVec position_vec(num_vertices(g)); + typedef iterator_property_map< PositionVec::iterator, + property_map< Graph, vertex_index_t >::type > + PositionMap; + PositionMap position(position_vec.begin(), get(vertex_index, g)); + + minstd_rand gen; + topology_type topo(gen, -width / 2, -height / 2, width / 2, height / 2); + random_graph_layout(g, position, topo); + fruchterman_reingold_force_directed_layout( + g, position, topo, cooling(progress_cooling(iterations))); + + graph_traits< Graph >::vertex_iterator vi, vi_end; + for (boost::tie(vi, vi_end) = vertices(g); vi != vi_end; ++vi) + { + std::cout << get(vertex_name, g, *vi) << '\t' << position[*vi][0] + << '\t' << position[*vi][1] << std::endl; + } + return 0; } diff --git a/example/gerdemann.cpp b/example/gerdemann.cpp index c90964590..09804f7c5 100644 --- a/example/gerdemann.cpp +++ b/example/gerdemann.cpp @@ -20,133 +20,145 @@ /* Sample output: - 0 --c--> 1 --j--> 1 --c--> 2 --x--> 2 - 1 --c--> 2 --d--> 3 - 2 --t--> 4 - 3 --h--> 4 - 4 + 0 --c--> 1 --j--> 1 --c--> 2 --x--> 2 + 1 --c--> 2 --d--> 3 + 2 --t--> 4 + 3 --h--> 4 + 4 merging vertex 1 into vertex 0 - 0 --c--> 0 --j--> 0 --c--> 1 --x--> 1 --d--> 2 - 1 --t--> 3 - 2 --h--> 3 - 3 + 0 --c--> 0 --j--> 0 --c--> 1 --x--> 1 --d--> 2 + 1 --t--> 3 + 2 --h--> 3 + 3 */ // merge_vertex(u,v,g): // incoming/outgoing edges for v become incoming/outgoing edges for u // v is deleted -template -void merge_vertex - (typename boost::graph_traits::vertex_descriptor u, - typename boost::graph_traits::vertex_descriptor v, - Graph& g, GetEdgeProperties getp) +template < class Graph, class GetEdgeProperties > +void merge_vertex(typename boost::graph_traits< Graph >::vertex_descriptor u, + typename boost::graph_traits< Graph >::vertex_descriptor v, Graph& g, + GetEdgeProperties getp) { - typedef boost::graph_traits Traits; - typename Traits::edge_descriptor e; - typename Traits::out_edge_iterator out_i, out_end; - for (boost::tie(out_i, out_end) = out_edges(v, g); out_i != out_end; ++out_i) { - e = *out_i; - typename Traits::vertex_descriptor targ = target(e, g); - add_edge(u, targ, getp(e), g); - } - typename Traits::in_edge_iterator in_i, in_end; - for (boost::tie(in_i, in_end) = in_edges(v, g); in_i != in_end; ++in_i) { - e = *in_i; - typename Traits::vertex_descriptor src = source(e, g); - add_edge(src, u, getp(e), g); - } - clear_vertex(v, g); - remove_vertex(v, g); + typedef boost::graph_traits< Graph > Traits; + typename Traits::edge_descriptor e; + typename Traits::out_edge_iterator out_i, out_end; + for (boost::tie(out_i, out_end) = out_edges(v, g); out_i != out_end; + ++out_i) + { + e = *out_i; + typename Traits::vertex_descriptor targ = target(e, g); + add_edge(u, targ, getp(e), g); + } + typename Traits::in_edge_iterator in_i, in_end; + for (boost::tie(in_i, in_end) = in_edges(v, g); in_i != in_end; ++in_i) + { + e = *in_i; + typename Traits::vertex_descriptor src = source(e, g); + add_edge(src, u, getp(e), g); + } + clear_vertex(v, g); + remove_vertex(v, g); } -template -struct order_by_name +template < class StoredEdge > struct order_by_name +{ + typedef StoredEdge first_argument_type; + typedef StoredEdge second_argument_type; + typedef bool result_type; + bool operator()(const StoredEdge& e1, const StoredEdge& e2) const + { + // Using std::pair operator< as an easy way to get lexicographical + // compare over tuples. + return std::make_pair(e1.get_target(), boost::get(boost::edge_name, e1)) + < std::make_pair(e2.get_target(), boost::get(boost::edge_name, e2)); + } +}; +struct ordered_set_by_nameS { - typedef StoredEdge first_argument_type; - typedef StoredEdge second_argument_type; - typedef bool result_type; - bool operator()(const StoredEdge& e1, const StoredEdge& e2) const { - // Using std::pair operator< as an easy way to get lexicographical - // compare over tuples. - return std::make_pair(e1.get_target(), boost::get(boost::edge_name, e1)) - < std::make_pair(e2.get_target(), boost::get(boost::edge_name, e2)); - } }; -struct ordered_set_by_nameS { }; #ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION -namespace boost { - template - struct container_gen { - typedef std::set > type; - }; - template <> - struct parallel_edge_traits { +namespace boost +{ +template < class ValueType > +struct container_gen< ordered_set_by_nameS, ValueType > +{ + typedef std::set< ValueType, order_by_name< ValueType > > type; +}; +template <> struct parallel_edge_traits< ordered_set_by_nameS > +{ typedef allow_parallel_edge_tag type; - }; +}; } #endif -template -struct get_edge_name { - get_edge_name(const Graph& g_) : g(g_) { } - - template - boost::property operator()(Edge e) const { - return boost::property(boost::get(boost::edge_name, g, e)); - } - const Graph& g; +template < class Graph > struct get_edge_name +{ + get_edge_name(const Graph& g_) : g(g_) {} + + template < class Edge > + boost::property< boost::edge_name_t, char > operator()(Edge e) const + { + return boost::property< boost::edge_name_t, char >( + boost::get(boost::edge_name, g, e)); + } + const Graph& g; }; -int -main() +int main() { #ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION - std::cout << "This program requires partial specialization." << std::endl; + std::cout << "This program requires partial specialization." << std::endl; #else - using namespace boost; - typedef property EdgeProperty; - typedef adjacency_list graph_type; - - graph_type g; - - add_edge(0, 1, EdgeProperty('j'), g); - add_edge(0, 2, EdgeProperty('c'), g); - add_edge(0, 2, EdgeProperty('x'), g); - add_edge(1, 3, EdgeProperty('d'), g); - add_edge(1, 2, EdgeProperty('c'), g); - add_edge(1, 3, EdgeProperty('d'), g); - add_edge(2, 4, EdgeProperty('t'), g); - add_edge(3, 4, EdgeProperty('h'), g); - add_edge(0, 1, EdgeProperty('c'), g); - - property_map::type id = get(vertex_index, g); - property_map::type name = get(edge_name, g); - - graph_traits::vertex_iterator i, end; - graph_traits::out_edge_iterator ei, edge_end; - - for (boost::tie(i, end) = vertices(g); i != end; ++i) { - std::cout << id[*i] << " "; - for (boost::tie(ei, edge_end) = out_edges(*i, g); ei != edge_end; ++ei) - std::cout << " --" << name[*ei] << "--> " << id[target(*ei, g)] << " "; + using namespace boost; + typedef property< edge_name_t, char > EdgeProperty; + typedef adjacency_list< ordered_set_by_nameS, vecS, bidirectionalS, + no_property, EdgeProperty > + graph_type; + + graph_type g; + + add_edge(0, 1, EdgeProperty('j'), g); + add_edge(0, 2, EdgeProperty('c'), g); + add_edge(0, 2, EdgeProperty('x'), g); + add_edge(1, 3, EdgeProperty('d'), g); + add_edge(1, 2, EdgeProperty('c'), g); + add_edge(1, 3, EdgeProperty('d'), g); + add_edge(2, 4, EdgeProperty('t'), g); + add_edge(3, 4, EdgeProperty('h'), g); + add_edge(0, 1, EdgeProperty('c'), g); + + property_map< graph_type, vertex_index_t >::type id = get(vertex_index, g); + property_map< graph_type, edge_name_t >::type name = get(edge_name, g); + + graph_traits< graph_type >::vertex_iterator i, end; + graph_traits< graph_type >::out_edge_iterator ei, edge_end; + + for (boost::tie(i, end) = vertices(g); i != end; ++i) + { + std::cout << id[*i] << " "; + for (boost::tie(ei, edge_end) = out_edges(*i, g); ei != edge_end; ++ei) + std::cout << " --" << name[*ei] << "--> " << id[target(*ei, g)] + << " "; + std::cout << std::endl; + } std::cout << std::endl; - } - std::cout << std::endl; - - std::cout << "merging vertex 1 into vertex 0" << std::endl << std::endl; - merge_vertex(0, 1, g, get_edge_name(g)); - - for (boost::tie(i, end) = vertices(g); i != end; ++i) { - std::cout << id[*i] << " "; - for (boost::tie(ei, edge_end) = out_edges(*i, g); ei != edge_end; ++ei) - std::cout << " --" << name[*ei] << "--> " << id[target(*ei, g)] << " "; + + std::cout << "merging vertex 1 into vertex 0" << std::endl << std::endl; + merge_vertex(0, 1, g, get_edge_name< graph_type >(g)); + + for (boost::tie(i, end) = vertices(g); i != end; ++i) + { + std::cout << id[*i] << " "; + for (boost::tie(ei, edge_end) = out_edges(*i, g); ei != edge_end; ++ei) + std::cout << " --" << name[*ei] << "--> " << id[target(*ei, g)] + << " "; + std::cout << std::endl; + } std::cout << std::endl; - } - std::cout << std::endl; -#endif - return 0; +#endif + return 0; } diff --git a/example/gerdemann.expected b/example/gerdemann.expected index bc5bdda65..bb63e9f25 100644 --- a/example/gerdemann.expected +++ b/example/gerdemann.expected @@ -1,13 +1,13 @@ -0 --c--> 1 --j--> 1 --c--> 2 --x--> 2 -1 --c--> 2 --d--> 3 -2 --t--> 4 -3 --h--> 4 -4 +0 --c--> 1 --j--> 1 --c--> 2 --x--> 2 +1 --c--> 2 --d--> 3 +2 --t--> 4 +3 --h--> 4 +4 merging vertex 1 into vertex 0 -0 --c--> 0 --j--> 0 --c--> 1 --x--> 1 --d--> 2 -1 --t--> 3 -2 --h--> 3 -3 +0 --c--> 0 --j--> 0 --c--> 1 --x--> 1 --d--> 2 +1 --t--> 3 +2 --h--> 3 +3 diff --git a/example/girth.cpp b/example/girth.cpp index 9c9cc23cc..3df89b01b 100644 --- a/example/girth.cpp +++ b/example/girth.cpp @@ -37,7 +37,7 @@ 3 vertices at distance 14, 1 vertices at distance 15. So the diameter is 15, and the girth is 9. - + */ #include @@ -49,112 +49,114 @@ #include #include -typedef boost::graph_traits Traits; +typedef boost::graph_traits< Graph* > Traits; typedef Traits::vertex_descriptor vertex_descriptor; typedef Traits::edge_descriptor edge_descriptor; typedef Traits::vertex_iterator vertex_iterator; -std::vector distance_list; +std::vector< std::size_t > distance_list; -typedef boost::v_property dist_t; -boost::property_map::type d_map; +typedef boost::v_property< long > dist_t; +boost::property_map< Graph*, dist_t >::type d_map; -typedef boost::u_property pred_t; -boost::property_map::type p_map; +typedef boost::u_property< vertex_descriptor > pred_t; +boost::property_map< Graph*, pred_t >::type p_map; -typedef boost::w_property color_t; -boost::property_map::type c_map; +typedef boost::w_property< long > color_t; +boost::property_map< Graph*, color_t >::type c_map; class diameter_and_girth_visitor : public boost::bfs_visitor<> { public: - diameter_and_girth_visitor(std::size_t& k_, std::size_t& girth_) - : k(k_), girth(girth_) { } - - void tree_edge(edge_descriptor e, Graph* g) { - vertex_descriptor u = source(e, g), v = target(e, g); - k = d_map[u] + 1; - d_map[v] = k; - ++distance_list[k]; - p_map[v] = u; - } - void non_tree_edge(edge_descriptor e, Graph* g) { - vertex_descriptor u = source(e, g), v = target(e, g); - k = d_map[u] + 1; - if (d_map[v] + k < girth && v != p_map[u]) - girth = d_map[v]+ k; - } -private: - std::size_t& k; - std::size_t& girth; -}; - - -int -main() -{ - std::cout << - "This program explores the girth and diameter of Ramanujan graphs." - << std::endl; - std::cout << - "The bipartite graphs have q^3-q vertices, and the non-bipartite" - << std::endl; - std::cout << - "graphs have half that number. Each vertex has degree p+1." - << std::endl; - std::cout << "Both p and q should be odd prime numbers;" << std::endl; - std::cout << " or you can try p = 2 with q = 17 or 43." << std::endl; - - while (1) { - - std::cout << std::endl - << "Choose a branching factor, p: "; - long p = 0, q = 0; - std::cin >> p; - if (p == 0) - break; - std::cout << "Ok, now choose the cube root of graph size, q: "; - std::cin >> q; - if (q == 0) - break; - - Graph* g; - g = raman(p, q, 0L, 0L); - if (g == 0) { - std::cerr << " Sorry, I couldn't make that graph (error code " - << panic_code << ")" << std::endl; - continue; + diameter_and_girth_visitor(std::size_t& k_, std::size_t& girth_) + : k(k_), girth(girth_) + { } - distance_list.clear(); - distance_list.resize(boost::num_vertices(g), 0); - - // obtain property maps - d_map = get(dist_t(), g); - p_map = get(pred_t(), g); - c_map = get(color_t(), g); - - vertex_iterator i, end; - for (boost::tie(i, end) = boost::vertices(g); i != end; ++i) - d_map[*i] = 0; - - std::size_t k = 0; - std::size_t girth = (std::numeric_limits::max)(); - diameter_and_girth_visitor vis(k, girth); - vertex_descriptor s = *boost::vertices(g).first; - - boost::breadth_first_search(g, s, visitor(vis).color_map(c_map)); - - std::cout << "Starting at any given vertex, there are" << std::endl; - - for (long d = 1; distance_list[d] != 0; ++d) - std::cout << distance_list[d] << " vertices at distance " << d - << (distance_list[d+1] != 0 ? "," : ".") << std::endl; + void tree_edge(edge_descriptor e, Graph* g) + { + vertex_descriptor u = source(e, g), v = target(e, g); + k = d_map[u] + 1; + d_map[v] = k; + ++distance_list[k]; + p_map[v] = u; + } + void non_tree_edge(edge_descriptor e, Graph* g) + { + vertex_descriptor u = source(e, g), v = target(e, g); + k = d_map[u] + 1; + if (d_map[v] + k < girth && v != p_map[u]) + girth = d_map[v] + k; + } - std::cout << "So the diameter is " << k - 1 - << ", and the girth is " << girth - << "." << std::endl; - } // end while +private: + std::size_t& k; + std::size_t& girth; +}; - return 0; +int main() +{ + std::cout + << "This program explores the girth and diameter of Ramanujan graphs." + << std::endl; + std::cout + << "The bipartite graphs have q^3-q vertices, and the non-bipartite" + << std::endl; + std::cout << "graphs have half that number. Each vertex has degree p+1." + << std::endl; + std::cout << "Both p and q should be odd prime numbers;" << std::endl; + std::cout << " or you can try p = 2 with q = 17 or 43." << std::endl; + + while (1) + { + + std::cout << std::endl << "Choose a branching factor, p: "; + long p = 0, q = 0; + std::cin >> p; + if (p == 0) + break; + std::cout << "Ok, now choose the cube root of graph size, q: "; + std::cin >> q; + if (q == 0) + break; + + Graph* g; + g = raman(p, q, 0L, 0L); + if (g == 0) + { + std::cerr << " Sorry, I couldn't make that graph (error code " + << panic_code << ")" << std::endl; + continue; + } + distance_list.clear(); + distance_list.resize(boost::num_vertices(g), 0); + + // obtain property maps + d_map = get(dist_t(), g); + p_map = get(pred_t(), g); + c_map = get(color_t(), g); + + vertex_iterator i, end; + for (boost::tie(i, end) = boost::vertices(g); i != end; ++i) + d_map[*i] = 0; + + std::size_t k = 0; + std::size_t girth = (std::numeric_limits< std::size_t >::max)(); + diameter_and_girth_visitor vis(k, girth); + + vertex_descriptor s = *boost::vertices(g).first; + + boost::breadth_first_search(g, s, visitor(vis).color_map(c_map)); + + std::cout << "Starting at any given vertex, there are" << std::endl; + + for (long d = 1; distance_list[d] != 0; ++d) + std::cout << distance_list[d] << " vertices at distance " << d + << (distance_list[d + 1] != 0 ? "," : ".") << std::endl; + + std::cout << "So the diameter is " << k - 1 << ", and the girth is " + << girth << "." << std::endl; + } // end while + + return 0; } diff --git a/example/graph-assoc-types.cpp b/example/graph-assoc-types.cpp index aedeebcad..5af9a8cc4 100644 --- a/example/graph-assoc-types.cpp +++ b/example/graph-assoc-types.cpp @@ -1,5 +1,5 @@ //======================================================================= -// Copyright 2001 Jeremy G. Siek, Andrew Lumsdaine, Lie-Quan Lee, +// Copyright 2001 Jeremy G. Siek, Andrew Lumsdaine, Lie-Quan Lee, // // Distributed under the Boost Software License, Version 1.0. (See // accompanying file LICENSE_1_0.txt or copy at @@ -10,95 +10,89 @@ using namespace boost; -template < typename Graph > void -generic_foo(Graph & g) +template < typename Graph > void generic_foo(Graph& g) { - // Access descriptor types - typedef typename graph_traits < Graph >::vertex_descriptor Vertex; - typedef typename graph_traits < Graph >::edge_descriptor Edge; - // Access category types - typedef typename graph_traits < Graph >::directed_category Dir; - typedef typename graph_traits < Graph >::edge_parallel_category Par; - // Access iterator types... - // Access size types... - // Now do something useful... + // Access descriptor types + typedef typename graph_traits< Graph >::vertex_descriptor Vertex; + typedef typename graph_traits< Graph >::edge_descriptor Edge; + // Access category types + typedef typename graph_traits< Graph >::directed_category Dir; + typedef typename graph_traits< Graph >::edge_parallel_category Par; + // Access iterator types... + // Access size types... + // Now do something useful... } -template < typename Graph > void -generic_bar(Graph & g) +template < typename Graph > void generic_bar(Graph& g) { - // Declare some vertex and edge descriptor variables - typename graph_traits < Graph >::vertex_descriptor u = vertex(0,g), v = vertex(1,g); - typename graph_traits < Graph >::edge_descriptor e1, e2; - // Set u and e1 to valid descriptors... - v = u; // Make v a handle to the same vertex as u. - e2 = e1; // Make e2 a handle to the same edge as e1. - assert(u == v); // Do u and v identify the same vertex? Yes - assert(!(u != v)); // Do u and v identify different vertices? No - assert(e1 == e2); // Do e1 and e2 identify the same edge? Yes - assert(!(e1 != e2)); // Do e1 and e2 identify different edges? No + // Declare some vertex and edge descriptor variables + typename graph_traits< Graph >::vertex_descriptor u = vertex(0, g), + v = vertex(1, g); + typename graph_traits< Graph >::edge_descriptor e1, e2; + // Set u and e1 to valid descriptors... + v = u; // Make v a handle to the same vertex as u. + e2 = e1; // Make e2 a handle to the same edge as e1. + assert(u == v); // Do u and v identify the same vertex? Yes + assert(!(u != v)); // Do u and v identify different vertices? No + assert(e1 == e2); // Do e1 and e2 identify the same edge? Yes + assert(!(e1 != e2)); // Do e1 and e2 identify different edges? No } // This version of foo gets called when g is directed -template < typename Graph > void -foo_dispatch(Graph & g, boost::directed_tag) +template < typename Graph > void foo_dispatch(Graph& g, boost::directed_tag) { - //... + //... } // This version of foo gets called when g is undirected -template < typename Graph > void -foo_dispatch(Graph & g, boost::undirected_tag) +template < typename Graph > void foo_dispatch(Graph& g, boost::undirected_tag) { - //... + //... } -template < typename Graph > void -foo(Graph & g) +template < typename Graph > void foo(Graph& g) { - typedef typename boost::graph_traits < Graph >::directed_category Cat; - foo_dispatch(g, Cat()); + typedef typename boost::graph_traits< Graph >::directed_category Cat; + foo_dispatch(g, Cat()); } -template < typename Digraph > void -foo(Digraph & digraph, - typename graph_traits < Digraph >::vertex_descriptor u, - typename graph_traits < Digraph >::vertex_descriptor v) +template < typename Digraph > +void foo(Digraph& digraph, + typename graph_traits< Digraph >::vertex_descriptor u, + typename graph_traits< Digraph >::vertex_descriptor v) { - typedef typename graph_traits < Digraph >::edge_descriptor edge_t; - std::pair e1, e2; - e1 = edge(u, v, digraph); - e2 = edge(v, u, digraph); - assert(e1.first != e2.first); + typedef typename graph_traits< Digraph >::edge_descriptor edge_t; + std::pair< edge_t, bool > e1, e2; + e1 = edge(u, v, digraph); + e2 = edge(v, u, digraph); + assert(e1.first != e2.first); } -template < typename Undigraph > void -bar(Undigraph & undigraph, - typename graph_traits < Undigraph >::vertex_descriptor u, - typename graph_traits < Undigraph >::vertex_descriptor v) +template < typename Undigraph > +void bar(Undigraph& undigraph, + typename graph_traits< Undigraph >::vertex_descriptor u, + typename graph_traits< Undigraph >::vertex_descriptor v) { - typedef typename graph_traits < Undigraph >::edge_descriptor edge_t; - std::pair e1, e2; - e1 = edge(u, v, undigraph); - e2 = edge(v, u, undigraph); - assert(e1.first == e2.first); + typedef typename graph_traits< Undigraph >::edge_descriptor edge_t; + std::pair< edge_t, bool > e1, e2; + e1 = edge(u, v, undigraph); + e2 = edge(v, u, undigraph); + assert(e1.first == e2.first); } - -int -main() +int main() { - boost::adjacency_list < vecS, vecS, directedS > g(2); - add_edge(0, 1, g); - add_edge(1, 0, g); - generic_foo(g); - generic_bar(g); - foo(g); - foo(g, vertex(0, g), vertex(1, g)); + boost::adjacency_list< vecS, vecS, directedS > g(2); + add_edge(0, 1, g); + add_edge(1, 0, g); + generic_foo(g); + generic_bar(g); + foo(g); + foo(g, vertex(0, g), vertex(1, g)); - boost::adjacency_list < vecS, vecS, undirectedS > ug(2); - add_edge(0, 1, g); - bar(ug, vertex(0, g), vertex(1, g)); + boost::adjacency_list< vecS, vecS, undirectedS > ug(2); + add_edge(0, 1, g); + bar(ug, vertex(0, g), vertex(1, g)); - return 0; + return 0; } diff --git a/example/graph-property-iter-eg.cpp b/example/graph-property-iter-eg.cpp index 0c11914a4..27ac96d45 100644 --- a/example/graph-property-iter-eg.cpp +++ b/example/graph-property-iter-eg.cpp @@ -1,5 +1,5 @@ //======================================================================= -// Copyright 2001 Jeremy G. Siek, Andrew Lumsdaine, Lie-Quan Lee, +// Copyright 2001 Jeremy G. Siek, Andrew Lumsdaine, Lie-Quan Lee, // // Distributed under the Boost Software License, Version 1.0. (See // accompanying file LICENSE_1_0.txt or copy at @@ -12,23 +12,23 @@ #include #include -int -main() +int main() { - using namespace boost; - typedef adjacency_list < listS, vecS, directedS, - property < vertex_name_t, std::string > >graph_t; - graph_t g(3); + using namespace boost; + typedef adjacency_list< listS, vecS, directedS, + property< vertex_name_t, std::string > > + graph_t; + graph_t g(3); - const char *vertex_names[] = { "Kubrick", "Clark", "Hal" }; - int i = 0; - graph_property_iter_range < graph_t, vertex_name_t >::iterator v, v_end; - for (boost::tie(v, v_end) = get_property_iter_range(g, vertex_name); - v != v_end; ++v, ++i) - *v = vertex_names[i]; + const char* vertex_names[] = { "Kubrick", "Clark", "Hal" }; + int i = 0; + graph_property_iter_range< graph_t, vertex_name_t >::iterator v, v_end; + for (boost::tie(v, v_end) = get_property_iter_range(g, vertex_name); + v != v_end; ++v, ++i) + *v = vertex_names[i]; - boost::tie(v, v_end) = get_property_iter_range(g, vertex_name); - std::copy(v, v_end, std::ostream_iterator < std::string > (std::cout, " ")); - std::cout << std::endl; - return 0; + boost::tie(v, v_end) = get_property_iter_range(g, vertex_name); + std::copy(v, v_end, std::ostream_iterator< std::string >(std::cout, " ")); + std::cout << std::endl; + return 0; } diff --git a/example/graph-thingie.cpp b/example/graph-thingie.cpp index 6b8031dd8..bf0d02fcf 100644 --- a/example/graph-thingie.cpp +++ b/example/graph-thingie.cpp @@ -9,8 +9,6 @@ // Author: Ronald Garcia - - #include #include #include @@ -20,61 +18,64 @@ using namespace boost; using namespace std; - // // Create a custom graph properties // (see the documentation for adjacency list) -struct graph_identifier_t { typedef graph_property_tag kind; }; -struct vertex_label_t { typedef vertex_property_tag kind; }; - -int main() { - - // Vertex properties - typedef property < vertex_name_t, string, - property < vertex_label_t, string, - property < vertex_root_t, int > > > vertex_p; - // Edge properties - typedef property < edge_name_t, string > edge_p; - // Graph properties - typedef property < graph_name_t, string, - property < graph_identifier_t, string > > graph_p; - // adjacency_list-based type - typedef adjacency_list < vecS, vecS, directedS, - vertex_p, edge_p, graph_p > graph_t; - - // Construct an empty graph and prepare the dynamic_property_maps. - graph_t graph(0); - dynamic_properties dp; - - property_map::type vname = - get(vertex_name, graph); - dp.property("node_id",vname); - - property_map::type vlabel = - get(vertex_label_t(), graph); - dp.property("label",vlabel); - - property_map::type root = - get(vertex_root, graph); - dp.property("root",root); - - property_map::type elabel = - get(edge_name, graph); - dp.property("label",elabel); - - // Use ref_property_map to turn a graph property into a property map - ref_property_map - gname(get_property(graph,graph_name)); - dp.property("name",gname); - - // Use ref_property_map to turn a graph property into a property map - ref_property_map - gid(get_property(graph,graph_identifier_t())); - dp.property("identifier",gid); - // Sample graph as an istream; - -const char* dot = -"digraph \ +struct graph_identifier_t +{ + typedef graph_property_tag kind; +}; +struct vertex_label_t +{ + typedef vertex_property_tag kind; +}; + +int main() +{ + + // Vertex properties + typedef property< vertex_name_t, string, + property< vertex_label_t, string, property< vertex_root_t, int > > > + vertex_p; + // Edge properties + typedef property< edge_name_t, string > edge_p; + // Graph properties + typedef property< graph_name_t, string, + property< graph_identifier_t, string > > + graph_p; + // adjacency_list-based type + typedef adjacency_list< vecS, vecS, directedS, vertex_p, edge_p, graph_p > + graph_t; + + // Construct an empty graph and prepare the dynamic_property_maps. + graph_t graph(0); + dynamic_properties dp; + + property_map< graph_t, vertex_name_t >::type vname + = get(vertex_name, graph); + dp.property("node_id", vname); + + property_map< graph_t, vertex_label_t >::type vlabel + = get(vertex_label_t(), graph); + dp.property("label", vlabel); + + property_map< graph_t, vertex_root_t >::type root = get(vertex_root, graph); + dp.property("root", root); + + property_map< graph_t, edge_name_t >::type elabel = get(edge_name, graph); + dp.property("label", elabel); + + // Use ref_property_map to turn a graph property into a property map + ref_property_map< graph_t*, string > gname(get_property(graph, graph_name)); + dp.property("name", gname); + + // Use ref_property_map to turn a graph property into a property map + ref_property_map< graph_t*, string > gid( + get_property(graph, graph_identifier_t())); + dp.property("identifier", gid); + // Sample graph as an istream; + + const char* dot = "digraph \ { \ graph [name=\"GRAPH\", identifier=\"CX2A1Z\"] \ \ @@ -85,22 +86,23 @@ const char* dot = b -> c [label=\"EDGE_2\"] \ }"; + istringstream gvgraph(dot); - istringstream gvgraph(dot); - - bool status = read_graphviz(gvgraph,graph,dp,"node_id"); - if (!status) { - cerr << "read_graphviz() failed." << endl; - return -1; - } + bool status = read_graphviz(gvgraph, graph, dp, "node_id"); + if (!status) + { + cerr << "read_graphviz() failed." << endl; + return -1; + } - cout << "graph " << get("name",dp,&graph) << - " (" << get("identifier",dp,&graph) << ")\n\n"; + cout << "graph " << get("name", dp, &graph) << " (" + << get("identifier", dp, &graph) << ")\n\n"; - BOOST_FOREACH( graph_t::vertex_descriptor v, vertices(graph) ) { - cout << "vertex " << get("node_id",dp,v) << - " (" << get("label",dp,v) << ")\n"; - } + BOOST_FOREACH (graph_t::vertex_descriptor v, vertices(graph)) + { + cout << "vertex " << get("node_id", dp, v) << " (" + << get("label", dp, v) << ")\n"; + } - return 0; + return 0; } diff --git a/example/graph.cpp b/example/graph.cpp index c73fba7b0..ee2de06c6 100644 --- a/example/graph.cpp +++ b/example/graph.cpp @@ -17,138 +17,149 @@ using namespace boost; using namespace std; -typedef property > > > > VertexProperty; -typedef property EdgeProperty; -typedef adjacency_list Graph; - -template -void print(Graph& g) { - typename Graph::vertex_iterator i, end; - typename Graph::out_edge_iterator ei, edge_end; - for(boost::tie(i,end) = vertices(g); i != end; ++i) { - cout << *i << " --> "; - for (boost::tie(ei,edge_end) = out_edges(*i, g); ei != edge_end; ++ei) - cout << target(*ei, g) << " "; - cout << endl; - } +typedef property< vertex_color_t, default_color_type, + property< vertex_distance_t, int, + property< vertex_degree_t, int, + property< vertex_in_degree_t, int, + property< vertex_out_degree_t, int > > > > > + VertexProperty; +typedef property< edge_weight_t, int > EdgeProperty; +typedef adjacency_list< vecS, vecS, bidirectionalS, VertexProperty, + EdgeProperty > + Graph; + +template < class Graph > void print(Graph& g) +{ + typename Graph::vertex_iterator i, end; + typename Graph::out_edge_iterator ei, edge_end; + for (boost::tie(i, end) = vertices(g); i != end; ++i) + { + cout << *i << " --> "; + for (boost::tie(ei, edge_end) = out_edges(*i, g); ei != edge_end; ++ei) + cout << target(*ei, g) << " "; + cout << endl; + } } -std::size_t myrand(std::size_t N) { - std::size_t ret = rand() % N; - // cout << "N = " << N << " rand = " << ret << endl; - return ret; +std::size_t myrand(std::size_t N) +{ + std::size_t ret = rand() % N; + // cout << "N = " << N << " rand = " << ret << endl; + return ret; } -template -bool check_edge(Graph& g, std::size_t a, std::size_t b) { - typename Graph::adjacency_iterator vi, viend, found; - boost::tie(vi, viend) = adjacent_vertices(vertex(a,g), g); +template < class Graph > bool check_edge(Graph& g, std::size_t a, std::size_t b) +{ + typename Graph::adjacency_iterator vi, viend, found; + boost::tie(vi, viend) = adjacent_vertices(vertex(a, g), g); - found = find(vi, viend, vertex(b, g)); - if ( found == viend ) - return false; + found = find(vi, viend, vertex(b, g)); + if (found == viend) + return false; - return true; + return true; } int main(int, char*[]) { - std::size_t N = 5; - - Graph g(N); - int i; - - bool is_failed = false; - - for (i=0; i<6; ++i) { - std::size_t a = myrand(N), b = myrand(N); - while ( a == b ) b = myrand(N); - cout << "edge edge (" << a << "," << b <<")" << endl; - //add edges - add_edge(a, b, g); - is_failed = is_failed || (! check_edge(g, a, b) ); - } - - if ( is_failed ) - cerr << " Failed."<< endl; - else - cerr << " Passed."<< endl; - - print(g); - - //remove_edge - for (i = 0; i<2; ++i) { - std::size_t a = myrand(N), b = myrand(N); - while ( a == b ) b = myrand(N); - cout << "remove edge (" << a << "," << b <<")" << endl; - remove_edge(a, b, g); - is_failed = is_failed || check_edge(g, a, b); - } - if ( is_failed ) - cerr << " Failed."<< endl; - else - cerr << " Passed."<< endl; - - print(g); - - //add_vertex - is_failed = false; - std::size_t old_N = N; - std::size_t vid = add_vertex(g); - std::size_t vidp1 = add_vertex(g); - - N = num_vertices(g); - if ( (N - 2) != old_N ) - cerr << " Failed."<< endl; - else - cerr << " Passed."<< endl; - - is_failed = false; - for (i=0; i<2; ++i) { - std::size_t a = myrand(N), b = myrand(N); - while ( a == vid ) a = myrand(N); - while ( b == vidp1 ) b = myrand(N); - cout << "add edge (" << vid << "," << a <<")" << endl; - cout << "add edge (" << vid << "," << vidp1 <<")" << endl; - add_edge(vid, a, g); - add_edge(b, vidp1, g); - is_failed = is_failed || ! check_edge(g, vid, a); - is_failed = is_failed || ! check_edge(g, b, vidp1); - } - if ( is_failed ) - cerr << " Failed."<< endl; - else - cerr << " Passed."<< endl; - print(g); - - // clear_vertex - std::size_t c = myrand(N); - is_failed = false; - clear_vertex(c, g); - - if ( out_degree(c, g) != 0 ) - is_failed = true; - - cout << "Removing vertex " << c << endl; - remove_vertex(c, g); - - old_N = N; - N = num_vertices(g); - - if ( (N + 1) != old_N ) - is_failed = true; - - if ( is_failed ) - cerr << " Failed."<< endl; - else - cerr << " Passed."<< endl; - - print(g); - - return 0; + std::size_t N = 5; + + Graph g(N); + int i; + + bool is_failed = false; + + for (i = 0; i < 6; ++i) + { + std::size_t a = myrand(N), b = myrand(N); + while (a == b) + b = myrand(N); + cout << "edge edge (" << a << "," << b << ")" << endl; + // add edges + add_edge(a, b, g); + is_failed = is_failed || (!check_edge(g, a, b)); + } + + if (is_failed) + cerr << " Failed." << endl; + else + cerr << " Passed." << endl; + + print(g); + + // remove_edge + for (i = 0; i < 2; ++i) + { + std::size_t a = myrand(N), b = myrand(N); + while (a == b) + b = myrand(N); + cout << "remove edge (" << a << "," << b << ")" << endl; + remove_edge(a, b, g); + is_failed = is_failed || check_edge(g, a, b); + } + if (is_failed) + cerr << " Failed." << endl; + else + cerr << " Passed." << endl; + + print(g); + + // add_vertex + is_failed = false; + std::size_t old_N = N; + std::size_t vid = add_vertex(g); + std::size_t vidp1 = add_vertex(g); + + N = num_vertices(g); + if ((N - 2) != old_N) + cerr << " Failed." << endl; + else + cerr << " Passed." << endl; + + is_failed = false; + for (i = 0; i < 2; ++i) + { + std::size_t a = myrand(N), b = myrand(N); + while (a == vid) + a = myrand(N); + while (b == vidp1) + b = myrand(N); + cout << "add edge (" << vid << "," << a << ")" << endl; + cout << "add edge (" << vid << "," << vidp1 << ")" << endl; + add_edge(vid, a, g); + add_edge(b, vidp1, g); + is_failed = is_failed || !check_edge(g, vid, a); + is_failed = is_failed || !check_edge(g, b, vidp1); + } + if (is_failed) + cerr << " Failed." << endl; + else + cerr << " Passed." << endl; + print(g); + + // clear_vertex + std::size_t c = myrand(N); + is_failed = false; + clear_vertex(c, g); + + if (out_degree(c, g) != 0) + is_failed = true; + + cout << "Removing vertex " << c << endl; + remove_vertex(c, g); + + old_N = N; + N = num_vertices(g); + + if ((N + 1) != old_N) + is_failed = true; + + if (is_failed) + cerr << " Failed." << endl; + else + cerr << " Passed." << endl; + + print(g); + + return 0; } diff --git a/example/graph_as_tree.cpp b/example/graph_as_tree.cpp index 635cd179b..29058a384 100644 --- a/example/graph_as_tree.cpp +++ b/example/graph_as_tree.cpp @@ -12,55 +12,54 @@ #include #include -class tree_printer { +class tree_printer +{ public: - template - void preorder(Node, Tree&) { - std::cout << "("; - } - template - void inorder(Node n, Tree& t) - { - std::cout << get(boost::vertex_name, t)[n]; - } - template - void postorder(Node, Tree&) { - std::cout << ")"; - } - + template < typename Node, typename Tree > void preorder(Node, Tree&) + { + std::cout << "("; + } + template < typename Node, typename Tree > void inorder(Node n, Tree& t) + { + std::cout << get(boost::vertex_name, t)[n]; + } + template < typename Node, typename Tree > void postorder(Node, Tree&) + { + std::cout << ")"; + } }; int main() { - using namespace boost; - typedef adjacency_list > graph_t; - typedef graph_traits::vertex_descriptor vertex_t; + using namespace boost; + typedef adjacency_list< vecS, vecS, directedS, + property< vertex_name_t, std::string > > + graph_t; + typedef graph_traits< graph_t >::vertex_descriptor vertex_t; + + graph_t g; + + vertex_t a = add_vertex(g), b = add_vertex(g), c = add_vertex(g); - graph_t g; + add_edge(a, b, g); + add_edge(a, c, g); - vertex_t a = add_vertex(g), - b = add_vertex(g), - c = add_vertex(g); + typedef property_map< graph_t, vertex_name_t >::type vertex_name_map_t; + vertex_name_map_t name = get(vertex_name, g); + name[a] = "A"; + name[b] = "B"; + name[c] = "C"; - add_edge(a, b, g); - add_edge(a, c, g); - - typedef property_map::type vertex_name_map_t; - vertex_name_map_t name = get(vertex_name, g); - name[a] = "A"; - name[b] = "B"; - name[c] = "C"; + typedef iterator_property_map< std::vector< vertex_t >::iterator, + property_map< graph_t, vertex_index_t >::type > + parent_map_t; + std::vector< vertex_t > parent(num_vertices(g)); + typedef graph_as_tree< graph_t, parent_map_t > tree_t; + tree_t t( + g, a, make_iterator_property_map(parent.begin(), get(vertex_index, g))); - typedef iterator_property_map::iterator, - property_map::type> parent_map_t; - std::vector parent(num_vertices(g)); - typedef graph_as_tree tree_t; - tree_t t(g, a, make_iterator_property_map(parent.begin(), - get(vertex_index, g))); + tree_printer vis; + traverse_tree(a, t, vis); - tree_printer vis; - traverse_tree(a, t, vis); - - return exit_success; + return exit_success; } diff --git a/example/graph_property.cpp b/example/graph_property.cpp index ceb71c47f..eec0ed2f1 100644 --- a/example/graph_property.cpp +++ b/example/graph_property.cpp @@ -1,4 +1,4 @@ -// (C) Copyright Jeremy Siek 2004 +// (C) Copyright Jeremy Siek 2004 // Distributed under the Boost Software License, Version 1.0. (See // accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) @@ -9,27 +9,26 @@ #include #include -int -main() +int main() { - using namespace boost; - using std::string; + using namespace boost; + using std::string; - typedef adjacency_list, - property > graph_t; + typedef adjacency_list< vecS, vecS, directedS, no_property, + property< edge_index_t, int >, property< graph_name_t, string > > + graph_t; - graph_t g; - get_property(g, graph_name) = "graph"; + graph_t g; + get_property(g, graph_name) = "graph"; - std::cout << "name: " << get_property(g, graph_name) << std::endl; + std::cout << "name: " << get_property(g, graph_name) << std::endl; - typedef subgraph subgraph_t; + typedef subgraph< graph_t > subgraph_t; - subgraph_t sg; - get_property(sg, graph_name) = "subgraph"; + subgraph_t sg; + get_property(sg, graph_name) = "subgraph"; - std::cout << "name: " << get_property(sg, graph_name) << std::endl; - - return exit_success; + std::cout << "name: " << get_property(sg, graph_name) << std::endl; + + return exit_success; } diff --git a/example/graphviz.cpp b/example/graphviz.cpp index 4e357aeb4..1d7fabac8 100644 --- a/example/graphviz.cpp +++ b/example/graphviz.cpp @@ -14,66 +14,66 @@ using namespace boost; -typedef boost::adjacency_list, - property > Digraph; +typedef boost::adjacency_list< vecS, vecS, directedS, + property< vertex_name_t, std::string >, property< edge_weight_t, double > > + Digraph; -typedef boost::adjacency_list, - property > Graph; +typedef boost::adjacency_list< vecS, vecS, undirectedS, + property< vertex_name_t, std::string >, property< edge_weight_t, double > > + Graph; void test_graph_read_write(const std::string& filename) { - std::ifstream in(filename.c_str()); - BOOST_REQUIRE(in); - - Graph g; - dynamic_properties dp; - dp.property("id", get(vertex_name, g)); - dp.property("weight", get(edge_weight, g)); - BOOST_CHECK(read_graphviz(in, g, dp, "id")); - - BOOST_CHECK(num_vertices(g) == 4); - BOOST_CHECK(num_edges(g) == 4); - - typedef graph_traits::vertex_descriptor Vertex; - - std::map name_to_vertex; - BGL_FORALL_VERTICES(v, g, Graph) + std::ifstream in(filename.c_str()); + BOOST_REQUIRE(in); + + Graph g; + dynamic_properties dp; + dp.property("id", get(vertex_name, g)); + dp.property("weight", get(edge_weight, g)); + BOOST_CHECK(read_graphviz(in, g, dp, "id")); + + BOOST_CHECK(num_vertices(g) == 4); + BOOST_CHECK(num_edges(g) == 4); + + typedef graph_traits< Graph >::vertex_descriptor Vertex; + + std::map< std::string, Vertex > name_to_vertex; + BGL_FORALL_VERTICES(v, g, Graph) name_to_vertex[get(vertex_name, g, v)] = v; - // Check vertices - BOOST_CHECK(name_to_vertex.find("0") != name_to_vertex.end()); - BOOST_CHECK(name_to_vertex.find("1") != name_to_vertex.end()); - BOOST_CHECK(name_to_vertex.find("foo") != name_to_vertex.end()); - BOOST_CHECK(name_to_vertex.find("bar") != name_to_vertex.end()); - - // Check edges - BOOST_CHECK(edge(name_to_vertex["0"], name_to_vertex["1"], g).second); - BOOST_CHECK(edge(name_to_vertex["1"], name_to_vertex["foo"], g).second); - BOOST_CHECK(edge(name_to_vertex["foo"], name_to_vertex["bar"], g).second); - BOOST_CHECK(edge(name_to_vertex["1"], name_to_vertex["bar"], g).second); - - BOOST_CHECK(get(edge_weight, g, - edge(name_to_vertex["0"], name_to_vertex["1"], g).first) - == 3.14159); - BOOST_CHECK(get(edge_weight, g, - edge(name_to_vertex["1"], name_to_vertex["foo"], g).first) - == 2.71828); - BOOST_CHECK(get(edge_weight, g, - edge(name_to_vertex["foo"], name_to_vertex["bar"], g).first) - == 10.0); - BOOST_CHECK(get(edge_weight, g, - edge(name_to_vertex["1"], name_to_vertex["bar"], g).first) - == 10.0); - - // Write out the graph - write_graphviz_dp(std::cout, g, dp, std::string("id")); + // Check vertices + BOOST_CHECK(name_to_vertex.find("0") != name_to_vertex.end()); + BOOST_CHECK(name_to_vertex.find("1") != name_to_vertex.end()); + BOOST_CHECK(name_to_vertex.find("foo") != name_to_vertex.end()); + BOOST_CHECK(name_to_vertex.find("bar") != name_to_vertex.end()); + + // Check edges + BOOST_CHECK(edge(name_to_vertex["0"], name_to_vertex["1"], g).second); + BOOST_CHECK(edge(name_to_vertex["1"], name_to_vertex["foo"], g).second); + BOOST_CHECK(edge(name_to_vertex["foo"], name_to_vertex["bar"], g).second); + BOOST_CHECK(edge(name_to_vertex["1"], name_to_vertex["bar"], g).second); + + BOOST_CHECK(get(edge_weight, g, + edge(name_to_vertex["0"], name_to_vertex["1"], g).first) + == 3.14159); + BOOST_CHECK(get(edge_weight, g, + edge(name_to_vertex["1"], name_to_vertex["foo"], g).first) + == 2.71828); + BOOST_CHECK(get(edge_weight, g, + edge(name_to_vertex["foo"], name_to_vertex["bar"], g).first) + == 10.0); + BOOST_CHECK(get(edge_weight, g, + edge(name_to_vertex["1"], name_to_vertex["bar"], g).first) + == 10.0); + + // Write out the graph + write_graphviz_dp(std::cout, g, dp, std::string("id")); } int test_main(int argc, char* argv[]) { - test_graph_read_write(argc >= 2 ? argv[1] : "graphviz_example.dot"); - - return 0; + test_graph_read_write(argc >= 2 ? argv[1] : "graphviz_example.dot"); + + return 0; } diff --git a/example/graphviz_test.dot b/example/graphviz_test.dot index c7eb4b5bd..dc59b7627 100644 --- a/example/graphviz_test.dot +++ b/example/graphviz_test.dot @@ -7,7 +7,7 @@ digraph G { subgraph inner { //subgraph or subgraph of subgraph node [color = green]; - a1 -> a2 -> a3 + a1 -> a2 -> a3 }; diff --git a/example/grid_graph_example.cpp b/example/grid_graph_example.cpp index 1406f2ef4..c49a3b16d 100644 --- a/example/grid_graph_example.cpp +++ b/example/grid_graph_example.cpp @@ -14,73 +14,78 @@ #define DIMENSIONS 3 using namespace boost; -typedef grid_graph Graph; -typedef graph_traits Traits; +typedef grid_graph< DIMENSIONS > Graph; +typedef graph_traits< Graph > Traits; // Define a simple function to print vertices -void print_vertex(Traits::vertex_descriptor vertex_to_print) { - std::cout << "(" << vertex_to_print[0] << ", " << vertex_to_print[1] << - ", " << vertex_to_print[2] << ")" << std::endl; +void print_vertex(Traits::vertex_descriptor vertex_to_print) +{ + std::cout << "(" << vertex_to_print[0] << ", " << vertex_to_print[1] << ", " + << vertex_to_print[2] << ")" << std::endl; } -int main(int argc, char* argv[]) { +int main(int argc, char* argv[]) +{ - // Define a 3x5x7 grid_graph where the second dimension doesn't wrap - boost::array lengths = { { 3, 5, 7 } }; - boost::array wrapped = { { true, false, true } }; - Graph graph(lengths, wrapped); + // Define a 3x5x7 grid_graph where the second dimension doesn't wrap + boost::array< std::size_t, 3 > lengths = { { 3, 5, 7 } }; + boost::array< bool, 3 > wrapped = { { true, false, true } }; + Graph graph(lengths, wrapped); - // Do a round-trip test of the vertex index functions - for (Traits::vertices_size_type v_index = 0; - v_index < num_vertices(graph); ++v_index) { + // Do a round-trip test of the vertex index functions + for (Traits::vertices_size_type v_index = 0; v_index < num_vertices(graph); + ++v_index) + { - // The two indicies should always be equal - std::cout << "Index of vertex " << v_index << " is " << - get(boost::vertex_index, graph, vertex(v_index, graph)) << std::endl; + // The two indicies should always be equal + std::cout << "Index of vertex " << v_index << " is " + << get(boost::vertex_index, graph, vertex(v_index, graph)) + << std::endl; + } - } + // Do a round-trip test of the edge index functions + for (Traits::edges_size_type e_index = 0; e_index < num_edges(graph); + ++e_index) + { - // Do a round-trip test of the edge index functions - for (Traits::edges_size_type e_index = 0; - e_index < num_edges(graph); ++e_index) { + // The two indicies should always be equal + std::cout << "Index of edge " << e_index << " is " + << get(boost::edge_index, graph, edge_at(e_index, graph)) + << std::endl; + } - // The two indicies should always be equal - std::cout << "Index of edge " << e_index << " is " << - get(boost::edge_index, graph, edge_at(e_index, graph)) << std::endl; + // Print number of dimensions + std::cout << graph.dimensions() << std::endl; // prints "3" - } + // Print dimension lengths (same order as in the lengths array) + std::cout << graph.length(0) << "x" << graph.length(1) << "x" + << graph.length(2) << std::endl; // prints "3x5x7" - // Print number of dimensions - std::cout << graph.dimensions() << std::endl; // prints "3" + // Print dimension wrapping (W = wrapped, U = unwrapped) + std::cout << (graph.wrapped(0) ? "W" : "U") << ", " + << (graph.wrapped(1) ? "W" : "U") << ", " + << (graph.wrapped(2) ? "W" : "U") + << std::endl; // prints "W, U, W" - // Print dimension lengths (same order as in the lengths array) - std::cout << graph.length(0) << "x" << graph.length(1) << - "x" << graph.length(2) << std::endl; // prints "3x5x7" + // Start with the first vertex in the graph + Traits::vertex_descriptor first_vertex = vertex(0, graph); + print_vertex(first_vertex); // prints "(0, 0, 0)" - // Print dimension wrapping (W = wrapped, U = unwrapped) - std::cout << (graph.wrapped(0) ? "W" : "U") << ", " << - (graph.wrapped(1) ? "W" : "U") << ", " << - (graph.wrapped(2) ? "W" : "U") << std::endl; // prints "W, U, W" + // Print the next vertex in dimension 0 + print_vertex(graph.next(first_vertex, 0)); // prints "(1, 0, 0)" - // Start with the first vertex in the graph - Traits::vertex_descriptor first_vertex = vertex(0, graph); - print_vertex(first_vertex); // prints "(0, 0, 0)" + // Print the next vertex in dimension 1 + print_vertex(graph.next(first_vertex, 1)); // prints "(0, 1, 0)" - // Print the next vertex in dimension 0 - print_vertex(graph.next(first_vertex, 0)); // prints "(1, 0, 0)" + // Print the 5th next vertex in dimension 2 + print_vertex(graph.next(first_vertex, 2, 5)); // prints "(0, 0, 4)" - // Print the next vertex in dimension 1 - print_vertex(graph.next(first_vertex, 1)); // prints "(0, 1, 0)" + // Print the previous vertex in dimension 0 (wraps) + print_vertex(graph.previous(first_vertex, 0)); // prints "(2, 0, 0)" - // Print the 5th next vertex in dimension 2 - print_vertex(graph.next(first_vertex, 2, 5)); // prints "(0, 0, 4)" + // Print the previous vertex in dimension 1 (doesn't wrap, so it's the same) + print_vertex(graph.previous(first_vertex, 1)); // prints "(0, 0, 0)" - // Print the previous vertex in dimension 0 (wraps) - print_vertex(graph.previous(first_vertex, 0)); // prints "(2, 0, 0)" - - // Print the previous vertex in dimension 1 (doesn't wrap, so it's the same) - print_vertex(graph.previous(first_vertex, 1)); // prints "(0, 0, 0)" - - // Print the 20th previous vertex in dimension 2 (wraps around twice) - print_vertex(graph.previous(first_vertex, 2, 20)); // prints "(0, 0, ?)" + // Print the 20th previous vertex in dimension 2 (wraps around twice) + print_vertex(graph.previous(first_vertex, 2, 20)); // prints "(0, 0, ?)" } diff --git a/example/grid_graph_properties.cpp b/example/grid_graph_properties.cpp index 37d252a85..83ca9f2eb 100644 --- a/example/grid_graph_properties.cpp +++ b/example/grid_graph_properties.cpp @@ -11,30 +11,32 @@ #include #include -int main(int argc, char* argv[]) +int main(int argc, char* argv[]) { - // A 2D grid graph - typedef boost::grid_graph<2> GraphType; + // A 2D grid graph + typedef boost::grid_graph< 2 > GraphType; - // Create a 5x5 graph - const unsigned int dimension = 5; - boost::array lengths = { { dimension, dimension } }; - GraphType graph(lengths); + // Create a 5x5 graph + const unsigned int dimension = 5; + boost::array< std::size_t, 2 > lengths = { { dimension, dimension } }; + GraphType graph(lengths); - // Get the index map of the grid graph - typedef boost::property_map::const_type indexMapType; - indexMapType indexMap(get(boost::vertex_index, graph)); + // Get the index map of the grid graph + typedef boost::property_map< GraphType, boost::vertex_index_t >::const_type + indexMapType; + indexMapType indexMap(get(boost::vertex_index, graph)); - // Create a float for every node in the graph - boost::vector_property_map dataMap(num_vertices(graph), indexMap); + // Create a float for every node in the graph + boost::vector_property_map< float, indexMapType > dataMap( + num_vertices(graph), indexMap); - // Associate the value 2.0 with the node at position (0,1) in the grid - boost::graph_traits::vertex_descriptor v = { { 0, 1 } }; - put(dataMap, v, 2.0f); + // Associate the value 2.0 with the node at position (0,1) in the grid + boost::graph_traits< GraphType >::vertex_descriptor v = { { 0, 1 } }; + put(dataMap, v, 2.0f); - // Get the data at the node at position (0,1) in the grid - float retrieved = get(dataMap, v); - std::cout << "Retrieved value: " << retrieved << std::endl; + // Get the data at the node at position (0,1) in the grid + float retrieved = get(dataMap, v); + std::cout << "Retrieved value: " << retrieved << std::endl; - return 0; + return 0; } diff --git a/example/hawick_circuits.cpp b/example/hawick_circuits.cpp index b29467b9e..682656035 100644 --- a/example/hawick_circuits.cpp +++ b/example/hawick_circuits.cpp @@ -16,15 +16,11 @@ #include #include - -template -struct cycle_printer +template < typename OutputStream > struct cycle_printer { - cycle_printer(OutputStream& stream) - : os(stream) - { } + cycle_printer(OutputStream& stream) : os(stream) {} - template + template < typename Path, typename Graph > void cycle(Path const& p, Graph const& g) { if (p.empty()) @@ -32,15 +28,15 @@ struct cycle_printer // Get the property map containing the vertex indices // so we can print them. - typedef typename boost::property_map< - Graph, boost::vertex_index_t - >::const_type IndexMap; + typedef typename boost::property_map< Graph, + boost::vertex_index_t >::const_type IndexMap; IndexMap indices = get(boost::vertex_index, g); // Iterate over path printing each vertex that forms the cycle. typename Path::const_iterator i, before_end = boost::prior(p.end()); - for (i = p.begin(); i != before_end; ++i) { + for (i = p.begin(); i != before_end; ++i) + { os << get(indices, *i) << " "; } os << get(indices, *i) << '\n'; @@ -48,20 +44,21 @@ struct cycle_printer OutputStream& os; }; - // VertexPairIterator is an iterator over pairs of whitespace separated // vertices `u` and `v` representing a directed edge from `u` to `v`. -template +template < typename Graph, typename VertexPairIterator > void build_graph(Graph& graph, unsigned int const nvertices, - VertexPairIterator first, VertexPairIterator last) { - typedef boost::graph_traits Traits; + VertexPairIterator first, VertexPairIterator last) +{ + typedef boost::graph_traits< Graph > Traits; typedef typename Traits::vertex_descriptor vertex_descriptor; - std::map vertices; + std::map< unsigned int, vertex_descriptor > vertices; for (unsigned int i = 0; i < nvertices; ++i) vertices[i] = add_vertex(graph); - for (; first != last; ++first) { + for (; first != last; ++first) + { unsigned int u = *first++; BOOST_ASSERT_MSG(first != last, @@ -77,19 +74,20 @@ void build_graph(Graph& graph, unsigned int const nvertices, BOOST_ASSERT(num_vertices(graph) == nvertices); } - -int main(int argc, char const* argv[]) { - if (argc < 2) { +int main(int argc, char const* argv[]) +{ + if (argc < 2) + { std::cout << "usage: " << argv[0] << " num_vertices < input\n"; return EXIT_FAILURE; } - unsigned int num_vertices = boost::lexical_cast(argv[1]); - std::istream_iterator first_vertex(std::cin), last_vertex; + unsigned int num_vertices = boost::lexical_cast< unsigned int >(argv[1]); + std::istream_iterator< unsigned int > first_vertex(std::cin), last_vertex; boost::directed_graph<> graph; build_graph(graph, num_vertices, first_vertex, last_vertex); - cycle_printer visitor(std::cout); + cycle_printer< std::ostream > visitor(std::cout); boost::hawick_circuits(graph, visitor); return EXIT_SUCCESS; diff --git a/example/helper.hpp b/example/helper.hpp index 1247618ac..571fb724e 100644 --- a/example/helper.hpp +++ b/example/helper.hpp @@ -14,24 +14,26 @@ #include -template -typename boost::graph_traits::vertex_descriptor -add_named_vertex(Graph& g, NameMap nm, const std::string& name, VertexMap& vm) +template < typename Graph, typename NameMap, typename VertexMap > +typename boost::graph_traits< Graph >::vertex_descriptor add_named_vertex( + Graph& g, NameMap nm, const std::string& name, VertexMap& vm) { - typedef typename boost::graph_traits::vertex_descriptor Vertex; + typedef typename boost::graph_traits< Graph >::vertex_descriptor Vertex; typedef typename VertexMap::iterator Iterator; Vertex v; Iterator iter; bool inserted; boost::tie(iter, inserted) = vm.insert(make_pair(name, Vertex())); - if(inserted) { + if (inserted) + { // The name was unique so we need to add a vertex to the graph v = add_vertex(g); iter->second = v; - put(nm, v, name); // store the name in the name map + put(nm, v, name); // store the name in the name map } - else { + else + { // We had alread inserted this name so we can return the // associated vertex. v = iter->second; @@ -39,14 +41,17 @@ add_named_vertex(Graph& g, NameMap nm, const std::string& name, VertexMap& vm) return v; } -template -inline std::map::vertex_descriptor> +template < typename Graph, typename NameMap, typename InputStream > +inline std::map< std::string, + typename boost::graph_traits< Graph >::vertex_descriptor > read_graph(Graph& g, NameMap nm, InputStream& is) { - typedef typename boost::graph_traits::vertex_descriptor Vertex; - std::map verts; - for(std::string line; std::getline(is, line); ) { - if(line.empty()) continue; + typedef typename boost::graph_traits< Graph >::vertex_descriptor Vertex; + std::map< std::string, Vertex > verts; + for (std::string line; std::getline(is, line);) + { + if (line.empty()) + continue; std::size_t index = line.find_first_of(','); std::string first(line, 0, index); std::string second(line, index + 1); @@ -58,24 +63,29 @@ read_graph(Graph& g, NameMap nm, InputStream& is) return verts; } -template -inline std::map::vertex_descriptor> +template < typename Graph, typename InputStream > +inline std::map< std::string, + typename boost::graph_traits< Graph >::vertex_descriptor > read_graph(Graph& g, InputStream& is) { - typedef typename boost::graph_traits::vertex_descriptor Vertex; - typedef boost::null_property_map NameMap; + typedef typename boost::graph_traits< Graph >::vertex_descriptor Vertex; + typedef boost::null_property_map< Vertex, std::string > NameMap; return read_graph(g, NameMap(), is); } -template -inline std::map::vertex_descriptor> +template < typename Graph, typename NameMap, typename WeightMap, + typename InputStream > +inline std::map< std::string, + typename boost::graph_traits< Graph >::vertex_descriptor > read_weighted_graph(Graph& g, NameMap nm, WeightMap wm, InputStream& is) { - typedef typename boost::graph_traits::vertex_descriptor Vertex; - typedef typename boost::graph_traits::edge_descriptor Edge; - std::map verts; - for(std::string line; std::getline(is, line); ) { - if(line.empty()) continue; + typedef typename boost::graph_traits< Graph >::vertex_descriptor Vertex; + typedef typename boost::graph_traits< Graph >::edge_descriptor Edge; + std::map< std::string, Vertex > verts; + for (std::string line; std::getline(is, line);) + { + if (line.empty()) + continue; std::size_t i = line.find_first_of(','); std::size_t j = line.find_first_of(',', i + 1); std::string first(line, 0, i); @@ -98,16 +108,15 @@ read_weighted_graph(Graph& g, NameMap nm, WeightMap wm, InputStream& is) return verts; } - -template -inline std::map::vertex_descriptor> +template < typename Graph, typename WeightMap, typename InputStream > +inline std::map< std::string, + typename boost::graph_traits< Graph >::vertex_descriptor > read_weighted_graph(Graph& g, WeightMap wm, InputStream& is) { - typedef typename boost::graph_traits::vertex_descriptor Vertex; - typedef boost::null_property_map NameMap; + typedef typename boost::graph_traits< Graph >::vertex_descriptor Vertex; + typedef boost::null_property_map< Vertex, std::string > NameMap; return read_weighted_graph(g, NameMap(), wm, is); } - #endif diff --git a/example/implicit_graph.cpp b/example/implicit_graph.cpp index 0d7887353..de462ad69 100644 --- a/example/implicit_graph.cpp +++ b/example/implicit_graph.cpp @@ -15,7 +15,6 @@ #include #include - /* This file defines a simple example of a read-only implicit weighted graph built using the Boost Graph Library. It can be used as a starting point for @@ -89,28 +88,28 @@ class ring_edge_iterator; struct edge_weight_map; // ReadablePropertyGraph associated types -namespace boost { - template<> - struct property_map< ring_graph, edge_weight_t > { +namespace boost +{ +template <> struct property_map< ring_graph, edge_weight_t > +{ typedef edge_weight_map type; typedef edge_weight_map const_type; - }; +}; - template<> - struct property_map< const ring_graph, edge_weight_t > { +template <> struct property_map< const ring_graph, edge_weight_t > +{ typedef edge_weight_map type; typedef edge_weight_map const_type; - }; +}; } // Tag values that specify the traversal type in graph::traversal_category. -struct ring_traversal_catetory: - virtual public boost::bidirectional_graph_tag, - virtual public boost::adjacency_graph_tag, - virtual public boost::vertex_list_graph_tag, - virtual public boost::edge_list_graph_tag - {}; - +struct ring_traversal_catetory : virtual public boost::bidirectional_graph_tag, + virtual public boost::adjacency_graph_tag, + virtual public boost::vertex_list_graph_tag, + virtual public boost::edge_list_graph_tag +{ +}; /* Undirected graph of vertices arranged in a ring shape. @@ -118,65 +117,74 @@ Undirected graph of vertices arranged in a ring shape. Vertices are indexed by integer, and edges connect vertices with consecutive indices. Vertex 0 is also adjacent to the vertex n-1. */ -class ring_graph { +class ring_graph +{ public: - // Graph associated types - typedef std::size_t vertex_descriptor; - typedef boost::undirected_tag directed_category; - typedef boost::disallow_parallel_edge_tag edge_parallel_category; - typedef ring_traversal_catetory traversal_category; - - // IncidenceGraph associated types - typedef std::pair edge_descriptor; - typedef ring_incident_edge_iterator out_edge_iterator; - typedef std::size_t degree_size_type; - - // BidirectionalGraph associated types - // Note that undirected graphs make no distinction between in- and out- - // edges. - typedef ring_incident_edge_iterator in_edge_iterator; - - // AdjacencyGraph associated types - typedef ring_adjacency_iterator adjacency_iterator; - - // VertexListGraph associated types - typedef boost::counting_iterator vertex_iterator; - typedef std::size_t vertices_size_type; - - // EdgeListGraph associated types - typedef ring_edge_iterator edge_iterator; - typedef std::size_t edges_size_type; - - // This type is not part of a graph concept, but is used to return the - // default vertex index map used by the Dijkstra search algorithm. - typedef vertex_descriptor vertex_property_type; - - ring_graph(std::size_t n):m_n(n) {}; - std::size_t n() const {return m_n;} + // Graph associated types + typedef std::size_t vertex_descriptor; + typedef boost::undirected_tag directed_category; + typedef boost::disallow_parallel_edge_tag edge_parallel_category; + typedef ring_traversal_catetory traversal_category; + + // IncidenceGraph associated types + typedef std::pair< vertex_descriptor, vertex_descriptor > edge_descriptor; + typedef ring_incident_edge_iterator out_edge_iterator; + typedef std::size_t degree_size_type; + + // BidirectionalGraph associated types + // Note that undirected graphs make no distinction between in- and out- + // edges. + typedef ring_incident_edge_iterator in_edge_iterator; + + // AdjacencyGraph associated types + typedef ring_adjacency_iterator adjacency_iterator; + + // VertexListGraph associated types + typedef boost::counting_iterator< vertex_descriptor > vertex_iterator; + typedef std::size_t vertices_size_type; + + // EdgeListGraph associated types + typedef ring_edge_iterator edge_iterator; + typedef std::size_t edges_size_type; + + // This type is not part of a graph concept, but is used to return the + // default vertex index map used by the Dijkstra search algorithm. + typedef vertex_descriptor vertex_property_type; + + ring_graph(std::size_t n) : m_n(n) {}; + std::size_t n() const { return m_n; } + private: - // The number of vertices in the graph. - std::size_t m_n; + // The number of vertices in the graph. + std::size_t m_n; }; // Use these graph_traits parameterizations to refer to the associated // graph types. -typedef boost::graph_traits::vertex_descriptor vertex_descriptor; -typedef boost::graph_traits::edge_descriptor edge_descriptor; -typedef boost::graph_traits::out_edge_iterator out_edge_iterator; -typedef boost::graph_traits::in_edge_iterator in_edge_iterator; -typedef boost::graph_traits::adjacency_iterator adjacency_iterator; -typedef boost::graph_traits::degree_size_type degree_size_type; -typedef boost::graph_traits::vertex_iterator vertex_iterator; -typedef boost::graph_traits::vertices_size_type vertices_size_type; -typedef boost::graph_traits::edge_iterator edge_iterator; -typedef boost::graph_traits::edges_size_type edges_size_type; - +typedef boost::graph_traits< ring_graph >::vertex_descriptor vertex_descriptor; +typedef boost::graph_traits< ring_graph >::edge_descriptor edge_descriptor; +typedef boost::graph_traits< ring_graph >::out_edge_iterator out_edge_iterator; +typedef boost::graph_traits< ring_graph >::in_edge_iterator in_edge_iterator; +typedef boost::graph_traits< ring_graph >::adjacency_iterator + adjacency_iterator; +typedef boost::graph_traits< ring_graph >::degree_size_type degree_size_type; +typedef boost::graph_traits< ring_graph >::vertex_iterator vertex_iterator; +typedef boost::graph_traits< ring_graph >::vertices_size_type + vertices_size_type; +typedef boost::graph_traits< ring_graph >::edge_iterator edge_iterator; +typedef boost::graph_traits< ring_graph >::edges_size_type edges_size_type; // Tag values passed to an iterator constructor to specify whether it should // be created at the start or the end of its range. -struct iterator_position {}; -struct iterator_start:virtual public iterator_position {}; -struct iterator_end:virtual public iterator_position {}; +struct iterator_position +{ +}; +struct iterator_start : virtual public iterator_position +{ +}; +struct iterator_end : virtual public iterator_position +{ +}; /* Iterator over edges incident on a vertex in a ring graph. @@ -187,144 +195,138 @@ around the end of the ring as needed. It is implemented with the boost::iterator_adaptor class, adapting an offset into the dereference::ring_offset array. */ -class ring_incident_edge_iterator:public boost::iterator_adaptor < - ring_incident_edge_iterator, - boost::counting_iterator, - edge_descriptor, - boost::use_default, - edge_descriptor > { +class ring_incident_edge_iterator +: public boost::iterator_adaptor< ring_incident_edge_iterator, + boost::counting_iterator< std::size_t >, edge_descriptor, + boost::use_default, edge_descriptor > +{ public: - ring_incident_edge_iterator(): - ring_incident_edge_iterator::iterator_adaptor_(0),m_n(0),m_u(0) {}; - explicit ring_incident_edge_iterator(const ring_graph& g, - vertex_descriptor u, - iterator_start): - ring_incident_edge_iterator::iterator_adaptor_(0), - m_n(g.n()),m_u(u) {}; - explicit ring_incident_edge_iterator(const ring_graph& g, - vertex_descriptor u, - iterator_end): - // A graph with one vertex only has a single self-loop. A graph with - // two vertices has a single edge between them. All other graphs have - // two edges per vertex. - ring_incident_edge_iterator::iterator_adaptor_(g.n() > 2 ? 2:1), - m_n(g.n()),m_u(u) {}; + ring_incident_edge_iterator() + : ring_incident_edge_iterator::iterator_adaptor_(0), m_n(0), m_u(0) {}; + explicit ring_incident_edge_iterator( + const ring_graph& g, vertex_descriptor u, iterator_start) + : ring_incident_edge_iterator::iterator_adaptor_(0), m_n(g.n()), m_u(u) {}; + explicit ring_incident_edge_iterator( + const ring_graph& g, vertex_descriptor u, iterator_end) + : // A graph with one vertex only has a single self-loop. A graph with + // two vertices has a single edge between them. All other graphs have + // two edges per vertex. + ring_incident_edge_iterator::iterator_adaptor_(g.n() > 2 ? 2 : 1) + , m_n(g.n()) + , m_u(u) {}; private: - friend class boost::iterator_core_access; - - edge_descriptor dereference() const { - static const int ring_offset[] = {1, -1}; - vertex_descriptor v; - - std::size_t p = *this->base_reference(); - if (m_u == 0 && p == 1) - v = m_n-1; // Vertex n-1 precedes vertex 0. - else - v = (m_u+ring_offset[p]) % m_n; - return edge_descriptor(m_u, v); - } + friend class boost::iterator_core_access; + + edge_descriptor dereference() const + { + static const int ring_offset[] = { 1, -1 }; + vertex_descriptor v; + + std::size_t p = *this->base_reference(); + if (m_u == 0 && p == 1) + v = m_n - 1; // Vertex n-1 precedes vertex 0. + else + v = (m_u + ring_offset[p]) % m_n; + return edge_descriptor(m_u, v); + } - std::size_t m_n; // Size of the graph - vertex_descriptor m_u; // Vertex whose out edges are iterated + std::size_t m_n; // Size of the graph + vertex_descriptor m_u; // Vertex whose out edges are iterated }; - // IncidenceGraph valid expressions -vertex_descriptor source(edge_descriptor e, const ring_graph&) { - // The first vertex in the edge pair is the source. - return e.first; +vertex_descriptor source(edge_descriptor e, const ring_graph&) +{ + // The first vertex in the edge pair is the source. + return e.first; } - -vertex_descriptor target(edge_descriptor e, const ring_graph&) { - // The second vertex in the edge pair is the target. - return e.second; +vertex_descriptor target(edge_descriptor e, const ring_graph&) +{ + // The second vertex in the edge pair is the target. + return e.second; } -std::pair -out_edges(vertex_descriptor u, const ring_graph& g) { - return std::pair( - out_edge_iterator(g, u, iterator_start()), - out_edge_iterator(g, u, iterator_end()) ); +std::pair< out_edge_iterator, out_edge_iterator > out_edges( + vertex_descriptor u, const ring_graph& g) +{ + return std::pair< out_edge_iterator, out_edge_iterator >( + out_edge_iterator(g, u, iterator_start()), + out_edge_iterator(g, u, iterator_end())); } - -degree_size_type out_degree(vertex_descriptor, const ring_graph&) { - // All vertices in a ring graph have two neighbors. - return 2; +degree_size_type out_degree(vertex_descriptor, const ring_graph&) +{ + // All vertices in a ring graph have two neighbors. + return 2; } - // BidirectionalGraph valid expressions -std::pair -in_edges(vertex_descriptor u, const ring_graph& g) { - // The in-edges and out-edges are the same in an undirected graph. - return out_edges(u, g); +std::pair< in_edge_iterator, in_edge_iterator > in_edges( + vertex_descriptor u, const ring_graph& g) +{ + // The in-edges and out-edges are the same in an undirected graph. + return out_edges(u, g); } -degree_size_type in_degree(vertex_descriptor u, const ring_graph& g) { - // The in-degree and out-degree are both equal to the number of incident - // edges in an undirected graph. - return out_degree(u, g); +degree_size_type in_degree(vertex_descriptor u, const ring_graph& g) +{ + // The in-degree and out-degree are both equal to the number of incident + // edges in an undirected graph. + return out_degree(u, g); } -degree_size_type degree(vertex_descriptor u, const ring_graph& g) { - // The in-degree and out-degree are both equal to the number of incident - // edges in an undirected graph. - return out_degree(u, g); +degree_size_type degree(vertex_descriptor u, const ring_graph& g) +{ + // The in-degree and out-degree are both equal to the number of incident + // edges in an undirected graph. + return out_degree(u, g); } - /* Iterator over vertices adjacent to a given vertex. This iterates over the target vertices of all the incident edges. */ -class ring_adjacency_iterator:public boost::adjacency_iterator_generator< - ring_graph, - vertex_descriptor, - out_edge_iterator>::type { - // The parent class is an iterator_adpator that turns an iterator over - // out edges into an iterator over adjacent vertices. - typedef boost::adjacency_iterator_generator< - ring_graph, - vertex_descriptor, - out_edge_iterator>::type parent_class; +class ring_adjacency_iterator +: public boost::adjacency_iterator_generator< ring_graph, vertex_descriptor, + out_edge_iterator >::type +{ + // The parent class is an iterator_adpator that turns an iterator over + // out edges into an iterator over adjacent vertices. + typedef boost::adjacency_iterator_generator< ring_graph, vertex_descriptor, + out_edge_iterator >::type parent_class; + public: - ring_adjacency_iterator() {}; - ring_adjacency_iterator(vertex_descriptor u, - const ring_graph& g, - iterator_start): - parent_class(out_edge_iterator(g, u, iterator_start()), &g) {}; - ring_adjacency_iterator(vertex_descriptor u, - const ring_graph& g, - iterator_end): - parent_class(out_edge_iterator(g, u, iterator_end()), &g) {}; + ring_adjacency_iterator() {}; + ring_adjacency_iterator( + vertex_descriptor u, const ring_graph& g, iterator_start) + : parent_class(out_edge_iterator(g, u, iterator_start()), &g) {}; + ring_adjacency_iterator( + vertex_descriptor u, const ring_graph& g, iterator_end) + : parent_class(out_edge_iterator(g, u, iterator_end()), &g) {}; }; - // AdjacencyGraph valid expressions -std::pair -adjacent_vertices(vertex_descriptor u, const ring_graph& g) { - return std::pair( - adjacency_iterator(u, g, iterator_start()), - adjacency_iterator(u, g, iterator_end())); +std::pair< adjacency_iterator, adjacency_iterator > adjacent_vertices( + vertex_descriptor u, const ring_graph& g) +{ + return std::pair< adjacency_iterator, adjacency_iterator >( + adjacency_iterator(u, g, iterator_start()), + adjacency_iterator(u, g, iterator_end())); } - // VertexListGraph valid expressions -vertices_size_type num_vertices(const ring_graph& g) { - return g.n(); -}; +vertices_size_type num_vertices(const ring_graph& g) { return g.n(); }; -std::pair vertices(const ring_graph& g) { - return std::pair( - vertex_iterator(0), // The first iterator position - vertex_iterator(num_vertices(g)) ); // The last iterator position +std::pair< vertex_iterator, vertex_iterator > vertices(const ring_graph& g) +{ + return std::pair< vertex_iterator, vertex_iterator >( + vertex_iterator(0), // The first iterator position + vertex_iterator(num_vertices(g))); // The last iterator position } - /* Iterator over edges in a ring graph. @@ -334,219 +336,229 @@ vertex returns its first outgoing edge. It is implemented with the boost::iterator_adaptor class, because it is essentially a vertex_iterator with a customized deference operation. */ -class ring_edge_iterator:public boost::iterator_adaptor< - ring_edge_iterator, - vertex_iterator, - edge_descriptor, - boost::use_default, - edge_descriptor > { +class ring_edge_iterator +: public boost::iterator_adaptor< ring_edge_iterator, vertex_iterator, + edge_descriptor, boost::use_default, edge_descriptor > +{ public: - ring_edge_iterator(): - ring_edge_iterator::iterator_adaptor_(0),m_g(NULL) {}; - explicit ring_edge_iterator(const ring_graph& g, iterator_start): - ring_edge_iterator::iterator_adaptor_(vertices(g).first),m_g(&g) {}; - explicit ring_edge_iterator(const ring_graph& g, iterator_end): - ring_edge_iterator::iterator_adaptor_( - // Size 2 graphs have a single edge connecting the two vertices. - g.n() == 2 ? ++(vertices(g).first) : vertices(g).second ), - m_g(&g) {}; + ring_edge_iterator() + : ring_edge_iterator::iterator_adaptor_(0), m_g(NULL) {}; + explicit ring_edge_iterator(const ring_graph& g, iterator_start) + : ring_edge_iterator::iterator_adaptor_(vertices(g).first), m_g(&g) {}; + explicit ring_edge_iterator(const ring_graph& g, iterator_end) + : ring_edge_iterator::iterator_adaptor_( + // Size 2 graphs have a single edge connecting the two vertices. + g.n() == 2 ? ++(vertices(g).first) : vertices(g).second) + , m_g(&g) {}; private: - friend class boost::iterator_core_access; + friend class boost::iterator_core_access; - edge_descriptor dereference() const { - // The first element in the incident edge list of the current vertex. - return *(out_edges(*this->base_reference(), *m_g).first); - } + edge_descriptor dereference() const + { + // The first element in the incident edge list of the current vertex. + return *(out_edges(*this->base_reference(), *m_g).first); + } - // The graph being iterated over - const ring_graph *m_g; + // The graph being iterated over + const ring_graph* m_g; }; // EdgeListGraph valid expressions -std::pair edges(const ring_graph& g) { - return std::pair( - ring_edge_iterator(g, iterator_start()), - ring_edge_iterator(g, iterator_end()) ); +std::pair< edge_iterator, edge_iterator > edges(const ring_graph& g) +{ + return std::pair< edge_iterator, edge_iterator >( + ring_edge_iterator(g, iterator_start()), + ring_edge_iterator(g, iterator_end())); } -edges_size_type num_edges(const ring_graph& g) { - // There are as many edges as there are vertices, except for size 2 - // graphs, which have a single edge connecting the two vertices. - return g.n() == 2 ? 1:g.n(); +edges_size_type num_edges(const ring_graph& g) +{ + // There are as many edges as there are vertices, except for size 2 + // graphs, which have a single edge connecting the two vertices. + return g.n() == 2 ? 1 : g.n(); } - // AdjacencyMatrix valid expressions -std::pair -edge(vertex_descriptor u, vertex_descriptor v, const ring_graph& g) { - if ((u == v + 1 || v == u + 1) && - u > 0 && u < num_vertices(g) && v > 0 && v < num_vertices(g)) - return std::pair(edge_descriptor(u, v), true); - else - return std::pair(edge_descriptor(), false); +std::pair< edge_descriptor, bool > edge( + vertex_descriptor u, vertex_descriptor v, const ring_graph& g) +{ + if ((u == v + 1 || v == u + 1) && u > 0 && u < num_vertices(g) && v > 0 + && v < num_vertices(g)) + return std::pair< edge_descriptor, bool >(edge_descriptor(u, v), true); + else + return std::pair< edge_descriptor, bool >(edge_descriptor(), false); } - /* Map from edges to weight values */ -struct edge_weight_map { - typedef double value_type; - typedef value_type reference; - typedef edge_descriptor key_type; - typedef boost::readable_property_map_tag category; - - // Edges have a weight equal to the average of their endpoint indexes. - reference operator[](key_type e) const { - return (e.first + e.second)/2.0; - } +struct edge_weight_map +{ + typedef double value_type; + typedef value_type reference; + typedef edge_descriptor key_type; + typedef boost::readable_property_map_tag category; + + // Edges have a weight equal to the average of their endpoint indexes. + reference operator[](key_type e) const + { + return (e.first + e.second) / 2.0; + } }; // Use these propety_map and property_traits parameterizations to refer to // the associated property map types. -typedef boost::property_map::const_type - const_edge_weight_map; -typedef boost::property_traits::reference - edge_weight_map_value_type; -typedef boost::property_traits::key_type - edge_weight_map_key; +typedef boost::property_map< ring_graph, boost::edge_weight_t >::const_type + const_edge_weight_map; +typedef boost::property_traits< const_edge_weight_map >::reference + edge_weight_map_value_type; +typedef boost::property_traits< const_edge_weight_map >::key_type + edge_weight_map_key; // PropertyMap valid expressions -edge_weight_map_value_type -get(const_edge_weight_map pmap, edge_weight_map_key e) { - return pmap[e]; +edge_weight_map_value_type get( + const_edge_weight_map pmap, edge_weight_map_key e) +{ + return pmap[e]; } - // ReadablePropertyGraph valid expressions -const_edge_weight_map get(boost::edge_weight_t, const ring_graph&) { - return const_edge_weight_map(); +const_edge_weight_map get(boost::edge_weight_t, const ring_graph&) +{ + return const_edge_weight_map(); } -edge_weight_map_value_type get(boost::edge_weight_t tag, - const ring_graph& g, - edge_weight_map_key e) { - return get(tag, g)[e]; +edge_weight_map_value_type get( + boost::edge_weight_t tag, const ring_graph& g, edge_weight_map_key e) +{ + return get(tag, g)[e]; } - // This expression is not part of a graph concept, but is used to return the // default vertex index map used by the Dijkstra search algorithm. -boost::identity_property_map get(boost::vertex_index_t, const ring_graph&) { - // The vertex descriptors are already unsigned integer indices, so just - // return an identity map. - return boost::identity_property_map(); +boost::identity_property_map get(boost::vertex_index_t, const ring_graph&) +{ + // The vertex descriptors are already unsigned integer indices, so just + // return an identity map. + return boost::identity_property_map(); } // Print edges as (x, y) -std::ostream& operator<<(std::ostream& output, const edge_descriptor& e) { - return output << "(" << e.first << ", " << e.second << ")"; +std::ostream& operator<<(std::ostream& output, const edge_descriptor& e) +{ + return output << "(" << e.first << ", " << e.second << ")"; } -int main (int argc, char const *argv[]) { - using namespace boost; - // Check the concepts that graph models. This is included to demonstrate - // how concept checking works, but is not required for a working program - // since Boost algorithms do their own concept checking. - BOOST_CONCEPT_ASSERT(( BidirectionalGraphConcept )); - BOOST_CONCEPT_ASSERT(( AdjacencyGraphConcept )); - BOOST_CONCEPT_ASSERT(( VertexListGraphConcept )); - BOOST_CONCEPT_ASSERT(( EdgeListGraphConcept )); - BOOST_CONCEPT_ASSERT(( AdjacencyMatrixConcept )); - BOOST_CONCEPT_ASSERT(( - ReadablePropertyMapConcept )); - BOOST_CONCEPT_ASSERT(( - ReadablePropertyGraphConcept )); - - // Specify the size of the graph on the command line, or use a default size - // of 5. - std::size_t n = argc == 2 ? boost::lexical_cast(argv[1]) : 5; - - // Create a small ring graph. - ring_graph g(n); - - // Print the outgoing edges of all the vertices. For n=5 this will print: - // - // Vertices, outgoing edges, and adjacent vertices - // Vertex 0: (0, 1) (0, 4) Adjacent vertices 1 4 - // Vertex 1: (1, 2) (1, 0) Adjacent vertices 2 0 - // Vertex 2: (2, 3) (2, 1) Adjacent vertices 3 1 - // Vertex 3: (3, 4) (3, 2) Adjacent vertices 4 2 - // Vertex 4: (4, 0) (4, 3) Adjacent vertices 0 3 - // 5 vertices - std::cout << "Vertices, outgoing edges, and adjacent vertices" << std::endl; - vertex_iterator vi, vi_end; - for (boost::tie(vi, vi_end) = vertices(g); vi != vi_end; vi++) { - vertex_descriptor u = *vi; - std::cout << "Vertex " << u << ": "; - // Adjacenct edges - out_edge_iterator ei, ei_end; - for (boost::tie(ei, ei_end) = out_edges(u, g); ei != ei_end; ei++) - std::cout << *ei << " "; - std::cout << " Adjacent vertices "; - // Adjacent vertices - // Here we want our adjacency_iterator and not boost::adjacency_iterator. - ::adjacency_iterator ai, ai_end; - for (boost::tie(ai, ai_end) = adjacent_vertices(u, g); ai != ai_end; ai++) { - std::cout << *ai << " "; +int main(int argc, char const* argv[]) +{ + using namespace boost; + // Check the concepts that graph models. This is included to demonstrate + // how concept checking works, but is not required for a working program + // since Boost algorithms do their own concept checking. + BOOST_CONCEPT_ASSERT((BidirectionalGraphConcept< ring_graph >)); + BOOST_CONCEPT_ASSERT((AdjacencyGraphConcept< ring_graph >)); + BOOST_CONCEPT_ASSERT((VertexListGraphConcept< ring_graph >)); + BOOST_CONCEPT_ASSERT((EdgeListGraphConcept< ring_graph >)); + BOOST_CONCEPT_ASSERT((AdjacencyMatrixConcept< ring_graph >)); + BOOST_CONCEPT_ASSERT( + (ReadablePropertyMapConcept< const_edge_weight_map, edge_descriptor >)); + BOOST_CONCEPT_ASSERT((ReadablePropertyGraphConcept< ring_graph, + edge_descriptor, edge_weight_t >)); + + // Specify the size of the graph on the command line, or use a default size + // of 5. + std::size_t n = argc == 2 ? boost::lexical_cast< std::size_t >(argv[1]) : 5; + + // Create a small ring graph. + ring_graph g(n); + + // Print the outgoing edges of all the vertices. For n=5 this will print: + // + // Vertices, outgoing edges, and adjacent vertices + // Vertex 0: (0, 1) (0, 4) Adjacent vertices 1 4 + // Vertex 1: (1, 2) (1, 0) Adjacent vertices 2 0 + // Vertex 2: (2, 3) (2, 1) Adjacent vertices 3 1 + // Vertex 3: (3, 4) (3, 2) Adjacent vertices 4 2 + // Vertex 4: (4, 0) (4, 3) Adjacent vertices 0 3 + // 5 vertices + std::cout << "Vertices, outgoing edges, and adjacent vertices" << std::endl; + vertex_iterator vi, vi_end; + for (boost::tie(vi, vi_end) = vertices(g); vi != vi_end; vi++) + { + vertex_descriptor u = *vi; + std::cout << "Vertex " << u << ": "; + // Adjacenct edges + out_edge_iterator ei, ei_end; + for (boost::tie(ei, ei_end) = out_edges(u, g); ei != ei_end; ei++) + std::cout << *ei << " "; + std::cout << " Adjacent vertices "; + // Adjacent vertices + // Here we want our adjacency_iterator and not + // boost::adjacency_iterator. + ::adjacency_iterator ai, ai_end; + for (boost::tie(ai, ai_end) = adjacent_vertices(u, g); ai != ai_end; + ai++) + { + std::cout << *ai << " "; + } + std::cout << std::endl; } - std::cout << std::endl; - } - std::cout << num_vertices(g) << " vertices" << std::endl << std::endl; - - // Print all the edges in the graph along with their weights. For n=5 this - // will print: - // - // Edges and weights - // (0, 1) weight 0.5 - // (1, 2) weight 1.5 - // (2, 3) weight 2.5 - // (3, 4) weight 3.5 - // (4, 0) weight 2 - // 5 edges - std::cout << "Edges and weights" << std::endl; - edge_iterator ei, ei_end; - for (boost::tie(ei, ei_end) = edges(g); ei != ei_end; ei++) { - edge_descriptor e = *ei; - std::cout << e << " weight " << get(edge_weight, g, e) << std::endl; - } - std::cout << num_edges(g) << " edges" << std::endl; - - if (n>0) { - std::cout << std::endl; - // Do a Dijkstra search from vertex 0. For n=5 this will print: + std::cout << num_vertices(g) << " vertices" << std::endl << std::endl; + + // Print all the edges in the graph along with their weights. For n=5 this + // will print: // - // Dijkstra search from vertex 0 - // Vertex 0: parent 0, distance 0 - // Vertex 1: parent 0, distance 0.5 - // Vertex 2: parent 1, distance 2 - // Vertex 3: parent 2, distance 4.5 - // Vertex 4: parent 0, distance 2 - vertex_descriptor source = 0; - std::vector pred(num_vertices(g)); - std::vector dist(num_vertices(g)); - iterator_property_map::iterator, - property_map::const_type> - pred_pm(pred.begin(), get(vertex_index, g)); - iterator_property_map::iterator, - property_map::const_type> - dist_pm(dist.begin(), get(vertex_index, g)); - - dijkstra_shortest_paths(g, source, - predecessor_map(pred_pm). - distance_map(dist_pm) ); - - std::cout << "Dijkstra search from vertex " << source << std::endl; - for (boost::tie(vi, vi_end) = vertices(g); vi != vi_end; ++vi) { - vertex_descriptor u = *vi; - std::cout << "Vertex " << u << ": " - << "parent "<< pred[*vi] << ", " - << "distance " << dist[u] - << std::endl; + // Edges and weights + // (0, 1) weight 0.5 + // (1, 2) weight 1.5 + // (2, 3) weight 2.5 + // (3, 4) weight 3.5 + // (4, 0) weight 2 + // 5 edges + std::cout << "Edges and weights" << std::endl; + edge_iterator ei, ei_end; + for (boost::tie(ei, ei_end) = edges(g); ei != ei_end; ei++) + { + edge_descriptor e = *ei; + std::cout << e << " weight " << get(edge_weight, g, e) << std::endl; + } + std::cout << num_edges(g) << " edges" << std::endl; + + if (n > 0) + { + std::cout << std::endl; + // Do a Dijkstra search from vertex 0. For n=5 this will print: + // + // Dijkstra search from vertex 0 + // Vertex 0: parent 0, distance 0 + // Vertex 1: parent 0, distance 0.5 + // Vertex 2: parent 1, distance 2 + // Vertex 3: parent 2, distance 4.5 + // Vertex 4: parent 0, distance 2 + vertex_descriptor source = 0; + std::vector< vertex_descriptor > pred(num_vertices(g)); + std::vector< edge_weight_map_value_type > dist(num_vertices(g)); + iterator_property_map< std::vector< vertex_descriptor >::iterator, + property_map< ring_graph, vertex_index_t >::const_type > + pred_pm(pred.begin(), get(vertex_index, g)); + iterator_property_map< + std::vector< edge_weight_map_value_type >::iterator, + property_map< ring_graph, vertex_index_t >::const_type > + dist_pm(dist.begin(), get(vertex_index, g)); + + dijkstra_shortest_paths( + g, source, predecessor_map(pred_pm).distance_map(dist_pm)); + + std::cout << "Dijkstra search from vertex " << source << std::endl; + for (boost::tie(vi, vi_end) = vertices(g); vi != vi_end; ++vi) + { + vertex_descriptor u = *vi; + std::cout << "Vertex " << u << ": " + << "parent " << pred[*vi] << ", " + << "distance " << dist[u] << std::endl; + } } - } - return 0; + return 0; } diff --git a/example/in_edges.cpp b/example/in_edges.cpp index f729c44da..1c27aa454 100644 --- a/example/in_edges.cpp +++ b/example/in_edges.cpp @@ -16,38 +16,39 @@ /* Sample Output - 0 <-- - 1 <-- 0 - 2 <-- 1 - 3 <-- 1 - 4 <-- 2 3 + 0 <-- + 1 <-- 0 + 2 <-- 1 + 3 <-- 1 + 4 <-- 2 3 */ -int main(int , char* []) +int main(int, char*[]) { - using namespace boost; - using namespace std; - using namespace boost; - - typedef adjacency_list Graph; - const int num_vertices = 5; - Graph g(num_vertices); - - add_edge(0, 1, g); - add_edge(1, 2, g); - add_edge(1, 3, g); - add_edge(2, 4, g); - add_edge(3, 4, g); - - boost::graph_traits::vertex_iterator i, end; - boost::graph_traits::in_edge_iterator ei, edge_end; - - for(boost::tie(i,end) = vertices(g); i != end; ++i) { - cout << *i << " <-- "; - for (boost::tie(ei,edge_end) = in_edges(*i, g); ei != edge_end; ++ei) - cout << source(*ei, g) << " "; - cout << endl; - } - return 0; + using namespace boost; + using namespace std; + using namespace boost; + + typedef adjacency_list< listS, vecS, bidirectionalS > Graph; + const int num_vertices = 5; + Graph g(num_vertices); + + add_edge(0, 1, g); + add_edge(1, 2, g); + add_edge(1, 3, g); + add_edge(2, 4, g); + add_edge(3, 4, g); + + boost::graph_traits< Graph >::vertex_iterator i, end; + boost::graph_traits< Graph >::in_edge_iterator ei, edge_end; + + for (boost::tie(i, end) = vertices(g); i != end; ++i) + { + cout << *i << " <-- "; + for (boost::tie(ei, edge_end) = in_edges(*i, g); ei != edge_end; ++ei) + cout << source(*ei, g) << " "; + cout << endl; + } + return 0; } diff --git a/example/in_edges.expected b/example/in_edges.expected index b7ed0a68e..7bb2a725e 100644 --- a/example/in_edges.expected +++ b/example/in_edges.expected @@ -1,5 +1,5 @@ -0 <-- -1 <-- 0 -2 <-- 1 -3 <-- 1 -4 <-- 2 3 +0 <-- +1 <-- 0 +2 <-- 1 +3 <-- 1 +4 <-- 2 3 diff --git a/example/inclusive_mean_geodesic.cpp b/example/inclusive_mean_geodesic.cpp index d825a27dc..ef88a720a 100644 --- a/example/inclusive_mean_geodesic.cpp +++ b/example/inclusive_mean_geodesic.cpp @@ -20,21 +20,21 @@ using namespace boost; // This template structure defines the function that we will apply // to compute both the per-vertex mean geodesic distances and the // graph's mean geodesic distance. -template > +template < typename Graph, typename DistanceType, typename ResultType, + typename Divides = divides< ResultType > > struct inclusive_average { typedef DistanceType distance_type; typedef ResultType result_type; - result_type operator ()(distance_type d, const Graph& g) + result_type operator()(distance_type d, const Graph& g) { - if(d == numeric_values::infinity()) { - return numeric_values::infinity(); + if (d == numeric_values< distance_type >::infinity()) + { + return numeric_values< result_type >::infinity(); } - else { + else + { return div(result_type(d), result_type(num_vertices(g))); } } @@ -56,36 +56,35 @@ struct Link }; // Declare the graph type and its vertex and edge types. -typedef directed_graph Graph; -typedef graph_traits::vertex_descriptor Vertex; -typedef graph_traits::edge_descriptor Edge; +typedef directed_graph< WebPage, Link > Graph; +typedef graph_traits< Graph >::vertex_descriptor Vertex; +typedef graph_traits< Graph >::edge_descriptor Edge; // The name map provides an abstract accessor for the names of // each vertex. This is used during graph creation. -typedef property_map::type NameMap; +typedef property_map< Graph, string WebPage::* >::type NameMap; // Declare a matrix type and its corresponding property map that // will contain the distances between each pair of vertices. -typedef exterior_vertex_property DistanceProperty; +typedef exterior_vertex_property< Graph, float > DistanceProperty; typedef DistanceProperty::matrix_type DistanceMatrix; typedef DistanceProperty::matrix_map_type DistanceMatrixMap; // Declare the weight map as an accessor into the bundled // edge property. -typedef property_map::type WeightMap; +typedef property_map< Graph, float Link::* >::type WeightMap; // Declare a container and its corresponding property map that // will contain the resulting mean geodesic distances of each // vertex in the graph. -typedef exterior_vertex_property GeodesicProperty; +typedef exterior_vertex_property< Graph, float > GeodesicProperty; typedef GeodesicProperty::container_type GeodesicContainer; typedef GeodesicProperty::map_type GeodesicMap; static float exclusive_geodesics(const Graph&, DistanceMatrixMap, GeodesicMap); static float inclusive_geodesics(const Graph&, DistanceMatrixMap, GeodesicMap); -int -main(int argc, char *argv[]) +int main(int argc, char* argv[]) { // Create the graph, a name map that providse abstract access // to the web page names, and the weight map as an accessor to @@ -120,12 +119,11 @@ main(int argc, char *argv[]) cout << setw(12) << setiosflags(ios::left) << "vertex"; cout << setw(12) << setiosflags(ios::left) << "excluding"; cout << setw(12) << setiosflags(ios::left) << "including" << endl; - graph_traits::vertex_iterator i, end; - for(boost::tie(i, end) = vertices(g); i != end; ++i) { - cout << setw(12) << setiosflags(ios::left) - << g[*i].name - << setw(12) << get(exmap, *i) - << setw(12) << get(inmap, *i) << endl; + graph_traits< Graph >::vertex_iterator i, end; + for (boost::tie(i, end) = vertices(g); i != end; ++i) + { + cout << setw(12) << setiosflags(ios::left) << g[*i].name << setw(12) + << get(exmap, *i) << setw(12) << get(inmap, *i) << endl; } cout << "small world (excluding self-loops): " << ex << endl; cout << "small world (including self-loops): " << in << endl; @@ -133,22 +131,19 @@ main(int argc, char *argv[]) return 0; } -float -exclusive_geodesics(const Graph& g, DistanceMatrixMap dm, GeodesicMap gm) +float exclusive_geodesics(const Graph& g, DistanceMatrixMap dm, GeodesicMap gm) { // Compute the mean geodesic distances, which excludes distances // of self-loops by default. Return the measure for the entire graph. return all_mean_geodesics(g, dm, gm); } - -float -inclusive_geodesics(const Graph &g, DistanceMatrixMap dm, GeodesicMap gm) +float inclusive_geodesics(const Graph& g, DistanceMatrixMap dm, GeodesicMap gm) { // Create a new measure object for computing the mean geodesic // distance of all vertices. This measure will actually be used // for both averages. - inclusive_average m; + inclusive_average< Graph, float, float > m; // Compute the mean geodesic distance using the inclusive average // to account for self-loop distances. Return the measure for the diff --git a/example/incremental-components-eg.cpp b/example/incremental-components-eg.cpp index 7faf44188..7fead1d95 100644 --- a/example/incremental-components-eg.cpp +++ b/example/incremental-components-eg.cpp @@ -1,5 +1,5 @@ //======================================================================= -// Copyright 2001 Jeremy G. Siek, Andrew Lumsdaine, Lie-Quan Lee, +// Copyright 2001 Jeremy G. Siek, Andrew Lumsdaine, Lie-Quan Lee, // Copyright 2009 Trustees of Indiana University. // Authors: Andrew Lumsdaine, Lie-Quan Lee, Jeremy G. Siek, Michael Hansen // @@ -18,67 +18,69 @@ using namespace boost; -int main(int argc, char* argv[]) +int main(int argc, char* argv[]) { - typedef adjacency_list Graph; - typedef graph_traits::vertex_descriptor Vertex; - //typedef graph_traits::edge_descriptor Edge; - typedef graph_traits::vertices_size_type VertexIndex; - - // Create a graph - const int VERTEX_COUNT = 6; - Graph graph(VERTEX_COUNT); - - add_edge(0, 1, graph); - add_edge(1, 4, graph); - - // reate the disjoint-sets object, which requires rank and parent - // vertex properties. - std::vector rank(num_vertices(graph)); - std::vector parent(num_vertices(graph)); - - typedef VertexIndex* Rank; - typedef Vertex* Parent; - disjoint_sets ds(&rank[0], &parent[0]); - - // Determine the connected components, storing the results in the - // disjoint-sets object. - initialize_incremental_components(graph, ds); - incremental_components(graph, ds); - - // Add a couple more edges and update the disjoint-sets - add_edge(4, 0, graph); - add_edge(2, 5, graph); - - ds.union_set(4, 0); - ds.union_set(2, 5); - - BOOST_FOREACH(Vertex current_vertex, vertices(graph)) { - std::cout << "representative[" << current_vertex << "] = " << - ds.find_set(current_vertex) << std::endl; - } - - std::cout << std::endl; - - // Generate component index. NOTE: We would need to pass in a vertex - // index map into the component_index constructor if our graph type - // used listS instead of vecS (identity_property_map is used by - // default). - typedef component_index Components; - Components components(parent.begin(), parent.end()); - - // Iterate through the component indices - BOOST_FOREACH(VertexIndex component_index, components) { - std::cout << "component " << component_index << " contains: "; - - // Iterate through the child vertex indices for [component_index] - BOOST_FOREACH(VertexIndex child_index, - components[component_index]) { - std::cout << child_index << " "; + typedef adjacency_list< vecS, vecS, undirectedS > Graph; + typedef graph_traits< Graph >::vertex_descriptor Vertex; + // typedef graph_traits::edge_descriptor Edge; + typedef graph_traits< Graph >::vertices_size_type VertexIndex; + + // Create a graph + const int VERTEX_COUNT = 6; + Graph graph(VERTEX_COUNT); + + add_edge(0, 1, graph); + add_edge(1, 4, graph); + + // reate the disjoint-sets object, which requires rank and parent + // vertex properties. + std::vector< Vertex > rank(num_vertices(graph)); + std::vector< Vertex > parent(num_vertices(graph)); + + typedef VertexIndex* Rank; + typedef Vertex* Parent; + disjoint_sets< Rank, Parent > ds(&rank[0], &parent[0]); + + // Determine the connected components, storing the results in the + // disjoint-sets object. + initialize_incremental_components(graph, ds); + incremental_components(graph, ds); + + // Add a couple more edges and update the disjoint-sets + add_edge(4, 0, graph); + add_edge(2, 5, graph); + + ds.union_set(4, 0); + ds.union_set(2, 5); + + BOOST_FOREACH (Vertex current_vertex, vertices(graph)) + { + std::cout << "representative[" << current_vertex + << "] = " << ds.find_set(current_vertex) << std::endl; } std::cout << std::endl; - } - return (0); + // Generate component index. NOTE: We would need to pass in a vertex + // index map into the component_index constructor if our graph type + // used listS instead of vecS (identity_property_map is used by + // default). + typedef component_index< VertexIndex > Components; + Components components(parent.begin(), parent.end()); + + // Iterate through the component indices + BOOST_FOREACH (VertexIndex component_index, components) + { + std::cout << "component " << component_index << " contains: "; + + // Iterate through the child vertex indices for [component_index] + BOOST_FOREACH (VertexIndex child_index, components[component_index]) + { + std::cout << child_index << " "; + } + + std::cout << std::endl; + } + + return (0); } diff --git a/example/incremental_components.cpp b/example/incremental_components.cpp index f8f156ef1..249e16bde 100644 --- a/example/incremental_components.cpp +++ b/example/incremental_components.cpp @@ -25,12 +25,12 @@ Sample output: An undirected graph: - 0 <--> 1 4 - 1 <--> 0 4 - 2 <--> 5 - 3 <--> - 4 <--> 1 0 - 5 <--> 2 + 0 <--> 1 4 + 1 <--> 0 4 + 2 <--> 5 + 3 <--> + 4 <--> 1 0 + 5 <--> 2 representative[0] = 1 representative[1] = 1 @@ -39,81 +39,82 @@ representative[4] = 1 representative[5] = 5 - component 0 contains: 4 1 0 - component 1 contains: 3 - component 2 contains: 5 2 + component 0 contains: 4 1 0 + component 1 contains: 3 + component 2 contains: 5 2 */ using namespace boost; -int main(int argc, char* argv[]) +int main(int argc, char* argv[]) { - typedef adjacency_list Graph; - typedef graph_traits::vertex_descriptor Vertex; - typedef graph_traits::vertices_size_type VertexIndex; + typedef adjacency_list< vecS, vecS, undirectedS > Graph; + typedef graph_traits< Graph >::vertex_descriptor Vertex; + typedef graph_traits< Graph >::vertices_size_type VertexIndex; - const int VERTEX_COUNT = 6; - Graph graph(VERTEX_COUNT); + const int VERTEX_COUNT = 6; + Graph graph(VERTEX_COUNT); - std::vector rank(num_vertices(graph)); - std::vector parent(num_vertices(graph)); + std::vector< VertexIndex > rank(num_vertices(graph)); + std::vector< Vertex > parent(num_vertices(graph)); - typedef VertexIndex* Rank; - typedef Vertex* Parent; + typedef VertexIndex* Rank; + typedef Vertex* Parent; - disjoint_sets ds(&rank[0], &parent[0]); + disjoint_sets< Rank, Parent > ds(&rank[0], &parent[0]); - initialize_incremental_components(graph, ds); - incremental_components(graph, ds); + initialize_incremental_components(graph, ds); + incremental_components(graph, ds); - graph_traits::edge_descriptor edge; - bool flag; + graph_traits< Graph >::edge_descriptor edge; + bool flag; - boost::tie(edge, flag) = add_edge(0, 1, graph); - ds.union_set(0,1); + boost::tie(edge, flag) = add_edge(0, 1, graph); + ds.union_set(0, 1); - boost::tie(edge, flag) = add_edge(1, 4, graph); - ds.union_set(1,4); + boost::tie(edge, flag) = add_edge(1, 4, graph); + ds.union_set(1, 4); - boost::tie(edge, flag) = add_edge(4, 0, graph); - ds.union_set(4,0); + boost::tie(edge, flag) = add_edge(4, 0, graph); + ds.union_set(4, 0); - boost::tie(edge, flag) = add_edge(2, 5, graph); - ds.union_set(2,5); - - std::cout << "An undirected graph:" << std::endl; - print_graph(graph, get(boost::vertex_index, graph)); - std::cout << std::endl; - - BOOST_FOREACH(Vertex current_vertex, vertices(graph)) { - std::cout << "representative[" << current_vertex << "] = " << - ds.find_set(current_vertex) << std::endl; - } + boost::tie(edge, flag) = add_edge(2, 5, graph); + ds.union_set(2, 5); - std::cout << std::endl; + std::cout << "An undirected graph:" << std::endl; + print_graph(graph, get(boost::vertex_index, graph)); + std::cout << std::endl; - typedef component_index Components; + BOOST_FOREACH (Vertex current_vertex, vertices(graph)) + { + std::cout << "representative[" << current_vertex + << "] = " << ds.find_set(current_vertex) << std::endl; + } - // NOTE: Because we're using vecS for the graph type, we're - // effectively using identity_property_map for a vertex index map. - // If we were to use listS instead, the index map would need to be - // explicitly passed to the component_index constructor. - Components components(parent.begin(), parent.end()); + std::cout << std::endl; - // Iterate through the component indices - BOOST_FOREACH(VertexIndex current_index, components) { - std::cout << "component " << current_index << " contains: "; + typedef component_index< VertexIndex > Components; - // Iterate through the child vertex indices for [current_index] - BOOST_FOREACH(VertexIndex child_index, - components[current_index]) { - std::cout << child_index << " "; - } + // NOTE: Because we're using vecS for the graph type, we're + // effectively using identity_property_map for a vertex index map. + // If we were to use listS instead, the index map would need to be + // explicitly passed to the component_index constructor. + Components components(parent.begin(), parent.end()); - std::cout << std::endl; - } + // Iterate through the component indices + BOOST_FOREACH (VertexIndex current_index, components) + { + std::cout << "component " << current_index << " contains: "; - return (0); -} + // Iterate through the child vertex indices for [current_index] + BOOST_FOREACH (VertexIndex child_index, components[current_index]) + { + std::cout << child_index << " "; + } + + std::cout << std::endl; + } + return (0); +} diff --git a/example/incremental_components.expected b/example/incremental_components.expected index e5cdd4a63..be2e0bf7b 100644 --- a/example/incremental_components.expected +++ b/example/incremental_components.expected @@ -1,10 +1,10 @@ An undirected graph: -0 <--> 1 4 -1 <--> 0 4 -2 <--> 5 -3 <--> -4 <--> 1 0 -5 <--> 2 +0 <--> 1 4 +1 <--> 0 4 +2 <--> 5 +3 <--> +4 <--> 1 0 +5 <--> 2 representative[0] = 1 representative[1] = 1 @@ -13,6 +13,6 @@ representative[3] = 3 representative[4] = 1 representative[5] = 5 -component 0 contains: 1 4 0 -component 1 contains: 3 -component 2 contains: 5 2 +component 0 contains: 1 4 0 +component 1 contains: 3 +component 2 contains: 5 2 diff --git a/example/influence_prestige.cpp b/example/influence_prestige.cpp index e7d26f134..65abac3bf 100644 --- a/example/influence_prestige.cpp +++ b/example/influence_prestige.cpp @@ -24,23 +24,22 @@ struct Actor }; // Declare the graph type and its vertex and edge types. -typedef directed_graph Graph; -typedef graph_traits::vertex_descriptor Vertex; -typedef graph_traits::edge_descriptor Edge; +typedef directed_graph< Actor > Graph; +typedef graph_traits< Graph >::vertex_descriptor Vertex; +typedef graph_traits< Graph >::edge_descriptor Edge; // The name map provides an abstract accessor for the names of // each vertex. This is used during graph creation. -typedef property_map::type NameMap; +typedef property_map< Graph, string Actor::* >::type NameMap; // Declare a container type for influence and prestige (both // of which are degree centralities) and its corresponding // property map. -typedef exterior_vertex_property CentralityProperty; +typedef exterior_vertex_property< Graph, unsigned > CentralityProperty; typedef CentralityProperty::container_type CentralityContainer; typedef CentralityProperty::map_type CentralityMap; -int -main(int argc, char *argv[]) +int main(int argc, char* argv[]) { // Create the graph and a property map that provides // access to the actor names. @@ -61,13 +60,12 @@ main(int argc, char *argv[]) all_prestige_values(g, pm); // Print the degree centrality of each vertex - graph_traits::vertex_iterator i, end; - for(boost::tie(i, end) = vertices(g); i != end; ++i) { + graph_traits< Graph >::vertex_iterator i, end; + for (boost::tie(i, end) = vertices(g); i != end; ++i) + { Vertex v = *i; - cout << setiosflags(ios::left) << setw(12) - << g[v].name << "\t" - << im[v] << "\t" - << pm[v] << endl; + cout << setiosflags(ios::left) << setw(12) << g[v].name << "\t" << im[v] + << "\t" << pm[v] << endl; } return 0; diff --git a/example/interior_pmap_bundled.cpp b/example/interior_pmap_bundled.cpp index cee50169c..6121e8e24 100644 --- a/example/interior_pmap_bundled.cpp +++ b/example/interior_pmap_bundled.cpp @@ -45,48 +45,48 @@ using namespace boost; */ -template +template < class EdgeIter, class Graph > void who_owes_who(EdgeIter first, EdgeIter last, const Graph& G) { - while (first != last) { - cout << G[source(*first, G)].first_name << " owes " - << G[target(*first, G)].first_name << " some money" << endl; - ++first; - } + while (first != last) + { + cout << G[source(*first, G)].first_name << " owes " + << G[target(*first, G)].first_name << " some money" << endl; + ++first; + } } struct VertexData { - string first_name; + string first_name; }; -int -main() +int main() { - { - // Create the graph, and specify that we will use std::string to - // store the first name's. - typedef adjacency_list MyGraphType; - - typedef pair Pair; - Pair edge_array[11] = { Pair(0,1), Pair(0,2), Pair(0,3), Pair(0,4), - Pair(2,0), Pair(3,0), Pair(2,4), Pair(3,1), - Pair(3,4), Pair(4,0), Pair(4,1) }; - - MyGraphType G(5); - for (int i=0; i<11; ++i) - add_edge(edge_array[i].first, edge_array[i].second, G); - - G[0].first_name = "Jeremy"; - G[1].first_name = "Rich"; - G[2].first_name = "Andrew"; - G[3].first_name = "Jeff"; - G[4].first_name = "Doug"; - - who_owes_who(edges(G).first, edges(G).second, G); - } - - cout << endl; - - return 0; + { + // Create the graph, and specify that we will use std::string to + // store the first name's. + typedef adjacency_list< vecS, vecS, directedS, VertexData > MyGraphType; + + typedef pair< int, int > Pair; + Pair edge_array[11] = { Pair(0, 1), Pair(0, 2), Pair(0, 3), Pair(0, 4), + Pair(2, 0), Pair(3, 0), Pair(2, 4), Pair(3, 1), Pair(3, 4), + Pair(4, 0), Pair(4, 1) }; + + MyGraphType G(5); + for (int i = 0; i < 11; ++i) + add_edge(edge_array[i].first, edge_array[i].second, G); + + G[0].first_name = "Jeremy"; + G[1].first_name = "Rich"; + G[2].first_name = "Andrew"; + G[3].first_name = "Jeff"; + G[4].first_name = "Doug"; + + who_owes_who(edges(G).first, edges(G).second, G); + } + + cout << endl; + + return 0; } diff --git a/example/interior_property_map.cpp b/example/interior_property_map.cpp index 7083d6639..9a9b7e2d6 100644 --- a/example/interior_property_map.cpp +++ b/example/interior_property_map.cpp @@ -46,63 +46,67 @@ using namespace boost; // create a tag for our new property -enum vertex_first_name_t { vertex_first_name }; -namespace boost { - BOOST_INSTALL_PROPERTY(vertex, first_name); +enum vertex_first_name_t +{ + vertex_first_name +}; +namespace boost +{ +BOOST_INSTALL_PROPERTY(vertex, first_name); } -template +template < class EdgeIter, class Graph > void who_owes_who(EdgeIter first, EdgeIter last, const Graph& G) { - // Access the propety acessor type for this graph - typedef typename property_map - ::const_type NamePA; - NamePA name = get(vertex_first_name, G); - - typedef typename boost::property_traits::value_type NameType; - - NameType src_name, targ_name; - - while (first != last) { - src_name = boost::get(name, source(*first,G)); - targ_name = boost::get(name, target(*first,G)); - cout << src_name << " owes " - << targ_name << " some money" << endl; - ++first; - } + // Access the propety acessor type for this graph + typedef + typename property_map< Graph, vertex_first_name_t >::const_type NamePA; + NamePA name = get(vertex_first_name, G); + + typedef typename boost::property_traits< NamePA >::value_type NameType; + + NameType src_name, targ_name; + + while (first != last) + { + src_name = boost::get(name, source(*first, G)); + targ_name = boost::get(name, target(*first, G)); + cout << src_name << " owes " << targ_name << " some money" << endl; + ++first; + } } -int -main() +int main() { - { - // Create the graph, and specify that we will use std::string to - // store the first name's. - typedef adjacency_list > MyGraphType; - - typedef pair Pair; - Pair edge_array[11] = { Pair(0,1), Pair(0,2), Pair(0,3), Pair(0,4), - Pair(2,0), Pair(3,0), Pair(2,4), Pair(3,1), - Pair(3,4), Pair(4,0), Pair(4,1) }; - - MyGraphType G(5); - for (int i=0; i<11; ++i) - add_edge(edge_array[i].first, edge_array[i].second, G); - - property_map::type name - = get(vertex_first_name, G); - - boost::put(name, 0, "Jeremy"); - boost::put(name, 1, "Rich"); - boost::put(name, 2, "Andrew"); - boost::put(name, 3, "Jeff"); - name[4] = "Kinis"; // you can use operator[] too - - who_owes_who(edges(G).first, edges(G).second, G); - } - - cout << endl; - - return 0; + { + // Create the graph, and specify that we will use std::string to + // store the first name's. + typedef adjacency_list< vecS, vecS, directedS, + property< vertex_first_name_t, std::string > > + MyGraphType; + + typedef pair< int, int > Pair; + Pair edge_array[11] = { Pair(0, 1), Pair(0, 2), Pair(0, 3), Pair(0, 4), + Pair(2, 0), Pair(3, 0), Pair(2, 4), Pair(3, 1), Pair(3, 4), + Pair(4, 0), Pair(4, 1) }; + + MyGraphType G(5); + for (int i = 0; i < 11; ++i) + add_edge(edge_array[i].first, edge_array[i].second, G); + + property_map< MyGraphType, vertex_first_name_t >::type name + = get(vertex_first_name, G); + + boost::put(name, 0, "Jeremy"); + boost::put(name, 1, "Rich"); + boost::put(name, 2, "Andrew"); + boost::put(name, 3, "Jeff"); + name[4] = "Kinis"; // you can use operator[] too + + who_owes_who(edges(G).first, edges(G).second, G); + } + + cout << endl; + + return 0; } diff --git a/example/iohb.c b/example/iohb.c index eac5abecb..8a216358d 100644 --- a/example/iohb.c +++ b/example/iohb.c @@ -1,4 +1,4 @@ -// (C) Copyright Jeremy Siek 2004 +// (C) Copyright Jeremy Siek 2004 // Distributed under the Boost Software License, Version 1.0. (See // accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) @@ -22,8 +22,8 @@ Fri Aug 15 16:29:47 EDT 1997 supporting documentation. Neither the Author nor the Institution (National Institute of Standards - and Technology) make any representations about the suitability of this - software for any purpose. This software is provided "as is" without + and Technology) make any representations about the suitability of this + software for any purpose. This software is provided "as is" without expressed or implied warranty. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ @@ -46,21 +46,21 @@ Fri Aug 15 16:29:47 EDT 1997 and columns in the stored matrix (M and N), the number of nonzeros in the matrix (nz), the 3-character matrix type(Type), and the number of right-hand-sides stored along with the matrix (Nrhs). This function - is designed to retrieve basic size information which can be used to + is designed to retrieve basic size information which can be used to allocate arrays. FUNCTION: - int readHB_header(FILE* in_file, char* Title, char* Key, char* Type, + int readHB_header(FILE* in_file, char* Title, char* Key, char* Type, int* Nrow, int* Ncol, int* Nnzero, int* Nrhs, - char* Ptrfmt, char* Indfmt, char* Valfmt, char* Rhsfmt, - int* Ptrcrd, int* Indcrd, int* Valcrd, int* Rhscrd, + char* Ptrfmt, char* Indfmt, char* Valfmt, char* Rhsfmt, + int* Ptrcrd, int* Indcrd, int* Valcrd, int* Rhscrd, char *Rhstype) DESCRIPTION: - More detailed than the readHB_info function, readHB_header() reads from - the specified Harwell-Boeing file all of the header information. + More detailed than the readHB_info function, readHB_header() reads from + the specified Harwell-Boeing file all of the header information. ------------------------------ @@ -82,7 +82,7 @@ Fri Aug 15 16:29:47 EDT 1997 format. (See readHB_aux_double to read auxillary vectors.) -- Values are interpreted as double precision numbers. -- - The "mat" function uses _pre-allocated_ vectors to hold the index and + The "mat" function uses _pre-allocated_ vectors to hold the index and nonzero value information. The "newmat" function allocates vectors to hold the index and nonzero @@ -101,11 +101,11 @@ Fri Aug 15 16:29:47 EDT 1997 The char argument Auxtype determines which type of auxillary vector(s) will be read (if present in the file). - AuxType = 'F' right-hand-side + AuxType = 'F' right-hand-side AuxType = 'G' initial estimate (Guess) AuxType = 'X' eXact solution - If Nrhs > 1, all of the Nrhs vectors of the given type are read and + If Nrhs > 1, all of the Nrhs vectors of the given type are read and stored in column-major order in the vector b. The "newaux" function allocates a vector to hold the values retrieved. @@ -113,11 +113,11 @@ Fri Aug 15 16:29:47 EDT 1997 FUNCTION: - int writeHB_mat_double(const char* filename, int M, int N, - int nz, const int colptr[], const int rowind[], - const double val[], int Nrhs, const double rhs[], + int writeHB_mat_double(const char* filename, int M, int N, + int nz, const int colptr[], const int rowind[], + const double val[], int Nrhs, const double rhs[], const double guess[], const double exact[], - const char* Title, const char* Key, const char* Type, + const char* Title, const char* Key, const char* Type, char* Ptrfmt, char* Indfmt, char* Valfmt, char* Rhsfmt, const char* Rhstype) @@ -135,16 +135,16 @@ Fri Aug 15 16:29:47 EDT 1997 Valfmt = Rhsfmt = "(4E20.13)" ----------------------- - CHARACTER I/O FUNCTIONS + CHARACTER I/O FUNCTIONS ----------------------- - FUNCTION: + FUNCTION: - int readHB_mat_char(const char* filename, int colptr[], int rowind[], + int readHB_mat_char(const char* filename, int colptr[], int rowind[], char val[], char* Valfmt) - int readHB_newmat_char(const char* filename, int* M, int* N, int* nonzeros, + int readHB_newmat_char(const char* filename, int* M, int* N, int* nonzeros, int** colptr, int** rowind, char** val, char** Valfmt) - DESCRIPTION: + DESCRIPTION: This function opens and reads the specified file, interpreting its contents as a sparse matrix stored in the Harwell/Boeing standard @@ -152,17 +152,17 @@ Fri Aug 15 16:29:47 EDT 1997 -- Values are interpreted as char strings. -- (Used to translate exact values from the file into a new storage format.) - The "mat" function uses _pre-allocated_ arrays to hold the index and + The "mat" function uses _pre-allocated_ arrays to hold the index and nonzero value information. - The "newmat" function allocates char arrays to hold the index - and nonzero value information, and returns pointers to these arrays + The "newmat" function allocates char arrays to hold the index + and nonzero value information, and returns pointers to these arrays along with matrix dimension and number of nonzeros. FUNCTION: int readHB_aux_char(const char* filename, const char AuxType, char b[]) - int readHB_newaux_char(const char* filename, const char AuxType, char** b, + int readHB_newaux_char(const char* filename, const char AuxType, char** b, char** Rhsfmt) DESCRIPTION: @@ -171,24 +171,24 @@ Fri Aug 15 16:29:47 EDT 1997 The char argument Auxtype determines which type of auxillary vector(s) will be read (if present in the file). - AuxType = 'F' right-hand-side + AuxType = 'F' right-hand-side AuxType = 'G' initial estimate (Guess) AuxType = 'X' eXact solution - If Nrhs > 1, all of the Nrhs vectors of the given type are read and + If Nrhs > 1, all of the Nrhs vectors of the given type are read and stored in column-major order in the vector b. - The "newaux" function allocates a character array to hold the values + The "newaux" function allocates a character array to hold the values retrieved. The "mat" function uses a _pre-allocated_ array to hold the values. FUNCTION: - int writeHB_mat_char(const char* filename, int M, int N, - int nz, const int colptr[], const int rowind[], - const char val[], int Nrhs, const char rhs[], - const char guess[], const char exact[], - const char* Title, const char* Key, const char* Type, + int writeHB_mat_char(const char* filename, int M, int N, + int nz, const int colptr[], const int rowind[], + const char val[], int Nrhs, const char rhs[], + const char guess[], const char exact[], + const char* Title, const char* Key, const char* Type, char* Ptrfmt, char* Indfmt, char* Valfmt, char* Rhsfmt, const char* Rhstype) @@ -198,9 +198,9 @@ Fri Aug 15 16:29:47 EDT 1997 matrix and optional auxillary vector(s) to that file in Harwell-Boeing format. The format arguments (Ptrfmt,Indfmt,Valfmt, and Rhsfmt) are character strings specifying "Fortran-style" output formats -- as they - would appear in a Harwell-Boeing file. Valfmt and Rhsfmt must accurately - represent the character representation of the values stored in val[] - and rhs[]. + would appear in a Harwell-Boeing file. Valfmt and Rhsfmt must accurately + represent the character representation of the values stored in val[] + and rhs[]. If NULL, the following defaults will be used for the integer vectors: Ptrfmt = Indfmt = "(8I10)" @@ -229,7 +229,7 @@ char* substr(const char* S, const int pos, const int len); void upcase(char* S); void IOHBTerminate(const char* message); -int readHB_info(const char* filename, int* M, int* N, int* nz, char** Type, +int readHB_info(const char* filename, int* M, int* N, int* nz, char** Type, int* Nrhs) { /****************************************************************************/ @@ -250,7 +250,7 @@ int readHB_info(const char* filename, int* M, int* N, int* nz, char** Type, /* */ /****************************************************************************/ FILE *in_file; - int Ptrcrd, Indcrd, Valcrd, Rhscrd; + int Ptrcrd, Indcrd, Valcrd, Rhscrd; int Nrow, Ncol, Nnzero; char* mat_type; char Title[73], Key[9], Rhstype[4]; @@ -258,14 +258,14 @@ int readHB_info(const char* filename, int* M, int* N, int* nz, char** Type, mat_type = *Type; if ( mat_type == NULL ) IOHBTerminate("Insufficient memory for mat_typen"); - + if ( (in_file = fopen( filename, "r")) == NULL ) { fprintf(stderr,"Error: Cannot open file: %s\n",filename); return 0; } readHB_header(in_file, Title, Key, mat_type, &Nrow, &Ncol, &Nnzero, Nrhs, - Ptrfmt, Indfmt, Valfmt, Rhsfmt, + Ptrfmt, Indfmt, Valfmt, Rhsfmt, &Ptrcrd, &Indcrd, &Valcrd, &Rhscrd, Rhstype); fclose(in_file); *Type = mat_type; @@ -282,22 +282,22 @@ int readHB_info(const char* filename, int* M, int* N, int* nz, char** Type, printf("Reading from Harwell-Boeing file %s (verbose on)...\n",filename); printf(" Title: %s\n",Title); printf(" Key: %s\n",Key); - printf(" The stored matrix is %i by %i with %i nonzeros.\n", + printf(" The stored matrix is %i by %i with %i nonzeros.\n", *M, *N, *nz ); printf(" %i right-hand--side(s) stored.\n",*Nrhs); } */ - + return 1; } -int readHB_header(FILE* in_file, char* Title, char* Key, char* Type, +int readHB_header(FILE* in_file, char* Title, char* Key, char* Type, int* Nrow, int* Ncol, int* Nnzero, int* Nrhs, - char* Ptrfmt, char* Indfmt, char* Valfmt, char* Rhsfmt, - int* Ptrcrd, int* Indcrd, int* Valcrd, int* Rhscrd, + char* Ptrfmt, char* Indfmt, char* Valfmt, char* Rhsfmt, + int* Ptrcrd, int* Indcrd, int* Valcrd, int* Rhscrd, char *Rhstype) { /*************************************************************************/ @@ -308,7 +308,7 @@ int readHB_header(FILE* in_file, char* Title, char* Key, char* Type, /* First line: */ fgets(line, BUFSIZ, in_file); - if ( sscanf(line,"%*s") < 0 ) + if ( sscanf(line,"%*s") < 0 ) IOHBTerminate("iohb.c: Null (or blank) first line of HB file.\n"); (void) sscanf(line, "%72c%8[^\n]", Title, Key); *(Key+8) = (char) NULL; @@ -316,7 +316,7 @@ int readHB_header(FILE* in_file, char* Title, char* Key, char* Type, /* Second line: */ fgets(line, BUFSIZ, in_file); - if ( sscanf(line,"%*s") < 0 ) + if ( sscanf(line,"%*s") < 0 ) IOHBTerminate("iohb.c: Null (or blank) second line of HB file.\n"); if ( sscanf(line,"%i",&Totcrd) != 1) Totcrd = 0; if ( sscanf(line,"%*i%i",Ptrcrd) != 1) *Ptrcrd = 0; @@ -326,9 +326,9 @@ int readHB_header(FILE* in_file, char* Title, char* Key, char* Type, /* Third line: */ fgets(line, BUFSIZ, in_file); - if ( sscanf(line,"%*s") < 0 ) + if ( sscanf(line,"%*s") < 0 ) IOHBTerminate("iohb.c: Null (or blank) third line of HB file.\n"); - if ( sscanf(line, "%3c", Type) != 1) + if ( sscanf(line, "%3c", Type) != 1) IOHBTerminate("iohb.c: Invalid Type info, line 3 of Harwell-Boeing file.\n"); upcase(Type); if ( sscanf(line,"%*3c%i",Nrow) != 1) *Nrow = 0 ; @@ -338,27 +338,27 @@ int readHB_header(FILE* in_file, char* Title, char* Key, char* Type, /* Fourth line: */ fgets(line, BUFSIZ, in_file); - if ( sscanf(line,"%*s") < 0 ) + if ( sscanf(line,"%*s") < 0 ) IOHBTerminate("iohb.c: Null (or blank) fourth line of HB file.\n"); if ( sscanf(line, "%16c",Ptrfmt) != 1) - IOHBTerminate("iohb.c: Invalid format info, line 4 of Harwell-Boeing file.\n"); + IOHBTerminate("iohb.c: Invalid format info, line 4 of Harwell-Boeing file.\n"); if ( sscanf(line, "%*16c%16c",Indfmt) != 1) - IOHBTerminate("iohb.c: Invalid format info, line 4 of Harwell-Boeing file.\n"); - if ( sscanf(line, "%*16c%*16c%20c",Valfmt) != 1) - IOHBTerminate("iohb.c: Invalid format info, line 4 of Harwell-Boeing file.\n"); + IOHBTerminate("iohb.c: Invalid format info, line 4 of Harwell-Boeing file.\n"); + if ( sscanf(line, "%*16c%*16c%20c",Valfmt) != 1) + IOHBTerminate("iohb.c: Invalid format info, line 4 of Harwell-Boeing file.\n"); sscanf(line, "%*16c%*16c%*20c%20c",Rhsfmt); *(Ptrfmt+16) = (char) NULL; *(Indfmt+16) = (char) NULL; *(Valfmt+20) = (char) NULL; *(Rhsfmt+20) = (char) NULL; - + /* (Optional) Fifth line: */ if (*Rhscrd != 0 ) - { + { fgets(line, BUFSIZ, in_file); - if ( sscanf(line,"%*s") < 0 ) + if ( sscanf(line,"%*s") < 0 ) IOHBTerminate("iohb.c: Null (or blank) fifth line of HB file.\n"); - if ( sscanf(line, "%3c", Rhstype) != 1) + if ( sscanf(line, "%3c", Rhstype) != 1) IOHBTerminate("iohb.c: Invalid RHS type information, line 5 of Harwell-Boeing file.\n"); if ( sscanf(line, "%*3c%i", Nrhs) != 1) *Nrhs = 0; if ( sscanf(line, "%*3c%*i%i", &Nrhsix) != 1) Nrhsix = 0; @@ -367,7 +367,7 @@ int readHB_header(FILE* in_file, char* Title, char* Key, char* Type, } -int readHB_mat_double(const char* filename, int colptr[], int rowind[], +int readHB_mat_double(const char* filename, int colptr[], int rowind[], double val[]) { /****************************************************************************/ @@ -428,7 +428,7 @@ int readHB_mat_double(const char* filename, int colptr[], int rowind[], for (i=0;i=0;j--) { ThisElement[j] = ThisElement[j-1]; if ( ThisElement[j] == '+' || ThisElement[j] == '-' ) { - ThisElement[j-1] = Valflag; + ThisElement[j-1] = Valflag; break; } } @@ -513,7 +513,7 @@ int readHB_mat_double(const char* filename, int colptr[], int rowind[], return 1; } -int readHB_newmat_double(const char* filename, int* M, int* N, int* nonzeros, +int readHB_newmat_double(const char* filename, int* M, int* N, int* nonzeros, int** colptr, int** rowind, double** val) { int Nrhs; @@ -534,7 +534,7 @@ int readHB_newmat_double(const char* filename, int* M, int* N, int* nonzeros, *val = (double *)malloc(*nonzeros*sizeof(double)*2); if ( *val == NULL ) IOHBTerminate("Insufficient memory for val.\n"); } else { - if ( Type[0] != 'P' ) { + if ( Type[0] != 'P' ) { /* Malloc enough space for real array val[] */ *val = (double *)malloc(*nonzeros*sizeof(double)); if ( *val == NULL ) IOHBTerminate("Insufficient memory for val.\n"); @@ -600,7 +600,7 @@ int readHB_aux_double(const char* filename, const char AuxType, double b[]) return 0; } -/* If reading complex data, allow for interleaved real and imaginary values. */ +/* If reading complex data, allow for interleaved real and imaginary values. */ if ( Type[0] == 'C' ) { Nentries = 2*Nrow; } else { @@ -608,7 +608,7 @@ int readHB_aux_double(const char* filename, const char AuxType, double b[]) } nvecs = 1; - + if ( Rhstype[1] == 'G' ) nvecs++; if ( Rhstype[2] == 'X' ) nvecs++; @@ -675,13 +675,13 @@ int readHB_aux_double(const char* filename, const char AuxType, double b[]) } strncpy(ThisElement,line+col,Rhswidth); /*ThisElement = substr(line, col, Rhswidth);*/ - if ( Rhsflag != 'F' && strchr(ThisElement,'E') == NULL ) { + if ( Rhsflag != 'F' && strchr(ThisElement,'E') == NULL ) { /* insert a char prefix for exp */ last = strlen(ThisElement); for (j=last+1;j>=0;j--) { ThisElement[j] = ThisElement[j-1]; if ( ThisElement[j] == '+' || ThisElement[j] == '-' ) { - ThisElement[j-1] = Rhsflag; + ThisElement[j-1] = Rhsflag; break; } } @@ -689,7 +689,7 @@ int readHB_aux_double(const char* filename, const char AuxType, double b[]) b[i] = atof(ThisElement); col += Rhswidth; } - + /* Skip any interleaved Guess/eXact vectors */ for (i=0;i=0;j--) { ThisElement[j] = ThisElement[j-1]; if ( ThisElement[j] == '+' || ThisElement[j] == '-' ) { - ThisElement[j-1] = Valflag; + ThisElement[j-1] = Valflag; break; } } @@ -1061,7 +1061,7 @@ int readHB_mat_char(const char* filename, int colptr[], int rowind[], return 1; } -int readHB_newmat_char(const char* filename, int* M, int* N, int* nonzeros, int** colptr, +int readHB_newmat_char(const char* filename, int* M, int* N, int* nonzeros, int** colptr, int** rowind, char** val, char** Valfmt) { FILE *in_file; @@ -1076,7 +1076,7 @@ int readHB_newmat_char(const char* filename, int* M, int* N, int* nonzeros, int* fprintf(stderr,"Error: Cannot open file: %s\n",filename); return 0; } - + *Valfmt = (char *)malloc(21*sizeof(char)); if ( *Valfmt == NULL ) IOHBTerminate("Insufficient memory for Valfmt."); readHB_header(in_file, Title, Key, Type, M, N, nonzeros, &Nrhs, @@ -1098,7 +1098,7 @@ int readHB_newmat_char(const char* filename, int* M, int* N, int* nonzeros, int* *val = (char *)malloc(*nonzeros*Valwidth*sizeof(char)*2); if ( *val == NULL ) IOHBTerminate("Insufficient memory for val.\n"); } else { - if ( Type[0] != 'P' ) { + if ( Type[0] != 'P' ) { /* Malloc enough space for real array val[] */ *val = (char *)malloc(*nonzeros*Valwidth*sizeof(char)); if ( *val == NULL ) IOHBTerminate("Insufficient memory for val.\n"); @@ -1163,7 +1163,7 @@ int readHB_aux_char(const char* filename, const char AuxType, char b[]) return 0; } -/* If reading complex data, allow for interleaved real and imaginary values. */ +/* If reading complex data, allow for interleaved real and imaginary values. */ if ( Type[0] == 'C' ) { Nentries = 2*Nrow; } else { @@ -1171,7 +1171,7 @@ int readHB_aux_char(const char* filename, const char AuxType, char b[]) } nvecs = 1; - + if ( Rhstype[1] == 'G' ) nvecs++; if ( Rhstype[2] == 'X' ) nvecs++; @@ -1204,7 +1204,7 @@ int readHB_aux_char(const char* filename, const char AuxType, char b[]) fgets(line, BUFSIZ, in_file); linel= strchr(line,'\n')-line; - if ( sscanf(line,"%*s") < 0 ) + if ( sscanf(line,"%*s") < 0 ) IOHBTerminate("iohb.c: Null (or blank) line in auxillary vector data region of HB file.\n"); col = 0; /* Skip to initial offset */ @@ -1214,7 +1214,7 @@ int readHB_aux_char(const char* filename, const char AuxType, char b[]) if ( col >= ( maxcol= ( maxcol=0;j--) { ThisElement[j] = ThisElement[j-1]; if ( ThisElement[j] == '+' || ThisElement[j] == '-' ) { - ThisElement[j-1] = Rhsflag; + ThisElement[j-1] = Rhsflag; break; } } @@ -1255,7 +1255,7 @@ int readHB_aux_char(const char* filename, const char AuxType, char b[]) col += Rhswidth; } b+=Nentries*Rhswidth; - + /* Skip any interleaved Guess/eXact vectors */ for (i=0;i= ( maxcol -#include +#include +#include #ifdef __cplusplus -extern "C" { +extern "C" +{ #endif -int readHB_info(const char* filename, int* M, int* N, int* nz, char** Type, - int* Nrhs); + int readHB_info( + const char* filename, int* M, int* N, int* nz, char** Type, int* Nrhs); -int readHB_header(FILE* in_file, char* Title, char* Key, char* Type, - int* Nrow, int* Ncol, int* Nnzero, int* Nrhs, - char* Ptrfmt, char* Indfmt, char* Valfmt, char* Rhsfmt, - int* Ptrcrd, int* Indcrd, int* Valcrd, int* Rhscrd, - char *Rhstype); + int readHB_header(FILE* in_file, char* Title, char* Key, char* Type, + int* Nrow, int* Ncol, int* Nnzero, int* Nrhs, char* Ptrfmt, + char* Indfmt, char* Valfmt, char* Rhsfmt, int* Ptrcrd, int* Indcrd, + int* Valcrd, int* Rhscrd, char* Rhstype); -int readHB_mat_double(const char* filename, int colptr[], int rowind[], - double val[]); + int readHB_mat_double( + const char* filename, int colptr[], int rowind[], double val[]); -int readHB_newmat_double(const char* filename, int* M, int* N, int* nonzeros, - int** colptr, int** rowind, double** val); + int readHB_newmat_double(const char* filename, int* M, int* N, + int* nonzeros, int** colptr, int** rowind, double** val); -int readHB_aux_double(const char* filename, const char AuxType, double b[]); + int readHB_aux_double(const char* filename, const char AuxType, double b[]); -int readHB_newaux_double(const char* filename, const char AuxType, double** b); + int readHB_newaux_double( + const char* filename, const char AuxType, double** b); -int writeHB_mat_double(const char* filename, int M, int N, - int nz, const int colptr[], const int rowind[], - const double val[], int Nrhs, const double rhs[], - const double guess[], const double exact[], - const char* Title, const char* Key, const char* Type, - char* Ptrfmt, char* Indfmt, char* Valfmt, char* Rhsfmt, - const char* Rhstype); + int writeHB_mat_double(const char* filename, int M, int N, int nz, + const int colptr[], const int rowind[], const double val[], int Nrhs, + const double rhs[], const double guess[], const double exact[], + const char* Title, const char* Key, const char* Type, char* Ptrfmt, + char* Indfmt, char* Valfmt, char* Rhsfmt, const char* Rhstype); -int readHB_mat_char(const char* filename, int colptr[], int rowind[], - char val[], char* Valfmt); + int readHB_mat_char(const char* filename, int colptr[], int rowind[], + char val[], char* Valfmt); -int readHB_newmat_char(const char* filename, int* M, int* N, int* nonzeros, int** colptr, - int** rowind, char** val, char** Valfmt); + int readHB_newmat_char(const char* filename, int* M, int* N, int* nonzeros, + int** colptr, int** rowind, char** val, char** Valfmt); -int readHB_aux_char(const char* filename, const char AuxType, char b[]); + int readHB_aux_char(const char* filename, const char AuxType, char b[]); -int readHB_newaux_char(const char* filename, const char AuxType, char** b, char** Rhsfmt); + int readHB_newaux_char( + const char* filename, const char AuxType, char** b, char** Rhsfmt); -int writeHB_mat_char(const char* filename, int M, int N, - int nz, const int colptr[], const int rowind[], - const char val[], int Nrhs, const char rhs[], - const char guess[], const char exact[], - const char* Title, const char* Key, const char* Type, - char* Ptrfmt, char* Indfmt, char* Valfmt, char* Rhsfmt, - const char* Rhstype); + int writeHB_mat_char(const char* filename, int M, int N, int nz, + const int colptr[], const int rowind[], const char val[], int Nrhs, + const char rhs[], const char guess[], const char exact[], + const char* Title, const char* Key, const char* Type, char* Ptrfmt, + char* Indfmt, char* Valfmt, char* Rhsfmt, const char* Rhstype); -int ParseIfmt(char* fmt, int* perline, int* width); + int ParseIfmt(char* fmt, int* perline, int* width); -int ParseRfmt(char* fmt, int* perline, int* width, int* prec, int* flag); + int ParseRfmt(char* fmt, int* perline, int* width, int* prec, int* flag); -void IOHBTerminate(const char* message); + void IOHBTerminate(const char* message); #ifdef __cplusplus } #endif diff --git a/example/isomorphism.cpp b/example/isomorphism.cpp index c11d70fa9..6a21520b4 100644 --- a/example/isomorphism.cpp +++ b/example/isomorphism.cpp @@ -13,70 +13,83 @@ /* Sample output: isomorphic? 1 - f: 9 10 11 0 1 3 2 4 6 8 7 5 + f: 9 10 11 0 1 3 2 4 6 8 7 5 */ -int -main() +int main() { - using namespace boost; - - const int n = 12; + using namespace boost; - typedef adjacency_list > graph_t; - graph_t g1(n), g2(n); + const int n = 12; - std::vector::vertex_descriptor> v1(n), v2(n); + typedef adjacency_list< vecS, listS, undirectedS, + property< vertex_index_t, int > > + graph_t; + graph_t g1(n), g2(n); - property_map::type - v1_index_map = get(vertex_index, g1), - v2_index_map = get(vertex_index, g2); + std::vector< graph_traits< graph_t >::vertex_descriptor > v1(n), v2(n); - graph_traits::vertex_iterator i, end; - int id = 0; - for (boost::tie(i, end) = vertices(g1); i != end; ++i, ++id) { - put(v1_index_map, *i, id); - v1[id] = *i; - } - id = 0; - for (boost::tie(i, end) = vertices(g2); i != end; ++i, ++id) { - put(v2_index_map, *i, id); - v2[id] = *i; - } - add_edge(v1[0], v1[1], g1); add_edge(v1[1], v1[2], g1); - add_edge(v1[0], v1[2], g1); - add_edge(v1[3], v1[4], g1); add_edge(v1[4], v1[5], g1); - add_edge(v1[5], v1[6], g1); add_edge(v1[6], v1[3], g1); - add_edge(v1[7], v1[8], g1); add_edge(v1[8], v1[9], g1); - add_edge(v1[9], v1[10], g1); - add_edge(v1[10], v1[11], g1); add_edge(v1[11], v1[7], g1); + property_map< graph_t, vertex_index_t >::type v1_index_map + = get(vertex_index, g1), + v2_index_map = get(vertex_index, g2); - add_edge(v2[9], v2[10], g2); add_edge(v2[10], v2[11], g2); - add_edge(v2[11], v2[9], g2); - add_edge(v2[0], v2[1], g2); add_edge(v2[1], v2[3], g2); - add_edge(v2[3], v2[2], g2); add_edge(v2[2], v2[0], g2); - add_edge(v2[4], v2[5], g2); add_edge(v2[5], v2[7], g2); - add_edge(v2[7], v2[8], g2); - add_edge(v2[8], v2[6], g2); add_edge(v2[6], v2[4], g2); + graph_traits< graph_t >::vertex_iterator i, end; + int id = 0; + for (boost::tie(i, end) = vertices(g1); i != end; ++i, ++id) + { + put(v1_index_map, *i, id); + v1[id] = *i; + } + id = 0; + for (boost::tie(i, end) = vertices(g2); i != end; ++i, ++id) + { + put(v2_index_map, *i, id); + v2[id] = *i; + } + add_edge(v1[0], v1[1], g1); + add_edge(v1[1], v1[2], g1); + add_edge(v1[0], v1[2], g1); + add_edge(v1[3], v1[4], g1); + add_edge(v1[4], v1[5], g1); + add_edge(v1[5], v1[6], g1); + add_edge(v1[6], v1[3], g1); + add_edge(v1[7], v1[8], g1); + add_edge(v1[8], v1[9], g1); + add_edge(v1[9], v1[10], g1); + add_edge(v1[10], v1[11], g1); + add_edge(v1[11], v1[7], g1); - std::vector::vertex_descriptor> f(n); + add_edge(v2[9], v2[10], g2); + add_edge(v2[10], v2[11], g2); + add_edge(v2[11], v2[9], g2); + add_edge(v2[0], v2[1], g2); + add_edge(v2[1], v2[3], g2); + add_edge(v2[3], v2[2], g2); + add_edge(v2[2], v2[0], g2); + add_edge(v2[4], v2[5], g2); + add_edge(v2[5], v2[7], g2); + add_edge(v2[7], v2[8], g2); + add_edge(v2[8], v2[6], g2); + add_edge(v2[6], v2[4], g2); + + std::vector< graph_traits< graph_t >::vertex_descriptor > f(n); #if defined(BOOST_MSVC) && BOOST_MSVC <= 1300 - bool ret = isomorphism - (g1, g2, make_iterator_property_map(f.begin(), v1_index_map, f[0]), - degree_vertex_invariant(), get(vertex_index, g1), get(vertex_index, g2)); + bool ret = isomorphism(g1, g2, + make_iterator_property_map(f.begin(), v1_index_map, f[0]), + degree_vertex_invariant(), get(vertex_index, g1), + get(vertex_index, g2)); #else - bool ret = isomorphism - (g1, g2, isomorphism_map - (make_iterator_property_map(f.begin(), v1_index_map, f[0]))); + bool ret = isomorphism(g1, g2, + isomorphism_map( + make_iterator_property_map(f.begin(), v1_index_map, f[0]))); #endif - std::cout << "isomorphic? " << ret << std::endl; + std::cout << "isomorphic? " << ret << std::endl; + + std::cout << "f: "; + for (std::size_t v = 0; v != f.size(); ++v) + std::cout << get(get(vertex_index, g2), f[v]) << " "; + std::cout << std::endl; - std::cout << "f: "; - for (std::size_t v = 0; v != f.size(); ++v) - std::cout << get(get(vertex_index, g2), f[v]) << " "; - std::cout << std::endl; - - return 0; + return 0; } diff --git a/example/iteration_macros.cpp b/example/iteration_macros.cpp index aacd1b0ef..ef2b08b27 100644 --- a/example/iteration_macros.cpp +++ b/example/iteration_macros.cpp @@ -10,46 +10,56 @@ #ifdef BOOST_MSVC // Without this we get hard errors, not warnings: -#pragma warning(disable:4703) +#pragma warning(disable : 4703) #endif #include #include #include -enum family { Jeanie, Debbie, Rick, John, Amanda, Margaret, Benjamin, N }; +enum family +{ + Jeanie, + Debbie, + Rick, + John, + Amanda, + Margaret, + Benjamin, + N +}; int main() { - using namespace boost; - const char *name[] = { "Jeanie", "Debbie", "Rick", "John", "Amanda", - "Margaret", "Benjamin" - }; - - adjacency_list <> g(N); - add_edge(Jeanie, Debbie, g); - add_edge(Jeanie, Rick, g); - add_edge(Jeanie, John, g); - add_edge(Debbie, Amanda, g); - add_edge(Rick, Margaret, g); - add_edge(John, Benjamin, g); - - graph_traits >::vertex_iterator i, end; - graph_traits >::adjacency_iterator ai, a_end; - property_map, vertex_index_t>::type - index_map = get(vertex_index, g); - - BGL_FORALL_VERTICES(i, g, adjacency_list<>) { - std::cout << name[get(index_map, i)]; - - if (out_degree(i, g) == 0) - std::cout << " has no children"; - else - std::cout << " is the parent of "; - - BGL_FORALL_ADJ(i, j, g, adjacency_list<>) - std::cout << name[get(index_map, j)] << ", "; - std::cout << std::endl; - } - return EXIT_SUCCESS; + using namespace boost; + const char* name[] = { "Jeanie", "Debbie", "Rick", "John", "Amanda", + "Margaret", "Benjamin" }; + + adjacency_list<> g(N); + add_edge(Jeanie, Debbie, g); + add_edge(Jeanie, Rick, g); + add_edge(Jeanie, John, g); + add_edge(Debbie, Amanda, g); + add_edge(Rick, Margaret, g); + add_edge(John, Benjamin, g); + + graph_traits< adjacency_list<> >::vertex_iterator i, end; + graph_traits< adjacency_list<> >::adjacency_iterator ai, a_end; + property_map< adjacency_list<>, vertex_index_t >::type index_map + = get(vertex_index, g); + + BGL_FORALL_VERTICES(i, g, adjacency_list<>) + { + std::cout << name[get(index_map, i)]; + + if (out_degree(i, g) == 0) + std::cout << " has no children"; + else + std::cout << " is the parent of "; + + BGL_FORALL_ADJ(i, j, g, adjacency_list<>) + std::cout << name[get(index_map, j)] << ", "; + std::cout << std::endl; + } + return EXIT_SUCCESS; } diff --git a/example/iterator-property-map-eg.cpp b/example/iterator-property-map-eg.cpp index 9257af4ee..a14923667 100644 --- a/example/iterator-property-map-eg.cpp +++ b/example/iterator-property-map-eg.cpp @@ -1,5 +1,5 @@ //======================================================================= -// Copyright 2001 Jeremy G. Siek, Andrew Lumsdaine, Lie-Quan Lee, +// Copyright 2001 Jeremy G. Siek, Andrew Lumsdaine, Lie-Quan Lee, // // Distributed under the Boost Software License, Version 1.0. (See // accompanying file LICENSE_1_0.txt or copy at @@ -8,14 +8,14 @@ #include #include -int -main() +int main() { - using namespace boost; - double x[] = { 0.2, 4.5, 3.2 }; - iterator_property_map < double *, identity_property_map, double, double& > pmap(x); - std::cout << "x[1] = " << get(pmap, 1) << std::endl; - put(pmap, 0, 1.7); - std::cout << "x[0] = " << pmap[0] << std::endl; - return 0; + using namespace boost; + double x[] = { 0.2, 4.5, 3.2 }; + iterator_property_map< double*, identity_property_map, double, double& > + pmap(x); + std::cout << "x[1] = " << get(pmap, 1) << std::endl; + put(pmap, 0, 1.7); + std::cout << "x[0] = " << pmap[0] << std::endl; + return 0; } diff --git a/example/johnson-eg.cpp b/example/johnson-eg.cpp index 557b17334..90d22b280 100644 --- a/example/johnson-eg.cpp +++ b/example/johnson-eg.cpp @@ -1,5 +1,5 @@ //======================================================================= -// Copyright 2001 Jeremy G. Siek, Andrew Lumsdaine, Lie-Quan Lee, +// Copyright 2001 Jeremy G. Siek, Andrew Lumsdaine, Lie-Quan Lee, // // Distributed under the Boost Software License, Version 1.0. (See // accompanying file LICENSE_1_0.txt or copy at @@ -15,68 +15,69 @@ #include #include -int -main() +int main() { - using namespace boost; - typedef adjacency_list > > Graph; - const int V = 6; - typedef std::pair < int, int >Edge; - Edge edge_array[] = - { Edge(0, 1), Edge(0, 2), Edge(0, 3), Edge(0, 4), Edge(0, 5), - Edge(1, 2), Edge(1, 5), Edge(1, 3), Edge(2, 4), Edge(2, 5), - Edge(3, 2), Edge(4, 3), Edge(4, 1), Edge(5, 4) - }; - const std::size_t E = sizeof(edge_array) / sizeof(Edge); + using namespace boost; + typedef adjacency_list< vecS, vecS, directedS, no_property, + property< edge_weight_t, int, property< edge_weight2_t, int > > > + Graph; + const int V = 6; + typedef std::pair< int, int > Edge; + Edge edge_array[] = { Edge(0, 1), Edge(0, 2), Edge(0, 3), Edge(0, 4), + Edge(0, 5), Edge(1, 2), Edge(1, 5), Edge(1, 3), Edge(2, 4), Edge(2, 5), + Edge(3, 2), Edge(4, 3), Edge(4, 1), Edge(5, 4) }; + const std::size_t E = sizeof(edge_array) / sizeof(Edge); #if defined(BOOST_MSVC) && BOOST_MSVC <= 1300 - // VC++ can't handle the iterator constructor - Graph g(V); - for (std::size_t j = 0; j < E; ++j) - add_edge(edge_array[j].first, edge_array[j].second, g); + // VC++ can't handle the iterator constructor + Graph g(V); + for (std::size_t j = 0; j < E; ++j) + add_edge(edge_array[j].first, edge_array[j].second, g); #else - Graph g(edge_array, edge_array + E, V); + Graph g(edge_array, edge_array + E, V); #endif - property_map < Graph, edge_weight_t >::type w = get(edge_weight, g); - int weights[] = { 0, 0, 0, 0, 0, 3, -4, 8, 1, 7, 4, -5, 2, 6 }; - int *wp = weights; + property_map< Graph, edge_weight_t >::type w = get(edge_weight, g); + int weights[] = { 0, 0, 0, 0, 0, 3, -4, 8, 1, 7, 4, -5, 2, 6 }; + int* wp = weights; - graph_traits < Graph >::edge_iterator e, e_end; - for (boost::tie(e, e_end) = edges(g); e != e_end; ++e) - w[*e] = *wp++; + graph_traits< Graph >::edge_iterator e, e_end; + for (boost::tie(e, e_end) = edges(g); e != e_end; ++e) + w[*e] = *wp++; - std::vector < int >d(V, (std::numeric_limits < int >::max)()); - int D[V][V]; - johnson_all_pairs_shortest_paths(g, D, distance_map(&d[0])); + std::vector< int > d(V, (std::numeric_limits< int >::max)()); + int D[V][V]; + johnson_all_pairs_shortest_paths(g, D, distance_map(&d[0])); - std::cout << " "; - for (int k = 0; k < V; ++k) - std::cout << std::setw(5) << k; - std::cout << std::endl; - for (int i = 0; i < V; ++i) { - std::cout << std::setw(3) << i << " -> "; - for (int j = 0; j < V; ++j) { - if (D[i][j] == (std::numeric_limits::max)()) - std::cout << std::setw(5) << "inf"; - else - std::cout << std::setw(5) << D[i][j]; - } + std::cout << " "; + for (int k = 0; k < V; ++k) + std::cout << std::setw(5) << k; std::cout << std::endl; - } + for (int i = 0; i < V; ++i) + { + std::cout << std::setw(3) << i << " -> "; + for (int j = 0; j < V; ++j) + { + if (D[i][j] == (std::numeric_limits< int >::max)()) + std::cout << std::setw(5) << "inf"; + else + std::cout << std::setw(5) << D[i][j]; + } + std::cout << std::endl; + } - std::ofstream fout("figs/johnson-eg.dot"); - fout << "digraph A {\n" - << " rankdir=LR\n" - << "size=\"5,3\"\n" - << "ratio=\"fill\"\n" - << "edge[style=\"bold\"]\n" << "node[shape=\"circle\"]\n"; + std::ofstream fout("figs/johnson-eg.dot"); + fout << "digraph A {\n" + << " rankdir=LR\n" + << "size=\"5,3\"\n" + << "ratio=\"fill\"\n" + << "edge[style=\"bold\"]\n" + << "node[shape=\"circle\"]\n"; - graph_traits < Graph >::edge_iterator ei, ei_end; - for (boost::tie(ei, ei_end) = edges(g); ei != ei_end; ++ei) - fout << source(*ei, g) << " -> " << target(*ei, g) - << "[label=" << get(edge_weight, g)[*ei] << "]\n"; + graph_traits< Graph >::edge_iterator ei, ei_end; + for (boost::tie(ei, ei_end) = edges(g); ei != ei_end; ++ei) + fout << source(*ei, g) << " -> " << target(*ei, g) + << "[label=" << get(edge_weight, g)[*ei] << "]\n"; - fout << "}\n"; - return 0; + fout << "}\n"; + return 0; } diff --git a/example/johnson.expected b/example/johnson.expected index 55084c127..c97e53e1a 100644 --- a/example/johnson.expected +++ b/example/johnson.expected @@ -1,7 +1,7 @@ - 0 1 2 3 4 5 -0 -> 0 0 -1 -5 0 -4 -1 -> inf 0 1 -3 2 -4 -2 -> inf 3 0 -4 1 -1 -3 -> inf 7 4 0 5 3 -4 -> inf 2 -1 -5 0 -2 -5 -> inf 8 5 1 6 0 + 0 1 2 3 4 5 +0 -> 0 0 -1 -5 0 -4 +1 -> inf 0 1 -3 2 -4 +2 -> inf 3 0 -4 1 -1 +3 -> inf 7 4 0 5 3 +4 -> inf 2 -1 -5 0 -2 +5 -> inf 8 5 1 6 0 diff --git a/example/kevin-bacon.cpp b/example/kevin-bacon.cpp index 974adee40..1ee274db0 100644 --- a/example/kevin-bacon.cpp +++ b/example/kevin-bacon.cpp @@ -1,5 +1,5 @@ //======================================================================= -// Copyright 2001 Jeremy G. Siek, Andrew Lumsdaine, Lie-Quan Lee, +// Copyright 2001 Jeremy G. Siek, Andrew Lumsdaine, Lie-Quan Lee, // // Distributed under the Boost Software License, Version 1.0. (See // accompanying file LICENSE_1_0.txt or copy at @@ -18,100 +18,107 @@ using namespace boost; -template +template < typename DistanceMap > class bacon_number_recorder : public default_bfs_visitor { public: - bacon_number_recorder(DistanceMap dist) : d(dist) { } - - template - void tree_edge(Edge e, const Graph& g) const - { - typename graph_traits::vertex_descriptor - u = source(e, g), v = target(e, g); - d[v] = d[u] + 1; - } + bacon_number_recorder(DistanceMap dist) : d(dist) {} + + template < typename Edge, typename Graph > + void tree_edge(Edge e, const Graph& g) const + { + typename graph_traits< Graph >::vertex_descriptor u = source(e, g), + v = target(e, g); + d[v] = d[u] + 1; + } + private: DistanceMap d; }; // Convenience function template < typename DistanceMap > -bacon_number_recorder -record_bacon_number(DistanceMap d) +bacon_number_recorder< DistanceMap > record_bacon_number(DistanceMap d) { - return bacon_number_recorder < DistanceMap > (d); + return bacon_number_recorder< DistanceMap >(d); } - -int -main(int argc, const char** argv) +int main(int argc, const char** argv) { - std::ifstream datafile(argc >= 2 ? argv[1] : "./kevin-bacon.dat"); - if (!datafile) { - std::cerr << "No ./kevin-bacon.dat file" << std::endl; - return EXIT_FAILURE; - } - - typedef adjacency_list < vecS, vecS, undirectedS, property < vertex_name_t, - std::string >, property < edge_name_t, std::string > > Graph; - Graph g; - - typedef property_map < Graph, vertex_name_t >::type actor_name_map_t; - actor_name_map_t actor_name = get(vertex_name, g); - typedef property_map < Graph, edge_name_t >::type movie_name_map_t; - movie_name_map_t connecting_movie = get(edge_name, g); - - typedef graph_traits < Graph >::vertex_descriptor Vertex; - typedef std::map < std::string, Vertex > NameVertexMap; - NameVertexMap actors; - - for (std::string line; std::getline(datafile, line);) { - char_delimiters_separator < char >sep(false, "", ";"); - tokenizer <> line_toks(line, sep); - tokenizer <>::iterator i = line_toks.begin(); - std::string actors_name = *i++; - NameVertexMap::iterator pos; - bool inserted; - Vertex u, v; - boost::tie(pos, inserted) = actors.insert(std::make_pair(actors_name, Vertex())); - if (inserted) { - u = add_vertex(g); - actor_name[u] = actors_name; - pos->second = u; - } else - u = pos->second; - - std::string movie_name = *i++; - - boost::tie(pos, inserted) = actors.insert(std::make_pair(*i, Vertex())); - if (inserted) { - v = add_vertex(g); - actor_name[v] = *i; - pos->second = v; - } else - v = pos->second; - - graph_traits < Graph >::edge_descriptor e; - boost::tie(e, inserted) = add_edge(u, v, g); - if (inserted) - connecting_movie[e] = movie_name; - - } - - std::vector < int >bacon_number(num_vertices(g)); - - Vertex src = actors["Kevin Bacon"]; - bacon_number[src] = 0; - - breadth_first_search(g, src, - visitor(record_bacon_number(&bacon_number[0]))); - - graph_traits < Graph >::vertex_iterator i, end; - for (boost::tie(i, end) = vertices(g); i != end; ++i) { - std::cout << actor_name[*i] << " has a Bacon number of " - << bacon_number[*i] << std::endl; - } - - return 0; + std::ifstream datafile(argc >= 2 ? argv[1] : "./kevin-bacon.dat"); + if (!datafile) + { + std::cerr << "No ./kevin-bacon.dat file" << std::endl; + return EXIT_FAILURE; + } + + typedef adjacency_list< vecS, vecS, undirectedS, + property< vertex_name_t, std::string >, + property< edge_name_t, std::string > > + Graph; + Graph g; + + typedef property_map< Graph, vertex_name_t >::type actor_name_map_t; + actor_name_map_t actor_name = get(vertex_name, g); + typedef property_map< Graph, edge_name_t >::type movie_name_map_t; + movie_name_map_t connecting_movie = get(edge_name, g); + + typedef graph_traits< Graph >::vertex_descriptor Vertex; + typedef std::map< std::string, Vertex > NameVertexMap; + NameVertexMap actors; + + for (std::string line; std::getline(datafile, line);) + { + char_delimiters_separator< char > sep(false, "", ";"); + tokenizer<> line_toks(line, sep); + tokenizer<>::iterator i = line_toks.begin(); + std::string actors_name = *i++; + NameVertexMap::iterator pos; + bool inserted; + Vertex u, v; + boost::tie(pos, inserted) + = actors.insert(std::make_pair(actors_name, Vertex())); + if (inserted) + { + u = add_vertex(g); + actor_name[u] = actors_name; + pos->second = u; + } + else + u = pos->second; + + std::string movie_name = *i++; + + boost::tie(pos, inserted) = actors.insert(std::make_pair(*i, Vertex())); + if (inserted) + { + v = add_vertex(g); + actor_name[v] = *i; + pos->second = v; + } + else + v = pos->second; + + graph_traits< Graph >::edge_descriptor e; + boost::tie(e, inserted) = add_edge(u, v, g); + if (inserted) + connecting_movie[e] = movie_name; + } + + std::vector< int > bacon_number(num_vertices(g)); + + Vertex src = actors["Kevin Bacon"]; + bacon_number[src] = 0; + + breadth_first_search( + g, src, visitor(record_bacon_number(&bacon_number[0]))); + + graph_traits< Graph >::vertex_iterator i, end; + for (boost::tie(i, end) = vertices(g); i != end; ++i) + { + std::cout << actor_name[*i] << " has a Bacon number of " + << bacon_number[*i] << std::endl; + } + + return 0; } diff --git a/example/kevin-bacon2.cpp b/example/kevin-bacon2.cpp index 37d706194..b52d4462c 100644 --- a/example/kevin-bacon2.cpp +++ b/example/kevin-bacon2.cpp @@ -1,17 +1,17 @@ //======================================================================= -// Copyright 2001 Jeremy G. Siek, Andrew Lumsdaine, Lie-Quan Lee, +// Copyright 2001 Jeremy G. Siek, Andrew Lumsdaine, Lie-Quan Lee, // // Distributed under the Boost Software License, Version 1.0. (See // accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) //======================================================================= - /* IMPORTANT: ~~~~~~~~~~ - This example appears to be broken and crashes at runtime, see https://github.com/boostorg/graph/issues/148 + This example appears to be broken and crashes at runtime, see + https://github.com/boostorg/graph/issues/148 */ @@ -28,74 +28,82 @@ #include #include -struct vertex_properties { - std::string name; +struct vertex_properties +{ + std::string name; - template - void serialize(Archive & ar, const unsigned int version) { - ar & name; - } + template < class Archive > + void serialize(Archive& ar, const unsigned int version) + { + ar& name; + } }; -struct edge_properties { - std::string name; +struct edge_properties +{ + std::string name; - template - void serialize(Archive & ar, const unsigned int version) { - ar & name; - } + template < class Archive > + void serialize(Archive& ar, const unsigned int version) + { + ar& name; + } }; using namespace boost; -typedef adjacency_list Graph; -typedef graph_traits::vertex_descriptor Vertex; -typedef graph_traits::edge_descriptor Edge; +typedef adjacency_list< vecS, vecS, undirectedS, vertex_properties, + edge_properties > + Graph; +typedef graph_traits< Graph >::vertex_descriptor Vertex; +typedef graph_traits< Graph >::edge_descriptor Edge; class bacon_number_recorder : public default_bfs_visitor { public: - bacon_number_recorder(int* dist) : d(dist) { } + bacon_number_recorder(int* dist) : d(dist) {} + + void tree_edge(Edge e, const Graph& g) const + { + Vertex u = source(e, g), v = target(e, g); + d[v] = d[u] + 1; + } - void tree_edge(Edge e, const Graph& g) const { - Vertex u = source(e, g), v = target(e, g); - d[v] = d[u] + 1; - } private: - int* d; + int* d; }; int main(int argc, const char** argv) { - std::ifstream ifs(argc >= 2 ? argv[1] : "./kevin-bacon2.dat"); - if (!ifs) { - std::cerr << "No ./kevin-bacon2.dat file" << std::endl; - return EXIT_FAILURE; - } - archive::text_iarchive ia(ifs); - Graph g; - ia >> g; - - std::vector bacon_number(num_vertices(g)); - - // Get the vertex for Kevin Bacon - Vertex src; - graph_traits::vertex_iterator i, end; - for (boost::tie(i, end) = vertices(g); i != end; ++i) - if (g[*i].name == "Kevin Bacon") - src = *i; - - // Set Kevin's number to zero - bacon_number[src] = 0; - - // Perform a breadth first search to compute everyone' Bacon number. - breadth_first_search(g, src, - visitor(bacon_number_recorder(&bacon_number[0]))); - - for (boost::tie(i, end) = vertices(g); i != end; ++i) - std::cout << g[*i].name << " has a Bacon number of " - << bacon_number[*i] << std::endl; - - return 0; + std::ifstream ifs(argc >= 2 ? argv[1] : "./kevin-bacon2.dat"); + if (!ifs) + { + std::cerr << "No ./kevin-bacon2.dat file" << std::endl; + return EXIT_FAILURE; + } + archive::text_iarchive ia(ifs); + Graph g; + ia >> g; + + std::vector< int > bacon_number(num_vertices(g)); + + // Get the vertex for Kevin Bacon + Vertex src; + graph_traits< Graph >::vertex_iterator i, end; + for (boost::tie(i, end) = vertices(g); i != end; ++i) + if (g[*i].name == "Kevin Bacon") + src = *i; + + // Set Kevin's number to zero + bacon_number[src] = 0; + + // Perform a breadth first search to compute everyone' Bacon number. + breadth_first_search( + g, src, visitor(bacon_number_recorder(&bacon_number[0]))); + + for (boost::tie(i, end) = vertices(g); i != end; ++i) + std::cout << g[*i].name << " has a Bacon number of " << bacon_number[*i] + << std::endl; + + return 0; } diff --git a/example/king_ordering.cpp b/example/king_ordering.cpp index 2b081fa28..9ef613009 100644 --- a/example/king_ordering.cpp +++ b/example/king_ordering.cpp @@ -20,112 +20,119 @@ Sample Output original bandwidth: 8 Reverse Cuthill-McKee ordering starting at: 6 - 8 3 0 9 2 5 1 4 7 6 + 8 3 0 9 2 5 1 4 7 6 bandwidth: 4 Reverse Cuthill-McKee ordering starting at: 0 - 9 1 4 6 7 2 8 5 3 0 + 9 1 4 6 7 2 8 5 3 0 bandwidth: 4 Reverse Cuthill-McKee ordering: - 0 8 5 7 3 6 4 2 1 9 + 0 8 5 7 3 6 4 2 1 9 bandwidth: 4 */ -int main(int , char* []) +int main(int, char*[]) { - using namespace boost; - using namespace std; - typedef adjacency_list > > Graph; - typedef graph_traits::vertex_descriptor Vertex; - typedef graph_traits::vertices_size_type size_type; + using namespace boost; + using namespace std; + typedef adjacency_list< vecS, vecS, undirectedS, + property< vertex_color_t, default_color_type, + property< vertex_degree_t, int > > > + Graph; + typedef graph_traits< Graph >::vertex_descriptor Vertex; + typedef graph_traits< Graph >::vertices_size_type size_type; - typedef std::pair Pair; - Pair edges[14] = { Pair(0,3), //a-d - Pair(0,5), //a-f - Pair(1,2), //b-c - Pair(1,4), //b-e - Pair(1,6), //b-g - Pair(1,9), //b-j - Pair(2,3), //c-d - Pair(2,4), //c-e - Pair(3,5), //d-f - Pair(3,8), //d-i - Pair(4,6), //e-g - Pair(5,6), //f-g - Pair(5,7), //f-h - Pair(6,7) }; //g-h - - Graph G(10); - for (int i = 0; i < 14; ++i) - add_edge(edges[i].first, edges[i].second, G); + typedef std::pair< std::size_t, std::size_t > Pair; + Pair edges[14] = { Pair(0, 3), // a-d + Pair(0, 5), // a-f + Pair(1, 2), // b-c + Pair(1, 4), // b-e + Pair(1, 6), // b-g + Pair(1, 9), // b-j + Pair(2, 3), // c-d + Pair(2, 4), // c-e + Pair(3, 5), // d-f + Pair(3, 8), // d-i + Pair(4, 6), // e-g + Pair(5, 6), // f-g + Pair(5, 7), // f-h + Pair(6, 7) }; // g-h - graph_traits::vertex_iterator ui, ui_end; + Graph G(10); + for (int i = 0; i < 14; ++i) + add_edge(edges[i].first, edges[i].second, G); - property_map::type deg = get(vertex_degree, G); - for (boost::tie(ui, ui_end) = vertices(G); ui != ui_end; ++ui) - deg[*ui] = degree(*ui, G); + graph_traits< Graph >::vertex_iterator ui, ui_end; - property_map::type - index_map = get(vertex_index, G); + property_map< Graph, vertex_degree_t >::type deg = get(vertex_degree, G); + for (boost::tie(ui, ui_end) = vertices(G); ui != ui_end; ++ui) + deg[*ui] = degree(*ui, G); - std::cout << "original bandwidth: " << bandwidth(G) << std::endl; + property_map< Graph, vertex_index_t >::type index_map + = get(vertex_index, G); - std::vector inv_perm(num_vertices(G)); - std::vector perm(num_vertices(G)); - { - Vertex s = vertex(6, G); - //king_ordering - king_ordering(G, s, inv_perm.rbegin(), get(vertex_color, G), - get(vertex_degree, G), get(vertex_index, G)); - cout << "King ordering starting at: " << s << endl; - cout << " "; - for (std::vector::const_iterator i = inv_perm.begin(); - i != inv_perm.end(); ++i) - cout << index_map[*i] << " "; - cout << endl; + std::cout << "original bandwidth: " << bandwidth(G) << std::endl; - for (size_type c = 0; c != inv_perm.size(); ++c) - perm[index_map[inv_perm[c]]] = c; - std::cout << " bandwidth: " - << bandwidth(G, make_iterator_property_map(&perm[0], index_map, perm[0])) - << std::endl; - } - { - Vertex s = vertex(0, G); - //king_ordering - king_ordering(G, s, inv_perm.rbegin(), get(vertex_color, G), - get(vertex_degree, G), get(vertex_index, G)); - cout << "King ordering starting at: " << s << endl; - cout << " "; - for (std::vector::const_iterator i=inv_perm.begin(); - i != inv_perm.end(); ++i) - cout << index_map[*i] << " "; - cout << endl; + std::vector< Vertex > inv_perm(num_vertices(G)); + std::vector< size_type > perm(num_vertices(G)); + { + Vertex s = vertex(6, G); + // king_ordering + king_ordering(G, s, inv_perm.rbegin(), get(vertex_color, G), + get(vertex_degree, G), get(vertex_index, G)); + cout << "King ordering starting at: " << s << endl; + cout << " "; + for (std::vector< Vertex >::const_iterator i = inv_perm.begin(); + i != inv_perm.end(); ++i) + cout << index_map[*i] << " "; + cout << endl; - for (size_type c = 0; c != inv_perm.size(); ++c) - perm[index_map[inv_perm[c]]] = c; - std::cout << " bandwidth: " - << bandwidth(G, make_iterator_property_map(&perm[0], index_map, perm[0])) - << std::endl; - } + for (size_type c = 0; c != inv_perm.size(); ++c) + perm[index_map[inv_perm[c]]] = c; + std::cout << " bandwidth: " + << bandwidth(G, + make_iterator_property_map( + &perm[0], index_map, perm[0])) + << std::endl; + } + { + Vertex s = vertex(0, G); + // king_ordering + king_ordering(G, s, inv_perm.rbegin(), get(vertex_color, G), + get(vertex_degree, G), get(vertex_index, G)); + cout << "King ordering starting at: " << s << endl; + cout << " "; + for (std::vector< Vertex >::const_iterator i = inv_perm.begin(); + i != inv_perm.end(); ++i) + cout << index_map[*i] << " "; + cout << endl; - { - //king_ordering - king_ordering(G, inv_perm.rbegin(), get(vertex_color, G), - make_degree_map(G), get(vertex_index, G)); - - cout << "King ordering:" << endl; - cout << " "; - for (std::vector::const_iterator i=inv_perm.begin(); - i != inv_perm.end(); ++i) - cout << index_map[*i] << " "; - cout << endl; + for (size_type c = 0; c != inv_perm.size(); ++c) + perm[index_map[inv_perm[c]]] = c; + std::cout << " bandwidth: " + << bandwidth(G, + make_iterator_property_map( + &perm[0], index_map, perm[0])) + << std::endl; + } - for (size_type c = 0; c != inv_perm.size(); ++c) - perm[index_map[inv_perm[c]]] = c; - std::cout << " bandwidth: " - << bandwidth(G, make_iterator_property_map(&perm[0], index_map, perm[0])) - << std::endl; - } - return 0; + { + // king_ordering + king_ordering(G, inv_perm.rbegin(), get(vertex_color, G), + make_degree_map(G), get(vertex_index, G)); + + cout << "King ordering:" << endl; + cout << " "; + for (std::vector< Vertex >::const_iterator i = inv_perm.begin(); + i != inv_perm.end(); ++i) + cout << index_map[*i] << " "; + cout << endl; + + for (size_type c = 0; c != inv_perm.size(); ++c) + perm[index_map[inv_perm[c]]] = c; + std::cout << " bandwidth: " + << bandwidth(G, + make_iterator_property_map( + &perm[0], index_map, perm[0])) + << std::endl; + } + return 0; } diff --git a/example/knights_tour.cpp b/example/knights_tour.cpp index e655b5c65..31b8945e7 100644 --- a/example/knights_tour.cpp +++ b/example/knights_tour.cpp @@ -1,5 +1,5 @@ //======================================================================= -// Copyright 2001 Jeremy G. Siek, Andrew Lumsdaine, Lie-Quan Lee, +// Copyright 2001 Jeremy G. Siek, Andrew Lumsdaine, Lie-Quan Lee, // // Distributed under the Boost Software License, Version 1.0. (See // accompanying file LICENSE_1_0.txt or copy at @@ -18,326 +18,269 @@ using namespace boost; -typedef -std::pair < int, int > - Position; -Position - knight_jumps[8] = { - Position(2, -1), - Position(1, -2), - Position(-1, -2), - Position(-2, -1), - Position(-2, 1), - Position(-1, 2), - Position(1, 2), - Position(2, 1) -}; - +typedef std::pair< int, int > Position; +Position knight_jumps[8] + = { Position(2, -1), Position(1, -2), Position(-1, -2), Position(-2, -1), + Position(-2, 1), Position(-1, 2), Position(1, 2), Position(2, 1) }; -Position -operator + (const Position & p1, const Position & p2) +Position operator+(const Position& p1, const Position& p2) { - return Position(p1.first + p2.first, p1.second + p2.second); + return Position(p1.first + p2.first, p1.second + p2.second); } struct knights_tour_graph; -struct knight_adjacency_iterator: - public - boost::forward_iterator_helper < - knight_adjacency_iterator, - Position, - std::ptrdiff_t, - Position *, - Position > +struct knight_adjacency_iterator +: public boost::forward_iterator_helper< knight_adjacency_iterator, Position, + std::ptrdiff_t, Position*, Position > { - knight_adjacency_iterator() - { - } - knight_adjacency_iterator(int ii, Position p, const knights_tour_graph & g) - : - m_pos(p), - m_g(&g), - m_i(ii) - { - valid_position(); - } - Position operator *() const - { - return - m_pos + - knight_jumps[m_i]; - } - void - operator++ () - { - ++m_i; - valid_position(); - } - bool - operator == (const knight_adjacency_iterator & x) const { - return - m_i == - x. - m_i; - } + knight_adjacency_iterator() {} + knight_adjacency_iterator(int ii, Position p, const knights_tour_graph& g) + : m_pos(p), m_g(&g), m_i(ii) + { + valid_position(); + } + Position operator*() const { return m_pos + knight_jumps[m_i]; } + void operator++() + { + ++m_i; + valid_position(); + } + bool operator==(const knight_adjacency_iterator& x) const + { + return m_i == x.m_i; + } + protected: - void - valid_position(); - Position - m_pos; - const knights_tour_graph * - m_g; - int - m_i; + void valid_position(); + Position m_pos; + const knights_tour_graph* m_g; + int m_i; }; struct knights_tour_graph { - typedef Position - vertex_descriptor; - typedef - std::pair < - vertex_descriptor, - vertex_descriptor > - edge_descriptor; - typedef knight_adjacency_iterator - adjacency_iterator; - typedef void - out_edge_iterator; - typedef void - in_edge_iterator; - typedef void - edge_iterator; - typedef void - vertex_iterator; - typedef int - degree_size_type; - typedef int - vertices_size_type; - typedef int - edges_size_type; - typedef directed_tag - directed_category; - typedef disallow_parallel_edge_tag - edge_parallel_category; - typedef adjacency_graph_tag - traversal_category; - knights_tour_graph(int n): - m_board_size(n) - { - } - int - m_board_size; + typedef Position vertex_descriptor; + typedef std::pair< vertex_descriptor, vertex_descriptor > edge_descriptor; + typedef knight_adjacency_iterator adjacency_iterator; + typedef void out_edge_iterator; + typedef void in_edge_iterator; + typedef void edge_iterator; + typedef void vertex_iterator; + typedef int degree_size_type; + typedef int vertices_size_type; + typedef int edges_size_type; + typedef directed_tag directed_category; + typedef disallow_parallel_edge_tag edge_parallel_category; + typedef adjacency_graph_tag traversal_category; + knights_tour_graph(int n) : m_board_size(n) {} + int m_board_size; }; -int -num_vertices(const knights_tour_graph & g) +int num_vertices(const knights_tour_graph& g) { - return g.m_board_size * g.m_board_size; + return g.m_board_size * g.m_board_size; } -void -knight_adjacency_iterator::valid_position() +void knight_adjacency_iterator::valid_position() { - Position new_pos = m_pos + knight_jumps[m_i]; - while (m_i < 8 && (new_pos.first < 0 || new_pos.second < 0 - || new_pos.first >= m_g->m_board_size - || new_pos.second >= m_g->m_board_size)) { - ++m_i; - new_pos = m_pos + knight_jumps[m_i]; - } + Position new_pos = m_pos + knight_jumps[m_i]; + while (m_i < 8 + && (new_pos.first < 0 || new_pos.second < 0 + || new_pos.first >= m_g->m_board_size + || new_pos.second >= m_g->m_board_size)) + { + ++m_i; + new_pos = m_pos + knight_jumps[m_i]; + } } - -std::pair < knights_tour_graph::adjacency_iterator, - knights_tour_graph::adjacency_iterator > -adjacent_vertices(knights_tour_graph::vertex_descriptor v, - const knights_tour_graph & g) +std::pair< knights_tour_graph::adjacency_iterator, + knights_tour_graph::adjacency_iterator > +adjacent_vertices( + knights_tour_graph::vertex_descriptor v, const knights_tour_graph& g) { - typedef knights_tour_graph::adjacency_iterator Iter; - return std::make_pair(Iter(0, v, g), Iter(8, v, g)); + typedef knights_tour_graph::adjacency_iterator Iter; + return std::make_pair(Iter(0, v, g), Iter(8, v, g)); } - struct compare_first { - template < typename P > bool operator() (const P & x, const P & y) - { - return x.first < y.first; - } + template < typename P > bool operator()(const P& x, const P& y) + { + return x.first < y.first; + } }; template < typename Graph, typename TimePropertyMap > - bool backtracking_search(Graph & g, - typename graph_traits < - Graph >::vertex_descriptor src, - TimePropertyMap time_map) +bool backtracking_search(Graph& g, + typename graph_traits< Graph >::vertex_descriptor src, + TimePropertyMap time_map) { - typedef typename graph_traits < Graph >::vertex_descriptor Vertex; - typedef std::pair < int, Vertex > P; - std::stack < P > S; - int time_stamp = 0; + typedef typename graph_traits< Graph >::vertex_descriptor Vertex; + typedef std::pair< int, Vertex > P; + std::stack< P > S; + int time_stamp = 0; - S.push(std::make_pair(time_stamp, src)); - while (!S.empty()) { - Vertex x; - boost::tie(time_stamp, x) = S.top(); - put(time_map, x, time_stamp); - // all vertices have been visited, success! - if (time_stamp == num_vertices(g) - 1) - return true; + S.push(std::make_pair(time_stamp, src)); + while (!S.empty()) + { + Vertex x; + boost::tie(time_stamp, x) = S.top(); + put(time_map, x, time_stamp); + // all vertices have been visited, success! + if (time_stamp == num_vertices(g) - 1) + return true; - bool deadend = true; - typename graph_traits < Graph >::adjacency_iterator i, end; - for (boost::tie(i, end) = adjacent_vertices(x, g); i != end; ++i) - if (get(time_map, *i) == -1) { - S.push(std::make_pair(time_stamp + 1, *i)); - deadend = false; - } + bool deadend = true; + typename graph_traits< Graph >::adjacency_iterator i, end; + for (boost::tie(i, end) = adjacent_vertices(x, g); i != end; ++i) + if (get(time_map, *i) == -1) + { + S.push(std::make_pair(time_stamp + 1, *i)); + deadend = false; + } - if (deadend) { - put(time_map, x, -1); - S.pop(); - boost::tie(time_stamp, x) = S.top(); - while (get(time_map, x) != -1) { // unwind stack to last unexplored vertex - put(time_map, x, -1); - S.pop(); - boost::tie(time_stamp, x) = S.top(); - } - } + if (deadend) + { + put(time_map, x, -1); + S.pop(); + boost::tie(time_stamp, x) = S.top(); + while (get(time_map, x) != -1) + { // unwind stack to last unexplored vertex + put(time_map, x, -1); + S.pop(); + boost::tie(time_stamp, x) = S.top(); + } + } - } // while (!S.empty()) - return false; + } // while (!S.empty()) + return false; } -template < typename Vertex, typename Graph, typename TimePropertyMap > int -number_of_successors(Vertex x, Graph & g, TimePropertyMap time_map) +template < typename Vertex, typename Graph, typename TimePropertyMap > +int number_of_successors(Vertex x, Graph& g, TimePropertyMap time_map) { - int s_x = 0; - typename graph_traits < Graph >::adjacency_iterator i, end; - for (boost::tie(i, end) = adjacent_vertices(x, g); i != end; ++i) - if (get(time_map, *i) == -1) - ++s_x; - return s_x; + int s_x = 0; + typename graph_traits< Graph >::adjacency_iterator i, end; + for (boost::tie(i, end) = adjacent_vertices(x, g); i != end; ++i) + if (get(time_map, *i) == -1) + ++s_x; + return s_x; } template < typename Graph, typename TimePropertyMap > - bool warnsdorff(Graph & g, - typename graph_traits < Graph >::vertex_descriptor src, - TimePropertyMap time_map) +bool warnsdorff(Graph& g, typename graph_traits< Graph >::vertex_descriptor src, + TimePropertyMap time_map) { - typedef typename graph_traits < Graph >::vertex_descriptor Vertex; - typedef std::pair < int, Vertex > P; - std::stack < P > S; - int time_stamp = 0; + typedef typename graph_traits< Graph >::vertex_descriptor Vertex; + typedef std::pair< int, Vertex > P; + std::stack< P > S; + int time_stamp = 0; - S.push(std::make_pair(time_stamp, src)); - while (!S.empty()) { - Vertex x; - boost::tie(time_stamp, x) = S.top(); - put(time_map, x, time_stamp); - // all vertices have been visited, success! - if (time_stamp == num_vertices(g) - 1) - return true; - - // Put adjacent vertices into a local priority queue - std::priority_queue < P, std::vector < P >, compare_first > Q; - typename graph_traits < Graph >::adjacency_iterator i, end; - int num_succ; - for (boost::tie(i, end) = adjacent_vertices(x, g); i != end; ++i) - if (get(time_map, *i) == -1) { - num_succ = number_of_successors(*i, g, time_map); - Q.push(std::make_pair(num_succ, *i)); - } - bool deadend = Q.empty(); - // move vertices from local priority queue to the stack - for (; !Q.empty(); Q.pop()) { - boost::tie(num_succ, x) = Q.top(); - S.push(std::make_pair(time_stamp + 1, x)); - } - if (deadend) { - put(time_map, x, -1); - S.pop(); - boost::tie(time_stamp, x) = S.top(); - while (get(time_map, x) != -1) { // unwind stack to last unexplored vertex - put(time_map, x, -1); - S.pop(); + S.push(std::make_pair(time_stamp, src)); + while (!S.empty()) + { + Vertex x; boost::tie(time_stamp, x) = S.top(); - } - } + put(time_map, x, time_stamp); + // all vertices have been visited, success! + if (time_stamp == num_vertices(g) - 1) + return true; - } // while (!S.empty()) - return false; -} + // Put adjacent vertices into a local priority queue + std::priority_queue< P, std::vector< P >, compare_first > Q; + typename graph_traits< Graph >::adjacency_iterator i, end; + int num_succ; + for (boost::tie(i, end) = adjacent_vertices(x, g); i != end; ++i) + if (get(time_map, *i) == -1) + { + num_succ = number_of_successors(*i, g, time_map); + Q.push(std::make_pair(num_succ, *i)); + } + bool deadend = Q.empty(); + // move vertices from local priority queue to the stack + for (; !Q.empty(); Q.pop()) + { + boost::tie(num_succ, x) = Q.top(); + S.push(std::make_pair(time_stamp + 1, x)); + } + if (deadend) + { + put(time_map, x, -1); + S.pop(); + boost::tie(time_stamp, x) = S.top(); + while (get(time_map, x) != -1) + { // unwind stack to last unexplored vertex + put(time_map, x, -1); + S.pop(); + boost::tie(time_stamp, x) = S.top(); + } + } + } // while (!S.empty()) + return false; +} struct board_map { - typedef int value_type; - typedef Position key_type; - typedef read_write_property_map_tag category; - board_map(int *b, int n):m_board(b), m_size(n) - { - } - friend int get(const board_map & ba, Position p); - friend void put(const board_map & ba, Position p, int v); - friend std::ostream & operator << (std::ostream & os, const board_map & ba); + typedef int value_type; + typedef Position key_type; + typedef read_write_property_map_tag category; + board_map(int* b, int n) : m_board(b), m_size(n) {} + friend int get(const board_map& ba, Position p); + friend void put(const board_map& ba, Position p, int v); + friend std::ostream& operator<<(std::ostream& os, const board_map& ba); + private: - int *m_board; - int m_size; + int* m_board; + int m_size; }; -int -get(const board_map & ba, Position p) +int get(const board_map& ba, Position p) { - return ba.m_board[p.first * ba.m_size + p.second]; + return ba.m_board[p.first * ba.m_size + p.second]; } -void -put(const board_map & ba, Position p, int v) +void put(const board_map& ba, Position p, int v) { - ba.m_board[p.first * ba.m_size + p.second] = v; + ba.m_board[p.first * ba.m_size + p.second] = v; } -std::ostream & operator << (std::ostream & os, const board_map & ba) { - for (int i = 0; i < ba.m_size; ++i) { - for (int j = 0; j < ba.m_size; ++j) - os << get(ba, Position(i, j)) << "\t"; - os << std::endl; - } - return os; +std::ostream& operator<<(std::ostream& os, const board_map& ba) +{ + for (int i = 0; i < ba.m_size; ++i) + { + for (int j = 0; j < ba.m_size; ++j) + os << get(ba, Position(i, j)) << "\t"; + os << std::endl; + } + return os; } -int -main(int argc, char *argv[]) +int main(int argc, char* argv[]) { - int - N; - if (argc == 2) - N = atoi(argv[1]); - else - N = 8; + int N; + if (argc == 2) + N = atoi(argv[1]); + else + N = 8; - knights_tour_graph - g(N); - int * - board = - new int[num_vertices(g)]; - board_map - chessboard(board, N); - for (int i = 0; i < N; ++i) - for (int j = 0; j < N; ++j) - put(chessboard, Position(i, j), -1); + knights_tour_graph g(N); + int* board = new int[num_vertices(g)]; + board_map chessboard(board, N); + for (int i = 0; i < N; ++i) + for (int j = 0; j < N; ++j) + put(chessboard, Position(i, j), -1); - bool - ret = - warnsdorff(g, Position(0, 0), chessboard); + bool ret = warnsdorff(g, Position(0, 0), chessboard); - if (ret) - for (int i = 0; i < N; ++i) { - for (int j = 0; j < N; ++j) - std::cout << get(chessboard, Position(i, j)) << "\t"; - std::cout << std::endl; - } else - std::cout << "method failed" << std::endl; - return 0; + if (ret) + for (int i = 0; i < N; ++i) + { + for (int j = 0; j < N; ++j) + std::cout << get(chessboard, Position(i, j)) << "\t"; + std::cout << std::endl; + } + else + std::cout << "method failed" << std::endl; + return 0; } diff --git a/example/knights_tour.expected b/example/knights_tour.expected index a7f230b46..3a0e9519e 100644 --- a/example/knights_tour.expected +++ b/example/knights_tour.expected @@ -1,8 +1,8 @@ -0 13 28 61 10 15 18 47 -29 36 11 14 27 46 9 16 -12 1 62 37 60 17 48 19 -35 30 59 54 49 26 45 8 -2 55 34 63 38 53 20 25 -31 58 39 52 23 50 7 44 -40 3 56 33 42 5 24 21 -57 32 41 4 51 22 43 6 +0 13 28 61 10 15 18 47 +29 36 11 14 27 46 9 16 +12 1 62 37 60 17 48 19 +35 30 59 54 49 26 45 8 +2 55 34 63 38 53 20 25 +31 58 39 52 23 50 7 44 +40 3 56 33 42 5 24 21 +57 32 41 4 51 22 43 6 diff --git a/example/kruskal-example.cpp b/example/kruskal-example.cpp index 642977682..4d8c41b7e 100644 --- a/example/kruskal-example.cpp +++ b/example/kruskal-example.cpp @@ -1,5 +1,5 @@ //======================================================================= -// Copyright 2001 Jeremy G. Siek, Andrew Lumsdaine, Lie-Quan Lee, +// Copyright 2001 Jeremy G. Siek, Andrew Lumsdaine, Lie-Quan Lee, // // Distributed under the Boost Software License, Version 1.0. (See // accompanying file LICENSE_1_0.txt or copy at @@ -10,62 +10,66 @@ #include #include -int -main() +int main() { - using namespace boost; - typedef adjacency_list < vecS, vecS, undirectedS, - no_property, property < edge_weight_t, int > > Graph; - typedef graph_traits < Graph >::edge_descriptor Edge; - typedef std::pair E; + using namespace boost; + typedef adjacency_list< vecS, vecS, undirectedS, no_property, + property< edge_weight_t, int > > + Graph; + typedef graph_traits< Graph >::edge_descriptor Edge; + typedef std::pair< int, int > E; - const int num_nodes = 5; - E edge_array[] = { E(0, 2), E(1, 3), E(1, 4), E(2, 1), E(2, 3), - E(3, 4), E(4, 0), E(4, 1) - }; - int weights[] = { 1, 1, 2, 7, 3, 1, 1, 1 }; - std::size_t num_edges = sizeof(edge_array) / sizeof(E); + const int num_nodes = 5; + E edge_array[] = { E(0, 2), E(1, 3), E(1, 4), E(2, 1), E(2, 3), E(3, 4), + E(4, 0), E(4, 1) }; + int weights[] = { 1, 1, 2, 7, 3, 1, 1, 1 }; + std::size_t num_edges = sizeof(edge_array) / sizeof(E); #if defined(BOOST_MSVC) && BOOST_MSVC <= 1300 - Graph g(num_nodes); - property_map::type weightmap = get(edge_weight, g); - for (std::size_t j = 0; j < num_edges; ++j) { - Edge e; bool inserted; - boost::tie(e, inserted) = add_edge(edge_array[j].first, edge_array[j].second, g); - weightmap[e] = weights[j]; - } + Graph g(num_nodes); + property_map< Graph, edge_weight_t >::type weightmap = get(edge_weight, g); + for (std::size_t j = 0; j < num_edges; ++j) + { + Edge e; + bool inserted; + boost::tie(e, inserted) + = add_edge(edge_array[j].first, edge_array[j].second, g); + weightmap[e] = weights[j]; + } #else - Graph g(edge_array, edge_array + num_edges, weights, num_nodes); + Graph g(edge_array, edge_array + num_edges, weights, num_nodes); #endif - property_map < Graph, edge_weight_t >::type weight = get(edge_weight, g); - std::vector < Edge > spanning_tree; + property_map< Graph, edge_weight_t >::type weight = get(edge_weight, g); + std::vector< Edge > spanning_tree; - kruskal_minimum_spanning_tree(g, std::back_inserter(spanning_tree)); + kruskal_minimum_spanning_tree(g, std::back_inserter(spanning_tree)); - std::cout << "Print the edges in the MST:" << std::endl; - for (std::vector < Edge >::iterator ei = spanning_tree.begin(); - ei != spanning_tree.end(); ++ei) { - std::cout << source(*ei, g) << " <--> " << target(*ei, g) - << " with weight of " << weight[*ei] - << std::endl; - } + std::cout << "Print the edges in the MST:" << std::endl; + for (std::vector< Edge >::iterator ei = spanning_tree.begin(); + ei != spanning_tree.end(); ++ei) + { + std::cout << source(*ei, g) << " <--> " << target(*ei, g) + << " with weight of " << weight[*ei] << std::endl; + } - std::ofstream fout("figs/kruskal-eg.dot"); - fout << "graph A {\n" - << " rankdir=LR\n" - << " size=\"3,3\"\n" - << " ratio=\"filled\"\n" - << " edge[style=\"bold\"]\n" << " node[shape=\"circle\"]\n"; - graph_traits::edge_iterator eiter, eiter_end; - for (boost::tie(eiter, eiter_end) = edges(g); eiter != eiter_end; ++eiter) { - fout << source(*eiter, g) << " -- " << target(*eiter, g); - if (std::find(spanning_tree.begin(), spanning_tree.end(), *eiter) - != spanning_tree.end()) - fout << "[color=\"black\", label=\"" << get(edge_weight, g, *eiter) - << "\"];\n"; - else - fout << "[color=\"gray\", label=\"" << get(edge_weight, g, *eiter) - << "\"];\n"; - } - fout << "}\n"; - return EXIT_SUCCESS; + std::ofstream fout("figs/kruskal-eg.dot"); + fout << "graph A {\n" + << " rankdir=LR\n" + << " size=\"3,3\"\n" + << " ratio=\"filled\"\n" + << " edge[style=\"bold\"]\n" + << " node[shape=\"circle\"]\n"; + graph_traits< Graph >::edge_iterator eiter, eiter_end; + for (boost::tie(eiter, eiter_end) = edges(g); eiter != eiter_end; ++eiter) + { + fout << source(*eiter, g) << " -- " << target(*eiter, g); + if (std::find(spanning_tree.begin(), spanning_tree.end(), *eiter) + != spanning_tree.end()) + fout << "[color=\"black\", label=\"" << get(edge_weight, g, *eiter) + << "\"];\n"; + else + fout << "[color=\"gray\", label=\"" << get(edge_weight, g, *eiter) + << "\"];\n"; + } + fout << "}\n"; + return EXIT_SUCCESS; } diff --git a/example/kruskal-telephone.cpp b/example/kruskal-telephone.cpp index 614775b62..c88337c55 100644 --- a/example/kruskal-telephone.cpp +++ b/example/kruskal-telephone.cpp @@ -1,5 +1,5 @@ //======================================================================= -// Copyright 2001 Jeremy G. Siek, Andrew Lumsdaine, Lie-Quan Lee, +// Copyright 2001 Jeremy G. Siek, Andrew Lumsdaine, Lie-Quan Lee, // // Distributed under the Boost Software License, Version 1.0. (See // accompanying file LICENSE_1_0.txt or copy at @@ -9,11 +9,10 @@ /* IMPORTANT!!! ~~~~~~~~~~~~ - This example uses interfaces that have been deprecated and removed from Boost.Grpah. - Someone needs to update it, as it does NOT compile. + This example uses interfaces that have been deprecated and removed from + Boost.Grpah. Someone needs to update it, as it does NOT compile. */ - #include #include #include @@ -21,46 +20,50 @@ #include #include -int -main() +int main() { - using namespace boost; - GraphvizGraph g_dot; - read_graphviz("figs/telephone-network.dot", g_dot); + using namespace boost; + GraphvizGraph g_dot; + read_graphviz("figs/telephone-network.dot", g_dot); - typedef adjacency_list < vecS, vecS, undirectedS, no_property, - property < edge_weight_t, int > > Graph; - Graph g(num_vertices(g_dot)); - property_map < GraphvizGraph, edge_attribute_t >::type - edge_attr_map = get(edge_attribute, g_dot); - graph_traits < GraphvizGraph >::edge_iterator ei, ei_end; - for (boost::tie(ei, ei_end) = edges(g_dot); ei != ei_end; ++ei) { - int weight = lexical_cast < int >(edge_attr_map[*ei]["label"]); - property < edge_weight_t, int >edge_property(weight); - add_edge(source(*ei, g_dot), target(*ei, g_dot), edge_property, g); - } + typedef adjacency_list< vecS, vecS, undirectedS, no_property, + property< edge_weight_t, int > > + Graph; + Graph g(num_vertices(g_dot)); + property_map< GraphvizGraph, edge_attribute_t >::type edge_attr_map + = get(edge_attribute, g_dot); + graph_traits< GraphvizGraph >::edge_iterator ei, ei_end; + for (boost::tie(ei, ei_end) = edges(g_dot); ei != ei_end; ++ei) + { + int weight = lexical_cast< int >(edge_attr_map[*ei]["label"]); + property< edge_weight_t, int > edge_property(weight); + add_edge(source(*ei, g_dot), target(*ei, g_dot), edge_property, g); + } - std::vector < graph_traits < Graph >::edge_descriptor > mst; - typedef std::vector < graph_traits < Graph >::edge_descriptor >::size_type size_type; - kruskal_minimum_spanning_tree(g, std::back_inserter(mst)); + std::vector< graph_traits< Graph >::edge_descriptor > mst; + typedef std::vector< graph_traits< Graph >::edge_descriptor >::size_type + size_type; + kruskal_minimum_spanning_tree(g, std::back_inserter(mst)); - property_map < Graph, edge_weight_t >::type weight = get(edge_weight, g); - int total_weight = 0; - for (size_type e = 0; e < mst.size(); ++e) - total_weight += get(weight, mst[e]); - std::cout << "total weight: " << total_weight << std::endl; + property_map< Graph, edge_weight_t >::type weight = get(edge_weight, g); + int total_weight = 0; + for (size_type e = 0; e < mst.size(); ++e) + total_weight += get(weight, mst[e]); + std::cout << "total weight: " << total_weight << std::endl; - typedef graph_traits < Graph >::vertex_descriptor Vertex; - for (size_type i = 0; i < mst.size(); ++i) { - Vertex u = source(mst[i], g), v = target(mst[i], g); - edge_attr_map[edge(u, v, g_dot).first]["color"] = "black"; - } - std::ofstream out("figs/telephone-mst-kruskal.dot"); - graph_property < GraphvizGraph, graph_edge_attribute_t >::type & - graph_edge_attr_map = get_property(g_dot, graph_edge_attribute); - graph_edge_attr_map["color"] = "gray"; - graph_edge_attr_map["style"] = "bold"; - write_graphviz(out, g_dot); + typedef graph_traits< Graph >::vertex_descriptor Vertex; + for (size_type i = 0; i < mst.size(); ++i) + { + Vertex u = source(mst[i], g), v = target(mst[i], g); + edge_attr_map[edge(u, v, g_dot).first]["color"] = "black"; + } + std::ofstream out("figs/telephone-mst-kruskal.dot"); + graph_property< GraphvizGraph, graph_edge_attribute_t >::type& + graph_edge_attr_map + = get_property(g_dot, graph_edge_attribute); + graph_edge_attr_map["color"] = "gray"; + graph_edge_attr_map["style"] = "bold"; + write_graphviz(out, g_dot); - return EXIT_SUCCESS; + return EXIT_SUCCESS; } diff --git a/example/kuratowski_subgraph.cpp b/example/kuratowski_subgraph.cpp index 8f55a3e65..e9779e633 100644 --- a/example/kuratowski_subgraph.cpp +++ b/example/kuratowski_subgraph.cpp @@ -18,79 +18,68 @@ using namespace boost; - int main(int argc, char** argv) { - typedef adjacency_list - < vecS, - vecS, - undirectedS, - property, - property - > - graph; - - // Create a K_6 (complete graph on 6 vertices), which - // contains both Kuratowski subgraphs as minors. - graph g(6); - add_edge(0,1,g); - add_edge(0,2,g); - add_edge(0,3,g); - add_edge(0,4,g); - add_edge(0,5,g); - add_edge(1,2,g); - add_edge(1,3,g); - add_edge(1,4,g); - add_edge(1,5,g); - add_edge(2,3,g); - add_edge(2,4,g); - add_edge(2,5,g); - add_edge(3,4,g); - add_edge(3,5,g); - add_edge(4,5,g); + typedef adjacency_list< vecS, vecS, undirectedS, + property< vertex_index_t, int >, property< edge_index_t, int > > + graph; + // Create a K_6 (complete graph on 6 vertices), which + // contains both Kuratowski subgraphs as minors. + graph g(6); + add_edge(0, 1, g); + add_edge(0, 2, g); + add_edge(0, 3, g); + add_edge(0, 4, g); + add_edge(0, 5, g); + add_edge(1, 2, g); + add_edge(1, 3, g); + add_edge(1, 4, g); + add_edge(1, 5, g); + add_edge(2, 3, g); + add_edge(2, 4, g); + add_edge(2, 5, g); + add_edge(3, 4, g); + add_edge(3, 5, g); + add_edge(4, 5, g); - // Initialize the interior edge index - property_map::type e_index = get(edge_index, g); - graph_traits::edges_size_type edge_count = 0; - graph_traits::edge_iterator ei, ei_end; - for(boost::tie(ei, ei_end) = edges(g); ei != ei_end; ++ei) - put(e_index, *ei, edge_count++); - + // Initialize the interior edge index + property_map< graph, edge_index_t >::type e_index = get(edge_index, g); + graph_traits< graph >::edges_size_type edge_count = 0; + graph_traits< graph >::edge_iterator ei, ei_end; + for (boost::tie(ei, ei_end) = edges(g); ei != ei_end; ++ei) + put(e_index, *ei, edge_count++); - // Test for planarity - we know it is not planar, we just want to - // compute the kuratowski subgraph as a side-effect - typedef std::vector< graph_traits::edge_descriptor > - kuratowski_edges_t; - kuratowski_edges_t kuratowski_edges; - if (boyer_myrvold_planarity_test(boyer_myrvold_params::graph = g, - boyer_myrvold_params::kuratowski_subgraph = - std::back_inserter(kuratowski_edges) - ) - ) - std::cout << "Input graph is planar" << std::endl; - else + // Test for planarity - we know it is not planar, we just want to + // compute the kuratowski subgraph as a side-effect + typedef std::vector< graph_traits< graph >::edge_descriptor > + kuratowski_edges_t; + kuratowski_edges_t kuratowski_edges; + if (boyer_myrvold_planarity_test(boyer_myrvold_params::graph = g, + boyer_myrvold_params::kuratowski_subgraph + = std::back_inserter(kuratowski_edges))) + std::cout << "Input graph is planar" << std::endl; + else { - std::cout << "Input graph is not planar" << std::endl; + std::cout << "Input graph is not planar" << std::endl; - std::cout << "Edges in the Kuratowski subgraph: "; - kuratowski_edges_t::iterator ki, ki_end; - ki_end = kuratowski_edges.end(); - for(ki = kuratowski_edges.begin(); ki != ki_end; ++ki) + std::cout << "Edges in the Kuratowski subgraph: "; + kuratowski_edges_t::iterator ki, ki_end; + ki_end = kuratowski_edges.end(); + for (ki = kuratowski_edges.begin(); ki != ki_end; ++ki) { - std::cout << *ki << " "; + std::cout << *ki << " "; } - std::cout << std::endl; + std::cout << std::endl; - std::cout << "Is a kuratowski subgraph? "; - if (is_kuratowski_subgraph - (g, kuratowski_edges.begin(), kuratowski_edges.end()) - ) - std::cout << "Yes." << std::endl; - else - std::cout << "No." << std::endl; + std::cout << "Is a kuratowski subgraph? "; + if (is_kuratowski_subgraph( + g, kuratowski_edges.begin(), kuratowski_edges.end())) + std::cout << "Yes." << std::endl; + else + std::cout << "No." << std::endl; } - return 0; + return 0; } diff --git a/example/labeled_graph.cpp b/example/labeled_graph.cpp index b38199d92..6224d768e 100644 --- a/example/labeled_graph.cpp +++ b/example/labeled_graph.cpp @@ -8,7 +8,8 @@ IMPORTANT!!! ~~~~~~~~~~~~ - This example does not compile, see https://github.com/boostorg/graph/issues/147 + This example does not compile, see + https://github.com/boostorg/graph/issues/147 */ @@ -21,14 +22,15 @@ using namespace boost; using namespace std; -int main() { +int main() +{ using namespace boost::graph_detail; typedef directed_graph<> Digraph; { - typedef labeled_graph Graph; + typedef labeled_graph< Digraph, unsigned > Graph; Graph g; add_vertex(1, g); add_vertex(2, g); @@ -37,14 +39,14 @@ int main() { } { - typedef labeled_graph Graph; + typedef labeled_graph< Digraph, string > Graph; Graph g; add_vertex("foo", g); add_vertex("bar", g); } { - typedef labeled_graph Graph; + typedef labeled_graph< Digraph, string, mapS > Graph; Graph g; add_vertex("foo", g); add_vertex("bar", g); @@ -52,23 +54,21 @@ int main() { } { - typedef labeled_graph TempGraph; + typedef labeled_graph< Digraph*, int > TempGraph; Digraph g; TempGraph h(&g); add_vertex(12, h); } - { // This is actually a fairly complicated specialization. - typedef adjacency_list G; - typedef labeled_graph Graph; + typedef adjacency_list< vecS, vecS, bidirectionalS > G; + typedef labeled_graph< G, size_t > Graph; Graph g; add_vertex(0, g); add_vertex(1, g); g.add_edge(0, 1); } - return 0; } diff --git a/example/last-mod-time.cpp b/example/last-mod-time.cpp index 95d13c7a4..7d8676ebd 100644 --- a/example/last-mod-time.cpp +++ b/example/last-mod-time.cpp @@ -1,17 +1,17 @@ //======================================================================= -// Copyright 2001 Jeremy G. Siek, Andrew Lumsdaine, Lie-Quan Lee, +// Copyright 2001 Jeremy G. Siek, Andrew Lumsdaine, Lie-Quan Lee, // // Distributed under the Boost Software License, Version 1.0. (See // accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) //======================================================================= - /* IMPORTANT: ~~~~~~~~~~ - This example appears to be broken and crashes at runtime, see https://github.com/boostorg/graph/issues/148 + This example appears to be broken and crashes at runtime, see + https://github.com/boostorg/graph/issues/148 */ @@ -32,77 +32,82 @@ using namespace boost; -template < typename Graph, typename VertexNamePropertyMap > void -read_graph_file(std::istream & graph_in, std::istream & name_in, - Graph & g, VertexNamePropertyMap name_map) +template < typename Graph, typename VertexNamePropertyMap > +void read_graph_file(std::istream& graph_in, std::istream& name_in, Graph& g, + VertexNamePropertyMap name_map) { - typedef typename graph_traits < Graph >::vertices_size_type size_type; - size_type n_vertices; - typename graph_traits < Graph >::vertex_descriptor u; - typename property_traits < VertexNamePropertyMap >::value_type name; + typedef typename graph_traits< Graph >::vertices_size_type size_type; + size_type n_vertices; + typename graph_traits< Graph >::vertex_descriptor u; + typename property_traits< VertexNamePropertyMap >::value_type name; - graph_in >> n_vertices; // read in number of vertices - for (size_type i = 0; i < n_vertices; ++i) { // Add n vertices to the graph - u = add_vertex(g); - name_in >> name; - put(name_map, u, name); // ** Attach name property to vertex u ** - } - size_type src, targ; - while (graph_in >> src) // Read in edges - if (graph_in >> targ) - add_edge(src, targ, g); // add an edge to the graph - else - break; + graph_in >> n_vertices; // read in number of vertices + for (size_type i = 0; i < n_vertices; ++i) + { // Add n vertices to the graph + u = add_vertex(g); + name_in >> name; + put(name_map, u, name); // ** Attach name property to vertex u ** + } + size_type src, targ; + while (graph_in >> src) // Read in edges + if (graph_in >> targ) + add_edge(src, targ, g); // add an edge to the graph + else + break; } - -int -main(int argc, const char** argv) +int main(int argc, const char** argv) { - typedef adjacency_list < listS, // Store out-edges of each vertex in a std::list - vecS, // Store vertex set in a std::vector - directedS, // The graph is directed - property < vertex_name_t, std::string > // Add a vertex property - >graph_type; + typedef adjacency_list< listS, // Store out-edges of each vertex in a + // std::list + vecS, // Store vertex set in a std::vector + directedS, // The graph is directed + property< vertex_name_t, std::string > // Add a vertex property + > + graph_type; - graph_type g; // use default constructor to create empty graph - std::ifstream file_in(argc >= 2 ? argv[1] : "makefile-dependencies.dat"), - name_in(argc >= 2 ? argv[1] : "makefile-target-names.dat"); - if (!file_in) { - std::cerr << "** Error: could not open file makefile-target-names.dat" - << std::endl; - exit(-1); - } - // Obtain internal property map from the graph - property_map < graph_type, vertex_name_t >::type name_map = - get(vertex_name, g); - read_graph_file(file_in, name_in, g, name_map); + graph_type g; // use default constructor to create empty graph + std::ifstream file_in(argc >= 2 ? argv[1] : "makefile-dependencies.dat"), + name_in(argc >= 2 ? argv[1] : "makefile-target-names.dat"); + if (!file_in) + { + std::cerr << "** Error: could not open file makefile-target-names.dat" + << std::endl; + exit(-1); + } + // Obtain internal property map from the graph + property_map< graph_type, vertex_name_t >::type name_map + = get(vertex_name, g); + read_graph_file(file_in, name_in, g, name_map); - // Create storage for last modified times - std::vector < time_t > last_mod_vec(num_vertices(g)); - // Create nickname for the property map type - typedef iterator_property_map < std::vector < time_t >::iterator, - property_map < graph_type, vertex_index_t >::type, time_t, time_t&> iter_map_t; - // Create last modified time property map - iter_map_t mod_time_map(last_mod_vec.begin(), get(vertex_index, g)); + // Create storage for last modified times + std::vector< time_t > last_mod_vec(num_vertices(g)); + // Create nickname for the property map type + typedef iterator_property_map< std::vector< time_t >::iterator, + property_map< graph_type, vertex_index_t >::type, time_t, time_t& > + iter_map_t; + // Create last modified time property map + iter_map_t mod_time_map(last_mod_vec.begin(), get(vertex_index, g)); - property_map < graph_type, vertex_name_t >::type name = get(vertex_name, g); - struct stat stat_buf; - graph_traits < graph_type >::vertex_descriptor u; - typedef graph_traits < graph_type >::vertex_iterator vertex_iter_t; - std::pair < vertex_iter_t, vertex_iter_t > p; - for (p = vertices(g); p.first != p.second; ++p.first) { - u = *p.first; - if (stat(name[u].c_str(), &stat_buf) != 0) - std::cerr << "error in stat() for file " << name[u] << std::endl; - put(mod_time_map, u, stat_buf.st_mtime); - } + property_map< graph_type, vertex_name_t >::type name = get(vertex_name, g); + struct stat stat_buf; + graph_traits< graph_type >::vertex_descriptor u; + typedef graph_traits< graph_type >::vertex_iterator vertex_iter_t; + std::pair< vertex_iter_t, vertex_iter_t > p; + for (p = vertices(g); p.first != p.second; ++p.first) + { + u = *p.first; + if (stat(name[u].c_str(), &stat_buf) != 0) + std::cerr << "error in stat() for file " << name[u] << std::endl; + put(mod_time_map, u, stat_buf.st_mtime); + } - for (p = vertices(g); p.first != p.second; ++p.first) { - std::cout << name[*p.first] << " was last modified at " - << ctime(&mod_time_map[*p.first]); - } - assert(num_vertices(g) == 15); - assert(num_edges(g) == 19); - return 0; + for (p = vertices(g); p.first != p.second; ++p.first) + { + std::cout << name[*p.first] << " was last modified at " + << ctime(&mod_time_map[*p.first]); + } + assert(num_vertices(g) == 15); + assert(num_edges(g) == 19); + return 0; } diff --git a/example/leda-concept-check.cpp b/example/leda-concept-check.cpp index f5720e7db..490d2d68b 100644 --- a/example/leda-concept-check.cpp +++ b/example/leda-concept-check.cpp @@ -1,5 +1,5 @@ //======================================================================= -// Copyright 2001 Jeremy G. Siek, Andrew Lumsdaine, Lie-Quan Lee, +// Copyright 2001 Jeremy G. Siek, Andrew Lumsdaine, Lie-Quan Lee, // // Distributed under the Boost Software License, Version 1.0. (See // accompanying file LICENSE_1_0.txt or copy at @@ -9,14 +9,13 @@ #include #include -int -main() +int main() { - using namespace boost; - typedef leda::GRAPH Graph; - BOOST_CONCEPT_ASSERT(( VertexListGraphConcept )); - BOOST_CONCEPT_ASSERT(( BidirectionalGraphConcept< Graph> )); - BOOST_CONCEPT_ASSERT(( VertexMutableGraphConcept< Graph> )); - BOOST_CONCEPT_ASSERT(( EdgeMutableGraphConcept )); - return EXIT_SUCCESS; + using namespace boost; + typedef leda::GRAPH< int, int > Graph; + BOOST_CONCEPT_ASSERT((VertexListGraphConcept< Graph >)); + BOOST_CONCEPT_ASSERT((BidirectionalGraphConcept< Graph >)); + BOOST_CONCEPT_ASSERT((VertexMutableGraphConcept< Graph >)); + BOOST_CONCEPT_ASSERT((EdgeMutableGraphConcept< Graph >)); + return EXIT_SUCCESS; } diff --git a/example/leda-graph-eg.cpp b/example/leda-graph-eg.cpp index 4fddab840..507498ecd 100644 --- a/example/leda-graph-eg.cpp +++ b/example/leda-graph-eg.cpp @@ -1,5 +1,5 @@ //======================================================================= -// Copyright 2001 Jeremy G. Siek, Andrew Lumsdaine, Lie-Quan Lee, +// Copyright 2001 Jeremy G. Siek, Andrew Lumsdaine, Lie-Quan Lee, // // Distributed under the Boost Software License, Version 1.0. (See // accompanying file LICENSE_1_0.txt or copy at @@ -7,22 +7,21 @@ //======================================================================= #include #include -#undef string // LEDA macro! -int -main() +#undef string // LEDA macro! +int main() { - using namespace boost; - typedef leda::GRAPH < std::string, int >graph_t; - graph_t g; - g.new_node("Philoctetes"); - g.new_node("Heracles"); - g.new_node("Alcmena"); - g.new_node("Eurystheus"); - g.new_node("Amphitryon"); - typedef property_map < graph_t, vertex_all_t >::type NodeMap; - NodeMap node_name_map = get(vertex_all, g); - graph_traits < graph_t >::vertex_iterator vi, vi_end; - for (boost::tie(vi, vi_end) = vertices(g); vi != vi_end; ++vi) - std::cout << node_name_map[*vi] << std::endl; - return EXIT_SUCCESS; + using namespace boost; + typedef leda::GRAPH< std::string, int > graph_t; + graph_t g; + g.new_node("Philoctetes"); + g.new_node("Heracles"); + g.new_node("Alcmena"); + g.new_node("Eurystheus"); + g.new_node("Amphitryon"); + typedef property_map< graph_t, vertex_all_t >::type NodeMap; + NodeMap node_name_map = get(vertex_all, g); + graph_traits< graph_t >::vertex_iterator vi, vi_end; + for (boost::tie(vi, vi_end) = vertices(g); vi != vi_end; ++vi) + std::cout << node_name_map[*vi] << std::endl; + return EXIT_SUCCESS; } diff --git a/example/loops_dfs.cpp b/example/loops_dfs.cpp index b53f7aa19..b56dd83a3 100644 --- a/example/loops_dfs.cpp +++ b/example/loops_dfs.cpp @@ -1,5 +1,5 @@ //======================================================================= -// Copyright 2001 Jeremy G. Siek, Andrew Lumsdaine, Lie-Quan Lee, +// Copyright 2001 Jeremy G. Siek, Andrew Lumsdaine, Lie-Quan Lee, // // Distributed under the Boost Software License, Version 1.0. (See // accompanying file LICENSE_1_0.txt or copy at @@ -9,8 +9,8 @@ /* IMPORTANT!!! ~~~~~~~~~~~~ - This example uses interfaces that have been deprecated and removed from Boost.Grpah. - Someone needs to update it, as it does NOT compile. + This example uses interfaces that have been deprecated and removed from + Boost.Grpah. Someone needs to update it, as it does NOT compile. */ #include @@ -28,169 +28,178 @@ using namespace boost; -template < typename OutputIterator > +template < typename OutputIterator > class back_edge_recorder : public default_dfs_visitor { public: - back_edge_recorder(OutputIterator out):m_out(out) { } + back_edge_recorder(OutputIterator out) : m_out(out) {} + + template < typename Edge, typename Graph > + void back_edge(Edge e, const Graph&) + { + *m_out++ = e; + } - template < typename Edge, typename Graph > - void back_edge(Edge e, const Graph &) - { - *m_out++ = e; - } private: - OutputIterator m_out; + OutputIterator m_out; }; // object generator function template < typename OutputIterator > -back_edge_recorder < OutputIterator > -make_back_edge_recorder(OutputIterator out) +back_edge_recorder< OutputIterator > make_back_edge_recorder(OutputIterator out) { - return back_edge_recorder < OutputIterator > (out); + return back_edge_recorder< OutputIterator >(out); } -template < typename Graph, typename Loops > void -find_loops(typename graph_traits < Graph >::vertex_descriptor entry, - const Graph & g, - Loops & loops) // A container of sets of vertices +template < typename Graph, typename Loops > +void find_loops(typename graph_traits< Graph >::vertex_descriptor entry, + const Graph& g, + Loops& loops) // A container of sets of vertices { - BOOST_CONCEPT_ASSERT(( BidirectionalGraphConcept )); - typedef typename graph_traits < Graph >::edge_descriptor Edge; - std::vector < Edge > back_edges; - std::vector < default_color_type > color_map(num_vertices(g)); - depth_first_visit(g, entry, - make_back_edge_recorder(std::back_inserter(back_edges)), - make_iterator_property_map(color_map.begin(), - get(vertex_index, g), color_map[0])); - - for (typename std::vector < Edge >::size_type i = 0; i < back_edges.size(); ++i) { - typename Loops::value_type x; - loops.push_back(x); - compute_loop_extent(back_edges[i], g, loops.back()); - } + BOOST_CONCEPT_ASSERT((BidirectionalGraphConcept< Graph >)); + typedef typename graph_traits< Graph >::edge_descriptor Edge; + std::vector< Edge > back_edges; + std::vector< default_color_type > color_map(num_vertices(g)); + depth_first_visit(g, entry, + make_back_edge_recorder(std::back_inserter(back_edges)), + make_iterator_property_map( + color_map.begin(), get(vertex_index, g), color_map[0])); + + for (typename std::vector< Edge >::size_type i = 0; i < back_edges.size(); + ++i) + { + typename Loops::value_type x; + loops.push_back(x); + compute_loop_extent(back_edges[i], g, loops.back()); + } } -template < typename Graph, typename Set > void -compute_loop_extent(typename graph_traits < - Graph >::edge_descriptor back_edge, const Graph & g, - Set & loop_set) +template < typename Graph, typename Set > +void compute_loop_extent( + typename graph_traits< Graph >::edge_descriptor back_edge, const Graph& g, + Set& loop_set) { - BOOST_CONCEPT_ASSERT(( BidirectionalGraphConcept )); - typedef typename graph_traits < Graph >::vertex_descriptor Vertex; - typedef color_traits < default_color_type > Color; - - Vertex loop_head, loop_tail; - loop_tail = source(back_edge, g); - loop_head = target(back_edge, g); - - std::vector < default_color_type > - reachable_from_head(num_vertices(g), Color::white()); - default_color_type c; - depth_first_visit(g, loop_head, default_dfs_visitor(), - make_iterator_property_map(reachable_from_head.begin(), - get(vertex_index, g), c)); - - std::vector < default_color_type > reachable_to_tail(num_vertices(g)); - reverse_graph < Graph > reverse_g(g); - depth_first_visit(reverse_g, loop_tail, default_dfs_visitor(), - make_iterator_property_map(reachable_to_tail.begin(), - get(vertex_index, g), c)); - - typename graph_traits < Graph >::vertex_iterator vi, vi_end; - for (boost::tie(vi, vi_end) = vertices(g); vi != vi_end; ++vi) - if (reachable_from_head[*vi] != Color::white() - && reachable_to_tail[*vi] != Color::white()) - loop_set.insert(*vi); + BOOST_CONCEPT_ASSERT((BidirectionalGraphConcept< Graph >)); + typedef typename graph_traits< Graph >::vertex_descriptor Vertex; + typedef color_traits< default_color_type > Color; + + Vertex loop_head, loop_tail; + loop_tail = source(back_edge, g); + loop_head = target(back_edge, g); + + std::vector< default_color_type > reachable_from_head( + num_vertices(g), Color::white()); + default_color_type c; + depth_first_visit(g, loop_head, default_dfs_visitor(), + make_iterator_property_map( + reachable_from_head.begin(), get(vertex_index, g), c)); + + std::vector< default_color_type > reachable_to_tail(num_vertices(g)); + reverse_graph< Graph > reverse_g(g); + depth_first_visit(reverse_g, loop_tail, default_dfs_visitor(), + make_iterator_property_map( + reachable_to_tail.begin(), get(vertex_index, g), c)); + + typename graph_traits< Graph >::vertex_iterator vi, vi_end; + for (boost::tie(vi, vi_end) = vertices(g); vi != vi_end; ++vi) + if (reachable_from_head[*vi] != Color::white() + && reachable_to_tail[*vi] != Color::white()) + loop_set.insert(*vi); } - -int -main(int argc, char *argv[]) +int main(int argc, char* argv[]) { - if (argc < 3) { - std::cerr << "usage: loops_dfs " << std::endl; - return -1; - } - GraphvizDigraph g_in; - read_graphviz(argv[1], g_in); - - typedef adjacency_list < vecS, vecS, bidirectionalS, - GraphvizVertexProperty, - GraphvizEdgeProperty, GraphvizGraphProperty > Graph; - typedef graph_traits < Graph >::vertex_descriptor Vertex; - - Graph g; -#if defined(BOOST_MSVC) && BOOST_MSVC <= 1300 - // VC++ has trouble with the get_property() function - get_property(g, graph_name) = "loops"; -#endif - - copy_graph(g_in, g); - - typedef std::set < Vertex > set_t; - typedef std::list < set_t > list_of_sets_t; - list_of_sets_t loops; - Vertex entry = *vertices(g).first; + if (argc < 3) + { + std::cerr << "usage: loops_dfs " << std::endl; + return -1; + } + GraphvizDigraph g_in; + read_graphviz(argv[1], g_in); - find_loops(entry, g, loops); + typedef adjacency_list< vecS, vecS, bidirectionalS, GraphvizVertexProperty, + GraphvizEdgeProperty, GraphvizGraphProperty > + Graph; + typedef graph_traits< Graph >::vertex_descriptor Vertex; - property_map::type vattr_map = get(vertex_attribute, g); - property_map::type eattr_map = get(edge_attribute, g); - graph_traits < Graph >::edge_iterator ei, ei_end; + Graph g; +#if defined(BOOST_MSVC) && BOOST_MSVC <= 1300 + // VC++ has trouble with the get_property() function + get_property(g, graph_name) = "loops"; +#endif - for (list_of_sets_t::iterator i = loops.begin(); i != loops.end(); ++i) { - std::vector < bool > in_loop(num_vertices(g), false); - for (set_t::iterator j = (*i).begin(); j != (*i).end(); ++j) { - vattr_map[*j]["color"] = "gray"; - in_loop[*j] = true; + copy_graph(g_in, g); + + typedef std::set< Vertex > set_t; + typedef std::list< set_t > list_of_sets_t; + list_of_sets_t loops; + Vertex entry = *vertices(g).first; + + find_loops(entry, g, loops); + + property_map< Graph, vertex_attribute_t >::type vattr_map + = get(vertex_attribute, g); + property_map< Graph, edge_attribute_t >::type eattr_map + = get(edge_attribute, g); + graph_traits< Graph >::edge_iterator ei, ei_end; + + for (list_of_sets_t::iterator i = loops.begin(); i != loops.end(); ++i) + { + std::vector< bool > in_loop(num_vertices(g), false); + for (set_t::iterator j = (*i).begin(); j != (*i).end(); ++j) + { + vattr_map[*j]["color"] = "gray"; + in_loop[*j] = true; + } + for (boost::tie(ei, ei_end) = edges(g); ei != ei_end; ++ei) + if (in_loop[source(*ei, g)] && in_loop[target(*ei, g)]) + eattr_map[*ei]["color"] = "gray"; } - for (boost::tie(ei, ei_end) = edges(g); ei != ei_end; ++ei) - if (in_loop[source(*ei, g)] && in_loop[target(*ei, g)]) - eattr_map[*ei]["color"] = "gray"; - } - std::ofstream loops_out(argv[2]); + std::ofstream loops_out(argv[2]); #if defined(BOOST_MSVC) && BOOST_MSVC <= 1300 - // VC++ has trouble with the get_property() functions - loops_out << "digraph loops {\n" - << "size=\"3,3\"\n" - << "ratio=\"fill\"\n" - << "shape=\"box\"\n"; - graph_traits::vertex_iterator vi, vi_end; - for (boost::tie(vi, vi_end) = vertices(g); vi != vi_end; ++vi) { - loops_out << *vi << "["; - for (std::map::iterator ai = vattr_map[*vi].begin(); - ai != vattr_map[*vi].end(); ++ai) { - loops_out << ai->first << "=" << ai->second; - if (next(ai) != vattr_map[*vi].end()) - loops_out << ", "; + // VC++ has trouble with the get_property() functions + loops_out << "digraph loops {\n" + << "size=\"3,3\"\n" + << "ratio=\"fill\"\n" + << "shape=\"box\"\n"; + graph_traits< Graph >::vertex_iterator vi, vi_end; + for (boost::tie(vi, vi_end) = vertices(g); vi != vi_end; ++vi) + { + loops_out << *vi << "["; + for (std::map< std::string, std::string >::iterator ai + = vattr_map[*vi].begin(); + ai != vattr_map[*vi].end(); ++ai) + { + loops_out << ai->first << "=" << ai->second; + if (next(ai) != vattr_map[*vi].end()) + loops_out << ", "; + } + loops_out << "]"; } - loops_out<< "]"; - } - - for (boost::tie(ei, ei_end) = edges(g); ei != ei_end; ++ei) { - loops_out << source(*ei, g) << " -> " << target(*ei, g) << "["; - std::map& attr_map = eattr_map[*ei]; - for (std::map::iterator eai = attr_map.begin(); - eai != attr_map.end(); ++eai) { - loops_out << eai->first << "=" << eai->second; - if (next(eai) != attr_map.end()) - loops_out << ", "; + + for (boost::tie(ei, ei_end) = edges(g); ei != ei_end; ++ei) + { + loops_out << source(*ei, g) << " -> " << target(*ei, g) << "["; + std::map< std::string, std::string >& attr_map = eattr_map[*ei]; + for (std::map< std::string, std::string >::iterator eai + = attr_map.begin(); + eai != attr_map.end(); ++eai) + { + loops_out << eai->first << "=" << eai->second; + if (next(eai) != attr_map.end()) + loops_out << ", "; + } + loops_out << "]"; } - loops_out<< "]"; - } - loops_out << "}\n"; + loops_out << "}\n"; #else - get_property(g, graph_graph_attribute)["size"] = "3,3"; - get_property(g, graph_graph_attribute)["ratio"] = "fill"; - get_property(g, graph_vertex_attribute)["shape"] = "box"; - - write_graphviz(loops_out, g, - make_vertex_attributes_writer(g), - make_edge_attributes_writer(g), - make_graph_attributes_writer(g)); + get_property(g, graph_graph_attribute)["size"] = "3,3"; + get_property(g, graph_graph_attribute)["ratio"] = "fill"; + get_property(g, graph_vertex_attribute)["shape"] = "box"; + + write_graphviz(loops_out, g, make_vertex_attributes_writer(g), + make_edge_attributes_writer(g), make_graph_attributes_writer(g)); #endif - return 0; + return 0; } diff --git a/example/make_biconnected_planar.cpp b/example/make_biconnected_planar.cpp index d0c0dd8eb..f9c101a7d 100644 --- a/example/make_biconnected_planar.cpp +++ b/example/make_biconnected_planar.cpp @@ -17,92 +17,79 @@ #include #include - using namespace boost; int main(int argc, char** argv) { - - typedef adjacency_list - < vecS, - vecS, - undirectedS, - property, - property - > - graph; - - graph g(11); - add_edge(0,1,g); - add_edge(2,3,g); - add_edge(3,0,g); - add_edge(3,4,g); - add_edge(4,5,g); - add_edge(5,3,g); - add_edge(5,6,g); - add_edge(6,7,g); - add_edge(7,8,g); - add_edge(8,5,g); - add_edge(8,9,g); - add_edge(0,10,g); - - - //Initialize the interior edge index - property_map::type e_index = get(edge_index, g); - graph_traits::edges_size_type edge_count = 0; - graph_traits::edge_iterator ei, ei_end; - for(boost::tie(ei, ei_end) = edges(g); ei != ei_end; ++ei) - put(e_index, *ei, edge_count++); - - - //Test for planarity; compute the planar embedding as a side-effect - typedef std::vector< graph_traits::edge_descriptor > vec_t; - std::vector embedding(num_vertices(g)); - if (boyer_myrvold_planarity_test(boyer_myrvold_params::graph = g, - boyer_myrvold_params::embedding = - &embedding[0] - ) - ) - std::cout << "Input graph is planar" << std::endl; - else - std::cout << "Input graph is not planar" << std::endl; - - typedef std::vector< graph_traits::edges_size_type > - component_storage_t; - typedef iterator_property_map - < component_storage_t::iterator, - property_map::type - > - component_map_t; - - component_storage_t component_storage(num_edges(g)); - component_map_t component(component_storage.begin(), get(edge_index, g)); - - std::cout << "Before calling make_biconnected_planar, the graph has " - << biconnected_components(g, component) - << " biconnected components" << std::endl; - - make_biconnected_planar(g, &embedding[0]); - - // Re-initialize the edge index, since we just added a few edges - edge_count = 0; - for(boost::tie(ei, ei_end) = edges(g); ei != ei_end; ++ei) - put(e_index, *ei, edge_count++); - - // Re-size the storage for the biconnected components, since we - // just added a few edges - - component_storage.resize(num_edges(g)); - component = component_map_t(component_storage.begin(), get(edge_index,g)); - - std::cout << "After calling make_biconnected_planar, the graph has " - << biconnected_components(g, component) - << " biconnected components" << std::endl; - - if (boyer_myrvold_planarity_test(g)) - std::cout << "Also, the graph is still planar." << std::endl; - else - std::cout << "But the graph is not still planar." << std::endl; - - return 0; + + typedef adjacency_list< vecS, vecS, undirectedS, + property< vertex_index_t, int >, property< edge_index_t, int > > + graph; + + graph g(11); + add_edge(0, 1, g); + add_edge(2, 3, g); + add_edge(3, 0, g); + add_edge(3, 4, g); + add_edge(4, 5, g); + add_edge(5, 3, g); + add_edge(5, 6, g); + add_edge(6, 7, g); + add_edge(7, 8, g); + add_edge(8, 5, g); + add_edge(8, 9, g); + add_edge(0, 10, g); + + // Initialize the interior edge index + property_map< graph, edge_index_t >::type e_index = get(edge_index, g); + graph_traits< graph >::edges_size_type edge_count = 0; + graph_traits< graph >::edge_iterator ei, ei_end; + for (boost::tie(ei, ei_end) = edges(g); ei != ei_end; ++ei) + put(e_index, *ei, edge_count++); + + // Test for planarity; compute the planar embedding as a side-effect + typedef std::vector< graph_traits< graph >::edge_descriptor > vec_t; + std::vector< vec_t > embedding(num_vertices(g)); + if (boyer_myrvold_planarity_test(boyer_myrvold_params::graph = g, + boyer_myrvold_params::embedding = &embedding[0])) + std::cout << "Input graph is planar" << std::endl; + else + std::cout << "Input graph is not planar" << std::endl; + + typedef std::vector< graph_traits< graph >::edges_size_type > + component_storage_t; + typedef iterator_property_map< component_storage_t::iterator, + property_map< graph, edge_index_t >::type > + component_map_t; + + component_storage_t component_storage(num_edges(g)); + component_map_t component(component_storage.begin(), get(edge_index, g)); + + std::cout << "Before calling make_biconnected_planar, the graph has " + << biconnected_components(g, component) + << " biconnected components" << std::endl; + + make_biconnected_planar(g, &embedding[0]); + + // Re-initialize the edge index, since we just added a few edges + edge_count = 0; + for (boost::tie(ei, ei_end) = edges(g); ei != ei_end; ++ei) + put(e_index, *ei, edge_count++); + + // Re-size the storage for the biconnected components, since we + // just added a few edges + + component_storage.resize(num_edges(g)); + component = component_map_t(component_storage.begin(), get(edge_index, g)); + + std::cout << "After calling make_biconnected_planar, the graph has " + << biconnected_components(g, component) + << " biconnected components" << std::endl; + + if (boyer_myrvold_planarity_test(g)) + std::cout << "Also, the graph is still planar." << std::endl; + else + std::cout << "But the graph is not still planar." << std::endl; + + return 0; } diff --git a/example/make_connected.cpp b/example/make_connected.cpp index 91ceb9a7f..84491b5e2 100644 --- a/example/make_connected.cpp +++ b/example/make_connected.cpp @@ -15,43 +15,37 @@ #include #include - - using namespace boost; int main(int argc, char** argv) { - typedef adjacency_list - < vecS, - vecS, - undirectedS, - property - > - graph; - - graph g(11); - add_edge(0,1,g); - add_edge(2,3,g); - add_edge(3,4,g); - add_edge(5,6,g); - add_edge(6,7,g); - add_edge(8,9,g); - add_edge(9,10,g); - add_edge(10,8,g); - - std::vector< graph_traits::vertices_size_type > - component(num_vertices(g)); - - std::cout << "Before calling make_connected, the graph has " - << connected_components(g, &component[0]) - << " connected components" << std::endl; - - make_connected(g); - - std::cout << "After calling make_connected, the graph has " - << connected_components(g, &component[0]) - << " connected components" << std::endl; - - return 0; + typedef adjacency_list< vecS, vecS, undirectedS, + property< vertex_index_t, int > > + graph; + + graph g(11); + add_edge(0, 1, g); + add_edge(2, 3, g); + add_edge(3, 4, g); + add_edge(5, 6, g); + add_edge(6, 7, g); + add_edge(8, 9, g); + add_edge(9, 10, g); + add_edge(10, 8, g); + + std::vector< graph_traits< graph >::vertices_size_type > component( + num_vertices(g)); + + std::cout << "Before calling make_connected, the graph has " + << connected_components(g, &component[0]) + << " connected components" << std::endl; + + make_connected(g); + + std::cout << "After calling make_connected, the graph has " + << connected_components(g, &component[0]) + << " connected components" << std::endl; + + return 0; } diff --git a/example/make_maximal_planar.cpp b/example/make_maximal_planar.cpp index 50d42e8de..4647f1c09 100644 --- a/example/make_maximal_planar.cpp +++ b/example/make_maximal_planar.cpp @@ -18,126 +18,102 @@ #include #include - - -// This example shows how to start with a connected planar graph +// This example shows how to start with a connected planar graph // and add edges to make the graph maximal planar (triangulated.) -// Any maximal planar simple graph on n vertices has 3n - 6 edges and +// Any maximal planar simple graph on n vertices has 3n - 6 edges and // 2n - 4 faces, a consequence of Euler's formula. - - using namespace boost; - -// This visitor is passed to planar_face_traversal to count the +// This visitor is passed to planar_face_traversal to count the // number of faces. struct face_counter : public planar_face_traversal_visitor { - face_counter() : count(0) {} - void begin_face() { ++count; } - int count; + face_counter() : count(0) {} + void begin_face() { ++count; } + int count; }; - int main(int argc, char** argv) { - typedef adjacency_list - < vecS, - vecS, - undirectedS, - property, - property - > - graph; - - // Create the graph - a straight line - graph g(10); - add_edge(0,1,g); - add_edge(1,2,g); - add_edge(2,3,g); - add_edge(3,4,g); - add_edge(4,5,g); - add_edge(5,6,g); - add_edge(6,7,g); - add_edge(7,8,g); - add_edge(8,9,g); - - std::cout << "Since the input graph is planar with " << num_vertices(g) - << " vertices," << std::endl - << "The output graph should be planar with " - << 3*num_vertices(g) - 6 << " edges and " - << 2*num_vertices(g) - 4 << " faces." << std::endl; - - //Initialize the interior edge index - property_map::type e_index = get(edge_index, g); - graph_traits::edges_size_type edge_count = 0; - graph_traits::edge_iterator ei, ei_end; - for(boost::tie(ei, ei_end) = edges(g); ei != ei_end; ++ei) - put(e_index, *ei, edge_count++); - - - //Test for planarity; compute the planar embedding as a side-effect - typedef std::vector< graph_traits::edge_descriptor > vec_t; - std::vector embedding(num_vertices(g)); - if (boyer_myrvold_planarity_test(boyer_myrvold_params::graph = g, - boyer_myrvold_params::embedding = - &embedding[0] - ) - ) - std::cout << "Input graph is planar" << std::endl; - else - std::cout << "Input graph is not planar" << std::endl; - - make_biconnected_planar(g, &embedding[0]); - - // Re-initialize the edge index, since we just added a few edges - edge_count = 0; - for(boost::tie(ei, ei_end) = edges(g); ei != ei_end; ++ei) - put(e_index, *ei, edge_count++); - - - //Test for planarity again; compute the planar embedding as a side-effect - if (boyer_myrvold_planarity_test(boyer_myrvold_params::graph = g, - boyer_myrvold_params::embedding = - &embedding[0] - ) - ) - std::cout << "After calling make_biconnected, the graph is still planar" - << std::endl; - else - std::cout << "After calling make_biconnected, the graph is not planar" + typedef adjacency_list< vecS, vecS, undirectedS, + property< vertex_index_t, int >, property< edge_index_t, int > > + graph; + + // Create the graph - a straight line + graph g(10); + add_edge(0, 1, g); + add_edge(1, 2, g); + add_edge(2, 3, g); + add_edge(3, 4, g); + add_edge(4, 5, g); + add_edge(5, 6, g); + add_edge(6, 7, g); + add_edge(7, 8, g); + add_edge(8, 9, g); + + std::cout << "Since the input graph is planar with " << num_vertices(g) + << " vertices," << std::endl + << "The output graph should be planar with " + << 3 * num_vertices(g) - 6 << " edges and " + << 2 * num_vertices(g) - 4 << " faces." << std::endl; + + // Initialize the interior edge index + property_map< graph, edge_index_t >::type e_index = get(edge_index, g); + graph_traits< graph >::edges_size_type edge_count = 0; + graph_traits< graph >::edge_iterator ei, ei_end; + for (boost::tie(ei, ei_end) = edges(g); ei != ei_end; ++ei) + put(e_index, *ei, edge_count++); + + // Test for planarity; compute the planar embedding as a side-effect + typedef std::vector< graph_traits< graph >::edge_descriptor > vec_t; + std::vector< vec_t > embedding(num_vertices(g)); + if (boyer_myrvold_planarity_test(boyer_myrvold_params::graph = g, + boyer_myrvold_params::embedding = &embedding[0])) + std::cout << "Input graph is planar" << std::endl; + else + std::cout << "Input graph is not planar" << std::endl; + + make_biconnected_planar(g, &embedding[0]); + + // Re-initialize the edge index, since we just added a few edges + edge_count = 0; + for (boost::tie(ei, ei_end) = edges(g); ei != ei_end; ++ei) + put(e_index, *ei, edge_count++); + + // Test for planarity again; compute the planar embedding as a side-effect + if (boyer_myrvold_planarity_test(boyer_myrvold_params::graph = g, + boyer_myrvold_params::embedding = &embedding[0])) + std::cout << "After calling make_biconnected, the graph is still planar" + << std::endl; + else + std::cout << "After calling make_biconnected, the graph is not planar" + << std::endl; + + make_maximal_planar(g, &embedding[0]); + + // Re-initialize the edge index, since we just added a few edges + edge_count = 0; + for (boost::tie(ei, ei_end) = edges(g); ei != ei_end; ++ei) + put(e_index, *ei, edge_count++); + + // Test for planarity one final time; compute the planar embedding as a + // side-effect + std::cout << "After calling make_maximal_planar, the final graph "; + if (boyer_myrvold_planarity_test(boyer_myrvold_params::graph = g, + boyer_myrvold_params::embedding = &embedding[0])) + std::cout << "is planar." << std::endl; + else + std::cout << "is not planar." << std::endl; + + std::cout << "The final graph has " << num_edges(g) << " edges." << std::endl; - make_maximal_planar(g, &embedding[0]); - - - - // Re-initialize the edge index, since we just added a few edges - edge_count = 0; - for(boost::tie(ei, ei_end) = edges(g); ei != ei_end; ++ei) - put(e_index, *ei, edge_count++); - - // Test for planarity one final time; compute the planar embedding as a - // side-effect - std::cout << "After calling make_maximal_planar, the final graph "; - if (boyer_myrvold_planarity_test(boyer_myrvold_params::graph = g, - boyer_myrvold_params::embedding = - &embedding[0] - ) - ) - std::cout << "is planar." << std::endl; - else - std::cout << "is not planar." << std::endl; - - std::cout << "The final graph has " << num_edges(g) - << " edges." << std::endl; - - face_counter count_visitor; - planar_face_traversal(g, &embedding[0], count_visitor); - std::cout << "The final graph has " << count_visitor.count << " faces." - << std::endl; + face_counter count_visitor; + planar_face_traversal(g, &embedding[0], count_visitor); + std::cout << "The final graph has " << count_visitor.count << " faces." + << std::endl; - return 0; + return 0; } diff --git a/example/makefile-dependencies.dat b/example/makefile-dependencies.dat index 8772cefb0..c185d492c 100644 --- a/example/makefile-dependencies.dat +++ b/example/makefile-dependencies.dat @@ -1,10 +1,10 @@ 15 -0 5 -0 7 +0 5 +0 7 0 11 -1 5 +1 5 1 11 -2 5 +2 5 2 9 2 11 3 7 diff --git a/example/matching_example.cpp b/example/matching_example.cpp index de39f57c5..3c8a4fbb9 100644 --- a/example/matching_example.cpp +++ b/example/matching_example.cpp @@ -1,7 +1,7 @@ //======================================================================= // Copyright (c) 2005 Aaron Windsor // -// Distributed under the Boost Software License, Version 1.0. +// Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // @@ -13,106 +13,113 @@ #include - using namespace boost; -typedef adjacency_list my_graph; +typedef adjacency_list< vecS, vecS, undirectedS > my_graph; int main() { - // Create the following graph: (it'll look better when output - // to the terminal in a fixed width font...) + // Create the following graph: (it'll look better when output + // to the terminal in a fixed width font...) + + const int n_vertices = 18; + + std::vector< std::string > ascii_graph; + + ascii_graph.push_back(" 0 1---2 3 "); + ascii_graph.push_back(" \\ / \\ / "); + ascii_graph.push_back(" 4---5 6---7 "); + ascii_graph.push_back(" | | | | "); + ascii_graph.push_back(" 8---9 10---11 "); + ascii_graph.push_back(" / \\ / \\ "); + ascii_graph.push_back(" 12 13 14---15 16 17 "); - const int n_vertices = 18; + // It has a perfect matching of size 8. There are two isolated + // vertices that we'll use later... - std::vector ascii_graph; + my_graph g(n_vertices); - ascii_graph.push_back(" 0 1---2 3 "); - ascii_graph.push_back(" \\ / \\ / "); - ascii_graph.push_back(" 4---5 6---7 "); - ascii_graph.push_back(" | | | | "); - ascii_graph.push_back(" 8---9 10---11 "); - ascii_graph.push_back(" / \\ / \\ "); - ascii_graph.push_back(" 12 13 14---15 16 17 "); + // our vertices are stored in a vector, so we can refer to vertices + // by integers in the range 0..15 - // It has a perfect matching of size 8. There are two isolated - // vertices that we'll use later... + add_edge(1, 2, g); + add_edge(0, 4, g); + add_edge(1, 5, g); + add_edge(2, 6, g); + add_edge(3, 7, g); + add_edge(4, 5, g); + add_edge(6, 7, g); + add_edge(4, 8, g); + add_edge(5, 9, g); + add_edge(6, 10, g); + add_edge(7, 11, g); + add_edge(8, 9, g); + add_edge(10, 11, g); + add_edge(8, 13, g); + add_edge(9, 14, g); + add_edge(10, 15, g); + add_edge(11, 16, g); + add_edge(14, 15, g); - my_graph g(n_vertices); - - // our vertices are stored in a vector, so we can refer to vertices - // by integers in the range 0..15 + std::vector< graph_traits< my_graph >::vertex_descriptor > mate(n_vertices); - add_edge(1,2,g); - add_edge(0,4,g); - add_edge(1,5,g); - add_edge(2,6,g); - add_edge(3,7,g); - add_edge(4,5,g); - add_edge(6,7,g); - add_edge(4,8,g); - add_edge(5,9,g); - add_edge(6,10,g); - add_edge(7,11,g); - add_edge(8,9,g); - add_edge(10,11,g); - add_edge(8,13,g); - add_edge(9,14,g); - add_edge(10,15,g); - add_edge(11,16,g); - add_edge(14,15,g); + // find the maximum cardinality matching. we'll use a checked version + // of the algorithm, which takes a little longer than the unchecked + // version, but has the advantage that it will return "false" if the + // matching returned is not actually a maximum cardinality matching + // in the graph. - std::vector::vertex_descriptor> mate(n_vertices); + bool success = checked_edmonds_maximum_cardinality_matching(g, &mate[0]); + assert(success); - // find the maximum cardinality matching. we'll use a checked version - // of the algorithm, which takes a little longer than the unchecked - // version, but has the advantage that it will return "false" if the - // matching returned is not actually a maximum cardinality matching - // in the graph. + std::cout << "In the following graph:" << std::endl << std::endl; - bool success = checked_edmonds_maximum_cardinality_matching(g, &mate[0]); - assert(success); + for (std::vector< std::string >::iterator itr = ascii_graph.begin(); + itr != ascii_graph.end(); ++itr) + std::cout << *itr << std::endl; - std::cout << "In the following graph:" << std::endl << std::endl; + std::cout << std::endl + << "Found a matching of size " << matching_size(g, &mate[0]) + << std::endl; - for(std::vector::iterator itr = ascii_graph.begin(); itr != ascii_graph.end(); ++itr) - std::cout << *itr << std::endl; + std::cout << "The matching is:" << std::endl; - std::cout << std::endl << "Found a matching of size " << matching_size(g, &mate[0]) << std::endl; + graph_traits< my_graph >::vertex_iterator vi, vi_end; + for (boost::tie(vi, vi_end) = vertices(g); vi != vi_end; ++vi) + if (mate[*vi] != graph_traits< my_graph >::null_vertex() + && *vi < mate[*vi]) + std::cout << "{" << *vi << ", " << mate[*vi] << "}" << std::endl; - std::cout << "The matching is:" << std::endl; - - graph_traits::vertex_iterator vi, vi_end; - for(boost::tie(vi,vi_end) = vertices(g); vi != vi_end; ++vi) - if (mate[*vi] != graph_traits::null_vertex() && *vi < mate[*vi]) - std::cout << "{" << *vi << ", " << mate[*vi] << "}" << std::endl; + std::cout << std::endl; - std::cout << std::endl; + // now we'll add two edges, and the perfect matching has size 9 - //now we'll add two edges, and the perfect matching has size 9 + ascii_graph.pop_back(); + ascii_graph.push_back(" 12---13 14---15 16---17 "); - ascii_graph.pop_back(); - ascii_graph.push_back(" 12---13 14---15 16---17 "); + add_edge(12, 13, g); + add_edge(16, 17, g); - add_edge(12,13,g); - add_edge(16,17,g); + success = checked_edmonds_maximum_cardinality_matching(g, &mate[0]); + assert(success); - success = checked_edmonds_maximum_cardinality_matching(g, &mate[0]); - assert(success); + std::cout << "In the following graph:" << std::endl << std::endl; - std::cout << "In the following graph:" << std::endl << std::endl; + for (std::vector< std::string >::iterator itr = ascii_graph.begin(); + itr != ascii_graph.end(); ++itr) + std::cout << *itr << std::endl; - for(std::vector::iterator itr = ascii_graph.begin(); itr != ascii_graph.end(); ++itr) - std::cout << *itr << std::endl; + std::cout << std::endl + << "Found a matching of size " << matching_size(g, &mate[0]) + << std::endl; - std::cout << std::endl << "Found a matching of size " << matching_size(g, &mate[0]) << std::endl; + std::cout << "The matching is:" << std::endl; - std::cout << "The matching is:" << std::endl; - - for(boost::tie(vi,vi_end) = vertices(g); vi != vi_end; ++vi) - if (mate[*vi] != graph_traits::null_vertex() && *vi < mate[*vi]) - std::cout << "{" << *vi << ", " << mate[*vi] << "}" << std::endl; + for (boost::tie(vi, vi_end) = vertices(g); vi != vi_end; ++vi) + if (mate[*vi] != graph_traits< my_graph >::null_vertex() + && *vi < mate[*vi]) + std::cout << "{" << *vi << ", " << mate[*vi] << "}" << std::endl; - return 0; + return 0; } diff --git a/example/max_flow.cpp b/example/max_flow.cpp index ad79824c2..170356888 100644 --- a/example/max_flow.cpp +++ b/example/max_flow.cpp @@ -48,52 +48,51 @@ // f 7 6 0 // f 7 5 0 -int -main() +int main() { - using namespace boost; + using namespace boost; - typedef adjacency_list_traits Traits; - typedef adjacency_list, - property > > - > Graph; + typedef adjacency_list_traits< vecS, vecS, directedS > Traits; + typedef adjacency_list< listS, vecS, directedS, + property< vertex_name_t, std::string >, + property< edge_capacity_t, long, + property< edge_residual_capacity_t, long, + property< edge_reverse_t, Traits::edge_descriptor > > > > + Graph; - Graph g; + Graph g; - property_map::type - capacity = get(edge_capacity, g); - property_map::type - rev = get(edge_reverse, g); - property_map::type - residual_capacity = get(edge_residual_capacity, g); + property_map< Graph, edge_capacity_t >::type capacity + = get(edge_capacity, g); + property_map< Graph, edge_reverse_t >::type rev = get(edge_reverse, g); + property_map< Graph, edge_residual_capacity_t >::type residual_capacity + = get(edge_residual_capacity, g); - Traits::vertex_descriptor s, t; - read_dimacs_max_flow(g, capacity, rev, s, t); + Traits::vertex_descriptor s, t; + read_dimacs_max_flow(g, capacity, rev, s, t); - long flow; + long flow; #if defined(BOOST_MSVC) && BOOST_MSVC <= 1300 - // Use non-named parameter version - property_map::type - indexmap = get(vertex_index, g); - flow = push_relabel_max_flow(g, s, t, capacity, residual_capacity, rev, indexmap); + // Use non-named parameter version + property_map< Graph, vertex_index_t >::type indexmap = get(vertex_index, g); + flow = push_relabel_max_flow( + g, s, t, capacity, residual_capacity, rev, indexmap); #else - flow = push_relabel_max_flow(g, s, t); + flow = push_relabel_max_flow(g, s, t); #endif - std::cout << "c The total flow:" << std::endl; - std::cout << "s " << flow << std::endl << std::endl; + std::cout << "c The total flow:" << std::endl; + std::cout << "s " << flow << std::endl << std::endl; - std::cout << "c flow values:" << std::endl; - graph_traits::vertex_iterator u_iter, u_end; - graph_traits::out_edge_iterator ei, e_end; - for (boost::tie(u_iter, u_end) = vertices(g); u_iter != u_end; ++u_iter) - for (boost::tie(ei, e_end) = out_edges(*u_iter, g); ei != e_end; ++ei) - if (capacity[*ei] > 0) - std::cout << "f " << *u_iter << " " << target(*ei, g) << " " - << (capacity[*ei] - residual_capacity[*ei]) << std::endl; - - return 0; + std::cout << "c flow values:" << std::endl; + graph_traits< Graph >::vertex_iterator u_iter, u_end; + graph_traits< Graph >::out_edge_iterator ei, e_end; + for (boost::tie(u_iter, u_end) = vertices(g); u_iter != u_end; ++u_iter) + for (boost::tie(ei, e_end) = out_edges(*u_iter, g); ei != e_end; ++ei) + if (capacity[*ei] > 0) + std::cout << "f " << *u_iter << " " << target(*ei, g) << " " + << (capacity[*ei] - residual_capacity[*ei]) + << std::endl; + + return 0; } diff --git a/example/mcgregor_subgraphs_example.cpp b/example/mcgregor_subgraphs_example.cpp index 543259fc7..f0b74fc99 100644 --- a/example/mcgregor_subgraphs_example.cpp +++ b/example/mcgregor_subgraphs_example.cpp @@ -23,122 +23,130 @@ using namespace boost; // Callback that looks for the first common subgraph whose size // matches the user's preference. -template -struct example_callback { +template < typename Graph > struct example_callback +{ - typedef typename graph_traits::vertices_size_type VertexSizeFirst; + typedef typename graph_traits< Graph >::vertices_size_type VertexSizeFirst; - example_callback(const Graph& graph1) : - m_graph1(graph1) { } + example_callback(const Graph& graph1) : m_graph1(graph1) {} - template - bool operator()(CorrespondenceMapFirstToSecond correspondence_map_1_to_2, - CorrespondenceMapSecondToFirst correspondence_map_2_to_1, - VertexSizeFirst subgraph_size) { + template < typename CorrespondenceMapFirstToSecond, + typename CorrespondenceMapSecondToFirst > + bool operator()(CorrespondenceMapFirstToSecond correspondence_map_1_to_2, + CorrespondenceMapSecondToFirst correspondence_map_2_to_1, + VertexSizeFirst subgraph_size) + { - // Fill membership map for first graph - typedef typename property_map::type VertexIndexMap; - typedef shared_array_property_map MembershipMap; - - MembershipMap membership_map1(num_vertices(m_graph1), - get(vertex_index, m_graph1)); + // Fill membership map for first graph + typedef + typename property_map< Graph, vertex_index_t >::type VertexIndexMap; + typedef shared_array_property_map< bool, VertexIndexMap > MembershipMap; - fill_membership_map(m_graph1, correspondence_map_1_to_2, membership_map1); + MembershipMap membership_map1( + num_vertices(m_graph1), get(vertex_index, m_graph1)); - // Generate filtered graphs using membership map - typedef typename membership_filtered_graph_traits::graph_type - MembershipFilteredGraph; + fill_membership_map< Graph >( + m_graph1, correspondence_map_1_to_2, membership_map1); - MembershipFilteredGraph subgraph1 = - make_membership_filtered_graph(m_graph1, membership_map1); + // Generate filtered graphs using membership map + typedef typename membership_filtered_graph_traits< Graph, + MembershipMap >::graph_type MembershipFilteredGraph; - // Print the graph out to the console - std::cout << "Found common subgraph (size " << subgraph_size << ")" << std::endl; - print_graph(subgraph1); - std::cout << std::endl; + MembershipFilteredGraph subgraph1 + = make_membership_filtered_graph(m_graph1, membership_map1); + + // Print the graph out to the console + std::cout << "Found common subgraph (size " << subgraph_size << ")" + << std::endl; + print_graph(subgraph1); + std::cout << std::endl; - // Explore the entire space - return (true); - } + // Explore the entire space + return (true); + } private: - const Graph& m_graph1; - VertexSizeFirst m_max_subgraph_size; + const Graph& m_graph1; + VertexSizeFirst m_max_subgraph_size; }; -int main (int argc, char *argv[]) { - - // Using a vecS graph here so that we don't have to mess around with - // a vertex index map; it will be implicit. - typedef adjacency_list >, - property > Graph; - - typedef property_map::type VertexNameMap; - - // Test maximum and unique variants on known graphs - Graph graph_simple1, graph_simple2; - example_callback user_callback(graph_simple1); - - VertexNameMap vname_map_simple1 = get(vertex_name, graph_simple1); - VertexNameMap vname_map_simple2 = get(vertex_name, graph_simple2); - - // Graph that looks like a triangle - put(vname_map_simple1, add_vertex(graph_simple1), 1); - put(vname_map_simple1, add_vertex(graph_simple1), 2); - put(vname_map_simple1, add_vertex(graph_simple1), 3); - - add_edge(0, 1, graph_simple1); - add_edge(0, 2, graph_simple1); - add_edge(1, 2, graph_simple1); - - std::cout << "First graph:" << std::endl; - print_graph(graph_simple1); - std::cout << std::endl; - - // Triangle with an extra vertex - put(vname_map_simple2, add_vertex(graph_simple2), 1); - put(vname_map_simple2, add_vertex(graph_simple2), 2); - put(vname_map_simple2, add_vertex(graph_simple2), 3); - put(vname_map_simple2, add_vertex(graph_simple2), 4); - - add_edge(0, 1, graph_simple2); - add_edge(0, 2, graph_simple2); - add_edge(1, 2, graph_simple2); - add_edge(1, 3, graph_simple2); - - std::cout << "Second graph:" << std::endl; - print_graph(graph_simple2); - std::cout << std::endl; - - // All subgraphs - std::cout << "mcgregor_common_subgraphs:" << std::endl; - mcgregor_common_subgraphs - (graph_simple1, graph_simple2, true, user_callback, - vertices_equivalent(make_property_map_equivalent(vname_map_simple1, vname_map_simple2))); - std::cout << std::endl; - - // Unique subgraphs - std::cout << "mcgregor_common_subgraphs_unique:" << std::endl; - mcgregor_common_subgraphs_unique - (graph_simple1, graph_simple2, true, user_callback, - vertices_equivalent(make_property_map_equivalent(vname_map_simple1, vname_map_simple2))); - std::cout << std::endl; - - // Maximum subgraphs - std::cout << "mcgregor_common_subgraphs_maximum:" << std::endl; - mcgregor_common_subgraphs_maximum - (graph_simple1, graph_simple2, true, user_callback, - vertices_equivalent(make_property_map_equivalent(vname_map_simple1, vname_map_simple2))); - std::cout << std::endl; - - // Maximum, unique subgraphs - std::cout << "mcgregor_common_subgraphs_maximum_unique:" << std::endl; - mcgregor_common_subgraphs_maximum_unique - (graph_simple1, graph_simple2, true, user_callback, - vertices_equivalent(make_property_map_equivalent(vname_map_simple1, vname_map_simple2))); - - return 0; +int main(int argc, char* argv[]) +{ + + // Using a vecS graph here so that we don't have to mess around with + // a vertex index map; it will be implicit. + typedef adjacency_list< listS, vecS, directedS, + property< vertex_name_t, unsigned int, + property< vertex_index_t, unsigned int > >, + property< edge_name_t, unsigned int > > + Graph; + + typedef property_map< Graph, vertex_name_t >::type VertexNameMap; + + // Test maximum and unique variants on known graphs + Graph graph_simple1, graph_simple2; + example_callback< Graph > user_callback(graph_simple1); + + VertexNameMap vname_map_simple1 = get(vertex_name, graph_simple1); + VertexNameMap vname_map_simple2 = get(vertex_name, graph_simple2); + + // Graph that looks like a triangle + put(vname_map_simple1, add_vertex(graph_simple1), 1); + put(vname_map_simple1, add_vertex(graph_simple1), 2); + put(vname_map_simple1, add_vertex(graph_simple1), 3); + + add_edge(0, 1, graph_simple1); + add_edge(0, 2, graph_simple1); + add_edge(1, 2, graph_simple1); + + std::cout << "First graph:" << std::endl; + print_graph(graph_simple1); + std::cout << std::endl; + + // Triangle with an extra vertex + put(vname_map_simple2, add_vertex(graph_simple2), 1); + put(vname_map_simple2, add_vertex(graph_simple2), 2); + put(vname_map_simple2, add_vertex(graph_simple2), 3); + put(vname_map_simple2, add_vertex(graph_simple2), 4); + + add_edge(0, 1, graph_simple2); + add_edge(0, 2, graph_simple2); + add_edge(1, 2, graph_simple2); + add_edge(1, 3, graph_simple2); + + std::cout << "Second graph:" << std::endl; + print_graph(graph_simple2); + std::cout << std::endl; + + // All subgraphs + std::cout << "mcgregor_common_subgraphs:" << std::endl; + mcgregor_common_subgraphs(graph_simple1, graph_simple2, true, user_callback, + vertices_equivalent(make_property_map_equivalent( + vname_map_simple1, vname_map_simple2))); + std::cout << std::endl; + + // Unique subgraphs + std::cout << "mcgregor_common_subgraphs_unique:" << std::endl; + mcgregor_common_subgraphs_unique(graph_simple1, graph_simple2, true, + user_callback, + vertices_equivalent(make_property_map_equivalent( + vname_map_simple1, vname_map_simple2))); + std::cout << std::endl; + + // Maximum subgraphs + std::cout << "mcgregor_common_subgraphs_maximum:" << std::endl; + mcgregor_common_subgraphs_maximum(graph_simple1, graph_simple2, true, + user_callback, + vertices_equivalent(make_property_map_equivalent( + vname_map_simple1, vname_map_simple2))); + std::cout << std::endl; + + // Maximum, unique subgraphs + std::cout << "mcgregor_common_subgraphs_maximum_unique:" << std::endl; + mcgregor_common_subgraphs_maximum_unique(graph_simple1, graph_simple2, true, + user_callback, + vertices_equivalent(make_property_map_equivalent( + vname_map_simple1, vname_map_simple2))); + + return 0; } diff --git a/example/mean_geodesic.cpp b/example/mean_geodesic.cpp index ca246b0a2..d0cfee821 100644 --- a/example/mean_geodesic.cpp +++ b/example/mean_geodesic.cpp @@ -24,32 +24,31 @@ struct Actor }; // Declare the graph type and its vertex and edge types. -typedef undirected_graph Graph; -typedef graph_traits::vertex_descriptor Vertex; -typedef graph_traits::edge_descriptor Edge; +typedef undirected_graph< Actor > Graph; +typedef graph_traits< Graph >::vertex_descriptor Vertex; +typedef graph_traits< Graph >::edge_descriptor Edge; // The name map provides an abstract accessor for the names of // each vertex. This is used during graph creation. -typedef property_map::type NameMap; +typedef property_map< Graph, string Actor::* >::type NameMap; // Declare a matrix type and its corresponding property map that // will contain the distances between each pair of vertices. -typedef exterior_vertex_property DistanceProperty; +typedef exterior_vertex_property< Graph, int > DistanceProperty; typedef DistanceProperty::matrix_type DistanceMatrix; typedef DistanceProperty::matrix_map_type DistanceMatrixMap; // Declare the weight map so that each edge returns the same value. -typedef constant_property_map WeightMap; +typedef constant_property_map< Edge, int > WeightMap; // Declare a container and its corresponding property map that // will contain the resulting mean geodesic distances of each // vertex in the graph. -typedef exterior_vertex_property GeodesicProperty; +typedef exterior_vertex_property< Graph, float > GeodesicProperty; typedef GeodesicProperty::container_type GeodesicContainer; typedef GeodesicProperty::map_type GeodesicMap; -int -main(int argc, char *argv[]) +int main(int argc, char* argv[]) { // Create the graph and a property map that provides access // to the actor names. @@ -76,14 +75,14 @@ main(int argc, char *argv[]) // Print the mean geodesic distance of each vertex and finally, // the graph itself. - graph_traits::vertex_iterator i, end; - for(boost::tie(i, end) = vertices(g); i != end; ++i) { - cout << setw(12) << setiosflags(ios::left) - << g[*i].name << get(gm, *i) << endl; + graph_traits< Graph >::vertex_iterator i, end; + for (boost::tie(i, end) = vertices(g); i != end; ++i) + { + cout << setw(12) << setiosflags(ios::left) << g[*i].name << get(gm, *i) + << endl; } cout << "small world distance: " << sw << endl; - return 0; } //] diff --git a/example/miles_span.cpp b/example/miles_span.cpp index e90586732..d09c7f6f9 100644 --- a/example/miles_span.cpp +++ b/example/miles_span.cpp @@ -22,87 +22,105 @@ // A visitor class for accumulating the total length of the minimum // spanning tree. The Distance template parameter is for a // PropertyMap. -template -struct total_length_visitor : public boost::dijkstra_visitor<> { - typedef typename boost::property_traits::value_type D; - total_length_visitor(D& len, Distance d) - : _total_length(len), _distance(d) { } - template - inline void finish_vertex(Vertex s, Graph& g) { - _total_length += boost::get(_distance, s); - } - D& _total_length; - Distance _distance; +template < class Distance > +struct total_length_visitor : public boost::dijkstra_visitor<> +{ + typedef typename boost::property_traits< Distance >::value_type D; + total_length_visitor(D& len, Distance d) : _total_length(len), _distance(d) + { + } + template < class Vertex, class Graph > + inline void finish_vertex(Vertex s, Graph& g) + { + _total_length += boost::get(_distance, s); + } + D& _total_length; + Distance _distance; }; int main(int argc, char* argv[]) { - using namespace boost; - Graph* g; + using namespace boost; + Graph* g; - unsigned long n = 100; - unsigned long n_weight = 0; - unsigned long w_weight = 0; - unsigned long p_weight = 0; - unsigned long d = 10; - long s = 0; - unsigned long r = 1; - char* file_name = NULL; + unsigned long n = 100; + unsigned long n_weight = 0; + unsigned long w_weight = 0; + unsigned long p_weight = 0; + unsigned long d = 10; + long s = 0; + unsigned long r = 1; + char* file_name = NULL; - while(--argc){ - if(sscanf(argv[argc],"-n%lu",&n)==1); - else if(sscanf(argv[argc],"-N%lu",&n_weight)==1); - else if(sscanf(argv[argc],"-W%lu",&w_weight)==1); - else if(sscanf(argv[argc],"-P%lu",&p_weight)==1); - else if(sscanf(argv[argc],"-d%lu",&d)==1); - else if(sscanf(argv[argc],"-r%lu",&r)==1); - else if(sscanf(argv[argc],"-s%ld",&s)==1); - else if(strcmp(argv[argc],"-v")==0) verbose = 1; - else if(strncmp(argv[argc],"-g",2)==0) file_name = argv[argc]+2; - else{ - fprintf(stderr, - "Usage: %s [-nN][-dN][-rN][-sN][-NN][-WN][-PN][-v][-gfoo]\n", - argv[0]); - return -2; + while (--argc) + { + if (sscanf(argv[argc], "-n%lu", &n) == 1) + ; + else if (sscanf(argv[argc], "-N%lu", &n_weight) == 1) + ; + else if (sscanf(argv[argc], "-W%lu", &w_weight) == 1) + ; + else if (sscanf(argv[argc], "-P%lu", &p_weight) == 1) + ; + else if (sscanf(argv[argc], "-d%lu", &d) == 1) + ; + else if (sscanf(argv[argc], "-r%lu", &r) == 1) + ; + else if (sscanf(argv[argc], "-s%ld", &s) == 1) + ; + else if (strcmp(argv[argc], "-v") == 0) + verbose = 1; + else if (strncmp(argv[argc], "-g", 2) == 0) + file_name = argv[argc] + 2; + else + { + fprintf(stderr, + "Usage: %s [-nN][-dN][-rN][-sN][-NN][-WN][-PN][-v][-gfoo]\n", + argv[0]); + return -2; + } } - } - if (file_name) r = 1; - - while (r--) { if (file_name) - g = restore_graph(file_name); - else - g = miles(n,n_weight,w_weight,p_weight,0L,d,s); + r = 1; - if(g == NULL || g->n <= 1) { - fprintf(stderr,"Sorry, can't create the graph! (error code %ld)\n", - panic_code); - return-1; - } + while (r--) + { + if (file_name) + g = restore_graph(file_name); + else + g = miles(n, n_weight, w_weight, p_weight, 0L, d, s); + + if (g == NULL || g->n <= 1) + { + fprintf(stderr, "Sorry, can't create the graph! (error code %ld)\n", + panic_code); + return -1; + } - printf("The graph %s has %ld edges,\n", g->id, g->m / 2); + printf("The graph %s has %ld edges,\n", g->id, g->m / 2); - long sp_length = 0; + long sp_length = 0; - // Use the "z" utility field for distance. - typedef property_map >::type Distance; - Distance d = get(z_property(), g); - // Use the "w" property for parent - typedef property_map >::type Parent; - Parent p = get(w_property(), g); - total_length_visitor length_vis(sp_length, d); + // Use the "z" utility field for distance. + typedef property_map< Graph*, z_property< long > >::type Distance; + Distance d = get(z_property< long >(), g); + // Use the "w" property for parent + typedef property_map< Graph*, w_property< Vertex* > >::type Parent; + Parent p = get(w_property< Vertex* >(), g); + total_length_visitor< Distance > length_vis(sp_length, d); - prim_minimum_spanning_tree(g, p, - distance_map(get(z_property(), g)). - weight_map(get(edge_length_t(), g)). - // Use the "y" utility field for color - color_map(get(y_property(), g)). - visitor(length_vis)); + prim_minimum_spanning_tree(g, p, + distance_map(get(z_property< long >(), g)) + .weight_map(get(edge_length_t(), g)) + . + // Use the "y" utility field for color + color_map(get(y_property< long >(), g)) + .visitor(length_vis)); - printf(" and its minimum spanning tree has length %ld.\n", sp_length); + printf(" and its minimum spanning tree has length %ld.\n", sp_length); - gb_recycle(g); - s++; - } - return 0; + gb_recycle(g); + s++; + } + return 0; } diff --git a/example/min_max_paths.cpp b/example/min_max_paths.cpp index f32dd76e2..fabf4c942 100644 --- a/example/min_max_paths.cpp +++ b/example/min_max_paths.cpp @@ -7,7 +7,8 @@ // http://www.boost.org/LICENSE_1_0.txt) //======================================================================= -#error "This example appears to be incorrect; it uses edge weights that are smaller than 0 using the comparison operator passed to Dijkstra's algorithm, which is not allowed." +#error \ + "This example appears to be incorrect; it uses edge weights that are smaller than 0 using the comparison operator passed to Dijkstra's algorithm, which is not allowed." #include #include @@ -29,77 +30,77 @@ distance(e) = 3 min-max paths tree - a --> c - b --> - c --> d - d --> e - e --> b + a --> c + b --> + c --> d + d --> e + e --> b */ -int -main(int , char* []) +int main(int, char*[]) { - using namespace boost; + using namespace boost; - typedef adjacency_list > Graph; - typedef graph_traits::vertex_descriptor Vertex; + typedef adjacency_list< listS, vecS, directedS, no_property, + property< edge_weight_t, int > > + Graph; + typedef graph_traits< Graph >::vertex_descriptor Vertex; - typedef std::pair E; + typedef std::pair< int, int > E; - const char name[] = "abcdef"; + const char name[] = "abcdef"; - const int num_nodes = 6; - E edges[] = { E(0,2), E(1,1), E(1,3), E(1,4), E(2,1), E(2,3), - E(3,4), E(4,0), E(4,1) }; - int weights[] = { 1, 2, 1, 2, 7, 3, 1, 1, 1}; - const int n_edges = sizeof(edges)/sizeof(E); + const int num_nodes = 6; + E edges[] = { E(0, 2), E(1, 1), E(1, 3), E(1, 4), E(2, 1), E(2, 3), E(3, 4), + E(4, 0), E(4, 1) }; + int weights[] = { 1, 2, 1, 2, 7, 3, 1, 1, 1 }; + const int n_edges = sizeof(edges) / sizeof(E); #if defined(BOOST_MSVC) && BOOST_MSVC <= 1300 - // VC++ can't handle iterator constructors - Graph G(num_nodes); - property_map::type weightmap = get(edge_weight, G); - for (std::size_t j = 0; j < sizeof(edges) / sizeof(E); ++j) { - graph_traits::edge_descriptor e; bool inserted; - boost::tie(e, inserted) = add_edge(edges[j].first, edges[j].second, G); - weightmap[e] = weights[j]; - } + // VC++ can't handle iterator constructors + Graph G(num_nodes); + property_map< Graph, edge_weight_t >::type weightmap = get(edge_weight, G); + for (std::size_t j = 0; j < sizeof(edges) / sizeof(E); ++j) + { + graph_traits< Graph >::edge_descriptor e; + bool inserted; + boost::tie(e, inserted) = add_edge(edges[j].first, edges[j].second, G); + weightmap[e] = weights[j]; + } #else - Graph G(edges, edges + n_edges, weights, num_nodes); - property_map::type weightmap = get(edge_weight, G); + Graph G(edges, edges + n_edges, weights, num_nodes); + property_map< Graph, edge_weight_t >::type weightmap = get(edge_weight, G); #endif - std::vector p(num_vertices(G)); - std::vector d(num_vertices(G)); + std::vector< Vertex > p(num_vertices(G)); + std::vector< int > d(num_vertices(G)); - Vertex s = *(vertices(G).first); + Vertex s = *(vertices(G).first); #if defined(BOOST_MSVC) && BOOST_MSVC <= 1300 - dijkstra_shortest_paths - (G, s, &p[0], &d[0], weightmap, get(vertex_index, G), - std::greater(), closed_plus(), (std::numeric_limits::max)(), 0, - default_dijkstra_visitor()); + dijkstra_shortest_paths(G, s, &p[0], &d[0], weightmap, get(vertex_index, G), + std::greater< int >(), closed_plus< int >(), + (std::numeric_limits< int >::max)(), 0, default_dijkstra_visitor()); #else - dijkstra_shortest_paths - (G, s, distance_map(&d[0]). - predecessor_map(&p[0]). - distance_compare(std::greater())); + dijkstra_shortest_paths(G, s, + distance_map(&d[0]).predecessor_map(&p[0]).distance_compare( + std::greater< int >())); #endif - std::cout << "distances from start vertex:" << std::endl; - graph_traits::vertex_iterator vi, vend; - for(boost::tie(vi,vend) = vertices(G); vi != vend; ++vi) - std::cout << "distance(" << name[*vi] << ") = " << d[*vi] << std::endl; - std::cout << std::endl; + std::cout << "distances from start vertex:" << std::endl; + graph_traits< Graph >::vertex_iterator vi, vend; + for (boost::tie(vi, vend) = vertices(G); vi != vend; ++vi) + std::cout << "distance(" << name[*vi] << ") = " << d[*vi] << std::endl; + std::cout << std::endl; - std::cout << "min-max paths tree" << std::endl; - adjacency_list<> tree(num_nodes); - - for(boost::tie(vi,vend) = vertices(G); vi != vend; ++vi) - if (*vi != p[*vi]) - add_edge(p[*vi], *vi, tree); + std::cout << "min-max paths tree" << std::endl; + adjacency_list<> tree(num_nodes); - print_graph(tree, name); + for (boost::tie(vi, vend) = vertices(G); vi != vend; ++vi) + if (*vi != p[*vi]) + add_edge(p[*vi], *vi, tree); - return 0; + print_graph(tree, name); + + return 0; } diff --git a/example/minimum_degree_ordering.cpp b/example/minimum_degree_ordering.cpp index 7eb0051b5..c096ccf6d 100644 --- a/example/minimum_degree_ordering.cpp +++ b/example/minimum_degree_ordering.cpp @@ -10,7 +10,7 @@ /* This file is to demo how to use minimum_degree_ordering algorithm. - + Important Note: This implementation requires the BGL graph to be directed. Therefore, nonzero entry (i, j) in a symmetrical matrix A coresponds to two directed edges (i->j and j->i). @@ -33,152 +33,167 @@ void terminate(const char* msg) { - std::cerr << msg << std::endl; - abort(); + std::cerr << msg << std::endl; + abort(); } -//copy and modify from mtl harwell boeing stream +// copy and modify from mtl harwell boeing stream struct harwell_boeing { - harwell_boeing(char* filename) { - int Nrhs; - char* Type; - Type = new char[4]; - isComplex = false; - // Never called: - //readHB_info(filename, &M, &N, &nonzeros, &Type, &Nrhs); - colptr = (int *)malloc((N+1)*sizeof(int)); - if ( colptr == NULL ) terminate("Insufficient memory for colptr.\n"); - rowind = (int *)malloc(nonzeros*sizeof(int)); - if ( rowind == NULL ) terminate("Insufficient memory for rowind.\n"); - - if ( Type[0] == 'C' ) { - isComplex = true; - val = (double *)malloc(nonzeros*sizeof(double)*2); - if ( val == NULL ) terminate("Insufficient memory for val.\n"); - - } else { - if ( Type[0] != 'P' ) { - val = (double *)malloc(nonzeros*sizeof(double)); - if ( val == NULL ) terminate("Insufficient memory for val.\n"); - } + harwell_boeing(char* filename) + { + int Nrhs; + char* Type; + Type = new char[4]; + isComplex = false; + // Never called: + // readHB_info(filename, &M, &N, &nonzeros, &Type, &Nrhs); + colptr = (int*)malloc((N + 1) * sizeof(int)); + if (colptr == NULL) + terminate("Insufficient memory for colptr.\n"); + rowind = (int*)malloc(nonzeros * sizeof(int)); + if (rowind == NULL) + terminate("Insufficient memory for rowind.\n"); + + if (Type[0] == 'C') + { + isComplex = true; + val = (double*)malloc(nonzeros * sizeof(double) * 2); + if (val == NULL) + terminate("Insufficient memory for val.\n"); + } + else + { + if (Type[0] != 'P') + { + val = (double*)malloc(nonzeros * sizeof(double)); + if (val == NULL) + terminate("Insufficient memory for val.\n"); + } + } + // Never called: + // readHB_mat_double(filename, colptr, rowind, val); + + cnt = 0; + col = 0; + delete[] Type; } - // Never called: - //readHB_mat_double(filename, colptr, rowind, val); - - cnt = 0; - col = 0; - delete [] Type; - } - - ~harwell_boeing() { - free(colptr); - free(rowind); - free(val); - } - - inline int nrows() const { return M; } - - int cnt; - int col; - int* colptr; - bool isComplex; - int M; - int N; - int nonzeros; - int* rowind; - double* val; -}; - -int main(int argc, char* argv[]) -{ - using namespace std; - using namespace boost; - - if (argc < 2) { - cout << argv[0] << " HB file" << endl; - return -1; - } - - int delta = 0; - - if ( argc >= 4 ) - delta = atoi(argv[3]); - - harwell_boeing hbs(argv[1]); - - //must be BGL directed graph now - typedef adjacency_list Graph; - - int n = hbs.nrows(); - - cout << "n is " << n << endl; - - Graph G(n); - int num_edge = 0; - - for (int i = 0; i < n; ++i) - for (int j = hbs.colptr[i]; j < hbs.colptr[i+1]; ++j) - if ( (hbs.rowind[j - 1] - 1 ) > i ) { - add_edge(hbs.rowind[j - 1] - 1, i, G); - add_edge(i, hbs.rowind[j - 1] - 1, G); - num_edge++; - } - - cout << "number of off-diagnal elements: " << num_edge << endl; - - typedef std::vector Vector; - - Vector inverse_perm(n, 0); - Vector perm(n, 0); - - Vector supernode_sizes(n, 1); // init has to be 1 - - boost::property_map::type - id = get(vertex_index, G); + ~harwell_boeing() + { + free(colptr); + free(rowind); + free(val); + } - Vector degree(n, 0); + inline int nrows() const { return M; } + + int cnt; + int col; + int* colptr; + bool isComplex; + int M; + int N; + int nonzeros; + int* rowind; + double* val; +}; - minimum_degree_ordering - (G, - make_iterator_property_map(°ree[0], id, degree[0]), - &inverse_perm[0], - &perm[0], - make_iterator_property_map(&supernode_sizes[0], id, supernode_sizes[0]), - delta, id); +int main(int argc, char* argv[]) +{ + using namespace std; + using namespace boost; - if ( argc >= 3 ) { - ifstream input(argv[2]); - if ( input.fail() ) { - cout << argv[3] << " is failed to open!. " << endl; - return -1; + if (argc < 2) + { + cout << argv[0] << " HB file" << endl; + return -1; } - int comp; - bool is_correct = true; - int i; - for ( i=0; i> comp; - if ( comp != inverse_perm[i]+1 ) { - cout << "at i= " << i << ": " << comp - << " ***is NOT EQUAL to*** " << inverse_perm[i]+1 << endl; - is_correct = false; - } - } - for ( i=0; i> comp; - if ( comp != perm[i]+1 ) { - cout << "at i= " << i << ": " << comp - << " ***is NOT EQUAL to*** " << perm[i]+1 << endl; - is_correct = false; - } + + int delta = 0; + + if (argc >= 4) + delta = atoi(argv[3]); + + harwell_boeing hbs(argv[1]); + + // must be BGL directed graph now + typedef adjacency_list< vecS, vecS, directedS > Graph; + + int n = hbs.nrows(); + + cout << "n is " << n << endl; + + Graph G(n); + + int num_edge = 0; + + for (int i = 0; i < n; ++i) + for (int j = hbs.colptr[i]; j < hbs.colptr[i + 1]; ++j) + if ((hbs.rowind[j - 1] - 1) > i) + { + add_edge(hbs.rowind[j - 1] - 1, i, G); + add_edge(i, hbs.rowind[j - 1] - 1, G); + num_edge++; + } + + cout << "number of off-diagnal elements: " << num_edge << endl; + + typedef std::vector< int > Vector; + + Vector inverse_perm(n, 0); + Vector perm(n, 0); + + Vector supernode_sizes(n, 1); // init has to be 1 + + boost::property_map< Graph, vertex_index_t >::type id + = get(vertex_index, G); + + Vector degree(n, 0); + + minimum_degree_ordering(G, + make_iterator_property_map(°ree[0], id, degree[0]), &inverse_perm[0], + &perm[0], + make_iterator_property_map(&supernode_sizes[0], id, supernode_sizes[0]), + delta, id); + + if (argc >= 3) + { + ifstream input(argv[2]); + if (input.fail()) + { + cout << argv[3] << " is failed to open!. " << endl; + return -1; + } + int comp; + bool is_correct = true; + int i; + for (i = 0; i < n; i++) + { + input >> comp; + if (comp != inverse_perm[i] + 1) + { + cout << "at i= " << i << ": " << comp + << " ***is NOT EQUAL to*** " << inverse_perm[i] + 1 + << endl; + is_correct = false; + } + } + for (i = 0; i < n; i++) + { + input >> comp; + if (comp != perm[i] + 1) + { + cout << "at i= " << i << ": " << comp + << " ***is NOT EQUAL to*** " << perm[i] + 1 << endl; + is_correct = false; + } + } + if (is_correct) + cout << "Permutation and inverse permutation are correct. " << endl; + else + cout << "WARNING -- Permutation or inverse permutation is not the " + << "same ones generated by Liu's " << endl; } - if ( is_correct ) - cout << "Permutation and inverse permutation are correct. "<< endl; - else - cout << "WARNING -- Permutation or inverse permutation is not the " - << "same ones generated by Liu's " << endl; - - } - return 0; + return 0; } diff --git a/example/modify_graph.cpp b/example/modify_graph.cpp index 42b668cb5..9c8836e07 100644 --- a/example/modify_graph.cpp +++ b/example/modify_graph.cpp @@ -15,189 +15,194 @@ using namespace boost; -// Predicate Function for use in remove if -template -struct name_equals_predicate +// Predicate Function for use in remove if +template < class NamePropertyMap > struct name_equals_predicate { - name_equals_predicate(const std::string& x, NamePropertyMap name) - : m_str(x), m_name(name) { } - - template - bool operator()(const Edge& e) const { - return m_str == m_name[e]; - } - std::string m_str; - NamePropertyMap m_name; + name_equals_predicate(const std::string& x, NamePropertyMap name) + : m_str(x), m_name(name) + { + } + + template < class Edge > bool operator()(const Edge& e) const + { + return m_str == m_name[e]; + } + std::string m_str; + NamePropertyMap m_name; }; // helper creation function -template -inline name_equals_predicate -name_equals(const std::string& str, NamePropertyMap name) { - return name_equals_predicate(str, name); +template < class NamePropertyMap > +inline name_equals_predicate< NamePropertyMap > name_equals( + const std::string& str, NamePropertyMap name) +{ + return name_equals_predicate< NamePropertyMap >(str, name); } -template -void modify_demo(MutableGraph& g) +template < class MutableGraph > void modify_demo(MutableGraph& g) { - typedef graph_traits GraphTraits; - typedef typename GraphTraits::vertices_size_type size_type; - typedef typename GraphTraits::edge_descriptor edge_descriptor; - size_type n = 0; - typename GraphTraits::edges_size_type m = 0; - typename GraphTraits::vertex_descriptor u, v, w; - edge_descriptor e, e1, e2; - typename property_map::type - name_map = get(edge_name, g); - bool added; - typename GraphTraits::vertex_iterator vi, vi_end; - - { - v = add_vertex(g); - - assert(num_vertices(g) == n + 1); - assert(size_type(vertices(g).second - vertices(g).first) == n + 1); - assert(v == *std::find(vertices(g).first, vertices(g).second, v)); - } - { - remove_vertex(v, g); - - assert(num_vertices(g) == n); - assert(size_type(vertices(g).second - vertices(g).first) == n); - // v is no longer a valid vertex descriptor - } - { - u = add_vertex(g); - v = add_vertex(g); - - std::pair p = add_edge(u, v, g); - - assert(num_edges(g) == m + 1); - assert(p.second == true); // edge should have been added - assert(source(p.first, g) == u); - assert(target(p.first, g) == v); - assert(p.first == *std::find(out_edges(u, g).first, - out_edges(u, g).second, p.first)); - assert(p.first == *std::find(in_edges(v, g).first, - in_edges(v, g).second, p.first)); - } - { - // use tie() for convenience, avoid using the std::pair - - u = add_vertex(g); - v = add_vertex(g); - - boost::tie(e, added) = add_edge(u, v, g); - - assert(num_edges(g) == m + 2); - assert(added == true); // edge should have been added - assert(source(e, g) == u); - assert(target(e, g) == v); - assert(e == *std::find(out_edges(u, g).first, out_edges(u, g).second, e)); - assert(e == *std::find(in_edges(v, g).first, in_edges(v, g).second, e)); - } - { - add_edge(u, v, g); // add a parallel edge - - remove_edge(u, v, g); - - assert(num_edges(g) == m + 1); - bool exists; - boost::tie(e, exists) = edge(u, v, g); - assert(exists == false); - assert(out_degree(u, g) == 0); - assert(in_degree(v, g) == 0); - } - { - e = *edges(g).first; - boost::tie(u, v) = incident(e, g); - - remove_edge(e, g); - - assert(num_edges(g) == m); - assert(out_degree(u, g) == 0); - assert(in_degree(v, g) == 0); - } - { - add_edge(u, v, g); - - typename GraphTraits::out_edge_iterator iter, iter_end; - boost::tie(iter, iter_end) = out_edges(u, g); - - remove_edge(iter, g); - - assert(num_edges(g) == m); - assert(out_degree(u, g) == 0); - assert(in_degree(v, g) == 0); - } - { - w = add_vertex(g); - boost::tie(e1, added) = add_edge(u, v, g); - boost::tie(e2, added) = add_edge(v, w, g); - name_map[e1] = "I-5"; - name_map[e2] = "Route 66"; - - typename GraphTraits::out_edge_iterator iter, iter_end; - boost::tie(iter, iter_end) = out_edges(u, g); - - remove_edge_if(name_equals("Route 66", name_map), g); - - assert(num_edges(g) == m + 1); - - remove_edge_if(name_equals("I-5", name_map), g); - - assert(num_edges(g) == m); - assert(out_degree(u, g) == 0); - assert(out_degree(v, g) == 0); - assert(in_degree(v, g) == 0); - assert(in_degree(w, g) == 0); - } - { - boost::tie(e1, added) = add_edge(u, v, g); - boost::tie(e2, added) = add_edge(u, w, g); - name_map[e1] = "foo"; - name_map[e2] = "foo"; - - remove_out_edge_if(u, name_equals("foo", name_map), g); - - assert(num_edges(g) == m); - assert(out_degree(u, g) == 0); - } - { - boost::tie(e1, added) = add_edge(u, v, g); - boost::tie(e2, added) = add_edge(w, v, g); - name_map[e1] = "bar"; - name_map[e2] = "bar"; - - remove_in_edge_if(v, name_equals("bar", name_map), g); - - assert(num_edges(g) == m); - assert(in_degree(v, g) == 0); - } - { - add_edge(u, v, g); - add_edge(u, w, g); - add_edge(u, v, g); - add_edge(v, u, g); - - clear_vertex(u, g); - - assert(out_degree(u, g) == 0); - - for (boost::tie(vi, vi_end) = vertices(g); vi != vi_end; ++vi) { - typename GraphTraits::adjacency_iterator ai, ai_end; - for (boost::tie(ai, ai_end) = adjacent_vertices(*vi, g); - ai != ai_end; ++ai) - assert(*ai != u); + typedef graph_traits< MutableGraph > GraphTraits; + typedef typename GraphTraits::vertices_size_type size_type; + typedef typename GraphTraits::edge_descriptor edge_descriptor; + size_type n = 0; + typename GraphTraits::edges_size_type m = 0; + typename GraphTraits::vertex_descriptor u, v, w; + edge_descriptor e, e1, e2; + typename property_map< MutableGraph, edge_name_t >::type name_map + = get(edge_name, g); + bool added; + typename GraphTraits::vertex_iterator vi, vi_end; + + { + v = add_vertex(g); + + assert(num_vertices(g) == n + 1); + assert(size_type(vertices(g).second - vertices(g).first) == n + 1); + assert(v == *std::find(vertices(g).first, vertices(g).second, v)); + } + { + remove_vertex(v, g); + + assert(num_vertices(g) == n); + assert(size_type(vertices(g).second - vertices(g).first) == n); + // v is no longer a valid vertex descriptor + } + { + u = add_vertex(g); + v = add_vertex(g); + + std::pair< edge_descriptor, bool > p = add_edge(u, v, g); + + assert(num_edges(g) == m + 1); + assert(p.second == true); // edge should have been added + assert(source(p.first, g) == u); + assert(target(p.first, g) == v); + assert(p.first + == *std::find( + out_edges(u, g).first, out_edges(u, g).second, p.first)); + assert(p.first + == *std::find( + in_edges(v, g).first, in_edges(v, g).second, p.first)); + } + { + // use tie() for convenience, avoid using the std::pair + + u = add_vertex(g); + v = add_vertex(g); + + boost::tie(e, added) = add_edge(u, v, g); + + assert(num_edges(g) == m + 2); + assert(added == true); // edge should have been added + assert(source(e, g) == u); + assert(target(e, g) == v); + assert( + e == *std::find(out_edges(u, g).first, out_edges(u, g).second, e)); + assert(e == *std::find(in_edges(v, g).first, in_edges(v, g).second, e)); + } + { + add_edge(u, v, g); // add a parallel edge + + remove_edge(u, v, g); + + assert(num_edges(g) == m + 1); + bool exists; + boost::tie(e, exists) = edge(u, v, g); + assert(exists == false); + assert(out_degree(u, g) == 0); + assert(in_degree(v, g) == 0); + } + { + e = *edges(g).first; + boost::tie(u, v) = incident(e, g); + + remove_edge(e, g); + + assert(num_edges(g) == m); + assert(out_degree(u, g) == 0); + assert(in_degree(v, g) == 0); + } + { + add_edge(u, v, g); + + typename GraphTraits::out_edge_iterator iter, iter_end; + boost::tie(iter, iter_end) = out_edges(u, g); + + remove_edge(iter, g); + + assert(num_edges(g) == m); + assert(out_degree(u, g) == 0); + assert(in_degree(v, g) == 0); + } + { + w = add_vertex(g); + boost::tie(e1, added) = add_edge(u, v, g); + boost::tie(e2, added) = add_edge(v, w, g); + name_map[e1] = "I-5"; + name_map[e2] = "Route 66"; + + typename GraphTraits::out_edge_iterator iter, iter_end; + boost::tie(iter, iter_end) = out_edges(u, g); + + remove_edge_if(name_equals("Route 66", name_map), g); + + assert(num_edges(g) == m + 1); + + remove_edge_if(name_equals("I-5", name_map), g); + + assert(num_edges(g) == m); + assert(out_degree(u, g) == 0); + assert(out_degree(v, g) == 0); + assert(in_degree(v, g) == 0); + assert(in_degree(w, g) == 0); + } + { + boost::tie(e1, added) = add_edge(u, v, g); + boost::tie(e2, added) = add_edge(u, w, g); + name_map[e1] = "foo"; + name_map[e2] = "foo"; + + remove_out_edge_if(u, name_equals("foo", name_map), g); + + assert(num_edges(g) == m); + assert(out_degree(u, g) == 0); + } + { + boost::tie(e1, added) = add_edge(u, v, g); + boost::tie(e2, added) = add_edge(w, v, g); + name_map[e1] = "bar"; + name_map[e2] = "bar"; + + remove_in_edge_if(v, name_equals("bar", name_map), g); + + assert(num_edges(g) == m); + assert(in_degree(v, g) == 0); + } + { + add_edge(u, v, g); + add_edge(u, w, g); + add_edge(u, v, g); + add_edge(v, u, g); + + clear_vertex(u, g); + + assert(out_degree(u, g) == 0); + + for (boost::tie(vi, vi_end) = vertices(g); vi != vi_end; ++vi) + { + typename GraphTraits::adjacency_iterator ai, ai_end; + for (boost::tie(ai, ai_end) = adjacent_vertices(*vi, g); + ai != ai_end; ++ai) + assert(*ai != u); + } } - } } -int -main() +int main() { - adjacency_list > g; + adjacency_list< listS, vecS, bidirectionalS, no_property, + property< edge_name_t, std::string > > + g; - modify_demo(g); - return 0; + modify_demo(g); + return 0; } diff --git a/example/neighbor_bfs.cpp b/example/neighbor_bfs.cpp index 7b3e339ab..2beb4b6e9 100644 --- a/example/neighbor_bfs.cpp +++ b/example/neighbor_bfs.cpp @@ -21,15 +21,15 @@ #include /* - + Sample Output: - 0 --> 2 - 1 --> 1 3 4 - 2 --> 1 3 4 - 3 --> 1 4 - 4 --> 0 1 - distances: 0 2 1 2 1 + 0 --> 2 + 1 --> 1 3 4 + 2 --> 1 3 4 + 3 --> 1 4 + 4 --> 0 1 + distances: 0 2 1 2 1 parent[0] = 0 parent[1] = 2 parent[2] = 0 @@ -40,109 +40,110 @@ using namespace boost; -template -struct print_parent { - print_parent(const ParentDecorator& p_) : p(p_) { } - template - void operator()(const Vertex& v) const { - std::cout << "parent[" << v << "] = " << p[v] << std::endl; - } - ParentDecorator p; +template < class ParentDecorator > struct print_parent +{ + print_parent(const ParentDecorator& p_) : p(p_) {} + template < class Vertex > void operator()(const Vertex& v) const + { + std::cout << "parent[" << v << "] = " << p[v] << std::endl; + } + ParentDecorator p; }; -template +template < class DistanceMap, class PredecessorMap, class ColorMap > class distance_and_pred_visitor : public neighbor_bfs_visitor<> { - typedef typename property_traits::value_type ColorValue; - typedef color_traits Color; + typedef typename property_traits< ColorMap >::value_type ColorValue; + typedef color_traits< ColorValue > Color; + public: - distance_and_pred_visitor(DistanceMap d, PredecessorMap p, ColorMap c) - : m_distance(d), m_predecessor(p), m_color(c) { } - - template - void tree_out_edge(Edge e, const Graph& g) const - { - typename graph_traits::vertex_descriptor - u = source(e, g), v = target(e, g); - put(m_distance, v, get(m_distance, u) + 1); - put(m_predecessor, v, u); - } - template - void tree_in_edge(Edge e, const Graph& g) const - { - typename graph_traits::vertex_descriptor - u = source(e, g), v = target(e, g); - put(m_distance, u, get(m_distance, v) + 1); - put(m_predecessor, u, v); - } - - DistanceMap m_distance; - PredecessorMap m_predecessor; - ColorMap m_color; + distance_and_pred_visitor(DistanceMap d, PredecessorMap p, ColorMap c) + : m_distance(d), m_predecessor(p), m_color(c) + { + } + + template < class Edge, class Graph > + void tree_out_edge(Edge e, const Graph& g) const + { + typename graph_traits< Graph >::vertex_descriptor u = source(e, g), + v = target(e, g); + put(m_distance, v, get(m_distance, u) + 1); + put(m_predecessor, v, u); + } + template < class Edge, class Graph > + void tree_in_edge(Edge e, const Graph& g) const + { + typename graph_traits< Graph >::vertex_descriptor u = source(e, g), + v = target(e, g); + put(m_distance, u, get(m_distance, v) + 1); + put(m_predecessor, u, v); + } + + DistanceMap m_distance; + PredecessorMap m_predecessor; + ColorMap m_color; }; -int main(int , char* []) +int main(int, char*[]) { - typedef adjacency_list< - mapS, vecS, bidirectionalS, - property - > Graph; - - typedef property_map::type - ColorMap; - - Graph G(5); - add_edge(0, 2, G); - add_edge(1, 1, G); - add_edge(1, 3, G); - add_edge(1, 4, G); - add_edge(2, 1, G); - add_edge(2, 3, G); - add_edge(2, 4, G); - add_edge(3, 1, G); - add_edge(3, 4, G); - add_edge(4, 0, G); - add_edge(4, 1, G); - - typedef Graph::vertex_descriptor Vertex; - - // Array to store predecessor (parent) of each vertex. This will be - // used as a Decorator (actually, its iterator will be). - std::vector p(num_vertices(G)); - // VC++ version of std::vector has no ::pointer, so - // I use ::value_type* instead. - typedef std::vector::value_type* Piter; - - // Array to store distances from the source to each vertex . We use - // a built-in array here just for variety. This will also be used as - // a Decorator. - typedef graph_traits::vertices_size_type size_type; - size_type d[5]; - std::fill_n(d, 5, 0); - - // The source vertex - Vertex s = *(vertices(G).first); - p[s] = s; - distance_and_pred_visitor - vis(d, &p[0], get(vertex_color, G)); - neighbor_breadth_first_search - (G, s, visitor(vis). - color_map(get(vertex_color, G))); - - print_graph(G); - - if (num_vertices(G) < 11) { - std::cout << "distances: "; + typedef adjacency_list< mapS, vecS, bidirectionalS, + property< vertex_color_t, default_color_type > > + Graph; + + typedef property_map< Graph, vertex_color_t >::type ColorMap; + + Graph G(5); + add_edge(0, 2, G); + add_edge(1, 1, G); + add_edge(1, 3, G); + add_edge(1, 4, G); + add_edge(2, 1, G); + add_edge(2, 3, G); + add_edge(2, 4, G); + add_edge(3, 1, G); + add_edge(3, 4, G); + add_edge(4, 0, G); + add_edge(4, 1, G); + + typedef Graph::vertex_descriptor Vertex; + + // Array to store predecessor (parent) of each vertex. This will be + // used as a Decorator (actually, its iterator will be). + std::vector< Vertex > p(num_vertices(G)); + // VC++ version of std::vector has no ::pointer, so + // I use ::value_type* instead. + typedef std::vector< Vertex >::value_type* Piter; + + // Array to store distances from the source to each vertex . We use + // a built-in array here just for variety. This will also be used as + // a Decorator. + typedef graph_traits< Graph >::vertices_size_type size_type; + size_type d[5]; + std::fill_n(d, 5, 0); + + // The source vertex + Vertex s = *(vertices(G).first); + p[s] = s; + distance_and_pred_visitor< size_type*, Vertex*, ColorMap > vis( + d, &p[0], get(vertex_color, G)); + neighbor_breadth_first_search( + G, s, visitor(vis).color_map(get(vertex_color, G))); + + print_graph(G); + + if (num_vertices(G) < 11) + { + std::cout << "distances: "; #ifdef BOOST_OLD_STREAM_ITERATORS - std::copy(d, d + 5, std::ostream_iterator(std::cout, " ")); + std::copy(d, d + 5, std::ostream_iterator< int, char >(std::cout, " ")); #else - std::copy(d, d + 5, std::ostream_iterator(std::cout, " ")); + std::copy(d, d + 5, std::ostream_iterator< int >(std::cout, " ")); #endif - std::cout << std::endl; + std::cout << std::endl; - std::for_each(vertices(G).first, vertices(G).second, - print_parent(&p[0])); - } + std::for_each(vertices(G).first, vertices(G).second, + print_parent< Piter >(&p[0])); + } - return 0; + return 0; } diff --git a/example/ordered_out_edges.cpp b/example/ordered_out_edges.cpp index 23e3e49bb..5235eb28c 100644 --- a/example/ordered_out_edges.cpp +++ b/example/ordered_out_edges.cpp @@ -7,13 +7,12 @@ // http://www.boost.org/LICENSE_1_0.txt) //======================================================================= - - /* IMPORTANT: ~~~~~~~~~~ - This example appears to be broken and crashes at runtime, see https://github.com/boostorg/graph/issues/149 + This example appears to be broken and crashes at runtime, see + https://github.com/boostorg/graph/issues/149 */ @@ -28,11 +27,11 @@ /* Sample output: - 0 --chandler--> 1 --joe--> 1 - 1 --chandler--> 0 --joe--> 0 --curly--> 2 --dick--> 3 --dick--> 3 - 2 --curly--> 1 --tom--> 4 - 3 --dick--> 1 --dick--> 1 --harry--> 4 - 4 --tom--> 2 --harry--> 3 + 0 --chandler--> 1 --joe--> 1 + 1 --chandler--> 0 --joe--> 0 --curly--> 2 --dick--> 3 --dick--> 3 + 2 --curly--> 1 --tom--> 4 + 3 --dick--> 1 --dick--> 1 --harry--> 4 + 4 --tom--> 2 --harry--> 3 name(0,1) = chandler @@ -41,96 +40,108 @@ */ -template -struct order_by_name +template < class StoredEdge > struct order_by_name { - typedef StoredEdge first_argument_type; - typedef StoredEdge second_argument_type; - typedef bool result_type; - bool operator()(const StoredEdge& e1, const StoredEdge& e2) const { - // Order by target vertex, then by name. - // std::pair's operator< does a nice job of implementing - // lexicographical compare on tuples. - return std::make_pair(e1.get_target(), boost::get(boost::edge_name, e1)) - < std::make_pair(e2.get_target(), boost::get(boost::edge_name, e2)); - } + typedef StoredEdge first_argument_type; + typedef StoredEdge second_argument_type; + typedef bool result_type; + bool operator()(const StoredEdge& e1, const StoredEdge& e2) const + { + // Order by target vertex, then by name. + // std::pair's operator< does a nice job of implementing + // lexicographical compare on tuples. + return std::make_pair(e1.get_target(), boost::get(boost::edge_name, e1)) + < std::make_pair(e2.get_target(), boost::get(boost::edge_name, e2)); + } }; #if !defined BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION -struct ordered_set_by_nameS { }; -namespace boost { - template - struct container_gen { - typedef std::multiset > type; - }; +struct ordered_set_by_nameS +{ +}; +namespace boost +{ +template < class ValueType > +struct container_gen< ordered_set_by_nameS, ValueType > +{ + typedef std::multiset< ValueType, order_by_name< ValueType > > type; +}; } #else -struct ordered_set_by_nameS { - template - struct bind_ { typedef std::multiset > type; }; +struct ordered_set_by_nameS +{ + template < class T > struct bind_ + { + typedef std::multiset< T, order_by_name< T > > type; + }; }; -namespace boost { - template <> struct container_selector { +namespace boost +{ +template <> struct container_selector< ordered_set_by_nameS > +{ typedef ordered_set_by_nameS type; - }; +}; } #endif -namespace boost { - template <> - struct parallel_edge_traits { +namespace boost +{ +template <> struct parallel_edge_traits< ordered_set_by_nameS > +{ typedef allow_parallel_edge_tag type; - }; +}; } -int -main() +int main() { #ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION - std::cout << "This program requires partial specialization" << std::endl; + std::cout << "This program requires partial specialization" << std::endl; #else - using namespace boost; - typedef property EdgeProperty; - typedef adjacency_list graph_type; - graph_type g; - - add_edge(0, 1, EdgeProperty("joe"), g); - add_edge(1, 2, EdgeProperty("curly"), g); - add_edge(1, 3, EdgeProperty("dick"), g); - add_edge(1, 3, EdgeProperty("dick"), g); - add_edge(2, 4, EdgeProperty("tom"), g); - add_edge(3, 4, EdgeProperty("harry"), g); - add_edge(0, 1, EdgeProperty("chandler"), g); - - property_map::type id = get(vertex_index, g); - property_map::type name = get(edge_name, g); - - graph_traits::vertex_iterator i, end; - graph_traits::out_edge_iterator ei, edge_end; - for (boost::tie(i, end) = vertices(g); i != end; ++i) { - std::cout << id[*i] << " "; - for (boost::tie(ei, edge_end) = out_edges(*i, g); ei != edge_end; ++ei) - std::cout << " --" << name[*ei] << "--> " << id[target(*ei, g)] << " "; + using namespace boost; + typedef property< edge_name_t, std::string > EdgeProperty; + typedef adjacency_list< ordered_set_by_nameS, vecS, undirectedS, + no_property, EdgeProperty > + graph_type; + graph_type g; + + add_edge(0, 1, EdgeProperty("joe"), g); + add_edge(1, 2, EdgeProperty("curly"), g); + add_edge(1, 3, EdgeProperty("dick"), g); + add_edge(1, 3, EdgeProperty("dick"), g); + add_edge(2, 4, EdgeProperty("tom"), g); + add_edge(3, 4, EdgeProperty("harry"), g); + add_edge(0, 1, EdgeProperty("chandler"), g); + + property_map< graph_type, vertex_index_t >::type id = get(vertex_index, g); + property_map< graph_type, edge_name_t >::type name = get(edge_name, g); + + graph_traits< graph_type >::vertex_iterator i, end; + graph_traits< graph_type >::out_edge_iterator ei, edge_end; + for (boost::tie(i, end) = vertices(g); i != end; ++i) + { + std::cout << id[*i] << " "; + for (boost::tie(ei, edge_end) = out_edges(*i, g); ei != edge_end; ++ei) + std::cout << " --" << name[*ei] << "--> " << id[target(*ei, g)] + << " "; + std::cout << std::endl; + } std::cout << std::endl; - } - std::cout << std::endl; - - bool found; - typedef graph_traits Traits; - Traits::edge_descriptor e; - Traits::out_edge_iterator e_first, e_last; - - boost::tie(e, found) = edge(0, 1, g); - if (found) - std::cout << "name(0,1) = " << name[e] << std::endl; - else - std::cout << "not found" << std::endl; - std::cout << std::endl; - - boost::tie(e_first, e_last) = edge_range(0, 1, g); - while (e_first != e_last) - std::cout << "name(0,1) = " << name[*e_first++] << std::endl; + + bool found; + typedef graph_traits< graph_type > Traits; + Traits::edge_descriptor e; + Traits::out_edge_iterator e_first, e_last; + + boost::tie(e, found) = edge(0, 1, g); + if (found) + std::cout << "name(0,1) = " << name[e] << std::endl; + else + std::cout << "not found" << std::endl; + std::cout << std::endl; + + boost::tie(e_first, e_last) = edge_range(0, 1, g); + while (e_first != e_last) + std::cout << "name(0,1) = " << name[*e_first++] << std::endl; #endif - return 0; + return 0; } diff --git a/example/ordered_out_edges.expected b/example/ordered_out_edges.expected index 63548a1a0..dc5e76f34 100644 --- a/example/ordered_out_edges.expected +++ b/example/ordered_out_edges.expected @@ -1,8 +1,8 @@ -0 --chandler--> 1 --joe--> 1 -1 --chandler--> 0 --joe--> 0 --curly--> 2 --dick--> 3 --dick--> 3 -2 --curly--> 1 --tom--> 4 -3 --dick--> 1 --dick--> 1 --harry--> 4 -4 --tom--> 2 --harry--> 3 +0 --chandler--> 1 --joe--> 1 +1 --chandler--> 0 --joe--> 0 --curly--> 2 --dick--> 3 --dick--> 3 +2 --curly--> 1 --tom--> 4 +3 --dick--> 1 --dick--> 1 --harry--> 4 +4 --tom--> 2 --harry--> 3 name(0,1) = chandler diff --git a/example/ospf-example.cpp b/example/ospf-example.cpp index 77354330b..54d30a1d5 100644 --- a/example/ospf-example.cpp +++ b/example/ospf-example.cpp @@ -1,111 +1,118 @@ //======================================================================= -// Copyright 2001 Jeremy G. Siek, Andrew Lumsdaine, Lie-Quan Lee, +// Copyright 2001 Jeremy G. Siek, Andrew Lumsdaine, Lie-Quan Lee, // // Distributed under the Boost Software License, Version 1.0. (See // accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) //======================================================================= -#include // for file I/O -#include // for read/write_graphviz() +#include // for file I/O +#include // for read/write_graphviz() #include #include -namespace boost { - enum graph_color_t { graph_color = 5556 }; - BOOST_INSTALL_PROPERTY(graph, color); +namespace boost +{ +enum graph_color_t +{ + graph_color = 5556 +}; +BOOST_INSTALL_PROPERTY(graph, color); } -int -main(int argc, const char** argv) +int main(int argc, const char** argv) { - using namespace boost; - typedef - adjacency_list, - property >, - property > - g_dot_type; - g_dot_type g_dot; - - dynamic_properties dp(ignore_other_properties); - dp.property("node_id", get(vertex_name, g_dot)); - dp.property("label", get(edge_weight, g_dot)); - dp.property("color", get(edge_color, g_dot)); - dp.property("color", ref_property_map(get_property(g_dot, graph_color))); - { - std::ifstream infile(argc >= 2 ? argv[1] : "figs/ospf-graph.dot"); - read_graphviz(infile, g_dot, dp); - } + using namespace boost; + typedef adjacency_list< vecS, vecS, directedS, + property< vertex_name_t, std::string >, + property< edge_color_t, std::string, property< edge_weight_t, int > >, + property< graph_color_t, std::string > > + g_dot_type; + g_dot_type g_dot; - typedef adjacency_list < vecS, vecS, directedS, no_property, - property < edge_weight_t, int > > Graph; - typedef graph_traits < Graph >::vertex_descriptor vertex_descriptor; - Graph g(num_vertices(g_dot)); - graph_traits < g_dot_type >::edge_iterator ei, ei_end; - for (boost::tie(ei, ei_end) = edges(g_dot); ei != ei_end; ++ei) { - int weight = get(edge_weight, g_dot, *ei); - property < edge_weight_t, int >edge_property(weight); - add_edge(source(*ei, g_dot), target(*ei, g_dot), edge_property, g); - } + dynamic_properties dp(ignore_other_properties); + dp.property("node_id", get(vertex_name, g_dot)); + dp.property("label", get(edge_weight, g_dot)); + dp.property("color", get(edge_color, g_dot)); + dp.property("color", + ref_property_map< g_dot_type*, std::string >( + get_property(g_dot, graph_color))); + { + std::ifstream infile(argc >= 2 ? argv[1] : "figs/ospf-graph.dot"); + read_graphviz(infile, g_dot, dp); + } - vertex_descriptor router_six; - graph_traits < g_dot_type >::vertex_iterator vi, vi_end; - for (boost::tie(vi, vi_end) = vertices(g_dot); vi != vi_end; ++vi) - if ("RT6" == get(vertex_name, g_dot, *vi)) { - router_six = *vi; - break; + typedef adjacency_list< vecS, vecS, directedS, no_property, + property< edge_weight_t, int > > + Graph; + typedef graph_traits< Graph >::vertex_descriptor vertex_descriptor; + Graph g(num_vertices(g_dot)); + graph_traits< g_dot_type >::edge_iterator ei, ei_end; + for (boost::tie(ei, ei_end) = edges(g_dot); ei != ei_end; ++ei) + { + int weight = get(edge_weight, g_dot, *ei); + property< edge_weight_t, int > edge_property(weight); + add_edge(source(*ei, g_dot), target(*ei, g_dot), edge_property, g); } - std::vector < vertex_descriptor > parent(num_vertices(g)); - // All vertices start out as there own parent - typedef graph_traits < Graph >::vertices_size_type size_type; - for (size_type p = 0; p < num_vertices(g); ++p) - parent[p] = p; + vertex_descriptor router_six; + graph_traits< g_dot_type >::vertex_iterator vi, vi_end; + for (boost::tie(vi, vi_end) = vertices(g_dot); vi != vi_end; ++vi) + if ("RT6" == get(vertex_name, g_dot, *vi)) + { + router_six = *vi; + break; + } + + std::vector< vertex_descriptor > parent(num_vertices(g)); + // All vertices start out as there own parent + typedef graph_traits< Graph >::vertices_size_type size_type; + for (size_type p = 0; p < num_vertices(g); ++p) + parent[p] = p; #if defined(BOOST_MSVC) && BOOST_MSVC <= 1300 - std::vector distance(num_vertices(g)); - property_map::type weightmap = get(edge_weight, g); - property_map::type indexmap = get(vertex_index, g); - dijkstra_shortest_paths - (g, router_six, &parent[0], &distance[0], weightmap, - indexmap, std::less(), closed_plus(), - (std::numeric_limits::max)(), 0, default_dijkstra_visitor()); + std::vector< int > distance(num_vertices(g)); + property_map< Graph, edge_weight_t >::type weightmap = get(edge_weight, g); + property_map< Graph, vertex_index_t >::type indexmap = get(vertex_index, g); + dijkstra_shortest_paths(g, router_six, &parent[0], &distance[0], weightmap, + indexmap, std::less< int >(), closed_plus< int >(), + (std::numeric_limits< int >::max)(), 0, default_dijkstra_visitor()); #else - dijkstra_shortest_paths(g, router_six, predecessor_map(&parent[0])); + dijkstra_shortest_paths(g, router_six, predecessor_map(&parent[0])); #endif - graph_traits < g_dot_type >::edge_descriptor e; - for (size_type i = 0; i < num_vertices(g); ++i) - if (parent[i] != i) { - e = edge(parent[i], i, g_dot).first; - put(edge_color, g_dot, e, "black"); - } - - get_property(g_dot, graph_color) = "grey"; - { - std::ofstream outfile(argc >= 3 ? argv[2] : "figs/ospf-sptree.dot"); - write_graphviz_dp(outfile, g_dot, dp); - } - - std::ofstream rtable(argc >= 4 ? argv[3] : "routing-table.dat"); - rtable << "Dest Next Hop Total Cost" << std::endl; - for (boost::tie(vi, vi_end) = vertices(g_dot); vi != vi_end; ++vi) - if (parent[*vi] != *vi) { - rtable << get(vertex_name, g_dot, *vi) << " "; - vertex_descriptor v = *vi, child; - int path_cost = 0; - property_map < Graph, edge_weight_t >::type - weight_map = get(edge_weight, g); - do { - path_cost += get(weight_map, edge(parent[v], v, g).first); - child = v; - v = parent[v]; - } while (v != parent[v]); - rtable << get(vertex_name, g_dot, child) << " "; - rtable << path_cost << std::endl; + graph_traits< g_dot_type >::edge_descriptor e; + for (size_type i = 0; i < num_vertices(g); ++i) + if (parent[i] != i) + { + e = edge(parent[i], i, g_dot).first; + put(edge_color, g_dot, e, "black"); + } + get_property(g_dot, graph_color) = "grey"; + { + std::ofstream outfile(argc >= 3 ? argv[2] : "figs/ospf-sptree.dot"); + write_graphviz_dp(outfile, g_dot, dp); } - return EXIT_SUCCESS; + std::ofstream rtable(argc >= 4 ? argv[3] : "routing-table.dat"); + rtable << "Dest Next Hop Total Cost" << std::endl; + for (boost::tie(vi, vi_end) = vertices(g_dot); vi != vi_end; ++vi) + if (parent[*vi] != *vi) + { + rtable << get(vertex_name, g_dot, *vi) << " "; + vertex_descriptor v = *vi, child; + int path_cost = 0; + property_map< Graph, edge_weight_t >::type weight_map + = get(edge_weight, g); + do + { + path_cost += get(weight_map, edge(parent[v], v, g).first); + child = v; + v = parent[v]; + } while (v != parent[v]); + rtable << get(vertex_name, g_dot, child) << " "; + rtable << path_cost << std::endl; + } + + return EXIT_SUCCESS; } diff --git a/example/parallel-compile-time.cpp b/example/parallel-compile-time.cpp index 0b1475d55..22c6e4795 100644 --- a/example/parallel-compile-time.cpp +++ b/example/parallel-compile-time.cpp @@ -1,5 +1,5 @@ //======================================================================= -// Copyright 2001 Jeremy G. Siek, Andrew Lumsdaine, Lie-Quan Lee, +// Copyright 2001 Jeremy G. Siek, Andrew Lumsdaine, Lie-Quan Lee, // // Distributed under the Boost Software License, Version 1.0. (See // accompanying file LICENSE_1_0.txt or copy at @@ -13,192 +13,187 @@ #include #include #include -#include // for default_dfs_visitor +#include // for default_dfs_visitor namespace std { - template < typename T > - std::istream & operator >> (std::istream & in, std::pair < T, T > &p) - { +template < typename T > +std::istream& operator>>(std::istream& in, std::pair< T, T >& p) +{ in >> p.first >> p.second; return in; - } +} } namespace boost { - enum vertex_compile_cost_t { vertex_compile_cost }; - BOOST_INSTALL_PROPERTY(vertex, compile_cost); +enum vertex_compile_cost_t +{ + vertex_compile_cost +}; +BOOST_INSTALL_PROPERTY(vertex, compile_cost); } using namespace boost; -typedef adjacency_list < listS, // Store out-edges of each vertex in a std::list - listS, // Store vertex set in a std::list - directedS, // The file dependency graph is directed - // vertex properties - property < vertex_name_t, std::string, - property < vertex_compile_cost_t, float, - property < vertex_distance_t, float, - property < vertex_color_t, default_color_type > > > >, - // an edge property - property < edge_weight_t, float > > - file_dep_graph2; - -typedef graph_traits::vertex_descriptor vertex_t; -typedef graph_traits::edge_descriptor edge_t; - - -template < typename Graph, typename ColorMap, typename Visitor > void -dfs_v2(const Graph & g, - typename graph_traits < Graph >::vertex_descriptor u, - ColorMap color, Visitor vis) +typedef adjacency_list< listS, // Store out-edges of each vertex in a std::list + listS, // Store vertex set in a std::list + directedS, // The file dependency graph is directed + // vertex properties + property< vertex_name_t, std::string, + property< vertex_compile_cost_t, float, + property< vertex_distance_t, float, + property< vertex_color_t, default_color_type > > > >, + // an edge property + property< edge_weight_t, float > > + file_dep_graph2; + +typedef graph_traits< file_dep_graph2 >::vertex_descriptor vertex_t; +typedef graph_traits< file_dep_graph2 >::edge_descriptor edge_t; + +template < typename Graph, typename ColorMap, typename Visitor > +void dfs_v2(const Graph& g, typename graph_traits< Graph >::vertex_descriptor u, + ColorMap color, Visitor vis) { - typedef typename property_traits < ColorMap >::value_type color_type; - typedef color_traits < color_type > ColorT; - color[u] = ColorT::gray(); - vis.discover_vertex(u, g); - typename graph_traits < Graph >::out_edge_iterator ei, ei_end; - for (boost::tie(ei, ei_end) = out_edges(u, g); ei != ei_end; ++ei) - if (color[target(*ei, g)] == ColorT::white()) { - vis.tree_edge(*ei, g); - dfs_v2(g, target(*ei, g), color, vis); - } else if (color[target(*ei, g)] == ColorT::gray()) - vis.back_edge(*ei, g); - else - vis.forward_or_cross_edge(*ei, g); - color[u] = ColorT::black(); - vis.finish_vertex(u, g); + typedef typename property_traits< ColorMap >::value_type color_type; + typedef color_traits< color_type > ColorT; + color[u] = ColorT::gray(); + vis.discover_vertex(u, g); + typename graph_traits< Graph >::out_edge_iterator ei, ei_end; + for (boost::tie(ei, ei_end) = out_edges(u, g); ei != ei_end; ++ei) + if (color[target(*ei, g)] == ColorT::white()) + { + vis.tree_edge(*ei, g); + dfs_v2(g, target(*ei, g), color, vis); + } + else if (color[target(*ei, g)] == ColorT::gray()) + vis.back_edge(*ei, g); + else + vis.forward_or_cross_edge(*ei, g); + color[u] = ColorT::black(); + vis.finish_vertex(u, g); } -template < typename Graph, typename Visitor, typename ColorMap > void -generic_dfs_v2(const Graph & g, Visitor vis, ColorMap color) +template < typename Graph, typename Visitor, typename ColorMap > +void generic_dfs_v2(const Graph& g, Visitor vis, ColorMap color) { - typedef typename property_traits ::value_type ColorValue; - typedef color_traits < ColorValue > ColorT; - typename graph_traits < Graph >::vertex_iterator vi, vi_end; - for (boost::tie(vi, vi_end) = vertices(g); vi != vi_end; ++vi) - color[*vi] = ColorT::white(); - for (boost::tie(vi, vi_end) = vertices(g); vi != vi_end; ++vi) - if (color[*vi] == ColorT::white()) - dfs_v2(g, *vi, color, vis); + typedef typename property_traits< ColorMap >::value_type ColorValue; + typedef color_traits< ColorValue > ColorT; + typename graph_traits< Graph >::vertex_iterator vi, vi_end; + for (boost::tie(vi, vi_end) = vertices(g); vi != vi_end; ++vi) + color[*vi] = ColorT::white(); + for (boost::tie(vi, vi_end) = vertices(g); vi != vi_end; ++vi) + if (color[*vi] == ColorT::white()) + dfs_v2(g, *vi, color, vis); } - -template < typename OutputIterator > -struct topo_visitor: public default_dfs_visitor +template < typename OutputIterator > +struct topo_visitor : public default_dfs_visitor { - topo_visitor(OutputIterator & order): - topo_order(order) - { - } - template < typename Graph > void - finish_vertex(typename graph_traits < Graph >::vertex_descriptor u, - const Graph &) - { - *topo_order++ = u; - } - OutputIterator & topo_order; + topo_visitor(OutputIterator& order) : topo_order(order) {} + template < typename Graph > + void finish_vertex( + typename graph_traits< Graph >::vertex_descriptor u, const Graph&) + { + *topo_order++ = u; + } + OutputIterator& topo_order; }; -template < typename Graph, typename OutputIterator, typename ColorMap > void -topo_sort(const Graph & g, OutputIterator topo_order, ColorMap color) +template < typename Graph, typename OutputIterator, typename ColorMap > +void topo_sort(const Graph& g, OutputIterator topo_order, ColorMap color) { - topo_visitor < OutputIterator > vis(topo_order); - generic_dfs_v2(g, vis, color); + topo_visitor< OutputIterator > vis(topo_order); + generic_dfs_v2(g, vis, color); } +typedef property_map< file_dep_graph2, vertex_name_t >::type name_map_t; +typedef property_map< file_dep_graph2, vertex_compile_cost_t >::type + compile_cost_map_t; +typedef property_map< file_dep_graph2, vertex_distance_t >::type distance_map_t; +typedef property_map< file_dep_graph2, vertex_color_t >::type color_map_t; -typedef property_map < file_dep_graph2, vertex_name_t >::type name_map_t; -typedef property_map < file_dep_graph2, vertex_compile_cost_t >::type - compile_cost_map_t; -typedef property_map < file_dep_graph2, vertex_distance_t >::type distance_map_t; -typedef property_map < file_dep_graph2, vertex_color_t >::type color_map_t; - - -int -main(int argc, const char** argv) +int main(int argc, const char** argv) { - std::ifstream file_in(argc >= 2 ? argv[1] : "makefile-dependencies.dat"); - typedef graph_traits < file_dep_graph2 >::vertices_size_type size_type; - size_type n_vertices; - file_in >> n_vertices; // read in number of vertices - std::istream_iterator < std::pair < size_type, - size_type > >input_begin(file_in), input_end; + std::ifstream file_in(argc >= 2 ? argv[1] : "makefile-dependencies.dat"); + typedef graph_traits< file_dep_graph2 >::vertices_size_type size_type; + size_type n_vertices; + file_in >> n_vertices; // read in number of vertices + std::istream_iterator< std::pair< size_type, size_type > > input_begin( + file_in), + input_end; #if defined(BOOST_MSVC) && BOOST_MSVC <= 1300 - // VC++ can't handle the iterator constructor - file_dep_graph2 g; - typedef graph_traits::vertex_descriptor vertex_t; - std::vector id2vertex; - for (std::size_t v = 0; v < n_vertices; ++v) - id2vertex.push_back(add_vertex(g)); - while (input_begin != input_end) { - size_type i, j; - boost::tie(i, j) = *input_begin++; - add_edge(id2vertex[i], id2vertex[j], g); - } + // VC++ can't handle the iterator constructor + file_dep_graph2 g; + typedef graph_traits< file_dep_graph2 >::vertex_descriptor vertex_t; + std::vector< vertex_t > id2vertex; + for (std::size_t v = 0; v < n_vertices; ++v) + id2vertex.push_back(add_vertex(g)); + while (input_begin != input_end) + { + size_type i, j; + boost::tie(i, j) = *input_begin++; + add_edge(id2vertex[i], id2vertex[j], g); + } #else - file_dep_graph2 g(input_begin, input_end, n_vertices); + file_dep_graph2 g(input_begin, input_end, n_vertices); #endif - name_map_t - name_map = - get(vertex_name, g); - compile_cost_map_t - compile_cost_map = - get(vertex_compile_cost, g); - distance_map_t - distance_map = - get(vertex_distance, g); - color_map_t - color_map = - get(vertex_color, g); - - { - std::ifstream name_in(argc >= 3 ? argv[2] : "makefile-target-names.dat"); - std::ifstream compile_cost_in(argc >= 4 ? argv[3] : "target-compile-costs.dat"); - graph_traits < file_dep_graph2 >::vertex_iterator vi, vi_end; - for (boost::tie(vi, vi_end) = vertices(g); vi != vi_end; ++vi) { - name_in >> name_map[*vi]; - compile_cost_in >> compile_cost_map[*vi]; + name_map_t name_map = get(vertex_name, g); + compile_cost_map_t compile_cost_map = get(vertex_compile_cost, g); + distance_map_t distance_map = get(vertex_distance, g); + color_map_t color_map = get(vertex_color, g); + + { + std::ifstream name_in( + argc >= 3 ? argv[2] : "makefile-target-names.dat"); + std::ifstream compile_cost_in( + argc >= 4 ? argv[3] : "target-compile-costs.dat"); + graph_traits< file_dep_graph2 >::vertex_iterator vi, vi_end; + for (boost::tie(vi, vi_end) = vertices(g); vi != vi_end; ++vi) + { + name_in >> name_map[*vi]; + compile_cost_in >> compile_cost_map[*vi]; + } } + std::vector< vertex_t > topo_order(num_vertices(g)); + topo_sort(g, topo_order.rbegin(), color_map); + + graph_traits< file_dep_graph2 >::vertex_iterator i, i_end; + graph_traits< file_dep_graph2 >::adjacency_iterator vi, vi_end; + + // find source vertices with zero in-degree by marking all vertices with + // incoming edges + for (boost::tie(i, i_end) = vertices(g); i != i_end; ++i) + color_map[*i] = white_color; + for (boost::tie(i, i_end) = vertices(g); i != i_end; ++i) + for (boost::tie(vi, vi_end) = adjacent_vertices(*i, g); vi != vi_end; + ++vi) + color_map[*vi] = black_color; + + // initialize distances to zero, or for source vertices, to the compile cost + for (boost::tie(i, i_end) = vertices(g); i != i_end; ++i) + if (color_map[*i] == white_color) + distance_map[*i] = compile_cost_map[*i]; + else + distance_map[*i] = 0; + + std::vector< vertex_t >::iterator ui; + for (ui = topo_order.begin(); ui != topo_order.end(); ++ui) + { + vertex_t u = *ui; + for (boost::tie(vi, vi_end) = adjacent_vertices(u, g); vi != vi_end; + ++vi) + if (distance_map[*vi] < distance_map[u] + compile_cost_map[*vi]) + distance_map[*vi] = distance_map[u] + compile_cost_map[*vi]; + } + + graph_property_iter_range< file_dep_graph2, vertex_distance_t >::iterator + ci, + ci_end; + boost::tie(ci, ci_end) = get_property_iter_range(g, vertex_distance); + std::cout << "total (parallel) compile time: " + << *std::max_element(ci, ci_end) << std::endl; - } - std::vector < vertex_t > topo_order(num_vertices(g)); - topo_sort(g, topo_order.rbegin(), color_map); - - graph_traits < file_dep_graph2 >::vertex_iterator i, i_end; - graph_traits < file_dep_graph2 >::adjacency_iterator vi, vi_end; - - // find source vertices with zero in-degree by marking all vertices with incoming edges - for (boost::tie(i, i_end) = vertices(g); i != i_end; ++i) - color_map[*i] = white_color; - for (boost::tie(i, i_end) = vertices(g); i != i_end; ++i) - for (boost::tie(vi, vi_end) = adjacent_vertices(*i, g); vi != vi_end; ++vi) - color_map[*vi] = black_color; - - // initialize distances to zero, or for source vertices, to the compile cost - for (boost::tie(i, i_end) = vertices(g); i != i_end; ++i) - if (color_map[*i] == white_color) - distance_map[*i] = compile_cost_map[*i]; - else - distance_map[*i] = 0; - - std::vector < vertex_t >::iterator ui; - for (ui = topo_order.begin(); ui != topo_order.end(); ++ui) { - vertex_t - u = * - ui; - for (boost::tie(vi, vi_end) = adjacent_vertices(u, g); vi != vi_end; ++vi) - if (distance_map[*vi] < distance_map[u] + compile_cost_map[*vi]) - distance_map[*vi] = distance_map[u] + compile_cost_map[*vi]; - } - - graph_property_iter_range < file_dep_graph2, - vertex_distance_t >::iterator ci, ci_end; - boost::tie(ci, ci_end) = get_property_iter_range(g, vertex_distance); - std::cout << "total (parallel) compile time: " - << *std::max_element(ci, ci_end) << std::endl; - - return 0; + return 0; } diff --git a/example/planar_face_traversal.cpp b/example/planar_face_traversal.cpp index fe96d2de4..f67e34c0d 100644 --- a/example/planar_face_traversal.cpp +++ b/example/planar_face_traversal.cpp @@ -16,109 +16,84 @@ #include #include - using namespace boost; - - -// Some planar face traversal visitors that will +// Some planar face traversal visitors that will // print the vertices and edges on the faces struct output_visitor : public planar_face_traversal_visitor { - void begin_face() { std::cout << "New face: "; } - void end_face() { std::cout << std::endl; } + void begin_face() { std::cout << "New face: "; } + void end_face() { std::cout << std::endl; } }; - - struct vertex_output_visitor : public output_visitor { - template - void next_vertex(Vertex v) - { - std::cout << v << " "; - } + template < typename Vertex > void next_vertex(Vertex v) + { + std::cout << v << " "; + } }; - - struct edge_output_visitor : public output_visitor { - template - void next_edge(Edge e) - { - std::cout << e << " "; - } + template < typename Edge > void next_edge(Edge e) { std::cout << e << " "; } }; - int main(int argc, char** argv) { - typedef adjacency_list - < vecS, - vecS, - undirectedS, - property, - property - > - graph; - - // Create a graph - this is a biconnected, 3 x 3 grid. - // It should have four small (four vertex/four edge) faces and - // one large face that contains all but the interior vertex - graph g(9); - - add_edge(0,1,g); - add_edge(1,2,g); - - add_edge(3,4,g); - add_edge(4,5,g); - - add_edge(6,7,g); - add_edge(7,8,g); - - - add_edge(0,3,g); - add_edge(3,6,g); - - add_edge(1,4,g); - add_edge(4,7,g); - - add_edge(2,5,g); - add_edge(5,8,g); - - - // Initialize the interior edge index - property_map::type e_index = get(edge_index, g); - graph_traits::edges_size_type edge_count = 0; - graph_traits::edge_iterator ei, ei_end; - for(boost::tie(ei, ei_end) = edges(g); ei != ei_end; ++ei) - put(e_index, *ei, edge_count++); - - - // Test for planarity - we know it is planar, we just want to - // compute the planar embedding as a side-effect - typedef std::vector< graph_traits::edge_descriptor > vec_t; - std::vector embedding(num_vertices(g)); - if (boyer_myrvold_planarity_test(boyer_myrvold_params::graph = g, - boyer_myrvold_params::embedding = - &embedding[0] - ) - ) - std::cout << "Input graph is planar" << std::endl; - else - std::cout << "Input graph is not planar" << std::endl; - - - std::cout << std::endl << "Vertices on the faces: " << std::endl; - vertex_output_visitor v_vis; - planar_face_traversal(g, &embedding[0], v_vis); - - std::cout << std::endl << "Edges on the faces: " << std::endl; - edge_output_visitor e_vis; - planar_face_traversal(g, &embedding[0], e_vis); - - return 0; + typedef adjacency_list< vecS, vecS, undirectedS, + property< vertex_index_t, int >, property< edge_index_t, int > > + graph; + + // Create a graph - this is a biconnected, 3 x 3 grid. + // It should have four small (four vertex/four edge) faces and + // one large face that contains all but the interior vertex + graph g(9); + + add_edge(0, 1, g); + add_edge(1, 2, g); + + add_edge(3, 4, g); + add_edge(4, 5, g); + + add_edge(6, 7, g); + add_edge(7, 8, g); + + add_edge(0, 3, g); + add_edge(3, 6, g); + + add_edge(1, 4, g); + add_edge(4, 7, g); + + add_edge(2, 5, g); + add_edge(5, 8, g); + + // Initialize the interior edge index + property_map< graph, edge_index_t >::type e_index = get(edge_index, g); + graph_traits< graph >::edges_size_type edge_count = 0; + graph_traits< graph >::edge_iterator ei, ei_end; + for (boost::tie(ei, ei_end) = edges(g); ei != ei_end; ++ei) + put(e_index, *ei, edge_count++); + + // Test for planarity - we know it is planar, we just want to + // compute the planar embedding as a side-effect + typedef std::vector< graph_traits< graph >::edge_descriptor > vec_t; + std::vector< vec_t > embedding(num_vertices(g)); + if (boyer_myrvold_planarity_test(boyer_myrvold_params::graph = g, + boyer_myrvold_params::embedding = &embedding[0])) + std::cout << "Input graph is planar" << std::endl; + else + std::cout << "Input graph is not planar" << std::endl; + + std::cout << std::endl << "Vertices on the faces: " << std::endl; + vertex_output_visitor v_vis; + planar_face_traversal(g, &embedding[0], v_vis); + + std::cout << std::endl << "Edges on the faces: " << std::endl; + edge_output_visitor e_vis; + planar_face_traversal(g, &embedding[0], e_vis); + + return 0; } diff --git a/example/prim-example.cpp b/example/prim-example.cpp index b36740bf8..d9a78758a 100644 --- a/example/prim-example.cpp +++ b/example/prim-example.cpp @@ -1,5 +1,5 @@ //======================================================================= -// Copyright 2001 Jeremy G. Siek, Andrew Lumsdaine, Lie-Quan Lee, +// Copyright 2001 Jeremy G. Siek, Andrew Lumsdaine, Lie-Quan Lee, // // Distributed under the Boost Software License, Version 1.0. (See // accompanying file LICENSE_1_0.txt or copy at @@ -10,47 +10,47 @@ #include #include -int -main() +int main() { - using namespace boost; - typedef adjacency_list < vecS, vecS, undirectedS, - property, property < edge_weight_t, int > > Graph; - typedef std::pair < int, int >E; - const int num_nodes = 5; - E edges[] = { E(0, 2), E(1, 3), E(1, 4), E(2, 1), E(2, 3), - E(3, 4), E(4, 0) - }; - int weights[] = { 1, 1, 2, 7, 3, 1, 1 }; + using namespace boost; + typedef adjacency_list< vecS, vecS, undirectedS, + property< vertex_distance_t, int >, property< edge_weight_t, int > > + Graph; + typedef std::pair< int, int > E; + const int num_nodes = 5; + E edges[] + = { E(0, 2), E(1, 3), E(1, 4), E(2, 1), E(2, 3), E(3, 4), E(4, 0) }; + int weights[] = { 1, 1, 2, 7, 3, 1, 1 }; #if defined(BOOST_MSVC) && BOOST_MSVC <= 1300 - Graph g(num_nodes); - property_map::type weightmap = get(edge_weight, g); - for (std::size_t j = 0; j < sizeof(edges) / sizeof(E); ++j) { - graph_traits::edge_descriptor e; bool inserted; - boost::tie(e, inserted) = add_edge(edges[j].first, edges[j].second, g); - weightmap[e] = weights[j]; - } + Graph g(num_nodes); + property_map< Graph, edge_weight_t >::type weightmap = get(edge_weight, g); + for (std::size_t j = 0; j < sizeof(edges) / sizeof(E); ++j) + { + graph_traits< Graph >::edge_descriptor e; + bool inserted; + boost::tie(e, inserted) = add_edge(edges[j].first, edges[j].second, g); + weightmap[e] = weights[j]; + } #else - Graph g(edges, edges + sizeof(edges) / sizeof(E), weights, num_nodes); + Graph g(edges, edges + sizeof(edges) / sizeof(E), weights, num_nodes); #endif - std::vector < graph_traits < Graph >::vertex_descriptor > - p(num_vertices(g)); + std::vector< graph_traits< Graph >::vertex_descriptor > p(num_vertices(g)); #if defined(BOOST_MSVC) && BOOST_MSVC <= 1300 - property_map::type distance = get(vertex_distance, g); - property_map::type indexmap = get(vertex_index, g); - prim_minimum_spanning_tree - (g, *vertices(g).first, &p[0], distance, weightmap, indexmap, - default_dijkstra_visitor()); + property_map< Graph, vertex_distance_t >::type distance + = get(vertex_distance, g); + property_map< Graph, vertex_index_t >::type indexmap = get(vertex_index, g); + prim_minimum_spanning_tree(g, *vertices(g).first, &p[0], distance, + weightmap, indexmap, default_dijkstra_visitor()); #else - prim_minimum_spanning_tree(g, &p[0]); + prim_minimum_spanning_tree(g, &p[0]); #endif - for (std::size_t i = 0; i != p.size(); ++i) - if (p[i] != i) - std::cout << "parent[" << i << "] = " << p[i] << std::endl; - else - std::cout << "parent[" << i << "] = no parent" << std::endl; + for (std::size_t i = 0; i != p.size(); ++i) + if (p[i] != i) + std::cout << "parent[" << i << "] = " << p[i] << std::endl; + else + std::cout << "parent[" << i << "] = no parent" << std::endl; - return EXIT_SUCCESS; + return EXIT_SUCCESS; } diff --git a/example/prim-telephone.cpp b/example/prim-telephone.cpp index 9354de648..1f256db06 100644 --- a/example/prim-telephone.cpp +++ b/example/prim-telephone.cpp @@ -1,5 +1,5 @@ //======================================================================= -// Copyright 2001 Jeremy G. Siek, Andrew Lumsdaine, Lie-Quan Lee, +// Copyright 2001 Jeremy G. Siek, Andrew Lumsdaine, Lie-Quan Lee, // // Distributed under the Boost Software License, Version 1.0. (See // accompanying file LICENSE_1_0.txt or copy at @@ -9,8 +9,8 @@ /* IMPORTANT!!! ~~~~~~~~~~~~ - This example uses interfaces that have been deprecated and removed from Boost.Grpah. - Someone needs to update it, as it does NOT compile. + This example uses interfaces that have been deprecated and removed from + Boost.Grpah. Someone needs to update it, as it does NOT compile. */ #include @@ -20,51 +20,53 @@ #include #include #include -int -main() +int main() { - using namespace boost; - GraphvizGraph g_dot; - read_graphviz("figs/telephone-network.dot", g_dot); + using namespace boost; + GraphvizGraph g_dot; + read_graphviz("figs/telephone-network.dot", g_dot); - typedef adjacency_list < vecS, vecS, undirectedS, no_property, - property < edge_weight_t, int > > Graph; - Graph g(num_vertices(g_dot)); - property_map < GraphvizGraph, edge_attribute_t >::type - edge_attr_map = get(edge_attribute, g_dot); - graph_traits < GraphvizGraph >::edge_iterator ei, ei_end; - for (boost::tie(ei, ei_end) = edges(g_dot); ei != ei_end; ++ei) { - int weight = lexical_cast < int >(edge_attr_map[*ei]["label"]); - property < edge_weight_t, int >edge_property(weight); - add_edge(source(*ei, g_dot), target(*ei, g_dot), edge_property, g); - } + typedef adjacency_list< vecS, vecS, undirectedS, no_property, + property< edge_weight_t, int > > + Graph; + Graph g(num_vertices(g_dot)); + property_map< GraphvizGraph, edge_attribute_t >::type edge_attr_map + = get(edge_attribute, g_dot); + graph_traits< GraphvizGraph >::edge_iterator ei, ei_end; + for (boost::tie(ei, ei_end) = edges(g_dot); ei != ei_end; ++ei) + { + int weight = lexical_cast< int >(edge_attr_map[*ei]["label"]); + property< edge_weight_t, int > edge_property(weight); + add_edge(source(*ei, g_dot), target(*ei, g_dot), edge_property, g); + } - typedef graph_traits < Graph >::vertex_descriptor Vertex; - std::vector < Vertex > parent(num_vertices(g)); - property_map < Graph, edge_weight_t >::type weight = get(edge_weight, g); + typedef graph_traits< Graph >::vertex_descriptor Vertex; + std::vector< Vertex > parent(num_vertices(g)); + property_map< Graph, edge_weight_t >::type weight = get(edge_weight, g); #if defined(BOOST_MSVC) && BOOST_MSVC <= 1300 - property_map::type indexmap = get(vertex_index, g); - std::vector distance(num_vertices(g)); - prim_minimum_spanning_tree(g, *vertices(g).first, &parent[0], &distance[0], - weight, indexmap, default_dijkstra_visitor()); + property_map< Graph, vertex_index_t >::type indexmap = get(vertex_index, g); + std::vector< std::size_t > distance(num_vertices(g)); + prim_minimum_spanning_tree(g, *vertices(g).first, &parent[0], &distance[0], + weight, indexmap, default_dijkstra_visitor()); #else - prim_minimum_spanning_tree(g, &parent[0]); + prim_minimum_spanning_tree(g, &parent[0]); #endif - int total_weight = 0; - for (int v = 0; v < num_vertices(g); ++v) - if (parent[v] != v) - total_weight += get(weight, edge(parent[v], v, g).first); - std::cout << "total weight: " << total_weight << std::endl; + int total_weight = 0; + for (int v = 0; v < num_vertices(g); ++v) + if (parent[v] != v) + total_weight += get(weight, edge(parent[v], v, g).first); + std::cout << "total weight: " << total_weight << std::endl; - for (int u = 0; u < num_vertices(g); ++u) - if (parent[u] != u) - edge_attr_map[edge(parent[u], u, g_dot).first]["color"] = "black"; - std::ofstream out("figs/telephone-mst-prim.dot"); - graph_property < GraphvizGraph, graph_edge_attribute_t >::type & - graph_edge_attr_map = get_property(g_dot, graph_edge_attribute); - graph_edge_attr_map["color"] = "gray"; - write_graphviz(out, g_dot); + for (int u = 0; u < num_vertices(g); ++u) + if (parent[u] != u) + edge_attr_map[edge(parent[u], u, g_dot).first]["color"] = "black"; + std::ofstream out("figs/telephone-mst-prim.dot"); + graph_property< GraphvizGraph, graph_edge_attribute_t >::type& + graph_edge_attr_map + = get_property(g_dot, graph_edge_attribute); + graph_edge_attr_map["color"] = "gray"; + write_graphviz(out, g_dot); - return EXIT_SUCCESS; + return EXIT_SUCCESS; } diff --git a/example/print-adjacent-vertices.cpp b/example/print-adjacent-vertices.cpp index d4b3383ad..22b0ba656 100644 --- a/example/print-adjacent-vertices.cpp +++ b/example/print-adjacent-vertices.cpp @@ -1,5 +1,5 @@ //======================================================================= -// Copyright 2001 Jeremy G. Siek, Andrew Lumsdaine, Lie-Quan Lee, +// Copyright 2001 Jeremy G. Siek, Andrew Lumsdaine, Lie-Quan Lee, // // Distributed under the Boost Software License, Version 1.0. (See // accompanying file LICENSE_1_0.txt or copy at @@ -13,99 +13,106 @@ using namespace boost; -template < typename Graph, typename VertexNamePropertyMap > void -read_graph_file(std::istream & graph_in, std::istream & name_in, - Graph & g, VertexNamePropertyMap name_map) +template < typename Graph, typename VertexNamePropertyMap > +void read_graph_file(std::istream& graph_in, std::istream& name_in, Graph& g, + VertexNamePropertyMap name_map) { - typedef typename graph_traits < Graph >::vertices_size_type size_type; - size_type n_vertices; - typename graph_traits < Graph >::vertex_descriptor u; - typename property_traits < VertexNamePropertyMap >::value_type name; + typedef typename graph_traits< Graph >::vertices_size_type size_type; + size_type n_vertices; + typename graph_traits< Graph >::vertex_descriptor u; + typename property_traits< VertexNamePropertyMap >::value_type name; - graph_in >> n_vertices; // read in number of vertices - for (size_type i = 0; i < n_vertices; ++i) { // Add n vertices to the graph - u = add_vertex(g); - name_in >> name; - put(name_map, u, name); // ** Attach name property to vertex u ** - } - size_type src, targ; - while (graph_in >> src) // Read in edges - if (graph_in >> targ) - add_edge(src, targ, g); // add an edge to the graph - else - break; + graph_in >> n_vertices; // read in number of vertices + for (size_type i = 0; i < n_vertices; ++i) + { // Add n vertices to the graph + u = add_vertex(g); + name_in >> name; + put(name_map, u, name); // ** Attach name property to vertex u ** + } + size_type src, targ; + while (graph_in >> src) // Read in edges + if (graph_in >> targ) + add_edge(src, targ, g); // add an edge to the graph + else + break; } -template < typename Graph, typename VertexNameMap > void -output_adjacent_vertices(std::ostream & out, - typename graph_traits < Graph >::vertex_descriptor u, - const Graph & g, VertexNameMap name_map) +template < typename Graph, typename VertexNameMap > +void output_adjacent_vertices(std::ostream& out, + typename graph_traits< Graph >::vertex_descriptor u, const Graph& g, + VertexNameMap name_map) { - typename graph_traits < Graph >::adjacency_iterator vi, vi_end; - out << get(name_map, u) << " -> { "; - for (boost::tie(vi, vi_end) = adjacent_vertices(u, g); vi != vi_end; ++vi) - out << get(name_map, *vi) << " "; - out << "}" << std::endl; + typename graph_traits< Graph >::adjacency_iterator vi, vi_end; + out << get(name_map, u) << " -> { "; + for (boost::tie(vi, vi_end) = adjacent_vertices(u, g); vi != vi_end; ++vi) + out << get(name_map, *vi) << " "; + out << "}" << std::endl; } -template < typename NameMap > class name_equals_t { +template < typename NameMap > class name_equals_t +{ public: - name_equals_t(const std::string & n, NameMap map) - : m_name(n), m_name_map(map) - { - } - template < typename Vertex > bool operator()(Vertex u) const - { - return get(m_name_map, u) == m_name; - } + name_equals_t(const std::string& n, NameMap map) + : m_name(n), m_name_map(map) + { + } + template < typename Vertex > bool operator()(Vertex u) const + { + return get(m_name_map, u) == m_name; + } + private: std::string m_name; - NameMap m_name_map; + NameMap m_name_map; }; // object generator function template < typename NameMap > - inline name_equals_t < NameMap > -name_equals(const std::string & str, NameMap name) +inline name_equals_t< NameMap > name_equals( + const std::string& str, NameMap name) { - return name_equals_t < NameMap > (str, name); + return name_equals_t< NameMap >(str, name); } - -int -main(int argc, const char** argv) +int main(int argc, const char** argv) { - typedef adjacency_list < listS, // Store out-edges of each vertex in a std::list - vecS, // Store vertex set in a std::vector - directedS, // The graph is directed - property < vertex_name_t, std::string > // Add a vertex property - >graph_type; + typedef adjacency_list< listS, // Store out-edges of each vertex in a + // std::list + vecS, // Store vertex set in a std::vector + directedS, // The graph is directed + property< vertex_name_t, std::string > // Add a vertex property + > + graph_type; - graph_type g; // use default constructor to create empty graph - const char* dep_file_name = argc >= 2 ? argv[1] : "makefile-dependencies.dat"; - const char* target_file_name = argc >= 3 ? argv[2] : "makefile-target-names.dat"; - std::ifstream file_in(dep_file_name), name_in(target_file_name); - if (!file_in) { - std::cerr << "** Error: could not open file " << dep_file_name - << std::endl; - return -1; - } - if (!name_in) { - std::cerr << "** Error: could not open file " << target_file_name - << std::endl; - return -1; - } - // Obtain internal property map from the graph - property_map < graph_type, vertex_name_t >::type name_map = - get(vertex_name, g); - read_graph_file(file_in, name_in, g, name_map); + graph_type g; // use default constructor to create empty graph + const char* dep_file_name + = argc >= 2 ? argv[1] : "makefile-dependencies.dat"; + const char* target_file_name + = argc >= 3 ? argv[2] : "makefile-target-names.dat"; + std::ifstream file_in(dep_file_name), name_in(target_file_name); + if (!file_in) + { + std::cerr << "** Error: could not open file " << dep_file_name + << std::endl; + return -1; + } + if (!name_in) + { + std::cerr << "** Error: could not open file " << target_file_name + << std::endl; + return -1; + } + // Obtain internal property map from the graph + property_map< graph_type, vertex_name_t >::type name_map + = get(vertex_name, g); + read_graph_file(file_in, name_in, g, name_map); - graph_traits < graph_type >::vertex_iterator i, end; - boost::tie(i, end) = vertices(g); - i = std::find_if(i, end, name_equals("dax.h", get(vertex_name, g))); - output_adjacent_vertices(std::cout, *i, g, get(vertex_name, g)); + graph_traits< graph_type >::vertex_iterator i, end; + boost::tie(i, end) = vertices(g); + i = std::find_if(i, end, name_equals("dax.h", get(vertex_name, g))); + output_adjacent_vertices(std::cout, *i, g, get(vertex_name, g)); - assert(num_vertices(g) == 15); - assert(num_edges(g) == 19); - return 0; + assert(num_vertices(g) == 15); + assert(num_edges(g) == 19); + return 0; } diff --git a/example/print-edges.cpp b/example/print-edges.cpp index d4d67046c..20d4e1900 100644 --- a/example/print-edges.cpp +++ b/example/print-edges.cpp @@ -1,5 +1,5 @@ //======================================================================= -// Copyright 2001 Jeremy G. Siek, Andrew Lumsdaine, Lie-Quan Lee, +// Copyright 2001 Jeremy G. Siek, Andrew Lumsdaine, Lie-Quan Lee, // // Distributed under the Boost Software License, Version 1.0. (See // accompanying file LICENSE_1_0.txt or copy at @@ -13,72 +13,77 @@ using namespace boost; -template < typename Graph, typename VertexNamePropertyMap > void -read_graph_file(std::istream & graph_in, std::istream & name_in, - Graph & g, VertexNamePropertyMap name_map) +template < typename Graph, typename VertexNamePropertyMap > +void read_graph_file(std::istream& graph_in, std::istream& name_in, Graph& g, + VertexNamePropertyMap name_map) { - typedef typename graph_traits < Graph >::vertices_size_type size_type; - size_type n_vertices; - typename graph_traits < Graph >::vertex_descriptor u; - typename property_traits < VertexNamePropertyMap >::value_type name; + typedef typename graph_traits< Graph >::vertices_size_type size_type; + size_type n_vertices; + typename graph_traits< Graph >::vertex_descriptor u; + typename property_traits< VertexNamePropertyMap >::value_type name; - graph_in >> n_vertices; // read in number of vertices - for (size_type i = 0; i < n_vertices; ++i) { // Add n vertices to the graph - u = add_vertex(g); - name_in >> name; - put(name_map, u, name); // ** Attach name property to vertex u ** - } - size_type src, targ; - while (graph_in >> src) // Read in edges - if (graph_in >> targ) - add_edge(src, targ, g); // add an edge to the graph - else - break; + graph_in >> n_vertices; // read in number of vertices + for (size_type i = 0; i < n_vertices; ++i) + { // Add n vertices to the graph + u = add_vertex(g); + name_in >> name; + put(name_map, u, name); // ** Attach name property to vertex u ** + } + size_type src, targ; + while (graph_in >> src) // Read in edges + if (graph_in >> targ) + add_edge(src, targ, g); // add an edge to the graph + else + break; } -template < typename Graph, typename VertexNameMap > void -print_dependencies(std::ostream & out, const Graph & g, - VertexNameMap name_map) +template < typename Graph, typename VertexNameMap > +void print_dependencies( + std::ostream& out, const Graph& g, VertexNameMap name_map) { - typename graph_traits < Graph >::edge_iterator ei, ei_end; - for (boost::tie(ei, ei_end) = edges(g); ei != ei_end; ++ei) - out << get(name_map, source(*ei, g)) << " -$>$ " - << get(name_map, target(*ei, g)) << std::endl; + typename graph_traits< Graph >::edge_iterator ei, ei_end; + for (boost::tie(ei, ei_end) = edges(g); ei != ei_end; ++ei) + out << get(name_map, source(*ei, g)) << " -$>$ " + << get(name_map, target(*ei, g)) << std::endl; } - -int -main(int argc, const char** argv) +int main(int argc, const char** argv) { - typedef adjacency_list < listS, // Store out-edges of each vertex in a std::list - vecS, // Store vertex set in a std::vector - directedS, // The graph is directed - property < vertex_name_t, std::string > // Add a vertex property - >graph_type; + typedef adjacency_list< listS, // Store out-edges of each vertex in a + // std::list + vecS, // Store vertex set in a std::vector + directedS, // The graph is directed + property< vertex_name_t, std::string > // Add a vertex property + > + graph_type; - graph_type g; // use default constructor to create empty graph - const char* dep_file_name = argc >= 2 ? argv[1] : "makefile-dependencies.dat"; - const char* target_file_name = argc >= 3 ? argv[2] : "makefile-target-names.dat"; - std::ifstream file_in(dep_file_name), name_in(target_file_name); - if (!file_in) { - std::cerr << "** Error: could not open file " << dep_file_name - << std::endl; - return -1; - } - if (!name_in) { - std::cerr << "** Error: could not open file " << target_file_name - << std::endl; - return -1; - } + graph_type g; // use default constructor to create empty graph + const char* dep_file_name + = argc >= 2 ? argv[1] : "makefile-dependencies.dat"; + const char* target_file_name + = argc >= 3 ? argv[2] : "makefile-target-names.dat"; + std::ifstream file_in(dep_file_name), name_in(target_file_name); + if (!file_in) + { + std::cerr << "** Error: could not open file " << dep_file_name + << std::endl; + return -1; + } + if (!name_in) + { + std::cerr << "** Error: could not open file " << target_file_name + << std::endl; + return -1; + } - // Obtain internal property map from the graph - property_map < graph_type, vertex_name_t >::type name_map = - get(vertex_name, g); - read_graph_file(file_in, name_in, g, name_map); + // Obtain internal property map from the graph + property_map< graph_type, vertex_name_t >::type name_map + = get(vertex_name, g); + read_graph_file(file_in, name_in, g, name_map); - print_dependencies(std::cout, g, get(vertex_name, g)); + print_dependencies(std::cout, g, get(vertex_name, g)); - assert(num_vertices(g) == 15); - assert(num_edges(g) == 19); - return 0; + assert(num_vertices(g) == 15); + assert(num_edges(g) == 19); + return 0; } diff --git a/example/print-in-edges.cpp b/example/print-in-edges.cpp index 1c40ae74d..f45ecde1a 100644 --- a/example/print-in-edges.cpp +++ b/example/print-in-edges.cpp @@ -1,5 +1,5 @@ //======================================================================= -// Copyright 2001 Jeremy G. Siek, Andrew Lumsdaine, Lie-Quan Lee, +// Copyright 2001 Jeremy G. Siek, Andrew Lumsdaine, Lie-Quan Lee, // // Distributed under the Boost Software License, Version 1.0. (See // accompanying file LICENSE_1_0.txt or copy at @@ -13,98 +13,105 @@ using namespace boost; -template < typename Graph, typename VertexNamePropertyMap > void -read_graph_file(std::istream & graph_in, std::istream & name_in, - Graph & g, VertexNamePropertyMap name_map) +template < typename Graph, typename VertexNamePropertyMap > +void read_graph_file(std::istream& graph_in, std::istream& name_in, Graph& g, + VertexNamePropertyMap name_map) { - typedef typename graph_traits < Graph >::vertices_size_type size_type; - size_type n_vertices; - typename graph_traits < Graph >::vertex_descriptor u; - typename property_traits < VertexNamePropertyMap >::value_type name; + typedef typename graph_traits< Graph >::vertices_size_type size_type; + size_type n_vertices; + typename graph_traits< Graph >::vertex_descriptor u; + typename property_traits< VertexNamePropertyMap >::value_type name; - graph_in >> n_vertices; // read in number of vertices - for (size_type i = 0; i < n_vertices; ++i) { // Add n vertices to the graph - u = add_vertex(g); - name_in >> name; - put(name_map, u, name); // ** Attach name property to vertex u ** - } - size_type src, targ; - while (graph_in >> src) // Read in edges - if (graph_in >> targ) - add_edge(src, targ, g); // add an edge to the graph - else - break; + graph_in >> n_vertices; // read in number of vertices + for (size_type i = 0; i < n_vertices; ++i) + { // Add n vertices to the graph + u = add_vertex(g); + name_in >> name; + put(name_map, u, name); // ** Attach name property to vertex u ** + } + size_type src, targ; + while (graph_in >> src) // Read in edges + if (graph_in >> targ) + add_edge(src, targ, g); // add an edge to the graph + else + break; } -template < typename Graph, typename VertexNameMap > void -output_in_edges(std::ostream & out, const Graph & g, - typename graph_traits < Graph >::vertex_descriptor v, - VertexNameMap name_map) +template < typename Graph, typename VertexNameMap > +void output_in_edges(std::ostream& out, const Graph& g, + typename graph_traits< Graph >::vertex_descriptor v, VertexNameMap name_map) { - typename graph_traits < Graph >::in_edge_iterator ei, ei_end; - for (boost::tie(ei, ei_end) = in_edges(v, g); ei != ei_end; ++ei) - out << get(name_map, source(*ei, g)) << " -> " - << get(name_map, target(*ei, g)) << std::endl; + typename graph_traits< Graph >::in_edge_iterator ei, ei_end; + for (boost::tie(ei, ei_end) = in_edges(v, g); ei != ei_end; ++ei) + out << get(name_map, source(*ei, g)) << " -> " + << get(name_map, target(*ei, g)) << std::endl; } -template < typename NameMap > class name_equals_t { +template < typename NameMap > class name_equals_t +{ public: - name_equals_t(const std::string & n, NameMap map) - : m_name(n), m_name_map(map) - { - } - template < typename Vertex > bool operator()(Vertex u) const - { - return get(m_name_map, u) == m_name; - } + name_equals_t(const std::string& n, NameMap map) + : m_name(n), m_name_map(map) + { + } + template < typename Vertex > bool operator()(Vertex u) const + { + return get(m_name_map, u) == m_name; + } + private: std::string m_name; - NameMap m_name_map; + NameMap m_name_map; }; // object generator function template < typename NameMap > - inline name_equals_t < NameMap > -name_equals(const std::string & str, NameMap name) +inline name_equals_t< NameMap > name_equals( + const std::string& str, NameMap name) { - return name_equals_t < NameMap > (str, name); + return name_equals_t< NameMap >(str, name); } - -int -main(int argc, const char** argv) +int main(int argc, const char** argv) { - typedef adjacency_list < listS, // Store out-edges of each vertex in a std::list - vecS, // Store vertex set in a std::vector - bidirectionalS, // The graph is directed, with both out-edges and in-edges - property < vertex_name_t, std::string > // Add a vertex property - >graph_type; + typedef adjacency_list< listS, // Store out-edges of each vertex in a + // std::list + vecS, // Store vertex set in a std::vector + bidirectionalS, // The graph is directed, with both out-edges and + // in-edges + property< vertex_name_t, std::string > // Add a vertex property + > + graph_type; - graph_type g; // use default constructor to create empty graph - const char* dep_file_name = argc >= 2 ? argv[1] : "makefile-dependencies.dat"; - const char* target_file_name = argc >= 3 ? argv[2] : "makefile-target-names.dat"; - std::ifstream file_in(dep_file_name), name_in(target_file_name); - if (!file_in) { - std::cerr << "** Error: could not open file " << dep_file_name - << std::endl; - return -1; - } - if (!name_in) { - std::cerr << "** Error: could not open file " << target_file_name - << std::endl; - return -1; - } + graph_type g; // use default constructor to create empty graph + const char* dep_file_name + = argc >= 2 ? argv[1] : "makefile-dependencies.dat"; + const char* target_file_name + = argc >= 3 ? argv[2] : "makefile-target-names.dat"; + std::ifstream file_in(dep_file_name), name_in(target_file_name); + if (!file_in) + { + std::cerr << "** Error: could not open file " << dep_file_name + << std::endl; + return -1; + } + if (!name_in) + { + std::cerr << "** Error: could not open file " << target_file_name + << std::endl; + return -1; + } - // Obtain internal property map from the graph - property_map < graph_type, vertex_name_t >::type name_map = - get(vertex_name, g); - read_graph_file(file_in, name_in, g, name_map); + // Obtain internal property map from the graph + property_map< graph_type, vertex_name_t >::type name_map + = get(vertex_name, g); + read_graph_file(file_in, name_in, g, name_map); - graph_traits < graph_type >::vertex_iterator i, end; - boost::tie(i, end) = vertices(g); - i = std::find_if(i, end, name_equals("libzigzag.a", get(vertex_name, g))); - output_in_edges(std::cout, g, *i, get(vertex_name, g)); - assert(num_vertices(g) == 15); - assert(num_edges(g) == 19); - return 0; + graph_traits< graph_type >::vertex_iterator i, end; + boost::tie(i, end) = vertices(g); + i = std::find_if(i, end, name_equals("libzigzag.a", get(vertex_name, g))); + output_in_edges(std::cout, g, *i, get(vertex_name, g)); + assert(num_vertices(g) == 15); + assert(num_edges(g) == 19); + return 0; } diff --git a/example/print-out-edges.cpp b/example/print-out-edges.cpp index 6d8d57097..8c97205d2 100644 --- a/example/print-out-edges.cpp +++ b/example/print-out-edges.cpp @@ -1,5 +1,5 @@ //======================================================================= -// Copyright 2001 Jeremy G. Siek, Andrew Lumsdaine, Lie-Quan Lee, +// Copyright 2001 Jeremy G. Siek, Andrew Lumsdaine, Lie-Quan Lee, // // Distributed under the Boost Software License, Version 1.0. (See // accompanying file LICENSE_1_0.txt or copy at @@ -13,100 +13,106 @@ using namespace boost; -template < typename Graph, typename VertexNamePropertyMap > void -read_graph_file(std::istream & graph_in, std::istream & name_in, - Graph & g, VertexNamePropertyMap name_map) +template < typename Graph, typename VertexNamePropertyMap > +void read_graph_file(std::istream& graph_in, std::istream& name_in, Graph& g, + VertexNamePropertyMap name_map) { - typedef typename graph_traits < Graph >::vertices_size_type size_type; - size_type n_vertices; - typename graph_traits < Graph >::vertex_descriptor u; - typename property_traits < VertexNamePropertyMap >::value_type name; + typedef typename graph_traits< Graph >::vertices_size_type size_type; + size_type n_vertices; + typename graph_traits< Graph >::vertex_descriptor u; + typename property_traits< VertexNamePropertyMap >::value_type name; - graph_in >> n_vertices; // read in number of vertices - for (size_type i = 0; i < n_vertices; ++i) { // Add n vertices to the graph - u = add_vertex(g); - name_in >> name; - put(name_map, u, name); // ** Attach name property to vertex u ** - } - size_type src, targ; - while (graph_in >> src) // Read in edges - if (graph_in >> targ) - add_edge(src, targ, g); // add an edge to the graph - else - break; + graph_in >> n_vertices; // read in number of vertices + for (size_type i = 0; i < n_vertices; ++i) + { // Add n vertices to the graph + u = add_vertex(g); + name_in >> name; + put(name_map, u, name); // ** Attach name property to vertex u ** + } + size_type src, targ; + while (graph_in >> src) // Read in edges + if (graph_in >> targ) + add_edge(src, targ, g); // add an edge to the graph + else + break; } -template < typename Graph, typename VertexNameMap > void -output_out_edges(std::ostream & out, const Graph & g, - typename graph_traits < Graph >::vertex_descriptor u, - VertexNameMap name_map) +template < typename Graph, typename VertexNameMap > +void output_out_edges(std::ostream& out, const Graph& g, + typename graph_traits< Graph >::vertex_descriptor u, VertexNameMap name_map) { - typename graph_traits < Graph >::out_edge_iterator ei, ei_end; - for (boost::tie(ei, ei_end) = out_edges(u, g); ei != ei_end; ++ei) - out << get(name_map, source(*ei, g)) << " -> " - << get(name_map, target(*ei, g)) << std::endl; + typename graph_traits< Graph >::out_edge_iterator ei, ei_end; + for (boost::tie(ei, ei_end) = out_edges(u, g); ei != ei_end; ++ei) + out << get(name_map, source(*ei, g)) << " -> " + << get(name_map, target(*ei, g)) << std::endl; } -template < typename NameMap > class name_equals_t { +template < typename NameMap > class name_equals_t +{ public: - name_equals_t(const std::string & n, NameMap map) - : m_name(n), m_name_map(map) - { - } - template < typename Vertex > bool operator()(Vertex u) const - { - return get(m_name_map, u) == m_name; - } + name_equals_t(const std::string& n, NameMap map) + : m_name(n), m_name_map(map) + { + } + template < typename Vertex > bool operator()(Vertex u) const + { + return get(m_name_map, u) == m_name; + } + private: std::string m_name; - NameMap m_name_map; + NameMap m_name_map; }; // object generator function template < typename NameMap > - inline name_equals_t < NameMap > -name_equals(const std::string & str, NameMap name) +inline name_equals_t< NameMap > name_equals( + const std::string& str, NameMap name) { - return name_equals_t < NameMap > (str, name); + return name_equals_t< NameMap >(str, name); } - -int -main(int argc, const char** argv) +int main(int argc, const char** argv) { - typedef adjacency_list < listS, // Store out-edges of each vertex in a std::list - vecS, // Store vertex set in a std::vector - directedS, // The graph is directed - property < vertex_name_t, std::string > // Add a vertex property - >graph_type; + typedef adjacency_list< listS, // Store out-edges of each vertex in a + // std::list + vecS, // Store vertex set in a std::vector + directedS, // The graph is directed + property< vertex_name_t, std::string > // Add a vertex property + > + graph_type; - graph_type g; // use default constructor to create empty graph - const char* dep_file_name = argc >= 2 ? argv[1] : "makefile-dependencies.dat"; - const char* target_file_name = argc >= 3 ? argv[2] : "makefile-target-names.dat"; - std::ifstream file_in(dep_file_name), name_in(target_file_name); - if (!file_in) { - std::cerr << "** Error: could not open file " << dep_file_name - << std::endl; - return -1; - } - if (!name_in) { - std::cerr << "** Error: could not open file " << target_file_name - << std::endl; - return -1; - } - // Obtain internal property map from the graph - property_map < graph_type, vertex_name_t >::type name_map = - get(vertex_name, g); - read_graph_file(file_in, name_in, g, name_map); + graph_type g; // use default constructor to create empty graph + const char* dep_file_name + = argc >= 2 ? argv[1] : "makefile-dependencies.dat"; + const char* target_file_name + = argc >= 3 ? argv[2] : "makefile-target-names.dat"; + std::ifstream file_in(dep_file_name), name_in(target_file_name); + if (!file_in) + { + std::cerr << "** Error: could not open file " << dep_file_name + << std::endl; + return -1; + } + if (!name_in) + { + std::cerr << "** Error: could not open file " << target_file_name + << std::endl; + return -1; + } + // Obtain internal property map from the graph + property_map< graph_type, vertex_name_t >::type name_map + = get(vertex_name, g); + read_graph_file(file_in, name_in, g, name_map); - graph_traits < graph_type >::vertex_iterator i, end; - boost::tie(i, end) = vertices(g); - typedef property_map < graph_type, vertex_name_t >::type name_map_t; - name_equals_t < name_map_t > predicate("dax.h", get(vertex_name, g)); - i = std::find_if(i, end, predicate); - output_out_edges(std::cout, g, *i, get(vertex_name, g)); + graph_traits< graph_type >::vertex_iterator i, end; + boost::tie(i, end) = vertices(g); + typedef property_map< graph_type, vertex_name_t >::type name_map_t; + name_equals_t< name_map_t > predicate("dax.h", get(vertex_name, g)); + i = std::find_if(i, end, predicate); + output_out_edges(std::cout, g, *i, get(vertex_name, g)); - assert(num_vertices(g) == 15); - assert(num_edges(g) == 19); - return 0; + assert(num_vertices(g) == 15); + assert(num_edges(g) == 19); + return 0; } diff --git a/example/property-map-traits-eg.cpp b/example/property-map-traits-eg.cpp index c82ab19c5..3df924324 100644 --- a/example/property-map-traits-eg.cpp +++ b/example/property-map-traits-eg.cpp @@ -1,5 +1,5 @@ //======================================================================= -// Copyright 2001 Jeremy G. Siek, Andrew Lumsdaine, Lie-Quan Lee, +// Copyright 2001 Jeremy G. Siek, Andrew Lumsdaine, Lie-Quan Lee, // // Distributed under the Boost Software License, Version 1.0. (See // accompanying file LICENSE_1_0.txt or copy at @@ -9,17 +9,16 @@ #include #include #include -int -main() +int main() { - using namespace boost; - typedef adjacency_list < listS, listS, directedS, - property < vertex_name_t, std::string > >graph_t; - graph_t g; - graph_traits < graph_t >::vertex_descriptor u = add_vertex(g); - property_map < graph_t, vertex_name_t >::type - name_map = get(vertex_name, g); - name_map[u] = "Joe"; - std::cout << name_map[u] << std::endl; - return EXIT_SUCCESS; + using namespace boost; + typedef adjacency_list< listS, listS, directedS, + property< vertex_name_t, std::string > > + graph_t; + graph_t g; + graph_traits< graph_t >::vertex_descriptor u = add_vertex(g); + property_map< graph_t, vertex_name_t >::type name_map = get(vertex_name, g); + name_map[u] = "Joe"; + std::cout << name_map[u] << std::endl; + return EXIT_SUCCESS; } diff --git a/example/property_iterator.cpp b/example/property_iterator.cpp index d8e61cc30..e95619b33 100644 --- a/example/property_iterator.cpp +++ b/example/property_iterator.cpp @@ -1,5 +1,5 @@ -// (C) Copyright Francois Faure, iMAGIS-GRAVIR / UJF, 2001. +// (C) Copyright Francois Faure, iMAGIS-GRAVIR / UJF, 2001. // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at @@ -7,7 +7,7 @@ // Revision History: // 03 May 2001 Jeremy Siek -// Moved property iterator code to headers. +// Moved property iterator code to headers. // 02 May 2001 Francois Faure // Initial version. @@ -16,102 +16,114 @@ #include #include - using namespace boost; //======== vertex properties -struct toto_t { - enum { num = 23063}; - typedef vertex_property_tag kind; +struct toto_t +{ + enum + { + num = 23063 + }; + typedef vertex_property_tag kind; }; typedef property< toto_t, double > Toto; -struct radius_t { - enum { num = 23062}; - typedef vertex_property_tag kind; +struct radius_t +{ + enum + { + num = 23062 + }; + typedef vertex_property_tag kind; }; typedef property< radius_t, double, Toto > Radius; -struct mass_t { - enum { num = 23061}; - typedef vertex_property_tag kind; +struct mass_t +{ + enum + { + num = 23061 + }; + typedef vertex_property_tag kind; }; typedef property< mass_t, int, Radius > Mass; - //====== edge properties -struct stiff_t { - enum { num = 23064}; - typedef edge_property_tag kind; +struct stiff_t +{ + enum + { + num = 23064 + }; + typedef edge_property_tag kind; }; -typedef property Stiff; - - +typedef property< stiff_t, double > Stiff; //===== graph type typedef Mass VertexProperty; typedef Stiff EdgeProperty; -typedef adjacency_list Graph; - +typedef adjacency_list< vecS, setS, bidirectionalS, VertexProperty, + EdgeProperty > + Graph; //===== utilities struct Print { - template - Print& operator() (const T& t) { - std::cout << t << " "; - return (*this); - } + template < class T > Print& operator()(const T& t) + { + std::cout << t << " "; + return (*this); + } }; -template -struct Set +template < class T > struct Set { - T value; - - Set( const T& t ):value(t){} - - Set& operator() (T& t) { - t=value; - return (*this); - } -}; + T value; + Set(const T& t) : value(t) {} + + Set& operator()(T& t) + { + t = value; + return (*this); + } +}; //===== program int main(int argc, char* argv[]) { - if (argc < 2) { - std::cerr<<"args: file"<> read( graph ); - std::cout << write( graph ); - - std::cout << "radii:" << std::endl; - graph_property_iter_range::type - seqRadius = get_property_iter_range(graph,radius_t()); - std::for_each( seqRadius.first, seqRadius.second, Print() ); - std::cout << std::endl; - - std::cout << "stiff:" << std::endl; - graph_property_iter_range::type + if (argc < 2) + { + std::cerr << "args: file" << std::endl; + return EXIT_FAILURE; + } + + std::ifstream readFile(argv[1]); + + Graph graph; + readFile >> read(graph); + std::cout << write(graph); + + std::cout << "radii:" << std::endl; + graph_property_iter_range< Graph, radius_t >::type seqRadius + = get_property_iter_range(graph, radius_t()); + std::for_each(seqRadius.first, seqRadius.second, Print()); + std::cout << std::endl; + + std::cout << "stiff:" << std::endl; + graph_property_iter_range< Graph, stiff_t >::type seqStiff + = get_property_iter_range(graph, stiff_t()); + std::for_each(seqStiff.first, seqStiff.second, Print()); + std::cout << std::endl; + + seqStiff = get_property_iter_range(graph, stiff_t()); + std::for_each(seqStiff.first, seqStiff.second, Set< double >(2.4)); + + std::cout << "new stiff:" << std::endl; seqStiff = get_property_iter_range(graph, stiff_t()); - std::for_each( seqStiff.first, seqStiff.second, Print() ); - std::cout << std::endl; - - seqStiff = get_property_iter_range(graph, stiff_t()); - std::for_each( seqStiff.first, seqStiff.second, Set(2.4) ); - - std::cout << "new stiff:" << std::endl; - seqStiff = get_property_iter_range(graph,stiff_t()); - std::for_each( seqStiff.first, seqStiff.second, Print() ); - std::cout << std::endl; - - return 0; + std::for_each(seqStiff.first, seqStiff.second, Print()); + std::cout << std::endl; + + return 0; } diff --git a/example/push-relabel-eg.cpp b/example/push-relabel-eg.cpp index 470b1e97c..04a6fa485 100644 --- a/example/push-relabel-eg.cpp +++ b/example/push-relabel-eg.cpp @@ -1,5 +1,5 @@ //======================================================================= -// Copyright 2001 Jeremy G. Siek, Andrew Lumsdaine, Lie-Quan Lee, +// Copyright 2001 Jeremy G. Siek, Andrew Lumsdaine, Lie-Quan Lee, // // Distributed under the Boost Software License, Version 1.0. (See // accompanying file LICENSE_1_0.txt or copy at @@ -44,44 +44,44 @@ // f 7 6 0 // f 7 5 0 - -int -main() +int main() { - using namespace boost; - typedef adjacency_list_traits < vecS, vecS, directedS > Traits; - typedef adjacency_list < vecS, vecS, directedS, - property < vertex_name_t, std::string >, - property < edge_capacity_t, long, - property < edge_residual_capacity_t, long, - property < edge_reverse_t, Traits::edge_descriptor > > > > Graph; - Graph g; + using namespace boost; + typedef adjacency_list_traits< vecS, vecS, directedS > Traits; + typedef adjacency_list< vecS, vecS, directedS, + property< vertex_name_t, std::string >, + property< edge_capacity_t, long, + property< edge_residual_capacity_t, long, + property< edge_reverse_t, Traits::edge_descriptor > > > > + Graph; + Graph g; - property_map < Graph, edge_capacity_t >::type - capacity = get(edge_capacity, g); - property_map < Graph, edge_residual_capacity_t >::type - residual_capacity = get(edge_residual_capacity, g); - property_map < Graph, edge_reverse_t >::type rev = get(edge_reverse, g); - Traits::vertex_descriptor s, t; - read_dimacs_max_flow(g, capacity, rev, s, t); + property_map< Graph, edge_capacity_t >::type capacity + = get(edge_capacity, g); + property_map< Graph, edge_residual_capacity_t >::type residual_capacity + = get(edge_residual_capacity, g); + property_map< Graph, edge_reverse_t >::type rev = get(edge_reverse, g); + Traits::vertex_descriptor s, t; + read_dimacs_max_flow(g, capacity, rev, s, t); #if defined(BOOST_MSVC) && BOOST_MSVC <= 1300 - property_map::type indexmap = get(vertex_index, g); - long flow = push_relabel_max_flow(g, s, t, capacity, residual_capacity, rev, - indexmap); + property_map< Graph, vertex_index_t >::type indexmap = get(vertex_index, g); + long flow = push_relabel_max_flow( + g, s, t, capacity, residual_capacity, rev, indexmap); #else - long flow = push_relabel_max_flow(g, s, t); + long flow = push_relabel_max_flow(g, s, t); #endif - std::cout << "c The total flow:" << std::endl; - std::cout << "s " << flow << std::endl << std::endl; - std::cout << "c flow values:" << std::endl; - graph_traits < Graph >::vertex_iterator u_iter, u_end; - graph_traits < Graph >::out_edge_iterator ei, e_end; - for (boost::tie(u_iter, u_end) = vertices(g); u_iter != u_end; ++u_iter) - for (boost::tie(ei, e_end) = out_edges(*u_iter, g); ei != e_end; ++ei) - if (capacity[*ei] > 0) - std::cout << "f " << *u_iter << " " << target(*ei, g) << " " - << (capacity[*ei] - residual_capacity[*ei]) << std::endl; - return EXIT_SUCCESS; + std::cout << "c The total flow:" << std::endl; + std::cout << "s " << flow << std::endl << std::endl; + std::cout << "c flow values:" << std::endl; + graph_traits< Graph >::vertex_iterator u_iter, u_end; + graph_traits< Graph >::out_edge_iterator ei, e_end; + for (boost::tie(u_iter, u_end) = vertices(g); u_iter != u_end; ++u_iter) + for (boost::tie(ei, e_end) = out_edges(*u_iter, g); ei != e_end; ++ei) + if (capacity[*ei] > 0) + std::cout << "f " << *u_iter << " " << target(*ei, g) << " " + << (capacity[*ei] - residual_capacity[*ei]) + << std::endl; + return EXIT_SUCCESS; } diff --git a/example/put-get-helper-eg.cpp b/example/put-get-helper-eg.cpp index 9c14e1b99..ae736ba10 100644 --- a/example/put-get-helper-eg.cpp +++ b/example/put-get-helper-eg.cpp @@ -1,5 +1,5 @@ //======================================================================= -// Copyright 2001 Jeremy G. Siek, Andrew Lumsdaine, Lie-Quan Lee, +// Copyright 2001 Jeremy G. Siek, Andrew Lumsdaine, Lie-Quan Lee, // // Distributed under the Boost Software License, Version 1.0. (See // accompanying file LICENSE_1_0.txt or copy at @@ -14,46 +14,47 @@ #error This examples requires a compiler that provides a working std::iterator_traits #endif - namespace foo { - using namespace boost; - template < class RandomAccessIterator, class IndexMap > - class iterator_property_map:public boost::put_get_helper < - typename std::iterator_traits < RandomAccessIterator >::reference, - iterator_property_map < RandomAccessIterator, IndexMap > > - { - public: +using namespace boost; +template < class RandomAccessIterator, class IndexMap > +class iterator_property_map +: public boost::put_get_helper< + typename std::iterator_traits< RandomAccessIterator >::reference, + iterator_property_map< RandomAccessIterator, IndexMap > > +{ +public: typedef std::ptrdiff_t key_type; - typedef typename std::iterator_traits < RandomAccessIterator >::value_type - value_type; - typedef typename std::iterator_traits < RandomAccessIterator >::reference - reference; + typedef typename std::iterator_traits< RandomAccessIterator >::value_type + value_type; + typedef typename std::iterator_traits< RandomAccessIterator >::reference + reference; typedef boost::lvalue_property_map_tag category; - iterator_property_map(RandomAccessIterator cc = RandomAccessIterator(), - const IndexMap & _id = - IndexMap()):iter(cc), index(_id) + iterator_property_map(RandomAccessIterator cc = RandomAccessIterator(), + const IndexMap& _id = IndexMap()) + : iter(cc), index(_id) { } - reference operator[] (std::ptrdiff_t v) const + reference operator[](std::ptrdiff_t v) const { - return *(iter + get(index, v)); + return *(iter + get(index, v)); } - protected: - RandomAccessIterator iter; + +protected: + RandomAccessIterator iter; IndexMap index; - }; +}; } -int -main() +int main() { - typedef std::vector < std::string > vec_t; - typedef foo::iterator_property_map < vec_t::iterator, - boost::identity_property_map > pmap_t; - using namespace boost; - BOOST_CONCEPT_ASSERT(( Mutable_LvaluePropertyMapConcept )); - return 0; + typedef std::vector< std::string > vec_t; + typedef foo::iterator_property_map< vec_t::iterator, + boost::identity_property_map > + pmap_t; + using namespace boost; + BOOST_CONCEPT_ASSERT((Mutable_LvaluePropertyMapConcept< pmap_t, int >)); + return 0; } diff --git a/example/quick-tour.cpp b/example/quick-tour.cpp index 31ffb6064..8d79b72b7 100644 --- a/example/quick-tour.cpp +++ b/example/quick-tour.cpp @@ -13,96 +13,93 @@ using namespace boost; -template < typename VertexDescriptor, typename VertexNameMap > void -print_vertex_name(VertexDescriptor v, VertexNameMap name_map) +template < typename VertexDescriptor, typename VertexNameMap > +void print_vertex_name(VertexDescriptor v, VertexNameMap name_map) { - std::cout << get(name_map, v); + std::cout << get(name_map, v); } -template < typename Graph, typename TransDelayMap, typename VertexNameMap > void -print_trans_delay(typename graph_traits < Graph >::edge_descriptor e, - const Graph & g, TransDelayMap delay_map, - VertexNameMap name_map) +template < typename Graph, typename TransDelayMap, typename VertexNameMap > +void print_trans_delay(typename graph_traits< Graph >::edge_descriptor e, + const Graph& g, TransDelayMap delay_map, VertexNameMap name_map) { - std::cout << "trans-delay(" << get(name_map, source(e, g)) << "," - << get(name_map, target(e, g)) << ") = " << get(delay_map, e); + std::cout << "trans-delay(" << get(name_map, source(e, g)) << "," + << get(name_map, target(e, g)) << ") = " << get(delay_map, e); } -template < typename Graph, typename VertexNameMap > void -print_vertex_names(const Graph & g, VertexNameMap name_map) +template < typename Graph, typename VertexNameMap > +void print_vertex_names(const Graph& g, VertexNameMap name_map) { - std::cout << "vertices(g) = { "; - typedef typename graph_traits < Graph >::vertex_iterator iter_t; - for (std::pair < iter_t, iter_t > p = vertices(g); p.first != p.second; - ++p.first) { - print_vertex_name(*p.first, name_map); - std::cout << ' '; - } - std::cout << "}" << std::endl; + std::cout << "vertices(g) = { "; + typedef typename graph_traits< Graph >::vertex_iterator iter_t; + for (std::pair< iter_t, iter_t > p = vertices(g); p.first != p.second; + ++p.first) + { + print_vertex_name(*p.first, name_map); + std::cout << ' '; + } + std::cout << "}" << std::endl; } -template < typename Graph, typename TransDelayMap, typename VertexNameMap > void -print_trans_delays(const Graph & g, TransDelayMap trans_delay_map, - VertexNameMap name_map) +template < typename Graph, typename TransDelayMap, typename VertexNameMap > +void print_trans_delays( + const Graph& g, TransDelayMap trans_delay_map, VertexNameMap name_map) { - typename graph_traits < Graph >::edge_iterator first, last; - for (boost::tie(first, last) = edges(g); first != last; ++first) { - print_trans_delay(*first, g, trans_delay_map, name_map); - std::cout << std::endl; - } + typename graph_traits< Graph >::edge_iterator first, last; + for (boost::tie(first, last) = edges(g); first != last; ++first) + { + print_trans_delay(*first, g, trans_delay_map, name_map); + std::cout << std::endl; + } } -template < typename Graph, typename VertexNameMap, typename TransDelayMap > void -build_router_network(Graph & g, VertexNameMap name_map, - TransDelayMap delay_map) +template < typename Graph, typename VertexNameMap, typename TransDelayMap > +void build_router_network( + Graph& g, VertexNameMap name_map, TransDelayMap delay_map) { - typename graph_traits < Graph >::vertex_descriptor a, b, c, d, e; - a = add_vertex(g); - name_map[a] = 'a'; - b = add_vertex(g); - name_map[b] = 'b'; - c = add_vertex(g); - name_map[c] = 'c'; - d = add_vertex(g); - name_map[d] = 'd'; - e = add_vertex(g); - name_map[e] = 'e'; + typename graph_traits< Graph >::vertex_descriptor a, b, c, d, e; + a = add_vertex(g); + name_map[a] = 'a'; + b = add_vertex(g); + name_map[b] = 'b'; + c = add_vertex(g); + name_map[c] = 'c'; + d = add_vertex(g); + name_map[d] = 'd'; + e = add_vertex(g); + name_map[e] = 'e'; - typename graph_traits < Graph >::edge_descriptor ed; - bool inserted; - - boost::tie(ed, inserted) = add_edge(a, b, g); - delay_map[ed] = 1.2; - boost::tie(ed, inserted) = add_edge(a, d, g); - delay_map[ed] = 4.5; - boost::tie(ed, inserted) = add_edge(b, d, g); - delay_map[ed] = 1.8; - boost::tie(ed, inserted) = add_edge(c, a, g); - delay_map[ed] = 2.6; - boost::tie(ed, inserted) = add_edge(c, e, g); - delay_map[ed] = 5.2; - boost::tie(ed, inserted) = add_edge(d, c, g); - delay_map[ed] = 0.4; - boost::tie(ed, inserted) = add_edge(d, e, g); - delay_map[ed] = 3.3; + typename graph_traits< Graph >::edge_descriptor ed; + bool inserted; + boost::tie(ed, inserted) = add_edge(a, b, g); + delay_map[ed] = 1.2; + boost::tie(ed, inserted) = add_edge(a, d, g); + delay_map[ed] = 4.5; + boost::tie(ed, inserted) = add_edge(b, d, g); + delay_map[ed] = 1.8; + boost::tie(ed, inserted) = add_edge(c, a, g); + delay_map[ed] = 2.6; + boost::tie(ed, inserted) = add_edge(c, e, g); + delay_map[ed] = 5.2; + boost::tie(ed, inserted) = add_edge(d, c, g); + delay_map[ed] = 0.4; + boost::tie(ed, inserted) = add_edge(d, e, g); + delay_map[ed] = 3.3; } - -int -main() +int main() { - typedef adjacency_list < listS, listS, directedS, - property < vertex_name_t, char >, - property < edge_weight_t, double > > graph_t; - graph_t g; + typedef adjacency_list< listS, listS, directedS, + property< vertex_name_t, char >, property< edge_weight_t, double > > + graph_t; + graph_t g; - property_map < graph_t, vertex_name_t >::type name_map = - get(vertex_name, g); - property_map < graph_t, edge_weight_t >::type delay_map = - get(edge_weight, g); + property_map< graph_t, vertex_name_t >::type name_map = get(vertex_name, g); + property_map< graph_t, edge_weight_t >::type delay_map + = get(edge_weight, g); - build_router_network(g, name_map, delay_map); - print_vertex_names(g, name_map); - print_trans_delays(g, delay_map, name_map); + build_router_network(g, name_map, delay_map); + print_vertex_names(g, name_map); + print_trans_delays(g, delay_map, name_map); } diff --git a/example/quick_tour.cpp b/example/quick_tour.cpp index e639fc5a5..25d1f5e11 100644 --- a/example/quick_tour.cpp +++ b/example/quick_tour.cpp @@ -8,134 +8,149 @@ //======================================================================= #include -#include // for std::cout -#include // for std::pair -#include // for std::for_each -#include // for boost::tie +#include // for std::cout +#include // for std::pair +#include // for std::for_each +#include // for boost::tie #include #include using namespace boost; -template struct exercise_vertex { - exercise_vertex(Graph& g_, const char name_[]) : g(g_),name(name_) { } - typedef typename graph_traits::vertex_descriptor Vertex; - void operator()(const Vertex& v) const - { - using namespace boost; - typename property_map::type - vertex_id = get(vertex_index, g); - std::cout << "vertex: " << name[get(vertex_id, v)] << std::endl; - - // Write out the outgoing edges - std::cout << "\tout-edges: "; - typename graph_traits::out_edge_iterator out_i, out_end; - typename graph_traits::edge_descriptor e; - for (boost::tie(out_i, out_end) = out_edges(v, g); - out_i != out_end; ++out_i) +template < class Graph > struct exercise_vertex +{ + exercise_vertex(Graph& g_, const char name_[]) : g(g_), name(name_) {} + typedef typename graph_traits< Graph >::vertex_descriptor Vertex; + void operator()(const Vertex& v) const { - e = *out_i; - Vertex src = source(e, g), targ = target(e, g); - std::cout << "(" << name[get(vertex_id, src)] - << "," << name[get(vertex_id, targ)] << ") "; + using namespace boost; + typename property_map< Graph, vertex_index_t >::type vertex_id + = get(vertex_index, g); + std::cout << "vertex: " << name[get(vertex_id, v)] << std::endl; + + // Write out the outgoing edges + std::cout << "\tout-edges: "; + typename graph_traits< Graph >::out_edge_iterator out_i, out_end; + typename graph_traits< Graph >::edge_descriptor e; + for (boost::tie(out_i, out_end) = out_edges(v, g); out_i != out_end; + ++out_i) + { + e = *out_i; + Vertex src = source(e, g), targ = target(e, g); + std::cout << "(" << name[get(vertex_id, src)] << "," + << name[get(vertex_id, targ)] << ") "; + } + std::cout << std::endl; + + // Write out the incoming edges + std::cout << "\tin-edges: "; + typename graph_traits< Graph >::in_edge_iterator in_i, in_end; + for (boost::tie(in_i, in_end) = in_edges(v, g); in_i != in_end; ++in_i) + { + e = *in_i; + Vertex src = source(e, g), targ = target(e, g); + std::cout << "(" << name[get(vertex_id, src)] << "," + << name[get(vertex_id, targ)] << ") "; + } + std::cout << std::endl; + + // Write out all adjacent vertices + std::cout << "\tadjacent vertices: "; + typename graph_traits< Graph >::adjacency_iterator ai, ai_end; + for (boost::tie(ai, ai_end) = adjacent_vertices(v, g); ai != ai_end; + ++ai) + std::cout << name[get(vertex_id, *ai)] << " "; + std::cout << std::endl; } - std::cout << std::endl; + Graph& g; + const char* name; +}; + +int main(int, char*[]) +{ + // create a typedef for the Graph type + typedef adjacency_list< vecS, vecS, bidirectionalS, no_property, + property< edge_weight_t, float > > + Graph; - // Write out the incoming edges - std::cout << "\tin-edges: "; - typename graph_traits::in_edge_iterator in_i, in_end; - for (boost::tie(in_i, in_end) = in_edges(v, g); in_i != in_end; ++in_i) + // Make convenient labels for the vertices + enum { - e = *in_i; - Vertex src = source(e, g), targ = target(e, g); - std::cout << "(" << name[get(vertex_id, src)] - << "," << name[get(vertex_id, targ)] << ") "; + A, + B, + C, + D, + E, + N + }; + const int num_vertices = N; + const char name[] = "ABCDE"; + + // writing out the edges in the graph + typedef std::pair< int, int > Edge; + Edge edge_array[] = { + Edge(A, B), + Edge(A, D), + Edge(C, A), + Edge(D, C), + Edge(C, E), + Edge(B, D), + Edge(D, E), + }; + const int num_edges = sizeof(edge_array) / sizeof(edge_array[0]); + + // average transmission delay (in milliseconds) for each connection + float transmission_delay[] = { 1.2, 4.5, 2.6, 0.4, 5.2, 1.8, 3.3, 9.1 }; + + // declare a graph object, adding the edges and edge properties +#if defined(BOOST_MSVC) && BOOST_MSVC <= 1300 + // VC++ can't handle the iterator constructor + Graph g(num_vertices); + property_map< Graph, edge_weight_t >::type weightmap = get(edge_weight, g); + for (std::size_t j = 0; j < num_edges; ++j) + { + graph_traits< Graph >::edge_descriptor e; + bool inserted; + boost::tie(e, inserted) + = add_edge(edge_array[j].first, edge_array[j].second, g); + weightmap[e] = transmission_delay[j]; } - std::cout << std::endl; +#else + Graph g( + edge_array, edge_array + num_edges, transmission_delay, num_vertices); +#endif - // Write out all adjacent vertices - std::cout << "\tadjacent vertices: "; - typename graph_traits::adjacency_iterator ai, ai_end; - for (boost::tie(ai,ai_end) = adjacent_vertices(v, g); ai != ai_end; ++ai) - std::cout << name[get(vertex_id, *ai)] << " "; + boost::property_map< Graph, vertex_index_t >::type vertex_id + = get(vertex_index, g); + boost::property_map< Graph, edge_weight_t >::type trans_delay + = get(edge_weight, g); + + std::cout << "vertices(g) = "; + typedef graph_traits< Graph >::vertex_iterator vertex_iter; + std::pair< vertex_iter, vertex_iter > vp; + for (vp = vertices(g); vp.first != vp.second; ++vp.first) + std::cout << name[get(vertex_id, *vp.first)] << " "; std::cout << std::endl; - } - Graph& g; - const char *name; -}; + std::cout << "edges(g) = "; + graph_traits< Graph >::edge_iterator ei, ei_end; + for (boost::tie(ei, ei_end) = edges(g); ei != ei_end; ++ei) + std::cout << "(" << name[get(vertex_id, source(*ei, g))] << "," + << name[get(vertex_id, target(*ei, g))] << ") "; + std::cout << std::endl; -int main(int,char*[]) -{ - // create a typedef for the Graph type - typedef adjacency_list > Graph; - - // Make convenient labels for the vertices - enum { A, B, C, D, E, N }; - const int num_vertices = N; - const char name[] = "ABCDE"; - - // writing out the edges in the graph - typedef std::pair Edge; - Edge edge_array[] = - { Edge(A,B), Edge(A,D), Edge(C,A), Edge(D,C), - Edge(C,E), Edge(B,D), Edge(D,E), }; - const int num_edges = sizeof(edge_array)/sizeof(edge_array[0]); - - // average transmission delay (in milliseconds) for each connection - float transmission_delay[] = { 1.2, 4.5, 2.6, 0.4, 5.2, 1.8, 3.3, 9.1 }; - - // declare a graph object, adding the edges and edge properties -#if defined(BOOST_MSVC) && BOOST_MSVC <= 1300 - // VC++ can't handle the iterator constructor - Graph g(num_vertices); - property_map::type weightmap = get(edge_weight, g); - for (std::size_t j = 0; j < num_edges; ++j) { - graph_traits::edge_descriptor e; bool inserted; - boost::tie(e, inserted) = add_edge(edge_array[j].first, edge_array[j].second, g); - weightmap[e] = transmission_delay[j]; - } -#else - Graph g(edge_array, edge_array + num_edges, - transmission_delay, num_vertices); -#endif + std::for_each(vertices(g).first, vertices(g).second, + exercise_vertex< Graph >(g, name)); - boost::property_map::type - vertex_id = get(vertex_index, g); - boost::property_map::type - trans_delay = get(edge_weight, g); - - std::cout << "vertices(g) = "; - typedef graph_traits::vertex_iterator vertex_iter; - std::pair vp; - for (vp = vertices(g); vp.first != vp.second; ++vp.first) - std::cout << name[get(vertex_id, *vp.first)] << " "; - std::cout << std::endl; - - std::cout << "edges(g) = "; - graph_traits::edge_iterator ei, ei_end; - for (boost::tie(ei,ei_end) = edges(g); ei != ei_end; ++ei) - std::cout << "(" << name[get(vertex_id, source(*ei, g))] - << "," << name[get(vertex_id, target(*ei, g))] << ") "; - std::cout << std::endl; - - std::for_each(vertices(g).first, vertices(g).second, - exercise_vertex(g, name)); - - std::map graph_attr, vertex_attr, edge_attr; - graph_attr["size"] = "3,3"; - graph_attr["rankdir"] = "LR"; - graph_attr["ratio"] = "fill"; - vertex_attr["shape"] = "circle"; - - boost::write_graphviz(std::cout, g, - make_label_writer(name), - make_label_writer(trans_delay), - make_graph_attributes_writer(graph_attr, vertex_attr, - edge_attr)); - - return 0; -} + std::map< std::string, std::string > graph_attr, vertex_attr, edge_attr; + graph_attr["size"] = "3,3"; + graph_attr["rankdir"] = "LR"; + graph_attr["ratio"] = "fill"; + vertex_attr["shape"] = "circle"; + boost::write_graphviz(std::cout, g, make_label_writer(name), + make_label_writer(trans_delay), + make_graph_attributes_writer(graph_attr, vertex_attr, edge_attr)); + return 0; +} diff --git a/example/quick_tour.expected b/example/quick_tour.expected index ec66d962e..fb2d34a85 100644 --- a/example/quick_tour.expected +++ b/example/quick_tour.expected @@ -1,22 +1,22 @@ -vertices(g) = 0 1 2 3 4 -edges(g) = (0,1) (0,2) (0,3) (0,4) (2,0) (2,4) (3,0) (3,1) (3,4) (4,0) (4,1) +vertices(g) = 0 1 2 3 4 +edges(g) = (0,1) (0,2) (0,3) (0,4) (2,0) (2,4) (3,0) (3,1) (3,4) (4,0) (4,1) vertex: 0 - out-edges: (0,1) (0,2) (0,3) (0,4) - in-edges: (2,0) (3,0) (4,0) - adjacent vertices: 1 2 3 4 + out-edges: (0,1) (0,2) (0,3) (0,4) + in-edges: (2,0) (3,0) (4,0) + adjacent vertices: 1 2 3 4 vertex: 1 - out-edges: - in-edges: (0,1) (3,1) (4,1) - adjacent vertices: + out-edges: + in-edges: (0,1) (3,1) (4,1) + adjacent vertices: vertex: 2 - out-edges: (2,0) (2,4) - in-edges: (0,2) - adjacent vertices: 0 4 + out-edges: (2,0) (2,4) + in-edges: (0,2) + adjacent vertices: 0 4 vertex: 3 - out-edges: (3,0) (3,1) (3,4) - in-edges: (0,3) - adjacent vertices: 0 1 4 + out-edges: (3,0) (3,1) (3,4) + in-edges: (0,3) + adjacent vertices: 0 1 4 vertex: 4 - out-edges: (4,0) (4,1) - in-edges: (0,4) (2,4) (3,4) - adjacent vertices: 0 1 + out-edges: (4,0) (4,1) + in-edges: (0,4) (2,4) (3,4) + adjacent vertices: 0 1 diff --git a/example/r_c_shortest_paths_example.cpp b/example/r_c_shortest_paths_example.cpp index 518b90c62..2d759e73d 100644 --- a/example/r_c_shortest_paths_example.cpp +++ b/example/r_c_shortest_paths_example.cpp @@ -1,13 +1,13 @@ // Copyright Michael Drexl 2005, 2006. // Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at +// (See accompanying file LICENSE_1_0.txt or copy at // http://boost.org/LICENSE_1_0.txt) // Example use of the resource-constrained shortest paths algorithm. #include #ifdef BOOST_MSVC -# pragma warning(disable: 4267) +#pragma warning(disable : 4267) #endif #include @@ -19,99 +19,98 @@ using namespace boost; struct SPPRC_Example_Graph_Vert_Prop { - SPPRC_Example_Graph_Vert_Prop( int n = 0, int e = 0, int l = 0 ) - : num( n ), eat( e ), lat( l ) {} - int num; - // earliest arrival time - int eat; - // latest arrival time - int lat; + SPPRC_Example_Graph_Vert_Prop(int n = 0, int e = 0, int l = 0) + : num(n), eat(e), lat(l) + { + } + int num; + // earliest arrival time + int eat; + // latest arrival time + int lat; }; struct SPPRC_Example_Graph_Arc_Prop { - SPPRC_Example_Graph_Arc_Prop( int n = 0, int c = 0, int t = 0 ) - : num( n ), cost( c ), time( t ) {} - int num; - // traversal cost - int cost; - // traversal time - int time; + SPPRC_Example_Graph_Arc_Prop(int n = 0, int c = 0, int t = 0) + : num(n), cost(c), time(t) + { + } + int num; + // traversal cost + int cost; + // traversal time + int time; }; -typedef adjacency_list - SPPRC_Example_Graph; +typedef adjacency_list< vecS, vecS, directedS, SPPRC_Example_Graph_Vert_Prop, + SPPRC_Example_Graph_Arc_Prop > + SPPRC_Example_Graph; // data structures for spp without resource constraints: // ResourceContainer model struct spp_no_rc_res_cont { - spp_no_rc_res_cont( int c = 0 ) : cost( c ) {}; - spp_no_rc_res_cont& operator=( const spp_no_rc_res_cont& other ) - { - if( this == &other ) - return *this; - this->~spp_no_rc_res_cont(); - new( this ) spp_no_rc_res_cont( other ); - return *this; - } - int cost; + spp_no_rc_res_cont(int c = 0) : cost(c) {}; + spp_no_rc_res_cont& operator=(const spp_no_rc_res_cont& other) + { + if (this == &other) + return *this; + this->~spp_no_rc_res_cont(); + new (this) spp_no_rc_res_cont(other); + return *this; + } + int cost; }; -bool operator==( const spp_no_rc_res_cont& res_cont_1, - const spp_no_rc_res_cont& res_cont_2 ) +bool operator==( + const spp_no_rc_res_cont& res_cont_1, const spp_no_rc_res_cont& res_cont_2) { - return ( res_cont_1.cost == res_cont_2.cost ); + return (res_cont_1.cost == res_cont_2.cost); } -bool operator<( const spp_no_rc_res_cont& res_cont_1, - const spp_no_rc_res_cont& res_cont_2 ) +bool operator<( + const spp_no_rc_res_cont& res_cont_1, const spp_no_rc_res_cont& res_cont_2) { - return ( res_cont_1.cost < res_cont_2.cost ); + return (res_cont_1.cost < res_cont_2.cost); } // ResourceExtensionFunction model class ref_no_res_cont { public: - inline bool operator()( const SPPRC_Example_Graph& g, - spp_no_rc_res_cont& new_cont, - const spp_no_rc_res_cont& old_cont, - graph_traits - ::edge_descriptor ed ) const - { - new_cont.cost = old_cont.cost + g[ed].cost; - return true; - } + inline bool operator()(const SPPRC_Example_Graph& g, + spp_no_rc_res_cont& new_cont, const spp_no_rc_res_cont& old_cont, + graph_traits< SPPRC_Example_Graph >::edge_descriptor ed) const + { + new_cont.cost = old_cont.cost + g[ed].cost; + return true; + } }; // DominanceFunction model class dominance_no_res_cont { public: - inline bool operator()( const spp_no_rc_res_cont& res_cont_1, - const spp_no_rc_res_cont& res_cont_2 ) const - { - // must be "<=" here!!! - // must NOT be "<"!!! - return res_cont_1.cost <= res_cont_2.cost; - // this is not a contradiction to the documentation - // the documentation says: - // "A label $l_1$ dominates a label $l_2$ if and only if both are resident - // at the same vertex, and if, for each resource, the resource consumption - // of $l_1$ is less than or equal to the resource consumption of $l_2$, - // and if there is at least one resource where $l_1$ has a lower resource - // consumption than $l_2$." - // one can think of a new label with a resource consumption equal to that - // of an old label as being dominated by that old label, because the new - // one will have a higher number and is created at a later point in time, - // so one can implicitly use the number or the creation time as a resource - // for tie-breaking - } + inline bool operator()(const spp_no_rc_res_cont& res_cont_1, + const spp_no_rc_res_cont& res_cont_2) const + { + // must be "<=" here!!! + // must NOT be "<"!!! + return res_cont_1.cost <= res_cont_2.cost; + // this is not a contradiction to the documentation + // the documentation says: + // "A label $l_1$ dominates a label $l_2$ if and only if both are + // resident at the same vertex, and if, for each resource, the resource + // consumption of $l_1$ is less than or equal to the resource + // consumption of $l_2$, and if there is at least one resource where + // $l_1$ has a lower resource consumption than $l_2$." one can think of + // a new label with a resource consumption equal to that of an old label + // as being dominated by that old label, because the new one will have a + // higher number and is created at a later point in time, so one can + // implicitly use the number or the creation time as a resource for + // tie-breaking + } }; // end data structures for spp without resource constraints: @@ -119,235 +118,215 @@ class dominance_no_res_cont // ResourceContainer model struct spp_spptw_res_cont { - spp_spptw_res_cont( int c = 0, int t = 0 ) : cost( c ), time( t ) {} - spp_spptw_res_cont& operator=( const spp_spptw_res_cont& other ) - { - if( this == &other ) - return *this; - this->~spp_spptw_res_cont(); - new( this ) spp_spptw_res_cont( other ); - return *this; - } - int cost; - int time; + spp_spptw_res_cont(int c = 0, int t = 0) : cost(c), time(t) {} + spp_spptw_res_cont& operator=(const spp_spptw_res_cont& other) + { + if (this == &other) + return *this; + this->~spp_spptw_res_cont(); + new (this) spp_spptw_res_cont(other); + return *this; + } + int cost; + int time; }; -bool operator==( const spp_spptw_res_cont& res_cont_1, - const spp_spptw_res_cont& res_cont_2 ) +bool operator==( + const spp_spptw_res_cont& res_cont_1, const spp_spptw_res_cont& res_cont_2) { - return ( res_cont_1.cost == res_cont_2.cost - && res_cont_1.time == res_cont_2.time ); + return (res_cont_1.cost == res_cont_2.cost + && res_cont_1.time == res_cont_2.time); } -bool operator<( const spp_spptw_res_cont& res_cont_1, - const spp_spptw_res_cont& res_cont_2 ) +bool operator<( + const spp_spptw_res_cont& res_cont_1, const spp_spptw_res_cont& res_cont_2) { - if( res_cont_1.cost > res_cont_2.cost ) - return false; - if( res_cont_1.cost == res_cont_2.cost ) - return res_cont_1.time < res_cont_2.time; - return true; + if (res_cont_1.cost > res_cont_2.cost) + return false; + if (res_cont_1.cost == res_cont_2.cost) + return res_cont_1.time < res_cont_2.time; + return true; } // ResourceExtensionFunction model class ref_spptw { public: - inline bool operator()( const SPPRC_Example_Graph& g, - spp_spptw_res_cont& new_cont, - const spp_spptw_res_cont& old_cont, - graph_traits - ::edge_descriptor ed ) const - { - const SPPRC_Example_Graph_Arc_Prop& arc_prop = - get( edge_bundle, g )[ed]; - const SPPRC_Example_Graph_Vert_Prop& vert_prop = - get( vertex_bundle, g )[target( ed, g )]; - new_cont.cost = old_cont.cost + arc_prop.cost; - int& i_time = new_cont.time; - i_time = old_cont.time + arc_prop.time; - i_time < vert_prop.eat ? i_time = vert_prop.eat : 0; - return i_time <= vert_prop.lat ? true : false; - } + inline bool operator()(const SPPRC_Example_Graph& g, + spp_spptw_res_cont& new_cont, const spp_spptw_res_cont& old_cont, + graph_traits< SPPRC_Example_Graph >::edge_descriptor ed) const + { + const SPPRC_Example_Graph_Arc_Prop& arc_prop = get(edge_bundle, g)[ed]; + const SPPRC_Example_Graph_Vert_Prop& vert_prop + = get(vertex_bundle, g)[target(ed, g)]; + new_cont.cost = old_cont.cost + arc_prop.cost; + int& i_time = new_cont.time; + i_time = old_cont.time + arc_prop.time; + i_time < vert_prop.eat ? i_time = vert_prop.eat : 0; + return i_time <= vert_prop.lat ? true : false; + } }; // DominanceFunction model class dominance_spptw { public: - inline bool operator()( const spp_spptw_res_cont& res_cont_1, - const spp_spptw_res_cont& res_cont_2 ) const - { - // must be "<=" here!!! - // must NOT be "<"!!! - return res_cont_1.cost <= res_cont_2.cost - && res_cont_1.time <= res_cont_2.time; - // this is not a contradiction to the documentation - // the documentation says: - // "A label $l_1$ dominates a label $l_2$ if and only if both are resident - // at the same vertex, and if, for each resource, the resource consumption - // of $l_1$ is less than or equal to the resource consumption of $l_2$, - // and if there is at least one resource where $l_1$ has a lower resource - // consumption than $l_2$." - // one can think of a new label with a resource consumption equal to that - // of an old label as being dominated by that old label, because the new - // one will have a higher number and is created at a later point in time, - // so one can implicitly use the number or the creation time as a resource - // for tie-breaking - } + inline bool operator()(const spp_spptw_res_cont& res_cont_1, + const spp_spptw_res_cont& res_cont_2) const + { + // must be "<=" here!!! + // must NOT be "<"!!! + return res_cont_1.cost <= res_cont_2.cost + && res_cont_1.time <= res_cont_2.time; + // this is not a contradiction to the documentation + // the documentation says: + // "A label $l_1$ dominates a label $l_2$ if and only if both are + // resident at the same vertex, and if, for each resource, the resource + // consumption of $l_1$ is less than or equal to the resource + // consumption of $l_2$, and if there is at least one resource where + // $l_1$ has a lower resource consumption than $l_2$." one can think of + // a new label with a resource consumption equal to that of an old label + // as being dominated by that old label, because the new one will have a + // higher number and is created at a later point in time, so one can + // implicitly use the number or the creation time as a resource for + // tie-breaking + } }; // end data structures for shortest path problem with time windows (spptw) -// example graph structure and cost from +// example graph structure and cost from // http://www.boost.org/libs/graph/example/dijkstra-example.cpp -enum nodes { A, B, C, D, E }; +enum nodes +{ + A, + B, + C, + D, + E +}; char name[] = "ABCDE"; int main() { - SPPRC_Example_Graph g; - - add_vertex( SPPRC_Example_Graph_Vert_Prop( A, 0, 0 ), g ); - add_vertex( SPPRC_Example_Graph_Vert_Prop( B, 5, 20 ), g ); - add_vertex( SPPRC_Example_Graph_Vert_Prop( C, 6, 10 ), g ); - add_vertex( SPPRC_Example_Graph_Vert_Prop( D, 3, 12 ), g ); - add_vertex( SPPRC_Example_Graph_Vert_Prop( E, 0, 100 ), g ); - - add_edge( A, C, SPPRC_Example_Graph_Arc_Prop( 0, 1, 5 ), g ); - add_edge( B, B, SPPRC_Example_Graph_Arc_Prop( 1, 2, 5 ), g ); - add_edge( B, D, SPPRC_Example_Graph_Arc_Prop( 2, 1, 2 ), g ); - add_edge( B, E, SPPRC_Example_Graph_Arc_Prop( 3, 2, 7 ), g ); - add_edge( C, B, SPPRC_Example_Graph_Arc_Prop( 4, 7, 3 ), g ); - add_edge( C, D, SPPRC_Example_Graph_Arc_Prop( 5, 3, 8 ), g ); - add_edge( D, E, SPPRC_Example_Graph_Arc_Prop( 6, 1, 3 ), g ); - add_edge( E, A, SPPRC_Example_Graph_Arc_Prop( 7, 1, 5 ), g ); - add_edge( E, B, SPPRC_Example_Graph_Arc_Prop( 8, 1, 4 ), g ); - - - // the unique shortest path from A to E in the dijkstra-example.cpp is - // A -> C -> D -> E - // its length is 5 - // the following code also yields this result - - // with the above time windows, this path is infeasible - // now, there are two shortest paths that are also feasible with respect to - // the vertex time windows: - // A -> C -> B -> D -> E and - // A -> C -> B -> E - // however, the latter has a longer total travel time and is therefore not - // pareto-optimal, i.e., it is dominated by the former path - // therefore, the code below returns only the former path - - // spp without resource constraints - graph_traits::vertex_descriptor s = A; - graph_traits::vertex_descriptor t = E; - - std::vector - ::edge_descriptor> > + SPPRC_Example_Graph g; + + add_vertex(SPPRC_Example_Graph_Vert_Prop(A, 0, 0), g); + add_vertex(SPPRC_Example_Graph_Vert_Prop(B, 5, 20), g); + add_vertex(SPPRC_Example_Graph_Vert_Prop(C, 6, 10), g); + add_vertex(SPPRC_Example_Graph_Vert_Prop(D, 3, 12), g); + add_vertex(SPPRC_Example_Graph_Vert_Prop(E, 0, 100), g); + + add_edge(A, C, SPPRC_Example_Graph_Arc_Prop(0, 1, 5), g); + add_edge(B, B, SPPRC_Example_Graph_Arc_Prop(1, 2, 5), g); + add_edge(B, D, SPPRC_Example_Graph_Arc_Prop(2, 1, 2), g); + add_edge(B, E, SPPRC_Example_Graph_Arc_Prop(3, 2, 7), g); + add_edge(C, B, SPPRC_Example_Graph_Arc_Prop(4, 7, 3), g); + add_edge(C, D, SPPRC_Example_Graph_Arc_Prop(5, 3, 8), g); + add_edge(D, E, SPPRC_Example_Graph_Arc_Prop(6, 1, 3), g); + add_edge(E, A, SPPRC_Example_Graph_Arc_Prop(7, 1, 5), g); + add_edge(E, B, SPPRC_Example_Graph_Arc_Prop(8, 1, 4), g); + + // the unique shortest path from A to E in the dijkstra-example.cpp is + // A -> C -> D -> E + // its length is 5 + // the following code also yields this result + + // with the above time windows, this path is infeasible + // now, there are two shortest paths that are also feasible with respect to + // the vertex time windows: + // A -> C -> B -> D -> E and + // A -> C -> B -> E + // however, the latter has a longer total travel time and is therefore not + // pareto-optimal, i.e., it is dominated by the former path + // therefore, the code below returns only the former path + + // spp without resource constraints + graph_traits< SPPRC_Example_Graph >::vertex_descriptor s = A; + graph_traits< SPPRC_Example_Graph >::vertex_descriptor t = E; + + std::vector< + std::vector< graph_traits< SPPRC_Example_Graph >::edge_descriptor > > opt_solutions; - std::vector pareto_opt_rcs_no_rc; - - r_c_shortest_paths - ( g, - get( &SPPRC_Example_Graph_Vert_Prop::num, g ), - get( &SPPRC_Example_Graph_Arc_Prop::num, g ), - s, - t, - opt_solutions, - pareto_opt_rcs_no_rc, - spp_no_rc_res_cont( 0 ), - ref_no_res_cont(), - dominance_no_res_cont(), - std::allocator - >(), - default_r_c_shortest_paths_visitor() ); - - std::cout << "SPP without resource constraints:" << std::endl; - std::cout << "Number of optimal solutions: "; - std::cout << static_cast( opt_solutions.size() ) << std::endl; - for( int i = 0; i < static_cast( opt_solutions.size() ); ++i ) - { - std::cout << "The " << i << "th shortest path from A to E is: "; + std::vector< spp_no_rc_res_cont > pareto_opt_rcs_no_rc; + + r_c_shortest_paths(g, get(&SPPRC_Example_Graph_Vert_Prop::num, g), + get(&SPPRC_Example_Graph_Arc_Prop::num, g), s, t, opt_solutions, + pareto_opt_rcs_no_rc, spp_no_rc_res_cont(0), ref_no_res_cont(), + dominance_no_res_cont(), + std::allocator< r_c_shortest_paths_label< SPPRC_Example_Graph, + spp_no_rc_res_cont > >(), + default_r_c_shortest_paths_visitor()); + + std::cout << "SPP without resource constraints:" << std::endl; + std::cout << "Number of optimal solutions: "; + std::cout << static_cast< int >(opt_solutions.size()) << std::endl; + for (int i = 0; i < static_cast< int >(opt_solutions.size()); ++i) + { + std::cout << "The " << i << "th shortest path from A to E is: "; + std::cout << std::endl; + for (int j = static_cast< int >(opt_solutions[i].size()) - 1; j >= 0; + --j) + std::cout << name[source(opt_solutions[i][j], g)] << std::endl; + std::cout << "E" << std::endl; + std::cout << "Length: " << pareto_opt_rcs_no_rc[i].cost << std::endl; + } std::cout << std::endl; - for( int j = static_cast( opt_solutions[i].size() ) - 1; j >= 0; --j ) - std::cout << name[source( opt_solutions[i][j], g )] << std::endl; - std::cout << "E" << std::endl; - std::cout << "Length: " << pareto_opt_rcs_no_rc[i].cost << std::endl; - } - std::cout << std::endl; - - // spptw - std::vector - ::edge_descriptor> > + + // spptw + std::vector< + std::vector< graph_traits< SPPRC_Example_Graph >::edge_descriptor > > opt_solutions_spptw; - std::vector pareto_opt_rcs_spptw; - - r_c_shortest_paths - ( g, - get( &SPPRC_Example_Graph_Vert_Prop::num, g ), - get( &SPPRC_Example_Graph_Arc_Prop::num, g ), - s, - t, - opt_solutions_spptw, - pareto_opt_rcs_spptw, - spp_spptw_res_cont( 0, 0 ), - ref_spptw(), - dominance_spptw(), - std::allocator - >(), - default_r_c_shortest_paths_visitor() ); - - std::cout << "SPP with time windows:" << std::endl; - std::cout << "Number of optimal solutions: "; - std::cout << static_cast( opt_solutions.size() ) << std::endl; - for( int i = 0; i < static_cast( opt_solutions.size() ); ++i ) - { - std::cout << "The " << i << "th shortest path from A to E is: "; + std::vector< spp_spptw_res_cont > pareto_opt_rcs_spptw; + + r_c_shortest_paths(g, get(&SPPRC_Example_Graph_Vert_Prop::num, g), + get(&SPPRC_Example_Graph_Arc_Prop::num, g), s, t, opt_solutions_spptw, + pareto_opt_rcs_spptw, spp_spptw_res_cont(0, 0), ref_spptw(), + dominance_spptw(), + std::allocator< r_c_shortest_paths_label< SPPRC_Example_Graph, + spp_spptw_res_cont > >(), + default_r_c_shortest_paths_visitor()); + + std::cout << "SPP with time windows:" << std::endl; + std::cout << "Number of optimal solutions: "; + std::cout << static_cast< int >(opt_solutions.size()) << std::endl; + for (int i = 0; i < static_cast< int >(opt_solutions.size()); ++i) + { + std::cout << "The " << i << "th shortest path from A to E is: "; + std::cout << std::endl; + for (int j = static_cast< int >(opt_solutions_spptw[i].size()) - 1; + j >= 0; --j) + std::cout << name[source(opt_solutions_spptw[i][j], g)] + << std::endl; + std::cout << "E" << std::endl; + std::cout << "Length: " << pareto_opt_rcs_spptw[i].cost << std::endl; + std::cout << "Time: " << pareto_opt_rcs_spptw[i].time << std::endl; + } + + // utility function check_r_c_path example std::cout << std::endl; - for( int j = static_cast( opt_solutions_spptw[i].size() ) - 1; - j >= 0; - --j ) - std::cout << name[source( opt_solutions_spptw[i][j], g )] << std::endl; - std::cout << "E" << std::endl; - std::cout << "Length: " << pareto_opt_rcs_spptw[i].cost << std::endl; - std::cout << "Time: " << pareto_opt_rcs_spptw[i].time << std::endl; - } - - // utility function check_r_c_path example - std::cout << std::endl; - bool b_is_a_path_at_all = false; - bool b_feasible = false; - bool b_correctly_extended = false; - spp_spptw_res_cont actual_final_resource_levels( 0, 0 ); - graph_traits::edge_descriptor ed_last_extended_arc; - check_r_c_path( g, - opt_solutions_spptw[0], - spp_spptw_res_cont( 0, 0 ), - true, - pareto_opt_rcs_spptw[0], - actual_final_resource_levels, - ref_spptw(), - b_is_a_path_at_all, - b_feasible, - b_correctly_extended, - ed_last_extended_arc ); - if( !b_is_a_path_at_all ) - std::cout << "Not a path." << std::endl; - if( !b_feasible ) - std::cout << "Not a feasible path." << std::endl; - if( !b_correctly_extended ) - std::cout << "Not correctly extended." << std::endl; - if( b_is_a_path_at_all && b_feasible && b_correctly_extended ) - { - std::cout << "Actual final resource levels:" << std::endl; - std::cout << "Length: " << actual_final_resource_levels.cost << std::endl; - std::cout << "Time: " << actual_final_resource_levels.time << std::endl; - std::cout << "OK." << std::endl; - } - - return 0; + bool b_is_a_path_at_all = false; + bool b_feasible = false; + bool b_correctly_extended = false; + spp_spptw_res_cont actual_final_resource_levels(0, 0); + graph_traits< SPPRC_Example_Graph >::edge_descriptor ed_last_extended_arc; + check_r_c_path(g, opt_solutions_spptw[0], spp_spptw_res_cont(0, 0), true, + pareto_opt_rcs_spptw[0], actual_final_resource_levels, ref_spptw(), + b_is_a_path_at_all, b_feasible, b_correctly_extended, + ed_last_extended_arc); + if (!b_is_a_path_at_all) + std::cout << "Not a path." << std::endl; + if (!b_feasible) + std::cout << "Not a feasible path." << std::endl; + if (!b_correctly_extended) + std::cout << "Not correctly extended." << std::endl; + if (b_is_a_path_at_all && b_feasible && b_correctly_extended) + { + std::cout << "Actual final resource levels:" << std::endl; + std::cout << "Length: " << actual_final_resource_levels.cost + << std::endl; + std::cout << "Time: " << actual_final_resource_levels.time << std::endl; + std::cout << "OK." << std::endl; + } + + return 0; } diff --git a/example/reachable-loop-head.cpp b/example/reachable-loop-head.cpp index eedd4b060..fcb90ff1e 100644 --- a/example/reachable-loop-head.cpp +++ b/example/reachable-loop-head.cpp @@ -1,5 +1,5 @@ //======================================================================= -// Copyright 2001 Jeremy G. Siek, Andrew Lumsdaine, Lie-Quan Lee, +// Copyright 2001 Jeremy G. Siek, Andrew Lumsdaine, Lie-Quan Lee, // // Distributed under the Boost Software License, Version 1.0. (See // accompanying file LICENSE_1_0.txt or copy at @@ -9,11 +9,10 @@ /* IMPORTANT!!! ~~~~~~~~~~~~ - This example uses interfaces that have been deprecated and removed from Boost.Grpah. - Someone needs to update it, as it does NOT compile. + This example uses interfaces that have been deprecated and removed from + Boost.Grpah. Someone needs to update it, as it does NOT compile. */ - #include #include #include @@ -22,81 +21,85 @@ #include #include -int -main(int argc, char *argv[]) +int main(int argc, char* argv[]) { - if (argc < 3) { - std::cerr << "usage: reachable-loop-head.exe " - << std::endl; - return -1; - } - using namespace boost; - GraphvizDigraph g; - read_graphviz(argv[1], g); - graph_traits < GraphvizDigraph >::vertex_descriptor loop_head = 1; - typedef color_traits < default_color_type > Color; + if (argc < 3) + { + std::cerr << "usage: reachable-loop-head.exe " + << std::endl; + return -1; + } + using namespace boost; + GraphvizDigraph g; + read_graphviz(argv[1], g); + graph_traits< GraphvizDigraph >::vertex_descriptor loop_head = 1; + typedef color_traits< default_color_type > Color; - std::vector < default_color_type > - reachable_from_head(num_vertices(g), Color::white()); - default_color_type c; - depth_first_visit(g, loop_head, default_dfs_visitor(), - make_iterator_property_map(reachable_from_head.begin(), - get(vertex_index, g), c)); + std::vector< default_color_type > reachable_from_head( + num_vertices(g), Color::white()); + default_color_type c; + depth_first_visit(g, loop_head, default_dfs_visitor(), + make_iterator_property_map( + reachable_from_head.begin(), get(vertex_index, g), c)); - property_map::type - vattr_map = get(vertex_attribute, g); + property_map< GraphvizDigraph, vertex_attribute_t >::type vattr_map + = get(vertex_attribute, g); - graph_traits < GraphvizDigraph >::vertex_iterator i, i_end; - for (boost::tie(i, i_end) = vertices(g); i != i_end; ++i) - if (reachable_from_head[*i] != Color::white()) { - vattr_map[*i]["color"] = "gray"; - vattr_map[*i]["style"] = "filled"; - } + graph_traits< GraphvizDigraph >::vertex_iterator i, i_end; + for (boost::tie(i, i_end) = vertices(g); i != i_end; ++i) + if (reachable_from_head[*i] != Color::white()) + { + vattr_map[*i]["color"] = "gray"; + vattr_map[*i]["style"] = "filled"; + } - std::ofstream loops_out(argv[2]); + std::ofstream loops_out(argv[2]); #if defined(BOOST_MSVC) && BOOST_MSVC <= 1300 - // VC++ has trouble with the get_property() functions - loops_out << "digraph G {\n" - << "size=\"3,3\"\n" - << "ratio=\"fill\"\n" - << "shape=\"box\"\n"; - graph_traits::vertex_iterator vi, vi_end; - for (boost::tie(vi, vi_end) = vertices(g); vi != vi_end; ++vi) { - loops_out << *vi << "["; - for (std::map::iterator ai = vattr_map[*vi].begin(); - ai != vattr_map[*vi].end(); ++ai) { - loops_out << ai->first << "=" << ai->second; - if (next(ai) != vattr_map[*vi].end()) - loops_out << ", "; + // VC++ has trouble with the get_property() functions + loops_out << "digraph G {\n" + << "size=\"3,3\"\n" + << "ratio=\"fill\"\n" + << "shape=\"box\"\n"; + graph_traits< GraphvizDigraph >::vertex_iterator vi, vi_end; + for (boost::tie(vi, vi_end) = vertices(g); vi != vi_end; ++vi) + { + loops_out << *vi << "["; + for (std::map< std::string, std::string >::iterator ai + = vattr_map[*vi].begin(); + ai != vattr_map[*vi].end(); ++ai) + { + loops_out << ai->first << "=" << ai->second; + if (next(ai) != vattr_map[*vi].end()) + loops_out << ", "; + } + loops_out << "]"; } - loops_out<< "]"; - } - property_map::type - eattr_map = get(edge_attribute, g); - graph_traits::edge_iterator ei, ei_end; - for (boost::tie(ei, ei_end) = edges(g); ei != ei_end; ++ei) { - loops_out << source(*ei, g) << " -> " << target(*ei, g) << "["; - std::map& attr_map = eattr_map[*ei]; - for (std::map::iterator eai = attr_map.begin(); - eai != attr_map.end(); ++eai) { - loops_out << eai->first << "=" << eai->second; - if (next(eai) != attr_map.end()) - loops_out << ", "; + property_map< GraphvizDigraph, edge_attribute_t >::type eattr_map + = get(edge_attribute, g); + graph_traits< GraphvizDigraph >::edge_iterator ei, ei_end; + for (boost::tie(ei, ei_end) = edges(g); ei != ei_end; ++ei) + { + loops_out << source(*ei, g) << " -> " << target(*ei, g) << "["; + std::map< std::string, std::string >& attr_map = eattr_map[*ei]; + for (std::map< std::string, std::string >::iterator eai + = attr_map.begin(); + eai != attr_map.end(); ++eai) + { + loops_out << eai->first << "=" << eai->second; + if (next(eai) != attr_map.end()) + loops_out << ", "; + } + loops_out << "]"; } - loops_out<< "]"; - } - loops_out << "}\n"; + loops_out << "}\n"; #else - get_property(g, graph_graph_attribute)["size"] = "3,3"; - get_property(g, graph_graph_attribute)["ratio"] = "fill"; - get_property(g, graph_vertex_attribute)["shape"] = "box"; + get_property(g, graph_graph_attribute)["size"] = "3,3"; + get_property(g, graph_graph_attribute)["ratio"] = "fill"; + get_property(g, graph_vertex_attribute)["shape"] = "box"; - write_graphviz(loops_out, g, - make_vertex_attributes_writer(g), - make_edge_attributes_writer(g), - make_graph_attributes_writer(g)); + write_graphviz(loops_out, g, make_vertex_attributes_writer(g), + make_edge_attributes_writer(g), make_graph_attributes_writer(g)); #endif - - return EXIT_SUCCESS; + return EXIT_SUCCESS; } diff --git a/example/reachable-loop-tail.cpp b/example/reachable-loop-tail.cpp index 5170d3b05..e3e50b0d9 100644 --- a/example/reachable-loop-tail.cpp +++ b/example/reachable-loop-tail.cpp @@ -1,5 +1,5 @@ //======================================================================= -// Copyright 2001 Jeremy G. Siek, Andrew Lumsdaine, Lie-Quan Lee, +// Copyright 2001 Jeremy G. Siek, Andrew Lumsdaine, Lie-Quan Lee, // // Distributed under the Boost Software License, Version 1.0. (See // accompanying file LICENSE_1_0.txt or copy at @@ -9,8 +9,8 @@ /* IMPORTANT!!! ~~~~~~~~~~~~ - This example uses interfaces that have been deprecated and removed from Boost.Grpah. - Someone needs to update it, as it does NOT compile. + This example uses interfaces that have been deprecated and removed from + Boost.Grpah. Someone needs to update it, as it does NOT compile. */ #include @@ -22,53 +22,55 @@ #include #include -int -main(int argc, char *argv[]) +int main(int argc, char* argv[]) { - if (argc < 3) { - std::cerr << "usage: reachable-loop-tail.exe " - << std::endl; - return -1; - } - using namespace boost; - GraphvizDigraph g_in; - read_graphviz(argv[1], g_in); + if (argc < 3) + { + std::cerr << "usage: reachable-loop-tail.exe " + << std::endl; + return -1; + } + using namespace boost; + GraphvizDigraph g_in; + read_graphviz(argv[1], g_in); - typedef adjacency_list < vecS, vecS, bidirectionalS, - GraphvizVertexProperty, - GraphvizEdgeProperty, GraphvizGraphProperty > Graph; - Graph g; - copy_graph(g_in, g); + typedef adjacency_list< vecS, vecS, bidirectionalS, GraphvizVertexProperty, + GraphvizEdgeProperty, GraphvizGraphProperty > + Graph; + Graph g; + copy_graph(g_in, g); - graph_traits < GraphvizDigraph >::vertex_descriptor loop_tail = 6; - typedef color_traits < default_color_type > Color; - default_color_type c; + graph_traits< GraphvizDigraph >::vertex_descriptor loop_tail = 6; + typedef color_traits< default_color_type > Color; + default_color_type c; - std::vector < default_color_type > reachable_to_tail(num_vertices(g)); - reverse_graph < Graph > reverse_g(g); - depth_first_visit(reverse_g, loop_tail, default_dfs_visitor(), - make_iterator_property_map(reachable_to_tail.begin(), - get(vertex_index, g), c)); + std::vector< default_color_type > reachable_to_tail(num_vertices(g)); + reverse_graph< Graph > reverse_g(g); + depth_first_visit(reverse_g, loop_tail, default_dfs_visitor(), + make_iterator_property_map( + reachable_to_tail.begin(), get(vertex_index, g), c)); - std::ofstream loops_out(argv[2]); - loops_out << "digraph G {\n" - << " graph [ratio=\"fill\",size=\"3,3\"];\n" - << " node [shape=\"box\"];\n" << " edge [style=\"bold\"];\n"; + std::ofstream loops_out(argv[2]); + loops_out << "digraph G {\n" + << " graph [ratio=\"fill\",size=\"3,3\"];\n" + << " node [shape=\"box\"];\n" + << " edge [style=\"bold\"];\n"; - property_map::type - vattr_map = get(vertex_attribute, g); - graph_traits < GraphvizDigraph >::vertex_iterator i, i_end; - for (boost::tie(i, i_end) = vertices(g_in); i != i_end; ++i) { - loops_out << *i << "[label=\"" << vattr_map[*i]["label"] - << "\""; - if (reachable_to_tail[*i] != Color::white()) { - loops_out << ", color=\"gray\", style=\"filled\""; + property_map< Graph, vertex_attribute_t >::type vattr_map + = get(vertex_attribute, g); + graph_traits< GraphvizDigraph >::vertex_iterator i, i_end; + for (boost::tie(i, i_end) = vertices(g_in); i != i_end; ++i) + { + loops_out << *i << "[label=\"" << vattr_map[*i]["label"] << "\""; + if (reachable_to_tail[*i] != Color::white()) + { + loops_out << ", color=\"gray\", style=\"filled\""; + } + loops_out << "]\n"; } - loops_out << "]\n"; - } - graph_traits < GraphvizDigraph >::edge_iterator e, e_end; - for (boost::tie(e, e_end) = edges(g_in); e != e_end; ++e) - loops_out << source(*e, g) << " -> " << target(*e, g) << ";\n"; - loops_out << "}\n"; - return EXIT_SUCCESS; + graph_traits< GraphvizDigraph >::edge_iterator e, e_end; + for (boost::tie(e, e_end) = edges(g_in); e != e_end; ++e) + loops_out << source(*e, g) << " -> " << target(*e, g) << ";\n"; + loops_out << "}\n"; + return EXIT_SUCCESS; } diff --git a/example/read_graphviz.cpp b/example/read_graphviz.cpp index 8750e9dcf..d3b395598 100644 --- a/example/read_graphviz.cpp +++ b/example/read_graphviz.cpp @@ -9,7 +9,6 @@ // Author: Ronald Garcia - #include #include #include @@ -18,44 +17,45 @@ using namespace boost; using namespace std; -int main() { - // Vertex properties - typedef property < vertex_name_t, std::string, - property < vertex_color_t, float > > vertex_p; - // Edge properties - typedef property < edge_weight_t, double > edge_p; - // Graph properties - typedef property < graph_name_t, std::string > graph_p; - // adjacency_list-based type - typedef adjacency_list < vecS, vecS, directedS, - vertex_p, edge_p, graph_p > graph_t; - - // Construct an empty graph and prepare the dynamic_property_maps. - graph_t graph(0); - dynamic_properties dp; - - property_map::type name = - get(vertex_name, graph); - dp.property("node_id",name); - - property_map::type mass = - get(vertex_color, graph); - dp.property("mass",mass); - - property_map::type weight = - get(edge_weight, graph); - dp.property("weight",weight); - - // Use ref_property_map to turn a graph property into a property map - boost::ref_property_map - gname(get_property(graph,graph_name)); - dp.property("name",gname); - - // Sample graph as an std::istream; - std::istringstream - gvgraph("digraph { graph [name=\"graphname\"] a c e [mass = 6.66] }"); - - bool status = read_graphviz(gvgraph,graph,dp,"node_id"); - - return status ? EXIT_SUCCESS : EXIT_FAILURE; +int main() +{ + // Vertex properties + typedef property< vertex_name_t, std::string, + property< vertex_color_t, float > > + vertex_p; + // Edge properties + typedef property< edge_weight_t, double > edge_p; + // Graph properties + typedef property< graph_name_t, std::string > graph_p; + // adjacency_list-based type + typedef adjacency_list< vecS, vecS, directedS, vertex_p, edge_p, graph_p > + graph_t; + + // Construct an empty graph and prepare the dynamic_property_maps. + graph_t graph(0); + dynamic_properties dp; + + property_map< graph_t, vertex_name_t >::type name = get(vertex_name, graph); + dp.property("node_id", name); + + property_map< graph_t, vertex_color_t >::type mass + = get(vertex_color, graph); + dp.property("mass", mass); + + property_map< graph_t, edge_weight_t >::type weight + = get(edge_weight, graph); + dp.property("weight", weight); + + // Use ref_property_map to turn a graph property into a property map + boost::ref_property_map< graph_t*, std::string > gname( + get_property(graph, graph_name)); + dp.property("name", gname); + + // Sample graph as an std::istream; + std::istringstream gvgraph( + "digraph { graph [name=\"graphname\"] a c e [mass = 6.66] }"); + + bool status = read_graphviz(gvgraph, graph, dp, "node_id"); + + return status ? EXIT_SUCCESS : EXIT_FAILURE; } diff --git a/example/read_write_dimacs-eg.cpp b/example/read_write_dimacs-eg.cpp index 50c3effba..d6435679f 100644 --- a/example/read_write_dimacs-eg.cpp +++ b/example/read_write_dimacs-eg.cpp @@ -39,88 +39,95 @@ #include #include - /************************************* -* -* example which reads in a max-flow problem from std::cin, augments all paths from -* source->NODE->sink and writes the graph back to std::cout -* -**************************************/ - -template -struct zero_edge_capacity{ - - zero_edge_capacity() { } - zero_edge_capacity(EdgeCapacityMap cap_map):m_cap_map(cap_map){}; - - template - bool operator() (const Edge& e) const { - return get(m_cap_map, e) == 0 ; - } - - EdgeCapacityMap m_cap_map; + * + * example which reads in a max-flow problem from std::cin, augments all paths + *from source->NODE->sink and writes the graph back to std::cout + * + **************************************/ + +template < typename EdgeCapacityMap > struct zero_edge_capacity +{ + + zero_edge_capacity() {} + zero_edge_capacity(EdgeCapacityMap cap_map) : m_cap_map(cap_map) {}; + + template < typename Edge > bool operator()(const Edge& e) const + { + return get(m_cap_map, e) == 0; + } + + EdgeCapacityMap m_cap_map; }; int main() { - using namespace boost; - typedef adjacency_list_traits < vecS, vecS, directedS > Traits; - typedef adjacency_list < vecS, vecS, directedS, - no_property, - property < edge_capacity_t, long, - property < edge_reverse_t, Traits::edge_descriptor > > > Graph; - - typedef graph_traits::out_edge_iterator out_edge_iterator; - typedef graph_traits::edge_descriptor edge_descriptor; - typedef graph_traits::vertex_descriptor vertex_descriptor; - - Graph g; - - typedef property_map < Graph, edge_capacity_t >::type tCapMap; - typedef tCapMap::value_type tCapMapValue; - - typedef property_map < Graph, edge_reverse_t >::type tRevEdgeMap; - - tCapMap capacity = get(edge_capacity, g); - tRevEdgeMap rev = get(edge_reverse, g); - - vertex_descriptor s, t; - /*reading the graph from stdin*/ - read_dimacs_max_flow(g, capacity, rev, s, t, std::cin); - - /*process graph*/ - tCapMapValue augmented_flow = 0; - - //we take the source node and check for each outgoing edge e which has a target(p) if we can augment that path - out_edge_iterator oei,oe_end; - for(boost::tie(oei, oe_end) = out_edges(s, g); oei != oe_end; ++oei){ - edge_descriptor from_source = *oei; - vertex_descriptor v = target(from_source, g); - edge_descriptor to_sink; - bool is_there; - boost::tie(to_sink, is_there) = edge(v, t, g); - if( is_there ){ - if( get(capacity, to_sink) > get(capacity, from_source) ){ - tCapMapValue to_augment = get(capacity, from_source); - capacity[from_source] = 0; - capacity[to_sink] -= to_augment; - augmented_flow += to_augment; - }else{ - tCapMapValue to_augment = get(capacity, to_sink); - capacity[to_sink] = 0; - capacity[from_source] -= to_augment; - augmented_flow += to_augment; - } + using namespace boost; + typedef adjacency_list_traits< vecS, vecS, directedS > Traits; + typedef adjacency_list< vecS, vecS, directedS, no_property, + property< edge_capacity_t, long, + property< edge_reverse_t, Traits::edge_descriptor > > > + Graph; + + typedef graph_traits< Graph >::out_edge_iterator out_edge_iterator; + typedef graph_traits< Graph >::edge_descriptor edge_descriptor; + typedef graph_traits< Graph >::vertex_descriptor vertex_descriptor; + + Graph g; + + typedef property_map< Graph, edge_capacity_t >::type tCapMap; + typedef tCapMap::value_type tCapMapValue; + + typedef property_map< Graph, edge_reverse_t >::type tRevEdgeMap; + + tCapMap capacity = get(edge_capacity, g); + tRevEdgeMap rev = get(edge_reverse, g); + + vertex_descriptor s, t; + /*reading the graph from stdin*/ + read_dimacs_max_flow(g, capacity, rev, s, t, std::cin); + + /*process graph*/ + tCapMapValue augmented_flow = 0; + + // we take the source node and check for each outgoing edge e which has a + // target(p) if we can augment that path + out_edge_iterator oei, oe_end; + for (boost::tie(oei, oe_end) = out_edges(s, g); oei != oe_end; ++oei) + { + edge_descriptor from_source = *oei; + vertex_descriptor v = target(from_source, g); + edge_descriptor to_sink; + bool is_there; + boost::tie(to_sink, is_there) = edge(v, t, g); + if (is_there) + { + if (get(capacity, to_sink) > get(capacity, from_source)) + { + tCapMapValue to_augment = get(capacity, from_source); + capacity[from_source] = 0; + capacity[to_sink] -= to_augment; + augmented_flow += to_augment; + } + else + { + tCapMapValue to_augment = get(capacity, to_sink); + capacity[to_sink] = 0; + capacity[from_source] -= to_augment; + augmented_flow += to_augment; + } + } } - } - - //remove edges with zero capacity (most of them are the reverse edges) - zero_edge_capacity filter(capacity); - remove_edge_if(filter, g); - - /*write the graph back to stdout */ - write_dimacs_max_flow(g, capacity, identity_property_map(),s, t, std::cout); - //print flow we augmented to std::cerr - std::cerr << "removed " << augmented_flow << " from SOURCE->NODE->SINK connects" < filter(capacity); + remove_edge_if(filter, g); + + /*write the graph back to stdout */ + write_dimacs_max_flow( + g, capacity, identity_property_map(), s, t, std::cout); + // print flow we augmented to std::cerr + std::cerr << "removed " << augmented_flow + << " from SOURCE->NODE->SINK connects" << std::endl; + return 0; } diff --git a/example/remove_edge_if_bidir.cpp b/example/remove_edge_if_bidir.cpp index 9b7ef69fa..a58df802d 100644 --- a/example/remove_edge_if_bidir.cpp +++ b/example/remove_edge_if_bidir.cpp @@ -16,87 +16,86 @@ Sample output: original graph: - 0 --> 3 2 3 - 1 --> 3 - 2 --> 0 - 3 --> 2 - 1(0,3) 2(0,2) 3(0,3) 4(1,3) 5(2,0) 6(3,2) + 0 --> 3 2 3 + 1 --> 3 + 2 --> 0 + 3 --> 2 + 1(0,3) 2(0,2) 3(0,3) 4(1,3) 5(2,0) 6(3,2) removing edges connecting 0 to 3 - 0 --> 2 - 1 --> 3 - 2 --> 0 - 3 --> 2 - 2(0,2) 4(1,3) 5(2,0) 6(3,2) + 0 --> 2 + 1 --> 3 + 2 --> 0 + 3 --> 2 + 2(0,2) 4(1,3) 5(2,0) 6(3,2) removing edges with weight greater than 3 - 0 --> 2 - 1 --> - 2 --> - 3 --> - 2(0,2) + 0 --> 2 + 1 --> + 2 --> + 3 --> + 2(0,2) */ using namespace boost; -typedef adjacency_list > Graph; +typedef adjacency_list< vecS, vecS, bidirectionalS, no_property, + property< edge_weight_t, int > > + Graph; -struct has_weight_greater_than { - has_weight_greater_than(int w_, Graph& g_) : w(w_), g(g_) { } - bool operator()(graph_traits::edge_descriptor e) { +struct has_weight_greater_than +{ + has_weight_greater_than(int w_, Graph& g_) : w(w_), g(g_) {} + bool operator()(graph_traits< Graph >::edge_descriptor e) + { #if defined(BOOST_MSVC) && BOOST_MSVC <= 1300 - property_map::type weight = get(edge_weight, g); - return get(weight, e) > w; + property_map< Graph, edge_weight_t >::type weight = get(edge_weight, g); + return get(weight, e) > w; #else - // This version of get() breaks VC++ - return get(edge_weight, g, e) > w; + // This version of get() breaks VC++ + return get(edge_weight, g, e) > w; #endif - } - int w; - Graph& g; + } + int w; + Graph& g; }; -int -main() +int main() { - typedef std::pair Edge; - Edge edge_array[6] = { Edge(0,3), Edge(0,2), Edge(0, 3), - Edge(1,3), - Edge(2, 0), - Edge(3, 2) }; + typedef std::pair< std::size_t, std::size_t > Edge; + Edge edge_array[6] = { Edge(0, 3), Edge(0, 2), Edge(0, 3), Edge(1, 3), + Edge(2, 0), Edge(3, 2) }; #if defined(BOOST_MSVC) && BOOST_MSVC <= 1300 - Graph g(4); - for (std::size_t j = 0; j < 6; ++j) - add_edge(edge_array[j].first, edge_array[j].second, g); + Graph g(4); + for (std::size_t j = 0; j < 6; ++j) + add_edge(edge_array[j].first, edge_array[j].second, g); #else - Graph g(edge_array, edge_array + 6, 4); + Graph g(edge_array, edge_array + 6, 4); #endif - property_map::type - weight = get(edge_weight, g); - - int w = 0; - graph_traits::edge_iterator ei, ei_end; - for (boost::tie(ei, ei_end) = edges(g); ei != ei_end; ++ei) - weight[*ei] = ++w; - - property_map::type indexmap = get(vertex_index, g); - - std::cout << "original graph:" << std::endl; - print_graph(g, indexmap); - print_edges2(g, indexmap, weight); - std::cout << std::endl; - - std::cout << "removing edges connecting 0 to 3" << std::endl; - remove_out_edge_if(vertex(0,g), incident_to(vertex(3,g), g), g); - print_graph(g, indexmap); - print_edges2(g, indexmap, weight); - - std::cout << "removing edges with weight greater than 3" << std::endl; - remove_edge_if(has_weight_greater_than(3, g), g); - print_graph(g, indexmap); - print_edges2(g, indexmap, weight); - return 0; + property_map< Graph, edge_weight_t >::type weight = get(edge_weight, g); + + int w = 0; + graph_traits< Graph >::edge_iterator ei, ei_end; + for (boost::tie(ei, ei_end) = edges(g); ei != ei_end; ++ei) + weight[*ei] = ++w; + + property_map< Graph, vertex_index_t >::type indexmap = get(vertex_index, g); + + std::cout << "original graph:" << std::endl; + print_graph(g, indexmap); + print_edges2(g, indexmap, weight); + std::cout << std::endl; + + std::cout << "removing edges connecting 0 to 3" << std::endl; + remove_out_edge_if(vertex(0, g), incident_to(vertex(3, g), g), g); + print_graph(g, indexmap); + print_edges2(g, indexmap, weight); + + std::cout << "removing edges with weight greater than 3" << std::endl; + remove_edge_if(has_weight_greater_than(3, g), g); + print_graph(g, indexmap); + print_edges2(g, indexmap, weight); + return 0; } diff --git a/example/remove_edge_if_bidir.expected b/example/remove_edge_if_bidir.expected index 62bf6ee03..e6fe9ac3c 100644 --- a/example/remove_edge_if_bidir.expected +++ b/example/remove_edge_if_bidir.expected @@ -1,19 +1,19 @@ original graph: -0 --> 3 2 3 -1 --> 3 -2 --> 0 -3 --> 2 -1(0,3) 2(0,2) 3(0,3) 4(1,3) 5(2,0) 6(3,2) +0 --> 3 2 3 +1 --> 3 +2 --> 0 +3 --> 2 +1(0,3) 2(0,2) 3(0,3) 4(1,3) 5(2,0) 6(3,2) removing edges connecting 0 to 3 -0 --> 2 -1 --> 3 -2 --> 0 -3 --> 2 -2(0,2) 4(1,3) 5(2,0) 6(3,2) +0 --> 2 +1 --> 3 +2 --> 0 +3 --> 2 +2(0,2) 4(1,3) 5(2,0) 6(3,2) removing edges with weight greater than 3 -0 --> 2 -1 --> -2 --> -3 --> -2(0,2) +0 --> 2 +1 --> +2 --> +3 --> +2(0,2) diff --git a/example/remove_edge_if_dir.cpp b/example/remove_edge_if_dir.cpp index 6b6f76edb..825e409bd 100644 --- a/example/remove_edge_if_dir.cpp +++ b/example/remove_edge_if_dir.cpp @@ -16,58 +16,54 @@ Sample output: original graph: - 0 --> 3 2 3 - 1 --> 3 - 2 --> 0 - 3 --> 2 + 0 --> 3 2 3 + 1 --> 3 + 2 --> 0 + 3 --> 2 removing edges (0,3) - 0 --> 2 - 1 --> 3 - 2 --> 0 - 3 --> 2 + 0 --> 2 + 1 --> 3 + 2 --> 0 + 3 --> 2 removing edge (0,2) and (3, 2) - 0 --> - 1 --> 3 - 2 --> 0 - 3 --> - + 0 --> + 1 --> 3 + 2 --> 0 + 3 --> + */ using namespace boost; -typedef adjacency_list Graph; - +typedef adjacency_list< vecS, vecS, directedS > Graph; -int -main() +int main() { - typedef std::pair Edge; - Edge edges[6] = { Edge(0,3), Edge(0,2), Edge(0, 3), - Edge(1,3), - Edge(2, 0), - Edge(3, 2) }; + typedef std::pair< std::size_t, std::size_t > Edge; + Edge edges[6] = { Edge(0, 3), Edge(0, 2), Edge(0, 3), Edge(1, 3), + Edge(2, 0), Edge(3, 2) }; #if defined(BOOST_MSVC) && BOOST_MSVC <= 1300 - // VC++ can't handle iterator constructor - Graph g(4); - for (std::size_t j = 0; j < 6; ++j) - add_edge(edges[j].first, edges[j].second, g); + // VC++ can't handle iterator constructor + Graph g(4); + for (std::size_t j = 0; j < 6; ++j) + add_edge(edges[j].first, edges[j].second, g); #else - Graph g(edges, edges + 6, 4); + Graph g(edges, edges + 6, 4); #endif - std::cout << "original graph:" << std::endl; - print_graph(g, get(vertex_index, g)); - std::cout << std::endl; + std::cout << "original graph:" << std::endl; + print_graph(g, get(vertex_index, g)); + std::cout << std::endl; - std::cout << "removing edges (0,3)" << std::endl; - remove_out_edge_if(vertex(0,g), incident_to(vertex(3,g), g), g); - print_graph(g, get(vertex_index, g)); + std::cout << "removing edges (0,3)" << std::endl; + remove_out_edge_if(vertex(0, g), incident_to(vertex(3, g), g), g); + print_graph(g, get(vertex_index, g)); - std::cout << "removing edge (0,2) and (3, 2)" << std::endl; - remove_edge_if(incident_to(vertex(2,g), g), g); - print_graph(g, get(vertex_index, g)); + std::cout << "removing edge (0,2) and (3, 2)" << std::endl; + remove_edge_if(incident_to(vertex(2, g), g), g); + print_graph(g, get(vertex_index, g)); - return 0; + return 0; } diff --git a/example/remove_edge_if_dir.expected b/example/remove_edge_if_dir.expected index 875e48548..214c49fda 100644 --- a/example/remove_edge_if_dir.expected +++ b/example/remove_edge_if_dir.expected @@ -1,16 +1,16 @@ original graph: -0 --> 3 2 3 -1 --> 3 -2 --> 0 -3 --> 2 +0 --> 3 2 3 +1 --> 3 +2 --> 0 +3 --> 2 removing edges (0,3) -0 --> 2 -1 --> 3 -2 --> 0 -3 --> 2 +0 --> 2 +1 --> 3 +2 --> 0 +3 --> 2 removing edge (0,2) and (3, 2) -0 --> -1 --> 3 -2 --> 0 -3 --> +0 --> +1 --> 3 +2 --> 0 +3 --> diff --git a/example/remove_edge_if_undir.cpp b/example/remove_edge_if_undir.cpp index 3fc5b5711..3f4b62e86 100644 --- a/example/remove_edge_if_undir.cpp +++ b/example/remove_edge_if_undir.cpp @@ -18,83 +18,82 @@ using namespace boost; Sample output: original graph: - 0 <--> 3 3 2 - 1 <--> 3 - 2 <--> 0 3 - 3 <--> 0 0 1 2 - 1(0,3) 2(0,3) 3(1,3) 4(2,0) 5(3,2) + 0 <--> 3 3 2 + 1 <--> 3 + 2 <--> 0 3 + 3 <--> 0 0 1 2 + 1(0,3) 2(0,3) 3(1,3) 4(2,0) 5(3,2) removing edges connecting 0 and 3 - 0 <--> 2 - 1 <--> 3 - 2 <--> 0 3 - 3 <--> 1 2 - 3(1,3) 4(2,0) 5(3,2) + 0 <--> 2 + 1 <--> 3 + 2 <--> 0 3 + 3 <--> 1 2 + 3(1,3) 4(2,0) 5(3,2) removing edges with weight greater than 3 - 0 <--> - 1 <--> 3 - 2 <--> - 3 <--> 1 - 3(1,3) - + 0 <--> + 1 <--> 3 + 2 <--> + 3 <--> 1 + 3(1,3) + */ -typedef adjacency_list > Graph; +typedef adjacency_list< vecS, vecS, undirectedS, no_property, + property< edge_weight_t, int > > + Graph; -struct has_weight_greater_than { - has_weight_greater_than(int w_, Graph& g_) : w(w_), g(g_) { } - bool operator()(graph_traits::edge_descriptor e) { +struct has_weight_greater_than +{ + has_weight_greater_than(int w_, Graph& g_) : w(w_), g(g_) {} + bool operator()(graph_traits< Graph >::edge_descriptor e) + { #if defined(BOOST_MSVC) && BOOST_MSVC <= 1300 - property_map::type weight = get(edge_weight, g); - return get(weight, e) > w; + property_map< Graph, edge_weight_t >::type weight = get(edge_weight, g); + return get(weight, e) > w; #else - // This version of get breaks VC++ - return get(edge_weight, g, e) > w; + // This version of get breaks VC++ + return get(edge_weight, g, e) > w; #endif - } - int w; - Graph& g; + } + int w; + Graph& g; }; -int -main() +int main() { - typedef std::pair Edge; - Edge edge_array[5] = { Edge(0, 3), Edge(0, 3), - Edge(1, 3), - Edge(2, 0), - Edge(3, 2) }; + typedef std::pair< std::size_t, std::size_t > Edge; + Edge edge_array[5] + = { Edge(0, 3), Edge(0, 3), Edge(1, 3), Edge(2, 0), Edge(3, 2) }; #if defined(BOOST_MSVC) && BOOST_MSVC <= 1300 - Graph g(4); - for (std::size_t j = 0; j < 5; ++j) - add_edge(edge_array[j].first, edge_array[j].second, g); + Graph g(4); + for (std::size_t j = 0; j < 5; ++j) + add_edge(edge_array[j].first, edge_array[j].second, g); #else - Graph g(edge_array, edge_array + 5, 4); + Graph g(edge_array, edge_array + 5, 4); #endif - property_map::type - weight = get(edge_weight, g); + property_map< Graph, edge_weight_t >::type weight = get(edge_weight, g); - int w = 0; - graph_traits::edge_iterator ei, ei_end; - for (boost::tie(ei, ei_end) = edges(g); ei != ei_end; ++ei) - weight[*ei] = ++w; + int w = 0; + graph_traits< Graph >::edge_iterator ei, ei_end; + for (boost::tie(ei, ei_end) = edges(g); ei != ei_end; ++ei) + weight[*ei] = ++w; - std::cout << "original graph:" << std::endl; - print_graph(g, get(vertex_index, g)); - print_edges2(g, get(vertex_index, g), get(edge_weight, g)); - std::cout << std::endl; + std::cout << "original graph:" << std::endl; + print_graph(g, get(vertex_index, g)); + print_edges2(g, get(vertex_index, g), get(edge_weight, g)); + std::cout << std::endl; - std::cout << "removing edges connecting 0 and 3" << std::endl; - remove_out_edge_if(vertex(0, g), incident_on(vertex(3, g), g), g); - print_graph(g, get(vertex_index, g)); - print_edges2(g, get(vertex_index, g), get(edge_weight, g)); + std::cout << "removing edges connecting 0 and 3" << std::endl; + remove_out_edge_if(vertex(0, g), incident_on(vertex(3, g), g), g); + print_graph(g, get(vertex_index, g)); + print_edges2(g, get(vertex_index, g), get(edge_weight, g)); - std::cout << "removing edges with weight greater than 3" << std::endl; - remove_edge_if(has_weight_greater_than(3, g), g); - print_graph(g, get(vertex_index, g)); - print_edges2(g, get(vertex_index, g), get(edge_weight, g)); + std::cout << "removing edges with weight greater than 3" << std::endl; + remove_edge_if(has_weight_greater_than(3, g), g); + print_graph(g, get(vertex_index, g)); + print_edges2(g, get(vertex_index, g), get(edge_weight, g)); - return 0; + return 0; } diff --git a/example/remove_edge_if_undir.expected b/example/remove_edge_if_undir.expected index 1614e3833..2ae4359ed 100644 --- a/example/remove_edge_if_undir.expected +++ b/example/remove_edge_if_undir.expected @@ -1,19 +1,19 @@ original graph: -0 <--> 3 3 2 -1 <--> 3 -2 <--> 0 3 -3 <--> 0 0 1 2 -1(0,3) 2(0,3) 3(1,3) 4(2,0) 5(3,2) +0 <--> 3 3 2 +1 <--> 3 +2 <--> 0 3 +3 <--> 0 0 1 2 +1(0,3) 2(0,3) 3(1,3) 4(2,0) 5(3,2) removing edges connecting 0 and 3 -0 <--> 2 -1 <--> 3 -2 <--> 0 3 -3 <--> 1 2 -3(1,3) 4(2,0) 5(3,2) +0 <--> 2 +1 <--> 3 +2 <--> 0 3 +3 <--> 1 2 +3(1,3) 4(2,0) 5(3,2) removing edges with weight greater than 3 -0 <--> -1 <--> 3 -2 <--> -3 <--> 1 -3(1,3) +0 <--> +1 <--> 3 +2 <--> +3 <--> 1 +3(1,3) diff --git a/example/reverse_graph.cpp b/example/reverse_graph.cpp index 9ccf1875c..be840bd0b 100644 --- a/example/reverse_graph.cpp +++ b/example/reverse_graph.cpp @@ -1,5 +1,5 @@ //======================================================================= -// Copyright 2001 Jeremy G. Siek, Andrew Lumsdaine, Lie-Quan Lee, +// Copyright 2001 Jeremy G. Siek, Andrew Lumsdaine, Lie-Quan Lee, // // Distributed under the Boost Software License, Version 1.0. (See // accompanying file LICENSE_1_0.txt or copy at @@ -16,36 +16,34 @@ #include #include -int -main() +int main() { - using namespace boost; - typedef adjacency_list < vecS, vecS, bidirectionalS > Graph; - - Graph G(5); - add_edge(0, 2, G); - add_edge(1, 1, G); - add_edge(1, 3, G); - add_edge(1, 4, G); - add_edge(2, 1, G); - add_edge(2, 3, G); - add_edge(2, 4, G); - add_edge(3, 1, G); - add_edge(3, 4, G); - add_edge(4, 0, G); - add_edge(4, 1, G); - - std::cout << "original graph:" << std::endl; - print_graph(G, get(vertex_index, G)); - - - std::cout << std::endl << "reversed graph:" << std::endl; -#if defined(BOOST_MSVC) && BOOST_MSVC <= 1300 // avoid VC++ bug... - reverse_graph R(G); - print_graph(R, get(vertex_index, G)); + using namespace boost; + typedef adjacency_list< vecS, vecS, bidirectionalS > Graph; + + Graph G(5); + add_edge(0, 2, G); + add_edge(1, 1, G); + add_edge(1, 3, G); + add_edge(1, 4, G); + add_edge(2, 1, G); + add_edge(2, 3, G); + add_edge(2, 4, G); + add_edge(3, 1, G); + add_edge(3, 4, G); + add_edge(4, 0, G); + add_edge(4, 1, G); + + std::cout << "original graph:" << std::endl; + print_graph(G, get(vertex_index, G)); + + std::cout << std::endl << "reversed graph:" << std::endl; +#if defined(BOOST_MSVC) && BOOST_MSVC <= 1300 // avoid VC++ bug... + reverse_graph< Graph > R(G); + print_graph(R, get(vertex_index, G)); #else - print_graph(make_reverse_graph(G), get(vertex_index, G)); + print_graph(make_reverse_graph(G), get(vertex_index, G)); #endif - return EXIT_SUCCESS; + return EXIT_SUCCESS; } diff --git a/example/reverse_graph.expected b/example/reverse_graph.expected index fc3bb22c9..068c8195e 100644 --- a/example/reverse_graph.expected +++ b/example/reverse_graph.expected @@ -1,13 +1,13 @@ original graph: -0 --> 2 -1 --> 1 3 4 -2 --> 1 3 4 -3 --> 1 4 -4 --> 0 1 +0 --> 2 +1 --> 1 3 4 +2 --> 1 3 4 +3 --> 1 4 +4 --> 0 1 reversed graph: -0 --> 4 -1 --> 1 2 3 4 -2 --> 0 -3 --> 1 2 -4 --> 1 2 3 +0 --> 4 +1 --> 1 2 3 4 +2 --> 0 +3 --> 1 2 +4 --> 1 2 3 diff --git a/example/roget_components.cpp b/example/roget_components.cpp index 7a11353fa..5347acca6 100644 --- a/example/roget_components.cpp +++ b/example/roget_components.cpp @@ -13,121 +13,134 @@ #include #include -#define specs(v) \ - (filename ? index_map[v] : v->cat_no) << " " << v->name +#define specs(v) (filename ? index_map[v] : v->cat_no) << " " << v->name int main(int argc, char* argv[]) { - using namespace boost; - Graph* g; - typedef graph_traits::vertex_descriptor vertex_t; - unsigned long n = 0; - unsigned long d = 0; - unsigned long p = 0; - long s = 0; - char* filename = NULL; - int c, i; - - while (--argc) { - if (sscanf(argv[argc], "-n%lu", &n) == 1); - else if (sscanf(argv[argc], "-d%lu", &d) == 1); - else if (sscanf(argv[argc], "-p%lu", &p) == 1); - else if (sscanf(argv[argc], "-s%ld", &s) == 1); - else if (strncmp(argv[argc], "-g", 2) == 0) - filename = argv[argc] + 2; - else { - fprintf(stderr, "Usage: %s [-nN][-dN][-pN][-sN][-gfoo]\n", argv[0]); - return -2; + using namespace boost; + Graph* g; + typedef graph_traits< Graph* >::vertex_descriptor vertex_t; + unsigned long n = 0; + unsigned long d = 0; + unsigned long p = 0; + long s = 0; + char* filename = NULL; + int c, i; + + while (--argc) + { + if (sscanf(argv[argc], "-n%lu", &n) == 1) + ; + else if (sscanf(argv[argc], "-d%lu", &d) == 1) + ; + else if (sscanf(argv[argc], "-p%lu", &p) == 1) + ; + else if (sscanf(argv[argc], "-s%ld", &s) == 1) + ; + else if (strncmp(argv[argc], "-g", 2) == 0) + filename = argv[argc] + 2; + else + { + fprintf(stderr, "Usage: %s [-nN][-dN][-pN][-sN][-gfoo]\n", argv[0]); + return -2; + } } - } - g = (filename ? restore_graph(filename) : roget(n, d, p, s)); - if (g == NULL) { - fprintf(stderr, "Sorry, can't create the graph! (error code %ld)\n", + g = (filename ? restore_graph(filename) : roget(n, d, p, s)); + if (g == NULL) + { + fprintf(stderr, "Sorry, can't create the graph! (error code %ld)\n", panic_code); - return -1; - } - printf("Reachability analysis of %s\n\n", g->id); - - // - The root map corresponds to what Knuth calls the "min" field. - // - The discover time map is the "rank" field - // - Knuth uses the rank field for double duty, to record the - // discover time, and to keep track of which vertices have - // been visited. The BGL strong_components() function needs - // a separate field for marking colors, so we use the w field. - - std::vector comp(num_vertices(g)); - property_map::type - index_map = get(vertex_index, g); - - property_map >::type - root = get(v_property(), g); - - int num_comp = strong_components - (g, make_iterator_property_map(comp.begin(), index_map), - root_map(root). - discover_time_map(get(z_property(), g)). - color_map(get(w_property(), g))); - - std::vector< std::vector > strong_comp(num_comp); - - // First add representative vertices to each component's list - graph_traits::vertex_iterator vi, vi_end; - for (boost::tie(vi, vi_end) = vertices(g); vi != vi_end; ++vi) - if (root[*vi] == *vi) - strong_comp[comp[index_map[*vi]]].push_back(*vi); - - // Then add the other vertices of the component - for (boost::tie(vi, vi_end) = vertices(g); vi != vi_end; ++vi) - if (root[*vi] != *vi) - strong_comp[comp[index_map[*vi]]].push_back(*vi); - - // We do not print out the "from" and "to" information as Knuth - // does because we no longer have easy access to that information - // from outside the algorithm. - - for (c = 0; c < num_comp; ++c) { - vertex_t v = strong_comp[c].front(); - std::cout << "Strong component `" << specs(v) << "'"; - if (strong_comp[c].size() > 1) { - std::cout << " also includes:\n"; - for (i = 1; i < strong_comp[c].size(); ++i) - std::cout << " " << specs(strong_comp[c][i]) << std::endl; - } else - std::cout << std::endl; - } - - // Next we print out the "component graph" or "condensation", that - // is, we consider each component to be a vertex in a new graph - // where there is an edge connecting one component to another if there - // is one or more edges connecting any of the vertices from the - // first component to any of the vertices in the second. We use the - // name of the representative vertex as the name of the component. - - printf("\nLinks between components:\n"); - - // This array provides an efficient way to check if we've already - // created a link from the current component to the component - // of the target vertex. - std::vector mark(num_comp, (std::numeric_limits::max)()); - - // We go in reverse order just to mimic the output ordering in - // Knuth's version. - for (c = num_comp - 1; c >= 0; --c) { - vertex_t u = strong_comp[c][0]; - for (i = 0; i < strong_comp[c].size(); ++i) { - vertex_t v = strong_comp[c][i]; - graph_traits::out_edge_iterator ei, ei_end; - for (boost::tie(ei, ei_end) = out_edges(v, g); ei != ei_end; ++ei) { - vertex_t x = target(*ei, g); - int comp_x = comp[index_map[x]]; - if (comp_x != c && mark[comp_x] != c) { - mark[comp_x] = c; - vertex_t w = strong_comp[comp_x][0]; - std::cout << specs(u) << " -> " << specs(w) - << " (e.g., " << specs(v) << " -> " << specs(x) << ")\n"; - } // if - } // for + return -1; + } + printf("Reachability analysis of %s\n\n", g->id); + + // - The root map corresponds to what Knuth calls the "min" field. + // - The discover time map is the "rank" field + // - Knuth uses the rank field for double duty, to record the + // discover time, and to keep track of which vertices have + // been visited. The BGL strong_components() function needs + // a separate field for marking colors, so we use the w field. + + std::vector< int > comp(num_vertices(g)); + property_map< Graph*, vertex_index_t >::type index_map + = get(vertex_index, g); + + property_map< Graph*, v_property< vertex_t > >::type root + = get(v_property< vertex_t >(), g); + + int num_comp = strong_components(g, + make_iterator_property_map(comp.begin(), index_map), + root_map(root) + .discover_time_map(get(z_property< long >(), g)) + .color_map(get(w_property< long >(), g))); + + std::vector< std::vector< vertex_t > > strong_comp(num_comp); + + // First add representative vertices to each component's list + graph_traits< Graph* >::vertex_iterator vi, vi_end; + for (boost::tie(vi, vi_end) = vertices(g); vi != vi_end; ++vi) + if (root[*vi] == *vi) + strong_comp[comp[index_map[*vi]]].push_back(*vi); + + // Then add the other vertices of the component + for (boost::tie(vi, vi_end) = vertices(g); vi != vi_end; ++vi) + if (root[*vi] != *vi) + strong_comp[comp[index_map[*vi]]].push_back(*vi); + + // We do not print out the "from" and "to" information as Knuth + // does because we no longer have easy access to that information + // from outside the algorithm. + + for (c = 0; c < num_comp; ++c) + { + vertex_t v = strong_comp[c].front(); + std::cout << "Strong component `" << specs(v) << "'"; + if (strong_comp[c].size() > 1) + { + std::cout << " also includes:\n"; + for (i = 1; i < strong_comp[c].size(); ++i) + std::cout << " " << specs(strong_comp[c][i]) << std::endl; + } + else + std::cout << std::endl; + } + + // Next we print out the "component graph" or "condensation", that + // is, we consider each component to be a vertex in a new graph + // where there is an edge connecting one component to another if there + // is one or more edges connecting any of the vertices from the + // first component to any of the vertices in the second. We use the + // name of the representative vertex as the name of the component. + + printf("\nLinks between components:\n"); + + // This array provides an efficient way to check if we've already + // created a link from the current component to the component + // of the target vertex. + std::vector< int > mark(num_comp, (std::numeric_limits< int >::max)()); + + // We go in reverse order just to mimic the output ordering in + // Knuth's version. + for (c = num_comp - 1; c >= 0; --c) + { + vertex_t u = strong_comp[c][0]; + for (i = 0; i < strong_comp[c].size(); ++i) + { + vertex_t v = strong_comp[c][i]; + graph_traits< Graph* >::out_edge_iterator ei, ei_end; + for (boost::tie(ei, ei_end) = out_edges(v, g); ei != ei_end; ++ei) + { + vertex_t x = target(*ei, g); + int comp_x = comp[index_map[x]]; + if (comp_x != c && mark[comp_x] != c) + { + mark[comp_x] = c; + vertex_t w = strong_comp[comp_x][0]; + std::cout << specs(u) << " -> " << specs(w) << " (e.g., " + << specs(v) << " -> " << specs(x) << ")\n"; + } // if + } // for + } // for } // for - } // for } diff --git a/example/scaled_closeness_centrality.cpp b/example/scaled_closeness_centrality.cpp index a2ade80c6..1f349f682 100644 --- a/example/scaled_closeness_centrality.cpp +++ b/example/scaled_closeness_centrality.cpp @@ -23,21 +23,21 @@ using namespace boost; // distances of each vertex. This measure allows customization // of the distance type, result type, and even the underlying // divide operation. -template > +template < typename Graph, typename Distance, typename Result, + typename Divide = divides< Result > > struct scaled_closeness_measure { typedef Distance distance_type; typedef Result result_type; - Result operator ()(Distance d, const Graph& g) + Result operator()(Distance d, const Graph& g) { - if(d == numeric_values::infinity()) { - return numeric_values::zero(); + if (d == numeric_values< Distance >::infinity()) + { + return numeric_values< Result >::zero(); } - else { + else + { return div(Result(num_vertices(g)), Result(d)); } } @@ -51,32 +51,31 @@ struct Actor }; // Declare the graph type and its vertex and edge types. -typedef undirected_graph Graph; -typedef graph_traits::vertex_descriptor Vertex; -typedef graph_traits::edge_descriptor Edge; +typedef undirected_graph< Actor > Graph; +typedef graph_traits< Graph >::vertex_descriptor Vertex; +typedef graph_traits< Graph >::edge_descriptor Edge; // The name map provides an abstract accessor for the names of // each vertex. This is used during graph creation. -typedef property_map::type NameMap; +typedef property_map< Graph, string Actor::* >::type NameMap; // Declare a matrix type and its corresponding property map that // will contain the distances between each pair of vertices. -typedef exterior_vertex_property DistanceProperty; +typedef exterior_vertex_property< Graph, int > DistanceProperty; typedef DistanceProperty::matrix_type DistanceMatrix; typedef DistanceProperty::matrix_map_type DistanceMatrixMap; // Declare the weight map so that each edge returns the same value. -typedef constant_property_map WeightMap; +typedef constant_property_map< Edge, int > WeightMap; // Declare a container and its corresponding property map that // will contain the resulting closeness centralities of each // vertex in the graph. -typedef boost::exterior_vertex_property ClosenessProperty; +typedef boost::exterior_vertex_property< Graph, float > ClosenessProperty; typedef ClosenessProperty::container_type ClosenessContainer; typedef ClosenessProperty::map_type ClosenessMap; -int -main(int argc, char *argv[]) +int main(int argc, char* argv[]) { // Create the graph and a property map that provides access // to the actor names. @@ -95,7 +94,7 @@ main(int argc, char *argv[]) floyd_warshall_all_pairs_shortest_paths(g, dm, weight_map(wm)); // Create the scaled closeness measure. - scaled_closeness_measure m; + scaled_closeness_measure< Graph, int, float > m; // Compute the degree centrality for graph ClosenessContainer cents(num_vertices(g)); @@ -103,10 +102,11 @@ main(int argc, char *argv[]) all_closeness_centralities(g, dm, cm, m); // Print the scaled closeness centrality of each vertex. - graph_traits::vertex_iterator i, end; - for(boost::tie(i, end) = vertices(g); i != end; ++i) { - cout << setw(12) << setiosflags(ios::left) - << g[*i].name << get(cm, *i) << endl; + graph_traits< Graph >::vertex_iterator i, end; + for (boost::tie(i, end) = vertices(g); i != end; ++i) + { + cout << setw(12) << setiosflags(ios::left) << g[*i].name << get(cm, *i) + << endl; } return 0; diff --git a/example/scc.cpp b/example/scc.cpp index d66382bfa..142316db9 100644 --- a/example/scc.cpp +++ b/example/scc.cpp @@ -1,5 +1,5 @@ //======================================================================= -// Copyright 2001 Jeremy G. Siek, Andrew Lumsdaine, Lie-Quan Lee, +// Copyright 2001 Jeremy G. Siek, Andrew Lumsdaine, Lie-Quan Lee, // // Distributed under the Boost Software License, Version 1.0. (See // accompanying file LICENSE_1_0.txt or copy at @@ -9,8 +9,8 @@ /* IMPORTANT!!! ~~~~~~~~~~~~ - This example uses interfaces that have been deprecated and removed from Boost.Grpah. - Someone needs to update it, as it does NOT compile. + This example uses interfaces that have been deprecated and removed from + Boost.Grpah. Someone needs to update it, as it does NOT compile. */ #include @@ -20,30 +20,29 @@ #include #include -int -main() +int main() { - using namespace boost; - GraphvizDigraph g; - read_graphviz("figs/scc.dot", g); + using namespace boost; + GraphvizDigraph g; + read_graphviz("figs/scc.dot", g); - typedef graph_traits < GraphvizDigraph >::vertex_descriptor vertex_t; - std::map < vertex_t, int >component; + typedef graph_traits< GraphvizDigraph >::vertex_descriptor vertex_t; + std::map< vertex_t, int > component; - strong_components(g, make_assoc_property_map(component)); + strong_components(g, make_assoc_property_map(component)); - property_map < GraphvizDigraph, vertex_attribute_t >::type - vertex_attr_map = get(vertex_attribute, g); - std::string color[] = { - "white", "gray", "black", "lightgray"}; - graph_traits < GraphvizDigraph >::vertex_iterator vi, vi_end; - for (boost::tie(vi, vi_end) = vertices(g); vi != vi_end; ++vi) { - vertex_attr_map[*vi]["color"] = color[component[*vi]]; - vertex_attr_map[*vi]["style"] = "filled"; - if (vertex_attr_map[*vi]["color"] == "black") - vertex_attr_map[*vi]["fontcolor"] = "white"; - } - write_graphviz("figs/scc-out.dot", g); + property_map< GraphvizDigraph, vertex_attribute_t >::type vertex_attr_map + = get(vertex_attribute, g); + std::string color[] = { "white", "gray", "black", "lightgray" }; + graph_traits< GraphvizDigraph >::vertex_iterator vi, vi_end; + for (boost::tie(vi, vi_end) = vertices(g); vi != vi_end; ++vi) + { + vertex_attr_map[*vi]["color"] = color[component[*vi]]; + vertex_attr_map[*vi]["style"] = "filled"; + if (vertex_attr_map[*vi]["color"] == "black") + vertex_attr_map[*vi]["fontcolor"] = "white"; + } + write_graphviz("figs/scc-out.dot", g); - return EXIT_SUCCESS; + return EXIT_SUCCESS; } diff --git a/example/scc.dot b/example/scc.dot index eb55f5d63..0775898da 100644 --- a/example/scc.dot +++ b/example/scc.dot @@ -16,9 +16,9 @@ digraph SCC { a -> b a -> f a -> h - b -> c + b -> c b -> a - c -> d + c -> d c -> b d -> e e -> d diff --git a/example/simple_planarity_test.cpp b/example/simple_planarity_test.cpp index 525c67019..cb67452a4 100644 --- a/example/simple_planarity_test.cpp +++ b/example/simple_planarity_test.cpp @@ -9,62 +9,59 @@ #include #include - int main(int argc, char** argv) { - // This program illustrates a simple use of boyer_myrvold_planar_embedding - // as a simple yes/no test for planarity. + // This program illustrates a simple use of boyer_myrvold_planar_embedding + // as a simple yes/no test for planarity. + + using namespace boost; - using namespace boost; + typedef adjacency_list< vecS, vecS, undirectedS, + property< vertex_index_t, int > > + graph; - typedef adjacency_list - > graph; + graph K_4(4); + add_edge(0, 1, K_4); + add_edge(0, 2, K_4); + add_edge(0, 3, K_4); + add_edge(1, 2, K_4); + add_edge(1, 3, K_4); + add_edge(2, 3, K_4); - graph K_4(4); - add_edge(0, 1, K_4); - add_edge(0, 2, K_4); - add_edge(0, 3, K_4); - add_edge(1, 2, K_4); - add_edge(1, 3, K_4); - add_edge(2, 3, K_4); + if (boyer_myrvold_planarity_test(K_4)) + std::cout << "K_4 is planar." << std::endl; + else + std::cout << "ERROR! K_4 should have been recognized as planar!" + << std::endl; - if (boyer_myrvold_planarity_test(K_4)) - std::cout << "K_4 is planar." << std::endl; - else - std::cout << "ERROR! K_4 should have been recognized as planar!" - << std::endl; + graph K_5(5); + add_edge(0, 1, K_5); + add_edge(0, 2, K_5); + add_edge(0, 3, K_5); + add_edge(0, 4, K_5); + add_edge(1, 2, K_5); + add_edge(1, 3, K_5); + add_edge(1, 4, K_5); + add_edge(2, 3, K_5); + add_edge(2, 4, K_5); - graph K_5(5); - add_edge(0, 1, K_5); - add_edge(0, 2, K_5); - add_edge(0, 3, K_5); - add_edge(0, 4, K_5); - add_edge(1, 2, K_5); - add_edge(1, 3, K_5); - add_edge(1, 4, K_5); - add_edge(2, 3, K_5); - add_edge(2, 4, K_5); + // We've almost created a K_5 - it's missing one edge - so it should still + // be planar at this point. - // We've almost created a K_5 - it's missing one edge - so it should still - // be planar at this point. + if (boyer_myrvold_planarity_test(K_5)) + std::cout << "K_5 (minus an edge) is planar." << std::endl; + else + std::cout << "ERROR! K_5 with one edge missing should" + << " have been recognized as planar!" << std::endl; - if (boyer_myrvold_planarity_test(K_5)) - std::cout << "K_5 (minus an edge) is planar." << std::endl; - else - std::cout << "ERROR! K_5 with one edge missing should" - << " have been recognized as planar!" << std::endl; + // Now add the final edge... + add_edge(3, 4, K_5); - // Now add the final edge... - add_edge(3, 4, K_5); - - if (boyer_myrvold_planarity_test(K_5)) - std::cout << "ERROR! K_5 was recognized as planar!" << std::endl; - else - std::cout << "K_5 is not planar." << std::endl; + if (boyer_myrvold_planarity_test(K_5)) + std::cout << "ERROR! K_5 was recognized as planar!" << std::endl; + else + std::cout << "K_5 is not planar." << std::endl; - return 0; + return 0; } diff --git a/example/sloan_ordering.cpp b/example/sloan_ordering.cpp index 7516ba41b..538e10601 100644 --- a/example/sloan_ordering.cpp +++ b/example/sloan_ordering.cpp @@ -10,7 +10,6 @@ //======================================================================= // - #include #include #include @@ -21,7 +20,6 @@ #include #include - using std::cout; using std::endl; @@ -62,174 +60,175 @@ using std::endl; ############################### */ -int main(int , char* []) +int main(int, char*[]) { - cout << endl; - cout << "#####################################" << endl; - cout << "### First light of sloan-ordering ###" << endl; - cout << "#####################################" << endl << endl; - - using namespace boost; - using namespace std; - - - //Defining the graph type - typedef adjacency_list< - setS, - vecS, - undirectedS, - property< - vertex_color_t, - default_color_type, - property< - vertex_degree_t, - int, - property< - vertex_priority_t, - double > > > > Graph; - - typedef graph_traits::vertex_descriptor Vertex; - typedef graph_traits::vertices_size_type size_type; - - typedef std::pair Pair; - - Pair edges[14] = { Pair(0,3), //a-d - Pair(0,5), //a-f - Pair(1,2), //b-c - Pair(1,4), //b-e - Pair(1,6), //b-g - Pair(1,9), //b-j - Pair(2,3), //c-d - Pair(2,4), //c-e - Pair(3,5), //d-f - Pair(3,8), //d-i - Pair(4,6), //e-g - Pair(5,6), //f-g - Pair(5,7), //f-h - Pair(6,7) }; //g-h - - - //Creating a graph and adding the edges from above into it - Graph G(10); - for (int i = 0; i < 14; ++i) - add_edge(edges[i].first, edges[i].second, G); - - //Creating two iterators over the vertices - graph_traits::vertex_iterator ui, ui_end; - - //Creating a property_map with the degrees of the degrees of each vertex - property_map::type deg = get(vertex_degree, G); - for (boost::tie(ui, ui_end) = vertices(G); ui != ui_end; ++ui) - deg[*ui] = degree(*ui, G); - - //Creating a property_map for the indices of a vertex - property_map::type index_map = get(vertex_index, G); - - std::cout << "original bandwidth: " << bandwidth(G) << std::endl; - std::cout << "original profile: " << profile(G) << std::endl; - std::cout << "original max_wavefront: " << max_wavefront(G) << std::endl; - std::cout << "original aver_wavefront: " << aver_wavefront(G) << std::endl; - std::cout << "original rms_wavefront: " << rms_wavefront(G) << std::endl; - - - //Creating a vector of vertices - std::vector sloan_order(num_vertices(G)); - //Creating a vector of size_type - std::vector perm(num_vertices(G)); - - { - - //Setting the start node - Vertex s = vertex(0, G); - int ecc; //defining a variable for the pseudoperipheral radius - - //Calculating the pseudoeperipheral node and radius - Vertex e = pseudo_peripheral_pair(G, s, ecc, get(vertex_color, G), get(vertex_degree, G) ); - cout << endl; - cout << "Starting vertex: " << s << endl; - cout << "Pseudoperipheral vertex: " << e << endl; - cout << "Pseudoperipheral radius: " << ecc << endl << endl; - - - - //Sloan ordering - sloan_ordering(G, s, e, sloan_order.begin(), get(vertex_color, G), - get(vertex_degree, G), get(vertex_priority, G)); - - cout << "Sloan ordering starting at: " << s << endl; - cout << " "; - - for (std::vector::const_iterator i = sloan_order.begin(); - i != sloan_order.end(); ++i) - cout << index_map[*i] << " "; - cout << endl; - - for (size_type c = 0; c != sloan_order.size(); ++c) - perm[index_map[sloan_order[c]]] = c; - std::cout << " bandwidth: " - << bandwidth(G, make_iterator_property_map(&perm[0], index_map, perm[0])) - << std::endl; - std::cout << " profile: " - << profile(G, make_iterator_property_map(&perm[0], index_map, perm[0])) - << std::endl; - std::cout << " max_wavefront: " - << max_wavefront(G, make_iterator_property_map(&perm[0], index_map, perm[0])) - << std::endl; - std::cout << " aver_wavefront: " - << aver_wavefront(G, make_iterator_property_map(&perm[0], index_map, perm[0])) - << std::endl; - std::cout << " rms_wavefront: " - << rms_wavefront(G, make_iterator_property_map(&perm[0], index_map, perm[0])) - << std::endl; - } - + cout << "#####################################" << endl; + cout << "### First light of sloan-ordering ###" << endl; + cout << "#####################################" << endl << endl; + + using namespace boost; + using namespace std; + + // Defining the graph type + typedef adjacency_list< setS, vecS, undirectedS, + property< vertex_color_t, default_color_type, + property< vertex_degree_t, int, + property< vertex_priority_t, double > > > > + Graph; + + typedef graph_traits< Graph >::vertex_descriptor Vertex; + typedef graph_traits< Graph >::vertices_size_type size_type; + + typedef std::pair< std::size_t, std::size_t > Pair; + + Pair edges[14] = { Pair(0, 3), // a-d + Pair(0, 5), // a-f + Pair(1, 2), // b-c + Pair(1, 4), // b-e + Pair(1, 6), // b-g + Pair(1, 9), // b-j + Pair(2, 3), // c-d + Pair(2, 4), // c-e + Pair(3, 5), // d-f + Pair(3, 8), // d-i + Pair(4, 6), // e-g + Pair(5, 6), // f-g + Pair(5, 7), // f-h + Pair(6, 7) }; // g-h + + // Creating a graph and adding the edges from above into it + Graph G(10); + for (int i = 0; i < 14; ++i) + add_edge(edges[i].first, edges[i].second, G); + + // Creating two iterators over the vertices + graph_traits< Graph >::vertex_iterator ui, ui_end; + + // Creating a property_map with the degrees of the degrees of each vertex + property_map< Graph, vertex_degree_t >::type deg = get(vertex_degree, G); + for (boost::tie(ui, ui_end) = vertices(G); ui != ui_end; ++ui) + deg[*ui] = degree(*ui, G); + + // Creating a property_map for the indices of a vertex + property_map< Graph, vertex_index_t >::type index_map + = get(vertex_index, G); + + std::cout << "original bandwidth: " << bandwidth(G) << std::endl; + std::cout << "original profile: " << profile(G) << std::endl; + std::cout << "original max_wavefront: " << max_wavefront(G) << std::endl; + std::cout << "original aver_wavefront: " << aver_wavefront(G) << std::endl; + std::cout << "original rms_wavefront: " << rms_wavefront(G) << std::endl; + + // Creating a vector of vertices + std::vector< Vertex > sloan_order(num_vertices(G)); + // Creating a vector of size_type + std::vector< size_type > perm(num_vertices(G)); + { + // Setting the start node + Vertex s = vertex(0, G); + int ecc; // defining a variable for the pseudoperipheral radius + + // Calculating the pseudoeperipheral node and radius + Vertex e = pseudo_peripheral_pair( + G, s, ecc, get(vertex_color, G), get(vertex_degree, G)); + + cout << endl; + cout << "Starting vertex: " << s << endl; + cout << "Pseudoperipheral vertex: " << e << endl; + cout << "Pseudoperipheral radius: " << ecc << endl << endl; + + // Sloan ordering + sloan_ordering(G, s, e, sloan_order.begin(), get(vertex_color, G), + get(vertex_degree, G), get(vertex_priority, G)); + + cout << "Sloan ordering starting at: " << s << endl; + cout << " "; + + for (std::vector< Vertex >::const_iterator i = sloan_order.begin(); + i != sloan_order.end(); ++i) + cout << index_map[*i] << " "; + cout << endl; + + for (size_type c = 0; c != sloan_order.size(); ++c) + perm[index_map[sloan_order[c]]] = c; + std::cout << " bandwidth: " + << bandwidth(G, + make_iterator_property_map( + &perm[0], index_map, perm[0])) + << std::endl; + std::cout << " profile: " + << profile(G, + make_iterator_property_map( + &perm[0], index_map, perm[0])) + << std::endl; + std::cout << " max_wavefront: " + << max_wavefront(G, + make_iterator_property_map( + &perm[0], index_map, perm[0])) + << std::endl; + std::cout << " aver_wavefront: " + << aver_wavefront(G, + make_iterator_property_map( + &perm[0], index_map, perm[0])) + << std::endl; + std::cout << " rms_wavefront: " + << rms_wavefront(G, + make_iterator_property_map( + &perm[0], index_map, perm[0])) + << std::endl; + } ///////////////////////////////////////////////// - //Version including finding a good starting point + // Version including finding a good starting point ///////////////////////////////////////////////// - + { - //sloan_ordering - sloan_ordering(G, sloan_order.begin(), - get(vertex_color, G), - make_degree_map(G), - get(vertex_priority, G) ); - - cout << endl << "Sloan ordering without a start-vertex:" << endl; - cout << " "; - for (std::vector::const_iterator i=sloan_order.begin(); - i != sloan_order.end(); ++i) - cout << index_map[*i] << " "; - cout << endl; - - for (size_type c = 0; c != sloan_order.size(); ++c) - perm[index_map[sloan_order[c]]] = c; - std::cout << " bandwidth: " - << bandwidth(G, make_iterator_property_map(&perm[0], index_map, perm[0])) - << std::endl; - std::cout << " profile: " - << profile(G, make_iterator_property_map(&perm[0], index_map, perm[0])) - << std::endl; - std::cout << " max_wavefront: " - << max_wavefront(G, make_iterator_property_map(&perm[0], index_map, perm[0])) - << std::endl; - std::cout << " aver_wavefront: " - << aver_wavefront(G, make_iterator_property_map(&perm[0], index_map, perm[0])) - << std::endl; - std::cout << " rms_wavefront: " - << rms_wavefront(G, make_iterator_property_map(&perm[0], index_map, perm[0])) - << std::endl; + // sloan_ordering + sloan_ordering(G, sloan_order.begin(), get(vertex_color, G), + make_degree_map(G), get(vertex_priority, G)); + + cout << endl << "Sloan ordering without a start-vertex:" << endl; + cout << " "; + for (std::vector< Vertex >::const_iterator i = sloan_order.begin(); + i != sloan_order.end(); ++i) + cout << index_map[*i] << " "; + cout << endl; + + for (size_type c = 0; c != sloan_order.size(); ++c) + perm[index_map[sloan_order[c]]] = c; + std::cout << " bandwidth: " + << bandwidth(G, + make_iterator_property_map( + &perm[0], index_map, perm[0])) + << std::endl; + std::cout << " profile: " + << profile(G, + make_iterator_property_map( + &perm[0], index_map, perm[0])) + << std::endl; + std::cout << " max_wavefront: " + << max_wavefront(G, + make_iterator_property_map( + &perm[0], index_map, perm[0])) + << std::endl; + std::cout << " aver_wavefront: " + << aver_wavefront(G, + make_iterator_property_map( + &perm[0], index_map, perm[0])) + << std::endl; + std::cout << " rms_wavefront: " + << rms_wavefront(G, + make_iterator_property_map( + &perm[0], index_map, perm[0])) + << std::endl; } - - - - cout << endl; - cout << "###############################" << endl; - cout << "### sloan-ordering finished ###" << endl; - cout << "###############################" << endl << endl; - return 0; + cout << endl; + cout << "###############################" << endl; + cout << "### sloan-ordering finished ###" << endl; + cout << "###############################" << endl << endl; + return 0; } diff --git a/example/stoer_wagner.cpp b/example/stoer_wagner.cpp index 09f13006a..ce5b0e59c 100644 --- a/example/stoer_wagner.cpp +++ b/example/stoer_wagner.cpp @@ -16,56 +16,68 @@ struct edge_t { - unsigned long first; - unsigned long second; + unsigned long first; + unsigned long second; }; -// A graphic of the min-cut is available at +// A graphic of the min-cut is available at +// int main() { - using namespace std; - - typedef boost::adjacency_list > undirected_graph; - typedef boost::property_map::type weight_map_type; - typedef boost::property_traits::value_type weight_type; - - // define the 16 edges of the graph. {3, 4} means an undirected edge between vertices 3 and 4. - edge_t edges[] = {{3, 4}, {3, 6}, {3, 5}, {0, 4}, {0, 1}, {0, 6}, {0, 7}, - {0, 5}, {0, 2}, {4, 1}, {1, 6}, {1, 5}, {6, 7}, {7, 5}, {5, 2}, {3, 4}}; - - // for each of the 16 edges, define the associated edge weight. ws[i] is the weight for the edge - // that is described by edges[i]. - weight_type ws[] = {0, 3, 1, 3, 1, 2, 6, 1, 8, 1, 1, 80, 2, 1, 1, 4}; - - // construct the graph object. 8 is the number of vertices, which are numbered from 0 - // through 7, and 16 is the number of edges. - undirected_graph g(edges, edges + 16, ws, 8, 16); - - // define a property map, `parities`, that will store a boolean value for each vertex. - // Vertices that have the same parity after `stoer_wagner_min_cut` runs are on the same side of the min-cut. - BOOST_AUTO(parities, boost::make_one_bit_color_map(num_vertices(g), get(boost::vertex_index, g))); - - // run the Stoer-Wagner algorithm to obtain the min-cut weight. `parities` is also filled in. - int w = boost::stoer_wagner_min_cut(g, get(boost::edge_weight, g), boost::parity_map(parities)); - - cout << "The min-cut weight of G is " << w << ".\n" << endl; - assert(w == 7); - - cout << "One set of vertices consists of:" << endl; - size_t i; - for (i = 0; i < num_vertices(g); ++i) { - if (get(parities, i)) - cout << i << endl; - } - cout << endl; - - cout << "The other set of vertices consists of:" << endl; - for (i = 0; i < num_vertices(g); ++i) { - if (!get(parities, i)) - cout << i << endl; - } - cout << endl; - - return EXIT_SUCCESS; + using namespace std; + + typedef boost::adjacency_list< boost::vecS, boost::vecS, boost::undirectedS, + boost::no_property, boost::property< boost::edge_weight_t, int > > + undirected_graph; + typedef boost::property_map< undirected_graph, boost::edge_weight_t >::type + weight_map_type; + typedef boost::property_traits< weight_map_type >::value_type weight_type; + + // define the 16 edges of the graph. {3, 4} means an undirected edge between + // vertices 3 and 4. + edge_t edges[] = { { 3, 4 }, { 3, 6 }, { 3, 5 }, { 0, 4 }, { 0, 1 }, + { 0, 6 }, { 0, 7 }, { 0, 5 }, { 0, 2 }, { 4, 1 }, { 1, 6 }, { 1, 5 }, + { 6, 7 }, { 7, 5 }, { 5, 2 }, { 3, 4 } }; + + // for each of the 16 edges, define the associated edge weight. ws[i] is the + // weight for the edge that is described by edges[i]. + weight_type ws[] = { 0, 3, 1, 3, 1, 2, 6, 1, 8, 1, 1, 80, 2, 1, 1, 4 }; + + // construct the graph object. 8 is the number of vertices, which are + // numbered from 0 through 7, and 16 is the number of edges. + undirected_graph g(edges, edges + 16, ws, 8, 16); + + // define a property map, `parities`, that will store a boolean value for + // each vertex. Vertices that have the same parity after + // `stoer_wagner_min_cut` runs are on the same side of the min-cut. + BOOST_AUTO(parities, + boost::make_one_bit_color_map( + num_vertices(g), get(boost::vertex_index, g))); + + // run the Stoer-Wagner algorithm to obtain the min-cut weight. `parities` + // is also filled in. + int w = boost::stoer_wagner_min_cut( + g, get(boost::edge_weight, g), boost::parity_map(parities)); + + cout << "The min-cut weight of G is " << w << ".\n" << endl; + assert(w == 7); + + cout << "One set of vertices consists of:" << endl; + size_t i; + for (i = 0; i < num_vertices(g); ++i) + { + if (get(parities, i)) + cout << i << endl; + } + cout << endl; + + cout << "The other set of vertices consists of:" << endl; + for (i = 0; i < num_vertices(g); ++i) + { + if (!get(parities, i)) + cout << i << endl; + } + cout << endl; + + return EXIT_SUCCESS; } diff --git a/example/straight_line_drawing.cpp b/example/straight_line_drawing.cpp index 15aa82968..b76bb4ab3 100644 --- a/example/straight_line_drawing.cpp +++ b/example/straight_line_drawing.cpp @@ -17,123 +17,94 @@ #include #include - - using namespace boost; -//a class to hold the coordinates of the straight line embedding +// a class to hold the coordinates of the straight line embedding struct coord_t { - std::size_t x; - std::size_t y; + std::size_t x; + std::size_t y; }; - int main(int argc, char** argv) { - typedef adjacency_list - < vecS, - vecS, - undirectedS, - property - > graph; - - - - //Define the storage type for the planar embedding - typedef std::vector< std::vector< graph_traits::edge_descriptor > > - embedding_storage_t; - typedef boost::iterator_property_map - < embedding_storage_t::iterator, - property_map::type - > - embedding_t; - - - - // Create the graph - a maximal planar graph on 7 vertices. The functions - // planar_canonical_ordering and chrobak_payne_straight_line_drawing both - // require a maximal planar graph. If you start with a graph that isn't - // maximal planar (or you're not sure), you can use the functions - // make_connected, make_biconnected_planar, and make_maximal planar in - // sequence to add a set of edges to any undirected planar graph to make - // it maximal planar. - - graph g(7); - add_edge(0,1,g); - add_edge(1,2,g); - add_edge(2,3,g); - add_edge(3,0,g); - add_edge(3,4,g); - add_edge(4,5,g); - add_edge(5,6,g); - add_edge(6,3,g); - add_edge(0,4,g); - add_edge(1,3,g); - add_edge(3,5,g); - add_edge(2,6,g); - add_edge(1,4,g); - add_edge(1,5,g); - add_edge(1,6,g); - - - - // Create the planar embedding - embedding_storage_t embedding_storage(num_vertices(g)); - embedding_t embedding(embedding_storage.begin(), get(vertex_index,g)); - - boyer_myrvold_planarity_test(boyer_myrvold_params::graph = g, - boyer_myrvold_params::embedding = embedding - ); - - - - // Find a canonical ordering - std::vector::vertex_descriptor> ordering; - planar_canonical_ordering(g, embedding, std::back_inserter(ordering)); - - - //Set up a property map to hold the mapping from vertices to coord_t's - typedef std::vector< coord_t > straight_line_drawing_storage_t; - typedef boost::iterator_property_map - < straight_line_drawing_storage_t::iterator, - property_map::type - > - straight_line_drawing_t; - - straight_line_drawing_storage_t straight_line_drawing_storage - (num_vertices(g)); - straight_line_drawing_t straight_line_drawing - (straight_line_drawing_storage.begin(), - get(vertex_index,g) - ); - - - - // Compute the straight line drawing - chrobak_payne_straight_line_drawing(g, - embedding, - ordering.begin(), - ordering.end(), - straight_line_drawing - ); - - - - std::cout << "The straight line drawing is: " << std::endl; - graph_traits::vertex_iterator vi, vi_end; - for(boost::tie(vi,vi_end) = vertices(g); vi != vi_end; ++vi) + typedef adjacency_list< vecS, vecS, undirectedS, + property< vertex_index_t, int > > + graph; + + // Define the storage type for the planar embedding + typedef std::vector< std::vector< graph_traits< graph >::edge_descriptor > > + embedding_storage_t; + typedef boost::iterator_property_map< embedding_storage_t::iterator, + property_map< graph, vertex_index_t >::type > + embedding_t; + + // Create the graph - a maximal planar graph on 7 vertices. The functions + // planar_canonical_ordering and chrobak_payne_straight_line_drawing both + // require a maximal planar graph. If you start with a graph that isn't + // maximal planar (or you're not sure), you can use the functions + // make_connected, make_biconnected_planar, and make_maximal planar in + // sequence to add a set of edges to any undirected planar graph to make + // it maximal planar. + + graph g(7); + add_edge(0, 1, g); + add_edge(1, 2, g); + add_edge(2, 3, g); + add_edge(3, 0, g); + add_edge(3, 4, g); + add_edge(4, 5, g); + add_edge(5, 6, g); + add_edge(6, 3, g); + add_edge(0, 4, g); + add_edge(1, 3, g); + add_edge(3, 5, g); + add_edge(2, 6, g); + add_edge(1, 4, g); + add_edge(1, 5, g); + add_edge(1, 6, g); + + // Create the planar embedding + embedding_storage_t embedding_storage(num_vertices(g)); + embedding_t embedding(embedding_storage.begin(), get(vertex_index, g)); + + boyer_myrvold_planarity_test(boyer_myrvold_params::graph = g, + boyer_myrvold_params::embedding = embedding); + + // Find a canonical ordering + std::vector< graph_traits< graph >::vertex_descriptor > ordering; + planar_canonical_ordering(g, embedding, std::back_inserter(ordering)); + + // Set up a property map to hold the mapping from vertices to coord_t's + typedef std::vector< coord_t > straight_line_drawing_storage_t; + typedef boost::iterator_property_map< + straight_line_drawing_storage_t::iterator, + property_map< graph, vertex_index_t >::type > + straight_line_drawing_t; + + straight_line_drawing_storage_t straight_line_drawing_storage( + num_vertices(g)); + straight_line_drawing_t straight_line_drawing( + straight_line_drawing_storage.begin(), get(vertex_index, g)); + + // Compute the straight line drawing + chrobak_payne_straight_line_drawing( + g, embedding, ordering.begin(), ordering.end(), straight_line_drawing); + + std::cout << "The straight line drawing is: " << std::endl; + graph_traits< graph >::vertex_iterator vi, vi_end; + for (boost::tie(vi, vi_end) = vertices(g); vi != vi_end; ++vi) { - coord_t coord(get(straight_line_drawing,*vi)); - std::cout << *vi << " -> (" << coord.x << ", " << coord.y << ")" - << std::endl; + coord_t coord(get(straight_line_drawing, *vi)); + std::cout << *vi << " -> (" << coord.x << ", " << coord.y << ")" + << std::endl; } - // Verify that the drawing is actually a plane drawing - if (is_straight_line_drawing(g, straight_line_drawing)) - std::cout << "Is a plane drawing." << std::endl; - else - std::cout << "Is not a plane drawing." << std::endl; + // Verify that the drawing is actually a plane drawing + if (is_straight_line_drawing(g, straight_line_drawing)) + std::cout << "Is a plane drawing." << std::endl; + else + std::cout << "Is not a plane drawing." << std::endl; - return 0; + return 0; } diff --git a/example/strong-components.cpp b/example/strong-components.cpp index 251b71668..12265daf0 100644 --- a/example/strong-components.cpp +++ b/example/strong-components.cpp @@ -1,5 +1,5 @@ //======================================================================= -// Copyright 2001 Jeremy G. Siek, Andrew Lumsdaine, Lie-Quan Lee, +// Copyright 2001 Jeremy G. Siek, Andrew Lumsdaine, Lie-Quan Lee, // // Distributed under the Boost Software License, Version 1.0. (See // accompanying file LICENSE_1_0.txt or copy at @@ -11,30 +11,29 @@ #include #include -int -main() +int main() { - using namespace boost; - typedef adjacency_list < vecS, vecS, directedS > Graph; - const int N = 6; - Graph G(N); - add_edge(0, 1, G); - add_edge(1, 1, G); - add_edge(1, 3, G); - add_edge(1, 4, G); - add_edge(3, 4, G); - add_edge(3, 0, G); - add_edge(4, 3, G); - add_edge(5, 2, G); + using namespace boost; + typedef adjacency_list< vecS, vecS, directedS > Graph; + const int N = 6; + Graph G(N); + add_edge(0, 1, G); + add_edge(1, 1, G); + add_edge(1, 3, G); + add_edge(1, 4, G); + add_edge(3, 4, G); + add_edge(3, 0, G); + add_edge(4, 3, G); + add_edge(5, 2, G); - std::vector c(N); - int num = strong_components - (G, make_iterator_property_map(c.begin(), get(vertex_index, G), c[0])); + std::vector< int > c(N); + int num = strong_components( + G, make_iterator_property_map(c.begin(), get(vertex_index, G), c[0])); - std::cout << "Total number of components: " << num << std::endl; - std::vector < int >::iterator i; - for (i = c.begin(); i != c.end(); ++i) - std::cout << "Vertex " << i - c.begin() - << " is in component " << *i << std::endl; - return EXIT_SUCCESS; + std::cout << "Total number of components: " << num << std::endl; + std::vector< int >::iterator i; + for (i = c.begin(); i != c.end(); ++i) + std::cout << "Vertex " << i - c.begin() << " is in component " << *i + << std::endl; + return EXIT_SUCCESS; } diff --git a/example/strong_components.cpp b/example/strong_components.cpp index 9bcd26a83..2b1e1b13b 100644 --- a/example/strong_components.cpp +++ b/example/strong_components.cpp @@ -10,8 +10,8 @@ /* IMPORTANT!!! ~~~~~~~~~~~~ - This example uses interfaces that have been deprecated and removed from Boost.Grpah. - Someone needs to update it, as it does NOT compile. + This example uses interfaces that have been deprecated and removed from + Boost.Grpah. Someone needs to update it, as it does NOT compile. */ #include @@ -24,16 +24,16 @@ /* Sample output: A directed graph: - a --> b f h - b --> c a - c --> d b - d --> e - e --> d - f --> g - g --> f d - h --> i - i --> h j e c - j --> + a --> b f h + b --> c a + c --> d b + d --> e + e --> d + f --> g + g --> f d + h --> i + i --> h j e c + j --> Total number of components: 4 Vertex a is in component 3 @@ -50,32 +50,37 @@ int main(int, char*[]) { - using namespace boost; - const char* name = "abcdefghij"; + using namespace boost; + const char* name = "abcdefghij"; - adjacency_list G; - dynamic_properties dp; - read_graphviz("scc.dot", G, dp); + adjacency_list< vecS, vecS, directedS > G; + dynamic_properties dp; + read_graphviz("scc.dot", G, dp); - std::cout << "A directed graph:" << std::endl; - print_graph(G, name); - std::cout << std::endl; + std::cout << "A directed graph:" << std::endl; + print_graph(G, name); + std::cout << std::endl; - typedef graph_traits >::vertex_descriptor Vertex; - - std::vector component(num_vertices(G)), discover_time(num_vertices(G)); - std::vector color(num_vertices(G)); - std::vector root(num_vertices(G)); - int num = strong_components(G, make_iterator_property_map(component.begin(), get(vertex_index, G)), - root_map(make_iterator_property_map(root.begin(), get(vertex_index, G))). - color_map(make_iterator_property_map(color.begin(), get(vertex_index, G))). - discover_time_map(make_iterator_property_map(discover_time.begin(), get(vertex_index, G)))); - - std::cout << "Total number of components: " << num << std::endl; - std::vector::size_type i; - for (i = 0; i != component.size(); ++i) - std::cout << "Vertex " << name[i] - <<" is in component " << component[i] << std::endl; - - return 0; + typedef graph_traits< + adjacency_list< vecS, vecS, directedS > >::vertex_descriptor Vertex; + + std::vector< int > component(num_vertices(G)), + discover_time(num_vertices(G)); + std::vector< default_color_type > color(num_vertices(G)); + std::vector< Vertex > root(num_vertices(G)); + int num = strong_components(G, + make_iterator_property_map(component.begin(), get(vertex_index, G)), + root_map(make_iterator_property_map(root.begin(), get(vertex_index, G))) + .color_map( + make_iterator_property_map(color.begin(), get(vertex_index, G))) + .discover_time_map(make_iterator_property_map( + discover_time.begin(), get(vertex_index, G)))); + + std::cout << "Total number of components: " << num << std::endl; + std::vector< int >::size_type i; + for (i = 0; i != component.size(); ++i) + std::cout << "Vertex " << name[i] << " is in component " << component[i] + << std::endl; + + return 0; } diff --git a/example/strong_components.expected b/example/strong_components.expected index 7786f51ea..3e25bdd75 100644 --- a/example/strong_components.expected +++ b/example/strong_components.expected @@ -1,14 +1,14 @@ A directed graph: -a --> b f h -b --> c a -c --> d b -d --> e -e --> d -f --> g -g --> f d -h --> i -i --> h j e c -j --> +a --> b f h +b --> c a +c --> d b +d --> e +e --> d +f --> g +g --> f d +h --> i +i --> h j e c +j --> Total number of components: 4 Vertex a is in component 3 diff --git a/example/subgraph.cpp b/example/subgraph.cpp index 289ae54d9..36fa274b3 100644 --- a/example/subgraph.cpp +++ b/example/subgraph.cpp @@ -11,24 +11,24 @@ Sample output: G0: - 0 --> 1 - 1 --> 2 3 - 2 --> 5 - 3 --> - 4 --> 1 5 - 5 --> 3 - 0(0,1) 1(1,2) 2(1,3) 6(2,5) 3(4,1) 4(4,5) 5(5,3) + 0 --> 1 + 1 --> 2 3 + 2 --> 5 + 3 --> + 4 --> 1 5 + 5 --> 3 + 0(0,1) 1(1,2) 2(1,3) 6(2,5) 3(4,1) 4(4,5) 5(5,3) G1: - 2 --> 5 - 4 --> 5 - 5 --> - 6(2,5) 4(4,5) + 2 --> 5 + 4 --> 5 + 5 --> + 6(2,5) 4(4,5) G2: - 0 --> 1 - 1 --> - 0(0,1) + 0 --> 1 + 1 --> + 0(0,1) */ @@ -38,50 +38,69 @@ #include #include -int main(int,char*[]) +int main(int, char*[]) { - using namespace boost; - typedef subgraph< adjacency_list, property > > Graph; - - const int N = 6; - Graph G0(N); - enum { A, B, C, D, E, F}; // for conveniently refering to vertices in G0 - - Graph& G1 = G0.create_subgraph(); - Graph& G2 = G0.create_subgraph(); - enum { A1, B1, C1 }; // for conveniently refering to vertices in G1 - enum { A2, B2 }; // for conveniently refering to vertices in G2 - - add_vertex(C, G1); // global vertex C becomes local A1 for G1 - add_vertex(E, G1); // global vertex E becomes local B1 for G1 - add_vertex(F, G1); // global vertex F becomes local C1 for G1 - - add_vertex(A, G2); // global vertex A becomes local A1 for G2 - add_vertex(B, G2); // global vertex B becomes local B1 for G2 - - add_edge(A, B, G0); - add_edge(B, C, G0); - add_edge(B, D, G0); - add_edge(E, B, G0); - add_edge(E, F, G0); - add_edge(F, D, G0); - - add_edge(A1, C1, G1); // (A1,C1) is subgraph G1 local indices for (C,F). - - std::cout << "G0:" << std::endl; - print_graph(G0, get(vertex_index, G0)); - print_edges2(G0, get(vertex_index, G0), get(edge_index, G0)); - std::cout << std::endl; - - Graph::children_iterator ci, ci_end; - int num = 1; - for (boost::tie(ci, ci_end) = G0.children(); ci != ci_end; ++ci) { - std::cout << "G" << num++ << ":" << std::endl; - print_graph(*ci, get(vertex_index, *ci)); - print_edges2(*ci, get(vertex_index, *ci), get(edge_index, *ci)); + using namespace boost; + typedef subgraph< adjacency_list< vecS, vecS, directedS, + property< vertex_color_t, int >, property< edge_index_t, int > > > + Graph; + + const int N = 6; + Graph G0(N); + enum + { + A, + B, + C, + D, + E, + F + }; // for conveniently refering to vertices in G0 + + Graph& G1 = G0.create_subgraph(); + Graph& G2 = G0.create_subgraph(); + enum + { + A1, + B1, + C1 + }; // for conveniently refering to vertices in G1 + enum + { + A2, + B2 + }; // for conveniently refering to vertices in G2 + + add_vertex(C, G1); // global vertex C becomes local A1 for G1 + add_vertex(E, G1); // global vertex E becomes local B1 for G1 + add_vertex(F, G1); // global vertex F becomes local C1 for G1 + + add_vertex(A, G2); // global vertex A becomes local A1 for G2 + add_vertex(B, G2); // global vertex B becomes local B1 for G2 + + add_edge(A, B, G0); + add_edge(B, C, G0); + add_edge(B, D, G0); + add_edge(E, B, G0); + add_edge(E, F, G0); + add_edge(F, D, G0); + + add_edge(A1, C1, G1); // (A1,C1) is subgraph G1 local indices for (C,F). + + std::cout << "G0:" << std::endl; + print_graph(G0, get(vertex_index, G0)); + print_edges2(G0, get(vertex_index, G0), get(edge_index, G0)); std::cout << std::endl; - } - return 0; + Graph::children_iterator ci, ci_end; + int num = 1; + for (boost::tie(ci, ci_end) = G0.children(); ci != ci_end; ++ci) + { + std::cout << "G" << num++ << ":" << std::endl; + print_graph(*ci, get(vertex_index, *ci)); + print_edges2(*ci, get(vertex_index, *ci), get(edge_index, *ci)); + std::cout << std::endl; + } + + return 0; } diff --git a/example/subgraph.expected b/example/subgraph.expected index a75a0ce75..026bac845 100644 --- a/example/subgraph.expected +++ b/example/subgraph.expected @@ -1,20 +1,20 @@ G0: -0 --> 1 -1 --> 2 3 -2 --> 5 -3 --> -4 --> 1 5 -5 --> 3 -0(0,1) 1(1,2) 2(1,3) 6(2,5) 3(4,1) 4(4,5) 5(5,3) +0 --> 1 +1 --> 2 3 +2 --> 5 +3 --> +4 --> 1 5 +5 --> 3 +0(0,1) 1(1,2) 2(1,3) 6(2,5) 3(4,1) 4(4,5) 5(5,3) G1: -2 --> 5 -4 --> 5 -5 --> -6(2,5) 4(4,5) +2 --> 5 +4 --> 5 +5 --> +6(2,5) 4(4,5) G2: -0 --> 1 -1 --> -0(0,1) +0 --> 1 +1 --> +0(0,1) diff --git a/example/subgraph_properties.cpp b/example/subgraph_properties.cpp index 613d53a3c..ac9316fad 100644 --- a/example/subgraph_properties.cpp +++ b/example/subgraph_properties.cpp @@ -1,4 +1,4 @@ -// (C) Copyright Jeremy Siek 2004 +// (C) Copyright Jeremy Siek 2004 // Distributed under the Boost Software License, Version 1.0. (See // accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) @@ -35,75 +35,113 @@ #include #include -int main(int,char*[]) +int main(int, char*[]) { - using namespace boost; - //typedef adjacency_list_traits Traits;// Does nothing? - typedef property< vertex_color_t, int, - property< vertex_name_t, std::string > > VertexProperty; - - typedef subgraph< adjacency_list< vecS, vecS, directedS, - VertexProperty, property > > Graph; - - const int N = 6; - Graph G0(N); - enum { A, B, C, D, E, F}; // for conveniently refering to vertices in G0 - - property_map::type name = get(vertex_name_t(), G0); - name[A] = "A"; - name[B] = "B"; - name[C] = "C"; - name[D] = "D"; - name[E] = "E"; - name[F] = "F"; - - Graph& G1 = G0.create_subgraph(); - enum { A1, B1, C1 }; // for conveniently refering to vertices in G1 - - add_vertex(C, G1); // global vertex C becomes local A1 for G1 - add_vertex(E, G1); // global vertex E becomes local B1 for G1 - add_vertex(F, G1); // global vertex F becomes local C1 for G1 - - property_map::type name1 = get(vertex_name_t(), G1); - name1[A1] = "A1"; - - std::cout << std::endl << "After initializing properties for G1:" << std::endl; - std::cout << " Global and local properties for vertex G0[C]..." << std::endl; - std::cout << " G0[C]= " << boost::get(vertex_name, G0, vertex(C, G0)) << std::endl;// prints: "G0[C]= C" - std::cout << " G1[A1]= " << boost::get(vertex_name, G1, vertex(A1, G1)) << std::endl;// prints: "G1[A1]= A1" - - name1[B1] = "B1"; - - std::cout << " Global and local properties for vertex G0[E]..." << std::endl; - std::cout << " G0[E]= " << boost::get(vertex_name, G0, vertex(E, G0)) << std::endl;// prints: "G0[E]= E" - std::cout << " G1[B1]= " << boost::get(vertex_name, G1, vertex(B1, G1)) << std::endl;// prints: "G1[B1]= B1" - - name1[C1] = "C1"; - - std::cout << " Global and local properties for vertex G0[F]..." << std::endl; - std::cout << " G0[F]= " << boost::get(vertex_name, G0, vertex(F, G0)) << std::endl;// prints: "G0[F]= F" - std::cout << " G1[C1]= " << boost::get(vertex_name, G1, vertex(C1, G1)) << std::endl;// prints: "G1[C1]= C1" - - Graph& G2 = G0.create_subgraph(); - enum { A2, B2 }; // for conveniently refering to vertices in G2 - - add_vertex(A, G2); // global vertex A becomes local A2 for G2 - add_vertex(C, G2); // global vertex C becomes local B2 for G2 - - property_map::type name2 = get(vertex_name_t(), G2); - name2[A2] = "A2"; - - std::cout << std::endl << std::endl << "After initializing properties for G2:" << std::endl; - std::cout << " Global and local properties for vertex G0[A]" << std::endl; - std::cout << " G0[A]= " << boost::get(vertex_name, G0, vertex(A, G0)) << std::endl;// prints: "G0[A]= A" - std::cout << " G2[A2]= " << boost::get(vertex_name, G2, vertex(A2, G2)) << std::endl;// prints: "G2[A2]= A2" - - name2[B2] = "B2"; - - std::cout << " Global and local properties for vertex G0[C]..." << std::endl; - std::cout << " G0[C]= " << boost::get(vertex_name, G0, vertex(C, G0)) << std::endl;// prints: "G0[C]= C" - std::cout << " G1[A1]= " << boost::get(vertex_name, G1, vertex(A1, G1)) << std::endl;// prints: "G1[A1]= A1" - std::cout << " G2[B2]= " << boost::get(vertex_name, G2, vertex(B2, G2)) << std::endl;// prints: "G2[B2]= B2" - - return 0; + using namespace boost; + // typedef adjacency_list_traits Traits;// Does + // nothing? + typedef property< vertex_color_t, int, + property< vertex_name_t, std::string > > + VertexProperty; + + typedef subgraph< adjacency_list< vecS, vecS, directedS, VertexProperty, + property< edge_index_t, int > > > + Graph; + + const int N = 6; + Graph G0(N); + enum + { + A, + B, + C, + D, + E, + F + }; // for conveniently refering to vertices in G0 + + property_map< Graph, vertex_name_t >::type name = get(vertex_name_t(), G0); + name[A] = "A"; + name[B] = "B"; + name[C] = "C"; + name[D] = "D"; + name[E] = "E"; + name[F] = "F"; + + Graph& G1 = G0.create_subgraph(); + enum + { + A1, + B1, + C1 + }; // for conveniently refering to vertices in G1 + + add_vertex(C, G1); // global vertex C becomes local A1 for G1 + add_vertex(E, G1); // global vertex E becomes local B1 for G1 + add_vertex(F, G1); // global vertex F becomes local C1 for G1 + + property_map< Graph, vertex_name_t >::type name1 = get(vertex_name_t(), G1); + name1[A1] = "A1"; + + std::cout << std::endl + << "After initializing properties for G1:" << std::endl; + std::cout << " Global and local properties for vertex G0[C]..." + << std::endl; + std::cout << " G0[C]= " << boost::get(vertex_name, G0, vertex(C, G0)) + << std::endl; // prints: "G0[C]= C" + std::cout << " G1[A1]= " << boost::get(vertex_name, G1, vertex(A1, G1)) + << std::endl; // prints: "G1[A1]= A1" + + name1[B1] = "B1"; + + std::cout << " Global and local properties for vertex G0[E]..." + << std::endl; + std::cout << " G0[E]= " << boost::get(vertex_name, G0, vertex(E, G0)) + << std::endl; // prints: "G0[E]= E" + std::cout << " G1[B1]= " << boost::get(vertex_name, G1, vertex(B1, G1)) + << std::endl; // prints: "G1[B1]= B1" + + name1[C1] = "C1"; + + std::cout << " Global and local properties for vertex G0[F]..." + << std::endl; + std::cout << " G0[F]= " << boost::get(vertex_name, G0, vertex(F, G0)) + << std::endl; // prints: "G0[F]= F" + std::cout << " G1[C1]= " << boost::get(vertex_name, G1, vertex(C1, G1)) + << std::endl; // prints: "G1[C1]= C1" + + Graph& G2 = G0.create_subgraph(); + enum + { + A2, + B2 + }; // for conveniently refering to vertices in G2 + + add_vertex(A, G2); // global vertex A becomes local A2 for G2 + add_vertex(C, G2); // global vertex C becomes local B2 for G2 + + property_map< Graph, vertex_name_t >::type name2 = get(vertex_name_t(), G2); + name2[A2] = "A2"; + + std::cout << std::endl + << std::endl + << "After initializing properties for G2:" << std::endl; + std::cout << " Global and local properties for vertex G0[A]" << std::endl; + std::cout << " G0[A]= " << boost::get(vertex_name, G0, vertex(A, G0)) + << std::endl; // prints: "G0[A]= A" + std::cout << " G2[A2]= " << boost::get(vertex_name, G2, vertex(A2, G2)) + << std::endl; // prints: "G2[A2]= A2" + + name2[B2] = "B2"; + + std::cout << " Global and local properties for vertex G0[C]..." + << std::endl; + std::cout << " G0[C]= " << boost::get(vertex_name, G0, vertex(C, G0)) + << std::endl; // prints: "G0[C]= C" + std::cout << " G1[A1]= " << boost::get(vertex_name, G1, vertex(A1, G1)) + << std::endl; // prints: "G1[A1]= A1" + std::cout << " G2[B2]= " << boost::get(vertex_name, G2, vertex(B2, G2)) + << std::endl; // prints: "G2[B2]= B2" + + return 0; } diff --git a/example/successive_shortest_path_nonnegative_weights_example.cpp b/example/successive_shortest_path_nonnegative_weights_example.cpp index 0edc3710f..017972038 100644 --- a/example/successive_shortest_path_nonnegative_weights_example.cpp +++ b/example/successive_shortest_path_nonnegative_weights_example.cpp @@ -1,6 +1,6 @@ //======================================================================= // Copyright 2013 University of Warsaw. -// Authors: Piotr Wygocki +// Authors: Piotr Wygocki // // Distributed under the Boost Software License, Version 1.0. (See // accompanying file LICENSE_1_0.txt or copy at @@ -12,19 +12,16 @@ #include "../test/min_cost_max_flow_utils.hpp" - -int main() { - boost::SampleGraph::vertex_descriptor s,t; - boost::SampleGraph::Graph g; +int main() +{ + boost::SampleGraph::vertex_descriptor s, t; + boost::SampleGraph::Graph g; boost::SampleGraph::getSampleGraph(g, s, t); boost::successive_shortest_path_nonnegative_weights(g, s, t); - int cost = boost::find_flow_cost(g); + int cost = boost::find_flow_cost(g); assert(cost == 29); return 0; } - - - diff --git a/example/tiernan_girth_circumference.cpp b/example/tiernan_girth_circumference.cpp index a277a3fd7..a2c36d3e5 100644 --- a/example/tiernan_girth_circumference.cpp +++ b/example/tiernan_girth_circumference.cpp @@ -17,11 +17,10 @@ using namespace boost; // Declare the graph type and its vertex and edge types. typedef directed_graph<> Graph; -typedef graph_traits::vertex_descriptor Vertex; -typedef graph_traits::edge_descriptor Edge; +typedef graph_traits< Graph >::vertex_descriptor Vertex; +typedef graph_traits< Graph >::edge_descriptor Edge; -int -main(int argc, char *argv[]) +int main(int argc, char* argv[]) { // Create the graph and read it from standard input. Graph g; diff --git a/example/tiernan_print_cycles.cpp b/example/tiernan_print_cycles.cpp index c4375615a..0905973a7 100644 --- a/example/tiernan_print_cycles.cpp +++ b/example/tiernan_print_cycles.cpp @@ -19,24 +19,23 @@ using namespace boost; // the cycle. Note that the back() vertex of the path is not the same as // the front(). It is implicit in the listing of vertices that the back() // vertex is connected to the front(). -template -struct cycle_printer +template < typename OutputStream > struct cycle_printer { - cycle_printer(OutputStream& stream) - : os(stream) - { } + cycle_printer(OutputStream& stream) : os(stream) {} - template + template < typename Path, typename Graph > void cycle(const Path& p, const Graph& g) { // Get the property map containing the vertex indices // so we can print them. - typedef typename property_map::const_type IndexMap; + typedef + typename property_map< Graph, vertex_index_t >::const_type IndexMap; IndexMap indices = get(vertex_index, g); // Iterate over path printing each vertex that forms the cycle. typename Path::const_iterator i, end = p.end(); - for(i = p.begin(); i != end; ++i) { + for (i = p.begin(); i != end; ++i) + { os << get(indices, *i) << " "; } os << endl; @@ -46,18 +45,17 @@ struct cycle_printer // Declare the graph type and its vertex and edge types. typedef directed_graph<> Graph; -typedef graph_traits::vertex_descriptor Vertex; -typedef graph_traits::edge_descriptor Edge; +typedef graph_traits< Graph >::vertex_descriptor Vertex; +typedef graph_traits< Graph >::edge_descriptor Edge; -int -main(int argc, char *argv[]) +int main(int argc, char* argv[]) { // Create the graph and read it from standard input. Graph g; read_graph(g, cin); // Instantiate the visitor for printing cycles - cycle_printer vis(cout); + cycle_printer< ostream > vis(cout); // Use the Tiernan algorithm to visit all cycles, printing them // as they are found. diff --git a/example/topo-sort-file-dep.cpp b/example/topo-sort-file-dep.cpp index 00cce78a0..6607e7e93 100644 --- a/example/topo-sort-file-dep.cpp +++ b/example/topo-sort-file-dep.cpp @@ -1,5 +1,5 @@ //======================================================================= -// Copyright 2001 Jeremy G. Siek, Andrew Lumsdaine, Lie-Quan Lee, +// Copyright 2001 Jeremy G. Siek, Andrew Lumsdaine, Lie-Quan Lee, // // Distributed under the Boost Software License, Version 1.0. (See // accompanying file LICENSE_1_0.txt or copy at @@ -16,77 +16,76 @@ using namespace boost; namespace std { - template < typename T > - std::istream & operator >> (std::istream & in, std::pair < T, T > &p) - { +template < typename T > +std::istream& operator>>(std::istream& in, std::pair< T, T >& p) +{ in >> p.first >> p.second; return in; - } +} } -typedef adjacency_list < listS, // Store out-edges of each vertex in a std::list - vecS, // Store vertex set in a std::vector - directedS // The file dependency graph is directed -> file_dep_graph; +typedef adjacency_list< listS, // Store out-edges of each vertex in a std::list + vecS, // Store vertex set in a std::vector + directedS // The file dependency graph is directed + > + file_dep_graph; -typedef graph_traits < file_dep_graph >::vertex_descriptor vertex_t; -typedef graph_traits < file_dep_graph >::edge_descriptor edge_t; +typedef graph_traits< file_dep_graph >::vertex_descriptor vertex_t; +typedef graph_traits< file_dep_graph >::edge_descriptor edge_t; -void -topo_sort_dfs(const file_dep_graph & g, vertex_t u, vertex_t * &topo_order, - int *mark) +void topo_sort_dfs( + const file_dep_graph& g, vertex_t u, vertex_t*& topo_order, int* mark) { - mark[u] = 1; // 1 means visited, 0 means not yet visited - graph_traits < file_dep_graph >::adjacency_iterator vi, vi_end; - for (boost::tie(vi, vi_end) = adjacent_vertices(u, g); vi != vi_end; ++vi) - if (mark[*vi] == 0) - topo_sort_dfs(g, *vi, topo_order, mark); + mark[u] = 1; // 1 means visited, 0 means not yet visited + graph_traits< file_dep_graph >::adjacency_iterator vi, vi_end; + for (boost::tie(vi, vi_end) = adjacent_vertices(u, g); vi != vi_end; ++vi) + if (mark[*vi] == 0) + topo_sort_dfs(g, *vi, topo_order, mark); - *--topo_order = u; + *--topo_order = u; } -void -topo_sort(const file_dep_graph & g, vertex_t * topo_order) +void topo_sort(const file_dep_graph& g, vertex_t* topo_order) { - std::vector < int >mark(num_vertices(g), 0); - graph_traits < file_dep_graph >::vertex_iterator vi, vi_end; - for (boost::tie(vi, vi_end) = vertices(g); vi != vi_end; ++vi) - if (mark[*vi] == 0) - topo_sort_dfs(g, *vi, topo_order, &mark[0]); + std::vector< int > mark(num_vertices(g), 0); + graph_traits< file_dep_graph >::vertex_iterator vi, vi_end; + for (boost::tie(vi, vi_end) = vertices(g); vi != vi_end; ++vi) + if (mark[*vi] == 0) + topo_sort_dfs(g, *vi, topo_order, &mark[0]); } - -int -main(int argc, const char** argv) +int main(int argc, const char** argv) { - std::ifstream file_in(argc >= 2 ? argv[1] : "makefile-dependencies.dat"); - typedef graph_traits < file_dep_graph >::vertices_size_type size_type; - size_type n_vertices; - file_in >> n_vertices; // read in number of vertices - std::istream_iterator < std::pair < size_type, size_type > > - input_begin(file_in), input_end; + std::ifstream file_in(argc >= 2 ? argv[1] : "makefile-dependencies.dat"); + typedef graph_traits< file_dep_graph >::vertices_size_type size_type; + size_type n_vertices; + file_in >> n_vertices; // read in number of vertices + std::istream_iterator< std::pair< size_type, size_type > > input_begin( + file_in), + input_end; #if defined(BOOST_MSVC) && BOOST_MSVC <= 1300 - // VC++ can't handle the iterator constructor - file_dep_graph g(n_vertices); - while (input_begin != input_end) { - size_type i, j; - boost::tie(i, j) = *input_begin++; - add_edge(i, j, g); - } + // VC++ can't handle the iterator constructor + file_dep_graph g(n_vertices); + while (input_begin != input_end) + { + size_type i, j; + boost::tie(i, j) = *input_begin++; + add_edge(i, j, g); + } #else - file_dep_graph g(input_begin, input_end, n_vertices); + file_dep_graph g(input_begin, input_end, n_vertices); #endif - std::vector < std::string > name(num_vertices(g)); - std::ifstream name_in(argc >= 3 ? argv[2] : "makefile-target-names.dat"); - graph_traits < file_dep_graph >::vertex_iterator vi, vi_end; - for (boost::tie(vi, vi_end) = vertices(g); vi != vi_end; ++vi) - name_in >> name[*vi]; + std::vector< std::string > name(num_vertices(g)); + std::ifstream name_in(argc >= 3 ? argv[2] : "makefile-target-names.dat"); + graph_traits< file_dep_graph >::vertex_iterator vi, vi_end; + for (boost::tie(vi, vi_end) = vertices(g); vi != vi_end; ++vi) + name_in >> name[*vi]; - std::vector < vertex_t > order(num_vertices(g)); - topo_sort(g, &order[0] + num_vertices(g)); - for (size_type i = 0; i < num_vertices(g); ++i) - std::cout << name[order[i]] << std::endl; + std::vector< vertex_t > order(num_vertices(g)); + topo_sort(g, &order[0] + num_vertices(g)); + for (size_type i = 0; i < num_vertices(g); ++i) + std::cout << name[order[i]] << std::endl; - return 0; + return 0; } diff --git a/example/topo-sort-file-dep2.cpp b/example/topo-sort-file-dep2.cpp index a7cb2b264..68304b3fe 100644 --- a/example/topo-sort-file-dep2.cpp +++ b/example/topo-sort-file-dep2.cpp @@ -1,5 +1,5 @@ //======================================================================= -// Copyright 2001 Jeremy G. Siek, Andrew Lumsdaine, Lie-Quan Lee, +// Copyright 2001 Jeremy G. Siek, Andrew Lumsdaine, Lie-Quan Lee, // // Distributed under the Boost Software License, Version 1.0. (See // accompanying file LICENSE_1_0.txt or copy at @@ -16,137 +16,119 @@ using namespace boost; namespace std { - template < typename T > - std::istream & - operator >> (std::istream & in, std::pair < T, T > &p) - { +template < typename T > +std::istream& operator>>(std::istream& in, std::pair< T, T >& p) +{ in >> p.first >> p.second; - return - in; - } + return in; +} } -typedef adjacency_list < - listS, // Store out-edges of each vertex in a std::list - vecS, // Store vertex set in a std::vector - directedS // The file dependency graph is directed - > file_dep_graph; +typedef adjacency_list< listS, // Store out-edges of each vertex in a std::list + vecS, // Store vertex set in a std::vector + directedS // The file dependency graph is directed + > + file_dep_graph; -typedef graph_traits ::vertex_descriptor vertex_t; -typedef graph_traits ::edge_descriptor edge_t; +typedef graph_traits< file_dep_graph >::vertex_descriptor vertex_t; +typedef graph_traits< file_dep_graph >::edge_descriptor edge_t; -template < typename Visitor > void -dfs_v1(const file_dep_graph & g, vertex_t u, default_color_type * color, - Visitor vis) +template < typename Visitor > +void dfs_v1( + const file_dep_graph& g, vertex_t u, default_color_type* color, Visitor vis) { - color[u] = gray_color; - vis.discover_vertex(u, g); - graph_traits < file_dep_graph >::out_edge_iterator ei, ei_end; - for (boost::tie(ei, ei_end) = out_edges(u, g); ei != ei_end; ++ei) { - if (color[target(*ei, g)] == white_color) { - vis.tree_edge(*ei, g); - dfs_v1(g, target(*ei, g), color, vis); - } else if (color[target(*ei, g)] == gray_color) - vis.back_edge(*ei, g); - else - vis.forward_or_cross_edge(*ei, g); - } - color[u] = black_color; - vis.finish_vertex(u, g); + color[u] = gray_color; + vis.discover_vertex(u, g); + graph_traits< file_dep_graph >::out_edge_iterator ei, ei_end; + for (boost::tie(ei, ei_end) = out_edges(u, g); ei != ei_end; ++ei) + { + if (color[target(*ei, g)] == white_color) + { + vis.tree_edge(*ei, g); + dfs_v1(g, target(*ei, g), color, vis); + } + else if (color[target(*ei, g)] == gray_color) + vis.back_edge(*ei, g); + else + vis.forward_or_cross_edge(*ei, g); + } + color[u] = black_color; + vis.finish_vertex(u, g); } -template < typename Visitor > void -generic_dfs_v1(const file_dep_graph & g, Visitor vis) +template < typename Visitor > +void generic_dfs_v1(const file_dep_graph& g, Visitor vis) { - std::vector < default_color_type > color(num_vertices(g), white_color); - graph_traits < file_dep_graph >::vertex_iterator vi, vi_end; - for (boost::tie(vi, vi_end) = vertices(g); vi != vi_end; ++vi) { - if (color[*vi] == white_color) - dfs_v1(g, *vi, &color[0], vis); - } + std::vector< default_color_type > color(num_vertices(g), white_color); + graph_traits< file_dep_graph >::vertex_iterator vi, vi_end; + for (boost::tie(vi, vi_end) = vertices(g); vi != vi_end; ++vi) + { + if (color[*vi] == white_color) + dfs_v1(g, *vi, &color[0], vis); + } } struct dfs_visitor_default { - template < typename V, typename G > void - discover_vertex(V, const G &) - { - } - - template < typename E, typename G > void - tree_edge(E, const G &) - { - } - - template < typename E, typename G > void - back_edge(E, const G &) - { - } - - template < typename E, typename G > void - forward_or_cross_edge(E, const G &) - { - } - - template < typename V, typename G > void - finish_vertex(V, const G &) - { - } + template < typename V, typename G > void discover_vertex(V, const G&) {} + + template < typename E, typename G > void tree_edge(E, const G&) {} + + template < typename E, typename G > void back_edge(E, const G&) {} + + template < typename E, typename G > void forward_or_cross_edge(E, const G&) + { + } + + template < typename V, typename G > void finish_vertex(V, const G&) {} }; struct topo_visitor : public dfs_visitor_default { - topo_visitor(vertex_t * &order) : topo_order(order) - { - } - void - finish_vertex(vertex_t u, const file_dep_graph &) - { - *--topo_order = u; - } - vertex_t*& topo_order; + topo_visitor(vertex_t*& order) : topo_order(order) {} + void finish_vertex(vertex_t u, const file_dep_graph&) { *--topo_order = u; } + vertex_t*& topo_order; }; -void -topo_sort(const file_dep_graph & g, vertex_t * topo_order) +void topo_sort(const file_dep_graph& g, vertex_t* topo_order) { - topo_visitor vis(topo_order); - generic_dfs_v1(g, vis); + topo_visitor vis(topo_order); + generic_dfs_v1(g, vis); } - -int -main(int argc, const char** argv) +int main(int argc, const char** argv) { - std::ifstream file_in(argc >= 2 ? argv[1] : "makefile-dependencies.dat"); - typedef graph_traits::vertices_size_type size_type; - size_type n_vertices; - file_in >> n_vertices; // read in number of vertices - std::istream_iterator < std::pair < size_type, - size_type > >input_begin(file_in), input_end; + std::ifstream file_in(argc >= 2 ? argv[1] : "makefile-dependencies.dat"); + typedef graph_traits< file_dep_graph >::vertices_size_type size_type; + size_type n_vertices; + file_in >> n_vertices; // read in number of vertices + std::istream_iterator< std::pair< size_type, size_type > > input_begin( + file_in), + input_end; #if defined(BOOST_MSVC) && BOOST_MSVC <= 1300 - // VC++ can't handle the iterator constructor - file_dep_graph g(n_vertices); - while (input_begin != input_end) { - size_type i, j; - boost::tie(i, j) = *input_begin++; - add_edge(i, j, g); - } + // VC++ can't handle the iterator constructor + file_dep_graph g(n_vertices); + while (input_begin != input_end) + { + size_type i, j; + boost::tie(i, j) = *input_begin++; + add_edge(i, j, g); + } #else - file_dep_graph g(input_begin, input_end, n_vertices); + file_dep_graph g(input_begin, input_end, n_vertices); #endif - std::vector < std::string > name(num_vertices(g)); - std::ifstream name_in(argc >= 2 ? argv[1] : "makefile-target-names.dat"); - graph_traits < file_dep_graph >::vertex_iterator vi, vi_end; - for (boost::tie(vi, vi_end) = vertices(g); vi != vi_end; ++vi) - name_in >> name[*vi]; + std::vector< std::string > name(num_vertices(g)); + std::ifstream name_in(argc >= 2 ? argv[1] : "makefile-target-names.dat"); + graph_traits< file_dep_graph >::vertex_iterator vi, vi_end; + for (boost::tie(vi, vi_end) = vertices(g); vi != vi_end; ++vi) + name_in >> name[*vi]; - std::vector < vertex_t > order(num_vertices(g)); - topo_sort(g, &order[0] + num_vertices(g)); - for (size_type i = 0; i < num_vertices(g); ++i) - std::cout << name[order[i]] << std::endl; + std::vector< vertex_t > order(num_vertices(g)); + topo_sort(g, &order[0] + num_vertices(g)); + for (size_type i = 0; i < num_vertices(g); ++i) + std::cout << name[order[i]] << std::endl; - return 0; + return 0; } diff --git a/example/topo-sort-with-leda.cpp b/example/topo-sort-with-leda.cpp index cd24b76e3..42c07e2ea 100644 --- a/example/topo-sort-with-leda.cpp +++ b/example/topo-sort-with-leda.cpp @@ -1,5 +1,5 @@ //======================================================================= -// Copyright 2001 Jeremy G. Siek, Andrew Lumsdaine, Lie-Quan Lee, +// Copyright 2001 Jeremy G. Siek, Andrew Lumsdaine, Lie-Quan Lee, // // Distributed under the Boost Software License, Version 1.0. (See // accompanying file LICENSE_1_0.txt or copy at @@ -13,42 +13,41 @@ #undef string #undef vector -int -main() +int main() { - using namespace boost; - typedef GRAPH < std::string, char >graph_t; - graph_t leda_g; - typedef graph_traits < graph_t >::vertex_descriptor vertex_t; - std::vector < vertex_t > vert(7); - vert[0] = add_vertex(std::string("pick up kids from school"), leda_g); - vert[1] = add_vertex(std::string("buy groceries (and snacks)"), leda_g); - vert[2] = add_vertex(std::string("get cash at ATM"), leda_g); - vert[3] = - add_vertex(std::string("drop off kids at soccer practice"), leda_g); - vert[4] = add_vertex(std::string("cook dinner"), leda_g); - vert[5] = add_vertex(std::string("pick up kids from soccer"), leda_g); - vert[6] = add_vertex(std::string("eat dinner"), leda_g); + using namespace boost; + typedef GRAPH< std::string, char > graph_t; + graph_t leda_g; + typedef graph_traits< graph_t >::vertex_descriptor vertex_t; + std::vector< vertex_t > vert(7); + vert[0] = add_vertex(std::string("pick up kids from school"), leda_g); + vert[1] = add_vertex(std::string("buy groceries (and snacks)"), leda_g); + vert[2] = add_vertex(std::string("get cash at ATM"), leda_g); + vert[3] + = add_vertex(std::string("drop off kids at soccer practice"), leda_g); + vert[4] = add_vertex(std::string("cook dinner"), leda_g); + vert[5] = add_vertex(std::string("pick up kids from soccer"), leda_g); + vert[6] = add_vertex(std::string("eat dinner"), leda_g); - add_edge(vert[0], vert[3], leda_g); - add_edge(vert[1], vert[3], leda_g); - add_edge(vert[1], vert[4], leda_g); - add_edge(vert[2], vert[1], leda_g); - add_edge(vert[3], vert[5], leda_g); - add_edge(vert[4], vert[6], leda_g); - add_edge(vert[5], vert[6], leda_g); + add_edge(vert[0], vert[3], leda_g); + add_edge(vert[1], vert[3], leda_g); + add_edge(vert[1], vert[4], leda_g); + add_edge(vert[2], vert[1], leda_g); + add_edge(vert[3], vert[5], leda_g); + add_edge(vert[4], vert[6], leda_g); + add_edge(vert[5], vert[6], leda_g); - std::vector < vertex_t > topo_order; - node_array < default_color_type > color_array(leda_g); + std::vector< vertex_t > topo_order; + node_array< default_color_type > color_array(leda_g); - topological_sort(leda_g, std::back_inserter(topo_order), - color_map(make_leda_node_property_map(color_array))); + topological_sort(leda_g, std::back_inserter(topo_order), + color_map(make_leda_node_property_map(color_array))); - std::reverse(topo_order.begin(), topo_order.end()); - int n = 1; - for (std::vector < vertex_t >::iterator i = topo_order.begin(); - i != topo_order.end(); ++i, ++n) - std::cout << n << ": " << leda_g[*i] << std::endl; + std::reverse(topo_order.begin(), topo_order.end()); + int n = 1; + for (std::vector< vertex_t >::iterator i = topo_order.begin(); + i != topo_order.end(); ++i, ++n) + std::cout << n << ": " << leda_g[*i] << std::endl; - return EXIT_SUCCESS; + return EXIT_SUCCESS; } diff --git a/example/topo-sort-with-sgb.cpp b/example/topo-sort-with-sgb.cpp index b7d9ae661..7453c3d3b 100644 --- a/example/topo-sort-with-sgb.cpp +++ b/example/topo-sort-with-sgb.cpp @@ -1,5 +1,5 @@ //======================================================================= -// Copyright 2001 Jeremy G. Siek, Andrew Lumsdaine, Lie-Quan Lee, +// Copyright 2001 Jeremy G. Siek, Andrew Lumsdaine, Lie-Quan Lee, // // Distributed under the Boost Software License, Version 1.0. (See // accompanying file LICENSE_1_0.txt or copy at @@ -11,41 +11,36 @@ #include #include -int -main() +int main() { - using namespace boost; - const int n_vertices = 7; - Graph *sgb_g = gb_new_graph(n_vertices); + using namespace boost; + const int n_vertices = 7; + Graph* sgb_g = gb_new_graph(n_vertices); - const char *tasks[] = { - "pick up kids from school", - "buy groceries (and snacks)", - "get cash at ATM", - "drop off kids at soccer practice", - "cook dinner", - "pick up kids from soccer", - "eat dinner" - }; - const int n_tasks = sizeof(tasks) / sizeof(char *); + const char* tasks[] + = { "pick up kids from school", "buy groceries (and snacks)", + "get cash at ATM", "drop off kids at soccer practice", + "cook dinner", "pick up kids from soccer", "eat dinner" }; + const int n_tasks = sizeof(tasks) / sizeof(char*); - gb_new_arc(sgb_g->vertices + 0, sgb_g->vertices + 3, 0); - gb_new_arc(sgb_g->vertices + 1, sgb_g->vertices + 3, 0); - gb_new_arc(sgb_g->vertices + 1, sgb_g->vertices + 4, 0); - gb_new_arc(sgb_g->vertices + 2, sgb_g->vertices + 1, 0); - gb_new_arc(sgb_g->vertices + 3, sgb_g->vertices + 5, 0); - gb_new_arc(sgb_g->vertices + 4, sgb_g->vertices + 6, 0); - gb_new_arc(sgb_g->vertices + 5, sgb_g->vertices + 6, 0); + gb_new_arc(sgb_g->vertices + 0, sgb_g->vertices + 3, 0); + gb_new_arc(sgb_g->vertices + 1, sgb_g->vertices + 3, 0); + gb_new_arc(sgb_g->vertices + 1, sgb_g->vertices + 4, 0); + gb_new_arc(sgb_g->vertices + 2, sgb_g->vertices + 1, 0); + gb_new_arc(sgb_g->vertices + 3, sgb_g->vertices + 5, 0); + gb_new_arc(sgb_g->vertices + 4, sgb_g->vertices + 6, 0); + gb_new_arc(sgb_g->vertices + 5, sgb_g->vertices + 6, 0); - typedef graph_traits < Graph * >::vertex_descriptor vertex_t; - std::vector < vertex_t > topo_order; - topological_sort(sgb_g, std::back_inserter(topo_order), - vertex_index_map(get(vertex_index, sgb_g))); - int n = 1; - for (std::vector < vertex_t >::reverse_iterator i = topo_order.rbegin(); - i != topo_order.rend(); ++i, ++n) - std::cout << n << ": " << tasks[get(vertex_index, sgb_g)[*i]] << std::endl; + typedef graph_traits< Graph* >::vertex_descriptor vertex_t; + std::vector< vertex_t > topo_order; + topological_sort(sgb_g, std::back_inserter(topo_order), + vertex_index_map(get(vertex_index, sgb_g))); + int n = 1; + for (std::vector< vertex_t >::reverse_iterator i = topo_order.rbegin(); + i != topo_order.rend(); ++i, ++n) + std::cout << n << ": " << tasks[get(vertex_index, sgb_g)[*i]] + << std::endl; - gb_recycle(sgb_g); - return EXIT_SUCCESS; + gb_recycle(sgb_g); + return EXIT_SUCCESS; } diff --git a/example/topo-sort1.cpp b/example/topo-sort1.cpp index 90c98a2d9..6579d0e04 100644 --- a/example/topo-sort1.cpp +++ b/example/topo-sort1.cpp @@ -1,50 +1,44 @@ //======================================================================= -// Copyright 2001 Jeremy G. Siek, Andrew Lumsdaine, Lie-Quan Lee, +// Copyright 2001 Jeremy G. Siek, Andrew Lumsdaine, Lie-Quan Lee, // // Distributed under the Boost Software License, Version 1.0. (See // accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) //======================================================================= -#include // to store the vertex ordering +#include // to store the vertex ordering #include #include #include #include #include -int -main() +int main() { - using namespace boost; - const char *tasks[] = { - "pick up kids from school", - "buy groceries (and snacks)", - "get cash at ATM", - "drop off kids at soccer practice", - "cook dinner", - "pick up kids from soccer", - "eat dinner" - }; - const int n_tasks = sizeof(tasks) / sizeof(char *); + using namespace boost; + const char* tasks[] + = { "pick up kids from school", "buy groceries (and snacks)", + "get cash at ATM", "drop off kids at soccer practice", + "cook dinner", "pick up kids from soccer", "eat dinner" }; + const int n_tasks = sizeof(tasks) / sizeof(char*); - std::vector < std::list < int > > g(n_tasks); - g[0].push_back(3); - g[1].push_back(3); - g[1].push_back(4); - g[2].push_back(1); - g[3].push_back(5); - g[4].push_back(6); - g[5].push_back(6); + std::vector< std::list< int > > g(n_tasks); + g[0].push_back(3); + g[1].push_back(3); + g[1].push_back(4); + g[2].push_back(1); + g[3].push_back(5); + g[4].push_back(6); + g[5].push_back(6); - std::deque < int >topo_order; + std::deque< int > topo_order; - topological_sort(g, std::front_inserter(topo_order), - vertex_index_map(identity_property_map())); + topological_sort(g, std::front_inserter(topo_order), + vertex_index_map(identity_property_map())); - int n = 1; - for (std::deque < int >::iterator i = topo_order.begin(); - i != topo_order.end(); ++i, ++n) - std::cout << tasks[*i] << std::endl; + int n = 1; + for (std::deque< int >::iterator i = topo_order.begin(); + i != topo_order.end(); ++i, ++n) + std::cout << tasks[*i] << std::endl; - return EXIT_SUCCESS; + return EXIT_SUCCESS; } diff --git a/example/topo-sort2.cpp b/example/topo-sort2.cpp index 4663181ef..80aa3412b 100644 --- a/example/topo-sort2.cpp +++ b/example/topo-sort2.cpp @@ -1,5 +1,5 @@ //======================================================================= -// Copyright 2001 Jeremy G. Siek, Andrew Lumsdaine, Lie-Quan Lee, +// Copyright 2001 Jeremy G. Siek, Andrew Lumsdaine, Lie-Quan Lee, // // Distributed under the Boost Software License, Version 1.0. (See // accompanying file LICENSE_1_0.txt or copy at @@ -11,40 +11,34 @@ #include #include #include -int -main() +int main() { - using namespace boost; - const char *tasks[] = { - "pick up kids from school", - "buy groceries (and snacks)", - "get cash at ATM", - "drop off kids at soccer practice", - "cook dinner", - "pick up kids from soccer", - "eat dinner" - }; - const int n_tasks = sizeof(tasks) / sizeof(char *); + using namespace boost; + const char* tasks[] + = { "pick up kids from school", "buy groceries (and snacks)", + "get cash at ATM", "drop off kids at soccer practice", + "cook dinner", "pick up kids from soccer", "eat dinner" }; + const int n_tasks = sizeof(tasks) / sizeof(char*); - adjacency_list < listS, vecS, directedS > g(n_tasks); + adjacency_list< listS, vecS, directedS > g(n_tasks); - add_edge(0, 3, g); - add_edge(1, 3, g); - add_edge(1, 4, g); - add_edge(2, 1, g); - add_edge(3, 5, g); - add_edge(4, 6, g); - add_edge(5, 6, g); + add_edge(0, 3, g); + add_edge(1, 3, g); + add_edge(1, 4, g); + add_edge(2, 1, g); + add_edge(3, 5, g); + add_edge(4, 6, g); + add_edge(5, 6, g); - std::deque < int >topo_order; + std::deque< int > topo_order; - topological_sort(g, std::front_inserter(topo_order), - vertex_index_map(identity_property_map())); + topological_sort(g, std::front_inserter(topo_order), + vertex_index_map(identity_property_map())); - int n = 1; - for (std::deque < int >::iterator i = topo_order.begin(); - i != topo_order.end(); ++i, ++n) - std::cout << tasks[*i] << std::endl; + int n = 1; + for (std::deque< int >::iterator i = topo_order.begin(); + i != topo_order.end(); ++i, ++n) + std::cout << tasks[*i] << std::endl; - return EXIT_SUCCESS; + return EXIT_SUCCESS; } diff --git a/example/topo_sort.cpp b/example/topo_sort.cpp index 124db6a2d..38dc4667c 100644 --- a/example/topo_sort.cpp +++ b/example/topo_sort.cpp @@ -15,8 +15,7 @@ #include #include - -typedef std::pair Pair; +typedef std::pair< std::size_t, std::size_t > Pair; /* Topological sort example @@ -31,44 +30,41 @@ typedef std::pair Pair; */ -int -main(int , char* []) +int main(int, char*[]) { - //begin - using namespace boost; + // begin + using namespace boost; - /* Topological sort will need to color the graph. Here we use an - internal decorator, so we "property" the color to the graph. - */ - typedef adjacency_list > Graph; + /* Topological sort will need to color the graph. Here we use an + internal decorator, so we "property" the color to the graph. + */ + typedef adjacency_list< vecS, vecS, directedS, + property< vertex_color_t, default_color_type > > + Graph; - typedef boost::graph_traits::vertex_descriptor Vertex; - Pair edges[6] = { Pair(0,1), Pair(2,4), - Pair(2,5), - Pair(0,3), Pair(1,4), - Pair(4,3) }; + typedef boost::graph_traits< Graph >::vertex_descriptor Vertex; + Pair edges[6] = { Pair(0, 1), Pair(2, 4), Pair(2, 5), Pair(0, 3), + Pair(1, 4), Pair(4, 3) }; #if defined(BOOST_MSVC) && BOOST_MSVC <= 1300 - // VC++ can't handle the iterator constructor - Graph G(6); - for (std::size_t j = 0; j < 6; ++j) - add_edge(edges[j].first, edges[j].second, G); + // VC++ can't handle the iterator constructor + Graph G(6); + for (std::size_t j = 0; j < 6; ++j) + add_edge(edges[j].first, edges[j].second, G); #else - Graph G(edges, edges + 6, 6); + Graph G(edges, edges + 6, 6); #endif - boost::property_map::type id = get(vertex_index, G); - - typedef std::vector< Vertex > container; - container c; - topological_sort(G, std::back_inserter(c)); + boost::property_map< Graph, vertex_index_t >::type id + = get(vertex_index, G); - std::cout << "A topological ordering: "; - for (container::reverse_iterator ii = c.rbegin(); - ii != c.rend(); ++ii) - std::cout << id[*ii] << " "; - std::cout << std::endl; + typedef std::vector< Vertex > container; + container c; + topological_sort(G, std::back_inserter(c)); - return 0; -} + std::cout << "A topological ordering: "; + for (container::reverse_iterator ii = c.rbegin(); ii != c.rend(); ++ii) + std::cout << id[*ii] << " "; + std::cout << std::endl; + return 0; +} diff --git a/example/topo_sort.expected b/example/topo_sort.expected index aeb3f41fe..ab0d6ec06 100644 --- a/example/topo_sort.expected +++ b/example/topo_sort.expected @@ -1 +1 @@ -A topological ordering: 2 5 0 1 4 3 +A topological ordering: 2 5 0 1 4 3 diff --git a/example/transitive_closure.cpp b/example/transitive_closure.cpp index 2b99cdb96..1699071e8 100644 --- a/example/transitive_closure.cpp +++ b/example/transitive_closure.cpp @@ -14,37 +14,36 @@ #include #include -int -main(int, char *[]) +int main(int, char*[]) { - using namespace boost; - typedef property < vertex_name_t, char >Name; - typedef property < vertex_index_t, std::size_t, Name > Index; - typedef adjacency_list < listS, listS, directedS, Index > graph_t; - typedef graph_traits < graph_t >::vertex_descriptor vertex_t; - graph_t G; - std::vector < vertex_t > verts(4); - for (int i = 0; i < 4; ++i) - verts[i] = add_vertex(Index(i, Name('a' + i)), G); - add_edge(verts[1], verts[2], G); - add_edge(verts[1], verts[3], G); - add_edge(verts[2], verts[1], G); - add_edge(verts[3], verts[2], G); - add_edge(verts[3], verts[0], G); - - std::cout << "Graph G:" << std::endl; - print_graph(G, get(vertex_name, G)); - - adjacency_list <> TC; - transitive_closure(G, TC); - - std::cout << std::endl << "Graph G+:" << std::endl; - char name[] = "abcd"; - print_graph(TC, name); - std::cout << std::endl; - - std::ofstream out("tc-out.dot"); - write_graphviz(out, TC, make_label_writer(name)); - - return 0; + using namespace boost; + typedef property< vertex_name_t, char > Name; + typedef property< vertex_index_t, std::size_t, Name > Index; + typedef adjacency_list< listS, listS, directedS, Index > graph_t; + typedef graph_traits< graph_t >::vertex_descriptor vertex_t; + graph_t G; + std::vector< vertex_t > verts(4); + for (int i = 0; i < 4; ++i) + verts[i] = add_vertex(Index(i, Name('a' + i)), G); + add_edge(verts[1], verts[2], G); + add_edge(verts[1], verts[3], G); + add_edge(verts[2], verts[1], G); + add_edge(verts[3], verts[2], G); + add_edge(verts[3], verts[0], G); + + std::cout << "Graph G:" << std::endl; + print_graph(G, get(vertex_name, G)); + + adjacency_list<> TC; + transitive_closure(G, TC); + + std::cout << std::endl << "Graph G+:" << std::endl; + char name[] = "abcd"; + print_graph(TC, name); + std::cout << std::endl; + + std::ofstream out("tc-out.dot"); + write_graphviz(out, TC, make_label_writer(name)); + + return 0; } diff --git a/example/transpose-example.cpp b/example/transpose-example.cpp index 7378dd195..618a288b7 100644 --- a/example/transpose-example.cpp +++ b/example/transpose-example.cpp @@ -1,5 +1,5 @@ //======================================================================= -// Copyright 2001 Jeremy G. Siek, Andrew Lumsdaine, Lie-Quan Lee, +// Copyright 2001 Jeremy G. Siek, Andrew Lumsdaine, Lie-Quan Lee, // // Distributed under the Boost Software License, Version 1.0. (See // accompanying file LICENSE_1_0.txt or copy at @@ -11,39 +11,47 @@ #include #include -int -main() +int main() { - using namespace boost; - typedef adjacency_list < vecS, vecS, bidirectionalS, - property < vertex_name_t, char > > graph_t; + using namespace boost; + typedef adjacency_list< vecS, vecS, bidirectionalS, + property< vertex_name_t, char > > + graph_t; - enum { a, b, c, d, e, f, g, N }; - graph_t G(N); - property_map < graph_t, vertex_name_t >::type - name_map = get(vertex_name, G); - char name = 'a'; - graph_traits < graph_t >::vertex_iterator v, v_end; - for (boost::tie(v, v_end) = vertices(G); v != v_end; ++v, ++name) - name_map[*v] = name; + enum + { + a, + b, + c, + d, + e, + f, + g, + N + }; + graph_t G(N); + property_map< graph_t, vertex_name_t >::type name_map = get(vertex_name, G); + char name = 'a'; + graph_traits< graph_t >::vertex_iterator v, v_end; + for (boost::tie(v, v_end) = vertices(G); v != v_end; ++v, ++name) + name_map[*v] = name; - typedef std::pair < int, int >E; - E edge_array[] = { E(a, c), E(a, d), E(b, a), E(b, d), E(c, f), - E(d, c), E(d, e), E(d, f), E(e, b), E(e, g), E(f, e), E(f, g) - }; - for (int i = 0; i < 12; ++i) - add_edge(edge_array[i].first, edge_array[i].second, G); + typedef std::pair< int, int > E; + E edge_array[] = { E(a, c), E(a, d), E(b, a), E(b, d), E(c, f), E(d, c), + E(d, e), E(d, f), E(e, b), E(e, g), E(f, e), E(f, g) }; + for (int i = 0; i < 12; ++i) + add_edge(edge_array[i].first, edge_array[i].second, G); - print_graph(G, name_map); - std::cout << std::endl; + print_graph(G, name_map); + std::cout << std::endl; - graph_t G_T; - transpose_graph(G, G_T); + graph_t G_T; + transpose_graph(G, G_T); - print_graph(G_T, name_map); + print_graph(G_T, name_map); - graph_traits < graph_t >::edge_iterator ei, ei_end; - for (boost::tie(ei, ei_end) = edges(G); ei != ei_end; ++ei) - assert(edge(target(*ei, G), source(*ei, G), G_T).second == true); - return 0; + graph_traits< graph_t >::edge_iterator ei, ei_end; + for (boost::tie(ei, ei_end) = edges(G); ei != ei_end; ++ei) + assert(edge(target(*ei, G), source(*ei, G), G_T).second == true); + return 0; } diff --git a/example/two_graphs_common_spanning_trees.cpp b/example/two_graphs_common_spanning_trees.cpp index 2fa851798..824556dbe 100644 --- a/example/two_graphs_common_spanning_trees.cpp +++ b/example/two_graphs_common_spanning_trees.cpp @@ -8,87 +8,65 @@ // Efficient Algorithm for Common Spanning Tree Problem // Electron. Lett., 28 April 1983, Volume 19, Issue 9, p.346-347 - #include #include #include #include - using namespace std; -typedef -boost::adjacency_list - < - boost::vecS, // OutEdgeList - boost::vecS, // VertexList - boost::undirectedS, // Directed - boost::no_property, // VertexProperties - boost::no_property, // EdgeProperties - boost::no_property, // GraphProperties - boost::listS // EdgeList - > -Graph -; +typedef boost::adjacency_list< boost::vecS, // OutEdgeList + boost::vecS, // VertexList + boost::undirectedS, // Directed + boost::no_property, // VertexProperties + boost::no_property, // EdgeProperties + boost::no_property, // GraphProperties + boost::listS // EdgeList + > + Graph; -typedef -boost::graph_traits::vertex_descriptor -vertex_descriptor; +typedef boost::graph_traits< Graph >::vertex_descriptor vertex_descriptor; -typedef -boost::graph_traits::edge_descriptor -edge_descriptor; +typedef boost::graph_traits< Graph >::edge_descriptor edge_descriptor; -typedef -boost::graph_traits::vertex_iterator -vertex_iterator; +typedef boost::graph_traits< Graph >::vertex_iterator vertex_iterator; -typedef -boost::graph_traits::edge_iterator -edge_iterator; +typedef boost::graph_traits< Graph >::edge_iterator edge_iterator; - -int main(int argc, char **argv) +int main(int argc, char** argv) { - Graph iG, vG; - vector< edge_descriptor > iG_o; - vector< edge_descriptor > vG_o; - - iG_o.push_back(boost::add_edge(0, 1, iG).first); - iG_o.push_back(boost::add_edge(0, 2, iG).first); - iG_o.push_back(boost::add_edge(0, 3, iG).first); - iG_o.push_back(boost::add_edge(0, 4, iG).first); - iG_o.push_back(boost::add_edge(1, 2, iG).first); - iG_o.push_back(boost::add_edge(3, 4, iG).first); - - vG_o.push_back(boost::add_edge(1, 2, vG).first); - vG_o.push_back(boost::add_edge(2, 0, vG).first); - vG_o.push_back(boost::add_edge(2, 3, vG).first); - vG_o.push_back(boost::add_edge(4, 3, vG).first); - vG_o.push_back(boost::add_edge(0, 3, vG).first); - vG_o.push_back(boost::add_edge(0, 4, vG).first); - - vector inL(iG_o.size(), false); - - std::vector< std::vector > coll; - boost::tree_collector< - std::vector< std::vector >, - std::vector - > tree_collector(coll); - boost::two_graphs_common_spanning_trees - ( - iG, - iG_o, - vG, - vG_o, - tree_collector, - inL - ); - - std::vector< std::vector >::iterator it; - for(it = coll.begin(); it != coll.end(); ++it) { - // Here you can play with the trees that the algorithm has found. - } - - return 0; + Graph iG, vG; + vector< edge_descriptor > iG_o; + vector< edge_descriptor > vG_o; + + iG_o.push_back(boost::add_edge(0, 1, iG).first); + iG_o.push_back(boost::add_edge(0, 2, iG).first); + iG_o.push_back(boost::add_edge(0, 3, iG).first); + iG_o.push_back(boost::add_edge(0, 4, iG).first); + iG_o.push_back(boost::add_edge(1, 2, iG).first); + iG_o.push_back(boost::add_edge(3, 4, iG).first); + + vG_o.push_back(boost::add_edge(1, 2, vG).first); + vG_o.push_back(boost::add_edge(2, 0, vG).first); + vG_o.push_back(boost::add_edge(2, 3, vG).first); + vG_o.push_back(boost::add_edge(4, 3, vG).first); + vG_o.push_back(boost::add_edge(0, 3, vG).first); + vG_o.push_back(boost::add_edge(0, 4, vG).first); + + vector< bool > inL(iG_o.size(), false); + + std::vector< std::vector< bool > > coll; + boost::tree_collector< std::vector< std::vector< bool > >, + std::vector< bool > > + tree_collector(coll); + boost::two_graphs_common_spanning_trees( + iG, iG_o, vG, vG_o, tree_collector, inL); + + std::vector< std::vector< bool > >::iterator it; + for (it = coll.begin(); it != coll.end(); ++it) + { + // Here you can play with the trees that the algorithm has found. + } + + return 0; } diff --git a/example/undirected_adjacency_list.cpp b/example/undirected_adjacency_list.cpp index 49d312021..9e3601493 100644 --- a/example/undirected_adjacency_list.cpp +++ b/example/undirected_adjacency_list.cpp @@ -1,5 +1,5 @@ //======================================================================= -// Copyright 2001 Jeremy G. Siek, Andrew Lumsdaine, Lie-Quan Lee, +// Copyright 2001 Jeremy G. Siek, Andrew Lumsdaine, Lie-Quan Lee, // // Distributed under the Boost Software License, Version 1.0. (See // accompanying file LICENSE_1_0.txt or copy at @@ -10,108 +10,104 @@ #include using namespace boost; -template < typename UndirectedGraph > void -undirected_graph_demo1() +template < typename UndirectedGraph > void undirected_graph_demo1() { - const int V = 3; - UndirectedGraph undigraph(V); - typename graph_traits < UndirectedGraph >::vertex_descriptor zero, one, two; - typename graph_traits < UndirectedGraph >::out_edge_iterator out, out_end; - typename graph_traits < UndirectedGraph >::in_edge_iterator in, in_end; + const int V = 3; + UndirectedGraph undigraph(V); + typename graph_traits< UndirectedGraph >::vertex_descriptor zero, one, two; + typename graph_traits< UndirectedGraph >::out_edge_iterator out, out_end; + typename graph_traits< UndirectedGraph >::in_edge_iterator in, in_end; - zero = vertex(0, undigraph); - one = vertex(1, undigraph); - two = vertex(2, undigraph); - add_edge(zero, one, undigraph); - add_edge(zero, two, undigraph); - add_edge(one, two, undigraph); + zero = vertex(0, undigraph); + one = vertex(1, undigraph); + two = vertex(2, undigraph); + add_edge(zero, one, undigraph); + add_edge(zero, two, undigraph); + add_edge(one, two, undigraph); - std::cout << "out_edges(0):"; - for (boost::tie(out, out_end) = out_edges(zero, undigraph); out != out_end; ++out) - std::cout << ' ' << *out; - std::cout << std::endl << "in_edges(0):"; - for (boost::tie(in, in_end) = in_edges(zero, undigraph); in != in_end; ++in) - std::cout << ' ' << *in; - std::cout << std::endl; + std::cout << "out_edges(0):"; + for (boost::tie(out, out_end) = out_edges(zero, undigraph); out != out_end; + ++out) + std::cout << ' ' << *out; + std::cout << std::endl << "in_edges(0):"; + for (boost::tie(in, in_end) = in_edges(zero, undigraph); in != in_end; ++in) + std::cout << ' ' << *in; + std::cout << std::endl; } -template < typename DirectedGraph > void -directed_graph_demo() +template < typename DirectedGraph > void directed_graph_demo() { - const int V = 2; - DirectedGraph digraph(V); - typename graph_traits < DirectedGraph >::vertex_descriptor u, v; - typedef typename DirectedGraph::edge_property_type Weight; - typename property_map < DirectedGraph, edge_weight_t >::type - weight = get(edge_weight, digraph); - typename graph_traits < DirectedGraph >::edge_descriptor e1, e2; - bool found; + const int V = 2; + DirectedGraph digraph(V); + typename graph_traits< DirectedGraph >::vertex_descriptor u, v; + typedef typename DirectedGraph::edge_property_type Weight; + typename property_map< DirectedGraph, edge_weight_t >::type weight + = get(edge_weight, digraph); + typename graph_traits< DirectedGraph >::edge_descriptor e1, e2; + bool found; - u = vertex(0, digraph); - v = vertex(1, digraph); - add_edge(u, v, Weight(1.2), digraph); - add_edge(v, u, Weight(2.4), digraph); - boost::tie(e1, found) = edge(u, v, digraph); - boost::tie(e2, found) = edge(v, u, digraph); - std::cout << "in a directed graph is "; + u = vertex(0, digraph); + v = vertex(1, digraph); + add_edge(u, v, Weight(1.2), digraph); + add_edge(v, u, Weight(2.4), digraph); + boost::tie(e1, found) = edge(u, v, digraph); + boost::tie(e2, found) = edge(v, u, digraph); + std::cout << "in a directed graph is "; #ifdef __GNUC__ - // no boolalpha - std::cout << "(u,v) == (v,u) ? " << (e1 == e2) << std::endl; + // no boolalpha + std::cout << "(u,v) == (v,u) ? " << (e1 == e2) << std::endl; #else - std::cout << "(u,v) == (v,u) ? " - << std::boolalpha << (e1 == e2) << std::endl; + std::cout << "(u,v) == (v,u) ? " << std::boolalpha << (e1 == e2) + << std::endl; #endif - std::cout << "weight[(u,v)] = " << get(weight, e1) << std::endl; - std::cout << "weight[(v,u)] = " << get(weight, e2) << std::endl; + std::cout << "weight[(u,v)] = " << get(weight, e1) << std::endl; + std::cout << "weight[(v,u)] = " << get(weight, e2) << std::endl; } -template < typename UndirectedGraph > void -undirected_graph_demo2() +template < typename UndirectedGraph > void undirected_graph_demo2() { - const int V = 2; - UndirectedGraph undigraph(V); - typename graph_traits < UndirectedGraph >::vertex_descriptor u, v; - typedef typename UndirectedGraph::edge_property_type Weight; - typename property_map < UndirectedGraph, edge_weight_t >::type - weight = get(edge_weight, undigraph); - typename graph_traits < UndirectedGraph >::edge_descriptor e1, e2; - bool found; + const int V = 2; + UndirectedGraph undigraph(V); + typename graph_traits< UndirectedGraph >::vertex_descriptor u, v; + typedef typename UndirectedGraph::edge_property_type Weight; + typename property_map< UndirectedGraph, edge_weight_t >::type weight + = get(edge_weight, undigraph); + typename graph_traits< UndirectedGraph >::edge_descriptor e1, e2; + bool found; - u = vertex(0, undigraph); - v = vertex(1, undigraph); - add_edge(u, v, Weight(3.1), undigraph); - boost::tie(e1, found) = edge(u, v, undigraph); - boost::tie(e2, found) = edge(v, u, undigraph); - std::cout << "in an undirected graph is "; + u = vertex(0, undigraph); + v = vertex(1, undigraph); + add_edge(u, v, Weight(3.1), undigraph); + boost::tie(e1, found) = edge(u, v, undigraph); + boost::tie(e2, found) = edge(v, u, undigraph); + std::cout << "in an undirected graph is "; #ifdef __GNUC__ - std::cout << "(u,v) == (v,u) ? " << (e1 == e2) << std::endl; + std::cout << "(u,v) == (v,u) ? " << (e1 == e2) << std::endl; #else - std::cout << "(u,v) == (v,u) ? " - << std::boolalpha << (e1 == e2) << std::endl; + std::cout << "(u,v) == (v,u) ? " << std::boolalpha << (e1 == e2) + << std::endl; #endif - std::cout << "weight[(u,v)] = " << get(weight, e1) << std::endl; - std::cout << "weight[(v,u)] = " << get(weight, e2) << std::endl; + std::cout << "weight[(u,v)] = " << get(weight, e1) << std::endl; + std::cout << "weight[(v,u)] = " << get(weight, e2) << std::endl; - std::cout << "the edges incident to v: "; - typename boost::graph_traits::out_edge_iterator e, e_end; - typename boost::graph_traits::vertex_descriptor - s = vertex(0, undigraph); - for (boost::tie(e, e_end) = out_edges(s, undigraph); e != e_end; ++e) - std::cout << "(" << source(*e, undigraph) - << "," << target(*e, undigraph) << ")" << std::endl; + std::cout << "the edges incident to v: "; + typename boost::graph_traits< UndirectedGraph >::out_edge_iterator e, e_end; + typename boost::graph_traits< UndirectedGraph >::vertex_descriptor s + = vertex(0, undigraph); + for (boost::tie(e, e_end) = out_edges(s, undigraph); e != e_end; ++e) + std::cout << "(" << source(*e, undigraph) << "," + << target(*e, undigraph) << ")" << std::endl; } - -int -main() +int main() { - typedef property < edge_weight_t, double >Weight; - typedef adjacency_list < vecS, vecS, undirectedS, - no_property, Weight > UndirectedGraph; - typedef adjacency_list < vecS, vecS, directedS, - no_property, Weight > DirectedGraph; - undirected_graph_demo1 < UndirectedGraph > (); - directed_graph_demo < DirectedGraph > (); - undirected_graph_demo2 < UndirectedGraph > (); - return 0; + typedef property< edge_weight_t, double > Weight; + typedef adjacency_list< vecS, vecS, undirectedS, no_property, Weight > + UndirectedGraph; + typedef adjacency_list< vecS, vecS, directedS, no_property, Weight > + DirectedGraph; + undirected_graph_demo1< UndirectedGraph >(); + directed_graph_demo< DirectedGraph >(); + undirected_graph_demo2< UndirectedGraph >(); + return 0; } diff --git a/example/undirected_dfs.cpp b/example/undirected_dfs.cpp index bc314d39b..05ce6e7ac 100644 --- a/example/undirected_dfs.cpp +++ b/example/undirected_dfs.cpp @@ -1,5 +1,5 @@ //======================================================================= -// Copyright 2002 Jeremy G. Siek, Andrew Lumsdaine, Lie-Quan Lee, +// Copyright 2002 Jeremy G. Siek, Andrew Lumsdaine, Lie-Quan Lee, // // Distributed under the Boost Software License, Version 1.0. (See // accompanying file LICENSE_1_0.txt or copy at @@ -28,53 +28,52 @@ H12 */ -std::string name[] = { "C0", "C1", "C2", "C3", "C4", "C5", "C6", "O7", - "H8", "H9", "H10", "H11", "H12", "H13", "H14", "H15"}; - +std::string name[] = { "C0", "C1", "C2", "C3", "C4", "C5", "C6", "O7", "H8", + "H9", "H10", "H11", "H12", "H13", "H14", "H15" }; struct detect_loops : public boost::dfs_visitor<> { - template - void back_edge(Edge e, const Graph& g) { - std::cout << name[source(e, g)] - << " -- " - << name[target(e, g)] << "\n"; - } + template < class Edge, class Graph > void back_edge(Edge e, const Graph& g) + { + std::cout << name[source(e, g)] << " -- " << name[target(e, g)] << "\n"; + } }; int main(int, char*[]) { - using namespace boost; - typedef adjacency_list< vecS, vecS, undirectedS, - no_property, - property > graph_t; - typedef graph_traits::vertex_descriptor vertex_t; - - const std::size_t N = sizeof(name)/sizeof(std::string); - graph_t g(N); - - add_edge(0, 1, g); - add_edge(0, 8, g); - add_edge(0, 9, g); - add_edge(0, 10, g); - add_edge(1, 2, g); - add_edge(1, 6, g); - add_edge(2, 15, g); - add_edge(2, 3, g); - add_edge(3, 7, g); - add_edge(3, 4, g); - add_edge(4, 13, g); - add_edge(4, 5, g); - add_edge(5, 12, g); - add_edge(5, 6, g); - add_edge(6, 11, g); - add_edge(7, 14, g); - - std::cout << "back edges:\n"; - detect_loops vis; - undirected_dfs(g, root_vertex(vertex_t(0)).visitor(vis) - .edge_color_map(get(edge_color, g))); - std::cout << std::endl; - - return boost::exit_success; + using namespace boost; + typedef adjacency_list< vecS, vecS, undirectedS, no_property, + property< edge_color_t, default_color_type > > + graph_t; + typedef graph_traits< graph_t >::vertex_descriptor vertex_t; + + const std::size_t N = sizeof(name) / sizeof(std::string); + graph_t g(N); + + add_edge(0, 1, g); + add_edge(0, 8, g); + add_edge(0, 9, g); + add_edge(0, 10, g); + add_edge(1, 2, g); + add_edge(1, 6, g); + add_edge(2, 15, g); + add_edge(2, 3, g); + add_edge(3, 7, g); + add_edge(3, 4, g); + add_edge(4, 13, g); + add_edge(4, 5, g); + add_edge(5, 12, g); + add_edge(5, 6, g); + add_edge(6, 11, g); + add_edge(7, 14, g); + + std::cout << "back edges:\n"; + detect_loops vis; + undirected_dfs(g, + root_vertex(vertex_t(0)) + .visitor(vis) + .edge_color_map(get(edge_color, g))); + std::cout << std::endl; + + return boost::exit_success; } diff --git a/example/undirected_graph.cpp b/example/undirected_graph.cpp index d926c7b51..0c0365ceb 100644 --- a/example/undirected_graph.cpp +++ b/example/undirected_graph.cpp @@ -10,21 +10,21 @@ #include #include -typedef boost::undirected_graph Graph; +typedef boost::undirected_graph< boost::no_property > Graph; -int main(int,char*[]) +int main(int, char*[]) { - // Create a graph object - Graph g; + // Create a graph object + Graph g; - // Add vertices - boost::graph_traits::vertex_descriptor v0 = g.add_vertex(); - boost::graph_traits::vertex_descriptor v1 = g.add_vertex(); - boost::graph_traits::vertex_descriptor v2 = g.add_vertex(); + // Add vertices + boost::graph_traits< Graph >::vertex_descriptor v0 = g.add_vertex(); + boost::graph_traits< Graph >::vertex_descriptor v1 = g.add_vertex(); + boost::graph_traits< Graph >::vertex_descriptor v2 = g.add_vertex(); - // Add edges - g.add_edge(v0, v1); - g.add_edge(v1, v2); + // Add edges + g.add_edge(v0, v1); + g.add_edge(v1, v2); - return 0; + return 0; } diff --git a/example/vector_as_graph.cpp b/example/vector_as_graph.cpp index ccf6abeb6..f9e785ed3 100644 --- a/example/vector_as_graph.cpp +++ b/example/vector_as_graph.cpp @@ -1,5 +1,5 @@ //======================================================================= -// Copyright 2001 Jeremy G. Siek, Andrew Lumsdaine, Lie-Quan Lee, +// Copyright 2001 Jeremy G. Siek, Andrew Lumsdaine, Lie-Quan Lee, // // Distributed under the Boost Software License, Version 1.0. (See // accompanying file LICENSE_1_0.txt or copy at @@ -16,24 +16,33 @@ #include #include -int -main() +int main() { - enum - { r, s, t, u, v, w, x, y, N }; - char name[] = "rstuvwxy"; - typedef std::vector < std::list < int > > Graph; - Graph g(N); - g[r].push_back(v); - g[s].push_back(r); - g[s].push_back(r); - g[s].push_back(w); - g[t].push_back(x); - g[u].push_back(t); - g[w].push_back(t); - g[w].push_back(x); - g[x].push_back(y); - g[y].push_back(u); - boost::print_graph(g, name); - return 0; + enum + { + r, + s, + t, + u, + v, + w, + x, + y, + N + }; + char name[] = "rstuvwxy"; + typedef std::vector< std::list< int > > Graph; + Graph g(N); + g[r].push_back(v); + g[s].push_back(r); + g[s].push_back(r); + g[s].push_back(w); + g[t].push_back(x); + g[u].push_back(t); + g[w].push_back(t); + g[w].push_back(x); + g[x].push_back(y); + g[y].push_back(u); + boost::print_graph(g, name); + return 0; } diff --git a/example/vector_as_graph.expected b/example/vector_as_graph.expected index 1f7287947..a41a4d4a1 100644 --- a/example/vector_as_graph.expected +++ b/example/vector_as_graph.expected @@ -1,2 +1,2 @@ -order of discovery: s r w v t x y u -order of finish: s r w v t x y u +order of discovery: s r w v t x y u +order of finish: s r w v t x y u diff --git a/example/vertex-name-property.cpp b/example/vertex-name-property.cpp index 7ae44d4f3..c1a3b0b70 100644 --- a/example/vertex-name-property.cpp +++ b/example/vertex-name-property.cpp @@ -1,5 +1,5 @@ //======================================================================= -// Copyright 2001 Jeremy G. Siek, Andrew Lumsdaine, Lie-Quan Lee, +// Copyright 2001 Jeremy G. Siek, Andrew Lumsdaine, Lie-Quan Lee, // // Distributed under the Boost Software License, Version 1.0. (See // accompanying file LICENSE_1_0.txt or copy at @@ -13,68 +13,74 @@ using namespace boost; -template < typename Graph, typename VertexNamePropertyMap > void -read_graph_file(std::istream & graph_in, std::istream & name_in, - Graph & g, VertexNamePropertyMap name_map) +template < typename Graph, typename VertexNamePropertyMap > +void read_graph_file(std::istream& graph_in, std::istream& name_in, Graph& g, + VertexNamePropertyMap name_map) { - typedef typename graph_traits < Graph >::vertices_size_type size_type; - size_type n_vertices; - typename graph_traits < Graph >::vertex_descriptor u; - typename property_traits < VertexNamePropertyMap >::value_type name; + typedef typename graph_traits< Graph >::vertices_size_type size_type; + size_type n_vertices; + typename graph_traits< Graph >::vertex_descriptor u; + typename property_traits< VertexNamePropertyMap >::value_type name; - graph_in >> n_vertices; // read in number of vertices - for (size_type i = 0; i < n_vertices; ++i) { // Add n vertices to the graph - u = add_vertex(g); - name_in >> name; - put(name_map, u, name); // ** Attach name property to vertex u ** - } - size_type src, targ; - while (graph_in >> src) // Read in edges - if (graph_in >> targ) - add_edge(src, targ, g); // add an edge to the graph - else - break; + graph_in >> n_vertices; // read in number of vertices + for (size_type i = 0; i < n_vertices; ++i) + { // Add n vertices to the graph + u = add_vertex(g); + name_in >> name; + put(name_map, u, name); // ** Attach name property to vertex u ** + } + size_type src, targ; + while (graph_in >> src) // Read in edges + if (graph_in >> targ) + add_edge(src, targ, g); // add an edge to the graph + else + break; } - -int -main(int argc, const char** argv) +int main(int argc, const char** argv) { - typedef adjacency_list < listS, // Store out-edges of each vertex in a std::list - vecS, // Store vertex set in a std::vector - directedS, // The graph is directed - property < vertex_name_t, std::string > // Add a vertex property - >graph_type; + typedef adjacency_list< listS, // Store out-edges of each vertex in a + // std::list + vecS, // Store vertex set in a std::vector + directedS, // The graph is directed + property< vertex_name_t, std::string > // Add a vertex property + > + graph_type; - graph_type g; // use default constructor to create empty graph - const char* dep_file_name = argc >= 2 ? argv[1] : "makefile-dependencies.dat"; - const char* target_file_name = argc >= 3 ? argv[2] : "makefile-target-names.dat"; - std::ifstream file_in(dep_file_name), name_in(target_file_name); - if (!file_in) { - std::cerr << "** Error: could not open file " << dep_file_name - << std::endl; - return -1; - } - if (!name_in) { - std::cerr << "** Error: could not open file " << target_file_name - << std::endl; - return -1; - } + graph_type g; // use default constructor to create empty graph + const char* dep_file_name + = argc >= 2 ? argv[1] : "makefile-dependencies.dat"; + const char* target_file_name + = argc >= 3 ? argv[2] : "makefile-target-names.dat"; + std::ifstream file_in(dep_file_name), name_in(target_file_name); + if (!file_in) + { + std::cerr << "** Error: could not open file " << dep_file_name + << std::endl; + return -1; + } + if (!name_in) + { + std::cerr << "** Error: could not open file " << target_file_name + << std::endl; + return -1; + } - // Obtain internal property map from the graph - property_map < graph_type, vertex_name_t >::type name_map = - get(vertex_name, g); - read_graph_file(file_in, name_in, g, name_map); + // Obtain internal property map from the graph + property_map< graph_type, vertex_name_t >::type name_map + = get(vertex_name, g); + read_graph_file(file_in, name_in, g, name_map); - // Create storage for last modified times - std::vector < time_t > last_mod_vec(num_vertices(g)); - // Create nickname for the property map type - typedef iterator_property_map < std::vector < time_t >::iterator, - property_map < graph_type, vertex_index_t >::type, time_t, time_t& > iter_map_t; - // Create last modified time property map - iter_map_t mod_time_map(last_mod_vec.begin(), get(vertex_index, g)); + // Create storage for last modified times + std::vector< time_t > last_mod_vec(num_vertices(g)); + // Create nickname for the property map type + typedef iterator_property_map< std::vector< time_t >::iterator, + property_map< graph_type, vertex_index_t >::type, time_t, time_t& > + iter_map_t; + // Create last modified time property map + iter_map_t mod_time_map(last_mod_vec.begin(), get(vertex_index, g)); - assert(num_vertices(g) == 15); - assert(num_edges(g) == 19); - return 0; + assert(num_vertices(g) == 15); + assert(num_edges(g) == 19); + return 0; } diff --git a/example/vertex_basics.cpp b/example/vertex_basics.cpp index 8d2053fbc..107fd5ebc 100644 --- a/example/vertex_basics.cpp +++ b/example/vertex_basics.cpp @@ -15,7 +15,6 @@ using namespace std; using namespace boost; - /* Vertex Basics @@ -23,137 +22,133 @@ using namespace boost; Sample output: - vertices(g) = 0 1 2 3 4 + vertices(g) = 0 1 2 3 4 vertex id: 0 - out-edges: (0,1) (0,2) (0,3) (0,4) - in-edges: (2,0) (3,0) (4,0) - adjacent vertices: 1 2 3 4 + out-edges: (0,1) (0,2) (0,3) (0,4) + in-edges: (2,0) (3,0) (4,0) + adjacent vertices: 1 2 3 4 vertex id: 1 - out-edges: - in-edges: (0,1) (3,1) (4,1) - adjacent vertices: + out-edges: + in-edges: (0,1) (3,1) (4,1) + adjacent vertices: vertex id: 2 - out-edges: (2,0) (2,4) - in-edges: (0,2) - adjacent vertices: 0 4 + out-edges: (2,0) (2,4) + in-edges: (0,2) + adjacent vertices: 0 4 vertex id: 3 - out-edges: (3,0) (3,1) (3,4) - in-edges: (0,3) - adjacent vertices: 0 1 4 + out-edges: (3,0) (3,1) (3,4) + in-edges: (0,3) + adjacent vertices: 0 1 4 vertex id: 4 - out-edges: (4,0) (4,1) - in-edges: (0,4) (2,4) (3,4) - adjacent vertices: 0 1 + out-edges: (4,0) (4,1) + in-edges: (0,4) (2,4) (3,4) + adjacent vertices: 0 1 */ - /* some helper functors for output */ -template -struct print_edge { - print_edge(Graph& g) : G(g) { } +template < class Graph > struct print_edge +{ + print_edge(Graph& g) : G(g) {} - typedef typename boost::graph_traits::edge_descriptor Edge; - typedef typename boost::graph_traits::vertex_descriptor Vertex; - void operator()(Edge e) const - { - typename boost::property_map::type - id = get(vertex_index, G); + typedef typename boost::graph_traits< Graph >::edge_descriptor Edge; + typedef typename boost::graph_traits< Graph >::vertex_descriptor Vertex; + void operator()(Edge e) const + { + typename boost::property_map< Graph, vertex_index_t >::type id + = get(vertex_index, G); - Vertex src = source(e, G); - Vertex targ = target(e, G); + Vertex src = source(e, G); + Vertex targ = target(e, G); - cout << "(" << id[src] << "," << id[targ] << ") "; - } + cout << "(" << id[src] << "," << id[targ] << ") "; + } - Graph& G; + Graph& G; }; -template -struct print_index { - print_index(Graph& g) : G(g){ } +template < class Graph > struct print_index +{ + print_index(Graph& g) : G(g) {} - typedef typename boost::graph_traits::vertex_descriptor Vertex; - void operator()(Vertex c) const - { - typename boost::property_map::type - id = get(vertex_index, G); - cout << id[c] << " "; - } + typedef typename boost::graph_traits< Graph >::vertex_descriptor Vertex; + void operator()(Vertex c) const + { + typename boost::property_map< Graph, vertex_index_t >::type id + = get(vertex_index, G); + cout << id[c] << " "; + } - Graph& G; + Graph& G; }; +template < class Graph > struct exercise_vertex +{ + typedef typename boost::graph_traits< Graph >::vertex_descriptor Vertex; -template -struct exercise_vertex { - typedef typename boost::graph_traits::vertex_descriptor Vertex; + exercise_vertex(Graph& _g) : g(_g) {} - exercise_vertex(Graph& _g) : g(_g) { } + void operator()(Vertex v) const + { + typename boost::property_map< Graph, vertex_index_t >::type id + = get(vertex_index, g); - void operator()(Vertex v) const - { - typename boost::property_map::type - id = get(vertex_index, g); + cout << "vertex id: " << id[v] << endl; - cout << "vertex id: " << id[v] << endl; - - cout << "out-edges: "; - for_each(out_edges(v, g).first, out_edges(v,g).second, - print_edge(g)); + cout << "out-edges: "; + for_each(out_edges(v, g).first, out_edges(v, g).second, + print_edge< Graph >(g)); - cout << endl; + cout << endl; - cout << "in-edges: "; - for_each(in_edges(v, g).first, in_edges(v,g).second, - print_edge(g)); + cout << "in-edges: "; + for_each(in_edges(v, g).first, in_edges(v, g).second, + print_edge< Graph >(g)); - cout << endl; - - cout << "adjacent vertices: "; - for_each(adjacent_vertices(v,g).first, - adjacent_vertices(v,g).second, print_index(g)); - cout << endl << endl; - } + cout << endl; - Graph& g; -}; + cout << "adjacent vertices: "; + for_each(adjacent_vertices(v, g).first, adjacent_vertices(v, g).second, + print_index< Graph >(g)); + cout << endl << endl; + } + Graph& g; +}; -int -main() +int main() { - typedef adjacency_list MyGraphType; + typedef adjacency_list< vecS, vecS, bidirectionalS > MyGraphType; - typedef pair Pair; - Pair edge_array[11] = { Pair(0,1), Pair(0,2), Pair(0,3), Pair(0,4), - Pair(2,0), Pair(3,0), Pair(2,4), Pair(3,1), - Pair(3,4), Pair(4,0), Pair(4,1) }; + typedef pair< int, int > Pair; + Pair edge_array[11] = { Pair(0, 1), Pair(0, 2), Pair(0, 3), Pair(0, 4), + Pair(2, 0), Pair(3, 0), Pair(2, 4), Pair(3, 1), Pair(3, 4), Pair(4, 0), + Pair(4, 1) }; - /* Construct a graph using the edge_array*/ - MyGraphType g(5); - for (int i=0; i<11; ++i) - add_edge(edge_array[i].first, edge_array[i].second, g); + /* Construct a graph using the edge_array*/ + MyGraphType g(5); + for (int i = 0; i < 11; ++i) + add_edge(edge_array[i].first, edge_array[i].second, g); - boost::property_map::type - id = get(vertex_index, g); + boost::property_map< MyGraphType, vertex_index_t >::type id + = get(vertex_index, g); - cout << "vertices(g) = "; - boost::graph_traits::vertex_iterator vi; - for (vi = vertices(g).first; vi != vertices(g).second; ++vi) - std::cout << id[*vi] << " "; - std::cout << std::endl; + cout << "vertices(g) = "; + boost::graph_traits< MyGraphType >::vertex_iterator vi; + for (vi = vertices(g).first; vi != vertices(g).second; ++vi) + std::cout << id[*vi] << " "; + std::cout << std::endl; - /* Use the STL for_each algorithm to "exercise" all - of the vertices in the graph */ - for_each(vertices(g).first, vertices(g).second, - exercise_vertex(g)); + /* Use the STL for_each algorithm to "exercise" all + of the vertices in the graph */ + for_each(vertices(g).first, vertices(g).second, + exercise_vertex< MyGraphType >(g)); - return 0; + return 0; } diff --git a/example/vertex_basics.expected b/example/vertex_basics.expected index 96a103d96..69012bfae 100644 --- a/example/vertex_basics.expected +++ b/example/vertex_basics.expected @@ -1,26 +1,26 @@ -vertices(g) = 0 1 2 3 4 +vertices(g) = 0 1 2 3 4 vertex id: 0 -out-edges: (0,1) (0,2) (0,3) (0,4) -in-edges: (2,0) (3,0) (4,0) -adjacent vertices: 1 2 3 4 +out-edges: (0,1) (0,2) (0,3) (0,4) +in-edges: (2,0) (3,0) (4,0) +adjacent vertices: 1 2 3 4 vertex id: 1 -out-edges: -in-edges: (0,1) (3,1) (4,1) -adjacent vertices: +out-edges: +in-edges: (0,1) (3,1) (4,1) +adjacent vertices: vertex id: 2 -out-edges: (2,0) (2,4) -in-edges: (0,2) -adjacent vertices: 0 4 +out-edges: (2,0) (2,4) +in-edges: (0,2) +adjacent vertices: 0 4 vertex id: 3 -out-edges: (3,0) (3,1) (3,4) -in-edges: (0,3) -adjacent vertices: 0 1 4 +out-edges: (3,0) (3,1) (3,4) +in-edges: (0,3) +adjacent vertices: 0 1 4 vertex id: 4 -out-edges: (4,0) (4,1) -in-edges: (0,4) (2,4) (3,4) -adjacent vertices: 0 1 +out-edges: (4,0) (4,1) +in-edges: (0,4) (2,4) (3,4) +adjacent vertices: 0 1 diff --git a/example/vf2_sub_graph_iso_example.cpp b/example/vf2_sub_graph_iso_example.cpp index 8e17d2a70..613cb6967 100644 --- a/example/vf2_sub_graph_iso_example.cpp +++ b/example/vf2_sub_graph_iso_example.cpp @@ -10,31 +10,43 @@ #include using namespace boost; - -int main() { - - typedef adjacency_list graph_type; - - // Build graph1 - int num_vertices1 = 8; graph_type graph1(num_vertices1); - add_edge(0, 6, graph1); add_edge(0, 7, graph1); - add_edge(1, 5, graph1); add_edge(1, 7, graph1); - add_edge(2, 4, graph1); add_edge(2, 5, graph1); add_edge(2, 6, graph1); - add_edge(3, 4, graph1); - - // Build graph2 - int num_vertices2 = 9; graph_type graph2(num_vertices2); - add_edge(0, 6, graph2); add_edge(0, 8, graph2); - add_edge(1, 5, graph2); add_edge(1, 7, graph2); - add_edge(2, 4, graph2); add_edge(2, 7, graph2); add_edge(2, 8, graph2); - add_edge(3, 4, graph2); add_edge(3, 5, graph2); add_edge(3, 6, graph2); - - // Create callback to print mappings - vf2_print_callback callback(graph1, graph2); - - // Print out all subgraph isomorphism mappings between graph1 and graph2. - // Vertices and edges are assumed to be always equivalent. - vf2_subgraph_iso(graph1, graph2, callback); - - return 0; +int main() +{ + + typedef adjacency_list< setS, vecS, bidirectionalS > graph_type; + + // Build graph1 + int num_vertices1 = 8; + graph_type graph1(num_vertices1); + add_edge(0, 6, graph1); + add_edge(0, 7, graph1); + add_edge(1, 5, graph1); + add_edge(1, 7, graph1); + add_edge(2, 4, graph1); + add_edge(2, 5, graph1); + add_edge(2, 6, graph1); + add_edge(3, 4, graph1); + + // Build graph2 + int num_vertices2 = 9; + graph_type graph2(num_vertices2); + add_edge(0, 6, graph2); + add_edge(0, 8, graph2); + add_edge(1, 5, graph2); + add_edge(1, 7, graph2); + add_edge(2, 4, graph2); + add_edge(2, 7, graph2); + add_edge(2, 8, graph2); + add_edge(3, 4, graph2); + add_edge(3, 5, graph2); + add_edge(3, 6, graph2); + + // Create callback to print mappings + vf2_print_callback< graph_type, graph_type > callback(graph1, graph2); + + // Print out all subgraph isomorphism mappings between graph1 and graph2. + // Vertices and edges are assumed to be always equivalent. + vf2_subgraph_iso(graph1, graph2, callback); + + return 0; } diff --git a/example/vf2_sub_graph_iso_multi_example.cpp b/example/vf2_sub_graph_iso_multi_example.cpp index 6f9e34a2a..330fe28c8 100644 --- a/example/vf2_sub_graph_iso_multi_example.cpp +++ b/example/vf2_sub_graph_iso_multi_example.cpp @@ -10,80 +10,86 @@ #include using namespace boost; -int main() { - typedef property edge_property; - typedef property > vertex_property; - - // Using a vecS graphs => the index maps are implicit. - typedef adjacency_list graph_type; - - // Build graph1 - graph_type graph1; - - add_vertex(vertex_property('a'), graph1); - add_vertex(vertex_property('a'), graph1); - add_vertex(vertex_property('a'), graph1); - - add_edge(0, 1, edge_property('b'), graph1); - add_edge(0, 1, edge_property('b'), graph1); - add_edge(0, 1, edge_property('d'), graph1); - - add_edge(1, 2, edge_property('s'), graph1); - - add_edge(2, 2, edge_property('l'), graph1); - add_edge(2, 2, edge_property('l'), graph1); - - // Build graph2 - graph_type graph2; - - add_vertex(vertex_property('a'), graph2); - add_vertex(vertex_property('a'), graph2); - add_vertex(vertex_property('a'), graph2); - add_vertex(vertex_property('a'), graph2); - add_vertex(vertex_property('a'), graph2); - add_vertex(vertex_property('a'), graph2); - - add_edge(0, 1, edge_property('a'), graph2); - add_edge(0, 1, edge_property('a'), graph2); - add_edge(0, 1, edge_property('b'), graph2); - - add_edge(1, 2, edge_property('s'), graph2); - - add_edge(2, 3, edge_property('b'), graph2); - add_edge(2, 3, edge_property('d'), graph2); - add_edge(2, 3, edge_property('b'), graph2); - - add_edge(3, 4, edge_property('s'), graph2); - - add_edge(4, 4, edge_property('l'), graph2); - add_edge(4, 4, edge_property('l'), graph2); - - add_edge(4, 5, edge_property('c'), graph2); - add_edge(4, 5, edge_property('c'), graph2); - add_edge(4, 5, edge_property('c'), graph2); - - add_edge(5, 0, edge_property('s'), graph2); - - // create predicates - typedef property_map::type vertex_name_map_t; - typedef property_map_equivalent vertex_comp_t; - vertex_comp_t vertex_comp = - make_property_map_equivalent(get(vertex_name, graph1), get(vertex_name, graph2)); - - typedef property_map::type edge_name_map_t; - typedef property_map_equivalent edge_comp_t; - edge_comp_t edge_comp = - make_property_map_equivalent(get(edge_name, graph1), get(edge_name, graph2)); - - // Create callback - vf2_print_callback callback(graph1, graph2); - - // Print out all subgraph isomorphism mappings between graph1 and graph2. - // Function vertex_order_by_mult is used to compute the order of - // vertices of graph1. This is the order in which the vertices are examined - // during the matching process. - vf2_subgraph_iso(graph1, graph2, callback, vertex_order_by_mult(graph1), - edges_equivalent(edge_comp).vertices_equivalent(vertex_comp)); - - return 0; +int main() +{ + typedef property< edge_name_t, char > edge_property; + typedef property< vertex_name_t, char, property< vertex_index_t, int > > + vertex_property; + + // Using a vecS graphs => the index maps are implicit. + typedef adjacency_list< vecS, vecS, bidirectionalS, vertex_property, + edge_property > + graph_type; + + // Build graph1 + graph_type graph1; + + add_vertex(vertex_property('a'), graph1); + add_vertex(vertex_property('a'), graph1); + add_vertex(vertex_property('a'), graph1); + + add_edge(0, 1, edge_property('b'), graph1); + add_edge(0, 1, edge_property('b'), graph1); + add_edge(0, 1, edge_property('d'), graph1); + + add_edge(1, 2, edge_property('s'), graph1); + + add_edge(2, 2, edge_property('l'), graph1); + add_edge(2, 2, edge_property('l'), graph1); + + // Build graph2 + graph_type graph2; + + add_vertex(vertex_property('a'), graph2); + add_vertex(vertex_property('a'), graph2); + add_vertex(vertex_property('a'), graph2); + add_vertex(vertex_property('a'), graph2); + add_vertex(vertex_property('a'), graph2); + add_vertex(vertex_property('a'), graph2); + + add_edge(0, 1, edge_property('a'), graph2); + add_edge(0, 1, edge_property('a'), graph2); + add_edge(0, 1, edge_property('b'), graph2); + + add_edge(1, 2, edge_property('s'), graph2); + + add_edge(2, 3, edge_property('b'), graph2); + add_edge(2, 3, edge_property('d'), graph2); + add_edge(2, 3, edge_property('b'), graph2); + + add_edge(3, 4, edge_property('s'), graph2); + + add_edge(4, 4, edge_property('l'), graph2); + add_edge(4, 4, edge_property('l'), graph2); + + add_edge(4, 5, edge_property('c'), graph2); + add_edge(4, 5, edge_property('c'), graph2); + add_edge(4, 5, edge_property('c'), graph2); + + add_edge(5, 0, edge_property('s'), graph2); + + // create predicates + typedef property_map< graph_type, vertex_name_t >::type vertex_name_map_t; + typedef property_map_equivalent< vertex_name_map_t, vertex_name_map_t > + vertex_comp_t; + vertex_comp_t vertex_comp = make_property_map_equivalent( + get(vertex_name, graph1), get(vertex_name, graph2)); + + typedef property_map< graph_type, edge_name_t >::type edge_name_map_t; + typedef property_map_equivalent< edge_name_map_t, edge_name_map_t > + edge_comp_t; + edge_comp_t edge_comp = make_property_map_equivalent( + get(edge_name, graph1), get(edge_name, graph2)); + + // Create callback + vf2_print_callback< graph_type, graph_type > callback(graph1, graph2); + + // Print out all subgraph isomorphism mappings between graph1 and graph2. + // Function vertex_order_by_mult is used to compute the order of + // vertices of graph1. This is the order in which the vertices are examined + // during the matching process. + vf2_subgraph_iso(graph1, graph2, callback, vertex_order_by_mult(graph1), + edges_equivalent(edge_comp).vertices_equivalent(vertex_comp)); + + return 0; } diff --git a/example/visitor.cpp b/example/visitor.cpp index cd5b4f5a8..8620c1165 100644 --- a/example/visitor.cpp +++ b/example/visitor.cpp @@ -47,61 +47,56 @@ using namespace boost; using namespace std; -template -struct edge_printer : public base_visitor > { - typedef Tag event_filter; - edge_printer(std::string edge_t) : m_edge_type(edge_t) { } - template - void operator()(Edge e, Graph& G) { - std::cout << m_edge_type << ": " << source(e, G) - << " --> " << target(e, G) << std::endl; - } - std::string m_edge_type; +template < class Tag > +struct edge_printer : public base_visitor< edge_printer< Tag > > +{ + typedef Tag event_filter; + edge_printer(std::string edge_t) : m_edge_type(edge_t) {} + template < class Edge, class Graph > void operator()(Edge e, Graph& G) + { + std::cout << m_edge_type << ": " << source(e, G) << " --> " + << target(e, G) << std::endl; + } + std::string m_edge_type; }; -template -edge_printer print_edge(std::string type, Tag) { - return edge_printer(type); +template < class Tag > edge_printer< Tag > print_edge(std::string type, Tag) +{ + return edge_printer< Tag >(type); } -int -main(int, char*[]) +int main(int, char*[]) { - using namespace boost; - - typedef adjacency_list<> Graph; - typedef std::pair E; - E edges[] = { E(0, 2), - E(1, 1), E(1, 3), - E(2, 1), E(2, 3), - E(3, 1), E(3, 4), - E(4, 0), E(4, 1) }; + using namespace boost; + + typedef adjacency_list<> Graph; + typedef std::pair< int, int > E; + E edges[] = { E(0, 2), E(1, 1), E(1, 3), E(2, 1), E(2, 3), E(3, 1), E(3, 4), + E(4, 0), E(4, 1) }; #if defined(BOOST_MSVC) && BOOST_MSVC <= 1300 - Graph G(5); - for (std::size_t j = 0; j < sizeof(edges)/sizeof(E); ++j) - add_edge(edges[j].first, edges[j].second, G); + Graph G(5); + for (std::size_t j = 0; j < sizeof(edges) / sizeof(E); ++j) + add_edge(edges[j].first, edges[j].second, G); #else - Graph G(edges, edges + sizeof(edges)/sizeof(E), 5); + Graph G(edges, edges + sizeof(edges) / sizeof(E), 5); #endif - typedef boost::graph_traits::vertices_size_type size_type; - - std::vector d(num_vertices(G)); - std::vector f(num_vertices(G)); + typedef boost::graph_traits< Graph >::vertices_size_type size_type; - cout << "DFS categorized directed graph" << endl; - depth_first_search(G, visitor(make_dfs_visitor( - make_list(print_edge("tree", on_tree_edge()), - print_edge("back", on_back_edge()), - print_edge("forward or cross", on_forward_or_cross_edge()) - )))); + std::vector< size_type > d(num_vertices(G)); + std::vector< size_type > f(num_vertices(G)); - cout << endl << "BFS categorized directed graph" << endl; - boost::breadth_first_search - (G, vertex(0, G), visitor(make_bfs_visitor( - std::make_pair(print_edge("tree", on_tree_edge()), - print_edge("cycle", on_non_tree_edge()))))); + cout << "DFS categorized directed graph" << endl; + depth_first_search(G, + visitor(make_dfs_visitor(make_list(print_edge("tree", on_tree_edge()), + print_edge("back", on_back_edge()), + print_edge("forward or cross", on_forward_or_cross_edge()))))); - return 0; -} + cout << endl << "BFS categorized directed graph" << endl; + boost::breadth_first_search(G, vertex(0, G), + visitor( + make_bfs_visitor(std::make_pair(print_edge("tree", on_tree_edge()), + print_edge("cycle", on_non_tree_edge()))))); + return 0; +} diff --git a/example/weighted_matching_example.cpp b/example/weighted_matching_example.cpp index 026394cf9..50fe5d50c 100644 --- a/example/weighted_matching_example.cpp +++ b/example/weighted_matching_example.cpp @@ -15,17 +15,20 @@ using namespace boost; -typedef property > EdgeProperty; -typedef adjacency_list my_graph; +typedef property< edge_weight_t, float, property< edge_index_t, int > > + EdgeProperty; +typedef adjacency_list< vecS, vecS, undirectedS, no_property, EdgeProperty > + my_graph; -int main(int argc, const char * argv[]) +int main(int argc, const char* argv[]) { - graph_traits::vertex_iterator vi, vi_end; + graph_traits< my_graph >::vertex_iterator vi, vi_end; const int n_vertices = 18; my_graph g(n_vertices); - - // vertices can be refered by integers because my_graph use vector to store them - + + // vertices can be refered by integers because my_graph use vector to store + // them + add_edge(1, 2, EdgeProperty(5), g); add_edge(0, 4, EdgeProperty(1), g); add_edge(1, 5, EdgeProperty(4), g); @@ -45,14 +48,13 @@ int main(int argc, const char * argv[]) add_edge(14, 15, EdgeProperty(6), g); add_edge(12, 13, EdgeProperty(2), g); add_edge(16, 17, EdgeProperty(5), g); - - + // print the ascii graph into terminal (better to use fixed-width font) // this graph has a maximum cardinality matching of size 8 // but maximum weighted matching is of size 7 - - std::vector ascii_graph_weighted; - + + std::vector< std::string > ascii_graph_weighted; + ascii_graph_weighted.push_back(" 5 "); ascii_graph_weighted.push_back(" A B---C D "); ascii_graph_weighted.push_back(" 1\\ 7 /4 1\\ 5 /4 "); @@ -62,51 +64,58 @@ int main(int argc, const char * argv[]) ascii_graph_weighted.push_back(" 4/ 3\\ 7/ 4 \\6 "); ascii_graph_weighted.push_back(" M---N O---P Q---R "); ascii_graph_weighted.push_back(" 2 6 5 "); - - + // our maximum weighted matching and result - + std::cout << "In the following graph:" << std::endl << std::endl; - - for(std::vector::iterator itr = ascii_graph_weighted.begin(); itr != ascii_graph_weighted.end(); ++itr) + + for (std::vector< std::string >::iterator itr + = ascii_graph_weighted.begin(); + itr != ascii_graph_weighted.end(); ++itr) std::cout << *itr << std::endl; - + std::cout << std::endl; - - std::vector::vertex_descriptor> mate1(n_vertices), mate2(n_vertices); + + std::vector< graph_traits< my_graph >::vertex_descriptor > mate1( + n_vertices), + mate2(n_vertices); maximum_weighted_matching(g, &mate1[0]); - + std::cout << "Found a weighted matching:" << std::endl; - std::cout << "Matching size is " << matching_size(g, &mate1[0]) << ", total weight is " << matching_weight_sum(g, &mate1[0]) << std::endl; + std::cout << "Matching size is " << matching_size(g, &mate1[0]) + << ", total weight is " << matching_weight_sum(g, &mate1[0]) + << std::endl; std::cout << std::endl; - + std::cout << "The matching is:" << std::endl; - for (boost::tie(vi,vi_end) = vertices(g); vi != vi_end; ++vi) - if (mate1[*vi] != graph_traits::null_vertex() && *vi < mate1[*vi]) + for (boost::tie(vi, vi_end) = vertices(g); vi != vi_end; ++vi) + if (mate1[*vi] != graph_traits< my_graph >::null_vertex() + && *vi < mate1[*vi]) std::cout << "{" << *vi << ", " << mate1[*vi] << "}" << std::endl; std::cout << std::endl; - - - // now we check the correctness by compare the weight sum to a brute-force matching result - // note that two matchings may be different because of multiple optimal solutions - + + // now we check the correctness by compare the weight sum to a brute-force + // matching result note that two matchings may be different because of + // multiple optimal solutions + brute_force_maximum_weighted_matching(g, &mate2[0]); - - std::cout << "Found a weighted matching by brute-force searching:" << std::endl; - std::cout << "Matching size is " << matching_size(g, &mate2[0]) << ", total weight is " << matching_weight_sum(g, &mate2[0]) << std::endl; + + std::cout << "Found a weighted matching by brute-force searching:" + << std::endl; + std::cout << "Matching size is " << matching_size(g, &mate2[0]) + << ", total weight is " << matching_weight_sum(g, &mate2[0]) + << std::endl; std::cout << std::endl; - + std::cout << "The brute-force matching is:" << std::endl; - for (boost::tie(vi,vi_end) = vertices(g); vi != vi_end; ++vi) - if (mate2[*vi] != graph_traits::null_vertex() && *vi < mate2[*vi]) + for (boost::tie(vi, vi_end) = vertices(g); vi != vi_end; ++vi) + if (mate2[*vi] != graph_traits< my_graph >::null_vertex() + && *vi < mate2[*vi]) std::cout << "{" << *vi << ", " << mate2[*vi] << "}" << std::endl; std::cout << std::endl; - - assert(matching_weight_sum(g, &mate1[0]) == matching_weight_sum(g, &mate2[0])); - - - return 0; -} - + assert( + matching_weight_sum(g, &mate1[0]) == matching_weight_sum(g, &mate2[0])); + return 0; +} diff --git a/example/write_graphviz.cpp b/example/write_graphviz.cpp index 890f08cf5..c033fcb9f 100644 --- a/example/write_graphviz.cpp +++ b/example/write_graphviz.cpp @@ -9,50 +9,54 @@ // Author: Doug Gregor - #include - -enum files_e { dax_h, yow_h, boz_h, zow_h, foo_cpp, - foo_o, bar_cpp, bar_o, libfoobar_a, - zig_cpp, zig_o, zag_cpp, zag_o, - libzigzag_a, killerapp, N }; -const char* name[] = { "dax.h", "yow.h", "boz.h", "zow.h", "foo.cpp", - "foo.o", "bar.cpp", "bar.o", "libfoobar.a", - "zig.cpp", "zig.o", "zag.cpp", "zag.o", - "libzigzag.a", "killerapp" }; - -int main(int,char*[]) +enum files_e { - - typedef std::pair Edge; - Edge used_by[] = { - Edge(dax_h, foo_cpp), Edge(dax_h, bar_cpp), Edge(dax_h, yow_h), - Edge(yow_h, bar_cpp), Edge(yow_h, zag_cpp), - Edge(boz_h, bar_cpp), Edge(boz_h, zig_cpp), Edge(boz_h, zag_cpp), - Edge(zow_h, foo_cpp), - Edge(foo_cpp, foo_o), - Edge(foo_o, libfoobar_a), - Edge(bar_cpp, bar_o), - Edge(bar_o, libfoobar_a), - Edge(libfoobar_a, libzigzag_a), - Edge(zig_cpp, zig_o), - Edge(zig_o, libzigzag_a), - Edge(zag_cpp, zag_o), - Edge(zag_o, libzigzag_a), - Edge(libzigzag_a, killerapp) - }; - const int nedges = sizeof(used_by)/sizeof(Edge); - int weights[nedges]; - std::fill(weights, weights + nedges, 1); - - using namespace boost; - - typedef adjacency_list< vecS, vecS, directedS, - property< vertex_color_t, default_color_type >, - property< edge_weight_t, int > - > Graph; - Graph g(used_by, used_by + nedges, weights, N); - - write_graphviz(std::cout, g, make_label_writer(name)); + dax_h, + yow_h, + boz_h, + zow_h, + foo_cpp, + foo_o, + bar_cpp, + bar_o, + libfoobar_a, + zig_cpp, + zig_o, + zag_cpp, + zag_o, + libzigzag_a, + killerapp, + N +}; +const char* name[] = { "dax.h", "yow.h", "boz.h", "zow.h", "foo.cpp", "foo.o", + "bar.cpp", "bar.o", "libfoobar.a", "zig.cpp", "zig.o", "zag.cpp", "zag.o", + "libzigzag.a", "killerapp" }; + +int main(int, char*[]) +{ + + typedef std::pair< int, int > Edge; + Edge used_by[] = { Edge(dax_h, foo_cpp), Edge(dax_h, bar_cpp), + Edge(dax_h, yow_h), Edge(yow_h, bar_cpp), Edge(yow_h, zag_cpp), + Edge(boz_h, bar_cpp), Edge(boz_h, zig_cpp), Edge(boz_h, zag_cpp), + Edge(zow_h, foo_cpp), Edge(foo_cpp, foo_o), Edge(foo_o, libfoobar_a), + Edge(bar_cpp, bar_o), Edge(bar_o, libfoobar_a), + Edge(libfoobar_a, libzigzag_a), Edge(zig_cpp, zig_o), + Edge(zig_o, libzigzag_a), Edge(zag_cpp, zag_o), + Edge(zag_o, libzigzag_a), Edge(libzigzag_a, killerapp) }; + const int nedges = sizeof(used_by) / sizeof(Edge); + int weights[nedges]; + std::fill(weights, weights + nedges, 1); + + using namespace boost; + + typedef adjacency_list< vecS, vecS, directedS, + property< vertex_color_t, default_color_type >, + property< edge_weight_t, int > > + Graph; + Graph g(used_by, used_by + nedges, weights, N); + + write_graphviz(std::cout, g, make_label_writer(name)); } diff --git a/include/boost/detail/algorithm.hpp b/include/boost/detail/algorithm.hpp index 3f9297bca..7793fb357 100644 --- a/include/boost/detail/algorithm.hpp +++ b/include/boost/detail/algorithm.hpp @@ -29,8 +29,8 @@ */ #ifndef BOOST_ALGORITHM_HPP -# define BOOST_ALGORITHM_HPP -# include +#define BOOST_ALGORITHM_HPP +#include // Algorithms on sequences // // The functions in this file have not yet gone through formal @@ -52,30 +52,31 @@ #include #include -namespace boost { +namespace boost +{ - template - bool any_if(InputIterator first, InputIterator last, Predicate p) - { +template < typename InputIterator, typename Predicate > +bool any_if(InputIterator first, InputIterator last, Predicate p) +{ return std::find_if(first, last, p) != last; - } +} - template - bool any_if(const Container& c, Predicate p) - { +template < typename Container, typename Predicate > +bool any_if(const Container& c, Predicate p) +{ return any_if(boost::begin(c), boost::end(c), p); - } +} - template - bool container_contains(InputIterator first, InputIterator last, T value) - { +template < typename InputIterator, typename T > +bool container_contains(InputIterator first, InputIterator last, T value) +{ return std::find(first, last, value) != last; - } - template - bool container_contains(const Container& c, const T& value) - { +} +template < typename Container, typename T > +bool container_contains(const Container& c, const T& value) +{ return container_contains(boost::begin(c), boost::end(c), value); - } +} } // namespace boost diff --git a/include/boost/graph/adj_list_serialize.hpp b/include/boost/graph/adj_list_serialize.hpp index 01db50282..399634040 100644 --- a/include/boost/graph/adj_list_serialize.hpp +++ b/include/boost/graph/adj_list_serialize.hpp @@ -19,98 +19,112 @@ #include #include -namespace boost { - -namespace serialization { - -// Turn off tracking for adjacency_list. It's not polymorphic, and we -// need to do this to enable saving of non-const adjacency lists. -template -struct tracking_level > { - typedef mpl::integral_c_tag tag; - typedef mpl::int_ type; - BOOST_STATIC_CONSTANT(int, value = tracking_level::type::value); -}; - -template -inline void save( - Archive & ar, - const boost::adjacency_list &graph, - const unsigned int /* file_version */ -){ - typedef adjacency_list Graph; - typedef typename graph_traits::vertex_descriptor Vertex; - - int V = num_vertices(graph); - int E = num_edges(graph); - ar << BOOST_SERIALIZATION_NVP(V); - ar << BOOST_SERIALIZATION_NVP(E); - - // assign indices to vertices - std::map indices; - int num = 0; - BGL_FORALL_VERTICES_T(v, graph, Graph) { - indices[v] = num++; - ar << serialization::make_nvp("vertex_property", get(vertex_all_t(), graph, v) ); - } - - // write edges - BGL_FORALL_EDGES_T(e, graph, Graph) { - ar << serialization::make_nvp("u" , indices[source(e,graph)]); - ar << serialization::make_nvp("v" , indices[target(e,graph)]); - ar << serialization::make_nvp("edge_property", get(edge_all_t(), graph, e) ); - } - - ar << serialization::make_nvp("graph_property", get_property(graph, graph_all_t()) ); -} - - -template -inline void load( - Archive & ar, - boost::adjacency_list &graph, - const unsigned int /* file_version */ -){ - typedef adjacency_list Graph; - typedef typename graph_traits::vertex_descriptor Vertex; - typedef typename graph_traits::edge_descriptor Edge; - - unsigned int V; - ar >> BOOST_SERIALIZATION_NVP(V); - unsigned int E; - ar >> BOOST_SERIALIZATION_NVP(E); - - std::vector verts(V); - int i = 0; - while(V-- > 0){ - Vertex v = add_vertex(graph); - verts[i++] = v; - ar >> serialization::make_nvp("vertex_property", get(vertex_all_t(), graph, v) ); - } - while(E-- > 0){ - int u; int v; - ar >> BOOST_SERIALIZATION_NVP(u); - ar >> BOOST_SERIALIZATION_NVP(v); - Edge e; bool inserted; - boost::tie(e,inserted) = add_edge(verts[u], verts[v], graph); - ar >> serialization::make_nvp("edge_property", get(edge_all_t(), graph, e) ); - } - ar >> serialization::make_nvp("graph_property", get_property(graph, graph_all_t()) ); -} - -template -inline void serialize( - Archive & ar, - boost::adjacency_list &graph, - const unsigned int file_version -){ - boost::serialization::split_free(ar, graph, file_version); -} - -}//serialization -}//boost - +namespace boost +{ + +namespace serialization +{ + + // Turn off tracking for adjacency_list. It's not polymorphic, and we + // need to do this to enable saving of non-const adjacency lists. + template < class OEL, class VL, class D, class VP, class EP, class GP, + class EL > + struct tracking_level< boost::adjacency_list< OEL, VL, D, VP, EP, GP, EL > > + { + typedef mpl::integral_c_tag tag; + typedef mpl::int_< track_never > type; + BOOST_STATIC_CONSTANT(int, value = tracking_level::type::value); + }; + + template < class Archive, class OEL, class VL, class D, class VP, class EP, + class GP, class EL > + inline void save(Archive& ar, + const boost::adjacency_list< OEL, VL, D, VP, EP, GP, EL >& graph, + const unsigned int /* file_version */ + ) + { + typedef adjacency_list< OEL, VL, D, VP, EP, GP, EL > Graph; + typedef typename graph_traits< Graph >::vertex_descriptor Vertex; + + int V = num_vertices(graph); + int E = num_edges(graph); + ar << BOOST_SERIALIZATION_NVP(V); + ar << BOOST_SERIALIZATION_NVP(E); + + // assign indices to vertices + std::map< Vertex, int > indices; + int num = 0; + BGL_FORALL_VERTICES_T(v, graph, Graph) + { + indices[v] = num++; + ar << serialization::make_nvp( + "vertex_property", get(vertex_all_t(), graph, v)); + } + + // write edges + BGL_FORALL_EDGES_T(e, graph, Graph) + { + ar << serialization::make_nvp("u", indices[source(e, graph)]); + ar << serialization::make_nvp("v", indices[target(e, graph)]); + ar << serialization::make_nvp( + "edge_property", get(edge_all_t(), graph, e)); + } + + ar << serialization::make_nvp( + "graph_property", get_property(graph, graph_all_t())); + } + + template < class Archive, class OEL, class VL, class D, class VP, class EP, + class GP, class EL > + inline void load( + Archive& ar, boost::adjacency_list< OEL, VL, D, VP, EP, GP, EL >& graph, + const unsigned int /* file_version */ + ) + { + typedef adjacency_list< OEL, VL, D, VP, EP, GP, EL > Graph; + typedef typename graph_traits< Graph >::vertex_descriptor Vertex; + typedef typename graph_traits< Graph >::edge_descriptor Edge; + + unsigned int V; + ar >> BOOST_SERIALIZATION_NVP(V); + unsigned int E; + ar >> BOOST_SERIALIZATION_NVP(E); + + std::vector< Vertex > verts(V); + int i = 0; + while (V-- > 0) + { + Vertex v = add_vertex(graph); + verts[i++] = v; + ar >> serialization::make_nvp( + "vertex_property", get(vertex_all_t(), graph, v)); + } + while (E-- > 0) + { + int u; + int v; + ar >> BOOST_SERIALIZATION_NVP(u); + ar >> BOOST_SERIALIZATION_NVP(v); + Edge e; + bool inserted; + boost::tie(e, inserted) = add_edge(verts[u], verts[v], graph); + ar >> serialization::make_nvp( + "edge_property", get(edge_all_t(), graph, e)); + } + ar >> serialization::make_nvp( + "graph_property", get_property(graph, graph_all_t())); + } + + template < class Archive, class OEL, class VL, class D, class VP, class EP, + class GP, class EL > + inline void serialize(Archive& ar, + boost::adjacency_list< OEL, VL, D, VP, EP, GP, EL >& graph, + const unsigned int file_version) + { + boost::serialization::split_free(ar, graph, file_version); + } + +} // serialization +} // boost #endif // ADJ_LIST_SERIALIZE_HPP diff --git a/include/boost/graph/adjacency_iterator.hpp b/include/boost/graph/adjacency_iterator.hpp index c134fe5ad..5325e7875 100644 --- a/include/boost/graph/adjacency_iterator.hpp +++ b/include/boost/graph/adjacency_iterator.hpp @@ -17,86 +17,77 @@ namespace boost { - template - struct adjacency_iterator - : iterator_adaptor< - adjacency_iterator - , OutEdgeIter - , Vertex - , use_default - , Vertex - , Difference - > - { - typedef iterator_adaptor< - adjacency_iterator - , OutEdgeIter - , Vertex - , use_default - , Vertex - , Difference - > super_t; - - inline adjacency_iterator() {} - inline adjacency_iterator(OutEdgeIter const& i, const Graph* g) : super_t(i), m_g(g) { } - - inline Vertex - dereference() const - { return target(*this->base(), *m_g); } - - const Graph* m_g; - }; - - template ::vertex_descriptor, - class OutEdgeIter=typename graph_traits::out_edge_iterator> - class adjacency_iterator_generator - { - typedef typename boost::detail::iterator_traits - ::difference_type difference_type; - public: - typedef adjacency_iterator type; - }; - - template - struct inv_adjacency_iterator - : iterator_adaptor< - inv_adjacency_iterator - , InEdgeIter - , Vertex - , use_default - , Vertex - , Difference - > +template < class Graph, class Vertex, class OutEdgeIter, class Difference > +struct adjacency_iterator +: iterator_adaptor< + adjacency_iterator< Graph, Vertex, OutEdgeIter, Difference >, OutEdgeIter, + Vertex, use_default, Vertex, Difference > +{ + typedef iterator_adaptor< + adjacency_iterator< Graph, Vertex, OutEdgeIter, Difference >, + OutEdgeIter, Vertex, use_default, Vertex, Difference > + super_t; + + inline adjacency_iterator() {} + inline adjacency_iterator(OutEdgeIter const& i, const Graph* g) + : super_t(i), m_g(g) + { + } + + inline Vertex dereference() const { return target(*this->base(), *m_g); } + + const Graph* m_g; +}; + +template < class Graph, + class Vertex = typename graph_traits< Graph >::vertex_descriptor, + class OutEdgeIter = typename graph_traits< Graph >::out_edge_iterator > +class adjacency_iterator_generator +{ + typedef + typename boost::detail::iterator_traits< OutEdgeIter >::difference_type + difference_type; + +public: + typedef adjacency_iterator< Graph, Vertex, OutEdgeIter, difference_type > + type; +}; + +template < class Graph, class Vertex, class InEdgeIter, class Difference > +struct inv_adjacency_iterator +: iterator_adaptor< + inv_adjacency_iterator< Graph, Vertex, InEdgeIter, Difference >, + InEdgeIter, Vertex, use_default, Vertex, Difference > +{ + typedef iterator_adaptor< + inv_adjacency_iterator< Graph, Vertex, InEdgeIter, Difference >, + InEdgeIter, Vertex, use_default, Vertex, Difference > + super_t; + + inline inv_adjacency_iterator() {} + inline inv_adjacency_iterator(InEdgeIter const& i, const Graph* g) + : super_t(i), m_g(g) { - typedef iterator_adaptor< - inv_adjacency_iterator - , InEdgeIter - , Vertex - , use_default - , Vertex - , Difference - > super_t; - - inline inv_adjacency_iterator() { } - inline inv_adjacency_iterator(InEdgeIter const& i, const Graph* g) : super_t(i), m_g(g) { } - - inline Vertex - dereference() const - { return source(*this->base(), *m_g); } - - const Graph* m_g; - }; - - template ::vertex_descriptor, - class InEdgeIter = typename graph_traits::in_edge_iterator> - class inv_adjacency_iterator_generator { - typedef typename boost::detail::iterator_traits - ::difference_type difference_type; - public: - typedef inv_adjacency_iterator type; - }; + } + + inline Vertex dereference() const { return source(*this->base(), *m_g); } + + const Graph* m_g; +}; + +template < class Graph, + class Vertex = typename graph_traits< Graph >::vertex_descriptor, + class InEdgeIter = typename graph_traits< Graph >::in_edge_iterator > +class inv_adjacency_iterator_generator +{ + typedef + typename boost::detail::iterator_traits< InEdgeIter >::difference_type + difference_type; + +public: + typedef inv_adjacency_iterator< Graph, Vertex, InEdgeIter, difference_type > + type; +}; } // namespace boost diff --git a/include/boost/graph/adjacency_list.hpp b/include/boost/graph/adjacency_list.hpp index da80063df..e5050b5b6 100644 --- a/include/boost/graph/adjacency_list.hpp +++ b/include/boost/graph/adjacency_list.hpp @@ -11,7 +11,6 @@ #ifndef BOOST_GRAPH_ADJACENCY_LIST_HPP #define BOOST_GRAPH_ADJACENCY_LIST_HPP - #include #include @@ -36,238 +35,272 @@ #include #include -namespace boost { - - //=========================================================================== - // Selectors for the VertexList and EdgeList template parameters of - // adjacency_list, and the container_gen traits class which is used - // to map the selectors to the container type used to implement the - // graph. - - struct vecS { }; - struct listS { }; - struct setS { }; - struct mapS { }; - struct multisetS { }; - struct multimapS { }; - struct hash_setS { }; - struct hash_mapS { }; - struct hash_multisetS { }; - struct hash_multimapS { }; - - template - struct container_gen { }; - - template - struct container_gen { - typedef std::list type; - }; - - template - struct container_gen { - typedef std::vector type; - }; - - template - struct container_gen { - typedef std::set type; - }; - - template - struct container_gen { - typedef std::set type; - }; - - template - struct container_gen { - typedef std::multiset type; - }; - - template - struct container_gen { - typedef std::multiset type; - }; - - template - struct container_gen { - typedef boost::unordered_set type; - }; - - template - struct container_gen { - typedef boost::unordered_set type; - }; - - template - struct container_gen { - typedef boost::unordered_multiset type; - }; - - template - struct container_gen { - typedef boost::unordered_multiset type; - }; - - template - struct parallel_edge_traits { }; - - template <> - struct parallel_edge_traits { - typedef allow_parallel_edge_tag type; }; - - template <> - struct parallel_edge_traits { - typedef allow_parallel_edge_tag type; }; - - template <> - struct parallel_edge_traits { - typedef disallow_parallel_edge_tag type; }; - - template <> - struct parallel_edge_traits { - typedef allow_parallel_edge_tag type; }; - - template <> - struct parallel_edge_traits { +namespace boost +{ + +//=========================================================================== +// Selectors for the VertexList and EdgeList template parameters of +// adjacency_list, and the container_gen traits class which is used +// to map the selectors to the container type used to implement the +// graph. + +struct vecS +{ +}; +struct listS +{ +}; +struct setS +{ +}; +struct mapS +{ +}; +struct multisetS +{ +}; +struct multimapS +{ +}; +struct hash_setS +{ +}; +struct hash_mapS +{ +}; +struct hash_multisetS +{ +}; +struct hash_multimapS +{ +}; + +template < class Selector, class ValueType > struct container_gen +{ +}; + +template < class ValueType > struct container_gen< listS, ValueType > +{ + typedef std::list< ValueType > type; +}; + +template < class ValueType > struct container_gen< vecS, ValueType > +{ + typedef std::vector< ValueType > type; +}; + +template < class ValueType > struct container_gen< mapS, ValueType > +{ + typedef std::set< ValueType > type; +}; + +template < class ValueType > struct container_gen< setS, ValueType > +{ + typedef std::set< ValueType > type; +}; + +template < class ValueType > struct container_gen< multisetS, ValueType > +{ + typedef std::multiset< ValueType > type; +}; + +template < class ValueType > struct container_gen< multimapS, ValueType > +{ + typedef std::multiset< ValueType > type; +}; + +template < class ValueType > struct container_gen< hash_setS, ValueType > +{ + typedef boost::unordered_set< ValueType > type; +}; + +template < class ValueType > struct container_gen< hash_mapS, ValueType > +{ + typedef boost::unordered_set< ValueType > type; +}; + +template < class ValueType > struct container_gen< hash_multisetS, ValueType > +{ + typedef boost::unordered_multiset< ValueType > type; +}; + +template < class ValueType > struct container_gen< hash_multimapS, ValueType > +{ + typedef boost::unordered_multiset< ValueType > type; +}; + +template < class StorageSelector > struct parallel_edge_traits +{ +}; + +template <> struct parallel_edge_traits< vecS > +{ + typedef allow_parallel_edge_tag type; +}; + +template <> struct parallel_edge_traits< listS > +{ + typedef allow_parallel_edge_tag type; +}; + +template <> struct parallel_edge_traits< setS > +{ + typedef disallow_parallel_edge_tag type; +}; + +template <> struct parallel_edge_traits< multisetS > +{ + typedef allow_parallel_edge_tag type; +}; + +template <> struct parallel_edge_traits< hash_setS > +{ typedef disallow_parallel_edge_tag type; - }; +}; - // mapS is obsolete, replaced with setS - template <> - struct parallel_edge_traits { - typedef disallow_parallel_edge_tag type; }; +// mapS is obsolete, replaced with setS +template <> struct parallel_edge_traits< mapS > +{ + typedef disallow_parallel_edge_tag type; +}; - template <> - struct parallel_edge_traits { +template <> struct parallel_edge_traits< hash_mapS > +{ typedef disallow_parallel_edge_tag type; - }; +}; - template <> - struct parallel_edge_traits { +template <> struct parallel_edge_traits< hash_multisetS > +{ typedef allow_parallel_edge_tag type; - }; +}; - template <> - struct parallel_edge_traits { +template <> struct parallel_edge_traits< hash_multimapS > +{ typedef allow_parallel_edge_tag type; - }; +}; - namespace detail { - template struct is_random_access { - enum { value = false}; - typedef mpl::false_ type; +namespace detail +{ + template < class Directed > struct is_random_access + { + enum + { + value = false + }; + typedef mpl::false_ type; }; - template <> - struct is_random_access { - enum { value = true }; - typedef mpl::true_ type; + template <> struct is_random_access< vecS > + { + enum + { + value = true + }; + typedef mpl::true_ type; }; - } // namespace detail - - template struct is_distributed_selector: mpl::false_ {}; - +} // namespace detail - //=========================================================================== - // The adjacency_list_traits class, which provides a way to access - // some of the associated types of an adjacency_list type without - // having to first create the adjacency_list type. This is useful - // when trying to create interior vertex or edge properties who's - // value type is a vertex or edge descriptor. +template < typename Selector > struct is_distributed_selector : mpl::false_ +{ +}; - template - struct adjacency_list_traits - { - typedef typename detail::is_random_access::type - is_rand_access; +//=========================================================================== +// The adjacency_list_traits class, which provides a way to access +// some of the associated types of an adjacency_list type without +// having to first create the adjacency_list type. This is useful +// when trying to create interior vertex or edge properties who's +// value type is a vertex or edge descriptor. + +template < class OutEdgeListS = vecS, class VertexListS = vecS, + class DirectedS = directedS, class EdgeListS = listS > +struct adjacency_list_traits +{ + typedef + typename detail::is_random_access< VertexListS >::type is_rand_access; typedef typename DirectedS::is_bidir_t is_bidir; typedef typename DirectedS::is_directed_t is_directed; - typedef typename mpl::if_::type - >::type directed_category; + typedef typename mpl::if_< is_bidir, bidirectional_tag, + typename mpl::if_< is_directed, directed_tag, + undirected_tag >::type >::type directed_category; - typedef typename parallel_edge_traits::type - edge_parallel_category; + typedef typename parallel_edge_traits< OutEdgeListS >::type + edge_parallel_category; typedef std::size_t vertices_size_type; typedef void* vertex_ptr; - typedef typename mpl::if_::type vertex_descriptor; - typedef detail::edge_desc_impl - edge_descriptor; + typedef typename mpl::if_< is_rand_access, vertices_size_type, + vertex_ptr >::type vertex_descriptor; + typedef detail::edge_desc_impl< directed_category, vertex_descriptor > + edge_descriptor; - private: +private: // Logic to figure out the edges_size_type - struct dummy {}; - typedef typename container_gen::type EdgeContainer; + struct dummy + { + }; + typedef typename container_gen< EdgeListS, dummy >::type EdgeContainer; typedef typename DirectedS::is_bidir_t BidirectionalT; typedef typename DirectedS::is_directed_t DirectedT; - typedef typename mpl::and_::type >::type on_edge_storage; - public: - typedef typename mpl::if_::type edges_size_type; + typedef typename mpl::and_< DirectedT, + typename mpl::not_< BidirectionalT >::type >::type on_edge_storage; - }; +public: + typedef typename mpl::if_< on_edge_storage, std::size_t, + typename EdgeContainer::size_type >::type edges_size_type; +}; } // namespace boost #include -namespace boost { - - //=========================================================================== - // The adjacency_list class. - // - - template - class adjacency_list - : public detail::adj_list_gen< - adjacency_list, - VertexListS, OutEdgeListS, DirectedS, - VertexProperty, EdgeProperty, - GraphProperty, EdgeListS>::type, - // Support for named vertices - public graph::maybe_named_graph< - adjacency_list, - typename adjacency_list_traits::vertex_descriptor, - VertexProperty> - { - public: +namespace boost +{ + +//=========================================================================== +// The adjacency_list class. +// + +template < class OutEdgeListS = vecS, // a Sequence or an AssociativeContainer + class VertexListS = vecS, // a Sequence or a RandomAccessContainer + class DirectedS = directedS, class VertexProperty = no_property, + class EdgeProperty = no_property, class GraphProperty = no_property, + class EdgeListS = listS > +class adjacency_list +: public detail::adj_list_gen< + adjacency_list< OutEdgeListS, VertexListS, DirectedS, VertexProperty, + EdgeProperty, GraphProperty, EdgeListS >, + VertexListS, OutEdgeListS, DirectedS, VertexProperty, EdgeProperty, + GraphProperty, EdgeListS >::type, + // Support for named vertices + public graph::maybe_named_graph< + adjacency_list< OutEdgeListS, VertexListS, DirectedS, VertexProperty, + EdgeProperty, GraphProperty, EdgeListS >, + typename adjacency_list_traits< OutEdgeListS, VertexListS, DirectedS, + EdgeListS >::vertex_descriptor, + VertexProperty > +{ +public: typedef GraphProperty graph_property_type; - typedef typename lookup_one_property::type graph_bundled; + typedef typename lookup_one_property< GraphProperty, graph_bundle_t >::type + graph_bundled; typedef VertexProperty vertex_property_type; - typedef typename lookup_one_property::type vertex_bundled; + typedef + typename lookup_one_property< VertexProperty, vertex_bundle_t >::type + vertex_bundled; typedef EdgeProperty edge_property_type; - typedef typename lookup_one_property::type edge_bundled; + typedef typename lookup_one_property< EdgeProperty, edge_bundle_t >::type + edge_bundled; - private: +private: typedef adjacency_list self; - typedef typename detail::adj_list_gen< - self, VertexListS, OutEdgeListS, DirectedS, - vertex_property_type, edge_property_type, GraphProperty, EdgeListS - >::type Base; + typedef typename detail::adj_list_gen< self, VertexListS, OutEdgeListS, + DirectedS, vertex_property_type, edge_property_type, GraphProperty, + EdgeListS >::type Base; - public: +public: typedef typename Base::stored_vertex stored_vertex; typedef typename Base::vertices_size_type vertices_size_type; typedef typename Base::edges_size_type edges_size_type; @@ -279,155 +312,164 @@ namespace boost { typedef DirectedS directed_selector; typedef EdgeListS edge_list_selector; - adjacency_list(const GraphProperty& p = GraphProperty()) - : m_property(new graph_property_type(p)) - { } + : m_property(new graph_property_type(p)) + { + } adjacency_list(const adjacency_list& x) - : Base(x), m_property(new graph_property_type(*x.m_property)) - { } - - adjacency_list& operator=(const adjacency_list& x) { - // TBD: probably should give the strong guarantee - if (&x != this) { - Base::operator=(x); - - // Copy/swap the ptr since we can't just assign it... - property_ptr p(new graph_property_type(*x.m_property)); - m_property.swap(p); - } - return *this; + : Base(x), m_property(new graph_property_type(*x.m_property)) + { + } + + adjacency_list& operator=(const adjacency_list& x) + { + // TBD: probably should give the strong guarantee + if (&x != this) + { + Base::operator=(x); + + // Copy/swap the ptr since we can't just assign it... + property_ptr p(new graph_property_type(*x.m_property)); + m_property.swap(p); + } + return *this; } // Required by Mutable Graph adjacency_list(vertices_size_type num_vertices, - const GraphProperty& p = GraphProperty()) - : Base(num_vertices), m_property(new graph_property_type(p)) - { } + const GraphProperty& p = GraphProperty()) + : Base(num_vertices), m_property(new graph_property_type(p)) + { + } // Required by Iterator Constructible Graph - template - adjacency_list(EdgeIterator first, EdgeIterator last, - vertices_size_type n, - edges_size_type = 0, - const GraphProperty& p = GraphProperty()) - : Base(n, first, last), m_property(new graph_property_type(p)) - { } + template < class EdgeIterator > + adjacency_list(EdgeIterator first, EdgeIterator last, vertices_size_type n, + edges_size_type = 0, const GraphProperty& p = GraphProperty()) + : Base(n, first, last), m_property(new graph_property_type(p)) + { + } - template + template < class EdgeIterator, class EdgePropertyIterator > adjacency_list(EdgeIterator first, EdgeIterator last, - EdgePropertyIterator ep_iter, - vertices_size_type n, - edges_size_type = 0, - const GraphProperty& p = GraphProperty()) - : Base(n, first, last, ep_iter), m_property(new graph_property_type(p)) - { } - - void swap(adjacency_list& x) { - // Is there a more efficient way to do this? - adjacency_list tmp(x); - x = *this; - *this = tmp; + EdgePropertyIterator ep_iter, vertices_size_type n, edges_size_type = 0, + const GraphProperty& p = GraphProperty()) + : Base(n, first, last, ep_iter), m_property(new graph_property_type(p)) + { + } + + void swap(adjacency_list& x) + { + // Is there a more efficient way to do this? + adjacency_list tmp(x); + x = *this; + *this = tmp; } void clear() { - this->clearing_graph(); - Base::clear(); + this->clearing_graph(); + Base::clear(); } #ifndef BOOST_GRAPH_NO_BUNDLED_PROPERTIES // Directly access a vertex or edge bundle vertex_bundled& operator[](vertex_descriptor v) - { return get(vertex_bundle, *this)[v]; } + { + return get(vertex_bundle, *this)[v]; + } const vertex_bundled& operator[](vertex_descriptor v) const - { return get(vertex_bundle, *this)[v]; } + { + return get(vertex_bundle, *this)[v]; + } edge_bundled& operator[](edge_descriptor e) - { return get(edge_bundle, *this)[e]; } + { + return get(edge_bundle, *this)[e]; + } const edge_bundled& operator[](edge_descriptor e) const - { return get(edge_bundle, *this)[e]; } + { + return get(edge_bundle, *this)[e]; + } - graph_bundled& operator[](graph_bundle_t) - { return get_property(*this); } + graph_bundled& operator[](graph_bundle_t) { return get_property(*this); } graph_bundled const& operator[](graph_bundle_t) const - { return get_property(*this); } + { + return get_property(*this); + } #endif // protected: (would be protected if friends were more portable) - typedef scoped_ptr property_ptr; - property_ptr m_property; - }; + typedef scoped_ptr< graph_property_type > property_ptr; + property_ptr m_property; +}; -#define ADJLIST_PARAMS \ +#define ADJLIST_PARAMS \ typename OEL, typename VL, typename D, typename VP, typename EP, \ - typename GP, typename EL -#define ADJLIST adjacency_list + typename GP, typename EL +#define ADJLIST adjacency_list< OEL, VL, D, VP, EP, GP, EL > - template - inline void set_property(ADJLIST& g, Tag tag, Value const& value) { +template < ADJLIST_PARAMS, typename Tag, typename Value > +inline void set_property(ADJLIST& g, Tag tag, Value const& value) +{ get_property_value(*g.m_property, tag) = value; - } +} - template - inline typename graph_property::type& - get_property(ADJLIST& g, Tag tag) { +template < ADJLIST_PARAMS, typename Tag > +inline typename graph_property< ADJLIST, Tag >::type& get_property( + ADJLIST& g, Tag tag) +{ return get_property_value(*g.m_property, tag); - } +} - template - inline typename graph_property::type const& - get_property(ADJLIST const& g, Tag tag) { +template < ADJLIST_PARAMS, typename Tag > +inline typename graph_property< ADJLIST, Tag >::type const& get_property( + ADJLIST const& g, Tag tag) +{ return get_property_value(*g.m_property, tag); - } - - // dwa 09/25/00 - needed to be more explicit so reverse_graph would work. - template - inline Vertex - source(const detail::edge_base& e, - const adjacency_list&) - { +} + +// dwa 09/25/00 - needed to be more explicit so reverse_graph would work. +template < class Directed, class Vertex, class OutEdgeListS, class VertexListS, + class DirectedS, class VertexProperty, class EdgeProperty, + class GraphProperty, class EdgeListS > +inline Vertex source(const detail::edge_base< Directed, Vertex >& e, + const adjacency_list< OutEdgeListS, VertexListS, DirectedS, VertexProperty, + EdgeProperty, GraphProperty, EdgeListS >&) +{ return e.m_source; - } - - template - inline Vertex - target(const detail::edge_base& e, - const adjacency_list&) - { +} + +template < class Directed, class Vertex, class OutEdgeListS, class VertexListS, + class DirectedS, class VertexProperty, class EdgeProperty, + class GraphProperty, class EdgeListS > +inline Vertex target(const detail::edge_base< Directed, Vertex >& e, + const adjacency_list< OutEdgeListS, VertexListS, DirectedS, VertexProperty, + EdgeProperty, GraphProperty, EdgeListS >&) +{ return e.m_target; - } +} // Mutability Traits -template -struct graph_mutability_traits { +template < ADJLIST_PARAMS > struct graph_mutability_traits< ADJLIST > +{ typedef mutable_property_graph_tag category; }; // Can't remove vertices from adjacency lists with VL==vecS -template -struct graph_mutability_traits< adjacency_list > { +template < typename OEL, typename D, typename VP, typename EP, typename GP, + typename EL > +struct graph_mutability_traits< adjacency_list< OEL, vecS, D, VP, EP, GP, EL > > +{ typedef add_only_property_graph_tag category; }; #undef ADJLIST_PARAMS #undef ADJLIST - } // namespace boost - #endif // BOOST_GRAPH_ADJACENCY_LIST_HPP diff --git a/include/boost/graph/adjacency_list_io.hpp b/include/boost/graph/adjacency_list_io.hpp index aaba8a43c..4a85bebd9 100644 --- a/include/boost/graph/adjacency_list_io.hpp +++ b/include/boost/graph/adjacency_list_io.hpp @@ -23,7 +23,8 @@ // cout << write( G ); // cout << write( G, NodePropertySubset(), EdgepropertySubset() ); -namespace boost { +namespace boost +{ /* outline - basic property input @@ -37,165 +38,164 @@ namespace boost { //=========================================================================== // basic property input -template -std::istream& operator >> ( std::istream& in, property& p ) +template < class Tag, class Value, class Next > +std::istream& operator>>(std::istream& in, property< Tag, Value, Next >& p) { - in >> p.m_value >> p.m_base; // houpla !! - return in; + in >> p.m_value >> p.m_base; // houpla !! + return in; } -template -std::istream& operator >> ( std::istream& in, property& p ) +template < class Tag, class Value > +std::istream& operator>>( + std::istream& in, property< Tag, Value, no_property >& p) { - in >> p.m_value; - return in; + in >> p.m_value; + return in; } -inline std::istream& operator >> ( std::istream& in, no_property& ) -{ - return in; -} +inline std::istream& operator>>(std::istream& in, no_property&) { return in; } // basic property input //=========================================================================== // get property subsets // get a single property tagged Stag -template -void get -( property& p, const V& v, Stag s ) +template < class Tag, class Value, class Next, class V, class Stag > +void get(property< Tag, Value, Next >& p, const V& v, Stag s) { - get( p.m_base,v,s ); + get(p.m_base, v, s); } -template -void get -( property& p, const V& v, Stag ) +template < class Value, class Next, class V, class Stag > +void get(property< Stag, Value, Next >& p, const V& v, Stag) { - p.m_value = v; + p.m_value = v; } // get a subset of properties tagged Stag -template -void getSubset -( property& p, const property& s ) +template < class Tag, class Value, class Next, class Stag, class Svalue, + class Snext > +void getSubset( + property< Tag, Value, Next >& p, const property< Stag, Svalue, Snext >& s) { - get( p, s.m_value, Stag() ); - getSubset( p, s.m_base ); + get(p, s.m_value, Stag()); + getSubset(p, s.m_base); } -template -void getSubset -( property& p, const property& s) +template < class Tag, class Value, class Next, class Stag, class Svalue > +void getSubset(property< Tag, Value, Next >& p, + const property< Stag, Svalue, no_property >& s) { - get( p, s.m_value, Stag() ); + get(p, s.m_value, Stag()); } -inline void getSubset -( no_property&, const no_property& ) -{ -} +inline void getSubset(no_property&, const no_property&) {} #if !defined(BOOST_GRAPH_NO_BUNDLED_PROPERTIES) -template -void getSubset(T& p, const U& s) -{ - p = s; -} - -template -void getSubset(T&, const no_property&) -{ -} +template < typename T, typename U > void getSubset(T& p, const U& s) { p = s; } +template < typename T > void getSubset(T&, const no_property&) {} #endif // get property subset //=========================================================================== // graph parser -typedef enum{ PARSE_NUM_NODES, PARSE_VERTEX, PARSE_EDGE } GraphParserState; +typedef enum +{ + PARSE_NUM_NODES, + PARSE_VERTEX, + PARSE_EDGE +} GraphParserState; -template +template < class Graph_t, class VertexProperty, class EdgeProperty, + class VertexPropertySubset, class EdgePropertySubset > struct GraphParser { - typedef Graph_t Graph; - - GraphParser( Graph* g ): graph(g) - {} - - GraphParser& operator () ( std::istream& in ) - { - typedef typename graph_traits::vertex_descriptor Vertex; - std::vector nodes; + typedef Graph_t Graph; - GraphParserState state = PARSE_VERTEX; + GraphParser(Graph* g) : graph(g) {} - unsigned int numLine = 1; - char c; - while ( in.get(c) ) - { - if( c== '#' ) skip(in); - else if( c== 'n' ) state = PARSE_NUM_NODES; - else if( c== 'v' ) state = PARSE_VERTEX; - else if( c== 'e' ) state = PARSE_EDGE; - else if( c== '\n' ) numLine++; - else if( !std::isspace(c) ){ - in.putback(c); - if( state == PARSE_VERTEX ){ - VertexPropertySubset readProp; - if( in >> readProp ) - { - VertexProperty vp; - getSubset( vp, readProp ); - nodes.push_back( add_vertex(vp, *graph) ); - } - else - std::cerr<<"read vertex, parse error at line"<> source >> target; - if( in >> readProp ) - { - EdgeProperty ep; - getSubset( ep, readProp ); - add_edge(nodes[source], nodes[target], ep, *graph); - } - else - std::cerr<<"read edge, parse error at line"<> n ){ - for( int i=0; i::vertex_descriptor Vertex; + std::vector< Vertex > nodes; - Graph* graph; - - void skip( std::istream& in ) + GraphParserState state = PARSE_VERTEX; + + unsigned int numLine = 1; + char c; + while (in.get(c)) { - char c = 0; - while( c!='\n' && !in.eof() ) - in.get(c); + if (c == '#') + skip(in); + else if (c == 'n') + state = PARSE_NUM_NODES; + else if (c == 'v') + state = PARSE_VERTEX; + else if (c == 'e') + state = PARSE_EDGE; + else if (c == '\n') + numLine++; + else if (!std::isspace(c)) + { in.putback(c); + if (state == PARSE_VERTEX) + { + VertexPropertySubset readProp; + if (in >> readProp) + { + VertexProperty vp; + getSubset(vp, readProp); + nodes.push_back(add_vertex(vp, *graph)); + } + else + std::cerr << "read vertex, parse error at line" + << numLine << std::endl; + } + else if (state == PARSE_EDGE) + { + int source, target; + EdgePropertySubset readProp; + in >> source >> target; + if (in >> readProp) + { + EdgeProperty ep; + getSubset(ep, readProp); + add_edge(nodes[source], nodes[target], ep, *graph); + } + else + std::cerr << "read edge, parse error at line" << numLine + << std::endl; + } + else + { // state == PARSE_NUM_NODES + int n; + if (in >> n) + { + for (int i = 0; i < n; ++i) + nodes.push_back(add_vertex(*graph)); + } + else + std::cerr << "read num_nodes, parse error at line " + << numLine << std::endl; + } + } } + return (*this); + } + +protected: + Graph* graph; + + void skip(std::istream& in) + { + char c = 0; + while (c != '\n' && !in.eof()) + in.get(c); + in.putback(c); + } }; // parser @@ -203,148 +203,142 @@ struct GraphParser // property printer #if defined(BOOST_GRAPH_NO_BUNDLED_PROPERTIES) -template -struct PropertyPrinter +template < class Graph, class Property > struct PropertyPrinter { - typedef typename Property::value_type Value; - typedef typename Property::tag_type Tag; - typedef typename Property::next_type Next; - - PropertyPrinter( const Graph& g ):graph(&g){} - - template - PropertyPrinter& operator () ( std::ostream& out, const Val& v ) - { - typename property_map::const_type ps = get(Tag(), *graph); - out << ps[ v ] <<" "; - PropertyPrinter print(*graph); - print(out, v); - return (*this); - } + typedef typename Property::value_type Value; + typedef typename Property::tag_type Tag; + typedef typename Property::next_type Next; + + PropertyPrinter(const Graph& g) : graph(&g) {} + + template < class Val > + PropertyPrinter& operator()(std::ostream& out, const Val& v) + { + typename property_map< Graph, Tag >::const_type ps = get(Tag(), *graph); + out << ps[v] << " "; + PropertyPrinter< Graph, Next > print(*graph); + print(out, v); + return (*this); + } + private: - const Graph* graph; + const Graph* graph; }; #else -template -struct PropertyPrinter +template < class Graph, typename Property > struct PropertyPrinter { - PropertyPrinter( const Graph& g ):graph(&g){} - - template - PropertyPrinter& operator () ( std::ostream& out, const Val& v ) - { - out << (*graph)[ v ] <<" "; - return (*this); - } + PropertyPrinter(const Graph& g) : graph(&g) {} + + template < class Val > + PropertyPrinter& operator()(std::ostream& out, const Val& v) + { + out << (*graph)[v] << " "; + return (*this); + } + private: - const Graph* graph; + const Graph* graph; }; -template -struct PropertyPrinter > +template < class Graph, typename Tag, typename Value, typename Next > +struct PropertyPrinter< Graph, property< Tag, Value, Next > > { - PropertyPrinter( const Graph& g ):graph(&g){} - - template - PropertyPrinter& operator () ( std::ostream& out, const Val& v ) - { - typename property_map::const_type ps = get(Tag(), *graph); - out << ps[ v ] <<" "; - PropertyPrinter print(*graph); - print(out, v); - return (*this); - } + PropertyPrinter(const Graph& g) : graph(&g) {} + + template < class Val > + PropertyPrinter& operator()(std::ostream& out, const Val& v) + { + typename property_map< Graph, Tag >::const_type ps = get(Tag(), *graph); + out << ps[v] << " "; + PropertyPrinter< Graph, Next > print(*graph); + print(out, v); + return (*this); + } + private: - const Graph* graph; + const Graph* graph; }; #endif -template -struct PropertyPrinter +template < class Graph > struct PropertyPrinter< Graph, no_property > { - PropertyPrinter( const Graph& ){} + PropertyPrinter(const Graph&) {} - template - PropertyPrinter& operator () ( std::ostream&, const Val& ){ return *this; } + template < class Val > + PropertyPrinter& operator()(std::ostream&, const Val&) + { + return *this; + } }; // property printer //========================================================================= // graph printer -template -struct EdgePrinter +template < class Graph_t, class EdgeProperty > struct EdgePrinter { - typedef Graph_t Graph; - typedef typename graph_traits::vertex_descriptor Vertex; - - EdgePrinter( const Graph& g ) - : graph(g) - {} - - const EdgePrinter& operator () ( std::ostream& out ) const - { - // assign indices to vertices - std::map indices; - int num = 0; - BGL_FORALL_VERTICES_T(v, graph, Graph) { - indices[v] = num++; - } + typedef Graph_t Graph; + typedef typename graph_traits< Graph >::vertex_descriptor Vertex; - // write edges - PropertyPrinter print_Edge(graph); - out << "e" << std::endl; - BGL_FORALL_EDGES_T(e, graph, Graph) { - out << indices[source(e,graph)] << " " << indices[target(e,graph)] << " "; - print_Edge(out,e); - out << std::endl; - } - out << std::endl; - return (*this); + EdgePrinter(const Graph& g) : graph(g) {} + + const EdgePrinter& operator()(std::ostream& out) const + { + // assign indices to vertices + std::map< Vertex, int > indices; + int num = 0; + BGL_FORALL_VERTICES_T(v, graph, Graph) { indices[v] = num++; } + + // write edges + PropertyPrinter< Graph, EdgeProperty > print_Edge(graph); + out << "e" << std::endl; + BGL_FORALL_EDGES_T(e, graph, Graph) + { + out << indices[source(e, graph)] << " " << indices[target(e, graph)] + << " "; + print_Edge(out, e); + out << std::endl; } - -protected: + out << std::endl; + return (*this); + } - const Graph& graph; - +protected: + const Graph& graph; }; -template -struct GraphPrinter: public EdgePrinter +template < class Graph, class V, class E > +struct GraphPrinter : public EdgePrinter< Graph, E > { - GraphPrinter( const Graph& g ) - : EdgePrinter(g) - {} - - const GraphPrinter& operator () ( std::ostream& out ) const + GraphPrinter(const Graph& g) : EdgePrinter< Graph, E >(g) {} + + const GraphPrinter& operator()(std::ostream& out) const + { + PropertyPrinter< Graph, V > printNode(this->graph); + out << "v" << std::endl; + BGL_FORALL_VERTICES_T(v, this->graph, Graph) { - PropertyPrinter printNode(this->graph); - out << "v"<graph, Graph) { - printNode(out,v); - out << std::endl; - } - - EdgePrinter::operator ()( out ); - return (*this); + printNode(out, v); + out << std::endl; } + + EdgePrinter< Graph, E >::operator()(out); + return (*this); + } }; -template -struct GraphPrinter - : public EdgePrinter +template < class Graph, class E > +struct GraphPrinter< Graph, no_property, E > : public EdgePrinter< Graph, E > { - GraphPrinter( const Graph& g ) - : EdgePrinter(g) - {} - - const GraphPrinter& operator () ( std::ostream& out ) const - { - out << "n "<< num_vertices(this->graph) << std::endl; - EdgePrinter::operator ()( out ); - return (*this); - } + GraphPrinter(const Graph& g) : EdgePrinter< Graph, E >(g) {} + + const GraphPrinter& operator()(std::ostream& out) const + { + out << "n " << num_vertices(this->graph) << std::endl; + EdgePrinter< Graph, E >::operator()(out); + return (*this); + } }; // graph printer @@ -352,55 +346,60 @@ struct GraphPrinter // user methods /// input stream for reading a graph -template -std::istream& operator >> ( std::istream& in, GraphParser gp ) -{ - gp(in); - return in; +template < class Graph, class VP, class EP, class VPS, class EPS > +std::istream& operator>>( + std::istream& in, GraphParser< Graph, VP, EP, VPS, EPS > gp) +{ + gp(in); + return in; } /// graph parser for given subsets of internal vertex and edge properties -template -GraphParser,VP,EP,VPS,EPS> -read( adjacency_list& g, VPS vps, EPS eps ) +template < class EL, class VL, class D, class VP, class EP, class GP, class VPS, + class EPS > +GraphParser< adjacency_list< EL, VL, D, VP, EP, GP >, VP, EP, VPS, EPS > read( + adjacency_list< EL, VL, D, VP, EP, GP >& g, VPS vps, EPS eps) { - return GraphParser,VP,EP,VPS,EPS>(&g); + return GraphParser< adjacency_list< EL, VL, D, VP, EP, GP >, VP, EP, VPS, + EPS >(&g); } /// graph parser for all internal vertex and edge properties -template -GraphParser,VP,EP,VP,EP> -read( adjacency_list& g ) +template < class EL, class VL, class D, class VP, class EP, class GP > +GraphParser< adjacency_list< EL, VL, D, VP, EP, GP >, VP, EP, VP, EP > read( + adjacency_list< EL, VL, D, VP, EP, GP >& g) { - return GraphParser,VP,EP,VP,EP>(&g); + return GraphParser< adjacency_list< EL, VL, D, VP, EP, GP >, VP, EP, VP, + EP >(&g); } - /// output stream for writing a graph -template -std::ostream& operator << ( std::ostream& out, const GraphPrinter& gp ) -{ - gp(out); - return out; +template < class Graph, class VP, class EP > +std::ostream& operator<<( + std::ostream& out, const GraphPrinter< Graph, VP, EP >& gp) +{ + gp(out); + return out; } /// write the graph with given property subsets -template -GraphPrinter,VPS,EPS> -write( const adjacency_list& g, VPS, EPS ) +template < class EL, class VL, class D, class VP, class EP, class GP, class VPS, + class EPS > +GraphPrinter< adjacency_list< EL, VL, D, VP, EP, GP >, VPS, EPS > write( + const adjacency_list< EL, VL, D, VP, EP, GP >& g, VPS, EPS) { - return GraphPrinter,VPS,EPS>(g); + return GraphPrinter< adjacency_list< EL, VL, D, VP, EP, GP >, VPS, EPS >(g); } /// write the graph with all internal vertex and edge properties -template -GraphPrinter,VP,EP> -write( const adjacency_list& g ) +template < class EL, class VL, class D, class VP, class EP, class GP > +GraphPrinter< adjacency_list< EL, VL, D, VP, EP, GP >, VP, EP > write( + const adjacency_list< EL, VL, D, VP, EP, GP >& g) { - return GraphPrinter,VP,EP>(g); + return GraphPrinter< adjacency_list< EL, VL, D, VP, EP, GP >, VP, EP >(g); } // user methods //========================================================================= -}// boost +} // boost #endif diff --git a/include/boost/graph/adjacency_matrix.hpp b/include/boost/graph/adjacency_matrix.hpp index 571bc3d3d..a089e1cb9 100644 --- a/include/boost/graph/adjacency_matrix.hpp +++ b/include/boost/graph/adjacency_matrix.hpp @@ -35,133 +35,139 @@ #include #include -namespace boost { +namespace boost +{ - namespace detail { +namespace detail +{ - template - class matrix_edge_desc_impl : public edge_desc_impl + template < class Directed, class Vertex > + class matrix_edge_desc_impl : public edge_desc_impl< Directed, Vertex > { - typedef edge_desc_impl Base; + typedef edge_desc_impl< Directed, Vertex > Base; + public: - matrix_edge_desc_impl() { } - matrix_edge_desc_impl(bool exists, Vertex s, Vertex d, - const void* ep = 0) - : Base(s, d, ep), m_exists(exists) { } - bool exists() const { return m_exists; } + matrix_edge_desc_impl() {} + matrix_edge_desc_impl( + bool exists, Vertex s, Vertex d, const void* ep = 0) + : Base(s, d, ep), m_exists(exists) + { + } + bool exists() const { return m_exists; } + private: - bool m_exists; + bool m_exists; }; - struct does_edge_exist { - template - bool operator()(const Edge& e) const { return e.exists(); } + struct does_edge_exist + { + template < class Edge > bool operator()(const Edge& e) const + { + return e.exists(); + } }; // Note to self... The int for get_edge_exists and set_edge exist helps // make these calls unambiguous. - template - bool get_edge_exists(const std::pair& stored_edge, int) { - return stored_edge.first; + template < typename EdgeProperty > + bool get_edge_exists( + const std::pair< bool, EdgeProperty >& stored_edge, int) + { + return stored_edge.first; } - template + template < typename EdgeProperty > void set_edge_exists( - std::pair& stored_edge, - bool flag, - int - ) { - stored_edge.first = flag; + std::pair< bool, EdgeProperty >& stored_edge, bool flag, int) + { + stored_edge.first = flag; } - template - bool get_edge_exists(const EdgeProxy& edge_proxy, ...) { - return edge_proxy; + template < typename EdgeProxy > + bool get_edge_exists(const EdgeProxy& edge_proxy, ...) + { + return edge_proxy; } - template - EdgeProxy& set_edge_exists(EdgeProxy& edge_proxy, bool flag, ...) { - edge_proxy = flag; - return edge_proxy; // just to avoid never used warning + template < typename EdgeProxy > + EdgeProxy& set_edge_exists(EdgeProxy& edge_proxy, bool flag, ...) + { + edge_proxy = flag; + return edge_proxy; // just to avoid never used warning } - // NOTE: These functions collide with the get_property function for // accessing bundled graph properties. Be excplicit when using them. - template - const EdgeProperty& - get_edge_property(const std::pair& stored_edge) { - return stored_edge.second; + template < typename EdgeProperty > + const EdgeProperty& get_edge_property( + const std::pair< bool, EdgeProperty >& stored_edge) + { + return stored_edge.second; } - template - EdgeProperty& - get_edge_property(std::pair& stored_edge) { - return stored_edge.second; + template < typename EdgeProperty > + EdgeProperty& get_edge_property( + std::pair< bool, EdgeProperty >& stored_edge) + { + return stored_edge.second; } - template - inline void - set_edge_property(std::pair& stored_edge, - const EdgeProperty& ep, int) { - stored_edge.second = ep; + template < typename StoredEdgeProperty, typename EdgeProperty > + inline void set_edge_property( + std::pair< bool, StoredEdgeProperty >& stored_edge, + const EdgeProperty& ep, int) + { + stored_edge.second = ep; } - inline const no_property& get_edge_property(const char&) { - static no_property s_prop; - return s_prop; + inline const no_property& get_edge_property(const char&) + { + static no_property s_prop; + return s_prop; } - inline no_property& get_edge_property(char&) { - static no_property s_prop; - return s_prop; + inline no_property& get_edge_property(char&) + { + static no_property s_prop; + return s_prop; + } + template < typename EdgeProxy, typename EdgeProperty > + inline void set_edge_property(EdgeProxy, const EdgeProperty&, ...) + { } - template - inline void set_edge_property(EdgeProxy, const EdgeProperty&, ...) {} //======================================================================= // Directed Out Edge Iterator - template < - typename VertexDescriptor, typename MatrixIter - , typename VerticesSizeType, typename EdgeDescriptor - > + template < typename VertexDescriptor, typename MatrixIter, + typename VerticesSizeType, typename EdgeDescriptor > struct dir_adj_matrix_out_edge_iter - : iterator_adaptor< - dir_adj_matrix_out_edge_iter - , MatrixIter - , EdgeDescriptor - , use_default - , EdgeDescriptor - , std::ptrdiff_t - > + : iterator_adaptor< dir_adj_matrix_out_edge_iter< VertexDescriptor, + MatrixIter, VerticesSizeType, EdgeDescriptor >, + MatrixIter, EdgeDescriptor, use_default, EdgeDescriptor, + std::ptrdiff_t > { typedef iterator_adaptor< - dir_adj_matrix_out_edge_iter - , MatrixIter - , EdgeDescriptor - , use_default - , EdgeDescriptor - , std::ptrdiff_t - > super_t; - - dir_adj_matrix_out_edge_iter() { } - - dir_adj_matrix_out_edge_iter( - const MatrixIter& i - , const VertexDescriptor& src - , const VerticesSizeType& n - ) - : super_t(i), m_src(src), m_targ(0), m_n(n) - { } - - void increment() { + dir_adj_matrix_out_edge_iter< VertexDescriptor, MatrixIter, + VerticesSizeType, EdgeDescriptor >, + MatrixIter, EdgeDescriptor, use_default, EdgeDescriptor, + std::ptrdiff_t > + super_t; + + dir_adj_matrix_out_edge_iter() {} + + dir_adj_matrix_out_edge_iter(const MatrixIter& i, + const VertexDescriptor& src, const VerticesSizeType& n) + : super_t(i), m_src(src), m_targ(0), m_n(n) + { + } + + void increment() + { ++this->base_reference(); ++m_targ; } - inline EdgeDescriptor - dereference() const + inline EdgeDescriptor dereference() const { - return EdgeDescriptor(get_edge_exists(*this->base(), 0), - m_src, m_targ, - &get_edge_property(*this->base())); + return EdgeDescriptor(get_edge_exists(*this->base(), 0), m_src, + m_targ, &get_edge_property(*this->base())); } VertexDescriptor m_src, m_targ; VerticesSizeType m_n; @@ -170,55 +176,46 @@ namespace boost { //======================================================================= // Directed In Edge Iterator - template < - typename VertexDescriptor, typename MatrixIter - , typename VerticesSizeType, typename EdgeDescriptor - > + template < typename VertexDescriptor, typename MatrixIter, + typename VerticesSizeType, typename EdgeDescriptor > struct dir_adj_matrix_in_edge_iter - : iterator_adaptor< - dir_adj_matrix_in_edge_iter - , MatrixIter - , EdgeDescriptor - , use_default - , EdgeDescriptor - , std::ptrdiff_t - > + : iterator_adaptor< dir_adj_matrix_in_edge_iter< VertexDescriptor, + MatrixIter, VerticesSizeType, EdgeDescriptor >, + MatrixIter, EdgeDescriptor, use_default, EdgeDescriptor, + std::ptrdiff_t > { typedef iterator_adaptor< - dir_adj_matrix_in_edge_iter - , MatrixIter - , EdgeDescriptor - , use_default - , EdgeDescriptor - , std::ptrdiff_t - > super_t; - - dir_adj_matrix_in_edge_iter() { } - - dir_adj_matrix_in_edge_iter( - const MatrixIter& i - , const MatrixIter& last - , const VertexDescriptor& tgt - , const VerticesSizeType& n - ) - : super_t(i), m_last(last), m_src(0), m_targ(tgt), m_n(n) - { } - - void increment() { - if (VerticesSizeType(m_last - this->base_reference()) >= m_n) { - this->base_reference() += m_n; - ++m_src; - } else { - this->base_reference() = m_last; - } + dir_adj_matrix_in_edge_iter< VertexDescriptor, MatrixIter, + VerticesSizeType, EdgeDescriptor >, + MatrixIter, EdgeDescriptor, use_default, EdgeDescriptor, + std::ptrdiff_t > + super_t; + + dir_adj_matrix_in_edge_iter() {} + + dir_adj_matrix_in_edge_iter(const MatrixIter& i, const MatrixIter& last, + const VertexDescriptor& tgt, const VerticesSizeType& n) + : super_t(i), m_last(last), m_src(0), m_targ(tgt), m_n(n) + { + } + + void increment() + { + if (VerticesSizeType(m_last - this->base_reference()) >= m_n) + { + this->base_reference() += m_n; + ++m_src; + } + else + { + this->base_reference() = m_last; + } } - inline EdgeDescriptor - dereference() const + inline EdgeDescriptor dereference() const { - return EdgeDescriptor(get_edge_exists(*this->base(), 0), - m_src, m_targ, - &get_edge_property(*this->base())); + return EdgeDescriptor(get_edge_exists(*this->base(), 0), m_src, + m_targ, &get_edge_property(*this->base())); } MatrixIter m_last; VertexDescriptor m_src, m_targ; @@ -228,63 +225,51 @@ namespace boost { //======================================================================= // Undirected Out Edge Iterator - template < - typename VertexDescriptor, typename MatrixIter - , typename VerticesSizeType, typename EdgeDescriptor - > + template < typename VertexDescriptor, typename MatrixIter, + typename VerticesSizeType, typename EdgeDescriptor > struct undir_adj_matrix_out_edge_iter - : iterator_adaptor< - undir_adj_matrix_out_edge_iter - , MatrixIter - , EdgeDescriptor - , use_default - , EdgeDescriptor - , std::ptrdiff_t - > + : iterator_adaptor< undir_adj_matrix_out_edge_iter< VertexDescriptor, + MatrixIter, VerticesSizeType, EdgeDescriptor >, + MatrixIter, EdgeDescriptor, use_default, EdgeDescriptor, + std::ptrdiff_t > { typedef iterator_adaptor< - undir_adj_matrix_out_edge_iter - , MatrixIter - , EdgeDescriptor - , use_default - , EdgeDescriptor - , std::ptrdiff_t - > super_t; - - undir_adj_matrix_out_edge_iter() { } - - undir_adj_matrix_out_edge_iter( - const MatrixIter& i - , const VertexDescriptor& src - , const VerticesSizeType& n - ) - : super_t(i), m_src(src), m_inc(src), m_targ(0), m_n(n) - {} + undir_adj_matrix_out_edge_iter< VertexDescriptor, MatrixIter, + VerticesSizeType, EdgeDescriptor >, + MatrixIter, EdgeDescriptor, use_default, EdgeDescriptor, + std::ptrdiff_t > + super_t; + + undir_adj_matrix_out_edge_iter() {} + + undir_adj_matrix_out_edge_iter(const MatrixIter& i, + const VertexDescriptor& src, const VerticesSizeType& n) + : super_t(i), m_src(src), m_inc(src), m_targ(0), m_n(n) + { + } void increment() { - if (m_targ < m_src) // first half + if (m_targ < m_src) // first half { ++this->base_reference(); } else if (m_targ < m_n - 1) - { // second half + { // second half ++m_inc; this->base_reference() += m_inc; } else - { // past-the-end + { // past-the-end this->base_reference() += m_n - m_src; } ++m_targ; } - inline EdgeDescriptor - dereference() const + inline EdgeDescriptor dereference() const { - return EdgeDescriptor(get_edge_exists(*this->base(), 0), - m_src, m_targ, - &get_edge_property(*this->base())); + return EdgeDescriptor(get_edge_exists(*this->base(), 0), m_src, + m_targ, &get_edge_property(*this->base())); } VertexDescriptor m_src, m_inc, m_targ; @@ -294,63 +279,51 @@ namespace boost { //======================================================================= // Undirected In Edge Iterator - template < - typename VertexDescriptor, typename MatrixIter - , typename VerticesSizeType, typename EdgeDescriptor - > + template < typename VertexDescriptor, typename MatrixIter, + typename VerticesSizeType, typename EdgeDescriptor > struct undir_adj_matrix_in_edge_iter - : iterator_adaptor< - undir_adj_matrix_in_edge_iter - , MatrixIter - , EdgeDescriptor - , use_default - , EdgeDescriptor - , std::ptrdiff_t - > + : iterator_adaptor< undir_adj_matrix_in_edge_iter< VertexDescriptor, + MatrixIter, VerticesSizeType, EdgeDescriptor >, + MatrixIter, EdgeDescriptor, use_default, EdgeDescriptor, + std::ptrdiff_t > { typedef iterator_adaptor< - undir_adj_matrix_in_edge_iter - , MatrixIter - , EdgeDescriptor - , use_default - , EdgeDescriptor - , std::ptrdiff_t - > super_t; - - undir_adj_matrix_in_edge_iter() { } - - undir_adj_matrix_in_edge_iter( - const MatrixIter& i - , const VertexDescriptor& src - , const VerticesSizeType& n - ) - : super_t(i), m_src(src), m_inc(src), m_targ(0), m_n(n) - {} + undir_adj_matrix_in_edge_iter< VertexDescriptor, MatrixIter, + VerticesSizeType, EdgeDescriptor >, + MatrixIter, EdgeDescriptor, use_default, EdgeDescriptor, + std::ptrdiff_t > + super_t; + + undir_adj_matrix_in_edge_iter() {} + + undir_adj_matrix_in_edge_iter(const MatrixIter& i, + const VertexDescriptor& src, const VerticesSizeType& n) + : super_t(i), m_src(src), m_inc(src), m_targ(0), m_n(n) + { + } void increment() { - if (m_targ < m_src) // first half + if (m_targ < m_src) // first half { ++this->base_reference(); } else if (m_targ < m_n - 1) - { // second half + { // second half ++m_inc; this->base_reference() += m_inc; } else - { // past-the-end + { // past-the-end this->base_reference() += m_n - m_src; } ++m_targ; } - inline EdgeDescriptor - dereference() const + inline EdgeDescriptor dereference() const { - return EdgeDescriptor(get_edge_exists(*this->base(), 0), - m_targ, m_src, - &get_edge_property(*this->base())); + return EdgeDescriptor(get_edge_exists(*this->base(), 0), m_targ, + m_src, &get_edge_property(*this->base())); } VertexDescriptor m_src, m_inc, m_targ; @@ -360,31 +333,27 @@ namespace boost { //======================================================================= // Edge Iterator - template + template < typename Directed, typename MatrixIter, + typename VerticesSizeType, typename EdgeDescriptor > struct adj_matrix_edge_iter - : iterator_adaptor< - adj_matrix_edge_iter - , MatrixIter - , EdgeDescriptor - , use_default - , EdgeDescriptor - , std::ptrdiff_t - > + : iterator_adaptor< adj_matrix_edge_iter< Directed, MatrixIter, + VerticesSizeType, EdgeDescriptor >, + MatrixIter, EdgeDescriptor, use_default, EdgeDescriptor, + std::ptrdiff_t > { - typedef iterator_adaptor< - adj_matrix_edge_iter - , MatrixIter - , EdgeDescriptor - , use_default - , EdgeDescriptor - , std::ptrdiff_t - > super_t; + typedef iterator_adaptor< adj_matrix_edge_iter< Directed, MatrixIter, + VerticesSizeType, EdgeDescriptor >, + MatrixIter, EdgeDescriptor, use_default, EdgeDescriptor, + std::ptrdiff_t > + super_t; - adj_matrix_edge_iter() { } + adj_matrix_edge_iter() {} - adj_matrix_edge_iter(const MatrixIter& i, const MatrixIter& start, const VerticesSizeType& n) - : super_t(i), m_start(start), m_src(0), m_targ(0), m_n(n) { } + adj_matrix_edge_iter(const MatrixIter& i, const MatrixIter& start, + const VerticesSizeType& n) + : super_t(i), m_start(start), m_src(0), m_targ(0), m_n(n) + { + } void increment() { @@ -419,96 +388,105 @@ namespace boost { } } - inline EdgeDescriptor - dereference() const + inline EdgeDescriptor dereference() const { - return EdgeDescriptor(get_edge_exists(*this->base(), 0), - m_src, m_targ, - &get_edge_property(*this->base())); + return EdgeDescriptor(get_edge_exists(*this->base(), 0), m_src, + m_targ, &get_edge_property(*this->base())); } MatrixIter m_start; VerticesSizeType m_src, m_targ, m_n; }; - } // namespace detail +} // namespace detail - //========================================================================= - // Adjacency Matrix Traits - template - class adjacency_matrix_traits { +//========================================================================= +// Adjacency Matrix Traits +template < typename Directed = directedS > class adjacency_matrix_traits +{ typedef typename Directed::is_directed_t is_directed; - public: + +public: // The bidirectionalS tag is not allowed with the adjacency_matrix // graph type. Instead, use directedS, which also provides the // functionality required for a Bidirectional Graph (in_edges, // in_degree, etc.). - BOOST_STATIC_ASSERT(!(is_same::value)); + BOOST_STATIC_ASSERT(!(is_same< Directed, bidirectionalS >::value)); - typedef typename mpl::if_::type - directed_category; + typedef typename mpl::if_< is_directed, bidirectional_tag, + undirected_tag >::type directed_category; typedef disallow_parallel_edge_tag edge_parallel_category; typedef std::size_t vertex_descriptor; - typedef detail::matrix_edge_desc_impl edge_descriptor; - }; - - struct adjacency_matrix_class_tag { }; - - struct adj_matrix_traversal_tag : - public virtual adjacency_matrix_tag, - public virtual vertex_list_graph_tag, - public virtual incidence_graph_tag, - public virtual adjacency_graph_tag, - public virtual edge_list_graph_tag { }; - - //========================================================================= - // Adjacency Matrix Class - template > - class adjacency_matrix { + typedef detail::matrix_edge_desc_impl< directed_category, + vertex_descriptor > + edge_descriptor; +}; + +struct adjacency_matrix_class_tag +{ +}; + +struct adj_matrix_traversal_tag : public virtual adjacency_matrix_tag, + public virtual vertex_list_graph_tag, + public virtual incidence_graph_tag, + public virtual adjacency_graph_tag, + public virtual edge_list_graph_tag +{ +}; + +//========================================================================= +// Adjacency Matrix Class +template < typename Directed = directedS, typename VertexProperty = no_property, + typename EdgeProperty = no_property, typename GraphProperty = no_property, + typename Allocator = std::allocator< bool > > +class adjacency_matrix +{ typedef adjacency_matrix self; - typedef adjacency_matrix_traits Traits; + typedef adjacency_matrix_traits< Directed > Traits; - public: +public: // The bidirectionalS tag is not allowed with the adjacency_matrix // graph type. Instead, use directedS, which also provides the // functionality required for a Bidirectional Graph (in_edges, // in_degree, etc.). - BOOST_STATIC_ASSERT(!(is_same::value)); + BOOST_STATIC_ASSERT(!(is_same< Directed, bidirectionalS >::value)); typedef GraphProperty graph_property_type; - typedef typename lookup_one_property::type graph_bundled; + typedef typename lookup_one_property< GraphProperty, graph_bundle_t >::type + graph_bundled; typedef VertexProperty vertex_property_type; - typedef typename lookup_one_property::type vertex_bundled; + typedef + typename lookup_one_property< VertexProperty, vertex_bundle_t >::type + vertex_bundled; typedef EdgeProperty edge_property_type; - typedef typename lookup_one_property::type edge_bundled; + typedef typename lookup_one_property< EdgeProperty, edge_bundle_t >::type + edge_bundled; - public: // should be private - typedef typename mpl::if_::type, - std::pair, char>::type StoredEdge; +public: // should be private + typedef + typename mpl::if_< typename has_property< edge_property_type >::type, + std::pair< bool, edge_property_type >, char >::type StoredEdge; #if defined(BOOST_NO_STD_ALLOCATOR) - typedef std::vector Matrix; + typedef std::vector< StoredEdge > Matrix; #else #if defined(BOOST_NO_CXX11_ALLOCATOR) - typedef typename Allocator::template rebind::other Alloc; + typedef typename Allocator::template rebind< StoredEdge >::other Alloc; #else - typedef typename std::allocator_traits::template rebind_alloc Alloc; + typedef typename std::allocator_traits< Allocator >::template rebind_alloc< + StoredEdge > + Alloc; #endif - typedef std::vector Matrix; + typedef std::vector< StoredEdge, Alloc > Matrix; #endif typedef typename Matrix::iterator MatrixIter; typedef typename Matrix::size_type size_type; - public: + +public: // Graph concept required types typedef typename Traits::vertex_descriptor vertex_descriptor; typedef typename Traits::edge_descriptor edge_descriptor; @@ -518,722 +496,801 @@ namespace boost { static vertex_descriptor null_vertex() { - return (std::numeric_limits::max)(); + return (std::numeric_limits< vertex_descriptor >::max)(); } - //private: if friends worked, these would be private + // private: if friends worked, these would be private - typedef detail::dir_adj_matrix_out_edge_iter< - vertex_descriptor, MatrixIter, size_type, edge_descriptor - > DirOutEdgeIter; + typedef detail::dir_adj_matrix_out_edge_iter< vertex_descriptor, MatrixIter, + size_type, edge_descriptor > + DirOutEdgeIter; - typedef detail::undir_adj_matrix_out_edge_iter< - vertex_descriptor, MatrixIter, size_type, edge_descriptor - > UnDirOutEdgeIter; + typedef detail::undir_adj_matrix_out_edge_iter< vertex_descriptor, + MatrixIter, size_type, edge_descriptor > + UnDirOutEdgeIter; - typedef typename mpl::if_< - typename Directed::is_directed_t, DirOutEdgeIter, UnDirOutEdgeIter - >::type unfiltered_out_edge_iter; + typedef typename mpl::if_< typename Directed::is_directed_t, DirOutEdgeIter, + UnDirOutEdgeIter >::type unfiltered_out_edge_iter; - typedef detail::dir_adj_matrix_in_edge_iter< - vertex_descriptor, MatrixIter, size_type, edge_descriptor - > DirInEdgeIter; + typedef detail::dir_adj_matrix_in_edge_iter< vertex_descriptor, MatrixIter, + size_type, edge_descriptor > + DirInEdgeIter; - typedef detail::undir_adj_matrix_in_edge_iter< - vertex_descriptor, MatrixIter, size_type, edge_descriptor - > UnDirInEdgeIter; + typedef detail::undir_adj_matrix_in_edge_iter< vertex_descriptor, + MatrixIter, size_type, edge_descriptor > + UnDirInEdgeIter; - typedef typename mpl::if_< - typename Directed::is_directed_t, DirInEdgeIter, UnDirInEdgeIter - >::type unfiltered_in_edge_iter; + typedef typename mpl::if_< typename Directed::is_directed_t, DirInEdgeIter, + UnDirInEdgeIter >::type unfiltered_in_edge_iter; - typedef detail::adj_matrix_edge_iter< - Directed, MatrixIter, size_type, edge_descriptor - > unfiltered_edge_iter; - - public: + typedef detail::adj_matrix_edge_iter< Directed, MatrixIter, size_type, + edge_descriptor > + unfiltered_edge_iter; +public: // IncidenceGraph concept required types - typedef filter_iterator - out_edge_iterator; + typedef filter_iterator< detail::does_edge_exist, unfiltered_out_edge_iter > + out_edge_iterator; typedef size_type degree_size_type; // BidirectionalGraph required types - typedef filter_iterator - in_edge_iterator; + typedef filter_iterator< detail::does_edge_exist, unfiltered_in_edge_iter > + in_edge_iterator; // AdjacencyGraph required types - typedef typename adjacency_iterator_generator::type adjacency_iterator; + typedef typename adjacency_iterator_generator< self, vertex_descriptor, + out_edge_iterator >::type adjacency_iterator; // VertexListGraph required types typedef size_type vertices_size_type; - typedef integer_range VertexList; + typedef integer_range< vertex_descriptor > VertexList; typedef typename VertexList::iterator vertex_iterator; // EdgeListGraph required types typedef size_type edges_size_type; - typedef filter_iterator< - detail::does_edge_exist, unfiltered_edge_iter - > edge_iterator; + typedef filter_iterator< detail::does_edge_exist, unfiltered_edge_iter > + edge_iterator; // PropertyGraph required types typedef adjacency_matrix_class_tag graph_tag; // Constructor required by MutableGraph - adjacency_matrix(vertices_size_type n_vertices, - const GraphProperty& p = GraphProperty()) - : m_matrix(Directed::is_directed ? - (n_vertices * n_vertices) - : (n_vertices * (n_vertices + 1) / 2)), - m_vertex_set(0, n_vertices), - m_vertex_properties(n_vertices), - m_num_edges(0), - m_property(p) { } - - template - adjacency_matrix(EdgeIterator first, - EdgeIterator last, - vertices_size_type n_vertices, - const GraphProperty& p = GraphProperty()) - : m_matrix(Directed::is_directed ? - (n_vertices * n_vertices) - : (n_vertices * (n_vertices + 1) / 2)), - m_vertex_set(0, n_vertices), - m_vertex_properties(n_vertices), - m_num_edges(0), - m_property(p) + adjacency_matrix( + vertices_size_type n_vertices, const GraphProperty& p = GraphProperty()) + : m_matrix(Directed::is_directed ? (n_vertices * n_vertices) + : (n_vertices * (n_vertices + 1) / 2)) + , m_vertex_set(0, n_vertices) + , m_vertex_properties(n_vertices) + , m_num_edges(0) + , m_property(p) { - for (; first != last; ++first) { - add_edge(first->first, first->second, *this); - } } - template - adjacency_matrix(EdgeIterator first, - EdgeIterator last, - EdgePropertyIterator ep_iter, - vertices_size_type n_vertices, - const GraphProperty& p = GraphProperty()) - : m_matrix(Directed::is_directed ? - (n_vertices * n_vertices) - : (n_vertices * (n_vertices + 1) / 2)), - m_vertex_set(0, n_vertices), - m_vertex_properties(n_vertices), - m_num_edges(0), - m_property(p) + template < typename EdgeIterator > + adjacency_matrix(EdgeIterator first, EdgeIterator last, + vertices_size_type n_vertices, const GraphProperty& p = GraphProperty()) + : m_matrix(Directed::is_directed ? (n_vertices * n_vertices) + : (n_vertices * (n_vertices + 1) / 2)) + , m_vertex_set(0, n_vertices) + , m_vertex_properties(n_vertices) + , m_num_edges(0) + , m_property(p) + { + for (; first != last; ++first) + { + add_edge(first->first, first->second, *this); + } + } + + template < typename EdgeIterator, typename EdgePropertyIterator > + adjacency_matrix(EdgeIterator first, EdgeIterator last, + EdgePropertyIterator ep_iter, vertices_size_type n_vertices, + const GraphProperty& p = GraphProperty()) + : m_matrix(Directed::is_directed ? (n_vertices * n_vertices) + : (n_vertices * (n_vertices + 1) / 2)) + , m_vertex_set(0, n_vertices) + , m_vertex_properties(n_vertices) + , m_num_edges(0) + , m_property(p) { - for (; first != last; ++first, ++ep_iter) { - add_edge(first->first, first->second, *ep_iter, *this); - } + for (; first != last; ++first, ++ep_iter) + { + add_edge(first->first, first->second, *ep_iter, *this); + } } #ifndef BOOST_GRAPH_NO_BUNDLED_PROPERTIES // Directly access a vertex or edge bundle vertex_bundled& operator[](vertex_descriptor v) - { return get(vertex_bundle, *this, v); } + { + return get(vertex_bundle, *this, v); + } const vertex_bundled& operator[](vertex_descriptor v) const - { return get(vertex_bundle, *this, v); } + { + return get(vertex_bundle, *this, v); + } edge_bundled& operator[](edge_descriptor e) - { return get(edge_bundle, *this, e); } + { + return get(edge_bundle, *this, e); + } const edge_bundled& operator[](edge_descriptor e) const - { return get(edge_bundle, *this, e); } + { + return get(edge_bundle, *this, e); + } - graph_bundled& operator[](graph_bundle_t) - { return get_property(*this); } + graph_bundled& operator[](graph_bundle_t) { return get_property(*this); } const graph_bundled& operator[](graph_bundle_t) const - { return get_property(*this); } + { + return get_property(*this); + } #endif - //private: if friends worked, these would be private - - typename Matrix::const_reference - get_edge(vertex_descriptor u, vertex_descriptor v) const { - if (Directed::is_directed) - return m_matrix[u * m_vertex_set.size() + v]; - else { - if (v > u) - std::swap(u, v); - return m_matrix[u * (u + 1)/2 + v]; - } + // private: if friends worked, these would be private + + typename Matrix::const_reference get_edge( + vertex_descriptor u, vertex_descriptor v) const + { + if (Directed::is_directed) + return m_matrix[u * m_vertex_set.size() + v]; + else + { + if (v > u) + std::swap(u, v); + return m_matrix[u * (u + 1) / 2 + v]; + } } - typename Matrix::reference - get_edge(vertex_descriptor u, vertex_descriptor v) { - if (Directed::is_directed) - return m_matrix[u * m_vertex_set.size() + v]; - else { - if (v > u) - std::swap(u, v); - return m_matrix[u * (u + 1)/2 + v]; - } + typename Matrix::reference get_edge( + vertex_descriptor u, vertex_descriptor v) + { + if (Directed::is_directed) + return m_matrix[u * m_vertex_set.size() + v]; + else + { + if (v > u) + std::swap(u, v); + return m_matrix[u * (u + 1) / 2 + v]; + } } Matrix m_matrix; VertexList m_vertex_set; - std::vector m_vertex_properties; + std::vector< vertex_property_type > m_vertex_properties; size_type m_num_edges; graph_property_type m_property; - }; - - //========================================================================= - // Functions required by the AdjacencyMatrix concept - - template - std::pair::edge_descriptor, - bool> - edge(typename adjacency_matrix::vertex_descriptor u, - typename adjacency_matrix::vertex_descriptor v, - const adjacency_matrix& g) - { - bool exists = detail::get_edge_exists(g.get_edge(u,v), 0); - typename adjacency_matrix::edge_descriptor - e(exists, u, v, &detail::get_edge_property(g.get_edge(u,v))); +}; + +//========================================================================= +// Functions required by the AdjacencyMatrix concept + +template < typename D, typename VP, typename EP, typename GP, typename A > +std::pair< typename adjacency_matrix< D, VP, EP, GP, A >::edge_descriptor, + bool > +edge(typename adjacency_matrix< D, VP, EP, GP, A >::vertex_descriptor u, + typename adjacency_matrix< D, VP, EP, GP, A >::vertex_descriptor v, + const adjacency_matrix< D, VP, EP, GP, A >& g) +{ + bool exists = detail::get_edge_exists(g.get_edge(u, v), 0); + typename adjacency_matrix< D, VP, EP, GP, A >::edge_descriptor e( + exists, u, v, &detail::get_edge_property(g.get_edge(u, v))); return std::make_pair(e, exists); - } - - //========================================================================= - // Functions required by the IncidenceGraph concept - - // O(1) - template - std::pair::out_edge_iterator, - typename adjacency_matrix::out_edge_iterator> - out_edges - (typename adjacency_matrix::vertex_descriptor u, - const adjacency_matrix& g_) - { - typedef adjacency_matrix Graph; - Graph& g = const_cast(g_); +} + +//========================================================================= +// Functions required by the IncidenceGraph concept + +// O(1) +template < typename VP, typename EP, typename GP, typename A > +std::pair< + typename adjacency_matrix< directedS, VP, EP, GP, A >::out_edge_iterator, + typename adjacency_matrix< directedS, VP, EP, GP, A >::out_edge_iterator > +out_edges( + typename adjacency_matrix< directedS, VP, EP, GP, A >::vertex_descriptor u, + const adjacency_matrix< directedS, VP, EP, GP, A >& g_) +{ + typedef adjacency_matrix< directedS, VP, EP, GP, A > Graph; + Graph& g = const_cast< Graph& >(g_); typename Graph::vertices_size_type offset = u * g.m_vertex_set.size(); typename Graph::MatrixIter f = g.m_matrix.begin() + offset; typename Graph::MatrixIter l = f + g.m_vertex_set.size(); - typename Graph::unfiltered_out_edge_iter - first(f, u, g.m_vertex_set.size()) - , last(l, u, g.m_vertex_set.size()); + typename Graph::unfiltered_out_edge_iter first(f, u, g.m_vertex_set.size()), + last(l, u, g.m_vertex_set.size()); detail::does_edge_exist pred; typedef typename Graph::out_edge_iterator out_edge_iterator; return std::make_pair(out_edge_iterator(pred, first, last), - out_edge_iterator(pred, last, last)); - } - - // O(1) - template - std::pair< - typename adjacency_matrix::out_edge_iterator, - typename adjacency_matrix::out_edge_iterator> - out_edges - (typename adjacency_matrix::vertex_descriptor u, - const adjacency_matrix& g_) - { - typedef adjacency_matrix Graph; - Graph& g = const_cast(g_); + out_edge_iterator(pred, last, last)); +} + +// O(1) +template < typename VP, typename EP, typename GP, typename A > +std::pair< + typename adjacency_matrix< undirectedS, VP, EP, GP, A >::out_edge_iterator, + typename adjacency_matrix< undirectedS, VP, EP, GP, A >::out_edge_iterator > +out_edges( + typename adjacency_matrix< undirectedS, VP, EP, GP, A >::vertex_descriptor + u, + const adjacency_matrix< undirectedS, VP, EP, GP, A >& g_) +{ + typedef adjacency_matrix< undirectedS, VP, EP, GP, A > Graph; + Graph& g = const_cast< Graph& >(g_); typename Graph::vertices_size_type offset = u * (u + 1) / 2; typename Graph::MatrixIter f = g.m_matrix.begin() + offset; typename Graph::MatrixIter l = g.m_matrix.end(); - typename Graph::unfiltered_out_edge_iter - first(f, u, g.m_vertex_set.size()) - , last(l, u, g.m_vertex_set.size()); + typename Graph::unfiltered_out_edge_iter first(f, u, g.m_vertex_set.size()), + last(l, u, g.m_vertex_set.size()); detail::does_edge_exist pred; typedef typename Graph::out_edge_iterator out_edge_iterator; return std::make_pair(out_edge_iterator(pred, first, last), - out_edge_iterator(pred, last, last)); - } - - // O(N) - template - typename adjacency_matrix::degree_size_type - out_degree(typename adjacency_matrix::vertex_descriptor u, - const adjacency_matrix& g) - { - typename adjacency_matrix::degree_size_type n = 0; - typename adjacency_matrix::out_edge_iterator f, l; + out_edge_iterator(pred, last, last)); +} + +// O(N) +template < typename D, typename VP, typename EP, typename GP, typename A > +typename adjacency_matrix< D, VP, EP, GP, A >::degree_size_type out_degree( + typename adjacency_matrix< D, VP, EP, GP, A >::vertex_descriptor u, + const adjacency_matrix< D, VP, EP, GP, A >& g) +{ + typename adjacency_matrix< D, VP, EP, GP, A >::degree_size_type n = 0; + typename adjacency_matrix< D, VP, EP, GP, A >::out_edge_iterator f, l; for (boost::tie(f, l) = out_edges(u, g); f != l; ++f) - ++n; + ++n; return n; - } - - // O(1) - template - typename adjacency_matrix::vertex_descriptor - source(const detail::matrix_edge_desc_impl& e, - const adjacency_matrix&) - { +} + +// O(1) +template < typename D, typename VP, typename EP, typename GP, typename A, + typename Dir, typename Vertex > +typename adjacency_matrix< D, VP, EP, GP, A >::vertex_descriptor source( + const detail::matrix_edge_desc_impl< Dir, Vertex >& e, + const adjacency_matrix< D, VP, EP, GP, A >&) +{ return e.m_source; - } - - // O(1) - template - typename adjacency_matrix::vertex_descriptor - target(const detail::matrix_edge_desc_impl& e, - const adjacency_matrix&) - { +} + +// O(1) +template < typename D, typename VP, typename EP, typename GP, typename A, + typename Dir, typename Vertex > +typename adjacency_matrix< D, VP, EP, GP, A >::vertex_descriptor target( + const detail::matrix_edge_desc_impl< Dir, Vertex >& e, + const adjacency_matrix< D, VP, EP, GP, A >&) +{ return e.m_target; - } - - //========================================================================= - // Functions required by the BidirectionalGraph concept - - // O(1) - template - std::pair::in_edge_iterator, - typename adjacency_matrix::in_edge_iterator> - in_edges - (typename adjacency_matrix::vertex_descriptor u, - const adjacency_matrix& g_) - { - typedef adjacency_matrix Graph; - Graph& g = const_cast(g_); +} + +//========================================================================= +// Functions required by the BidirectionalGraph concept + +// O(1) +template < typename VP, typename EP, typename GP, typename A > +std::pair< + typename adjacency_matrix< directedS, VP, EP, GP, A >::in_edge_iterator, + typename adjacency_matrix< directedS, VP, EP, GP, A >::in_edge_iterator > +in_edges( + typename adjacency_matrix< directedS, VP, EP, GP, A >::vertex_descriptor u, + const adjacency_matrix< directedS, VP, EP, GP, A >& g_) +{ + typedef adjacency_matrix< directedS, VP, EP, GP, A > Graph; + Graph& g = const_cast< Graph& >(g_); typename Graph::MatrixIter f = g.m_matrix.begin() + u; typename Graph::MatrixIter l = g.m_matrix.end(); - typename Graph::unfiltered_in_edge_iter - first(f, l, u, g.m_vertex_set.size()) - , last(l, l, u, g.m_vertex_set.size()); + typename Graph::unfiltered_in_edge_iter first( + f, l, u, g.m_vertex_set.size()), + last(l, l, u, g.m_vertex_set.size()); detail::does_edge_exist pred; typedef typename Graph::in_edge_iterator in_edge_iterator; return std::make_pair(in_edge_iterator(pred, first, last), - in_edge_iterator(pred, last, last)); - } - - // O(1) - template - std::pair< - typename adjacency_matrix::in_edge_iterator, - typename adjacency_matrix::in_edge_iterator> - in_edges - (typename adjacency_matrix::vertex_descriptor u, - const adjacency_matrix& g_) - { - typedef adjacency_matrix Graph; - Graph& g = const_cast(g_); + in_edge_iterator(pred, last, last)); +} + +// O(1) +template < typename VP, typename EP, typename GP, typename A > +std::pair< + typename adjacency_matrix< undirectedS, VP, EP, GP, A >::in_edge_iterator, + typename adjacency_matrix< undirectedS, VP, EP, GP, A >::in_edge_iterator > +in_edges( + typename adjacency_matrix< undirectedS, VP, EP, GP, A >::vertex_descriptor + u, + const adjacency_matrix< undirectedS, VP, EP, GP, A >& g_) +{ + typedef adjacency_matrix< undirectedS, VP, EP, GP, A > Graph; + Graph& g = const_cast< Graph& >(g_); typename Graph::vertices_size_type offset = u * (u + 1) / 2; typename Graph::MatrixIter f = g.m_matrix.begin() + offset; typename Graph::MatrixIter l = g.m_matrix.end(); - typename Graph::unfiltered_in_edge_iter - first(f, u, g.m_vertex_set.size()) - , last(l, u, g.m_vertex_set.size()); + typename Graph::unfiltered_in_edge_iter first(f, u, g.m_vertex_set.size()), + last(l, u, g.m_vertex_set.size()); detail::does_edge_exist pred; typedef typename Graph::in_edge_iterator in_edge_iterator; return std::make_pair(in_edge_iterator(pred, first, last), - in_edge_iterator(pred, last, last)); - } - - // O(N) - template - typename adjacency_matrix::degree_size_type - in_degree(typename adjacency_matrix::vertex_descriptor u, - const adjacency_matrix& g) - { - typename adjacency_matrix::degree_size_type n = 0; - typename adjacency_matrix::in_edge_iterator f, l; + in_edge_iterator(pred, last, last)); +} + +// O(N) +template < typename D, typename VP, typename EP, typename GP, typename A > +typename adjacency_matrix< D, VP, EP, GP, A >::degree_size_type in_degree( + typename adjacency_matrix< D, VP, EP, GP, A >::vertex_descriptor u, + const adjacency_matrix< D, VP, EP, GP, A >& g) +{ + typename adjacency_matrix< D, VP, EP, GP, A >::degree_size_type n = 0; + typename adjacency_matrix< D, VP, EP, GP, A >::in_edge_iterator f, l; for (boost::tie(f, l) = in_edges(u, g); f != l; ++f) - ++n; + ++n; return n; - } - - //========================================================================= - // Functions required by the AdjacencyGraph concept - - template - std::pair::adjacency_iterator, - typename adjacency_matrix::adjacency_iterator> - adjacent_vertices - (typename adjacency_matrix::vertex_descriptor u, - const adjacency_matrix& g_) - { - typedef adjacency_matrix Graph; - const Graph& cg = static_cast(g_); - Graph& g = const_cast(cg); - typedef typename Graph::adjacency_iterator adjacency_iterator; - typename Graph::out_edge_iterator first, last; - boost::tie(first, last) = out_edges(u, g); - return std::make_pair(adjacency_iterator(first, &g), - adjacency_iterator(last, &g)); - } - - //========================================================================= - // Functions required by the VertexListGraph concept - - template - std::pair::vertex_iterator, - typename adjacency_matrix::vertex_iterator> - vertices(const adjacency_matrix& g_) { - typedef adjacency_matrix Graph; - Graph& g = const_cast(g_); +} + +//========================================================================= +// Functions required by the AdjacencyGraph concept + +template < typename D, typename VP, typename EP, typename GP, typename A > +std::pair< typename adjacency_matrix< D, VP, EP, GP, A >::adjacency_iterator, + typename adjacency_matrix< D, VP, EP, GP, A >::adjacency_iterator > +adjacent_vertices( + typename adjacency_matrix< D, VP, EP, GP, A >::vertex_descriptor u, + const adjacency_matrix< D, VP, EP, GP, A >& g_) +{ + typedef adjacency_matrix< D, VP, EP, GP, A > Graph; + const Graph& cg = static_cast< const Graph& >(g_); + Graph& g = const_cast< Graph& >(cg); + typedef typename Graph::adjacency_iterator adjacency_iterator; + typename Graph::out_edge_iterator first, last; + boost::tie(first, last) = out_edges(u, g); + return std::make_pair( + adjacency_iterator(first, &g), adjacency_iterator(last, &g)); +} + +//========================================================================= +// Functions required by the VertexListGraph concept + +template < typename D, typename VP, typename EP, typename GP, typename A > +std::pair< typename adjacency_matrix< D, VP, EP, GP, A >::vertex_iterator, + typename adjacency_matrix< D, VP, EP, GP, A >::vertex_iterator > +vertices(const adjacency_matrix< D, VP, EP, GP, A >& g_) +{ + typedef adjacency_matrix< D, VP, EP, GP, A > Graph; + Graph& g = const_cast< Graph& >(g_); return std::make_pair(g.m_vertex_set.begin(), g.m_vertex_set.end()); - } +} - template - typename adjacency_matrix::vertices_size_type - num_vertices(const adjacency_matrix& g) { +template < typename D, typename VP, typename EP, typename GP, typename A > +typename adjacency_matrix< D, VP, EP, GP, A >::vertices_size_type num_vertices( + const adjacency_matrix< D, VP, EP, GP, A >& g) +{ return g.m_vertex_set.size(); - } - - //========================================================================= - // Functions required by the EdgeListGraph concept - - template - std::pair::edge_iterator, - typename adjacency_matrix::edge_iterator> - edges(const adjacency_matrix& g_) - { - typedef adjacency_matrix Graph; - Graph& g = const_cast(g_); - - typename Graph::unfiltered_edge_iter - first(g.m_matrix.begin(), g.m_matrix.begin(), - g.m_vertex_set.size()), - last(g.m_matrix.end(), g.m_matrix.begin(), - g.m_vertex_set.size()); +} + +//========================================================================= +// Functions required by the EdgeListGraph concept + +template < typename D, typename VP, typename EP, typename GP, typename A > +std::pair< typename adjacency_matrix< D, VP, EP, GP, A >::edge_iterator, + typename adjacency_matrix< D, VP, EP, GP, A >::edge_iterator > +edges(const adjacency_matrix< D, VP, EP, GP, A >& g_) +{ + typedef adjacency_matrix< D, VP, EP, GP, A > Graph; + Graph& g = const_cast< Graph& >(g_); + + typename Graph::unfiltered_edge_iter first( + g.m_matrix.begin(), g.m_matrix.begin(), g.m_vertex_set.size()), + last(g.m_matrix.end(), g.m_matrix.begin(), g.m_vertex_set.size()); detail::does_edge_exist pred; typedef typename Graph::edge_iterator edge_iterator; - return std::make_pair(edge_iterator(pred, first, last), - edge_iterator(pred, last, last)); - } - - // O(1) - template - typename adjacency_matrix::edges_size_type - num_edges(const adjacency_matrix& g) - { + return std::make_pair( + edge_iterator(pred, first, last), edge_iterator(pred, last, last)); +} + +// O(1) +template < typename D, typename VP, typename EP, typename GP, typename A > +typename adjacency_matrix< D, VP, EP, GP, A >::edges_size_type num_edges( + const adjacency_matrix< D, VP, EP, GP, A >& g) +{ return g.m_num_edges; - } - - //========================================================================= - // Functions required by the MutableGraph concept - - // O(1) - template - std::pair::edge_descriptor, bool> - add_edge(typename adjacency_matrix::vertex_descriptor u, - typename adjacency_matrix::vertex_descriptor v, - const EP2& ep, - adjacency_matrix& g) - { - typedef typename adjacency_matrix::edge_descriptor - edge_descriptor; - if (detail::get_edge_exists(g.get_edge(u,v), 0) == false) { - ++(g.m_num_edges); - detail::set_edge_property(g.get_edge(u,v), EP(ep), 0); - detail::set_edge_exists(g.get_edge(u,v), true, 0); - return std::make_pair - (edge_descriptor(true, u, v, &detail::get_edge_property(g.get_edge(u,v))), - true); - } else - return std::make_pair - (edge_descriptor(true, u, v, &detail::get_edge_property(g.get_edge(u,v))), - false); - } - // O(1) - template - std::pair::edge_descriptor, bool> - add_edge(typename adjacency_matrix::vertex_descriptor u, - typename adjacency_matrix::vertex_descriptor v, - adjacency_matrix& g) - { +} + +//========================================================================= +// Functions required by the MutableGraph concept + +// O(1) +template < typename D, typename VP, typename EP, typename GP, typename A, + typename EP2 > +std::pair< typename adjacency_matrix< D, VP, EP, GP, A >::edge_descriptor, + bool > +add_edge(typename adjacency_matrix< D, VP, EP, GP, A >::vertex_descriptor u, + typename adjacency_matrix< D, VP, EP, GP, A >::vertex_descriptor v, + const EP2& ep, adjacency_matrix< D, VP, EP, GP, A >& g) +{ + typedef typename adjacency_matrix< D, VP, EP, GP, A >::edge_descriptor + edge_descriptor; + if (detail::get_edge_exists(g.get_edge(u, v), 0) == false) + { + ++(g.m_num_edges); + detail::set_edge_property(g.get_edge(u, v), EP(ep), 0); + detail::set_edge_exists(g.get_edge(u, v), true, 0); + return std::make_pair(edge_descriptor(true, u, v, + &detail::get_edge_property(g.get_edge(u, v))), + true); + } + else + return std::make_pair(edge_descriptor(true, u, v, + &detail::get_edge_property(g.get_edge(u, v))), + false); +} +// O(1) +template < typename D, typename VP, typename EP, typename GP, typename A > +std::pair< typename adjacency_matrix< D, VP, EP, GP, A >::edge_descriptor, + bool > +add_edge(typename adjacency_matrix< D, VP, EP, GP, A >::vertex_descriptor u, + typename adjacency_matrix< D, VP, EP, GP, A >::vertex_descriptor v, + adjacency_matrix< D, VP, EP, GP, A >& g) +{ EP ep; return add_edge(u, v, ep, g); - } - - // O(1) - template - void - remove_edge(typename adjacency_matrix::vertex_descriptor u, - typename adjacency_matrix::vertex_descriptor v, - adjacency_matrix& g) - { +} + +// O(1) +template < typename D, typename VP, typename EP, typename GP, typename A > +void remove_edge( + typename adjacency_matrix< D, VP, EP, GP, A >::vertex_descriptor u, + typename adjacency_matrix< D, VP, EP, GP, A >::vertex_descriptor v, + adjacency_matrix< D, VP, EP, GP, A >& g) +{ // Don'remove the edge unless it already exists. - if(detail::get_edge_exists(g.get_edge(u,v), 0)) { - --(g.m_num_edges); - detail::set_edge_exists(g.get_edge(u,v), false, 0); + if (detail::get_edge_exists(g.get_edge(u, v), 0)) + { + --(g.m_num_edges); + detail::set_edge_exists(g.get_edge(u, v), false, 0); } - } - - // O(1) - template - void - remove_edge(typename adjacency_matrix::edge_descriptor e, - adjacency_matrix& g) - { +} + +// O(1) +template < typename D, typename VP, typename EP, typename GP, typename A > +void remove_edge( + typename adjacency_matrix< D, VP, EP, GP, A >::edge_descriptor e, + adjacency_matrix< D, VP, EP, GP, A >& g) +{ remove_edge(source(e, g), target(e, g), g); - } +} - - template - inline typename adjacency_matrix::vertex_descriptor - add_vertex(adjacency_matrix& g) { +template < typename D, typename VP, typename EP, typename GP, typename A > +inline typename adjacency_matrix< D, VP, EP, GP, A >::vertex_descriptor +add_vertex(adjacency_matrix< D, VP, EP, GP, A >& g) +{ // UNDER CONSTRUCTION BOOST_ASSERT(false); return *vertices(g).first; - } +} - template - inline typename adjacency_matrix::vertex_descriptor - add_vertex(const VP2& /*vp*/, adjacency_matrix& g) { +template < typename D, typename VP, typename EP, typename GP, typename A, + typename VP2 > +inline typename adjacency_matrix< D, VP, EP, GP, A >::vertex_descriptor +add_vertex(const VP2& /*vp*/, adjacency_matrix< D, VP, EP, GP, A >& g) +{ // UNDER CONSTRUCTION BOOST_ASSERT(false); return *vertices(g).first; - } +} - template - inline void - remove_vertex(typename adjacency_matrix::vertex_descriptor /*u*/, - adjacency_matrix& /*g*/) - { +template < typename D, typename VP, typename EP, typename GP, typename A > +inline void remove_vertex( + typename adjacency_matrix< D, VP, EP, GP, A >::vertex_descriptor /*u*/, + adjacency_matrix< D, VP, EP, GP, A >& /*g*/) +{ // UNDER CONSTRUCTION BOOST_ASSERT(false); - } - - // O(V) - template - void - clear_vertex - (typename adjacency_matrix::vertex_descriptor u, - adjacency_matrix& g) - { - typename adjacency_matrix::vertex_iterator - vi, vi_end; +} + +// O(V) +template < typename VP, typename EP, typename GP, typename A > +void clear_vertex( + typename adjacency_matrix< directedS, VP, EP, GP, A >::vertex_descriptor u, + adjacency_matrix< directedS, VP, EP, GP, A >& g) +{ + typename adjacency_matrix< directedS, VP, EP, GP, A >::vertex_iterator vi, + vi_end; for (boost::tie(vi, vi_end) = vertices(g); vi != vi_end; ++vi) - remove_edge(u, *vi, g); + remove_edge(u, *vi, g); for (boost::tie(vi, vi_end) = vertices(g); vi != vi_end; ++vi) - remove_edge(*vi, u, g); - } - - // O(V) - template - void - clear_vertex - (typename adjacency_matrix::vertex_descriptor u, - adjacency_matrix& g) - { - typename adjacency_matrix::vertex_iterator - vi, vi_end; + remove_edge(*vi, u, g); +} + +// O(V) +template < typename VP, typename EP, typename GP, typename A > +void clear_vertex( + typename adjacency_matrix< undirectedS, VP, EP, GP, A >::vertex_descriptor + u, + adjacency_matrix< undirectedS, VP, EP, GP, A >& g) +{ + typename adjacency_matrix< undirectedS, VP, EP, GP, A >::vertex_iterator vi, + vi_end; for (boost::tie(vi, vi_end) = vertices(g); vi != vi_end; ++vi) - remove_edge(u, *vi, g); - } - - //========================================================================= - // Functions required by the PropertyGraph concept - - template - struct adj_mat_pm_helper; - - template - struct adj_mat_pm_helper { - typedef typename graph_traits >::vertex_descriptor arg_type; - typedef typed_identity_property_map vi_map_type; - typedef iterator_property_map::iterator, vi_map_type> all_map_type; - typedef iterator_property_map::const_iterator, vi_map_type> all_map_const_type; + remove_edge(u, *vi, g); +} + +//========================================================================= +// Functions required by the PropertyGraph concept + +template < typename D, typename VP, typename EP, typename GP, typename A, + typename Prop, typename Kind > +struct adj_mat_pm_helper; + +template < typename D, typename VP, typename EP, typename GP, typename A, + typename Prop > +struct adj_mat_pm_helper< D, VP, EP, GP, A, Prop, vertex_property_tag > +{ + typedef typename graph_traits< + adjacency_matrix< D, VP, EP, GP, A > >::vertex_descriptor arg_type; + typedef typed_identity_property_map< arg_type > vi_map_type; + typedef iterator_property_map< typename std::vector< VP >::iterator, + vi_map_type > + all_map_type; + typedef iterator_property_map< typename std::vector< VP >::const_iterator, + vi_map_type > + all_map_const_type; typedef transform_value_property_map< - detail::lookup_one_property_f, - all_map_type> - type; + detail::lookup_one_property_f< VP, Prop >, all_map_type > + type; typedef transform_value_property_map< - detail::lookup_one_property_f, - all_map_const_type> - const_type; - typedef typename property_traits::reference single_nonconst_type; - typedef typename property_traits::reference single_const_type; - - static type get_nonconst(adjacency_matrix& g, Prop prop) { - return type(prop, all_map_type(g.m_vertex_properties.begin(), vi_map_type())); + detail::lookup_one_property_f< const VP, Prop >, all_map_const_type > + const_type; + typedef typename property_traits< type >::reference single_nonconst_type; + typedef typename property_traits< const_type >::reference single_const_type; + + static type get_nonconst(adjacency_matrix< D, VP, EP, GP, A >& g, Prop prop) + { + return type( + prop, all_map_type(g.m_vertex_properties.begin(), vi_map_type())); } - static const_type get_const(const adjacency_matrix& g, Prop prop) { - return const_type(prop, all_map_const_type(g.m_vertex_properties.begin(), vi_map_type())); + static const_type get_const( + const adjacency_matrix< D, VP, EP, GP, A >& g, Prop prop) + { + return const_type(prop, + all_map_const_type(g.m_vertex_properties.begin(), vi_map_type())); } - static single_nonconst_type get_nonconst_one(adjacency_matrix& g, Prop prop, arg_type v) { - return lookup_one_property::lookup(g.m_vertex_properties[v], prop); + static single_nonconst_type get_nonconst_one( + adjacency_matrix< D, VP, EP, GP, A >& g, Prop prop, arg_type v) + { + return lookup_one_property< VP, Prop >::lookup( + g.m_vertex_properties[v], prop); } - static single_const_type get_const_one(const adjacency_matrix& g, Prop prop, arg_type v) { - return lookup_one_property::lookup(g.m_vertex_properties[v], prop); + static single_const_type get_const_one( + const adjacency_matrix< D, VP, EP, GP, A >& g, Prop prop, arg_type v) + { + return lookup_one_property< const VP, Prop >::lookup( + g.m_vertex_properties[v], prop); } - }; - - template - struct adj_mat_pm_helper { - typedef typename graph_traits >::edge_descriptor edge_descriptor; - - template - struct lookup_property_from_edge { - Tag tag; - lookup_property_from_edge(Tag tag): tag(tag) {} - typedef typename boost::mpl::if_::type ep_type_nonref; - typedef ep_type_nonref& ep_type; - typedef typename lookup_one_property::type& result_type; - result_type operator()(edge_descriptor e) const { - return lookup_one_property::lookup(*static_cast(e.get_property()), tag); - } +}; + +template < typename D, typename VP, typename EP, typename GP, typename A, + typename Tag > +struct adj_mat_pm_helper< D, VP, EP, GP, A, Tag, edge_property_tag > +{ + typedef typename graph_traits< + adjacency_matrix< D, VP, EP, GP, A > >::edge_descriptor edge_descriptor; + + template < typename IsConst > struct lookup_property_from_edge + { + Tag tag; + lookup_property_from_edge(Tag tag) : tag(tag) {} + typedef typename boost::mpl::if_< IsConst, const EP, EP >::type + ep_type_nonref; + typedef ep_type_nonref& ep_type; + typedef typename lookup_one_property< ep_type_nonref, Tag >::type& + result_type; + result_type operator()(edge_descriptor e) const + { + return lookup_one_property< ep_type_nonref, Tag >::lookup( + *static_cast< ep_type_nonref* >(e.get_property()), tag); + } }; typedef function_property_map< - lookup_property_from_edge, - typename graph_traits >::edge_descriptor> type; + lookup_property_from_edge< boost::mpl::false_ >, + typename graph_traits< + adjacency_matrix< D, VP, EP, GP, A > >::edge_descriptor > + type; typedef function_property_map< - lookup_property_from_edge, - typename graph_traits >::edge_descriptor> const_type; + lookup_property_from_edge< boost::mpl::true_ >, + typename graph_traits< + adjacency_matrix< D, VP, EP, GP, A > >::edge_descriptor > + const_type; typedef edge_descriptor arg_type; - typedef typename lookup_property_from_edge::result_type single_nonconst_type; - typedef typename lookup_property_from_edge::result_type single_const_type; + typedef + typename lookup_property_from_edge< boost::mpl::false_ >::result_type + single_nonconst_type; + typedef typename lookup_property_from_edge< boost::mpl::true_ >::result_type + single_const_type; - static type get_nonconst(adjacency_matrix& g, Tag tag) { - return type(tag); + static type get_nonconst(adjacency_matrix< D, VP, EP, GP, A >& g, Tag tag) + { + return type(tag); } - static const_type get_const(const adjacency_matrix& g, Tag tag) { - return const_type(tag); + static const_type get_const( + const adjacency_matrix< D, VP, EP, GP, A >& g, Tag tag) + { + return const_type(tag); } - static single_nonconst_type get_nonconst_one(adjacency_matrix& g, Tag tag, edge_descriptor e) { - return lookup_one_property::lookup(*static_cast(e.get_property()), tag); + static single_nonconst_type get_nonconst_one( + adjacency_matrix< D, VP, EP, GP, A >& g, Tag tag, edge_descriptor e) + { + return lookup_one_property< EP, Tag >::lookup( + *static_cast< EP* >(e.get_property()), tag); } - static single_const_type get_const_one(const adjacency_matrix& g, Tag tag, edge_descriptor e) { - return lookup_one_property::lookup(*static_cast(e.get_property()), tag); + static single_const_type get_const_one( + const adjacency_matrix< D, VP, EP, GP, A >& g, Tag tag, + edge_descriptor e) + { + return lookup_one_property< const EP, Tag >::lookup( + *static_cast< const EP* >(e.get_property()), tag); } - }; - - template - struct property_map, Tag> - : adj_mat_pm_helper, Tag>::type> {}; - - template - typename property_map, Tag>::type - get(Tag tag, adjacency_matrix& g) { - return property_map, Tag>::get_nonconst(g, tag); - } - - template - typename property_map, Tag>::const_type - get(Tag tag, const adjacency_matrix& g) { - return property_map, Tag>::get_const(g, tag); - } - - template - typename property_map, Tag>::single_nonconst_type - get(Tag tag, adjacency_matrix& g, typename property_map, Tag>::arg_type a) { - return property_map, Tag>::get_nonconst_one(g, tag, a); - } - - template - typename property_map, Tag>::single_const_type - get(Tag tag, const adjacency_matrix& g, typename property_map, Tag>::arg_type a) { - return property_map, Tag>::get_const_one(g, tag, a); - } - - template - void - put(Tag tag, - adjacency_matrix& g, - typename property_map, Tag>::arg_type a, - typename property_map, Tag>::single_const_type val) { - property_map, Tag>::get_nonconst_one(g, tag, a) = val; - } - - // O(1) - template - inline void - set_property(adjacency_matrix& g, Tag tag, const Value& value) - { - get_property_value(g.m_property, tag) = value; - } - - template - inline typename graph_property, Tag>::type& - get_property(adjacency_matrix& g, Tag tag) - { - return get_property_value(g.m_property, tag); - } - - template - inline const typename graph_property, Tag>::type& - get_property(const adjacency_matrix& g, Tag tag) - { - return get_property_value(g.m_property, tag); - } - - //========================================================================= - // Vertex Property Map - - template - struct property_map, vertex_index_t> { - typedef typename adjacency_matrix::vertex_descriptor Vertex; - typedef typed_identity_property_map type; +}; + +template < typename D, typename VP, typename EP, typename GP, typename A, + typename Tag > +struct property_map< adjacency_matrix< D, VP, EP, GP, A >, Tag > +: adj_mat_pm_helper< D, VP, EP, GP, A, Tag, + typename detail::property_kind_from_graph< + adjacency_matrix< D, VP, EP, GP, A >, Tag >::type > +{ +}; + +template < typename D, typename VP, typename EP, typename GP, typename A, + typename Tag > +typename property_map< adjacency_matrix< D, VP, EP, GP, A >, Tag >::type get( + Tag tag, adjacency_matrix< D, VP, EP, GP, A >& g) +{ + return property_map< adjacency_matrix< D, VP, EP, GP, A >, + Tag >::get_nonconst(g, tag); +} + +template < typename D, typename VP, typename EP, typename GP, typename A, + typename Tag > +typename property_map< adjacency_matrix< D, VP, EP, GP, A >, Tag >::const_type +get(Tag tag, const adjacency_matrix< D, VP, EP, GP, A >& g) +{ + return property_map< adjacency_matrix< D, VP, EP, GP, A >, Tag >::get_const( + g, tag); +} + +template < typename D, typename VP, typename EP, typename GP, typename A, + typename Tag > +typename property_map< adjacency_matrix< D, VP, EP, GP, A >, + Tag >::single_nonconst_type +get(Tag tag, adjacency_matrix< D, VP, EP, GP, A >& g, + typename property_map< adjacency_matrix< D, VP, EP, GP, A >, Tag >::arg_type + a) +{ + return property_map< adjacency_matrix< D, VP, EP, GP, A >, + Tag >::get_nonconst_one(g, tag, a); +} + +template < typename D, typename VP, typename EP, typename GP, typename A, + typename Tag > +typename property_map< adjacency_matrix< D, VP, EP, GP, A >, + Tag >::single_const_type +get(Tag tag, const adjacency_matrix< D, VP, EP, GP, A >& g, + typename property_map< adjacency_matrix< D, VP, EP, GP, A >, Tag >::arg_type + a) +{ + return property_map< adjacency_matrix< D, VP, EP, GP, A >, + Tag >::get_const_one(g, tag, a); +} + +template < typename D, typename VP, typename EP, typename GP, typename A, + typename Tag > +void put(Tag tag, adjacency_matrix< D, VP, EP, GP, A >& g, + typename property_map< adjacency_matrix< D, VP, EP, GP, A >, Tag >::arg_type + a, + typename property_map< adjacency_matrix< D, VP, EP, GP, A >, + Tag >::single_const_type val) +{ + property_map< adjacency_matrix< D, VP, EP, GP, A >, Tag >::get_nonconst_one( + g, tag, a) + = val; +} + +// O(1) +template < typename D, typename VP, typename EP, typename GP, typename A, + typename Tag, typename Value > +inline void set_property( + adjacency_matrix< D, VP, EP, GP, A >& g, Tag tag, const Value& value) +{ + get_property_value(g.m_property, tag) = value; +} + +template < typename D, typename VP, typename EP, typename GP, typename A, + typename Tag > +inline + typename graph_property< adjacency_matrix< D, VP, EP, GP, A >, Tag >::type& + get_property(adjacency_matrix< D, VP, EP, GP, A >& g, Tag tag) +{ + return get_property_value(g.m_property, tag); +} + +template < typename D, typename VP, typename EP, typename GP, typename A, + typename Tag > +inline const typename graph_property< adjacency_matrix< D, VP, EP, GP, A >, + Tag >::type& +get_property(const adjacency_matrix< D, VP, EP, GP, A >& g, Tag tag) +{ + return get_property_value(g.m_property, tag); +} + +//========================================================================= +// Vertex Property Map + +template < typename D, typename VP, typename EP, typename GP, typename A > +struct property_map< adjacency_matrix< D, VP, EP, GP, A >, vertex_index_t > +{ + typedef + typename adjacency_matrix< D, VP, EP, GP, A >::vertex_descriptor Vertex; + typedef typed_identity_property_map< Vertex > type; typedef type const_type; - }; - - template - typename property_map, vertex_index_t>::const_type - get(vertex_index_t, adjacency_matrix&) { - return typename property_map, vertex_index_t>::const_type(); - } - - template - typename adjacency_matrix::vertex_descriptor - get(vertex_index_t, - adjacency_matrix&, - typename adjacency_matrix::vertex_descriptor v) { +}; + +template < typename D, typename VP, typename EP, typename GP, typename A > +typename property_map< adjacency_matrix< D, VP, EP, GP, A >, + vertex_index_t >::const_type +get(vertex_index_t, adjacency_matrix< D, VP, EP, GP, A >&) +{ + return typename property_map< adjacency_matrix< D, VP, EP, GP, A >, + vertex_index_t >::const_type(); +} + +template < typename D, typename VP, typename EP, typename GP, typename A > +typename adjacency_matrix< D, VP, EP, GP, A >::vertex_descriptor get( + vertex_index_t, adjacency_matrix< D, VP, EP, GP, A >&, + typename adjacency_matrix< D, VP, EP, GP, A >::vertex_descriptor v) +{ return v; - } - - template - typename property_map, vertex_index_t>::const_type - get(vertex_index_t, const adjacency_matrix&) { - return typename property_map, vertex_index_t>::const_type(); - } - - template - typename adjacency_matrix::vertex_descriptor - get(vertex_index_t, - const adjacency_matrix&, - typename adjacency_matrix::vertex_descriptor v) { +} + +template < typename D, typename VP, typename EP, typename GP, typename A > +typename property_map< adjacency_matrix< D, VP, EP, GP, A >, + vertex_index_t >::const_type +get(vertex_index_t, const adjacency_matrix< D, VP, EP, GP, A >&) +{ + return typename property_map< adjacency_matrix< D, VP, EP, GP, A >, + vertex_index_t >::const_type(); +} + +template < typename D, typename VP, typename EP, typename GP, typename A > +typename adjacency_matrix< D, VP, EP, GP, A >::vertex_descriptor get( + vertex_index_t, const adjacency_matrix< D, VP, EP, GP, A >&, + typename adjacency_matrix< D, VP, EP, GP, A >::vertex_descriptor v) +{ return v; - } +} - //========================================================================= - // Other Functions +//========================================================================= +// Other Functions - template - typename adjacency_matrix::vertex_descriptor - vertex(typename adjacency_matrix::vertices_size_type n, - const adjacency_matrix&) - { +template < typename D, typename VP, typename EP, typename GP, typename A > +typename adjacency_matrix< D, VP, EP, GP, A >::vertex_descriptor vertex( + typename adjacency_matrix< D, VP, EP, GP, A >::vertices_size_type n, + const adjacency_matrix< D, VP, EP, GP, A >&) +{ return n; - } +} -template -struct graph_mutability_traits > { - typedef mutable_edge_property_graph_tag category; +template < typename D, typename VP, typename EP, typename GP, typename A > +struct graph_mutability_traits< adjacency_matrix< D, VP, EP, GP, A > > +{ + typedef mutable_edge_property_graph_tag category; }; - } // namespace boost #endif // BOOST_ADJACENCY_MATRIX_HPP diff --git a/include/boost/graph/astar_search.hpp b/include/boost/graph/astar_search.hpp index 8201b50f1..2d4f264fe 100644 --- a/include/boost/graph/astar_search.hpp +++ b/include/boost/graph/astar_search.hpp @@ -13,7 +13,6 @@ #ifndef BOOST_GRAPH_ASTAR_SEARCH_HPP #define BOOST_GRAPH_ASTAR_SEARCH_HPP - #include #include #include @@ -30,748 +29,627 @@ #include #include -namespace boost { - +namespace boost +{ - template - struct AStarHeuristicConcept { +template < class Heuristic, class Graph > struct AStarHeuristicConcept +{ void constraints() { - BOOST_CONCEPT_ASSERT(( CopyConstructibleConcept )); - h(u); + BOOST_CONCEPT_ASSERT((CopyConstructibleConcept< Heuristic >)); + h(u); } Heuristic h; - typename graph_traits::vertex_descriptor u; - }; - + typename graph_traits< Graph >::vertex_descriptor u; +}; - template - class astar_heuristic - { - public: - typedef typename graph_traits::vertex_descriptor Vertex; +template < class Graph, class CostType > class astar_heuristic +{ +public: + typedef typename graph_traits< Graph >::vertex_descriptor Vertex; typedef Vertex argument_type; typedef CostType result_type; astar_heuristic() {} - CostType operator()(Vertex u) { return static_cast(0); } - }; - - + CostType operator()(Vertex u) { return static_cast< CostType >(0); } +}; - template - struct AStarVisitorConcept { +template < class Visitor, class Graph > struct AStarVisitorConcept +{ void constraints() { - BOOST_CONCEPT_ASSERT(( CopyConstructibleConcept )); - vis.initialize_vertex(u, g); - vis.discover_vertex(u, g); - vis.examine_vertex(u, g); - vis.examine_edge(e, g); - vis.edge_relaxed(e, g); - vis.edge_not_relaxed(e, g); - vis.black_target(e, g); - vis.finish_vertex(u, g); + BOOST_CONCEPT_ASSERT((CopyConstructibleConcept< Visitor >)); + vis.initialize_vertex(u, g); + vis.discover_vertex(u, g); + vis.examine_vertex(u, g); + vis.examine_edge(e, g); + vis.edge_relaxed(e, g); + vis.edge_not_relaxed(e, g); + vis.black_target(e, g); + vis.finish_vertex(u, g); } Visitor vis; Graph g; - typename graph_traits::vertex_descriptor u; - typename graph_traits::edge_descriptor e; - }; - - - template - class astar_visitor : public bfs_visitor { - public: + typename graph_traits< Graph >::vertex_descriptor u; + typename graph_traits< Graph >::edge_descriptor e; +}; + +template < class Visitors = null_visitor > +class astar_visitor : public bfs_visitor< Visitors > +{ +public: astar_visitor() {} - astar_visitor(Visitors vis) - : bfs_visitor(vis) {} + astar_visitor(Visitors vis) : bfs_visitor< Visitors >(vis) {} + + template < class Edge, class Graph > + void edge_relaxed(Edge e, const Graph& g) + { + invoke_visitors(this->m_vis, e, g, on_edge_relaxed()); + } + template < class Edge, class Graph > + void edge_not_relaxed(Edge e, const Graph& g) + { + invoke_visitors(this->m_vis, e, g, on_edge_not_relaxed()); + } - template - void edge_relaxed(Edge e, const Graph& g) { - invoke_visitors(this->m_vis, e, g, on_edge_relaxed()); +private: + template < class Edge, class Graph > void tree_edge(Edge e, const Graph& g) + { } - template - void edge_not_relaxed(Edge e, const Graph& g) { - invoke_visitors(this->m_vis, e, g, on_edge_not_relaxed()); + template < class Edge, class Graph > + void non_tree_edge(Edge e, const Graph& g) + { } - private: - template - void tree_edge(Edge e, const Graph& g) {} - template - void non_tree_edge(Edge e, const Graph& g) {} - }; - template - astar_visitor - make_astar_visitor(Visitors vis) { - return astar_visitor(vis); - } - typedef astar_visitor<> default_astar_visitor; - - - namespace detail { - - template +}; +template < class Visitors > +astar_visitor< Visitors > make_astar_visitor(Visitors vis) +{ + return astar_visitor< Visitors >(vis); +} +typedef astar_visitor<> default_astar_visitor; + +namespace detail +{ + + template < class AStarHeuristic, class UniformCostVisitor, + class UpdatableQueue, class PredecessorMap, class CostMap, + class DistanceMap, class WeightMap, class ColorMap, + class BinaryFunction, class BinaryPredicate > struct astar_bfs_visitor { - typedef typename property_traits::value_type C; - typedef typename property_traits::value_type ColorValue; - typedef color_traits Color; - typedef typename property_traits::value_type distance_type; - - astar_bfs_visitor(AStarHeuristic h, UniformCostVisitor vis, - UpdatableQueue& Q, PredecessorMap p, - CostMap c, DistanceMap d, WeightMap w, - ColorMap col, BinaryFunction combine, - BinaryPredicate compare, C zero) - : m_h(h), m_vis(vis), m_Q(Q), m_predecessor(p), m_cost(c), - m_distance(d), m_weight(w), m_color(col), - m_combine(combine), m_compare(compare), m_zero(zero) {} - - - template - void initialize_vertex(Vertex u, const Graph& g) { - m_vis.initialize_vertex(u, g); - } - template - void discover_vertex(Vertex u, const Graph& g) { - m_vis.discover_vertex(u, g); - } - template - void examine_vertex(Vertex u, const Graph& g) { - m_vis.examine_vertex(u, g); - } - template - void finish_vertex(Vertex u, const Graph& g) { - m_vis.finish_vertex(u, g); - } - template - void examine_edge(Edge e, const Graph& g) { - if (m_compare(get(m_weight, e), m_zero)) - BOOST_THROW_EXCEPTION(negative_edge()); - m_vis.examine_edge(e, g); - } - template - void non_tree_edge(Edge, const Graph&) {} - - - - template - void tree_edge(Edge e, const Graph& g) { - using boost::get; - bool m_decreased = - relax(e, g, m_weight, m_predecessor, m_distance, + typedef typename property_traits< CostMap >::value_type C; + typedef typename property_traits< ColorMap >::value_type ColorValue; + typedef color_traits< ColorValue > Color; + typedef + typename property_traits< DistanceMap >::value_type distance_type; + + astar_bfs_visitor(AStarHeuristic h, UniformCostVisitor vis, + UpdatableQueue& Q, PredecessorMap p, CostMap c, DistanceMap d, + WeightMap w, ColorMap col, BinaryFunction combine, + BinaryPredicate compare, C zero) + : m_h(h) + , m_vis(vis) + , m_Q(Q) + , m_predecessor(p) + , m_cost(c) + , m_distance(d) + , m_weight(w) + , m_color(col) + , m_combine(combine) + , m_compare(compare) + , m_zero(zero) + { + } + + template < class Vertex, class Graph > + void initialize_vertex(Vertex u, const Graph& g) + { + m_vis.initialize_vertex(u, g); + } + template < class Vertex, class Graph > + void discover_vertex(Vertex u, const Graph& g) + { + m_vis.discover_vertex(u, g); + } + template < class Vertex, class Graph > + void examine_vertex(Vertex u, const Graph& g) + { + m_vis.examine_vertex(u, g); + } + template < class Vertex, class Graph > + void finish_vertex(Vertex u, const Graph& g) + { + m_vis.finish_vertex(u, g); + } + template < class Edge, class Graph > + void examine_edge(Edge e, const Graph& g) + { + if (m_compare(get(m_weight, e), m_zero)) + BOOST_THROW_EXCEPTION(negative_edge()); + m_vis.examine_edge(e, g); + } + template < class Edge, class Graph > + void non_tree_edge(Edge, const Graph&) + { + } + + template < class Edge, class Graph > + void tree_edge(Edge e, const Graph& g) + { + using boost::get; + bool m_decreased = relax(e, g, m_weight, m_predecessor, m_distance, m_combine, m_compare); - if(m_decreased) { - m_vis.edge_relaxed(e, g); - put(m_cost, target(e, g), - m_combine(get(m_distance, target(e, g)), - m_h(target(e, g)))); - } else - m_vis.edge_not_relaxed(e, g); - } - - - template - void gray_target(Edge e, const Graph& g) { - using boost::get; - bool m_decreased = - relax(e, g, m_weight, m_predecessor, m_distance, + if (m_decreased) + { + m_vis.edge_relaxed(e, g); + put(m_cost, target(e, g), + m_combine( + get(m_distance, target(e, g)), m_h(target(e, g)))); + } + else + m_vis.edge_not_relaxed(e, g); + } + + template < class Edge, class Graph > + void gray_target(Edge e, const Graph& g) + { + using boost::get; + bool m_decreased = relax(e, g, m_weight, m_predecessor, m_distance, m_combine, m_compare); - if(m_decreased) { - put(m_cost, target(e, g), - m_combine(get(m_distance, target(e, g)), - m_h(target(e, g)))); - m_Q.update(target(e, g)); - m_vis.edge_relaxed(e, g); - } else - m_vis.edge_not_relaxed(e, g); - } - - - template - void black_target(Edge e, const Graph& g) { - using boost::get; - bool m_decreased = - relax(e, g, m_weight, m_predecessor, m_distance, + if (m_decreased) + { + put(m_cost, target(e, g), + m_combine( + get(m_distance, target(e, g)), m_h(target(e, g)))); + m_Q.update(target(e, g)); + m_vis.edge_relaxed(e, g); + } + else + m_vis.edge_not_relaxed(e, g); + } + + template < class Edge, class Graph > + void black_target(Edge e, const Graph& g) + { + using boost::get; + bool m_decreased = relax(e, g, m_weight, m_predecessor, m_distance, m_combine, m_compare); - if(m_decreased) { - m_vis.edge_relaxed(e, g); - put(m_cost, target(e, g), - m_combine(get(m_distance, target(e, g)), - m_h(target(e, g)))); - m_Q.push(target(e, g)); - put(m_color, target(e, g), Color::gray()); - m_vis.black_target(e, g); - } else - m_vis.edge_not_relaxed(e, g); - } - - - - AStarHeuristic m_h; - UniformCostVisitor m_vis; - UpdatableQueue& m_Q; - PredecessorMap m_predecessor; - CostMap m_cost; - DistanceMap m_distance; - WeightMap m_weight; - ColorMap m_color; - BinaryFunction m_combine; - BinaryPredicate m_compare; - C m_zero; + if (m_decreased) + { + m_vis.edge_relaxed(e, g); + put(m_cost, target(e, g), + m_combine( + get(m_distance, target(e, g)), m_h(target(e, g)))); + m_Q.push(target(e, g)); + put(m_color, target(e, g), Color::gray()); + m_vis.black_target(e, g); + } + else + m_vis.edge_not_relaxed(e, g); + } + AStarHeuristic m_h; + UniformCostVisitor m_vis; + UpdatableQueue& m_Q; + PredecessorMap m_predecessor; + CostMap m_cost; + DistanceMap m_distance; + WeightMap m_weight; + ColorMap m_color; + BinaryFunction m_combine; + BinaryPredicate m_compare; + C m_zero; }; - } // namespace detail - - - - template - inline void - astar_search_no_init - (const VertexListGraph &g, - typename graph_traits::vertex_descriptor s, - AStarHeuristic h, AStarVisitor vis, - PredecessorMap predecessor, CostMap cost, - DistanceMap distance, WeightMap weight, - ColorMap color, VertexIndexMap index_map, - CompareFunction compare, CombineFunction combine, - CostInf /*inf*/, CostZero zero) - { - typedef typename graph_traits::vertex_descriptor - Vertex; - typedef boost::vector_property_map IndexInHeapMap; +} // namespace detail + +template < typename VertexListGraph, typename AStarHeuristic, + typename AStarVisitor, typename PredecessorMap, typename CostMap, + typename DistanceMap, typename WeightMap, typename ColorMap, + typename VertexIndexMap, typename CompareFunction, typename CombineFunction, + typename CostInf, typename CostZero > +inline void astar_search_no_init(const VertexListGraph& g, + typename graph_traits< VertexListGraph >::vertex_descriptor s, + AStarHeuristic h, AStarVisitor vis, PredecessorMap predecessor, + CostMap cost, DistanceMap distance, WeightMap weight, ColorMap color, + VertexIndexMap index_map, CompareFunction compare, CombineFunction combine, + CostInf /*inf*/, CostZero zero) +{ + typedef typename graph_traits< VertexListGraph >::vertex_descriptor Vertex; + typedef boost::vector_property_map< std::size_t, VertexIndexMap > + IndexInHeapMap; IndexInHeapMap index_in_heap(index_map); - typedef d_ary_heap_indirect - MutableQueue; + typedef d_ary_heap_indirect< Vertex, 4, IndexInHeapMap, CostMap, + CompareFunction > + MutableQueue; MutableQueue Q(cost, index_in_heap, compare); - detail::astar_bfs_visitor - bfs_vis(h, vis, Q, predecessor, cost, distance, weight, - color, combine, compare, zero); + detail::astar_bfs_visitor< AStarHeuristic, AStarVisitor, MutableQueue, + PredecessorMap, CostMap, DistanceMap, WeightMap, ColorMap, + CombineFunction, CompareFunction > + bfs_vis(h, vis, Q, predecessor, cost, distance, weight, color, combine, + compare, zero); breadth_first_visit(g, s, Q, bfs_vis, color); - } - - namespace graph_detail { - template - struct select1st { - typedef std::pair argument_type; - typedef A result_type; - A operator()(const std::pair& p) const {return p.first;} +} + +namespace graph_detail +{ + template < typename A, typename B > struct select1st + { + typedef std::pair< A, B > argument_type; + typedef A result_type; + A operator()(const std::pair< A, B >& p) const { return p.first; } }; - } - - template - inline void - astar_search_no_init_tree - (const VertexListGraph &g, - typename graph_traits::vertex_descriptor s, - AStarHeuristic h, AStarVisitor vis, - PredecessorMap predecessor, CostMap cost, - DistanceMap distance, WeightMap weight, - CompareFunction compare, CombineFunction combine, - CostInf /*inf*/, CostZero zero) - { - typedef typename graph_traits::vertex_descriptor - Vertex; - typedef typename property_traits::value_type Distance; - typedef d_ary_heap_indirect< - std::pair, - 4, - null_property_map, std::size_t>, - function_property_map, std::pair >, - CompareFunction> - MutableQueue; - MutableQueue Q( - make_function_property_map >(graph_detail::select1st()), - null_property_map, std::size_t>(), - compare); +} + +template < typename VertexListGraph, typename AStarHeuristic, + typename AStarVisitor, typename PredecessorMap, typename CostMap, + typename DistanceMap, typename WeightMap, typename CompareFunction, + typename CombineFunction, typename CostInf, typename CostZero > +inline void astar_search_no_init_tree(const VertexListGraph& g, + typename graph_traits< VertexListGraph >::vertex_descriptor s, + AStarHeuristic h, AStarVisitor vis, PredecessorMap predecessor, + CostMap cost, DistanceMap distance, WeightMap weight, + CompareFunction compare, CombineFunction combine, CostInf /*inf*/, + CostZero zero) +{ + typedef typename graph_traits< VertexListGraph >::vertex_descriptor Vertex; + typedef typename property_traits< DistanceMap >::value_type Distance; + typedef d_ary_heap_indirect< std::pair< Distance, Vertex >, 4, + null_property_map< std::pair< Distance, Vertex >, std::size_t >, + function_property_map< graph_detail::select1st< Distance, Vertex >, + std::pair< Distance, Vertex > >, + CompareFunction > + MutableQueue; + MutableQueue Q(make_function_property_map< std::pair< Distance, Vertex > >( + graph_detail::select1st< Distance, Vertex >()), + null_property_map< std::pair< Distance, Vertex >, std::size_t >(), + compare); vis.discover_vertex(s, g); Q.push(std::make_pair(get(cost, s), s)); - while (!Q.empty()) { - Vertex v; - Distance v_rank; - boost::tie(v_rank, v) = Q.top(); - Q.pop(); - vis.examine_vertex(v, g); - BGL_FORALL_OUTEDGES_T(v, e, g, VertexListGraph) { - Vertex w = target(e, g); - vis.examine_edge(e, g); - Distance e_weight = get(weight, e); - if (compare(e_weight, zero)) - BOOST_THROW_EXCEPTION(negative_edge()); - bool decreased = - relax(e, g, weight, predecessor, distance, - combine, compare); - combine(get(distance, v), e_weight); - if (decreased) { - vis.edge_relaxed(e, g); - Distance w_rank = combine(get(distance, w), h(w)); - put(cost, w, w_rank); - vis.discover_vertex(w, g); - Q.push(std::make_pair(w_rank, w)); - } else { - vis.edge_not_relaxed(e, g); + while (!Q.empty()) + { + Vertex v; + Distance v_rank; + boost::tie(v_rank, v) = Q.top(); + Q.pop(); + vis.examine_vertex(v, g); + BGL_FORALL_OUTEDGES_T(v, e, g, VertexListGraph) + { + Vertex w = target(e, g); + vis.examine_edge(e, g); + Distance e_weight = get(weight, e); + if (compare(e_weight, zero)) + BOOST_THROW_EXCEPTION(negative_edge()); + bool decreased + = relax(e, g, weight, predecessor, distance, combine, compare); + combine(get(distance, v), e_weight); + if (decreased) + { + vis.edge_relaxed(e, g); + Distance w_rank = combine(get(distance, w), h(w)); + put(cost, w, w_rank); + vis.discover_vertex(w, g); + Q.push(std::make_pair(w_rank, w)); + } + else + { + vis.edge_not_relaxed(e, g); + } } - } - vis.finish_vertex(v, g); + vis.finish_vertex(v, g); } - } - - // Non-named parameter interface - template - inline void - astar_search - (const VertexListGraph &g, - typename graph_traits::vertex_descriptor s, - AStarHeuristic h, AStarVisitor vis, - PredecessorMap predecessor, CostMap cost, - DistanceMap distance, WeightMap weight, - VertexIndexMap index_map, ColorMap color, - CompareFunction compare, CombineFunction combine, - CostInf inf, CostZero zero) - { - - typedef typename property_traits::value_type ColorValue; - typedef color_traits Color; - typename graph_traits::vertex_iterator ui, ui_end; - for (boost::tie(ui, ui_end) = vertices(g); ui != ui_end; ++ui) { - put(color, *ui, Color::white()); - put(distance, *ui, inf); - put(cost, *ui, inf); - put(predecessor, *ui, *ui); - vis.initialize_vertex(*ui, g); +} + +// Non-named parameter interface +template < typename VertexListGraph, typename AStarHeuristic, + typename AStarVisitor, typename PredecessorMap, typename CostMap, + typename DistanceMap, typename WeightMap, typename VertexIndexMap, + typename ColorMap, typename CompareFunction, typename CombineFunction, + typename CostInf, typename CostZero > +inline void astar_search(const VertexListGraph& g, + typename graph_traits< VertexListGraph >::vertex_descriptor s, + AStarHeuristic h, AStarVisitor vis, PredecessorMap predecessor, + CostMap cost, DistanceMap distance, WeightMap weight, + VertexIndexMap index_map, ColorMap color, CompareFunction compare, + CombineFunction combine, CostInf inf, CostZero zero) +{ + + typedef typename property_traits< ColorMap >::value_type ColorValue; + typedef color_traits< ColorValue > Color; + typename graph_traits< VertexListGraph >::vertex_iterator ui, ui_end; + for (boost::tie(ui, ui_end) = vertices(g); ui != ui_end; ++ui) + { + put(color, *ui, Color::white()); + put(distance, *ui, inf); + put(cost, *ui, inf); + put(predecessor, *ui, *ui); + vis.initialize_vertex(*ui, g); } put(distance, s, zero); put(cost, s, h(s)); - astar_search_no_init - (g, s, h, vis, predecessor, cost, distance, weight, - color, index_map, compare, combine, inf, zero); - - } - - // Non-named parameter interface - template - inline void - astar_search_tree - (const VertexListGraph &g, - typename graph_traits::vertex_descriptor s, - AStarHeuristic h, AStarVisitor vis, - PredecessorMap predecessor, CostMap cost, - DistanceMap distance, WeightMap weight, - CompareFunction compare, CombineFunction combine, - CostInf inf, CostZero zero) - { - - typename graph_traits::vertex_iterator ui, ui_end; - for (boost::tie(ui, ui_end) = vertices(g); ui != ui_end; ++ui) { - put(distance, *ui, inf); - put(cost, *ui, inf); - put(predecessor, *ui, *ui); - vis.initialize_vertex(*ui, g); + astar_search_no_init(g, s, h, vis, predecessor, cost, distance, weight, + color, index_map, compare, combine, inf, zero); +} + +// Non-named parameter interface +template < typename VertexListGraph, typename AStarHeuristic, + typename AStarVisitor, typename PredecessorMap, typename CostMap, + typename DistanceMap, typename WeightMap, typename CompareFunction, + typename CombineFunction, typename CostInf, typename CostZero > +inline void astar_search_tree(const VertexListGraph& g, + typename graph_traits< VertexListGraph >::vertex_descriptor s, + AStarHeuristic h, AStarVisitor vis, PredecessorMap predecessor, + CostMap cost, DistanceMap distance, WeightMap weight, + CompareFunction compare, CombineFunction combine, CostInf inf, + CostZero zero) +{ + + typename graph_traits< VertexListGraph >::vertex_iterator ui, ui_end; + for (boost::tie(ui, ui_end) = vertices(g); ui != ui_end; ++ui) + { + put(distance, *ui, inf); + put(cost, *ui, inf); + put(predecessor, *ui, *ui); + vis.initialize_vertex(*ui, g); } put(distance, s, zero); put(cost, s, h(s)); - astar_search_no_init_tree - (g, s, h, vis, predecessor, cost, distance, weight, - compare, combine, inf, zero); - - } - - // Named parameter interfaces - template - void - astar_search - (const VertexListGraph &g, - typename graph_traits::vertex_descriptor s, - AStarHeuristic h, const bgl_named_params& params) - { + astar_search_no_init_tree(g, s, h, vis, predecessor, cost, distance, weight, + compare, combine, inf, zero); +} + +// Named parameter interfaces +template < typename VertexListGraph, typename AStarHeuristic, typename P, + typename T, typename R > +void astar_search(const VertexListGraph& g, + typename graph_traits< VertexListGraph >::vertex_descriptor s, + AStarHeuristic h, const bgl_named_params< P, T, R >& params) +{ using namespace boost::graph::keywords; - typedef bgl_named_params params_type; + typedef bgl_named_params< P, T, R > params_type; BOOST_GRAPH_DECLARE_CONVERTED_PARAMETERS(params_type, params) // Distance type is the value type of the distance map if there is one, // otherwise the value type of the weight map. - typedef typename boost::detail::override_const_property_result< - arg_pack_type, - boost::graph::keywords::tag::weight_map, - edge_weight_t, - VertexListGraph - >::type weight_map_type; - typedef typename boost::property_traits::value_type D; - const D inf = arg_pack[_distance_inf || detail::get_max()]; + typedef + typename boost::detail::override_const_property_result< arg_pack_type, + boost::graph::keywords::tag::weight_map, edge_weight_t, + VertexListGraph >::type weight_map_type; + typedef typename boost::property_traits< weight_map_type >::value_type D; + const D inf = arg_pack[_distance_inf || detail::get_max< D >()]; const D zero_actual = D(); const D zero_d = arg_pack[_distance_zero | zero_actual]; null_visitor null_vis; - astar_visitor default_visitor(null_vis); - typename boost::parameter::binding< - arg_pack_type, - boost::graph::keywords::tag::visitor, - dummy_property_map& - >::type vis = arg_pack[_visitor | default_visitor]; + astar_visitor< null_visitor > default_visitor(null_vis); + typename boost::parameter::binding< arg_pack_type, + boost::graph::keywords::tag::visitor, dummy_property_map& >::type vis + = arg_pack[_visitor | default_visitor]; dummy_property_map dummy_prop; - typename boost::parameter::binding< - arg_pack_type, + typename boost::parameter::binding< arg_pack_type, boost::graph::keywords::tag::predecessor_map, - dummy_property_map& - >::type pred_map = arg_pack[_predecessor_map | dummy_prop]; + dummy_property_map& >::type pred_map + = arg_pack[_predecessor_map | dummy_prop]; boost::detail::make_property_map_from_arg_pack_gen< - boost::graph::keywords::tag::rank_map, - D - > rank_map_gen(zero_actual); - typename boost::detail::map_maker< - VertexListGraph, - arg_pack_type, - boost::graph::keywords::tag::rank_map, - D - >::map_type r_map = rank_map_gen(g, arg_pack); + boost::graph::keywords::tag::rank_map, D > + rank_map_gen(zero_actual); + typename boost::detail::map_maker< VertexListGraph, arg_pack_type, + boost::graph::keywords::tag::rank_map, D >::map_type r_map + = rank_map_gen(g, arg_pack); boost::detail::make_property_map_from_arg_pack_gen< - boost::graph::keywords::tag::distance_map, - D - > dist_map_gen(zero_actual); - typename boost::detail::map_maker< - VertexListGraph, - arg_pack_type, - boost::graph::keywords::tag::distance_map, - D - >::map_type dist_map = dist_map_gen(g, arg_pack); - weight_map_type w_map = detail::override_const_property(arg_pack, _weight_map, g, edge_weight); - typename boost::detail::override_const_property_result< - arg_pack_type, - boost::graph::keywords::tag::vertex_index_map, - vertex_index_t, - VertexListGraph - >::type v_i_map = detail::override_const_property(arg_pack, _vertex_index_map, g, vertex_index); - typename boost::detail::map_maker< - VertexListGraph, - arg_pack_type, + boost::graph::keywords::tag::distance_map, D > + dist_map_gen(zero_actual); + typename boost::detail::map_maker< VertexListGraph, arg_pack_type, + boost::graph::keywords::tag::distance_map, D >::map_type dist_map + = dist_map_gen(g, arg_pack); + weight_map_type w_map = detail::override_const_property( + arg_pack, _weight_map, g, edge_weight); + typename boost::detail::override_const_property_result< arg_pack_type, + boost::graph::keywords::tag::vertex_index_map, vertex_index_t, + VertexListGraph >::type v_i_map + = detail::override_const_property( + arg_pack, _vertex_index_map, g, vertex_index); + typename boost::detail::map_maker< VertexListGraph, arg_pack_type, boost::graph::keywords::tag::color_map, - boost::default_color_type - >::map_type c_map = boost::detail::make_color_map_from_arg_pack(g, arg_pack); - std::less default_compare; - typename boost::parameter::binding< - arg_pack_type, - boost::graph::keywords::tag::distance_compare, - std::less& - >::type dist_comp = arg_pack[_distance_compare | default_compare]; - closed_plus default_combine(inf); - typename boost::parameter::binding< - arg_pack_type, - boost::graph::keywords::tag::distance_combine, - closed_plus& - >::type dist_comb = arg_pack[_distance_combine | default_combine]; - astar_search - (g, s, h, - vis, - pred_map, - r_map, - dist_map, - w_map, - v_i_map, - c_map, - dist_comp, - dist_comb, - inf, - zero_d); - } - - template - void - astar_search_tree - (const VertexListGraph &g, - typename graph_traits::vertex_descriptor s, - AStarHeuristic h, const bgl_named_params& params) - { + boost::default_color_type >::map_type c_map + = boost::detail::make_color_map_from_arg_pack(g, arg_pack); + std::less< D > default_compare; + typename boost::parameter::binding< arg_pack_type, + boost::graph::keywords::tag::distance_compare, std::less< D >& >::type + dist_comp + = arg_pack[_distance_compare | default_compare]; + closed_plus< D > default_combine(inf); + typename boost::parameter::binding< arg_pack_type, + boost::graph::keywords::tag::distance_combine, closed_plus< D >& >::type + dist_comb + = arg_pack[_distance_combine | default_combine]; + astar_search(g, s, h, vis, pred_map, r_map, dist_map, w_map, v_i_map, c_map, + dist_comp, dist_comb, inf, zero_d); +} + +template < typename VertexListGraph, typename AStarHeuristic, typename P, + typename T, typename R > +void astar_search_tree(const VertexListGraph& g, + typename graph_traits< VertexListGraph >::vertex_descriptor s, + AStarHeuristic h, const bgl_named_params< P, T, R >& params) +{ using namespace boost::graph::keywords; - typedef bgl_named_params params_type; + typedef bgl_named_params< P, T, R > params_type; BOOST_GRAPH_DECLARE_CONVERTED_PARAMETERS(params_type, params) // Distance type is the value type of the distance map if there is one, // otherwise the value type of the weight map. - typedef typename boost::detail::override_const_property_result< - arg_pack_type, - boost::graph::keywords::tag::weight_map, - edge_weight_t, - VertexListGraph - >::type weight_map_type; - typedef typename boost::property_traits::value_type D; - const D inf = arg_pack[_distance_inf || detail::get_max()]; + typedef + typename boost::detail::override_const_property_result< arg_pack_type, + boost::graph::keywords::tag::weight_map, edge_weight_t, + VertexListGraph >::type weight_map_type; + typedef typename boost::property_traits< weight_map_type >::value_type D; + const D inf = arg_pack[_distance_inf || detail::get_max< D >()]; const D zero_actual = D(); const D zero_d = arg_pack[_distance_zero | zero_actual]; null_visitor null_vis; - astar_visitor default_visitor(null_vis); - typename boost::parameter::binding< - arg_pack_type, - boost::graph::keywords::tag::visitor, - dummy_property_map& - >::type vis = arg_pack[_visitor | default_visitor]; + astar_visitor< null_visitor > default_visitor(null_vis); + typename boost::parameter::binding< arg_pack_type, + boost::graph::keywords::tag::visitor, dummy_property_map& >::type vis + = arg_pack[_visitor | default_visitor]; dummy_property_map dummy_prop; - typename boost::parameter::binding< - arg_pack_type, + typename boost::parameter::binding< arg_pack_type, boost::graph::keywords::tag::predecessor_map, - dummy_property_map& - >::type pred_map = arg_pack[_predecessor_map | dummy_prop]; + dummy_property_map& >::type pred_map + = arg_pack[_predecessor_map | dummy_prop]; boost::detail::make_property_map_from_arg_pack_gen< - boost::graph::keywords::tag::rank_map, - D - > rank_map_gen(zero_actual); - typename boost::detail::map_maker< - VertexListGraph, - arg_pack_type, - boost::graph::keywords::tag::rank_map, - D - >::map_type r_map = rank_map_gen(g, arg_pack); + boost::graph::keywords::tag::rank_map, D > + rank_map_gen(zero_actual); + typename boost::detail::map_maker< VertexListGraph, arg_pack_type, + boost::graph::keywords::tag::rank_map, D >::map_type r_map + = rank_map_gen(g, arg_pack); boost::detail::make_property_map_from_arg_pack_gen< - boost::graph::keywords::tag::distance_map, - D - > dist_map_gen(zero_actual); - typename boost::detail::map_maker< - VertexListGraph, - arg_pack_type, - boost::graph::keywords::tag::distance_map, - D - >::map_type dist_map = dist_map_gen(g, arg_pack); - weight_map_type w_map = detail::override_const_property(arg_pack, _weight_map, g, edge_weight); - std::less default_compare; - typename boost::parameter::binding< - arg_pack_type, - boost::graph::keywords::tag::distance_compare, - std::less& - >::type dist_comp = arg_pack[_distance_compare | default_compare]; - closed_plus default_combine(inf); - typename boost::parameter::binding< - arg_pack_type, - boost::graph::keywords::tag::distance_combine, - closed_plus& - >::type dist_comb = arg_pack[_distance_combine | default_combine]; - astar_search_tree - (g, s, h, - vis, - pred_map, - r_map, - dist_map, - w_map, - dist_comp, - dist_comb, - inf, - zero_d); - } - - template - void - astar_search_no_init - (const VertexListGraph &g, - typename graph_traits::vertex_descriptor s, - AStarHeuristic h, const bgl_named_params& params) - { + boost::graph::keywords::tag::distance_map, D > + dist_map_gen(zero_actual); + typename boost::detail::map_maker< VertexListGraph, arg_pack_type, + boost::graph::keywords::tag::distance_map, D >::map_type dist_map + = dist_map_gen(g, arg_pack); + weight_map_type w_map = detail::override_const_property( + arg_pack, _weight_map, g, edge_weight); + std::less< D > default_compare; + typename boost::parameter::binding< arg_pack_type, + boost::graph::keywords::tag::distance_compare, std::less< D >& >::type + dist_comp + = arg_pack[_distance_compare | default_compare]; + closed_plus< D > default_combine(inf); + typename boost::parameter::binding< arg_pack_type, + boost::graph::keywords::tag::distance_combine, closed_plus< D >& >::type + dist_comb + = arg_pack[_distance_combine | default_combine]; + astar_search_tree(g, s, h, vis, pred_map, r_map, dist_map, w_map, dist_comp, + dist_comb, inf, zero_d); +} + +template < typename VertexListGraph, typename AStarHeuristic, typename P, + typename T, typename R > +void astar_search_no_init(const VertexListGraph& g, + typename graph_traits< VertexListGraph >::vertex_descriptor s, + AStarHeuristic h, const bgl_named_params< P, T, R >& params) +{ using namespace boost::graph::keywords; - typedef bgl_named_params params_type; + typedef bgl_named_params< P, T, R > params_type; BOOST_GRAPH_DECLARE_CONVERTED_PARAMETERS(params_type, params) - typedef typename boost::detail::override_const_property_result< - arg_pack_type, - boost::graph::keywords::tag::weight_map, - edge_weight_t, - VertexListGraph - >::type weight_map_type; - typedef typename boost::property_traits::value_type D; - const D inf = arg_pack[_distance_inf || detail::get_max()]; + typedef + typename boost::detail::override_const_property_result< arg_pack_type, + boost::graph::keywords::tag::weight_map, edge_weight_t, + VertexListGraph >::type weight_map_type; + typedef typename boost::property_traits< weight_map_type >::value_type D; + const D inf = arg_pack[_distance_inf || detail::get_max< D >()]; const D zero_actual = D(); const D zero_d = arg_pack[_distance_zero | zero_actual]; null_visitor null_vis; - astar_visitor default_visitor(null_vis); - typename boost::parameter::binding< - arg_pack_type, - boost::graph::keywords::tag::visitor, - dummy_property_map& - >::type vis = arg_pack[_visitor | default_visitor]; + astar_visitor< null_visitor > default_visitor(null_vis); + typename boost::parameter::binding< arg_pack_type, + boost::graph::keywords::tag::visitor, dummy_property_map& >::type vis + = arg_pack[_visitor | default_visitor]; dummy_property_map dummy_prop; - typename boost::parameter::binding< - arg_pack_type, + typename boost::parameter::binding< arg_pack_type, boost::graph::keywords::tag::predecessor_map, - dummy_property_map& - >::type pred_map = arg_pack[_predecessor_map | dummy_prop]; + dummy_property_map& >::type pred_map + = arg_pack[_predecessor_map | dummy_prop]; boost::detail::make_property_map_from_arg_pack_gen< - boost::graph::keywords::tag::rank_map, - D - > rank_map_gen(zero_actual); - typename boost::detail::map_maker< - VertexListGraph, - arg_pack_type, - boost::graph::keywords::tag::rank_map, - D - >::map_type r_map = rank_map_gen(g, arg_pack); + boost::graph::keywords::tag::rank_map, D > + rank_map_gen(zero_actual); + typename boost::detail::map_maker< VertexListGraph, arg_pack_type, + boost::graph::keywords::tag::rank_map, D >::map_type r_map + = rank_map_gen(g, arg_pack); boost::detail::make_property_map_from_arg_pack_gen< - boost::graph::keywords::tag::distance_map, - D - > dist_map_gen(zero_actual); - typename boost::detail::map_maker< - VertexListGraph, - arg_pack_type, - boost::graph::keywords::tag::distance_map, - D - >::map_type dist_map = dist_map_gen(g, arg_pack); - weight_map_type w_map = detail::override_const_property(arg_pack, _weight_map, g, edge_weight); - typename boost::detail::map_maker< - VertexListGraph, - arg_pack_type, + boost::graph::keywords::tag::distance_map, D > + dist_map_gen(zero_actual); + typename boost::detail::map_maker< VertexListGraph, arg_pack_type, + boost::graph::keywords::tag::distance_map, D >::map_type dist_map + = dist_map_gen(g, arg_pack); + weight_map_type w_map = detail::override_const_property( + arg_pack, _weight_map, g, edge_weight); + typename boost::detail::map_maker< VertexListGraph, arg_pack_type, boost::graph::keywords::tag::color_map, - boost::default_color_type - >::map_type c_map = boost::detail::make_color_map_from_arg_pack(g, arg_pack); - typename boost::detail::override_const_property_result< - arg_pack_type, - boost::graph::keywords::tag::vertex_index_map, - vertex_index_t, - VertexListGraph - >::type v_i_map = detail::override_const_property(arg_pack, _vertex_index_map, g, vertex_index); - std::less default_compare; - typename boost::parameter::binding< - arg_pack_type, - boost::graph::keywords::tag::distance_compare, - std::less& - >::type dist_comp = arg_pack[_distance_compare | default_compare]; - closed_plus default_combine(inf); - typename boost::parameter::binding< - arg_pack_type, - boost::graph::keywords::tag::distance_combine, - closed_plus& - >::type dist_comb = arg_pack[_distance_combine | default_combine]; - astar_search_no_init - (g, s, h, - vis, - pred_map, - r_map, - dist_map, - w_map, - c_map, - v_i_map, - dist_comp, - dist_comb, - inf, - zero_d); - } - - template - void - astar_search_no_init_tree - (const VertexListGraph &g, - typename graph_traits::vertex_descriptor s, - AStarHeuristic h, const bgl_named_params& params) - { + boost::default_color_type >::map_type c_map + = boost::detail::make_color_map_from_arg_pack(g, arg_pack); + typename boost::detail::override_const_property_result< arg_pack_type, + boost::graph::keywords::tag::vertex_index_map, vertex_index_t, + VertexListGraph >::type v_i_map + = detail::override_const_property( + arg_pack, _vertex_index_map, g, vertex_index); + std::less< D > default_compare; + typename boost::parameter::binding< arg_pack_type, + boost::graph::keywords::tag::distance_compare, std::less< D >& >::type + dist_comp + = arg_pack[_distance_compare | default_compare]; + closed_plus< D > default_combine(inf); + typename boost::parameter::binding< arg_pack_type, + boost::graph::keywords::tag::distance_combine, closed_plus< D >& >::type + dist_comb + = arg_pack[_distance_combine | default_combine]; + astar_search_no_init(g, s, h, vis, pred_map, r_map, dist_map, w_map, c_map, + v_i_map, dist_comp, dist_comb, inf, zero_d); +} + +template < typename VertexListGraph, typename AStarHeuristic, typename P, + typename T, typename R > +void astar_search_no_init_tree(const VertexListGraph& g, + typename graph_traits< VertexListGraph >::vertex_descriptor s, + AStarHeuristic h, const bgl_named_params< P, T, R >& params) +{ using namespace boost::graph::keywords; - typedef bgl_named_params params_type; + typedef bgl_named_params< P, T, R > params_type; BOOST_GRAPH_DECLARE_CONVERTED_PARAMETERS(params_type, params) - typedef typename boost::detail::override_const_property_result< - arg_pack_type, - boost::graph::keywords::tag::weight_map, - edge_weight_t, - VertexListGraph - >::type weight_map_type; - typedef typename boost::property_traits::value_type D; - const D inf = arg_pack[_distance_inf || detail::get_max()]; + typedef + typename boost::detail::override_const_property_result< arg_pack_type, + boost::graph::keywords::tag::weight_map, edge_weight_t, + VertexListGraph >::type weight_map_type; + typedef typename boost::property_traits< weight_map_type >::value_type D; + const D inf = arg_pack[_distance_inf || detail::get_max< D >()]; const D zero_actual = D(); const D zero_d = arg_pack[_distance_zero | zero_actual]; null_visitor null_vis; - astar_visitor default_visitor(null_vis); - typename boost::parameter::binding< - arg_pack_type, - boost::graph::keywords::tag::visitor, - dummy_property_map& - >::type vis = arg_pack[_visitor | default_visitor]; + astar_visitor< null_visitor > default_visitor(null_vis); + typename boost::parameter::binding< arg_pack_type, + boost::graph::keywords::tag::visitor, dummy_property_map& >::type vis + = arg_pack[_visitor | default_visitor]; dummy_property_map dummy_prop; - typename boost::parameter::binding< - arg_pack_type, + typename boost::parameter::binding< arg_pack_type, boost::graph::keywords::tag::predecessor_map, - dummy_property_map& - >::type pred_map = arg_pack[_predecessor_map | dummy_prop]; + dummy_property_map& >::type pred_map + = arg_pack[_predecessor_map | dummy_prop]; boost::detail::make_property_map_from_arg_pack_gen< - boost::graph::keywords::tag::rank_map, - D - > rank_map_gen(zero_actual); - typename boost::detail::map_maker< - VertexListGraph, - arg_pack_type, - boost::graph::keywords::tag::rank_map, - D - >::map_type r_map = rank_map_gen(g, arg_pack); + boost::graph::keywords::tag::rank_map, D > + rank_map_gen(zero_actual); + typename boost::detail::map_maker< VertexListGraph, arg_pack_type, + boost::graph::keywords::tag::rank_map, D >::map_type r_map + = rank_map_gen(g, arg_pack); boost::detail::make_property_map_from_arg_pack_gen< - boost::graph::keywords::tag::distance_map, - D - > dist_map_gen(zero_actual); - typename boost::detail::map_maker< - VertexListGraph, - arg_pack_type, - boost::graph::keywords::tag::distance_map, - D - >::map_type dist_map = dist_map_gen(g, arg_pack); - weight_map_type w_map = detail::override_const_property(arg_pack, _weight_map, g, edge_weight); - std::less default_compare; - typename boost::parameter::binding< - arg_pack_type, - boost::graph::keywords::tag::distance_compare, - std::less& - >::type dist_comp = arg_pack[_distance_compare | default_compare]; - closed_plus default_combine(inf); - typename boost::parameter::binding< - arg_pack_type, - boost::graph::keywords::tag::distance_combine, - closed_plus& - >::type dist_comb = arg_pack[_distance_combine | default_combine]; - astar_search_no_init_tree - (g, s, h, - vis, - pred_map, - r_map, - dist_map, - w_map, - dist_comp, - dist_comb, - inf, - zero_d); - } + boost::graph::keywords::tag::distance_map, D > + dist_map_gen(zero_actual); + typename boost::detail::map_maker< VertexListGraph, arg_pack_type, + boost::graph::keywords::tag::distance_map, D >::map_type dist_map + = dist_map_gen(g, arg_pack); + weight_map_type w_map = detail::override_const_property( + arg_pack, _weight_map, g, edge_weight); + std::less< D > default_compare; + typename boost::parameter::binding< arg_pack_type, + boost::graph::keywords::tag::distance_compare, std::less< D >& >::type + dist_comp + = arg_pack[_distance_compare | default_compare]; + closed_plus< D > default_combine(inf); + typename boost::parameter::binding< arg_pack_type, + boost::graph::keywords::tag::distance_combine, closed_plus< D >& >::type + dist_comb + = arg_pack[_distance_combine | default_combine]; + astar_search_no_init_tree(g, s, h, vis, pred_map, r_map, dist_map, w_map, + dist_comp, dist_comb, inf, zero_d); +} } // namespace boost diff --git a/include/boost/graph/bandwidth.hpp b/include/boost/graph/bandwidth.hpp index e8e7bf2cf..9d08ea54c 100644 --- a/include/boost/graph/bandwidth.hpp +++ b/include/boost/graph/bandwidth.hpp @@ -12,76 +12,82 @@ #include #include -namespace boost { +namespace boost +{ - template - typename graph_traits::vertices_size_type - ith_bandwidth(typename graph_traits::vertex_descriptor i, - const Graph& g, - VertexIndexMap index) - { +template < typename Graph, typename VertexIndexMap > +typename graph_traits< Graph >::vertices_size_type ith_bandwidth( + typename graph_traits< Graph >::vertex_descriptor i, const Graph& g, + VertexIndexMap index) +{ BOOST_USING_STD_MAX(); using std::abs; - typedef typename graph_traits::vertices_size_type vertices_size_type; + typedef + typename graph_traits< Graph >::vertices_size_type vertices_size_type; vertices_size_type b = 0; - typename graph_traits::out_edge_iterator e, end; - for (boost::tie(e, end) = out_edges(i, g); e != end; ++e) { - int f_i = get(index, i); - int f_j = get(index, target(*e, g)); - b = max BOOST_PREVENT_MACRO_SUBSTITUTION (b, vertices_size_type(abs(f_i - f_j))); + typename graph_traits< Graph >::out_edge_iterator e, end; + for (boost::tie(e, end) = out_edges(i, g); e != end; ++e) + { + int f_i = get(index, i); + int f_j = get(index, target(*e, g)); + b = max BOOST_PREVENT_MACRO_SUBSTITUTION( + b, vertices_size_type(abs(f_i - f_j))); } return b; - } +} - template - typename graph_traits::vertices_size_type - ith_bandwidth(typename graph_traits::vertex_descriptor i, - const Graph& g) - { +template < typename Graph > +typename graph_traits< Graph >::vertices_size_type ith_bandwidth( + typename graph_traits< Graph >::vertex_descriptor i, const Graph& g) +{ return ith_bandwidth(i, g, get(vertex_index, g)); - } +} - template - typename graph_traits::vertices_size_type - bandwidth(const Graph& g, VertexIndexMap index) - { +template < typename Graph, typename VertexIndexMap > +typename graph_traits< Graph >::vertices_size_type bandwidth( + const Graph& g, VertexIndexMap index) +{ BOOST_USING_STD_MAX(); using std::abs; - typedef typename graph_traits::vertices_size_type vertices_size_type; + typedef + typename graph_traits< Graph >::vertices_size_type vertices_size_type; vertices_size_type b = 0; - typename graph_traits::edge_iterator i, end; - for (boost::tie(i, end) = edges(g); i != end; ++i) { - int f_i = get(index, source(*i, g)); - int f_j = get(index, target(*i, g)); - b = max BOOST_PREVENT_MACRO_SUBSTITUTION (b, vertices_size_type(abs(f_i - f_j))); + typename graph_traits< Graph >::edge_iterator i, end; + for (boost::tie(i, end) = edges(g); i != end; ++i) + { + int f_i = get(index, source(*i, g)); + int f_j = get(index, target(*i, g)); + b = max BOOST_PREVENT_MACRO_SUBSTITUTION( + b, vertices_size_type(abs(f_i - f_j))); } return b; - } +} - template - typename graph_traits::vertices_size_type - bandwidth(const Graph& g) - { +template < typename Graph > +typename graph_traits< Graph >::vertices_size_type bandwidth(const Graph& g) +{ return bandwidth(g, get(vertex_index, g)); - } +} - template - typename graph_traits::vertices_size_type - edgesum(const Graph& g, VertexIndexMap index_map) - { - typedef typename graph_traits::vertices_size_type size_type; - typedef typename detail::numeric_traits::difference_type diff_t; +template < typename Graph, typename VertexIndexMap > +typename graph_traits< Graph >::vertices_size_type edgesum( + const Graph& g, VertexIndexMap index_map) +{ + typedef typename graph_traits< Graph >::vertices_size_type size_type; + typedef + typename detail::numeric_traits< size_type >::difference_type diff_t; size_type sum = 0; - typename graph_traits::edge_iterator i, end; - for (boost::tie(i, end) = edges(g); i != end; ++i) { - diff_t f_u = get(index_map, source(*i, g)); - diff_t f_v = get(index_map, target(*i, g)); - using namespace std; // to call abs() unqualified - sum += abs(f_u - f_v); + typename graph_traits< Graph >::edge_iterator i, end; + for (boost::tie(i, end) = edges(g); i != end; ++i) + { + diff_t f_u = get(index_map, source(*i, g)); + diff_t f_v = get(index_map, target(*i, g)); + using namespace std; // to call abs() unqualified + sum += abs(f_u - f_v); } return sum; - } - +} + } // namespace boost #endif // BOOST_GRAPH_BANDWIDTH_HPP diff --git a/include/boost/graph/bc_clustering.hpp b/include/boost/graph/bc_clustering.hpp index beba4d8e1..23d5dd580 100644 --- a/include/boost/graph/bc_clustering.hpp +++ b/include/boost/graph/bc_clustering.hpp @@ -17,59 +17,63 @@ #include #include -namespace boost { +namespace boost +{ /** Threshold termination function for the betweenness centrality * clustering algorithm. */ -template -struct bc_clustering_threshold +template < typename T > struct bc_clustering_threshold { - typedef T centrality_type; - - /// Terminate clustering when maximum absolute edge centrality is - /// below the given threshold. - explicit bc_clustering_threshold(T threshold) - : threshold(threshold), dividend(1.0) {} - - /** - * Terminate clustering when the maximum edge centrality is below - * the given threshold. - * - * @param threshold the threshold value - * - * @param g the graph on which the threshold will be calculated - * - * @param normalize when true, the threshold is compared against the - * normalized edge centrality based on the input graph; otherwise, - * the threshold is compared against the absolute edge centrality. - */ - template - bc_clustering_threshold(T threshold, const Graph& g, bool normalize = true) + typedef T centrality_type; + + /// Terminate clustering when maximum absolute edge centrality is + /// below the given threshold. + explicit bc_clustering_threshold(T threshold) + : threshold(threshold), dividend(1.0) + { + } + + /** + * Terminate clustering when the maximum edge centrality is below + * the given threshold. + * + * @param threshold the threshold value + * + * @param g the graph on which the threshold will be calculated + * + * @param normalize when true, the threshold is compared against the + * normalized edge centrality based on the input graph; otherwise, + * the threshold is compared against the absolute edge centrality. + */ + template < typename Graph > + bc_clustering_threshold(T threshold, const Graph& g, bool normalize = true) : threshold(threshold), dividend(1.0) - { - if (normalize) { - typename graph_traits::vertices_size_type n = num_vertices(g); - dividend = T((n - 1) * (n - 2)) / T(2); + { + if (normalize) + { + typename graph_traits< Graph >::vertices_size_type n + = num_vertices(g); + dividend = T((n - 1) * (n - 2)) / T(2); + } } - } - - /** Returns true when the given maximum edge centrality (potentially - * normalized) falls below the threshold. - */ - template - bool operator()(T max_centrality, Edge, const Graph&) - { - return (max_centrality / dividend) < threshold; - } - - protected: - T threshold; - T dividend; + + /** Returns true when the given maximum edge centrality (potentially + * normalized) falls below the threshold. + */ + template < typename Graph, typename Edge > + bool operator()(T max_centrality, Edge, const Graph&) + { + return (max_centrality / dividend) < threshold; + } + +protected: + T threshold; + T dividend; }; /** Graph clustering based on edge betweenness centrality. - * + * * This algorithm implements graph clustering based on edge * betweenness centrality. It is an iterative algorithm, where in each * step it compute the edge betweenness centrality (via @ref @@ -93,70 +97,71 @@ struct bc_clustering_threshold * terminates, it will contain the edge centralities for the * graph. The type of this property map must model the * ReadWritePropertyMap concept. Defaults to an @c - * iterator_property_map whose value type is - * @c Done::centrality_type and using @c get(edge_index, g) for the + * iterator_property_map whose value type is + * @c Done::centrality_type and using @c get(edge_index, g) for the * index map. * * @param vertex_index (IN) The property map that maps vertices to * indices in the range @c [0, num_vertices(g)). This type of this * property map must model the ReadablePropertyMap concept and its - * value type must be an integral type. Defaults to + * value type must be an integral type. Defaults to * @c get(vertex_index, g). */ -template -void -betweenness_centrality_clustering(MutableGraph& g, Done done, - EdgeCentralityMap edge_centrality, - VertexIndexMap vertex_index) +template < typename MutableGraph, typename Done, typename EdgeCentralityMap, + typename VertexIndexMap > +void betweenness_centrality_clustering(MutableGraph& g, Done done, + EdgeCentralityMap edge_centrality, VertexIndexMap vertex_index) { - typedef typename property_traits::value_type - centrality_type; - typedef typename graph_traits::edge_iterator edge_iterator; - typedef typename graph_traits::edge_descriptor edge_descriptor; - - if (has_no_edges(g)) return; - - // Function object that compares the centrality of edges - indirect_cmp > - cmp(edge_centrality); - - bool is_done; - do { - brandes_betweenness_centrality(g, - edge_centrality_map(edge_centrality) - .vertex_index_map(vertex_index)); - std::pair edges_iters = edges(g); - edge_descriptor e = *max_element(edges_iters.first, edges_iters.second, cmp); - is_done = done(get(edge_centrality, e), e, g); - if (!is_done) remove_edge(e, g); - } while (!is_done && !has_no_edges(g)); + typedef typename property_traits< EdgeCentralityMap >::value_type + centrality_type; + typedef typename graph_traits< MutableGraph >::edge_iterator edge_iterator; + typedef + typename graph_traits< MutableGraph >::edge_descriptor edge_descriptor; + + if (has_no_edges(g)) + return; + + // Function object that compares the centrality of edges + indirect_cmp< EdgeCentralityMap, std::less< centrality_type > > cmp( + edge_centrality); + + bool is_done; + do + { + brandes_betweenness_centrality(g, + edge_centrality_map(edge_centrality) + .vertex_index_map(vertex_index)); + std::pair< edge_iterator, edge_iterator > edges_iters = edges(g); + edge_descriptor e + = *max_element(edges_iters.first, edges_iters.second, cmp); + is_done = done(get(edge_centrality, e), e, g); + if (!is_done) + remove_edge(e, g); + } while (!is_done && !has_no_edges(g)); } /** * \overload - */ -template -void -betweenness_centrality_clustering(MutableGraph& g, Done done, - EdgeCentralityMap edge_centrality) + */ +template < typename MutableGraph, typename Done, typename EdgeCentralityMap > +void betweenness_centrality_clustering( + MutableGraph& g, Done done, EdgeCentralityMap edge_centrality) { - betweenness_centrality_clustering(g, done, edge_centrality, - get(vertex_index, g)); + betweenness_centrality_clustering( + g, done, edge_centrality, get(vertex_index, g)); } /** * \overload - */ -template -void -betweenness_centrality_clustering(MutableGraph& g, Done done) + */ +template < typename MutableGraph, typename Done > +void betweenness_centrality_clustering(MutableGraph& g, Done done) { - typedef typename Done::centrality_type centrality_type; - std::vector edge_centrality(num_edges(g)); - betweenness_centrality_clustering(g, done, - make_iterator_property_map(edge_centrality.begin(), get(edge_index, g)), - get(vertex_index, g)); + typedef typename Done::centrality_type centrality_type; + std::vector< centrality_type > edge_centrality(num_edges(g)); + betweenness_centrality_clustering(g, done, + make_iterator_property_map(edge_centrality.begin(), get(edge_index, g)), + get(vertex_index, g)); } } // end namespace boost diff --git a/include/boost/graph/bellman_ford_shortest_paths.hpp b/include/boost/graph/bellman_ford_shortest_paths.hpp index 7873067a1..2aa4e8083 100644 --- a/include/boost/graph/bellman_ford_shortest_paths.hpp +++ b/include/boost/graph/bellman_ford_shortest_paths.hpp @@ -13,11 +13,10 @@ This file implements the function template - bool bellman_ford_shortest_paths(EdgeListGraph& g, Size N, + bool bellman_ford_shortest_paths(EdgeListGraph& g, Size N, const bgl_named_params& params) - - */ + */ #ifndef BOOST_GRAPH_BELLMAN_FORD_SHORTEST_PATHS_HPP #define BOOST_GRAPH_BELLMAN_FORD_SHORTEST_PATHS_HPP @@ -31,210 +30,197 @@ #include #include -namespace boost { - - template - struct BellmanFordVisitorConcept { - void constraints() { - BOOST_CONCEPT_ASSERT(( CopyConstructibleConcept )); - vis.examine_edge(e, g); - vis.edge_relaxed(e, g); - vis.edge_not_relaxed(e, g); - vis.edge_minimized(e, g); - vis.edge_not_minimized(e, g); +namespace boost +{ + +template < class Visitor, class Graph > struct BellmanFordVisitorConcept +{ + void constraints() + { + BOOST_CONCEPT_ASSERT((CopyConstructibleConcept< Visitor >)); + vis.examine_edge(e, g); + vis.edge_relaxed(e, g); + vis.edge_not_relaxed(e, g); + vis.edge_minimized(e, g); + vis.edge_not_minimized(e, g); } Visitor vis; Graph g; - typename graph_traits::edge_descriptor e; - }; - - template - class bellman_visitor { - public: - bellman_visitor() { } - bellman_visitor(Visitors vis) : m_vis(vis) { } - - template - void examine_edge(Edge u, Graph& g) { - invoke_visitors(m_vis, u, g, on_examine_edge()); + typename graph_traits< Graph >::edge_descriptor e; +}; + +template < class Visitors = null_visitor > class bellman_visitor +{ +public: + bellman_visitor() {} + bellman_visitor(Visitors vis) : m_vis(vis) {} + + template < class Edge, class Graph > void examine_edge(Edge u, Graph& g) + { + invoke_visitors(m_vis, u, g, on_examine_edge()); } - template - void edge_relaxed(Edge u, Graph& g) { - invoke_visitors(m_vis, u, g, on_edge_relaxed()); + template < class Edge, class Graph > void edge_relaxed(Edge u, Graph& g) + { + invoke_visitors(m_vis, u, g, on_edge_relaxed()); } - template - void edge_not_relaxed(Edge u, Graph& g) { - invoke_visitors(m_vis, u, g, on_edge_not_relaxed()); + template < class Edge, class Graph > void edge_not_relaxed(Edge u, Graph& g) + { + invoke_visitors(m_vis, u, g, on_edge_not_relaxed()); } - template - void edge_minimized(Edge u, Graph& g) { - invoke_visitors(m_vis, u, g, on_edge_minimized()); + template < class Edge, class Graph > void edge_minimized(Edge u, Graph& g) + { + invoke_visitors(m_vis, u, g, on_edge_minimized()); } - template - void edge_not_minimized(Edge u, Graph& g) { - invoke_visitors(m_vis, u, g, on_edge_not_minimized()); + template < class Edge, class Graph > + void edge_not_minimized(Edge u, Graph& g) + { + invoke_visitors(m_vis, u, g, on_edge_not_minimized()); } - protected: + +protected: Visitors m_vis; - }; - template - bellman_visitor - make_bellman_visitor(Visitors vis) { - return bellman_visitor(vis); - } - typedef bellman_visitor<> default_bellman_visitor; - - template - bool bellman_ford_shortest_paths(EdgeListGraph& g, Size N, - WeightMap weight, - PredecessorMap pred, - DistanceMap distance, - BinaryFunction combine, - BinaryPredicate compare, - BellmanFordVisitor v) - { - BOOST_CONCEPT_ASSERT(( EdgeListGraphConcept )); - typedef graph_traits GTraits; +}; +template < class Visitors > +bellman_visitor< Visitors > make_bellman_visitor(Visitors vis) +{ + return bellman_visitor< Visitors >(vis); +} +typedef bellman_visitor<> default_bellman_visitor; + +template < class EdgeListGraph, class Size, class WeightMap, + class PredecessorMap, class DistanceMap, class BinaryFunction, + class BinaryPredicate, class BellmanFordVisitor > +bool bellman_ford_shortest_paths(EdgeListGraph& g, Size N, WeightMap weight, + PredecessorMap pred, DistanceMap distance, BinaryFunction combine, + BinaryPredicate compare, BellmanFordVisitor v) +{ + BOOST_CONCEPT_ASSERT((EdgeListGraphConcept< EdgeListGraph >)); + typedef graph_traits< EdgeListGraph > GTraits; typedef typename GTraits::edge_descriptor Edge; typedef typename GTraits::vertex_descriptor Vertex; - BOOST_CONCEPT_ASSERT(( ReadWritePropertyMapConcept )); - BOOST_CONCEPT_ASSERT(( ReadablePropertyMapConcept )); + BOOST_CONCEPT_ASSERT((ReadWritePropertyMapConcept< DistanceMap, Vertex >)); + BOOST_CONCEPT_ASSERT((ReadablePropertyMapConcept< WeightMap, Edge >)); typename GTraits::edge_iterator i, end; - for (Size k = 0; k < N; ++k) { - bool at_least_one_edge_relaxed = false; - for (boost::tie(i, end) = edges(g); i != end; ++i) { - v.examine_edge(*i, g); - if (relax(*i, g, weight, pred, distance, combine, compare)) { - at_least_one_edge_relaxed = true; - v.edge_relaxed(*i, g); - } else - v.edge_not_relaxed(*i, g); - } - if (!at_least_one_edge_relaxed) - break; + for (Size k = 0; k < N; ++k) + { + bool at_least_one_edge_relaxed = false; + for (boost::tie(i, end) = edges(g); i != end; ++i) + { + v.examine_edge(*i, g); + if (relax(*i, g, weight, pred, distance, combine, compare)) + { + at_least_one_edge_relaxed = true; + v.edge_relaxed(*i, g); + } + else + v.edge_not_relaxed(*i, g); + } + if (!at_least_one_edge_relaxed) + break; } for (boost::tie(i, end) = edges(g); i != end; ++i) - if (compare(combine(get(distance, source(*i, g)), get(weight, *i)), - get(distance, target(*i,g)))) - { - v.edge_not_minimized(*i, g); - return false; - } else - v.edge_minimized(*i, g); + if (compare(combine(get(distance, source(*i, g)), get(weight, *i)), + get(distance, target(*i, g)))) + { + v.edge_not_minimized(*i, g); + return false; + } + else + v.edge_minimized(*i, g); return true; - } - - namespace detail { - - template - bool - bellman_dispatch2 - (VertexAndEdgeListGraph& g, - typename graph_traits::vertex_descriptor s, - Size N, WeightMap weight, PredecessorMap pred, DistanceMap distance, - const bgl_named_params& params) +} + +namespace detail +{ + + template < typename VertexAndEdgeListGraph, typename Size, + typename WeightMap, typename PredecessorMap, typename DistanceMap, + typename P, typename T, typename R > + bool bellman_dispatch2(VertexAndEdgeListGraph& g, + typename graph_traits< VertexAndEdgeListGraph >::vertex_descriptor s, + Size N, WeightMap weight, PredecessorMap pred, DistanceMap distance, + const bgl_named_params< P, T, R >& params) { - typedef typename property_traits::value_type D; - bellman_visitor<> null_vis; - typedef typename property_traits::value_type weight_type; - typename graph_traits::vertex_iterator v, v_end; - for (boost::tie(v, v_end) = vertices(g); v != v_end; ++v) { - put(distance, *v, (std::numeric_limits::max)()); - put(pred, *v, *v); - } - put(distance, s, weight_type(0)); - return bellman_ford_shortest_paths - (g, N, weight, pred, distance, - choose_param(get_param(params, distance_combine_t()), - closed_plus()), - choose_param(get_param(params, distance_compare_t()), - std::less()), - choose_param(get_param(params, graph_visitor), - null_vis) - ); + typedef typename property_traits< DistanceMap >::value_type D; + bellman_visitor<> null_vis; + typedef typename property_traits< WeightMap >::value_type weight_type; + typename graph_traits< VertexAndEdgeListGraph >::vertex_iterator v, + v_end; + for (boost::tie(v, v_end) = vertices(g); v != v_end; ++v) + { + put(distance, *v, (std::numeric_limits< weight_type >::max)()); + put(pred, *v, *v); + } + put(distance, s, weight_type(0)); + return bellman_ford_shortest_paths(g, N, weight, pred, distance, + choose_param( + get_param(params, distance_combine_t()), closed_plus< D >()), + choose_param( + get_param(params, distance_compare_t()), std::less< D >()), + choose_param(get_param(params, graph_visitor), null_vis)); } - template - bool - bellman_dispatch2 - (VertexAndEdgeListGraph& g, - param_not_found, - Size N, WeightMap weight, PredecessorMap pred, DistanceMap distance, - const bgl_named_params& params) + template < typename VertexAndEdgeListGraph, typename Size, + typename WeightMap, typename PredecessorMap, typename DistanceMap, + typename P, typename T, typename R > + bool bellman_dispatch2(VertexAndEdgeListGraph& g, param_not_found, Size N, + WeightMap weight, PredecessorMap pred, DistanceMap distance, + const bgl_named_params< P, T, R >& params) { - typedef typename property_traits::value_type D; - bellman_visitor<> null_vis; - return bellman_ford_shortest_paths - (g, N, weight, pred, distance, - choose_param(get_param(params, distance_combine_t()), - closed_plus()), - choose_param(get_param(params, distance_compare_t()), - std::less()), - choose_param(get_param(params, graph_visitor), - null_vis) - ); + typedef typename property_traits< DistanceMap >::value_type D; + bellman_visitor<> null_vis; + return bellman_ford_shortest_paths(g, N, weight, pred, distance, + choose_param( + get_param(params, distance_combine_t()), closed_plus< D >()), + choose_param( + get_param(params, distance_compare_t()), std::less< D >()), + choose_param(get_param(params, graph_visitor), null_vis)); } - template - bool bellman_dispatch(EdgeListGraph& g, Size N, - WeightMap weight, DistanceMap distance, - const bgl_named_params& params) + template < class EdgeListGraph, class Size, class WeightMap, + class DistanceMap, class P, class T, class R > + bool bellman_dispatch(EdgeListGraph& g, Size N, WeightMap weight, + DistanceMap distance, const bgl_named_params< P, T, R >& params) { - dummy_property_map dummy_pred; - return - detail::bellman_dispatch2 - (g, - get_param(params, root_vertex_t()), - N, weight, - choose_param(get_param(params, vertex_predecessor), dummy_pred), - distance, - params); + dummy_property_map dummy_pred; + return detail::bellman_dispatch2(g, get_param(params, root_vertex_t()), + N, weight, + choose_param(get_param(params, vertex_predecessor), dummy_pred), + distance, params); } - } // namespace detail - - template - bool bellman_ford_shortest_paths - (EdgeListGraph& g, Size N, - const bgl_named_params& params) - { - return detail::bellman_dispatch - (g, N, - choose_const_pmap(get_param(params, edge_weight), g, edge_weight), - choose_pmap(get_param(params, vertex_distance), g, vertex_distance), - params); - } - - template - bool bellman_ford_shortest_paths(EdgeListGraph& g, Size N) - { - bgl_named_params params(0); +} // namespace detail + +template < class EdgeListGraph, class Size, class P, class T, class R > +bool bellman_ford_shortest_paths( + EdgeListGraph& g, Size N, const bgl_named_params< P, T, R >& params) +{ + return detail::bellman_dispatch(g, N, + choose_const_pmap(get_param(params, edge_weight), g, edge_weight), + choose_pmap(get_param(params, vertex_distance), g, vertex_distance), + params); +} + +template < class EdgeListGraph, class Size > +bool bellman_ford_shortest_paths(EdgeListGraph& g, Size N) +{ + bgl_named_params< int, int > params(0); return bellman_ford_shortest_paths(g, N, params); - } - - template - bool bellman_ford_shortest_paths - (VertexAndEdgeListGraph& g, - const bgl_named_params& params) - { - BOOST_CONCEPT_ASSERT(( VertexListGraphConcept )); - return detail::bellman_dispatch - (g, num_vertices(g), - choose_const_pmap(get_param(params, edge_weight), g, edge_weight), - choose_pmap(get_param(params, vertex_distance), g, vertex_distance), - params); - } +} + +template < class VertexAndEdgeListGraph, class P, class T, class R > +bool bellman_ford_shortest_paths( + VertexAndEdgeListGraph& g, const bgl_named_params< P, T, R >& params) +{ + BOOST_CONCEPT_ASSERT((VertexListGraphConcept< VertexAndEdgeListGraph >)); + return detail::bellman_dispatch(g, num_vertices(g), + choose_const_pmap(get_param(params, edge_weight), g, edge_weight), + choose_pmap(get_param(params, vertex_distance), g, vertex_distance), + params); +} } // namespace boost #endif // BOOST_GRAPH_BELLMAN_FORD_SHORTEST_PATHS_HPP diff --git a/include/boost/graph/betweenness_centrality.hpp b/include/boost/graph/betweenness_centrality.hpp index d596d5a28..b6148e46a 100644 --- a/include/boost/graph/betweenness_centrality.hpp +++ b/include/boost/graph/betweenness_centrality.hpp @@ -24,542 +24,565 @@ #include #include -namespace boost { - -namespace detail { namespace graph { - - /** - * Customized visitor passed to Dijkstra's algorithm by Brandes' - * betweenness centrality algorithm. This visitor is responsible for - * keeping track of the order in which vertices are discovered, the - * predecessors on the shortest path(s) to a vertex, and the number - * of shortest paths. - */ - template - struct brandes_dijkstra_visitor : public bfs_visitor<> - { - typedef typename graph_traits::vertex_descriptor vertex_descriptor; - typedef typename graph_traits::edge_descriptor edge_descriptor; - - brandes_dijkstra_visitor(std::stack& ordered_vertices, - WeightMap weight, - IncomingMap incoming, - DistanceMap distance, - PathCountMap path_count) - : ordered_vertices(ordered_vertices), weight(weight), - incoming(incoming), distance(distance), - path_count(path_count) - { } - - /** - * Whenever an edge e = (v, w) is relaxed, the incoming edge list - * for w is set to {(v, w)} and the shortest path count of w is set to - * the number of paths that reach {v}. - */ - void edge_relaxed(edge_descriptor e, const Graph& g) - { - vertex_descriptor v = source(e, g), w = target(e, g); - incoming[w].clear(); - incoming[w].push_back(e); - put(path_count, w, get(path_count, v)); - } +namespace boost +{ - /** - * If an edge e = (v, w) was not relaxed, it may still be the case - * that we've found more equally-short paths, so include {(v, w)} in the - * incoming edges of w and add all of the shortest paths to v to the - * shortest path count of w. - */ - void edge_not_relaxed(edge_descriptor e, const Graph& g) +namespace detail +{ + namespace graph { - typedef typename property_traits::value_type weight_type; - typedef typename property_traits::value_type distance_type; - vertex_descriptor v = source(e, g), w = target(e, g); - distance_type d_v = get(distance, v), d_w = get(distance, w); - weight_type w_e = get(weight, e); - - closed_plus combine; - if (d_w == combine(d_v, w_e)) { - put(path_count, w, get(path_count, w) + get(path_count, v)); - incoming[w].push_back(e); - } - } - /// Keep track of vertices as they are reached - void examine_vertex(vertex_descriptor w, const Graph&) - { - ordered_vertices.push(w); - } + /** + * Customized visitor passed to Dijkstra's algorithm by Brandes' + * betweenness centrality algorithm. This visitor is responsible for + * keeping track of the order in which vertices are discovered, the + * predecessors on the shortest path(s) to a vertex, and the number + * of shortest paths. + */ + template < typename Graph, typename WeightMap, typename IncomingMap, + typename DistanceMap, typename PathCountMap > + struct brandes_dijkstra_visitor : public bfs_visitor<> + { + typedef typename graph_traits< Graph >::vertex_descriptor + vertex_descriptor; + typedef + typename graph_traits< Graph >::edge_descriptor edge_descriptor; + + brandes_dijkstra_visitor( + std::stack< vertex_descriptor >& ordered_vertices, + WeightMap weight, IncomingMap incoming, DistanceMap distance, + PathCountMap path_count) + : ordered_vertices(ordered_vertices) + , weight(weight) + , incoming(incoming) + , distance(distance) + , path_count(path_count) + { + } + + /** + * Whenever an edge e = (v, w) is relaxed, the incoming edge list + * for w is set to {(v, w)} and the shortest path count of w is set + * to the number of paths that reach {v}. + */ + void edge_relaxed(edge_descriptor e, const Graph& g) + { + vertex_descriptor v = source(e, g), w = target(e, g); + incoming[w].clear(); + incoming[w].push_back(e); + put(path_count, w, get(path_count, v)); + } + + /** + * If an edge e = (v, w) was not relaxed, it may still be the case + * that we've found more equally-short paths, so include {(v, w)} in + * the incoming edges of w and add all of the shortest paths to v to + * the shortest path count of w. + */ + void edge_not_relaxed(edge_descriptor e, const Graph& g) + { + typedef typename property_traits< WeightMap >::value_type + weight_type; + typedef typename property_traits< DistanceMap >::value_type + distance_type; + vertex_descriptor v = source(e, g), w = target(e, g); + distance_type d_v = get(distance, v), d_w = get(distance, w); + weight_type w_e = get(weight, e); + + closed_plus< distance_type > combine; + if (d_w == combine(d_v, w_e)) + { + put(path_count, w, get(path_count, w) + get(path_count, v)); + incoming[w].push_back(e); + } + } + + /// Keep track of vertices as they are reached + void examine_vertex(vertex_descriptor w, const Graph&) + { + ordered_vertices.push(w); + } + + private: + std::stack< vertex_descriptor >& ordered_vertices; + WeightMap weight; + IncomingMap incoming; + DistanceMap distance; + PathCountMap path_count; + }; + + /** + * Function object that calls Dijkstra's shortest paths algorithm + * using the Dijkstra visitor for the Brandes betweenness centrality + * algorithm. + */ + template < typename WeightMap > struct brandes_dijkstra_shortest_paths + { + brandes_dijkstra_shortest_paths(WeightMap weight_map) + : weight_map(weight_map) + { + } + + template < typename Graph, typename IncomingMap, + typename DistanceMap, typename PathCountMap, + typename VertexIndexMap > + void operator()(Graph& g, + typename graph_traits< Graph >::vertex_descriptor s, + std::stack< typename graph_traits< Graph >::vertex_descriptor >& + ov, + IncomingMap incoming, DistanceMap distance, + PathCountMap path_count, VertexIndexMap vertex_index) + { + typedef brandes_dijkstra_visitor< Graph, WeightMap, IncomingMap, + DistanceMap, PathCountMap > + visitor_type; + visitor_type visitor( + ov, weight_map, incoming, distance, path_count); + + dijkstra_shortest_paths(g, s, + boost::weight_map(weight_map) + .vertex_index_map(vertex_index) + .distance_map(distance) + .visitor(visitor)); + } + + private: + WeightMap weight_map; + }; + + /** + * Function object that invokes breadth-first search for the + * unweighted form of the Brandes betweenness centrality algorithm. + */ + struct brandes_unweighted_shortest_paths + { + /** + * Customized visitor passed to breadth-first search, which + * records predecessor and the number of shortest paths to each + * vertex. + */ + template < typename Graph, typename IncomingMap, + typename DistanceMap, typename PathCountMap > + struct visitor_type : public bfs_visitor<> + { + typedef typename graph_traits< Graph >::edge_descriptor + edge_descriptor; + typedef typename graph_traits< Graph >::vertex_descriptor + vertex_descriptor; + + visitor_type(IncomingMap incoming, DistanceMap distance, + PathCountMap path_count, + std::stack< vertex_descriptor >& ordered_vertices) + : incoming(incoming) + , distance(distance) + , path_count(path_count) + , ordered_vertices(ordered_vertices) + { + } + + /// Keep track of vertices as they are reached + void examine_vertex(vertex_descriptor v, Graph&) + { + ordered_vertices.push(v); + } + + /** + * Whenever an edge e = (v, w) is labelled a tree edge, the + * incoming edge list for w is set to {(v, w)} and the shortest + * path count of w is set to the number of paths that reach {v}. + */ + void tree_edge(edge_descriptor e, Graph& g) + { + vertex_descriptor v = source(e, g); + vertex_descriptor w = target(e, g); + put(distance, w, get(distance, v) + 1); + + put(path_count, w, get(path_count, v)); + incoming[w].push_back(e); + } + + /** + * If an edge e = (v, w) is not a tree edge, it may still be the + * case that we've found more equally-short paths, so include + * (v, w) in the incoming edge list of w and add all of the + * shortest paths to v to the shortest path count of w. + */ + void non_tree_edge(edge_descriptor e, Graph& g) + { + vertex_descriptor v = source(e, g); + vertex_descriptor w = target(e, g); + if (get(distance, w) == get(distance, v) + 1) + { + put(path_count, w, + get(path_count, w) + get(path_count, v)); + incoming[w].push_back(e); + } + } + + private: + IncomingMap incoming; + DistanceMap distance; + PathCountMap path_count; + std::stack< vertex_descriptor >& ordered_vertices; + }; + + template < typename Graph, typename IncomingMap, + typename DistanceMap, typename PathCountMap, + typename VertexIndexMap > + void operator()(Graph& g, + typename graph_traits< Graph >::vertex_descriptor s, + std::stack< typename graph_traits< Graph >::vertex_descriptor >& + ov, + IncomingMap incoming, DistanceMap distance, + PathCountMap path_count, VertexIndexMap vertex_index) + { + typedef typename graph_traits< Graph >::vertex_descriptor + vertex_descriptor; + + visitor_type< Graph, IncomingMap, DistanceMap, PathCountMap > + visitor(incoming, distance, path_count, ov); + + std::vector< default_color_type > colors(num_vertices(g), + color_traits< default_color_type >::white()); + boost::queue< vertex_descriptor > Q; + breadth_first_visit(g, s, Q, visitor, + make_iterator_property_map(colors.begin(), vertex_index)); + } + }; + + // When the edge centrality map is a dummy property map, no + // initialization is needed. + template < typename Iter > + inline void init_centrality_map( + std::pair< Iter, Iter >, dummy_property_map) + { + } - private: - std::stack& ordered_vertices; - WeightMap weight; - IncomingMap incoming; - DistanceMap distance; - PathCountMap path_count; - }; - - /** - * Function object that calls Dijkstra's shortest paths algorithm - * using the Dijkstra visitor for the Brandes betweenness centrality - * algorithm. - */ - template - struct brandes_dijkstra_shortest_paths - { - brandes_dijkstra_shortest_paths(WeightMap weight_map) - : weight_map(weight_map) { } - - template - void - operator()(Graph& g, - typename graph_traits::vertex_descriptor s, - std::stack::vertex_descriptor>& ov, - IncomingMap incoming, - DistanceMap distance, - PathCountMap path_count, - VertexIndexMap vertex_index) - { - typedef brandes_dijkstra_visitor visitor_type; - visitor_type visitor(ov, weight_map, incoming, distance, path_count); - - dijkstra_shortest_paths(g, s, - boost::weight_map(weight_map) - .vertex_index_map(vertex_index) - .distance_map(distance) - .visitor(visitor)); - } + // When we have a real edge centrality map, initialize all of the + // centralities to zero. + template < typename Iter, typename Centrality > + void init_centrality_map( + std::pair< Iter, Iter > keys, Centrality centrality_map) + { + typedef typename property_traits< Centrality >::value_type + centrality_type; + while (keys.first != keys.second) + { + put(centrality_map, *keys.first, centrality_type(0)); + ++keys.first; + } + } - private: - WeightMap weight_map; - }; - - /** - * Function object that invokes breadth-first search for the - * unweighted form of the Brandes betweenness centrality algorithm. - */ - struct brandes_unweighted_shortest_paths - { - /** - * Customized visitor passed to breadth-first search, which - * records predecessor and the number of shortest paths to each - * vertex. - */ - template - struct visitor_type : public bfs_visitor<> - { - typedef typename graph_traits::edge_descriptor edge_descriptor; - typedef typename graph_traits::vertex_descriptor - vertex_descriptor; - - visitor_type(IncomingMap incoming, DistanceMap distance, - PathCountMap path_count, - std::stack& ordered_vertices) - : incoming(incoming), distance(distance), - path_count(path_count), ordered_vertices(ordered_vertices) { } - - /// Keep track of vertices as they are reached - void examine_vertex(vertex_descriptor v, Graph&) - { - ordered_vertices.push(v); - } - - /** - * Whenever an edge e = (v, w) is labelled a tree edge, the - * incoming edge list for w is set to {(v, w)} and the shortest - * path count of w is set to the number of paths that reach {v}. - */ - void tree_edge(edge_descriptor e, Graph& g) - { - vertex_descriptor v = source(e, g); - vertex_descriptor w = target(e, g); - put(distance, w, get(distance, v) + 1); - - put(path_count, w, get(path_count, v)); - incoming[w].push_back(e); - } - - /** - * If an edge e = (v, w) is not a tree edge, it may still be the - * case that we've found more equally-short paths, so include (v, w) - * in the incoming edge list of w and add all of the shortest - * paths to v to the shortest path count of w. - */ - void non_tree_edge(edge_descriptor e, Graph& g) - { - vertex_descriptor v = source(e, g); - vertex_descriptor w = target(e, g); - if (get(distance, w) == get(distance, v) + 1) { - put(path_count, w, get(path_count, w) + get(path_count, v)); - incoming[w].push_back(e); + // When the edge centrality map is a dummy property map, no update + // is performed. + template < typename Key, typename T > + inline void update_centrality(dummy_property_map, const Key&, const T&) + { } - } - - private: - IncomingMap incoming; - DistanceMap distance; - PathCountMap path_count; - std::stack& ordered_vertices; - }; - - template - void - operator()(Graph& g, - typename graph_traits::vertex_descriptor s, - std::stack::vertex_descriptor>& ov, - IncomingMap incoming, - DistanceMap distance, - PathCountMap path_count, - VertexIndexMap vertex_index) - { - typedef typename graph_traits::vertex_descriptor - vertex_descriptor; - - visitor_type - visitor(incoming, distance, path_count, ov); - - std::vector - colors(num_vertices(g), color_traits::white()); - boost::queue Q; - breadth_first_visit(g, s, Q, visitor, - make_iterator_property_map(colors.begin(), - vertex_index)); - } - }; - - // When the edge centrality map is a dummy property map, no - // initialization is needed. - template - inline void - init_centrality_map(std::pair, dummy_property_map) { } - - // When we have a real edge centrality map, initialize all of the - // centralities to zero. - template - void - init_centrality_map(std::pair keys, Centrality centrality_map) - { - typedef typename property_traits::value_type - centrality_type; - while (keys.first != keys.second) { - put(centrality_map, *keys.first, centrality_type(0)); - ++keys.first; - } - } - - // When the edge centrality map is a dummy property map, no update - // is performed. - template - inline void - update_centrality(dummy_property_map, const Key&, const T&) { } - - // When we have a real edge centrality map, add the value to the map - template - inline void - update_centrality(CentralityMap centrality_map, Key k, const T& x) - { put(centrality_map, k, get(centrality_map, k) + x); } - - template - inline void - divide_centrality_by_two(std::pair, dummy_property_map) {} - - template - inline void - divide_centrality_by_two(std::pair keys, - CentralityMap centrality_map) - { - typename property_traits::value_type two(2); - while (keys.first != keys.second) { - put(centrality_map, *keys.first, get(centrality_map, *keys.first) / two); - ++keys.first; - } - } - - template - void - brandes_betweenness_centrality_impl(const Graph& g, - CentralityMap centrality, // C_B - EdgeCentralityMap edge_centrality_map, - IncomingMap incoming, // P - DistanceMap distance, // d - DependencyMap dependency, // delta - PathCountMap path_count, // sigma - VertexIndexMap vertex_index, - ShortestPaths shortest_paths) - { - typedef typename graph_traits::vertex_iterator vertex_iterator; - typedef typename graph_traits::vertex_descriptor vertex_descriptor; - - // Initialize centrality - init_centrality_map(vertices(g), centrality); - init_centrality_map(edges(g), edge_centrality_map); - - std::stack ordered_vertices; - vertex_iterator s, s_end; - for (boost::tie(s, s_end) = vertices(g); s != s_end; ++s) { - // Initialize for this iteration - vertex_iterator w, w_end; - for (boost::tie(w, w_end) = vertices(g); w != w_end; ++w) { - incoming[*w].clear(); - put(path_count, *w, 0); - put(dependency, *w, 0); - } - put(path_count, *s, 1); - - // Execute the shortest paths algorithm. This will be either - // Dijkstra's algorithm or a customized breadth-first search, - // depending on whether the graph is weighted or unweighted. - shortest_paths(g, *s, ordered_vertices, incoming, distance, - path_count, vertex_index); - - while (!ordered_vertices.empty()) { - vertex_descriptor w = ordered_vertices.top(); - ordered_vertices.pop(); - - typedef typename property_traits::value_type - incoming_type; - typedef typename incoming_type::iterator incoming_iterator; - typedef typename property_traits::value_type - dependency_type; - - for (incoming_iterator vw = incoming[w].begin(); - vw != incoming[w].end(); ++vw) { - vertex_descriptor v = source(*vw, g); - dependency_type factor = dependency_type(get(path_count, v)) - / dependency_type(get(path_count, w)); - factor *= (dependency_type(1) + get(dependency, w)); - put(dependency, v, get(dependency, v) + factor); - update_centrality(edge_centrality_map, *vw, factor); + + // When we have a real edge centrality map, add the value to the map + template < typename CentralityMap, typename Key, typename T > + inline void update_centrality( + CentralityMap centrality_map, Key k, const T& x) + { + put(centrality_map, k, get(centrality_map, k) + x); } - - if (w != *s) { - update_centrality(centrality, w, get(dependency, w)); + + template < typename Iter > + inline void divide_centrality_by_two( + std::pair< Iter, Iter >, dummy_property_map) + { + } + + template < typename Iter, typename CentralityMap > + inline void divide_centrality_by_two( + std::pair< Iter, Iter > keys, CentralityMap centrality_map) + { + typename property_traits< CentralityMap >::value_type two(2); + while (keys.first != keys.second) + { + put(centrality_map, *keys.first, + get(centrality_map, *keys.first) / two); + ++keys.first; + } + } + + template < typename Graph, typename CentralityMap, + typename EdgeCentralityMap, typename IncomingMap, + typename DistanceMap, typename DependencyMap, typename PathCountMap, + typename VertexIndexMap, typename ShortestPaths > + void brandes_betweenness_centrality_impl(const Graph& g, + CentralityMap centrality, // C_B + EdgeCentralityMap edge_centrality_map, + IncomingMap incoming, // P + DistanceMap distance, // d + DependencyMap dependency, // delta + PathCountMap path_count, // sigma + VertexIndexMap vertex_index, ShortestPaths shortest_paths) + { + typedef + typename graph_traits< Graph >::vertex_iterator vertex_iterator; + typedef typename graph_traits< Graph >::vertex_descriptor + vertex_descriptor; + + // Initialize centrality + init_centrality_map(vertices(g), centrality); + init_centrality_map(edges(g), edge_centrality_map); + + std::stack< vertex_descriptor > ordered_vertices; + vertex_iterator s, s_end; + for (boost::tie(s, s_end) = vertices(g); s != s_end; ++s) + { + // Initialize for this iteration + vertex_iterator w, w_end; + for (boost::tie(w, w_end) = vertices(g); w != w_end; ++w) + { + incoming[*w].clear(); + put(path_count, *w, 0); + put(dependency, *w, 0); + } + put(path_count, *s, 1); + + // Execute the shortest paths algorithm. This will be either + // Dijkstra's algorithm or a customized breadth-first search, + // depending on whether the graph is weighted or unweighted. + shortest_paths(g, *s, ordered_vertices, incoming, distance, + path_count, vertex_index); + + while (!ordered_vertices.empty()) + { + vertex_descriptor w = ordered_vertices.top(); + ordered_vertices.pop(); + + typedef typename property_traits< IncomingMap >::value_type + incoming_type; + typedef typename incoming_type::iterator incoming_iterator; + typedef + typename property_traits< DependencyMap >::value_type + dependency_type; + + for (incoming_iterator vw = incoming[w].begin(); + vw != incoming[w].end(); ++vw) + { + vertex_descriptor v = source(*vw, g); + dependency_type factor + = dependency_type(get(path_count, v)) + / dependency_type(get(path_count, w)); + factor *= (dependency_type(1) + get(dependency, w)); + put(dependency, v, get(dependency, v) + factor); + update_centrality(edge_centrality_map, *vw, factor); + } + + if (w != *s) + { + update_centrality(centrality, w, get(dependency, w)); + } + } + } + + typedef typename graph_traits< Graph >::directed_category + directed_category; + const bool is_undirected + = is_convertible< directed_category*, undirected_tag* >::value; + if (is_undirected) + { + divide_centrality_by_two(vertices(g), centrality); + divide_centrality_by_two(edges(g), edge_centrality_map); + } } - } - } - typedef typename graph_traits::directed_category directed_category; - const bool is_undirected = - is_convertible::value; - if (is_undirected) { - divide_centrality_by_two(vertices(g), centrality); - divide_centrality_by_two(edges(g), edge_centrality_map); } - } - -} } // end namespace detail::graph - -template -void -brandes_betweenness_centrality(const Graph& g, - CentralityMap centrality, // C_B - EdgeCentralityMap edge_centrality_map, - IncomingMap incoming, // P - DistanceMap distance, // d - DependencyMap dependency, // delta - PathCountMap path_count, // sigma - VertexIndexMap vertex_index - BOOST_GRAPH_ENABLE_IF_MODELS_PARM(Graph,vertex_list_graph_tag)) +} // end namespace detail::graph + +template < typename Graph, typename CentralityMap, typename EdgeCentralityMap, + typename IncomingMap, typename DistanceMap, typename DependencyMap, + typename PathCountMap, typename VertexIndexMap > +void brandes_betweenness_centrality(const Graph& g, + CentralityMap centrality, // C_B + EdgeCentralityMap edge_centrality_map, + IncomingMap incoming, // P + DistanceMap distance, // d + DependencyMap dependency, // delta + PathCountMap path_count, // sigma + VertexIndexMap vertex_index BOOST_GRAPH_ENABLE_IF_MODELS_PARM( + Graph, vertex_list_graph_tag)) { - detail::graph::brandes_unweighted_shortest_paths shortest_paths; - - detail::graph::brandes_betweenness_centrality_impl(g, centrality, - edge_centrality_map, - incoming, distance, - dependency, path_count, - vertex_index, - shortest_paths); + detail::graph::brandes_unweighted_shortest_paths shortest_paths; + + detail::graph::brandes_betweenness_centrality_impl(g, centrality, + edge_centrality_map, incoming, distance, dependency, path_count, + vertex_index, shortest_paths); } -template -void -brandes_betweenness_centrality(const Graph& g, - CentralityMap centrality, // C_B - EdgeCentralityMap edge_centrality_map, - IncomingMap incoming, // P - DistanceMap distance, // d - DependencyMap dependency, // delta - PathCountMap path_count, // sigma - VertexIndexMap vertex_index, - WeightMap weight_map - BOOST_GRAPH_ENABLE_IF_MODELS_PARM(Graph,vertex_list_graph_tag)) +template < typename Graph, typename CentralityMap, typename EdgeCentralityMap, + typename IncomingMap, typename DistanceMap, typename DependencyMap, + typename PathCountMap, typename VertexIndexMap, typename WeightMap > +void brandes_betweenness_centrality(const Graph& g, + CentralityMap centrality, // C_B + EdgeCentralityMap edge_centrality_map, + IncomingMap incoming, // P + DistanceMap distance, // d + DependencyMap dependency, // delta + PathCountMap path_count, // sigma + VertexIndexMap vertex_index, + WeightMap weight_map BOOST_GRAPH_ENABLE_IF_MODELS_PARM( + Graph, vertex_list_graph_tag)) { - detail::graph::brandes_dijkstra_shortest_paths - shortest_paths(weight_map); - - detail::graph::brandes_betweenness_centrality_impl(g, centrality, - edge_centrality_map, - incoming, distance, - dependency, path_count, - vertex_index, - shortest_paths); + detail::graph::brandes_dijkstra_shortest_paths< WeightMap > shortest_paths( + weight_map); + + detail::graph::brandes_betweenness_centrality_impl(g, centrality, + edge_centrality_map, incoming, distance, dependency, path_count, + vertex_index, shortest_paths); } -namespace detail { namespace graph { - template - void - brandes_betweenness_centrality_dispatch2(const Graph& g, - CentralityMap centrality, - EdgeCentralityMap edge_centrality_map, - WeightMap weight_map, - VertexIndexMap vertex_index) - { - typedef typename graph_traits::degree_size_type degree_size_type; - typedef typename graph_traits::edge_descriptor edge_descriptor; - typedef typename mpl::if_c<(is_same::value), - EdgeCentralityMap, - CentralityMap>::type a_centrality_map; - typedef typename property_traits::value_type - centrality_type; - - typename graph_traits::vertices_size_type V = num_vertices(g); - - std::vector > incoming(V); - std::vector distance(V); - std::vector dependency(V); - std::vector path_count(V); - - brandes_betweenness_centrality( - g, centrality, edge_centrality_map, - make_iterator_property_map(incoming.begin(), vertex_index), - make_iterator_property_map(distance.begin(), vertex_index), - make_iterator_property_map(dependency.begin(), vertex_index), - make_iterator_property_map(path_count.begin(), vertex_index), - vertex_index, - weight_map); - } - - - template - void - brandes_betweenness_centrality_dispatch2(const Graph& g, - CentralityMap centrality, - EdgeCentralityMap edge_centrality_map, - VertexIndexMap vertex_index) - { - typedef typename graph_traits::degree_size_type degree_size_type; - typedef typename graph_traits::edge_descriptor edge_descriptor; - typedef typename mpl::if_c<(is_same::value), - EdgeCentralityMap, - CentralityMap>::type a_centrality_map; - typedef typename property_traits::value_type - centrality_type; - - typename graph_traits::vertices_size_type V = num_vertices(g); - - std::vector > incoming(V); - std::vector distance(V); - std::vector dependency(V); - std::vector path_count(V); - - brandes_betweenness_centrality( - g, centrality, edge_centrality_map, - make_iterator_property_map(incoming.begin(), vertex_index), - make_iterator_property_map(distance.begin(), vertex_index), - make_iterator_property_map(dependency.begin(), vertex_index), - make_iterator_property_map(path_count.begin(), vertex_index), - vertex_index); - } - - template - struct brandes_betweenness_centrality_dispatch1 - { - template - static void - run(const Graph& g, CentralityMap centrality, - EdgeCentralityMap edge_centrality_map, VertexIndexMap vertex_index, - WeightMap weight_map) - { - brandes_betweenness_centrality_dispatch2(g, centrality, edge_centrality_map, - weight_map, vertex_index); - } - }; - - template<> - struct brandes_betweenness_centrality_dispatch1 - { - template - static void - run(const Graph& g, CentralityMap centrality, - EdgeCentralityMap edge_centrality_map, VertexIndexMap vertex_index, - param_not_found) +namespace detail +{ + namespace graph { - brandes_betweenness_centrality_dispatch2(g, centrality, edge_centrality_map, - vertex_index); - } - }; + template < typename Graph, typename CentralityMap, + typename EdgeCentralityMap, typename WeightMap, + typename VertexIndexMap > + void brandes_betweenness_centrality_dispatch2(const Graph& g, + CentralityMap centrality, EdgeCentralityMap edge_centrality_map, + WeightMap weight_map, VertexIndexMap vertex_index) + { + typedef typename graph_traits< Graph >::degree_size_type + degree_size_type; + typedef + typename graph_traits< Graph >::edge_descriptor edge_descriptor; + typedef typename mpl::if_c< + (is_same< CentralityMap, dummy_property_map >::value), + EdgeCentralityMap, CentralityMap >::type a_centrality_map; + typedef typename property_traits< a_centrality_map >::value_type + centrality_type; + + typename graph_traits< Graph >::vertices_size_type V + = num_vertices(g); + + std::vector< std::vector< edge_descriptor > > incoming(V); + std::vector< centrality_type > distance(V); + std::vector< centrality_type > dependency(V); + std::vector< degree_size_type > path_count(V); + + brandes_betweenness_centrality(g, centrality, edge_centrality_map, + make_iterator_property_map(incoming.begin(), vertex_index), + make_iterator_property_map(distance.begin(), vertex_index), + make_iterator_property_map(dependency.begin(), vertex_index), + make_iterator_property_map(path_count.begin(), vertex_index), + vertex_index, weight_map); + } - template - struct is_bgl_named_params { - BOOST_STATIC_CONSTANT(bool, value = false); - }; + template < typename Graph, typename CentralityMap, + typename EdgeCentralityMap, typename VertexIndexMap > + void brandes_betweenness_centrality_dispatch2(const Graph& g, + CentralityMap centrality, EdgeCentralityMap edge_centrality_map, + VertexIndexMap vertex_index) + { + typedef typename graph_traits< Graph >::degree_size_type + degree_size_type; + typedef + typename graph_traits< Graph >::edge_descriptor edge_descriptor; + typedef typename mpl::if_c< + (is_same< CentralityMap, dummy_property_map >::value), + EdgeCentralityMap, CentralityMap >::type a_centrality_map; + typedef typename property_traits< a_centrality_map >::value_type + centrality_type; + + typename graph_traits< Graph >::vertices_size_type V + = num_vertices(g); + + std::vector< std::vector< edge_descriptor > > incoming(V); + std::vector< centrality_type > distance(V); + std::vector< centrality_type > dependency(V); + std::vector< degree_size_type > path_count(V); + + brandes_betweenness_centrality(g, centrality, edge_centrality_map, + make_iterator_property_map(incoming.begin(), vertex_index), + make_iterator_property_map(distance.begin(), vertex_index), + make_iterator_property_map(dependency.begin(), vertex_index), + make_iterator_property_map(path_count.begin(), vertex_index), + vertex_index); + } - template - struct is_bgl_named_params > { - BOOST_STATIC_CONSTANT(bool, value = true); - }; + template < typename WeightMap > + struct brandes_betweenness_centrality_dispatch1 + { + template < typename Graph, typename CentralityMap, + typename EdgeCentralityMap, typename VertexIndexMap > + static void run(const Graph& g, CentralityMap centrality, + EdgeCentralityMap edge_centrality_map, + VertexIndexMap vertex_index, WeightMap weight_map) + { + brandes_betweenness_centrality_dispatch2(g, centrality, + edge_centrality_map, weight_map, vertex_index); + } + }; + + template <> + struct brandes_betweenness_centrality_dispatch1< param_not_found > + { + template < typename Graph, typename CentralityMap, + typename EdgeCentralityMap, typename VertexIndexMap > + static void run(const Graph& g, CentralityMap centrality, + EdgeCentralityMap edge_centrality_map, + VertexIndexMap vertex_index, param_not_found) + { + brandes_betweenness_centrality_dispatch2( + g, centrality, edge_centrality_map, vertex_index); + } + }; + + template < typename T > struct is_bgl_named_params + { + BOOST_STATIC_CONSTANT(bool, value = false); + }; + + template < typename Param, typename Tag, typename Rest > + struct is_bgl_named_params< bgl_named_params< Param, Tag, Rest > > + { + BOOST_STATIC_CONSTANT(bool, value = true); + }; -} } // end namespace detail::graph + } +} // end namespace detail::graph -template -void -brandes_betweenness_centrality(const Graph& g, - const bgl_named_params& params - BOOST_GRAPH_ENABLE_IF_MODELS_PARM(Graph,vertex_list_graph_tag)) +template < typename Graph, typename Param, typename Tag, typename Rest > +void brandes_betweenness_centrality(const Graph& g, + const bgl_named_params< Param, Tag, Rest >& params + BOOST_GRAPH_ENABLE_IF_MODELS_PARM(Graph, vertex_list_graph_tag)) { - typedef bgl_named_params named_params; - - typedef typename get_param_type::type ew; - detail::graph::brandes_betweenness_centrality_dispatch1::run( - g, - choose_param(get_param(params, vertex_centrality), - dummy_property_map()), - choose_param(get_param(params, edge_centrality), - dummy_property_map()), - choose_const_pmap(get_param(params, vertex_index), g, vertex_index), - get_param(params, edge_weight)); + typedef bgl_named_params< Param, Tag, Rest > named_params; + + typedef typename get_param_type< edge_weight_t, named_params >::type ew; + detail::graph::brandes_betweenness_centrality_dispatch1< ew >::run(g, + choose_param( + get_param(params, vertex_centrality), dummy_property_map()), + choose_param(get_param(params, edge_centrality), dummy_property_map()), + choose_const_pmap(get_param(params, vertex_index), g, vertex_index), + get_param(params, edge_weight)); } // disable_if is required to work around problem with MSVC 7.1 (it seems to not // get partial ordering getween this overload and the previous one correct) -template -typename disable_if, - void>::type -brandes_betweenness_centrality(const Graph& g, CentralityMap centrality - BOOST_GRAPH_ENABLE_IF_MODELS_PARM(Graph,vertex_list_graph_tag)) +template < typename Graph, typename CentralityMap > +typename disable_if< detail::graph::is_bgl_named_params< CentralityMap >, + void >::type +brandes_betweenness_centrality(const Graph& g, + CentralityMap centrality BOOST_GRAPH_ENABLE_IF_MODELS_PARM( + Graph, vertex_list_graph_tag)) { - detail::graph::brandes_betweenness_centrality_dispatch2( - g, centrality, dummy_property_map(), get(vertex_index, g)); + detail::graph::brandes_betweenness_centrality_dispatch2( + g, centrality, dummy_property_map(), get(vertex_index, g)); } -template -void -brandes_betweenness_centrality(const Graph& g, CentralityMap centrality, - EdgeCentralityMap edge_centrality_map - BOOST_GRAPH_ENABLE_IF_MODELS_PARM(Graph,vertex_list_graph_tag)) +template < typename Graph, typename CentralityMap, typename EdgeCentralityMap > +void brandes_betweenness_centrality(const Graph& g, CentralityMap centrality, + EdgeCentralityMap edge_centrality_map BOOST_GRAPH_ENABLE_IF_MODELS_PARM( + Graph, vertex_list_graph_tag)) { - detail::graph::brandes_betweenness_centrality_dispatch2( - g, centrality, edge_centrality_map, get(vertex_index, g)); + detail::graph::brandes_betweenness_centrality_dispatch2( + g, centrality, edge_centrality_map, get(vertex_index, g)); } /** @@ -568,47 +591,53 @@ brandes_betweenness_centrality(const Graph& g, CentralityMap centrality, * into "relative" centrality. The result is placed back into the * given centrality map. */ -template -void -relative_betweenness_centrality(const Graph& g, CentralityMap centrality) +template < typename Graph, typename CentralityMap > +void relative_betweenness_centrality(const Graph& g, CentralityMap centrality) { - typedef typename graph_traits::vertex_iterator vertex_iterator; - typedef typename property_traits::value_type centrality_type; - - typename graph_traits::vertices_size_type n = num_vertices(g); - centrality_type factor = centrality_type(2)/centrality_type(n*n - 3*n + 2); - vertex_iterator v, v_end; - for (boost::tie(v, v_end) = vertices(g); v != v_end; ++v) { - put(centrality, *v, factor * get(centrality, *v)); - } + typedef typename graph_traits< Graph >::vertex_iterator vertex_iterator; + typedef + typename property_traits< CentralityMap >::value_type centrality_type; + + typename graph_traits< Graph >::vertices_size_type n = num_vertices(g); + centrality_type factor + = centrality_type(2) / centrality_type(n * n - 3 * n + 2); + vertex_iterator v, v_end; + for (boost::tie(v, v_end) = vertices(g); v != v_end; ++v) + { + put(centrality, *v, factor * get(centrality, *v)); + } } // Compute the central point dominance of a graph. -template -typename property_traits::value_type -central_point_dominance(const Graph& g, CentralityMap centrality - BOOST_GRAPH_ENABLE_IF_MODELS_PARM(Graph,vertex_list_graph_tag)) +template < typename Graph, typename CentralityMap > +typename property_traits< CentralityMap >::value_type central_point_dominance( + const Graph& g, + CentralityMap centrality BOOST_GRAPH_ENABLE_IF_MODELS_PARM( + Graph, vertex_list_graph_tag)) { - using std::max; - - typedef typename graph_traits::vertex_iterator vertex_iterator; - typedef typename property_traits::value_type centrality_type; - - typename graph_traits::vertices_size_type n = num_vertices(g); - - // Find max centrality - centrality_type max_centrality(0); - vertex_iterator v, v_end; - for (boost::tie(v, v_end) = vertices(g); v != v_end; ++v) { - max_centrality = (max)(max_centrality, get(centrality, *v)); - } - - // Compute central point dominance - centrality_type sum(0); - for (boost::tie(v, v_end) = vertices(g); v != v_end; ++v) { - sum += (max_centrality - get(centrality, *v)); - } - return sum/(n-1); + using std::max; + + typedef typename graph_traits< Graph >::vertex_iterator vertex_iterator; + typedef + typename property_traits< CentralityMap >::value_type centrality_type; + + typename graph_traits< Graph >::vertices_size_type n = num_vertices(g); + + // Find max centrality + centrality_type max_centrality(0); + vertex_iterator v, v_end; + for (boost::tie(v, v_end) = vertices(g); v != v_end; ++v) + { + max_centrality = (max)(max_centrality, get(centrality, *v)); + } + + // Compute central point dominance + centrality_type sum(0); + for (boost::tie(v, v_end) = vertices(g); v != v_end; ++v) + { + sum += (max_centrality - get(centrality, *v)); + } + return sum / (n - 1); } } // end namespace boost diff --git a/include/boost/graph/biconnected_components.hpp b/include/boost/graph/biconnected_components.hpp index 1669f6952..9b70e0eb4 100644 --- a/include/boost/graph/biconnected_components.hpp +++ b/include/boost/graph/biconnected_components.hpp @@ -25,393 +25,416 @@ namespace boost { - namespace detail - { - template +namespace detail +{ + template < typename ComponentMap, typename DiscoverTimeMap, + typename LowPointMap, typename PredecessorMap, typename OutputIterator, + typename Stack, typename ArticulationVector, typename IndexMap, + typename DFSVisitor > struct biconnected_components_visitor : public dfs_visitor<> { - biconnected_components_visitor - (ComponentMap comp, std::size_t& c, - std::size_t& children_of_root, DiscoverTimeMap dtm, - std::size_t& dfs_time, LowPointMap lowpt, PredecessorMap pred, - OutputIterator out, Stack& S, - ArticulationVector& is_articulation_point, IndexMap index_map, - DFSVisitor vis) - : comp(comp), c(c), children_of_root(children_of_root), - dtm(dtm), dfs_time(dfs_time), lowpt(lowpt), - pred(pred), out(out), S(S), - is_articulation_point(is_articulation_point), - index_map(index_map), vis(vis) { } - - template - void initialize_vertex(const Vertex& u, Graph& g) - { - put(pred, u, u); - vis.initialize_vertex(u, g); - } - - template - void start_vertex(const Vertex& u, Graph& g) - { - children_of_root = 0; - vis.start_vertex(u, g); - } - - template - void discover_vertex(const Vertex& u, Graph& g) - { - put(dtm, u, ++dfs_time); - put(lowpt, u, get(dtm, u)); - vis.discover_vertex(u, g); - } - - template - void examine_edge(const Edge& e, Graph& g) - { - vis.examine_edge(e, g); - } - - template - void tree_edge(const Edge& e, Graph& g) - { - typename boost::graph_traits::vertex_descriptor src = source(e, g); - typename boost::graph_traits::vertex_descriptor tgt = target(e, g); - - S.push(e); - put(pred, tgt, src); - if ( get(pred, src) == src ) { - ++children_of_root; + biconnected_components_visitor(ComponentMap comp, std::size_t& c, + std::size_t& children_of_root, DiscoverTimeMap dtm, + std::size_t& dfs_time, LowPointMap lowpt, PredecessorMap pred, + OutputIterator out, Stack& S, + ArticulationVector& is_articulation_point, IndexMap index_map, + DFSVisitor vis) + : comp(comp) + , c(c) + , children_of_root(children_of_root) + , dtm(dtm) + , dfs_time(dfs_time) + , lowpt(lowpt) + , pred(pred) + , out(out) + , S(S) + , is_articulation_point(is_articulation_point) + , index_map(index_map) + , vis(vis) + { + } + + template < typename Vertex, typename Graph > + void initialize_vertex(const Vertex& u, Graph& g) + { + put(pred, u, u); + vis.initialize_vertex(u, g); + } + + template < typename Vertex, typename Graph > + void start_vertex(const Vertex& u, Graph& g) + { + children_of_root = 0; + vis.start_vertex(u, g); + } + + template < typename Vertex, typename Graph > + void discover_vertex(const Vertex& u, Graph& g) + { + put(dtm, u, ++dfs_time); + put(lowpt, u, get(dtm, u)); + vis.discover_vertex(u, g); } - vis.tree_edge(e, g); - } - - template - void back_edge(const Edge& e, Graph& g) - { - BOOST_USING_STD_MIN(); - - typename boost::graph_traits::vertex_descriptor src = source(e, g); - typename boost::graph_traits::vertex_descriptor tgt = target(e, g); - if ( tgt != get(pred, src) ) { - S.push(e); - put(lowpt, src, - min BOOST_PREVENT_MACRO_SUBSTITUTION(get(lowpt, src), - get(dtm, tgt))); + + template < typename Edge, typename Graph > + void examine_edge(const Edge& e, Graph& g) + { + vis.examine_edge(e, g); } - vis.back_edge(e, g); - } - - template - void forward_or_cross_edge(const Edge& e, Graph& g) - { - vis.forward_or_cross_edge(e, g); - } - - template - void finish_vertex(const Vertex& u, Graph& g) - { - BOOST_USING_STD_MIN(); - Vertex parent = get(pred, u); - if (parent == u) { // Root of tree is special - is_articulation_point[get(index_map, u)] = (children_of_root > 1); - } else { - put(lowpt, parent, - min BOOST_PREVENT_MACRO_SUBSTITUTION(get(lowpt, parent), - get(lowpt, u))); - if ( get(lowpt, u) >= get(dtm, parent) ) { - is_articulation_point[get(index_map, parent)] = true; - while ( get(dtm, source(S.top(), g)) >= get(dtm, u) ) { - put(comp, S.top(), c); - S.pop(); + + template < typename Edge, typename Graph > + void tree_edge(const Edge& e, Graph& g) + { + typename boost::graph_traits< Graph >::vertex_descriptor src + = source(e, g); + typename boost::graph_traits< Graph >::vertex_descriptor tgt + = target(e, g); + + S.push(e); + put(pred, tgt, src); + if (get(pred, src) == src) + { + ++children_of_root; } - BOOST_ASSERT (source(S.top(), g) == parent); - BOOST_ASSERT (target(S.top(), g) == u); - put(comp, S.top(), c); - S.pop(); - ++c; - } + vis.tree_edge(e, g); } - if ( is_articulation_point[get(index_map, u)] ) { - *out++ = u; + + template < typename Edge, typename Graph > + void back_edge(const Edge& e, Graph& g) + { + BOOST_USING_STD_MIN(); + + typename boost::graph_traits< Graph >::vertex_descriptor src + = source(e, g); + typename boost::graph_traits< Graph >::vertex_descriptor tgt + = target(e, g); + if (tgt != get(pred, src)) + { + S.push(e); + put(lowpt, src, + min BOOST_PREVENT_MACRO_SUBSTITUTION( + get(lowpt, src), get(dtm, tgt))); + } + vis.back_edge(e, g); } - vis.finish_vertex(u, g); - } - - ComponentMap comp; - std::size_t& c; - std::size_t& children_of_root; - DiscoverTimeMap dtm; - std::size_t& dfs_time; - LowPointMap lowpt; - PredecessorMap pred; - OutputIterator out; - Stack& S; - ArticulationVector& is_articulation_point; - IndexMap index_map; - DFSVisitor vis; + + template < typename Edge, typename Graph > + void forward_or_cross_edge(const Edge& e, Graph& g) + { + vis.forward_or_cross_edge(e, g); + } + + template < typename Vertex, typename Graph > + void finish_vertex(const Vertex& u, Graph& g) + { + BOOST_USING_STD_MIN(); + Vertex parent = get(pred, u); + if (parent == u) + { // Root of tree is special + is_articulation_point[get(index_map, u)] + = (children_of_root > 1); + } + else + { + put(lowpt, parent, + min BOOST_PREVENT_MACRO_SUBSTITUTION( + get(lowpt, parent), get(lowpt, u))); + if (get(lowpt, u) >= get(dtm, parent)) + { + is_articulation_point[get(index_map, parent)] = true; + while (get(dtm, source(S.top(), g)) >= get(dtm, u)) + { + put(comp, S.top(), c); + S.pop(); + } + BOOST_ASSERT(source(S.top(), g) == parent); + BOOST_ASSERT(target(S.top(), g) == u); + put(comp, S.top(), c); + S.pop(); + ++c; + } + } + if (is_articulation_point[get(index_map, u)]) + { + *out++ = u; + } + vis.finish_vertex(u, g); + } + + ComponentMap comp; + std::size_t& c; + std::size_t& children_of_root; + DiscoverTimeMap dtm; + std::size_t& dfs_time; + LowPointMap lowpt; + PredecessorMap pred; + OutputIterator out; + Stack& S; + ArticulationVector& is_articulation_point; + IndexMap index_map; + DFSVisitor vis; }; - template - std::pair - biconnected_components_impl(const Graph & g, ComponentMap comp, - OutputIterator out, VertexIndexMap index_map, DiscoverTimeMap dtm, - LowPointMap lowpt, PredecessorMap pred, DFSVisitor dfs_vis) - { - typedef typename graph_traits::vertex_descriptor vertex_t; - typedef typename graph_traits::edge_descriptor edge_t; - BOOST_CONCEPT_ASSERT(( VertexListGraphConcept )); - BOOST_CONCEPT_ASSERT(( IncidenceGraphConcept )); - BOOST_CONCEPT_ASSERT(( WritablePropertyMapConcept )); - BOOST_CONCEPT_ASSERT(( ReadWritePropertyMapConcept )); - BOOST_CONCEPT_ASSERT(( ReadWritePropertyMapConcept )); - BOOST_CONCEPT_ASSERT(( ReadWritePropertyMapConcept )); - - std::size_t num_components = 0; - std::size_t children_of_root; - std::size_t dfs_time = 0; - std::stack S; - std::vector is_articulation_point(num_vertices(g)); - - biconnected_components_visitor, - std::vector, VertexIndexMap, DFSVisitor> - vis(comp, num_components, children_of_root, dtm, dfs_time, - lowpt, pred, out, S, is_articulation_point, index_map, dfs_vis); - - depth_first_search(g, visitor(vis).vertex_index_map(index_map)); - - return std::pair(num_components, vis.out); - } - - template - struct bicomp_dispatch3 + typename PredecessorMap, typename DFSVisitor > + std::pair< std::size_t, OutputIterator > biconnected_components_impl( + const Graph& g, ComponentMap comp, OutputIterator out, + VertexIndexMap index_map, DiscoverTimeMap dtm, LowPointMap lowpt, + PredecessorMap pred, DFSVisitor dfs_vis) + { + typedef typename graph_traits< Graph >::vertex_descriptor vertex_t; + typedef typename graph_traits< Graph >::edge_descriptor edge_t; + BOOST_CONCEPT_ASSERT((VertexListGraphConcept< Graph >)); + BOOST_CONCEPT_ASSERT((IncidenceGraphConcept< Graph >)); + BOOST_CONCEPT_ASSERT( + (WritablePropertyMapConcept< ComponentMap, edge_t >)); + BOOST_CONCEPT_ASSERT( + (ReadWritePropertyMapConcept< DiscoverTimeMap, vertex_t >)); + BOOST_CONCEPT_ASSERT( + (ReadWritePropertyMapConcept< LowPointMap, vertex_t >)); + BOOST_CONCEPT_ASSERT( + (ReadWritePropertyMapConcept< PredecessorMap, vertex_t >)); + + std::size_t num_components = 0; + std::size_t children_of_root; + std::size_t dfs_time = 0; + std::stack< edge_t > S; + std::vector< char > is_articulation_point(num_vertices(g)); + + biconnected_components_visitor< ComponentMap, DiscoverTimeMap, + LowPointMap, PredecessorMap, OutputIterator, std::stack< edge_t >, + std::vector< char >, VertexIndexMap, DFSVisitor > + vis(comp, num_components, children_of_root, dtm, dfs_time, lowpt, + pred, out, S, is_articulation_point, index_map, dfs_vis); + + depth_first_search(g, visitor(vis).vertex_index_map(index_map)); + + return std::pair< std::size_t, OutputIterator >( + num_components, vis.out); + } + + template < typename PredecessorMap > struct bicomp_dispatch3 { - template - static std::pair apply (const Graph & g, - ComponentMap comp, OutputIterator out, VertexIndexMap index_map, - DiscoverTimeMap dtm, LowPointMap lowpt, - const bgl_named_params& params, PredecessorMap pred) - { - return biconnected_components_impl - (g, comp, out, index_map, dtm, lowpt, pred, - choose_param(get_param(params, graph_visitor), + template < typename Graph, typename ComponentMap, + typename OutputIterator, typename VertexIndexMap, + typename DiscoverTimeMap, typename LowPointMap, class P, class T, + class R > + static std::pair< std::size_t, OutputIterator > apply(const Graph& g, + ComponentMap comp, OutputIterator out, VertexIndexMap index_map, + DiscoverTimeMap dtm, LowPointMap lowpt, + const bgl_named_params< P, T, R >& params, PredecessorMap pred) + { + return biconnected_components_impl(g, comp, out, index_map, dtm, + lowpt, pred, + choose_param(get_param(params, graph_visitor), make_dfs_visitor(null_visitor()))); - } + } }; - - template <> - struct bicomp_dispatch3 + + template <> struct bicomp_dispatch3< param_not_found > { - template - static std::pair apply (const Graph & g, - ComponentMap comp, OutputIterator out, VertexIndexMap index_map, - DiscoverTimeMap dtm, LowPointMap lowpt, - const bgl_named_params& params, - param_not_found) - { - typedef typename graph_traits::vertex_descriptor vertex_t; - std::vector pred(num_vertices(g)); - vertex_t vert = graph_traits::null_vertex(); - - return biconnected_components_impl - (g, comp, out, index_map, dtm, lowpt, - make_iterator_property_map(pred.begin(), index_map, vert), - choose_param(get_param(params, graph_visitor), + template < typename Graph, typename ComponentMap, + typename OutputIterator, typename VertexIndexMap, + typename DiscoverTimeMap, typename LowPointMap, class P, class T, + class R > + static std::pair< std::size_t, OutputIterator > apply(const Graph& g, + ComponentMap comp, OutputIterator out, VertexIndexMap index_map, + DiscoverTimeMap dtm, LowPointMap lowpt, + const bgl_named_params< P, T, R >& params, param_not_found) + { + typedef typename graph_traits< Graph >::vertex_descriptor vertex_t; + std::vector< vertex_t > pred(num_vertices(g)); + vertex_t vert = graph_traits< Graph >::null_vertex(); + + return biconnected_components_impl(g, comp, out, index_map, dtm, + lowpt, + make_iterator_property_map(pred.begin(), index_map, vert), + choose_param(get_param(params, graph_visitor), make_dfs_visitor(null_visitor()))); - } + } }; - template - struct bicomp_dispatch2 + template < typename LowPointMap > struct bicomp_dispatch2 { - template - static std::pair apply (const Graph& g, - ComponentMap comp, OutputIterator out, VertexIndexMap index_map, - DiscoverTimeMap dtm, const bgl_named_params& params, - LowPointMap lowpt) - { - typedef typename get_param_type< vertex_predecessor_t, bgl_named_params >::type dispatch_type; - - return bicomp_dispatch3::apply - (g, comp, out, index_map, dtm, lowpt, params, - get_param(params, vertex_predecessor)); - } + template < typename Graph, typename ComponentMap, + typename OutputIterator, typename VertexIndexMap, + typename DiscoverTimeMap, typename P, typename T, typename R > + static std::pair< std::size_t, OutputIterator > apply(const Graph& g, + ComponentMap comp, OutputIterator out, VertexIndexMap index_map, + DiscoverTimeMap dtm, const bgl_named_params< P, T, R >& params, + LowPointMap lowpt) + { + typedef typename get_param_type< vertex_predecessor_t, + bgl_named_params< P, T, R > >::type dispatch_type; + + return bicomp_dispatch3< dispatch_type >::apply(g, comp, out, + index_map, dtm, lowpt, params, + get_param(params, vertex_predecessor)); + } }; - - template <> - struct bicomp_dispatch2 + template <> struct bicomp_dispatch2< param_not_found > { - template - static std::pair apply (const Graph& g, - ComponentMap comp, OutputIterator out, VertexIndexMap index_map, - DiscoverTimeMap dtm, const bgl_named_params& params, - param_not_found) - { - typedef typename graph_traits::vertices_size_type - vertices_size_type; - std::vector lowpt(num_vertices(g)); - vertices_size_type vst(0); - - typedef typename get_param_type< vertex_predecessor_t, bgl_named_params >::type dispatch_type; - - return bicomp_dispatch3::apply - (g, comp, out, index_map, dtm, - make_iterator_property_map(lowpt.begin(), index_map, vst), - params, get_param(params, vertex_predecessor)); - } + template < typename Graph, typename ComponentMap, + typename OutputIterator, typename VertexIndexMap, + typename DiscoverTimeMap, typename P, typename T, typename R > + static std::pair< std::size_t, OutputIterator > apply(const Graph& g, + ComponentMap comp, OutputIterator out, VertexIndexMap index_map, + DiscoverTimeMap dtm, const bgl_named_params< P, T, R >& params, + param_not_found) + { + typedef typename graph_traits< Graph >::vertices_size_type + vertices_size_type; + std::vector< vertices_size_type > lowpt(num_vertices(g)); + vertices_size_type vst(0); + + typedef typename get_param_type< vertex_predecessor_t, + bgl_named_params< P, T, R > >::type dispatch_type; + + return bicomp_dispatch3< dispatch_type >::apply(g, comp, out, + index_map, dtm, + make_iterator_property_map(lowpt.begin(), index_map, vst), + params, get_param(params, vertex_predecessor)); + } }; - template - struct bicomp_dispatch1 + template < typename DiscoverTimeMap > struct bicomp_dispatch1 { - template - static std::pair apply(const Graph& g, - ComponentMap comp, OutputIterator out, VertexIndexMap index_map, - const bgl_named_params& params, DiscoverTimeMap dtm) - { - typedef typename get_param_type< vertex_lowpoint_t, bgl_named_params >::type dispatch_type; - - return bicomp_dispatch2::apply - (g, comp, out, index_map, dtm, params, - get_param(params, vertex_lowpoint)); - } + template < typename Graph, typename ComponentMap, + typename OutputIterator, typename VertexIndexMap, class P, class T, + class R > + static std::pair< std::size_t, OutputIterator > apply(const Graph& g, + ComponentMap comp, OutputIterator out, VertexIndexMap index_map, + const bgl_named_params< P, T, R >& params, DiscoverTimeMap dtm) + { + typedef typename get_param_type< vertex_lowpoint_t, + bgl_named_params< P, T, R > >::type dispatch_type; + + return bicomp_dispatch2< dispatch_type >::apply(g, comp, out, + index_map, dtm, params, get_param(params, vertex_lowpoint)); + } }; - template <> - struct bicomp_dispatch1 + template <> struct bicomp_dispatch1< param_not_found > { - template - static std::pair apply(const Graph& g, - ComponentMap comp, OutputIterator out, VertexIndexMap index_map, - const bgl_named_params& params, param_not_found) - { - typedef typename graph_traits::vertices_size_type - vertices_size_type; - std::vector discover_time(num_vertices(g)); - vertices_size_type vst(0); - - typedef typename get_param_type< vertex_lowpoint_t, bgl_named_params >::type dispatch_type; - - return bicomp_dispatch2::apply - (g, comp, out, index_map, - make_iterator_property_map(discover_time.begin(), index_map, vst), - params, get_param(params, vertex_lowpoint)); - } + template < typename Graph, typename ComponentMap, + typename OutputIterator, typename VertexIndexMap, class P, class T, + class R > + static std::pair< std::size_t, OutputIterator > apply(const Graph& g, + ComponentMap comp, OutputIterator out, VertexIndexMap index_map, + const bgl_named_params< P, T, R >& params, param_not_found) + { + typedef typename graph_traits< Graph >::vertices_size_type + vertices_size_type; + std::vector< vertices_size_type > discover_time(num_vertices(g)); + vertices_size_type vst(0); + + typedef typename get_param_type< vertex_lowpoint_t, + bgl_named_params< P, T, R > >::type dispatch_type; + + return bicomp_dispatch2< dispatch_type >::apply(g, comp, out, + index_map, + make_iterator_property_map( + discover_time.begin(), index_map, vst), + params, get_param(params, vertex_lowpoint)); + } }; - } +} - template - std::pair - biconnected_components(const Graph& g, ComponentMap comp, - OutputIterator out, DiscoverTimeMap dtm, LowPointMap lowpt) - { +template < typename Graph, typename ComponentMap, typename OutputIterator, + typename DiscoverTimeMap, typename LowPointMap > +std::pair< std::size_t, OutputIterator > biconnected_components(const Graph& g, + ComponentMap comp, OutputIterator out, DiscoverTimeMap dtm, + LowPointMap lowpt) +{ typedef param_not_found dispatch_type; - return detail::bicomp_dispatch3::apply - (g, comp, out, - get(vertex_index, g), - dtm, lowpt, - bgl_named_params(0), - param_not_found()); - } - - template - std::pair - biconnected_components(const Graph& g, ComponentMap comp, OutputIterator out, - const bgl_named_params& params) - { - typedef typename get_param_type< vertex_discover_time_t, bgl_named_params >::type dispatch_type; - - return detail::bicomp_dispatch1::apply(g, comp, out, - choose_const_pmap(get_param(params, vertex_index), g, vertex_index), + return detail::bicomp_dispatch3< dispatch_type >::apply(g, comp, out, + get(vertex_index, g), dtm, lowpt, + bgl_named_params< int, buffer_param_t >(0), param_not_found()); +} + +template < typename Graph, typename ComponentMap, typename OutputIterator, + typename P, typename T, typename R > +std::pair< std::size_t, OutputIterator > biconnected_components(const Graph& g, + ComponentMap comp, OutputIterator out, + const bgl_named_params< P, T, R >& params) +{ + typedef typename get_param_type< vertex_discover_time_t, + bgl_named_params< P, T, R > >::type dispatch_type; + + return detail::bicomp_dispatch1< dispatch_type >::apply(g, comp, out, + choose_const_pmap(get_param(params, vertex_index), g, vertex_index), params, get_param(params, vertex_discover_time)); - } +} - template < typename Graph, typename ComponentMap, typename OutputIterator> - std::pair - biconnected_components(const Graph& g, ComponentMap comp, OutputIterator out) - { - return biconnected_components(g, comp, out, - bgl_named_params(0)); - } +template < typename Graph, typename ComponentMap, typename OutputIterator > +std::pair< std::size_t, OutputIterator > biconnected_components( + const Graph& g, ComponentMap comp, OutputIterator out) +{ + return biconnected_components( + g, comp, out, bgl_named_params< int, buffer_param_t >(0)); +} - namespace graph_detail { +namespace graph_detail +{ struct dummy_output_iterator { - typedef std::output_iterator_tag iterator_category; - typedef void value_type; - typedef void pointer; - typedef void difference_type; - - struct reference { - template - reference& operator=(const T&) { return *this; } - }; - - reference operator*() const { return reference(); } - dummy_output_iterator& operator++() { return *this; } - dummy_output_iterator operator++(int) { return *this; } + typedef std::output_iterator_tag iterator_category; + typedef void value_type; + typedef void pointer; + typedef void difference_type; + + struct reference + { + template < typename T > reference& operator=(const T&) + { + return *this; + } + }; + + reference operator*() const { return reference(); } + dummy_output_iterator& operator++() { return *this; } + dummy_output_iterator operator++(int) { return *this; } }; - } // end namespace graph_detail - - template - std::size_t - biconnected_components(const Graph& g, ComponentMap comp, - const bgl_named_params& params) - { - return biconnected_components(g, comp, - graph_detail::dummy_output_iterator(), params).first; - } - - template - std::size_t - biconnected_components(const Graph& g, ComponentMap comp) - { - return biconnected_components(g, comp, - graph_detail::dummy_output_iterator()).first; - } - - template - OutputIterator - articulation_points(const Graph& g, OutputIterator out, - const bgl_named_params& params) - { - return biconnected_components(g, dummy_property_map(), out, - params).second; - } - - template - OutputIterator - articulation_points(const Graph& g, OutputIterator out) - { - return biconnected_components(g, dummy_property_map(), out, - bgl_named_params(0)).second; - } - -} // namespace boost - -#endif /* BOOST_GRAPH_BICONNECTED_COMPONENTS_HPP */ +} // end namespace graph_detail + +template < typename Graph, typename ComponentMap, typename P, typename T, + typename R > +std::size_t biconnected_components(const Graph& g, ComponentMap comp, + const bgl_named_params< P, T, R >& params) +{ + return biconnected_components( + g, comp, graph_detail::dummy_output_iterator(), params) + .first; +} + +template < typename Graph, typename ComponentMap > +std::size_t biconnected_components(const Graph& g, ComponentMap comp) +{ + return biconnected_components( + g, comp, graph_detail::dummy_output_iterator()) + .first; +} + +template < typename Graph, typename OutputIterator, typename P, typename T, + typename R > +OutputIterator articulation_points(const Graph& g, OutputIterator out, + const bgl_named_params< P, T, R >& params) +{ + return biconnected_components(g, dummy_property_map(), out, params).second; +} + +template < typename Graph, typename OutputIterator > +OutputIterator articulation_points(const Graph& g, OutputIterator out) +{ + return biconnected_components(g, dummy_property_map(), out, + bgl_named_params< int, buffer_param_t >(0)) + .second; +} + +} // namespace boost + +#endif /* BOOST_GRAPH_BICONNECTED_COMPONENTS_HPP */ diff --git a/include/boost/graph/bipartite.hpp b/include/boost/graph/bipartite.hpp index 6e2e70739..549d027d3 100644 --- a/include/boost/graph/bipartite.hpp +++ b/include/boost/graph/bipartite.hpp @@ -22,63 +22,59 @@ #include #include -namespace boost { +namespace boost +{ - namespace detail { +namespace detail +{ /** * The bipartite_visitor_error is thrown if an edge cannot be colored. * The witnesses are the edges incident vertices. */ - template - struct BOOST_SYMBOL_VISIBLE bipartite_visitor_error: std::exception + template < typename Vertex > + struct BOOST_SYMBOL_VISIBLE bipartite_visitor_error : std::exception { - std::pair witnesses; + std::pair< Vertex, Vertex > witnesses; - bipartite_visitor_error (Vertex a, Vertex b) : - witnesses (a, b) - { + bipartite_visitor_error(Vertex a, Vertex b) : witnesses(a, b) {} - } - - const char* what () const throw () - { - return "Graph is not bipartite."; - } + const char* what() const throw() { return "Graph is not bipartite."; } }; /** * Functor which colors edges to be non-monochromatic. */ - template - struct bipartition_colorize + template < typename PartitionMap > struct bipartition_colorize { - typedef on_tree_edge event_filter; - - bipartition_colorize (PartitionMap partition_map) : - partition_map_ (partition_map) - { + typedef on_tree_edge event_filter; - } - - template - void operator() (Edge e, const Graph& g) - { - typedef typename graph_traits ::vertex_descriptor vertex_descriptor_t; - typedef color_traits ::value_type> color_traits; + bipartition_colorize(PartitionMap partition_map) + : partition_map_(partition_map) + { + } - vertex_descriptor_t source_vertex = source (e, g); - vertex_descriptor_t target_vertex = target (e, g); - if (get (partition_map_, source_vertex) == color_traits::white ()) - put (partition_map_, target_vertex, color_traits::black ()); - else - put (partition_map_, target_vertex, color_traits::white ()); - } + template < typename Edge, typename Graph > + void operator()(Edge e, const Graph& g) + { + typedef typename graph_traits< Graph >::vertex_descriptor + vertex_descriptor_t; + typedef color_traits< + typename property_traits< PartitionMap >::value_type > + color_traits; + + vertex_descriptor_t source_vertex = source(e, g); + vertex_descriptor_t target_vertex = target(e, g); + if (get(partition_map_, source_vertex) == color_traits::white()) + put(partition_map_, target_vertex, color_traits::black()); + else + put(partition_map_, target_vertex, color_traits::white()); + } private: - PartitionMap partition_map_; + PartitionMap partition_map_; }; /** @@ -89,40 +85,42 @@ namespace boost { * @return The functor. */ - template - inline bipartition_colorize colorize_bipartition (PartitionMap partition_map) + template < typename PartitionMap > + inline bipartition_colorize< PartitionMap > colorize_bipartition( + PartitionMap partition_map) { - return bipartition_colorize (partition_map); + return bipartition_colorize< PartitionMap >(partition_map); } /** * Functor which tests an edge to be monochromatic. */ - template - struct bipartition_check + template < typename PartitionMap > struct bipartition_check { - typedef on_back_edge event_filter; - - bipartition_check (PartitionMap partition_map) : - partition_map_ (partition_map) - { + typedef on_back_edge event_filter; - } - - template - void operator() (Edge e, const Graph& g) - { - typedef typename graph_traits ::vertex_descriptor vertex_descriptor_t; + bipartition_check(PartitionMap partition_map) + : partition_map_(partition_map) + { + } - vertex_descriptor_t source_vertex = source (e, g); - vertex_descriptor_t target_vertex = target (e, g); - if (get (partition_map_, source_vertex) == get (partition_map_, target_vertex)) - throw bipartite_visitor_error (source_vertex, target_vertex); - } + template < typename Edge, typename Graph > + void operator()(Edge e, const Graph& g) + { + typedef typename graph_traits< Graph >::vertex_descriptor + vertex_descriptor_t; + + vertex_descriptor_t source_vertex = source(e, g); + vertex_descriptor_t target_vertex = target(e, g); + if (get(partition_map_, source_vertex) + == get(partition_map_, target_vertex)) + throw bipartite_visitor_error< vertex_descriptor_t >( + source_vertex, target_vertex); + } private: - PartitionMap partition_map_; + PartitionMap partition_map_; }; /** @@ -133,249 +131,274 @@ namespace boost { * @return The functor. */ - template - inline bipartition_check check_bipartition (PartitionMap partition_map) + template < typename PartitionMap > + inline bipartition_check< PartitionMap > check_bipartition( + PartitionMap partition_map) { - return bipartition_check (partition_map); + return bipartition_check< PartitionMap >(partition_map); } /** * Find the beginning of a common suffix of two sequences - * - * @param sequence1 Pair of bidirectional iterators defining the first sequence. - * @param sequence2 Pair of bidirectional iterators defining the second sequence. + * + * @param sequence1 Pair of bidirectional iterators defining the first + * sequence. + * @param sequence2 Pair of bidirectional iterators defining the second + * sequence. * @return Pair of iterators pointing to the beginning of the common suffix. */ - template - inline std::pair reverse_mismatch (std::pair < - BiDirectionalIterator1, BiDirectionalIterator1> sequence1, std::pair sequence2) + template < typename BiDirectionalIterator1, + typename BiDirectionalIterator2 > + inline std::pair< BiDirectionalIterator1, BiDirectionalIterator2 > + reverse_mismatch( + std::pair< BiDirectionalIterator1, BiDirectionalIterator1 > sequence1, + std::pair< BiDirectionalIterator2, BiDirectionalIterator2 > sequence2) { - if (sequence1.first == sequence1.second || sequence2.first == sequence2.second) - return std::make_pair (sequence1.first, sequence2.first); + if (sequence1.first == sequence1.second + || sequence2.first == sequence2.second) + return std::make_pair(sequence1.first, sequence2.first); - BiDirectionalIterator1 iter1 = sequence1.second; - BiDirectionalIterator2 iter2 = sequence2.second; + BiDirectionalIterator1 iter1 = sequence1.second; + BiDirectionalIterator2 iter2 = sequence2.second; - while (true) - { - --iter1; - --iter2; - if (*iter1 != *iter2) + while (true) { - ++iter1; - ++iter2; - break; + --iter1; + --iter2; + if (*iter1 != *iter2) + { + ++iter1; + ++iter2; + break; + } + if (iter1 == sequence1.first) + break; + if (iter2 == sequence2.first) + break; } - if (iter1 == sequence1.first) - break; - if (iter2 == sequence2.first) - break; - } - return std::make_pair (iter1, iter2); + return std::make_pair(iter1, iter2); } - } - - /** - * Checks a given graph for bipartiteness and fills the given color map with - * white and black according to the bipartition. If the graph is not - * bipartite, the contents of the color map are undefined. Runs in linear - * time in the size of the graph, if access to the property maps is in - * constant time. - * - * @param graph The given graph. - * @param index_map An index map associating vertices with an index. - * @param partition_map A color map to fill with the bipartition. - * @return true if and only if the given graph is bipartite. - */ - - template - bool is_bipartite (const Graph& graph, const IndexMap index_map, PartitionMap partition_map) - { +} + +/** + * Checks a given graph for bipartiteness and fills the given color map with + * white and black according to the bipartition. If the graph is not + * bipartite, the contents of the color map are undefined. Runs in linear + * time in the size of the graph, if access to the property maps is in + * constant time. + * + * @param graph The given graph. + * @param index_map An index map associating vertices with an index. + * @param partition_map A color map to fill with the bipartition. + * @return true if and only if the given graph is bipartite. + */ + +template < typename Graph, typename IndexMap, typename PartitionMap > +bool is_bipartite( + const Graph& graph, const IndexMap index_map, PartitionMap partition_map) +{ /// General types and variables - typedef typename property_traits ::value_type partition_color_t; - typedef typename graph_traits ::vertex_descriptor vertex_descriptor_t; + typedef + typename property_traits< PartitionMap >::value_type partition_color_t; + typedef + typename graph_traits< Graph >::vertex_descriptor vertex_descriptor_t; /// Declare dfs visitor // detail::empty_recorder recorder; - // typedef detail::bipartite_visitor dfs_visitor_t; - // dfs_visitor_t dfs_visitor (partition_map, recorder); - + // typedef detail::bipartite_visitor dfs_visitor_t; dfs_visitor_t dfs_visitor + // (partition_map, recorder); /// Call dfs try { - depth_first_search (graph, vertex_index_map (index_map).visitor (make_dfs_visitor (std::make_pair ( - detail::colorize_bipartition (partition_map), std::make_pair (detail::check_bipartition (partition_map), - put_property (partition_map, color_traits ::white (), on_start_vertex ())))))); + depth_first_search(graph, + vertex_index_map(index_map).visitor(make_dfs_visitor( + std::make_pair(detail::colorize_bipartition(partition_map), + std::make_pair(detail::check_bipartition(partition_map), + put_property(partition_map, + color_traits< partition_color_t >::white(), + on_start_vertex())))))); } - catch (const detail::bipartite_visitor_error &) + catch (const detail::bipartite_visitor_error< vertex_descriptor_t >&) { - return false; + return false; } return true; - } - - /** - * Checks a given graph for bipartiteness. - * - * @param graph The given graph. - * @param index_map An index map associating vertices with an index. - * @return true if and only if the given graph is bipartite. - */ - - template - bool is_bipartite (const Graph& graph, const IndexMap index_map) - { - typedef one_bit_color_map partition_map_t; - partition_map_t partition_map (num_vertices (graph), index_map); - - return is_bipartite (graph, index_map, partition_map); - } - - /** - * Checks a given graph for bipartiteness. The graph must - * have an internal vertex_index property. Runs in linear time in the - * size of the graph, if access to the property maps is in constant time. - * - * @param graph The given graph. - * @return true if and only if the given graph is bipartite. - */ - - template - bool is_bipartite (const Graph& graph) - { - return is_bipartite (graph, get (vertex_index, graph)); - } - - /** - * Checks a given graph for bipartiteness and fills a given color map with - * white and black according to the bipartition. If the graph is not - * bipartite, a sequence of vertices, producing an odd-cycle, is written to - * the output iterator. The final iterator value is returned. Runs in linear - * time in the size of the graph, if access to the property maps is in - * constant time. - * - * @param graph The given graph. - * @param index_map An index map associating vertices with an index. - * @param partition_map A color map to fill with the bipartition. - * @param result An iterator to write the odd-cycle vertices to. - * @return The final iterator value after writing. - */ - - template - OutputIterator find_odd_cycle (const Graph& graph, const IndexMap index_map, PartitionMap partition_map, - OutputIterator result) - { +} + +/** + * Checks a given graph for bipartiteness. + * + * @param graph The given graph. + * @param index_map An index map associating vertices with an index. + * @return true if and only if the given graph is bipartite. + */ + +template < typename Graph, typename IndexMap > +bool is_bipartite(const Graph& graph, const IndexMap index_map) +{ + typedef one_bit_color_map< IndexMap > partition_map_t; + partition_map_t partition_map(num_vertices(graph), index_map); + + return is_bipartite(graph, index_map, partition_map); +} + +/** + * Checks a given graph for bipartiteness. The graph must + * have an internal vertex_index property. Runs in linear time in the + * size of the graph, if access to the property maps is in constant time. + * + * @param graph The given graph. + * @return true if and only if the given graph is bipartite. + */ + +template < typename Graph > bool is_bipartite(const Graph& graph) +{ + return is_bipartite(graph, get(vertex_index, graph)); +} + +/** + * Checks a given graph for bipartiteness and fills a given color map with + * white and black according to the bipartition. If the graph is not + * bipartite, a sequence of vertices, producing an odd-cycle, is written to + * the output iterator. The final iterator value is returned. Runs in linear + * time in the size of the graph, if access to the property maps is in + * constant time. + * + * @param graph The given graph. + * @param index_map An index map associating vertices with an index. + * @param partition_map A color map to fill with the bipartition. + * @param result An iterator to write the odd-cycle vertices to. + * @return The final iterator value after writing. + */ + +template < typename Graph, typename IndexMap, typename PartitionMap, + typename OutputIterator > +OutputIterator find_odd_cycle(const Graph& graph, const IndexMap index_map, + PartitionMap partition_map, OutputIterator result) +{ /// General types and variables - typedef typename property_traits ::value_type partition_color_t; - typedef typename graph_traits ::vertex_descriptor vertex_descriptor_t; - typedef typename graph_traits ::vertex_iterator vertex_iterator_t; + typedef + typename property_traits< PartitionMap >::value_type partition_color_t; + typedef + typename graph_traits< Graph >::vertex_descriptor vertex_descriptor_t; + typedef typename graph_traits< Graph >::vertex_iterator vertex_iterator_t; vertex_iterator_t vertex_iter, vertex_end; /// Declare predecessor map - typedef std::vector predecessors_t; - typedef iterator_property_map predecessor_map_t; + typedef std::vector< vertex_descriptor_t > predecessors_t; + typedef iterator_property_map< typename predecessors_t::iterator, IndexMap, + vertex_descriptor_t, vertex_descriptor_t& > + predecessor_map_t; - predecessors_t predecessors (num_vertices (graph), graph_traits ::null_vertex ()); - predecessor_map_t predecessor_map (predecessors.begin (), index_map); + predecessors_t predecessors( + num_vertices(graph), graph_traits< Graph >::null_vertex()); + predecessor_map_t predecessor_map(predecessors.begin(), index_map); /// Initialize predecessor map - for (boost::tie (vertex_iter, vertex_end) = vertices (graph); vertex_iter != vertex_end; ++vertex_iter) + for (boost::tie(vertex_iter, vertex_end) = vertices(graph); + vertex_iter != vertex_end; ++vertex_iter) { - put (predecessor_map, *vertex_iter, *vertex_iter); + put(predecessor_map, *vertex_iter, *vertex_iter); } /// Call dfs try { - depth_first_search (graph, vertex_index_map (index_map).visitor (make_dfs_visitor (std::make_pair ( - detail::colorize_bipartition (partition_map), std::make_pair (detail::check_bipartition (partition_map), - std::make_pair (put_property (partition_map, color_traits ::white (), - on_start_vertex ()), record_predecessors (predecessor_map, on_tree_edge ()))))))); + depth_first_search(graph, + vertex_index_map(index_map).visitor(make_dfs_visitor( + std::make_pair(detail::colorize_bipartition(partition_map), + std::make_pair(detail::check_bipartition(partition_map), + std::make_pair( + put_property(partition_map, + color_traits< partition_color_t >::white(), + on_start_vertex()), + record_predecessors( + predecessor_map, on_tree_edge()))))))); } - catch (const detail::bipartite_visitor_error & error) + catch (const detail::bipartite_visitor_error< vertex_descriptor_t >& error) { - typedef std::vector path_t; - - path_t path1, path2; - vertex_descriptor_t next, current; - - /// First path - next = error.witnesses.first; - do - { - current = next; - path1.push_back (current); - next = predecessor_map[current]; - } - while (current != next); - - /// Second path - next = error.witnesses.second; - do - { - current = next; - path2.push_back (current); - next = predecessor_map[current]; - } - while (current != next); - - /// Find beginning of common suffix - std::pair mismatch = detail::reverse_mismatch ( - std::make_pair (path1.begin (), path1.end ()), std::make_pair (path2.begin (), path2.end ())); - - /// Copy the odd-length cycle - result = std::copy (path1.begin (), mismatch.first + 1, result); - return std::reverse_copy (path2.begin (), mismatch.second, result); + typedef std::vector< vertex_descriptor_t > path_t; + + path_t path1, path2; + vertex_descriptor_t next, current; + + /// First path + next = error.witnesses.first; + do + { + current = next; + path1.push_back(current); + next = predecessor_map[current]; + } while (current != next); + + /// Second path + next = error.witnesses.second; + do + { + current = next; + path2.push_back(current); + next = predecessor_map[current]; + } while (current != next); + + /// Find beginning of common suffix + std::pair< typename path_t::iterator, typename path_t::iterator > + mismatch = detail::reverse_mismatch( + std::make_pair(path1.begin(), path1.end()), + std::make_pair(path2.begin(), path2.end())); + + /// Copy the odd-length cycle + result = std::copy(path1.begin(), mismatch.first + 1, result); + return std::reverse_copy(path2.begin(), mismatch.second, result); } return result; - } - - /** - * Checks a given graph for bipartiteness. If the graph is not bipartite, a - * sequence of vertices, producing an odd-cycle, is written to the output - * iterator. The final iterator value is returned. Runs in linear time in the - * size of the graph, if access to the property maps is in constant time. - * - * @param graph The given graph. - * @param index_map An index map associating vertices with an index. - * @param result An iterator to write the odd-cycle vertices to. - * @return The final iterator value after writing. - */ - - template - OutputIterator find_odd_cycle (const Graph& graph, const IndexMap index_map, OutputIterator result) - { - typedef one_bit_color_map partition_map_t; - partition_map_t partition_map (num_vertices (graph), index_map); - - return find_odd_cycle (graph, index_map, partition_map, result); - } - - /** - * Checks a given graph for bipartiteness. If the graph is not bipartite, a - * sequence of vertices, producing an odd-cycle, is written to the output - * iterator. The final iterator value is returned. The graph must have an - * internal vertex_index property. Runs in linear time in the size of the - * graph, if access to the property maps is in constant time. - * - * @param graph The given graph. - * @param result An iterator to write the odd-cycle vertices to. - * @return The final iterator value after writing. - */ - - template - OutputIterator find_odd_cycle (const Graph& graph, OutputIterator result) - { - return find_odd_cycle (graph, get (vertex_index, graph), result); - } +} + +/** + * Checks a given graph for bipartiteness. If the graph is not bipartite, a + * sequence of vertices, producing an odd-cycle, is written to the output + * iterator. The final iterator value is returned. Runs in linear time in the + * size of the graph, if access to the property maps is in constant time. + * + * @param graph The given graph. + * @param index_map An index map associating vertices with an index. + * @param result An iterator to write the odd-cycle vertices to. + * @return The final iterator value after writing. + */ + +template < typename Graph, typename IndexMap, typename OutputIterator > +OutputIterator find_odd_cycle( + const Graph& graph, const IndexMap index_map, OutputIterator result) +{ + typedef one_bit_color_map< IndexMap > partition_map_t; + partition_map_t partition_map(num_vertices(graph), index_map); + + return find_odd_cycle(graph, index_map, partition_map, result); +} + +/** + * Checks a given graph for bipartiteness. If the graph is not bipartite, a + * sequence of vertices, producing an odd-cycle, is written to the output + * iterator. The final iterator value is returned. The graph must have an + * internal vertex_index property. Runs in linear time in the size of the + * graph, if access to the property maps is in constant time. + * + * @param graph The given graph. + * @param result An iterator to write the odd-cycle vertices to. + * @return The final iterator value after writing. + */ + +template < typename Graph, typename OutputIterator > +OutputIterator find_odd_cycle(const Graph& graph, OutputIterator result) +{ + return find_odd_cycle(graph, get(vertex_index, graph), result); +} } #endif /// BOOST_GRAPH_BIPARTITE_HPP diff --git a/include/boost/graph/boyer_myrvold_planar_test.hpp b/include/boost/graph/boyer_myrvold_planar_test.hpp index 111c5ac4a..34a476b50 100644 --- a/include/boost/graph/boyer_myrvold_planar_test.hpp +++ b/include/boost/graph/boyer_myrvold_planar_test.hpp @@ -14,328 +14,248 @@ #include #include - namespace boost { - struct no_kuratowski_subgraph_isolation {}; - struct no_planar_embedding {}; +struct no_kuratowski_subgraph_isolation +{ +}; +struct no_planar_embedding +{ +}; + +namespace boyer_myrvold_params +{ - namespace boyer_myrvold_params - { - BOOST_PARAMETER_KEYWORD(tag, graph) BOOST_PARAMETER_KEYWORD(tag, embedding) BOOST_PARAMETER_KEYWORD(tag, kuratowski_subgraph) BOOST_PARAMETER_KEYWORD(tag, vertex_index_map) BOOST_PARAMETER_KEYWORD(tag, edge_index_map) - - typedef parameter::parameters< parameter::required, - tag::embedding, - tag::kuratowski_subgraph, - tag::vertex_index_map, - tag::edge_index_map - > boyer_myrvold_params_t; - + + typedef parameter::parameters< parameter::required< tag::graph >, + tag::embedding, tag::kuratowski_subgraph, tag::vertex_index_map, + tag::edge_index_map > + boyer_myrvold_params_t; + namespace core { - - template - bool dispatched_boyer_myrvold(ArgumentPack const& args, - mpl::true_, - mpl::true_ - ) - { - //Dispatch for no planar embedding, no kuratowski subgraph isolation - - typedef typename remove_const< - typename parameter::value_type::type - >::type graph_t; - - typedef typename property_map< - graph_t, - vertex_index_t - >::const_type vertex_default_index_map_t; - - typedef typename parameter::value_type< - ArgumentPack, - tag::vertex_index_map, - vertex_default_index_map_t - >::type vertex_index_map_t; - - graph_t const& g = args[graph]; - vertex_default_index_map_t v_d_map = get(vertex_index, g); - vertex_index_map_t v_i_map = args[vertex_index_map | v_d_map]; - boyer_myrvold_impl - - planarity_tester(g, v_i_map); - - return planarity_tester.is_planar() ? true : false; - } - - - - template - bool dispatched_boyer_myrvold(ArgumentPack const& args, - mpl::true_, - mpl::false_ - ) - { - //Dispatch for no planar embedding, kuratowski subgraph isolation - typedef typename remove_const< - typename parameter::value_type::type - >::type graph_t; - - typedef typename property_map< - graph_t, - vertex_index_t - >::const_type vertex_default_index_map_t; - - typedef typename parameter::value_type< - ArgumentPack, - tag::vertex_index_map, - vertex_default_index_map_t - >::type vertex_index_map_t; - - typedef typename property_map< - graph_t, - edge_index_t - >::const_type edge_default_index_map_t; - - typedef typename parameter::value_type< - ArgumentPack, - tag::edge_index_map, - edge_default_index_map_t - >::type edge_index_map_t; - - graph_t const& g = args[graph]; - vertex_default_index_map_t v_d_map = get(vertex_index, g); - vertex_index_map_t v_i_map = args[vertex_index_map | v_d_map]; - edge_default_index_map_t e_d_map = get(edge_index, g); - edge_index_map_t e_i_map = args[edge_index_map | e_d_map]; - boyer_myrvold_impl - - planarity_tester(g, v_i_map); - - if (planarity_tester.is_planar()) - return true; - else - { - planarity_tester.extract_kuratowski_subgraph - (args[kuratowski_subgraph], e_i_map); - return false; - } - } - - - - - template - bool dispatched_boyer_myrvold(ArgumentPack const& args, - mpl::false_, - mpl::true_ - ) - { - //Dispatch for planar embedding, no kuratowski subgraph isolation - typedef typename remove_const< - typename parameter::value_type::type - >::type graph_t; - - typedef typename property_map< - graph_t, - vertex_index_t - >::const_type vertex_default_index_map_t; - - typedef typename parameter::value_type< - ArgumentPack, - tag::vertex_index_map, - vertex_default_index_map_t - >::type vertex_index_map_t; - - graph_t const& g = args[graph]; - vertex_default_index_map_t v_d_map = get(vertex_index, g); - vertex_index_map_t v_i_map = args[vertex_index_map | v_d_map]; - boyer_myrvold_impl - + bool dispatched_boyer_myrvold( + ArgumentPack const& args, mpl::true_, mpl::true_) + { + // Dispatch for no planar embedding, no kuratowski subgraph + // isolation + + typedef typename remove_const< typename parameter::value_type< + ArgumentPack, tag::graph >::type >::type graph_t; + + typedef typename property_map< graph_t, vertex_index_t >::const_type + vertex_default_index_map_t; + + typedef typename parameter::value_type< ArgumentPack, + tag::vertex_index_map, vertex_default_index_map_t >::type + vertex_index_map_t; + + graph_t const& g = args[graph]; + vertex_default_index_map_t v_d_map = get(vertex_index, g); + vertex_index_map_t v_i_map = args[vertex_index_map | v_d_map]; + boyer_myrvold_impl< graph_t, vertex_index_map_t, + graph::detail::no_old_handles, graph::detail::no_embedding > + planarity_tester(g, v_i_map); + + return planarity_tester.is_planar() ? true : false; + } + + template < typename ArgumentPack > + bool dispatched_boyer_myrvold( + ArgumentPack const& args, mpl::true_, mpl::false_) + { + // Dispatch for no planar embedding, kuratowski subgraph isolation + typedef typename remove_const< typename parameter::value_type< + ArgumentPack, tag::graph >::type >::type graph_t; + + typedef typename property_map< graph_t, vertex_index_t >::const_type + vertex_default_index_map_t; + + typedef typename parameter::value_type< ArgumentPack, + tag::vertex_index_map, vertex_default_index_map_t >::type + vertex_index_map_t; + + typedef typename property_map< graph_t, edge_index_t >::const_type + edge_default_index_map_t; + + typedef typename parameter::value_type< ArgumentPack, + tag::edge_index_map, edge_default_index_map_t >::type + edge_index_map_t; + + graph_t const& g = args[graph]; + vertex_default_index_map_t v_d_map = get(vertex_index, g); + vertex_index_map_t v_i_map = args[vertex_index_map | v_d_map]; + edge_default_index_map_t e_d_map = get(edge_index, g); + edge_index_map_t e_i_map = args[edge_index_map | e_d_map]; + boyer_myrvold_impl< graph_t, vertex_index_map_t, + graph::detail::store_old_handles, graph::detail::no_embedding > + planarity_tester(g, v_i_map); + + if (planarity_tester.is_planar()) + return true; + else + { + planarity_tester.extract_kuratowski_subgraph( + args[kuratowski_subgraph], e_i_map); + return false; + } + } + + template < typename ArgumentPack > + bool dispatched_boyer_myrvold( + ArgumentPack const& args, mpl::false_, mpl::true_) + { + // Dispatch for planar embedding, no kuratowski subgraph isolation + typedef typename remove_const< typename parameter::value_type< + ArgumentPack, tag::graph >::type >::type graph_t; + + typedef typename property_map< graph_t, vertex_index_t >::const_type + vertex_default_index_map_t; + + typedef typename parameter::value_type< ArgumentPack, + tag::vertex_index_map, vertex_default_index_map_t >::type + vertex_index_map_t; + + graph_t const& g = args[graph]; + vertex_default_index_map_t v_d_map = get(vertex_index, g); + vertex_index_map_t v_i_map = args[vertex_index_map | v_d_map]; + boyer_myrvold_impl< graph_t, vertex_index_map_t, + graph::detail::no_old_handles, #ifdef BOOST_GRAPH_PREFER_STD_LIB - graph::detail::std_list + graph::detail::std_list #else - graph::detail::recursive_lazy_list + graph::detail::recursive_lazy_list #endif - > - planarity_tester(g, v_i_map); - - if (planarity_tester.is_planar()) - { - planarity_tester.make_edge_permutation(args[embedding]); - return true; - } - else - return false; - } - - - - template - bool dispatched_boyer_myrvold(ArgumentPack const& args, - mpl::false_, - mpl::false_ - ) - { - //Dispatch for planar embedding, kuratowski subgraph isolation - typedef typename remove_const< - typename parameter::value_type::type - >::type graph_t; - - typedef typename property_map< - graph_t, - vertex_index_t - >::const_type vertex_default_index_map_t; - - typedef typename parameter::value_type< - ArgumentPack, - tag::vertex_index_map, - vertex_default_index_map_t - >::type vertex_index_map_t; - - typedef typename property_map< - graph_t, - edge_index_t - >::const_type edge_default_index_map_t; - - typedef typename parameter::value_type< - ArgumentPack, - tag::edge_index_map, - edge_default_index_map_t - >::type edge_index_map_t; - - graph_t const& g = args[graph]; - vertex_default_index_map_t v_d_map = get(vertex_index, g); - vertex_index_map_t v_i_map = args[vertex_index_map | v_d_map]; - edge_default_index_map_t e_d_map = get(edge_index, g); - edge_index_map_t e_i_map = args[edge_index_map | e_d_map]; - boyer_myrvold_impl - + planarity_tester(g, v_i_map); + + if (planarity_tester.is_planar()) + { + planarity_tester.make_edge_permutation(args[embedding]); + return true; + } + else + return false; + } + + template < typename ArgumentPack > + bool dispatched_boyer_myrvold( + ArgumentPack const& args, mpl::false_, mpl::false_) + { + // Dispatch for planar embedding, kuratowski subgraph isolation + typedef typename remove_const< typename parameter::value_type< + ArgumentPack, tag::graph >::type >::type graph_t; + + typedef typename property_map< graph_t, vertex_index_t >::const_type + vertex_default_index_map_t; + + typedef typename parameter::value_type< ArgumentPack, + tag::vertex_index_map, vertex_default_index_map_t >::type + vertex_index_map_t; + + typedef typename property_map< graph_t, edge_index_t >::const_type + edge_default_index_map_t; + + typedef typename parameter::value_type< ArgumentPack, + tag::edge_index_map, edge_default_index_map_t >::type + edge_index_map_t; + + graph_t const& g = args[graph]; + vertex_default_index_map_t v_d_map = get(vertex_index, g); + vertex_index_map_t v_i_map = args[vertex_index_map | v_d_map]; + edge_default_index_map_t e_d_map = get(edge_index, g); + edge_index_map_t e_i_map = args[edge_index_map | e_d_map]; + boyer_myrvold_impl< graph_t, vertex_index_map_t, + graph::detail::store_old_handles, #ifdef BOOST_BGL_PREFER_STD_LIB - graph::detail::std_list + graph::detail::std_list #else - graph::detail::recursive_lazy_list + graph::detail::recursive_lazy_list #endif - > - planarity_tester(g, v_i_map); - - if (planarity_tester.is_planar()) - { - planarity_tester.make_edge_permutation(args[embedding]); - return true; - } - else - { - planarity_tester.extract_kuratowski_subgraph - (args[kuratowski_subgraph], e_i_map); - return false; - } - } - - - - - template - bool boyer_myrvold_planarity_test(ArgumentPack const& args) - { - - typedef typename parameter::binding - < ArgumentPack, - tag::kuratowski_subgraph, - const no_kuratowski_subgraph_isolation& - >::type - kuratowski_arg_t; - - typedef typename parameter::binding - < ArgumentPack, - tag::embedding, - const no_planar_embedding& - >::type - embedding_arg_t; - - return dispatched_boyer_myrvold - (args, - boost::is_same - (), - boost::is_same - () - ); - } - - - - } //namespace core - - } //namespace boyer_myrvold_params - - - template - bool boyer_myrvold_planarity_test(A0 const& arg0) - { - return boyer_myrvold_params::core::boyer_myrvold_planarity_test - (boyer_myrvold_params::boyer_myrvold_params_t()(arg0)); - } - - template - // bool boyer_myrvold_planarity_test(A0 const& arg0, A1 const& arg1) - bool boyer_myrvold_planarity_test(A0 const& arg0, A1 const& arg1) - { - return boyer_myrvold_params::core::boyer_myrvold_planarity_test - (boyer_myrvold_params::boyer_myrvold_params_t()(arg0,arg1)); - } - - template - bool boyer_myrvold_planarity_test(A0 const& arg0, - A1 const& arg1, - A2 const& arg2 - ) - { - return boyer_myrvold_params::core::boyer_myrvold_planarity_test - (boyer_myrvold_params::boyer_myrvold_params_t()(arg0,arg1,arg2)); - } - - template - bool boyer_myrvold_planarity_test(A0 const& arg0, - A1 const& arg1, - A2 const& arg2, - A3 const& arg3 - ) - { - return boyer_myrvold_params::core::boyer_myrvold_planarity_test - (boyer_myrvold_params::boyer_myrvold_params_t()(arg0,arg1,arg2,arg3)); - } - - template - bool boyer_myrvold_planarity_test(A0 const& arg0, - A1 const& arg1, - A2 const& arg2, - A3 const& arg3, - A4 const& arg4 - ) - { - return boyer_myrvold_params::core::boyer_myrvold_planarity_test - (boyer_myrvold_params::boyer_myrvold_params_t() - (arg0,arg1,arg2,arg3,arg4) - ); - } - + > + planarity_tester(g, v_i_map); + + if (planarity_tester.is_planar()) + { + planarity_tester.make_edge_permutation(args[embedding]); + return true; + } + else + { + planarity_tester.extract_kuratowski_subgraph( + args[kuratowski_subgraph], e_i_map); + return false; + } + } + + template < typename ArgumentPack > + bool boyer_myrvold_planarity_test(ArgumentPack const& args) + { + + typedef typename parameter::binding< ArgumentPack, + tag::kuratowski_subgraph, + const no_kuratowski_subgraph_isolation& >::type + kuratowski_arg_t; + + typedef typename parameter::binding< ArgumentPack, tag::embedding, + const no_planar_embedding& >::type embedding_arg_t; + + return dispatched_boyer_myrvold(args, + boost::is_same< embedding_arg_t, const no_planar_embedding& >(), + boost::is_same< kuratowski_arg_t, + const no_kuratowski_subgraph_isolation& >()); + } + + } // namespace core + +} // namespace boyer_myrvold_params + +template < typename A0 > bool boyer_myrvold_planarity_test(A0 const& arg0) +{ + return boyer_myrvold_params::core::boyer_myrvold_planarity_test( + boyer_myrvold_params::boyer_myrvold_params_t()(arg0)); +} + +template < typename A0, typename A1 > +// bool boyer_myrvold_planarity_test(A0 const& arg0, A1 const& arg1) +bool boyer_myrvold_planarity_test(A0 const& arg0, A1 const& arg1) +{ + return boyer_myrvold_params::core::boyer_myrvold_planarity_test( + boyer_myrvold_params::boyer_myrvold_params_t()(arg0, arg1)); +} + +template < typename A0, typename A1, typename A2 > +bool boyer_myrvold_planarity_test( + A0 const& arg0, A1 const& arg1, A2 const& arg2) +{ + return boyer_myrvold_params::core::boyer_myrvold_planarity_test( + boyer_myrvold_params::boyer_myrvold_params_t()(arg0, arg1, arg2)); +} + +template < typename A0, typename A1, typename A2, typename A3 > +bool boyer_myrvold_planarity_test( + A0 const& arg0, A1 const& arg1, A2 const& arg2, A3 const& arg3) +{ + return boyer_myrvold_params::core::boyer_myrvold_planarity_test( + boyer_myrvold_params::boyer_myrvold_params_t()(arg0, arg1, arg2, arg3)); +} + +template < typename A0, typename A1, typename A2, typename A3, typename A4 > +bool boyer_myrvold_planarity_test(A0 const& arg0, A1 const& arg1, + A2 const& arg2, A3 const& arg3, A4 const& arg4) +{ + return boyer_myrvold_params::core::boyer_myrvold_planarity_test( + boyer_myrvold_params::boyer_myrvold_params_t()( + arg0, arg1, arg2, arg3, arg4)); +} } diff --git a/include/boost/graph/boykov_kolmogorov_max_flow.hpp b/include/boost/graph/boykov_kolmogorov_max_flow.hpp index 1edc1323e..7c74f338f 100644 --- a/include/boost/graph/boykov_kolmogorov_max_flow.hpp +++ b/include/boost/graph/boykov_kolmogorov_max_flow.hpp @@ -61,741 +61,944 @@ // Kolmogorov, V. "Graph Based Algorithms for Scene Reconstruction from Two or // More Views". PhD thesis, Cornell University, Sep 2003. -namespace boost { - -namespace detail { - -template -class bk_max_flow { - typedef typename property_traits::value_type tEdgeVal; - typedef graph_traits tGraphTraits; - typedef typename tGraphTraits::vertex_iterator vertex_iterator; - typedef typename tGraphTraits::vertex_descriptor vertex_descriptor; - typedef typename tGraphTraits::edge_descriptor edge_descriptor; - typedef typename tGraphTraits::edge_iterator edge_iterator; - typedef typename tGraphTraits::out_edge_iterator out_edge_iterator; - typedef boost::queue tQueue; //queue of vertices, used in adoption-stage - typedef typename property_traits::value_type tColorValue; - typedef color_traits tColorTraits; - typedef typename property_traits::value_type tDistanceVal; +namespace boost +{ + +namespace detail +{ + + template < class Graph, class EdgeCapacityMap, + class ResidualCapacityEdgeMap, class ReverseEdgeMap, + class PredecessorMap, class ColorMap, class DistanceMap, + class IndexMap > + class bk_max_flow + { + typedef + typename property_traits< EdgeCapacityMap >::value_type tEdgeVal; + typedef graph_traits< Graph > tGraphTraits; + typedef typename tGraphTraits::vertex_iterator vertex_iterator; + typedef typename tGraphTraits::vertex_descriptor vertex_descriptor; + typedef typename tGraphTraits::edge_descriptor edge_descriptor; + typedef typename tGraphTraits::edge_iterator edge_iterator; + typedef typename tGraphTraits::out_edge_iterator out_edge_iterator; + typedef boost::queue< vertex_descriptor > + tQueue; // queue of vertices, used in adoption-stage + typedef typename property_traits< ColorMap >::value_type tColorValue; + typedef color_traits< tColorValue > tColorTraits; + typedef + typename property_traits< DistanceMap >::value_type tDistanceVal; public: - bk_max_flow(Graph& g, - EdgeCapacityMap cap, - ResidualCapacityEdgeMap res, - ReverseEdgeMap rev, - PredecessorMap pre, - ColorMap color, - DistanceMap dist, - IndexMap idx, - vertex_descriptor src, - vertex_descriptor sink): - m_g(g), - m_index_map(idx), - m_cap_map(cap), - m_res_cap_map(res), - m_rev_edge_map(rev), - m_pre_map(pre), - m_tree_map(color), - m_dist_map(dist), - m_source(src), - m_sink(sink), - m_active_nodes(), - m_in_active_list_vec(num_vertices(g), false), - m_in_active_list_map(make_iterator_property_map(m_in_active_list_vec.begin(), m_index_map)), - m_has_parent_vec(num_vertices(g), false), - m_has_parent_map(make_iterator_property_map(m_has_parent_vec.begin(), m_index_map)), - m_time_vec(num_vertices(g), 0), - m_time_map(make_iterator_property_map(m_time_vec.begin(), m_index_map)), - m_flow(0), - m_time(1), - m_last_grow_vertex(graph_traits::null_vertex()){ - // initialize the color-map with gray-values - vertex_iterator vi, v_end; - for(boost::tie(vi, v_end) = vertices(m_g); vi != v_end; ++vi){ - set_tree(*vi, tColorTraits::gray()); - } - // Initialize flow to zero which means initializing - // the residual capacity equal to the capacity - edge_iterator ei, e_end; - for(boost::tie(ei, e_end) = edges(m_g); ei != e_end; ++ei) { - put(m_res_cap_map, *ei, get(m_cap_map, *ei)); - BOOST_ASSERT(get(m_rev_edge_map, get(m_rev_edge_map, *ei)) == *ei); //check if the reverse edge map is build up properly - } - //init the search trees with the two terminals - set_tree(m_source, tColorTraits::black()); - set_tree(m_sink, tColorTraits::white()); - put(m_time_map, m_source, 1); - put(m_time_map, m_sink, 1); - } - - tEdgeVal max_flow(){ - //augment direct paths from SOURCE->SINK and SOURCE->VERTEX->SINK - augment_direct_paths(); - //start the main-loop - while(true){ - bool path_found; - edge_descriptor connecting_edge; - boost::tie(connecting_edge, path_found) = grow(); //find a path from source to sink - if(!path_found){ - //we're finished, no more paths were found - break; - } - ++m_time; - augment(connecting_edge); //augment that path - adopt(); //rebuild search tree structure + bk_max_flow(Graph& g, EdgeCapacityMap cap, ResidualCapacityEdgeMap res, + ReverseEdgeMap rev, PredecessorMap pre, ColorMap color, + DistanceMap dist, IndexMap idx, vertex_descriptor src, + vertex_descriptor sink) + : m_g(g) + , m_index_map(idx) + , m_cap_map(cap) + , m_res_cap_map(res) + , m_rev_edge_map(rev) + , m_pre_map(pre) + , m_tree_map(color) + , m_dist_map(dist) + , m_source(src) + , m_sink(sink) + , m_active_nodes() + , m_in_active_list_vec(num_vertices(g), false) + , m_in_active_list_map(make_iterator_property_map( + m_in_active_list_vec.begin(), m_index_map)) + , m_has_parent_vec(num_vertices(g), false) + , m_has_parent_map( + make_iterator_property_map(m_has_parent_vec.begin(), m_index_map)) + , m_time_vec(num_vertices(g), 0) + , m_time_map( + make_iterator_property_map(m_time_vec.begin(), m_index_map)) + , m_flow(0) + , m_time(1) + , m_last_grow_vertex(graph_traits< Graph >::null_vertex()) + { + // initialize the color-map with gray-values + vertex_iterator vi, v_end; + for (boost::tie(vi, v_end) = vertices(m_g); vi != v_end; ++vi) + { + set_tree(*vi, tColorTraits::gray()); + } + // Initialize flow to zero which means initializing + // the residual capacity equal to the capacity + edge_iterator ei, e_end; + for (boost::tie(ei, e_end) = edges(m_g); ei != e_end; ++ei) + { + put(m_res_cap_map, *ei, get(m_cap_map, *ei)); + BOOST_ASSERT(get(m_rev_edge_map, get(m_rev_edge_map, *ei)) + == *ei); // check if the reverse edge map is build up + // properly + } + // init the search trees with the two terminals + set_tree(m_source, tColorTraits::black()); + set_tree(m_sink, tColorTraits::white()); + put(m_time_map, m_source, 1); + put(m_time_map, m_sink, 1); } - return m_flow; - } - // the complete class is protected, as we want access to members in - // derived test-class (see test/boykov_kolmogorov_max_flow_test.cpp) - protected: - void augment_direct_paths(){ - // in a first step, we augment all direct paths from source->NODE->sink - // and additionally paths from source->sink. This improves especially - // graphcuts for segmentation, as most of the nodes have source/sink - // connects but shouldn't have an impact on other maxflow problems - // (this is done in grow() anyway) - out_edge_iterator ei, e_end; - for(boost::tie(ei, e_end) = out_edges(m_source, m_g); ei != e_end; ++ei){ - edge_descriptor from_source = *ei; - vertex_descriptor current_node = target(from_source, m_g); - if(current_node == m_sink){ - tEdgeVal cap = get(m_res_cap_map, from_source); - put(m_res_cap_map, from_source, 0); - m_flow += cap; - continue; - } - edge_descriptor to_sink; - bool is_there; - boost::tie(to_sink, is_there) = lookup_edge(current_node, m_sink, m_g); - if(is_there){ - tEdgeVal cap_from_source = get(m_res_cap_map, from_source); - tEdgeVal cap_to_sink = get(m_res_cap_map, to_sink); - if(cap_from_source > cap_to_sink){ - set_tree(current_node, tColorTraits::black()); - add_active_node(current_node); - set_edge_to_parent(current_node, from_source); - put(m_dist_map, current_node, 1); - put(m_time_map, current_node, 1); - // add stuff to flow and update residuals. we dont need to - // update reverse_edges, as incoming/outgoing edges to/from - // source/sink don't count for max-flow - put(m_res_cap_map, from_source, get(m_res_cap_map, from_source) - cap_to_sink); - put(m_res_cap_map, to_sink, 0); - m_flow += cap_to_sink; - } else if(cap_to_sink > 0){ - set_tree(current_node, tColorTraits::white()); - add_active_node(current_node); - set_edge_to_parent(current_node, to_sink); - put(m_dist_map, current_node, 1); - put(m_time_map, current_node, 1); - // add stuff to flow and update residuals. we dont need to update - // reverse_edges, as incoming/outgoing edges to/from source/sink - // don't count for max-flow - put(m_res_cap_map, to_sink, get(m_res_cap_map, to_sink) - cap_from_source); - put(m_res_cap_map, from_source, 0); - m_flow += cap_from_source; + tEdgeVal max_flow() + { + // augment direct paths from SOURCE->SINK and SOURCE->VERTEX->SINK + augment_direct_paths(); + // start the main-loop + while (true) + { + bool path_found; + edge_descriptor connecting_edge; + boost::tie(connecting_edge, path_found) + = grow(); // find a path from source to sink + if (!path_found) + { + // we're finished, no more paths were found + break; + } + ++m_time; + augment(connecting_edge); // augment that path + adopt(); // rebuild search tree structure } - } else if(get(m_res_cap_map, from_source)){ - // there is no sink connect, so we can't augment this path, but to - // avoid adding m_source to the active nodes, we just activate this - // node and set the approciate things - set_tree(current_node, tColorTraits::black()); - set_edge_to_parent(current_node, from_source); - put(m_dist_map, current_node, 1); - put(m_time_map, current_node, 1); - add_active_node(current_node); - } - } - for(boost::tie(ei, e_end) = out_edges(m_sink, m_g); ei != e_end; ++ei){ - edge_descriptor to_sink = get(m_rev_edge_map, *ei); - vertex_descriptor current_node = source(to_sink, m_g); - if(get(m_res_cap_map, to_sink)){ - set_tree(current_node, tColorTraits::white()); - set_edge_to_parent(current_node, to_sink); - put(m_dist_map, current_node, 1); - put(m_time_map, current_node, 1); - add_active_node(current_node); - } + return m_flow; } - } - - /** - * Returns a pair of an edge and a boolean. if the bool is true, the - * edge is a connection of a found path from s->t , read "the link" and - * source(returnVal, m_g) is the end of the path found in the source-tree - * target(returnVal, m_g) is the beginning of the path found in the sink-tree - */ - std::pair grow(){ - BOOST_ASSERT(m_orphans.empty()); - vertex_descriptor current_node; - while((current_node = get_next_active_node()) != graph_traits::null_vertex()){ //if there is one - BOOST_ASSERT(get_tree(current_node) != tColorTraits::gray() && - (has_parent(current_node) || - current_node == m_source || - current_node == m_sink)); - - if(get_tree(current_node) == tColorTraits::black()){ - //source tree growing + + // the complete class is protected, as we want access to members in + // derived test-class (see test/boykov_kolmogorov_max_flow_test.cpp) + protected: + void augment_direct_paths() + { + // in a first step, we augment all direct paths from + // source->NODE->sink and additionally paths from source->sink. This + // improves especially graphcuts for segmentation, as most of the + // nodes have source/sink connects but shouldn't have an impact on + // other maxflow problems (this is done in grow() anyway) out_edge_iterator ei, e_end; - if(current_node != m_last_grow_vertex){ - m_last_grow_vertex = current_node; - boost::tie(m_last_grow_edge_it, m_last_grow_edge_end) = out_edges(current_node, m_g); - } - for(; m_last_grow_edge_it != m_last_grow_edge_end; ++m_last_grow_edge_it) { - edge_descriptor out_edge = *m_last_grow_edge_it; - if(get(m_res_cap_map, out_edge) > 0){ //check if we have capacity left on this edge - vertex_descriptor other_node = target(out_edge, m_g); - if(get_tree(other_node) == tColorTraits::gray()){ //it's a free node - set_tree(other_node, tColorTraits::black()); //aquire other node to our search tree - set_edge_to_parent(other_node, out_edge); //set us as parent - put(m_dist_map, other_node, get(m_dist_map, current_node) + 1); //and update the distance-heuristic - put(m_time_map, other_node, get(m_time_map, current_node)); - add_active_node(other_node); - } else if(get_tree(other_node) == tColorTraits::black()) { - // we do this to get shorter paths. check if we are nearer to - // the source as its parent is - if(is_closer_to_terminal(current_node, other_node)){ - set_edge_to_parent(other_node, out_edge); - put(m_dist_map, other_node, get(m_dist_map, current_node) + 1); - put(m_time_map, other_node, get(m_time_map, current_node)); - } - } else{ - BOOST_ASSERT(get_tree(other_node)==tColorTraits::white()); - //kewl, found a path from one to the other search tree, return - // the connecting edge in src->sink dir - return std::make_pair(out_edge, true); + for (boost::tie(ei, e_end) = out_edges(m_source, m_g); ei != e_end; + ++ei) + { + edge_descriptor from_source = *ei; + vertex_descriptor current_node = target(from_source, m_g); + if (current_node == m_sink) + { + tEdgeVal cap = get(m_res_cap_map, from_source); + put(m_res_cap_map, from_source, 0); + m_flow += cap; + continue; + } + edge_descriptor to_sink; + bool is_there; + boost::tie(to_sink, is_there) + = lookup_edge(current_node, m_sink, m_g); + if (is_there) + { + tEdgeVal cap_from_source = get(m_res_cap_map, from_source); + tEdgeVal cap_to_sink = get(m_res_cap_map, to_sink); + if (cap_from_source > cap_to_sink) + { + set_tree(current_node, tColorTraits::black()); + add_active_node(current_node); + set_edge_to_parent(current_node, from_source); + put(m_dist_map, current_node, 1); + put(m_time_map, current_node, 1); + // add stuff to flow and update residuals. we dont need + // to update reverse_edges, as incoming/outgoing edges + // to/from source/sink don't count for max-flow + put(m_res_cap_map, from_source, + get(m_res_cap_map, from_source) - cap_to_sink); + put(m_res_cap_map, to_sink, 0); + m_flow += cap_to_sink; + } + else if (cap_to_sink > 0) + { + set_tree(current_node, tColorTraits::white()); + add_active_node(current_node); + set_edge_to_parent(current_node, to_sink); + put(m_dist_map, current_node, 1); + put(m_time_map, current_node, 1); + // add stuff to flow and update residuals. we dont need + // to update reverse_edges, as incoming/outgoing edges + // to/from source/sink don't count for max-flow + put(m_res_cap_map, to_sink, + get(m_res_cap_map, to_sink) - cap_from_source); + put(m_res_cap_map, from_source, 0); + m_flow += cap_from_source; + } + } + else if (get(m_res_cap_map, from_source)) + { + // there is no sink connect, so we can't augment this path, + // but to avoid adding m_source to the active nodes, we just + // activate this node and set the approciate things + set_tree(current_node, tColorTraits::black()); + set_edge_to_parent(current_node, from_source); + put(m_dist_map, current_node, 1); + put(m_time_map, current_node, 1); + add_active_node(current_node); } - } - } //for all out-edges - } //source-tree-growing - else{ - BOOST_ASSERT(get_tree(current_node) == tColorTraits::white()); - out_edge_iterator ei, e_end; - if(current_node != m_last_grow_vertex){ - m_last_grow_vertex = current_node; - boost::tie(m_last_grow_edge_it, m_last_grow_edge_end) = out_edges(current_node, m_g); } - for(; m_last_grow_edge_it != m_last_grow_edge_end; ++m_last_grow_edge_it){ - edge_descriptor in_edge = get(m_rev_edge_map, *m_last_grow_edge_it); - if(get(m_res_cap_map, in_edge) > 0){ //check if there is capacity left - vertex_descriptor other_node = source(in_edge, m_g); - if(get_tree(other_node) == tColorTraits::gray()){ //it's a free node - set_tree(other_node, tColorTraits::white()); //aquire that node to our search tree - set_edge_to_parent(other_node, in_edge); //set us as parent - add_active_node(other_node); //activate that node - put(m_dist_map, other_node, get(m_dist_map, current_node) + 1); //set its distance - put(m_time_map, other_node, get(m_time_map, current_node));//and time - } else if(get_tree(other_node) == tColorTraits::white()){ - if(is_closer_to_terminal(current_node, other_node)){ - //we are closer to the sink than its parent is, so we "adopt" him - set_edge_to_parent(other_node, in_edge); - put(m_dist_map, other_node, get(m_dist_map, current_node) + 1); - put(m_time_map, other_node, get(m_time_map, current_node)); - } - } else{ - BOOST_ASSERT(get_tree(other_node)==tColorTraits::black()); - //kewl, found a path from one to the other search tree, - // return the connecting edge in src->sink dir - return std::make_pair(in_edge, true); + for (boost::tie(ei, e_end) = out_edges(m_sink, m_g); ei != e_end; + ++ei) + { + edge_descriptor to_sink = get(m_rev_edge_map, *ei); + vertex_descriptor current_node = source(to_sink, m_g); + if (get(m_res_cap_map, to_sink)) + { + set_tree(current_node, tColorTraits::white()); + set_edge_to_parent(current_node, to_sink); + put(m_dist_map, current_node, 1); + put(m_time_map, current_node, 1); + add_active_node(current_node); } - } - } //for all out-edges - } //sink-tree growing - - //all edges of that node are processed, and no more paths were found. - // remove if from the front of the active queue - finish_node(current_node); - } //while active_nodes not empty - - //no active nodes anymore and no path found, we're done - return std::make_pair(edge_descriptor(), false); - } - - /** - * augments path from s->t and updates residual graph - * source(e, m_g) is the end of the path found in the source-tree - * target(e, m_g) is the beginning of the path found in the sink-tree - * this phase generates orphans on satured edges, if the attached verts are - * from different search-trees orphans are ordered in distance to - * sink/source. first the farest from the source are front_inserted into - * the orphans list, and after that the sink-tree-orphans are - * front_inserted. when going to adoption stage the orphans are popped_front, - * and so we process the nearest verts to the terminals first - */ - void augment(edge_descriptor e) { - BOOST_ASSERT(get_tree(target(e, m_g)) == tColorTraits::white()); - BOOST_ASSERT(get_tree(source(e, m_g)) == tColorTraits::black()); - BOOST_ASSERT(m_orphans.empty()); - - const tEdgeVal bottleneck = find_bottleneck(e); - //now we push the found flow through the path - //for each edge we saturate we have to look for the verts that belong to that edge, one of them becomes an orphans - //now process the connecting edge - put(m_res_cap_map, e, get(m_res_cap_map, e) - bottleneck); - BOOST_ASSERT(get(m_res_cap_map, e) >= 0); - put(m_res_cap_map, get(m_rev_edge_map, e), get(m_res_cap_map, get(m_rev_edge_map, e)) + bottleneck); - - //now we follow the path back to the source - vertex_descriptor current_node = source(e, m_g); - while(current_node != m_source){ - edge_descriptor pred = get_edge_to_parent(current_node); - put(m_res_cap_map, pred, get(m_res_cap_map, pred) - bottleneck); - BOOST_ASSERT(get(m_res_cap_map, pred) >= 0); - put(m_res_cap_map, get(m_rev_edge_map, pred), get(m_res_cap_map, get(m_rev_edge_map, pred)) + bottleneck); - if(get(m_res_cap_map, pred) == 0){ - set_no_parent(current_node); - m_orphans.push_front(current_node); - } - current_node = source(pred, m_g); + } } - //then go forward in the sink-tree - current_node = target(e, m_g); - while(current_node != m_sink){ - edge_descriptor pred = get_edge_to_parent(current_node); - put(m_res_cap_map, pred, get(m_res_cap_map, pred) - bottleneck); - BOOST_ASSERT(get(m_res_cap_map, pred) >= 0); - put(m_res_cap_map, get(m_rev_edge_map, pred), get(m_res_cap_map, get(m_rev_edge_map, pred)) + bottleneck); - if(get(m_res_cap_map, pred) == 0){ - set_no_parent(current_node); - m_orphans.push_front(current_node); - } - current_node = target(pred, m_g); + + /** + * Returns a pair of an edge and a boolean. if the bool is true, the + * edge is a connection of a found path from s->t , read "the link" and + * source(returnVal, m_g) is the end of the path found in the + * source-tree target(returnVal, m_g) is the beginning of the path found + * in the sink-tree + */ + std::pair< edge_descriptor, bool > grow() + { + BOOST_ASSERT(m_orphans.empty()); + vertex_descriptor current_node; + while ((current_node = get_next_active_node()) + != graph_traits< Graph >::null_vertex()) + { // if there is one + BOOST_ASSERT(get_tree(current_node) != tColorTraits::gray() + && (has_parent(current_node) || current_node == m_source + || current_node == m_sink)); + + if (get_tree(current_node) == tColorTraits::black()) + { + // source tree growing + out_edge_iterator ei, e_end; + if (current_node != m_last_grow_vertex) + { + m_last_grow_vertex = current_node; + boost::tie(m_last_grow_edge_it, m_last_grow_edge_end) + = out_edges(current_node, m_g); + } + for (; m_last_grow_edge_it != m_last_grow_edge_end; + ++m_last_grow_edge_it) + { + edge_descriptor out_edge = *m_last_grow_edge_it; + if (get(m_res_cap_map, out_edge) > 0) + { // check if we have capacity left on this edge + vertex_descriptor other_node + = target(out_edge, m_g); + if (get_tree(other_node) == tColorTraits::gray()) + { // it's a free node + set_tree(other_node, + tColorTraits::black()); // aquire other node + // to our search + // tree + set_edge_to_parent( + other_node, out_edge); // set us as parent + put(m_dist_map, other_node, + get(m_dist_map, current_node) + + 1); // and update the + // distance-heuristic + put(m_time_map, other_node, + get(m_time_map, current_node)); + add_active_node(other_node); + } + else if (get_tree(other_node) + == tColorTraits::black()) + { + // we do this to get shorter paths. check if we + // are nearer to the source as its parent is + if (is_closer_to_terminal( + current_node, other_node)) + { + set_edge_to_parent(other_node, out_edge); + put(m_dist_map, other_node, + get(m_dist_map, current_node) + 1); + put(m_time_map, other_node, + get(m_time_map, current_node)); + } + } + else + { + BOOST_ASSERT(get_tree(other_node) + == tColorTraits::white()); + // kewl, found a path from one to the other + // search tree, return + // the connecting edge in src->sink dir + return std::make_pair(out_edge, true); + } + } + } // for all out-edges + } // source-tree-growing + else + { + BOOST_ASSERT( + get_tree(current_node) == tColorTraits::white()); + out_edge_iterator ei, e_end; + if (current_node != m_last_grow_vertex) + { + m_last_grow_vertex = current_node; + boost::tie(m_last_grow_edge_it, m_last_grow_edge_end) + = out_edges(current_node, m_g); + } + for (; m_last_grow_edge_it != m_last_grow_edge_end; + ++m_last_grow_edge_it) + { + edge_descriptor in_edge + = get(m_rev_edge_map, *m_last_grow_edge_it); + if (get(m_res_cap_map, in_edge) > 0) + { // check if there is capacity left + vertex_descriptor other_node = source(in_edge, m_g); + if (get_tree(other_node) == tColorTraits::gray()) + { // it's a free node + set_tree(other_node, + tColorTraits::white()); // aquire that node + // to our search + // tree + set_edge_to_parent( + other_node, in_edge); // set us as parent + add_active_node( + other_node); // activate that node + put(m_dist_map, other_node, + get(m_dist_map, current_node) + + 1); // set its distance + put(m_time_map, other_node, + get(m_time_map, current_node)); // and time + } + else if (get_tree(other_node) + == tColorTraits::white()) + { + if (is_closer_to_terminal( + current_node, other_node)) + { + // we are closer to the sink than its parent + // is, so we "adopt" him + set_edge_to_parent(other_node, in_edge); + put(m_dist_map, other_node, + get(m_dist_map, current_node) + 1); + put(m_time_map, other_node, + get(m_time_map, current_node)); + } + } + else + { + BOOST_ASSERT(get_tree(other_node) + == tColorTraits::black()); + // kewl, found a path from one to the other + // search tree, + // return the connecting edge in src->sink dir + return std::make_pair(in_edge, true); + } + } + } // for all out-edges + } // sink-tree growing + + // all edges of that node are processed, and no more paths were + // found. + // remove if from the front of the active queue + finish_node(current_node); + } // while active_nodes not empty + + // no active nodes anymore and no path found, we're done + return std::make_pair(edge_descriptor(), false); } - //and add it to the max-flow - m_flow += bottleneck; - } - - /** - * returns the bottleneck of a s->t path (end_of_path is last vertex in - * source-tree, begin_of_path is first vertex in sink-tree) - */ - inline tEdgeVal find_bottleneck(edge_descriptor e){ - BOOST_USING_STD_MIN(); - tEdgeVal minimum_cap = get(m_res_cap_map, e); - vertex_descriptor current_node = source(e, m_g); - //first go back in the source tree - while(current_node != m_source){ - edge_descriptor pred = get_edge_to_parent(current_node); - minimum_cap = min BOOST_PREVENT_MACRO_SUBSTITUTION(minimum_cap, get(m_res_cap_map, pred)); - current_node = source(pred, m_g); + + /** + * augments path from s->t and updates residual graph + * source(e, m_g) is the end of the path found in the source-tree + * target(e, m_g) is the beginning of the path found in the sink-tree + * this phase generates orphans on satured edges, if the attached verts + * are from different search-trees orphans are ordered in distance to + * sink/source. first the farest from the source are front_inserted into + * the orphans list, and after that the sink-tree-orphans are + * front_inserted. when going to adoption stage the orphans are + * popped_front, and so we process the nearest verts to the terminals + * first + */ + void augment(edge_descriptor e) + { + BOOST_ASSERT(get_tree(target(e, m_g)) == tColorTraits::white()); + BOOST_ASSERT(get_tree(source(e, m_g)) == tColorTraits::black()); + BOOST_ASSERT(m_orphans.empty()); + + const tEdgeVal bottleneck = find_bottleneck(e); + // now we push the found flow through the path + // for each edge we saturate we have to look for the verts that + // belong to that edge, one of them becomes an orphans now process + // the connecting edge + put(m_res_cap_map, e, get(m_res_cap_map, e) - bottleneck); + BOOST_ASSERT(get(m_res_cap_map, e) >= 0); + put(m_res_cap_map, get(m_rev_edge_map, e), + get(m_res_cap_map, get(m_rev_edge_map, e)) + bottleneck); + + // now we follow the path back to the source + vertex_descriptor current_node = source(e, m_g); + while (current_node != m_source) + { + edge_descriptor pred = get_edge_to_parent(current_node); + put(m_res_cap_map, pred, get(m_res_cap_map, pred) - bottleneck); + BOOST_ASSERT(get(m_res_cap_map, pred) >= 0); + put(m_res_cap_map, get(m_rev_edge_map, pred), + get(m_res_cap_map, get(m_rev_edge_map, pred)) + bottleneck); + if (get(m_res_cap_map, pred) == 0) + { + set_no_parent(current_node); + m_orphans.push_front(current_node); + } + current_node = source(pred, m_g); + } + // then go forward in the sink-tree + current_node = target(e, m_g); + while (current_node != m_sink) + { + edge_descriptor pred = get_edge_to_parent(current_node); + put(m_res_cap_map, pred, get(m_res_cap_map, pred) - bottleneck); + BOOST_ASSERT(get(m_res_cap_map, pred) >= 0); + put(m_res_cap_map, get(m_rev_edge_map, pred), + get(m_res_cap_map, get(m_rev_edge_map, pred)) + bottleneck); + if (get(m_res_cap_map, pred) == 0) + { + set_no_parent(current_node); + m_orphans.push_front(current_node); + } + current_node = target(pred, m_g); + } + // and add it to the max-flow + m_flow += bottleneck; } - //then go forward in the sink-tree - current_node = target(e, m_g); - while(current_node != m_sink){ - edge_descriptor pred = get_edge_to_parent(current_node); - minimum_cap = min BOOST_PREVENT_MACRO_SUBSTITUTION(minimum_cap, get(m_res_cap_map, pred)); - current_node = target(pred, m_g); + + /** + * returns the bottleneck of a s->t path (end_of_path is last vertex in + * source-tree, begin_of_path is first vertex in sink-tree) + */ + inline tEdgeVal find_bottleneck(edge_descriptor e) + { + BOOST_USING_STD_MIN(); + tEdgeVal minimum_cap = get(m_res_cap_map, e); + vertex_descriptor current_node = source(e, m_g); + // first go back in the source tree + while (current_node != m_source) + { + edge_descriptor pred = get_edge_to_parent(current_node); + minimum_cap = min BOOST_PREVENT_MACRO_SUBSTITUTION( + minimum_cap, get(m_res_cap_map, pred)); + current_node = source(pred, m_g); + } + // then go forward in the sink-tree + current_node = target(e, m_g); + while (current_node != m_sink) + { + edge_descriptor pred = get_edge_to_parent(current_node); + minimum_cap = min BOOST_PREVENT_MACRO_SUBSTITUTION( + minimum_cap, get(m_res_cap_map, pred)); + current_node = target(pred, m_g); + } + return minimum_cap; } - return minimum_cap; - } - - /** - * rebuild search trees - * empty the queue of orphans, and find new parents for them or just drop - * them from the search trees - */ - void adopt(){ - while(!m_orphans.empty() || !m_child_orphans.empty()){ - vertex_descriptor current_node; - if(m_child_orphans.empty()){ - //get the next orphan from the main-queue and remove it - current_node = m_orphans.front(); - m_orphans.pop_front(); - } else{ - current_node = m_child_orphans.front(); - m_child_orphans.pop(); - } - if(get_tree(current_node) == tColorTraits::black()){ - //we're in the source-tree - tDistanceVal min_distance = (std::numeric_limits::max)(); - edge_descriptor new_parent_edge; - out_edge_iterator ei, e_end; - for(boost::tie(ei, e_end) = out_edges(current_node, m_g); ei != e_end; ++ei){ - const edge_descriptor in_edge = get(m_rev_edge_map, *ei); - BOOST_ASSERT(target(in_edge, m_g) == current_node); //we should be the target of this edge - if(get(m_res_cap_map, in_edge) > 0){ - vertex_descriptor other_node = source(in_edge, m_g); - if(get_tree(other_node) == tColorTraits::black() && has_source_connect(other_node)){ - if(get(m_dist_map, other_node) < min_distance){ - min_distance = get(m_dist_map, other_node); - new_parent_edge = in_edge; - } + + /** + * rebuild search trees + * empty the queue of orphans, and find new parents for them or just + * drop them from the search trees + */ + void adopt() + { + while (!m_orphans.empty() || !m_child_orphans.empty()) + { + vertex_descriptor current_node; + if (m_child_orphans.empty()) + { + // get the next orphan from the main-queue and remove it + current_node = m_orphans.front(); + m_orphans.pop_front(); } - } - } - if(min_distance != (std::numeric_limits::max)()){ - set_edge_to_parent(current_node, new_parent_edge); - put(m_dist_map, current_node, min_distance + 1); - put(m_time_map, current_node, m_time); - } else{ - put(m_time_map, current_node, 0); - for(boost::tie(ei, e_end) = out_edges(current_node, m_g); ei != e_end; ++ei){ - edge_descriptor in_edge = get(m_rev_edge_map, *ei); - vertex_descriptor other_node = source(in_edge, m_g); - if(get_tree(other_node) == tColorTraits::black() && other_node != m_source){ - if(get(m_res_cap_map, in_edge) > 0){ - add_active_node(other_node); - } - if(has_parent(other_node) && source(get_edge_to_parent(other_node), m_g) == current_node){ - //we are the parent of that node - //it has to find a new parent, too - set_no_parent(other_node); - m_child_orphans.push(other_node); - } + else + { + current_node = m_child_orphans.front(); + m_child_orphans.pop(); + } + if (get_tree(current_node) == tColorTraits::black()) + { + // we're in the source-tree + tDistanceVal min_distance + = (std::numeric_limits< tDistanceVal >::max)(); + edge_descriptor new_parent_edge; + out_edge_iterator ei, e_end; + for (boost::tie(ei, e_end) = out_edges(current_node, m_g); + ei != e_end; ++ei) + { + const edge_descriptor in_edge + = get(m_rev_edge_map, *ei); + BOOST_ASSERT(target(in_edge, m_g) + == current_node); // we should be the target of this + // edge + if (get(m_res_cap_map, in_edge) > 0) + { + vertex_descriptor other_node = source(in_edge, m_g); + if (get_tree(other_node) == tColorTraits::black() + && has_source_connect(other_node)) + { + if (get(m_dist_map, other_node) < min_distance) + { + min_distance = get(m_dist_map, other_node); + new_parent_edge = in_edge; + } + } + } + } + if (min_distance + != (std::numeric_limits< tDistanceVal >::max)()) + { + set_edge_to_parent(current_node, new_parent_edge); + put(m_dist_map, current_node, min_distance + 1); + put(m_time_map, current_node, m_time); + } + else + { + put(m_time_map, current_node, 0); + for (boost::tie(ei, e_end) + = out_edges(current_node, m_g); + ei != e_end; ++ei) + { + edge_descriptor in_edge = get(m_rev_edge_map, *ei); + vertex_descriptor other_node = source(in_edge, m_g); + if (get_tree(other_node) == tColorTraits::black() + && other_node != m_source) + { + if (get(m_res_cap_map, in_edge) > 0) + { + add_active_node(other_node); + } + if (has_parent(other_node) + && source( + get_edge_to_parent(other_node), m_g) + == current_node) + { + // we are the parent of that node + // it has to find a new parent, too + set_no_parent(other_node); + m_child_orphans.push(other_node); + } + } + } + set_tree(current_node, tColorTraits::gray()); + } // no parent found + } // source-tree-adoption + else + { + // now we should be in the sink-tree, check that... + BOOST_ASSERT( + get_tree(current_node) == tColorTraits::white()); + out_edge_iterator ei, e_end; + edge_descriptor new_parent_edge; + tDistanceVal min_distance + = (std::numeric_limits< tDistanceVal >::max)(); + for (boost::tie(ei, e_end) = out_edges(current_node, m_g); + ei != e_end; ++ei) + { + const edge_descriptor out_edge = *ei; + if (get(m_res_cap_map, out_edge) > 0) + { + const vertex_descriptor other_node + = target(out_edge, m_g); + if (get_tree(other_node) == tColorTraits::white() + && has_sink_connect(other_node)) + if (get(m_dist_map, other_node) < min_distance) + { + min_distance = get(m_dist_map, other_node); + new_parent_edge = out_edge; + } + } + } + if (min_distance + != (std::numeric_limits< tDistanceVal >::max)()) + { + set_edge_to_parent(current_node, new_parent_edge); + put(m_dist_map, current_node, min_distance + 1); + put(m_time_map, current_node, m_time); + } + else + { + put(m_time_map, current_node, 0); + for (boost::tie(ei, e_end) + = out_edges(current_node, m_g); + ei != e_end; ++ei) + { + const edge_descriptor out_edge = *ei; + const vertex_descriptor other_node + = target(out_edge, m_g); + if (get_tree(other_node) == tColorTraits::white() + && other_node != m_sink) + { + if (get(m_res_cap_map, out_edge) > 0) + { + add_active_node(other_node); + } + if (has_parent(other_node) + && target( + get_edge_to_parent(other_node), m_g) + == current_node) + { + // we were it's parent, so it has to find a + // new one, too + set_no_parent(other_node); + m_child_orphans.push(other_node); + } + } + } + set_tree(current_node, tColorTraits::gray()); + } // no parent found + } // sink-tree adoption + } // while !orphans.empty() + } // adopt + + /** + * return next active vertex if there is one, otherwise a null_vertex + */ + inline vertex_descriptor get_next_active_node() + { + while (true) + { + if (m_active_nodes.empty()) + return graph_traits< Graph >::null_vertex(); + vertex_descriptor v = m_active_nodes.front(); + + // if it has no parent, this node can't be active (if its not + // source or sink) + if (!has_parent(v) && v != m_source && v != m_sink) + { + m_active_nodes.pop(); + put(m_in_active_list_map, v, false); + } + else + { + BOOST_ASSERT(get_tree(v) == tColorTraits::black() + || get_tree(v) == tColorTraits::white()); + return v; } - } - set_tree(current_node, tColorTraits::gray()); - } //no parent found - } //source-tree-adoption - else{ - //now we should be in the sink-tree, check that... - BOOST_ASSERT(get_tree(current_node) == tColorTraits::white()); - out_edge_iterator ei, e_end; - edge_descriptor new_parent_edge; - tDistanceVal min_distance = (std::numeric_limits::max)(); - for(boost::tie(ei, e_end) = out_edges(current_node, m_g); ei != e_end; ++ei){ - const edge_descriptor out_edge = *ei; - if(get(m_res_cap_map, out_edge) > 0){ - const vertex_descriptor other_node = target(out_edge, m_g); - if(get_tree(other_node) == tColorTraits::white() && has_sink_connect(other_node)) - if(get(m_dist_map, other_node) < min_distance){ - min_distance = get(m_dist_map, other_node); - new_parent_edge = out_edge; - } - } } - if(min_distance != (std::numeric_limits::max)()){ - set_edge_to_parent(current_node, new_parent_edge); - put(m_dist_map, current_node, min_distance + 1); - put(m_time_map, current_node, m_time); - } else{ - put(m_time_map, current_node, 0); - for(boost::tie(ei, e_end) = out_edges(current_node, m_g); ei != e_end; ++ei){ - const edge_descriptor out_edge = *ei; - const vertex_descriptor other_node = target(out_edge, m_g); - if(get_tree(other_node) == tColorTraits::white() && other_node != m_sink){ - if(get(m_res_cap_map, out_edge) > 0){ - add_active_node(other_node); - } - if(has_parent(other_node) && target(get_edge_to_parent(other_node), m_g) == current_node){ - //we were it's parent, so it has to find a new one, too - set_no_parent(other_node); - m_child_orphans.push(other_node); - } + } + + /** + * adds v as an active vertex, but only if its not in the list already + */ + inline void add_active_node(vertex_descriptor v) + { + BOOST_ASSERT(get_tree(v) != tColorTraits::gray()); + if (get(m_in_active_list_map, v)) + { + if (m_last_grow_vertex == v) + { + m_last_grow_vertex = graph_traits< Graph >::null_vertex(); } - } - set_tree(current_node, tColorTraits::gray()); - } //no parent found - } //sink-tree adoption - } //while !orphans.empty() - } //adopt - - /** - * return next active vertex if there is one, otherwise a null_vertex - */ - inline vertex_descriptor get_next_active_node(){ - while(true){ - if(m_active_nodes.empty()) - return graph_traits::null_vertex(); - vertex_descriptor v = m_active_nodes.front(); - - //if it has no parent, this node can't be active (if its not source or sink) - if(!has_parent(v) && v != m_source && v != m_sink){ + return; + } + else + { + put(m_in_active_list_map, v, true); + m_active_nodes.push(v); + } + } + + /** + * finish_node removes a node from the front of the active queue (its + * called in grow phase, if no more paths can be found using this node) + */ + inline void finish_node(vertex_descriptor v) + { + BOOST_ASSERT(m_active_nodes.front() == v); m_active_nodes.pop(); put(m_in_active_list_map, v, false); - } else{ - BOOST_ASSERT(get_tree(v) == tColorTraits::black() || get_tree(v) == tColorTraits::white()); - return v; - } + m_last_grow_vertex = graph_traits< Graph >::null_vertex(); + } + + /** + * removes a vertex from the queue of active nodes (actually this does + * nothing, but checks if this node has no parent edge, as this is the + * criteria for being no more active) + */ + inline void remove_active_node(vertex_descriptor v) + { + BOOST_ASSERT(!has_parent(v)); } - } - - /** - * adds v as an active vertex, but only if its not in the list already - */ - inline void add_active_node(vertex_descriptor v){ - BOOST_ASSERT(get_tree(v) != tColorTraits::gray()); - if(get(m_in_active_list_map, v)){ - if (m_last_grow_vertex == v) { - m_last_grow_vertex = graph_traits::null_vertex(); - } - return; - } else{ - put(m_in_active_list_map, v, true); - m_active_nodes.push(v); + + /** + * returns the search tree of v; tColorValue::black() for source tree, + * white() for sink tree, gray() for no tree + */ + inline tColorValue get_tree(vertex_descriptor v) const + { + return get(m_tree_map, v); } - } - - /** - * finish_node removes a node from the front of the active queue (its called in grow phase, if no more paths can be found using this node) - */ - inline void finish_node(vertex_descriptor v){ - BOOST_ASSERT(m_active_nodes.front() == v); - m_active_nodes.pop(); - put(m_in_active_list_map, v, false); - m_last_grow_vertex = graph_traits::null_vertex(); - } - - /** - * removes a vertex from the queue of active nodes (actually this does nothing, - * but checks if this node has no parent edge, as this is the criteria for - * being no more active) - */ - inline void remove_active_node(vertex_descriptor v){ - BOOST_ASSERT(!has_parent(v)); - } - - /** - * returns the search tree of v; tColorValue::black() for source tree, - * white() for sink tree, gray() for no tree - */ - inline tColorValue get_tree(vertex_descriptor v) const { - return get(m_tree_map, v); - } - - /** - * sets search tree of v; tColorValue::black() for source tree, white() - * for sink tree, gray() for no tree - */ - inline void set_tree(vertex_descriptor v, tColorValue t){ - put(m_tree_map, v, t); - } - - /** - * returns edge to parent vertex of v; - */ - inline edge_descriptor get_edge_to_parent(vertex_descriptor v) const{ - return get(m_pre_map, v); - } - - /** - * returns true if the edge stored in m_pre_map[v] is a valid entry - */ - inline bool has_parent(vertex_descriptor v) const{ - return get(m_has_parent_map, v); - } - - /** - * sets edge to parent vertex of v; - */ - inline void set_edge_to_parent(vertex_descriptor v, edge_descriptor f_edge_to_parent){ - BOOST_ASSERT(get(m_res_cap_map, f_edge_to_parent) > 0); - put(m_pre_map, v, f_edge_to_parent); - put(m_has_parent_map, v, true); - } - - /** - * removes the edge to parent of v (this is done by invalidating the - * entry an additional map) - */ - inline void set_no_parent(vertex_descriptor v){ - put(m_has_parent_map, v, false); - } - - /** - * checks if vertex v has a connect to the sink-vertex (@var m_sink) - * @param v the vertex which is checked - * @return true if a path to the sink was found, false if not - */ - inline bool has_sink_connect(vertex_descriptor v){ - tDistanceVal current_distance = 0; - vertex_descriptor current_vertex = v; - while(true){ - if(get(m_time_map, current_vertex) == m_time){ - //we found a node which was already checked this round. use it for distance calculations - current_distance += get(m_dist_map, current_vertex); - break; - } - if(current_vertex == m_sink){ - put(m_time_map, m_sink, m_time); - break; - } - if(has_parent(current_vertex)){ - //it has a parent, so get it - current_vertex = target(get_edge_to_parent(current_vertex), m_g); - ++current_distance; - } else{ - //no path found - return false; - } + + /** + * sets search tree of v; tColorValue::black() for source tree, white() + * for sink tree, gray() for no tree + */ + inline void set_tree(vertex_descriptor v, tColorValue t) + { + put(m_tree_map, v, t); } - current_vertex=v; - while(get(m_time_map, current_vertex) != m_time){ - put(m_dist_map, current_vertex, current_distance); - --current_distance; - put(m_time_map, current_vertex, m_time); - current_vertex = target(get_edge_to_parent(current_vertex), m_g); + + /** + * returns edge to parent vertex of v; + */ + inline edge_descriptor get_edge_to_parent(vertex_descriptor v) const + { + return get(m_pre_map, v); + } + + /** + * returns true if the edge stored in m_pre_map[v] is a valid entry + */ + inline bool has_parent(vertex_descriptor v) const + { + return get(m_has_parent_map, v); + } + + /** + * sets edge to parent vertex of v; + */ + inline void set_edge_to_parent( + vertex_descriptor v, edge_descriptor f_edge_to_parent) + { + BOOST_ASSERT(get(m_res_cap_map, f_edge_to_parent) > 0); + put(m_pre_map, v, f_edge_to_parent); + put(m_has_parent_map, v, true); } - return true; - } - - /** - * checks if vertex v has a connect to the source-vertex (@var m_source) - * @param v the vertex which is checked - * @return true if a path to the source was found, false if not - */ - inline bool has_source_connect(vertex_descriptor v){ - tDistanceVal current_distance = 0; - vertex_descriptor current_vertex = v; - while(true){ - if(get(m_time_map, current_vertex) == m_time){ - //we found a node which was already checked this round. use it for distance calculations - current_distance += get(m_dist_map, current_vertex); - break; - } - if(current_vertex == m_source){ - put(m_time_map, m_source, m_time); - break; - } - if(has_parent(current_vertex)){ - //it has a parent, so get it - current_vertex = source(get_edge_to_parent(current_vertex), m_g); - ++current_distance; - } else{ - //no path found - return false; - } + + /** + * removes the edge to parent of v (this is done by invalidating the + * entry an additional map) + */ + inline void set_no_parent(vertex_descriptor v) + { + put(m_has_parent_map, v, false); } - current_vertex=v; - while(get(m_time_map, current_vertex) != m_time){ - put(m_dist_map, current_vertex, current_distance); - --current_distance; - put(m_time_map, current_vertex, m_time); - current_vertex = source(get_edge_to_parent(current_vertex), m_g); + + /** + * checks if vertex v has a connect to the sink-vertex (@var m_sink) + * @param v the vertex which is checked + * @return true if a path to the sink was found, false if not + */ + inline bool has_sink_connect(vertex_descriptor v) + { + tDistanceVal current_distance = 0; + vertex_descriptor current_vertex = v; + while (true) + { + if (get(m_time_map, current_vertex) == m_time) + { + // we found a node which was already checked this round. use + // it for distance calculations + current_distance += get(m_dist_map, current_vertex); + break; + } + if (current_vertex == m_sink) + { + put(m_time_map, m_sink, m_time); + break; + } + if (has_parent(current_vertex)) + { + // it has a parent, so get it + current_vertex + = target(get_edge_to_parent(current_vertex), m_g); + ++current_distance; + } + else + { + // no path found + return false; + } + } + current_vertex = v; + while (get(m_time_map, current_vertex) != m_time) + { + put(m_dist_map, current_vertex, current_distance); + --current_distance; + put(m_time_map, current_vertex, m_time); + current_vertex + = target(get_edge_to_parent(current_vertex), m_g); + } + return true; } - return true; - } - - /** - * returns true, if p is closer to a terminal than q - */ - inline bool is_closer_to_terminal(vertex_descriptor p, vertex_descriptor q){ - //checks the timestamps first, to build no cycles, and after that the real distance - return (get(m_time_map, q) <= get(m_time_map, p) && - get(m_dist_map, q) > get(m_dist_map, p)+1); - } - - //////// - // member vars - //////// - Graph& m_g; - IndexMap m_index_map; - EdgeCapacityMap m_cap_map; - ResidualCapacityEdgeMap m_res_cap_map; - ReverseEdgeMap m_rev_edge_map; - PredecessorMap m_pre_map; //stores paths found in the growth stage - ColorMap m_tree_map; //maps each vertex into one of the two search tree or none (gray()) - DistanceMap m_dist_map; //stores distance to source/sink nodes - vertex_descriptor m_source; - vertex_descriptor m_sink; - - tQueue m_active_nodes; - std::vector m_in_active_list_vec; - iterator_property_map::iterator, IndexMap> m_in_active_list_map; - - std::list m_orphans; - tQueue m_child_orphans; // we use a second queuqe for child orphans, as they are FIFO processed - - std::vector m_has_parent_vec; - iterator_property_map::iterator, IndexMap> m_has_parent_map; - - std::vector m_time_vec; //timestamp of each node, used for sink/source-path calculations - iterator_property_map::iterator, IndexMap> m_time_map; - tEdgeVal m_flow; - long m_time; - vertex_descriptor m_last_grow_vertex; - out_edge_iterator m_last_grow_edge_it; - out_edge_iterator m_last_grow_edge_end; -}; - -} //namespace boost::detail + + /** + * checks if vertex v has a connect to the source-vertex (@var m_source) + * @param v the vertex which is checked + * @return true if a path to the source was found, false if not + */ + inline bool has_source_connect(vertex_descriptor v) + { + tDistanceVal current_distance = 0; + vertex_descriptor current_vertex = v; + while (true) + { + if (get(m_time_map, current_vertex) == m_time) + { + // we found a node which was already checked this round. use + // it for distance calculations + current_distance += get(m_dist_map, current_vertex); + break; + } + if (current_vertex == m_source) + { + put(m_time_map, m_source, m_time); + break; + } + if (has_parent(current_vertex)) + { + // it has a parent, so get it + current_vertex + = source(get_edge_to_parent(current_vertex), m_g); + ++current_distance; + } + else + { + // no path found + return false; + } + } + current_vertex = v; + while (get(m_time_map, current_vertex) != m_time) + { + put(m_dist_map, current_vertex, current_distance); + --current_distance; + put(m_time_map, current_vertex, m_time); + current_vertex + = source(get_edge_to_parent(current_vertex), m_g); + } + return true; + } + + /** + * returns true, if p is closer to a terminal than q + */ + inline bool is_closer_to_terminal( + vertex_descriptor p, vertex_descriptor q) + { + // checks the timestamps first, to build no cycles, and after that + // the real distance + return (get(m_time_map, q) <= get(m_time_map, p) + && get(m_dist_map, q) > get(m_dist_map, p) + 1); + } + + //////// + // member vars + //////// + Graph& m_g; + IndexMap m_index_map; + EdgeCapacityMap m_cap_map; + ResidualCapacityEdgeMap m_res_cap_map; + ReverseEdgeMap m_rev_edge_map; + PredecessorMap m_pre_map; // stores paths found in the growth stage + ColorMap m_tree_map; // maps each vertex into one of the two search tree + // or none (gray()) + DistanceMap m_dist_map; // stores distance to source/sink nodes + vertex_descriptor m_source; + vertex_descriptor m_sink; + + tQueue m_active_nodes; + std::vector< bool > m_in_active_list_vec; + iterator_property_map< std::vector< bool >::iterator, IndexMap > + m_in_active_list_map; + + std::list< vertex_descriptor > m_orphans; + tQueue m_child_orphans; // we use a second queuqe for child orphans, as + // they are FIFO processed + + std::vector< bool > m_has_parent_vec; + iterator_property_map< std::vector< bool >::iterator, IndexMap > + m_has_parent_map; + + std::vector< long > m_time_vec; // timestamp of each node, used for + // sink/source-path calculations + iterator_property_map< std::vector< long >::iterator, IndexMap > + m_time_map; + tEdgeVal m_flow; + long m_time; + vertex_descriptor m_last_grow_vertex; + out_edge_iterator m_last_grow_edge_it; + out_edge_iterator m_last_grow_edge_end; + }; + +} // namespace boost::detail /** - * non-named-parameter version, given everything - * this is the catch all version - */ -template -typename property_traits::value_type -boykov_kolmogorov_max_flow(Graph& g, - CapacityEdgeMap cap, - ResidualCapacityEdgeMap res_cap, - ReverseEdgeMap rev_map, - PredecessorMap pre_map, - ColorMap color, - DistanceMap dist, - IndexMap idx, - typename graph_traits::vertex_descriptor src, - typename graph_traits::vertex_descriptor sink) + * non-named-parameter version, given everything + * this is the catch all version + */ +template < class Graph, class CapacityEdgeMap, class ResidualCapacityEdgeMap, + class ReverseEdgeMap, class PredecessorMap, class ColorMap, + class DistanceMap, class IndexMap > +typename property_traits< CapacityEdgeMap >::value_type +boykov_kolmogorov_max_flow(Graph& g, CapacityEdgeMap cap, + ResidualCapacityEdgeMap res_cap, ReverseEdgeMap rev_map, + PredecessorMap pre_map, ColorMap color, DistanceMap dist, IndexMap idx, + typename graph_traits< Graph >::vertex_descriptor src, + typename graph_traits< Graph >::vertex_descriptor sink) { - typedef typename graph_traits::vertex_descriptor vertex_descriptor; - typedef typename graph_traits::edge_descriptor edge_descriptor; - - //as this method is the last one before we instantiate the solver, we do the concept checks here - BOOST_CONCEPT_ASSERT(( VertexListGraphConcept )); //to have vertices(), num_vertices(), - BOOST_CONCEPT_ASSERT(( EdgeListGraphConcept )); //to have edges() - BOOST_CONCEPT_ASSERT(( IncidenceGraphConcept )); //to have source(), target() and out_edges() - BOOST_CONCEPT_ASSERT(( ReadablePropertyMapConcept )); //read flow-values from edges - BOOST_CONCEPT_ASSERT(( ReadWritePropertyMapConcept )); //write flow-values to residuals - BOOST_CONCEPT_ASSERT(( ReadablePropertyMapConcept )); //read out reverse edges - BOOST_CONCEPT_ASSERT(( ReadWritePropertyMapConcept )); //store predecessor there - BOOST_CONCEPT_ASSERT(( ReadWritePropertyMapConcept )); //write corresponding tree - BOOST_CONCEPT_ASSERT(( ReadWritePropertyMapConcept )); //write distance to source/sink - BOOST_CONCEPT_ASSERT(( ReadablePropertyMapConcept )); //get index 0...|V|-1 - BOOST_ASSERT(num_vertices(g) >= 2 && src != sink); - - detail::bk_max_flow< - Graph, CapacityEdgeMap, ResidualCapacityEdgeMap, ReverseEdgeMap, - PredecessorMap, ColorMap, DistanceMap, IndexMap - > algo(g, cap, res_cap, rev_map, pre_map, color, dist, idx, src, sink); - - return algo.max_flow(); + typedef typename graph_traits< Graph >::vertex_descriptor vertex_descriptor; + typedef typename graph_traits< Graph >::edge_descriptor edge_descriptor; + + // as this method is the last one before we instantiate the solver, we do + // the concept checks here + BOOST_CONCEPT_ASSERT( + (VertexListGraphConcept< Graph >)); // to have vertices(), + // num_vertices(), + BOOST_CONCEPT_ASSERT((EdgeListGraphConcept< Graph >)); // to have edges() + BOOST_CONCEPT_ASSERT( + (IncidenceGraphConcept< Graph >)); // to have source(), target() and + // out_edges() + BOOST_CONCEPT_ASSERT((ReadablePropertyMapConcept< CapacityEdgeMap, + edge_descriptor >)); // read flow-values from edges + BOOST_CONCEPT_ASSERT((ReadWritePropertyMapConcept< ResidualCapacityEdgeMap, + edge_descriptor >)); // write flow-values to residuals + BOOST_CONCEPT_ASSERT((ReadablePropertyMapConcept< ReverseEdgeMap, + edge_descriptor >)); // read out reverse edges + BOOST_CONCEPT_ASSERT((ReadWritePropertyMapConcept< PredecessorMap, + vertex_descriptor >)); // store predecessor there + BOOST_CONCEPT_ASSERT((ReadWritePropertyMapConcept< ColorMap, + vertex_descriptor >)); // write corresponding tree + BOOST_CONCEPT_ASSERT((ReadWritePropertyMapConcept< DistanceMap, + vertex_descriptor >)); // write distance to source/sink + BOOST_CONCEPT_ASSERT((ReadablePropertyMapConcept< IndexMap, + vertex_descriptor >)); // get index 0...|V|-1 + BOOST_ASSERT(num_vertices(g) >= 2 && src != sink); + + detail::bk_max_flow< Graph, CapacityEdgeMap, ResidualCapacityEdgeMap, + ReverseEdgeMap, PredecessorMap, ColorMap, DistanceMap, IndexMap > + algo(g, cap, res_cap, rev_map, pre_map, color, dist, idx, src, sink); + + return algo.max_flow(); } /** * non-named-parameter version, given capacity, residucal_capacity, * reverse_edges, and an index map. */ -template -typename property_traits::value_type -boykov_kolmogorov_max_flow(Graph& g, - CapacityEdgeMap cap, - ResidualCapacityEdgeMap res_cap, - ReverseEdgeMap rev, - IndexMap idx, - typename graph_traits::vertex_descriptor src, - typename graph_traits::vertex_descriptor sink) +template < class Graph, class CapacityEdgeMap, class ResidualCapacityEdgeMap, + class ReverseEdgeMap, class IndexMap > +typename property_traits< CapacityEdgeMap >::value_type +boykov_kolmogorov_max_flow(Graph& g, CapacityEdgeMap cap, + ResidualCapacityEdgeMap res_cap, ReverseEdgeMap rev, IndexMap idx, + typename graph_traits< Graph >::vertex_descriptor src, + typename graph_traits< Graph >::vertex_descriptor sink) { - typename graph_traits::vertices_size_type n_verts = num_vertices(g); - std::vector::edge_descriptor> predecessor_vec(n_verts); - std::vector color_vec(n_verts); - std::vector::vertices_size_type> distance_vec(n_verts); - return - boykov_kolmogorov_max_flow( - g, cap, res_cap, rev, - make_iterator_property_map(predecessor_vec.begin(), idx), - make_iterator_property_map(color_vec.begin(), idx), - make_iterator_property_map(distance_vec.begin(), idx), - idx, src, sink); + typename graph_traits< Graph >::vertices_size_type n_verts + = num_vertices(g); + std::vector< typename graph_traits< Graph >::edge_descriptor > + predecessor_vec(n_verts); + std::vector< default_color_type > color_vec(n_verts); + std::vector< typename graph_traits< Graph >::vertices_size_type > + distance_vec(n_verts); + return boykov_kolmogorov_max_flow(g, cap, res_cap, rev, + make_iterator_property_map(predecessor_vec.begin(), idx), + make_iterator_property_map(color_vec.begin(), idx), + make_iterator_property_map(distance_vec.begin(), idx), idx, src, sink); } /** @@ -803,71 +1006,63 @@ boykov_kolmogorov_max_flow(Graph& g, * reverse_edges, color_map and an index map. Use this if you are interested in * the minimum cut, as the color map provides that info. */ -template -typename property_traits::value_type -boykov_kolmogorov_max_flow(Graph& g, - CapacityEdgeMap cap, - ResidualCapacityEdgeMap res_cap, - ReverseEdgeMap rev, - ColorMap color, - IndexMap idx, - typename graph_traits::vertex_descriptor src, - typename graph_traits::vertex_descriptor sink) +template < class Graph, class CapacityEdgeMap, class ResidualCapacityEdgeMap, + class ReverseEdgeMap, class ColorMap, class IndexMap > +typename property_traits< CapacityEdgeMap >::value_type +boykov_kolmogorov_max_flow(Graph& g, CapacityEdgeMap cap, + ResidualCapacityEdgeMap res_cap, ReverseEdgeMap rev, ColorMap color, + IndexMap idx, typename graph_traits< Graph >::vertex_descriptor src, + typename graph_traits< Graph >::vertex_descriptor sink) { - typename graph_traits::vertices_size_type n_verts = num_vertices(g); - std::vector::edge_descriptor> predecessor_vec(n_verts); - std::vector::vertices_size_type> distance_vec(n_verts); - return - boykov_kolmogorov_max_flow( - g, cap, res_cap, rev, - make_iterator_property_map(predecessor_vec.begin(), idx), - color, - make_iterator_property_map(distance_vec.begin(), idx), - idx, src, sink); + typename graph_traits< Graph >::vertices_size_type n_verts + = num_vertices(g); + std::vector< typename graph_traits< Graph >::edge_descriptor > + predecessor_vec(n_verts); + std::vector< typename graph_traits< Graph >::vertices_size_type > + distance_vec(n_verts); + return boykov_kolmogorov_max_flow(g, cap, res_cap, rev, + make_iterator_property_map(predecessor_vec.begin(), idx), color, + make_iterator_property_map(distance_vec.begin(), idx), idx, src, sink); } /** * named-parameter version, some given */ -template -typename property_traits::const_type>::value_type +template < class Graph, class P, class T, class R > +typename property_traits< + typename property_map< Graph, edge_capacity_t >::const_type >::value_type boykov_kolmogorov_max_flow(Graph& g, - typename graph_traits::vertex_descriptor src, - typename graph_traits::vertex_descriptor sink, - const bgl_named_params& params) + typename graph_traits< Graph >::vertex_descriptor src, + typename graph_traits< Graph >::vertex_descriptor sink, + const bgl_named_params< P, T, R >& params) { - return - boykov_kolmogorov_max_flow( - g, - choose_const_pmap(get_param(params, edge_capacity), g, edge_capacity), - choose_pmap(get_param(params, edge_residual_capacity), g, edge_residual_capacity), - choose_const_pmap(get_param(params, edge_reverse), g, edge_reverse), - choose_pmap(get_param(params, vertex_predecessor), g, vertex_predecessor), - choose_pmap(get_param(params, vertex_color), g, vertex_color), - choose_pmap(get_param(params, vertex_distance), g, vertex_distance), - choose_const_pmap(get_param(params, vertex_index), g, vertex_index), - src, sink); + return boykov_kolmogorov_max_flow(g, + choose_const_pmap(get_param(params, edge_capacity), g, edge_capacity), + choose_pmap(get_param(params, edge_residual_capacity), g, + edge_residual_capacity), + choose_const_pmap(get_param(params, edge_reverse), g, edge_reverse), + choose_pmap( + get_param(params, vertex_predecessor), g, vertex_predecessor), + choose_pmap(get_param(params, vertex_color), g, vertex_color), + choose_pmap(get_param(params, vertex_distance), g, vertex_distance), + choose_const_pmap(get_param(params, vertex_index), g, vertex_index), + src, sink); } /** * named-parameter version, none given */ -template -typename property_traits::const_type>::value_type +template < class Graph > +typename property_traits< + typename property_map< Graph, edge_capacity_t >::const_type >::value_type boykov_kolmogorov_max_flow(Graph& g, - typename graph_traits::vertex_descriptor src, - typename graph_traits::vertex_descriptor sink) + typename graph_traits< Graph >::vertex_descriptor src, + typename graph_traits< Graph >::vertex_descriptor sink) { - bgl_named_params params(0); // bogus empty param - return boykov_kolmogorov_max_flow(g, src, sink, params); + bgl_named_params< int, buffer_param_t > params(0); // bogus empty param + return boykov_kolmogorov_max_flow(g, src, sink, params); } } // namespace boost #endif // BOOST_BOYKOV_KOLMOGOROV_MAX_FLOW_HPP - diff --git a/include/boost/graph/breadth_first_search.hpp b/include/boost/graph/breadth_first_search.hpp index 620107674..e0525cd18 100644 --- a/include/boost/graph/breadth_first_search.hpp +++ b/include/boost/graph/breadth_first_search.hpp @@ -27,248 +27,251 @@ #include #include -#include BOOST_GRAPH_MPI_INCLUDE() - -namespace boost { - - template - struct BFSVisitorConcept { - void constraints() { - BOOST_CONCEPT_ASSERT(( CopyConstructibleConcept )); - vis.initialize_vertex(u, g); - vis.discover_vertex(u, g); - vis.examine_vertex(u, g); - vis.examine_edge(e, g); - vis.tree_edge(e, g); - vis.non_tree_edge(e, g); - vis.gray_target(e, g); - vis.black_target(e, g); - vis.finish_vertex(u, g); +#include BOOST_GRAPH_MPI_INCLUDE(< boost / graph / distributed / concepts.hpp >) + +namespace boost +{ + +template < class Visitor, class Graph > struct BFSVisitorConcept +{ + void constraints() + { + BOOST_CONCEPT_ASSERT((CopyConstructibleConcept< Visitor >)); + vis.initialize_vertex(u, g); + vis.discover_vertex(u, g); + vis.examine_vertex(u, g); + vis.examine_edge(e, g); + vis.tree_edge(e, g); + vis.non_tree_edge(e, g); + vis.gray_target(e, g); + vis.black_target(e, g); + vis.finish_vertex(u, g); } Visitor vis; Graph g; - typename graph_traits::vertex_descriptor u; - typename graph_traits::edge_descriptor e; - }; - - - // Multiple-source version - template - void breadth_first_visit - (const IncidenceGraph& g, - SourceIterator sources_begin, SourceIterator sources_end, - Buffer& Q, BFSVisitor vis, ColorMap color) - { - BOOST_CONCEPT_ASSERT(( IncidenceGraphConcept )); - typedef graph_traits GTraits; + typename graph_traits< Graph >::vertex_descriptor u; + typename graph_traits< Graph >::edge_descriptor e; +}; + +// Multiple-source version +template < class IncidenceGraph, class Buffer, class BFSVisitor, class ColorMap, + class SourceIterator > +void breadth_first_visit(const IncidenceGraph& g, SourceIterator sources_begin, + SourceIterator sources_end, Buffer& Q, BFSVisitor vis, ColorMap color) +{ + BOOST_CONCEPT_ASSERT((IncidenceGraphConcept< IncidenceGraph >)); + typedef graph_traits< IncidenceGraph > GTraits; typedef typename GTraits::vertex_descriptor Vertex; - BOOST_CONCEPT_ASSERT(( BFSVisitorConcept )); - BOOST_CONCEPT_ASSERT(( ReadWritePropertyMapConcept )); - typedef typename property_traits::value_type ColorValue; - typedef color_traits Color; + BOOST_CONCEPT_ASSERT((BFSVisitorConcept< BFSVisitor, IncidenceGraph >)); + BOOST_CONCEPT_ASSERT((ReadWritePropertyMapConcept< ColorMap, Vertex >)); + typedef typename property_traits< ColorMap >::value_type ColorValue; + typedef color_traits< ColorValue > Color; typename GTraits::out_edge_iterator ei, ei_end; - for (; sources_begin != sources_end; ++sources_begin) { - Vertex s = *sources_begin; - put(color, s, Color::gray()); vis.discover_vertex(s, g); - Q.push(s); + for (; sources_begin != sources_end; ++sources_begin) + { + Vertex s = *sources_begin; + put(color, s, Color::gray()); + vis.discover_vertex(s, g); + Q.push(s); } - while (! Q.empty()) { - Vertex u = Q.top(); Q.pop(); vis.examine_vertex(u, g); - for (boost::tie(ei, ei_end) = out_edges(u, g); ei != ei_end; ++ei) { - Vertex v = target(*ei, g); vis.examine_edge(*ei, g); - ColorValue v_color = get(color, v); - if (v_color == Color::white()) { vis.tree_edge(*ei, g); - put(color, v, Color::gray()); vis.discover_vertex(v, g); - Q.push(v); - } else { vis.non_tree_edge(*ei, g); - if (v_color == Color::gray()) vis.gray_target(*ei, g); - else vis.black_target(*ei, g); - } - } // end for - put(color, u, Color::black()); vis.finish_vertex(u, g); + while (!Q.empty()) + { + Vertex u = Q.top(); + Q.pop(); + vis.examine_vertex(u, g); + for (boost::tie(ei, ei_end) = out_edges(u, g); ei != ei_end; ++ei) + { + Vertex v = target(*ei, g); + vis.examine_edge(*ei, g); + ColorValue v_color = get(color, v); + if (v_color == Color::white()) + { + vis.tree_edge(*ei, g); + put(color, v, Color::gray()); + vis.discover_vertex(v, g); + Q.push(v); + } + else + { + vis.non_tree_edge(*ei, g); + if (v_color == Color::gray()) + vis.gray_target(*ei, g); + else + vis.black_target(*ei, g); + } + } // end for + put(color, u, Color::black()); + vis.finish_vertex(u, g); } // end while - } // breadth_first_visit - - // Single-source version - template - void breadth_first_visit - (const IncidenceGraph& g, - typename graph_traits::vertex_descriptor s, - Buffer& Q, BFSVisitor vis, ColorMap color) - { - typename graph_traits::vertex_descriptor sources[1] = {s}; +} // breadth_first_visit + +// Single-source version +template < class IncidenceGraph, class Buffer, class BFSVisitor, + class ColorMap > +void breadth_first_visit(const IncidenceGraph& g, + typename graph_traits< IncidenceGraph >::vertex_descriptor s, Buffer& Q, + BFSVisitor vis, ColorMap color) +{ + typename graph_traits< IncidenceGraph >::vertex_descriptor sources[1] + = { s }; breadth_first_visit(g, sources, sources + 1, Q, vis, color); - } - - - template - void breadth_first_search - (const VertexListGraph& g, - SourceIterator sources_begin, SourceIterator sources_end, - Buffer& Q, BFSVisitor vis, ColorMap color) - { +} + +template < class VertexListGraph, class SourceIterator, class Buffer, + class BFSVisitor, class ColorMap > +void breadth_first_search(const VertexListGraph& g, + SourceIterator sources_begin, SourceIterator sources_end, Buffer& Q, + BFSVisitor vis, ColorMap color) +{ // Initialization - typedef typename property_traits::value_type ColorValue; - typedef color_traits Color; - typename boost::graph_traits::vertex_iterator i, i_end; - for (boost::tie(i, i_end) = vertices(g); i != i_end; ++i) { - vis.initialize_vertex(*i, g); - put(color, *i, Color::white()); + typedef typename property_traits< ColorMap >::value_type ColorValue; + typedef color_traits< ColorValue > Color; + typename boost::graph_traits< VertexListGraph >::vertex_iterator i, i_end; + for (boost::tie(i, i_end) = vertices(g); i != i_end; ++i) + { + vis.initialize_vertex(*i, g); + put(color, *i, Color::white()); } breadth_first_visit(g, sources_begin, sources_end, Q, vis, color); - } - - template - void breadth_first_search - (const VertexListGraph& g, - typename graph_traits::vertex_descriptor s, - Buffer& Q, BFSVisitor vis, ColorMap color) - { - typename graph_traits::vertex_descriptor sources[1] = {s}; +} + +template < class VertexListGraph, class Buffer, class BFSVisitor, + class ColorMap > +void breadth_first_search(const VertexListGraph& g, + typename graph_traits< VertexListGraph >::vertex_descriptor s, Buffer& Q, + BFSVisitor vis, ColorMap color) +{ + typename graph_traits< VertexListGraph >::vertex_descriptor sources[1] + = { s }; breadth_first_search(g, sources, sources + 1, Q, vis, color); - } - - namespace graph { struct bfs_visitor_event_not_overridden {}; } +} +namespace graph +{ + struct bfs_visitor_event_not_overridden + { + }; +} - template - class bfs_visitor { - public: - bfs_visitor() { } - bfs_visitor(Visitors vis) : m_vis(vis) { } +template < class Visitors = null_visitor > class bfs_visitor +{ +public: + bfs_visitor() {} + bfs_visitor(Visitors vis) : m_vis(vis) {} - template - graph::bfs_visitor_event_not_overridden - initialize_vertex(Vertex u, Graph& g) + template < class Vertex, class Graph > + graph::bfs_visitor_event_not_overridden initialize_vertex( + Vertex u, Graph& g) { - invoke_visitors(m_vis, u, g, ::boost::on_initialize_vertex()); - return graph::bfs_visitor_event_not_overridden(); + invoke_visitors(m_vis, u, g, ::boost::on_initialize_vertex()); + return graph::bfs_visitor_event_not_overridden(); } - template - graph::bfs_visitor_event_not_overridden - discover_vertex(Vertex u, Graph& g) + template < class Vertex, class Graph > + graph::bfs_visitor_event_not_overridden discover_vertex(Vertex u, Graph& g) { - invoke_visitors(m_vis, u, g, ::boost::on_discover_vertex()); - return graph::bfs_visitor_event_not_overridden(); + invoke_visitors(m_vis, u, g, ::boost::on_discover_vertex()); + return graph::bfs_visitor_event_not_overridden(); } - template - graph::bfs_visitor_event_not_overridden - examine_vertex(Vertex u, Graph& g) + template < class Vertex, class Graph > + graph::bfs_visitor_event_not_overridden examine_vertex(Vertex u, Graph& g) { - invoke_visitors(m_vis, u, g, ::boost::on_examine_vertex()); - return graph::bfs_visitor_event_not_overridden(); + invoke_visitors(m_vis, u, g, ::boost::on_examine_vertex()); + return graph::bfs_visitor_event_not_overridden(); } - template - graph::bfs_visitor_event_not_overridden - examine_edge(Edge e, Graph& g) + template < class Edge, class Graph > + graph::bfs_visitor_event_not_overridden examine_edge(Edge e, Graph& g) { - invoke_visitors(m_vis, e, g, ::boost::on_examine_edge()); - return graph::bfs_visitor_event_not_overridden(); + invoke_visitors(m_vis, e, g, ::boost::on_examine_edge()); + return graph::bfs_visitor_event_not_overridden(); } - template - graph::bfs_visitor_event_not_overridden - tree_edge(Edge e, Graph& g) + template < class Edge, class Graph > + graph::bfs_visitor_event_not_overridden tree_edge(Edge e, Graph& g) { - invoke_visitors(m_vis, e, g, ::boost::on_tree_edge()); - return graph::bfs_visitor_event_not_overridden(); + invoke_visitors(m_vis, e, g, ::boost::on_tree_edge()); + return graph::bfs_visitor_event_not_overridden(); } - template - graph::bfs_visitor_event_not_overridden - non_tree_edge(Edge e, Graph& g) + template < class Edge, class Graph > + graph::bfs_visitor_event_not_overridden non_tree_edge(Edge e, Graph& g) { - invoke_visitors(m_vis, e, g, ::boost::on_non_tree_edge()); - return graph::bfs_visitor_event_not_overridden(); + invoke_visitors(m_vis, e, g, ::boost::on_non_tree_edge()); + return graph::bfs_visitor_event_not_overridden(); } - template - graph::bfs_visitor_event_not_overridden - gray_target(Edge e, Graph& g) + template < class Edge, class Graph > + graph::bfs_visitor_event_not_overridden gray_target(Edge e, Graph& g) { - invoke_visitors(m_vis, e, g, ::boost::on_gray_target()); - return graph::bfs_visitor_event_not_overridden(); + invoke_visitors(m_vis, e, g, ::boost::on_gray_target()); + return graph::bfs_visitor_event_not_overridden(); } - template - graph::bfs_visitor_event_not_overridden - black_target(Edge e, Graph& g) + template < class Edge, class Graph > + graph::bfs_visitor_event_not_overridden black_target(Edge e, Graph& g) { - invoke_visitors(m_vis, e, g, ::boost::on_black_target()); - return graph::bfs_visitor_event_not_overridden(); + invoke_visitors(m_vis, e, g, ::boost::on_black_target()); + return graph::bfs_visitor_event_not_overridden(); } - template - graph::bfs_visitor_event_not_overridden - finish_vertex(Vertex u, Graph& g) + template < class Vertex, class Graph > + graph::bfs_visitor_event_not_overridden finish_vertex(Vertex u, Graph& g) { - invoke_visitors(m_vis, u, g, ::boost::on_finish_vertex()); - return graph::bfs_visitor_event_not_overridden(); + invoke_visitors(m_vis, u, g, ::boost::on_finish_vertex()); + return graph::bfs_visitor_event_not_overridden(); } - BOOST_GRAPH_EVENT_STUB(on_initialize_vertex,bfs) - BOOST_GRAPH_EVENT_STUB(on_discover_vertex,bfs) - BOOST_GRAPH_EVENT_STUB(on_examine_vertex,bfs) - BOOST_GRAPH_EVENT_STUB(on_examine_edge,bfs) - BOOST_GRAPH_EVENT_STUB(on_tree_edge,bfs) - BOOST_GRAPH_EVENT_STUB(on_non_tree_edge,bfs) - BOOST_GRAPH_EVENT_STUB(on_gray_target,bfs) - BOOST_GRAPH_EVENT_STUB(on_black_target,bfs) - BOOST_GRAPH_EVENT_STUB(on_finish_vertex,bfs) - - protected: + BOOST_GRAPH_EVENT_STUB(on_initialize_vertex, bfs) + BOOST_GRAPH_EVENT_STUB(on_discover_vertex, bfs) + BOOST_GRAPH_EVENT_STUB(on_examine_vertex, bfs) + BOOST_GRAPH_EVENT_STUB(on_examine_edge, bfs) + BOOST_GRAPH_EVENT_STUB(on_tree_edge, bfs) + BOOST_GRAPH_EVENT_STUB(on_non_tree_edge, bfs) + BOOST_GRAPH_EVENT_STUB(on_gray_target, bfs) + BOOST_GRAPH_EVENT_STUB(on_black_target, bfs) + BOOST_GRAPH_EVENT_STUB(on_finish_vertex, bfs) + +protected: Visitors m_vis; - }; - template - bfs_visitor - make_bfs_visitor(Visitors vis) { - return bfs_visitor(vis); - } - typedef bfs_visitor<> default_bfs_visitor; - - - namespace detail { - - template - void bfs_helper - (VertexListGraph& g, - typename graph_traits::vertex_descriptor s, - ColorMap color, - BFSVisitor vis, - const bgl_named_params& params, - boost::mpl::false_) +}; +template < class Visitors > +bfs_visitor< Visitors > make_bfs_visitor(Visitors vis) +{ + return bfs_visitor< Visitors >(vis); +} +typedef bfs_visitor<> default_bfs_visitor; + +namespace detail +{ + + template < class VertexListGraph, class ColorMap, class BFSVisitor, class P, + class T, class R > + void bfs_helper(VertexListGraph& g, + typename graph_traits< VertexListGraph >::vertex_descriptor s, + ColorMap color, BFSVisitor vis, + const bgl_named_params< P, T, R >& params, boost::mpl::false_) { - typedef graph_traits Traits; - // Buffer default - typedef typename Traits::vertex_descriptor Vertex; - typedef boost::queue queue_t; - queue_t Q; - breadth_first_search - (g, s, - choose_param(get_param(params, buffer_param_t()), boost::ref(Q)).get(), - vis, color); + typedef graph_traits< VertexListGraph > Traits; + // Buffer default + typedef typename Traits::vertex_descriptor Vertex; + typedef boost::queue< Vertex > queue_t; + queue_t Q; + breadth_first_search(g, s, + choose_param(get_param(params, buffer_param_t()), boost::ref(Q)) + .get(), + vis, color); } #ifdef BOOST_GRAPH_USE_MPI - template - void bfs_helper - (DistributedGraph& g, - typename graph_traits::vertex_descriptor s, - ColorMap color, - BFSVisitor vis, - const bgl_named_params& params, - boost::mpl::true_); + template < class DistributedGraph, class ColorMap, class BFSVisitor, + class P, class T, class R > + void bfs_helper(DistributedGraph& g, + typename graph_traits< DistributedGraph >::vertex_descriptor s, + ColorMap color, BFSVisitor vis, + const bgl_named_params< P, T, R >& params, boost::mpl::true_); #endif // BOOST_GRAPH_USE_MPI //------------------------------------------------------------------------- @@ -276,126 +279,122 @@ namespace boost { // function dispatching so that we don't require vertex index if // the color default is not being used. - template - struct bfs_dispatch { - template - static void apply - (VertexListGraph& g, - typename graph_traits::vertex_descriptor s, - const bgl_named_params& params, - ColorMap color) - { - bfs_helper - (g, s, color, - choose_param(get_param(params, graph_visitor), - make_bfs_visitor(null_visitor())), - params, - boost::mpl::bool_< - boost::is_base_and_derived< - distributed_graph_tag, - typename graph_traits::traversal_category>::value>()); - } + template < class ColorMap > struct bfs_dispatch + { + template < class VertexListGraph, class P, class T, class R > + static void apply(VertexListGraph& g, + typename graph_traits< VertexListGraph >::vertex_descriptor s, + const bgl_named_params< P, T, R >& params, ColorMap color) + { + bfs_helper(g, s, color, + choose_param(get_param(params, graph_visitor), + make_bfs_visitor(null_visitor())), + params, + boost::mpl::bool_< + boost::is_base_and_derived< distributed_graph_tag, + typename graph_traits< + VertexListGraph >::traversal_category >::value >()); + } }; - template <> - struct bfs_dispatch { - template - static void apply - (VertexListGraph& g, - typename graph_traits::vertex_descriptor s, - const bgl_named_params& params, - param_not_found) - { - null_visitor null_vis; - - bfs_helper - (g, s, - make_two_bit_color_map - (num_vertices(g), - choose_const_pmap(get_param(params, vertex_index), - g, vertex_index)), - choose_param(get_param(params, graph_visitor), - make_bfs_visitor(null_vis)), - params, - boost::mpl::bool_< - boost::is_base_and_derived< - distributed_graph_tag, - typename graph_traits::traversal_category>::value>()); - } + template <> struct bfs_dispatch< param_not_found > + { + template < class VertexListGraph, class P, class T, class R > + static void apply(VertexListGraph& g, + typename graph_traits< VertexListGraph >::vertex_descriptor s, + const bgl_named_params< P, T, R >& params, param_not_found) + { + null_visitor null_vis; + + bfs_helper(g, s, + make_two_bit_color_map(num_vertices(g), + choose_const_pmap( + get_param(params, vertex_index), g, vertex_index)), + choose_param(get_param(params, graph_visitor), + make_bfs_visitor(null_vis)), + params, + boost::mpl::bool_< + boost::is_base_and_derived< distributed_graph_tag, + typename graph_traits< + VertexListGraph >::traversal_category >::value >()); + } }; - } // namespace detail +} // namespace detail #if 1 - // Named Parameter Variant - template - void breadth_first_search - (const VertexListGraph& g, - typename graph_traits::vertex_descriptor s, - const bgl_named_params& params) - { +// Named Parameter Variant +template < class VertexListGraph, class P, class T, class R > +void breadth_first_search(const VertexListGraph& g, + typename graph_traits< VertexListGraph >::vertex_descriptor s, + const bgl_named_params< P, T, R >& params) +{ // The graph is passed by *const* reference so that graph adaptors // (temporaries) can be passed into this function. However, the // graph is not really const since we may write to property maps // of the graph. - VertexListGraph& ng = const_cast(g); - typedef typename get_param_type< vertex_color_t, bgl_named_params >::type C; - detail::bfs_dispatch::apply(ng, s, params, - get_param(params, vertex_color)); - } + VertexListGraph& ng = const_cast< VertexListGraph& >(g); + typedef typename get_param_type< vertex_color_t, + bgl_named_params< P, T, R > >::type C; + detail::bfs_dispatch< C >::apply( + ng, s, params, get_param(params, vertex_color)); +} #endif +// This version does not initialize colors, user has to. - // This version does not initialize colors, user has to. - - template - void breadth_first_visit - (const IncidenceGraph& g, - typename graph_traits::vertex_descriptor s, - const bgl_named_params& params) - { +template < class IncidenceGraph, class P, class T, class R > +void breadth_first_visit(const IncidenceGraph& g, + typename graph_traits< IncidenceGraph >::vertex_descriptor s, + const bgl_named_params< P, T, R >& params) +{ // The graph is passed by *const* reference so that graph adaptors // (temporaries) can be passed into this function. However, the // graph is not really const since we may write to property maps // of the graph. - IncidenceGraph& ng = const_cast(g); + IncidenceGraph& ng = const_cast< IncidenceGraph& >(g); - typedef graph_traits Traits; + typedef graph_traits< IncidenceGraph > Traits; // Buffer default typedef typename Traits::vertex_descriptor vertex_descriptor; - typedef boost::queue queue_t; + typedef boost::queue< vertex_descriptor > queue_t; queue_t Q; - breadth_first_visit - (ng, s, - choose_param(get_param(params, buffer_param_t()), boost::ref(Q)).get(), - choose_param(get_param(params, graph_visitor), - make_bfs_visitor(null_visitor())), - choose_pmap(get_param(params, vertex_color), ng, vertex_color) - ); - } - - namespace graph { - namespace detail { - template - struct breadth_first_search_impl { - typedef void result_type; - template - void operator()(const Graph& g, const Source& source, const ArgPack& arg_pack) { - using namespace boost::graph::keywords; - typename boost::graph_traits::vertex_descriptor sources[1] = {source}; - boost::queue::vertex_descriptor> Q; - boost::breadth_first_search(g, - &sources[0], - &sources[1], - boost::unwrap_ref(arg_pack[_buffer | boost::ref(Q)]), - arg_pack[_visitor | make_bfs_visitor(null_visitor())], - boost::detail::make_color_map_from_arg_pack(g, arg_pack)); - } - }; + breadth_first_visit(ng, s, + choose_param(get_param(params, buffer_param_t()), boost::ref(Q)).get(), + choose_param( + get_param(params, graph_visitor), make_bfs_visitor(null_visitor())), + choose_pmap(get_param(params, vertex_color), ng, vertex_color)); +} + +namespace graph +{ + namespace detail + { + template < typename Graph, typename Source > + struct breadth_first_search_impl + { + typedef void result_type; + template < typename ArgPack > + void operator()( + const Graph& g, const Source& source, const ArgPack& arg_pack) + { + using namespace boost::graph::keywords; + typename boost::graph_traits< Graph >::vertex_descriptor + sources[1] + = { source }; + boost::queue< + typename boost::graph_traits< Graph >::vertex_descriptor > + Q; + boost::breadth_first_search(g, &sources[0], &sources[1], + boost::unwrap_ref(arg_pack[_buffer | boost::ref(Q)]), + arg_pack[_visitor | make_bfs_visitor(null_visitor())], + boost::detail::make_color_map_from_arg_pack(g, arg_pack)); + } + }; } BOOST_GRAPH_MAKE_FORWARDING_FUNCTION(breadth_first_search, 2, 4) - } +} #if 0 // Named Parameter Variant @@ -404,7 +403,6 @@ namespace boost { } // namespace boost -#include BOOST_GRAPH_MPI_INCLUDE() +#include BOOST_GRAPH_MPI_INCLUDE(< boost / graph / distributed / breadth_first_search.hpp >) #endif // BOOST_GRAPH_BREADTH_FIRST_SEARCH_HPP - diff --git a/include/boost/graph/bron_kerbosch_all_cliques.hpp b/include/boost/graph/bron_kerbosch_all_cliques.hpp index 1dcc04975..e0f862e83 100644 --- a/include/boost/graph/bron_kerbosch_all_cliques.hpp +++ b/include/boost/graph/bron_kerbosch_all_cliques.hpp @@ -17,20 +17,20 @@ #include #include -namespace boost { - namespace concepts { - BOOST_concept(CliqueVisitor,(Visitor)(Clique)(Graph)) - { - BOOST_CONCEPT_USAGE(CliqueVisitor) - { - vis.clique(k, g); - } - private: - Visitor vis; - Graph g; - Clique k; - }; - } /* namespace concepts */ +namespace boost +{ +namespace concepts +{ + BOOST_concept(CliqueVisitor, (Visitor)(Clique)(Graph)) + { + BOOST_CONCEPT_USAGE(CliqueVisitor) { vis.clique(k, g); } + + private: + Visitor vis; + Graph g; + Clique k; + }; +} /* namespace concepts */ using concepts::CliqueVisitorConcept; } /* namespace boost */ #include @@ -78,12 +78,9 @@ namespace boost // // @article{DBLP:journals/tcs/TomitaTT06, // author = {Etsuji Tomita and Akira Tanaka and Haruhisa Takahashi}, -// title = {The worst-case time complexity for generating all maximal cliques and computational experiments}, -// journal = {Theor. Comput. Sci.}, -// volume = {363}, -// number = {1}, -// year = {2006}, -// pages = {28-42} +// title = {The worst-case time complexity for generating all maximal +// cliques and computational experiments}, journal = {Theor. Comput. +// Sci.}, volume = {363}, number = {1}, year = {2006}, pages = {28-42} // ee = {https://doi.org/10.1016/j.tcs.2006.06.015} // } @@ -92,9 +89,10 @@ namespace boost */ struct clique_visitor { - template + template < typename VertexSet, typename Graph > void clique(const VertexSet&, Graph&) - { } + { + } }; /** @@ -103,40 +101,38 @@ struct clique_visitor */ struct max_clique_visitor { - max_clique_visitor(std::size_t& max) - : maximum(max) - { } + max_clique_visitor(std::size_t& max) : maximum(max) {} - template + template < typename Clique, typename Graph > inline void clique(const Clique& p, const Graph& g) { BOOST_USING_STD_MAX(); - maximum = max BOOST_PREVENT_MACRO_SUBSTITUTION (maximum, p.size()); + maximum = max BOOST_PREVENT_MACRO_SUBSTITUTION(maximum, p.size()); } std::size_t& maximum; }; inline max_clique_visitor find_max_clique(std::size_t& max) -{ return max_clique_visitor(max); } +{ + return max_clique_visitor(max); +} namespace detail { - template - inline bool - is_connected_to_clique(const Graph& g, - typename graph_traits::vertex_descriptor u, - typename graph_traits::vertex_descriptor v, - typename graph_traits::undirected_category) + template < typename Graph > + inline bool is_connected_to_clique(const Graph& g, + typename graph_traits< Graph >::vertex_descriptor u, + typename graph_traits< Graph >::vertex_descriptor v, + typename graph_traits< Graph >::undirected_category) { return lookup_edge(u, v, g).second; } - template - inline bool - is_connected_to_clique(const Graph& g, - typename graph_traits::vertex_descriptor u, - typename graph_traits::vertex_descriptor v, - typename graph_traits::directed_category) + template < typename Graph > + inline bool is_connected_to_clique(const Graph& g, + typename graph_traits< Graph >::vertex_descriptor u, + typename graph_traits< Graph >::vertex_descriptor v, + typename graph_traits< Graph >::directed_category) { // Note that this could alternate between using an || to determine // full connectivity. I believe that this should produce strongly @@ -146,39 +142,34 @@ namespace detail return lookup_edge(u, v, g).second && lookup_edge(v, u, g).second; } - template - inline void - filter_unconnected_vertices(const Graph& g, - typename graph_traits::vertex_descriptor v, - const Container& in, - Container& out) + template < typename Graph, typename Container > + inline void filter_unconnected_vertices(const Graph& g, + typename graph_traits< Graph >::vertex_descriptor v, + const Container& in, Container& out) { - BOOST_CONCEPT_ASSERT(( GraphConcept )); + BOOST_CONCEPT_ASSERT((GraphConcept< Graph >)); - typename graph_traits::directed_category cat; + typename graph_traits< Graph >::directed_category cat; typename Container::const_iterator i, end = in.end(); - for(i = in.begin(); i != end; ++i) { - if(is_connected_to_clique(g, v, *i, cat)) { + for (i = in.begin(); i != end; ++i) + { + if (is_connected_to_clique(g, v, *i, cat)) + { out.push_back(*i); } } } - template < - typename Graph, - typename Clique, // compsub type - typename Container, // candidates/not type - typename Visitor> - void extend_clique(const Graph& g, - Clique& clique, - Container& cands, - Container& nots, - Visitor vis, - std::size_t min) + template < typename Graph, + typename Clique, // compsub type + typename Container, // candidates/not type + typename Visitor > + void extend_clique(const Graph& g, Clique& clique, Container& cands, + Container& nots, Visitor vis, std::size_t min) { - BOOST_CONCEPT_ASSERT(( GraphConcept )); - BOOST_CONCEPT_ASSERT(( CliqueVisitorConcept )); - typedef typename graph_traits::vertex_descriptor Vertex; + BOOST_CONCEPT_ASSERT((GraphConcept< Graph >)); + BOOST_CONCEPT_ASSERT((CliqueVisitorConcept< Visitor, Clique, Graph >)); + typedef typename graph_traits< Graph >::vertex_descriptor Vertex; // Is there vertex in nots that is connected to all vertices // in the candidate set? If so, no clique can ever be found. @@ -186,17 +177,22 @@ namespace detail { typename Container::iterator ni, nend = nots.end(); typename Container::iterator ci, cend = cands.end(); - for(ni = nots.begin(); ni != nend; ++ni) { - for(ci = cands.begin(); ci != cend; ++ci) { + for (ni = nots.begin(); ni != nend; ++ni) + { + for (ci = cands.begin(); ci != cend; ++ci) + { // if we don't find an edge, then we're okay. - if(!lookup_edge(*ni, *ci, g).second) break; + if (!lookup_edge(*ni, *ci, g).second) + break; } // if we iterated all the way to the end, then *ni // is connected to all *ci - if(ci == cend) break; + if (ci == cend) + break; } // if we broke early, we found *ni connected to all *ci - if(ni != nend) return; + if (ni != nend) + return; } // TODO: the original algorithm 457 describes an alternative @@ -225,11 +221,13 @@ namespace detail // otherwise, iterate over candidates and and test // for maxmimal cliquiness. typename Container::iterator i, j; - for(i = cands.begin(); i != cands.end(); ) { + for (i = cands.begin(); i != cands.end();) + { Vertex candidate = *i; // add the candidate to the clique (keeping the iterator!) - // typename Clique::iterator ci = clique.insert(clique.end(), candidate); + // typename Clique::iterator ci = clique.insert(clique.end(), + // candidate); clique.push_back(candidate); // remove it from the candidate set @@ -243,15 +241,18 @@ namespace detail filter_unconnected_vertices(g, candidate, cands, new_cands); filter_unconnected_vertices(g, candidate, nots, new_nots); - if(new_cands.empty() && new_nots.empty()) { + if (new_cands.empty() && new_nots.empty()) + { // our current clique is maximal since there's nothing // that's connected that we haven't already visited. If // the clique is below our radar, then we won't visit it. - if(clique.size() >= min) { + if (clique.size() >= min) + { vis.clique(clique, g); } } - else { + else + { // recurse to explore the new candidates extend_clique(g, clique, new_cands, new_nots, vis, min); } @@ -264,41 +265,42 @@ namespace detail } } /* namespace detail */ -template -inline void -bron_kerbosch_all_cliques(const Graph& g, Visitor vis, std::size_t min) +template < typename Graph, typename Visitor > +inline void bron_kerbosch_all_cliques( + const Graph& g, Visitor vis, std::size_t min) { - BOOST_CONCEPT_ASSERT(( IncidenceGraphConcept )); - BOOST_CONCEPT_ASSERT(( VertexListGraphConcept )); - BOOST_CONCEPT_ASSERT(( AdjacencyMatrixConcept )); // Structural requirement only - typedef typename graph_traits::vertex_descriptor Vertex; - typedef typename graph_traits::vertex_iterator VertexIterator; - typedef std::vector VertexSet; - typedef std::deque Clique; - BOOST_CONCEPT_ASSERT(( CliqueVisitorConcept )); + BOOST_CONCEPT_ASSERT((IncidenceGraphConcept< Graph >)); + BOOST_CONCEPT_ASSERT((VertexListGraphConcept< Graph >)); + BOOST_CONCEPT_ASSERT( + (AdjacencyMatrixConcept< Graph >)); // Structural requirement only + typedef typename graph_traits< Graph >::vertex_descriptor Vertex; + typedef typename graph_traits< Graph >::vertex_iterator VertexIterator; + typedef std::vector< Vertex > VertexSet; + typedef std::deque< Vertex > Clique; + BOOST_CONCEPT_ASSERT((CliqueVisitorConcept< Visitor, Clique, Graph >)); // NOTE: We're using a deque to implement the clique, because it provides // constant inserts and removals at the end and also a constant size. VertexIterator i, end; boost::tie(i, end) = vertices(g); - VertexSet cands(i, end); // start with all vertices as candidates - VertexSet nots; // start with no vertices visited + VertexSet cands(i, end); // start with all vertices as candidates + VertexSet nots; // start with no vertices visited - Clique clique; // the first clique is an empty vertex set + Clique clique; // the first clique is an empty vertex set detail::extend_clique(g, clique, cands, nots, vis, min); } // NOTE: By default the minimum number of vertices per clique is set at 2 // because singleton cliques aren't really very interesting. -template -inline void -bron_kerbosch_all_cliques(const Graph& g, Visitor vis) -{ bron_kerbosch_all_cliques(g, vis, 2); } - -template -inline std::size_t -bron_kerbosch_clique_number(const Graph& g) +template < typename Graph, typename Visitor > +inline void bron_kerbosch_all_cliques(const Graph& g, Visitor vis) +{ + bron_kerbosch_all_cliques(g, vis, 2); +} + +template < typename Graph > +inline std::size_t bron_kerbosch_clique_number(const Graph& g) { std::size_t ret = 0; bron_kerbosch_all_cliques(g, find_max_clique(ret)); diff --git a/include/boost/graph/buffer_concepts.hpp b/include/boost/graph/buffer_concepts.hpp index 233a7206b..1eb48abcf 100644 --- a/include/boost/graph/buffer_concepts.hpp +++ b/include/boost/graph/buffer_concepts.hpp @@ -13,78 +13,83 @@ #include #include -namespace boost { +namespace boost +{ - BOOST_concept(Buffer, (B)) - { +BOOST_concept(Buffer, (B)) +{ typedef typename B::value_type value_type; typedef typename B::size_type size_type; - - BOOST_CONCEPT_USAGE(Buffer) { - typedef typename boost::add_reference::type reference; - - BOOST_CONCEPT_ASSERT((Assignable)); - - buf.push(g_ct); - buf.pop(); - reference t = buf.top(); - boost::ignore_unused_variable_warning(t); + + BOOST_CONCEPT_USAGE(Buffer) + { + typedef typename boost::add_reference< value_type >::type reference; + + BOOST_CONCEPT_ASSERT((Assignable< value_type >)); + + buf.push(g_ct); + buf.pop(); + reference t = buf.top(); + boost::ignore_unused_variable_warning(t); } - - void const_constraints(const B& cbuf) { - typedef typename boost::add_const::type>::type& const_reference; - - const_reference ct = cbuf.top(); - s = cbuf.size(); - if (cbuf.empty()) - dummy = __LINE__; + + void const_constraints(const B& cbuf) + { + typedef typename boost::add_const< + typename boost::remove_reference< value_type >::type >::type& + const_reference; + + const_reference ct = cbuf.top(); + s = cbuf.size(); + if (cbuf.empty()) + dummy = __LINE__; } - + int dummy; - + static const value_type g_ct; size_type s; B buf; - }; - - BOOST_concept(UpdatableQueue, (Q)) - : Buffer - { - BOOST_CONCEPT_USAGE(UpdatableQueue) { - q.update(g_ct); - } - - void const_constraints(const Q& cq) { - if (cq.contains(g_ct)) - dummy = __LINE__; +}; + +BOOST_concept(UpdatableQueue, (Q)) : Buffer< Q > +{ + BOOST_CONCEPT_USAGE(UpdatableQueue) { q.update(g_ct); } + + void const_constraints(const Q& cq) + { + if (cq.contains(g_ct)) + dummy = __LINE__; } - + int dummy; - - static const typename Buffer::value_type g_ct; + + static const typename Buffer< Q >::value_type g_ct; Q q; - }; - - BOOST_concept(KeyedUpdatableQueue, (Q)) - : UpdatableQueue - { +}; + +BOOST_concept(KeyedUpdatableQueue, (Q)) : UpdatableQueue< Q > +{ typedef typename Q::key_type key_type; typedef typename Q::key_map key_map; - - BOOST_CONCEPT_USAGE(KeyedUpdatableQueue) { - BOOST_CONCEPT_ASSERT((boost::ReadWritePropertyMapConcept::value_type>)); + + BOOST_CONCEPT_USAGE(KeyedUpdatableQueue) + { + BOOST_CONCEPT_ASSERT((boost::ReadWritePropertyMapConcept< key_map, + typename Buffer< Q >::value_type >)); } - - void const_constraints(const Q& cq) { - km = cq.keys(); - k = get(km, g_ct); + + void const_constraints(const Q& cq) + { + km = cq.keys(); + k = get(km, g_ct); } - - static const typename Buffer::value_type g_ct; + + static const typename Buffer< Q >::value_type g_ct; key_type k; key_map km; Q q; - }; +}; } // end `namespace boost` #include diff --git a/include/boost/graph/chrobak_payne_drawing.hpp b/include/boost/graph/chrobak_payne_drawing.hpp index 0e1f05255..fc3ca40d3 100644 --- a/include/boost/graph/chrobak_payne_drawing.hpp +++ b/include/boost/graph/chrobak_payne_drawing.hpp @@ -16,92 +16,81 @@ #include #include - namespace boost { - namespace graph { namespace detail - { - - template - void accumulate_offsets(typename graph_traits::vertex_descriptor v, - std::size_t offset, - const Graph& g, - VertexTo1DCoordMap x, - VertexTo1DCoordMap delta_x, - VertexToVertexMap left, - VertexToVertexMap right) +namespace graph +{ + namespace detail { - typedef typename graph_traits::vertex_descriptor vertex_descriptor; - // Suggestion of explicit stack from Aaron Windsor to avoid system stack - // overflows. - typedef std::pair stack_entry; - std::stack st; - st.push(stack_entry(v, offset)); - while (!st.empty()) { - vertex_descriptor v = st.top().first; - std::size_t offset = st.top().second; - st.pop(); - if (v != graph_traits::null_vertex()) { - x[v] += delta_x[v] + offset; - st.push(stack_entry(left[v], x[v])); - st.push(stack_entry(right[v], x[v])); + + template < typename Graph, typename VertexToVertexMap, + typename VertexTo1DCoordMap > + void accumulate_offsets( + typename graph_traits< Graph >::vertex_descriptor v, + std::size_t offset, const Graph& g, VertexTo1DCoordMap x, + VertexTo1DCoordMap delta_x, VertexToVertexMap left, + VertexToVertexMap right) + { + typedef typename graph_traits< Graph >::vertex_descriptor + vertex_descriptor; + // Suggestion of explicit stack from Aaron Windsor to avoid system + // stack overflows. + typedef std::pair< vertex_descriptor, std::size_t > stack_entry; + std::stack< stack_entry > st; + st.push(stack_entry(v, offset)); + while (!st.empty()) + { + vertex_descriptor v = st.top().first; + std::size_t offset = st.top().second; + st.pop(); + if (v != graph_traits< Graph >::null_vertex()) + { + x[v] += delta_x[v] + offset; + st.push(stack_entry(left[v], x[v])); + st.push(stack_entry(right[v], x[v])); + } + } } - } - } - } /*namespace detail*/ } /*namespace graph*/ - - - - - - template - void chrobak_payne_straight_line_drawing(const Graph& g, - PlanarEmbedding embedding, - ForwardIterator ordering_begin, - ForwardIterator ordering_end, - GridPositionMap drawing, - VertexIndexMap vm - ) - { - - typedef typename graph_traits::vertex_descriptor vertex_t; - typedef typename graph_traits::vertex_iterator vertex_iterator_t; - typedef typename PlanarEmbedding::value_type::const_iterator - edge_permutation_iterator_t; - typedef typename graph_traits::vertices_size_type v_size_t; - typedef std::vector vertex_vector_t; - typedef std::vector vsize_vector_t; - typedef std::vector bool_vector_t; - typedef boost::iterator_property_map - - vertex_to_vertex_map_t; - typedef boost::iterator_property_map - - vertex_to_vsize_map_t; - typedef boost::iterator_property_map - - vertex_to_bool_map_t; - - vertex_vector_t left_vector(num_vertices(g), - graph_traits::null_vertex() - ); - vertex_vector_t right_vector(num_vertices(g), - graph_traits::null_vertex() - ); + } /*namespace detail*/ +} /*namespace graph*/ + +template < typename Graph, typename PlanarEmbedding, typename ForwardIterator, + typename GridPositionMap, typename VertexIndexMap > +void chrobak_payne_straight_line_drawing(const Graph& g, + PlanarEmbedding embedding, ForwardIterator ordering_begin, + ForwardIterator ordering_end, GridPositionMap drawing, VertexIndexMap vm) +{ + + typedef typename graph_traits< Graph >::vertex_descriptor vertex_t; + typedef typename graph_traits< Graph >::vertex_iterator vertex_iterator_t; + typedef typename PlanarEmbedding::value_type::const_iterator + edge_permutation_iterator_t; + typedef typename graph_traits< Graph >::vertices_size_type v_size_t; + typedef std::vector< vertex_t > vertex_vector_t; + typedef std::vector< v_size_t > vsize_vector_t; + typedef std::vector< bool > bool_vector_t; + typedef boost::iterator_property_map< typename vertex_vector_t::iterator, + VertexIndexMap > + vertex_to_vertex_map_t; + typedef boost::iterator_property_map< typename vsize_vector_t::iterator, + VertexIndexMap > + vertex_to_vsize_map_t; + typedef boost::iterator_property_map< typename bool_vector_t::iterator, + VertexIndexMap > + vertex_to_bool_map_t; + + vertex_vector_t left_vector( + num_vertices(g), graph_traits< Graph >::null_vertex()); + vertex_vector_t right_vector( + num_vertices(g), graph_traits< Graph >::null_vertex()); vsize_vector_t seen_as_right_vector(num_vertices(g), 0); vsize_vector_t seen_vector(num_vertices(g), 0); - vsize_vector_t delta_x_vector(num_vertices(g),0); + vsize_vector_t delta_x_vector(num_vertices(g), 0); vsize_vector_t y_vector(num_vertices(g)); - vsize_vector_t x_vector(num_vertices(g),0); - bool_vector_t installed_vector(num_vertices(g),false); + vsize_vector_t x_vector(num_vertices(g), 0); + bool_vector_t installed_vector(num_vertices(g), false); vertex_to_vertex_map_t left(left_vector.begin(), vm); vertex_to_vertex_map_t right(right_vector.begin(), vm); @@ -116,13 +105,16 @@ namespace boost vertex_vector_t installed_neighbors; ForwardIterator itr = ordering_begin; - vertex_t v1 = *itr; ++itr; - vertex_t v2 = *itr; ++itr; - vertex_t v3 = *itr; ++itr; - - delta_x[v2] = 1; + vertex_t v1 = *itr; + ++itr; + vertex_t v2 = *itr; + ++itr; + vertex_t v3 = *itr; + ++itr; + + delta_x[v2] = 1; delta_x[v3] = 1; - + y[v1] = 0; y[v2] = 0; y[v3] = 1; @@ -132,147 +124,126 @@ namespace boost installed[v1] = installed[v2] = installed[v3] = true; - for(ForwardIterator itr_end = ordering_end; itr != itr_end; ++itr) - { + for (ForwardIterator itr_end = ordering_end; itr != itr_end; ++itr) + { vertex_t v = *itr; - // First, find the leftmost and rightmost neighbor of v on the outer - // cycle of the embedding. - // Note: since we're moving clockwise through the edges adjacent to v, + // First, find the leftmost and rightmost neighbor of v on the outer + // cycle of the embedding. + // Note: since we're moving clockwise through the edges adjacent to v, // we're actually moving from right to left among v's neighbors on the - // outer face (since v will be installed above them all) looking for + // outer face (since v will be installed above them all) looking for // the leftmost and rightmost installed neigbhors - vertex_t leftmost = graph_traits::null_vertex(); - vertex_t rightmost = graph_traits::null_vertex(); + vertex_t leftmost = graph_traits< Graph >::null_vertex(); + vertex_t rightmost = graph_traits< Graph >::null_vertex(); installed_neighbors.clear(); - vertex_t prev_vertex = graph_traits::null_vertex(); + vertex_t prev_vertex = graph_traits< Graph >::null_vertex(); edge_permutation_iterator_t pi, pi_end; pi_end = embedding[v].end(); - for(pi = embedding[v].begin(); pi != pi_end; ++pi) - { - vertex_t curr_vertex = source(*pi,g) == v ? - target(*pi,g) : source(*pi,g); - + for (pi = embedding[v].begin(); pi != pi_end; ++pi) + { + vertex_t curr_vertex + = source(*pi, g) == v ? target(*pi, g) : source(*pi, g); + // Skip any self-loops or parallel edges if (curr_vertex == v || curr_vertex == prev_vertex) continue; if (installed[curr_vertex]) - { + { seen[curr_vertex] = timestamp; - if (right[curr_vertex] != graph_traits::null_vertex()) - { + if (right[curr_vertex] != graph_traits< Graph >::null_vertex()) + { seen_as_right[right[curr_vertex]] = timestamp; - } + } installed_neighbors.push_back(curr_vertex); - } + } prev_vertex = curr_vertex; - } + } typename vertex_vector_t::iterator vi, vi_end; vi_end = installed_neighbors.end(); - for(vi = installed_neighbors.begin(); vi != vi_end; ++vi) - { - if (right[*vi] == graph_traits::null_vertex() || - seen[right[*vi]] != timestamp - ) - rightmost = *vi; + for (vi = installed_neighbors.begin(); vi != vi_end; ++vi) + { + if (right[*vi] == graph_traits< Graph >::null_vertex() + || seen[right[*vi]] != timestamp) + rightmost = *vi; if (seen_as_right[*vi] != timestamp) - leftmost = *vi; - } + leftmost = *vi; + } ++timestamp; - //stretch gaps + // stretch gaps ++delta_x[right[leftmost]]; ++delta_x[rightmost]; - //adjust offsets + // adjust offsets std::size_t delta_p_q = 0; vertex_t stopping_vertex = right[rightmost]; - for(vertex_t temp = right[leftmost]; temp != stopping_vertex; - temp = right[temp] - ) - { + for (vertex_t temp = right[leftmost]; temp != stopping_vertex; + temp = right[temp]) + { delta_p_q += delta_x[temp]; - } + } - delta_x[v] = ((y[rightmost] + delta_p_q) - y[leftmost])/2; + delta_x[v] = ((y[rightmost] + delta_p_q) - y[leftmost]) / 2; y[v] = y[leftmost] + delta_x[v]; delta_x[rightmost] = delta_p_q - delta_x[v]; - + bool leftmost_and_rightmost_adjacent = right[leftmost] == rightmost; if (!leftmost_and_rightmost_adjacent) - delta_x[right[leftmost]] -= delta_x[v]; + delta_x[right[leftmost]] -= delta_x[v]; - //install v + // install v if (!leftmost_and_rightmost_adjacent) - { + { left[v] = right[leftmost]; vertex_t next_to_rightmost; - for(vertex_t temp = leftmost; temp != rightmost; - temp = right[temp] - ) - { + for (vertex_t temp = leftmost; temp != rightmost; + temp = right[temp]) + { next_to_rightmost = temp; - } + } - right[next_to_rightmost] = graph_traits::null_vertex(); - } + right[next_to_rightmost] = graph_traits< Graph >::null_vertex(); + } else - { - left[v] = graph_traits::null_vertex(); - } + { + left[v] = graph_traits< Graph >::null_vertex(); + } right[leftmost] = v; right[v] = rightmost; installed[v] = true; + } - } - - graph::detail::accumulate_offsets - (*ordering_begin,0,g,x,delta_x,left,right); + graph::detail::accumulate_offsets( + *ordering_begin, 0, g, x, delta_x, left, right); vertex_iterator_t vi, vi_end; - for(boost::tie(vi,vi_end) = vertices(g); vi != vi_end; ++vi) - { + for (boost::tie(vi, vi_end) = vertices(g); vi != vi_end; ++vi) + { vertex_t v(*vi); drawing[v].x = x[v]; drawing[v].y = y[v]; - } - - } - - - - - template - inline void chrobak_payne_straight_line_drawing(const Graph& g, - PlanarEmbedding embedding, - ForwardIterator ord_begin, - ForwardIterator ord_end, - GridPositionMap drawing - ) - { - chrobak_payne_straight_line_drawing(g, - embedding, - ord_begin, - ord_end, - drawing, - get(vertex_index,g) - ); - } - + } +} - +template < typename Graph, typename PlanarEmbedding, typename ForwardIterator, + typename GridPositionMap > +inline void chrobak_payne_straight_line_drawing(const Graph& g, + PlanarEmbedding embedding, ForwardIterator ord_begin, + ForwardIterator ord_end, GridPositionMap drawing) +{ + chrobak_payne_straight_line_drawing( + g, embedding, ord_begin, ord_end, drawing, get(vertex_index, g)); +} } // namespace boost diff --git a/include/boost/graph/circle_layout.hpp b/include/boost/graph/circle_layout.hpp index 9c6ca6ef5..f30ee65be 100644 --- a/include/boost/graph/circle_layout.hpp +++ b/include/boost/graph/circle_layout.hpp @@ -16,43 +16,45 @@ #include #include -namespace boost { - /** - * \brief Layout the graph with the vertices at the points of a regular - * n-polygon. - * - * The distance from the center of the polygon to each point is - * determined by the @p radius parameter. The @p position parameter - * must be an Lvalue Property Map whose value type is a class type - * containing @c x and @c y members that will be set to the @c x and - * @c y coordinates. - */ - template - void - circle_graph_layout(const VertexListGraph& g, PositionMap position, - Radius radius) - { - BOOST_STATIC_ASSERT (property_traits::value_type::dimensions >= 2); - const double pi = boost::math::constants::pi(); +namespace boost +{ +/** + * \brief Layout the graph with the vertices at the points of a regular + * n-polygon. + * + * The distance from the center of the polygon to each point is + * determined by the @p radius parameter. The @p position parameter + * must be an Lvalue Property Map whose value type is a class type + * containing @c x and @c y members that will be set to the @c x and + * @c y coordinates. + */ +template < typename VertexListGraph, typename PositionMap, typename Radius > +void circle_graph_layout( + const VertexListGraph& g, PositionMap position, Radius radius) +{ + BOOST_STATIC_ASSERT( + property_traits< PositionMap >::value_type::dimensions >= 2); + const double pi = boost::math::constants::pi< double >(); #ifndef BOOST_NO_STDC_NAMESPACE - using std::sin; using std::cos; + using std::sin; #endif // BOOST_NO_STDC_NAMESPACE - typedef typename graph_traits::vertices_size_type - vertices_size_type; + typedef typename graph_traits< VertexListGraph >::vertices_size_type + vertices_size_type; vertices_size_type n = num_vertices(g); - + vertices_size_type i = 0; double two_pi_over_n = 2. * pi / n; - BGL_FORALL_VERTICES_T(v, g, VertexListGraph) { - position[v][0] = radius * cos(i * two_pi_over_n); - position[v][1] = radius * sin(i * two_pi_over_n); - ++i; + BGL_FORALL_VERTICES_T(v, g, VertexListGraph) + { + position[v][0] = radius * cos(i * two_pi_over_n); + position[v][1] = radius * sin(i * two_pi_over_n); + ++i; } - } +} } // end namespace boost #endif // BOOST_GRAPH_CIRCLE_LAYOUT_HPP diff --git a/include/boost/graph/closeness_centrality.hpp b/include/boost/graph/closeness_centrality.hpp index 3ddf284b5..d28123cad 100644 --- a/include/boost/graph/closeness_centrality.hpp +++ b/include/boost/graph/closeness_centrality.hpp @@ -13,142 +13,137 @@ namespace boost { -template > +template < typename Graph, typename DistanceType, typename ResultType, + typename Reciprocal = detail::reciprocal< ResultType > > struct closeness_measure - : public geodesic_measure +: public geodesic_measure< Graph, DistanceType, ResultType > { - typedef geodesic_measure< Graph, DistanceType, ResultType> base_type; + typedef geodesic_measure< Graph, DistanceType, ResultType > base_type; typedef typename base_type::distance_type distance_type; typedef typename base_type::result_type result_type; - result_type operator ()(distance_type d, const Graph&) + result_type operator()(distance_type d, const Graph&) { - BOOST_CONCEPT_ASSERT(( NumericValueConcept )); - BOOST_CONCEPT_ASSERT(( NumericValueConcept )); - BOOST_CONCEPT_ASSERT(( AdaptableUnaryFunctionConcept )); - return (d == base_type::infinite_distance()) - ? base_type::zero_result() - : rec(result_type(d)); + BOOST_CONCEPT_ASSERT((NumericValueConcept< DistanceType >)); + BOOST_CONCEPT_ASSERT((NumericValueConcept< ResultType >)); + BOOST_CONCEPT_ASSERT((AdaptableUnaryFunctionConcept< Reciprocal, + ResultType, ResultType >)); + return (d == base_type::infinite_distance()) ? base_type::zero_result() + : rec(result_type(d)); } Reciprocal rec; }; -template -inline closeness_measure< - Graph, typename property_traits::value_type, double, - detail::reciprocal > +template < typename Graph, typename DistanceMap > +inline closeness_measure< Graph, + typename property_traits< DistanceMap >::value_type, double, + detail::reciprocal< double > > measure_closeness(const Graph&, DistanceMap) { - typedef typename property_traits::value_type Distance; - return closeness_measure >(); + typedef typename property_traits< DistanceMap >::value_type Distance; + return closeness_measure< Graph, Distance, double, + detail::reciprocal< double > >(); } -template -inline closeness_measure< - Graph, typename property_traits::value_type, T, - detail::reciprocal > +template < typename T, typename Graph, typename DistanceMap > +inline closeness_measure< Graph, + typename property_traits< DistanceMap >::value_type, T, + detail::reciprocal< T > > measure_closeness(const Graph&, DistanceMap) { - typedef typename property_traits::value_type Distance; - return closeness_measure >(); + typedef typename property_traits< DistanceMap >::value_type Distance; + return closeness_measure< Graph, Distance, T, detail::reciprocal< T > >(); } -template -inline closeness_measure< - Graph, typename property_traits::value_type, T, - Reciprocal> +template < typename T, typename Graph, typename DistanceMap, + typename Reciprocal > +inline closeness_measure< Graph, + typename property_traits< DistanceMap >::value_type, T, Reciprocal > measure_closeness(const Graph&, DistanceMap) { - typedef typename property_traits::value_type Distance; - return closeness_measure(); + typedef typename property_traits< DistanceMap >::value_type Distance; + return closeness_measure< Graph, Distance, T, Reciprocal >(); } -template -inline typename Measure::result_type -closeness_centrality(const Graph& g, - DistanceMap dist, - Measure measure, - Combinator combine) +template < typename Graph, typename DistanceMap, typename Measure, + typename Combinator > +inline typename Measure::result_type closeness_centrality( + const Graph& g, DistanceMap dist, Measure measure, Combinator combine) { - BOOST_CONCEPT_ASSERT(( VertexListGraphConcept )); - typedef typename graph_traits::vertex_descriptor Vertex; - BOOST_CONCEPT_ASSERT(( ReadablePropertyMapConcept )); - typedef typename property_traits::value_type Distance; - BOOST_CONCEPT_ASSERT(( NumericValueConcept )); - BOOST_CONCEPT_ASSERT(( DistanceMeasureConcept )); + BOOST_CONCEPT_ASSERT((VertexListGraphConcept< Graph >)); + typedef typename graph_traits< Graph >::vertex_descriptor Vertex; + BOOST_CONCEPT_ASSERT((ReadablePropertyMapConcept< DistanceMap, Vertex >)); + typedef typename property_traits< DistanceMap >::value_type Distance; + BOOST_CONCEPT_ASSERT((NumericValueConcept< Distance >)); + BOOST_CONCEPT_ASSERT((DistanceMeasureConcept< Measure, Graph >)); Distance n = detail::combine_distances(g, dist, combine, Distance(0)); return measure(n, g); } -template -inline typename Measure::result_type -closeness_centrality(const Graph& g, DistanceMap dist, Measure measure) +template < typename Graph, typename DistanceMap, typename Measure > +inline typename Measure::result_type closeness_centrality( + const Graph& g, DistanceMap dist, Measure measure) { - BOOST_CONCEPT_ASSERT(( GraphConcept )); - typedef typename graph_traits::vertex_descriptor Vertex; - BOOST_CONCEPT_ASSERT(( ReadablePropertyMapConcept )); - typedef typename property_traits::value_type Distance; + BOOST_CONCEPT_ASSERT((GraphConcept< Graph >)); + typedef typename graph_traits< Graph >::vertex_descriptor Vertex; + BOOST_CONCEPT_ASSERT((ReadablePropertyMapConcept< DistanceMap, Vertex >)); + typedef typename property_traits< DistanceMap >::value_type Distance; - return closeness_centrality(g, dist, measure, std::plus()); + return closeness_centrality(g, dist, measure, std::plus< Distance >()); } -template +template < typename Graph, typename DistanceMap > inline double closeness_centrality(const Graph& g, DistanceMap dist) -{ return closeness_centrality(g, dist, measure_closeness(g, dist)); } +{ + return closeness_centrality(g, dist, measure_closeness(g, dist)); +} -template +template < typename T, typename Graph, typename DistanceMap > inline T closeness_centrality(const Graph& g, DistanceMap dist) -{ return closeness_centrality(g, dist, measure_closeness(g, dist)); } - -template -inline void -all_closeness_centralities(const Graph& g, - DistanceMatrixMap dist, - CentralityMap cent, - Measure measure) { - BOOST_CONCEPT_ASSERT(( VertexListGraphConcept )); - typedef typename graph_traits::vertex_descriptor Vertex; - BOOST_CONCEPT_ASSERT(( ReadablePropertyMapConcept )); - typedef typename property_traits::value_type DistanceMap; - BOOST_CONCEPT_ASSERT(( ReadablePropertyMapConcept )); - BOOST_CONCEPT_ASSERT(( WritablePropertyMapConcept )); - typedef typename property_traits::value_type Centrality; - - typename graph_traits::vertex_iterator i, end; - for(boost::tie(i, end) = vertices(g); i != end; ++i) { + return closeness_centrality(g, dist, measure_closeness< T >(g, dist)); +} + +template < typename Graph, typename DistanceMatrixMap, typename CentralityMap, + typename Measure > +inline void all_closeness_centralities( + const Graph& g, DistanceMatrixMap dist, CentralityMap cent, Measure measure) +{ + BOOST_CONCEPT_ASSERT((VertexListGraphConcept< Graph >)); + typedef typename graph_traits< Graph >::vertex_descriptor Vertex; + BOOST_CONCEPT_ASSERT( + (ReadablePropertyMapConcept< DistanceMatrixMap, Vertex >)); + typedef + typename property_traits< DistanceMatrixMap >::value_type DistanceMap; + BOOST_CONCEPT_ASSERT((ReadablePropertyMapConcept< DistanceMap, Vertex >)); + BOOST_CONCEPT_ASSERT((WritablePropertyMapConcept< CentralityMap, Vertex >)); + typedef typename property_traits< CentralityMap >::value_type Centrality; + + typename graph_traits< Graph >::vertex_iterator i, end; + for (boost::tie(i, end) = vertices(g); i != end; ++i) + { DistanceMap dm = get(dist, *i); Centrality c = closeness_centrality(g, dm, measure); put(cent, *i, c); } } -template -inline void -all_closeness_centralities(const Graph& g, - DistanceMatrixMap dist, - CentralityMap cent) +template < typename Graph, typename DistanceMatrixMap, typename CentralityMap > +inline void all_closeness_centralities( + const Graph& g, DistanceMatrixMap dist, CentralityMap cent) { - BOOST_CONCEPT_ASSERT(( GraphConcept )); - typedef typename graph_traits::vertex_descriptor Vertex; - BOOST_CONCEPT_ASSERT(( ReadablePropertyMapConcept )); - typedef typename property_traits::value_type DistanceMap; - BOOST_CONCEPT_ASSERT(( ReadablePropertyMapConcept )); - typedef typename property_traits::value_type Result; - - all_closeness_centralities(g, dist, cent, measure_closeness(g, DistanceMap())); + BOOST_CONCEPT_ASSERT((GraphConcept< Graph >)); + typedef typename graph_traits< Graph >::vertex_descriptor Vertex; + BOOST_CONCEPT_ASSERT( + (ReadablePropertyMapConcept< DistanceMatrixMap, Vertex >)); + typedef + typename property_traits< DistanceMatrixMap >::value_type DistanceMap; + BOOST_CONCEPT_ASSERT((ReadablePropertyMapConcept< DistanceMap, Vertex >)); + typedef typename property_traits< CentralityMap >::value_type Result; + + all_closeness_centralities( + g, dist, cent, measure_closeness< Result >(g, DistanceMap())); } } /* namespace boost */ diff --git a/include/boost/graph/clustering_coefficient.hpp b/include/boost/graph/clustering_coefficient.hpp index 5345ed999..e275dd7e3 100644 --- a/include/boost/graph/clustering_coefficient.hpp +++ b/include/boost/graph/clustering_coefficient.hpp @@ -17,57 +17,54 @@ namespace boost { namespace detail { - template - inline typename graph_traits::degree_size_type - possible_edges(const Graph& g, std::size_t k, directed_tag) + template < class Graph > + inline typename graph_traits< Graph >::degree_size_type possible_edges( + const Graph& g, std::size_t k, directed_tag) { - BOOST_CONCEPT_ASSERT(( GraphConcept )); - typedef typename graph_traits::degree_size_type T; + BOOST_CONCEPT_ASSERT((GraphConcept< Graph >)); + typedef typename graph_traits< Graph >::degree_size_type T; return T(k) * (T(k) - 1); } - template - inline typename graph_traits::degree_size_type - possible_edges(const Graph& g, size_t k, undirected_tag) + template < class Graph > + inline typename graph_traits< Graph >::degree_size_type possible_edges( + const Graph& g, size_t k, undirected_tag) { // dirty little trick... return possible_edges(g, k, directed_tag()) / 2; } // This template matches directedS and bidirectionalS. - template - inline typename graph_traits::degree_size_type - count_edges(const Graph& g, - typename graph_traits::vertex_descriptor u, - typename graph_traits::vertex_descriptor v, - directed_tag) + template < class Graph > + inline typename graph_traits< Graph >::degree_size_type count_edges( + const Graph& g, typename graph_traits< Graph >::vertex_descriptor u, + typename graph_traits< Graph >::vertex_descriptor v, directed_tag) { - BOOST_CONCEPT_ASSERT(( AdjacencyMatrixConcept )); - return (lookup_edge(u, v, g).second ? 1 : 0) + - (lookup_edge(v, u, g).second ? 1 : 0); + BOOST_CONCEPT_ASSERT((AdjacencyMatrixConcept< Graph >)); + return (lookup_edge(u, v, g).second ? 1 : 0) + + (lookup_edge(v, u, g).second ? 1 : 0); } // This template matches undirectedS - template - inline typename graph_traits::degree_size_type - count_edges(const Graph& g, - typename graph_traits::vertex_descriptor u, - typename graph_traits::vertex_descriptor v, - undirected_tag) + template < class Graph > + inline typename graph_traits< Graph >::degree_size_type count_edges( + const Graph& g, typename graph_traits< Graph >::vertex_descriptor u, + typename graph_traits< Graph >::vertex_descriptor v, undirected_tag) { - BOOST_CONCEPT_ASSERT(( AdjacencyMatrixConcept )); + BOOST_CONCEPT_ASSERT((AdjacencyMatrixConcept< Graph >)); return lookup_edge(u, v, g).second ? 1 : 0; } } -template -inline typename graph_traits::degree_size_type +template < typename Graph, typename Vertex > +inline typename graph_traits< Graph >::degree_size_type num_paths_through_vertex(const Graph& g, Vertex v) { - BOOST_CONCEPT_ASSERT(( AdjacencyGraphConcept )); - typedef typename graph_traits::directed_category Directed; - typedef typename graph_traits::adjacency_iterator AdjacencyIterator; + BOOST_CONCEPT_ASSERT((AdjacencyGraphConcept< Graph >)); + typedef typename graph_traits< Graph >::directed_category Directed; + typedef + typename graph_traits< Graph >::adjacency_iterator AdjacencyIterator; // TODO: There should actually be a set of neighborhood functions // for things like this (num_neighbors() would be great). @@ -78,77 +75,81 @@ num_paths_through_vertex(const Graph& g, Vertex v) return detail::possible_edges(g, k, Directed()); } -template -inline typename graph_traits::degree_size_type -num_triangles_on_vertex(const Graph& g, Vertex v) +template < typename Graph, typename Vertex > +inline typename graph_traits< Graph >::degree_size_type num_triangles_on_vertex( + const Graph& g, Vertex v) { - BOOST_CONCEPT_ASSERT(( IncidenceGraphConcept )); - BOOST_CONCEPT_ASSERT(( AdjacencyGraphConcept )); - typedef typename graph_traits::degree_size_type Degree; - typedef typename graph_traits::directed_category Directed; - typedef typename graph_traits::adjacency_iterator AdjacencyIterator; + BOOST_CONCEPT_ASSERT((IncidenceGraphConcept< Graph >)); + BOOST_CONCEPT_ASSERT((AdjacencyGraphConcept< Graph >)); + typedef typename graph_traits< Graph >::degree_size_type Degree; + typedef typename graph_traits< Graph >::directed_category Directed; + typedef + typename graph_traits< Graph >::adjacency_iterator AdjacencyIterator; // TODO: I might be able to reduce the requirement from adjacency graph // to incidence graph by using out edges. Degree count(0); AdjacencyIterator i, j, end; - for(boost::tie(i, end) = adjacent_vertices(v, g); i != end; ++i) { - for(j = boost::next(i); j != end; ++j) { + for (boost::tie(i, end) = adjacent_vertices(v, g); i != end; ++i) + { + for (j = boost::next(i); j != end; ++j) + { count += detail::count_edges(g, *i, *j, Directed()); } } return count; } /* namespace detail */ -template -inline T -clustering_coefficient(const Graph& g, Vertex v) +template < typename T, typename Graph, typename Vertex > +inline T clustering_coefficient(const Graph& g, Vertex v) { T zero(0); T routes = T(num_paths_through_vertex(g, v)); - return (routes > zero) ? - T(num_triangles_on_vertex(g, v)) / routes : zero; + return (routes > zero) ? T(num_triangles_on_vertex(g, v)) / routes : zero; } -template -inline double -clustering_coefficient(const Graph& g, Vertex v) -{ return clustering_coefficient(g, v); } +template < typename Graph, typename Vertex > +inline double clustering_coefficient(const Graph& g, Vertex v) +{ + return clustering_coefficient< double >(g, v); +} -template -inline typename property_traits::value_type +template < typename Graph, typename ClusteringMap > +inline typename property_traits< ClusteringMap >::value_type all_clustering_coefficients(const Graph& g, ClusteringMap cm) { - BOOST_CONCEPT_ASSERT(( VertexListGraphConcept )); - typedef typename graph_traits::vertex_descriptor Vertex; - typedef typename graph_traits::vertex_iterator VertexIterator; - BOOST_CONCEPT_ASSERT(( WritablePropertyMapConcept )); - typedef typename property_traits::value_type Coefficient; + BOOST_CONCEPT_ASSERT((VertexListGraphConcept< Graph >)); + typedef typename graph_traits< Graph >::vertex_descriptor Vertex; + typedef typename graph_traits< Graph >::vertex_iterator VertexIterator; + BOOST_CONCEPT_ASSERT((WritablePropertyMapConcept< ClusteringMap, Vertex >)); + typedef typename property_traits< ClusteringMap >::value_type Coefficient; Coefficient sum(0); VertexIterator i, end; - for(boost::tie(i, end) = vertices(g); i != end; ++i) { - Coefficient cc = clustering_coefficient(g, *i); + for (boost::tie(i, end) = vertices(g); i != end; ++i) + { + Coefficient cc = clustering_coefficient< Coefficient >(g, *i); put(cm, *i, cc); sum += cc; } return sum / Coefficient(num_vertices(g)); } -template -inline typename property_traits::value_type +template < typename Graph, typename ClusteringMap > +inline typename property_traits< ClusteringMap >::value_type mean_clustering_coefficient(const Graph& g, ClusteringMap cm) { - BOOST_CONCEPT_ASSERT(( VertexListGraphConcept )); - typedef typename graph_traits::vertex_descriptor Vertex; - typedef typename graph_traits::vertex_iterator VertexIterator; - BOOST_CONCEPT_ASSERT(( ReadablePropertyMapConcept )); - typedef typename property_traits::value_type Coefficient; + BOOST_CONCEPT_ASSERT((VertexListGraphConcept< Graph >)); + typedef typename graph_traits< Graph >::vertex_descriptor Vertex; + typedef typename graph_traits< Graph >::vertex_iterator VertexIterator; + BOOST_CONCEPT_ASSERT((ReadablePropertyMapConcept< ClusteringMap, Vertex >)); + typedef typename property_traits< ClusteringMap >::value_type Coefficient; Coefficient cc(0); VertexIterator i, end; - for(boost::tie(i, end) = vertices(g); i != end; ++i) { + for (boost::tie(i, end) = vertices(g); i != end; ++i) + { cc += get(cm, *i); } return cc / Coefficient(num_vertices(g)); diff --git a/include/boost/graph/compressed_sparse_row_graph.hpp b/include/boost/graph/compressed_sparse_row_graph.hpp index 7b91d4d6c..e777d8c4b 100644 --- a/include/boost/graph/compressed_sparse_row_graph.hpp +++ b/include/boost/graph/compressed_sparse_row_graph.hpp @@ -47,7 +47,8 @@ #include #include -namespace boost { +namespace boost +{ // A tag type indicating that the graph in question is a compressed // sparse row graph. This is an internal detail of the BGL. @@ -56,24 +57,36 @@ struct csr_graph_tag; // A type (edges_are_sorted_t) and a value (edges_are_sorted) used to indicate // that the edge list passed into the CSR graph is already sorted by source // vertex. -enum edges_are_sorted_t {edges_are_sorted}; +enum edges_are_sorted_t +{ + edges_are_sorted +}; // A type (edges_are_sorted_global_t) and a value (edges_are_sorted_global) // used to indicate that the edge list passed into the CSR graph is already // sorted by source vertex. -enum edges_are_sorted_global_t {edges_are_sorted_global}; +enum edges_are_sorted_global_t +{ + edges_are_sorted_global +}; // A type (edges_are_unsorted_t) and a value (edges_are_unsorted) used to // indicate that the edge list passed into the CSR graph is not sorted by // source vertex. This version caches the edge information in memory, and thus // requires only a single pass over the input data. -enum edges_are_unsorted_t {edges_are_unsorted}; +enum edges_are_unsorted_t +{ + edges_are_unsorted +}; // A type (edges_are_unsorted_multi_pass_t) and a value // (edges_are_unsorted_multi_pass) used to indicate that the edge list passed // into the CSR graph is not sorted by source vertex. This version uses less // memory but requires multi-pass capability on the iterators. -enum edges_are_unsorted_multi_pass_t {edges_are_unsorted_multi_pass}; +enum edges_are_unsorted_multi_pass_t +{ + edges_are_unsorted_multi_pass +}; // A type (edges_are_unsorted_multi_pass_global_t) and a value // (edges_are_unsorted_multi_pass_global) used to indicate that the edge list @@ -81,14 +94,20 @@ enum edges_are_unsorted_multi_pass_t {edges_are_unsorted_multi_pass}; // less memory but requires multi-pass capability on the iterators. The // global mapping and filtering is done here because it is often faster and it // greatly simplifies handling of edge properties. -enum edges_are_unsorted_multi_pass_global_t {edges_are_unsorted_multi_pass_global}; +enum edges_are_unsorted_multi_pass_global_t +{ + edges_are_unsorted_multi_pass_global +}; // A type (construct_inplace_from_sources_and_targets_t) and a value // (construct_inplace_from_sources_and_targets) used to indicate that mutable // vectors of sources and targets (and possibly edge properties) are being used // to construct the CSR graph. These vectors are sorted in-place and then the // targets and properties are swapped into the graph data structure. -enum construct_inplace_from_sources_and_targets_t {construct_inplace_from_sources_and_targets}; +enum construct_inplace_from_sources_and_targets_t +{ + construct_inplace_from_sources_and_targets +}; // A type (construct_inplace_from_sources_and_targets_global_t) and a value // (construct_inplace_from_sources_and_targets_global) used to indicate that @@ -99,7 +118,10 @@ enum construct_inplace_from_sources_and_targets_t {construct_inplace_from_source // used, and a map is required to convert those to local indices. This // constructor is intended for internal use by the various CSR graphs // (sequential and distributed). -enum construct_inplace_from_sources_and_targets_global_t {construct_inplace_from_sources_and_targets_global}; +enum construct_inplace_from_sources_and_targets_global_t +{ + construct_inplace_from_sources_and_targets_global +}; // A type (edges_are_unsorted_global_t) and a value (edges_are_unsorted_global) // used to indicate that the edge list passed into the CSR graph is not sorted @@ -108,61 +130,75 @@ enum construct_inplace_from_sources_and_targets_global_t {construct_inplace_from // edge information in memory, and thus requires only a single pass over the // input data. This constructor is intended for internal use by the // distributed CSR constructors. -enum edges_are_unsorted_global_t {edges_are_unsorted_global}; +enum edges_are_unsorted_global_t +{ + edges_are_unsorted_global +}; /**************************************************************************** * Local helper macros to reduce typing and clutter later on. * ****************************************************************************/ -#define BOOST_CSR_GRAPH_TEMPLATE_PARMS \ - typename Directed, typename VertexProperty, typename EdgeProperty, \ - typename GraphProperty, typename Vertex, typename EdgeIndex -#define BOOST_CSR_GRAPH_TYPE \ - compressed_sparse_row_graph -#define BOOST_DIR_CSR_GRAPH_TEMPLATE_PARMS \ - typename VertexProperty, typename EdgeProperty, \ - typename GraphProperty, typename Vertex, typename EdgeIndex -#define BOOST_DIR_CSR_GRAPH_TYPE \ - compressed_sparse_row_graph -#define BOOST_BIDIR_CSR_GRAPH_TEMPLATE_PARMS \ - typename VertexProperty, typename EdgeProperty, \ - typename GraphProperty, typename Vertex, typename EdgeIndex -#define BOOST_BIDIR_CSR_GRAPH_TYPE \ - compressed_sparse_row_graph - -namespace detail { - template - struct default_construct_iterator: public boost::iterator_facade, T, boost::random_access_traversal_tag, const T&> { - typedef boost::iterator_facade, T, std::random_access_iterator_tag, const T&> base_type; - T saved_value; - const T& dereference() const {return saved_value;} - bool equal(default_construct_iterator /*i*/) const {return true;} - void increment() {} - void decrement() {} - void advance(typename base_type::difference_type) {} - typename base_type::difference_type distance_to(default_construct_iterator) const {return 0;} - }; - - template - struct compare_first { - Less less; - compare_first(Less less = Less()): less(less) {} - template - bool operator()(const Tuple& a, const Tuple& b) const { - return less(a.template get<0>(), b.template get<0>()); - } - }; - - template - struct my_tuple_get_class { - typedef const Result& result_type; - template - result_type operator()(const Tuple& t) const { - return t.template get(); - } - }; +#define BOOST_CSR_GRAPH_TEMPLATE_PARMS \ + typename Directed, typename VertexProperty, typename EdgeProperty, \ + typename GraphProperty, typename Vertex, typename EdgeIndex +#define BOOST_CSR_GRAPH_TYPE \ + compressed_sparse_row_graph< Directed, VertexProperty, EdgeProperty, \ + GraphProperty, Vertex, EdgeIndex > +#define BOOST_DIR_CSR_GRAPH_TEMPLATE_PARMS \ + typename VertexProperty, typename EdgeProperty, typename GraphProperty, \ + typename Vertex, typename EdgeIndex +#define BOOST_DIR_CSR_GRAPH_TYPE \ + compressed_sparse_row_graph< directedS, VertexProperty, EdgeProperty, \ + GraphProperty, Vertex, EdgeIndex > +#define BOOST_BIDIR_CSR_GRAPH_TEMPLATE_PARMS \ + typename VertexProperty, typename EdgeProperty, typename GraphProperty, \ + typename Vertex, typename EdgeIndex +#define BOOST_BIDIR_CSR_GRAPH_TYPE \ + compressed_sparse_row_graph< bidirectionalS, VertexProperty, EdgeProperty, \ + GraphProperty, Vertex, EdgeIndex > + +namespace detail +{ + template < typename T > + struct default_construct_iterator + : public boost::iterator_facade< default_construct_iterator< T >, T, + boost::random_access_traversal_tag, const T& > + { + typedef boost::iterator_facade< default_construct_iterator< T >, T, + std::random_access_iterator_tag, const T& > + base_type; + T saved_value; + const T& dereference() const { return saved_value; } + bool equal(default_construct_iterator /*i*/) const { return true; } + void increment() {} + void decrement() {} + void advance(typename base_type::difference_type) {} + typename base_type::difference_type distance_to( + default_construct_iterator) const + { + return 0; + } + }; + + template < typename Less > struct compare_first + { + Less less; + compare_first(Less less = Less()) : less(less) {} + template < typename Tuple > + bool operator()(const Tuple& a, const Tuple& b) const + { + return less(a.template get< 0 >(), b.template get< 0 >()); + } + }; + + template < int N, typename Result > struct my_tuple_get_class + { + typedef const Result& result_type; + template < typename Tuple > result_type operator()(const Tuple& t) const + { + return t.template get< N >(); + } + }; } /** Compressed sparse row graph. @@ -170,1428 +206,1545 @@ namespace detail { * Vertex and EdgeIndex should be unsigned integral types and should * specialize numeric_limits. */ -template +template < typename Directed = directedS, typename VertexProperty = no_property, + typename EdgeProperty = no_property, typename GraphProperty = no_property, + typename Vertex = std::size_t, + typename EdgeIndex = Vertex > class compressed_sparse_row_graph; // Not defined -template -class compressed_sparse_row_graph - : public detail::indexed_vertex_properties > -{ - public: - typedef detail::indexed_vertex_properties > - inherited_vertex_properties; - - // Some tests to prevent use of "void" is a property type (as was done in some test cases): - BOOST_STATIC_ASSERT((!is_same::value)); - BOOST_STATIC_ASSERT((!is_same::value)); - BOOST_STATIC_ASSERT((!is_same::value)); - - public: - // For Property Graph - typedef GraphProperty graph_property_type; - typedef typename lookup_one_property::type graph_bundled; - - typedef detail::compressed_sparse_row_structure forward_type; - - public: - /* At this time, the compressed sparse row graph can only be used to - * create directed and bidirectional graphs. In the future, - * undirected CSR graphs will also be supported. - */ - // BOOST_STATIC_ASSERT((is_same::value)); - - // Concept requirements: - // For Graph - typedef Vertex vertex_descriptor; - typedef detail::csr_edge_descriptor edge_descriptor; - typedef directed_tag directed_category; - typedef allow_parallel_edge_tag edge_parallel_category; - - class traversal_category: public incidence_graph_tag, - public adjacency_graph_tag, - public vertex_list_graph_tag, - public edge_list_graph_tag {}; - - static vertex_descriptor null_vertex() { return vertex_descriptor(-1); } - - // For VertexListGraph - typedef counting_iterator vertex_iterator; - typedef Vertex vertices_size_type; - - // For EdgeListGraph - typedef EdgeIndex edges_size_type; - - // For IncidenceGraph - typedef detail::csr_out_edge_iterator out_edge_iterator; - typedef EdgeIndex degree_size_type; - - // For AdjacencyGraph - typedef typename std::vector::const_iterator adjacency_iterator; - - // For EdgeListGraph - typedef detail::csr_edge_iterator edge_iterator; - - // For BidirectionalGraph (not implemented) - typedef void in_edge_iterator; - - // For internal use - typedef csr_graph_tag graph_tag; - - typedef typename forward_type::inherited_edge_properties::edge_bundled edge_bundled; - typedef typename forward_type::inherited_edge_properties::edge_push_back_type edge_push_back_type; - typedef typename forward_type::inherited_edge_properties::edge_property_type edge_property_type; - - // Constructors - - // Default constructor: an empty graph. - compressed_sparse_row_graph(): m_property() {} - - // With numverts vertices - compressed_sparse_row_graph(vertices_size_type numverts) - : inherited_vertex_properties(numverts), m_forward(numverts) {} - - // From number of vertices and unsorted list of edges - template - compressed_sparse_row_graph(edges_are_unsorted_multi_pass_t, - MultiPassInputIterator edge_begin, - MultiPassInputIterator edge_end, - vertices_size_type numverts, - const GraphProperty& prop = GraphProperty()) +template < typename VertexProperty, typename EdgeProperty, + typename GraphProperty, typename Vertex, typename EdgeIndex > +class compressed_sparse_row_graph< directedS, VertexProperty, EdgeProperty, + GraphProperty, Vertex, EdgeIndex > +: public detail::indexed_vertex_properties< BOOST_DIR_CSR_GRAPH_TYPE, + VertexProperty, Vertex, typed_identity_property_map< Vertex > > +{ +public: + typedef detail::indexed_vertex_properties< compressed_sparse_row_graph, + VertexProperty, Vertex, typed_identity_property_map< Vertex > > + inherited_vertex_properties; + + // Some tests to prevent use of "void" is a property type (as was done in + // some test cases): + BOOST_STATIC_ASSERT((!is_same< VertexProperty, void >::value)); + BOOST_STATIC_ASSERT((!is_same< EdgeProperty, void >::value)); + BOOST_STATIC_ASSERT((!is_same< GraphProperty, void >::value)); + +public: + // For Property Graph + typedef GraphProperty graph_property_type; + typedef typename lookup_one_property< GraphProperty, graph_bundle_t >::type + graph_bundled; + + typedef detail::compressed_sparse_row_structure< EdgeProperty, Vertex, + EdgeIndex > + forward_type; + +public: + /* At this time, the compressed sparse row graph can only be used to + * create directed and bidirectional graphs. In the future, + * undirected CSR graphs will also be supported. + */ + // BOOST_STATIC_ASSERT((is_same::value)); + + // Concept requirements: + // For Graph + typedef Vertex vertex_descriptor; + typedef detail::csr_edge_descriptor< Vertex, EdgeIndex > edge_descriptor; + typedef directed_tag directed_category; + typedef allow_parallel_edge_tag edge_parallel_category; + + class traversal_category : public incidence_graph_tag, + public adjacency_graph_tag, + public vertex_list_graph_tag, + public edge_list_graph_tag + { + }; + + static vertex_descriptor null_vertex() { return vertex_descriptor(-1); } + + // For VertexListGraph + typedef counting_iterator< Vertex > vertex_iterator; + typedef Vertex vertices_size_type; + + // For EdgeListGraph + typedef EdgeIndex edges_size_type; + + // For IncidenceGraph + typedef detail::csr_out_edge_iterator< compressed_sparse_row_graph > + out_edge_iterator; + typedef EdgeIndex degree_size_type; + + // For AdjacencyGraph + typedef typename std::vector< Vertex >::const_iterator adjacency_iterator; + + // For EdgeListGraph + typedef detail::csr_edge_iterator< compressed_sparse_row_graph > + edge_iterator; + + // For BidirectionalGraph (not implemented) + typedef void in_edge_iterator; + + // For internal use + typedef csr_graph_tag graph_tag; + + typedef typename forward_type::inherited_edge_properties::edge_bundled + edge_bundled; + typedef + typename forward_type::inherited_edge_properties::edge_push_back_type + edge_push_back_type; + typedef typename forward_type::inherited_edge_properties::edge_property_type + edge_property_type; + + // Constructors + + // Default constructor: an empty graph. + compressed_sparse_row_graph() : m_property() {} + + // With numverts vertices + compressed_sparse_row_graph(vertices_size_type numverts) + : inherited_vertex_properties(numverts), m_forward(numverts) + { + } + + // From number of vertices and unsorted list of edges + template < typename MultiPassInputIterator > + compressed_sparse_row_graph(edges_are_unsorted_multi_pass_t, + MultiPassInputIterator edge_begin, MultiPassInputIterator edge_end, + vertices_size_type numverts, + const GraphProperty& prop = GraphProperty()) : inherited_vertex_properties(numverts), m_property(prop) - { - m_forward.assign_unsorted_multi_pass_edges(edge_begin, edge_end, numverts, typed_identity_property_map(), keep_all()); - } - - // From number of vertices and unsorted list of edges, plus edge properties - template - compressed_sparse_row_graph(edges_are_unsorted_multi_pass_t, - MultiPassInputIterator edge_begin, - MultiPassInputIterator edge_end, - EdgePropertyIterator ep_iter, - vertices_size_type numverts, - const GraphProperty& prop = GraphProperty()) + { + m_forward.assign_unsorted_multi_pass_edges(edge_begin, edge_end, + numverts, typed_identity_property_map< vertices_size_type >(), + keep_all()); + } + + // From number of vertices and unsorted list of edges, plus edge properties + template < typename MultiPassInputIterator, typename EdgePropertyIterator > + compressed_sparse_row_graph(edges_are_unsorted_multi_pass_t, + MultiPassInputIterator edge_begin, MultiPassInputIterator edge_end, + EdgePropertyIterator ep_iter, vertices_size_type numverts, + const GraphProperty& prop = GraphProperty()) : inherited_vertex_properties(numverts), m_forward(), m_property(prop) - { - m_forward.assign_unsorted_multi_pass_edges(edge_begin, edge_end, ep_iter, numverts, typed_identity_property_map(), keep_all()); - } - - // From number of vertices and unsorted list of edges, with filter and - // global-to-local map - template - compressed_sparse_row_graph(edges_are_unsorted_multi_pass_global_t, - MultiPassInputIterator edge_begin, - MultiPassInputIterator edge_end, - vertices_size_type numlocalverts, - const GlobalToLocal& global_to_local, - const SourcePred& source_pred, - const GraphProperty& prop = GraphProperty()) + { + m_forward.assign_unsorted_multi_pass_edges(edge_begin, edge_end, + ep_iter, numverts, + typed_identity_property_map< vertices_size_type >(), keep_all()); + } + + // From number of vertices and unsorted list of edges, with filter and + // global-to-local map + template < typename MultiPassInputIterator, typename GlobalToLocal, + typename SourcePred > + compressed_sparse_row_graph(edges_are_unsorted_multi_pass_global_t, + MultiPassInputIterator edge_begin, MultiPassInputIterator edge_end, + vertices_size_type numlocalverts, const GlobalToLocal& global_to_local, + const SourcePred& source_pred, + const GraphProperty& prop = GraphProperty()) : inherited_vertex_properties(numlocalverts), m_forward(), m_property(prop) - { - m_forward.assign_unsorted_multi_pass_edges(edge_begin, edge_end, numlocalverts, global_to_local, source_pred); - } - - // From number of vertices and unsorted list of edges, plus edge properties, - // with filter and global-to-local map - template - compressed_sparse_row_graph(edges_are_unsorted_multi_pass_global_t, - MultiPassInputIterator edge_begin, - MultiPassInputIterator edge_end, - EdgePropertyIterator ep_iter, - vertices_size_type numlocalverts, - const GlobalToLocal& global_to_local, - const SourcePred& source_pred, - const GraphProperty& prop = GraphProperty()) + { + m_forward.assign_unsorted_multi_pass_edges( + edge_begin, edge_end, numlocalverts, global_to_local, source_pred); + } + + // From number of vertices and unsorted list of edges, plus edge + // properties, with filter and global-to-local map + template < typename MultiPassInputIterator, typename EdgePropertyIterator, + typename GlobalToLocal, typename SourcePred > + compressed_sparse_row_graph(edges_are_unsorted_multi_pass_global_t, + MultiPassInputIterator edge_begin, MultiPassInputIterator edge_end, + EdgePropertyIterator ep_iter, vertices_size_type numlocalverts, + const GlobalToLocal& global_to_local, const SourcePred& source_pred, + const GraphProperty& prop = GraphProperty()) : inherited_vertex_properties(numlocalverts), m_forward(), m_property(prop) - { - m_forward.assign_unsorted_multi_pass_edges(edge_begin, edge_end, ep_iter, numlocalverts, global_to_local, source_pred); - } - - // From number of vertices and sorted list of edges (new interface) - template - compressed_sparse_row_graph(edges_are_sorted_t, - InputIterator edge_begin, InputIterator edge_end, - vertices_size_type numverts, - edges_size_type numedges = 0, - const GraphProperty& prop = GraphProperty()) + { + m_forward.assign_unsorted_multi_pass_edges(edge_begin, edge_end, + ep_iter, numlocalverts, global_to_local, source_pred); + } + + // From number of vertices and sorted list of edges (new interface) + template < typename InputIterator > + compressed_sparse_row_graph(edges_are_sorted_t, InputIterator edge_begin, + InputIterator edge_end, vertices_size_type numverts, + edges_size_type numedges = 0, + const GraphProperty& prop = GraphProperty()) : m_property(prop) - { - m_forward.assign_from_sorted_edges(edge_begin, edge_end, typed_identity_property_map(), keep_all(), numverts, numedges); - inherited_vertex_properties::resize(numverts); - } - - // From number of vertices and sorted list of edges (new interface) - template - compressed_sparse_row_graph(edges_are_sorted_t, - InputIterator edge_begin, InputIterator edge_end, - EdgePropertyIterator ep_iter, - vertices_size_type numverts, - edges_size_type numedges = 0, - const GraphProperty& prop = GraphProperty()) + { + m_forward.assign_from_sorted_edges(edge_begin, edge_end, + typed_identity_property_map< vertices_size_type >(), keep_all(), + numverts, numedges); + inherited_vertex_properties::resize(numverts); + } + + // From number of vertices and sorted list of edges (new interface) + template < typename InputIterator, typename EdgePropertyIterator > + compressed_sparse_row_graph(edges_are_sorted_t, InputIterator edge_begin, + InputIterator edge_end, EdgePropertyIterator ep_iter, + vertices_size_type numverts, edges_size_type numedges = 0, + const GraphProperty& prop = GraphProperty()) : m_property(prop) - { - m_forward.assign_from_sorted_edges(edge_begin, edge_end, ep_iter, typed_identity_property_map(), keep_all(), numverts, numedges); - inherited_vertex_properties::resize(numverts); - } - - // From number of vertices and sorted list of edges, filtered and global (new interface) - template - compressed_sparse_row_graph(edges_are_sorted_global_t, - InputIterator edge_begin, InputIterator edge_end, - const GlobalToLocal& global_to_local, - const SourcePred& source_pred, - vertices_size_type numverts, - const GraphProperty& prop = GraphProperty()) + { + m_forward.assign_from_sorted_edges(edge_begin, edge_end, ep_iter, + typed_identity_property_map< vertices_size_type >(), keep_all(), + numverts, numedges); + inherited_vertex_properties::resize(numverts); + } + + // From number of vertices and sorted list of edges, filtered and global + // (new interface) + template < typename InputIterator, typename GlobalToLocal, + typename SourcePred > + compressed_sparse_row_graph(edges_are_sorted_global_t, + InputIterator edge_begin, InputIterator edge_end, + const GlobalToLocal& global_to_local, const SourcePred& source_pred, + vertices_size_type numverts, + const GraphProperty& prop = GraphProperty()) : m_property(prop) - { - m_forward.assign_from_sorted_edges(edge_begin, edge_end, global_to_local, source_pred, numverts, 0); - inherited_vertex_properties::resize(numverts); - } - - // From number of vertices and sorted list of edges (new interface) - template - compressed_sparse_row_graph(edges_are_sorted_global_t, - InputIterator edge_begin, InputIterator edge_end, - EdgePropertyIterator ep_iter, - const GlobalToLocal& global_to_local, - const SourcePred& source_pred, - vertices_size_type numverts, - const GraphProperty& prop = GraphProperty()) + { + m_forward.assign_from_sorted_edges( + edge_begin, edge_end, global_to_local, source_pred, numverts, 0); + inherited_vertex_properties::resize(numverts); + } + + // From number of vertices and sorted list of edges (new interface) + template < typename InputIterator, typename EdgePropertyIterator, + typename GlobalToLocal, typename SourcePred > + compressed_sparse_row_graph(edges_are_sorted_global_t, + InputIterator edge_begin, InputIterator edge_end, + EdgePropertyIterator ep_iter, const GlobalToLocal& global_to_local, + const SourcePred& source_pred, vertices_size_type numverts, + const GraphProperty& prop = GraphProperty()) : m_property(prop) - { - m_forward.assign_from_sorted_edges(edge_begin, edge_end, ep_iter, global_to_local, source_pred, numverts, 0); - inherited_vertex_properties::resize(numverts); - } - - // From number of vertices and mutable vectors of sources and targets; - // vectors are returned with unspecified contents but are guaranteed not to - // share storage with the constructed graph. - compressed_sparse_row_graph(construct_inplace_from_sources_and_targets_t, - std::vector& sources, - std::vector& targets, - vertices_size_type numverts, - const GraphProperty& prop = GraphProperty()) + { + m_forward.assign_from_sorted_edges(edge_begin, edge_end, ep_iter, + global_to_local, source_pred, numverts, 0); + inherited_vertex_properties::resize(numverts); + } + + // From number of vertices and mutable vectors of sources and targets; + // vectors are returned with unspecified contents but are guaranteed not to + // share storage with the constructed graph. + compressed_sparse_row_graph(construct_inplace_from_sources_and_targets_t, + std::vector< vertex_descriptor >& sources, + std::vector< vertex_descriptor >& targets, vertices_size_type numverts, + const GraphProperty& prop = GraphProperty()) : inherited_vertex_properties(numverts), m_property(prop) - { - m_forward.assign_sources_and_targets_global(sources, targets, numverts, boost::typed_identity_property_map()); - } - - // From number of vertices and mutable vectors of sources and targets, - // expressed with global vertex indices; vectors are returned with - // unspecified contents but are guaranteed not to share storage with the - // constructed graph. This constructor should only be used by the - // distributed CSR graph. - template - compressed_sparse_row_graph(construct_inplace_from_sources_and_targets_global_t, - std::vector& sources, - std::vector& targets, - vertices_size_type numlocalverts, - GlobalToLocal global_to_local, - const GraphProperty& prop = GraphProperty()) + { + m_forward.assign_sources_and_targets_global(sources, targets, numverts, + boost::typed_identity_property_map< vertices_size_type >()); + } + + // From number of vertices and mutable vectors of sources and targets, + // expressed with global vertex indices; vectors are returned with + // unspecified contents but are guaranteed not to share storage with the + // constructed graph. This constructor should only be used by the + // distributed CSR graph. + template < typename GlobalToLocal > + compressed_sparse_row_graph( + construct_inplace_from_sources_and_targets_global_t, + std::vector< vertex_descriptor >& sources, + std::vector< vertex_descriptor >& targets, + vertices_size_type numlocalverts, GlobalToLocal global_to_local, + const GraphProperty& prop = GraphProperty()) : inherited_vertex_properties(numlocalverts), m_property(prop) - { - m_forward.assign_sources_and_targets_global(sources, targets, numlocalverts, global_to_local); - } - - // From number of vertices and mutable vectors of sources, targets, and edge - // properties; vectors are returned with unspecified contents but are - // guaranteed not to share storage with the constructed graph. - compressed_sparse_row_graph(construct_inplace_from_sources_and_targets_t, - std::vector& sources, - std::vector& targets, - std::vector& edge_props, - vertices_size_type numverts, - const GraphProperty& prop = GraphProperty()) + { + m_forward.assign_sources_and_targets_global( + sources, targets, numlocalverts, global_to_local); + } + + // From number of vertices and mutable vectors of sources, targets, and + // edge properties; vectors are returned with unspecified contents but are + // guaranteed not to share storage with the constructed graph. + compressed_sparse_row_graph(construct_inplace_from_sources_and_targets_t, + std::vector< vertex_descriptor >& sources, + std::vector< vertex_descriptor >& targets, + std::vector< + typename forward_type::inherited_edge_properties::edge_bundled >& + edge_props, + vertices_size_type numverts, + const GraphProperty& prop = GraphProperty()) : inherited_vertex_properties(numverts), m_property(prop) - { - m_forward.assign_sources_and_targets_global(sources, targets, edge_props, numverts, boost::typed_identity_property_map()); - } - - // From number of vertices and mutable vectors of sources and targets and - // edge properties, expressed with global vertex indices; vectors are - // returned with unspecified contents but are guaranteed not to share - // storage with the constructed graph. This constructor should only be used - // by the distributed CSR graph. - template - compressed_sparse_row_graph(construct_inplace_from_sources_and_targets_global_t, - std::vector& sources, - std::vector& targets, - std::vector& edge_props, - vertices_size_type numlocalverts, - GlobalToLocal global_to_local, - const GraphProperty& prop = GraphProperty()) + { + m_forward.assign_sources_and_targets_global(sources, targets, + edge_props, numverts, + boost::typed_identity_property_map< vertices_size_type >()); + } + + // From number of vertices and mutable vectors of sources and targets and + // edge properties, expressed with global vertex indices; vectors are + // returned with unspecified contents but are guaranteed not to share + // storage with the constructed graph. This constructor should only be + // used by the distributed CSR graph. + template < typename GlobalToLocal > + compressed_sparse_row_graph( + construct_inplace_from_sources_and_targets_global_t, + std::vector< vertex_descriptor >& sources, + std::vector< vertex_descriptor >& targets, + std::vector< + typename forward_type::inherited_edge_properties::edge_bundled >& + edge_props, + vertices_size_type numlocalverts, GlobalToLocal global_to_local, + const GraphProperty& prop = GraphProperty()) : inherited_vertex_properties(numlocalverts), m_property(prop) - { - m_forward.assign_sources_and_targets_global(sources, targets, edge_props, numlocalverts, global_to_local); - } - - // From number of vertices and single-pass range of unsorted edges. Data is - // cached in coordinate form before creating the actual graph. - template - compressed_sparse_row_graph(edges_are_unsorted_t, - InputIterator edge_begin, InputIterator edge_end, - vertices_size_type numverts, - const GraphProperty& prop = GraphProperty()) + { + m_forward.assign_sources_and_targets_global( + sources, targets, edge_props, numlocalverts, global_to_local); + } + + // From number of vertices and single-pass range of unsorted edges. Data + // is cached in coordinate form before creating the actual graph. + template < typename InputIterator > + compressed_sparse_row_graph(edges_are_unsorted_t, InputIterator edge_begin, + InputIterator edge_end, vertices_size_type numverts, + const GraphProperty& prop = GraphProperty()) : inherited_vertex_properties(numverts), m_property(prop) - { - std::vector sources, targets; - boost::graph::detail::split_into_separate_coords - (edge_begin, edge_end, sources, targets); - m_forward.assign_sources_and_targets_global(sources, targets, numverts, boost::typed_identity_property_map()); - } - - // From number of vertices and single-pass range of unsorted edges and - // single-pass range of edge properties. Data is cached in coordinate form - // before creating the actual graph. - template - compressed_sparse_row_graph(edges_are_unsorted_t, - InputIterator edge_begin, InputIterator edge_end, - EdgePropertyIterator ep_iter, - vertices_size_type numverts, - const GraphProperty& prop = GraphProperty()) + { + std::vector< vertex_descriptor > sources, targets; + boost::graph::detail::split_into_separate_coords( + edge_begin, edge_end, sources, targets); + m_forward.assign_sources_and_targets_global(sources, targets, numverts, + boost::typed_identity_property_map< vertices_size_type >()); + } + + // From number of vertices and single-pass range of unsorted edges and + // single-pass range of edge properties. Data is cached in coordinate form + // before creating the actual graph. + template < typename InputIterator, typename EdgePropertyIterator > + compressed_sparse_row_graph(edges_are_unsorted_t, InputIterator edge_begin, + InputIterator edge_end, EdgePropertyIterator ep_iter, + vertices_size_type numverts, + const GraphProperty& prop = GraphProperty()) : inherited_vertex_properties(numverts), m_property(prop) - { - std::vector sources, targets; - boost::graph::detail::split_into_separate_coords - (edge_begin, edge_end, sources, targets); - size_t numedges = sources.size(); - std::vector edge_props(numedges); - for (size_t i = 0; i < numedges; ++i) { - edge_props[i] = *ep_iter++; + { + std::vector< vertex_descriptor > sources, targets; + boost::graph::detail::split_into_separate_coords( + edge_begin, edge_end, sources, targets); + size_t numedges = sources.size(); + std::vector< + typename forward_type::inherited_edge_properties::edge_bundled > + edge_props(numedges); + for (size_t i = 0; i < numedges; ++i) + { + edge_props[i] = *ep_iter++; + } + m_forward.assign_sources_and_targets_global(sources, targets, + edge_props, numverts, + boost::typed_identity_property_map< vertices_size_type >()); } - m_forward.assign_sources_and_targets_global(sources, targets, edge_props, numverts, boost::typed_identity_property_map()); - } - - // From number of vertices and single-pass range of unsorted edges. Data is - // cached in coordinate form before creating the actual graph. Edges are - // filtered and transformed for use in a distributed graph. - template - compressed_sparse_row_graph(edges_are_unsorted_global_t, - InputIterator edge_begin, InputIterator edge_end, - vertices_size_type numlocalverts, - GlobalToLocal global_to_local, - const SourcePred& source_pred, - const GraphProperty& prop = GraphProperty()) + + // From number of vertices and single-pass range of unsorted edges. Data + // is cached in coordinate form before creating the actual graph. Edges + // are filtered and transformed for use in a distributed graph. + template < typename InputIterator, typename GlobalToLocal, + typename SourcePred > + compressed_sparse_row_graph(edges_are_unsorted_global_t, + InputIterator edge_begin, InputIterator edge_end, + vertices_size_type numlocalverts, GlobalToLocal global_to_local, + const SourcePred& source_pred, + const GraphProperty& prop = GraphProperty()) : inherited_vertex_properties(numlocalverts), m_property(prop) - { - std::vector sources, targets; - boost::graph::detail::split_into_separate_coords_filtered - (edge_begin, edge_end, sources, targets, source_pred); - m_forward.assign_sources_and_targets_global(sources, targets, numlocalverts, global_to_local); - } - - // From number of vertices and single-pass range of unsorted edges and - // single-pass range of edge properties. Data is cached in coordinate form - // before creating the actual graph. Edges are filtered and transformed for - // use in a distributed graph. - template - compressed_sparse_row_graph(edges_are_unsorted_global_t, - InputIterator edge_begin, InputIterator edge_end, - EdgePropertyIterator ep_iter, - vertices_size_type numlocalverts, - GlobalToLocal global_to_local, - const SourcePred& source_pred, - const GraphProperty& prop = GraphProperty()) + { + std::vector< vertex_descriptor > sources, targets; + boost::graph::detail::split_into_separate_coords_filtered( + edge_begin, edge_end, sources, targets, source_pred); + m_forward.assign_sources_and_targets_global( + sources, targets, numlocalverts, global_to_local); + } + + // From number of vertices and single-pass range of unsorted edges and + // single-pass range of edge properties. Data is cached in coordinate form + // before creating the actual graph. Edges are filtered and transformed + // for use in a distributed graph. + template < typename InputIterator, typename EdgePropertyIterator, + typename GlobalToLocal, typename SourcePred > + compressed_sparse_row_graph(edges_are_unsorted_global_t, + InputIterator edge_begin, InputIterator edge_end, + EdgePropertyIterator ep_iter, vertices_size_type numlocalverts, + GlobalToLocal global_to_local, const SourcePred& source_pred, + const GraphProperty& prop = GraphProperty()) : inherited_vertex_properties(numlocalverts), m_property(prop) - { - std::vector sources, targets; - std::vector edge_props; - boost::graph::detail::split_into_separate_coords_filtered - (edge_begin, edge_end, ep_iter, sources, targets, edge_props, source_pred); - m_forward.assign_sources_and_targets_global(sources, targets, edge_props, numlocalverts, global_to_local); - } - - - // Requires IncidenceGraph and a vertex index map - template - compressed_sparse_row_graph(const Graph& g, const VertexIndexMap& vi, - vertices_size_type numverts, - edges_size_type numedges) - : m_property() - { - assign(g, vi, numverts, numedges); - inherited_vertex_properties::resize(numverts); - } - - // Requires VertexListGraph and EdgeListGraph - template - compressed_sparse_row_graph(const Graph& g, const VertexIndexMap& vi) + { + std::vector< vertex_descriptor > sources, targets; + std::vector< edge_bundled > edge_props; + boost::graph::detail::split_into_separate_coords_filtered(edge_begin, + edge_end, ep_iter, sources, targets, edge_props, source_pred); + m_forward.assign_sources_and_targets_global( + sources, targets, edge_props, numlocalverts, global_to_local); + } + + // Requires IncidenceGraph and a vertex index map + template < typename Graph, typename VertexIndexMap > + compressed_sparse_row_graph(const Graph& g, const VertexIndexMap& vi, + vertices_size_type numverts, edges_size_type numedges) : m_property() - { - typename graph_traits::edges_size_type numedges = num_edges(g); - if (is_same::directed_category, undirectedS>::value) { - numedges *= 2; // Double each edge (actual doubling done by out_edges function) + { + assign(g, vi, numverts, numedges); + inherited_vertex_properties::resize(numverts); } - vertices_size_type numverts = num_vertices(g); - assign(g, vi, numverts, numedges); - inherited_vertex_properties::resize(numverts); - } - - // Requires vertex index map plus requirements of previous constructor - template - explicit compressed_sparse_row_graph(const Graph& g) + + // Requires VertexListGraph and EdgeListGraph + template < typename Graph, typename VertexIndexMap > + compressed_sparse_row_graph(const Graph& g, const VertexIndexMap& vi) : m_property() - { - typename graph_traits::edges_size_type numedges = num_edges(g); - if (is_same::directed_category, undirectedS>::value) { - numedges *= 2; // Double each edge (actual doubling done by out_edges function) + { + typename graph_traits< Graph >::edges_size_type numedges = num_edges(g); + if (is_same< typename graph_traits< Graph >::directed_category, + undirectedS >::value) + { + numedges *= 2; // Double each edge (actual doubling done by + // out_edges function) + } + vertices_size_type numverts = num_vertices(g); + assign(g, vi, numverts, numedges); + inherited_vertex_properties::resize(numverts); + } + + // Requires vertex index map plus requirements of previous constructor + template < typename Graph > + explicit compressed_sparse_row_graph(const Graph& g) : m_property() + { + typename graph_traits< Graph >::edges_size_type numedges = num_edges(g); + if (is_same< typename graph_traits< Graph >::directed_category, + undirectedS >::value) + { + numedges *= 2; // Double each edge (actual doubling done by + // out_edges function) + } + assign(g, get(vertex_index, g), num_vertices(g), numedges); + } + + // From any graph (slow and uses a lot of memory) + // Requires IncidenceGraph and a vertex index map + // Internal helper function + // Note that numedges must be doubled for undirected source graphs + template < typename Graph, typename VertexIndexMap > + void assign(const Graph& g, const VertexIndexMap& vi, + vertices_size_type numverts, edges_size_type numedges) + { + m_forward.assign(g, vi, numverts, numedges); + inherited_vertex_properties::resize(numverts); + } + + // Requires the above, plus VertexListGraph and EdgeListGraph + template < typename Graph, typename VertexIndexMap > + void assign(const Graph& g, const VertexIndexMap& vi) + { + typename graph_traits< Graph >::edges_size_type numedges = num_edges(g); + if (is_same< typename graph_traits< Graph >::directed_category, + undirectedS >::value) + { + numedges *= 2; // Double each edge (actual doubling done by + // out_edges function) + } + vertices_size_type numverts = num_vertices(g); + m_forward.assign(g, vi, numverts, numedges); + inherited_vertex_properties::resize(numverts); + } + + // Requires the above, plus a vertex_index map. + template < typename Graph > void assign(const Graph& g) + { + typename graph_traits< Graph >::edges_size_type numedges = num_edges(g); + if (is_same< typename graph_traits< Graph >::directed_category, + undirectedS >::value) + { + numedges *= 2; // Double each edge (actual doubling done by + // out_edges function) + } + vertices_size_type numverts = num_vertices(g); + m_forward.assign(g, get(vertex_index, g), numverts, numedges); + inherited_vertex_properties::resize(numverts); + } + + // Add edges from a sorted (smallest sources first) range of pairs and edge + // properties + template < typename BidirectionalIteratorOrig, typename EPIterOrig, + typename GlobalToLocal > + void add_edges_sorted_internal(BidirectionalIteratorOrig first_sorted, + BidirectionalIteratorOrig last_sorted, EPIterOrig ep_iter_sorted, + const GlobalToLocal& global_to_local) + { + m_forward.add_edges_sorted_internal( + first_sorted, last_sorted, ep_iter_sorted, global_to_local); + } + + template < typename BidirectionalIteratorOrig, typename EPIterOrig > + void add_edges_sorted_internal(BidirectionalIteratorOrig first_sorted, + BidirectionalIteratorOrig last_sorted, EPIterOrig ep_iter_sorted) + { + m_forward.add_edges_sorted_internal(first_sorted, last_sorted, + ep_iter_sorted, + typed_identity_property_map< vertices_size_type >()); + } + + // Add edges from a sorted (smallest sources first) range of pairs + template < typename BidirectionalIteratorOrig > + void add_edges_sorted_internal(BidirectionalIteratorOrig first_sorted, + BidirectionalIteratorOrig last_sorted) + { + m_forward.add_edges_sorted_internal(first_sorted, last_sorted, + detail::default_construct_iterator< edge_bundled >()); + } + + template < typename BidirectionalIteratorOrig, typename GlobalToLocal > + void add_edges_sorted_internal_global( + BidirectionalIteratorOrig first_sorted, + BidirectionalIteratorOrig last_sorted, + const GlobalToLocal& global_to_local) + { + m_forward.add_edges_sorted_internal(first_sorted, last_sorted, + detail::default_construct_iterator< edge_bundled >(), + global_to_local); + } + + template < typename BidirectionalIteratorOrig, typename EPIterOrig, + typename GlobalToLocal > + void add_edges_sorted_internal_global( + BidirectionalIteratorOrig first_sorted, + BidirectionalIteratorOrig last_sorted, EPIterOrig ep_iter_sorted, + const GlobalToLocal& global_to_local) + { + m_forward.add_edges_sorted_internal( + first_sorted, last_sorted, ep_iter_sorted, global_to_local); + } + + // Add edges from a range of (source, target) pairs that are unsorted + template < typename InputIterator, typename GlobalToLocal > + inline void add_edges_internal(InputIterator first, InputIterator last, + const GlobalToLocal& global_to_local) + { + typedef compressed_sparse_row_graph Graph; + typedef + typename boost::graph_traits< Graph >::vertex_descriptor vertex_t; + typedef std::vector< std::pair< vertex_t, vertex_t > > edge_vector_t; + edge_vector_t new_edges(first, last); + if (new_edges.empty()) + return; + std::sort(new_edges.begin(), new_edges.end()); + this->add_edges_sorted_internal_global( + new_edges.begin(), new_edges.end(), global_to_local); + } + + template < typename InputIterator > + inline void add_edges_internal(InputIterator first, InputIterator last) + { + this->add_edges_internal( + first, last, typed_identity_property_map< vertices_size_type >()); + } + + // Add edges from a range of (source, target) pairs and edge properties that + // are unsorted + template < typename InputIterator, typename EPIterator, + typename GlobalToLocal > + inline void add_edges_internal(InputIterator first, InputIterator last, + EPIterator ep_iter, EPIterator ep_iter_end, + const GlobalToLocal& global_to_local) + { + typedef compressed_sparse_row_graph Graph; + typedef + typename boost::graph_traits< Graph >::vertex_descriptor vertex_t; + typedef std::pair< vertex_t, vertex_t > vertex_pair; + typedef std::vector< boost::tuple< vertex_pair, edge_bundled > > + edge_vector_t; + edge_vector_t new_edges( + boost::make_zip_iterator(boost::make_tuple(first, ep_iter)), + boost::make_zip_iterator(boost::make_tuple(last, ep_iter_end))); + if (new_edges.empty()) + return; + std::sort(new_edges.begin(), new_edges.end(), + boost::detail::compare_first< std::less< vertex_pair > >()); + m_forward.add_edges_sorted_internal( + boost::make_transform_iterator(new_edges.begin(), + boost::detail::my_tuple_get_class< 0, vertex_pair >()), + boost::make_transform_iterator(new_edges.end(), + boost::detail::my_tuple_get_class< 0, vertex_pair >()), + boost::make_transform_iterator(new_edges.begin(), + boost::detail::my_tuple_get_class< 1, edge_bundled >()), + global_to_local); + } + + // Add edges from a range of (source, target) pairs and edge properties that + // are unsorted + template < typename InputIterator, typename EPIterator > + inline void add_edges_internal(InputIterator first, InputIterator last, + EPIterator ep_iter, EPIterator ep_iter_end) + { + this->add_edges_internal(first, last, ep_iter, ep_iter_end, + typed_identity_property_map< vertices_size_type >()); + } + + using inherited_vertex_properties::operator[]; + + // Directly access a edge or edge bundle + edge_push_back_type& operator[](const edge_descriptor& v) + { + return m_forward.m_edge_properties[get(edge_index, *this, v)]; } - assign(g, get(vertex_index, g), num_vertices(g), numedges); - } - - // From any graph (slow and uses a lot of memory) - // Requires IncidenceGraph and a vertex index map - // Internal helper function - // Note that numedges must be doubled for undirected source graphs - template - void - assign(const Graph& g, const VertexIndexMap& vi, - vertices_size_type numverts, edges_size_type numedges) - { - m_forward.assign(g, vi, numverts, numedges); - inherited_vertex_properties::resize(numverts); - } - - // Requires the above, plus VertexListGraph and EdgeListGraph - template - void assign(const Graph& g, const VertexIndexMap& vi) - { - typename graph_traits::edges_size_type numedges = num_edges(g); - if (is_same::directed_category, undirectedS>::value) { - numedges *= 2; // Double each edge (actual doubling done by out_edges function) + + const edge_push_back_type& operator[](const edge_descriptor& v) const + { + return m_forward.m_edge_properties[get(edge_index, *this, v)]; + } + + // Directly access a graph bundle + graph_bundled& operator[](graph_bundle_t) { return get_property(*this); } + + const graph_bundled& operator[](graph_bundle_t) const + { + return get_property(*this); + } + + // private: non-portable, requires friend templates + inherited_vertex_properties& vertex_properties() { return *this; } + const inherited_vertex_properties& vertex_properties() const + { + return *this; } - vertices_size_type numverts = num_vertices(g); - m_forward.assign(g, vi, numverts, numedges); - inherited_vertex_properties::resize(numverts); - } - - // Requires the above, plus a vertex_index map. - template - void assign(const Graph& g) - { - typename graph_traits::edges_size_type numedges = num_edges(g); - if (is_same::directed_category, undirectedS>::value) { - numedges *= 2; // Double each edge (actual doubling done by out_edges function) + typename forward_type::inherited_edge_properties& edge_properties() + { + return m_forward; } - vertices_size_type numverts = num_vertices(g); - m_forward.assign(g, get(vertex_index, g), numverts, numedges); - inherited_vertex_properties::resize(numverts); - } - - // Add edges from a sorted (smallest sources first) range of pairs and edge - // properties - template - void - add_edges_sorted_internal( - BidirectionalIteratorOrig first_sorted, - BidirectionalIteratorOrig last_sorted, - EPIterOrig ep_iter_sorted, - const GlobalToLocal& global_to_local) { - m_forward.add_edges_sorted_internal(first_sorted, last_sorted, ep_iter_sorted, global_to_local); - } - - template - void - add_edges_sorted_internal( - BidirectionalIteratorOrig first_sorted, - BidirectionalIteratorOrig last_sorted, - EPIterOrig ep_iter_sorted) { - m_forward.add_edges_sorted_internal(first_sorted, last_sorted, ep_iter_sorted, typed_identity_property_map()); - } - - // Add edges from a sorted (smallest sources first) range of pairs - template - void - add_edges_sorted_internal( - BidirectionalIteratorOrig first_sorted, - BidirectionalIteratorOrig last_sorted) { - m_forward.add_edges_sorted_internal(first_sorted, last_sorted, detail::default_construct_iterator()); - } - - template - void - add_edges_sorted_internal_global( - BidirectionalIteratorOrig first_sorted, - BidirectionalIteratorOrig last_sorted, - const GlobalToLocal& global_to_local) { - m_forward.add_edges_sorted_internal(first_sorted, last_sorted, detail::default_construct_iterator(), global_to_local); - } - - template - void - add_edges_sorted_internal_global( - BidirectionalIteratorOrig first_sorted, - BidirectionalIteratorOrig last_sorted, - EPIterOrig ep_iter_sorted, - const GlobalToLocal& global_to_local) { - m_forward.add_edges_sorted_internal(first_sorted, last_sorted, ep_iter_sorted, global_to_local); - } - - // Add edges from a range of (source, target) pairs that are unsorted - template - inline void - add_edges_internal(InputIterator first, InputIterator last, - const GlobalToLocal& global_to_local) { - typedef compressed_sparse_row_graph Graph; - typedef typename boost::graph_traits::vertex_descriptor vertex_t; - typedef std::vector > edge_vector_t; - edge_vector_t new_edges(first, last); - if (new_edges.empty()) return; - std::sort(new_edges.begin(), new_edges.end()); - this->add_edges_sorted_internal_global(new_edges.begin(), new_edges.end(), global_to_local); - } - - template - inline void - add_edges_internal(InputIterator first, InputIterator last) { - this->add_edges_internal(first, last, typed_identity_property_map()); - } - - // Add edges from a range of (source, target) pairs and edge properties that - // are unsorted - template - inline void - add_edges_internal(InputIterator first, InputIterator last, - EPIterator ep_iter, EPIterator ep_iter_end, - const GlobalToLocal& global_to_local) { - typedef compressed_sparse_row_graph Graph; - typedef typename boost::graph_traits::vertex_descriptor vertex_t; - typedef std::pair vertex_pair; - typedef std::vector< - boost::tuple > - edge_vector_t; - edge_vector_t new_edges - (boost::make_zip_iterator(boost::make_tuple(first, ep_iter)), - boost::make_zip_iterator(boost::make_tuple(last, ep_iter_end))); - if (new_edges.empty()) return; - std::sort(new_edges.begin(), new_edges.end(), - boost::detail::compare_first< - std::less >()); - m_forward.add_edges_sorted_internal - (boost::make_transform_iterator( - new_edges.begin(), - boost::detail::my_tuple_get_class<0, vertex_pair>()), - boost::make_transform_iterator( - new_edges.end(), - boost::detail::my_tuple_get_class<0, vertex_pair>()), - boost::make_transform_iterator( - new_edges.begin(), - boost::detail::my_tuple_get_class - <1, edge_bundled>()), - global_to_local); - } - - // Add edges from a range of (source, target) pairs and edge properties that - // are unsorted - template - inline void - add_edges_internal(InputIterator first, InputIterator last, - EPIterator ep_iter, EPIterator ep_iter_end) { - this->add_edges_internal(first, last, ep_iter, ep_iter_end, typed_identity_property_map()); - } - - using inherited_vertex_properties::operator[]; - - // Directly access a edge or edge bundle - edge_push_back_type& operator[](const edge_descriptor& v) - { return m_forward.m_edge_properties[get(edge_index, *this, v)]; } - - const edge_push_back_type& operator[](const edge_descriptor& v) const - { return m_forward.m_edge_properties[get(edge_index, *this, v)]; } - - // Directly access a graph bundle - graph_bundled& operator[](graph_bundle_t) - { return get_property(*this); } - - const graph_bundled& operator[](graph_bundle_t) const - { return get_property(*this); } - - // private: non-portable, requires friend templates - inherited_vertex_properties& vertex_properties() {return *this;} - const inherited_vertex_properties& vertex_properties() const {return *this;} - typename forward_type::inherited_edge_properties& edge_properties() { return m_forward; } - const typename forward_type::inherited_edge_properties& edge_properties() const { return m_forward; } - - forward_type m_forward; - GraphProperty m_property; + const typename forward_type::inherited_edge_properties& + edge_properties() const + { + return m_forward; + } + + forward_type m_forward; + GraphProperty m_property; }; -template -class compressed_sparse_row_graph - : public detail::indexed_vertex_properties > -{ - public: - typedef detail::indexed_vertex_properties > - inherited_vertex_properties; - - public: - // For Property Graph - typedef GraphProperty graph_property_type; - typedef typename lookup_one_property::type graph_bundled; - // typedef GraphProperty graph_property_type; - - typedef detail::compressed_sparse_row_structure forward_type; - typedef EdgeIndex /* typename boost::mpl::if_c, boost::no_property, EdgeIndex> */ backward_edge_property; - typedef detail::compressed_sparse_row_structure backward_type; - - public: - // Concept requirements: - // For Graph - typedef Vertex vertex_descriptor; - typedef detail::csr_edge_descriptor edge_descriptor; - typedef bidirectional_tag directed_category; - typedef allow_parallel_edge_tag edge_parallel_category; - - class traversal_category: public bidirectional_graph_tag, - public adjacency_graph_tag, - public vertex_list_graph_tag, - public edge_list_graph_tag {}; - - static vertex_descriptor null_vertex() { return vertex_descriptor(-1); } - - // For VertexListGraph - typedef counting_iterator vertex_iterator; - typedef Vertex vertices_size_type; - - // For EdgeListGraph - typedef EdgeIndex edges_size_type; - - // For IncidenceGraph - typedef detail::csr_out_edge_iterator out_edge_iterator; - typedef EdgeIndex degree_size_type; - - // For AdjacencyGraph - typedef typename std::vector::const_iterator adjacency_iterator; - - // For EdgeListGraph - typedef detail::csr_edge_iterator edge_iterator; - - // For BidirectionalGraph (not implemented) - typedef detail::csr_in_edge_iterator in_edge_iterator; - - // For internal use - typedef csr_graph_tag graph_tag; - - typedef typename forward_type::inherited_edge_properties::edge_bundled edge_bundled; - typedef typename forward_type::inherited_edge_properties::edge_push_back_type edge_push_back_type; - typedef typename forward_type::inherited_edge_properties::edge_property_type edge_property_type; - - // Constructors - - // Default constructor: an empty graph. - compressed_sparse_row_graph(): m_property() {} - - // With numverts vertices - compressed_sparse_row_graph(vertices_size_type numverts) - : inherited_vertex_properties(numverts), - m_forward(numverts), m_backward(numverts) {} - - private: - - void set_up_backward_property_links() { - std::pair e = edges(*this); - m_backward.assign_unsorted_multi_pass_edges - (detail::transpose_edges( - detail::make_edge_to_index_pair_iter - (*this, get(vertex_index, *this), e.first)), - detail::transpose_edges( - detail::make_edge_to_index_pair_iter - (*this, get(vertex_index, *this), e.second)), - boost::counting_iterator(0), - m_forward.m_rowstart.size() - 1, - typed_identity_property_map(), - keep_all()); - } - - public: - - // From number of vertices and unsorted list of edges - template - compressed_sparse_row_graph(edges_are_unsorted_multi_pass_t, - MultiPassInputIterator edge_begin, - MultiPassInputIterator edge_end, - vertices_size_type numverts, - const GraphProperty& prop = GraphProperty()) +template < typename VertexProperty, typename EdgeProperty, + typename GraphProperty, typename Vertex, typename EdgeIndex > +class compressed_sparse_row_graph< bidirectionalS, VertexProperty, EdgeProperty, + GraphProperty, Vertex, EdgeIndex > +: public detail::indexed_vertex_properties< BOOST_BIDIR_CSR_GRAPH_TYPE, + VertexProperty, Vertex, typed_identity_property_map< Vertex > > +{ +public: + typedef detail::indexed_vertex_properties< compressed_sparse_row_graph, + VertexProperty, Vertex, typed_identity_property_map< Vertex > > + inherited_vertex_properties; + +public: + // For Property Graph + typedef GraphProperty graph_property_type; + typedef typename lookup_one_property< GraphProperty, graph_bundle_t >::type + graph_bundled; + // typedef GraphProperty graph_property_type; + + typedef detail::compressed_sparse_row_structure< EdgeProperty, Vertex, + EdgeIndex > + forward_type; + typedef EdgeIndex /* typename boost::mpl::if_c, boost::no_property, EdgeIndex> */ + backward_edge_property; + typedef detail::compressed_sparse_row_structure< backward_edge_property, + Vertex, EdgeIndex > + backward_type; + +public: + // Concept requirements: + // For Graph + typedef Vertex vertex_descriptor; + typedef detail::csr_edge_descriptor< Vertex, EdgeIndex > edge_descriptor; + typedef bidirectional_tag directed_category; + typedef allow_parallel_edge_tag edge_parallel_category; + + class traversal_category : public bidirectional_graph_tag, + public adjacency_graph_tag, + public vertex_list_graph_tag, + public edge_list_graph_tag + { + }; + + static vertex_descriptor null_vertex() { return vertex_descriptor(-1); } + + // For VertexListGraph + typedef counting_iterator< Vertex > vertex_iterator; + typedef Vertex vertices_size_type; + + // For EdgeListGraph + typedef EdgeIndex edges_size_type; + + // For IncidenceGraph + typedef detail::csr_out_edge_iterator< compressed_sparse_row_graph > + out_edge_iterator; + typedef EdgeIndex degree_size_type; + + // For AdjacencyGraph + typedef typename std::vector< Vertex >::const_iterator adjacency_iterator; + + // For EdgeListGraph + typedef detail::csr_edge_iterator< compressed_sparse_row_graph > + edge_iterator; + + // For BidirectionalGraph (not implemented) + typedef detail::csr_in_edge_iterator< compressed_sparse_row_graph > + in_edge_iterator; + + // For internal use + typedef csr_graph_tag graph_tag; + + typedef typename forward_type::inherited_edge_properties::edge_bundled + edge_bundled; + typedef + typename forward_type::inherited_edge_properties::edge_push_back_type + edge_push_back_type; + typedef typename forward_type::inherited_edge_properties::edge_property_type + edge_property_type; + + // Constructors + + // Default constructor: an empty graph. + compressed_sparse_row_graph() : m_property() {} + + // With numverts vertices + compressed_sparse_row_graph(vertices_size_type numverts) + : inherited_vertex_properties(numverts) + , m_forward(numverts) + , m_backward(numverts) + { + } + +private: + void set_up_backward_property_links() + { + std::pair< edge_iterator, edge_iterator > e = edges(*this); + m_backward.assign_unsorted_multi_pass_edges( + detail::transpose_edges(detail::make_edge_to_index_pair_iter( + *this, get(vertex_index, *this), e.first)), + detail::transpose_edges(detail::make_edge_to_index_pair_iter( + *this, get(vertex_index, *this), e.second)), + boost::counting_iterator< EdgeIndex >(0), + m_forward.m_rowstart.size() - 1, + typed_identity_property_map< Vertex >(), keep_all()); + } + +public: + // From number of vertices and unsorted list of edges + template < typename MultiPassInputIterator > + compressed_sparse_row_graph(edges_are_unsorted_multi_pass_t, + MultiPassInputIterator edge_begin, MultiPassInputIterator edge_end, + vertices_size_type numverts, + const GraphProperty& prop = GraphProperty()) : inherited_vertex_properties(numverts), m_property(prop) - { - m_forward.assign_unsorted_multi_pass_edges(edge_begin, edge_end, numverts, typed_identity_property_map(), keep_all()); - set_up_backward_property_links(); - } - - // From number of vertices and unsorted list of edges, plus edge properties - template - compressed_sparse_row_graph(edges_are_unsorted_multi_pass_t, - MultiPassInputIterator edge_begin, - MultiPassInputIterator edge_end, - EdgePropertyIterator ep_iter, - vertices_size_type numverts, - const GraphProperty& prop = GraphProperty()) + { + m_forward.assign_unsorted_multi_pass_edges(edge_begin, edge_end, + numverts, typed_identity_property_map< Vertex >(), keep_all()); + set_up_backward_property_links(); + } + + // From number of vertices and unsorted list of edges, plus edge properties + template < typename MultiPassInputIterator, typename EdgePropertyIterator > + compressed_sparse_row_graph(edges_are_unsorted_multi_pass_t, + MultiPassInputIterator edge_begin, MultiPassInputIterator edge_end, + EdgePropertyIterator ep_iter, vertices_size_type numverts, + const GraphProperty& prop = GraphProperty()) : inherited_vertex_properties(numverts), m_forward(), m_property(prop) - { - m_forward.assign_unsorted_multi_pass_edges(edge_begin, edge_end, ep_iter, numverts, typed_identity_property_map(), keep_all()); - set_up_backward_property_links(); - } - - // From number of vertices and unsorted list of edges, with filter and - // global-to-local map - template - compressed_sparse_row_graph(edges_are_unsorted_multi_pass_global_t, - MultiPassInputIterator edge_begin, - MultiPassInputIterator edge_end, - vertices_size_type numlocalverts, - const GlobalToLocal& global_to_local, - const SourcePred& source_pred, - const GraphProperty& prop = GraphProperty()) + { + m_forward.assign_unsorted_multi_pass_edges(edge_begin, edge_end, + ep_iter, numverts, typed_identity_property_map< Vertex >(), + keep_all()); + set_up_backward_property_links(); + } + + // From number of vertices and unsorted list of edges, with filter and + // global-to-local map + template < typename MultiPassInputIterator, typename GlobalToLocal, + typename SourcePred > + compressed_sparse_row_graph(edges_are_unsorted_multi_pass_global_t, + MultiPassInputIterator edge_begin, MultiPassInputIterator edge_end, + vertices_size_type numlocalverts, const GlobalToLocal& global_to_local, + const SourcePred& source_pred, + const GraphProperty& prop = GraphProperty()) : inherited_vertex_properties(numlocalverts), m_forward(), m_property(prop) - { - m_forward.assign_unsorted_multi_pass_edges(edge_begin, edge_end, numlocalverts, global_to_local, source_pred); - set_up_backward_property_links(); - } - - // From number of vertices and unsorted list of edges, plus edge properties, - // with filter and global-to-local map - template - compressed_sparse_row_graph(edges_are_unsorted_multi_pass_global_t, - MultiPassInputIterator edge_begin, - MultiPassInputIterator edge_end, - EdgePropertyIterator ep_iter, - vertices_size_type numlocalverts, - const GlobalToLocal& global_to_local, - const SourcePred& source_pred, - const GraphProperty& prop = GraphProperty()) + { + m_forward.assign_unsorted_multi_pass_edges( + edge_begin, edge_end, numlocalverts, global_to_local, source_pred); + set_up_backward_property_links(); + } + + // From number of vertices and unsorted list of edges, plus edge + // properties, with filter and global-to-local map + template < typename MultiPassInputIterator, typename EdgePropertyIterator, + typename GlobalToLocal, typename SourcePred > + compressed_sparse_row_graph(edges_are_unsorted_multi_pass_global_t, + MultiPassInputIterator edge_begin, MultiPassInputIterator edge_end, + EdgePropertyIterator ep_iter, vertices_size_type numlocalverts, + const GlobalToLocal& global_to_local, const SourcePred& source_pred, + const GraphProperty& prop = GraphProperty()) : inherited_vertex_properties(numlocalverts), m_forward(), m_property(prop) - { - m_forward.assign_unsorted_multi_pass_edges(edge_begin, edge_end, ep_iter, numlocalverts, global_to_local, source_pred); - set_up_backward_property_links(); - } - - // Requires IncidenceGraph and a vertex index map - template - compressed_sparse_row_graph(const Graph& g, const VertexIndexMap& vi, - vertices_size_type numverts, - edges_size_type numedges) - : m_property() - { - assign(g, vi, numverts, numedges); - inherited_vertex_properties::resize(numverts); - } - - // Requires VertexListGraph and EdgeListGraph - template - compressed_sparse_row_graph(const Graph& g, const VertexIndexMap& vi) + { + m_forward.assign_unsorted_multi_pass_edges(edge_begin, edge_end, + ep_iter, numlocalverts, global_to_local, source_pred); + set_up_backward_property_links(); + } + + // Requires IncidenceGraph and a vertex index map + template < typename Graph, typename VertexIndexMap > + compressed_sparse_row_graph(const Graph& g, const VertexIndexMap& vi, + vertices_size_type numverts, edges_size_type numedges) : m_property() - { - typename graph_traits::edges_size_type numedges = num_edges(g); - if (is_same::directed_category, undirectedS>::value) { - numedges *= 2; // Double each edge (actual doubling done by out_edges function) + { + assign(g, vi, numverts, numedges); + inherited_vertex_properties::resize(numverts); } - vertices_size_type numverts = num_vertices(g); - assign(g, vi, numverts, numedges); - inherited_vertex_properties::resize(numverts); - } - - // Requires vertex index map plus requirements of previous constructor - template - explicit compressed_sparse_row_graph(const Graph& g) + + // Requires VertexListGraph and EdgeListGraph + template < typename Graph, typename VertexIndexMap > + compressed_sparse_row_graph(const Graph& g, const VertexIndexMap& vi) : m_property() - { - typename graph_traits::edges_size_type numedges = num_edges(g); - if (is_same::directed_category, undirectedS>::value) { - numedges *= 2; // Double each edge (actual doubling done by out_edges function) + { + typename graph_traits< Graph >::edges_size_type numedges = num_edges(g); + if (is_same< typename graph_traits< Graph >::directed_category, + undirectedS >::value) + { + numedges *= 2; // Double each edge (actual doubling done by + // out_edges function) + } + vertices_size_type numverts = num_vertices(g); + assign(g, vi, numverts, numedges); + inherited_vertex_properties::resize(numverts); + } + + // Requires vertex index map plus requirements of previous constructor + template < typename Graph > + explicit compressed_sparse_row_graph(const Graph& g) : m_property() + { + typename graph_traits< Graph >::edges_size_type numedges = num_edges(g); + if (is_same< typename graph_traits< Graph >::directed_category, + undirectedS >::value) + { + numedges *= 2; // Double each edge (actual doubling done by + // out_edges function) + } + assign(g, get(vertex_index, g), num_vertices(g), numedges); } - assign(g, get(vertex_index, g), num_vertices(g), numedges); - } - - // From any graph (slow and uses a lot of memory) - // Requires IncidenceGraph and a vertex index map - // Internal helper function - // Note that numedges must be doubled for undirected source graphs - template - void - assign(const Graph& g, const VertexIndexMap& vi, - vertices_size_type numverts, edges_size_type numedges) - { - m_forward.assign(g, vi, numverts, numedges); - inherited_vertex_properties::resize(numverts); - set_up_backward_property_links(); - } - - // Requires the above, plus VertexListGraph and EdgeListGraph - template - void assign(const Graph& g, const VertexIndexMap& vi) - { - typename graph_traits::edges_size_type numedges = num_edges(g); - if (is_same::directed_category, undirectedS>::value) { - numedges *= 2; // Double each edge (actual doubling done by out_edges function) + + // From any graph (slow and uses a lot of memory) + // Requires IncidenceGraph and a vertex index map + // Internal helper function + // Note that numedges must be doubled for undirected source graphs + template < typename Graph, typename VertexIndexMap > + void assign(const Graph& g, const VertexIndexMap& vi, + vertices_size_type numverts, edges_size_type numedges) + { + m_forward.assign(g, vi, numverts, numedges); + inherited_vertex_properties::resize(numverts); + set_up_backward_property_links(); } - vertices_size_type numverts = num_vertices(g); - m_forward.assign(g, vi, numverts, numedges); - inherited_vertex_properties::resize(numverts); - set_up_backward_property_links(); - } - - // Requires the above, plus a vertex_index map. - template - void assign(const Graph& g) - { - typename graph_traits::edges_size_type numedges = num_edges(g); - if (is_same::directed_category, undirectedS>::value) { - numedges *= 2; // Double each edge (actual doubling done by out_edges function) + + // Requires the above, plus VertexListGraph and EdgeListGraph + template < typename Graph, typename VertexIndexMap > + void assign(const Graph& g, const VertexIndexMap& vi) + { + typename graph_traits< Graph >::edges_size_type numedges = num_edges(g); + if (is_same< typename graph_traits< Graph >::directed_category, + undirectedS >::value) + { + numedges *= 2; // Double each edge (actual doubling done by + // out_edges function) + } + vertices_size_type numverts = num_vertices(g); + m_forward.assign(g, vi, numverts, numedges); + inherited_vertex_properties::resize(numverts); + set_up_backward_property_links(); } - vertices_size_type numverts = num_vertices(g); - m_forward.assign(g, get(vertex_index, g), numverts, numedges); - inherited_vertex_properties::resize(numverts); - set_up_backward_property_links(); - } - - using inherited_vertex_properties::operator[]; - - // Directly access a edge or edge bundle - edge_push_back_type& operator[](const edge_descriptor& v) - { return m_forward.m_edge_properties[get(edge_index, *this, v)]; } - - const edge_push_back_type& operator[](const edge_descriptor& v) const - { return m_forward.m_edge_properties[get(edge_index, *this, v)]; } - - // private: non-portable, requires friend templates - inherited_vertex_properties& vertex_properties() {return *this;} - const inherited_vertex_properties& vertex_properties() const {return *this;} - typename forward_type::inherited_edge_properties& edge_properties() { return m_forward; } - const typename forward_type::inherited_edge_properties& edge_properties() const { return m_forward; } - - forward_type m_forward; - backward_type m_backward; - GraphProperty m_property; + + // Requires the above, plus a vertex_index map. + template < typename Graph > void assign(const Graph& g) + { + typename graph_traits< Graph >::edges_size_type numedges = num_edges(g); + if (is_same< typename graph_traits< Graph >::directed_category, + undirectedS >::value) + { + numedges *= 2; // Double each edge (actual doubling done by + // out_edges function) + } + vertices_size_type numverts = num_vertices(g); + m_forward.assign(g, get(vertex_index, g), numverts, numedges); + inherited_vertex_properties::resize(numverts); + set_up_backward_property_links(); + } + + using inherited_vertex_properties::operator[]; + + // Directly access a edge or edge bundle + edge_push_back_type& operator[](const edge_descriptor& v) + { + return m_forward.m_edge_properties[get(edge_index, *this, v)]; + } + + const edge_push_back_type& operator[](const edge_descriptor& v) const + { + return m_forward.m_edge_properties[get(edge_index, *this, v)]; + } + + // private: non-portable, requires friend templates + inherited_vertex_properties& vertex_properties() { return *this; } + const inherited_vertex_properties& vertex_properties() const + { + return *this; + } + typename forward_type::inherited_edge_properties& edge_properties() + { + return m_forward; + } + const typename forward_type::inherited_edge_properties& + edge_properties() const + { + return m_forward; + } + + forward_type m_forward; + backward_type m_backward; + GraphProperty m_property; }; // Construction functions -template -inline Vertex -add_vertex(BOOST_CSR_GRAPH_TYPE& g) { - add_vertex(g, typename BOOST_CSR_GRAPH_TYPE::vertex_bundled()); +template < BOOST_CSR_GRAPH_TEMPLATE_PARMS > +inline Vertex add_vertex(BOOST_CSR_GRAPH_TYPE& g) +{ + add_vertex(g, typename BOOST_CSR_GRAPH_TYPE::vertex_bundled()); } -template -inline Vertex -add_vertex(BOOST_DIR_CSR_GRAPH_TYPE& g, - typename BOOST_DIR_CSR_GRAPH_TYPE::vertex_bundled const& p) { - Vertex old_num_verts_plus_one = g.m_forward.m_rowstart.size(); - g.m_forward.m_rowstart.push_back(g.m_forward.m_rowstart.back()); - g.vertex_properties().push_back(p); - return old_num_verts_plus_one - 1; +template < BOOST_DIR_CSR_GRAPH_TEMPLATE_PARMS > +inline Vertex add_vertex(BOOST_DIR_CSR_GRAPH_TYPE& g, + typename BOOST_DIR_CSR_GRAPH_TYPE::vertex_bundled const& p) +{ + Vertex old_num_verts_plus_one = g.m_forward.m_rowstart.size(); + g.m_forward.m_rowstart.push_back(g.m_forward.m_rowstart.back()); + g.vertex_properties().push_back(p); + return old_num_verts_plus_one - 1; } -template -inline Vertex -add_vertex(BOOST_BIDIR_CSR_GRAPH_TYPE& g, - typename BOOST_BIDIR_CSR_GRAPH_TYPE::vertex_bundled const& p) { - Vertex old_num_verts_plus_one = g.m_forward.m_rowstart.size(); - g.m_forward.m_rowstart.push_back(g.m_forward.m_rowstart.back()); - g.m_backward.m_rowstart.push_back(g.m_backward.m_rowstart.back()); - g.vertex_properties().push_back(p); - return old_num_verts_plus_one - 1; +template < BOOST_BIDIR_CSR_GRAPH_TEMPLATE_PARMS > +inline Vertex add_vertex(BOOST_BIDIR_CSR_GRAPH_TYPE& g, + typename BOOST_BIDIR_CSR_GRAPH_TYPE::vertex_bundled const& p) +{ + Vertex old_num_verts_plus_one = g.m_forward.m_rowstart.size(); + g.m_forward.m_rowstart.push_back(g.m_forward.m_rowstart.back()); + g.m_backward.m_rowstart.push_back(g.m_backward.m_rowstart.back()); + g.vertex_properties().push_back(p); + return old_num_verts_plus_one - 1; } -template -inline Vertex -add_vertices(typename BOOST_DIR_CSR_GRAPH_TYPE::vertices_size_type count, BOOST_DIR_CSR_GRAPH_TYPE& g) { - Vertex old_num_verts_plus_one = g.m_forward.m_rowstart.size(); - EdgeIndex numedges = g.m_forward.m_rowstart.back(); - g.m_forward.m_rowstart.resize(old_num_verts_plus_one + count, numedges); - g.vertex_properties().resize(num_vertices(g)); - return old_num_verts_plus_one - 1; +template < BOOST_DIR_CSR_GRAPH_TEMPLATE_PARMS > +inline Vertex add_vertices( + typename BOOST_DIR_CSR_GRAPH_TYPE::vertices_size_type count, + BOOST_DIR_CSR_GRAPH_TYPE& g) +{ + Vertex old_num_verts_plus_one = g.m_forward.m_rowstart.size(); + EdgeIndex numedges = g.m_forward.m_rowstart.back(); + g.m_forward.m_rowstart.resize(old_num_verts_plus_one + count, numedges); + g.vertex_properties().resize(num_vertices(g)); + return old_num_verts_plus_one - 1; } - // Add edges from a sorted (smallest sources first) range of pairs and edge - // properties - template - void - add_edges_sorted( - BidirectionalIteratorOrig first_sorted, - BidirectionalIteratorOrig last_sorted, - EPIterOrig ep_iter_sorted, - BOOST_DIR_CSR_GRAPH_TYPE& g) { +// Add edges from a sorted (smallest sources first) range of pairs and edge +// properties +template < BOOST_DIR_CSR_GRAPH_TEMPLATE_PARMS, + typename BidirectionalIteratorOrig, typename EPIterOrig > +void add_edges_sorted(BidirectionalIteratorOrig first_sorted, + BidirectionalIteratorOrig last_sorted, EPIterOrig ep_iter_sorted, + BOOST_DIR_CSR_GRAPH_TYPE& g) +{ g.add_edges_sorted_internal(first_sorted, last_sorted, ep_iter_sorted); - } - - // Add edges from a sorted (smallest sources first) range of pairs - template - void - add_edges_sorted( - BidirectionalIteratorOrig first_sorted, - BidirectionalIteratorOrig last_sorted, - BOOST_DIR_CSR_GRAPH_TYPE& g) { +} + +// Add edges from a sorted (smallest sources first) range of pairs +template < BOOST_DIR_CSR_GRAPH_TEMPLATE_PARMS, + typename BidirectionalIteratorOrig > +void add_edges_sorted(BidirectionalIteratorOrig first_sorted, + BidirectionalIteratorOrig last_sorted, BOOST_DIR_CSR_GRAPH_TYPE& g) +{ g.add_edges_sorted_internal(first_sorted, last_sorted); - } - - template - void - add_edges_sorted_global( - BidirectionalIteratorOrig first_sorted, - BidirectionalIteratorOrig last_sorted, - EPIterOrig ep_iter_sorted, - const GlobalToLocal& global_to_local, - BOOST_DIR_CSR_GRAPH_TYPE& g) { - g.add_edges_sorted_internal_global(first_sorted, last_sorted, ep_iter_sorted, - global_to_local); - } - - // Add edges from a sorted (smallest sources first) range of pairs - template - void - add_edges_sorted_global( - BidirectionalIteratorOrig first_sorted, - BidirectionalIteratorOrig last_sorted, - const GlobalToLocal& global_to_local, - BOOST_DIR_CSR_GRAPH_TYPE& g) { - g.add_edges_sorted_internal_global(first_sorted, last_sorted, global_to_local); - } - - // Add edges from a range of (source, target) pairs that are unsorted - template - inline void - add_edges_global(InputIterator first, InputIterator last, - const GlobalToLocal& global_to_local, BOOST_DIR_CSR_GRAPH_TYPE& g) { +} + +template < BOOST_DIR_CSR_GRAPH_TEMPLATE_PARMS, + typename BidirectionalIteratorOrig, typename EPIterOrig, + typename GlobalToLocal > +void add_edges_sorted_global(BidirectionalIteratorOrig first_sorted, + BidirectionalIteratorOrig last_sorted, EPIterOrig ep_iter_sorted, + const GlobalToLocal& global_to_local, BOOST_DIR_CSR_GRAPH_TYPE& g) +{ + g.add_edges_sorted_internal_global( + first_sorted, last_sorted, ep_iter_sorted, global_to_local); +} + +// Add edges from a sorted (smallest sources first) range of pairs +template < BOOST_DIR_CSR_GRAPH_TEMPLATE_PARMS, + typename BidirectionalIteratorOrig, typename GlobalToLocal > +void add_edges_sorted_global(BidirectionalIteratorOrig first_sorted, + BidirectionalIteratorOrig last_sorted, const GlobalToLocal& global_to_local, + BOOST_DIR_CSR_GRAPH_TYPE& g) +{ + g.add_edges_sorted_internal_global( + first_sorted, last_sorted, global_to_local); +} + +// Add edges from a range of (source, target) pairs that are unsorted +template < BOOST_DIR_CSR_GRAPH_TEMPLATE_PARMS, typename InputIterator, + typename GlobalToLocal > +inline void add_edges_global(InputIterator first, InputIterator last, + const GlobalToLocal& global_to_local, BOOST_DIR_CSR_GRAPH_TYPE& g) +{ g.add_edges_internal(first, last, global_to_local); - } +} - // Add edges from a range of (source, target) pairs that are unsorted - template - inline void - add_edges(InputIterator first, InputIterator last, BOOST_DIR_CSR_GRAPH_TYPE& g) { +// Add edges from a range of (source, target) pairs that are unsorted +template < BOOST_DIR_CSR_GRAPH_TEMPLATE_PARMS, typename InputIterator > +inline void add_edges( + InputIterator first, InputIterator last, BOOST_DIR_CSR_GRAPH_TYPE& g) +{ g.add_edges_internal(first, last); - } - - // Add edges from a range of (source, target) pairs and edge properties that - // are unsorted - template - inline void - add_edges(InputIterator first, InputIterator last, - EPIterator ep_iter, EPIterator ep_iter_end, - BOOST_DIR_CSR_GRAPH_TYPE& g) { +} + +// Add edges from a range of (source, target) pairs and edge properties that +// are unsorted +template < BOOST_DIR_CSR_GRAPH_TEMPLATE_PARMS, typename InputIterator, + typename EPIterator > +inline void add_edges(InputIterator first, InputIterator last, + EPIterator ep_iter, EPIterator ep_iter_end, BOOST_DIR_CSR_GRAPH_TYPE& g) +{ g.add_edges_internal(first, last, ep_iter, ep_iter_end); - } - - template - inline void - add_edges_global(InputIterator first, InputIterator last, - EPIterator ep_iter, EPIterator ep_iter_end, - const GlobalToLocal& global_to_local, - BOOST_DIR_CSR_GRAPH_TYPE& g) { +} + +template < BOOST_DIR_CSR_GRAPH_TEMPLATE_PARMS, typename InputIterator, + typename EPIterator, typename GlobalToLocal > +inline void add_edges_global(InputIterator first, InputIterator last, + EPIterator ep_iter, EPIterator ep_iter_end, + const GlobalToLocal& global_to_local, BOOST_DIR_CSR_GRAPH_TYPE& g) +{ g.add_edges_internal(first, last, ep_iter, ep_iter_end, global_to_local); - } +} // From VertexListGraph -template -inline Vertex -num_vertices(const BOOST_CSR_GRAPH_TYPE& g) { - return g.m_forward.m_rowstart.size() - 1; +template < BOOST_CSR_GRAPH_TEMPLATE_PARMS > +inline Vertex num_vertices(const BOOST_CSR_GRAPH_TYPE& g) +{ + return g.m_forward.m_rowstart.size() - 1; } -template -std::pair, counting_iterator > -inline vertices(const BOOST_CSR_GRAPH_TYPE& g) { - return std::make_pair(counting_iterator(0), - counting_iterator(num_vertices(g))); +template < BOOST_CSR_GRAPH_TEMPLATE_PARMS > +std::pair< counting_iterator< Vertex >, + counting_iterator< Vertex > > inline vertices(const BOOST_CSR_GRAPH_TYPE& g) +{ + return std::make_pair(counting_iterator< Vertex >(0), + counting_iterator< Vertex >(num_vertices(g))); } // From IncidenceGraph -template -inline Vertex -source(typename BOOST_CSR_GRAPH_TYPE::edge_descriptor e, - const BOOST_CSR_GRAPH_TYPE&) +template < BOOST_CSR_GRAPH_TEMPLATE_PARMS > +inline Vertex source(typename BOOST_CSR_GRAPH_TYPE::edge_descriptor e, + const BOOST_CSR_GRAPH_TYPE&) { - return e.src; + return e.src; } -template -inline Vertex -target(typename BOOST_CSR_GRAPH_TYPE::edge_descriptor e, - const BOOST_CSR_GRAPH_TYPE& g) +template < BOOST_CSR_GRAPH_TEMPLATE_PARMS > +inline Vertex target(typename BOOST_CSR_GRAPH_TYPE::edge_descriptor e, + const BOOST_CSR_GRAPH_TYPE& g) { - return g.m_forward.m_column[e.idx]; + return g.m_forward.m_column[e.idx]; } -template -inline std::pair +template < BOOST_CSR_GRAPH_TEMPLATE_PARMS > +inline std::pair< typename BOOST_CSR_GRAPH_TYPE::out_edge_iterator, + typename BOOST_CSR_GRAPH_TYPE::out_edge_iterator > out_edges(Vertex v, const BOOST_CSR_GRAPH_TYPE& g) { - typedef typename BOOST_CSR_GRAPH_TYPE::edge_descriptor ed; - typedef typename BOOST_CSR_GRAPH_TYPE::out_edge_iterator it; - EdgeIndex v_row_start = g.m_forward.m_rowstart[v]; - EdgeIndex next_row_start = g.m_forward.m_rowstart[v + 1]; - return std::make_pair(it(ed(v, v_row_start)), - it(ed(v, next_row_start))); + typedef typename BOOST_CSR_GRAPH_TYPE::edge_descriptor ed; + typedef typename BOOST_CSR_GRAPH_TYPE::out_edge_iterator it; + EdgeIndex v_row_start = g.m_forward.m_rowstart[v]; + EdgeIndex next_row_start = g.m_forward.m_rowstart[v + 1]; + return std::make_pair(it(ed(v, v_row_start)), it(ed(v, next_row_start))); } -template -inline EdgeIndex -out_degree(Vertex v, const BOOST_CSR_GRAPH_TYPE& g) +template < BOOST_CSR_GRAPH_TEMPLATE_PARMS > +inline EdgeIndex out_degree(Vertex v, const BOOST_CSR_GRAPH_TYPE& g) { - EdgeIndex v_row_start = g.m_forward.m_rowstart[v]; - EdgeIndex next_row_start = g.m_forward.m_rowstart[v + 1]; - return next_row_start - v_row_start; + EdgeIndex v_row_start = g.m_forward.m_rowstart[v]; + EdgeIndex next_row_start = g.m_forward.m_rowstart[v + 1]; + return next_row_start - v_row_start; } -template -inline std::pair +template < BOOST_BIDIR_CSR_GRAPH_TEMPLATE_PARMS > +inline std::pair< typename BOOST_BIDIR_CSR_GRAPH_TYPE::in_edge_iterator, + typename BOOST_BIDIR_CSR_GRAPH_TYPE::in_edge_iterator > in_edges(Vertex v, const BOOST_BIDIR_CSR_GRAPH_TYPE& g) { - typedef typename BOOST_BIDIR_CSR_GRAPH_TYPE::in_edge_iterator it; - EdgeIndex v_row_start = g.m_backward.m_rowstart[v]; - EdgeIndex next_row_start = g.m_backward.m_rowstart[v + 1]; - return std::make_pair(it(g, v_row_start), - it(g, next_row_start)); + typedef typename BOOST_BIDIR_CSR_GRAPH_TYPE::in_edge_iterator it; + EdgeIndex v_row_start = g.m_backward.m_rowstart[v]; + EdgeIndex next_row_start = g.m_backward.m_rowstart[v + 1]; + return std::make_pair(it(g, v_row_start), it(g, next_row_start)); } -template -inline EdgeIndex -in_degree(Vertex v, const BOOST_BIDIR_CSR_GRAPH_TYPE& g) +template < BOOST_BIDIR_CSR_GRAPH_TEMPLATE_PARMS > +inline EdgeIndex in_degree(Vertex v, const BOOST_BIDIR_CSR_GRAPH_TYPE& g) { - EdgeIndex v_row_start = g.m_backward.m_rowstart[v]; - EdgeIndex next_row_start = g.m_backward.m_rowstart[v + 1]; - return next_row_start - v_row_start; + EdgeIndex v_row_start = g.m_backward.m_rowstart[v]; + EdgeIndex next_row_start = g.m_backward.m_rowstart[v + 1]; + return next_row_start - v_row_start; } // From AdjacencyGraph -template -inline std::pair +template < BOOST_CSR_GRAPH_TEMPLATE_PARMS > +inline std::pair< typename BOOST_CSR_GRAPH_TYPE::adjacency_iterator, + typename BOOST_CSR_GRAPH_TYPE::adjacency_iterator > adjacent_vertices(Vertex v, const BOOST_CSR_GRAPH_TYPE& g) { - EdgeIndex v_row_start = g.m_forward.m_rowstart[v]; - EdgeIndex next_row_start = g.m_forward.m_rowstart[v + 1]; - return std::make_pair(g.m_forward.m_column.begin() + v_row_start, - g.m_forward.m_column.begin() + next_row_start); + EdgeIndex v_row_start = g.m_forward.m_rowstart[v]; + EdgeIndex next_row_start = g.m_forward.m_rowstart[v + 1]; + return std::make_pair(g.m_forward.m_column.begin() + v_row_start, + g.m_forward.m_column.begin() + next_row_start); } // Extra, common functions -template -inline typename graph_traits::vertex_descriptor -vertex(typename graph_traits::vertex_descriptor i, - const BOOST_CSR_GRAPH_TYPE&) +template < BOOST_CSR_GRAPH_TEMPLATE_PARMS > +inline typename graph_traits< BOOST_CSR_GRAPH_TYPE >::vertex_descriptor vertex( + typename graph_traits< BOOST_CSR_GRAPH_TYPE >::vertex_descriptor i, + const BOOST_CSR_GRAPH_TYPE&) { - return i; + return i; } // edge() can be provided in linear time for the new interface -template -inline std::pair -edge(Vertex i, Vertex j, const BOOST_CSR_GRAPH_TYPE& g) -{ - typedef typename BOOST_CSR_GRAPH_TYPE::out_edge_iterator out_edge_iter; - std::pair range = out_edges(i, g); - for (; range.first != range.second; ++range.first) { - if (target(*range.first, g) == j) - return std::make_pair(*range.first, true); - } - return std::make_pair(typename BOOST_CSR_GRAPH_TYPE::edge_descriptor(), - false); +template < BOOST_CSR_GRAPH_TEMPLATE_PARMS > +inline std::pair< typename BOOST_CSR_GRAPH_TYPE::edge_descriptor, bool > edge( + Vertex i, Vertex j, const BOOST_CSR_GRAPH_TYPE& g) +{ + typedef typename BOOST_CSR_GRAPH_TYPE::out_edge_iterator out_edge_iter; + std::pair< out_edge_iter, out_edge_iter > range = out_edges(i, g); + for (; range.first != range.second; ++range.first) + { + if (target(*range.first, g) == j) + return std::make_pair(*range.first, true); + } + return std::make_pair( + typename BOOST_CSR_GRAPH_TYPE::edge_descriptor(), false); } // Find an edge given its index in the graph -template -inline typename BOOST_CSR_GRAPH_TYPE::edge_descriptor -edge_from_index(EdgeIndex idx, const BOOST_CSR_GRAPH_TYPE& g) -{ - typedef typename std::vector::const_iterator row_start_iter; - BOOST_ASSERT (idx < num_edges(g)); - row_start_iter src_plus_1 = - std::upper_bound(g.m_forward.m_rowstart.begin(), - g.m_forward.m_rowstart.end(), - idx); +template < BOOST_CSR_GRAPH_TEMPLATE_PARMS > +inline typename BOOST_CSR_GRAPH_TYPE::edge_descriptor edge_from_index( + EdgeIndex idx, const BOOST_CSR_GRAPH_TYPE& g) +{ + typedef typename std::vector< EdgeIndex >::const_iterator row_start_iter; + BOOST_ASSERT(idx < num_edges(g)); + row_start_iter src_plus_1 = std::upper_bound( + g.m_forward.m_rowstart.begin(), g.m_forward.m_rowstart.end(), idx); // Get last source whose rowstart is at most idx // upper_bound returns this position plus 1 - Vertex src = (src_plus_1 - g.m_forward.m_rowstart.begin()) - 1; - return typename BOOST_CSR_GRAPH_TYPE::edge_descriptor(src, idx); + Vertex src = (src_plus_1 - g.m_forward.m_rowstart.begin()) - 1; + return typename BOOST_CSR_GRAPH_TYPE::edge_descriptor(src, idx); } -template -inline EdgeIndex -num_edges(const BOOST_CSR_GRAPH_TYPE& g) +template < BOOST_CSR_GRAPH_TEMPLATE_PARMS > +inline EdgeIndex num_edges(const BOOST_CSR_GRAPH_TYPE& g) { - return g.m_forward.m_column.size(); + return g.m_forward.m_column.size(); } -template -std::pair +template < BOOST_CSR_GRAPH_TEMPLATE_PARMS > +std::pair< typename BOOST_CSR_GRAPH_TYPE::edge_iterator, + typename BOOST_CSR_GRAPH_TYPE::edge_iterator > edges(const BOOST_CSR_GRAPH_TYPE& g) { - typedef typename BOOST_CSR_GRAPH_TYPE::edge_iterator ei; - typedef typename BOOST_CSR_GRAPH_TYPE::edge_descriptor edgedesc; - if (g.m_forward.m_rowstart.size() == 1 || g.m_forward.m_column.empty()) { - return std::make_pair(ei(), ei()); - } else { - // Find the first vertex that has outgoing edges - Vertex src = 0; - while (g.m_forward.m_rowstart[src + 1] == 0) ++src; - return std::make_pair(ei(g, edgedesc(src, 0), g.m_forward.m_rowstart[src + 1]), - ei(g, edgedesc(num_vertices(g), g.m_forward.m_column.size()), 0)); - } + typedef typename BOOST_CSR_GRAPH_TYPE::edge_iterator ei; + typedef typename BOOST_CSR_GRAPH_TYPE::edge_descriptor edgedesc; + if (g.m_forward.m_rowstart.size() == 1 || g.m_forward.m_column.empty()) + { + return std::make_pair(ei(), ei()); + } + else + { + // Find the first vertex that has outgoing edges + Vertex src = 0; + while (g.m_forward.m_rowstart[src + 1] == 0) + ++src; + return std::make_pair( + ei(g, edgedesc(src, 0), g.m_forward.m_rowstart[src + 1]), + ei(g, edgedesc(num_vertices(g), g.m_forward.m_column.size()), 0)); + } } // For Property Graph // Graph properties -template -inline void -set_property(BOOST_CSR_GRAPH_TYPE& g, Tag tag, const Value& value) +template < BOOST_CSR_GRAPH_TEMPLATE_PARMS, class Tag, class Value > +inline void set_property(BOOST_CSR_GRAPH_TYPE& g, Tag tag, const Value& value) { - get_property_value(g.m_property, tag) = value; + get_property_value(g.m_property, tag) = value; } -template -inline -typename graph_property::type& -get_property(BOOST_CSR_GRAPH_TYPE& g, Tag tag) +template < BOOST_CSR_GRAPH_TEMPLATE_PARMS, class Tag > +inline typename graph_property< BOOST_CSR_GRAPH_TYPE, Tag >::type& get_property( + BOOST_CSR_GRAPH_TYPE& g, Tag tag) { - return get_property_value(g.m_property, tag); + return get_property_value(g.m_property, tag); } -template -inline -const -typename graph_property::type& +template < BOOST_CSR_GRAPH_TEMPLATE_PARMS, class Tag > +inline const typename graph_property< BOOST_CSR_GRAPH_TYPE, Tag >::type& get_property(const BOOST_CSR_GRAPH_TYPE& g, Tag tag) { - return get_property_value(g.m_property, tag); + return get_property_value(g.m_property, tag); } -template -struct csr_property_map_helper {}; +template < typename G, typename Tag, typename Kind > +struct csr_property_map_helper +{ +}; // Kind == void for invalid property tags, so we can use that to SFINAE out -template -struct csr_property_map_helper { - typedef vertex_all_t all_tag; - typedef typename property_traits::type>::key_type key_type; - typedef VertexProperty plist_type; - typedef typename property_map::type all_type; - typedef typename property_map::const_type all_const_type; - typedef transform_value_property_map, all_type> type; - typedef transform_value_property_map, all_const_type> const_type; +template < BOOST_CSR_GRAPH_TEMPLATE_PARMS, typename Tag > +struct csr_property_map_helper< BOOST_CSR_GRAPH_TYPE, Tag, vertex_property_tag > +{ + typedef vertex_all_t all_tag; + typedef + typename property_traits< typename property_map< BOOST_CSR_GRAPH_TYPE, + vertex_all_t >::type >::key_type key_type; + typedef VertexProperty plist_type; + typedef typename property_map< BOOST_CSR_GRAPH_TYPE, vertex_all_t >::type + all_type; + typedef + typename property_map< BOOST_CSR_GRAPH_TYPE, vertex_all_t >::const_type + all_const_type; + typedef transform_value_property_map< + detail::lookup_one_property_f< plist_type, Tag >, all_type > + type; + typedef transform_value_property_map< + detail::lookup_one_property_f< const plist_type, Tag >, all_const_type > + const_type; }; -template -struct csr_property_map_helper { - typedef edge_all_t all_tag; - typedef typename property_traits::type>::key_type key_type; - typedef EdgeProperty plist_type; - typedef typename property_map::type all_type; - typedef typename property_map::const_type all_const_type; - typedef transform_value_property_map, all_type> type; - typedef transform_value_property_map, all_const_type> const_type; +template < BOOST_CSR_GRAPH_TEMPLATE_PARMS, typename Tag > +struct csr_property_map_helper< BOOST_CSR_GRAPH_TYPE, Tag, edge_property_tag > +{ + typedef edge_all_t all_tag; + typedef + typename property_traits< typename property_map< BOOST_CSR_GRAPH_TYPE, + edge_all_t >::type >::key_type key_type; + typedef EdgeProperty plist_type; + typedef typename property_map< BOOST_CSR_GRAPH_TYPE, edge_all_t >::type + all_type; + typedef + typename property_map< BOOST_CSR_GRAPH_TYPE, edge_all_t >::const_type + all_const_type; + typedef transform_value_property_map< + detail::lookup_one_property_f< plist_type, Tag >, all_type > + type; + typedef transform_value_property_map< + detail::lookup_one_property_f< const plist_type, Tag >, all_const_type > + const_type; }; -template -struct csr_property_map_helper { - typedef graph_all_t all_tag; - typedef BOOST_CSR_GRAPH_TYPE* key_type; - typedef GraphProperty plist_type; - typedef typename property_map::type all_type; - typedef typename property_map::const_type all_const_type; - typedef transform_value_property_map, all_type> type; - typedef transform_value_property_map, all_const_type> const_type; +template < BOOST_CSR_GRAPH_TEMPLATE_PARMS, typename Tag > +struct csr_property_map_helper< BOOST_CSR_GRAPH_TYPE, Tag, graph_property_tag > +{ + typedef graph_all_t all_tag; + typedef BOOST_CSR_GRAPH_TYPE* key_type; + typedef GraphProperty plist_type; + typedef typename property_map< BOOST_CSR_GRAPH_TYPE, graph_all_t >::type + all_type; + typedef + typename property_map< BOOST_CSR_GRAPH_TYPE, graph_all_t >::const_type + all_const_type; + typedef transform_value_property_map< + detail::lookup_one_property_f< plist_type, Tag >, all_type > + type; + typedef transform_value_property_map< + detail::lookup_one_property_f< const plist_type, Tag >, all_const_type > + const_type; +}; + +// disable_if isn't truly necessary but required to avoid ambiguity with +// specializations below +template < BOOST_CSR_GRAPH_TEMPLATE_PARMS, typename Tag > +struct property_map< BOOST_CSR_GRAPH_TYPE, Tag, + typename disable_if< detail::is_distributed_selector< Vertex > >::type > +: csr_property_map_helper< BOOST_CSR_GRAPH_TYPE, Tag, + typename detail::property_kind_from_graph< BOOST_CSR_GRAPH_TYPE, + Tag >::type > +{ }; -// disable_if isn't truly necessary but required to avoid ambiguity with specializations below -template -struct property_map >::type>: - csr_property_map_helper< - BOOST_CSR_GRAPH_TYPE, - Tag, - typename detail::property_kind_from_graph - ::type> {}; - -template -typename property_map::type -get(Tag tag, BOOST_CSR_GRAPH_TYPE& g) { - return typename property_map::type(tag, get(typename property_map::all_tag(), g)); +template < BOOST_CSR_GRAPH_TEMPLATE_PARMS, typename Tag > +typename property_map< BOOST_CSR_GRAPH_TYPE, Tag >::type get( + Tag tag, BOOST_CSR_GRAPH_TYPE& g) +{ + return typename property_map< BOOST_CSR_GRAPH_TYPE, Tag >::type(tag, + get(typename property_map< BOOST_CSR_GRAPH_TYPE, Tag >::all_tag(), g)); } -template -typename property_map::const_type -get(Tag tag, const BOOST_CSR_GRAPH_TYPE& g) { - return typename property_map::const_type(tag, get(typename property_map::all_tag(), g)); +template < BOOST_CSR_GRAPH_TEMPLATE_PARMS, typename Tag > +typename property_map< BOOST_CSR_GRAPH_TYPE, Tag >::const_type get( + Tag tag, const BOOST_CSR_GRAPH_TYPE& g) +{ + return typename property_map< BOOST_CSR_GRAPH_TYPE, Tag >::const_type(tag, + get(typename property_map< BOOST_CSR_GRAPH_TYPE, Tag >::all_tag(), g)); } -template -typename property_traits::type>::reference -get(Tag tag, BOOST_CSR_GRAPH_TYPE& g, typename property_map::key_type k) { - typedef typename property_map::all_tag all_tag; - typedef typename property_map::type outer_pm; - return lookup_one_property::value_type, Tag>::lookup(get(all_tag(), g, k), tag); +template < BOOST_CSR_GRAPH_TEMPLATE_PARMS, typename Tag > +typename property_traits< + typename property_map< BOOST_CSR_GRAPH_TYPE, Tag >::type >::reference +get(Tag tag, BOOST_CSR_GRAPH_TYPE& g, + typename property_map< BOOST_CSR_GRAPH_TYPE, Tag >::key_type k) +{ + typedef typename property_map< BOOST_CSR_GRAPH_TYPE, Tag >::all_tag all_tag; + typedef + typename property_map< BOOST_CSR_GRAPH_TYPE, all_tag >::type outer_pm; + return lookup_one_property< + typename property_traits< outer_pm >::value_type, + Tag >::lookup(get(all_tag(), g, k), tag); } -template -typename property_traits::const_type>::reference -get(Tag tag, const BOOST_CSR_GRAPH_TYPE& g, typename property_map::key_type k) { - typedef typename property_map::all_tag all_tag; - typedef typename property_map::const_type outer_pm; - return lookup_one_property::value_type, Tag>::lookup(get(all_tag(), g, k), tag); +template < BOOST_CSR_GRAPH_TEMPLATE_PARMS, typename Tag > +typename property_traits< + typename property_map< BOOST_CSR_GRAPH_TYPE, Tag >::const_type >::reference +get(Tag tag, const BOOST_CSR_GRAPH_TYPE& g, + typename property_map< BOOST_CSR_GRAPH_TYPE, Tag >::key_type k) +{ + typedef typename property_map< BOOST_CSR_GRAPH_TYPE, Tag >::all_tag all_tag; + typedef typename property_map< BOOST_CSR_GRAPH_TYPE, all_tag >::const_type + outer_pm; + return lookup_one_property< + const typename property_traits< outer_pm >::value_type, + Tag >::lookup(get(all_tag(), g, k), tag); } -template -void -put(Tag tag, - BOOST_CSR_GRAPH_TYPE& g, - typename property_map::key_type k, - typename lookup_one_property::plist_type, Tag>::type val) { - typedef typename property_map::all_tag all_tag; - lookup_one_property::plist_type, Tag>::lookup(get(all_tag(), g, k), tag) = val; +template < BOOST_CSR_GRAPH_TEMPLATE_PARMS, typename Tag > +void put(Tag tag, BOOST_CSR_GRAPH_TYPE& g, + typename property_map< BOOST_CSR_GRAPH_TYPE, Tag >::key_type k, + typename lookup_one_property< + typename property_map< BOOST_CSR_GRAPH_TYPE, Tag >::plist_type, + Tag >::type val) +{ + typedef typename property_map< BOOST_CSR_GRAPH_TYPE, Tag >::all_tag all_tag; + lookup_one_property< + typename property_map< BOOST_CSR_GRAPH_TYPE, Tag >::plist_type, + Tag >::lookup(get(all_tag(), g, k), tag) + = val; } -template -struct property_map >::type> +template < BOOST_CSR_GRAPH_TEMPLATE_PARMS > +struct property_map< BOOST_CSR_GRAPH_TYPE, vertex_index_t, + typename disable_if< detail::is_distributed_selector< Vertex > >::type > { - typedef typed_identity_property_map type; - typedef type const_type; + typedef typed_identity_property_map< Vertex > type; + typedef type const_type; }; -template -struct property_map >::type> +template < BOOST_CSR_GRAPH_TEMPLATE_PARMS > +struct property_map< BOOST_CSR_GRAPH_TYPE, edge_index_t, + typename disable_if< detail::is_distributed_selector< Vertex > >::type > { - typedef detail::csr_edge_index_map type; - typedef type const_type; + typedef detail::csr_edge_index_map< Vertex, EdgeIndex > type; + typedef type const_type; }; -template -struct property_map >::type> +template < BOOST_CSR_GRAPH_TEMPLATE_PARMS > +struct property_map< BOOST_CSR_GRAPH_TYPE, vertex_all_t, + typename disable_if< detail::is_distributed_selector< Vertex > >::type > { - typedef typename BOOST_CSR_GRAPH_TYPE::inherited_vertex_properties::vertex_map_type type; - typedef typename BOOST_CSR_GRAPH_TYPE::inherited_vertex_properties::const_vertex_map_type const_type; + typedef typename BOOST_CSR_GRAPH_TYPE::inherited_vertex_properties:: + vertex_map_type type; + typedef typename BOOST_CSR_GRAPH_TYPE::inherited_vertex_properties:: + const_vertex_map_type const_type; }; -template -struct property_map >::type> +template < BOOST_CSR_GRAPH_TEMPLATE_PARMS > +struct property_map< BOOST_CSR_GRAPH_TYPE, edge_all_t, + typename disable_if< detail::is_distributed_selector< Vertex > >::type > { - typedef typename BOOST_CSR_GRAPH_TYPE::forward_type::inherited_edge_properties::edge_map_type type; - typedef typename BOOST_CSR_GRAPH_TYPE::forward_type::inherited_edge_properties::const_edge_map_type const_type; + typedef typename BOOST_CSR_GRAPH_TYPE::forward_type:: + inherited_edge_properties::edge_map_type type; + typedef typename BOOST_CSR_GRAPH_TYPE::forward_type:: + inherited_edge_properties::const_edge_map_type const_type; }; -template -struct property_map >::type> +template < BOOST_CSR_GRAPH_TEMPLATE_PARMS > +struct property_map< BOOST_CSR_GRAPH_TYPE, graph_all_t, + typename disable_if< detail::is_distributed_selector< Vertex > >::type > { - typedef boost::ref_property_map type; - typedef boost::ref_property_map const_type; + typedef boost::ref_property_map< BOOST_CSR_GRAPH_TYPE*, + typename BOOST_CSR_GRAPH_TYPE::graph_property_type > + type; + typedef boost::ref_property_map< BOOST_CSR_GRAPH_TYPE*, + const typename BOOST_CSR_GRAPH_TYPE::graph_property_type > + const_type; }; -template -inline typed_identity_property_map -get(vertex_index_t, const BOOST_CSR_GRAPH_TYPE&) +template < BOOST_CSR_GRAPH_TEMPLATE_PARMS > +inline typed_identity_property_map< Vertex > get( + vertex_index_t, const BOOST_CSR_GRAPH_TYPE&) { - return typed_identity_property_map(); + return typed_identity_property_map< Vertex >(); } -template -inline Vertex -get(vertex_index_t, - const BOOST_CSR_GRAPH_TYPE&, Vertex v) +template < BOOST_CSR_GRAPH_TEMPLATE_PARMS > +inline Vertex get(vertex_index_t, const BOOST_CSR_GRAPH_TYPE&, Vertex v) { - return v; + return v; } -template -inline typed_identity_property_map -get(vertex_index_t, BOOST_CSR_GRAPH_TYPE&) +template < BOOST_CSR_GRAPH_TEMPLATE_PARMS > +inline typed_identity_property_map< Vertex > get( + vertex_index_t, BOOST_CSR_GRAPH_TYPE&) { - return typed_identity_property_map(); + return typed_identity_property_map< Vertex >(); } -template -inline Vertex -get(vertex_index_t, - BOOST_CSR_GRAPH_TYPE&, Vertex v) +template < BOOST_CSR_GRAPH_TEMPLATE_PARMS > +inline Vertex get(vertex_index_t, BOOST_CSR_GRAPH_TYPE&, Vertex v) { - return v; + return v; } -template -inline typename property_map::const_type +template < BOOST_CSR_GRAPH_TEMPLATE_PARMS > +inline typename property_map< BOOST_CSR_GRAPH_TYPE, edge_index_t >::const_type get(edge_index_t, const BOOST_CSR_GRAPH_TYPE&) { - typedef typename property_map::const_type - result_type; - return result_type(); + typedef + typename property_map< BOOST_CSR_GRAPH_TYPE, edge_index_t >::const_type + result_type; + return result_type(); } -template -inline EdgeIndex -get(edge_index_t, const BOOST_CSR_GRAPH_TYPE&, +template < BOOST_CSR_GRAPH_TEMPLATE_PARMS > +inline EdgeIndex get(edge_index_t, const BOOST_CSR_GRAPH_TYPE&, typename BOOST_CSR_GRAPH_TYPE::edge_descriptor e) { - return e.idx; + return e.idx; } -template -inline typename property_map::const_type +template < BOOST_CSR_GRAPH_TEMPLATE_PARMS > +inline typename property_map< BOOST_CSR_GRAPH_TYPE, edge_index_t >::const_type get(edge_index_t, BOOST_CSR_GRAPH_TYPE&) { - typedef typename property_map::const_type - result_type; - return result_type(); + typedef + typename property_map< BOOST_CSR_GRAPH_TYPE, edge_index_t >::const_type + result_type; + return result_type(); } -template -inline EdgeIndex -get(edge_index_t, BOOST_CSR_GRAPH_TYPE&, +template < BOOST_CSR_GRAPH_TEMPLATE_PARMS > +inline EdgeIndex get(edge_index_t, BOOST_CSR_GRAPH_TYPE&, typename BOOST_CSR_GRAPH_TYPE::edge_descriptor e) { - return e.idx; + return e.idx; } -template -inline typename property_map::type -get(vertex_all_t, BOOST_CSR_GRAPH_TYPE& g) +template < BOOST_CSR_GRAPH_TEMPLATE_PARMS > +inline typename property_map< BOOST_CSR_GRAPH_TYPE, vertex_all_t >::type get( + vertex_all_t, BOOST_CSR_GRAPH_TYPE& g) { - return g.get_vertex_bundle(get(vertex_index, g)); + return g.get_vertex_bundle(get(vertex_index, g)); } -template -inline typename property_map::const_type +template < BOOST_CSR_GRAPH_TEMPLATE_PARMS > +inline typename property_map< BOOST_CSR_GRAPH_TYPE, vertex_all_t >::const_type get(vertex_all_t, const BOOST_CSR_GRAPH_TYPE& g) { - return g.get_vertex_bundle(get(vertex_index, g)); + return g.get_vertex_bundle(get(vertex_index, g)); } -template -inline VertexProperty& -get(vertex_all_t, - BOOST_CSR_GRAPH_TYPE& g, Vertex v) +template < BOOST_CSR_GRAPH_TEMPLATE_PARMS > +inline VertexProperty& get(vertex_all_t, BOOST_CSR_GRAPH_TYPE& g, Vertex v) { - return get(vertex_all, g)[v]; + return get(vertex_all, g)[v]; } -template -inline const VertexProperty& -get(vertex_all_t, - const BOOST_CSR_GRAPH_TYPE& g, Vertex v) +template < BOOST_CSR_GRAPH_TEMPLATE_PARMS > +inline const VertexProperty& get( + vertex_all_t, const BOOST_CSR_GRAPH_TYPE& g, Vertex v) { - return get(vertex_all, g)[v]; + return get(vertex_all, g)[v]; } -template -inline void -put(vertex_all_t, - BOOST_CSR_GRAPH_TYPE& g, - Vertex v, - const VertexProperty& val) +template < BOOST_CSR_GRAPH_TEMPLATE_PARMS > +inline void put( + vertex_all_t, BOOST_CSR_GRAPH_TYPE& g, Vertex v, const VertexProperty& val) { - put(get(vertex_all, g), v, val); + put(get(vertex_all, g), v, val); } -template -inline typename property_map::type -get(edge_all_t, BOOST_CSR_GRAPH_TYPE& g) +template < BOOST_CSR_GRAPH_TEMPLATE_PARMS > +inline typename property_map< BOOST_CSR_GRAPH_TYPE, edge_all_t >::type get( + edge_all_t, BOOST_CSR_GRAPH_TYPE& g) { - return g.m_forward.get_edge_bundle(get(edge_index, g)); + return g.m_forward.get_edge_bundle(get(edge_index, g)); } -template -inline typename property_map::const_type +template < BOOST_CSR_GRAPH_TEMPLATE_PARMS > +inline typename property_map< BOOST_CSR_GRAPH_TYPE, edge_all_t >::const_type get(edge_all_t, const BOOST_CSR_GRAPH_TYPE& g) { - return g.m_forward.get_edge_bundle(get(edge_index, g)); + return g.m_forward.get_edge_bundle(get(edge_index, g)); } -template -inline EdgeProperty& -get(edge_all_t, - BOOST_CSR_GRAPH_TYPE& g, +template < BOOST_CSR_GRAPH_TEMPLATE_PARMS > +inline EdgeProperty& get(edge_all_t, BOOST_CSR_GRAPH_TYPE& g, const typename BOOST_CSR_GRAPH_TYPE::edge_descriptor& e) { - return get(edge_all, g)[e]; + return get(edge_all, g)[e]; } -template -inline const EdgeProperty& -get(edge_all_t, - const BOOST_CSR_GRAPH_TYPE& g, +template < BOOST_CSR_GRAPH_TEMPLATE_PARMS > +inline const EdgeProperty& get(edge_all_t, const BOOST_CSR_GRAPH_TYPE& g, const typename BOOST_CSR_GRAPH_TYPE::edge_descriptor& e) { - return get(edge_all, g)[e]; + return get(edge_all, g)[e]; } -template -inline void -put(edge_all_t, - BOOST_CSR_GRAPH_TYPE& g, +template < BOOST_CSR_GRAPH_TEMPLATE_PARMS > +inline void put(edge_all_t, BOOST_CSR_GRAPH_TYPE& g, const typename BOOST_CSR_GRAPH_TYPE::edge_descriptor& e, const EdgeProperty& val) { - put(get(edge_all, g), e, val); + put(get(edge_all, g), e, val); } -template -inline typename property_map::type -get(graph_all_t, BOOST_CSR_GRAPH_TYPE& g) +template < BOOST_CSR_GRAPH_TEMPLATE_PARMS > +inline typename property_map< BOOST_CSR_GRAPH_TYPE, graph_all_t >::type get( + graph_all_t, BOOST_CSR_GRAPH_TYPE& g) { - return typename property_map::type(g.m_property); + return typename property_map< BOOST_CSR_GRAPH_TYPE, graph_all_t >::type( + g.m_property); } -template -inline typename property_map::const_type +template < BOOST_CSR_GRAPH_TEMPLATE_PARMS > +inline typename property_map< BOOST_CSR_GRAPH_TYPE, graph_all_t >::const_type get(graph_all_t, const BOOST_CSR_GRAPH_TYPE& g) { - return typename property_map::const_type(g.m_property); + return + typename property_map< BOOST_CSR_GRAPH_TYPE, graph_all_t >::const_type( + g.m_property); } -template -inline GraphProperty& -get(graph_all_t, - BOOST_CSR_GRAPH_TYPE& g, - BOOST_CSR_GRAPH_TYPE*) +template < BOOST_CSR_GRAPH_TEMPLATE_PARMS > +inline GraphProperty& get( + graph_all_t, BOOST_CSR_GRAPH_TYPE& g, BOOST_CSR_GRAPH_TYPE*) { - return g.m_property; + return g.m_property; } -template -inline const GraphProperty& -get(graph_all_t, - const BOOST_CSR_GRAPH_TYPE& g, - BOOST_CSR_GRAPH_TYPE*) +template < BOOST_CSR_GRAPH_TEMPLATE_PARMS > +inline const GraphProperty& get( + graph_all_t, const BOOST_CSR_GRAPH_TYPE& g, BOOST_CSR_GRAPH_TYPE*) { - return g.m_property; + return g.m_property; } -template -inline void -put(graph_all_t, - BOOST_CSR_GRAPH_TYPE& g, - BOOST_CSR_GRAPH_TYPE*, +template < BOOST_CSR_GRAPH_TEMPLATE_PARMS > +inline void put(graph_all_t, BOOST_CSR_GRAPH_TYPE& g, BOOST_CSR_GRAPH_TYPE*, const GraphProperty& val) { - g.m_property = val; + g.m_property = val; } #undef BOOST_CSR_GRAPH_TYPE diff --git a/include/boost/graph/connected_components.hpp b/include/boost/graph/connected_components.hpp index 117e6a82c..1980d32b9 100644 --- a/include/boost/graph/connected_components.hpp +++ b/include/boost/graph/connected_components.hpp @@ -20,87 +20,95 @@ #include #include -namespace boost { +namespace boost +{ - namespace detail { +namespace detail +{ // This visitor is used both in the connected_components algorithm // and in the kosaraju strong components algorithm during the // second DFS traversal. - template + template < class ComponentsMap > class components_recorder : public dfs_visitor<> { - typedef typename property_traits::value_type comp_type; + typedef typename property_traits< ComponentsMap >::value_type comp_type; + public: - components_recorder(ComponentsMap c, - comp_type& c_count) - : m_component(c), m_count(c_count) {} - - template - void start_vertex(Vertex, Graph&) { - if (m_count == (std::numeric_limits::max)()) - m_count = 0; // start counting components at zero - else - ++m_count; - } - template - void discover_vertex(Vertex u, Graph&) { - put(m_component, u, m_count); - } + components_recorder(ComponentsMap c, comp_type& c_count) + : m_component(c), m_count(c_count) + { + } + + template < class Vertex, class Graph > void start_vertex(Vertex, Graph&) + { + if (m_count == (std::numeric_limits< comp_type >::max)()) + m_count = 0; // start counting components at zero + else + ++m_count; + } + template < class Vertex, class Graph > + void discover_vertex(Vertex u, Graph&) + { + put(m_component, u, m_count); + } + protected: - ComponentsMap m_component; - comp_type& m_count; + ComponentsMap m_component; + comp_type& m_count; }; - } // namespace detail +} // namespace detail - // This function computes the connected components of an undirected - // graph using a single application of depth first search. +// This function computes the connected components of an undirected +// graph using a single application of depth first search. - template - inline typename property_traits::value_type - connected_components(const Graph& g, ComponentMap c, - const bgl_named_params& params - BOOST_GRAPH_ENABLE_IF_MODELS_PARM(Graph, vertex_list_graph_tag)) - { - if (num_vertices(g) == 0) return 0; +template < class Graph, class ComponentMap, class P, class T, class R > +inline typename property_traits< ComponentMap >::value_type +connected_components(const Graph& g, ComponentMap c, + const bgl_named_params< P, T, R >& params BOOST_GRAPH_ENABLE_IF_MODELS_PARM( + Graph, vertex_list_graph_tag)) +{ + if (num_vertices(g) == 0) + return 0; - typedef typename graph_traits::vertex_descriptor Vertex; - BOOST_CONCEPT_ASSERT(( WritablePropertyMapConcept )); - typedef typename boost::graph_traits::directed_category directed; - BOOST_STATIC_ASSERT((boost::is_same::value)); + typedef typename graph_traits< Graph >::vertex_descriptor Vertex; + BOOST_CONCEPT_ASSERT((WritablePropertyMapConcept< ComponentMap, Vertex >)); + typedef typename boost::graph_traits< Graph >::directed_category directed; + BOOST_STATIC_ASSERT((boost::is_same< directed, undirected_tag >::value)); - typedef typename property_traits::value_type comp_type; + typedef typename property_traits< ComponentMap >::value_type comp_type; // c_count initialized to "nil" (with nil represented by (max)()) - comp_type c_count((std::numeric_limits::max)()); - detail::components_recorder vis(c, c_count); + comp_type c_count((std::numeric_limits< comp_type >::max)()); + detail::components_recorder< ComponentMap > vis(c, c_count); depth_first_search(g, params.visitor(vis)); return c_count + 1; - } - - template - inline typename property_traits::value_type - connected_components(const Graph& g, ComponentMap c - BOOST_GRAPH_ENABLE_IF_MODELS_PARM(Graph, vertex_list_graph_tag)) - { - if (num_vertices(g) == 0) return 0; - - typedef typename graph_traits::vertex_descriptor Vertex; - BOOST_CONCEPT_ASSERT(( WritablePropertyMapConcept )); +} + +template < class Graph, class ComponentMap > +inline typename property_traits< ComponentMap >::value_type +connected_components(const Graph& g, + ComponentMap c BOOST_GRAPH_ENABLE_IF_MODELS_PARM( + Graph, vertex_list_graph_tag)) +{ + if (num_vertices(g) == 0) + return 0; + + typedef typename graph_traits< Graph >::vertex_descriptor Vertex; + BOOST_CONCEPT_ASSERT((WritablePropertyMapConcept< ComponentMap, Vertex >)); // typedef typename boost::graph_traits::directed_category directed; // BOOST_STATIC_ASSERT((boost::is_same::value)); - typedef typename property_traits::value_type comp_type; + typedef typename property_traits< ComponentMap >::value_type comp_type; // c_count initialized to "nil" (with nil represented by (max)()) - comp_type c_count((std::numeric_limits::max)()); - detail::components_recorder vis(c, c_count); + comp_type c_count((std::numeric_limits< comp_type >::max)()); + detail::components_recorder< ComponentMap > vis(c, c_count); depth_first_search(g, visitor(vis)); return c_count + 1; - } +} - } // namespace boost -#include BOOST_GRAPH_MPI_INCLUDE() +#include BOOST_GRAPH_MPI_INCLUDE(< boost / graph / distributed / connected_components.hpp >) #endif // BOOST_GRAPH_CONNECTED_COMPONENTS_HPP diff --git a/include/boost/graph/copy.hpp b/include/boost/graph/copy.hpp index 77aebcde1..7cbbc25c7 100644 --- a/include/boost/graph/copy.hpp +++ b/include/boost/graph/copy.hpp @@ -16,28 +16,27 @@ template void copy_graph(const VertexListGraph& g_in, MutableGraph& g_out) - template - void copy_graph(const VertexListGraph& g_in, MutableGraph& g_out, + void copy_graph(const VertexListGraph& g_in, MutableGraph& g_out, const bgl_named_params& params) template typename graph_traits::vertex_descriptor - copy_component(IncidenceGraph& g_in, + copy_component(IncidenceGraph& g_in, typename graph_traits::vertex_descriptor src, MutableGraph& g_out) - template typename graph_traits::vertex_descriptor - copy_component(IncidenceGraph& g_in, + copy_component(IncidenceGraph& g_in, typename graph_traits::vertex_descriptor src, - MutableGraph& g_out, + MutableGraph& g_out, const bgl_named_params& params) */ - #ifndef BOOST_GRAPH_COPY_HPP #define BOOST_GRAPH_COPY_HPP @@ -50,23 +49,30 @@ #include #include -namespace boost { +namespace boost +{ - namespace detail { +namespace detail +{ // Hack to make transpose_graph work with the same interface as before - template - struct remove_reverse_edge_descriptor { - typedef Desc type; - static Desc convert(const Desc& d, const Graph&) {return d;} + template < typename Graph, typename Desc > + struct remove_reverse_edge_descriptor + { + typedef Desc type; + static Desc convert(const Desc& d, const Graph&) { return d; } }; - template - struct remove_reverse_edge_descriptor > { - typedef Desc type; - static Desc convert(const reverse_graph_edge_descriptor& d, const Graph& g) { - return get(edge_underlying, g, d); - } + template < typename Graph, typename Desc > + struct remove_reverse_edge_descriptor< Graph, + reverse_graph_edge_descriptor< Desc > > + { + typedef Desc type; + static Desc convert( + const reverse_graph_edge_descriptor< Desc >& d, const Graph& g) + { + return get(edge_underlying, g, d); + } }; // Add a reverse_graph_edge_descriptor wrapper if the Graph is a @@ -74,437 +80,478 @@ namespace boost { // case comes from the fact that transpose_graph uses reverse_graph // internally but doesn't expose the different edge descriptor type to the // user). - template - struct add_reverse_edge_descriptor { - typedef Desc type; - static Desc convert(const Desc& d) {return d;} + template < typename Desc, typename Graph > + struct add_reverse_edge_descriptor + { + typedef Desc type; + static Desc convert(const Desc& d) { return d; } }; - template - struct add_reverse_edge_descriptor > { - typedef reverse_graph_edge_descriptor type; - static reverse_graph_edge_descriptor convert(const Desc& d) { - return reverse_graph_edge_descriptor(d); - } + template < typename Desc, typename G, typename GR > + struct add_reverse_edge_descriptor< Desc, boost::reverse_graph< G, GR > > + { + typedef reverse_graph_edge_descriptor< Desc > type; + static reverse_graph_edge_descriptor< Desc > convert(const Desc& d) + { + return reverse_graph_edge_descriptor< Desc >(d); + } }; - template - struct add_reverse_edge_descriptor, boost::reverse_graph > { - typedef reverse_graph_edge_descriptor type; - static reverse_graph_edge_descriptor convert(const reverse_graph_edge_descriptor& d) { - return d; - } + template < typename Desc, typename G, typename GR > + struct add_reverse_edge_descriptor< reverse_graph_edge_descriptor< Desc >, + boost::reverse_graph< G, GR > > + { + typedef reverse_graph_edge_descriptor< Desc > type; + static reverse_graph_edge_descriptor< Desc > convert( + const reverse_graph_edge_descriptor< Desc >& d) + { + return d; + } }; // Default edge and vertex property copiers - template - struct edge_copier { - edge_copier(const Graph1& g1, Graph2& g2) - : edge_all_map1(get(edge_all, g1)), - edge_all_map2(get(edge_all, g2)) { } - - template - void operator()(const Edge1& e1, Edge2& e2) const { - put(edge_all_map2, e2, get(edge_all_map1, add_reverse_edge_descriptor::convert(e1))); - } - typename property_map::const_type edge_all_map1; - mutable typename property_map::type edge_all_map2; + template < typename Graph1, typename Graph2 > struct edge_copier + { + edge_copier(const Graph1& g1, Graph2& g2) + : edge_all_map1(get(edge_all, g1)), edge_all_map2(get(edge_all, g2)) + { + } + + template < typename Edge1, typename Edge2 > + void operator()(const Edge1& e1, Edge2& e2) const + { + put(edge_all_map2, e2, + get(edge_all_map1, + add_reverse_edge_descriptor< Edge1, Graph1 >::convert(e1))); + } + typename property_map< Graph1, edge_all_t >::const_type edge_all_map1; + mutable typename property_map< Graph2, edge_all_t >::type edge_all_map2; }; - template - inline edge_copier - make_edge_copier(const Graph1& g1, Graph2& g2) + template < typename Graph1, typename Graph2 > + inline edge_copier< Graph1, Graph2 > make_edge_copier( + const Graph1& g1, Graph2& g2) { - return edge_copier(g1, g2); + return edge_copier< Graph1, Graph2 >(g1, g2); } - template - struct vertex_copier { - vertex_copier(const Graph1& g1, Graph2& g2) - : vertex_all_map1(get(vertex_all, g1)), - vertex_all_map2(get(vertex_all, g2)) { } - - template - void operator()(const Vertex1& v1, Vertex2& v2) const { - put(vertex_all_map2, v2, get(vertex_all_map1, v1)); - } - typename property_map::const_type vertex_all_map1; - mutable typename property_map::type - vertex_all_map2; + template < typename Graph1, typename Graph2 > struct vertex_copier + { + vertex_copier(const Graph1& g1, Graph2& g2) + : vertex_all_map1(get(vertex_all, g1)) + , vertex_all_map2(get(vertex_all, g2)) + { + } + + template < typename Vertex1, typename Vertex2 > + void operator()(const Vertex1& v1, Vertex2& v2) const + { + put(vertex_all_map2, v2, get(vertex_all_map1, v1)); + } + typename property_map< Graph1, vertex_all_t >::const_type + vertex_all_map1; + mutable + typename property_map< Graph2, vertex_all_t >::type vertex_all_map2; }; - template - inline vertex_copier - make_vertex_copier(const Graph1& g1, Graph2& g2) + template < typename Graph1, typename Graph2 > + inline vertex_copier< Graph1, Graph2 > make_vertex_copier( + const Graph1& g1, Graph2& g2) { - return vertex_copier(g1, g2); + return vertex_copier< Graph1, Graph2 >(g1, g2); } // Copy all the vertices and edges of graph g_in into graph g_out. // The copy_vertex and copy_edge function objects control how vertex // and edge properties are copied. - template - struct copy_graph_impl { }; + template < int Version > struct copy_graph_impl + { + }; - template <> struct copy_graph_impl<0> + template <> struct copy_graph_impl< 0 > { - template - static void apply(const Graph& g_in, MutableGraph& g_out, - CopyVertex copy_vertex, CopyEdge copy_edge, - Orig2CopyVertexIndexMap orig2copy, IndexMap) - { - typedef remove_reverse_edge_descriptor::edge_descriptor> cvt; - typename graph_traits::vertex_iterator vi, vi_end; - for (boost::tie(vi, vi_end) = vertices(g_in); vi != vi_end; ++vi) { - typename graph_traits::vertex_descriptor - new_v = add_vertex(g_out); - put(orig2copy, *vi, new_v); - copy_vertex(*vi, new_v); - } - typename graph_traits::edge_iterator ei, ei_end; - for (boost::tie(ei, ei_end) = edges(g_in); ei != ei_end; ++ei) { - typename graph_traits::edge_descriptor new_e; - bool inserted; - boost::tie(new_e, inserted) = add_edge(get(orig2copy, source(*ei, g_in)), - get(orig2copy, target(*ei, g_in)), - g_out); - copy_edge(cvt::convert(*ei, g_in), new_e); + template < typename Graph, typename MutableGraph, typename CopyVertex, + typename CopyEdge, typename IndexMap, + typename Orig2CopyVertexIndexMap > + static void apply(const Graph& g_in, MutableGraph& g_out, + CopyVertex copy_vertex, CopyEdge copy_edge, + Orig2CopyVertexIndexMap orig2copy, IndexMap) + { + typedef remove_reverse_edge_descriptor< Graph, + typename graph_traits< Graph >::edge_descriptor > + cvt; + typename graph_traits< Graph >::vertex_iterator vi, vi_end; + for (boost::tie(vi, vi_end) = vertices(g_in); vi != vi_end; ++vi) + { + typename graph_traits< MutableGraph >::vertex_descriptor new_v + = add_vertex(g_out); + put(orig2copy, *vi, new_v); + copy_vertex(*vi, new_v); + } + typename graph_traits< Graph >::edge_iterator ei, ei_end; + for (boost::tie(ei, ei_end) = edges(g_in); ei != ei_end; ++ei) + { + typename graph_traits< MutableGraph >::edge_descriptor new_e; + bool inserted; + boost::tie(new_e, inserted) + = add_edge(get(orig2copy, source(*ei, g_in)), + get(orig2copy, target(*ei, g_in)), g_out); + copy_edge(cvt::convert(*ei, g_in), new_e); + } } - } }; // for directed graphs - template <> struct copy_graph_impl<1> + template <> struct copy_graph_impl< 1 > { - template - static void apply(const Graph& g_in, MutableGraph& g_out, - CopyVertex copy_vertex, CopyEdge copy_edge, - Orig2CopyVertexIndexMap orig2copy, IndexMap) - { - typedef remove_reverse_edge_descriptor::edge_descriptor> cvt; - typename graph_traits::vertex_iterator vi, vi_end; - for (boost::tie(vi, vi_end) = vertices(g_in); vi != vi_end; ++vi) { - typename graph_traits::vertex_descriptor - new_v = add_vertex(g_out); - put(orig2copy, *vi, new_v); - copy_vertex(*vi, new_v); - } - for (boost::tie(vi, vi_end) = vertices(g_in); vi != vi_end; ++vi) { - typename graph_traits::out_edge_iterator ei, ei_end; - for (boost::tie(ei, ei_end) = out_edges(*vi, g_in); ei != ei_end; ++ei) { - typename graph_traits::edge_descriptor new_e; - bool inserted; - boost::tie(new_e, inserted) = add_edge(get(orig2copy, source(*ei, g_in)), - get(orig2copy, target(*ei, g_in)), - g_out); - copy_edge(cvt::convert(*ei, g_in), new_e); - } + template < typename Graph, typename MutableGraph, typename CopyVertex, + typename CopyEdge, typename IndexMap, + typename Orig2CopyVertexIndexMap > + static void apply(const Graph& g_in, MutableGraph& g_out, + CopyVertex copy_vertex, CopyEdge copy_edge, + Orig2CopyVertexIndexMap orig2copy, IndexMap) + { + typedef remove_reverse_edge_descriptor< Graph, + typename graph_traits< Graph >::edge_descriptor > + cvt; + typename graph_traits< Graph >::vertex_iterator vi, vi_end; + for (boost::tie(vi, vi_end) = vertices(g_in); vi != vi_end; ++vi) + { + typename graph_traits< MutableGraph >::vertex_descriptor new_v + = add_vertex(g_out); + put(orig2copy, *vi, new_v); + copy_vertex(*vi, new_v); + } + for (boost::tie(vi, vi_end) = vertices(g_in); vi != vi_end; ++vi) + { + typename graph_traits< Graph >::out_edge_iterator ei, ei_end; + for (boost::tie(ei, ei_end) = out_edges(*vi, g_in); + ei != ei_end; ++ei) + { + typename graph_traits< MutableGraph >::edge_descriptor + new_e; + bool inserted; + boost::tie(new_e, inserted) + = add_edge(get(orig2copy, source(*ei, g_in)), + get(orig2copy, target(*ei, g_in)), g_out); + copy_edge(cvt::convert(*ei, g_in), new_e); + } + } } - } }; // for undirected graphs - template <> struct copy_graph_impl<2> + template <> struct copy_graph_impl< 2 > { - template - static void apply(const Graph& g_in, MutableGraph& g_out, - CopyVertex copy_vertex, CopyEdge copy_edge, - Orig2CopyVertexIndexMap orig2copy, - IndexMap index_map) - { - typedef remove_reverse_edge_descriptor::edge_descriptor> cvt; - typedef color_traits Color; - std::vector - color(num_vertices(g_in), Color::white()); - typename graph_traits::vertex_iterator vi, vi_end; - for (boost::tie(vi, vi_end) = vertices(g_in); vi != vi_end; ++vi) { - typename graph_traits::vertex_descriptor - new_v = add_vertex(g_out); - put(orig2copy, *vi, new_v); - copy_vertex(*vi, new_v); - } - for (boost::tie(vi, vi_end) = vertices(g_in); vi != vi_end; ++vi) { - typename graph_traits::out_edge_iterator ei, ei_end; - for (boost::tie(ei, ei_end) = out_edges(*vi, g_in); ei != ei_end; ++ei) { - typename graph_traits::edge_descriptor new_e; - bool inserted; - if (color[get(index_map, target(*ei, g_in))] == Color::white()) { - boost::tie(new_e, inserted) = add_edge(get(orig2copy, source(*ei,g_in)), - get(orig2copy, target(*ei,g_in)), - g_out); - copy_edge(cvt::convert(*ei, g_in), new_e); + template < typename Graph, typename MutableGraph, typename CopyVertex, + typename CopyEdge, typename IndexMap, + typename Orig2CopyVertexIndexMap > + static void apply(const Graph& g_in, MutableGraph& g_out, + CopyVertex copy_vertex, CopyEdge copy_edge, + Orig2CopyVertexIndexMap orig2copy, IndexMap index_map) + { + typedef remove_reverse_edge_descriptor< Graph, + typename graph_traits< Graph >::edge_descriptor > + cvt; + typedef color_traits< default_color_type > Color; + std::vector< default_color_type > color( + num_vertices(g_in), Color::white()); + typename graph_traits< Graph >::vertex_iterator vi, vi_end; + for (boost::tie(vi, vi_end) = vertices(g_in); vi != vi_end; ++vi) + { + typename graph_traits< MutableGraph >::vertex_descriptor new_v + = add_vertex(g_out); + put(orig2copy, *vi, new_v); + copy_vertex(*vi, new_v); + } + for (boost::tie(vi, vi_end) = vertices(g_in); vi != vi_end; ++vi) + { + typename graph_traits< Graph >::out_edge_iterator ei, ei_end; + for (boost::tie(ei, ei_end) = out_edges(*vi, g_in); + ei != ei_end; ++ei) + { + typename graph_traits< MutableGraph >::edge_descriptor + new_e; + bool inserted; + if (color[get(index_map, target(*ei, g_in))] + == Color::white()) + { + boost::tie(new_e, inserted) + = add_edge(get(orig2copy, source(*ei, g_in)), + get(orig2copy, target(*ei, g_in)), g_out); + copy_edge(cvt::convert(*ei, g_in), new_e); + } + } + color[get(index_map, *vi)] = Color::black(); } - } - color[get(index_map, *vi)] = Color::black(); } - } }; - template - struct choose_graph_copy { - typedef typename graph_traits::traversal_category Trv; - typedef typename graph_traits::directed_category Dr; - enum { algo = - (is_convertible::value - && is_convertible::value) - ? 0 : is_convertible::value ? 1 : 2 }; - typedef copy_graph_impl type; + template < class Graph > struct choose_graph_copy + { + typedef typename graph_traits< Graph >::traversal_category Trv; + typedef typename graph_traits< Graph >::directed_category Dr; + enum + { + algo = (is_convertible< Trv, vertex_list_graph_tag >::value + && is_convertible< Trv, edge_list_graph_tag >::value) + ? 0 + : is_convertible< Dr, directed_tag >::value ? 1 : 2 + }; + typedef copy_graph_impl< algo > type; }; //------------------------------------------------------------------------- - struct choose_copier_parameter { - template - struct bind_ { - typedef const P& result_type; - static result_type apply(const P& p, const G1&, G2&) - { return p; } - }; + struct choose_copier_parameter + { + template < class P, class G1, class G2 > struct bind_ + { + typedef const P& result_type; + static result_type apply(const P& p, const G1&, G2&) { return p; } + }; }; - struct choose_default_edge_copier { - template - struct bind_ { - typedef edge_copier result_type; - static result_type apply(const P&, const G1& g1, G2& g2) { - return result_type(g1, g2); - } - }; + struct choose_default_edge_copier + { + template < class P, class G1, class G2 > struct bind_ + { + typedef edge_copier< G1, G2 > result_type; + static result_type apply(const P&, const G1& g1, G2& g2) + { + return result_type(g1, g2); + } + }; }; - template - struct choose_edge_copy { - typedef choose_copier_parameter type; + template < class Param > struct choose_edge_copy + { + typedef choose_copier_parameter type; }; - template <> - struct choose_edge_copy { - typedef choose_default_edge_copier type; + template <> struct choose_edge_copy< param_not_found > + { + typedef choose_default_edge_copier type; }; - template - struct choose_edge_copier_helper { - typedef typename choose_edge_copy::type Selector; - typedef typename Selector:: template bind_ Bind; - typedef Bind type; - typedef typename Bind::result_type result_type; + template < class Param, class G1, class G2 > + struct choose_edge_copier_helper + { + typedef typename choose_edge_copy< Param >::type Selector; + typedef typename Selector::template bind_< Param, G1, G2 > Bind; + typedef Bind type; + typedef typename Bind::result_type result_type; }; - template - typename detail::choose_edge_copier_helper::result_type + template < typename Param, typename G1, typename G2 > + typename detail::choose_edge_copier_helper< Param, G1, G2 >::result_type choose_edge_copier(const Param& params, const G1& g_in, G2& g_out) { - typedef typename - detail::choose_edge_copier_helper::type Choice; - return Choice::apply(params, g_in, g_out); + typedef + typename detail::choose_edge_copier_helper< Param, G1, G2 >::type + Choice; + return Choice::apply(params, g_in, g_out); } - - struct choose_default_vertex_copier { - template - struct bind_ { - typedef vertex_copier result_type; - static result_type apply(const P&, const G1& g1, G2& g2) { - return result_type(g1, g2); - } - }; + struct choose_default_vertex_copier + { + template < class P, class G1, class G2 > struct bind_ + { + typedef vertex_copier< G1, G2 > result_type; + static result_type apply(const P&, const G1& g1, G2& g2) + { + return result_type(g1, g2); + } + }; }; - template - struct choose_vertex_copy { - typedef choose_copier_parameter type; + template < class Param > struct choose_vertex_copy + { + typedef choose_copier_parameter type; }; - template <> - struct choose_vertex_copy { - typedef choose_default_vertex_copier type; + template <> struct choose_vertex_copy< param_not_found > + { + typedef choose_default_vertex_copier type; }; - template - struct choose_vertex_copier_helper { - typedef typename choose_vertex_copy::type Selector; - typedef typename Selector:: template bind_ Bind; - typedef Bind type; - typedef typename Bind::result_type result_type; + template < class Param, class G1, class G2 > + struct choose_vertex_copier_helper + { + typedef typename choose_vertex_copy< Param >::type Selector; + typedef typename Selector::template bind_< Param, G1, G2 > Bind; + typedef Bind type; + typedef typename Bind::result_type result_type; }; - template - typename detail::choose_vertex_copier_helper::result_type + template < typename Param, typename G1, typename G2 > + typename detail::choose_vertex_copier_helper< Param, G1, G2 >::result_type choose_vertex_copier(const Param& params, const G1& g_in, G2& g_out) { - typedef typename - detail::choose_vertex_copier_helper::type Choice; - return Choice::apply(params, g_in, g_out); + typedef + typename detail::choose_vertex_copier_helper< Param, G1, G2 >::type + Choice; + return Choice::apply(params, g_in, g_out); } - } // namespace detail - +} // namespace detail - template - void copy_graph(const VertexListGraph& g_in, MutableGraph& g_out) - { +template < typename VertexListGraph, typename MutableGraph > +void copy_graph(const VertexListGraph& g_in, MutableGraph& g_out) +{ if (num_vertices(g_in) == 0) - return; - typedef typename graph_traits::vertex_descriptor vertex_t; - std::vector orig2copy(num_vertices(g_in)); - typedef typename detail::choose_graph_copy::type - copy_impl; - copy_impl::apply - (g_in, g_out, - detail::make_vertex_copier(g_in, g_out), - detail::make_edge_copier(g_in, g_out), - make_iterator_property_map(orig2copy.begin(), - get(vertex_index, g_in), orig2copy[0]), - get(vertex_index, g_in) - ); - } - - template - void copy_graph(const VertexListGraph& g_in, MutableGraph& g_out, - const bgl_named_params& params) - { - typename std::vector::size_type n; - n = is_default_param(get_param(params, orig_to_copy_t())) - ? num_vertices(g_in) : 1; + return; + typedef typename graph_traits< MutableGraph >::vertex_descriptor vertex_t; + std::vector< vertex_t > orig2copy(num_vertices(g_in)); + typedef + typename detail::choose_graph_copy< VertexListGraph >::type copy_impl; + copy_impl::apply(g_in, g_out, detail::make_vertex_copier(g_in, g_out), + detail::make_edge_copier(g_in, g_out), + make_iterator_property_map( + orig2copy.begin(), get(vertex_index, g_in), orig2copy[0]), + get(vertex_index, g_in)); +} + +template < typename VertexListGraph, typename MutableGraph, class P, class T, + class R > +void copy_graph(const VertexListGraph& g_in, MutableGraph& g_out, + const bgl_named_params< P, T, R >& params) +{ + typename std::vector< T >::size_type n; + n = is_default_param(get_param(params, orig_to_copy_t())) + ? num_vertices(g_in) + : 1; if (n == 0) - return; - std::vector::vertex_descriptor> - orig2copy(n); - - typedef typename detail::choose_graph_copy::type - copy_impl; - copy_impl::apply - (g_in, g_out, - detail::choose_vertex_copier(get_param(params, vertex_copy_t()), - g_in, g_out), - detail::choose_edge_copier(get_param(params, edge_copy_t()), - g_in, g_out), - choose_param(get_param(params, orig_to_copy_t()), - make_iterator_property_map - (orig2copy.begin(), - choose_const_pmap(get_param(params, vertex_index), - g_in, vertex_index), orig2copy[0])), - choose_const_pmap(get_param(params, vertex_index), g_in, vertex_index) - ); - } - - namespace detail { - - template + return; + std::vector< + BOOST_DEDUCED_TYPENAME graph_traits< MutableGraph >::vertex_descriptor > + orig2copy(n); + + typedef + typename detail::choose_graph_copy< VertexListGraph >::type copy_impl; + copy_impl::apply(g_in, g_out, + detail::choose_vertex_copier( + get_param(params, vertex_copy_t()), g_in, g_out), + detail::choose_edge_copier( + get_param(params, edge_copy_t()), g_in, g_out), + choose_param(get_param(params, orig_to_copy_t()), + make_iterator_property_map(orig2copy.begin(), + choose_const_pmap( + get_param(params, vertex_index), g_in, vertex_index), + orig2copy[0])), + choose_const_pmap(get_param(params, vertex_index), g_in, vertex_index)); +} + +namespace detail +{ + + template < class NewGraph, class Copy2OrigIndexMap, class CopyVertex, + class CopyEdge > struct graph_copy_visitor : public bfs_visitor<> { - graph_copy_visitor(NewGraph& graph, Copy2OrigIndexMap c, - CopyVertex cv, CopyEdge ce) - : g_out(graph), orig2copy(c), copy_vertex(cv), copy_edge(ce) { } - - template - typename graph_traits::vertex_descriptor copy_one_vertex(Vertex u) const { - typename graph_traits::vertex_descriptor - new_u = add_vertex(g_out); - put(orig2copy, u, new_u); - copy_vertex(u, new_u); - return new_u; - } - - template - void tree_edge(Edge e, const Graph& g_in) const { - // For a tree edge, the target vertex has not been copied yet. - typename graph_traits::edge_descriptor new_e; - bool inserted; - boost::tie(new_e, inserted) = add_edge(get(orig2copy, source(e, g_in)), - this->copy_one_vertex(target(e, g_in)), - g_out); - copy_edge(e, new_e); - } - - template - void non_tree_edge(Edge e, const Graph& g_in) const { - // For a non-tree edge, the target vertex has already been copied. - typename graph_traits::edge_descriptor new_e; - bool inserted; - boost::tie(new_e, inserted) = add_edge(get(orig2copy, source(e, g_in)), - get(orig2copy, target(e, g_in)), - g_out); - copy_edge(e, new_e); - } + graph_copy_visitor( + NewGraph& graph, Copy2OrigIndexMap c, CopyVertex cv, CopyEdge ce) + : g_out(graph), orig2copy(c), copy_vertex(cv), copy_edge(ce) + { + } + + template < class Vertex > + typename graph_traits< NewGraph >::vertex_descriptor copy_one_vertex( + Vertex u) const + { + typename graph_traits< NewGraph >::vertex_descriptor new_u + = add_vertex(g_out); + put(orig2copy, u, new_u); + copy_vertex(u, new_u); + return new_u; + } + + template < class Edge, class Graph > + void tree_edge(Edge e, const Graph& g_in) const + { + // For a tree edge, the target vertex has not been copied yet. + typename graph_traits< NewGraph >::edge_descriptor new_e; + bool inserted; + boost::tie(new_e, inserted) + = add_edge(get(orig2copy, source(e, g_in)), + this->copy_one_vertex(target(e, g_in)), g_out); + copy_edge(e, new_e); + } + + template < class Edge, class Graph > + void non_tree_edge(Edge e, const Graph& g_in) const + { + // For a non-tree edge, the target vertex has already been copied. + typename graph_traits< NewGraph >::edge_descriptor new_e; + bool inserted; + boost::tie(new_e, inserted) + = add_edge(get(orig2copy, source(e, g_in)), + get(orig2copy, target(e, g_in)), g_out); + copy_edge(e, new_e); + } + private: - NewGraph& g_out; - Copy2OrigIndexMap orig2copy; - CopyVertex copy_vertex; - CopyEdge copy_edge; + NewGraph& g_out; + Copy2OrigIndexMap orig2copy; + CopyVertex copy_vertex; + CopyEdge copy_edge; }; - template - typename graph_traits::vertex_descriptor - copy_component_impl - (const Graph& g_in, - typename graph_traits::vertex_descriptor src, - MutableGraph& g_out, - CopyVertex copy_vertex, CopyEdge copy_edge, - Orig2CopyVertexIndexMap orig2copy, - const Params& params) + template < typename Graph, typename MutableGraph, typename CopyVertex, + typename CopyEdge, typename Orig2CopyVertexIndexMap, typename Params > + typename graph_traits< MutableGraph >::vertex_descriptor + copy_component_impl(const Graph& g_in, + typename graph_traits< Graph >::vertex_descriptor src, + MutableGraph& g_out, CopyVertex copy_vertex, CopyEdge copy_edge, + Orig2CopyVertexIndexMap orig2copy, const Params& params) { - graph_copy_visitor vis(g_out, orig2copy, copy_vertex, copy_edge); - typename graph_traits::vertex_descriptor src_copy - = vis.copy_one_vertex(src); - breadth_first_search(g_in, src, params.visitor(vis)); - return src_copy; + graph_copy_visitor< MutableGraph, Orig2CopyVertexIndexMap, CopyVertex, + CopyEdge > + vis(g_out, orig2copy, copy_vertex, copy_edge); + typename graph_traits< MutableGraph >::vertex_descriptor src_copy + = vis.copy_one_vertex(src); + breadth_first_search(g_in, src, params.visitor(vis)); + return src_copy; } - } // namespace detail - - - // Copy all the vertices and edges of graph g_in that are reachable - // from the source vertex into graph g_out. Return the vertex - // in g_out that matches the source vertex of g_in. - template - typename graph_traits::vertex_descriptor - copy_component(IncidenceGraph& g_in, - typename graph_traits::vertex_descriptor src, - MutableGraph& g_out, - const bgl_named_params& params) - { - typename std::vector::size_type n; - n = is_default_param(get_param(params, orig_to_copy_t())) - ? num_vertices(g_in) : 1; - std::vector::vertex_descriptor> - orig2copy(n); - - return detail::copy_component_impl - (g_in, src, g_out, - detail::choose_vertex_copier(get_param(params, vertex_copy_t()), - g_in, g_out), - detail::choose_edge_copier(get_param(params, edge_copy_t()), - g_in, g_out), - choose_param(get_param(params, orig_to_copy_t()), - make_iterator_property_map - (orig2copy.begin(), - choose_pmap(get_param(params, vertex_index), - g_in, vertex_index), orig2copy[0])), - params - ); - } - - template - typename graph_traits::vertex_descriptor - copy_component(IncidenceGraph& g_in, - typename graph_traits::vertex_descriptor src, - MutableGraph& g_out) - { - std::vector::vertex_descriptor> - orig2copy(num_vertices(g_in)); - - return detail::copy_component_impl - (g_in, src, g_out, - make_vertex_copier(g_in, g_out), - make_edge_copier(g_in, g_out), - make_iterator_property_map(orig2copy.begin(), - get(vertex_index, g_in), orig2copy[0]), - bgl_named_params('x') // dummy param object - ); - } +} // namespace detail + +// Copy all the vertices and edges of graph g_in that are reachable +// from the source vertex into graph g_out. Return the vertex +// in g_out that matches the source vertex of g_in. +template < typename IncidenceGraph, typename MutableGraph, typename P, + typename T, typename R > +typename graph_traits< MutableGraph >::vertex_descriptor copy_component( + IncidenceGraph& g_in, + typename graph_traits< IncidenceGraph >::vertex_descriptor src, + MutableGraph& g_out, const bgl_named_params< P, T, R >& params) +{ + typename std::vector< T >::size_type n; + n = is_default_param(get_param(params, orig_to_copy_t())) + ? num_vertices(g_in) + : 1; + std::vector< typename graph_traits< IncidenceGraph >::vertex_descriptor > + orig2copy(n); + + return detail::copy_component_impl(g_in, src, g_out, + detail::choose_vertex_copier( + get_param(params, vertex_copy_t()), g_in, g_out), + detail::choose_edge_copier( + get_param(params, edge_copy_t()), g_in, g_out), + choose_param(get_param(params, orig_to_copy_t()), + make_iterator_property_map(orig2copy.begin(), + choose_pmap( + get_param(params, vertex_index), g_in, vertex_index), + orig2copy[0])), + params); +} + +template < typename IncidenceGraph, typename MutableGraph > +typename graph_traits< MutableGraph >::vertex_descriptor copy_component( + IncidenceGraph& g_in, + typename graph_traits< IncidenceGraph >::vertex_descriptor src, + MutableGraph& g_out) +{ + std::vector< typename graph_traits< IncidenceGraph >::vertex_descriptor > + orig2copy(num_vertices(g_in)); + + return detail::copy_component_impl(g_in, src, g_out, + make_vertex_copier(g_in, g_out), make_edge_copier(g_in, g_out), + make_iterator_property_map( + orig2copy.begin(), get(vertex_index, g_in), orig2copy[0]), + bgl_named_params< char, char >('x') // dummy param object + ); +} } // namespace boost diff --git a/include/boost/graph/core_numbers.hpp b/include/boost/graph/core_numbers.hpp index 9384f5d66..95053caf1 100644 --- a/include/boost/graph/core_numbers.hpp +++ b/include/boost/graph/core_numbers.hpp @@ -30,297 +30,321 @@ // 8 February 2008 // Fixed headers and missing typename -namespace boost { - - // A linear time O(m) algorithm to compute the indegree core number - // of a graph for unweighted graphs. - // - // and a O((n+m) log n) algorithm to compute the in-edge-weight core - // numbers of a weighted graph. - // - // The linear algorithm comes from: - // Vladimir Batagelj and Matjaz Zaversnik, "An O(m) Algorithm for Cores - // Decomposition of Networks." Sept. 1 2002. - - template - struct CoreNumbersVisitorConcept { - void constraints() - { - BOOST_CONCEPT_ASSERT(( CopyConstructibleConcept )); - vis.examine_vertex(u,g); - vis.finish_vertex(u,g); - vis.examine_edge(e,g); - } - Visitor vis; - Graph g; - typename graph_traits::vertex_descriptor u; - typename graph_traits::edge_descriptor e; - }; +namespace boost +{ - template - class core_numbers_visitor : public bfs_visitor { - public: - core_numbers_visitor() {} - core_numbers_visitor(Visitors vis) - : bfs_visitor(vis) {} +// A linear time O(m) algorithm to compute the indegree core number +// of a graph for unweighted graphs. +// +// and a O((n+m) log n) algorithm to compute the in-edge-weight core +// numbers of a weighted graph. +// +// The linear algorithm comes from: +// Vladimir Batagelj and Matjaz Zaversnik, "An O(m) Algorithm for Cores +// Decomposition of Networks." Sept. 1 2002. - private: - template - void initialize_vertex(Vertex, Graph&) {} +template < typename Visitor, typename Graph > struct CoreNumbersVisitorConcept +{ + void constraints() + { + BOOST_CONCEPT_ASSERT((CopyConstructibleConcept< Visitor >)); + vis.examine_vertex(u, g); + vis.finish_vertex(u, g); + vis.examine_edge(e, g); + } + Visitor vis; + Graph g; + typename graph_traits< Graph >::vertex_descriptor u; + typename graph_traits< Graph >::edge_descriptor e; +}; + +template < class Visitors = null_visitor > +class core_numbers_visitor : public bfs_visitor< Visitors > +{ +public: + core_numbers_visitor() {} + core_numbers_visitor(Visitors vis) : bfs_visitor< Visitors >(vis) {} + +private: + template < class Vertex, class Graph > + void initialize_vertex(Vertex, Graph&) + { + } - template - void discover_vertex(Vertex , Graph&) {} + template < class Vertex, class Graph > void discover_vertex(Vertex, Graph&) + { + } - template - void gray_target(Vertex, Graph&) {} + template < class Vertex, class Graph > void gray_target(Vertex, Graph&) {} - template - void black_target(Vertex, Graph&) {} + template < class Vertex, class Graph > void black_target(Vertex, Graph&) {} - template - void tree_edge(Edge, Graph&) {} + template < class Edge, class Graph > void tree_edge(Edge, Graph&) {} - template - void non_tree_edge(Edge, Graph&) {} - }; + template < class Edge, class Graph > void non_tree_edge(Edge, Graph&) {} +}; - template - core_numbers_visitor make_core_numbers_visitor(Visitors vis) - { return core_numbers_visitor(vis); } +template < class Visitors > +core_numbers_visitor< Visitors > make_core_numbers_visitor(Visitors vis) +{ + return core_numbers_visitor< Visitors >(vis); +} - typedef core_numbers_visitor<> default_core_numbers_visitor; +typedef core_numbers_visitor<> default_core_numbers_visitor; - namespace detail { +namespace detail +{ - // implement a constant_property_map to simplify compute_in_degree - // for the weighted and unweighted case - // this is based on dummy property map - template - class constant_value_property_map - : public boost::put_get_helper > + // implement a constant_property_map to simplify compute_in_degree + // for the weighted and unweighted case + // this is based on dummy property map + template < typename ValueType > + class constant_value_property_map + : public boost::put_get_helper< ValueType, + constant_value_property_map< ValueType > > + { + public: + typedef void key_type; + typedef ValueType value_type; + typedef const ValueType& reference; + typedef boost::readable_property_map_tag category; + inline constant_value_property_map(ValueType cc) : c(cc) {} + inline constant_value_property_map( + const constant_value_property_map< ValueType >& x) + : c(x.c) { - public: - typedef void key_type; - typedef ValueType value_type; - typedef const ValueType& reference; - typedef boost::readable_property_map_tag category; - inline constant_value_property_map(ValueType cc) : c(cc) { } - inline constant_value_property_map(const constant_value_property_map& x) - : c(x.c) { } - template - inline reference operator[](Vertex) const { return c; } - protected: - ValueType c; - }; - - - // the core numbers start as the indegree or inweight. This function - // will initialize these values - template - void compute_in_degree_map(Graph& g, CoreMap d, EdgeWeightMap wm) + } + template < class Vertex > inline reference operator[](Vertex) const { - typename graph_traits::vertex_iterator vi,vi_end; - typename graph_traits::out_edge_iterator ei,ei_end; - for (boost::tie(vi,vi_end) = vertices(g); vi!=vi_end; ++vi) { - put(d,*vi,0); - } - for (boost::tie(vi,vi_end) = vertices(g); vi!=vi_end; ++vi) { - for (boost::tie(ei,ei_end) = out_edges(*vi,g); ei!=ei_end; ++ei) { - put(d,target(*ei,g),get(d,target(*ei,g))+get(wm,*ei)); - } + return c; + } + + protected: + ValueType c; + }; + + // the core numbers start as the indegree or inweight. This function + // will initialize these values + template < typename Graph, typename CoreMap, typename EdgeWeightMap > + void compute_in_degree_map(Graph& g, CoreMap d, EdgeWeightMap wm) + { + typename graph_traits< Graph >::vertex_iterator vi, vi_end; + typename graph_traits< Graph >::out_edge_iterator ei, ei_end; + for (boost::tie(vi, vi_end) = vertices(g); vi != vi_end; ++vi) + { + put(d, *vi, 0); + } + for (boost::tie(vi, vi_end) = vertices(g); vi != vi_end; ++vi) + { + for (boost::tie(ei, ei_end) = out_edges(*vi, g); ei != ei_end; ++ei) + { + put(d, target(*ei, g), get(d, target(*ei, g)) + get(wm, *ei)); } } + } - // the version for weighted graphs is a little different - template - typename property_traits::value_type - core_numbers_impl(Graph& g, CoreMap c, EdgeWeightMap wm, - MutableQueue& Q, Visitor vis) + // the version for weighted graphs is a little different + template < typename Graph, typename CoreMap, typename EdgeWeightMap, + typename MutableQueue, typename Visitor > + typename property_traits< CoreMap >::value_type core_numbers_impl( + Graph& g, CoreMap c, EdgeWeightMap wm, MutableQueue& Q, Visitor vis) + { + typename property_traits< CoreMap >::value_type v_cn = 0; + typedef typename graph_traits< Graph >::vertex_descriptor vertex; + while (!Q.empty()) { - typename property_traits::value_type v_cn = 0; - typedef typename graph_traits::vertex_descriptor vertex; - while (!Q.empty()) + // remove v from the Q, and then decrease the core numbers + // of its successors + vertex v = Q.top(); + vis.examine_vertex(v, g); + Q.pop(); + v_cn = get(c, v); + typename graph_traits< Graph >::out_edge_iterator oi, oi_end; + for (boost::tie(oi, oi_end) = out_edges(v, g); oi != oi_end; ++oi) { - // remove v from the Q, and then decrease the core numbers - // of its successors - vertex v = Q.top(); - vis.examine_vertex(v,g); - Q.pop(); - v_cn = get(c,v); - typename graph_traits::out_edge_iterator oi,oi_end; - for (boost::tie(oi,oi_end) = out_edges(v,g); oi!=oi_end; ++oi) { - vis.examine_edge(*oi,g); - vertex u = target(*oi,g); - // if c[u] > c[v], then u is still in the graph, - if (get(c,u) > v_cn) { - // remove the edge - put(c,u,get(c,u)-get(wm,*oi)); - if (Q.contains(u)) - Q.update(u); - } + vis.examine_edge(*oi, g); + vertex u = target(*oi, g); + // if c[u] > c[v], then u is still in the graph, + if (get(c, u) > v_cn) + { + // remove the edge + put(c, u, get(c, u) - get(wm, *oi)); + if (Q.contains(u)) + Q.update(u); } - vis.finish_vertex(v,g); } - return (v_cn); + vis.finish_vertex(v, g); } + return (v_cn); + } - template - typename property_traits::value_type - core_numbers_dispatch(Graph&g, CoreMap c, EdgeWeightMap wm, - IndexMap im, CoreNumVisitor vis) + template < typename Graph, typename CoreMap, typename EdgeWeightMap, + typename IndexMap, typename CoreNumVisitor > + typename property_traits< CoreMap >::value_type core_numbers_dispatch( + Graph& g, CoreMap c, EdgeWeightMap wm, IndexMap im, CoreNumVisitor vis) + { + typedef typename property_traits< CoreMap >::value_type D; + typedef std::less< D > Cmp; + // build the mutable queue + typedef typename graph_traits< Graph >::vertex_descriptor vertex; + std::vector< std::size_t > index_in_heap_data(num_vertices(g)); + typedef iterator_property_map< std::vector< std::size_t >::iterator, + IndexMap > + index_in_heap_map_type; + index_in_heap_map_type index_in_heap_map( + index_in_heap_data.begin(), im); + typedef d_ary_heap_indirect< vertex, 4, index_in_heap_map_type, CoreMap, + Cmp > + MutableQueue; + MutableQueue Q(c, index_in_heap_map, Cmp()); + typename graph_traits< Graph >::vertex_iterator vi, vi_end; + for (boost::tie(vi, vi_end) = vertices(g); vi != vi_end; ++vi) { - typedef typename property_traits::value_type D; - typedef std::less Cmp; - // build the mutable queue - typedef typename graph_traits::vertex_descriptor vertex; - std::vector index_in_heap_data(num_vertices(g)); - typedef iterator_property_map::iterator, IndexMap> - index_in_heap_map_type; - index_in_heap_map_type index_in_heap_map(index_in_heap_data.begin(), im); - typedef d_ary_heap_indirect MutableQueue; - MutableQueue Q(c, index_in_heap_map, Cmp()); - typename graph_traits::vertex_iterator vi,vi_end; - for (boost::tie(vi,vi_end) = vertices(g); vi!=vi_end; ++vi) { - Q.push(*vi); - } - return core_numbers_impl(g, c, wm, Q, vis); + Q.push(*vi); } + return core_numbers_impl(g, c, wm, Q, vis); + } + + // the version for the unweighted case + // for this functions CoreMap must be initialized + // with the in degree of each vertex + template < typename Graph, typename CoreMap, typename PositionMap, + typename Visitor > + typename property_traits< CoreMap >::value_type core_numbers_impl( + Graph& g, CoreMap c, PositionMap pos, Visitor vis) + { + typedef typename graph_traits< Graph >::vertices_size_type size_type; + typedef typename graph_traits< Graph >::degree_size_type degree_type; + typedef typename graph_traits< Graph >::vertex_descriptor vertex; + typename graph_traits< Graph >::vertex_iterator vi, vi_end; + + // store the vertex core numbers + typename property_traits< CoreMap >::value_type v_cn = 0; - // the version for the unweighted case - // for this functions CoreMap must be initialized - // with the in degree of each vertex - template - typename property_traits::value_type - core_numbers_impl(Graph& g, CoreMap c, PositionMap pos, Visitor vis) + // compute the maximum degree (degrees are in the coremap) + typename graph_traits< Graph >::degree_size_type max_deg = 0; + for (boost::tie(vi, vi_end) = vertices(g); vi != vi_end; ++vi) { - typedef typename graph_traits::vertices_size_type size_type; - typedef typename graph_traits::degree_size_type degree_type; - typedef typename graph_traits::vertex_descriptor vertex; - typename graph_traits::vertex_iterator vi,vi_end; - - // store the vertex core numbers - typename property_traits::value_type v_cn = 0; - - // compute the maximum degree (degrees are in the coremap) - typename graph_traits::degree_size_type max_deg = 0; - for (boost::tie(vi,vi_end) = vertices(g); vi!=vi_end; ++vi) { - max_deg = (std::max::degree_size_type>)(max_deg, get(c,*vi)); - } + max_deg = (std::max< + typename graph_traits< Graph >::degree_size_type >)(max_deg, + get(c, *vi)); + } - // store the vertices in bins by their degree - // allocate two extra locations to ease boundary cases - std::vector bin(max_deg+2); - for (boost::tie(vi,vi_end) = vertices(g); vi!=vi_end; ++vi) { - ++bin[get(c,*vi)]; - } + // store the vertices in bins by their degree + // allocate two extra locations to ease boundary cases + std::vector< size_type > bin(max_deg + 2); + for (boost::tie(vi, vi_end) = vertices(g); vi != vi_end; ++vi) + { + ++bin[get(c, *vi)]; + } - // this loop sets bin[d] to the starting position of vertices - // with degree d in the vert array for the bucket sort - size_type cur_pos = 0; - for (degree_type cur_deg = 0; cur_deg < max_deg+2; ++cur_deg) { - degree_type tmp = bin[cur_deg]; - bin[cur_deg] = cur_pos; - cur_pos += tmp; - } + // this loop sets bin[d] to the starting position of vertices + // with degree d in the vert array for the bucket sort + size_type cur_pos = 0; + for (degree_type cur_deg = 0; cur_deg < max_deg + 2; ++cur_deg) + { + degree_type tmp = bin[cur_deg]; + bin[cur_deg] = cur_pos; + cur_pos += tmp; + } - // perform the bucket sort with pos and vert so that - // pos[0] is the vertex of smallest degree - std::vector vert(num_vertices(g)); - for (boost::tie(vi,vi_end) = vertices(g); vi!=vi_end; ++vi) { - vertex v=*vi; - size_type p=bin[get(c,v)]; - put(pos,v,p); - vert[p]=v; - ++bin[get(c,v)]; - } - // we ``abused'' bin while placing the vertices, now, - // we need to restore it - std::copy(boost::make_reverse_iterator(bin.end()-2), - boost::make_reverse_iterator(bin.begin()), - boost::make_reverse_iterator(bin.end()-1)); - // now simulate removing the vertices - for (size_type i=0; i < num_vertices(g); ++i) { - vertex v = vert[i]; - vis.examine_vertex(v,g); - v_cn = get(c,v); - typename graph_traits::out_edge_iterator oi,oi_end; - for (boost::tie(oi,oi_end) = out_edges(v,g); oi!=oi_end; ++oi) { - vis.examine_edge(*oi,g); - vertex u = target(*oi,g); - // if c[u] > c[v], then u is still in the graph, - if (get(c,u) > v_cn) { - degree_type deg_u = get(c,u); - degree_type pos_u = get(pos,u); - // w is the first vertex with the same degree as u - // (this is the resort operation!) - degree_type pos_w = bin[deg_u]; - vertex w = vert[pos_w]; - if (u!=v) { - // swap u and w - put(pos,u,pos_w); - put(pos,w,pos_u); - vert[pos_w] = u; - vert[pos_u] = w; - } - // now, the vertices array is sorted assuming - // we perform the following step - // start the set of vertices with degree of u - // one into the future (this now points at vertex - // w which we swapped with u). - ++bin[deg_u]; - // we are removing v from the graph, so u's degree - // decreases - put(c,u,get(c,u)-1); + // perform the bucket sort with pos and vert so that + // pos[0] is the vertex of smallest degree + std::vector< vertex > vert(num_vertices(g)); + for (boost::tie(vi, vi_end) = vertices(g); vi != vi_end; ++vi) + { + vertex v = *vi; + size_type p = bin[get(c, v)]; + put(pos, v, p); + vert[p] = v; + ++bin[get(c, v)]; + } + // we ``abused'' bin while placing the vertices, now, + // we need to restore it + std::copy(boost::make_reverse_iterator(bin.end() - 2), + boost::make_reverse_iterator(bin.begin()), + boost::make_reverse_iterator(bin.end() - 1)); + // now simulate removing the vertices + for (size_type i = 0; i < num_vertices(g); ++i) + { + vertex v = vert[i]; + vis.examine_vertex(v, g); + v_cn = get(c, v); + typename graph_traits< Graph >::out_edge_iterator oi, oi_end; + for (boost::tie(oi, oi_end) = out_edges(v, g); oi != oi_end; ++oi) + { + vis.examine_edge(*oi, g); + vertex u = target(*oi, g); + // if c[u] > c[v], then u is still in the graph, + if (get(c, u) > v_cn) + { + degree_type deg_u = get(c, u); + degree_type pos_u = get(pos, u); + // w is the first vertex with the same degree as u + // (this is the resort operation!) + degree_type pos_w = bin[deg_u]; + vertex w = vert[pos_w]; + if (u != v) + { + // swap u and w + put(pos, u, pos_w); + put(pos, w, pos_u); + vert[pos_w] = u; + vert[pos_u] = w; } + // now, the vertices array is sorted assuming + // we perform the following step + // start the set of vertices with degree of u + // one into the future (this now points at vertex + // w which we swapped with u). + ++bin[deg_u]; + // we are removing v from the graph, so u's degree + // decreases + put(c, u, get(c, u) - 1); } - vis.finish_vertex(v,g); } - return v_cn; + vis.finish_vertex(v, g); } - - } // namespace detail - - // non-named parameter version for the unweighted case - template - typename property_traits::value_type - core_numbers(Graph& g, CoreMap c, CoreNumVisitor vis) - { - typedef typename graph_traits::vertices_size_type size_type; - detail::compute_in_degree_map(g,c, - detail::constant_value_property_map< - typename property_traits::value_type>(1) ); - return detail::core_numbers_impl(g,c, - make_iterator_property_map( - std::vector(num_vertices(g)).begin(),get(vertex_index, g)), - vis - ); - } - - // non-named paramter version for the unweighted case - template - typename property_traits::value_type - core_numbers(Graph& g, CoreMap c) - { - return core_numbers(g, c, make_core_numbers_visitor(null_visitor())); + return v_cn; } - // non-named parameter version for the weighted case - template - typename property_traits::value_type - core_numbers(Graph& g, CoreMap c, EdgeWeightMap wm, VertexIndexMap vim, - CoreNumVisitor vis) - { - detail::compute_in_degree_map(g,c,wm); - return detail::core_numbers_dispatch(g,c,wm,vim,vis); - } - - // non-named parameter version for the weighted case +} // namespace detail + +// non-named parameter version for the unweighted case +template < typename Graph, typename CoreMap, typename CoreNumVisitor > +typename property_traits< CoreMap >::value_type core_numbers( + Graph& g, CoreMap c, CoreNumVisitor vis) +{ + typedef typename graph_traits< Graph >::vertices_size_type size_type; + detail::compute_in_degree_map(g, c, + detail::constant_value_property_map< + typename property_traits< CoreMap >::value_type >(1)); + return detail::core_numbers_impl(g, c, + make_iterator_property_map( + std::vector< size_type >(num_vertices(g)).begin(), + get(vertex_index, g)), + vis); +} + +// non-named paramter version for the unweighted case +template < typename Graph, typename CoreMap > +typename property_traits< CoreMap >::value_type core_numbers( + Graph& g, CoreMap c) +{ + return core_numbers(g, c, make_core_numbers_visitor(null_visitor())); +} + +// non-named parameter version for the weighted case +template < typename Graph, typename CoreMap, typename EdgeWeightMap, + typename VertexIndexMap, typename CoreNumVisitor > +typename property_traits< CoreMap >::value_type core_numbers(Graph& g, + CoreMap c, EdgeWeightMap wm, VertexIndexMap vim, CoreNumVisitor vis) +{ + detail::compute_in_degree_map(g, c, wm); + return detail::core_numbers_dispatch(g, c, wm, vim, vis); +} + +// non-named parameter version for the weighted case // template // typename property_traits::value_type // core_numbers(Graph& g, CoreMap c, EdgeWeightMap wm) @@ -331,21 +355,21 @@ namespace boost { // make_core_numbers_visitor(null_visitor())); // } - template - typename property_traits::value_type - weighted_core_numbers(Graph& g, CoreMap c) - { - return weighted_core_numbers( - g,c, make_core_numbers_visitor(null_visitor()) - ); - } - - template - typename property_traits::value_type - weighted_core_numbers(Graph& g, CoreMap c, CoreNumVisitor vis) - { return core_numbers(g,c,get(edge_weight,g),get(vertex_index,g),vis); } +template < typename Graph, typename CoreMap > +typename property_traits< CoreMap >::value_type weighted_core_numbers( + Graph& g, CoreMap c) +{ + return weighted_core_numbers( + g, c, make_core_numbers_visitor(null_visitor())); +} + +template < typename Graph, typename CoreMap, typename CoreNumVisitor > +typename property_traits< CoreMap >::value_type weighted_core_numbers( + Graph& g, CoreMap c, CoreNumVisitor vis) +{ + return core_numbers(g, c, get(edge_weight, g), get(vertex_index, g), vis); +} } // namespace boost #endif // BOOST_GRAPH_CORE_NUMBERS_HPP - diff --git a/include/boost/graph/create_condensation_graph.hpp b/include/boost/graph/create_condensation_graph.hpp index f874a0868..1eb6fa2b6 100644 --- a/include/boost/graph/create_condensation_graph.hpp +++ b/include/boost/graph/create_condensation_graph.hpp @@ -13,70 +13,73 @@ #include #include -namespace boost { +namespace boost +{ - template - void create_condensation_graph(const Graph& g, - const ComponentLists& components, - ComponentNumberMap component_number, - CondensationGraph& cg, - EdgeMultiplicityMap edge_mult_map) - { - typedef typename graph_traits::vertex_descriptor vertex; - typedef typename graph_traits::vertices_size_type size_type; - typedef typename graph_traits::vertex_descriptor - cg_vertex; - std::vector to_cg_vertex(components.size()); +template < typename Graph, typename ComponentLists, typename ComponentNumberMap, + typename CondensationGraph, typename EdgeMultiplicityMap > +void create_condensation_graph(const Graph& g, const ComponentLists& components, + ComponentNumberMap component_number, CondensationGraph& cg, + EdgeMultiplicityMap edge_mult_map) +{ + typedef typename graph_traits< Graph >::vertex_descriptor vertex; + typedef typename graph_traits< Graph >::vertices_size_type size_type; + typedef + typename graph_traits< CondensationGraph >::vertex_descriptor cg_vertex; + std::vector< cg_vertex > to_cg_vertex(components.size()); for (size_type s = 0; s < components.size(); ++s) - to_cg_vertex[s] = add_vertex(cg); + to_cg_vertex[s] = add_vertex(cg); - for (size_type si = 0; si < components.size(); ++si) { - cg_vertex s = to_cg_vertex[si]; - std::vector adj; - for (size_type i = 0; i < components[si].size(); ++i) { - vertex u = components[s][i]; - typename graph_traits::adjacency_iterator v, v_end; - for (boost::tie(v, v_end) = adjacent_vertices(u, g); v != v_end; ++v) { - cg_vertex t = to_cg_vertex[component_number[*v]]; - if (s != t) // Avoid loops in the condensation graph - adj.push_back(t); + for (size_type si = 0; si < components.size(); ++si) + { + cg_vertex s = to_cg_vertex[si]; + std::vector< cg_vertex > adj; + for (size_type i = 0; i < components[si].size(); ++i) + { + vertex u = components[s][i]; + typename graph_traits< Graph >::adjacency_iterator v, v_end; + for (boost::tie(v, v_end) = adjacent_vertices(u, g); v != v_end; + ++v) + { + cg_vertex t = to_cg_vertex[component_number[*v]]; + if (s != t) // Avoid loops in the condensation graph + adj.push_back(t); + } } - } - std::sort(adj.begin(), adj.end()); - if (! adj.empty()) { - size_type i = 0; - cg_vertex t = adj[i]; - typename graph_traits::edge_descriptor e; - bool inserted; - boost::tie(e, inserted) = add_edge(s, t, cg); - put(edge_mult_map, e, 1); - ++i; - while (i < adj.size()) { - if (adj[i] == t) - put(edge_mult_map, e, get(edge_mult_map, e) + 1); - else { - t = adj[i]; + std::sort(adj.begin(), adj.end()); + if (!adj.empty()) + { + size_type i = 0; + cg_vertex t = adj[i]; + typename graph_traits< CondensationGraph >::edge_descriptor e; + bool inserted; boost::tie(e, inserted) = add_edge(s, t, cg); put(edge_mult_map, e, 1); - } - ++i; + ++i; + while (i < adj.size()) + { + if (adj[i] == t) + put(edge_mult_map, e, get(edge_mult_map, e) + 1); + else + { + t = adj[i]; + boost::tie(e, inserted) = add_edge(s, t, cg); + put(edge_mult_map, e, 1); + } + ++i; + } } - } } - } - - template - void create_condensation_graph(const Graph& g, - const ComponentLists& components, - ComponentNumberMap component_number, - CondensationGraph& cg) - { - create_condensation_graph(g, components, component_number, cg, - dummy_property_map()); - } +} + +template < typename Graph, typename ComponentLists, typename ComponentNumberMap, + typename CondensationGraph > +void create_condensation_graph(const Graph& g, const ComponentLists& components, + ComponentNumberMap component_number, CondensationGraph& cg) +{ + create_condensation_graph( + g, components, component_number, cg, dummy_property_map()); +} } // namespace boost diff --git a/include/boost/graph/cuthill_mckee_ordering.hpp b/include/boost/graph/cuthill_mckee_ordering.hpp index e16595c6c..75750bdf5 100644 --- a/include/boost/graph/cuthill_mckee_ordering.hpp +++ b/include/boost/graph/cuthill_mckee_ordering.hpp @@ -16,173 +16,166 @@ #include #include - /* (Reverse) Cuthill-McKee Algorithm for matrix reordering */ -namespace boost { - - namespace detail { - +namespace boost +{ +namespace detail +{ - template < typename OutputIterator, typename Buffer, typename DegreeMap > - class bfs_rcm_visitor:public default_bfs_visitor + template < typename OutputIterator, typename Buffer, typename DegreeMap > + class bfs_rcm_visitor : public default_bfs_visitor { public: - bfs_rcm_visitor(OutputIterator *iter, Buffer *b, DegreeMap deg): - permutation(iter), Qptr(b), degree(deg) { } - template - void examine_vertex(Vertex u, Graph&) { - *(*permutation)++ = u; - index_begin = Qptr->size(); - } - template - void finish_vertex(Vertex, Graph&) { - using std::sort; - - typedef typename property_traits::value_type ds_type; - - typedef indirect_cmp > Compare; - Compare comp(degree); - - sort(Qptr->begin()+index_begin, Qptr->end(), comp); - } + bfs_rcm_visitor(OutputIterator* iter, Buffer* b, DegreeMap deg) + : permutation(iter), Qptr(b), degree(deg) + { + } + template < class Vertex, class Graph > + void examine_vertex(Vertex u, Graph&) + { + *(*permutation)++ = u; + index_begin = Qptr->size(); + } + template < class Vertex, class Graph > + void finish_vertex(Vertex, Graph&) + { + using std::sort; + + typedef typename property_traits< DegreeMap >::value_type ds_type; + + typedef indirect_cmp< DegreeMap, std::less< ds_type > > Compare; + Compare comp(degree); + + sort(Qptr->begin() + index_begin, Qptr->end(), comp); + } + protected: - OutputIterator *permutation; - int index_begin; - Buffer *Qptr; - DegreeMap degree; + OutputIterator* permutation; + int index_begin; + Buffer* Qptr; + DegreeMap degree; }; - } // namespace detail - - - // Reverse Cuthill-McKee algorithm with a given starting Vertex. - // - // If user provides a reverse iterator, this will be a reverse-cuthill-mckee - // algorithm, otherwise it will be a standard CM algorithm - - template - OutputIterator - cuthill_mckee_ordering(const Graph& g, - std::deque< typename - graph_traits::vertex_descriptor > vertex_queue, - OutputIterator permutation, - ColorMap color, DegreeMap degree) - { - - //create queue, visitor...don't forget namespaces! - typedef typename graph_traits::vertex_descriptor Vertex; - typedef typename boost::sparse::sparse_ordering_queue queue; - typedef typename detail::bfs_rcm_visitor Visitor; - typedef typename property_traits::value_type ColorValue; - typedef color_traits Color; +} // namespace detail +// Reverse Cuthill-McKee algorithm with a given starting Vertex. +// +// If user provides a reverse iterator, this will be a reverse-cuthill-mckee +// algorithm, otherwise it will be a standard CM algorithm + +template < class Graph, class OutputIterator, class ColorMap, class DegreeMap > +OutputIterator cuthill_mckee_ordering(const Graph& g, + std::deque< typename graph_traits< Graph >::vertex_descriptor > + vertex_queue, + OutputIterator permutation, ColorMap color, DegreeMap degree) +{ + + // create queue, visitor...don't forget namespaces! + typedef typename graph_traits< Graph >::vertex_descriptor Vertex; + typedef typename boost::sparse::sparse_ordering_queue< Vertex > queue; + typedef typename detail::bfs_rcm_visitor< OutputIterator, queue, DegreeMap > + Visitor; + typedef typename property_traits< ColorMap >::value_type ColorValue; + typedef color_traits< ColorValue > Color; queue Q; - //create a bfs_rcm_visitor as defined above - Visitor vis(&permutation, &Q, degree); + // create a bfs_rcm_visitor as defined above + Visitor vis(&permutation, &Q, degree); - typename graph_traits::vertex_iterator ui, ui_end; + typename graph_traits< Graph >::vertex_iterator ui, ui_end; // Copy degree to pseudo_degree // initialize the color map - for (boost::tie(ui, ui_end) = vertices(g); ui != ui_end; ++ui){ - put(color, *ui, Color::white()); + for (boost::tie(ui, ui_end) = vertices(g); ui != ui_end; ++ui) + { + put(color, *ui, Color::white()); } + while (!vertex_queue.empty()) + { + Vertex s = vertex_queue.front(); + vertex_queue.pop_front(); - while( !vertex_queue.empty() ) { - Vertex s = vertex_queue.front(); - vertex_queue.pop_front(); - - //call BFS with visitor - breadth_first_visit(g, s, Q, vis, color); + // call BFS with visitor + breadth_first_visit(g, s, Q, vis, color); } return permutation; - } - - - // This is the case where only a single starting vertex is supplied. - template - OutputIterator - cuthill_mckee_ordering(const Graph& g, - typename graph_traits::vertex_descriptor s, - OutputIterator permutation, - ColorMap color, DegreeMap degree) - { - - std::deque< typename graph_traits::vertex_descriptor > vertex_queue; - vertex_queue.push_front( s ); +} + +// This is the case where only a single starting vertex is supplied. +template < class Graph, class OutputIterator, class ColorMap, class DegreeMap > +OutputIterator cuthill_mckee_ordering(const Graph& g, + typename graph_traits< Graph >::vertex_descriptor s, + OutputIterator permutation, ColorMap color, DegreeMap degree) +{ + + std::deque< typename graph_traits< Graph >::vertex_descriptor > + vertex_queue; + vertex_queue.push_front(s); return cuthill_mckee_ordering(g, vertex_queue, permutation, color, degree); - - } - - - // This is the version of CM which selects its own starting vertex - template < class Graph, class OutputIterator, - class ColorMap, class DegreeMap> - OutputIterator - cuthill_mckee_ordering(const Graph& G, OutputIterator permutation, - ColorMap color, DegreeMap degree) - { +} + +// This is the version of CM which selects its own starting vertex +template < class Graph, class OutputIterator, class ColorMap, class DegreeMap > +OutputIterator cuthill_mckee_ordering(const Graph& G, + OutputIterator permutation, ColorMap color, DegreeMap degree) +{ if (boost::graph::has_no_vertices(G)) - return permutation; + return permutation; - typedef typename boost::graph_traits::vertex_descriptor Vertex; - typedef typename property_traits::value_type ColorValue; - typedef color_traits Color; + typedef typename boost::graph_traits< Graph >::vertex_descriptor Vertex; + typedef typename property_traits< ColorMap >::value_type ColorValue; + typedef color_traits< ColorValue > Color; - std::deque vertex_queue; + std::deque< Vertex > vertex_queue; // Mark everything white BGL_FORALL_VERTICES_T(v, G, Graph) put(color, v, Color::white()); - // Find one vertex from each connected component - BGL_FORALL_VERTICES_T(v, G, Graph) { - if (get(color, v) == Color::white()) { - depth_first_visit(G, v, dfs_visitor<>(), color); - vertex_queue.push_back(v); - } + // Find one vertex from each connected component + BGL_FORALL_VERTICES_T(v, G, Graph) + { + if (get(color, v) == Color::white()) + { + depth_first_visit(G, v, dfs_visitor<>(), color); + vertex_queue.push_back(v); + } } // Find starting nodes for all vertices // TBD: How to do this with a directed graph? - for (typename std::deque::iterator i = vertex_queue.begin(); + for (typename std::deque< Vertex >::iterator i = vertex_queue.begin(); i != vertex_queue.end(); ++i) - *i = find_starting_node(G, *i, color, degree); - - return cuthill_mckee_ordering(G, vertex_queue, permutation, - color, degree); - } - - template - OutputIterator - cuthill_mckee_ordering(const Graph& G, OutputIterator permutation, - VertexIndexMap index_map) - { + *i = find_starting_node(G, *i, color, degree); + + return cuthill_mckee_ordering(G, vertex_queue, permutation, color, degree); +} + +template < typename Graph, typename OutputIterator, typename VertexIndexMap > +OutputIterator cuthill_mckee_ordering( + const Graph& G, OutputIterator permutation, VertexIndexMap index_map) +{ if (boost::graph::has_no_vertices(G)) - return permutation; - - std::vector colors(num_vertices(G)); - return cuthill_mckee_ordering(G, permutation, - make_iterator_property_map(&colors[0], - index_map, - colors[0]), - make_out_degree_map(G)); - } - - template - inline OutputIterator - cuthill_mckee_ordering(const Graph& G, OutputIterator permutation) - { return cuthill_mckee_ordering(G, permutation, get(vertex_index, G)); } + return permutation; + + std::vector< default_color_type > colors(num_vertices(G)); + return cuthill_mckee_ordering(G, permutation, + make_iterator_property_map(&colors[0], index_map, colors[0]), + make_out_degree_map(G)); +} + +template < typename Graph, typename OutputIterator > +inline OutputIterator cuthill_mckee_ordering( + const Graph& G, OutputIterator permutation) +{ + return cuthill_mckee_ordering(G, permutation, get(vertex_index, G)); +} } // namespace boost - #endif // BOOST_GRAPH_CUTHILL_MCKEE_HPP diff --git a/include/boost/graph/cycle_canceling.hpp b/include/boost/graph/cycle_canceling.hpp index bc7e69099..5aaa25e75 100644 --- a/include/boost/graph/cycle_canceling.hpp +++ b/include/boost/graph/cycle_canceling.hpp @@ -8,7 +8,8 @@ //======================================================================= // // -//This algorithm is described in "Network Flows: Theory, Algorithms, and Applications" +// This algorithm is described in "Network Flows: Theory, Algorithms, and +// Applications" // by Ahuja, Magnanti, Orlin. #ifndef BOOST_GRAPH_CYCLE_CANCELING_HPP @@ -25,155 +26,166 @@ #include #include -namespace boost { +namespace boost +{ +namespace detail +{ -namespace detail { + template < typename PredEdgeMap, typename Vertex > + class RecordEdgeMapAndCycleVertex + : public bellman_visitor< + edge_predecessor_recorder< PredEdgeMap, on_edge_relaxed > > + { + typedef edge_predecessor_recorder< PredEdgeMap, on_edge_relaxed > + PredRec; -template -class RecordEdgeMapAndCycleVertex - : public bellman_visitor > { - typedef edge_predecessor_recorder PredRec; -public: - RecordEdgeMapAndCycleVertex(PredEdgeMap pred, Vertex & v) : - bellman_visitor(PredRec(pred)), m_v(v), m_pred(pred) {} - - template - void edge_not_minimized(Edge e, const Graph & g) const { - typename graph_traits::vertices_size_type n = num_vertices(g) + 1; + public: + RecordEdgeMapAndCycleVertex(PredEdgeMap pred, Vertex& v) + : bellman_visitor< PredRec >(PredRec(pred)), m_v(v), m_pred(pred) + { + } - //edge e is not minimized but does not have to be on the negative weight cycle - //to find vertex on negative wieight cycle we move n+1 times backword in the PredEdgeMap graph. - while(n > 0) { - e = get(m_pred, source(e, g)); - --n; + template < typename Graph, typename Edge > + void edge_not_minimized(Edge e, const Graph& g) const + { + typename graph_traits< Graph >::vertices_size_type n + = num_vertices(g) + 1; + + // edge e is not minimized but does not have to be on the negative + // weight cycle to find vertex on negative wieight cycle we move n+1 + // times backword in the PredEdgeMap graph. + while (n > 0) + { + e = get(m_pred, source(e, g)); + --n; + } + m_v = source(e, g); } - m_v = source(e, g); - } -private: - Vertex & m_v; - PredEdgeMap m_pred; -}; -} //detail + private: + Vertex& m_v; + PredEdgeMap m_pred; + }; +} // detail -template -void cycle_canceling(const Graph &g, Weight weight, Reversed rev, ResidualCapacity residual_capacity, Pred pred, Distance distance) { - typedef filtered_graph > ResGraph; +template < class Graph, class Pred, class Distance, class Reversed, + class ResidualCapacity, class Weight > +void cycle_canceling(const Graph& g, Weight weight, Reversed rev, + ResidualCapacity residual_capacity, Pred pred, Distance distance) +{ + typedef filtered_graph< const Graph, is_residual_edge< ResidualCapacity > > + ResGraph; ResGraph gres = detail::residual_graph(g, residual_capacity); - typedef graph_traits ResGTraits; - typedef graph_traits GTraits; + typedef graph_traits< ResGraph > ResGTraits; + typedef graph_traits< Graph > GTraits; typedef typename ResGTraits::edge_descriptor edge_descriptor; typedef typename ResGTraits::vertex_descriptor vertex_descriptor; typename GTraits::vertices_size_type N = num_vertices(g); - BGL_FORALL_VERTICES_T(v, g, Graph) { + BGL_FORALL_VERTICES_T(v, g, Graph) + { put(pred, v, edge_descriptor()); put(distance, v, 0); } vertex_descriptor cycleStart; - while(!bellman_ford_shortest_paths(gres, N, - weight_map(weight). - distance_map(distance). - visitor(detail::RecordEdgeMapAndCycleVertex(pred, cycleStart)))) { + while (!bellman_ford_shortest_paths(gres, N, + weight_map(weight).distance_map(distance).visitor( + detail::RecordEdgeMapAndCycleVertex< Pred, vertex_descriptor >( + pred, cycleStart)))) + { - detail::augment(g, cycleStart, cycleStart, pred, residual_capacity, rev); + detail::augment( + g, cycleStart, cycleStart, pred, residual_capacity, rev); - BGL_FORALL_VERTICES_T(v, g, Graph) { + BGL_FORALL_VERTICES_T(v, g, Graph) + { put(pred, v, edge_descriptor()); put(distance, v, 0); } } } +// in this namespace argument dispatching takes place +namespace detail +{ + + template < class Graph, class P, class T, class R, class ResidualCapacity, + class Weight, class Reversed, class Pred, class Distance > + void cycle_canceling_dispatch2(const Graph& g, Weight weight, Reversed rev, + ResidualCapacity residual_capacity, Pred pred, Distance dist, + const bgl_named_params< P, T, R >& params) + { + cycle_canceling(g, weight, rev, residual_capacity, pred, dist); + } -//in this namespace argument dispatching takes place -namespace detail { - -template -void cycle_canceling_dispatch2( - const Graph &g, - Weight weight, - Reversed rev, - ResidualCapacity residual_capacity, - Pred pred, - Distance dist, - const bgl_named_params& params) { - cycle_canceling(g, weight, rev, residual_capacity, pred, dist); -} - -//setting default distance map -template -void cycle_canceling_dispatch2( - Graph &g, - Weight weight, - Reversed rev, - ResidualCapacity residual_capacity, - Pred pred, - param_not_found, - const bgl_named_params& params) { - typedef typename property_traits::value_type D; - - std::vector d_map(num_vertices(g)); - - cycle_canceling(g, weight, rev, residual_capacity, pred, - make_iterator_property_map(d_map.begin(), choose_const_pmap(get_param(params, vertex_index), g, vertex_index))); -} + // setting default distance map + template < class Graph, class P, class T, class R, class Pred, + class ResidualCapacity, class Weight, class Reversed > + void cycle_canceling_dispatch2(Graph& g, Weight weight, Reversed rev, + ResidualCapacity residual_capacity, Pred pred, param_not_found, + const bgl_named_params< P, T, R >& params) + { + typedef typename property_traits< Weight >::value_type D; + + std::vector< D > d_map(num_vertices(g)); + + cycle_canceling(g, weight, rev, residual_capacity, pred, + make_iterator_property_map(d_map.begin(), + choose_const_pmap( + get_param(params, vertex_index), g, vertex_index))); + } -template -void cycle_canceling_dispatch1( - Graph &g, - Weight weight, - Reversed rev, - ResidualCapacity residual_capacity, - Pred pred, - const bgl_named_params& params) { - cycle_canceling_dispatch2(g, weight, rev,residual_capacity, pred, - get_param(params, vertex_distance), params); -} + template < class Graph, class P, class T, class R, class ResidualCapacity, + class Weight, class Reversed, class Pred > + void cycle_canceling_dispatch1(Graph& g, Weight weight, Reversed rev, + ResidualCapacity residual_capacity, Pred pred, + const bgl_named_params< P, T, R >& params) + { + cycle_canceling_dispatch2(g, weight, rev, residual_capacity, pred, + get_param(params, vertex_distance), params); + } -//setting default predecessors map -template -void cycle_canceling_dispatch1( - Graph &g, - Weight weight, - Reversed rev, - ResidualCapacity residual_capacity, - param_not_found, - const bgl_named_params& params) { - typedef typename graph_traits::edge_descriptor edge_descriptor; - std::vector p_map(num_vertices(g)); - - cycle_canceling_dispatch2(g, weight, rev, residual_capacity, - make_iterator_property_map(p_map.begin(), choose_const_pmap(get_param(params, vertex_index), g, vertex_index)), - get_param(params, vertex_distance), params); -} + // setting default predecessors map + template < class Graph, class P, class T, class R, class ResidualCapacity, + class Weight, class Reversed > + void cycle_canceling_dispatch1(Graph& g, Weight weight, Reversed rev, + ResidualCapacity residual_capacity, param_not_found, + const bgl_named_params< P, T, R >& params) + { + typedef typename graph_traits< Graph >::edge_descriptor edge_descriptor; + std::vector< edge_descriptor > p_map(num_vertices(g)); + + cycle_canceling_dispatch2(g, weight, rev, residual_capacity, + make_iterator_property_map(p_map.begin(), + choose_const_pmap( + get_param(params, vertex_index), g, vertex_index)), + get_param(params, vertex_distance), params); + } -}//detail +} // detail -template -void cycle_canceling(Graph &g, - const bgl_named_params& params) { +template < class Graph, class P, class T, class R > +void cycle_canceling(Graph& g, const bgl_named_params< P, T, R >& params) +{ cycle_canceling_dispatch1(g, - choose_const_pmap(get_param(params, edge_weight), g, edge_weight), - choose_const_pmap(get_param(params, edge_reverse), g, edge_reverse), - choose_pmap(get_param(params, edge_residual_capacity), - g, edge_residual_capacity), - get_param(params, vertex_predecessor), - params); + choose_const_pmap(get_param(params, edge_weight), g, edge_weight), + choose_const_pmap(get_param(params, edge_reverse), g, edge_reverse), + choose_pmap(get_param(params, edge_residual_capacity), g, + edge_residual_capacity), + get_param(params, vertex_predecessor), params); } -template -void cycle_canceling(Graph &g) { - bgl_named_params params(0); +template < class Graph > void cycle_canceling(Graph& g) +{ + bgl_named_params< int, buffer_param_t > params(0); cycle_canceling(g, params); } - } #endif /* BOOST_GRAPH_CYCLE_CANCELING_HPP */ diff --git a/include/boost/graph/dag_shortest_paths.hpp b/include/boost/graph/dag_shortest_paths.hpp index 325d1516c..a0aecc169 100644 --- a/include/boost/graph/dag_shortest_paths.hpp +++ b/include/boost/graph/dag_shortest_paths.hpp @@ -15,25 +15,21 @@ // single-source shortest paths for a Directed Acyclic Graph (DAG) -namespace boost { - - // Initalize distances and call depth first search - template - inline void - dag_shortest_paths - (const VertexListGraph& g, - typename graph_traits::vertex_descriptor s, - DistanceMap distance, WeightMap weight, ColorMap color, - PredecessorMap pred, - DijkstraVisitor vis, Compare compare, Combine combine, - DistInf inf, DistZero zero) - { - typedef typename graph_traits::vertex_descriptor Vertex; - std::vector rev_topo_order; +namespace boost +{ + +// Initalize distances and call depth first search +template < class VertexListGraph, class DijkstraVisitor, class DistanceMap, + class WeightMap, class ColorMap, class PredecessorMap, class Compare, + class Combine, class DistInf, class DistZero > +inline void dag_shortest_paths(const VertexListGraph& g, + typename graph_traits< VertexListGraph >::vertex_descriptor s, + DistanceMap distance, WeightMap weight, ColorMap color, PredecessorMap pred, + DijkstraVisitor vis, Compare compare, Combine combine, DistInf inf, + DistZero zero) +{ + typedef typename graph_traits< VertexListGraph >::vertex_descriptor Vertex; + std::vector< Vertex > rev_topo_order; rev_topo_order.reserve(num_vertices(g)); // Call 'depth_first_visit', not 'topological_sort', because we don't @@ -41,119 +37,109 @@ namespace boost { // and 'topological_sort' will traverse everything. The logic below // is the same as for 'topological_sort', only we call 'depth_first_visit' // and 'topological_sort' calls 'depth_first_search'. - topo_sort_visitor > > + topo_sort_visitor< std::back_insert_iterator< std::vector< Vertex > > > topo_visitor(std::back_inserter(rev_topo_order)); depth_first_visit(g, s, topo_visitor, color); - typename graph_traits::vertex_iterator ui, ui_end; - for (boost::tie(ui, ui_end) = vertices(g); ui != ui_end; ++ui) { - put(distance, *ui, inf); - put(pred, *ui, *ui); + typename graph_traits< VertexListGraph >::vertex_iterator ui, ui_end; + for (boost::tie(ui, ui_end) = vertices(g); ui != ui_end; ++ui) + { + put(distance, *ui, inf); + put(pred, *ui, *ui); } put(distance, s, zero); vis.discover_vertex(s, g); - typename std::vector::reverse_iterator i; - for (i = rev_topo_order.rbegin(); i != rev_topo_order.rend(); ++i) { - Vertex u = *i; - vis.examine_vertex(u, g); - typename graph_traits::out_edge_iterator e, e_end; - for (boost::tie(e, e_end) = out_edges(u, g); e != e_end; ++e) { - vis.discover_vertex(target(*e, g), g); - bool decreased = relax(*e, g, weight, pred, distance, - combine, compare); - if (decreased) - vis.edge_relaxed(*e, g); - else - vis.edge_not_relaxed(*e, g); - } - vis.finish_vertex(u, g); + typename std::vector< Vertex >::reverse_iterator i; + for (i = rev_topo_order.rbegin(); i != rev_topo_order.rend(); ++i) + { + Vertex u = *i; + vis.examine_vertex(u, g); + typename graph_traits< VertexListGraph >::out_edge_iterator e, e_end; + for (boost::tie(e, e_end) = out_edges(u, g); e != e_end; ++e) + { + vis.discover_vertex(target(*e, g), g); + bool decreased + = relax(*e, g, weight, pred, distance, combine, compare); + if (decreased) + vis.edge_relaxed(*e, g); + else + vis.edge_not_relaxed(*e, g); + } + vis.finish_vertex(u, g); } - } +} - namespace detail { +namespace detail +{ // Defaults are the same as Dijkstra's algorithm // Handle Distance Compare, Combine, Inf and Zero defaults - template - inline void - dag_sp_dispatch2 - (const VertexListGraph& g, - typename graph_traits::vertex_descriptor s, - DistanceMap distance, WeightMap weight, ColorMap color, IndexMap /*id*/, - DijkstraVisitor vis, const Params& params) + template < class VertexListGraph, class DijkstraVisitor, class DistanceMap, + class WeightMap, class ColorMap, class IndexMap, class Params > + inline void dag_sp_dispatch2(const VertexListGraph& g, + typename graph_traits< VertexListGraph >::vertex_descriptor s, + DistanceMap distance, WeightMap weight, ColorMap color, IndexMap /*id*/, + DijkstraVisitor vis, const Params& params) { - typedef typename property_traits::value_type D; - dummy_property_map p_map; - D inf = - choose_param(get_param(params, distance_inf_t()), - (std::numeric_limits::max)()); - dag_shortest_paths - (g, s, distance, weight, color, - choose_param(get_param(params, vertex_predecessor), p_map), - vis, - choose_param(get_param(params, distance_compare_t()), std::less()), - choose_param(get_param(params, distance_combine_t()), closed_plus(inf)), - inf, - choose_param(get_param(params, distance_zero_t()), - D())); + typedef typename property_traits< DistanceMap >::value_type D; + dummy_property_map p_map; + D inf = choose_param(get_param(params, distance_inf_t()), + (std::numeric_limits< D >::max)()); + dag_shortest_paths(g, s, distance, weight, color, + choose_param(get_param(params, vertex_predecessor), p_map), vis, + choose_param( + get_param(params, distance_compare_t()), std::less< D >()), + choose_param( + get_param(params, distance_combine_t()), closed_plus< D >(inf)), + inf, choose_param(get_param(params, distance_zero_t()), D())); } // Handle DistanceMap and ColorMap defaults - template - inline void - dag_sp_dispatch1 - (const VertexListGraph& g, - typename graph_traits::vertex_descriptor s, - DistanceMap distance, WeightMap weight, ColorMap color, IndexMap id, - DijkstraVisitor vis, const Params& params) + template < class VertexListGraph, class DijkstraVisitor, class DistanceMap, + class WeightMap, class ColorMap, class IndexMap, class Params > + inline void dag_sp_dispatch1(const VertexListGraph& g, + typename graph_traits< VertexListGraph >::vertex_descriptor s, + DistanceMap distance, WeightMap weight, ColorMap color, IndexMap id, + DijkstraVisitor vis, const Params& params) { - typedef typename property_traits::value_type T; - typename std::vector::size_type n; - n = is_default_param(distance) ? num_vertices(g) : 1; - std::vector distance_map(n); - n = is_default_param(color) ? num_vertices(g) : 1; - std::vector color_map(n); - - dag_sp_dispatch2 - (g, s, - choose_param(distance, - make_iterator_property_map(distance_map.begin(), id, - distance_map[0])), - weight, - choose_param(color, - make_iterator_property_map(color_map.begin(), id, - color_map[0])), - id, vis, params); + typedef typename property_traits< WeightMap >::value_type T; + typename std::vector< T >::size_type n; + n = is_default_param(distance) ? num_vertices(g) : 1; + std::vector< T > distance_map(n); + n = is_default_param(color) ? num_vertices(g) : 1; + std::vector< default_color_type > color_map(n); + + dag_sp_dispatch2(g, s, + choose_param(distance, + make_iterator_property_map( + distance_map.begin(), id, distance_map[0])), + weight, + choose_param(color, + make_iterator_property_map( + color_map.begin(), id, color_map[0])), + id, vis, params); } - - } // namespace detail - - template - inline void - dag_shortest_paths - (const VertexListGraph& g, - typename graph_traits::vertex_descriptor s, - const bgl_named_params& params) - { + +} // namespace detail + +template < class VertexListGraph, class Param, class Tag, class Rest > +inline void dag_shortest_paths(const VertexListGraph& g, + typename graph_traits< VertexListGraph >::vertex_descriptor s, + const bgl_named_params< Param, Tag, Rest >& params) +{ // assert that the graph is directed... null_visitor null_vis; - detail::dag_sp_dispatch1 - (g, s, - get_param(params, vertex_distance), - choose_const_pmap(get_param(params, edge_weight), g, edge_weight), - get_param(params, vertex_color), - choose_const_pmap(get_param(params, vertex_index), g, vertex_index), - choose_param(get_param(params, graph_visitor), - make_dijkstra_visitor(null_vis)), - params); - } - + detail::dag_sp_dispatch1(g, s, get_param(params, vertex_distance), + choose_const_pmap(get_param(params, edge_weight), g, edge_weight), + get_param(params, vertex_color), + choose_const_pmap(get_param(params, vertex_index), g, vertex_index), + choose_param( + get_param(params, graph_visitor), make_dijkstra_visitor(null_vis)), + params); +} + } // namespace boost #endif // BOOST_GRAPH_DAG_SHORTEST_PATHS_HPP diff --git a/include/boost/graph/degree_centrality.hpp b/include/boost/graph/degree_centrality.hpp index f6cc7a22f..6db11b95e 100644 --- a/include/boost/graph/degree_centrality.hpp +++ b/include/boost/graph/degree_centrality.hpp @@ -10,122 +10,126 @@ #include #include -namespace boost { +namespace boost +{ -template -struct degree_centrality_measure +template < typename Graph > struct degree_centrality_measure { - typedef typename graph_traits::degree_size_type degree_type; - typedef typename graph_traits::vertex_descriptor vertex_type; + typedef typename graph_traits< Graph >::degree_size_type degree_type; + typedef typename graph_traits< Graph >::vertex_descriptor vertex_type; }; -template -struct influence_measure - : public degree_centrality_measure +template < typename Graph > +struct influence_measure : public degree_centrality_measure< Graph > { - typedef degree_centrality_measure base_type; + typedef degree_centrality_measure< Graph > base_type; typedef typename base_type::degree_type degree_type; typedef typename base_type::vertex_type vertex_type; - inline degree_type operator ()(vertex_type v, const Graph& g) + inline degree_type operator()(vertex_type v, const Graph& g) { - BOOST_CONCEPT_ASSERT(( IncidenceGraphConcept )); + BOOST_CONCEPT_ASSERT((IncidenceGraphConcept< Graph >)); return out_degree(v, g); } }; -template -inline influence_measure -measure_influence(const Graph&) -{ return influence_measure(); } - +template < typename Graph > +inline influence_measure< Graph > measure_influence(const Graph&) +{ + return influence_measure< Graph >(); +} -template -struct prestige_measure - : public degree_centrality_measure +template < typename Graph > +struct prestige_measure : public degree_centrality_measure< Graph > { - typedef degree_centrality_measure base_type; + typedef degree_centrality_measure< Graph > base_type; typedef typename base_type::degree_type degree_type; typedef typename base_type::vertex_type vertex_type; - inline degree_type operator ()(vertex_type v, const Graph& g) + inline degree_type operator()(vertex_type v, const Graph& g) { - BOOST_CONCEPT_ASSERT(( BidirectionalGraphConcept )); + BOOST_CONCEPT_ASSERT((BidirectionalGraphConcept< Graph >)); return in_degree(v, g); } }; -template -inline prestige_measure -measure_prestige(const Graph&) -{ return prestige_measure(); } - +template < typename Graph > +inline prestige_measure< Graph > measure_prestige(const Graph&) +{ + return prestige_measure< Graph >(); +} -template -inline typename Measure::degree_type -degree_centrality(const Graph& g, Vertex v, Measure measure) +template < typename Graph, typename Vertex, typename Measure > +inline typename Measure::degree_type degree_centrality( + const Graph& g, Vertex v, Measure measure) { - BOOST_CONCEPT_ASSERT(( DegreeMeasureConcept )); + BOOST_CONCEPT_ASSERT((DegreeMeasureConcept< Measure, Graph >)); return measure(v, g); } -template -inline typename graph_traits::degree_size_type -degree_centrality(const Graph& g, Vertex v) +template < typename Graph, typename Vertex > +inline typename graph_traits< Graph >::degree_size_type degree_centrality( + const Graph& g, Vertex v) { return degree_centrality(g, v, measure_influence(g)); } - // These are alias functions, intended to provide a more expressive interface. -template -inline typename graph_traits::degree_size_type -influence(const Graph& g, Vertex v) -{ return degree_centrality(g, v, measure_influence(g)); } - - -template -inline typename graph_traits::degree_size_type -prestige(const Graph& g, Vertex v) -{ return degree_centrality(g, v, measure_prestige(g)); } +template < typename Graph, typename Vertex > +inline typename graph_traits< Graph >::degree_size_type influence( + const Graph& g, Vertex v) +{ + return degree_centrality(g, v, measure_influence(g)); +} +template < typename Graph, typename Vertex > +inline typename graph_traits< Graph >::degree_size_type prestige( + const Graph& g, Vertex v) +{ + return degree_centrality(g, v, measure_prestige(g)); +} -template -inline void -all_degree_centralities(const Graph& g, CentralityMap cent, Measure measure) +template < typename Graph, typename CentralityMap, typename Measure > +inline void all_degree_centralities( + const Graph& g, CentralityMap cent, Measure measure) { - BOOST_CONCEPT_ASSERT(( VertexListGraphConcept )); - typedef typename graph_traits::vertex_descriptor Vertex; - typedef typename graph_traits::vertex_iterator VertexIterator; - BOOST_CONCEPT_ASSERT(( WritablePropertyMapConcept )); - typedef typename property_traits::value_type Centrality; + BOOST_CONCEPT_ASSERT((VertexListGraphConcept< Graph >)); + typedef typename graph_traits< Graph >::vertex_descriptor Vertex; + typedef typename graph_traits< Graph >::vertex_iterator VertexIterator; + BOOST_CONCEPT_ASSERT((WritablePropertyMapConcept< CentralityMap, Vertex >)); + typedef typename property_traits< CentralityMap >::value_type Centrality; VertexIterator i, end; - for(boost::tie(i, end) = vertices(g); i != end; ++i) { + for (boost::tie(i, end) = vertices(g); i != end; ++i) + { Centrality c = degree_centrality(g, *i, measure); put(cent, *i, c); } } -template +template < typename Graph, typename CentralityMap > inline void all_degree_centralities(const Graph& g, CentralityMap cent) -{ all_degree_centralities(g, cent, measure_influence(g)); } +{ + all_degree_centralities(g, cent, measure_influence(g)); +} // More helper functions for computing influence and prestige. // I hate the names of these functions, but influence and prestige // don't pluralize too well. -template +template < typename Graph, typename CentralityMap > inline void all_influence_values(const Graph& g, CentralityMap cent) -{ all_degree_centralities(g, cent, measure_influence(g)); } +{ + all_degree_centralities(g, cent, measure_influence(g)); +} -template +template < typename Graph, typename CentralityMap > inline void all_prestige_values(const Graph& g, CentralityMap cent) -{ all_degree_centralities(g, cent, measure_prestige(g)); } +{ + all_degree_centralities(g, cent, measure_prestige(g)); +} } /* namespace boost */ #endif - - diff --git a/include/boost/graph/depth_first_search.hpp b/include/boost/graph/depth_first_search.hpp index 0a29de1da..607a6f611 100644 --- a/include/boost/graph/depth_first_search.hpp +++ b/include/boost/graph/depth_first_search.hpp @@ -30,65 +30,80 @@ #include #include -namespace boost { - - template - class DFSVisitorConcept { - public: - void constraints() { - BOOST_CONCEPT_ASSERT(( CopyConstructibleConcept )); - vis.initialize_vertex(u, g); - vis.start_vertex(u, g); - vis.discover_vertex(u, g); - vis.examine_edge(e, g); - vis.tree_edge(e, g); - vis.back_edge(e, g); - vis.forward_or_cross_edge(e, g); - // vis.finish_edge(e, g); // Optional for user - vis.finish_vertex(u, g); +namespace boost +{ + +template < class Visitor, class Graph > class DFSVisitorConcept +{ +public: + void constraints() + { + BOOST_CONCEPT_ASSERT((CopyConstructibleConcept< Visitor >)); + vis.initialize_vertex(u, g); + vis.start_vertex(u, g); + vis.discover_vertex(u, g); + vis.examine_edge(e, g); + vis.tree_edge(e, g); + vis.back_edge(e, g); + vis.forward_or_cross_edge(e, g); + // vis.finish_edge(e, g); // Optional for user + vis.finish_vertex(u, g); } - private: + +private: Visitor vis; Graph g; - typename graph_traits::vertex_descriptor u; - typename graph_traits::edge_descriptor e; - }; + typename graph_traits< Graph >::vertex_descriptor u; + typename graph_traits< Graph >::edge_descriptor e; +}; - namespace detail { +namespace detail +{ - struct nontruth2 { - template - bool operator()(const T&, const T2&) const { return false; } + struct nontruth2 + { + template < class T, class T2 > + bool operator()(const T&, const T2&) const + { + return false; + } }; BOOST_TTI_HAS_MEMBER_FUNCTION(finish_edge) - template struct do_call_finish_edge { - template - static void call_finish_edge(Vis& vis, E e, const G& g) { - vis.finish_edge(e, g); - } + template < bool IsCallable > struct do_call_finish_edge + { + template < typename E, typename G, typename Vis > + static void call_finish_edge(Vis& vis, E e, const G& g) + { + vis.finish_edge(e, g); + } }; - template <> struct do_call_finish_edge { - template - static void call_finish_edge(Vis&, E, const G&) {} + template <> struct do_call_finish_edge< false > + { + template < typename E, typename G, typename Vis > + static void call_finish_edge(Vis&, E, const G&) + { + } }; - template - void call_finish_edge(Vis& vis, E e, const G& g) { // Only call if method exists -#if ((defined(__GNUC__) && (__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 9))) || \ - defined(__clang__) || \ - (defined(__INTEL_COMPILER) && (__INTEL_COMPILER >= 1200))) - do_call_finish_edge< - has_member_function_finish_edge >::value>::call_finish_edge(vis, e, g); + template < typename E, typename G, typename Vis > + void call_finish_edge(Vis& vis, E e, const G& g) + { // Only call if method exists +#if ((defined(__GNUC__) && (__GNUC__ > 4) \ + || ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 9))) \ + || defined(__clang__) \ + || (defined(__INTEL_COMPILER) && (__INTEL_COMPILER >= 1200))) + do_call_finish_edge< has_member_function_finish_edge< Vis, void, + boost::mpl::vector< E, const G& > >::value >::call_finish_edge(vis, + e, g); #else - do_call_finish_edge::value>::call_finish_edge(vis, e, g); + do_call_finish_edge< has_member_function_finish_edge< Vis, + void >::value >::call_finish_edge(vis, e, g); #endif } - // Define BOOST_RECURSIVE_DFS to use older, recursive version. // It is retained for a while in order to perform performance // comparison. @@ -105,268 +120,314 @@ namespace boost { // // See https://lists.boost.org/Archives/boost/2003/06/49265.php for FAQ. - template - void depth_first_visit_impl - (const IncidenceGraph& g, - typename graph_traits::vertex_descriptor u, - DFSVisitor& vis, - ColorMap color, TerminatorFunc func = TerminatorFunc()) + template < class IncidenceGraph, class DFSVisitor, class ColorMap, + class TerminatorFunc > + void depth_first_visit_impl(const IncidenceGraph& g, + typename graph_traits< IncidenceGraph >::vertex_descriptor u, + DFSVisitor& vis, ColorMap color, TerminatorFunc func = TerminatorFunc()) { - BOOST_CONCEPT_ASSERT(( IncidenceGraphConcept )); - BOOST_CONCEPT_ASSERT(( DFSVisitorConcept )); - typedef typename graph_traits::vertex_descriptor Vertex; - typedef typename graph_traits::edge_descriptor Edge; - BOOST_CONCEPT_ASSERT(( ReadWritePropertyMapConcept )); - typedef typename property_traits::value_type ColorValue; - BOOST_CONCEPT_ASSERT(( ColorValueConcept )); - typedef color_traits Color; - typedef typename graph_traits::out_edge_iterator Iter; - typedef std::pair, std::pair > > VertexInfo; - - boost::optional src_e; - Iter ei, ei_end; - std::vector stack; - - // Possible optimization for vector - //stack.reserve(num_vertices(g)); - - put(color, u, Color::gray()); - vis.discover_vertex(u, g); - boost::tie(ei, ei_end) = out_edges(u, g); - if (func(u, g)) { - // If this vertex terminates the search, we push empty range - stack.push_back(std::make_pair(u, std::make_pair(boost::optional(), std::make_pair(ei_end, ei_end)))); - } else { - stack.push_back(std::make_pair(u, std::make_pair(boost::optional(), std::make_pair(ei, ei_end)))); - } - while (!stack.empty()) { - VertexInfo& back = stack.back(); - u = back.first; - src_e = back.second.first; - boost::tie(ei, ei_end) = back.second.second; - stack.pop_back(); - // finish_edge has to be called here, not after the - // loop. Think of the pop as the return from a recursive call. - if (src_e) { - call_finish_edge(vis, src_e.get(), g); - } - while (ei != ei_end) { - Vertex v = target(*ei, g); - vis.examine_edge(*ei, g); - ColorValue v_color = get(color, v); - if (v_color == Color::white()) { - vis.tree_edge(*ei, g); - src_e = *ei; - stack.push_back(std::make_pair(u, std::make_pair(src_e, std::make_pair(++ei, ei_end)))); - u = v; - put(color, u, Color::gray()); - vis.discover_vertex(u, g); - boost::tie(ei, ei_end) = out_edges(u, g); - if (func(u, g)) { - ei = ei_end; + BOOST_CONCEPT_ASSERT((IncidenceGraphConcept< IncidenceGraph >)); + BOOST_CONCEPT_ASSERT((DFSVisitorConcept< DFSVisitor, IncidenceGraph >)); + typedef + typename graph_traits< IncidenceGraph >::vertex_descriptor Vertex; + typedef typename graph_traits< IncidenceGraph >::edge_descriptor Edge; + BOOST_CONCEPT_ASSERT((ReadWritePropertyMapConcept< ColorMap, Vertex >)); + typedef typename property_traits< ColorMap >::value_type ColorValue; + BOOST_CONCEPT_ASSERT((ColorValueConcept< ColorValue >)); + typedef color_traits< ColorValue > Color; + typedef typename graph_traits< IncidenceGraph >::out_edge_iterator Iter; + typedef std::pair< Vertex, + std::pair< boost::optional< Edge >, std::pair< Iter, Iter > > > + VertexInfo; + + boost::optional< Edge > src_e; + Iter ei, ei_end; + std::vector< VertexInfo > stack; + + // Possible optimization for vector + // stack.reserve(num_vertices(g)); + + put(color, u, Color::gray()); + vis.discover_vertex(u, g); + boost::tie(ei, ei_end) = out_edges(u, g); + if (func(u, g)) + { + // If this vertex terminates the search, we push empty range + stack.push_back(std::make_pair(u, + std::make_pair(boost::optional< Edge >(), + std::make_pair(ei_end, ei_end)))); + } + else + { + stack.push_back(std::make_pair(u, + std::make_pair( + boost::optional< Edge >(), std::make_pair(ei, ei_end)))); + } + while (!stack.empty()) + { + VertexInfo& back = stack.back(); + u = back.first; + src_e = back.second.first; + boost::tie(ei, ei_end) = back.second.second; + stack.pop_back(); + // finish_edge has to be called here, not after the + // loop. Think of the pop as the return from a recursive call. + if (src_e) + { + call_finish_edge(vis, src_e.get(), g); } - } else { - if (v_color == Color::gray()) { - vis.back_edge(*ei, g); - } else { - vis.forward_or_cross_edge(*ei, g); + while (ei != ei_end) + { + Vertex v = target(*ei, g); + vis.examine_edge(*ei, g); + ColorValue v_color = get(color, v); + if (v_color == Color::white()) + { + vis.tree_edge(*ei, g); + src_e = *ei; + stack.push_back(std::make_pair(u, + std::make_pair(src_e, std::make_pair(++ei, ei_end)))); + u = v; + put(color, u, Color::gray()); + vis.discover_vertex(u, g); + boost::tie(ei, ei_end) = out_edges(u, g); + if (func(u, g)) + { + ei = ei_end; + } + } + else + { + if (v_color == Color::gray()) + { + vis.back_edge(*ei, g); + } + else + { + vis.forward_or_cross_edge(*ei, g); + } + call_finish_edge(vis, *ei, g); + ++ei; + } } - call_finish_edge(vis, *ei, g); - ++ei; - } + put(color, u, Color::black()); + vis.finish_vertex(u, g); } - put(color, u, Color::black()); - vis.finish_vertex(u, g); - } } #else // BOOST_RECURSIVE_DFS is defined - template - void depth_first_visit_impl - (const IncidenceGraph& g, - typename graph_traits::vertex_descriptor u, - DFSVisitor& vis, // pass-by-reference here, important! - ColorMap color, TerminatorFunc func) + template < class IncidenceGraph, class DFSVisitor, class ColorMap, + class TerminatorFunc > + void depth_first_visit_impl(const IncidenceGraph& g, + typename graph_traits< IncidenceGraph >::vertex_descriptor u, + DFSVisitor& vis, // pass-by-reference here, important! + ColorMap color, TerminatorFunc func) { - BOOST_CONCEPT_ASSERT(( IncidenceGraphConcept )); - BOOST_CONCEPT_ASSERT(( DFSVisitorConcept )); - typedef typename graph_traits::vertex_descriptor Vertex; - BOOST_CONCEPT_ASSERT(( ReadWritePropertyMapConcept )); - typedef typename property_traits::value_type ColorValue; - BOOST_CONCEPT_ASSERT(( ColorValueConcept )); - typedef color_traits Color; - typename graph_traits::out_edge_iterator ei, ei_end; - - put(color, u, Color::gray()); vis.discover_vertex(u, g); - - if (!func(u, g)) - for (boost::tie(ei, ei_end) = out_edges(u, g); ei != ei_end; ++ei) { - Vertex v = target(*ei, g); vis.examine_edge(*ei, g); - ColorValue v_color = get(color, v); - if (v_color == Color::white()) { vis.tree_edge(*ei, g); - depth_first_visit_impl(g, v, vis, color, func); - } else if (v_color == Color::gray()) vis.back_edge(*ei, g); - else vis.forward_or_cross_edge(*ei, g); - call_finish_edge(vis, *ei, g); - } - put(color, u, Color::black()); vis.finish_vertex(u, g); + BOOST_CONCEPT_ASSERT((IncidenceGraphConcept< IncidenceGraph >)); + BOOST_CONCEPT_ASSERT((DFSVisitorConcept< DFSVisitor, IncidenceGraph >)); + typedef + typename graph_traits< IncidenceGraph >::vertex_descriptor Vertex; + BOOST_CONCEPT_ASSERT((ReadWritePropertyMapConcept< ColorMap, Vertex >)); + typedef typename property_traits< ColorMap >::value_type ColorValue; + BOOST_CONCEPT_ASSERT((ColorValueConcept< ColorValue >)); + typedef color_traits< ColorValue > Color; + typename graph_traits< IncidenceGraph >::out_edge_iterator ei, ei_end; + + put(color, u, Color::gray()); + vis.discover_vertex(u, g); + + if (!func(u, g)) + for (boost::tie(ei, ei_end) = out_edges(u, g); ei != ei_end; ++ei) + { + Vertex v = target(*ei, g); + vis.examine_edge(*ei, g); + ColorValue v_color = get(color, v); + if (v_color == Color::white()) + { + vis.tree_edge(*ei, g); + depth_first_visit_impl(g, v, vis, color, func); + } + else if (v_color == Color::gray()) + vis.back_edge(*ei, g); + else + vis.forward_or_cross_edge(*ei, g); + call_finish_edge(vis, *ei, g); + } + put(color, u, Color::black()); + vis.finish_vertex(u, g); } #endif - } // namespace detail - - template - void - depth_first_search(const VertexListGraph& g, DFSVisitor vis, ColorMap color, - typename graph_traits::vertex_descriptor start_vertex) - { - typedef typename graph_traits::vertex_descriptor Vertex; - BOOST_CONCEPT_ASSERT(( DFSVisitorConcept )); - typedef typename property_traits::value_type ColorValue; - typedef color_traits Color; - - typename graph_traits::vertex_iterator ui, ui_end; - for (boost::tie(ui, ui_end) = vertices(g); ui != ui_end; ++ui) { - Vertex u = implicit_cast(*ui); - put(color, u, Color::white()); vis.initialize_vertex(u, g); +} // namespace detail + +template < class VertexListGraph, class DFSVisitor, class ColorMap > +void depth_first_search(const VertexListGraph& g, DFSVisitor vis, + ColorMap color, + typename graph_traits< VertexListGraph >::vertex_descriptor start_vertex) +{ + typedef typename graph_traits< VertexListGraph >::vertex_descriptor Vertex; + BOOST_CONCEPT_ASSERT((DFSVisitorConcept< DFSVisitor, VertexListGraph >)); + typedef typename property_traits< ColorMap >::value_type ColorValue; + typedef color_traits< ColorValue > Color; + + typename graph_traits< VertexListGraph >::vertex_iterator ui, ui_end; + for (boost::tie(ui, ui_end) = vertices(g); ui != ui_end; ++ui) + { + Vertex u = implicit_cast< Vertex >(*ui); + put(color, u, Color::white()); + vis.initialize_vertex(u, g); } - if (start_vertex != detail::get_default_starting_vertex(g)){ vis.start_vertex(start_vertex, g); - detail::depth_first_visit_impl(g, start_vertex, vis, color, - detail::nontruth2()); + if (start_vertex != detail::get_default_starting_vertex(g)) + { + vis.start_vertex(start_vertex, g); + detail::depth_first_visit_impl( + g, start_vertex, vis, color, detail::nontruth2()); } - for (boost::tie(ui, ui_end) = vertices(g); ui != ui_end; ++ui) { - Vertex u = implicit_cast(*ui); - ColorValue u_color = get(color, u); - if (u_color == Color::white()) { vis.start_vertex(u, g); - detail::depth_first_visit_impl(g, u, vis, color, detail::nontruth2()); - } + for (boost::tie(ui, ui_end) = vertices(g); ui != ui_end; ++ui) + { + Vertex u = implicit_cast< Vertex >(*ui); + ColorValue u_color = get(color, u); + if (u_color == Color::white()) + { + vis.start_vertex(u, g); + detail::depth_first_visit_impl( + g, u, vis, color, detail::nontruth2()); + } } - } - - template - void - depth_first_search(const VertexListGraph& g, DFSVisitor vis, ColorMap color) - { - typedef typename boost::graph_traits::vertex_iterator vi; - std::pair verts = vertices(g); +} + +template < class VertexListGraph, class DFSVisitor, class ColorMap > +void depth_first_search( + const VertexListGraph& g, DFSVisitor vis, ColorMap color) +{ + typedef typename boost::graph_traits< VertexListGraph >::vertex_iterator vi; + std::pair< vi, vi > verts = vertices(g); if (verts.first == verts.second) - return; + return; depth_first_search(g, vis, color, detail::get_default_starting_vertex(g)); - } +} - template - class dfs_visitor { - public: - dfs_visitor() { } - dfs_visitor(Visitors vis) : m_vis(vis) { } +template < class Visitors = null_visitor > class dfs_visitor +{ +public: + dfs_visitor() {} + dfs_visitor(Visitors vis) : m_vis(vis) {} - template - void initialize_vertex(Vertex u, const Graph& g) { - invoke_visitors(m_vis, u, g, ::boost::on_initialize_vertex()); + template < class Vertex, class Graph > + void initialize_vertex(Vertex u, const Graph& g) + { + invoke_visitors(m_vis, u, g, ::boost::on_initialize_vertex()); } - template - void start_vertex(Vertex u, const Graph& g) { - invoke_visitors(m_vis, u, g, ::boost::on_start_vertex()); + template < class Vertex, class Graph > + void start_vertex(Vertex u, const Graph& g) + { + invoke_visitors(m_vis, u, g, ::boost::on_start_vertex()); } - template - void discover_vertex(Vertex u, const Graph& g) { - invoke_visitors(m_vis, u, g, ::boost::on_discover_vertex()); + template < class Vertex, class Graph > + void discover_vertex(Vertex u, const Graph& g) + { + invoke_visitors(m_vis, u, g, ::boost::on_discover_vertex()); } - template - void examine_edge(Edge u, const Graph& g) { - invoke_visitors(m_vis, u, g, ::boost::on_examine_edge()); + template < class Edge, class Graph > + void examine_edge(Edge u, const Graph& g) + { + invoke_visitors(m_vis, u, g, ::boost::on_examine_edge()); } - template - void tree_edge(Edge u, const Graph& g) { - invoke_visitors(m_vis, u, g, ::boost::on_tree_edge()); + template < class Edge, class Graph > void tree_edge(Edge u, const Graph& g) + { + invoke_visitors(m_vis, u, g, ::boost::on_tree_edge()); } - template - void back_edge(Edge u, const Graph& g) { - invoke_visitors(m_vis, u, g, ::boost::on_back_edge()); + template < class Edge, class Graph > void back_edge(Edge u, const Graph& g) + { + invoke_visitors(m_vis, u, g, ::boost::on_back_edge()); } - template - void forward_or_cross_edge(Edge u, const Graph& g) { - invoke_visitors(m_vis, u, g, ::boost::on_forward_or_cross_edge()); + template < class Edge, class Graph > + void forward_or_cross_edge(Edge u, const Graph& g) + { + invoke_visitors(m_vis, u, g, ::boost::on_forward_or_cross_edge()); } - template - void finish_edge(Edge u, const Graph& g) { - invoke_visitors(m_vis, u, g, ::boost::on_finish_edge()); + template < class Edge, class Graph > + void finish_edge(Edge u, const Graph& g) + { + invoke_visitors(m_vis, u, g, ::boost::on_finish_edge()); } - template - void finish_vertex(Vertex u, const Graph& g) { - invoke_visitors(m_vis, u, g, ::boost::on_finish_vertex()); + template < class Vertex, class Graph > + void finish_vertex(Vertex u, const Graph& g) + { + invoke_visitors(m_vis, u, g, ::boost::on_finish_vertex()); } - BOOST_GRAPH_EVENT_STUB(on_initialize_vertex,dfs) - BOOST_GRAPH_EVENT_STUB(on_start_vertex,dfs) - BOOST_GRAPH_EVENT_STUB(on_discover_vertex,dfs) - BOOST_GRAPH_EVENT_STUB(on_examine_edge,dfs) - BOOST_GRAPH_EVENT_STUB(on_tree_edge,dfs) - BOOST_GRAPH_EVENT_STUB(on_back_edge,dfs) - BOOST_GRAPH_EVENT_STUB(on_forward_or_cross_edge,dfs) - BOOST_GRAPH_EVENT_STUB(on_finish_edge,dfs) - BOOST_GRAPH_EVENT_STUB(on_finish_vertex,dfs) - - protected: + BOOST_GRAPH_EVENT_STUB(on_initialize_vertex, dfs) + BOOST_GRAPH_EVENT_STUB(on_start_vertex, dfs) + BOOST_GRAPH_EVENT_STUB(on_discover_vertex, dfs) + BOOST_GRAPH_EVENT_STUB(on_examine_edge, dfs) + BOOST_GRAPH_EVENT_STUB(on_tree_edge, dfs) + BOOST_GRAPH_EVENT_STUB(on_back_edge, dfs) + BOOST_GRAPH_EVENT_STUB(on_forward_or_cross_edge, dfs) + BOOST_GRAPH_EVENT_STUB(on_finish_edge, dfs) + BOOST_GRAPH_EVENT_STUB(on_finish_vertex, dfs) + +protected: Visitors m_vis; - }; - template - dfs_visitor - make_dfs_visitor(Visitors vis) { - return dfs_visitor(vis); - } - typedef dfs_visitor<> default_dfs_visitor; - - // Boost.Parameter named parameter variant - namespace graph { - namespace detail { - template - struct depth_first_search_impl { - typedef void result_type; - template - void operator()(const Graph& g, const ArgPack& arg_pack) const { - using namespace boost::graph::keywords; - boost::depth_first_search(g, - arg_pack[_visitor | make_dfs_visitor(null_visitor())], - boost::detail::make_color_map_from_arg_pack(g, arg_pack), - arg_pack[_root_vertex || boost::detail::get_default_starting_vertex_t(g)]); - } - }; +}; +template < class Visitors > +dfs_visitor< Visitors > make_dfs_visitor(Visitors vis) +{ + return dfs_visitor< Visitors >(vis); +} +typedef dfs_visitor<> default_dfs_visitor; + +// Boost.Parameter named parameter variant +namespace graph +{ + namespace detail + { + template < typename Graph > struct depth_first_search_impl + { + typedef void result_type; + template < typename ArgPack > + void operator()(const Graph& g, const ArgPack& arg_pack) const + { + using namespace boost::graph::keywords; + boost::depth_first_search(g, + arg_pack[_visitor | make_dfs_visitor(null_visitor())], + boost::detail::make_color_map_from_arg_pack(g, arg_pack), + arg_pack[_root_vertex + || boost::detail::get_default_starting_vertex_t< + Graph >(g)]); + } + }; } BOOST_GRAPH_MAKE_FORWARDING_FUNCTION(depth_first_search, 1, 4) - } +} - BOOST_GRAPH_MAKE_OLD_STYLE_PARAMETER_FUNCTION(depth_first_search, 1) +BOOST_GRAPH_MAKE_OLD_STYLE_PARAMETER_FUNCTION(depth_first_search, 1) - template - void depth_first_visit - (const IncidenceGraph& g, - typename graph_traits::vertex_descriptor u, - DFSVisitor vis, ColorMap color) - { +template < class IncidenceGraph, class DFSVisitor, class ColorMap > +void depth_first_visit(const IncidenceGraph& g, + typename graph_traits< IncidenceGraph >::vertex_descriptor u, + DFSVisitor vis, ColorMap color) +{ vis.start_vertex(u, g); detail::depth_first_visit_impl(g, u, vis, color, detail::nontruth2()); - } - - template - void depth_first_visit - (const IncidenceGraph& g, - typename graph_traits::vertex_descriptor u, - DFSVisitor vis, ColorMap color, TerminatorFunc func = TerminatorFunc()) - { +} + +template < class IncidenceGraph, class DFSVisitor, class ColorMap, + class TerminatorFunc > +void depth_first_visit(const IncidenceGraph& g, + typename graph_traits< IncidenceGraph >::vertex_descriptor u, + DFSVisitor vis, ColorMap color, TerminatorFunc func = TerminatorFunc()) +{ vis.start_vertex(u, g); detail::depth_first_visit_impl(g, u, vis, color, func); - } +} } // namespace boost -#include BOOST_GRAPH_MPI_INCLUDE() +#include BOOST_GRAPH_MPI_INCLUDE(< boost / graph / distributed / depth_first_search.hpp >) #endif diff --git a/include/boost/graph/detail/adj_list_edge_iterator.hpp b/include/boost/graph/detail/adj_list_edge_iterator.hpp index 12cb6ee97..ce4bee167 100644 --- a/include/boost/graph/detail/adj_list_edge_iterator.hpp +++ b/include/boost/graph/detail/adj_list_edge_iterator.hpp @@ -15,100 +15,118 @@ #include #include -#if BOOST_WORKAROUND( __IBMCPP__, <= 600 ) -# define BOOST_GRAPH_NO_OPTIONAL +#if BOOST_WORKAROUND(__IBMCPP__, <= 600) +#define BOOST_GRAPH_NO_OPTIONAL #endif #ifdef BOOST_GRAPH_NO_OPTIONAL -# define BOOST_GRAPH_MEMBER . -#else -# define BOOST_GRAPH_MEMBER -> -# include +#define BOOST_GRAPH_MEMBER . +#else +#define BOOST_GRAPH_MEMBER -> +#include #endif // ndef BOOST_GRAPH_NO_OPTIONAL -namespace boost { +namespace boost +{ + +namespace detail +{ - namespace detail { + template < class VertexIterator, class OutEdgeIterator, class Graph > + class adj_list_edge_iterator + { + typedef adj_list_edge_iterator self; - template - class adj_list_edge_iterator { - typedef adj_list_edge_iterator self; public: - typedef std::forward_iterator_tag iterator_category; - typedef typename OutEdgeIterator::value_type value_type; - typedef typename OutEdgeIterator::reference reference; - typedef typename OutEdgeIterator::pointer pointer; - typedef typename OutEdgeIterator::difference_type difference_type; - typedef difference_type distance_type; - - inline adj_list_edge_iterator() {} - - inline adj_list_edge_iterator(const self& x) - : vBegin(x.vBegin), vCurr(x.vCurr), vEnd(x.vEnd), - edges(x.edges), m_g(x.m_g) { } - - template - inline adj_list_edge_iterator(VertexIterator b, - VertexIterator c, - VertexIterator e, - const G& g) - : vBegin(b), vCurr(c), vEnd(e), m_g(&g) { - if ( vCurr != vEnd ) { - while ( vCurr != vEnd && out_degree(*vCurr, *m_g) == 0 ) - ++vCurr; - if ( vCurr != vEnd ) - edges = out_edges(*vCurr, *m_g); + typedef std::forward_iterator_tag iterator_category; + typedef typename OutEdgeIterator::value_type value_type; + typedef typename OutEdgeIterator::reference reference; + typedef typename OutEdgeIterator::pointer pointer; + typedef typename OutEdgeIterator::difference_type difference_type; + typedef difference_type distance_type; + + inline adj_list_edge_iterator() {} + + inline adj_list_edge_iterator(const self& x) + : vBegin(x.vBegin) + , vCurr(x.vCurr) + , vEnd(x.vEnd) + , edges(x.edges) + , m_g(x.m_g) + { + } + + template < class G > + inline adj_list_edge_iterator( + VertexIterator b, VertexIterator c, VertexIterator e, const G& g) + : vBegin(b), vCurr(c), vEnd(e), m_g(&g) + { + if (vCurr != vEnd) + { + while (vCurr != vEnd && out_degree(*vCurr, *m_g) == 0) + ++vCurr; + if (vCurr != vEnd) + edges = out_edges(*vCurr, *m_g); + } + } + + /*Note: + In the directed graph cases, it is fine. + For undirected graphs, one edge go through twice. + */ + inline self& operator++() + { + ++edges BOOST_GRAPH_MEMBER first; + if (edges BOOST_GRAPH_MEMBER first + == edges BOOST_GRAPH_MEMBER second) + { + ++vCurr; + while (vCurr != vEnd && out_degree(*vCurr, *m_g) == 0) + ++vCurr; + if (vCurr != vEnd) + edges = out_edges(*vCurr, *m_g); + } + return *this; } - } - - /*Note: - In the directed graph cases, it is fine. - For undirected graphs, one edge go through twice. - */ - inline self& operator++() { - ++edges BOOST_GRAPH_MEMBER first; - if (edges BOOST_GRAPH_MEMBER first == edges BOOST_GRAPH_MEMBER second) + inline self operator++(int) { - ++vCurr; - while ( vCurr != vEnd && out_degree(*vCurr, *m_g) == 0 ) - ++vCurr; - if ( vCurr != vEnd ) - edges = out_edges(*vCurr, *m_g); + self tmp = *this; + ++(*this); + return tmp; } - return *this; - } - inline self operator++(int) { - self tmp = *this; - ++(*this); - return tmp; - } - inline value_type operator*() const - { return *edges BOOST_GRAPH_MEMBER first; } - inline bool operator==(const self& x) const { - return vCurr == x.vCurr - && (vCurr == vEnd - || edges BOOST_GRAPH_MEMBER first == x.edges BOOST_GRAPH_MEMBER first); - } - inline bool operator!=(const self& x) const { - return vCurr != x.vCurr - || (vCurr != vEnd - && edges BOOST_GRAPH_MEMBER first != x.edges BOOST_GRAPH_MEMBER first); - } + inline value_type operator*() const + { + return *edges BOOST_GRAPH_MEMBER first; + } + inline bool operator==(const self& x) const + { + return vCurr == x.vCurr + && (vCurr == vEnd + || edges BOOST_GRAPH_MEMBER first + == x.edges BOOST_GRAPH_MEMBER first); + } + inline bool operator!=(const self& x) const + { + return vCurr != x.vCurr + || (vCurr != vEnd + && edges BOOST_GRAPH_MEMBER first + != x.edges BOOST_GRAPH_MEMBER first); + } + protected: - VertexIterator vBegin; - VertexIterator vCurr; - VertexIterator vEnd; + VertexIterator vBegin; + VertexIterator vCurr; + VertexIterator vEnd; #ifdef BOOST_GRAPH_NO_OPTIONAL - std::pair edges; + std::pair< OutEdgeIterator, OutEdgeIterator > edges; #else - boost::optional > - edges; + boost::optional< std::pair< OutEdgeIterator, OutEdgeIterator > > edges; #endif // ndef BOOST_GRAPH_NO_OPTIONAL - const Graph* m_g; + const Graph* m_g; }; - } // namespace detail +} // namespace detail } diff --git a/include/boost/graph/detail/adjacency_list.hpp b/include/boost/graph/detail/adjacency_list.hpp index 01d400ffd..4b11fa516 100644 --- a/include/boost/graph/detail/adjacency_list.hpp +++ b/include/boost/graph/detail/adjacency_list.hpp @@ -69,1199 +69,1209 @@ bidirectional code... it is awful similar. */ +namespace boost +{ -namespace boost { +namespace detail +{ - namespace detail { - - template - struct directed_category_traits { - typedef directed_tag directed_category; + template < typename DirectedS > struct directed_category_traits + { + typedef directed_tag directed_category; }; - template <> - struct directed_category_traits { - typedef directed_tag directed_category; + template <> struct directed_category_traits< directedS > + { + typedef directed_tag directed_category; }; - template <> - struct directed_category_traits { - typedef undirected_tag directed_category; + template <> struct directed_category_traits< undirectedS > + { + typedef undirected_tag directed_category; }; - template <> - struct directed_category_traits { - typedef bidirectional_tag directed_category; + template <> struct directed_category_traits< bidirectionalS > + { + typedef bidirectional_tag directed_category; }; - template - struct target_is { - target_is(const Vertex& v) : m_target(v) { } - template - bool operator()(const StoredEdge& e) const { - return e.get_target() == m_target; - } - Vertex m_target; + template < class Vertex > struct target_is + { + target_is(const Vertex& v) : m_target(v) {} + template < class StoredEdge > bool operator()(const StoredEdge& e) const + { + return e.get_target() == m_target; + } + Vertex m_target; }; // O(E/V) - template - void erase_from_incidence_list(EdgeList& el, vertex_descriptor v, - allow_parallel_edge_tag) + template < class EdgeList, class vertex_descriptor > + void erase_from_incidence_list( + EdgeList& el, vertex_descriptor v, allow_parallel_edge_tag) { - boost::graph_detail::erase_if(el, detail::target_is(v)); + boost::graph_detail::erase_if( + el, detail::target_is< vertex_descriptor >(v)); } // O(log(E/V)) - template - void erase_from_incidence_list(EdgeList& el, vertex_descriptor v, - disallow_parallel_edge_tag) + template < class EdgeList, class vertex_descriptor > + void erase_from_incidence_list( + EdgeList& el, vertex_descriptor v, disallow_parallel_edge_tag) { - typedef typename EdgeList::value_type StoredEdge; - el.erase(StoredEdge(v)); + typedef typename EdgeList::value_type StoredEdge; + el.erase(StoredEdge(v)); } //========================================================================= // Out-Edge and In-Edge Iterator Implementation - template + template < class BaseIter, class VertexDescriptor, class EdgeDescriptor, + class Difference > struct out_edge_iter - : iterator_adaptor< - out_edge_iter - , BaseIter - , EdgeDescriptor - , use_default - , EdgeDescriptor - , Difference - > - { - typedef iterator_adaptor< - out_edge_iter - , BaseIter - , EdgeDescriptor - , use_default - , EdgeDescriptor - , Difference - > super_t; - - inline out_edge_iter() { } + : iterator_adaptor< out_edge_iter< BaseIter, VertexDescriptor, + EdgeDescriptor, Difference >, + BaseIter, EdgeDescriptor, use_default, EdgeDescriptor, Difference > + { + typedef iterator_adaptor< out_edge_iter< BaseIter, VertexDescriptor, + EdgeDescriptor, Difference >, + BaseIter, EdgeDescriptor, use_default, EdgeDescriptor, Difference > + super_t; + + inline out_edge_iter() {} inline out_edge_iter(const BaseIter& i, const VertexDescriptor& src) - : super_t(i), m_src(src) { } - - inline EdgeDescriptor - dereference() const - { - return EdgeDescriptor(m_src, (*this->base()).get_target(), - &(*this->base()).get_property()); - } - VertexDescriptor m_src; + : super_t(i), m_src(src) + { + } + + inline EdgeDescriptor dereference() const + { + return EdgeDescriptor(m_src, (*this->base()).get_target(), + &(*this->base()).get_property()); + } + VertexDescriptor m_src; }; - template + template < class BaseIter, class VertexDescriptor, class EdgeDescriptor, + class Difference > struct in_edge_iter - : iterator_adaptor< - in_edge_iter - , BaseIter - , EdgeDescriptor - , use_default - , EdgeDescriptor - , Difference - > - { - typedef iterator_adaptor< - in_edge_iter - , BaseIter - , EdgeDescriptor - , use_default - , EdgeDescriptor - , Difference - > super_t; - - inline in_edge_iter() { } - inline in_edge_iter(const BaseIter& i, const VertexDescriptor& src) - : super_t(i), m_src(src) { } - - inline EdgeDescriptor - dereference() const - { - return EdgeDescriptor((*this->base()).get_target(), m_src, - &this->base()->get_property()); - } - VertexDescriptor m_src; + : iterator_adaptor< in_edge_iter< BaseIter, VertexDescriptor, + EdgeDescriptor, Difference >, + BaseIter, EdgeDescriptor, use_default, EdgeDescriptor, Difference > + { + typedef iterator_adaptor< in_edge_iter< BaseIter, VertexDescriptor, + EdgeDescriptor, Difference >, + BaseIter, EdgeDescriptor, use_default, EdgeDescriptor, Difference > + super_t; + + inline in_edge_iter() {} + inline in_edge_iter(const BaseIter& i, const VertexDescriptor& src) + : super_t(i), m_src(src) + { + } + + inline EdgeDescriptor dereference() const + { + return EdgeDescriptor((*this->base()).get_target(), m_src, + &this->base()->get_property()); + } + VertexDescriptor m_src; }; //========================================================================= // Undirected Edge Iterator Implementation - template + template < class EdgeIter, class EdgeDescriptor, class Difference > struct undirected_edge_iter - : iterator_adaptor< - undirected_edge_iter - , EdgeIter - , EdgeDescriptor - , use_default - , EdgeDescriptor - , Difference - > - { - typedef iterator_adaptor< - undirected_edge_iter - , EdgeIter - , EdgeDescriptor - , use_default - , EdgeDescriptor - , Difference - > super_t; - - undirected_edge_iter() {} - - explicit undirected_edge_iter(EdgeIter i) - : super_t(i) {} - - inline EdgeDescriptor - dereference() const { - return EdgeDescriptor( - (*this->base()).m_source - , (*this->base()).m_target - , &this->base()->get_property()); - } + : iterator_adaptor< + undirected_edge_iter< EdgeIter, EdgeDescriptor, Difference >, + EdgeIter, EdgeDescriptor, use_default, EdgeDescriptor, Difference > + { + typedef iterator_adaptor< + undirected_edge_iter< EdgeIter, EdgeDescriptor, Difference >, + EdgeIter, EdgeDescriptor, use_default, EdgeDescriptor, Difference > + super_t; + + undirected_edge_iter() {} + + explicit undirected_edge_iter(EdgeIter i) : super_t(i) {} + + inline EdgeDescriptor dereference() const + { + return EdgeDescriptor((*this->base()).m_source, + (*this->base()).m_target, &this->base()->get_property()); + } }; //========================================================================= // Edge Storage Types (stored in the out-edge/in-edge lists) - template + template < class Vertex > class stored_edge - : public boost::equality_comparable1< stored_edge, - boost::less_than_comparable1< stored_edge > > + : public boost::equality_comparable1< stored_edge< Vertex >, + boost::less_than_comparable1< stored_edge< Vertex > > > { public: - typedef no_property property_type; - inline stored_edge() { } - inline stored_edge(Vertex target, const no_property& = no_property()) - : m_target(target) { } - inline Vertex& get_target() const { return m_target; } - inline const no_property& get_property() const { return s_prop; } - inline bool operator==(const stored_edge& x) const - { return m_target == x.get_target(); } - inline bool operator<(const stored_edge& x) const - { return m_target < x.get_target(); } - //protected: need to add hash<> as a friend - static no_property s_prop; - // Sometimes target not used as key in the set, and in that case - // it is ok to change the target. - mutable Vertex m_target; + typedef no_property property_type; + inline stored_edge() {} + inline stored_edge(Vertex target, const no_property& = no_property()) + : m_target(target) + { + } + inline Vertex& get_target() const { return m_target; } + inline const no_property& get_property() const { return s_prop; } + inline bool operator==(const stored_edge& x) const + { + return m_target == x.get_target(); + } + inline bool operator<(const stored_edge& x) const + { + return m_target < x.get_target(); + } + // protected: need to add hash<> as a friend + static no_property s_prop; + // Sometimes target not used as key in the set, and in that case + // it is ok to change the target. + mutable Vertex m_target; }; - template - no_property stored_edge::s_prop; - -#if defined(BOOST_NO_CXX11_RVALUE_REFERENCES) || defined(BOOST_NO_CXX11_SMART_PTR) - template - class stored_edge_property : public stored_edge { - typedef stored_edge_property self; - typedef stored_edge Base; + template < class Vertex > no_property stored_edge< Vertex >::s_prop; + +#if defined(BOOST_NO_CXX11_RVALUE_REFERENCES) \ + || defined(BOOST_NO_CXX11_SMART_PTR) + template < class Vertex, class Property > + class stored_edge_property : public stored_edge< Vertex > + { + typedef stored_edge_property self; + typedef stored_edge< Vertex > Base; + public: - typedef Property property_type; - inline stored_edge_property() { } - inline stored_edge_property(Vertex target, - const Property& p = Property()) - : stored_edge(target), m_property(new Property(p)) { } - stored_edge_property(const self& x) - : Base(static_cast< Base const& >(x)), m_property(const_cast(x).m_property) { } - self& operator=(const self& x) { - // NOTE: avoid 'Base::operator=(x);' broken on SGI MIPSpro (bug 55771 of Mozilla). - static_cast(*this) = static_cast< Base const& >(x); - m_property = const_cast(x).m_property; - return *this; - } + typedef Property property_type; + inline stored_edge_property() {} + inline stored_edge_property( + Vertex target, const Property& p = Property()) + : stored_edge< Vertex >(target), m_property(new Property(p)) + { + } + stored_edge_property(const self& x) + : Base(static_cast< Base const& >(x)) + , m_property(const_cast< self& >(x).m_property) + { + } + self& operator=(const self& x) + { + // NOTE: avoid 'Base::operator=(x);' broken on SGI MIPSpro (bug + // 55771 of Mozilla). + static_cast< Base& >(*this) = static_cast< Base const& >(x); + m_property = const_cast< self& >(x).m_property; + return *this; + } #if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) - // NOTE Don't rely on default operators, their behavior is broken on several compilers (GCC 4.6). - stored_edge_property(self&& x) - : Base(static_cast< Base&& >(x)), m_property(std::move(x.m_property)) { } - self& operator=(self&& x) { - // NOTE: avoid 'Base::operator=(x);' broken on SGI MIPSpro (bug 55771 of Mozilla). - static_cast(*this) = static_cast< Base&& >(x); - m_property = std::move(x.m_property); - return *this; - } + // NOTE Don't rely on default operators, their behavior is broken on + // several compilers (GCC 4.6). + stored_edge_property(self&& x) + : Base(static_cast< Base&& >(x)), m_property(std::move(x.m_property)) + { + } + self& operator=(self&& x) + { + // NOTE: avoid 'Base::operator=(x);' broken on SGI MIPSpro (bug + // 55771 of Mozilla). + static_cast< Base& >(*this) = static_cast< Base&& >(x); + m_property = std::move(x.m_property); + return *this; + } #endif - inline Property& get_property() { return *m_property; } - inline const Property& get_property() const { return *m_property; } + inline Property& get_property() { return *m_property; } + inline const Property& get_property() const { return *m_property; } + protected: - // Holding the property by-value causes edge-descriptor - // invalidation for add_edge() with EdgeList=vecS. Instead we - // hold a pointer to the property. std::auto_ptr is not - // a perfect fit for the job, but it is darn close. + // Holding the property by-value causes edge-descriptor + // invalidation for add_edge() with EdgeList=vecS. Instead we + // hold a pointer to the property. std::auto_ptr is not + // a perfect fit for the job, but it is darn close. #ifdef BOOST_NO_AUTO_PTR - std::unique_ptr m_property; + std::unique_ptr< Property > m_property; #else - std::auto_ptr m_property; + std::auto_ptr< Property > m_property; #endif }; #else - template - class stored_edge_property : public stored_edge { - typedef stored_edge_property self; - typedef stored_edge Base; + template < class Vertex, class Property > + class stored_edge_property : public stored_edge< Vertex > + { + typedef stored_edge_property self; + typedef stored_edge< Vertex > Base; + public: - typedef Property property_type; - inline stored_edge_property() { } - inline stored_edge_property(Vertex target, - const Property& p = Property()) - : stored_edge(target), m_property(new Property(p)) { } - stored_edge_property(self&& x) : Base(static_cast< Base&& >(x)), - m_property(std::move(x.m_property)) { } - stored_edge_property(self const& x) : Base(static_cast< Base const& >(x)), - m_property(std::move(const_cast(x).m_property)) { } - self& operator=(self&& x) { - // NOTE: avoid 'Base::operator=(x);' broken on SGI MIPSpro (bug 55771 of Mozilla). - static_cast(*this) = static_cast< Base&& >(x); - m_property = std::move(x.m_property); - return *this; - } - self& operator=(self const& x) { - // NOTE: avoid 'Base::operator=(x);' broken on SGI MIPSpro (bug 55771 of Mozilla). - static_cast(*this) = static_cast< Base const& >(x); - m_property = std::move(const_cast(x).m_property); - return *this; - } - inline Property& get_property() { return *m_property; } - inline const Property& get_property() const { return *m_property; } + typedef Property property_type; + inline stored_edge_property() {} + inline stored_edge_property( + Vertex target, const Property& p = Property()) + : stored_edge< Vertex >(target), m_property(new Property(p)) + { + } + stored_edge_property(self&& x) + : Base(static_cast< Base&& >(x)), m_property(std::move(x.m_property)) + { + } + stored_edge_property(self const& x) + : Base(static_cast< Base const& >(x)) + , m_property(std::move(const_cast< self& >(x).m_property)) + { + } + self& operator=(self&& x) + { + // NOTE: avoid 'Base::operator=(x);' broken on SGI MIPSpro (bug + // 55771 of Mozilla). + static_cast< Base& >(*this) = static_cast< Base&& >(x); + m_property = std::move(x.m_property); + return *this; + } + self& operator=(self const& x) + { + // NOTE: avoid 'Base::operator=(x);' broken on SGI MIPSpro (bug + // 55771 of Mozilla). + static_cast< Base& >(*this) = static_cast< Base const& >(x); + m_property = std::move(const_cast< self& >(x).m_property); + return *this; + } + inline Property& get_property() { return *m_property; } + inline const Property& get_property() const { return *m_property; } + protected: - std::unique_ptr m_property; + std::unique_ptr< Property > m_property; }; #endif - - template - class stored_edge_iter - : public stored_edge + template < class Vertex, class Iter, class Property > + class stored_edge_iter : public stored_edge< Vertex > { public: - typedef Property property_type; - inline stored_edge_iter() { } - inline stored_edge_iter(Vertex v) - : stored_edge(v) { } - inline stored_edge_iter(Vertex v, Iter i, void* = 0) - : stored_edge(v), m_iter(i) { } - inline Property& get_property() { return m_iter->get_property(); } - inline const Property& get_property() const { - return m_iter->get_property(); - } - inline Iter get_iter() const { return m_iter; } + typedef Property property_type; + inline stored_edge_iter() {} + inline stored_edge_iter(Vertex v) : stored_edge< Vertex >(v) {} + inline stored_edge_iter(Vertex v, Iter i, void* = 0) + : stored_edge< Vertex >(v), m_iter(i) + { + } + inline Property& get_property() { return m_iter->get_property(); } + inline const Property& get_property() const + { + return m_iter->get_property(); + } + inline Iter get_iter() const { return m_iter; } + protected: - Iter m_iter; + Iter m_iter; }; // For when the EdgeList is a std::vector. // Want to make the iterator stable, so use an offset // instead of an iterator into a std::vector - template - class stored_ra_edge_iter - : public stored_edge + template < class Vertex, class EdgeVec, class Property > + class stored_ra_edge_iter : public stored_edge< Vertex > { - typedef typename EdgeVec::iterator Iter; + typedef typename EdgeVec::iterator Iter; + public: - typedef Property property_type; - inline stored_ra_edge_iter() { } - inline explicit stored_ra_edge_iter(Vertex v) // Only used for comparisons - : stored_edge(v), m_i(0), m_vec(0){ } - inline stored_ra_edge_iter(Vertex v, Iter i, EdgeVec* edge_vec) - : stored_edge(v), m_i(i - edge_vec->begin()), m_vec(edge_vec){ } - inline Property& get_property() { BOOST_ASSERT ((m_vec != 0)); return (*m_vec)[m_i].get_property(); } - inline const Property& get_property() const { - BOOST_ASSERT ((m_vec != 0)); - return (*m_vec)[m_i].get_property(); - } - inline Iter get_iter() const { BOOST_ASSERT ((m_vec != 0)); return m_vec->begin() + m_i; } + typedef Property property_type; + inline stored_ra_edge_iter() {} + inline explicit stored_ra_edge_iter( + Vertex v) // Only used for comparisons + : stored_edge< Vertex >(v), m_i(0), m_vec(0) + { + } + inline stored_ra_edge_iter(Vertex v, Iter i, EdgeVec* edge_vec) + : stored_edge< Vertex >(v), m_i(i - edge_vec->begin()), m_vec(edge_vec) + { + } + inline Property& get_property() + { + BOOST_ASSERT((m_vec != 0)); + return (*m_vec)[m_i].get_property(); + } + inline const Property& get_property() const + { + BOOST_ASSERT((m_vec != 0)); + return (*m_vec)[m_i].get_property(); + } + inline Iter get_iter() const + { + BOOST_ASSERT((m_vec != 0)); + return m_vec->begin() + m_i; + } + protected: - std::size_t m_i; - EdgeVec* m_vec; + std::size_t m_i; + EdgeVec* m_vec; }; - } // namespace detail +} // namespace detail - template - const typename property_value::type& - get(Tag property_tag, - const detail::stored_edge_property& e) - { +template < class Tag, class Vertex, class Property > +const typename property_value< Property, Tag >::type& get( + Tag property_tag, const detail::stored_edge_property< Vertex, Property >& e) +{ return get_property_value(e.get_property(), property_tag); - } +} - template - const typename property_value::type& - get(Tag property_tag, - const detail::stored_edge_iter& e) - { +template < class Tag, class Vertex, class Iter, class Property > +const typename property_value< Property, Tag >::type& get(Tag property_tag, + const detail::stored_edge_iter< Vertex, Iter, Property >& e) +{ return get_property_value(e.get_property(), property_tag); - } +} - template - const typename property_value::type& - get(Tag property_tag, - const detail::stored_ra_edge_iter& e) - { +template < class Tag, class Vertex, class EdgeVec, class Property > +const typename property_value< Property, Tag >::type& get(Tag property_tag, + const detail::stored_ra_edge_iter< Vertex, EdgeVec, Property >& e) +{ return get_property_value(e.get_property(), property_tag); - } +} - //========================================================================= - // Directed Edges Helper Class - - namespace detail { - - // O(E/V) - template - inline void - remove_directed_edge_dispatch(edge_descriptor, EdgeList& el, - StoredProperty& p) - { - for (typename EdgeList::iterator i = el.begin(); - i != el.end(); ++i) - if (&(*i).get_property() == &p) { - el.erase(i); - return; - } - } - - template - inline void - remove_directed_edge_if_dispatch(incidence_iterator first, - incidence_iterator last, - EdgeList& el, Predicate pred, - boost::allow_parallel_edge_tag) - { +//========================================================================= +// Directed Edges Helper Class + +namespace detail +{ + + // O(E/V) + template < class edge_descriptor, class EdgeList, class StoredProperty > + inline void remove_directed_edge_dispatch( + edge_descriptor, EdgeList& el, StoredProperty& p) + { + for (typename EdgeList::iterator i = el.begin(); i != el.end(); ++i) + if (&(*i).get_property() == &p) + { + el.erase(i); + return; + } + } + + template < class incidence_iterator, class EdgeList, class Predicate > + inline void remove_directed_edge_if_dispatch(incidence_iterator first, + incidence_iterator last, EdgeList& el, Predicate pred, + boost::allow_parallel_edge_tag) + { // remove_if while (first != last && !pred(*first)) - ++first; + ++first; incidence_iterator i = first; if (first != last) - for (++i; i != last; ++i) - if (!pred(*i)) { - *first.base() = BOOST_GRAPH_MOVE_IF_POSSIBLE(*i.base()); - ++first; - } + for (++i; i != last; ++i) + if (!pred(*i)) + { + *first.base() = BOOST_GRAPH_MOVE_IF_POSSIBLE(*i.base()); + ++first; + } el.erase(first.base(), el.end()); - } - template - inline void - remove_directed_edge_if_dispatch(incidence_iterator first, - incidence_iterator last, - EdgeList& el, - Predicate pred, - boost::disallow_parallel_edge_tag) - { - for (incidence_iterator next = first; - first != last; first = next) { - ++next; - if (pred(*first)) - el.erase( first.base() ); + } + template < class incidence_iterator, class EdgeList, class Predicate > + inline void remove_directed_edge_if_dispatch(incidence_iterator first, + incidence_iterator last, EdgeList& el, Predicate pred, + boost::disallow_parallel_edge_tag) + { + for (incidence_iterator next = first; first != last; first = next) + { + ++next; + if (pred(*first)) + el.erase(first.base()); } - } - - template - inline void - undirected_remove_out_edge_if_dispatch(Graph& g, - incidence_iterator first, - incidence_iterator last, - EdgeList& el, Predicate pred, - boost::allow_parallel_edge_tag) - { + } + + template < class PropT, class Graph, class incidence_iterator, + class EdgeList, class Predicate > + inline void undirected_remove_out_edge_if_dispatch(Graph& g, + incidence_iterator first, incidence_iterator last, EdgeList& el, + Predicate pred, boost::allow_parallel_edge_tag) + { typedef typename Graph::global_edgelist_selector EdgeListS; - BOOST_STATIC_ASSERT((!is_same::value)); + BOOST_STATIC_ASSERT((!is_same< EdgeListS, vecS >::value)); // remove_if while (first != last && !pred(*first)) - ++first; + ++first; incidence_iterator i = first; bool self_loop_removed = false; if (first != last) - for (; i != last; ++i) { - if (self_loop_removed) { - /* With self loops, the descriptor will show up - * twice. The first time it will be removed, and now it - * will be skipped. - */ - self_loop_removed = false; - } - else if (!pred(*i)) { - *first.base() = BOOST_GRAPH_MOVE_IF_POSSIBLE(*i.base()); - ++first; - } else { - if (source(*i, g) == target(*i, g)) self_loop_removed = true; - else { - // Remove the edge from the target - detail::remove_directed_edge_dispatch - (*i, - g.out_edge_list(target(*i, g)), - *(PropT*)(*i).get_property()); - } - - // Erase the edge property - g.m_edges.erase( (*i.base()).get_iter() ); + for (; i != last; ++i) + { + if (self_loop_removed) + { + /* With self loops, the descriptor will show up + * twice. The first time it will be removed, and now it + * will be skipped. + */ + self_loop_removed = false; + } + else if (!pred(*i)) + { + *first.base() = BOOST_GRAPH_MOVE_IF_POSSIBLE(*i.base()); + ++first; + } + else + { + if (source(*i, g) == target(*i, g)) + self_loop_removed = true; + else + { + // Remove the edge from the target + detail::remove_directed_edge_dispatch(*i, + g.out_edge_list(target(*i, g)), + *(PropT*)(*i).get_property()); + } + + // Erase the edge property + g.m_edges.erase((*i.base()).get_iter()); + } } - } el.erase(first.base(), el.end()); - } - template - inline void - undirected_remove_out_edge_if_dispatch(Graph& g, - incidence_iterator first, - incidence_iterator last, - EdgeList& el, - Predicate pred, - boost::disallow_parallel_edge_tag) - { + } + template < class PropT, class Graph, class incidence_iterator, + class EdgeList, class Predicate > + inline void undirected_remove_out_edge_if_dispatch(Graph& g, + incidence_iterator first, incidence_iterator last, EdgeList& el, + Predicate pred, boost::disallow_parallel_edge_tag) + { typedef typename Graph::global_edgelist_selector EdgeListS; - BOOST_STATIC_ASSERT((!is_same::value)); - - for (incidence_iterator next = first; - first != last; first = next) { - ++next; - if (pred(*first)) { - if (source(*first, g) != target(*first, g)) { - // Remove the edge from the target - detail::remove_directed_edge_dispatch - (*first, - g.out_edge_list(target(*first, g)), - *(PropT*)(*first).get_property()); - } - - // Erase the edge property - g.m_edges.erase( (*first.base()).get_iter() ); + BOOST_STATIC_ASSERT((!is_same< EdgeListS, vecS >::value)); - // Erase the edge in the source - el.erase( first.base() ); - } + for (incidence_iterator next = first; first != last; first = next) + { + ++next; + if (pred(*first)) + { + if (source(*first, g) != target(*first, g)) + { + // Remove the edge from the target + detail::remove_directed_edge_dispatch(*first, + g.out_edge_list(target(*first, g)), + *(PropT*)(*first).get_property()); + } + + // Erase the edge property + g.m_edges.erase((*first.base()).get_iter()); + + // Erase the edge in the source + el.erase(first.base()); + } } - } - - // O(E/V) - template - inline void - remove_directed_edge_dispatch(edge_descriptor e, EdgeList& el, - no_property&) - { - for (typename EdgeList::iterator i = el.begin(); - i != el.end(); ++i) - if ((*i).get_target() == e.m_target) { - el.erase(i); - return; - } - } + } + + // O(E/V) + template < class edge_descriptor, class EdgeList, class StoredProperty > + inline void remove_directed_edge_dispatch( + edge_descriptor e, EdgeList& el, no_property&) + { + for (typename EdgeList::iterator i = el.begin(); i != el.end(); ++i) + if ((*i).get_target() == e.m_target) + { + el.erase(i); + return; + } + } - } // namespace detail +} // namespace detail - template - struct directed_edges_helper { +template < class Config > struct directed_edges_helper +{ - // Placement of these overloaded remove_edge() functions - // inside the class avoids a VC++ bug. + // Placement of these overloaded remove_edge() functions + // inside the class avoids a VC++ bug. - // O(E/V) - inline void - remove_edge(typename Config::edge_descriptor e) - { + // O(E/V) + inline void remove_edge(typename Config::edge_descriptor e) + { typedef typename Config::graph_type graph_type; - graph_type& g = static_cast(*this); + graph_type& g = static_cast< graph_type& >(*this); typename Config::OutEdgeList& el = g.out_edge_list(source(e, g)); typedef typename Config::OutEdgeList::value_type::property_type PType; - detail::remove_directed_edge_dispatch(e, el, - *(PType*)e.get_property()); - } - - // O(1) - inline void - remove_edge(typename Config::out_edge_iterator iter) - { + detail::remove_directed_edge_dispatch(e, el, *(PType*)e.get_property()); + } + + // O(1) + inline void remove_edge(typename Config::out_edge_iterator iter) + { typedef typename Config::graph_type graph_type; - graph_type& g = static_cast(*this); + graph_type& g = static_cast< graph_type& >(*this); typename Config::edge_descriptor e = *iter; typename Config::OutEdgeList& el = g.out_edge_list(source(e, g)); el.erase(iter.base()); - } - - }; - - // O(1) - template - inline std::pair - edges(const directed_edges_helper& g_) - { - typedef typename Config::graph_type graph_type; - typedef typename Config::edge_iterator edge_iterator; - const graph_type& cg = static_cast(g_); - graph_type& g = const_cast(cg); - return std::make_pair( edge_iterator(g.vertex_set().begin(), - g.vertex_set().begin(), - g.vertex_set().end(), g), - edge_iterator(g.vertex_set().begin(), - g.vertex_set().end(), - g.vertex_set().end(), g) ); } +}; + +// O(1) +template < class Config > +inline std::pair< typename Config::edge_iterator, + typename Config::edge_iterator > +edges(const directed_edges_helper< Config >& g_) +{ + typedef typename Config::graph_type graph_type; + typedef typename Config::edge_iterator edge_iterator; + const graph_type& cg = static_cast< const graph_type& >(g_); + graph_type& g = const_cast< graph_type& >(cg); + return std::make_pair(edge_iterator(g.vertex_set().begin(), + g.vertex_set().begin(), g.vertex_set().end(), g), + edge_iterator(g.vertex_set().begin(), g.vertex_set().end(), + g.vertex_set().end(), g)); +} - //========================================================================= - // Directed Graph Helper Class - - struct adj_list_dir_traversal_tag : - public virtual vertex_list_graph_tag, - public virtual incidence_graph_tag, - public virtual adjacency_graph_tag, - public virtual edge_list_graph_tag { }; - - template - struct directed_graph_helper - : public directed_edges_helper { - typedef typename Config::edge_descriptor edge_descriptor; - typedef adj_list_dir_traversal_tag traversal_category; - }; - - // O(E/V) - template - inline void - remove_edge(typename Config::vertex_descriptor u, - typename Config::vertex_descriptor v, - directed_graph_helper& g_) - { - typedef typename Config::graph_type graph_type; - typedef typename Config::edge_parallel_category Cat; - graph_type& g = static_cast(g_); - detail::erase_from_incidence_list(g.out_edge_list(u), v, Cat()); - } +//========================================================================= +// Directed Graph Helper Class + +struct adj_list_dir_traversal_tag : public virtual vertex_list_graph_tag, + public virtual incidence_graph_tag, + public virtual adjacency_graph_tag, + public virtual edge_list_graph_tag +{ +}; + +template < class Config > +struct directed_graph_helper : public directed_edges_helper< Config > +{ + typedef typename Config::edge_descriptor edge_descriptor; + typedef adj_list_dir_traversal_tag traversal_category; +}; + +// O(E/V) +template < class Config > +inline void remove_edge(typename Config::vertex_descriptor u, + typename Config::vertex_descriptor v, directed_graph_helper< Config >& g_) +{ + typedef typename Config::graph_type graph_type; + typedef typename Config::edge_parallel_category Cat; + graph_type& g = static_cast< graph_type& >(g_); + detail::erase_from_incidence_list(g.out_edge_list(u), v, Cat()); +} - template - inline void - remove_out_edge_if(typename Config::vertex_descriptor u, Predicate pred, - directed_graph_helper& g_) - { - typedef typename Config::graph_type graph_type; - graph_type& g = static_cast(g_); - typename Config::out_edge_iterator first, last; - boost::tie(first, last) = out_edges(u, g); - typedef typename Config::edge_parallel_category edge_parallel_category; - detail::remove_directed_edge_if_dispatch - (first, last, g.out_edge_list(u), pred, edge_parallel_category()); - } +template < class Config, class Predicate > +inline void remove_out_edge_if(typename Config::vertex_descriptor u, + Predicate pred, directed_graph_helper< Config >& g_) +{ + typedef typename Config::graph_type graph_type; + graph_type& g = static_cast< graph_type& >(g_); + typename Config::out_edge_iterator first, last; + boost::tie(first, last) = out_edges(u, g); + typedef typename Config::edge_parallel_category edge_parallel_category; + detail::remove_directed_edge_if_dispatch( + first, last, g.out_edge_list(u), pred, edge_parallel_category()); +} - template - inline void - remove_edge_if(Predicate pred, directed_graph_helper& g_) - { - typedef typename Config::graph_type graph_type; - graph_type& g = static_cast(g_); +template < class Config, class Predicate > +inline void remove_edge_if(Predicate pred, directed_graph_helper< Config >& g_) +{ + typedef typename Config::graph_type graph_type; + graph_type& g = static_cast< graph_type& >(g_); - typename Config::vertex_iterator vi, vi_end; - for (boost::tie(vi, vi_end) = vertices(g); vi != vi_end; ++vi) + typename Config::vertex_iterator vi, vi_end; + for (boost::tie(vi, vi_end) = vertices(g); vi != vi_end; ++vi) remove_out_edge_if(*vi, pred, g); - } +} - template - inline void - remove_edge(EdgeOrIter e_or_iter, directed_graph_helper& g_) - { - g_.remove_edge(e_or_iter); - } +template < class EdgeOrIter, class Config > +inline void remove_edge( + EdgeOrIter e_or_iter, directed_graph_helper< Config >& g_) +{ + g_.remove_edge(e_or_iter); +} - // O(V + E) for allow_parallel_edges - // O(V * log(E/V)) for disallow_parallel_edges - template - inline void - clear_vertex(typename Config::vertex_descriptor u, - directed_graph_helper& g_) - { - typedef typename Config::graph_type graph_type; - typedef typename Config::edge_parallel_category Cat; - graph_type& g = static_cast(g_); - typename Config::vertex_iterator vi, viend; - for (boost::tie(vi, viend) = vertices(g); vi != viend; ++vi) +// O(V + E) for allow_parallel_edges +// O(V * log(E/V)) for disallow_parallel_edges +template < class Config > +inline void clear_vertex( + typename Config::vertex_descriptor u, directed_graph_helper< Config >& g_) +{ + typedef typename Config::graph_type graph_type; + typedef typename Config::edge_parallel_category Cat; + graph_type& g = static_cast< graph_type& >(g_); + typename Config::vertex_iterator vi, viend; + for (boost::tie(vi, viend) = vertices(g); vi != viend; ++vi) detail::erase_from_incidence_list(g.out_edge_list(*vi), u, Cat()); - g.out_edge_list(u).clear(); - // clear() should be a req of Sequence and AssociativeContainer, - // or maybe just Container - } + g.out_edge_list(u).clear(); + // clear() should be a req of Sequence and AssociativeContainer, + // or maybe just Container +} - template - inline void - clear_out_edges(typename Config::vertex_descriptor u, - directed_graph_helper& g_) - { - typedef typename Config::graph_type graph_type; - graph_type& g = static_cast(g_); - g.out_edge_list(u).clear(); - // clear() should be a req of Sequence and AssociativeContainer, - // or maybe just Container - } +template < class Config > +inline void clear_out_edges( + typename Config::vertex_descriptor u, directed_graph_helper< Config >& g_) +{ + typedef typename Config::graph_type graph_type; + graph_type& g = static_cast< graph_type& >(g_); + g.out_edge_list(u).clear(); + // clear() should be a req of Sequence and AssociativeContainer, + // or maybe just Container +} - // O(V), could do better... - template - inline typename Config::edges_size_type - num_edges(const directed_graph_helper& g_) - { - typedef typename Config::graph_type graph_type; - const graph_type& g = static_cast(g_); - typename Config::edges_size_type num_e = 0; - typename Config::vertex_iterator vi, vi_end; - for (boost::tie(vi, vi_end) = vertices(g); vi != vi_end; ++vi) +// O(V), could do better... +template < class Config > +inline typename Config::edges_size_type num_edges( + const directed_graph_helper< Config >& g_) +{ + typedef typename Config::graph_type graph_type; + const graph_type& g = static_cast< const graph_type& >(g_); + typename Config::edges_size_type num_e = 0; + typename Config::vertex_iterator vi, vi_end; + for (boost::tie(vi, vi_end) = vertices(g); vi != vi_end; ++vi) num_e += out_degree(*vi, g); - return num_e; - } - // O(1) for allow_parallel_edge_tag - // O(log(E/V)) for disallow_parallel_edge_tag - template - inline std::pair::edge_descriptor, bool> - add_edge(typename Config::vertex_descriptor u, - typename Config::vertex_descriptor v, - const typename Config::edge_property_type& p, - directed_graph_helper& g_) - { - typedef typename Config::edge_descriptor edge_descriptor; - typedef typename Config::graph_type graph_type; - typedef typename Config::StoredEdge StoredEdge; - graph_type& g = static_cast(g_); - typename Config::OutEdgeList::iterator i; - bool inserted; - boost::tie(i, inserted) = boost::graph_detail::push(g.out_edge_list(u), - StoredEdge(v, p)); - return std::make_pair(edge_descriptor(u, v, &(*i).get_property()), - inserted); - } - // Did not use default argument here because that - // causes Visual C++ to get confused. - template - inline std::pair - add_edge(typename Config::vertex_descriptor u, - typename Config::vertex_descriptor v, - directed_graph_helper& g_) - { - typename Config::edge_property_type p; - return add_edge(u, v, p, g_); - } - //========================================================================= - // Undirected Graph Helper Class + return num_e; +} +// O(1) for allow_parallel_edge_tag +// O(log(E/V)) for disallow_parallel_edge_tag +template < class Config > +inline std::pair< typename directed_graph_helper< Config >::edge_descriptor, + bool > +add_edge(typename Config::vertex_descriptor u, + typename Config::vertex_descriptor v, + const typename Config::edge_property_type& p, + directed_graph_helper< Config >& g_) +{ + typedef typename Config::edge_descriptor edge_descriptor; + typedef typename Config::graph_type graph_type; + typedef typename Config::StoredEdge StoredEdge; + graph_type& g = static_cast< graph_type& >(g_); + typename Config::OutEdgeList::iterator i; + bool inserted; + boost::tie(i, inserted) + = boost::graph_detail::push(g.out_edge_list(u), StoredEdge(v, p)); + return std::make_pair( + edge_descriptor(u, v, &(*i).get_property()), inserted); +} +// Did not use default argument here because that +// causes Visual C++ to get confused. +template < class Config > +inline std::pair< typename Config::edge_descriptor, bool > add_edge( + typename Config::vertex_descriptor u, typename Config::vertex_descriptor v, + directed_graph_helper< Config >& g_) +{ + typename Config::edge_property_type p; + return add_edge(u, v, p, g_); +} +//========================================================================= +// Undirected Graph Helper Class - template - struct undirected_graph_helper; +template < class Config > struct undirected_graph_helper; - struct undir_adj_list_traversal_tag : - public virtual vertex_list_graph_tag, - public virtual incidence_graph_tag, - public virtual adjacency_graph_tag, - public virtual edge_list_graph_tag, - public virtual bidirectional_graph_tag { }; +struct undir_adj_list_traversal_tag : public virtual vertex_list_graph_tag, + public virtual incidence_graph_tag, + public virtual adjacency_graph_tag, + public virtual edge_list_graph_tag, + public virtual bidirectional_graph_tag +{ +}; - namespace detail { +namespace detail +{ - // using class with specialization for dispatch is a VC++ workaround. - template - struct remove_undirected_edge_dispatch { + // using class with specialization for dispatch is a VC++ workaround. + template < class StoredProperty > struct remove_undirected_edge_dispatch + { // O(E/V) - template - static void - apply(edge_descriptor e, - undirected_graph_helper& g_, - StoredProperty& p) + template < class edge_descriptor, class Config > + static void apply(edge_descriptor e, + undirected_graph_helper< Config >& g_, StoredProperty& p) { - typedef typename Config::global_edgelist_selector EdgeListS; - BOOST_STATIC_ASSERT((!is_same::value)); - - typedef typename Config::graph_type graph_type; - graph_type& g = static_cast(g_); - - typename Config::OutEdgeList& out_el = g.out_edge_list(source(e, g)); - typename Config::OutEdgeList::iterator out_i = out_el.begin(); - typename Config::EdgeIter edge_iter_to_erase; - for (; out_i != out_el.end(); ++out_i) - if (&(*out_i).get_property() == &p) { - edge_iter_to_erase = (*out_i).get_iter(); - out_el.erase(out_i); - break; - } - typename Config::OutEdgeList& in_el = g.out_edge_list(target(e, g)); - typename Config::OutEdgeList::iterator in_i = in_el.begin(); - for (; in_i != in_el.end(); ++in_i) - if (&(*in_i).get_property() == &p) { - in_el.erase(in_i); - break; - } - g.m_edges.erase(edge_iter_to_erase); + typedef typename Config::global_edgelist_selector EdgeListS; + BOOST_STATIC_ASSERT((!is_same< EdgeListS, vecS >::value)); + + typedef typename Config::graph_type graph_type; + graph_type& g = static_cast< graph_type& >(g_); + + typename Config::OutEdgeList& out_el + = g.out_edge_list(source(e, g)); + typename Config::OutEdgeList::iterator out_i = out_el.begin(); + typename Config::EdgeIter edge_iter_to_erase; + for (; out_i != out_el.end(); ++out_i) + if (&(*out_i).get_property() == &p) + { + edge_iter_to_erase = (*out_i).get_iter(); + out_el.erase(out_i); + break; + } + typename Config::OutEdgeList& in_el = g.out_edge_list(target(e, g)); + typename Config::OutEdgeList::iterator in_i = in_el.begin(); + for (; in_i != in_el.end(); ++in_i) + if (&(*in_i).get_property() == &p) + { + in_el.erase(in_i); + break; + } + g.m_edges.erase(edge_iter_to_erase); } - }; + }; - template <> - struct remove_undirected_edge_dispatch { + template <> struct remove_undirected_edge_dispatch< no_property > + { // O(E/V) - template - static void - apply(edge_descriptor e, - undirected_graph_helper& g_, - no_property&) + template < class edge_descriptor, class Config > + static void apply(edge_descriptor e, + undirected_graph_helper< Config >& g_, no_property&) { - typedef typename Config::global_edgelist_selector EdgeListS; - BOOST_STATIC_ASSERT((!is_same::value)); - - typedef typename Config::graph_type graph_type; - graph_type& g = static_cast(g_); - no_property* p = (no_property*)e.get_property(); - typename Config::OutEdgeList& out_el = g.out_edge_list(source(e, g)); - typename Config::OutEdgeList::iterator out_i = out_el.begin(); - typename Config::EdgeIter edge_iter_to_erase; - for (; out_i != out_el.end(); ++out_i) - if (&(*out_i).get_property() == p) { - edge_iter_to_erase = (*out_i).get_iter(); - out_el.erase(out_i); - break; - } - typename Config::OutEdgeList& in_el = g.out_edge_list(target(e, g)); - typename Config::OutEdgeList::iterator in_i = in_el.begin(); - for (; in_i != in_el.end(); ++in_i) - if (&(*in_i).get_property() == p) { - in_el.erase(in_i); - break; - } - g.m_edges.erase(edge_iter_to_erase); + typedef typename Config::global_edgelist_selector EdgeListS; + BOOST_STATIC_ASSERT((!is_same< EdgeListS, vecS >::value)); + + typedef typename Config::graph_type graph_type; + graph_type& g = static_cast< graph_type& >(g_); + no_property* p = (no_property*)e.get_property(); + typename Config::OutEdgeList& out_el + = g.out_edge_list(source(e, g)); + typename Config::OutEdgeList::iterator out_i = out_el.begin(); + typename Config::EdgeIter edge_iter_to_erase; + for (; out_i != out_el.end(); ++out_i) + if (&(*out_i).get_property() == p) + { + edge_iter_to_erase = (*out_i).get_iter(); + out_el.erase(out_i); + break; + } + typename Config::OutEdgeList& in_el = g.out_edge_list(target(e, g)); + typename Config::OutEdgeList::iterator in_i = in_el.begin(); + for (; in_i != in_el.end(); ++in_i) + if (&(*in_i).get_property() == p) + { + in_el.erase(in_i); + break; + } + g.m_edges.erase(edge_iter_to_erase); } - }; - - // O(E/V) - template - inline void - remove_edge_and_property(Graph& g, EdgeList& el, Vertex v, - boost::allow_parallel_edge_tag cat) - { + }; + + // O(E/V) + template < class Graph, class EdgeList, class Vertex > + inline void remove_edge_and_property( + Graph& g, EdgeList& el, Vertex v, boost::allow_parallel_edge_tag cat) + { typedef typename Graph::global_edgelist_selector EdgeListS; - BOOST_STATIC_ASSERT((!is_same::value)); + BOOST_STATIC_ASSERT((!is_same< EdgeListS, vecS >::value)); typename EdgeList::iterator i = el.begin(), end = el.end(); - for (; i != end; ++i) { - if ((*i).get_target() == v) { - // NOTE: Wihtout this skip, this loop will double-delete properties - // of loop edges. This solution is based on the observation that - // the incidence edges of a vertex with a loop are adjacent in the - // out edge list. This *may* actually hold for multisets also. - bool skip = (boost::next(i) != end && i->get_iter() == boost::next(i)->get_iter()); - g.m_edges.erase((*i).get_iter()); - if (skip) ++i; - } + for (; i != end; ++i) + { + if ((*i).get_target() == v) + { + // NOTE: Wihtout this skip, this loop will double-delete + // properties of loop edges. This solution is based on the + // observation that the incidence edges of a vertex with a loop + // are adjacent in the out edge list. This *may* actually hold + // for multisets also. + bool skip = (boost::next(i) != end + && i->get_iter() == boost::next(i)->get_iter()); + g.m_edges.erase((*i).get_iter()); + if (skip) + ++i; + } } detail::erase_from_incidence_list(el, v, cat); - } - // O(log(E/V)) - template - inline void - remove_edge_and_property(Graph& g, EdgeList& el, Vertex v, - boost::disallow_parallel_edge_tag) - { + } + // O(log(E/V)) + template < class Graph, class EdgeList, class Vertex > + inline void remove_edge_and_property( + Graph& g, EdgeList& el, Vertex v, boost::disallow_parallel_edge_tag) + { typedef typename Graph::global_edgelist_selector EdgeListS; - BOOST_STATIC_ASSERT((!is_same::value)); + BOOST_STATIC_ASSERT((!is_same< EdgeListS, vecS >::value)); typedef typename EdgeList::value_type StoredEdge; typename EdgeList::iterator i = el.find(StoredEdge(v)), end = el.end(); - if (i != end) { - g.m_edges.erase((*i).get_iter()); - el.erase(i); + if (i != end) + { + g.m_edges.erase((*i).get_iter()); + el.erase(i); } - } - - } // namespace detail - - template - struct list_edge // short name due to VC++ truncation and linker problems - : public boost::detail::edge_base - { - typedef EdgeProperty property_type; - typedef boost::detail::edge_base Base; - list_edge(Vertex u, Vertex v, const EdgeProperty& p = EdgeProperty()) - : Base(u, v), m_property(p) { } - EdgeProperty& get_property() { return m_property; } - const EdgeProperty& get_property() const { return m_property; } - // the following methods should never be used, but are needed - // to make SGI MIPSpro C++ happy - list_edge() { } - bool operator==(const list_edge&) const { return false; } - bool operator<(const list_edge&) const { return false; } - EdgeProperty m_property; - }; + } + +} // namespace detail - template - struct undirected_graph_helper { +template < class Vertex, class EdgeProperty > +struct list_edge // short name due to VC++ truncation and linker problems +: public boost::detail::edge_base< boost::undirected_tag, Vertex > +{ + typedef EdgeProperty property_type; + typedef boost::detail::edge_base< boost::undirected_tag, Vertex > Base; + list_edge(Vertex u, Vertex v, const EdgeProperty& p = EdgeProperty()) + : Base(u, v), m_property(p) + { + } + EdgeProperty& get_property() { return m_property; } + const EdgeProperty& get_property() const { return m_property; } + // the following methods should never be used, but are needed + // to make SGI MIPSpro C++ happy + list_edge() {} + bool operator==(const list_edge&) const { return false; } + bool operator<(const list_edge&) const { return false; } + EdgeProperty m_property; +}; - typedef undir_adj_list_traversal_tag traversal_category; +template < class Config > struct undirected_graph_helper +{ - // Placement of these overloaded remove_edge() functions - // inside the class avoids a VC++ bug. + typedef undir_adj_list_traversal_tag traversal_category; - // O(E/V) - inline void - remove_edge(typename Config::edge_descriptor e) - { + // Placement of these overloaded remove_edge() functions + // inside the class avoids a VC++ bug. + + // O(E/V) + inline void remove_edge(typename Config::edge_descriptor e) + { typedef typename Config::global_edgelist_selector EdgeListS; - BOOST_STATIC_ASSERT((!is_same::value)); + BOOST_STATIC_ASSERT((!is_same< EdgeListS, vecS >::value)); typedef typename Config::OutEdgeList::value_type::property_type PType; - detail::remove_undirected_edge_dispatch::apply - (e, *this, *(PType*)e.get_property()); - } - // O(E/V) - inline void - remove_edge(typename Config::out_edge_iterator iter) - { - this->remove_edge(*iter); - } - }; - - // Had to make these non-members to avoid accidental instantiation - // on SGI MIPSpro C++ - template - inline typename C::InEdgeList& - in_edge_list(undirected_graph_helper&, - typename C::vertex_descriptor v) - { - typename C::stored_vertex* sv = (typename C::stored_vertex*)v; - return sv->m_out_edges; - } - template - inline const typename C::InEdgeList& - in_edge_list(const undirected_graph_helper&, - typename C::vertex_descriptor v) { - typename C::stored_vertex* sv = (typename C::stored_vertex*)v; - return sv->m_out_edges; + detail::remove_undirected_edge_dispatch< PType >::apply( + e, *this, *(PType*)e.get_property()); } - // O(E/V) - template - inline void - remove_edge(EdgeOrIter e, undirected_graph_helper& g_) + inline void remove_edge(typename Config::out_edge_iterator iter) { - typedef typename Config::global_edgelist_selector EdgeListS; - BOOST_STATIC_ASSERT((!is_same::value)); - - g_.remove_edge(e); + this->remove_edge(*iter); } +}; - // O(E/V) or O(log(E/V)) - template - void - remove_edge(typename Config::vertex_descriptor u, - typename Config::vertex_descriptor v, - undirected_graph_helper& g_) - { - typedef typename Config::global_edgelist_selector EdgeListS; - BOOST_STATIC_ASSERT((!is_same::value)); - - typedef typename Config::graph_type graph_type; - graph_type& g = static_cast(g_); - typedef typename Config::edge_parallel_category Cat; - detail::remove_edge_and_property(g, g.out_edge_list(u), v, Cat()); - detail::erase_from_incidence_list(g.out_edge_list(v), u, Cat()); - } - - template - void - remove_out_edge_if(typename Config::vertex_descriptor u, Predicate pred, - undirected_graph_helper& g_) - { - typedef typename Config::global_edgelist_selector EdgeListS; - BOOST_STATIC_ASSERT((!is_same::value)); - - typedef typename Config::graph_type graph_type; - typedef typename Config::OutEdgeList::value_type::property_type PropT; - graph_type& g = static_cast(g_); - typename Config::out_edge_iterator first, last; - boost::tie(first, last) = out_edges(u, g); - typedef typename Config::edge_parallel_category Cat; - detail::undirected_remove_out_edge_if_dispatch - (g, first, last, g.out_edge_list(u), pred, Cat()); - } - template - void - remove_in_edge_if(typename Config::vertex_descriptor u, Predicate pred, - undirected_graph_helper& g_) - { - typedef typename Config::global_edgelist_selector EdgeListS; - BOOST_STATIC_ASSERT((!is_same::value)); - - remove_out_edge_if(u, pred, g_); - } - - // O(E/V * E) or O(log(E/V) * E) - template - void - remove_edge_if(Predicate pred, undirected_graph_helper& g_) - { - typedef typename Config::global_edgelist_selector EdgeListS; - BOOST_STATIC_ASSERT((!is_same::value)); - - typedef typename Config::graph_type graph_type; - graph_type& g = static_cast(g_); - typename Config::edge_iterator ei, ei_end, next; - boost::tie(ei, ei_end) = edges(g); - for (next = ei; ei != ei_end; ei = next) { +// Had to make these non-members to avoid accidental instantiation +// on SGI MIPSpro C++ +template < class C > +inline typename C::InEdgeList& in_edge_list( + undirected_graph_helper< C >&, typename C::vertex_descriptor v) +{ + typename C::stored_vertex* sv = (typename C::stored_vertex*)v; + return sv->m_out_edges; +} +template < class C > +inline const typename C::InEdgeList& in_edge_list( + const undirected_graph_helper< C >&, typename C::vertex_descriptor v) +{ + typename C::stored_vertex* sv = (typename C::stored_vertex*)v; + return sv->m_out_edges; +} + +// O(E/V) +template < class EdgeOrIter, class Config > +inline void remove_edge(EdgeOrIter e, undirected_graph_helper< Config >& g_) +{ + typedef typename Config::global_edgelist_selector EdgeListS; + BOOST_STATIC_ASSERT((!is_same< EdgeListS, vecS >::value)); + + g_.remove_edge(e); +} + +// O(E/V) or O(log(E/V)) +template < class Config > +void remove_edge(typename Config::vertex_descriptor u, + typename Config::vertex_descriptor v, undirected_graph_helper< Config >& g_) +{ + typedef typename Config::global_edgelist_selector EdgeListS; + BOOST_STATIC_ASSERT((!is_same< EdgeListS, vecS >::value)); + + typedef typename Config::graph_type graph_type; + graph_type& g = static_cast< graph_type& >(g_); + typedef typename Config::edge_parallel_category Cat; + detail::remove_edge_and_property(g, g.out_edge_list(u), v, Cat()); + detail::erase_from_incidence_list(g.out_edge_list(v), u, Cat()); +} + +template < class Config, class Predicate > +void remove_out_edge_if(typename Config::vertex_descriptor u, Predicate pred, + undirected_graph_helper< Config >& g_) +{ + typedef typename Config::global_edgelist_selector EdgeListS; + BOOST_STATIC_ASSERT((!is_same< EdgeListS, vecS >::value)); + + typedef typename Config::graph_type graph_type; + typedef typename Config::OutEdgeList::value_type::property_type PropT; + graph_type& g = static_cast< graph_type& >(g_); + typename Config::out_edge_iterator first, last; + boost::tie(first, last) = out_edges(u, g); + typedef typename Config::edge_parallel_category Cat; + detail::undirected_remove_out_edge_if_dispatch< PropT >( + g, first, last, g.out_edge_list(u), pred, Cat()); +} +template < class Config, class Predicate > +void remove_in_edge_if(typename Config::vertex_descriptor u, Predicate pred, + undirected_graph_helper< Config >& g_) +{ + typedef typename Config::global_edgelist_selector EdgeListS; + BOOST_STATIC_ASSERT((!is_same< EdgeListS, vecS >::value)); + + remove_out_edge_if(u, pred, g_); +} + +// O(E/V * E) or O(log(E/V) * E) +template < class Predicate, class Config > +void remove_edge_if(Predicate pred, undirected_graph_helper< Config >& g_) +{ + typedef typename Config::global_edgelist_selector EdgeListS; + BOOST_STATIC_ASSERT((!is_same< EdgeListS, vecS >::value)); + + typedef typename Config::graph_type graph_type; + graph_type& g = static_cast< graph_type& >(g_); + typename Config::edge_iterator ei, ei_end, next; + boost::tie(ei, ei_end) = edges(g); + for (next = ei; ei != ei_end; ei = next) + { ++next; if (pred(*ei)) - remove_edge(*ei, g); - } + remove_edge(*ei, g); } +} - // O(1) - template - inline std::pair - edges(const undirected_graph_helper& g_) - { - typedef typename Config::graph_type graph_type; - typedef typename Config::edge_iterator edge_iterator; - const graph_type& cg = static_cast(g_); - graph_type& g = const_cast(cg); - return std::make_pair( edge_iterator(g.m_edges.begin()), - edge_iterator(g.m_edges.end()) ); - } - // O(1) - template - inline typename Config::edges_size_type - num_edges(const undirected_graph_helper& g_) - { - typedef typename Config::graph_type graph_type; - const graph_type& g = static_cast(g_); - return g.m_edges.size(); - } - // O(E/V * E/V) - template - inline void - clear_vertex(typename Config::vertex_descriptor u, - undirected_graph_helper& g_) - { - typedef typename Config::global_edgelist_selector EdgeListS; - BOOST_STATIC_ASSERT((!is_same::value)); - - typedef typename Config::graph_type graph_type; - graph_type& g = static_cast(g_); - while (true) { +// O(1) +template < class Config > +inline std::pair< typename Config::edge_iterator, + typename Config::edge_iterator > +edges(const undirected_graph_helper< Config >& g_) +{ + typedef typename Config::graph_type graph_type; + typedef typename Config::edge_iterator edge_iterator; + const graph_type& cg = static_cast< const graph_type& >(g_); + graph_type& g = const_cast< graph_type& >(cg); + return std::make_pair( + edge_iterator(g.m_edges.begin()), edge_iterator(g.m_edges.end())); +} +// O(1) +template < class Config > +inline typename Config::edges_size_type num_edges( + const undirected_graph_helper< Config >& g_) +{ + typedef typename Config::graph_type graph_type; + const graph_type& g = static_cast< const graph_type& >(g_); + return g.m_edges.size(); +} +// O(E/V * E/V) +template < class Config > +inline void clear_vertex( + typename Config::vertex_descriptor u, undirected_graph_helper< Config >& g_) +{ + typedef typename Config::global_edgelist_selector EdgeListS; + BOOST_STATIC_ASSERT((!is_same< EdgeListS, vecS >::value)); + + typedef typename Config::graph_type graph_type; + graph_type& g = static_cast< graph_type& >(g_); + while (true) + { typename Config::out_edge_iterator ei, ei_end; boost::tie(ei, ei_end) = out_edges(u, g); - if (ei == ei_end) break; + if (ei == ei_end) + break; remove_edge(*ei, g); - } - } - // O(1) for allow_parallel_edge_tag - // O(log(E/V)) for disallow_parallel_edge_tag - template - inline std::pair - add_edge(typename Config::vertex_descriptor u, - typename Config::vertex_descriptor v, - const typename Config::edge_property_type& p, - undirected_graph_helper& g_) - { - typedef typename Config::StoredEdge StoredEdge; - typedef typename Config::edge_descriptor edge_descriptor; - typedef typename Config::graph_type graph_type; - graph_type& g = static_cast(g_); - - bool inserted; - typename Config::EdgeContainer::value_type e(u, v, p); - typename Config::EdgeContainer::iterator p_iter + } +} +// O(1) for allow_parallel_edge_tag +// O(log(E/V)) for disallow_parallel_edge_tag +template < class Config > +inline std::pair< typename Config::edge_descriptor, bool > add_edge( + typename Config::vertex_descriptor u, typename Config::vertex_descriptor v, + const typename Config::edge_property_type& p, + undirected_graph_helper< Config >& g_) +{ + typedef typename Config::StoredEdge StoredEdge; + typedef typename Config::edge_descriptor edge_descriptor; + typedef typename Config::graph_type graph_type; + graph_type& g = static_cast< graph_type& >(g_); + + bool inserted; + typename Config::EdgeContainer::value_type e(u, v, p); + typename Config::EdgeContainer::iterator p_iter = graph_detail::push(g.m_edges, e).first; - typename Config::OutEdgeList::iterator i; - boost::tie(i, inserted) = boost::graph_detail::push(g.out_edge_list(u), - StoredEdge(v, p_iter, &g.m_edges)); - if (inserted) { - boost::graph_detail::push(g.out_edge_list(v), StoredEdge(u, p_iter, &g.m_edges)); - return std::make_pair(edge_descriptor(u, v, &p_iter->get_property()), - true); - } else { - g.m_edges.erase(p_iter); - return std::make_pair - (edge_descriptor(u, v, &i->get_iter()->get_property()), false); - } - } - template - inline std::pair - add_edge(typename Config::vertex_descriptor u, - typename Config::vertex_descriptor v, - undirected_graph_helper& g_) + typename Config::OutEdgeList::iterator i; + boost::tie(i, inserted) = boost::graph_detail::push( + g.out_edge_list(u), StoredEdge(v, p_iter, &g.m_edges)); + if (inserted) { - typename Config::edge_property_type p; - return add_edge(u, v, p, g_); + boost::graph_detail::push( + g.out_edge_list(v), StoredEdge(u, p_iter, &g.m_edges)); + return std::make_pair( + edge_descriptor(u, v, &p_iter->get_property()), true); } - - // O(1) - template - inline typename Config::degree_size_type - degree(typename Config::vertex_descriptor u, - const undirected_graph_helper& g_) + else { - typedef typename Config::graph_type Graph; - const Graph& g = static_cast(g_); - return out_degree(u, g); + g.m_edges.erase(p_iter); + return std::make_pair( + edge_descriptor(u, v, &i->get_iter()->get_property()), false); } +} +template < class Config > +inline std::pair< typename Config::edge_descriptor, bool > add_edge( + typename Config::vertex_descriptor u, typename Config::vertex_descriptor v, + undirected_graph_helper< Config >& g_) +{ + typename Config::edge_property_type p; + return add_edge(u, v, p, g_); +} + +// O(1) +template < class Config > +inline typename Config::degree_size_type degree( + typename Config::vertex_descriptor u, + const undirected_graph_helper< Config >& g_) +{ + typedef typename Config::graph_type Graph; + const Graph& g = static_cast< const Graph& >(g_); + return out_degree(u, g); +} + +template < class Config > +inline std::pair< typename Config::in_edge_iterator, + typename Config::in_edge_iterator > +in_edges(typename Config::vertex_descriptor u, + const undirected_graph_helper< Config >& g_) +{ + typedef typename Config::graph_type Graph; + const Graph& cg = static_cast< const Graph& >(g_); + Graph& g = const_cast< Graph& >(cg); + typedef typename Config::in_edge_iterator in_edge_iterator; + return std::make_pair(in_edge_iterator(g.out_edge_list(u).begin(), u), + in_edge_iterator(g.out_edge_list(u).end(), u)); +} + +template < class Config > +inline typename Config::degree_size_type in_degree( + typename Config::vertex_descriptor u, + const undirected_graph_helper< Config >& g_) +{ + return degree(u, g_); +} + +//========================================================================= +// Bidirectional Graph Helper Class + +struct bidir_adj_list_traversal_tag : public virtual vertex_list_graph_tag, + public virtual incidence_graph_tag, + public virtual adjacency_graph_tag, + public virtual edge_list_graph_tag, + public virtual bidirectional_graph_tag +{ +}; + +template < class Config > +struct bidirectional_graph_helper : public directed_edges_helper< Config > +{ + typedef bidir_adj_list_traversal_tag traversal_category; +}; + +// Had to make these non-members to avoid accidental instantiation +// on SGI MIPSpro C++ +template < class C > +inline typename C::InEdgeList& in_edge_list( + bidirectional_graph_helper< C >&, typename C::vertex_descriptor v) +{ + typename C::stored_vertex* sv = (typename C::stored_vertex*)v; + return sv->m_in_edges; +} +template < class C > +inline const typename C::InEdgeList& in_edge_list( + const bidirectional_graph_helper< C >&, typename C::vertex_descriptor v) +{ + typename C::stored_vertex* sv = (typename C::stored_vertex*)v; + return sv->m_in_edges; +} - template - inline std::pair - in_edges(typename Config::vertex_descriptor u, - const undirected_graph_helper& g_) +template < class Predicate, class Config > +inline void remove_edge_if( + Predicate pred, bidirectional_graph_helper< Config >& g_) +{ + typedef typename Config::global_edgelist_selector EdgeListS; + BOOST_STATIC_ASSERT((!is_same< EdgeListS, vecS >::value)); + + typedef typename Config::graph_type graph_type; + graph_type& g = static_cast< graph_type& >(g_); + typename Config::edge_iterator ei, ei_end, next; + boost::tie(ei, ei_end) = edges(g); + for (next = ei; ei != ei_end; ei = next) { - typedef typename Config::graph_type Graph; - const Graph& cg = static_cast(g_); - Graph& g = const_cast(cg); - typedef typename Config::in_edge_iterator in_edge_iterator; - return - std::make_pair(in_edge_iterator(g.out_edge_list(u).begin(), u), - in_edge_iterator(g.out_edge_list(u).end(), u)); + ++next; + if (pred(*ei)) + remove_edge(*ei, g); } +} - template - inline typename Config::degree_size_type - in_degree(typename Config::vertex_descriptor u, - const undirected_graph_helper& g_) - { return degree(u, g_); } +template < class Config > +inline std::pair< typename Config::in_edge_iterator, + typename Config::in_edge_iterator > +in_edges(typename Config::vertex_descriptor u, + const bidirectional_graph_helper< Config >& g_) +{ + typedef typename Config::graph_type graph_type; + const graph_type& cg = static_cast< const graph_type& >(g_); + graph_type& g = const_cast< graph_type& >(cg); + typedef typename Config::in_edge_iterator in_edge_iterator; + return std::make_pair(in_edge_iterator(in_edge_list(g, u).begin(), u), + in_edge_iterator(in_edge_list(g, u).end(), u)); +} - //========================================================================= - // Bidirectional Graph Helper Class - - struct bidir_adj_list_traversal_tag : - public virtual vertex_list_graph_tag, - public virtual incidence_graph_tag, - public virtual adjacency_graph_tag, - public virtual edge_list_graph_tag, - public virtual bidirectional_graph_tag { }; - - template - struct bidirectional_graph_helper - : public directed_edges_helper { - typedef bidir_adj_list_traversal_tag traversal_category; - }; +// O(1) +template < class Config > +inline std::pair< typename Config::edge_iterator, + typename Config::edge_iterator > +edges(const bidirectional_graph_helper< Config >& g_) +{ + typedef typename Config::graph_type graph_type; + typedef typename Config::edge_iterator edge_iterator; + const graph_type& cg = static_cast< const graph_type& >(g_); + graph_type& g = const_cast< graph_type& >(cg); + return std::make_pair( + edge_iterator(g.m_edges.begin()), edge_iterator(g.m_edges.end())); +} - // Had to make these non-members to avoid accidental instantiation - // on SGI MIPSpro C++ - template - inline typename C::InEdgeList& - in_edge_list(bidirectional_graph_helper&, - typename C::vertex_descriptor v) +//========================================================================= +// Bidirectional Graph Helper Class (with edge properties) + +template < class Config > +struct bidirectional_graph_helper_with_property +: public bidirectional_graph_helper< Config > +{ + typedef typename Config::graph_type graph_type; + typedef typename Config::out_edge_iterator out_edge_iterator; + + std::pair< out_edge_iterator, out_edge_iterator > get_parallel_edge_sublist( + typename Config::edge_descriptor e, const graph_type& g, void*) { - typename C::stored_vertex* sv = (typename C::stored_vertex*)v; - return sv->m_in_edges; - } - template - inline const typename C::InEdgeList& - in_edge_list(const bidirectional_graph_helper&, - typename C::vertex_descriptor v) { - typename C::stored_vertex* sv = (typename C::stored_vertex*)v; - return sv->m_in_edges; + return out_edges(source(e, g), g); } - template - inline void - remove_edge_if(Predicate pred, bidirectional_graph_helper& g_) + std::pair< out_edge_iterator, out_edge_iterator > get_parallel_edge_sublist( + typename Config::edge_descriptor e, const graph_type& g, setS*) { - typedef typename Config::global_edgelist_selector EdgeListS; - BOOST_STATIC_ASSERT((!is_same::value)); - - typedef typename Config::graph_type graph_type; - graph_type& g = static_cast(g_); - typename Config::edge_iterator ei, ei_end, next; - boost::tie(ei, ei_end) = edges(g); - for (next = ei; ei != ei_end; ei = next) { - ++next; - if (pred(*ei)) - remove_edge(*ei, g); - } + return edge_range(source(e, g), target(e, g), g); } - template - inline std::pair - in_edges(typename Config::vertex_descriptor u, - const bidirectional_graph_helper& g_) + std::pair< out_edge_iterator, out_edge_iterator > get_parallel_edge_sublist( + typename Config::edge_descriptor e, const graph_type& g, multisetS*) { - typedef typename Config::graph_type graph_type; - const graph_type& cg = static_cast(g_); - graph_type& g = const_cast(cg); - typedef typename Config::in_edge_iterator in_edge_iterator; - return - std::make_pair(in_edge_iterator(in_edge_list(g, u).begin(), u), - in_edge_iterator(in_edge_list(g, u).end(), u)); + return edge_range(source(e, g), target(e, g), g); } - // O(1) - template - inline std::pair - edges(const bidirectional_graph_helper& g_) + std::pair< out_edge_iterator, out_edge_iterator > get_parallel_edge_sublist( + typename Config::edge_descriptor e, const graph_type& g, hash_setS*) { - typedef typename Config::graph_type graph_type; - typedef typename Config::edge_iterator edge_iterator; - const graph_type& cg = static_cast(g_); - graph_type& g = const_cast(cg); - return std::make_pair( edge_iterator(g.m_edges.begin()), - edge_iterator(g.m_edges.end()) ); + return edge_range(source(e, g), target(e, g), g); } - //========================================================================= - // Bidirectional Graph Helper Class (with edge properties) - - - template - struct bidirectional_graph_helper_with_property - : public bidirectional_graph_helper - { - typedef typename Config::graph_type graph_type; - typedef typename Config::out_edge_iterator out_edge_iterator; - - std::pair - get_parallel_edge_sublist(typename Config::edge_descriptor e, - const graph_type& g, - void*) - { return out_edges(source(e, g), g); } - - std::pair - get_parallel_edge_sublist(typename Config::edge_descriptor e, - const graph_type& g, - setS*) - { return edge_range(source(e, g), target(e, g), g); } - - std::pair - get_parallel_edge_sublist(typename Config::edge_descriptor e, - const graph_type& g, - multisetS*) - { return edge_range(source(e, g), target(e, g), g); } - - std::pair - get_parallel_edge_sublist(typename Config::edge_descriptor e, - const graph_type& g, - hash_setS*) - { return edge_range(source(e, g), target(e, g), g); } - - // Placement of these overloaded remove_edge() functions - // inside the class avoids a VC++ bug. - - // O(E/V) or O(log(E/V)) - void - remove_edge(typename Config::edge_descriptor e) - { + // Placement of these overloaded remove_edge() functions + // inside the class avoids a VC++ bug. + + // O(E/V) or O(log(E/V)) + void remove_edge(typename Config::edge_descriptor e) + { typedef typename Config::global_edgelist_selector EdgeListS; - BOOST_STATIC_ASSERT((!is_same::value)); + BOOST_STATIC_ASSERT((!is_same< EdgeListS, vecS >::value)); - graph_type& g = static_cast(*this); + graph_type& g = static_cast< graph_type& >(*this); typedef typename Config::edgelist_selector OutEdgeListS; - std::pair rng = - get_parallel_edge_sublist(e, g, (OutEdgeListS*)(0)); + std::pair< out_edge_iterator, out_edge_iterator > rng + = get_parallel_edge_sublist(e, g, (OutEdgeListS*)(0)); rng.first = std::find(rng.first, rng.second, e); BOOST_ASSERT(rng.first != rng.second); remove_edge(rng.first); - } + } - inline void - remove_edge(typename Config::out_edge_iterator iter) - { + inline void remove_edge(typename Config::out_edge_iterator iter) + { typedef typename Config::global_edgelist_selector EdgeListS; - BOOST_STATIC_ASSERT((!is_same::value)); + BOOST_STATIC_ASSERT((!is_same< EdgeListS, vecS >::value)); typedef typename Config::graph_type graph_type; - graph_type& g = static_cast(*this); + graph_type& g = static_cast< graph_type& >(*this); typename Config::edge_descriptor e = *iter; typename Config::OutEdgeList& oel = g.out_edge_list(source(e, g)); typename Config::InEdgeList& iel = in_edge_list(g, target(e, g)); @@ -1270,1542 +1280,1602 @@ namespace boost { detail::remove_directed_edge_dispatch(*iter, iel, p); g.m_edges.erase(iter.base()->get_iter()); oel.erase(iter.base()); - } - }; - - // O(E/V) for allow_parallel_edge_tag - // O(log(E/V)) for disallow_parallel_edge_tag - template - inline void - remove_edge(typename Config::vertex_descriptor u, - typename Config::vertex_descriptor v, - bidirectional_graph_helper_with_property& g_) - { - typedef typename Config::global_edgelist_selector EdgeListS; - BOOST_STATIC_ASSERT((!is_same::value)); - - typedef typename Config::graph_type graph_type; - graph_type& g = static_cast(g_); - typedef typename Config::edge_parallel_category Cat; - detail::remove_edge_and_property(g, g.out_edge_list(u), v, Cat()); - detail::erase_from_incidence_list(in_edge_list(g, v), u, Cat()); } +}; + +// O(E/V) for allow_parallel_edge_tag +// O(log(E/V)) for disallow_parallel_edge_tag +template < class Config > +inline void remove_edge(typename Config::vertex_descriptor u, + typename Config::vertex_descriptor v, + bidirectional_graph_helper_with_property< Config >& g_) +{ + typedef typename Config::global_edgelist_selector EdgeListS; + BOOST_STATIC_ASSERT((!is_same< EdgeListS, vecS >::value)); + + typedef typename Config::graph_type graph_type; + graph_type& g = static_cast< graph_type& >(g_); + typedef typename Config::edge_parallel_category Cat; + detail::remove_edge_and_property(g, g.out_edge_list(u), v, Cat()); + detail::erase_from_incidence_list(in_edge_list(g, v), u, Cat()); +} - // O(E/V) or O(log(E/V)) - template - inline void - remove_edge(EdgeOrIter e, - bidirectional_graph_helper_with_property& g_) - { - typedef typename Config::global_edgelist_selector EdgeListS; - BOOST_STATIC_ASSERT((!is_same::value)); - - g_.remove_edge(e); - } - - template - inline void - remove_out_edge_if(typename Config::vertex_descriptor u, Predicate pred, - bidirectional_graph_helper_with_property& g_) - { - typedef typename Config::global_edgelist_selector EdgeListS; - BOOST_STATIC_ASSERT((!is_same::value)); - - typedef typename Config::graph_type graph_type; - typedef typename Config::OutEdgeList::value_type::property_type PropT; - graph_type& g = static_cast(g_); - - typedef typename Config::EdgeIter EdgeIter; - typedef std::vector Garbage; - Garbage garbage; - - // First remove the edges from the targets' in-edge lists and - // from the graph's edge set list. - typename Config::out_edge_iterator out_i, out_end; - for (boost::tie(out_i, out_end) = out_edges(u, g); out_i != out_end; ++out_i) - if (pred(*out_i)) { - detail::remove_directed_edge_dispatch - (*out_i, in_edge_list(g, target(*out_i, g)), - *(PropT*)(*out_i).get_property()); - // Put in garbage to delete later. Will need the properties - // for the remove_if of the out-edges. - garbage.push_back((*out_i.base()).get_iter()); - } +// O(E/V) or O(log(E/V)) +template < class EdgeOrIter, class Config > +inline void remove_edge( + EdgeOrIter e, bidirectional_graph_helper_with_property< Config >& g_) +{ + typedef typename Config::global_edgelist_selector EdgeListS; + BOOST_STATIC_ASSERT((!is_same< EdgeListS, vecS >::value)); - // Now remove the edges from this out-edge list. - typename Config::out_edge_iterator first, last; - boost::tie(first, last) = out_edges(u, g); - typedef typename Config::edge_parallel_category Cat; - detail::remove_directed_edge_if_dispatch - (first, last, g.out_edge_list(u), pred, Cat()); + g_.remove_edge(e); +} + +template < class Config, class Predicate > +inline void remove_out_edge_if(typename Config::vertex_descriptor u, + Predicate pred, bidirectional_graph_helper_with_property< Config >& g_) +{ + typedef typename Config::global_edgelist_selector EdgeListS; + BOOST_STATIC_ASSERT((!is_same< EdgeListS, vecS >::value)); + + typedef typename Config::graph_type graph_type; + typedef typename Config::OutEdgeList::value_type::property_type PropT; + graph_type& g = static_cast< graph_type& >(g_); + + typedef typename Config::EdgeIter EdgeIter; + typedef std::vector< EdgeIter > Garbage; + Garbage garbage; + + // First remove the edges from the targets' in-edge lists and + // from the graph's edge set list. + typename Config::out_edge_iterator out_i, out_end; + for (boost::tie(out_i, out_end) = out_edges(u, g); out_i != out_end; + ++out_i) + if (pred(*out_i)) + { + detail::remove_directed_edge_dispatch(*out_i, + in_edge_list(g, target(*out_i, g)), + *(PropT*)(*out_i).get_property()); + // Put in garbage to delete later. Will need the properties + // for the remove_if of the out-edges. + garbage.push_back((*out_i.base()).get_iter()); + } + + // Now remove the edges from this out-edge list. + typename Config::out_edge_iterator first, last; + boost::tie(first, last) = out_edges(u, g); + typedef typename Config::edge_parallel_category Cat; + detail::remove_directed_edge_if_dispatch( + first, last, g.out_edge_list(u), pred, Cat()); - // Now delete the edge properties from the g.m_edges list - for (typename Garbage::iterator i = garbage.begin(); - i != garbage.end(); ++i) + // Now delete the edge properties from the g.m_edges list + for (typename Garbage::iterator i = garbage.begin(); i != garbage.end(); + ++i) g.m_edges.erase(*i); - } - template - inline void - remove_in_edge_if(typename Config::vertex_descriptor v, Predicate pred, - bidirectional_graph_helper_with_property& g_) - { - typedef typename Config::global_edgelist_selector EdgeListS; - BOOST_STATIC_ASSERT((!is_same::value)); - - typedef typename Config::graph_type graph_type; - typedef typename Config::OutEdgeList::value_type::property_type PropT; - graph_type& g = static_cast(g_); - - typedef typename Config::EdgeIter EdgeIter; - typedef std::vector Garbage; - Garbage garbage; - - // First remove the edges from the sources' out-edge lists and - // from the graph's edge set list. - typename Config::in_edge_iterator in_i, in_end; - for (boost::tie(in_i, in_end) = in_edges(v, g); in_i != in_end; ++in_i) - if (pred(*in_i)) { - typename Config::vertex_descriptor u = source(*in_i, g); - detail::remove_directed_edge_dispatch - (*in_i, g.out_edge_list(u), *(PropT*)(*in_i).get_property()); - // Put in garbage to delete later. Will need the properties - // for the remove_if of the out-edges. - garbage.push_back((*in_i.base()).get_iter()); +} +template < class Config, class Predicate > +inline void remove_in_edge_if(typename Config::vertex_descriptor v, + Predicate pred, bidirectional_graph_helper_with_property< Config >& g_) +{ + typedef typename Config::global_edgelist_selector EdgeListS; + BOOST_STATIC_ASSERT((!is_same< EdgeListS, vecS >::value)); + + typedef typename Config::graph_type graph_type; + typedef typename Config::OutEdgeList::value_type::property_type PropT; + graph_type& g = static_cast< graph_type& >(g_); + + typedef typename Config::EdgeIter EdgeIter; + typedef std::vector< EdgeIter > Garbage; + Garbage garbage; + + // First remove the edges from the sources' out-edge lists and + // from the graph's edge set list. + typename Config::in_edge_iterator in_i, in_end; + for (boost::tie(in_i, in_end) = in_edges(v, g); in_i != in_end; ++in_i) + if (pred(*in_i)) + { + typename Config::vertex_descriptor u = source(*in_i, g); + detail::remove_directed_edge_dispatch( + *in_i, g.out_edge_list(u), *(PropT*)(*in_i).get_property()); + // Put in garbage to delete later. Will need the properties + // for the remove_if of the out-edges. + garbage.push_back((*in_i.base()).get_iter()); } - // Now remove the edges from this in-edge list. - typename Config::in_edge_iterator first, last; - boost::tie(first, last) = in_edges(v, g); - typedef typename Config::edge_parallel_category Cat; - detail::remove_directed_edge_if_dispatch - (first, last, in_edge_list(g, v), pred, Cat()); - - // Now delete the edge properties from the g.m_edges list - for (typename Garbage::iterator i = garbage.begin(); - i != garbage.end(); ++i) + // Now remove the edges from this in-edge list. + typename Config::in_edge_iterator first, last; + boost::tie(first, last) = in_edges(v, g); + typedef typename Config::edge_parallel_category Cat; + detail::remove_directed_edge_if_dispatch( + first, last, in_edge_list(g, v), pred, Cat()); + + // Now delete the edge properties from the g.m_edges list + for (typename Garbage::iterator i = garbage.begin(); i != garbage.end(); + ++i) g.m_edges.erase(*i); - } +} - // O(1) - template - inline typename Config::edges_size_type - num_edges(const bidirectional_graph_helper_with_property& g_) - { - typedef typename Config::graph_type graph_type; - const graph_type& g = static_cast(g_); - return g.m_edges.size(); - } - // O(E/V * E/V) for allow_parallel_edge_tag - // O(E/V * log(E/V)) for disallow_parallel_edge_tag - template - inline void - clear_vertex(typename Config::vertex_descriptor u, - bidirectional_graph_helper_with_property& g_) - { - typedef typename Config::global_edgelist_selector EdgeListS; - BOOST_STATIC_ASSERT((!is_same::value)); - - typedef typename Config::graph_type graph_type; - typedef typename Config::edge_parallel_category Cat; - graph_type& g = static_cast(g_); - typename Config::OutEdgeList& el = g.out_edge_list(u); - typename Config::OutEdgeList::iterator - ei = el.begin(), ei_end = el.end(); - for (; ei != ei_end; ++ei) { - detail::erase_from_incidence_list - (in_edge_list(g, (*ei).get_target()), u, Cat()); +// O(1) +template < class Config > +inline typename Config::edges_size_type num_edges( + const bidirectional_graph_helper_with_property< Config >& g_) +{ + typedef typename Config::graph_type graph_type; + const graph_type& g = static_cast< const graph_type& >(g_); + return g.m_edges.size(); +} +// O(E/V * E/V) for allow_parallel_edge_tag +// O(E/V * log(E/V)) for disallow_parallel_edge_tag +template < class Config > +inline void clear_vertex(typename Config::vertex_descriptor u, + bidirectional_graph_helper_with_property< Config >& g_) +{ + typedef typename Config::global_edgelist_selector EdgeListS; + BOOST_STATIC_ASSERT((!is_same< EdgeListS, vecS >::value)); + + typedef typename Config::graph_type graph_type; + typedef typename Config::edge_parallel_category Cat; + graph_type& g = static_cast< graph_type& >(g_); + typename Config::OutEdgeList& el = g.out_edge_list(u); + typename Config::OutEdgeList::iterator ei = el.begin(), ei_end = el.end(); + for (; ei != ei_end; ++ei) + { + detail::erase_from_incidence_list( + in_edge_list(g, (*ei).get_target()), u, Cat()); g.m_edges.erase((*ei).get_iter()); - } - typename Config::InEdgeList& in_el = in_edge_list(g, u); - typename Config::InEdgeList::iterator - in_ei = in_el.begin(), in_ei_end = in_el.end(); - for (; in_ei != in_ei_end; ++in_ei) { - detail::erase_from_incidence_list - (g.out_edge_list((*in_ei).get_target()), u, Cat()); + } + typename Config::InEdgeList& in_el = in_edge_list(g, u); + typename Config::InEdgeList::iterator in_ei = in_el.begin(), + in_ei_end = in_el.end(); + for (; in_ei != in_ei_end; ++in_ei) + { + detail::erase_from_incidence_list( + g.out_edge_list((*in_ei).get_target()), u, Cat()); g.m_edges.erase((*in_ei).get_iter()); - } - g.out_edge_list(u).clear(); - in_edge_list(g, u).clear(); - } - - template - inline void - clear_out_edges(typename Config::vertex_descriptor u, - bidirectional_graph_helper_with_property& g_) - { - typedef typename Config::global_edgelist_selector EdgeListS; - BOOST_STATIC_ASSERT((!is_same::value)); - - typedef typename Config::graph_type graph_type; - typedef typename Config::edge_parallel_category Cat; - graph_type& g = static_cast(g_); - typename Config::OutEdgeList& el = g.out_edge_list(u); - typename Config::OutEdgeList::iterator - ei = el.begin(), ei_end = el.end(); - for (; ei != ei_end; ++ei) { - detail::erase_from_incidence_list - (in_edge_list(g, (*ei).get_target()), u, Cat()); + } + g.out_edge_list(u).clear(); + in_edge_list(g, u).clear(); +} + +template < class Config > +inline void clear_out_edges(typename Config::vertex_descriptor u, + bidirectional_graph_helper_with_property< Config >& g_) +{ + typedef typename Config::global_edgelist_selector EdgeListS; + BOOST_STATIC_ASSERT((!is_same< EdgeListS, vecS >::value)); + + typedef typename Config::graph_type graph_type; + typedef typename Config::edge_parallel_category Cat; + graph_type& g = static_cast< graph_type& >(g_); + typename Config::OutEdgeList& el = g.out_edge_list(u); + typename Config::OutEdgeList::iterator ei = el.begin(), ei_end = el.end(); + for (; ei != ei_end; ++ei) + { + detail::erase_from_incidence_list( + in_edge_list(g, (*ei).get_target()), u, Cat()); g.m_edges.erase((*ei).get_iter()); - } - g.out_edge_list(u).clear(); - } - - template - inline void - clear_in_edges(typename Config::vertex_descriptor u, - bidirectional_graph_helper_with_property& g_) - { - typedef typename Config::global_edgelist_selector EdgeListS; - BOOST_STATIC_ASSERT((!is_same::value)); - - typedef typename Config::graph_type graph_type; - typedef typename Config::edge_parallel_category Cat; - graph_type& g = static_cast(g_); - typename Config::InEdgeList& in_el = in_edge_list(g, u); - typename Config::InEdgeList::iterator - in_ei = in_el.begin(), in_ei_end = in_el.end(); - for (; in_ei != in_ei_end; ++in_ei) { - detail::erase_from_incidence_list - (g.out_edge_list((*in_ei).get_target()), u, Cat()); + } + g.out_edge_list(u).clear(); +} + +template < class Config > +inline void clear_in_edges(typename Config::vertex_descriptor u, + bidirectional_graph_helper_with_property< Config >& g_) +{ + typedef typename Config::global_edgelist_selector EdgeListS; + BOOST_STATIC_ASSERT((!is_same< EdgeListS, vecS >::value)); + + typedef typename Config::graph_type graph_type; + typedef typename Config::edge_parallel_category Cat; + graph_type& g = static_cast< graph_type& >(g_); + typename Config::InEdgeList& in_el = in_edge_list(g, u); + typename Config::InEdgeList::iterator in_ei = in_el.begin(), + in_ei_end = in_el.end(); + for (; in_ei != in_ei_end; ++in_ei) + { + detail::erase_from_incidence_list( + g.out_edge_list((*in_ei).get_target()), u, Cat()); g.m_edges.erase((*in_ei).get_iter()); - } - in_edge_list(g, u).clear(); - } - - // O(1) for allow_parallel_edge_tag - // O(log(E/V)) for disallow_parallel_edge_tag - template - inline std::pair - add_edge(typename Config::vertex_descriptor u, - typename Config::vertex_descriptor v, - const typename Config::edge_property_type& p, - bidirectional_graph_helper_with_property& g_) - { - typedef typename Config::graph_type graph_type; - graph_type& g = static_cast(g_); - typedef typename Config::edge_descriptor edge_descriptor; - typedef typename Config::StoredEdge StoredEdge; - bool inserted; - typename Config::EdgeContainer::value_type e(u, v, p); - typename Config::EdgeContainer::iterator p_iter - = graph_detail::push(g.m_edges, e).first; - typename Config::OutEdgeList::iterator i; - boost::tie(i, inserted) = boost::graph_detail::push(g.out_edge_list(u), - StoredEdge(v, p_iter, &g.m_edges)); - if (inserted) { - boost::graph_detail::push(in_edge_list(g, v), StoredEdge(u, p_iter, &g.m_edges)); - return std::make_pair(edge_descriptor(u, v, &p_iter->m_property), - true); - } else { - g.m_edges.erase(p_iter); - return std::make_pair(edge_descriptor(u, v, - &i->get_iter()->get_property()), - false); - } } + in_edge_list(g, u).clear(); +} - template - inline std::pair - add_edge(typename Config::vertex_descriptor u, - typename Config::vertex_descriptor v, - bidirectional_graph_helper_with_property& g_) +// O(1) for allow_parallel_edge_tag +// O(log(E/V)) for disallow_parallel_edge_tag +template < class Config > +inline std::pair< typename Config::edge_descriptor, bool > add_edge( + typename Config::vertex_descriptor u, typename Config::vertex_descriptor v, + const typename Config::edge_property_type& p, + bidirectional_graph_helper_with_property< Config >& g_) +{ + typedef typename Config::graph_type graph_type; + graph_type& g = static_cast< graph_type& >(g_); + typedef typename Config::edge_descriptor edge_descriptor; + typedef typename Config::StoredEdge StoredEdge; + bool inserted; + typename Config::EdgeContainer::value_type e(u, v, p); + typename Config::EdgeContainer::iterator p_iter + = graph_detail::push(g.m_edges, e).first; + typename Config::OutEdgeList::iterator i; + boost::tie(i, inserted) = boost::graph_detail::push( + g.out_edge_list(u), StoredEdge(v, p_iter, &g.m_edges)); + if (inserted) { - typename Config::edge_property_type p; - return add_edge(u, v, p, g_); + boost::graph_detail::push( + in_edge_list(g, v), StoredEdge(u, p_iter, &g.m_edges)); + return std::make_pair(edge_descriptor(u, v, &p_iter->m_property), true); } - // O(1) - template - inline typename Config::degree_size_type - degree(typename Config::vertex_descriptor u, - const bidirectional_graph_helper_with_property& g_) + else { - typedef typename Config::graph_type graph_type; - const graph_type& g = static_cast(g_); - return in_degree(u, g) + out_degree(u, g); + g.m_edges.erase(p_iter); + return std::make_pair( + edge_descriptor(u, v, &i->get_iter()->get_property()), false); } +} - //========================================================================= - // Adjacency List Helper Class - - template - struct adj_list_helper : public Base - { - typedef typename Config::graph_type AdjList; - typedef typename Config::vertex_descriptor vertex_descriptor; - typedef typename Config::edge_descriptor edge_descriptor; - typedef typename Config::out_edge_iterator out_edge_iterator; - typedef typename Config::in_edge_iterator in_edge_iterator; - typedef typename Config::adjacency_iterator adjacency_iterator; - typedef typename Config::inv_adjacency_iterator inv_adjacency_iterator; - typedef typename Config::vertex_iterator vertex_iterator; - typedef typename Config::edge_iterator edge_iterator; - typedef typename Config::directed_category directed_category; - typedef typename Config::edge_parallel_category edge_parallel_category; - typedef typename Config::vertices_size_type vertices_size_type; - typedef typename Config::edges_size_type edges_size_type; - typedef typename Config::degree_size_type degree_size_type; - typedef typename Config::StoredEdge StoredEdge; - typedef typename Config::vertex_property_type vertex_property_type; - typedef typename Config::edge_property_type edge_property_type; - typedef typename Config::graph_property_type graph_property_type; - - typedef typename Config::global_edgelist_selector - global_edgelist_selector; - - typedef typename lookup_one_property::type vertex_bundled; - typedef typename lookup_one_property::type edge_bundled; - typedef typename lookup_one_property::type graph_bundled; - }; +template < class Config > +inline std::pair< typename Config::edge_descriptor, bool > add_edge( + typename Config::vertex_descriptor u, typename Config::vertex_descriptor v, + bidirectional_graph_helper_with_property< Config >& g_) +{ + typename Config::edge_property_type p; + return add_edge(u, v, p, g_); +} +// O(1) +template < class Config > +inline typename Config::degree_size_type degree( + typename Config::vertex_descriptor u, + const bidirectional_graph_helper_with_property< Config >& g_) +{ + typedef typename Config::graph_type graph_type; + const graph_type& g = static_cast< const graph_type& >(g_); + return in_degree(u, g) + out_degree(u, g); +} - template - inline std::pair - adjacent_vertices(typename Config::vertex_descriptor u, - const adj_list_helper& g_) - { - typedef typename Config::graph_type AdjList; - const AdjList& cg = static_cast(g_); - AdjList& g = const_cast(cg); - typedef typename Config::adjacency_iterator adjacency_iterator; - typename Config::out_edge_iterator first, last; - boost::tie(first, last) = out_edges(u, g); - return std::make_pair(adjacency_iterator(first, &g), - adjacency_iterator(last, &g)); - } - template - inline std::pair - inv_adjacent_vertices(typename Config::vertex_descriptor u, - const adj_list_helper& g_) - { - typedef typename Config::graph_type AdjList; - const AdjList& cg = static_cast(g_); - AdjList& g = const_cast(cg); - typedef typename Config::inv_adjacency_iterator inv_adjacency_iterator; - typename Config::in_edge_iterator first, last; - boost::tie(first, last) = in_edges(u, g); - return std::make_pair(inv_adjacency_iterator(first, &g), - inv_adjacency_iterator(last, &g)); - } - template - inline std::pair - out_edges(typename Config::vertex_descriptor u, - const adj_list_helper& g_) - { - typedef typename Config::graph_type AdjList; - typedef typename Config::out_edge_iterator out_edge_iterator; - const AdjList& cg = static_cast(g_); - AdjList& g = const_cast(cg); - return - std::make_pair(out_edge_iterator(g.out_edge_list(u).begin(), u), - out_edge_iterator(g.out_edge_list(u).end(), u)); - } - template - inline std::pair - vertices(const adj_list_helper& g_) - { - typedef typename Config::graph_type AdjList; - const AdjList& cg = static_cast(g_); - AdjList& g = const_cast(cg); - return std::make_pair( g.vertex_set().begin(), g.vertex_set().end() ); - } - template - inline typename Config::vertices_size_type - num_vertices(const adj_list_helper& g_) - { - typedef typename Config::graph_type AdjList; - const AdjList& g = static_cast(g_); - return g.vertex_set().size(); - } - template - inline typename Config::degree_size_type - out_degree(typename Config::vertex_descriptor u, - const adj_list_helper& g_) - { - typedef typename Config::graph_type AdjList; - const AdjList& g = static_cast(g_); - return g.out_edge_list(u).size(); - } - template - inline std::pair - edge(typename Config::vertex_descriptor u, - typename Config::vertex_descriptor v, - const adj_list_helper& g_) - { - typedef typename Config::graph_type Graph; - typedef typename Config::StoredEdge StoredEdge; - const Graph& cg = static_cast(g_); - const typename Config::OutEdgeList& el = cg.out_edge_list(u); - typename Config::OutEdgeList::const_iterator it = graph_detail:: - find(el, StoredEdge(v)); - return std::make_pair( - typename Config::edge_descriptor - (u, v, (it == el.end() ? 0 : &(*it).get_property())), - (it != el.end())); - } - - template - inline std::pair - edge_range(typename Config::vertex_descriptor u, - typename Config::vertex_descriptor v, - const adj_list_helper& g_) - { - typedef typename Config::graph_type Graph; - typedef typename Config::StoredEdge StoredEdge; - const Graph& cg = static_cast(g_); - Graph& g = const_cast(cg); - typedef typename Config::out_edge_iterator out_edge_iterator; - typename Config::OutEdgeList& el = g.out_edge_list(u); - typename Config::OutEdgeList::iterator first, last; - typename Config::EdgeContainer fake_edge_container; - boost::tie(first, last) = graph_detail:: - equal_range(el, StoredEdge(v)); - return std::make_pair(out_edge_iterator(first, u), - out_edge_iterator(last, u)); - } - - template - inline typename Config::degree_size_type - in_degree(typename Config::vertex_descriptor u, - const directed_edges_helper& g_) - { - typedef typename Config::graph_type Graph; - const Graph& cg = static_cast(g_); - Graph& g = const_cast(cg); - return in_edge_list(g, u).size(); - } - - namespace detail { - template - inline - typename boost::property_map::type - get_dispatch(adj_list_helper&, Property p, - boost::edge_property_tag) { +//========================================================================= +// Adjacency List Helper Class + +template < class Config, class Base > struct adj_list_helper : public Base +{ + typedef typename Config::graph_type AdjList; + typedef typename Config::vertex_descriptor vertex_descriptor; + typedef typename Config::edge_descriptor edge_descriptor; + typedef typename Config::out_edge_iterator out_edge_iterator; + typedef typename Config::in_edge_iterator in_edge_iterator; + typedef typename Config::adjacency_iterator adjacency_iterator; + typedef typename Config::inv_adjacency_iterator inv_adjacency_iterator; + typedef typename Config::vertex_iterator vertex_iterator; + typedef typename Config::edge_iterator edge_iterator; + typedef typename Config::directed_category directed_category; + typedef typename Config::edge_parallel_category edge_parallel_category; + typedef typename Config::vertices_size_type vertices_size_type; + typedef typename Config::edges_size_type edges_size_type; + typedef typename Config::degree_size_type degree_size_type; + typedef typename Config::StoredEdge StoredEdge; + typedef typename Config::vertex_property_type vertex_property_type; + typedef typename Config::edge_property_type edge_property_type; + typedef typename Config::graph_property_type graph_property_type; + + typedef typename Config::global_edgelist_selector global_edgelist_selector; + + typedef typename lookup_one_property< vertex_property_type, + vertex_bundle_t >::type vertex_bundled; + typedef + typename lookup_one_property< edge_property_type, edge_bundle_t >::type + edge_bundled; + typedef typename lookup_one_property< graph_property_type, + graph_bundle_t >::type graph_bundled; +}; + +template < class Config, class Base > +inline std::pair< typename Config::adjacency_iterator, + typename Config::adjacency_iterator > +adjacent_vertices(typename Config::vertex_descriptor u, + const adj_list_helper< Config, Base >& g_) +{ + typedef typename Config::graph_type AdjList; + const AdjList& cg = static_cast< const AdjList& >(g_); + AdjList& g = const_cast< AdjList& >(cg); + typedef typename Config::adjacency_iterator adjacency_iterator; + typename Config::out_edge_iterator first, last; + boost::tie(first, last) = out_edges(u, g); + return std::make_pair( + adjacency_iterator(first, &g), adjacency_iterator(last, &g)); +} +template < class Config, class Base > +inline std::pair< typename Config::inv_adjacency_iterator, + typename Config::inv_adjacency_iterator > +inv_adjacent_vertices(typename Config::vertex_descriptor u, + const adj_list_helper< Config, Base >& g_) +{ + typedef typename Config::graph_type AdjList; + const AdjList& cg = static_cast< const AdjList& >(g_); + AdjList& g = const_cast< AdjList& >(cg); + typedef typename Config::inv_adjacency_iterator inv_adjacency_iterator; + typename Config::in_edge_iterator first, last; + boost::tie(first, last) = in_edges(u, g); + return std::make_pair( + inv_adjacency_iterator(first, &g), inv_adjacency_iterator(last, &g)); +} +template < class Config, class Base > +inline std::pair< typename Config::out_edge_iterator, + typename Config::out_edge_iterator > +out_edges(typename Config::vertex_descriptor u, + const adj_list_helper< Config, Base >& g_) +{ + typedef typename Config::graph_type AdjList; + typedef typename Config::out_edge_iterator out_edge_iterator; + const AdjList& cg = static_cast< const AdjList& >(g_); + AdjList& g = const_cast< AdjList& >(cg); + return std::make_pair(out_edge_iterator(g.out_edge_list(u).begin(), u), + out_edge_iterator(g.out_edge_list(u).end(), u)); +} +template < class Config, class Base > +inline std::pair< typename Config::vertex_iterator, + typename Config::vertex_iterator > +vertices(const adj_list_helper< Config, Base >& g_) +{ + typedef typename Config::graph_type AdjList; + const AdjList& cg = static_cast< const AdjList& >(g_); + AdjList& g = const_cast< AdjList& >(cg); + return std::make_pair(g.vertex_set().begin(), g.vertex_set().end()); +} +template < class Config, class Base > +inline typename Config::vertices_size_type num_vertices( + const adj_list_helper< Config, Base >& g_) +{ + typedef typename Config::graph_type AdjList; + const AdjList& g = static_cast< const AdjList& >(g_); + return g.vertex_set().size(); +} +template < class Config, class Base > +inline typename Config::degree_size_type out_degree( + typename Config::vertex_descriptor u, + const adj_list_helper< Config, Base >& g_) +{ + typedef typename Config::graph_type AdjList; + const AdjList& g = static_cast< const AdjList& >(g_); + return g.out_edge_list(u).size(); +} +template < class Config, class Base > +inline std::pair< typename Config::edge_descriptor, bool > edge( + typename Config::vertex_descriptor u, typename Config::vertex_descriptor v, + const adj_list_helper< Config, Base >& g_) +{ + typedef typename Config::graph_type Graph; + typedef typename Config::StoredEdge StoredEdge; + const Graph& cg = static_cast< const Graph& >(g_); + const typename Config::OutEdgeList& el = cg.out_edge_list(u); + typename Config::OutEdgeList::const_iterator it + = graph_detail::find(el, StoredEdge(v)); + return std::make_pair(typename Config::edge_descriptor(u, v, + (it == el.end() ? 0 : &(*it).get_property())), + (it != el.end())); +} + +template < class Config, class Base > +inline std::pair< typename Config::out_edge_iterator, + typename Config::out_edge_iterator > +edge_range(typename Config::vertex_descriptor u, + typename Config::vertex_descriptor v, + const adj_list_helper< Config, Base >& g_) +{ + typedef typename Config::graph_type Graph; + typedef typename Config::StoredEdge StoredEdge; + const Graph& cg = static_cast< const Graph& >(g_); + Graph& g = const_cast< Graph& >(cg); + typedef typename Config::out_edge_iterator out_edge_iterator; + typename Config::OutEdgeList& el = g.out_edge_list(u); + typename Config::OutEdgeList::iterator first, last; + typename Config::EdgeContainer fake_edge_container; + boost::tie(first, last) = graph_detail::equal_range(el, StoredEdge(v)); + return std::make_pair( + out_edge_iterator(first, u), out_edge_iterator(last, u)); +} + +template < class Config > +inline typename Config::degree_size_type in_degree( + typename Config::vertex_descriptor u, + const directed_edges_helper< Config >& g_) +{ + typedef typename Config::graph_type Graph; + const Graph& cg = static_cast< const Graph& >(g_); + Graph& g = const_cast< Graph& >(cg); + return in_edge_list(g, u).size(); +} + +namespace detail +{ + template < class Config, class Base, class Property > + inline typename boost::property_map< typename Config::graph_type, + Property >::type + get_dispatch( + adj_list_helper< Config, Base >&, Property p, boost::edge_property_tag) + { typedef typename Config::graph_type Graph; - typedef typename boost::property_map::type PA; + typedef typename boost::property_map< Graph, Property >::type PA; return PA(p); - } - template - inline - typename boost::property_map::const_type - get_dispatch(const adj_list_helper&, Property p, - boost::edge_property_tag) { + } + template < class Config, class Base, class Property > + inline typename boost::property_map< typename Config::graph_type, + Property >::const_type + get_dispatch(const adj_list_helper< Config, Base >&, Property p, + boost::edge_property_tag) + { typedef typename Config::graph_type Graph; - typedef typename boost::property_map::const_type PA; + typedef typename boost::property_map< Graph, Property >::const_type PA; return PA(p); - } - - template - inline - typename boost::property_map::type - get_dispatch(adj_list_helper& g, Property p, - boost::vertex_property_tag) { + } + + template < class Config, class Base, class Property > + inline typename boost::property_map< typename Config::graph_type, + Property >::type + get_dispatch(adj_list_helper< Config, Base >& g, Property p, + boost::vertex_property_tag) + { typedef typename Config::graph_type Graph; - typedef typename boost::property_map::type PA; - return PA(&static_cast(g), p); - } - template - inline - typename boost::property_map::const_type - get_dispatch(const adj_list_helper& g, Property p, - boost::vertex_property_tag) { + typedef typename boost::property_map< Graph, Property >::type PA; + return PA(&static_cast< Graph& >(g), p); + } + template < class Config, class Base, class Property > + inline typename boost::property_map< typename Config::graph_type, + Property >::const_type + get_dispatch(const adj_list_helper< Config, Base >& g, Property p, + boost::vertex_property_tag) + { typedef typename Config::graph_type Graph; - typedef typename boost::property_map::const_type PA; - const Graph& cg = static_cast(g); + typedef typename boost::property_map< Graph, Property >::const_type PA; + const Graph& cg = static_cast< const Graph& >(g); return PA(&cg, p); - } - - } // namespace detail - - // Implementation of the PropertyGraph interface - template - inline - typename boost::property_map::type - get(Property p, adj_list_helper& g) { - typedef typename detail::property_kind_from_graph, Property>::type Kind; - return detail::get_dispatch(g, p, Kind()); - } - template - inline - typename boost::property_map::const_type - get(Property p, const adj_list_helper& g) { - typedef typename detail::property_kind_from_graph, Property>::type Kind; - return detail::get_dispatch(g, p, Kind()); - } - - template - inline - typename boost::property_traits< - typename boost::property_map::type - >::reference - get(Property p, adj_list_helper& g, const Key& key) { - return get(get(p, g), key); } - template - inline - typename boost::property_traits< - typename boost::property_map::const_type - >::reference - get(Property p, const adj_list_helper& g, const Key& key) { - return get(get(p, g), key); - } +} // namespace detail - template - inline void - put(Property p, adj_list_helper& g, - const Key& key, const Value& value) - { - typedef typename Config::graph_type Graph; - typedef typename boost::property_map::type Map; - Map pmap = get(p, static_cast(g)); - put(pmap, key, value); - } +// Implementation of the PropertyGraph interface +template < class Config, class Base, class Property > +inline + typename boost::property_map< typename Config::graph_type, Property >::type + get(Property p, adj_list_helper< Config, Base >& g) +{ + typedef typename detail::property_kind_from_graph< + adj_list_helper< Config, Base >, Property >::type Kind; + return detail::get_dispatch(g, p, Kind()); +} +template < class Config, class Base, class Property > +inline typename boost::property_map< typename Config::graph_type, + Property >::const_type +get(Property p, const adj_list_helper< Config, Base >& g) +{ + typedef typename detail::property_kind_from_graph< + adj_list_helper< Config, Base >, Property >::type Kind; + return detail::get_dispatch(g, p, Kind()); +} +template < class Config, class Base, class Property, class Key > +inline typename boost::property_traits< typename boost::property_map< + typename Config::graph_type, Property >::type >::reference +get(Property p, adj_list_helper< Config, Base >& g, const Key& key) +{ + return get(get(p, g), key); +} - //========================================================================= - // Generalize Adjacency List Implementation +template < class Config, class Base, class Property, class Key > +inline typename boost::property_traits< typename boost::property_map< + typename Config::graph_type, Property >::const_type >::reference +get(Property p, const adj_list_helper< Config, Base >& g, const Key& key) +{ + return get(get(p, g), key); +} - struct adj_list_tag { }; +template < class Config, class Base, class Property, class Key, class Value > +inline void put(Property p, adj_list_helper< Config, Base >& g, const Key& key, + const Value& value) +{ + typedef typename Config::graph_type Graph; + typedef typename boost::property_map< Graph, Property >::type Map; + Map pmap = get(p, static_cast< Graph& >(g)); + put(pmap, key, value); +} - template - class adj_list_impl - : public adj_list_helper +//========================================================================= +// Generalize Adjacency List Implementation + +struct adj_list_tag +{ +}; + +template < class Derived, class Config, class Base > +class adj_list_impl : public adj_list_helper< Config, Base > +{ + typedef typename Config::OutEdgeList OutEdgeList; + typedef typename Config::InEdgeList InEdgeList; + typedef typename Config::StoredVertexList StoredVertexList; + +public: + typedef typename Config::stored_vertex stored_vertex; + typedef typename Config::EdgeContainer EdgeContainer; + typedef typename Config::vertex_descriptor vertex_descriptor; + typedef typename Config::edge_descriptor edge_descriptor; + typedef typename Config::vertex_iterator vertex_iterator; + typedef typename Config::edge_iterator edge_iterator; + typedef typename Config::edge_parallel_category edge_parallel_category; + typedef typename Config::vertices_size_type vertices_size_type; + typedef typename Config::edges_size_type edges_size_type; + typedef typename Config::degree_size_type degree_size_type; + typedef typename Config::edge_property_type edge_property_type; + typedef adj_list_tag graph_tag; + + static vertex_descriptor null_vertex() { return 0; } + + inline adj_list_impl() {} + + inline adj_list_impl(const adj_list_impl& x) { copy_impl(x); } + inline adj_list_impl& operator=(const adj_list_impl& x) { - typedef typename Config::OutEdgeList OutEdgeList; - typedef typename Config::InEdgeList InEdgeList; - typedef typename Config::StoredVertexList StoredVertexList; - public: - typedef typename Config::stored_vertex stored_vertex; - typedef typename Config::EdgeContainer EdgeContainer; - typedef typename Config::vertex_descriptor vertex_descriptor; - typedef typename Config::edge_descriptor edge_descriptor; - typedef typename Config::vertex_iterator vertex_iterator; - typedef typename Config::edge_iterator edge_iterator; - typedef typename Config::edge_parallel_category edge_parallel_category; - typedef typename Config::vertices_size_type vertices_size_type; - typedef typename Config::edges_size_type edges_size_type; - typedef typename Config::degree_size_type degree_size_type; - typedef typename Config::edge_property_type edge_property_type; - typedef adj_list_tag graph_tag; - - static vertex_descriptor null_vertex() - { - return 0; - } - - inline adj_list_impl() { } - - inline adj_list_impl(const adj_list_impl& x) { - copy_impl(x); - } - inline adj_list_impl& operator=(const adj_list_impl& x) { this->clear(); copy_impl(x); return *this; - } - inline void clear() { + } + inline void clear() + { for (typename StoredVertexList::iterator i = m_vertices.begin(); i != m_vertices.end(); ++i) - delete (stored_vertex*)*i; + delete (stored_vertex*)*i; m_vertices.clear(); m_edges.clear(); - } - inline adj_list_impl(vertices_size_type num_vertices) { + } + inline adj_list_impl(vertices_size_type num_vertices) + { for (vertices_size_type i = 0; i < num_vertices; ++i) - add_vertex(static_cast(*this)); - } - template - inline adj_list_impl(vertices_size_type num_vertices, - EdgeIterator first, EdgeIterator last) - { + add_vertex(static_cast< Derived& >(*this)); + } + template < class EdgeIterator > + inline adj_list_impl( + vertices_size_type num_vertices, EdgeIterator first, EdgeIterator last) + { vertex_descriptor* v = new vertex_descriptor[num_vertices]; for (vertices_size_type i = 0; i < num_vertices; ++i) - v[i] = add_vertex(static_cast(*this)); + v[i] = add_vertex(static_cast< Derived& >(*this)); - while (first != last) { - add_edge(v[(*first).first], v[(*first).second], *this); - ++first; + while (first != last) + { + add_edge(v[(*first).first], v[(*first).second], *this); + ++first; } - delete [] v; - } - template - inline adj_list_impl(vertices_size_type num_vertices, - EdgeIterator first, EdgeIterator last, - EdgePropertyIterator ep_iter) - { + delete[] v; + } + template < class EdgeIterator, class EdgePropertyIterator > + inline adj_list_impl(vertices_size_type num_vertices, EdgeIterator first, + EdgeIterator last, EdgePropertyIterator ep_iter) + { vertex_descriptor* v = new vertex_descriptor[num_vertices]; for (vertices_size_type i = 0; i < num_vertices; ++i) - v[i] = add_vertex(static_cast(*this)); + v[i] = add_vertex(static_cast< Derived& >(*this)); - while (first != last) { - add_edge(v[(*first).first], v[(*first).second], *ep_iter, *this); - ++first; - ++ep_iter; + while (first != last) + { + add_edge(v[(*first).first], v[(*first).second], *ep_iter, *this); + ++first; + ++ep_iter; } - delete [] v; - } - ~adj_list_impl() { + delete[] v; + } + ~adj_list_impl() + { for (typename StoredVertexList::iterator i = m_vertices.begin(); i != m_vertices.end(); ++i) - delete (stored_vertex*)*i; - } - // protected: - inline OutEdgeList& out_edge_list(vertex_descriptor v) { + delete (stored_vertex*)*i; + } + // protected: + inline OutEdgeList& out_edge_list(vertex_descriptor v) + { stored_vertex* sv = (stored_vertex*)v; return sv->m_out_edges; - } - inline const OutEdgeList& out_edge_list(vertex_descriptor v) const { + } + inline const OutEdgeList& out_edge_list(vertex_descriptor v) const + { stored_vertex* sv = (stored_vertex*)v; return sv->m_out_edges; - } - inline StoredVertexList& vertex_set() { return m_vertices; } - inline const StoredVertexList& vertex_set() const { return m_vertices; } + } + inline StoredVertexList& vertex_set() { return m_vertices; } + inline const StoredVertexList& vertex_set() const { return m_vertices; } - inline void copy_impl(const adj_list_impl& x_) - { - const Derived& x = static_cast(x_); + inline void copy_impl(const adj_list_impl& x_) + { + const Derived& x = static_cast< const Derived& >(x_); // Would be better to have a constant time way to get from // vertices in x to the corresponding vertices in *this. - std::map vertex_map; + std::map< stored_vertex*, stored_vertex* > vertex_map; // Copy the stored vertex objects by adding each vertex // and copying its property object. vertex_iterator vi, vi_end; - for (boost::tie(vi, vi_end) = vertices(x); vi != vi_end; ++vi) { - stored_vertex* v = (stored_vertex*)add_vertex(*this); - v->m_property = ((stored_vertex*)*vi)->m_property; - vertex_map[(stored_vertex*)*vi] = v; + for (boost::tie(vi, vi_end) = vertices(x); vi != vi_end; ++vi) + { + stored_vertex* v = (stored_vertex*)add_vertex(*this); + v->m_property = ((stored_vertex*)*vi)->m_property; + vertex_map[(stored_vertex*)*vi] = v; } // Copy the edges by adding each edge and copying its // property object. edge_iterator ei, ei_end; - for (boost::tie(ei, ei_end) = edges(x); ei != ei_end; ++ei) { - edge_descriptor e; - bool inserted; - vertex_descriptor s = source(*ei,x), t = target(*ei,x); - boost::tie(e, inserted) = add_edge(vertex_map[(stored_vertex*)s], - vertex_map[(stored_vertex*)t], *this); - *((edge_property_type*)e.m_eproperty) - = *((edge_property_type*)(*ei).m_eproperty); + for (boost::tie(ei, ei_end) = edges(x); ei != ei_end; ++ei) + { + edge_descriptor e; + bool inserted; + vertex_descriptor s = source(*ei, x), t = target(*ei, x); + boost::tie(e, inserted) = add_edge(vertex_map[(stored_vertex*)s], + vertex_map[(stored_vertex*)t], *this); + *((edge_property_type*)e.m_eproperty) + = *((edge_property_type*)(*ei).m_eproperty); } - } - - - typename Config::EdgeContainer m_edges; - StoredVertexList m_vertices; - }; - - // O(1) - template - inline typename Config::vertex_descriptor - add_vertex(adj_list_impl& g_) - { - Derived& g = static_cast(g_); - typedef typename Config::stored_vertex stored_vertex; - stored_vertex* v = new stored_vertex; - typename Config::StoredVertexList::iterator pos; - bool inserted; - boost::tie(pos,inserted) = boost::graph_detail::push(g.m_vertices, v); - v->m_position = pos; - g.added_vertex(v); - return v; } - // O(1) - template - inline typename Config::vertex_descriptor - add_vertex(const typename Config::vertex_property_type& p, - adj_list_impl& g_) - { - typedef typename Config::vertex_descriptor vertex_descriptor; - Derived& g = static_cast(g_); - if (optional v - = g.vertex_by_property(get_property_value(p, vertex_bundle))) + + typename Config::EdgeContainer m_edges; + StoredVertexList m_vertices; +}; + +// O(1) +template < class Derived, class Config, class Base > +inline typename Config::vertex_descriptor add_vertex( + adj_list_impl< Derived, Config, Base >& g_) +{ + Derived& g = static_cast< Derived& >(g_); + typedef typename Config::stored_vertex stored_vertex; + stored_vertex* v = new stored_vertex; + typename Config::StoredVertexList::iterator pos; + bool inserted; + boost::tie(pos, inserted) = boost::graph_detail::push(g.m_vertices, v); + v->m_position = pos; + g.added_vertex(v); + return v; +} +// O(1) +template < class Derived, class Config, class Base > +inline typename Config::vertex_descriptor add_vertex( + const typename Config::vertex_property_type& p, + adj_list_impl< Derived, Config, Base >& g_) +{ + typedef typename Config::vertex_descriptor vertex_descriptor; + Derived& g = static_cast< Derived& >(g_); + if (optional< vertex_descriptor > v + = g.vertex_by_property(get_property_value(p, vertex_bundle))) return *v; - typedef typename Config::stored_vertex stored_vertex; - stored_vertex* v = new stored_vertex(p); - typename Config::StoredVertexList::iterator pos; - bool inserted; - boost::tie(pos,inserted) = boost::graph_detail::push(g.m_vertices, v); - v->m_position = pos; - g.added_vertex(v); - return v; - } - // O(1) - template - inline void remove_vertex(typename Config::vertex_descriptor u, - adj_list_impl& g_) - { - typedef typename Config::stored_vertex stored_vertex; - Derived& g = static_cast(g_); - g.removing_vertex(u, boost::graph_detail::iterator_stability(g_.m_vertices)); - stored_vertex* su = (stored_vertex*)u; - g.m_vertices.erase(su->m_position); - delete su; - } - // O(V) - template - inline typename Config::vertex_descriptor - vertex(typename Config::vertices_size_type n, - const adj_list_impl& g_) - { - const Derived& g = static_cast(g_); - typename Config::vertex_iterator i = vertices(g).first; - while (n--) ++i; // std::advance(i, n); (not VC++ portable) - return *i; - } + typedef typename Config::stored_vertex stored_vertex; + stored_vertex* v = new stored_vertex(p); + typename Config::StoredVertexList::iterator pos; + bool inserted; + boost::tie(pos, inserted) = boost::graph_detail::push(g.m_vertices, v); + v->m_position = pos; + g.added_vertex(v); + return v; +} +// O(1) +template < class Derived, class Config, class Base > +inline void remove_vertex(typename Config::vertex_descriptor u, + adj_list_impl< Derived, Config, Base >& g_) +{ + typedef typename Config::stored_vertex stored_vertex; + Derived& g = static_cast< Derived& >(g_); + g.removing_vertex( + u, boost::graph_detail::iterator_stability(g_.m_vertices)); + stored_vertex* su = (stored_vertex*)u; + g.m_vertices.erase(su->m_position); + delete su; +} +// O(V) +template < class Derived, class Config, class Base > +inline typename Config::vertex_descriptor vertex( + typename Config::vertices_size_type n, + const adj_list_impl< Derived, Config, Base >& g_) +{ + const Derived& g = static_cast< const Derived& >(g_); + typename Config::vertex_iterator i = vertices(g).first; + while (n--) + ++i; // std::advance(i, n); (not VC++ portable) + return *i; +} - //========================================================================= - // Vector-Backbone Adjacency List Implementation +//========================================================================= +// Vector-Backbone Adjacency List Implementation - namespace detail { +namespace detail +{ - template - inline void - remove_vertex_dispatch(Graph& g, vertex_descriptor u, - boost::directed_tag) - { + template < class Graph, class vertex_descriptor > + inline void remove_vertex_dispatch( + Graph& g, vertex_descriptor u, boost::directed_tag) + { typedef typename Graph::edge_parallel_category edge_parallel_category; g.m_vertices.erase(g.m_vertices.begin() + u); vertex_descriptor V = num_vertices(g); - if (u != V) { - for (vertex_descriptor v = 0; v < V; ++v) - reindex_edge_list(g.out_edge_list(v), u, edge_parallel_category()); + if (u != V) + { + for (vertex_descriptor v = 0; v < V; ++v) + reindex_edge_list( + g.out_edge_list(v), u, edge_parallel_category()); } - } + } - template - inline void - remove_vertex_dispatch(Graph& g, vertex_descriptor u, - boost::undirected_tag) - { + template < class Graph, class vertex_descriptor > + inline void remove_vertex_dispatch( + Graph& g, vertex_descriptor u, boost::undirected_tag) + { typedef typename Graph::global_edgelist_selector EdgeListS; - BOOST_STATIC_ASSERT((!is_same::value)); + BOOST_STATIC_ASSERT((!is_same< EdgeListS, vecS >::value)); typedef typename Graph::edge_parallel_category edge_parallel_category; g.m_vertices.erase(g.m_vertices.begin() + u); vertex_descriptor V = num_vertices(g); for (vertex_descriptor v = 0; v < V; ++v) - reindex_edge_list(g.out_edge_list(v), u, - edge_parallel_category()); + reindex_edge_list(g.out_edge_list(v), u, edge_parallel_category()); typedef typename Graph::EdgeContainer Container; typedef typename Container::iterator Iter; Iter ei = g.m_edges.begin(), ei_end = g.m_edges.end(); - for (; ei != ei_end; ++ei) { - if (ei->m_source > u) - --ei->m_source; - if (ei->m_target > u) - --ei->m_target; + for (; ei != ei_end; ++ei) + { + if (ei->m_source > u) + --ei->m_source; + if (ei->m_target > u) + --ei->m_target; } - } - template - inline void - remove_vertex_dispatch(Graph& g, vertex_descriptor u, - boost::bidirectional_tag) - { + } + template < class Graph, class vertex_descriptor > + inline void remove_vertex_dispatch( + Graph& g, vertex_descriptor u, boost::bidirectional_tag) + { typedef typename Graph::global_edgelist_selector EdgeListS; - BOOST_STATIC_ASSERT((!is_same::value)); + BOOST_STATIC_ASSERT((!is_same< EdgeListS, vecS >::value)); typedef typename Graph::edge_parallel_category edge_parallel_category; g.m_vertices.erase(g.m_vertices.begin() + u); vertex_descriptor V = num_vertices(g); vertex_descriptor v; - if (u != V) { - for (v = 0; v < V; ++v) - reindex_edge_list(g.out_edge_list(v), u, - edge_parallel_category()); - for (v = 0; v < V; ++v) - reindex_edge_list(in_edge_list(g, v), u, - edge_parallel_category()); - - typedef typename Graph::EdgeContainer Container; - typedef typename Container::iterator Iter; - Iter ei = g.m_edges.begin(), ei_end = g.m_edges.end(); - for (; ei != ei_end; ++ei) { - if (ei->m_source > u) - --ei->m_source; - if (ei->m_target > u) - --ei->m_target; - } + if (u != V) + { + for (v = 0; v < V; ++v) + reindex_edge_list( + g.out_edge_list(v), u, edge_parallel_category()); + for (v = 0; v < V; ++v) + reindex_edge_list( + in_edge_list(g, v), u, edge_parallel_category()); + + typedef typename Graph::EdgeContainer Container; + typedef typename Container::iterator Iter; + Iter ei = g.m_edges.begin(), ei_end = g.m_edges.end(); + for (; ei != ei_end; ++ei) + { + if (ei->m_source > u) + --ei->m_source; + if (ei->m_target > u) + --ei->m_target; + } } - } + } - template - inline void - reindex_edge_list(EdgeList& el, vertex_descriptor u, - boost::allow_parallel_edge_tag) - { + template < class EdgeList, class vertex_descriptor > + inline void reindex_edge_list( + EdgeList& el, vertex_descriptor u, boost::allow_parallel_edge_tag) + { typename EdgeList::iterator ei = el.begin(), e_end = el.end(); for (; ei != e_end; ++ei) - if ((*ei).get_target() > u) - --(*ei).get_target(); - } - - template - inline void - reindex_edge_list(EdgeList& el, vertex_descriptor u, - boost::disallow_parallel_edge_tag) - { - for(typename EdgeList::iterator ei = el.begin(); ei != el.end(); ++ei) { - if (ei->get_target() > u) { - typename EdgeList::value_type ce = *ei; - el.erase(ce); - --ce.get_target(); - el.insert(ce); - } + if ((*ei).get_target() > u) + --(*ei).get_target(); + } + + template < class EdgeList, class vertex_descriptor > + inline void reindex_edge_list( + EdgeList& el, vertex_descriptor u, boost::disallow_parallel_edge_tag) + { + for (typename EdgeList::iterator ei = el.begin(); ei != el.end(); ++ei) + { + if (ei->get_target() > u) + { + typename EdgeList::value_type ce = *ei; + el.erase(ce); + --ce.get_target(); + el.insert(ce); + } } - } - } // namespace detail + } +} // namespace detail - struct vec_adj_list_tag { }; +struct vec_adj_list_tag +{ +}; - template - class vec_adj_list_impl - : public adj_list_helper +template < class Graph, class Config, class Base > +class vec_adj_list_impl : public adj_list_helper< Config, Base > +{ + typedef typename Config::OutEdgeList OutEdgeList; + typedef typename Config::InEdgeList InEdgeList; + typedef typename Config::StoredVertexList StoredVertexList; + +public: + typedef typename Config::vertex_descriptor vertex_descriptor; + typedef typename Config::edge_descriptor edge_descriptor; + typedef typename Config::out_edge_iterator out_edge_iterator; + typedef typename Config::edge_iterator edge_iterator; + typedef typename Config::directed_category directed_category; + typedef typename Config::vertices_size_type vertices_size_type; + typedef typename Config::edges_size_type edges_size_type; + typedef typename Config::degree_size_type degree_size_type; + typedef typename Config::StoredEdge StoredEdge; + typedef typename Config::stored_vertex stored_vertex; + typedef typename Config::EdgeContainer EdgeContainer; + typedef typename Config::edge_property_type edge_property_type; + typedef vec_adj_list_tag graph_tag; + + static vertex_descriptor null_vertex() + { + return (std::numeric_limits< vertex_descriptor >::max)(); + } + + inline vec_adj_list_impl() {} + + inline vec_adj_list_impl(const vec_adj_list_impl& x) { copy_impl(x); } + inline vec_adj_list_impl& operator=(const vec_adj_list_impl& x) { - typedef typename Config::OutEdgeList OutEdgeList; - typedef typename Config::InEdgeList InEdgeList; - typedef typename Config::StoredVertexList StoredVertexList; - public: - typedef typename Config::vertex_descriptor vertex_descriptor; - typedef typename Config::edge_descriptor edge_descriptor; - typedef typename Config::out_edge_iterator out_edge_iterator; - typedef typename Config::edge_iterator edge_iterator; - typedef typename Config::directed_category directed_category; - typedef typename Config::vertices_size_type vertices_size_type; - typedef typename Config::edges_size_type edges_size_type; - typedef typename Config::degree_size_type degree_size_type; - typedef typename Config::StoredEdge StoredEdge; - typedef typename Config::stored_vertex stored_vertex; - typedef typename Config::EdgeContainer EdgeContainer; - typedef typename Config::edge_property_type edge_property_type; - typedef vec_adj_list_tag graph_tag; - - static vertex_descriptor null_vertex() - { - return (std::numeric_limits::max)(); - } - - inline vec_adj_list_impl() { } - - inline vec_adj_list_impl(const vec_adj_list_impl& x) { - copy_impl(x); - } - inline vec_adj_list_impl& operator=(const vec_adj_list_impl& x) { this->clear(); copy_impl(x); return *this; - } - inline void clear() { + } + inline void clear() + { m_vertices.clear(); m_edges.clear(); - } - - inline vec_adj_list_impl(vertices_size_type _num_vertices) - : m_vertices(_num_vertices) { } - - template - inline vec_adj_list_impl(vertices_size_type num_vertices, - EdgeIterator first, EdgeIterator last) - : m_vertices(num_vertices) - { - while (first != last) { - add_edge((*first).first, (*first).second, - static_cast(*this)); - ++first; + } + + inline vec_adj_list_impl(vertices_size_type _num_vertices) + : m_vertices(_num_vertices) + { + } + + template < class EdgeIterator > + inline vec_adj_list_impl( + vertices_size_type num_vertices, EdgeIterator first, EdgeIterator last) + : m_vertices(num_vertices) + { + while (first != last) + { + add_edge( + (*first).first, (*first).second, static_cast< Graph& >(*this)); + ++first; } - } - template - inline vec_adj_list_impl(vertices_size_type num_vertices, - EdgeIterator first, EdgeIterator last, - EdgePropertyIterator ep_iter) - : m_vertices(num_vertices) - { - while (first != last) { - add_edge((*first).first, (*first).second, *ep_iter, - static_cast(*this)); - ++first; - ++ep_iter; + } + template < class EdgeIterator, class EdgePropertyIterator > + inline vec_adj_list_impl(vertices_size_type num_vertices, + EdgeIterator first, EdgeIterator last, EdgePropertyIterator ep_iter) + : m_vertices(num_vertices) + { + while (first != last) + { + add_edge((*first).first, (*first).second, *ep_iter, + static_cast< Graph& >(*this)); + ++first; + ++ep_iter; } - } + } - // protected: - inline boost::integer_range vertex_set() const { - return boost::integer_range(0, m_vertices.size()); - } - inline OutEdgeList& out_edge_list(vertex_descriptor v) { + // protected: + inline boost::integer_range< vertex_descriptor > vertex_set() const + { + return boost::integer_range< vertex_descriptor >(0, m_vertices.size()); + } + inline OutEdgeList& out_edge_list(vertex_descriptor v) + { return m_vertices[v].m_out_edges; - } - inline const OutEdgeList& out_edge_list(vertex_descriptor v) const { + } + inline const OutEdgeList& out_edge_list(vertex_descriptor v) const + { return m_vertices[v].m_out_edges; - } - inline void copy_impl(const vec_adj_list_impl& x_) - { - const Graph& x = static_cast(x_); + } + inline void copy_impl(const vec_adj_list_impl& x_) + { + const Graph& x = static_cast< const Graph& >(x_); // Copy the stored vertex objects by adding each vertex // and copying its property object. - for (vertices_size_type i = 0; i < num_vertices(x); ++i) { - vertex_descriptor v = add_vertex(*this); - m_vertices[v].m_property = x.m_vertices[i].m_property; + for (vertices_size_type i = 0; i < num_vertices(x); ++i) + { + vertex_descriptor v = add_vertex(*this); + m_vertices[v].m_property = x.m_vertices[i].m_property; } // Copy the edges by adding each edge and copying its // property object. edge_iterator ei, ei_end; - for (boost::tie(ei, ei_end) = edges(x); ei != ei_end; ++ei) { - edge_descriptor e; - bool inserted; - boost::tie(e, inserted) = add_edge(source(*ei,x), target(*ei,x) , *this); - *((edge_property_type*)e.m_eproperty) - = *((edge_property_type*)(*ei).m_eproperty); + for (boost::tie(ei, ei_end) = edges(x); ei != ei_end; ++ei) + { + edge_descriptor e; + bool inserted; + boost::tie(e, inserted) + = add_edge(source(*ei, x), target(*ei, x), *this); + *((edge_property_type*)e.m_eproperty) + = *((edge_property_type*)(*ei).m_eproperty); } - } - typename Config::EdgeContainer m_edges; - StoredVertexList m_vertices; - }; - // Had to make these non-members to avoid accidental instantiation - // on SGI MIPSpro C++ - template - inline typename C::InEdgeList& - in_edge_list(vec_adj_list_impl& g, - typename C::vertex_descriptor v) { - return g.m_vertices[v].m_in_edges; - } - template - inline const typename C::InEdgeList& - in_edge_list(const vec_adj_list_impl& g, - typename C::vertex_descriptor v) { - return g.m_vertices[v].m_in_edges; - } - - // O(1) - template - inline typename Config::vertex_descriptor - add_vertex(vec_adj_list_impl& g_) { - Graph& g = static_cast(g_); - g.m_vertices.resize(g.m_vertices.size() + 1); - g.added_vertex(g.m_vertices.size() - 1); - return g.m_vertices.size() - 1; - } - - template - inline typename Config::vertex_descriptor - add_vertex(const typename Config::vertex_property_type& p, - vec_adj_list_impl& g_) { - typedef typename Config::vertex_descriptor vertex_descriptor; - Graph& g = static_cast(g_); - if (optional v - = g.vertex_by_property(get_property_value(p, vertex_bundle))) - return *v; - typedef typename Config::stored_vertex stored_vertex; - g.m_vertices.push_back(stored_vertex(p)); - g.added_vertex(g.m_vertices.size() - 1); - return g.m_vertices.size() - 1; - } - - // Here we override the directed_graph_helper add_edge() function - // so that the number of vertices is automatically changed if - // either u or v is greater than the number of vertices. - template - inline std::pair - add_edge(typename Config::vertex_descriptor u, - typename Config::vertex_descriptor v, - const typename Config::edge_property_type& p, - vec_adj_list_impl& g_) - { - BOOST_USING_STD_MAX(); - typename Config::vertex_descriptor x = max BOOST_PREVENT_MACRO_SUBSTITUTION(u, v); - if (x >= num_vertices(g_)) - g_.m_vertices.resize(x + 1); - adj_list_helper& g = g_; - return add_edge(u, v, p, g); - } - template - inline std::pair - add_edge(typename Config::vertex_descriptor u, - typename Config::vertex_descriptor v, - vec_adj_list_impl& g_) - { - typename Config::edge_property_type p; - return add_edge(u, v, p, g_); } + typename Config::EdgeContainer m_edges; + StoredVertexList m_vertices; +}; +// Had to make these non-members to avoid accidental instantiation +// on SGI MIPSpro C++ +template < class G, class C, class B > +inline typename C::InEdgeList& in_edge_list( + vec_adj_list_impl< G, C, B >& g, typename C::vertex_descriptor v) +{ + return g.m_vertices[v].m_in_edges; +} +template < class G, class C, class B > +inline const typename C::InEdgeList& in_edge_list( + const vec_adj_list_impl< G, C, B >& g, typename C::vertex_descriptor v) +{ + return g.m_vertices[v].m_in_edges; +} +// O(1) +template < class Graph, class Config, class Base > +inline typename Config::vertex_descriptor add_vertex( + vec_adj_list_impl< Graph, Config, Base >& g_) +{ + Graph& g = static_cast< Graph& >(g_); + g.m_vertices.resize(g.m_vertices.size() + 1); + g.added_vertex(g.m_vertices.size() - 1); + return g.m_vertices.size() - 1; +} - // O(V + E) - template - inline void remove_vertex(typename Config::vertex_descriptor v, - vec_adj_list_impl& g_) - { - typedef typename Config::directed_category Cat; - Graph& g = static_cast(g_); - g.removing_vertex(v, boost::graph_detail::iterator_stability(g_.m_vertices)); - detail::remove_vertex_dispatch(g, v, Cat()); - } - // O(1) - template - inline typename Config::vertex_descriptor - vertex(typename Config::vertices_size_type n, - const vec_adj_list_impl&) - { - return n; - } +template < class Graph, class Config, class Base > +inline typename Config::vertex_descriptor add_vertex( + const typename Config::vertex_property_type& p, + vec_adj_list_impl< Graph, Config, Base >& g_) +{ + typedef typename Config::vertex_descriptor vertex_descriptor; + Graph& g = static_cast< Graph& >(g_); + if (optional< vertex_descriptor > v + = g.vertex_by_property(get_property_value(p, vertex_bundle))) + return *v; + typedef typename Config::stored_vertex stored_vertex; + g.m_vertices.push_back(stored_vertex(p)); + g.added_vertex(g.m_vertices.size() - 1); + return g.m_vertices.size() - 1; +} + +// Here we override the directed_graph_helper add_edge() function +// so that the number of vertices is automatically changed if +// either u or v is greater than the number of vertices. +template < class Graph, class Config, class Base > +inline std::pair< typename Config::edge_descriptor, bool > add_edge( + typename Config::vertex_descriptor u, typename Config::vertex_descriptor v, + const typename Config::edge_property_type& p, + vec_adj_list_impl< Graph, Config, Base >& g_) +{ + BOOST_USING_STD_MAX(); + typename Config::vertex_descriptor x + = max BOOST_PREVENT_MACRO_SUBSTITUTION(u, v); + if (x >= num_vertices(g_)) + g_.m_vertices.resize(x + 1); + adj_list_helper< Config, Base >& g = g_; + return add_edge(u, v, p, g); +} +template < class Graph, class Config, class Base > +inline std::pair< typename Config::edge_descriptor, bool > add_edge( + typename Config::vertex_descriptor u, typename Config::vertex_descriptor v, + vec_adj_list_impl< Graph, Config, Base >& g_) +{ + typename Config::edge_property_type p; + return add_edge(u, v, p, g_); +} +// O(V + E) +template < class Graph, class Config, class Base > +inline void remove_vertex(typename Config::vertex_descriptor v, + vec_adj_list_impl< Graph, Config, Base >& g_) +{ + typedef typename Config::directed_category Cat; + Graph& g = static_cast< Graph& >(g_); + g.removing_vertex( + v, boost::graph_detail::iterator_stability(g_.m_vertices)); + detail::remove_vertex_dispatch(g, v, Cat()); +} +// O(1) +template < class Graph, class Config, class Base > +inline typename Config::vertex_descriptor vertex( + typename Config::vertices_size_type n, + const vec_adj_list_impl< Graph, Config, Base >&) +{ + return n; +} - namespace detail { +namespace detail +{ //========================================================================= // Adjacency List Generator - template + template < class Graph, class VertexListS, class OutEdgeListS, + class DirectedS, class VertexProperty, class EdgeProperty, + class GraphProperty, class EdgeListS > struct adj_list_gen { - typedef typename detail::is_random_access::type - is_rand_access; - typedef typename has_property::type has_edge_property; - typedef typename DirectedS::is_directed_t DirectedT; - typedef typename DirectedS::is_bidir_t BidirectionalT; - - struct config - { - typedef OutEdgeListS edgelist_selector; - typedef EdgeListS global_edgelist_selector; - - typedef Graph graph_type; - typedef EdgeProperty edge_property_type; - typedef VertexProperty vertex_property_type; - typedef GraphProperty graph_property_type; - typedef std::size_t vertices_size_type; - - typedef adjacency_list_traits - Traits; - - typedef typename Traits::directed_category directed_category; - typedef typename Traits::edge_parallel_category edge_parallel_category; - typedef typename Traits::vertex_descriptor vertex_descriptor; - typedef typename Traits::edge_descriptor edge_descriptor; + typedef typename detail::is_random_access< VertexListS >::type + is_rand_access; + typedef typename has_property< EdgeProperty >::type has_edge_property; + typedef typename DirectedS::is_directed_t DirectedT; + typedef typename DirectedS::is_bidir_t BidirectionalT; - typedef void* vertex_ptr; - - // need to reorganize this to avoid instantiating stuff - // that doesn't get used -JGS - - // VertexList and vertex_iterator - typedef typename container_gen::type SeqVertexList; - typedef boost::integer_range RandVertexList; - typedef typename mpl::if_::type VertexList; - - typedef typename VertexList::iterator vertex_iterator; - - // EdgeContainer and StoredEdge - - typedef typename container_gen >::type EdgeContainer; - - typedef typename mpl::and_::type >::type on_edge_storage; - - typedef typename mpl::if_::type edges_size_type; - - typedef typename EdgeContainer::iterator EdgeIter; - - typedef typename detail::is_random_access::type is_edge_ra; - - typedef typename mpl::if_, - typename mpl::if_, - stored_edge_iter - >::type - >::type StoredEdge; - - // Adjacency Types - - typedef typename container_gen::type - OutEdgeList; - typedef typename OutEdgeList::size_type degree_size_type; - typedef typename OutEdgeList::iterator OutEdgeIter; - - typedef boost::detail::iterator_traits OutEdgeIterTraits; - typedef typename OutEdgeIterTraits::iterator_category OutEdgeIterCat; - typedef typename OutEdgeIterTraits::difference_type OutEdgeIterDiff; - - typedef out_edge_iter< - OutEdgeIter, vertex_descriptor, edge_descriptor, OutEdgeIterDiff - > out_edge_iterator; - - typedef typename adjacency_iterator_generator::type adjacency_iterator; - - typedef OutEdgeList InEdgeList; - typedef OutEdgeIter InEdgeIter; - typedef OutEdgeIterCat InEdgeIterCat; - typedef OutEdgeIterDiff InEdgeIterDiff; - - typedef in_edge_iter< - InEdgeIter, vertex_descriptor, edge_descriptor, InEdgeIterDiff - > in_edge_iterator; - - typedef typename inv_adjacency_iterator_generator::type inv_adjacency_iterator; - - // Edge Iterator - - typedef boost::detail::iterator_traits EdgeIterTraits; - typedef typename EdgeIterTraits::iterator_category EdgeIterCat; - typedef typename EdgeIterTraits::difference_type EdgeIterDiff; - - typedef undirected_edge_iter< - EdgeIter - , edge_descriptor - , EdgeIterDiff - > UndirectedEdgeIter; // also used for bidirectional + struct config + { + typedef OutEdgeListS edgelist_selector; + typedef EdgeListS global_edgelist_selector; - typedef adj_list_edge_iterator DirectedEdgeIter; + typedef Graph graph_type; + typedef EdgeProperty edge_property_type; + typedef VertexProperty vertex_property_type; + typedef GraphProperty graph_property_type; + typedef std::size_t vertices_size_type; - typedef typename mpl::if_::type edge_iterator; + typedef adjacency_list_traits< OutEdgeListS, VertexListS, + DirectedS > + Traits; - // stored_vertex and StoredVertexList - typedef typename container_gen::type - SeqStoredVertexList; - struct seq_stored_vertex { - seq_stored_vertex() { } - seq_stored_vertex(const VertexProperty& p) : m_property(p) { } - OutEdgeList m_out_edges; - VertexProperty m_property; - typename SeqStoredVertexList::iterator m_position; - }; - struct bidir_seq_stored_vertex { - bidir_seq_stored_vertex() { } - bidir_seq_stored_vertex(const VertexProperty& p) : m_property(p) { } - OutEdgeList m_out_edges; - InEdgeList m_in_edges; - VertexProperty m_property; - typename SeqStoredVertexList::iterator m_position; - }; - struct rand_stored_vertex { - rand_stored_vertex() { } - rand_stored_vertex(const VertexProperty& p) : m_property(p) { } - OutEdgeList m_out_edges; - VertexProperty m_property; - }; - struct bidir_rand_stored_vertex { - bidir_rand_stored_vertex() { } - bidir_rand_stored_vertex(const VertexProperty& p) : m_property(p) { } - OutEdgeList m_out_edges; - InEdgeList m_in_edges; - VertexProperty m_property; - }; - typedef typename mpl::if_::type, - typename mpl::if_::type - >::type StoredVertex; - struct stored_vertex : public StoredVertex { - stored_vertex() { } - stored_vertex(const VertexProperty& p) : StoredVertex(p) { } - }; + typedef typename Traits::directed_category directed_category; + typedef + typename Traits::edge_parallel_category edge_parallel_category; + typedef typename Traits::vertex_descriptor vertex_descriptor; + typedef typename Traits::edge_descriptor edge_descriptor; + + typedef void* vertex_ptr; + + // need to reorganize this to avoid instantiating stuff + // that doesn't get used -JGS + + // VertexList and vertex_iterator + typedef typename container_gen< VertexListS, vertex_ptr >::type + SeqVertexList; + typedef boost::integer_range< vertex_descriptor > RandVertexList; + typedef typename mpl::if_< is_rand_access, RandVertexList, + SeqVertexList >::type VertexList; + + typedef typename VertexList::iterator vertex_iterator; + + // EdgeContainer and StoredEdge + + typedef typename container_gen< EdgeListS, + list_edge< vertex_descriptor, EdgeProperty > >::type + EdgeContainer; + + typedef typename mpl::and_< DirectedT, + typename mpl::not_< BidirectionalT >::type >::type + on_edge_storage; + + typedef typename mpl::if_< on_edge_storage, std::size_t, + typename EdgeContainer::size_type >::type edges_size_type; + + typedef typename EdgeContainer::iterator EdgeIter; + + typedef + typename detail::is_random_access< EdgeListS >::type is_edge_ra; + + typedef typename mpl::if_< on_edge_storage, + stored_edge_property< vertex_descriptor, EdgeProperty >, + typename mpl::if_< is_edge_ra, + stored_ra_edge_iter< vertex_descriptor, EdgeContainer, + EdgeProperty >, + stored_edge_iter< vertex_descriptor, EdgeIter, + EdgeProperty > >::type >::type StoredEdge; + + // Adjacency Types + + typedef typename container_gen< OutEdgeListS, StoredEdge >::type + OutEdgeList; + typedef typename OutEdgeList::size_type degree_size_type; + typedef typename OutEdgeList::iterator OutEdgeIter; + + typedef boost::detail::iterator_traits< OutEdgeIter > + OutEdgeIterTraits; + typedef + typename OutEdgeIterTraits::iterator_category OutEdgeIterCat; + typedef typename OutEdgeIterTraits::difference_type OutEdgeIterDiff; + + typedef out_edge_iter< OutEdgeIter, vertex_descriptor, + edge_descriptor, OutEdgeIterDiff > + out_edge_iterator; + + typedef typename adjacency_iterator_generator< graph_type, + vertex_descriptor, out_edge_iterator >::type adjacency_iterator; + + typedef OutEdgeList InEdgeList; + typedef OutEdgeIter InEdgeIter; + typedef OutEdgeIterCat InEdgeIterCat; + typedef OutEdgeIterDiff InEdgeIterDiff; + + typedef in_edge_iter< InEdgeIter, vertex_descriptor, + edge_descriptor, InEdgeIterDiff > + in_edge_iterator; + + typedef typename inv_adjacency_iterator_generator< graph_type, + vertex_descriptor, in_edge_iterator >::type + inv_adjacency_iterator; + + // Edge Iterator + + typedef boost::detail::iterator_traits< EdgeIter > EdgeIterTraits; + typedef typename EdgeIterTraits::iterator_category EdgeIterCat; + typedef typename EdgeIterTraits::difference_type EdgeIterDiff; + + typedef undirected_edge_iter< EdgeIter, edge_descriptor, + EdgeIterDiff > + UndirectedEdgeIter; // also used for bidirectional + + typedef adj_list_edge_iterator< vertex_iterator, out_edge_iterator, + graph_type > + DirectedEdgeIter; + + typedef typename mpl::if_< on_edge_storage, DirectedEdgeIter, + UndirectedEdgeIter >::type edge_iterator; + + // stored_vertex and StoredVertexList + typedef typename container_gen< VertexListS, vertex_ptr >::type + SeqStoredVertexList; + struct seq_stored_vertex + { + seq_stored_vertex() {} + seq_stored_vertex(const VertexProperty& p) : m_property(p) {} + OutEdgeList m_out_edges; + VertexProperty m_property; + typename SeqStoredVertexList::iterator m_position; + }; + struct bidir_seq_stored_vertex + { + bidir_seq_stored_vertex() {} + bidir_seq_stored_vertex(const VertexProperty& p) : m_property(p) + { + } + OutEdgeList m_out_edges; + InEdgeList m_in_edges; + VertexProperty m_property; + typename SeqStoredVertexList::iterator m_position; + }; + struct rand_stored_vertex + { + rand_stored_vertex() {} + rand_stored_vertex(const VertexProperty& p) : m_property(p) {} + OutEdgeList m_out_edges; + VertexProperty m_property; + }; + struct bidir_rand_stored_vertex + { + bidir_rand_stored_vertex() {} + bidir_rand_stored_vertex(const VertexProperty& p) + : m_property(p) + { + } + OutEdgeList m_out_edges; + InEdgeList m_in_edges; + VertexProperty m_property; + }; + typedef typename mpl::if_< is_rand_access, + typename mpl::if_< BidirectionalT, bidir_rand_stored_vertex, + rand_stored_vertex >::type, + typename mpl::if_< BidirectionalT, bidir_seq_stored_vertex, + seq_stored_vertex >::type >::type StoredVertex; + struct stored_vertex : public StoredVertex + { + stored_vertex() {} + stored_vertex(const VertexProperty& p) : StoredVertex(p) {} + }; + + typedef typename container_gen< VertexListS, stored_vertex >::type + RandStoredVertexList; + typedef typename mpl::if_< is_rand_access, RandStoredVertexList, + SeqStoredVertexList >::type StoredVertexList; + }; // end of config + + typedef typename mpl::if_< BidirectionalT, + bidirectional_graph_helper_with_property< config >, + typename mpl::if_< DirectedT, directed_graph_helper< config >, + undirected_graph_helper< config > >::type >::type + DirectedHelper; - typedef typename container_gen::type - RandStoredVertexList; typedef typename mpl::if_< is_rand_access, - RandStoredVertexList, SeqStoredVertexList>::type StoredVertexList; - }; // end of config - - - typedef typename mpl::if_, - typename mpl::if_, - undirected_graph_helper - >::type - >::type DirectedHelper; - - typedef typename mpl::if_, - adj_list_impl - >::type type; - + vec_adj_list_impl< Graph, config, DirectedHelper >, + adj_list_impl< Graph, config, DirectedHelper > >::type type; }; - } // namespace detail +} // namespace detail - //========================================================================= - // Vertex Property Maps - - template - struct adj_list_vertex_property_map - : public boost::put_get_helper< - Reference, - adj_list_vertex_property_map - > - { - typedef typename Graph::stored_vertex StoredVertex; - typedef ValueType value_type; - typedef Reference reference; - typedef typename Graph::vertex_descriptor key_type; - typedef boost::lvalue_property_map_tag category; - inline adj_list_vertex_property_map(const Graph* = 0, Tag tag = Tag()): m_tag(tag) { } - inline Reference operator[](key_type v) const { +//========================================================================= +// Vertex Property Maps + +template < class Graph, class ValueType, class Reference, class Tag > +struct adj_list_vertex_property_map +: public boost::put_get_helper< Reference, + adj_list_vertex_property_map< Graph, ValueType, Reference, Tag > > +{ + typedef typename Graph::stored_vertex StoredVertex; + typedef ValueType value_type; + typedef Reference reference; + typedef typename Graph::vertex_descriptor key_type; + typedef boost::lvalue_property_map_tag category; + inline adj_list_vertex_property_map(const Graph* = 0, Tag tag = Tag()) + : m_tag(tag) + { + } + inline Reference operator[](key_type v) const + { StoredVertex* sv = (StoredVertex*)v; return get_property_value(sv->m_property, m_tag); - } - inline Reference operator()(key_type v) const { + } + inline Reference operator()(key_type v) const + { return this->operator[](v); - } - Tag m_tag; - }; + } + Tag m_tag; +}; - template - struct adj_list_vertex_all_properties_map - : public boost::put_get_helper - > - { - typedef typename Graph::stored_vertex StoredVertex; - typedef Property value_type; - typedef PropRef reference; - typedef typename Graph::vertex_descriptor key_type; - typedef boost::lvalue_property_map_tag category; - inline adj_list_vertex_all_properties_map(const Graph* = 0, vertex_all_t = vertex_all_t()) { } - inline PropRef operator[](key_type v) const { +template < class Graph, class Property, class PropRef > +struct adj_list_vertex_all_properties_map +: public boost::put_get_helper< PropRef, + adj_list_vertex_all_properties_map< Graph, Property, PropRef > > +{ + typedef typename Graph::stored_vertex StoredVertex; + typedef Property value_type; + typedef PropRef reference; + typedef typename Graph::vertex_descriptor key_type; + typedef boost::lvalue_property_map_tag category; + inline adj_list_vertex_all_properties_map( + const Graph* = 0, vertex_all_t = vertex_all_t()) + { + } + inline PropRef operator[](key_type v) const + { StoredVertex* sv = (StoredVertex*)v; return sv->m_property; - } - inline PropRef operator()(key_type v) const { - return this->operator[](v); - } - }; + } + inline PropRef operator()(key_type v) const { return this->operator[](v); } +}; - template - struct vec_adj_list_vertex_property_map - : public boost::put_get_helper< - Reference, - vec_adj_list_vertex_property_map - > - { - typedef ValueType value_type; - typedef Reference reference; - typedef typename boost::graph_traits::vertex_descriptor key_type; - typedef boost::lvalue_property_map_tag category; - vec_adj_list_vertex_property_map(GraphPtr g = 0, Tag tag = Tag()) : m_g(g), m_tag(tag) { } - inline Reference operator[](key_type v) const { +template < class Graph, class GraphPtr, class ValueType, class Reference, + class Tag > +struct vec_adj_list_vertex_property_map +: public boost::put_get_helper< Reference, + vec_adj_list_vertex_property_map< Graph, GraphPtr, ValueType, Reference, + Tag > > +{ + typedef ValueType value_type; + typedef Reference reference; + typedef typename boost::graph_traits< Graph >::vertex_descriptor key_type; + typedef boost::lvalue_property_map_tag category; + vec_adj_list_vertex_property_map(GraphPtr g = 0, Tag tag = Tag()) + : m_g(g), m_tag(tag) + { + } + inline Reference operator[](key_type v) const + { return get_property_value(m_g->m_vertices[v].m_property, m_tag); - } - inline Reference operator()(key_type v) const { + } + inline Reference operator()(key_type v) const + { return this->operator[](v); - } - GraphPtr m_g; - Tag m_tag; - }; + } + GraphPtr m_g; + Tag m_tag; +}; - template - struct vec_adj_list_vertex_all_properties_map - : public boost::put_get_helper - > - { - typedef Property value_type; - typedef PropertyRef reference; - typedef typename boost::graph_traits::vertex_descriptor key_type; - typedef boost::lvalue_property_map_tag category; - vec_adj_list_vertex_all_properties_map(GraphPtr g = 0, vertex_all_t = vertex_all_t()) : m_g(g) { } - inline PropertyRef operator[](key_type v) const { +template < class Graph, class GraphPtr, class Property, class PropertyRef > +struct vec_adj_list_vertex_all_properties_map +: public boost::put_get_helper< PropertyRef, + vec_adj_list_vertex_all_properties_map< Graph, GraphPtr, Property, + PropertyRef > > +{ + typedef Property value_type; + typedef PropertyRef reference; + typedef typename boost::graph_traits< Graph >::vertex_descriptor key_type; + typedef boost::lvalue_property_map_tag category; + vec_adj_list_vertex_all_properties_map( + GraphPtr g = 0, vertex_all_t = vertex_all_t()) + : m_g(g) + { + } + inline PropertyRef operator[](key_type v) const + { return m_g->m_vertices[v].m_property; - } - inline PropertyRef operator()(key_type v) const { + } + inline PropertyRef operator()(key_type v) const + { return this->operator[](v); - } - GraphPtr m_g; - }; + } + GraphPtr m_g; +}; - struct adj_list_any_vertex_pa { - template - struct bind_ { - typedef typename property_value::type value_type; +struct adj_list_any_vertex_pa +{ + template < class Tag, class Graph, class Property > struct bind_ + { + typedef typename property_value< Property, Tag >::type value_type; typedef value_type& reference; typedef const value_type& const_reference; - typedef adj_list_vertex_property_map - type; - typedef adj_list_vertex_property_map - const_type; - }; + typedef adj_list_vertex_property_map< Graph, value_type, reference, + Tag > + type; + typedef adj_list_vertex_property_map< Graph, value_type, + const_reference, Tag > + const_type; }; - struct adj_list_all_vertex_pa { - template - struct bind_ { +}; +struct adj_list_all_vertex_pa +{ + template < class Tag, class Graph, class Property > struct bind_ + { typedef typename Graph::vertex_descriptor Vertex; - typedef adj_list_vertex_all_properties_map type; - typedef adj_list_vertex_all_properties_map const_type; - }; - }; - - template - struct vec_adj_list_vertex_id_map - : public boost::put_get_helper< - Vertex, vec_adj_list_vertex_id_map - > - { - typedef Vertex value_type; - typedef Vertex key_type; - typedef Vertex reference; - typedef boost::readable_property_map_tag category; - inline vec_adj_list_vertex_id_map() { } - template - inline vec_adj_list_vertex_id_map(const Graph&, vertex_index_t) { } - inline value_type operator[](key_type v) const { return v; } - inline value_type operator()(key_type v) const { return v; } + typedef adj_list_vertex_all_properties_map< Graph, Property, Property& > + type; + typedef adj_list_vertex_all_properties_map< Graph, Property, + const Property& > + const_type; }; - - struct vec_adj_list_any_vertex_pa { - template - struct bind_ { - typedef typename property_value::type value_type; +}; + +template < class Property, class Vertex > +struct vec_adj_list_vertex_id_map +: public boost::put_get_helper< Vertex, + vec_adj_list_vertex_id_map< Property, Vertex > > +{ + typedef Vertex value_type; + typedef Vertex key_type; + typedef Vertex reference; + typedef boost::readable_property_map_tag category; + inline vec_adj_list_vertex_id_map() {} + template < class Graph > + inline vec_adj_list_vertex_id_map(const Graph&, vertex_index_t) + { + } + inline value_type operator[](key_type v) const { return v; } + inline value_type operator()(key_type v) const { return v; } +}; + +struct vec_adj_list_any_vertex_pa +{ + template < class Tag, class Graph, class Property > struct bind_ + { + typedef typename property_value< Property, Tag >::type value_type; typedef value_type& reference; typedef const value_type& const_reference; - typedef vec_adj_list_vertex_property_map - type; - typedef vec_adj_list_vertex_property_map - const_type; - }; + typedef vec_adj_list_vertex_property_map< Graph, Graph*, value_type, + reference, Tag > + type; + typedef vec_adj_list_vertex_property_map< Graph, const Graph*, + value_type, const_reference, Tag > + const_type; }; - struct vec_adj_list_id_vertex_pa { - template - struct bind_ { +}; +struct vec_adj_list_id_vertex_pa +{ + template < class Tag, class Graph, class Property > struct bind_ + { typedef typename Graph::vertex_descriptor Vertex; - typedef vec_adj_list_vertex_id_map type; - typedef vec_adj_list_vertex_id_map const_type; - }; + typedef vec_adj_list_vertex_id_map< Property, Vertex > type; + typedef vec_adj_list_vertex_id_map< Property, Vertex > const_type; }; - struct vec_adj_list_all_vertex_pa { - template - struct bind_ { +}; +struct vec_adj_list_all_vertex_pa +{ + template < class Tag, class Graph, class Property > struct bind_ + { typedef typename Graph::vertex_descriptor Vertex; - typedef vec_adj_list_vertex_all_properties_map - type; - typedef vec_adj_list_vertex_all_properties_map - const_type; - }; + typedef vec_adj_list_vertex_all_properties_map< Graph, Graph*, Property, + Property& > + type; + typedef vec_adj_list_vertex_all_properties_map< Graph, const Graph*, + Property, const Property& > + const_type; }; - namespace detail { - template +}; +namespace detail +{ + template < class Tag, class Graph, class Property > struct adj_list_choose_vertex_pa - : boost::mpl::if_< - boost::is_same, - adj_list_all_vertex_pa, - adj_list_any_vertex_pa>::type - ::template bind_ - {}; - + : boost::mpl::if_< boost::is_same< Tag, vertex_all_t >, + adj_list_all_vertex_pa, adj_list_any_vertex_pa >::type :: + template bind_< Tag, Graph, Property > + { + }; - template - struct vec_adj_list_choose_vertex_pa_helper { - typedef vec_adj_list_any_vertex_pa type; + template < class Tag > struct vec_adj_list_choose_vertex_pa_helper + { + typedef vec_adj_list_any_vertex_pa type; }; - template <> - struct vec_adj_list_choose_vertex_pa_helper { - typedef vec_adj_list_id_vertex_pa type; + template <> struct vec_adj_list_choose_vertex_pa_helper< vertex_index_t > + { + typedef vec_adj_list_id_vertex_pa type; }; - template <> - struct vec_adj_list_choose_vertex_pa_helper { - typedef vec_adj_list_all_vertex_pa type; + template <> struct vec_adj_list_choose_vertex_pa_helper< vertex_all_t > + { + typedef vec_adj_list_all_vertex_pa type; }; - template + template < class Tag, class Graph, class Property > struct vec_adj_list_choose_vertex_pa - : vec_adj_list_choose_vertex_pa_helper::type::template bind_ - {}; - } // namespace detail - - //========================================================================= - // Edge Property Map - - template - struct adj_list_edge_property_map - : public put_get_helper< - Ref, - adj_list_edge_property_map - > - { - Tag tag; - explicit adj_list_edge_property_map(Tag tag = Tag()): tag(tag) {} - - typedef Value value_type; - typedef Ref reference; - typedef detail::edge_desc_impl key_type; - typedef boost::lvalue_property_map_tag category; - inline Ref operator[](key_type e) const { + : vec_adj_list_choose_vertex_pa_helper< Tag >::type::template bind_< Tag, + Graph, Property > + { + }; +} // namespace detail + +//========================================================================= +// Edge Property Map + +template < class Directed, class Value, class Ref, class Vertex, class Property, + class Tag > +struct adj_list_edge_property_map +: public put_get_helper< Ref, + adj_list_edge_property_map< Directed, Value, Ref, Vertex, Property, + Tag > > +{ + Tag tag; + explicit adj_list_edge_property_map(Tag tag = Tag()) : tag(tag) {} + + typedef Value value_type; + typedef Ref reference; + typedef detail::edge_desc_impl< Directed, Vertex > key_type; + typedef boost::lvalue_property_map_tag category; + inline Ref operator[](key_type e) const + { Property& p = *(Property*)e.get_property(); return get_property_value(p, tag); - } - inline Ref operator()(key_type e) const { - return this->operator[](e); - } - }; - - template - struct adj_list_edge_all_properties_map - : public put_get_helper - > - { - explicit adj_list_edge_all_properties_map(edge_all_t = edge_all_t()) {} - typedef Property value_type; - typedef PropRef reference; - typedef detail::edge_desc_impl key_type; - typedef boost::lvalue_property_map_tag category; - inline PropRef operator[](key_type e) const { + } + inline Ref operator()(key_type e) const { return this->operator[](e); } +}; + +template < class Directed, class Property, class PropRef, class PropPtr, + class Vertex > +struct adj_list_edge_all_properties_map +: public put_get_helper< PropRef, + adj_list_edge_all_properties_map< Directed, Property, PropRef, PropPtr, + Vertex > > +{ + explicit adj_list_edge_all_properties_map(edge_all_t = edge_all_t()) {} + typedef Property value_type; + typedef PropRef reference; + typedef detail::edge_desc_impl< Directed, Vertex > key_type; + typedef boost::lvalue_property_map_tag category; + inline PropRef operator[](key_type e) const + { return *(PropPtr)e.get_property(); - } - inline PropRef operator()(key_type e) const { - return this->operator[](e); - } - }; + } + inline PropRef operator()(key_type e) const { return this->operator[](e); } +}; - // Edge Property Maps +// Edge Property Maps - namespace detail { - struct adj_list_any_edge_pmap { - template - struct bind_ { - typedef typename property_value::type value_type; - typedef value_type& reference; - typedef const value_type& const_reference; - - typedef adj_list_edge_property_map - type; - typedef adj_list_edge_property_map - const_type; - }; +namespace detail +{ + struct adj_list_any_edge_pmap + { + template < class Graph, class Property, class Tag > struct bind_ + { + typedef typename property_value< Property, Tag >::type value_type; + typedef value_type& reference; + typedef const value_type& const_reference; + + typedef adj_list_edge_property_map< + typename Graph::directed_category, value_type, reference, + typename Graph::vertex_descriptor, Property, Tag > + type; + typedef adj_list_edge_property_map< + typename Graph::directed_category, value_type, const_reference, + typename Graph::vertex_descriptor, const Property, Tag > + const_type; + }; }; - struct adj_list_all_edge_pmap { - template - struct bind_ { - typedef adj_list_edge_all_properties_map - type; - typedef adj_list_edge_all_properties_map - const_type; - }; + struct adj_list_all_edge_pmap + { + template < class Graph, class Property, class Tag > struct bind_ + { + typedef adj_list_edge_all_properties_map< + typename Graph::directed_category, Property, Property&, + Property*, typename Graph::vertex_descriptor > + type; + typedef adj_list_edge_all_properties_map< + typename Graph::directed_category, Property, const Property&, + const Property*, typename Graph::vertex_descriptor > + const_type; + }; }; - template - struct adj_list_choose_edge_pmap_helper { - typedef adj_list_any_edge_pmap type; + template < class Tag > struct adj_list_choose_edge_pmap_helper + { + typedef adj_list_any_edge_pmap type; }; - template <> - struct adj_list_choose_edge_pmap_helper { - typedef adj_list_all_edge_pmap type; + template <> struct adj_list_choose_edge_pmap_helper< edge_all_t > + { + typedef adj_list_all_edge_pmap type; }; - template + template < class Tag, class Graph, class Property > struct adj_list_choose_edge_pmap - : adj_list_choose_edge_pmap_helper::type::template bind_ - {}; - struct adj_list_edge_property_selector { - template - struct bind_: adj_list_choose_edge_pmap {}; + : adj_list_choose_edge_pmap_helper< Tag >::type::template bind_< Graph, + Property, Tag > + { + }; + struct adj_list_edge_property_selector + { + template < class Graph, class Property, class Tag > + struct bind_ : adj_list_choose_edge_pmap< Tag, Graph, Property > + { + }; }; - } // namespace detail +} // namespace detail - template <> - struct edge_property_selector { +template <> struct edge_property_selector< adj_list_tag > +{ typedef detail::adj_list_edge_property_selector type; - }; - template <> - struct edge_property_selector { +}; +template <> struct edge_property_selector< vec_adj_list_tag > +{ typedef detail::adj_list_edge_property_selector type; - }; - - // Vertex Property Maps - - struct adj_list_vertex_property_selector { - template - struct bind_ - : detail::adj_list_choose_vertex_pa - {}; - }; - template <> - struct vertex_property_selector { +}; + +// Vertex Property Maps + +struct adj_list_vertex_property_selector +{ + template < class Graph, class Property, class Tag > + struct bind_ : detail::adj_list_choose_vertex_pa< Tag, Graph, Property > + { + }; +}; +template <> struct vertex_property_selector< adj_list_tag > +{ typedef adj_list_vertex_property_selector type; - }; - - struct vec_adj_list_vertex_property_selector { - template - struct bind_: detail::vec_adj_list_choose_vertex_pa {}; - }; - template <> - struct vertex_property_selector { +}; + +struct vec_adj_list_vertex_property_selector +{ + template < class Graph, class Property, class Tag > + struct bind_ : detail::vec_adj_list_choose_vertex_pa< Tag, Graph, Property > + { + }; +}; +template <> struct vertex_property_selector< vec_adj_list_tag > +{ typedef vec_adj_list_vertex_property_selector type; - }; +}; } // namespace boost -namespace boost { +namespace boost +{ - template - struct hash< boost::detail::stored_edge > - { - std::size_t - operator()(const boost::detail::stored_edge& e) const +template < typename V > struct hash< boost::detail::stored_edge< V > > +{ + std::size_t operator()(const boost::detail::stored_edge< V >& e) const { - return hash()(e.m_target); + return hash< V >()(e.m_target); } - }; +}; - template - struct hash< boost::detail::stored_edge_property > - { - std::size_t - operator()(const boost::detail::stored_edge_property& e) const +template < typename V, typename P > +struct hash< boost::detail::stored_edge_property< V, P > > +{ + std::size_t operator()( + const boost::detail::stored_edge_property< V, P >& e) const { - return hash()(e.m_target); + return hash< V >()(e.m_target); } - }; +}; - template - struct hash< boost::detail::stored_edge_iter > - { - std::size_t - operator()(const boost::detail::stored_edge_iter& e) const +template < typename V, typename I, typename P > +struct hash< boost::detail::stored_edge_iter< V, I, P > > +{ + std::size_t operator()( + const boost::detail::stored_edge_iter< V, I, P >& e) const { - return hash()(e.m_target); + return hash< V >()(e.m_target); } - }; +}; } - #endif // BOOST_GRAPH_DETAIL_DETAIL_ADJACENCY_LIST_CCT /* diff --git a/include/boost/graph/detail/array_binary_tree.hpp b/include/boost/graph/detail/array_binary_tree.hpp index a594ba6bf..7d2c4e22c 100644 --- a/include/boost/graph/detail/array_binary_tree.hpp +++ b/include/boost/graph/detail/array_binary_tree.hpp @@ -15,171 +15,223 @@ #include #include -namespace boost { +namespace boost +{ /* * Note: array_binary_tree is a completey balanced binary tree. */ #if !defined BOOST_NO_STD_ITERATOR_TRAITS - template +template < class RandomAccessIterator, class ID > #else - template +template < class RandomAccessIterator, class ValueType, class ID > #endif -class array_binary_tree_node { +class array_binary_tree_node +{ public: - typedef array_binary_tree_node ArrayBinaryTreeNode; - typedef RandomAccessIterator rep_iterator; + typedef array_binary_tree_node ArrayBinaryTreeNode; + typedef RandomAccessIterator rep_iterator; #if !defined BOOST_NO_STD_ITERATOR_TRAITS - typedef typename std::iterator_traits::difference_type - difference_type; - typedef typename std::iterator_traits::value_type - value_type; + typedef + typename std::iterator_traits< RandomAccessIterator >::difference_type + difference_type; + typedef typename std::iterator_traits< RandomAccessIterator >::value_type + value_type; #else - typedef int difference_type; - typedef ValueType value_type; + typedef int difference_type; + typedef ValueType value_type; #endif - typedef difference_type size_type; + typedef difference_type size_type; - struct children_type { - struct iterator - { // replace with iterator_adaptor implementation -JGS - typedef std::bidirectional_iterator_tag iterator_category; - typedef ArrayBinaryTreeNode value_type; - typedef size_type difference_type; - typedef array_binary_tree_node* pointer; - typedef ArrayBinaryTreeNode& reference; + struct children_type + { + struct iterator + { // replace with iterator_adaptor implementation -JGS + typedef std::bidirectional_iterator_tag iterator_category; + typedef ArrayBinaryTreeNode value_type; + typedef size_type difference_type; + typedef array_binary_tree_node* pointer; + typedef ArrayBinaryTreeNode& reference; - inline iterator() : i(0), n(0) { } - inline iterator(const iterator& x) : r(x.r), i(x.i), n(x.n), id(x.id) { } - inline iterator& operator=(const iterator& x) { - r = x.r; i = x.i; n = x.n; + inline iterator() : i(0), n(0) {} + inline iterator(const iterator& x) + : r(x.r), i(x.i), n(x.n), id(x.id) + { + } + inline iterator& operator=(const iterator& x) + { + r = x.r; + i = x.i; + n = x.n; + /*egcs generate a warning*/ + id = x.id; + return *this; + } + inline iterator( + rep_iterator rr, size_type ii, size_type nn, const ID& _id) + : r(rr), i(ii), n(nn), id(_id) + { + } + inline array_binary_tree_node operator*() + { + return ArrayBinaryTreeNode(r, i, n, id); + } + inline iterator& operator++() + { + ++i; + return *this; + } + inline iterator operator++(int) + { + iterator t = *this; + ++(*this); + return t; + } + inline iterator& operator--() + { + --i; + return *this; + } + inline iterator operator--(int) + { + iterator t = *this; + --(*this); + return t; + } + inline bool operator==(const iterator& x) const { return i == x.i; } + inline bool operator!=(const iterator& x) const + { + return !(*this == x); + } + rep_iterator r; + size_type i; + size_type n; + ID id; + }; + inline children_type() : i(0), n(0) {} + inline children_type(const children_type& x) + : r(x.r), i(x.i), n(x.n), id(x.id) + { + } + inline children_type& operator=(const children_type& x) + { + r = x.r; + i = x.i; + n = x.n; + /*egcs generate a warning*/ + id = x.id; + return *this; + } + inline children_type( + rep_iterator rr, size_type ii, size_type nn, const ID& _id) + : r(rr), i(ii), n(nn), id(_id) + { + } + inline iterator begin() { return iterator(r, 2 * i + 1, n, id); } + inline iterator end() { return iterator(r, 2 * i + 1 + size(), n, id); } + inline size_type size() const + { + size_type c = 2 * i + 1; + size_type s; + if (c + 1 < n) + s = 2; + else if (c < n) + s = 1; + else + s = 0; + return s; + } + rep_iterator r; + size_type i; + size_type n; + ID id; + }; + inline array_binary_tree_node() : i(0), n(0) {} + inline array_binary_tree_node(const array_binary_tree_node& x) + : r(x.r), i(x.i), n(x.n), id(x.id) + { + } + inline ArrayBinaryTreeNode& operator=(const ArrayBinaryTreeNode& x) + { + r = x.r; + i = x.i; + n = x.n; /*egcs generate a warning*/ id = x.id; return *this; - } - inline iterator(rep_iterator rr, - size_type ii, - size_type nn, - const ID& _id) : r(rr), i(ii), n(nn), id(_id) { } - inline array_binary_tree_node operator*() { - return ArrayBinaryTreeNode(r, i, n, id); } - inline iterator& operator++() { ++i; return *this; } - inline iterator operator++(int) - { iterator t = *this; ++(*this); return t; } - inline iterator& operator--() { --i; return *this; } - inline iterator operator--(int) - { iterator t = *this; --(*this); return t; } - inline bool operator==(const iterator& x) const { return i == x.i; } - inline bool operator!=(const iterator& x) const - { return !(*this == x); } - rep_iterator r; - size_type i; - size_type n; - ID id; - }; - inline children_type() : i(0), n(0) { } - inline children_type(const children_type& x) - : r(x.r), i(x.i), n(x.n), id(x.id) { } - inline children_type& operator=(const children_type& x) { - r = x.r; i = x.i; n = x.n; - /*egcs generate a warning*/ - id = x.id; - return *this; } - inline children_type(rep_iterator rr, - size_type ii, - size_type nn, - const ID& _id) : r(rr), i(ii), n(nn), id(_id) { } - inline iterator begin() { return iterator(r, 2 * i + 1, n, id); } - inline iterator end() { return iterator(r, 2 * i + 1 + size(), n, id); } - inline size_type size() const { - size_type c = 2 * i + 1; - size_type s; - if (c + 1 < n) s = 2; - else if (c < n) s = 1; - else s = 0; - return s; + inline array_binary_tree_node( + rep_iterator start, rep_iterator end, rep_iterator pos, const ID& _id) + : r(start), i(pos - start), n(end - start), id(_id) + { + } + inline array_binary_tree_node( + rep_iterator rr, size_type ii, size_type nn, const ID& _id) + : r(rr), i(ii), n(nn), id(_id) + { + } + inline value_type& value() { return *(r + i); } + inline const value_type& value() const { return *(r + i); } + inline ArrayBinaryTreeNode parent() const + { + return ArrayBinaryTreeNode(r, (i - 1) / 2, n, id); + } + inline bool has_parent() const { return i != 0; } + inline children_type children() { return children_type(r, i, n, id); } + /* + inline void swap(array_binary_tree_node x) { + value_type tmp = x.value(); + x.value() = value(); + value() = tmp; + i = x.i; + } + */ + template < class ExternalData > + inline void swap(ArrayBinaryTreeNode x, ExternalData& edata) + { + using boost::get; + + value_type tmp = x.value(); + + /*swap external data*/ + edata[get(id, tmp)] = i; + edata[get(id, value())] = x.i; + + x.value() = value(); + value() = tmp; + i = x.i; + } + inline const children_type children() const + { + return children_type(r, i, n); } + inline size_type index() const { return i; } rep_iterator r; size_type i; size_type n; ID id; - }; - inline array_binary_tree_node() : i(0), n(0) { } - inline array_binary_tree_node(const array_binary_tree_node& x) - : r(x.r), i(x.i), n(x.n), id(x.id) { } - inline ArrayBinaryTreeNode& operator=(const ArrayBinaryTreeNode& x) { - r = x.r; - i = x.i; - n = x.n; - /*egcs generate a warning*/ - id = x.id; - return *this; - } - inline array_binary_tree_node(rep_iterator start, - rep_iterator end, - rep_iterator pos, const ID& _id) - : r(start), i(pos - start), n(end - start), id(_id) { } - inline array_binary_tree_node(rep_iterator rr, - size_type ii, - size_type nn, const ID& _id) - : r(rr), i(ii), n(nn), id(_id) { } - inline value_type& value() { return *(r + i); } - inline const value_type& value() const { return *(r + i); } - inline ArrayBinaryTreeNode parent() const { - return ArrayBinaryTreeNode(r, (i - 1) / 2, n, id); - } - inline bool has_parent() const { return i != 0; } - inline children_type children() { return children_type(r, i, n, id); } - /* - inline void swap(array_binary_tree_node x) { - value_type tmp = x.value(); - x.value() = value(); - value() = tmp; - i = x.i; - } - */ - template - inline void swap(ArrayBinaryTreeNode x, ExternalData& edata ) { - using boost::get; - - value_type tmp = x.value(); - - /*swap external data*/ - edata[ get(id, tmp) ] = i; - edata[ get(id, value()) ] = x.i; - - x.value() = value(); - value() = tmp; - i = x.i; - } - inline const children_type children() const { - return children_type(r, i, n); - } - inline size_type index() const { return i; } - rep_iterator r; - size_type i; - size_type n; - ID id; }; -template > -struct compare_array_node { - typedef typename RandomAccessContainer::value_type value_type; - compare_array_node(const Compare& x) : comp(x) {} - compare_array_node(const compare_array_node& x) : comp(x.comp) {} +template < class RandomAccessContainer, + class Compare = std::less< typename RandomAccessContainer::value_type > > +struct compare_array_node +{ + typedef typename RandomAccessContainer::value_type value_type; + compare_array_node(const Compare& x) : comp(x) {} + compare_array_node(const compare_array_node& x) : comp(x.comp) {} - template< class node_type > - inline bool operator()(const node_type& x, const node_type& y) { - return comp(x.value(), y.value()); - } + template < class node_type > + inline bool operator()(const node_type& x, const node_type& y) + { + return comp(x.value(), y.value()); + } - template< class node_type > - inline bool operator()(const node_type& x, const node_type& y) const { - return comp(x.value(), y.value()); - } - Compare comp; + template < class node_type > + inline bool operator()(const node_type& x, const node_type& y) const + { + return comp(x.value(), y.value()); + } + Compare comp; }; } // namespace boost diff --git a/include/boost/graph/detail/augment.hpp b/include/boost/graph/detail/augment.hpp index 3b20dcc4a..956f274cb 100644 --- a/include/boost/graph/detail/augment.hpp +++ b/include/boost/graph/detail/augment.hpp @@ -1,6 +1,6 @@ //======================================================================= // Copyright 2013 University of Warsaw. -// Authors: Piotr Wygocki +// Authors: Piotr Wygocki // // Distributed under the Boost Software License, Version 1.0. (See // accompanying file LICENSE_1_0.txt or copy at @@ -12,52 +12,55 @@ #include -namespace boost { -namespace detail { - -template -filtered_graph > -residual_graph(const Graph& g, ResCapMap residual_capacity) { - return filtered_graph > - (g, is_residual_edge(residual_capacity)); -} - -template -inline void -augment(const Graph& g, - typename graph_traits::vertex_descriptor src, - typename graph_traits::vertex_descriptor sink, - PredEdgeMap p, - ResCapMap residual_capacity, - RevEdgeMap reverse_edge) +namespace boost { - typename graph_traits::edge_descriptor e; - typename graph_traits::vertex_descriptor u; - typedef typename property_traits::value_type FlowValue; - - // find minimum residual capacity along the augmenting path - FlowValue delta = (std::numeric_limits::max)(); - e = get(p, sink); - do { - BOOST_USING_STD_MIN(); - delta = min BOOST_PREVENT_MACRO_SUBSTITUTION(delta, get(residual_capacity, e)); - u = source(e, g); - e = get(p, u); - } while (u != src); - - // push delta units of flow along the augmenting path - e = get(p, sink); - do { - put(residual_capacity, e, get(residual_capacity, e) - delta); - put(residual_capacity, get(reverse_edge, e), get(residual_capacity, get(reverse_edge, e)) + delta); - u = source(e, g); - e = get(p, u); - } while (u != src); -} +namespace detail +{ + + template < class Graph, class ResCapMap > + filtered_graph< const Graph, is_residual_edge< ResCapMap > > residual_graph( + const Graph& g, ResCapMap residual_capacity) + { + return filtered_graph< const Graph, is_residual_edge< ResCapMap > >( + g, is_residual_edge< ResCapMap >(residual_capacity)); + } + + template < class Graph, class PredEdgeMap, class ResCapMap, + class RevEdgeMap > + inline void augment(const Graph& g, + typename graph_traits< Graph >::vertex_descriptor src, + typename graph_traits< Graph >::vertex_descriptor sink, PredEdgeMap p, + ResCapMap residual_capacity, RevEdgeMap reverse_edge) + { + typename graph_traits< Graph >::edge_descriptor e; + typename graph_traits< Graph >::vertex_descriptor u; + typedef typename property_traits< ResCapMap >::value_type FlowValue; + + // find minimum residual capacity along the augmenting path + FlowValue delta = (std::numeric_limits< FlowValue >::max)(); + e = get(p, sink); + do + { + BOOST_USING_STD_MIN(); + delta = min BOOST_PREVENT_MACRO_SUBSTITUTION( + delta, get(residual_capacity, e)); + u = source(e, g); + e = get(p, u); + } while (u != src); + + // push delta units of flow along the augmenting path + e = get(p, sink); + do + { + put(residual_capacity, e, get(residual_capacity, e) - delta); + put(residual_capacity, get(reverse_edge, e), + get(residual_capacity, get(reverse_edge, e)) + delta); + u = source(e, g); + e = get(p, u); + } while (u != src); + } } // namespace detail -} //namespace boost +} // namespace boost #endif /* BOOST_GRAPH_AUGMENT_HPP */ - diff --git a/include/boost/graph/detail/compressed_sparse_row_struct.hpp b/include/boost/graph/detail/compressed_sparse_row_struct.hpp index 44c64e11c..a6be13e51 100644 --- a/include/boost/graph/detail/compressed_sparse_row_struct.hpp +++ b/include/boost/graph/detail/compressed_sparse_row_struct.hpp @@ -45,602 +45,695 @@ #include #include -namespace boost { - -namespace detail { - // Forward declaration of CSR edge descriptor type, needed to pass to - // indexed_edge_properties. - template - class csr_edge_descriptor; - - // Add edge_index property map - template - struct csr_edge_index_map - { - typedef EdgeIndex value_type; - typedef EdgeIndex reference; - typedef csr_edge_descriptor key_type; - typedef readable_property_map_tag category; - }; - - template - inline EdgeIndex - get(const csr_edge_index_map&, - const csr_edge_descriptor& key) - { - return key.idx; - } - - /** Compressed sparse row graph internal structure. - * - * Vertex and EdgeIndex should be unsigned integral types and should - * specialize numeric_limits. - */ - template - class compressed_sparse_row_structure : - public detail::indexed_edge_properties< - compressed_sparse_row_structure, - EdgeProperty, - csr_edge_descriptor, - csr_edge_index_map > { - public: - typedef detail::indexed_edge_properties< - compressed_sparse_row_structure, - EdgeProperty, - csr_edge_descriptor, - csr_edge_index_map > - inherited_edge_properties; - - typedef Vertex vertices_size_type; - typedef Vertex vertex_descriptor; - typedef EdgeIndex edges_size_type; - - static vertex_descriptor null_vertex() { return vertex_descriptor(-1); } - - std::vector m_rowstart; - std::vector m_column; - - compressed_sparse_row_structure(Vertex numverts = 0) - : m_rowstart(numverts + 1, EdgeIndex(0)), m_column() - {} - - // Rebuild graph from number of vertices and multi-pass unsorted list of - // edges (filtered using source_pred and mapped using global_to_local) - template - void - assign_unsorted_multi_pass_edges(MultiPassInputIterator edge_begin, - MultiPassInputIterator edge_end, - vertices_size_type numlocalverts, - const GlobalToLocal& global_to_local, - const SourcePred& source_pred) { - m_rowstart.clear(); - m_rowstart.resize(numlocalverts + 1, 0); - typedef std::pair edge_type; - typedef boost::transform_iterator, MultiPassInputIterator> source_iterator; - typedef boost::transform_iterator, MultiPassInputIterator> target_iterator; - source_iterator sources_begin(edge_begin, boost::graph::detail::project1st()); - source_iterator sources_end(edge_end, boost::graph::detail::project1st()); - target_iterator targets_begin(edge_begin, boost::graph::detail::project2nd()); - target_iterator targets_end(edge_end, boost::graph::detail::project2nd()); - - boost::graph::detail::count_starts - (sources_begin, sources_end, m_rowstart.begin(), numlocalverts, - source_pred, boost::make_property_map_function(global_to_local)); - - m_column.resize(m_rowstart.back()); - inherited_edge_properties::resize(m_rowstart.back()); - - boost::graph::detail::histogram_sort - (sources_begin, sources_end, m_rowstart.begin(), numlocalverts, - targets_begin, m_column.begin(), - source_pred, boost::make_property_map_function(global_to_local)); - } +namespace boost +{ - // Rebuild graph from number of vertices and multi-pass unsorted list of - // edges and their properties (filtered using source_pred and mapped using - // global_to_local) - template - void - assign_unsorted_multi_pass_edges(MultiPassInputIterator edge_begin, - MultiPassInputIterator edge_end, - EdgePropertyIterator ep_iter, - vertices_size_type numlocalverts, - const GlobalToLocal& global_to_local, - const SourcePred& source_pred) { - m_rowstart.clear(); - m_rowstart.resize(numlocalverts + 1, 0); - typedef std::pair edge_type; - typedef boost::transform_iterator, MultiPassInputIterator> source_iterator; - typedef boost::transform_iterator, MultiPassInputIterator> target_iterator; - source_iterator sources_begin(edge_begin, boost::graph::detail::project1st()); - source_iterator sources_end(edge_end, boost::graph::detail::project1st()); - target_iterator targets_begin(edge_begin, boost::graph::detail::project2nd()); - target_iterator targets_end(edge_end, boost::graph::detail::project2nd()); - - boost::graph::detail::count_starts - (sources_begin, sources_end, m_rowstart.begin(), numlocalverts, - source_pred, boost::make_property_map_function(global_to_local)); - - m_column.resize(m_rowstart.back()); - inherited_edge_properties::resize(m_rowstart.back()); - - boost::graph::detail::histogram_sort - (sources_begin, sources_end, m_rowstart.begin(), numlocalverts, - targets_begin, m_column.begin(), - ep_iter, inherited_edge_properties::begin(), - source_pred, boost::make_property_map_function(global_to_local)); - } +namespace detail +{ + // Forward declaration of CSR edge descriptor type, needed to pass to + // indexed_edge_properties. + template < typename Vertex, typename EdgeIndex > class csr_edge_descriptor; - // Assign from number of vertices and sorted list of edges - template - void assign_from_sorted_edges( - InputIterator edge_begin, InputIterator edge_end, - const GlobalToLocal& global_to_local, - const SourcePred& source_pred, - vertices_size_type numlocalverts, - edges_size_type numedges_or_zero) { - m_column.clear(); - m_column.reserve(numedges_or_zero); - m_rowstart.resize(numlocalverts + 1); - EdgeIndex current_edge = 0; - Vertex current_vertex_plus_one = 1; - m_rowstart[0] = 0; - for (InputIterator ei = edge_begin; ei != edge_end; ++ei) { - if (!source_pred(ei->first)) continue; - Vertex src = get(global_to_local, ei->first); - Vertex tgt = ei->second; - for (; current_vertex_plus_one != src + 1; ++current_vertex_plus_one) - m_rowstart[current_vertex_plus_one] = current_edge; - m_column.push_back(tgt); - ++current_edge; - } - - // The remaining vertices have no edges - for (; current_vertex_plus_one != numlocalverts + 1; ++current_vertex_plus_one) - m_rowstart[current_vertex_plus_one] = current_edge; - - // Default-construct properties for edges - inherited_edge_properties::resize(m_column.size()); + // Add edge_index property map + template < typename Vertex, typename EdgeIndex > struct csr_edge_index_map + { + typedef EdgeIndex value_type; + typedef EdgeIndex reference; + typedef csr_edge_descriptor< Vertex, EdgeIndex > key_type; + typedef readable_property_map_tag category; + }; + + template < typename Vertex, typename EdgeIndex > + inline EdgeIndex get(const csr_edge_index_map< Vertex, EdgeIndex >&, + const csr_edge_descriptor< Vertex, EdgeIndex >& key) + { + return key.idx; } - // Assign from number of vertices and sorted list of edges - template - void assign_from_sorted_edges( - InputIterator edge_begin, InputIterator edge_end, - EdgePropertyIterator ep_iter, - const GlobalToLocal& global_to_local, - const SourcePred& source_pred, - vertices_size_type numlocalverts, - edges_size_type numedges_or_zero) { - // Reserving storage in advance can save us lots of time and - // memory, but it can only be done if we have forward iterators or - // the user has supplied the number of edges. - edges_size_type numedges = numedges_or_zero; - if (numedges == 0) { - numedges = boost::graph::detail::reserve_count_for_single_pass(edge_begin, edge_end); - } - m_column.clear(); - m_column.reserve(numedges_or_zero); - inherited_edge_properties::clear(); - inherited_edge_properties::reserve(numedges_or_zero); - m_rowstart.resize(numlocalverts + 1); - EdgeIndex current_edge = 0; - Vertex current_vertex_plus_one = 1; - m_rowstart[0] = 0; - for (InputIterator ei = edge_begin; ei != edge_end; ++ei, ++ep_iter) { - if (!source_pred(ei->first)) continue; - Vertex src = get(global_to_local, ei->first); - Vertex tgt = ei->second; - for (; current_vertex_plus_one != src + 1; ++current_vertex_plus_one) - m_rowstart[current_vertex_plus_one] = current_edge; - m_column.push_back(tgt); - inherited_edge_properties::push_back(*ep_iter); - ++current_edge; - } - - // The remaining vertices have no edges - for (; current_vertex_plus_one != numlocalverts + 1; ++current_vertex_plus_one) - m_rowstart[current_vertex_plus_one] = current_edge; - } + /** Compressed sparse row graph internal structure. + * + * Vertex and EdgeIndex should be unsigned integral types and should + * specialize numeric_limits. + */ + template < typename EdgeProperty, typename Vertex = std::size_t, + typename EdgeIndex = Vertex > + class compressed_sparse_row_structure + : public detail::indexed_edge_properties< + compressed_sparse_row_structure< EdgeProperty, Vertex, EdgeIndex >, + EdgeProperty, csr_edge_descriptor< Vertex, EdgeIndex >, + csr_edge_index_map< Vertex, EdgeIndex > > + { + public: + typedef detail::indexed_edge_properties< + compressed_sparse_row_structure< EdgeProperty, Vertex, EdgeIndex >, + EdgeProperty, csr_edge_descriptor< Vertex, EdgeIndex >, + csr_edge_index_map< Vertex, EdgeIndex > > + inherited_edge_properties; - // Replace graph with sources and targets given, sorting them in-place, and - // using the given global-to-local property map to get local indices from - // global ones in the two arrays. - template - void assign_sources_and_targets_global(std::vector& sources, - std::vector& targets, - vertices_size_type numverts, - GlobalToLocal global_to_local) { - BOOST_ASSERT (sources.size() == targets.size()); - // Do an in-place histogram sort (at least that's what I think it is) to - // sort sources and targets - m_rowstart.clear(); - m_rowstart.resize(numverts + 1); - boost::graph::detail::count_starts - (sources.begin(), sources.end(), m_rowstart.begin(), numverts, - keep_all(), boost::make_property_map_function(global_to_local)); - boost::graph::detail::histogram_sort_inplace - (sources.begin(), m_rowstart.begin(), numverts, - targets.begin(), boost::make_property_map_function(global_to_local)); - // Now targets is the correct vector (properly sorted by source) for - // m_column - m_column.swap(targets); - inherited_edge_properties::resize(m_rowstart.back()); - } + typedef Vertex vertices_size_type; + typedef Vertex vertex_descriptor; + typedef EdgeIndex edges_size_type; - // Replace graph with sources and targets and edge properties given, sorting - // them in-place, and using the given global-to-local property map to get - // local indices from global ones in the two arrays. - template - void assign_sources_and_targets_global(std::vector& sources, - std::vector& targets, - std::vector& edge_props, - vertices_size_type numverts, - GlobalToLocal global_to_local) { - BOOST_ASSERT (sources.size() == targets.size()); - BOOST_ASSERT (sources.size() == edge_props.size()); - // Do an in-place histogram sort (at least that's what I think it is) to - // sort sources and targets - m_rowstart.clear(); - m_rowstart.resize(numverts + 1); - boost::graph::detail::count_starts - (sources.begin(), sources.end(), m_rowstart.begin(), numverts, - keep_all(), boost::make_property_map_function(global_to_local)); - boost::graph::detail::histogram_sort_inplace - (sources.begin(), m_rowstart.begin(), numverts, - targets.begin(), edge_props.begin(), - boost::make_property_map_function(global_to_local)); - // Now targets is the correct vector (properly sorted by source) for - // m_column, and edge_props for m_edge_properties - m_column.swap(targets); - this->m_edge_properties.swap(edge_props); - } + static vertex_descriptor null_vertex() { return vertex_descriptor(-1); } - // From any graph (slow and uses a lot of memory) - // Requires IncidenceGraph and a vertex index map - // Internal helper function - // Note that numedges must be doubled for undirected source graphs - template - void - assign(const Graph& g, const VertexIndexMap& vi, - vertices_size_type numverts, edges_size_type numedges) + std::vector< EdgeIndex > m_rowstart; + std::vector< Vertex > m_column; + + compressed_sparse_row_structure(Vertex numverts = 0) + : m_rowstart(numverts + 1, EdgeIndex(0)), m_column() + { + } + + // Rebuild graph from number of vertices and multi-pass unsorted list + // of edges (filtered using source_pred and mapped using + // global_to_local) + template < typename MultiPassInputIterator, typename GlobalToLocal, + typename SourcePred > + void assign_unsorted_multi_pass_edges(MultiPassInputIterator edge_begin, + MultiPassInputIterator edge_end, vertices_size_type numlocalverts, + const GlobalToLocal& global_to_local, const SourcePred& source_pred) + { + m_rowstart.clear(); + m_rowstart.resize(numlocalverts + 1, 0); + typedef std::pair< vertices_size_type, vertices_size_type > + edge_type; + typedef boost::transform_iterator< + boost::graph::detail::project1st< edge_type >, + MultiPassInputIterator > + source_iterator; + typedef boost::transform_iterator< + boost::graph::detail::project2nd< edge_type >, + MultiPassInputIterator > + target_iterator; + source_iterator sources_begin( + edge_begin, boost::graph::detail::project1st< edge_type >()); + source_iterator sources_end( + edge_end, boost::graph::detail::project1st< edge_type >()); + target_iterator targets_begin( + edge_begin, boost::graph::detail::project2nd< edge_type >()); + target_iterator targets_end( + edge_end, boost::graph::detail::project2nd< edge_type >()); + + boost::graph::detail::count_starts(sources_begin, sources_end, + m_rowstart.begin(), numlocalverts, source_pred, + boost::make_property_map_function(global_to_local)); + + m_column.resize(m_rowstart.back()); + inherited_edge_properties::resize(m_rowstart.back()); + + boost::graph::detail::histogram_sort(sources_begin, sources_end, + m_rowstart.begin(), numlocalverts, targets_begin, + m_column.begin(), source_pred, + boost::make_property_map_function(global_to_local)); + } + + // Rebuild graph from number of vertices and multi-pass unsorted list + // of edges and their properties (filtered using source_pred and mapped + // using global_to_local) + template < typename MultiPassInputIterator, + typename EdgePropertyIterator, typename GlobalToLocal, + typename SourcePred > + void assign_unsorted_multi_pass_edges(MultiPassInputIterator edge_begin, + MultiPassInputIterator edge_end, EdgePropertyIterator ep_iter, + vertices_size_type numlocalverts, + const GlobalToLocal& global_to_local, const SourcePred& source_pred) + { + m_rowstart.clear(); + m_rowstart.resize(numlocalverts + 1, 0); + typedef std::pair< vertices_size_type, vertices_size_type > + edge_type; + typedef boost::transform_iterator< + boost::graph::detail::project1st< edge_type >, + MultiPassInputIterator > + source_iterator; + typedef boost::transform_iterator< + boost::graph::detail::project2nd< edge_type >, + MultiPassInputIterator > + target_iterator; + source_iterator sources_begin( + edge_begin, boost::graph::detail::project1st< edge_type >()); + source_iterator sources_end( + edge_end, boost::graph::detail::project1st< edge_type >()); + target_iterator targets_begin( + edge_begin, boost::graph::detail::project2nd< edge_type >()); + target_iterator targets_end( + edge_end, boost::graph::detail::project2nd< edge_type >()); + + boost::graph::detail::count_starts(sources_begin, sources_end, + m_rowstart.begin(), numlocalverts, source_pred, + boost::make_property_map_function(global_to_local)); + + m_column.resize(m_rowstart.back()); + inherited_edge_properties::resize(m_rowstart.back()); + + boost::graph::detail::histogram_sort(sources_begin, sources_end, + m_rowstart.begin(), numlocalverts, targets_begin, + m_column.begin(), ep_iter, inherited_edge_properties::begin(), + source_pred, + boost::make_property_map_function(global_to_local)); + } + + // Assign from number of vertices and sorted list of edges + template < typename InputIterator, typename GlobalToLocal, + typename SourcePred > + void assign_from_sorted_edges(InputIterator edge_begin, + InputIterator edge_end, const GlobalToLocal& global_to_local, + const SourcePred& source_pred, vertices_size_type numlocalverts, + edges_size_type numedges_or_zero) + { + m_column.clear(); + m_column.reserve(numedges_or_zero); + m_rowstart.resize(numlocalverts + 1); + EdgeIndex current_edge = 0; + Vertex current_vertex_plus_one = 1; + m_rowstart[0] = 0; + for (InputIterator ei = edge_begin; ei != edge_end; ++ei) + { + if (!source_pred(ei->first)) + continue; + Vertex src = get(global_to_local, ei->first); + Vertex tgt = ei->second; + for (; current_vertex_plus_one != src + 1; + ++current_vertex_plus_one) + m_rowstart[current_vertex_plus_one] = current_edge; + m_column.push_back(tgt); + ++current_edge; + } + + // The remaining vertices have no edges + for (; current_vertex_plus_one != numlocalverts + 1; + ++current_vertex_plus_one) + m_rowstart[current_vertex_plus_one] = current_edge; + + // Default-construct properties for edges + inherited_edge_properties::resize(m_column.size()); + } + + // Assign from number of vertices and sorted list of edges + template < typename InputIterator, typename EdgePropertyIterator, + typename GlobalToLocal, typename SourcePred > + void assign_from_sorted_edges(InputIterator edge_begin, + InputIterator edge_end, EdgePropertyIterator ep_iter, + const GlobalToLocal& global_to_local, const SourcePred& source_pred, + vertices_size_type numlocalverts, edges_size_type numedges_or_zero) + { + // Reserving storage in advance can save us lots of time and + // memory, but it can only be done if we have forward iterators or + // the user has supplied the number of edges. + edges_size_type numedges = numedges_or_zero; + if (numedges == 0) + { + numedges = boost::graph::detail::reserve_count_for_single_pass( + edge_begin, edge_end); + } + m_column.clear(); + m_column.reserve(numedges_or_zero); + inherited_edge_properties::clear(); + inherited_edge_properties::reserve(numedges_or_zero); + m_rowstart.resize(numlocalverts + 1); + EdgeIndex current_edge = 0; + Vertex current_vertex_plus_one = 1; + m_rowstart[0] = 0; + for (InputIterator ei = edge_begin; ei != edge_end; ++ei, ++ep_iter) + { + if (!source_pred(ei->first)) + continue; + Vertex src = get(global_to_local, ei->first); + Vertex tgt = ei->second; + for (; current_vertex_plus_one != src + 1; + ++current_vertex_plus_one) + m_rowstart[current_vertex_plus_one] = current_edge; + m_column.push_back(tgt); + inherited_edge_properties::push_back(*ep_iter); + ++current_edge; + } + + // The remaining vertices have no edges + for (; current_vertex_plus_one != numlocalverts + 1; + ++current_vertex_plus_one) + m_rowstart[current_vertex_plus_one] = current_edge; + } + + // Replace graph with sources and targets given, sorting them in-place, + // and using the given global-to-local property map to get local indices + // from global ones in the two arrays. + template < typename GlobalToLocal > + void assign_sources_and_targets_global( + std::vector< vertex_descriptor >& sources, + std::vector< vertex_descriptor >& targets, + vertices_size_type numverts, GlobalToLocal global_to_local) + { + BOOST_ASSERT(sources.size() == targets.size()); + // Do an in-place histogram sort (at least that's what I think it + // is) to sort sources and targets + m_rowstart.clear(); + m_rowstart.resize(numverts + 1); + boost::graph::detail::count_starts(sources.begin(), sources.end(), + m_rowstart.begin(), numverts, keep_all(), + boost::make_property_map_function(global_to_local)); + boost::graph::detail::histogram_sort_inplace(sources.begin(), + m_rowstart.begin(), numverts, targets.begin(), + boost::make_property_map_function(global_to_local)); + // Now targets is the correct vector (properly sorted by source) for + // m_column + m_column.swap(targets); + inherited_edge_properties::resize(m_rowstart.back()); + } + + // Replace graph with sources and targets and edge properties given, + // sorting them in-place, and using the given global-to-local property + // map to get local indices from global ones in the two arrays. + template < typename GlobalToLocal > + void assign_sources_and_targets_global( + std::vector< vertex_descriptor >& sources, + std::vector< vertex_descriptor >& targets, + std::vector< typename inherited_edge_properties::edge_bundled >& + edge_props, + vertices_size_type numverts, GlobalToLocal global_to_local) + { + BOOST_ASSERT(sources.size() == targets.size()); + BOOST_ASSERT(sources.size() == edge_props.size()); + // Do an in-place histogram sort (at least that's what I think it + // is) to sort sources and targets + m_rowstart.clear(); + m_rowstart.resize(numverts + 1); + boost::graph::detail::count_starts(sources.begin(), sources.end(), + m_rowstart.begin(), numverts, keep_all(), + boost::make_property_map_function(global_to_local)); + boost::graph::detail::histogram_sort_inplace(sources.begin(), + m_rowstart.begin(), numverts, targets.begin(), + edge_props.begin(), + boost::make_property_map_function(global_to_local)); + // Now targets is the correct vector (properly sorted by source) for + // m_column, and edge_props for m_edge_properties + m_column.swap(targets); + this->m_edge_properties.swap(edge_props); + } + + // From any graph (slow and uses a lot of memory) + // Requires IncidenceGraph and a vertex index map + // Internal helper function + // Note that numedges must be doubled for undirected source graphs + template < typename Graph, typename VertexIndexMap > + void assign(const Graph& g, const VertexIndexMap& vi, + vertices_size_type numverts, edges_size_type numedges) + { + m_rowstart.resize(numverts + 1); + m_column.resize(numedges); + inherited_edge_properties::resize(numedges); + EdgeIndex current_edge = 0; + typedef typename boost::graph_traits< Graph >::vertex_descriptor + g_vertex; + typedef typename boost::graph_traits< Graph >::out_edge_iterator + g_out_edge_iter; + + std::vector< g_vertex > ordered_verts_of_g(numverts); + BGL_FORALL_VERTICES_T(v, g, Graph) + { + ordered_verts_of_g[get(vertex_index, g, v)] = v; + } + for (Vertex i = 0; i != numverts; ++i) + { + m_rowstart[i] = current_edge; + g_vertex v = ordered_verts_of_g[i]; + g_out_edge_iter ei, ei_end; + for (boost::tie(ei, ei_end) = out_edges(v, g); ei != ei_end; + ++ei) + { + m_column[current_edge++] = get(vi, target(*ei, g)); + } + } + m_rowstart[numverts] = current_edge; + } + + // Add edges from a sorted (smallest sources first) range of pairs and + // edge properties + template < typename BidirectionalIteratorOrig, typename EPIterOrig, + typename GlobalToLocal > + void add_edges_sorted_internal(BidirectionalIteratorOrig first_sorted, + BidirectionalIteratorOrig last_sorted, EPIterOrig ep_iter_sorted, + const GlobalToLocal& global_to_local) + { + typedef boost::reverse_iterator< BidirectionalIteratorOrig > + BidirectionalIterator; + typedef boost::reverse_iterator< EPIterOrig > EPIter; + // Flip sequence + BidirectionalIterator first(last_sorted); + BidirectionalIterator last(first_sorted); + typedef Vertex vertex_num; + typedef EdgeIndex edge_num; + edge_num new_edge_count = std::distance(first, last); + + EPIter ep_iter(ep_iter_sorted); + std::advance(ep_iter, -(std::ptrdiff_t)new_edge_count); + edge_num edges_added_before_i + = new_edge_count; // Count increment to add to rowstarts + m_column.resize(m_column.size() + new_edge_count); + inherited_edge_properties::resize( + inherited_edge_properties::size() + new_edge_count); + BidirectionalIterator current_new_edge = first, + prev_new_edge = first; + EPIter current_new_edge_prop = ep_iter; + for (vertex_num i_plus_1 = m_rowstart.size() - 1; i_plus_1 > 0; + --i_plus_1) + { + vertex_num i = i_plus_1 - 1; + prev_new_edge = current_new_edge; + // edges_added_to_this_vertex = #mbrs of new_edges with first == + // i + edge_num edges_added_to_this_vertex = 0; + while (current_new_edge != last) + { + if (get(global_to_local, current_new_edge->first) != i) + break; + ++current_new_edge; + ++current_new_edge_prop; + ++edges_added_to_this_vertex; + } + edges_added_before_i -= edges_added_to_this_vertex; + // Invariant: edges_added_before_i = #mbrs of new_edges with + // first < i + edge_num old_rowstart = m_rowstart[i]; + edge_num new_rowstart = m_rowstart[i] + edges_added_before_i; + edge_num old_degree = m_rowstart[i + 1] - m_rowstart[i]; + edge_num new_degree = old_degree + edges_added_to_this_vertex; + // Move old edges forward (by #new_edges before this i) to make + // room new_rowstart > old_rowstart, so use copy_backwards + if (old_rowstart != new_rowstart) + { + std::copy_backward(m_column.begin() + old_rowstart, + m_column.begin() + old_rowstart + old_degree, + m_column.begin() + new_rowstart + old_degree); + inherited_edge_properties::move_range( + old_rowstart, old_rowstart + old_degree, new_rowstart); + } + // Add new edges (reversed because current_new_edge is a + // const_reverse_iterator) + BidirectionalIterator temp = current_new_edge; + EPIter temp_prop = current_new_edge_prop; + for (; temp != prev_new_edge; ++old_degree) + { + --temp; + --temp_prop; + m_column[new_rowstart + old_degree] = temp->second; + inherited_edge_properties::write_by_index( + new_rowstart + old_degree, *temp_prop); + } + m_rowstart[i + 1] = new_rowstart + new_degree; + if (edges_added_before_i == 0) + break; // No more edges inserted before this point + // m_rowstart[i] will be fixed up on the next iteration (to + // avoid changing the degree of vertex i - 1); the last + // iteration never changes it (either because of the condition + // of the break or because m_rowstart[0] is always 0) + } + } + }; + + template < typename Vertex, typename EdgeIndex > class csr_edge_descriptor { - m_rowstart.resize(numverts + 1); - m_column.resize(numedges); - inherited_edge_properties::resize(numedges); - EdgeIndex current_edge = 0; - typedef typename boost::graph_traits::vertex_descriptor g_vertex; - typedef typename boost::graph_traits::out_edge_iterator - g_out_edge_iter; - - std::vector ordered_verts_of_g(numverts); - BGL_FORALL_VERTICES_T(v, g, Graph) { - ordered_verts_of_g[get(vertex_index, g, v)] = v; - } - for (Vertex i = 0; i != numverts; ++i) { - m_rowstart[i] = current_edge; - g_vertex v = ordered_verts_of_g[i]; - g_out_edge_iter ei, ei_end; - for (boost::tie(ei, ei_end) = out_edges(v, g); ei != ei_end; ++ei) { - m_column[current_edge++] = get(vi, target(*ei, g)); + public: + Vertex src; + EdgeIndex idx; + + csr_edge_descriptor(Vertex src, EdgeIndex idx) : src(src), idx(idx) {} + csr_edge_descriptor() : src(0), idx(0) {} + + bool operator==(const csr_edge_descriptor& e) const + { + return idx == e.idx; } - } - m_rowstart[numverts] = current_edge; - } + bool operator!=(const csr_edge_descriptor& e) const + { + return idx != e.idx; + } + bool operator<(const csr_edge_descriptor& e) const + { + return idx < e.idx; + } + bool operator>(const csr_edge_descriptor& e) const + { + return idx > e.idx; + } + bool operator<=(const csr_edge_descriptor& e) const + { + return idx <= e.idx; + } + bool operator>=(const csr_edge_descriptor& e) const + { + return idx >= e.idx; + } + + template < typename Archiver > + void serialize(Archiver& ar, const unsigned int /*version*/) + { + ar& src& idx; + } + }; + + // Common out edge and edge iterators + template < typename CSRGraph > + class csr_out_edge_iterator + : public iterator_facade< csr_out_edge_iterator< CSRGraph >, + typename CSRGraph::edge_descriptor, std::random_access_iterator_tag, + const typename CSRGraph::edge_descriptor&, + typename int_t< CHAR_BIT + * sizeof(typename CSRGraph::edges_size_type) >::fast > + { + public: + typedef typename CSRGraph::edges_size_type EdgeIndex; + typedef typename CSRGraph::edge_descriptor edge_descriptor; + typedef typename int_t< CHAR_BIT * sizeof(EdgeIndex) >::fast + difference_type; + + csr_out_edge_iterator() {} + // Implicit copy constructor OK + explicit csr_out_edge_iterator(edge_descriptor edge) : m_edge(edge) {} + + public: // GCC 4.2.1 doesn't like the private-and-friend thing + // iterator_facade requirements + const edge_descriptor& dereference() const { return m_edge; } + + bool equal(const csr_out_edge_iterator& other) const + { + return m_edge == other.m_edge; + } + + void increment() { ++m_edge.idx; } + void decrement() { --m_edge.idx; } + void advance(difference_type n) { m_edge.idx += n; } - // Add edges from a sorted (smallest sources first) range of pairs and edge - // properties - template - void - add_edges_sorted_internal( - BidirectionalIteratorOrig first_sorted, - BidirectionalIteratorOrig last_sorted, - EPIterOrig ep_iter_sorted, - const GlobalToLocal& global_to_local) { - typedef boost::reverse_iterator BidirectionalIterator; - typedef boost::reverse_iterator EPIter; - // Flip sequence - BidirectionalIterator first(last_sorted); - BidirectionalIterator last(first_sorted); - typedef Vertex vertex_num; - typedef EdgeIndex edge_num; - edge_num new_edge_count = std::distance(first, last); - - EPIter ep_iter(ep_iter_sorted); - std::advance(ep_iter, -(std::ptrdiff_t)new_edge_count); - edge_num edges_added_before_i = new_edge_count; // Count increment to add to rowstarts - m_column.resize(m_column.size() + new_edge_count); - inherited_edge_properties::resize(inherited_edge_properties::size() + new_edge_count); - BidirectionalIterator current_new_edge = first, prev_new_edge = first; - EPIter current_new_edge_prop = ep_iter; - for (vertex_num i_plus_1 = m_rowstart.size() - 1; i_plus_1 > 0; --i_plus_1) { - vertex_num i = i_plus_1 - 1; - prev_new_edge = current_new_edge; - // edges_added_to_this_vertex = #mbrs of new_edges with first == i - edge_num edges_added_to_this_vertex = 0; - while (current_new_edge != last) { - if (get(global_to_local, current_new_edge->first) != i) break; - ++current_new_edge; - ++current_new_edge_prop; - ++edges_added_to_this_vertex; + difference_type distance_to(const csr_out_edge_iterator& other) const + { + return other.m_edge.idx - m_edge.idx; } - edges_added_before_i -= edges_added_to_this_vertex; - // Invariant: edges_added_before_i = #mbrs of new_edges with first < i - edge_num old_rowstart = m_rowstart[i]; - edge_num new_rowstart = m_rowstart[i] + edges_added_before_i; - edge_num old_degree = m_rowstart[i + 1] - m_rowstart[i]; - edge_num new_degree = old_degree + edges_added_to_this_vertex; - // Move old edges forward (by #new_edges before this i) to make room - // new_rowstart > old_rowstart, so use copy_backwards - if (old_rowstart != new_rowstart) { - std::copy_backward(m_column.begin() + old_rowstart, - m_column.begin() + old_rowstart + old_degree, - m_column.begin() + new_rowstart + old_degree); - inherited_edge_properties::move_range(old_rowstart, old_rowstart + old_degree, new_rowstart); + + edge_descriptor m_edge; + + friend class boost::iterator_core_access; + }; + + template < typename CSRGraph > + class csr_edge_iterator + : public iterator_facade< csr_edge_iterator< CSRGraph >, + typename CSRGraph::edge_descriptor, boost::forward_traversal_tag, + typename CSRGraph::edge_descriptor > + { + private: + typedef typename CSRGraph::edge_descriptor edge_descriptor; + typedef typename CSRGraph::edges_size_type EdgeIndex; + + public: + csr_edge_iterator() + : rowstart_array(0) + , current_edge() + , end_of_this_vertex(0) + , total_num_edges(0) + { } - // Add new edges (reversed because current_new_edge is a - // const_reverse_iterator) - BidirectionalIterator temp = current_new_edge; - EPIter temp_prop = current_new_edge_prop; - for (; temp != prev_new_edge; ++old_degree) { - --temp; - --temp_prop; - m_column[new_rowstart + old_degree] = temp->second; - inherited_edge_properties::write_by_index(new_rowstart + old_degree, *temp_prop); + + csr_edge_iterator(const CSRGraph& graph, edge_descriptor current_edge, + EdgeIndex end_of_this_vertex) + : rowstart_array(&graph.m_forward.m_rowstart[0]) + , current_edge(current_edge) + , end_of_this_vertex(end_of_this_vertex) + , total_num_edges(num_edges(graph)) + { } - m_rowstart[i + 1] = new_rowstart + new_degree; - if (edges_added_before_i == 0) break; // No more edges inserted before this point - // m_rowstart[i] will be fixed up on the next iteration (to avoid - // changing the degree of vertex i - 1); the last iteration never changes - // it (either because of the condition of the break or because - // m_rowstart[0] is always 0) - } - } - }; + public: // See above + friend class boost::iterator_core_access; - template - class csr_edge_descriptor - { - public: - Vertex src; - EdgeIndex idx; + edge_descriptor dereference() const { return current_edge; } - csr_edge_descriptor(Vertex src, EdgeIndex idx): src(src), idx(idx) {} - csr_edge_descriptor(): src(0), idx(0) {} + bool equal(const csr_edge_iterator& o) const + { + return current_edge == o.current_edge; + } - bool operator==(const csr_edge_descriptor& e) const {return idx == e.idx;} - bool operator!=(const csr_edge_descriptor& e) const {return idx != e.idx;} - bool operator<(const csr_edge_descriptor& e) const {return idx < e.idx;} - bool operator>(const csr_edge_descriptor& e) const {return idx > e.idx;} - bool operator<=(const csr_edge_descriptor& e) const {return idx <= e.idx;} - bool operator>=(const csr_edge_descriptor& e) const {return idx >= e.idx;} + void increment() + { + ++current_edge.idx; + if (current_edge.idx == total_num_edges) + return; + while (current_edge.idx == end_of_this_vertex) + { + ++current_edge.src; + end_of_this_vertex = rowstart_array[current_edge.src + 1]; + } + } - template - void serialize(Archiver& ar, const unsigned int /*version*/) + const EdgeIndex* rowstart_array; + edge_descriptor current_edge; + EdgeIndex end_of_this_vertex; + EdgeIndex total_num_edges; + }; + + // Only for bidirectional graphs + template < typename CSRGraph > + class csr_in_edge_iterator + : public iterator_facade< csr_in_edge_iterator< CSRGraph >, + typename CSRGraph::edge_descriptor, boost::forward_traversal_tag, + typename CSRGraph::edge_descriptor > { - ar & src & idx; - } - }; - - // Common out edge and edge iterators - template - class csr_out_edge_iterator - : public iterator_facade, - typename CSRGraph::edge_descriptor, - std::random_access_iterator_tag, - const typename CSRGraph::edge_descriptor&, - typename int_t::fast> - { - public: - typedef typename CSRGraph::edges_size_type EdgeIndex; - typedef typename CSRGraph::edge_descriptor edge_descriptor; - typedef typename int_t::fast difference_type; - - csr_out_edge_iterator() {} - // Implicit copy constructor OK - explicit csr_out_edge_iterator(edge_descriptor edge) : m_edge(edge) { } - - public: // GCC 4.2.1 doesn't like the private-and-friend thing - // iterator_facade requirements - const edge_descriptor& dereference() const { return m_edge; } - - bool equal(const csr_out_edge_iterator& other) const - { return m_edge == other.m_edge; } - - void increment() { ++m_edge.idx; } - void decrement() { --m_edge.idx; } - void advance(difference_type n) { m_edge.idx += n; } - - difference_type distance_to(const csr_out_edge_iterator& other) const - { return other.m_edge.idx - m_edge.idx; } - - edge_descriptor m_edge; - - friend class boost::iterator_core_access; - }; - - template - class csr_edge_iterator - : public iterator_facade, - typename CSRGraph::edge_descriptor, - boost::forward_traversal_tag, - typename CSRGraph::edge_descriptor> - { - private: - typedef typename CSRGraph::edge_descriptor edge_descriptor; - typedef typename CSRGraph::edges_size_type EdgeIndex; - - public: - csr_edge_iterator() : rowstart_array(0), current_edge(), end_of_this_vertex(0), total_num_edges(0) {} - - csr_edge_iterator(const CSRGraph& graph, - edge_descriptor current_edge, - EdgeIndex end_of_this_vertex) - : rowstart_array(&graph.m_forward.m_rowstart[0]), - current_edge(current_edge), - end_of_this_vertex(end_of_this_vertex), - total_num_edges(num_edges(graph)) {} - - public: // See above - friend class boost::iterator_core_access; - - edge_descriptor dereference() const {return current_edge;} - - bool equal(const csr_edge_iterator& o) const { - return current_edge == o.current_edge; - } + public: + typedef typename CSRGraph::edges_size_type EdgeIndex; + typedef typename CSRGraph::edge_descriptor edge_descriptor; + + csr_in_edge_iterator() : m_graph(0) {} + // Implicit copy constructor OK + csr_in_edge_iterator( + const CSRGraph& graph, EdgeIndex index_in_backward_graph) + : m_index_in_backward_graph(index_in_backward_graph), m_graph(&graph) + { + } - void increment() { - ++current_edge.idx; - if (current_edge.idx == total_num_edges) return; - while (current_edge.idx == end_of_this_vertex) { - ++current_edge.src; - end_of_this_vertex = rowstart_array[current_edge.src + 1]; - } - } + public: // See above + // iterator_facade requirements + edge_descriptor dereference() const + { + return edge_descriptor( + m_graph->m_backward.m_column[m_index_in_backward_graph], + m_graph->m_backward + .m_edge_properties[m_index_in_backward_graph]); + } - const EdgeIndex* rowstart_array; - edge_descriptor current_edge; - EdgeIndex end_of_this_vertex; - EdgeIndex total_num_edges; - }; - - // Only for bidirectional graphs - template - class csr_in_edge_iterator - : public iterator_facade, - typename CSRGraph::edge_descriptor, - boost::forward_traversal_tag, - typename CSRGraph::edge_descriptor> - { - public: - typedef typename CSRGraph::edges_size_type EdgeIndex; - typedef typename CSRGraph::edge_descriptor edge_descriptor; - - csr_in_edge_iterator(): m_graph(0) {} - // Implicit copy constructor OK - csr_in_edge_iterator(const CSRGraph& graph, - EdgeIndex index_in_backward_graph) - : m_index_in_backward_graph(index_in_backward_graph), m_graph(&graph) {} - - public: // See above - // iterator_facade requirements - edge_descriptor dereference() const { - return edge_descriptor( - m_graph->m_backward.m_column[m_index_in_backward_graph], - m_graph->m_backward.m_edge_properties[m_index_in_backward_graph]); - } + bool equal(const csr_in_edge_iterator& other) const + { + return m_index_in_backward_graph == other.m_index_in_backward_graph; + } - bool equal(const csr_in_edge_iterator& other) const - { return m_index_in_backward_graph == other.m_index_in_backward_graph; } + void increment() { ++m_index_in_backward_graph; } + void decrement() { --m_index_in_backward_graph; } + void advance(std::ptrdiff_t n) { m_index_in_backward_graph += n; } - void increment() { ++m_index_in_backward_graph; } - void decrement() { --m_index_in_backward_graph; } - void advance(std::ptrdiff_t n) { m_index_in_backward_graph += n; } + std::ptrdiff_t distance_to(const csr_in_edge_iterator& other) const + { + return other.m_index_in_backward_graph - m_index_in_backward_graph; + } - std::ptrdiff_t distance_to(const csr_in_edge_iterator& other) const - { return other.m_index_in_backward_graph - m_index_in_backward_graph; } + EdgeIndex m_index_in_backward_graph; + const CSRGraph* m_graph; - EdgeIndex m_index_in_backward_graph; - const CSRGraph* m_graph; + friend class boost::iterator_core_access; + }; - friend class boost::iterator_core_access; - }; + template < typename A, typename B > struct transpose_pair + { + typedef std::pair< B, A > result_type; + result_type operator()(const std::pair< A, B >& p) const + { + return result_type(p.second, p.first); + } + }; - template - struct transpose_pair { - typedef std::pair result_type; - result_type operator()(const std::pair& p) const { - return result_type(p.second, p.first); - } - }; - - template - struct transpose_iterator_gen { - typedef typename std::iterator_traits::value_type vt; - typedef typename vt::first_type first_type; - typedef typename vt::second_type second_type; - typedef transpose_pair transpose; - typedef boost::transform_iterator type; - static type make(Iter it) { - return type(it, transpose()); + template < typename Iter > struct transpose_iterator_gen + { + typedef typename std::iterator_traits< Iter >::value_type vt; + typedef typename vt::first_type first_type; + typedef typename vt::second_type second_type; + typedef transpose_pair< first_type, second_type > transpose; + typedef boost::transform_iterator< transpose, Iter > type; + static type make(Iter it) { return type(it, transpose()); } + }; + + template < typename Iter > + typename transpose_iterator_gen< Iter >::type transpose_edges(Iter i) + { + return transpose_iterator_gen< Iter >::make(i); } - }; - template - typename transpose_iterator_gen::type transpose_edges(Iter i) { - return transpose_iterator_gen::make(i); - } + template < typename GraphT, typename VertexIndexMap > + class edge_to_index_pair + { + typedef typename boost::graph_traits< GraphT >::vertices_size_type + vertices_size_type; + typedef typename boost::graph_traits< GraphT >::edge_descriptor + edge_descriptor; - template - class edge_to_index_pair - { - typedef typename boost::graph_traits::vertices_size_type - vertices_size_type; - typedef typename boost::graph_traits::edge_descriptor edge_descriptor; + public: + typedef std::pair< vertices_size_type, vertices_size_type > result_type; - public: - typedef std::pair result_type; + edge_to_index_pair() : g(0), index() {} + edge_to_index_pair(const GraphT& g, const VertexIndexMap& index) + : g(&g), index(index) + { + } - edge_to_index_pair() : g(0), index() { } - edge_to_index_pair(const GraphT& g, const VertexIndexMap& index) - : g(&g), index(index) - { } + result_type operator()(edge_descriptor e) const + { + return result_type( + get(index, source(e, *g)), get(index, target(e, *g))); + } - result_type operator()(edge_descriptor e) const + private: + const GraphT* g; + VertexIndexMap index; + }; + + template < typename GraphT, typename VertexIndexMap > + edge_to_index_pair< GraphT, VertexIndexMap > make_edge_to_index_pair( + const GraphT& g, const VertexIndexMap& index) { - return result_type(get(index, source(e, *g)), get(index, target(e, *g))); + return edge_to_index_pair< GraphT, VertexIndexMap >(g, index); } - private: - const GraphT* g; - VertexIndexMap index; - }; - - template - edge_to_index_pair - make_edge_to_index_pair(const GraphT& g, const VertexIndexMap& index) - { - return edge_to_index_pair(g, index); - } - - template - edge_to_index_pair - ::const_type> - make_edge_to_index_pair(const GraphT& g) - { - typedef typename boost::property_map::const_type - VertexIndexMap; - return edge_to_index_pair(g, - get(boost::vertex_index, - g)); - } - - template - boost::transform_iterator, Iter> - make_edge_to_index_pair_iter(const GraphT& g, const VertexIndexMap& index, - Iter it) { - return boost::transform_iterator, Iter>(it, edge_to_index_pair(g, index)); - } + template < typename GraphT > + edge_to_index_pair< GraphT, + typename boost::property_map< GraphT, + boost::vertex_index_t >::const_type > + make_edge_to_index_pair(const GraphT& g) + { + typedef typename boost::property_map< GraphT, + boost::vertex_index_t >::const_type VertexIndexMap; + return edge_to_index_pair< GraphT, VertexIndexMap >( + g, get(boost::vertex_index, g)); + } + + template < typename GraphT, typename VertexIndexMap, typename Iter > + boost::transform_iterator< edge_to_index_pair< GraphT, VertexIndexMap >, + Iter > + make_edge_to_index_pair_iter( + const GraphT& g, const VertexIndexMap& index, Iter it) + { + return boost::transform_iterator< + edge_to_index_pair< GraphT, VertexIndexMap >, Iter >( + it, edge_to_index_pair< GraphT, VertexIndexMap >(g, index)); + } } // namespace detail - template - struct hash > - { - std::size_t operator() - (detail::csr_edge_descriptor const& x) const +template < typename Vertex, typename EdgeIndex > +struct hash< detail::csr_edge_descriptor< Vertex, EdgeIndex > > +{ + std::size_t operator()( + detail::csr_edge_descriptor< Vertex, EdgeIndex > const& x) const { - std::size_t hash = hash_value(x.src); - hash_combine(hash, x.idx); - return hash; + std::size_t hash = hash_value(x.src); + hash_combine(hash, x.idx); + return hash; } - }; +}; } // namespace boost diff --git a/include/boost/graph/detail/connected_components.hpp b/include/boost/graph/detail/connected_components.hpp index 0af774601..a97159118 100644 --- a/include/boost/graph/detail/connected_components.hpp +++ b/include/boost/graph/detail/connected_components.hpp @@ -15,9 +15,11 @@ #include -namespace boost { +namespace boost +{ - namespace detail { +namespace detail +{ //========================================================================= // Implementation details of connected_components @@ -25,184 +27,180 @@ namespace boost { // This is used both in the connected_components algorithm and in // the kosaraju strong components algorithm during the second DFS // traversal. - template + template < class ComponentsPA, class DFSVisitor > class components_recorder : public DFSVisitor { - typedef typename property_traits::value_type comp_type; + typedef typename property_traits< ComponentsPA >::value_type comp_type; + public: - components_recorder(ComponentsPA c, - comp_type& c_count, - DFSVisitor v) - : DFSVisitor(v), m_component(c), m_count(c_count) {} - - template - void start_vertex(Vertex u, Graph& g) { - ++m_count; - DFSVisitor::start_vertex(u, g); - } - template - void discover_vertex(Vertex u, Graph& g) { - put(m_component, u, m_count); - DFSVisitor::discover_vertex(u, g); - } + components_recorder(ComponentsPA c, comp_type& c_count, DFSVisitor v) + : DFSVisitor(v), m_component(c), m_count(c_count) + { + } + + template < class Vertex, class Graph > + void start_vertex(Vertex u, Graph& g) + { + ++m_count; + DFSVisitor::start_vertex(u, g); + } + template < class Vertex, class Graph > + void discover_vertex(Vertex u, Graph& g) + { + put(m_component, u, m_count); + DFSVisitor::discover_vertex(u, g); + } + protected: - ComponentsPA m_component; - comp_type& m_count; + ComponentsPA m_component; + comp_type& m_count; }; - template + template < class DiscoverTimeMap, class FinishTimeMap, class TimeT, + class DFSVisitor > class time_recorder : public DFSVisitor { public: - time_recorder(DiscoverTimeMap d, FinishTimeMap f, TimeT& t, DFSVisitor v) - : DFSVisitor(v), m_discover_time(d), m_finish_time(f), m_t(t) {} - - template - void discover_vertex(Vertex u, Graph& g) { - put(m_discover_time, u, ++m_t); - DFSVisitor::discover_vertex(u, g); - } - template - void finish_vertex(Vertex u, Graph& g) { - put(m_finish_time, u, ++m_t); - DFSVisitor::discover_vertex(u, g); - } + time_recorder( + DiscoverTimeMap d, FinishTimeMap f, TimeT& t, DFSVisitor v) + : DFSVisitor(v), m_discover_time(d), m_finish_time(f), m_t(t) + { + } + + template < class Vertex, class Graph > + void discover_vertex(Vertex u, Graph& g) + { + put(m_discover_time, u, ++m_t); + DFSVisitor::discover_vertex(u, g); + } + template < class Vertex, class Graph > + void finish_vertex(Vertex u, Graph& g) + { + put(m_finish_time, u, ++m_t); + DFSVisitor::discover_vertex(u, g); + } + protected: - DiscoverTimeMap m_discover_time; - FinishTimeMap m_finish_time; - TimeT m_t; + DiscoverTimeMap m_discover_time; + FinishTimeMap m_finish_time; + TimeT m_t; }; - template - time_recorder + template < class DiscoverTimeMap, class FinishTimeMap, class TimeT, + class DFSVisitor > + time_recorder< DiscoverTimeMap, FinishTimeMap, TimeT, DFSVisitor > record_times(DiscoverTimeMap d, FinishTimeMap f, TimeT& t, DFSVisitor vis) { - return time_recorder - (d, f, t, vis); + return time_recorder< DiscoverTimeMap, FinishTimeMap, TimeT, + DFSVisitor >(d, f, t, vis); } //========================================================================= // Implementation detail of dynamic_components - //------------------------------------------------------------------------- // Helper functions for the component_index class - + // Record the representative vertices in the header array. // Representative vertices now point to the component number. - - template - inline void - build_components_header(Parent p, - OutputIterator header, - Integer num_nodes) + + template < class Parent, class OutputIterator, class Integer > + inline void build_components_header( + Parent p, OutputIterator header, Integer num_nodes) { - Parent component = p; - Integer component_num = 0; - for (Integer v = 0; v != num_nodes; ++v) - if (p[v] == v) { - *header++ = v; - component[v] = component_num++; - } + Parent component = p; + Integer component_num = 0; + for (Integer v = 0; v != num_nodes; ++v) + if (p[v] == v) + { + *header++ = v; + component[v] = component_num++; + } } - - + // Pushes x onto the front of the list. The list is represented in // an array. - template + template < class Next, class T, class V > inline void push_front(Next next, T& head, V x) { - T tmp = head; - head = x; - next[x] = tmp; + T tmp = head; + head = x; + next[x] = tmp; } - - + // Create a linked list of the vertices in each component // by reusing the representative array. - template - void - link_components(Parent1 component, Parent2 header, - Integer num_nodes, Integer num_components) + template < class Parent1, class Parent2, class Integer > + void link_components(Parent1 component, Parent2 header, Integer num_nodes, + Integer num_components) { - // Make the non-representative vertices point to their component - Parent1 representative = component; - for (Integer v = 0; v != num_nodes; ++v) - if (component[v] >= num_components || header[component[v]] != v) - component[v] = component[representative[v]]; - - // initialize the "head" of the lists to "NULL" - std::fill_n(header, num_components, num_nodes); - - // Add each vertex to the linked list for its component - Parent1 next = component; - for (Integer k = 0; k != num_nodes; ++k) - push_front(next, header[component[k]], k); + // Make the non-representative vertices point to their component + Parent1 representative = component; + for (Integer v = 0; v != num_nodes; ++v) + if (component[v] >= num_components || header[component[v]] != v) + component[v] = component[representative[v]]; + + // initialize the "head" of the lists to "NULL" + std::fill_n(header, num_components, num_nodes); + + // Add each vertex to the linked list for its component + Parent1 next = component; + for (Integer k = 0; k != num_nodes; ++k) + push_front(next, header[component[k]], k); } - - - template - void - construct_component_index(IndexContainer& index, HeaderContainer& header) + template < class IndexContainer, class HeaderContainer > + void construct_component_index( + IndexContainer& index, HeaderContainer& header) { - build_components_header(index.begin(), - std::back_inserter(header), - index.end() - index.begin()); - - link_components(index.begin(), header.begin(), - index.end() - index.begin(), - header.end() - header.begin()); + build_components_header(index.begin(), std::back_inserter(header), + index.end() - index.begin()); + + link_components(index.begin(), header.begin(), + index.end() - index.begin(), header.end() - header.begin()); } - - - - template - class component_iterator - : boost::forward_iterator_helper< - component_iterator, - Integer, Distance,Integer*, Integer&> + + template < class IndexIterator, class Integer, class Distance > + class component_iterator + : boost::forward_iterator_helper< + component_iterator< IndexIterator, Integer, Distance >, Integer, + Distance, Integer*, Integer& > { public: - typedef component_iterator self; - - IndexIterator next; - Integer node; - - typedef std::forward_iterator_tag iterator_category; - typedef Integer value_type; - typedef Integer& reference; - typedef Integer* pointer; - typedef Distance difference_type; - - component_iterator() {} - component_iterator(IndexIterator x, Integer i) - : next(x), node(i) {} - Integer operator*() const { - return node; - } - self& operator++() { - node = next[node]; - return *this; - } + typedef component_iterator self; + + IndexIterator next; + Integer node; + + typedef std::forward_iterator_tag iterator_category; + typedef Integer value_type; + typedef Integer& reference; + typedef Integer* pointer; + typedef Distance difference_type; + + component_iterator() {} + component_iterator(IndexIterator x, Integer i) : next(x), node(i) {} + Integer operator*() const { return node; } + self& operator++() + { + node = next[node]; + return *this; + } }; - - template - inline bool - operator==(const component_iterator& x, - const component_iterator& y) + + template < class IndexIterator, class Integer, class Distance > + inline bool operator==( + const component_iterator< IndexIterator, Integer, Distance >& x, + const component_iterator< IndexIterator, Integer, Distance >& y) { - return x.node == y.node; + return x.node == y.node; } - - } // namespace detail - + +} // namespace detail + } // namespace detail #if defined(__sgi) && !defined(__GNUC__) #pragma reset woff 1234 #endif -#endif +#endif diff --git a/include/boost/graph/detail/d_ary_heap.hpp b/include/boost/graph/detail/d_ary_heap.hpp index cf930fc18..e7dc4b91f 100644 --- a/include/boost/graph/detail/d_ary_heap.hpp +++ b/include/boost/graph/detail/d_ary_heap.hpp @@ -25,160 +25,172 @@ // (without move support from C++11), but it deep-copies the heap contents yet // shallow-copies the index_in_heap_map. -namespace boost { +namespace boost +{ - // Swap two elements in a property map without assuming they model - // LvaluePropertyMap -- currently not used - template - inline void property_map_swap( - PropMap prop_map, - const typename boost::property_traits::key_type& ka, - const typename boost::property_traits::key_type& kb) { - typename boost::property_traits::value_type va = get(prop_map, ka); +// Swap two elements in a property map without assuming they model +// LvaluePropertyMap -- currently not used +template < typename PropMap > +inline void property_map_swap(PropMap prop_map, + const typename boost::property_traits< PropMap >::key_type& ka, + const typename boost::property_traits< PropMap >::key_type& kb) +{ + typename boost::property_traits< PropMap >::value_type va + = get(prop_map, ka); put(prop_map, ka, get(prop_map, kb)); put(prop_map, kb, va); - } +} - namespace detail { - template - class fixed_max_size_vector { - boost::shared_array m_data; - std::size_t m_size; +namespace detail +{ + template < typename Value > class fixed_max_size_vector + { + boost::shared_array< Value > m_data; + std::size_t m_size; - public: - typedef std::size_t size_type; - fixed_max_size_vector(std::size_t max_size) - : m_data(new Value[max_size]), m_size(0) {} - std::size_t size() const {return m_size;} - bool empty() const {return m_size == 0;} - Value& operator[](std::size_t i) {return m_data[i];} - const Value& operator[](std::size_t i) const {return m_data[i];} - void push_back(Value v) {m_data[m_size++] = v;} - void pop_back() {--m_size;} - Value& back() {return m_data[m_size - 1];} - const Value& back() const {return m_data[m_size - 1];} + public: + typedef std::size_t size_type; + fixed_max_size_vector(std::size_t max_size) + : m_data(new Value[max_size]), m_size(0) + { + } + std::size_t size() const { return m_size; } + bool empty() const { return m_size == 0; } + Value& operator[](std::size_t i) { return m_data[i]; } + const Value& operator[](std::size_t i) const { return m_data[i]; } + void push_back(Value v) { m_data[m_size++] = v; } + void pop_back() { --m_size; } + Value& back() { return m_data[m_size - 1]; } + const Value& back() const { return m_data[m_size - 1]; } }; - } +} - // D-ary heap using an indirect compare operator (use identity_property_map - // as DistanceMap to get a direct compare operator). This heap appears to be - // commonly used for Dijkstra's algorithm for its good practical performance - // on some platforms; asymptotically, it has an O(lg N) decrease-key - // operation while that can be done in constant time on a relaxed heap. The - // implementation is mostly based on the binary heap page on Wikipedia and - // online sources that state that the operations are the same for d-ary - // heaps. This code is not based on the old Boost d-ary heap code. - // - // - d_ary_heap_indirect is a model of UpdatableQueue as is needed for - // dijkstra_shortest_paths. - // - // - Value must model Assignable. - // - Arity must be at least 2 (optimal value appears to be 4, both in my and - // third-party experiments). - // - IndexInHeapMap must be a ReadWritePropertyMap from Value to - // Container::size_type (to store the index of each stored value within the - // heap for decrease-key aka update). - // - DistanceMap must be a ReadablePropertyMap from Value to something - // (typedef'ed as distance_type). - // - Compare must be a BinaryPredicate used as a less-than operator on - // distance_type. - // - Container must be a random-access, contiguous container (in practice, - // the operations used probably require that it is std::vector). - // - template , - typename Container = std::vector > - class d_ary_heap_indirect { - BOOST_STATIC_ASSERT (Arity >= 2); +// D-ary heap using an indirect compare operator (use identity_property_map +// as DistanceMap to get a direct compare operator). This heap appears to be +// commonly used for Dijkstra's algorithm for its good practical performance +// on some platforms; asymptotically, it has an O(lg N) decrease-key +// operation while that can be done in constant time on a relaxed heap. The +// implementation is mostly based on the binary heap page on Wikipedia and +// online sources that state that the operations are the same for d-ary +// heaps. This code is not based on the old Boost d-ary heap code. +// +// - d_ary_heap_indirect is a model of UpdatableQueue as is needed for +// dijkstra_shortest_paths. +// +// - Value must model Assignable. +// - Arity must be at least 2 (optimal value appears to be 4, both in my and +// third-party experiments). +// - IndexInHeapMap must be a ReadWritePropertyMap from Value to +// Container::size_type (to store the index of each stored value within the +// heap for decrease-key aka update). +// - DistanceMap must be a ReadablePropertyMap from Value to something +// (typedef'ed as distance_type). +// - Compare must be a BinaryPredicate used as a less-than operator on +// distance_type. +// - Container must be a random-access, contiguous container (in practice, +// the operations used probably require that it is std::vector). +// +template < typename Value, std::size_t Arity, typename IndexInHeapPropertyMap, + typename DistanceMap, typename Compare = std::less< Value >, + typename Container = std::vector< Value > > +class d_ary_heap_indirect +{ + BOOST_STATIC_ASSERT(Arity >= 2); - public: +public: typedef typename Container::size_type size_type; typedef Value value_type; - typedef typename boost::property_traits::value_type key_type; + typedef typename boost::property_traits< DistanceMap >::value_type key_type; typedef DistanceMap key_map; d_ary_heap_indirect(DistanceMap distance, - IndexInHeapPropertyMap index_in_heap, - const Compare& compare = Compare(), - const Container& data = Container()) - : compare(compare), data(data), distance(distance), - index_in_heap(index_in_heap) {} + IndexInHeapPropertyMap index_in_heap, + const Compare& compare = Compare(), const Container& data = Container()) + : compare(compare) + , data(data) + , distance(distance) + , index_in_heap(index_in_heap) + { + } /* Implicit copy constructor */ /* Implicit assignment operator */ - size_type size() const { - return data.size(); - } + size_type size() const { return data.size(); } - bool empty() const { - return data.empty(); - } + bool empty() const { return data.empty(); } - void push(const Value& v) { - size_type index = data.size(); - data.push_back(v); - put(index_in_heap, v, index); - preserve_heap_property_up(index); - verify_heap(); + void push(const Value& v) + { + size_type index = data.size(); + data.push_back(v); + put(index_in_heap, v, index); + preserve_heap_property_up(index); + verify_heap(); } - Value& top() { - BOOST_ASSERT (!this->empty()); - return data[0]; + Value& top() + { + BOOST_ASSERT(!this->empty()); + return data[0]; } - const Value& top() const { - BOOST_ASSERT (!this->empty()); - return data[0]; + const Value& top() const + { + BOOST_ASSERT(!this->empty()); + return data[0]; } - void pop() { - BOOST_ASSERT (!this->empty()); - put(index_in_heap, data[0], (size_type)(-1)); - if (data.size() != 1) { - data[0] = data.back(); - put(index_in_heap, data[0], (size_type)(0)); - data.pop_back(); - preserve_heap_property_down(); - verify_heap(); - } else { - data.pop_back(); - } + void pop() + { + BOOST_ASSERT(!this->empty()); + put(index_in_heap, data[0], (size_type)(-1)); + if (data.size() != 1) + { + data[0] = data.back(); + put(index_in_heap, data[0], (size_type)(0)); + data.pop_back(); + preserve_heap_property_down(); + verify_heap(); + } + else + { + data.pop_back(); + } } // This function assumes the key has been updated (using an external write // to the distance map or such) - // See http://coding.derkeiler.com/Archive/General/comp.theory/2007-05/msg00043.html - void update(const Value& v) { /* decrease-key */ - size_type index = get(index_in_heap, v); - preserve_heap_property_up(index); - verify_heap(); + // See + // http://coding.derkeiler.com/Archive/General/comp.theory/2007-05/msg00043.html + void update(const Value& v) + { /* decrease-key */ + size_type index = get(index_in_heap, v); + preserve_heap_property_up(index); + verify_heap(); } - bool contains(const Value& v) const { - size_type index = get(index_in_heap, v); - return (index != (size_type)(-1)); + bool contains(const Value& v) const + { + size_type index = get(index_in_heap, v); + return (index != (size_type)(-1)); } - void push_or_update(const Value& v) { /* insert if not present, else update */ - size_type index = get(index_in_heap, v); - if (index == (size_type)(-1)) { - index = data.size(); - data.push_back(v); - put(index_in_heap, v, index); - } - preserve_heap_property_up(index); - verify_heap(); + void push_or_update(const Value& v) + { /* insert if not present, else update */ + size_type index = get(index_in_heap, v); + if (index == (size_type)(-1)) + { + index = data.size(); + data.push_back(v); + put(index_in_heap, v, index); + } + preserve_heap_property_up(index); + verify_heap(); } - DistanceMap keys() const { - return distance; - } + DistanceMap keys() const { return distance; } - private: +private: Compare compare; Container data; DistanceMap distance; @@ -186,38 +198,41 @@ namespace boost { // The distances being compared using compare and that are stored in the // distance map - typedef typename boost::property_traits::value_type distance_type; + typedef typename boost::property_traits< DistanceMap >::value_type + distance_type; // Get the parent of a given node in the heap - static size_type parent(size_type index) { - return (index - 1) / Arity; - } + static size_type parent(size_type index) { return (index - 1) / Arity; } // Get the child_idx'th child of a given node; 0 <= child_idx < Arity - static size_type child(size_type index, std::size_t child_idx) { - return index * Arity + child_idx + 1; + static size_type child(size_type index, std::size_t child_idx) + { + return index * Arity + child_idx + 1; } // Swap two elements in the heap by index, updating index_in_heap - void swap_heap_elements(size_type index_a, size_type index_b) { - using std::swap; - Value value_a = data[index_a]; - Value value_b = data[index_b]; - data[index_a] = value_b; - data[index_b] = value_a; - put(index_in_heap, value_a, index_b); - put(index_in_heap, value_b, index_a); + void swap_heap_elements(size_type index_a, size_type index_b) + { + using std::swap; + Value value_a = data[index_a]; + Value value_b = data[index_b]; + data[index_a] = value_b; + data[index_b] = value_a; + put(index_in_heap, value_a, index_b); + put(index_in_heap, value_b, index_a); } // Emulate the indirect_cmp that is now folded into this heap class - bool compare_indirect(const Value& a, const Value& b) const { - return compare(get(distance, a), get(distance, b)); + bool compare_indirect(const Value& a, const Value& b) const + { + return compare(get(distance, a), get(distance, b)); } // Verify that the array forms a heap; commented out by default - void verify_heap() const { - // This is a very expensive test so it should be disabled even when - // NDEBUG is not defined + void verify_heap() const + { + // This is a very expensive test so it should be disabled even when + // NDEBUG is not defined #if 0 for (size_t i = 1; i < data.size(); ++i) { if (compare_indirect(data[i], data[parent(i)])) { @@ -229,90 +244,114 @@ namespace boost { // Starting at a node, move up the tree swapping elements to preserve the // heap property - void preserve_heap_property_up(size_type index) { - size_type orig_index = index; - size_type num_levels_moved = 0; - // The first loop just saves swaps that need to be done in order to avoid - // aliasing issues in its search; there is a second loop that does the - // necessary swap operations - if (index == 0) return; // Do nothing on root - Value currently_being_moved = data[index]; - distance_type currently_being_moved_dist = - get(distance, currently_being_moved); - for (;;) { - if (index == 0) break; // Stop at root - size_type parent_index = parent(index); - Value parent_value = data[parent_index]; - if (compare(currently_being_moved_dist, get(distance, parent_value))) { - ++num_levels_moved; - index = parent_index; - continue; - } else { - break; // Heap property satisfied + void preserve_heap_property_up(size_type index) + { + size_type orig_index = index; + size_type num_levels_moved = 0; + // The first loop just saves swaps that need to be done in order to + // avoid aliasing issues in its search; there is a second loop that does + // the necessary swap operations + if (index == 0) + return; // Do nothing on root + Value currently_being_moved = data[index]; + distance_type currently_being_moved_dist + = get(distance, currently_being_moved); + for (;;) + { + if (index == 0) + break; // Stop at root + size_type parent_index = parent(index); + Value parent_value = data[parent_index]; + if (compare( + currently_being_moved_dist, get(distance, parent_value))) + { + ++num_levels_moved; + index = parent_index; + continue; + } + else + { + break; // Heap property satisfied + } } - } - // Actually do the moves -- move num_levels_moved elements down in the - // tree, then put currently_being_moved at the top - index = orig_index; - for (size_type i = 0; i < num_levels_moved; ++i) { - size_type parent_index = parent(index); - Value parent_value = data[parent_index]; - put(index_in_heap, parent_value, index); - data[index] = parent_value; - index = parent_index; - } - data[index] = currently_being_moved; - put(index_in_heap, currently_being_moved, index); - verify_heap(); + // Actually do the moves -- move num_levels_moved elements down in the + // tree, then put currently_being_moved at the top + index = orig_index; + for (size_type i = 0; i < num_levels_moved; ++i) + { + size_type parent_index = parent(index); + Value parent_value = data[parent_index]; + put(index_in_heap, parent_value, index); + data[index] = parent_value; + index = parent_index; + } + data[index] = currently_being_moved; + put(index_in_heap, currently_being_moved, index); + verify_heap(); } // From the root, swap elements (each one with its smallest child) if there // are any parent-child pairs that violate the heap property - void preserve_heap_property_down() { - if (data.empty()) return; - size_type index = 0; - Value currently_being_moved = data[0]; - distance_type currently_being_moved_dist = - get(distance, currently_being_moved); - size_type heap_size = data.size(); - Value* data_ptr = &data[0]; - for (;;) { - size_type first_child_index = child(index, 0); - if (first_child_index >= heap_size) break; /* No children */ - Value* child_base_ptr = data_ptr + first_child_index; - size_type smallest_child_index = 0; - distance_type smallest_child_dist = get(distance, child_base_ptr[smallest_child_index]); - if (first_child_index + Arity <= heap_size) { - // Special case for a statically known loop count (common case) - for (size_t i = 1; i < Arity; ++i) { - Value i_value = child_base_ptr[i]; - distance_type i_dist = get(distance, i_value); - if (compare(i_dist, smallest_child_dist)) { - smallest_child_index = i; - smallest_child_dist = i_dist; + void preserve_heap_property_down() + { + if (data.empty()) + return; + size_type index = 0; + Value currently_being_moved = data[0]; + distance_type currently_being_moved_dist + = get(distance, currently_being_moved); + size_type heap_size = data.size(); + Value* data_ptr = &data[0]; + for (;;) + { + size_type first_child_index = child(index, 0); + if (first_child_index >= heap_size) + break; /* No children */ + Value* child_base_ptr = data_ptr + first_child_index; + size_type smallest_child_index = 0; + distance_type smallest_child_dist + = get(distance, child_base_ptr[smallest_child_index]); + if (first_child_index + Arity <= heap_size) + { + // Special case for a statically known loop count (common case) + for (size_t i = 1; i < Arity; ++i) + { + Value i_value = child_base_ptr[i]; + distance_type i_dist = get(distance, i_value); + if (compare(i_dist, smallest_child_dist)) + { + smallest_child_index = i; + smallest_child_dist = i_dist; + } + } } - } - } else { - for (size_t i = 1; i < heap_size - first_child_index; ++i) { - distance_type i_dist = get(distance, child_base_ptr[i]); - if (compare(i_dist, smallest_child_dist)) { - smallest_child_index = i; - smallest_child_dist = i_dist; + else + { + for (size_t i = 1; i < heap_size - first_child_index; ++i) + { + distance_type i_dist = get(distance, child_base_ptr[i]); + if (compare(i_dist, smallest_child_dist)) + { + smallest_child_index = i; + smallest_child_dist = i_dist; + } + } + } + if (compare(smallest_child_dist, currently_being_moved_dist)) + { + swap_heap_elements( + smallest_child_index + first_child_index, index); + index = smallest_child_index + first_child_index; + continue; + } + else + { + break; // Heap property satisfied } - } - } - if (compare(smallest_child_dist, currently_being_moved_dist)) { - swap_heap_elements(smallest_child_index + first_child_index, index); - index = smallest_child_index + first_child_index; - continue; - } else { - break; // Heap property satisfied } - } - verify_heap(); + verify_heap(); } - - }; +}; } // namespace boost diff --git a/include/boost/graph/detail/edge.hpp b/include/boost/graph/detail/edge.hpp index 3aba9f8d9..33cb305ec 100644 --- a/include/boost/graph/detail/edge.hpp +++ b/include/boost/graph/detail/edge.hpp @@ -15,107 +15,108 @@ #include -namespace boost { +namespace boost +{ - namespace detail { +namespace detail +{ - template - struct edge_base + template < typename Directed, typename Vertex > struct edge_base { - inline edge_base() {} - inline edge_base(Vertex s, Vertex d) - : m_source(s), m_target(d) { } - Vertex m_source; - Vertex m_target; + inline edge_base() {} + inline edge_base(Vertex s, Vertex d) : m_source(s), m_target(d) {} + Vertex m_source; + Vertex m_target; }; - template - class edge_desc_impl : public edge_base { - typedef edge_desc_impl self; - typedef edge_base Base; - public: - typedef void property_type; - - inline edge_desc_impl() : m_eproperty(0) {} - - inline edge_desc_impl(Vertex s, Vertex d, const property_type* eplug) - : Base(s,d), m_eproperty(const_cast(eplug)) { } - - property_type* get_property() { return m_eproperty; } - const property_type* get_property() const { return m_eproperty; } - - // protected: - property_type* m_eproperty; + template < typename Directed, typename Vertex > + class edge_desc_impl : public edge_base< Directed, Vertex > + { + typedef edge_desc_impl self; + typedef edge_base< Directed, Vertex > Base; + + public: + typedef void property_type; + + inline edge_desc_impl() : m_eproperty(0) {} + + inline edge_desc_impl(Vertex s, Vertex d, const property_type* eplug) + : Base(s, d), m_eproperty(const_cast< property_type* >(eplug)) + { + } + + property_type* get_property() { return m_eproperty; } + const property_type* get_property() const { return m_eproperty; } + + // protected: + property_type* m_eproperty; }; - template - inline bool - operator==(const detail::edge_desc_impl& a, - const detail::edge_desc_impl& b) + template < class D, class V > + inline bool operator==(const detail::edge_desc_impl< D, V >& a, + const detail::edge_desc_impl< D, V >& b) { - return a.get_property() == b.get_property(); + return a.get_property() == b.get_property(); } - template - inline bool - operator!=(const detail::edge_desc_impl& a, - const detail::edge_desc_impl& b) + template < class D, class V > + inline bool operator!=(const detail::edge_desc_impl< D, V >& a, + const detail::edge_desc_impl< D, V >& b) { - return ! (a.get_property() == b.get_property()); + return !(a.get_property() == b.get_property()); } // Order edges according to the address of their property object - template - inline bool - operator<(const detail::edge_desc_impl& a, - const detail::edge_desc_impl& b) + template < class D, class V > + inline bool operator<(const detail::edge_desc_impl< D, V >& a, + const detail::edge_desc_impl< D, V >& b) { - return a.get_property() < b.get_property(); + return a.get_property() < b.get_property(); } - template - inline bool - operator<=(const detail::edge_desc_impl& a, - const detail::edge_desc_impl& b) + template < class D, class V > + inline bool operator<=(const detail::edge_desc_impl< D, V >& a, + const detail::edge_desc_impl< D, V >& b) { - return a.get_property() <= b.get_property(); + return a.get_property() <= b.get_property(); } - template - inline bool - operator>(const detail::edge_desc_impl& a, - const detail::edge_desc_impl& b) + template < class D, class V > + inline bool operator>(const detail::edge_desc_impl< D, V >& a, + const detail::edge_desc_impl< D, V >& b) { - return a.get_property() > b.get_property(); + return a.get_property() > b.get_property(); } - template - inline bool - operator>=(const detail::edge_desc_impl& a, - const detail::edge_desc_impl& b) + template < class D, class V > + inline bool operator>=(const detail::edge_desc_impl< D, V >& a, + const detail::edge_desc_impl< D, V >& b) { - return a.get_property() >= b.get_property(); + return a.get_property() >= b.get_property(); } - } //namespace detail - +} // namespace detail + } // namespace boost -namespace std { - template - std::basic_ostream& - operator<<(std::basic_ostream& os, - const boost::detail::edge_desc_impl& e) - { +namespace std +{ +template < class Char, class Traits, class D, class V > +std::basic_ostream< Char, Traits >& operator<<( + std::basic_ostream< Char, Traits >& os, + const boost::detail::edge_desc_impl< D, V >& e) +{ return os << "(" << e.m_source << "," << e.m_target << ")"; - } +} } // Boost's functional/hash -namespace boost { - template - struct hash > - { - std::size_t operator()(const boost::detail::edge_desc_impl & x) const - { return hash_value(x.get_property()); } - }; +namespace boost +{ +template < typename D, typename V > +struct hash< boost::detail::edge_desc_impl< D, V > > +{ + std::size_t operator()(const boost::detail::edge_desc_impl< D, V >& x) const + { + return hash_value(x.get_property()); + } +}; } - #endif // BOOST_GRAPH_DETAIL_DETAIL_EDGE_HPP diff --git a/include/boost/graph/detail/geodesic.hpp b/include/boost/graph/detail/geodesic.hpp index b94482ccd..40b3cefc4 100644 --- a/include/boost/graph/detail/geodesic.hpp +++ b/include/boost/graph/detail/geodesic.hpp @@ -39,26 +39,24 @@ namespace boost // } // } -namespace detail { +namespace detail +{ // Note that this assumes T == property_traits::value_type // and that the args and return of combine are also T. - template - inline Distance - combine_distances(const Graph& g, - DistanceMap dist, - Combinator combine, - Distance init) + template < typename Graph, typename DistanceMap, typename Combinator, + typename Distance > + inline Distance combine_distances( + const Graph& g, DistanceMap dist, Combinator combine, Distance init) { - BOOST_CONCEPT_ASSERT(( VertexListGraphConcept )); - typedef typename graph_traits::vertex_descriptor Vertex; - typedef typename graph_traits::vertex_iterator VertexIterator; - BOOST_CONCEPT_ASSERT(( ReadablePropertyMapConcept )); - BOOST_CONCEPT_ASSERT(( NumericValueConcept )); - typedef numeric_values DistanceNumbers; - BOOST_CONCEPT_ASSERT(( AdaptableBinaryFunction )); + BOOST_CONCEPT_ASSERT((VertexListGraphConcept< Graph >)); + typedef typename graph_traits< Graph >::vertex_descriptor Vertex; + typedef typename graph_traits< Graph >::vertex_iterator VertexIterator; + BOOST_CONCEPT_ASSERT( + (ReadablePropertyMapConcept< DistanceMap, Vertex >)); + BOOST_CONCEPT_ASSERT((NumericValueConcept< Distance >)); + typedef numeric_values< Distance > DistanceNumbers; + BOOST_CONCEPT_ASSERT((AdaptableBinaryFunction< Combinator, Distance, + Distance, Distance >)); // If there's ever an infinite distance, then we simply return // infinity. Note that this /will/ include the a non-zero @@ -66,12 +64,15 @@ namespace detail { // zero, so it shouldn't be too problematic. Distance ret = init; VertexIterator i, end; - for(boost::tie(i, end) = vertices(g); i != end; ++i) { + for (boost::tie(i, end) = vertices(g); i != end; ++i) + { Vertex v = *i; - if(get(dist, v) != DistanceNumbers::infinity()) { + if (get(dist, v) != DistanceNumbers::infinity()) + { ret = combine(ret, get(dist, v)); } - else { + else + { ret = DistanceNumbers::infinity(); break; } @@ -81,51 +82,54 @@ namespace detail { // Similar to std::plus, but maximizes parameters // rather than adding them. - template - struct maximize + template < typename T > struct maximize { typedef T result_type; typedef T first_argument_type; typedef T second_argument_type; - T operator ()(T x, T y) const - { BOOST_USING_STD_MAX(); return max BOOST_PREVENT_MACRO_SUBSTITUTION (x, y); } + T operator()(T x, T y) const + { + BOOST_USING_STD_MAX(); + return max BOOST_PREVENT_MACRO_SUBSTITUTION(x, y); + } }; // Another helper, like maximize() to help abstract functional // concepts. This is trivially instantiated for builtin numeric // types, but should be specialized for those types that have // discrete notions of reciprocals. - template - struct reciprocal + template < typename T > struct reciprocal { typedef T result_type; typedef T argument_type; - T operator ()(T t) - { return T(1) / t; } + T operator()(T t) { return T(1) / t; } }; } /* namespace detail */ // This type defines the basic facilities used for computing values // based on the geodesic distances between vertices. Examples include // closeness centrality and mean geodesic distance. -template +template < typename Graph, typename DistanceType, typename ResultType > struct geodesic_measure { typedef DistanceType distance_type; typedef ResultType result_type; - typedef typename graph_traits::vertices_size_type size_type; + typedef typename graph_traits< Graph >::vertices_size_type size_type; - typedef numeric_values distance_values; - typedef numeric_values result_values; + typedef numeric_values< distance_type > distance_values; + typedef numeric_values< result_type > result_values; static inline distance_type infinite_distance() - { return distance_values::infinity(); } + { + return distance_values::infinity(); + } static inline result_type infinite_result() - { return result_values::infinity(); } + { + return result_values::infinity(); + } - static inline result_type zero_result() - { return result_values::zero(); } + static inline result_type zero_result() { return result_values::zero(); } }; } /* namespace boost */ diff --git a/include/boost/graph/detail/histogram_sort.hpp b/include/boost/graph/detail/histogram_sort.hpp index ef0363563..40025f5a7 100644 --- a/include/boost/graph/detail/histogram_sort.hpp +++ b/include/boost/graph/detail/histogram_sort.hpp @@ -12,282 +12,308 @@ #include -namespace boost { - namespace graph { - namespace detail { - -template -size_t -reserve_count_for_single_pass_helper(InputIterator, InputIterator, - std::input_iterator_tag) +namespace boost { - // Do nothing: we have no idea how much storage to reserve. - return 0; -} - -template -size_t -reserve_count_for_single_pass_helper(InputIterator first, InputIterator last, - std::random_access_iterator_tag) +namespace graph { - using std::distance; - typename std::iterator_traits::difference_type n = - distance(first, last); - return (size_t)n; -} - -template -size_t -reserve_count_for_single_pass(InputIterator first, InputIterator last) { - typedef typename std::iterator_traits::iterator_category - category; - return reserve_count_for_single_pass_helper(first, last, category()); -} - -template -void -count_starts - (KeyIterator begin, KeyIterator end, - RowstartIterator starts, // Must support numverts + 1 elements - VerticesSize numkeys, - KeyFilter key_filter, - KeyTransform key_transform) { - - typedef typename std::iterator_traits::value_type EdgeIndex; - - // Put the degree of each vertex v into m_rowstart[v + 1] - for (KeyIterator i = begin; i != end; ++i) { - if (key_filter(*i)) { - BOOST_ASSERT (key_transform(*i) < numkeys); - ++starts[key_transform(*i) + 1]; - } - } - - // Compute the partial sum of the degrees to get the actual values of - // m_rowstart - EdgeIndex start_of_this_row = 0; - starts[0] = start_of_this_row; - for (VerticesSize i = 1; i < numkeys + 1; ++i) { - start_of_this_row += starts[i]; - starts[i] = start_of_this_row; - } -} - -template -void -histogram_sort(KeyIterator key_begin, KeyIterator key_end, - RowstartIterator rowstart, // Must support numkeys + 1 elements and be precomputed - NumKeys numkeys, - Value1InputIter values1_begin, - Value1OutputIter values1_out, - KeyFilter key_filter, - KeyTransform key_transform) { - - typedef typename std::iterator_traits::value_type EdgeIndex; - - // Histogram sort the edges by their source vertices, putting the targets - // into m_column. The index current_insert_positions[v] contains the next - // location to insert out edges for vertex v. - std::vector - current_insert_positions(rowstart, rowstart + numkeys); - Value1InputIter v1i = values1_begin; - for (KeyIterator i = key_begin; i != key_end; ++i, ++v1i) { - if (key_filter(*i)) { - NumKeys source = key_transform(*i); - BOOST_ASSERT (source < numkeys); - EdgeIndex insert_pos = current_insert_positions[source]; - ++current_insert_positions[source]; - values1_out[insert_pos] = *v1i; - } - } -} - -template -void -histogram_sort(KeyIterator key_begin, KeyIterator key_end, - RowstartIterator rowstart, // Must support numkeys + 1 elements and be precomputed - NumKeys numkeys, - Value1InputIter values1_begin, - Value1OutputIter values1_out, - Value2InputIter values2_begin, - Value2OutputIter values2_out, - KeyFilter key_filter, - KeyTransform key_transform) { - - typedef typename std::iterator_traits::value_type EdgeIndex; - - // Histogram sort the edges by their source vertices, putting the targets - // into m_column. The index current_insert_positions[v] contains the next - // location to insert out edges for vertex v. - std::vector - current_insert_positions(rowstart, rowstart + numkeys); - Value1InputIter v1i = values1_begin; - Value2InputIter v2i = values2_begin; - for (KeyIterator i = key_begin; i != key_end; ++i, ++v1i, ++v2i) { - if (key_filter(*i)) { - NumKeys source = key_transform(*i); - BOOST_ASSERT (source < numkeys); - EdgeIndex insert_pos = current_insert_positions[source]; - ++current_insert_positions[source]; - values1_out[insert_pos] = *v1i; - values2_out[insert_pos] = *v2i; - } - } -} - -template -void -histogram_sort_inplace(KeyIterator key_begin, - RowstartIterator rowstart, // Must support numkeys + 1 elements and be precomputed - NumKeys numkeys, - Value1Iter values1, - KeyTransform key_transform) { - - typedef typename std::iterator_traits::value_type EdgeIndex; - - // 1. Copy m_rowstart (except last element) to get insert positions - std::vector insert_positions(rowstart, rowstart + numkeys); - // 2. Swap the sources and targets into place - for (size_t i = 0; i < rowstart[numkeys]; ++i) { - BOOST_ASSERT (key_transform(key_begin[i]) < numkeys); - // While edge i is not in the right bucket: - while (!(i >= rowstart[key_transform(key_begin[i])] && i < insert_positions[key_transform(key_begin[i])])) { - // Add a slot in the right bucket - size_t target_pos = insert_positions[key_transform(key_begin[i])]++; - BOOST_ASSERT (target_pos < rowstart[key_transform(key_begin[i]) + 1]); - if (target_pos == i) continue; - // Swap this edge into place - using std::swap; - swap(key_begin[i], key_begin[target_pos]); - swap(values1[i], values1[target_pos]); - } - } -} - -template -void -histogram_sort_inplace(KeyIterator key_begin, - RowstartIterator rowstart, // Must support numkeys + 1 elements and be precomputed - NumKeys numkeys, - Value1Iter values1, - Value2Iter values2, - KeyTransform key_transform) { - - typedef typename std::iterator_traits::value_type EdgeIndex; - - // 1. Copy m_rowstart (except last element) to get insert positions - std::vector insert_positions(rowstart, rowstart + numkeys); - // 2. Swap the sources and targets into place - for (size_t i = 0; i < rowstart[numkeys]; ++i) { - BOOST_ASSERT (key_transform(key_begin[i]) < numkeys); - // While edge i is not in the right bucket: - while (!(i >= rowstart[key_transform(key_begin[i])] && i < insert_positions[key_transform(key_begin[i])])) { - // Add a slot in the right bucket - size_t target_pos = insert_positions[key_transform(key_begin[i])]++; - BOOST_ASSERT (target_pos < rowstart[key_transform(key_begin[i]) + 1]); - if (target_pos == i) continue; - // Swap this edge into place - using std::swap; - swap(key_begin[i], key_begin[target_pos]); - swap(values1[i], values1[target_pos]); - swap(values2[i], values2[target_pos]); - } - } -} - -template -void split_into_separate_coords(InputIterator begin, InputIterator end, - std::vector& firsts, - std::vector& seconds) { - firsts.clear(); - seconds.clear(); - size_t reserve_size - = detail::reserve_count_for_single_pass(begin, end); - firsts.reserve(reserve_size); - seconds.reserve(reserve_size); - for (; begin != end; ++begin) { - std::pair edge = *begin; - firsts.push_back(edge.first); - seconds.push_back(edge.second); - } -} + namespace detail + { + + template < typename InputIterator > + size_t reserve_count_for_single_pass_helper( + InputIterator, InputIterator, std::input_iterator_tag) + { + // Do nothing: we have no idea how much storage to reserve. + return 0; + } + + template < typename InputIterator > + size_t reserve_count_for_single_pass_helper(InputIterator first, + InputIterator last, std::random_access_iterator_tag) + { + using std::distance; + typename std::iterator_traits< InputIterator >::difference_type n + = distance(first, last); + return (size_t)n; + } + + template < typename InputIterator > + size_t reserve_count_for_single_pass( + InputIterator first, InputIterator last) + { + typedef typename std::iterator_traits< + InputIterator >::iterator_category category; + return reserve_count_for_single_pass_helper( + first, last, category()); + } + + template < typename KeyIterator, typename RowstartIterator, + typename VerticesSize, typename KeyFilter, typename KeyTransform > + void count_starts(KeyIterator begin, KeyIterator end, + RowstartIterator starts, // Must support numverts + 1 elements + VerticesSize numkeys, KeyFilter key_filter, + KeyTransform key_transform) + { + + typedef + typename std::iterator_traits< RowstartIterator >::value_type + EdgeIndex; + + // Put the degree of each vertex v into m_rowstart[v + 1] + for (KeyIterator i = begin; i != end; ++i) + { + if (key_filter(*i)) + { + BOOST_ASSERT(key_transform(*i) < numkeys); + ++starts[key_transform(*i) + 1]; + } + } + + // Compute the partial sum of the degrees to get the actual values + // of m_rowstart + EdgeIndex start_of_this_row = 0; + starts[0] = start_of_this_row; + for (VerticesSize i = 1; i < numkeys + 1; ++i) + { + start_of_this_row += starts[i]; + starts[i] = start_of_this_row; + } + } + + template < typename KeyIterator, typename RowstartIterator, + typename NumKeys, typename Value1InputIter, + typename Value1OutputIter, typename KeyFilter, + typename KeyTransform > + void histogram_sort(KeyIterator key_begin, KeyIterator key_end, + RowstartIterator rowstart, // Must support numkeys + 1 elements and + // be precomputed + NumKeys numkeys, Value1InputIter values1_begin, + Value1OutputIter values1_out, KeyFilter key_filter, + KeyTransform key_transform) + { + + typedef + typename std::iterator_traits< RowstartIterator >::value_type + EdgeIndex; + + // Histogram sort the edges by their source vertices, putting the + // targets into m_column. The index current_insert_positions[v] + // contains the next location to insert out edges for vertex v. + std::vector< EdgeIndex > current_insert_positions( + rowstart, rowstart + numkeys); + Value1InputIter v1i = values1_begin; + for (KeyIterator i = key_begin; i != key_end; ++i, ++v1i) + { + if (key_filter(*i)) + { + NumKeys source = key_transform(*i); + BOOST_ASSERT(source < numkeys); + EdgeIndex insert_pos = current_insert_positions[source]; + ++current_insert_positions[source]; + values1_out[insert_pos] = *v1i; + } + } + } + + template < typename KeyIterator, typename RowstartIterator, + typename NumKeys, typename Value1InputIter, + typename Value1OutputIter, typename Value2InputIter, + typename Value2OutputIter, typename KeyFilter, + typename KeyTransform > + void histogram_sort(KeyIterator key_begin, KeyIterator key_end, + RowstartIterator rowstart, // Must support numkeys + 1 elements and + // be precomputed + NumKeys numkeys, Value1InputIter values1_begin, + Value1OutputIter values1_out, Value2InputIter values2_begin, + Value2OutputIter values2_out, KeyFilter key_filter, + KeyTransform key_transform) + { + + typedef + typename std::iterator_traits< RowstartIterator >::value_type + EdgeIndex; + + // Histogram sort the edges by their source vertices, putting the + // targets into m_column. The index current_insert_positions[v] + // contains the next location to insert out edges for vertex v. + std::vector< EdgeIndex > current_insert_positions( + rowstart, rowstart + numkeys); + Value1InputIter v1i = values1_begin; + Value2InputIter v2i = values2_begin; + for (KeyIterator i = key_begin; i != key_end; ++i, ++v1i, ++v2i) + { + if (key_filter(*i)) + { + NumKeys source = key_transform(*i); + BOOST_ASSERT(source < numkeys); + EdgeIndex insert_pos = current_insert_positions[source]; + ++current_insert_positions[source]; + values1_out[insert_pos] = *v1i; + values2_out[insert_pos] = *v2i; + } + } + } + + template < typename KeyIterator, typename RowstartIterator, + typename NumKeys, typename Value1Iter, typename KeyTransform > + void histogram_sort_inplace(KeyIterator key_begin, + RowstartIterator rowstart, // Must support numkeys + 1 elements and + // be precomputed + NumKeys numkeys, Value1Iter values1, KeyTransform key_transform) + { + + typedef + typename std::iterator_traits< RowstartIterator >::value_type + EdgeIndex; + + // 1. Copy m_rowstart (except last element) to get insert positions + std::vector< EdgeIndex > insert_positions( + rowstart, rowstart + numkeys); + // 2. Swap the sources and targets into place + for (size_t i = 0; i < rowstart[numkeys]; ++i) + { + BOOST_ASSERT(key_transform(key_begin[i]) < numkeys); + // While edge i is not in the right bucket: + while (!(i >= rowstart[key_transform(key_begin[i])] + && i < insert_positions[key_transform(key_begin[i])])) + { + // Add a slot in the right bucket + size_t target_pos + = insert_positions[key_transform(key_begin[i])]++; + BOOST_ASSERT( + target_pos < rowstart[key_transform(key_begin[i]) + 1]); + if (target_pos == i) + continue; + // Swap this edge into place + using std::swap; + swap(key_begin[i], key_begin[target_pos]); + swap(values1[i], values1[target_pos]); + } + } + } + + template < typename KeyIterator, typename RowstartIterator, + typename NumKeys, typename Value1Iter, typename Value2Iter, + typename KeyTransform > + void histogram_sort_inplace(KeyIterator key_begin, + RowstartIterator rowstart, // Must support numkeys + 1 elements and + // be precomputed + NumKeys numkeys, Value1Iter values1, Value2Iter values2, + KeyTransform key_transform) + { + + typedef + typename std::iterator_traits< RowstartIterator >::value_type + EdgeIndex; + + // 1. Copy m_rowstart (except last element) to get insert positions + std::vector< EdgeIndex > insert_positions( + rowstart, rowstart + numkeys); + // 2. Swap the sources and targets into place + for (size_t i = 0; i < rowstart[numkeys]; ++i) + { + BOOST_ASSERT(key_transform(key_begin[i]) < numkeys); + // While edge i is not in the right bucket: + while (!(i >= rowstart[key_transform(key_begin[i])] + && i < insert_positions[key_transform(key_begin[i])])) + { + // Add a slot in the right bucket + size_t target_pos + = insert_positions[key_transform(key_begin[i])]++; + BOOST_ASSERT( + target_pos < rowstart[key_transform(key_begin[i]) + 1]); + if (target_pos == i) + continue; + // Swap this edge into place + using std::swap; + swap(key_begin[i], key_begin[target_pos]); + swap(values1[i], values1[target_pos]); + swap(values2[i], values2[target_pos]); + } + } + } + + template < typename InputIterator, typename VerticesSize > + void split_into_separate_coords(InputIterator begin, InputIterator end, + std::vector< VerticesSize >& firsts, + std::vector< VerticesSize >& seconds) + { + firsts.clear(); + seconds.clear(); + size_t reserve_size + = detail::reserve_count_for_single_pass(begin, end); + firsts.reserve(reserve_size); + seconds.reserve(reserve_size); + for (; begin != end; ++begin) + { + std::pair< VerticesSize, VerticesSize > edge = *begin; + firsts.push_back(edge.first); + seconds.push_back(edge.second); + } + } + + template < typename InputIterator, typename VerticesSize, + typename SourceFilter > + void split_into_separate_coords_filtered(InputIterator begin, + InputIterator end, std::vector< VerticesSize >& firsts, + std::vector< VerticesSize >& seconds, const SourceFilter& filter) + { + firsts.clear(); + seconds.clear(); + for (; begin != end; ++begin) + { + std::pair< VerticesSize, VerticesSize > edge = *begin; + if (filter(edge.first)) + { + firsts.push_back(edge.first); + seconds.push_back(edge.second); + } + } + } + + template < typename InputIterator, typename PropInputIterator, + typename VerticesSize, typename PropType, typename SourceFilter > + void split_into_separate_coords_filtered(InputIterator begin, + InputIterator end, PropInputIterator props, + std::vector< VerticesSize >& firsts, + std::vector< VerticesSize >& seconds, + std::vector< PropType >& props_out, const SourceFilter& filter) + { + firsts.clear(); + seconds.clear(); + props_out.clear(); + for (; begin != end; ++begin) + { + std::pair< VerticesSize, VerticesSize > edge = *begin; + if (filter(edge.first)) + { + firsts.push_back(edge.first); + seconds.push_back(edge.second); + props_out.push_back(*props); + } + ++props; + } + } + + // The versions of operator()() here can't return by reference because + // the actual type passed in may not match Pair, in which case the + // reference parameter is bound to a temporary that could end up + // dangling after the operator returns. + + template < typename Pair > struct project1st + { + typedef typename Pair::first_type result_type; + result_type operator()(const Pair& p) const { return p.first; } + }; + + template < typename Pair > struct project2nd + { + typedef typename Pair::second_type result_type; + result_type operator()(const Pair& p) const { return p.second; } + }; -template -void split_into_separate_coords_filtered - (InputIterator begin, InputIterator end, - std::vector& firsts, - std::vector& seconds, - const SourceFilter& filter) { - firsts.clear(); - seconds.clear(); - for (; begin != end; ++begin) { - std::pair edge = *begin; - if (filter(edge.first)) { - firsts.push_back(edge.first); - seconds.push_back(edge.second); } - } } - -template -void split_into_separate_coords_filtered - (InputIterator begin, InputIterator end, - PropInputIterator props, - std::vector& firsts, - std::vector& seconds, - std::vector& props_out, - const SourceFilter& filter) { - firsts.clear(); - seconds.clear(); - props_out.clear(); - for (; begin != end; ++begin) { - std::pair edge = *begin; - if (filter(edge.first)) { - firsts.push_back(edge.first); - seconds.push_back(edge.second); - props_out.push_back(*props); - } - ++props; - } -} - -// The versions of operator()() here can't return by reference because the -// actual type passed in may not match Pair, in which case the reference -// parameter is bound to a temporary that could end up dangling after the -// operator returns. - -template -struct project1st { - typedef typename Pair::first_type result_type; - result_type operator()(const Pair& p) const {return p.first;} -}; - -template -struct project2nd { - typedef typename Pair::second_type result_type; - result_type operator()(const Pair& p) const {return p.second;} -}; - - } - } } #endif // BOOST_GRAPH_DETAIL_HISTOGRAM_SORT_HPP diff --git a/include/boost/graph/detail/incidence_iterator.hpp b/include/boost/graph/detail/incidence_iterator.hpp index 836ad1526..2da4874ac 100644 --- a/include/boost/graph/detail/incidence_iterator.hpp +++ b/include/boost/graph/detail/incidence_iterator.hpp @@ -16,64 +16,83 @@ // OBSOLETE -namespace boost { +namespace boost +{ - namespace detail { +namespace detail +{ // EdgeDir tags - struct in_edge_tag { }; - struct out_edge_tag { }; - - template - struct bidir_incidence_iterator { - typedef bidir_incidence_iterator self; - typedef Edge edge_type; - typedef typename Edge::property_type EdgeProperty; + struct in_edge_tag + { + }; + struct out_edge_tag + { + }; + + template < class Vertex, class Edge, class Iterator1D, class EdgeDir > + struct bidir_incidence_iterator + { + typedef bidir_incidence_iterator self; + typedef Edge edge_type; + typedef typename Edge::property_type EdgeProperty; + public: - typedef int difference_type; - typedef std::forward_iterator_tag iterator_category; - typedef edge_type reference; - typedef edge_type value_type; - typedef value_type* pointer; - inline bidir_incidence_iterator() {} - inline bidir_incidence_iterator(Iterator1D ii, Vertex src) - : i(ii), _src(src) { } - - inline self& operator++() { ++i; return *this; } - inline self operator++(int) { self tmp = *this; ++(*this); return tmp; } - - inline reference operator*() const { - return deref_helper(EdgeDir()); - } - inline self* operator->() { return this; } - - Iterator1D& iter() { return i; } - const Iterator1D& iter() const { return i; } + typedef int difference_type; + typedef std::forward_iterator_tag iterator_category; + typedef edge_type reference; + typedef edge_type value_type; + typedef value_type* pointer; + inline bidir_incidence_iterator() {} + inline bidir_incidence_iterator(Iterator1D ii, Vertex src) + : i(ii), _src(src) + { + } + + inline self& operator++() + { + ++i; + return *this; + } + inline self operator++(int) + { + self tmp = *this; + ++(*this); + return tmp; + } + + inline reference operator*() const { return deref_helper(EdgeDir()); } + inline self* operator->() { return this; } + + Iterator1D& iter() { return i; } + const Iterator1D& iter() const { return i; } + + Iterator1D i; + Vertex _src; - Iterator1D i; - Vertex _src; protected: - inline reference deref_helper(out_edge_tag) const { - return edge_type( _src, (*i).get_target(), &(*i).get_property() ); - } - inline reference deref_helper(in_edge_tag) const { - return edge_type((*i).get_target(), _src, &(*i).get_property() ); - } + inline reference deref_helper(out_edge_tag) const + { + return edge_type(_src, (*i).get_target(), &(*i).get_property()); + } + inline reference deref_helper(in_edge_tag) const + { + return edge_type((*i).get_target(), _src, &(*i).get_property()); + } }; - template - inline bool operator==(const bidir_incidence_iterator& x, - const bidir_incidence_iterator& y) + template < class V, class E, class Iter, class Dir > + inline bool operator==(const bidir_incidence_iterator< V, E, Iter, Dir >& x, + const bidir_incidence_iterator< V, E, Iter, Dir >& y) { - return x.i == y.i; + return x.i == y.i; } - template - inline bool operator!=(const bidir_incidence_iterator& x, - const bidir_incidence_iterator& y) + template < class V, class E, class Iter, class Dir > + inline bool operator!=(const bidir_incidence_iterator< V, E, Iter, Dir >& x, + const bidir_incidence_iterator< V, E, Iter, Dir >& y) { - return x.i != y.i; + return x.i != y.i; } - - } -} +} +} #endif diff --git a/include/boost/graph/detail/incremental_components.hpp b/include/boost/graph/detail/incremental_components.hpp index f66a3660f..8941f6728 100644 --- a/include/boost/graph/detail/incremental_components.hpp +++ b/include/boost/graph/detail/incremental_components.hpp @@ -13,65 +13,80 @@ #include -namespace boost { +namespace boost +{ - namespace detail { +namespace detail +{ // Iterator for a component index linked list. The contents of // each array element represent the next index in the list. A // special value (the maximum index + 1) is used to terminate a // list. - template - class component_index_iterator : - boost::forward_iterator_helper, - typename std::iterator_traits::value_type, - typename std::iterator_traits::difference_type, - typename std::iterator_traits::pointer, - typename std::iterator_traits::reference> { + template < typename IndexRandomAccessIterator > + class component_index_iterator + : boost::forward_iterator_helper< + component_index_iterator< IndexRandomAccessIterator >, + typename std::iterator_traits< + IndexRandomAccessIterator >::value_type, + typename std::iterator_traits< + IndexRandomAccessIterator >::difference_type, + typename std::iterator_traits< IndexRandomAccessIterator >::pointer, + typename std::iterator_traits< + IndexRandomAccessIterator >::reference > + { private: - typedef component_index_iterator self; + typedef component_index_iterator< IndexRandomAccessIterator > self; public: - typedef std::forward_iterator_tag iterator_category; - typedef typename std::iterator_traits::value_type value_type; - typedef typename std::iterator_traits::difference_type reference; - typedef typename std::iterator_traits::pointer pointer; - typedef typename std::iterator_traits::reference difference_type; - - // Constructor for "begin" iterator - component_index_iterator(IndexRandomAccessIterator index_iterator, - value_type begin_index) : - m_index_iterator(index_iterator), - m_current_index(begin_index) { } - - // Constructor for "end" iterator (end_index should be the linked - // list terminator). - component_index_iterator(value_type end_index) : - m_current_index(end_index) { } - - inline value_type operator*() const { - return (m_current_index); - } - - self& operator++() { - // Move to the next element in the linked list - m_current_index = m_index_iterator[m_current_index]; - return (*this); - } - - bool operator==(const self& other_iterator) const { - return (m_current_index == *other_iterator); - } + typedef std::forward_iterator_tag iterator_category; + typedef typename std::iterator_traits< + IndexRandomAccessIterator >::value_type value_type; + typedef typename std::iterator_traits< + IndexRandomAccessIterator >::difference_type reference; + typedef + typename std::iterator_traits< IndexRandomAccessIterator >::pointer + pointer; + typedef typename std::iterator_traits< + IndexRandomAccessIterator >::reference difference_type; + + // Constructor for "begin" iterator + component_index_iterator( + IndexRandomAccessIterator index_iterator, value_type begin_index) + : m_index_iterator(index_iterator), m_current_index(begin_index) + { + } + + // Constructor for "end" iterator (end_index should be the linked + // list terminator). + component_index_iterator(value_type end_index) + : m_current_index(end_index) + { + } + + inline value_type operator*() const { return (m_current_index); } + + self& operator++() + { + // Move to the next element in the linked list + m_current_index = m_index_iterator[m_current_index]; + return (*this); + } + + bool operator==(const self& other_iterator) const + { + return (m_current_index == *other_iterator); + } protected: - IndexRandomAccessIterator m_index_iterator; - value_type m_current_index; + IndexRandomAccessIterator m_index_iterator; + value_type m_current_index; }; // class component_index_iterator - } // namespace detail - +} // namespace detail + } // namespace detail #endif // BOOST_GRAPH_DETAIL_INCREMENTAL_COMPONENTS_HPP diff --git a/include/boost/graph/detail/index.hpp b/include/boost/graph/detail/index.hpp index db1152f8c..1565c57c8 100644 --- a/include/boost/graph/detail/index.hpp +++ b/include/boost/graph/detail/index.hpp @@ -16,59 +16,62 @@ namespace boost { - namespace detail +namespace detail +{ + template < typename Graph > struct vertex_indexer { - template - struct vertex_indexer - { - typedef vertex_index_t index_type; - typedef typename property_map::type map_type; - typedef typename property_map::const_type const_map_type; - typedef typename property_traits::value_type value_type; - typedef typename graph_traits::vertex_descriptor key_type; - - static const_map_type index_map(const Graph& g) - { return get(vertex_index, g); } + typedef vertex_index_t index_type; + typedef typename property_map< Graph, vertex_index_t >::type map_type; + typedef typename property_map< Graph, vertex_index_t >::const_type + const_map_type; + typedef typename property_traits< map_type >::value_type value_type; + typedef typename graph_traits< Graph >::vertex_descriptor key_type; - static map_type index_map(Graph& g) - { return get(vertex_index, g); } + static const_map_type index_map(const Graph& g) + { + return get(vertex_index, g); + } - static value_type index(key_type k, const Graph& g) - { return get(vertex_index, g, k); } - }; + static map_type index_map(Graph& g) { return get(vertex_index, g); } - template - struct edge_indexer + static value_type index(key_type k, const Graph& g) { - typedef edge_index_t index_type; - typedef typename property_map::type map_type; - typedef typename property_map::const_type const_map_type; - typedef typename property_traits::value_type value_type; - typedef typename graph_traits::edge_descriptor key_type; + return get(vertex_index, g, k); + } + }; - static const_map_type index_map(const Graph& g) - { return get(edge_index, g); } + template < typename Graph > struct edge_indexer + { + typedef edge_index_t index_type; + typedef typename property_map< Graph, edge_index_t >::type map_type; + typedef typename property_map< Graph, edge_index_t >::const_type + const_map_type; + typedef typename property_traits< map_type >::value_type value_type; + typedef typename graph_traits< Graph >::edge_descriptor key_type; - static map_type index_map(Graph& g) - { return get(edge_index, g); } + static const_map_type index_map(const Graph& g) + { + return get(edge_index, g); + } - static value_type index(key_type k, const Graph& g) - { return get(edge_index, g, k); } - }; + static map_type index_map(Graph& g) { return get(edge_index, g); } - // NOTE: The Graph parameter MUST be a model of VertexIndexGraph or - // VertexEdgeGraph - whichever type Key is selecting. - template - struct choose_indexer + static value_type index(key_type k, const Graph& g) { - typedef typename mpl::if_< - is_same::vertex_descriptor>, - vertex_indexer, - edge_indexer - >::type indexer_type; - typedef typename indexer_type::index_type index_type; - }; - } + return get(edge_index, g, k); + } + }; + + // NOTE: The Graph parameter MUST be a model of VertexIndexGraph or + // VertexEdgeGraph - whichever type Key is selecting. + template < typename Graph, typename Key > struct choose_indexer + { + typedef typename mpl::if_< + is_same< Key, typename graph_traits< Graph >::vertex_descriptor >, + vertex_indexer< Graph >, edge_indexer< Graph > >::type indexer_type; + typedef typename indexer_type::index_type index_type; + }; +} } #endif diff --git a/include/boost/graph/detail/indexed_properties.hpp b/include/boost/graph/detail/indexed_properties.hpp index 4494625c6..b86cf31a7 100644 --- a/include/boost/graph/detail/indexed_properties.hpp +++ b/include/boost/graph/detail/indexed_properties.hpp @@ -26,257 +26,271 @@ #include #include -namespace boost { -namespace detail { - -template -class indexed_vertex_properties +namespace boost { -public: - typedef no_property vertex_property_type; - typedef Property vertex_bundled; - typedef iterator_property_map< - typename std::vector::iterator, - IndexMap> vertex_map_type; - typedef iterator_property_map< - typename std::vector::const_iterator, - IndexMap> const_vertex_map_type; - - // Directly access a vertex or edge bundle - Property& operator[](Descriptor v) - { return m_vertex_properties[get(vertex_index, derived(), v)]; } - - const Property& operator[](Descriptor v) const - { return m_vertex_properties[get(vertex_index, derived(), v)]; } - - vertex_map_type get_vertex_bundle(const IndexMap& index_map = IndexMap()) { - return vertex_map_type(m_vertex_properties.begin(), index_map); - } - - const_vertex_map_type get_vertex_bundle(const IndexMap& index_map = IndexMap()) const { - return const_vertex_map_type(m_vertex_properties.begin(), index_map); - } - -protected: - // Default-construct with no property values - indexed_vertex_properties() {} - - // Initialize with n default-constructed property values - indexed_vertex_properties(std::size_t n) : m_vertex_properties(n) { } - -public: - // Clear the properties vector - void clear() - { - m_vertex_properties.clear(); - } - - // Resize the properties vector - void resize(std::size_t n) - { - m_vertex_properties.resize(n); - } - - // Reserve space in the vector of properties - void reserve(std::size_t n) - { - m_vertex_properties.reserve(n); - } - - // Add a new property value to the back - void push_back(const Property& prop) - { - m_vertex_properties.push_back(prop); - } - - // Write an element by raw index - void write_by_index(std::size_t idx, const Property& prop) - { - m_vertex_properties[idx] = prop; - } - - // Access to the derived object - Derived& derived() { return *static_cast(this); } - - const Derived& derived() const - { return *static_cast(this); } - -public: // should be private, but friend templates not portable - std::vector m_vertex_properties; -}; - -template -class indexed_vertex_properties +namespace detail { - struct secret {}; - - public: - typedef no_property vertex_property_type; - typedef void vertex_bundled; - typedef secret vertex_map_type; - typedef secret const_vertex_map_type; - - secret operator[](secret) { return secret(); } - - vertex_map_type get_vertex_bundle() const { - return vertex_map_type(); - } - protected: - // All operations do nothing. - indexed_vertex_properties() { } - indexed_vertex_properties(std::size_t) { } - -public: - void clear() { } - void resize(std::size_t) { } - void reserve(std::size_t) { } -}; - -template -class indexed_edge_properties -{ -public: - typedef no_property edge_property_type; - typedef Property edge_bundled; - typedef Property edge_push_back_type; - typedef iterator_property_map< - typename std::vector::iterator, - IndexMap> edge_map_type; - typedef iterator_property_map< - typename std::vector::const_iterator, - IndexMap> const_edge_map_type; - - // Directly access a edge or edge bundle - Property& operator[](Descriptor v) - { return m_edge_properties[get(edge_index, derived(), v)]; } - - const Property& operator[](Descriptor v) const - { return m_edge_properties[get(edge_index, derived(), v)]; } - - edge_map_type get_edge_bundle(const IndexMap& index_map = IndexMap()) { - return edge_map_type(m_edge_properties.begin(), index_map); - } - - const_edge_map_type get_edge_bundle(const IndexMap& index_map = IndexMap()) const { - return const_edge_map_type(m_edge_properties.begin(), index_map); - } - -protected: - // Default-construct with no property values - indexed_edge_properties() {} - - // Initialize with n default-constructed property values - indexed_edge_properties(std::size_t n) : m_edge_properties(n) { } - - // Get the size of the properties vector - std::size_t size() const - { - return m_edge_properties.size(); - } - - // Clear the properties vector - void clear() - { - m_edge_properties.clear(); - } - - // Resize the properties vector - void resize(std::size_t n) - { - m_edge_properties.resize(n); - } - - // Reserve space in the vector of properties - void reserve(std::size_t n) - { - m_edge_properties.reserve(n); - } - - // Write an element by raw index - void write_by_index(std::size_t idx, const Property& prop) - { - m_edge_properties[idx] = prop; - } - - public: - // Add a new property value to the back - void push_back(const Property& prop) - { - m_edge_properties.push_back(prop); - } - - // Move range of properties backwards - void move_range(std::size_t src_begin, std::size_t src_end, std::size_t dest_begin) { - std::copy_backward( - m_edge_properties.begin() + src_begin, - m_edge_properties.begin() + src_end, - m_edge_properties.begin() + dest_begin + (src_end - src_begin)); - } - - typedef typename std::vector::iterator iterator; - iterator begin() {return m_edge_properties.begin();} - iterator end() {return m_edge_properties.end();} - - private: - // Access to the derived object - Derived& derived() { return *static_cast(this); } - - const Derived& derived() const - { return *static_cast(this); } - -public: // should be private, but friend templates not portable - std::vector m_edge_properties; -}; - -struct dummy_no_property_iterator -: public boost::iterator_facade { - mutable no_property prop; - no_property& dereference() const {return prop;} - bool equal(const dummy_no_property_iterator&) const {return true;} - void increment() {} - void decrement() {} - void advance(std::ptrdiff_t) {} - std::ptrdiff_t distance_to(const dummy_no_property_iterator) const {return 0;} -}; - -template -class indexed_edge_properties -{ - struct secret {}; - - public: - typedef no_property edge_property_type; - typedef void edge_bundled; - typedef void* edge_push_back_type; - typedef secret edge_map_type; - typedef secret const_edge_map_type; - - secret operator[](secret) { return secret(); } - void write_by_index(std::size_t /*idx*/, const no_property& /*prop*/) {} - - edge_map_type get_edge_bundle(const IndexMap& = IndexMap()) const { - return edge_map_type(); - } - - protected: - // All operations do nothing. - indexed_edge_properties() { } - indexed_edge_properties(std::size_t) { } - std::size_t size() const {return 0;} - void clear() { } - void resize(std::size_t) { } - void reserve(std::size_t) { } - - public: - void push_back(const edge_push_back_type&) { } - void move_range(std::size_t /*src_begin*/, std::size_t /*src_end*/, std::size_t /*dest_begin*/) {} - - typedef dummy_no_property_iterator iterator; - iterator begin() {return dummy_no_property_iterator();} - iterator end() {return dummy_no_property_iterator();} - -}; + template < typename Derived, typename Property, typename Descriptor, + typename IndexMap > + class indexed_vertex_properties + { + public: + typedef no_property vertex_property_type; + typedef Property vertex_bundled; + typedef iterator_property_map< + typename std::vector< Property >::iterator, IndexMap > + vertex_map_type; + typedef iterator_property_map< + typename std::vector< Property >::const_iterator, IndexMap > + const_vertex_map_type; + + // Directly access a vertex or edge bundle + Property& operator[](Descriptor v) + { + return m_vertex_properties[get(vertex_index, derived(), v)]; + } + + const Property& operator[](Descriptor v) const + { + return m_vertex_properties[get(vertex_index, derived(), v)]; + } + + vertex_map_type get_vertex_bundle( + const IndexMap& index_map = IndexMap()) + { + return vertex_map_type(m_vertex_properties.begin(), index_map); + } + + const_vertex_map_type get_vertex_bundle( + const IndexMap& index_map = IndexMap()) const + { + return const_vertex_map_type( + m_vertex_properties.begin(), index_map); + } + + protected: + // Default-construct with no property values + indexed_vertex_properties() {} + + // Initialize with n default-constructed property values + indexed_vertex_properties(std::size_t n) : m_vertex_properties(n) {} + + public: + // Clear the properties vector + void clear() { m_vertex_properties.clear(); } + + // Resize the properties vector + void resize(std::size_t n) { m_vertex_properties.resize(n); } + + // Reserve space in the vector of properties + void reserve(std::size_t n) { m_vertex_properties.reserve(n); } + + // Add a new property value to the back + void push_back(const Property& prop) + { + m_vertex_properties.push_back(prop); + } + + // Write an element by raw index + void write_by_index(std::size_t idx, const Property& prop) + { + m_vertex_properties[idx] = prop; + } + + // Access to the derived object + Derived& derived() { return *static_cast< Derived* >(this); } + + const Derived& derived() const + { + return *static_cast< const Derived* >(this); + } + + public: // should be private, but friend templates not portable + std::vector< Property > m_vertex_properties; + }; + + template < typename Derived, typename Descriptor, typename IndexMap > + class indexed_vertex_properties< Derived, void, Descriptor, IndexMap > + { + struct secret + { + }; + + public: + typedef no_property vertex_property_type; + typedef void vertex_bundled; + typedef secret vertex_map_type; + typedef secret const_vertex_map_type; + + secret operator[](secret) { return secret(); } + + vertex_map_type get_vertex_bundle() const { return vertex_map_type(); } + + protected: + // All operations do nothing. + indexed_vertex_properties() {} + indexed_vertex_properties(std::size_t) {} + + public: + void clear() {} + void resize(std::size_t) {} + void reserve(std::size_t) {} + }; + + template < typename Derived, typename Property, typename Descriptor, + typename IndexMap > + class indexed_edge_properties + { + public: + typedef no_property edge_property_type; + typedef Property edge_bundled; + typedef Property edge_push_back_type; + typedef iterator_property_map< + typename std::vector< Property >::iterator, IndexMap > + edge_map_type; + typedef iterator_property_map< + typename std::vector< Property >::const_iterator, IndexMap > + const_edge_map_type; + + // Directly access a edge or edge bundle + Property& operator[](Descriptor v) + { + return m_edge_properties[get(edge_index, derived(), v)]; + } + + const Property& operator[](Descriptor v) const + { + return m_edge_properties[get(edge_index, derived(), v)]; + } + + edge_map_type get_edge_bundle(const IndexMap& index_map = IndexMap()) + { + return edge_map_type(m_edge_properties.begin(), index_map); + } + + const_edge_map_type get_edge_bundle( + const IndexMap& index_map = IndexMap()) const + { + return const_edge_map_type(m_edge_properties.begin(), index_map); + } + + protected: + // Default-construct with no property values + indexed_edge_properties() {} + + // Initialize with n default-constructed property values + indexed_edge_properties(std::size_t n) : m_edge_properties(n) {} + + // Get the size of the properties vector + std::size_t size() const { return m_edge_properties.size(); } + + // Clear the properties vector + void clear() { m_edge_properties.clear(); } + + // Resize the properties vector + void resize(std::size_t n) { m_edge_properties.resize(n); } + + // Reserve space in the vector of properties + void reserve(std::size_t n) { m_edge_properties.reserve(n); } + + // Write an element by raw index + void write_by_index(std::size_t idx, const Property& prop) + { + m_edge_properties[idx] = prop; + } + + public: + // Add a new property value to the back + void push_back(const Property& prop) + { + m_edge_properties.push_back(prop); + } + + // Move range of properties backwards + void move_range( + std::size_t src_begin, std::size_t src_end, std::size_t dest_begin) + { + std::copy_backward(m_edge_properties.begin() + src_begin, + m_edge_properties.begin() + src_end, + m_edge_properties.begin() + dest_begin + (src_end - src_begin)); + } + + typedef typename std::vector< Property >::iterator iterator; + iterator begin() { return m_edge_properties.begin(); } + iterator end() { return m_edge_properties.end(); } + + private: + // Access to the derived object + Derived& derived() { return *static_cast< Derived* >(this); } + + const Derived& derived() const + { + return *static_cast< const Derived* >(this); + } + + public: // should be private, but friend templates not portable + std::vector< Property > m_edge_properties; + }; + + struct dummy_no_property_iterator + : public boost::iterator_facade< dummy_no_property_iterator, no_property, + std::random_access_iterator_tag > + { + mutable no_property prop; + no_property& dereference() const { return prop; } + bool equal(const dummy_no_property_iterator&) const { return true; } + void increment() {} + void decrement() {} + void advance(std::ptrdiff_t) {} + std::ptrdiff_t distance_to(const dummy_no_property_iterator) const + { + return 0; + } + }; + + template < typename Derived, typename Descriptor, typename IndexMap > + class indexed_edge_properties< Derived, void, Descriptor, IndexMap > + { + struct secret + { + }; + + public: + typedef no_property edge_property_type; + typedef void edge_bundled; + typedef void* edge_push_back_type; + typedef secret edge_map_type; + typedef secret const_edge_map_type; + + secret operator[](secret) { return secret(); } + void write_by_index(std::size_t /*idx*/, const no_property& /*prop*/) {} + + edge_map_type get_edge_bundle(const IndexMap& = IndexMap()) const + { + return edge_map_type(); + } + + protected: + // All operations do nothing. + indexed_edge_properties() {} + indexed_edge_properties(std::size_t) {} + std::size_t size() const { return 0; } + void clear() {} + void resize(std::size_t) {} + void reserve(std::size_t) {} + + public: + void push_back(const edge_push_back_type&) {} + void move_range(std::size_t /*src_begin*/, std::size_t /*src_end*/, + std::size_t /*dest_begin*/) + { + } + + typedef dummy_no_property_iterator iterator; + iterator begin() { return dummy_no_property_iterator(); } + iterator end() { return dummy_no_property_iterator(); } + }; } } diff --git a/include/boost/graph/detail/is_distributed_selector.hpp b/include/boost/graph/detail/is_distributed_selector.hpp index 4319d9d89..0a25a6852 100644 --- a/include/boost/graph/detail/is_distributed_selector.hpp +++ b/include/boost/graph/detail/is_distributed_selector.hpp @@ -17,10 +17,14 @@ #include -namespace boost { - namespace detail { - template struct is_distributed_selector: boost::mpl::false_ {}; - } +namespace boost +{ +namespace detail +{ + template < typename > struct is_distributed_selector : boost::mpl::false_ + { + }; +} } #endif // BOOST_GRAPH_DETAIL_IS_DISTRIBUTED_SELECTOR_HPP diff --git a/include/boost/graph/detail/labeled_graph_traits.hpp b/include/boost/graph/detail/labeled_graph_traits.hpp index a0c0973f9..b6600dbb0 100644 --- a/include/boost/graph/detail/labeled_graph_traits.hpp +++ b/include/boost/graph/detail/labeled_graph_traits.hpp @@ -9,7 +9,8 @@ #include -namespace boost { +namespace boost +{ // Extend the graph mutability traits (and metafunctions) to include options // for labeled graphs. @@ -20,213 +21,207 @@ namespace boost { // TODO: We might also overlay the uniqueness/multiplicity of labels in this // hierarchy also. For now, we just assumed that labels are unique. -struct label_vertex_tag { }; -struct labeled_add_vertex_tag : virtual label_vertex_tag { }; -struct labeled_add_vertex_property_tag : virtual labeled_add_vertex_tag { }; -struct labeled_remove_vertex_tag { }; -struct labeled_add_edge_tag : virtual label_vertex_tag { }; -struct labeled_add_edge_property_tag : virtual labeled_add_edge_tag{ }; -struct labeled_remove_edge_tag { }; - -struct labeled_mutable_vertex_graph_tag - : virtual labeled_add_vertex_tag, virtual labeled_remove_vertex_tag -{ }; +struct label_vertex_tag +{ +}; +struct labeled_add_vertex_tag : virtual label_vertex_tag +{ +}; +struct labeled_add_vertex_property_tag : virtual labeled_add_vertex_tag +{ +}; +struct labeled_remove_vertex_tag +{ +}; +struct labeled_add_edge_tag : virtual label_vertex_tag +{ +}; +struct labeled_add_edge_property_tag : virtual labeled_add_edge_tag +{ +}; +struct labeled_remove_edge_tag +{ +}; + +struct labeled_mutable_vertex_graph_tag : virtual labeled_add_vertex_tag, + virtual labeled_remove_vertex_tag +{ +}; struct labeled_mutable_vertex_property_graph_tag - : virtual labeled_add_vertex_property_tag, virtual labeled_remove_vertex_tag -{ }; -struct labeled_mutable_edge_graph_tag - : virtual labeled_add_edge_tag, virtual labeled_remove_edge_tag -{ }; +: virtual labeled_add_vertex_property_tag, + virtual labeled_remove_vertex_tag +{ +}; +struct labeled_mutable_edge_graph_tag : virtual labeled_add_edge_tag, + virtual labeled_remove_edge_tag +{ +}; struct labeled_mutable_edge_property_graph_tag - : virtual labeled_add_edge_property_tag, virtual labeled_remove_edge_tag -{ }; - -struct labeled_graph_tag - : virtual label_vertex_tag -{ }; -struct labeled_mutable_graph_tag - : virtual labeled_mutable_vertex_graph_tag - , virtual labeled_mutable_edge_graph_tag -{ }; +: virtual labeled_add_edge_property_tag, + virtual labeled_remove_edge_tag +{ +}; + +struct labeled_graph_tag : virtual label_vertex_tag +{ +}; +struct labeled_mutable_graph_tag : virtual labeled_mutable_vertex_graph_tag, + virtual labeled_mutable_edge_graph_tag +{ +}; struct labeled_mutable_property_graph_tag - : virtual labeled_mutable_vertex_property_graph_tag - , virtual labeled_mutable_edge_property_graph_tag -{ }; +: virtual labeled_mutable_vertex_property_graph_tag, + virtual labeled_mutable_edge_property_graph_tag +{ +}; struct labeled_add_only_property_graph_tag - : virtual labeled_add_vertex_property_tag - , virtual labeled_mutable_edge_property_graph_tag -{ }; +: virtual labeled_add_vertex_property_tag, + virtual labeled_mutable_edge_property_graph_tag +{ +}; // Metafunctions -template +template < typename Graph > struct graph_has_add_vertex_by_label - : mpl::bool_< - is_convertible< - typename graph_mutability_traits::category, - labeled_add_vertex_tag - >::value - > -{ }; - -template +: mpl::bool_< + is_convertible< typename graph_mutability_traits< Graph >::category, + labeled_add_vertex_tag >::value > +{ +}; + +template < typename Graph > struct graph_has_add_vertex_by_label_with_property - : mpl::bool_< - is_convertible< - typename graph_mutability_traits::category, - labeled_add_vertex_property_tag - >::value - > -{ }; - -template +: mpl::bool_< + is_convertible< typename graph_mutability_traits< Graph >::category, + labeled_add_vertex_property_tag >::value > +{ +}; + +template < typename Graph > struct graph_has_remove_vertex_by_label - : mpl::bool_< - is_convertible< - typename graph_mutability_traits::category, - labeled_remove_vertex_tag - >::value - > -{ }; - -template +: mpl::bool_< + is_convertible< typename graph_mutability_traits< Graph >::category, + labeled_remove_vertex_tag >::value > +{ +}; + +template < typename Graph > struct graph_has_add_edge_by_label - : mpl::bool_< - is_convertible< - typename graph_mutability_traits::category, - labeled_add_edge_tag - >::value - > -{ }; - -template +: mpl::bool_< + is_convertible< typename graph_mutability_traits< Graph >::category, + labeled_add_edge_tag >::value > +{ +}; + +template < typename Graph > struct graph_has_add_edge_by_label_with_property - : mpl::bool_< - is_convertible< - typename graph_mutability_traits::category, - labeled_add_edge_property_tag - >::value - > -{ }; - -template +: mpl::bool_< + is_convertible< typename graph_mutability_traits< Graph >::category, + labeled_add_edge_property_tag >::value > +{ +}; + +template < typename Graph > struct graph_has_remove_edge_by_label - : mpl::bool_< - is_convertible< - typename graph_mutability_traits::category, - labeled_remove_edge_tag - >::value - > -{ }; - -template +: mpl::bool_< + is_convertible< typename graph_mutability_traits< Graph >::category, + labeled_remove_edge_tag >::value > +{ +}; + +template < typename Graph > struct is_labeled_mutable_vertex_graph - : mpl::and_< - graph_has_add_vertex_by_label, - graph_has_remove_vertex_by_label - > -{ }; +: mpl::and_< graph_has_add_vertex_by_label< Graph >, + graph_has_remove_vertex_by_label< Graph > > +{ +}; -template +template < typename Graph > struct is_labeled_mutable_vertex_property_graph - : mpl::and_< - graph_has_add_vertex_by_label, - graph_has_remove_vertex_by_label - > -{ }; +: mpl::and_< graph_has_add_vertex_by_label< Graph >, + graph_has_remove_vertex_by_label< Graph > > +{ +}; -template +template < typename Graph > struct is_labeled_mutable_edge_graph - : mpl::and_< - graph_has_add_edge_by_label, - graph_has_remove_edge_by_label - > -{ }; +: mpl::and_< graph_has_add_edge_by_label< Graph >, + graph_has_remove_edge_by_label< Graph > > +{ +}; -template +template < typename Graph > struct is_labeled_mutable_edge_property_graph - : mpl::and_< - graph_has_add_edge_by_label, - graph_has_remove_edge_by_label - > -{ }; +: mpl::and_< graph_has_add_edge_by_label< Graph >, + graph_has_remove_edge_by_label< Graph > > +{ +}; -template +template < typename Graph > struct is_labeled_mutable_graph - : mpl::and_< - is_labeled_mutable_vertex_graph, - is_labeled_mutable_edge_graph - > -{ }; +: mpl::and_< is_labeled_mutable_vertex_graph< Graph >, + is_labeled_mutable_edge_graph< Graph > > +{ +}; -template +template < typename Graph > struct is_labeled_mutable_property_graph - : mpl::and_< - is_labeled_mutable_vertex_property_graph, - is_labeled_mutable_edge_property_graph - > -{ }; +: mpl::and_< is_labeled_mutable_vertex_property_graph< Graph >, + is_labeled_mutable_edge_property_graph< Graph > > +{ +}; -template +template < typename Graph > struct is_labeled_add_only_property_graph - : mpl::bool_< - is_convertible< - typename graph_mutability_traits::category, - labeled_add_only_property_graph_tag - >::value - > -{ }; - -template +: mpl::bool_< + is_convertible< typename graph_mutability_traits< Graph >::category, + labeled_add_only_property_graph_tag >::value > +{ +}; + +template < typename Graph > struct is_labeled_graph - : mpl::bool_< - is_convertible< - typename graph_mutability_traits::category, - label_vertex_tag - >::value - > -{ }; +: mpl::bool_< + is_convertible< typename graph_mutability_traits< Graph >::category, + label_vertex_tag >::value > +{ +}; -template struct graph_mutability_traits; +template < typename > struct graph_mutability_traits; -namespace graph_detail { +namespace graph_detail +{ // The determine mutability metafunction computes a labeled mutability tag // based on the mutability of the given graph type. This is used by the // graph_mutability_traits specialization below. - template - struct determine_mutability { - typedef typename mpl::if_< - is_add_only_property_graph, + template < typename Graph > struct determine_mutability + { + typedef typename mpl::if_< is_add_only_property_graph< Graph >, labeled_add_only_property_graph_tag, - typename mpl::if_< - is_mutable_property_graph, + typename mpl::if_< is_mutable_property_graph< Graph >, labeled_mutable_property_graph_tag, - typename mpl::if_< - is_mutable_graph, + typename mpl::if_< is_mutable_graph< Graph >, labeled_mutable_graph_tag, - typename mpl::if_< - is_mutable_edge_graph, + typename mpl::if_< is_mutable_edge_graph< Graph >, labeled_graph_tag, - typename graph_mutability_traits::category - >::type - >::type - >::type - >::type type; + typename graph_mutability_traits< Graph >::category >:: + type >::type >::type >::type type; }; } // namespace graph_detail #define LABELED_GRAPH_PARAMS typename G, typename L, typename S -#define LABELED_GRAPH labeled_graph +#define LABELED_GRAPH labeled_graph< G, L, S > // Specialize mutability traits for the labeled graph. // This specialization depends on the mutability of the underlying graph type. // If the underlying graph is fully mutable, this is also fully mutable. // Otherwise, it's different. -template -struct graph_mutability_traits< LABELED_GRAPH > { +template < LABELED_GRAPH_PARAMS > +struct graph_mutability_traits< LABELED_GRAPH > +{ typedef typename graph_detail::determine_mutability< - typename LABELED_GRAPH::graph_type - >::type category; + typename LABELED_GRAPH::graph_type >::type category; }; #undef LABELED_GRAPH_PARAMS diff --git a/include/boost/graph/detail/list_base.hpp b/include/boost/graph/detail/list_base.hpp index 60332406f..bd1fc1711 100644 --- a/include/boost/graph/detail/list_base.hpp +++ b/include/boost/graph/detail/list_base.hpp @@ -20,201 +20,187 @@ functions that do not require the container object! */ -namespace boost { - namespace detail { +namespace boost +{ +namespace detail +{ //========================================================================= // Linked-List Generic Implementation Functions - template - inline Node - slist_insert_after(Node pos, Node x, - Next next) + template < class Node, class Next > + inline Node slist_insert_after(Node pos, Node x, Next next) { - next(x) = next(pos); - next(pos) = x; - return x; + next(x) = next(pos); + next(pos) = x; + return x; } // return next(pos) or next(next(pos)) ? - template - inline Node - slist_remove_after(Node pos, - Next next) + template < class Node, class Next > + inline Node slist_remove_after(Node pos, Next next) { - Node n = next(pos); - next(pos) = next(n); - return n; + Node n = next(pos); + next(pos) = next(n); + return n; } - template - inline Node - slist_remove_range(Node before_first, Node last, - Next next) + template < class Node, class Next > + inline Node slist_remove_range(Node before_first, Node last, Next next) { - next(before_first) = last; - return last; + next(before_first) = last; + return last; } - template - inline Node - slist_previous(Node head, Node x, Node empty, - Next next) + template < class Node, class Next > + inline Node slist_previous(Node head, Node x, Node empty, Next next) { - while (head != empty && next(head) != x) - head = next(head); - return head; + while (head != empty && next(head) != x) + head = next(head); + return head; } - template - inline void - slist_splice_after(Node pos, Node before_first, Node before_last, - Next next) + template < class Node, class Next > + inline void slist_splice_after( + Node pos, Node before_first, Node before_last, Next next) { - if (pos != before_first && pos != before_last) { - Node first = next(before_first); - Node after = next(pos); - next(before_first) = next(before_last); - next(pos) = first; - next(before_last) = after; - } + if (pos != before_first && pos != before_last) + { + Node first = next(before_first); + Node after = next(pos); + next(before_first) = next(before_last); + next(pos) = first; + next(before_last) = after; + } } - template - inline Node - slist_reverse(Node node, Node empty, - Next next) + template < class Node, class Next > + inline Node slist_reverse(Node node, Node empty, Next next) { - Node result = node; - node = next(node); - next(result) = empty; - while(node) { - Node next = next(node); - next(node) = result; - result = node; - node = next; - } - return result; + Node result = node; + node = next(node); + next(result) = empty; + while (node) + { + Node next = next(node); + next(node) = result; + result = node; + node = next; + } + return result; } - template - inline std::size_t - slist_size(Node head, Node empty, - Next next) + template < class Node, class Next > + inline std::size_t slist_size(Node head, Node empty, Next next) { - std::size_t s = 0; - for ( ; head != empty; head = next(head)) - ++s; - return s; + std::size_t s = 0; + for (; head != empty; head = next(head)) + ++s; + return s; } - template - class slist_iterator_policies + template < class Next, class Data > class slist_iterator_policies { public: - explicit slist_iterator_policies(const Next& n, const Data& d) - : m_next(n), m_data(d) { } + explicit slist_iterator_policies(const Next& n, const Data& d) + : m_next(n), m_data(d) + { + } - template - Reference dereference(type, const Node& x) const - { return m_data(x); } + template < class Reference, class Node > + Reference dereference(type< Reference >, const Node& x) const + { + return m_data(x); + } - template - void increment(Node& x) const - { x = m_next(x); } + template < class Node > void increment(Node& x) const { x = m_next(x); } - template - bool equal(Node& x, Node& y) const - { return x == y; } + template < class Node > bool equal(Node& x, Node& y) const + { + return x == y; + } protected: - Next m_next; - Data m_data; + Next m_next; + Data m_data; }; - //=========================================================================== - // Doubly-Linked List Generic Implementation Functions + //=========================================================================== + // Doubly-Linked List Generic Implementation Functions - template - inline void - dlist_insert_before(Node pos, Node x, - Next next, Prev prev) + template < class Node, class Next, class Prev > + inline void dlist_insert_before(Node pos, Node x, Next next, Prev prev) { - next(x) = pos; - prev(x) = prev(pos); - next(prev(pos)) = x; - prev(pos) = x; + next(x) = pos; + prev(x) = prev(pos); + next(prev(pos)) = x; + prev(pos) = x; } - template - void - dlist_remove(Node pos, - Next next, Prev prev) + template < class Node, class Next, class Prev > + void dlist_remove(Node pos, Next next, Prev prev) { - Node next_node = next(pos); - Node prev_node = prev(pos); - next(prev_node) = next_node; - prev(next_node) = prev_node; + Node next_node = next(pos); + Node prev_node = prev(pos); + next(prev_node) = next_node; + prev(next_node) = prev_node; } // This deletes every node in the list except the // sentinel node. - template - inline void - dlist_clear(Node sentinel, Delete del) + template < class Node, class Delete > + inline void dlist_clear(Node sentinel, Delete del) { - Node i, tmp; - i = next(sentinel); - while (i != sentinel) { - tmp = i; - i = next(i); - del(tmp); - } + Node i, tmp; + i = next(sentinel); + while (i != sentinel) + { + tmp = i; + i = next(i); + del(tmp); + } } - - template - inline bool - dlist_empty(Node dummy) + + template < class Node > inline bool dlist_empty(Node dummy) { - return next(dummy) == dummy; + return next(dummy) == dummy; } - template - void - dlist_transfer(Node pos, Node first, Node last, - Next next, Prev prev) + template < class Node, class Next, class Prev > + void dlist_transfer(Node pos, Node first, Node last, Next next, Prev prev) { - if (pos != last) { - // Remove [first,last) from its old position - next(prev(last)) = pos; - next(prev(first)) = last; - next(prev(pos)) = first; - - // Splice [first,last) into its new position - Node tmp = prev(pos); - prev(pos) = prev(last); - prev(last) = prev(first); - prev(first) = tmp; - } - } - - template - class dlist_iterator_policies - : public slist_iterator_policies + if (pos != last) + { + // Remove [first,last) from its old position + next(prev(last)) = pos; + next(prev(first)) = last; + next(prev(pos)) = first; + + // Splice [first,last) into its new position + Node tmp = prev(pos); + prev(pos) = prev(last); + prev(last) = prev(first); + prev(first) = tmp; + } + } + + template < class Next, class Prev, class Data > + class dlist_iterator_policies : public slist_iterator_policies< Next, Data > { - typedef slist_iterator_policies Base; + typedef slist_iterator_policies< Next, Data > Base; + public: - template - void decrement(Node& x) const - { x = m_prev(x); } + template < class Node > void decrement(Node& x) const { x = m_prev(x); } + + dlist_iterator_policies(Next n, Prev p, Data d) : Base(n, d), m_prev(p) + { + } - dlist_iterator_policies(Next n, Prev p, Data d) - : Base(n,d), m_prev(p) { } protected: - Prev m_prev; + Prev m_prev; }; - } // namespace detail +} // namespace detail } // namespace boost #endif // BOOST_LIST_BASE_HPP diff --git a/include/boost/graph/detail/mpi_include.hpp b/include/boost/graph/detail/mpi_include.hpp index 9e1c8858a..f64592dab 100644 --- a/include/boost/graph/detail/mpi_include.hpp +++ b/include/boost/graph/detail/mpi_include.hpp @@ -8,9 +8,9 @@ // LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) #if defined BOOST_GRAPH_USE_MPI -# define BOOST_GRAPH_MPI_INCLUDE(x) x +#define BOOST_GRAPH_MPI_INCLUDE(x) x #else -# define BOOST_GRAPH_MPI_INCLUDE(x) +#define BOOST_GRAPH_MPI_INCLUDE(x) #endif #endif // #ifndef BOOST_GRAPH_DETAIL_MPI_INCLUDE_HPP_INCLUDED diff --git a/include/boost/graph/detail/permutation.hpp b/include/boost/graph/detail/permutation.hpp index f1db906ab..31ced8e79 100644 --- a/include/boost/graph/detail/permutation.hpp +++ b/include/boost/graph/detail/permutation.hpp @@ -12,194 +12,200 @@ #include #include -namespace boost { +namespace boost +{ -template +template < class Iter1, class Iter2 > void permute_serial(Iter1 permuter, Iter1 last, Iter2 result) { #ifdef BOOST_NO_STD_ITERATOR_TRAITS - typedef std::ptrdiff_t D: + typedef std::ptrdiff_t D : #else - typedef typename std::iterator_traits::difference_type D; + typedef typename std::iterator_traits< Iter1 >::difference_type D; #endif - D n = 0; - while (permuter != last) { - std::swap(result[n], result[*permuter]); - ++n; - ++permuter; - } + D n + = 0; + while (permuter != last) + { + std::swap(result[n], result[*permuter]); + ++n; + ++permuter; + } } -template +template < class InIter, class RandIterP, class RandIterR > void permute_copy(InIter first, InIter last, RandIterP p, RandIterR result) { #ifdef BOOST_NO_STD_ITERATOR_TRAITS - typedef std::ptrdiff_t i = 0; + typedef std::ptrdiff_t i = 0; #else - typename std::iterator_traits::difference_type i = 0; + typename std::iterator_traits< RandIterP >::difference_type i = 0; #endif - for (; first != last; ++first, ++i) - result[p[i]] = *first; + for (; first != last; ++first, ++i) + result[p[i]] = *first; } -namespace detail { - -template -void permute_helper(RandIter first, RandIter last, RandIterPerm p, D, T) +namespace detail { - D i = 0, pi, n = last - first, cycle_start; - T tmp; - std::vector visited(n, false); - - while (i != n) { // continue until all elements have been processed - cycle_start = i; - tmp = first[i]; - do { // walk around a cycle - pi = p[i]; - visited[pi] = true; - std::swap(tmp, first[pi]); - i = pi; - } while (i != cycle_start); - - // find the next cycle - for (i = 0; i < n; ++i) - if (visited[i] == false) - break; - } -} + + template < class RandIter, class RandIterPerm, class D, class T > + void permute_helper(RandIter first, RandIter last, RandIterPerm p, D, T) + { + D i = 0, pi, n = last - first, cycle_start; + T tmp; + std::vector< int > visited(n, false); + + while (i != n) + { // continue until all elements have been processed + cycle_start = i; + tmp = first[i]; + do + { // walk around a cycle + pi = p[i]; + visited[pi] = true; + std::swap(tmp, first[pi]); + i = pi; + } while (i != cycle_start); + + // find the next cycle + for (i = 0; i < n; ++i) + if (visited[i] == false) + break; + } + } } // namespace detail -template +template < class RandIter, class RandIterPerm > void permute(RandIter first, RandIter last, RandIterPerm p) { - detail::permute_helper(first, last, p, last - first, *first); + detail::permute_helper(first, last, p, last - first, *first); } - // Knuth 1.3.3, Vol. 1 p 176 // modified for zero-based arrays // time complexity? // // WARNING: T must be a signed integer! -template -void invert_permutation(PermIter X, PermIter Xend) +template < class PermIter > void invert_permutation(PermIter X, PermIter Xend) { #ifdef BOOST_NO_STD_ITERATOR_TRAITS - typedef std::ptrdiff_t T: + typedef std::ptrdiff_t T : #else - typedef typename std::iterator_traits::value_type T; + typedef typename std::iterator_traits< PermIter >::value_type T; #endif - T n = Xend - X; - T m = n; - T j = -1; - - while (m > 0) { - T i = X[m-1] + 1; - if (i > 0) { - do { - X[m-1] = j - 1; - j = -m; - m = i; - i = X[m-1] + 1; - } while (i > 0); - i = j; + T n + = Xend - X; + T m = n; + T j = -1; + + while (m > 0) + { + T i = X[m - 1] + 1; + if (i > 0) + { + do + { + X[m - 1] = j - 1; + j = -m; + m = i; + i = X[m - 1] + 1; + } while (i > 0); + i = j; + } + X[m - 1] = -i - 1; + --m; } - X[m-1] = -i - 1; - --m; - } } // Takes a "normal" permutation array (and its inverse), and turns it // into a BLAS-style permutation array (which can be thought of as a // serialized permutation). -template +template < class Iter1, class Iter2, class Iter3 > inline void serialize_permutation(Iter1 q, Iter1 q_end, Iter2 q_inv, Iter3 p) { #ifdef BOOST_NO_STD_ITERATOR_TRAITS - typedef std::ptrdiff_t P1; - typedef std::ptrdiff_t P2; - typedef std::ptrdiff_t D; + typedef std::ptrdiff_t P1; + typedef std::ptrdiff_t P2; + typedef std::ptrdiff_t D; #else - typedef typename std::iterator_traits::value_type P1; - typedef typename std::iterator_traits::value_type P2; - typedef typename std::iterator_traits::difference_type D; + typedef typename std::iterator_traits< Iter1 >::value_type P1; + typedef typename std::iterator_traits< Iter2 >::value_type P2; + typedef typename std::iterator_traits< Iter1 >::difference_type D; #endif - D n = q_end - q; - for (D i = 0; i < n; ++i) { - P1 qi = q[i]; - P2 qii = q_inv[i]; - *p++ = qii; - std::swap(q[i], q[qii]); - std::swap(q_inv[i], q_inv[qi]); - } + D n = q_end - q; + for (D i = 0; i < n; ++i) + { + P1 qi = q[i]; + P2 qii = q_inv[i]; + *p++ = qii; + std::swap(q[i], q[qii]); + std::swap(q_inv[i], q_inv[qi]); + } } // Not used anymore, leaving it here for future reference. -template +template < typename Iter, typename Compare > void merge_sort(Iter first, Iter last, Compare cmp) { - if (first + 1 < last) { - Iter mid = first + (last - first)/2; - merge_sort(first, mid, cmp); - merge_sort(mid, last, cmp); - std::inplace_merge(first, mid, last, cmp); - } + if (first + 1 < last) + { + Iter mid = first + (last - first) / 2; + merge_sort(first, mid, cmp); + merge_sort(mid, last, cmp); + std::inplace_merge(first, mid, last, cmp); + } } - // time: N log N + 3N + ? // space: 2N -template +template < class Iter, class IterP, class Cmp, class Alloc > inline void sortp(Iter first, Iter last, IterP p, Cmp cmp, Alloc alloc) { - typedef typename std::iterator_traits::value_type P; - typedef typename std::iterator_traits::difference_type D; - D n = last - first; - std::vector q(n); - for (D i = 0; i < n; ++i) - q[i] = i; - std::sort(make_shadow_iter(first, q.begin()), - make_shadow_iter(last, q.end()), - shadow_cmp(cmp)); - invert_permutation(q.begin(), q.end()); - std::copy(q.begin(), q.end(), p); + typedef typename std::iterator_traits< IterP >::value_type P; + typedef typename std::iterator_traits< IterP >::difference_type D; + D n = last - first; + std::vector< P, Alloc > q(n); + for (D i = 0; i < n; ++i) + q[i] = i; + std::sort(make_shadow_iter(first, q.begin()), + make_shadow_iter(last, q.end()), shadow_cmp< Cmp >(cmp)); + invert_permutation(q.begin(), q.end()); + std::copy(q.begin(), q.end(), p); } -template +template < class Iter, class IterP, class Cmp > inline void sortp(Iter first, Iter last, IterP p, Cmp cmp) { - typedef typename std::iterator_traits::value_type P; - sortp(first, last, p, cmp, std::allocator

    ()); + typedef typename std::iterator_traits< IterP >::value_type P; + sortp(first, last, p, cmp, std::allocator< P >()); } -template +template < class Iter, class IterP > inline void sortp(Iter first, Iter last, IterP p) { - typedef typename std::iterator_traits::value_type T; - typedef typename std::iterator_traits::value_type P; - sortp(first, last, p, std::less(), std::allocator

    ()); + typedef typename std::iterator_traits< Iter >::value_type T; + typedef typename std::iterator_traits< IterP >::value_type P; + sortp(first, last, p, std::less< T >(), std::allocator< P >()); } -template +template < class Iter, class IterP, class Cmp, class Alloc > inline void sortv(Iter first, Iter last, IterP p, Cmp cmp, Alloc alloc) { - typedef typename std::iterator_traits::value_type P; - typedef typename std::iterator_traits::difference_type D; - D n = last - first; - std::vector q(n), q_inv(n); - for (D i = 0; i < n; ++i) - q_inv[i] = i; - std::sort(make_shadow_iter(first, q_inv.begin()), - make_shadow_iter(last, q_inv.end()), - shadow_cmp(cmp)); - std::copy(q_inv, q_inv.end(), q.begin()); - invert_permutation(q.begin(), q.end()); - serialize_permutation(q.begin(), q.end(), q_inv.end(), p); + typedef typename std::iterator_traits< IterP >::value_type P; + typedef typename std::iterator_traits< IterP >::difference_type D; + D n = last - first; + std::vector< P, Alloc > q(n), q_inv(n); + for (D i = 0; i < n; ++i) + q_inv[i] = i; + std::sort(make_shadow_iter(first, q_inv.begin()), + make_shadow_iter(last, q_inv.end()), shadow_cmp< Cmp >(cmp)); + std::copy(q_inv, q_inv.end(), q.begin()); + invert_permutation(q.begin(), q.end()); + serialize_permutation(q.begin(), q.end(), q_inv.end(), p); } - } // namespace boost #endif // BOOST_PERMUTATION_HPP diff --git a/include/boost/graph/detail/read_graphviz_new.hpp b/include/boost/graph/detail/read_graphviz_new.hpp index 8d3eea522..1e7ca7ca5 100644 --- a/include/boost/graph/detail/read_graphviz_new.hpp +++ b/include/boost/graph/detail/read_graphviz_new.hpp @@ -17,7 +17,7 @@ // http://www.graphviz.org/doc/info/lang.html // and page 34 or http://www.graphviz.org/pdf/dotguide.pdf // -// See documentation for this code at: +// See documentation for this code at: // http://www.boost.org/libs/graph/doc/read_graphviz.html // @@ -41,66 +41,82 @@ #include #include -namespace boost { - -namespace read_graphviz_detail { - typedef std::string node_name; - typedef std::string subgraph_name; - - typedef std::map properties; - - struct node_and_port { - node_name name; - std::string angle; // Or empty if no angle - std::vector location; // Up to two identifiers - - friend inline bool operator==(const node_and_port& a, const node_and_port& b) { - return a.name == b.name && - a.angle == b.angle && - a.location == b.location; - } - - friend inline bool operator<(const node_and_port& a, const node_and_port& b) { - if (a.name != b.name) return a.name < b.name; - if (a.angle != b.angle) return a.angle < b.angle; - return a.location < b.location; - } - }; - - struct edge_info { - node_and_port source; - node_and_port target; - properties props; - }; - - struct parser_result { - bool graph_is_directed; - bool graph_is_strict; - std::map nodes; // Global set - std::vector edges; - std::map graph_props; // Root and subgraphs - }; - - // The actual parser, from libs/graph/src/read_graphviz_new.cpp - void parse_graphviz_from_string(const std::string& str, parser_result& result, bool want_directed); - - // Translate from those results to a graph - void translate_results_to_graph(const parser_result& r, ::boost::detail::graph::mutate_graph* mg); +namespace boost +{ + +namespace read_graphviz_detail +{ + typedef std::string node_name; + typedef std::string subgraph_name; + + typedef std::map< std::string, std::string > properties; + + struct node_and_port + { + node_name name; + std::string angle; // Or empty if no angle + std::vector< std::string > location; // Up to two identifiers + + friend inline bool operator==( + const node_and_port& a, const node_and_port& b) + { + return a.name == b.name && a.angle == b.angle + && a.location == b.location; + } + + friend inline bool operator<( + const node_and_port& a, const node_and_port& b) + { + if (a.name != b.name) + return a.name < b.name; + if (a.angle != b.angle) + return a.angle < b.angle; + return a.location < b.location; + } + }; + + struct edge_info + { + node_and_port source; + node_and_port target; + properties props; + }; + + struct parser_result + { + bool graph_is_directed; + bool graph_is_strict; + std::map< node_name, properties > nodes; // Global set + std::vector< edge_info > edges; + std::map< subgraph_name, properties > graph_props; // Root and subgraphs + }; + + // The actual parser, from libs/graph/src/read_graphviz_new.cpp + void parse_graphviz_from_string( + const std::string& str, parser_result& result, bool want_directed); + + // Translate from those results to a graph + void translate_results_to_graph( + const parser_result& r, ::boost::detail::graph::mutate_graph* mg); } // namespace read_graphviz_detail -namespace detail { - namespace graph { - BOOST_GRAPH_DECL bool read_graphviz_new(const std::string& str, boost::detail::graph::mutate_graph* mg); - } // end namespace graph +namespace detail +{ + namespace graph + { + BOOST_GRAPH_DECL bool read_graphviz_new( + const std::string& str, boost::detail::graph::mutate_graph* mg); + } // end namespace graph } // end namespace detail -template -bool read_graphviz_new(const std::string& str, - MutableGraph& graph, boost::dynamic_properties& dp, - std::string const& node_id = "node_id") { - boost::detail::graph::mutate_graph_impl mg(graph, dp, node_id); - return detail::graph::read_graphviz_new(str, &mg); +template < typename MutableGraph > +bool read_graphviz_new(const std::string& str, MutableGraph& graph, + boost::dynamic_properties& dp, std::string const& node_id = "node_id") +{ + boost::detail::graph::mutate_graph_impl< MutableGraph > mg( + graph, dp, node_id); + return detail::graph::read_graphviz_new(str, &mg); } } // namespace boost diff --git a/include/boost/graph/detail/read_graphviz_spirit.hpp b/include/boost/graph/detail/read_graphviz_spirit.hpp index d10bbc720..b39ad7d63 100644 --- a/include/boost/graph/detail/read_graphviz_spirit.hpp +++ b/include/boost/graph/detail/read_graphviz_spirit.hpp @@ -13,7 +13,7 @@ // Based on the grammar found at: // https://web.archive.org/web/20041213234742/http://www.graphviz.org/cvs/doc/info/lang.html // -// See documentation for this code at: +// See documentation for this code at: // http://www.boost.org/libs/graph/doc/read_graphviz.html // @@ -27,7 +27,6 @@ #define PHOENIX_LIMIT 6 #define BOOST_SPIRIT_CLOSURE_LIMIT 6 - #include #include #include @@ -56,557 +55,617 @@ #include #include -namespace phoenix { +namespace phoenix +{ // Workaround: std::map::operator[] uses a different return type than all // other standard containers. Phoenix doesn't account for that. -template -struct binary_operator, T1> +template < typename TK, typename T0, typename T1 > +struct binary_operator< index_op, std::map< TK, T0 >, T1 > { - typedef typename std::map::mapped_type& result_type; - static result_type eval(std::map& container, T1 const& index) - { return container[index]; } + typedef typename std::map< TK, T0 >::mapped_type& result_type; + static result_type eval(std::map< TK, T0 >& container, T1 const& index) + { + return container[index]; + } }; } // namespace phoenix -namespace boost { -namespace detail { -namespace graph { - - -///////////////////////////////////////////////////////////////////////////// -// Application-specific type definitions -///////////////////////////////////////////////////////////////////////////// - -typedef std::set edges_t; -typedef std::set nodes_t; -typedef std::set ids_t; -typedef std::map edge_map_t; -typedef std::map node_map_t; -typedef std::map props_t; -typedef std::map subgraph_props_t; -typedef boost::function2 actor_t; -typedef std::vector edge_stack_t; -typedef std::map subgraph_nodes_t; -typedef std::map subgraph_edges_t; - - - -///////////////////////////////////////////////////////////////////////////// -// Stack frames used by semantic actions -///////////////////////////////////////////////////////////////////////////// -struct id_closure : boost::spirit::classic::closure { - member1 name; -}; - - -struct node_id_closure : boost::spirit::classic::closure { - member1 name; -}; - -struct attr_list_closure : boost::spirit::classic::closure { - member1 prop_actor; -}; - -struct property_closure : boost::spirit::classic::closure { - member1 key; - member2 value; -}; - -struct data_stmt_closure : boost::spirit::classic::closure { - member1 sources; - member2 dests; - member3 edge_stack; - member4 saw_node; - member5 active_node; -}; - -struct subgraph_closure : boost::spirit::classic::closure { - member1 nodes; - member2 edges; - member3 name; -}; +namespace boost +{ +namespace detail +{ + namespace graph + { -///////////////////////////////////////////////////////////////////////////// -// Grammar and Actions for the DOT Language -///////////////////////////////////////////////////////////////////////////// - -// Grammar for a dot file. -struct dot_grammar : public boost::spirit::classic::grammar { - mutate_graph& graph_; - explicit dot_grammar(mutate_graph& graph) : graph_(graph) { } - - template - struct definition { - - definition(dot_grammar const& self) : self(self), subgraph_depth(0), - keyword_p("0-9a-zA-Z_") { - using namespace boost::spirit::classic; - using namespace phoenix; - - // RG - Future Work - // - Handle multi-line strings using \ line continuation - // - Make keywords case insensitive - ID - = ( lexeme_d[((alpha_p | ch_p('_')) >> *(alnum_p | ch_p('_')))] - | real_p - | lexeme_d[confix_p('"', *c_escape_ch_p, '"')] - | comment_nest_p('<', '>') - )[ID.name = construct_(arg1,arg2)] - ; - - a_list - = list_p( ID[(a_list.key = arg1), - (a_list.value = "true") - ] - >> !( ch_p('=') - >> ID[a_list.value = arg1]) - [phoenix::bind(&definition::call_prop_actor) - (var(*this),a_list.key,a_list.value)],!ch_p(',')); - - attr_list = +(ch_p('[') >> !a_list >> ch_p(']')); - - // RG - disregard port id's for now. - port_location - = (ch_p(':') >> ID) - | (ch_p(':') >> ch_p('(') >> ID >> ch_p(',') >> ID >> ch_p(')')) - ; - - port_angle = ch_p('@') >> ID; - - port - = port_location >> (!port_angle) - | port_angle >> (!port_location); - - - node_id - = ( ID[node_id.name = arg1] >> (!port) ) - [phoenix::bind(&definition::memoize_node)(var(*this))]; - - graph_stmt - = (ID[graph_stmt.key = arg1] >> - ch_p('=') >> - ID[graph_stmt.value = arg1]) - [phoenix::bind(&definition::call_graph_prop) - (var(*this),graph_stmt.key,graph_stmt.value)] - ; // Graph property. - - attr_stmt - = (as_lower_d[keyword_p("graph")] - >> attr_list(actor_t(phoenix::bind(&definition::default_graph_prop) - (var(*this),arg1,arg2)))) - | (as_lower_d[keyword_p("node")] - >> attr_list(actor_t(phoenix::bind(&definition::default_node_prop) - (var(*this),arg1,arg2)))) - | (as_lower_d[keyword_p("edge")] - >> attr_list(actor_t(phoenix::bind(&definition::default_edge_prop) - (var(*this),arg1,arg2)))) - ; - - // edge_head is set depending on the graph type (directed/undirected) - edgeop = ch_p('-') >> ch_p(boost::ref(edge_head)); - - edgeRHS - = +( edgeop[(data_stmt.sources = data_stmt.dests), - (data_stmt.dests = construct_())] - >> ( subgraph[data_stmt.dests = arg1] - | node_id[phoenix::bind(&definition::insert_node) - (var(*this),data_stmt.dests,arg1)] - ) - [phoenix::bind(&definition::activate_edge) - (var(*this),data_stmt.sources,data_stmt.dests, - var(edges), var(default_edge_props))] - ); - - - // To avoid backtracking, edge, node, and subgraph statements are - // processed as one nonterminal. - data_stmt - = ( subgraph[(data_stmt.dests = arg1),// will get moved in rhs - (data_stmt.saw_node = false)] - | node_id[(phoenix::bind(&definition::insert_node) - (var(*this),data_stmt.dests,arg1)), - (data_stmt.saw_node = true), + ///////////////////////////////////////////////////////////////////////////// + // Application-specific type definitions + ///////////////////////////////////////////////////////////////////////////// + + typedef std::set< edge_t > edges_t; + typedef std::set< node_t > nodes_t; + typedef std::set< id_t > ids_t; + typedef std::map< edge_t, ids_t > edge_map_t; + typedef std::map< node_t, ids_t > node_map_t; + typedef std::map< id_t, id_t > props_t; + typedef std::map< id_t, props_t > subgraph_props_t; + typedef boost::function2< void, id_t const&, id_t const& > actor_t; + typedef std::vector< edge_t > edge_stack_t; + typedef std::map< id_t, nodes_t > subgraph_nodes_t; + typedef std::map< id_t, edges_t > subgraph_edges_t; + + ///////////////////////////////////////////////////////////////////////////// + // Stack frames used by semantic actions + ///////////////////////////////////////////////////////////////////////////// + struct id_closure + : boost::spirit::classic::closure< id_closure, node_t > + { + member1 name; + }; + + struct node_id_closure + : boost::spirit::classic::closure< node_id_closure, node_t > + { + member1 name; + }; + + struct attr_list_closure + : boost::spirit::classic::closure< attr_list_closure, actor_t > + { + member1 prop_actor; + }; + + struct property_closure + : boost::spirit::classic::closure< property_closure, id_t, id_t > + { + member1 key; + member2 value; + }; + + struct data_stmt_closure + : boost::spirit::classic::closure< data_stmt_closure, nodes_t, nodes_t, + edge_stack_t, bool, node_t > + { + member1 sources; + member2 dests; + member3 edge_stack; + member4 saw_node; + member5 active_node; + }; + + struct subgraph_closure + : boost::spirit::classic::closure< subgraph_closure, nodes_t, edges_t, + node_t > + { + member1 nodes; + member2 edges; + member3 name; + }; + + ///////////////////////////////////////////////////////////////////////////// + // Grammar and Actions for the DOT Language + ///////////////////////////////////////////////////////////////////////////// + + // Grammar for a dot file. + struct dot_grammar + : public boost::spirit::classic::grammar< dot_grammar > + { + mutate_graph& graph_; + explicit dot_grammar(mutate_graph& graph) : graph_(graph) {} + + template < class ScannerT > struct definition + { + + definition(dot_grammar const& self) + : self(self), subgraph_depth(0), keyword_p("0-9a-zA-Z_") + { + using namespace boost::spirit::classic; + using namespace phoenix; + + // RG - Future Work + // - Handle multi-line strings using \ line continuation + // - Make keywords case insensitive + ID = (lexeme_d[( + (alpha_p | ch_p('_')) >> *(alnum_p | ch_p('_')))] + | real_p | lexeme_d[confix_p('"', *c_escape_ch_p, '"')] + | comment_nest_p('<', '>'))[ID.name + = construct_< std::string >(arg1, arg2)]; + + a_list = list_p( + ID[(a_list.key = arg1), (a_list.value = "true")] >> !( + ch_p('=') >> ID[a_list.value = arg1])[phoenix::bind( + &definition::call_prop_actor)( + var(*this), a_list.key, a_list.value)], + !ch_p(',')); + + attr_list = +(ch_p('[') >> !a_list >> ch_p(']')); + + // RG - disregard port id's for now. + port_location = (ch_p(':') >> ID) + | (ch_p(':') >> ch_p('(') >> ID >> ch_p(',') >> ID + >> ch_p(')')); + + port_angle = ch_p('@') >> ID; + + port = port_location >> (!port_angle) + | port_angle >> (!port_location); + + node_id + = (ID[node_id.name = arg1] >> (!port))[phoenix::bind( + &definition::memoize_node)(var(*this))]; + + graph_stmt = (ID[graph_stmt.key = arg1] >> ch_p('=') + >> ID[graph_stmt.value = arg1])[phoenix::bind( + &definition::call_graph_prop)(var(*this), + graph_stmt.key, graph_stmt.value)]; // Graph property. + + attr_stmt + = (as_lower_d[keyword_p("graph")] >> attr_list(actor_t( + phoenix::bind(&definition::default_graph_prop)( + var(*this), arg1, arg2)))) + | (as_lower_d[keyword_p("node")] >> attr_list(actor_t( + phoenix::bind(&definition::default_node_prop)( + var(*this), arg1, arg2)))) + | (as_lower_d[keyword_p("edge")] >> attr_list(actor_t( + phoenix::bind(&definition::default_edge_prop)( + var(*this), arg1, arg2)))); + + // edge_head is set depending on the graph type + // (directed/undirected) + edgeop = ch_p('-') >> ch_p(boost::ref(edge_head)); + + edgeRHS = +(edgeop[(data_stmt.sources = data_stmt.dests), + (data_stmt.dests = construct_< nodes_t >())] + >> (subgraph[data_stmt.dests = arg1] + | node_id[phoenix::bind(&definition::insert_node)( + var(*this), data_stmt.dests, arg1)]) + [phoenix::bind(&definition::activate_edge)( + var(*this), data_stmt.sources, data_stmt.dests, + var(edges), var(default_edge_props))]); + + // To avoid backtracking, edge, node, and subgraph + // statements are processed as one nonterminal. + data_stmt + = (subgraph[(data_stmt.dests + = arg1), // will get moved in rhs + (data_stmt.saw_node = false)] + | node_id[(phoenix::bind( + &definition::insert_node)( + var(*this), data_stmt.dests, arg1)), + (data_stmt.saw_node = true), #ifdef BOOST_GRAPH_DEBUG - (std::cout << val("AcTive Node: ") << arg1 << "\n"), + (std::cout << val("AcTive Node: ") << arg1 + << "\n"), #endif // BOOST_GRAPH_DEBUG - (data_stmt.active_node = arg1)] - ) >> if_p(edgeRHS)[ - !attr_list( - actor_t(phoenix::bind(&definition::edge_prop) - (var(*this),arg1,arg2))) - ].else_p[ - if_p(data_stmt.saw_node)[ - !attr_list( - actor_t(phoenix::bind(&definition::node_prop) - (var(*this),arg1,arg2))) - ] // otherwise it's a subgraph, nothing more to do. - ]; - - - stmt - = graph_stmt - | attr_stmt - | data_stmt - ; - - stmt_list = *( stmt >> !ch_p(';') ); - - subgraph - = !( as_lower_d[keyword_p("subgraph")] - >> (!ID[(subgraph.name = arg1), - (subgraph.nodes = (var(subgraph_nodes))[arg1]), - (subgraph.edges = (var(subgraph_edges))[arg1])]) - ) - >> ch_p('{')[++var(subgraph_depth)] - >> stmt_list - >> ch_p('}')[--var(subgraph_depth)] - [(var(subgraph_nodes))[subgraph.name] = subgraph.nodes] - [(var(subgraph_edges))[subgraph.name] = subgraph.edges] - - | as_lower_d[keyword_p("subgraph")] - >> ID[(subgraph.nodes = (var(subgraph_nodes))[arg1]), - (subgraph.edges = (var(subgraph_edges))[arg1])] - ; - - the_grammar - = (!as_lower_d[keyword_p("strict")]) - >> ( as_lower_d[keyword_p("graph")][ - (var(edge_head) = '-'), - (phoenix::bind(&definition::check_undirected)(var(*this)))] - | as_lower_d[keyword_p("digraph")][ - (var(edge_head) = '>'), - (phoenix::bind(&definition::check_directed)(var(*this)))] - ) - >> (!ID) >> ch_p('{') >> stmt_list >> ch_p('}'); - - } // definition() - - typedef boost::spirit::classic::rule rule_t; - - rule_t const& start() const { return the_grammar; } - - - // - // Semantic actions - // - - void check_undirected() { - if(self.graph_.is_directed()) - boost::throw_exception(boost::undirected_graph_error()); - } - - void check_directed() { - if(!self.graph_.is_directed()) - boost::throw_exception(boost::directed_graph_error()); - } - - void memoize_node() { - id_t const& node = node_id.name(); - props_t& node_props = default_node_props; - - if(nodes.find(node) == nodes.end()) { - nodes.insert(node); - self.graph_.do_add_vertex(node); - - node_map.insert(std::make_pair(node,ids_t())); + (data_stmt.active_node = arg1)]) + >> if_p(edgeRHS)[!attr_list(actor_t(phoenix::bind( + &definition::edge_prop)( + var(*this), arg1, arg2)))] + .else_p[if_p(data_stmt.saw_node)[!attr_list( + actor_t(phoenix::bind( + &definition::node_prop)(var(*this), arg1, + arg2)))] // otherwise it's a subgraph, + // nothing more to do. + ]; + + stmt = graph_stmt | attr_stmt | data_stmt; + + stmt_list = *(stmt >> !ch_p(';')); + + subgraph = !(as_lower_d[keyword_p("subgraph")] + >> (!ID[(subgraph.name = arg1), + (subgraph.nodes + = (var(subgraph_nodes))[arg1]), + (subgraph.edges + = (var(subgraph_edges))[arg1])])) + >> ch_p('{')[++var(subgraph_depth)] >> stmt_list + >> ch_p('}')[--var(subgraph_depth)] + [(var(subgraph_nodes))[subgraph.name] + = subgraph.nodes] + [(var(subgraph_edges))[subgraph.name] + = subgraph.edges] + + | as_lower_d[keyword_p("subgraph")] + >> ID[(subgraph.nodes + = (var(subgraph_nodes))[arg1]), + (subgraph.edges = (var(subgraph_edges))[arg1])]; + + the_grammar = (!as_lower_d[keyword_p("strict")]) + >> (as_lower_d[keyword_p( + "graph")][(var(edge_head) = '-'), + (phoenix::bind(&definition::check_undirected)( + var(*this)))] + | as_lower_d[keyword_p( + "digraph")][(var(edge_head) = '>'), + (phoenix::bind(&definition::check_directed)( + var(*this)))]) + >> (!ID) >> ch_p('{') >> stmt_list >> ch_p('}'); + + } // definition() + + typedef boost::spirit::classic::rule< ScannerT > rule_t; + + rule_t const& start() const { return the_grammar; } + + // + // Semantic actions + // + + void check_undirected() + { + if (self.graph_.is_directed()) + boost::throw_exception(boost::undirected_graph_error()); + } + + void check_directed() + { + if (!self.graph_.is_directed()) + boost::throw_exception(boost::directed_graph_error()); + } + + void memoize_node() + { + id_t const& node = node_id.name(); + props_t& node_props = default_node_props; + + if (nodes.find(node) == nodes.end()) + { + nodes.insert(node); + self.graph_.do_add_vertex(node); + + node_map.insert(std::make_pair(node, ids_t())); #ifdef BOOST_GRAPH_DEBUG - std::cout << "Add new node " << node << std::endl; + std::cout << "Add new node " << node << std::endl; #endif // BOOST_GRAPH_DEBUG - // Set the default properties for this edge - // RG: Here I would actually set the properties - for(props_t::iterator i = node_props.begin(); - i != node_props.end(); ++i) { - set_node_property(node,i->first,i->second); - } - if(subgraph_depth > 0) { - subgraph.nodes().insert(node); - // Set the subgraph's default properties as well - props_t& props = subgraph_node_props[subgraph.name()]; - for(props_t::iterator i = props.begin(); i != props.end(); ++i) { - set_node_property(node,i->first,i->second); - } - } - } else { + // Set the default properties for this edge + // RG: Here I would actually set the properties + for (props_t::iterator i = node_props.begin(); + i != node_props.end(); ++i) + { + set_node_property(node, i->first, i->second); + } + if (subgraph_depth > 0) + { + subgraph.nodes().insert(node); + // Set the subgraph's default properties as well + props_t& props + = subgraph_node_props[subgraph.name()]; + for (props_t::iterator i = props.begin(); + i != props.end(); ++i) + { + set_node_property(node, i->first, i->second); + } + } + } + else + { #ifdef BOOST_GRAPH_DEBUG - std::cout << "See node " << node << std::endl; + std::cout << "See node " << node << std::endl; #endif // BOOST_GRAPH_DEBUG - } - } - - void activate_edge(nodes_t& sources, nodes_t& dests, edges_t& edges, - props_t& edge_props) { - edge_stack_t& edge_stack = data_stmt.edge_stack(); - for(nodes_t::iterator i = sources.begin(); i != sources.end(); ++i) { - for(nodes_t::iterator j = dests.begin(); j != dests.end(); ++j) { - // Create the edge and push onto the edge stack. + } + } + + void activate_edge(nodes_t& sources, nodes_t& dests, + edges_t& edges, props_t& edge_props) + { + edge_stack_t& edge_stack = data_stmt.edge_stack(); + for (nodes_t::iterator i = sources.begin(); + i != sources.end(); ++i) + { + for (nodes_t::iterator j = dests.begin(); + j != dests.end(); ++j) + { + // Create the edge and push onto the edge stack. #ifdef BOOST_GRAPH_DEBUG - std::cout << "Edge " << *i << " to " << *j << std::endl; + std::cout << "Edge " << *i << " to " << *j + << std::endl; #endif // BOOST_GRAPH_DEBUG - edge_t edge = edge_t::new_edge(); - edge_stack.push_back(edge); - edges.insert(edge); - edge_map.insert(std::make_pair(edge,ids_t())); - - // Add the real edge. - self.graph_.do_add_edge(edge, *i, *j); - - // Set the default properties for this edge - for(props_t::iterator k = edge_props.begin(); - k != edge_props.end(); ++k) { - set_edge_property(edge,k->first,k->second); - } - if(subgraph_depth > 0) { - subgraph.edges().insert(edge); - // Set the subgraph's default properties as well - props_t& props = subgraph_edge_props[subgraph.name()]; - for(props_t::iterator k = props.begin(); k != props.end(); ++k) { - set_edge_property(edge,k->first,k->second); - } - } - } - } - } - - // node_prop - Assign the property for the current active node. - void node_prop(id_t const& key, id_t const& value) { - node_t& active_object = data_stmt.active_node(); - set_node_property(active_object, key, value); - } - - // edge_prop - Assign the property for the current active edges. - void edge_prop(id_t const& key, id_t const& value) { - edge_stack_t const& active_edges_ = data_stmt.edge_stack(); - for (edge_stack_t::const_iterator i = active_edges_.begin(); - i != active_edges_.end(); ++i) { - set_edge_property(*i,key,value); - } - } - - // default_graph_prop - Store as a graph property. - void default_graph_prop(id_t const& key, id_t const& value) { + edge_t edge = edge_t::new_edge(); + edge_stack.push_back(edge); + edges.insert(edge); + edge_map.insert(std::make_pair(edge, ids_t())); + + // Add the real edge. + self.graph_.do_add_edge(edge, *i, *j); + + // Set the default properties for this edge + for (props_t::iterator k = edge_props.begin(); + k != edge_props.end(); ++k) + { + set_edge_property(edge, k->first, k->second); + } + if (subgraph_depth > 0) + { + subgraph.edges().insert(edge); + // Set the subgraph's default properties as well + props_t& props + = subgraph_edge_props[subgraph.name()]; + for (props_t::iterator k = props.begin(); + k != props.end(); ++k) + { + set_edge_property( + edge, k->first, k->second); + } + } + } + } + } + + // node_prop - Assign the property for the current active node. + void node_prop(id_t const& key, id_t const& value) + { + node_t& active_object = data_stmt.active_node(); + set_node_property(active_object, key, value); + } + + // edge_prop - Assign the property for the current active edges. + void edge_prop(id_t const& key, id_t const& value) + { + edge_stack_t const& active_edges_ = data_stmt.edge_stack(); + for (edge_stack_t::const_iterator i = active_edges_.begin(); + i != active_edges_.end(); ++i) + { + set_edge_property(*i, key, value); + } + } + + // default_graph_prop - Store as a graph property. + void default_graph_prop(id_t const& key, id_t const& value) + { #ifdef BOOST_GRAPH_DEBUG - std::cout << key << " = " << value << std::endl; + std::cout << key << " = " << value << std::endl; #endif // BOOST_GRAPH_DEBUG - self.graph_.set_graph_property(key, value); - } - - // default_node_prop - declare default properties for any future new nodes - void default_node_prop(id_t const& key, id_t const& value) { - nodes_t& nodes_ = - subgraph_depth == 0 ? nodes : subgraph.nodes(); - props_t& node_props_ = - subgraph_depth == 0 ? - default_node_props : - subgraph_node_props[subgraph.name()]; - - // add this to the selected list of default node properties. - node_props_[key] = value; - // for each node, set its property to default-constructed value - // if it hasn't been set already. - // set the dynamic property map value - for(nodes_t::iterator i = nodes_.begin(); i != nodes_.end(); ++i) - if(node_map[*i].find(key) == node_map[*i].end()) { - set_node_property(*i,key,id_t()); - } - } - - // default_edge_prop - declare default properties for any future new edges - void default_edge_prop(id_t const& key, id_t const& value) { - edges_t& edges_ = - subgraph_depth == 0 ? edges : subgraph.edges(); - props_t& edge_props_ = - subgraph_depth == 0 ? - default_edge_props : - subgraph_edge_props[subgraph.name()]; - - // add this to the list of default edge properties. - edge_props_[key] = value; - // for each edge, set its property to be empty string - // set the dynamic property map value - for(edges_t::iterator i = edges_.begin(); i != edges_.end(); ++i) - if(edge_map[*i].find(key) == edge_map[*i].end()) - set_edge_property(*i,key,id_t()); - } - - // helper function - void insert_node(nodes_t& nodes, id_t const& name) { - nodes.insert(name); - } - - void call_prop_actor(std::string const& lhs, std::string const& rhs) { - actor_t& actor = attr_list.prop_actor(); - // If first and last characters of the rhs are double-quotes, - // remove them. - if (!rhs.empty() && rhs[0] == '"' && rhs[rhs.size() - 1] == '"') - actor(lhs, rhs.substr(1, rhs.size()-2)); - else - actor(lhs,rhs); - } - - void call_graph_prop(std::string const& lhs, std::string const& rhs) { - // If first and last characters of the rhs are double-quotes, - // remove them. - if (!rhs.empty() && rhs[0] == '"' && rhs[rhs.size() - 1] == '"') - this->default_graph_prop(lhs, rhs.substr(1, rhs.size()-2)); - else - this->default_graph_prop(lhs,rhs); - } - - void set_node_property(node_t const& node, id_t const& key, - id_t const& value) { - - // Add the property key to the "set" table to avoid default overwrite - node_map[node].insert(key); - // Set the user's property map - self.graph_.set_node_property(key, node, value); + self.graph_.set_graph_property(key, value); + } + + // default_node_prop - declare default properties for any future + // new nodes + void default_node_prop(id_t const& key, id_t const& value) + { + nodes_t& nodes_ + = subgraph_depth == 0 ? nodes : subgraph.nodes(); + props_t& node_props_ = subgraph_depth == 0 + ? default_node_props + : subgraph_node_props[subgraph.name()]; + + // add this to the selected list of default node properties. + node_props_[key] = value; + // for each node, set its property to default-constructed + // value + // if it hasn't been set already. + // set the dynamic property map value + for (nodes_t::iterator i = nodes_.begin(); + i != nodes_.end(); ++i) + if (node_map[*i].find(key) == node_map[*i].end()) + { + set_node_property(*i, key, id_t()); + } + } + + // default_edge_prop - declare default properties for any future + // new edges + void default_edge_prop(id_t const& key, id_t const& value) + { + edges_t& edges_ + = subgraph_depth == 0 ? edges : subgraph.edges(); + props_t& edge_props_ = subgraph_depth == 0 + ? default_edge_props + : subgraph_edge_props[subgraph.name()]; + + // add this to the list of default edge properties. + edge_props_[key] = value; + // for each edge, set its property to be empty string + // set the dynamic property map value + for (edges_t::iterator i = edges_.begin(); + i != edges_.end(); ++i) + if (edge_map[*i].find(key) == edge_map[*i].end()) + set_edge_property(*i, key, id_t()); + } + + // helper function + void insert_node(nodes_t& nodes, id_t const& name) + { + nodes.insert(name); + } + + void call_prop_actor( + std::string const& lhs, std::string const& rhs) + { + actor_t& actor = attr_list.prop_actor(); + // If first and last characters of the rhs are + // double-quotes, remove them. + if (!rhs.empty() && rhs[0] == '"' + && rhs[rhs.size() - 1] == '"') + actor(lhs, rhs.substr(1, rhs.size() - 2)); + else + actor(lhs, rhs); + } + + void call_graph_prop( + std::string const& lhs, std::string const& rhs) + { + // If first and last characters of the rhs are + // double-quotes, remove them. + if (!rhs.empty() && rhs[0] == '"' + && rhs[rhs.size() - 1] == '"') + this->default_graph_prop( + lhs, rhs.substr(1, rhs.size() - 2)); + else + this->default_graph_prop(lhs, rhs); + } + + void set_node_property( + node_t const& node, id_t const& key, id_t const& value) + { + + // Add the property key to the "set" table to avoid default + // overwrite + node_map[node].insert(key); + // Set the user's property map + self.graph_.set_node_property(key, node, value); #ifdef BOOST_GRAPH_DEBUG - // Tell the world - std::cout << node << ": " << key << " = " << value << std::endl; + // Tell the world + std::cout << node << ": " << key << " = " << value + << std::endl; #endif // BOOST_GRAPH_DEBUG - } + } - void set_edge_property(edge_t const& edge, id_t const& key, - id_t const& value) { + void set_edge_property( + edge_t const& edge, id_t const& key, id_t const& value) + { - // Add the property key to the "set" table to avoid default overwrite - edge_map[edge].insert(key); - // Set the user's property map - self.graph_.set_edge_property(key, edge, value); + // Add the property key to the "set" table to avoid default + // overwrite + edge_map[edge].insert(key); + // Set the user's property map + self.graph_.set_edge_property(key, edge, value); #ifdef BOOST_GRAPH_DEBUG - // Tell the world -#if 0 // RG - edge representation changed, + // Tell the world +#if 0 // RG - edge representation changed, std::cout << "(" << edge.first << "," << edge.second << "): " #else - std::cout << "an edge: " + std::cout << "an edge: " #endif // 0 - << key << " = " << value << std::endl; + << key << " = " << value << std::endl; #endif // BOOST_GRAPH_DEBUG - } - - // Variables explicitly initialized - dot_grammar const& self; - // if subgraph_depth > 0, then we're processing a subgraph. - int subgraph_depth; - - // Keywords; - const boost::spirit::classic::distinct_parser<> keyword_p; - // - // rules that make up the grammar - // - boost::spirit::classic::rule ID; - boost::spirit::classic::rule a_list; - boost::spirit::classic::rule attr_list; - rule_t port_location; - rule_t port_angle; - rule_t port; - boost::spirit::classic::rule node_id; - boost::spirit::classic::rule graph_stmt; - rule_t attr_stmt; - boost::spirit::classic::rule data_stmt; - boost::spirit::classic::rule subgraph; - rule_t edgeop; - rule_t edgeRHS; - rule_t stmt; - rule_t stmt_list; - rule_t the_grammar; - - - // The grammar uses edge_head to dynamically set the syntax for edges - // directed graphs: edge_head = '>', and so edgeop = "->" - // undirected graphs: edge_head = '-', and so edgeop = "--" - char edge_head; - - - // - // Support data structures - // - - nodes_t nodes; // list of node names seen - edges_t edges; // list of edges seen - node_map_t node_map; // remember the properties set for each node - edge_map_t edge_map; // remember the properties set for each edge - - subgraph_nodes_t subgraph_nodes; // per-subgraph lists of nodes - subgraph_edges_t subgraph_edges; // per-subgraph lists of edges - - props_t default_node_props; // global default node properties - props_t default_edge_props; // global default edge properties - subgraph_props_t subgraph_node_props; // per-subgraph default node properties - subgraph_props_t subgraph_edge_props; // per-subgraph default edge properties - }; // struct definition -}; // struct dot_grammar - - - -// -// dot_skipper - GraphViz whitespace and comment skipper -// -struct dot_skipper : public boost::spirit::classic::grammar -{ - dot_skipper() {} - - template - struct definition - { - definition(dot_skipper const& /*self*/) { - using namespace boost::spirit::classic; - using namespace phoenix; - // comment forms - skip = eol_p >> comment_p("#") - | space_p - | comment_p("//") + } + + // Variables explicitly initialized + dot_grammar const& self; + // if subgraph_depth > 0, then we're processing a subgraph. + int subgraph_depth; + + // Keywords; + const boost::spirit::classic::distinct_parser<> keyword_p; + // + // rules that make up the grammar + // + boost::spirit::classic::rule< ScannerT, id_closure::context_t > + ID; + boost::spirit::classic::rule< ScannerT, + property_closure::context_t > + a_list; + boost::spirit::classic::rule< ScannerT, + attr_list_closure::context_t > + attr_list; + rule_t port_location; + rule_t port_angle; + rule_t port; + boost::spirit::classic::rule< ScannerT, + node_id_closure::context_t > + node_id; + boost::spirit::classic::rule< ScannerT, + property_closure::context_t > + graph_stmt; + rule_t attr_stmt; + boost::spirit::classic::rule< ScannerT, + data_stmt_closure::context_t > + data_stmt; + boost::spirit::classic::rule< ScannerT, + subgraph_closure::context_t > + subgraph; + rule_t edgeop; + rule_t edgeRHS; + rule_t stmt; + rule_t stmt_list; + rule_t the_grammar; + + // The grammar uses edge_head to dynamically set the syntax for + // edges directed graphs: edge_head = '>', and so edgeop = "->" + // undirected graphs: edge_head = '-', and so edgeop = "--" + char edge_head; + + // + // Support data structures + // + + nodes_t nodes; // list of node names seen + edges_t edges; // list of edges seen + node_map_t + node_map; // remember the properties set for each node + edge_map_t + edge_map; // remember the properties set for each edge + + subgraph_nodes_t subgraph_nodes; // per-subgraph lists of nodes + subgraph_edges_t subgraph_edges; // per-subgraph lists of edges + + props_t default_node_props; // global default node properties + props_t default_edge_props; // global default edge properties + subgraph_props_t + subgraph_node_props; // per-subgraph default node properties + subgraph_props_t + subgraph_edge_props; // per-subgraph default edge properties + }; // struct definition + }; // struct dot_grammar + + // + // dot_skipper - GraphViz whitespace and comment skipper + // + struct dot_skipper + : public boost::spirit::classic::grammar< dot_skipper > + { + dot_skipper() {} + + template < typename ScannerT > struct definition + { + definition(dot_skipper const& /*self*/) + { + using namespace boost::spirit::classic; + using namespace phoenix; + // comment forms + skip = eol_p >> comment_p("#") | space_p | comment_p("//") #if BOOST_WORKAROUND(BOOST_MSVC, <= 1400) - | confix_p(str_p("/*") ,*anychar_p, str_p("*/")) + | confix_p(str_p("/*"), *anychar_p, str_p("*/")) #else - | confix_p("/*" ,*anychar_p, "*/") + | confix_p("/*", *anychar_p, "*/") #endif - ; + ; #ifdef BOOST_SPIRIT_DEBUG - BOOST_SPIRIT_DEBUG_RULE(skip); + BOOST_SPIRIT_DEBUG_RULE(skip); #endif - } + } - boost::spirit::classic::rule skip; - boost::spirit::classic::rule const& - start() const { return skip; } - }; // definition -}; // dot_skipper + boost::spirit::classic::rule< ScannerT > skip; + boost::spirit::classic::rule< ScannerT > const& start() const + { + return skip; + } + }; // definition + }; // dot_skipper -} // namespace graph + } // namespace graph } // namespace detail -template +template < typename MultiPassIterator, typename MutableGraph > bool read_graphviz_spirit(MultiPassIterator begin, MultiPassIterator end, - MutableGraph& graph, dynamic_properties& dp, - std::string const& node_id = "node_id") { - using namespace boost; - using namespace boost::spirit::classic; + MutableGraph& graph, dynamic_properties& dp, + std::string const& node_id = "node_id") +{ + using namespace boost; + using namespace boost::spirit::classic; - typedef MultiPassIterator iterator_t; - typedef skip_parser_iteration_policy< boost::detail::graph::dot_skipper> - iter_policy_t; - typedef scanner_policies scanner_policies_t; - typedef scanner scanner_t; + typedef MultiPassIterator iterator_t; + typedef skip_parser_iteration_policy< boost::detail::graph::dot_skipper > + iter_policy_t; + typedef scanner_policies< iter_policy_t > scanner_policies_t; + typedef scanner< iterator_t, scanner_policies_t > scanner_t; - ::boost::detail::graph::mutate_graph_impl - m_graph(graph, dp, node_id); + ::boost::detail::graph::mutate_graph_impl< MutableGraph > m_graph( + graph, dp, node_id); - ::boost::detail::graph::dot_grammar p(m_graph); - ::boost::detail::graph::dot_skipper skip_p; + ::boost::detail::graph::dot_grammar p(m_graph); + ::boost::detail::graph::dot_skipper skip_p; - iter_policy_t iter_policy(skip_p); - scanner_policies_t policies(iter_policy); + iter_policy_t iter_policy(skip_p); + scanner_policies_t policies(iter_policy); - scanner_t scan(begin, end, policies); + scanner_t scan(begin, end, policies); - bool ok = p.parse(scan); - m_graph.finish_building_graph(); - return ok; + bool ok = p.parse(scan); + m_graph.finish_building_graph(); + return ok; } } // namespace boost diff --git a/include/boost/graph/detail/self_avoiding_walk.hpp b/include/boost/graph/detail/self_avoiding_walk.hpp index c171897f2..52ad1cbb9 100644 --- a/include/boost/graph/detail/self_avoiding_walk.hpp +++ b/include/boost/graph/detail/self_avoiding_walk.hpp @@ -10,19 +10,19 @@ #define BOOST_SELF_AVOIDING_WALK_HPP /* - This file defines necessary components for SAW. + This file defines necessary components for SAW. mesh language: (defined by myself to clearify what is what) A triangle in mesh is called an triangle. - An edge in mesh is called an line. + An edge in mesh is called an line. A vertex in mesh is called a point. A triangular mesh corresponds to a graph in which a vertex is a - triangle and an edge(u, v) stands for triangle u and triangle v + triangle and an edge(u, v) stands for triangle u and triangle v share an line. After this point, a vertex always refers to vertex in graph, - therefore it is a traingle in mesh. + therefore it is a traingle in mesh. */ @@ -33,135 +33,161 @@ #define SAW_SENTINAL -1 -namespace boost { +namespace boost +{ - template - struct triple { +template < class T1, class T2, class T3 > struct triple +{ T1 first; T2 second; T3 third; - triple(const T1& a, const T2& b, const T3& c) : first(a), second(b), third(c) {} + triple(const T1& a, const T2& b, const T3& c) + : first(a), second(b), third(c) + { + } triple() : first(SAW_SENTINAL), second(SAW_SENTINAL), third(SAW_SENTINAL) {} - }; - - typedef triple Triple; - - /* Define a vertex property which has a triangle inside. Triangle is - represented by a triple. */ - struct triangle_tag { enum { num = 100 }; }; - typedef property triangle_property; - - /* Define an edge property with a line. A line is represented by a - pair. This is not required for SAW though. - */ - struct line_tag { enum { num = 101 }; }; - template struct line_property - : public property > { }; - - /*Precondition: Points in a Triangle are in order */ - template - inline void get_sharing(const Triangle& a, const Triangle& b, Line& l) - { +}; + +typedef triple< int, int, int > Triple; + +/* Define a vertex property which has a triangle inside. Triangle is + represented by a triple. */ +struct triangle_tag +{ + enum + { + num = 100 + }; +}; +typedef property< triangle_tag, Triple > triangle_property; + +/* Define an edge property with a line. A line is represented by a + pair. This is not required for SAW though. +*/ +struct line_tag +{ + enum + { + num = 101 + }; +}; +template < class T > +struct line_property : public property< line_tag, std::pair< T, T > > +{ +}; + +/*Precondition: Points in a Triangle are in order */ +template < class Triangle, class Line > +inline void get_sharing(const Triangle& a, const Triangle& b, Line& l) +{ l.first = SAW_SENTINAL; l.second = SAW_SENTINAL; - if ( a.first == b.first ) { - l.first = a.first; - if ( a.second == b.second || a.second == b.third ) - l.second = a.second; - else if ( a.third == b.second || a.third == b.third ) - l.second = a.third; - - } else if ( a.first == b.second ) { - l.first = a.first; - if ( a.second == b.third ) - l.second = a.second; - else if ( a.third == b.third ) - l.second = a.third; - - } else if ( a.first == b.third ) { - l.first = a.first; - - - } else if ( a.second == b.first ) { - l.first = a.second; - if ( a.third == b.second || a.third == b.third ) - l.second = a.third; - - } else if ( a.second == b.second ) { - l.first = a.second; - if ( a.third == b.third ) - l.second = a.third; - - } else if ( a.second == b.third ) { - l.first = a.second; - - - } else if ( a.third == b.first - || a.third == b.second - || a.third == b.third ) - l.first = a.third; + if (a.first == b.first) + { + l.first = a.first; + if (a.second == b.second || a.second == b.third) + l.second = a.second; + else if (a.third == b.second || a.third == b.third) + l.second = a.third; + } + else if (a.first == b.second) + { + l.first = a.first; + if (a.second == b.third) + l.second = a.second; + else if (a.third == b.third) + l.second = a.third; + } + else if (a.first == b.third) + { + l.first = a.first; + } + else if (a.second == b.first) + { + l.first = a.second; + if (a.third == b.second || a.third == b.third) + l.second = a.third; + } + else if (a.second == b.second) + { + l.first = a.second; + if (a.third == b.third) + l.second = a.third; + } + else if (a.second == b.third) + { + l.first = a.second; + } + else if (a.third == b.first || a.third == b.second || a.third == b.third) + l.first = a.third; /*Make it in order*/ - if ( l.first > l.second ) { - typename Line::first_type i = l.first; - l.first = l.second; - l.second = i; + if (l.first > l.second) + { + typename Line::first_type i = l.first; + l.first = l.second; + l.second = i; } +} - } - - template - struct get_vertex_sharing { - typedef std::pair Pair; +template < class TriangleDecorator, class Vertex, class Line > +struct get_vertex_sharing +{ + typedef std::pair< Vertex, Line > Pair; get_vertex_sharing(const TriangleDecorator& _td) : td(_td) {} - inline Line operator()(const Vertex& u, const Vertex& v) const { - Line l; - get_sharing(td[u], td[v], l); - return l; + inline Line operator()(const Vertex& u, const Vertex& v) const + { + Line l; + get_sharing(td[u], td[v], l); + return l; } - inline Line operator()(const Pair& u, const Vertex& v) const { - Line l; - get_sharing(td[u.first], td[v], l); - return l; + inline Line operator()(const Pair& u, const Vertex& v) const + { + Line l; + get_sharing(td[u.first], td[v], l); + return l; } - inline Line operator()(const Pair& u, const Pair& v) const { - Line l; - get_sharing(td[u.first], td[v.first], l); - return l; + inline Line operator()(const Pair& u, const Pair& v) const + { + Line l; + get_sharing(td[u.first], td[v.first], l); + return l; } TriangleDecorator td; - }; - - /* HList has to be a handle of data holder so that pass-by-value is - * in right logic. - * - * The element of HList is a pair of vertex and line. (remember a - * line is a pair of two ints.). That indicates the walk w from - * current vertex is across line. (If the first of line is -1, it is - * a point though. - */ - template < class TriangleDecorator, class HList, class IteratorD> - class SAW_visitor - : public bfs_visitor<>, public dfs_visitor<> - { - typedef typename boost::property_traits::value_type iter; +}; + +/* HList has to be a handle of data holder so that pass-by-value is + * in right logic. + * + * The element of HList is a pair of vertex and line. (remember a + * line is a pair of two ints.). That indicates the walk w from + * current vertex is across line. (If the first of line is -1, it is + * a point though. + */ +template < class TriangleDecorator, class HList, class IteratorD > +class SAW_visitor : public bfs_visitor<>, public dfs_visitor<> +{ + typedef typename boost::property_traits< IteratorD >::value_type iter; /*use boost shared_ptr*/ - typedef typename HList::element_type::value_type::second_type Line; - public: + typedef typename HList::element_type::value_type::second_type Line; +public: typedef tree_edge_tag category; inline SAW_visitor(TriangleDecorator _td, HList _hlist, IteratorD ia) - : td(_td), hlist(_hlist), iter_d(ia) {} - - template - inline void start_vertex(Vertex v, Graph&) { - Line l1; - l1.first = SAW_SENTINAL; - l1.second = SAW_SENTINAL; - hlist->push_front(std::make_pair(v, l1)); - iter_d[v] = hlist->begin(); + : td(_td), hlist(_hlist), iter_d(ia) + { + } + + template < class Vertex, class Graph > + inline void start_vertex(Vertex v, Graph&) + { + Line l1; + l1.first = SAW_SENTINAL; + l1.second = SAW_SENTINAL; + hlist->push_front(std::make_pair(v, l1)); + iter_d[v] = hlist->begin(); } /*Several symbols: @@ -171,248 +197,287 @@ namespace boost { w(i) -> w(i+1): w enter w(i+1) from w(i) w(i) ^ w(i+1): the line or point w go over from w(i) to w(i+1) */ - template - bool tree_edge(Edge e, Graph& G) { - using std::make_pair; - typedef typename boost::graph_traits::vertex_descriptor Vertex; - Vertex tau = target(e, G); - Vertex i = source(e, G); - - get_vertex_sharing get_sharing_line(td); - - Line tau_i = get_sharing_line(tau, i); - - iter w_end = hlist->end(); - - iter w_i = iter_d[i]; - - iter w_i_m_1 = w_i; - iter w_i_p_1 = w_i; - - /*---------------------------------------------------------- - * true false - *========================================================== - *a w(i-1) |- w(i) w(i-1) ~> w(i) or w(i-1) is null - *---------------------------------------------------------- - *b w(i) |- w(i+1) w(i) ~> w(i+1) or no w(i+1) yet - *---------------------------------------------------------- - */ - - bool a = false, b = false; - - --w_i_m_1; - ++w_i_p_1; - b = ( w_i->second.first != SAW_SENTINAL ); - - if ( w_i_m_1 != w_end ) { - a = ( w_i_m_1->second.first != SAW_SENTINAL ); - } - - if ( a ) { - - if ( b ) { - /*Case 1: - - w(i-1) |- w(i) |- w(i+1) - */ - Line l1 = get_sharing_line(*w_i_m_1, tau); - - iter w_i_m_2 = w_i_m_1; - --w_i_m_2; - - bool c = true; - - if ( w_i_m_2 != w_end ) { - c = w_i_m_2->second != l1; - } - - if ( c ) { /* w(i-1) ^ tau != w(i-2) ^ w(i-1) */ - /*extension: w(i-1) -> tau |- w(i) */ - w_i_m_1->second = l1; - /*insert(pos, const T&) is to insert before pos*/ - iter_d[tau] = hlist->insert(w_i, make_pair(tau, tau_i)); - - } else { /* w(i-1) ^ tau == w(i-2) ^ w(i-1) */ - /*must be w(i-2) ~> w(i-1) */ - - bool d = true; - //need to handle the case when w_i_p_1 is null - Line l3 = get_sharing_line(*w_i_p_1, tau); - if ( w_i_p_1 != w_end ) - d = w_i_p_1->second != l3; - if ( d ) { /* w(i+1) ^ tau != w(i+1) ^ w(i+2) */ - /*extension: w(i) |- tau -> w(i+1) */ - w_i->second = tau_i; - iter_d[tau] = hlist->insert(w_i_p_1, make_pair(tau, l3)); - } else { /* w(i+1) ^ tau == w(i+1) ^ w(i+2) */ - /*must be w(1+1) ~> w(i+2) */ - Line l5 = get_sharing_line(*w_i_m_1, *w_i_p_1); - if ( l5 != w_i_p_1->second ) { /* w(i-1) ^ w(i+1) != w(i+1) ^ w(i+2) */ - /*extension: w(i-2) -> tau |- w(i) |- w(i-1) -> w(i+1) */ - w_i_m_2->second = get_sharing_line(*w_i_m_2, tau); - iter_d[tau] = hlist->insert(w_i, make_pair(tau, tau_i)); - w_i->second = w_i_m_1->second; - w_i_m_1->second = l5; - iter_d[w_i_m_1->first] = hlist->insert(w_i_p_1, *w_i_m_1); - hlist->erase(w_i_m_1); - } else { - /*mesh is tetrahedral*/ - // dont know what that means. - ; - } + template < class Edge, class Graph > bool tree_edge(Edge e, Graph& G) + { + using std::make_pair; + typedef typename boost::graph_traits< Graph >::vertex_descriptor Vertex; + Vertex tau = target(e, G); + Vertex i = source(e, G); + + get_vertex_sharing< TriangleDecorator, Vertex, Line > get_sharing_line( + td); + + Line tau_i = get_sharing_line(tau, i); + + iter w_end = hlist->end(); + + iter w_i = iter_d[i]; + + iter w_i_m_1 = w_i; + iter w_i_p_1 = w_i; + + /*---------------------------------------------------------- + * true false + *========================================================== + *a w(i-1) |- w(i) w(i-1) ~> w(i) or w(i-1) is null + *---------------------------------------------------------- + *b w(i) |- w(i+1) w(i) ~> w(i+1) or no w(i+1) yet + *---------------------------------------------------------- + */ + + bool a = false, b = false; + + --w_i_m_1; + ++w_i_p_1; + b = (w_i->second.first != SAW_SENTINAL); + + if (w_i_m_1 != w_end) + { + a = (w_i_m_1->second.first != SAW_SENTINAL); + } + + if (a) + { + + if (b) + { + /*Case 1: + + w(i-1) |- w(i) |- w(i+1) + */ + Line l1 = get_sharing_line(*w_i_m_1, tau); + + iter w_i_m_2 = w_i_m_1; + --w_i_m_2; + + bool c = true; + + if (w_i_m_2 != w_end) + { + c = w_i_m_2->second != l1; + } + + if (c) + { /* w(i-1) ^ tau != w(i-2) ^ w(i-1) */ + /*extension: w(i-1) -> tau |- w(i) */ + w_i_m_1->second = l1; + /*insert(pos, const T&) is to insert before pos*/ + iter_d[tau] = hlist->insert(w_i, make_pair(tau, tau_i)); + } + else + { /* w(i-1) ^ tau == w(i-2) ^ w(i-1) */ + /*must be w(i-2) ~> w(i-1) */ + + bool d = true; + // need to handle the case when w_i_p_1 is null + Line l3 = get_sharing_line(*w_i_p_1, tau); + if (w_i_p_1 != w_end) + d = w_i_p_1->second != l3; + if (d) + { /* w(i+1) ^ tau != w(i+1) ^ w(i+2) */ + /*extension: w(i) |- tau -> w(i+1) */ + w_i->second = tau_i; + iter_d[tau] + = hlist->insert(w_i_p_1, make_pair(tau, l3)); + } + else + { /* w(i+1) ^ tau == w(i+1) ^ w(i+2) */ + /*must be w(1+1) ~> w(i+2) */ + Line l5 = get_sharing_line(*w_i_m_1, *w_i_p_1); + if (l5 != w_i_p_1->second) + { /* w(i-1) ^ w(i+1) != w(i+1) ^ w(i+2) */ + /*extension: w(i-2) -> tau |- w(i) |- w(i-1) -> + * w(i+1) */ + w_i_m_2->second = get_sharing_line(*w_i_m_2, tau); + iter_d[tau] + = hlist->insert(w_i, make_pair(tau, tau_i)); + w_i->second = w_i_m_1->second; + w_i_m_1->second = l5; + iter_d[w_i_m_1->first] + = hlist->insert(w_i_p_1, *w_i_m_1); + hlist->erase(w_i_m_1); + } + else + { + /*mesh is tetrahedral*/ + // dont know what that means. + ; + } + } + } } - - } - } else { - /*Case 2: - - w(i-1) |- w(i) ~> w(1+1) - */ - - if ( w_i->second.second == tau_i.first - || w_i->second.second == tau_i.second ) { /*w(i) ^ w(i+1) < w(i) ^ tau*/ - /*extension: w(i) |- tau -> w(i+1) */ - w_i->second = tau_i; - Line l1 = get_sharing_line(*w_i_p_1, tau); - iter_d[tau] = hlist->insert(w_i_p_1, make_pair(tau, l1)); - } else { /*w(i) ^ w(i+1) !< w(i) ^ tau*/ - Line l1 = get_sharing_line(*w_i_m_1, tau); - bool c = true; - iter w_i_m_2 = w_i_m_1; - --w_i_m_2; - if ( w_i_m_2 != w_end ) - c = l1 != w_i_m_2->second; - if (c) { /*w(i-1) ^ tau != w(i-2) ^ w(i-1)*/ - /*extension: w(i-1) -> tau |- w(i)*/ - w_i_m_1->second = l1; - iter_d[tau] = hlist->insert(w_i, make_pair(tau, tau_i)); - } else { /*w(i-1) ^ tau == w(i-2) ^ w(i-1)*/ - /*must be w(i-2)~>w(i-1)*/ - /*extension: w(i-2) -> tau |- w(i) |- w(i-1) -> w(i+1)*/ - w_i_m_2->second = get_sharing_line(*w_i_m_2, tau); - iter_d[tau] = hlist->insert(w_i, make_pair(tau, tau_i)); - w_i->second = w_i_m_1->second; - w_i_m_1->second = get_sharing_line(*w_i_m_1, *w_i_p_1); - iter_d[w_i_m_1->first] = hlist->insert(w_i_p_1, *w_i_m_1); - hlist->erase(w_i_m_1); + else + { + /*Case 2: + + w(i-1) |- w(i) ~> w(1+1) + */ + + if (w_i->second.second == tau_i.first + || w_i->second.second == tau_i.second) + { /*w(i) ^ w(i+1) < w(i) ^ tau*/ + /*extension: w(i) |- tau -> w(i+1) */ + w_i->second = tau_i; + Line l1 = get_sharing_line(*w_i_p_1, tau); + iter_d[tau] = hlist->insert(w_i_p_1, make_pair(tau, l1)); + } + else + { /*w(i) ^ w(i+1) !< w(i) ^ tau*/ + Line l1 = get_sharing_line(*w_i_m_1, tau); + bool c = true; + iter w_i_m_2 = w_i_m_1; + --w_i_m_2; + if (w_i_m_2 != w_end) + c = l1 != w_i_m_2->second; + if (c) + { /*w(i-1) ^ tau != w(i-2) ^ w(i-1)*/ + /*extension: w(i-1) -> tau |- w(i)*/ + w_i_m_1->second = l1; + iter_d[tau] = hlist->insert(w_i, make_pair(tau, tau_i)); + } + else + { /*w(i-1) ^ tau == w(i-2) ^ w(i-1)*/ + /*must be w(i-2)~>w(i-1)*/ + /*extension: w(i-2) -> tau |- w(i) |- w(i-1) -> w(i+1)*/ + w_i_m_2->second = get_sharing_line(*w_i_m_2, tau); + iter_d[tau] = hlist->insert(w_i, make_pair(tau, tau_i)); + w_i->second = w_i_m_1->second; + w_i_m_1->second = get_sharing_line(*w_i_m_1, *w_i_p_1); + iter_d[w_i_m_1->first] + = hlist->insert(w_i_p_1, *w_i_m_1); + hlist->erase(w_i_m_1); + } + } } - - } - } - - } else { - - if ( b ) { - /*Case 3: - - w(i-1) ~> w(i) |- w(i+1) - */ - bool c = false; - if ( w_i_m_1 != w_end ) - c = ( w_i_m_1->second.second == tau_i.first) - || ( w_i_m_1->second.second == tau_i.second); - - if ( c ) { /*w(i-1) ^ w(i) < w(i) ^ tau*/ - /* extension: w(i-1) -> tau |- w(i) */ - if ( w_i_m_1 != w_end ) - w_i_m_1->second = get_sharing_line(*w_i_m_1, tau); - iter_d[tau] = hlist->insert(w_i, make_pair(tau, tau_i)); - } else { - bool d = true; - Line l1; - l1.first = SAW_SENTINAL; - l1.second = SAW_SENTINAL; - if ( w_i_p_1 != w_end ) { - l1 = get_sharing_line(*w_i_p_1, tau); - d = l1 != w_i_p_1->second; + else + { + + if (b) + { + /*Case 3: + + w(i-1) ~> w(i) |- w(i+1) + */ + bool c = false; + if (w_i_m_1 != w_end) + c = (w_i_m_1->second.second == tau_i.first) + || (w_i_m_1->second.second == tau_i.second); + + if (c) + { /*w(i-1) ^ w(i) < w(i) ^ tau*/ + /* extension: w(i-1) -> tau |- w(i) */ + if (w_i_m_1 != w_end) + w_i_m_1->second = get_sharing_line(*w_i_m_1, tau); + iter_d[tau] = hlist->insert(w_i, make_pair(tau, tau_i)); + } + else + { + bool d = true; + Line l1; + l1.first = SAW_SENTINAL; + l1.second = SAW_SENTINAL; + if (w_i_p_1 != w_end) + { + l1 = get_sharing_line(*w_i_p_1, tau); + d = l1 != w_i_p_1->second; + } + if (d) + { /*w(i+1) ^ tau != w(i+1) ^ w(i+2)*/ + /*extension: w(i) |- tau -> w(i+1) */ + w_i->second = tau_i; + iter_d[tau] + = hlist->insert(w_i_p_1, make_pair(tau, l1)); + } + else + { + /*must be w(i+1) ~> w(i+2)*/ + /*extension: w(i-1) -> w(i+1) |- w(i) |- tau -> w(i+2) + */ + iter w_i_p_2 = w_i_p_1; + ++w_i_p_2; + + w_i_p_1->second = w_i->second; + iter_d[i] = hlist->insert(w_i_p_2, make_pair(i, tau_i)); + hlist->erase(w_i); + Line l2 = get_sharing_line(*w_i_p_2, tau); + iter_d[tau] + = hlist->insert(w_i_p_2, make_pair(tau, l2)); + } + } } - if (d) { /*w(i+1) ^ tau != w(i+1) ^ w(i+2)*/ - /*extension: w(i) |- tau -> w(i+1) */ - w_i->second = tau_i; - iter_d[tau] = hlist->insert(w_i_p_1, make_pair(tau, l1)); - } else { - /*must be w(i+1) ~> w(i+2)*/ - /*extension: w(i-1) -> w(i+1) |- w(i) |- tau -> w(i+2) */ - iter w_i_p_2 = w_i_p_1; - ++w_i_p_2; - - w_i_p_1->second = w_i->second; - iter_d[i] = hlist->insert(w_i_p_2, make_pair(i, tau_i)); - hlist->erase(w_i); - Line l2 = get_sharing_line(*w_i_p_2, tau); - iter_d[tau] = hlist->insert(w_i_p_2, make_pair(tau, l2)); + else + { + /*Case 4: + + w(i-1) ~> w(i) ~> w(i+1) + + */ + bool c = false; + if (w_i_m_1 != w_end) + { + c = (w_i_m_1->second.second == tau_i.first) + || (w_i_m_1->second.second == tau_i.second); + } + if (c) + { /*w(i-1) ^ w(i) < w(i) ^ tau */ + /*extension: w(i-1) -> tau |- w(i) */ + if (w_i_m_1 != w_end) + w_i_m_1->second = get_sharing_line(*w_i_m_1, tau); + iter_d[tau] = hlist->insert(w_i, make_pair(tau, tau_i)); + } + else + { + /*extension: w(i) |- tau -> w(i+1) */ + w_i->second = tau_i; + Line l1; + l1.first = SAW_SENTINAL; + l1.second = SAW_SENTINAL; + if (w_i_p_1 != w_end) + l1 = get_sharing_line(*w_i_p_1, tau); + iter_d[tau] = hlist->insert(w_i_p_1, make_pair(tau, l1)); + } } - } - - } else { - /*Case 4: - - w(i-1) ~> w(i) ~> w(i+1) - - */ - bool c = false; - if ( w_i_m_1 != w_end ) { - c = (w_i_m_1->second.second == tau_i.first) - || (w_i_m_1->second.second == tau_i.second); - } - if ( c ) { /*w(i-1) ^ w(i) < w(i) ^ tau */ - /*extension: w(i-1) -> tau |- w(i) */ - if ( w_i_m_1 != w_end ) - w_i_m_1->second = get_sharing_line(*w_i_m_1, tau); - iter_d[tau] = hlist->insert(w_i, make_pair(tau, tau_i)); - } else { - /*extension: w(i) |- tau -> w(i+1) */ - w_i->second = tau_i; - Line l1; - l1.first = SAW_SENTINAL; - l1.second = SAW_SENTINAL; - if ( w_i_p_1 != w_end ) - l1 = get_sharing_line(*w_i_p_1, tau); - iter_d[tau] = hlist->insert(w_i_p_1, make_pair(tau, l1)); - } } - - } - return true; + return true; } - - protected: + +protected: TriangleDecorator td; /*a decorator for vertex*/ - HList hlist; + HList hlist; /*This must be a handle of list to record the SAW The element type of the list is pair */ - - IteratorD iter_d; + + IteratorD iter_d; /*Problem statement: Need a fast access to w for triangle i. - *Possible solution: mantain an array to record. - iter_d[i] will return an iterator + *Possible solution: mantain an array to record. + iter_d[i] will return an iterator which points to w(i), where i is a vertex representing triangle i. */ - }; - - template - inline - SAW_visitor - visit_SAW(Triangle t, HList hl, Iterator i) { - return SAW_visitor(t, hl, i); - } - - template - inline - SAW_visitor< random_access_iterator_property_map, - HList, random_access_iterator_property_map > - visit_SAW_ptr(Tri* t, HList hl, Iter* i) { - typedef random_access_iterator_property_map TriD; - typedef random_access_iterator_property_map IterD; - return SAW_visitor(t, hl, i); - } - - // should also have combo's of pointers, and also const :( - +}; + +template < class Triangle, class HList, class Iterator > +inline SAW_visitor< Triangle, HList, Iterator > visit_SAW( + Triangle t, HList hl, Iterator i) +{ + return SAW_visitor< Triangle, HList, Iterator >(t, hl, i); +} + +template < class Tri, class HList, class Iter > +inline SAW_visitor< random_access_iterator_property_map< Tri*, Tri, Tri& >, + HList, random_access_iterator_property_map< Iter*, Iter, Iter& > > +visit_SAW_ptr(Tri* t, HList hl, Iter* i) +{ + typedef random_access_iterator_property_map< Tri*, Tri, Tri& > TriD; + typedef random_access_iterator_property_map< Iter*, Iter, Iter& > IterD; + return SAW_visitor< TriD, HList, IterD >(t, hl, i); +} + +// should also have combo's of pointers, and also const :( + } #endif /*BOOST_SAW_H*/ diff --git a/include/boost/graph/detail/set_adaptor.hpp b/include/boost/graph/detail/set_adaptor.hpp index 33acc07e3..487d3be2f 100644 --- a/include/boost/graph/detail/set_adaptor.hpp +++ b/include/boost/graph/detail/set_adaptor.hpp @@ -9,115 +9,110 @@ #include #include -namespace boost { +namespace boost +{ - template - bool set_contains(const std::set& s, const T& x) { - return s.find(x) != s.end(); - } - - template - bool set_contains(const boost::unordered_set& s, const T& x) { - return s.find(x) != s.end(); - } - - template - bool set_equal(const std::set& x, - const std::set& y) - { - return x == y; - } +template < class K, class C, class A, class T > +bool set_contains(const std::set< K, C, A >& s, const T& x) +{ + return s.find(x) != s.end(); +} + +template < class K, class H, class C, class A, class T > +bool set_contains(const boost::unordered_set< K, H, C, A >& s, const T& x) +{ + return s.find(x) != s.end(); +} + +template < class K, class C, class A > +bool set_equal(const std::set< K, C, A >& x, const std::set< K, C, A >& y) +{ + return x == y; +} - // Not the same as lexicographical_compare_3way applied to std::set. - // this is equivalent semantically to bitset::operator<() - template - int set_lex_order(const std::set& x, - const std::set& y) +// Not the same as lexicographical_compare_3way applied to std::set. +// this is equivalent semantically to bitset::operator<() +template < class K, class C, class A > +int set_lex_order(const std::set< K, C, A >& x, const std::set< K, C, A >& y) +{ + typename std::set< K, C, A >::iterator xi = x.begin(), yi = y.begin(), + xend = x.end(), yend = y.end(); + for (; xi != xend && yi != yend; ++xi, ++yi) { - typename std::set::iterator - xi = x.begin(), yi = y.begin(), xend = x.end(), yend = y.end(); - for (; xi != xend && yi != yend; ++xi, ++yi) { if (*xi < *yi) - return 1; + return 1; else if (*yi < *xi) - return -1; - } - if (xi == xend) + return -1; + } + if (xi == xend) return (yi == yend) ? 0 : -1; - else + else return 1; - } +} - template - void set_clear(std::set& x) { - x.clear(); - } +template < class K, class C, class A > void set_clear(std::set< K, C, A >& x) +{ + x.clear(); +} - template - bool set_empty(const std::set& x) { - return x.empty(); - } +template < class K, class C, class A > +bool set_empty(const std::set< K, C, A >& x) +{ + return x.empty(); +} - template - void set_insert(std::set& x, const T& a) { - x.insert(a); - } +template < class K, class C, class A, class T > +void set_insert(std::set< K, C, A >& x, const T& a) +{ + x.insert(a); +} - template - void set_remove(std::set& x, const T& a) { - x.erase(a); - } - - template - void set_intersect(const std::set& x, - const std::set& y, - std::set& z) - { - z.clear(); - std::set_intersection(x.begin(), x.end(), - y.begin(), y.end(), - std::inserter(z)); - } +template < class K, class C, class A, class T > +void set_remove(std::set< K, C, A >& x, const T& a) +{ + x.erase(a); +} - template - void set_union(const std::set& x, - const std::set& y, - std::set& z) - { - z.clear(); - std::set_union(x.begin(), x.end(), - y.begin(), y.end(), - std::inserter(z)); - } +template < class K, class C, class A > +void set_intersect(const std::set< K, C, A >& x, const std::set< K, C, A >& y, + std::set< K, C, A >& z) +{ + z.clear(); + std::set_intersection( + x.begin(), x.end(), y.begin(), y.end(), std::inserter(z)); +} - template - void set_difference(const std::set& x, - const std::set& y, - std::set& z) - { - z.clear(); - std::set_difference(x.begin(), x.end(), - y.begin(), y.end(), - std::inserter(z, z.begin())); - } +template < class K, class C, class A > +void set_union(const std::set< K, C, A >& x, const std::set< K, C, A >& y, + std::set< K, C, A >& z) +{ + z.clear(); + std::set_union(x.begin(), x.end(), y.begin(), y.end(), std::inserter(z)); +} - template - bool set_subset(const std::set& x, - const std::set& y) - { - return std::includes(x.begin(), x.end(), y.begin(), y.end()); - } +template < class K, class C, class A > +void set_difference(const std::set< K, C, A >& x, const std::set< K, C, A >& y, + std::set< K, C, A >& z) +{ + z.clear(); + std::set_difference( + x.begin(), x.end(), y.begin(), y.end(), std::inserter(z, z.begin())); +} - // Shit, can't implement this without knowing the size of the - // universe. - template - void set_compliment(const std::set& /*x*/, - std::set& z) - { - z.clear(); - - } - -} // namespace boost +template < class K, class C, class A > +bool set_subset(const std::set< K, C, A >& x, const std::set< K, C, A >& y) +{ + return std::includes(x.begin(), x.end(), y.begin(), y.end()); +} + +// Shit, can't implement this without knowing the size of the +// universe. +template < class K, class C, class A > +void set_compliment(const std::set< K, C, A >& /*x*/, std::set< K, C, A >& z) +{ + z.clear(); +} + +} // namespace boost #endif // BOOST_SET_ADAPTOR_HPP diff --git a/include/boost/graph/detail/shadow_iterator.hpp b/include/boost/graph/detail/shadow_iterator.hpp index 6cd15384f..060d13fcc 100644 --- a/include/boost/graph/detail/shadow_iterator.hpp +++ b/include/boost/graph/detail/shadow_iterator.hpp @@ -9,131 +9,175 @@ #include #include -namespace boost { +namespace boost +{ - namespace detail { +namespace detail +{ - template - class shadow_proxy - : boost::operators< shadow_proxy > + template < class A, class B, class D > + class shadow_proxy : boost::operators< shadow_proxy< A, B, D > > { - typedef shadow_proxy self; + typedef shadow_proxy self; + public: - inline shadow_proxy(A aa, B bb) : a(aa), b(bb) { } - inline shadow_proxy(const self& x) : a(x.a), b(x.b) { } - template - inline shadow_proxy(Self x) : a(x.a), b(x.b) { } - inline self& operator=(const self& x) { a = x.a; b = x.b; return *this; } - inline self& operator++() { ++a; return *this; } - inline self& operator--() { --a; return *this; } - inline self& operator+=(const self& x) { a += x.a; return *this; } - inline self& operator-=(const self& x) { a -= x.a; return *this; } - inline self& operator*=(const self& x) { a *= x.a; return *this; } - inline self& operator/=(const self& x) { a /= x.a; return *this; } - inline self& operator%=(const self& x) { return *this; } // JGS - inline self& operator&=(const self& x) { return *this; } // JGS - inline self& operator|=(const self& x) { return *this; } // JGS - inline self& operator^=(const self& x) { return *this; } // JGS - inline friend D operator-(const self& x, const self& y) { - return x.a - y.a; - } - inline bool operator==(const self& x) const { return a == x.a; } - inline bool operator<(const self& x) const { return a < x.a; } - // protected: - A a; - B b; + inline shadow_proxy(A aa, B bb) : a(aa), b(bb) {} + inline shadow_proxy(const self& x) : a(x.a), b(x.b) {} + template < class Self > inline shadow_proxy(Self x) : a(x.a), b(x.b) {} + inline self& operator=(const self& x) + { + a = x.a; + b = x.b; + return *this; + } + inline self& operator++() + { + ++a; + return *this; + } + inline self& operator--() + { + --a; + return *this; + } + inline self& operator+=(const self& x) + { + a += x.a; + return *this; + } + inline self& operator-=(const self& x) + { + a -= x.a; + return *this; + } + inline self& operator*=(const self& x) + { + a *= x.a; + return *this; + } + inline self& operator/=(const self& x) + { + a /= x.a; + return *this; + } + inline self& operator%=(const self& x) { return *this; } // JGS + inline self& operator&=(const self& x) { return *this; } // JGS + inline self& operator|=(const self& x) { return *this; } // JGS + inline self& operator^=(const self& x) { return *this; } // JGS + inline friend D operator-(const self& x, const self& y) + { + return x.a - y.a; + } + inline bool operator==(const self& x) const { return a == x.a; } + inline bool operator<(const self& x) const { return a < x.a; } + // protected: + A a; + B b; }; struct shadow_iterator_policies { - template - void initialize(const iter_pair&) { } - - template - typename Iter::reference dereference(const Iter& i) const { - typedef typename Iter::reference R; - return R(*i.base().first, *i.base().second); - } - template - bool equal(const Iter& p1, const Iter& p2) const { - return p1.base().first == p2.base().first; - } - template - void increment(Iter& i) { ++i.base().first; ++i.base().second; } - - template - void decrement(Iter& i) { --i.base().first; --i.base().second; } - - template - bool less(const Iter& x, const Iter& y) const { - return x.base().first < y.base().first; - } - template - typename Iter::difference_type - distance(const Iter& x, const Iter& y) const { - return y.base().first - x.base().first; - } - template - void advance(Iter& p, D n) { p.base().first += n; p.base().second += n; } + template < typename iter_pair > void initialize(const iter_pair&) {} + + template < typename Iter > + typename Iter::reference dereference(const Iter& i) const + { + typedef typename Iter::reference R; + return R(*i.base().first, *i.base().second); + } + template < typename Iter > + bool equal(const Iter& p1, const Iter& p2) const + { + return p1.base().first == p2.base().first; + } + template < typename Iter > void increment(Iter& i) + { + ++i.base().first; + ++i.base().second; + } + + template < typename Iter > void decrement(Iter& i) + { + --i.base().first; + --i.base().second; + } + + template < typename Iter > bool less(const Iter& x, const Iter& y) const + { + return x.base().first < y.base().first; + } + template < typename Iter > + typename Iter::difference_type distance( + const Iter& x, const Iter& y) const + { + return y.base().first - x.base().first; + } + template < typename D, typename Iter > void advance(Iter& p, D n) + { + p.base().first += n; + p.base().second += n; + } }; - } // namespace detail +} // namespace detail + +template < typename IterA, typename IterB > struct shadow_iterator_generator +{ - template - struct shadow_iterator_generator { - // To use the iterator_adaptor we can't derive from // random_access_iterator because we don't have a real reference. // However, we want the STL algorithms to treat the shadow // iterator like a random access iterator. - struct shadow_iterator_tag : public std::input_iterator_tag { - operator std::random_access_iterator_tag() { - return std::random_access_iterator_tag(); - }; + struct shadow_iterator_tag : public std::input_iterator_tag + { + operator std::random_access_iterator_tag() + { + return std::random_access_iterator_tag(); + }; }; - typedef typename std::iterator_traits::value_type Aval; - typedef typename std::iterator_traits::value_type Bval; - typedef typename std::iterator_traits::reference Aref; - typedef typename std::iterator_traits::reference Bref; - typedef typename std::iterator_traits::difference_type D; - typedef detail::shadow_proxy V; - typedef detail::shadow_proxy R; - typedef iterator_adaptor< std::pair, - detail::shadow_iterator_policies, - V, R, V*, shadow_iterator_tag, - D> type; - }; - - // short cut for creating a shadow iterator - template - inline typename shadow_iterator_generator::type - make_shadow_iter(IterA a, IterB b) { - typedef typename shadow_iterator_generator::type Iter; - return Iter(std::make_pair(a,b)); - } - - template - struct shadow_cmp { - inline shadow_cmp(const Cmp& c) : cmp(c) { } - template + typedef typename std::iterator_traits< IterA >::value_type Aval; + typedef typename std::iterator_traits< IterB >::value_type Bval; + typedef typename std::iterator_traits< IterA >::reference Aref; + typedef typename std::iterator_traits< IterB >::reference Bref; + typedef typename std::iterator_traits< IterA >::difference_type D; + typedef detail::shadow_proxy< Aval, Bval, Aval > V; + typedef detail::shadow_proxy< Aref, Bref, Aval > R; + typedef iterator_adaptor< std::pair< IterA, IterB >, + detail::shadow_iterator_policies, V, R, V*, shadow_iterator_tag, D > + type; +}; + +// short cut for creating a shadow iterator +template < class IterA, class IterB > +inline typename shadow_iterator_generator< IterA, IterB >::type +make_shadow_iter(IterA a, IterB b) +{ + typedef typename shadow_iterator_generator< IterA, IterB >::type Iter; + return Iter(std::make_pair(a, b)); +} + +template < class Cmp > struct shadow_cmp +{ + inline shadow_cmp(const Cmp& c) : cmp(c) {} + template < class ShadowProxy1, class ShadowProxy2 > inline bool operator()(const ShadowProxy1& x, const ShadowProxy2& y) const { - return cmp(x.a, y.a); + return cmp(x.a, y.a); } Cmp cmp; - }; +}; } // namespace boost -namespace std { - template - void swap(boost::detail::shadow_proxy x, - boost::detail::shadow_proxy y) - { +namespace std +{ +template < class A1, class B1, class D1, class A2, class B2, class D2 > +void swap(boost::detail::shadow_proxy< A1&, B1&, D1 > x, + boost::detail::shadow_proxy< A2&, B2&, D2 > y) +{ std::swap(x.a, y.a); std::swap(x.b, y.b); - } +} } #endif // BOOST_SHADOW_ITERATOR_HPP diff --git a/include/boost/graph/detail/sparse_ordering.hpp b/include/boost/graph/detail/sparse_ordering.hpp index 7a7350e6f..1b1e1eb65 100644 --- a/include/boost/graph/detail/sparse_ordering.hpp +++ b/include/boost/graph/detail/sparse_ordering.hpp @@ -25,9 +25,11 @@ #include #include -namespace boost { +namespace boost +{ - namespace sparse { +namespace sparse +{ // rcm_queue // @@ -35,164 +37,175 @@ namespace boost { // *_ordering algorithms. // In addition to the normal queue operations, the // rcm_queue provides: - // + // // int eccentricity() const; // value_type spouse() const; - // + // // yes, it's a bad name...but it works, so use it template < class Vertex, class DegreeMap, - class Container = std::deque > - class rcm_queue : public std::queue { - typedef std::queue base; + class Container = std::deque< Vertex > > + class rcm_queue : public std::queue< Vertex, Container > + { + typedef std::queue< Vertex > base; + public: - typedef typename base::value_type value_type; - typedef typename base::size_type size_type; - - /* SGI queue has not had a contructor queue(const Container&) */ - inline rcm_queue(DegreeMap deg) - : _size(0), Qsize(1), eccen(-1), degree(deg) { } - - inline void pop() { - if ( !_size ) - Qsize = base::size(); - - base::pop(); - if ( _size == Qsize-1 ) { - _size = 0; - ++eccen; - } else - ++_size; - - } - - inline value_type& front() { - value_type& u = base::front(); - if ( _size == 0 ) - w = u; - else if (get(degree,u) < get(degree,w) ) - w = u; - return u; - } - - inline const value_type& front() const { - const value_type& u = base::front(); - if ( _size == 0 ) - w = u; - else if (get(degree,u) < get(degree,w) ) - w = u; - return u; - } - - inline value_type& top() { return front(); } - inline const value_type& top() const { return front(); } - - inline size_type size() const { return base::size(); } - - inline size_type eccentricity() const { return eccen; } - inline value_type spouse() const { return w; } + typedef typename base::value_type value_type; + typedef typename base::size_type size_type; + + /* SGI queue has not had a contructor queue(const Container&) */ + inline rcm_queue(DegreeMap deg) + : _size(0), Qsize(1), eccen(-1), degree(deg) + { + } + + inline void pop() + { + if (!_size) + Qsize = base::size(); + + base::pop(); + if (_size == Qsize - 1) + { + _size = 0; + ++eccen; + } + else + ++_size; + } + + inline value_type& front() + { + value_type& u = base::front(); + if (_size == 0) + w = u; + else if (get(degree, u) < get(degree, w)) + w = u; + return u; + } + + inline const value_type& front() const + { + const value_type& u = base::front(); + if (_size == 0) + w = u; + else if (get(degree, u) < get(degree, w)) + w = u; + return u; + } + + inline value_type& top() { return front(); } + inline const value_type& top() const { return front(); } + + inline size_type size() const { return base::size(); } + + inline size_type eccentricity() const { return eccen; } + inline value_type spouse() const { return w; } protected: - size_type _size; - size_type Qsize; - int eccen; - mutable value_type w; - DegreeMap degree; + size_type _size; + size_type Qsize; + int eccen; + mutable value_type w; + DegreeMap degree; }; + template < typename Tp, typename Sequence = std::deque< Tp > > + class sparse_ordering_queue : public boost::queue< Tp, Sequence > + { + public: + typedef typename Sequence::iterator iterator; + typedef typename Sequence::reverse_iterator reverse_iterator; + typedef queue< Tp, Sequence > base; + typedef typename Sequence::size_type size_type; + + inline iterator begin() { return this->c.begin(); } + inline reverse_iterator rbegin() { return this->c.rbegin(); } + inline iterator end() { return this->c.end(); } + inline reverse_iterator rend() { return this->c.rend(); } + inline Tp& operator[](int n) { return this->c[n]; } + inline size_type size() { return this->c.size(); } - template > - class sparse_ordering_queue : public boost::queue{ - public: - typedef typename Sequence::iterator iterator; - typedef typename Sequence::reverse_iterator reverse_iterator; - typedef queue base; - typedef typename Sequence::size_type size_type; - - inline iterator begin() { return this->c.begin(); } - inline reverse_iterator rbegin() { return this->c.rbegin(); } - inline iterator end() { return this->c.end(); } - inline reverse_iterator rend() { return this->c.rend(); } - inline Tp &operator[](int n) { return this->c[n]; } - inline size_type size() {return this->c.size(); } protected: - //nothing + // nothing }; - - } // namespace sparse - - // Compute Pseudo peripheral - // - // To compute an approximated peripheral for a given vertex. - // Used in king_ordering algorithm. - // - template - Vertex - pseudo_peripheral_pair(Graph const& G, const Vertex& u, int& ecc, - ColorMap color, DegreeMap degree) - { - typedef typename property_traits::value_type ColorValue; - typedef color_traits Color; - - sparse::rcm_queue Q(degree); - - typename boost::graph_traits::vertex_iterator ui, ui_end; + +} // namespace sparse + +// Compute Pseudo peripheral +// +// To compute an approximated peripheral for a given vertex. +// Used in king_ordering algorithm. +// +template < class Graph, class Vertex, class ColorMap, class DegreeMap > +Vertex pseudo_peripheral_pair( + Graph const& G, const Vertex& u, int& ecc, ColorMap color, DegreeMap degree) +{ + typedef typename property_traits< ColorMap >::value_type ColorValue; + typedef color_traits< ColorValue > Color; + + sparse::rcm_queue< Vertex, DegreeMap > Q(degree); + + typename boost::graph_traits< Graph >::vertex_iterator ui, ui_end; for (boost::tie(ui, ui_end) = vertices(G); ui != ui_end; ++ui) - if (get(color, *ui) != Color::red()) put(color, *ui, Color::white()); + if (get(color, *ui) != Color::red()) + put(color, *ui, Color::white()); breadth_first_visit(G, u, buffer(Q).color_map(color)); - ecc = Q.eccentricity(); + ecc = Q.eccentricity(); return Q.spouse(); - } - - // Find a good starting node - // - // This is to find a good starting node for the - // king_ordering algorithm. "good" is in the sense - // of the ordering generated by RCM. - // - template - Vertex find_starting_node(Graph const& G, Vertex r, Color color, Degree degree) - { +} + +// Find a good starting node +// +// This is to find a good starting node for the +// king_ordering algorithm. "good" is in the sense +// of the ordering generated by RCM. +// +template < class Graph, class Vertex, class Color, class Degree > +Vertex find_starting_node(Graph const& G, Vertex r, Color color, Degree degree) +{ Vertex x, y; int eccen_r, eccen_x; x = pseudo_peripheral_pair(G, r, eccen_r, color, degree); y = pseudo_peripheral_pair(G, x, eccen_x, color, degree); - while (eccen_x > eccen_r) { - r = x; - eccen_r = eccen_x; - x = y; - y = pseudo_peripheral_pair(G, x, eccen_x, color, degree); + while (eccen_x > eccen_r) + { + r = x; + eccen_r = eccen_x; + x = y; + y = pseudo_peripheral_pair(G, x, eccen_x, color, degree); } return x; - } +} -template -class out_degree_property_map - : public put_get_helper::degree_size_type, - out_degree_property_map > +template < typename Graph > +class out_degree_property_map +: public put_get_helper< typename graph_traits< Graph >::degree_size_type, + out_degree_property_map< Graph > > { public: - typedef typename graph_traits::vertex_descriptor key_type; - typedef typename graph_traits::degree_size_type value_type; - typedef value_type reference; - typedef readable_property_map_tag category; - out_degree_property_map(const Graph& g) : m_g(g) { } - value_type operator[](const key_type& v) const { - return out_degree(v, m_g); - } + typedef typename graph_traits< Graph >::vertex_descriptor key_type; + typedef typename graph_traits< Graph >::degree_size_type value_type; + typedef value_type reference; + typedef readable_property_map_tag category; + out_degree_property_map(const Graph& g) : m_g(g) {} + value_type operator[](const key_type& v) const + { + return out_degree(v, m_g); + } + private: - const Graph& m_g; + const Graph& m_g; }; -template -inline out_degree_property_map -make_out_degree_map(const Graph& g) { - return out_degree_property_map(g); +template < typename Graph > +inline out_degree_property_map< Graph > make_out_degree_map(const Graph& g) +{ + return out_degree_property_map< Graph >(g); } } // namespace boost - #endif // BOOST_GRAPH_KING_HPP diff --git a/include/boost/graph/dijkstra_shortest_paths.hpp b/include/boost/graph/dijkstra_shortest_paths.hpp index f4a2a2474..535408348 100644 --- a/include/boost/graph/dijkstra_shortest_paths.hpp +++ b/include/boost/graph/dijkstra_shortest_paths.hpp @@ -33,565 +33,548 @@ #include #ifdef BOOST_GRAPH_DIJKSTRA_TESTING -# include +#include #endif // BOOST_GRAPH_DIJKSTRA_TESTING -namespace boost { - - /** - * @brief Updates a particular value in a queue used by Dijkstra's - * algorithm. - * - * This routine is called by Dijkstra's algorithm after it has - * decreased the distance from the source vertex to the given @p - * vertex. By default, this routine will just call @c - * Q.update(vertex). However, other queues may provide more - * specialized versions of this routine. - * - * @param Q the queue that will be updated. - * @param vertex the vertex whose distance has been updated - * @param old_distance the previous distance to @p vertex - */ - template - inline void - dijkstra_queue_update(Buffer& Q, Vertex vertex, DistanceType old_distance) - { +namespace boost +{ + +/** + * @brief Updates a particular value in a queue used by Dijkstra's + * algorithm. + * + * This routine is called by Dijkstra's algorithm after it has + * decreased the distance from the source vertex to the given @p + * vertex. By default, this routine will just call @c + * Q.update(vertex). However, other queues may provide more + * specialized versions of this routine. + * + * @param Q the queue that will be updated. + * @param vertex the vertex whose distance has been updated + * @param old_distance the previous distance to @p vertex + */ +template < typename Buffer, typename Vertex, typename DistanceType > +inline void dijkstra_queue_update( + Buffer& Q, Vertex vertex, DistanceType old_distance) +{ (void)old_distance; Q.update(vertex); - } - - - template - struct DijkstraVisitorConcept { - void constraints() { - BOOST_CONCEPT_ASSERT(( CopyConstructibleConcept )); - vis.initialize_vertex(u, g); - vis.discover_vertex(u, g); - vis.examine_vertex(u, g); - vis.examine_edge(e, g); - vis.edge_relaxed(e, g); - vis.edge_not_relaxed(e, g); - vis.finish_vertex(u, g); +} + +template < class Visitor, class Graph > struct DijkstraVisitorConcept +{ + void constraints() + { + BOOST_CONCEPT_ASSERT((CopyConstructibleConcept< Visitor >)); + vis.initialize_vertex(u, g); + vis.discover_vertex(u, g); + vis.examine_vertex(u, g); + vis.examine_edge(e, g); + vis.edge_relaxed(e, g); + vis.edge_not_relaxed(e, g); + vis.finish_vertex(u, g); } Visitor vis; Graph g; - typename graph_traits::vertex_descriptor u; - typename graph_traits::edge_descriptor e; - }; - - template - class dijkstra_visitor : public bfs_visitor { - public: - dijkstra_visitor() { } - dijkstra_visitor(Visitors vis) - : bfs_visitor(vis) { } - - template - void edge_relaxed(Edge e, Graph& g) { - invoke_visitors(this->m_vis, e, g, on_edge_relaxed()); + typename graph_traits< Graph >::vertex_descriptor u; + typename graph_traits< Graph >::edge_descriptor e; +}; + +template < class Visitors = null_visitor > +class dijkstra_visitor : public bfs_visitor< Visitors > +{ +public: + dijkstra_visitor() {} + dijkstra_visitor(Visitors vis) : bfs_visitor< Visitors >(vis) {} + + template < class Edge, class Graph > void edge_relaxed(Edge e, Graph& g) + { + invoke_visitors(this->m_vis, e, g, on_edge_relaxed()); } - template - void edge_not_relaxed(Edge e, Graph& g) { - invoke_visitors(this->m_vis, e, g, on_edge_not_relaxed()); + template < class Edge, class Graph > void edge_not_relaxed(Edge e, Graph& g) + { + invoke_visitors(this->m_vis, e, g, on_edge_not_relaxed()); } - private: - template - void tree_edge(Edge u, Graph& g) { } - }; - template - dijkstra_visitor - make_dijkstra_visitor(Visitors vis) { - return dijkstra_visitor(vis); - } - typedef dijkstra_visitor<> default_dijkstra_visitor; - - namespace detail { - - template + +private: + template < class Edge, class Graph > void tree_edge(Edge u, Graph& g) {} +}; +template < class Visitors > +dijkstra_visitor< Visitors > make_dijkstra_visitor(Visitors vis) +{ + return dijkstra_visitor< Visitors >(vis); +} +typedef dijkstra_visitor<> default_dijkstra_visitor; + +namespace detail +{ + + template < class UniformCostVisitor, class UpdatableQueue, class WeightMap, + class PredecessorMap, class DistanceMap, class BinaryFunction, + class BinaryPredicate > struct dijkstra_bfs_visitor { - typedef typename property_traits::value_type D; - typedef typename property_traits::value_type W; - - dijkstra_bfs_visitor(UniformCostVisitor vis, UpdatableQueue& Q, - WeightMap w, PredecessorMap p, DistanceMap d, - BinaryFunction combine, BinaryPredicate compare, - D zero) - : m_vis(vis), m_Q(Q), m_weight(w), m_predecessor(p), m_distance(d), - m_combine(combine), m_compare(compare), m_zero(zero) { } - - template - void tree_edge(Edge e, Graph& g) { - bool decreased = relax_target(e, g, m_weight, m_predecessor, m_distance, - m_combine, m_compare); - if (decreased) - m_vis.edge_relaxed(e, g); - else - m_vis.edge_not_relaxed(e, g); - } - template - void gray_target(Edge e, Graph& g) { - D old_distance = get(m_distance, target(e, g)); - - bool decreased = relax_target(e, g, m_weight, m_predecessor, m_distance, - m_combine, m_compare); - if (decreased) { - dijkstra_queue_update(m_Q, target(e, g), old_distance); - m_vis.edge_relaxed(e, g); - } else - m_vis.edge_not_relaxed(e, g); - } - - template - void initialize_vertex(Vertex u, Graph& g) - { m_vis.initialize_vertex(u, g); } - template - void non_tree_edge(Edge, Graph&) { } - template - void discover_vertex(Vertex u, Graph& g) { m_vis.discover_vertex(u, g); } - template - void examine_vertex(Vertex u, Graph& g) { m_vis.examine_vertex(u, g); } - template - void examine_edge(Edge e, Graph& g) { - // Test for negative-weight edges: - // - // Reasons that other comparisons do not work: - // - // m_compare(e_weight, D(0)): - // m_compare only needs to work on distances, not weights, and those - // types do not need to be the same (bug 8398, - // https://svn.boost.org/trac/boost/ticket/8398). - // m_compare(m_combine(source_dist, e_weight), source_dist): - // if m_combine is project2nd (as in prim_minimum_spanning_tree), - // this test will claim that the edge weight is negative whenever - // the edge weight is less than source_dist, even if both of those - // are positive (bug 9012, - // https://svn.boost.org/trac/boost/ticket/9012). - // m_compare(m_combine(e_weight, source_dist), source_dist): - // would fix project2nd issue, but documentation only requires that - // m_combine be able to take a distance and a weight (in that order) - // and return a distance. - - // W e_weight = get(m_weight, e); - // sd_plus_ew = source_dist + e_weight. - // D sd_plus_ew = m_combine(source_dist, e_weight); - // sd_plus_2ew = source_dist + 2 * e_weight. - // D sd_plus_2ew = m_combine(sd_plus_ew, e_weight); - // The test here is equivalent to e_weight < 0 if m_combine has a - // cancellation law, but always returns false when m_combine is a - // projection operator. - if (m_compare(m_combine(m_zero, get(m_weight, e)), m_zero)) - boost::throw_exception(negative_edge()); - // End of test for negative-weight edges. - - m_vis.examine_edge(e, g); - - } - template - void black_target(Edge, Graph&) { } - template - void finish_vertex(Vertex u, Graph& g) { m_vis.finish_vertex(u, g); } - - UniformCostVisitor m_vis; - UpdatableQueue& m_Q; - WeightMap m_weight; - PredecessorMap m_predecessor; - DistanceMap m_distance; - BinaryFunction m_combine; - BinaryPredicate m_compare; - D m_zero; + typedef typename property_traits< DistanceMap >::value_type D; + typedef typename property_traits< WeightMap >::value_type W; + + dijkstra_bfs_visitor(UniformCostVisitor vis, UpdatableQueue& Q, + WeightMap w, PredecessorMap p, DistanceMap d, + BinaryFunction combine, BinaryPredicate compare, D zero) + : m_vis(vis) + , m_Q(Q) + , m_weight(w) + , m_predecessor(p) + , m_distance(d) + , m_combine(combine) + , m_compare(compare) + , m_zero(zero) + { + } + + template < class Edge, class Graph > void tree_edge(Edge e, Graph& g) + { + bool decreased = relax_target(e, g, m_weight, m_predecessor, + m_distance, m_combine, m_compare); + if (decreased) + m_vis.edge_relaxed(e, g); + else + m_vis.edge_not_relaxed(e, g); + } + template < class Edge, class Graph > void gray_target(Edge e, Graph& g) + { + D old_distance = get(m_distance, target(e, g)); + + bool decreased = relax_target(e, g, m_weight, m_predecessor, + m_distance, m_combine, m_compare); + if (decreased) + { + dijkstra_queue_update(m_Q, target(e, g), old_distance); + m_vis.edge_relaxed(e, g); + } + else + m_vis.edge_not_relaxed(e, g); + } + + template < class Vertex, class Graph > + void initialize_vertex(Vertex u, Graph& g) + { + m_vis.initialize_vertex(u, g); + } + template < class Edge, class Graph > void non_tree_edge(Edge, Graph&) {} + template < class Vertex, class Graph > + void discover_vertex(Vertex u, Graph& g) + { + m_vis.discover_vertex(u, g); + } + template < class Vertex, class Graph > + void examine_vertex(Vertex u, Graph& g) + { + m_vis.examine_vertex(u, g); + } + template < class Edge, class Graph > void examine_edge(Edge e, Graph& g) + { + // Test for negative-weight edges: + // + // Reasons that other comparisons do not work: + // + // m_compare(e_weight, D(0)): + // m_compare only needs to work on distances, not weights, and + // those types do not need to be the same (bug 8398, + // https://svn.boost.org/trac/boost/ticket/8398). + // m_compare(m_combine(source_dist, e_weight), source_dist): + // if m_combine is project2nd (as in prim_minimum_spanning_tree), + // this test will claim that the edge weight is negative whenever + // the edge weight is less than source_dist, even if both of + // those are positive (bug 9012, + // https://svn.boost.org/trac/boost/ticket/9012). + // m_compare(m_combine(e_weight, source_dist), source_dist): + // would fix project2nd issue, but documentation only requires + // that m_combine be able to take a distance and a weight (in + // that order) and return a distance. + + // W e_weight = get(m_weight, e); + // sd_plus_ew = source_dist + e_weight. + // D sd_plus_ew = m_combine(source_dist, e_weight); + // sd_plus_2ew = source_dist + 2 * e_weight. + // D sd_plus_2ew = m_combine(sd_plus_ew, e_weight); + // The test here is equivalent to e_weight < 0 if m_combine has a + // cancellation law, but always returns false when m_combine is a + // projection operator. + if (m_compare(m_combine(m_zero, get(m_weight, e)), m_zero)) + boost::throw_exception(negative_edge()); + // End of test for negative-weight edges. + + m_vis.examine_edge(e, g); + } + template < class Edge, class Graph > void black_target(Edge, Graph&) {} + template < class Vertex, class Graph > + void finish_vertex(Vertex u, Graph& g) + { + m_vis.finish_vertex(u, g); + } + + UniformCostVisitor m_vis; + UpdatableQueue& m_Q; + WeightMap m_weight; + PredecessorMap m_predecessor; + DistanceMap m_distance; + BinaryFunction m_combine; + BinaryPredicate m_compare; + D m_zero; }; - } // namespace detail +} // namespace detail - namespace detail { - template - struct vertex_property_map_generator_helper {}; +namespace detail +{ + template < class Graph, class IndexMap, class Value, bool KnownNumVertices > + struct vertex_property_map_generator_helper + { + }; - template - struct vertex_property_map_generator_helper { - typedef boost::iterator_property_map type; - static type build(const Graph& g, const IndexMap& index, boost::scoped_array& array_holder) { - array_holder.reset(new Value[num_vertices(g)]); - std::fill(array_holder.get(), array_holder.get() + num_vertices(g), Value()); - return make_iterator_property_map(array_holder.get(), index); - } + template < class Graph, class IndexMap, class Value > + struct vertex_property_map_generator_helper< Graph, IndexMap, Value, true > + { + typedef boost::iterator_property_map< Value*, IndexMap > type; + static type build(const Graph& g, const IndexMap& index, + boost::scoped_array< Value >& array_holder) + { + array_holder.reset(new Value[num_vertices(g)]); + std::fill(array_holder.get(), array_holder.get() + num_vertices(g), + Value()); + return make_iterator_property_map(array_holder.get(), index); + } }; - template - struct vertex_property_map_generator_helper { - typedef boost::vector_property_map type; - static type build(const Graph& g, const IndexMap& index, boost::scoped_array& array_holder) { - return boost::make_vector_property_map(index); - } + template < class Graph, class IndexMap, class Value > + struct vertex_property_map_generator_helper< Graph, IndexMap, Value, false > + { + typedef boost::vector_property_map< Value, IndexMap > type; + static type build(const Graph& g, const IndexMap& index, + boost::scoped_array< Value >& array_holder) + { + return boost::make_vector_property_map< Value >(index); + } }; - template - struct vertex_property_map_generator { - typedef boost::is_base_and_derived< - boost::vertex_list_graph_tag, - typename boost::graph_traits::traversal_category> - known_num_vertices; - typedef vertex_property_map_generator_helper helper; - typedef typename helper::type type; - static type build(const Graph& g, const IndexMap& index, boost::scoped_array& array_holder) { - return helper::build(g, index, array_holder); - } + template < class Graph, class IndexMap, class Value > + struct vertex_property_map_generator + { + typedef boost::is_base_and_derived< boost::vertex_list_graph_tag, + typename boost::graph_traits< Graph >::traversal_category > + known_num_vertices; + typedef vertex_property_map_generator_helper< Graph, IndexMap, Value, + known_num_vertices::value > + helper; + typedef typename helper::type type; + static type build(const Graph& g, const IndexMap& index, + boost::scoped_array< Value >& array_holder) + { + return helper::build(g, index, array_holder); + } }; - } - - namespace detail { - template - struct default_color_map_generator_helper {}; - - template - struct default_color_map_generator_helper { - typedef boost::two_bit_color_map type; - static type build(const Graph& g, const IndexMap& index) { - size_t nv = num_vertices(g); - return boost::two_bit_color_map(nv, index); - } +} + +namespace detail +{ + template < class Graph, class IndexMap, bool KnownNumVertices > + struct default_color_map_generator_helper + { }; - template - struct default_color_map_generator_helper { - typedef boost::vector_property_map type; - static type build(const Graph& g, const IndexMap& index) { - return boost::make_vector_property_map(index); - } + template < class Graph, class IndexMap > + struct default_color_map_generator_helper< Graph, IndexMap, true > + { + typedef boost::two_bit_color_map< IndexMap > type; + static type build(const Graph& g, const IndexMap& index) + { + size_t nv = num_vertices(g); + return boost::two_bit_color_map< IndexMap >(nv, index); + } + }; + + template < class Graph, class IndexMap > + struct default_color_map_generator_helper< Graph, IndexMap, false > + { + typedef boost::vector_property_map< boost::two_bit_color_type, + IndexMap > + type; + static type build(const Graph& g, const IndexMap& index) + { + return boost::make_vector_property_map< boost::two_bit_color_type >( + index); + } }; - template - struct default_color_map_generator { - typedef boost::is_base_and_derived< - boost::vertex_list_graph_tag, - typename boost::graph_traits::traversal_category> - known_num_vertices; - typedef default_color_map_generator_helper helper; - typedef typename helper::type type; - static type build(const Graph& g, const IndexMap& index) { - return helper::build(g, index); - } + template < class Graph, class IndexMap > struct default_color_map_generator + { + typedef boost::is_base_and_derived< boost::vertex_list_graph_tag, + typename boost::graph_traits< Graph >::traversal_category > + known_num_vertices; + typedef default_color_map_generator_helper< Graph, IndexMap, + known_num_vertices::value > + helper; + typedef typename helper::type type; + static type build(const Graph& g, const IndexMap& index) + { + return helper::build(g, index); + } }; - } - - // Call breadth first search with default color map. - template - inline void - dijkstra_shortest_paths_no_init - (const Graph& g, - SourceInputIter s_begin, SourceInputIter s_end, - PredecessorMap predecessor, DistanceMap distance, WeightMap weight, - IndexMap index_map, - Compare compare, Combine combine, DistZero zero, - DijkstraVisitor vis) - { - typedef - detail::default_color_map_generator - ColorMapHelper; +} + +// Call breadth first search with default color map. +template < class Graph, class SourceInputIter, class DijkstraVisitor, + class PredecessorMap, class DistanceMap, class WeightMap, class IndexMap, + class Compare, class Combine, class DistZero > +inline void dijkstra_shortest_paths_no_init(const Graph& g, + SourceInputIter s_begin, SourceInputIter s_end, PredecessorMap predecessor, + DistanceMap distance, WeightMap weight, IndexMap index_map, Compare compare, + Combine combine, DistZero zero, DijkstraVisitor vis) +{ + typedef detail::default_color_map_generator< Graph, IndexMap > + ColorMapHelper; typedef typename ColorMapHelper::type ColorMap; - ColorMap color = - ColorMapHelper::build(g, index_map); - dijkstra_shortest_paths_no_init( g, s_begin, s_end, predecessor, distance, weight, - index_map, compare, combine, zero, vis, - color); - } - - // Call breadth first search with default color map. - template - inline void - dijkstra_shortest_paths_no_init - (const Graph& g, - typename graph_traits::vertex_descriptor s, - PredecessorMap predecessor, DistanceMap distance, WeightMap weight, - IndexMap index_map, - Compare compare, Combine combine, DistZero zero, - DijkstraVisitor vis) - { + ColorMap color = ColorMapHelper::build(g, index_map); + dijkstra_shortest_paths_no_init(g, s_begin, s_end, predecessor, distance, + weight, index_map, compare, combine, zero, vis, color); +} + +// Call breadth first search with default color map. +template < class Graph, class DijkstraVisitor, class PredecessorMap, + class DistanceMap, class WeightMap, class IndexMap, class Compare, + class Combine, class DistZero > +inline void dijkstra_shortest_paths_no_init(const Graph& g, + typename graph_traits< Graph >::vertex_descriptor s, + PredecessorMap predecessor, DistanceMap distance, WeightMap weight, + IndexMap index_map, Compare compare, Combine combine, DistZero zero, + DijkstraVisitor vis) +{ dijkstra_shortest_paths_no_init(g, &s, &s + 1, predecessor, distance, - weight, index_map, compare, combine, zero, - vis); - } - - // Call breadth first search - template - inline void - dijkstra_shortest_paths_no_init - (const Graph& g, - SourceInputIter s_begin, SourceInputIter s_end, - PredecessorMap predecessor, DistanceMap distance, WeightMap weight, - IndexMap index_map, - Compare compare, Combine combine, DistZero zero, - DijkstraVisitor vis, ColorMap color) - { - typedef indirect_cmp IndirectCmp; + weight, index_map, compare, combine, zero, vis); +} + +// Call breadth first search +template < class Graph, class SourceInputIter, class DijkstraVisitor, + class PredecessorMap, class DistanceMap, class WeightMap, class IndexMap, + class Compare, class Combine, class DistZero, class ColorMap > +inline void dijkstra_shortest_paths_no_init(const Graph& g, + SourceInputIter s_begin, SourceInputIter s_end, PredecessorMap predecessor, + DistanceMap distance, WeightMap weight, IndexMap index_map, Compare compare, + Combine combine, DistZero zero, DijkstraVisitor vis, ColorMap color) +{ + typedef indirect_cmp< DistanceMap, Compare > IndirectCmp; IndirectCmp icmp(distance, compare); - typedef typename graph_traits::vertex_descriptor Vertex; + typedef typename graph_traits< Graph >::vertex_descriptor Vertex; // Now the default: use a d-ary heap - boost::scoped_array index_in_heap_map_holder; - typedef - detail::vertex_property_map_generator + boost::scoped_array< std::size_t > index_in_heap_map_holder; + typedef detail::vertex_property_map_generator< Graph, IndexMap, + std::size_t > IndexInHeapMapHelper; - typedef typename IndexInHeapMapHelper::type IndexInHeapMap; - IndexInHeapMap index_in_heap = - IndexInHeapMapHelper::build(g, index_map, index_in_heap_map_holder); - typedef d_ary_heap_indirect + typedef typename IndexInHeapMapHelper::type IndexInHeapMap; + IndexInHeapMap index_in_heap + = IndexInHeapMapHelper::build(g, index_map, index_in_heap_map_holder); + typedef d_ary_heap_indirect< Vertex, 4, IndexInHeapMap, DistanceMap, + Compare > MutableQueue; - MutableQueue Q(distance, index_in_heap, compare); + MutableQueue Q(distance, index_in_heap, compare); - detail::dijkstra_bfs_visitor + detail::dijkstra_bfs_visitor< DijkstraVisitor, MutableQueue, WeightMap, + PredecessorMap, DistanceMap, Combine, Compare > bfs_vis(vis, Q, weight, predecessor, distance, combine, compare, zero); breadth_first_visit(g, s_begin, s_end, Q, bfs_vis, color); - } - - // Call breadth first search - template - inline void - dijkstra_shortest_paths_no_init - (const Graph& g, - typename graph_traits::vertex_descriptor s, - PredecessorMap predecessor, DistanceMap distance, WeightMap weight, - IndexMap index_map, - Compare compare, Combine combine, DistZero zero, - DijkstraVisitor vis, ColorMap color) - { +} + +// Call breadth first search +template < class Graph, class DijkstraVisitor, class PredecessorMap, + class DistanceMap, class WeightMap, class IndexMap, class Compare, + class Combine, class DistZero, class ColorMap > +inline void dijkstra_shortest_paths_no_init(const Graph& g, + typename graph_traits< Graph >::vertex_descriptor s, + PredecessorMap predecessor, DistanceMap distance, WeightMap weight, + IndexMap index_map, Compare compare, Combine combine, DistZero zero, + DijkstraVisitor vis, ColorMap color) +{ dijkstra_shortest_paths_no_init(g, &s, &s + 1, predecessor, distance, - weight, index_map, compare, combine, - zero, vis, color); - } - - // Initialize distances and call breadth first search with default color map - template - inline void - dijkstra_shortest_paths - (const VertexListGraph& g, - SourceInputIter s_begin, SourceInputIter s_end, - PredecessorMap predecessor, DistanceMap distance, WeightMap weight, - IndexMap index_map, - Compare compare, Combine combine, DistInf inf, DistZero zero, - DijkstraVisitor vis, - const bgl_named_params& - BOOST_GRAPH_ENABLE_IF_MODELS_PARM(VertexListGraph,vertex_list_graph_tag)) - { - boost::two_bit_color_map color(num_vertices(g), index_map); + weight, index_map, compare, combine, zero, vis, color); +} + +// Initialize distances and call breadth first search with default color map +template < class VertexListGraph, class SourceInputIter, class DijkstraVisitor, + class PredecessorMap, class DistanceMap, class WeightMap, class IndexMap, + class Compare, class Combine, class DistInf, class DistZero, typename T, + typename Tag, typename Base > +inline void dijkstra_shortest_paths(const VertexListGraph& g, + SourceInputIter s_begin, SourceInputIter s_end, PredecessorMap predecessor, + DistanceMap distance, WeightMap weight, IndexMap index_map, Compare compare, + Combine combine, DistInf inf, DistZero zero, DijkstraVisitor vis, + const bgl_named_params< T, Tag, Base >& BOOST_GRAPH_ENABLE_IF_MODELS_PARM( + VertexListGraph, vertex_list_graph_tag)) +{ + boost::two_bit_color_map< IndexMap > color(num_vertices(g), index_map); dijkstra_shortest_paths(g, s_begin, s_end, predecessor, distance, weight, - index_map, compare, combine, inf, zero, vis, - color); - } - - // Initialize distances and call breadth first search with default color map - template - inline void - dijkstra_shortest_paths - (const VertexListGraph& g, - typename graph_traits::vertex_descriptor s, - PredecessorMap predecessor, DistanceMap distance, WeightMap weight, - IndexMap index_map, - Compare compare, Combine combine, DistInf inf, DistZero zero, - DijkstraVisitor vis, - const bgl_named_params& - BOOST_GRAPH_ENABLE_IF_MODELS_PARM(VertexListGraph,vertex_list_graph_tag)) - { + index_map, compare, combine, inf, zero, vis, color); +} + +// Initialize distances and call breadth first search with default color map +template < class VertexListGraph, class DijkstraVisitor, class PredecessorMap, + class DistanceMap, class WeightMap, class IndexMap, class Compare, + class Combine, class DistInf, class DistZero, typename T, typename Tag, + typename Base > +inline void dijkstra_shortest_paths(const VertexListGraph& g, + typename graph_traits< VertexListGraph >::vertex_descriptor s, + PredecessorMap predecessor, DistanceMap distance, WeightMap weight, + IndexMap index_map, Compare compare, Combine combine, DistInf inf, + DistZero zero, DijkstraVisitor vis, + const bgl_named_params< T, Tag, Base >& BOOST_GRAPH_ENABLE_IF_MODELS_PARM( + VertexListGraph, vertex_list_graph_tag)) +{ dijkstra_shortest_paths(g, &s, &s + 1, predecessor, distance, weight, - index_map, compare, combine, inf, zero, vis); - } - - // Initialize distances and call breadth first search - template - inline void - dijkstra_shortest_paths - (const VertexListGraph& g, - SourceInputIter s_begin, SourceInputIter s_end, - PredecessorMap predecessor, DistanceMap distance, WeightMap weight, - IndexMap index_map, - Compare compare, Combine combine, DistInf inf, DistZero zero, - DijkstraVisitor vis, ColorMap color) - { - typedef typename property_traits::value_type ColorValue; - typedef color_traits Color; - typename graph_traits::vertex_iterator ui, ui_end; - for (boost::tie(ui, ui_end) = vertices(g); ui != ui_end; ++ui) { - vis.initialize_vertex(*ui, g); - put(distance, *ui, inf); - put(predecessor, *ui, *ui); - put(color, *ui, Color::white()); + index_map, compare, combine, inf, zero, vis); +} + +// Initialize distances and call breadth first search +template < class VertexListGraph, class SourceInputIter, class DijkstraVisitor, + class PredecessorMap, class DistanceMap, class WeightMap, class IndexMap, + class Compare, class Combine, class DistInf, class DistZero, + class ColorMap > +inline void dijkstra_shortest_paths(const VertexListGraph& g, + SourceInputIter s_begin, SourceInputIter s_end, PredecessorMap predecessor, + DistanceMap distance, WeightMap weight, IndexMap index_map, Compare compare, + Combine combine, DistInf inf, DistZero zero, DijkstraVisitor vis, + ColorMap color) +{ + typedef typename property_traits< ColorMap >::value_type ColorValue; + typedef color_traits< ColorValue > Color; + typename graph_traits< VertexListGraph >::vertex_iterator ui, ui_end; + for (boost::tie(ui, ui_end) = vertices(g); ui != ui_end; ++ui) + { + vis.initialize_vertex(*ui, g); + put(distance, *ui, inf); + put(predecessor, *ui, *ui); + put(color, *ui, Color::white()); } - for (SourceInputIter it = s_begin; it != s_end; ++it) { - put(distance, *it, zero); + for (SourceInputIter it = s_begin; it != s_end; ++it) + { + put(distance, *it, zero); } dijkstra_shortest_paths_no_init(g, s_begin, s_end, predecessor, distance, - weight, index_map, compare, combine, zero, vis, - color); - } - - // Initialize distances and call breadth first search - template - inline void - dijkstra_shortest_paths - (const VertexListGraph& g, - typename graph_traits::vertex_descriptor s, - PredecessorMap predecessor, DistanceMap distance, WeightMap weight, - IndexMap index_map, - Compare compare, Combine combine, DistInf inf, DistZero zero, - DijkstraVisitor vis, ColorMap color) - { + weight, index_map, compare, combine, zero, vis, color); +} + +// Initialize distances and call breadth first search +template < class VertexListGraph, class DijkstraVisitor, class PredecessorMap, + class DistanceMap, class WeightMap, class IndexMap, class Compare, + class Combine, class DistInf, class DistZero, class ColorMap > +inline void dijkstra_shortest_paths(const VertexListGraph& g, + typename graph_traits< VertexListGraph >::vertex_descriptor s, + PredecessorMap predecessor, DistanceMap distance, WeightMap weight, + IndexMap index_map, Compare compare, Combine combine, DistInf inf, + DistZero zero, DijkstraVisitor vis, ColorMap color) +{ dijkstra_shortest_paths(g, &s, &s + 1, predecessor, distance, weight, - index_map, compare, combine, inf, zero, - vis, color); - } - - // Initialize distances and call breadth first search - template - inline void - dijkstra_shortest_paths - (const VertexListGraph& g, - SourceInputIter s_begin, SourceInputIter s_end, - PredecessorMap predecessor, DistanceMap distance, WeightMap weight, - IndexMap index_map, - Compare compare, Combine combine, DistInf inf, DistZero zero, - DijkstraVisitor vis) - { - dijkstra_shortest_paths(g, s_begin, s_end, predecessor, distance, - weight, index_map, - compare, combine, inf, zero, vis, - no_named_parameters()); - } - - // Initialize distances and call breadth first search - template - inline void - dijkstra_shortest_paths - (const VertexListGraph& g, - typename graph_traits::vertex_descriptor s, - PredecessorMap predecessor, DistanceMap distance, WeightMap weight, - IndexMap index_map, - Compare compare, Combine combine, DistInf inf, DistZero zero, - DijkstraVisitor vis) - { - dijkstra_shortest_paths(g, &s, &s + 1, predecessor, distance, - weight, index_map, - compare, combine, inf, zero, vis); - } - - namespace detail { + index_map, compare, combine, inf, zero, vis, color); +} + +// Initialize distances and call breadth first search +template < class VertexListGraph, class SourceInputIter, class DijkstraVisitor, + class PredecessorMap, class DistanceMap, class WeightMap, class IndexMap, + class Compare, class Combine, class DistInf, class DistZero > +inline void dijkstra_shortest_paths(const VertexListGraph& g, + SourceInputIter s_begin, SourceInputIter s_end, PredecessorMap predecessor, + DistanceMap distance, WeightMap weight, IndexMap index_map, Compare compare, + Combine combine, DistInf inf, DistZero zero, DijkstraVisitor vis) +{ + dijkstra_shortest_paths(g, s_begin, s_end, predecessor, distance, weight, + index_map, compare, combine, inf, zero, vis, no_named_parameters()); +} + +// Initialize distances and call breadth first search +template < class VertexListGraph, class DijkstraVisitor, class PredecessorMap, + class DistanceMap, class WeightMap, class IndexMap, class Compare, + class Combine, class DistInf, class DistZero > +inline void dijkstra_shortest_paths(const VertexListGraph& g, + typename graph_traits< VertexListGraph >::vertex_descriptor s, + PredecessorMap predecessor, DistanceMap distance, WeightMap weight, + IndexMap index_map, Compare compare, Combine combine, DistInf inf, + DistZero zero, DijkstraVisitor vis) +{ + dijkstra_shortest_paths(g, &s, &s + 1, predecessor, distance, weight, + index_map, compare, combine, inf, zero, vis); +} + +namespace detail +{ // Handle defaults for PredecessorMap and // Distance Compare, Combine, Inf and Zero - template - inline void - dijkstra_dispatch2 - (const VertexListGraph& g, - typename graph_traits::vertex_descriptor s, - DistanceMap distance, WeightMap weight, IndexMap index_map, - const Params& params) + template < class VertexListGraph, class DistanceMap, class WeightMap, + class IndexMap, class Params > + inline void dijkstra_dispatch2(const VertexListGraph& g, + typename graph_traits< VertexListGraph >::vertex_descriptor s, + DistanceMap distance, WeightMap weight, IndexMap index_map, + const Params& params) { - // Default for predecessor map - dummy_property_map p_map; - - typedef typename property_traits::value_type D; - D inf = choose_param(get_param(params, distance_inf_t()), - (std::numeric_limits::max)()); - - dijkstra_shortest_paths - (g, s, - choose_param(get_param(params, vertex_predecessor), p_map), - distance, weight, index_map, - choose_param(get_param(params, distance_compare_t()), - std::less()), - choose_param(get_param(params, distance_combine_t()), - std::plus()), - inf, - choose_param(get_param(params, distance_zero_t()), - D()), - choose_param(get_param(params, graph_visitor), - make_dijkstra_visitor(null_visitor())), - params); + // Default for predecessor map + dummy_property_map p_map; + + typedef typename property_traits< DistanceMap >::value_type D; + D inf = choose_param(get_param(params, distance_inf_t()), + (std::numeric_limits< D >::max)()); + + dijkstra_shortest_paths(g, s, + choose_param(get_param(params, vertex_predecessor), p_map), + distance, weight, index_map, + choose_param( + get_param(params, distance_compare_t()), std::less< D >()), + choose_param( + get_param(params, distance_combine_t()), std::plus< D >()), + inf, choose_param(get_param(params, distance_zero_t()), D()), + choose_param(get_param(params, graph_visitor), + make_dijkstra_visitor(null_visitor())), + params); } - template - inline void - dijkstra_dispatch1 - (const VertexListGraph& g, - typename graph_traits::vertex_descriptor s, - DistanceMap distance, WeightMap weight, IndexMap index_map, - const Params& params) + template < class VertexListGraph, class DistanceMap, class WeightMap, + class IndexMap, class Params > + inline void dijkstra_dispatch1(const VertexListGraph& g, + typename graph_traits< VertexListGraph >::vertex_descriptor s, + DistanceMap distance, WeightMap weight, IndexMap index_map, + const Params& params) { - // Default for distance map - typedef typename property_traits::value_type D; - typename std::vector::size_type - n = is_default_param(distance) ? num_vertices(g) : 1; - std::vector distance_map(n); - - detail::dijkstra_dispatch2 - (g, s, choose_param(distance, make_iterator_property_map - (distance_map.begin(), index_map, - distance_map[0])), - weight, index_map, params); + // Default for distance map + typedef typename property_traits< WeightMap >::value_type D; + typename std::vector< D >::size_type n + = is_default_param(distance) ? num_vertices(g) : 1; + std::vector< D > distance_map(n); + + detail::dijkstra_dispatch2(g, s, + choose_param(distance, + make_iterator_property_map( + distance_map.begin(), index_map, distance_map[0])), + weight, index_map, params); } - } // namespace detail - - // Named Parameter Variant - template - inline void - dijkstra_shortest_paths - (const VertexListGraph& g, - typename graph_traits::vertex_descriptor s, - const bgl_named_params& params) - { +} // namespace detail + +// Named Parameter Variant +template < class VertexListGraph, class Param, class Tag, class Rest > +inline void dijkstra_shortest_paths(const VertexListGraph& g, + typename graph_traits< VertexListGraph >::vertex_descriptor s, + const bgl_named_params< Param, Tag, Rest >& params) +{ // Default for edge weight and vertex index map is to ask for them // from the graph. Default for the visitor is null_visitor. - detail::dijkstra_dispatch1 - (g, s, - get_param(params, vertex_distance), - choose_const_pmap(get_param(params, edge_weight), g, edge_weight), - choose_const_pmap(get_param(params, vertex_index), g, vertex_index), - params); - } + detail::dijkstra_dispatch1(g, s, get_param(params, vertex_distance), + choose_const_pmap(get_param(params, edge_weight), g, edge_weight), + choose_const_pmap(get_param(params, vertex_index), g, vertex_index), + params); +} } // namespace boost -#include BOOST_GRAPH_MPI_INCLUDE() +#include BOOST_GRAPH_MPI_INCLUDE(< boost / graph / distributed / dijkstra_shortest_paths.hpp >) #endif // BOOST_GRAPH_DIJKSTRA_HPP diff --git a/include/boost/graph/dijkstra_shortest_paths_no_color_map.hpp b/include/boost/graph/dijkstra_shortest_paths_no_color_map.hpp index ae8769fc6..09607c49a 100644 --- a/include/boost/graph/dijkstra_shortest_paths_no_color_map.hpp +++ b/include/boost/graph/dijkstra_shortest_paths_no_color_map.hpp @@ -17,48 +17,43 @@ #include #include -namespace boost { - - // No init version - template - void dijkstra_shortest_paths_no_color_map_no_init - (const Graph& graph, - typename graph_traits::vertex_descriptor start_vertex, - PredecessorMap predecessor_map, - DistanceMap distance_map, - WeightMap weight_map, - VertexIndexMap index_map, - DistanceCompare distance_compare, - DistanceWeightCombine distance_weight_combine, - DistanceInfinity distance_infinity, - DistanceZero distance_zero, - DijkstraVisitor visitor) - { - typedef typename graph_traits::vertex_descriptor Vertex; - typedef typename property_traits::value_type Distance; - - typedef indirect_cmp DistanceIndirectCompare; - DistanceIndirectCompare - distance_indirect_compare(distance_map, distance_compare); - +namespace boost +{ + +// No init version +template < typename Graph, typename DijkstraVisitor, typename PredecessorMap, + typename DistanceMap, typename WeightMap, typename VertexIndexMap, + typename DistanceCompare, typename DistanceWeightCombine, + typename DistanceInfinity, typename DistanceZero > +void dijkstra_shortest_paths_no_color_map_no_init(const Graph& graph, + typename graph_traits< Graph >::vertex_descriptor start_vertex, + PredecessorMap predecessor_map, DistanceMap distance_map, + WeightMap weight_map, VertexIndexMap index_map, + DistanceCompare distance_compare, + DistanceWeightCombine distance_weight_combine, + DistanceInfinity distance_infinity, DistanceZero distance_zero, + DijkstraVisitor visitor) +{ + typedef typename graph_traits< Graph >::vertex_descriptor Vertex; + typedef typename property_traits< DistanceMap >::value_type Distance; + + typedef indirect_cmp< DistanceMap, DistanceCompare > + DistanceIndirectCompare; + DistanceIndirectCompare distance_indirect_compare( + distance_map, distance_compare); // Default - use d-ary heap (d = 4) - typedef - detail::vertex_property_map_generator - IndexInHeapMapHelper; + typedef detail::vertex_property_map_generator< Graph, VertexIndexMap, + std::size_t > + IndexInHeapMapHelper; typedef typename IndexInHeapMapHelper::type IndexInHeapMap; - typedef - d_ary_heap_indirect - VertexQueue; - - boost::scoped_array index_in_heap_map_holder; - IndexInHeapMap index_in_heap = - IndexInHeapMapHelper::build(graph, index_map, - index_in_heap_map_holder); + typedef d_ary_heap_indirect< Vertex, 4, IndexInHeapMap, DistanceMap, + DistanceCompare > + VertexQueue; + + boost::scoped_array< std::size_t > index_in_heap_map_holder; + IndexInHeapMap index_in_heap = IndexInHeapMapHelper::build( + graph, index_map, index_in_heap_map_holder); VertexQueue vertex_queue(distance_map, index_in_heap, distance_compare); // Add vertex to the queue @@ -67,174 +62,173 @@ namespace boost { // Starting vertex will always be the first discovered vertex visitor.discover_vertex(start_vertex, graph); - while (!vertex_queue.empty()) { - Vertex min_vertex = vertex_queue.top(); - vertex_queue.pop(); - - visitor.examine_vertex(min_vertex, graph); - - // Check if any other vertices can be reached - Distance min_vertex_distance = get(distance_map, min_vertex); - - if (!distance_compare(min_vertex_distance, distance_infinity)) { - // This is the minimum vertex, so all other vertices are unreachable - return; - } + while (!vertex_queue.empty()) + { + Vertex min_vertex = vertex_queue.top(); + vertex_queue.pop(); - // Examine neighbors of min_vertex - BGL_FORALL_OUTEDGES_T(min_vertex, current_edge, graph, Graph) { - visitor.examine_edge(current_edge, graph); + visitor.examine_vertex(min_vertex, graph); - // Check if the edge has a negative weight - if (distance_compare(get(weight_map, current_edge), distance_zero)) { - boost::throw_exception(negative_edge()); - } + // Check if any other vertices can be reached + Distance min_vertex_distance = get(distance_map, min_vertex); - // Extract the neighboring vertex and get its distance - Vertex neighbor_vertex = target(current_edge, graph); - Distance neighbor_vertex_distance = get(distance_map, neighbor_vertex); - bool is_neighbor_undiscovered = - !distance_compare(neighbor_vertex_distance, distance_infinity); - - // Attempt to relax the edge - bool was_edge_relaxed = relax_target(current_edge, graph, weight_map, - predecessor_map, distance_map, - distance_weight_combine, distance_compare); - - if (was_edge_relaxed) { - visitor.edge_relaxed(current_edge, graph); - if (is_neighbor_undiscovered) { - visitor.discover_vertex(neighbor_vertex, graph); - vertex_queue.push(neighbor_vertex); - } else { - vertex_queue.update(neighbor_vertex); - } - } else { - visitor.edge_not_relaxed(current_edge, graph); + if (!distance_compare(min_vertex_distance, distance_infinity)) + { + // This is the minimum vertex, so all other vertices are unreachable + return; } - } // end out edge iteration - - visitor.finish_vertex(min_vertex, graph); + // Examine neighbors of min_vertex + BGL_FORALL_OUTEDGES_T(min_vertex, current_edge, graph, Graph) + { + visitor.examine_edge(current_edge, graph); + + // Check if the edge has a negative weight + if (distance_compare(get(weight_map, current_edge), distance_zero)) + { + boost::throw_exception(negative_edge()); + } + + // Extract the neighboring vertex and get its distance + Vertex neighbor_vertex = target(current_edge, graph); + Distance neighbor_vertex_distance + = get(distance_map, neighbor_vertex); + bool is_neighbor_undiscovered = !distance_compare( + neighbor_vertex_distance, distance_infinity); + + // Attempt to relax the edge + bool was_edge_relaxed + = relax_target(current_edge, graph, weight_map, predecessor_map, + distance_map, distance_weight_combine, distance_compare); + + if (was_edge_relaxed) + { + visitor.edge_relaxed(current_edge, graph); + if (is_neighbor_undiscovered) + { + visitor.discover_vertex(neighbor_vertex, graph); + vertex_queue.push(neighbor_vertex); + } + else + { + vertex_queue.update(neighbor_vertex); + } + } + else + { + visitor.edge_not_relaxed(current_edge, graph); + } + + } // end out edge iteration + + visitor.finish_vertex(min_vertex, graph); } // end while queue not empty - } - - // Full init version - template - void dijkstra_shortest_paths_no_color_map - (const Graph& graph, - typename graph_traits::vertex_descriptor start_vertex, - PredecessorMap predecessor_map, - DistanceMap distance_map, - WeightMap weight_map, - VertexIndexMap index_map, - DistanceCompare distance_compare, - DistanceWeightCombine distance_weight_combine, - DistanceInfinity distance_infinity, - DistanceZero distance_zero, - DijkstraVisitor visitor) - { +} + +// Full init version +template < typename Graph, typename DijkstraVisitor, typename PredecessorMap, + typename DistanceMap, typename WeightMap, typename VertexIndexMap, + typename DistanceCompare, typename DistanceWeightCombine, + typename DistanceInfinity, typename DistanceZero > +void dijkstra_shortest_paths_no_color_map(const Graph& graph, + typename graph_traits< Graph >::vertex_descriptor start_vertex, + PredecessorMap predecessor_map, DistanceMap distance_map, + WeightMap weight_map, VertexIndexMap index_map, + DistanceCompare distance_compare, + DistanceWeightCombine distance_weight_combine, + DistanceInfinity distance_infinity, DistanceZero distance_zero, + DijkstraVisitor visitor) +{ // Initialize vertices - BGL_FORALL_VERTICES_T(current_vertex, graph, Graph) { - visitor.initialize_vertex(current_vertex, graph); + BGL_FORALL_VERTICES_T(current_vertex, graph, Graph) + { + visitor.initialize_vertex(current_vertex, graph); - // Default all distances to infinity - put(distance_map, current_vertex, distance_infinity); + // Default all distances to infinity + put(distance_map, current_vertex, distance_infinity); - // Default all vertex predecessors to the vertex itself - put(predecessor_map, current_vertex, current_vertex); + // Default all vertex predecessors to the vertex itself + put(predecessor_map, current_vertex, current_vertex); } // Set distance for start_vertex to zero put(distance_map, start_vertex, distance_zero); // Pass everything on to the no_init version - dijkstra_shortest_paths_no_color_map_no_init(graph, - start_vertex, predecessor_map, distance_map, weight_map, - index_map, distance_compare, distance_weight_combine, - distance_infinity, distance_zero, visitor); - } + dijkstra_shortest_paths_no_color_map_no_init(graph, start_vertex, + predecessor_map, distance_map, weight_map, index_map, distance_compare, + distance_weight_combine, distance_infinity, distance_zero, visitor); +} - namespace detail { +namespace detail +{ // Handle defaults for PredecessorMap, DistanceCompare, // DistanceWeightCombine, DistanceInfinity and DistanceZero - template - inline void - dijkstra_no_color_map_dispatch2 - (const Graph& graph, - typename graph_traits::vertex_descriptor start_vertex, - DistanceMap distance_map, WeightMap weight_map, - VertexIndexMap index_map, const Params& params) + template < typename Graph, typename DistanceMap, typename WeightMap, + typename VertexIndexMap, typename Params > + inline void dijkstra_no_color_map_dispatch2(const Graph& graph, + typename graph_traits< Graph >::vertex_descriptor start_vertex, + DistanceMap distance_map, WeightMap weight_map, + VertexIndexMap index_map, const Params& params) { - // Default for predecessor map - dummy_property_map predecessor_map; - - typedef typename property_traits::value_type DistanceType; - DistanceType inf = - choose_param(get_param(params, distance_inf_t()), - (std::numeric_limits::max)()); - dijkstra_shortest_paths_no_color_map - (graph, start_vertex, - choose_param(get_param(params, vertex_predecessor), predecessor_map), - distance_map, weight_map, index_map, - choose_param(get_param(params, distance_compare_t()), - std::less()), - choose_param(get_param(params, distance_combine_t()), - std::plus()), - inf, - choose_param(get_param(params, distance_zero_t()), - DistanceType()), - choose_param(get_param(params, graph_visitor), - make_dijkstra_visitor(null_visitor()))); + // Default for predecessor map + dummy_property_map predecessor_map; + + typedef + typename property_traits< DistanceMap >::value_type DistanceType; + DistanceType inf = choose_param(get_param(params, distance_inf_t()), + (std::numeric_limits< DistanceType >::max)()); + dijkstra_shortest_paths_no_color_map(graph, start_vertex, + choose_param( + get_param(params, vertex_predecessor), predecessor_map), + distance_map, weight_map, index_map, + choose_param(get_param(params, distance_compare_t()), + std::less< DistanceType >()), + choose_param(get_param(params, distance_combine_t()), + std::plus< DistanceType >()), + inf, + choose_param(get_param(params, distance_zero_t()), DistanceType()), + choose_param(get_param(params, graph_visitor), + make_dijkstra_visitor(null_visitor()))); } - template - inline void - dijkstra_no_color_map_dispatch1 - (const Graph& graph, - typename graph_traits::vertex_descriptor start_vertex, - DistanceMap distance_map, WeightMap weight_map, - IndexMap index_map, const Params& params) + template < typename Graph, typename DistanceMap, typename WeightMap, + typename IndexMap, typename Params > + inline void dijkstra_no_color_map_dispatch1(const Graph& graph, + typename graph_traits< Graph >::vertex_descriptor start_vertex, + DistanceMap distance_map, WeightMap weight_map, IndexMap index_map, + const Params& params) { - // Default for distance map - typedef typename property_traits::value_type DistanceType; - typename std::vector::size_type - vertex_count = is_default_param(distance_map) ? num_vertices(graph) : 1; - - std::vector default_distance_map(vertex_count); - - detail::dijkstra_no_color_map_dispatch2 - (graph, start_vertex, choose_param(distance_map, - make_iterator_property_map(default_distance_map.begin(), index_map, - default_distance_map[0])), - weight_map, index_map, params); + // Default for distance map + typedef typename property_traits< WeightMap >::value_type DistanceType; + typename std::vector< DistanceType >::size_type vertex_count + = is_default_param(distance_map) ? num_vertices(graph) : 1; + + std::vector< DistanceType > default_distance_map(vertex_count); + + detail::dijkstra_no_color_map_dispatch2(graph, start_vertex, + choose_param(distance_map, + make_iterator_property_map(default_distance_map.begin(), + index_map, default_distance_map[0])), + weight_map, index_map, params); } - } // namespace detail - - // Named parameter version - template - inline void - dijkstra_shortest_paths_no_color_map - (const Graph& graph, - typename graph_traits::vertex_descriptor start_vertex, - const bgl_named_params& params) - { +} // namespace detail + +// Named parameter version +template < typename Graph, typename Param, typename Tag, typename Rest > +inline void dijkstra_shortest_paths_no_color_map(const Graph& graph, + typename graph_traits< Graph >::vertex_descriptor start_vertex, + const bgl_named_params< Param, Tag, Rest >& params) +{ // Default for edge weight and vertex index map is to ask for them // from the graph. Default for the visitor is null_visitor. - detail::dijkstra_no_color_map_dispatch1 - (graph, start_vertex, - get_param(params, vertex_distance), - choose_const_pmap(get_param(params, edge_weight), graph, edge_weight), - choose_const_pmap(get_param(params, vertex_index), graph, vertex_index), - params); - } + detail::dijkstra_no_color_map_dispatch1(graph, start_vertex, + get_param(params, vertex_distance), + choose_const_pmap(get_param(params, edge_weight), graph, edge_weight), + choose_const_pmap(get_param(params, vertex_index), graph, vertex_index), + params); +} } // namespace boost diff --git a/include/boost/graph/dimacs.hpp b/include/boost/graph/dimacs.hpp index 12adba81e..584e3056b 100644 --- a/include/boost/graph/dimacs.hpp +++ b/include/boost/graph/dimacs.hpp @@ -19,292 +19,356 @@ #include #include -namespace boost { namespace graph { - -class BOOST_SYMBOL_VISIBLE dimacs_exception : public std::exception {}; - -class dimacs_basic_reader { -public: - typedef std::size_t vertices_size_type; - typedef std::size_t edges_size_type; - typedef double vertex_weight_type; - typedef double edge_weight_type; - typedef std::pair edge_type; - enum incr_mode {edge, edge_weight}; - - dimacs_basic_reader( std::istream& in, bool want_weights = true ) : - inpt( in ), seen_edges( 0 ), want_weights(want_weights) +namespace boost +{ +namespace graph +{ + + class BOOST_SYMBOL_VISIBLE dimacs_exception : public std::exception { - while( getline( inpt, buf ) && !buf.empty() && buf[0] == 'c' ); - - if( buf[0] != 'p' ) { - boost::throw_exception(dimacs_exception()); - } - - std::stringstream instr( buf ); - std::string junk; - - instr >> junk >> junk >> num_vertices >> num_edges; - read_edge_weights.push( -1 ); - incr( edge_weight ); - } - - //for a past the end iterator - dimacs_basic_reader() : inpt( std::cin ), num_vertices( 0 ), - num_edges( 0 ), seen_edges( 0 ), want_weights(false) {} - - edge_type edge_deref() { - BOOST_ASSERT( !read_edges.empty() ); - return read_edges.front(); - } - - inline edge_type* edge_ref() { - BOOST_ASSERT( !read_edges.empty() ); - return &read_edges.front(); - } - - inline edge_weight_type edge_weight_deref() { - BOOST_ASSERT( !read_edge_weights.empty() ); - return read_edge_weights.front(); - } - - inline dimacs_basic_reader incr( incr_mode mode ) { - if( mode == edge ) { - BOOST_ASSERT( !read_edges.empty() ); - read_edges.pop(); - } - else if( mode == edge_weight ) { - BOOST_ASSERT( !read_edge_weights.empty() ); - read_edge_weights.pop(); - } - - if( (mode == edge && read_edges.empty()) || - (mode == edge_weight && read_edge_weights.empty() )) { - - if( seen_edges > num_edges ) { - boost::throw_exception(dimacs_exception()); - } - - while( getline( inpt, buf ) && !buf.empty() && buf[0] == 'c' ); - - if( !inpt.eof() ) { - int source, dest, weight; - read_edge_line((char*) buf.c_str(), source, dest, weight); - - seen_edges++; - source--; - dest--; - - read_edges.push( edge_type( source, dest ) ); - if (want_weights) { - read_edge_weights.push( weight ); - } - } - BOOST_ASSERT( read_edges.size() < 100 ); - BOOST_ASSERT( read_edge_weights.size() < 100 ); - } - - // the 1000000 just happens to be about how many edges can be read in - // 10s -// if( !(seen_edges % 1000000) && !process_id( pg ) && mode == edge ) { -// std::cout << "read " << seen_edges << " edges" << std::endl; -// } - return *this; - } - - inline bool done_edges() { - return inpt.eof() && read_edges.size() == 0; - } - - inline bool done_edge_weights() { - return inpt.eof() && read_edge_weights.size() == 0; - } - - inline vertices_size_type n_vertices() { - return num_vertices; - } - - inline vertices_size_type processed_edges() { - return seen_edges - read_edges.size(); - } - - inline vertices_size_type processed_edge_weights() { - return seen_edges - read_edge_weights.size(); - } - - inline vertices_size_type n_edges() { - return num_edges; - } - -protected: - bool read_edge_line(char *linebuf, int &from, int &to, int &weight) + }; + + class dimacs_basic_reader { - char *fs = NULL, *ts = NULL, *ws = NULL; - char *tmp = linebuf + 2; - - fs = tmp; - if ('e' == linebuf[0]) { - while (*tmp != '\n' && *tmp != '\0') { - if (*tmp == ' ') { - *tmp = '\0'; - ts = ++tmp; - break; + public: + typedef std::size_t vertices_size_type; + typedef std::size_t edges_size_type; + typedef double vertex_weight_type; + typedef double edge_weight_type; + typedef std::pair< vertices_size_type, vertices_size_type > edge_type; + enum incr_mode + { + edge, + edge_weight + }; + + dimacs_basic_reader(std::istream& in, bool want_weights = true) + : inpt(in), seen_edges(0), want_weights(want_weights) + { + while (getline(inpt, buf) && !buf.empty() && buf[0] == 'c') + ; + + if (buf[0] != 'p') + { + boost::throw_exception(dimacs_exception()); + } + + std::stringstream instr(buf); + std::string junk; + + instr >> junk >> junk >> num_vertices >> num_edges; + read_edge_weights.push(-1); + incr(edge_weight); + } + + // for a past the end iterator + dimacs_basic_reader() + : inpt(std::cin) + , num_vertices(0) + , num_edges(0) + , seen_edges(0) + , want_weights(false) + { + } + + edge_type edge_deref() + { + BOOST_ASSERT(!read_edges.empty()); + return read_edges.front(); + } + + inline edge_type* edge_ref() + { + BOOST_ASSERT(!read_edges.empty()); + return &read_edges.front(); + } + + inline edge_weight_type edge_weight_deref() + { + BOOST_ASSERT(!read_edge_weights.empty()); + return read_edge_weights.front(); + } + + inline dimacs_basic_reader incr(incr_mode mode) + { + if (mode == edge) + { + BOOST_ASSERT(!read_edges.empty()); + read_edges.pop(); + } + else if (mode == edge_weight) + { + BOOST_ASSERT(!read_edge_weights.empty()); + read_edge_weights.pop(); + } + + if ((mode == edge && read_edges.empty()) + || (mode == edge_weight && read_edge_weights.empty())) + { + + if (seen_edges > num_edges) + { + boost::throw_exception(dimacs_exception()); + } + + while (getline(inpt, buf) && !buf.empty() && buf[0] == 'c') + ; + + if (!inpt.eof()) + { + int source, dest, weight; + read_edge_line((char*)buf.c_str(), source, dest, weight); + + seen_edges++; + source--; + dest--; + + read_edges.push(edge_type(source, dest)); + if (want_weights) + { + read_edge_weights.push(weight); + } + } + BOOST_ASSERT(read_edges.size() < 100); + BOOST_ASSERT(read_edge_weights.size() < 100); + } + + // the 1000000 just happens to be about how many edges can be read + // in 10s + // if( !(seen_edges % 1000000) && !process_id( pg ) && mode == + // edge ) { + // std::cout << "read " << seen_edges << " edges" << + // std::endl; + // } + return *this; + } + + inline bool done_edges() + { + return inpt.eof() && read_edges.size() == 0; + } + + inline bool done_edge_weights() + { + return inpt.eof() && read_edge_weights.size() == 0; + } + + inline vertices_size_type n_vertices() { return num_vertices; } + + inline vertices_size_type processed_edges() + { + return seen_edges - read_edges.size(); + } + + inline vertices_size_type processed_edge_weights() + { + return seen_edges - read_edge_weights.size(); + } + + inline vertices_size_type n_edges() { return num_edges; } + + protected: + bool read_edge_line(char* linebuf, int& from, int& to, int& weight) + { + char *fs = NULL, *ts = NULL, *ws = NULL; + char* tmp = linebuf + 2; + + fs = tmp; + if ('e' == linebuf[0]) + { + while (*tmp != '\n' && *tmp != '\0') + { + if (*tmp == ' ') + { + *tmp = '\0'; + ts = ++tmp; + break; + } + tmp++; } - tmp++; + *tmp = '\0'; + if (NULL == fs || NULL == ts) + return false; + from = atoi(fs); + to = atoi(ts); + weight = 0; } - *tmp = '\0'; - if (NULL == fs || NULL == ts) return false; - from = atoi(fs); to = atoi(ts); weight = 0; - - } else if ('a' == linebuf[0]) { - while (*tmp != '\n' && *tmp != '\0') { - if (*tmp == ' ') { - *tmp = '\0'; - ts = ++tmp; - break; + else if ('a' == linebuf[0]) + { + while (*tmp != '\n' && *tmp != '\0') + { + if (*tmp == ' ') + { + *tmp = '\0'; + ts = ++tmp; + break; + } + tmp++; } - tmp++; - } - while (*tmp != '\n' && *tmp != '\0') { - if (*tmp == ' ') { - *tmp = '\0'; - ws = ++tmp; - break; + while (*tmp != '\n' && *tmp != '\0') + { + if (*tmp == ' ') + { + *tmp = '\0'; + ws = ++tmp; + break; + } + tmp++; } - tmp++; + while (*tmp != '\n' && *tmp != '\0') + tmp++; + *tmp = '\0'; + if (fs == NULL || ts == NULL || ws == NULL) + return false; + from = atoi(fs); + to = atoi(ts); + if (want_weights) + weight = atoi(ws); + else + weight = 0; } - while (*tmp != '\n' && *tmp != '\0') tmp++; - *tmp = '\0'; - if (fs == NULL || ts == NULL || ws == NULL) return false; - from = atoi(fs); to = atoi(ts) ; - if (want_weights) weight = atoi(ws); else weight = 0; + else + { + return false; + } + + return true; + } + + std::queue< edge_type > read_edges; + std::queue< edge_weight_type > read_edge_weights; + + std::istream& inpt; + std::string buf; + vertices_size_type num_vertices, num_edges, seen_edges; + bool want_weights; + }; + + template < typename T > class dimacs_edge_iterator + { + public: + typedef dimacs_basic_reader::edge_type edge_type; + typedef dimacs_basic_reader::incr_mode incr_mode; + + typedef std::input_iterator_tag iterator_category; + typedef edge_type value_type; + typedef value_type reference; + typedef edge_type* pointer; + typedef std::ptrdiff_t difference_type; + + dimacs_edge_iterator(T& reader) : reader(reader) {} + + inline dimacs_edge_iterator& operator++() + { + reader.incr(dimacs_basic_reader::edge); + return *this; + } + + inline edge_type operator*() { return reader.edge_deref(); } + + inline edge_type* operator->() { return reader.edge_ref(); } + + // don't expect this to do the right thing if you're not comparing + // against a general past-the-end-iterator made with the default + // constructor for dimacs_basic_reader + inline bool operator==(dimacs_edge_iterator arg) + { + if (reader.n_vertices() == 0) + { + return arg.reader.done_edges(); + } + else if (arg.reader.n_vertices() == 0) + { + return reader.done_edges(); + } + else + { + return false; + } + return false; + } + + inline bool operator!=(dimacs_edge_iterator arg) + { + if (reader.n_vertices() == 0) + { + return !arg.reader.done_edges(); + } + else if (arg.reader.n_vertices() == 0) + { + return !reader.done_edges(); + } + else + { + return true; + } + return true; + } + + private: + T& reader; + }; + + template < typename T > class dimacs_edge_weight_iterator + { + public: + typedef dimacs_basic_reader::edge_weight_type edge_weight_type; + typedef dimacs_basic_reader::incr_mode incr_mode; + + dimacs_edge_weight_iterator(T& reader) : reader(reader) {} + + inline dimacs_edge_weight_iterator& operator++() + { + reader.incr(dimacs_basic_reader::edge_weight); + return *this; + } + + inline edge_weight_type operator*() + { + return reader.edge_weight_deref(); + } - } else { + // don't expect this to do the right thing if you're not comparing + // against a general past-the-end-iterator made with the default + // constructor for dimacs_basic_reader + inline bool operator==(dimacs_edge_weight_iterator arg) + { + if (reader.n_vertices() == 0) + { + return arg.reader.done_edge_weights(); + } + else if (arg.reader.n_vertices() == 0) + { + return reader.done_edge_weights(); + } + else + { + return false; + } return false; } - return true; - } - - std::queue read_edges; - std::queue read_edge_weights; - - std::istream& inpt; - std::string buf; - vertices_size_type num_vertices, num_edges, seen_edges; - bool want_weights; -}; - -template -class dimacs_edge_iterator { -public: - typedef dimacs_basic_reader::edge_type edge_type; - typedef dimacs_basic_reader::incr_mode incr_mode; - - typedef std::input_iterator_tag iterator_category; - typedef edge_type value_type; - typedef value_type reference; - typedef edge_type* pointer; - typedef std::ptrdiff_t difference_type; - - dimacs_edge_iterator( T& reader ) : - reader( reader ) {} - - inline dimacs_edge_iterator& operator++() { - reader.incr( dimacs_basic_reader::edge ); - return *this; - } - - inline edge_type operator*() { - return reader.edge_deref(); - } - - inline edge_type* operator->() { - return reader.edge_ref(); - } - - // don't expect this to do the right thing if you're not comparing against a - // general past-the-end-iterator made with the default constructor for - // dimacs_basic_reader - inline bool operator==( dimacs_edge_iterator arg ) { - if( reader.n_vertices() == 0 ) { - return arg.reader.done_edges(); - } - else if( arg.reader.n_vertices() == 0 ) { - return reader.done_edges(); - } - else { - return false; - } - return false; - } - - inline bool operator!=( dimacs_edge_iterator arg ) { - if( reader.n_vertices() == 0 ) { - return !arg.reader.done_edges(); - } - else if( arg.reader.n_vertices() == 0 ) { - return !reader.done_edges(); - } - else { - return true; - } - return true; - } - -private: - T& reader; -}; - -template -class dimacs_edge_weight_iterator { -public: - typedef dimacs_basic_reader::edge_weight_type edge_weight_type; - typedef dimacs_basic_reader::incr_mode incr_mode; - - dimacs_edge_weight_iterator( T& reader ) : reader( reader ) {} - - inline dimacs_edge_weight_iterator& operator++() { - reader.incr( dimacs_basic_reader::edge_weight ); - return *this; - } - - inline edge_weight_type operator*() { - return reader.edge_weight_deref(); - } - - // don't expect this to do the right thing if you're not comparing against a - // general past-the-end-iterator made with the default constructor for - // dimacs_basic_reader - inline bool operator==( dimacs_edge_weight_iterator arg ) { - if( reader.n_vertices() == 0 ) { - return arg.reader.done_edge_weights(); - } - else if( arg.reader.n_vertices() == 0 ) { - return reader.done_edge_weights(); - } - else { - return false; - } - return false; - } - - inline bool operator!=( dimacs_edge_weight_iterator arg ) { - if( reader.n_vertices() == 0 ) { - return !arg.reader.done_edge_weights(); - } - else if( arg.reader.n_vertices() == 0 ) { - return !reader.done_edge_weights(); - } - else { - return true; - } - return true; - } -private: - T& reader; -}; - -} } // end namespace boost::graph + inline bool operator!=(dimacs_edge_weight_iterator arg) + { + if (reader.n_vertices() == 0) + { + return !arg.reader.done_edge_weights(); + } + else if (arg.reader.n_vertices() == 0) + { + return !reader.done_edge_weights(); + } + else + { + return true; + } + return true; + } + + private: + T& reader; + }; + +} +} // end namespace boost::graph #endif diff --git a/include/boost/graph/directed_graph.hpp b/include/boost/graph/directed_graph.hpp index fdbd30086..f40c1beb1 100644 --- a/include/boost/graph/directed_graph.hpp +++ b/include/boost/graph/directed_graph.hpp @@ -16,7 +16,9 @@ namespace boost { -struct directed_graph_tag { }; +struct directed_graph_tag +{ +}; /** * The directed_graph class template is a simplified version of the BGL @@ -29,30 +31,32 @@ struct directed_graph_tag { }; * @note Special care must be taken when removing vertices or edges since * those operations can invalidate the numbering of vertices. */ -template < - typename VertexProp = no_property, - typename EdgeProp = no_property, - typename GraphProp = no_property> +template < typename VertexProp = no_property, typename EdgeProp = no_property, + typename GraphProp = no_property > class directed_graph { public: typedef GraphProp graph_property_type; typedef VertexProp vertex_property_type; typedef EdgeProp edge_property_type; - typedef typename lookup_one_property::type graph_bundled; - typedef typename lookup_one_property::type vertex_bundled; - typedef typename lookup_one_property::type edge_bundled; + typedef typename lookup_one_property< GraphProp, graph_bundle_t >::type + graph_bundled; + typedef typename lookup_one_property< VertexProp, vertex_bundle_t >::type + vertex_bundled; + typedef typename lookup_one_property< EdgeProp, edge_bundle_t >::type + edge_bundled; public: // Embed indices into the vertex type. - typedef property internal_vertex_property; - typedef property internal_edge_property; + typedef property< vertex_index_t, unsigned, vertex_property_type > + internal_vertex_property; + typedef property< edge_index_t, unsigned, edge_property_type > + internal_edge_property; + public: - typedef adjacency_list< - listS, listS, bidirectionalS, - internal_vertex_property, internal_edge_property, GraphProp, - listS - > graph_type; + typedef adjacency_list< listS, listS, bidirectionalS, + internal_vertex_property, internal_edge_property, GraphProp, listS > + graph_type; private: // storage selectors @@ -87,28 +91,41 @@ class directed_graph typedef std::size_t edge_index_type; directed_graph(GraphProp const& p = GraphProp()) - : m_graph(p), m_num_vertices(0), m_num_edges(0), m_max_vertex_index(0) - , m_max_edge_index(0) - { } + : m_graph(p) + , m_num_vertices(0) + , m_num_edges(0) + , m_max_vertex_index(0) + , m_max_edge_index(0) + { + } directed_graph(directed_graph const& x) - : m_graph(x.m_graph), m_num_vertices(x.m_num_vertices), m_num_edges(x.m_num_edges) - , m_max_vertex_index(x.m_max_vertex_index), m_max_edge_index(x.m_max_edge_index) - { } + : m_graph(x.m_graph) + , m_num_vertices(x.m_num_vertices) + , m_num_edges(x.m_num_edges) + , m_max_vertex_index(x.m_max_vertex_index) + , m_max_edge_index(x.m_max_edge_index) + { + } directed_graph(vertices_size_type n, GraphProp const& p = GraphProp()) - : m_graph(n, p), m_num_vertices(n), m_num_edges(0), m_max_vertex_index(n) - , m_max_edge_index(0) - { renumber_vertex_indices(); } - - template - directed_graph(EdgeIterator f, - EdgeIterator l, - vertices_size_type n, - edges_size_type m = 0, - GraphProp const& p = GraphProp()) - : m_graph(f, l, n, m, p), m_num_vertices(n), m_num_edges(0) - , m_max_vertex_index(n), m_max_edge_index(0) + : m_graph(n, p) + , m_num_vertices(n) + , m_num_edges(0) + , m_max_vertex_index(n) + , m_max_edge_index(0) + { + renumber_vertex_indices(); + } + + template < typename EdgeIterator > + directed_graph(EdgeIterator f, EdgeIterator l, vertices_size_type n, + edges_size_type m = 0, GraphProp const& p = GraphProp()) + : m_graph(f, l, n, m, p) + , m_num_vertices(n) + , m_num_edges(0) + , m_max_vertex_index(n) + , m_max_edge_index(0) { // Unfortunately, we have to renumber the entire graph. renumber_indices(); @@ -118,8 +135,10 @@ class directed_graph m_num_edges = m_max_edge_index = boost::num_edges(m_graph); } - directed_graph& operator=(directed_graph const& g) { - if(&g != this) { + directed_graph& operator=(directed_graph const& g) + { + if (&g != this) + { m_graph = g.m_graph; m_num_vertices = g.m_num_vertices; m_num_edges = g.m_num_edges; @@ -130,31 +149,34 @@ class directed_graph } // The impl_() methods are not part of the public interface. - graph_type& impl() - { return m_graph; } + graph_type& impl() { return m_graph; } - graph_type const& impl() const - { return m_graph; } + graph_type const& impl() const { return m_graph; } // The following methods are not part of the public interface - vertices_size_type num_vertices() const - { return m_num_vertices; } - + vertices_size_type num_vertices() const { return m_num_vertices; } private: // This helper function manages the attribution of vertex indices. - vertex_descriptor make_index(vertex_descriptor v) { + vertex_descriptor make_index(vertex_descriptor v) + { boost::put(vertex_index, m_graph, v, m_max_vertex_index); m_num_vertices++; m_max_vertex_index++; return v; } + public: vertex_descriptor add_vertex() - { return make_index(boost::add_vertex(m_graph)); } + { + return make_index(boost::add_vertex(m_graph)); + } vertex_descriptor add_vertex(vertex_property_type const& p) - { return make_index(boost::add_vertex(internal_vertex_property(0u, p), m_graph)); } + { + return make_index( + boost::add_vertex(internal_vertex_property(0u, p), m_graph)); + } void clear_vertex(vertex_descriptor v) { @@ -168,52 +190,59 @@ class directed_graph --m_num_vertices; } - edges_size_type num_edges() const - { return m_num_edges; } + edges_size_type num_edges() const { return m_num_edges; } private: // A helper function for managing edge index attributes. - std::pair const& - make_index(std::pair const& x) + std::pair< edge_descriptor, bool > const& make_index( + std::pair< edge_descriptor, bool > const& x) { - if(x.second) { + if (x.second) + { boost::put(edge_index, m_graph, x.first, m_max_edge_index); ++m_num_edges; ++m_max_edge_index; } return x; } + public: - std::pair - add_edge(vertex_descriptor u, vertex_descriptor v) - { return make_index(boost::add_edge(u, v, m_graph)); } + std::pair< edge_descriptor, bool > add_edge( + vertex_descriptor u, vertex_descriptor v) + { + return make_index(boost::add_edge(u, v, m_graph)); + } - std::pair - add_edge(vertex_descriptor u, vertex_descriptor v, edge_property_type const& p) - { return make_index(boost::add_edge(u, v, internal_edge_property(0u, p), m_graph)); } + std::pair< edge_descriptor, bool > add_edge( + vertex_descriptor u, vertex_descriptor v, edge_property_type const& p) + { + return make_index( + boost::add_edge(u, v, internal_edge_property(0u, p), m_graph)); + } void remove_edge(vertex_descriptor u, vertex_descriptor v) { // find all edges, (u, v) - std::vector edges; + std::vector< edge_descriptor > edges; out_edge_iterator i, i_end; - for(boost::tie(i, i_end) = boost::out_edges(u, m_graph); i != i_end; ++i) { - if(boost::target(*i, m_graph) == v) { + for (boost::tie(i, i_end) = boost::out_edges(u, m_graph); i != i_end; + ++i) + { + if (boost::target(*i, m_graph) == v) + { edges.push_back(*i); } } // remove all edges, (u, v) - typename std::vector::iterator - j = edges.begin(), j_end = edges.end(); - for( ; j != j_end; ++j) { + typename std::vector< edge_descriptor >::iterator j = edges.begin(), + j_end = edges.end(); + for (; j != j_end; ++j) + { remove_edge(*j); } } - void remove_edge(edge_iterator i) - { - remove_edge(*i); - } + void remove_edge(edge_iterator i) { remove_edge(*i); } void remove_edge(edge_descriptor e) { @@ -221,19 +250,16 @@ class directed_graph --m_num_edges; } - vertex_index_type max_vertex_index() const - { return m_max_vertex_index; } + vertex_index_type max_vertex_index() const { return m_max_vertex_index; } - void - renumber_vertex_indices() + void renumber_vertex_indices() { vertex_iterator i, end; boost::tie(i, end) = vertices(m_graph); m_max_vertex_index = renumber_vertex_indices(i, end, 0); } - void - remove_vertex_and_renumber_indices(vertex_iterator i) + void remove_vertex_and_renumber_indices(vertex_iterator i) { vertex_iterator j = next(i), end = vertices(m_graph).second; vertex_index_type n = get(vertex_index, m_graph, *i); @@ -243,20 +269,16 @@ class directed_graph m_max_vertex_index = renumber_vertex_indices(j, end, n); } - edge_index_type - max_edge_index() const - { return m_max_edge_index; } + edge_index_type max_edge_index() const { return m_max_edge_index; } - void - renumber_edge_indices() + void renumber_edge_indices() { edge_iterator i, end; boost::tie(i, end) = edges(m_graph); m_max_edge_index = renumber_edge_indices(i, end, 0); } - void - remove_edge_and_renumber_indices(edge_iterator i) + void remove_edge_and_renumber_indices(edge_iterator i) { edge_iterator j = next(i), end = edges(m_graph).second; edge_index_type n = get(edge_index, m_graph, *i); @@ -266,8 +288,7 @@ class directed_graph m_max_edge_index = renumber_edge_indices(j, end, n); } - void - renumber_indices() + void renumber_indices() { renumber_vertex_indices(); renumber_edge_indices(); @@ -275,28 +296,30 @@ class directed_graph // bundled property support #ifndef BOOST_GRAPH_NO_BUNDLED_PROPERTIES - vertex_bundled& operator[](vertex_descriptor v) - { return m_graph[v]; } + vertex_bundled& operator[](vertex_descriptor v) { return m_graph[v]; } vertex_bundled const& operator[](vertex_descriptor v) const - { return m_graph[v]; } + { + return m_graph[v]; + } - edge_bundled& operator[](edge_descriptor e) - { return m_graph[e]; } + edge_bundled& operator[](edge_descriptor e) { return m_graph[e]; } edge_bundled const& operator[](edge_descriptor e) const - { return m_graph[e]; } + { + return m_graph[e]; + } - graph_bundled& operator[](graph_bundle_t) - { return get_property(*this); } + graph_bundled& operator[](graph_bundle_t) { return get_property(*this); } graph_bundled const& operator[](graph_bundle_t) const - { return get_property(*this); } + { + return get_property(*this); + } #endif // Graph concepts - static vertex_descriptor null_vertex() - { return graph_type::null_vertex(); } + static vertex_descriptor null_vertex() { return graph_type::null_vertex(); } void clear() { @@ -315,27 +338,27 @@ class directed_graph } private: - vertices_size_type - renumber_vertex_indices(vertex_iterator i, - vertex_iterator end, - vertices_size_type n) + vertices_size_type renumber_vertex_indices( + vertex_iterator i, vertex_iterator end, vertices_size_type n) { - typedef typename property_map::type IndexMap; + typedef + typename property_map< graph_type, vertex_index_t >::type IndexMap; IndexMap indices = get(vertex_index, m_graph); - for( ; i != end; ++i) { + for (; i != end; ++i) + { indices[*i] = n++; } return n; } - vertices_size_type - renumber_edge_indices(edge_iterator i, - edge_iterator end, - vertices_size_type n) + vertices_size_type renumber_edge_indices( + edge_iterator i, edge_iterator end, vertices_size_type n) { - typedef typename property_map::type IndexMap; + typedef + typename property_map< graph_type, edge_index_t >::type IndexMap; IndexMap indices = get(edge_index, m_graph); - for( ; i != end; ++i) { + for (; i != end; ++i) + { indices[*i] = n++; } return n; @@ -349,347 +372,418 @@ class directed_graph }; #define DIRECTED_GRAPH_PARAMS typename VP, typename EP, typename GP -#define DIRECTED_GRAPH directed_graph +#define DIRECTED_GRAPH directed_graph< VP, EP, GP > // IncidenceGraph concepts -template -inline typename DIRECTED_GRAPH::vertex_descriptor -source(typename DIRECTED_GRAPH::edge_descriptor e, DIRECTED_GRAPH const& g) -{ return source(e, g.impl()); } - -template -inline typename DIRECTED_GRAPH::vertex_descriptor -target(typename DIRECTED_GRAPH::edge_descriptor e, DIRECTED_GRAPH const& g) -{ return target(e, g.impl()); } - -template -inline typename DIRECTED_GRAPH::degree_size_type -out_degree(typename DIRECTED_GRAPH::vertex_descriptor v, DIRECTED_GRAPH const& g) -{ return out_degree(v, g.impl()); } - -template -inline std::pair< - typename DIRECTED_GRAPH::out_edge_iterator, - typename DIRECTED_GRAPH::out_edge_iterator -> -out_edges(typename DIRECTED_GRAPH::vertex_descriptor v, - DIRECTED_GRAPH const& g) -{ return out_edges(v, g.impl()); } +template < DIRECTED_GRAPH_PARAMS > +inline typename DIRECTED_GRAPH::vertex_descriptor source( + typename DIRECTED_GRAPH::edge_descriptor e, DIRECTED_GRAPH const& g) +{ + return source(e, g.impl()); +} + +template < DIRECTED_GRAPH_PARAMS > +inline typename DIRECTED_GRAPH::vertex_descriptor target( + typename DIRECTED_GRAPH::edge_descriptor e, DIRECTED_GRAPH const& g) +{ + return target(e, g.impl()); +} + +template < DIRECTED_GRAPH_PARAMS > +inline typename DIRECTED_GRAPH::degree_size_type out_degree( + typename DIRECTED_GRAPH::vertex_descriptor v, DIRECTED_GRAPH const& g) +{ + return out_degree(v, g.impl()); +} + +template < DIRECTED_GRAPH_PARAMS > +inline std::pair< typename DIRECTED_GRAPH::out_edge_iterator, + typename DIRECTED_GRAPH::out_edge_iterator > +out_edges(typename DIRECTED_GRAPH::vertex_descriptor v, DIRECTED_GRAPH const& g) +{ + return out_edges(v, g.impl()); +} // BidirectionalGraph concepts -template -inline typename DIRECTED_GRAPH::degree_size_type -in_degree(typename DIRECTED_GRAPH::vertex_descriptor v, DIRECTED_GRAPH const& g) -{ return in_degree(v, g.impl()); } - -template -inline std::pair< - typename DIRECTED_GRAPH::in_edge_iterator, - typename DIRECTED_GRAPH::in_edge_iterator -> -in_edges(typename DIRECTED_GRAPH::vertex_descriptor v, - DIRECTED_GRAPH const& g) -{ return in_edges(v, g.impl()); } - - -template -inline typename DIRECTED_GRAPH::degree_size_type -degree(typename DIRECTED_GRAPH::vertex_descriptor v, DIRECTED_GRAPH const& g) -{ return degree(v, g.impl()); } +template < DIRECTED_GRAPH_PARAMS > +inline typename DIRECTED_GRAPH::degree_size_type in_degree( + typename DIRECTED_GRAPH::vertex_descriptor v, DIRECTED_GRAPH const& g) +{ + return in_degree(v, g.impl()); +} + +template < DIRECTED_GRAPH_PARAMS > +inline std::pair< typename DIRECTED_GRAPH::in_edge_iterator, + typename DIRECTED_GRAPH::in_edge_iterator > +in_edges(typename DIRECTED_GRAPH::vertex_descriptor v, DIRECTED_GRAPH const& g) +{ + return in_edges(v, g.impl()); +} + +template < DIRECTED_GRAPH_PARAMS > +inline typename DIRECTED_GRAPH::degree_size_type degree( + typename DIRECTED_GRAPH::vertex_descriptor v, DIRECTED_GRAPH const& g) +{ + return degree(v, g.impl()); +} // AdjacencyGraph concepts -template -inline std::pair< - typename DIRECTED_GRAPH::adjacency_iterator, - typename DIRECTED_GRAPH::adjacency_iterator - > -adjacent_vertices(typename DIRECTED_GRAPH::vertex_descriptor v, - DIRECTED_GRAPH const& g) -{ return adjacent_vertices(v, g.impl()); } - -template -typename DIRECTED_GRAPH::vertex_descriptor -vertex(typename DIRECTED_GRAPH::vertices_size_type n, - DIRECTED_GRAPH const& g) -{ return vertex(n, g.impl()); } - -template -std::pair -edge(typename DIRECTED_GRAPH::vertex_descriptor u, - typename DIRECTED_GRAPH::vertex_descriptor v, - DIRECTED_GRAPH const& g) -{ return edge(u, v, g.impl()); } +template < DIRECTED_GRAPH_PARAMS > +inline std::pair< typename DIRECTED_GRAPH::adjacency_iterator, + typename DIRECTED_GRAPH::adjacency_iterator > +adjacent_vertices( + typename DIRECTED_GRAPH::vertex_descriptor v, DIRECTED_GRAPH const& g) +{ + return adjacent_vertices(v, g.impl()); +} + +template < DIRECTED_GRAPH_PARAMS > +typename DIRECTED_GRAPH::vertex_descriptor vertex( + typename DIRECTED_GRAPH::vertices_size_type n, DIRECTED_GRAPH const& g) +{ + return vertex(n, g.impl()); +} + +template < DIRECTED_GRAPH_PARAMS > +std::pair< typename DIRECTED_GRAPH::edge_descriptor, bool > edge( + typename DIRECTED_GRAPH::vertex_descriptor u, + typename DIRECTED_GRAPH::vertex_descriptor v, DIRECTED_GRAPH const& g) +{ + return edge(u, v, g.impl()); +} // VertexListGraph concepts -template -inline typename DIRECTED_GRAPH::vertices_size_type -num_vertices(DIRECTED_GRAPH const& g) -{ return g.num_vertices(); } - -template -inline std::pair< - typename DIRECTED_GRAPH::vertex_iterator, - typename DIRECTED_GRAPH::vertex_iterator -> +template < DIRECTED_GRAPH_PARAMS > +inline typename DIRECTED_GRAPH::vertices_size_type num_vertices( + DIRECTED_GRAPH const& g) +{ + return g.num_vertices(); +} + +template < DIRECTED_GRAPH_PARAMS > +inline std::pair< typename DIRECTED_GRAPH::vertex_iterator, + typename DIRECTED_GRAPH::vertex_iterator > vertices(DIRECTED_GRAPH const& g) -{ return vertices(g.impl()); } +{ + return vertices(g.impl()); +} // EdgeListGraph concepts -template -inline typename DIRECTED_GRAPH::edges_size_type -num_edges(DIRECTED_GRAPH const& g) -{ return g.num_edges(); } - -template -inline std::pair< - typename DIRECTED_GRAPH::edge_iterator, - typename DIRECTED_GRAPH::edge_iterator -> +template < DIRECTED_GRAPH_PARAMS > +inline typename DIRECTED_GRAPH::edges_size_type num_edges( + DIRECTED_GRAPH const& g) +{ + return g.num_edges(); +} + +template < DIRECTED_GRAPH_PARAMS > +inline std::pair< typename DIRECTED_GRAPH::edge_iterator, + typename DIRECTED_GRAPH::edge_iterator > edges(DIRECTED_GRAPH const& g) -{ return edges(g.impl()); } +{ + return edges(g.impl()); +} // MutableGraph concepts -template -inline typename DIRECTED_GRAPH::vertex_descriptor -add_vertex(DIRECTED_GRAPH& g) -{ return g.add_vertex(); } - -template -inline typename DIRECTED_GRAPH::vertex_descriptor -add_vertex(typename DIRECTED_GRAPH::vertex_property_type const& p, - DIRECTED_GRAPH& g) -{ return g.add_vertex(p); } - -template -inline void -clear_vertex(typename DIRECTED_GRAPH::vertex_descriptor v, -DIRECTED_GRAPH& g) -{ return g.clear_vertex(v); } - -template -inline void -remove_vertex(typename DIRECTED_GRAPH::vertex_descriptor v, - DIRECTED_GRAPH& g) -{ return g.remove_vertex(v); } - -template -inline std::pair -add_edge(typename DIRECTED_GRAPH::vertex_descriptor u, - typename DIRECTED_GRAPH::vertex_descriptor v, - DIRECTED_GRAPH& g) -{ return g.add_edge(u, v); } - -template -inline std::pair -add_edge(typename DIRECTED_GRAPH::vertex_descriptor u, - typename DIRECTED_GRAPH::vertex_descriptor v, - typename DIRECTED_GRAPH::edge_property_type const& p, - DIRECTED_GRAPH& g) -{ return g.add_edge(u, v, p); } - -template -inline void remove_edge(typename DIRECTED_GRAPH::vertex_descriptor u, - typename DIRECTED_GRAPH::vertex_descriptor v, - DIRECTED_GRAPH& g) -{ return g.remove_edge(u, v); } +template < DIRECTED_GRAPH_PARAMS > +inline typename DIRECTED_GRAPH::vertex_descriptor add_vertex(DIRECTED_GRAPH& g) +{ + return g.add_vertex(); +} + +template < DIRECTED_GRAPH_PARAMS > +inline typename DIRECTED_GRAPH::vertex_descriptor add_vertex( + typename DIRECTED_GRAPH::vertex_property_type const& p, DIRECTED_GRAPH& g) +{ + return g.add_vertex(p); +} + +template < DIRECTED_GRAPH_PARAMS > +inline void clear_vertex( + typename DIRECTED_GRAPH::vertex_descriptor v, DIRECTED_GRAPH& g) +{ + return g.clear_vertex(v); +} + +template < DIRECTED_GRAPH_PARAMS > +inline void remove_vertex( + typename DIRECTED_GRAPH::vertex_descriptor v, DIRECTED_GRAPH& g) +{ + return g.remove_vertex(v); +} +template < DIRECTED_GRAPH_PARAMS > +inline std::pair< typename DIRECTED_GRAPH::edge_descriptor, bool > add_edge( + typename DIRECTED_GRAPH::vertex_descriptor u, + typename DIRECTED_GRAPH::vertex_descriptor v, DIRECTED_GRAPH& g) +{ + return g.add_edge(u, v); +} -template -inline void remove_edge(typename DIRECTED_GRAPH::edge_descriptor e, DIRECTED_GRAPH& g) -{ return g.remove_edge(e); } +template < DIRECTED_GRAPH_PARAMS > +inline std::pair< typename DIRECTED_GRAPH::edge_descriptor, bool > add_edge( + typename DIRECTED_GRAPH::vertex_descriptor u, + typename DIRECTED_GRAPH::vertex_descriptor v, + typename DIRECTED_GRAPH::edge_property_type const& p, DIRECTED_GRAPH& g) +{ + return g.add_edge(u, v, p); +} -template -inline void remove_edge(typename DIRECTED_GRAPH::edge_iterator i, DIRECTED_GRAPH& g) -{ return g.remove_edge(i); } +template < DIRECTED_GRAPH_PARAMS > +inline void remove_edge(typename DIRECTED_GRAPH::vertex_descriptor u, + typename DIRECTED_GRAPH::vertex_descriptor v, DIRECTED_GRAPH& g) +{ + return g.remove_edge(u, v); +} -template +template < DIRECTED_GRAPH_PARAMS > +inline void remove_edge( + typename DIRECTED_GRAPH::edge_descriptor e, DIRECTED_GRAPH& g) +{ + return g.remove_edge(e); +} + +template < DIRECTED_GRAPH_PARAMS > +inline void remove_edge( + typename DIRECTED_GRAPH::edge_iterator i, DIRECTED_GRAPH& g) +{ + return g.remove_edge(i); +} + +template < DIRECTED_GRAPH_PARAMS, class Predicate > inline void remove_edge_if(Predicate pred, DIRECTED_GRAPH& g) -{ return remove_edge_if(pred, g.impl()); } - -template -inline void -remove_out_edge_if(typename DIRECTED_GRAPH::vertex_descriptor v, - Predicate pred, - DIRECTED_GRAPH& g) -{ return remove_out_edge_if(v, pred, g.impl()); } - -template -inline void -remove_in_edge_if(typename DIRECTED_GRAPH::vertex_descriptor v, - Predicate pred, - DIRECTED_GRAPH& g) -{ return remove_in_edge_if(v, pred, g.impl()); } - -template -struct property_map: property_map {}; - -template -struct property_map { - typedef transform_value_property_map< - detail::remove_first_property, - typename property_map::const_type> - const_type; - typedef transform_value_property_map< - detail::remove_first_property, - typename property_map::type> - type; +{ + return remove_edge_if(pred, g.impl()); +} + +template < DIRECTED_GRAPH_PARAMS, class Predicate > +inline void remove_out_edge_if(typename DIRECTED_GRAPH::vertex_descriptor v, + Predicate pred, DIRECTED_GRAPH& g) +{ + return remove_out_edge_if(v, pred, g.impl()); +} + +template < DIRECTED_GRAPH_PARAMS, class Predicate > +inline void remove_in_edge_if(typename DIRECTED_GRAPH::vertex_descriptor v, + Predicate pred, DIRECTED_GRAPH& g) +{ + return remove_in_edge_if(v, pred, g.impl()); +} + +template < DIRECTED_GRAPH_PARAMS, typename Property > +struct property_map< DIRECTED_GRAPH, Property > +: property_map< typename DIRECTED_GRAPH::graph_type, Property > +{ +}; + +template < DIRECTED_GRAPH_PARAMS > +struct property_map< DIRECTED_GRAPH, vertex_all_t > +{ + typedef transform_value_property_map< detail::remove_first_property, + typename property_map< typename DIRECTED_GRAPH::graph_type, + vertex_all_t >::const_type > + const_type; + typedef transform_value_property_map< detail::remove_first_property, + typename property_map< typename DIRECTED_GRAPH::graph_type, + vertex_all_t >::type > + type; }; -template -struct property_map { - typedef transform_value_property_map< - detail::remove_first_property, - typename property_map::const_type> - const_type; - typedef transform_value_property_map< - detail::remove_first_property, - typename property_map::type> - type; +template < DIRECTED_GRAPH_PARAMS > +struct property_map< DIRECTED_GRAPH, edge_all_t > +{ + typedef transform_value_property_map< detail::remove_first_property, + typename property_map< typename DIRECTED_GRAPH::graph_type, + edge_all_t >::const_type > + const_type; + typedef transform_value_property_map< detail::remove_first_property, + typename property_map< typename DIRECTED_GRAPH::graph_type, + edge_all_t >::type > + type; }; // PropertyGraph concepts -template -inline typename property_map::type -get(Property p, DIRECTED_GRAPH& g) -{ return get(p, g.impl()); } - -template -inline typename property_map::const_type -get(Property p, DIRECTED_GRAPH const& g) -{ return get(p, g.impl()); } - -template -inline typename property_map::type -get(vertex_all_t, DIRECTED_GRAPH& g) -{ return typename property_map::type(detail::remove_first_property(), get(vertex_all, g.impl())); } - -template -inline typename property_map::const_type -get(vertex_all_t, DIRECTED_GRAPH const& g) -{ return typename property_map::const_type(detail::remove_first_property(), get(vertex_all, g.impl())); } - -template -inline typename property_map::type -get(edge_all_t, DIRECTED_GRAPH& g) -{ return typename property_map::type(detail::remove_first_property(), get(edge_all, g.impl())); } - -template -inline typename property_map::const_type -get(edge_all_t, DIRECTED_GRAPH const& g) -{ return typename property_map::const_type(detail::remove_first_property(), get(edge_all, g.impl())); } - -template -inline typename property_traits< - typename property_map< - typename DIRECTED_GRAPH::graph_type, Property - >::const_type ->::value_type +template < DIRECTED_GRAPH_PARAMS, typename Property > +inline typename property_map< DIRECTED_GRAPH, Property >::type get( + Property p, DIRECTED_GRAPH& g) +{ + return get(p, g.impl()); +} + +template < DIRECTED_GRAPH_PARAMS, typename Property > +inline typename property_map< DIRECTED_GRAPH, Property >::const_type get( + Property p, DIRECTED_GRAPH const& g) +{ + return get(p, g.impl()); +} + +template < DIRECTED_GRAPH_PARAMS > +inline typename property_map< DIRECTED_GRAPH, vertex_all_t >::type get( + vertex_all_t, DIRECTED_GRAPH& g) +{ + return typename property_map< DIRECTED_GRAPH, vertex_all_t >::type( + detail::remove_first_property(), get(vertex_all, g.impl())); +} + +template < DIRECTED_GRAPH_PARAMS > +inline typename property_map< DIRECTED_GRAPH, vertex_all_t >::const_type get( + vertex_all_t, DIRECTED_GRAPH const& g) +{ + return typename property_map< DIRECTED_GRAPH, vertex_all_t >::const_type( + detail::remove_first_property(), get(vertex_all, g.impl())); +} + +template < DIRECTED_GRAPH_PARAMS > +inline typename property_map< DIRECTED_GRAPH, edge_all_t >::type get( + edge_all_t, DIRECTED_GRAPH& g) +{ + return typename property_map< DIRECTED_GRAPH, edge_all_t >::type( + detail::remove_first_property(), get(edge_all, g.impl())); +} + +template < DIRECTED_GRAPH_PARAMS > +inline typename property_map< DIRECTED_GRAPH, edge_all_t >::const_type get( + edge_all_t, DIRECTED_GRAPH const& g) +{ + return typename property_map< DIRECTED_GRAPH, edge_all_t >::const_type( + detail::remove_first_property(), get(edge_all, g.impl())); +} + +template < DIRECTED_GRAPH_PARAMS, typename Property, typename Key > +inline typename property_traits< typename property_map< + typename DIRECTED_GRAPH::graph_type, Property >::const_type >::value_type get(Property p, DIRECTED_GRAPH const& g, Key const& k) -{ return get(p, g.impl(), k); } +{ + return get(p, g.impl(), k); +} -template +template < DIRECTED_GRAPH_PARAMS, typename Key > inline typename property_traits< - typename property_map< - typename DIRECTED_GRAPH::graph_type, vertex_all_t - >::const_type ->::value_type + typename property_map< typename DIRECTED_GRAPH::graph_type, + vertex_all_t >::const_type >::value_type get(vertex_all_t, DIRECTED_GRAPH const& g, Key const& k) -{ return get(vertex_all, g.impl(), k).m_base; } +{ + return get(vertex_all, g.impl(), k).m_base; +} -template -inline typename property_traits< - typename property_map< - typename DIRECTED_GRAPH::graph_type, edge_all_t - >::const_type ->::value_type +template < DIRECTED_GRAPH_PARAMS, typename Key > +inline typename property_traits< typename property_map< + typename DIRECTED_GRAPH::graph_type, edge_all_t >::const_type >::value_type get(edge_all_t, DIRECTED_GRAPH const& g, Key const& k) -{ return get(edge_all, g.impl(), k).m_base; } +{ + return get(edge_all, g.impl(), k).m_base; +} -template +template < DIRECTED_GRAPH_PARAMS, typename Property, typename Key, + typename Value > inline void put(Property p, DIRECTED_GRAPH& g, Key const& k, Value const& v) -{ put(p, g.impl(), k, v); } +{ + put(p, g.impl(), k, v); +} -template +template < DIRECTED_GRAPH_PARAMS, typename Key, typename Value > inline void put(vertex_all_t, DIRECTED_GRAPH& g, Key const& k, Value const& v) -{ put(vertex_all, g.impl(), k, - typename DIRECTED_GRAPH::internal_vertex_property(get(vertex_index, g.impl(), k), v)); +{ + put(vertex_all, g.impl(), k, + typename DIRECTED_GRAPH::internal_vertex_property( + get(vertex_index, g.impl(), k), v)); } -template +template < DIRECTED_GRAPH_PARAMS, typename Key, typename Value > inline void put(edge_all_t, DIRECTED_GRAPH& g, Key const& k, Value const& v) -{ put(edge_all, g.impl(), k, - typename DIRECTED_GRAPH::internal_vertex_property(get(edge_index, g.impl(), k), v)); +{ + put(edge_all, g.impl(), k, + typename DIRECTED_GRAPH::internal_vertex_property( + get(edge_index, g.impl(), k), v)); } -template -typename graph_property::type& -get_property(DIRECTED_GRAPH& g, Property p) -{ return get_property(g.impl(), p); } +template < DIRECTED_GRAPH_PARAMS, class Property > +typename graph_property< DIRECTED_GRAPH, Property >::type& get_property( + DIRECTED_GRAPH& g, Property p) +{ + return get_property(g.impl(), p); +} -template -typename graph_property::type const& -get_property(DIRECTED_GRAPH const& g, Property p) -{ return get_property(g.impl(), p); } +template < DIRECTED_GRAPH_PARAMS, class Property > +typename graph_property< DIRECTED_GRAPH, Property >::type const& get_property( + DIRECTED_GRAPH const& g, Property p) +{ + return get_property(g.impl(), p); +} -template -void -set_property(DIRECTED_GRAPH& g, Property p, Value v) -{ return set_property(g.impl(), p, v); } +template < DIRECTED_GRAPH_PARAMS, class Property, class Value > +void set_property(DIRECTED_GRAPH& g, Property p, Value v) +{ + return set_property(g.impl(), p, v); +} // Vertex index management -template -inline typename DIRECTED_GRAPH::vertex_index_type -get_vertex_index(typename DIRECTED_GRAPH::vertex_descriptor v, - DIRECTED_GRAPH const& g) -{ return get(vertex_index, g, v); } +template < DIRECTED_GRAPH_PARAMS > +inline typename DIRECTED_GRAPH::vertex_index_type get_vertex_index( + typename DIRECTED_GRAPH::vertex_descriptor v, DIRECTED_GRAPH const& g) +{ + return get(vertex_index, g, v); +} -template -typename DIRECTED_GRAPH::vertex_index_type -max_vertex_index(DIRECTED_GRAPH const& g) -{ return g.max_vertex_index(); } +template < DIRECTED_GRAPH_PARAMS > +typename DIRECTED_GRAPH::vertex_index_type max_vertex_index( + DIRECTED_GRAPH const& g) +{ + return g.max_vertex_index(); +} -template -inline void -renumber_vertex_indices(DIRECTED_GRAPH& g) -{ g.renumber_vertex_indices(); } +template < DIRECTED_GRAPH_PARAMS > +inline void renumber_vertex_indices(DIRECTED_GRAPH& g) +{ + g.renumber_vertex_indices(); +} -template -inline void -remove_vertex_and_renumber_indices(typename DIRECTED_GRAPH::vertex_iterator i, - DIRECTED_GRAPH& g) -{ g.remove_vertex_and_renumber_indices(i); } +template < DIRECTED_GRAPH_PARAMS > +inline void remove_vertex_and_renumber_indices( + typename DIRECTED_GRAPH::vertex_iterator i, DIRECTED_GRAPH& g) +{ + g.remove_vertex_and_renumber_indices(i); +} // Edge index management -template -inline typename DIRECTED_GRAPH::edge_index_type -get_edge_index(typename DIRECTED_GRAPH::edge_descriptor v, DIRECTED_GRAPH const& g) -{ return get(edge_index, g, v); } +template < DIRECTED_GRAPH_PARAMS > +inline typename DIRECTED_GRAPH::edge_index_type get_edge_index( + typename DIRECTED_GRAPH::edge_descriptor v, DIRECTED_GRAPH const& g) +{ + return get(edge_index, g, v); +} -template -typename DIRECTED_GRAPH::edge_index_type -max_edge_index(DIRECTED_GRAPH const& g) -{ return g.max_edge_index(); } +template < DIRECTED_GRAPH_PARAMS > +typename DIRECTED_GRAPH::edge_index_type max_edge_index(DIRECTED_GRAPH const& g) +{ + return g.max_edge_index(); +} -template +template < DIRECTED_GRAPH_PARAMS > inline void renumber_edge_indices(DIRECTED_GRAPH& g) -{ g.renumber_edge_indices(); } +{ + g.renumber_edge_indices(); +} -template -inline void -remove_edge_and_renumber_indices(typename DIRECTED_GRAPH::edge_iterator i, - DIRECTED_GRAPH& g) -{ g.remove_edge_and_renumber_indices(i); } +template < DIRECTED_GRAPH_PARAMS > +inline void remove_edge_and_renumber_indices( + typename DIRECTED_GRAPH::edge_iterator i, DIRECTED_GRAPH& g) +{ + g.remove_edge_and_renumber_indices(i); +} // Index management -template -inline void -renumber_indices(DIRECTED_GRAPH& g) -{ g.renumber_indices(); } +template < DIRECTED_GRAPH_PARAMS > +inline void renumber_indices(DIRECTED_GRAPH& g) +{ + g.renumber_indices(); +} // Mutability Traits -template -struct graph_mutability_traits { +template < DIRECTED_GRAPH_PARAMS > +struct graph_mutability_traits< DIRECTED_GRAPH > +{ typedef mutable_property_graph_tag category; }; diff --git a/include/boost/graph/dll_import_export.hpp b/include/boost/graph/dll_import_export.hpp index d03fcd3f2..7f042373b 100644 --- a/include/boost/graph/dll_import_export.hpp +++ b/include/boost/graph/dll_import_export.hpp @@ -14,15 +14,15 @@ #include #if defined(BOOST_ALL_DYN_LINK) || defined(BOOST_GRAPH_DYN_LINK) -# ifdef BOOST_GRAPH_SOURCE -# define BOOST_GRAPH_DECL BOOST_SYMBOL_EXPORT -# else -# define BOOST_GRAPH_DECL BOOST_SYMBOL_IMPORT -# endif // BOOST_GRAPH_SOURCE -#endif // DYN_LINK +#ifdef BOOST_GRAPH_SOURCE +#define BOOST_GRAPH_DECL BOOST_SYMBOL_EXPORT +#else +#define BOOST_GRAPH_DECL BOOST_SYMBOL_IMPORT +#endif // BOOST_GRAPH_SOURCE +#endif // DYN_LINK #ifndef BOOST_GRAPH_DECL -# define BOOST_GRAPH_DECL +#define BOOST_GRAPH_DECL #endif #endif // BOOST_GRAPH_DLL_IMPORT_EXPORT_HPP diff --git a/include/boost/graph/dominator_tree.hpp b/include/boost/graph/dominator_tree.hpp index e4a7eef5f..df9783b0b 100644 --- a/include/boost/graph/dominator_tree.hpp +++ b/include/boost/graph/dominator_tree.hpp @@ -17,478 +17,467 @@ // Dominator tree computation -namespace boost { - namespace detail { +namespace boost +{ +namespace detail +{ /** * An extended time_stamper which also records vertices for each dfs number */ - template + template < class TimeMap, class VertexVector, class TimeT, class Tag > class time_stamper_with_vertex_vector - : public base_visitor< - time_stamper_with_vertex_vector > + : public base_visitor< + time_stamper_with_vertex_vector< TimeMap, VertexVector, TimeT, Tag > > { - public : - typedef Tag event_filter; - time_stamper_with_vertex_vector(TimeMap timeMap, VertexVector& v, - TimeT& t) - : timeStamper_(timeMap, t), v_(v) { } - - template - void - operator()(const typename property_traits::key_type& v, - const Graph& g) - { - timeStamper_(v, g); - v_[timeStamper_.m_time] = v; - } - - private : - time_stamper timeStamper_; - VertexVector& v_; + public: + typedef Tag event_filter; + time_stamper_with_vertex_vector( + TimeMap timeMap, VertexVector& v, TimeT& t) + : timeStamper_(timeMap, t), v_(v) + { + } + + template < class Graph > + void operator()(const typename property_traits< TimeMap >::key_type& v, + const Graph& g) + { + timeStamper_(v, g); + v_[timeStamper_.m_time] = v; + } + + private: + time_stamper< TimeMap, TimeT, Tag > timeStamper_; + VertexVector& v_; }; /** * A convenient way to create a time_stamper_with_vertex_vector */ - template - time_stamper_with_vertex_vector - stamp_times_with_vertex_vector(TimeMap timeMap, VertexVector& v, TimeT& t, - Tag) + template < class TimeMap, class VertexVector, class TimeT, class Tag > + time_stamper_with_vertex_vector< TimeMap, VertexVector, TimeT, Tag > + stamp_times_with_vertex_vector( + TimeMap timeMap, VertexVector& v, TimeT& t, Tag) { - return time_stamper_with_vertex_vector(timeMap, v, t); + return time_stamper_with_vertex_vector< TimeMap, VertexVector, TimeT, + Tag >(timeMap, v, t); } - template + template < class Graph, class IndexMap, class TimeMap, class PredMap, + class DomTreePredMap > class dominator_visitor { - typedef typename graph_traits::vertex_descriptor Vertex; - typedef typename graph_traits::vertices_size_type VerticesSizeType; - - public : - /** - * @param g [in] the target graph of the dominator tree - * @param entry [in] the entry node of g - * @param indexMap [in] the vertex index map for g - * @param domTreePredMap [out] the immediate dominator map - * (parent map in dominator tree) - */ - dominator_visitor(const Graph& g, const Vertex& entry, - const IndexMap& indexMap, - DomTreePredMap domTreePredMap) - : semi_(num_vertices(g)), - ancestor_(num_vertices(g), graph_traits::null_vertex()), - samedom_(ancestor_), - best_(semi_), - semiMap_(make_iterator_property_map(semi_.begin(), - indexMap)), - ancestorMap_(make_iterator_property_map(ancestor_.begin(), - indexMap)), - bestMap_(make_iterator_property_map(best_.begin(), - indexMap)), - buckets_(num_vertices(g)), - bucketMap_(make_iterator_property_map(buckets_.begin(), - indexMap)), - entry_(entry), - domTreePredMap_(domTreePredMap), - numOfVertices_(num_vertices(g)), - samedomMap(make_iterator_property_map(samedom_.begin(), - indexMap)) - { - } - - void - operator()(const Vertex& n, const TimeMap& dfnumMap, - const PredMap& parentMap, const Graph& g) - { - if (n == entry_) return; - - const Vertex p(get(parentMap, n)); - Vertex s(p); - - // 1. Calculate the semidominator of n, - // based on the semidominator thm. - // * Semidominator thm. : To find the semidominator of a node n, - // consider all predecessors v of n in the CFG (Control Flow Graph). - // - If v is a proper ancestor of n in the spanning tree - // (so dfnum(v) < dfnum(n)), then v is a candidate for semi(n) - // - If v is a non-ancestor of n (so dfnum(v) > dfnum(n)) - // then for each u that is an ancestor of v (or u = v), - // Let semi(u) be a candidate for semi(n) - // of all these candidates, the one with lowest dfnum is - // the semidominator of n. - - // For each predecessor of n - typename graph_traits::in_edge_iterator inItr, inEnd; - for (boost::tie(inItr, inEnd) = in_edges(n, g); inItr != inEnd; ++inItr) - { - const Vertex v = source(*inItr, g); - // To deal with unreachable nodes - if (get(dfnumMap, v) < 0 || get(dfnumMap, v) >= numOfVertices_) - continue; - - Vertex s2; - if (get(dfnumMap, v) <= get(dfnumMap, n)) - s2 = v; - else - s2 = get(semiMap_, ancestor_with_lowest_semi_(v, dfnumMap)); - - if (get(dfnumMap, s2) < get(dfnumMap, s)) - s = s2; - } - put(semiMap_, n, s); - - // 2. Calculation of n's dominator is deferred until - // the path from s to n has been linked into the forest - get(bucketMap_, s).push_back(n); - get(ancestorMap_, n) = p; - get(bestMap_, n) = n; - - // 3. Now that the path from p to v has been linked into - // the spanning forest, these lines calculate the dominator of v, - // based on the dominator thm., or else defer the calculation - // until y's dominator is known - // * Dominator thm. : On the spanning-tree path below semi(n) and - // above or including n, let y be the node - // with the smallest-numbered semidominator. Then, - // - // idom(n) = semi(n) if semi(y)=semi(n) or - // idom(y) if semi(y) != semi(n) - typename std::deque::iterator buckItr; - for (buckItr = get(bucketMap_, p).begin(); - buckItr != get(bucketMap_, p).end(); - ++buckItr) - { - const Vertex v(*buckItr); - const Vertex y(ancestor_with_lowest_semi_(v, dfnumMap)); - if (get(semiMap_, y) == get(semiMap_, v)) - put(domTreePredMap_, v, p); - else - put(samedomMap, v, y); - } - - get(bucketMap_, p).clear(); - } - - protected : - - /** - * Evaluate function in Tarjan's path compression - */ - const Vertex - ancestor_with_lowest_semi_(const Vertex& v, const TimeMap& dfnumMap) - { - const Vertex a(get(ancestorMap_, v)); - - if (get(ancestorMap_, a) != graph_traits::null_vertex()) - { - const Vertex b(ancestor_with_lowest_semi_(a, dfnumMap)); - - put(ancestorMap_, v, get(ancestorMap_, a)); - - if (get(dfnumMap, get(semiMap_, b)) < - get(dfnumMap, get(semiMap_, get(bestMap_, v)))) - put(bestMap_, v, b); - } - - return get(bestMap_, v); - } - - std::vector semi_, ancestor_, samedom_, best_; - PredMap semiMap_, ancestorMap_, bestMap_; - std::vector< std::deque > buckets_; - - iterator_property_map >::iterator, - IndexMap> bucketMap_; - - const Vertex& entry_; - DomTreePredMap domTreePredMap_; - const VerticesSizeType numOfVertices_; - - public : - - PredMap samedomMap; + typedef typename graph_traits< Graph >::vertex_descriptor Vertex; + typedef + typename graph_traits< Graph >::vertices_size_type VerticesSizeType; + + public: + /** + * @param g [in] the target graph of the dominator tree + * @param entry [in] the entry node of g + * @param indexMap [in] the vertex index map for g + * @param domTreePredMap [out] the immediate dominator map + * (parent map in dominator tree) + */ + dominator_visitor(const Graph& g, const Vertex& entry, + const IndexMap& indexMap, DomTreePredMap domTreePredMap) + : semi_(num_vertices(g)) + , ancestor_(num_vertices(g), graph_traits< Graph >::null_vertex()) + , samedom_(ancestor_) + , best_(semi_) + , semiMap_(make_iterator_property_map(semi_.begin(), indexMap)) + , ancestorMap_(make_iterator_property_map(ancestor_.begin(), indexMap)) + , bestMap_(make_iterator_property_map(best_.begin(), indexMap)) + , buckets_(num_vertices(g)) + , bucketMap_(make_iterator_property_map(buckets_.begin(), indexMap)) + , entry_(entry) + , domTreePredMap_(domTreePredMap) + , numOfVertices_(num_vertices(g)) + , samedomMap(make_iterator_property_map(samedom_.begin(), indexMap)) + { + } + + void operator()(const Vertex& n, const TimeMap& dfnumMap, + const PredMap& parentMap, const Graph& g) + { + if (n == entry_) + return; + + const Vertex p(get(parentMap, n)); + Vertex s(p); + + // 1. Calculate the semidominator of n, + // based on the semidominator thm. + // * Semidominator thm. : To find the semidominator of a node n, + // consider all predecessors v of n in the CFG (Control Flow + // Graph). + // - If v is a proper ancestor of n in the spanning tree + // (so dfnum(v) < dfnum(n)), then v is a candidate for semi(n) + // - If v is a non-ancestor of n (so dfnum(v) > dfnum(n)) + // then for each u that is an ancestor of v (or u = v), + // Let semi(u) be a candidate for semi(n) + // of all these candidates, the one with lowest dfnum is + // the semidominator of n. + + // For each predecessor of n + typename graph_traits< Graph >::in_edge_iterator inItr, inEnd; + for (boost::tie(inItr, inEnd) = in_edges(n, g); inItr != inEnd; + ++inItr) + { + const Vertex v = source(*inItr, g); + // To deal with unreachable nodes + if (get(dfnumMap, v) < 0 || get(dfnumMap, v) >= numOfVertices_) + continue; + + Vertex s2; + if (get(dfnumMap, v) <= get(dfnumMap, n)) + s2 = v; + else + s2 = get(semiMap_, ancestor_with_lowest_semi_(v, dfnumMap)); + + if (get(dfnumMap, s2) < get(dfnumMap, s)) + s = s2; + } + put(semiMap_, n, s); + + // 2. Calculation of n's dominator is deferred until + // the path from s to n has been linked into the forest + get(bucketMap_, s).push_back(n); + get(ancestorMap_, n) = p; + get(bestMap_, n) = n; + + // 3. Now that the path from p to v has been linked into + // the spanning forest, these lines calculate the dominator of v, + // based on the dominator thm., or else defer the calculation + // until y's dominator is known + // * Dominator thm. : On the spanning-tree path below semi(n) and + // above or including n, let y be the node + // with the smallest-numbered semidominator. Then, + // + // idom(n) = semi(n) if semi(y)=semi(n) or + // idom(y) if semi(y) != semi(n) + typename std::deque< Vertex >::iterator buckItr; + for (buckItr = get(bucketMap_, p).begin(); + buckItr != get(bucketMap_, p).end(); ++buckItr) + { + const Vertex v(*buckItr); + const Vertex y(ancestor_with_lowest_semi_(v, dfnumMap)); + if (get(semiMap_, y) == get(semiMap_, v)) + put(domTreePredMap_, v, p); + else + put(samedomMap, v, y); + } + + get(bucketMap_, p).clear(); + } + + protected: + /** + * Evaluate function in Tarjan's path compression + */ + const Vertex ancestor_with_lowest_semi_( + const Vertex& v, const TimeMap& dfnumMap) + { + const Vertex a(get(ancestorMap_, v)); + + if (get(ancestorMap_, a) != graph_traits< Graph >::null_vertex()) + { + const Vertex b(ancestor_with_lowest_semi_(a, dfnumMap)); + + put(ancestorMap_, v, get(ancestorMap_, a)); + + if (get(dfnumMap, get(semiMap_, b)) + < get(dfnumMap, get(semiMap_, get(bestMap_, v)))) + put(bestMap_, v, b); + } + + return get(bestMap_, v); + } + + std::vector< Vertex > semi_, ancestor_, samedom_, best_; + PredMap semiMap_, ancestorMap_, bestMap_; + std::vector< std::deque< Vertex > > buckets_; + + iterator_property_map< + typename std::vector< std::deque< Vertex > >::iterator, IndexMap > + bucketMap_; + + const Vertex& entry_; + DomTreePredMap domTreePredMap_; + const VerticesSizeType numOfVertices_; + + public: + PredMap samedomMap; }; - } // namespace detail - - /** - * @brief Build dominator tree using Lengauer-Tarjan algorithm. - * It takes O((V+E)log(V+E)) time. - * - * @pre dfnumMap, parentMap and verticesByDFNum have dfs results corresponding - * indexMap. - * If dfs has already run before, - * this function would be good for saving computations. - * @pre Unreachable nodes must be masked as - * graph_traits::null_vertex in parentMap. - * @pre Unreachable nodes must be masked as - * (std::numeric_limits::max)() in dfnumMap. - * - * @param domTreePredMap [out] : immediate dominator map (parent map - * in dom. tree) - * - * @note reference Appel. p. 452~453. algorithm 19.9, 19.10. - * - * @todo : Optimization in Finding Dominators in Practice, Loukas Georgiadis - */ - template - void - lengauer_tarjan_dominator_tree_without_dfs - (const Graph& g, - const typename graph_traits::vertex_descriptor& entry, - const IndexMap& indexMap, - TimeMap dfnumMap, PredMap parentMap, VertexVector& verticesByDFNum, - DomTreePredMap domTreePredMap) - { +} // namespace detail + +/** + * @brief Build dominator tree using Lengauer-Tarjan algorithm. + * It takes O((V+E)log(V+E)) time. + * + * @pre dfnumMap, parentMap and verticesByDFNum have dfs results corresponding + * indexMap. + * If dfs has already run before, + * this function would be good for saving computations. + * @pre Unreachable nodes must be masked as + * graph_traits::null_vertex in parentMap. + * @pre Unreachable nodes must be masked as + * (std::numeric_limits::max)() in dfnumMap. + * + * @param domTreePredMap [out] : immediate dominator map (parent map + * in dom. tree) + * + * @note reference Appel. p. 452~453. algorithm 19.9, 19.10. + * + * @todo : Optimization in Finding Dominators in Practice, Loukas Georgiadis + */ +template < class Graph, class IndexMap, class TimeMap, class PredMap, + class VertexVector, class DomTreePredMap > +void lengauer_tarjan_dominator_tree_without_dfs(const Graph& g, + const typename graph_traits< Graph >::vertex_descriptor& entry, + const IndexMap& indexMap, TimeMap dfnumMap, PredMap parentMap, + VertexVector& verticesByDFNum, DomTreePredMap domTreePredMap) +{ // Typedefs and concept check - typedef typename graph_traits::vertex_descriptor Vertex; - typedef typename graph_traits::vertices_size_type VerticesSizeType; + typedef typename graph_traits< Graph >::vertex_descriptor Vertex; + typedef typename graph_traits< Graph >::vertices_size_type VerticesSizeType; - BOOST_CONCEPT_ASSERT(( BidirectionalGraphConcept )); + BOOST_CONCEPT_ASSERT((BidirectionalGraphConcept< Graph >)); const VerticesSizeType numOfVertices = num_vertices(g); - if (numOfVertices == 0) return; + if (numOfVertices == 0) + return; // 1. Visit each vertex in reverse post order and calculate sdom. - detail::dominator_visitor - visitor(g, entry, indexMap, domTreePredMap); + detail::dominator_visitor< Graph, IndexMap, TimeMap, PredMap, + DomTreePredMap > + visitor(g, entry, indexMap, domTreePredMap); VerticesSizeType i; for (i = 0; i < numOfVertices; ++i) - { + { const Vertex u(verticesByDFNum[numOfVertices - 1 - i]); - if (u != graph_traits::null_vertex()) - visitor(u, dfnumMap, parentMap, g); - } + if (u != graph_traits< Graph >::null_vertex()) + visitor(u, dfnumMap, parentMap, g); + } // 2. Now all the deferred dominator calculations, // based on the second clause of the dominator thm., are performed for (i = 0; i < numOfVertices; ++i) - { + { const Vertex n(verticesByDFNum[i]); - if (n == entry || n == graph_traits::null_vertex()) - continue; + if (n == entry || n == graph_traits< Graph >::null_vertex()) + continue; Vertex u = get(visitor.samedomMap, n); - if (u != graph_traits::null_vertex()) - { + if (u != graph_traits< Graph >::null_vertex()) + { put(domTreePredMap, n, get(domTreePredMap, u)); - } - } - } - - /** - * Unlike lengauer_tarjan_dominator_tree_without_dfs, - * dfs is run in this function and - * the result is written to dfnumMap, parentMap, vertices. - * - * If the result of dfs required after this algorithm, - * this function can eliminate the need of rerunning dfs. - */ - template - void - lengauer_tarjan_dominator_tree - (const Graph& g, - const typename graph_traits::vertex_descriptor& entry, - const IndexMap& indexMap, - TimeMap dfnumMap, PredMap parentMap, VertexVector& verticesByDFNum, - DomTreePredMap domTreePredMap) - { + } + } +} + +/** + * Unlike lengauer_tarjan_dominator_tree_without_dfs, + * dfs is run in this function and + * the result is written to dfnumMap, parentMap, vertices. + * + * If the result of dfs required after this algorithm, + * this function can eliminate the need of rerunning dfs. + */ +template < class Graph, class IndexMap, class TimeMap, class PredMap, + class VertexVector, class DomTreePredMap > +void lengauer_tarjan_dominator_tree(const Graph& g, + const typename graph_traits< Graph >::vertex_descriptor& entry, + const IndexMap& indexMap, TimeMap dfnumMap, PredMap parentMap, + VertexVector& verticesByDFNum, DomTreePredMap domTreePredMap) +{ // Typedefs and concept check - typedef typename graph_traits::vertices_size_type VerticesSizeType; + typedef typename graph_traits< Graph >::vertices_size_type VerticesSizeType; - BOOST_CONCEPT_ASSERT(( BidirectionalGraphConcept )); + BOOST_CONCEPT_ASSERT((BidirectionalGraphConcept< Graph >)); // 1. Depth first visit const VerticesSizeType numOfVertices = num_vertices(g); - if (numOfVertices == 0) return; - - VerticesSizeType time = - (std::numeric_limits::max)(); - std::vector - colors(numOfVertices, color_traits::white()); - depth_first_visit - (g, entry, - make_dfs_visitor - (make_pair(record_predecessors(parentMap, on_tree_edge()), - detail::stamp_times_with_vertex_vector - (dfnumMap, verticesByDFNum, time, on_discover_vertex()))), - make_iterator_property_map(colors.begin(), indexMap)); + if (numOfVertices == 0) + return; + + VerticesSizeType time = (std::numeric_limits< VerticesSizeType >::max)(); + std::vector< default_color_type > colors( + numOfVertices, color_traits< default_color_type >::white()); + depth_first_visit(g, entry, + make_dfs_visitor( + make_pair(record_predecessors(parentMap, on_tree_edge()), + detail::stamp_times_with_vertex_vector( + dfnumMap, verticesByDFNum, time, on_discover_vertex()))), + make_iterator_property_map(colors.begin(), indexMap)); // 2. Run main algorithm. lengauer_tarjan_dominator_tree_without_dfs(g, entry, indexMap, dfnumMap, - parentMap, verticesByDFNum, - domTreePredMap); - } - - /** - * Use vertex_index as IndexMap and make dfnumMap, parentMap, verticesByDFNum - * internally. - * If we don't need the result of dfs (dfnumMap, parentMap, verticesByDFNum), - * this function would be more convenient one. - */ - template - void - lengauer_tarjan_dominator_tree - (const Graph& g, - const typename graph_traits::vertex_descriptor& entry, - DomTreePredMap domTreePredMap) - { + parentMap, verticesByDFNum, domTreePredMap); +} + +/** + * Use vertex_index as IndexMap and make dfnumMap, parentMap, verticesByDFNum + * internally. + * If we don't need the result of dfs (dfnumMap, parentMap, verticesByDFNum), + * this function would be more convenient one. + */ +template < class Graph, class DomTreePredMap > +void lengauer_tarjan_dominator_tree(const Graph& g, + const typename graph_traits< Graph >::vertex_descriptor& entry, + DomTreePredMap domTreePredMap) +{ // typedefs - typedef typename graph_traits::vertex_descriptor Vertex; - typedef typename graph_traits::vertices_size_type VerticesSizeType; - typedef typename property_map::const_type IndexMap; - typedef - iterator_property_map::iterator, - IndexMap> TimeMap; - typedef - iterator_property_map::iterator, IndexMap> - PredMap; + typedef typename graph_traits< Graph >::vertex_descriptor Vertex; + typedef typename graph_traits< Graph >::vertices_size_type VerticesSizeType; + typedef typename property_map< Graph, vertex_index_t >::const_type IndexMap; + typedef iterator_property_map< + typename std::vector< VerticesSizeType >::iterator, IndexMap > + TimeMap; + typedef iterator_property_map< typename std::vector< Vertex >::iterator, + IndexMap > + PredMap; // Make property maps const VerticesSizeType numOfVertices = num_vertices(g); - if (numOfVertices == 0) return; + if (numOfVertices == 0) + return; const IndexMap indexMap = get(vertex_index, g); - std::vector dfnum(numOfVertices, 0); + std::vector< VerticesSizeType > dfnum(numOfVertices, 0); TimeMap dfnumMap(make_iterator_property_map(dfnum.begin(), indexMap)); - std::vector parent(numOfVertices, - graph_traits::null_vertex()); + std::vector< Vertex > parent( + numOfVertices, graph_traits< Graph >::null_vertex()); PredMap parentMap(make_iterator_property_map(parent.begin(), indexMap)); - std::vector verticesByDFNum(parent); + std::vector< Vertex > verticesByDFNum(parent); // Run main algorithm - lengauer_tarjan_dominator_tree(g, entry, - indexMap, dfnumMap, parentMap, - verticesByDFNum, domTreePredMap); - } - - /** - * Muchnick. p. 182, 184 - * - * using iterative bit vector analysis - */ - template - void - iterative_bit_vector_dominator_tree - (const Graph& g, - const typename graph_traits::vertex_descriptor& entry, - const IndexMap& indexMap, - DomTreePredMap domTreePredMap) - { - typedef typename graph_traits::vertex_descriptor Vertex; - typedef typename graph_traits::vertex_iterator vertexItr; - typedef typename graph_traits::vertices_size_type VerticesSizeType; - typedef - iterator_property_map >::iterator, - IndexMap> vertexSetMap; - - BOOST_CONCEPT_ASSERT(( BidirectionalGraphConcept )); + lengauer_tarjan_dominator_tree(g, entry, indexMap, dfnumMap, parentMap, + verticesByDFNum, domTreePredMap); +} + +/** + * Muchnick. p. 182, 184 + * + * using iterative bit vector analysis + */ +template < class Graph, class IndexMap, class DomTreePredMap > +void iterative_bit_vector_dominator_tree(const Graph& g, + const typename graph_traits< Graph >::vertex_descriptor& entry, + const IndexMap& indexMap, DomTreePredMap domTreePredMap) +{ + typedef typename graph_traits< Graph >::vertex_descriptor Vertex; + typedef typename graph_traits< Graph >::vertex_iterator vertexItr; + typedef typename graph_traits< Graph >::vertices_size_type VerticesSizeType; + typedef iterator_property_map< + typename std::vector< std::set< Vertex > >::iterator, IndexMap > + vertexSetMap; + + BOOST_CONCEPT_ASSERT((BidirectionalGraphConcept< Graph >)); // 1. Finding dominator // 1.1. Initialize const VerticesSizeType numOfVertices = num_vertices(g); - if (numOfVertices == 0) return; + if (numOfVertices == 0) + return; vertexItr vi, viend; boost::tie(vi, viend) = vertices(g); - const std::set N(vi, viend); + const std::set< Vertex > N(vi, viend); bool change = true; - std::vector< std::set > dom(numOfVertices, N); + std::vector< std::set< Vertex > > dom(numOfVertices, N); vertexSetMap domMap(make_iterator_property_map(dom.begin(), indexMap)); get(domMap, entry).clear(); get(domMap, entry).insert(entry); while (change) - { + { change = false; for (boost::tie(vi, viend) = vertices(g); vi != viend; ++vi) - { - if (*vi == entry) continue; + { + if (*vi == entry) + continue; - std::set T(N); + std::set< Vertex > T(N); - typename graph_traits::in_edge_iterator inItr, inEnd; - for (boost::tie(inItr, inEnd) = in_edges(*vi, g); inItr != inEnd; ++inItr) - { + typename graph_traits< Graph >::in_edge_iterator inItr, inEnd; + for (boost::tie(inItr, inEnd) = in_edges(*vi, g); inItr != inEnd; + ++inItr) + { const Vertex p = source(*inItr, g); - std::set tempSet; + std::set< Vertex > tempSet; std::set_intersection(T.begin(), T.end(), - get(domMap, p).begin(), - get(domMap, p).end(), - std::inserter(tempSet, tempSet.begin())); + get(domMap, p).begin(), get(domMap, p).end(), + std::inserter(tempSet, tempSet.begin())); T.swap(tempSet); - } + } T.insert(*vi); if (T != get(domMap, *vi)) - { + { change = true; get(domMap, *vi).swap(T); - } - } // end of for (boost::tie(vi, viend) = vertices(g) - } // end of while(change) + } + } // end of for (boost::tie(vi, viend) = vertices(g) + } // end of while(change) // 2. Build dominator tree for (boost::tie(vi, viend) = vertices(g); vi != viend; ++vi) - get(domMap, *vi).erase(*vi); + get(domMap, *vi).erase(*vi); Graph domTree(numOfVertices); for (boost::tie(vi, viend) = vertices(g); vi != viend; ++vi) - { - if (*vi == entry) continue; + { + if (*vi == entry) + continue; // We have to iterate through copied dominator set - const std::set tempSet(get(domMap, *vi)); - typename std::set::const_iterator s; + const std::set< Vertex > tempSet(get(domMap, *vi)); + typename std::set< Vertex >::const_iterator s; for (s = tempSet.begin(); s != tempSet.end(); ++s) - { - typename std::set::iterator t; - for (t = get(domMap, *vi).begin(); t != get(domMap, *vi).end(); ) - { - typename std::set::iterator old_t = t; - ++t; // Done early because t may become invalid - if (*old_t == *s) continue; + { + typename std::set< Vertex >::iterator t; + for (t = get(domMap, *vi).begin(); t != get(domMap, *vi).end();) + { + typename std::set< Vertex >::iterator old_t = t; + ++t; // Done early because t may become invalid + if (*old_t == *s) + continue; if (get(domMap, *s).find(*old_t) != get(domMap, *s).end()) - get(domMap, *vi).erase(old_t); - } - } - } + get(domMap, *vi).erase(old_t); + } + } + } for (boost::tie(vi, viend) = vertices(g); vi != viend; ++vi) - { + { if (*vi != entry && get(domMap, *vi).size() == 1) - { + { Vertex temp = *get(domMap, *vi).begin(); put(domTreePredMap, *vi, temp); - } - } - } - - template - void - iterative_bit_vector_dominator_tree - (const Graph& g, - const typename graph_traits::vertex_descriptor& entry, - DomTreePredMap domTreePredMap) - { - typename property_map::const_type - indexMap = get(vertex_index, g); + } + } +} + +template < class Graph, class DomTreePredMap > +void iterative_bit_vector_dominator_tree(const Graph& g, + const typename graph_traits< Graph >::vertex_descriptor& entry, + DomTreePredMap domTreePredMap) +{ + typename property_map< Graph, vertex_index_t >::const_type indexMap + = get(vertex_index, g); iterative_bit_vector_dominator_tree(g, entry, indexMap, domTreePredMap); - } +} } // namespace boost #endif // BOOST_GRAPH_DOMINATOR_HPP diff --git a/include/boost/graph/eccentricity.hpp b/include/boost/graph/eccentricity.hpp index 63797a830..26480ced0 100644 --- a/include/boost/graph/eccentricity.hpp +++ b/include/boost/graph/eccentricity.hpp @@ -14,74 +14,78 @@ namespace boost { -template -inline typename property_traits::value_type -eccentricity(const Graph& g, DistanceMap dist, Combinator combine) +template < typename Graph, typename DistanceMap, typename Combinator > +inline typename property_traits< DistanceMap >::value_type eccentricity( + const Graph& g, DistanceMap dist, Combinator combine) { - BOOST_CONCEPT_ASSERT(( GraphConcept )); - typedef typename graph_traits::vertex_descriptor Vertex; - BOOST_CONCEPT_ASSERT(( ReadablePropertyMapConcept )); - typedef typename property_traits::value_type Distance; + BOOST_CONCEPT_ASSERT((GraphConcept< Graph >)); + typedef typename graph_traits< Graph >::vertex_descriptor Vertex; + BOOST_CONCEPT_ASSERT((ReadablePropertyMapConcept< DistanceMap, Vertex >)); + typedef typename property_traits< DistanceMap >::value_type Distance; return detail::combine_distances(g, dist, combine, Distance(0)); } -template -inline typename property_traits::value_type -eccentricity(const Graph& g, DistanceMap dist) +template < typename Graph, typename DistanceMap > +inline typename property_traits< DistanceMap >::value_type eccentricity( + const Graph& g, DistanceMap dist) { - BOOST_CONCEPT_ASSERT(( GraphConcept )); - typedef typename graph_traits::vertex_descriptor Vertex; - BOOST_CONCEPT_ASSERT(( ReadablePropertyMapConcept )); - typedef typename property_traits::value_type Distance; + BOOST_CONCEPT_ASSERT((GraphConcept< Graph >)); + typedef typename graph_traits< Graph >::vertex_descriptor Vertex; + BOOST_CONCEPT_ASSERT((ReadablePropertyMapConcept< DistanceMap, Vertex >)); + typedef typename property_traits< DistanceMap >::value_type Distance; - return eccentricity(g, dist, detail::maximize()); + return eccentricity(g, dist, detail::maximize< Distance >()); } -template -inline std::pair::value_type, - typename property_traits::value_type> -all_eccentricities(const Graph& g, const DistanceMatrix& dist, EccentricityMap ecc) +template < typename Graph, typename DistanceMatrix, typename EccentricityMap > +inline std::pair< typename property_traits< EccentricityMap >::value_type, + typename property_traits< EccentricityMap >::value_type > +all_eccentricities( + const Graph& g, const DistanceMatrix& dist, EccentricityMap ecc) { - BOOST_CONCEPT_ASSERT(( VertexListGraphConcept )); - typedef typename graph_traits::vertex_descriptor Vertex; - typedef typename graph_traits::vertex_iterator VertexIterator; - BOOST_CONCEPT_ASSERT(( ReadablePropertyMapConcept )); - typedef typename property_traits::value_type DistanceMap; - BOOST_CONCEPT_ASSERT(( WritablePropertyMapConcept )); - typedef typename property_traits::value_type Eccentricity; + BOOST_CONCEPT_ASSERT((VertexListGraphConcept< Graph >)); + typedef typename graph_traits< Graph >::vertex_descriptor Vertex; + typedef typename graph_traits< Graph >::vertex_iterator VertexIterator; + BOOST_CONCEPT_ASSERT( + (ReadablePropertyMapConcept< DistanceMatrix, Vertex >)); + typedef typename property_traits< DistanceMatrix >::value_type DistanceMap; + BOOST_CONCEPT_ASSERT( + (WritablePropertyMapConcept< EccentricityMap, Vertex >)); + typedef + typename property_traits< EccentricityMap >::value_type Eccentricity; BOOST_USING_STD_MIN(); BOOST_USING_STD_MAX(); - - Eccentricity - r = numeric_values::infinity(), - d = numeric_values::zero(); + + Eccentricity r = numeric_values< Eccentricity >::infinity(), + d = numeric_values< Eccentricity >::zero(); VertexIterator i, end; boost::tie(i, end) = vertices(g); - for(boost::tie(i, end) = vertices(g); i != end; ++i) { + for (boost::tie(i, end) = vertices(g); i != end; ++i) + { DistanceMap dm = get(dist, *i); Eccentricity e = eccentricity(g, dm); put(ecc, *i, e); // track the radius and diameter at the same time - r = min BOOST_PREVENT_MACRO_SUBSTITUTION (r, e); - d = max BOOST_PREVENT_MACRO_SUBSTITUTION (d, e); + r = min BOOST_PREVENT_MACRO_SUBSTITUTION(r, e); + d = max BOOST_PREVENT_MACRO_SUBSTITUTION(d, e); } return std::make_pair(r, d); } -template -inline std::pair::value_type, - typename property_traits::value_type> +template < typename Graph, typename EccentricityMap > +inline std::pair< typename property_traits< EccentricityMap >::value_type, + typename property_traits< EccentricityMap >::value_type > radius_and_diameter(const Graph& g, EccentricityMap ecc) { - BOOST_CONCEPT_ASSERT(( VertexListGraphConcept )); - typedef typename graph_traits::vertex_descriptor Vertex; - typedef typename graph_traits::vertex_iterator VertexIterator; - BOOST_CONCEPT_ASSERT(( ReadablePropertyMapConcept )); - typedef typename property_traits::value_type Eccentricity; + BOOST_CONCEPT_ASSERT((VertexListGraphConcept< Graph >)); + typedef typename graph_traits< Graph >::vertex_descriptor Vertex; + typedef typename graph_traits< Graph >::vertex_iterator VertexIterator; + BOOST_CONCEPT_ASSERT( + (ReadablePropertyMapConcept< EccentricityMap, Vertex >)); + typedef + typename property_traits< EccentricityMap >::value_type Eccentricity; BOOST_USING_STD_MIN(); BOOST_USING_STD_MAX(); @@ -89,25 +93,28 @@ radius_and_diameter(const Graph& g, EccentricityMap ecc) boost::tie(i, end) = vertices(g); Eccentricity radius = get(ecc, *i); Eccentricity diameter = get(ecc, *i); - for(i = boost::next(i); i != end; ++i) { + for (i = boost::next(i); i != end; ++i) + { Eccentricity cur = get(ecc, *i); - radius = min BOOST_PREVENT_MACRO_SUBSTITUTION (radius, cur); - diameter = max BOOST_PREVENT_MACRO_SUBSTITUTION (diameter, cur); + radius = min BOOST_PREVENT_MACRO_SUBSTITUTION(radius, cur); + diameter = max BOOST_PREVENT_MACRO_SUBSTITUTION(diameter, cur); } return std::make_pair(radius, diameter); } +template < typename Graph, typename EccentricityMap > +inline typename property_traits< EccentricityMap >::value_type radius( + const Graph& g, EccentricityMap ecc) +{ + return radius_and_diameter(g, ecc).first; +} -template -inline typename property_traits::value_type -radius(const Graph& g, EccentricityMap ecc) -{ return radius_and_diameter(g, ecc).first; } - - -template -inline typename property_traits::value_type -diameter(const Graph& g, EccentricityMap ecc) -{ return radius_and_diameter(g, ecc).second; } +template < typename Graph, typename EccentricityMap > +inline typename property_traits< EccentricityMap >::value_type diameter( + const Graph& g, EccentricityMap ecc) +{ + return radius_and_diameter(g, ecc).second; +} } /* namespace boost */ diff --git a/include/boost/graph/edge_coloring.hpp b/include/boost/graph/edge_coloring.hpp index 8eb79ad43..9de277658 100644 --- a/include/boost/graph/edge_coloring.hpp +++ b/include/boost/graph/edge_coloring.hpp @@ -24,173 +24,178 @@ theorem. In Information Processing Letters. */ -namespace boost { - namespace detail { - template - bool - is_free(const Graph &g, - ColorMap color, - typename boost::graph_traits::vertex_descriptor u, - typename boost::property_traits::value_type free_color) +namespace boost +{ +namespace detail +{ + template < typename Graph, typename ColorMap > + bool is_free(const Graph& g, ColorMap color, + typename boost::graph_traits< Graph >::vertex_descriptor u, + typename boost::property_traits< ColorMap >::value_type free_color) { - typedef typename boost::property_traits::value_type color_t; - if (free_color == (std::numeric_limits::max)()) - return false; - BGL_FORALL_OUTEDGES_T(u, e, g, Graph) { - if (get(color, e) == free_color) { - return false; + typedef typename boost::property_traits< ColorMap >::value_type color_t; + if (free_color == (std::numeric_limits< color_t >::max)()) + return false; + BGL_FORALL_OUTEDGES_T(u, e, g, Graph) + { + if (get(color, e) == free_color) + { + return false; + } } - } - return true; + return true; } - template - std::vector::vertex_descriptor> - maximal_fan(const Graph &g, - ColorMap color, - typename boost::graph_traits::vertex_descriptor x, - typename boost::graph_traits::vertex_descriptor y) + template < typename Graph, typename ColorMap > + std::vector< typename boost::graph_traits< Graph >::vertex_descriptor > + maximal_fan(const Graph& g, ColorMap color, + typename boost::graph_traits< Graph >::vertex_descriptor x, + typename boost::graph_traits< Graph >::vertex_descriptor y) { - typedef typename boost::graph_traits::vertex_descriptor vertex_t; - std::vector fan; - fan.push_back(y); - bool extended; - do { - extended = false; - BGL_FORALL_OUTEDGES_T(x, e, g, Graph) { - vertex_t v = target(e, g); - if (is_free(g, color, fan.back(), get(color, e)) && - std::find(fan.begin(), fan.end(), v) == fan.end()) { - fan.push_back(v); - extended = true; - } - } - } while(extended); - return fan; + typedef + typename boost::graph_traits< Graph >::vertex_descriptor vertex_t; + std::vector< vertex_t > fan; + fan.push_back(y); + bool extended; + do + { + extended = false; + BGL_FORALL_OUTEDGES_T(x, e, g, Graph) + { + vertex_t v = target(e, g); + if (is_free(g, color, fan.back(), get(color, e)) + && std::find(fan.begin(), fan.end(), v) == fan.end()) + { + fan.push_back(v); + extended = true; + } + } + } while (extended); + return fan; } - template - typename boost::property_traits::value_type - find_free_color(const Graph &g, - ColorMap color, - typename boost::graph_traits::vertex_descriptor u) + template < typename Graph, typename ColorMap > + typename boost::property_traits< ColorMap >::value_type find_free_color( + const Graph& g, ColorMap color, + typename boost::graph_traits< Graph >::vertex_descriptor u) { - typename boost::property_traits::value_type c = 0; - while (!is_free(g, color, u, c)) c++; - return c; + typename boost::property_traits< ColorMap >::value_type c = 0; + while (!is_free(g, color, u, c)) + c++; + return c; } - template - void - invert_cd_path(const Graph &g, - ColorMap color, - typename boost::graph_traits::vertex_descriptor x, - typename boost::graph_traits::edge_descriptor eold, - typename boost::property_traits::value_type c, - typename boost::property_traits::value_type d) + template < typename Graph, typename ColorMap > + void invert_cd_path(const Graph& g, ColorMap color, + typename boost::graph_traits< Graph >::vertex_descriptor x, + typename boost::graph_traits< Graph >::edge_descriptor eold, + typename boost::property_traits< ColorMap >::value_type c, + typename boost::property_traits< ColorMap >::value_type d) { - put(color, eold, d); - BGL_FORALL_OUTEDGES_T(x, e, g, Graph) { - if (get(color, e) == d && e != eold) { - invert_cd_path(g, color, target(e, g), e, d, c); - return; + put(color, eold, d); + BGL_FORALL_OUTEDGES_T(x, e, g, Graph) + { + if (get(color, e) == d && e != eold) + { + invert_cd_path(g, color, target(e, g), e, d, c); + return; + } } - } } - template - void - invert_cd_path(const Graph &g, - ColorMap color, - typename boost::graph_traits::vertex_descriptor x, - typename boost::property_traits::value_type c, - typename boost::property_traits::value_type d) + template < typename Graph, typename ColorMap > + void invert_cd_path(const Graph& g, ColorMap color, + typename boost::graph_traits< Graph >::vertex_descriptor x, + typename boost::property_traits< ColorMap >::value_type c, + typename boost::property_traits< ColorMap >::value_type d) { - BGL_FORALL_OUTEDGES_T(x, e, g, Graph) { - if (get(color, e) == d) { - invert_cd_path(g, color, target(e, g), e, d, c); - return; + BGL_FORALL_OUTEDGES_T(x, e, g, Graph) + { + if (get(color, e) == d) + { + invert_cd_path(g, color, target(e, g), e, d, c); + return; + } } - } } - - template - void - rotate_fan(const Graph &g, - ColorMap color, - typename boost::graph_traits::vertex_descriptor x, - ForwardIterator begin, - ForwardIterator end) + + template < typename Graph, typename ColorMap, typename ForwardIterator > + void rotate_fan(const Graph& g, ColorMap color, + typename boost::graph_traits< Graph >::vertex_descriptor x, + ForwardIterator begin, ForwardIterator end) { - typedef typename boost::graph_traits::edge_descriptor edge_t; - if (begin == end) { - return; - } - edge_t previous = edge(x, *begin, g).first; - for (begin++; begin != end; begin++) { - edge_t current = edge(x, *begin, g).first; - put(color, previous, get(color, current)); - previous = current; - } + typedef typename boost::graph_traits< Graph >::edge_descriptor edge_t; + if (begin == end) + { + return; + } + edge_t previous = edge(x, *begin, g).first; + for (begin++; begin != end; begin++) + { + edge_t current = edge(x, *begin, g).first; + put(color, previous, get(color, current)); + previous = current; + } } - template - class find_free_in_fan + template < typename Graph, typename ColorMap > class find_free_in_fan { public: - find_free_in_fan(const Graph &graph, - const ColorMap color, - typename boost::property_traits::value_type d) - : graph(graph), - color(color), - d(d) {} - bool operator()(const typename boost::graph_traits::vertex_descriptor u) const { - return is_free(graph, color, u, d); - } + find_free_in_fan(const Graph& graph, const ColorMap color, + typename boost::property_traits< ColorMap >::value_type d) + : graph(graph), color(color), d(d) + { + } + bool operator()( + const typename boost::graph_traits< Graph >::vertex_descriptor u) + const + { + return is_free(graph, color, u, d); + } + private: - const Graph &graph; - const ColorMap color; - const typename boost::property_traits::value_type d; + const Graph& graph; + const ColorMap color; + const typename boost::property_traits< ColorMap >::value_type d; }; - } +} - template - typename boost::property_traits::value_type - color_edge(const Graph &g, - ColorMap color, - typename boost::graph_traits::edge_descriptor e) - { - typedef typename boost::graph_traits::vertex_descriptor vertex_t; - typedef typename boost::property_traits::value_type color_t; - typedef typename std::vector::iterator fan_iterator; +template < typename Graph, typename ColorMap > +typename boost::property_traits< ColorMap >::value_type color_edge( + const Graph& g, ColorMap color, + typename boost::graph_traits< Graph >::edge_descriptor e) +{ + typedef typename boost::graph_traits< Graph >::vertex_descriptor vertex_t; + typedef typename boost::property_traits< ColorMap >::value_type color_t; + typedef typename std::vector< vertex_t >::iterator fan_iterator; using namespace detail; vertex_t x = source(e, g), y = target(e, g); - std::vector fan = maximal_fan(g, color, x, y); + std::vector< vertex_t > fan = maximal_fan(g, color, x, y); color_t c = find_free_color(g, color, x); color_t d = find_free_color(g, color, fan.back()); invert_cd_path(g, color, x, c, d); - fan_iterator w = std::find_if(fan.begin(), - fan.end(), - find_free_in_fan(g, color, d)); + fan_iterator w = std::find_if(fan.begin(), fan.end(), + find_free_in_fan< Graph, ColorMap >(g, color, d)); rotate_fan(g, color, x, fan.begin(), w + 1); put(color, edge(x, *w, g).first, d); return (std::max)(c, d); - } +} - template - typename boost::property_traits::value_type - edge_coloring(const Graph &g, - ColorMap color) - { - typedef typename boost::property_traits::value_type color_t; - BGL_FORALL_EDGES_T(e, g, Graph) { - put(color, e, (std::numeric_limits::max)()); +template < typename Graph, typename ColorMap > +typename boost::property_traits< ColorMap >::value_type edge_coloring( + const Graph& g, ColorMap color) +{ + typedef typename boost::property_traits< ColorMap >::value_type color_t; + BGL_FORALL_EDGES_T(e, g, Graph) + { + put(color, e, (std::numeric_limits< color_t >::max)()); } color_t colors = 0; - BGL_FORALL_EDGES_T(e, g, Graph) { - colors = (std::max)(colors, color_edge(g, color, e) + 1); + BGL_FORALL_EDGES_T(e, g, Graph) + { + colors = (std::max)(colors, color_edge(g, color, e) + 1); } return colors; - } +} } #endif diff --git a/include/boost/graph/edge_connectivity.hpp b/include/boost/graph/edge_connectivity.hpp index e255d84bc..975d329f5 100644 --- a/include/boost/graph/edge_connectivity.hpp +++ b/include/boost/graph/edge_connectivity.hpp @@ -18,74 +18,75 @@ #include #include -namespace boost { +namespace boost +{ - namespace detail { +namespace detail +{ - template - inline - std::pair::vertex_descriptor, - typename graph_traits::degree_size_type> + template < class Graph > + inline std::pair< typename graph_traits< Graph >::vertex_descriptor, + typename graph_traits< Graph >::degree_size_type > min_degree_vertex(Graph& g) { - typedef graph_traits Traits; - typename Traits::vertex_descriptor p; - typedef typename Traits::degree_size_type size_type; - size_type delta = (std::numeric_limits::max)(); - - typename Traits::vertex_iterator i, iend; - for (boost::tie(i, iend) = vertices(g); i != iend; ++i) - if (degree(*i, g) < delta) { - delta = degree(*i, g); - p = *i; - } - return std::make_pair(p, delta); + typedef graph_traits< Graph > Traits; + typename Traits::vertex_descriptor p; + typedef typename Traits::degree_size_type size_type; + size_type delta = (std::numeric_limits< size_type >::max)(); + + typename Traits::vertex_iterator i, iend; + for (boost::tie(i, iend) = vertices(g); i != iend; ++i) + if (degree(*i, g) < delta) + { + delta = degree(*i, g); + p = *i; + } + return std::make_pair(p, delta); } - template - void neighbors(const Graph& g, - typename graph_traits::vertex_descriptor u, - OutputIterator result) + template < class Graph, class OutputIterator > + void neighbors(const Graph& g, + typename graph_traits< Graph >::vertex_descriptor u, + OutputIterator result) { - typename graph_traits::adjacency_iterator ai, aend; - for (boost::tie(ai, aend) = adjacent_vertices(u, g); ai != aend; ++ai) - *result++ = *ai; + typename graph_traits< Graph >::adjacency_iterator ai, aend; + for (boost::tie(ai, aend) = adjacent_vertices(u, g); ai != aend; ++ai) + *result++ = *ai; } - template - void neighbors(const Graph& g, - VertexIterator first, VertexIterator last, - OutputIterator result) + template < class Graph, class VertexIterator, class OutputIterator > + void neighbors(const Graph& g, VertexIterator first, VertexIterator last, + OutputIterator result) { - for (; first != last; ++first) - neighbors(g, *first, result); + for (; first != last; ++first) + neighbors(g, *first, result); } - } // namespace detail +} // namespace detail - // O(m n) - template - typename graph_traits::degree_size_type - edge_connectivity(VertexListGraph& g, OutputIterator disconnecting_set) - { +// O(m n) +template < class VertexListGraph, class OutputIterator > +typename graph_traits< VertexListGraph >::degree_size_type edge_connectivity( + VertexListGraph& g, OutputIterator disconnecting_set) +{ //------------------------------------------------------------------------- // Type Definitions - typedef graph_traits Traits; + typedef graph_traits< VertexListGraph > Traits; typedef typename Traits::vertex_iterator vertex_iterator; typedef typename Traits::edge_iterator edge_iterator; typedef typename Traits::out_edge_iterator out_edge_iterator; typedef typename Traits::vertex_descriptor vertex_descriptor; typedef typename Traits::degree_size_type degree_size_type; - typedef color_traits Color; + typedef color_traits< default_color_type > Color; - typedef adjacency_list_traits Tr; + typedef adjacency_list_traits< vecS, vecS, directedS > Tr; typedef typename Tr::edge_descriptor Tr_edge_desc; - typedef adjacency_list > > > - FlowGraph; - typedef typename graph_traits::edge_descriptor edge_descriptor; + typedef adjacency_list< vecS, vecS, directedS, no_property, + property< edge_capacity_t, degree_size_type, + property< edge_residual_capacity_t, degree_size_type, + property< edge_reverse_t, Tr_edge_desc > > > > + FlowGraph; + typedef typename graph_traits< FlowGraph >::edge_descriptor edge_descriptor; //------------------------------------------------------------------------- // Variable Declarations @@ -95,30 +96,31 @@ namespace boost { vertex_iterator vi, vi_end; edge_iterator ei, ei_end; degree_size_type delta, alpha_star, alpha_S_k; - std::set S, neighbor_S; - std::vector S_star, non_neighbor_S; - std::vector color(num_vertices(g)); - std::vector pred(num_vertices(g)); + std::set< vertex_descriptor > S, neighbor_S; + std::vector< vertex_descriptor > S_star, non_neighbor_S; + std::vector< default_color_type > color(num_vertices(g)); + std::vector< edge_descriptor > pred(num_vertices(g)); //------------------------------------------------------------------------- // Create a network flow graph out of the undirected graph FlowGraph flow_g(num_vertices(g)); - typename property_map::type - cap = get(edge_capacity, flow_g); - typename property_map::type - res_cap = get(edge_residual_capacity, flow_g); - typename property_map::type - rev_edge = get(edge_reverse, flow_g); - - for (boost::tie(ei, ei_end) = edges(g); ei != ei_end; ++ei) { - u = source(*ei, g), v = target(*ei, g); - boost::tie(e1, inserted) = add_edge(u, v, flow_g); - cap[e1] = 1; - boost::tie(e2, inserted) = add_edge(v, u, flow_g); - cap[e2] = 1; // not sure about this - rev_edge[e1] = e2; - rev_edge[e2] = e1; + typename property_map< FlowGraph, edge_capacity_t >::type cap + = get(edge_capacity, flow_g); + typename property_map< FlowGraph, edge_residual_capacity_t >::type res_cap + = get(edge_residual_capacity, flow_g); + typename property_map< FlowGraph, edge_reverse_t >::type rev_edge + = get(edge_reverse, flow_g); + + for (boost::tie(ei, ei_end) = edges(g); ei != ei_end; ++ei) + { + u = source(*ei, g), v = target(*ei, g); + boost::tie(e1, inserted) = add_edge(u, v, flow_g); + cap[e1] = 1; + boost::tie(e2, inserted) = add_edge(v, u, flow_g); + cap[e2] = 1; // not sure about this + rev_edge[e1] = e2; + rev_edge[e2] = e1; } //------------------------------------------------------------------------- @@ -129,54 +131,56 @@ namespace boost { alpha_star = delta; S.insert(p); neighbor_S.insert(p); - detail::neighbors(g, S.begin(), S.end(), - std::inserter(neighbor_S, neighbor_S.begin())); + detail::neighbors( + g, S.begin(), S.end(), std::inserter(neighbor_S, neighbor_S.begin())); boost::tie(vi, vi_end) = vertices(g); - std::set_difference(vi, vi_end, - neighbor_S.begin(), neighbor_S.end(), - std::back_inserter(non_neighbor_S)); - - while (!non_neighbor_S.empty()) { // at most n - 1 times - k = non_neighbor_S.front(); - - alpha_S_k = edmonds_karp_max_flow - (flow_g, p, k, cap, res_cap, rev_edge, &color[0], &pred[0]); - - if (alpha_S_k < alpha_star) { - alpha_star = alpha_S_k; - S_star.clear(); - for (boost::tie(vi, vi_end) = vertices(flow_g); vi != vi_end; ++vi) - if (color[*vi] != Color::white()) - S_star.push_back(*vi); - } - S.insert(k); - neighbor_S.insert(k); - detail::neighbors(g, k, std::inserter(neighbor_S, neighbor_S.begin())); - non_neighbor_S.clear(); - boost::tie(vi, vi_end) = vertices(g); - std::set_difference(vi, vi_end, - neighbor_S.begin(), neighbor_S.end(), - std::back_inserter(non_neighbor_S)); + std::set_difference(vi, vi_end, neighbor_S.begin(), neighbor_S.end(), + std::back_inserter(non_neighbor_S)); + + while (!non_neighbor_S.empty()) + { // at most n - 1 times + k = non_neighbor_S.front(); + + alpha_S_k = edmonds_karp_max_flow( + flow_g, p, k, cap, res_cap, rev_edge, &color[0], &pred[0]); + + if (alpha_S_k < alpha_star) + { + alpha_star = alpha_S_k; + S_star.clear(); + for (boost::tie(vi, vi_end) = vertices(flow_g); vi != vi_end; ++vi) + if (color[*vi] != Color::white()) + S_star.push_back(*vi); + } + S.insert(k); + neighbor_S.insert(k); + detail::neighbors(g, k, std::inserter(neighbor_S, neighbor_S.begin())); + non_neighbor_S.clear(); + boost::tie(vi, vi_end) = vertices(g); + std::set_difference(vi, vi_end, neighbor_S.begin(), neighbor_S.end(), + std::back_inserter(non_neighbor_S)); } //------------------------------------------------------------------------- // Compute edges of the cut [S*, ~S*] - std::vector in_S_star(num_vertices(g), false); - typename std::vector::iterator si; + std::vector< bool > in_S_star(num_vertices(g), false); + typename std::vector< vertex_descriptor >::iterator si; for (si = S_star.begin(); si != S_star.end(); ++si) - in_S_star[*si] = true; + in_S_star[*si] = true; degree_size_type c = 0; - for (si = S_star.begin(); si != S_star.end(); ++si) { - out_edge_iterator ei, ei_end; - for (boost::tie(ei, ei_end) = out_edges(*si, g); ei != ei_end; ++ei) - if (!in_S_star[target(*ei, g)]) { - *disconnecting_set++ = *ei; - ++c; - } + for (si = S_star.begin(); si != S_star.end(); ++si) + { + out_edge_iterator ei, ei_end; + for (boost::tie(ei, ei_end) = out_edges(*si, g); ei != ei_end; ++ei) + if (!in_S_star[target(*ei, g)]) + { + *disconnecting_set++ = *ei; + ++c; + } } return c; - } +} } // namespace boost diff --git a/include/boost/graph/edge_list.hpp b/include/boost/graph/edge_list.hpp index 5f0265efa..77c0c01ea 100644 --- a/include/boost/graph/edge_list.hpp +++ b/include/boost/graph/edge_list.hpp @@ -19,33 +19,35 @@ #include #include -namespace boost { +namespace boost +{ - // - // The edge_list class is an EdgeListGraph module that is constructed - // from a pair of iterators whose value type is a pair of vertex - // descriptors. - // - // For example: - // - // typedef std::pair E; - // list elist; - // ... - // typedef edge_list::iterator> Graph; - // Graph g(elist.begin(), elist.end()); - // - // If the iterators are random access, then Graph::edge_descriptor - // is of Integral type, otherwise it is a struct, though it is - // convertible to an Integral type. - // +// +// The edge_list class is an EdgeListGraph module that is constructed +// from a pair of iterators whose value type is a pair of vertex +// descriptors. +// +// For example: +// +// typedef std::pair E; +// list elist; +// ... +// typedef edge_list::iterator> Graph; +// Graph g(elist.begin(), elist.end()); +// +// If the iterators are random access, then Graph::edge_descriptor +// is of Integral type, otherwise it is a struct, though it is +// convertible to an Integral type. +// - struct edge_list_tag { }; +struct edge_list_tag +{ +}; - // The implementation class for edge_list. - template - class edge_list_impl - { - public: +// The implementation class for edge_list. +template < class G, class EdgeIter, class T, class D > class edge_list_impl +{ +public: typedef D edge_id; typedef T Vpair; typedef typename Vpair::first_type V; @@ -55,108 +57,124 @@ namespace boost { struct edge_descriptor { - edge_descriptor() { } - edge_descriptor(EdgeIter p, edge_id id) : _ptr(p), _id(id) { } - operator edge_id() { return _id; } - EdgeIter _ptr; - edge_id _id; + edge_descriptor() {} + edge_descriptor(EdgeIter p, edge_id id) : _ptr(p), _id(id) {} + operator edge_id() { return _id; } + EdgeIter _ptr; + edge_id _id; }; typedef edge_descriptor E; struct edge_iterator { - typedef edge_iterator self; - typedef E value_type; - typedef E& reference; - typedef E* pointer; - typedef std::ptrdiff_t difference_type; - typedef std::input_iterator_tag iterator_category; - edge_iterator() { } - edge_iterator(EdgeIter iter) : _iter(iter), _i(0) { } - E operator*() { return E(_iter, _i); } - self& operator++() { ++_iter; ++_i; return *this; } - self operator++(int) { self t = *this; ++(*this); return t; } - bool operator==(const self& x) { return _iter == x._iter; } - bool operator!=(const self& x) { return _iter != x._iter; } - EdgeIter _iter; - edge_id _i; + typedef edge_iterator self; + typedef E value_type; + typedef E& reference; + typedef E* pointer; + typedef std::ptrdiff_t difference_type; + typedef std::input_iterator_tag iterator_category; + edge_iterator() {} + edge_iterator(EdgeIter iter) : _iter(iter), _i(0) {} + E operator*() { return E(_iter, _i); } + self& operator++() + { + ++_iter; + ++_i; + return *this; + } + self operator++(int) + { + self t = *this; + ++(*this); + return t; + } + bool operator==(const self& x) { return _iter == x._iter; } + bool operator!=(const self& x) { return _iter != x._iter; } + EdgeIter _iter; + edge_id _i; }; typedef void out_edge_iterator; typedef void in_edge_iterator; typedef void adjacency_iterator; typedef void vertex_iterator; - }; +}; - template - std::pair::edge_iterator, - typename edge_list_impl::edge_iterator> - edges(const edge_list_impl& g_) { - const G& g = static_cast(g_); - typedef typename edge_list_impl::edge_iterator edge_iterator; +template < class G, class EI, class T, class D > +std::pair< typename edge_list_impl< G, EI, T, D >::edge_iterator, + typename edge_list_impl< G, EI, T, D >::edge_iterator > +edges(const edge_list_impl< G, EI, T, D >& g_) +{ + const G& g = static_cast< const G& >(g_); + typedef typename edge_list_impl< G, EI, T, D >::edge_iterator edge_iterator; return std::make_pair(edge_iterator(g._first), edge_iterator(g._last)); - } - template - typename edge_list_impl::vertex_descriptor - source(typename edge_list_impl::edge_descriptor e, - const edge_list_impl&) { +} +template < class G, class EI, class T, class D > +typename edge_list_impl< G, EI, T, D >::vertex_descriptor source( + typename edge_list_impl< G, EI, T, D >::edge_descriptor e, + const edge_list_impl< G, EI, T, D >&) +{ return (*e._ptr).first; - } - template - typename edge_list_impl::vertex_descriptor - target(typename edge_list_impl::edge_descriptor e, - const edge_list_impl&) { +} +template < class G, class EI, class T, class D > +typename edge_list_impl< G, EI, T, D >::vertex_descriptor target( + typename edge_list_impl< G, EI, T, D >::edge_descriptor e, + const edge_list_impl< G, EI, T, D >&) +{ return (*e._ptr).second; - } +} - template - class el_edge_property_map - : public put_get_helper >{ - public: +template < class D, class E > +class el_edge_property_map +: public put_get_helper< D, el_edge_property_map< D, E > > +{ +public: typedef E key_type; typedef D value_type; typedef D reference; typedef readable_property_map_tag category; - value_type operator[](key_type e) const { - return e._i; - } - }; - struct edge_list_edge_property_selector { - template - struct bind_ { - typedef el_edge_property_map type; - typedef type const_type; + value_type operator[](key_type e) const { return e._i; } +}; +struct edge_list_edge_property_selector +{ + template < class Graph, class Property, class Tag > struct bind_ + { + typedef el_edge_property_map< typename Graph::edge_id, + typename Graph::edge_descriptor > + type; + typedef type const_type; }; - }; - template <> - struct edge_property_selector { +}; +template <> struct edge_property_selector< edge_list_tag > +{ typedef edge_list_edge_property_selector type; - }; +}; - template - typename property_map< edge_list_impl, edge_index_t>::type - get(edge_index_t, const edge_list_impl&) { - typedef typename property_map< edge_list_impl, - edge_index_t>::type EdgeIndexMap; +template < class G, class EI, class T, class D > +typename property_map< edge_list_impl< G, EI, T, D >, edge_index_t >::type get( + edge_index_t, const edge_list_impl< G, EI, T, D >&) +{ + typedef typename property_map< edge_list_impl< G, EI, T, D >, + edge_index_t >::type EdgeIndexMap; return EdgeIndexMap(); - } +} - template - inline D - get(edge_index_t, const edge_list_impl&, - typename edge_list_impl::edge_descriptor e) { +template < class G, class EI, class T, class D > +inline D get(edge_index_t, const edge_list_impl< G, EI, T, D >&, + typename edge_list_impl< G, EI, T, D >::edge_descriptor e) +{ return e._i; - } +} - // A specialized implementation for when the iterators are random access. +// A specialized implementation for when the iterators are random access. - struct edge_list_ra_tag { }; +struct edge_list_ra_tag +{ +}; - template - class edge_list_impl_ra - { - public: +template < class G, class EdgeIter, class T, class D > class edge_list_impl_ra +{ +public: typedef D edge_id; typedef T Vpair; typedef typename Vpair::first_type V; @@ -165,138 +183,146 @@ namespace boost { typedef edge_id edge_descriptor; typedef V vertex_descriptor; - typedef typename boost::integer_range::iterator edge_iterator; + typedef typename boost::integer_range< edge_id >::iterator edge_iterator; typedef void out_edge_iterator; typedef void in_edge_iterator; typedef void adjacency_iterator; typedef void vertex_iterator; - }; +}; - template - std::pair::edge_iterator, - typename edge_list_impl_ra::edge_iterator> - edges(const edge_list_impl_ra& g_) - { - const G& g = static_cast(g_); - typedef typename edge_list_impl_ra::edge_iterator edge_iterator; +template < class G, class EI, class T, class D > +std::pair< typename edge_list_impl_ra< G, EI, T, D >::edge_iterator, + typename edge_list_impl_ra< G, EI, T, D >::edge_iterator > +edges(const edge_list_impl_ra< G, EI, T, D >& g_) +{ + const G& g = static_cast< const G& >(g_); + typedef + typename edge_list_impl_ra< G, EI, T, D >::edge_iterator edge_iterator; return std::make_pair(edge_iterator(0), edge_iterator(g._last - g._first)); - } - template - typename edge_list_impl_ra::vertex_descriptor - source(typename edge_list_impl_ra::edge_descriptor e, - const edge_list_impl_ra& g_) - { - const G& g = static_cast(g_); +} +template < class G, class EI, class T, class D > +typename edge_list_impl_ra< G, EI, T, D >::vertex_descriptor source( + typename edge_list_impl_ra< G, EI, T, D >::edge_descriptor e, + const edge_list_impl_ra< G, EI, T, D >& g_) +{ + const G& g = static_cast< const G& >(g_); return g._first[e].first; - } - template - typename edge_list_impl_ra::vertex_descriptor - target(typename edge_list_impl_ra::edge_descriptor e, - const edge_list_impl_ra& g_) - { - const G& g = static_cast(g_); +} +template < class G, class EI, class T, class D > +typename edge_list_impl_ra< G, EI, T, D >::vertex_descriptor target( + typename edge_list_impl_ra< G, EI, T, D >::edge_descriptor e, + const edge_list_impl_ra< G, EI, T, D >& g_) +{ + const G& g = static_cast< const G& >(g_); return g._first[e].second; - } - template - class el_ra_edge_property_map - : public put_get_helper >{ - public: +} +template < class E > +class el_ra_edge_property_map +: public put_get_helper< E, el_ra_edge_property_map< E > > +{ +public: typedef E key_type; typedef E value_type; typedef E reference; typedef readable_property_map_tag category; - value_type operator[](key_type e) const { - return e; - } - }; - struct edge_list_ra_edge_property_selector { - template - struct bind_ { - typedef el_ra_edge_property_map type; - typedef type const_type; + value_type operator[](key_type e) const { return e; } +}; +struct edge_list_ra_edge_property_selector +{ + template < class Graph, class Property, class Tag > struct bind_ + { + typedef el_ra_edge_property_map< typename Graph::edge_descriptor > type; + typedef type const_type; }; - }; - template <> - struct edge_property_selector { +}; +template <> struct edge_property_selector< edge_list_ra_tag > +{ typedef edge_list_ra_edge_property_selector type; - }; - template - inline - typename property_map< edge_list_impl_ra, edge_index_t>::type - get(edge_index_t, const edge_list_impl_ra&) { - typedef typename property_map< edge_list_impl_ra, - edge_index_t>::type EdgeIndexMap; +}; +template < class G, class EI, class T, class D > +inline typename property_map< edge_list_impl_ra< G, EI, T, D >, + edge_index_t >::type +get(edge_index_t, const edge_list_impl_ra< G, EI, T, D >&) +{ + typedef typename property_map< edge_list_impl_ra< G, EI, T, D >, + edge_index_t >::type EdgeIndexMap; return EdgeIndexMap(); - } +} - template - inline D - get(edge_index_t, const edge_list_impl_ra&, - typename edge_list_impl_ra::edge_descriptor e) { +template < class G, class EI, class T, class D > +inline D get(edge_index_t, const edge_list_impl_ra< G, EI, T, D >&, + typename edge_list_impl_ra< G, EI, T, D >::edge_descriptor e) +{ return e; - } +} - - // Some helper classes for determining if the iterators are random access - template - struct is_random { - enum { RET = false }; +// Some helper classes for determining if the iterators are random access +template < class Cat > struct is_random +{ + enum + { + RET = false + }; typedef mpl::false_ type; - }; - template <> - struct is_random { - enum { RET = true }; typedef mpl::true_ type; - }; +}; +template <> struct is_random< std::random_access_iterator_tag > +{ + enum + { + RET = true + }; + typedef mpl::true_ type; +}; - // The edge_list class conditionally inherits from one of the - // above two classes. +// The edge_list class conditionally inherits from one of the +// above two classes. - template ::value_type, - class D = typename std::iterator_traits::difference_type, - class Cat = typename std::iterator_traits::iterator_category> + class T = typename std::iterator_traits< EdgeIter >::value_type, + class D = typename std::iterator_traits< EdgeIter >::difference_type, + class Cat = typename std::iterator_traits< EdgeIter >::iterator_category > #else - class T, - class D, - class Cat> + class T, class D, class Cat > #endif - class edge_list - : public mpl::if_< typename is_random::type, - edge_list_impl_ra< edge_list, EdgeIter,T,D>, - edge_list_impl< edge_list, EdgeIter,T,D> - >::type - { - public: +class edge_list +: public mpl::if_< typename is_random< Cat >::type, + edge_list_impl_ra< edge_list< EdgeIter, T, D, Cat >, EdgeIter, T, D >, + edge_list_impl< edge_list< EdgeIter, T, D, Cat >, EdgeIter, T, D > >::type +{ +public: typedef directed_tag directed_category; typedef allow_parallel_edge_tag edge_parallel_category; typedef edge_list_graph_tag traversal_category; typedef std::size_t edges_size_type; typedef std::size_t vertices_size_type; typedef std::size_t degree_size_type; - edge_list(EdgeIter first, EdgeIter last) : _first(first), _last(last) { - m_num_edges = std::distance(first, last); + edge_list(EdgeIter first, EdgeIter last) : _first(first), _last(last) + { + m_num_edges = std::distance(first, last); } edge_list(EdgeIter first, EdgeIter last, edges_size_type E) - : _first(first), _last(last), m_num_edges(E) { } + : _first(first), _last(last), m_num_edges(E) + { + } EdgeIter _first, _last; edges_size_type m_num_edges; - }; +}; - template - std::size_t num_edges(const edge_list& el) { +template < class EdgeIter, class T, class D, class Cat > +std::size_t num_edges(const edge_list< EdgeIter, T, D, Cat >& el) +{ return el.m_num_edges; - } +} #ifndef BOOST_NO_STD_ITERATOR_TRAITS - template - inline edge_list - make_edge_list(EdgeIter first, EdgeIter last) - { - return edge_list(first, last); - } +template < class EdgeIter > +inline edge_list< EdgeIter > make_edge_list(EdgeIter first, EdgeIter last) +{ + return edge_list< EdgeIter >(first, last); +} #endif } /* namespace boost */ diff --git a/include/boost/graph/edmonds_karp_max_flow.hpp b/include/boost/graph/edmonds_karp_max_flow.hpp index 377e6f14d..e67f0fffc 100644 --- a/include/boost/graph/edmonds_karp_max_flow.hpp +++ b/include/boost/graph/edmonds_karp_max_flow.hpp @@ -21,228 +21,224 @@ #include #include -namespace boost { +namespace boost +{ - // The "labeling" algorithm from "Network Flows" by Ahuja, Magnanti, - // Orlin. I think this is the same as or very similar to the original - // Edmonds-Karp algorithm. This solves the maximum flow problem. +// The "labeling" algorithm from "Network Flows" by Ahuja, Magnanti, +// Orlin. I think this is the same as or very similar to the original +// Edmonds-Karp algorithm. This solves the maximum flow problem. - namespace detail { +namespace detail +{ - template - filtered_graph > - residual_graph(Graph& g, ResCapMap residual_capacity) { - return filtered_graph > - (g, is_residual_edge(residual_capacity)); + template < class Graph, class ResCapMap > + filtered_graph< Graph, is_residual_edge< ResCapMap > > residual_graph( + Graph& g, ResCapMap residual_capacity) + { + return filtered_graph< Graph, is_residual_edge< ResCapMap > >( + g, is_residual_edge< ResCapMap >(residual_capacity)); } - template - inline void - augment(Graph& g, - typename graph_traits::vertex_descriptor src, - typename graph_traits::vertex_descriptor sink, - PredEdgeMap p, - ResCapMap residual_capacity, - RevEdgeMap reverse_edge) + template < class Graph, class PredEdgeMap, class ResCapMap, + class RevEdgeMap > + inline void augment(Graph& g, + typename graph_traits< Graph >::vertex_descriptor src, + typename graph_traits< Graph >::vertex_descriptor sink, PredEdgeMap p, + ResCapMap residual_capacity, RevEdgeMap reverse_edge) { - typename graph_traits::edge_descriptor e; - typename graph_traits::vertex_descriptor u; - typedef typename property_traits::value_type FlowValue; - - // find minimum residual capacity along the augmenting path - FlowValue delta = (std::numeric_limits::max)(); - e = get(p, sink); - do { - BOOST_USING_STD_MIN(); - delta = min BOOST_PREVENT_MACRO_SUBSTITUTION(delta, get(residual_capacity, e)); - u = source(e, g); - e = get(p, u); - } while (u != src); - - // push delta units of flow along the augmenting path - e = get(p, sink); - do { - put(residual_capacity, e, get(residual_capacity, e) - delta); - put(residual_capacity, get(reverse_edge, e), get(residual_capacity, get(reverse_edge, e)) + delta); - u = source(e, g); - e = get(p, u); - } while (u != src); + typename graph_traits< Graph >::edge_descriptor e; + typename graph_traits< Graph >::vertex_descriptor u; + typedef typename property_traits< ResCapMap >::value_type FlowValue; + + // find minimum residual capacity along the augmenting path + FlowValue delta = (std::numeric_limits< FlowValue >::max)(); + e = get(p, sink); + do + { + BOOST_USING_STD_MIN(); + delta = min BOOST_PREVENT_MACRO_SUBSTITUTION( + delta, get(residual_capacity, e)); + u = source(e, g); + e = get(p, u); + } while (u != src); + + // push delta units of flow along the augmenting path + e = get(p, sink); + do + { + put(residual_capacity, e, get(residual_capacity, e) - delta); + put(residual_capacity, get(reverse_edge, e), + get(residual_capacity, get(reverse_edge, e)) + delta); + u = source(e, g); + e = get(p, u); + } while (u != src); } - } // namespace detail - - template - typename property_traits::value_type - edmonds_karp_max_flow - (Graph& g, - typename graph_traits::vertex_descriptor src, - typename graph_traits::vertex_descriptor sink, - CapacityEdgeMap cap, - ResidualCapacityEdgeMap res, - ReverseEdgeMap rev, - ColorMap color, - PredEdgeMap pred) - { - typedef typename graph_traits::vertex_descriptor vertex_t; - typedef typename property_traits::value_type ColorValue; - typedef color_traits Color; - - typename graph_traits::vertex_iterator u_iter, u_end; - typename graph_traits::out_edge_iterator ei, e_end; +} // namespace detail + +template < class Graph, class CapacityEdgeMap, class ResidualCapacityEdgeMap, + class ReverseEdgeMap, class ColorMap, class PredEdgeMap > +typename property_traits< CapacityEdgeMap >::value_type edmonds_karp_max_flow( + Graph& g, typename graph_traits< Graph >::vertex_descriptor src, + typename graph_traits< Graph >::vertex_descriptor sink, CapacityEdgeMap cap, + ResidualCapacityEdgeMap res, ReverseEdgeMap rev, ColorMap color, + PredEdgeMap pred) +{ + typedef typename graph_traits< Graph >::vertex_descriptor vertex_t; + typedef typename property_traits< ColorMap >::value_type ColorValue; + typedef color_traits< ColorValue > Color; + + typename graph_traits< Graph >::vertex_iterator u_iter, u_end; + typename graph_traits< Graph >::out_edge_iterator ei, e_end; for (boost::tie(u_iter, u_end) = vertices(g); u_iter != u_end; ++u_iter) - for (boost::tie(ei, e_end) = out_edges(*u_iter, g); ei != e_end; ++ei) - put(res, *ei, get(cap, *ei)); - + for (boost::tie(ei, e_end) = out_edges(*u_iter, g); ei != e_end; ++ei) + put(res, *ei, get(cap, *ei)); + put(color, sink, Color::gray()); - while (get(color, sink) != Color::white()) { - boost::queue Q; - breadth_first_search - (detail::residual_graph(g, res), src, Q, - make_bfs_visitor(record_edge_predecessors(pred, on_tree_edge())), - color); - if (get(color, sink) != Color::white()) - detail::augment(g, src, sink, pred, res, rev); + while (get(color, sink) != Color::white()) + { + boost::queue< vertex_t > Q; + breadth_first_search(detail::residual_graph(g, res), src, Q, + make_bfs_visitor(record_edge_predecessors(pred, on_tree_edge())), + color); + if (get(color, sink) != Color::white()) + detail::augment(g, src, sink, pred, res, rev); } // while - - typename property_traits::value_type flow = 0; + + typename property_traits< CapacityEdgeMap >::value_type flow = 0; for (boost::tie(ei, e_end) = out_edges(src, g); ei != e_end; ++ei) - flow += (get(cap, *ei) - get(res, *ei)); + flow += (get(cap, *ei) - get(res, *ei)); return flow; - } // edmonds_karp_max_flow() - - namespace detail { +} // edmonds_karp_max_flow() + +namespace detail +{ //------------------------------------------------------------------------- // Handle default for color property map // use of class here is a VC++ workaround - template - struct edmonds_karp_dispatch2 { - template - static typename edge_capacity_value::type - apply - (Graph& g, - typename graph_traits::vertex_descriptor src, - typename graph_traits::vertex_descriptor sink, - PredMap pred, - const bgl_named_params& params, - ColorMap color) - { - return edmonds_karp_max_flow - (g, src, sink, - choose_const_pmap(get_param(params, edge_capacity), g, edge_capacity), - choose_pmap(get_param(params, edge_residual_capacity), - g, edge_residual_capacity), - choose_const_pmap(get_param(params, edge_reverse), g, edge_reverse), - color, pred); - } + template < class ColorMap > struct edmonds_karp_dispatch2 + { + template < class Graph, class PredMap, class P, class T, class R > + static typename edge_capacity_value< Graph, P, T, R >::type apply( + Graph& g, typename graph_traits< Graph >::vertex_descriptor src, + typename graph_traits< Graph >::vertex_descriptor sink, + PredMap pred, const bgl_named_params< P, T, R >& params, + ColorMap color) + { + return edmonds_karp_max_flow(g, src, sink, + choose_const_pmap( + get_param(params, edge_capacity), g, edge_capacity), + choose_pmap(get_param(params, edge_residual_capacity), g, + edge_residual_capacity), + choose_const_pmap( + get_param(params, edge_reverse), g, edge_reverse), + color, pred); + } }; - template<> - struct edmonds_karp_dispatch2 { - template - static typename edge_capacity_value::type - apply - (Graph& g, - typename graph_traits::vertex_descriptor src, - typename graph_traits::vertex_descriptor sink, - PredMap pred, - const bgl_named_params& params, - param_not_found) - { - typedef typename graph_traits::vertices_size_type size_type; - size_type n = is_default_param(get_param(params, vertex_color)) ? - num_vertices(g) : 1; - std::vector color_vec(n); - return edmonds_karp_max_flow - (g, src, sink, - choose_const_pmap(get_param(params, edge_capacity), g, edge_capacity), - choose_pmap(get_param(params, edge_residual_capacity), - g, edge_residual_capacity), - choose_const_pmap(get_param(params, edge_reverse), g, edge_reverse), - make_iterator_property_map(color_vec.begin(), choose_const_pmap - (get_param(params, vertex_index), - g, vertex_index), color_vec[0]), - pred); - } + template <> struct edmonds_karp_dispatch2< param_not_found > + { + template < class Graph, class PredMap, class P, class T, class R > + static typename edge_capacity_value< Graph, P, T, R >::type apply( + Graph& g, typename graph_traits< Graph >::vertex_descriptor src, + typename graph_traits< Graph >::vertex_descriptor sink, + PredMap pred, const bgl_named_params< P, T, R >& params, + param_not_found) + { + typedef + typename graph_traits< Graph >::vertices_size_type size_type; + size_type n = is_default_param(get_param(params, vertex_color)) + ? num_vertices(g) + : 1; + std::vector< default_color_type > color_vec(n); + return edmonds_karp_max_flow(g, src, sink, + choose_const_pmap( + get_param(params, edge_capacity), g, edge_capacity), + choose_pmap(get_param(params, edge_residual_capacity), g, + edge_residual_capacity), + choose_const_pmap( + get_param(params, edge_reverse), g, edge_reverse), + make_iterator_property_map(color_vec.begin(), + choose_const_pmap( + get_param(params, vertex_index), g, vertex_index), + color_vec[0]), + pred); + } }; //------------------------------------------------------------------------- // Handle default for predecessor property map // use of class here is a VC++ workaround - template - struct edmonds_karp_dispatch1 { - template - static typename edge_capacity_value::type - apply(Graph& g, - typename graph_traits::vertex_descriptor src, - typename graph_traits::vertex_descriptor sink, - const bgl_named_params& params, - PredMap pred) - { - typedef typename get_param_type< vertex_color_t, bgl_named_params >::type C; - return edmonds_karp_dispatch2::apply - (g, src, sink, pred, params, get_param(params, vertex_color)); - } + template < class PredMap > struct edmonds_karp_dispatch1 + { + template < class Graph, class P, class T, class R > + static typename edge_capacity_value< Graph, P, T, R >::type apply( + Graph& g, typename graph_traits< Graph >::vertex_descriptor src, + typename graph_traits< Graph >::vertex_descriptor sink, + const bgl_named_params< P, T, R >& params, PredMap pred) + { + typedef typename get_param_type< vertex_color_t, + bgl_named_params< P, T, R > >::type C; + return edmonds_karp_dispatch2< C >::apply( + g, src, sink, pred, params, get_param(params, vertex_color)); + } }; - template<> - struct edmonds_karp_dispatch1 { - - template - static typename edge_capacity_value::type - apply - (Graph& g, - typename graph_traits::vertex_descriptor src, - typename graph_traits::vertex_descriptor sink, - const bgl_named_params& params, - param_not_found) - { - typedef typename graph_traits::edge_descriptor edge_descriptor; - typedef typename graph_traits::vertices_size_type size_type; - size_type n = is_default_param(get_param(params, vertex_predecessor)) ? - num_vertices(g) : 1; - std::vector pred_vec(n); - - typedef typename get_param_type< vertex_color_t, bgl_named_params >::type C; - return edmonds_karp_dispatch2::apply - (g, src, sink, - make_iterator_property_map(pred_vec.begin(), choose_const_pmap - (get_param(params, vertex_index), - g, vertex_index), pred_vec[0]), - params, - get_param(params, vertex_color)); - } + template <> struct edmonds_karp_dispatch1< param_not_found > + { + + template < class Graph, class P, class T, class R > + static typename edge_capacity_value< Graph, P, T, R >::type apply( + Graph& g, typename graph_traits< Graph >::vertex_descriptor src, + typename graph_traits< Graph >::vertex_descriptor sink, + const bgl_named_params< P, T, R >& params, param_not_found) + { + typedef + typename graph_traits< Graph >::edge_descriptor edge_descriptor; + typedef + typename graph_traits< Graph >::vertices_size_type size_type; + size_type n + = is_default_param(get_param(params, vertex_predecessor)) + ? num_vertices(g) + : 1; + std::vector< edge_descriptor > pred_vec(n); + + typedef typename get_param_type< vertex_color_t, + bgl_named_params< P, T, R > >::type C; + return edmonds_karp_dispatch2< C >::apply(g, src, sink, + make_iterator_property_map(pred_vec.begin(), + choose_const_pmap( + get_param(params, vertex_index), g, vertex_index), + pred_vec[0]), + params, get_param(params, vertex_color)); + } }; - - } // namespace detail - - template - typename detail::edge_capacity_value::type - edmonds_karp_max_flow - (Graph& g, - typename graph_traits::vertex_descriptor src, - typename graph_traits::vertex_descriptor sink, - const bgl_named_params& params) - { - typedef typename get_param_type< vertex_predecessor_t, bgl_named_params >::type Pred; - return detail::edmonds_karp_dispatch1::apply - (g, src, sink, params, get_param(params, vertex_predecessor)); - } - - template - typename property_traits< - typename property_map::const_type - >::value_type - edmonds_karp_max_flow - (Graph& g, - typename graph_traits::vertex_descriptor src, - typename graph_traits::vertex_descriptor sink) - { - bgl_named_params params(0); + +} // namespace detail + +template < class Graph, class P, class T, class R > +typename detail::edge_capacity_value< Graph, P, T, R >::type +edmonds_karp_max_flow(Graph& g, + typename graph_traits< Graph >::vertex_descriptor src, + typename graph_traits< Graph >::vertex_descriptor sink, + const bgl_named_params< P, T, R >& params) +{ + typedef typename get_param_type< vertex_predecessor_t, + bgl_named_params< P, T, R > >::type Pred; + return detail::edmonds_karp_dispatch1< Pred >::apply( + g, src, sink, params, get_param(params, vertex_predecessor)); +} + +template < class Graph > +typename property_traits< + typename property_map< Graph, edge_capacity_t >::const_type >::value_type +edmonds_karp_max_flow(Graph& g, + typename graph_traits< Graph >::vertex_descriptor src, + typename graph_traits< Graph >::vertex_descriptor sink) +{ + bgl_named_params< int, buffer_param_t > params(0); return edmonds_karp_max_flow(g, src, sink, params); - } +} } // namespace boost diff --git a/include/boost/graph/edmunds_karp_max_flow.hpp b/include/boost/graph/edmunds_karp_max_flow.hpp index 3697db208..c5ff7ec17 100644 --- a/include/boost/graph/edmunds_karp_max_flow.hpp +++ b/include/boost/graph/edmunds_karp_max_flow.hpp @@ -9,9 +9,12 @@ #define BOOST_DEPRECATED_INCLUDE_EDMONDS_KARP_MAX_FLOW_HPP #if defined(_MSC_VER) || defined(__BORLANDC__) || defined(__DMC__) -# pragma message ("Warning: This header is deprecated. Please use: boost/graph/edmonds_karp_max_flow.hpp") -#elif defined(__GNUC__) || defined(__HP_aCC) || defined(__SUNPRO_CC) || defined(__IBMCPP__) -# warning "This header is deprecated. Please use: boost/graph/edmonds_karp_max_flow.hpp" +#pragma message( \ + "Warning: This header is deprecated. Please use: boost/graph/edmonds_karp_max_flow.hpp") +#elif defined(__GNUC__) || defined(__HP_aCC) || defined(__SUNPRO_CC) \ + || defined(__IBMCPP__) +#warning \ + "This header is deprecated. Please use: boost/graph/edmonds_karp_max_flow.hpp" #endif #include diff --git a/include/boost/graph/erdos_renyi_generator.hpp b/include/boost/graph/erdos_renyi_generator.hpp index 5be06d79d..f5e33c963 100644 --- a/include/boost/graph/erdos_renyi_generator.hpp +++ b/include/boost/graph/erdos_renyi_generator.hpp @@ -22,173 +22,199 @@ #include #include -namespace boost { - - template - class erdos_renyi_iterator - : public iterator_facade< - erdos_renyi_iterator, - std::pair::vertices_size_type, - typename graph_traits::vertices_size_type>, - std::input_iterator_tag, - const - std::pair::vertices_size_type, - typename graph_traits::vertices_size_type>&> - { - typedef typename graph_traits::directed_category directed_category; - typedef typename graph_traits::vertices_size_type vertices_size_type; - typedef typename graph_traits::edges_size_type edges_size_type; - - BOOST_STATIC_CONSTANT - (bool, - is_undirected = (is_base_of::value)); - - public: +namespace boost +{ + +template < typename RandomGenerator, typename Graph > +class erdos_renyi_iterator +: public iterator_facade< erdos_renyi_iterator< RandomGenerator, Graph >, + std::pair< typename graph_traits< Graph >::vertices_size_type, + typename graph_traits< Graph >::vertices_size_type >, + std::input_iterator_tag, + const std::pair< typename graph_traits< Graph >::vertices_size_type, + typename graph_traits< Graph >::vertices_size_type >& > +{ + typedef typename graph_traits< Graph >::directed_category directed_category; + typedef + typename graph_traits< Graph >::vertices_size_type vertices_size_type; + typedef typename graph_traits< Graph >::edges_size_type edges_size_type; + + BOOST_STATIC_CONSTANT(bool, + is_undirected + = (is_base_of< undirected_tag, directed_category >::value)); + +public: erdos_renyi_iterator() : gen(), n(0), edges(0), allow_self_loops(false) {} erdos_renyi_iterator(RandomGenerator& gen, vertices_size_type n, - double fraction = 0.0, bool allow_self_loops = false) - : gen(&gen), n(n), edges(edges_size_type(fraction * n * n)), - allow_self_loops(allow_self_loops) + double fraction = 0.0, bool allow_self_loops = false) + : gen(&gen) + , n(n) + , edges(edges_size_type(fraction * n * n)) + , allow_self_loops(allow_self_loops) { - if (is_undirected) edges = edges / 2; - next(); + if (is_undirected) + edges = edges / 2; + next(); } erdos_renyi_iterator(RandomGenerator& gen, vertices_size_type n, - edges_size_type m, bool allow_self_loops = false) - : gen(&gen), n(n), edges(m), - allow_self_loops(allow_self_loops) + edges_size_type m, bool allow_self_loops = false) + : gen(&gen), n(n), edges(m), allow_self_loops(allow_self_loops) { - next(); + next(); } - const std::pair& - dereference() const { return current; } + const std::pair< vertices_size_type, vertices_size_type >& + dereference() const + { + return current; + } - void increment() { - --edges; - next(); + void increment() + { + --edges; + next(); } bool equal(const erdos_renyi_iterator& other) const - { return edges == other.edges; } + { + return edges == other.edges; + } - private: +private: void next() { - uniform_int rand_vertex(0, n-1); - current.first = rand_vertex(*gen); - do { - current.second = rand_vertex(*gen); - } while (current.first == current.second && !allow_self_loops); + uniform_int< vertices_size_type > rand_vertex(0, n - 1); + current.first = rand_vertex(*gen); + do + { + current.second = rand_vertex(*gen); + } while (current.first == current.second && !allow_self_loops); } RandomGenerator* gen; vertices_size_type n; edges_size_type edges; bool allow_self_loops; - std::pair current; - }; - - template - class sorted_erdos_renyi_iterator - : public iterator_facade< - sorted_erdos_renyi_iterator, - std::pair::vertices_size_type, - typename graph_traits::vertices_size_type>, - std::input_iterator_tag, - const - std::pair::vertices_size_type, - typename graph_traits::vertices_size_type>&> - { - typedef typename graph_traits::directed_category directed_category; - typedef typename graph_traits::vertices_size_type vertices_size_type; - typedef typename graph_traits::edges_size_type edges_size_type; - - BOOST_STATIC_CONSTANT - (bool, - is_undirected = (is_base_of::value)); - - public: + std::pair< vertices_size_type, vertices_size_type > current; +}; + +template < typename RandomGenerator, typename Graph > +class sorted_erdos_renyi_iterator +: public iterator_facade< sorted_erdos_renyi_iterator< RandomGenerator, Graph >, + std::pair< typename graph_traits< Graph >::vertices_size_type, + typename graph_traits< Graph >::vertices_size_type >, + std::input_iterator_tag, + const std::pair< typename graph_traits< Graph >::vertices_size_type, + typename graph_traits< Graph >::vertices_size_type >& > +{ + typedef typename graph_traits< Graph >::directed_category directed_category; + typedef + typename graph_traits< Graph >::vertices_size_type vertices_size_type; + typedef typename graph_traits< Graph >::edges_size_type edges_size_type; + + BOOST_STATIC_CONSTANT(bool, + is_undirected + = (is_base_of< undirected_tag, directed_category >::value)); + +public: sorted_erdos_renyi_iterator() - : gen(), rand_vertex(0.5), n(0), allow_self_loops(false) - , src((std::numeric_limits::max)()), - tgt_index(vertices_size_type(-1)), prob(.5) - { } + : gen() + , rand_vertex(0.5) + , n(0) + , allow_self_loops(false) + , src((std::numeric_limits< vertices_size_type >::max)()) + , tgt_index(vertices_size_type(-1)) + , prob(.5) + { + } // NOTE: The default probability has been changed to be the same as that // used by the geometic distribution. It was previously 0.0, which would // cause an assertion. sorted_erdos_renyi_iterator(RandomGenerator& gen, vertices_size_type n, - double prob = 0.5, - bool loops = false) - : gen(), rand_vertex(1. - prob), n(n), allow_self_loops(loops), src(0) - , tgt_index(vertices_size_type(-1)), prob(prob) + double prob = 0.5, bool loops = false) + : gen() + , rand_vertex(1. - prob) + , n(n) + , allow_self_loops(loops) + , src(0) + , tgt_index(vertices_size_type(-1)) + , prob(prob) { - this->gen.reset(new uniform_01(&gen)); + this->gen.reset(new uniform_01< RandomGenerator* >(&gen)); - if (prob == 0.0) {src = (std::numeric_limits::max)(); return;} - next(); + if (prob == 0.0) + { + src = (std::numeric_limits< vertices_size_type >::max)(); + return; + } + next(); } - const std::pair& - dereference() const { - return current; + const std::pair< vertices_size_type, vertices_size_type >& + dereference() const + { + return current; } - bool equal(const sorted_erdos_renyi_iterator& o) const { - return src == o.src && tgt_index == o.tgt_index; + bool equal(const sorted_erdos_renyi_iterator& o) const + { + return src == o.src && tgt_index == o.tgt_index; } - void increment() { - next(); - } + void increment() { next(); } - private: +private: void next() { - // In order to get the edges from the generator in sorted order, one - // effective (but slow) procedure would be to use a - // bernoulli_distribution for each legal (src, tgt_index) pair. Because of - // the O(|V|^2) cost of that, a geometric distribution is used. The - // geometric distribution tells how many times the - // bernoulli_distribution would need to be run until it returns true. - // Thus, this distribution can be used to step through the edges - // which are actually present. - BOOST_ASSERT (src != (std::numeric_limits::max)() && - src != n); - while (src != n) { - vertices_size_type increment = rand_vertex(*gen); - size_t tgt_index_limit = - (is_undirected ? src + 1 : n) + - (allow_self_loops ? 0 : -1); - if (tgt_index + increment >= tgt_index_limit) { - // Overflowed this source; go to the next one and try again. - ++src; - // This bias is because the geometric distribution always returns - // values >=1, and we want to allow 0 as a valid target. - tgt_index = vertices_size_type(-1); - continue; - } else { - tgt_index += increment; - current.first = src; - current.second = - tgt_index + - (!allow_self_loops && !is_undirected && tgt_index >= src ? 1 : 0); - break; + // In order to get the edges from the generator in sorted order, one + // effective (but slow) procedure would be to use a + // bernoulli_distribution for each legal (src, tgt_index) pair. Because + // of the O(|V|^2) cost of that, a geometric distribution is used. The + // geometric distribution tells how many times the + // bernoulli_distribution would need to be run until it returns true. + // Thus, this distribution can be used to step through the edges + // which are actually present. + BOOST_ASSERT(src != (std::numeric_limits< vertices_size_type >::max)() + && src != n); + while (src != n) + { + vertices_size_type increment = rand_vertex(*gen); + size_t tgt_index_limit + = (is_undirected ? src + 1 : n) + (allow_self_loops ? 0 : -1); + if (tgt_index + increment >= tgt_index_limit) + { + // Overflowed this source; go to the next one and try again. + ++src; + // This bias is because the geometric distribution always + // returns values >=1, and we want to allow 0 as a valid target. + tgt_index = vertices_size_type(-1); + continue; + } + else + { + tgt_index += increment; + current.first = src; + current.second = tgt_index + + (!allow_self_loops && !is_undirected && tgt_index >= src + ? 1 + : 0); + break; + } } - } - if (src == n) src = (std::numeric_limits::max)(); + if (src == n) + src = (std::numeric_limits< vertices_size_type >::max)(); } - shared_ptr > gen; - geometric_distribution rand_vertex; + shared_ptr< uniform_01< RandomGenerator* > > gen; + geometric_distribution< vertices_size_type > rand_vertex; vertices_size_type n; bool allow_self_loops; vertices_size_type src, tgt_index; - std::pair current; + std::pair< vertices_size_type, vertices_size_type > current; double prob; - }; +}; } // end namespace boost diff --git a/include/boost/graph/exception.hpp b/include/boost/graph/exception.hpp index f1f13dcf8..81323a361 100644 --- a/include/boost/graph/exception.hpp +++ b/include/boost/graph/exception.hpp @@ -13,42 +13,43 @@ #include #include -namespace boost { - - struct BOOST_SYMBOL_VISIBLE bad_graph : public std::invalid_argument { - bad_graph(const std::string& what_arg) - : std::invalid_argument(what_arg) { } - }; - - struct BOOST_SYMBOL_VISIBLE not_a_dag : public bad_graph { - not_a_dag() - : bad_graph("The graph must be a DAG.") - { } - }; - - struct BOOST_SYMBOL_VISIBLE negative_edge : public bad_graph { - negative_edge() - : bad_graph("The graph may not contain an edge with negative weight.") - { } - }; - - struct BOOST_SYMBOL_VISIBLE negative_cycle : public bad_graph { - negative_cycle() - : bad_graph("The graph may not contain negative cycles.") - { } - }; - - struct BOOST_SYMBOL_VISIBLE not_connected : public bad_graph { - not_connected() - : bad_graph("The graph must be connected.") - { } - }; - - struct BOOST_SYMBOL_VISIBLE not_complete : public bad_graph { - not_complete() - : bad_graph("The graph must be complete.") - { } - }; +namespace boost +{ + +struct BOOST_SYMBOL_VISIBLE bad_graph : public std::invalid_argument +{ + bad_graph(const std::string& what_arg) : std::invalid_argument(what_arg) {} +}; + +struct BOOST_SYMBOL_VISIBLE not_a_dag : public bad_graph +{ + not_a_dag() : bad_graph("The graph must be a DAG.") {} +}; + +struct BOOST_SYMBOL_VISIBLE negative_edge : public bad_graph +{ + negative_edge() + : bad_graph("The graph may not contain an edge with negative weight.") + { + } +}; + +struct BOOST_SYMBOL_VISIBLE negative_cycle : public bad_graph +{ + negative_cycle() : bad_graph("The graph may not contain negative cycles.") + { + } +}; + +struct BOOST_SYMBOL_VISIBLE not_connected : public bad_graph +{ + not_connected() : bad_graph("The graph must be connected.") {} +}; + +struct BOOST_SYMBOL_VISIBLE not_complete : public bad_graph +{ + not_complete() : bad_graph("The graph must be complete.") {} +}; } // namespace boost diff --git a/include/boost/graph/exterior_property.hpp b/include/boost/graph/exterior_property.hpp index f920939f3..281b7bb2a 100644 --- a/include/boost/graph/exterior_property.hpp +++ b/include/boost/graph/exterior_property.hpp @@ -11,15 +11,16 @@ #include #include -namespace boost { -namespace detail { +namespace boost +{ +namespace detail +{ // The vector matrix provides a little abstraction over vector // types that makes matrices easier to work with. - template - struct vector_matrix + template < typename Value > struct vector_matrix { - typedef std::vector container_type; - typedef std::vector matrix_type; + typedef std::vector< Value > container_type; + typedef std::vector< container_type > matrix_type; typedef container_type value_type; typedef container_type& reference; @@ -30,15 +31,14 @@ namespace detail { // Instantiate the matrix over n elements (creates an n by n matrix). // The graph has to be passed in order to ensure the index maps // are constructed correctly when returning indexible elements. - inline vector_matrix(size_type n) - : m_matrix(n, container_type(n)) - { } + inline vector_matrix(size_type n) : m_matrix(n, container_type(n)) {} - inline reference operator [](size_type n) - { return m_matrix[n]; } + inline reference operator[](size_type n) { return m_matrix[n]; } - inline const_reference operator [](size_type n) const - { return m_matrix[n]; } + inline const_reference operator[](size_type n) const + { + return m_matrix[n]; + } matrix_type m_matrix; }; @@ -56,21 +56,21 @@ namespace detail { * solution should not be especially difficult, but will require an extension * of type traits to affect the type selection. */ -template +template < typename Graph, typename Key, typename Value > struct exterior_property { typedef Key key_type; typedef Value value_type; - typedef std::vector container_type; - typedef container_property_map map_type; + typedef std::vector< Value > container_type; + typedef container_property_map< Graph, Key, container_type > map_type; - typedef detail::vector_matrix matrix_type; - typedef matrix_property_map matrix_map_type; + typedef detail::vector_matrix< Value > matrix_type; + typedef matrix_property_map< Graph, Key, matrix_type > matrix_map_type; private: - exterior_property() { } - exterior_property(const exterior_property&) { } + exterior_property() {} + exterior_property(const exterior_property&) {} }; /** @@ -78,12 +78,11 @@ struct exterior_property * vertex property for the given value type. The Graph parameter is required to * model the VertexIndexGraph concept. */ -template -struct exterior_vertex_property +template < typename Graph, typename Value > struct exterior_vertex_property { - typedef exterior_property< - Graph, typename graph_traits::vertex_descriptor, Value - > property_type; + typedef exterior_property< Graph, + typename graph_traits< Graph >::vertex_descriptor, Value > + property_type; typedef typename property_type::key_type key_type; typedef typename property_type::value_type value_type; typedef typename property_type::container_type container_type; @@ -97,12 +96,11 @@ struct exterior_vertex_property * edge property for the given value type. The Graph parameter is required to * model the EdgeIndexGraph concept. */ -template -struct exterior_edge_property +template < typename Graph, typename Value > struct exterior_edge_property { - typedef exterior_property< - Graph, typename graph_traits::edge_descriptor, Value - > property_type; + typedef exterior_property< Graph, + typename graph_traits< Graph >::edge_descriptor, Value > + property_type; typedef typename property_type::key_type key_type; typedef typename property_type::value_type value_type; typedef typename property_type::container_type container_type; diff --git a/include/boost/graph/filtered_graph.hpp b/include/boost/graph/filtered_graph.hpp index 5426eac6f..05d65b806 100644 --- a/include/boost/graph/filtered_graph.hpp +++ b/include/boost/graph/filtered_graph.hpp @@ -16,545 +16,576 @@ #include #include -namespace boost { - - //========================================================================= - // Some predicate classes. - - struct keep_all { - template - bool operator()(const T&) const { return true; } - }; - - // Keep residual edges (used in maximum-flow algorithms). - template - struct is_residual_edge { - is_residual_edge() { } - is_residual_edge(ResidualCapacityEdgeMap rcap) : m_rcap(rcap) { } - template - bool operator()(const Edge& e) const { - return 0 < get(m_rcap, e); +namespace boost +{ + +//========================================================================= +// Some predicate classes. + +struct keep_all +{ + template < typename T > bool operator()(const T&) const { return true; } +}; + +// Keep residual edges (used in maximum-flow algorithms). +template < typename ResidualCapacityEdgeMap > struct is_residual_edge +{ + is_residual_edge() {} + is_residual_edge(ResidualCapacityEdgeMap rcap) : m_rcap(rcap) {} + template < typename Edge > bool operator()(const Edge& e) const + { + return 0 < get(m_rcap, e); } ResidualCapacityEdgeMap m_rcap; - }; +}; - template - struct is_in_subset { - is_in_subset() : m_s(0) { } - is_in_subset(const Set& s) : m_s(&s) { } +template < typename Set > struct is_in_subset +{ + is_in_subset() : m_s(0) {} + is_in_subset(const Set& s) : m_s(&s) {} - template - bool operator()(const Elt& x) const { - return set_contains(*m_s, x); + template < typename Elt > bool operator()(const Elt& x) const + { + return set_contains(*m_s, x); } const Set* m_s; - }; +}; - template - struct is_not_in_subset { - is_not_in_subset() : m_s(0) { } - is_not_in_subset(const Set& s) : m_s(&s) { } +template < typename Set > struct is_not_in_subset +{ + is_not_in_subset() : m_s(0) {} + is_not_in_subset(const Set& s) : m_s(&s) {} - template - bool operator()(const Elt& x) const { - return !set_contains(*m_s, x); + template < typename Elt > bool operator()(const Elt& x) const + { + return !set_contains(*m_s, x); } const Set* m_s; - }; - - namespace detail { - - template - struct out_edge_predicate { - out_edge_predicate() { } - out_edge_predicate(EdgePredicate ep, VertexPredicate vp, - const Graph& g) - : m_edge_pred(ep), m_vertex_pred(vp), m_g(&g) { } - - template - bool operator()(const Edge& e) const { - return m_edge_pred(e) && m_vertex_pred(target(e, *m_g)); - } - EdgePredicate m_edge_pred; - VertexPredicate m_vertex_pred; - const Graph* m_g; - }; +}; - template - struct in_edge_predicate { - in_edge_predicate() { } - in_edge_predicate(EdgePredicate ep, VertexPredicate vp, - const Graph& g) - : m_edge_pred(ep), m_vertex_pred(vp), m_g(&g) { } - - template - bool operator()(const Edge& e) const { - return m_edge_pred(e) && m_vertex_pred(source(e, *m_g)); - } - EdgePredicate m_edge_pred; - VertexPredicate m_vertex_pred; - const Graph* m_g; - }; +namespace detail +{ - template - struct edge_predicate { - edge_predicate() { } - edge_predicate(EdgePredicate ep, VertexPredicate vp, - const Graph& g) - : m_edge_pred(ep), m_vertex_pred(vp), m_g(&g) { } - - template - bool operator()(const Edge& e) const { - return m_edge_pred(e) - && m_vertex_pred(source(e, *m_g)) && m_vertex_pred(target(e, *m_g)); - } - EdgePredicate m_edge_pred; - VertexPredicate m_vertex_pred; - const Graph* m_g; + template < typename EdgePredicate, typename VertexPredicate, + typename Graph > + struct out_edge_predicate + { + out_edge_predicate() {} + out_edge_predicate(EdgePredicate ep, VertexPredicate vp, const Graph& g) + : m_edge_pred(ep), m_vertex_pred(vp), m_g(&g) + { + } + + template < typename Edge > bool operator()(const Edge& e) const + { + return m_edge_pred(e) && m_vertex_pred(target(e, *m_g)); + } + EdgePredicate m_edge_pred; + VertexPredicate m_vertex_pred; + const Graph* m_g; }; - } // namespace detail - - - //=========================================================================== - // Filtered Graph + template < typename EdgePredicate, typename VertexPredicate, + typename Graph > + struct in_edge_predicate + { + in_edge_predicate() {} + in_edge_predicate(EdgePredicate ep, VertexPredicate vp, const Graph& g) + : m_edge_pred(ep), m_vertex_pred(vp), m_g(&g) + { + } + + template < typename Edge > bool operator()(const Edge& e) const + { + return m_edge_pred(e) && m_vertex_pred(source(e, *m_g)); + } + EdgePredicate m_edge_pred; + VertexPredicate m_vertex_pred; + const Graph* m_g; + }; - struct filtered_graph_tag { }; + template < typename EdgePredicate, typename VertexPredicate, + typename Graph > + struct edge_predicate + { + edge_predicate() {} + edge_predicate(EdgePredicate ep, VertexPredicate vp, const Graph& g) + : m_edge_pred(ep), m_vertex_pred(vp), m_g(&g) + { + } + + template < typename Edge > bool operator()(const Edge& e) const + { + return m_edge_pred(e) && m_vertex_pred(source(e, *m_g)) + && m_vertex_pred(target(e, *m_g)); + } + EdgePredicate m_edge_pred; + VertexPredicate m_vertex_pred; + const Graph* m_g; + }; - // This base class is a stupid hack to change overload resolution - // rules for the source and target functions so that they are a - // worse match than the source and target functions defined for - // pairs in graph_traits.hpp. I feel dirty. -JGS - template - struct filtered_graph_base { - typedef graph_traits Traits; - typedef typename Traits::vertex_descriptor vertex_descriptor; - typedef typename Traits::edge_descriptor edge_descriptor; - filtered_graph_base(const G& g) : m_g(g) { } - //protected: +} // namespace detail + +//=========================================================================== +// Filtered Graph + +struct filtered_graph_tag +{ +}; + +// This base class is a stupid hack to change overload resolution +// rules for the source and target functions so that they are a +// worse match than the source and target functions defined for +// pairs in graph_traits.hpp. I feel dirty. -JGS +template < class G > struct filtered_graph_base +{ + typedef graph_traits< G > Traits; + typedef typename Traits::vertex_descriptor vertex_descriptor; + typedef typename Traits::edge_descriptor edge_descriptor; + filtered_graph_base(const G& g) : m_g(g) {} + // protected: const G& m_g; - }; - - template - class filtered_graph : public filtered_graph_base { - typedef filtered_graph_base Base; - typedef graph_traits Traits; +}; + +template < typename Graph, typename EdgePredicate, + typename VertexPredicate = keep_all > +class filtered_graph : public filtered_graph_base< Graph > +{ + typedef filtered_graph_base< Graph > Base; + typedef graph_traits< Graph > Traits; typedef filtered_graph self; - public: + +public: typedef Graph graph_type; - typedef detail::out_edge_predicate OutEdgePred; - typedef detail::in_edge_predicate InEdgePred; - typedef detail::edge_predicate EdgePred; + typedef detail::out_edge_predicate< EdgePredicate, VertexPredicate, self > + OutEdgePred; + typedef detail::in_edge_predicate< EdgePredicate, VertexPredicate, self > + InEdgePred; + typedef detail::edge_predicate< EdgePredicate, VertexPredicate, self > + EdgePred; // Constructors - filtered_graph(const Graph& g, EdgePredicate ep) - : Base(g), m_edge_pred(ep) { } + filtered_graph(const Graph& g, EdgePredicate ep) : Base(g), m_edge_pred(ep) + { + } filtered_graph(const Graph& g, EdgePredicate ep, VertexPredicate vp) - : Base(g), m_edge_pred(ep), m_vertex_pred(vp) { } + : Base(g), m_edge_pred(ep), m_vertex_pred(vp) + { + } // Graph requirements - typedef typename Traits::vertex_descriptor vertex_descriptor; - typedef typename Traits::edge_descriptor edge_descriptor; - typedef typename Traits::directed_category directed_category; - typedef typename Traits::edge_parallel_category edge_parallel_category; - typedef typename Traits::traversal_category traversal_category; + typedef typename Traits::vertex_descriptor vertex_descriptor; + typedef typename Traits::edge_descriptor edge_descriptor; + typedef typename Traits::directed_category directed_category; + typedef typename Traits::edge_parallel_category edge_parallel_category; + typedef typename Traits::traversal_category traversal_category; // IncidenceGraph requirements - typedef filter_iterator< - OutEdgePred, typename Traits::out_edge_iterator - > out_edge_iterator; - - typedef typename Traits::degree_size_type degree_size_type; + typedef filter_iterator< OutEdgePred, typename Traits::out_edge_iterator > + out_edge_iterator; + + typedef typename Traits::degree_size_type degree_size_type; // AdjacencyGraph requirements - typedef typename adjacency_iterator_generator::type adjacency_iterator; + typedef typename adjacency_iterator_generator< self, vertex_descriptor, + out_edge_iterator >::type adjacency_iterator; // BidirectionalGraph requirements - typedef filter_iterator< - InEdgePred, typename Traits::in_edge_iterator - > in_edge_iterator; + typedef filter_iterator< InEdgePred, typename Traits::in_edge_iterator > + in_edge_iterator; // VertexListGraph requirements - typedef filter_iterator< - VertexPredicate, typename Traits::vertex_iterator - > vertex_iterator; - typedef typename Traits::vertices_size_type vertices_size_type; + typedef filter_iterator< VertexPredicate, typename Traits::vertex_iterator > + vertex_iterator; + typedef typename Traits::vertices_size_type vertices_size_type; // EdgeListGraph requirements - typedef filter_iterator< - EdgePred, typename Traits::edge_iterator - > edge_iterator; - typedef typename Traits::edges_size_type edges_size_type; + typedef filter_iterator< EdgePred, typename Traits::edge_iterator > + edge_iterator; + typedef typename Traits::edges_size_type edges_size_type; typedef filtered_graph_tag graph_tag; // Bundled properties support - template - typename graph::detail::bundled_result::type& + template < typename Descriptor > + typename graph::detail::bundled_result< Graph, Descriptor >::type& operator[](Descriptor x) - { return const_cast(this->m_g)[x]; } + { + return const_cast< Graph& >(this->m_g)[x]; + } - template - typename graph::detail::bundled_result::type const& + template < typename Descriptor > + typename graph::detail::bundled_result< Graph, Descriptor >::type const& operator[](Descriptor x) const - { return this->m_g[x]; } - - static vertex_descriptor null_vertex() { - return Traits::null_vertex(); + return this->m_g[x]; } - //private: + static vertex_descriptor null_vertex() { return Traits::null_vertex(); } + + // private: EdgePredicate m_edge_pred; VertexPredicate m_vertex_pred; - }; - - // Do not instantiate these unless needed - template - struct vertex_property_type >: - vertex_property_type {}; - - template - struct edge_property_type >: - edge_property_type {}; - - template - struct graph_property_type >: - graph_property_type {}; - - template - struct vertex_bundle_type > - : vertex_bundle_type { }; - - template - struct edge_bundle_type > - : edge_bundle_type { }; - - template - struct graph_bundle_type > - : graph_bundle_type { }; - - //=========================================================================== - // Non-member functions for the Filtered Edge Graph - - // Helper functions - template - inline filtered_graph - make_filtered_graph(Graph& g, EdgePredicate ep) { - return filtered_graph(g, ep); - } - template - inline filtered_graph - make_filtered_graph(Graph& g, EdgePredicate ep, VertexPredicate vp) { - return filtered_graph(g, ep, vp); - } - - template - inline filtered_graph - make_filtered_graph(const Graph& g, EdgePredicate ep) { - return filtered_graph(g, ep); - } - template - inline filtered_graph - make_filtered_graph(const Graph& g, EdgePredicate ep, VertexPredicate vp) { - return filtered_graph(g, ep, vp); - } - - template - std::pair::vertex_iterator, - typename filtered_graph::vertex_iterator> - vertices(const filtered_graph& g) - { - typedef filtered_graph Graph; - typename graph_traits::vertex_iterator f, l; +}; + +// Do not instantiate these unless needed +template < typename Graph, typename EdgePredicate, typename VertexPredicate > +struct vertex_property_type< + filtered_graph< Graph, EdgePredicate, VertexPredicate > > +: vertex_property_type< Graph > +{ +}; + +template < typename Graph, typename EdgePredicate, typename VertexPredicate > +struct edge_property_type< + filtered_graph< Graph, EdgePredicate, VertexPredicate > > +: edge_property_type< Graph > +{ +}; + +template < typename Graph, typename EdgePredicate, typename VertexPredicate > +struct graph_property_type< + filtered_graph< Graph, EdgePredicate, VertexPredicate > > +: graph_property_type< Graph > +{ +}; + +template < typename Graph, typename EdgePredicate, typename VertexPredicate > +struct vertex_bundle_type< + filtered_graph< Graph, EdgePredicate, VertexPredicate > > +: vertex_bundle_type< Graph > +{ +}; + +template < typename Graph, typename EdgePredicate, typename VertexPredicate > +struct edge_bundle_type< + filtered_graph< Graph, EdgePredicate, VertexPredicate > > +: edge_bundle_type< Graph > +{ +}; + +template < typename Graph, typename EdgePredicate, typename VertexPredicate > +struct graph_bundle_type< + filtered_graph< Graph, EdgePredicate, VertexPredicate > > +: graph_bundle_type< Graph > +{ +}; + +//=========================================================================== +// Non-member functions for the Filtered Edge Graph + +// Helper functions +template < typename Graph, typename EdgePredicate > +inline filtered_graph< Graph, EdgePredicate > make_filtered_graph( + Graph& g, EdgePredicate ep) +{ + return filtered_graph< Graph, EdgePredicate >(g, ep); +} +template < typename Graph, typename EdgePredicate, typename VertexPredicate > +inline filtered_graph< Graph, EdgePredicate, VertexPredicate > +make_filtered_graph(Graph& g, EdgePredicate ep, VertexPredicate vp) +{ + return filtered_graph< Graph, EdgePredicate, VertexPredicate >(g, ep, vp); +} + +template < typename Graph, typename EdgePredicate > +inline filtered_graph< const Graph, EdgePredicate > make_filtered_graph( + const Graph& g, EdgePredicate ep) +{ + return filtered_graph< const Graph, EdgePredicate >(g, ep); +} +template < typename Graph, typename EdgePredicate, typename VertexPredicate > +inline filtered_graph< const Graph, EdgePredicate, VertexPredicate > +make_filtered_graph(const Graph& g, EdgePredicate ep, VertexPredicate vp) +{ + return filtered_graph< const Graph, EdgePredicate, VertexPredicate >( + g, ep, vp); +} + +template < typename G, typename EP, typename VP > +std::pair< typename filtered_graph< G, EP, VP >::vertex_iterator, + typename filtered_graph< G, EP, VP >::vertex_iterator > +vertices(const filtered_graph< G, EP, VP >& g) +{ + typedef filtered_graph< G, EP, VP > Graph; + typename graph_traits< G >::vertex_iterator f, l; boost::tie(f, l) = vertices(g.m_g); typedef typename Graph::vertex_iterator iter; - return std::make_pair(iter(g.m_vertex_pred, f, l), - iter(g.m_vertex_pred, l, l)); - } - - template - std::pair::edge_iterator, - typename filtered_graph::edge_iterator> - edges(const filtered_graph& g) - { - typedef filtered_graph Graph; + return std::make_pair( + iter(g.m_vertex_pred, f, l), iter(g.m_vertex_pred, l, l)); +} + +template < typename G, typename EP, typename VP > +std::pair< typename filtered_graph< G, EP, VP >::edge_iterator, + typename filtered_graph< G, EP, VP >::edge_iterator > +edges(const filtered_graph< G, EP, VP >& g) +{ + typedef filtered_graph< G, EP, VP > Graph; typename Graph::EdgePred pred(g.m_edge_pred, g.m_vertex_pred, g); - typename graph_traits::edge_iterator f, l; + typename graph_traits< G >::edge_iterator f, l; boost::tie(f, l) = edges(g.m_g); typedef typename Graph::edge_iterator iter; return std::make_pair(iter(pred, f, l), iter(pred, l, l)); - } - - // An alternative for num_vertices() and num_edges() would be to - // count the number in the filtered graph. This is problematic - // because of the interaction with the vertex indices... they would - // no longer go from 0 to num_vertices(), which would cause trouble - // for algorithms allocating property storage in an array. We could - // try to create a mapping to new recalibrated indices, but I don't - // see an efficient way to do this. - // - // However, the current solution is still unsatisfactory because - // the following semantic constraints no longer hold: - // boost::tie(vi, viend) = vertices(g); - // assert(std::distance(vi, viend) == num_vertices(g)); - - template - typename filtered_graph::vertices_size_type - num_vertices(const filtered_graph& g) { +} + +// An alternative for num_vertices() and num_edges() would be to +// count the number in the filtered graph. This is problematic +// because of the interaction with the vertex indices... they would +// no longer go from 0 to num_vertices(), which would cause trouble +// for algorithms allocating property storage in an array. We could +// try to create a mapping to new recalibrated indices, but I don't +// see an efficient way to do this. +// +// However, the current solution is still unsatisfactory because +// the following semantic constraints no longer hold: +// boost::tie(vi, viend) = vertices(g); +// assert(std::distance(vi, viend) == num_vertices(g)); + +template < typename G, typename EP, typename VP > +typename filtered_graph< G, EP, VP >::vertices_size_type num_vertices( + const filtered_graph< G, EP, VP >& g) +{ return num_vertices(g.m_g); - } +} - template - typename filtered_graph::edges_size_type - num_edges(const filtered_graph& g) { +template < typename G, typename EP, typename VP > +typename filtered_graph< G, EP, VP >::edges_size_type num_edges( + const filtered_graph< G, EP, VP >& g) +{ return num_edges(g.m_g); - } - - template - typename filtered_graph_base::vertex_descriptor - source(typename filtered_graph_base::edge_descriptor e, - const filtered_graph_base& g) - { +} + +template < typename G > +typename filtered_graph_base< G >::vertex_descriptor source( + typename filtered_graph_base< G >::edge_descriptor e, + const filtered_graph_base< G >& g) +{ return source(e, g.m_g); - } +} - template - typename filtered_graph_base::vertex_descriptor - target(typename filtered_graph_base::edge_descriptor e, - const filtered_graph_base& g) - { +template < typename G > +typename filtered_graph_base< G >::vertex_descriptor target( + typename filtered_graph_base< G >::edge_descriptor e, + const filtered_graph_base< G >& g) +{ return target(e, g.m_g); - } - - template - std::pair::out_edge_iterator, - typename filtered_graph::out_edge_iterator> - out_edges(typename filtered_graph::vertex_descriptor u, - const filtered_graph& g) - { - typedef filtered_graph Graph; +} + +template < typename G, typename EP, typename VP > +std::pair< typename filtered_graph< G, EP, VP >::out_edge_iterator, + typename filtered_graph< G, EP, VP >::out_edge_iterator > +out_edges(typename filtered_graph< G, EP, VP >::vertex_descriptor u, + const filtered_graph< G, EP, VP >& g) +{ + typedef filtered_graph< G, EP, VP > Graph; typename Graph::OutEdgePred pred(g.m_edge_pred, g.m_vertex_pred, g); typedef typename Graph::out_edge_iterator iter; - typename graph_traits::out_edge_iterator f, l; + typename graph_traits< G >::out_edge_iterator f, l; boost::tie(f, l) = out_edges(u, g.m_g); return std::make_pair(iter(pred, f, l), iter(pred, l, l)); - } - - template - typename filtered_graph::degree_size_type - out_degree(typename filtered_graph::vertex_descriptor u, - const filtered_graph& g) - { - typename filtered_graph::degree_size_type n = 0; - typename filtered_graph::out_edge_iterator f, l; +} + +template < typename G, typename EP, typename VP > +typename filtered_graph< G, EP, VP >::degree_size_type out_degree( + typename filtered_graph< G, EP, VP >::vertex_descriptor u, + const filtered_graph< G, EP, VP >& g) +{ + typename filtered_graph< G, EP, VP >::degree_size_type n = 0; + typename filtered_graph< G, EP, VP >::out_edge_iterator f, l; for (boost::tie(f, l) = out_edges(u, g); f != l; ++f) - ++n; + ++n; return n; - } - - template - std::pair::adjacency_iterator, - typename filtered_graph::adjacency_iterator> - adjacent_vertices(typename filtered_graph::vertex_descriptor u, - const filtered_graph& g) - { - typedef filtered_graph Graph; +} + +template < typename G, typename EP, typename VP > +std::pair< typename filtered_graph< G, EP, VP >::adjacency_iterator, + typename filtered_graph< G, EP, VP >::adjacency_iterator > +adjacent_vertices(typename filtered_graph< G, EP, VP >::vertex_descriptor u, + const filtered_graph< G, EP, VP >& g) +{ + typedef filtered_graph< G, EP, VP > Graph; typedef typename Graph::adjacency_iterator adjacency_iterator; typename Graph::out_edge_iterator f, l; boost::tie(f, l) = out_edges(u, g); - return std::make_pair(adjacency_iterator(f, const_cast(&g)), - adjacency_iterator(l, const_cast(&g))); - } - - template - std::pair::in_edge_iterator, - typename filtered_graph::in_edge_iterator> - in_edges(typename filtered_graph::vertex_descriptor u, - const filtered_graph& g) - { - typedef filtered_graph Graph; + return std::make_pair(adjacency_iterator(f, const_cast< Graph* >(&g)), + adjacency_iterator(l, const_cast< Graph* >(&g))); +} + +template < typename G, typename EP, typename VP > +std::pair< typename filtered_graph< G, EP, VP >::in_edge_iterator, + typename filtered_graph< G, EP, VP >::in_edge_iterator > +in_edges(typename filtered_graph< G, EP, VP >::vertex_descriptor u, + const filtered_graph< G, EP, VP >& g) +{ + typedef filtered_graph< G, EP, VP > Graph; typename Graph::InEdgePred pred(g.m_edge_pred, g.m_vertex_pred, g); typedef typename Graph::in_edge_iterator iter; - typename graph_traits::in_edge_iterator f, l; + typename graph_traits< G >::in_edge_iterator f, l; boost::tie(f, l) = in_edges(u, g.m_g); return std::make_pair(iter(pred, f, l), iter(pred, l, l)); - } - - template - typename filtered_graph::degree_size_type - in_degree(typename filtered_graph::vertex_descriptor u, - const filtered_graph& g) - { - typename filtered_graph::degree_size_type n = 0; - typename filtered_graph::in_edge_iterator f, l; +} + +template < typename G, typename EP, typename VP > +typename filtered_graph< G, EP, VP >::degree_size_type in_degree( + typename filtered_graph< G, EP, VP >::vertex_descriptor u, + const filtered_graph< G, EP, VP >& g) +{ + typename filtered_graph< G, EP, VP >::degree_size_type n = 0; + typename filtered_graph< G, EP, VP >::in_edge_iterator f, l; for (boost::tie(f, l) = in_edges(u, g); f != l; ++f) - ++n; + ++n; return n; - } - - template - typename enable_if::type, - typename filtered_graph::degree_size_type - >::type - degree(typename filtered_graph::vertex_descriptor u, - const filtered_graph& g) - { +} + +template < typename G, typename EP, typename VP > +typename enable_if< typename is_directed_graph< G >::type, + typename filtered_graph< G, EP, VP >::degree_size_type >::type +degree(typename filtered_graph< G, EP, VP >::vertex_descriptor u, + const filtered_graph< G, EP, VP >& g) +{ return out_degree(u, g) + in_degree(u, g); - } - - template - typename disable_if::type, - typename filtered_graph::degree_size_type - >::type - degree(typename filtered_graph::vertex_descriptor u, - const filtered_graph& g) - { +} + +template < typename G, typename EP, typename VP > +typename disable_if< typename is_directed_graph< G >::type, + typename filtered_graph< G, EP, VP >::degree_size_type >::type +degree(typename filtered_graph< G, EP, VP >::vertex_descriptor u, + const filtered_graph< G, EP, VP >& g) +{ return out_degree(u, g); - } - - template - std::pair::edge_descriptor, bool> - edge(typename filtered_graph::vertex_descriptor u, - typename filtered_graph::vertex_descriptor v, - const filtered_graph& g) - { - typename graph_traits::edge_descriptor e; +} + +template < typename G, typename EP, typename VP > +std::pair< typename filtered_graph< G, EP, VP >::edge_descriptor, bool > edge( + typename filtered_graph< G, EP, VP >::vertex_descriptor u, + typename filtered_graph< G, EP, VP >::vertex_descriptor v, + const filtered_graph< G, EP, VP >& g) +{ + typename graph_traits< G >::edge_descriptor e; bool exists; boost::tie(e, exists) = edge(u, v, g.m_g); return std::make_pair(e, exists && g.m_edge_pred(e)); - } - - template - std::pair::out_edge_iterator, - typename filtered_graph::out_edge_iterator> - edge_range(typename filtered_graph::vertex_descriptor u, - typename filtered_graph::vertex_descriptor v, - const filtered_graph& g) - { - typedef filtered_graph Graph; +} + +template < typename G, typename EP, typename VP > +std::pair< typename filtered_graph< G, EP, VP >::out_edge_iterator, + typename filtered_graph< G, EP, VP >::out_edge_iterator > +edge_range(typename filtered_graph< G, EP, VP >::vertex_descriptor u, + typename filtered_graph< G, EP, VP >::vertex_descriptor v, + const filtered_graph< G, EP, VP >& g) +{ + typedef filtered_graph< G, EP, VP > Graph; typename Graph::OutEdgePred pred(g.m_edge_pred, g.m_vertex_pred, g); typedef typename Graph::out_edge_iterator iter; - typename graph_traits::out_edge_iterator f, l; + typename graph_traits< G >::out_edge_iterator f, l; boost::tie(f, l) = edge_range(u, v, g.m_g); return std::make_pair(iter(pred, f, l), iter(pred, l, l)); - } - - - //=========================================================================== - // Property map - - template - struct property_map, Property> - : property_map {}; - - template - typename property_map::type - get(Property p, filtered_graph& g) - { - return get(p, const_cast(g.m_g)); - } - - template - typename property_map::const_type - get(Property p, const filtered_graph& g) - { +} + +//=========================================================================== +// Property map + +template < typename G, typename EP, typename VP, typename Property > +struct property_map< filtered_graph< G, EP, VP >, Property > +: property_map< G, Property > +{ +}; + +template < typename G, typename EP, typename VP, typename Property > +typename property_map< G, Property >::type get( + Property p, filtered_graph< G, EP, VP >& g) +{ + return get(p, const_cast< G& >(g.m_g)); +} + +template < typename G, typename EP, typename VP, typename Property > +typename property_map< G, Property >::const_type get( + Property p, const filtered_graph< G, EP, VP >& g) +{ return get(p, (const G&)g.m_g); - } +} - template - typename property_map_value::type - get(Property p, const filtered_graph& g, const Key& k) - { +template < typename G, typename EP, typename VP, typename Property, + typename Key > +typename property_map_value< G, Property >::type get( + Property p, const filtered_graph< G, EP, VP >& g, const Key& k) +{ return get(p, (const G&)g.m_g, k); - } - - template - void - put(Property p, const filtered_graph& g, const Key& k, - const Value& val) - { - put(p, const_cast(g.m_g), k, val); - } - - //=========================================================================== - // Some filtered subgraph specializations - - template - struct vertex_subset_filter { - typedef filtered_graph > type; - }; - template - inline typename vertex_subset_filter::type - make_vertex_subset_filter(Graph& g, const Set& s) { - typedef typename vertex_subset_filter::type Filter; - is_in_subset p(s); +} + +template < typename G, typename EP, typename VP, typename Property, + typename Key, typename Value > +void put(Property p, const filtered_graph< G, EP, VP >& g, const Key& k, + const Value& val) +{ + put(p, const_cast< G& >(g.m_g), k, val); +} + +//=========================================================================== +// Some filtered subgraph specializations + +template < typename Graph, typename Set > struct vertex_subset_filter +{ + typedef filtered_graph< Graph, keep_all, is_in_subset< Set > > type; +}; +template < typename Graph, typename Set > +inline typename vertex_subset_filter< Graph, Set >::type +make_vertex_subset_filter(Graph& g, const Set& s) +{ + typedef typename vertex_subset_filter< Graph, Set >::type Filter; + is_in_subset< Set > p(s); return Filter(g, keep_all(), p); - } - - // This is misspelled, but present for backwards compatibility; new code - // should use the version below that has the correct spelling. - template - struct vertex_subset_compliment_filter { - typedef filtered_graph > type; - }; - template - inline typename vertex_subset_compliment_filter::type - make_vertex_subset_compliment_filter(Graph& g, const Set& s) { - typedef typename vertex_subset_compliment_filter::type Filter; - is_not_in_subset p(s); +} + +// This is misspelled, but present for backwards compatibility; new code +// should use the version below that has the correct spelling. +template < typename Graph, typename Set > struct vertex_subset_compliment_filter +{ + typedef filtered_graph< Graph, keep_all, is_not_in_subset< Set > > type; +}; +template < typename Graph, typename Set > +inline typename vertex_subset_compliment_filter< Graph, Set >::type +make_vertex_subset_compliment_filter(Graph& g, const Set& s) +{ + typedef typename vertex_subset_compliment_filter< Graph, Set >::type Filter; + is_not_in_subset< Set > p(s); return Filter(g, keep_all(), p); - } - - template - struct vertex_subset_complement_filter { - typedef filtered_graph > type; - }; - template - inline typename vertex_subset_complement_filter::type - make_vertex_subset_complement_filter(Graph& g, const Set& s) { - typedef typename vertex_subset_complement_filter::type Filter; - is_not_in_subset p(s); +} + +template < typename Graph, typename Set > struct vertex_subset_complement_filter +{ + typedef filtered_graph< Graph, keep_all, is_not_in_subset< Set > > type; +}; +template < typename Graph, typename Set > +inline typename vertex_subset_complement_filter< Graph, Set >::type +make_vertex_subset_complement_filter(Graph& g, const Set& s) +{ + typedef typename vertex_subset_complement_filter< Graph, Set >::type Filter; + is_not_in_subset< Set > p(s); return Filter(g, keep_all(), p); - } - - // Filter that uses a property map whose value_type is a boolean - template - struct property_map_filter { - - property_map_filter() { } - - property_map_filter(const PropertyMap& property_map) : - m_property_map(property_map) { } - - template - bool operator()(const Key& key) const { - return (get(m_property_map, key)); +} + +// Filter that uses a property map whose value_type is a boolean +template < typename PropertyMap > struct property_map_filter +{ + + property_map_filter() {} + + property_map_filter(const PropertyMap& property_map) + : m_property_map(property_map) + { + } + + template < typename Key > bool operator()(const Key& key) const + { + return (get(m_property_map, key)); } - - private : + +private: PropertyMap m_property_map; - }; +}; } // namespace boost - #endif // BOOST_FILTERED_GRAPH_HPP diff --git a/include/boost/graph/find_flow_cost.hpp b/include/boost/graph/find_flow_cost.hpp index 1d49cddd5..78fd955d8 100644 --- a/include/boost/graph/find_flow_cost.hpp +++ b/include/boost/graph/find_flow_cost.hpp @@ -1,6 +1,6 @@ //======================================================================= // Copyright 2013 University of Warsaw. -// Authors: Piotr Wygocki +// Authors: Piotr Wygocki // // Distributed under the Boost Software License, Version 1.0. (See // accompanying file LICENSE_1_0.txt or copy at @@ -11,42 +11,47 @@ #include -namespace boost { +namespace boost +{ -template -typename property_traits::value_type -find_flow_cost(const Graph & g, Capacity capacity, ResidualCapacity residual_capacity, Weight weight) { - typedef typename property_traits::value_type Cost; +template < class Graph, class Capacity, class ResidualCapacity, class Weight > +typename property_traits< Weight >::value_type find_flow_cost(const Graph& g, + Capacity capacity, ResidualCapacity residual_capacity, Weight weight) +{ + typedef typename property_traits< Weight >::value_type Cost; Cost cost = 0; - BGL_FORALL_EDGES_T(e, g, Graph) { - if(get(capacity, e) > Cost(0)) { - cost += (get(capacity, e) - get(residual_capacity, e)) * get(weight, e); - } + BGL_FORALL_EDGES_T(e, g, Graph) + { + if (get(capacity, e) > Cost(0)) + { + cost += (get(capacity, e) - get(residual_capacity, e)) + * get(weight, e); + } } return cost; } -template -typename detail::edge_weight_value::type -find_flow_cost(const Graph & g, - const bgl_named_params& params) { +template < class Graph, class P, class T, class R > +typename detail::edge_weight_value< Graph, P, T, R >::type find_flow_cost( + const Graph& g, const bgl_named_params< P, T, R >& params) +{ return find_flow_cost(g, - choose_const_pmap(get_param(params, edge_capacity), g, edge_capacity), - choose_const_pmap(get_param(params, edge_residual_capacity), - g, edge_residual_capacity), - choose_const_pmap(get_param(params, edge_weight), g, edge_weight)); + choose_const_pmap(get_param(params, edge_capacity), g, edge_capacity), + choose_const_pmap(get_param(params, edge_residual_capacity), g, + edge_residual_capacity), + choose_const_pmap(get_param(params, edge_weight), g, edge_weight)); } -template -typename property_traits::type>::value_type -find_flow_cost(const Graph &g) { - bgl_named_params params(0); +template < class Graph > +typename property_traits< + typename property_map< Graph, edge_capacity_t >::type >::value_type +find_flow_cost(const Graph& g) +{ + bgl_named_params< int, buffer_param_t > params(0); return find_flow_cost(g, params); } - -} //boost +} // boost #endif /* BOOST_GRAPH_FIND_FLOW_COST_HPP */ - diff --git a/include/boost/graph/floyd_warshall_shortest.hpp b/include/boost/graph/floyd_warshall_shortest.hpp index 472995f04..e8eeae547 100644 --- a/include/boost/graph/floyd_warshall_shortest.hpp +++ b/include/boost/graph/floyd_warshall_shortest.hpp @@ -10,22 +10,21 @@ /* This file implements the functions - template bool floyd_warshall_initialized_all_pairs_shortest_paths( - const VertexListGraph& g, DistanceMatrix& d, + const VertexListGraph& g, DistanceMatrix& d, const bgl_named_params& params) AND - template bool floyd_warshall_all_pairs_shortest_paths( - const VertexAndEdgeListGraph& g, DistanceMatrix& d, + const VertexAndEdgeListGraph& g, DistanceMatrix& d, const bgl_named_params& params) */ - #ifndef BOOST_GRAPH_FLOYD_WARSHALL_HPP #define BOOST_GRAPH_FLOYD_WARSHALL_HPP @@ -38,219 +37,187 @@ namespace boost { - namespace detail { - template +namespace detail +{ + template < typename T, typename BinaryPredicate > T min_with_compare(const T& x, const T& y, const BinaryPredicate& compare) { - if (compare(x, y)) return x; - else return y; + if (compare(x, y)) + return x; + else + return y; } - template - bool floyd_warshall_dispatch(const VertexListGraph& g, - DistanceMatrix& d, const BinaryPredicate &compare, - const BinaryFunction &combine, const Infinity& inf, - const Zero& zero) + template < typename VertexListGraph, typename DistanceMatrix, + typename BinaryPredicate, typename BinaryFunction, typename Infinity, + typename Zero > + bool floyd_warshall_dispatch(const VertexListGraph& g, DistanceMatrix& d, + const BinaryPredicate& compare, const BinaryFunction& combine, + const Infinity& inf, const Zero& zero) { - typename graph_traits::vertex_iterator - i, lasti, j, lastj, k, lastk; - - - for (boost::tie(k, lastk) = vertices(g); k != lastk; k++) + typename graph_traits< VertexListGraph >::vertex_iterator i, lasti, j, + lastj, k, lastk; + + for (boost::tie(k, lastk) = vertices(g); k != lastk; k++) + for (boost::tie(i, lasti) = vertices(g); i != lasti; i++) + if (d[*i][*k] != inf) + for (boost::tie(j, lastj) = vertices(g); j != lastj; j++) + if (d[*k][*j] != inf) + d[*i][*j] = detail::min_with_compare(d[*i][*j], + combine(d[*i][*k], d[*k][*j]), compare); + for (boost::tie(i, lasti) = vertices(g); i != lasti; i++) - if(d[*i][*k] != inf) - for (boost::tie(j, lastj) = vertices(g); j != lastj; j++) - if(d[*k][*j] != inf) - d[*i][*j] = - detail::min_with_compare(d[*i][*j], - combine(d[*i][*k], d[*k][*j]), - compare); - - - for (boost::tie(i, lasti) = vertices(g); i != lasti; i++) - if (compare(d[*i][*i], zero)) - return false; - return true; + if (compare(d[*i][*i], zero)) + return false; + return true; } - } +} + +template < typename VertexListGraph, typename DistanceMatrix, + typename BinaryPredicate, typename BinaryFunction, typename Infinity, + typename Zero > +bool floyd_warshall_initialized_all_pairs_shortest_paths( + const VertexListGraph& g, DistanceMatrix& d, const BinaryPredicate& compare, + const BinaryFunction& combine, const Infinity& inf, const Zero& zero) +{ + BOOST_CONCEPT_ASSERT((VertexListGraphConcept< VertexListGraph >)); - template - bool floyd_warshall_initialized_all_pairs_shortest_paths( - const VertexListGraph& g, DistanceMatrix& d, - const BinaryPredicate& compare, - const BinaryFunction& combine, const Infinity& inf, - const Zero& zero) - { - BOOST_CONCEPT_ASSERT(( VertexListGraphConcept )); - - return detail::floyd_warshall_dispatch(g, d, compare, combine, - inf, zero); - } - - - - template - bool floyd_warshall_all_pairs_shortest_paths( - const VertexAndEdgeListGraph& g, - DistanceMatrix& d, const WeightMap& w, - const BinaryPredicate& compare, const BinaryFunction& combine, - const Infinity& inf, const Zero& zero) - { - BOOST_CONCEPT_ASSERT(( VertexListGraphConcept )); - BOOST_CONCEPT_ASSERT(( EdgeListGraphConcept )); - BOOST_CONCEPT_ASSERT(( IncidenceGraphConcept )); - - typename graph_traits::vertex_iterator - firstv, lastv, firstv2, lastv2; - typename graph_traits::edge_iterator first, last; - - - for(boost::tie(firstv, lastv) = vertices(g); firstv != lastv; firstv++) - for(boost::tie(firstv2, lastv2) = vertices(g); firstv2 != lastv2; firstv2++) - d[*firstv][*firstv2] = inf; - - - for(boost::tie(firstv, lastv) = vertices(g); firstv != lastv; firstv++) - d[*firstv][*firstv] = zero; - - - for(boost::tie(first, last) = edges(g); first != last; first++) + return detail::floyd_warshall_dispatch(g, d, compare, combine, inf, zero); +} + +template < typename VertexAndEdgeListGraph, typename DistanceMatrix, + typename WeightMap, typename BinaryPredicate, typename BinaryFunction, + typename Infinity, typename Zero > +bool floyd_warshall_all_pairs_shortest_paths(const VertexAndEdgeListGraph& g, + DistanceMatrix& d, const WeightMap& w, const BinaryPredicate& compare, + const BinaryFunction& combine, const Infinity& inf, const Zero& zero) +{ + BOOST_CONCEPT_ASSERT((VertexListGraphConcept< VertexAndEdgeListGraph >)); + BOOST_CONCEPT_ASSERT((EdgeListGraphConcept< VertexAndEdgeListGraph >)); + BOOST_CONCEPT_ASSERT((IncidenceGraphConcept< VertexAndEdgeListGraph >)); + + typename graph_traits< VertexAndEdgeListGraph >::vertex_iterator firstv, + lastv, firstv2, lastv2; + typename graph_traits< VertexAndEdgeListGraph >::edge_iterator first, last; + + for (boost::tie(firstv, lastv) = vertices(g); firstv != lastv; firstv++) + for (boost::tie(firstv2, lastv2) = vertices(g); firstv2 != lastv2; + firstv2++) + d[*firstv][*firstv2] = inf; + + for (boost::tie(firstv, lastv) = vertices(g); firstv != lastv; firstv++) + d[*firstv][*firstv] = zero; + + for (boost::tie(first, last) = edges(g); first != last; first++) { - if (d[source(*first, g)][target(*first, g)] != inf) { - d[source(*first, g)][target(*first, g)] = - detail::min_with_compare( - get(w, *first), - d[source(*first, g)][target(*first, g)], - compare); - } else - d[source(*first, g)][target(*first, g)] = get(w, *first); + if (d[source(*first, g)][target(*first, g)] != inf) + { + d[source(*first, g)][target(*first, g)] + = detail::min_with_compare(get(w, *first), + d[source(*first, g)][target(*first, g)], compare); + } + else + d[source(*first, g)][target(*first, g)] = get(w, *first); } - - bool is_undirected = is_same::directed_category, - undirected_tag>::value; + + bool is_undirected = is_same< + typename graph_traits< VertexAndEdgeListGraph >::directed_category, + undirected_tag >::value; if (is_undirected) { - for(boost::tie(first, last) = edges(g); first != last; first++) - { - if (d[target(*first, g)][source(*first, g)] != inf) - d[target(*first, g)][source(*first, g)] = - detail::min_with_compare( - get(w, *first), - d[target(*first, g)][source(*first, g)], - compare); - else - d[target(*first, g)][source(*first, g)] = get(w, *first); - } + for (boost::tie(first, last) = edges(g); first != last; first++) + { + if (d[target(*first, g)][source(*first, g)] != inf) + d[target(*first, g)][source(*first, g)] + = detail::min_with_compare(get(w, *first), + d[target(*first, g)][source(*first, g)], compare); + else + d[target(*first, g)][source(*first, g)] = get(w, *first); + } } - - - return detail::floyd_warshall_dispatch(g, d, compare, combine, - inf, zero); - } - - - namespace detail { - template - bool floyd_warshall_init_dispatch(const VertexListGraph& g, - DistanceMatrix& d, WeightMap /*w*/, - const bgl_named_params& params) + + return detail::floyd_warshall_dispatch(g, d, compare, combine, inf, zero); +} + +namespace detail +{ + template < class VertexListGraph, class DistanceMatrix, class WeightMap, + class P, class T, class R > + bool floyd_warshall_init_dispatch(const VertexListGraph& g, + DistanceMatrix& d, WeightMap /*w*/, + const bgl_named_params< P, T, R >& params) { - typedef typename property_traits::value_type WM; - WM inf = - choose_param(get_param(params, distance_inf_t()), - std::numeric_limits::max BOOST_PREVENT_MACRO_SUBSTITUTION()); - - return floyd_warshall_initialized_all_pairs_shortest_paths(g, d, - choose_param(get_param(params, distance_compare_t()), - std::less()), - choose_param(get_param(params, distance_combine_t()), - closed_plus(inf)), - inf, - choose_param(get_param(params, distance_zero_t()), - WM())); + typedef typename property_traits< WeightMap >::value_type WM; + WM inf = choose_param(get_param(params, distance_inf_t()), + std::numeric_limits< WM >::max BOOST_PREVENT_MACRO_SUBSTITUTION()); + + return floyd_warshall_initialized_all_pairs_shortest_paths(g, d, + choose_param( + get_param(params, distance_compare_t()), std::less< WM >()), + choose_param(get_param(params, distance_combine_t()), + closed_plus< WM >(inf)), + inf, choose_param(get_param(params, distance_zero_t()), WM())); } - - - - template - bool floyd_warshall_noninit_dispatch(const VertexAndEdgeListGraph& g, - DistanceMatrix& d, WeightMap w, - const bgl_named_params& params) + + template < class VertexAndEdgeListGraph, class DistanceMatrix, + class WeightMap, class P, class T, class R > + bool floyd_warshall_noninit_dispatch(const VertexAndEdgeListGraph& g, + DistanceMatrix& d, WeightMap w, + const bgl_named_params< P, T, R >& params) { - typedef typename property_traits::value_type WM; - - WM inf = - choose_param(get_param(params, distance_inf_t()), - std::numeric_limits::max BOOST_PREVENT_MACRO_SUBSTITUTION()); - return floyd_warshall_all_pairs_shortest_paths(g, d, w, - choose_param(get_param(params, distance_compare_t()), - std::less()), - choose_param(get_param(params, distance_combine_t()), - closed_plus(inf)), - inf, - choose_param(get_param(params, distance_zero_t()), - WM())); + typedef typename property_traits< WeightMap >::value_type WM; + + WM inf = choose_param(get_param(params, distance_inf_t()), + std::numeric_limits< WM >::max BOOST_PREVENT_MACRO_SUBSTITUTION()); + return floyd_warshall_all_pairs_shortest_paths(g, d, w, + choose_param( + get_param(params, distance_compare_t()), std::less< WM >()), + choose_param(get_param(params, distance_combine_t()), + closed_plus< WM >(inf)), + inf, choose_param(get_param(params, distance_zero_t()), WM())); } - - } // namespace detail +} // namespace detail - - - template - bool floyd_warshall_initialized_all_pairs_shortest_paths( - const VertexListGraph& g, DistanceMatrix& d, - const bgl_named_params& params) - { - return detail::floyd_warshall_init_dispatch(g, d, - choose_const_pmap(get_param(params, edge_weight), g, edge_weight), - params); - } - - template - bool floyd_warshall_initialized_all_pairs_shortest_paths( - const VertexListGraph& g, DistanceMatrix& d) - { - bgl_named_params params(0); +template < class VertexListGraph, class DistanceMatrix, class P, class T, + class R > +bool floyd_warshall_initialized_all_pairs_shortest_paths( + const VertexListGraph& g, DistanceMatrix& d, + const bgl_named_params< P, T, R >& params) +{ return detail::floyd_warshall_init_dispatch(g, d, - get(edge_weight, g), params); - } - + choose_const_pmap(get_param(params, edge_weight), g, edge_weight), + params); +} - - - template - bool floyd_warshall_all_pairs_shortest_paths( - const VertexAndEdgeListGraph& g, DistanceMatrix& d, - const bgl_named_params& params) - { - return detail::floyd_warshall_noninit_dispatch(g, d, - choose_const_pmap(get_param(params, edge_weight), g, edge_weight), - params); - } - - template - bool floyd_warshall_all_pairs_shortest_paths( - const VertexAndEdgeListGraph& g, DistanceMatrix& d) - { - bgl_named_params params(0); +template < class VertexListGraph, class DistanceMatrix > +bool floyd_warshall_initialized_all_pairs_shortest_paths( + const VertexListGraph& g, DistanceMatrix& d) +{ + bgl_named_params< int, int > params(0); + return detail::floyd_warshall_init_dispatch( + g, d, get(edge_weight, g), params); +} + +template < class VertexAndEdgeListGraph, class DistanceMatrix, class P, class T, + class R > +bool floyd_warshall_all_pairs_shortest_paths(const VertexAndEdgeListGraph& g, + DistanceMatrix& d, const bgl_named_params< P, T, R >& params) +{ return detail::floyd_warshall_noninit_dispatch(g, d, - get(edge_weight, g), params); - } - + choose_const_pmap(get_param(params, edge_weight), g, edge_weight), + params); +} + +template < class VertexAndEdgeListGraph, class DistanceMatrix > +bool floyd_warshall_all_pairs_shortest_paths( + const VertexAndEdgeListGraph& g, DistanceMatrix& d) +{ + bgl_named_params< int, int > params(0); + return detail::floyd_warshall_noninit_dispatch( + g, d, get(edge_weight, g), params); +} } // namespace boost #endif - diff --git a/include/boost/graph/fruchterman_reingold.hpp b/include/boost/graph/fruchterman_reingold.hpp index 24e1ae8cf..55a262291 100644 --- a/include/boost/graph/fruchterman_reingold.hpp +++ b/include/boost/graph/fruchterman_reingold.hpp @@ -22,418 +22,439 @@ #include // for std::sqrt and std::fabs #include -namespace boost { - -struct square_distance_attractive_force { - template - T - operator()(typename graph_traits::edge_descriptor, - T k, - T d, - const Graph&) const - { - return d * d / k; - } +namespace boost +{ + +struct square_distance_attractive_force +{ + template < typename Graph, typename T > + T operator()(typename graph_traits< Graph >::edge_descriptor, T k, T d, + const Graph&) const + { + return d * d / k; + } }; -struct square_distance_repulsive_force { - template - T - operator()(typename graph_traits::vertex_descriptor, - typename graph_traits::vertex_descriptor, - T k, - T d, - const Graph&) const - { - return k * k / d; - } +struct square_distance_repulsive_force +{ + template < typename Graph, typename T > + T operator()(typename graph_traits< Graph >::vertex_descriptor, + typename graph_traits< Graph >::vertex_descriptor, T k, T d, + const Graph&) const + { + return k * k / d; + } }; -template -struct linear_cooling { - typedef T result_type; +template < typename T > struct linear_cooling +{ + typedef T result_type; - linear_cooling(std::size_t iterations) - : temp(T(iterations) / T(10)), step(0.1) { } + linear_cooling(std::size_t iterations) + : temp(T(iterations) / T(10)), step(0.1) + { + } - linear_cooling(std::size_t iterations, T temp) - : temp(temp), step(temp / T(iterations)) { } + linear_cooling(std::size_t iterations, T temp) + : temp(temp), step(temp / T(iterations)) + { + } - T operator()() - { - T old_temp = temp; - temp -= step; - if (temp < T(0)) temp = T(0); - return old_temp; - } + T operator()() + { + T old_temp = temp; + temp -= step; + if (temp < T(0)) + temp = T(0); + return old_temp; + } - private: - T temp; - T step; +private: + T temp; + T step; }; struct all_force_pairs { - template - void operator()(const Graph& g, ApplyForce apply_force) - { - typedef typename graph_traits::vertex_iterator vertex_iterator; - vertex_iterator v, end; - for (boost::tie(v, end) = vertices(g); v != end; ++v) { - vertex_iterator u = v; - for (++u; u != end; ++u) { - apply_force(*u, *v); - apply_force(*v, *u); - } + template < typename Graph, typename ApplyForce > + void operator()(const Graph& g, ApplyForce apply_force) + { + typedef typename graph_traits< Graph >::vertex_iterator vertex_iterator; + vertex_iterator v, end; + for (boost::tie(v, end) = vertices(g); v != end; ++v) + { + vertex_iterator u = v; + for (++u; u != end; ++u) + { + apply_force(*u, *v); + apply_force(*v, *u); + } + } } - } }; -template -struct grid_force_pairs +template < typename Topology, typename PositionMap > struct grid_force_pairs { - typedef typename property_traits::value_type Point; - BOOST_STATIC_ASSERT (Point::dimensions == 2); - typedef typename Topology::point_difference_type point_difference_type; - - template - explicit - grid_force_pairs(const Topology& topology, - PositionMap position, const Graph& g) + typedef typename property_traits< PositionMap >::value_type Point; + BOOST_STATIC_ASSERT(Point::dimensions == 2); + typedef typename Topology::point_difference_type point_difference_type; + + template < typename Graph > + explicit grid_force_pairs( + const Topology& topology, PositionMap position, const Graph& g) : topology(topology), position(position) - { - two_k = 2. * this->topology.volume(this->topology.extent()) / std::sqrt((double)num_vertices(g)); - } - - template - void operator()(const Graph& g, ApplyForce apply_force) - { - typedef typename graph_traits::vertex_iterator vertex_iterator; - typedef typename graph_traits::vertex_descriptor vertex_descriptor; - typedef std::list bucket_t; - typedef std::vector buckets_t; - - std::size_t columns = std::size_t(topology.extent()[0] / two_k + 1.); - std::size_t rows = std::size_t(topology.extent()[1] / two_k + 1.); - buckets_t buckets(rows * columns); - vertex_iterator v, v_end; - for (boost::tie(v, v_end) = vertices(g); v != v_end; ++v) { - std::size_t column = - std::size_t((get(position, *v)[0] + topology.extent()[0] / 2) / two_k); - std::size_t row = - std::size_t((get(position, *v)[1] + topology.extent()[1] / 2) / two_k); - - if (column >= columns) column = columns - 1; - if (row >= rows) row = rows - 1; - buckets[row * columns + column].push_back(*v); + { + two_k = 2. * this->topology.volume(this->topology.extent()) + / std::sqrt((double)num_vertices(g)); } - for (std::size_t row = 0; row < rows; ++row) - for (std::size_t column = 0; column < columns; ++column) { - bucket_t& bucket = buckets[row * columns + column]; - typedef typename bucket_t::iterator bucket_iterator; - for (bucket_iterator u = bucket.begin(); u != bucket.end(); ++u) { - // Repulse vertices in this bucket - bucket_iterator v = u; - for (++v; v != bucket.end(); ++v) { - apply_force(*u, *v); - apply_force(*v, *u); - } - - std::size_t adj_start_row = row == 0? 0 : row - 1; - std::size_t adj_end_row = row == rows - 1? row : row + 1; - std::size_t adj_start_column = column == 0? 0 : column - 1; - std::size_t adj_end_column = column == columns - 1? column : column + 1; - for (std::size_t other_row = adj_start_row; other_row <= adj_end_row; - ++other_row) - for (std::size_t other_column = adj_start_column; - other_column <= adj_end_column; ++other_column) - if (other_row != row || other_column != column) { - // Repulse vertices in this bucket - bucket_t& other_bucket - = buckets[other_row * columns + other_column]; - for (v = other_bucket.begin(); v != other_bucket.end(); ++v) { - double dist = - topology.distance(get(position, *u), get(position, *v)); - if (dist < two_k) apply_force(*u, *v); - } - } + template < typename Graph, typename ApplyForce > + void operator()(const Graph& g, ApplyForce apply_force) + { + typedef typename graph_traits< Graph >::vertex_iterator vertex_iterator; + typedef + typename graph_traits< Graph >::vertex_descriptor vertex_descriptor; + typedef std::list< vertex_descriptor > bucket_t; + typedef std::vector< bucket_t > buckets_t; + + std::size_t columns = std::size_t(topology.extent()[0] / two_k + 1.); + std::size_t rows = std::size_t(topology.extent()[1] / two_k + 1.); + buckets_t buckets(rows * columns); + vertex_iterator v, v_end; + for (boost::tie(v, v_end) = vertices(g); v != v_end; ++v) + { + std::size_t column = std::size_t( + (get(position, *v)[0] + topology.extent()[0] / 2) / two_k); + std::size_t row = std::size_t( + (get(position, *v)[1] + topology.extent()[1] / 2) / two_k); + + if (column >= columns) + column = columns - 1; + if (row >= rows) + row = rows - 1; + buckets[row * columns + column].push_back(*v); } - } - } - private: - const Topology& topology; - PositionMap position; - double two_k; + for (std::size_t row = 0; row < rows; ++row) + for (std::size_t column = 0; column < columns; ++column) + { + bucket_t& bucket = buckets[row * columns + column]; + typedef typename bucket_t::iterator bucket_iterator; + for (bucket_iterator u = bucket.begin(); u != bucket.end(); ++u) + { + // Repulse vertices in this bucket + bucket_iterator v = u; + for (++v; v != bucket.end(); ++v) + { + apply_force(*u, *v); + apply_force(*v, *u); + } + + std::size_t adj_start_row = row == 0 ? 0 : row - 1; + std::size_t adj_end_row = row == rows - 1 ? row : row + 1; + std::size_t adj_start_column = column == 0 ? 0 : column - 1; + std::size_t adj_end_column + = column == columns - 1 ? column : column + 1; + for (std::size_t other_row = adj_start_row; + other_row <= adj_end_row; ++other_row) + for (std::size_t other_column = adj_start_column; + other_column <= adj_end_column; ++other_column) + if (other_row != row || other_column != column) + { + // Repulse vertices in this bucket + bucket_t& other_bucket + = buckets[other_row * columns + + other_column]; + for (v = other_bucket.begin(); + v != other_bucket.end(); ++v) + { + double dist = topology.distance( + get(position, *u), get(position, *v)); + if (dist < two_k) + apply_force(*u, *v); + } + } + } + } + } + +private: + const Topology& topology; + PositionMap position; + double two_k; }; -template -inline grid_force_pairs -make_grid_force_pairs - (const Topology& topology, - const PositionMap& position, const Graph& g) -{ return grid_force_pairs(topology, position, g); } - -template -void -scale_graph(const Graph& g, PositionMap position, const Topology& topology, - typename Topology::point_type upper_left, typename Topology::point_type lower_right) +template < typename PositionMap, typename Topology, typename Graph > +inline grid_force_pairs< Topology, PositionMap > make_grid_force_pairs( + const Topology& topology, const PositionMap& position, const Graph& g) { - if (num_vertices(g) == 0) return; - - typedef typename Topology::point_type Point; - typedef typename Topology::point_difference_type point_difference_type; - - // Find min/max ranges - Point min_point = get(position, *vertices(g).first), max_point = min_point; - BGL_FORALL_VERTICES_T(v, g, Graph) { - min_point = topology.pointwise_min(min_point, get(position, v)); - max_point = topology.pointwise_max(max_point, get(position, v)); - } - - Point old_origin = topology.move_position_toward(min_point, 0.5, max_point); - Point new_origin = topology.move_position_toward(upper_left, 0.5, lower_right); - point_difference_type old_size = topology.difference(max_point, min_point); - point_difference_type new_size = topology.difference(lower_right, upper_left); - - // Scale to bounding box provided - BGL_FORALL_VERTICES_T(v, g, Graph) { - point_difference_type relative_loc = topology.difference(get(position, v), old_origin); - relative_loc = (relative_loc / old_size) * new_size; - put(position, v, topology.adjust(new_origin, relative_loc)); - } + return grid_force_pairs< Topology, PositionMap >(topology, position, g); } -namespace detail { - template - void - maybe_jitter_point(const Topology& topology, - const PropMap& pm, Vertex v, - const typename Topology::point_type& p2) - { - double too_close = topology.norm(topology.extent()) / 10000.; - if (topology.distance(get(pm, v), p2) < too_close) { - put(pm, v, - topology.move_position_toward(get(pm, v), 1./200, - topology.random_point())); - } - } +template < typename Graph, typename PositionMap, typename Topology > +void scale_graph(const Graph& g, PositionMap position, const Topology& topology, + typename Topology::point_type upper_left, + typename Topology::point_type lower_right) +{ + if (num_vertices(g) == 0) + return; - template - struct fr_apply_force - { - typedef typename graph_traits::vertex_descriptor vertex_descriptor; typedef typename Topology::point_type Point; - typedef typename Topology::point_difference_type PointDiff; + typedef typename Topology::point_difference_type point_difference_type; + + // Find min/max ranges + Point min_point = get(position, *vertices(g).first), max_point = min_point; + BGL_FORALL_VERTICES_T(v, g, Graph) + { + min_point = topology.pointwise_min(min_point, get(position, v)); + max_point = topology.pointwise_max(max_point, get(position, v)); + } - fr_apply_force(const Topology& topology, - const PositionMap& position, - const DisplacementMap& displacement, - RepulsiveForce repulsive_force, double k, const Graph& g) - : topology(topology), position(position), displacement(displacement), - repulsive_force(repulsive_force), k(k), g(g) - { } + Point old_origin = topology.move_position_toward(min_point, 0.5, max_point); + Point new_origin + = topology.move_position_toward(upper_left, 0.5, lower_right); + point_difference_type old_size = topology.difference(max_point, min_point); + point_difference_type new_size + = topology.difference(lower_right, upper_left); - void operator()(vertex_descriptor u, vertex_descriptor v) + // Scale to bounding box provided + BGL_FORALL_VERTICES_T(v, g, Graph) { - if (u != v) { - // When the vertices land on top of each other, move the - // first vertex away from the boundaries. - maybe_jitter_point(topology, position, u, get(position, v)); - - double dist = topology.distance(get(position, u), get(position, v)); - typename Topology::point_difference_type dispv = get(displacement, v); - if (dist == 0.) { - for (std::size_t i = 0; i < Point::dimensions; ++i) { - dispv[i] += 0.01; - } - } else { - double fr = repulsive_force(u, v, k, dist, g); - dispv += (fr / dist) * - topology.difference(get(position, v), get(position, u)); + point_difference_type relative_loc + = topology.difference(get(position, v), old_origin); + relative_loc = (relative_loc / old_size) * new_size; + put(position, v, topology.adjust(new_origin, relative_loc)); + } +} + +namespace detail +{ + template < typename Topology, typename PropMap, typename Vertex > + void maybe_jitter_point(const Topology& topology, const PropMap& pm, + Vertex v, const typename Topology::point_type& p2) + { + double too_close = topology.norm(topology.extent()) / 10000.; + if (topology.distance(get(pm, v), p2) < too_close) + { + put(pm, v, + topology.move_position_toward( + get(pm, v), 1. / 200, topology.random_point())); } - put(displacement, v, dispv); - } } - private: - const Topology& topology; - PositionMap position; - DisplacementMap displacement; - RepulsiveForce repulsive_force; - double k; - const Graph& g; - }; + template < typename Topology, typename PositionMap, + typename DisplacementMap, typename RepulsiveForce, typename Graph > + struct fr_apply_force + { + typedef + typename graph_traits< Graph >::vertex_descriptor vertex_descriptor; + typedef typename Topology::point_type Point; + typedef typename Topology::point_difference_type PointDiff; + + fr_apply_force(const Topology& topology, const PositionMap& position, + const DisplacementMap& displacement, RepulsiveForce repulsive_force, + double k, const Graph& g) + : topology(topology) + , position(position) + , displacement(displacement) + , repulsive_force(repulsive_force) + , k(k) + , g(g) + { + } + + void operator()(vertex_descriptor u, vertex_descriptor v) + { + if (u != v) + { + // When the vertices land on top of each other, move the + // first vertex away from the boundaries. + maybe_jitter_point(topology, position, u, get(position, v)); + + double dist + = topology.distance(get(position, u), get(position, v)); + typename Topology::point_difference_type dispv + = get(displacement, v); + if (dist == 0.) + { + for (std::size_t i = 0; i < Point::dimensions; ++i) + { + dispv[i] += 0.01; + } + } + else + { + double fr = repulsive_force(u, v, k, dist, g); + dispv += (fr / dist) + * topology.difference( + get(position, v), get(position, u)); + } + put(displacement, v, dispv); + } + } + + private: + const Topology& topology; + PositionMap position; + DisplacementMap displacement; + RepulsiveForce repulsive_force; + double k; + const Graph& g; + }; } // end namespace detail -template -void -fruchterman_reingold_force_directed_layout - (const Graph& g, - PositionMap position, - const Topology& topology, - AttractiveForce attractive_force, - RepulsiveForce repulsive_force, - ForcePairs force_pairs, - Cooling cool, - DisplacementMap displacement) +template < typename Topology, typename Graph, typename PositionMap, + typename AttractiveForce, typename RepulsiveForce, typename ForcePairs, + typename Cooling, typename DisplacementMap > +void fruchterman_reingold_force_directed_layout(const Graph& g, + PositionMap position, const Topology& topology, + AttractiveForce attractive_force, RepulsiveForce repulsive_force, + ForcePairs force_pairs, Cooling cool, DisplacementMap displacement) { - typedef typename graph_traits::vertex_iterator vertex_iterator; - typedef typename graph_traits::vertex_descriptor vertex_descriptor; - typedef typename graph_traits::edge_iterator edge_iterator; - - double volume = topology.volume(topology.extent()); - - // assume positions are initialized randomly - double k = pow(volume / num_vertices(g), 1. / (double)(Topology::point_difference_type::dimensions)); - - detail::fr_apply_force - apply_force(topology, position, displacement, repulsive_force, k, g); - - do { - // Calculate repulsive forces - vertex_iterator v, v_end; - for (boost::tie(v, v_end) = vertices(g); v != v_end; ++v) - put(displacement, *v, typename Topology::point_difference_type()); - force_pairs(g, apply_force); - - // Calculate attractive forces - edge_iterator e, e_end; - for (boost::tie(e, e_end) = edges(g); e != e_end; ++e) { - vertex_descriptor v = source(*e, g); - vertex_descriptor u = target(*e, g); - - // When the vertices land on top of each other, move the - // first vertex away from the boundaries. - ::boost::detail::maybe_jitter_point(topology, position, u, get(position, v)); - - typename Topology::point_difference_type delta = - topology.difference(get(position, v), get(position, u)); - double dist = topology.distance(get(position, u), get(position, v)); - double fa = attractive_force(*e, k, dist, g); - - put(displacement, v, get(displacement, v) - (fa / dist) * delta); - put(displacement, u, get(displacement, u) + (fa / dist) * delta); - } + typedef typename graph_traits< Graph >::vertex_iterator vertex_iterator; + typedef typename graph_traits< Graph >::vertex_descriptor vertex_descriptor; + typedef typename graph_traits< Graph >::edge_iterator edge_iterator; - if (double temp = cool()) { - // Update positions - BGL_FORALL_VERTICES_T (v, g, Graph) { - BOOST_USING_STD_MIN(); - BOOST_USING_STD_MAX(); - double disp_size = topology.norm(get(displacement, v)); - put(position, v, topology.adjust(get(position, v), get(displacement, v) * (min BOOST_PREVENT_MACRO_SUBSTITUTION (disp_size, temp) / disp_size))); - put(position, v, topology.bound(get(position, v))); - } - } else { - break; - } - } while (true); + double volume = topology.volume(topology.extent()); + + // assume positions are initialized randomly + double k = pow(volume / num_vertices(g), + 1. / (double)(Topology::point_difference_type::dimensions)); + + detail::fr_apply_force< Topology, PositionMap, DisplacementMap, + RepulsiveForce, Graph > + apply_force(topology, position, displacement, repulsive_force, k, g); + + do + { + // Calculate repulsive forces + vertex_iterator v, v_end; + for (boost::tie(v, v_end) = vertices(g); v != v_end; ++v) + put(displacement, *v, typename Topology::point_difference_type()); + force_pairs(g, apply_force); + + // Calculate attractive forces + edge_iterator e, e_end; + for (boost::tie(e, e_end) = edges(g); e != e_end; ++e) + { + vertex_descriptor v = source(*e, g); + vertex_descriptor u = target(*e, g); + + // When the vertices land on top of each other, move the + // first vertex away from the boundaries. + ::boost::detail::maybe_jitter_point( + topology, position, u, get(position, v)); + + typename Topology::point_difference_type delta + = topology.difference(get(position, v), get(position, u)); + double dist = topology.distance(get(position, u), get(position, v)); + double fa = attractive_force(*e, k, dist, g); + + put(displacement, v, get(displacement, v) - (fa / dist) * delta); + put(displacement, u, get(displacement, u) + (fa / dist) * delta); + } + + if (double temp = cool()) + { + // Update positions + BGL_FORALL_VERTICES_T(v, g, Graph) + { + BOOST_USING_STD_MIN(); + BOOST_USING_STD_MAX(); + double disp_size = topology.norm(get(displacement, v)); + put(position, v, + topology.adjust(get(position, v), + get(displacement, v) + * (min BOOST_PREVENT_MACRO_SUBSTITUTION( + disp_size, temp) + / disp_size))); + put(position, v, topology.bound(get(position, v))); + } + } + else + { + break; + } + } while (true); } -namespace detail { - template - struct fr_force_directed_layout - { - template - static void - run(const Graph& g, - PositionMap position, - const Topology& topology, - AttractiveForce attractive_force, - RepulsiveForce repulsive_force, - ForcePairs force_pairs, - Cooling cool, - DisplacementMap displacement, - const bgl_named_params&) +namespace detail +{ + template < typename DisplacementMap > struct fr_force_directed_layout { - fruchterman_reingold_force_directed_layout - (g, position, topology, attractive_force, repulsive_force, - force_pairs, cool, displacement); - } - }; - - template<> - struct fr_force_directed_layout - { - template - static void - run(const Graph& g, - PositionMap position, - const Topology& topology, - AttractiveForce attractive_force, - RepulsiveForce repulsive_force, - ForcePairs force_pairs, - Cooling cool, - param_not_found, - const bgl_named_params& params) + template < typename Topology, typename Graph, typename PositionMap, + typename AttractiveForce, typename RepulsiveForce, + typename ForcePairs, typename Cooling, typename Param, typename Tag, + typename Rest > + static void run(const Graph& g, PositionMap position, + const Topology& topology, AttractiveForce attractive_force, + RepulsiveForce repulsive_force, ForcePairs force_pairs, + Cooling cool, DisplacementMap displacement, + const bgl_named_params< Param, Tag, Rest >&) + { + fruchterman_reingold_force_directed_layout(g, position, topology, + attractive_force, repulsive_force, force_pairs, cool, + displacement); + } + }; + + template <> struct fr_force_directed_layout< param_not_found > { - typedef typename Topology::point_difference_type PointDiff; - std::vector displacements(num_vertices(g)); - fruchterman_reingold_force_directed_layout - (g, position, topology, attractive_force, repulsive_force, - force_pairs, cool, - make_iterator_property_map - (displacements.begin(), - choose_const_pmap(get_param(params, vertex_index), g, - vertex_index), - PointDiff())); - } - }; + template < typename Topology, typename Graph, typename PositionMap, + typename AttractiveForce, typename RepulsiveForce, + typename ForcePairs, typename Cooling, typename Param, typename Tag, + typename Rest > + static void run(const Graph& g, PositionMap position, + const Topology& topology, AttractiveForce attractive_force, + RepulsiveForce repulsive_force, ForcePairs force_pairs, + Cooling cool, param_not_found, + const bgl_named_params< Param, Tag, Rest >& params) + { + typedef typename Topology::point_difference_type PointDiff; + std::vector< PointDiff > displacements(num_vertices(g)); + fruchterman_reingold_force_directed_layout(g, position, topology, + attractive_force, repulsive_force, force_pairs, cool, + make_iterator_property_map(displacements.begin(), + choose_const_pmap( + get_param(params, vertex_index), g, vertex_index), + PointDiff())); + } + }; } // end namespace detail -template -void -fruchterman_reingold_force_directed_layout - (const Graph& g, - PositionMap position, - const Topology& topology, - const bgl_named_params& params) +template < typename Topology, typename Graph, typename PositionMap, + typename Param, typename Tag, typename Rest > +void fruchterman_reingold_force_directed_layout(const Graph& g, + PositionMap position, const Topology& topology, + const bgl_named_params< Param, Tag, Rest >& params) { - typedef typename get_param_type >::type D; - - detail::fr_force_directed_layout::run - (g, position, topology, - choose_param(get_param(params, attractive_force_t()), - square_distance_attractive_force()), - choose_param(get_param(params, repulsive_force_t()), - square_distance_repulsive_force()), - choose_param(get_param(params, force_pairs_t()), - make_grid_force_pairs(topology, position, g)), - choose_param(get_param(params, cooling_t()), - linear_cooling(100)), - get_param(params, vertex_displacement_t()), - params); + typedef typename get_param_type< vertex_displacement_t, + bgl_named_params< Param, Tag, Rest > >::type D; + + detail::fr_force_directed_layout< D >::run(g, position, topology, + choose_param(get_param(params, attractive_force_t()), + square_distance_attractive_force()), + choose_param(get_param(params, repulsive_force_t()), + square_distance_repulsive_force()), + choose_param(get_param(params, force_pairs_t()), + make_grid_force_pairs(topology, position, g)), + choose_param( + get_param(params, cooling_t()), linear_cooling< double >(100)), + get_param(params, vertex_displacement_t()), params); } -template -void -fruchterman_reingold_force_directed_layout - (const Graph& g, - PositionMap position, - const Topology& topology) +template < typename Topology, typename Graph, typename PositionMap > +void fruchterman_reingold_force_directed_layout( + const Graph& g, PositionMap position, const Topology& topology) { - fruchterman_reingold_force_directed_layout - (g, position, topology, - attractive_force(square_distance_attractive_force())); + fruchterman_reingold_force_directed_layout(g, position, topology, + attractive_force(square_distance_attractive_force())); } } // end namespace boost -#include BOOST_GRAPH_MPI_INCLUDE() +#include BOOST_GRAPH_MPI_INCLUDE(< boost / graph / distributed / fruchterman_reingold.hpp >) #endif // BOOST_GRAPH_FRUCHTERMAN_REINGOLD_FORCE_DIRECTED_LAYOUT_HPP diff --git a/include/boost/graph/geodesic_distance.hpp b/include/boost/graph/geodesic_distance.hpp index d76d321e1..0da9666b5 100644 --- a/include/boost/graph/geodesic_distance.hpp +++ b/include/boost/graph/geodesic_distance.hpp @@ -13,23 +13,22 @@ namespace boost { -template > +template < typename Graph, typename DistanceType, typename ResultType, + typename Divides = std::divides< ResultType > > struct mean_geodesic_measure - : public geodesic_measure +: public geodesic_measure< Graph, DistanceType, ResultType > { - typedef geodesic_measure base_type; + typedef geodesic_measure< Graph, DistanceType, ResultType > base_type; typedef typename base_type::distance_type distance_type; typedef typename base_type::result_type result_type; - result_type operator ()(distance_type d, const Graph& g) + result_type operator()(distance_type d, const Graph& g) { - BOOST_CONCEPT_ASSERT(( VertexListGraphConcept )); - BOOST_CONCEPT_ASSERT(( NumericValueConcept )); - BOOST_CONCEPT_ASSERT(( NumericValueConcept )); - BOOST_CONCEPT_ASSERT(( AdaptableBinaryFunctionConcept )); + BOOST_CONCEPT_ASSERT((VertexListGraphConcept< Graph >)); + BOOST_CONCEPT_ASSERT((NumericValueConcept< DistanceType >)); + BOOST_CONCEPT_ASSERT((NumericValueConcept< ResultType >)); + BOOST_CONCEPT_ASSERT((AdaptableBinaryFunctionConcept< Divides, + ResultType, ResultType, ResultType >)); return (d == base_type::infinite_distance()) ? base_type::infinite_result() @@ -38,18 +37,22 @@ struct mean_geodesic_measure Divides div; }; -template -inline mean_geodesic_measure::value_type, double> +template < typename Graph, typename DistanceMap > +inline mean_geodesic_measure< Graph, + typename property_traits< DistanceMap >::value_type, double > measure_mean_geodesic(const Graph&, DistanceMap) { - return mean_geodesic_measure::value_type, double>(); + return mean_geodesic_measure< Graph, + typename property_traits< DistanceMap >::value_type, double >(); } -template -inline mean_geodesic_measure::value_type, T> +template < typename T, typename Graph, typename DistanceMap > +inline mean_geodesic_measure< Graph, + typename property_traits< DistanceMap >::value_type, T > measure_mean_geodesic(const Graph&, DistanceMap) { - return mean_geodesic_measure::value_type, T>(); + return mean_geodesic_measure< Graph, + typename property_traits< DistanceMap >::value_type, T >(); } // This is a little different because it's expected that the result type @@ -60,113 +63,110 @@ measure_mean_geodesic(const Graph&, DistanceMap) // // This type is a little under-genericized... It needs generic parameters // for addition and division. -template +template < typename Graph, typename DistanceType > struct mean_graph_distance_measure - : public geodesic_measure +: public geodesic_measure< Graph, DistanceType, DistanceType > { - typedef geodesic_measure base_type; + typedef geodesic_measure< Graph, DistanceType, DistanceType > base_type; typedef typename base_type::distance_type distance_type; typedef typename base_type::result_type result_type; - inline result_type operator ()(distance_type d, const Graph& g) + inline result_type operator()(distance_type d, const Graph& g) { - BOOST_CONCEPT_ASSERT(( VertexListGraphConcept )); - BOOST_CONCEPT_ASSERT(( NumericValueConcept )); + BOOST_CONCEPT_ASSERT((VertexListGraphConcept< Graph >)); + BOOST_CONCEPT_ASSERT((NumericValueConcept< DistanceType >)); - if(d == base_type::infinite_distance()) { + if (d == base_type::infinite_distance()) + { return base_type::infinite_result(); } - else { + else + { return d / result_type(num_vertices(g)); } } }; -template -inline mean_graph_distance_measure::value_type> +template < typename Graph, typename DistanceMap > +inline mean_graph_distance_measure< Graph, + typename property_traits< DistanceMap >::value_type > measure_graph_mean_geodesic(const Graph&, DistanceMap) { - typedef typename property_traits::value_type T; - return mean_graph_distance_measure(); + typedef typename property_traits< DistanceMap >::value_type T; + return mean_graph_distance_measure< Graph, T >(); } -template -inline typename Measure::result_type -mean_geodesic(const Graph& g, - DistanceMap dist, - Measure measure, - Combinator combine) +template < typename Graph, typename DistanceMap, typename Measure, + typename Combinator > +inline typename Measure::result_type mean_geodesic( + const Graph& g, DistanceMap dist, Measure measure, Combinator combine) { - BOOST_CONCEPT_ASSERT(( DistanceMeasureConcept )); + BOOST_CONCEPT_ASSERT((DistanceMeasureConcept< Measure, Graph >)); typedef typename Measure::distance_type Distance; Distance n = detail::combine_distances(g, dist, combine, Distance(0)); return measure(n, g); } -template -inline typename Measure::result_type -mean_geodesic(const Graph& g, DistanceMap dist, Measure measure) +template < typename Graph, typename DistanceMap, typename Measure > +inline typename Measure::result_type mean_geodesic( + const Graph& g, DistanceMap dist, Measure measure) { - BOOST_CONCEPT_ASSERT(( DistanceMeasureConcept )); + BOOST_CONCEPT_ASSERT((DistanceMeasureConcept< Measure, Graph >)); typedef typename Measure::distance_type Distance; - return mean_geodesic(g, dist, measure, std::plus()); + return mean_geodesic(g, dist, measure, std::plus< Distance >()); } -template -inline double -mean_geodesic(const Graph& g, DistanceMap dist) -{ return mean_geodesic(g, dist, measure_mean_geodesic(g, dist)); } - -template -inline T -mean_geodesic(const Graph& g, DistanceMap dist) -{ return mean_geodesic(g, dist, measure_mean_geodesic(g, dist)); } - - -template -inline typename property_traits::value_type -all_mean_geodesics(const Graph& g, - DistanceMatrixMap dist, - GeodesicMap geo, - Measure measure) +template < typename Graph, typename DistanceMap > +inline double mean_geodesic(const Graph& g, DistanceMap dist) { - BOOST_CONCEPT_ASSERT(( VertexListGraphConcept )); - typedef typename graph_traits::vertex_descriptor Vertex; - typedef typename graph_traits::vertex_iterator VertexIterator; - BOOST_CONCEPT_ASSERT(( ReadablePropertyMapConcept )); - typedef typename property_traits::value_type DistanceMap; - BOOST_CONCEPT_ASSERT(( DistanceMeasureConcept )); + return mean_geodesic(g, dist, measure_mean_geodesic(g, dist)); +} + +template < typename T, typename Graph, typename DistanceMap > +inline T mean_geodesic(const Graph& g, DistanceMap dist) +{ + return mean_geodesic(g, dist, measure_mean_geodesic< T >(g, dist)); +} + +template < typename Graph, typename DistanceMatrixMap, typename GeodesicMap, + typename Measure > +inline typename property_traits< GeodesicMap >::value_type all_mean_geodesics( + const Graph& g, DistanceMatrixMap dist, GeodesicMap geo, Measure measure) +{ + BOOST_CONCEPT_ASSERT((VertexListGraphConcept< Graph >)); + typedef typename graph_traits< Graph >::vertex_descriptor Vertex; + typedef typename graph_traits< Graph >::vertex_iterator VertexIterator; + BOOST_CONCEPT_ASSERT( + (ReadablePropertyMapConcept< DistanceMatrixMap, Vertex >)); + typedef + typename property_traits< DistanceMatrixMap >::value_type DistanceMap; + BOOST_CONCEPT_ASSERT((DistanceMeasureConcept< Measure, Graph >)); typedef typename Measure::result_type Result; - BOOST_CONCEPT_ASSERT(( WritablePropertyMapConcept )); - BOOST_CONCEPT_ASSERT(( NumericValueConcept )); + BOOST_CONCEPT_ASSERT((WritablePropertyMapConcept< GeodesicMap, Vertex >)); + BOOST_CONCEPT_ASSERT((NumericValueConcept< Result >)); // NOTE: We could compute the mean geodesic here by performing additional // computations (i.e., adding and dividing). However, I don't really feel // like fully genericizing the entire operation yet so I'm not going to. - Result inf = numeric_values::infinity(); - Result sum = numeric_values::zero(); + Result inf = numeric_values< Result >::infinity(); + Result sum = numeric_values< Result >::zero(); VertexIterator i, end; - for(boost::tie(i, end) = vertices(g); i != end; ++i) { + for (boost::tie(i, end) = vertices(g); i != end; ++i) + { DistanceMap dm = get(dist, *i); Result r = mean_geodesic(g, dm, measure); put(geo, *i, r); // compute the sum along with geodesics - if(r == inf) { + if (r == inf) + { sum = inf; } - else if(sum != inf) { + else if (sum != inf) + { sum += r; } } @@ -175,36 +175,41 @@ all_mean_geodesics(const Graph& g, return sum / Result(num_vertices(g)); } -template -inline typename property_traits::value_type -all_mean_geodesics(const Graph& g, DistanceMatrixMap dist, GeodesicMap geo) +template < typename Graph, typename DistanceMatrixMap, typename GeodesicMap > +inline typename property_traits< GeodesicMap >::value_type all_mean_geodesics( + const Graph& g, DistanceMatrixMap dist, GeodesicMap geo) { - BOOST_CONCEPT_ASSERT(( GraphConcept )); - typedef typename graph_traits::vertex_descriptor Vertex; - BOOST_CONCEPT_ASSERT(( ReadablePropertyMapConcept )); - typedef typename property_traits::value_type DistanceMap; - BOOST_CONCEPT_ASSERT(( WritablePropertyMapConcept )); - typedef typename property_traits::value_type Result; - - return all_mean_geodesics(g, dist, geo, measure_mean_geodesic(g, DistanceMap())); + BOOST_CONCEPT_ASSERT((GraphConcept< Graph >)); + typedef typename graph_traits< Graph >::vertex_descriptor Vertex; + BOOST_CONCEPT_ASSERT( + (ReadablePropertyMapConcept< DistanceMatrixMap, Vertex >)); + typedef + typename property_traits< DistanceMatrixMap >::value_type DistanceMap; + BOOST_CONCEPT_ASSERT((WritablePropertyMapConcept< GeodesicMap, Vertex >)); + typedef typename property_traits< GeodesicMap >::value_type Result; + + return all_mean_geodesics( + g, dist, geo, measure_mean_geodesic< Result >(g, DistanceMap())); } - -template -inline typename Measure::result_type -small_world_distance(const Graph& g, GeodesicMap geo, Measure measure) +template < typename Graph, typename GeodesicMap, typename Measure > +inline typename Measure::result_type small_world_distance( + const Graph& g, GeodesicMap geo, Measure measure) { - BOOST_CONCEPT_ASSERT(( DistanceMeasureConcept )); + BOOST_CONCEPT_ASSERT((DistanceMeasureConcept< Measure, Graph >)); typedef typename Measure::result_type Result; - Result sum = detail::combine_distances(g, geo, std::plus(), Result(0)); + Result sum + = detail::combine_distances(g, geo, std::plus< Result >(), Result(0)); return measure(sum, g); } -template -inline typename property_traits::value_type -small_world_distance(const Graph& g, GeodesicMap geo) -{ return small_world_distance(g, geo, measure_graph_mean_geodesic(g, geo)); } +template < typename Graph, typename GeodesicMap > +inline typename property_traits< GeodesicMap >::value_type small_world_distance( + const Graph& g, GeodesicMap geo) +{ + return small_world_distance(g, geo, measure_graph_mean_geodesic(g, geo)); +} } diff --git a/include/boost/graph/graph_archetypes.hpp b/include/boost/graph/graph_archetypes.hpp index 81f9c2c8a..428c3c5af 100644 --- a/include/boost/graph/graph_archetypes.hpp +++ b/include/boost/graph/graph_archetypes.hpp @@ -15,22 +15,28 @@ #include #include -namespace boost { // should use a different namespace for this +namespace boost +{ // should use a different namespace for this - namespace detail { - struct null_graph_archetype : public null_archetype<> { - struct traversal_category { }; +namespace detail +{ + struct null_graph_archetype : public null_archetype<> + { + struct traversal_category + { + }; }; - } - - //=========================================================================== - template - struct incidence_graph_archetype : public Base - { +struct incidence_graph_archetype : public Base +{ typedef typename Base::traversal_category base_trav_cat; - struct traversal_category - : public incidence_graph_tag, public base_trav_cat { }; + struct traversal_category : public incidence_graph_tag, public base_trav_cat + { + }; #if 0 typedef immutable_graph_tag mutability_category; #endif @@ -38,13 +44,14 @@ namespace boost { // should use a different namespace for this typedef unsigned int degree_size_type; typedef unsigned int vertices_size_type; typedef unsigned int edges_size_type; - struct edge_descriptor { - edge_descriptor() { } - edge_descriptor(const detail::dummy_constructor&) { } - bool operator==(const edge_descriptor&) const { return false; } - bool operator!=(const edge_descriptor&) const { return false; } + struct edge_descriptor + { + edge_descriptor() {} + edge_descriptor(const detail::dummy_constructor&) {} + bool operator==(const edge_descriptor&) const { return false; } + bool operator!=(const edge_descriptor&) const { return false; } }; - typedef input_iterator_archetype out_edge_iterator; + typedef input_iterator_archetype< edge_descriptor > out_edge_iterator; typedef Directed directed_category; typedef ParallelCategory edge_parallel_category; @@ -54,51 +61,55 @@ namespace boost { // should use a different namespace for this typedef void vertex_iterator; typedef void edge_iterator; - static vertex_descriptor null_vertex() {return vertex_descriptor();} - }; - template - V source(const typename incidence_graph_archetype::edge_descriptor&, - const incidence_graph_archetype& ) - { - return V(static_object::get()); - } - template - V target(const typename incidence_graph_archetype::edge_descriptor&, - const incidence_graph_archetype& ) - { - return V(static_object::get()); - } - - template - std::pair::out_edge_iterator, - typename incidence_graph_archetype::out_edge_iterator> - out_edges(const V&, const incidence_graph_archetype& ) - { - typedef typename incidence_graph_archetype::out_edge_iterator Iter; + static vertex_descriptor null_vertex() { return vertex_descriptor(); } +}; +template < typename V, typename D, typename P, typename B > +V source( + const typename incidence_graph_archetype< V, D, P, B >::edge_descriptor&, + const incidence_graph_archetype< V, D, P, B >&) +{ + return V(static_object< detail::dummy_constructor >::get()); +} +template < typename V, typename D, typename P, typename B > +V target( + const typename incidence_graph_archetype< V, D, P, B >::edge_descriptor&, + const incidence_graph_archetype< V, D, P, B >&) +{ + return V(static_object< detail::dummy_constructor >::get()); +} + +template < typename V, typename D, typename P, typename B > +std::pair< typename incidence_graph_archetype< V, D, P, B >::out_edge_iterator, + typename incidence_graph_archetype< V, D, P, B >::out_edge_iterator > +out_edges(const V&, const incidence_graph_archetype< V, D, P, B >&) +{ + typedef typename incidence_graph_archetype< V, D, P, B >::out_edge_iterator + Iter; return std::make_pair(Iter(), Iter()); - } - - template - typename incidence_graph_archetype::degree_size_type - out_degree(const V&, const incidence_graph_archetype& ) - { +} + +template < typename V, typename D, typename P, typename B > +typename incidence_graph_archetype< V, D, P, B >::degree_size_type out_degree( + const V&, const incidence_graph_archetype< V, D, P, B >&) +{ return 0; - } +} - //=========================================================================== - template - struct adjacency_graph_archetype : public Base - { +struct adjacency_graph_archetype : public Base +{ typedef typename Base::traversal_category base_trav_cat; - struct traversal_category - : public adjacency_graph_tag, public base_trav_cat { }; + struct traversal_category : public adjacency_graph_tag, public base_trav_cat + { + }; typedef Vertex vertex_descriptor; typedef unsigned int degree_size_type; typedef unsigned int vertices_size_type; typedef unsigned int edges_size_type; typedef void edge_descriptor; - typedef input_iterator_archetype adjacency_iterator; + typedef input_iterator_archetype< Vertex > adjacency_iterator; typedef Directed directed_category; typedef ParallelCategory edge_parallel_category; @@ -108,38 +119,41 @@ namespace boost { // should use a different namespace for this typedef void vertex_iterator; typedef void edge_iterator; - static vertex_descriptor null_vertex() {return vertex_descriptor();} - }; - - template - std::pair::adjacency_iterator, - typename adjacency_graph_archetype::adjacency_iterator> - adjacent_vertices(const V&, const adjacency_graph_archetype& ) - { - typedef typename adjacency_graph_archetype::adjacency_iterator Iter; + static vertex_descriptor null_vertex() { return vertex_descriptor(); } +}; + +template < typename V, typename D, typename P, typename B > +std::pair< typename adjacency_graph_archetype< V, D, P, B >::adjacency_iterator, + typename adjacency_graph_archetype< V, D, P, B >::adjacency_iterator > +adjacent_vertices(const V&, const adjacency_graph_archetype< V, D, P, B >&) +{ + typedef typename adjacency_graph_archetype< V, D, P, B >::adjacency_iterator + Iter; return std::make_pair(Iter(), Iter()); - } +} - template - typename adjacency_graph_archetype::degree_size_type - out_degree(const V&, const adjacency_graph_archetype& ) - { +template < typename V, typename D, typename P, typename B > +typename adjacency_graph_archetype< V, D, P, B >::degree_size_type out_degree( + const V&, const adjacency_graph_archetype< V, D, P, B >&) +{ return 0; - } +} - //=========================================================================== - template - struct vertex_list_graph_archetype : public Base - { - typedef incidence_graph_archetype - Incidence; - typedef adjacency_graph_archetype - Adjacency; +struct vertex_list_graph_archetype : public Base +{ + typedef incidence_graph_archetype< Vertex, Directed, ParallelCategory > + Incidence; + typedef adjacency_graph_archetype< Vertex, Directed, ParallelCategory > + Adjacency; typedef typename Base::traversal_category base_trav_cat; - struct traversal_category - : public vertex_list_graph_tag, public base_trav_cat { }; + struct traversal_category : public vertex_list_graph_tag, + public base_trav_cat + { + }; #if 0 typedef immutable_graph_tag mutability_category; #endif @@ -149,7 +163,7 @@ namespace boost { // should use a different namespace for this typedef typename Incidence::out_edge_iterator out_edge_iterator; typedef typename Adjacency::adjacency_iterator adjacency_iterator; - typedef input_iterator_archetype vertex_iterator; + typedef input_iterator_archetype< Vertex > vertex_iterator; typedef unsigned int vertices_size_type; typedef unsigned int edges_size_type; @@ -159,140 +173,154 @@ namespace boost { // should use a different namespace for this typedef void in_edge_iterator; typedef void edge_iterator; - static vertex_descriptor null_vertex() {return vertex_descriptor();} - }; - - template - std::pair::vertex_iterator, - typename vertex_list_graph_archetype::vertex_iterator> - vertices(const vertex_list_graph_archetype& ) - { - typedef typename vertex_list_graph_archetype::vertex_iterator Iter; + static vertex_descriptor null_vertex() { return vertex_descriptor(); } +}; + +template < typename V, typename D, typename P, typename B > +std::pair< typename vertex_list_graph_archetype< V, D, P, B >::vertex_iterator, + typename vertex_list_graph_archetype< V, D, P, B >::vertex_iterator > +vertices(const vertex_list_graph_archetype< V, D, P, B >&) +{ + typedef typename vertex_list_graph_archetype< V, D, P, B >::vertex_iterator + Iter; return std::make_pair(Iter(), Iter()); - } +} - template - typename vertex_list_graph_archetype::vertices_size_type - num_vertices(const vertex_list_graph_archetype& ) - { +template < typename V, typename D, typename P, typename B > +typename vertex_list_graph_archetype< V, D, P, B >::vertices_size_type +num_vertices(const vertex_list_graph_archetype< V, D, P, B >&) +{ return 0; - } +} - // ambiguously inherited from incidence graph and adjacency graph - template - typename vertex_list_graph_archetype::degree_size_type - out_degree(const V&, const vertex_list_graph_archetype& ) - { +// ambiguously inherited from incidence graph and adjacency graph +template < typename V, typename D, typename P, typename B > +typename vertex_list_graph_archetype< V, D, P, B >::degree_size_type out_degree( + const V&, const vertex_list_graph_archetype< V, D, P, B >&) +{ return 0; - } +} - //=========================================================================== +//=========================================================================== - struct property_graph_archetype_tag { }; +struct property_graph_archetype_tag +{ +}; - template - struct property_graph_archetype : public GraphArchetype - { +template < typename GraphArchetype, typename Property, typename ValueArch > +struct property_graph_archetype : public GraphArchetype +{ typedef property_graph_archetype_tag graph_tag; typedef ValueArch vertex_property_type; typedef ValueArch edge_property_type; - }; - - struct choose_edge_property_map_archetype { - template - struct bind_ { - typedef mutable_lvalue_property_map_archetype - type; - typedef lvalue_property_map_archetype - const_type; +}; + +struct choose_edge_property_map_archetype +{ + template < typename Graph, typename Property, typename Tag > struct bind_ + { + typedef mutable_lvalue_property_map_archetype< + typename Graph::edge_descriptor, Property > + type; + typedef lvalue_property_map_archetype< typename Graph::edge_descriptor, + Property > + const_type; }; - }; - template <> - struct edge_property_selector { +}; +template <> struct edge_property_selector< property_graph_archetype_tag > +{ typedef choose_edge_property_map_archetype type; - }; - - struct choose_vertex_property_map_archetype { - template - struct bind_ { - typedef mutable_lvalue_property_map_archetype - type; - typedef lvalue_property_map_archetype - const_type; +}; + +struct choose_vertex_property_map_archetype +{ + template < typename Graph, typename Property, typename Tag > struct bind_ + { + typedef mutable_lvalue_property_map_archetype< + typename Graph::vertex_descriptor, Property > + type; + typedef lvalue_property_map_archetype< + typename Graph::vertex_descriptor, Property > + const_type; }; - }; +}; - template <> - struct vertex_property_selector { +template <> struct vertex_property_selector< property_graph_archetype_tag > +{ typedef choose_vertex_property_map_archetype type; - }; - - template - typename property_map, P>::type - get(P, property_graph_archetype&) { - typename property_map, P>::type pmap; - return pmap; - } +}; - template - typename property_map, P>::const_type - get(P, const property_graph_archetype&) { - typename property_map, P>::const_type pmap; +template < typename G, typename P, typename V > +typename property_map< property_graph_archetype< G, P, V >, P >::type get( + P, property_graph_archetype< G, P, V >&) +{ + typename property_map< property_graph_archetype< G, P, V >, P >::type pmap; + return pmap; +} + +template < typename G, typename P, typename V > +typename property_map< property_graph_archetype< G, P, V >, P >::const_type get( + P, const property_graph_archetype< G, P, V >&) +{ + typename property_map< property_graph_archetype< G, P, V >, P >::const_type + pmap; return pmap; - } - - template - typename property_traits, P>::const_type>::value_type - get(P p, const property_graph_archetype& g, K k) { - return get( get(p, g), k); - } - - template - void - put(P p, property_graph_archetype& g, - const Key& key, const V& value) - { - typedef typename boost::property_map, P>::type Map; +} + +template < typename G, typename P, typename K, typename V > +typename property_traits< typename property_map< + property_graph_archetype< G, P, V >, P >::const_type >::value_type +get(P p, const property_graph_archetype< G, P, V >& g, K k) +{ + return get(get(p, g), k); +} + +template < typename G, typename P, typename V, typename Key > +void put( + P p, property_graph_archetype< G, P, V >& g, const Key& key, const V& value) +{ + typedef typename boost::property_map< property_graph_archetype< G, P, V >, + P >::type Map; Map pmap = get(p, g); put(pmap, key, value); - } - - struct color_value_archetype { - color_value_archetype() { } - color_value_archetype(detail::dummy_constructor) { } - bool operator==(const color_value_archetype& ) const { return true; } - bool operator!=(const color_value_archetype& ) const { return true; } - }; - template <> - struct color_traits { +} + +struct color_value_archetype +{ + color_value_archetype() {} + color_value_archetype(detail::dummy_constructor) {} + bool operator==(const color_value_archetype&) const { return true; } + bool operator!=(const color_value_archetype&) const { return true; } +}; +template <> struct color_traits< color_value_archetype > +{ static color_value_archetype white() - { - return color_value_archetype - (static_object::get()); + { + return color_value_archetype( + static_object< detail::dummy_constructor >::get()); } static color_value_archetype gray() { - return color_value_archetype - (static_object::get()); + return color_value_archetype( + static_object< detail::dummy_constructor >::get()); } static color_value_archetype black() { - return color_value_archetype - (static_object::get()); + return color_value_archetype( + static_object< detail::dummy_constructor >::get()); } - }; +}; - template - class buffer_archetype { - public: +template < typename T > class buffer_archetype +{ +public: void push(const T&) {} void pop() {} - T& top() { return static_object::get(); } - const T& top() const { return static_object::get(); } + T& top() { return static_object< T >::get(); } + const T& top() const { return static_object< T >::get(); } bool empty() const { return true; } - }; - -} // namespace boost +}; +} // namespace boost #endif // BOOST_GRAPH_ARCHETYPES_HPP diff --git a/include/boost/graph/graph_as_tree.hpp b/include/boost/graph/graph_as_tree.hpp index 721e503e8..ce6057c98 100644 --- a/include/boost/graph/graph_as_tree.hpp +++ b/include/boost/graph/graph_as_tree.hpp @@ -19,131 +19,137 @@ #include #include -namespace boost { +namespace boost +{ - template - class graph_as_tree_base - { +template < class Graph, class Node, class ChIt, class Derived > +class graph_as_tree_base +{ typedef Derived Tree; - public: + +public: typedef Node node_descriptor; typedef ChIt children_iterator; - - graph_as_tree_base(Graph& g, Node root) : _g(g), _root(root) { } - + + graph_as_tree_base(Graph& g, Node root) : _g(g), _root(root) {} + friend Node root(const Tree& t) { return t._root; } - - template - friend std::pair - children(N n, const Tree& t) { return adjacent_vertices(n, t._g); } - - template - friend Node parent(N n, const Tree& t) { - return boost::get(t.parent_pa(), n); + + template < class N > + friend std::pair< ChIt, ChIt > children(N n, const Tree& t) + { + return adjacent_vertices(n, t._g); } - + + template < class N > friend Node parent(N n, const Tree& t) + { + return boost::get(t.parent_pa(), n); + } + Graph& _g; Node _root; - }; - - struct graph_as_tree_tag { }; - - template ::vertex_descriptor - , class ChIt - = typename graph_traits::adjacency_iterator - > - class graph_as_tree - : public graph_as_tree_base > - { +}; + +struct graph_as_tree_tag +{ +}; + +template < class Graph, class ParentMap, + class Node = typename graph_traits< Graph >::vertex_descriptor, + class ChIt = typename graph_traits< Graph >::adjacency_iterator > +class graph_as_tree : public graph_as_tree_base< Graph, Node, ChIt, + graph_as_tree< Graph, ParentMap, Node, ChIt > > +{ typedef graph_as_tree self; - typedef graph_as_tree_base super; - public: - graph_as_tree(Graph& g, Node root) : super(g, root) { } - - graph_as_tree(Graph& g, Node root, ParentMap p) : super(g, root), _p(p) { - breadth_first_search(g, root, - visitor(make_bfs_visitor - (record_predecessors(p, boost::on_tree_edge())))); + typedef graph_as_tree_base< Graph, Node, ChIt, self > super; + +public: + graph_as_tree(Graph& g, Node root) : super(g, root) {} + + graph_as_tree(Graph& g, Node root, ParentMap p) : super(g, root), _p(p) + { + breadth_first_search(g, root, + visitor(make_bfs_visitor( + record_predecessors(p, boost::on_tree_edge())))); } ParentMap parent_pa() const { return _p; } typedef graph_as_tree_tag graph_tag; // for property_map - protected: +protected: ParentMap _p; - }; - - - namespace detail { - - struct graph_as_tree_vertex_property_selector { - template - struct bind_ { - typedef typename GraphAsTree::base_type Graph; - typedef property_map PMap; - typedef typename PMap::type type; - typedef typename PMap::const_type const_type; - }; +}; + +namespace detail +{ + + struct graph_as_tree_vertex_property_selector + { + template < typename GraphAsTree, typename Property, typename Tag > + struct bind_ + { + typedef typename GraphAsTree::base_type Graph; + typedef property_map< Graph, Tag > PMap; + typedef typename PMap::type type; + typedef typename PMap::const_type const_type; + }; }; - struct graph_as_tree_edge_property_selector { - template - struct bind_ { - typedef typename GraphAsTree::base_type Graph; - typedef property_map PMap; - typedef typename PMap::type type; - typedef typename PMap::const_type const_type; - }; + struct graph_as_tree_edge_property_selector + { + template < typename GraphAsTree, typename Property, typename Tag > + struct bind_ + { + typedef typename GraphAsTree::base_type Graph; + typedef property_map< Graph, Tag > PMap; + typedef typename PMap::type type; + typedef typename PMap::const_type const_type; + }; }; - } // namespace detail +} // namespace detail - template <> - struct vertex_property_selector { +template <> struct vertex_property_selector< graph_as_tree_tag > +{ typedef detail::graph_as_tree_vertex_property_selector type; - }; +}; - template <> - struct edge_property_selector { +template <> struct edge_property_selector< graph_as_tree_tag > +{ typedef detail::graph_as_tree_edge_property_selector type; - }; +}; - template - typename property_map::type - get(Property p, graph_as_tree& g) - { +template < typename Graph, typename P, typename N, typename C, + typename Property > +typename property_map< Graph, Property >::type get( + Property p, graph_as_tree< Graph, P, N, C >& g) +{ return get(p, g._g); - } +} - template - typename property_map::const_type - get(Property p, const graph_as_tree& g) - { +template < typename Graph, typename P, typename N, typename C, + typename Property > +typename property_map< Graph, Property >::const_type get( + Property p, const graph_as_tree< Graph, P, N, C >& g) +{ const Graph& gref = g._g; // in case GRef is non-const return get(p, gref); - } - - template - typename property_traits< - typename property_map::const_type - >::value_type - get(Property p, const graph_as_tree& g, const Key& k) - { +} + +template < typename Graph, typename P, typename N, typename C, + typename Property, typename Key > +typename property_traits< + typename property_map< Graph, Property >::const_type >::value_type +get(Property p, const graph_as_tree< Graph, P, N, C >& g, const Key& k) +{ return get(p, g._g, k); - } - - template - void - put(Property p, const graph_as_tree& g, const Key& k, - const Value& val) - { +} + +template < typename Graph, typename P, typename N, typename C, + typename Property, typename Key, typename Value > +void put(Property p, const graph_as_tree< Graph, P, N, C >& g, const Key& k, + const Value& val) +{ put(p, g._g, k, val); - } +} } // namespace boost diff --git a/include/boost/graph/graph_concepts.hpp b/include/boost/graph/graph_concepts.hpp index 3b873a823..19e4df82d 100644 --- a/include/boost/graph/graph_concepts.hpp +++ b/include/boost/graph/graph_concepts.hpp @@ -37,156 +37,158 @@ namespace boost // // It is needed in order to allow us to write using boost::vertices as // needed for ADL when using vector_as_graph below. -#if !defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP) \ - && !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564)) -# define BOOST_VECTOR_AS_GRAPH_GRAPH_ADL_HACK +#if !defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP) \ + && !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564)) +#define BOOST_VECTOR_AS_GRAPH_GRAPH_ADL_HACK #endif #ifdef BOOST_VECTOR_AS_GRAPH_GRAPH_ADL_HACK -template +template < class T > typename T::ThereReallyIsNoMemberByThisNameInT vertices(T const&); #endif - namespace concepts { - BOOST_concept(MultiPassInputIterator,(T)) { - BOOST_CONCEPT_USAGE(MultiPassInputIterator) { - BOOST_CONCEPT_ASSERT((InputIterator)); - } - }; +namespace concepts +{ + BOOST_concept(MultiPassInputIterator, (T)) { BOOST_CONCEPT_USAGE( + MultiPassInputIterator) { BOOST_CONCEPT_ASSERT((InputIterator< T >)); +} +}; - BOOST_concept(Graph,(G)) +BOOST_concept(Graph, (G)) +{ + typedef typename graph_traits< G >::vertex_descriptor vertex_descriptor; + typedef typename graph_traits< G >::edge_descriptor edge_descriptor; + typedef typename graph_traits< G >::directed_category directed_category; + typedef typename graph_traits< G >::edge_parallel_category + edge_parallel_category; + typedef typename graph_traits< G >::traversal_category traversal_category; + + BOOST_CONCEPT_USAGE(Graph) { - typedef typename graph_traits::vertex_descriptor vertex_descriptor; - typedef typename graph_traits::edge_descriptor edge_descriptor; - typedef typename graph_traits::directed_category directed_category; - typedef typename graph_traits::edge_parallel_category edge_parallel_category; - typedef typename graph_traits::traversal_category traversal_category; - - BOOST_CONCEPT_USAGE(Graph) - { - BOOST_CONCEPT_ASSERT((DefaultConstructible)); - BOOST_CONCEPT_ASSERT((EqualityComparable)); - BOOST_CONCEPT_ASSERT((Assignable)); - } - G g; - }; - - BOOST_concept(IncidenceGraph,(G)) - : Graph + BOOST_CONCEPT_ASSERT((DefaultConstructible< vertex_descriptor >)); + BOOST_CONCEPT_ASSERT((EqualityComparable< vertex_descriptor >)); + BOOST_CONCEPT_ASSERT((Assignable< vertex_descriptor >)); + } + G g; +}; + +BOOST_concept(IncidenceGraph, (G)) : Graph< G > +{ + typedef typename graph_traits< G >::edge_descriptor edge_descriptor; + typedef typename graph_traits< G >::out_edge_iterator out_edge_iterator; + typedef typename graph_traits< G >::degree_size_type degree_size_type; + typedef typename graph_traits< G >::traversal_category traversal_category; + + BOOST_STATIC_ASSERT( + (boost::mpl::not_< boost::is_same< out_edge_iterator, void > >::value)); + BOOST_STATIC_ASSERT( + (boost::mpl::not_< boost::is_same< degree_size_type, void > >::value)); + + BOOST_CONCEPT_USAGE(IncidenceGraph) { - typedef typename graph_traits::edge_descriptor edge_descriptor; - typedef typename graph_traits::out_edge_iterator out_edge_iterator; - typedef typename graph_traits::degree_size_type degree_size_type; - typedef typename graph_traits::traversal_category traversal_category; - - BOOST_STATIC_ASSERT((boost::mpl::not_ >::value)); - BOOST_STATIC_ASSERT((boost::mpl::not_ >::value)); - - BOOST_CONCEPT_USAGE(IncidenceGraph) { - BOOST_CONCEPT_ASSERT((MultiPassInputIterator)); - BOOST_CONCEPT_ASSERT((DefaultConstructible)); - BOOST_CONCEPT_ASSERT((EqualityComparable)); - BOOST_CONCEPT_ASSERT((Assignable)); - BOOST_CONCEPT_ASSERT((Convertible)); - - p = out_edges(u, g); - n = out_degree(u, g); - e = *p.first; - u = source(e, g); - v = target(e, g); - const_constraints(g); - } - void const_constraints(const G& cg) { - p = out_edges(u, cg); - n = out_degree(u, cg); - e = *p.first; - u = source(e, cg); - v = target(e, cg); - } - std::pair p; - typename graph_traits::vertex_descriptor u, v; - typename graph_traits::edge_descriptor e; - typename graph_traits::degree_size_type n; - G g; - }; - - BOOST_concept(BidirectionalGraph,(G)) - : IncidenceGraph + BOOST_CONCEPT_ASSERT((MultiPassInputIterator< out_edge_iterator >)); + BOOST_CONCEPT_ASSERT((DefaultConstructible< edge_descriptor >)); + BOOST_CONCEPT_ASSERT((EqualityComparable< edge_descriptor >)); + BOOST_CONCEPT_ASSERT((Assignable< edge_descriptor >)); + BOOST_CONCEPT_ASSERT( + (Convertible< traversal_category, incidence_graph_tag >)); + + p = out_edges(u, g); + n = out_degree(u, g); + e = *p.first; + u = source(e, g); + v = target(e, g); + const_constraints(g); + } + void const_constraints(const G& cg) { - typedef typename graph_traits::in_edge_iterator - in_edge_iterator; - typedef typename graph_traits::traversal_category - traversal_category; + p = out_edges(u, cg); + n = out_degree(u, cg); + e = *p.first; + u = source(e, cg); + v = target(e, cg); + } + std::pair< out_edge_iterator, out_edge_iterator > p; + typename graph_traits< G >::vertex_descriptor u, v; + typename graph_traits< G >::edge_descriptor e; + typename graph_traits< G >::degree_size_type n; + G g; +}; + +BOOST_concept(BidirectionalGraph, (G)) : IncidenceGraph< G > +{ + typedef typename graph_traits< G >::in_edge_iterator in_edge_iterator; + typedef typename graph_traits< G >::traversal_category traversal_category; - BOOST_CONCEPT_USAGE(BidirectionalGraph) { - BOOST_CONCEPT_ASSERT((MultiPassInputIterator)); - BOOST_CONCEPT_ASSERT((Convertible)); + BOOST_CONCEPT_USAGE(BidirectionalGraph) + { + BOOST_CONCEPT_ASSERT((MultiPassInputIterator< in_edge_iterator >)); + BOOST_CONCEPT_ASSERT( + (Convertible< traversal_category, bidirectional_graph_tag >)); - BOOST_STATIC_ASSERT((boost::mpl::not_ >::value)); + BOOST_STATIC_ASSERT((boost::mpl::not_< + boost::is_same< in_edge_iterator, void > >::value)); p = in_edges(v, g); n = in_degree(v, g); n = degree(v, g); e = *p.first; const_constraints(g); - } - void const_constraints(const G& cg) { + } + void const_constraints(const G& cg) + { p = in_edges(v, cg); n = in_degree(v, cg); n = degree(v, cg); e = *p.first; - } - std::pair p; - typename graph_traits::vertex_descriptor v; - typename graph_traits::edge_descriptor e; - typename graph_traits::degree_size_type n; - G g; - }; - - BOOST_concept(AdjacencyGraph,(G)) - : Graph - { - typedef typename graph_traits::adjacency_iterator - adjacency_iterator; - typedef typename graph_traits::traversal_category - traversal_category; + } + std::pair< in_edge_iterator, in_edge_iterator > p; + typename graph_traits< G >::vertex_descriptor v; + typename graph_traits< G >::edge_descriptor e; + typename graph_traits< G >::degree_size_type n; + G g; +}; + +BOOST_concept(AdjacencyGraph, (G)) : Graph< G > +{ + typedef typename graph_traits< G >::adjacency_iterator adjacency_iterator; + typedef typename graph_traits< G >::traversal_category traversal_category; - BOOST_CONCEPT_USAGE(AdjacencyGraph) { - BOOST_CONCEPT_ASSERT((MultiPassInputIterator)); - BOOST_CONCEPT_ASSERT((Convertible)); + BOOST_CONCEPT_USAGE(AdjacencyGraph) + { + BOOST_CONCEPT_ASSERT((MultiPassInputIterator< adjacency_iterator >)); + BOOST_CONCEPT_ASSERT( + (Convertible< traversal_category, adjacency_graph_tag >)); - BOOST_STATIC_ASSERT((boost::mpl::not_ >::value)); + BOOST_STATIC_ASSERT((boost::mpl::not_< + boost::is_same< adjacency_iterator, void > >::value)); p = adjacent_vertices(v, g); v = *p.first; const_constraints(g); - } - void const_constraints(const G& cg) { - p = adjacent_vertices(v, cg); - } - std::pair p; - typename graph_traits::vertex_descriptor v; - G g; - }; - - BOOST_concept(VertexListGraph,(G)) - : Graph - { - typedef typename graph_traits::vertex_iterator vertex_iterator; - typedef typename graph_traits::vertices_size_type vertices_size_type; - typedef typename graph_traits::traversal_category - traversal_category; + } + void const_constraints(const G& cg) { p = adjacent_vertices(v, cg); } + std::pair< adjacency_iterator, adjacency_iterator > p; + typename graph_traits< G >::vertex_descriptor v; + G g; +}; + +BOOST_concept(VertexListGraph, (G)) : Graph< G > +{ + typedef typename graph_traits< G >::vertex_iterator vertex_iterator; + typedef typename graph_traits< G >::vertices_size_type vertices_size_type; + typedef typename graph_traits< G >::traversal_category traversal_category; - BOOST_CONCEPT_USAGE(VertexListGraph) { - BOOST_CONCEPT_ASSERT((MultiPassInputIterator)); - BOOST_CONCEPT_ASSERT((Convertible)); + BOOST_CONCEPT_USAGE(VertexListGraph) + { + BOOST_CONCEPT_ASSERT((MultiPassInputIterator< vertex_iterator >)); + BOOST_CONCEPT_ASSERT( + (Convertible< traversal_category, vertex_list_graph_tag >)); - BOOST_STATIC_ASSERT((boost::mpl::not_ >::value)); - BOOST_STATIC_ASSERT((boost::mpl::not_ >::value)); + BOOST_STATIC_ASSERT((boost::mpl::not_< + boost::is_same< vertex_iterator, void > >::value)); + BOOST_STATIC_ASSERT((boost::mpl::not_< + boost::is_same< vertices_size_type, void > >::value)); #ifdef BOOST_VECTOR_AS_GRAPH_GRAPH_ADL_HACK // dwa 2003/7/11 -- This clearly shouldn't be necessary, but if @@ -199,8 +201,9 @@ typename T::ThereReallyIsNoMemberByThisNameInT vertices(T const&); p = vertices(g); v = *p.first; const_constraints(g); - } - void const_constraints(const G& cg) { + } + void const_constraints(const G& cg) + { #ifdef BOOST_VECTOR_AS_GRAPH_GRAPH_ADL_HACK // dwa 2003/7/11 -- This clearly shouldn't be necessary, but if // you want to use vector_as_graph, it is! I'm sure the graph @@ -213,406 +216,395 @@ typename T::ThereReallyIsNoMemberByThisNameInT vertices(T const&); p = vertices(cg); v = *p.first; V = num_vertices(cg); - } - std::pair p; - typename graph_traits::vertex_descriptor v; - G g; - vertices_size_type V; - }; - - BOOST_concept(EdgeListGraph,(G)) - : Graph + } + std::pair< vertex_iterator, vertex_iterator > p; + typename graph_traits< G >::vertex_descriptor v; + G g; + vertices_size_type V; +}; + +BOOST_concept(EdgeListGraph, (G)) : Graph< G > +{ + typedef typename graph_traits< G >::edge_descriptor edge_descriptor; + typedef typename graph_traits< G >::edge_iterator edge_iterator; + typedef typename graph_traits< G >::edges_size_type edges_size_type; + typedef typename graph_traits< G >::traversal_category traversal_category; + + BOOST_CONCEPT_USAGE(EdgeListGraph) { - typedef typename graph_traits::edge_descriptor edge_descriptor; - typedef typename graph_traits::edge_iterator edge_iterator; - typedef typename graph_traits::edges_size_type edges_size_type; - typedef typename graph_traits::traversal_category - traversal_category; - - BOOST_CONCEPT_USAGE(EdgeListGraph) { - BOOST_CONCEPT_ASSERT((MultiPassInputIterator)); - BOOST_CONCEPT_ASSERT((DefaultConstructible)); - BOOST_CONCEPT_ASSERT((EqualityComparable)); - BOOST_CONCEPT_ASSERT((Assignable)); - BOOST_CONCEPT_ASSERT((Convertible)); - - BOOST_STATIC_ASSERT((boost::mpl::not_ >::value)); - BOOST_STATIC_ASSERT((boost::mpl::not_ >::value)); + BOOST_CONCEPT_ASSERT((MultiPassInputIterator< edge_iterator >)); + BOOST_CONCEPT_ASSERT((DefaultConstructible< edge_descriptor >)); + BOOST_CONCEPT_ASSERT((EqualityComparable< edge_descriptor >)); + BOOST_CONCEPT_ASSERT((Assignable< edge_descriptor >)); + BOOST_CONCEPT_ASSERT( + (Convertible< traversal_category, edge_list_graph_tag >)); + + BOOST_STATIC_ASSERT( + (boost::mpl::not_< boost::is_same< edge_iterator, void > >::value)); + BOOST_STATIC_ASSERT((boost::mpl::not_< + boost::is_same< edges_size_type, void > >::value)); p = edges(g); e = *p.first; u = source(e, g); v = target(e, g); const_constraints(g); - } - void const_constraints(const G& cg) { + } + void const_constraints(const G& cg) + { p = edges(cg); E = num_edges(cg); e = *p.first; u = source(e, cg); v = target(e, cg); - } - std::pair p; - typename graph_traits::vertex_descriptor u, v; - typename graph_traits::edge_descriptor e; - edges_size_type E; - G g; - }; - - BOOST_concept(VertexAndEdgeListGraph,(G)) - : VertexListGraph - , EdgeListGraph - { - }; + } + std::pair< edge_iterator, edge_iterator > p; + typename graph_traits< G >::vertex_descriptor u, v; + typename graph_traits< G >::edge_descriptor e; + edges_size_type E; + G g; +}; + +BOOST_concept(VertexAndEdgeListGraph, (G)) +: VertexListGraph< G >, EdgeListGraph< G > {}; + +// Where to put the requirement for this constructor? +// G g(n_vertices); +// Not in mutable graph, then LEDA graph's can't be models of +// MutableGraph. +BOOST_concept(EdgeMutableGraph, (G)) +{ + typedef typename graph_traits< G >::edge_descriptor edge_descriptor; - // Where to put the requirement for this constructor? - // G g(n_vertices); - // Not in mutable graph, then LEDA graph's can't be models of - // MutableGraph. - BOOST_concept(EdgeMutableGraph,(G)) + BOOST_CONCEPT_USAGE(EdgeMutableGraph) { - typedef typename graph_traits::edge_descriptor edge_descriptor; - - BOOST_CONCEPT_USAGE(EdgeMutableGraph) { p = add_edge(u, v, g); remove_edge(u, v, g); remove_edge(e, g); clear_vertex(v, g); - } - G g; - edge_descriptor e; - std::pair p; - typename graph_traits::vertex_descriptor u, v; - }; - - BOOST_concept(VertexMutableGraph,(G)) - { + } + G g; + edge_descriptor e; + std::pair< edge_descriptor, bool > p; + typename graph_traits< G >::vertex_descriptor u, v; +}; + +BOOST_concept(VertexMutableGraph, (G)) +{ - BOOST_CONCEPT_USAGE(VertexMutableGraph) { + BOOST_CONCEPT_USAGE(VertexMutableGraph) + { v = add_vertex(g); remove_vertex(v, g); - } - G g; - typename graph_traits::vertex_descriptor u, v; - }; - - BOOST_concept(MutableGraph,(G)) - : EdgeMutableGraph - , VertexMutableGraph - { - }; + } + G g; + typename graph_traits< G >::vertex_descriptor u, v; +}; - template - struct dummy_edge_predicate { - bool operator()(const edge_descriptor&) const { - return false; - } - }; +BOOST_concept(MutableGraph, (G)) +: EdgeMutableGraph< G >, VertexMutableGraph< G > {}; + +template < class edge_descriptor > struct dummy_edge_predicate +{ + bool operator()(const edge_descriptor&) const { return false; } +}; - BOOST_concept(MutableIncidenceGraph,(G)) - : MutableGraph +BOOST_concept(MutableIncidenceGraph, (G)) : MutableGraph< G > +{ + BOOST_CONCEPT_USAGE(MutableIncidenceGraph) { - BOOST_CONCEPT_USAGE(MutableIncidenceGraph) { remove_edge(iter, g); remove_out_edge_if(u, p, g); - } - G g; - typedef typename graph_traits::edge_descriptor edge_descriptor; - dummy_edge_predicate p; - typename boost::graph_traits::vertex_descriptor u; - typename boost::graph_traits::out_edge_iterator iter; - }; - - BOOST_concept(MutableBidirectionalGraph,(G)) - : MutableIncidenceGraph - { - BOOST_CONCEPT_USAGE(MutableBidirectionalGraph) - { - remove_in_edge_if(u, p, g); - } - G g; - typedef typename graph_traits::edge_descriptor edge_descriptor; - dummy_edge_predicate p; - typename boost::graph_traits::vertex_descriptor u; - }; - - BOOST_concept(MutableEdgeListGraph,(G)) - : EdgeMutableGraph - { - BOOST_CONCEPT_USAGE(MutableEdgeListGraph) { - remove_edge_if(p, g); - } - G g; - typedef typename graph_traits::edge_descriptor edge_descriptor; - dummy_edge_predicate p; - }; - - BOOST_concept(VertexMutablePropertyGraph,(G)) - : VertexMutableGraph - { - BOOST_CONCEPT_USAGE(VertexMutablePropertyGraph) { - v = add_vertex(vp, g); - } - G g; - typename graph_traits::vertex_descriptor v; - typename vertex_property_type::type vp; - }; - - BOOST_concept(EdgeMutablePropertyGraph,(G)) - : EdgeMutableGraph - { - typedef typename graph_traits::edge_descriptor edge_descriptor; - - BOOST_CONCEPT_USAGE(EdgeMutablePropertyGraph) { - p = add_edge(u, v, ep, g); - } - G g; - std::pair p; - typename graph_traits::vertex_descriptor u, v; - typename edge_property_type::type ep; - }; - - BOOST_concept(AdjacencyMatrix,(G)) - : Graph + } + G g; + typedef typename graph_traits< G >::edge_descriptor edge_descriptor; + dummy_edge_predicate< edge_descriptor > p; + typename boost::graph_traits< G >::vertex_descriptor u; + typename boost::graph_traits< G >::out_edge_iterator iter; +}; + +BOOST_concept(MutableBidirectionalGraph, (G)) : MutableIncidenceGraph< G > +{ + BOOST_CONCEPT_USAGE(MutableBidirectionalGraph) { - typedef typename graph_traits::edge_descriptor edge_descriptor; + remove_in_edge_if(u, p, g); + } + G g; + typedef typename graph_traits< G >::edge_descriptor edge_descriptor; + dummy_edge_predicate< edge_descriptor > p; + typename boost::graph_traits< G >::vertex_descriptor u; +}; + +BOOST_concept(MutableEdgeListGraph, (G)) : EdgeMutableGraph< G > +{ + BOOST_CONCEPT_USAGE(MutableEdgeListGraph) { remove_edge_if(p, g); } + G g; + typedef typename graph_traits< G >::edge_descriptor edge_descriptor; + dummy_edge_predicate< edge_descriptor > p; +}; + +BOOST_concept(VertexMutablePropertyGraph, (G)) : VertexMutableGraph< G > +{ + BOOST_CONCEPT_USAGE(VertexMutablePropertyGraph) { v = add_vertex(vp, g); } + G g; + typename graph_traits< G >::vertex_descriptor v; + typename vertex_property_type< G >::type vp; +}; + +BOOST_concept(EdgeMutablePropertyGraph, (G)) : EdgeMutableGraph< G > +{ + typedef typename graph_traits< G >::edge_descriptor edge_descriptor; - BOOST_CONCEPT_USAGE(AdjacencyMatrix) { + BOOST_CONCEPT_USAGE(EdgeMutablePropertyGraph) { p = add_edge(u, v, ep, g); } + G g; + std::pair< edge_descriptor, bool > p; + typename graph_traits< G >::vertex_descriptor u, v; + typename edge_property_type< G >::type ep; +}; + +BOOST_concept(AdjacencyMatrix, (G)) : Graph< G > +{ + typedef typename graph_traits< G >::edge_descriptor edge_descriptor; + + BOOST_CONCEPT_USAGE(AdjacencyMatrix) + { p = edge(u, v, g); const_constraints(g); - } - void const_constraints(const G& cg) { - p = edge(u, v, cg); - } - typename graph_traits::vertex_descriptor u, v; - std::pair p; - G g; - }; - - BOOST_concept(ReadablePropertyGraph,(G)(X)(Property)) - : Graph - { - typedef typename property_map::const_type const_Map; + } + void const_constraints(const G& cg) { p = edge(u, v, cg); } + typename graph_traits< G >::vertex_descriptor u, v; + std::pair< edge_descriptor, bool > p; + G g; +}; + +BOOST_concept(ReadablePropertyGraph, (G)(X)(Property)) : Graph< G > +{ + typedef typename property_map< G, Property >::const_type const_Map; - BOOST_CONCEPT_USAGE(ReadablePropertyGraph) - { - BOOST_CONCEPT_ASSERT((ReadablePropertyMapConcept)); + BOOST_CONCEPT_USAGE(ReadablePropertyGraph) + { + BOOST_CONCEPT_ASSERT((ReadablePropertyMapConcept< const_Map, X >)); const_constraints(g); - } - void const_constraints(const G& cg) { + } + void const_constraints(const G& cg) + { const_Map pmap = get(Property(), cg); pval = get(Property(), cg, x); ignore_unused_variable_warning(pmap); - } - G g; - X x; - typename property_traits::value_type pval; - }; - - BOOST_concept(PropertyGraph,(G)(X)(Property)) - : ReadablePropertyGraph + } + G g; + X x; + typename property_traits< const_Map >::value_type pval; +}; + +BOOST_concept(PropertyGraph, (G)(X)(Property)) +: ReadablePropertyGraph< G, X, Property > +{ + typedef typename property_map< G, Property >::type Map; + BOOST_CONCEPT_USAGE(PropertyGraph) { - typedef typename property_map::type Map; - BOOST_CONCEPT_USAGE(PropertyGraph) { - BOOST_CONCEPT_ASSERT((ReadWritePropertyMapConcept)); + BOOST_CONCEPT_ASSERT((ReadWritePropertyMapConcept< Map, X >)); Map pmap = get(Property(), g); pval = get(Property(), g, x); put(Property(), g, x, pval); ignore_unused_variable_warning(pmap); - } - G g; - X x; - typename property_traits::value_type pval; - }; - - BOOST_concept(LvaluePropertyGraph,(G)(X)(Property)) - : ReadablePropertyGraph - { - typedef typename property_map::type Map; - typedef typename property_map::const_type const_Map; + } + G g; + X x; + typename property_traits< Map >::value_type pval; +}; + +BOOST_concept(LvaluePropertyGraph, (G)(X)(Property)) +: ReadablePropertyGraph< G, X, Property > +{ + typedef typename property_map< G, Property >::type Map; + typedef typename property_map< G, Property >::const_type const_Map; - BOOST_CONCEPT_USAGE(LvaluePropertyGraph) { - BOOST_CONCEPT_ASSERT((LvaluePropertyMapConcept)); + BOOST_CONCEPT_USAGE(LvaluePropertyGraph) + { + BOOST_CONCEPT_ASSERT((LvaluePropertyMapConcept< const_Map, X >)); pval = get(Property(), g, x); put(Property(), g, x, pval); - } - G g; - X x; - typename property_traits::value_type pval; - }; - - // The *IndexGraph concepts are "semantic" graph concpepts. These can be - // applied to describe any graph that has an index map that can be accessed - // using the get(*_index, g) method. For example, adjacency lists with - // VertexSet == vecS are implicitly models of this concept. - // - // NOTE: We could require an associated type vertex_index_type, but that - // would mean propagating that type name into graph_traits and all of the - // other graph implementations. Much easier to simply call it unsigned. - - BOOST_concept(VertexIndexGraph,(Graph)) + } + G g; + X x; + typename property_traits< Map >::value_type pval; +}; + +// The *IndexGraph concepts are "semantic" graph concpepts. These can be +// applied to describe any graph that has an index map that can be accessed +// using the get(*_index, g) method. For example, adjacency lists with +// VertexSet == vecS are implicitly models of this concept. +// +// NOTE: We could require an associated type vertex_index_type, but that +// would mean propagating that type name into graph_traits and all of the +// other graph implementations. Much easier to simply call it unsigned. + +BOOST_concept(VertexIndexGraph, (Graph)) +{ + BOOST_CONCEPT_USAGE(VertexIndexGraph) + { + typedef typename graph_traits< Graph >::vertex_descriptor Vertex; + typedef typename property_map< Graph, vertex_index_t >::type Map; + typedef unsigned Index; // This could be Graph::vertex_index_type + Map m = get(vertex_index, g); + Index x = get(vertex_index, g, Vertex()); + ignore_unused_variable_warning(m); + ignore_unused_variable_warning(x); + + // This is relaxed + renumber_vertex_indices(g); + + const_constraints(g); + } + void const_constraints(const Graph& g_) { - BOOST_CONCEPT_USAGE(VertexIndexGraph) - { - typedef typename graph_traits::vertex_descriptor Vertex; - typedef typename property_map::type Map; - typedef unsigned Index; // This could be Graph::vertex_index_type - Map m = get(vertex_index, g); - Index x = get(vertex_index, g, Vertex()); - ignore_unused_variable_warning(m); - ignore_unused_variable_warning(x); - - // This is relaxed - renumber_vertex_indices(g); - - const_constraints(g); - } - void const_constraints(const Graph& g_) - { - typedef typename property_map::const_type Map; - Map m = get(vertex_index, g_); - ignore_unused_variable_warning(m); - } - private: - Graph g; - }; - - BOOST_concept(EdgeIndexGraph,(Graph)) + typedef typename property_map< Graph, vertex_index_t >::const_type Map; + Map m = get(vertex_index, g_); + ignore_unused_variable_warning(m); + } + +private: + Graph g; +}; + +BOOST_concept(EdgeIndexGraph, (Graph)) +{ + BOOST_CONCEPT_USAGE(EdgeIndexGraph) { - BOOST_CONCEPT_USAGE(EdgeIndexGraph) - { - typedef typename graph_traits::edge_descriptor Edge; - typedef typename property_map::type Map; - typedef unsigned Index; // This could be Graph::vertex_index_type - Map m = get(edge_index, g); - Index x = get(edge_index, g, Edge()); - ignore_unused_variable_warning(m); - ignore_unused_variable_warning(x); - - // This is relaxed - renumber_edge_indices(g); - - const_constraints(g); - } - void const_constraints(const Graph& g_) - { - typedef typename property_map::const_type Map; - Map m = get(edge_index, g_); - ignore_unused_variable_warning(m); - } - private: - Graph g; - }; - - BOOST_concept(ColorValue,(C)) - : EqualityComparable - , DefaultConstructible + typedef typename graph_traits< Graph >::edge_descriptor Edge; + typedef typename property_map< Graph, edge_index_t >::type Map; + typedef unsigned Index; // This could be Graph::vertex_index_type + Map m = get(edge_index, g); + Index x = get(edge_index, g, Edge()); + ignore_unused_variable_warning(m); + ignore_unused_variable_warning(x); + + // This is relaxed + renumber_edge_indices(g); + + const_constraints(g); + } + void const_constraints(const Graph& g_) + { + typedef typename property_map< Graph, edge_index_t >::const_type Map; + Map m = get(edge_index, g_); + ignore_unused_variable_warning(m); + } + +private: + Graph g; +}; + +BOOST_concept(ColorValue, (C)) +: EqualityComparable< C >, DefaultConstructible< C > +{ + BOOST_CONCEPT_USAGE(ColorValue) { - BOOST_CONCEPT_USAGE(ColorValue) { - c = color_traits::white(); - c = color_traits::gray(); - c = color_traits::black(); - } - C c; - }; - - BOOST_concept(BasicMatrix,(M)(I)(V)) + c = color_traits< C >::white(); + c = color_traits< C >::gray(); + c = color_traits< C >::black(); + } + C c; +}; + +BOOST_concept(BasicMatrix, (M)(I)(V)) +{ + BOOST_CONCEPT_USAGE(BasicMatrix) { - BOOST_CONCEPT_USAGE(BasicMatrix) { V& elt = A[i][j]; const_constraints(A); ignore_unused_variable_warning(elt); - } - void const_constraints(const M& cA) { + } + void const_constraints(const M& cA) + { const V& elt = cA[i][j]; ignore_unused_variable_warning(elt); - } - M A; - I i, j; - }; + } + M A; + I i, j; +}; + +// The following concepts describe aspects of numberic values and measure +// functions. We're extending the notion of numeric values to include +// emulation for zero and infinity. + +BOOST_concept(NumericValue, (Numeric)) { BOOST_CONCEPT_USAGE(NumericValue) { + BOOST_CONCEPT_ASSERT((DefaultConstructible< Numeric >)); +BOOST_CONCEPT_ASSERT((CopyConstructible< Numeric >)); +numeric_values< Numeric >::zero(); +numeric_values< Numeric >::infinity(); +} +} +; + +BOOST_concept(DegreeMeasure, (Measure)(Graph)) +{ + BOOST_CONCEPT_USAGE(DegreeMeasure) + { + typedef typename Measure::degree_type Degree; + typedef typename Measure::vertex_type Vertex; - // The following concepts describe aspects of numberic values and measure - // functions. We're extending the notion of numeric values to include - // emulation for zero and infinity. + Degree d = m(Vertex(), g); + ignore_unused_variable_warning(d); + } - BOOST_concept(NumericValue,(Numeric)) - { - BOOST_CONCEPT_USAGE(NumericValue) - { - BOOST_CONCEPT_ASSERT(( DefaultConstructible )); - BOOST_CONCEPT_ASSERT(( CopyConstructible )); - numeric_values::zero(); - numeric_values::infinity(); - } - }; - - BOOST_concept(DegreeMeasure,(Measure)(Graph)) - { - BOOST_CONCEPT_USAGE(DegreeMeasure) - { - typedef typename Measure::degree_type Degree; - typedef typename Measure::vertex_type Vertex; - - Degree d = m(Vertex(), g); - ignore_unused_variable_warning(d); - } - private: - Measure m; - Graph g; - }; - - BOOST_concept(DistanceMeasure,(Measure)(Graph)) +private: + Measure m; + Graph g; +}; + +BOOST_concept(DistanceMeasure, (Measure)(Graph)) +{ + BOOST_CONCEPT_USAGE(DistanceMeasure) { - BOOST_CONCEPT_USAGE(DistanceMeasure) - { - typedef typename Measure::distance_type Distance; - typedef typename Measure::result_type Result; - Result r = m(Distance(), g); - ignore_unused_variable_warning(r); - } - private: - Measure m; - Graph g; - }; + typedef typename Measure::distance_type Distance; + typedef typename Measure::result_type Result; + Result r = m(Distance(), g); + ignore_unused_variable_warning(r); + } + +private: + Measure m; + Graph g; +}; } /* namespace concepts */ using boost::concepts::MultiPassInputIteratorConcept; // Graph concepts -using boost::concepts::GraphConcept; -using boost::concepts::IncidenceGraphConcept; -using boost::concepts::BidirectionalGraphConcept; using boost::concepts::AdjacencyGraphConcept; -using boost::concepts::VertexListGraphConcept; +using boost::concepts::AdjacencyMatrixConcept; +using boost::concepts::BidirectionalGraphConcept; +using boost::concepts::EdgeIndexGraphConcept; using boost::concepts::EdgeListGraphConcept; -using boost::concepts::VertexAndEdgeListGraphConcept; using boost::concepts::EdgeMutableGraphConcept; -using boost::concepts::VertexMutableGraphConcept; -using boost::concepts::MutableGraphConcept; -using boost::concepts::MutableIncidenceGraphConcept; +using boost::concepts::EdgeMutablePropertyGraphConcept; +using boost::concepts::GraphConcept; +using boost::concepts::IncidenceGraphConcept; +using boost::concepts::LvaluePropertyGraphConcept; using boost::concepts::MutableBidirectionalGraphConcept; using boost::concepts::MutableEdgeListGraphConcept; -using boost::concepts::VertexMutablePropertyGraphConcept; -using boost::concepts::EdgeMutablePropertyGraphConcept; -using boost::concepts::AdjacencyMatrixConcept; -using boost::concepts::ReadablePropertyGraphConcept; +using boost::concepts::MutableGraphConcept; +using boost::concepts::MutableIncidenceGraphConcept; using boost::concepts::PropertyGraphConcept; -using boost::concepts::LvaluePropertyGraphConcept; +using boost::concepts::ReadablePropertyGraphConcept; +using boost::concepts::VertexAndEdgeListGraphConcept; using boost::concepts::VertexIndexGraphConcept; -using boost::concepts::EdgeIndexGraphConcept; +using boost::concepts::VertexListGraphConcept; +using boost::concepts::VertexMutableGraphConcept; +using boost::concepts::VertexMutablePropertyGraphConcept; // Utility concepts -using boost::concepts::ColorValueConcept; using boost::concepts::BasicMatrixConcept; -using boost::concepts::NumericValueConcept; -using boost::concepts::DistanceMeasureConcept; +using boost::concepts::ColorValueConcept; using boost::concepts::DegreeMeasureConcept; - +using boost::concepts::DistanceMeasureConcept; +using boost::concepts::NumericValueConcept; } /* namespace boost */ #include diff --git a/include/boost/graph/graph_mutability_traits.hpp b/include/boost/graph/graph_mutability_traits.hpp index 726d8d141..333a026d2 100644 --- a/include/boost/graph/graph_mutability_traits.hpp +++ b/include/boost/graph/graph_mutability_traits.hpp @@ -13,7 +13,8 @@ #include #include -namespace boost { +namespace boost +{ // The mutabiltiy categories classify graphs by their mutating operations // on the edge and vertex sets. This is a substantially more refined @@ -23,176 +24,163 @@ namespace boost { // constructive or destructive algorithms (i.e., graph generators) that // may use these to describe requirements on graph inputs. -struct add_vertex_tag { }; -struct add_vertex_property_tag : virtual add_vertex_tag { }; -struct add_edge_tag { }; -struct add_edge_property_tag : virtual add_edge_tag { }; -struct remove_vertex_tag { }; -struct remove_edge_tag { }; - -struct mutable_vertex_graph_tag - : virtual add_vertex_tag, virtual remove_vertex_tag -{ }; -struct mutable_vertex_property_graph_tag - : virtual add_vertex_property_tag, virtual remove_vertex_tag -{ }; - -struct mutable_edge_graph_tag - : virtual add_edge_tag, virtual remove_edge_tag -{ }; -struct mutable_edge_property_graph_tag - : virtual add_edge_property_tag, virtual remove_edge_tag -{ }; - -struct mutable_graph_tag - : virtual mutable_vertex_graph_tag - , virtual mutable_edge_graph_tag -{ }; -struct mutable_property_graph_tag - : virtual mutable_vertex_property_graph_tag - , virtual mutable_edge_property_graph_tag -{ }; +struct add_vertex_tag +{ +}; +struct add_vertex_property_tag : virtual add_vertex_tag +{ +}; +struct add_edge_tag +{ +}; +struct add_edge_property_tag : virtual add_edge_tag +{ +}; +struct remove_vertex_tag +{ +}; +struct remove_edge_tag +{ +}; + +struct mutable_vertex_graph_tag : virtual add_vertex_tag, + virtual remove_vertex_tag +{ +}; +struct mutable_vertex_property_graph_tag : virtual add_vertex_property_tag, + virtual remove_vertex_tag +{ +}; + +struct mutable_edge_graph_tag : virtual add_edge_tag, virtual remove_edge_tag +{ +}; +struct mutable_edge_property_graph_tag : virtual add_edge_property_tag, + virtual remove_edge_tag +{ +}; + +struct mutable_graph_tag : virtual mutable_vertex_graph_tag, + virtual mutable_edge_graph_tag +{ +}; +struct mutable_property_graph_tag : virtual mutable_vertex_property_graph_tag, + virtual mutable_edge_property_graph_tag +{ +}; // Some graphs just don't like to be torn down. Note this only restricts // teardown to the set of vertices, not the vertex set. // TODO: Find a better name for this tag. -struct add_only_property_graph_tag - : virtual add_vertex_property_tag - , virtual mutable_edge_property_graph_tag -{ }; +struct add_only_property_graph_tag : virtual add_vertex_property_tag, + virtual mutable_edge_property_graph_tag +{ +}; /** * The graph_mutability_traits provide methods for determining the * interfaces supported by graph classes for adding and removing vertices * and edges. */ -template -struct graph_mutability_traits { +template < typename Graph > struct graph_mutability_traits +{ typedef typename Graph::mutability_category category; }; -template +template < typename Graph > struct graph_has_add_vertex - : mpl::bool_< - is_convertible< - typename graph_mutability_traits::category, - add_vertex_tag - >::value - > -{ }; - -template -struct graph_has_add_vertex_with_property - : mpl::bool_< - is_convertible< - typename graph_mutability_traits::category, - add_vertex_property_tag - >::value - > -{ }; +: mpl::bool_< + is_convertible< typename graph_mutability_traits< Graph >::category, + add_vertex_tag >::value > +{ +}; +template < typename Graph > +struct graph_has_add_vertex_with_property +: mpl::bool_< + is_convertible< typename graph_mutability_traits< Graph >::category, + add_vertex_property_tag >::value > +{ +}; -template +template < typename Graph > struct graph_has_remove_vertex - : mpl::bool_< - is_convertible< - typename graph_mutability_traits::category, - remove_vertex_tag - >::value - > -{ }; - -template +: mpl::bool_< + is_convertible< typename graph_mutability_traits< Graph >::category, + remove_vertex_tag >::value > +{ +}; + +template < typename Graph > struct graph_has_add_edge - : mpl::bool_< - is_convertible< - typename graph_mutability_traits::category, - add_edge_tag - >::value - > -{ }; - -template -struct graph_has_add_edge_with_property - : mpl::bool_< - is_convertible< - typename graph_mutability_traits::category, - add_edge_property_tag - >::value - > -{ }; +: mpl::bool_< + is_convertible< typename graph_mutability_traits< Graph >::category, + add_edge_tag >::value > +{ +}; +template < typename Graph > +struct graph_has_add_edge_with_property +: mpl::bool_< + is_convertible< typename graph_mutability_traits< Graph >::category, + add_edge_property_tag >::value > +{ +}; -template +template < typename Graph > struct graph_has_remove_edge - : mpl::bool_< - is_convertible< - typename graph_mutability_traits::category, - remove_edge_tag - >::value - > -{ }; - +: mpl::bool_< + is_convertible< typename graph_mutability_traits< Graph >::category, + remove_edge_tag >::value > +{ +}; -template +template < typename Graph > struct is_mutable_vertex_graph - : mpl::and_< - graph_has_add_vertex, - graph_has_remove_vertex - > -{ }; +: mpl::and_< graph_has_add_vertex< Graph >, graph_has_remove_vertex< Graph > > +{ +}; -template +template < typename Graph > struct is_mutable_vertex_property_graph - : mpl::and_< - graph_has_add_vertex_with_property, - graph_has_remove_vertex - > -{ }; - +: mpl::and_< graph_has_add_vertex_with_property< Graph >, + graph_has_remove_vertex< Graph > > +{ +}; -template +template < typename Graph > struct is_mutable_edge_graph - : mpl::and_< - graph_has_add_edge, - graph_has_remove_edge - > -{ }; +: mpl::and_< graph_has_add_edge< Graph >, graph_has_remove_edge< Graph > > +{ +}; -template +template < typename Graph > struct is_mutable_edge_property_graph - : mpl::and_< - graph_has_add_edge_with_property, - graph_has_remove_edge - > -{ }; - +: mpl::and_< graph_has_add_edge_with_property< Graph >, + graph_has_remove_edge< Graph > > +{ +}; -template +template < typename Graph > struct is_mutable_graph - : mpl::and_< - is_mutable_vertex_graph, - is_mutable_edge_graph - > -{ }; +: mpl::and_< is_mutable_vertex_graph< Graph >, is_mutable_edge_graph< Graph > > +{ +}; -template +template < typename Graph > struct is_mutable_property_graph - : mpl::and_< - is_mutable_vertex_property_graph, - is_mutable_edge_property_graph - > -{ }; +: mpl::and_< is_mutable_vertex_property_graph< Graph >, + is_mutable_edge_property_graph< Graph > > +{ +}; -template +template < typename Graph > struct is_add_only_property_graph - : mpl::bool_< - is_convertible< - typename graph_mutability_traits::category, - add_only_property_graph_tag - >::value - > -{ }; +: mpl::bool_< + is_convertible< typename graph_mutability_traits< Graph >::category, + add_only_property_graph_tag >::value > +{ +}; /** @name Mutability Traits Specializations */ //@{ diff --git a/include/boost/graph/graph_selectors.hpp b/include/boost/graph/graph_selectors.hpp index 777ebefc9..e37210d09 100644 --- a/include/boost/graph/graph_selectors.hpp +++ b/include/boost/graph/graph_selectors.hpp @@ -12,26 +12,43 @@ #include -namespace boost { +namespace boost +{ - //=========================================================================== - // Selectors for the Directed template parameter of adjacency_list - // and adjacency_matrix. +//=========================================================================== +// Selectors for the Directed template parameter of adjacency_list +// and adjacency_matrix. - struct directedS { enum { is_directed = true, is_bidir = false }; - typedef mpl::true_ is_directed_t; +struct directedS +{ + enum + { + is_directed = true, + is_bidir = false + }; + typedef mpl::true_ is_directed_t; typedef mpl::false_ is_bidir_t; - }; - struct undirectedS { - enum { is_directed = false, is_bidir = false }; +}; +struct undirectedS +{ + enum + { + is_directed = false, + is_bidir = false + }; typedef mpl::false_ is_directed_t; typedef mpl::false_ is_bidir_t; - }; - struct bidirectionalS { - enum { is_directed = true, is_bidir = true }; +}; +struct bidirectionalS +{ + enum + { + is_directed = true, + is_bidir = true + }; typedef mpl::true_ is_directed_t; typedef mpl::true_ is_bidir_t; - }; +}; } // namespace boost diff --git a/include/boost/graph/graph_stats.hpp b/include/boost/graph/graph_stats.hpp index ad0e330ca..00c84dd86 100644 --- a/include/boost/graph/graph_stats.hpp +++ b/include/boost/graph/graph_stats.hpp @@ -14,124 +14,133 @@ #include #include -namespace boost { namespace graph { - -template -struct sort_edge_by_origin { -public: - typedef typename graph_traits::edge_descriptor edge_type; - - explicit sort_edge_by_origin( Graph& g ) : g(g) {} - - inline bool operator()( edge_type a, edge_type b ) { - return source( a, g ) == source( b, g ) ? target( a, g ) < target( b, g ) : - source( a, g ) < source( b, g ); - } - -private: - Graph& g; -}; - -template -struct equal_edge { -public: - typedef typename graph_traits::edge_descriptor edge_type; - - explicit equal_edge( Graph& g ) : g(g) {} - - inline bool operator()( edge_type a, edge_type b ) { - return source( a, g ) == source( b, g ) && - target( a, g ) == target( b, g ); - } - -private: - Graph& g; -}; - -template -unsigned long num_dup_edges( Graph& g ) { - typedef typename graph_traits::edge_iterator e_iterator_type; - typedef typename graph_traits::edge_descriptor edge_type; - - std::list all_edges; - - BGL_FORALL_EDGES_T( e, g, Graph ) { - all_edges.push_back( e ); - } - - sort_edge_by_origin cmp1( g ); - all_edges.sort( cmp1 ); - equal_edge cmp2( g ); - all_edges.unique( cmp2 ); - - return num_edges( g ) - all_edges.size(); -} +namespace boost +{ +namespace graph +{ + + template < typename Graph > struct sort_edge_by_origin + { + public: + typedef typename graph_traits< Graph >::edge_descriptor edge_type; + + explicit sort_edge_by_origin(Graph& g) : g(g) {} + + inline bool operator()(edge_type a, edge_type b) + { + return source(a, g) == source(b, g) ? target(a, g) < target(b, g) + : source(a, g) < source(b, g); + } + + private: + Graph& g; + }; + + template < typename Graph > struct equal_edge + { + public: + typedef typename graph_traits< Graph >::edge_descriptor edge_type; + + explicit equal_edge(Graph& g) : g(g) {} + + inline bool operator()(edge_type a, edge_type b) + { + return source(a, g) == source(b, g) && target(a, g) == target(b, g); + } + + private: + Graph& g; + }; + + template < typename Graph > unsigned long num_dup_edges(Graph& g) + { + typedef typename graph_traits< Graph >::edge_iterator e_iterator_type; + typedef typename graph_traits< Graph >::edge_descriptor edge_type; + + std::list< edge_type > all_edges; + BGL_FORALL_EDGES_T(e, g, Graph) { all_edges.push_back(e); } -template -std::map dup_edge_dist( Graph& g ) { - std::map dist; - typedef typename graph_traits::adjacency_iterator a_iterator_type; - typedef typename graph_traits::vertex_descriptor vertex_type; + sort_edge_by_origin< Graph > cmp1(g); + all_edges.sort(cmp1); + equal_edge< Graph > cmp2(g); + all_edges.unique(cmp2); - - BGL_FORALL_VERTICES_T( v, g, Graph ) { - std::list front_neighbors; - a_iterator_type a_iter, a_end; - for( boost::tie( a_iter, a_end ) = adjacent_vertices( v, g ); - a_iter != a_end; ++a_iter ) { - front_neighbors.push_back( *a_iter ); + return num_edges(g) - all_edges.size(); } - - front_neighbors.sort(); - front_neighbors.unique(); - dist[out_degree( v, g ) - front_neighbors.size()] += 1; - } - return dist; -} -template -std::map degree_dist( Graph& g ) { - std::map dist; - typedef typename graph_traits::adjacency_iterator a_iterator_type; - typedef typename graph_traits::vertex_descriptor vertex_type; - - BGL_FORALL_VERTICES_T( v, g, Graph ) { - dist[out_degree( v, g )] += 1; - } - - return dist; -} + template < typename Graph > + std::map< unsigned long, unsigned long > dup_edge_dist(Graph& g) + { + std::map< unsigned long, unsigned long > dist; + typedef + typename graph_traits< Graph >::adjacency_iterator a_iterator_type; + typedef typename graph_traits< Graph >::vertex_descriptor vertex_type; + + BGL_FORALL_VERTICES_T(v, g, Graph) + { + std::list< vertex_type > front_neighbors; + a_iterator_type a_iter, a_end; + for (boost::tie(a_iter, a_end) = adjacent_vertices(v, g); + a_iter != a_end; ++a_iter) + { + front_neighbors.push_back(*a_iter); + } + + front_neighbors.sort(); + front_neighbors.unique(); + dist[out_degree(v, g) - front_neighbors.size()] += 1; + } + return dist; + } -template -std::map weight_degree_dist( Graph& g ) { - std::map dist, n; - typedef typename graph_traits::adjacency_iterator a_iterator_type; - typedef typename graph_traits::vertex_descriptor vertex_type; - typedef typename property_map::const_type edge_map_type; - typedef typename property_traits::value_type - edge_weight_type; - - typename property_map::type em = get( edge_weight, g ); - - BGL_FORALL_VERTICES_T( v, g, Graph ) { - edge_weight_type tmp = 0; - BGL_FORALL_OUTEDGES_T( v, e, g, Graph ) { - tmp += em[e]; - } - n[out_degree( v, g )] += 1.; - dist[out_degree( v, g )] += tmp; - } - - for( std::map::iterator iter = dist.begin(); - iter != dist.end(); ++iter ) { - BOOST_ASSERT( n[iter->first] != 0 ); - dist[iter->first] /= n[iter->first]; - } - - return dist; -} + template < typename Graph > + std::map< unsigned long, unsigned long > degree_dist(Graph& g) + { + std::map< unsigned long, unsigned long > dist; + typedef + typename graph_traits< Graph >::adjacency_iterator a_iterator_type; + typedef typename graph_traits< Graph >::vertex_descriptor vertex_type; + + BGL_FORALL_VERTICES_T(v, g, Graph) { dist[out_degree(v, g)] += 1; } -}} + return dist; + } + + template < typename Graph > + std::map< unsigned long, double > weight_degree_dist(Graph& g) + { + std::map< unsigned long, double > dist, n; + typedef + typename graph_traits< Graph >::adjacency_iterator a_iterator_type; + typedef typename graph_traits< Graph >::vertex_descriptor vertex_type; + typedef typename property_map< Graph, edge_weight_t >::const_type + edge_map_type; + typedef typename property_traits< edge_map_type >::value_type + edge_weight_type; + + typename property_map< Graph, edge_weight_t >::type em + = get(edge_weight, g); + + BGL_FORALL_VERTICES_T(v, g, Graph) + { + edge_weight_type tmp = 0; + BGL_FORALL_OUTEDGES_T(v, e, g, Graph) { tmp += em[e]; } + n[out_degree(v, g)] += 1.; + dist[out_degree(v, g)] += tmp; + } + + for (std::map< unsigned long, double >::iterator iter = dist.begin(); + iter != dist.end(); ++iter) + { + BOOST_ASSERT(n[iter->first] != 0); + dist[iter->first] /= n[iter->first]; + } + + return dist; + } + +} +} #endif diff --git a/include/boost/graph/graph_traits.hpp b/include/boost/graph/graph_traits.hpp index a1c27483a..6b874059e 100644 --- a/include/boost/graph/graph_traits.hpp +++ b/include/boost/graph/graph_traits.hpp @@ -27,351 +27,398 @@ #include #include -namespace boost { - - namespace detail { -#define BOOST_GRAPH_MEMBER_OR_VOID(name) \ - BOOST_MPL_HAS_XXX_TRAIT_DEF(name) \ - template struct BOOST_JOIN(get_member_, name) {typedef typename T::name type;}; \ - template struct BOOST_JOIN(get_opt_member_, name): \ - boost::mpl::eval_if_c< \ - BOOST_JOIN(has_, name)::value, \ - BOOST_JOIN(get_member_, name), \ - boost::mpl::identity > \ - {}; - BOOST_GRAPH_MEMBER_OR_VOID(adjacency_iterator) - BOOST_GRAPH_MEMBER_OR_VOID(out_edge_iterator) - BOOST_GRAPH_MEMBER_OR_VOID(in_edge_iterator) - BOOST_GRAPH_MEMBER_OR_VOID(vertex_iterator) - BOOST_GRAPH_MEMBER_OR_VOID(edge_iterator) - BOOST_GRAPH_MEMBER_OR_VOID(vertices_size_type) - BOOST_GRAPH_MEMBER_OR_VOID(edges_size_type) - BOOST_GRAPH_MEMBER_OR_VOID(degree_size_type) - } +namespace boost +{ + +namespace detail +{ +#define BOOST_GRAPH_MEMBER_OR_VOID(name) \ + BOOST_MPL_HAS_XXX_TRAIT_DEF(name) \ + template < typename T > struct BOOST_JOIN(get_member_, name) \ + { \ + typedef typename T::name type; \ + }; \ + template < typename T > \ + struct BOOST_JOIN(get_opt_member_, name) \ + : boost::mpl::eval_if_c< BOOST_JOIN(has_, name) < T >::value, BOOST_JOIN(get_member_, name)< T >, boost::mpl::identity< void >> \ + { \ + }; + BOOST_GRAPH_MEMBER_OR_VOID(adjacency_iterator) + BOOST_GRAPH_MEMBER_OR_VOID(out_edge_iterator) + BOOST_GRAPH_MEMBER_OR_VOID(in_edge_iterator) + BOOST_GRAPH_MEMBER_OR_VOID(vertex_iterator) + BOOST_GRAPH_MEMBER_OR_VOID(edge_iterator) + BOOST_GRAPH_MEMBER_OR_VOID(vertices_size_type) + BOOST_GRAPH_MEMBER_OR_VOID(edges_size_type) + BOOST_GRAPH_MEMBER_OR_VOID(degree_size_type) +} - template - struct graph_traits { +template < typename G > struct graph_traits +{ #define BOOST_GRAPH_PULL_OPT_MEMBER(name) \ - typedef typename detail::BOOST_JOIN(get_opt_member_, name)::type name; - - typedef typename G::vertex_descriptor vertex_descriptor; - typedef typename G::edge_descriptor edge_descriptor; - BOOST_GRAPH_PULL_OPT_MEMBER(adjacency_iterator) - BOOST_GRAPH_PULL_OPT_MEMBER(out_edge_iterator) - BOOST_GRAPH_PULL_OPT_MEMBER(in_edge_iterator) - BOOST_GRAPH_PULL_OPT_MEMBER(vertex_iterator) - BOOST_GRAPH_PULL_OPT_MEMBER(edge_iterator) - - typedef typename G::directed_category directed_category; - typedef typename G::edge_parallel_category edge_parallel_category; - typedef typename G::traversal_category traversal_category; - - BOOST_GRAPH_PULL_OPT_MEMBER(vertices_size_type) - BOOST_GRAPH_PULL_OPT_MEMBER(edges_size_type) - BOOST_GRAPH_PULL_OPT_MEMBER(degree_size_type) + typedef typename detail::BOOST_JOIN(get_opt_member_, name)< G >::type name; + + typedef typename G::vertex_descriptor vertex_descriptor; + typedef typename G::edge_descriptor edge_descriptor; + BOOST_GRAPH_PULL_OPT_MEMBER(adjacency_iterator) + BOOST_GRAPH_PULL_OPT_MEMBER(out_edge_iterator) + BOOST_GRAPH_PULL_OPT_MEMBER(in_edge_iterator) + BOOST_GRAPH_PULL_OPT_MEMBER(vertex_iterator) + BOOST_GRAPH_PULL_OPT_MEMBER(edge_iterator) + + typedef typename G::directed_category directed_category; + typedef typename G::edge_parallel_category edge_parallel_category; + typedef typename G::traversal_category traversal_category; + + BOOST_GRAPH_PULL_OPT_MEMBER(vertices_size_type) + BOOST_GRAPH_PULL_OPT_MEMBER(edges_size_type) + BOOST_GRAPH_PULL_OPT_MEMBER(degree_size_type) #undef BOOST_GRAPH_PULL_OPT_MEMBER - static inline vertex_descriptor null_vertex(); - }; + static inline vertex_descriptor null_vertex(); +}; - template - inline typename graph_traits::vertex_descriptor - graph_traits::null_vertex() - { return G::null_vertex(); } - - // directed_category tags - struct directed_tag { }; - struct undirected_tag { }; - struct bidirectional_tag : public directed_tag { }; - - namespace detail { - inline bool is_directed(directed_tag) { return true; } - inline bool is_directed(undirected_tag) { return false; } - } +template < typename G > +inline typename graph_traits< G >::vertex_descriptor +graph_traits< G >::null_vertex() +{ + return G::null_vertex(); +} - /** Return true if the given graph is directed. */ - template - bool is_directed(const Graph&) { - typedef typename graph_traits::directed_category Cat; - return detail::is_directed(Cat()); - } +// directed_category tags +struct directed_tag +{ +}; +struct undirected_tag +{ +}; +struct bidirectional_tag : public directed_tag +{ +}; + +namespace detail +{ + inline bool is_directed(directed_tag) { return true; } + inline bool is_directed(undirected_tag) { return false; } +} - /** Return true if the given graph is undirected. */ - template - bool is_undirected(const Graph& g) { - return !is_directed(g); - } +/** Return true if the given graph is directed. */ +template < typename Graph > bool is_directed(const Graph&) +{ + typedef typename graph_traits< Graph >::directed_category Cat; + return detail::is_directed(Cat()); +} - /** @name Directed/Undirected Graph Traits */ - //@{ - namespace graph_detail { - template - struct is_directed_tag - : mpl::bool_::value> - { }; - } // namespace graph_detail - - template - struct is_directed_graph - : graph_detail::is_directed_tag< - typename graph_traits::directed_category - > - { }; - - template - struct is_undirected_graph - : mpl::not_< is_directed_graph > - { }; - //@} - - // edge_parallel_category tags - struct allow_parallel_edge_tag { }; - struct disallow_parallel_edge_tag { }; - - namespace detail { - inline bool allows_parallel(allow_parallel_edge_tag) { return true; } - inline bool allows_parallel(disallow_parallel_edge_tag) { return false; } - } +/** Return true if the given graph is undirected. */ +template < typename Graph > bool is_undirected(const Graph& g) +{ + return !is_directed(g); +} - template - bool allows_parallel_edges(const Graph&) { - typedef typename graph_traits::edge_parallel_category Cat; - return detail::allows_parallel(Cat()); - } +/** @name Directed/Undirected Graph Traits */ +//@{ +namespace graph_detail +{ + template < typename Tag > + struct is_directed_tag + : mpl::bool_< is_convertible< Tag, directed_tag >::value > + { + }; +} // namespace graph_detail + +template < typename Graph > +struct is_directed_graph +: graph_detail::is_directed_tag< + typename graph_traits< Graph >::directed_category > +{ +}; + +template < typename Graph > +struct is_undirected_graph : mpl::not_< is_directed_graph< Graph > > +{ +}; +//@} + +// edge_parallel_category tags +struct allow_parallel_edge_tag +{ +}; +struct disallow_parallel_edge_tag +{ +}; + +namespace detail +{ + inline bool allows_parallel(allow_parallel_edge_tag) { return true; } + inline bool allows_parallel(disallow_parallel_edge_tag) { return false; } +} - /** @name Parallel Edges Traits */ - //@{ - /** - * The is_multigraph metafunction returns true if the graph allows - * parallel edges. Technically, a multigraph is a simple graph that - * allows parallel edges, but since there are no traits for the allowance - * or disallowance of loops, this is a moot point. - */ - template - struct is_multigraph - : mpl::bool_< - is_same< - typename graph_traits::edge_parallel_category, - allow_parallel_edge_tag - >::value - > - { }; - //@} - - // traversal_category tags - struct incidence_graph_tag { }; - struct adjacency_graph_tag { }; - struct bidirectional_graph_tag : virtual incidence_graph_tag { }; - struct vertex_list_graph_tag { }; - struct edge_list_graph_tag { }; - struct adjacency_matrix_tag { }; - - // Parallel traversal_category tags - struct distributed_graph_tag { }; - struct distributed_vertex_list_graph_tag { }; - struct distributed_edge_list_graph_tag { }; -#define BOOST_GRAPH_SEQUENTIAL_TRAITS_DEFINES_DISTRIBUTED_TAGS // Disable these from external versions of PBGL - - /** @name Traversal Category Traits - * These traits classify graph types by their supported methods of - * vertex and edge traversal. - */ - //@{ - template - struct is_incidence_graph - : mpl::bool_< - is_convertible< - typename graph_traits::traversal_category, - incidence_graph_tag - >::value - > - { }; - - template - struct is_bidirectional_graph - : mpl::bool_< - is_convertible< - typename graph_traits::traversal_category, - bidirectional_graph_tag - >::value - > - { }; - - template - struct is_vertex_list_graph - : mpl::bool_< - is_convertible< - typename graph_traits::traversal_category, - vertex_list_graph_tag - >::value - > - { }; - - template - struct is_edge_list_graph - : mpl::bool_< - is_convertible< - typename graph_traits::traversal_category, - edge_list_graph_tag - >::value - > - { }; - - template - struct is_adjacency_matrix - : mpl::bool_< - is_convertible< - typename graph_traits::traversal_category, - adjacency_matrix_tag - >::value - > - { }; - //@} - - /** @name Directed Graph Traits - * These metafunctions are used to fully classify directed vs. undirected - * graphs. Recall that an undirected graph is also bidirectional, but it - * cannot be both undirected and directed at the same time. - */ - //@{ - template - struct is_directed_unidirectional_graph - : mpl::and_< - is_directed_graph, mpl::not_< is_bidirectional_graph > - > - { }; - - template - struct is_directed_bidirectional_graph - : mpl::and_< - is_directed_graph, is_bidirectional_graph - > - { }; - //@} - - //?? not the right place ?? Lee - typedef boost::forward_traversal_tag multi_pass_input_iterator_tag; - - namespace detail { - BOOST_MPL_HAS_XXX_TRAIT_DEF(graph_property_type) - BOOST_MPL_HAS_XXX_TRAIT_DEF(edge_property_type) - BOOST_MPL_HAS_XXX_TRAIT_DEF(vertex_property_type) - - template struct get_graph_property_type {typedef typename G::graph_property_type type;}; - template struct get_edge_property_type {typedef typename G::edge_property_type type;}; - template struct get_vertex_property_type {typedef typename G::vertex_property_type type;}; - } +template < typename Graph > bool allows_parallel_edges(const Graph&) +{ + typedef typename graph_traits< Graph >::edge_parallel_category Cat; + return detail::allows_parallel(Cat()); +} - template - struct graph_property_type - : boost::mpl::eval_if, - detail::get_graph_property_type, - no_property> {}; - template - struct edge_property_type - : boost::mpl::eval_if, - detail::get_edge_property_type, - no_property> {}; - template - struct vertex_property_type - : boost::mpl::eval_if, - detail::get_vertex_property_type, - no_property> {}; - - template - struct graph_bundle_type { - typedef typename G::graph_bundled type; +/** @name Parallel Edges Traits */ +//@{ +/** + * The is_multigraph metafunction returns true if the graph allows + * parallel edges. Technically, a multigraph is a simple graph that + * allows parallel edges, but since there are no traits for the allowance + * or disallowance of loops, this is a moot point. + */ +template < typename Graph > +struct is_multigraph +: mpl::bool_< is_same< typename graph_traits< Graph >::edge_parallel_category, + allow_parallel_edge_tag >::value > +{ +}; +//@} + +// traversal_category tags +struct incidence_graph_tag +{ +}; +struct adjacency_graph_tag +{ +}; +struct bidirectional_graph_tag : virtual incidence_graph_tag +{ +}; +struct vertex_list_graph_tag +{ +}; +struct edge_list_graph_tag +{ +}; +struct adjacency_matrix_tag +{ +}; + +// Parallel traversal_category tags +struct distributed_graph_tag +{ +}; +struct distributed_vertex_list_graph_tag +{ +}; +struct distributed_edge_list_graph_tag +{ +}; +#define BOOST_GRAPH_SEQUENTIAL_TRAITS_DEFINES_DISTRIBUTED_TAGS // Disable these + // from external + // versions of + // PBGL + +/** @name Traversal Category Traits + * These traits classify graph types by their supported methods of + * vertex and edge traversal. + */ +//@{ +template < typename Graph > +struct is_incidence_graph +: mpl::bool_< + is_convertible< typename graph_traits< Graph >::traversal_category, + incidence_graph_tag >::value > +{ +}; + +template < typename Graph > +struct is_bidirectional_graph +: mpl::bool_< + is_convertible< typename graph_traits< Graph >::traversal_category, + bidirectional_graph_tag >::value > +{ +}; + +template < typename Graph > +struct is_vertex_list_graph +: mpl::bool_< + is_convertible< typename graph_traits< Graph >::traversal_category, + vertex_list_graph_tag >::value > +{ +}; + +template < typename Graph > +struct is_edge_list_graph +: mpl::bool_< + is_convertible< typename graph_traits< Graph >::traversal_category, + edge_list_graph_tag >::value > +{ +}; + +template < typename Graph > +struct is_adjacency_matrix +: mpl::bool_< + is_convertible< typename graph_traits< Graph >::traversal_category, + adjacency_matrix_tag >::value > +{ +}; +//@} + +/** @name Directed Graph Traits + * These metafunctions are used to fully classify directed vs. undirected + * graphs. Recall that an undirected graph is also bidirectional, but it + * cannot be both undirected and directed at the same time. + */ +//@{ +template < typename Graph > +struct is_directed_unidirectional_graph +: mpl::and_< is_directed_graph< Graph >, + mpl::not_< is_bidirectional_graph< Graph > > > +{ +}; + +template < typename Graph > +struct is_directed_bidirectional_graph +: mpl::and_< is_directed_graph< Graph >, is_bidirectional_graph< Graph > > +{ +}; +//@} + +//?? not the right place ?? Lee +typedef boost::forward_traversal_tag multi_pass_input_iterator_tag; + +namespace detail +{ + BOOST_MPL_HAS_XXX_TRAIT_DEF(graph_property_type) + BOOST_MPL_HAS_XXX_TRAIT_DEF(edge_property_type) + BOOST_MPL_HAS_XXX_TRAIT_DEF(vertex_property_type) + + template < typename G > struct get_graph_property_type + { + typedef typename G::graph_property_type type; }; - - template - struct vertex_bundle_type { - typedef typename G::vertex_bundled type; + template < typename G > struct get_edge_property_type + { + typedef typename G::edge_property_type type; }; - - template - struct edge_bundle_type { - typedef typename G::edge_bundled type; + template < typename G > struct get_vertex_property_type + { + typedef typename G::vertex_property_type type; }; +} + +template < typename G > +struct graph_property_type +: boost::mpl::eval_if< detail::has_graph_property_type< G >, + detail::get_graph_property_type< G >, no_property > +{ +}; +template < typename G > +struct edge_property_type +: boost::mpl::eval_if< detail::has_edge_property_type< G >, + detail::get_edge_property_type< G >, no_property > +{ +}; +template < typename G > +struct vertex_property_type +: boost::mpl::eval_if< detail::has_vertex_property_type< G >, + detail::get_vertex_property_type< G >, no_property > +{ +}; + +template < typename G > struct graph_bundle_type +{ + typedef typename G::graph_bundled type; +}; + +template < typename G > struct vertex_bundle_type +{ + typedef typename G::vertex_bundled type; +}; + +template < typename G > struct edge_bundle_type +{ + typedef typename G::edge_bundled type; +}; + +namespace graph +{ + namespace detail + { + template < typename Graph, typename Descriptor > class bundled_result + { + typedef typename graph_traits< Graph >::vertex_descriptor Vertex; + typedef typename mpl::if_c< (is_same< Descriptor, Vertex >::value), + vertex_bundle_type< Graph >, edge_bundle_type< Graph > >::type + bundler; - namespace graph { namespace detail { - template - class bundled_result { - typedef typename graph_traits::vertex_descriptor Vertex; - typedef typename mpl::if_c<(is_same::value), - vertex_bundle_type, - edge_bundle_type >::type bundler; public: typedef typename bundler::type type; }; - template - class bundled_result { - typedef typename graph_traits::vertex_descriptor Vertex; - typedef graph_bundle_type bundler; + template < typename Graph > + class bundled_result< Graph, graph_bundle_t > + { + typedef typename graph_traits< Graph >::vertex_descriptor Vertex; + typedef graph_bundle_type< Graph > bundler; + public: typedef typename bundler::type type; }; - } } // namespace graph::detail - - namespace graph_detail { - // A helper metafunction for determining whether or not a type is - // bundled. - template - struct is_no_bundle : mpl::bool_::value> - { }; - } // namespace graph_detail - - /** @name Graph Property Traits - * These metafunctions (along with those above), can be used to access the - * vertex and edge properties (bundled or otherwise) of vertices and - * edges. - */ - //@{ - template - struct has_graph_property - : mpl::not_< - typename detail::is_no_property< - typename graph_property_type::type - >::type - >::type - { }; - - template - struct has_bundled_graph_property - : mpl::not_< - graph_detail::is_no_bundle::type> - > - { }; - - template - struct has_vertex_property - : mpl::not_< - typename detail::is_no_property::type> - >::type - { }; - - template - struct has_bundled_vertex_property - : mpl::not_< - graph_detail::is_no_bundle::type> - > - { }; - - template - struct has_edge_property - : mpl::not_< - typename detail::is_no_property::type> - >::type - { }; - - template - struct has_bundled_edge_property - : mpl::not_< - graph_detail::is_no_bundle::type> - > - { }; - //@} + } +} // namespace graph::detail + +namespace graph_detail +{ + // A helper metafunction for determining whether or not a type is + // bundled. + template < typename T > + struct is_no_bundle : mpl::bool_< is_same< T, no_property >::value > + { + }; +} // namespace graph_detail + +/** @name Graph Property Traits + * These metafunctions (along with those above), can be used to access the + * vertex and edge properties (bundled or otherwise) of vertices and + * edges. + */ +//@{ +template < typename Graph > +struct has_graph_property +: mpl::not_< typename detail::is_no_property< + typename graph_property_type< Graph >::type >::type >::type +{ +}; + +template < typename Graph > +struct has_bundled_graph_property +: mpl::not_< + graph_detail::is_no_bundle< typename graph_bundle_type< Graph >::type > > +{ +}; + +template < typename Graph > +struct has_vertex_property +: mpl::not_< typename detail::is_no_property< + typename vertex_property_type< Graph >::type > >::type +{ +}; + +template < typename Graph > +struct has_bundled_vertex_property +: mpl::not_< + graph_detail::is_no_bundle< typename vertex_bundle_type< Graph >::type > > +{ +}; + +template < typename Graph > +struct has_edge_property +: mpl::not_< typename detail::is_no_property< + typename edge_property_type< Graph >::type > >::type +{ +}; + +template < typename Graph > +struct has_bundled_edge_property +: mpl::not_< + graph_detail::is_no_bundle< typename edge_bundle_type< Graph >::type > > +{ +}; +//@} } // namespace boost @@ -380,14 +427,19 @@ namespace boost { // but the alternative is to put source and target in the global // namespace which causes name conflicts with other libraries (like // SUIF). -namespace std { +namespace std +{ - /* Some helper functions for dealing with pairs as edges */ - template - T source(pair p, const G&) { return p.first; } +/* Some helper functions for dealing with pairs as edges */ +template < class T, class G > T source(pair< T, T > p, const G&) +{ + return p.first; +} - template - T target(pair p, const G&) { return p.second; } +template < class T, class G > T target(pair< T, T > p, const G&) +{ + return p.second; +} } @@ -395,9 +447,10 @@ namespace std { // For some reason g++ with STLport does not see the above definition // of source() and target() unless we bring them into the boost // namespace. -namespace boost { - using std::source; - using std::target; +namespace boost +{ +using std::source; +using std::target; } #endif diff --git a/include/boost/graph/graph_utility.hpp b/include/boost/graph/graph_utility.hpp index b7278b6b4..4082dbf98 100644 --- a/include/boost/graph/graph_utility.hpp +++ b/include/boost/graph/graph_utility.hpp @@ -25,453 +25,464 @@ // iota moved to detail/algorithm.hpp #include -namespace boost { - - // Provide an undirected graph interface alternative to the - // the source() and target() edge functions. - template - inline - std::pair::vertex_descriptor, - typename graph_traits::vertex_descriptor> - incident(typename graph_traits::edge_descriptor e, - UndirectedGraph& g) - { - return std::make_pair(source(e,g), target(e,g)); - } - - // Provide an undirected graph interface alternative - // to the out_edges() function. - template - inline - std::pair::out_edge_iterator, - typename graph_traits::out_edge_iterator> - incident_edges(typename graph_traits::vertex_descriptor u, - Graph& g) - { +namespace boost +{ + +// Provide an undirected graph interface alternative to the +// the source() and target() edge functions. +template < class UndirectedGraph > +inline std::pair< typename graph_traits< UndirectedGraph >::vertex_descriptor, + typename graph_traits< UndirectedGraph >::vertex_descriptor > +incident(typename graph_traits< UndirectedGraph >::edge_descriptor e, + UndirectedGraph& g) +{ + return std::make_pair(source(e, g), target(e, g)); +} + +// Provide an undirected graph interface alternative +// to the out_edges() function. +template < class Graph > +inline std::pair< typename graph_traits< Graph >::out_edge_iterator, + typename graph_traits< Graph >::out_edge_iterator > +incident_edges(typename graph_traits< Graph >::vertex_descriptor u, Graph& g) +{ return out_edges(u, g); - } - - template - inline typename graph_traits::vertex_descriptor - opposite(typename graph_traits::edge_descriptor e, - typename graph_traits::vertex_descriptor v, - const Graph& g) - { - typedef typename graph_traits::vertex_descriptor vertex_descriptor; +} + +template < class Graph > +inline typename graph_traits< Graph >::vertex_descriptor opposite( + typename graph_traits< Graph >::edge_descriptor e, + typename graph_traits< Graph >::vertex_descriptor v, const Graph& g) +{ + typedef typename graph_traits< Graph >::vertex_descriptor vertex_descriptor; if (v == source(e, g)) - return target(e, g); + return target(e, g); else if (v == target(e, g)) - return source(e, g); + return source(e, g); else - return vertex_descriptor(); - } - - //=========================================================================== - // Some handy predicates - - template - struct incident_from_predicate { - incident_from_predicate(Vertex u, const Graph& g) - : m_u(u), m_g(g) { } - template - bool operator()(const Edge& e) const { - return source(e, m_g) == m_u; + return vertex_descriptor(); +} + +//=========================================================================== +// Some handy predicates + +template < typename Vertex, typename Graph > struct incident_from_predicate +{ + incident_from_predicate(Vertex u, const Graph& g) : m_u(u), m_g(g) {} + template < class Edge > bool operator()(const Edge& e) const + { + return source(e, m_g) == m_u; } Vertex m_u; const Graph& m_g; - }; - template - inline incident_from_predicate - incident_from(Vertex u, const Graph& g) { - return incident_from_predicate(u, g); - } - - template - struct incident_to_predicate { - incident_to_predicate(Vertex u, const Graph& g) - : m_u(u), m_g(g) { } - template - bool operator()(const Edge& e) const { - return target(e, m_g) == m_u; +}; +template < typename Vertex, typename Graph > +inline incident_from_predicate< Vertex, Graph > incident_from( + Vertex u, const Graph& g) +{ + return incident_from_predicate< Vertex, Graph >(u, g); +} + +template < typename Vertex, typename Graph > struct incident_to_predicate +{ + incident_to_predicate(Vertex u, const Graph& g) : m_u(u), m_g(g) {} + template < class Edge > bool operator()(const Edge& e) const + { + return target(e, m_g) == m_u; } Vertex m_u; const Graph& m_g; - }; - template - inline incident_to_predicate - incident_to(Vertex u, const Graph& g) { - return incident_to_predicate(u, g); - } - - template - struct incident_on_predicate { - incident_on_predicate(Vertex u, const Graph& g) - : m_u(u), m_g(g) { } - template - bool operator()(const Edge& e) const { - return source(e, m_g) == m_u || target(e, m_g) == m_u; +}; +template < typename Vertex, typename Graph > +inline incident_to_predicate< Vertex, Graph > incident_to( + Vertex u, const Graph& g) +{ + return incident_to_predicate< Vertex, Graph >(u, g); +} + +template < typename Vertex, typename Graph > struct incident_on_predicate +{ + incident_on_predicate(Vertex u, const Graph& g) : m_u(u), m_g(g) {} + template < class Edge > bool operator()(const Edge& e) const + { + return source(e, m_g) == m_u || target(e, m_g) == m_u; } Vertex m_u; const Graph& m_g; - }; - template - inline incident_on_predicate - incident_on(Vertex u, const Graph& g) { - return incident_on_predicate(u, g); - } - - template - struct connects_predicate { +}; +template < typename Vertex, typename Graph > +inline incident_on_predicate< Vertex, Graph > incident_on( + Vertex u, const Graph& g) +{ + return incident_on_predicate< Vertex, Graph >(u, g); +} + +template < typename Vertex, typename Graph > struct connects_predicate +{ connects_predicate(Vertex u, Vertex v, const Graph& g) - : m_u(u), m_v(v), m_g(g) { } - template - bool operator()(const Edge& e) const { - if (is_directed(m_g)) - return source(e, m_g) == m_u && target(e, m_g) == m_v; - else - return (source(e, m_g) == m_u && target(e, m_g) == m_v) - || (source(e, m_g) == m_v && target(e, m_g) == m_u); + : m_u(u), m_v(v), m_g(g) + { + } + template < class Edge > bool operator()(const Edge& e) const + { + if (is_directed(m_g)) + return source(e, m_g) == m_u && target(e, m_g) == m_v; + else + return (source(e, m_g) == m_u && target(e, m_g) == m_v) + || (source(e, m_g) == m_v && target(e, m_g) == m_u); } Vertex m_u, m_v; const Graph& m_g; - }; - template - inline connects_predicate - connects(Vertex u, Vertex v, const Graph& g) { - return connects_predicate(u, v, g); - } - - - // Need to convert all of these printing functions to take an ostream object - // -JGS - - template - void print_in_edges(const IncidenceGraph& G, Name name, std::ostream& os = std::cout) - { - typename graph_traits::vertex_iterator ui,ui_end; - for (boost::tie(ui,ui_end) = vertices(G); ui != ui_end; ++ui) { - os << get(name,*ui) << " <-- "; - typename graph_traits - ::in_edge_iterator ei, ei_end; - for(boost::tie(ei,ei_end) = in_edges(*ui,G); ei != ei_end; ++ei) - os << get(name,source(*ei,G)) << " "; - os << '\n'; +}; +template < typename Vertex, typename Graph > +inline connects_predicate< Vertex, Graph > connects( + Vertex u, Vertex v, const Graph& g) +{ + return connects_predicate< Vertex, Graph >(u, v, g); +} + +// Need to convert all of these printing functions to take an ostream object +// -JGS + +template < class IncidenceGraph, class Name > +void print_in_edges( + const IncidenceGraph& G, Name name, std::ostream& os = std::cout) +{ + typename graph_traits< IncidenceGraph >::vertex_iterator ui, ui_end; + for (boost::tie(ui, ui_end) = vertices(G); ui != ui_end; ++ui) + { + os << get(name, *ui) << " <-- "; + typename graph_traits< IncidenceGraph >::in_edge_iterator ei, ei_end; + for (boost::tie(ei, ei_end) = in_edges(*ui, G); ei != ei_end; ++ei) + os << get(name, source(*ei, G)) << " "; + os << '\n'; } - } - - template - void print_graph_dispatch(const IncidenceGraph& G, Name name, directed_tag, std::ostream& os = std::cout) - { - typename graph_traits::vertex_iterator ui,ui_end; - for (boost::tie(ui,ui_end) = vertices(G); ui != ui_end; ++ui) { - os << get(name,*ui) << " --> "; - typename graph_traits - ::out_edge_iterator ei, ei_end; - for(boost::tie(ei,ei_end) = out_edges(*ui,G); ei != ei_end; ++ei) - os << get(name,target(*ei,G)) << " "; - os << '\n'; +} + +template < class IncidenceGraph, class Name > +void print_graph_dispatch(const IncidenceGraph& G, Name name, directed_tag, + std::ostream& os = std::cout) +{ + typename graph_traits< IncidenceGraph >::vertex_iterator ui, ui_end; + for (boost::tie(ui, ui_end) = vertices(G); ui != ui_end; ++ui) + { + os << get(name, *ui) << " --> "; + typename graph_traits< IncidenceGraph >::out_edge_iterator ei, ei_end; + for (boost::tie(ei, ei_end) = out_edges(*ui, G); ei != ei_end; ++ei) + os << get(name, target(*ei, G)) << " "; + os << '\n'; } - } - template - void print_graph_dispatch(const IncidenceGraph& G, Name name, undirected_tag, std::ostream& os = std::cout) - { - typename graph_traits::vertex_iterator ui,ui_end; - for (boost::tie(ui,ui_end) = vertices(G); ui != ui_end; ++ui) { - os << get(name,*ui) << " <--> "; - typename graph_traits - ::out_edge_iterator ei, ei_end; - for(boost::tie(ei,ei_end) = out_edges(*ui,G); ei != ei_end; ++ei) - os << get(name,target(*ei,G)) << " "; - os << '\n'; +} +template < class IncidenceGraph, class Name > +void print_graph_dispatch(const IncidenceGraph& G, Name name, undirected_tag, + std::ostream& os = std::cout) +{ + typename graph_traits< IncidenceGraph >::vertex_iterator ui, ui_end; + for (boost::tie(ui, ui_end) = vertices(G); ui != ui_end; ++ui) + { + os << get(name, *ui) << " <--> "; + typename graph_traits< IncidenceGraph >::out_edge_iterator ei, ei_end; + for (boost::tie(ei, ei_end) = out_edges(*ui, G); ei != ei_end; ++ei) + os << get(name, target(*ei, G)) << " "; + os << '\n'; } - } - template - void print_graph(const IncidenceGraph& G, Name name, std::ostream& os = std::cout) - { - typedef typename graph_traits - ::directed_category Cat; +} +template < class IncidenceGraph, class Name > +void print_graph( + const IncidenceGraph& G, Name name, std::ostream& os = std::cout) +{ + typedef typename graph_traits< IncidenceGraph >::directed_category Cat; print_graph_dispatch(G, name, Cat(), os); - } - template - void print_graph(const IncidenceGraph& G, std::ostream& os = std::cout) { +} +template < class IncidenceGraph > +void print_graph(const IncidenceGraph& G, std::ostream& os = std::cout) +{ print_graph(G, get(vertex_index, G), os); - } +} - template - void print_edges(const EdgeListGraph& G, Name name, std::ostream& os = std::cout) - { - typename graph_traits::edge_iterator ei, ei_end; +template < class EdgeListGraph, class Name > +void print_edges( + const EdgeListGraph& G, Name name, std::ostream& os = std::cout) +{ + typename graph_traits< EdgeListGraph >::edge_iterator ei, ei_end; for (boost::tie(ei, ei_end) = edges(G); ei != ei_end; ++ei) - os << "(" << get(name, source(*ei, G)) - << "," << get(name, target(*ei, G)) << ") "; + os << "(" << get(name, source(*ei, G)) << "," + << get(name, target(*ei, G)) << ") "; os << '\n'; - } +} - template - void print_edges2(const EdgeListGraph& G, VertexName vname, EdgeName ename, std::ostream& os = std::cout) - { - typename graph_traits::edge_iterator ei, ei_end; +template < class EdgeListGraph, class VertexName, class EdgeName > +void print_edges2(const EdgeListGraph& G, VertexName vname, EdgeName ename, + std::ostream& os = std::cout) +{ + typename graph_traits< EdgeListGraph >::edge_iterator ei, ei_end; for (boost::tie(ei, ei_end) = edges(G); ei != ei_end; ++ei) - os << get(ename, *ei) << "(" << get(vname, source(*ei, G)) - << "," << get(vname, target(*ei, G)) << ") "; + os << get(ename, *ei) << "(" << get(vname, source(*ei, G)) << "," + << get(vname, target(*ei, G)) << ") "; os << '\n'; - } - - template - void print_vertices(const VertexListGraph& G, Name name, std::ostream& os = std::cout) - { - typename graph_traits::vertex_iterator vi,vi_end; - for (boost::tie(vi,vi_end) = vertices(G); vi != vi_end; ++vi) - os << get(name,*vi) << " "; +} + +template < class VertexListGraph, class Name > +void print_vertices( + const VertexListGraph& G, Name name, std::ostream& os = std::cout) +{ + typename graph_traits< VertexListGraph >::vertex_iterator vi, vi_end; + for (boost::tie(vi, vi_end) = vertices(G); vi != vi_end; ++vi) + os << get(name, *vi) << " "; os << '\n'; - } +} - template - bool is_adj_dispatch(Graph& g, Vertex a, Vertex b, bidirectional_tag) - { - typename graph_traits::adjacency_iterator vi, viend, - adj_found; +template < class Graph, class Vertex > +bool is_adj_dispatch(Graph& g, Vertex a, Vertex b, bidirectional_tag) +{ + typename graph_traits< Graph >::adjacency_iterator vi, viend, adj_found; boost::tie(vi, viend) = adjacent_vertices(a, g); adj_found = std::find(vi, viend, b); if (adj_found == viend) - return false; + return false; - typename graph_traits::out_edge_iterator oi, oiend, - out_found; + typename graph_traits< Graph >::out_edge_iterator oi, oiend, out_found; boost::tie(oi, oiend) = out_edges(a, g); out_found = std::find_if(oi, oiend, incident_to(b, g)); if (out_found == oiend) - return false; + return false; - typename graph_traits::in_edge_iterator ii, iiend, - in_found; + typename graph_traits< Graph >::in_edge_iterator ii, iiend, in_found; boost::tie(ii, iiend) = in_edges(b, g); in_found = std::find_if(ii, iiend, incident_from(a, g)); if (in_found == iiend) - return false; + return false; return true; - } - template - bool is_adj_dispatch(Graph& g, Vertex a, Vertex b, directed_tag) - { - typename graph_traits::adjacency_iterator vi, viend, found; +} +template < class Graph, class Vertex > +bool is_adj_dispatch(Graph& g, Vertex a, Vertex b, directed_tag) +{ + typename graph_traits< Graph >::adjacency_iterator vi, viend, found; boost::tie(vi, viend) = adjacent_vertices(a, g); found = std::find(vi, viend, b); - if ( found == viend ) - return false; + if (found == viend) + return false; - typename graph_traits::out_edge_iterator oi, oiend, - out_found; + typename graph_traits< Graph >::out_edge_iterator oi, oiend, out_found; boost::tie(oi, oiend) = out_edges(a, g); out_found = std::find_if(oi, oiend, incident_to(b, g)); if (out_found == oiend) - return false; + return false; return true; - } - template - bool is_adj_dispatch(Graph& g, Vertex a, Vertex b, undirected_tag) - { +} +template < class Graph, class Vertex > +bool is_adj_dispatch(Graph& g, Vertex a, Vertex b, undirected_tag) +{ return is_adj_dispatch(g, a, b, directed_tag()); - } +} - template - bool is_adjacent(Graph& g, Vertex a, Vertex b) { - typedef typename graph_traits::directed_category Cat; +template < class Graph, class Vertex > +bool is_adjacent(Graph& g, Vertex a, Vertex b) +{ + typedef typename graph_traits< Graph >::directed_category Cat; return is_adj_dispatch(g, a, b, Cat()); - } +} - template - bool in_edge_set(Graph& g, Edge e) - { +template < class Graph, class Edge > bool in_edge_set(Graph& g, Edge e) +{ typename Graph::edge_iterator ei, ei_end, found; boost::tie(ei, ei_end) = edges(g); found = std::find(ei, ei_end, e); return found != ei_end; - } +} - template - bool in_vertex_set(Graph& g, Vertex v) - { +template < class Graph, class Vertex > bool in_vertex_set(Graph& g, Vertex v) +{ typename Graph::vertex_iterator vi, vi_end, found; boost::tie(vi, vi_end) = vertices(g); found = std::find(vi, vi_end, v); return found != vi_end; - } +} - template - bool in_edge_set(Graph& g, Vertex u, Vertex v) - { +template < class Graph, class Vertex > +bool in_edge_set(Graph& g, Vertex u, Vertex v) +{ typename Graph::edge_iterator ei, ei_end; - for (boost::tie(ei,ei_end) = edges(g); ei != ei_end; ++ei) - if (source(*ei,g) == u && target(*ei,g) == v) - return true; + for (boost::tie(ei, ei_end) = edges(g); ei != ei_end; ++ei) + if (source(*ei, g) == u && target(*ei, g) == v) + return true; return false; - } - - // is x a descendant of y? - template - inline bool is_descendant - (typename property_traits::value_type x, - typename property_traits::value_type y, - ParentMap parent) - { +} + +// is x a descendant of y? +template < typename ParentMap > +inline bool is_descendant(typename property_traits< ParentMap >::value_type x, + typename property_traits< ParentMap >::value_type y, ParentMap parent) +{ if (get(parent, x) == x) // x is the root of the tree - return false; + return false; else if (get(parent, x) == y) - return true; + return true; else - return is_descendant(get(parent, x), y, parent); - } - - // is y reachable from x? - template - inline bool is_reachable - (typename graph_traits::vertex_descriptor x, - typename graph_traits::vertex_descriptor y, - const IncidenceGraph& g, - VertexColorMap color) // should start out white for every vertex - { - typedef typename property_traits::value_type ColorValue; + return is_descendant(get(parent, x), y, parent); +} + +// is y reachable from x? +template < typename IncidenceGraph, typename VertexColorMap > +inline bool is_reachable( + typename graph_traits< IncidenceGraph >::vertex_descriptor x, + typename graph_traits< IncidenceGraph >::vertex_descriptor y, + const IncidenceGraph& g, + VertexColorMap color) // should start out white for every vertex +{ + typedef typename property_traits< VertexColorMap >::value_type ColorValue; dfs_visitor<> vis; depth_first_visit(g, x, vis, color); - return get(color, y) != color_traits::white(); - } - - // Is the undirected graph connected? - // Is the directed graph strongly connected? - template - inline bool is_connected(const VertexListGraph& g, VertexColorMap color) - { - typedef typename property_traits::value_type ColorValue; - typedef color_traits Color; - typename graph_traits::vertex_iterator - ui, ui_end, vi, vi_end, ci, ci_end; + return get(color, y) != color_traits< ColorValue >::white(); +} + +// Is the undirected graph connected? +// Is the directed graph strongly connected? +template < typename VertexListGraph, typename VertexColorMap > +inline bool is_connected(const VertexListGraph& g, VertexColorMap color) +{ + typedef typename property_traits< VertexColorMap >::value_type ColorValue; + typedef color_traits< ColorValue > Color; + typename graph_traits< VertexListGraph >::vertex_iterator ui, ui_end, vi, + vi_end, ci, ci_end; for (boost::tie(ui, ui_end) = vertices(g); ui != ui_end; ++ui) - for (boost::tie(vi, vi_end) = vertices(g); vi != vi_end; ++vi) - if (*ui != *vi) { - for (boost::tie(ci, ci_end) = vertices(g); ci != ci_end; ++ci) - put(color, *ci, Color::white()); - if (! is_reachable(*ui, *vi, g, color)) - return false; - } + for (boost::tie(vi, vi_end) = vertices(g); vi != vi_end; ++vi) + if (*ui != *vi) + { + for (boost::tie(ci, ci_end) = vertices(g); ci != ci_end; ++ci) + put(color, *ci, Color::white()); + if (!is_reachable(*ui, *vi, g, color)) + return false; + } return true; - } +} - template - bool is_self_loop - (typename graph_traits::edge_descriptor e, - const Graph& g) - { +template < typename Graph > +bool is_self_loop( + typename graph_traits< Graph >::edge_descriptor e, const Graph& g) +{ return source(e, g) == target(e, g); - } - - - template - std::pair - make_list(const T1& t1, const T2& t2) - { return std::make_pair(t1, t2); } - - template - std::pair > - make_list(const T1& t1, const T2& t2, const T3& t3) - { return std::make_pair(t1, std::make_pair(t2, t3)); } - - template - std::pair > > - make_list(const T1& t1, const T2& t2, const T3& t3, const T4& t4) - { return std::make_pair(t1, std::make_pair(t2, std::make_pair(t3, t4))); } - - template - std::pair > > > - make_list(const T1& t1, const T2& t2, const T3& t3, const T4& t4, const T5& t5) - { return std::make_pair(t1, std::make_pair(t2, std::make_pair(t3, std::make_pair(t4, t5)))); } - - namespace graph { - - // Functor for remove_parallel_edges: edge property of the removed edge is added to the remaining - template - struct add_removed_edge_property +} + +template < class T1, class T2 > +std::pair< T1, T2 > make_list(const T1& t1, const T2& t2) +{ + return std::make_pair(t1, t2); +} + +template < class T1, class T2, class T3 > +std::pair< T1, std::pair< T2, T3 > > make_list( + const T1& t1, const T2& t2, const T3& t3) +{ + return std::make_pair(t1, std::make_pair(t2, t3)); +} + +template < class T1, class T2, class T3, class T4 > +std::pair< T1, std::pair< T2, std::pair< T3, T4 > > > make_list( + const T1& t1, const T2& t2, const T3& t3, const T4& t4) +{ + return std::make_pair(t1, std::make_pair(t2, std::make_pair(t3, t4))); +} + +template < class T1, class T2, class T3, class T4, class T5 > +std::pair< T1, std::pair< T2, std::pair< T3, std::pair< T4, T5 > > > > +make_list(const T1& t1, const T2& t2, const T3& t3, const T4& t4, const T5& t5) +{ + return std::make_pair( + t1, std::make_pair(t2, std::make_pair(t3, std::make_pair(t4, t5)))); +} + +namespace graph +{ + + // Functor for remove_parallel_edges: edge property of the removed edge is + // added to the remaining + template < typename EdgeProperty > struct add_removed_edge_property { - add_removed_edge_property(EdgeProperty ep) : ep(ep) {} - - template - void operator() (Edge stay, Edge away) - { - put(ep, stay, get(ep, stay) + get(ep, away)); - } - EdgeProperty ep; + add_removed_edge_property(EdgeProperty ep) : ep(ep) {} + + template < typename Edge > void operator()(Edge stay, Edge away) + { + put(ep, stay, get(ep, stay) + get(ep, away)); + } + EdgeProperty ep; }; // Same as above: edge property is capacity here - template + template < typename Graph > struct add_removed_edge_capacity - : add_removed_edge_property::type> + : add_removed_edge_property< + typename property_map< Graph, edge_capacity_t >::type > + { + typedef add_removed_edge_property< + typename property_map< Graph, edge_capacity_t >::type > + base; + add_removed_edge_capacity(Graph& g) : base(get(edge_capacity, g)) {} + }; + + template < typename Graph > bool has_no_vertices(const Graph& g) { - typedef add_removed_edge_property::type> base; - add_removed_edge_capacity(Graph& g) : base(get(edge_capacity, g)) {} - }; - - template - bool has_no_vertices(const Graph& g) { - typedef typename boost::graph_traits::vertex_iterator vi; - std::pair p = vertices(g); - return (p.first == p.second); + typedef typename boost::graph_traits< Graph >::vertex_iterator vi; + std::pair< vi, vi > p = vertices(g); + return (p.first == p.second); } - template - bool has_no_edges(const Graph& g) { - typedef typename boost::graph_traits::edge_iterator ei; - std::pair p = edges(g); - return (p.first == p.second); + template < typename Graph > bool has_no_edges(const Graph& g) + { + typedef typename boost::graph_traits< Graph >::edge_iterator ei; + std::pair< ei, ei > p = edges(g); + return (p.first == p.second); } - template - bool has_no_out_edges(const typename boost::graph_traits::vertex_descriptor& v, const Graph& g) { - typedef typename boost::graph_traits::out_edge_iterator ei; - std::pair p = out_edges(v, g); - return (p.first == p.second); + template < typename Graph > + bool has_no_out_edges( + const typename boost::graph_traits< Graph >::vertex_descriptor& v, + const Graph& g) + { + typedef typename boost::graph_traits< Graph >::out_edge_iterator ei; + std::pair< ei, ei > p = out_edges(v, g); + return (p.first == p.second); } - } // namespace graph +} // namespace graph - #include +#include - template - void copy_vertex_property(PropertyIn p_in, PropertyOut p_out, Graph& g) - { +template < class PropertyIn, class PropertyOut, class Graph > +void copy_vertex_property(PropertyIn p_in, PropertyOut p_out, Graph& g) +{ BGL_FORALL_VERTICES_T(u, g, Graph) - put(p_out, u, get(p_in, g)); - } + put(p_out, u, get(p_in, g)); +} - template - void copy_edge_property(PropertyIn p_in, PropertyOut p_out, Graph& g) - { +template < class PropertyIn, class PropertyOut, class Graph > +void copy_edge_property(PropertyIn p_in, PropertyOut p_out, Graph& g) +{ BGL_FORALL_EDGES_T(e, g, Graph) - put(p_out, e, get(p_in, g)); - } - - // Return true if property_map1 and property_map2 differ - // for any of the vertices in graph. - template - bool are_property_maps_different - (const PropertyMapFirst property_map1, - const PropertyMapSecond property_map2, - const Graph& graph) { - - BGL_FORALL_VERTICES_T(vertex, graph, Graph) { - if (get(property_map1, vertex) != - get(property_map2, vertex)) { - - return (true); - } + put(p_out, e, get(p_in, g)); +} + +// Return true if property_map1 and property_map2 differ +// for any of the vertices in graph. +template < typename PropertyMapFirst, typename PropertyMapSecond, + typename Graph > +bool are_property_maps_different(const PropertyMapFirst property_map1, + const PropertyMapSecond property_map2, const Graph& graph) +{ + + BGL_FORALL_VERTICES_T(vertex, graph, Graph) + { + if (get(property_map1, vertex) != get(property_map2, vertex)) + { + + return (true); + } } return (false); - } +} } /* namespace boost */ diff --git a/include/boost/graph/graphml.hpp b/include/boost/graph/graphml.hpp index 9d798520c..f768f9653 100644 --- a/include/boost/graph/graphml.hpp +++ b/include/boost/graph/graphml.hpp @@ -34,16 +34,19 @@ namespace boost ///////////////////////////////////////////////////////////////////////////// // Graph reader exceptions ///////////////////////////////////////////////////////////////////////////// -struct BOOST_SYMBOL_VISIBLE parse_error: public graph_exception +struct BOOST_SYMBOL_VISIBLE parse_error : public graph_exception { - parse_error(const std::string& err) {error = err; statement = "parse error: " + error;} + parse_error(const std::string& err) + { + error = err; + statement = "parse error: " + error; + } virtual ~parse_error() throw() {} - virtual const char* what() const throw() {return statement.c_str();} + virtual const char* what() const throw() { return statement.c_str(); } std::string statement; std::string error; }; - class mutate_graph { public: @@ -51,138 +54,148 @@ class mutate_graph virtual bool is_directed() const = 0; virtual boost::any do_add_vertex() = 0; - virtual std::pair do_add_edge(boost::any source, boost::any target) = 0; + virtual std::pair< boost::any, bool > do_add_edge( + boost::any source, boost::any target) + = 0; - virtual void - set_graph_property(const std::string& name, const std::string& value, const std::string& value_type) = 0; + virtual void set_graph_property(const std::string& name, + const std::string& value, const std::string& value_type) + = 0; - virtual void - set_vertex_property(const std::string& name, boost::any vertex, const std::string& value, const std::string& value_type) = 0; + virtual void set_vertex_property(const std::string& name, boost::any vertex, + const std::string& value, const std::string& value_type) + = 0; - virtual void - set_edge_property(const std::string& name, boost::any edge, const std::string& value, const std::string& value_type) = 0; + virtual void set_edge_property(const std::string& name, boost::any edge, + const std::string& value, const std::string& value_type) + = 0; }; -template -class mutate_graph_impl : public mutate_graph +template < typename MutableGraph > class mutate_graph_impl : public mutate_graph { - typedef typename graph_traits::vertex_descriptor vertex_descriptor; - typedef typename graph_traits::edge_descriptor edge_descriptor; + typedef typename graph_traits< MutableGraph >::vertex_descriptor + vertex_descriptor; + typedef + typename graph_traits< MutableGraph >::edge_descriptor edge_descriptor; - public: +public: mutate_graph_impl(MutableGraph& g, dynamic_properties& dp) - : m_g(g), m_dp(dp) { } - - bool is_directed() const + : m_g(g), m_dp(dp) { - return is_convertible::directed_category, - directed_tag>::value; } - virtual any do_add_vertex() + bool is_directed() const { - return any(add_vertex(m_g)); + return is_convertible< + typename graph_traits< MutableGraph >::directed_category, + directed_tag >::value; } - virtual std::pair do_add_edge(any source, any target) + virtual any do_add_vertex() { return any(add_vertex(m_g)); } + + virtual std::pair< any, bool > do_add_edge(any source, any target) { - std::pair retval = add_edge(any_cast(source), - any_cast(target), m_g); + std::pair< edge_descriptor, bool > retval + = add_edge(any_cast< vertex_descriptor >(source), + any_cast< vertex_descriptor >(target), m_g); return std::make_pair(any(retval.first), retval.second); } - virtual void - set_graph_property(const std::string& name, const std::string& value, const std::string& value_type) + virtual void set_graph_property(const std::string& name, + const std::string& value, const std::string& value_type) { bool type_found = false; try { - mpl::for_each(put_property - (name, m_dp, &m_g, value, value_type, m_type_names, type_found)); + mpl::for_each< value_types >( + put_property< MutableGraph*, value_types >(name, m_dp, &m_g, + value, value_type, m_type_names, type_found)); } catch (const bad_lexical_cast&) { - BOOST_THROW_EXCEPTION( - parse_error("invalid value \"" + value + "\" for key " + - name + " of type " + value_type)); + BOOST_THROW_EXCEPTION(parse_error("invalid value \"" + value + + "\" for key " + name + " of type " + value_type)); } if (!type_found) { - BOOST_THROW_EXCEPTION( - parse_error("unrecognized type \"" + value_type + - "\" for key " + name)); + BOOST_THROW_EXCEPTION(parse_error( + "unrecognized type \"" + value_type + "\" for key " + name)); } - } - virtual void - set_vertex_property(const std::string& name, any vertex, const std::string& value, const std::string& value_type) + virtual void set_vertex_property(const std::string& name, any vertex, + const std::string& value, const std::string& value_type) { bool type_found = false; try { - mpl::for_each(put_property - (name, m_dp, any_cast(vertex), - value, value_type, m_type_names, type_found)); + mpl::for_each< value_types >( + put_property< vertex_descriptor, value_types >(name, m_dp, + any_cast< vertex_descriptor >(vertex), value, value_type, + m_type_names, type_found)); } catch (const bad_lexical_cast&) { - BOOST_THROW_EXCEPTION( - parse_error("invalid value \"" + value + "\" for key " + - name + " of type " + value_type)); + BOOST_THROW_EXCEPTION(parse_error("invalid value \"" + value + + "\" for key " + name + " of type " + value_type)); } if (!type_found) { - BOOST_THROW_EXCEPTION( - parse_error("unrecognized type \"" + value_type + - "\" for key " + name)); + BOOST_THROW_EXCEPTION(parse_error( + "unrecognized type \"" + value_type + "\" for key " + name)); } - } - virtual void - set_edge_property(const std::string& name, any edge, const std::string& value, const std::string& value_type) + virtual void set_edge_property(const std::string& name, any edge, + const std::string& value, const std::string& value_type) { bool type_found = false; try { - mpl::for_each(put_property - (name, m_dp, any_cast(edge), - value, value_type, m_type_names, type_found)); + mpl::for_each< value_types >( + put_property< edge_descriptor, value_types >(name, m_dp, + any_cast< edge_descriptor >(edge), value, value_type, + m_type_names, type_found)); } catch (const bad_lexical_cast&) { - BOOST_THROW_EXCEPTION( - parse_error("invalid value \"" + value + "\" for key " + - name + " of type " + value_type)); + BOOST_THROW_EXCEPTION(parse_error("invalid value \"" + value + + "\" for key " + name + " of type " + value_type)); } if (!type_found) { - BOOST_THROW_EXCEPTION( - parse_error("unrecognized type \"" + value_type + - "\" for key " + name)); + BOOST_THROW_EXCEPTION(parse_error( + "unrecognized type \"" + value_type + "\" for key " + name)); } } - template - class put_property + template < typename Key, typename ValueVector > class put_property { public: - put_property(const std::string& name, dynamic_properties& dp, const Key& key, - const std::string& value, const std::string& value_type, - const char** type_names, bool& type_found) - : m_name(name), m_dp(dp), m_key(key), m_value(value), - m_value_type(value_type), m_type_names(type_names), - m_type_found(type_found) {} - template - void operator()(Value) + put_property(const std::string& name, dynamic_properties& dp, + const Key& key, const std::string& value, + const std::string& value_type, const char** type_names, + bool& type_found) + : m_name(name) + , m_dp(dp) + , m_key(key) + , m_value(value) + , m_value_type(value_type) + , m_type_names(type_names) + , m_type_found(type_found) { - if (m_value_type == m_type_names[mpl::find::type::pos::value]) + } + template < class Value > void operator()(Value) + { + if (m_value_type + == m_type_names[mpl::find< ValueVector, + Value >::type::pos::value]) { - put(m_name, m_dp, m_key, lexical_cast(m_value)); + put(m_name, m_dp, m_key, lexical_cast< Value >(m_value)); m_type_found = true; } } + private: const std::string& m_name; dynamic_properties& m_dp; @@ -196,72 +209,83 @@ class mutate_graph_impl : public mutate_graph protected: MutableGraph& m_g; dynamic_properties& m_dp; - typedef mpl::vector value_types; + typedef mpl::vector< bool, int, long, float, double, std::string > + value_types; static const char* m_type_names[]; }; -template -const char* mutate_graph_impl::m_type_names[] = {"boolean", "int", "long", "float", "double", "string"}; +template < typename MutableGraph > +const char* mutate_graph_impl< MutableGraph >::m_type_names[] + = { "boolean", "int", "long", "float", "double", "string" }; -void BOOST_GRAPH_DECL -read_graphml(std::istream& in, mutate_graph& g, size_t desired_idx); +void BOOST_GRAPH_DECL read_graphml( + std::istream& in, mutate_graph& g, size_t desired_idx); -template -void -read_graphml(std::istream& in, MutableGraph& g, dynamic_properties& dp, size_t desired_idx = 0) +template < typename MutableGraph > +void read_graphml(std::istream& in, MutableGraph& g, dynamic_properties& dp, + size_t desired_idx = 0) { - mutate_graph_impl mg(g,dp); + mutate_graph_impl< MutableGraph > mg(g, dp); read_graphml(in, mg, desired_idx); } -template -class get_type_name +template < typename Types > class get_type_name { public: - get_type_name(const std::type_info& type, const char** type_names, std::string& type_name) - : m_type(type), m_type_names(type_names), m_type_name(type_name) {} - template - void operator()(Type) + get_type_name(const std::type_info& type, const char** type_names, + std::string& type_name) + : m_type(type), m_type_names(type_names), m_type_name(type_name) + { + } + template < typename Type > void operator()(Type) { if (typeid(Type) == m_type) - m_type_name = m_type_names[mpl::find::type::pos::value]; + m_type_name + = m_type_names[mpl::find< Types, Type >::type::pos::value]; } + private: - const std::type_info &m_type; + const std::type_info& m_type; const char** m_type_names; - std::string &m_type_name; + std::string& m_type_name; }; - -template -void -write_graphml(std::ostream& out, const Graph& g, VertexIndexMap vertex_index, - const dynamic_properties& dp, bool ordered_vertices=false) +template < typename Graph, typename VertexIndexMap > +void write_graphml(std::ostream& out, const Graph& g, + VertexIndexMap vertex_index, const dynamic_properties& dp, + bool ordered_vertices = false) { - typedef typename graph_traits::directed_category directed_category; - typedef typename graph_traits::edge_descriptor edge_descriptor; - typedef typename graph_traits::vertex_descriptor vertex_descriptor; + typedef typename graph_traits< Graph >::directed_category directed_category; + typedef typename graph_traits< Graph >::edge_descriptor edge_descriptor; + typedef typename graph_traits< Graph >::vertex_descriptor vertex_descriptor; using boost::property_tree::xml_parser::encode_char_entities; BOOST_STATIC_CONSTANT(bool, - graph_is_directed = - (is_convertible::value)); + graph_is_directed + = (is_convertible< directed_category*, directed_tag* >::value)); out << "\n" - << "\n"; - - typedef mpl::vector value_types; - const char* type_names[] = {"boolean", "int", "int", "int", "int", "long", "long", "long", "long", "float", "double", "double", "string"}; - std::map graph_key_ids; - std::map vertex_key_ids; - std::map edge_key_ids; + << "\n"; + + typedef mpl::vector< bool, short, unsigned short, int, unsigned int, long, + unsigned long, long long, unsigned long long, float, double, + long double, std::string > + value_types; + const char* type_names[] = { "boolean", "int", "int", "int", "int", "long", + "long", "long", "long", "float", "double", "double", "string" }; + std::map< std::string, std::string > graph_key_ids; + std::map< std::string, std::string > vertex_key_ids; + std::map< std::string, std::string > edge_key_ids; int key_count = 0; // Output keys for (dynamic_properties::const_iterator i = dp.begin(); i != dp.end(); ++i) { - std::string key_id = "key" + lexical_cast(key_count++); + std::string key_id = "key" + lexical_cast< std::string >(key_count++); if (i->second->key() == typeid(Graph*)) graph_key_ids[i->first] = key_id; else if (i->second->key() == typeid(vertex_descriptor)) @@ -271,9 +295,15 @@ write_graphml(std::ostream& out, const Graph& g, VertexIndexMap vertex_index, else continue; std::string type_name = "string"; - mpl::for_each(get_type_name(i->second->value(), type_names, type_name)); + mpl::for_each< value_types >(get_type_name< value_types >( + i->second->value(), type_names, type_name)); out << " second->key() == typeid(Graph*) ? "graph" : (i->second->key() == typeid(vertex_descriptor) ? "node" : "edge")) << "\"" + << (i->second->key() == typeid(Graph*) + ? "graph" + : (i->second->key() == typeid(vertex_descriptor) + ? "node" + : "edge")) + << "\"" << " attr.name=\"" << i->first << "\"" << " attr.type=\"" << type_name << "\"" << " />\n"; @@ -281,7 +311,8 @@ write_graphml(std::ostream& out, const Graph& g, VertexIndexMap vertex_index, out << " \n"; // Output graph data @@ -292,30 +323,34 @@ write_graphml(std::ostream& out, const Graph& g, VertexIndexMap vertex_index, // The const_cast here is just to get typeid correct for property // map key; the graph should not be mutated using it. out << " first] << "\">" - << encode_char_entities(i->second->get_string(const_cast(&g))) << "\n"; + << encode_char_entities( + i->second->get_string(const_cast< Graph* >(&g))) + << "\n"; } } - typedef typename graph_traits::vertex_iterator vertex_iterator; + typedef typename graph_traits< Graph >::vertex_iterator vertex_iterator; vertex_iterator v, v_end; for (boost::tie(v, v_end) = vertices(g); v != v_end; ++v) { out << " \n"; // Output data - for (dynamic_properties::const_iterator i = dp.begin(); i != dp.end(); ++i) + for (dynamic_properties::const_iterator i = dp.begin(); i != dp.end(); + ++i) { if (i->second->key() == typeid(vertex_descriptor)) { out << " first] << "\">" - << encode_char_entities(i->second->get_string(*v)) << "\n"; + << encode_char_entities(i->second->get_string(*v)) + << "\n"; } } out << " \n"; } - typedef typename graph_traits::edge_iterator edge_iterator; + typedef typename graph_traits< Graph >::edge_iterator edge_iterator; edge_iterator e, e_end; - typename graph_traits::edges_size_type edge_count = 0; + typename graph_traits< Graph >::edges_size_type edge_count = 0; for (boost::tie(e, e_end) = edges(g); e != e_end; ++e) { out << " \n"; // Output data - for (dynamic_properties::const_iterator i = dp.begin(); i != dp.end(); ++i) + for (dynamic_properties::const_iterator i = dp.begin(); i != dp.end(); + ++i) { if (i->second->key() == typeid(edge_descriptor)) { out << " first] << "\">" - << encode_char_entities(i->second->get_string(*e)) << "\n"; + << encode_char_entities(i->second->get_string(*e)) + << "\n"; } } out << " \n"; @@ -338,11 +375,9 @@ write_graphml(std::ostream& out, const Graph& g, VertexIndexMap vertex_index, << "\n"; } - -template -void -write_graphml(std::ostream& out, const Graph& g, const dynamic_properties& dp, - bool ordered_vertices=false) +template < typename Graph > +void write_graphml(std::ostream& out, const Graph& g, + const dynamic_properties& dp, bool ordered_vertices = false) { write_graphml(out, g, get(vertex_index, g), dp, ordered_vertices); } diff --git a/include/boost/graph/graphviz.hpp b/include/boost/graph/graphviz.hpp index b82e11a92..8753ac974 100644 --- a/include/boost/graph/graphviz.hpp +++ b/include/boost/graph/graphviz.hpp @@ -35,408 +35,418 @@ #include #include -namespace boost { +namespace boost +{ - template - struct graphviz_io_traits { - static std::string name() { - return "digraph"; - } - static std::string delimiter() { - return "->"; - } }; - - template <> - struct graphviz_io_traits { - static std::string name() { - return "graph"; - } - static std::string delimiter() { - return "--"; - } - }; +template < typename directed_category > struct graphviz_io_traits +{ + static std::string name() { return "digraph"; } + static std::string delimiter() { return "->"; } +}; - struct default_writer { - void operator()(std::ostream&) const { - } - template - void operator()(std::ostream&, const VorE&) const { - } - }; +template <> struct graphviz_io_traits< undirected_tag > +{ + static std::string name() { return "graph"; } + static std::string delimiter() { return "--"; } +}; + +struct default_writer +{ + void operator()(std::ostream&) const {} + template < class VorE > void operator()(std::ostream&, const VorE&) const {} +}; - template - inline std::string escape_dot_string(const T& obj) { +template < typename T > inline std::string escape_dot_string(const T& obj) +{ using namespace boost::xpressive; - static sregex valid_unquoted_id = (((alpha | '_') >> *_w) | (!as_xpr('-') >> (('.' >> *_d) | (+_d >> !('.' >> *_d))))); - std::string s(boost::lexical_cast(obj)); - if (regex_match(s, valid_unquoted_id)) { - return s; - } else { - boost::algorithm::replace_all(s, "\"", "\\\""); - return "\"" + s + "\""; + static sregex valid_unquoted_id = (((alpha | '_') >> *_w) + | (!as_xpr('-') >> (('.' >> *_d) | (+_d >> !('.' >> *_d))))); + std::string s(boost::lexical_cast< std::string >(obj)); + if (regex_match(s, valid_unquoted_id)) + { + return s; + } + else + { + boost::algorithm::replace_all(s, "\"", "\\\""); + return "\"" + s + "\""; } - } +} - template - class label_writer { - public: +template < class Name > class label_writer +{ +public: label_writer(Name _name) : name(_name) {} - template - void operator()(std::ostream& out, const VertexOrEdge& v) const { - out << "[label=" << escape_dot_string(get(name, v)) << "]"; + template < class VertexOrEdge > + void operator()(std::ostream& out, const VertexOrEdge& v) const + { + out << "[label=" << escape_dot_string(get(name, v)) << "]"; } - private: + +private: Name name; - }; - template - inline label_writer - make_label_writer(Name n) { - return label_writer(n); - } - - enum edge_attribute_t { edge_attribute = 1111 }; - enum vertex_attribute_t { vertex_attribute = 2222 }; - enum graph_graph_attribute_t { graph_graph_attribute = 3333 }; - enum graph_vertex_attribute_t { graph_vertex_attribute = 4444 }; - enum graph_edge_attribute_t { graph_edge_attribute = 5555 }; - - BOOST_INSTALL_PROPERTY(edge, attribute); - BOOST_INSTALL_PROPERTY(vertex, attribute); - BOOST_INSTALL_PROPERTY(graph, graph_attribute); - BOOST_INSTALL_PROPERTY(graph, vertex_attribute); - BOOST_INSTALL_PROPERTY(graph, edge_attribute); - - - template - inline void write_attributes(const Attribute& attr, std::ostream& out) { +}; +template < class Name > inline label_writer< Name > make_label_writer(Name n) +{ + return label_writer< Name >(n); +} + +enum edge_attribute_t +{ + edge_attribute = 1111 +}; +enum vertex_attribute_t +{ + vertex_attribute = 2222 +}; +enum graph_graph_attribute_t +{ + graph_graph_attribute = 3333 +}; +enum graph_vertex_attribute_t +{ + graph_vertex_attribute = 4444 +}; +enum graph_edge_attribute_t +{ + graph_edge_attribute = 5555 +}; + +BOOST_INSTALL_PROPERTY(edge, attribute); +BOOST_INSTALL_PROPERTY(vertex, attribute); +BOOST_INSTALL_PROPERTY(graph, graph_attribute); +BOOST_INSTALL_PROPERTY(graph, vertex_attribute); +BOOST_INSTALL_PROPERTY(graph, edge_attribute); + +template < class Attribute > +inline void write_attributes(const Attribute& attr, std::ostream& out) +{ typename Attribute::const_iterator i, iend; - i = attr.begin(); + i = attr.begin(); iend = attr.end(); - while ( i != iend ) { - out << i->first << "=" << escape_dot_string(i->second); - ++i; - if ( i != iend ) - out << ", "; + while (i != iend) + { + out << i->first << "=" << escape_dot_string(i->second); + ++i; + if (i != iend) + out << ", "; } - } +} - template - inline void write_all_attributes(Attributes attributes, - const std::string& name, - std::ostream& out) - { +template < typename Attributes > +inline void write_all_attributes( + Attributes attributes, const std::string& name, std::ostream& out) +{ typename Attributes::const_iterator i = attributes.begin(), end = attributes.end(); - if (i != end) { - out << name << " [\n"; - write_attributes(attributes, out); - out << "];\n"; + if (i != end) + { + out << name << " [\n"; + write_attributes(attributes, out); + out << "];\n"; } - } +} - inline void write_all_attributes(detail::error_property_not_found, - const std::string&, - std::ostream&) - { +inline void write_all_attributes( + detail::error_property_not_found, const std::string&, std::ostream&) +{ // Do nothing - no attributes exist - } - - - +} - template - struct graph_attributes_writer - { - graph_attributes_writer(GraphGraphAttributes gg, - GraphNodeAttributes gn, - GraphEdgeAttributes ge) - : g_attributes(gg), n_attributes(gn), e_attributes(ge) { } +template < typename GraphGraphAttributes, typename GraphNodeAttributes, + typename GraphEdgeAttributes > +struct graph_attributes_writer +{ + graph_attributes_writer( + GraphGraphAttributes gg, GraphNodeAttributes gn, GraphEdgeAttributes ge) + : g_attributes(gg), n_attributes(gn), e_attributes(ge) + { + } - void operator()(std::ostream& out) const { - write_all_attributes(g_attributes, "graph", out); - write_all_attributes(n_attributes, "node", out); - write_all_attributes(e_attributes, "edge", out); + void operator()(std::ostream& out) const + { + write_all_attributes(g_attributes, "graph", out); + write_all_attributes(n_attributes, "node", out); + write_all_attributes(e_attributes, "edge", out); } GraphGraphAttributes g_attributes; GraphNodeAttributes n_attributes; GraphEdgeAttributes e_attributes; - }; - - template - graph_attributes_writer - make_graph_attributes_writer(const GAttrMap& g_attr, const NAttrMap& n_attr, - const EAttrMap& e_attr) { - return graph_attributes_writer - (g_attr, n_attr, e_attr); - } - - - template - graph_attributes_writer - ::type, - typename graph_property::type, - typename graph_property::type> - make_graph_attributes_writer(const Graph& g) - { - typedef typename graph_property::type - GAttrMap; - typedef typename graph_property::type - NAttrMap; - typedef typename graph_property::type - EAttrMap; +}; + +template < typename GAttrMap, typename NAttrMap, typename EAttrMap > +graph_attributes_writer< GAttrMap, NAttrMap, EAttrMap > +make_graph_attributes_writer( + const GAttrMap& g_attr, const NAttrMap& n_attr, const EAttrMap& e_attr) +{ + return graph_attributes_writer< GAttrMap, NAttrMap, EAttrMap >( + g_attr, n_attr, e_attr); +} + +template < typename Graph > +graph_attributes_writer< + typename graph_property< Graph, graph_graph_attribute_t >::type, + typename graph_property< Graph, graph_vertex_attribute_t >::type, + typename graph_property< Graph, graph_edge_attribute_t >::type > +make_graph_attributes_writer(const Graph& g) +{ + typedef typename graph_property< Graph, graph_graph_attribute_t >::type + GAttrMap; + typedef typename graph_property< Graph, graph_vertex_attribute_t >::type + NAttrMap; + typedef + typename graph_property< Graph, graph_edge_attribute_t >::type EAttrMap; GAttrMap gam = get_property(g, graph_graph_attribute); NAttrMap nam = get_property(g, graph_vertex_attribute); EAttrMap eam = get_property(g, graph_edge_attribute); - graph_attributes_writer writer(gam, nam, eam); + graph_attributes_writer< GAttrMap, NAttrMap, EAttrMap > writer( + gam, nam, eam); return writer; - } +} - template - struct attributes_writer { - attributes_writer(AttributeMap attr) - : attributes(attr) { } +template < typename AttributeMap > struct attributes_writer +{ + attributes_writer(AttributeMap attr) : attributes(attr) {} - template - void operator()(std::ostream& out, const VorE& e) const { - this->write_attribute(out, attributes[e]); + template < class VorE > + void operator()(std::ostream& out, const VorE& e) const + { + this->write_attribute(out, attributes[e]); } - private: - template - void write_attribute(std::ostream& out, - const AttributeSequence& seq) const - { - if (!seq.empty()) { - out << "["; - write_attributes(seq, out); - out << "]"; +private: + template < typename AttributeSequence > + void write_attribute(std::ostream& out, const AttributeSequence& seq) const + { + if (!seq.empty()) + { + out << "["; + write_attributes(seq, out); + out << "]"; } - } + } - void write_attribute(std::ostream&, - detail::error_property_not_found) const - { - } + void write_attribute(std::ostream&, detail::error_property_not_found) const + { + } AttributeMap attributes; - }; - - template - attributes_writer - ::const_type> - make_edge_attributes_writer(const Graph& g) - { - typedef typename property_map::const_type - EdgeAttributeMap; - return attributes_writer(get(edge_attribute, g)); - } - - template - attributes_writer - ::const_type> - make_vertex_attributes_writer(const Graph& g) - { - typedef typename property_map::const_type - VertexAttributeMap; - return attributes_writer(get(vertex_attribute, g)); - } - - template - inline void - write_graphviz - (std::ostream& out, const Graph& g, - VertexPropertiesWriter vpw, - EdgePropertiesWriter epw, - GraphPropertiesWriter gpw, - VertexID vertex_id - BOOST_GRAPH_ENABLE_IF_MODELS_PARM(Graph,vertex_list_graph_tag)) - { - BOOST_CONCEPT_ASSERT((EdgeListGraphConcept)); - - typedef typename graph_traits::directed_category cat_type; - typedef graphviz_io_traits Traits; +}; + +template < typename Graph > +attributes_writer< + typename property_map< Graph, edge_attribute_t >::const_type > +make_edge_attributes_writer(const Graph& g) +{ + typedef typename property_map< Graph, edge_attribute_t >::const_type + EdgeAttributeMap; + return attributes_writer< EdgeAttributeMap >(get(edge_attribute, g)); +} + +template < typename Graph > +attributes_writer< + typename property_map< Graph, vertex_attribute_t >::const_type > +make_vertex_attributes_writer(const Graph& g) +{ + typedef typename property_map< Graph, vertex_attribute_t >::const_type + VertexAttributeMap; + return attributes_writer< VertexAttributeMap >(get(vertex_attribute, g)); +} + +template < typename Graph, typename VertexPropertiesWriter, + typename EdgePropertiesWriter, typename GraphPropertiesWriter, + typename VertexID > +inline void write_graphviz(std::ostream& out, const Graph& g, + VertexPropertiesWriter vpw, EdgePropertiesWriter epw, + GraphPropertiesWriter gpw, + VertexID vertex_id BOOST_GRAPH_ENABLE_IF_MODELS_PARM( + Graph, vertex_list_graph_tag)) +{ + BOOST_CONCEPT_ASSERT((EdgeListGraphConcept< Graph >)); + + typedef typename graph_traits< Graph >::directed_category cat_type; + typedef graphviz_io_traits< cat_type > Traits; std::string name = "G"; - out << Traits::name() << " " << escape_dot_string(name) << " {" << std::endl; + out << Traits::name() << " " << escape_dot_string(name) << " {" + << std::endl; - gpw(out); //print graph properties + gpw(out); // print graph properties - typename graph_traits::vertex_iterator i, end; + typename graph_traits< Graph >::vertex_iterator i, end; - for(boost::tie(i,end) = vertices(g); i != end; ++i) { - out << escape_dot_string(get(vertex_id, *i)); - vpw(out, *i); //print vertex attributes - out << ";" << std::endl; + for (boost::tie(i, end) = vertices(g); i != end; ++i) + { + out << escape_dot_string(get(vertex_id, *i)); + vpw(out, *i); // print vertex attributes + out << ";" << std::endl; } - typename graph_traits::edge_iterator ei, edge_end; - for(boost::tie(ei, edge_end) = edges(g); ei != edge_end; ++ei) { - out << escape_dot_string(get(vertex_id, source(*ei, g))) << Traits::delimiter() << escape_dot_string(get(vertex_id, target(*ei, g))) << " "; - epw(out, *ei); //print edge attributes - out << ";" << std::endl; + typename graph_traits< Graph >::edge_iterator ei, edge_end; + for (boost::tie(ei, edge_end) = edges(g); ei != edge_end; ++ei) + { + out << escape_dot_string(get(vertex_id, source(*ei, g))) + << Traits::delimiter() + << escape_dot_string(get(vertex_id, target(*ei, g))) << " "; + epw(out, *ei); // print edge attributes + out << ";" << std::endl; } out << "}" << std::endl; - } - - template - inline void - write_graphviz(std::ostream& out, const Graph& g, - VertexPropertiesWriter vpw, - EdgePropertiesWriter epw, - GraphPropertiesWriter gpw - BOOST_GRAPH_ENABLE_IF_MODELS_PARM(Graph,vertex_list_graph_tag)) - { write_graphviz(out, g, vpw, epw, gpw, get(vertex_index, g)); } - - template - inline void - write_graphviz(std::ostream& out, const Graph& g - BOOST_GRAPH_ENABLE_IF_MODELS_PARM(Graph,vertex_list_graph_tag)) - { +} + +template < typename Graph, typename VertexPropertiesWriter, + typename EdgePropertiesWriter, typename GraphPropertiesWriter > +inline void write_graphviz(std::ostream& out, const Graph& g, + VertexPropertiesWriter vpw, EdgePropertiesWriter epw, + GraphPropertiesWriter gpw BOOST_GRAPH_ENABLE_IF_MODELS_PARM( + Graph, vertex_list_graph_tag)) +{ + write_graphviz(out, g, vpw, epw, gpw, get(vertex_index, g)); +} + +template < typename Graph > +inline void write_graphviz(std::ostream& out, + const Graph& g BOOST_GRAPH_ENABLE_IF_MODELS_PARM( + Graph, vertex_list_graph_tag)) +{ default_writer dw; default_writer gw; write_graphviz(out, g, dw, dw, gw); - } +} - template - inline void - write_graphviz(std::ostream& out, const Graph& g, VertexWriter vw - BOOST_GRAPH_ENABLE_IF_MODELS_PARM(Graph,vertex_list_graph_tag)) - { +template < typename Graph, typename VertexWriter > +inline void write_graphviz(std::ostream& out, const Graph& g, + VertexWriter vw BOOST_GRAPH_ENABLE_IF_MODELS_PARM( + Graph, vertex_list_graph_tag)) +{ default_writer dw; default_writer gw; write_graphviz(out, g, vw, dw, gw); - } - - template - inline void - write_graphviz(std::ostream& out, const Graph& g, - VertexWriter vw, EdgeWriter ew - BOOST_GRAPH_ENABLE_IF_MODELS_PARM(Graph,vertex_list_graph_tag)) - { +} + +template < typename Graph, typename VertexWriter, typename EdgeWriter > +inline void write_graphviz(std::ostream& out, const Graph& g, VertexWriter vw, + EdgeWriter ew BOOST_GRAPH_ENABLE_IF_MODELS_PARM( + Graph, vertex_list_graph_tag)) +{ default_writer gw; write_graphviz(out, g, vw, ew, gw); - } +} - namespace detail { +namespace detail +{ - template - void write_graphviz_subgraph (std::ostream& out, - const subgraph& g, - RandomAccessIterator vertex_marker, - RandomAccessIterator edge_marker, - VertexID vertex_id) + template < class Graph_, class RandomAccessIterator, class VertexID > + void write_graphviz_subgraph(std::ostream& out, const subgraph< Graph_ >& g, + RandomAccessIterator vertex_marker, RandomAccessIterator edge_marker, + VertexID vertex_id) { - typedef subgraph Graph; - typedef typename graph_traits::vertex_descriptor Vertex; - typedef typename graph_traits::directed_category cat_type; - typedef graphviz_io_traits Traits; - - typedef typename graph_property::type NameType; - const NameType& g_name = get_property(g, graph_name); + typedef subgraph< Graph_ > Graph; + typedef typename graph_traits< Graph >::vertex_descriptor Vertex; + typedef typename graph_traits< Graph >::directed_category cat_type; + typedef graphviz_io_traits< cat_type > Traits; + + typedef typename graph_property< Graph, graph_name_t >::type NameType; + const NameType& g_name = get_property(g, graph_name); + + if (g.is_root()) + out << Traits::name(); + else + out << "subgraph"; + + out << " " << escape_dot_string(g_name) << " {" << std::endl; + + typename Graph::const_children_iterator i_child, j_child; + + // print graph/node/edge attributes + make_graph_attributes_writer(g)(out); + + // print subgraph + for (boost::tie(i_child, j_child) = g.children(); i_child != j_child; + ++i_child) + write_graphviz_subgraph( + out, *i_child, vertex_marker, edge_marker, vertex_id); + + // Print out vertices and edges not in the subgraphs. + + typename graph_traits< Graph >::vertex_iterator i, end; + typename graph_traits< Graph >::edge_iterator ei, edge_end; + + for (boost::tie(i, end) = vertices(g); i != end; ++i) + { + Vertex v = g.local_to_global(*i); + int pos = get(vertex_id, v); + if (vertex_marker[pos]) + { + vertex_marker[pos] = false; + out << escape_dot_string(pos); + make_vertex_attributes_writer(g.root())(out, v); + out << ";" << std::endl; + } + } - if ( g.is_root() ) - out << Traits::name() ; - else - out << "subgraph"; + for (boost::tie(ei, edge_end) = edges(g); ei != edge_end; ++ei) + { + Vertex u = g.local_to_global(source(*ei, g)), + v = g.local_to_global(target(*ei, g)); + int pos = get(get(edge_index, g.root()), g.local_to_global(*ei)); + if (edge_marker[pos]) + { + edge_marker[pos] = false; + out << escape_dot_string(get(vertex_id, u)) << " " + << Traits::delimiter() << " " + << escape_dot_string(get(vertex_id, v)); + make_edge_attributes_writer(g)( + out, *ei); // print edge properties + out << ";" << std::endl; + } + } + out << "}" << std::endl; + } +} // namespace detail - out << " " << escape_dot_string(g_name) << " {" << std::endl; +// requires graph_name graph property +template < typename Graph > +void write_graphviz(std::ostream& out, const subgraph< Graph >& g) +{ + std::vector< bool > edge_marker(num_edges(g), true); + std::vector< bool > vertex_marker(num_vertices(g), true); - typename Graph::const_children_iterator i_child, j_child; + detail::write_graphviz_subgraph(out, g, vertex_marker.begin(), + edge_marker.begin(), get(vertex_index, g)); +} - //print graph/node/edge attributes - make_graph_attributes_writer(g)(out); +template < typename Graph > +void write_graphviz(const std::string& filename, const subgraph< Graph >& g) +{ + std::ofstream out(filename.c_str()); + std::vector< bool > edge_marker(num_edges(g), true); + std::vector< bool > vertex_marker(num_vertices(g), true); - //print subgraph - for ( boost::tie(i_child,j_child) = g.children(); - i_child != j_child; ++i_child ) - write_graphviz_subgraph(out, *i_child, vertex_marker, edge_marker, - vertex_id); + detail::write_graphviz_subgraph(out, g, vertex_marker.begin(), + edge_marker.begin(), get(vertex_index, g)); +} - // Print out vertices and edges not in the subgraphs. +template < typename Graph, typename VertexID > +void write_graphviz( + std::ostream& out, const subgraph< Graph >& g, VertexID vertex_id) +{ + std::vector< bool > edge_marker(num_edges(g), true); + std::vector< bool > vertex_marker(num_vertices(g), true); - typename graph_traits::vertex_iterator i, end; - typename graph_traits::edge_iterator ei, edge_end; + detail::write_graphviz_subgraph( + out, g, vertex_marker.begin(), edge_marker.begin(), vertex_id); +} - for(boost::tie(i,end) = vertices(g); i != end; ++i) { - Vertex v = g.local_to_global(*i); - int pos = get(vertex_id, v); - if ( vertex_marker[pos] ) { - vertex_marker[pos] = false; - out << escape_dot_string(pos); - make_vertex_attributes_writer(g.root())(out, v); - out << ";" << std::endl; - } - } - - for (boost::tie(ei, edge_end) = edges(g); ei != edge_end; ++ei) { - Vertex u = g.local_to_global(source(*ei,g)), - v = g.local_to_global(target(*ei, g)); - int pos = get(get(edge_index, g.root()), g.local_to_global(*ei)); - if ( edge_marker[pos] ) { - edge_marker[pos] = false; - out << escape_dot_string(get(vertex_id, u)) << " " << Traits::delimiter() - << " " << escape_dot_string(get(vertex_id, v)); - make_edge_attributes_writer(g)(out, *ei); //print edge properties - out << ";" << std::endl; - } - } - out << "}" << std::endl; - } - } // namespace detail - - // requires graph_name graph property - template - void write_graphviz(std::ostream& out, const subgraph& g) { - std::vector edge_marker(num_edges(g), true); - std::vector vertex_marker(num_vertices(g), true); - - detail::write_graphviz_subgraph(out, g, - vertex_marker.begin(), - edge_marker.begin(), - get(vertex_index, g)); - } - - template - void write_graphviz(const std::string& filename, const subgraph& g) { - std::ofstream out(filename.c_str()); - std::vector edge_marker(num_edges(g), true); - std::vector vertex_marker(num_vertices(g), true); - - detail::write_graphviz_subgraph(out, g, - vertex_marker.begin(), - edge_marker.begin(), - get(vertex_index, g)); - } - - template - void write_graphviz(std::ostream& out, const subgraph& g, - VertexID vertex_id) - { - std::vector edge_marker(num_edges(g), true); - std::vector vertex_marker(num_vertices(g), true); - - detail::write_graphviz_subgraph(out, g, - vertex_marker.begin(), - edge_marker.begin(), - vertex_id); - } - - template - void write_graphviz(const std::string& filename, const subgraph& g, - VertexID vertex_id) - { +template < typename Graph, typename VertexID > +void write_graphviz( + const std::string& filename, const subgraph< Graph >& g, VertexID vertex_id) +{ std::ofstream out(filename.c_str()); - std::vector edge_marker(num_edges(g), true); - std::vector vertex_marker(num_vertices(g), true); + std::vector< bool > edge_marker(num_edges(g), true); + std::vector< bool > vertex_marker(num_vertices(g), true); - detail::write_graphviz_subgraph(out, g, - vertex_marker.begin(), - edge_marker.begin(), - vertex_id); - } + detail::write_graphviz_subgraph( + out, g, vertex_marker.begin(), edge_marker.begin(), vertex_id); +} #if 0 // This interface has not worked for a long time @@ -474,484 +484,547 @@ namespace boost { // Library has not existed for a while extern void read_graphviz(const std::string& file, GraphvizDigraph& g); extern void read_graphviz(FILE* file, GraphvizDigraph& g); - + extern void read_graphviz(const std::string& file, GraphvizGraph& g); extern void read_graphviz(FILE* file, GraphvizGraph& g); #endif - class dynamic_properties_writer - { - public: - dynamic_properties_writer(const dynamic_properties& dp) : dp(&dp) { } +class dynamic_properties_writer +{ +public: + dynamic_properties_writer(const dynamic_properties& dp) : dp(&dp) {} - template + template < typename Descriptor > void operator()(std::ostream& out, Descriptor key) const { - bool first = true; - for (dynamic_properties::const_iterator i = dp->begin(); - i != dp->end(); ++i) { - if (typeid(key) == i->second->key()) { - if (first) out << " ["; - else out << ", "; - first = false; - - out << i->first << "=" << escape_dot_string(i->second->get_string(key)); + bool first = true; + for (dynamic_properties::const_iterator i = dp->begin(); i != dp->end(); + ++i) + { + if (typeid(key) == i->second->key()) + { + if (first) + out << " ["; + else + out << ", "; + first = false; + + out << i->first << "=" + << escape_dot_string(i->second->get_string(key)); + } } - } - if (!first) out << "]"; + if (!first) + out << "]"; } - private: +private: const dynamic_properties* dp; - }; +}; - class dynamic_vertex_properties_writer - { - public: - dynamic_vertex_properties_writer(const dynamic_properties& dp, - const std::string& node_id) - : dp(&dp), node_id(&node_id) { } +class dynamic_vertex_properties_writer +{ +public: + dynamic_vertex_properties_writer( + const dynamic_properties& dp, const std::string& node_id) + : dp(&dp), node_id(&node_id) + { + } - template + template < typename Descriptor > void operator()(std::ostream& out, Descriptor key) const { - bool first = true; - for (dynamic_properties::const_iterator i = dp->begin(); - i != dp->end(); ++i) { - if (typeid(key) == i->second->key() - && i->first != *node_id) { - if (first) out << " ["; - else out << ", "; - first = false; - - out << i->first << "=" << escape_dot_string(i->second->get_string(key)); + bool first = true; + for (dynamic_properties::const_iterator i = dp->begin(); i != dp->end(); + ++i) + { + if (typeid(key) == i->second->key() && i->first != *node_id) + { + if (first) + out << " ["; + else + out << ", "; + first = false; + + out << i->first << "=" + << escape_dot_string(i->second->get_string(key)); + } } - } - if (!first) out << "]"; + if (!first) + out << "]"; } - private: +private: const dynamic_properties* dp; const std::string* node_id; - }; +}; - template - class dynamic_graph_properties_writer - { - public: - dynamic_graph_properties_writer(const dynamic_properties& dp, const Graph& g) : g(&g), dp(&dp) { } +template < typename Graph > class dynamic_graph_properties_writer +{ +public: + dynamic_graph_properties_writer( + const dynamic_properties& dp, const Graph& g) + : g(&g), dp(&dp) + { + } void operator()(std::ostream& out) const { - for (dynamic_properties::const_iterator i = dp->begin(); - i != dp->end(); ++i) { - if (typeid(Graph*) == i->second->key()) { - // const_cast here is to match interface used in read_graphviz - out << i->first << "=" << escape_dot_string(i->second->get_string(const_cast(g))) << ";\n"; + for (dynamic_properties::const_iterator i = dp->begin(); i != dp->end(); + ++i) + { + if (typeid(Graph*) == i->second->key()) + { + // const_cast here is to match interface used in read_graphviz + out << i->first << "=" + << escape_dot_string( + i->second->get_string(const_cast< Graph* >(g))) + << ";\n"; + } } - } } - private: +private: const Graph* g; const dynamic_properties* dp; - }; - - namespace graph { namespace detail { +}; - template - struct node_id_property_map +namespace graph +{ + namespace detail { - typedef std::string value_type; - typedef value_type reference; - typedef Vertex key_type; - typedef readable_property_map_tag category; - - node_id_property_map() {} - - node_id_property_map(const dynamic_properties& dp, - const std::string& node_id) - : dp(&dp), node_id(&node_id) { } - - const dynamic_properties* dp; - const std::string* node_id; - }; - - template - inline std::string - get(node_id_property_map pm, - typename node_id_property_map::key_type v) - { return get(*pm.node_id, *pm.dp, v); } - - } } // end namespace graph::detail - - template - inline void - write_graphviz_dp(std::ostream& out, const Graph& g, - const dynamic_properties& dp, - const std::string& node_id = "node_id" - BOOST_GRAPH_ENABLE_IF_MODELS_PARM(Graph,vertex_list_graph_tag)) - { - typedef typename graph_traits::vertex_descriptor Vertex; + + template < typename Vertex > struct node_id_property_map + { + typedef std::string value_type; + typedef value_type reference; + typedef Vertex key_type; + typedef readable_property_map_tag category; + + node_id_property_map() {} + + node_id_property_map( + const dynamic_properties& dp, const std::string& node_id) + : dp(&dp), node_id(&node_id) + { + } + + const dynamic_properties* dp; + const std::string* node_id; + }; + + template < typename Vertex > + inline std::string get(node_id_property_map< Vertex > pm, + typename node_id_property_map< Vertex >::key_type v) + { + return get(*pm.node_id, *pm.dp, v); + } + + } +} // end namespace graph::detail + +template < typename Graph > +inline void write_graphviz_dp(std::ostream& out, const Graph& g, + const dynamic_properties& dp, + const std::string& node_id + = "node_id" BOOST_GRAPH_ENABLE_IF_MODELS_PARM(Graph, vertex_list_graph_tag)) +{ + typedef typename graph_traits< Graph >::vertex_descriptor Vertex; write_graphviz_dp(out, g, dp, node_id, - graph::detail::node_id_property_map(dp, node_id)); - } - - template - void - write_graphviz_dp(std::ostream& out, const Graph& g, - const dynamic_properties& dp, const std::string& node_id, - VertexID id - BOOST_GRAPH_ENABLE_IF_MODELS_PARM(Graph,vertex_list_graph_tag)) - { - write_graphviz - (out, g, - /*vertex_writer=*/dynamic_vertex_properties_writer(dp, node_id), - /*edge_writer=*/dynamic_properties_writer(dp), - /*graph_writer=*/dynamic_graph_properties_writer(dp, g), - id); - } + graph::detail::node_id_property_map< Vertex >(dp, node_id)); +} + +template < typename Graph, typename VertexID > +void write_graphviz_dp(std::ostream& out, const Graph& g, + const dynamic_properties& dp, const std::string& node_id, + VertexID id BOOST_GRAPH_ENABLE_IF_MODELS_PARM(Graph, vertex_list_graph_tag)) +{ + write_graphviz(out, g, + /*vertex_writer=*/dynamic_vertex_properties_writer(dp, node_id), + /*edge_writer=*/dynamic_properties_writer(dp), + /*graph_writer=*/dynamic_graph_properties_writer< Graph >(dp, g), id); +} ///////////////////////////////////////////////////////////////////////////// // Graph reader exceptions ///////////////////////////////////////////////////////////////////////////// -struct BOOST_SYMBOL_VISIBLE graph_exception : public std::exception { - virtual ~graph_exception() throw() {} - virtual const char* what() const throw() = 0; +struct BOOST_SYMBOL_VISIBLE graph_exception : public std::exception +{ + virtual ~graph_exception() throw() {} + virtual const char* what() const throw() = 0; }; -struct BOOST_SYMBOL_VISIBLE bad_parallel_edge : public graph_exception { - std::string from; - std::string to; - mutable std::string statement; - bad_parallel_edge(const std::string& i, const std::string& j) : - from(i), to(j) {} - - virtual ~bad_parallel_edge() throw() {} - const char* what() const throw() { - if(statement.empty()) - statement = - std::string("Failed to add parallel edge: (") - + from + "," + to + ")\n"; - - return statement.c_str(); - } -}; +struct BOOST_SYMBOL_VISIBLE bad_parallel_edge : public graph_exception +{ + std::string from; + std::string to; + mutable std::string statement; + bad_parallel_edge(const std::string& i, const std::string& j) + : from(i), to(j) + { + } -struct BOOST_SYMBOL_VISIBLE directed_graph_error : public graph_exception { - virtual ~directed_graph_error() throw() {} - virtual const char* what() const throw() { - return - "read_graphviz: " - "Tried to read a directed graph into an undirected graph."; - } -}; + virtual ~bad_parallel_edge() throw() {} + const char* what() const throw() + { + if (statement.empty()) + statement = std::string("Failed to add parallel edge: (") + from + + "," + to + ")\n"; -struct BOOST_SYMBOL_VISIBLE undirected_graph_error : public graph_exception { - virtual ~undirected_graph_error() throw() {} - virtual const char* what() const throw() { - return - "read_graphviz: " - "Tried to read an undirected graph into a directed graph."; - } + return statement.c_str(); + } }; -struct BOOST_SYMBOL_VISIBLE bad_graphviz_syntax: public graph_exception { - std::string errmsg; - bad_graphviz_syntax(const std::string& errmsg) - : errmsg(errmsg) {} - const char* what() const throw () {return errmsg.c_str();} - ~bad_graphviz_syntax() throw () {}; +struct BOOST_SYMBOL_VISIBLE directed_graph_error : public graph_exception +{ + virtual ~directed_graph_error() throw() {} + virtual const char* what() const throw() + { + return "read_graphviz: " + "Tried to read a directed graph into an undirected graph."; + } }; -namespace detail { namespace graph { - -typedef std::string id_t; -typedef id_t node_t; - -// edges are not uniquely determined by adjacent nodes -class edge_t { - int idx_; - explicit edge_t(int i) : idx_(i) {} -public: - static edge_t new_edge() { - static int idx = 0; - return edge_t(idx++); - }; - - bool operator==(const edge_t& rhs) const { - return idx_ == rhs.idx_; - } - bool operator<(const edge_t& rhs) const { - return idx_ < rhs.idx_; - } +struct BOOST_SYMBOL_VISIBLE undirected_graph_error : public graph_exception +{ + virtual ~undirected_graph_error() throw() {} + virtual const char* what() const throw() + { + return "read_graphviz: " + "Tried to read an undirected graph into a directed graph."; + } }; -class mutate_graph +struct BOOST_SYMBOL_VISIBLE bad_graphviz_syntax : public graph_exception { - public: - virtual ~mutate_graph() {} - virtual bool is_directed() const = 0; - virtual void do_add_vertex(const node_t& node) = 0; - - virtual void - do_add_edge(const edge_t& edge, const node_t& source, const node_t& target) - = 0; - - virtual void - set_node_property(const id_t& key, const node_t& node, const id_t& value) = 0; - - virtual void - set_edge_property(const id_t& key, const edge_t& edge, const id_t& value) = 0; - - virtual void // RG: need new second parameter to support BGL subgraphs - set_graph_property(const id_t& key, const id_t& value) = 0; - - virtual void - finish_building_graph() = 0; + std::string errmsg; + bad_graphviz_syntax(const std::string& errmsg) : errmsg(errmsg) {} + const char* what() const throw() { return errmsg.c_str(); } + ~bad_graphviz_syntax() throw() {}; }; -template -class mutate_graph_impl : public mutate_graph -{ - typedef typename graph_traits::vertex_descriptor bgl_vertex_t; - typedef typename graph_traits::edge_descriptor bgl_edge_t; - - public: - mutate_graph_impl(MutableGraph& graph, dynamic_properties& dp, - std::string node_id_prop) - : graph_(graph), dp_(dp), node_id_prop_(node_id_prop) { } - - ~mutate_graph_impl() {} - - bool is_directed() const - { - return - boost::is_convertible< - typename boost::graph_traits::directed_category, - boost::directed_tag>::value; - } - - virtual void do_add_vertex(const node_t& node) - { - // Add the node to the graph. - bgl_vertex_t v = add_vertex(graph_); - - // Set up a mapping from name to BGL vertex. - bgl_nodes.insert(std::make_pair(node, v)); - - // node_id_prop_ allows the caller to see the real id names for nodes. - put(node_id_prop_, dp_, v, node); - } - - void - do_add_edge(const edge_t& edge, const node_t& source, const node_t& target) - { - std::pair result = - add_edge(bgl_nodes[source], bgl_nodes[target], graph_); - - if(!result.second) { - // In the case of no parallel edges allowed - boost::throw_exception(bad_parallel_edge(source, target)); - } else { - bgl_edges.insert(std::make_pair(edge, result.first)); - } - } - - void - set_node_property(const id_t& key, const node_t& node, const id_t& value) - { - put(key, dp_, bgl_nodes[node], value); - } - - void - set_edge_property(const id_t& key, const edge_t& edge, const id_t& value) - { - put(key, dp_, bgl_edges[edge], value); - } - - void - set_graph_property(const id_t& key, const id_t& value) - { - /* RG: pointer to graph prevents copying */ - put(key, dp_, &graph_, value); - } - - void finish_building_graph() {} - - - protected: - MutableGraph& graph_; - dynamic_properties& dp_; - std::string node_id_prop_; - std::map bgl_nodes; - std::map bgl_edges; -}; +namespace detail +{ + namespace graph + { -template -class mutate_graph_impl > - : public mutate_graph -{ - typedef compressed_sparse_row_graph CSRGraph; - typedef typename graph_traits::vertices_size_type bgl_vertex_t; - typedef typename graph_traits::edges_size_type bgl_edge_t; - typedef typename graph_traits::edge_descriptor edge_descriptor; - - public: - mutate_graph_impl(CSRGraph& graph, dynamic_properties& dp, - std::string node_id_prop) - : graph_(graph), dp_(dp), vertex_count(0), node_id_prop_(node_id_prop) { } - - ~mutate_graph_impl() {} - - void finish_building_graph() { - typedef compressed_sparse_row_graph TempCSRGraph; - TempCSRGraph temp(edges_are_unsorted_multi_pass, - edges_to_add.begin(), edges_to_add.end(), - counting_iterator(0), - vertex_count); - set_property(temp, graph_all, get_property(graph_, graph_all)); - graph_.assign(temp); // Copies structure, not properties - std::vector edge_permutation_from_sorting(num_edges(temp)); - BGL_FORALL_EDGES_T(e, temp, TempCSRGraph) { - edge_permutation_from_sorting[temp[e]] = e; - } - typedef boost::tuple v_prop; - BOOST_FOREACH(const v_prop& t, vertex_props) { - put(boost::get<0>(t), dp_, boost::get<1>(t), boost::get<2>(t)); - } - typedef boost::tuple e_prop; - BOOST_FOREACH(const e_prop& t, edge_props) { - put(boost::get<0>(t), dp_, edge_permutation_from_sorting[boost::get<1>(t)], boost::get<2>(t)); - } - } - - bool is_directed() const - { - return - boost::is_convertible< - typename boost::graph_traits::directed_category, - boost::directed_tag>::value; - } - - virtual void do_add_vertex(const node_t& node) - { - // Add the node to the graph. - bgl_vertex_t v = vertex_count++; - - // Set up a mapping from name to BGL vertex. - bgl_nodes.insert(std::make_pair(node, v)); - - // node_id_prop_ allows the caller to see the real id names for nodes. - vertex_props.push_back(boost::make_tuple(node_id_prop_, v, node)); - } - - void - do_add_edge(const edge_t& edge, const node_t& source, const node_t& target) - { - bgl_edge_t result = edges_to_add.size(); - edges_to_add.push_back(std::make_pair(bgl_nodes[source], bgl_nodes[target])); - bgl_edges.insert(std::make_pair(edge, result)); - } - - void - set_node_property(const id_t& key, const node_t& node, const id_t& value) - { - vertex_props.push_back(boost::make_tuple(key, bgl_nodes[node], value)); - } - - void - set_edge_property(const id_t& key, const edge_t& edge, const id_t& value) - { - edge_props.push_back(boost::make_tuple(key, bgl_edges[edge], value)); - } - - void - set_graph_property(const id_t& key, const id_t& value) - { - /* RG: pointer to graph prevents copying */ - put(key, dp_, &graph_, value); - } - - - protected: - CSRGraph& graph_; - dynamic_properties& dp_; - bgl_vertex_t vertex_count; - std::string node_id_prop_; - std::vector > vertex_props; - std::vector > edge_props; - std::vector > edges_to_add; - std::map bgl_nodes; - std::map bgl_edges; -}; + typedef std::string id_t; + typedef id_t node_t; + + // edges are not uniquely determined by adjacent nodes + class edge_t + { + int idx_; + explicit edge_t(int i) : idx_(i) {} + + public: + static edge_t new_edge() + { + static int idx = 0; + return edge_t(idx++); + }; + + bool operator==(const edge_t& rhs) const + { + return idx_ == rhs.idx_; + } + bool operator<(const edge_t& rhs) const { return idx_ < rhs.idx_; } + }; + + class mutate_graph + { + public: + virtual ~mutate_graph() {} + virtual bool is_directed() const = 0; + virtual void do_add_vertex(const node_t& node) = 0; + + virtual void do_add_edge( + const edge_t& edge, const node_t& source, const node_t& target) + = 0; + + virtual void set_node_property( + const id_t& key, const node_t& node, const id_t& value) + = 0; + + virtual void set_edge_property( + const id_t& key, const edge_t& edge, const id_t& value) + = 0; + + virtual void // RG: need new second parameter to support BGL + // subgraphs + set_graph_property(const id_t& key, const id_t& value) + = 0; + + virtual void finish_building_graph() = 0; + }; + + template < typename MutableGraph > + class mutate_graph_impl : public mutate_graph + { + typedef typename graph_traits< MutableGraph >::vertex_descriptor + bgl_vertex_t; + typedef typename graph_traits< MutableGraph >::edge_descriptor + bgl_edge_t; + + public: + mutate_graph_impl(MutableGraph& graph, dynamic_properties& dp, + std::string node_id_prop) + : graph_(graph), dp_(dp), node_id_prop_(node_id_prop) + { + } + + ~mutate_graph_impl() {} + + bool is_directed() const + { + return boost::is_convertible< + typename boost::graph_traits< + MutableGraph >::directed_category, + boost::directed_tag >::value; + } + + virtual void do_add_vertex(const node_t& node) + { + // Add the node to the graph. + bgl_vertex_t v = add_vertex(graph_); + + // Set up a mapping from name to BGL vertex. + bgl_nodes.insert(std::make_pair(node, v)); + + // node_id_prop_ allows the caller to see the real id names for + // nodes. + put(node_id_prop_, dp_, v, node); + } + + void do_add_edge( + const edge_t& edge, const node_t& source, const node_t& target) + { + std::pair< bgl_edge_t, bool > result + = add_edge(bgl_nodes[source], bgl_nodes[target], graph_); + + if (!result.second) + { + // In the case of no parallel edges allowed + boost::throw_exception(bad_parallel_edge(source, target)); + } + else + { + bgl_edges.insert(std::make_pair(edge, result.first)); + } + } + + void set_node_property( + const id_t& key, const node_t& node, const id_t& value) + { + put(key, dp_, bgl_nodes[node], value); + } + + void set_edge_property( + const id_t& key, const edge_t& edge, const id_t& value) + { + put(key, dp_, bgl_edges[edge], value); + } + + void set_graph_property(const id_t& key, const id_t& value) + { + /* RG: pointer to graph prevents copying */ + put(key, dp_, &graph_, value); + } + + void finish_building_graph() {} + + protected: + MutableGraph& graph_; + dynamic_properties& dp_; + std::string node_id_prop_; + std::map< node_t, bgl_vertex_t > bgl_nodes; + std::map< edge_t, bgl_edge_t > bgl_edges; + }; + + template < typename Directed, typename VertexProperty, + typename EdgeProperty, typename GraphProperty, typename Vertex, + typename EdgeIndex > + class mutate_graph_impl< compressed_sparse_row_graph< Directed, + VertexProperty, EdgeProperty, GraphProperty, Vertex, EdgeIndex > > + : public mutate_graph + { + typedef compressed_sparse_row_graph< Directed, VertexProperty, + EdgeProperty, GraphProperty, Vertex, EdgeIndex > + CSRGraph; + typedef typename graph_traits< CSRGraph >::vertices_size_type + bgl_vertex_t; + typedef + typename graph_traits< CSRGraph >::edges_size_type bgl_edge_t; + typedef typename graph_traits< CSRGraph >::edge_descriptor + edge_descriptor; + + public: + mutate_graph_impl(CSRGraph& graph, dynamic_properties& dp, + std::string node_id_prop) + : graph_(graph) + , dp_(dp) + , vertex_count(0) + , node_id_prop_(node_id_prop) + { + } + + ~mutate_graph_impl() {} + + void finish_building_graph() + { + typedef compressed_sparse_row_graph< directedS, no_property, + bgl_edge_t, GraphProperty, Vertex, EdgeIndex > + TempCSRGraph; + TempCSRGraph temp(edges_are_unsorted_multi_pass, + edges_to_add.begin(), edges_to_add.end(), + counting_iterator< bgl_edge_t >(0), vertex_count); + set_property(temp, graph_all, get_property(graph_, graph_all)); + graph_.assign(temp); // Copies structure, not properties + std::vector< edge_descriptor > edge_permutation_from_sorting( + num_edges(temp)); + BGL_FORALL_EDGES_T(e, temp, TempCSRGraph) + { + edge_permutation_from_sorting[temp[e]] = e; + } + typedef boost::tuple< id_t, bgl_vertex_t, id_t > v_prop; + BOOST_FOREACH (const v_prop& t, vertex_props) + { + put(boost::get< 0 >(t), dp_, boost::get< 1 >(t), + boost::get< 2 >(t)); + } + typedef boost::tuple< id_t, bgl_edge_t, id_t > e_prop; + BOOST_FOREACH (const e_prop& t, edge_props) + { + put(boost::get< 0 >(t), dp_, + edge_permutation_from_sorting[boost::get< 1 >(t)], + boost::get< 2 >(t)); + } + } + + bool is_directed() const + { + return boost::is_convertible< + typename boost::graph_traits< CSRGraph >::directed_category, + boost::directed_tag >::value; + } + + virtual void do_add_vertex(const node_t& node) + { + // Add the node to the graph. + bgl_vertex_t v = vertex_count++; + + // Set up a mapping from name to BGL vertex. + bgl_nodes.insert(std::make_pair(node, v)); + + // node_id_prop_ allows the caller to see the real id names for + // nodes. + vertex_props.push_back( + boost::make_tuple(node_id_prop_, v, node)); + } + + void do_add_edge( + const edge_t& edge, const node_t& source, const node_t& target) + { + bgl_edge_t result = edges_to_add.size(); + edges_to_add.push_back( + std::make_pair(bgl_nodes[source], bgl_nodes[target])); + bgl_edges.insert(std::make_pair(edge, result)); + } + + void set_node_property( + const id_t& key, const node_t& node, const id_t& value) + { + vertex_props.push_back( + boost::make_tuple(key, bgl_nodes[node], value)); + } + + void set_edge_property( + const id_t& key, const edge_t& edge, const id_t& value) + { + edge_props.push_back( + boost::make_tuple(key, bgl_edges[edge], value)); + } + + void set_graph_property(const id_t& key, const id_t& value) + { + /* RG: pointer to graph prevents copying */ + put(key, dp_, &graph_, value); + } + + protected: + CSRGraph& graph_; + dynamic_properties& dp_; + bgl_vertex_t vertex_count; + std::string node_id_prop_; + std::vector< boost::tuple< id_t, bgl_vertex_t, id_t > > + vertex_props; + std::vector< boost::tuple< id_t, bgl_edge_t, id_t > > edge_props; + std::vector< std::pair< bgl_vertex_t, bgl_vertex_t > > edges_to_add; + std::map< node_t, bgl_vertex_t > bgl_nodes; + std::map< edge_t, bgl_edge_t > bgl_edges; + }; -} } } // end namespace boost::detail::graph + } +} +} // end namespace boost::detail::graph #ifdef BOOST_GRAPH_USE_SPIRIT_PARSER -# ifndef BOOST_GRAPH_READ_GRAPHVIZ_ITERATORS -# define BOOST_GRAPH_READ_GRAPHVIZ_ITERATORS -# endif -# include +#ifndef BOOST_GRAPH_READ_GRAPHVIZ_ITERATORS +#define BOOST_GRAPH_READ_GRAPHVIZ_ITERATORS +#endif +#include #else // New default parser -# include +#include #endif // BOOST_GRAPH_USE_SPIRIT_PARSER -namespace boost { +namespace boost +{ // Parse the passed string as a GraphViz dot file. -template -bool read_graphviz(const std::string& data, - MutableGraph& graph, - dynamic_properties& dp, - std::string const& node_id = "node_id") { +template < typename MutableGraph > +bool read_graphviz(const std::string& data, MutableGraph& graph, + dynamic_properties& dp, std::string const& node_id = "node_id") +{ #ifdef BOOST_GRAPH_USE_SPIRIT_PARSER - return read_graphviz_spirit(data.begin(), data.end(), graph, dp, node_id); + return read_graphviz_spirit(data.begin(), data.end(), graph, dp, node_id); #else // Non-Spirit parser - return read_graphviz_new(data,graph,dp,node_id); + return read_graphviz_new(data, graph, dp, node_id); #endif } // Parse the passed iterator range as a GraphViz dot file. -template -bool read_graphviz(InputIterator user_first, - InputIterator user_last, - MutableGraph& graph, - dynamic_properties& dp, - std::string const& node_id = "node_id") { +template < typename InputIterator, typename MutableGraph > +bool read_graphviz(InputIterator user_first, InputIterator user_last, + MutableGraph& graph, dynamic_properties& dp, + std::string const& node_id = "node_id") +{ #ifdef BOOST_GRAPH_USE_SPIRIT_PARSER - typedef InputIterator is_t; - typedef boost::spirit::classic::multi_pass iterator_t; + typedef InputIterator is_t; + typedef boost::spirit::classic::multi_pass< is_t > iterator_t; - iterator_t first(boost::spirit::classic::make_multi_pass(user_first)); - iterator_t last(boost::spirit::classic::make_multi_pass(user_last)); + iterator_t first(boost::spirit::classic::make_multi_pass(user_first)); + iterator_t last(boost::spirit::classic::make_multi_pass(user_last)); - return read_graphviz_spirit(first, last, graph, dp, node_id); + return read_graphviz_spirit(first, last, graph, dp, node_id); #else // Non-Spirit parser - return read_graphviz_new(std::string(user_first, user_last), graph, dp, node_id); + return read_graphviz_new( + std::string(user_first, user_last), graph, dp, node_id); #endif } // Parse the passed stream as a GraphViz dot file. -template +template < typename MutableGraph > bool read_graphviz(std::istream& in, MutableGraph& graph, - dynamic_properties& dp, - std::string const& node_id = "node_id") + dynamic_properties& dp, std::string const& node_id = "node_id") { - typedef std::istream_iterator is_t; - in >> std::noskipws; - return read_graphviz(is_t(in), is_t(), graph, dp, node_id); + typedef std::istream_iterator< char > is_t; + in >> std::noskipws; + return read_graphviz(is_t(in), is_t(), graph, dp, node_id); } } // namespace boost -#include BOOST_GRAPH_MPI_INCLUDE() +#include BOOST_GRAPH_MPI_INCLUDE(< boost / graph / distributed / graphviz.hpp >) #endif // BOOST_GRAPHVIZ_HPP diff --git a/include/boost/graph/grid_graph.hpp b/include/boost/graph/grid_graph.hpp index 9a09fca34..fa2fa69d6 100644 --- a/include/boost/graph/grid_graph.hpp +++ b/include/boost/graph/grid_graph.hpp @@ -24,250 +24,264 @@ #include #define BOOST_GRID_GRAPH_TEMPLATE_PARAMS \ - std::size_t DimensionsT, typename VertexIndexT, \ - typename EdgeIndexT + std::size_t DimensionsT, typename VertexIndexT, typename EdgeIndexT #define BOOST_GRID_GRAPH_TYPE \ - grid_graph + grid_graph< DimensionsT, VertexIndexT, EdgeIndexT > -#define BOOST_GRID_GRAPH_TRAITS_T \ - typename graph_traits +#define BOOST_GRID_GRAPH_TRAITS_T typename graph_traits< BOOST_GRID_GRAPH_TYPE > -namespace boost { +namespace boost +{ - // Class prototype for grid_graph - template - class grid_graph; +// Class prototype for grid_graph +template < BOOST_GRID_GRAPH_TEMPLATE_PARAMS > class grid_graph; - //=================== - // Index Property Map - //=================== +//=================== +// Index Property Map +//=================== - template - struct grid_graph_index_map { - public: +template < typename Graph, typename Descriptor, typename Index > +struct grid_graph_index_map +{ +public: typedef Index value_type; typedef Index reference_type; typedef reference_type reference; typedef Descriptor key_type; typedef readable_property_map_tag category; - grid_graph_index_map() { } + grid_graph_index_map() {} - grid_graph_index_map(const Graph& graph) : - m_graph(&graph) { } + grid_graph_index_map(const Graph& graph) : m_graph(&graph) {} - value_type operator[](key_type key) const { - return (m_graph->index_of(key)); + value_type operator[](key_type key) const + { + return (m_graph->index_of(key)); } - friend inline Index - get(const grid_graph_index_map& index_map, - const typename grid_graph_index_map::key_type& key) + friend inline Index get( + const grid_graph_index_map< Graph, Descriptor, Index >& index_map, + const typename grid_graph_index_map< Graph, Descriptor, + Index >::key_type& key) { - return (index_map[key]); + return (index_map[key]); } - protected: +protected: const Graph* m_graph; - }; - - template - struct property_map { - typedef grid_graph_index_map type; +}; + +template < BOOST_GRID_GRAPH_TEMPLATE_PARAMS > +struct property_map< BOOST_GRID_GRAPH_TYPE, vertex_index_t > +{ + typedef grid_graph_index_map< BOOST_GRID_GRAPH_TYPE, + BOOST_GRID_GRAPH_TRAITS_T::vertex_descriptor, + BOOST_GRID_GRAPH_TRAITS_T::vertices_size_type > + type; typedef type const_type; - }; - - template - struct property_map { - typedef grid_graph_index_map type; +}; + +template < BOOST_GRID_GRAPH_TEMPLATE_PARAMS > +struct property_map< BOOST_GRID_GRAPH_TYPE, edge_index_t > +{ + typedef grid_graph_index_map< BOOST_GRID_GRAPH_TYPE, + BOOST_GRID_GRAPH_TRAITS_T::edge_descriptor, + BOOST_GRID_GRAPH_TRAITS_T::edges_size_type > + type; typedef type const_type; - }; +}; - //========================== - // Reverse Edge Property Map - //========================== +//========================== +// Reverse Edge Property Map +//========================== - template - struct grid_graph_reverse_edge_map { - public: +template < typename Descriptor > struct grid_graph_reverse_edge_map +{ +public: typedef Descriptor value_type; typedef Descriptor reference_type; typedef reference_type reference; typedef Descriptor key_type; typedef readable_property_map_tag category; - grid_graph_reverse_edge_map() { } + grid_graph_reverse_edge_map() {} - value_type operator[](const key_type& key) const { - return (value_type(key.second, key.first)); + value_type operator[](const key_type& key) const + { + return (value_type(key.second, key.first)); } - friend inline Descriptor - get(const grid_graph_reverse_edge_map& rev_map, - const typename grid_graph_reverse_edge_map::key_type& key) + friend inline Descriptor get( + const grid_graph_reverse_edge_map< Descriptor >& rev_map, + const typename grid_graph_reverse_edge_map< Descriptor >::key_type& key) { - return (rev_map[key]); + return (rev_map[key]); } - }; - - template - struct property_map { - typedef grid_graph_reverse_edge_map type; +}; + +template < BOOST_GRID_GRAPH_TEMPLATE_PARAMS > +struct property_map< BOOST_GRID_GRAPH_TYPE, edge_reverse_t > +{ + typedef grid_graph_reverse_edge_map< + BOOST_GRID_GRAPH_TRAITS_T::edge_descriptor > + type; typedef type const_type; - }; +}; - //================= - // Function Objects - //================= +//================= +// Function Objects +//================= - namespace detail { +namespace detail +{ // vertex_at - template - struct grid_graph_vertex_at { + template < typename Graph > struct grid_graph_vertex_at + { - typedef typename graph_traits::vertex_descriptor result_type; + typedef typename graph_traits< Graph >::vertex_descriptor result_type; - grid_graph_vertex_at() : m_graph(0) {} + grid_graph_vertex_at() : m_graph(0) {} - grid_graph_vertex_at(const Graph* graph) : - m_graph(graph) { } + grid_graph_vertex_at(const Graph* graph) : m_graph(graph) {} - result_type - operator() - (typename graph_traits::vertices_size_type vertex_index) const { - return (vertex(vertex_index, *m_graph)); - } + result_type operator()( + typename graph_traits< Graph >::vertices_size_type vertex_index) + const + { + return (vertex(vertex_index, *m_graph)); + } private: - const Graph* m_graph; + const Graph* m_graph; }; // out_edge_at - template - struct grid_graph_out_edge_at { + template < typename Graph > struct grid_graph_out_edge_at + { private: - typedef typename graph_traits::vertex_descriptor vertex_descriptor; + typedef + typename graph_traits< Graph >::vertex_descriptor vertex_descriptor; public: - typedef typename graph_traits::edge_descriptor result_type; + typedef typename graph_traits< Graph >::edge_descriptor result_type; - grid_graph_out_edge_at() : m_vertex(), m_graph(0) {} + grid_graph_out_edge_at() : m_vertex(), m_graph(0) {} - grid_graph_out_edge_at(vertex_descriptor source_vertex, - const Graph* graph) : - m_vertex(source_vertex), - m_graph(graph) { } + grid_graph_out_edge_at( + vertex_descriptor source_vertex, const Graph* graph) + : m_vertex(source_vertex), m_graph(graph) + { + } - result_type - operator() - (typename graph_traits::degree_size_type out_edge_index) const { - return (out_edge_at(m_vertex, out_edge_index, *m_graph)); - } + result_type operator()( + typename graph_traits< Graph >::degree_size_type out_edge_index) + const + { + return (out_edge_at(m_vertex, out_edge_index, *m_graph)); + } private: - vertex_descriptor m_vertex; - const Graph* m_graph; + vertex_descriptor m_vertex; + const Graph* m_graph; }; // in_edge_at - template - struct grid_graph_in_edge_at { + template < typename Graph > struct grid_graph_in_edge_at + { private: - typedef typename graph_traits::vertex_descriptor vertex_descriptor; + typedef + typename graph_traits< Graph >::vertex_descriptor vertex_descriptor; public: - typedef typename graph_traits::edge_descriptor result_type; + typedef typename graph_traits< Graph >::edge_descriptor result_type; - grid_graph_in_edge_at() : m_vertex(), m_graph(0) {} + grid_graph_in_edge_at() : m_vertex(), m_graph(0) {} - grid_graph_in_edge_at(vertex_descriptor target_vertex, - const Graph* graph) : - m_vertex(target_vertex), - m_graph(graph) { } + grid_graph_in_edge_at( + vertex_descriptor target_vertex, const Graph* graph) + : m_vertex(target_vertex), m_graph(graph) + { + } - result_type - operator() - (typename graph_traits::degree_size_type in_edge_index) const { - return (in_edge_at(m_vertex, in_edge_index, *m_graph)); - } + result_type operator()( + typename graph_traits< Graph >::degree_size_type in_edge_index) + const + { + return (in_edge_at(m_vertex, in_edge_index, *m_graph)); + } private: - vertex_descriptor m_vertex; - const Graph* m_graph; + vertex_descriptor m_vertex; + const Graph* m_graph; }; // edge_at - template - struct grid_graph_edge_at { + template < typename Graph > struct grid_graph_edge_at + { - typedef typename graph_traits::edge_descriptor result_type; + typedef typename graph_traits< Graph >::edge_descriptor result_type; - grid_graph_edge_at() : m_graph(0) {} + grid_graph_edge_at() : m_graph(0) {} - grid_graph_edge_at(const Graph* graph) : - m_graph(graph) { } + grid_graph_edge_at(const Graph* graph) : m_graph(graph) {} - result_type - operator() - (typename graph_traits::edges_size_type edge_index) const { - return (edge_at(edge_index, *m_graph)); - } + result_type operator()( + typename graph_traits< Graph >::edges_size_type edge_index) const + { + return (edge_at(edge_index, *m_graph)); + } private: - const Graph* m_graph; + const Graph* m_graph; }; // adjacent_vertex_at - template - struct grid_graph_adjacent_vertex_at { + template < typename Graph > struct grid_graph_adjacent_vertex_at + { public: - typedef typename graph_traits::vertex_descriptor result_type; + typedef typename graph_traits< Graph >::vertex_descriptor result_type; - grid_graph_adjacent_vertex_at(result_type source_vertex, - const Graph* graph) : - m_vertex(source_vertex), - m_graph(graph) { } + grid_graph_adjacent_vertex_at( + result_type source_vertex, const Graph* graph) + : m_vertex(source_vertex), m_graph(graph) + { + } - result_type - operator() - (typename graph_traits::degree_size_type adjacent_index) const { - return (target(out_edge_at(m_vertex, adjacent_index, *m_graph), *m_graph)); - } + result_type operator()( + typename graph_traits< Graph >::degree_size_type adjacent_index) + const + { + return (target( + out_edge_at(m_vertex, adjacent_index, *m_graph), *m_graph)); + } private: - result_type m_vertex; - const Graph* m_graph; + result_type m_vertex; + const Graph* m_graph; }; - } // namespace detail +} // namespace detail - //=========== - // Grid Graph - //=========== +//=========== +// Grid Graph +//=========== - template - class grid_graph { +template < std::size_t Dimensions, typename VertexIndex = std::size_t, + typename EdgeIndex = VertexIndex > +class grid_graph +{ - private: - typedef boost::array WrapDimensionArray; - grid_graph() { }; +private: + typedef boost::array< bool, Dimensions > WrapDimensionArray; + grid_graph() {}; - public: - - typedef grid_graph type; +public: + typedef grid_graph< Dimensions, VertexIndex, EdgeIndex > type; // sizes typedef VertexIndex vertices_size_type; @@ -275,736 +289,767 @@ namespace boost { typedef EdgeIndex degree_size_type; // descriptors - typedef boost::array vertex_descriptor; - typedef std::pair edge_descriptor; + typedef boost::array< VertexIndex, Dimensions > vertex_descriptor; + typedef std::pair< vertex_descriptor, vertex_descriptor > edge_descriptor; // vertex_iterator - typedef counting_iterator vertex_index_iterator; - typedef detail::grid_graph_vertex_at vertex_function; - typedef transform_iterator vertex_iterator; + typedef counting_iterator< vertices_size_type > vertex_index_iterator; + typedef detail::grid_graph_vertex_at< type > vertex_function; + typedef transform_iterator< vertex_function, vertex_index_iterator > + vertex_iterator; // edge_iterator - typedef counting_iterator edge_index_iterator; - typedef detail::grid_graph_edge_at edge_function; - typedef transform_iterator edge_iterator; + typedef counting_iterator< edges_size_type > edge_index_iterator; + typedef detail::grid_graph_edge_at< type > edge_function; + typedef transform_iterator< edge_function, edge_index_iterator > + edge_iterator; // out_edge_iterator - typedef counting_iterator degree_iterator; - typedef detail::grid_graph_out_edge_at out_edge_function; - typedef transform_iterator out_edge_iterator; + typedef counting_iterator< degree_size_type > degree_iterator; + typedef detail::grid_graph_out_edge_at< type > out_edge_function; + typedef transform_iterator< out_edge_function, degree_iterator > + out_edge_iterator; // in_edge_iterator - typedef detail::grid_graph_in_edge_at in_edge_function; - typedef transform_iterator in_edge_iterator; + typedef detail::grid_graph_in_edge_at< type > in_edge_function; + typedef transform_iterator< in_edge_function, degree_iterator > + in_edge_iterator; // adjacency_iterator - typedef detail::grid_graph_adjacent_vertex_at adjacent_vertex_function; - typedef transform_iterator adjacency_iterator; + typedef detail::grid_graph_adjacent_vertex_at< type > + adjacent_vertex_function; + typedef transform_iterator< adjacent_vertex_function, degree_iterator > + adjacency_iterator; // categories typedef directed_tag directed_category; - typedef disallow_parallel_edge_tag edge_parallel_category; + typedef disallow_parallel_edge_tag edge_parallel_category; struct traversal_category : virtual public incidence_graph_tag, virtual public adjacency_graph_tag, virtual public vertex_list_graph_tag, virtual public edge_list_graph_tag, virtual public bidirectional_graph_tag, - virtual public adjacency_matrix_tag { }; + virtual public adjacency_matrix_tag + { + }; static inline vertex_descriptor null_vertex() { - vertex_descriptor maxed_out_vertex; - std::fill(maxed_out_vertex.begin(), maxed_out_vertex.end(), - (std::numeric_limits::max)()); + vertex_descriptor maxed_out_vertex; + std::fill(maxed_out_vertex.begin(), maxed_out_vertex.end(), + (std::numeric_limits< vertices_size_type >::max)()); - return (maxed_out_vertex); + return (maxed_out_vertex); } // Constructor that defaults to no wrapping for all dimensions. - grid_graph(vertex_descriptor dimension_lengths) : - m_dimension_lengths(dimension_lengths) { + grid_graph(vertex_descriptor dimension_lengths) + : m_dimension_lengths(dimension_lengths) + { - std::fill(m_wrap_dimension.begin(), - m_wrap_dimension.end(), false); + std::fill(m_wrap_dimension.begin(), m_wrap_dimension.end(), false); - precalculate(); + precalculate(); } // Constructor that allows for wrapping to be specified for all // dimensions at once. - grid_graph(vertex_descriptor dimension_lengths, - bool wrap_all_dimensions) : - m_dimension_lengths(dimension_lengths) { - - std::fill(m_wrap_dimension.begin(), - m_wrap_dimension.end(), - wrap_all_dimensions); + grid_graph(vertex_descriptor dimension_lengths, bool wrap_all_dimensions) + : m_dimension_lengths(dimension_lengths) + { + + std::fill(m_wrap_dimension.begin(), m_wrap_dimension.end(), + wrap_all_dimensions); - precalculate(); + precalculate(); } // Constructor that allows for individual dimension wrapping to be // specified. - grid_graph(vertex_descriptor dimension_lengths, - WrapDimensionArray wrap_dimension) : - m_dimension_lengths(dimension_lengths), - m_wrap_dimension(wrap_dimension) { + grid_graph( + vertex_descriptor dimension_lengths, WrapDimensionArray wrap_dimension) + : m_dimension_lengths(dimension_lengths), m_wrap_dimension(wrap_dimension) + { - precalculate(); + precalculate(); } // Returns the number of dimensions in the graph - inline std::size_t dimensions() const { - return (Dimensions); - } + inline std::size_t dimensions() const { return (Dimensions); } // Returns the length of dimension [dimension_index] - inline vertices_size_type length(std::size_t dimension) const { - return (m_dimension_lengths[dimension]); + inline vertices_size_type length(std::size_t dimension) const + { + return (m_dimension_lengths[dimension]); } // Returns a value indicating if dimension [dimension_index] wraps - inline bool wrapped(std::size_t dimension) const { - return (m_wrap_dimension[dimension]); + inline bool wrapped(std::size_t dimension) const + { + return (m_wrap_dimension[dimension]); } // Gets the vertex that is [distance] units ahead of [vertex] in // dimension [dimension_index]. - vertex_descriptor next - (vertex_descriptor vertex, - std::size_t dimension_index, - vertices_size_type distance = 1) const { + vertex_descriptor next(vertex_descriptor vertex, + std::size_t dimension_index, vertices_size_type distance = 1) const + { - vertices_size_type new_position = - vertex[dimension_index] + distance; + vertices_size_type new_position = vertex[dimension_index] + distance; - if (wrapped(dimension_index)) { - new_position %= length(dimension_index); - } - else { - // Stop at the end of this dimension if necessary. - new_position = - (std::min)(new_position, - vertices_size_type(length(dimension_index) - 1)); - } + if (wrapped(dimension_index)) + { + new_position %= length(dimension_index); + } + else + { + // Stop at the end of this dimension if necessary. + new_position = (std::min)( + new_position, vertices_size_type(length(dimension_index) - 1)); + } - vertex[dimension_index] = new_position; + vertex[dimension_index] = new_position; - return (vertex); + return (vertex); } // Gets the vertex that is [distance] units behind [vertex] in // dimension [dimension_index]. - vertex_descriptor previous - (vertex_descriptor vertex, - std::size_t dimension_index, - vertices_size_type distance = 1) const { - - // We're assuming that vertices_size_type is unsigned, so we - // need to be careful about the math. - vertex[dimension_index] = - (distance > vertex[dimension_index]) ? - (wrapped(dimension_index) ? - (length(dimension_index) - (distance % length(dimension_index))) : 0) : - vertex[dimension_index] - distance; + vertex_descriptor previous(vertex_descriptor vertex, + std::size_t dimension_index, vertices_size_type distance = 1) const + { - return (vertex); - } + // We're assuming that vertices_size_type is unsigned, so we + // need to be careful about the math. + vertex[dimension_index] = (distance > vertex[dimension_index]) + ? (wrapped(dimension_index) ? (length(dimension_index) + - (distance % length(dimension_index))) + : 0) + : vertex[dimension_index] - distance; - protected: + return (vertex); + } +protected: // Returns the number of vertices in the graph - inline vertices_size_type num_vertices() const { - return (m_num_vertices); - } - + inline vertices_size_type num_vertices() const { return (m_num_vertices); } + // Returns the number of edges in the graph - inline edges_size_type num_edges() const { - return (m_num_edges); - } + inline edges_size_type num_edges() const { return (m_num_edges); } // Returns the number of edges in dimension [dimension_index] - inline edges_size_type num_edges - (std::size_t dimension_index) const { - return (m_edge_count[dimension_index]); + inline edges_size_type num_edges(std::size_t dimension_index) const + { + return (m_edge_count[dimension_index]); } // Returns the index of [vertex] (See also vertex_at) - vertices_size_type index_of(vertex_descriptor vertex) const { + vertices_size_type index_of(vertex_descriptor vertex) const + { - vertices_size_type vertex_index = 0; - vertices_size_type index_multiplier = 1; + vertices_size_type vertex_index = 0; + vertices_size_type index_multiplier = 1; - for (std::size_t dimension_index = 0; - dimension_index < Dimensions; - ++dimension_index) { + for (std::size_t dimension_index = 0; dimension_index < Dimensions; + ++dimension_index) + { - vertex_index += (vertex[dimension_index] * index_multiplier); - index_multiplier *= length(dimension_index); - } + vertex_index += (vertex[dimension_index] * index_multiplier); + index_multiplier *= length(dimension_index); + } - return (vertex_index); + return (vertex_index); } // Returns the vertex whose index is [vertex_index] (See also // index_of(vertex_descriptor)) - vertex_descriptor vertex_at - (vertices_size_type vertex_index) const { - - boost::array vertex; - vertices_size_type index_divider = 1; + vertex_descriptor vertex_at(vertices_size_type vertex_index) const + { + + boost::array< vertices_size_type, Dimensions > vertex; + vertices_size_type index_divider = 1; - for (std::size_t dimension_index = 0; - dimension_index < Dimensions; - ++dimension_index) { + for (std::size_t dimension_index = 0; dimension_index < Dimensions; + ++dimension_index) + { - vertex[dimension_index] = (vertex_index / index_divider) % - length(dimension_index); + vertex[dimension_index] + = (vertex_index / index_divider) % length(dimension_index); - index_divider *= length(dimension_index); - } + index_divider *= length(dimension_index); + } - return (vertex); - } + return (vertex); + } // Returns the edge whose index is [edge_index] (See also // index_of(edge_descriptor)). NOTE: The index mapping is // dependent upon dimension wrapping. - edge_descriptor edge_at(edges_size_type edge_index) const { - - // Edge indices are sorted into bins by dimension - std::size_t dimension_index = 0; - edges_size_type dimension_edges = num_edges(0); - - while (edge_index >= dimension_edges) { - edge_index -= dimension_edges; - ++dimension_index; - dimension_edges = num_edges(dimension_index); - } - - vertex_descriptor vertex_source, vertex_target; - bool is_forward = ((edge_index / (num_edges(dimension_index) / 2)) == 0); - - if (wrapped(dimension_index)) { - vertex_source = vertex_at(edge_index % num_vertices()); - vertex_target = is_forward ? - next(vertex_source, dimension_index) : - previous(vertex_source, dimension_index); - } - else { - - // Dimensions can wrap arbitrarily, so an index needs to be - // computed in a more complex manner. This is done by - // grouping the edges for each dimension together into "bins" - // and considering [edge_index] as an offset into the bin. - // Each bin consists of two parts: the "forward" looking edges - // and the "backward" looking edges for the dimension. - - edges_size_type vertex_offset = edge_index % num_edges(dimension_index); - - // Consider vertex_offset an index into the graph's vertex - // space but with the dimension [dimension_index] reduced in - // size by one. - vertices_size_type index_divider = 1; + edge_descriptor edge_at(edges_size_type edge_index) const + { - for (std::size_t dimension_index_iter = 0; - dimension_index_iter < Dimensions; - ++dimension_index_iter) { + // Edge indices are sorted into bins by dimension + std::size_t dimension_index = 0; + edges_size_type dimension_edges = num_edges(0); - std::size_t dimension_length = (dimension_index_iter == dimension_index) ? - length(dimension_index_iter) - 1 : - length(dimension_index_iter); + while (edge_index >= dimension_edges) + { + edge_index -= dimension_edges; + ++dimension_index; + dimension_edges = num_edges(dimension_index); + } - vertex_source[dimension_index_iter] = (vertex_offset / index_divider) % - dimension_length; + vertex_descriptor vertex_source, vertex_target; + bool is_forward + = ((edge_index / (num_edges(dimension_index) / 2)) == 0); - index_divider *= dimension_length; + if (wrapped(dimension_index)) + { + vertex_source = vertex_at(edge_index % num_vertices()); + vertex_target = is_forward + ? next(vertex_source, dimension_index) + : previous(vertex_source, dimension_index); } + else + { + + // Dimensions can wrap arbitrarily, so an index needs to be + // computed in a more complex manner. This is done by + // grouping the edges for each dimension together into "bins" + // and considering [edge_index] as an offset into the bin. + // Each bin consists of two parts: the "forward" looking edges + // and the "backward" looking edges for the dimension. + + edges_size_type vertex_offset + = edge_index % num_edges(dimension_index); + + // Consider vertex_offset an index into the graph's vertex + // space but with the dimension [dimension_index] reduced in + // size by one. + vertices_size_type index_divider = 1; + + for (std::size_t dimension_index_iter = 0; + dimension_index_iter < Dimensions; ++dimension_index_iter) + { + + std::size_t dimension_length + = (dimension_index_iter == dimension_index) + ? length(dimension_index_iter) - 1 + : length(dimension_index_iter); + + vertex_source[dimension_index_iter] + = (vertex_offset / index_divider) % dimension_length; + + index_divider *= dimension_length; + } + + if (is_forward) + { + vertex_target = next(vertex_source, dimension_index); + } + else + { + // Shift forward one more unit in the dimension for backward + // edges since the algorithm above will leave us one behind. + vertex_target = vertex_source; + ++vertex_source[dimension_index]; + } + + } // if (wrapped(dimension_index)) + + return (std::make_pair(vertex_source, vertex_target)); + } - if (is_forward) { - vertex_target = next(vertex_source, dimension_index); - } - else { - // Shift forward one more unit in the dimension for backward - // edges since the algorithm above will leave us one behind. - vertex_target = vertex_source; - ++vertex_source[dimension_index]; + // Returns the index for [edge] (See also edge_at) + edges_size_type index_of(edge_descriptor edge) const + { + vertex_descriptor source_vertex = source(edge, *this); + vertex_descriptor target_vertex = target(edge, *this); + + BOOST_ASSERT(source_vertex != target_vertex); + + // Determine the dimension where the source and target vertices + // differ (should only be one if this is a valid edge). + std::size_t different_dimension_index = 0; + + while (source_vertex[different_dimension_index] + == target_vertex[different_dimension_index]) + { + + ++different_dimension_index; } - } // if (wrapped(dimension_index)) - - return (std::make_pair(vertex_source, vertex_target)); - } - - // Returns the index for [edge] (See also edge_at) - edges_size_type index_of(edge_descriptor edge) const { - vertex_descriptor source_vertex = source(edge, *this); - vertex_descriptor target_vertex = target(edge, *this); - - BOOST_ASSERT (source_vertex != target_vertex); - - // Determine the dimension where the source and target vertices - // differ (should only be one if this is a valid edge). - std::size_t different_dimension_index = 0; - - while (source_vertex[different_dimension_index] == - target_vertex[different_dimension_index]) { - - ++different_dimension_index; - } - - edges_size_type edge_index = 0; - - // Offset the edge index into the appropriate "bin" (see edge_at - // for a more in-depth description). - for (std::size_t dimension_index = 0; - dimension_index < different_dimension_index; - ++dimension_index) { - - edge_index += num_edges(dimension_index); - } - - // Get the position of both vertices in the differing dimension. - vertices_size_type source_position = source_vertex[different_dimension_index]; - vertices_size_type target_position = target_vertex[different_dimension_index]; - - // Determine if edge is forward or backward - bool is_forward = true; - - if (wrapped(different_dimension_index)) { - - // If the dimension is wrapped, an edge is going backward if - // either A: its target precedes the source in the differing - // dimension and the vertices are adjacent or B: its source - // precedes the target and they're not adjacent. - if (((target_position < source_position) && - ((source_position - target_position) == 1)) || - ((source_position < target_position) && - ((target_position - source_position) > 1))) { - - is_forward = false; + edges_size_type edge_index = 0; + + // Offset the edge index into the appropriate "bin" (see edge_at + // for a more in-depth description). + for (std::size_t dimension_index = 0; + dimension_index < different_dimension_index; ++dimension_index) + { + + edge_index += num_edges(dimension_index); } - } - else if (target_position < source_position) { - is_forward = false; - } - - // "Backward" edges are in the second half of the bin. - if (!is_forward) { - edge_index += (num_edges(different_dimension_index) / 2); - } - - // Finally, apply the vertex offset - if (wrapped(different_dimension_index)) { - edge_index += index_of(source_vertex); - } - else { - vertices_size_type index_multiplier = 1; - if (!is_forward) { - --source_vertex[different_dimension_index]; + // Get the position of both vertices in the differing dimension. + vertices_size_type source_position + = source_vertex[different_dimension_index]; + vertices_size_type target_position + = target_vertex[different_dimension_index]; + + // Determine if edge is forward or backward + bool is_forward = true; + + if (wrapped(different_dimension_index)) + { + + // If the dimension is wrapped, an edge is going backward if + // either A: its target precedes the source in the differing + // dimension and the vertices are adjacent or B: its source + // precedes the target and they're not adjacent. + if (((target_position < source_position) + && ((source_position - target_position) == 1)) + || ((source_position < target_position) + && ((target_position - source_position) > 1))) + { + + is_forward = false; + } + } + else if (target_position < source_position) + { + is_forward = false; } - for (std::size_t dimension_index = 0; - dimension_index < Dimensions; - ++dimension_index) { + // "Backward" edges are in the second half of the bin. + if (!is_forward) + { + edge_index += (num_edges(different_dimension_index) / 2); + } - edge_index += (source_vertex[dimension_index] * index_multiplier); - index_multiplier *= (dimension_index == different_dimension_index) ? - length(dimension_index) - 1 : - length(dimension_index); + // Finally, apply the vertex offset + if (wrapped(different_dimension_index)) + { + edge_index += index_of(source_vertex); + } + else + { + vertices_size_type index_multiplier = 1; + + if (!is_forward) + { + --source_vertex[different_dimension_index]; + } + + for (std::size_t dimension_index = 0; dimension_index < Dimensions; + ++dimension_index) + { + + edge_index + += (source_vertex[dimension_index] * index_multiplier); + index_multiplier + *= (dimension_index == different_dimension_index) + ? length(dimension_index) - 1 + : length(dimension_index); + } } - } - return (edge_index); + return (edge_index); } // Returns the number of out-edges for [vertex] - degree_size_type out_degree(vertex_descriptor vertex) const { - - degree_size_type out_edge_count = 0; - - for (std::size_t dimension_index = 0; - dimension_index < Dimensions; - ++dimension_index) { + degree_size_type out_degree(vertex_descriptor vertex) const + { - // If the vertex is on the edge of this dimension, then its - // number of out edges is dependent upon whether the dimension - // wraps or not. - if ((vertex[dimension_index] == 0) || - (vertex[dimension_index] == (length(dimension_index) - 1))) { - out_edge_count += (wrapped(dimension_index) ? 2 : 1); - } - else { - // Next and previous edges, regardless or wrapping - out_edge_count += 2; + degree_size_type out_edge_count = 0; + + for (std::size_t dimension_index = 0; dimension_index < Dimensions; + ++dimension_index) + { + + // If the vertex is on the edge of this dimension, then its + // number of out edges is dependent upon whether the dimension + // wraps or not. + if ((vertex[dimension_index] == 0) + || (vertex[dimension_index] == (length(dimension_index) - 1))) + { + out_edge_count += (wrapped(dimension_index) ? 2 : 1); + } + else + { + // Next and previous edges, regardless or wrapping + out_edge_count += 2; + } } - } - return (out_edge_count); + return (out_edge_count); } // Returns an out-edge for [vertex] by index. Indices are in the // range [0, out_degree(vertex)). - edge_descriptor out_edge_at - (vertex_descriptor vertex, - degree_size_type out_edge_index) const { - - edges_size_type edges_left = out_edge_index + 1; - std::size_t dimension_index = 0; - bool is_forward = false; - - // Walks the out edges of [vertex] and accommodates for dimension - // wrapping. - while (edges_left > 0) { - - if (!wrapped(dimension_index)) { - if (!is_forward && (vertex[dimension_index] == 0)) { - is_forward = true; - continue; - } - else if (is_forward && - (vertex[dimension_index] == (length(dimension_index) - 1))) { - is_forward = false; - ++dimension_index; - continue; - } - } - - --edges_left; + edge_descriptor out_edge_at( + vertex_descriptor vertex, degree_size_type out_edge_index) const + { - if (edges_left > 0) { - is_forward = !is_forward; - - if (!is_forward) { - ++dimension_index; - } + edges_size_type edges_left = out_edge_index + 1; + std::size_t dimension_index = 0; + bool is_forward = false; + + // Walks the out edges of [vertex] and accommodates for dimension + // wrapping. + while (edges_left > 0) + { + + if (!wrapped(dimension_index)) + { + if (!is_forward && (vertex[dimension_index] == 0)) + { + is_forward = true; + continue; + } + else if (is_forward + && (vertex[dimension_index] + == (length(dimension_index) - 1))) + { + is_forward = false; + ++dimension_index; + continue; + } + } + + --edges_left; + + if (edges_left > 0) + { + is_forward = !is_forward; + + if (!is_forward) + { + ++dimension_index; + } + } } - } - return (std::make_pair(vertex, is_forward ? - next(vertex, dimension_index) : - previous(vertex, dimension_index))); + return (std::make_pair(vertex, + is_forward ? next(vertex, dimension_index) + : previous(vertex, dimension_index))); } // Returns the number of in-edges for [vertex] - inline degree_size_type in_degree(vertex_descriptor vertex) const { - return (out_degree(vertex)); + inline degree_size_type in_degree(vertex_descriptor vertex) const + { + return (out_degree(vertex)); } // Returns an in-edge for [vertex] by index. Indices are in the // range [0, in_degree(vertex)). - edge_descriptor in_edge_at - (vertex_descriptor vertex, - edges_size_type in_edge_index) const { - - edge_descriptor out_edge = out_edge_at(vertex, in_edge_index); - return (std::make_pair(target(out_edge, *this), source(out_edge, *this))); + edge_descriptor in_edge_at( + vertex_descriptor vertex, edges_size_type in_edge_index) const + { + edge_descriptor out_edge = out_edge_at(vertex, in_edge_index); + return ( + std::make_pair(target(out_edge, *this), source(out_edge, *this))); } // Pre-computes the number of vertices and edges - void precalculate() { - m_num_vertices = - std::accumulate(m_dimension_lengths.begin(), - m_dimension_lengths.end(), - vertices_size_type(1), - std::multiplies()); - - // Calculate number of edges in each dimension - m_num_edges = 0; - - for (std::size_t dimension_index = 0; - dimension_index < Dimensions; - ++dimension_index) { - - if (wrapped(dimension_index)) { - m_edge_count[dimension_index] = num_vertices() * 2; - } - else { - m_edge_count[dimension_index] = - (num_vertices() - (num_vertices() / length(dimension_index))) * 2; + void precalculate() + { + m_num_vertices = std::accumulate(m_dimension_lengths.begin(), + m_dimension_lengths.end(), vertices_size_type(1), + std::multiplies< vertices_size_type >()); + + // Calculate number of edges in each dimension + m_num_edges = 0; + + for (std::size_t dimension_index = 0; dimension_index < Dimensions; + ++dimension_index) + { + + if (wrapped(dimension_index)) + { + m_edge_count[dimension_index] = num_vertices() * 2; + } + else + { + m_edge_count[dimension_index] + = (num_vertices() + - (num_vertices() / length(dimension_index))) + * 2; + } + + m_num_edges += num_edges(dimension_index); } - - m_num_edges += num_edges(dimension_index); - } } const vertex_descriptor m_dimension_lengths; WrapDimensionArray m_wrap_dimension; vertices_size_type m_num_vertices; - boost::array m_edge_count; + boost::array< edges_size_type, Dimensions > m_edge_count; edges_size_type m_num_edges; - public: - +public: //================ // VertexListGraph //================ - friend inline std::pair - vertices(const type& graph) { - typedef typename type::vertex_iterator vertex_iterator; - typedef typename type::vertex_function vertex_function; - typedef typename type::vertex_index_iterator vertex_index_iterator; - - return (std::make_pair - (vertex_iterator(vertex_index_iterator(0), - vertex_function(&graph)), - vertex_iterator(vertex_index_iterator(graph.num_vertices()), - vertex_function(&graph)))); + friend inline std::pair< typename type::vertex_iterator, + typename type::vertex_iterator > + vertices(const type& graph) + { + typedef typename type::vertex_iterator vertex_iterator; + typedef typename type::vertex_function vertex_function; + typedef typename type::vertex_index_iterator vertex_index_iterator; + + return (std::make_pair( + vertex_iterator(vertex_index_iterator(0), vertex_function(&graph)), + vertex_iterator(vertex_index_iterator(graph.num_vertices()), + vertex_function(&graph)))); } - friend inline typename type::vertices_size_type - num_vertices(const type& graph) { - return (graph.num_vertices()); + friend inline typename type::vertices_size_type num_vertices( + const type& graph) + { + return (graph.num_vertices()); } - friend inline typename type::vertex_descriptor - vertex(typename type::vertices_size_type vertex_index, - const type& graph) { + friend inline typename type::vertex_descriptor vertex( + typename type::vertices_size_type vertex_index, const type& graph) + { - return (graph.vertex_at(vertex_index)); + return (graph.vertex_at(vertex_index)); } //=============== // IncidenceGraph //=============== - friend inline std::pair - out_edges(typename type::vertex_descriptor vertex, - const type& graph) { - typedef typename type::degree_iterator degree_iterator; - typedef typename type::out_edge_function out_edge_function; - typedef typename type::out_edge_iterator out_edge_iterator; - - return (std::make_pair - (out_edge_iterator(degree_iterator(0), - out_edge_function(vertex, &graph)), - out_edge_iterator(degree_iterator(graph.out_degree(vertex)), - out_edge_function(vertex, &graph)))); + friend inline std::pair< typename type::out_edge_iterator, + typename type::out_edge_iterator > + out_edges(typename type::vertex_descriptor vertex, const type& graph) + { + typedef typename type::degree_iterator degree_iterator; + typedef typename type::out_edge_function out_edge_function; + typedef typename type::out_edge_iterator out_edge_iterator; + + return (std::make_pair(out_edge_iterator(degree_iterator(0), + out_edge_function(vertex, &graph)), + out_edge_iterator(degree_iterator(graph.out_degree(vertex)), + out_edge_function(vertex, &graph)))); } - friend inline typename type::degree_size_type - out_degree - (typename type::vertex_descriptor vertex, - const type& graph) { - return (graph.out_degree(vertex)); + friend inline typename type::degree_size_type out_degree( + typename type::vertex_descriptor vertex, const type& graph) + { + return (graph.out_degree(vertex)); } - friend inline typename type::edge_descriptor - out_edge_at(typename type::vertex_descriptor vertex, - typename type::degree_size_type out_edge_index, - const type& graph) { - return (graph.out_edge_at(vertex, out_edge_index)); + friend inline typename type::edge_descriptor out_edge_at( + typename type::vertex_descriptor vertex, + typename type::degree_size_type out_edge_index, const type& graph) + { + return (graph.out_edge_at(vertex, out_edge_index)); } //=============== // AdjacencyGraph //=============== - friend typename std::pair - adjacent_vertices (typename type::vertex_descriptor vertex, - const type& graph) { - typedef typename type::degree_iterator degree_iterator; - typedef typename type::adjacent_vertex_function adjacent_vertex_function; - typedef typename type::adjacency_iterator adjacency_iterator; - - return (std::make_pair - (adjacency_iterator(degree_iterator(0), - adjacent_vertex_function(vertex, &graph)), - adjacency_iterator(degree_iterator(graph.out_degree(vertex)), - adjacent_vertex_function(vertex, &graph)))); + friend typename std::pair< typename type::adjacency_iterator, + typename type::adjacency_iterator > + adjacent_vertices( + typename type::vertex_descriptor vertex, const type& graph) + { + typedef typename type::degree_iterator degree_iterator; + typedef + typename type::adjacent_vertex_function adjacent_vertex_function; + typedef typename type::adjacency_iterator adjacency_iterator; + + return (std::make_pair(adjacency_iterator(degree_iterator(0), + adjacent_vertex_function(vertex, &graph)), + adjacency_iterator(degree_iterator(graph.out_degree(vertex)), + adjacent_vertex_function(vertex, &graph)))); } //============== // EdgeListGraph //============== - friend inline typename type::edges_size_type - num_edges(const type& graph) { - return (graph.num_edges()); + friend inline typename type::edges_size_type num_edges(const type& graph) + { + return (graph.num_edges()); } - friend inline typename type::edge_descriptor - edge_at(typename type::edges_size_type edge_index, - const type& graph) { - return (graph.edge_at(edge_index)); + friend inline typename type::edge_descriptor edge_at( + typename type::edges_size_type edge_index, const type& graph) + { + return (graph.edge_at(edge_index)); } - friend inline std::pair - edges(const type& graph) { - typedef typename type::edge_index_iterator edge_index_iterator; - typedef typename type::edge_function edge_function; - typedef typename type::edge_iterator edge_iterator; - - return (std::make_pair - (edge_iterator(edge_index_iterator(0), - edge_function(&graph)), - edge_iterator(edge_index_iterator(graph.num_edges()), - edge_function(&graph)))); + friend inline std::pair< typename type::edge_iterator, + typename type::edge_iterator > + edges(const type& graph) + { + typedef typename type::edge_index_iterator edge_index_iterator; + typedef typename type::edge_function edge_function; + typedef typename type::edge_iterator edge_iterator; + + return (std::make_pair( + edge_iterator(edge_index_iterator(0), edge_function(&graph)), + edge_iterator(edge_index_iterator(graph.num_edges()), + edge_function(&graph)))); } //=================== // BiDirectionalGraph //=================== - friend inline std::pair - in_edges(typename type::vertex_descriptor vertex, - const type& graph) { - typedef typename type::in_edge_function in_edge_function; - typedef typename type::degree_iterator degree_iterator; - typedef typename type::in_edge_iterator in_edge_iterator; - - return (std::make_pair - (in_edge_iterator(degree_iterator(0), - in_edge_function(vertex, &graph)), - in_edge_iterator(degree_iterator(graph.in_degree(vertex)), - in_edge_function(vertex, &graph)))); + friend inline std::pair< typename type::in_edge_iterator, + typename type::in_edge_iterator > + in_edges(typename type::vertex_descriptor vertex, const type& graph) + { + typedef typename type::in_edge_function in_edge_function; + typedef typename type::degree_iterator degree_iterator; + typedef typename type::in_edge_iterator in_edge_iterator; + + return (std::make_pair(in_edge_iterator(degree_iterator(0), + in_edge_function(vertex, &graph)), + in_edge_iterator(degree_iterator(graph.in_degree(vertex)), + in_edge_function(vertex, &graph)))); } - friend inline typename type::degree_size_type - in_degree (typename type::vertex_descriptor vertex, - const type& graph) { - return (graph.in_degree(vertex)); + friend inline typename type::degree_size_type in_degree( + typename type::vertex_descriptor vertex, const type& graph) + { + return (graph.in_degree(vertex)); } - friend inline typename type::degree_size_type - degree (typename type::vertex_descriptor vertex, - const type& graph) { - return (graph.out_degree(vertex) * 2); + friend inline typename type::degree_size_type degree( + typename type::vertex_descriptor vertex, const type& graph) + { + return (graph.out_degree(vertex) * 2); } - friend inline typename type::edge_descriptor - in_edge_at(typename type::vertex_descriptor vertex, - typename type::degree_size_type in_edge_index, - const type& graph) { - return (graph.in_edge_at(vertex, in_edge_index)); + friend inline typename type::edge_descriptor in_edge_at( + typename type::vertex_descriptor vertex, + typename type::degree_size_type in_edge_index, const type& graph) + { + return (graph.in_edge_at(vertex, in_edge_index)); } - //================== // Adjacency Matrix //================== - friend std::pair - edge (typename type::vertex_descriptor source_vertex, - typename type::vertex_descriptor destination_vertex, - const type& graph) { - - std::pair edge_exists = - std::make_pair(std::make_pair(source_vertex, destination_vertex), false); - - for (std::size_t dimension_index = 0; - dimension_index < Dimensions; - ++dimension_index) { - - typename type::vertices_size_type dim_difference = 0; - typename type::vertices_size_type - source_dim = source_vertex[dimension_index], - dest_dim = destination_vertex[dimension_index]; - - dim_difference = (source_dim > dest_dim) ? - (source_dim - dest_dim) : (dest_dim - source_dim); - - if (dim_difference > 0) { - - // If we've already found a valid edge, this would mean that - // the vertices are really diagonal across dimensions and - // therefore not connected. - if (edge_exists.second) { - edge_exists.second = false; - break; - } - - // If the difference is one, the vertices are right next to - // each other and the edge is valid. The edge is still - // valid, though, if the dimension wraps and the vertices - // are on opposite ends. - if ((dim_difference == 1) || - (graph.wrapped(dimension_index) && - (((source_dim == 0) && (dest_dim == (graph.length(dimension_index) - 1))) || - ((dest_dim == 0) && (source_dim == (graph.length(dimension_index) - 1)))))) { - - edge_exists.second = true; - // Stay in the loop to check for diagonal vertices. - } - else { - - // Stop checking - the vertices are too far apart. - edge_exists.second = false; - break; - } - } - - } // for dimension_index + friend std::pair< typename type::edge_descriptor, bool > edge( + typename type::vertex_descriptor source_vertex, + typename type::vertex_descriptor destination_vertex, const type& graph) + { - return (edge_exists); + std::pair< typename type::edge_descriptor, bool > edge_exists + = std::make_pair( + std::make_pair(source_vertex, destination_vertex), false); + + for (std::size_t dimension_index = 0; dimension_index < Dimensions; + ++dimension_index) + { + + typename type::vertices_size_type dim_difference = 0; + typename type::vertices_size_type source_dim + = source_vertex[dimension_index], + dest_dim = destination_vertex[dimension_index]; + + dim_difference = (source_dim > dest_dim) ? (source_dim - dest_dim) + : (dest_dim - source_dim); + + if (dim_difference > 0) + { + + // If we've already found a valid edge, this would mean that + // the vertices are really diagonal across dimensions and + // therefore not connected. + if (edge_exists.second) + { + edge_exists.second = false; + break; + } + + // If the difference is one, the vertices are right next to + // each other and the edge is valid. The edge is still + // valid, though, if the dimension wraps and the vertices + // are on opposite ends. + if ((dim_difference == 1) + || (graph.wrapped(dimension_index) + && (((source_dim == 0) + && (dest_dim + == (graph.length(dimension_index) - 1))) + || ((dest_dim == 0) + && (source_dim + == (graph.length(dimension_index) - 1)))))) + { + + edge_exists.second = true; + // Stay in the loop to check for diagonal vertices. + } + else + { + + // Stop checking - the vertices are too far apart. + edge_exists.second = false; + break; + } + } + + } // for dimension_index + + return (edge_exists); } - //============================= // Index Property Map Functions //============================= - friend inline typename type::vertices_size_type - get(vertex_index_t, - const type& graph, - typename type::vertex_descriptor vertex) { - return (graph.index_of(vertex)); - } - - friend inline typename type::edges_size_type - get(edge_index_t, - const type& graph, - typename type::edge_descriptor edge) { - return (graph.index_of(edge)); - } - - friend inline grid_graph_index_map< - type, - typename type::vertex_descriptor, - typename type::vertices_size_type> - get(vertex_index_t, const type& graph) { - return (grid_graph_index_map< - type, - typename type::vertex_descriptor, - typename type::vertices_size_type>(graph)); - } - - friend inline grid_graph_index_map< - type, - typename type::edge_descriptor, - typename type::edges_size_type> - get(edge_index_t, const type& graph) { - return (grid_graph_index_map< - type, - typename type::edge_descriptor, - typename type::edges_size_type>(graph)); - } - - friend inline grid_graph_reverse_edge_map< - typename type::edge_descriptor> - get(edge_reverse_t, const type& graph) { - return (grid_graph_reverse_edge_map< - typename type::edge_descriptor>()); - } - - template + friend inline typename type::vertices_size_type get(vertex_index_t, + const type& graph, typename type::vertex_descriptor vertex) + { + return (graph.index_of(vertex)); + } + + friend inline typename type::edges_size_type get( + edge_index_t, const type& graph, typename type::edge_descriptor edge) + { + return (graph.index_of(edge)); + } + + friend inline grid_graph_index_map< type, typename type::vertex_descriptor, + typename type::vertices_size_type > + get(vertex_index_t, const type& graph) + { + return (grid_graph_index_map< type, typename type::vertex_descriptor, + typename type::vertices_size_type >(graph)); + } + + friend inline grid_graph_index_map< type, typename type::edge_descriptor, + typename type::edges_size_type > + get(edge_index_t, const type& graph) + { + return (grid_graph_index_map< type, typename type::edge_descriptor, + typename type::edges_size_type >(graph)); + } + + friend inline grid_graph_reverse_edge_map< typename type::edge_descriptor > + get(edge_reverse_t, const type& graph) + { + return ( + grid_graph_reverse_edge_map< typename type::edge_descriptor >()); + } + + template < typename Graph, typename Descriptor, typename Index > friend struct grid_graph_index_map; - template - friend struct grid_graph_reverse_edge_map; + template < typename Descriptor > friend struct grid_graph_reverse_edge_map; - }; // grid_graph +}; // grid_graph } // namespace boost diff --git a/include/boost/graph/gursoy_atun_layout.hpp b/include/boost/graph/gursoy_atun_layout.hpp index 5ac52f30e..1a8709b17 100644 --- a/include/boost/graph/gursoy_atun_layout.hpp +++ b/include/boost/graph/gursoy_atun_layout.hpp @@ -12,8 +12,8 @@ // Gürsoy-Atun graph layout, based on: // "Neighbourhood Preserving Load Balancing: A Self-Organizing Approach" -// in 6th International Euro-Par Conference Munich, Germany, August 29 – September 1, 2000 Proceedings, -// pp 234-241 +// in 6th International Euro-Par Conference Munich, Germany, August 29 – +// September 1, 2000 Proceedings, pp 234-241 // https://doi.org/10.1007/3-540-44520-X_32 #include @@ -33,324 +33,304 @@ #include #include -namespace boost { +namespace boost +{ -namespace detail { +namespace detail +{ -struct over_distance_limit : public std::exception {}; + struct over_distance_limit : public std::exception + { + }; -template -struct update_position_visitor { - typedef typename Topology::point_type Point; - PositionMap position_map; - NodeDistanceMap node_distance; - const Topology& space; - Point input_vector; - double distance_limit; - double learning_constant; - double falloff_ratio; + template < typename PositionMap, typename NodeDistanceMap, + typename Topology, typename Graph > + struct update_position_visitor + { + typedef typename Topology::point_type Point; + PositionMap position_map; + NodeDistanceMap node_distance; + const Topology& space; + Point input_vector; + double distance_limit; + double learning_constant; + double falloff_ratio; - typedef boost::on_examine_vertex event_filter; + typedef boost::on_examine_vertex event_filter; - typedef typename graph_traits::vertex_descriptor - vertex_descriptor; + typedef + typename graph_traits< Graph >::vertex_descriptor vertex_descriptor; - update_position_visitor(PositionMap position_map, - NodeDistanceMap node_distance, - const Topology& space, - const Point& input_vector, - double distance_limit, - double learning_constant, - double falloff_ratio): - position_map(position_map), node_distance(node_distance), - space(space), - input_vector(input_vector), distance_limit(distance_limit), - learning_constant(learning_constant), falloff_ratio(falloff_ratio) {} + update_position_visitor(PositionMap position_map, + NodeDistanceMap node_distance, const Topology& space, + const Point& input_vector, double distance_limit, + double learning_constant, double falloff_ratio) + : position_map(position_map) + , node_distance(node_distance) + , space(space) + , input_vector(input_vector) + , distance_limit(distance_limit) + , learning_constant(learning_constant) + , falloff_ratio(falloff_ratio) + { + } - void operator()(vertex_descriptor v, const Graph&) const - { + void operator()(vertex_descriptor v, const Graph&) const + { #ifndef BOOST_NO_STDC_NAMESPACE - using std::pow; + using std::pow; #endif - if (get(node_distance, v) > distance_limit) - BOOST_THROW_EXCEPTION(over_distance_limit()); - Point old_position = get(position_map, v); - double distance = get(node_distance, v); - double fraction = - learning_constant * pow(falloff_ratio, distance * distance); - put(position_map, v, - space.move_position_toward(old_position, fraction, input_vector)); - } -}; + if (get(node_distance, v) > distance_limit) + BOOST_THROW_EXCEPTION(over_distance_limit()); + Point old_position = get(position_map, v); + double distance = get(node_distance, v); + double fraction + = learning_constant * pow(falloff_ratio, distance * distance); + put(position_map, v, + space.move_position_toward( + old_position, fraction, input_vector)); + } + }; -template -struct gursoy_shortest -{ - template - static inline void - run(const Graph& g, typename graph_traits::vertex_descriptor s, - NodeDistanceMap node_distance, UpdatePosition& update_position, - EdgeWeightMap weight) - { - boost::dijkstra_shortest_paths(g, s, weight_map(weight). - visitor(boost::make_dijkstra_visitor(std::make_pair( - boost::record_distances(node_distance, boost::on_edge_relaxed()), - update_position)))); - } -}; + template < typename EdgeWeightMap > struct gursoy_shortest + { + template < typename Graph, typename NodeDistanceMap, + typename UpdatePosition > + static inline void run(const Graph& g, + typename graph_traits< Graph >::vertex_descriptor s, + NodeDistanceMap node_distance, UpdatePosition& update_position, + EdgeWeightMap weight) + { + boost::dijkstra_shortest_paths(g, s, + weight_map(weight).visitor(boost::make_dijkstra_visitor( + std::make_pair(boost::record_distances( + node_distance, boost::on_edge_relaxed()), + update_position)))); + } + }; -template<> -struct gursoy_shortest -{ - template - static inline void - run(const Graph& g, typename graph_traits::vertex_descriptor s, - NodeDistanceMap node_distance, UpdatePosition& update_position, - dummy_property_map) - { - boost::breadth_first_search(g, s, - visitor(boost::make_bfs_visitor(std::make_pair( - boost::record_distances(node_distance, boost::on_tree_edge()), - update_position)))); - } -}; + template <> struct gursoy_shortest< dummy_property_map > + { + template < typename Graph, typename NodeDistanceMap, + typename UpdatePosition > + static inline void run(const Graph& g, + typename graph_traits< Graph >::vertex_descriptor s, + NodeDistanceMap node_distance, UpdatePosition& update_position, + dummy_property_map) + { + boost::breadth_first_search(g, s, + visitor(boost::make_bfs_visitor( + std::make_pair(boost::record_distances( + node_distance, boost::on_tree_edge()), + update_position)))); + } + }; } // namespace detail -template -void -gursoy_atun_step - (const VertexListAndIncidenceGraph& graph, - const Topology& space, - PositionMap position, - Diameter diameter, - double learning_constant, - VertexIndexMap vertex_index_map, - EdgeWeightMap weight) +template < typename VertexListAndIncidenceGraph, typename Topology, + typename PositionMap, typename Diameter, typename VertexIndexMap, + typename EdgeWeightMap > +void gursoy_atun_step(const VertexListAndIncidenceGraph& graph, + const Topology& space, PositionMap position, Diameter diameter, + double learning_constant, VertexIndexMap vertex_index_map, + EdgeWeightMap weight) { #ifndef BOOST_NO_STDC_NAMESPACE - using std::pow; - using std::exp; + using std::exp; + using std::pow; #endif - typedef typename graph_traits::vertex_iterator - vertex_iterator; - typedef typename graph_traits::vertex_descriptor - vertex_descriptor; - typedef typename Topology::point_type point_type; - vertex_iterator i, iend; - std::vector distance_from_input_vector(num_vertices(graph)); - typedef boost::iterator_property_map::iterator, - VertexIndexMap, - double, double&> - DistanceFromInputMap; - DistanceFromInputMap distance_from_input(distance_from_input_vector.begin(), - vertex_index_map); - std::vector node_distance_map_vector(num_vertices(graph)); - typedef boost::iterator_property_map::iterator, - VertexIndexMap, - double, double&> - NodeDistanceMap; - NodeDistanceMap node_distance(node_distance_map_vector.begin(), - vertex_index_map); - point_type input_vector = space.random_point(); - vertex_descriptor min_distance_loc - = graph_traits::null_vertex(); - double min_distance = 0.0; - bool min_distance_unset = true; - for (boost::tie(i, iend) = vertices(graph); i != iend; ++i) { - double this_distance = space.distance(get(position, *i), input_vector); - put(distance_from_input, *i, this_distance); - if (min_distance_unset || this_distance < min_distance) { - min_distance = this_distance; - min_distance_loc = *i; + typedef + typename graph_traits< VertexListAndIncidenceGraph >::vertex_iterator + vertex_iterator; + typedef + typename graph_traits< VertexListAndIncidenceGraph >::vertex_descriptor + vertex_descriptor; + typedef typename Topology::point_type point_type; + vertex_iterator i, iend; + std::vector< double > distance_from_input_vector(num_vertices(graph)); + typedef boost::iterator_property_map< std::vector< double >::iterator, + VertexIndexMap, double, double& > + DistanceFromInputMap; + DistanceFromInputMap distance_from_input( + distance_from_input_vector.begin(), vertex_index_map); + std::vector< double > node_distance_map_vector(num_vertices(graph)); + typedef boost::iterator_property_map< std::vector< double >::iterator, + VertexIndexMap, double, double& > + NodeDistanceMap; + NodeDistanceMap node_distance( + node_distance_map_vector.begin(), vertex_index_map); + point_type input_vector = space.random_point(); + vertex_descriptor min_distance_loc + = graph_traits< VertexListAndIncidenceGraph >::null_vertex(); + double min_distance = 0.0; + bool min_distance_unset = true; + for (boost::tie(i, iend) = vertices(graph); i != iend; ++i) + { + double this_distance = space.distance(get(position, *i), input_vector); + put(distance_from_input, *i, this_distance); + if (min_distance_unset || this_distance < min_distance) + { + min_distance = this_distance; + min_distance_loc = *i; + } + min_distance_unset = false; + } + BOOST_ASSERT(!min_distance_unset); // Graph must have at least one vertex + boost::detail::update_position_visitor< PositionMap, NodeDistanceMap, + Topology, VertexListAndIncidenceGraph > + update_position(position, node_distance, space, input_vector, diameter, + learning_constant, exp(-1. / (2 * diameter * diameter))); + std::fill( + node_distance_map_vector.begin(), node_distance_map_vector.end(), 0); + try + { + typedef detail::gursoy_shortest< EdgeWeightMap > shortest; + shortest::run( + graph, min_distance_loc, node_distance, update_position, weight); + } + catch (const detail::over_distance_limit&) + { + /* Thrown to break out of BFS or Dijkstra early */ } - min_distance_unset = false; - } - BOOST_ASSERT (!min_distance_unset); // Graph must have at least one vertex - boost::detail::update_position_visitor< - PositionMap, NodeDistanceMap, Topology, - VertexListAndIncidenceGraph> - update_position(position, node_distance, space, - input_vector, diameter, learning_constant, - exp(-1. / (2 * diameter * diameter))); - std::fill(node_distance_map_vector.begin(), node_distance_map_vector.end(), 0); - try { - typedef detail::gursoy_shortest shortest; - shortest::run(graph, min_distance_loc, node_distance, update_position, - weight); - } catch (const detail::over_distance_limit&) { - /* Thrown to break out of BFS or Dijkstra early */ - } } -template -void gursoy_atun_refine(const VertexListAndIncidenceGraph& graph, - const Topology& space, - PositionMap position, - int nsteps, - double diameter_initial, - double diameter_final, - double learning_constant_initial, - double learning_constant_final, - VertexIndexMap vertex_index_map, - EdgeWeightMap weight) +template < typename VertexListAndIncidenceGraph, typename Topology, + typename PositionMap, typename VertexIndexMap, typename EdgeWeightMap > +void gursoy_atun_refine(const VertexListAndIncidenceGraph& graph, + const Topology& space, PositionMap position, int nsteps, + double diameter_initial, double diameter_final, + double learning_constant_initial, double learning_constant_final, + VertexIndexMap vertex_index_map, EdgeWeightMap weight) { #ifndef BOOST_NO_STDC_NAMESPACE - using std::pow; - using std::exp; + using std::exp; + using std::pow; #endif - typedef typename graph_traits::vertex_iterator - vertex_iterator; - vertex_iterator i, iend; - double diameter_ratio = (double)diameter_final / diameter_initial; - double learning_constant_ratio = - learning_constant_final / learning_constant_initial; - std::vector distance_from_input_vector(num_vertices(graph)); - typedef boost::iterator_property_map::iterator, - VertexIndexMap, - double, double&> - DistanceFromInputMap; - DistanceFromInputMap distance_from_input(distance_from_input_vector.begin(), - vertex_index_map); - std::vector node_distance_map_vector(num_vertices(graph)); - typedef boost::iterator_property_map::iterator, - VertexIndexMap, double, double&> - NodeDistanceMap; - NodeDistanceMap node_distance(node_distance_map_vector.begin(), - vertex_index_map); - for (int round = 0; round < nsteps; ++round) { - double part_done = (double)round / (nsteps - 1); - // fprintf(stderr, "%2d%% done\n", int(rint(part_done * 100.))); - int diameter = (int)(diameter_initial * pow(diameter_ratio, part_done)); - double learning_constant = - learning_constant_initial * pow(learning_constant_ratio, part_done); - gursoy_atun_step(graph, space, position, diameter, learning_constant, - vertex_index_map, weight); - } + typedef + typename graph_traits< VertexListAndIncidenceGraph >::vertex_iterator + vertex_iterator; + vertex_iterator i, iend; + double diameter_ratio = (double)diameter_final / diameter_initial; + double learning_constant_ratio + = learning_constant_final / learning_constant_initial; + std::vector< double > distance_from_input_vector(num_vertices(graph)); + typedef boost::iterator_property_map< std::vector< double >::iterator, + VertexIndexMap, double, double& > + DistanceFromInputMap; + DistanceFromInputMap distance_from_input( + distance_from_input_vector.begin(), vertex_index_map); + std::vector< int > node_distance_map_vector(num_vertices(graph)); + typedef boost::iterator_property_map< std::vector< int >::iterator, + VertexIndexMap, double, double& > + NodeDistanceMap; + NodeDistanceMap node_distance( + node_distance_map_vector.begin(), vertex_index_map); + for (int round = 0; round < nsteps; ++round) + { + double part_done = (double)round / (nsteps - 1); + // fprintf(stderr, "%2d%% done\n", int(rint(part_done * 100.))); + int diameter = (int)(diameter_initial * pow(diameter_ratio, part_done)); + double learning_constant = learning_constant_initial + * pow(learning_constant_ratio, part_done); + gursoy_atun_step(graph, space, position, diameter, learning_constant, + vertex_index_map, weight); + } } -template -void gursoy_atun_layout(const VertexListAndIncidenceGraph& graph, - const Topology& space, - PositionMap position, - int nsteps, - double diameter_initial, - double diameter_final, - double learning_constant_initial, - double learning_constant_final, - VertexIndexMap vertex_index_map, - EdgeWeightMap weight) +template < typename VertexListAndIncidenceGraph, typename Topology, + typename PositionMap, typename VertexIndexMap, typename EdgeWeightMap > +void gursoy_atun_layout(const VertexListAndIncidenceGraph& graph, + const Topology& space, PositionMap position, int nsteps, + double diameter_initial, double diameter_final, + double learning_constant_initial, double learning_constant_final, + VertexIndexMap vertex_index_map, EdgeWeightMap weight) { - typedef typename graph_traits::vertex_iterator - vertex_iterator; - vertex_iterator i, iend; - for (boost::tie(i, iend) = vertices(graph); i != iend; ++i) { - put(position, *i, space.random_point()); - } - gursoy_atun_refine(graph, space, - position, nsteps, - diameter_initial, diameter_final, - learning_constant_initial, learning_constant_final, - vertex_index_map, weight); + typedef + typename graph_traits< VertexListAndIncidenceGraph >::vertex_iterator + vertex_iterator; + vertex_iterator i, iend; + for (boost::tie(i, iend) = vertices(graph); i != iend; ++i) + { + put(position, *i, space.random_point()); + } + gursoy_atun_refine(graph, space, position, nsteps, diameter_initial, + diameter_final, learning_constant_initial, learning_constant_final, + vertex_index_map, weight); } -template -void gursoy_atun_layout(const VertexListAndIncidenceGraph& graph, - const Topology& space, - PositionMap position, - int nsteps, - double diameter_initial, - double diameter_final, - double learning_constant_initial, - double learning_constant_final, - VertexIndexMap vertex_index_map) +template < typename VertexListAndIncidenceGraph, typename Topology, + typename PositionMap, typename VertexIndexMap > +void gursoy_atun_layout(const VertexListAndIncidenceGraph& graph, + const Topology& space, PositionMap position, int nsteps, + double diameter_initial, double diameter_final, + double learning_constant_initial, double learning_constant_final, + VertexIndexMap vertex_index_map) { - gursoy_atun_layout(graph, space, position, nsteps, - diameter_initial, diameter_final, - learning_constant_initial, learning_constant_final, - vertex_index_map, dummy_property_map()); + gursoy_atun_layout(graph, space, position, nsteps, diameter_initial, + diameter_final, learning_constant_initial, learning_constant_final, + vertex_index_map, dummy_property_map()); } -template -void gursoy_atun_layout(const VertexListAndIncidenceGraph& graph, - const Topology& space, - PositionMap position, - int nsteps, - double diameter_initial, - double diameter_final = 1.0, - double learning_constant_initial = 0.8, - double learning_constant_final = 0.2) -{ - gursoy_atun_layout(graph, space, position, nsteps, diameter_initial, - diameter_final, learning_constant_initial, - learning_constant_final, get(vertex_index, graph)); +template < typename VertexListAndIncidenceGraph, typename Topology, + typename PositionMap > +void gursoy_atun_layout(const VertexListAndIncidenceGraph& graph, + const Topology& space, PositionMap position, int nsteps, + double diameter_initial, double diameter_final = 1.0, + double learning_constant_initial = 0.8, + double learning_constant_final = 0.2) +{ + gursoy_atun_layout(graph, space, position, nsteps, diameter_initial, + diameter_final, learning_constant_initial, learning_constant_final, + get(vertex_index, graph)); } -template -void gursoy_atun_layout(const VertexListAndIncidenceGraph& graph, - const Topology& space, - PositionMap position, - int nsteps) +template < typename VertexListAndIncidenceGraph, typename Topology, + typename PositionMap > +void gursoy_atun_layout(const VertexListAndIncidenceGraph& graph, + const Topology& space, PositionMap position, int nsteps) { #ifndef BOOST_NO_STDC_NAMESPACE - using std::sqrt; + using std::sqrt; #endif - gursoy_atun_layout(graph, space, position, nsteps, - sqrt((double)num_vertices(graph))); + gursoy_atun_layout( + graph, space, position, nsteps, sqrt((double)num_vertices(graph))); } -template -void gursoy_atun_layout(const VertexListAndIncidenceGraph& graph, - const Topology& space, - PositionMap position) +template < typename VertexListAndIncidenceGraph, typename Topology, + typename PositionMap > +void gursoy_atun_layout(const VertexListAndIncidenceGraph& graph, + const Topology& space, PositionMap position) { - gursoy_atun_layout(graph, space, position, num_vertices(graph)); + gursoy_atun_layout(graph, space, position, num_vertices(graph)); } -template -void -gursoy_atun_layout(const VertexListAndIncidenceGraph& graph, - const Topology& space, - PositionMap position, - const bgl_named_params& params) +template < typename VertexListAndIncidenceGraph, typename Topology, + typename PositionMap, typename P, typename T, typename R > +void gursoy_atun_layout(const VertexListAndIncidenceGraph& graph, + const Topology& space, PositionMap position, + const bgl_named_params< P, T, R >& params) { #ifndef BOOST_NO_STDC_NAMESPACE - using std::sqrt; + using std::sqrt; #endif - std::pair diam(sqrt(double(num_vertices(graph))), 1.0); - std::pair learn(0.8, 0.2); - gursoy_atun_layout(graph, space, position, - choose_param(get_param(params, iterations_t()), - num_vertices(graph)), - choose_param(get_param(params, diameter_range_t()), - diam).first, - choose_param(get_param(params, diameter_range_t()), - diam).second, - choose_param(get_param(params, learning_constant_range_t()), - learn).first, - choose_param(get_param(params, learning_constant_range_t()), - learn).second, - choose_const_pmap(get_param(params, vertex_index), graph, - vertex_index), - choose_param(get_param(params, edge_weight), - dummy_property_map())); + std::pair< double, double > diam(sqrt(double(num_vertices(graph))), 1.0); + std::pair< double, double > learn(0.8, 0.2); + gursoy_atun_layout(graph, space, position, + choose_param(get_param(params, iterations_t()), num_vertices(graph)), + choose_param(get_param(params, diameter_range_t()), diam).first, + choose_param(get_param(params, diameter_range_t()), diam).second, + choose_param(get_param(params, learning_constant_range_t()), learn) + .first, + choose_param(get_param(params, learning_constant_range_t()), learn) + .second, + choose_const_pmap(get_param(params, vertex_index), graph, vertex_index), + choose_param(get_param(params, edge_weight), dummy_property_map())); } } // namespace boost diff --git a/include/boost/graph/hawick_circuits.hpp b/include/boost/graph/hawick_circuits.hpp index 93c12b5c7..ba4065492 100644 --- a/include/boost/graph/hawick_circuits.hpp +++ b/include/boost/graph/hawick_circuits.hpp @@ -25,131 +25,141 @@ #include // for std::pair #include +namespace boost +{ +namespace hawick_circuits_detail +{ + //! @internal Functor returning all the vertices adjacent to a vertex. + struct get_all_adjacent_vertices + { + template < typename Sig > struct result; + + template < typename This, typename Vertex, typename Graph > + struct result< This(Vertex, Graph) > + { + private: + typedef typename remove_reference< Graph >::type RawGraph; + typedef graph_traits< RawGraph > Traits; + typedef typename Traits::adjacency_iterator AdjacencyIterator; + + public: + typedef std::pair< AdjacencyIterator, AdjacencyIterator > type; + }; + + template < typename Vertex, typename Graph > + typename result< get_all_adjacent_vertices( + BOOST_FWD_REF(Vertex), BOOST_FWD_REF(Graph)) >::type + operator()(BOOST_FWD_REF(Vertex) v, BOOST_FWD_REF(Graph) g) const + { + return adjacent_vertices( + boost::forward< Vertex >(v), boost::forward< Graph >(g)); + } + }; -namespace boost { -namespace hawick_circuits_detail { -//! @internal Functor returning all the vertices adjacent to a vertex. -struct get_all_adjacent_vertices { - template - struct result; + //! @internal Functor returning a set of the vertices adjacent to a vertex. + struct get_unique_adjacent_vertices + { + template < typename Sig > struct result; - template - struct result { - private: - typedef typename remove_reference::type RawGraph; - typedef graph_traits Traits; - typedef typename Traits::adjacency_iterator AdjacencyIterator; + template < typename This, typename Vertex, typename Graph > + struct result< This(Vertex, Graph) > + { + typedef std::set< typename remove_reference< Vertex >::type > type; + }; - public: - typedef std::pair type; + template < typename Vertex, typename Graph > + typename result< get_unique_adjacent_vertices( + Vertex, Graph const&) >::type + operator()(Vertex v, Graph const& g) const + { + typedef typename result< get_unique_adjacent_vertices( + Vertex, Graph const&) >::type Set; + return Set( + adjacent_vertices(v, g).first, adjacent_vertices(v, g).second); + } }; - template - typename result< - get_all_adjacent_vertices(BOOST_FWD_REF(Vertex), BOOST_FWD_REF(Graph)) - >::type - operator()(BOOST_FWD_REF(Vertex) v, BOOST_FWD_REF(Graph) g) const { - return adjacent_vertices(boost::forward(v), - boost::forward(g)); + //! @internal + //! Return whether a container contains a given value. + //! This is not meant as a general purpose membership testing function; it + //! would have to be more clever about possible optimizations. + template < typename Container, typename Value > + bool contains(Container const& c, Value const& v) + { + return std::find(boost::begin(c), boost::end(c), v) != boost::end(c); } -}; - -//! @internal Functor returning a set of the vertices adjacent to a vertex. -struct get_unique_adjacent_vertices { - template - struct result; - template - struct result { - typedef std::set::type> type; - }; + /*! + * @internal + * Algorithm finding all the cycles starting from a given vertex. + * + * The search is only done in the subgraph induced by the starting vertex + * and the vertices with an index higher than the starting vertex. + */ + template < typename Graph, typename Visitor, typename VertexIndexMap, + typename Stack, typename ClosedMatrix, typename GetAdjacentVertices > + struct hawick_circuits_from + { + private: + typedef graph_traits< Graph > Traits; + typedef typename Traits::vertex_descriptor Vertex; + typedef typename Traits::edge_descriptor Edge; + typedef typename Traits::vertices_size_type VerticesSize; + typedef + typename property_traits< VertexIndexMap >::value_type VertexIndex; + + typedef typename result_of< GetAdjacentVertices( + Vertex, Graph const&) >::type AdjacentVertices; + typedef typename range_iterator< AdjacentVertices const >::type + AdjacencyIterator; + + // The one_bit_color_map starts all white, i.e. not blocked. + // Since we make that assumption (I looked at the implementation, but + // I can't find anything that documents this behavior), we're gonna + // assert it in the constructor. + typedef one_bit_color_map< VertexIndexMap > BlockedMap; + typedef typename property_traits< BlockedMap >::value_type BlockedColor; + + static BlockedColor blocked_false_color() + { + return color_traits< BlockedColor >::white(); + } - template - typename result::type - operator()(Vertex v, Graph const& g) const { - typedef typename result< - get_unique_adjacent_vertices(Vertex, Graph const&) - >::type Set; - return Set(adjacent_vertices(v, g).first, - adjacent_vertices(v, g).second); - } -}; - -//! @internal -//! Return whether a container contains a given value. -//! This is not meant as a general purpose membership testing function; it -//! would have to be more clever about possible optimizations. -template -bool contains(Container const& c, Value const& v) { - return std::find(boost::begin(c), boost::end(c), v) != boost::end(c); -} + static BlockedColor blocked_true_color() + { + return color_traits< BlockedColor >::black(); + } -/*! - * @internal - * Algorithm finding all the cycles starting from a given vertex. - * - * The search is only done in the subgraph induced by the starting vertex - * and the vertices with an index higher than the starting vertex. - */ -template < - typename Graph, - typename Visitor, - typename VertexIndexMap, - typename Stack, - typename ClosedMatrix, - typename GetAdjacentVertices -> -struct hawick_circuits_from { -private: - typedef graph_traits Traits; - typedef typename Traits::vertex_descriptor Vertex; - typedef typename Traits::edge_descriptor Edge; - typedef typename Traits::vertices_size_type VerticesSize; - typedef typename property_traits::value_type VertexIndex; - - typedef typename result_of< - GetAdjacentVertices(Vertex, Graph const&) - >::type AdjacentVertices; - typedef typename range_iterator::type AdjacencyIterator; - - // The one_bit_color_map starts all white, i.e. not blocked. - // Since we make that assumption (I looked at the implementation, but - // I can't find anything that documents this behavior), we're gonna - // assert it in the constructor. - typedef one_bit_color_map BlockedMap; - typedef typename property_traits::value_type BlockedColor; - - static BlockedColor blocked_false_color() - { return color_traits::white(); } - - static BlockedColor blocked_true_color() - { return color_traits::black(); } - - // This is used by the constructor to secure the assumption - // documented above. - bool blocked_map_starts_all_unblocked() const { - BOOST_FOREACH(Vertex v, vertices(graph_)) - if (is_blocked(v)) - return false; - return true; - } + // This is used by the constructor to secure the assumption + // documented above. + bool blocked_map_starts_all_unblocked() const + { + BOOST_FOREACH (Vertex v, vertices(graph_)) + if (is_blocked(v)) + return false; + return true; + } - // This is only used in the constructor to make sure the optimization of - // sharing data structures between iterations does not break the code. - bool all_closed_rows_are_empty() const { - BOOST_FOREACH(typename ClosedMatrix::reference row, closed_) - if (!row.empty()) - return false; - return true; - } + // This is only used in the constructor to make sure the optimization of + // sharing data structures between iterations does not break the code. + bool all_closed_rows_are_empty() const + { + BOOST_FOREACH (typename ClosedMatrix::reference row, closed_) + if (!row.empty()) + return false; + return true; + } -public: - hawick_circuits_from(Graph const& graph, Visitor& visitor, - VertexIndexMap const& vim, - Stack& stack, ClosedMatrix& closed, - VerticesSize n_vertices) - : graph_(graph), visitor_(visitor), vim_(vim), stack_(stack), - closed_(closed), blocked_(n_vertices, vim_) + public: + hawick_circuits_from(Graph const& graph, Visitor& visitor, + VertexIndexMap const& vim, Stack& stack, ClosedMatrix& closed, + VerticesSize n_vertices) + : graph_(graph) + , visitor_(visitor) + , vim_(vim) + , stack_(stack) + , closed_(closed) + , blocked_(n_vertices, vim_) { BOOST_ASSERT(blocked_map_starts_all_unblocked()); @@ -161,220 +171,216 @@ struct hawick_circuits_from { BOOST_ASSERT(all_closed_rows_are_empty()); } -private: - //! @internal Return the index of a given vertex. - VertexIndex index_of(Vertex v) const { - return get(vim_, v); - } - - - //! @internal Return whether a vertex `v` is closed to a vertex `u`. - bool is_closed_to(Vertex u, Vertex v) const { - typedef typename ClosedMatrix::const_reference VertexList; - VertexList closed_to_u = closed_[index_of(u)]; - return contains(closed_to_u, v); - } + private: + //! @internal Return the index of a given vertex. + VertexIndex index_of(Vertex v) const { return get(vim_, v); } - //! @internal Close a vertex `v` to a vertex `u`. - void close_to(Vertex u, Vertex v) { - BOOST_ASSERT(!is_closed_to(u, v)); - closed_[index_of(u)].push_back(v); - } + //! @internal Return whether a vertex `v` is closed to a vertex `u`. + bool is_closed_to(Vertex u, Vertex v) const + { + typedef typename ClosedMatrix::const_reference VertexList; + VertexList closed_to_u = closed_[index_of(u)]; + return contains(closed_to_u, v); + } + //! @internal Close a vertex `v` to a vertex `u`. + void close_to(Vertex u, Vertex v) + { + BOOST_ASSERT(!is_closed_to(u, v)); + closed_[index_of(u)].push_back(v); + } - //! @internal Return whether a given vertex is blocked. - bool is_blocked(Vertex v) const { - return get(blocked_, v) == blocked_true_color(); - } + //! @internal Return whether a given vertex is blocked. + bool is_blocked(Vertex v) const + { + return get(blocked_, v) == blocked_true_color(); + } - //! @internal Block a given vertex. - void block(Vertex v) { - put(blocked_, v, blocked_true_color()); - } + //! @internal Block a given vertex. + void block(Vertex v) { put(blocked_, v, blocked_true_color()); } - //! @internal Unblock a given vertex. - void unblock(Vertex u) { - typedef typename ClosedMatrix::reference VertexList; + //! @internal Unblock a given vertex. + void unblock(Vertex u) + { + typedef typename ClosedMatrix::reference VertexList; - put(blocked_, u, blocked_false_color()); - VertexList closed_to_u = closed_[index_of(u)]; + put(blocked_, u, blocked_false_color()); + VertexList closed_to_u = closed_[index_of(u)]; - while (!closed_to_u.empty()) { - Vertex const w = closed_to_u.back(); - closed_to_u.pop_back(); - if (is_blocked(w)) - unblock(w); + while (!closed_to_u.empty()) + { + Vertex const w = closed_to_u.back(); + closed_to_u.pop_back(); + if (is_blocked(w)) + unblock(w); + } + BOOST_ASSERT(closed_to_u.empty()); } - BOOST_ASSERT(closed_to_u.empty()); - } - - //! @internal Main procedure as described in the paper. - bool circuit(Vertex start, Vertex v) { - bool found_circuit = false; - stack_.push_back(v); - block(v); - - // Cache some values that are used more than once in the function. - VertexIndex const index_of_start = index_of(start); - AdjacentVertices const adj_vertices = GetAdjacentVertices()(v, graph_); - AdjacencyIterator const w_end = boost::end(adj_vertices); - for (AdjacencyIterator w_it = boost::begin(adj_vertices); - w_it != w_end; - ++w_it) + //! @internal Main procedure as described in the paper. + bool circuit(Vertex start, Vertex v) { - Vertex const w = *w_it; - // Since we're only looking in the subgraph induced by `start` - // and the vertices with an index higher than `start`, we skip - // any vertex that does not satisfy that. - if (index_of(w) < index_of_start) - continue; - - // If the last vertex is equal to `start`, we have a circuit. - else if (w == start) { - // const_cast to ensure the visitor does not modify the stack - visitor_.cycle(const_cast(stack_), graph_); - found_circuit = true; - } + bool found_circuit = false; + stack_.push_back(v); + block(v); - // If `w` is not blocked, we continue searching further down the - // same path for a cycle with `w` in it. - else if (!is_blocked(w) && circuit(start, w)) - found_circuit = true; - } + // Cache some values that are used more than once in the function. + VertexIndex const index_of_start = index_of(start); + AdjacentVertices const adj_vertices + = GetAdjacentVertices()(v, graph_); + AdjacencyIterator const w_end = boost::end(adj_vertices); - if (found_circuit) - unblock(v); - else for (AdjacencyIterator w_it = boost::begin(adj_vertices); - w_it != w_end; - ++w_it) + w_it != w_end; ++w_it) { Vertex const w = *w_it; - // Like above, we skip vertices that are not in the subgraph - // we're considering. + // Since we're only looking in the subgraph induced by `start` + // and the vertices with an index higher than `start`, we skip + // any vertex that does not satisfy that. if (index_of(w) < index_of_start) continue; - // If `v` is not closed to `w`, we make it so. - if (!is_closed_to(w, v)) - close_to(w, v); + // If the last vertex is equal to `start`, we have a circuit. + else if (w == start) + { + // const_cast to ensure the visitor does not modify the + // stack + visitor_.cycle(const_cast< Stack const& >(stack_), graph_); + found_circuit = true; + } + + // If `w` is not blocked, we continue searching further down the + // same path for a cycle with `w` in it. + else if (!is_blocked(w) && circuit(start, w)) + found_circuit = true; } - BOOST_ASSERT(v == stack_.back()); - stack_.pop_back(); - return found_circuit; - } + if (found_circuit) + unblock(v); + else + for (AdjacencyIterator w_it = boost::begin(adj_vertices); + w_it != w_end; ++w_it) + { + Vertex const w = *w_it; + // Like above, we skip vertices that are not in the subgraph + // we're considering. + if (index_of(w) < index_of_start) + continue; + + // If `v` is not closed to `w`, we make it so. + if (!is_closed_to(w, v)) + close_to(w, v); + } + + BOOST_ASSERT(v == stack_.back()); + stack_.pop_back(); + return found_circuit; + } -public: - void operator()(Vertex start) { - circuit(start, start); - } + public: + void operator()(Vertex start) { circuit(start, start); } -private: - Graph const& graph_; - Visitor& visitor_; - VertexIndexMap const& vim_; - Stack& stack_; - ClosedMatrix& closed_; - BlockedMap blocked_; -}; - -template < - typename GetAdjacentVertices, - typename Graph, typename Visitor, typename VertexIndexMap -> -void call_hawick_circuits(Graph const& graph, - Visitor /* by value */ visitor, - VertexIndexMap const& vertex_index_map) { - typedef graph_traits Traits; - typedef typename Traits::vertex_descriptor Vertex; - typedef typename Traits::vertices_size_type VerticesSize; - typedef typename Traits::vertex_iterator VertexIterator; - - typedef std::vector Stack; - typedef std::vector > ClosedMatrix; - - typedef hawick_circuits_from< - Graph, Visitor, VertexIndexMap, Stack, ClosedMatrix, - GetAdjacentVertices - > SubAlgorithm; - - VerticesSize const n_vertices = num_vertices(graph); - Stack stack; stack.reserve(n_vertices); - ClosedMatrix closed(n_vertices); - - VertexIterator start, last; - for (boost::tie(start, last) = vertices(graph); start != last; ++start) { - // Note1: The sub algorithm may NOT be reused once it has been called. - - // Note2: We reuse the Stack and the ClosedMatrix (after clearing them) - // in each iteration to avoid redundant destruction and construction. - // It would be strictly equivalent to have these as member variables - // of the sub algorithm. - SubAlgorithm sub_algo(graph, visitor, vertex_index_map, - stack, closed, n_vertices); - sub_algo(*start); - stack.clear(); - typename ClosedMatrix::iterator row, last_row = closed.end(); - for (row = closed.begin(); row != last_row; ++row) - row->clear(); + private: + Graph const& graph_; + Visitor& visitor_; + VertexIndexMap const& vim_; + Stack& stack_; + ClosedMatrix& closed_; + BlockedMap blocked_; + }; + + template < typename GetAdjacentVertices, typename Graph, typename Visitor, + typename VertexIndexMap > + void call_hawick_circuits(Graph const& graph, + Visitor /* by value */ visitor, VertexIndexMap const& vertex_index_map) + { + typedef graph_traits< Graph > Traits; + typedef typename Traits::vertex_descriptor Vertex; + typedef typename Traits::vertices_size_type VerticesSize; + typedef typename Traits::vertex_iterator VertexIterator; + + typedef std::vector< Vertex > Stack; + typedef std::vector< std::vector< Vertex > > ClosedMatrix; + + typedef hawick_circuits_from< Graph, Visitor, VertexIndexMap, Stack, + ClosedMatrix, GetAdjacentVertices > + SubAlgorithm; + + VerticesSize const n_vertices = num_vertices(graph); + Stack stack; + stack.reserve(n_vertices); + ClosedMatrix closed(n_vertices); + + VertexIterator start, last; + for (boost::tie(start, last) = vertices(graph); start != last; ++start) + { + // Note1: The sub algorithm may NOT be reused once it has been + // called. + + // Note2: We reuse the Stack and the ClosedMatrix (after clearing + // them) in each iteration to avoid redundant destruction and + // construction. It would be strictly equivalent to have these as + // member variables of the sub algorithm. + SubAlgorithm sub_algo( + graph, visitor, vertex_index_map, stack, closed, n_vertices); + sub_algo(*start); + stack.clear(); + typename ClosedMatrix::iterator row, last_row = closed.end(); + for (row = closed.begin(); row != last_row; ++row) + row->clear(); + } } -} -template -void call_hawick_circuits(Graph const& graph, BOOST_FWD_REF(Visitor) visitor) { - call_hawick_circuits( - graph, boost::forward(visitor), get(vertex_index, graph) - ); -} + template < typename GetAdjacentVertices, typename Graph, typename Visitor > + void call_hawick_circuits( + Graph const& graph, BOOST_FWD_REF(Visitor) visitor) + { + call_hawick_circuits< GetAdjacentVertices >(graph, + boost::forward< Visitor >(visitor), get(vertex_index, graph)); + } } // end namespace hawick_circuits_detail //! Enumerate all the elementary circuits in a directed multigraph. -template -void hawick_circuits(BOOST_FWD_REF(Graph) graph, - BOOST_FWD_REF(Visitor) visitor, - BOOST_FWD_REF(VertexIndexMap) vertex_index_map) { +template < typename Graph, typename Visitor, typename VertexIndexMap > +void hawick_circuits(BOOST_FWD_REF(Graph) graph, BOOST_FWD_REF(Visitor) visitor, + BOOST_FWD_REF(VertexIndexMap) vertex_index_map) +{ hawick_circuits_detail::call_hawick_circuits< - hawick_circuits_detail::get_all_adjacent_vertices - >( - boost::forward(graph), - boost::forward(visitor), - boost::forward(vertex_index_map) - ); + hawick_circuits_detail::get_all_adjacent_vertices >( + boost::forward< Graph >(graph), boost::forward< Visitor >(visitor), + boost::forward< VertexIndexMap >(vertex_index_map)); } -template -void hawick_circuits(BOOST_FWD_REF(Graph) graph, - BOOST_FWD_REF(Visitor) visitor) { +template < typename Graph, typename Visitor > +void hawick_circuits(BOOST_FWD_REF(Graph) graph, BOOST_FWD_REF(Visitor) visitor) +{ hawick_circuits_detail::call_hawick_circuits< - hawick_circuits_detail::get_all_adjacent_vertices - >(boost::forward(graph), boost::forward(visitor)); + hawick_circuits_detail::get_all_adjacent_vertices >( + boost::forward< Graph >(graph), boost::forward< Visitor >(visitor)); } /*! * Same as `boost::hawick_circuits`, but duplicate circuits caused by parallel * edges will not be considered. Each circuit will be considered only once. */ -template +template < typename Graph, typename Visitor, typename VertexIndexMap > void hawick_unique_circuits(BOOST_FWD_REF(Graph) graph, - BOOST_FWD_REF(Visitor) visitor, - BOOST_FWD_REF(VertexIndexMap) vertex_index_map) { + BOOST_FWD_REF(Visitor) visitor, + BOOST_FWD_REF(VertexIndexMap) vertex_index_map) +{ hawick_circuits_detail::call_hawick_circuits< - hawick_circuits_detail::get_unique_adjacent_vertices - >( - boost::forward(graph), - boost::forward(visitor), - boost::forward(vertex_index_map) - ); + hawick_circuits_detail::get_unique_adjacent_vertices >( + boost::forward< Graph >(graph), boost::forward< Visitor >(visitor), + boost::forward< VertexIndexMap >(vertex_index_map)); } -template -void hawick_unique_circuits(BOOST_FWD_REF(Graph) graph, - BOOST_FWD_REF(Visitor) visitor) { +template < typename Graph, typename Visitor > +void hawick_unique_circuits( + BOOST_FWD_REF(Graph) graph, BOOST_FWD_REF(Visitor) visitor) +{ hawick_circuits_detail::call_hawick_circuits< - hawick_circuits_detail::get_unique_adjacent_vertices - >(boost::forward(graph), boost::forward(visitor)); + hawick_circuits_detail::get_unique_adjacent_vertices >( + boost::forward< Graph >(graph), boost::forward< Visitor >(visitor)); } } // end namespace boost diff --git a/include/boost/graph/howard_cycle_ratio.hpp b/include/boost/graph/howard_cycle_ratio.hpp index afbf26d87..226df7148 100644 --- a/include/boost/graph/howard_cycle_ratio.hpp +++ b/include/boost/graph/howard_cycle_ratio.hpp @@ -28,437 +28,469 @@ * @author Andrey Parfenov */ -namespace boost { - - /** - * The mcr_float is like numeric_limits, but only for floating point types - * and only defines infinity() and epsilon(). This class is primarily used - * to encapsulate a less-precise epsilon than natively supported by the - * floating point type. - */ - template struct mcr_float { +namespace boost +{ + +/** + * The mcr_float is like numeric_limits, but only for floating point types + * and only defines infinity() and epsilon(). This class is primarily used + * to encapsulate a less-precise epsilon than natively supported by the + * floating point type. + */ +template < typename Float = double > struct mcr_float +{ typedef Float value_type; static Float infinity() - { return std::numeric_limits::infinity(); } + { + return std::numeric_limits< value_type >::infinity(); + } - static Float epsilon() - { return Float(-0.005); } - }; + static Float epsilon() { return Float(-0.005); } +}; - namespace detail { +namespace detail +{ - template struct - min_comparator_props { - typedef std::greater comparator; - static const int multiplier = 1; + template < typename FloatTraits > struct min_comparator_props + { + typedef std::greater< typename FloatTraits::value_type > comparator; + static const int multiplier = 1; }; - template struct - max_comparator_props { - typedef std::less comparator; - static const int multiplier = -1; + template < typename FloatTraits > struct max_comparator_props + { + typedef std::less< typename FloatTraits::value_type > comparator; + static const int multiplier = -1; }; - template - struct float_wrapper { - typedef typename FloatTraits::value_type value_type; - typedef ComparatorProps comparator_props_t; - typedef typename ComparatorProps::comparator comparator; - - static value_type infinity() - { return FloatTraits::infinity() * ComparatorProps::multiplier; } - - static value_type epsilon() - { return FloatTraits::epsilon() * ComparatorProps::multiplier; } - + template < typename FloatTraits, typename ComparatorProps > + struct float_wrapper + { + typedef typename FloatTraits::value_type value_type; + typedef ComparatorProps comparator_props_t; + typedef typename ComparatorProps::comparator comparator; + + static value_type infinity() + { + return FloatTraits::infinity() * ComparatorProps::multiplier; + } + + static value_type epsilon() + { + return FloatTraits::epsilon() * ComparatorProps::multiplier; + } }; /*! @class mcr_howard - * @brief Calculates optimum (maximum/minimum) cycle ratio of a directed graph. - * Uses Howard's iteration policy algorithm.
    (It is described in the paper - * "Experimental Analysis of the Fastest Optimum Cycle Ratio and Mean Algorithm" - * by Ali Dasdan). + * @brief Calculates optimum (maximum/minimum) cycle ratio of a directed + * graph. Uses Howard's iteration policy algorithm.
    (It is described + * in the paper "Experimental Analysis of the Fastest Optimum Cycle Ratio + * and Mean Algorithm" by Ali Dasdan). */ - template + template < typename FloatTraits, typename Graph, typename VertexIndexMap, + typename EdgeWeight1, typename EdgeWeight2 > class mcr_howard { public: - typedef typename FloatTraits::value_type float_t; - typedef typename FloatTraits::comparator_props_t cmp_props_t; - typedef typename FloatTraits::comparator comparator_t; - typedef enum{ my_white = 0, my_black } my_color_type; - typedef typename graph_traits::vertex_descriptor vertex_t; - typedef typename graph_traits::edge_descriptor edge_t; - typedef typename graph_traits::vertices_size_type vn_t; - typedef std::vector vp_t; - typedef typename boost::iterator_property_map< - typename vp_t::iterator, VertexIndexMap - > distance_map_t; //V -> float_t - - typedef typename std::vector ve_t; - typedef std::vector vcol_t; - typedef typename ::boost::iterator_property_map< - typename ve_t::iterator, VertexIndexMap - > policy_t; //Vertex -> Edge - typedef typename ::boost::iterator_property_map< - typename vcol_t::iterator, VertexIndexMap - > color_map_t; - - typedef typename std::list pinel_t;// The in_edges list of the policy graph - typedef typename std::vector inedges1_t; - typedef typename ::boost::iterator_property_map< - typename inedges1_t::iterator, VertexIndexMap - > inedges_t; - typedef typename std::vector critical_cycle_t; - - //Bad vertex flag. If true, then the vertex is "bad". - // Vertex is "bad" if its out_degree is equal to zero. - typedef typename boost::iterator_property_map< - std::vector::iterator, VertexIndexMap - > badv_t; - - /*! - * Constructor - * \param g = (V, E) - a directed multigraph. - * \param vim Vertex Index Map. Read property Map: V -> [0, num_vertices(g)). - * \param ewm edge weight map. Read property map: E -> R - * \param ew2m edge weight map. Read property map: E -> R+ - * \param infty A big enough value to guaranty that there exist a cycle with - * better ratio. - * \param cmp The compare operator for float_ts. - */ - mcr_howard(const Graph &g, VertexIndexMap vim, - EdgeWeight1 ewm, EdgeWeight2 ew2m) : - m_g(g), m_vim(vim), m_ew1m(ewm), m_ew2m(ew2m), - m_bound(mcr_bound()), - m_cr(m_bound), - m_V(num_vertices(m_g)), - m_dis(m_V, 0), m_dm(m_dis.begin(), m_vim), - m_policyc(m_V), m_policy(m_policyc.begin(), m_vim), - m_inelc(m_V), m_inel(m_inelc.begin(), m_vim), - m_badvc(m_V, false), m_badv(m_badvc.begin(), m_vim), - m_colcv(m_V), - m_col_bfs(m_V) - { } - - /*! - * \return maximum/minimum_{for all cycles C} - * [sum_{e in C} w1(e)] / [sum_{e in C} w2(e)], - * or FloatTraits::infinity() if graph has no cycles. - */ - float_t ocr_howard() - { - construct_policy_graph(); - int k = 0; - float_t mcr = 0; - do - { - mcr = policy_mcr(); - ++k; - } - while (try_improve_policy(mcr) && k < 100); //To avoid infinite loop - - const float_t eps_ = -0.00000001 * cmp_props_t::multiplier; - if (m_cmp(mcr, m_bound + eps_)) - { - return FloatTraits::infinity(); - } - else - { - return mcr; - } - } - virtual ~mcr_howard() {} + typedef typename FloatTraits::value_type float_t; + typedef typename FloatTraits::comparator_props_t cmp_props_t; + typedef typename FloatTraits::comparator comparator_t; + typedef enum + { + my_white = 0, + my_black + } my_color_type; + typedef typename graph_traits< Graph >::vertex_descriptor vertex_t; + typedef typename graph_traits< Graph >::edge_descriptor edge_t; + typedef typename graph_traits< Graph >::vertices_size_type vn_t; + typedef std::vector< float_t > vp_t; + typedef typename boost::iterator_property_map< typename vp_t::iterator, + VertexIndexMap > + distance_map_t; // V -> float_t + + typedef typename std::vector< edge_t > ve_t; + typedef std::vector< my_color_type > vcol_t; + typedef + typename ::boost::iterator_property_map< typename ve_t::iterator, + VertexIndexMap > + policy_t; // Vertex -> Edge + typedef + typename ::boost::iterator_property_map< typename vcol_t::iterator, + VertexIndexMap > + color_map_t; + + typedef typename std::list< vertex_t > + pinel_t; // The in_edges list of the policy graph + typedef typename std::vector< pinel_t > inedges1_t; + typedef typename ::boost::iterator_property_map< + typename inedges1_t::iterator, VertexIndexMap > + inedges_t; + typedef typename std::vector< edge_t > critical_cycle_t; + + // Bad vertex flag. If true, then the vertex is "bad". + // Vertex is "bad" if its out_degree is equal to zero. + typedef + typename boost::iterator_property_map< std::vector< int >::iterator, + VertexIndexMap > + badv_t; + + /*! + * Constructor + * \param g = (V, E) - a directed multigraph. + * \param vim Vertex Index Map. Read property Map: V -> [0, + * num_vertices(g)). \param ewm edge weight map. Read property map: E + * -> R \param ew2m edge weight map. Read property map: E -> R+ \param + * infty A big enough value to guaranty that there exist a cycle with + * better ratio. + * \param cmp The compare operator for float_ts. + */ + mcr_howard(const Graph& g, VertexIndexMap vim, EdgeWeight1 ewm, + EdgeWeight2 ew2m) + : m_g(g) + , m_vim(vim) + , m_ew1m(ewm) + , m_ew2m(ew2m) + , m_bound(mcr_bound()) + , m_cr(m_bound) + , m_V(num_vertices(m_g)) + , m_dis(m_V, 0) + , m_dm(m_dis.begin(), m_vim) + , m_policyc(m_V) + , m_policy(m_policyc.begin(), m_vim) + , m_inelc(m_V) + , m_inel(m_inelc.begin(), m_vim) + , m_badvc(m_V, false) + , m_badv(m_badvc.begin(), m_vim) + , m_colcv(m_V) + , m_col_bfs(m_V) + { + } + + /*! + * \return maximum/minimum_{for all cycles C} + * [sum_{e in C} w1(e)] / [sum_{e in C} w2(e)], + * or FloatTraits::infinity() if graph has no cycles. + */ + float_t ocr_howard() + { + construct_policy_graph(); + int k = 0; + float_t mcr = 0; + do + { + mcr = policy_mcr(); + ++k; + } while ( + try_improve_policy(mcr) && k < 100); // To avoid infinite loop + + const float_t eps_ = -0.00000001 * cmp_props_t::multiplier; + if (m_cmp(mcr, m_bound + eps_)) + { + return FloatTraits::infinity(); + } + else + { + return mcr; + } + } + virtual ~mcr_howard() {} protected: - virtual void store_critical_edge(edge_t, critical_cycle_t &) {} - virtual void store_critical_cycle(critical_cycle_t &) {} + virtual void store_critical_edge(edge_t, critical_cycle_t&) {} + virtual void store_critical_cycle(critical_cycle_t&) {} private: - /*! - * \return lower/upper bound for the maximal/minimal cycle ratio - */ - float_t mcr_bound() - { - typename graph_traits::vertex_iterator vi, vie; - typename graph_traits::out_edge_iterator oei, oeie; - float_t cz = (std::numeric_limits::max)(); //Closest to zero value - float_t s = 0; - const float_t eps_ = std::numeric_limits::epsilon(); - for (boost::tie(vi, vie) = vertices(m_g); vi != vie; ++vi) - { - for (boost::tie(oei, oeie) = out_edges(*vi, m_g); oei != oeie; ++oei) - { - s += std::abs(m_ew1m[*oei]); - float_t a = std::abs(m_ew2m[*oei]); - if ( a > eps_ && a < cz) + /*! + * \return lower/upper bound for the maximal/minimal cycle ratio + */ + float_t mcr_bound() + { + typename graph_traits< Graph >::vertex_iterator vi, vie; + typename graph_traits< Graph >::out_edge_iterator oei, oeie; + float_t cz = (std::numeric_limits< float_t >::max)(); // Closest to + // zero value + float_t s = 0; + const float_t eps_ = std::numeric_limits< float_t >::epsilon(); + for (boost::tie(vi, vie) = vertices(m_g); vi != vie; ++vi) + { + for (boost::tie(oei, oeie) = out_edges(*vi, m_g); oei != oeie; + ++oei) { - cz = a; + s += std::abs(m_ew1m[*oei]); + float_t a = std::abs(m_ew2m[*oei]); + if (a > eps_ && a < cz) + { + cz = a; + } } - } - } - return cmp_props_t::multiplier * (s / cz); - } - - - /*! - * Constructs an arbitrary policy graph. - */ - void construct_policy_graph() - { - m_sink = graph_traits().null_vertex(); - typename graph_traits::vertex_iterator vi, vie; - typename graph_traits::out_edge_iterator oei, oeie; - for ( boost::tie(vi, vie) = vertices(m_g); vi != vie; ++vi ) - { - boost::tie(oei, oeie) = out_edges(*vi, m_g); - typename graph_traits::out_edge_iterator mei = - std::max_element(oei, oeie, - boost::bind(m_cmp, - boost::bind(&EdgeWeight1::operator[], m_ew1m, _1), - boost::bind(&EdgeWeight1::operator[], m_ew1m, _2) - ) - ); - if (mei == oeie) - { - if (m_sink == graph_traits().null_vertex()) - { - m_sink = *vi; - } - m_badv[*vi] = true; - m_inel[m_sink].push_back(*vi); - } - else - { - m_inel[target(*mei, m_g)].push_back(*vi); - m_policy[*vi] = *mei; - } - } - } - /*! Sets the distance value for all vertices "v" such that there is - * a path from "v" to "sv". It does "inverse" breadth first visit of the policy - * graph, starting from the vertex "sv". - */ - void mcr_bfv(vertex_t sv, float_t cr, color_map_t c) - { - boost::queue Q; - c[sv] = my_black; - Q.push(sv); - while (!Q.empty()) - { - vertex_t v = Q.top(); Q.pop(); - for (typename pinel_t::const_iterator itr = m_inel[v].begin(); - itr != m_inel[v].end(); ++itr) - //For all in_edges of the policy graph - { - if (*itr != sv) - { - if (m_badv[*itr]) - { - m_dm[*itr] = m_dm[v] + m_bound - cr; - } - else - { - m_dm[*itr] = m_dm[v] + m_ew1m[m_policy[*itr]] - - m_ew2m[m_policy[*itr]] * cr; - } - c[*itr] = my_black; - Q.push(*itr); - } - } - } - } - - /*! - * \param sv an arbitrary (undiscovered) vertex of the policy graph. - * \return a vertex in the policy graph that belongs to a cycle. - * Performs a depth first visit until a cycle edge is found. - */ - vertex_t find_cycle_vertex(vertex_t sv) - { - vertex_t gv = sv; - std::fill(m_colcv.begin(), m_colcv.end(), my_white); - color_map_t cm(m_colcv.begin(), m_vim); - do - { - cm[gv] = my_black; - if (! m_badv[gv]) - { - gv = target(m_policy[gv], m_g); - } - else - { - gv = m_sink; - } - } - while (cm[gv] != my_black); - return gv; - } - - /*! - * \param sv - vertex that belongs to a cycle in the policy graph. - */ - float_t cycle_ratio(vertex_t sv) - { - if (sv == m_sink) return m_bound; - std::pair sums_(float_t(0), float_t(0)); - vertex_t v = sv; - critical_cycle_t cc; - do - { - store_critical_edge(m_policy[v], cc); - sums_.first += m_ew1m[m_policy[v]]; - sums_.second += m_ew2m[m_policy[v]]; - v = target(m_policy[v], m_g); - } - while (v != sv); - float_t cr = sums_.first / sums_.second; - if ( m_cmp(m_cr, cr) ) - { - m_cr = cr; - store_critical_cycle(cc); - } - return cr; - } - - /*! - * Finds the optimal cycle ratio of the policy graph - */ - float_t policy_mcr() - { - std::fill(m_col_bfs.begin(), m_col_bfs.end(), my_white); - color_map_t vcm_ = color_map_t(m_col_bfs.begin(), m_vim); - typename graph_traits::vertex_iterator uv_itr, vie; - boost::tie(uv_itr, vie) = vertices(m_g); - float_t mcr = m_bound; - while ( (uv_itr = std::find_if(uv_itr, vie, - boost::bind(std::equal_to(), - my_white, - boost::bind(&color_map_t::operator[], vcm_, _1) - ) - ) - ) != vie ) - ///While there are undiscovered vertices - { - vertex_t gv = find_cycle_vertex(*uv_itr); - float_t cr = cycle_ratio(gv) ; - mcr_bfv(gv, cr, vcm_); - if ( m_cmp(mcr, cr) ) mcr = cr; - ++uv_itr; - } - return mcr; - } - - /*! - * Changes the edge m_policy[s] to the new_edge. - */ - void improve_policy(vertex_t s, edge_t new_edge) - { - vertex_t t = target(m_policy[s], m_g); - typename property_traits::value_type ti = m_vim[t]; - m_inelc[ti].erase( std::find(m_inelc[ti].begin(), m_inelc[ti].end(), s)); - m_policy[s] = new_edge; - t = target(new_edge, m_g); - m_inel[t].push_back(s); ///Maintain in_edge list - } - - /*! - * A negative cycle detector. - */ - bool try_improve_policy(float_t cr) - { - bool improved = false; - typename graph_traits::vertex_iterator vi, vie; - typename graph_traits::out_edge_iterator oei, oeie; - const float_t eps_ = FloatTraits::epsilon(); - for (boost::tie(vi, vie) = vertices(m_g); vi != vie; ++vi) - { - if (!m_badv[*vi]) - { - for (boost::tie(oei, oeie) = out_edges(*vi, m_g); oei != oeie; ++oei) - { - vertex_t t = target(*oei, m_g); - //Current distance from *vi to some vertex - float_t dis_ = m_ew1m[*oei] - m_ew2m[*oei] * cr + m_dm[t]; - if ( m_cmp(m_dm[*vi] + eps_, dis_) ) - { - improve_policy(*vi, *oei); + } + return cmp_props_t::multiplier * (s / cz); + } + + /*! + * Constructs an arbitrary policy graph. + */ + void construct_policy_graph() + { + m_sink = graph_traits< Graph >().null_vertex(); + typename graph_traits< Graph >::vertex_iterator vi, vie; + typename graph_traits< Graph >::out_edge_iterator oei, oeie; + for (boost::tie(vi, vie) = vertices(m_g); vi != vie; ++vi) + { + boost::tie(oei, oeie) = out_edges(*vi, m_g); + typename graph_traits< Graph >::out_edge_iterator mei + = std::max_element(oei, oeie, + boost::bind(m_cmp, + boost::bind(&EdgeWeight1::operator[], m_ew1m, _1), + boost::bind(&EdgeWeight1::operator[], m_ew1m, _2))); + if (mei == oeie) + { + if (m_sink == graph_traits< Graph >().null_vertex()) + { + m_sink = *vi; + } + m_badv[*vi] = true; + m_inel[m_sink].push_back(*vi); + } + else + { + m_inel[target(*mei, m_g)].push_back(*vi); + m_policy[*vi] = *mei; + } + } + } + /*! Sets the distance value for all vertices "v" such that there is + * a path from "v" to "sv". It does "inverse" breadth first visit of the + * policy graph, starting from the vertex "sv". + */ + void mcr_bfv(vertex_t sv, float_t cr, color_map_t c) + { + boost::queue< vertex_t > Q; + c[sv] = my_black; + Q.push(sv); + while (!Q.empty()) + { + vertex_t v = Q.top(); + Q.pop(); + for (typename pinel_t::const_iterator itr = m_inel[v].begin(); + itr != m_inel[v].end(); ++itr) + // For all in_edges of the policy graph + { + if (*itr != sv) + { + if (m_badv[*itr]) + { + m_dm[*itr] = m_dm[v] + m_bound - cr; + } + else + { + m_dm[*itr] = m_dm[v] + m_ew1m[m_policy[*itr]] + - m_ew2m[m_policy[*itr]] * cr; + } + c[*itr] = my_black; + Q.push(*itr); + } + } + } + } + + /*! + * \param sv an arbitrary (undiscovered) vertex of the policy graph. + * \return a vertex in the policy graph that belongs to a cycle. + * Performs a depth first visit until a cycle edge is found. + */ + vertex_t find_cycle_vertex(vertex_t sv) + { + vertex_t gv = sv; + std::fill(m_colcv.begin(), m_colcv.end(), my_white); + color_map_t cm(m_colcv.begin(), m_vim); + do + { + cm[gv] = my_black; + if (!m_badv[gv]) + { + gv = target(m_policy[gv], m_g); + } + else + { + gv = m_sink; + } + } while (cm[gv] != my_black); + return gv; + } + + /*! + * \param sv - vertex that belongs to a cycle in the policy graph. + */ + float_t cycle_ratio(vertex_t sv) + { + if (sv == m_sink) + return m_bound; + std::pair< float_t, float_t > sums_(float_t(0), float_t(0)); + vertex_t v = sv; + critical_cycle_t cc; + do + { + store_critical_edge(m_policy[v], cc); + sums_.first += m_ew1m[m_policy[v]]; + sums_.second += m_ew2m[m_policy[v]]; + v = target(m_policy[v], m_g); + } while (v != sv); + float_t cr = sums_.first / sums_.second; + if (m_cmp(m_cr, cr)) + { + m_cr = cr; + store_critical_cycle(cc); + } + return cr; + } + + /*! + * Finds the optimal cycle ratio of the policy graph + */ + float_t policy_mcr() + { + std::fill(m_col_bfs.begin(), m_col_bfs.end(), my_white); + color_map_t vcm_ = color_map_t(m_col_bfs.begin(), m_vim); + typename graph_traits< Graph >::vertex_iterator uv_itr, vie; + boost::tie(uv_itr, vie) = vertices(m_g); + float_t mcr = m_bound; + while ((uv_itr = std::find_if(uv_itr, vie, + boost::bind(std::equal_to< my_color_type >(), my_white, + boost::bind(&color_map_t::operator[], vcm_, _1)))) + != vie) + /// While there are undiscovered vertices + { + vertex_t gv = find_cycle_vertex(*uv_itr); + float_t cr = cycle_ratio(gv); + mcr_bfv(gv, cr, vcm_); + if (m_cmp(mcr, cr)) + mcr = cr; + ++uv_itr; + } + return mcr; + } + + /*! + * Changes the edge m_policy[s] to the new_edge. + */ + void improve_policy(vertex_t s, edge_t new_edge) + { + vertex_t t = target(m_policy[s], m_g); + typename property_traits< VertexIndexMap >::value_type ti + = m_vim[t]; + m_inelc[ti].erase( + std::find(m_inelc[ti].begin(), m_inelc[ti].end(), s)); + m_policy[s] = new_edge; + t = target(new_edge, m_g); + m_inel[t].push_back(s); /// Maintain in_edge list + } + + /*! + * A negative cycle detector. + */ + bool try_improve_policy(float_t cr) + { + bool improved = false; + typename graph_traits< Graph >::vertex_iterator vi, vie; + typename graph_traits< Graph >::out_edge_iterator oei, oeie; + const float_t eps_ = FloatTraits::epsilon(); + for (boost::tie(vi, vie) = vertices(m_g); vi != vie; ++vi) + { + if (!m_badv[*vi]) + { + for (boost::tie(oei, oeie) = out_edges(*vi, m_g); + oei != oeie; ++oei) + { + vertex_t t = target(*oei, m_g); + // Current distance from *vi to some vertex + float_t dis_ + = m_ew1m[*oei] - m_ew2m[*oei] * cr + m_dm[t]; + if (m_cmp(m_dm[*vi] + eps_, dis_)) + { + improve_policy(*vi, *oei); + m_dm[*vi] = dis_; + improved = true; + } + } + } + else + { + float_t dis_ = m_bound - cr + m_dm[m_sink]; + if (m_cmp(m_dm[*vi] + eps_, dis_)) + { m_dm[*vi] = dis_; - improved = true; - } - } - } - else - { - float_t dis_ = m_bound - cr + m_dm[m_sink]; - if ( m_cmp(m_dm[*vi] + eps_, dis_) ) - { - m_dm[*vi] = dis_; - } - } - } - return improved; - } - private: - const Graph &m_g; - VertexIndexMap m_vim; - EdgeWeight1 m_ew1m; - EdgeWeight2 m_ew2m; - comparator_t m_cmp; - float_t m_bound; //> The lower/upper bound to the maximal/minimal cycle ratio - float_t m_cr; //>The best cycle ratio that has been found so far - - vn_t m_V; //>The number of the vertices in the graph - vp_t m_dis; //>Container for the distance map - distance_map_t m_dm; //>Distance map - - ve_t m_policyc; //>Container for the policy graph - policy_t m_policy; //>The interface for the policy graph - - inedges1_t m_inelc; //>Container fot in edges list - inedges_t m_inel; //>Policy graph, input edges list - - std::vector m_badvc; - badv_t m_badv; //Marks "bad" vertices + } + } + } + return improved; + } - vcol_t m_colcv, m_col_bfs; //Color maps - vertex_t m_sink; //To convert any graph to "good" + private: + const Graph& m_g; + VertexIndexMap m_vim; + EdgeWeight1 m_ew1m; + EdgeWeight2 m_ew2m; + comparator_t m_cmp; + float_t m_bound; //> The lower/upper bound to the maximal/minimal cycle + // ratio + float_t m_cr; //>The best cycle ratio that has been found so far + + vn_t m_V; //>The number of the vertices in the graph + vp_t m_dis; //>Container for the distance map + distance_map_t m_dm; //>Distance map + + ve_t m_policyc; //>Container for the policy graph + policy_t m_policy; //>The interface for the policy graph + + inedges1_t m_inelc; //>Container fot in edges list + inedges_t m_inel; //>Policy graph, input edges list + + std::vector< int > m_badvc; + badv_t m_badv; // Marks "bad" vertices + + vcol_t m_colcv, m_col_bfs; // Color maps + vertex_t m_sink; // To convert any graph to "good" }; /*! \class mcr_howard1 - * \brief Finds optimum cycle raio and a critical cycle + * \brief Finds optimum cycle raio and a critical cycle */ - template - class mcr_howard1 : public - mcr_howard + template < typename FloatTraits, typename Graph, typename VertexIndexMap, + typename EdgeWeight1, typename EdgeWeight2 > + class mcr_howard1 : public mcr_howard< FloatTraits, Graph, VertexIndexMap, + EdgeWeight1, EdgeWeight2 > { public: - typedef mcr_howard inhr_t; - mcr_howard1(const Graph &g, VertexIndexMap vim, - EdgeWeight1 ewm, EdgeWeight2 ew2m) : - inhr_t(g, vim, ewm, ew2m) - { } - - void get_critical_cycle(typename inhr_t::critical_cycle_t &cc) - { return cc.swap(m_cc); } + typedef mcr_howard< FloatTraits, Graph, VertexIndexMap, EdgeWeight1, + EdgeWeight2 > + inhr_t; + mcr_howard1(const Graph& g, VertexIndexMap vim, EdgeWeight1 ewm, + EdgeWeight2 ew2m) + : inhr_t(g, vim, ewm, ew2m) + { + } + + void get_critical_cycle(typename inhr_t::critical_cycle_t& cc) + { + return cc.swap(m_cc); + } protected: - void store_critical_edge(typename inhr_t::edge_t ed, - typename inhr_t::critical_cycle_t &cc) - { cc.push_back(ed); } + void store_critical_edge( + typename inhr_t::edge_t ed, typename inhr_t::critical_cycle_t& cc) + { + cc.push_back(ed); + } - void store_critical_cycle(typename inhr_t::critical_cycle_t &cc) - { m_cc.swap(cc); } + void store_critical_cycle(typename inhr_t::critical_cycle_t& cc) + { + m_cc.swap(cc); + } private: - typename inhr_t::critical_cycle_t m_cc; //Critical cycle + typename inhr_t::critical_cycle_t m_cc; // Critical cycle }; /*! @@ -467,169 +499,138 @@ namespace boost { * \param ewm Edge weight1 map. * \param ew2m Edge weight2 map. * \param pcc pointer to the critical edges list. - * \return Optimum cycle ratio of g or FloatTraits::infinity() if g has no cycles. + * \return Optimum cycle ratio of g or FloatTraits::infinity() if g has no + * cycles. */ - template - typename FT::value_type - optimum_cycle_ratio(const TG &g, TVIM vim, TEW1 ewm, TEW2 ew2m, EV* pcc) + template < typename FT, typename TG, typename TVIM, typename TEW1, + typename TEW2, typename EV > + typename FT::value_type optimum_cycle_ratio( + const TG& g, TVIM vim, TEW1 ewm, TEW2 ew2m, EV* pcc) { - typedef typename graph_traits::directed_category DirCat; - BOOST_STATIC_ASSERT((is_convertible::value == true)); - BOOST_CONCEPT_ASSERT(( IncidenceGraphConcept )); - BOOST_CONCEPT_ASSERT(( VertexListGraphConcept )); - typedef typename graph_traits::vertex_descriptor Vertex; - BOOST_CONCEPT_ASSERT(( ReadablePropertyMapConcept )); - typedef typename graph_traits::edge_descriptor Edge; - BOOST_CONCEPT_ASSERT(( ReadablePropertyMapConcept )); - BOOST_CONCEPT_ASSERT(( ReadablePropertyMapConcept )); - - if(pcc == 0) { - return detail::mcr_howard( - g, vim, ewm, ew2m - ).ocr_howard(); - } - - detail::mcr_howard1 obj(g, vim, ewm, ew2m); - double ocr = obj.ocr_howard(); - obj.get_critical_cycle(*pcc); - return ocr; + typedef typename graph_traits< TG >::directed_category DirCat; + BOOST_STATIC_ASSERT( + (is_convertible< DirCat*, directed_tag* >::value == true)); + BOOST_CONCEPT_ASSERT((IncidenceGraphConcept< TG >)); + BOOST_CONCEPT_ASSERT((VertexListGraphConcept< TG >)); + typedef typename graph_traits< TG >::vertex_descriptor Vertex; + BOOST_CONCEPT_ASSERT((ReadablePropertyMapConcept< TVIM, Vertex >)); + typedef typename graph_traits< TG >::edge_descriptor Edge; + BOOST_CONCEPT_ASSERT((ReadablePropertyMapConcept< TEW1, Edge >)); + BOOST_CONCEPT_ASSERT((ReadablePropertyMapConcept< TEW2, Edge >)); + + if (pcc == 0) + { + return detail::mcr_howard< FT, TG, TVIM, TEW1, TEW2 >( + g, vim, ewm, ew2m) + .ocr_howard(); + } + + detail::mcr_howard1< FT, TG, TVIM, TEW1, TEW2 > obj(g, vim, ewm, ew2m); + double ocr = obj.ocr_howard(); + obj.get_critical_cycle(*pcc); + return ocr; } - } // namespace detail +} // namespace detail // Algorithms // Maximum Cycle Ratio -template < - typename FloatTraits, - typename Graph, - typename VertexIndexMap, - typename EdgeWeight1Map, - typename EdgeWeight2Map> -inline typename FloatTraits::value_type -maximum_cycle_ratio(const Graph &g, VertexIndexMap vim, EdgeWeight1Map ew1m, - EdgeWeight2Map ew2m, - std::vector::edge_descriptor>* pcc = 0, - FloatTraits = FloatTraits()) +template < typename FloatTraits, typename Graph, typename VertexIndexMap, + typename EdgeWeight1Map, typename EdgeWeight2Map > +inline typename FloatTraits::value_type maximum_cycle_ratio(const Graph& g, + VertexIndexMap vim, EdgeWeight1Map ew1m, EdgeWeight2Map ew2m, + std::vector< typename graph_traits< Graph >::edge_descriptor >* pcc = 0, + FloatTraits = FloatTraits()) { - typedef detail::float_wrapper< - FloatTraits, detail::max_comparator_props - > Traits; - return detail::optimum_cycle_ratio(g, vim, ew1m, ew2m, pcc); + typedef detail::float_wrapper< FloatTraits, + detail::max_comparator_props< FloatTraits > > + Traits; + return detail::optimum_cycle_ratio< Traits >(g, vim, ew1m, ew2m, pcc); } -template < - typename Graph, - typename VertexIndexMap, - typename EdgeWeight1Map, - typename EdgeWeight2Map> -inline double -maximum_cycle_ratio(const Graph &g, VertexIndexMap vim, - EdgeWeight1Map ew1m, EdgeWeight2Map ew2m, - std::vector::edge_descriptor>* pcc = 0) -{ return maximum_cycle_ratio(g, vim, ew1m, ew2m, pcc, mcr_float<>()); } +template < typename Graph, typename VertexIndexMap, typename EdgeWeight1Map, + typename EdgeWeight2Map > +inline double maximum_cycle_ratio(const Graph& g, VertexIndexMap vim, + EdgeWeight1Map ew1m, EdgeWeight2Map ew2m, + std::vector< typename graph_traits< Graph >::edge_descriptor >* pcc = 0) +{ + return maximum_cycle_ratio(g, vim, ew1m, ew2m, pcc, mcr_float<>()); +} // Minimum Cycle Ratio -template < - typename FloatTraits, - typename Graph, - typename VertexIndexMap, - typename EdgeWeight1Map, - typename EdgeWeight2Map> -typename FloatTraits::value_type -minimum_cycle_ratio(const Graph &g, VertexIndexMap vim, - EdgeWeight1Map ew1m, EdgeWeight2Map ew2m, - std::vector::edge_descriptor> *pcc = 0, - FloatTraits = FloatTraits()) +template < typename FloatTraits, typename Graph, typename VertexIndexMap, + typename EdgeWeight1Map, typename EdgeWeight2Map > +typename FloatTraits::value_type minimum_cycle_ratio(const Graph& g, + VertexIndexMap vim, EdgeWeight1Map ew1m, EdgeWeight2Map ew2m, + std::vector< typename graph_traits< Graph >::edge_descriptor >* pcc = 0, + FloatTraits = FloatTraits()) { - typedef detail::float_wrapper< - FloatTraits, detail::min_comparator_props - > Traits; - return detail::optimum_cycle_ratio(g, vim, ew1m, ew2m, pcc); + typedef detail::float_wrapper< FloatTraits, + detail::min_comparator_props< FloatTraits > > + Traits; + return detail::optimum_cycle_ratio< Traits >(g, vim, ew1m, ew2m, pcc); } -template < - typename Graph, - typename VertexIndexMap, - typename EdgeWeight1Map, - typename EdgeWeight2Map> -inline double -minimum_cycle_ratio(const Graph &g, VertexIndexMap vim, - EdgeWeight1Map ew1m, EdgeWeight2Map ew2m, - std::vector::edge_descriptor>* pcc = 0) -{ return minimum_cycle_ratio(g, vim, ew1m, ew2m, pcc, mcr_float<>()); } +template < typename Graph, typename VertexIndexMap, typename EdgeWeight1Map, + typename EdgeWeight2Map > +inline double minimum_cycle_ratio(const Graph& g, VertexIndexMap vim, + EdgeWeight1Map ew1m, EdgeWeight2Map ew2m, + std::vector< typename graph_traits< Graph >::edge_descriptor >* pcc = 0) +{ + return minimum_cycle_ratio(g, vim, ew1m, ew2m, pcc, mcr_float<>()); +} // Maximum Cycle Mean -template < - typename FloatTraits, - typename Graph, - typename VertexIndexMap, - typename EdgeWeightMap, - typename EdgeIndexMap> -inline typename FloatTraits::value_type -maximum_cycle_mean(const Graph &g, VertexIndexMap vim, - EdgeWeightMap ewm, EdgeIndexMap eim, - std::vector::edge_descriptor>* pcc = 0, - FloatTraits ft = FloatTraits()) +template < typename FloatTraits, typename Graph, typename VertexIndexMap, + typename EdgeWeightMap, typename EdgeIndexMap > +inline typename FloatTraits::value_type maximum_cycle_mean(const Graph& g, + VertexIndexMap vim, EdgeWeightMap ewm, EdgeIndexMap eim, + std::vector< typename graph_traits< Graph >::edge_descriptor >* pcc = 0, + FloatTraits ft = FloatTraits()) { typedef typename remove_const< - typename property_traits::value_type - >::type Weight; - typename std::vector ed_w2(boost::num_edges(g), 1); - return maximum_cycle_ratio(g, vim, ewm, - make_iterator_property_map(ed_w2.begin(), eim), - pcc, ft); + typename property_traits< EdgeWeightMap >::value_type >::type Weight; + typename std::vector< Weight > ed_w2(boost::num_edges(g), 1); + return maximum_cycle_ratio( + g, vim, ewm, make_iterator_property_map(ed_w2.begin(), eim), pcc, ft); } -template < - typename Graph, - typename VertexIndexMap, - typename EdgeWeightMap, - typename EdgeIndexMap> -inline double -maximum_cycle_mean(const Graph& g, VertexIndexMap vim, - EdgeWeightMap ewm, EdgeIndexMap eim, - std::vector::edge_descriptor>* pcc = 0) -{ return maximum_cycle_mean(g, vim, ewm, eim, pcc, mcr_float<>()); } +template < typename Graph, typename VertexIndexMap, typename EdgeWeightMap, + typename EdgeIndexMap > +inline double maximum_cycle_mean(const Graph& g, VertexIndexMap vim, + EdgeWeightMap ewm, EdgeIndexMap eim, + std::vector< typename graph_traits< Graph >::edge_descriptor >* pcc = 0) +{ + return maximum_cycle_mean(g, vim, ewm, eim, pcc, mcr_float<>()); +} // Minimum Cycle Mean -template < - typename FloatTraits, - typename Graph, - typename VertexIndexMap, - typename EdgeWeightMap, - typename EdgeIndexMap> -inline typename FloatTraits::value_type -minimum_cycle_mean(const Graph &g, VertexIndexMap vim, - EdgeWeightMap ewm, EdgeIndexMap eim, - std::vector::edge_descriptor>* pcc = 0, - FloatTraits ft = FloatTraits()) +template < typename FloatTraits, typename Graph, typename VertexIndexMap, + typename EdgeWeightMap, typename EdgeIndexMap > +inline typename FloatTraits::value_type minimum_cycle_mean(const Graph& g, + VertexIndexMap vim, EdgeWeightMap ewm, EdgeIndexMap eim, + std::vector< typename graph_traits< Graph >::edge_descriptor >* pcc = 0, + FloatTraits ft = FloatTraits()) { typedef typename remove_const< - typename property_traits::value_type - >::type Weight; - typename std::vector ed_w2(boost::num_edges(g), 1); - return minimum_cycle_ratio(g, vim, ewm, - make_iterator_property_map(ed_w2.begin(), eim), - pcc, ft); + typename property_traits< EdgeWeightMap >::value_type >::type Weight; + typename std::vector< Weight > ed_w2(boost::num_edges(g), 1); + return minimum_cycle_ratio( + g, vim, ewm, make_iterator_property_map(ed_w2.begin(), eim), pcc, ft); +} + +template < typename Graph, typename VertexIndexMap, typename EdgeWeightMap, + typename EdgeIndexMap > +inline double minimum_cycle_mean(const Graph& g, VertexIndexMap vim, + EdgeWeightMap ewm, EdgeIndexMap eim, + std::vector< typename graph_traits< Graph >::edge_descriptor >* pcc = 0) +{ + return minimum_cycle_mean(g, vim, ewm, eim, pcc, mcr_float<>()); } -template < - typename Graph, - typename VertexIndexMap, - typename EdgeWeightMap, - typename EdgeIndexMap> -inline double -minimum_cycle_mean(const Graph &g, VertexIndexMap vim, - EdgeWeightMap ewm, EdgeIndexMap eim, - std::vector::edge_descriptor>* pcc = 0) -{ return minimum_cycle_mean(g, vim, ewm, eim, pcc, mcr_float<>()); } - -} //namespace boost +} // namespace boost #endif diff --git a/include/boost/graph/incremental_components.hpp b/include/boost/graph/incremental_components.hpp index fff3a3244..1ad8c9403 100644 --- a/include/boost/graph/incremental_components.hpp +++ b/include/boost/graph/incremental_components.hpp @@ -20,212 +20,215 @@ #include #include -namespace boost { - - // A connected component algorithm for the case when dynamically - // adding (but not removing) edges is common. The - // incremental_components() function is a preparing operation. Call - // same_component to check whether two vertices are in the same - // component, or use disjoint_set::find_set to determine the - // representative for a vertex. - - // This version of connected components does not require a full - // Graph. Instead, it just needs an edge list, where the vertices of - // each edge need to be of integer type. The edges are assumed to - // be undirected. The other difference is that the result is stored in - // a container, instead of just a decorator. The container should be - // empty before the algorithm is called. It will grow during the - // course of the algorithm. The container must be a model of - // BackInsertionSequence and RandomAccessContainer - // (std::vector is a good choice). After running the algorithm the - // index container will map each vertex to the representative - // vertex of the component to which it belongs. - // - // Adapted from an implementation by Alex Stepanov. The disjoint - // sets data structure is from Tarjan's "Data Structures and Network - // Algorithms", and the application to connected components is - // similar to the algorithm described in Ch. 22 of "Intro to - // Algorithms" by Cormen, et. all. - // - - // An implementation of disjoint sets can be found in - // boost/pending/disjoint_sets.hpp - - template - void incremental_components(EdgeListGraph& g, DisjointSets& ds) - { - typename graph_traits::edge_iterator e, end; - for (boost::tie(e,end) = edges(g); e != end; ++e) - ds.union_set(source(*e,g),target(*e,g)); - } - - template - void compress_components(ParentIterator first, ParentIterator last) - { - for (ParentIterator current = first; current != last; ++current) - detail::find_representative_with_full_compression(first, current-first); - } - - template - typename boost::detail::iterator_traits::difference_type - component_count(ParentIterator first, ParentIterator last) - { +namespace boost +{ + +// A connected component algorithm for the case when dynamically +// adding (but not removing) edges is common. The +// incremental_components() function is a preparing operation. Call +// same_component to check whether two vertices are in the same +// component, or use disjoint_set::find_set to determine the +// representative for a vertex. + +// This version of connected components does not require a full +// Graph. Instead, it just needs an edge list, where the vertices of +// each edge need to be of integer type. The edges are assumed to +// be undirected. The other difference is that the result is stored in +// a container, instead of just a decorator. The container should be +// empty before the algorithm is called. It will grow during the +// course of the algorithm. The container must be a model of +// BackInsertionSequence and RandomAccessContainer +// (std::vector is a good choice). After running the algorithm the +// index container will map each vertex to the representative +// vertex of the component to which it belongs. +// +// Adapted from an implementation by Alex Stepanov. The disjoint +// sets data structure is from Tarjan's "Data Structures and Network +// Algorithms", and the application to connected components is +// similar to the algorithm described in Ch. 22 of "Intro to +// Algorithms" by Cormen, et. all. +// + +// An implementation of disjoint sets can be found in +// boost/pending/disjoint_sets.hpp + +template < class EdgeListGraph, class DisjointSets > +void incremental_components(EdgeListGraph& g, DisjointSets& ds) +{ + typename graph_traits< EdgeListGraph >::edge_iterator e, end; + for (boost::tie(e, end) = edges(g); e != end; ++e) + ds.union_set(source(*e, g), target(*e, g)); +} + +template < class ParentIterator > +void compress_components(ParentIterator first, ParentIterator last) +{ + for (ParentIterator current = first; current != last; ++current) + detail::find_representative_with_full_compression( + first, current - first); +} + +template < class ParentIterator > +typename boost::detail::iterator_traits< ParentIterator >::difference_type +component_count(ParentIterator first, ParentIterator last) +{ std::ptrdiff_t count = 0; - for (ParentIterator current = first; current != last; ++current) - if (*current == current - first) ++count; + for (ParentIterator current = first; current != last; ++current) + if (*current == current - first) + ++count; return count; - } - - // This algorithm can be applied to the result container of the - // connected_components algorithm to normalize - // the components. - template - void normalize_components(ParentIterator first, ParentIterator last) - { - for (ParentIterator current = first; current != last; ++current) - detail::normalize_node(first, current - first); - } - - template - void initialize_incremental_components(VertexListGraph& G, DisjointSets& ds) - { - typename graph_traits - ::vertex_iterator v, vend; +} + +// This algorithm can be applied to the result container of the +// connected_components algorithm to normalize +// the components. +template < class ParentIterator > +void normalize_components(ParentIterator first, ParentIterator last) +{ + for (ParentIterator current = first; current != last; ++current) + detail::normalize_node(first, current - first); +} + +template < class VertexListGraph, class DisjointSets > +void initialize_incremental_components(VertexListGraph& G, DisjointSets& ds) +{ + typename graph_traits< VertexListGraph >::vertex_iterator v, vend; for (boost::tie(v, vend) = vertices(G); v != vend; ++v) - ds.make_set(*v); - } + ds.make_set(*v); +} - template - inline bool same_component(Vertex u, Vertex v, DisjointSet& ds) - { +template < class Vertex, class DisjointSet > +inline bool same_component(Vertex u, Vertex v, DisjointSet& ds) +{ return ds.find_set(u) == ds.find_set(v); - } +} - // Class that builds a quick-access indexed linked list that allows - // for fast iterating through a parent component's children. - template - class component_index { +// Class that builds a quick-access indexed linked list that allows +// for fast iterating through a parent component's children. +template < typename IndexType > class component_index +{ - private: - typedef std::vector IndexContainer; +private: + typedef std::vector< IndexType > IndexContainer; - public: - typedef counting_iterator iterator; +public: + typedef counting_iterator< IndexType > iterator; typedef iterator const_iterator; typedef IndexType value_type; typedef IndexType size_type; - typedef detail::component_index_iterator - component_iterator; - - public: - template - component_index(ParentIterator parent_start, - ParentIterator parent_end, - const ElementIndexMap& index_map) : - m_num_elements(std::distance(parent_start, parent_end)), - m_components(make_shared()), - m_index_list(make_shared(m_num_elements)) { - - build_index_lists(parent_start, index_map); - + typedef detail::component_index_iterator< + typename IndexContainer::iterator > + component_iterator; + +public: + template < typename ParentIterator, typename ElementIndexMap > + component_index(ParentIterator parent_start, ParentIterator parent_end, + const ElementIndexMap& index_map) + : m_num_elements(std::distance(parent_start, parent_end)) + , m_components(make_shared< IndexContainer >()) + , m_index_list(make_shared< IndexContainer >(m_num_elements)) + { + + build_index_lists(parent_start, index_map); + } // component_index - template - component_index(ParentIterator parent_start, - ParentIterator parent_end) : - m_num_elements(std::distance(parent_start, parent_end)), - m_components(make_shared()), - m_index_list(make_shared(m_num_elements)) { + template < typename ParentIterator > + component_index(ParentIterator parent_start, ParentIterator parent_end) + : m_num_elements(std::distance(parent_start, parent_end)) + , m_components(make_shared< IndexContainer >()) + , m_index_list(make_shared< IndexContainer >(m_num_elements)) + { - build_index_lists(parent_start, boost::identity_property_map()); + build_index_lists(parent_start, boost::identity_property_map()); } // component_index // Returns the number of components - inline std::size_t size() const { - return (m_components->size()); - } + inline std::size_t size() const { return (m_components->size()); } // Beginning iterator for component indices - iterator begin() const { - return (iterator(0)); - } + iterator begin() const { return (iterator(0)); } // End iterator for component indices - iterator end() const { - return (iterator(this->size())); - } + iterator end() const { return (iterator(this->size())); } // Returns a pair of begin and end iterators for the child // elements of component [component_index]. - std::pair - operator[](IndexType component_index) const { + std::pair< component_iterator, component_iterator > operator[]( + IndexType component_index) const + { - IndexType first_index = (*m_components)[component_index]; + IndexType first_index = (*m_components)[component_index]; - return (std::make_pair - (component_iterator(m_index_list->begin(), first_index), - component_iterator(m_num_elements))); + return (std::make_pair( + component_iterator(m_index_list->begin(), first_index), + component_iterator(m_num_elements))); } - private: - template - void build_index_lists(ParentIterator parent_start, - const ElementIndexMap& index_map) { - - typedef typename std::iterator_traits::value_type Element; - typename IndexContainer::iterator index_list = - m_index_list->begin(); - - // First pass - find root elements, construct index list - for (IndexType element_index = 0; element_index < m_num_elements; - ++element_index) { - - Element parent_element = parent_start[element_index]; - IndexType parent_index = get(index_map, parent_element); - - if (element_index != parent_index) { - index_list[element_index] = parent_index; - } - else { - m_components->push_back(element_index); - - // m_num_elements is the linked list terminator - index_list[element_index] = m_num_elements; +private: + template < typename ParentIterator, typename ElementIndexMap > + void build_index_lists( + ParentIterator parent_start, const ElementIndexMap& index_map) + { + + typedef + typename std::iterator_traits< ParentIterator >::value_type Element; + typename IndexContainer::iterator index_list = m_index_list->begin(); + + // First pass - find root elements, construct index list + for (IndexType element_index = 0; element_index < m_num_elements; + ++element_index) + { + + Element parent_element = parent_start[element_index]; + IndexType parent_index = get(index_map, parent_element); + + if (element_index != parent_index) + { + index_list[element_index] = parent_index; + } + else + { + m_components->push_back(element_index); + + // m_num_elements is the linked list terminator + index_list[element_index] = m_num_elements; + } } - } - // Second pass - build linked list - for (IndexType element_index = 0; element_index < m_num_elements; - ++element_index) { + // Second pass - build linked list + for (IndexType element_index = 0; element_index < m_num_elements; + ++element_index) + { - Element parent_element = parent_start[element_index]; - IndexType parent_index = get(index_map, parent_element); + Element parent_element = parent_start[element_index]; + IndexType parent_index = get(index_map, parent_element); - if (element_index != parent_index) { + if (element_index != parent_index) + { - // Follow list until a component parent is found - while (index_list[parent_index] != m_num_elements) { - parent_index = index_list[parent_index]; - } + // Follow list until a component parent is found + while (index_list[parent_index] != m_num_elements) + { + parent_index = index_list[parent_index]; + } - // Push element to the front of the linked list - index_list[element_index] = index_list[parent_index]; - index_list[parent_index] = element_index; + // Push element to the front of the linked list + index_list[element_index] = index_list[parent_index]; + index_list[parent_index] = element_index; + } } - } } // build_index_lists - protected: +protected: IndexType m_num_elements; - shared_ptr m_components, m_index_list; + shared_ptr< IndexContainer > m_components, m_index_list; + +}; // class component_index - }; // class component_index - } // namespace boost #endif // BOOST_INCREMENTAL_COMPONENTS_HPP diff --git a/include/boost/graph/is_kuratowski_subgraph.hpp b/include/boost/graph/is_kuratowski_subgraph.hpp index d0a2aede9..1624a9646 100644 --- a/include/boost/graph/is_kuratowski_subgraph.hpp +++ b/include/boost/graph/is_kuratowski_subgraph.hpp @@ -9,7 +9,7 @@ #define __IS_KURATOWSKI_SUBGRAPH_HPP__ #include -#include //for tie +#include //for tie #include #include #include @@ -19,313 +19,277 @@ #include #include - - namespace boost { - - namespace detail - { - template - Graph make_K_5() +namespace detail +{ + + template < typename Graph > Graph make_K_5() { - typename graph_traits::vertex_iterator vi, vi_end, inner_vi; - Graph K_5(5); - for(boost::tie(vi,vi_end) = vertices(K_5); vi != vi_end; ++vi) - for(inner_vi = next(vi); inner_vi != vi_end; ++inner_vi) - add_edge(*vi, *inner_vi, K_5); - return K_5; + typename graph_traits< Graph >::vertex_iterator vi, vi_end, inner_vi; + Graph K_5(5); + for (boost::tie(vi, vi_end) = vertices(K_5); vi != vi_end; ++vi) + for (inner_vi = next(vi); inner_vi != vi_end; ++inner_vi) + add_edge(*vi, *inner_vi, K_5); + return K_5; } - - template - Graph make_K_3_3() + template < typename Graph > Graph make_K_3_3() { - typename graph_traits::vertex_iterator - vi, vi_end, bipartition_start, inner_vi; - Graph K_3_3(6); - bipartition_start = next(next(next(vertices(K_3_3).first))); - for(boost::tie(vi, vi_end) = vertices(K_3_3); vi != bipartition_start; ++vi) - for(inner_vi= bipartition_start; inner_vi != vi_end; ++inner_vi) - add_edge(*vi, *inner_vi, K_3_3); - return K_3_3; + typename graph_traits< Graph >::vertex_iterator vi, vi_end, + bipartition_start, inner_vi; + Graph K_3_3(6); + bipartition_start = next(next(next(vertices(K_3_3).first))); + for (boost::tie(vi, vi_end) = vertices(K_3_3); vi != bipartition_start; + ++vi) + for (inner_vi = bipartition_start; inner_vi != vi_end; ++inner_vi) + add_edge(*vi, *inner_vi, K_3_3); + return K_3_3; } - - template + template < typename AdjacencyList, typename Vertex > void contract_edge(AdjacencyList& neighbors, Vertex u, Vertex v) { - // Remove u from v's neighbor list - neighbors[v].erase(std::remove(neighbors[v].begin(), - neighbors[v].end(), u - ), - neighbors[v].end() - ); - - // Replace any references to u with references to v - typedef typename AdjacencyList::value_type::iterator - adjacency_iterator_t; - - adjacency_iterator_t u_neighbor_end = neighbors[u].end(); - for(adjacency_iterator_t u_neighbor_itr = neighbors[u].begin(); - u_neighbor_itr != u_neighbor_end; ++u_neighbor_itr - ) + // Remove u from v's neighbor list + neighbors[v].erase( + std::remove(neighbors[v].begin(), neighbors[v].end(), u), + neighbors[v].end()); + + // Replace any references to u with references to v + typedef + typename AdjacencyList::value_type::iterator adjacency_iterator_t; + + adjacency_iterator_t u_neighbor_end = neighbors[u].end(); + for (adjacency_iterator_t u_neighbor_itr = neighbors[u].begin(); + u_neighbor_itr != u_neighbor_end; ++u_neighbor_itr) { - Vertex u_neighbor(*u_neighbor_itr); - std::replace(neighbors[u_neighbor].begin(), - neighbors[u_neighbor].end(), u, v - ); + Vertex u_neighbor(*u_neighbor_itr); + std::replace(neighbors[u_neighbor].begin(), + neighbors[u_neighbor].end(), u, v); } - - // Remove v from u's neighbor list - neighbors[u].erase(std::remove(neighbors[u].begin(), - neighbors[u].end(), v - ), - neighbors[u].end() - ); - - // Add everything in u's neighbor list to v's neighbor list - std::copy(neighbors[u].begin(), - neighbors[u].end(), - std::back_inserter(neighbors[v]) - ); - - // Clear u's neighbor list - neighbors[u].clear(); - - } - enum target_graph_t { tg_k_3_3, tg_k_5}; + // Remove v from u's neighbor list + neighbors[u].erase( + std::remove(neighbors[u].begin(), neighbors[u].end(), v), + neighbors[u].end()); - } // namespace detail + // Add everything in u's neighbor list to v's neighbor list + std::copy(neighbors[u].begin(), neighbors[u].end(), + std::back_inserter(neighbors[v])); + // Clear u's neighbor list + neighbors[u].clear(); + } + enum target_graph_t + { + tg_k_3_3, + tg_k_5 + }; +} // namespace detail - template - bool is_kuratowski_subgraph(const Graph& g, - ForwardIterator begin, - ForwardIterator end, - VertexIndexMap vm - ) - { +template < typename Graph, typename ForwardIterator, typename VertexIndexMap > +bool is_kuratowski_subgraph(const Graph& g, ForwardIterator begin, + ForwardIterator end, VertexIndexMap vm) +{ - typedef typename graph_traits::vertex_descriptor vertex_t; - typedef typename graph_traits::vertex_iterator vertex_iterator_t; - typedef typename graph_traits::edge_descriptor edge_t; - typedef typename graph_traits::edges_size_type e_size_t; - typedef typename graph_traits::vertices_size_type v_size_t; - typedef typename std::vector v_list_t; + typedef typename graph_traits< Graph >::vertex_descriptor vertex_t; + typedef typename graph_traits< Graph >::vertex_iterator vertex_iterator_t; + typedef typename graph_traits< Graph >::edge_descriptor edge_t; + typedef typename graph_traits< Graph >::edges_size_type e_size_t; + typedef typename graph_traits< Graph >::vertices_size_type v_size_t; + typedef typename std::vector< vertex_t > v_list_t; typedef typename v_list_t::iterator v_list_iterator_t; - typedef iterator_property_map - ::iterator, VertexIndexMap> - vertex_to_v_list_map_t; + typedef iterator_property_map< typename std::vector< v_list_t >::iterator, + VertexIndexMap > + vertex_to_v_list_map_t; - typedef adjacency_list small_graph_t; + typedef adjacency_list< vecS, vecS, undirectedS > small_graph_t; - detail::target_graph_t target_graph = detail::tg_k_3_3; //unless we decide otherwise later + detail::target_graph_t target_graph + = detail::tg_k_3_3; // unless we decide otherwise later - static small_graph_t K_5(detail::make_K_5()); + static small_graph_t K_5(detail::make_K_5< small_graph_t >()); - static small_graph_t K_3_3(detail::make_K_3_3()); + static small_graph_t K_3_3(detail::make_K_3_3< small_graph_t >()); v_size_t n_vertices(num_vertices(g)); - v_size_t max_num_edges(3*n_vertices - 5); + v_size_t max_num_edges(3 * n_vertices - 5); - std::vector neighbors_vector(n_vertices); + std::vector< v_list_t > neighbors_vector(n_vertices); vertex_to_v_list_map_t neighbors(neighbors_vector.begin(), vm); e_size_t count = 0; - for(ForwardIterator itr = begin; itr != end; ++itr) - { + for (ForwardIterator itr = begin; itr != end; ++itr) + { if (count++ > max_num_edges) - return false; + return false; edge_t e(*itr); - vertex_t u(source(e,g)); - vertex_t v(target(e,g)); + vertex_t u(source(e, g)); + vertex_t v(target(e, g)); neighbors[u].push_back(v); neighbors[v].push_back(u); + } - } - - - for(v_size_t max_size = 2; max_size < 5; ++max_size) - { + for (v_size_t max_size = 2; max_size < 5; ++max_size) + { vertex_iterator_t vi, vi_end; - for(boost::tie(vi,vi_end) = vertices(g); vi != vi_end; ++vi) - { + for (boost::tie(vi, vi_end) = vertices(g); vi != vi_end; ++vi) + { vertex_t v(*vi); - //a hack to make sure we don't contract the middle edge of a path - //of four degree-3 vertices + // a hack to make sure we don't contract the middle edge of a path + // of four degree-3 vertices if (max_size == 4 && neighbors[v].size() == 3) - { - if (neighbors[neighbors[v][0]].size() + - neighbors[neighbors[v][1]].size() + - neighbors[neighbors[v][2]].size() + { + if (neighbors[neighbors[v][0]].size() + + neighbors[neighbors[v][1]].size() + + neighbors[neighbors[v][2]].size() < 11 // so, it has two degree-3 neighbors - ) - continue; - } + ) + continue; + } while (neighbors[v].size() > 0 && neighbors[v].size() < max_size) - { + { // Find one of v's neighbors u such that v and u - // have no neighbors in common. We'll look for such a - // neighbor with a naive cubic-time algorithm since the - // max size of any of the neighbor sets we'll consider + // have no neighbors in common. We'll look for such a + // neighbor with a naive cubic-time algorithm since the + // max size of any of the neighbor sets we'll consider // merging is 3 - + bool neighbor_sets_intersect = false; - - vertex_t min_u = graph_traits::null_vertex(); + + vertex_t min_u = graph_traits< Graph >::null_vertex(); vertex_t u; v_list_iterator_t v_neighbor_end = neighbors[v].end(); - for(v_list_iterator_t v_neighbor_itr = neighbors[v].begin(); - v_neighbor_itr != v_neighbor_end; - ++v_neighbor_itr - ) - { + for (v_list_iterator_t v_neighbor_itr = neighbors[v].begin(); + v_neighbor_itr != v_neighbor_end; ++v_neighbor_itr) + { neighbor_sets_intersect = false; u = *v_neighbor_itr; v_list_iterator_t u_neighbor_end = neighbors[u].end(); - for(v_list_iterator_t u_neighbor_itr = - neighbors[u].begin(); - u_neighbor_itr != u_neighbor_end && - !neighbor_sets_intersect; - ++u_neighbor_itr - ) - { - for(v_list_iterator_t inner_v_neighbor_itr = - neighbors[v].begin(); - inner_v_neighbor_itr != v_neighbor_end; - ++inner_v_neighbor_itr - ) - { + for (v_list_iterator_t u_neighbor_itr + = neighbors[u].begin(); + u_neighbor_itr != u_neighbor_end + && !neighbor_sets_intersect; + ++u_neighbor_itr) + { + for (v_list_iterator_t inner_v_neighbor_itr + = neighbors[v].begin(); + inner_v_neighbor_itr != v_neighbor_end; + ++inner_v_neighbor_itr) + { if (*u_neighbor_itr == *inner_v_neighbor_itr) - { + { neighbor_sets_intersect = true; break; - } - } - - } - if (!neighbor_sets_intersect && - (min_u == graph_traits::null_vertex() || - neighbors[u].size() < neighbors[min_u].size()) - ) - { + } + } + } + if (!neighbor_sets_intersect + && (min_u == graph_traits< Graph >::null_vertex() + || neighbors[u].size() < neighbors[min_u].size())) + { min_u = u; - } - - } - - if (min_u == graph_traits::null_vertex()) - // Exited the loop without finding an appropriate neighbor of - // v, so v must be a lost cause. Move on to other vertices. - break; + } + } + + if (min_u == graph_traits< Graph >::null_vertex()) + // Exited the loop without finding an appropriate neighbor + // of v, so v must be a lost cause. Move on to other + // vertices. + break; else - u = min_u; + u = min_u; detail::contract_edge(neighbors, u, v); - }//end iteration over v's neighbors + } // end iteration over v's neighbors - }//end iteration through vertices v + } // end iteration through vertices v if (max_size == 3) - { + { // check to see whether we should go on to find a K_5 - for(boost::tie(vi,vi_end) = vertices(g); vi != vi_end; ++vi) - if (neighbors[*vi].size() == 4) + for (boost::tie(vi, vi_end) = vertices(g); vi != vi_end; ++vi) + if (neighbors[*vi].size() == 4) { - target_graph = detail::tg_k_5; - break; + target_graph = detail::tg_k_5; + break; } if (target_graph == detail::tg_k_3_3) - break; - } - - }//end iteration through max degree 2,3, and 4 - - - //Now, there should only be 5 or 6 vertices with any neighbors. Find them. - + break; + } + + } // end iteration through max degree 2,3, and 4 + + // Now, there should only be 5 or 6 vertices with any neighbors. Find them. + v_list_t main_vertices; vertex_iterator_t vi, vi_end; - - for(boost::tie(vi,vi_end) = vertices(g); vi != vi_end; ++vi) - { + + for (boost::tie(vi, vi_end) = vertices(g); vi != vi_end; ++vi) + { if (!neighbors[*vi].empty()) - main_vertices.push_back(*vi); - } - - // create a graph isomorphic to the contracted graph to test + main_vertices.push_back(*vi); + } + + // create a graph isomorphic to the contracted graph to test // against K_5 and K_3_3 small_graph_t contracted_graph(main_vertices.size()); - std::map::vertex_descriptor> - contracted_vertex_map; - + std::map< vertex_t, + typename graph_traits< small_graph_t >::vertex_descriptor > + contracted_vertex_map; + typename v_list_t::iterator itr, itr_end; itr_end = main_vertices.end(); - typename graph_traits::vertex_iterator - si = vertices(contracted_graph).first; - - for(itr = main_vertices.begin(); itr != itr_end; ++itr, ++si) - { + typename graph_traits< small_graph_t >::vertex_iterator si + = vertices(contracted_graph).first; + + for (itr = main_vertices.begin(); itr != itr_end; ++itr, ++si) + { contracted_vertex_map[*itr] = *si; - } + } typename v_list_t::iterator jtr, jtr_end; - for(itr = main_vertices.begin(); itr != itr_end; ++itr) - { + for (itr = main_vertices.begin(); itr != itr_end; ++itr) + { jtr_end = neighbors[*itr].end(); - for(jtr = neighbors[*itr].begin(); jtr != jtr_end; ++jtr) - { - if (get(vm,*itr) < get(vm,*jtr)) - { + for (jtr = neighbors[*itr].begin(); jtr != jtr_end; ++jtr) + { + if (get(vm, *itr) < get(vm, *jtr)) + { add_edge(contracted_vertex_map[*itr], - contracted_vertex_map[*jtr], - contracted_graph - ); - } - } - } - - if (target_graph == detail::tg_k_5) - { - return boost::isomorphism(K_5,contracted_graph); - } - else //target_graph == tg_k_3_3 - { - return boost::isomorphism(K_3_3,contracted_graph); - } - - - } - - - - - - template - bool is_kuratowski_subgraph(const Graph& g, - ForwardIterator begin, - ForwardIterator end - ) - { - return is_kuratowski_subgraph(g, begin, end, get(vertex_index,g)); - } + contracted_vertex_map[*jtr], contracted_graph); + } + } + } + if (target_graph == detail::tg_k_5) + { + return boost::isomorphism(K_5, contracted_graph); + } + else // target_graph == tg_k_3_3 + { + return boost::isomorphism(K_3_3, contracted_graph); + } +} +template < typename Graph, typename ForwardIterator > +bool is_kuratowski_subgraph( + const Graph& g, ForwardIterator begin, ForwardIterator end) +{ + return is_kuratowski_subgraph(g, begin, end, get(vertex_index, g)); +} - } #endif //__IS_KURATOWSKI_SUBGRAPH_HPP__ diff --git a/include/boost/graph/is_straight_line_drawing.hpp b/include/boost/graph/is_straight_line_drawing.hpp index a4bd8ff5f..013f4b400 100644 --- a/include/boost/graph/is_straight_line_drawing.hpp +++ b/include/boost/graph/is_straight_line_drawing.hpp @@ -21,229 +21,188 @@ #include #include - - namespace boost { - // Return true exactly when the line segments s1 = ((x1,y1), (x2,y2)) and - // s2 = ((a1,b1), (a2,b2)) intersect in a point other than the endpoints of - // the line segments. The one exception to this rule is when s1 = s2, in - // which case false is returned - this is to accomodate multiple edges - // between the same pair of vertices, which shouldn't invalidate the straight - // line embedding. A tolerance variable epsilon can also be used, which - // defines how far away from the endpoints of s1 and s2 we want to consider - // an intersection. - - inline bool intersects(double x1, double y1, - double x2, double y2, - double a1, double b1, - double a2, double b2, - double epsilon = 0.000001 - ) - { +// Return true exactly when the line segments s1 = ((x1,y1), (x2,y2)) and +// s2 = ((a1,b1), (a2,b2)) intersect in a point other than the endpoints of +// the line segments. The one exception to this rule is when s1 = s2, in +// which case false is returned - this is to accomodate multiple edges +// between the same pair of vertices, which shouldn't invalidate the straight +// line embedding. A tolerance variable epsilon can also be used, which +// defines how far away from the endpoints of s1 and s2 we want to consider +// an intersection. + +inline bool intersects(double x1, double y1, double x2, double y2, double a1, + double b1, double a2, double b2, double epsilon = 0.000001) +{ if (x1 - x2 == 0) - { - std::swap(x1,a1); - std::swap(y1,b1); - std::swap(x2,a2); - std::swap(y2,b2); - } + { + std::swap(x1, a1); + std::swap(y1, b1); + std::swap(x2, a2); + std::swap(y2, b2); + } if (x1 - x2 == 0) - { + { BOOST_USING_STD_MAX(); BOOST_USING_STD_MIN(); - //two vertical line segments - double min_y = min BOOST_PREVENT_MACRO_SUBSTITUTION(y1,y2); - double max_y = max BOOST_PREVENT_MACRO_SUBSTITUTION(y1,y2); - double min_b = min BOOST_PREVENT_MACRO_SUBSTITUTION(b1,b2); - double max_b = max BOOST_PREVENT_MACRO_SUBSTITUTION(b1,b2); - if ((max_y > max_b && max_b > min_y) || - (max_b > max_y && max_y > min_b) - ) - return true; + // two vertical line segments + double min_y = min BOOST_PREVENT_MACRO_SUBSTITUTION(y1, y2); + double max_y = max BOOST_PREVENT_MACRO_SUBSTITUTION(y1, y2); + double min_b = min BOOST_PREVENT_MACRO_SUBSTITUTION(b1, b2); + double max_b = max BOOST_PREVENT_MACRO_SUBSTITUTION(b1, b2); + if ((max_y > max_b && max_b > min_y) + || (max_b > max_y && max_y > min_b)) + return true; else - return false; - } + return false; + } double x_diff = x1 - x2; double y_diff = y1 - y2; double a_diff = a2 - a1; double b_diff = b2 - b1; - double beta_denominator = b_diff - (y_diff/((double)x_diff)) * a_diff; + double beta_denominator = b_diff - (y_diff / ((double)x_diff)) * a_diff; if (beta_denominator == 0) - { - //parallel lines + { + // parallel lines return false; - } + } - double beta = (b2 - y2 - (y_diff/((double)x_diff)) * (a2 - x2)) / - beta_denominator; - double alpha = (a2 - x2 - beta*(a_diff))/x_diff; + double beta = (b2 - y2 - (y_diff / ((double)x_diff)) * (a2 - x2)) + / beta_denominator; + double alpha = (a2 - x2 - beta * (a_diff)) / x_diff; double upper_bound = 1 - epsilon; double lower_bound = 0 + epsilon; - return (beta < upper_bound && beta > lower_bound && - alpha < upper_bound && alpha > lower_bound); - - } - + return (beta < upper_bound && beta > lower_bound && alpha < upper_bound + && alpha > lower_bound); +} - template - bool is_straight_line_drawing(const Graph& g, - GridPositionMap drawing, - VertexIndexMap - ) - { +template < typename Graph, typename GridPositionMap, typename VertexIndexMap > +bool is_straight_line_drawing( + const Graph& g, GridPositionMap drawing, VertexIndexMap) +{ - typedef typename graph_traits::vertex_descriptor vertex_t; - typedef typename graph_traits::edge_descriptor edge_t; - typedef typename graph_traits::edge_iterator edge_iterator_t; + typedef typename graph_traits< Graph >::vertex_descriptor vertex_t; + typedef typename graph_traits< Graph >::edge_descriptor edge_t; + typedef typename graph_traits< Graph >::edge_iterator edge_iterator_t; typedef std::size_t x_coord_t; typedef std::size_t y_coord_t; - typedef boost::tuple edge_event_t; + typedef boost::tuple< edge_t, x_coord_t, y_coord_t > edge_event_t; typedef typename std::vector< edge_event_t > edge_event_queue_t; - typedef tuple active_map_key_t; + typedef tuple< y_coord_t, y_coord_t, x_coord_t, x_coord_t > + active_map_key_t; typedef edge_t active_map_value_t; typedef std::map< active_map_key_t, active_map_value_t > active_map_t; typedef typename active_map_t::iterator active_map_iterator_t; - edge_event_queue_t edge_event_queue; active_map_t active_edges; edge_iterator_t ei, ei_end; - for(boost::tie(ei,ei_end) = edges(g); ei != ei_end; ++ei) - { + for (boost::tie(ei, ei_end) = edges(g); ei != ei_end; ++ei) + { edge_t e(*ei); - vertex_t s(source(e,g)); - vertex_t t(target(e,g)); - edge_event_queue.push_back - (make_tuple(e, - static_cast(drawing[s].x), - static_cast(drawing[s].y) - ) - ); - edge_event_queue.push_back - (make_tuple(e, - static_cast(drawing[t].x), - static_cast(drawing[t].y) - ) - ); - } - - // Order by edge_event_queue by first, then second coordinate + vertex_t s(source(e, g)); + vertex_t t(target(e, g)); + edge_event_queue.push_back( + make_tuple(e, static_cast< std::size_t >(drawing[s].x), + static_cast< std::size_t >(drawing[s].y))); + edge_event_queue.push_back( + make_tuple(e, static_cast< std::size_t >(drawing[t].x), + static_cast< std::size_t >(drawing[t].y))); + } + + // Order by edge_event_queue by first, then second coordinate // (bucket_sort is a stable sort.) bucket_sort(edge_event_queue.begin(), edge_event_queue.end(), - property_map_tuple_adaptor() - ); - + property_map_tuple_adaptor< edge_event_t, 2 >()); + bucket_sort(edge_event_queue.begin(), edge_event_queue.end(), - property_map_tuple_adaptor() - ); + property_map_tuple_adaptor< edge_event_t, 1 >()); typedef typename edge_event_queue_t::iterator event_queue_iterator_t; event_queue_iterator_t itr_end = edge_event_queue.end(); - for(event_queue_iterator_t itr = edge_event_queue.begin(); - itr != itr_end; ++itr - ) - { - edge_t e(get<0>(*itr)); - vertex_t source_v(source(e,g)); - vertex_t target_v(target(e,g)); + for (event_queue_iterator_t itr = edge_event_queue.begin(); itr != itr_end; + ++itr) + { + edge_t e(get< 0 >(*itr)); + vertex_t source_v(source(e, g)); + vertex_t target_v(target(e, g)); if (drawing[source_v].y > drawing[target_v].y) - std::swap(source_v, target_v); + std::swap(source_v, target_v); - active_map_key_t key(get(drawing, source_v).y, - get(drawing, target_v).y, - get(drawing, source_v).x, - get(drawing, target_v).x - ); + active_map_key_t key(get(drawing, source_v).y, get(drawing, target_v).y, + get(drawing, source_v).x, get(drawing, target_v).x); active_map_iterator_t a_itr = active_edges.find(key); if (a_itr == active_edges.end()) - { + { active_edges[key] = e; - } + } else - { + { active_map_iterator_t before, after; if (a_itr == active_edges.begin()) - before = active_edges.end(); + before = active_edges.end(); else - before = prior(a_itr); + before = prior(a_itr); after = boost::next(a_itr); if (before != active_edges.end()) - { - + { + edge_t f = before->second; - vertex_t e_source(source(e,g)); - vertex_t e_target(target(e,g)); - vertex_t f_source(source(f,g)); - vertex_t f_target(target(f,g)); - - if (intersects(drawing[e_source].x, - drawing[e_source].y, - drawing[e_target].x, - drawing[e_target].y, - drawing[f_source].x, - drawing[f_source].y, - drawing[f_target].x, - drawing[f_target].y - ) - ) - return false; - } + vertex_t e_source(source(e, g)); + vertex_t e_target(target(e, g)); + vertex_t f_source(source(f, g)); + vertex_t f_target(target(f, g)); + + if (intersects(drawing[e_source].x, drawing[e_source].y, + drawing[e_target].x, drawing[e_target].y, + drawing[f_source].x, drawing[f_source].y, + drawing[f_target].x, drawing[f_target].y)) + return false; + } if (after != active_edges.end()) - { - + { + edge_t f = after->second; - vertex_t e_source(source(e,g)); - vertex_t e_target(target(e,g)); - vertex_t f_source(source(f,g)); - vertex_t f_target(target(f,g)); - - if (intersects(drawing[e_source].x, - drawing[e_source].y, - drawing[e_target].x, - drawing[e_target].y, - drawing[f_source].x, - drawing[f_source].y, - drawing[f_target].x, - drawing[f_target].y - ) - ) - return false; - } + vertex_t e_source(source(e, g)); + vertex_t e_target(target(e, g)); + vertex_t f_source(source(f, g)); + vertex_t f_target(target(f, g)); + + if (intersects(drawing[e_source].x, drawing[e_source].y, + drawing[e_target].x, drawing[e_target].y, + drawing[f_source].x, drawing[f_source].y, + drawing[f_target].x, drawing[f_target].y)) + return false; + } active_edges.erase(a_itr); - - } - } + } + } return true; - - } - +} - template - bool is_straight_line_drawing(const Graph& g, GridPositionMap drawing) - { - return is_straight_line_drawing(g, drawing, get(vertex_index,g)); - } +template < typename Graph, typename GridPositionMap > +bool is_straight_line_drawing(const Graph& g, GridPositionMap drawing) +{ + return is_straight_line_drawing(g, drawing, get(vertex_index, g)); +} } diff --git a/include/boost/graph/isomorphism.hpp b/include/boost/graph/isomorphism.hpp index cf70834aa..0deb6e080 100644 --- a/include/boost/graph/isomorphism.hpp +++ b/include/boost/graph/isomorphism.hpp @@ -23,554 +23,681 @@ #include #endif -namespace boost { +namespace boost +{ - namespace detail { +namespace detail +{ - template + template < typename Graph1, typename Graph2, typename IsoMapping, + typename Invariant1, typename Invariant2, typename IndexMap1, + typename IndexMap2 > class isomorphism_algo { - typedef typename graph_traits::vertex_descriptor vertex1_t; - typedef typename graph_traits::vertex_descriptor vertex2_t; - typedef typename graph_traits::edge_descriptor edge1_t; - typedef typename graph_traits::vertices_size_type size_type; - typedef typename Invariant1::result_type invar1_value; - typedef typename Invariant2::result_type invar2_value; - - const Graph1& G1; - const Graph2& G2; - IsoMapping f; - Invariant1 invariant1; - Invariant2 invariant2; - std::size_t max_invariant; - IndexMap1 index_map1; - IndexMap2 index_map2; - - std::vector dfs_vertices; - typedef typename std::vector::iterator vertex_iter; - std::vector dfs_num_vec; - typedef safe_iterator_property_map::iterator, - IndexMap1 + typedef typename graph_traits< Graph1 >::vertex_descriptor vertex1_t; + typedef typename graph_traits< Graph2 >::vertex_descriptor vertex2_t; + typedef typename graph_traits< Graph1 >::edge_descriptor edge1_t; + typedef typename graph_traits< Graph1 >::vertices_size_type size_type; + typedef typename Invariant1::result_type invar1_value; + typedef typename Invariant2::result_type invar2_value; + + const Graph1& G1; + const Graph2& G2; + IsoMapping f; + Invariant1 invariant1; + Invariant2 invariant2; + std::size_t max_invariant; + IndexMap1 index_map1; + IndexMap2 index_map2; + + std::vector< vertex1_t > dfs_vertices; + typedef typename std::vector< vertex1_t >::iterator vertex_iter; + std::vector< int > dfs_num_vec; + typedef safe_iterator_property_map< + typename std::vector< int >::iterator, IndexMap1 #ifdef BOOST_NO_STD_ITERATOR_TRAITS - , int, int& + , + int, int& #endif /* BOOST_NO_STD_ITERATOR_TRAITS */ - > DFSNumMap; - DFSNumMap dfs_num; - std::vector ordered_edges; - typedef typename std::vector::iterator edge_iter; - - std::vector in_S_vec; - typedef safe_iterator_property_map::iterator, - IndexMap2 + > + DFSNumMap; + DFSNumMap dfs_num; + std::vector< edge1_t > ordered_edges; + typedef typename std::vector< edge1_t >::iterator edge_iter; + + std::vector< char > in_S_vec; + typedef safe_iterator_property_map< + typename std::vector< char >::iterator, IndexMap2 #ifdef BOOST_NO_STD_ITERATOR_TRAITS - , char, char& + , + char, char& #endif /* BOOST_NO_STD_ITERATOR_TRAITS */ - > InSMap; - InSMap in_S; - - int num_edges_on_k; - - friend struct compare_multiplicity; - struct compare_multiplicity - { - compare_multiplicity(Invariant1 invariant1, size_type* multiplicity) - : invariant1(invariant1), multiplicity(multiplicity) { } - bool operator()(const vertex1_t& x, const vertex1_t& y) const { - return multiplicity[invariant1(x)] < multiplicity[invariant1(y)]; - } - Invariant1 invariant1; - size_type* multiplicity; - }; - - struct record_dfs_order : default_dfs_visitor - { - record_dfs_order(std::vector& v, std::vector& e) - : vertices(v), edges(e) { } - - void discover_vertex(vertex1_t v, const Graph1&) const { - vertices.push_back(v); - } - void examine_edge(edge1_t e, const Graph1&) const { - edges.push_back(e); - } - std::vector& vertices; - std::vector& edges; - }; - - struct edge_cmp { - edge_cmp(const Graph1& G1, DFSNumMap dfs_num) - : G1(G1), dfs_num(dfs_num) { } - bool operator()(const edge1_t& e1, const edge1_t& e2) const { - using namespace std; - int u1 = dfs_num[source(e1,G1)], v1 = dfs_num[target(e1,G1)]; - int u2 = dfs_num[source(e2,G1)], v2 = dfs_num[target(e2,G1)]; - int m1 = (max)(u1, v1); - int m2 = (max)(u2, v2); - // lexicographical comparison - return std::make_pair(m1, std::make_pair(u1, v1)) - < std::make_pair(m2, std::make_pair(u2, v2)); - } - const Graph1& G1; - DFSNumMap dfs_num; - }; - + > + InSMap; + InSMap in_S; + + int num_edges_on_k; + + friend struct compare_multiplicity; + struct compare_multiplicity + { + compare_multiplicity(Invariant1 invariant1, size_type* multiplicity) + : invariant1(invariant1), multiplicity(multiplicity) + { + } + bool operator()(const vertex1_t& x, const vertex1_t& y) const + { + return multiplicity[invariant1(x)] + < multiplicity[invariant1(y)]; + } + Invariant1 invariant1; + size_type* multiplicity; + }; + + struct record_dfs_order : default_dfs_visitor + { + record_dfs_order( + std::vector< vertex1_t >& v, std::vector< edge1_t >& e) + : vertices(v), edges(e) + { + } + + void discover_vertex(vertex1_t v, const Graph1&) const + { + vertices.push_back(v); + } + void examine_edge(edge1_t e, const Graph1&) const + { + edges.push_back(e); + } + std::vector< vertex1_t >& vertices; + std::vector< edge1_t >& edges; + }; + + struct edge_cmp + { + edge_cmp(const Graph1& G1, DFSNumMap dfs_num) + : G1(G1), dfs_num(dfs_num) + { + } + bool operator()(const edge1_t& e1, const edge1_t& e2) const + { + using namespace std; + int u1 = dfs_num[source(e1, G1)], v1 = dfs_num[target(e1, G1)]; + int u2 = dfs_num[source(e2, G1)], v2 = dfs_num[target(e2, G1)]; + int m1 = (max)(u1, v1); + int m2 = (max)(u2, v2); + // lexicographical comparison + return std::make_pair(m1, std::make_pair(u1, v1)) + < std::make_pair(m2, std::make_pair(u2, v2)); + } + const Graph1& G1; + DFSNumMap dfs_num; + }; + public: - isomorphism_algo(const Graph1& G1, const Graph2& G2, IsoMapping f, - Invariant1 invariant1, Invariant2 invariant2, std::size_t max_invariant, - IndexMap1 index_map1, IndexMap2 index_map2) - : G1(G1), G2(G2), f(f), invariant1(invariant1), invariant2(invariant2), - max_invariant(max_invariant), - index_map1(index_map1), index_map2(index_map2) - { - in_S_vec.resize(num_vertices(G1)); - in_S = make_safe_iterator_property_map - (in_S_vec.begin(), in_S_vec.size(), index_map2 + isomorphism_algo(const Graph1& G1, const Graph2& G2, IsoMapping f, + Invariant1 invariant1, Invariant2 invariant2, + std::size_t max_invariant, IndexMap1 index_map1, + IndexMap2 index_map2) + : G1(G1) + , G2(G2) + , f(f) + , invariant1(invariant1) + , invariant2(invariant2) + , max_invariant(max_invariant) + , index_map1(index_map1) + , index_map2(index_map2) + { + in_S_vec.resize(num_vertices(G1)); + in_S = make_safe_iterator_property_map( + in_S_vec.begin(), in_S_vec.size(), index_map2 #ifdef BOOST_NO_STD_ITERATOR_TRAITS - , in_S_vec.front() + , + in_S_vec.front() #endif /* BOOST_NO_STD_ITERATOR_TRAITS */ - ); - } - - bool test_isomorphism() - { - // reset isomapping - BGL_FORALL_VERTICES_T(v, G1, Graph1) - f[v] = graph_traits::null_vertex(); - - { - std::vector invar1_array; - BGL_FORALL_VERTICES_T(v, G1, Graph1) - invar1_array.push_back(invariant1(v)); - sort(invar1_array); - - std::vector invar2_array; - BGL_FORALL_VERTICES_T(v, G2, Graph2) - invar2_array.push_back(invariant2(v)); - sort(invar2_array); - if (! equal(invar1_array, invar2_array)) - return false; + ); } - - std::vector V_mult; - BGL_FORALL_VERTICES_T(v, G1, Graph1) - V_mult.push_back(v); + + bool test_isomorphism() { - std::vector multiplicity(max_invariant, 0); - BGL_FORALL_VERTICES_T(v, G1, Graph1) - ++multiplicity.at(invariant1(v)); - sort(V_mult, compare_multiplicity(invariant1, &multiplicity[0])); - } - - std::vector color_vec(num_vertices(G1)); - safe_iterator_property_map::iterator, - IndexMap1 + // reset isomapping + BGL_FORALL_VERTICES_T(v, G1, Graph1) + f[v] = graph_traits< Graph2 >::null_vertex(); + + { + std::vector< invar1_value > invar1_array; + BGL_FORALL_VERTICES_T(v, G1, Graph1) + invar1_array.push_back(invariant1(v)); + sort(invar1_array); + + std::vector< invar2_value > invar2_array; + BGL_FORALL_VERTICES_T(v, G2, Graph2) + invar2_array.push_back(invariant2(v)); + sort(invar2_array); + if (!equal(invar1_array, invar2_array)) + return false; + } + + std::vector< vertex1_t > V_mult; + BGL_FORALL_VERTICES_T(v, G1, Graph1) + V_mult.push_back(v); + { + std::vector< size_type > multiplicity(max_invariant, 0); + BGL_FORALL_VERTICES_T(v, G1, Graph1) + ++multiplicity.at(invariant1(v)); + sort( + V_mult, compare_multiplicity(invariant1, &multiplicity[0])); + } + + std::vector< default_color_type > color_vec(num_vertices(G1)); + safe_iterator_property_map< + std::vector< default_color_type >::iterator, IndexMap1 #ifdef BOOST_NO_STD_ITERATOR_TRAITS - , default_color_type, default_color_type& + , + default_color_type, default_color_type& #endif /* BOOST_NO_STD_ITERATOR_TRAITS */ - > - color_map(color_vec.begin(), color_vec.size(), index_map1); - record_dfs_order dfs_visitor(dfs_vertices, ordered_edges); - typedef color_traits Color; - for (vertex_iter u = V_mult.begin(); u != V_mult.end(); ++u) { - if (color_map[*u] == Color::white()) { - dfs_visitor.start_vertex(*u, G1); - depth_first_visit(G1, *u, dfs_visitor, color_map); - } - } - // Create the dfs_num array and dfs_num_map - dfs_num_vec.resize(num_vertices(G1)); - dfs_num = make_safe_iterator_property_map(dfs_num_vec.begin(), - dfs_num_vec.size(), - index_map1 + > + color_map(color_vec.begin(), color_vec.size(), index_map1); + record_dfs_order dfs_visitor(dfs_vertices, ordered_edges); + typedef color_traits< default_color_type > Color; + for (vertex_iter u = V_mult.begin(); u != V_mult.end(); ++u) + { + if (color_map[*u] == Color::white()) + { + dfs_visitor.start_vertex(*u, G1); + depth_first_visit(G1, *u, dfs_visitor, color_map); + } + } + // Create the dfs_num array and dfs_num_map + dfs_num_vec.resize(num_vertices(G1)); + dfs_num = make_safe_iterator_property_map( + dfs_num_vec.begin(), dfs_num_vec.size(), index_map1 #ifdef BOOST_NO_STD_ITERATOR_TRAITS - , dfs_num_vec.front() + , + dfs_num_vec.front() #endif /* BOOST_NO_STD_ITERATOR_TRAITS */ - ); - size_type n = 0; - for (vertex_iter v = dfs_vertices.begin(); v != dfs_vertices.end(); ++v) - dfs_num[*v] = n++; - - sort(ordered_edges, edge_cmp(G1, dfs_num)); - - - int dfs_num_k = -1; - return this->match(ordered_edges.begin(), dfs_num_k); - } - + ); + size_type n = 0; + for (vertex_iter v = dfs_vertices.begin(); v != dfs_vertices.end(); + ++v) + dfs_num[*v] = n++; + + sort(ordered_edges, edge_cmp(G1, dfs_num)); + + int dfs_num_k = -1; + return this->match(ordered_edges.begin(), dfs_num_k); + } + private: - struct match_continuation { - enum {pos_G2_vertex_loop, pos_fi_adj_loop, pos_dfs_num} position; - typedef typename graph_traits::vertex_iterator vertex_iterator; - std::pair G2_verts; - typedef typename graph_traits::adjacency_iterator adjacency_iterator; - std::pair fi_adj; - edge_iter iter; - int dfs_num_k; - }; - - bool match(edge_iter iter, int dfs_num_k) - { - std::vector k; - typedef typename graph_traits::vertex_iterator vertex_iterator; - std::pair G2_verts(vertices(G2)); - typedef typename graph_traits::adjacency_iterator adjacency_iterator; - std::pair fi_adj; - vertex1_t i, j; + struct match_continuation + { + enum + { + pos_G2_vertex_loop, + pos_fi_adj_loop, + pos_dfs_num + } position; + typedef typename graph_traits< Graph2 >::vertex_iterator + vertex_iterator; + std::pair< vertex_iterator, vertex_iterator > G2_verts; + typedef typename graph_traits< Graph2 >::adjacency_iterator + adjacency_iterator; + std::pair< adjacency_iterator, adjacency_iterator > fi_adj; + edge_iter iter; + int dfs_num_k; + }; + + bool match(edge_iter iter, int dfs_num_k) + { + std::vector< match_continuation > k; + typedef typename graph_traits< Graph2 >::vertex_iterator + vertex_iterator; + std::pair< vertex_iterator, vertex_iterator > G2_verts( + vertices(G2)); + typedef typename graph_traits< Graph2 >::adjacency_iterator + adjacency_iterator; + std::pair< adjacency_iterator, adjacency_iterator > fi_adj; + vertex1_t i, j; recur: - if (iter != ordered_edges.end()) { - i = source(*iter, G1); - j = target(*iter, G1); - if (dfs_num[i] > dfs_num_k) { - G2_verts = vertices(G2); - while (G2_verts.first != G2_verts.second) { - { - vertex2_t u = *G2_verts.first; - vertex1_t kp1 = dfs_vertices[dfs_num_k + 1]; - if (invariant1(kp1) == invariant2(u) && in_S[u] == false) { - { - f[kp1] = u; - in_S[u] = true; - num_edges_on_k = 0; - - match_continuation new_k; - new_k.position = match_continuation::pos_G2_vertex_loop; - new_k.G2_verts = G2_verts; - new_k.iter = iter; - new_k.dfs_num_k = dfs_num_k; - k.push_back(new_k); - ++dfs_num_k; - goto recur; - } + if (iter != ordered_edges.end()) + { + i = source(*iter, G1); + j = target(*iter, G1); + if (dfs_num[i] > dfs_num_k) + { + G2_verts = vertices(G2); + while (G2_verts.first != G2_verts.second) + { + { + vertex2_t u = *G2_verts.first; + vertex1_t kp1 = dfs_vertices[dfs_num_k + 1]; + if (invariant1(kp1) == invariant2(u) + && in_S[u] == false) + { + { + f[kp1] = u; + in_S[u] = true; + num_edges_on_k = 0; + + match_continuation new_k; + new_k.position = match_continuation:: + pos_G2_vertex_loop; + new_k.G2_verts = G2_verts; + new_k.iter = iter; + new_k.dfs_num_k = dfs_num_k; + k.push_back(new_k); + ++dfs_num_k; + goto recur; + } + } + } + G2_loop_k: + ++G2_verts.first; + } + } + else if (dfs_num[j] > dfs_num_k) + { + { + vertex1_t vk = dfs_vertices[dfs_num_k]; + num_edges_on_k -= count_if(adjacent_vertices(f[vk], G2), + make_indirect_pmap(in_S)); + + for (int jj = 0; jj < dfs_num_k; ++jj) + { + vertex1_t j = dfs_vertices[jj]; + num_edges_on_k + -= count(adjacent_vertices(f[j], G2), f[vk]); + } + } + + if (num_edges_on_k != 0) + goto return_point_false; + fi_adj = adjacent_vertices(f[i], G2); + while (fi_adj.first != fi_adj.second) + { + { + vertex2_t v = *fi_adj.first; + if (invariant2(v) == invariant1(j) + && in_S[v] == false) + { + f[j] = v; + in_S[v] = true; + num_edges_on_k = 1; + BOOST_USING_STD_MAX(); + int next_k + = max BOOST_PREVENT_MACRO_SUBSTITUTION( + dfs_num_k, + max BOOST_PREVENT_MACRO_SUBSTITUTION( + dfs_num[i], dfs_num[j])); + match_continuation new_k; + new_k.position + = match_continuation::pos_fi_adj_loop; + new_k.fi_adj = fi_adj; + new_k.iter = iter; + new_k.dfs_num_k = dfs_num_k; + ++iter; + dfs_num_k = next_k; + k.push_back(new_k); + goto recur; + } + } + fi_adj_loop_k: + ++fi_adj.first; + } + } + else + { + if (container_contains(adjacent_vertices(f[i], G2), f[j])) + { + ++num_edges_on_k; + match_continuation new_k; + new_k.position = match_continuation::pos_dfs_num; + k.push_back(new_k); + ++iter; + goto recur; + } } - } -G2_loop_k: ++G2_verts.first; } - - } - else if (dfs_num[j] > dfs_num_k) { + else + goto return_point_true; + goto return_point_false; + { - vertex1_t vk = dfs_vertices[dfs_num_k]; - num_edges_on_k -= - count_if(adjacent_vertices(f[vk], G2), make_indirect_pmap(in_S)); - - for (int jj = 0; jj < dfs_num_k; ++jj) { - vertex1_t j = dfs_vertices[jj]; - num_edges_on_k -= count(adjacent_vertices(f[j], G2), f[vk]); - } - } - - if (num_edges_on_k != 0) - goto return_point_false; - fi_adj = adjacent_vertices(f[i], G2); - while (fi_adj.first != fi_adj.second) { - { - vertex2_t v = *fi_adj.first; - if (invariant2(v) == invariant1(j) && in_S[v] == false) { - f[j] = v; - in_S[v] = true; - num_edges_on_k = 1; - BOOST_USING_STD_MAX(); - int next_k = max BOOST_PREVENT_MACRO_SUBSTITUTION(dfs_num_k, max BOOST_PREVENT_MACRO_SUBSTITUTION(dfs_num[i], dfs_num[j])); - match_continuation new_k; - new_k.position = match_continuation::pos_fi_adj_loop; - new_k.fi_adj = fi_adj; - new_k.iter = iter; - new_k.dfs_num_k = dfs_num_k; - ++iter; - dfs_num_k = next_k; - k.push_back(new_k); - goto recur; + return_point_true: + return true; + + return_point_false: + if (k.empty()) + return false; + const match_continuation& this_k = k.back(); + switch (this_k.position) + { + case match_continuation::pos_G2_vertex_loop: + { + G2_verts = this_k.G2_verts; + iter = this_k.iter; + dfs_num_k = this_k.dfs_num_k; + k.pop_back(); + in_S[*G2_verts.first] = false; + i = source(*iter, G1); + j = target(*iter, G1); + goto G2_loop_k; } - } -fi_adj_loop_k:++fi_adj.first; - } - } - else { - if (container_contains(adjacent_vertices(f[i], G2), f[j])) { - ++num_edges_on_k; - match_continuation new_k; - new_k.position = match_continuation::pos_dfs_num; - k.push_back(new_k); - ++iter; - goto recur; - } - - } - } else - goto return_point_true; - goto return_point_false; - - { - return_point_true: return true; - - return_point_false: - if (k.empty()) return false; - const match_continuation& this_k = k.back(); - switch (this_k.position) { - case match_continuation::pos_G2_vertex_loop: {G2_verts = this_k.G2_verts; iter = this_k.iter; dfs_num_k = this_k.dfs_num_k; k.pop_back(); in_S[*G2_verts.first] = false; i = source(*iter, G1); j = target(*iter, G1); goto G2_loop_k;} - case match_continuation::pos_fi_adj_loop: {fi_adj = this_k.fi_adj; iter = this_k.iter; dfs_num_k = this_k.dfs_num_k; k.pop_back(); in_S[*fi_adj.first] = false; i = source(*iter, G1); j = target(*iter, G1); goto fi_adj_loop_k;} - case match_continuation::pos_dfs_num: {k.pop_back(); goto return_point_false;} - default: { - BOOST_ASSERT(!"Bad position"); + case match_continuation::pos_fi_adj_loop: + { + fi_adj = this_k.fi_adj; + iter = this_k.iter; + dfs_num_k = this_k.dfs_num_k; + k.pop_back(); + in_S[*fi_adj.first] = false; + i = source(*iter, G1); + j = target(*iter, G1); + goto fi_adj_loop_k; + } + case match_continuation::pos_dfs_num: + { + k.pop_back(); + goto return_point_false; + } + default: + { + BOOST_ASSERT(!"Bad position"); #ifdef UNDER_CE - exit(-1); + exit(-1); #else - abort(); + abort(); #endif + } + } } - } } - } }; - - template + template < typename Graph, typename InDegreeMap > void compute_in_degree(const Graph& g, InDegreeMap in_degree_map) { - BGL_FORALL_VERTICES_T(v, g, Graph) + BGL_FORALL_VERTICES_T(v, g, Graph) put(in_degree_map, v, 0); - BGL_FORALL_VERTICES_T(u, g, Graph) + BGL_FORALL_VERTICES_T(u, g, Graph) BGL_FORALL_ADJ_T(u, v, g, Graph) put(in_degree_map, v, get(in_degree_map, v) + 1); } - } // namespace detail +} // namespace detail +template < typename InDegreeMap, typename Graph > class degree_vertex_invariant +{ + typedef typename graph_traits< Graph >::vertex_descriptor vertex_t; + typedef typename graph_traits< Graph >::degree_size_type size_type; - template - class degree_vertex_invariant - { - typedef typename graph_traits::vertex_descriptor vertex_t; - typedef typename graph_traits::degree_size_type size_type; - public: +public: typedef vertex_t argument_type; typedef size_type result_type; degree_vertex_invariant(const InDegreeMap& in_degree_map, const Graph& g) - : m_in_degree_map(in_degree_map), - m_max_vertex_in_degree(0), - m_max_vertex_out_degree(0), - m_g(g) { - BGL_FORALL_VERTICES_T(v, g, Graph) { - m_max_vertex_in_degree = - (std::max)(m_max_vertex_in_degree, get(m_in_degree_map, v)); - m_max_vertex_out_degree = - (std::max)(m_max_vertex_out_degree, out_degree(v, g)); - } + : m_in_degree_map(in_degree_map) + , m_max_vertex_in_degree(0) + , m_max_vertex_out_degree(0) + , m_g(g) + { + BGL_FORALL_VERTICES_T(v, g, Graph) + { + m_max_vertex_in_degree + = (std::max)(m_max_vertex_in_degree, get(m_in_degree_map, v)); + m_max_vertex_out_degree + = (std::max)(m_max_vertex_out_degree, out_degree(v, g)); + } } - size_type operator()(vertex_t v) const { - return (m_max_vertex_in_degree + 1) * out_degree(v, m_g) - + get(m_in_degree_map, v); + size_type operator()(vertex_t v) const + { + return (m_max_vertex_in_degree + 1) * out_degree(v, m_g) + + get(m_in_degree_map, v); } // The largest possible vertex invariant number - size_type max BOOST_PREVENT_MACRO_SUBSTITUTION () const { - return (m_max_vertex_in_degree + 1) * (m_max_vertex_out_degree + 1); + size_type max BOOST_PREVENT_MACRO_SUBSTITUTION() const + { + return (m_max_vertex_in_degree + 1) * (m_max_vertex_out_degree + 1); } - private: + +private: InDegreeMap m_in_degree_map; size_type m_max_vertex_in_degree; size_type m_max_vertex_out_degree; const Graph& m_g; - }; - - // Count actual number of vertices, even in filtered graphs. - template - size_t count_vertices(const Graph& g) - { - size_t n = 0; - BGL_FORALL_VERTICES_T(v, g, Graph) {(void)v; ++n;} - return n; - } - - template - bool isomorphism(const Graph1& G1, const Graph2& G2, IsoMapping f, - Invariant1 invariant1, Invariant2 invariant2, - std::size_t max_invariant, - IndexMap1 index_map1, IndexMap2 index_map2) - - { +}; + +// Count actual number of vertices, even in filtered graphs. +template < typename Graph > size_t count_vertices(const Graph& g) +{ + size_t n = 0; + BGL_FORALL_VERTICES_T(v, g, Graph) + { + (void)v; + ++n; + } + return n; +} + +template < typename Graph1, typename Graph2, typename IsoMapping, + typename Invariant1, typename Invariant2, typename IndexMap1, + typename IndexMap2 > +bool isomorphism(const Graph1& G1, const Graph2& G2, IsoMapping f, + Invariant1 invariant1, Invariant2 invariant2, std::size_t max_invariant, + IndexMap1 index_map1, IndexMap2 index_map2) + +{ // Graph requirements - BOOST_CONCEPT_ASSERT(( VertexListGraphConcept )); - BOOST_CONCEPT_ASSERT(( EdgeListGraphConcept )); - BOOST_CONCEPT_ASSERT(( VertexListGraphConcept )); - //BOOST_CONCEPT_ASSERT(( BidirectionalGraphConcept )); - - typedef typename graph_traits::vertex_descriptor vertex1_t; - typedef typename graph_traits::vertex_descriptor vertex2_t; - typedef typename graph_traits::vertices_size_type size_type; - + BOOST_CONCEPT_ASSERT((VertexListGraphConcept< Graph1 >)); + BOOST_CONCEPT_ASSERT((EdgeListGraphConcept< Graph1 >)); + BOOST_CONCEPT_ASSERT((VertexListGraphConcept< Graph2 >)); + // BOOST_CONCEPT_ASSERT(( BidirectionalGraphConcept )); + + typedef typename graph_traits< Graph1 >::vertex_descriptor vertex1_t; + typedef typename graph_traits< Graph2 >::vertex_descriptor vertex2_t; + typedef typename graph_traits< Graph1 >::vertices_size_type size_type; + // Vertex invariant requirement - BOOST_CONCEPT_ASSERT(( AdaptableUnaryFunctionConcept )); - BOOST_CONCEPT_ASSERT(( AdaptableUnaryFunctionConcept )); - + BOOST_CONCEPT_ASSERT( + (AdaptableUnaryFunctionConcept< Invariant1, size_type, vertex1_t >)); + BOOST_CONCEPT_ASSERT( + (AdaptableUnaryFunctionConcept< Invariant2, size_type, vertex2_t >)); + // Property map requirements - BOOST_CONCEPT_ASSERT(( ReadWritePropertyMapConcept )); - typedef typename property_traits::value_type IsoMappingValue; - BOOST_STATIC_ASSERT((is_convertible::value)); - - BOOST_CONCEPT_ASSERT(( ReadablePropertyMapConcept )); - typedef typename property_traits::value_type IndexMap1Value; - BOOST_STATIC_ASSERT((is_convertible::value)); - - BOOST_CONCEPT_ASSERT(( ReadablePropertyMapConcept )); - typedef typename property_traits::value_type IndexMap2Value; - BOOST_STATIC_ASSERT((is_convertible::value)); - + BOOST_CONCEPT_ASSERT( + (ReadWritePropertyMapConcept< IsoMapping, vertex1_t >)); + typedef typename property_traits< IsoMapping >::value_type IsoMappingValue; + BOOST_STATIC_ASSERT((is_convertible< IsoMappingValue, vertex2_t >::value)); + + BOOST_CONCEPT_ASSERT((ReadablePropertyMapConcept< IndexMap1, vertex1_t >)); + typedef typename property_traits< IndexMap1 >::value_type IndexMap1Value; + BOOST_STATIC_ASSERT((is_convertible< IndexMap1Value, size_type >::value)); + + BOOST_CONCEPT_ASSERT((ReadablePropertyMapConcept< IndexMap2, vertex2_t >)); + typedef typename property_traits< IndexMap2 >::value_type IndexMap2Value; + BOOST_STATIC_ASSERT((is_convertible< IndexMap2Value, size_type >::value)); + if (count_vertices(G1) != count_vertices(G2)) - return false; + return false; if (count_vertices(G1) == 0 && count_vertices(G2) == 0) - return true; - - detail::isomorphism_algo - algo(G1, G2, f, invariant1, invariant2, max_invariant, - index_map1, index_map2); + return true; + + detail::isomorphism_algo< Graph1, Graph2, IsoMapping, Invariant1, + Invariant2, IndexMap1, IndexMap2 > + algo(G1, G2, f, invariant1, invariant2, max_invariant, index_map1, + index_map2); return algo.test_isomorphism(); - } - - - namespace detail { - - template - bool isomorphism_impl(const Graph1& G1, const Graph2& G2, - IsoMapping f, IndexMap1 index_map1, IndexMap2 index_map2, - const bgl_named_params& params) +} + +namespace detail +{ + + template < typename Graph1, typename Graph2, typename IsoMapping, + typename IndexMap1, typename IndexMap2, typename P, typename T, + typename R > + bool isomorphism_impl(const Graph1& G1, const Graph2& G2, IsoMapping f, + IndexMap1 index_map1, IndexMap2 index_map2, + const bgl_named_params< P, T, R >& params) { - std::vector in_degree1_vec(num_vertices(G1)); - typedef safe_iterator_property_map::iterator, - IndexMap1 + std::vector< std::size_t > in_degree1_vec(num_vertices(G1)); + typedef safe_iterator_property_map< + std::vector< std::size_t >::iterator, IndexMap1 #ifdef BOOST_NO_STD_ITERATOR_TRAITS - , std::size_t, std::size_t& + , + std::size_t, std::size_t& #endif /* BOOST_NO_STD_ITERATOR_TRAITS */ - > InDeg1; - InDeg1 in_degree1(in_degree1_vec.begin(), in_degree1_vec.size(), index_map1); - compute_in_degree(G1, in_degree1); + > + InDeg1; + InDeg1 in_degree1( + in_degree1_vec.begin(), in_degree1_vec.size(), index_map1); + compute_in_degree(G1, in_degree1); - std::vector in_degree2_vec(num_vertices(G2)); - typedef safe_iterator_property_map::iterator, - IndexMap2 + std::vector< std::size_t > in_degree2_vec(num_vertices(G2)); + typedef safe_iterator_property_map< + std::vector< std::size_t >::iterator, IndexMap2 #ifdef BOOST_NO_STD_ITERATOR_TRAITS - , std::size_t, std::size_t& + , + std::size_t, std::size_t& #endif /* BOOST_NO_STD_ITERATOR_TRAITS */ - > InDeg2; - InDeg2 in_degree2(in_degree2_vec.begin(), in_degree2_vec.size(), index_map2); - compute_in_degree(G2, in_degree2); - - degree_vertex_invariant invariant1(in_degree1, G1); - degree_vertex_invariant invariant2(in_degree2, G2); - - return isomorphism(G1, G2, f, - choose_param(get_param(params, vertex_invariant1_t()), invariant1), - choose_param(get_param(params, vertex_invariant2_t()), invariant2), - choose_param(get_param(params, vertex_max_invariant_t()), (invariant2.max)()), - index_map1, index_map2 - ); - } - - template - struct make_degree_invariant { - const G& g; - const Index& index; - make_degree_invariant(const G& g, const Index& index): g(g), index(index) {} - typedef typename boost::graph_traits::degree_size_type degree_size_type; - typedef shared_array_property_map prop_map_type; - typedef degree_vertex_invariant result_type; - result_type operator()() const { - prop_map_type pm = make_shared_array_property_map(num_vertices(g), degree_size_type(), index); - compute_in_degree(g, pm); - return result_type(pm, g); - } + > + InDeg2; + InDeg2 in_degree2( + in_degree2_vec.begin(), in_degree2_vec.size(), index_map2); + compute_in_degree(G2, in_degree2); + + degree_vertex_invariant< InDeg1, Graph1 > invariant1(in_degree1, G1); + degree_vertex_invariant< InDeg2, Graph2 > invariant2(in_degree2, G2); + + return isomorphism(G1, G2, f, + choose_param(get_param(params, vertex_invariant1_t()), invariant1), + choose_param(get_param(params, vertex_invariant2_t()), invariant2), + choose_param(get_param(params, vertex_max_invariant_t()), + (invariant2.max)()), + index_map1, index_map2); + } + + template < typename G, typename Index > struct make_degree_invariant + { + const G& g; + const Index& index; + make_degree_invariant(const G& g, const Index& index) + : g(g), index(index) + { + } + typedef typename boost::graph_traits< G >::degree_size_type + degree_size_type; + typedef shared_array_property_map< degree_size_type, Index > + prop_map_type; + typedef degree_vertex_invariant< prop_map_type, G > result_type; + result_type operator()() const + { + prop_map_type pm = make_shared_array_property_map( + num_vertices(g), degree_size_type(), index); + compute_in_degree(g, pm); + return result_type(pm, g); + } }; - - } // namespace detail - - namespace graph { - namespace detail { - template - struct isomorphism_impl { - typedef bool result_type; - typedef result_type type; - template - bool operator()(const Graph1& g1, const Graph2& g2, const ArgPack& arg_pack) const { - using namespace boost::graph::keywords; - typedef typename boost::detail::override_const_property_result::type index1_map_type; - typedef typename boost::detail::override_const_property_result::type index2_map_type; - index1_map_type index1_map = boost::detail::override_const_property(arg_pack, _vertex_index1_map, g1, boost::vertex_index); - index2_map_type index2_map = boost::detail::override_const_property(arg_pack, _vertex_index2_map, g2, boost::vertex_index); - typedef typename graph_traits::vertex_descriptor vertex2_t; - typename std::vector::size_type n = (typename std::vector::size_type)num_vertices(g1); - std::vector f(n); - typename boost::parameter::lazy_binding< - ArgPack, - tag::vertex_invariant1, - boost::detail::make_degree_invariant >::type - invariant1 = - arg_pack[_vertex_invariant1 || boost::detail::make_degree_invariant(g1, index1_map)]; - typename boost::parameter::lazy_binding< - ArgPack, - tag::vertex_invariant2, - boost::detail::make_degree_invariant >::type - invariant2 = - arg_pack[_vertex_invariant2 || boost::detail::make_degree_invariant(g2, index2_map)]; - return boost::isomorphism - (g1, g2, - choose_param(arg_pack[_isomorphism_map | boost::param_not_found()], - make_shared_array_property_map(num_vertices(g1), vertex2_t(), index1_map)), - invariant1, - invariant2, + +} // namespace detail + +namespace graph +{ + namespace detail + { + template < typename Graph1, typename Graph2 > struct isomorphism_impl + { + typedef bool result_type; + typedef result_type type; + template < typename ArgPack > + bool operator()(const Graph1& g1, const Graph2& g2, + const ArgPack& arg_pack) const + { + using namespace boost::graph::keywords; + typedef typename boost::detail::override_const_property_result< + ArgPack, tag::vertex_index1_map, boost::vertex_index_t, + Graph1 >::type index1_map_type; + typedef typename boost::detail::override_const_property_result< + ArgPack, tag::vertex_index2_map, boost::vertex_index_t, + Graph2 >::type index2_map_type; + index1_map_type index1_map + = boost::detail::override_const_property( + arg_pack, _vertex_index1_map, g1, boost::vertex_index); + index2_map_type index2_map + = boost::detail::override_const_property( + arg_pack, _vertex_index2_map, g2, boost::vertex_index); + typedef typename graph_traits< Graph2 >::vertex_descriptor + vertex2_t; + typename std::vector< vertex2_t >::size_type n + = (typename std::vector< vertex2_t >::size_type) + num_vertices(g1); + std::vector< vertex2_t > f(n); + typename boost::parameter::lazy_binding< ArgPack, + tag::vertex_invariant1, + boost::detail::make_degree_invariant< Graph1, + index1_map_type > >::type invariant1 + = arg_pack[_vertex_invariant1 + || boost::detail::make_degree_invariant< Graph1, + index1_map_type >(g1, index1_map)]; + typename boost::parameter::lazy_binding< ArgPack, + tag::vertex_invariant2, + boost::detail::make_degree_invariant< Graph2, + index2_map_type > >::type invariant2 + = arg_pack[_vertex_invariant2 + || boost::detail::make_degree_invariant< Graph2, + index2_map_type >(g2, index2_map)]; + return boost::isomorphism(g1, g2, + choose_param( + arg_pack[_isomorphism_map | boost::param_not_found()], + make_shared_array_property_map( + num_vertices(g1), vertex2_t(), index1_map)), + invariant1, invariant2, arg_pack[_vertex_max_invariant | (invariant2.max)()], - index1_map, - index2_map); - } - }; + index1_map, index2_map); + } + }; } BOOST_GRAPH_MAKE_FORWARDING_FUNCTION(isomorphism, 2, 6) - } - - // Named parameter interface - BOOST_GRAPH_MAKE_OLD_STYLE_PARAMETER_FUNCTION(isomorphism, 2) - - // Verify that the given mapping iso_map from the vertices of g1 to the - // vertices of g2 describes an isomorphism. - // Note: this could be made much faster by specializing based on the graph - // concepts modeled, but since we're verifying an O(n^(lg n)) algorithm, - // O(n^4) won't hurt us. - template - inline bool verify_isomorphism(const Graph1& g1, const Graph2& g2, IsoMap iso_map) - { +} + +// Named parameter interface +BOOST_GRAPH_MAKE_OLD_STYLE_PARAMETER_FUNCTION(isomorphism, 2) + +// Verify that the given mapping iso_map from the vertices of g1 to the +// vertices of g2 describes an isomorphism. +// Note: this could be made much faster by specializing based on the graph +// concepts modeled, but since we're verifying an O(n^(lg n)) algorithm, +// O(n^4) won't hurt us. +template < typename Graph1, typename Graph2, typename IsoMap > +inline bool verify_isomorphism( + const Graph1& g1, const Graph2& g2, IsoMap iso_map) +{ #if 0 // problematic for filtered_graph! if (num_vertices(g1) != num_vertices(g2) || num_edges(g1) != num_edges(g2)) return false; #endif - - BGL_FORALL_EDGES_T(e1, g1, Graph1) { - bool found_edge = false; - BGL_FORALL_EDGES_T(e2, g2, Graph2) { - if (source(e2, g2) == get(iso_map, source(e1, g1)) && - target(e2, g2) == get(iso_map, target(e1, g1))) { - found_edge = true; + + BGL_FORALL_EDGES_T(e1, g1, Graph1) + { + bool found_edge = false; + BGL_FORALL_EDGES_T(e2, g2, Graph2) + { + if (source(e2, g2) == get(iso_map, source(e1, g1)) + && target(e2, g2) == get(iso_map, target(e1, g1))) + { + found_edge = true; + } } - } - - if (!found_edge) - return false; + + if (!found_edge) + return false; } - + return true; - } +} } // namespace boost diff --git a/include/boost/graph/iteration_macros.hpp b/include/boost/graph/iteration_macros.hpp index 2bf40f958..0b830315c 100644 --- a/include/boost/graph/iteration_macros.hpp +++ b/include/boost/graph/iteration_macros.hpp @@ -12,8 +12,8 @@ #include -#define BGL_CAT(x,y) x ## y -#define BGL_RANGE(linenum) BGL_CAT(bgl_range_,linenum) +#define BGL_CAT(x, y) x##y +#define BGL_RANGE(linenum) BGL_CAT(bgl_range_, linenum) #define BGL_FIRST(linenum) (BGL_RANGE(linenum).first) #define BGL_LAST(linenum) (BGL_RANGE(linenum).second) @@ -21,7 +21,7 @@ BGL_FORALL_VERTICES_T(v, g, graph_t) // This is on line 9 expands to the following, but all on the same line - for (typename boost::graph_traits::vertex_iterator + for (typename boost::graph_traits::vertex_iterator bgl_first_9 = vertices(g).first, bgl_last_9 = vertices(g).second; bgl_first_9 != bgl_last_9; bgl_first_9 = bgl_last_9) for (typename boost::graph_traits::vertex_descriptor v; @@ -39,102 +39,158 @@ Use the _T versions when the graph type is a template parameter or dependent on a template parameter. Otherwise use the non _T versions. - + ----------------------- 6/9/09 THK - + The above contains two calls to the vertices function. I modified these macros to expand to - + for (std::pair::vertex_iterator, - typename boost::graph_traits::vertex_iterator> bgl_range_9 = vertices(g); - bgl_range_9.first != bgl_range_9.second; + typename boost::graph_traits::vertex_iterator> + bgl_range_9 = vertices(g); bgl_range_9.first != bgl_range_9.second; bgl_range_9.first = bgl_range_9.second) for (typename boost::graph_traits::vertex_descriptor v; - bgl_range_9.first != bgl_range_9.second ? (v = *bgl_range_9.first, true) : false; + bgl_range_9.first != bgl_range_9.second ? (v = *bgl_range_9.first, + true) : false; ++bgl_range_9.first) - - */ + */ -#define BGL_FORALL_VERTICES_T(VNAME, GNAME, GraphType) \ -for (std::pair::vertex_iterator, \ - typename boost::graph_traits::vertex_iterator> BGL_RANGE(__LINE__) = vertices(GNAME); \ - BGL_FIRST(__LINE__) != BGL_LAST(__LINE__); BGL_FIRST(__LINE__) = BGL_LAST(__LINE__)) \ - for (typename boost::graph_traits::vertex_descriptor VNAME; \ - BGL_FIRST(__LINE__) != BGL_LAST(__LINE__) ? (VNAME = *BGL_FIRST(__LINE__), true):false; \ - ++BGL_FIRST(__LINE__)) - -#define BGL_FORALL_VERTICES(VNAME, GNAME, GraphType) \ -for (std::pair::vertex_iterator, \ - boost::graph_traits::vertex_iterator> BGL_RANGE(__LINE__) = vertices(GNAME); \ - BGL_FIRST(__LINE__) != BGL_LAST(__LINE__); BGL_FIRST(__LINE__) = BGL_LAST(__LINE__)) \ - for (boost::graph_traits::vertex_descriptor VNAME; \ - BGL_FIRST(__LINE__) != BGL_LAST(__LINE__) ? (VNAME = *BGL_FIRST(__LINE__), true):false; \ - ++BGL_FIRST(__LINE__)) - -#define BGL_FORALL_EDGES_T(ENAME, GNAME, GraphType) \ -for (std::pair::edge_iterator, \ - typename boost::graph_traits::edge_iterator> BGL_RANGE(__LINE__) = edges(GNAME); \ - BGL_FIRST(__LINE__) != BGL_LAST(__LINE__); BGL_FIRST(__LINE__) = BGL_LAST(__LINE__)) \ - for (typename boost::graph_traits::edge_descriptor ENAME; \ - BGL_FIRST(__LINE__) != BGL_LAST(__LINE__) ? (ENAME = *BGL_FIRST(__LINE__), true):false; \ - ++BGL_FIRST(__LINE__)) - -#define BGL_FORALL_EDGES(ENAME, GNAME, GraphType) \ -for (std::pair::edge_iterator, \ - boost::graph_traits::edge_iterator> BGL_RANGE(__LINE__) = edges(GNAME); \ - BGL_FIRST(__LINE__) != BGL_LAST(__LINE__); BGL_FIRST(__LINE__) = BGL_LAST(__LINE__)) \ - for (boost::graph_traits::edge_descriptor ENAME; \ - BGL_FIRST(__LINE__) != BGL_LAST(__LINE__) ? (ENAME = *BGL_FIRST(__LINE__), true):false; \ - ++BGL_FIRST(__LINE__)) - -#define BGL_FORALL_ADJ_T(UNAME, VNAME, GNAME, GraphType) \ -for (std::pair::adjacency_iterator, \ - typename boost::graph_traits::adjacency_iterator> BGL_RANGE(__LINE__) = adjacent_vertices(UNAME, GNAME); \ - BGL_FIRST(__LINE__) != BGL_LAST(__LINE__); BGL_FIRST(__LINE__) = BGL_LAST(__LINE__)) \ -for (typename boost::graph_traits::vertex_descriptor VNAME; \ - BGL_FIRST(__LINE__) != BGL_LAST(__LINE__) ? (VNAME = *BGL_FIRST(__LINE__), true) : false; \ - ++BGL_FIRST(__LINE__)) - -#define BGL_FORALL_ADJ(UNAME, VNAME, GNAME, GraphType) \ -for (std::pair::adjacency_iterator, \ - boost::graph_traits::adjacency_iterator> BGL_RANGE(__LINE__) = adjacent_vertices(UNAME, GNAME); \ - BGL_FIRST(__LINE__) != BGL_LAST(__LINE__); BGL_FIRST(__LINE__) = BGL_LAST(__LINE__)) \ -for (boost::graph_traits::vertex_descriptor VNAME; \ - BGL_FIRST(__LINE__) != BGL_LAST(__LINE__) ? (VNAME = *BGL_FIRST(__LINE__), true) : false; \ - ++BGL_FIRST(__LINE__)) - -#define BGL_FORALL_OUTEDGES_T(UNAME, ENAME, GNAME, GraphType) \ -for (std::pair::out_edge_iterator, \ - typename boost::graph_traits::out_edge_iterator> BGL_RANGE(__LINE__) = out_edges(UNAME, GNAME); \ - BGL_FIRST(__LINE__) != BGL_LAST(__LINE__); BGL_FIRST(__LINE__) = BGL_LAST(__LINE__)) \ -for (typename boost::graph_traits::edge_descriptor ENAME; \ - BGL_FIRST(__LINE__) != BGL_LAST(__LINE__) ? (ENAME = *BGL_FIRST(__LINE__), true) : false; \ - ++BGL_FIRST(__LINE__)) - -#define BGL_FORALL_OUTEDGES(UNAME, ENAME, GNAME, GraphType) \ -for (std::pair::out_edge_iterator, \ - boost::graph_traits::out_edge_iterator> BGL_RANGE(__LINE__) = out_edges(UNAME, GNAME); \ - BGL_FIRST(__LINE__) != BGL_LAST(__LINE__); BGL_FIRST(__LINE__) = BGL_LAST(__LINE__)) \ -for (boost::graph_traits::edge_descriptor ENAME; \ - BGL_FIRST(__LINE__) != BGL_LAST(__LINE__) ? (ENAME = *BGL_FIRST(__LINE__), true) : false; \ - ++BGL_FIRST(__LINE__)) - -#define BGL_FORALL_INEDGES_T(UNAME, ENAME, GNAME, GraphType) \ -for (std::pair::in_edge_iterator, \ - typename boost::graph_traits::in_edge_iterator> BGL_RANGE(__LINE__) = in_edges(UNAME, GNAME); \ - BGL_FIRST(__LINE__) != BGL_LAST(__LINE__); BGL_FIRST(__LINE__) = BGL_LAST(__LINE__)) \ -for (typename boost::graph_traits::edge_descriptor ENAME; \ - BGL_FIRST(__LINE__) != BGL_LAST(__LINE__) ? (ENAME = *BGL_FIRST(__LINE__), true) : false; \ - ++BGL_FIRST(__LINE__)) - -#define BGL_FORALL_INEDGES(UNAME, ENAME, GNAME, GraphType) \ -for (std::pair::in_edge_iterator, \ - boost::graph_traits::in_edge_iterator> BGL_RANGE(__LINE__) = in_edges(UNAME, GNAME); \ - BGL_FIRST(__LINE__) != BGL_LAST(__LINE__); BGL_FIRST(__LINE__) = BGL_LAST(__LINE__)) \ -for (boost::graph_traits::edge_descriptor ENAME; \ - BGL_FIRST(__LINE__) != BGL_LAST(__LINE__) ? (ENAME = *BGL_FIRST(__LINE__), true) : false; \ - ++BGL_FIRST(__LINE__)) +#define BGL_FORALL_VERTICES_T(VNAME, GNAME, GraphType) \ + for (std::pair< \ + typename boost::graph_traits< GraphType >::vertex_iterator, \ + typename boost::graph_traits< GraphType >::vertex_iterator > \ + BGL_RANGE(__LINE__) \ + = vertices(GNAME); \ + BGL_FIRST(__LINE__) != BGL_LAST(__LINE__); \ + BGL_FIRST(__LINE__) = BGL_LAST(__LINE__)) \ + for (typename boost::graph_traits< GraphType >::vertex_descriptor \ + VNAME; \ + BGL_FIRST(__LINE__) != BGL_LAST(__LINE__) \ + ? (VNAME = *BGL_FIRST(__LINE__), true) \ + : false; \ + ++BGL_FIRST(__LINE__)) + +#define BGL_FORALL_VERTICES(VNAME, GNAME, GraphType) \ + for (std::pair< boost::graph_traits< GraphType >::vertex_iterator, \ + boost::graph_traits< GraphType >::vertex_iterator > \ + BGL_RANGE(__LINE__) \ + = vertices(GNAME); \ + BGL_FIRST(__LINE__) != BGL_LAST(__LINE__); \ + BGL_FIRST(__LINE__) = BGL_LAST(__LINE__)) \ + for (boost::graph_traits< GraphType >::vertex_descriptor VNAME; \ + BGL_FIRST(__LINE__) != BGL_LAST(__LINE__) \ + ? (VNAME = *BGL_FIRST(__LINE__), true) \ + : false; \ + ++BGL_FIRST(__LINE__)) + +#define BGL_FORALL_EDGES_T(ENAME, GNAME, GraphType) \ + for (std::pair< typename boost::graph_traits< GraphType >::edge_iterator, \ + typename boost::graph_traits< GraphType >::edge_iterator > \ + BGL_RANGE(__LINE__) \ + = edges(GNAME); \ + BGL_FIRST(__LINE__) != BGL_LAST(__LINE__); \ + BGL_FIRST(__LINE__) = BGL_LAST(__LINE__)) \ + for (typename boost::graph_traits< GraphType >::edge_descriptor ENAME; \ + BGL_FIRST(__LINE__) != BGL_LAST(__LINE__) \ + ? (ENAME = *BGL_FIRST(__LINE__), true) \ + : false; \ + ++BGL_FIRST(__LINE__)) + +#define BGL_FORALL_EDGES(ENAME, GNAME, GraphType) \ + for (std::pair< boost::graph_traits< GraphType >::edge_iterator, \ + boost::graph_traits< GraphType >::edge_iterator > \ + BGL_RANGE(__LINE__) \ + = edges(GNAME); \ + BGL_FIRST(__LINE__) != BGL_LAST(__LINE__); \ + BGL_FIRST(__LINE__) = BGL_LAST(__LINE__)) \ + for (boost::graph_traits< GraphType >::edge_descriptor ENAME; \ + BGL_FIRST(__LINE__) != BGL_LAST(__LINE__) \ + ? (ENAME = *BGL_FIRST(__LINE__), true) \ + : false; \ + ++BGL_FIRST(__LINE__)) + +#define BGL_FORALL_ADJ_T(UNAME, VNAME, GNAME, GraphType) \ + for (std::pair< \ + typename boost::graph_traits< GraphType >::adjacency_iterator, \ + typename boost::graph_traits< GraphType >::adjacency_iterator > \ + BGL_RANGE(__LINE__) \ + = adjacent_vertices(UNAME, GNAME); \ + BGL_FIRST(__LINE__) != BGL_LAST(__LINE__); \ + BGL_FIRST(__LINE__) = BGL_LAST(__LINE__)) \ + for (typename boost::graph_traits< GraphType >::vertex_descriptor \ + VNAME; \ + BGL_FIRST(__LINE__) != BGL_LAST(__LINE__) \ + ? (VNAME = *BGL_FIRST(__LINE__), true) \ + : false; \ + ++BGL_FIRST(__LINE__)) + +#define BGL_FORALL_ADJ(UNAME, VNAME, GNAME, GraphType) \ + for (std::pair< boost::graph_traits< GraphType >::adjacency_iterator, \ + boost::graph_traits< GraphType >::adjacency_iterator > \ + BGL_RANGE(__LINE__) \ + = adjacent_vertices(UNAME, GNAME); \ + BGL_FIRST(__LINE__) != BGL_LAST(__LINE__); \ + BGL_FIRST(__LINE__) = BGL_LAST(__LINE__)) \ + for (boost::graph_traits< GraphType >::vertex_descriptor VNAME; \ + BGL_FIRST(__LINE__) != BGL_LAST(__LINE__) \ + ? (VNAME = *BGL_FIRST(__LINE__), true) \ + : false; \ + ++BGL_FIRST(__LINE__)) + +#define BGL_FORALL_OUTEDGES_T(UNAME, ENAME, GNAME, GraphType) \ + for (std::pair< \ + typename boost::graph_traits< GraphType >::out_edge_iterator, \ + typename boost::graph_traits< GraphType >::out_edge_iterator > \ + BGL_RANGE(__LINE__) \ + = out_edges(UNAME, GNAME); \ + BGL_FIRST(__LINE__) != BGL_LAST(__LINE__); \ + BGL_FIRST(__LINE__) = BGL_LAST(__LINE__)) \ + for (typename boost::graph_traits< GraphType >::edge_descriptor ENAME; \ + BGL_FIRST(__LINE__) != BGL_LAST(__LINE__) \ + ? (ENAME = *BGL_FIRST(__LINE__), true) \ + : false; \ + ++BGL_FIRST(__LINE__)) + +#define BGL_FORALL_OUTEDGES(UNAME, ENAME, GNAME, GraphType) \ + for (std::pair< boost::graph_traits< GraphType >::out_edge_iterator, \ + boost::graph_traits< GraphType >::out_edge_iterator > \ + BGL_RANGE(__LINE__) \ + = out_edges(UNAME, GNAME); \ + BGL_FIRST(__LINE__) != BGL_LAST(__LINE__); \ + BGL_FIRST(__LINE__) = BGL_LAST(__LINE__)) \ + for (boost::graph_traits< GraphType >::edge_descriptor ENAME; \ + BGL_FIRST(__LINE__) != BGL_LAST(__LINE__) \ + ? (ENAME = *BGL_FIRST(__LINE__), true) \ + : false; \ + ++BGL_FIRST(__LINE__)) + +#define BGL_FORALL_INEDGES_T(UNAME, ENAME, GNAME, GraphType) \ + for (std::pair< \ + typename boost::graph_traits< GraphType >::in_edge_iterator, \ + typename boost::graph_traits< GraphType >::in_edge_iterator > \ + BGL_RANGE(__LINE__) \ + = in_edges(UNAME, GNAME); \ + BGL_FIRST(__LINE__) != BGL_LAST(__LINE__); \ + BGL_FIRST(__LINE__) = BGL_LAST(__LINE__)) \ + for (typename boost::graph_traits< GraphType >::edge_descriptor ENAME; \ + BGL_FIRST(__LINE__) != BGL_LAST(__LINE__) \ + ? (ENAME = *BGL_FIRST(__LINE__), true) \ + : false; \ + ++BGL_FIRST(__LINE__)) + +#define BGL_FORALL_INEDGES(UNAME, ENAME, GNAME, GraphType) \ + for (std::pair< boost::graph_traits< GraphType >::in_edge_iterator, \ + boost::graph_traits< GraphType >::in_edge_iterator > \ + BGL_RANGE(__LINE__) \ + = in_edges(UNAME, GNAME); \ + BGL_FIRST(__LINE__) != BGL_LAST(__LINE__); \ + BGL_FIRST(__LINE__) = BGL_LAST(__LINE__)) \ + for (boost::graph_traits< GraphType >::edge_descriptor ENAME; \ + BGL_FIRST(__LINE__) != BGL_LAST(__LINE__) \ + ? (ENAME = *BGL_FIRST(__LINE__), true) \ + : false; \ + ++BGL_FIRST(__LINE__)) #endif // BOOST_GRAPH_ITERATION_MACROS_HPP diff --git a/include/boost/graph/johnson_all_pairs_shortest.hpp b/include/boost/graph/johnson_all_pairs_shortest.hpp index 1e703791d..2cc4697a1 100644 --- a/include/boost/graph/johnson_all_pairs_shortest.hpp +++ b/include/boost/graph/johnson_all_pairs_shortest.hpp @@ -14,7 +14,7 @@ class P, class T, class R> bool johnson_all_pairs_shortest_paths - (VertexAndEdgeListGraph& g, + (VertexAndEdgeListGraph& g, DistanceMatrix& D, const bgl_named_params& params) */ @@ -31,173 +31,168 @@ #include #include -namespace boost { - - template - bool - johnson_all_pairs_shortest_paths(VertexAndEdgeListGraph& g1, - DistanceMatrix& D, - VertexID id1, Weight w1, const BinaryPredicate& compare, - const BinaryFunction& combine, const Infinity& inf, - DistanceZero zero) - { - typedef graph_traits Traits1; - typedef typename property_traits::value_type DT; - BOOST_CONCEPT_ASSERT(( BasicMatrixConcept )); +namespace boost +{ + +template < class VertexAndEdgeListGraph, class DistanceMatrix, class VertexID, + class Weight, typename BinaryPredicate, typename BinaryFunction, + typename Infinity, class DistanceZero > +bool johnson_all_pairs_shortest_paths(VertexAndEdgeListGraph& g1, + DistanceMatrix& D, VertexID id1, Weight w1, const BinaryPredicate& compare, + const BinaryFunction& combine, const Infinity& inf, DistanceZero zero) +{ + typedef graph_traits< VertexAndEdgeListGraph > Traits1; + typedef typename property_traits< Weight >::value_type DT; + BOOST_CONCEPT_ASSERT((BasicMatrixConcept< DistanceMatrix, + typename Traits1::vertices_size_type, DT >)); typedef typename Traits1::directed_category DirCat; - bool is_undirected = is_same::value; + bool is_undirected = is_same< DirCat, undirected_tag >::value; - typedef adjacency_list, - property< edge_weight_t, DT, - property< edge_weight2_t, DT > > > Graph2; - typedef graph_traits Traits2; + typedef adjacency_list< vecS, vecS, directedS, + property< vertex_distance_t, DT >, + property< edge_weight_t, DT, property< edge_weight2_t, DT > > > + Graph2; + typedef graph_traits< Graph2 > Traits2; Graph2 g2(num_vertices(g1) + 1); - typename property_map::type - w = get(edge_weight, g2); - typename property_map::type - w_hat = get(edge_weight2, g2); - typename property_map::type - d = get(vertex_distance, g2); - typedef typename property_map::type VertexID2; + typename property_map< Graph2, edge_weight_t >::type w + = get(edge_weight, g2); + typename property_map< Graph2, edge_weight2_t >::type w_hat + = get(edge_weight2, g2); + typename property_map< Graph2, vertex_distance_t >::type d + = get(vertex_distance, g2); + typedef typename property_map< Graph2, vertex_index_t >::type VertexID2; VertexID2 id2 = get(vertex_index, g2); // Construct g2 where V[g2] = V[g1] U {s} // and E[g2] = E[g1] U {(s,v)| v in V[g1]} - std::vector - verts1(num_vertices(g1) + 1); + std::vector< typename Traits1::vertex_descriptor > verts1( + num_vertices(g1) + 1); typename Traits2::vertex_descriptor s = *vertices(g2).first; { - typename Traits1::vertex_iterator v, v_end; - int i = 1; - for (boost::tie(v, v_end) = vertices(g1); v != v_end; ++v, ++i) { - typename Traits2::edge_descriptor e; bool z; - boost::tie(e, z) = add_edge(s, get(id1, *v) + 1, g2); - put(w, e, zero); - verts1[i] = *v; - } - typename Traits1::edge_iterator e, e_end; - for (boost::tie(e, e_end) = edges(g1); e != e_end; ++e) { - typename Traits2::edge_descriptor e2; bool z; - boost::tie(e2, z) = add_edge(get(id1, source(*e, g1)) + 1, - get(id1, target(*e, g1)) + 1, g2); - put(w, e2, get(w1, *e)); - if (is_undirected) { - boost::tie(e2, z) = add_edge(get(id1, target(*e, g1)) + 1, - get(id1, source(*e, g1)) + 1, g2); - put(w, e2, get(w1, *e)); + typename Traits1::vertex_iterator v, v_end; + int i = 1; + for (boost::tie(v, v_end) = vertices(g1); v != v_end; ++v, ++i) + { + typename Traits2::edge_descriptor e; + bool z; + boost::tie(e, z) = add_edge(s, get(id1, *v) + 1, g2); + put(w, e, zero); + verts1[i] = *v; + } + typename Traits1::edge_iterator e, e_end; + for (boost::tie(e, e_end) = edges(g1); e != e_end; ++e) + { + typename Traits2::edge_descriptor e2; + bool z; + boost::tie(e2, z) = add_edge( + get(id1, source(*e, g1)) + 1, get(id1, target(*e, g1)) + 1, g2); + put(w, e2, get(w1, *e)); + if (is_undirected) + { + boost::tie(e2, z) = add_edge(get(id1, target(*e, g1)) + 1, + get(id1, source(*e, g1)) + 1, g2); + put(w, e2, get(w1, *e)); + } } - } } typename Traits2::vertex_iterator v, v_end, u, u_end; typename Traits2::edge_iterator e, e_end; - shared_array_property_map h(num_vertices(g2), id2); + shared_array_property_map< DT, VertexID2 > h(num_vertices(g2), id2); for (boost::tie(v, v_end) = vertices(g2); v != v_end; ++v) - put(d, *v, inf); + put(d, *v, inf); put(d, s, zero); // Using the non-named parameter versions of bellman_ford and // dijkstra for portability reasons. - dummy_property_map pred; bellman_visitor<> bvis; - if (bellman_ford_shortest_paths - (g2, num_vertices(g2), w, pred, d, combine, compare, bvis)) { - for (boost::tie(v, v_end) = vertices(g2); v != v_end; ++v) - put(h, *v, get(d, *v)); - // Reweight the edges to remove negatives - for (boost::tie(e, e_end) = edges(g2); e != e_end; ++e) { - typename Traits2::vertex_descriptor a = source(*e, g2), - b = target(*e, g2); - put(w_hat, *e, combine((get(h, a) - get(h, b)), get(w, *e))); - } - for (boost::tie(u, u_end) = vertices(g2); u != u_end; ++u) { - dijkstra_visitor<> dvis; - dijkstra_shortest_paths - (g2, *u, pred, d, w_hat, id2, compare, combine, inf, zero,dvis); - for (boost::tie(v, v_end) = vertices(g2); v != v_end; ++v) { - if (*u != s && *v != s) { - D[get(id2, *u)-1][get(id2, *v)-1] = combine((get(h, *v) - get(h, *u)), get(d, *v)); - } + dummy_property_map pred; + bellman_visitor<> bvis; + if (bellman_ford_shortest_paths( + g2, num_vertices(g2), w, pred, d, combine, compare, bvis)) + { + for (boost::tie(v, v_end) = vertices(g2); v != v_end; ++v) + put(h, *v, get(d, *v)); + // Reweight the edges to remove negatives + for (boost::tie(e, e_end) = edges(g2); e != e_end; ++e) + { + typename Traits2::vertex_descriptor a = source(*e, g2), + b = target(*e, g2); + put(w_hat, *e, combine((get(h, a) - get(h, b)), get(w, *e))); } - } - return true; - } else - return false; - } - - template - bool - johnson_all_pairs_shortest_paths(VertexAndEdgeListGraph& g1, - DistanceMatrix& D, - VertexID id1, Weight w1, DistanceZero zero) - { - typedef typename property_traits::value_type WT; - return johnson_all_pairs_shortest_paths(g1, D, id1, w1, - std::less(), - closed_plus(), - (std::numeric_limits::max)(), - zero); - } - - namespace detail { - - template - bool - johnson_dispatch(VertexAndEdgeListGraph& g, - DistanceMatrix& D, - const bgl_named_params& params, - Weight w, VertexID id) + for (boost::tie(u, u_end) = vertices(g2); u != u_end; ++u) + { + dijkstra_visitor<> dvis; + dijkstra_shortest_paths( + g2, *u, pred, d, w_hat, id2, compare, combine, inf, zero, dvis); + for (boost::tie(v, v_end) = vertices(g2); v != v_end; ++v) + { + if (*u != s && *v != s) + { + D[get(id2, *u) - 1][get(id2, *v) - 1] + = combine((get(h, *v) - get(h, *u)), get(d, *v)); + } + } + } + return true; + } + else + return false; +} + +template < class VertexAndEdgeListGraph, class DistanceMatrix, class VertexID, + class Weight, class DistanceZero > +bool johnson_all_pairs_shortest_paths(VertexAndEdgeListGraph& g1, + DistanceMatrix& D, VertexID id1, Weight w1, DistanceZero zero) +{ + typedef typename property_traits< Weight >::value_type WT; + return johnson_all_pairs_shortest_paths(g1, D, id1, w1, std::less< WT >(), + closed_plus< WT >(), (std::numeric_limits< WT >::max)(), zero); +} + +namespace detail +{ + + template < class VertexAndEdgeListGraph, class DistanceMatrix, class P, + class T, class R, class Weight, class VertexID > + bool johnson_dispatch(VertexAndEdgeListGraph& g, DistanceMatrix& D, + const bgl_named_params< P, T, R >& params, Weight w, VertexID id) { - typedef typename property_traits::value_type WT; - - return johnson_all_pairs_shortest_paths - (g, D, id, w, - choose_param(get_param(params, distance_compare_t()), - std::less()), - choose_param(get_param(params, distance_combine_t()), - closed_plus()), - choose_param(get_param(params, distance_inf_t()), - std::numeric_limits::max BOOST_PREVENT_MACRO_SUBSTITUTION()), - choose_param(get_param(params, distance_zero_t()), WT()) ); + typedef typename property_traits< Weight >::value_type WT; + + return johnson_all_pairs_shortest_paths(g, D, id, w, + choose_param( + get_param(params, distance_compare_t()), std::less< WT >()), + choose_param( + get_param(params, distance_combine_t()), closed_plus< WT >()), + choose_param(get_param(params, distance_inf_t()), + std::numeric_limits< WT >::max + BOOST_PREVENT_MACRO_SUBSTITUTION()), + choose_param(get_param(params, distance_zero_t()), WT())); } - } // namespace detail - - template - bool - johnson_all_pairs_shortest_paths - (VertexAndEdgeListGraph& g, - DistanceMatrix& D, - const bgl_named_params& params) - { - return detail::johnson_dispatch - (g, D, params, - choose_const_pmap(get_param(params, edge_weight), g, edge_weight), - choose_const_pmap(get_param(params, vertex_index), g, vertex_index) - ); - } - - template - bool - johnson_all_pairs_shortest_paths - (VertexAndEdgeListGraph& g, DistanceMatrix& D) - { - bgl_named_params params(1); - return detail::johnson_dispatch - (g, D, params, get(edge_weight, g), get(vertex_index, g)); - } +} // namespace detail + +template < class VertexAndEdgeListGraph, class DistanceMatrix, class P, class T, + class R > +bool johnson_all_pairs_shortest_paths(VertexAndEdgeListGraph& g, + DistanceMatrix& D, const bgl_named_params< P, T, R >& params) +{ + return detail::johnson_dispatch(g, D, params, + choose_const_pmap(get_param(params, edge_weight), g, edge_weight), + choose_const_pmap(get_param(params, vertex_index), g, vertex_index)); +} + +template < class VertexAndEdgeListGraph, class DistanceMatrix > +bool johnson_all_pairs_shortest_paths( + VertexAndEdgeListGraph& g, DistanceMatrix& D) +{ + bgl_named_params< int, int > params(1); + return detail::johnson_dispatch( + g, D, params, get(edge_weight, g), get(vertex_index, g)); +} } // namespace boost #endif // BOOST_GRAPH_JOHNSON_HPP - - diff --git a/include/boost/graph/kamada_kawai_spring_layout.hpp b/include/boost/graph/kamada_kawai_spring_layout.hpp index b10ebe3dc..148ebd9ee 100644 --- a/include/boost/graph/kamada_kawai_spring_layout.hpp +++ b/include/boost/graph/kamada_kawai_spring_layout.hpp @@ -21,602 +21,668 @@ #include #include -namespace boost { - namespace detail { namespace graph { - /** - * Denotes an edge or display area side length used to scale a - * Kamada-Kawai drawing. - */ - template - struct edge_or_side +namespace boost +{ +namespace detail +{ + namespace graph { - explicit edge_or_side(T value) : value(value) {} - - T value; - }; - - /** - * Compute the edge length from an edge length. This is trivial. - */ - template - T compute_edge_length(const Graph&, DistanceMap, IndexMap, - edge_or_side length) - { return length.value; } - - /** - * Compute the edge length based on the display area side - length. We do this by dividing the side length by the largest - shortest distance between any two vertices in the graph. - */ - template - T - compute_edge_length(const Graph& g, DistanceMap distance, IndexMap index, - edge_or_side length) - { - T result(0); - - typedef typename graph_traits::vertex_iterator vertex_iterator; - - for (vertex_iterator ui = vertices(g).first, end = vertices(g).second; - ui != end; ++ui) { - vertex_iterator vi = ui; - for (++vi; vi != end; ++vi) { - T dij = distance[get(index, *ui)][get(index, *vi)]; - if (dij > result) result = dij; + /** + * Denotes an edge or display area side length used to scale a + * Kamada-Kawai drawing. + */ + template < bool Edge, typename T > struct edge_or_side + { + explicit edge_or_side(T value) : value(value) {} + + T value; + }; + + /** + * Compute the edge length from an edge length. This is trivial. + */ + template < typename Graph, typename DistanceMap, typename IndexMap, + typename T > + T compute_edge_length( + const Graph&, DistanceMap, IndexMap, edge_or_side< true, T > length) + { + return length.value; } - } - return length.value / result; - } - /** - * Dense linear solver for fixed-size matrices. - */ - template - struct linear_solver { - // Indices in mat are (row, column) - // template - // static Vec solve(double mat[Size][Size], Vec rhs); - }; - - template <> - struct linear_solver<1> { - template - static Vec solve(double mat[1][1], Vec rhs) { - return rhs / mat[0][0]; - } - }; - - // These are from http://en.wikipedia.org/wiki/Cramer%27s_rule - template <> - struct linear_solver<2> { - template - static Vec solve(double mat[2][2], Vec rhs) { - double denom = mat[0][0] * mat[1][1] - mat[1][0] * mat[0][1]; - double x_num = rhs[0] * mat[1][1] - rhs[1] * mat[0][1]; - double y_num = mat[0][0] * rhs[1] - mat[1][0] * rhs[0] ; - Vec result; - result[0] = x_num / denom; - result[1] = y_num / denom; - return result; - } - }; - - template <> - struct linear_solver<3> { - template - static Vec solve(double mat[3][3], Vec rhs) { - double denom = mat[0][0] * (mat[1][1] * mat[2][2] - mat[2][1] * mat[1][2]) - - mat[1][0] * (mat[0][1] * mat[2][2] - mat[2][1] * mat[0][2]) - + mat[2][0] * (mat[0][1] * mat[1][2] - mat[1][1] * mat[0][2]); - double x_num = rhs[0] * (mat[1][1] * mat[2][2] - mat[2][1] * mat[1][2]) - - rhs[1] * (mat[0][1] * mat[2][2] - mat[2][1] * mat[0][2]) - + rhs[2] * (mat[0][1] * mat[1][2] - mat[1][1] * mat[0][2]); - double y_num = mat[0][0] * (rhs[1] * mat[2][2] - rhs[2] * mat[1][2]) - - mat[1][0] * (rhs[0] * mat[2][2] - rhs[2] * mat[0][2]) - + mat[2][0] * (rhs[0] * mat[1][2] - rhs[1] * mat[0][2]); - double z_num = mat[0][0] * (mat[1][1] * rhs[2] - mat[2][1] * rhs[1] ) - - mat[1][0] * (mat[0][1] * rhs[2] - mat[2][1] * rhs[0] ) - + mat[2][0] * (mat[0][1] * rhs[1] - mat[1][1] * rhs[0] ); - Vec result; - result[0] = x_num / denom; - result[1] = y_num / denom; - result[2] = z_num / denom; - return result; - } - }; - - /** - * Implementation of the Kamada-Kawai spring layout algorithm. - */ - template - struct kamada_kawai_spring_layout_impl - { - typedef typename property_traits::value_type weight_type; - typedef typename Topology::point_type Point; - typedef typename Topology::point_difference_type point_difference_type; - typedef point_difference_type deriv_type; - typedef typename graph_traits::vertex_iterator vertex_iterator; - typedef typename graph_traits::vertex_descriptor - vertex_descriptor; - - kamada_kawai_spring_layout_impl( - const Topology& topology, - const Graph& g, - PositionMap position, - WeightMap weight, - EdgeOrSideLength edge_or_side_length, - Done done, - weight_type spring_constant, - VertexIndexMap index, - DistanceMatrix distance, - SpringStrengthMatrix spring_strength, - PartialDerivativeMap partial_derivatives) - : topology(topology), g(g), position(position), weight(weight), - edge_or_side_length(edge_or_side_length), done(done), - spring_constant(spring_constant), index(index), distance(distance), - spring_strength(spring_strength), - partial_derivatives(partial_derivatives) {} - - // Compute contribution of vertex i to the first partial - // derivatives (dE/dx_m, dE/dy_m) (for vertex m) - deriv_type - compute_partial_derivative(vertex_descriptor m, vertex_descriptor i) - { -#ifndef BOOST_NO_STDC_NAMESPACE - using std::sqrt; -#endif // BOOST_NO_STDC_NAMESPACE - - deriv_type result; - if (i != m) { - point_difference_type diff = topology.difference(position[m], position[i]); - weight_type dist = topology.norm(diff); - result = spring_strength[get(index, m)][get(index, i)] - * (diff - distance[get(index, m)][get(index, i)]/dist*diff); + /** + * Compute the edge length based on the display area side + length. We do this by dividing the side length by the largest + shortest distance between any two vertices in the graph. + */ + template < typename Graph, typename DistanceMap, typename IndexMap, + typename T > + T compute_edge_length(const Graph& g, DistanceMap distance, + IndexMap index, edge_or_side< false, T > length) + { + T result(0); + + typedef + typename graph_traits< Graph >::vertex_iterator vertex_iterator; + + for (vertex_iterator ui = vertices(g).first, + end = vertices(g).second; + ui != end; ++ui) + { + vertex_iterator vi = ui; + for (++vi; vi != end; ++vi) + { + T dij = distance[get(index, *ui)][get(index, *vi)]; + if (dij > result) + result = dij; + } + } + return length.value / result; } - return result; - } + /** + * Dense linear solver for fixed-size matrices. + */ + template < std::size_t Size > struct linear_solver + { + // Indices in mat are (row, column) + // template + // static Vec solve(double mat[Size][Size], Vec rhs); + }; + + template <> struct linear_solver< 1 > + { + template < typename Vec > + static Vec solve(double mat[1][1], Vec rhs) + { + return rhs / mat[0][0]; + } + }; + + // These are from http://en.wikipedia.org/wiki/Cramer%27s_rule + template <> struct linear_solver< 2 > + { + template < typename Vec > + static Vec solve(double mat[2][2], Vec rhs) + { + double denom = mat[0][0] * mat[1][1] - mat[1][0] * mat[0][1]; + double x_num = rhs[0] * mat[1][1] - rhs[1] * mat[0][1]; + double y_num = mat[0][0] * rhs[1] - mat[1][0] * rhs[0]; + Vec result; + result[0] = x_num / denom; + result[1] = y_num / denom; + return result; + } + }; + + template <> struct linear_solver< 3 > + { + template < typename Vec > + static Vec solve(double mat[3][3], Vec rhs) + { + double denom = mat[0][0] + * (mat[1][1] * mat[2][2] - mat[2][1] * mat[1][2]) + - mat[1][0] + * (mat[0][1] * mat[2][2] - mat[2][1] * mat[0][2]) + + mat[2][0] + * (mat[0][1] * mat[1][2] - mat[1][1] * mat[0][2]); + double x_num + = rhs[0] * (mat[1][1] * mat[2][2] - mat[2][1] * mat[1][2]) + - rhs[1] * (mat[0][1] * mat[2][2] - mat[2][1] * mat[0][2]) + + rhs[2] * (mat[0][1] * mat[1][2] - mat[1][1] * mat[0][2]); + double y_num + = mat[0][0] * (rhs[1] * mat[2][2] - rhs[2] * mat[1][2]) + - mat[1][0] * (rhs[0] * mat[2][2] - rhs[2] * mat[0][2]) + + mat[2][0] * (rhs[0] * mat[1][2] - rhs[1] * mat[0][2]); + double z_num + = mat[0][0] * (mat[1][1] * rhs[2] - mat[2][1] * rhs[1]) + - mat[1][0] * (mat[0][1] * rhs[2] - mat[2][1] * rhs[0]) + + mat[2][0] * (mat[0][1] * rhs[1] - mat[1][1] * rhs[0]); + Vec result; + result[0] = x_num / denom; + result[1] = y_num / denom; + result[2] = z_num / denom; + return result; + } + }; + + /** + * Implementation of the Kamada-Kawai spring layout algorithm. + */ + template < typename Topology, typename Graph, typename PositionMap, + typename WeightMap, typename EdgeOrSideLength, typename Done, + typename VertexIndexMap, typename DistanceMatrix, + typename SpringStrengthMatrix, typename PartialDerivativeMap > + struct kamada_kawai_spring_layout_impl + { + typedef + typename property_traits< WeightMap >::value_type weight_type; + typedef typename Topology::point_type Point; + typedef + typename Topology::point_difference_type point_difference_type; + typedef point_difference_type deriv_type; + typedef + typename graph_traits< Graph >::vertex_iterator vertex_iterator; + typedef typename graph_traits< Graph >::vertex_descriptor + vertex_descriptor; + + kamada_kawai_spring_layout_impl(const Topology& topology, + const Graph& g, PositionMap position, WeightMap weight, + EdgeOrSideLength edge_or_side_length, Done done, + weight_type spring_constant, VertexIndexMap index, + DistanceMatrix distance, SpringStrengthMatrix spring_strength, + PartialDerivativeMap partial_derivatives) + : topology(topology) + , g(g) + , position(position) + , weight(weight) + , edge_or_side_length(edge_or_side_length) + , done(done) + , spring_constant(spring_constant) + , index(index) + , distance(distance) + , spring_strength(spring_strength) + , partial_derivatives(partial_derivatives) + { + } - // Compute partial derivatives dE/dx_m and dE/dy_m - deriv_type - compute_partial_derivatives(vertex_descriptor m) - { + // Compute contribution of vertex i to the first partial + // derivatives (dE/dx_m, dE/dy_m) (for vertex m) + deriv_type compute_partial_derivative( + vertex_descriptor m, vertex_descriptor i) + { #ifndef BOOST_NO_STDC_NAMESPACE - using std::sqrt; + using std::sqrt; #endif // BOOST_NO_STDC_NAMESPACE - deriv_type result; - - // TBD: looks like an accumulate to me - BGL_FORALL_VERTICES_T(i, g, Graph) { - deriv_type deriv = compute_partial_derivative(m, i); - result += deriv; - } + deriv_type result; + if (i != m) + { + point_difference_type diff + = topology.difference(position[m], position[i]); + weight_type dist = topology.norm(diff); + result = spring_strength[get(index, m)][get(index, i)] + * (diff + - distance[get(index, m)][get(index, i)] / dist + * diff); + } - return result; - } + return result; + } - // The actual Kamada-Kawai spring layout algorithm implementation - bool run() - { + // Compute partial derivatives dE/dx_m and dE/dy_m + deriv_type compute_partial_derivatives(vertex_descriptor m) + { #ifndef BOOST_NO_STDC_NAMESPACE - using std::sqrt; + using std::sqrt; #endif // BOOST_NO_STDC_NAMESPACE - // Compute d_{ij} and place it in the distance matrix - if (!johnson_all_pairs_shortest_paths(g, distance, index, weight, - weight_type(0))) - return false; - - // Compute L based on side length (if needed), or retrieve L - weight_type edge_length = - detail::graph::compute_edge_length(g, distance, index, - edge_or_side_length); - - // std::cerr << "edge_length = " << edge_length << std::endl; - - // Compute l_{ij} and k_{ij} - const weight_type K = spring_constant; - vertex_iterator ui, end; - for (ui = vertices(g).first, end = vertices(g).second; ui != end; ++ui) { - vertex_iterator vi = ui; - for (++vi; vi != end; ++vi) { - weight_type dij = distance[get(index, *ui)][get(index, *vi)]; - if (dij == (std::numeric_limits::max)()) - return false; - distance[get(index, *ui)][get(index, *vi)] = edge_length * dij; - distance[get(index, *vi)][get(index, *ui)] = edge_length * dij; - spring_strength[get(index, *ui)][get(index, *vi)] = K/(dij*dij); - spring_strength[get(index, *vi)][get(index, *ui)] = K/(dij*dij); - } - } - - // Compute Delta_i and find max - vertex_descriptor p = *vertices(g).first; - weight_type delta_p(0); + deriv_type result; - for (ui = vertices(g).first, end = vertices(g).second; ui != end; ++ui) { - deriv_type deriv = compute_partial_derivatives(*ui); - put(partial_derivatives, *ui, deriv); + // TBD: looks like an accumulate to me + BGL_FORALL_VERTICES_T(i, g, Graph) + { + deriv_type deriv = compute_partial_derivative(m, i); + result += deriv; + } - weight_type delta = topology.norm(deriv); + return result; + } - if (delta > delta_p) { - p = *ui; - delta_p = delta; - } - } + // The actual Kamada-Kawai spring layout algorithm implementation + bool run() + { +#ifndef BOOST_NO_STDC_NAMESPACE + using std::sqrt; +#endif // BOOST_NO_STDC_NAMESPACE - while (!done(delta_p, p, g, true)) { - // The contribution p makes to the partial derivatives of - // each vertex. Computing this (at O(n) cost) allows us to - // update the delta_i values in O(n) time instead of O(n^2) - // time. - std::vector p_partials(num_vertices(g)); - for (ui = vertices(g).first, end = vertices(g).second; ui != end; ++ui) { - vertex_descriptor i = *ui; - p_partials[get(index, i)] = compute_partial_derivative(i, p); - } - - do { - // For debugging, compute the energy value E - double E = 0.; - for (ui = vertices(g).first, end = vertices(g).second; ui != end; ++ui) { - vertex_iterator vi = ui; - for (++vi; vi != end; ++vi) { - double dist = topology.distance(position[*ui], position[*vi]); - weight_type k_ij = spring_strength[get(index,*ui)][get(index,*vi)]; - weight_type l_ij = distance[get(index, *ui)][get(index, *vi)]; - E += .5 * k_ij * (dist - l_ij) * (dist - l_ij); - } - } - // std::cerr << "E = " << E << std::endl; - - // Compute the elements of the Jacobian - // From - // http://www.cs.panam.edu/~rfowler/papers/1994_kumar_fowler_A_Spring_UTPACSTR.pdf - // with the bugs fixed in the off-diagonal case - weight_type dE_d_d[Point::dimensions][Point::dimensions]; - for (std::size_t i = 0; i < Point::dimensions; ++i) - for (std::size_t j = 0; j < Point::dimensions; ++j) - dE_d_d[i][j] = 0.; - for (ui = vertices(g).first, end = vertices(g).second; ui != end; ++ui) { - vertex_descriptor i = *ui; - if (i != p) { - point_difference_type diff = topology.difference(position[p], position[i]); - weight_type dist = topology.norm(diff); - weight_type dist_squared = dist * dist; - weight_type inv_dist_cubed = 1. / (dist_squared * dist); - weight_type k_mi = spring_strength[get(index,p)][get(index,i)]; - weight_type l_mi = distance[get(index, p)][get(index, i)]; - for (std::size_t i = 0; i < Point::dimensions; ++i) { - for (std::size_t j = 0; j < Point::dimensions; ++j) { - if (i == j) { - dE_d_d[i][i] += k_mi * (1 + (l_mi * (diff[i] * diff[i] - dist_squared) * inv_dist_cubed)); - } else { - dE_d_d[i][j] += k_mi * l_mi * diff[i] * diff[j] * inv_dist_cubed; - // dE_d_d[i][j] += k_mi * l_mi * sqrt(hypot(diff[i], diff[j])) * inv_dist_cubed; + // Compute d_{ij} and place it in the distance matrix + if (!johnson_all_pairs_shortest_paths( + g, distance, index, weight, weight_type(0))) + return false; + + // Compute L based on side length (if needed), or retrieve L + weight_type edge_length = detail::graph::compute_edge_length( + g, distance, index, edge_or_side_length); + + // std::cerr << "edge_length = " << edge_length << std::endl; + + // Compute l_{ij} and k_{ij} + const weight_type K = spring_constant; + vertex_iterator ui, end; + for (ui = vertices(g).first, end = vertices(g).second; + ui != end; ++ui) + { + vertex_iterator vi = ui; + for (++vi; vi != end; ++vi) + { + weight_type dij + = distance[get(index, *ui)][get(index, *vi)]; + if (dij == (std::numeric_limits< weight_type >::max)()) + return false; + distance[get(index, *ui)][get(index, *vi)] + = edge_length * dij; + distance[get(index, *vi)][get(index, *ui)] + = edge_length * dij; + spring_strength[get(index, *ui)][get(index, *vi)] + = K / (dij * dij); + spring_strength[get(index, *vi)][get(index, *ui)] + = K / (dij * dij); } - } } - } - } - - deriv_type dE_d = get(partial_derivatives, p); - // Solve dE_d_d * delta = -dE_d to get delta - point_difference_type delta = -linear_solver::solve(dE_d_d, dE_d); + // Compute Delta_i and find max + vertex_descriptor p = *vertices(g).first; + weight_type delta_p(0); - // Move p by delta - position[p] = topology.adjust(position[p], delta); + for (ui = vertices(g).first, end = vertices(g).second; + ui != end; ++ui) + { + deriv_type deriv = compute_partial_derivatives(*ui); + put(partial_derivatives, *ui, deriv); - // Recompute partial derivatives and delta_p - deriv_type deriv = compute_partial_derivatives(p); - put(partial_derivatives, p, deriv); + weight_type delta = topology.norm(deriv); - delta_p = topology.norm(deriv); - } while (!done(delta_p, p, g, false)); - - // Select new p by updating each partial derivative and delta - vertex_descriptor old_p = p; - for (ui = vertices(g).first, end = vertices(g).second; ui != end; ++ui) { - deriv_type old_deriv_p = p_partials[get(index, *ui)]; - deriv_type old_p_partial = - compute_partial_derivative(*ui, old_p); - deriv_type deriv = get(partial_derivatives, *ui); + if (delta > delta_p) + { + p = *ui; + delta_p = delta; + } + } - deriv += old_p_partial - old_deriv_p; + while (!done(delta_p, p, g, true)) + { + // The contribution p makes to the partial derivatives of + // each vertex. Computing this (at O(n) cost) allows us to + // update the delta_i values in O(n) time instead of O(n^2) + // time. + std::vector< deriv_type > p_partials(num_vertices(g)); + for (ui = vertices(g).first, end = vertices(g).second; + ui != end; ++ui) + { + vertex_descriptor i = *ui; + p_partials[get(index, i)] + = compute_partial_derivative(i, p); + } - put(partial_derivatives, *ui, deriv); - weight_type delta = topology.norm(deriv); + do + { + // For debugging, compute the energy value E + double E = 0.; + for (ui = vertices(g).first, end = vertices(g).second; + ui != end; ++ui) + { + vertex_iterator vi = ui; + for (++vi; vi != end; ++vi) + { + double dist = topology.distance( + position[*ui], position[*vi]); + weight_type k_ij = spring_strength[get( + index, *ui)][get(index, *vi)]; + weight_type l_ij = distance[get(index, *ui)] + [get(index, *vi)]; + E += .5 * k_ij * (dist - l_ij) * (dist - l_ij); + } + } + // std::cerr << "E = " << E << std::endl; + + // Compute the elements of the Jacobian + // From + // http://www.cs.panam.edu/~rfowler/papers/1994_kumar_fowler_A_Spring_UTPACSTR.pdf + // with the bugs fixed in the off-diagonal case + weight_type dE_d_d[Point::dimensions] + [Point::dimensions]; + for (std::size_t i = 0; i < Point::dimensions; ++i) + for (std::size_t j = 0; j < Point::dimensions; ++j) + dE_d_d[i][j] = 0.; + for (ui = vertices(g).first, end = vertices(g).second; + ui != end; ++ui) + { + vertex_descriptor i = *ui; + if (i != p) + { + point_difference_type diff + = topology.difference( + position[p], position[i]); + weight_type dist = topology.norm(diff); + weight_type dist_squared = dist * dist; + weight_type inv_dist_cubed + = 1. / (dist_squared * dist); + weight_type k_mi = spring_strength[get( + index, p)][get(index, i)]; + weight_type l_mi + = distance[get(index, p)][get(index, i)]; + for (std::size_t i = 0; i < Point::dimensions; + ++i) + { + for (std::size_t j = 0; + j < Point::dimensions; ++j) + { + if (i == j) + { + dE_d_d[i][i] += k_mi + * (1 + + (l_mi + * (diff[i] * diff[i] + - dist_squared) + * inv_dist_cubed)); + } + else + { + dE_d_d[i][j] += k_mi * l_mi + * diff[i] * diff[j] + * inv_dist_cubed; + // dE_d_d[i][j] += k_mi * l_mi * + // sqrt(hypot(diff[i], diff[j])) * + // inv_dist_cubed; + } + } + } + } + } + + deriv_type dE_d = get(partial_derivatives, p); + + // Solve dE_d_d * delta = -dE_d to get delta + point_difference_type delta + = -linear_solver< Point::dimensions >::solve( + dE_d_d, dE_d); + + // Move p by delta + position[p] = topology.adjust(position[p], delta); + + // Recompute partial derivatives and delta_p + deriv_type deriv = compute_partial_derivatives(p); + put(partial_derivatives, p, deriv); + + delta_p = topology.norm(deriv); + } while (!done(delta_p, p, g, false)); + + // Select new p by updating each partial derivative and + // delta + vertex_descriptor old_p = p; + for (ui = vertices(g).first, end = vertices(g).second; + ui != end; ++ui) + { + deriv_type old_deriv_p = p_partials[get(index, *ui)]; + deriv_type old_p_partial + = compute_partial_derivative(*ui, old_p); + deriv_type deriv = get(partial_derivatives, *ui); + + deriv += old_p_partial - old_deriv_p; + + put(partial_derivatives, *ui, deriv); + weight_type delta = topology.norm(deriv); + + if (delta > delta_p) + { + p = *ui; + delta_p = delta; + } + } + } - if (delta > delta_p) { - p = *ui; - delta_p = delta; + return true; } - } - } - return true; - } - - const Topology& topology; - const Graph& g; - PositionMap position; - WeightMap weight; - EdgeOrSideLength edge_or_side_length; - Done done; - weight_type spring_constant; - VertexIndexMap index; - DistanceMatrix distance; - SpringStrengthMatrix spring_strength; - PartialDerivativeMap partial_derivatives; - }; - } } // end namespace detail::graph - - /// States that the given quantity is an edge length. - template - inline detail::graph::edge_or_side - edge_length(T x) - { return detail::graph::edge_or_side(x); } - - /// States that the given quantity is a display area side length. - template - inline detail::graph::edge_or_side - side_length(T x) - { return detail::graph::edge_or_side(x); } - - /** - * \brief Determines when to terminate layout of a particular graph based - * on a given relative tolerance. - */ - template - struct layout_tolerance - { + const Topology& topology; + const Graph& g; + PositionMap position; + WeightMap weight; + EdgeOrSideLength edge_or_side_length; + Done done; + weight_type spring_constant; + VertexIndexMap index; + DistanceMatrix distance; + SpringStrengthMatrix spring_strength; + PartialDerivativeMap partial_derivatives; + }; + } +} // end namespace detail::graph + +/// States that the given quantity is an edge length. +template < typename T > +inline detail::graph::edge_or_side< true, T > edge_length(T x) +{ + return detail::graph::edge_or_side< true, T >(x); +} + +/// States that the given quantity is a display area side length. +template < typename T > +inline detail::graph::edge_or_side< false, T > side_length(T x) +{ + return detail::graph::edge_or_side< false, T >(x); +} + +/** + * \brief Determines when to terminate layout of a particular graph based + * on a given relative tolerance. + */ +template < typename T = double > struct layout_tolerance +{ layout_tolerance(const T& tolerance = T(0.001)) - : tolerance(tolerance), last_energy((std::numeric_limits::max)()), - last_local_energy((std::numeric_limits::max)()) { } - - template - bool - operator()(T delta_p, - typename boost::graph_traits::vertex_descriptor p, - const Graph& g, - bool global) + : tolerance(tolerance) + , last_energy((std::numeric_limits< T >::max)()) + , last_local_energy((std::numeric_limits< T >::max)()) + { + } + + template < typename Graph > + bool operator()(T delta_p, + typename boost::graph_traits< Graph >::vertex_descriptor p, + const Graph& g, bool global) { - if (global) { - if (last_energy == (std::numeric_limits::max)()) { - last_energy = delta_p; - return false; + if (global) + { + if (last_energy == (std::numeric_limits< T >::max)()) + { + last_energy = delta_p; + return false; + } + + T diff = last_energy - delta_p; + if (diff < T(0)) + diff = -diff; + bool done = (delta_p == T(0) || diff / last_energy < tolerance); + last_energy = delta_p; + return done; } - - T diff = last_energy - delta_p; - if (diff < T(0)) diff = -diff; - bool done = (delta_p == T(0) || diff / last_energy < tolerance); - last_energy = delta_p; - return done; - } else { - if (last_local_energy == (std::numeric_limits::max)()) { - last_local_energy = delta_p; - return delta_p == T(0); + else + { + if (last_local_energy == (std::numeric_limits< T >::max)()) + { + last_local_energy = delta_p; + return delta_p == T(0); + } + + T diff = last_local_energy - delta_p; + bool done + = (delta_p == T(0) || (diff / last_local_energy) < tolerance); + last_local_energy = delta_p; + return done; } - - T diff = last_local_energy - delta_p; - bool done = (delta_p == T(0) || (diff / last_local_energy) < tolerance); - last_local_energy = delta_p; - return done; - } } - private: +private: T tolerance; T last_energy; T last_local_energy; - }; - - /** \brief Kamada-Kawai spring layout for undirected graphs. - * - * This algorithm performs graph layout (in two dimensions) for - * connected, undirected graphs. It operates by relating the layout - * of graphs to a dynamic spring system and minimizing the energy - * within that system. The strength of a spring between two vertices - * is inversely proportional to the square of the shortest distance - * (in graph terms) between those two vertices. Essentially, - * vertices that are closer in the graph-theoretic sense (i.e., by - * following edges) will have stronger springs and will therefore be - * placed closer together. - * - * Prior to invoking this algorithm, it is recommended that the - * vertices be placed along the vertices of a regular n-sided - * polygon. - * - * \param g (IN) must be a model of Vertex List Graph, Edge List - * Graph, and Incidence Graph and must be undirected. - * - * \param position (OUT) must be a model of Lvalue Property Map, - * where the value type is a class containing fields @c x and @c y - * that will be set to the @c x and @c y coordinates of each vertex. - * - * \param weight (IN) must be a model of Readable Property Map, - * which provides the weight of each edge in the graph @p g. - * - * \param topology (IN) must be a topology object (see topology.hpp), - * which provides operations on points and differences between them. - * - * \param edge_or_side_length (IN) provides either the unit length - * @c e of an edge in the layout or the length of a side @c s of the - * display area, and must be either @c boost::edge_length(e) or @c - * boost::side_length(s), respectively. - * - * \param done (IN) is a 4-argument function object that is passed - * the current value of delta_p (i.e., the energy of vertex @p p), - * the vertex @p p, the graph @p g, and a boolean flag indicating - * whether @p delta_p is the maximum energy in the system (when @c - * true) or the energy of the vertex being moved. Defaults to @c - * layout_tolerance instantiated over the value type of the weight - * map. - * - * \param spring_constant (IN) is the constant multiplied by each - * spring's strength. Larger values create systems with more energy - * that can take longer to stabilize; smaller values create systems - * with less energy that stabilize quickly but do not necessarily - * result in pleasing layouts. The default value is 1. - * - * \param index (IN) is a mapping from vertices to index values - * between 0 and @c num_vertices(g). The default is @c - * get(vertex_index,g). - * - * \param distance (UTIL/OUT) will be used to store the distance - * from every vertex to every other vertex, which is computed in the - * first stages of the algorithm. This value's type must be a model - * of BasicMatrix with value type equal to the value type of the - * weight map. The default is a vector of vectors. - * - * \param spring_strength (UTIL/OUT) will be used to store the - * strength of the spring between every pair of vertices. This - * value's type must be a model of BasicMatrix with value type equal - * to the value type of the weight map. The default is a vector of - * vectors. - * - * \param partial_derivatives (UTIL) will be used to store the - * partial derivates of each vertex with respect to the @c x and @c - * y coordinates. This must be a Read/Write Property Map whose value - * type is a pair with both types equivalent to the value type of - * the weight map. The default is an iterator property map. - * - * \returns @c true if layout was successful or @c false if a - * negative weight cycle was detected. - */ - template - bool - kamada_kawai_spring_layout( - const Graph& g, - PositionMap position, - WeightMap weight, - const Topology& topology, - detail::graph::edge_or_side edge_or_side_length, +}; + +/** \brief Kamada-Kawai spring layout for undirected graphs. + * + * This algorithm performs graph layout (in two dimensions) for + * connected, undirected graphs. It operates by relating the layout + * of graphs to a dynamic spring system and minimizing the energy + * within that system. The strength of a spring between two vertices + * is inversely proportional to the square of the shortest distance + * (in graph terms) between those two vertices. Essentially, + * vertices that are closer in the graph-theoretic sense (i.e., by + * following edges) will have stronger springs and will therefore be + * placed closer together. + * + * Prior to invoking this algorithm, it is recommended that the + * vertices be placed along the vertices of a regular n-sided + * polygon. + * + * \param g (IN) must be a model of Vertex List Graph, Edge List + * Graph, and Incidence Graph and must be undirected. + * + * \param position (OUT) must be a model of Lvalue Property Map, + * where the value type is a class containing fields @c x and @c y + * that will be set to the @c x and @c y coordinates of each vertex. + * + * \param weight (IN) must be a model of Readable Property Map, + * which provides the weight of each edge in the graph @p g. + * + * \param topology (IN) must be a topology object (see topology.hpp), + * which provides operations on points and differences between them. + * + * \param edge_or_side_length (IN) provides either the unit length + * @c e of an edge in the layout or the length of a side @c s of the + * display area, and must be either @c boost::edge_length(e) or @c + * boost::side_length(s), respectively. + * + * \param done (IN) is a 4-argument function object that is passed + * the current value of delta_p (i.e., the energy of vertex @p p), + * the vertex @p p, the graph @p g, and a boolean flag indicating + * whether @p delta_p is the maximum energy in the system (when @c + * true) or the energy of the vertex being moved. Defaults to @c + * layout_tolerance instantiated over the value type of the weight + * map. + * + * \param spring_constant (IN) is the constant multiplied by each + * spring's strength. Larger values create systems with more energy + * that can take longer to stabilize; smaller values create systems + * with less energy that stabilize quickly but do not necessarily + * result in pleasing layouts. The default value is 1. + * + * \param index (IN) is a mapping from vertices to index values + * between 0 and @c num_vertices(g). The default is @c + * get(vertex_index,g). + * + * \param distance (UTIL/OUT) will be used to store the distance + * from every vertex to every other vertex, which is computed in the + * first stages of the algorithm. This value's type must be a model + * of BasicMatrix with value type equal to the value type of the + * weight map. The default is a vector of vectors. + * + * \param spring_strength (UTIL/OUT) will be used to store the + * strength of the spring between every pair of vertices. This + * value's type must be a model of BasicMatrix with value type equal + * to the value type of the weight map. The default is a vector of + * vectors. + * + * \param partial_derivatives (UTIL) will be used to store the + * partial derivates of each vertex with respect to the @c x and @c + * y coordinates. This must be a Read/Write Property Map whose value + * type is a pair with both types equivalent to the value type of + * the weight map. The default is an iterator property map. + * + * \returns @c true if layout was successful or @c false if a + * negative weight cycle was detected. + */ +template < typename Topology, typename Graph, typename PositionMap, + typename WeightMap, typename T, bool EdgeOrSideLength, typename Done, + typename VertexIndexMap, typename DistanceMatrix, + typename SpringStrengthMatrix, typename PartialDerivativeMap > +bool kamada_kawai_spring_layout(const Graph& g, PositionMap position, + WeightMap weight, const Topology& topology, + detail::graph::edge_or_side< EdgeOrSideLength, T > edge_or_side_length, Done done, - typename property_traits::value_type spring_constant, - VertexIndexMap index, - DistanceMatrix distance, + typename property_traits< WeightMap >::value_type spring_constant, + VertexIndexMap index, DistanceMatrix distance, SpringStrengthMatrix spring_strength, PartialDerivativeMap partial_derivatives) - { - BOOST_STATIC_ASSERT((is_convertible< - typename graph_traits::directed_category*, - undirected_tag* - >::value)); - - detail::graph::kamada_kawai_spring_layout_impl< - Topology, Graph, PositionMap, WeightMap, - detail::graph::edge_or_side, Done, VertexIndexMap, - DistanceMatrix, SpringStrengthMatrix, PartialDerivativeMap> - alg(topology, g, position, weight, edge_or_side_length, done, spring_constant, - index, distance, spring_strength, partial_derivatives); +{ + BOOST_STATIC_ASSERT( + (is_convertible< typename graph_traits< Graph >::directed_category*, + undirected_tag* >::value)); + + detail::graph::kamada_kawai_spring_layout_impl< Topology, Graph, + PositionMap, WeightMap, + detail::graph::edge_or_side< EdgeOrSideLength, T >, Done, + VertexIndexMap, DistanceMatrix, SpringStrengthMatrix, + PartialDerivativeMap > + alg(topology, g, position, weight, edge_or_side_length, done, + spring_constant, index, distance, spring_strength, + partial_derivatives); return alg.run(); - } - - /** - * \overload - */ - template - bool - kamada_kawai_spring_layout( - const Graph& g, - PositionMap position, - WeightMap weight, - const Topology& topology, - detail::graph::edge_or_side edge_or_side_length, +} + +/** + * \overload + */ +template < typename Topology, typename Graph, typename PositionMap, + typename WeightMap, typename T, bool EdgeOrSideLength, typename Done, + typename VertexIndexMap > +bool kamada_kawai_spring_layout(const Graph& g, PositionMap position, + WeightMap weight, const Topology& topology, + detail::graph::edge_or_side< EdgeOrSideLength, T > edge_or_side_length, Done done, - typename property_traits::value_type spring_constant, + typename property_traits< WeightMap >::value_type spring_constant, VertexIndexMap index) - { - typedef typename property_traits::value_type weight_type; +{ + typedef typename property_traits< WeightMap >::value_type weight_type; - typename graph_traits::vertices_size_type n = num_vertices(g); - typedef std::vector weight_vec; + typename graph_traits< Graph >::vertices_size_type n = num_vertices(g); + typedef std::vector< weight_type > weight_vec; - std::vector distance(n, weight_vec(n)); - std::vector spring_strength(n, weight_vec(n)); - std::vector partial_derivatives(n); + std::vector< weight_vec > distance(n, weight_vec(n)); + std::vector< weight_vec > spring_strength(n, weight_vec(n)); + std::vector< typename Topology::point_difference_type > partial_derivatives( + n); - return - kamada_kawai_spring_layout( - g, position, weight, topology, edge_or_side_length, done, spring_constant, index, - distance.begin(), + return kamada_kawai_spring_layout(g, position, weight, topology, + edge_or_side_length, done, spring_constant, index, distance.begin(), spring_strength.begin(), make_iterator_property_map(partial_derivatives.begin(), index, - typename Topology::point_difference_type())); - } - - /** - * \overload - */ - template - bool - kamada_kawai_spring_layout( - const Graph& g, - PositionMap position, - WeightMap weight, - const Topology& topology, - detail::graph::edge_or_side edge_or_side_length, + typename Topology::point_difference_type())); +} + +/** + * \overload + */ +template < typename Topology, typename Graph, typename PositionMap, + typename WeightMap, typename T, bool EdgeOrSideLength, typename Done > +bool kamada_kawai_spring_layout(const Graph& g, PositionMap position, + WeightMap weight, const Topology& topology, + detail::graph::edge_or_side< EdgeOrSideLength, T > edge_or_side_length, Done done, - typename property_traits::value_type spring_constant) - { - return kamada_kawai_spring_layout(g, position, weight, topology, edge_or_side_length, - done, spring_constant, - get(vertex_index, g)); - } - - /** - * \overload - */ - template - bool - kamada_kawai_spring_layout( - const Graph& g, - PositionMap position, - WeightMap weight, - const Topology& topology, - detail::graph::edge_or_side edge_or_side_length, + typename property_traits< WeightMap >::value_type spring_constant) +{ + return kamada_kawai_spring_layout(g, position, weight, topology, + edge_or_side_length, done, spring_constant, get(vertex_index, g)); +} + +/** + * \overload + */ +template < typename Topology, typename Graph, typename PositionMap, + typename WeightMap, typename T, bool EdgeOrSideLength, typename Done > +bool kamada_kawai_spring_layout(const Graph& g, PositionMap position, + WeightMap weight, const Topology& topology, + detail::graph::edge_or_side< EdgeOrSideLength, T > edge_or_side_length, Done done) - { - typedef typename property_traits::value_type weight_type; - return kamada_kawai_spring_layout(g, position, weight, topology, edge_or_side_length, - done, weight_type(1)); - } - - /** - * \overload - */ - template - bool - kamada_kawai_spring_layout( - const Graph& g, - PositionMap position, - WeightMap weight, - const Topology& topology, - detail::graph::edge_or_side edge_or_side_length) - { - typedef typename property_traits::value_type weight_type; - return kamada_kawai_spring_layout(g, position, weight, topology, edge_or_side_length, - layout_tolerance(), - weight_type(1.0), - get(vertex_index, g)); - } +{ + typedef typename property_traits< WeightMap >::value_type weight_type; + return kamada_kawai_spring_layout(g, position, weight, topology, + edge_or_side_length, done, weight_type(1)); +} + +/** + * \overload + */ +template < typename Topology, typename Graph, typename PositionMap, + typename WeightMap, typename T, bool EdgeOrSideLength > +bool kamada_kawai_spring_layout(const Graph& g, PositionMap position, + WeightMap weight, const Topology& topology, + detail::graph::edge_or_side< EdgeOrSideLength, T > edge_or_side_length) +{ + typedef typename property_traits< WeightMap >::value_type weight_type; + return kamada_kawai_spring_layout(g, position, weight, topology, + edge_or_side_length, layout_tolerance< weight_type >(), + weight_type(1.0), get(vertex_index, g)); +} } // end namespace boost #endif // BOOST_GRAPH_KAMADA_KAWAI_SPRING_LAYOUT_HPP diff --git a/include/boost/graph/king_ordering.hpp b/include/boost/graph/king_ordering.hpp index 29e7ac970..7c1ddc16f 100644 --- a/include/boost/graph/king_ordering.hpp +++ b/include/boost/graph/king_ordering.hpp @@ -19,298 +19,321 @@ King Algorithm for matrix reordering */ -namespace boost { - namespace detail { - template - class bfs_king_visitor:public default_bfs_visitor +namespace boost +{ +namespace detail +{ + template < typename OutputIterator, typename Buffer, typename Compare, + typename PseudoDegreeMap, typename VecMap, typename VertexIndexMap > + class bfs_king_visitor : public default_bfs_visitor { public: - bfs_king_visitor(OutputIterator *iter, Buffer *b, Compare compare, - PseudoDegreeMap deg, std::vector loc, VecMap color, - VertexIndexMap vertices): - permutation(iter), Qptr(b), degree(deg), comp(compare), - Qlocation(loc), colors(color), vertex_map(vertices) { } - - template - void finish_vertex(Vertex, Graph& g) { - typename graph_traits::out_edge_iterator ei, ei_end; - Vertex v, w; - - typedef typename std::deque::reverse_iterator reverse_iterator; - - reverse_iterator rend = Qptr->rend()-index_begin; - reverse_iterator rbegin = Qptr->rbegin(); - - - //heap the vertices already there - std::make_heap(rbegin, rend, boost::bind(comp, _2, _1)); - - unsigned i = 0; - - for(i = index_begin; i != Qptr->size(); ++i){ - colors[get(vertex_map, (*Qptr)[i])] = 1; - Qlocation[get(vertex_map, (*Qptr)[i])] = i; + bfs_king_visitor(OutputIterator* iter, Buffer* b, Compare compare, + PseudoDegreeMap deg, std::vector< int > loc, VecMap color, + VertexIndexMap vertices) + : permutation(iter) + , Qptr(b) + , degree(deg) + , comp(compare) + , Qlocation(loc) + , colors(color) + , vertex_map(vertices) + { } - i = 0; - - for( ; rbegin != rend; rend--){ - percolate_down(i); - w = (*Qptr)[index_begin+i]; - for (boost::tie(ei, ei_end) = out_edges(w, g); ei != ei_end; ++ei) { - v = target(*ei, g); - put(degree, v, get(degree, v) - 1); - - if (colors[get(vertex_map, v)] == 1) { - percolate_up(get(vertex_map, v), i); + template < typename Vertex, typename Graph > + void finish_vertex(Vertex, Graph& g) + { + typename graph_traits< Graph >::out_edge_iterator ei, ei_end; + Vertex v, w; + + typedef typename std::deque< Vertex >::reverse_iterator + reverse_iterator; + + reverse_iterator rend = Qptr->rend() - index_begin; + reverse_iterator rbegin = Qptr->rbegin(); + + // heap the vertices already there + std::make_heap(rbegin, rend, boost::bind< bool >(comp, _2, _1)); + + unsigned i = 0; + + for (i = index_begin; i != Qptr->size(); ++i) + { + colors[get(vertex_map, (*Qptr)[i])] = 1; + Qlocation[get(vertex_map, (*Qptr)[i])] = i; } - } - - colors[get(vertex_map, w)] = 0; - i++; + + i = 0; + + for (; rbegin != rend; rend--) + { + percolate_down< Vertex >(i); + w = (*Qptr)[index_begin + i]; + for (boost::tie(ei, ei_end) = out_edges(w, g); ei != ei_end; + ++ei) + { + v = target(*ei, g); + put(degree, v, get(degree, v) - 1); + + if (colors[get(vertex_map, v)] == 1) + { + percolate_up< Vertex >(get(vertex_map, v), i); + } + } + + colors[get(vertex_map, w)] = 0; + i++; + } + } + + template < typename Vertex, typename Graph > + void examine_vertex(Vertex u, const Graph&) + { + + *(*permutation)++ = u; + index_begin = Qptr->size(); } - } - - template - void examine_vertex(Vertex u, const Graph&) { - - *(*permutation)++ = u; - index_begin = Qptr->size(); - - } + protected: + // this function replaces pop_heap, and tracks state information + template < typename Vertex > void percolate_down(int offset) + { + int heap_last = index_begin + offset; + int heap_first = Qptr->size() - 1; + + // pop_heap functionality: + // swap first, last + std::swap((*Qptr)[heap_last], (*Qptr)[heap_first]); + + // swap in the location queue + std::swap(Qlocation[heap_first], Qlocation[heap_last]); + + // set drifter, children + int drifter = heap_first; + int drifter_heap = Qptr->size() - drifter; + + int right_child_heap = drifter_heap * 2 + 1; + int right_child = Qptr->size() - right_child_heap; + + int left_child_heap = drifter_heap * 2; + int left_child = Qptr->size() - left_child_heap; + + // check that we are staying in the heap + bool valid = (right_child < heap_last) ? false : true; + + // pick smallest child of drifter, and keep in mind there might only + // be left child + int smallest_child = (valid + && get(degree, (*Qptr)[left_child]) + > get(degree, (*Qptr)[right_child])) + ? right_child + : left_child; + + while (valid && smallest_child < heap_last + && comp((*Qptr)[drifter], (*Qptr)[smallest_child])) + { + // if smallest child smaller than drifter, swap them + std::swap((*Qptr)[smallest_child], (*Qptr)[drifter]); + std::swap(Qlocation[drifter], Qlocation[smallest_child]); - //this function replaces pop_heap, and tracks state information - template - void percolate_down(int offset){ - int heap_last = index_begin + offset; - int heap_first = Qptr->size() - 1; - - //pop_heap functionality: - //swap first, last - std::swap((*Qptr)[heap_last], (*Qptr)[heap_first]); - - //swap in the location queue - std::swap(Qlocation[heap_first], Qlocation[heap_last]); - - //set drifter, children - int drifter = heap_first; - int drifter_heap = Qptr->size() - drifter; - - int right_child_heap = drifter_heap * 2 + 1; - int right_child = Qptr->size() - right_child_heap; - - int left_child_heap = drifter_heap * 2; - int left_child = Qptr->size() - left_child_heap; - - //check that we are staying in the heap - bool valid = (right_child < heap_last) ? false : true; - - //pick smallest child of drifter, and keep in mind there might only be left child - int smallest_child = (valid && get(degree, (*Qptr)[left_child]) > get(degree,(*Qptr)[right_child])) ? - right_child : left_child; - - while(valid && smallest_child < heap_last && comp((*Qptr)[drifter], (*Qptr)[smallest_child])){ - - //if smallest child smaller than drifter, swap them - std::swap((*Qptr)[smallest_child], (*Qptr)[drifter]); - std::swap(Qlocation[drifter], Qlocation[smallest_child]); - - //update the values, run again, as necessary - drifter = smallest_child; - drifter_heap = Qptr->size() - drifter; - - right_child_heap = drifter_heap * 2 + 1; - right_child = Qptr->size() - right_child_heap; - - left_child_heap = drifter_heap * 2; - left_child = Qptr->size() - left_child_heap; - - valid = (right_child < heap_last) ? false : true; - - smallest_child = (valid && get(degree, (*Qptr)[left_child]) > get(degree,(*Qptr)[right_child])) ? - right_child : left_child; + // update the values, run again, as necessary + drifter = smallest_child; + drifter_heap = Qptr->size() - drifter; + + right_child_heap = drifter_heap * 2 + 1; + right_child = Qptr->size() - right_child_heap; + + left_child_heap = drifter_heap * 2; + left_child = Qptr->size() - left_child_heap; + + valid = (right_child < heap_last) ? false : true; + + smallest_child = (valid + && get(degree, (*Qptr)[left_child]) + > get(degree, (*Qptr)[right_child])) + ? right_child + : left_child; + } } - } - - - - // this is like percolate down, but we always compare against the - // parent, as there is only a single choice - template - void percolate_up(int vertex, int offset){ - - int child_location = Qlocation[vertex]; - int heap_child_location = Qptr->size() - child_location; - int heap_parent_location = (int)(heap_child_location/2); - unsigned parent_location = Qptr->size() - heap_parent_location; - - bool valid = (heap_parent_location != 0 && child_location > index_begin + offset && - parent_location < Qptr->size()); - - while(valid && comp((*Qptr)[child_location], (*Qptr)[parent_location])){ - - //swap in the heap - std::swap((*Qptr)[child_location], (*Qptr)[parent_location]); - - //swap in the location queue - std::swap(Qlocation[child_location], Qlocation[parent_location]); - - child_location = parent_location; - heap_child_location = heap_parent_location; - heap_parent_location = (int)(heap_child_location/2); - parent_location = Qptr->size() - heap_parent_location; - valid = (heap_parent_location != 0 && child_location > index_begin + offset); + // this is like percolate down, but we always compare against the + // parent, as there is only a single choice + template < typename Vertex > void percolate_up(int vertex, int offset) + { + + int child_location = Qlocation[vertex]; + int heap_child_location = Qptr->size() - child_location; + int heap_parent_location = (int)(heap_child_location / 2); + unsigned parent_location = Qptr->size() - heap_parent_location; + + bool valid = (heap_parent_location != 0 + && child_location > index_begin + offset + && parent_location < Qptr->size()); + + while (valid + && comp((*Qptr)[child_location], (*Qptr)[parent_location])) + { + + // swap in the heap + std::swap((*Qptr)[child_location], (*Qptr)[parent_location]); + + // swap in the location queue + std::swap( + Qlocation[child_location], Qlocation[parent_location]); + + child_location = parent_location; + heap_child_location = heap_parent_location; + heap_parent_location = (int)(heap_child_location / 2); + parent_location = Qptr->size() - heap_parent_location; + valid = (heap_parent_location != 0 + && child_location > index_begin + offset); + } } - } - - OutputIterator *permutation; - int index_begin; - Buffer *Qptr; - PseudoDegreeMap degree; - Compare comp; - std::vector Qlocation; - VecMap colors; - VertexIndexMap vertex_map; + + OutputIterator* permutation; + int index_begin; + Buffer* Qptr; + PseudoDegreeMap degree; + Compare comp; + std::vector< int > Qlocation; + VecMap colors; + VertexIndexMap vertex_map; }; - - - } // namespace detail - - - template - OutputIterator - king_ordering(const Graph& g, - std::deque< typename graph_traits::vertex_descriptor > - vertex_queue, - OutputIterator permutation, - ColorMap color, DegreeMap degree, - VertexIndexMap index_map) - { - typedef typename property_traits::value_type ds_type; - typedef typename property_traits::value_type ColorValue; - typedef color_traits Color; - typedef typename graph_traits::vertex_descriptor Vertex; - typedef iterator_property_map::iterator, VertexIndexMap, ds_type, ds_type&> PseudoDegreeMap; - typedef indirect_cmp > Compare; - typedef typename boost::sparse::sparse_ordering_queue queue; - typedef typename detail::bfs_king_visitor, VertexIndexMap > Visitor; - typedef typename graph_traits::vertices_size_type - vertices_size_type; - std::vector pseudo_degree_vec(num_vertices(g)); + +} // namespace detail + +template < class Graph, class OutputIterator, class ColorMap, class DegreeMap, + typename VertexIndexMap > +OutputIterator king_ordering(const Graph& g, + std::deque< typename graph_traits< Graph >::vertex_descriptor > + vertex_queue, + OutputIterator permutation, ColorMap color, DegreeMap degree, + VertexIndexMap index_map) +{ + typedef typename property_traits< DegreeMap >::value_type ds_type; + typedef typename property_traits< ColorMap >::value_type ColorValue; + typedef color_traits< ColorValue > Color; + typedef typename graph_traits< Graph >::vertex_descriptor Vertex; + typedef iterator_property_map< typename std::vector< ds_type >::iterator, + VertexIndexMap, ds_type, ds_type& > + PseudoDegreeMap; + typedef indirect_cmp< PseudoDegreeMap, std::less< ds_type > > Compare; + typedef typename boost::sparse::sparse_ordering_queue< Vertex > queue; + typedef typename detail::bfs_king_visitor< OutputIterator, queue, Compare, + PseudoDegreeMap, std::vector< int >, VertexIndexMap > + Visitor; + typedef + typename graph_traits< Graph >::vertices_size_type vertices_size_type; + std::vector< ds_type > pseudo_degree_vec(num_vertices(g)); PseudoDegreeMap pseudo_degree(pseudo_degree_vec.begin(), index_map); - - typename graph_traits::vertex_iterator ui, ui_end; + + typename graph_traits< Graph >::vertex_iterator ui, ui_end; queue Q; // Copy degree to pseudo_degree // initialize the color map - for (boost::tie(ui, ui_end) = vertices(g); ui != ui_end; ++ui){ - put(pseudo_degree, *ui, get(degree, *ui)); - put(color, *ui, Color::white()); + for (boost::tie(ui, ui_end) = vertices(g); ui != ui_end; ++ui) + { + put(pseudo_degree, *ui, get(degree, *ui)); + put(color, *ui, Color::white()); } - + Compare comp(pseudo_degree); - std::vector colors(num_vertices(g)); + std::vector< int > colors(num_vertices(g)); - for(vertices_size_type i = 0; i < num_vertices(g); i++) - colors[i] = 0; + for (vertices_size_type i = 0; i < num_vertices(g); i++) + colors[i] = 0; - std::vector loc(num_vertices(g)); + std::vector< int > loc(num_vertices(g)); - //create the visitor + // create the visitor Visitor vis(&permutation, &Q, comp, pseudo_degree, loc, colors, index_map); - - while( !vertex_queue.empty() ) { - Vertex s = vertex_queue.front(); - vertex_queue.pop_front(); - - //call BFS with visitor - breadth_first_visit(g, s, Q, vis, color); + + while (!vertex_queue.empty()) + { + Vertex s = vertex_queue.front(); + vertex_queue.pop_front(); + + // call BFS with visitor + breadth_first_visit(g, s, Q, vis, color); } return permutation; - } - - - // This is the case where only a single starting vertex is supplied. - template - OutputIterator - king_ordering(const Graph& g, - typename graph_traits::vertex_descriptor s, - OutputIterator permutation, - ColorMap color, DegreeMap degree, VertexIndexMap index_map) - { - - std::deque< typename graph_traits::vertex_descriptor > vertex_queue; - vertex_queue.push_front( s ); - return king_ordering(g, vertex_queue, permutation, color, degree, - index_map); - } - - - template < class Graph, class OutputIterator, - class ColorMap, class DegreeMap, class VertexIndexMap> - OutputIterator - king_ordering(const Graph& G, OutputIterator permutation, - ColorMap color, DegreeMap degree, VertexIndexMap index_map) - { +} + +// This is the case where only a single starting vertex is supplied. +template < class Graph, class OutputIterator, class ColorMap, class DegreeMap, + typename VertexIndexMap > +OutputIterator king_ordering(const Graph& g, + typename graph_traits< Graph >::vertex_descriptor s, + OutputIterator permutation, ColorMap color, DegreeMap degree, + VertexIndexMap index_map) +{ + + std::deque< typename graph_traits< Graph >::vertex_descriptor > + vertex_queue; + vertex_queue.push_front(s); + return king_ordering( + g, vertex_queue, permutation, color, degree, index_map); +} + +template < class Graph, class OutputIterator, class ColorMap, class DegreeMap, + class VertexIndexMap > +OutputIterator king_ordering(const Graph& G, OutputIterator permutation, + ColorMap color, DegreeMap degree, VertexIndexMap index_map) +{ if (has_no_vertices(G)) - return permutation; + return permutation; - typedef typename boost::graph_traits::vertex_descriptor Vertex; - typedef typename property_traits::value_type ColorValue; - typedef color_traits Color; + typedef typename boost::graph_traits< Graph >::vertex_descriptor Vertex; + typedef typename property_traits< ColorMap >::value_type ColorValue; + typedef color_traits< ColorValue > Color; - std::deque vertex_queue; + std::deque< Vertex > vertex_queue; // Mark everything white BGL_FORALL_VERTICES_T(v, G, Graph) put(color, v, Color::white()); - // Find one vertex from each connected component - BGL_FORALL_VERTICES_T(v, G, Graph) { - if (get(color, v) == Color::white()) { - depth_first_visit(G, v, dfs_visitor<>(), color); - vertex_queue.push_back(v); - } + // Find one vertex from each connected component + BGL_FORALL_VERTICES_T(v, G, Graph) + { + if (get(color, v) == Color::white()) + { + depth_first_visit(G, v, dfs_visitor<>(), color); + vertex_queue.push_back(v); + } } // Find starting nodes for all vertices // TBD: How to do this with a directed graph? - for (typename std::deque::iterator i = vertex_queue.begin(); + for (typename std::deque< Vertex >::iterator i = vertex_queue.begin(); i != vertex_queue.end(); ++i) - *i = find_starting_node(G, *i, color, degree); - - return king_ordering(G, vertex_queue, permutation, color, degree, - index_map); - } - - template - OutputIterator - king_ordering(const Graph& G, OutputIterator permutation, - VertexIndexMap index_map) - { + *i = find_starting_node(G, *i, color, degree); + + return king_ordering( + G, vertex_queue, permutation, color, degree, index_map); +} + +template < typename Graph, typename OutputIterator, typename VertexIndexMap > +OutputIterator king_ordering( + const Graph& G, OutputIterator permutation, VertexIndexMap index_map) +{ if (has_no_vertices(G)) - return permutation; + return permutation; - std::vector colors(num_vertices(G)); - return king_ordering(G, permutation, - make_iterator_property_map(&colors[0], index_map, - colors[0]), - make_out_degree_map(G), index_map); - } + std::vector< default_color_type > colors(num_vertices(G)); + return king_ordering(G, permutation, + make_iterator_property_map(&colors[0], index_map, colors[0]), + make_out_degree_map(G), index_map); +} - template - inline OutputIterator - king_ordering(const Graph& G, OutputIterator permutation) - { return king_ordering(G, permutation, get(vertex_index, G)); } +template < typename Graph, typename OutputIterator > +inline OutputIterator king_ordering(const Graph& G, OutputIterator permutation) +{ + return king_ordering(G, permutation, get(vertex_index, G)); +} } // namespace boost - #endif // BOOST_GRAPH_KING_HPP diff --git a/include/boost/graph/kruskal_min_spanning_tree.hpp b/include/boost/graph/kruskal_min_spanning_tree.hpp index b7e815770..1e91feb49 100644 --- a/include/boost/graph/kruskal_min_spanning_tree.hpp +++ b/include/boost/graph/kruskal_min_spanning_tree.hpp @@ -12,7 +12,7 @@ #define BOOST_GRAPH_MST_KRUSKAL_HPP /* - *Minimum Spanning Tree + *Minimum Spanning Tree * Kruskal Algorithm * *Requirement: @@ -30,126 +30,123 @@ #include #include +namespace boost +{ -namespace boost { - - // Kruskal's algorithm for Minimum Spanning Tree - // - // This is a greedy algorithm to calculate the Minimum Spanning Tree - // for an undirected graph with weighted edges. The output will be a - // set of edges. - // +// Kruskal's algorithm for Minimum Spanning Tree +// +// This is a greedy algorithm to calculate the Minimum Spanning Tree +// for an undirected graph with weighted edges. The output will be a +// set of edges. +// - namespace detail { +namespace detail +{ - template - void - kruskal_mst_impl(const Graph& G, - OutputIterator spanning_tree_edges, - Rank rank, Parent parent, Weight weight) + template < class Graph, class OutputIterator, class Rank, class Parent, + class Weight > + void kruskal_mst_impl(const Graph& G, OutputIterator spanning_tree_edges, + Rank rank, Parent parent, Weight weight) { - if (num_vertices(G) == 0) return; // Nothing to do in this case - typedef typename graph_traits::vertex_descriptor Vertex; - typedef typename graph_traits::edge_descriptor Edge; - BOOST_CONCEPT_ASSERT(( VertexListGraphConcept )); - BOOST_CONCEPT_ASSERT(( EdgeListGraphConcept )); - BOOST_CONCEPT_ASSERT(( OutputIteratorConcept )); - BOOST_CONCEPT_ASSERT(( ReadWritePropertyMapConcept )); - BOOST_CONCEPT_ASSERT(( ReadWritePropertyMapConcept )); - BOOST_CONCEPT_ASSERT(( ReadablePropertyMapConcept )); - typedef typename property_traits::value_type W_value; - typedef typename property_traits::value_type R_value; - typedef typename property_traits::value_type P_value; - BOOST_CONCEPT_ASSERT(( ComparableConcept )); - BOOST_CONCEPT_ASSERT(( ConvertibleConcept )); - BOOST_CONCEPT_ASSERT(( IntegerConcept )); - - disjoint_sets dset(rank, parent); - - typename graph_traits::vertex_iterator ui, uiend; - for (boost::tie(ui, uiend) = vertices(G); ui != uiend; ++ui) - dset.make_set(*ui); - - typedef indirect_cmp > weight_greater; - weight_greater wl(weight); - std::priority_queue, weight_greater> Q(wl); - /*push all edge into Q*/ - typename graph_traits::edge_iterator ei, eiend; - for (boost::tie(ei, eiend) = edges(G); ei != eiend; ++ei) - Q.push(*ei); - - while (! Q.empty()) { - Edge e = Q.top(); - Q.pop(); - Vertex u = dset.find_set(source(e, G)); - Vertex v = dset.find_set(target(e, G)); - if ( u != v ) { - *spanning_tree_edges++ = e; - dset.link(u, v); + if (num_vertices(G) == 0) + return; // Nothing to do in this case + typedef typename graph_traits< Graph >::vertex_descriptor Vertex; + typedef typename graph_traits< Graph >::edge_descriptor Edge; + BOOST_CONCEPT_ASSERT((VertexListGraphConcept< Graph >)); + BOOST_CONCEPT_ASSERT((EdgeListGraphConcept< Graph >)); + BOOST_CONCEPT_ASSERT((OutputIteratorConcept< OutputIterator, Edge >)); + BOOST_CONCEPT_ASSERT((ReadWritePropertyMapConcept< Rank, Vertex >)); + BOOST_CONCEPT_ASSERT((ReadWritePropertyMapConcept< Parent, Vertex >)); + BOOST_CONCEPT_ASSERT((ReadablePropertyMapConcept< Weight, Edge >)); + typedef typename property_traits< Weight >::value_type W_value; + typedef typename property_traits< Rank >::value_type R_value; + typedef typename property_traits< Parent >::value_type P_value; + BOOST_CONCEPT_ASSERT((ComparableConcept< W_value >)); + BOOST_CONCEPT_ASSERT((ConvertibleConcept< P_value, Vertex >)); + BOOST_CONCEPT_ASSERT((IntegerConcept< R_value >)); + + disjoint_sets< Rank, Parent > dset(rank, parent); + + typename graph_traits< Graph >::vertex_iterator ui, uiend; + for (boost::tie(ui, uiend) = vertices(G); ui != uiend; ++ui) + dset.make_set(*ui); + + typedef indirect_cmp< Weight, std::greater< W_value > > weight_greater; + weight_greater wl(weight); + std::priority_queue< Edge, std::vector< Edge >, weight_greater > Q(wl); + /*push all edge into Q*/ + typename graph_traits< Graph >::edge_iterator ei, eiend; + for (boost::tie(ei, eiend) = edges(G); ei != eiend; ++ei) + Q.push(*ei); + + while (!Q.empty()) + { + Edge e = Q.top(); + Q.pop(); + Vertex u = dset.find_set(source(e, G)); + Vertex v = dset.find_set(target(e, G)); + if (u != v) + { + *spanning_tree_edges++ = e; + dset.link(u, v); + } } - } } - } // namespace detail - - // Named Parameters Variants - - template - inline void - kruskal_minimum_spanning_tree(const Graph& g, - OutputIterator spanning_tree_edges) - { - typedef typename graph_traits::vertices_size_type size_type; - typedef typename graph_traits::vertex_descriptor vertex_t; - if (num_vertices(g) == 0) return; // Nothing to do in this case - typename graph_traits::vertices_size_type - n = num_vertices(g); - std::vector rank_map(n); - std::vector pred_map(n); - - detail::kruskal_mst_impl - (g, spanning_tree_edges, - make_iterator_property_map(rank_map.begin(), get(vertex_index, g), rank_map[0]), - make_iterator_property_map(pred_map.begin(), get(vertex_index, g), pred_map[0]), - get(edge_weight, g)); - } - - template - inline void - kruskal_minimum_spanning_tree(const Graph& g, - OutputIterator spanning_tree_edges, - const bgl_named_params& params) - { - typedef typename graph_traits::vertices_size_type size_type; - typedef typename graph_traits::vertex_descriptor vertex_t; - if (num_vertices(g) == 0) return; // Nothing to do in this case - typename graph_traits::vertices_size_type n; - n = is_default_param(get_param(params, vertex_rank)) - ? num_vertices(g) : 1; - std::vector rank_map(n); +} // namespace detail + +// Named Parameters Variants + +template < class Graph, class OutputIterator > +inline void kruskal_minimum_spanning_tree( + const Graph& g, OutputIterator spanning_tree_edges) +{ + typedef typename graph_traits< Graph >::vertices_size_type size_type; + typedef typename graph_traits< Graph >::vertex_descriptor vertex_t; + if (num_vertices(g) == 0) + return; // Nothing to do in this case + typename graph_traits< Graph >::vertices_size_type n = num_vertices(g); + std::vector< size_type > rank_map(n); + std::vector< vertex_t > pred_map(n); + + detail::kruskal_mst_impl(g, spanning_tree_edges, + make_iterator_property_map( + rank_map.begin(), get(vertex_index, g), rank_map[0]), + make_iterator_property_map( + pred_map.begin(), get(vertex_index, g), pred_map[0]), + get(edge_weight, g)); +} + +template < class Graph, class OutputIterator, class P, class T, class R > +inline void kruskal_minimum_spanning_tree(const Graph& g, + OutputIterator spanning_tree_edges, + const bgl_named_params< P, T, R >& params) +{ + typedef typename graph_traits< Graph >::vertices_size_type size_type; + typedef typename graph_traits< Graph >::vertex_descriptor vertex_t; + if (num_vertices(g) == 0) + return; // Nothing to do in this case + typename graph_traits< Graph >::vertices_size_type n; + n = is_default_param(get_param(params, vertex_rank)) ? num_vertices(g) : 1; + std::vector< size_type > rank_map(n); n = is_default_param(get_param(params, vertex_predecessor)) - ? num_vertices(g) : 1; - std::vector pred_map(n); - - detail::kruskal_mst_impl - (g, spanning_tree_edges, - choose_param - (get_param(params, vertex_rank), - make_iterator_property_map - (rank_map.begin(), - choose_pmap(get_param(params, vertex_index), g, vertex_index), rank_map[0])), - choose_param - (get_param(params, vertex_predecessor), - make_iterator_property_map - (pred_map.begin(), - choose_const_pmap(get_param(params, vertex_index), g, vertex_index), - pred_map[0])), - choose_const_pmap(get_param(params, edge_weight), g, edge_weight)); - } - -} // namespace boost + ? num_vertices(g) + : 1; + std::vector< vertex_t > pred_map(n); + + detail::kruskal_mst_impl(g, spanning_tree_edges, + choose_param(get_param(params, vertex_rank), + make_iterator_property_map(rank_map.begin(), + choose_pmap(get_param(params, vertex_index), g, vertex_index), + rank_map[0])), + choose_param(get_param(params, vertex_predecessor), + make_iterator_property_map(pred_map.begin(), + choose_const_pmap( + get_param(params, vertex_index), g, vertex_index), + pred_map[0])), + choose_const_pmap(get_param(params, edge_weight), g, edge_weight)); +} +} // namespace boost #endif // BOOST_GRAPH_MST_KRUSKAL_HPP - diff --git a/include/boost/graph/labeled_graph.hpp b/include/boost/graph/labeled_graph.hpp index 59df0feb8..09321a367 100644 --- a/include/boost/graph/labeled_graph.hpp +++ b/include/boost/graph/labeled_graph.hpp @@ -19,34 +19,37 @@ #include #include #include +#include // This file implements a utility for creating mappings from arbitrary // identifiers to the vertices of a graph. -namespace boost { +namespace boost +{ // A type selector that denotes the use of some default value. -struct defaultS { }; +struct defaultS +{ +}; /** @internal */ -namespace graph_detail { +namespace graph_detail +{ /** Returns true if the selector is the default selector. */ - template - struct is_default - : mpl::bool_::value> - { }; + template < typename Selector > + struct is_default : mpl::bool_< is_same< Selector, defaultS >::value > + { + }; /** * Choose the default map instance. If Label is an unsigned integral type * the we can use a vector to store the information. */ - template - struct choose_default_map { - typedef typename mpl::if_< - is_unsigned

    > { + template < typename P > struct extract_lg_tag + { typedef P type; }; - template struct extract_lg_tag< global_property

    > { + template < typename P > struct extract_lg_tag< local_property< P > > + { + typedef P type; + }; + template < typename P > struct extract_lg_tag< global_property< P > > + { typedef P type; }; // NOTE: Mysterious Property template parameter unused in both metafunction // classes. - struct subgraph_global_pmap { - template - struct bind_ { + struct subgraph_global_pmap + { + template < class Tag, class SubGraph, class Property > struct bind_ + { typedef typename SubGraph::graph_type Graph; typedef SubGraph* SubGraphPtr; typedef const SubGraph* const_SubGraphPtr; - typedef typename extract_lg_tag::type TagType; - typedef typename property_map::type PMap; - typedef typename property_map::const_type const_PMap; + typedef typename extract_lg_tag< Tag >::type TagType; + typedef typename property_map< Graph, TagType >::type PMap; + typedef + typename property_map< Graph, TagType >::const_type const_PMap; + public: - typedef subgraph_global_property_map type; - typedef subgraph_global_property_map - const_type; + typedef subgraph_global_property_map< SubGraphPtr, PMap, TagType > + type; + typedef subgraph_global_property_map< const_SubGraphPtr, const_PMap, + TagType > + const_type; }; }; - struct subgraph_local_pmap { - template - struct bind_ { + struct subgraph_local_pmap + { + template < class Tag, class SubGraph, class Property > struct bind_ + { typedef typename SubGraph::graph_type Graph; typedef SubGraph* SubGraphPtr; typedef const SubGraph* const_SubGraphPtr; - typedef typename extract_lg_tag::type TagType; - typedef typename property_map::type PMap; - typedef typename property_map::const_type const_PMap; + typedef typename extract_lg_tag< Tag >::type TagType; + typedef typename property_map< Graph, TagType >::type PMap; + typedef + typename property_map< Graph, TagType >::const_type const_PMap; + public: - typedef subgraph_local_property_map type; - typedef subgraph_local_property_map - const_type; + typedef subgraph_local_property_map< SubGraphPtr, PMap, TagType > + type; + typedef subgraph_local_property_map< const_SubGraphPtr, const_PMap, + TagType > + const_type; }; }; @@ -909,99 +1009,108 @@ namespace detail { // are used by the choose_pmap metafunction below to specialize the choice // of local/global property map. By default, we defer to the global // property. - template - struct subgraph_choose_pmap_helper { + template < class Tag > struct subgraph_choose_pmap_helper + { typedef subgraph_global_pmap type; }; - template - struct subgraph_choose_pmap_helper< local_property > { + template < class Tag > + struct subgraph_choose_pmap_helper< local_property< Tag > > + { typedef subgraph_local_pmap type; }; - template - struct subgraph_choose_pmap_helper< global_property > { + template < class Tag > + struct subgraph_choose_pmap_helper< global_property< Tag > > + { typedef subgraph_global_pmap type; }; // As above, unless we're requesting vertex_index_t. Then it's always a // local property map. This enables the correct translation of descriptors // between local and global layers. - template <> - struct subgraph_choose_pmap_helper { + template <> struct subgraph_choose_pmap_helper< vertex_index_t > + { typedef subgraph_local_pmap type; }; template <> - struct subgraph_choose_pmap_helper< local_property > { + struct subgraph_choose_pmap_helper< local_property< vertex_index_t > > + { typedef subgraph_local_pmap type; }; template <> - struct subgraph_choose_pmap_helper< global_property > { + struct subgraph_choose_pmap_helper< global_property< vertex_index_t > > + { typedef subgraph_local_pmap type; }; // Determine the kind of property. If SameType, then // the property lookup is always local. Otherwise, the lookup is global. // NOTE: Property parameter is basically unused. - template - struct subgraph_choose_pmap { - typedef typename subgraph_choose_pmap_helper::type Helper; - typedef typename Helper::template bind_ Bind; + template < class Tag, class Graph, class Property > + struct subgraph_choose_pmap + { + typedef typename subgraph_choose_pmap_helper< Tag >::type Helper; + typedef typename Helper::template bind_< Tag, Graph, Property > Bind; typedef typename Bind::type type; typedef typename Bind::const_type const_type; }; // Used by the vertex/edge property selectors to determine the kind(s) of // property maps used by the property_map type generator. - struct subgraph_property_generator { - template - struct bind_ { - typedef subgraph_choose_pmap Choice; + struct subgraph_property_generator + { + template < class SubGraph, class Property, class Tag > struct bind_ + { + typedef subgraph_choose_pmap< Tag, SubGraph, Property > Choice; typedef typename Choice::type type; typedef typename Choice::const_type const_type; }; }; - } // namespace detail +} // namespace detail -template <> -struct vertex_property_selector { +template <> struct vertex_property_selector< subgraph_tag > +{ typedef detail::subgraph_property_generator type; }; -template <> -struct edge_property_selector { +template <> struct edge_property_selector< subgraph_tag > +{ typedef detail::subgraph_property_generator type; }; // ================================================== // get(p, g), get(p, g, k), and put(p, g, k, v) // ================================================== -template -typename property_map, Property>::type -get(Property p, subgraph& g) { - typedef typename property_map< subgraph, Property>::type PMap; +template < typename G, typename Property > +typename property_map< subgraph< G >, Property >::type get( + Property p, subgraph< G >& g) +{ + typedef typename property_map< subgraph< G >, Property >::type PMap; return PMap(&g, p); } -template -typename property_map, Property>::const_type -get(Property p, const subgraph& g) { - typedef typename property_map< subgraph, Property>::const_type PMap; +template < typename G, typename Property > +typename property_map< subgraph< G >, Property >::const_type get( + Property p, const subgraph< G >& g) +{ + typedef typename property_map< subgraph< G >, Property >::const_type PMap; return PMap(&g, p); } -template +template < typename G, typename Property, typename Key > typename property_traits< - typename property_map, Property>::const_type ->::value_type -get(Property p, const subgraph& g, const Key& k) { - typedef typename property_map< subgraph, Property>::const_type PMap; + typename property_map< subgraph< G >, Property >::const_type >::value_type +get(Property p, const subgraph< G >& g, const Key& k) +{ + typedef typename property_map< subgraph< G >, Property >::const_type PMap; PMap pmap(&g, p); return pmap[k]; } -template -void put(Property p, subgraph& g, const Key& k, const Value& val) { - typedef typename property_map< subgraph, Property>::type PMap; +template < typename G, typename Property, typename Key, typename Value > +void put(Property p, subgraph< G >& g, const Key& k, const Value& val) +{ + typedef typename property_map< subgraph< G >, Property >::type PMap; PMap pmap(&g, p); pmap[k] = val; } @@ -1010,21 +1119,21 @@ void put(Property p, subgraph& g, const Key& k, const Value& val) { // get(global(p), g) // NOTE: get(global(p), g, k) and put(global(p), g, k, v) not supported // ================================================== -template -typename property_map, global_property >::type -get(global_property p, subgraph& g) { - typedef typename property_map< - subgraph, global_property - >::type Map; +template < typename G, typename Property > +typename property_map< subgraph< G >, global_property< Property > >::type get( + global_property< Property > p, subgraph< G >& g) +{ + typedef typename property_map< subgraph< G >, + global_property< Property > >::type Map; return Map(&g, p.value); } -template -typename property_map, global_property >::const_type -get(global_property p, const subgraph& g) { - typedef typename property_map< - subgraph, global_property - >::const_type Map; +template < typename G, typename Property > +typename property_map< subgraph< G >, global_property< Property > >::const_type +get(global_property< Property > p, const subgraph< G >& g) +{ + typedef typename property_map< subgraph< G >, + global_property< Property > >::const_type Map; return Map(&g, p.value); } @@ -1032,51 +1141,56 @@ get(global_property p, const subgraph& g) { // get(local(p), g) // NOTE: get(local(p), g, k) and put(local(p), g, k, v) not supported // ================================================== -template -typename property_map, local_property >::type -get(local_property p, subgraph& g) { - typedef typename property_map< - subgraph, local_property - >::type Map; +template < typename G, typename Property > +typename property_map< subgraph< G >, local_property< Property > >::type get( + local_property< Property > p, subgraph< G >& g) +{ + typedef + typename property_map< subgraph< G >, local_property< Property > >::type + Map; return Map(&g, p.value); } -template -typename property_map, local_property >::const_type -get(local_property p, const subgraph& g) { - typedef typename property_map< - subgraph, local_property - >::const_type Map; +template < typename G, typename Property > +typename property_map< subgraph< G >, local_property< Property > >::const_type +get(local_property< Property > p, const subgraph< G >& g) +{ + typedef typename property_map< subgraph< G >, + local_property< Property > >::const_type Map; return Map(&g, p.value); } -template -inline typename graph_property::type& -get_property(subgraph& g, Tag tag) { +template < typename G, typename Tag > +inline typename graph_property< G, Tag >::type& get_property( + subgraph< G >& g, Tag tag) +{ return get_property(g.m_graph, tag); } -template -inline const typename graph_property::type& -get_property(const subgraph& g, Tag tag) { +template < typename G, typename Tag > +inline const typename graph_property< G, Tag >::type& get_property( + const subgraph< G >& g, Tag tag) +{ return get_property(g.m_graph, tag); } //=========================================================================== // Miscellaneous Functions -template -typename subgraph::vertex_descriptor -vertex(typename subgraph::vertices_size_type n, const subgraph& g) -{ return vertex(n, g.m_graph); } +template < typename G > +typename subgraph< G >::vertex_descriptor vertex( + typename subgraph< G >::vertices_size_type n, const subgraph< G >& g) +{ + return vertex(n, g.m_graph); +} //=========================================================================== // Mutability Traits // Just pull the mutability traits form the underlying graph. Note that this // will probably fail (badly) for labeled graphs. -template -struct graph_mutability_traits< subgraph > { - typedef typename graph_mutability_traits::category category; +template < typename G > struct graph_mutability_traits< subgraph< G > > +{ + typedef typename graph_mutability_traits< G >::category category; }; } // namespace boost diff --git a/include/boost/graph/successive_shortest_path_nonnegative_weights.hpp b/include/boost/graph/successive_shortest_path_nonnegative_weights.hpp index 6a3aeb168..8e1f5ad94 100644 --- a/include/boost/graph/successive_shortest_path_nonnegative_weights.hpp +++ b/include/boost/graph/successive_shortest_path_nonnegative_weights.hpp @@ -7,7 +7,8 @@ // http://www.boost.org/LICENSE_1_0.txt) //======================================================================= // -//This algorithm is described in "Network Flows: Theory, Algorithms, and Applications" +// This algorithm is described in "Network Flows: Theory, Algorithms, and +// Applications" // by Ahuja, Magnanti, Orlin. #ifndef BOOST_GRAPH_SUCCESSIVE_SHORTEST_PATH_HPP @@ -24,82 +25,90 @@ #include #include -namespace boost { - - -namespace detail { +namespace boost +{ + +namespace detail +{ + + template < class Graph, class Weight, class Distance, class Reversed > + class MapReducedWeight + : public put_get_helper< typename property_traits< Weight >::value_type, + MapReducedWeight< Graph, Weight, Distance, Reversed > > + { + typedef graph_traits< Graph > gtraits; + + public: + typedef boost::readable_property_map_tag category; + typedef typename property_traits< Weight >::value_type value_type; + typedef value_type reference; + typedef typename gtraits::edge_descriptor key_type; + MapReducedWeight(const Graph& g, Weight w, Distance d, Reversed r) + : g_(g), weight_(w), distance_(d), rev_(r) + { + } -template -class MapReducedWeight : - public put_get_helper::value_type, MapReducedWeight > { - typedef graph_traits gtraits; -public: - typedef boost::readable_property_map_tag category; - typedef typename property_traits::value_type value_type; - typedef value_type reference; - typedef typename gtraits::edge_descriptor key_type; - MapReducedWeight(const Graph & g, Weight w, Distance d, Reversed r) : - g_(g), weight_(w), distance_(d), rev_(r) {} + reference operator[](key_type v) const + { + return get(distance_, source(v, g_)) - get(distance_, target(v, g_)) + + get(weight_, v); + } - reference operator[](key_type v) const { - return get(distance_, source(v, g_)) - get(distance_,target(v, g_)) + get(weight_, v); + private: + const Graph& g_; + Weight weight_; + Distance distance_; + Reversed rev_; + }; + + template < class Graph, class Weight, class Distance, class Reversed > + MapReducedWeight< Graph, Weight, Distance, Reversed > make_mapReducedWeight( + const Graph& g, Weight w, Distance d, Reversed r) + { + return MapReducedWeight< Graph, Weight, Distance, Reversed >( + g, w, d, r); } -private: - const Graph & g_; - Weight weight_; - Distance distance_; - Reversed rev_; -}; - -template -MapReducedWeight -make_mapReducedWeight(const Graph & g, Weight w, Distance d, Reversed r) { - return MapReducedWeight(g, w, d, r); -} -}//detail - - -template -void successive_shortest_path_nonnegative_weights( - const Graph &g, - typename graph_traits::vertex_descriptor s, - typename graph_traits::vertex_descriptor t, - Capacity capacity, - ResidualCapacity residual_capacity, - Weight weight, - Reversed rev, - VertexIndex index, - Pred pred, - Distance distance, - Distance2 distance_prev) { - filtered_graph > - gres = detail::residual_graph(g, residual_capacity); - typedef typename graph_traits::edge_descriptor edge_descriptor; - - BGL_FORALL_EDGES_T(e, g, Graph) { +} // detail + +template < class Graph, class Capacity, class ResidualCapacity, class Reversed, + class Pred, class Weight, class Distance, class Distance2, + class VertexIndex > +void successive_shortest_path_nonnegative_weights(const Graph& g, + typename graph_traits< Graph >::vertex_descriptor s, + typename graph_traits< Graph >::vertex_descriptor t, Capacity capacity, + ResidualCapacity residual_capacity, Weight weight, Reversed rev, + VertexIndex index, Pred pred, Distance distance, Distance2 distance_prev) +{ + filtered_graph< const Graph, is_residual_edge< ResidualCapacity > > gres + = detail::residual_graph(g, residual_capacity); + typedef typename graph_traits< Graph >::edge_descriptor edge_descriptor; + + BGL_FORALL_EDGES_T(e, g, Graph) + { put(residual_capacity, e, get(capacity, e)); } - BGL_FORALL_VERTICES_T(v, g, Graph) { - put(distance_prev, v, 0); - } + BGL_FORALL_VERTICES_T(v, g, Graph) { put(distance_prev, v, 0); } - while(true) { - BGL_FORALL_VERTICES_T(v, g, Graph) { - put(pred, v, edge_descriptor()); - } + while (true) + { + BGL_FORALL_VERTICES_T(v, g, Graph) { put(pred, v, edge_descriptor()); } dijkstra_shortest_paths(gres, s, - weight_map(detail::make_mapReducedWeight(gres, weight, distance_prev, rev)). - distance_map(distance). - vertex_index_map(index). - visitor(make_dijkstra_visitor(record_edge_predecessors(pred, on_edge_relaxed())))); - - if(get(pred, t) == edge_descriptor()) { + weight_map( + detail::make_mapReducedWeight(gres, weight, distance_prev, rev)) + .distance_map(distance) + .vertex_index_map(index) + .visitor(make_dijkstra_visitor( + record_edge_predecessors(pred, on_edge_relaxed())))); + + if (get(pred, t) == edge_descriptor()) + { break; } - BGL_FORALL_VERTICES_T(v, g, Graph) { + BGL_FORALL_VERTICES_T(v, g, Graph) + { put(distance_prev, v, get(distance_prev, v) + get(distance, v)); } @@ -107,153 +116,140 @@ void successive_shortest_path_nonnegative_weights( } } -//in this namespace argument dispatching tak place -namespace detail { - -template -void successive_shortest_path_nonnegative_weights_dispatch3( - const Graph &g, - typename graph_traits::vertex_descriptor s, - typename graph_traits::vertex_descriptor t, - Capacity capacity, - ResidualCapacity residual_capacity, - Weight weight, - Reversed rev, - VertexIndex index, - Pred pred, - Distance dist, - Distance2 dist_pred) { - successive_shortest_path_nonnegative_weights(g, s, t, capacity, residual_capacity, weight, rev, index, pred, dist, dist_pred); -} +// in this namespace argument dispatching tak place +namespace detail +{ + + template < class Graph, class Capacity, class ResidualCapacity, + class Weight, class Reversed, class Pred, class Distance, + class Distance2, class VertexIndex > + void successive_shortest_path_nonnegative_weights_dispatch3(const Graph& g, + typename graph_traits< Graph >::vertex_descriptor s, + typename graph_traits< Graph >::vertex_descriptor t, Capacity capacity, + ResidualCapacity residual_capacity, Weight weight, Reversed rev, + VertexIndex index, Pred pred, Distance dist, Distance2 dist_pred) + { + successive_shortest_path_nonnegative_weights(g, s, t, capacity, + residual_capacity, weight, rev, index, pred, dist, dist_pred); + } -//setting default distance map -template -void successive_shortest_path_nonnegative_weights_dispatch3( - Graph &g, - typename graph_traits::vertex_descriptor s, - typename graph_traits::vertex_descriptor t, - Capacity capacity, - ResidualCapacity residual_capacity, - Weight weight, - Reversed rev, - VertexIndex index, - Pred pred, - Distance dist, - param_not_found) { - typedef typename property_traits::value_type D; - - std::vector d_map(num_vertices(g)); - - successive_shortest_path_nonnegative_weights(g, s, t, capacity, residual_capacity, weight, rev, index, pred, dist, - make_iterator_property_map(d_map.begin(), index)); -} + // setting default distance map + template < class Graph, class Capacity, class ResidualCapacity, + class Weight, class Reversed, class Pred, class Distance, + class VertexIndex > + void successive_shortest_path_nonnegative_weights_dispatch3(Graph& g, + typename graph_traits< Graph >::vertex_descriptor s, + typename graph_traits< Graph >::vertex_descriptor t, Capacity capacity, + ResidualCapacity residual_capacity, Weight weight, Reversed rev, + VertexIndex index, Pred pred, Distance dist, param_not_found) + { + typedef typename property_traits< Weight >::value_type D; + + std::vector< D > d_map(num_vertices(g)); + + successive_shortest_path_nonnegative_weights(g, s, t, capacity, + residual_capacity, weight, rev, index, pred, dist, + make_iterator_property_map(d_map.begin(), index)); + } -template -void successive_shortest_path_nonnegative_weights_dispatch2( - Graph &g, - typename graph_traits::vertex_descriptor s, - typename graph_traits::vertex_descriptor t, - Capacity capacity, - ResidualCapacity residual_capacity, - Weight weight, - Reversed rev, - VertexIndex index, - Pred pred, - Distance dist, - const bgl_named_params& params) { - successive_shortest_path_nonnegative_weights_dispatch3(g, s, t, capacity, residual_capacity, weight, rev, index, pred, dist, get_param(params, vertex_distance2)); -} + template < class Graph, class P, class T, class R, class Capacity, + class ResidualCapacity, class Weight, class Reversed, class Pred, + class Distance, class VertexIndex > + void successive_shortest_path_nonnegative_weights_dispatch2(Graph& g, + typename graph_traits< Graph >::vertex_descriptor s, + typename graph_traits< Graph >::vertex_descriptor t, Capacity capacity, + ResidualCapacity residual_capacity, Weight weight, Reversed rev, + VertexIndex index, Pred pred, Distance dist, + const bgl_named_params< P, T, R >& params) + { + successive_shortest_path_nonnegative_weights_dispatch3(g, s, t, + capacity, residual_capacity, weight, rev, index, pred, dist, + get_param(params, vertex_distance2)); + } -//setting default distance map -template -void successive_shortest_path_nonnegative_weights_dispatch2( - Graph &g, - typename graph_traits::vertex_descriptor s, - typename graph_traits::vertex_descriptor t, - Capacity capacity, - ResidualCapacity residual_capacity, - Weight weight, - Reversed rev, - VertexIndex index, - Pred pred, - param_not_found, - const bgl_named_params& params) { - typedef typename property_traits::value_type D; - - std::vector d_map(num_vertices(g)); - - successive_shortest_path_nonnegative_weights_dispatch3(g, s, t, capacity, residual_capacity, weight, rev, index, pred, + // setting default distance map + template < class Graph, class P, class T, class R, class Capacity, + class ResidualCapacity, class Weight, class Reversed, class Pred, + class VertexIndex > + void successive_shortest_path_nonnegative_weights_dispatch2(Graph& g, + typename graph_traits< Graph >::vertex_descriptor s, + typename graph_traits< Graph >::vertex_descriptor t, Capacity capacity, + ResidualCapacity residual_capacity, Weight weight, Reversed rev, + VertexIndex index, Pred pred, param_not_found, + const bgl_named_params< P, T, R >& params) + { + typedef typename property_traits< Weight >::value_type D; + + std::vector< D > d_map(num_vertices(g)); + + successive_shortest_path_nonnegative_weights_dispatch3(g, s, t, + capacity, residual_capacity, weight, rev, index, pred, make_iterator_property_map(d_map.begin(), index), get_param(params, vertex_distance2)); -} + } -template -void successive_shortest_path_nonnegative_weights_dispatch1( - Graph &g, - typename graph_traits::vertex_descriptor s, - typename graph_traits::vertex_descriptor t, - Capacity capacity, - ResidualCapacity residual_capacity, - Weight weight, - Reversed rev, - VertexIndex index, - Pred pred, - const bgl_named_params& params) { - successive_shortest_path_nonnegative_weights_dispatch2(g, s, t, capacity, residual_capacity, weight, rev, index, pred, - get_param(params, vertex_distance), params); -} + template < class Graph, class P, class T, class R, class Capacity, + class ResidualCapacity, class Weight, class Reversed, class Pred, + class VertexIndex > + void successive_shortest_path_nonnegative_weights_dispatch1(Graph& g, + typename graph_traits< Graph >::vertex_descriptor s, + typename graph_traits< Graph >::vertex_descriptor t, Capacity capacity, + ResidualCapacity residual_capacity, Weight weight, Reversed rev, + VertexIndex index, Pred pred, const bgl_named_params< P, T, R >& params) + { + successive_shortest_path_nonnegative_weights_dispatch2(g, s, t, + capacity, residual_capacity, weight, rev, index, pred, + get_param(params, vertex_distance), params); + } -//setting default predecessors map -template -void successive_shortest_path_nonnegative_weights_dispatch1( - Graph &g, - typename graph_traits::vertex_descriptor s, - typename graph_traits::vertex_descriptor t, - Capacity capacity, - ResidualCapacity residual_capacity, - Weight weight, - Reversed rev, - VertexIndex index, - param_not_found, - const bgl_named_params& params) { - typedef typename graph_traits::edge_descriptor edge_descriptor; - std::vector pred_vec(num_vertices(g)); - - successive_shortest_path_nonnegative_weights_dispatch2(g, s, t, capacity, residual_capacity, weight, rev, index, + // setting default predecessors map + template < class Graph, class P, class T, class R, class Capacity, + class ResidualCapacity, class Weight, class Reversed, + class VertexIndex > + void successive_shortest_path_nonnegative_weights_dispatch1(Graph& g, + typename graph_traits< Graph >::vertex_descriptor s, + typename graph_traits< Graph >::vertex_descriptor t, Capacity capacity, + ResidualCapacity residual_capacity, Weight weight, Reversed rev, + VertexIndex index, param_not_found, + const bgl_named_params< P, T, R >& params) + { + typedef typename graph_traits< Graph >::edge_descriptor edge_descriptor; + std::vector< edge_descriptor > pred_vec(num_vertices(g)); + + successive_shortest_path_nonnegative_weights_dispatch2(g, s, t, + capacity, residual_capacity, weight, rev, index, make_iterator_property_map(pred_vec.begin(), index), get_param(params, vertex_distance), params); -} + } -}//detail - - -template -void successive_shortest_path_nonnegative_weights( - Graph &g, - typename graph_traits::vertex_descriptor s, - typename graph_traits::vertex_descriptor t, - const bgl_named_params& params) { - - return detail::successive_shortest_path_nonnegative_weights_dispatch1(g, s, t, - choose_const_pmap(get_param(params, edge_capacity), g, edge_capacity), - choose_pmap(get_param(params, edge_residual_capacity), - g, edge_residual_capacity), - choose_const_pmap(get_param(params, edge_weight), g, edge_weight), - choose_const_pmap(get_param(params, edge_reverse), g, edge_reverse), - choose_const_pmap(get_param(params, vertex_index), g, vertex_index), - get_param(params, vertex_predecessor), - params); +} // detail + +template < class Graph, class P, class T, class R > +void successive_shortest_path_nonnegative_weights(Graph& g, + typename graph_traits< Graph >::vertex_descriptor s, + typename graph_traits< Graph >::vertex_descriptor t, + const bgl_named_params< P, T, R >& params) +{ + + return detail::successive_shortest_path_nonnegative_weights_dispatch1(g, s, + t, + choose_const_pmap(get_param(params, edge_capacity), g, edge_capacity), + choose_pmap(get_param(params, edge_residual_capacity), g, + edge_residual_capacity), + choose_const_pmap(get_param(params, edge_weight), g, edge_weight), + choose_const_pmap(get_param(params, edge_reverse), g, edge_reverse), + choose_const_pmap(get_param(params, vertex_index), g, vertex_index), + get_param(params, vertex_predecessor), params); } -template -void successive_shortest_path_nonnegative_weights( - Graph &g, - typename graph_traits::vertex_descriptor s, - typename graph_traits::vertex_descriptor t) { - bgl_named_params params(0); +template < class Graph > +void successive_shortest_path_nonnegative_weights(Graph& g, + typename graph_traits< Graph >::vertex_descriptor s, + typename graph_traits< Graph >::vertex_descriptor t) +{ + bgl_named_params< int, buffer_param_t > params(0); successive_shortest_path_nonnegative_weights(g, s, t, params); } - -}//boost +} // boost #endif /* BOOST_GRAPH_SUCCESSIVE_SHORTEST_PATH_HPP */ diff --git a/include/boost/graph/tiernan_all_cycles.hpp b/include/boost/graph/tiernan_all_cycles.hpp index d4527d552..c24c87553 100644 --- a/include/boost/graph/tiernan_all_cycles.hpp +++ b/include/boost/graph/tiernan_all_cycles.hpp @@ -16,25 +16,24 @@ #include #include -namespace boost { - namespace concepts { - BOOST_concept(CycleVisitor,(Visitor)(Path)(Graph)) - { - BOOST_CONCEPT_USAGE(CycleVisitor) - { - vis.cycle(p, g); - } - private: - Visitor vis; - Graph g; - Path p; - }; - } /* namespace concepts */ +namespace boost +{ +namespace concepts +{ + BOOST_concept(CycleVisitor, (Visitor)(Path)(Graph)) + { + BOOST_CONCEPT_USAGE(CycleVisitor) { vis.cycle(p, g); } + + private: + Visitor vis; + Graph g; + Path p; + }; +} /* namespace concepts */ using concepts::CycleVisitorConcept; } /* namespace boost */ #include - namespace boost { @@ -43,43 +42,35 @@ namespace boost // // @article{362819, // author = {James C. Tiernan}, -// title = {An efficient search algorithm to find the elementary circuits of a graph}, -// journal = {Commun. ACM}, -// volume = {13}, -// number = {12}, -// year = {1970}, -// issn = {0001-0782}, -// pages = {722--726}, -// doi = {http://doi.acm.org/10.1145/362814.362819}, +// title = {An efficient search algorithm to find the elementary +// circuits of a graph}, journal = {Commun. ACM}, volume = {13}, number +// = {12}, year = {1970}, issn = {0001-0782}, pages = {722--726}, doi = +// {http://doi.acm.org/10.1145/362814.362819}, // publisher = {ACM Press}, // address = {New York, NY, USA}, // } // -// It should be pointed out that the author does not provide a complete analysis for -// either time or space. This is in part, due to the fact that it's a fairly input -// sensitive problem related to the density and construction of the graph, not just -// its size. +// It should be pointed out that the author does not provide a complete analysis +// for either time or space. This is in part, due to the fact that it's a fairly +// input sensitive problem related to the density and construction of the graph, +// not just its size. // -// I've also taken some liberties with the interpretation of the algorithm - I've -// basically modernized it to use real data structures (no more arrays and matrices). -// Oh... and there's explicit control structures - not just gotos. +// I've also taken some liberties with the interpretation of the algorithm - +// I've basically modernized it to use real data structures (no more arrays and +// matrices). Oh... and there's explicit control structures - not just gotos. // // The problem is definitely NP-complete, an unbounded implementation of this // will probably run for quite a while on a large graph. The conclusions // of this paper also reference a Paton algorithm for undirected graphs as being -// much more efficient (apparently based on spanning trees). Although not implemented, -// it can be found here: +// much more efficient (apparently based on spanning trees). Although not +// implemented, it can be found here: // // @article{363232, // author = {Keith Paton}, -// title = {An algorithm for finding a fundamental set of cycles of a graph}, -// journal = {Commun. ACM}, -// volume = {12}, -// number = {9}, -// year = {1969}, -// issn = {0001-0782}, -// pages = {514--518}, -// doi = {http://doi.acm.org/10.1145/363219.363232}, +// title = {An algorithm for finding a fundamental set of cycles of a +// graph}, journal = {Commun. ACM}, volume = {12}, number = {9}, year = +// {1969}, issn = {0001-0782}, pages = {514--518}, doi = +// {http://doi.acm.org/10.1145/363219.363232}, // publisher = {ACM Press}, // address = {New York, NY, USA}, // } @@ -90,9 +81,10 @@ namespace boost */ struct cycle_visitor { - template + template < typename Path, typename Graph > inline void cycle(const Path& p, const Graph& g) - { } + { + } }; /** @@ -102,69 +94,66 @@ struct cycle_visitor struct min_max_cycle_visitor { min_max_cycle_visitor(std::size_t& min_, std::size_t& max_) - : minimum(min_), maximum(max_) - { } + : minimum(min_), maximum(max_) + { + } - template + template < typename Path, typename Graph > inline void cycle(const Path& p, const Graph& g) { BOOST_USING_STD_MIN(); BOOST_USING_STD_MAX(); std::size_t len = p.size(); - minimum = min BOOST_PREVENT_MACRO_SUBSTITUTION (minimum, len); - maximum = max BOOST_PREVENT_MACRO_SUBSTITUTION (maximum, len); + minimum = min BOOST_PREVENT_MACRO_SUBSTITUTION(minimum, len); + maximum = max BOOST_PREVENT_MACRO_SUBSTITUTION(maximum, len); } std::size_t& minimum; std::size_t& maximum; }; -inline min_max_cycle_visitor -find_min_max_cycle(std::size_t& min_, std::size_t& max_) -{ return min_max_cycle_visitor(min_, max_); } +inline min_max_cycle_visitor find_min_max_cycle( + std::size_t& min_, std::size_t& max_) +{ + return min_max_cycle_visitor(min_, max_); +} namespace detail { - template - inline bool - is_vertex_in_path(const Graph&, - typename graph_traits::vertex_descriptor v, - const Path& p) + template < typename Graph, typename Path > + inline bool is_vertex_in_path(const Graph&, + typename graph_traits< Graph >::vertex_descriptor v, const Path& p) { return (std::find(p.begin(), p.end(), v) != p.end()); } - template - inline bool - is_path_closed(const Graph& g, - typename graph_traits::vertex_descriptor u, - typename graph_traits::vertex_descriptor v, - const ClosedMatrix& closed) + template < typename Graph, typename ClosedMatrix > + inline bool is_path_closed(const Graph& g, + typename graph_traits< Graph >::vertex_descriptor u, + typename graph_traits< Graph >::vertex_descriptor v, + const ClosedMatrix& closed) { // the path from u to v is closed if v can be found in the list // of closed vertices associated with u. typedef typename ClosedMatrix::const_reference Row; Row r = closed[get(vertex_index, g, u)]; - if(find(r.begin(), r.end(), v) != r.end()) { + if (find(r.begin(), r.end(), v) != r.end()) + { return true; } return false; } - template - inline bool - can_extend_path(const Graph& g, - typename graph_traits::edge_descriptor e, - const Path& p, - const ClosedMatrix& m) + template < typename Graph, typename Path, typename ClosedMatrix > + inline bool can_extend_path(const Graph& g, + typename graph_traits< Graph >::edge_descriptor e, const Path& p, + const ClosedMatrix& m) { - BOOST_CONCEPT_ASSERT(( IncidenceGraphConcept )); - BOOST_CONCEPT_ASSERT(( VertexIndexGraphConcept )); - typedef typename graph_traits::vertex_descriptor Vertex; + BOOST_CONCEPT_ASSERT((IncidenceGraphConcept< Graph >)); + BOOST_CONCEPT_ASSERT((VertexIndexGraphConcept< Graph >)); + typedef typename graph_traits< Graph >::vertex_descriptor Vertex; // get the vertices in question - Vertex - u = source(e, g), - v = target(e, g); + Vertex u = source(e, g), v = target(e, g); // conditions for allowing a traversal along this edge are: // 1. the index of v must be greater than that at which the @@ -172,61 +161,59 @@ namespace detail // 2. the vertex v cannot already be in the path // 3. the vertex v cannot be closed to the vertex u - bool indices = get(vertex_index, g, p.front()) < get(vertex_index, g, v); + bool indices + = get(vertex_index, g, p.front()) < get(vertex_index, g, v); bool path = !is_vertex_in_path(g, v, p); bool closed = !is_path_closed(g, u, v, m); return indices && path && closed; } - template - inline bool - can_wrap_path(const Graph& g, const Path& p) + template < typename Graph, typename Path > + inline bool can_wrap_path(const Graph& g, const Path& p) { - BOOST_CONCEPT_ASSERT(( IncidenceGraphConcept )); - typedef typename graph_traits::vertex_descriptor Vertex; - typedef typename graph_traits::out_edge_iterator OutIterator; + BOOST_CONCEPT_ASSERT((IncidenceGraphConcept< Graph >)); + typedef typename graph_traits< Graph >::vertex_descriptor Vertex; + typedef typename graph_traits< Graph >::out_edge_iterator OutIterator; // iterate over the out-edges of the back, looking for the // front of the path. also, we can't travel along the same // edge that we did on the way here, but we don't quite have the // stringent requirements that we do in can_extend_path(). - Vertex - u = p.back(), - v = p.front(); + Vertex u = p.back(), v = p.front(); OutIterator i, end; - for(boost::tie(i, end) = out_edges(u, g); i != end; ++i) { - if((target(*i, g) == v)) { + for (boost::tie(i, end) = out_edges(u, g); i != end; ++i) + { + if ((target(*i, g) == v)) + { return true; } } return false; } - template - inline typename graph_traits::vertex_descriptor - extend_path(const Graph& g, - Path& p, - ClosedMatrix& closed) + template < typename Graph, typename Path, typename ClosedMatrix > + inline typename graph_traits< Graph >::vertex_descriptor extend_path( + const Graph& g, Path& p, ClosedMatrix& closed) { - BOOST_CONCEPT_ASSERT(( IncidenceGraphConcept )); - typedef typename graph_traits::vertex_descriptor Vertex; - typedef typename graph_traits::out_edge_iterator OutIterator; + BOOST_CONCEPT_ASSERT((IncidenceGraphConcept< Graph >)); + typedef typename graph_traits< Graph >::vertex_descriptor Vertex; + typedef typename graph_traits< Graph >::out_edge_iterator OutIterator; // get the current vertex Vertex u = p.back(); - Vertex ret = graph_traits::null_vertex(); + Vertex ret = graph_traits< Graph >::null_vertex(); // AdjacencyIterator i, end; OutIterator i, end; - for(boost::tie(i, end) = out_edges(u, g); i != end; ++i) { + for (boost::tie(i, end) = out_edges(u, g); i != end; ++i) + { Vertex v = target(*i, g); // if we can actually extend along this edge, // then that's what we want to do - if(can_extend_path(g, *i, p, closed)) { - p.push_back(v); // add the vertex to the path + if (can_extend_path(g, *i, p, closed)) + { + p.push_back(v); // add the vertex to the path ret = v; break; } @@ -234,17 +221,17 @@ namespace detail return ret; } - template - inline bool - exhaust_paths(const Graph& g, Path& p, ClosedMatrix& closed) + template < typename Graph, typename Path, typename ClosedMatrix > + inline bool exhaust_paths(const Graph& g, Path& p, ClosedMatrix& closed) { - BOOST_CONCEPT_ASSERT(( GraphConcept )); - typedef typename graph_traits::vertex_descriptor Vertex; + BOOST_CONCEPT_ASSERT((GraphConcept< Graph >)); + typedef typename graph_traits< Graph >::vertex_descriptor Vertex; // if there's more than one vertex in the path, this closes // of some possible routes and returns true. otherwise, if there's // only one vertex left, the vertex has been used up - if(p.size() > 1) { + if (p.size() > 1) + { // get the last and second to last vertices, popping the last // vertex off the path Vertex last, prev; @@ -259,49 +246,50 @@ namespace detail closed[get(vertex_index, g, prev)].push_back(last); return true; } - else { + else + { return false; } } - template - inline void - all_cycles_from_vertex(const Graph& g, - typename graph_traits::vertex_descriptor v, - Visitor vis, - std::size_t minlen, - std::size_t maxlen) + template < typename Graph, typename Visitor > + inline void all_cycles_from_vertex(const Graph& g, + typename graph_traits< Graph >::vertex_descriptor v, Visitor vis, + std::size_t minlen, std::size_t maxlen) { - BOOST_CONCEPT_ASSERT(( VertexListGraphConcept )); - typedef typename graph_traits::vertex_descriptor Vertex; - typedef std::vector Path; - BOOST_CONCEPT_ASSERT(( CycleVisitorConcept )); - typedef std::vector VertexList; - typedef std::vector ClosedMatrix; + BOOST_CONCEPT_ASSERT((VertexListGraphConcept< Graph >)); + typedef typename graph_traits< Graph >::vertex_descriptor Vertex; + typedef std::vector< Vertex > Path; + BOOST_CONCEPT_ASSERT((CycleVisitorConcept< Visitor, Path, Graph >)); + typedef std::vector< Vertex > VertexList; + typedef std::vector< VertexList > ClosedMatrix; Path p; ClosedMatrix closed(num_vertices(g), VertexList()); - Vertex null = graph_traits::null_vertex(); + Vertex null = graph_traits< Graph >::null_vertex(); // each path investigation starts at the ith vertex p.push_back(v); - while(1) { + while (1) + { // extend the path until we've reached the end or the // maxlen-sized cycle Vertex j = null; - while(((j = detail::extend_path(g, p, closed)) != null) - && (p.size() < maxlen)) + while (((j = detail::extend_path(g, p, closed)) != null) + && (p.size() < maxlen)) ; // empty loop // if we're done extending the path and there's an edge // connecting the back to the front, then we should have // a cycle. - if(detail::can_wrap_path(g, p) && p.size() >= minlen) { + if (detail::can_wrap_path(g, p) && p.size() >= minlen) + { vis.cycle(p, g); } - if(!detail::exhaust_paths(g, p, closed)) { + if (!detail::exhaust_paths(g, p, closed)) + { break; } } @@ -309,67 +297,75 @@ namespace detail // Select the minimum allowable length of a cycle based on the directedness // of the graph - 2 for directed, 3 for undirected. - template struct min_cycles { enum { value = 2 }; }; - template <> struct min_cycles { enum { value = 3 }; }; + template < typename D > struct min_cycles + { + enum + { + value = 2 + }; + }; + template <> struct min_cycles< undirected_tag > + { + enum + { + value = 3 + }; + }; } /* namespace detail */ -template -inline void -tiernan_all_cycles(const Graph& g, - Visitor vis, - std::size_t minlen, - std::size_t maxlen) +template < typename Graph, typename Visitor > +inline void tiernan_all_cycles( + const Graph& g, Visitor vis, std::size_t minlen, std::size_t maxlen) { - BOOST_CONCEPT_ASSERT(( VertexListGraphConcept )); - typedef typename graph_traits::vertex_iterator VertexIterator; + BOOST_CONCEPT_ASSERT((VertexListGraphConcept< Graph >)); + typedef typename graph_traits< Graph >::vertex_iterator VertexIterator; VertexIterator i, end; - for(boost::tie(i, end) = vertices(g); i != end; ++i) { + for (boost::tie(i, end) = vertices(g); i != end; ++i) + { detail::all_cycles_from_vertex(g, *i, vis, minlen, maxlen); } } -template -inline void -tiernan_all_cycles(const Graph& g, Visitor vis, std::size_t maxlen) +template < typename Graph, typename Visitor > +inline void tiernan_all_cycles(const Graph& g, Visitor vis, std::size_t maxlen) { - typedef typename graph_traits::directed_category Dir; - tiernan_all_cycles(g, vis, detail::min_cycles

    ::value, maxlen); + typedef typename graph_traits< Graph >::directed_category Dir; + tiernan_all_cycles(g, vis, detail::min_cycles< Dir >::value, maxlen); } -template -inline void -tiernan_all_cycles(const Graph& g, Visitor vis) +template < typename Graph, typename Visitor > +inline void tiernan_all_cycles(const Graph& g, Visitor vis) { - typedef typename graph_traits::directed_category Dir; - tiernan_all_cycles(g, vis, detail::min_cycles::value, - (std::numeric_limits::max)()); + typedef typename graph_traits< Graph >::directed_category Dir; + tiernan_all_cycles(g, vis, detail::min_cycles< Dir >::value, + (std::numeric_limits< std::size_t >::max)()); } -template -inline std::pair -tiernan_girth_and_circumference(const Graph& g) +template < typename Graph > +inline std::pair< std::size_t, std::size_t > tiernan_girth_and_circumference( + const Graph& g) { - std::size_t - min_ = (std::numeric_limits::max)(), - max_ = 0; + std::size_t min_ = (std::numeric_limits< std::size_t >::max)(), max_ = 0; tiernan_all_cycles(g, find_min_max_cycle(min_, max_)); // if this is the case, the graph is acyclic... - if(max_ == 0) max_ = min_; + if (max_ == 0) + max_ = min_; return std::make_pair(min_, max_); } -template -inline std::size_t -tiernan_girth(const Graph& g) -{ return tiernan_girth_and_circumference(g).first; } +template < typename Graph > inline std::size_t tiernan_girth(const Graph& g) +{ + return tiernan_girth_and_circumference(g).first; +} -template -inline std::size_t -tiernan_circumference(const Graph& g) -{ return tiernan_girth_and_circumference(g).second; } +template < typename Graph > +inline std::size_t tiernan_circumference(const Graph& g) +{ + return tiernan_girth_and_circumference(g).second; +} } /* namespace boost */ diff --git a/include/boost/graph/topological_sort.hpp b/include/boost/graph/topological_sort.hpp index 08baf69b8..5cffdde1a 100644 --- a/include/boost/graph/topological_sort.hpp +++ b/include/boost/graph/topological_sort.hpp @@ -18,59 +18,63 @@ #include #include -namespace boost { +namespace boost +{ +// Topological sort visitor +// +// This visitor merely writes the linear ordering into an +// OutputIterator. The OutputIterator could be something like an +// ostream_iterator, or it could be a back/front_insert_iterator. +// Note that if it is a back_insert_iterator, the recorded order is +// the reverse topological order. On the other hand, if it is a +// front_insert_iterator, the recorded order is the topological +// order. +// +template < typename OutputIterator > +struct topo_sort_visitor : public dfs_visitor<> +{ + topo_sort_visitor(OutputIterator _iter) : m_iter(_iter) {} - // Topological sort visitor - // - // This visitor merely writes the linear ordering into an - // OutputIterator. The OutputIterator could be something like an - // ostream_iterator, or it could be a back/front_insert_iterator. - // Note that if it is a back_insert_iterator, the recorded order is - // the reverse topological order. On the other hand, if it is a - // front_insert_iterator, the recorded order is the topological - // order. - // - template - struct topo_sort_visitor : public dfs_visitor<> - { - topo_sort_visitor(OutputIterator _iter) - : m_iter(_iter) { } - - template - void back_edge(const Edge&, Graph&) { BOOST_THROW_EXCEPTION(not_a_dag()); } - - template - void finish_vertex(const Vertex& u, Graph&) { *m_iter++ = u; } - - OutputIterator m_iter; - }; + template < typename Edge, typename Graph > + void back_edge(const Edge&, Graph&) + { + BOOST_THROW_EXCEPTION(not_a_dag()); + } + template < typename Vertex, typename Graph > + void finish_vertex(const Vertex& u, Graph&) + { + *m_iter++ = u; + } - // Topological Sort - // - // The topological sort algorithm creates a linear ordering - // of the vertices such that if edge (u,v) appears in the graph, - // then u comes before v in the ordering. The graph must - // be a directed acyclic graph (DAG). The implementation - // consists mainly of a call to depth-first search. - // + OutputIterator m_iter; +}; + +// Topological Sort +// +// The topological sort algorithm creates a linear ordering +// of the vertices such that if edge (u,v) appears in the graph, +// then u comes before v in the ordering. The graph must +// be a directed acyclic graph (DAG). The implementation +// consists mainly of a call to depth-first search. +// - template - void topological_sort(VertexListGraph& g, OutputIterator result, - const bgl_named_params& params) - { - typedef topo_sort_visitor TopoVisitor; +template < typename VertexListGraph, typename OutputIterator, typename P, + typename T, typename R > +void topological_sort(VertexListGraph& g, OutputIterator result, + const bgl_named_params< P, T, R >& params) +{ + typedef topo_sort_visitor< OutputIterator > TopoVisitor; depth_first_search(g, params.visitor(TopoVisitor(result))); - } +} - template - void topological_sort(VertexListGraph& g, OutputIterator result) - { - topological_sort(g, result, - bgl_named_params(0)); // bogus - } +template < typename VertexListGraph, typename OutputIterator > +void topological_sort(VertexListGraph& g, OutputIterator result) +{ + topological_sort( + g, result, bgl_named_params< int, buffer_param_t >(0)); // bogus +} } // namespace boost diff --git a/include/boost/graph/topology.hpp b/include/boost/graph/topology.hpp index ada36d19b..8136ba965 100644 --- a/include/boost/graph/topology.hpp +++ b/include/boost/graph/topology.hpp @@ -23,574 +23,676 @@ // operations (used for Gurson-Atun layout), plus other things like bounding // boxes used for other layout algorithms. -namespace boost { +namespace boost +{ /*********************************************************** * Topologies * ***********************************************************/ -template -class convex_topology +template < std::size_t Dims > class convex_topology { - public: // For VisualAge C++ - struct point - { - BOOST_STATIC_CONSTANT(std::size_t, dimensions = Dims); - point() { } - double& operator[](std::size_t i) {return values[i];} - const double& operator[](std::size_t i) const {return values[i];} +public: // For VisualAge C++ + struct point + { + BOOST_STATIC_CONSTANT(std::size_t, dimensions = Dims); + point() {} + double& operator[](std::size_t i) { return values[i]; } + const double& operator[](std::size_t i) const { return values[i]; } + + private: + double values[Dims]; + }; + +public: // For VisualAge C++ + struct point_difference + { + BOOST_STATIC_CONSTANT(std::size_t, dimensions = Dims); + point_difference() + { + for (std::size_t i = 0; i < Dims; ++i) + values[i] = 0.; + } + double& operator[](std::size_t i) { return values[i]; } + const double& operator[](std::size_t i) const { return values[i]; } + + friend point_difference operator+( + const point_difference& a, const point_difference& b) + { + point_difference result; + for (std::size_t i = 0; i < Dims; ++i) + result[i] = a[i] + b[i]; + return result; + } + + friend point_difference& operator+=( + point_difference& a, const point_difference& b) + { + for (std::size_t i = 0; i < Dims; ++i) + a[i] += b[i]; + return a; + } + + friend point_difference operator-(const point_difference& a) + { + point_difference result; + for (std::size_t i = 0; i < Dims; ++i) + result[i] = -a[i]; + return result; + } + + friend point_difference operator-( + const point_difference& a, const point_difference& b) + { + point_difference result; + for (std::size_t i = 0; i < Dims; ++i) + result[i] = a[i] - b[i]; + return result; + } + + friend point_difference& operator-=( + point_difference& a, const point_difference& b) + { + for (std::size_t i = 0; i < Dims; ++i) + a[i] -= b[i]; + return a; + } + + friend point_difference operator*( + const point_difference& a, const point_difference& b) + { + point_difference result; + for (std::size_t i = 0; i < Dims; ++i) + result[i] = a[i] * b[i]; + return result; + } + + friend point_difference operator*(const point_difference& a, double b) + { + point_difference result; + for (std::size_t i = 0; i < Dims; ++i) + result[i] = a[i] * b; + return result; + } + + friend point_difference operator*(double a, const point_difference& b) + { + point_difference result; + for (std::size_t i = 0; i < Dims; ++i) + result[i] = a * b[i]; + return result; + } + + friend point_difference operator/( + const point_difference& a, const point_difference& b) + { + point_difference result; + for (std::size_t i = 0; i < Dims; ++i) + result[i] = (b[i] == 0.) ? 0. : a[i] / b[i]; + return result; + } + + friend double dot(const point_difference& a, const point_difference& b) + { + double result = 0; + for (std::size_t i = 0; i < Dims; ++i) + result += a[i] * b[i]; + return result; + } + + private: + double values[Dims]; + }; + +public: + typedef point point_type; + typedef point_difference point_difference_type; + + double distance(point a, point b) const + { + double dist = 0.; + for (std::size_t i = 0; i < Dims; ++i) + { + double diff = b[i] - a[i]; + dist = boost::math::hypot(dist, diff); + } + // Exact properties of the distance are not important, as long as + // < on what this returns matches real distances; l_2 is used because + // Fruchterman-Reingold also uses this code and it relies on l_2. + return dist; + } + + point move_position_toward(point a, double fraction, point b) const + { + point result; + for (std::size_t i = 0; i < Dims; ++i) + result[i] = a[i] + (b[i] - a[i]) * fraction; + return result; + } + + point_difference difference(point a, point b) const + { + point_difference result; + for (std::size_t i = 0; i < Dims; ++i) + result[i] = a[i] - b[i]; + return result; + } - private: - double values[Dims]; - }; + point adjust(point a, point_difference delta) const + { + point result; + for (std::size_t i = 0; i < Dims; ++i) + result[i] = a[i] + delta[i]; + return result; + } + + point pointwise_min(point a, point b) const + { + BOOST_USING_STD_MIN(); + point result; + for (std::size_t i = 0; i < Dims; ++i) + result[i] = min BOOST_PREVENT_MACRO_SUBSTITUTION(a[i], b[i]); + return result; + } + + point pointwise_max(point a, point b) const + { + BOOST_USING_STD_MAX(); + point result; + for (std::size_t i = 0; i < Dims; ++i) + result[i] = max BOOST_PREVENT_MACRO_SUBSTITUTION(a[i], b[i]); + return result; + } - public: // For VisualAge C++ - struct point_difference - { - BOOST_STATIC_CONSTANT(std::size_t, dimensions = Dims); - point_difference() { - for (std::size_t i = 0; i < Dims; ++i) values[i] = 0.; + double norm(point_difference delta) const + { + double n = 0.; + for (std::size_t i = 0; i < Dims; ++i) + n = boost::math::hypot(n, delta[i]); + return n; } - double& operator[](std::size_t i) {return values[i];} - const double& operator[](std::size_t i) const {return values[i];} - - friend point_difference operator+(const point_difference& a, const point_difference& b) { - point_difference result; - for (std::size_t i = 0; i < Dims; ++i) - result[i] = a[i] + b[i]; - return result; - } - - friend point_difference& operator+=(point_difference& a, const point_difference& b) { - for (std::size_t i = 0; i < Dims; ++i) - a[i] += b[i]; - return a; - } - - friend point_difference operator-(const point_difference& a) { - point_difference result; - for (std::size_t i = 0; i < Dims; ++i) - result[i] = -a[i]; - return result; - } - - friend point_difference operator-(const point_difference& a, const point_difference& b) { - point_difference result; - for (std::size_t i = 0; i < Dims; ++i) - result[i] = a[i] - b[i]; - return result; - } - - friend point_difference& operator-=(point_difference& a, const point_difference& b) { - for (std::size_t i = 0; i < Dims; ++i) - a[i] -= b[i]; - return a; - } - - friend point_difference operator*(const point_difference& a, const point_difference& b) { - point_difference result; - for (std::size_t i = 0; i < Dims; ++i) - result[i] = a[i] * b[i]; - return result; - } - - friend point_difference operator*(const point_difference& a, double b) { - point_difference result; - for (std::size_t i = 0; i < Dims; ++i) - result[i] = a[i] * b; - return result; - } - - friend point_difference operator*(double a, const point_difference& b) { - point_difference result; - for (std::size_t i = 0; i < Dims; ++i) - result[i] = a * b[i]; - return result; - } - - friend point_difference operator/(const point_difference& a, const point_difference& b) { - point_difference result; - for (std::size_t i = 0; i < Dims; ++i) - result[i] = (b[i] == 0.) ? 0. : a[i] / b[i]; - return result; - } - - friend double dot(const point_difference& a, const point_difference& b) { - double result = 0; - for (std::size_t i = 0; i < Dims; ++i) - result += a[i] * b[i]; - return result; - } - - private: - double values[Dims]; - }; - - public: - typedef point point_type; - typedef point_difference point_difference_type; - - double distance(point a, point b) const - { - double dist = 0.; - for (std::size_t i = 0; i < Dims; ++i) { - double diff = b[i] - a[i]; - dist = boost::math::hypot(dist, diff); - } - // Exact properties of the distance are not important, as long as - // < on what this returns matches real distances; l_2 is used because - // Fruchterman-Reingold also uses this code and it relies on l_2. - return dist; - } - - point move_position_toward(point a, double fraction, point b) const - { - point result; - for (std::size_t i = 0; i < Dims; ++i) - result[i] = a[i] + (b[i] - a[i]) * fraction; - return result; - } - - point_difference difference(point a, point b) const { - point_difference result; - for (std::size_t i = 0; i < Dims; ++i) - result[i] = a[i] - b[i]; - return result; - } - - point adjust(point a, point_difference delta) const { - point result; - for (std::size_t i = 0; i < Dims; ++i) - result[i] = a[i] + delta[i]; - return result; - } - - point pointwise_min(point a, point b) const { - BOOST_USING_STD_MIN(); - point result; - for (std::size_t i = 0; i < Dims; ++i) - result[i] = min BOOST_PREVENT_MACRO_SUBSTITUTION (a[i], b[i]); - return result; - } - - point pointwise_max(point a, point b) const { - BOOST_USING_STD_MAX(); - point result; - for (std::size_t i = 0; i < Dims; ++i) - result[i] = max BOOST_PREVENT_MACRO_SUBSTITUTION (a[i], b[i]); - return result; - } - - double norm(point_difference delta) const { - double n = 0.; - for (std::size_t i = 0; i < Dims; ++i) - n = boost::math::hypot(n, delta[i]); - return n; - } - - double volume(point_difference delta) const { - double n = 1.; - for (std::size_t i = 0; i < Dims; ++i) - n *= delta[i]; - return n; - } + double volume(point_difference delta) const + { + double n = 1.; + for (std::size_t i = 0; i < Dims; ++i) + n *= delta[i]; + return n; + } }; -template -class hypercube_topology : public convex_topology +template < std::size_t Dims, typename RandomNumberGenerator = minstd_rand > +class hypercube_topology : public convex_topology< Dims > { - typedef uniform_01 rand_t; - - public: - typedef typename convex_topology::point_type point_type; - typedef typename convex_topology::point_difference_type point_difference_type; - - explicit hypercube_topology(double scaling = 1.0) - : gen_ptr(new RandomNumberGenerator), rand(new rand_t(*gen_ptr)), - scaling(scaling) - { } - - hypercube_topology(RandomNumberGenerator& gen, double scaling = 1.0) - : gen_ptr(), rand(new rand_t(gen)), scaling(scaling) { } - - point_type random_point() const - { - point_type p; - for (std::size_t i = 0; i < Dims; ++i) - p[i] = (*rand)() * scaling; - return p; - } - - point_type bound(point_type a) const - { - BOOST_USING_STD_MIN(); - BOOST_USING_STD_MAX(); - point_type p; - for (std::size_t i = 0; i < Dims; ++i) - p[i] = min BOOST_PREVENT_MACRO_SUBSTITUTION (scaling, max BOOST_PREVENT_MACRO_SUBSTITUTION (-scaling, a[i])); - return p; - } - - double distance_from_boundary(point_type a) const - { - BOOST_USING_STD_MIN(); - BOOST_USING_STD_MAX(); + typedef uniform_01< RandomNumberGenerator, double > rand_t; + +public: + typedef typename convex_topology< Dims >::point_type point_type; + typedef typename convex_topology< Dims >::point_difference_type + point_difference_type; + + explicit hypercube_topology(double scaling = 1.0) + : gen_ptr(new RandomNumberGenerator) + , rand(new rand_t(*gen_ptr)) + , scaling(scaling) + { + } + + hypercube_topology(RandomNumberGenerator& gen, double scaling = 1.0) + : gen_ptr(), rand(new rand_t(gen)), scaling(scaling) + { + } + + point_type random_point() const + { + point_type p; + for (std::size_t i = 0; i < Dims; ++i) + p[i] = (*rand)() * scaling; + return p; + } + + point_type bound(point_type a) const + { + BOOST_USING_STD_MIN(); + BOOST_USING_STD_MAX(); + point_type p; + for (std::size_t i = 0; i < Dims; ++i) + p[i] = min BOOST_PREVENT_MACRO_SUBSTITUTION( + scaling, max BOOST_PREVENT_MACRO_SUBSTITUTION(-scaling, a[i])); + return p; + } + + double distance_from_boundary(point_type a) const + { + BOOST_USING_STD_MIN(); + BOOST_USING_STD_MAX(); #ifndef BOOST_NO_STDC_NAMESPACE - using std::abs; + using std::abs; #endif - BOOST_STATIC_ASSERT (Dims >= 1); - double dist = abs(scaling - a[0]); - for (std::size_t i = 1; i < Dims; ++i) - dist = min BOOST_PREVENT_MACRO_SUBSTITUTION (dist, abs(scaling - a[i])); - return dist; - } - - point_type center() const { - point_type result; - for (std::size_t i = 0; i < Dims; ++i) - result[i] = scaling * .5; - return result; - } - - point_type origin() const { - point_type result; - for (std::size_t i = 0; i < Dims; ++i) - result[i] = 0; - return result; - } - - point_difference_type extent() const { - point_difference_type result; - for (std::size_t i = 0; i < Dims; ++i) - result[i] = scaling; - return result; - } - - private: - shared_ptr gen_ptr; - shared_ptr rand; - double scaling; + BOOST_STATIC_ASSERT(Dims >= 1); + double dist = abs(scaling - a[0]); + for (std::size_t i = 1; i < Dims; ++i) + dist = min BOOST_PREVENT_MACRO_SUBSTITUTION( + dist, abs(scaling - a[i])); + return dist; + } + + point_type center() const + { + point_type result; + for (std::size_t i = 0; i < Dims; ++i) + result[i] = scaling * .5; + return result; + } + + point_type origin() const + { + point_type result; + for (std::size_t i = 0; i < Dims; ++i) + result[i] = 0; + return result; + } + + point_difference_type extent() const + { + point_difference_type result; + for (std::size_t i = 0; i < Dims; ++i) + result[i] = scaling; + return result; + } + +private: + shared_ptr< RandomNumberGenerator > gen_ptr; + shared_ptr< rand_t > rand; + double scaling; }; -template -class square_topology : public hypercube_topology<2, RandomNumberGenerator> +template < typename RandomNumberGenerator = minstd_rand > +class square_topology : public hypercube_topology< 2, RandomNumberGenerator > { - typedef hypercube_topology<2, RandomNumberGenerator> inherited; + typedef hypercube_topology< 2, RandomNumberGenerator > inherited; - public: - explicit square_topology(double scaling = 1.0) : inherited(scaling) { } - - square_topology(RandomNumberGenerator& gen, double scaling = 1.0) - : inherited(gen, scaling) { } +public: + explicit square_topology(double scaling = 1.0) : inherited(scaling) {} + + square_topology(RandomNumberGenerator& gen, double scaling = 1.0) + : inherited(gen, scaling) + { + } }; -template -class rectangle_topology : public convex_topology<2> +template < typename RandomNumberGenerator = minstd_rand > +class rectangle_topology : public convex_topology< 2 > { - typedef uniform_01 rand_t; - - public: - rectangle_topology(double left, double top, double right, double bottom) - : gen_ptr(new RandomNumberGenerator), rand(new rand_t(*gen_ptr)), - left(std::min BOOST_PREVENT_MACRO_SUBSTITUTION (left, right)), - top(std::min BOOST_PREVENT_MACRO_SUBSTITUTION (top, bottom)), - right(std::max BOOST_PREVENT_MACRO_SUBSTITUTION (left, right)), - bottom(std::max BOOST_PREVENT_MACRO_SUBSTITUTION (top, bottom)) { } - - rectangle_topology(RandomNumberGenerator& gen, double left, double top, double right, double bottom) - : gen_ptr(), rand(new rand_t(gen)), - left(std::min BOOST_PREVENT_MACRO_SUBSTITUTION (left, right)), - top(std::min BOOST_PREVENT_MACRO_SUBSTITUTION (top, bottom)), - right(std::max BOOST_PREVENT_MACRO_SUBSTITUTION (left, right)), - bottom(std::max BOOST_PREVENT_MACRO_SUBSTITUTION (top, bottom)) { } - - typedef typename convex_topology<2>::point_type point_type; - typedef typename convex_topology<2>::point_difference_type point_difference_type; - - point_type random_point() const - { - point_type p; - p[0] = (*rand)() * (right - left) + left; - p[1] = (*rand)() * (bottom - top) + top; - return p; - } - - point_type bound(point_type a) const - { - BOOST_USING_STD_MIN(); - BOOST_USING_STD_MAX(); - point_type p; - p[0] = min BOOST_PREVENT_MACRO_SUBSTITUTION (right, max BOOST_PREVENT_MACRO_SUBSTITUTION (left, a[0])); - p[1] = min BOOST_PREVENT_MACRO_SUBSTITUTION (bottom, max BOOST_PREVENT_MACRO_SUBSTITUTION (top, a[1])); - return p; - } - - double distance_from_boundary(point_type a) const - { - BOOST_USING_STD_MIN(); - BOOST_USING_STD_MAX(); + typedef uniform_01< RandomNumberGenerator, double > rand_t; + +public: + rectangle_topology(double left, double top, double right, double bottom) + : gen_ptr(new RandomNumberGenerator) + , rand(new rand_t(*gen_ptr)) + , left(std::min BOOST_PREVENT_MACRO_SUBSTITUTION(left, right)) + , top(std::min BOOST_PREVENT_MACRO_SUBSTITUTION(top, bottom)) + , right(std::max BOOST_PREVENT_MACRO_SUBSTITUTION(left, right)) + , bottom(std::max BOOST_PREVENT_MACRO_SUBSTITUTION(top, bottom)) + { + } + + rectangle_topology(RandomNumberGenerator& gen, double left, double top, + double right, double bottom) + : gen_ptr() + , rand(new rand_t(gen)) + , left(std::min BOOST_PREVENT_MACRO_SUBSTITUTION(left, right)) + , top(std::min BOOST_PREVENT_MACRO_SUBSTITUTION(top, bottom)) + , right(std::max BOOST_PREVENT_MACRO_SUBSTITUTION(left, right)) + , bottom(std::max BOOST_PREVENT_MACRO_SUBSTITUTION(top, bottom)) + { + } + + typedef typename convex_topology< 2 >::point_type point_type; + typedef typename convex_topology< 2 >::point_difference_type + point_difference_type; + + point_type random_point() const + { + point_type p; + p[0] = (*rand)() * (right - left) + left; + p[1] = (*rand)() * (bottom - top) + top; + return p; + } + + point_type bound(point_type a) const + { + BOOST_USING_STD_MIN(); + BOOST_USING_STD_MAX(); + point_type p; + p[0] = min BOOST_PREVENT_MACRO_SUBSTITUTION( + right, max BOOST_PREVENT_MACRO_SUBSTITUTION(left, a[0])); + p[1] = min BOOST_PREVENT_MACRO_SUBSTITUTION( + bottom, max BOOST_PREVENT_MACRO_SUBSTITUTION(top, a[1])); + return p; + } + + double distance_from_boundary(point_type a) const + { + BOOST_USING_STD_MIN(); + BOOST_USING_STD_MAX(); #ifndef BOOST_NO_STDC_NAMESPACE - using std::abs; + using std::abs; #endif - double dist = abs(left - a[0]); - dist = min BOOST_PREVENT_MACRO_SUBSTITUTION (dist, abs(right - a[0])); - dist = min BOOST_PREVENT_MACRO_SUBSTITUTION (dist, abs(top - a[1])); - dist = min BOOST_PREVENT_MACRO_SUBSTITUTION (dist, abs(bottom - a[1])); - return dist; - } - - point_type center() const { - point_type result; - result[0] = (left + right) / 2.; - result[1] = (top + bottom) / 2.; - return result; - } - - point_type origin() const { - point_type result; - result[0] = left; - result[1] = top; - return result; - } - - point_difference_type extent() const { - point_difference_type result; - result[0] = right - left; - result[1] = bottom - top; - return result; - } - - private: - shared_ptr gen_ptr; - shared_ptr rand; - double left, top, right, bottom; + double dist = abs(left - a[0]); + dist = min BOOST_PREVENT_MACRO_SUBSTITUTION(dist, abs(right - a[0])); + dist = min BOOST_PREVENT_MACRO_SUBSTITUTION(dist, abs(top - a[1])); + dist = min BOOST_PREVENT_MACRO_SUBSTITUTION(dist, abs(bottom - a[1])); + return dist; + } + + point_type center() const + { + point_type result; + result[0] = (left + right) / 2.; + result[1] = (top + bottom) / 2.; + return result; + } + + point_type origin() const + { + point_type result; + result[0] = left; + result[1] = top; + return result; + } + + point_difference_type extent() const + { + point_difference_type result; + result[0] = right - left; + result[1] = bottom - top; + return result; + } + +private: + shared_ptr< RandomNumberGenerator > gen_ptr; + shared_ptr< rand_t > rand; + double left, top, right, bottom; }; -template -class cube_topology : public hypercube_topology<3, RandomNumberGenerator> +template < typename RandomNumberGenerator = minstd_rand > +class cube_topology : public hypercube_topology< 3, RandomNumberGenerator > { - typedef hypercube_topology<3, RandomNumberGenerator> inherited; + typedef hypercube_topology< 3, RandomNumberGenerator > inherited; + +public: + explicit cube_topology(double scaling = 1.0) : inherited(scaling) {} - public: - explicit cube_topology(double scaling = 1.0) : inherited(scaling) { } - - cube_topology(RandomNumberGenerator& gen, double scaling = 1.0) - : inherited(gen, scaling) { } + cube_topology(RandomNumberGenerator& gen, double scaling = 1.0) + : inherited(gen, scaling) + { + } }; -template -class ball_topology : public convex_topology +template < std::size_t Dims, typename RandomNumberGenerator = minstd_rand > +class ball_topology : public convex_topology< Dims > { - typedef uniform_01 rand_t; - - public: - typedef typename convex_topology::point_type point_type; - typedef typename convex_topology::point_difference_type point_difference_type; - - explicit ball_topology(double radius = 1.0) - : gen_ptr(new RandomNumberGenerator), rand(new rand_t(*gen_ptr)), - radius(radius) - { } - - ball_topology(RandomNumberGenerator& gen, double radius = 1.0) - : gen_ptr(), rand(new rand_t(gen)), radius(radius) { } - - point_type random_point() const - { - point_type p; - double dist_sum; - do { - dist_sum = 0.0; - for (std::size_t i = 0; i < Dims; ++i) { - double x = (*rand)() * 2*radius - radius; - p[i] = x; - dist_sum += x * x; - } - } while (dist_sum > radius*radius); - return p; - } - - point_type bound(point_type a) const - { - BOOST_USING_STD_MIN(); - BOOST_USING_STD_MAX(); - double r = 0.; - for (std::size_t i = 0; i < Dims; ++i) - r = boost::math::hypot(r, a[i]); - if (r <= radius) return a; - double scaling_factor = radius / r; - point_type p; - for (std::size_t i = 0; i < Dims; ++i) - p[i] = a[i] * scaling_factor; - return p; - } - - double distance_from_boundary(point_type a) const - { - double r = 0.; - for (std::size_t i = 0; i < Dims; ++i) - r = boost::math::hypot(r, a[i]); - return radius - r; - } - - point_type center() const { - point_type result; - for (std::size_t i = 0; i < Dims; ++i) - result[i] = 0; - return result; - } - - point_type origin() const { - point_type result; - for (std::size_t i = 0; i < Dims; ++i) - result[i] = -radius; - return result; - } - - point_difference_type extent() const { - point_difference_type result; - for (std::size_t i = 0; i < Dims; ++i) - result[i] = 2. * radius; - return result; - } - - private: - shared_ptr gen_ptr; - shared_ptr rand; - double radius; + typedef uniform_01< RandomNumberGenerator, double > rand_t; + +public: + typedef typename convex_topology< Dims >::point_type point_type; + typedef typename convex_topology< Dims >::point_difference_type + point_difference_type; + + explicit ball_topology(double radius = 1.0) + : gen_ptr(new RandomNumberGenerator) + , rand(new rand_t(*gen_ptr)) + , radius(radius) + { + } + + ball_topology(RandomNumberGenerator& gen, double radius = 1.0) + : gen_ptr(), rand(new rand_t(gen)), radius(radius) + { + } + + point_type random_point() const + { + point_type p; + double dist_sum; + do + { + dist_sum = 0.0; + for (std::size_t i = 0; i < Dims; ++i) + { + double x = (*rand)() * 2 * radius - radius; + p[i] = x; + dist_sum += x * x; + } + } while (dist_sum > radius * radius); + return p; + } + + point_type bound(point_type a) const + { + BOOST_USING_STD_MIN(); + BOOST_USING_STD_MAX(); + double r = 0.; + for (std::size_t i = 0; i < Dims; ++i) + r = boost::math::hypot(r, a[i]); + if (r <= radius) + return a; + double scaling_factor = radius / r; + point_type p; + for (std::size_t i = 0; i < Dims; ++i) + p[i] = a[i] * scaling_factor; + return p; + } + + double distance_from_boundary(point_type a) const + { + double r = 0.; + for (std::size_t i = 0; i < Dims; ++i) + r = boost::math::hypot(r, a[i]); + return radius - r; + } + + point_type center() const + { + point_type result; + for (std::size_t i = 0; i < Dims; ++i) + result[i] = 0; + return result; + } + + point_type origin() const + { + point_type result; + for (std::size_t i = 0; i < Dims; ++i) + result[i] = -radius; + return result; + } + + point_difference_type extent() const + { + point_difference_type result; + for (std::size_t i = 0; i < Dims; ++i) + result[i] = 2. * radius; + return result; + } + +private: + shared_ptr< RandomNumberGenerator > gen_ptr; + shared_ptr< rand_t > rand; + double radius; }; -template -class circle_topology : public ball_topology<2, RandomNumberGenerator> +template < typename RandomNumberGenerator = minstd_rand > +class circle_topology : public ball_topology< 2, RandomNumberGenerator > { - typedef ball_topology<2, RandomNumberGenerator> inherited; + typedef ball_topology< 2, RandomNumberGenerator > inherited; + +public: + explicit circle_topology(double radius = 1.0) : inherited(radius) {} - public: - explicit circle_topology(double radius = 1.0) : inherited(radius) { } - - circle_topology(RandomNumberGenerator& gen, double radius = 1.0) - : inherited(gen, radius) { } + circle_topology(RandomNumberGenerator& gen, double radius = 1.0) + : inherited(gen, radius) + { + } }; -template -class sphere_topology : public ball_topology<3, RandomNumberGenerator> +template < typename RandomNumberGenerator = minstd_rand > +class sphere_topology : public ball_topology< 3, RandomNumberGenerator > { - typedef ball_topology<3, RandomNumberGenerator> inherited; + typedef ball_topology< 3, RandomNumberGenerator > inherited; - public: - explicit sphere_topology(double radius = 1.0) : inherited(radius) { } - - sphere_topology(RandomNumberGenerator& gen, double radius = 1.0) - : inherited(gen, radius) { } +public: + explicit sphere_topology(double radius = 1.0) : inherited(radius) {} + + sphere_topology(RandomNumberGenerator& gen, double radius = 1.0) + : inherited(gen, radius) + { + } }; -template -class heart_topology +template < typename RandomNumberGenerator = minstd_rand > class heart_topology { - // Heart is defined as the union of three shapes: - // Square w/ corners (+-1000, -1000), (0, 0), (0, -2000) - // Circle centered at (-500, -500) radius 500*sqrt(2) - // Circle centered at (500, -500) radius 500*sqrt(2) - // Bounding box (-1000, -2000) - (1000, 500*(sqrt(2) - 1)) - - struct point - { - point() { values[0] = 0.0; values[1] = 0.0; } - point(double x, double y) { values[0] = x; values[1] = y; } - - double& operator[](std::size_t i) { return values[i]; } - double operator[](std::size_t i) const { return values[i]; } - - private: - double values[2]; - }; - - bool in_heart(point p) const - { + // Heart is defined as the union of three shapes: + // Square w/ corners (+-1000, -1000), (0, 0), (0, -2000) + // Circle centered at (-500, -500) radius 500*sqrt(2) + // Circle centered at (500, -500) radius 500*sqrt(2) + // Bounding box (-1000, -2000) - (1000, 500*(sqrt(2) - 1)) + + struct point + { + point() + { + values[0] = 0.0; + values[1] = 0.0; + } + point(double x, double y) + { + values[0] = x; + values[1] = y; + } + + double& operator[](std::size_t i) { return values[i]; } + double operator[](std::size_t i) const { return values[i]; } + + private: + double values[2]; + }; + + bool in_heart(point p) const + { #ifndef BOOST_NO_STDC_NAMESPACE - using std::abs; + using std::abs; #endif - if (p[1] < abs(p[0]) - 2000) return false; // Bottom - if (p[1] <= -1000) return true; // Diagonal of square - if (boost::math::hypot(p[0] - -500, p[1] - -500) <= 500. * boost::math::constants::root_two()) - return true; // Left circle - if (boost::math::hypot(p[0] - 500, p[1] - -500) <= 500. * boost::math::constants::root_two()) - return true; // Right circle - return false; - } - - bool segment_within_heart(point p1, point p2) const - { - // Assumes that p1 and p2 are within the heart - if ((p1[0] < 0) == (p2[0] < 0)) return true; // Same side of symmetry line - if (p1[0] == p2[0]) return true; // Vertical - double slope = (p2[1] - p1[1]) / (p2[0] - p1[0]); - double intercept = p1[1] - p1[0] * slope; - if (intercept > 0) return false; // Crosses between circles - return true; - } - - typedef uniform_01 rand_t; - - public: - typedef point point_type; - - heart_topology() - : gen_ptr(new RandomNumberGenerator), rand(new rand_t(*gen_ptr)) { } - - heart_topology(RandomNumberGenerator& gen) - : gen_ptr(), rand(new rand_t(gen)) { } - - point random_point() const - { - point result; - do { - result[0] = (*rand)() * (1000 + 1000 * boost::math::constants::root_two()) - (500 + 500 * boost::math::constants::root_two()); - result[1] = (*rand)() * (2000 + 500 * (boost::math::constants::root_two() - 1)) - 2000; - } while (!in_heart(result)); - return result; - } - - // Not going to provide clipping to bounding region or distance from boundary - - double distance(point a, point b) const - { - if (segment_within_heart(a, b)) { - // Straight line - return boost::math::hypot(b[0] - a[0], b[1] - a[1]); - } else { - // Straight line bending around (0, 0) - return boost::math::hypot(a[0], a[1]) + boost::math::hypot(b[0], b[1]); - } - } - - point move_position_toward(point a, double fraction, point b) const - { - if (segment_within_heart(a, b)) { - // Straight line - return point(a[0] + (b[0] - a[0]) * fraction, - a[1] + (b[1] - a[1]) * fraction); - } else { - double distance_to_point_a = boost::math::hypot(a[0], a[1]); - double distance_to_point_b = boost::math::hypot(b[0], b[1]); - double location_of_point = distance_to_point_a / - (distance_to_point_a + distance_to_point_b); - if (fraction < location_of_point) - return point(a[0] * (1 - fraction / location_of_point), - a[1] * (1 - fraction / location_of_point)); - else - return point( - b[0] * ((fraction - location_of_point) / (1 - location_of_point)), - b[1] * ((fraction - location_of_point) / (1 - location_of_point))); - } - } - - private: - shared_ptr gen_ptr; - shared_ptr rand; + if (p[1] < abs(p[0]) - 2000) + return false; // Bottom + if (p[1] <= -1000) + return true; // Diagonal of square + if (boost::math::hypot(p[0] - -500, p[1] - -500) + <= 500. * boost::math::constants::root_two< double >()) + return true; // Left circle + if (boost::math::hypot(p[0] - 500, p[1] - -500) + <= 500. * boost::math::constants::root_two< double >()) + return true; // Right circle + return false; + } + + bool segment_within_heart(point p1, point p2) const + { + // Assumes that p1 and p2 are within the heart + if ((p1[0] < 0) == (p2[0] < 0)) + return true; // Same side of symmetry line + if (p1[0] == p2[0]) + return true; // Vertical + double slope = (p2[1] - p1[1]) / (p2[0] - p1[0]); + double intercept = p1[1] - p1[0] * slope; + if (intercept > 0) + return false; // Crosses between circles + return true; + } + + typedef uniform_01< RandomNumberGenerator, double > rand_t; + +public: + typedef point point_type; + + heart_topology() + : gen_ptr(new RandomNumberGenerator), rand(new rand_t(*gen_ptr)) + { + } + + heart_topology(RandomNumberGenerator& gen) + : gen_ptr(), rand(new rand_t(gen)) + { + } + + point random_point() const + { + point result; + do + { + result[0] = (*rand)() + * (1000 + + 1000 * boost::math::constants::root_two< double >()) + - (500 + 500 * boost::math::constants::root_two< double >()); + result[1] = (*rand)() + * (2000 + + 500 + * (boost::math::constants::root_two< double >() + - 1)) + - 2000; + } while (!in_heart(result)); + return result; + } + + // Not going to provide clipping to bounding region or distance from + // boundary + + double distance(point a, point b) const + { + if (segment_within_heart(a, b)) + { + // Straight line + return boost::math::hypot(b[0] - a[0], b[1] - a[1]); + } + else + { + // Straight line bending around (0, 0) + return boost::math::hypot(a[0], a[1]) + + boost::math::hypot(b[0], b[1]); + } + } + + point move_position_toward(point a, double fraction, point b) const + { + if (segment_within_heart(a, b)) + { + // Straight line + return point(a[0] + (b[0] - a[0]) * fraction, + a[1] + (b[1] - a[1]) * fraction); + } + else + { + double distance_to_point_a = boost::math::hypot(a[0], a[1]); + double distance_to_point_b = boost::math::hypot(b[0], b[1]); + double location_of_point = distance_to_point_a + / (distance_to_point_a + distance_to_point_b); + if (fraction < location_of_point) + return point(a[0] * (1 - fraction / location_of_point), + a[1] * (1 - fraction / location_of_point)); + else + return point(b[0] + * ((fraction - location_of_point) + / (1 - location_of_point)), + b[1] + * ((fraction - location_of_point) + / (1 - location_of_point))); + } + } + +private: + shared_ptr< RandomNumberGenerator > gen_ptr; + shared_ptr< rand_t > rand; }; } // namespace boost diff --git a/include/boost/graph/transitive_closure.hpp b/include/boost/graph/transitive_closure.hpp index ac1f0ae3f..cf4d5cec7 100644 --- a/include/boost/graph/transitive_closure.hpp +++ b/include/boost/graph/transitive_closure.hpp @@ -24,291 +24,300 @@ namespace boost { - namespace detail - { - inline void - union_successor_sets(const std::vector < std::size_t > &s1, - const std::vector < std::size_t > &s2, - std::vector < std::size_t > &s3) +namespace detail +{ + inline void union_successor_sets(const std::vector< std::size_t >& s1, + const std::vector< std::size_t >& s2, std::vector< std::size_t >& s3) { - BOOST_USING_STD_MIN(); - for (std::size_t k = 0; k < s1.size(); ++k) - s3[k] = min BOOST_PREVENT_MACRO_SUBSTITUTION(s1[k], s2[k]); + BOOST_USING_STD_MIN(); + for (std::size_t k = 0; k < s1.size(); ++k) + s3[k] = min BOOST_PREVENT_MACRO_SUBSTITUTION(s1[k], s2[k]); } - } // namespace detail +} // namespace detail - namespace detail - { +namespace detail +{ template < typename TheContainer, typename ST = std::size_t, - typename VT = typename TheContainer::value_type > - struct subscript_t + typename VT = typename TheContainer::value_type > + struct subscript_t { - typedef ST argument_type; - typedef VT& result_type; - - subscript_t(TheContainer & c):container(&c) - { - } - VT & operator() (const ST & i) const - { - return (*container)[i]; - } + typedef ST argument_type; + typedef VT& result_type; + + subscript_t(TheContainer& c) : container(&c) {} + VT& operator()(const ST& i) const { return (*container)[i]; } + protected: - TheContainer * container; + TheContainer* container; }; template < typename TheContainer > - subscript_t < TheContainer > subscript(TheContainer & c) { - return subscript_t < TheContainer > (c); + subscript_t< TheContainer > subscript(TheContainer& c) + { + return subscript_t< TheContainer >(c); } - } // namespace detail +} // namespace detail - template < typename Graph, typename GraphTC, - typename G_to_TC_VertexMap, +template < typename Graph, typename GraphTC, typename G_to_TC_VertexMap, typename VertexIndexMap > - void transitive_closure(const Graph & g, GraphTC & tc, - G_to_TC_VertexMap g_to_tc_map, - VertexIndexMap index_map) - { +void transitive_closure(const Graph& g, GraphTC& tc, + G_to_TC_VertexMap g_to_tc_map, VertexIndexMap index_map) +{ if (num_vertices(g) == 0) - return; - typedef typename graph_traits < Graph >::vertex_descriptor vertex; - typedef typename graph_traits < Graph >::vertex_iterator vertex_iterator; - typedef typename property_traits < VertexIndexMap >::value_type size_type; - typedef typename graph_traits < - Graph >::adjacency_iterator adjacency_iterator; - - BOOST_CONCEPT_ASSERT(( VertexListGraphConcept < Graph > )); - BOOST_CONCEPT_ASSERT(( AdjacencyGraphConcept < Graph > )); - BOOST_CONCEPT_ASSERT(( VertexMutableGraphConcept < GraphTC > )); - BOOST_CONCEPT_ASSERT(( EdgeMutableGraphConcept < GraphTC > )); - BOOST_CONCEPT_ASSERT(( ReadablePropertyMapConcept < VertexIndexMap, - vertex > )); + return; + typedef typename graph_traits< Graph >::vertex_descriptor vertex; + typedef typename graph_traits< Graph >::vertex_iterator vertex_iterator; + typedef typename property_traits< VertexIndexMap >::value_type size_type; + typedef + typename graph_traits< Graph >::adjacency_iterator adjacency_iterator; + + BOOST_CONCEPT_ASSERT((VertexListGraphConcept< Graph >)); + BOOST_CONCEPT_ASSERT((AdjacencyGraphConcept< Graph >)); + BOOST_CONCEPT_ASSERT((VertexMutableGraphConcept< GraphTC >)); + BOOST_CONCEPT_ASSERT((EdgeMutableGraphConcept< GraphTC >)); + BOOST_CONCEPT_ASSERT( + (ReadablePropertyMapConcept< VertexIndexMap, vertex >)); typedef size_type cg_vertex; - std::vector < cg_vertex > component_number_vec(num_vertices(g)); - iterator_property_map < cg_vertex *, VertexIndexMap, cg_vertex, cg_vertex& > - component_number(&component_number_vec[0], index_map); + std::vector< cg_vertex > component_number_vec(num_vertices(g)); + iterator_property_map< cg_vertex*, VertexIndexMap, cg_vertex, cg_vertex& > + component_number(&component_number_vec[0], index_map); - int num_scc = strong_components(g, component_number, - vertex_index_map(index_map)); + int num_scc + = strong_components(g, component_number, vertex_index_map(index_map)); - std::vector < std::vector < vertex > >components; + std::vector< std::vector< vertex > > components; build_component_lists(g, num_scc, component_number, components); - typedef boost::adjacency_list CG_t; + typedef boost::adjacency_list< boost::vecS, boost::vecS, boost::directedS > + CG_t; CG_t CG(num_scc); - for (cg_vertex s = 0; s < components.size(); ++s) { - std::vector < cg_vertex > adj; - for (size_type i = 0; i < components[s].size(); ++i) { - vertex u = components[s][i]; - adjacency_iterator v, v_end; - for (boost::tie(v, v_end) = adjacent_vertices(u, g); v != v_end; ++v) { - cg_vertex t = component_number[*v]; - if (s != t) // Avoid loops in the condensation graph - adj.push_back(t); + for (cg_vertex s = 0; s < components.size(); ++s) + { + std::vector< cg_vertex > adj; + for (size_type i = 0; i < components[s].size(); ++i) + { + vertex u = components[s][i]; + adjacency_iterator v, v_end; + for (boost::tie(v, v_end) = adjacent_vertices(u, g); v != v_end; + ++v) + { + cg_vertex t = component_number[*v]; + if (s != t) // Avoid loops in the condensation graph + adj.push_back(t); + } + } + std::sort(adj.begin(), adj.end()); + typename std::vector< cg_vertex >::iterator di + = std::unique(adj.begin(), adj.end()); + if (di != adj.end()) + adj.erase(di, adj.end()); + for (typename std::vector< cg_vertex >::const_iterator i = adj.begin(); + i != adj.end(); ++i) + { + add_edge(s, *i, CG); } - } - std::sort(adj.begin(), adj.end()); - typename std::vector::iterator di = - std::unique(adj.begin(), adj.end()); - if (di != adj.end()) - adj.erase(di, adj.end()); - for (typename std::vector::const_iterator i = adj.begin(); - i != adj.end(); ++i) { - add_edge(s, *i, CG); - } } - std::vector topo_order; - std::vector topo_number(num_vertices(CG)); + std::vector< cg_vertex > topo_order; + std::vector< cg_vertex > topo_number(num_vertices(CG)); topological_sort(CG, std::back_inserter(topo_order), - vertex_index_map(identity_property_map())); + vertex_index_map(identity_property_map())); std::reverse(topo_order.begin(), topo_order.end()); size_type n = 0; - for (typename std::vector::iterator iter = topo_order.begin(); + for (typename std::vector< cg_vertex >::iterator iter = topo_order.begin(); iter != topo_order.end(); ++iter) - topo_number[*iter] = n++; - - std::vector > CG_vec(num_vertices(CG)); - for (size_type i = 0; i < num_vertices(CG); ++i) { - typedef typename boost::graph_traits::adjacency_iterator cg_adj_iter; - std::pair pr = adjacent_vertices(i, CG); - CG_vec[i].assign(pr.first, pr.second); - std::sort(CG_vec[i].begin(), CG_vec[i].end(), - boost::bind(std::less(), - boost::bind(detail::subscript(topo_number), _1), - boost::bind(detail::subscript(topo_number), _2))); + topo_number[*iter] = n++; + + std::vector< std::vector< cg_vertex > > CG_vec(num_vertices(CG)); + for (size_type i = 0; i < num_vertices(CG); ++i) + { + typedef typename boost::graph_traits< CG_t >::adjacency_iterator + cg_adj_iter; + std::pair< cg_adj_iter, cg_adj_iter > pr = adjacent_vertices(i, CG); + CG_vec[i].assign(pr.first, pr.second); + std::sort(CG_vec[i].begin(), CG_vec[i].end(), + boost::bind(std::less< cg_vertex >(), + boost::bind(detail::subscript(topo_number), _1), + boost::bind(detail::subscript(topo_number), _2))); } - std::vector > chains; + std::vector< std::vector< cg_vertex > > chains; { - std::vector in_a_chain(CG_vec.size()); - for (typename std::vector::iterator i = topo_order.begin(); - i != topo_order.end(); ++i) { - cg_vertex v = *i; - if (!in_a_chain[v]) { - chains.resize(chains.size() + 1); - std::vector& chain = chains.back(); - for (;;) { - chain.push_back(v); - in_a_chain[v] = true; - typename std::vector::const_iterator next - = std::find_if(CG_vec[v].begin(), CG_vec[v].end(), - std::not1(detail::subscript(in_a_chain))); - if (next != CG_vec[v].end()) - v = *next; - else - break; // end of chain, dead-end - - } + std::vector< cg_vertex > in_a_chain(CG_vec.size()); + for (typename std::vector< cg_vertex >::iterator i = topo_order.begin(); + i != topo_order.end(); ++i) + { + cg_vertex v = *i; + if (!in_a_chain[v]) + { + chains.resize(chains.size() + 1); + std::vector< cg_vertex >& chain = chains.back(); + for (;;) + { + chain.push_back(v); + in_a_chain[v] = true; + typename std::vector< cg_vertex >::const_iterator next + = std::find_if(CG_vec[v].begin(), CG_vec[v].end(), + std::not1(detail::subscript(in_a_chain))); + if (next != CG_vec[v].end()) + v = *next; + else + break; // end of chain, dead-end + } + } } - } } - std::vector chain_number(CG_vec.size()); - std::vector pos_in_chain(CG_vec.size()); + std::vector< size_type > chain_number(CG_vec.size()); + std::vector< size_type > pos_in_chain(CG_vec.size()); for (size_type i = 0; i < chains.size(); ++i) - for (size_type j = 0; j < chains[i].size(); ++j) { - cg_vertex v = chains[i][j]; - chain_number[v] = i; - pos_in_chain[v] = j; - } + for (size_type j = 0; j < chains[i].size(); ++j) + { + cg_vertex v = chains[i][j]; + chain_number[v] = i; + pos_in_chain[v] = j; + } cg_vertex inf = (std::numeric_limits< cg_vertex >::max)(); - std::vector > successors(CG_vec.size(), - std::vector - (chains.size(), inf)); - for (typename std::vector::reverse_iterator - i = topo_order.rbegin(); i != topo_order.rend(); ++i) { - cg_vertex u = *i; - typename std::vector::const_iterator adj, adj_last; - for (adj = CG_vec[u].begin(), adj_last = CG_vec[u].end(); - adj != adj_last; ++adj) { - cg_vertex v = *adj; - if (topo_number[v] < successors[u][chain_number[v]]) { - // Succ(u) = Succ(u) U Succ(v) - detail::union_successor_sets(successors[u], successors[v], - successors[u]); - // Succ(u) = Succ(u) U {v} - successors[u][chain_number[v]] = topo_number[v]; + std::vector< std::vector< cg_vertex > > successors( + CG_vec.size(), std::vector< cg_vertex >(chains.size(), inf)); + for (typename std::vector< cg_vertex >::reverse_iterator i + = topo_order.rbegin(); + i != topo_order.rend(); ++i) + { + cg_vertex u = *i; + typename std::vector< cg_vertex >::const_iterator adj, adj_last; + for (adj = CG_vec[u].begin(), adj_last = CG_vec[u].end(); + adj != adj_last; ++adj) + { + cg_vertex v = *adj; + if (topo_number[v] < successors[u][chain_number[v]]) + { + // Succ(u) = Succ(u) U Succ(v) + detail::union_successor_sets( + successors[u], successors[v], successors[u]); + // Succ(u) = Succ(u) U {v} + successors[u][chain_number[v]] = topo_number[v]; + } } - } } for (size_type i = 0; i < CG_vec.size(); ++i) - CG_vec[i].clear(); + CG_vec[i].clear(); for (size_type i = 0; i < CG_vec.size(); ++i) - for (size_type j = 0; j < chains.size(); ++j) { - size_type topo_num = successors[i][j]; - if (topo_num < inf) { - cg_vertex v = topo_order[topo_num]; - for (size_type k = pos_in_chain[v]; k < chains[j].size(); ++k) - CG_vec[i].push_back(chains[j][k]); + for (size_type j = 0; j < chains.size(); ++j) + { + size_type topo_num = successors[i][j]; + if (topo_num < inf) + { + cg_vertex v = topo_order[topo_num]; + for (size_type k = pos_in_chain[v]; k < chains[j].size(); ++k) + CG_vec[i].push_back(chains[j][k]); + } } - } - // Add vertices to the transitive closure graph { - vertex_iterator i, i_end; - for (boost::tie(i, i_end) = vertices(g); i != i_end; ++i) - g_to_tc_map[*i] = add_vertex(tc); + vertex_iterator i, i_end; + for (boost::tie(i, i_end) = vertices(g); i != i_end; ++i) + g_to_tc_map[*i] = add_vertex(tc); } // Add edges between all the vertices in two adjacent SCCs - typename std::vector >::const_iterator si, si_end; - for (si = CG_vec.begin(), si_end = CG_vec.end(); si != si_end; ++si) { - cg_vertex s = si - CG_vec.begin(); - typename std::vector::const_iterator i, i_end; - for (i = CG_vec[s].begin(), i_end = CG_vec[s].end(); i != i_end; ++i) { - cg_vertex t = *i; - for (size_type k = 0; k < components[s].size(); ++k) - for (size_type l = 0; l < components[t].size(); ++l) - add_edge(g_to_tc_map[components[s][k]], - g_to_tc_map[components[t][l]], tc); - } + typename std::vector< std::vector< cg_vertex > >::const_iterator si, si_end; + for (si = CG_vec.begin(), si_end = CG_vec.end(); si != si_end; ++si) + { + cg_vertex s = si - CG_vec.begin(); + typename std::vector< cg_vertex >::const_iterator i, i_end; + for (i = CG_vec[s].begin(), i_end = CG_vec[s].end(); i != i_end; ++i) + { + cg_vertex t = *i; + for (size_type k = 0; k < components[s].size(); ++k) + for (size_type l = 0; l < components[t].size(); ++l) + add_edge(g_to_tc_map[components[s][k]], + g_to_tc_map[components[t][l]], tc); + } } // Add edges connecting all vertices in a SCC for (size_type i = 0; i < components.size(); ++i) - if (components[i].size() > 1) - for (size_type k = 0; k < components[i].size(); ++k) - for (size_type l = 0; l < components[i].size(); ++l) { - vertex u = components[i][k], v = components[i][l]; - add_edge(g_to_tc_map[u], g_to_tc_map[v], tc); - } + if (components[i].size() > 1) + for (size_type k = 0; k < components[i].size(); ++k) + for (size_type l = 0; l < components[i].size(); ++l) + { + vertex u = components[i][k], v = components[i][l]; + add_edge(g_to_tc_map[u], g_to_tc_map[v], tc); + } // Find loopbacks in the original graph. // Need to add it to transitive closure. { - vertex_iterator i, i_end; - for (boost::tie(i, i_end) = vertices(g); i != i_end; ++i) + vertex_iterator i, i_end; + for (boost::tie(i, i_end) = vertices(g); i != i_end; ++i) { - adjacency_iterator ab, ae; - for (boost::tie(ab, ae) = adjacent_vertices(*i, g); ab != ae; ++ab) + adjacency_iterator ab, ae; + for (boost::tie(ab, ae) = adjacent_vertices(*i, g); ab != ae; ++ab) { - if (*ab == *i) - if (components[component_number[*i]].size() == 1) - add_edge(g_to_tc_map[*i], g_to_tc_map[*i], tc); + if (*ab == *i) + if (components[component_number[*i]].size() == 1) + add_edge(g_to_tc_map[*i], g_to_tc_map[*i], tc); } } } - } +} - template - void transitive_closure(const Graph & g, GraphTC & tc) - { +template < typename Graph, typename GraphTC > +void transitive_closure(const Graph& g, GraphTC& tc) +{ if (num_vertices(g) == 0) - return; - typedef typename property_map::const_type - VertexIndexMap; + return; + typedef typename property_map< Graph, vertex_index_t >::const_type + VertexIndexMap; VertexIndexMap index_map = get(vertex_index, g); - typedef typename graph_traits::vertex_descriptor tc_vertex; - std::vector to_tc_vec(num_vertices(g)); - iterator_property_map < tc_vertex *, VertexIndexMap, tc_vertex, tc_vertex&> - g_to_tc_map(&to_tc_vec[0], index_map); + typedef typename graph_traits< GraphTC >::vertex_descriptor tc_vertex; + std::vector< tc_vertex > to_tc_vec(num_vertices(g)); + iterator_property_map< tc_vertex*, VertexIndexMap, tc_vertex, tc_vertex& > + g_to_tc_map(&to_tc_vec[0], index_map); transitive_closure(g, tc, g_to_tc_map, index_map); - } +} - namespace detail - { +namespace detail +{ template < typename Graph, typename GraphTC, typename G_to_TC_VertexMap, - typename VertexIndexMap> - void transitive_closure_dispatch - (const Graph & g, GraphTC & tc, - G_to_TC_VertexMap g_to_tc_map, VertexIndexMap index_map) + typename VertexIndexMap > + void transitive_closure_dispatch(const Graph& g, GraphTC& tc, + G_to_TC_VertexMap g_to_tc_map, VertexIndexMap index_map) { - typedef typename graph_traits < GraphTC >::vertex_descriptor tc_vertex; - typename std::vector < tc_vertex >::size_type - n = is_default_param(g_to_tc_map) ? num_vertices(g) : 1; - std::vector < tc_vertex > to_tc_vec(n); - - transitive_closure - (g, tc, - choose_param(g_to_tc_map, make_iterator_property_map - (to_tc_vec.begin(), index_map, to_tc_vec[0])), - index_map); + typedef typename graph_traits< GraphTC >::vertex_descriptor tc_vertex; + typename std::vector< tc_vertex >::size_type n + = is_default_param(g_to_tc_map) ? num_vertices(g) : 1; + std::vector< tc_vertex > to_tc_vec(n); + + transitive_closure(g, tc, + choose_param(g_to_tc_map, + make_iterator_property_map( + to_tc_vec.begin(), index_map, to_tc_vec[0])), + index_map); } - } // namespace detail +} // namespace detail - template < typename Graph, typename GraphTC, - typename P, typename T, typename R > - void transitive_closure(const Graph & g, GraphTC & tc, - const bgl_named_params < P, T, R > ¶ms) - { +template < typename Graph, typename GraphTC, typename P, typename T, + typename R > +void transitive_closure( + const Graph& g, GraphTC& tc, const bgl_named_params< P, T, R >& params) +{ if (num_vertices(g) == 0) - return; - detail::transitive_closure_dispatch - (g, tc, get_param(params, orig_to_copy_t()), - choose_const_pmap(get_param(params, vertex_index), g, vertex_index) ); - } + return; + detail::transitive_closure_dispatch(g, tc, + get_param(params, orig_to_copy_t()), + choose_const_pmap(get_param(params, vertex_index), g, vertex_index)); +} +template < typename G > void warshall_transitive_closure(G& g) +{ + typedef typename graph_traits< G >::vertex_iterator vertex_iterator; - template < typename G > void warshall_transitive_closure(G & g) - { - typedef typename graph_traits < G >::vertex_iterator vertex_iterator; - - BOOST_CONCEPT_ASSERT(( AdjacencyMatrixConcept < G > )); - BOOST_CONCEPT_ASSERT(( EdgeMutableGraphConcept < G > )); + BOOST_CONCEPT_ASSERT((AdjacencyMatrixConcept< G >)); + BOOST_CONCEPT_ASSERT((EdgeMutableGraphConcept< G >)); // Matrix form: // for k @@ -318,26 +327,26 @@ namespace boost // A[i,j] = A[i,j] | A[k,j] vertex_iterator ki, ke, ii, ie, ji, je; for (boost::tie(ki, ke) = vertices(g); ki != ke; ++ki) - for (boost::tie(ii, ie) = vertices(g); ii != ie; ++ii) - if (edge(*ii, *ki, g).second) - for (boost::tie(ji, je) = vertices(g); ji != je; ++ji) - if (!edge(*ii, *ji, g).second && edge(*ki, *ji, g).second) { - add_edge(*ii, *ji, g); - } - } - - - template < typename G > void warren_transitive_closure(G & g) - { + for (boost::tie(ii, ie) = vertices(g); ii != ie; ++ii) + if (edge(*ii, *ki, g).second) + for (boost::tie(ji, je) = vertices(g); ji != je; ++ji) + if (!edge(*ii, *ji, g).second && edge(*ki, *ji, g).second) + { + add_edge(*ii, *ji, g); + } +} + +template < typename G > void warren_transitive_closure(G& g) +{ using namespace boost; - typedef typename graph_traits < G >::vertex_iterator vertex_iterator; + typedef typename graph_traits< G >::vertex_iterator vertex_iterator; - BOOST_CONCEPT_ASSERT(( AdjacencyMatrixConcept < G > )); - BOOST_CONCEPT_ASSERT(( EdgeMutableGraphConcept < G > )); + BOOST_CONCEPT_ASSERT((AdjacencyMatrixConcept< G >)); + BOOST_CONCEPT_ASSERT((EdgeMutableGraphConcept< G >)); // Make sure second loop will work if (num_vertices(g) == 0) - return; + return; // for i = 2 to n // for k = 1 to i - 1 @@ -347,12 +356,13 @@ namespace boost vertex_iterator ic, ie, jc, je, kc, ke; for (boost::tie(ic, ie) = vertices(g), ++ic; ic != ie; ++ic) - for (boost::tie(kc, ke) = vertices(g); *kc != *ic; ++kc) - if (edge(*ic, *kc, g).second) - for (boost::tie(jc, je) = vertices(g); jc != je; ++jc) - if (!edge(*ic, *jc, g).second && edge(*kc, *jc, g).second) { - add_edge(*ic, *jc, g); - } + for (boost::tie(kc, ke) = vertices(g); *kc != *ic; ++kc) + if (edge(*ic, *kc, g).second) + for (boost::tie(jc, je) = vertices(g); jc != je; ++jc) + if (!edge(*ic, *jc, g).second && edge(*kc, *jc, g).second) + { + add_edge(*ic, *jc, g); + } // for i = 1 to n - 1 // for k = i + 1 to n // if A[i,k] @@ -360,15 +370,15 @@ namespace boost // A[i,j] = A[i,j] | A[k,j] for (boost::tie(ic, ie) = vertices(g), --ie; ic != ie; ++ic) - for (kc = ic, ke = ie, ++kc; kc != ke; ++kc) - if (edge(*ic, *kc, g).second) - for (boost::tie(jc, je) = vertices(g); jc != je; ++jc) - if (!edge(*ic, *jc, g).second && edge(*kc, *jc, g).second) { - add_edge(*ic, *jc, g); - } - } - - -} // namespace boost + for (kc = ic, ke = ie, ++kc; kc != ke; ++kc) + if (edge(*ic, *kc, g).second) + for (boost::tie(jc, je) = vertices(g); jc != je; ++jc) + if (!edge(*ic, *jc, g).second && edge(*kc, *jc, g).second) + { + add_edge(*ic, *jc, g); + } +} + +} // namespace boost #endif // BOOST_GRAPH_TRANSITIVE_CLOSURE_HPP diff --git a/include/boost/graph/transitive_reduction.hpp b/include/boost/graph/transitive_reduction.hpp index f7cb34b8c..32cb384aa 100644 --- a/include/boost/graph/transitive_reduction.hpp +++ b/include/boost/graph/transitive_reduction.hpp @@ -28,103 +28,110 @@ // reduction, but I think my implementation spoiled this up at some point // indicated below. -namespace boost { +namespace boost +{ -template < - typename Graph, typename GraphTR, typename G_to_TR_VertexMap, - typename VertexIndexMap -> +template < typename Graph, typename GraphTR, typename G_to_TR_VertexMap, + typename VertexIndexMap > BOOST_CONCEPT_REQUIRES( - ((VertexListGraphConcept< Graph >)) - ((IncidenceGraphConcept< Graph >)) - ((MutableGraphConcept< GraphTR >)) - ((ReadablePropertyMapConcept< VertexIndexMap, - typename graph_traits::vertex_descriptor >)) - ((Integer< typename - property_traits< VertexIndexMap >::value_type >)) - ((LvaluePropertyMapConcept< G_to_TR_VertexMap, - typename graph_traits::vertex_descriptor >)), - (void)) -transitive_reduction(const Graph& g, GraphTR& tr, - G_to_TR_VertexMap g_to_tr_map, - VertexIndexMap g_index_map ) + ((VertexListGraphConcept< Graph >))((IncidenceGraphConcept< Graph >))( + (MutableGraphConcept< GraphTR >))( + (ReadablePropertyMapConcept< VertexIndexMap, + typename graph_traits< Graph >::vertex_descriptor >))( + (Integer< typename property_traits< VertexIndexMap >::value_type >))( + (LvaluePropertyMapConcept< G_to_TR_VertexMap, + typename graph_traits< Graph >::vertex_descriptor >)), + (void)) +transitive_reduction(const Graph& g, GraphTR& tr, G_to_TR_VertexMap g_to_tr_map, + VertexIndexMap g_index_map) { - typedef typename graph_traits::vertex_descriptor Vertex; - typedef typename graph_traits::vertex_iterator VertexIterator; - typedef typename std::vector::size_type size_type; + typedef typename graph_traits< Graph >::vertex_descriptor Vertex; + typedef typename graph_traits< Graph >::vertex_iterator VertexIterator; + typedef typename std::vector< Vertex >::size_type size_type; - std::vector topo_order; + std::vector< Vertex > topo_order; topological_sort(g, std::back_inserter(topo_order)); - std::vector topo_number_storage(num_vertices(g)); + std::vector< size_type > topo_number_storage(num_vertices(g)); - iterator_property_map topo_number( &topo_number_storage[0], g_index_map ); + iterator_property_map< size_type*, VertexIndexMap, size_type, size_type& > + topo_number(&topo_number_storage[0], g_index_map); { - typename std::vector::reverse_iterator it = topo_order.rbegin(); + typename std::vector< Vertex >::reverse_iterator it + = topo_order.rbegin(); size_type n = 0; - for(; it != topo_order.rend(); ++it,++n ) { - topo_number[ *it ] = n; + for (; it != topo_order.rend(); ++it, ++n) + { + topo_number[*it] = n; } } - std::vector< std::vector< bool > > edge_in_closure(num_vertices(g), - std::vector( num_vertices(g), false)); + std::vector< std::vector< bool > > edge_in_closure( + num_vertices(g), std::vector< bool >(num_vertices(g), false)); { - typename std::vector::reverse_iterator it = topo_order.rbegin(); - for( ; it != topo_order.rend(); ++it ) { + typename std::vector< Vertex >::reverse_iterator it + = topo_order.rbegin(); + for (; it != topo_order.rend(); ++it) + { g_to_tr_map[*it] = add_vertex(tr); } } - typename std::vector::iterator - it = topo_order.begin(), - end = topo_order.end(); - for( ; it != end; ++it ) { - size_type i = topo_number[ *it ]; + typename std::vector< Vertex >::iterator it = topo_order.begin(), + end = topo_order.end(); + for (; it != end; ++it) + { + size_type i = topo_number[*it]; edge_in_closure[i][i] = true; - std::vector neighbors; + std::vector< Vertex > neighbors; - //I have to collect the successors of *it and traverse them in - //ascending topological order. I didn't know a better way, how to - //do that. So what I'm doint is, collection the successors of *it here + // I have to collect the successors of *it and traverse them in + // ascending topological order. I didn't know a better way, how to + // do that. So what I'm doint is, collection the successors of *it here { - typename Graph::out_edge_iterator oi,oi_end; - for( boost::tie(oi, oi_end) = out_edges( *it, g ); oi != oi_end; ++oi ) { - neighbors.push_back( target( *oi, g ) ); + typename Graph::out_edge_iterator oi, oi_end; + for (boost::tie(oi, oi_end) = out_edges(*it, g); oi != oi_end; ++oi) + { + neighbors.push_back(target(*oi, g)); } } { - //and run through all vertices in topological order - typename std::vector::reverse_iterator - rit = topo_order.rbegin(), + // and run through all vertices in topological order + typename std::vector< Vertex >::reverse_iterator rit + = topo_order.rbegin(), rend = topo_order.rend(); - for(; rit != rend; ++rit ) { - //looking if they are successors of *it - if( std::find( neighbors.begin(), neighbors.end(), *rit) != neighbors.end() ) { - size_type j = topo_number[ *rit ]; - if( not edge_in_closure[i][j] ) { - for(size_type k = j; k < num_vertices(g); ++k) { - if( not edge_in_closure[i][k] ) { - //here we need edge_in_closure to be in topological order, - edge_in_closure[i][k] = edge_in_closure[j][k]; + for (; rit != rend; ++rit) + { + // looking if they are successors of *it + if (std::find(neighbors.begin(), neighbors.end(), *rit) + != neighbors.end()) + { + size_type j = topo_number[*rit]; + if (not edge_in_closure[i][j]) + { + for (size_type k = j; k < num_vertices(g); ++k) + { + if (not edge_in_closure[i][k]) + { + // here we need edge_in_closure to be in + // topological order, + edge_in_closure[i][k] = edge_in_closure[j][k]; + } } - } - //therefore we only access edge_in_closure only through - //topo_number property_map - add_edge(g_to_tr_map[*it], g_to_tr_map[*rit], tr); - } //if ( not edge_in_ - } //if (find ( - } //for( typename vector::reverse_iterator + // therefore we only access edge_in_closure only through + // topo_number property_map + add_edge(g_to_tr_map[*it], g_to_tr_map[*rit], tr); + } // if ( not edge_in_ + } // if (find ( + } // for( typename vector::reverse_iterator } // { - } //for( typename vector::iterator + } // for( typename vector::iterator -} //void transitive_reduction +} // void transitive_reduction } // namespace boost #endif - diff --git a/include/boost/graph/transpose_graph.hpp b/include/boost/graph/transpose_graph.hpp index b12ba1005..9970e5936 100644 --- a/include/boost/graph/transpose_graph.hpp +++ b/include/boost/graph/transpose_graph.hpp @@ -16,24 +16,24 @@ #include #include +namespace boost +{ -namespace boost { - - template - void transpose_graph(const VertexListGraph& G, MutableGraph& G_T) - { - reverse_graph R(G); +template < class VertexListGraph, class MutableGraph > +void transpose_graph(const VertexListGraph& G, MutableGraph& G_T) +{ + reverse_graph< VertexListGraph > R(G); copy_graph(R, G_T); - } - - template - void transpose_graph(const VertexListGraph& G, MutableGraph& G_T, - const bgl_named_params& params) - { - reverse_graph Rev(G); +} + +template < class VertexListGraph, class MutableGraph, class P, class T, + class R > +void transpose_graph(const VertexListGraph& G, MutableGraph& G_T, + const bgl_named_params< P, T, R >& params) +{ + reverse_graph< VertexListGraph > Rev(G); copy_graph(Rev, G_T, params); - } +} } // namespace boost diff --git a/include/boost/graph/tree_traits.hpp b/include/boost/graph/tree_traits.hpp index a04c750f7..e27396ebf 100644 --- a/include/boost/graph/tree_traits.hpp +++ b/include/boost/graph/tree_traits.hpp @@ -8,37 +8,40 @@ #include //For boost::tie() -namespace boost { - - template - struct tree_traits { - typedef typename T::node_descriptor node_descriptor; - typedef typename T::children_iterator children_iterator; - }; - - - template - void traverse_tree(typename tree_traits::node_descriptor v, - Tree& t, TreeVisitor visitor) - { +namespace boost +{ + +template < class T > struct tree_traits +{ + typedef typename T::node_descriptor node_descriptor; + typedef typename T::children_iterator children_iterator; +}; + +template < class Tree, class TreeVisitor > +void traverse_tree(typename tree_traits< Tree >::node_descriptor v, Tree& t, + TreeVisitor visitor) +{ visitor.preorder(v, t); - typename tree_traits::children_iterator i, end; + typename tree_traits< Tree >::children_iterator i, end; boost::tie(i, end) = children(v, t); - if (i != end) { - traverse_tree(*i++, t, visitor); - visitor.inorder(v, t); - while (i != end) + if (i != end) + { traverse_tree(*i++, t, visitor); - } else - visitor.inorder(v, t); + visitor.inorder(v, t); + while (i != end) + traverse_tree(*i++, t, visitor); + } + else + visitor.inorder(v, t); visitor.postorder(v, t); - } - - struct null_tree_visitor { - template void preorder(Node, Tree&) { } - template void inorder(Node, Tree&) { } - template void postorder(Node, Tree&) { } - }; +} + +struct null_tree_visitor +{ + template < typename Node, typename Tree > void preorder(Node, Tree&) {} + template < typename Node, typename Tree > void inorder(Node, Tree&) {} + template < typename Node, typename Tree > void postorder(Node, Tree&) {} +}; } /* namespace boost */ diff --git a/include/boost/graph/two_bit_color_map.hpp b/include/boost/graph/two_bit_color_map.hpp index 7cbaf5a3b..d7572de3a 100644 --- a/include/boost/graph/two_bit_color_map.hpp +++ b/include/boost/graph/two_bit_color_map.hpp @@ -22,85 +22,87 @@ #include #include -namespace boost { +namespace boost +{ -enum two_bit_color_type { - two_bit_white = 0, - two_bit_gray = 1, - two_bit_green = 2, - two_bit_black = 3 +enum two_bit_color_type +{ + two_bit_white = 0, + two_bit_gray = 1, + two_bit_green = 2, + two_bit_black = 3 }; -template <> -struct color_traits +template <> struct color_traits< two_bit_color_type > { - static two_bit_color_type white() { return two_bit_white; } - static two_bit_color_type gray() { return two_bit_gray; } - static two_bit_color_type green() { return two_bit_green; } - static two_bit_color_type black() { return two_bit_black; } + static two_bit_color_type white() { return two_bit_white; } + static two_bit_color_type gray() { return two_bit_gray; } + static two_bit_color_type green() { return two_bit_green; } + static two_bit_color_type black() { return two_bit_black; } }; - -template -struct two_bit_color_map +template < typename IndexMap = identity_property_map > struct two_bit_color_map { - std::size_t n; - IndexMap index; - shared_array data; - - BOOST_STATIC_CONSTANT(int, bits_per_char = std::numeric_limits::digits); - BOOST_STATIC_CONSTANT(int, elements_per_char = bits_per_char / 2); - typedef typename property_traits::key_type key_type; - typedef two_bit_color_type value_type; - typedef void reference; - typedef read_write_property_map_tag category; - - explicit two_bit_color_map(std::size_t n, const IndexMap& index = IndexMap()) - : n(n), index(index), data(new unsigned char[(n + elements_per_char - 1) / elements_per_char]()) - { - } + std::size_t n; + IndexMap index; + shared_array< unsigned char > data; + + BOOST_STATIC_CONSTANT( + int, bits_per_char = std::numeric_limits< unsigned char >::digits); + BOOST_STATIC_CONSTANT(int, elements_per_char = bits_per_char / 2); + typedef typename property_traits< IndexMap >::key_type key_type; + typedef two_bit_color_type value_type; + typedef void reference; + typedef read_write_property_map_tag category; + + explicit two_bit_color_map( + std::size_t n, const IndexMap& index = IndexMap()) + : n(n) + , index(index) + , data(new unsigned char[(n + elements_per_char - 1) / elements_per_char]()) + { + } }; -template -inline two_bit_color_type -get(const two_bit_color_map& pm, - typename property_traits::key_type key) +template < typename IndexMap > +inline two_bit_color_type get(const two_bit_color_map< IndexMap >& pm, + typename property_traits< IndexMap >::key_type key) { - BOOST_STATIC_CONSTANT(int, elements_per_char = two_bit_color_map::elements_per_char); - typename property_traits::value_type i = get(pm.index, key); - BOOST_ASSERT ((std::size_t)i < pm.n); - std::size_t byte_num = i / elements_per_char; - std::size_t bit_position = ((i % elements_per_char) * 2); - return two_bit_color_type((pm.data.get()[byte_num] >> bit_position) & 3); + BOOST_STATIC_CONSTANT(int, + elements_per_char = two_bit_color_map< IndexMap >::elements_per_char); + typename property_traits< IndexMap >::value_type i = get(pm.index, key); + BOOST_ASSERT((std::size_t)i < pm.n); + std::size_t byte_num = i / elements_per_char; + std::size_t bit_position = ((i % elements_per_char) * 2); + return two_bit_color_type((pm.data.get()[byte_num] >> bit_position) & 3); } -template -inline void -put(const two_bit_color_map& pm, - typename property_traits::key_type key, +template < typename IndexMap > +inline void put(const two_bit_color_map< IndexMap >& pm, + typename property_traits< IndexMap >::key_type key, two_bit_color_type value) { - BOOST_STATIC_CONSTANT(int, elements_per_char = two_bit_color_map::elements_per_char); - typename property_traits::value_type i = get(pm.index, key); - BOOST_ASSERT ((std::size_t)i < pm.n); - BOOST_ASSERT (value >= 0 && value < 4); - std::size_t byte_num = i / elements_per_char; - std::size_t bit_position = ((i % elements_per_char) * 2); - pm.data.get()[byte_num] = - (unsigned char) - ((pm.data.get()[byte_num] & ~(3 << bit_position)) - | (value << bit_position)); + BOOST_STATIC_CONSTANT(int, + elements_per_char = two_bit_color_map< IndexMap >::elements_per_char); + typename property_traits< IndexMap >::value_type i = get(pm.index, key); + BOOST_ASSERT((std::size_t)i < pm.n); + BOOST_ASSERT(value >= 0 && value < 4); + std::size_t byte_num = i / elements_per_char; + std::size_t bit_position = ((i % elements_per_char) * 2); + pm.data.get()[byte_num] + = (unsigned char)((pm.data.get()[byte_num] & ~(3 << bit_position)) + | (value << bit_position)); } -template -inline two_bit_color_map -make_two_bit_color_map(std::size_t n, const IndexMap& index_map) +template < typename IndexMap > +inline two_bit_color_map< IndexMap > make_two_bit_color_map( + std::size_t n, const IndexMap& index_map) { - return two_bit_color_map(n, index_map); + return two_bit_color_map< IndexMap >(n, index_map); } } // end namespace boost -#include BOOST_GRAPH_MPI_INCLUDE() +#include BOOST_GRAPH_MPI_INCLUDE(< boost / graph / distributed / two_bit_color_map.hpp >) #endif // BOOST_TWO_BIT_COLOR_MAP_HPP diff --git a/include/boost/graph/two_graphs_common_spanning_trees.hpp b/include/boost/graph/two_graphs_common_spanning_trees.hpp index 48f80df17..a41dc84b2 100644 --- a/include/boost/graph/two_graphs_common_spanning_trees.hpp +++ b/include/boost/graph/two_graphs_common_spanning_trees.hpp @@ -8,11 +8,9 @@ // Efficient Algorithm for Common Spanning Tree Problem // Electron. Lett., 28 April 1983, Volume 19, Issue 9, p.346-347 - #ifndef BOOST_GRAPH_TWO_GRAPHS_COMMON_SPANNING_TREES_HPP #define BOOST_GRAPH_TWO_GRAPHS_COMMON_SPANNING_TREES_HPP - #include #include @@ -26,838 +24,829 @@ #include #include - namespace boost { +namespace detail +{ -namespace detail { - - - template - < - typename TreeMap, - typename PredMap, - typename DistMap, - typename LowMap, - typename Buffer - > - struct bridges_visitor: public default_dfs_visitor - { - bridges_visitor( - TreeMap tree, - PredMap pred, - DistMap dist, - LowMap low, - Buffer& buffer - ): mTree(tree), mPred(pred), mDist(dist), mLow(low), mBuffer(buffer) - { mNum = -1; } - - template - void initialize_vertex(const Vertex& u, const Graph& g) - { - put(mPred, u, u); - put(mDist, u, -1); - } - - template - void discover_vertex(const Vertex& u, const Graph& g) + template < typename TreeMap, typename PredMap, typename DistMap, + typename LowMap, typename Buffer > + struct bridges_visitor : public default_dfs_visitor { - put(mDist, u, ++mNum); - put(mLow, u, get(mDist, u)); - } + bridges_visitor(TreeMap tree, PredMap pred, DistMap dist, LowMap low, + Buffer& buffer) + : mTree(tree), mPred(pred), mDist(dist), mLow(low), mBuffer(buffer) + { + mNum = -1; + } - template - void tree_edge(const Edge& e, const Graph& g) - { - put(mPred, target(e, g), source(e, g)); - put(mTree, target(e, g), e); - } + template < typename Vertex, typename Graph > + void initialize_vertex(const Vertex& u, const Graph& g) + { + put(mPred, u, u); + put(mDist, u, -1); + } - template - void back_edge(const Edge& e, const Graph& g) - { - put(mLow, source(e, g), - (std::min)(get(mLow, source(e, g)), get(mDist, target(e, g)))); - } + template < typename Vertex, typename Graph > + void discover_vertex(const Vertex& u, const Graph& g) + { + put(mDist, u, ++mNum); + put(mLow, u, get(mDist, u)); + } - template - void finish_vertex(const Vertex& u, const Graph& g) - { - Vertex parent = get(mPred, u); - if(get(mLow, u) > get(mDist, parent)) - mBuffer.push(get(mTree, u)); - put(mLow, parent, - (std::min)(get(mLow, parent), get(mLow, u))); - } + template < typename Edge, typename Graph > + void tree_edge(const Edge& e, const Graph& g) + { + put(mPred, target(e, g), source(e, g)); + put(mTree, target(e, g), e); + } - TreeMap mTree; - PredMap mPred; - DistMap mDist; - LowMap mLow; - Buffer& mBuffer; - int mNum; - }; - - - template - struct cycle_finder: public base_visitor< cycle_finder > - { - typedef on_back_edge event_filter; - cycle_finder(): mBuffer(0) { } - cycle_finder(Buffer* buffer) - : mBuffer(buffer) { } - template - void operator()(const Edge& e, const Graph& g) - { - if(mBuffer) - mBuffer->push(e); - } - Buffer* mBuffer; - }; - - - template - struct deleted_edge_status - { - deleted_edge_status() { } - deleted_edge_status(DeletedMap map): mMap(map) { } - template - bool operator()(const Edge& e) const - { return (!get(mMap, e)); } - DeletedMap mMap; - }; - - - template - struct inL_edge_status - { - inL_edge_status() { } - inL_edge_status(InLMap map): mMap(map) { } - template - bool operator()(const Edge& e) const - { return get(mMap, e); } - InLMap mMap; - }; - - - template < - typename Graph, - typename Func, - typename Seq, - typename Map - > - void rec_two_graphs_common_spanning_trees - ( - const Graph& iG, - bimap< - bimaps::set_of, - bimaps::set_of< typename graph_traits::edge_descriptor > - > iG_bimap, - Map aiG_inL, - Map diG, - const Graph& vG, - bimap< - bimaps::set_of, - bimaps::set_of< typename graph_traits::edge_descriptor > - > vG_bimap, - Map avG_inL, - Map dvG, - Func func, - Seq inL - ) - { - typedef graph_traits GraphTraits; + template < typename Edge, typename Graph > + void back_edge(const Edge& e, const Graph& g) + { + put(mLow, source(e, g), + (std::min)(get(mLow, source(e, g)), get(mDist, target(e, g)))); + } - typedef typename GraphTraits::vertex_descriptor vertex_descriptor; - typedef typename GraphTraits::edge_descriptor edge_descriptor; + template < typename Vertex, typename Graph > + void finish_vertex(const Vertex& u, const Graph& g) + { + Vertex parent = get(mPred, u); + if (get(mLow, u) > get(mDist, parent)) + mBuffer.push(get(mTree, u)); + put(mLow, parent, (std::min)(get(mLow, parent), get(mLow, u))); + } - typedef typename Seq::size_type seq_size_type; + TreeMap mTree; + PredMap mPred; + DistMap mDist; + LowMap mLow; + Buffer& mBuffer; + int mNum; + }; - int edges = num_vertices(iG) - 1; -// -// [ Michele Caini ] -// -// Using the condition (edges != 0) leads to the accidental submission of -// sub-graphs ((V-1+1)-fake-tree, named here fat-tree). -// Remove this condition is a workaround for the problem of fat-trees. -// Please do not add that condition, even if it improves performance. -// -// Here is proposed the previous guard (that was wrong): -// for(seq_size_type i = 0; (i < inL.size()) && (edges != 0); ++i) -// + template < typename Buffer > + struct cycle_finder : public base_visitor< cycle_finder< Buffer > > { - for(seq_size_type i = 0; i < inL.size(); ++i) - if(inL[i]) - --edges; - - if(edges < 0) - return; - } - - bool is_tree = (edges == 0); - if(is_tree) { - func(inL); - } else { - std::map vertex_color; - std::map edge_color; - - std::stack iG_buf, vG_buf; - bool found = false; - - seq_size_type m; - for(seq_size_type j = 0; j < inL.size() && !found; ++j) { - if(!inL[j] - && !get(diG, iG_bimap.left.at(j)) - && !get(dvG, vG_bimap.left.at(j))) + typedef on_back_edge event_filter; + cycle_finder() : mBuffer(0) {} + cycle_finder(Buffer* buffer) : mBuffer(buffer) {} + template < typename Edge, typename Graph > + void operator()(const Edge& e, const Graph& g) { - put(aiG_inL, iG_bimap.left.at(j), true); - put(avG_inL, vG_bimap.left.at(j), true); - - undirected_dfs( - make_filtered_graph(iG, - detail::inL_edge_status< associative_property_map< - std::map > >(aiG_inL)), - make_dfs_visitor( - detail::cycle_finder< std::stack > (&iG_buf)), - associative_property_map< - std::map >(vertex_color), - associative_property_map< - std::map >(edge_color) - ); - undirected_dfs( - make_filtered_graph(vG, - detail::inL_edge_status< associative_property_map< - std::map > >(avG_inL)), - make_dfs_visitor( - detail::cycle_finder< std::stack > (&vG_buf)), - associative_property_map< - std::map >(vertex_color), - associative_property_map< - std::map >(edge_color) - ); - - if(iG_buf.empty() && vG_buf.empty()) { - inL[j] = true; - found = true; - m = j; - } else { - while(!iG_buf.empty()) iG_buf.pop(); - while(!vG_buf.empty()) vG_buf.pop(); - put(aiG_inL, iG_bimap.left.at(j), false); - put(avG_inL, vG_bimap.left.at(j), false); - } + if (mBuffer) + mBuffer->push(e); } - } - - if(found) { - - std::stack iG_buf_copy, vG_buf_copy; - for(seq_size_type j = 0; j < inL.size(); ++j) { - if(!inL[j] - && !get(diG, iG_bimap.left.at(j)) - && !get(dvG, vG_bimap.left.at(j))) - { - - put(aiG_inL, iG_bimap.left.at(j), true); - put(avG_inL, vG_bimap.left.at(j), true); - - undirected_dfs( - make_filtered_graph(iG, - detail::inL_edge_status< associative_property_map< - std::map > >(aiG_inL)), - make_dfs_visitor( - detail::cycle_finder< - std::stack > (&iG_buf)), - associative_property_map< std::map< - vertex_descriptor, default_color_type> >(vertex_color), - associative_property_map< - std::map >(edge_color) - ); - undirected_dfs( - make_filtered_graph(vG, - detail::inL_edge_status< associative_property_map< - std::map > >(avG_inL)), - make_dfs_visitor( - detail::cycle_finder< - std::stack > (&vG_buf)), - associative_property_map< std::map< - vertex_descriptor, default_color_type> >(vertex_color), - associative_property_map< - std::map >(edge_color) - ); - - if(!iG_buf.empty() || !vG_buf.empty()) { - while(!iG_buf.empty()) iG_buf.pop(); - while(!vG_buf.empty()) vG_buf.pop(); - put(diG, iG_bimap.left.at(j), true); - put(dvG, vG_bimap.left.at(j), true); - iG_buf_copy.push(iG_bimap.left.at(j)); - vG_buf_copy.push(vG_bimap.left.at(j)); - } + Buffer* mBuffer; + }; - put(aiG_inL, iG_bimap.left.at(j), false); - put(avG_inL, vG_bimap.left.at(j), false); - } + template < typename DeletedMap > struct deleted_edge_status + { + deleted_edge_status() {} + deleted_edge_status(DeletedMap map) : mMap(map) {} + template < typename Edge > bool operator()(const Edge& e) const + { + return (!get(mMap, e)); } + DeletedMap mMap; + }; - // REC - detail::rec_two_graphs_common_spanning_trees - (iG, iG_bimap, aiG_inL, diG, vG, vG_bimap, aiG_inL, dvG, func, inL); - - while(!iG_buf_copy.empty()) { - put(diG, iG_buf_copy.top(), false); - put(dvG, vG_bimap.left.at( - iG_bimap.right.at(iG_buf_copy.top())), false); - iG_buf_copy.pop(); - } - while(!vG_buf_copy.empty()) { - put(dvG, vG_buf_copy.top(), false); - put(diG, iG_bimap.left.at( - vG_bimap.right.at(vG_buf_copy.top())), false); - vG_buf_copy.pop(); + template < typename InLMap > struct inL_edge_status + { + inL_edge_status() {} + inL_edge_status(InLMap map) : mMap(map) {} + template < typename Edge > bool operator()(const Edge& e) const + { + return get(mMap, e); } + InLMap mMap; + }; + + template < typename Graph, typename Func, typename Seq, typename Map > + void rec_two_graphs_common_spanning_trees(const Graph& iG, + bimap< bimaps::set_of< int >, + bimaps::set_of< typename graph_traits< Graph >::edge_descriptor > > + iG_bimap, + Map aiG_inL, Map diG, const Graph& vG, + bimap< bimaps::set_of< int >, + bimaps::set_of< typename graph_traits< Graph >::edge_descriptor > > + vG_bimap, + Map avG_inL, Map dvG, Func func, Seq inL) + { + typedef graph_traits< Graph > GraphTraits; + + typedef typename GraphTraits::vertex_descriptor vertex_descriptor; + typedef typename GraphTraits::edge_descriptor edge_descriptor; + + typedef typename Seq::size_type seq_size_type; + + int edges = num_vertices(iG) - 1; + // + // [ Michele Caini ] + // + // Using the condition (edges != 0) leads to the accidental submission + // of + // sub-graphs ((V-1+1)-fake-tree, named here fat-tree). + // Remove this condition is a workaround for the problem of fat-trees. + // Please do not add that condition, even if it improves performance. + // + // Here is proposed the previous guard (that was wrong): + // for(seq_size_type i = 0; (i < inL.size()) && (edges != 0); ++i) + // + { + for (seq_size_type i = 0; i < inL.size(); ++i) + if (inL[i]) + --edges; - inL[m] = false; - put(aiG_inL, iG_bimap.left.at(m), false); - put(avG_inL, vG_bimap.left.at(m), false); - - put(diG, iG_bimap.left.at(m), true); - put(dvG, vG_bimap.left.at(m), true); - - std::map tree_map; - std::map pred_map; - std::map dist_map, low_map; - - detail::bridges_visitor< - associative_property_map< - std::map - >, - associative_property_map< - std::map - >, - associative_property_map< std::map >, - associative_property_map< std::map >, - std::stack - > - iG_vis( - associative_property_map< - std::map< vertex_descriptor, edge_descriptor> >(tree_map), - associative_property_map< - std::map< vertex_descriptor, vertex_descriptor> >(pred_map), - associative_property_map< - std::map< vertex_descriptor, int> >(dist_map), - associative_property_map< - std::map< vertex_descriptor, int> >(low_map), - iG_buf - ), - vG_vis( - associative_property_map< - std::map< vertex_descriptor, edge_descriptor> >(tree_map), - associative_property_map< - std::map< vertex_descriptor, vertex_descriptor> >(pred_map), - associative_property_map< - std::map< vertex_descriptor, int> >(dist_map), - associative_property_map< - std::map< vertex_descriptor, int> >(low_map), - vG_buf - ); - - undirected_dfs(make_filtered_graph(iG, - detail::deleted_edge_status< associative_property_map< - std::map > >(diG)), - iG_vis, - associative_property_map< - std::map >(vertex_color), - associative_property_map< - std::map >(edge_color) - ); - undirected_dfs(make_filtered_graph(vG, - detail::deleted_edge_status< associative_property_map< - std::map > >(dvG)), - vG_vis, - associative_property_map< - std::map >(vertex_color), - associative_property_map< - std::map >(edge_color) - ); - - found = false; - std::stack iG_buf_tmp, vG_buf_tmp; - while(!iG_buf.empty() && !found) { - if(!inL[iG_bimap.right.at(iG_buf.top())]) { - put(aiG_inL, iG_buf.top(), true); - put(avG_inL, vG_bimap.left.at( - iG_bimap.right.at(iG_buf.top())), true); - - undirected_dfs( - make_filtered_graph(iG, - detail::inL_edge_status< associative_property_map< - std::map > >(aiG_inL)), - make_dfs_visitor( - detail::cycle_finder< - std::stack > (&iG_buf_tmp)), - associative_property_map< - std::map< - vertex_descriptor, default_color_type> >(vertex_color), - associative_property_map< - std::map >(edge_color) - ); - undirected_dfs( - make_filtered_graph(vG, - detail::inL_edge_status< associative_property_map< - std::map > >(avG_inL)), - make_dfs_visitor( - detail::cycle_finder< - std::stack > (&vG_buf_tmp)), - associative_property_map< - std::map< - vertex_descriptor, default_color_type> >(vertex_color), - associative_property_map< - std::map >(edge_color) - ); - - if(!iG_buf_tmp.empty() || !vG_buf_tmp.empty()) { - found = true; - } else { - while(!iG_buf_tmp.empty()) iG_buf_tmp.pop(); - while(!vG_buf_tmp.empty()) vG_buf_tmp.pop(); - iG_buf_copy.push(iG_buf.top()); - } + if (edges < 0) + return; + } - put(aiG_inL, iG_buf.top(), false); - put(avG_inL, vG_bimap.left.at( - iG_bimap.right.at(iG_buf.top())), false); - } - iG_buf.pop(); + bool is_tree = (edges == 0); + if (is_tree) + { + func(inL); } - while(!vG_buf.empty() && !found) { - if(!inL[vG_bimap.right.at(vG_buf.top())]) { - put(avG_inL, vG_buf.top(), true); - put(aiG_inL, iG_bimap.left.at( - vG_bimap.right.at(vG_buf.top())), true); - - undirected_dfs( - make_filtered_graph(iG, - detail::inL_edge_status< associative_property_map< - std::map > >(aiG_inL)), - make_dfs_visitor( - detail::cycle_finder< - std::stack > (&iG_buf_tmp)), - associative_property_map< - std::map< - vertex_descriptor, default_color_type> >(vertex_color), - associative_property_map< - std::map >(edge_color) - ); - undirected_dfs( - make_filtered_graph(vG, - detail::inL_edge_status< associative_property_map< - std::map > >(avG_inL)), - make_dfs_visitor( - detail::cycle_finder< - std::stack > (&vG_buf_tmp)), - associative_property_map< - std::map< - vertex_descriptor, default_color_type> >(vertex_color), - associative_property_map< - std::map >(edge_color) - ); - - if(!iG_buf_tmp.empty() || !vG_buf_tmp.empty()) { - found = true; - } else { - while(!iG_buf_tmp.empty()) iG_buf_tmp.pop(); - while(!vG_buf_tmp.empty()) vG_buf_tmp.pop(); - vG_buf_copy.push(vG_buf.top()); + else + { + std::map< vertex_descriptor, default_color_type > vertex_color; + std::map< edge_descriptor, default_color_type > edge_color; + + std::stack< edge_descriptor > iG_buf, vG_buf; + bool found = false; + + seq_size_type m; + for (seq_size_type j = 0; j < inL.size() && !found; ++j) + { + if (!inL[j] && !get(diG, iG_bimap.left.at(j)) + && !get(dvG, vG_bimap.left.at(j))) + { + put(aiG_inL, iG_bimap.left.at(j), true); + put(avG_inL, vG_bimap.left.at(j), true); + + undirected_dfs( + make_filtered_graph(iG, + detail::inL_edge_status< associative_property_map< + std::map< edge_descriptor, bool > > >(aiG_inL)), + make_dfs_visitor(detail::cycle_finder< + std::stack< edge_descriptor > >(&iG_buf)), + associative_property_map< + std::map< vertex_descriptor, default_color_type > >( + vertex_color), + associative_property_map< + std::map< edge_descriptor, default_color_type > >( + edge_color)); + undirected_dfs( + make_filtered_graph(vG, + detail::inL_edge_status< associative_property_map< + std::map< edge_descriptor, bool > > >(avG_inL)), + make_dfs_visitor(detail::cycle_finder< + std::stack< edge_descriptor > >(&vG_buf)), + associative_property_map< + std::map< vertex_descriptor, default_color_type > >( + vertex_color), + associative_property_map< + std::map< edge_descriptor, default_color_type > >( + edge_color)); + + if (iG_buf.empty() && vG_buf.empty()) + { + inL[j] = true; + found = true; + m = j; + } + else + { + while (!iG_buf.empty()) + iG_buf.pop(); + while (!vG_buf.empty()) + vG_buf.pop(); + put(aiG_inL, iG_bimap.left.at(j), false); + put(avG_inL, vG_bimap.left.at(j), false); + } + } } - put(avG_inL, vG_buf.top(), false); - put(aiG_inL, iG_bimap.left.at( - vG_bimap.right.at(vG_buf.top())), false); - } - vG_buf.pop(); + if (found) + { + + std::stack< edge_descriptor > iG_buf_copy, vG_buf_copy; + for (seq_size_type j = 0; j < inL.size(); ++j) + { + if (!inL[j] && !get(diG, iG_bimap.left.at(j)) + && !get(dvG, vG_bimap.left.at(j))) + { + + put(aiG_inL, iG_bimap.left.at(j), true); + put(avG_inL, vG_bimap.left.at(j), true); + + undirected_dfs( + make_filtered_graph(iG, + detail::inL_edge_status< + associative_property_map< + std::map< edge_descriptor, bool > > >( + aiG_inL)), + make_dfs_visitor(detail::cycle_finder< + std::stack< edge_descriptor > >(&iG_buf)), + associative_property_map< std::map< + vertex_descriptor, default_color_type > >( + vertex_color), + associative_property_map< std::map< edge_descriptor, + default_color_type > >(edge_color)); + undirected_dfs( + make_filtered_graph(vG, + detail::inL_edge_status< + associative_property_map< + std::map< edge_descriptor, bool > > >( + avG_inL)), + make_dfs_visitor(detail::cycle_finder< + std::stack< edge_descriptor > >(&vG_buf)), + associative_property_map< std::map< + vertex_descriptor, default_color_type > >( + vertex_color), + associative_property_map< std::map< edge_descriptor, + default_color_type > >(edge_color)); + + if (!iG_buf.empty() || !vG_buf.empty()) + { + while (!iG_buf.empty()) + iG_buf.pop(); + while (!vG_buf.empty()) + vG_buf.pop(); + put(diG, iG_bimap.left.at(j), true); + put(dvG, vG_bimap.left.at(j), true); + iG_buf_copy.push(iG_bimap.left.at(j)); + vG_buf_copy.push(vG_bimap.left.at(j)); + } + + put(aiG_inL, iG_bimap.left.at(j), false); + put(avG_inL, vG_bimap.left.at(j), false); + } + } + + // REC + detail::rec_two_graphs_common_spanning_trees< Graph, Func, Seq, + Map >(iG, iG_bimap, aiG_inL, diG, vG, vG_bimap, aiG_inL, + dvG, func, inL); + + while (!iG_buf_copy.empty()) + { + put(diG, iG_buf_copy.top(), false); + put(dvG, + vG_bimap.left.at(iG_bimap.right.at(iG_buf_copy.top())), + false); + iG_buf_copy.pop(); + } + while (!vG_buf_copy.empty()) + { + put(dvG, vG_buf_copy.top(), false); + put(diG, + iG_bimap.left.at(vG_bimap.right.at(vG_buf_copy.top())), + false); + vG_buf_copy.pop(); + } + + inL[m] = false; + put(aiG_inL, iG_bimap.left.at(m), false); + put(avG_inL, vG_bimap.left.at(m), false); + + put(diG, iG_bimap.left.at(m), true); + put(dvG, vG_bimap.left.at(m), true); + + std::map< vertex_descriptor, edge_descriptor > tree_map; + std::map< vertex_descriptor, vertex_descriptor > pred_map; + std::map< vertex_descriptor, int > dist_map, low_map; + + detail::bridges_visitor< + associative_property_map< + std::map< vertex_descriptor, edge_descriptor > >, + associative_property_map< + std::map< vertex_descriptor, vertex_descriptor > >, + associative_property_map< + std::map< vertex_descriptor, int > >, + associative_property_map< + std::map< vertex_descriptor, int > >, + std::stack< edge_descriptor > > + iG_vis(associative_property_map< + std::map< vertex_descriptor, edge_descriptor > >( + tree_map), + associative_property_map< + std::map< vertex_descriptor, vertex_descriptor > >( + pred_map), + associative_property_map< + std::map< vertex_descriptor, int > >(dist_map), + associative_property_map< + std::map< vertex_descriptor, int > >(low_map), + iG_buf), + vG_vis(associative_property_map< + std::map< vertex_descriptor, edge_descriptor > >( + tree_map), + associative_property_map< + std::map< vertex_descriptor, vertex_descriptor > >( + pred_map), + associative_property_map< + std::map< vertex_descriptor, int > >(dist_map), + associative_property_map< + std::map< vertex_descriptor, int > >(low_map), + vG_buf); + + undirected_dfs( + make_filtered_graph(iG, + detail::deleted_edge_status< associative_property_map< + std::map< edge_descriptor, bool > > >(diG)), + iG_vis, + associative_property_map< + std::map< vertex_descriptor, default_color_type > >( + vertex_color), + associative_property_map< + std::map< edge_descriptor, default_color_type > >( + edge_color)); + undirected_dfs( + make_filtered_graph(vG, + detail::deleted_edge_status< associative_property_map< + std::map< edge_descriptor, bool > > >(dvG)), + vG_vis, + associative_property_map< + std::map< vertex_descriptor, default_color_type > >( + vertex_color), + associative_property_map< + std::map< edge_descriptor, default_color_type > >( + edge_color)); + + found = false; + std::stack< edge_descriptor > iG_buf_tmp, vG_buf_tmp; + while (!iG_buf.empty() && !found) + { + if (!inL[iG_bimap.right.at(iG_buf.top())]) + { + put(aiG_inL, iG_buf.top(), true); + put(avG_inL, + vG_bimap.left.at(iG_bimap.right.at(iG_buf.top())), + true); + + undirected_dfs( + make_filtered_graph(iG, + detail::inL_edge_status< + associative_property_map< + std::map< edge_descriptor, bool > > >( + aiG_inL)), + make_dfs_visitor(detail::cycle_finder< + std::stack< edge_descriptor > >(&iG_buf_tmp)), + associative_property_map< std::map< + vertex_descriptor, default_color_type > >( + vertex_color), + associative_property_map< std::map< edge_descriptor, + default_color_type > >(edge_color)); + undirected_dfs( + make_filtered_graph(vG, + detail::inL_edge_status< + associative_property_map< + std::map< edge_descriptor, bool > > >( + avG_inL)), + make_dfs_visitor(detail::cycle_finder< + std::stack< edge_descriptor > >(&vG_buf_tmp)), + associative_property_map< std::map< + vertex_descriptor, default_color_type > >( + vertex_color), + associative_property_map< std::map< edge_descriptor, + default_color_type > >(edge_color)); + + if (!iG_buf_tmp.empty() || !vG_buf_tmp.empty()) + { + found = true; + } + else + { + while (!iG_buf_tmp.empty()) + iG_buf_tmp.pop(); + while (!vG_buf_tmp.empty()) + vG_buf_tmp.pop(); + iG_buf_copy.push(iG_buf.top()); + } + + put(aiG_inL, iG_buf.top(), false); + put(avG_inL, + vG_bimap.left.at(iG_bimap.right.at(iG_buf.top())), + false); + } + iG_buf.pop(); + } + while (!vG_buf.empty() && !found) + { + if (!inL[vG_bimap.right.at(vG_buf.top())]) + { + put(avG_inL, vG_buf.top(), true); + put(aiG_inL, + iG_bimap.left.at(vG_bimap.right.at(vG_buf.top())), + true); + + undirected_dfs( + make_filtered_graph(iG, + detail::inL_edge_status< + associative_property_map< + std::map< edge_descriptor, bool > > >( + aiG_inL)), + make_dfs_visitor(detail::cycle_finder< + std::stack< edge_descriptor > >(&iG_buf_tmp)), + associative_property_map< std::map< + vertex_descriptor, default_color_type > >( + vertex_color), + associative_property_map< std::map< edge_descriptor, + default_color_type > >(edge_color)); + undirected_dfs( + make_filtered_graph(vG, + detail::inL_edge_status< + associative_property_map< + std::map< edge_descriptor, bool > > >( + avG_inL)), + make_dfs_visitor(detail::cycle_finder< + std::stack< edge_descriptor > >(&vG_buf_tmp)), + associative_property_map< std::map< + vertex_descriptor, default_color_type > >( + vertex_color), + associative_property_map< std::map< edge_descriptor, + default_color_type > >(edge_color)); + + if (!iG_buf_tmp.empty() || !vG_buf_tmp.empty()) + { + found = true; + } + else + { + while (!iG_buf_tmp.empty()) + iG_buf_tmp.pop(); + while (!vG_buf_tmp.empty()) + vG_buf_tmp.pop(); + vG_buf_copy.push(vG_buf.top()); + } + + put(avG_inL, vG_buf.top(), false); + put(aiG_inL, + iG_bimap.left.at(vG_bimap.right.at(vG_buf.top())), + false); + } + vG_buf.pop(); + } + + if (!found) + { + + while (!iG_buf_copy.empty()) + { + inL[iG_bimap.right.at(iG_buf_copy.top())] = true; + put(aiG_inL, iG_buf_copy.top(), true); + put(avG_inL, + vG_bimap.left.at( + iG_bimap.right.at(iG_buf_copy.top())), + true); + iG_buf.push(iG_buf_copy.top()); + iG_buf_copy.pop(); + } + while (!vG_buf_copy.empty()) + { + inL[vG_bimap.right.at(vG_buf_copy.top())] = true; + put(avG_inL, vG_buf_copy.top(), true); + put(aiG_inL, + iG_bimap.left.at( + vG_bimap.right.at(vG_buf_copy.top())), + true); + vG_buf.push(vG_buf_copy.top()); + vG_buf_copy.pop(); + } + + // REC + detail::rec_two_graphs_common_spanning_trees< Graph, Func, + Seq, Map >(iG, iG_bimap, aiG_inL, diG, vG, vG_bimap, + aiG_inL, dvG, func, inL); + + while (!iG_buf.empty()) + { + inL[iG_bimap.right.at(iG_buf.top())] = false; + put(aiG_inL, iG_buf.top(), false); + put(avG_inL, + vG_bimap.left.at(iG_bimap.right.at(iG_buf.top())), + false); + iG_buf.pop(); + } + while (!vG_buf.empty()) + { + inL[vG_bimap.right.at(vG_buf.top())] = false; + put(avG_inL, vG_buf.top(), false); + put(aiG_inL, + iG_bimap.left.at(vG_bimap.right.at(vG_buf.top())), + false); + vG_buf.pop(); + } + } + + put(diG, iG_bimap.left.at(m), false); + put(dvG, vG_bimap.left.at(m), false); + } } + } - if(!found) { - - while(!iG_buf_copy.empty()) { - inL[iG_bimap.right.at(iG_buf_copy.top())] = true; - put(aiG_inL, iG_buf_copy.top(), true); - put(avG_inL, vG_bimap.left.at( - iG_bimap.right.at(iG_buf_copy.top())), true); - iG_buf.push(iG_buf_copy.top()); - iG_buf_copy.pop(); - } - while(!vG_buf_copy.empty()) { - inL[vG_bimap.right.at(vG_buf_copy.top())] = true; - put(avG_inL, vG_buf_copy.top(), true); - put(aiG_inL, iG_bimap.left.at( - vG_bimap.right.at(vG_buf_copy.top())), true); - vG_buf.push(vG_buf_copy.top()); - vG_buf_copy.pop(); - } - - // REC - detail::rec_two_graphs_common_spanning_trees< - Graph, Func, Seq, Map> - (iG, iG_bimap, aiG_inL, diG, vG, vG_bimap, aiG_inL, dvG, func, inL); - - while(!iG_buf.empty()) { - inL[iG_bimap.right.at(iG_buf.top())] = false; - put(aiG_inL, iG_buf.top(), false); - put(avG_inL, vG_bimap.left.at( - iG_bimap.right.at(iG_buf.top())), false); - iG_buf.pop(); - } - while(!vG_buf.empty()) { - inL[vG_bimap.right.at(vG_buf.top())] = false; - put(avG_inL, vG_buf.top(), false); - put(aiG_inL, iG_bimap.left.at( - vG_bimap.right.at(vG_buf.top())), false); - vG_buf.pop(); - } +} // namespace detail - } +template < typename Coll, typename Seq > struct tree_collector +{ - put(diG, iG_bimap.left.at(m), false); - put(dvG, vG_bimap.left.at(m), false); +public: + BOOST_CONCEPT_ASSERT((BackInsertionSequence< Coll >)); + BOOST_CONCEPT_ASSERT((RandomAccessContainer< Seq >)); + BOOST_CONCEPT_ASSERT((CopyConstructible< Seq >)); - } - } - } + typedef typename Coll::value_type coll_value_type; + typedef typename Seq::value_type seq_value_type; -} // namespace detail + BOOST_STATIC_ASSERT((is_same< coll_value_type, Seq >::value)); + BOOST_STATIC_ASSERT((is_same< seq_value_type, bool >::value)); + tree_collector(Coll& seqs) : mSeqs(seqs) {} + inline void operator()(Seq seq) { mSeqs.push_back(seq); } -template -struct tree_collector +private: + Coll& mSeqs; +}; + +template < typename Graph, typename Order, typename Func, typename Seq > +BOOST_CONCEPT_REQUIRES( + ((RandomAccessContainer< Order >))((IncidenceGraphConcept< Graph >))( + (UnaryFunction< Func, void, Seq >))( + (Mutable_RandomAccessContainer< Seq >))( + (VertexAndEdgeListGraphConcept< Graph >)), + (void)) +two_graphs_common_spanning_trees(const Graph& iG, Order iG_map, const Graph& vG, + Order vG_map, Func func, Seq inL) { + typedef graph_traits< Graph > GraphTraits; -public: - BOOST_CONCEPT_ASSERT((BackInsertionSequence)); - BOOST_CONCEPT_ASSERT((RandomAccessContainer)); - BOOST_CONCEPT_ASSERT((CopyConstructible)); + typedef typename GraphTraits::directed_category directed_category; + typedef typename GraphTraits::vertex_descriptor vertex_descriptor; + typedef typename GraphTraits::edge_descriptor edge_descriptor; - typedef typename Coll::value_type coll_value_type; - typedef typename Seq::value_type seq_value_type; + typedef typename GraphTraits::edges_size_type edges_size_type; + typedef typename GraphTraits::edge_iterator edge_iterator; - BOOST_STATIC_ASSERT((is_same::value)); - BOOST_STATIC_ASSERT((is_same::value)); + typedef typename Seq::value_type seq_value_type; + typedef typename Seq::size_type seq_size_type; - tree_collector(Coll& seqs): mSeqs(seqs) { } + typedef typename Order::value_type order_value_type; + typedef typename Order::size_type order_size_type; - inline void operator()(Seq seq) - { mSeqs.push_back(seq); } + BOOST_STATIC_ASSERT((is_same< order_value_type, edge_descriptor >::value)); + BOOST_CONCEPT_ASSERT((Convertible< order_size_type, edges_size_type >)); -private: - Coll& mSeqs; + BOOST_CONCEPT_ASSERT((Convertible< seq_size_type, edges_size_type >)); + BOOST_STATIC_ASSERT((is_same< seq_value_type, bool >::value)); -}; + BOOST_STATIC_ASSERT((is_same< directed_category, undirected_tag >::value)); + if (num_vertices(iG) != num_vertices(vG)) + return; + if (inL.size() != num_edges(iG) || inL.size() != num_edges(vG)) + return; -template < - typename Graph, - typename Order, - typename Func, - typename Seq -> -BOOST_CONCEPT_REQUIRES( - ((RandomAccessContainer)) - ((IncidenceGraphConcept)) - ((UnaryFunction)) - ((Mutable_RandomAccessContainer)) - ((VertexAndEdgeListGraphConcept)), - (void) -) -two_graphs_common_spanning_trees - ( - const Graph& iG, - Order iG_map, - const Graph& vG, - Order vG_map, - Func func, - Seq inL - ) -{ - typedef graph_traits GraphTraits; - - typedef typename GraphTraits::directed_category directed_category; - typedef typename GraphTraits::vertex_descriptor vertex_descriptor; - typedef typename GraphTraits::edge_descriptor edge_descriptor; - - typedef typename GraphTraits::edges_size_type edges_size_type; - typedef typename GraphTraits::edge_iterator edge_iterator; - - typedef typename Seq::value_type seq_value_type; - typedef typename Seq::size_type seq_size_type; - - typedef typename Order::value_type order_value_type; - typedef typename Order::size_type order_size_type; - - BOOST_STATIC_ASSERT((is_same::value)); - BOOST_CONCEPT_ASSERT((Convertible)); - - BOOST_CONCEPT_ASSERT((Convertible)); - BOOST_STATIC_ASSERT((is_same::value)); - - BOOST_STATIC_ASSERT((is_same::value)); - - if(num_vertices(iG) != num_vertices(vG)) - return; - - if(inL.size() != num_edges(iG) - || inL.size() != num_edges(vG)) - return; - - if(iG_map.size() != num_edges(iG) - || vG_map.size() != num_edges(vG)) - return; - - typedef bimaps::bimap< - bimaps::set_of< int >, - bimaps::set_of< order_value_type > - > bimap_type; - typedef typename bimap_type::value_type bimap_value; - - bimap_type iG_bimap, vG_bimap; - for(order_size_type i = 0; i < iG_map.size(); ++i) - iG_bimap.insert(bimap_value(i, iG_map[i])); - for(order_size_type i = 0; i < vG_map.size(); ++i) - vG_bimap.insert(bimap_value(i, vG_map[i])); - - edge_iterator current, last; - boost::tuples::tie(current, last) = edges(iG); - for(; current != last; ++current) - if(iG_bimap.right.find(*current) == iG_bimap.right.end()) - return; - boost::tuples::tie(current, last) = edges(vG); - for(; current != last; ++current) - if(vG_bimap.right.find(*current) == vG_bimap.right.end()) - return; - - std::stack iG_buf, vG_buf; - - std::map tree_map; - std::map pred_map; - std::map dist_map, low_map; - - detail::bridges_visitor< - associative_property_map< - std::map - >, - associative_property_map< - std::map - >, - associative_property_map< std::map >, - associative_property_map< std::map >, - std::stack - > - iG_vis( - associative_property_map< - std::map< vertex_descriptor, edge_descriptor> >(tree_map), - associative_property_map< - std::map< vertex_descriptor, vertex_descriptor> >(pred_map), - associative_property_map >(dist_map), - associative_property_map >(low_map), - iG_buf - ), - vG_vis( - associative_property_map< - std::map< vertex_descriptor, edge_descriptor> >(tree_map), - associative_property_map< - std::map< vertex_descriptor, vertex_descriptor> >(pred_map), - associative_property_map >(dist_map), - associative_property_map >(low_map), - vG_buf - ); - - std::map vertex_color; - std::map edge_color; - - undirected_dfs(iG, iG_vis, - associative_property_map< - std::map >(vertex_color), - associative_property_map< - std::map >(edge_color) - ); - undirected_dfs(vG, vG_vis, - associative_property_map< - std::map >(vertex_color), - associative_property_map< - std::map >(edge_color) - ); - - while(!iG_buf.empty()) { - inL[iG_bimap.right.at(iG_buf.top())] = true; - iG_buf.pop(); - } - while(!vG_buf.empty()) { - inL[vG_bimap.right.at(vG_buf.top())] = true; - vG_buf.pop(); - } - - std::map iG_inL, vG_inL; - associative_property_map< std::map > - aiG_inL(iG_inL), avG_inL(vG_inL); - - for(seq_size_type i = 0; i < inL.size(); ++i) - { - if(inL[i]) { - put(aiG_inL, iG_bimap.left.at(i), true); - put(avG_inL, vG_bimap.left.at(i), true); - } else { - put(aiG_inL, iG_bimap.left.at(i), false); - put(avG_inL, vG_bimap.left.at(i), false); - } - } - - undirected_dfs( - make_filtered_graph(iG, - detail::inL_edge_status< associative_property_map< - std::map > >(aiG_inL)), - make_dfs_visitor( - detail::cycle_finder< std::stack > (&iG_buf)), - associative_property_map< - std::map >(vertex_color), - associative_property_map< - std::map >(edge_color) - ); - undirected_dfs( - make_filtered_graph(vG, - detail::inL_edge_status< associative_property_map< - std::map > >(avG_inL)), - make_dfs_visitor( - detail::cycle_finder< std::stack > (&vG_buf)), - associative_property_map< - std::map >(vertex_color), - associative_property_map< - std::map >(edge_color) - ); - - if(iG_buf.empty() && vG_buf.empty()) { - - std::map iG_deleted, vG_deleted; - associative_property_map< std::map > diG(iG_deleted); - associative_property_map< std::map > dvG(vG_deleted); + if (iG_map.size() != num_edges(iG) || vG_map.size() != num_edges(vG)) + return; + + typedef bimaps::bimap< bimaps::set_of< int >, + bimaps::set_of< order_value_type > > + bimap_type; + typedef typename bimap_type::value_type bimap_value; + bimap_type iG_bimap, vG_bimap; + for (order_size_type i = 0; i < iG_map.size(); ++i) + iG_bimap.insert(bimap_value(i, iG_map[i])); + for (order_size_type i = 0; i < vG_map.size(); ++i) + vG_bimap.insert(bimap_value(i, vG_map[i])); + + edge_iterator current, last; boost::tuples::tie(current, last) = edges(iG); - for(; current != last; ++current) - put(diG, *current, false); + for (; current != last; ++current) + if (iG_bimap.right.find(*current) == iG_bimap.right.end()) + return; boost::tuples::tie(current, last) = edges(vG); - for(; current != last; ++current) - put(dvG, *current, false); + for (; current != last; ++current) + if (vG_bimap.right.find(*current) == vG_bimap.right.end()) + return; + + std::stack< edge_descriptor > iG_buf, vG_buf; + + std::map< vertex_descriptor, edge_descriptor > tree_map; + std::map< vertex_descriptor, vertex_descriptor > pred_map; + std::map< vertex_descriptor, int > dist_map, low_map; + + detail::bridges_visitor< associative_property_map< std::map< + vertex_descriptor, edge_descriptor > >, + associative_property_map< + std::map< vertex_descriptor, vertex_descriptor > >, + associative_property_map< std::map< vertex_descriptor, int > >, + associative_property_map< std::map< vertex_descriptor, int > >, + std::stack< edge_descriptor > > + iG_vis(associative_property_map< + std::map< vertex_descriptor, edge_descriptor > >(tree_map), + associative_property_map< + std::map< vertex_descriptor, vertex_descriptor > >(pred_map), + associative_property_map< std::map< vertex_descriptor, int > >( + dist_map), + associative_property_map< std::map< vertex_descriptor, int > >(low_map), + iG_buf), + vG_vis(associative_property_map< + std::map< vertex_descriptor, edge_descriptor > >(tree_map), + associative_property_map< + std::map< vertex_descriptor, vertex_descriptor > >(pred_map), + associative_property_map< std::map< vertex_descriptor, int > >( + dist_map), + associative_property_map< std::map< vertex_descriptor, int > >( + low_map), + vG_buf); + + std::map< vertex_descriptor, default_color_type > vertex_color; + std::map< edge_descriptor, default_color_type > edge_color; + + undirected_dfs(iG, iG_vis, + associative_property_map< + std::map< vertex_descriptor, default_color_type > >(vertex_color), + associative_property_map< + std::map< edge_descriptor, default_color_type > >(edge_color)); + undirected_dfs(vG, vG_vis, + associative_property_map< + std::map< vertex_descriptor, default_color_type > >(vertex_color), + associative_property_map< + std::map< edge_descriptor, default_color_type > >(edge_color)); + + while (!iG_buf.empty()) + { + inL[iG_bimap.right.at(iG_buf.top())] = true; + iG_buf.pop(); + } + while (!vG_buf.empty()) + { + inL[vG_bimap.right.at(vG_buf.top())] = true; + vG_buf.pop(); + } - for(seq_size_type j = 0; j < inL.size(); ++j) { - if(!inL[j]) { - put(aiG_inL, iG_bimap.left.at(j), true); - put(avG_inL, vG_bimap.left.at(j), true); + std::map< edge_descriptor, bool > iG_inL, vG_inL; + associative_property_map< std::map< edge_descriptor, bool > > aiG_inL( + iG_inL), + avG_inL(vG_inL); - undirected_dfs( - make_filtered_graph(iG, - detail::inL_edge_status< associative_property_map< - std::map > >(aiG_inL)), - make_dfs_visitor( - detail::cycle_finder< std::stack > (&iG_buf)), - associative_property_map< - std::map >(vertex_color), - associative_property_map< - std::map >(edge_color) - ); - undirected_dfs( - make_filtered_graph(vG, - detail::inL_edge_status< associative_property_map< - std::map > >(avG_inL)), - make_dfs_visitor( - detail::cycle_finder< std::stack > (&vG_buf)), - associative_property_map< - std::map >(vertex_color), - associative_property_map< - std::map >(edge_color) - ); - - if(!iG_buf.empty() || !vG_buf.empty()) { - while(!iG_buf.empty()) iG_buf.pop(); - while(!vG_buf.empty()) vG_buf.pop(); - put(diG, iG_bimap.left.at(j), true); - put(dvG, vG_bimap.left.at(j), true); + for (seq_size_type i = 0; i < inL.size(); ++i) + { + if (inL[i]) + { + put(aiG_inL, iG_bimap.left.at(i), true); + put(avG_inL, vG_bimap.left.at(i), true); + } + else + { + put(aiG_inL, iG_bimap.left.at(i), false); + put(avG_inL, vG_bimap.left.at(i), false); } - - put(aiG_inL, iG_bimap.left.at(j), false); - put(avG_inL, vG_bimap.left.at(j), false); - } } - int cc = 0; - - std::map com_map; - cc += connected_components( + undirected_dfs( make_filtered_graph(iG, - detail::deleted_edge_status > >(diG)), - associative_property_map >(com_map) - ); - cc += connected_components( + detail::inL_edge_status< + associative_property_map< std::map< edge_descriptor, bool > > >( + aiG_inL)), + make_dfs_visitor( + detail::cycle_finder< std::stack< edge_descriptor > >(&iG_buf)), + associative_property_map< + std::map< vertex_descriptor, default_color_type > >(vertex_color), + associative_property_map< + std::map< edge_descriptor, default_color_type > >(edge_color)); + undirected_dfs( make_filtered_graph(vG, - detail::deleted_edge_status > >(dvG)), - associative_property_map< std::map >(com_map) - ); + detail::inL_edge_status< + associative_property_map< std::map< edge_descriptor, bool > > >( + avG_inL)), + make_dfs_visitor( + detail::cycle_finder< std::stack< edge_descriptor > >(&vG_buf)), + associative_property_map< + std::map< vertex_descriptor, default_color_type > >(vertex_color), + associative_property_map< + std::map< edge_descriptor, default_color_type > >(edge_color)); + + if (iG_buf.empty() && vG_buf.empty()) + { + + std::map< edge_descriptor, bool > iG_deleted, vG_deleted; + associative_property_map< std::map< edge_descriptor, bool > > diG( + iG_deleted); + associative_property_map< std::map< edge_descriptor, bool > > dvG( + vG_deleted); - if(cc != 2) - return; + boost::tuples::tie(current, last) = edges(iG); + for (; current != last; ++current) + put(diG, *current, false); + boost::tuples::tie(current, last) = edges(vG); + for (; current != last; ++current) + put(dvG, *current, false); - // REC - detail::rec_two_graphs_common_spanning_trees > > - (iG, iG_bimap, aiG_inL, diG, vG, vG_bimap, aiG_inL, dvG, func, inL); + for (seq_size_type j = 0; j < inL.size(); ++j) + { + if (!inL[j]) + { + put(aiG_inL, iG_bimap.left.at(j), true); + put(avG_inL, vG_bimap.left.at(j), true); + + undirected_dfs( + make_filtered_graph(iG, + detail::inL_edge_status< associative_property_map< + std::map< edge_descriptor, bool > > >(aiG_inL)), + make_dfs_visitor( + detail::cycle_finder< std::stack< edge_descriptor > >( + &iG_buf)), + associative_property_map< + std::map< vertex_descriptor, default_color_type > >( + vertex_color), + associative_property_map< + std::map< edge_descriptor, default_color_type > >( + edge_color)); + undirected_dfs( + make_filtered_graph(vG, + detail::inL_edge_status< associative_property_map< + std::map< edge_descriptor, bool > > >(avG_inL)), + make_dfs_visitor( + detail::cycle_finder< std::stack< edge_descriptor > >( + &vG_buf)), + associative_property_map< + std::map< vertex_descriptor, default_color_type > >( + vertex_color), + associative_property_map< + std::map< edge_descriptor, default_color_type > >( + edge_color)); + + if (!iG_buf.empty() || !vG_buf.empty()) + { + while (!iG_buf.empty()) + iG_buf.pop(); + while (!vG_buf.empty()) + vG_buf.pop(); + put(diG, iG_bimap.left.at(j), true); + put(dvG, vG_bimap.left.at(j), true); + } + + put(aiG_inL, iG_bimap.left.at(j), false); + put(avG_inL, vG_bimap.left.at(j), false); + } + } - } + int cc = 0; -} + std::map< vertex_descriptor, int > com_map; + cc += connected_components( + make_filtered_graph(iG, + detail::deleted_edge_status< associative_property_map< + std::map< edge_descriptor, bool > > >(diG)), + associative_property_map< std::map< vertex_descriptor, int > >( + com_map)); + cc += connected_components( + make_filtered_graph(vG, + detail::deleted_edge_status< associative_property_map< + std::map< edge_descriptor, bool > > >(dvG)), + associative_property_map< std::map< vertex_descriptor, int > >( + com_map)); + if (cc != 2) + return; -template < - typename Graph, - typename Func, - typename Seq -> + // REC + detail::rec_two_graphs_common_spanning_trees< Graph, Func, Seq, + associative_property_map< std::map< edge_descriptor, bool > > >( + iG, iG_bimap, aiG_inL, diG, vG, vG_bimap, aiG_inL, dvG, func, inL); + } +} + +template < typename Graph, typename Func, typename Seq > BOOST_CONCEPT_REQUIRES( - ((IncidenceGraphConcept)) - ((EdgeListGraphConcept)), - (void) -) -two_graphs_common_spanning_trees - ( - const Graph& iG, - const Graph& vG, - Func func, - Seq inL - ) + ((IncidenceGraphConcept< Graph >))((EdgeListGraphConcept< Graph >)), (void)) +two_graphs_common_spanning_trees( + const Graph& iG, const Graph& vG, Func func, Seq inL) { - typedef graph_traits GraphTraits; + typedef graph_traits< Graph > GraphTraits; - typedef typename GraphTraits::edge_descriptor edge_descriptor; - typedef typename GraphTraits::edge_iterator edge_iterator; + typedef typename GraphTraits::edge_descriptor edge_descriptor; + typedef typename GraphTraits::edge_iterator edge_iterator; - std::vector iGO, vGO; - edge_iterator curr, last; + std::vector< edge_descriptor > iGO, vGO; + edge_iterator curr, last; - boost::tuples::tie(curr, last) = edges(iG); - for(; curr != last; ++curr) - iGO.push_back(*curr); + boost::tuples::tie(curr, last) = edges(iG); + for (; curr != last; ++curr) + iGO.push_back(*curr); - boost::tuples::tie(curr, last) = edges(vG); - for(; curr != last; ++curr) - vGO.push_back(*curr); + boost::tuples::tie(curr, last) = edges(vG); + for (; curr != last; ++curr) + vGO.push_back(*curr); - two_graphs_common_spanning_trees(iG, iGO, vG, vGO, func, inL); + two_graphs_common_spanning_trees(iG, iGO, vG, vGO, func, inL); } - } // namespace boost - #endif // BOOST_GRAPH_TWO_GRAPHS_COMMON_SPANNING_TREES_HPP diff --git a/include/boost/graph/undirected_dfs.hpp b/include/boost/graph/undirected_dfs.hpp index 89cb10f28..62088c87f 100644 --- a/include/boost/graph/undirected_dfs.hpp +++ b/include/boost/graph/undirected_dfs.hpp @@ -15,241 +15,255 @@ #include #include -namespace boost { +namespace boost +{ - namespace detail { +namespace detail +{ // Define BOOST_RECURSIVE_DFS to use older, recursive version. // It is retained for a while in order to perform performance // comparison. #ifndef BOOST_RECURSIVE_DFS - template - void undir_dfv_impl - (const IncidenceGraph& g, - typename graph_traits::vertex_descriptor u, - DFSVisitor& vis, - VertexColorMap vertex_color, - EdgeColorMap edge_color) + template < typename IncidenceGraph, typename DFSVisitor, + typename VertexColorMap, typename EdgeColorMap > + void undir_dfv_impl(const IncidenceGraph& g, + typename graph_traits< IncidenceGraph >::vertex_descriptor u, + DFSVisitor& vis, VertexColorMap vertex_color, EdgeColorMap edge_color) { - BOOST_CONCEPT_ASSERT(( IncidenceGraphConcept )); - BOOST_CONCEPT_ASSERT(( DFSVisitorConcept )); - typedef typename graph_traits::vertex_descriptor Vertex; - typedef typename graph_traits::edge_descriptor Edge; - BOOST_CONCEPT_ASSERT(( ReadWritePropertyMapConcept )); - BOOST_CONCEPT_ASSERT(( ReadWritePropertyMapConcept )); - typedef typename property_traits::value_type ColorValue; - typedef typename property_traits::value_type EColorValue; - BOOST_CONCEPT_ASSERT(( ColorValueConcept )); - BOOST_CONCEPT_ASSERT(( ColorValueConcept )); - typedef color_traits Color; - typedef color_traits EColor; - typedef typename graph_traits::out_edge_iterator Iter; - typedef std::pair, std::pair > > VertexInfo; - - std::vector stack; - - put(vertex_color, u, Color::gray()); - vis.discover_vertex(u, g); - stack.push_back(std::make_pair(u, std::make_pair(boost::optional(), out_edges(u, g)))); - while (!stack.empty()) { - VertexInfo& back = stack.back(); - u = back.first; - boost::optional src_e = back.second.first; - Iter ei = back.second.second.first, ei_end = back.second.second.second; - stack.pop_back(); - while (ei != ei_end) { - Vertex v = target(*ei, g); - vis.examine_edge(*ei, g); - ColorValue v_color = get(vertex_color, v); - EColorValue uv_color = get(edge_color, *ei); - put(edge_color, *ei, EColor::black()); - if (v_color == Color::white()) { - vis.tree_edge(*ei, g); - src_e = *ei; - stack.push_back(std::make_pair(u, std::make_pair(src_e, std::make_pair(++ei, ei_end)))); - u = v; - put(vertex_color, u, Color::gray()); - vis.discover_vertex(u, g); - boost::tie(ei, ei_end) = out_edges(u, g); - } else if (v_color == Color::gray()) { - if (uv_color == EColor::white()) vis.back_edge(*ei, g); - call_finish_edge(vis, *ei, g); - ++ei; - } else { // if (v_color == Color::black()) - call_finish_edge(vis, *ei, g); - ++ei; - } + BOOST_CONCEPT_ASSERT((IncidenceGraphConcept< IncidenceGraph >)); + BOOST_CONCEPT_ASSERT((DFSVisitorConcept< DFSVisitor, IncidenceGraph >)); + typedef + typename graph_traits< IncidenceGraph >::vertex_descriptor Vertex; + typedef typename graph_traits< IncidenceGraph >::edge_descriptor Edge; + BOOST_CONCEPT_ASSERT( + (ReadWritePropertyMapConcept< VertexColorMap, Vertex >)); + BOOST_CONCEPT_ASSERT( + (ReadWritePropertyMapConcept< EdgeColorMap, Edge >)); + typedef + typename property_traits< VertexColorMap >::value_type ColorValue; + typedef + typename property_traits< EdgeColorMap >::value_type EColorValue; + BOOST_CONCEPT_ASSERT((ColorValueConcept< ColorValue >)); + BOOST_CONCEPT_ASSERT((ColorValueConcept< EColorValue >)); + typedef color_traits< ColorValue > Color; + typedef color_traits< EColorValue > EColor; + typedef typename graph_traits< IncidenceGraph >::out_edge_iterator Iter; + typedef std::pair< Vertex, + std::pair< boost::optional< Edge >, std::pair< Iter, Iter > > > + VertexInfo; + + std::vector< VertexInfo > stack; + + put(vertex_color, u, Color::gray()); + vis.discover_vertex(u, g); + stack.push_back(std::make_pair( + u, std::make_pair(boost::optional< Edge >(), out_edges(u, g)))); + while (!stack.empty()) + { + VertexInfo& back = stack.back(); + u = back.first; + boost::optional< Edge > src_e = back.second.first; + Iter ei = back.second.second.first, + ei_end = back.second.second.second; + stack.pop_back(); + while (ei != ei_end) + { + Vertex v = target(*ei, g); + vis.examine_edge(*ei, g); + ColorValue v_color = get(vertex_color, v); + EColorValue uv_color = get(edge_color, *ei); + put(edge_color, *ei, EColor::black()); + if (v_color == Color::white()) + { + vis.tree_edge(*ei, g); + src_e = *ei; + stack.push_back(std::make_pair(u, + std::make_pair(src_e, std::make_pair(++ei, ei_end)))); + u = v; + put(vertex_color, u, Color::gray()); + vis.discover_vertex(u, g); + boost::tie(ei, ei_end) = out_edges(u, g); + } + else if (v_color == Color::gray()) + { + if (uv_color == EColor::white()) + vis.back_edge(*ei, g); + call_finish_edge(vis, *ei, g); + ++ei; + } + else + { // if (v_color == Color::black()) + call_finish_edge(vis, *ei, g); + ++ei; + } + } + put(vertex_color, u, Color::black()); + vis.finish_vertex(u, g); + if (src_e) + call_finish_edge(vis, src_e.get(), g); } - put(vertex_color, u, Color::black()); - vis.finish_vertex(u, g); - if (src_e) call_finish_edge(vis, src_e.get(), g); - } } #else // BOOST_RECURSIVE_DFS - template - void undir_dfv_impl - (const IncidenceGraph& g, - typename graph_traits::vertex_descriptor u, - DFSVisitor& vis, // pass-by-reference here, important! - VertexColorMap vertex_color, - EdgeColorMap edge_color) + template < typename IncidenceGraph, typename DFSVisitor, + typename VertexColorMap, typename EdgeColorMap > + void undir_dfv_impl(const IncidenceGraph& g, + typename graph_traits< IncidenceGraph >::vertex_descriptor u, + DFSVisitor& vis, // pass-by-reference here, important! + VertexColorMap vertex_color, EdgeColorMap edge_color) { - BOOST_CONCEPT_ASSERT(( IncidenceGraphConcept )); - BOOST_CONCEPT_ASSERT(( DFSVisitorConcept )); - typedef typename graph_traits::vertex_descriptor Vertex; - typedef typename graph_traits::edge_descriptor Edge; - BOOST_CONCEPT_ASSERT(( ReadWritePropertyMapConcept )); - BOOST_CONCEPT_ASSERT(( ReadWritePropertyMapConcept )); - typedef typename property_traits::value_type ColorValue; - typedef typename property_traits::value_type EColorValue; - BOOST_CONCEPT_ASSERT(( ColorValueConcept )); - BOOST_CONCEPT_ASSERT(( ColorValueConcept )); - typedef color_traits Color; - typedef color_traits EColor; - typename graph_traits::out_edge_iterator ei, ei_end; - - put(vertex_color, u, Color::gray()); vis.discover_vertex(u, g); - for (boost::tie(ei, ei_end) = out_edges(u, g); ei != ei_end; ++ei) { - Vertex v = target(*ei, g); vis.examine_edge(*ei, g); - ColorValue v_color = get(vertex_color, v); - EColorValue uv_color = get(edge_color, *ei); - put(edge_color, *ei, EColor::black()); - if (v_color == Color::white()) { vis.tree_edge(*ei, g); - undir_dfv_impl(g, v, vis, vertex_color, edge_color); - } else if (v_color == Color::gray() && uv_color == EColor::white()) - vis.back_edge(*ei, g); - call_finish_edge(vis, *ei, g); - } - put(vertex_color, u, Color::black()); vis.finish_vertex(u, g); + BOOST_CONCEPT_ASSERT((IncidenceGraphConcept< IncidenceGraph >)); + BOOST_CONCEPT_ASSERT((DFSVisitorConcept< DFSVisitor, IncidenceGraph >)); + typedef + typename graph_traits< IncidenceGraph >::vertex_descriptor Vertex; + typedef typename graph_traits< IncidenceGraph >::edge_descriptor Edge; + BOOST_CONCEPT_ASSERT( + (ReadWritePropertyMapConcept< VertexColorMap, Vertex >)); + BOOST_CONCEPT_ASSERT( + (ReadWritePropertyMapConcept< EdgeColorMap, Edge >)); + typedef + typename property_traits< VertexColorMap >::value_type ColorValue; + typedef + typename property_traits< EdgeColorMap >::value_type EColorValue; + BOOST_CONCEPT_ASSERT((ColorValueConcept< ColorValue >)); + BOOST_CONCEPT_ASSERT((ColorValueConcept< EColorValue >)); + typedef color_traits< ColorValue > Color; + typedef color_traits< EColorValue > EColor; + typename graph_traits< IncidenceGraph >::out_edge_iterator ei, ei_end; + + put(vertex_color, u, Color::gray()); + vis.discover_vertex(u, g); + for (boost::tie(ei, ei_end) = out_edges(u, g); ei != ei_end; ++ei) + { + Vertex v = target(*ei, g); + vis.examine_edge(*ei, g); + ColorValue v_color = get(vertex_color, v); + EColorValue uv_color = get(edge_color, *ei); + put(edge_color, *ei, EColor::black()); + if (v_color == Color::white()) + { + vis.tree_edge(*ei, g); + undir_dfv_impl(g, v, vis, vertex_color, edge_color); + } + else if (v_color == Color::gray() && uv_color == EColor::white()) + vis.back_edge(*ei, g); + call_finish_edge(vis, *ei, g); + } + put(vertex_color, u, Color::black()); + vis.finish_vertex(u, g); } #endif // ! BOOST_RECURSIVE_DFS - } // namespace detail - - template - void - undirected_dfs(const Graph& g, DFSVisitor vis, - VertexColorMap vertex_color, EdgeColorMap edge_color, - Vertex start_vertex) - { - BOOST_CONCEPT_ASSERT(( DFSVisitorConcept )); - BOOST_CONCEPT_ASSERT(( EdgeListGraphConcept )); - - typedef typename property_traits::value_type ColorValue; - typedef color_traits Color; - - typename graph_traits::vertex_iterator ui, ui_end; - for (boost::tie(ui, ui_end) = vertices(g); ui != ui_end; ++ui) { - put(vertex_color, *ui, Color::white()); vis.initialize_vertex(*ui, g); +} // namespace detail + +template < typename Graph, typename DFSVisitor, typename VertexColorMap, + typename EdgeColorMap, typename Vertex > +void undirected_dfs(const Graph& g, DFSVisitor vis, VertexColorMap vertex_color, + EdgeColorMap edge_color, Vertex start_vertex) +{ + BOOST_CONCEPT_ASSERT((DFSVisitorConcept< DFSVisitor, Graph >)); + BOOST_CONCEPT_ASSERT((EdgeListGraphConcept< Graph >)); + + typedef typename property_traits< VertexColorMap >::value_type ColorValue; + typedef color_traits< ColorValue > Color; + + typename graph_traits< Graph >::vertex_iterator ui, ui_end; + for (boost::tie(ui, ui_end) = vertices(g); ui != ui_end; ++ui) + { + put(vertex_color, *ui, Color::white()); + vis.initialize_vertex(*ui, g); } - typename graph_traits::edge_iterator ei, ei_end; + typename graph_traits< Graph >::edge_iterator ei, ei_end; for (boost::tie(ei, ei_end) = edges(g); ei != ei_end; ++ei) - put(edge_color, *ei, Color::white()); + put(edge_color, *ei, Color::white()); - if (start_vertex != *vertices(g).first){ vis.start_vertex(start_vertex, g); - detail::undir_dfv_impl(g, start_vertex, vis, vertex_color, edge_color); + if (start_vertex != *vertices(g).first) + { + vis.start_vertex(start_vertex, g); + detail::undir_dfv_impl(g, start_vertex, vis, vertex_color, edge_color); } - for (boost::tie(ui, ui_end) = vertices(g); ui != ui_end; ++ui) { - ColorValue u_color = get(vertex_color, *ui); - if (u_color == Color::white()) { vis.start_vertex(*ui, g); - detail::undir_dfv_impl(g, *ui, vis, vertex_color, edge_color); - } + for (boost::tie(ui, ui_end) = vertices(g); ui != ui_end; ++ui) + { + ColorValue u_color = get(vertex_color, *ui); + if (u_color == Color::white()) + { + vis.start_vertex(*ui, g); + detail::undir_dfv_impl(g, *ui, vis, vertex_color, edge_color); + } } - } - - template - void - undirected_dfs(const Graph& g, DFSVisitor vis, - VertexColorMap vertex_color, EdgeColorMap edge_color) - { +} + +template < typename Graph, typename DFSVisitor, typename VertexColorMap, + typename EdgeColorMap > +void undirected_dfs(const Graph& g, DFSVisitor vis, VertexColorMap vertex_color, + EdgeColorMap edge_color) +{ undirected_dfs(g, vis, vertex_color, edge_color, *vertices(g).first); - } - - namespace detail { - template - struct udfs_dispatch { - - template - static void - apply(const Graph& g, DFSVisitor vis, Vertex start_vertex, - const bgl_named_params&, - EdgeColorMap edge_color, +} + +namespace detail +{ + template < typename VertexColorMap > struct udfs_dispatch + { + + template < typename Graph, typename Vertex, typename DFSVisitor, + typename EdgeColorMap, typename P, typename T, typename R > + static void apply(const Graph& g, DFSVisitor vis, Vertex start_vertex, + const bgl_named_params< P, T, R >&, EdgeColorMap edge_color, VertexColorMap vertex_color) - { - undirected_dfs(g, vis, vertex_color, edge_color, start_vertex); - } + { + undirected_dfs(g, vis, vertex_color, edge_color, start_vertex); + } }; - template <> - struct udfs_dispatch { - template - static void - apply(const Graph& g, DFSVisitor vis, Vertex start_vertex, - const bgl_named_params& params, - EdgeColorMap edge_color, + template <> struct udfs_dispatch< param_not_found > + { + template < typename Graph, typename Vertex, typename DFSVisitor, + typename EdgeColorMap, typename P, typename T, typename R > + static void apply(const Graph& g, DFSVisitor vis, Vertex start_vertex, + const bgl_named_params< P, T, R >& params, EdgeColorMap edge_color, param_not_found) - { - std::vector color_vec(num_vertices(g)); - default_color_type c = white_color; // avoid warning about un-init - undirected_dfs - (g, vis, make_iterator_property_map - (color_vec.begin(), - choose_const_pmap(get_param(params, vertex_index), - g, vertex_index), c), - edge_color, - start_vertex); - } + { + std::vector< default_color_type > color_vec(num_vertices(g)); + default_color_type c = white_color; // avoid warning about un-init + undirected_dfs(g, vis, + make_iterator_property_map(color_vec.begin(), + choose_const_pmap( + get_param(params, vertex_index), g, vertex_index), + c), + edge_color, start_vertex); + } }; - } // namespace detail - - - // Named Parameter Variant - template - void - undirected_dfs(const Graph& g, - const bgl_named_params& params) - { - typedef typename get_param_type< vertex_color_t, bgl_named_params >::type C; - detail::udfs_dispatch::apply - (g, - choose_param(get_param(params, graph_visitor), - make_dfs_visitor(null_visitor())), - choose_param(get_param(params, root_vertex_t()), - *vertices(g).first), - params, - get_param(params, edge_color), - get_param(params, vertex_color) - ); - } - - - template - void undirected_depth_first_visit - (const IncidenceGraph& g, - typename graph_traits::vertex_descriptor u, - DFSVisitor vis, VertexColorMap vertex_color, EdgeColorMap edge_color) - { - detail::undir_dfv_impl(g, u, vis, vertex_color, edge_color); - } +} // namespace detail +// Named Parameter Variant +template < typename Graph, typename P, typename T, typename R > +void undirected_dfs(const Graph& g, const bgl_named_params< P, T, R >& params) +{ + typedef typename get_param_type< vertex_color_t, + bgl_named_params< P, T, R > >::type C; + detail::udfs_dispatch< C >::apply(g, + choose_param( + get_param(params, graph_visitor), make_dfs_visitor(null_visitor())), + choose_param(get_param(params, root_vertex_t()), *vertices(g).first), + params, get_param(params, edge_color), get_param(params, vertex_color)); +} -} // namespace boost +template < typename IncidenceGraph, typename DFSVisitor, + typename VertexColorMap, typename EdgeColorMap > +void undirected_depth_first_visit(const IncidenceGraph& g, + typename graph_traits< IncidenceGraph >::vertex_descriptor u, + DFSVisitor vis, VertexColorMap vertex_color, EdgeColorMap edge_color) +{ + detail::undir_dfv_impl(g, u, vis, vertex_color, edge_color); +} +} // namespace boost #endif diff --git a/include/boost/graph/undirected_graph.hpp b/include/boost/graph/undirected_graph.hpp index 1db21a64a..ec1bbbba6 100644 --- a/include/boost/graph/undirected_graph.hpp +++ b/include/boost/graph/undirected_graph.hpp @@ -16,7 +16,9 @@ namespace boost { -struct undirected_graph_tag { }; +struct undirected_graph_tag +{ +}; /** * The undirected_graph class template is a simplified version of the BGL @@ -29,32 +31,33 @@ struct undirected_graph_tag { }; * @note Special care must be taken when removing vertices or edges since * those operations can invalidate the numbering of vertices. */ -template < - typename VertexProp = no_property, - typename EdgeProp = no_property, - typename GraphProp = no_property> +template < typename VertexProp = no_property, typename EdgeProp = no_property, + typename GraphProp = no_property > class undirected_graph { public: typedef GraphProp graph_property_type; typedef VertexProp vertex_property_type; typedef EdgeProp edge_property_type; - typedef typename lookup_one_property::type graph_bundled; - typedef typename lookup_one_property::type vertex_bundled; - typedef typename lookup_one_property::type edge_bundled; + typedef typename lookup_one_property< GraphProp, graph_bundle_t >::type + graph_bundled; + typedef typename lookup_one_property< VertexProp, vertex_bundle_t >::type + vertex_bundled; + typedef typename lookup_one_property< EdgeProp, edge_bundle_t >::type + edge_bundled; public: // Embed indices into the vertex type. - typedef property internal_vertex_property; - typedef property internal_edge_property; + typedef property< vertex_index_t, unsigned, vertex_property_type > + internal_vertex_property; + typedef property< edge_index_t, unsigned, edge_property_type > + internal_edge_property; + public: - typedef adjacency_list graph_type; + typedef adjacency_list< listS, listS, undirectedS, internal_vertex_property, + internal_edge_property, GraphProp, listS > + graph_type; + private: // storage selectors typedef typename graph_type::vertex_list_selector vertex_list_selector; @@ -88,29 +91,43 @@ class undirected_graph typedef std::size_t edge_index_type; inline undirected_graph(GraphProp const& p = GraphProp()) - : m_graph(p), m_num_vertices(0), m_num_edges(0), m_max_vertex_index(0) - , m_max_edge_index(0) - { } + : m_graph(p) + , m_num_vertices(0) + , m_num_edges(0) + , m_max_vertex_index(0) + , m_max_edge_index(0) + { + } inline undirected_graph(undirected_graph const& x) - : m_graph(x.m_graph), m_num_vertices(x.m_num_vertices), m_num_edges(x.m_num_edges) - , m_max_vertex_index(x.m_max_vertex_index), m_max_edge_index(x.m_max_edge_index) - { } - - inline undirected_graph(vertices_size_type n, - GraphProp const& p = GraphProp()) - : m_graph(n, p), m_num_vertices(n), m_num_edges(0), m_max_vertex_index(n) - , m_max_edge_index(0) - { renumber_vertex_indices(); } - - template - inline undirected_graph(EdgeIterator f, - EdgeIterator l, - vertices_size_type n, - edges_size_type m = 0, - GraphProp const& p = GraphProp()) - : m_graph(f, l, n, m, p), m_num_vertices(n), m_num_edges(0) - , m_max_vertex_index(n), m_max_edge_index(0) + : m_graph(x.m_graph) + , m_num_vertices(x.m_num_vertices) + , m_num_edges(x.m_num_edges) + , m_max_vertex_index(x.m_max_vertex_index) + , m_max_edge_index(x.m_max_edge_index) + { + } + + inline undirected_graph( + vertices_size_type n, GraphProp const& p = GraphProp()) + : m_graph(n, p) + , m_num_vertices(n) + , m_num_edges(0) + , m_max_vertex_index(n) + , m_max_edge_index(0) + { + renumber_vertex_indices(); + } + + template < typename EdgeIterator > + inline undirected_graph(EdgeIterator f, EdgeIterator l, + vertices_size_type n, edges_size_type m = 0, + GraphProp const& p = GraphProp()) + : m_graph(f, l, n, m, p) + , m_num_vertices(n) + , m_num_edges(0) + , m_max_vertex_index(n) + , m_max_edge_index(0) { // Unfortunately, we have to renumber to ensure correct indexing. renumber_indices(); @@ -120,8 +137,10 @@ class undirected_graph m_num_edges = m_max_edge_index = boost::num_edges(m_graph); } - undirected_graph& operator =(undirected_graph const& g) { - if(&g != this) { + undirected_graph& operator=(undirected_graph const& g) + { + if (&g != this) + { m_graph = g.m_graph; m_num_vertices = g.m_num_vertices; m_num_edges = g.m_num_edges; @@ -131,105 +150,120 @@ class undirected_graph } // The impl_() methods are not part of the public interface. - graph_type& impl() - { return m_graph; } + graph_type& impl() { return m_graph; } - graph_type const& impl() const - { return m_graph; } + graph_type const& impl() const { return m_graph; } // The following methods are not part of the public interface - vertices_size_type num_vertices() const - { return m_num_vertices; } - + vertices_size_type num_vertices() const { return m_num_vertices; } private: // This helper function manages the attribution of vertex indices. - vertex_descriptor make_index(vertex_descriptor v) { + vertex_descriptor make_index(vertex_descriptor v) + { boost::put(vertex_index, m_graph, v, m_max_vertex_index); m_num_vertices++; m_max_vertex_index++; return v; } + public: vertex_descriptor add_vertex() - { return make_index(boost::add_vertex(m_graph)); } + { + return make_index(boost::add_vertex(m_graph)); + } vertex_descriptor add_vertex(vertex_property_type const& p) - { return make_index(boost::add_vertex(internal_vertex_property(0u, p), m_graph)); } + { + return make_index( + boost::add_vertex(internal_vertex_property(0u, p), m_graph)); + } - void clear_vertex(vertex_descriptor v) { - std::pair - p = boost::out_edges(v, m_graph); + void clear_vertex(vertex_descriptor v) + { + std::pair< out_edge_iterator, out_edge_iterator > p + = boost::out_edges(v, m_graph); m_num_edges -= std::distance(p.first, p.second); boost::clear_vertex(v, m_graph); } - void remove_vertex(vertex_descriptor v) { + void remove_vertex(vertex_descriptor v) + { boost::remove_vertex(v, m_graph); --m_num_vertices; } - edges_size_type num_edges() const - { return m_num_edges; } + edges_size_type num_edges() const { return m_num_edges; } private: // A helper fucntion for managing edge index attributes. - std::pair const& - make_index(std::pair const& x) + std::pair< edge_descriptor, bool > const& make_index( + std::pair< edge_descriptor, bool > const& x) { - if(x.second) { + if (x.second) + { boost::put(edge_index, m_graph, x.first, m_max_edge_index); ++m_num_edges; ++m_max_edge_index; } return x; } + public: - std::pair - add_edge(vertex_descriptor u, vertex_descriptor v) - { return make_index(boost::add_edge(u, v, m_graph)); } + std::pair< edge_descriptor, bool > add_edge( + vertex_descriptor u, vertex_descriptor v) + { + return make_index(boost::add_edge(u, v, m_graph)); + } - std::pair - add_edge(vertex_descriptor u, vertex_descriptor v, - edge_property_type const& p) - { return make_index(boost::add_edge(u, v, internal_edge_property(0u, p), m_graph)); } + std::pair< edge_descriptor, bool > add_edge( + vertex_descriptor u, vertex_descriptor v, edge_property_type const& p) + { + return make_index( + boost::add_edge(u, v, internal_edge_property(0u, p), m_graph)); + } - void remove_edge(vertex_descriptor u, vertex_descriptor v) { + void remove_edge(vertex_descriptor u, vertex_descriptor v) + { // find all edges, (u, v) - std::vector edges; + std::vector< edge_descriptor > edges; out_edge_iterator i, i_end; - for(boost::tie(i, i_end) = boost::out_edges(u, m_graph); i != i_end; ++i) { - if(boost::target(*i, m_graph) == v) { + for (boost::tie(i, i_end) = boost::out_edges(u, m_graph); i != i_end; + ++i) + { + if (boost::target(*i, m_graph) == v) + { edges.push_back(*i); } } // remove all edges, (u, v) - typename std::vector::iterator - j = edges.begin(), j_end = edges.end(); - for( ; j != j_end; ++j) { + typename std::vector< edge_descriptor >::iterator j = edges.begin(), + j_end = edges.end(); + for (; j != j_end; ++j) + { remove_edge(*j); } } - void remove_edge(edge_iterator i) { - remove_edge(*i); - } + void remove_edge(edge_iterator i) { remove_edge(*i); } - void remove_edge(edge_descriptor e) { + void remove_edge(edge_descriptor e) + { boost::remove_edge(e, m_graph); --m_num_edges; } - vertex_index_type max_vertex_index() const - { return m_max_vertex_index; } + vertex_index_type max_vertex_index() const { return m_max_vertex_index; } - void renumber_vertex_indices() { + void renumber_vertex_indices() + { vertex_iterator i, i_end; boost::tie(i, i_end) = vertices(m_graph); m_max_vertex_index = renumber_vertex_indices(i, i_end, 0); } - void remove_vertex_and_renumber_indices(vertex_iterator i) { + void remove_vertex_and_renumber_indices(vertex_iterator i) + { vertex_iterator j = next(i), end = vertices(m_graph).second; vertex_index_type n = get(vertex_index, m_graph, *i); @@ -238,17 +272,17 @@ class undirected_graph m_max_vertex_index = renumber_vertex_indices(j, end, n); } + edge_index_type max_edge_index() const { return m_max_edge_index; } - edge_index_type max_edge_index() const - { return m_max_edge_index; } - - void renumber_edge_indices() { + void renumber_edge_indices() + { edge_iterator i, end; boost::tie(i, end) = edges(m_graph); m_max_edge_index = renumber_edge_indices(i, end, 0); } - void remove_edge_and_renumber_indices(edge_iterator i) { + void remove_edge_and_renumber_indices(edge_iterator i) + { edge_iterator j = next(i), end = edges(m_graph.second); edge_index_type n = get(edge_index, m_graph, *i); @@ -257,43 +291,48 @@ class undirected_graph m_max_edge_index = renumber_edge_indices(j, end, n); } - void renumber_indices() { + void renumber_indices() + { renumber_vertex_indices(); renumber_edge_indices(); } // bundled property support #ifndef BOOST_GRAPH_NO_BUNDLED_PROPERTIES - vertex_bundled& operator[](vertex_descriptor v) - { return m_graph[v]; } + vertex_bundled& operator[](vertex_descriptor v) { return m_graph[v]; } vertex_bundled const& operator[](vertex_descriptor v) const - { return m_graph[v]; } + { + return m_graph[v]; + } - edge_bundled& operator[](edge_descriptor e) - { return m_graph[e]; } + edge_bundled& operator[](edge_descriptor e) { return m_graph[e]; } edge_bundled const& operator[](edge_descriptor e) const - { return m_graph[e]; } + { + return m_graph[e]; + } - graph_bundled& operator[](graph_bundle_t) - { return get_property(*this); } + graph_bundled& operator[](graph_bundle_t) { return get_property(*this); } graph_bundled const& operator[](graph_bundle_t) const - { return get_property(*this); } + { + return get_property(*this); + } #endif // Graph concepts - static vertex_descriptor null_vertex() - { return graph_type::null_vertex(); } + static vertex_descriptor null_vertex() { return graph_type::null_vertex(); } - void clear() { + void clear() + { m_graph.clear(); m_num_vertices = m_max_vertex_index = 0; m_num_edges = m_max_edge_index = 0; } - void swap(undirected_graph& g) { + void swap(undirected_graph& g) + { m_graph.swap(g.m_graph); std::swap(m_num_vertices, g.m_num_vertices); std::swap(m_max_vertex_index, g.m_max_vertex_index); @@ -302,25 +341,27 @@ class undirected_graph } private: - vertices_size_type renumber_vertex_indices(vertex_iterator i, - vertex_iterator end, - vertices_size_type n) + vertices_size_type renumber_vertex_indices( + vertex_iterator i, vertex_iterator end, vertices_size_type n) { - typedef typename property_map::type IndexMap; + typedef + typename property_map< graph_type, vertex_index_t >::type IndexMap; IndexMap indices = get(vertex_index, m_graph); - for( ; i != end; ++i) { + for (; i != end; ++i) + { indices[*i] = n++; } return n; } - edges_size_type renumber_edge_indices(edge_iterator i, - edge_iterator end, - edges_size_type n) + edges_size_type renumber_edge_indices( + edge_iterator i, edge_iterator end, edges_size_type n) { - typedef typename property_map::type IndexMap; + typedef + typename property_map< graph_type, edge_index_t >::type IndexMap; IndexMap indices = get(edge_index, m_graph); - for( ; i != end; ++i) { + for (; i != end; ++i) + { indices[*i] = n++; } return n; @@ -334,371 +375,442 @@ class undirected_graph }; #define UNDIRECTED_GRAPH_PARAMS typename VP, typename EP, typename GP -#define UNDIRECTED_GRAPH undirected_graph +#define UNDIRECTED_GRAPH undirected_graph< VP, EP, GP > // IncidenceGraph concepts -template -inline typename UNDIRECTED_GRAPH::vertex_descriptor -source(typename UNDIRECTED_GRAPH::edge_descriptor e, - UNDIRECTED_GRAPH const& g) -{ return source(e, g.impl()); } - -template -inline typename UNDIRECTED_GRAPH::vertex_descriptor -target(typename UNDIRECTED_GRAPH::edge_descriptor e, - UNDIRECTED_GRAPH const& g) -{ return target(e, g.impl()); } - -template -inline typename UNDIRECTED_GRAPH::degree_size_type -out_degree(typename UNDIRECTED_GRAPH::vertex_descriptor v, - UNDIRECTED_GRAPH const& g) -{ return out_degree(v, g.impl()); } - -template -inline std::pair< - typename UNDIRECTED_GRAPH::out_edge_iterator, - typename UNDIRECTED_GRAPH::out_edge_iterator -> -out_edges(typename UNDIRECTED_GRAPH::vertex_descriptor v, - UNDIRECTED_GRAPH const& g) -{ return out_edges(v, g.impl()); } +template < UNDIRECTED_GRAPH_PARAMS > +inline typename UNDIRECTED_GRAPH::vertex_descriptor source( + typename UNDIRECTED_GRAPH::edge_descriptor e, UNDIRECTED_GRAPH const& g) +{ + return source(e, g.impl()); +} + +template < UNDIRECTED_GRAPH_PARAMS > +inline typename UNDIRECTED_GRAPH::vertex_descriptor target( + typename UNDIRECTED_GRAPH::edge_descriptor e, UNDIRECTED_GRAPH const& g) +{ + return target(e, g.impl()); +} + +template < UNDIRECTED_GRAPH_PARAMS > +inline typename UNDIRECTED_GRAPH::degree_size_type out_degree( + typename UNDIRECTED_GRAPH::vertex_descriptor v, UNDIRECTED_GRAPH const& g) +{ + return out_degree(v, g.impl()); +} + +template < UNDIRECTED_GRAPH_PARAMS > +inline std::pair< typename UNDIRECTED_GRAPH::out_edge_iterator, + typename UNDIRECTED_GRAPH::out_edge_iterator > +out_edges( + typename UNDIRECTED_GRAPH::vertex_descriptor v, UNDIRECTED_GRAPH const& g) +{ + return out_edges(v, g.impl()); +} // BidirectionalGraph concepts -template -inline typename UNDIRECTED_GRAPH::degree_size_type -in_degree(typename UNDIRECTED_GRAPH::vertex_descriptor v, - UNDIRECTED_GRAPH const& g) -{ return in_degree(v, g.impl()); } - -template -inline std::pair< - typename UNDIRECTED_GRAPH::in_edge_iterator, - typename UNDIRECTED_GRAPH::in_edge_iterator -> -in_edges(typename UNDIRECTED_GRAPH::vertex_descriptor v, - UNDIRECTED_GRAPH const& g) -{ return in_edges(v, g.impl()); } - -template -inline std::pair< - typename UNDIRECTED_GRAPH::out_edge_iterator, - typename UNDIRECTED_GRAPH::out_edge_iterator -> -incident_edges(typename UNDIRECTED_GRAPH::vertex_descriptor v, - UNDIRECTED_GRAPH const& g) -{ return out_edges(v, g.impl()); } - -template -inline typename UNDIRECTED_GRAPH::degree_size_type -degree(typename UNDIRECTED_GRAPH::vertex_descriptor v, - UNDIRECTED_GRAPH const& g) -{ return degree(v, g.impl()); } +template < UNDIRECTED_GRAPH_PARAMS > +inline typename UNDIRECTED_GRAPH::degree_size_type in_degree( + typename UNDIRECTED_GRAPH::vertex_descriptor v, UNDIRECTED_GRAPH const& g) +{ + return in_degree(v, g.impl()); +} + +template < UNDIRECTED_GRAPH_PARAMS > +inline std::pair< typename UNDIRECTED_GRAPH::in_edge_iterator, + typename UNDIRECTED_GRAPH::in_edge_iterator > +in_edges( + typename UNDIRECTED_GRAPH::vertex_descriptor v, UNDIRECTED_GRAPH const& g) +{ + return in_edges(v, g.impl()); +} + +template < UNDIRECTED_GRAPH_PARAMS > +inline std::pair< typename UNDIRECTED_GRAPH::out_edge_iterator, + typename UNDIRECTED_GRAPH::out_edge_iterator > +incident_edges( + typename UNDIRECTED_GRAPH::vertex_descriptor v, UNDIRECTED_GRAPH const& g) +{ + return out_edges(v, g.impl()); +} + +template < UNDIRECTED_GRAPH_PARAMS > +inline typename UNDIRECTED_GRAPH::degree_size_type degree( + typename UNDIRECTED_GRAPH::vertex_descriptor v, UNDIRECTED_GRAPH const& g) +{ + return degree(v, g.impl()); +} // AdjacencyGraph concepts -template -inline std::pair< - typename UNDIRECTED_GRAPH::adjacency_iterator, - typename UNDIRECTED_GRAPH::adjacency_iterator - > -adjacent_vertices(typename UNDIRECTED_GRAPH::vertex_descriptor v, - UNDIRECTED_GRAPH const& g) -{ return adjacent_vertices(v, g.impl()); } - -template -typename UNDIRECTED_GRAPH::vertex_descriptor -vertex(typename UNDIRECTED_GRAPH::vertices_size_type n, - UNDIRECTED_GRAPH const& g) -{ return vertex(n, g.impl()); } - -template -std::pair -edge(typename UNDIRECTED_GRAPH::vertex_descriptor u, - typename UNDIRECTED_GRAPH::vertex_descriptor v, - UNDIRECTED_GRAPH const& g) -{ return edge(u, v, g.impl()); } +template < UNDIRECTED_GRAPH_PARAMS > +inline std::pair< typename UNDIRECTED_GRAPH::adjacency_iterator, + typename UNDIRECTED_GRAPH::adjacency_iterator > +adjacent_vertices( + typename UNDIRECTED_GRAPH::vertex_descriptor v, UNDIRECTED_GRAPH const& g) +{ + return adjacent_vertices(v, g.impl()); +} + +template < UNDIRECTED_GRAPH_PARAMS > +typename UNDIRECTED_GRAPH::vertex_descriptor vertex( + typename UNDIRECTED_GRAPH::vertices_size_type n, UNDIRECTED_GRAPH const& g) +{ + return vertex(n, g.impl()); +} + +template < UNDIRECTED_GRAPH_PARAMS > +std::pair< typename UNDIRECTED_GRAPH::edge_descriptor, bool > edge( + typename UNDIRECTED_GRAPH::vertex_descriptor u, + typename UNDIRECTED_GRAPH::vertex_descriptor v, UNDIRECTED_GRAPH const& g) +{ + return edge(u, v, g.impl()); +} // VertexListGraph concepts -template -inline typename UNDIRECTED_GRAPH::vertices_size_type -num_vertices(UNDIRECTED_GRAPH const& g) -{ return g.num_vertices(); } - -template -inline std::pair< - typename UNDIRECTED_GRAPH::vertex_iterator, - typename UNDIRECTED_GRAPH::vertex_iterator -> +template < UNDIRECTED_GRAPH_PARAMS > +inline typename UNDIRECTED_GRAPH::vertices_size_type num_vertices( + UNDIRECTED_GRAPH const& g) +{ + return g.num_vertices(); +} + +template < UNDIRECTED_GRAPH_PARAMS > +inline std::pair< typename UNDIRECTED_GRAPH::vertex_iterator, + typename UNDIRECTED_GRAPH::vertex_iterator > vertices(UNDIRECTED_GRAPH const& g) -{ return vertices(g.impl()); } +{ + return vertices(g.impl()); +} // EdgeListGraph concepts -template -inline typename UNDIRECTED_GRAPH::edges_size_type -num_edges(UNDIRECTED_GRAPH const& g) -{ return g.num_edges(); } - -template -inline std::pair< - typename UNDIRECTED_GRAPH::edge_iterator, - typename UNDIRECTED_GRAPH::edge_iterator -> +template < UNDIRECTED_GRAPH_PARAMS > +inline typename UNDIRECTED_GRAPH::edges_size_type num_edges( + UNDIRECTED_GRAPH const& g) +{ + return g.num_edges(); +} + +template < UNDIRECTED_GRAPH_PARAMS > +inline std::pair< typename UNDIRECTED_GRAPH::edge_iterator, + typename UNDIRECTED_GRAPH::edge_iterator > edges(UNDIRECTED_GRAPH const& g) -{ return edges(g.impl()); } +{ + return edges(g.impl()); +} // MutableGraph concepts -template -inline typename UNDIRECTED_GRAPH::vertex_descriptor -add_vertex(UNDIRECTED_GRAPH& g) -{ return g.add_vertex(); } - -template -inline typename UNDIRECTED_GRAPH::vertex_descriptor -add_vertex(typename UNDIRECTED_GRAPH::vertex_property_type const& p, - UNDIRECTED_GRAPH& g) -{ return g.add_vertex(p); } - -template -inline void -clear_vertex(typename UNDIRECTED_GRAPH::vertex_descriptor v, - UNDIRECTED_GRAPH& g) -{ return g.clear_vertex(v); } - -template -inline void -remove_vertex(typename UNDIRECTED_GRAPH::vertex_descriptor v, UNDIRECTED_GRAPH& g) -{ return g.remove_vertex(v); } - -template -inline std::pair -add_edge(typename UNDIRECTED_GRAPH::vertex_descriptor u, - typename UNDIRECTED_GRAPH::vertex_descriptor v, - UNDIRECTED_GRAPH& g) -{ return g.add_edge(u, v); } - -template -inline std::pair -add_edge(typename UNDIRECTED_GRAPH::vertex_descriptor u, - typename UNDIRECTED_GRAPH::vertex_descriptor v, - typename UNDIRECTED_GRAPH::edge_property_type const& p, - UNDIRECTED_GRAPH& g) -{ return g.add_edge(u, v, p); } - -template -inline void -remove_edge(typename UNDIRECTED_GRAPH::vertex_descriptor u, - typename UNDIRECTED_GRAPH::vertex_descriptor v, - UNDIRECTED_GRAPH& g) -{ return g.remove_edge(u, v); } - -template -inline void -remove_edge(typename UNDIRECTED_GRAPH::edge_descriptor e, UNDIRECTED_GRAPH& g) -{ return g.remove_edge(e); } - -template -inline void -remove_edge(typename UNDIRECTED_GRAPH::edge_iterator i, UNDIRECTED_GRAPH& g) -{ return g.remove_edge(i); } - -template +template < UNDIRECTED_GRAPH_PARAMS > +inline typename UNDIRECTED_GRAPH::vertex_descriptor add_vertex( + UNDIRECTED_GRAPH& g) +{ + return g.add_vertex(); +} + +template < UNDIRECTED_GRAPH_PARAMS > +inline typename UNDIRECTED_GRAPH::vertex_descriptor add_vertex( + typename UNDIRECTED_GRAPH::vertex_property_type const& p, + UNDIRECTED_GRAPH& g) +{ + return g.add_vertex(p); +} + +template < UNDIRECTED_GRAPH_PARAMS > +inline void clear_vertex( + typename UNDIRECTED_GRAPH::vertex_descriptor v, UNDIRECTED_GRAPH& g) +{ + return g.clear_vertex(v); +} + +template < UNDIRECTED_GRAPH_PARAMS > +inline void remove_vertex( + typename UNDIRECTED_GRAPH::vertex_descriptor v, UNDIRECTED_GRAPH& g) +{ + return g.remove_vertex(v); +} + +template < UNDIRECTED_GRAPH_PARAMS > +inline std::pair< typename UNDIRECTED_GRAPH::edge_descriptor, bool > add_edge( + typename UNDIRECTED_GRAPH::vertex_descriptor u, + typename UNDIRECTED_GRAPH::vertex_descriptor v, UNDIRECTED_GRAPH& g) +{ + return g.add_edge(u, v); +} + +template < UNDIRECTED_GRAPH_PARAMS > +inline std::pair< typename UNDIRECTED_GRAPH::edge_descriptor, bool > add_edge( + typename UNDIRECTED_GRAPH::vertex_descriptor u, + typename UNDIRECTED_GRAPH::vertex_descriptor v, + typename UNDIRECTED_GRAPH::edge_property_type const& p, UNDIRECTED_GRAPH& g) +{ + return g.add_edge(u, v, p); +} + +template < UNDIRECTED_GRAPH_PARAMS > +inline void remove_edge(typename UNDIRECTED_GRAPH::vertex_descriptor u, + typename UNDIRECTED_GRAPH::vertex_descriptor v, UNDIRECTED_GRAPH& g) +{ + return g.remove_edge(u, v); +} + +template < UNDIRECTED_GRAPH_PARAMS > +inline void remove_edge( + typename UNDIRECTED_GRAPH::edge_descriptor e, UNDIRECTED_GRAPH& g) +{ + return g.remove_edge(e); +} + +template < UNDIRECTED_GRAPH_PARAMS > +inline void remove_edge( + typename UNDIRECTED_GRAPH::edge_iterator i, UNDIRECTED_GRAPH& g) +{ + return g.remove_edge(i); +} + +template < UNDIRECTED_GRAPH_PARAMS, class Predicate > inline void remove_edge_if(Predicate pred, UNDIRECTED_GRAPH& g) -{ return remove_edge_if(pred, g.impl()); } - -template -inline void -remove_incident_edge_if(typename UNDIRECTED_GRAPH::vertex_descriptor v, - Predicate pred, - UNDIRECTED_GRAPH& g) -{ return remove_out_edge_if(v, pred, g.impl()); } - -template -inline void -remove_out_edge_if(typename UNDIRECTED_GRAPH::vertex_descriptor v, - Predicate pred, - UNDIRECTED_GRAPH& g) -{ return remove_out_edge_if(v, pred, g.impl()); } - -template -inline void -remove_in_edge_if(typename UNDIRECTED_GRAPH::vertex_descriptor v, - Predicate pred, - UNDIRECTED_GRAPH& g) -{ return remove_in_edge_if(v, pred, g.impl()); } - -template -struct property_map: property_map {}; - -template -struct property_map { - typedef transform_value_property_map< - detail::remove_first_property, - typename property_map::const_type> - const_type; - typedef transform_value_property_map< - detail::remove_first_property, - typename property_map::type> - type; +{ + return remove_edge_if(pred, g.impl()); +} + +template < UNDIRECTED_GRAPH_PARAMS, class Predicate > +inline void remove_incident_edge_if( + typename UNDIRECTED_GRAPH::vertex_descriptor v, Predicate pred, + UNDIRECTED_GRAPH& g) +{ + return remove_out_edge_if(v, pred, g.impl()); +} + +template < UNDIRECTED_GRAPH_PARAMS, class Predicate > +inline void remove_out_edge_if(typename UNDIRECTED_GRAPH::vertex_descriptor v, + Predicate pred, UNDIRECTED_GRAPH& g) +{ + return remove_out_edge_if(v, pred, g.impl()); +} + +template < UNDIRECTED_GRAPH_PARAMS, class Predicate > +inline void remove_in_edge_if(typename UNDIRECTED_GRAPH::vertex_descriptor v, + Predicate pred, UNDIRECTED_GRAPH& g) +{ + return remove_in_edge_if(v, pred, g.impl()); +} + +template < UNDIRECTED_GRAPH_PARAMS, typename Property > +struct property_map< UNDIRECTED_GRAPH, Property > +: property_map< typename UNDIRECTED_GRAPH::graph_type, Property > +{ +}; + +template < UNDIRECTED_GRAPH_PARAMS > +struct property_map< UNDIRECTED_GRAPH, vertex_all_t > +{ + typedef transform_value_property_map< detail::remove_first_property, + typename property_map< typename UNDIRECTED_GRAPH::graph_type, + vertex_all_t >::const_type > + const_type; + typedef transform_value_property_map< detail::remove_first_property, + typename property_map< typename UNDIRECTED_GRAPH::graph_type, + vertex_all_t >::type > + type; }; -template -struct property_map { - typedef transform_value_property_map< - detail::remove_first_property, - typename property_map::const_type> - const_type; - typedef transform_value_property_map< - detail::remove_first_property, - typename property_map::type> - type; +template < UNDIRECTED_GRAPH_PARAMS > +struct property_map< UNDIRECTED_GRAPH, edge_all_t > +{ + typedef transform_value_property_map< detail::remove_first_property, + typename property_map< typename UNDIRECTED_GRAPH::graph_type, + edge_all_t >::const_type > + const_type; + typedef transform_value_property_map< detail::remove_first_property, + typename property_map< typename UNDIRECTED_GRAPH::graph_type, + edge_all_t >::type > + type; }; // PropertyGraph concepts -template -inline typename property_map::type -get(Property p, UNDIRECTED_GRAPH& g) -{ return get(p, g.impl()); } - -template -inline typename property_map::const_type -get(Property p, UNDIRECTED_GRAPH const& g) -{ return get(p, g.impl()); } - -template -inline typename property_map::type -get(vertex_all_t, UNDIRECTED_GRAPH& g) -{ return typename property_map::type(detail::remove_first_property(), get(vertex_all, g.impl())); } - -template -inline typename property_map::const_type -get(vertex_all_t, UNDIRECTED_GRAPH const& g) -{ return typename property_map::const_type(detail::remove_first_property(), get(vertex_all, g.impl())); } - -template -inline typename property_map::type -get(edge_all_t, UNDIRECTED_GRAPH& g) -{ return typename property_map::type(detail::remove_first_property(), get(edge_all, g.impl())); } - -template -inline typename property_map::const_type -get(edge_all_t, UNDIRECTED_GRAPH const& g) -{ return typename property_map::const_type(detail::remove_first_property(), get(edge_all, g.impl())); } - -template -inline typename property_traits< - typename property_map< - typename UNDIRECTED_GRAPH::graph_type, Property - >::const_type ->::value_type +template < UNDIRECTED_GRAPH_PARAMS, typename Property > +inline typename property_map< UNDIRECTED_GRAPH, Property >::type get( + Property p, UNDIRECTED_GRAPH& g) +{ + return get(p, g.impl()); +} + +template < UNDIRECTED_GRAPH_PARAMS, typename Property > +inline typename property_map< UNDIRECTED_GRAPH, Property >::const_type get( + Property p, UNDIRECTED_GRAPH const& g) +{ + return get(p, g.impl()); +} + +template < UNDIRECTED_GRAPH_PARAMS > +inline typename property_map< UNDIRECTED_GRAPH, vertex_all_t >::type get( + vertex_all_t, UNDIRECTED_GRAPH& g) +{ + return typename property_map< UNDIRECTED_GRAPH, vertex_all_t >::type( + detail::remove_first_property(), get(vertex_all, g.impl())); +} + +template < UNDIRECTED_GRAPH_PARAMS > +inline typename property_map< UNDIRECTED_GRAPH, vertex_all_t >::const_type get( + vertex_all_t, UNDIRECTED_GRAPH const& g) +{ + return typename property_map< UNDIRECTED_GRAPH, vertex_all_t >::const_type( + detail::remove_first_property(), get(vertex_all, g.impl())); +} + +template < UNDIRECTED_GRAPH_PARAMS > +inline typename property_map< UNDIRECTED_GRAPH, edge_all_t >::type get( + edge_all_t, UNDIRECTED_GRAPH& g) +{ + return typename property_map< UNDIRECTED_GRAPH, edge_all_t >::type( + detail::remove_first_property(), get(edge_all, g.impl())); +} + +template < UNDIRECTED_GRAPH_PARAMS > +inline typename property_map< UNDIRECTED_GRAPH, edge_all_t >::const_type get( + edge_all_t, UNDIRECTED_GRAPH const& g) +{ + return typename property_map< UNDIRECTED_GRAPH, edge_all_t >::const_type( + detail::remove_first_property(), get(edge_all, g.impl())); +} + +template < UNDIRECTED_GRAPH_PARAMS, typename Property, typename Key > +inline typename property_traits< typename property_map< + typename UNDIRECTED_GRAPH::graph_type, Property >::const_type >::value_type get(Property p, UNDIRECTED_GRAPH const& g, Key const& k) -{ return get(p, g.impl(), k); } +{ + return get(p, g.impl(), k); +} -template +template < UNDIRECTED_GRAPH_PARAMS, typename Key > inline typename property_traits< - typename property_map< - typename UNDIRECTED_GRAPH::graph_type, vertex_all_t - >::const_type ->::value_type + typename property_map< typename UNDIRECTED_GRAPH::graph_type, + vertex_all_t >::const_type >::value_type get(vertex_all_t, UNDIRECTED_GRAPH const& g, Key const& k) -{ return get(vertex_all, g.impl(), k).m_base; } +{ + return get(vertex_all, g.impl(), k).m_base; +} -template +template < UNDIRECTED_GRAPH_PARAMS, typename Key > inline typename property_traits< - typename property_map< - typename UNDIRECTED_GRAPH::graph_type, edge_all_t - >::const_type ->::value_type + typename property_map< typename UNDIRECTED_GRAPH::graph_type, + edge_all_t >::const_type >::value_type get(edge_all_t, UNDIRECTED_GRAPH const& g, Key const& k) -{ return get(edge_all, g.impl(), k).m_base; } +{ + return get(edge_all, g.impl(), k).m_base; +} -template +template < UNDIRECTED_GRAPH_PARAMS, typename Property, typename Key, + typename Value > inline void put(Property p, UNDIRECTED_GRAPH& g, Key const& k, Value const& v) -{ put(p, g.impl(), k, v); } +{ + put(p, g.impl(), k, v); +} -template +template < UNDIRECTED_GRAPH_PARAMS, typename Key, typename Value > inline void put(vertex_all_t, UNDIRECTED_GRAPH& g, Key const& k, Value const& v) -{ put(vertex_all, g.impl(), k, - typename UNDIRECTED_GRAPH::internal_vertex_property(get(vertex_index, g.impl(), k), v)); +{ + put(vertex_all, g.impl(), k, + typename UNDIRECTED_GRAPH::internal_vertex_property( + get(vertex_index, g.impl(), k), v)); } -template +template < UNDIRECTED_GRAPH_PARAMS, typename Key, typename Value > inline void put(edge_all_t, UNDIRECTED_GRAPH& g, Key const& k, Value const& v) -{ put(edge_all, g.impl(), k, - typename UNDIRECTED_GRAPH::internal_vertex_property(get(edge_index, g.impl(), k), v)); +{ + put(edge_all, g.impl(), k, + typename UNDIRECTED_GRAPH::internal_vertex_property( + get(edge_index, g.impl(), k), v)); } -template -inline typename graph_property::type& +template < UNDIRECTED_GRAPH_PARAMS, class Property > +inline typename graph_property< UNDIRECTED_GRAPH, Property >::type& get_property(UNDIRECTED_GRAPH& g, Property p) -{ return get_property(g.impl(), p); } +{ + return get_property(g.impl(), p); +} -template -inline typename graph_property::type const& +template < UNDIRECTED_GRAPH_PARAMS, class Property > +inline typename graph_property< UNDIRECTED_GRAPH, Property >::type const& get_property(UNDIRECTED_GRAPH const& g, Property p) -{ return get_property(g.impl(), p); } +{ + return get_property(g.impl(), p); +} -template +template < UNDIRECTED_GRAPH_PARAMS, class Property, class Value > inline void set_property(UNDIRECTED_GRAPH& g, Property p, Value v) -{ return set_property(g.impl(), p, v); } +{ + return set_property(g.impl(), p, v); +} // Indexed Vertex graph -template -inline typename UNDIRECTED_GRAPH::vertex_index_type -get_vertex_index(typename UNDIRECTED_GRAPH::vertex_descriptor v, - UNDIRECTED_GRAPH const& g) -{ return get(vertex_index, g, v); } - -template -typename UNDIRECTED_GRAPH::vertex_index_type -max_vertex_index(UNDIRECTED_GRAPH const& g) -{ return g.max_vertex_index(); } +template < UNDIRECTED_GRAPH_PARAMS > +inline typename UNDIRECTED_GRAPH::vertex_index_type get_vertex_index( + typename UNDIRECTED_GRAPH::vertex_descriptor v, UNDIRECTED_GRAPH const& g) +{ + return get(vertex_index, g, v); +} -template -inline void -renumber_vertex_indices(UNDIRECTED_GRAPH& g) -{ g.renumber_vertex_indices(); } +template < UNDIRECTED_GRAPH_PARAMS > +typename UNDIRECTED_GRAPH::vertex_index_type max_vertex_index( + UNDIRECTED_GRAPH const& g) +{ + return g.max_vertex_index(); +} -template -inline void -remove_vertex_and_renumber_indices(typename UNDIRECTED_GRAPH::vertex_iterator i, - UNDIRECTED_GRAPH& g) -{ g.remove_vertex_and_renumber_indices(i); } +template < UNDIRECTED_GRAPH_PARAMS > +inline void renumber_vertex_indices(UNDIRECTED_GRAPH& g) +{ + g.renumber_vertex_indices(); +} +template < UNDIRECTED_GRAPH_PARAMS > +inline void remove_vertex_and_renumber_indices( + typename UNDIRECTED_GRAPH::vertex_iterator i, UNDIRECTED_GRAPH& g) +{ + g.remove_vertex_and_renumber_indices(i); +} // Edge index management -template -inline typename UNDIRECTED_GRAPH::edge_index_type -get_edge_index(typename UNDIRECTED_GRAPH::edge_descriptor v, - UNDIRECTED_GRAPH const& g) -{ return get(edge_index, g, v); } +template < UNDIRECTED_GRAPH_PARAMS > +inline typename UNDIRECTED_GRAPH::edge_index_type get_edge_index( + typename UNDIRECTED_GRAPH::edge_descriptor v, UNDIRECTED_GRAPH const& g) +{ + return get(edge_index, g, v); +} -template -typename UNDIRECTED_GRAPH::edge_index_type -max_edge_index(UNDIRECTED_GRAPH const& g) -{ return g.max_edge_index(); } +template < UNDIRECTED_GRAPH_PARAMS > +typename UNDIRECTED_GRAPH::edge_index_type max_edge_index( + UNDIRECTED_GRAPH const& g) +{ + return g.max_edge_index(); +} -template -inline void -renumber_edge_indices(UNDIRECTED_GRAPH& g) -{ g.renumber_edge_indices(); } +template < UNDIRECTED_GRAPH_PARAMS > +inline void renumber_edge_indices(UNDIRECTED_GRAPH& g) +{ + g.renumber_edge_indices(); +} -template -inline void -remove_edge_and_renumber_indices(typename UNDIRECTED_GRAPH::edge_iterator i, - UNDIRECTED_GRAPH& g) -{ g.remove_edge_and_renumber_indices(i); } +template < UNDIRECTED_GRAPH_PARAMS > +inline void remove_edge_and_renumber_indices( + typename UNDIRECTED_GRAPH::edge_iterator i, UNDIRECTED_GRAPH& g) +{ + g.remove_edge_and_renumber_indices(i); +} // Index management -template -inline void -renumber_indices(UNDIRECTED_GRAPH& g) -{ g.renumber_indices(); } +template < UNDIRECTED_GRAPH_PARAMS > +inline void renumber_indices(UNDIRECTED_GRAPH& g) +{ + g.renumber_indices(); +} // Mutability Traits -template -struct graph_mutability_traits { +template < UNDIRECTED_GRAPH_PARAMS > +struct graph_mutability_traits< UNDIRECTED_GRAPH > +{ typedef mutable_property_graph_tag category; }; diff --git a/include/boost/graph/vector_as_graph.hpp b/include/boost/graph/vector_as_graph.hpp index 1c3890224..444df8767 100644 --- a/include/boost/graph/vector_as_graph.hpp +++ b/include/boost/graph/vector_as_graph.hpp @@ -40,290 +40,295 @@ */ - - -namespace boost { - namespace detail { - template struct val_out_edge_ret; - template struct val_out_edge_iter; - template struct val_edge; - } +namespace boost +{ +namespace detail +{ + template < class EdgeList > struct val_out_edge_ret; + template < class EdgeList > struct val_out_edge_iter; + template < class EdgeList > struct val_edge; +} } -namespace boost { +namespace boost +{ - struct vector_as_graph_traversal_tag - : public vertex_list_graph_tag, - public adjacency_graph_tag, - public incidence_graph_tag { }; +struct vector_as_graph_traversal_tag : public vertex_list_graph_tag, + public adjacency_graph_tag, + public incidence_graph_tag +{ +}; - template - struct graph_traits< std::vector > - { +template < class EdgeList > struct graph_traits< std::vector< EdgeList > > +{ typedef typename EdgeList::value_type V; typedef V vertex_descriptor; - typedef typename detail::val_edge::type edge_descriptor; + typedef typename detail::val_edge< EdgeList >::type edge_descriptor; typedef typename EdgeList::const_iterator adjacency_iterator; - typedef typename detail::val_out_edge_iter::type - out_edge_iterator; + typedef + typename detail::val_out_edge_iter< EdgeList >::type out_edge_iterator; typedef void in_edge_iterator; typedef void edge_iterator; - typedef counting_iterator vertex_iterator; + typedef counting_iterator< V > vertex_iterator; typedef directed_tag directed_category; typedef allow_parallel_edge_tag edge_parallel_category; typedef vector_as_graph_traversal_tag traversal_category; - typedef typename std::vector::size_type vertices_size_type; + typedef typename std::vector< EdgeList >::size_type vertices_size_type; typedef void edges_size_type; typedef typename EdgeList::size_type degree_size_type; - static V null_vertex() {return V(-1);} - }; - template - struct edge_property_type< std::vector > - { + static V null_vertex() { return V(-1); } +}; +template < class EdgeList > struct edge_property_type< std::vector< EdgeList > > +{ typedef void type; - }; - template - struct vertex_property_type< std::vector > - { +}; +template < class EdgeList > +struct vertex_property_type< std::vector< EdgeList > > +{ typedef void type; - }; - template - struct graph_property_type< std::vector > - { +}; +template < class EdgeList > +struct graph_property_type< std::vector< EdgeList > > +{ typedef void type; - }; +}; } -namespace boost { +namespace boost +{ - namespace detail { +namespace detail +{ // "val" is short for Vector Adjacency List - template - struct val_edge + template < class EdgeList > struct val_edge { - typedef typename EdgeList::value_type V; - typedef std::pair type; + typedef typename EdgeList::value_type V; + typedef std::pair< V, V > type; }; // need rewrite this using boost::iterator_adaptor - template - class val_out_edge_iterator + template < class V, class Iter > class val_out_edge_iterator { - typedef val_out_edge_iterator self; - typedef std::pair Edge; + typedef val_out_edge_iterator self; + typedef std::pair< V, V > Edge; + public: - typedef std::input_iterator_tag iterator_category; - typedef std::pair value_type; - typedef std::ptrdiff_t difference_type; - typedef std::pair* pointer; - typedef const std::pair reference; - val_out_edge_iterator() { } - val_out_edge_iterator(V s, Iter i) : _source(s), _iter(i) { } - Edge operator*() const { return Edge(_source, *_iter); } - self& operator++() { ++_iter; return *this; } - self operator++(int) { self t = *this; ++_iter; return t; } - bool operator==(const self& x) const { return _iter == x._iter; } - bool operator!=(const self& x) const { return _iter != x._iter; } + typedef std::input_iterator_tag iterator_category; + typedef std::pair< V, V > value_type; + typedef std::ptrdiff_t difference_type; + typedef std::pair< V, V >* pointer; + typedef const std::pair< V, V > reference; + val_out_edge_iterator() {} + val_out_edge_iterator(V s, Iter i) : _source(s), _iter(i) {} + Edge operator*() const { return Edge(_source, *_iter); } + self& operator++() + { + ++_iter; + return *this; + } + self operator++(int) + { + self t = *this; + ++_iter; + return t; + } + bool operator==(const self& x) const { return _iter == x._iter; } + bool operator!=(const self& x) const { return _iter != x._iter; } + protected: - V _source; - Iter _iter; + V _source; + Iter _iter; }; - template - struct val_out_edge_iter + template < class EdgeList > struct val_out_edge_iter { - typedef typename EdgeList::value_type V; - typedef typename EdgeList::const_iterator Iter; - typedef val_out_edge_iterator type; + typedef typename EdgeList::value_type V; + typedef typename EdgeList::const_iterator Iter; + typedef val_out_edge_iterator< V, Iter > type; }; - template - struct val_out_edge_ret + template < class EdgeList > struct val_out_edge_ret { - typedef typename val_out_edge_iter::type IncIter; - typedef std::pair type; + typedef typename val_out_edge_iter< EdgeList >::type IncIter; + typedef std::pair< IncIter, IncIter > type; }; - } // namesapce detail +} // namesapce detail - template - typename detail::val_out_edge_ret::type - out_edges(typename EdgeList::value_type v, - const std::vector& g) - { - typedef typename detail::val_out_edge_iter::type Iter; - typedef typename detail::val_out_edge_ret::type return_type; +template < class EdgeList, class Alloc > +typename detail::val_out_edge_ret< EdgeList >::type out_edges( + typename EdgeList::value_type v, const std::vector< EdgeList, Alloc >& g) +{ + typedef typename detail::val_out_edge_iter< EdgeList >::type Iter; + typedef typename detail::val_out_edge_ret< EdgeList >::type return_type; return return_type(Iter(v, g[v].begin()), Iter(v, g[v].end())); - } +} - template - typename EdgeList::size_type - out_degree(typename EdgeList::value_type v, - const std::vector& g) - { +template < class EdgeList, class Alloc > +typename EdgeList::size_type out_degree( + typename EdgeList::value_type v, const std::vector< EdgeList, Alloc >& g) +{ return g[v].size(); - } - - template - std::pair - adjacent_vertices(typename EdgeList::value_type v, - const std::vector& g) - { +} + +template < class EdgeList, class Alloc > +std::pair< typename EdgeList::const_iterator, + typename EdgeList::const_iterator > +adjacent_vertices( + typename EdgeList::value_type v, const std::vector< EdgeList, Alloc >& g) +{ return std::make_pair(g[v].begin(), g[v].end()); - } +} - // source() and target() already provided for pairs in graph_traits.hpp +// source() and target() already provided for pairs in graph_traits.hpp - template - std::pair, - boost::counting_iterator > - vertices(const std::vector& v) - { - typedef boost::counting_iterator Iter; +template < class EdgeList, class Alloc > +std::pair< boost::counting_iterator< typename EdgeList::value_type >, + boost::counting_iterator< typename EdgeList::value_type > > +vertices(const std::vector< EdgeList, Alloc >& v) +{ + typedef boost::counting_iterator< typename EdgeList::value_type > Iter; return std::make_pair(Iter(0), Iter(v.size())); - } +} - template - typename std::vector::size_type - num_vertices(const std::vector& v) - { +template < class EdgeList, class Alloc > +typename std::vector< EdgeList, Alloc >::size_type num_vertices( + const std::vector< EdgeList, Alloc >& v) +{ return v.size(); - } - - template - typename std::pair::type, bool> - add_edge(typename EdgeList::value_type u, typename EdgeList::value_type v, - std::vector& g) - { - typedef typename detail::val_edge::type edge_type; +} + +template < class EdgeList, class Allocator > +typename std::pair< typename detail::val_edge< EdgeList >::type, bool > +add_edge(typename EdgeList::value_type u, typename EdgeList::value_type v, + std::vector< EdgeList, Allocator >& g) +{ + typedef typename detail::val_edge< EdgeList >::type edge_type; g[u].insert(g[u].end(), v); return std::make_pair(edge_type(u, v), true); - } - - template - typename std::pair::type, bool> - edge(typename EdgeList::value_type u, typename EdgeList::value_type v, - std::vector& g) - { - typedef typename detail::val_edge::type edge_type; +} + +template < class EdgeList, class Allocator > +typename std::pair< typename detail::val_edge< EdgeList >::type, bool > edge( + typename EdgeList::value_type u, typename EdgeList::value_type v, + std::vector< EdgeList, Allocator >& g) +{ + typedef typename detail::val_edge< EdgeList >::type edge_type; typename EdgeList::iterator i = g[u].begin(), end = g[u].end(); for (; i != end; ++i) - if (*i == v) - return std::make_pair(edge_type(u, v), true); + if (*i == v) + return std::make_pair(edge_type(u, v), true); return std::make_pair(edge_type(), false); - } +} - template - void - remove_edge(typename EdgeList::value_type u, typename EdgeList::value_type v, - std::vector& g) - { +template < class EdgeList, class Allocator > +void remove_edge(typename EdgeList::value_type u, + typename EdgeList::value_type v, std::vector< EdgeList, Allocator >& g) +{ typename EdgeList::iterator i = std::remove(g[u].begin(), g[u].end(), v); if (i != g[u].end()) - g[u].erase(i, g[u].end()); - } - - template - void - remove_edge(typename detail::val_edge::type e, - std::vector& g) - { + g[u].erase(i, g[u].end()); +} + +template < class EdgeList, class Allocator > +void remove_edge(typename detail::val_edge< EdgeList >::type e, + std::vector< EdgeList, Allocator >& g) +{ typename EdgeList::value_type u, v; u = e.first; v = e.second; // FIXME: edge type does not fully specify the edge to be deleted typename EdgeList::iterator i = std::remove(g[u].begin(), g[u].end(), v); if (i != g[u].end()) - g[u].erase(i, g[u].end()); - } - - template - void - remove_edge_if(Predicate p, - std::vector& g) - { - for (std::size_t u = 0; u < g.size(); ++u) { - // Oops! gcc gets internal compiler error on compose_....... - - typedef typename EdgeList::iterator iterator; - iterator b = g[u].begin(), e = g[u].end(); - - if (!g[u].empty()) { - - for(; b != e;) { - if (p(std::make_pair(u, *b))) { - --e; - if (b == e) - break; - else - iter_swap(b, e); - } else { - ++b; - } - } - } - - if (e != g[u].end()) - g[u].erase(e, g[u].end()); - } - } - - template - typename EdgeList::value_type - add_vertex(std::vector& g) - { - g.resize(g.size()+1); - return g.size()-1; - } - - template - void - clear_vertex(typename EdgeList::value_type u, - std::vector& g) - { + g[u].erase(i, g[u].end()); +} + +template < class EdgeList, class Allocator, class Predicate > +void remove_edge_if(Predicate p, std::vector< EdgeList, Allocator >& g) +{ + for (std::size_t u = 0; u < g.size(); ++u) + { + // Oops! gcc gets internal compiler error on compose_....... + + typedef typename EdgeList::iterator iterator; + iterator b = g[u].begin(), e = g[u].end(); + + if (!g[u].empty()) + { + + for (; b != e;) + { + if (p(std::make_pair(u, *b))) + { + --e; + if (b == e) + break; + else + iter_swap(b, e); + } + else + { + ++b; + } + } + } + + if (e != g[u].end()) + g[u].erase(e, g[u].end()); + } +} + +template < class EdgeList, class Allocator > +typename EdgeList::value_type add_vertex(std::vector< EdgeList, Allocator >& g) +{ + g.resize(g.size() + 1); + return g.size() - 1; +} + +template < class EdgeList, class Allocator > +void clear_vertex( + typename EdgeList::value_type u, std::vector< EdgeList, Allocator >& g) +{ g[u].clear(); for (std::size_t i = 0; i < g.size(); ++i) - remove_edge(i, u, g); - } - - template - void - remove_vertex(typename EdgeList::value_type u, - std::vector& g) - { + remove_edge(i, u, g); +} + +template < class EdgeList, class Allocator > +void remove_vertex( + typename EdgeList::value_type u, std::vector< EdgeList, Allocator >& g) +{ typedef typename EdgeList::iterator iterator; clear_vertex(u, g); g.erase(g.begin() + u); for (std::size_t i = 0; i < g.size(); ++i) - for ( iterator it = g[i].begin(); it != g[i].end(); ++it ) - // after clear_vertex *it is never equal to u - if ( *it > u ) - --*it; - } - - template - struct property_map, vertex_index_t> - { + for (iterator it = g[i].begin(); it != g[i].end(); ++it) + // after clear_vertex *it is never equal to u + if (*it > u) + --*it; +} + +template < typename EdgeList, typename Allocator > +struct property_map< std::vector< EdgeList, Allocator >, vertex_index_t > +{ typedef identity_property_map type; typedef type const_type; - }; +}; - template - identity_property_map - get(vertex_index_t, const std::vector&) - { +template < typename EdgeList, typename Allocator > +identity_property_map get( + vertex_index_t, const std::vector< EdgeList, Allocator >&) +{ return identity_property_map(); - } +} - template - identity_property_map - get(vertex_index_t, std::vector&) - { +template < typename EdgeList, typename Allocator > +identity_property_map get(vertex_index_t, std::vector< EdgeList, Allocator >&) +{ return identity_property_map(); - } +} } // namespace boost #endif // BOOST_VECTOR_AS_GRAPH_HPP diff --git a/include/boost/graph/vertex_and_edge_range.hpp b/include/boost/graph/vertex_and_edge_range.hpp index bcba2bfbb..c9e217bd7 100644 --- a/include/boost/graph/vertex_and_edge_range.hpp +++ b/include/boost/graph/vertex_and_edge_range.hpp @@ -13,129 +13,146 @@ #include #include -namespace boost { - -namespace graph { - template - class vertex_and_edge_range - { - typedef graph_traits traits_type; - - public: - typedef typename traits_type::directed_category directed_category; - typedef typename traits_type::edge_parallel_category - edge_parallel_category; - struct traversal_category - : public virtual vertex_list_graph_tag, - public virtual edge_list_graph_tag { }; - - typedef std::size_t vertices_size_type; - typedef VertexIterator vertex_iterator; - typedef typename std::iterator_traits::value_type - vertex_descriptor; - - typedef EdgeIterator edge_iterator; - typedef typename std::iterator_traits::value_type - edge_descriptor; - - typedef std::size_t edges_size_type; - - typedef void adjacency_iterator; - typedef void out_edge_iterator; - typedef void in_edge_iterator; - typedef void degree_size_type; - - static vertex_descriptor null_vertex() - { return traits_type::null_vertex(); } - - vertex_and_edge_range(const Graph& g, - VertexIterator first_v, VertexIterator last_v, - vertices_size_type n, - EdgeIterator first_e, EdgeIterator last_e, - edges_size_type m) - : g(&g), - first_vertex(first_v), last_vertex(last_v), m_num_vertices(n), - first_edge(first_e), last_edge(last_e), m_num_edges(m) +namespace boost +{ + +namespace graph +{ + template < typename Graph, typename VertexIterator, typename EdgeIterator > + class vertex_and_edge_range + { + typedef graph_traits< Graph > traits_type; + + public: + typedef typename traits_type::directed_category directed_category; + typedef + typename traits_type::edge_parallel_category edge_parallel_category; + struct traversal_category : public virtual vertex_list_graph_tag, + public virtual edge_list_graph_tag + { + }; + + typedef std::size_t vertices_size_type; + typedef VertexIterator vertex_iterator; + typedef typename std::iterator_traits< VertexIterator >::value_type + vertex_descriptor; + + typedef EdgeIterator edge_iterator; + typedef typename std::iterator_traits< EdgeIterator >::value_type + edge_descriptor; + + typedef std::size_t edges_size_type; + + typedef void adjacency_iterator; + typedef void out_edge_iterator; + typedef void in_edge_iterator; + typedef void degree_size_type; + + static vertex_descriptor null_vertex() + { + return traits_type::null_vertex(); + } + + vertex_and_edge_range(const Graph& g, VertexIterator first_v, + VertexIterator last_v, vertices_size_type n, EdgeIterator first_e, + EdgeIterator last_e, edges_size_type m) + : g(&g) + , first_vertex(first_v) + , last_vertex(last_v) + , m_num_vertices(n) + , first_edge(first_e) + , last_edge(last_e) + , m_num_edges(m) + { + } + + vertex_and_edge_range(const Graph& g, VertexIterator first_v, + VertexIterator last_v, EdgeIterator first_e, EdgeIterator last_e) + : g(&g) + , first_vertex(first_v) + , last_vertex(last_v) + , first_edge(first_e) + , last_edge(last_e) + { + m_num_vertices = std::distance(first_v, last_v); + m_num_edges = std::distance(first_e, last_e); + } + + const Graph* g; + vertex_iterator first_vertex; + vertex_iterator last_vertex; + vertices_size_type m_num_vertices; + edge_iterator first_edge; + edge_iterator last_edge; + edges_size_type m_num_edges; + }; + + template < typename Graph, typename VertexIterator, typename EdgeIterator > + inline std::pair< VertexIterator, VertexIterator > vertices( + const vertex_and_edge_range< Graph, VertexIterator, EdgeIterator >& g) + { + return std::make_pair(g.first_vertex, g.last_vertex); + } + + template < typename Graph, typename VertexIterator, typename EdgeIterator > + inline typename vertex_and_edge_range< Graph, VertexIterator, + EdgeIterator >::vertices_size_type + num_vertices( + const vertex_and_edge_range< Graph, VertexIterator, EdgeIterator >& g) + { + return g.m_num_vertices; + } + + template < typename Graph, typename VertexIterator, typename EdgeIterator > + inline std::pair< EdgeIterator, EdgeIterator > edges( + const vertex_and_edge_range< Graph, VertexIterator, EdgeIterator >& g) + { + return std::make_pair(g.first_edge, g.last_edge); + } + + template < typename Graph, typename VertexIterator, typename EdgeIterator > + inline typename vertex_and_edge_range< Graph, VertexIterator, + EdgeIterator >::edges_size_type + num_edges( + const vertex_and_edge_range< Graph, VertexIterator, EdgeIterator >& g) { + return g.m_num_edges; } - vertex_and_edge_range(const Graph& g, - VertexIterator first_v, VertexIterator last_v, - EdgeIterator first_e, EdgeIterator last_e) - : g(&g), - first_vertex(first_v), last_vertex(last_v), - first_edge(first_e), last_edge(last_e) + template < typename Graph, typename VertexIterator, typename EdgeIterator > + inline typename vertex_and_edge_range< Graph, VertexIterator, + EdgeIterator >::vertex_descriptor + source(typename vertex_and_edge_range< Graph, VertexIterator, + EdgeIterator >::edge_descriptor e, + const vertex_and_edge_range< Graph, VertexIterator, EdgeIterator >& g) { - m_num_vertices = std::distance(first_v, last_v); - m_num_edges = std::distance(first_e, last_e); + return source(e, *g.g); } - const Graph* g; - vertex_iterator first_vertex; - vertex_iterator last_vertex; - vertices_size_type m_num_vertices; - edge_iterator first_edge; - edge_iterator last_edge; - edges_size_type m_num_edges; - }; - - template - inline std::pair - vertices(const vertex_and_edge_range& g) - { return std::make_pair(g.first_vertex, g.last_vertex); } - - template - inline typename vertex_and_edge_range - ::vertices_size_type - num_vertices(const vertex_and_edge_range& g) - { return g.m_num_vertices; } - - template - inline std::pair - edges(const vertex_and_edge_range& g) - { return std::make_pair(g.first_edge, g.last_edge); } - - template - inline typename vertex_and_edge_range - ::edges_size_type - num_edges(const vertex_and_edge_range& g) - { return g.m_num_edges; } - - template - inline typename vertex_and_edge_range - ::vertex_descriptor - source(typename vertex_and_edge_range - ::edge_descriptor e, - const vertex_and_edge_range& g) - { return source(e, *g.g); } - - template - inline typename vertex_and_edge_range - ::vertex_descriptor - target(typename vertex_and_edge_range - ::edge_descriptor e, - const vertex_and_edge_range& g) - { return target(e, *g.g); } - - template - inline vertex_and_edge_range - make_vertex_and_edge_range(const Graph& g, - VertexIterator first_v, VertexIterator last_v, - EdgeIterator first_e, EdgeIterator last_e) - { - typedef vertex_and_edge_range - result_type; - return result_type(g, first_v, last_v, first_e, last_e); - } + template < typename Graph, typename VertexIterator, typename EdgeIterator > + inline typename vertex_and_edge_range< Graph, VertexIterator, + EdgeIterator >::vertex_descriptor + target(typename vertex_and_edge_range< Graph, VertexIterator, + EdgeIterator >::edge_descriptor e, + const vertex_and_edge_range< Graph, VertexIterator, EdgeIterator >& g) + { + return target(e, *g.g); + } + + template < typename Graph, typename VertexIterator, typename EdgeIterator > + inline vertex_and_edge_range< Graph, VertexIterator, EdgeIterator > + make_vertex_and_edge_range(const Graph& g, VertexIterator first_v, + VertexIterator last_v, EdgeIterator first_e, EdgeIterator last_e) + { + typedef vertex_and_edge_range< Graph, VertexIterator, EdgeIterator > + result_type; + return result_type(g, first_v, last_v, first_e, last_e); + } } // end namespace graph -using graph::vertex_and_edge_range; using graph::make_vertex_and_edge_range; +using graph::vertex_and_edge_range; } // end namespace boost #endif // BOOST_GRAPH_VERTEX_AND_EDGE_RANGE_HPP diff --git a/include/boost/graph/vf2_sub_graph_iso.hpp b/include/boost/graph/vf2_sub_graph_iso.hpp index 564b00f3d..77f7496bd 100644 --- a/include/boost/graph/vf2_sub_graph_iso.hpp +++ b/include/boost/graph/vf2_sub_graph_iso.hpp @@ -1,9 +1,10 @@ //======================================================================= // Copyright (C) 2012 Flavio De Lorenzi (fdlorenzi@gmail.com) -// Copyright (C) 2013 Jakob Lykke Andersen, University of Southern Denmark (jlandersen@imada.sdu.dk) +// Copyright (C) 2013 Jakob Lykke Andersen, University of Southern Denmark +// (jlandersen@imada.sdu.dk) // -// The algorithm implemented here is derived from original ideas by -// Pasquale Foggia and colaborators. For further information see +// The algorithm implemented here is derived from original ideas by +// Pasquale Foggia and colaborators. For further information see // e.g. Cordella et al. 2001, 2004. // // Distributed under the Boost Software License, Version 1.0. (See @@ -12,7 +13,7 @@ //======================================================================= // Revision History: -// 8 April 2013: Fixed a typo in vf2_print_callback. (Flavio De Lorenzi) +// 8 April 2013: Fixed a typo in vf2_print_callback. (Flavio De Lorenzi) #ifndef BOOST_VF2_SUB_GRAPH_ISO_HPP #define BOOST_VF2_SUB_GRAPH_ISO_HPP @@ -41,621 +42,705 @@ #include #endif -namespace boost { - - // Default print_callback - template - struct vf2_print_callback { - - vf2_print_callback(const Graph1& graph1, const Graph2& graph2) - : graph1_(graph1), graph2_(graph2) {} - - template - bool operator()(CorrespondenceMap1To2 f, CorrespondenceMap2To1) const { - - // Print (sub)graph isomorphism map - BGL_FORALL_VERTICES_T(v, graph1_, Graph1) - std::cout << '(' << get(vertex_index_t(), graph1_, v) << ", " +namespace boost +{ + +// Default print_callback +template < typename Graph1, typename Graph2 > struct vf2_print_callback +{ + + vf2_print_callback(const Graph1& graph1, const Graph2& graph2) + : graph1_(graph1), graph2_(graph2) + { + } + + template < typename CorrespondenceMap1To2, typename CorrespondenceMap2To1 > + bool operator()(CorrespondenceMap1To2 f, CorrespondenceMap2To1) const + { + + // Print (sub)graph isomorphism map + BGL_FORALL_VERTICES_T(v, graph1_, Graph1) + std::cout << '(' << get(vertex_index_t(), graph1_, v) << ", " << get(vertex_index_t(), graph2_, get(f, v)) << ") "; - - std::cout << std::endl; - - return true; + + std::cout << std::endl; + + return true; } - - private: + +private: const Graph1& graph1_; const Graph2& graph2_; - }; - - namespace detail { - +}; + +namespace detail +{ + // State associated with a single graph (graph_this) - template - class base_state { - - typedef typename graph_traits::vertex_descriptor vertex_this_type; - typedef typename graph_traits::vertex_descriptor vertex_other_type; - - typedef typename graph_traits::vertices_size_type size_type; - - const GraphThis& graph_this_; - const GraphOther& graph_other_; - - IndexMapThis index_map_this_; - IndexMapOther index_map_other_; - - std::vector core_vec_; - typedef iterator_property_map::iterator, - IndexMapThis, vertex_other_type, - vertex_other_type&> core_map_type; - core_map_type core_; - - std::vector in_vec_, out_vec_; - typedef iterator_property_map::iterator, - IndexMapThis, size_type, size_type&> in_out_map_type; - in_out_map_type in_, out_; - - size_type term_in_count_, term_out_count_, term_both_count_, core_count_; - - // Forbidden - base_state(const base_state&); - base_state& operator=(const base_state&); + template < typename GraphThis, typename GraphOther, typename IndexMapThis, + typename IndexMapOther > + class base_state + { + + typedef typename graph_traits< GraphThis >::vertex_descriptor + vertex_this_type; + typedef typename graph_traits< GraphOther >::vertex_descriptor + vertex_other_type; + + typedef + typename graph_traits< GraphThis >::vertices_size_type size_type; + + const GraphThis& graph_this_; + const GraphOther& graph_other_; + + IndexMapThis index_map_this_; + IndexMapOther index_map_other_; + + std::vector< vertex_other_type > core_vec_; + typedef iterator_property_map< + typename std::vector< vertex_other_type >::iterator, IndexMapThis, + vertex_other_type, vertex_other_type& > + core_map_type; + core_map_type core_; + + std::vector< size_type > in_vec_, out_vec_; + typedef iterator_property_map< + typename std::vector< size_type >::iterator, IndexMapThis, + size_type, size_type& > + in_out_map_type; + in_out_map_type in_, out_; + + size_type term_in_count_, term_out_count_, term_both_count_, + core_count_; + + // Forbidden + base_state(const base_state&); + base_state& operator=(const base_state&); public: + base_state(const GraphThis& graph_this, const GraphOther& graph_other, + IndexMapThis index_map_this, IndexMapOther index_map_other) + : graph_this_(graph_this) + , graph_other_(graph_other) + , index_map_this_(index_map_this) + , index_map_other_(index_map_other) + , core_vec_(num_vertices(graph_this_), + graph_traits< GraphOther >::null_vertex()) + , core_(core_vec_.begin(), index_map_this_) + , in_vec_(num_vertices(graph_this_), 0) + , out_vec_(num_vertices(graph_this_), 0) + , in_(in_vec_.begin(), index_map_this_) + , out_(out_vec_.begin(), index_map_this_) + , term_in_count_(0) + , term_out_count_(0) + , term_both_count_(0) + , core_count_(0) + { + } - base_state(const GraphThis& graph_this, const GraphOther& graph_other, - IndexMapThis index_map_this, IndexMapOther index_map_other) - : graph_this_(graph_this), graph_other_(graph_other), - index_map_this_(index_map_this), index_map_other_(index_map_other), - core_vec_(num_vertices(graph_this_), graph_traits::null_vertex()), - core_(core_vec_.begin(), index_map_this_), - in_vec_(num_vertices(graph_this_), 0), - out_vec_(num_vertices(graph_this_), 0), - in_(in_vec_.begin(), index_map_this_), - out_(out_vec_.begin(), index_map_this_), - term_in_count_(0), term_out_count_(0), term_both_count_(0), core_count_(0) { - } - - // Adds a vertex pair to the state of graph graph_this - void push(const vertex_this_type& v_this, const vertex_other_type& v_other) { - - ++core_count_; - - put(core_, v_this, v_other); - - if (!get(in_, v_this)) { - put(in_, v_this, core_count_); - ++term_in_count_; - if (get(out_, v_this)) - ++term_both_count_; + // Adds a vertex pair to the state of graph graph_this + void push( + const vertex_this_type& v_this, const vertex_other_type& v_other) + { + + ++core_count_; + + put(core_, v_this, v_other); + + if (!get(in_, v_this)) + { + put(in_, v_this, core_count_); + ++term_in_count_; + if (get(out_, v_this)) + ++term_both_count_; + } + + if (!get(out_, v_this)) + { + put(out_, v_this, core_count_); + ++term_out_count_; + if (get(in_, v_this)) + ++term_both_count_; + } + + BGL_FORALL_INEDGES_T(v_this, e, graph_this_, GraphThis) + { + vertex_this_type w = source(e, graph_this_); + if (!get(in_, w)) + { + put(in_, w, core_count_); + ++term_in_count_; + if (get(out_, w)) + ++term_both_count_; + } + } + + BGL_FORALL_OUTEDGES_T(v_this, e, graph_this_, GraphThis) + { + vertex_this_type w = target(e, graph_this_); + if (!get(out_, w)) + { + put(out_, w, core_count_); + ++term_out_count_; + if (get(in_, w)) + ++term_both_count_; + } + } } - if (!get(out_, v_this)) { - put(out_, v_this, core_count_); - ++term_out_count_; - if (get(in_, v_this)) - ++term_both_count_; + // Removes vertex pair from state of graph_this + void pop(const vertex_this_type& v_this, const vertex_other_type&) + { + + if (!core_count_) + return; + + if (get(in_, v_this) == core_count_) + { + put(in_, v_this, 0); + --term_in_count_; + if (get(out_, v_this)) + --term_both_count_; + } + + BGL_FORALL_INEDGES_T(v_this, e, graph_this_, GraphThis) + { + vertex_this_type w = source(e, graph_this_); + if (get(in_, w) == core_count_) + { + put(in_, w, 0); + --term_in_count_; + if (get(out_, w)) + --term_both_count_; + } + } + + if (get(out_, v_this) == core_count_) + { + put(out_, v_this, 0); + --term_out_count_; + if (get(in_, v_this)) + --term_both_count_; + } + + BGL_FORALL_OUTEDGES_T(v_this, e, graph_this_, GraphThis) + { + vertex_this_type w = target(e, graph_this_); + if (get(out_, w) == core_count_) + { + put(out_, w, 0); + --term_out_count_; + if (get(in_, w)) + --term_both_count_; + } + } + put(core_, v_this, graph_traits< GraphOther >::null_vertex()); + + --core_count_; } - BGL_FORALL_INEDGES_T(v_this, e, graph_this_, GraphThis) { - vertex_this_type w = source(e, graph_this_); - if (!get(in_, w)) { - put(in_, w, core_count_); - ++term_in_count_; - if (get(out_, w)) - ++term_both_count_; - } + // Returns true if the in-terminal set is not empty + bool term_in() const { return core_count_ < term_in_count_; } + + // Returns true if vertex belongs to the in-terminal set + bool term_in(const vertex_this_type& v) const + { + return (get(in_, v) > 0) + && (get(core_, v) == graph_traits< GraphOther >::null_vertex()); } - - BGL_FORALL_OUTEDGES_T(v_this, e, graph_this_, GraphThis) { - vertex_this_type w = target(e, graph_this_); - if (!get(out_, w)) { - put(out_, w, core_count_); - ++term_out_count_; - if (get(in_, w)) - ++term_both_count_; - } + + // Returns true if the out-terminal set is not empty + bool term_out() const { return core_count_ < term_out_count_; } + + // Returns true if vertex belongs to the out-terminal set + bool term_out(const vertex_this_type& v) const + { + return (get(out_, v) > 0) + && (get(core_, v) == graph_traits< GraphOther >::null_vertex()); } - - } - - // Removes vertex pair from state of graph_this - void pop(const vertex_this_type& v_this, const vertex_other_type&) { - - if (!core_count_) return; - - if (get(in_, v_this) == core_count_) { - put(in_, v_this, 0); - --term_in_count_; - if (get(out_, v_this)) - --term_both_count_; + + // Returns true of both (in- and out-terminal) sets are not empty + bool term_both() const { return core_count_ < term_both_count_; } + + // Returns true if vertex belongs to both (in- and out-terminal) sets + bool term_both(const vertex_this_type& v) const + { + return (get(in_, v) > 0) && (get(out_, v) > 0) + && (get(core_, v) == graph_traits< GraphOther >::null_vertex()); } - BGL_FORALL_INEDGES_T(v_this, e, graph_this_, GraphThis) { - vertex_this_type w = source(e, graph_this_); - if (get(in_, w) == core_count_) { - put(in_, w, 0); - --term_in_count_; - if (get(out_, w)) - --term_both_count_; - } + // Returns true if vertex belongs to the core map, i.e. it is in the + // present mapping + bool in_core(const vertex_this_type& v) const + { + return get(core_, v) != graph_traits< GraphOther >::null_vertex(); } - if (get(out_, v_this) == core_count_) { - put(out_, v_this, 0); - --term_out_count_; - if (get(in_, v_this)) - --term_both_count_; + // Returns the number of vertices in the mapping + size_type count() const { return core_count_; } + + // Returns the image (in graph_other) of vertex v (in graph_this) + vertex_other_type core(const vertex_this_type& v) const + { + return get(core_, v); } - BGL_FORALL_OUTEDGES_T(v_this, e, graph_this_, GraphThis) { - vertex_this_type w = target(e, graph_this_); - if (get(out_, w) == core_count_) { - put(out_, w, 0); - --term_out_count_; - if (get(in_, w)) - --term_both_count_; - } + // Returns the mapping + core_map_type get_map() const { return core_; } + + // Returns the "time" (or depth) when vertex was added to the + // in-terminal set + size_type in_depth(const vertex_this_type& v) const + { + return get(in_, v); } - put(core_, v_this, graph_traits::null_vertex()); - - --core_count_; - - } - - // Returns true if the in-terminal set is not empty - bool term_in() const { - return core_count_ < term_in_count_ ; - } - - // Returns true if vertex belongs to the in-terminal set - bool term_in(const vertex_this_type& v) const { - return (get(in_, v) > 0) && - (get(core_, v) == graph_traits::null_vertex()); - } - - // Returns true if the out-terminal set is not empty - bool term_out() const { - return core_count_ < term_out_count_; - } - - // Returns true if vertex belongs to the out-terminal set - bool term_out(const vertex_this_type& v) const { - return (get(out_, v) > 0) && - (get(core_, v) == graph_traits::null_vertex()); - } - - // Returns true of both (in- and out-terminal) sets are not empty - bool term_both() const { - return core_count_ < term_both_count_; - } - - // Returns true if vertex belongs to both (in- and out-terminal) sets - bool term_both(const vertex_this_type& v) const { - return (get(in_, v) > 0) && (get(out_, v) > 0) && - (get(core_, v) == graph_traits::null_vertex()); - } - - // Returns true if vertex belongs to the core map, i.e. it is in the - // present mapping - bool in_core(const vertex_this_type& v) const { - return get(core_, v) != graph_traits::null_vertex(); - } - - // Returns the number of vertices in the mapping - size_type count() const { - return core_count_; - } - - // Returns the image (in graph_other) of vertex v (in graph_this) - vertex_other_type core(const vertex_this_type& v) const { - return get(core_, v); - } - - // Returns the mapping - core_map_type get_map() const { - return core_; - } - - // Returns the "time" (or depth) when vertex was added to the in-terminal set - size_type in_depth(const vertex_this_type& v) const { - return get(in_, v); - } - - // Returns the "time" (or depth) when vertex was added to the out-terminal set - size_type out_depth(const vertex_this_type& v) const { - return get(out_, v); - } - - // Returns the terminal set counts - boost::tuple - term_set() const { - return boost::make_tuple(term_in_count_, term_out_count_, - term_both_count_); - } - - }; + // Returns the "time" (or depth) when vertex was added to the + // out-terminal set + size_type out_depth(const vertex_this_type& v) const + { + return get(out_, v); + } - // Function object that checks whether a valid edge - // exists. For multi-graphs matched edges are excluded - template - struct equivalent_edge_exists { - typedef typename boost::graph_traits::edge_descriptor edge_type; - - BOOST_CONCEPT_ASSERT(( LessThanComparable )); - - template - bool operator()(typename graph_traits::vertex_descriptor s, - typename graph_traits::vertex_descriptor t, - EdgePredicate is_valid_edge, const Graph& g) { - - BGL_FORALL_OUTEDGES_T(s, e, g, Graph) { - if ((target(e, g) == t) && is_valid_edge(e) && - (matched_edges_.find(e) == matched_edges_.end())) { - matched_edges_.insert(e); - return true; - } + // Returns the terminal set counts + boost::tuple< size_type, size_type, size_type > term_set() const + { + return boost::make_tuple( + term_in_count_, term_out_count_, term_both_count_); } + }; - return false; - } + // Function object that checks whether a valid edge + // exists. For multi-graphs matched edges are excluded + template < typename Graph, typename Enable = void > + struct equivalent_edge_exists + { + typedef + typename boost::graph_traits< Graph >::edge_descriptor edge_type; + + BOOST_CONCEPT_ASSERT((LessThanComparable< edge_type >)); + + template < typename EdgePredicate > + bool operator()(typename graph_traits< Graph >::vertex_descriptor s, + typename graph_traits< Graph >::vertex_descriptor t, + EdgePredicate is_valid_edge, const Graph& g) + { + + BGL_FORALL_OUTEDGES_T(s, e, g, Graph) + { + if ((target(e, g) == t) && is_valid_edge(e) + && (matched_edges_.find(e) == matched_edges_.end())) + { + matched_edges_.insert(e); + return true; + } + } + + return false; + } private: - - std::set matched_edges_; - }; - - template - struct equivalent_edge_exists >::type> { - template - bool operator()(typename graph_traits::vertex_descriptor s, - typename graph_traits::vertex_descriptor t, - EdgePredicate is_valid_edge, const Graph& g) { - - typename graph_traits::edge_descriptor e; - bool found; - boost::tie(e, found) = edge(s, t, g); - if (!found) - return false; - else if (is_valid_edge(e)) - return true; - - return false; - } - + std::set< edge_type > matched_edges_; }; + template < typename Graph > + struct equivalent_edge_exists< Graph, + typename boost::disable_if< is_multigraph< Graph > >::type > + { + template < typename EdgePredicate > + bool operator()(typename graph_traits< Graph >::vertex_descriptor s, + typename graph_traits< Graph >::vertex_descriptor t, + EdgePredicate is_valid_edge, const Graph& g) + { + + typename graph_traits< Graph >::edge_descriptor e; + bool found; + boost::tie(e, found) = edge(s, t, g); + if (!found) + return false; + else if (is_valid_edge(e)) + return true; - // Generates a predicate for edge e1 given a binary predicate and a - // fixed edge e2 - template - struct edge1_predicate { - - edge1_predicate(EdgeEquivalencePredicate edge_comp, - typename graph_traits::edge_descriptor e2) - : edge_comp_(edge_comp), e2_(e2) {} - - bool operator()(typename graph_traits::edge_descriptor e1) { - return edge_comp_(e1, e2_); - } - - EdgeEquivalencePredicate edge_comp_; - typename graph_traits::edge_descriptor e2_; + return false; + } }; + // Generates a predicate for edge e1 given a binary predicate and a + // fixed edge e2 + template < typename Graph1, typename Graph2, + typename EdgeEquivalencePredicate > + struct edge1_predicate + { + + edge1_predicate(EdgeEquivalencePredicate edge_comp, + typename graph_traits< Graph2 >::edge_descriptor e2) + : edge_comp_(edge_comp), e2_(e2) + { + } + + bool operator()(typename graph_traits< Graph1 >::edge_descriptor e1) + { + return edge_comp_(e1, e2_); + } + + EdgeEquivalencePredicate edge_comp_; + typename graph_traits< Graph2 >::edge_descriptor e2_; + }; // Generates a predicate for edge e2 given given a binary predicate and a // fixed edge e1 - template - struct edge2_predicate { - - edge2_predicate(EdgeEquivalencePredicate edge_comp, - typename graph_traits::edge_descriptor e1) - : edge_comp_(edge_comp), e1_(e1) {} - - bool operator()(typename graph_traits::edge_descriptor e2) { - return edge_comp_(e1_, e2); - } - - EdgeEquivalencePredicate edge_comp_; - typename graph_traits::edge_descriptor e1_; + template < typename Graph1, typename Graph2, + typename EdgeEquivalencePredicate > + struct edge2_predicate + { + + edge2_predicate(EdgeEquivalencePredicate edge_comp, + typename graph_traits< Graph1 >::edge_descriptor e1) + : edge_comp_(edge_comp), e1_(e1) + { + } + + bool operator()(typename graph_traits< Graph2 >::edge_descriptor e2) + { + return edge_comp_(e1_, e2); + } + + EdgeEquivalencePredicate edge_comp_; + typename graph_traits< Graph1 >::edge_descriptor e1_; }; + enum problem_selector + { + subgraph_mono, + subgraph_iso, + isomorphism + }; - enum problem_selector {subgraph_mono, subgraph_iso, isomorphism }; - // The actual state associated with both graphs - template - class state { - - typedef typename graph_traits::vertex_descriptor vertex1_type; - typedef typename graph_traits::vertex_descriptor vertex2_type; - - typedef typename graph_traits::edge_descriptor edge1_type; - typedef typename graph_traits::edge_descriptor edge2_type; - - typedef typename graph_traits::vertices_size_type graph1_size_type; - typedef typename graph_traits::vertices_size_type graph2_size_type; - - const Graph1& graph1_; - const Graph2& graph2_; - - IndexMap1 index_map1_; - - EdgeEquivalencePredicate edge_comp_; - VertexEquivalencePredicate vertex_comp_; - - base_state state1_; - base_state state2_; - - // Three helper functions used in Feasibility and Valid functions to test - // terminal set counts when testing for: - // - graph sub-graph monomorphism, or - inline bool comp_term_sets(graph1_size_type a, - graph2_size_type b, - boost::mpl::int_) const { - return a <= b; - } - - // - graph sub-graph isomorphism, or - inline bool comp_term_sets(graph1_size_type a, - graph2_size_type b, - boost::mpl::int_) const { - return a <= b; - } - - // - graph isomorphism - inline bool comp_term_sets(graph1_size_type a, - graph2_size_type b, - boost::mpl::int_) const { - return a == b; - } - - // Forbidden - state(const state&); - state& operator=(const state&); + template < typename Graph1, typename Graph2, typename IndexMap1, + typename IndexMap2, typename EdgeEquivalencePredicate, + typename VertexEquivalencePredicate, typename SubGraphIsoMapCallback, + problem_selector problem_selection > + class state + { - public: + typedef typename graph_traits< Graph1 >::vertex_descriptor vertex1_type; + typedef typename graph_traits< Graph2 >::vertex_descriptor vertex2_type; + + typedef typename graph_traits< Graph1 >::edge_descriptor edge1_type; + typedef typename graph_traits< Graph2 >::edge_descriptor edge2_type; + + typedef typename graph_traits< Graph1 >::vertices_size_type + graph1_size_type; + typedef typename graph_traits< Graph2 >::vertices_size_type + graph2_size_type; + + const Graph1& graph1_; + const Graph2& graph2_; + + IndexMap1 index_map1_; + + EdgeEquivalencePredicate edge_comp_; + VertexEquivalencePredicate vertex_comp_; + + base_state< Graph1, Graph2, IndexMap1, IndexMap2 > state1_; + base_state< Graph2, Graph1, IndexMap2, IndexMap1 > state2_; + + // Three helper functions used in Feasibility and Valid functions to + // test terminal set counts when testing for: + // - graph sub-graph monomorphism, or + inline bool comp_term_sets(graph1_size_type a, graph2_size_type b, + boost::mpl::int_< subgraph_mono >) const + { + return a <= b; + } + + // - graph sub-graph isomorphism, or + inline bool comp_term_sets(graph1_size_type a, graph2_size_type b, + boost::mpl::int_< subgraph_iso >) const + { + return a <= b; + } - state(const Graph1& graph1, const Graph2& graph2, - IndexMap1 index_map1, IndexMap2 index_map2, - EdgeEquivalencePredicate edge_comp, + // - graph isomorphism + inline bool comp_term_sets(graph1_size_type a, graph2_size_type b, + boost::mpl::int_< isomorphism >) const + { + return a == b; + } + + // Forbidden + state(const state&); + state& operator=(const state&); + + public: + state(const Graph1& graph1, const Graph2& graph2, IndexMap1 index_map1, + IndexMap2 index_map2, EdgeEquivalencePredicate edge_comp, VertexEquivalencePredicate vertex_comp) - : graph1_(graph1), graph2_(graph2), - index_map1_(index_map1), - edge_comp_(edge_comp), vertex_comp_(vertex_comp), - state1_(graph1, graph2, index_map1, index_map2), - state2_(graph2, graph1, index_map2, index_map1) {} - - // Add vertex pair to the state - void push(const vertex1_type& v, const vertex2_type& w) { - state1_.push(v, w); - state2_.push(w, v); - } - - // Remove vertex pair from state - void pop(const vertex1_type& v, const vertex2_type&) { - vertex2_type w = state1_.core(v); - state1_.pop(v, w); - state2_.pop(w, v); - } - - // Checks the feasibility of a new vertex pair - bool feasible(const vertex1_type& v_new, const vertex2_type& w_new) { - - if (!vertex_comp_(v_new, w_new)) return false; - - // graph1 - graph1_size_type term_in1_count = 0, term_out1_count = 0, rest1_count = 0; - + : graph1_(graph1) + , graph2_(graph2) + , index_map1_(index_map1) + , edge_comp_(edge_comp) + , vertex_comp_(vertex_comp) + , state1_(graph1, graph2, index_map1, index_map2) + , state2_(graph2, graph1, index_map2, index_map1) { - equivalent_edge_exists edge2_exists; - - BGL_FORALL_INEDGES_T(v_new, e1, graph1_, Graph1) { - vertex1_type v = source(e1, graph1_); - - if (state1_.in_core(v) || (v == v_new)) { - vertex2_type w = w_new; - if (v != v_new) - w = state1_.core(v); - if (!edge2_exists(w, w_new, - edge2_predicate(edge_comp_, e1), - graph2_)) - return false; - - } else { - if (0 < state1_.in_depth(v)) - ++term_in1_count; - if (0 < state1_.out_depth(v)) - ++term_out1_count; - if ((state1_.in_depth(v) == 0) && (state1_.out_depth(v) == 0)) - ++rest1_count; - } - } } - + + // Add vertex pair to the state + void push(const vertex1_type& v, const vertex2_type& w) { - equivalent_edge_exists edge2_exists; - - BGL_FORALL_OUTEDGES_T(v_new, e1, graph1_, Graph1) { - vertex1_type v = target(e1, graph1_); - if (state1_.in_core(v) || (v == v_new)) { - vertex2_type w = w_new; - if (v != v_new) - w = state1_.core(v); - - if (!edge2_exists(w_new, w, - edge2_predicate(edge_comp_, e1), - graph2_)) + state1_.push(v, w); + state2_.push(w, v); + } + + // Remove vertex pair from state + void pop(const vertex1_type& v, const vertex2_type&) + { + vertex2_type w = state1_.core(v); + state1_.pop(v, w); + state2_.pop(w, v); + } + + // Checks the feasibility of a new vertex pair + bool feasible(const vertex1_type& v_new, const vertex2_type& w_new) + { + + if (!vertex_comp_(v_new, w_new)) return false; - - } else { - if (0 < state1_.in_depth(v)) - ++term_in1_count; - if (0 < state1_.out_depth(v)) - ++term_out1_count; - if ((state1_.in_depth(v) == 0) && (state1_.out_depth(v) == 0)) - ++rest1_count; + + // graph1 + graph1_size_type term_in1_count = 0, term_out1_count = 0, + rest1_count = 0; + + { + equivalent_edge_exists< Graph2 > edge2_exists; + + BGL_FORALL_INEDGES_T(v_new, e1, graph1_, Graph1) + { + vertex1_type v = source(e1, graph1_); + + if (state1_.in_core(v) || (v == v_new)) + { + vertex2_type w = w_new; + if (v != v_new) + w = state1_.core(v); + if (!edge2_exists(w, w_new, + edge2_predicate< Graph1, Graph2, + EdgeEquivalencePredicate >(edge_comp_, e1), + graph2_)) + return false; + } + else + { + if (0 < state1_.in_depth(v)) + ++term_in1_count; + if (0 < state1_.out_depth(v)) + ++term_out1_count; + if ((state1_.in_depth(v) == 0) + && (state1_.out_depth(v) == 0)) + ++rest1_count; + } + } + } + + { + equivalent_edge_exists< Graph2 > edge2_exists; + + BGL_FORALL_OUTEDGES_T(v_new, e1, graph1_, Graph1) + { + vertex1_type v = target(e1, graph1_); + if (state1_.in_core(v) || (v == v_new)) + { + vertex2_type w = w_new; + if (v != v_new) + w = state1_.core(v); + + if (!edge2_exists(w_new, w, + edge2_predicate< Graph1, Graph2, + EdgeEquivalencePredicate >(edge_comp_, e1), + graph2_)) + return false; + } + else + { + if (0 < state1_.in_depth(v)) + ++term_in1_count; + if (0 < state1_.out_depth(v)) + ++term_out1_count; + if ((state1_.in_depth(v) == 0) + && (state1_.out_depth(v) == 0)) + ++rest1_count; + } + } + } + + // graph2 + graph2_size_type term_out2_count = 0, term_in2_count = 0, + rest2_count = 0; + + { + equivalent_edge_exists< Graph1 > edge1_exists; + + BGL_FORALL_INEDGES_T(w_new, e2, graph2_, Graph2) + { + vertex2_type w = source(e2, graph2_); + if (state2_.in_core(w) || (w == w_new)) + { + if (problem_selection != subgraph_mono) + { + vertex1_type v = v_new; + if (w != w_new) + v = state2_.core(w); + + if (!edge1_exists(v, v_new, + edge1_predicate< Graph1, Graph2, + EdgeEquivalencePredicate >( + edge_comp_, e2), + graph1_)) + return false; + } + } + else + { + if (0 < state2_.in_depth(w)) + ++term_in2_count; + if (0 < state2_.out_depth(w)) + ++term_out2_count; + if ((state2_.in_depth(w) == 0) + && (state2_.out_depth(w) == 0)) + ++rest2_count; + } + } } - } + + { + equivalent_edge_exists< Graph1 > edge1_exists; + + BGL_FORALL_OUTEDGES_T(w_new, e2, graph2_, Graph2) + { + vertex2_type w = target(e2, graph2_); + if (state2_.in_core(w) || (w == w_new)) + { + if (problem_selection != subgraph_mono) + { + vertex1_type v = v_new; + if (w != w_new) + v = state2_.core(w); + + if (!edge1_exists(v_new, v, + edge1_predicate< Graph1, Graph2, + EdgeEquivalencePredicate >( + edge_comp_, e2), + graph1_)) + return false; + } + } + else + { + if (0 < state2_.in_depth(w)) + ++term_in2_count; + if (0 < state2_.out_depth(w)) + ++term_out2_count; + if ((state2_.in_depth(w) == 0) + && (state2_.out_depth(w) == 0)) + ++rest2_count; + } + } + } + + if (problem_selection != subgraph_mono) + { // subgraph_iso and isomorphism + return comp_term_sets(term_in1_count, term_in2_count, + boost::mpl::int_< problem_selection >()) + && comp_term_sets(term_out1_count, term_out2_count, + boost::mpl::int_< problem_selection >()) + && comp_term_sets(rest1_count, rest2_count, + boost::mpl::int_< problem_selection >()); + } + else + { // subgraph_mono + return comp_term_sets(term_in1_count, term_in2_count, + boost::mpl::int_< problem_selection >()) + && comp_term_sets(term_out1_count, term_out2_count, + boost::mpl::int_< problem_selection >()) + && comp_term_sets( + term_in1_count + term_out1_count + rest1_count, + term_in2_count + term_out2_count + rest2_count, + boost::mpl::int_< problem_selection >()); + } + } + + // Returns true if vertex v in graph1 is a possible candidate to + // be added to the current state + bool possible_candidate1(const vertex1_type& v) const + { + if (state1_.term_both() && state2_.term_both()) + return state1_.term_both(v); + else if (state1_.term_out() && state2_.term_out()) + return state1_.term_out(v); + else if (state1_.term_in() && state2_.term_in()) + return state1_.term_in(v); + else + return !state1_.in_core(v); } - - // graph2 - graph2_size_type term_out2_count = 0, term_in2_count = 0, rest2_count = 0; - + + // Returns true if vertex w in graph2 is a possible candidate to + // be added to the current state + bool possible_candidate2(const vertex2_type& w) const { - equivalent_edge_exists edge1_exists; - - BGL_FORALL_INEDGES_T(w_new, e2, graph2_, Graph2) { - vertex2_type w = source(e2, graph2_); - if (state2_.in_core(w) || (w == w_new)) { - if (problem_selection != subgraph_mono) { - vertex1_type v = v_new; - if (w != w_new) - v = state2_.core(w); - - if (!edge1_exists(v, v_new, - edge1_predicate(edge_comp_, e2), - graph1_)) - return false; - } - } else { - if (0 < state2_.in_depth(w)) - ++term_in2_count; - if (0 < state2_.out_depth(w)) - ++term_out2_count; - if ((state2_.in_depth(w) == 0) && (state2_.out_depth(w) == 0)) - ++rest2_count; - } - } + if (state1_.term_both() && state2_.term_both()) + return state2_.term_both(w); + else if (state1_.term_out() && state2_.term_out()) + return state2_.term_out(w); + else if (state1_.term_in() && state2_.term_in()) + return state2_.term_in(w); + else + return !state2_.in_core(w); } + // Returns true if a mapping was found + bool success() const { - equivalent_edge_exists edge1_exists; - - BGL_FORALL_OUTEDGES_T(w_new, e2, graph2_, Graph2) { - vertex2_type w = target(e2, graph2_); - if (state2_.in_core(w) || (w == w_new)) { - if (problem_selection != subgraph_mono) { - vertex1_type v = v_new; - if (w != w_new) - v = state2_.core(w); - - if (!edge1_exists(v_new, v, - edge1_predicate(edge_comp_, e2), - graph1_)) - return false; - } - } else { - if (0 < state2_.in_depth(w)) - ++term_in2_count; - if (0 < state2_.out_depth(w)) - ++term_out2_count; - if ((state2_.in_depth(w) == 0) && (state2_.out_depth(w) == 0)) - ++rest2_count; - } - } + return state1_.count() == num_vertices(graph1_); + } + + // Returns true if a state is valid + bool valid() const + { + boost::tuple< graph1_size_type, graph1_size_type, graph1_size_type > + term1; + boost::tuple< graph2_size_type, graph2_size_type, graph2_size_type > + term2; + + term1 = state1_.term_set(); + term2 = state2_.term_set(); + + return comp_term_sets(boost::get< 0 >(term1), + boost::get< 0 >(term2), + boost::mpl::int_< problem_selection >()) + && comp_term_sets(boost::get< 1 >(term1), + boost::get< 1 >(term2), + boost::mpl::int_< problem_selection >()) + && comp_term_sets(boost::get< 2 >(term1), + boost::get< 2 >(term2), + boost::mpl::int_< problem_selection >()); } - if (problem_selection != subgraph_mono) { // subgraph_iso and isomorphism - return comp_term_sets(term_in1_count, term_in2_count, - boost::mpl::int_()) && - comp_term_sets(term_out1_count, term_out2_count, - boost::mpl::int_()) && - comp_term_sets(rest1_count, rest2_count, - boost::mpl::int_()); - } else { // subgraph_mono - return comp_term_sets(term_in1_count, term_in2_count, - boost::mpl::int_()) && - comp_term_sets(term_out1_count, term_out2_count, - boost::mpl::int_()) && - comp_term_sets(term_in1_count + term_out1_count + rest1_count, - term_in2_count + term_out2_count + rest2_count, - boost::mpl::int_()); + // Calls the user_callback with a graph (sub)graph mapping + bool call_back(SubGraphIsoMapCallback user_callback) const + { + return user_callback(state1_.get_map(), state2_.get_map()); } - } - - // Returns true if vertex v in graph1 is a possible candidate to - // be added to the current state - bool possible_candidate1(const vertex1_type& v) const { - if (state1_.term_both() && state2_.term_both()) - return state1_.term_both(v); - else if (state1_.term_out() && state2_.term_out()) - return state1_.term_out(v); - else if (state1_.term_in() && state2_.term_in()) - return state1_.term_in(v); - else - return !state1_.in_core(v); - } - - // Returns true if vertex w in graph2 is a possible candidate to - // be added to the current state - bool possible_candidate2(const vertex2_type& w) const { - if (state1_.term_both() && state2_.term_both()) - return state2_.term_both(w); - else if (state1_.term_out() && state2_.term_out()) - return state2_.term_out(w); - else if (state1_.term_in() && state2_.term_in()) - return state2_.term_in(w); - else - return !state2_.in_core(w); - } - - // Returns true if a mapping was found - bool success() const { - return state1_.count() == num_vertices(graph1_); - } - - // Returns true if a state is valid - bool valid() const { - boost::tuple term1; - boost::tuple term2; - - term1 = state1_.term_set(); - term2 = state2_.term_set(); - - return comp_term_sets(boost::get<0>(term1), boost::get<0>(term2), - boost::mpl::int_()) && - comp_term_sets(boost::get<1>(term1), boost::get<1>(term2), - boost::mpl::int_()) && - comp_term_sets(boost::get<2>(term1), boost::get<2>(term2), - boost::mpl::int_()); - } - - // Calls the user_callback with a graph (sub)graph mapping - bool call_back(SubGraphIsoMapCallback user_callback) const { - return user_callback(state1_.get_map(), state2_.get_map()); - } - }; - // Data structure to keep info used for back tracking during // matching process - template - struct vf2_match_continuation { - typename VertexOrder1::const_iterator graph1_verts_iter; - typename graph_traits::vertex_iterator graph2_verts_iter; + template < typename Graph1, typename Graph2, typename VertexOrder1 > + struct vf2_match_continuation + { + typename VertexOrder1::const_iterator graph1_verts_iter; + typename graph_traits< Graph2 >::vertex_iterator graph2_verts_iter; }; // Non-recursive method that explores state space using a depth-first @@ -665,560 +750,546 @@ namespace boost { // of a correspondence map (graph1 to graph2). Returning false from the // user_callback will terminate the search. Function match will return // true if the entire search space was explored. - template - bool match(const Graph1& graph1, const Graph2& graph2, - SubGraphIsoMapCallback user_callback, const VertexOrder1& vertex_order1, - state& s) { - - typename VertexOrder1::const_iterator graph1_verts_iter; - - typedef typename graph_traits::vertex_iterator vertex2_iterator_type; - vertex2_iterator_type graph2_verts_iter, graph2_verts_iter_end; - - typedef vf2_match_continuation match_continuation_type; - std::vector k; - bool found_match = false; - - recur: - if (s.success()) { - if (!s.call_back(user_callback)) - return true; - found_match = true; - - goto back_track; - } - - if (!s.valid()) - goto back_track; - - graph1_verts_iter = vertex_order1.begin(); - while (graph1_verts_iter != vertex_order1.end() && - !s.possible_candidate1(*graph1_verts_iter)) { - ++graph1_verts_iter; - } - - boost::tie(graph2_verts_iter, graph2_verts_iter_end) = vertices(graph2); - while (graph2_verts_iter != graph2_verts_iter_end) { - if (s.possible_candidate2(*graph2_verts_iter)) { - if (s.feasible(*graph1_verts_iter, *graph2_verts_iter)) { - match_continuation_type kk; - kk.graph1_verts_iter = graph1_verts_iter; - kk.graph2_verts_iter = graph2_verts_iter; - k.push_back(kk); - - s.push(*graph1_verts_iter, *graph2_verts_iter); - goto recur; - } + template < typename Graph1, typename Graph2, typename IndexMap1, + typename IndexMap2, typename VertexOrder1, + typename EdgeEquivalencePredicate, typename VertexEquivalencePredicate, + typename SubGraphIsoMapCallback, problem_selector problem_selection > + bool match(const Graph1& graph1, const Graph2& graph2, + SubGraphIsoMapCallback user_callback, const VertexOrder1& vertex_order1, + state< Graph1, Graph2, IndexMap1, IndexMap2, EdgeEquivalencePredicate, + VertexEquivalencePredicate, SubGraphIsoMapCallback, + problem_selection >& s) + { + + typename VertexOrder1::const_iterator graph1_verts_iter; + + typedef typename graph_traits< Graph2 >::vertex_iterator + vertex2_iterator_type; + vertex2_iterator_type graph2_verts_iter, graph2_verts_iter_end; + + typedef vf2_match_continuation< Graph1, Graph2, VertexOrder1 > + match_continuation_type; + std::vector< match_continuation_type > k; + bool found_match = false; + + recur: + if (s.success()) + { + if (!s.call_back(user_callback)) + return true; + found_match = true; + + goto back_track; } - graph2_loop: ++graph2_verts_iter; - } - - back_track: - if (k.empty()) - return found_match; - - const match_continuation_type kk = k.back(); - graph1_verts_iter = kk.graph1_verts_iter; - graph2_verts_iter = kk.graph2_verts_iter; - k.pop_back(); - - s.pop(*graph1_verts_iter, *graph2_verts_iter); - - goto graph2_loop; - } + if (!s.valid()) + goto back_track; + + graph1_verts_iter = vertex_order1.begin(); + while (graph1_verts_iter != vertex_order1.end() + && !s.possible_candidate1(*graph1_verts_iter)) + { + ++graph1_verts_iter; + } + + boost::tie(graph2_verts_iter, graph2_verts_iter_end) = vertices(graph2); + while (graph2_verts_iter != graph2_verts_iter_end) + { + if (s.possible_candidate2(*graph2_verts_iter)) + { + if (s.feasible(*graph1_verts_iter, *graph2_verts_iter)) + { + match_continuation_type kk; + kk.graph1_verts_iter = graph1_verts_iter; + kk.graph2_verts_iter = graph2_verts_iter; + k.push_back(kk); + + s.push(*graph1_verts_iter, *graph2_verts_iter); + goto recur; + } + } + graph2_loop: + ++graph2_verts_iter; + } + + back_track: + if (k.empty()) + return found_match; + + const match_continuation_type kk = k.back(); + graph1_verts_iter = kk.graph1_verts_iter; + graph2_verts_iter = kk.graph2_verts_iter; + k.pop_back(); + + s.pop(*graph1_verts_iter, *graph2_verts_iter); + + goto graph2_loop; + } // Used to sort nodes by in/out degrees - template - struct vertex_in_out_degree_cmp { - typedef typename graph_traits::vertex_descriptor vertex_type; + template < typename Graph > struct vertex_in_out_degree_cmp + { + typedef typename graph_traits< Graph >::vertex_descriptor vertex_type; - vertex_in_out_degree_cmp(const Graph& graph) - : graph_(graph) {} + vertex_in_out_degree_cmp(const Graph& graph) : graph_(graph) {} - bool operator()(const vertex_type& v, const vertex_type& w) const { - // lexicographical comparison - return std::make_pair(in_degree(v, graph_), out_degree(v, graph_)) < - std::make_pair(in_degree(w, graph_), out_degree(w, graph_)); - } + bool operator()(const vertex_type& v, const vertex_type& w) const + { + // lexicographical comparison + return std::make_pair(in_degree(v, graph_), out_degree(v, graph_)) + < std::make_pair(in_degree(w, graph_), out_degree(w, graph_)); + } - const Graph& graph_; + const Graph& graph_; }; - // Used to sort nodes by multiplicity of in/out degrees - template - struct vertex_frequency_degree_cmp { - typedef typename graph_traits::vertex_descriptor vertex_type; - - vertex_frequency_degree_cmp(const Graph& graph, FrequencyMap freq) - : graph_(graph), freq_(freq) {} - - bool operator()(const vertex_type& v, const vertex_type& w) const { - // lexicographical comparison - return std::make_pair(freq_[v], in_degree(v, graph_)+out_degree(v, graph_)) < - std::make_pair(freq_[w], in_degree(w, graph_)+out_degree(w, graph_)); - } - - const Graph& graph_; - FrequencyMap freq_; - }; + template < typename Graph, typename FrequencyMap > + struct vertex_frequency_degree_cmp + { + typedef typename graph_traits< Graph >::vertex_descriptor vertex_type; + + vertex_frequency_degree_cmp(const Graph& graph, FrequencyMap freq) + : graph_(graph), freq_(freq) + { + } - - // Sorts vertices of a graph by multiplicity of in/out degrees - template - void sort_vertices(const Graph& graph, IndexMap index_map, VertexOrder& order) { - typedef typename graph_traits::vertices_size_type size_type; - - boost::range::sort(order, vertex_in_out_degree_cmp(graph)); - - std::vector freq_vec(num_vertices(graph), 0); - typedef iterator_property_map::iterator, - IndexMap, size_type, size_type&> frequency_map_type; - - frequency_map_type freq = make_iterator_property_map(freq_vec.begin(), index_map); - - typedef typename VertexOrder::iterator order_iterator; - - for (order_iterator order_iter = order.begin(); order_iter != order.end(); ) { - size_type count = 0; - for (order_iterator count_iter = order_iter; - (count_iter != order.end()) && - (in_degree(*order_iter, graph) == in_degree(*count_iter, graph)) && - (out_degree(*order_iter, graph) == out_degree(*count_iter, graph)); - ++count_iter) - ++count; - - for (size_type i = 0; i < count; ++i) { - freq[*order_iter] = count; - ++order_iter; + bool operator()(const vertex_type& v, const vertex_type& w) const + { + // lexicographical comparison + return std::make_pair( + freq_[v], in_degree(v, graph_) + out_degree(v, graph_)) + < std::make_pair( + freq_[w], in_degree(w, graph_) + out_degree(w, graph_)); } - } - boost::range::sort(order, vertex_frequency_degree_cmp(graph, freq)); + const Graph& graph_; + FrequencyMap freq_; + }; - } + // Sorts vertices of a graph by multiplicity of in/out degrees + template < typename Graph, typename IndexMap, typename VertexOrder > + void sort_vertices( + const Graph& graph, IndexMap index_map, VertexOrder& order) + { + typedef typename graph_traits< Graph >::vertices_size_type size_type; - // Enumerates all graph sub-graph mono-/iso-morphism mappings between graphs - // graph_small and graph_large. Continues until user_callback returns true or the - // search space has been fully explored. - template - bool vf2_subgraph_morphism(const GraphSmall& graph_small, const GraphLarge& graph_large, - SubGraphIsoMapCallback user_callback, - IndexMapSmall index_map_small, IndexMapLarge index_map_large, - const VertexOrderSmall& vertex_order_small, - EdgeEquivalencePredicate edge_comp, - VertexEquivalencePredicate vertex_comp) { - - // Graph requirements - BOOST_CONCEPT_ASSERT(( BidirectionalGraphConcept )); - BOOST_CONCEPT_ASSERT(( VertexListGraphConcept )); - BOOST_CONCEPT_ASSERT(( EdgeListGraphConcept )); - BOOST_CONCEPT_ASSERT(( AdjacencyMatrixConcept )); - - BOOST_CONCEPT_ASSERT(( BidirectionalGraphConcept )); - BOOST_CONCEPT_ASSERT(( VertexListGraphConcept )); - BOOST_CONCEPT_ASSERT(( EdgeListGraphConcept )); - BOOST_CONCEPT_ASSERT(( AdjacencyMatrixConcept )); - - typedef typename graph_traits::vertex_descriptor vertex_small_type; - typedef typename graph_traits::vertex_descriptor vertex_large_type; - - typedef typename graph_traits::vertices_size_type size_type_small; - typedef typename graph_traits::vertices_size_type size_type_large; - - // Property map requirements - BOOST_CONCEPT_ASSERT(( ReadablePropertyMapConcept )); - typedef typename property_traits::value_type IndexMapSmallValue; - BOOST_STATIC_ASSERT(( is_convertible::value )); - - BOOST_CONCEPT_ASSERT(( ReadablePropertyMapConcept )); - typedef typename property_traits::value_type IndexMapLargeValue; - BOOST_STATIC_ASSERT(( is_convertible::value )); - - // Edge & vertex requirements - typedef typename graph_traits::edge_descriptor edge_small_type; - typedef typename graph_traits::edge_descriptor edge_large_type; - - BOOST_CONCEPT_ASSERT(( BinaryPredicateConcept )); - - BOOST_CONCEPT_ASSERT(( BinaryPredicateConcept )); - - // Vertex order requirements - BOOST_CONCEPT_ASSERT(( ContainerConcept )); - typedef typename VertexOrderSmall::value_type order_value_type; - BOOST_STATIC_ASSERT(( is_same::value )); - BOOST_ASSERT( num_vertices(graph_small) == vertex_order_small.size() ); - - if (num_vertices(graph_small) > num_vertices(graph_large)) - return false; + boost::range::sort(order, vertex_in_out_degree_cmp< Graph >(graph)); - typename graph_traits::edges_size_type num_edges_small = num_edges(graph_small); - typename graph_traits::edges_size_type num_edges_large = num_edges(graph_large); + std::vector< size_type > freq_vec(num_vertices(graph), 0); + typedef iterator_property_map< + typename std::vector< size_type >::iterator, IndexMap, size_type, + size_type& > + frequency_map_type; - // Double the number of edges for undirected graphs: each edge counts as - // in-edge and out-edge - if (is_undirected(graph_small)) num_edges_small *= 2; - if (is_undirected(graph_large)) num_edges_large *= 2; - if (num_edges_small > num_edges_large) - return false; - - detail::state - s(graph_small, graph_large, index_map_small, index_map_large, edge_comp, vertex_comp); + frequency_map_type freq + = make_iterator_property_map(freq_vec.begin(), index_map); + + typedef typename VertexOrder::iterator order_iterator; + + for (order_iterator order_iter = order.begin(); + order_iter != order.end();) + { + size_type count = 0; + for (order_iterator count_iter = order_iter; + (count_iter != order.end()) + && (in_degree(*order_iter, graph) + == in_degree(*count_iter, graph)) + && (out_degree(*order_iter, graph) + == out_degree(*count_iter, graph)); + ++count_iter) + ++count; + + for (size_type i = 0; i < count; ++i) + { + freq[*order_iter] = count; + ++order_iter; + } + } - return detail::match(graph_small, graph_large, user_callback, vertex_order_small, s); + boost::range::sort(order, + vertex_frequency_degree_cmp< Graph, frequency_map_type >( + graph, freq)); } - } // namespace detail + // Enumerates all graph sub-graph mono-/iso-morphism mappings between graphs + // graph_small and graph_large. Continues until user_callback returns true + // or the search space has been fully explored. + template < problem_selector problem_selection, typename GraphSmall, + typename GraphLarge, typename IndexMapSmall, typename IndexMapLarge, + typename VertexOrderSmall, typename EdgeEquivalencePredicate, + typename VertexEquivalencePredicate, typename SubGraphIsoMapCallback > + bool vf2_subgraph_morphism(const GraphSmall& graph_small, + const GraphLarge& graph_large, SubGraphIsoMapCallback user_callback, + IndexMapSmall index_map_small, IndexMapLarge index_map_large, + const VertexOrderSmall& vertex_order_small, + EdgeEquivalencePredicate edge_comp, + VertexEquivalencePredicate vertex_comp) + { + + // Graph requirements + BOOST_CONCEPT_ASSERT((BidirectionalGraphConcept< GraphSmall >)); + BOOST_CONCEPT_ASSERT((VertexListGraphConcept< GraphSmall >)); + BOOST_CONCEPT_ASSERT((EdgeListGraphConcept< GraphSmall >)); + BOOST_CONCEPT_ASSERT((AdjacencyMatrixConcept< GraphSmall >)); + + BOOST_CONCEPT_ASSERT((BidirectionalGraphConcept< GraphLarge >)); + BOOST_CONCEPT_ASSERT((VertexListGraphConcept< GraphLarge >)); + BOOST_CONCEPT_ASSERT((EdgeListGraphConcept< GraphLarge >)); + BOOST_CONCEPT_ASSERT((AdjacencyMatrixConcept< GraphLarge >)); + + typedef typename graph_traits< GraphSmall >::vertex_descriptor + vertex_small_type; + typedef typename graph_traits< GraphLarge >::vertex_descriptor + vertex_large_type; + + typedef typename graph_traits< GraphSmall >::vertices_size_type + size_type_small; + typedef typename graph_traits< GraphLarge >::vertices_size_type + size_type_large; + + // Property map requirements + BOOST_CONCEPT_ASSERT( + (ReadablePropertyMapConcept< IndexMapSmall, vertex_small_type >)); + typedef typename property_traits< IndexMapSmall >::value_type + IndexMapSmallValue; + BOOST_STATIC_ASSERT( + (is_convertible< IndexMapSmallValue, size_type_small >::value)); + + BOOST_CONCEPT_ASSERT( + (ReadablePropertyMapConcept< IndexMapLarge, vertex_large_type >)); + typedef typename property_traits< IndexMapLarge >::value_type + IndexMapLargeValue; + BOOST_STATIC_ASSERT( + (is_convertible< IndexMapLargeValue, size_type_large >::value)); + + // Edge & vertex requirements + typedef typename graph_traits< GraphSmall >::edge_descriptor + edge_small_type; + typedef typename graph_traits< GraphLarge >::edge_descriptor + edge_large_type; + + BOOST_CONCEPT_ASSERT((BinaryPredicateConcept< EdgeEquivalencePredicate, + edge_small_type, edge_large_type >)); + + BOOST_CONCEPT_ASSERT( + (BinaryPredicateConcept< VertexEquivalencePredicate, + vertex_small_type, vertex_large_type >)); + + // Vertex order requirements + BOOST_CONCEPT_ASSERT((ContainerConcept< VertexOrderSmall >)); + typedef typename VertexOrderSmall::value_type order_value_type; + BOOST_STATIC_ASSERT( + (is_same< vertex_small_type, order_value_type >::value)); + BOOST_ASSERT(num_vertices(graph_small) == vertex_order_small.size()); + + if (num_vertices(graph_small) > num_vertices(graph_large)) + return false; + + typename graph_traits< GraphSmall >::edges_size_type num_edges_small + = num_edges(graph_small); + typename graph_traits< GraphLarge >::edges_size_type num_edges_large + = num_edges(graph_large); + + // Double the number of edges for undirected graphs: each edge counts as + // in-edge and out-edge + if (is_undirected(graph_small)) + num_edges_small *= 2; + if (is_undirected(graph_large)) + num_edges_large *= 2; + if (num_edges_small > num_edges_large) + return false; + + detail::state< GraphSmall, GraphLarge, IndexMapSmall, IndexMapLarge, + EdgeEquivalencePredicate, VertexEquivalencePredicate, + SubGraphIsoMapCallback, problem_selection > + s(graph_small, graph_large, index_map_small, index_map_large, + edge_comp, vertex_comp); + + return detail::match( + graph_small, graph_large, user_callback, vertex_order_small, s); + } +} // namespace detail - // Returns vertex order (vertices sorted by multiplicity of in/out degrees) - template - std::vector::vertex_descriptor> - vertex_order_by_mult(const Graph& graph) { +// Returns vertex order (vertices sorted by multiplicity of in/out degrees) +template < typename Graph > +std::vector< typename graph_traits< Graph >::vertex_descriptor > +vertex_order_by_mult(const Graph& graph) +{ - std::vector::vertex_descriptor> vertex_order; - std::copy(vertices(graph).first, vertices(graph).second, std::back_inserter(vertex_order)); + std::vector< typename graph_traits< Graph >::vertex_descriptor > + vertex_order; + std::copy(vertices(graph).first, vertices(graph).second, + std::back_inserter(vertex_order)); detail::sort_vertices(graph, get(vertex_index, graph), vertex_order); return vertex_order; - } - - - // Enumerates all graph sub-graph monomorphism mappings between graphs - // graph_small and graph_large. Continues until user_callback returns true or the - // search space has been fully explored. - template - bool vf2_subgraph_mono(const GraphSmall& graph_small, const GraphLarge& graph_large, - SubGraphIsoMapCallback user_callback, - IndexMapSmall index_map_small, IndexMapLarge index_map_large, - const VertexOrderSmall& vertex_order_small, - EdgeEquivalencePredicate edge_comp, - VertexEquivalencePredicate vertex_comp) { - return detail::vf2_subgraph_morphism - (graph_small, graph_large, - user_callback, - index_map_small, index_map_large, - vertex_order_small, - edge_comp, - vertex_comp); - } - - - // All default interface for vf2_subgraph_iso - template - bool vf2_subgraph_mono(const GraphSmall& graph_small, const GraphLarge& graph_large, - SubGraphIsoMapCallback user_callback) { - return vf2_subgraph_mono(graph_small, graph_large, user_callback, - get(vertex_index, graph_small), get(vertex_index, graph_large), - vertex_order_by_mult(graph_small), - always_equivalent(), always_equivalent()); - } - - - // Named parameter interface of vf2_subgraph_iso - template - bool vf2_subgraph_mono(const GraphSmall& graph_small, const GraphLarge& graph_large, - SubGraphIsoMapCallback user_callback, - const VertexOrderSmall& vertex_order_small, - const bgl_named_params& params) { +} + +// Enumerates all graph sub-graph monomorphism mappings between graphs +// graph_small and graph_large. Continues until user_callback returns true or +// the search space has been fully explored. +template < typename GraphSmall, typename GraphLarge, typename IndexMapSmall, + typename IndexMapLarge, typename VertexOrderSmall, + typename EdgeEquivalencePredicate, typename VertexEquivalencePredicate, + typename SubGraphIsoMapCallback > +bool vf2_subgraph_mono(const GraphSmall& graph_small, + const GraphLarge& graph_large, SubGraphIsoMapCallback user_callback, + IndexMapSmall index_map_small, IndexMapLarge index_map_large, + const VertexOrderSmall& vertex_order_small, + EdgeEquivalencePredicate edge_comp, VertexEquivalencePredicate vertex_comp) +{ + return detail::vf2_subgraph_morphism< detail::subgraph_mono >(graph_small, + graph_large, user_callback, index_map_small, index_map_large, + vertex_order_small, edge_comp, vertex_comp); +} + +// All default interface for vf2_subgraph_iso +template < typename GraphSmall, typename GraphLarge, + typename SubGraphIsoMapCallback > +bool vf2_subgraph_mono(const GraphSmall& graph_small, + const GraphLarge& graph_large, SubGraphIsoMapCallback user_callback) +{ + return vf2_subgraph_mono(graph_small, graph_large, user_callback, + get(vertex_index, graph_small), get(vertex_index, graph_large), + vertex_order_by_mult(graph_small), always_equivalent(), + always_equivalent()); +} + +// Named parameter interface of vf2_subgraph_iso +template < typename GraphSmall, typename GraphLarge, typename VertexOrderSmall, + typename SubGraphIsoMapCallback, typename Param, typename Tag, + typename Rest > +bool vf2_subgraph_mono(const GraphSmall& graph_small, + const GraphLarge& graph_large, SubGraphIsoMapCallback user_callback, + const VertexOrderSmall& vertex_order_small, + const bgl_named_params< Param, Tag, Rest >& params) +{ return vf2_subgraph_mono(graph_small, graph_large, user_callback, - choose_const_pmap(get_param(params, vertex_index1), - graph_small, vertex_index), - choose_const_pmap(get_param(params, vertex_index2), - graph_large, vertex_index), - vertex_order_small, - choose_param(get_param(params, edges_equivalent_t()), - always_equivalent()), - choose_param(get_param(params, vertices_equivalent_t()), - always_equivalent()) - ); - } - - - // Enumerates all graph sub-graph isomorphism mappings between graphs - // graph_small and graph_large. Continues until user_callback returns true or the - // search space has been fully explored. - template - bool vf2_subgraph_iso(const GraphSmall& graph_small, const GraphLarge& graph_large, - SubGraphIsoMapCallback user_callback, - IndexMapSmall index_map_small, IndexMapLarge index_map_large, - const VertexOrderSmall& vertex_order_small, - EdgeEquivalencePredicate edge_comp, - VertexEquivalencePredicate vertex_comp) { - return detail::vf2_subgraph_morphism - (graph_small, graph_large, - user_callback, - index_map_small, index_map_large, - vertex_order_small, - edge_comp, - vertex_comp); - } - - - // All default interface for vf2_subgraph_iso - template - bool vf2_subgraph_iso(const GraphSmall& graph_small, const GraphLarge& graph_large, - SubGraphIsoMapCallback user_callback) { - - return vf2_subgraph_iso(graph_small, graph_large, user_callback, - get(vertex_index, graph_small), get(vertex_index, graph_large), - vertex_order_by_mult(graph_small), - always_equivalent(), always_equivalent()); - } - - - // Named parameter interface of vf2_subgraph_iso - template - bool vf2_subgraph_iso(const GraphSmall& graph_small, const GraphLarge& graph_large, - SubGraphIsoMapCallback user_callback, - const VertexOrderSmall& vertex_order_small, - const bgl_named_params& params) { - + choose_const_pmap( + get_param(params, vertex_index1), graph_small, vertex_index), + choose_const_pmap( + get_param(params, vertex_index2), graph_large, vertex_index), + vertex_order_small, + choose_param( + get_param(params, edges_equivalent_t()), always_equivalent()), + choose_param( + get_param(params, vertices_equivalent_t()), always_equivalent())); +} + +// Enumerates all graph sub-graph isomorphism mappings between graphs +// graph_small and graph_large. Continues until user_callback returns true or +// the search space has been fully explored. +template < typename GraphSmall, typename GraphLarge, typename IndexMapSmall, + typename IndexMapLarge, typename VertexOrderSmall, + typename EdgeEquivalencePredicate, typename VertexEquivalencePredicate, + typename SubGraphIsoMapCallback > +bool vf2_subgraph_iso(const GraphSmall& graph_small, + const GraphLarge& graph_large, SubGraphIsoMapCallback user_callback, + IndexMapSmall index_map_small, IndexMapLarge index_map_large, + const VertexOrderSmall& vertex_order_small, + EdgeEquivalencePredicate edge_comp, VertexEquivalencePredicate vertex_comp) +{ + return detail::vf2_subgraph_morphism< detail::subgraph_iso >(graph_small, + graph_large, user_callback, index_map_small, index_map_large, + vertex_order_small, edge_comp, vertex_comp); +} + +// All default interface for vf2_subgraph_iso +template < typename GraphSmall, typename GraphLarge, + typename SubGraphIsoMapCallback > +bool vf2_subgraph_iso(const GraphSmall& graph_small, + const GraphLarge& graph_large, SubGraphIsoMapCallback user_callback) +{ + + return vf2_subgraph_iso(graph_small, graph_large, user_callback, + get(vertex_index, graph_small), get(vertex_index, graph_large), + vertex_order_by_mult(graph_small), always_equivalent(), + always_equivalent()); +} + +// Named parameter interface of vf2_subgraph_iso +template < typename GraphSmall, typename GraphLarge, typename VertexOrderSmall, + typename SubGraphIsoMapCallback, typename Param, typename Tag, + typename Rest > +bool vf2_subgraph_iso(const GraphSmall& graph_small, + const GraphLarge& graph_large, SubGraphIsoMapCallback user_callback, + const VertexOrderSmall& vertex_order_small, + const bgl_named_params< Param, Tag, Rest >& params) +{ + return vf2_subgraph_iso(graph_small, graph_large, user_callback, - choose_const_pmap(get_param(params, vertex_index1), - graph_small, vertex_index), - choose_const_pmap(get_param(params, vertex_index2), - graph_large, vertex_index), - vertex_order_small, - choose_param(get_param(params, edges_equivalent_t()), - always_equivalent()), - choose_param(get_param(params, vertices_equivalent_t()), - always_equivalent()) - ); - - } - - - // Enumerates all isomorphism mappings between graphs graph1_ and graph2_. - // Continues until user_callback returns true or the search space has been - // fully explored. - template - bool vf2_graph_iso(const Graph1& graph1, const Graph2& graph2, - GraphIsoMapCallback user_callback, - IndexMap1 index_map1, IndexMap2 index_map2, - const VertexOrder1& vertex_order1, - EdgeEquivalencePredicate edge_comp, - VertexEquivalencePredicate vertex_comp) { + choose_const_pmap( + get_param(params, vertex_index1), graph_small, vertex_index), + choose_const_pmap( + get_param(params, vertex_index2), graph_large, vertex_index), + vertex_order_small, + choose_param( + get_param(params, edges_equivalent_t()), always_equivalent()), + choose_param( + get_param(params, vertices_equivalent_t()), always_equivalent())); +} + +// Enumerates all isomorphism mappings between graphs graph1_ and graph2_. +// Continues until user_callback returns true or the search space has been +// fully explored. +template < typename Graph1, typename Graph2, typename IndexMap1, + typename IndexMap2, typename VertexOrder1, + typename EdgeEquivalencePredicate, typename VertexEquivalencePredicate, + typename GraphIsoMapCallback > +bool vf2_graph_iso(const Graph1& graph1, const Graph2& graph2, + GraphIsoMapCallback user_callback, IndexMap1 index_map1, + IndexMap2 index_map2, const VertexOrder1& vertex_order1, + EdgeEquivalencePredicate edge_comp, VertexEquivalencePredicate vertex_comp) +{ // Graph requirements - BOOST_CONCEPT_ASSERT(( BidirectionalGraphConcept )); - BOOST_CONCEPT_ASSERT(( VertexListGraphConcept )); - BOOST_CONCEPT_ASSERT(( EdgeListGraphConcept )); - BOOST_CONCEPT_ASSERT(( AdjacencyMatrixConcept )); - - BOOST_CONCEPT_ASSERT(( BidirectionalGraphConcept )); - BOOST_CONCEPT_ASSERT(( VertexListGraphConcept )); - BOOST_CONCEPT_ASSERT(( EdgeListGraphConcept )); - BOOST_CONCEPT_ASSERT(( AdjacencyMatrixConcept )); - - - typedef typename graph_traits::vertex_descriptor vertex1_type; - typedef typename graph_traits::vertex_descriptor vertex2_type; - - typedef typename graph_traits::vertices_size_type size_type1; - typedef typename graph_traits::vertices_size_type size_type2; - + BOOST_CONCEPT_ASSERT((BidirectionalGraphConcept< Graph1 >)); + BOOST_CONCEPT_ASSERT((VertexListGraphConcept< Graph1 >)); + BOOST_CONCEPT_ASSERT((EdgeListGraphConcept< Graph1 >)); + BOOST_CONCEPT_ASSERT((AdjacencyMatrixConcept< Graph1 >)); + + BOOST_CONCEPT_ASSERT((BidirectionalGraphConcept< Graph2 >)); + BOOST_CONCEPT_ASSERT((VertexListGraphConcept< Graph2 >)); + BOOST_CONCEPT_ASSERT((EdgeListGraphConcept< Graph2 >)); + BOOST_CONCEPT_ASSERT((AdjacencyMatrixConcept< Graph2 >)); + + typedef typename graph_traits< Graph1 >::vertex_descriptor vertex1_type; + typedef typename graph_traits< Graph2 >::vertex_descriptor vertex2_type; + + typedef typename graph_traits< Graph1 >::vertices_size_type size_type1; + typedef typename graph_traits< Graph2 >::vertices_size_type size_type2; + // Property map requirements - BOOST_CONCEPT_ASSERT(( ReadablePropertyMapConcept )); - typedef typename property_traits::value_type IndexMap1Value; - BOOST_STATIC_ASSERT(( is_convertible::value )); - - BOOST_CONCEPT_ASSERT(( ReadablePropertyMapConcept )); - typedef typename property_traits::value_type IndexMap2Value; - BOOST_STATIC_ASSERT(( is_convertible::value )); + BOOST_CONCEPT_ASSERT( + (ReadablePropertyMapConcept< IndexMap1, vertex1_type >)); + typedef typename property_traits< IndexMap1 >::value_type IndexMap1Value; + BOOST_STATIC_ASSERT((is_convertible< IndexMap1Value, size_type1 >::value)); + + BOOST_CONCEPT_ASSERT( + (ReadablePropertyMapConcept< IndexMap2, vertex2_type >)); + typedef typename property_traits< IndexMap2 >::value_type IndexMap2Value; + BOOST_STATIC_ASSERT((is_convertible< IndexMap2Value, size_type2 >::value)); // Edge & vertex requirements - typedef typename graph_traits::edge_descriptor edge1_type; - typedef typename graph_traits::edge_descriptor edge2_type; + typedef typename graph_traits< Graph1 >::edge_descriptor edge1_type; + typedef typename graph_traits< Graph2 >::edge_descriptor edge2_type; + + BOOST_CONCEPT_ASSERT((BinaryPredicateConcept< EdgeEquivalencePredicate, + edge1_type, edge2_type >)); - BOOST_CONCEPT_ASSERT(( BinaryPredicateConcept )); + BOOST_CONCEPT_ASSERT((BinaryPredicateConcept< VertexEquivalencePredicate, + vertex1_type, vertex2_type >)); - BOOST_CONCEPT_ASSERT(( BinaryPredicateConcept )); - // Vertex order requirements - BOOST_CONCEPT_ASSERT(( ContainerConcept )); + BOOST_CONCEPT_ASSERT((ContainerConcept< VertexOrder1 >)); typedef typename VertexOrder1::value_type order_value_type; - BOOST_STATIC_ASSERT(( is_same::value )); - BOOST_ASSERT( num_vertices(graph1) == vertex_order1.size() ); + BOOST_STATIC_ASSERT((is_same< vertex1_type, order_value_type >::value)); + BOOST_ASSERT(num_vertices(graph1) == vertex_order1.size()); if (num_vertices(graph1) != num_vertices(graph2)) - return false; + return false; - typename graph_traits::edges_size_type num_edges1 = num_edges(graph1); - typename graph_traits::edges_size_type num_edges2 = num_edges(graph2); + typename graph_traits< Graph1 >::edges_size_type num_edges1 + = num_edges(graph1); + typename graph_traits< Graph2 >::edges_size_type num_edges2 + = num_edges(graph2); // Double the number of edges for undirected graphs: each edge counts as // in-edge and out-edge - if (is_undirected(graph1)) num_edges1 *= 2; - if (is_undirected(graph2)) num_edges2 *= 2; + if (is_undirected(graph1)) + num_edges1 *= 2; + if (is_undirected(graph2)) + num_edges2 *= 2; if (num_edges1 != num_edges2) - return false; + return false; - detail::state - s(graph1, graph2, index_map1, index_map2, edge_comp, vertex_comp); + detail::state< Graph1, Graph2, IndexMap1, IndexMap2, + EdgeEquivalencePredicate, VertexEquivalencePredicate, + GraphIsoMapCallback, detail::isomorphism > + s(graph1, graph2, index_map1, index_map2, edge_comp, vertex_comp); return detail::match(graph1, graph2, user_callback, vertex_order1, s); - } - - - // All default interface for vf2_graph_iso - template - bool vf2_graph_iso(const Graph1& graph1, const Graph2& graph2, - GraphIsoMapCallback user_callback) { - - return vf2_graph_iso(graph1, graph2, user_callback, - get(vertex_index, graph1), get(vertex_index, graph2), - vertex_order_by_mult(graph1), - always_equivalent(), always_equivalent()); - } - - - // Named parameter interface of vf2_graph_iso - template - bool vf2_graph_iso(const Graph1& graph1, const Graph2& graph2, - GraphIsoMapCallback user_callback, - const VertexOrder1& vertex_order1, - const bgl_named_params& params) { - - return vf2_graph_iso(graph1, graph2, user_callback, - choose_const_pmap(get_param(params, vertex_index1), - graph1, vertex_index), - choose_const_pmap(get_param(params, vertex_index2), - graph2, vertex_index), - vertex_order1, - choose_param(get_param(params, edges_equivalent_t()), - always_equivalent()), - choose_param(get_param(params, vertices_equivalent_t()), - always_equivalent()) - ); - - } - - - // Verifies a graph (sub)graph isomorphism map - template - inline bool verify_vf2_subgraph_iso(const Graph1& graph1, const Graph2& graph2, - const CorresponenceMap1To2 f, - EdgeEquivalencePredicate edge_comp, - VertexEquivalencePredicate vertex_comp) { - - BOOST_CONCEPT_ASSERT(( EdgeListGraphConcept )); - BOOST_CONCEPT_ASSERT(( AdjacencyMatrixConcept )); - - detail::equivalent_edge_exists edge2_exists; - - BGL_FORALL_EDGES_T(e1, graph1, Graph1) { - typename graph_traits::vertex_descriptor s1, t1; - typename graph_traits::vertex_descriptor s2, t2; - - s1 = source(e1, graph1); t1 = target(e1, graph1); - s2 = get(f, s1); t2 = get(f, t1); - - if (!vertex_comp(s1, s2) || !vertex_comp(t1, t2)) - return false; +} - typename graph_traits::edge_descriptor e2; - - if (!edge2_exists(s2, t2, - detail::edge2_predicate(edge_comp, e1), - graph2)) - return false; - - } - - return true; - } +// All default interface for vf2_graph_iso +template < typename Graph1, typename Graph2, typename GraphIsoMapCallback > +bool vf2_graph_iso(const Graph1& graph1, const Graph2& graph2, + GraphIsoMapCallback user_callback) +{ - // Variant of verify_subgraph_iso with all default parameters - template - inline bool verify_vf2_subgraph_iso(const Graph1& graph1, const Graph2& graph2, - const CorresponenceMap1To2 f) { - return verify_vf2_subgraph_iso(graph1, graph2, f, - always_equivalent(), always_equivalent()); - } + return vf2_graph_iso(graph1, graph2, user_callback, + get(vertex_index, graph1), get(vertex_index, graph2), + vertex_order_by_mult(graph1), always_equivalent(), always_equivalent()); +} + +// Named parameter interface of vf2_graph_iso +template < typename Graph1, typename Graph2, typename VertexOrder1, + typename GraphIsoMapCallback, typename Param, typename Tag, typename Rest > +bool vf2_graph_iso(const Graph1& graph1, const Graph2& graph2, + GraphIsoMapCallback user_callback, const VertexOrder1& vertex_order1, + const bgl_named_params< Param, Tag, Rest >& params) +{ + return vf2_graph_iso(graph1, graph2, user_callback, + choose_const_pmap( + get_param(params, vertex_index1), graph1, vertex_index), + choose_const_pmap( + get_param(params, vertex_index2), graph2, vertex_index), + vertex_order1, + choose_param( + get_param(params, edges_equivalent_t()), always_equivalent()), + choose_param( + get_param(params, vertices_equivalent_t()), always_equivalent())); +} + +// Verifies a graph (sub)graph isomorphism map +template < typename Graph1, typename Graph2, typename CorresponenceMap1To2, + typename EdgeEquivalencePredicate, typename VertexEquivalencePredicate > +inline bool verify_vf2_subgraph_iso(const Graph1& graph1, const Graph2& graph2, + const CorresponenceMap1To2 f, EdgeEquivalencePredicate edge_comp, + VertexEquivalencePredicate vertex_comp) +{ + + BOOST_CONCEPT_ASSERT((EdgeListGraphConcept< Graph1 >)); + BOOST_CONCEPT_ASSERT((AdjacencyMatrixConcept< Graph2 >)); + + detail::equivalent_edge_exists< Graph2 > edge2_exists; + + BGL_FORALL_EDGES_T(e1, graph1, Graph1) + { + typename graph_traits< Graph1 >::vertex_descriptor s1, t1; + typename graph_traits< Graph2 >::vertex_descriptor s2, t2; + + s1 = source(e1, graph1); + t1 = target(e1, graph1); + s2 = get(f, s1); + t2 = get(f, t1); + + if (!vertex_comp(s1, s2) || !vertex_comp(t1, t2)) + return false; + + typename graph_traits< Graph2 >::edge_descriptor e2; + + if (!edge2_exists(s2, t2, + detail::edge2_predicate< Graph1, Graph2, + EdgeEquivalencePredicate >(edge_comp, e1), + graph2)) + return false; + } + return true; +} + +// Variant of verify_subgraph_iso with all default parameters +template < typename Graph1, typename Graph2, typename CorresponenceMap1To2 > +inline bool verify_vf2_subgraph_iso( + const Graph1& graph1, const Graph2& graph2, const CorresponenceMap1To2 f) +{ + return verify_vf2_subgraph_iso( + graph1, graph2, f, always_equivalent(), always_equivalent()); +} } // namespace boost diff --git a/include/boost/graph/visitors.hpp b/include/boost/graph/visitors.hpp index 120314f90..534794b6a 100644 --- a/include/boost/graph/visitors.hpp +++ b/include/boost/graph/visitors.hpp @@ -21,278 +21,406 @@ #include #include -namespace boost { +namespace boost +{ - // This is a bit more convenient than std::numeric_limits because - // you don't have to explicitly provide type T. - template - inline T numeric_limits_max(T) { return (std::numeric_limits::max)(); } +// This is a bit more convenient than std::numeric_limits because +// you don't have to explicitly provide type T. +template < class T > inline T numeric_limits_max(T) +{ + return (std::numeric_limits< T >::max)(); +} - //======================================================================== - // Event Tags +//======================================================================== +// Event Tags - namespace detail { +namespace detail +{ // For partial specialization workaround enum event_visitor_enum - { on_no_event_num, - on_initialize_vertex_num, on_start_vertex_num, - on_discover_vertex_num, on_finish_vertex_num, on_examine_vertex_num, - on_examine_edge_num, on_tree_edge_num, on_non_tree_edge_num, - on_gray_target_num, on_black_target_num, - on_forward_or_cross_edge_num, on_back_edge_num, on_finish_edge_num, - on_edge_relaxed_num, on_edge_not_relaxed_num, - on_edge_minimized_num, on_edge_not_minimized_num + { + on_no_event_num, + on_initialize_vertex_num, + on_start_vertex_num, + on_discover_vertex_num, + on_finish_vertex_num, + on_examine_vertex_num, + on_examine_edge_num, + on_tree_edge_num, + on_non_tree_edge_num, + on_gray_target_num, + on_black_target_num, + on_forward_or_cross_edge_num, + on_back_edge_num, + on_finish_edge_num, + on_edge_relaxed_num, + on_edge_not_relaxed_num, + on_edge_minimized_num, + on_edge_not_minimized_num }; - template + template < typename Event, typename Visitor > struct functor_to_visitor : Visitor { - typedef Event event_filter; - functor_to_visitor(const Visitor& visitor) : Visitor(visitor) {} + typedef Event event_filter; + functor_to_visitor(const Visitor& visitor) : Visitor(visitor) {} + }; + +} // namespace detail + +struct on_no_event +{ + enum + { + num = detail::on_no_event_num + }; +}; + +struct on_initialize_vertex +{ + enum + { + num = detail::on_initialize_vertex_num + }; +}; +struct on_start_vertex +{ + enum + { + num = detail::on_start_vertex_num + }; +}; +struct on_discover_vertex +{ + enum + { + num = detail::on_discover_vertex_num + }; +}; +struct on_examine_vertex +{ + enum + { + num = detail::on_examine_vertex_num + }; +}; +struct on_finish_vertex +{ + enum + { + num = detail::on_finish_vertex_num + }; +}; + +struct on_examine_edge +{ + enum + { + num = detail::on_examine_edge_num + }; +}; +struct on_tree_edge +{ + enum + { + num = detail::on_tree_edge_num + }; +}; +struct on_non_tree_edge +{ + enum + { + num = detail::on_non_tree_edge_num + }; +}; +struct on_gray_target +{ + enum + { + num = detail::on_gray_target_num + }; +}; +struct on_black_target +{ + enum + { + num = detail::on_black_target_num + }; +}; +struct on_forward_or_cross_edge +{ + enum + { + num = detail::on_forward_or_cross_edge_num }; +}; +struct on_back_edge +{ + enum + { + num = detail::on_back_edge_num + }; +}; +struct on_finish_edge +{ + enum + { + num = detail::on_finish_edge_num + }; +}; - } // namespace detail - - struct on_no_event { enum { num = detail::on_no_event_num }; }; - - struct on_initialize_vertex { - enum { num = detail::on_initialize_vertex_num }; }; - struct on_start_vertex { enum { num = detail::on_start_vertex_num }; }; - struct on_discover_vertex { enum { num = detail::on_discover_vertex_num }; }; - struct on_examine_vertex { enum { num = detail::on_examine_vertex_num }; }; - struct on_finish_vertex { enum { num = detail::on_finish_vertex_num }; }; - - struct on_examine_edge { enum { num = detail::on_examine_edge_num }; }; - struct on_tree_edge { enum { num = detail::on_tree_edge_num }; }; - struct on_non_tree_edge { enum { num = detail::on_non_tree_edge_num }; }; - struct on_gray_target { enum { num = detail::on_gray_target_num }; }; - struct on_black_target { enum { num = detail::on_black_target_num }; }; - struct on_forward_or_cross_edge { - enum { num = detail::on_forward_or_cross_edge_num }; }; - struct on_back_edge { enum { num = detail::on_back_edge_num }; }; - struct on_finish_edge { enum { num = detail::on_finish_edge_num }; }; - - struct on_edge_relaxed { enum { num = detail::on_edge_relaxed_num }; }; - struct on_edge_not_relaxed { - enum { num = detail::on_edge_not_relaxed_num }; }; - struct on_edge_minimized { enum { num = detail::on_edge_minimized_num }; }; - struct on_edge_not_minimized { - enum { num = detail::on_edge_not_minimized_num }; }; - - //======================================================================== - // base_visitor and null_visitor - - // needed for MSVC workaround - template - struct base_visitor { +struct on_edge_relaxed +{ + enum + { + num = detail::on_edge_relaxed_num + }; +}; +struct on_edge_not_relaxed +{ + enum + { + num = detail::on_edge_not_relaxed_num + }; +}; +struct on_edge_minimized +{ + enum + { + num = detail::on_edge_minimized_num + }; +}; +struct on_edge_not_minimized +{ + enum + { + num = detail::on_edge_not_minimized_num + }; +}; + +//======================================================================== +// base_visitor and null_visitor + +// needed for MSVC workaround +template < class Visitor > struct base_visitor +{ typedef on_no_event event_filter; - template - void operator()(T, Graph&) { } - }; + template < class T, class Graph > void operator()(T, Graph&) {} +}; - struct null_visitor : public base_visitor { +struct null_visitor : public base_visitor< null_visitor > +{ typedef on_no_event event_filter; - template - void operator()(T, Graph&) { } - }; + template < class T, class Graph > void operator()(T, Graph&) {} +}; - //======================================================================== - // The invoke_visitors() function +//======================================================================== +// The invoke_visitors() function - namespace detail { - template - inline void invoke_dispatch(Visitor& v, T x, Graph& g, mpl::true_) { - v(x, g); +namespace detail +{ + template < class Visitor, class T, class Graph > + inline void invoke_dispatch(Visitor& v, T x, Graph& g, mpl::true_) + { + v(x, g); } - template + template < class Visitor, class T, class Graph > inline void invoke_dispatch(Visitor&, T, Graph&, mpl::false_) - { } - } // namespace detail + { + } +} // namespace detail - template - inline void - invoke_visitors(std::pair& vlist, T x, Graph& g, Tag tag) { +template < class Visitor, class Rest, class T, class Graph, class Tag > +inline void invoke_visitors( + std::pair< Visitor, Rest >& vlist, T x, Graph& g, Tag tag) +{ typedef typename Visitor::event_filter Category; - typedef typename is_same::type IsSameTag; + typedef typename is_same< Category, Tag >::type IsSameTag; detail::invoke_dispatch(vlist.first, x, g, IsSameTag()); invoke_visitors(vlist.second, x, g, tag); - } - template - inline void - invoke_visitors(Visitor& v, T x, Graph& g, Tag) { +} +template < class Visitor, class T, class Graph, class Tag > +inline void invoke_visitors(Visitor& v, T x, Graph& g, Tag) +{ typedef typename Visitor::event_filter Category; - typedef typename is_same::type IsSameTag; + typedef typename is_same< Category, Tag >::type IsSameTag; detail::invoke_dispatch(v, x, g, IsSameTag()); - } +} - //======================================================================== - // predecessor_recorder +//======================================================================== +// predecessor_recorder - template - struct predecessor_recorder - : public base_visitor > - { +template < class PredecessorMap, class Tag > +struct predecessor_recorder +: public base_visitor< predecessor_recorder< PredecessorMap, Tag > > +{ typedef Tag event_filter; - predecessor_recorder(PredecessorMap pa) : m_predecessor(pa) { } - template - void operator()(Edge e, const Graph& g) { - put(m_predecessor, target(e, g), source(e, g)); + predecessor_recorder(PredecessorMap pa) : m_predecessor(pa) {} + template < class Edge, class Graph > void operator()(Edge e, const Graph& g) + { + put(m_predecessor, target(e, g), source(e, g)); } PredecessorMap m_predecessor; - }; - template - predecessor_recorder - record_predecessors(PredecessorMap pa, Tag) { - return predecessor_recorder (pa); - } - - //======================================================================== - // edge_predecessor_recorder - - template - struct edge_predecessor_recorder - : public base_visitor > - { +}; +template < class PredecessorMap, class Tag > +predecessor_recorder< PredecessorMap, Tag > record_predecessors( + PredecessorMap pa, Tag) +{ + return predecessor_recorder< PredecessorMap, Tag >(pa); +} + +//======================================================================== +// edge_predecessor_recorder + +template < class PredEdgeMap, class Tag > +struct edge_predecessor_recorder +: public base_visitor< edge_predecessor_recorder< PredEdgeMap, Tag > > +{ typedef Tag event_filter; - edge_predecessor_recorder(PredEdgeMap pa) : m_predecessor(pa) { } - template - void operator()(Edge e, const Graph& g) { - put(m_predecessor, target(e, g), e); + edge_predecessor_recorder(PredEdgeMap pa) : m_predecessor(pa) {} + template < class Edge, class Graph > void operator()(Edge e, const Graph& g) + { + put(m_predecessor, target(e, g), e); } PredEdgeMap m_predecessor; - }; - template - edge_predecessor_recorder - record_edge_predecessors(PredEdgeMap pa, Tag) { - return edge_predecessor_recorder (pa); - } - - //======================================================================== - // distance_recorder - - template - struct distance_recorder - : public base_visitor > - { +}; +template < class PredEdgeMap, class Tag > +edge_predecessor_recorder< PredEdgeMap, Tag > record_edge_predecessors( + PredEdgeMap pa, Tag) +{ + return edge_predecessor_recorder< PredEdgeMap, Tag >(pa); +} + +//======================================================================== +// distance_recorder + +template < class DistanceMap, class Tag > +struct distance_recorder +: public base_visitor< distance_recorder< DistanceMap, Tag > > +{ typedef Tag event_filter; - distance_recorder(DistanceMap pa) : m_distance(pa) { } - template - void operator()(Edge e, const Graph& g) { - typename graph_traits::vertex_descriptor - u = source(e, g), v = target(e, g); - put(m_distance, v, get(m_distance, u) + 1); + distance_recorder(DistanceMap pa) : m_distance(pa) {} + template < class Edge, class Graph > void operator()(Edge e, const Graph& g) + { + typename graph_traits< Graph >::vertex_descriptor u = source(e, g), + v = target(e, g); + put(m_distance, v, get(m_distance, u) + 1); } DistanceMap m_distance; - }; - template - distance_recorder - record_distances(DistanceMap pa, Tag) { - return distance_recorder (pa); - } - - //======================================================================== - // time_stamper - - - template - struct time_stamper - : public base_visitor > - { +}; +template < class DistanceMap, class Tag > +distance_recorder< DistanceMap, Tag > record_distances(DistanceMap pa, Tag) +{ + return distance_recorder< DistanceMap, Tag >(pa); +} + +//======================================================================== +// time_stamper + +template < class TimeMap, class TimeT, class Tag > +struct time_stamper : public base_visitor< time_stamper< TimeMap, TimeT, Tag > > +{ typedef Tag event_filter; - time_stamper(TimeMap pa, TimeT& t) : m_time_pa(pa), m_time(t) { } - template - void operator()(Vertex u, const Graph&) { - put(m_time_pa, u, ++m_time); + time_stamper(TimeMap pa, TimeT& t) : m_time_pa(pa), m_time(t) {} + template < class Vertex, class Graph > + void operator()(Vertex u, const Graph&) + { + put(m_time_pa, u, ++m_time); } TimeMap m_time_pa; TimeT& m_time; - }; - template - time_stamper - stamp_times(TimeMap pa, TimeT& time_counter, Tag) { - return time_stamper(pa, time_counter); - } - - //======================================================================== - // property_writer - - template - struct property_writer - : public base_visitor > - { +}; +template < class TimeMap, class TimeT, class Tag > +time_stamper< TimeMap, TimeT, Tag > stamp_times( + TimeMap pa, TimeT& time_counter, Tag) +{ + return time_stamper< TimeMap, TimeT, Tag >(pa, time_counter); +} + +//======================================================================== +// property_writer + +template < class PA, class OutputIterator, class Tag > +struct property_writer +: public base_visitor< property_writer< PA, OutputIterator, Tag > > +{ typedef Tag event_filter; - property_writer(PA pa, OutputIterator out) : m_pa(pa), m_out(out) { } + property_writer(PA pa, OutputIterator out) : m_pa(pa), m_out(out) {} - template - void operator()(T x, Graph&) { *m_out++ = get(m_pa, x); } + template < class T, class Graph > void operator()(T x, Graph&) + { + *m_out++ = get(m_pa, x); + } PA m_pa; OutputIterator m_out; - }; - template - property_writer - write_property(PA pa, OutputIterator out, Tag) { - return property_writer(pa, out); - } - - //======================================================================== - // property_put - - /** - * Functor which just sets a given value to a vertex or edge in a property map. - */ - - template - struct property_put - { +}; +template < class PA, class OutputIterator, class Tag > +property_writer< PA, OutputIterator, Tag > write_property( + PA pa, OutputIterator out, Tag) +{ + return property_writer< PA, OutputIterator, Tag >(pa, out); +} + +//======================================================================== +// property_put + +/** + * Functor which just sets a given value to a vertex or edge in a property map. + */ + +template < typename PropertyMap, typename EventTag > struct property_put +{ typedef EventTag event_filter; - - property_put (PropertyMap property_map, - typename property_traits ::value_type value) : - property_map_ (property_map), value_ (value) - {} - - template - void operator() (VertexOrEdge v, const Graph&) + + property_put(PropertyMap property_map, + typename property_traits< PropertyMap >::value_type value) + : property_map_(property_map), value_(value) { - put (property_map_, v, value_); } - private: - PropertyMap property_map_; - typename property_traits ::value_type value_; - }; - - /** - * Creates a property_put functor which just sets a given value to a vertex or edge. - * - * @param property_map Given writeable property map - * @param value Fixed value of the map - * @param tag Event Filter - * @return The functor. - */ - - template - inline property_put - put_property (PropertyMap property_map, - typename property_traits ::value_type value, - EventTag) + template < typename VertexOrEdge, typename Graph > + void operator()(VertexOrEdge v, const Graph&) { - return property_put (property_map, value); + put(property_map_, v, value_); } -#define BOOST_GRAPH_EVENT_STUB(Event,Kind) \ - typedef ::boost::Event Event##_type; \ - template \ - Kind##_visitor, Visitors> > \ - do_##Event(Visitor visitor) \ - { \ - typedef std::pair, \ - Visitors> visitor_list; \ - typedef Kind##_visitor result_type; \ - return result_type(visitor_list(visitor, m_vis)); \ +private: + PropertyMap property_map_; + typename property_traits< PropertyMap >::value_type value_; +}; + +/** + * Creates a property_put functor which just sets a given value to a vertex or + * edge. + * + * @param property_map Given writeable property map + * @param value Fixed value of the map + * @param tag Event Filter + * @return The functor. + */ + +template < typename PropertyMap, typename EventTag > +inline property_put< PropertyMap, EventTag > put_property( + PropertyMap property_map, + typename property_traits< PropertyMap >::value_type value, EventTag) +{ + return property_put< PropertyMap, EventTag >(property_map, value); +} + +#define BOOST_GRAPH_EVENT_STUB(Event, Kind) \ + typedef ::boost::Event Event##_type; \ + template < typename Visitor > \ + Kind##_visitor< std::pair< \ + detail::functor_to_visitor< Event##_type, Visitor >, Visitors > > \ + do_##Event(Visitor visitor) \ + { \ + typedef std::pair< \ + detail::functor_to_visitor< Event##_type, Visitor >, Visitors > \ + visitor_list; \ + typedef Kind##_visitor< visitor_list > result_type; \ + return result_type(visitor_list(visitor, m_vis)); \ } } /* namespace boost */ diff --git a/include/boost/graph/wavefront.hpp b/include/boost/graph/wavefront.hpp index 3873ac718..aec285367 100644 --- a/include/boost/graph/wavefront.hpp +++ b/include/boost/graph/wavefront.hpp @@ -21,116 +21,105 @@ #include #include // for std::min and std::max -namespace boost { - - template - typename graph_traits::vertices_size_type - ith_wavefront(typename graph_traits::vertex_descriptor i, - const Graph& g, - VertexIndexMap index) - { - typename graph_traits::vertex_descriptor v, w; - typename graph_traits::vertices_size_type b = 1; - typename graph_traits::out_edge_iterator edge_it2, edge_it2_end; - typename graph_traits::vertices_size_type index_i = index[i]; - std::vector rows_active(num_vertices(g), false); +namespace boost +{ + +template < typename Graph, typename VertexIndexMap > +typename graph_traits< Graph >::vertices_size_type ith_wavefront( + typename graph_traits< Graph >::vertex_descriptor i, const Graph& g, + VertexIndexMap index) +{ + typename graph_traits< Graph >::vertex_descriptor v, w; + typename graph_traits< Graph >::vertices_size_type b = 1; + typename graph_traits< Graph >::out_edge_iterator edge_it2, edge_it2_end; + typename graph_traits< Graph >::vertices_size_type index_i = index[i]; + std::vector< bool > rows_active(num_vertices(g), false); rows_active[index_i] = true; - - typename graph_traits::vertex_iterator ui, ui_end; - for (boost::tie(ui, ui_end) = vertices(g); ui != ui_end; ++ui) - { + + typename graph_traits< Graph >::vertex_iterator ui, ui_end; + for (boost::tie(ui, ui_end) = vertices(g); ui != ui_end; ++ui) + { v = *ui; - if(index[v] <= index_i) + if (index[v] <= index_i) + { + for (boost::tie(edge_it2, edge_it2_end) = out_edges(v, g); + edge_it2 != edge_it2_end; ++edge_it2) { - for (boost::tie(edge_it2, edge_it2_end) = out_edges(v, g); edge_it2 != edge_it2_end; ++edge_it2) - { w = target(*edge_it2, g); - if( (index[w] >= index_i) && (!rows_active[index[w]]) ) - { + if ((index[w] >= index_i) && (!rows_active[index[w]])) + { b++; rows_active[index[w]] = true; - } - } + } } - } - - return b; - } + } + } + return b; +} - template - typename graph_traits::vertices_size_type - ith_wavefront(typename graph_traits::vertex_descriptor i, - const Graph& g) - { +template < typename Graph > +typename graph_traits< Graph >::vertices_size_type ith_wavefront( + typename graph_traits< Graph >::vertex_descriptor i, const Graph& g) +{ return ith_wavefront(i, g, get(vertex_index, g)); - } - +} - template - typename graph_traits::vertices_size_type - max_wavefront(const Graph& g, VertexIndexMap index) - { +template < typename Graph, typename VertexIndexMap > +typename graph_traits< Graph >::vertices_size_type max_wavefront( + const Graph& g, VertexIndexMap index) +{ BOOST_USING_STD_MAX(); - typename graph_traits::vertices_size_type b = 0; - typename graph_traits::vertex_iterator i, end; + typename graph_traits< Graph >::vertices_size_type b = 0; + typename graph_traits< Graph >::vertex_iterator i, end; for (boost::tie(i, end) = vertices(g); i != end; ++i) - b = max BOOST_PREVENT_MACRO_SUBSTITUTION(b, ith_wavefront(*i, g, index)); + b = max BOOST_PREVENT_MACRO_SUBSTITUTION( + b, ith_wavefront(*i, g, index)); return b; - } +} - template - typename graph_traits::vertices_size_type - max_wavefront(const Graph& g) - { +template < typename Graph > +typename graph_traits< Graph >::vertices_size_type max_wavefront(const Graph& g) +{ return max_wavefront(g, get(vertex_index, g)); - } +} - - template - double - aver_wavefront(const Graph& g, VertexIndexMap index) - { +template < typename Graph, typename VertexIndexMap > +double aver_wavefront(const Graph& g, VertexIndexMap index) +{ double b = 0; - typename graph_traits::vertex_iterator i, end; + typename graph_traits< Graph >::vertex_iterator i, end; for (boost::tie(i, end) = vertices(g); i != end; ++i) - b += ith_wavefront(*i, g, index); + b += ith_wavefront(*i, g, index); b /= num_vertices(g); return b; - } +} - template - double - aver_wavefront(const Graph& g) - { +template < typename Graph > double aver_wavefront(const Graph& g) +{ return aver_wavefront(g, get(vertex_index, g)); - } - +} - template - double - rms_wavefront(const Graph& g, VertexIndexMap index) - { +template < typename Graph, typename VertexIndexMap > +double rms_wavefront(const Graph& g, VertexIndexMap index) +{ double b = 0; - typename graph_traits::vertex_iterator i, end; + typename graph_traits< Graph >::vertex_iterator i, end; for (boost::tie(i, end) = vertices(g); i != end; ++i) - b += std::pow(double ( ith_wavefront(*i, g, index) ), 2.0); + b += std::pow(double(ith_wavefront(*i, g, index)), 2.0); b /= num_vertices(g); return std::sqrt(b); - } +} - template - double - rms_wavefront(const Graph& g) - { +template < typename Graph > double rms_wavefront(const Graph& g) +{ return rms_wavefront(g, get(vertex_index, g)); - } - - +} + } // namespace boost #endif // BOOST_GRAPH_WAVEFRONT_HPP diff --git a/include/boost/graph/write_dimacs.hpp b/include/boost/graph/write_dimacs.hpp index a4a577736..ec0e2c532 100644 --- a/include/boost/graph/write_dimacs.hpp +++ b/include/boost/graph/write_dimacs.hpp @@ -41,28 +41,33 @@ #include #include -namespace boost { +namespace boost +{ -template -void write_dimacs_max_flow(const Graph& g, - CapacityMap capacity, - IndexMap idx, - typename graph_traits::vertex_descriptor src, - typename graph_traits::vertex_descriptor sink, - std::ostream& out) +template < class Graph, class CapacityMap, class IndexMap > +void write_dimacs_max_flow(const Graph& g, CapacityMap capacity, IndexMap idx, + typename graph_traits< Graph >::vertex_descriptor src, + typename graph_traits< Graph >::vertex_descriptor sink, std::ostream& out) { - typedef typename graph_traits::edge_iterator edge_iterator; - - out << "c DIMACS max-flow file generated from boost::write_dimacs_max_flow" << std::endl; - out << "p max " << num_vertices(g) << " " << num_edges(g) << std::endl; //print problem description "max" and number of verts and edges - out << "n " << get(idx, src) + 1 << " s" << std::endl;; //say which one is source - out << "n " << get(idx, sink) + 1 << " t" << std::endl; //say which one is sink - - //output the edges - edge_iterator ei, e_end; - for(boost::tie(ei,e_end) = edges(g); ei!=e_end; ++ei){ - out << "a " << idx[ source(*ei, g) ] + 1 << " " << idx[ target(*ei, g) ] + 1 << " " << get(capacity,*ei) << std::endl; - } + typedef typename graph_traits< Graph >::edge_iterator edge_iterator; + + out << "c DIMACS max-flow file generated from boost::write_dimacs_max_flow" + << std::endl; + out << "p max " << num_vertices(g) << " " << num_edges(g) + << std::endl; // print problem description "max" and number of verts and + // edges + out << "n " << get(idx, src) + 1 << " s" << std::endl; + ; // say which one is source + out << "n " << get(idx, sink) + 1 << " t" + << std::endl; // say which one is sink + + // output the edges + edge_iterator ei, e_end; + for (boost::tie(ei, e_end) = edges(g); ei != e_end; ++ei) + { + out << "a " << idx[source(*ei, g)] + 1 << " " << idx[target(*ei, g)] + 1 + << " " << get(capacity, *ei) << std::endl; + } } } // namespace boost diff --git a/include/boost/pending/bucket_sorter.hpp b/include/boost/pending/bucket_sorter.hpp index 97c26b262..e39133d43 100644 --- a/include/boost/pending/bucket_sorter.hpp +++ b/include/boost/pending/bucket_sorter.hpp @@ -22,115 +22,136 @@ #include #include -namespace boost { +namespace boost +{ - template - class bucket_sorter { - BOOST_CONCEPT_ASSERT(( ReadablePropertyMapConcept )); - public: +template < class BucketType, class ValueType, class Bucket, + class ValueIndexMap > +class bucket_sorter +{ + BOOST_CONCEPT_ASSERT( + (ReadablePropertyMapConcept< ValueIndexMap, ValueType >)); + +public: typedef BucketType bucket_type; typedef ValueType value_type; - typedef typename std::vector::size_type size_type; + typedef typename std::vector< value_type >::size_type size_type; bucket_sorter(size_type _length, bucket_type _max_bucket, - const Bucket& _bucket = Bucket(), - const ValueIndexMap& _id = ValueIndexMap()) - : head(_max_bucket, invalid_value()), - next(_length, invalid_value()), - prev(_length, invalid_value()), - id_to_value(_length), - bucket(_bucket), id(_id) { } - - void remove(const value_type& x) { - const size_type i = get(id, x); - const size_type& next_node = next[i]; - const size_type& prev_node = prev[i]; - - //check if i is the end of the bucket list - if ( next_node != invalid_value() ) - prev[next_node] = prev_node; - //check if i is the begin of the bucket list - if ( prev_node != invalid_value() ) - next[prev_node] = next_node; - else //need update head of current bucket list - head[ bucket[x] ] = next_node; + const Bucket& _bucket = Bucket(), + const ValueIndexMap& _id = ValueIndexMap()) + : head(_max_bucket, invalid_value()) + , next(_length, invalid_value()) + , prev(_length, invalid_value()) + , id_to_value(_length) + , bucket(_bucket) + , id(_id) + { + } + + void remove(const value_type& x) + { + const size_type i = get(id, x); + const size_type& next_node = next[i]; + const size_type& prev_node = prev[i]; + + // check if i is the end of the bucket list + if (next_node != invalid_value()) + prev[next_node] = prev_node; + // check if i is the begin of the bucket list + if (prev_node != invalid_value()) + next[prev_node] = next_node; + else // need update head of current bucket list + head[bucket[x]] = next_node; } - void push(const value_type& x) { - id_to_value[get(id, x)] = x; - (*this)[bucket[x]].push(x); + void push(const value_type& x) + { + id_to_value[get(id, x)] = x; + (*this)[bucket[x]].push(x); } - void update(const value_type& x) { - remove(x); - (*this)[bucket[x]].push(x); + void update(const value_type& x) + { + remove(x); + (*this)[bucket[x]].push(x); } // private: // with KCC, the nested stack class is having access problems // despite the friend decl. - static size_type invalid_value() { - return (std::numeric_limits::max)(); + static size_type invalid_value() + { + return (std::numeric_limits< size_type >::max)(); } - typedef typename std::vector::iterator Iter; - typedef typename std::vector::iterator IndexValueMap; + typedef typename std::vector< size_type >::iterator Iter; + typedef typename std::vector< value_type >::iterator IndexValueMap; - public: +public: friend class stack; - class stack { + class stack + { public: - stack(bucket_type _bucket_id, Iter h, Iter n, Iter p, IndexValueMap v, + stack(bucket_type _bucket_id, Iter h, Iter n, Iter p, IndexValueMap v, const ValueIndexMap& _id) - : bucket_id(_bucket_id), head(h), next(n), prev(p), value(v), id(_id) {} - - // Avoid using default arg for ValueIndexMap so that the default - // constructor of the ValueIndexMap is not required if not used. - stack(bucket_type _bucket_id, Iter h, Iter n, Iter p, IndexValueMap v) - : bucket_id(_bucket_id), head(h), next(n), prev(p), value(v) {} - - void push(const value_type& x) { - const size_type new_head = get(id, x); - const size_type current = head[bucket_id]; - if ( current != invalid_value() ) - prev[current] = new_head; - prev[new_head] = invalid_value(); - next[new_head] = current; - head[bucket_id] = new_head; - } - void pop() { - size_type current = head[bucket_id]; - size_type next_node = next[current]; - head[bucket_id] = next_node; - if ( next_node != invalid_value() ) - prev[next_node] = invalid_value(); - } - value_type& top() { return value[ head[bucket_id] ]; } - const value_type& top() const { return value[ head[bucket_id] ]; } - bool empty() const { return head[bucket_id] == invalid_value(); } + : bucket_id(_bucket_id), head(h), next(n), prev(p), value(v), id(_id) + { + } + + // Avoid using default arg for ValueIndexMap so that the default + // constructor of the ValueIndexMap is not required if not used. + stack(bucket_type _bucket_id, Iter h, Iter n, Iter p, IndexValueMap v) + : bucket_id(_bucket_id), head(h), next(n), prev(p), value(v) + { + } + + void push(const value_type& x) + { + const size_type new_head = get(id, x); + const size_type current = head[bucket_id]; + if (current != invalid_value()) + prev[current] = new_head; + prev[new_head] = invalid_value(); + next[new_head] = current; + head[bucket_id] = new_head; + } + void pop() + { + size_type current = head[bucket_id]; + size_type next_node = next[current]; + head[bucket_id] = next_node; + if (next_node != invalid_value()) + prev[next_node] = invalid_value(); + } + value_type& top() { return value[head[bucket_id]]; } + const value_type& top() const { return value[head[bucket_id]]; } + bool empty() const { return head[bucket_id] == invalid_value(); } + private: - bucket_type bucket_id; - Iter head; - Iter next; - Iter prev; - IndexValueMap value; - ValueIndexMap id; + bucket_type bucket_id; + Iter head; + Iter next; + Iter prev; + IndexValueMap value; + ValueIndexMap id; }; - stack operator[](const bucket_type& i) { - assert(i < head.size()); - return stack(i, head.begin(), next.begin(), prev.begin(), - id_to_value.begin(), id); + stack operator[](const bucket_type& i) + { + assert(i < head.size()); + return stack(i, head.begin(), next.begin(), prev.begin(), + id_to_value.begin(), id); } - protected: - std::vector head; - std::vector next; - std::vector prev; - std::vector id_to_value; + +protected: + std::vector< size_type > head; + std::vector< size_type > next; + std::vector< size_type > prev; + std::vector< value_type > id_to_value; Bucket bucket; ValueIndexMap id; - }; +}; } diff --git a/include/boost/pending/container_traits.hpp b/include/boost/pending/container_traits.hpp index 13800a300..8bf113a3e 100644 --- a/include/boost/pending/container_traits.hpp +++ b/include/boost/pending/container_traits.hpp @@ -1,4 +1,4 @@ -// (C) Copyright Jeremy Siek 2004 +// (C) Copyright Jeremy Siek 2004 // (C) Copyright Thomas Claveirole 2010 // (C) Copyright Ignacy Gawedzki 2010 // Distributed under the Boost Software License, Version 1.0. (See @@ -10,11 +10,11 @@ // Sure would be nice to be able to forward declare these // instead of pulling in all the headers. Too bad that -// is not legal. There ought to be a standard header. -JGS +// is not legal. There ought to be a standard header. -JGS #include -#include // for std::remove +#include // for std::remove #include #include #include @@ -36,528 +36,622 @@ #define BOOST_PENDING_FWD_VALUE(type, var) (var) #else #define BOOST_PENDING_FWD_TYPE(type) type&& -#define BOOST_PENDING_FWD_VALUE(type, var) (std::forward((var))) +#define BOOST_PENDING_FWD_VALUE(type, var) (std::forward< type >((var))) #endif // The content of this file is in 'graph_detail' because otherwise -// there will be name clashes with +// there will be name clashes with // sandbox/boost/sequence_algo/container_traits.hpp // The 'detail' subnamespace will still cause problems. -namespace boost { namespace graph_detail { - - //====================================================================== - // Container Category Tags - // - // They use virtual inheritance because there are lots of - // inheritance diamonds. +namespace boost +{ +namespace graph_detail +{ + + //====================================================================== + // Container Category Tags + // + // They use virtual inheritance because there are lots of + // inheritance diamonds. + + struct container_tag + { + }; + struct forward_container_tag : virtual public container_tag + { + }; + struct reversible_container_tag : virtual public forward_container_tag + { + }; + struct random_access_container_tag : virtual public reversible_container_tag + { + }; + + struct sequence_tag : virtual public forward_container_tag + { + }; + + struct associative_container_tag : virtual public forward_container_tag + { + }; + + struct sorted_associative_container_tag + : virtual public associative_container_tag, + virtual public reversible_container_tag + { + }; + + struct front_insertion_sequence_tag : virtual public sequence_tag + { + }; + struct back_insertion_sequence_tag : virtual public sequence_tag + { + }; + + struct unique_associative_container_tag + : virtual public associative_container_tag + { + }; + struct multiple_associative_container_tag + : virtual public associative_container_tag + { + }; + struct simple_associative_container_tag + : virtual public associative_container_tag + { + }; + struct pair_associative_container_tag + : virtual public associative_container_tag + { + }; + + //====================================================================== + // Iterator Stability Tags + // + // Do mutating operations such as insert/erase/resize invalidate all + // outstanding iterators? + + struct stable_tag + { + }; + struct unstable_tag + { + }; + + //====================================================================== + // Container Traits Class and container_category() function + + // don't use this unless there is partial specialization + template < class Container > struct container_traits + { + typedef typename Container::category category; + typedef typename Container::iterator_stability iterator_stability; + }; + + // Use this as a compile-time assertion that X is stable + inline void require_stable(stable_tag) {} + + // std::vector + struct vector_tag : virtual public random_access_container_tag, + virtual public back_insertion_sequence_tag + { + }; + + template < class T, class Alloc > + vector_tag container_category(const std::vector< T, Alloc >&) + { + return vector_tag(); + } - struct container_tag { }; - struct forward_container_tag : virtual public container_tag { }; - struct reversible_container_tag : virtual public forward_container_tag { }; - struct random_access_container_tag - : virtual public reversible_container_tag { }; - - struct sequence_tag : virtual public forward_container_tag { }; + template < class T, class Alloc > + unstable_tag iterator_stability(const std::vector< T, Alloc >&) + { + return unstable_tag(); + } - struct associative_container_tag : virtual public forward_container_tag { }; + template < class T, class Alloc > + struct container_traits< std::vector< T, Alloc > > + { + typedef vector_tag category; + typedef unstable_tag iterator_stability; + }; - struct sorted_associative_container_tag - : virtual public associative_container_tag, - virtual public reversible_container_tag { }; - - struct front_insertion_sequence_tag : virtual public sequence_tag { }; - struct back_insertion_sequence_tag : virtual public sequence_tag { }; - - struct unique_associative_container_tag - : virtual public associative_container_tag { }; - struct multiple_associative_container_tag - : virtual public associative_container_tag { }; - struct simple_associative_container_tag - : virtual public associative_container_tag { }; - struct pair_associative_container_tag - : virtual public associative_container_tag { }; - - - //====================================================================== - // Iterator Stability Tags - // - // Do mutating operations such as insert/erase/resize invalidate all - // outstanding iterators? - - struct stable_tag { }; - struct unstable_tag { }; - - //====================================================================== - // Container Traits Class and container_category() function - - // don't use this unless there is partial specialization - template - struct container_traits { - typedef typename Container::category category; - typedef typename Container::iterator_stability iterator_stability; - }; - - // Use this as a compile-time assertion that X is stable - inline void require_stable(stable_tag) { } - - // std::vector - struct vector_tag : - virtual public random_access_container_tag, - virtual public back_insertion_sequence_tag { }; - - template - vector_tag container_category(const std::vector&) - { return vector_tag(); } - - template - unstable_tag iterator_stability(const std::vector&) - { return unstable_tag(); } - - template - struct container_traits< std::vector > { - typedef vector_tag category; - typedef unstable_tag iterator_stability; - }; - - // std::list - struct list_tag : - virtual public reversible_container_tag, - virtual public back_insertion_sequence_tag + // std::list + struct list_tag : virtual public reversible_container_tag, + virtual public back_insertion_sequence_tag // this causes problems for push_dispatch... // virtual public front_insertion_sequence_tag - { }; - - template - list_tag container_category(const std::list&) - { return list_tag(); } - - template - stable_tag iterator_stability(const std::list&) - { return stable_tag(); } - - template - struct container_traits< std::list > { - typedef list_tag category; - typedef stable_tag iterator_stability; - }; - - // std::set - struct set_tag : - virtual public sorted_associative_container_tag, - virtual public simple_associative_container_tag, - virtual public unique_associative_container_tag - { }; - - template - set_tag container_category(const std::set&) - { return set_tag(); } - - template - stable_tag iterator_stability(const std::set&) - { return stable_tag(); } - - template - struct container_traits< std::set > { - typedef set_tag category; - typedef stable_tag iterator_stability; - }; - - // std::multiset - struct multiset_tag : - virtual public sorted_associative_container_tag, - virtual public simple_associative_container_tag, - virtual public multiple_associative_container_tag - { }; - - template - multiset_tag container_category(const std::multiset&) - { return multiset_tag(); } - - template - stable_tag iterator_stability(const std::multiset&) - { return stable_tag(); } - - template - struct container_traits< std::multiset > { - typedef multiset_tag category; - typedef stable_tag iterator_stability; - }; - - // deque - - // std::map - struct map_tag : - virtual public sorted_associative_container_tag, - virtual public pair_associative_container_tag, - virtual public unique_associative_container_tag - { }; - - template - struct container_traits< std::map > { - typedef map_tag category; - typedef stable_tag iterator_stability; - }; - - template - map_tag container_category(const std::map&) - { return map_tag(); } - - template - stable_tag iterator_stability(const std::map&) - { return stable_tag(); } - - // std::multimap - struct multimap_tag : - virtual public sorted_associative_container_tag, - virtual public pair_associative_container_tag, - virtual public multiple_associative_container_tag - { }; - - template - struct container_traits< std::multimap > { - typedef multimap_tag category; - typedef stable_tag iterator_stability; - }; - - template - multimap_tag container_category(const std::multimap&) - { return multimap_tag(); } - - template - stable_tag iterator_stability(const std::multimap&) - { return stable_tag(); } - - - // hash_set, hash_map - - struct unordered_set_tag : - virtual public simple_associative_container_tag, - virtual public unique_associative_container_tag - { }; - - struct unordered_multiset_tag : - virtual public simple_associative_container_tag, - virtual public multiple_associative_container_tag - { }; - - - struct unordered_map_tag : - virtual public pair_associative_container_tag, - virtual public unique_associative_container_tag - { }; - - struct unordered_multimap_tag : - virtual public pair_associative_container_tag, - virtual public multiple_associative_container_tag - { }; - - - template - struct container_traits< boost::unordered_set > { - typedef unordered_set_tag category; - typedef unstable_tag iterator_stability; - }; - template - struct container_traits< boost::unordered_map > { - typedef unordered_map_tag category; - typedef unstable_tag iterator_stability; - }; - template - struct container_traits< boost::unordered_multiset > { - typedef unordered_multiset_tag category; - typedef unstable_tag iterator_stability; - }; - template - struct container_traits< boost::unordered_multimap > { - typedef unordered_multimap_tag category; - typedef unstable_tag iterator_stability; - }; - - template - unordered_set_tag - container_category(const boost::unordered_set&) - { return unordered_set_tag(); } - - template - unordered_map_tag - container_category(const boost::unordered_map&) - { return unordered_map_tag(); } - - template - unstable_tag iterator_stability(const boost::unordered_set&) - { return unstable_tag(); } - - template - unstable_tag iterator_stability(const boost::unordered_map&) - { return unstable_tag(); } - template - unordered_multiset_tag - container_category(const boost::unordered_multiset&) - { return unordered_multiset_tag(); } - - template - unordered_multimap_tag - container_category(const boost::unordered_multimap&) - { return unordered_multimap_tag(); } - - template - unstable_tag - iterator_stability(const boost::unordered_multiset&) - { return unstable_tag(); } - - template - unstable_tag - iterator_stability(const boost::unordered_multimap&) - { return unstable_tag(); } + { + }; + + template < class T, class Alloc > + list_tag container_category(const std::list< T, Alloc >&) + { + return list_tag(); + } + + template < class T, class Alloc > + stable_tag iterator_stability(const std::list< T, Alloc >&) + { + return stable_tag(); + } + + template < class T, class Alloc > + struct container_traits< std::list< T, Alloc > > + { + typedef list_tag category; + typedef stable_tag iterator_stability; + }; + + // std::set + struct set_tag : virtual public sorted_associative_container_tag, + virtual public simple_associative_container_tag, + virtual public unique_associative_container_tag + { + }; + + template < class Key, class Cmp, class Alloc > + set_tag container_category(const std::set< Key, Cmp, Alloc >&) + { + return set_tag(); + } + + template < class Key, class Cmp, class Alloc > + stable_tag iterator_stability(const std::set< Key, Cmp, Alloc >&) + { + return stable_tag(); + } + + template < class Key, class Cmp, class Alloc > + struct container_traits< std::set< Key, Cmp, Alloc > > + { + typedef set_tag category; + typedef stable_tag iterator_stability; + }; + + // std::multiset + struct multiset_tag : virtual public sorted_associative_container_tag, + virtual public simple_associative_container_tag, + virtual public multiple_associative_container_tag + { + }; + + template < class Key, class Cmp, class Alloc > + multiset_tag container_category(const std::multiset< Key, Cmp, Alloc >&) + { + return multiset_tag(); + } + + template < class Key, class Cmp, class Alloc > + stable_tag iterator_stability(const std::multiset< Key, Cmp, Alloc >&) + { + return stable_tag(); + } + + template < class Key, class Cmp, class Alloc > + struct container_traits< std::multiset< Key, Cmp, Alloc > > + { + typedef multiset_tag category; + typedef stable_tag iterator_stability; + }; + + // deque + + // std::map + struct map_tag : virtual public sorted_associative_container_tag, + virtual public pair_associative_container_tag, + virtual public unique_associative_container_tag + { + }; + + template < class Key, class T, class Cmp, class Alloc > + struct container_traits< std::map< Key, T, Cmp, Alloc > > + { + typedef map_tag category; + typedef stable_tag iterator_stability; + }; + + template < class Key, class T, class Cmp, class Alloc > + map_tag container_category(const std::map< Key, T, Cmp, Alloc >&) + { + return map_tag(); + } + + template < class Key, class T, class Cmp, class Alloc > + stable_tag iterator_stability(const std::map< Key, T, Cmp, Alloc >&) + { + return stable_tag(); + } + + // std::multimap + struct multimap_tag : virtual public sorted_associative_container_tag, + virtual public pair_associative_container_tag, + virtual public multiple_associative_container_tag + { + }; + + template < class Key, class T, class Cmp, class Alloc > + struct container_traits< std::multimap< Key, T, Cmp, Alloc > > + { + typedef multimap_tag category; + typedef stable_tag iterator_stability; + }; + + template < class Key, class T, class Cmp, class Alloc > + multimap_tag container_category(const std::multimap< Key, T, Cmp, Alloc >&) + { + return multimap_tag(); + } + + template < class Key, class T, class Cmp, class Alloc > + stable_tag iterator_stability(const std::multimap< Key, T, Cmp, Alloc >&) + { + return stable_tag(); + } + + // hash_set, hash_map + + struct unordered_set_tag : virtual public simple_associative_container_tag, + virtual public unique_associative_container_tag + { + }; + + struct unordered_multiset_tag + : virtual public simple_associative_container_tag, + virtual public multiple_associative_container_tag + { + }; + + struct unordered_map_tag : virtual public pair_associative_container_tag, + virtual public unique_associative_container_tag + { + }; + + struct unordered_multimap_tag + : virtual public pair_associative_container_tag, + virtual public multiple_associative_container_tag + { + }; + + template < class Key, class Eq, class Hash, class Alloc > + struct container_traits< boost::unordered_set< Key, Eq, Hash, Alloc > > + { + typedef unordered_set_tag category; + typedef unstable_tag iterator_stability; + }; + template < class Key, class T, class Eq, class Hash, class Alloc > + struct container_traits< boost::unordered_map< Key, T, Eq, Hash, Alloc > > + { + typedef unordered_map_tag category; + typedef unstable_tag iterator_stability; + }; + template < class Key, class Eq, class Hash, class Alloc > + struct container_traits< boost::unordered_multiset< Key, Eq, Hash, Alloc > > + { + typedef unordered_multiset_tag category; + typedef unstable_tag iterator_stability; + }; + template < class Key, class T, class Eq, class Hash, class Alloc > + struct container_traits< + boost::unordered_multimap< Key, T, Eq, Hash, Alloc > > + { + typedef unordered_multimap_tag category; + typedef unstable_tag iterator_stability; + }; + + template < class Key, class Eq, class Hash, class Alloc > + unordered_set_tag container_category( + const boost::unordered_set< Key, Eq, Hash, Alloc >&) + { + return unordered_set_tag(); + } + + template < class Key, class T, class Eq, class Hash, class Alloc > + unordered_map_tag container_category( + const boost::unordered_map< Key, T, Eq, Hash, Alloc >&) + { + return unordered_map_tag(); + } + + template < class Key, class Eq, class Hash, class Alloc > + unstable_tag iterator_stability( + const boost::unordered_set< Key, Eq, Hash, Alloc >&) + { + return unstable_tag(); + } + + template < class Key, class T, class Eq, class Hash, class Alloc > + unstable_tag iterator_stability( + const boost::unordered_map< Key, T, Eq, Hash, Alloc >&) + { + return unstable_tag(); + } + template < class Key, class Eq, class Hash, class Alloc > + unordered_multiset_tag container_category( + const boost::unordered_multiset< Key, Eq, Hash, Alloc >&) + { + return unordered_multiset_tag(); + } + + template < class Key, class T, class Eq, class Hash, class Alloc > + unordered_multimap_tag container_category( + const boost::unordered_multimap< Key, T, Eq, Hash, Alloc >&) + { + return unordered_multimap_tag(); + } + + template < class Key, class Eq, class Hash, class Alloc > + unstable_tag iterator_stability( + const boost::unordered_multiset< Key, Eq, Hash, Alloc >&) + { + return unstable_tag(); + } + + template < class Key, class T, class Eq, class Hash, class Alloc > + unstable_tag iterator_stability( + const boost::unordered_multimap< Key, T, Eq, Hash, Alloc >&) + { + return unstable_tag(); + } #ifndef BOOST_NO_CXX11_HDR_UNORDERED_SET - template - struct container_traits< std::unordered_set > { - typedef unordered_set_tag category; - typedef unstable_tag iterator_stability; - }; + template < class Key, class Eq, class Hash, class Alloc > + struct container_traits< std::unordered_set< Key, Eq, Hash, Alloc > > + { + typedef unordered_set_tag category; + typedef unstable_tag iterator_stability; + }; #endif #ifndef BOOST_NO_CXX11_HDR_UNORDERED_MAP - template - struct container_traits< std::unordered_map > { - typedef unordered_map_tag category; - typedef unstable_tag iterator_stability; - }; + template < class Key, class T, class Eq, class Hash, class Alloc > + struct container_traits< std::unordered_map< Key, T, Eq, Hash, Alloc > > + { + typedef unordered_map_tag category; + typedef unstable_tag iterator_stability; + }; #endif #ifndef BOOST_NO_CXX11_HDR_UNORDERED_SET - template - struct container_traits< std::unordered_multiset > { - typedef unordered_multiset_tag category; - typedef unstable_tag iterator_stability; - }; + template < class Key, class Eq, class Hash, class Alloc > + struct container_traits< std::unordered_multiset< Key, Eq, Hash, Alloc > > + { + typedef unordered_multiset_tag category; + typedef unstable_tag iterator_stability; + }; #endif #ifndef BOOST_NO_CXX11_HDR_UNORDERED_MAP - template - struct container_traits< std::unordered_multimap > { - typedef unordered_multimap_tag category; - typedef unstable_tag iterator_stability; - }; + template < class Key, class T, class Eq, class Hash, class Alloc > + struct container_traits< + std::unordered_multimap< Key, T, Eq, Hash, Alloc > > + { + typedef unordered_multimap_tag category; + typedef unstable_tag iterator_stability; + }; #endif #ifndef BOOST_NO_CXX11_HDR_UNORDERED_SET - template - unordered_set_tag - container_category(const std::unordered_set&) - { return unordered_set_tag(); } + template < class Key, class Eq, class Hash, class Alloc > + unordered_set_tag container_category( + const std::unordered_set< Key, Eq, Hash, Alloc >&) + { + return unordered_set_tag(); + } #endif #ifndef BOOST_NO_CXX11_HDR_UNORDERED_MAP - template - unordered_map_tag - container_category(const std::unordered_map&) - { return unordered_map_tag(); } + template < class Key, class T, class Eq, class Hash, class Alloc > + unordered_map_tag container_category( + const std::unordered_map< Key, T, Eq, Hash, Alloc >&) + { + return unordered_map_tag(); + } #endif #ifndef BOOST_NO_CXX11_HDR_UNORDERED_SET - template - unstable_tag iterator_stability(const std::unordered_set&) - { return unstable_tag(); } + template < class Key, class Eq, class Hash, class Alloc > + unstable_tag iterator_stability( + const std::unordered_set< Key, Eq, Hash, Alloc >&) + { + return unstable_tag(); + } #endif #ifndef BOOST_NO_CXX11_HDR_UNORDERED_MAP - template - unstable_tag iterator_stability(const std::unordered_map&) - { return unstable_tag(); } + template < class Key, class T, class Eq, class Hash, class Alloc > + unstable_tag iterator_stability( + const std::unordered_map< Key, T, Eq, Hash, Alloc >&) + { + return unstable_tag(); + } #endif #ifndef BOOST_NO_CXX11_HDR_UNORDERED_SET - template - unordered_multiset_tag - container_category(const std::unordered_multiset&) - { return unordered_multiset_tag(); } + template < class Key, class Eq, class Hash, class Alloc > + unordered_multiset_tag container_category( + const std::unordered_multiset< Key, Eq, Hash, Alloc >&) + { + return unordered_multiset_tag(); + } #endif #ifndef BOOST_NO_CXX11_HDR_UNORDERED_MAP - template - unordered_multimap_tag - container_category(const std::unordered_multimap&) - { return unordered_multimap_tag(); } + template < class Key, class T, class Eq, class Hash, class Alloc > + unordered_multimap_tag container_category( + const std::unordered_multimap< Key, T, Eq, Hash, Alloc >&) + { + return unordered_multimap_tag(); + } #endif #ifndef BOOST_NO_CXX11_HDR_UNORDERED_SET - template - unstable_tag - iterator_stability(const std::unordered_multiset&) - { return unstable_tag(); } + template < class Key, class Eq, class Hash, class Alloc > + unstable_tag iterator_stability( + const std::unordered_multiset< Key, Eq, Hash, Alloc >&) + { + return unstable_tag(); + } #endif #ifndef BOOST_NO_CXX11_HDR_UNORDERED_MAP - template - unstable_tag - iterator_stability(const std::unordered_multimap&) - { return unstable_tag(); } + template < class Key, class T, class Eq, class Hash, class Alloc > + unstable_tag iterator_stability( + const std::unordered_multimap< Key, T, Eq, Hash, Alloc >&) + { + return unstable_tag(); + } #endif + //=========================================================================== + // Generalized Container Functions - //=========================================================================== - // Generalized Container Functions - - - // Erase - template - void erase_dispatch(Sequence& c, const T& x, - sequence_tag) - { - c.erase(std::remove(c.begin(), c.end(), x), c.end()); - } + // Erase + template < class Sequence, class T > + void erase_dispatch(Sequence& c, const T& x, sequence_tag) + { + c.erase(std::remove(c.begin(), c.end(), x), c.end()); + } - template - void erase_dispatch(AssociativeContainer& c, const T& x, - associative_container_tag) - { - c.erase(x); - } - template - void erase(Container& c, const T& x) - { - erase_dispatch(c, x, container_category(c)); - } + template < class AssociativeContainer, class T > + void erase_dispatch( + AssociativeContainer& c, const T& x, associative_container_tag) + { + c.erase(x); + } + template < class Container, class T > void erase(Container& c, const T& x) + { + erase_dispatch(c, x, container_category(c)); + } - // Erase If - template - void erase_if_dispatch(Sequence& c, Predicate p, - sequence_tag, IteratorStability) - { + // Erase If + template < class Sequence, class Predicate, class IteratorStability > + void erase_if_dispatch( + Sequence& c, Predicate p, sequence_tag, IteratorStability) + { #if 0 c.erase(std::remove_if(c.begin(), c.end(), p), c.end()); #else - if (! c.empty()) - c.erase(std::remove_if(c.begin(), c.end(), p), c.end()); + if (!c.empty()) + c.erase(std::remove_if(c.begin(), c.end(), p), c.end()); #endif - } - template - void erase_if_dispatch(AssociativeContainer& c, Predicate p, - associative_container_tag, stable_tag) - { - typename AssociativeContainer::iterator i, next; - for (i = next = c.begin(); next != c.end(); i = next) { - ++next; - if (p(*i)) - c.erase(i); } - } - template - void erase_if_dispatch(AssociativeContainer& c, Predicate p, - associative_container_tag, unstable_tag) - { - // This method is really slow, so hopefully we won't have any - // associative containers with unstable iterators! - // Is there a better way to do this? - typename AssociativeContainer::iterator i; - typename AssociativeContainer::size_type n = c.size(); - while (n--) - for (i = c.begin(); i != c.end(); ++i) - if (p(*i)) { - c.erase(i); - break; + template < class AssociativeContainer, class Predicate > + void erase_if_dispatch(AssociativeContainer& c, Predicate p, + associative_container_tag, stable_tag) + { + typename AssociativeContainer::iterator i, next; + for (i = next = c.begin(); next != c.end(); i = next) + { + ++next; + if (p(*i)) + c.erase(i); } - } - template - void erase_if(Container& c, Predicate p) - { - erase_if_dispatch(c, p, container_category(c), iterator_stability(c)); - } + } + template < class AssociativeContainer, class Predicate > + void erase_if_dispatch(AssociativeContainer& c, Predicate p, + associative_container_tag, unstable_tag) + { + // This method is really slow, so hopefully we won't have any + // associative containers with unstable iterators! + // Is there a better way to do this? + typename AssociativeContainer::iterator i; + typename AssociativeContainer::size_type n = c.size(); + while (n--) + for (i = c.begin(); i != c.end(); ++i) + if (p(*i)) + { + c.erase(i); + break; + } + } + template < class Container, class Predicate > + void erase_if(Container& c, Predicate p) + { + erase_if_dispatch(c, p, container_category(c), iterator_stability(c)); + } - // Push - template - std::pair - push_dispatch(Container& c, BOOST_PENDING_FWD_TYPE(T) v, back_insertion_sequence_tag) - { - c.push_back(BOOST_PENDING_FWD_VALUE(T, v)); - return std::make_pair(boost::prior(c.end()), true); - } + // Push + template < class Container, class T > + std::pair< typename Container::iterator, bool > push_dispatch( + Container& c, BOOST_PENDING_FWD_TYPE(T) v, back_insertion_sequence_tag) + { + c.push_back(BOOST_PENDING_FWD_VALUE(T, v)); + return std::make_pair(boost::prior(c.end()), true); + } - template - std::pair - push_dispatch(Container& c, BOOST_PENDING_FWD_TYPE(T) v, front_insertion_sequence_tag) - { - c.push_front(BOOST_PENDING_FWD_VALUE(T, v)); - return std::make_pair(c.begin(), true); - } + template < class Container, class T > + std::pair< typename Container::iterator, bool > push_dispatch( + Container& c, BOOST_PENDING_FWD_TYPE(T) v, front_insertion_sequence_tag) + { + c.push_front(BOOST_PENDING_FWD_VALUE(T, v)); + return std::make_pair(c.begin(), true); + } - template - std::pair - push_dispatch(AssociativeContainer& c, BOOST_PENDING_FWD_TYPE(T) v, - unique_associative_container_tag) - { - return c.insert(BOOST_PENDING_FWD_VALUE(T, v)); - } + template < class AssociativeContainer, class T > + std::pair< typename AssociativeContainer::iterator, bool > push_dispatch( + AssociativeContainer& c, BOOST_PENDING_FWD_TYPE(T) v, + unique_associative_container_tag) + { + return c.insert(BOOST_PENDING_FWD_VALUE(T, v)); + } - template - std::pair - push_dispatch(AssociativeContainer& c, BOOST_PENDING_FWD_TYPE(T) v, - multiple_associative_container_tag) - { - return std::make_pair(c.insert(BOOST_PENDING_FWD_VALUE(T, v)), true); - } + template < class AssociativeContainer, class T > + std::pair< typename AssociativeContainer::iterator, bool > push_dispatch( + AssociativeContainer& c, BOOST_PENDING_FWD_TYPE(T) v, + multiple_associative_container_tag) + { + return std::make_pair(c.insert(BOOST_PENDING_FWD_VALUE(T, v)), true); + } - template - std::pair - push(Container& c, BOOST_PENDING_FWD_TYPE(T) v) - { - return push_dispatch(c, BOOST_PENDING_FWD_VALUE(T, v), container_category(c)); - } + template < class Container, class T > + std::pair< typename Container::iterator, bool > push( + Container& c, BOOST_PENDING_FWD_TYPE(T) v) + { + return push_dispatch( + c, BOOST_PENDING_FWD_VALUE(T, v), container_category(c)); + } - // Find - template - typename Container::iterator - find_dispatch(Container& c, - const Value& value, - container_tag) - { - return std::find(c.begin(), c.end(), value); - } + // Find + template < class Container, class Value > + typename Container::iterator find_dispatch( + Container& c, const Value& value, container_tag) + { + return std::find(c.begin(), c.end(), value); + } - template - typename AssociativeContainer::iterator - find_dispatch(AssociativeContainer& c, - const Value& value, - associative_container_tag) - { - return c.find(value); - } + template < class AssociativeContainer, class Value > + typename AssociativeContainer::iterator find_dispatch( + AssociativeContainer& c, const Value& value, associative_container_tag) + { + return c.find(value); + } - template - typename Container::iterator - find(Container& c, - const Value& value) - { - return find_dispatch(c, value, - graph_detail::container_category(c)); - } + template < class Container, class Value > + typename Container::iterator find(Container& c, const Value& value) + { + return find_dispatch(c, value, graph_detail::container_category(c)); + } - // Find (const versions) - template - typename Container::const_iterator - find_dispatch(const Container& c, - const Value& value, - container_tag) - { - return std::find(c.begin(), c.end(), value); - } + // Find (const versions) + template < class Container, class Value > + typename Container::const_iterator find_dispatch( + const Container& c, const Value& value, container_tag) + { + return std::find(c.begin(), c.end(), value); + } - template - typename AssociativeContainer::const_iterator - find_dispatch(const AssociativeContainer& c, - const Value& value, - associative_container_tag) - { - return c.find(value); - } + template < class AssociativeContainer, class Value > + typename AssociativeContainer::const_iterator find_dispatch( + const AssociativeContainer& c, const Value& value, + associative_container_tag) + { + return c.find(value); + } - template - typename Container::const_iterator - find(const Container& c, - const Value& value) - { - return find_dispatch(c, value, - graph_detail::container_category(c)); - } + template < class Container, class Value > + typename Container::const_iterator find( + const Container& c, const Value& value) + { + return find_dispatch(c, value, graph_detail::container_category(c)); + } - // Equal range + // Equal range #if 0 // Make the dispatch fail if c is not an Associative Container (and thus // doesn't have equal_range unless it is sorted, which we cannot check @@ -574,26 +668,25 @@ namespace boost { namespace graph_detail { } #endif - template - std::pair - equal_range_dispatch(AssociativeContainer& c, - const Value& value, - associative_container_tag) - { - return c.equal_range(value); - } + template < class AssociativeContainer, class Value > + std::pair< typename AssociativeContainer::iterator, + typename AssociativeContainer::iterator > + equal_range_dispatch( + AssociativeContainer& c, const Value& value, associative_container_tag) + { + return c.equal_range(value); + } - template - std::pair - equal_range(Container& c, - const Value& value) - { - return equal_range_dispatch(c, value, - graph_detail::container_category(c)); - } + template < class Container, class Value > + std::pair< typename Container::iterator, typename Container::iterator > + equal_range(Container& c, const Value& value) + { + return equal_range_dispatch( + c, value, graph_detail::container_category(c)); + } -}} // namespace boost::graph_detail +} +} // namespace boost::graph_detail #undef BOOST_PENDING_FWD_TYPE #undef BOOST_PENDING_FWD_VALUE diff --git a/include/boost/pending/detail/disjoint_sets.hpp b/include/boost/pending/detail/disjoint_sets.hpp index 6d1ec3ac7..1ec0e4950 100644 --- a/include/boost/pending/detail/disjoint_sets.hpp +++ b/include/boost/pending/detail/disjoint_sets.hpp @@ -1,4 +1,4 @@ -// (C) Copyright Jeremy Siek 2004 +// (C) Copyright Jeremy Siek 2004 // Distributed under the Boost Software License, Version 1.0. (See // accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) @@ -6,83 +6,88 @@ #ifndef BOOST_DETAIL_DISJOINT_SETS_HPP #define BOOST_DETAIL_DISJOINT_SETS_HPP -namespace boost { +namespace boost +{ -namespace detail { +namespace detail +{ -template -Vertex -find_representative_with_path_halving(ParentPA p, Vertex v) -{ - Vertex parent = get(p, v); - Vertex grandparent = get(p, parent); - while (parent != grandparent) { - put(p, v, grandparent); - v = grandparent; - parent = get(p, v); - grandparent = get(p, parent); - } - return parent; -} + template < class ParentPA, class Vertex > + Vertex find_representative_with_path_halving(ParentPA p, Vertex v) + { + Vertex parent = get(p, v); + Vertex grandparent = get(p, parent); + while (parent != grandparent) + { + put(p, v, grandparent); + v = grandparent; + parent = get(p, v); + grandparent = get(p, parent); + } + return parent; + } -template -Vertex -find_representative_with_full_compression(ParentPA parent, Vertex v) -{ - Vertex old = v; - Vertex ancestor = get(parent, v); - while (ancestor != v) { - v = ancestor; - ancestor = get(parent, v); - } - v = get(parent, old); - while (ancestor != v) { - put(parent, old, ancestor); - old = v; - v = get(parent, old); - } - return ancestor; -} + template < class ParentPA, class Vertex > + Vertex find_representative_with_full_compression(ParentPA parent, Vertex v) + { + Vertex old = v; + Vertex ancestor = get(parent, v); + while (ancestor != v) + { + v = ancestor; + ancestor = get(parent, v); + } + v = get(parent, old); + while (ancestor != v) + { + put(parent, old, ancestor); + old = v; + v = get(parent, old); + } + return ancestor; + } -/* the postcondition of link sets is: - component_representative(i) == component_representative(j) - */ -template -inline void -link_sets(ParentPA p, RankPA rank, Vertex i, Vertex j, - ComponentRepresentative comp_rep) -{ - i = comp_rep(p, i); - j = comp_rep(p, j); - if (i == j) return; - if (get(rank, i) > get(rank, j)) - put(p, j, i); - else { - put(p, i, j); - if (get(rank, i) == get(rank, j)) - put(rank, j, get(rank, j) + 1); - } -} + /* the postcondition of link sets is: + component_representative(i) == component_representative(j) + */ + template < class ParentPA, class RankPA, class Vertex, + class ComponentRepresentative > + inline void link_sets(ParentPA p, RankPA rank, Vertex i, Vertex j, + ComponentRepresentative comp_rep) + { + i = comp_rep(p, i); + j = comp_rep(p, j); + if (i == j) + return; + if (get(rank, i) > get(rank, j)) + put(p, j, i); + else + { + put(p, i, j); + if (get(rank, i) == get(rank, j)) + put(rank, j, get(rank, j) + 1); + } + } -// normalize components has the following postcondidition: -// i >= p[i] -// that is, the representative is the node with the smallest index in its class -// as its precondition it it assumes that the node container is compressed + // normalize components has the following postcondidition: + // i >= p[i] + // that is, the representative is the node with the smallest index in its + // class as its precondition it it assumes that the node container is + // compressed -template -inline void -normalize_node(ParentPA p, Vertex i) -{ - if (i > get(p,i) || get(p, get(p,i)) != get(p,i)) - put(p,i, get(p, get(p,i))); - else { - put(p, get(p,i), i); - put(p, i, i); - } -} + template < class ParentPA, class Vertex > + inline void normalize_node(ParentPA p, Vertex i) + { + if (i > get(p, i) || get(p, get(p, i)) != get(p, i)) + put(p, i, get(p, get(p, i))); + else + { + put(p, get(p, i), i); + put(p, i, i); + } + } - } // namespace detail +} // namespace detail } // namespace boost #endif // BOOST_DETAIL_DISJOINT_SETS_HPP diff --git a/include/boost/pending/detail/property.hpp b/include/boost/pending/detail/property.hpp index 42c7ce07d..9967ffb28 100644 --- a/include/boost/pending/detail/property.hpp +++ b/include/boost/pending/detail/property.hpp @@ -1,4 +1,4 @@ -// (C) Copyright Jeremy Siek 2004 +// (C) Copyright Jeremy Siek 2004 // Distributed under the Boost Software License, Version 1.0. (See // accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) @@ -9,13 +9,17 @@ #include // for std::pair #include // for is_same -namespace boost { +namespace boost +{ - namespace detail { +namespace detail +{ - struct error_property_not_found { }; + struct error_property_not_found + { + }; - } // namespace detail +} // namespace detail } // namespace boost #endif // BOOST_DETAIL_PROPERTY_HPP diff --git a/include/boost/pending/disjoint_sets.hpp b/include/boost/pending/disjoint_sets.hpp index e64bc2b71..85a7c4ce8 100644 --- a/include/boost/pending/disjoint_sets.hpp +++ b/include/boost/pending/disjoint_sets.hpp @@ -15,197 +15,188 @@ #include #include -namespace boost { - - struct find_with_path_halving { - template - Vertex operator()(ParentPA p, Vertex v) { - return detail::find_representative_with_path_halving(p, v); - } - }; - - struct find_with_full_path_compression { - template - Vertex operator()(ParentPA p, Vertex v){ - return detail::find_representative_with_full_compression(p, v); - } - }; - - // This is a generalized functor to provide disjoint sets operations - // with "union by rank" and "path compression". A disjoint-set data - // structure maintains a collection S={S1, S2, ..., Sk} of disjoint - // sets. Each set is identified by a representative, which is some - // member of of the set. Sets are represented by rooted trees. Two - // heuristics: "union by rank" and "path compression" are used to - // speed up the operations. - - // Disjoint Set requires two vertex properties for internal use. A - // RankPA and a ParentPA. The RankPA must map Vertex to some Integral type - // (preferably the size_type associated with Vertex). The ParentPA - // must map Vertex to Vertex. - template - class disjoint_sets { +namespace boost +{ + +struct find_with_path_halving +{ + template < class ParentPA, class Vertex > + Vertex operator()(ParentPA p, Vertex v) + { + return detail::find_representative_with_path_halving(p, v); + } +}; + +struct find_with_full_path_compression +{ + template < class ParentPA, class Vertex > + Vertex operator()(ParentPA p, Vertex v) + { + return detail::find_representative_with_full_compression(p, v); + } +}; + +// This is a generalized functor to provide disjoint sets operations +// with "union by rank" and "path compression". A disjoint-set data +// structure maintains a collection S={S1, S2, ..., Sk} of disjoint +// sets. Each set is identified by a representative, which is some +// member of of the set. Sets are represented by rooted trees. Two +// heuristics: "union by rank" and "path compression" are used to +// speed up the operations. + +// Disjoint Set requires two vertex properties for internal use. A +// RankPA and a ParentPA. The RankPA must map Vertex to some Integral type +// (preferably the size_type associated with Vertex). The ParentPA +// must map Vertex to Vertex. +template < class RankPA, class ParentPA, + class FindCompress = find_with_full_path_compression > +class disjoint_sets +{ typedef disjoint_sets self; - + inline disjoint_sets() {} - public: - inline disjoint_sets(RankPA r, ParentPA p) - : rank(r), parent(p) {} - inline disjoint_sets(const self& c) - : rank(c.rank), parent(c.parent) {} - +public: + inline disjoint_sets(RankPA r, ParentPA p) : rank(r), parent(p) {} + + inline disjoint_sets(const self& c) : rank(c.rank), parent(c.parent) {} + // Make Set -- Create a singleton set containing vertex x - template - inline void make_set(Element x) + template < class Element > inline void make_set(Element x) { - put(parent, x, x); - typedef typename property_traits::value_type R; - put(rank, x, R()); + put(parent, x, x); + typedef typename property_traits< RankPA >::value_type R; + put(rank, x, R()); } - + // Link - union the two sets represented by vertex x and y - template - inline void link(Element x, Element y) + template < class Element > inline void link(Element x, Element y) { - detail::link_sets(parent, rank, x, y, rep); + detail::link_sets(parent, rank, x, y, rep); } - - // Union-Set - union the two sets containing vertex x and y - template - inline void union_set(Element x, Element y) + + // Union-Set - union the two sets containing vertex x and y + template < class Element > inline void union_set(Element x, Element y) { - link(find_set(x), find_set(y)); + link(find_set(x), find_set(y)); } - + // Find-Set - returns the Element representative of the set // containing Element x and applies path compression. - template - inline Element find_set(Element x) + template < class Element > inline Element find_set(Element x) { - return rep(parent, x); + return rep(parent, x); } - template + template < class ElementIterator > inline std::size_t count_sets(ElementIterator first, ElementIterator last) { - std::size_t count = 0; - for ( ; first != last; ++first) - if (get(parent, *first) == *first) - ++count; - return count; + std::size_t count = 0; + for (; first != last; ++first) + if (get(parent, *first) == *first) + ++count; + return count; } - template + template < class ElementIterator > inline void normalize_sets(ElementIterator first, ElementIterator last) { - for (; first != last; ++first) - detail::normalize_node(parent, *first); - } - - template + for (; first != last; ++first) + detail::normalize_node(parent, *first); + } + + template < class ElementIterator > inline void compress_sets(ElementIterator first, ElementIterator last) { - for (; first != last; ++first) - detail::find_representative_with_full_compression(parent, *first); - } - protected: + for (; first != last; ++first) + detail::find_representative_with_full_compression(parent, *first); + } + +protected: RankPA rank; ParentPA parent; FindCompress rep; - }; - - - - - template - class disjoint_sets_with_storage - { - typedef typename property_traits::value_type Index; - typedef std::vector ParentContainer; - typedef std::vector RankContainer; - public: +}; + +template < class ID = identity_property_map, + class InverseID = identity_property_map, + class FindCompress = find_with_full_path_compression > +class disjoint_sets_with_storage +{ + typedef typename property_traits< ID >::value_type Index; + typedef std::vector< Index > ParentContainer; + typedef std::vector< unsigned char > RankContainer; + +public: typedef typename ParentContainer::size_type size_type; - disjoint_sets_with_storage(size_type n = 0, - ID id_ = ID(), - InverseID inv = InverseID()) - : id(id_), id_to_vertex(inv), rank(n, 0), parent(n) + disjoint_sets_with_storage( + size_type n = 0, ID id_ = ID(), InverseID inv = InverseID()) + : id(id_), id_to_vertex(inv), rank(n, 0), parent(n) { - for (Index i = 0; i < n; ++i) - parent[i] = i; + for (Index i = 0; i < n; ++i) + parent[i] = i; } // note this is not normally needed - template - inline void - make_set(Element x) { - parent[x] = x; - rank[x] = 0; + template < class Element > inline void make_set(Element x) + { + parent[x] = x; + rank[x] = 0; } - template - inline void - link(Element x, Element y) + template < class Element > inline void link(Element x, Element y) { - extend_sets(x,y); - detail::link_sets(&parent[0], &rank[0], - get(id,x), get(id,y), rep); + extend_sets(x, y); + detail::link_sets(&parent[0], &rank[0], get(id, x), get(id, y), rep); } - template - inline void - union_set(Element x, Element y) { - Element rx = find_set(x); - Element ry = find_set(y); - link(rx, ry); + template < class Element > inline void union_set(Element x, Element y) + { + Element rx = find_set(x); + Element ry = find_set(y); + link(rx, ry); } - template - inline Element find_set(Element x) { - return id_to_vertex[rep(&parent[0], get(id,x))]; + template < class Element > inline Element find_set(Element x) + { + return id_to_vertex[rep(&parent[0], get(id, x))]; } - template + template < class ElementIterator > inline std::size_t count_sets(ElementIterator first, ElementIterator last) { - std::size_t count = 0; - for ( ; first != last; ++first) - if (parent[*first] == *first) - ++count; - return count; + std::size_t count = 0; + for (; first != last; ++first) + if (parent[*first] == *first) + ++count; + return count; } - template + template < class ElementIterator > inline void normalize_sets(ElementIterator first, ElementIterator last) { - for (; first != last; ++first) - detail::normalize_node(&parent[0], *first); - } - - template + for (; first != last; ++first) + detail::normalize_node(&parent[0], *first); + } + + template < class ElementIterator > inline void compress_sets(ElementIterator first, ElementIterator last) { - for (; first != last; ++first) - detail::find_representative_with_full_compression(&parent[0], - *first); - } + for (; first != last; ++first) + detail::find_representative_with_full_compression( + &parent[0], *first); + } const ParentContainer& parents() { return parent; } - protected: - - template - inline void - extend_sets(Element x, Element y) +protected: + template < class Element > inline void extend_sets(Element x, Element y) { - Index needed = get(id,x) > get(id,y) ? get(id,x) + 1 : get(id,y) + 1; - if (needed > parent.size()) { - rank.insert(rank.end(), needed - rank.size(), 0); - for (Index k = parent.size(); k < needed; ++k) - parent.push_back(k); - } + Index needed + = get(id, x) > get(id, y) ? get(id, x) + 1 : get(id, y) + 1; + if (needed > parent.size()) + { + rank.insert(rank.end(), needed - rank.size(), 0); + for (Index k = parent.size(); k < needed; ++k) + parent.push_back(k); + } } ID id; @@ -213,7 +204,7 @@ namespace boost { RankContainer rank; ParentContainer parent; FindCompress rep; - }; +}; } // namespace boost diff --git a/include/boost/pending/fenced_priority_queue.hpp b/include/boost/pending/fenced_priority_queue.hpp index 4d4e3aff9..64d18692b 100644 --- a/include/boost/pending/fenced_priority_queue.hpp +++ b/include/boost/pending/fenced_priority_queue.hpp @@ -1,4 +1,4 @@ -// (C) Copyright Jeremiah Willcock 2004 +// (C) Copyright Jeremiah Willcock 2004 // Distributed under the Boost Software License, Version 1.0. (See // accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) @@ -30,18 +30,19 @@ // are then popped from the front of Q, and if that is empty the front // of PQ. -namespace boost { +namespace boost +{ - template, bool implicit_fence = true, - class Buffer = boost::queue > - class fenced_priority_queue { - public: +template < class T, class Compare = std::less< T >, bool implicit_fence = true, + class Buffer = boost::queue< T > > +class fenced_priority_queue +{ +public: typedef T value_type; typedef typename Buffer::size_type size_type; - fenced_priority_queue(const Compare _comp = Compare() ) - : PQ(_comp) {} - + fenced_priority_queue(const Compare _comp = Compare()) : PQ(_comp) {} + void push(const T& data); void pop(void); T& top(void); @@ -49,104 +50,111 @@ namespace boost { size_type size(void) const; bool empty(void) const; void fence(void); - - private: + +private: void fence(void) const; - //let them mutable to allow const version of top and the same - //semantics with non-constant version. Rich Lee - mutable std::priority_queue, Compare> PQ; + // let them mutable to allow const version of top and the same + // semantics with non-constant version. Rich Lee + mutable std::priority_queue< T, std::vector< T >, Compare > PQ; mutable Buffer Q; - }; - - template - inline void - fenced_priority_queue:: - push(const T &t) { +}; + +template < class T, class Compare, bool implicit_fence, class Buffer > +inline void fenced_priority_queue< T, Compare, implicit_fence, Buffer >::push( + const T& t) +{ // Push a new element after the last fence. This puts it into the // priority queue to be sorted with all other elements in its // partition. PQ.push(t); - } +} - template - inline void fenced_priority_queue:: - pop(void) { +template < class T, class Compare, bool implicit_fence, class Buffer > +inline void fenced_priority_queue< T, Compare, implicit_fence, Buffer >::pop( + void) +{ // Pop one element from the front of the queue. Removes from the // already-sorted part of the queue if it is non-empty, otherwise // removes from the new-element priority queue. Runs an implicit // "fence" operation if the implicit_fence template argument is // true. - if (implicit_fence) fence(); - if ( !Q.empty() ) - Q.pop(); + if (implicit_fence) + fence(); + if (!Q.empty()) + Q.pop(); else - PQ.pop(); - } + PQ.pop(); +} - template - inline T& fenced_priority_queue:: - top(void) { +template < class T, class Compare, bool implicit_fence, class Buffer > +inline T& fenced_priority_queue< T, Compare, implicit_fence, Buffer >::top(void) +{ // Get the top element from the queue. This element comes from Q if // possible, otherwise from PQ. Causes an implicit "fence" // operation if the implicit_fence template argument is true. - if (implicit_fence) fence(); - if ( !Q.empty() ) - return Q.top(); + if (implicit_fence) + fence(); + if (!Q.empty()) + return Q.top(); else - //std::priority_queue only have const version of top. Rich Lee - return const_cast(PQ.top()); - } - - template - inline const T& - fenced_priority_queue:: - top(void) const { - if (implicit_fence) fence(); - if ( !Q.empty() ) - return Q.top(); + // std::priority_queue only have const version of top. Rich Lee + return const_cast< T& >(PQ.top()); +} + +template < class T, class Compare, bool implicit_fence, class Buffer > +inline const T& +fenced_priority_queue< T, Compare, implicit_fence, Buffer >::top(void) const +{ + if (implicit_fence) + fence(); + if (!Q.empty()) + return Q.top(); else - return PQ.top(); - } + return PQ.top(); +} - template - inline typename fenced_priority_queue::size_type - fenced_priority_queue:: - size(void) const { +template < class T, class Compare, bool implicit_fence, class Buffer > +inline typename fenced_priority_queue< T, Compare, implicit_fence, + Buffer >::size_type +fenced_priority_queue< T, Compare, implicit_fence, Buffer >::size(void) const +{ // Returns the size of the queue (both parts together). return Q.size() + PQ.size(); - } +} - template - inline bool - fenced_priority_queue:: - empty(void) const { +template < class T, class Compare, bool implicit_fence, class Buffer > +inline bool fenced_priority_queue< T, Compare, implicit_fence, Buffer >::empty( + void) const +{ // Returns if the queue is empty, i.e. both parts are empty. return Q.empty() && PQ.empty(); - } - - template - inline void - fenced_priority_queue:: - fence(void) { +} + +template < class T, class Compare, bool implicit_fence, class Buffer > +inline void fenced_priority_queue< T, Compare, implicit_fence, Buffer >::fence( + void) +{ // Perform a fence operation. Remove elements from PQ in sorted // order and insert them in the back of Q. - while ( !PQ.empty() ) { - Q.push(PQ.top()); - PQ.pop(); + while (!PQ.empty()) + { + Q.push(PQ.top()); + PQ.pop(); } - } - template - inline void - fenced_priority_queue:: - fence(void) const { +} +template < class T, class Compare, bool implicit_fence, class Buffer > +inline void fenced_priority_queue< T, Compare, implicit_fence, Buffer >::fence( + void) const +{ // Perform a fence operation. Remove elements from PQ in sorted // order and insert them in the back of Q. - while ( !PQ.empty() ) { - Q.push(PQ.top()); - PQ.pop(); + while (!PQ.empty()) + { + Q.push(PQ.top()); + PQ.pop(); } - } +} -} +} #endif /* BOOST_FENCED_PRIORITY_QUEUE_HPP */ diff --git a/include/boost/pending/fibonacci_heap.hpp b/include/boost/pending/fibonacci_heap.hpp index a386e285e..3be462369 100644 --- a/include/boost/pending/fibonacci_heap.hpp +++ b/include/boost/pending/fibonacci_heap.hpp @@ -6,9 +6,9 @@ #define BOOST_FIBONACCI_HEAP_HPP #if defined(__sgi) && !defined(__GNUC__) -# include +#include #else -# include +#include #endif #include #include @@ -21,251 +21,300 @@ // in "The Stanford Graph Base", pages 475-482. // -namespace boost { - +namespace boost +{ -template , - class ID = identity_property_map> +template < class T, class Compare = std::less< T >, + class ID = identity_property_map > class fibonacci_heap { - typedef typename boost::property_traits::value_type size_type; - typedef T value_type; + typedef typename boost::property_traits< ID >::value_type size_type; + typedef T value_type; + protected: - typedef fibonacci_heap self; - typedef std::vector LinkVec; - typedef typename LinkVec::iterator LinkIter; -public: + typedef fibonacci_heap self; + typedef std::vector< size_type > LinkVec; + typedef typename LinkVec::iterator LinkIter; - fibonacci_heap(size_type n, - const Compare& cmp, - const ID& id = identity_property_map()) - : _key(n), _left(n), _right(n), _p(n), _mark(n), _degree(n), - _n(0), _root(n), _id(id), _compare(cmp), _child(n), +public: + fibonacci_heap( + size_type n, const Compare& cmp, const ID& id = identity_property_map()) + : _key(n) + , _left(n) + , _right(n) + , _p(n) + , _mark(n) + , _degree(n) + , _n(0) + , _root(n) + , _id(id) + , _compare(cmp) + , _child(n) + , #if defined(BOOST_MSVC) || defined(__ICL) // need a new macro? - new_roots(size_type(log(float(n))) + 5) { } + new_roots(size_type(log(float(n))) + 5) + { + } #else - new_roots(size_type(std::log(float(n))) + 5) { } + new_roots(size_type(std::log(float(n))) + 5) + { + } #endif - // 33 - void push(const T& d) { - ++_n; - size_type v = get(_id, d); - _key[v] = d; - _p[v] = nil(); - _degree[v] = 0; - _mark[v] = false; - _child[v] = nil(); - if (_root == nil()) { - _root = _left[v] = _right[v] = v; - //std::cout << "root added" << std::endl; - } else { - size_type u = _left[_root]; - _left[v] = u; - _right[v] = _root; - _left[_root] = _right[u] = v; - if (_compare(d, _key[_root])) - _root = v; - //std::cout << "non-root node added" << std::endl; + // 33 + void push(const T& d) + { + ++_n; + size_type v = get(_id, d); + _key[v] = d; + _p[v] = nil(); + _degree[v] = 0; + _mark[v] = false; + _child[v] = nil(); + if (_root == nil()) + { + _root = _left[v] = _right[v] = v; + // std::cout << "root added" << std::endl; + } + else + { + size_type u = _left[_root]; + _left[v] = u; + _right[v] = _root; + _left[_root] = _right[u] = v; + if (_compare(d, _key[_root])) + _root = v; + // std::cout << "non-root node added" << std::endl; + } } - } - T& top() { return _key[_root]; } - const T& top() const { return _key[_root]; } + T& top() { return _key[_root]; } + const T& top() const { return _key[_root]; } - // 38 - void pop() { - --_n; - int h = -1; - size_type v, w; - if (_root != nil()) { - if (_degree[_root] == 0) { - v = _right[_root]; - } else { - w = _child[_root]; - v = _right[w]; - _right[w] = _right[_root]; - for (w = v; w != _right[_root]; w = _right[w]) - _p[w] = nil(); - } - while (v != _root) { - w = _right[v]; - add_tree_to_new_roots(v, new_roots.begin(), h); - v = w; - } - rebuild_root_list(new_roots.begin(), h); + // 38 + void pop() + { + --_n; + int h = -1; + size_type v, w; + if (_root != nil()) + { + if (_degree[_root] == 0) + { + v = _right[_root]; + } + else + { + w = _child[_root]; + v = _right[w]; + _right[w] = _right[_root]; + for (w = v; w != _right[_root]; w = _right[w]) + _p[w] = nil(); + } + while (v != _root) + { + w = _right[v]; + add_tree_to_new_roots(v, new_roots.begin(), h); + v = w; + } + rebuild_root_list(new_roots.begin(), h); + } } - } - // 39 - inline void add_tree_to_new_roots(size_type v, - LinkIter new_roots, - int& h) - { - int r; - size_type u; - r = _degree[v]; - while (1) { - if (h < r) { - do { - ++h; - new_roots[h] = (h == r ? v : nil()); - } while (h < r); - break; - } - if (new_roots[r] == nil()) { - new_roots[r] = v; - break; - } - u = new_roots[r]; - new_roots[r] = nil(); - if (_compare(_key[u], _key[v])) { + // 39 + inline void add_tree_to_new_roots(size_type v, LinkIter new_roots, int& h) + { + int r; + size_type u; + r = _degree[v]; + while (1) + { + if (h < r) + { + do + { + ++h; + new_roots[h] = (h == r ? v : nil()); + } while (h < r); + break; + } + if (new_roots[r] == nil()) + { + new_roots[r] = v; + break; + } + u = new_roots[r]; + new_roots[r] = nil(); + if (_compare(_key[u], _key[v])) + { + _degree[v] = r; + _mark[v] = false; + std::swap(u, v); + } + make_child(u, v, r); + ++r; + } _degree[v] = r; _mark[v] = false; - std::swap(u, v); - } - make_child(u, v, r); - ++r; } - _degree[v] = r; - _mark[v] = false; - } - // 40 - void make_child(size_type u, size_type v, size_type r) { - if (r == 0) { - _child[v] = u; - _left[u] = u; - _right[u] = u; - } else { - size_type t = _child[v]; - _right[u] = _right[t]; - _left[u] = t; - _right[t] = u; - _left[_right[u]] = u; + // 40 + void make_child(size_type u, size_type v, size_type r) + { + if (r == 0) + { + _child[v] = u; + _left[u] = u; + _right[u] = u; + } + else + { + size_type t = _child[v]; + _right[u] = _right[t]; + _left[u] = t; + _right[t] = u; + _left[_right[u]] = u; + } + _p[u] = v; } - _p[u] = v; - } - // 41 - inline void rebuild_root_list(LinkIter new_roots, int& h) - { - size_type u, v, w; - if (h < 0) - _root = nil(); - else { - T d; - u = v = new_roots[h]; - d = _key[u]; - _root = u; - for (h--; h >= 0; --h) - if (new_roots[h] != nil()) { - w = new_roots[h]; - _left[w] = v; - _right[v] = w; - if (_compare(_key[w], d)) { - _root = w; - d = _key[w]; - } - v = w; + // 41 + inline void rebuild_root_list(LinkIter new_roots, int& h) + { + size_type u, v, w; + if (h < 0) + _root = nil(); + else + { + T d; + u = v = new_roots[h]; + d = _key[u]; + _root = u; + for (h--; h >= 0; --h) + if (new_roots[h] != nil()) + { + w = new_roots[h]; + _left[w] = v; + _right[v] = w; + if (_compare(_key[w], d)) + { + _root = w; + d = _key[w]; + } + v = w; + } + _right[v] = u; + _left[u] = v; } - _right[v] = u; - _left[u] = v; } - } - // 34 - void update(const T& d) { - size_type v = get(_id, d); - assert(!_compare(_key[v], d)); - _key[v] = d; - size_type p = _p[v]; - if (p == nil()) { - if (_compare(d, _key[_root])) - _root = v; - } else if (_compare(d, _key[p])) - while (1) { - size_type r = _degree[p]; - if (r >= 2) - remove_from_family(v, p); - insert_into_forest(v, d); - size_type pp = _p[p]; - if (pp == nil()) { - --_degree[p]; - break; + // 34 + void update(const T& d) + { + size_type v = get(_id, d); + assert(!_compare(_key[v], d)); + _key[v] = d; + size_type p = _p[v]; + if (p == nil()) + { + if (_compare(d, _key[_root])) + _root = v; } - if (_mark[p] == false) { - _mark[p] = true; - --_degree[p]; - break; - } else - --_degree[p]; - v = p; - p = pp; - } - } + else if (_compare(d, _key[p])) + while (1) + { + size_type r = _degree[p]; + if (r >= 2) + remove_from_family(v, p); + insert_into_forest(v, d); + size_type pp = _p[p]; + if (pp == nil()) + { + --_degree[p]; + break; + } + if (_mark[p] == false) + { + _mark[p] = true; + --_degree[p]; + break; + } + else + --_degree[p]; + v = p; + p = pp; + } + } - inline size_type size() const { return _n; } - inline bool empty() const { return _n == 0; } + inline size_type size() const { return _n; } + inline bool empty() const { return _n == 0; } - void print(std::ostream& os) { - if (_root != nil()) { - size_type i = _root; - do { - print_recur(i, os); - os << std::endl; - i = _right[i]; - } while (i != _root); + void print(std::ostream& os) + { + if (_root != nil()) + { + size_type i = _root; + do + { + print_recur(i, os); + os << std::endl; + i = _right[i]; + } while (i != _root); + } } - } protected: - // 35 - inline void remove_from_family(size_type v, size_type p) { - size_type u = _left[v]; - size_type w = _right[v]; - _right[u] = w; - _left[w] = u; - if (_child[p] == v) - _child[p] = w; - } - // 36 - inline void insert_into_forest(size_type v, const T& d) { - _p[v] = nil(); - size_type u = _left[_root]; - _left[v] = u; - _right[v] = _root; - _left[_root] = _right[u] = v; - if (_compare(d, _key[_root])) - _root = v; - } + // 35 + inline void remove_from_family(size_type v, size_type p) + { + size_type u = _left[v]; + size_type w = _right[v]; + _right[u] = w; + _left[w] = u; + if (_child[p] == v) + _child[p] = w; + } + // 36 + inline void insert_into_forest(size_type v, const T& d) + { + _p[v] = nil(); + size_type u = _left[_root]; + _left[v] = u; + _right[v] = _root; + _left[_root] = _right[u] = v; + if (_compare(d, _key[_root])) + _root = v; + } - void print_recur(size_type x, std::ostream& os) { - if (x != nil()) { - os << x; - if (_degree[x] > 0) { - os << "("; - size_type i = _child[x]; - do { - print_recur(i, os); os << " "; - i = _right[i]; - } while (i != _child[x]); - os << ")"; - } + void print_recur(size_type x, std::ostream& os) + { + if (x != nil()) + { + os << x; + if (_degree[x] > 0) + { + os << "("; + size_type i = _child[x]; + do + { + print_recur(i, os); + os << " "; + i = _right[i]; + } while (i != _child[x]); + os << ")"; + } + } } - } - - size_type nil() const { return _left.size(); } - std::vector _key; - LinkVec _left, _right, _p; - std::vector _mark; - LinkVec _degree; - size_type _n, _root; - ID _id; - Compare _compare; - LinkVec _child; - LinkVec new_roots; + size_type nil() const { return _left.size(); } + + std::vector< T > _key; + LinkVec _left, _right, _p; + std::vector< bool > _mark; + LinkVec _degree; + size_type _n, _root; + ID _id; + Compare _compare; + LinkVec _child; + LinkVec new_roots; }; } // namespace boost - #endif // BOOST_FIBONACCI_HEAP_HPP diff --git a/include/boost/pending/indirect_cmp.hpp b/include/boost/pending/indirect_cmp.hpp index 14ee5314a..76088ea4c 100644 --- a/include/boost/pending/indirect_cmp.hpp +++ b/include/boost/pending/indirect_cmp.hpp @@ -16,72 +16,77 @@ #include #include -namespace boost { +namespace boost +{ - //: indirect_cmp - // - // could also do this with compose_f_gx_hx, and the member binder... - // - //!category: functors - //!component: type - //!tparam: ReadablePropertyMap - a model of ReadablePropertyMap - //!definition: functor.h - template - class indirect_cmp { - public: - typedef typename boost::property_traits::value_type T; - typedef typename boost::property_traits::key_type K; +//: indirect_cmp +// +// could also do this with compose_f_gx_hx, and the member binder... +// +//! category: functors +//! component: type +//! tparam: ReadablePropertyMap - a model of ReadablePropertyMap +//! definition: functor.h +template < class ReadablePropertyMap, class Compare > class indirect_cmp +{ +public: + typedef + typename boost::property_traits< ReadablePropertyMap >::value_type T; + typedef typename boost::property_traits< ReadablePropertyMap >::key_type K; typedef K first_argument_type; typedef K second_argument_type; typedef bool result_type; - inline indirect_cmp(const ReadablePropertyMap& df, const Compare& c = Compare()) - : d(df), cmp(c) { } + inline indirect_cmp( + const ReadablePropertyMap& df, const Compare& c = Compare()) + : d(df), cmp(c) + { + } - template - inline bool - operator()(const A& u, const B& v) const { - const T& du = get(d, u); - const T& dv = get(d, v); - return cmp(du, dv); + template < class A, class B > + inline bool operator()(const A& u, const B& v) const + { + const T& du = get(d, u); + const T& dv = get(d, v); + return cmp(du, dv); } - protected: + +protected: ReadablePropertyMap d; Compare cmp; - }; +}; - template - indirect_cmp - make_indirect_cmp(const Compare& cmp, ReadablePropertyMap pmap) { - indirect_cmp p(pmap, cmp); +template < typename Compare, typename ReadablePropertyMap > +indirect_cmp< ReadablePropertyMap, Compare > make_indirect_cmp( + const Compare& cmp, ReadablePropertyMap pmap) +{ + indirect_cmp< ReadablePropertyMap, Compare > p(pmap, cmp); return p; - } +} - template - class indirect_pmap { - public: - typedef typename boost::property_traits::value_type T; - typedef typename boost::property_traits::key_type K; +template < class ReadablePropertyMap > class indirect_pmap +{ +public: + typedef + typename boost::property_traits< ReadablePropertyMap >::value_type T; + typedef typename boost::property_traits< ReadablePropertyMap >::key_type K; typedef K argument_type; typedef T result_type; - inline indirect_pmap(const ReadablePropertyMap& df) - : d(df) { } + inline indirect_pmap(const ReadablePropertyMap& df) : d(df) {} - inline T operator()(const K& u) const { - return get(d, u); - } - protected: + inline T operator()(const K& u) const { return get(d, u); } + +protected: ReadablePropertyMap d; - }; +}; - template - indirect_pmap - make_indirect_pmap(ReadablePropertyMap pmap) { - indirect_pmap f(pmap); +template < typename ReadablePropertyMap > +indirect_pmap< ReadablePropertyMap > make_indirect_pmap( + ReadablePropertyMap pmap) +{ + indirect_pmap< ReadablePropertyMap > f(pmap); return f; - } - +} } // namespace boost - #endif // GGCL_INDIRECT_CMP_HPP diff --git a/include/boost/pending/is_heap.hpp b/include/boost/pending/is_heap.hpp index b2e4b0069..697aa1ec8 100644 --- a/include/boost/pending/is_heap.hpp +++ b/include/boost/pending/is_heap.hpp @@ -9,53 +9,54 @@ //======================================================================= // #if __KCC -namespace std { - -template -bool __is_heap(RandomAccessIterator first, RandomAccessIterator last, - Distance*) +namespace std { - const Distance n = last - first; - Distance parent = 0; - for (Distance child = 1; child < n; ++child) { - if (first[parent] < first[child]) - return false; - if ((child & 1) == 0) - ++parent; - } - return true; +template < class RandomAccessIterator, class Distance > +bool __is_heap(RandomAccessIterator first, RandomAccessIterator last, Distance*) +{ + const Distance n = last - first; + + Distance parent = 0; + for (Distance child = 1; child < n; ++child) + { + if (first[parent] < first[child]) + return false; + if ((child & 1) == 0) + ++parent; + } + return true; } -template +template < class RandomAccessIterator > inline bool is_heap(RandomAccessIterator first, RandomAccessIterator last) { - return __is_heap(first, last, distance_type(first)); + return __is_heap(first, last, distance_type(first)); } - -template +template < class RandomAccessIterator, class Distance, + class StrictWeakOrdering > bool __is_heap(RandomAccessIterator first, RandomAccessIterator last, - StrictWeakOrdering comp, - Distance*) + StrictWeakOrdering comp, Distance*) { - const Distance n = last - first; - - Distance parent = 0; - for (Distance child = 1; child < n; ++child) { - if (comp(first[parent], first[child])) - return false; - if ((child & 1) == 0) - ++parent; - } - return true; + const Distance n = last - first; + + Distance parent = 0; + for (Distance child = 1; child < n; ++child) + { + if (comp(first[parent], first[child])) + return false; + if ((child & 1) == 0) + ++parent; + } + return true; } -template +template < class RandomAccessIterator, class StrictWeakOrdering > inline bool is_heap(RandomAccessIterator first, RandomAccessIterator last, - StrictWeakOrdering comp) + StrictWeakOrdering comp) { - return __is_heap(first, last, comp, distance_type(first)); + return __is_heap(first, last, comp, distance_type(first)); } } diff --git a/include/boost/pending/mutable_heap.hpp b/include/boost/pending/mutable_heap.hpp index bbc818819..b8f84fd33 100644 --- a/include/boost/pending/mutable_heap.hpp +++ b/include/boost/pending/mutable_heap.hpp @@ -30,35 +30,38 @@ */ -namespace boost { +namespace boost +{ - template - inline TreeNode up_heap(TreeNode x, const Compare& comp, ExternalData& edata) { +template < class TreeNode, class Compare, class ExternalData > +inline TreeNode up_heap(TreeNode x, const Compare& comp, ExternalData& edata) +{ while (x.has_parent() && comp(x, x.parent())) - x.swap(x.parent(), edata); + x.swap(x.parent(), edata); return x; - } +} - template - inline TreeNode down_heap(TreeNode x, const Compare& comp, ExternalData& edata) { - while (x.children().size() > 0) { - typename TreeNode::children_type::iterator - child_iter = std::min_element(x.children().begin(), - x.children().end(), - comp); - if (comp(*child_iter, x)) - x.swap(*child_iter, edata); - else - break; +template < class TreeNode, class Compare, class ExternalData > +inline TreeNode down_heap(TreeNode x, const Compare& comp, ExternalData& edata) +{ + while (x.children().size() > 0) + { + typename TreeNode::children_type::iterator child_iter + = std::min_element(x.children().begin(), x.children().end(), comp); + if (comp(*child_iter, x)) + x.swap(*child_iter, edata); + else + break; } return x; - } +} - template - inline void update_heap(TreeNode x, const Compare& comp, ExternalData& edata) { +template < class TreeNode, class Compare, class ExternalData > +inline void update_heap(TreeNode x, const Compare& comp, ExternalData& edata) +{ x = down_heap(x, comp, edata); (void)up_heap(x, comp, edata); - } +} } #endif diff --git a/include/boost/pending/mutable_queue.hpp b/include/boost/pending/mutable_queue.hpp index 82cfdd818..96c37d5e2 100644 --- a/include/boost/pending/mutable_queue.hpp +++ b/include/boost/pending/mutable_queue.hpp @@ -20,88 +20,97 @@ #include #include -namespace boost { - - // The mutable queue whose elements are indexed - // - // This adaptor provides a special kind of priority queue that has - // and update operation. This allows the ordering of the items to - // change. After the ordering criteria for item x changes, one must - // call the Q.update(x) - // - // In order to efficiently find x in the queue, a functor must be - // provided to map value_type to a unique ID, which the - // mutable_queue will then use to map to the location of the - // item. The ID's generated must be between 0 and N, where N is the - // value passed to the constructor of mutable_queue - - template , - class Comp = std::less, - class ID = identity_property_map > - class mutable_queue { - public: +namespace boost +{ + +// The mutable queue whose elements are indexed +// +// This adaptor provides a special kind of priority queue that has +// and update operation. This allows the ordering of the items to +// change. After the ordering criteria for item x changes, one must +// call the Q.update(x) +// +// In order to efficiently find x in the queue, a functor must be +// provided to map value_type to a unique ID, which the +// mutable_queue will then use to map to the location of the +// item. The ID's generated must be between 0 and N, where N is the +// value passed to the constructor of mutable_queue + +template < class IndexedType, + class RandomAccessContainer = std::vector< IndexedType >, + class Comp = std::less< typename RandomAccessContainer::value_type >, + class ID = identity_property_map > +class mutable_queue +{ +public: typedef IndexedType value_type; typedef typename RandomAccessContainer::size_type size_type; - protected: + +protected: typedef typename RandomAccessContainer::iterator iterator; #if !defined BOOST_NO_STD_ITERATOR_TRAITS - typedef array_binary_tree_node Node; + typedef array_binary_tree_node< iterator, ID > Node; #else - typedef array_binary_tree_node Node; + typedef array_binary_tree_node< iterator, value_type, ID > Node; #endif - typedef compare_array_node Compare; - typedef std::vector IndexArray; - public: + typedef compare_array_node< RandomAccessContainer, Comp > Compare; + typedef std::vector< size_type > IndexArray; + +public: typedef Compare value_compare; typedef ID id_generator; mutable_queue(size_type n, const Comp& x, const ID& _id) - : index_array(n), comp(x), id(_id) { - c.reserve(n); + : index_array(n), comp(x), id(_id) + { + c.reserve(n); } - template - mutable_queue(ForwardIterator first, ForwardIterator last, - const Comp& x, const ID& _id) - : index_array(std::distance(first, last)), comp(x), id(_id) + template < class ForwardIterator > + mutable_queue(ForwardIterator first, ForwardIterator last, const Comp& x, + const ID& _id) + : index_array(std::distance(first, last)), comp(x), id(_id) { - while( first != last ) { - push(*first); - ++first; - } + while (first != last) + { + push(*first); + ++first; + } } bool empty() const { return c.empty(); } - void pop() { - value_type tmp = c.back(); - c.back() = c.front(); - c.front() = tmp; - - size_type id_f = get(id, c.back()); - size_type id_b = get(id, tmp); - size_type i = index_array[ id_b ]; - index_array[ id_b ] = index_array[ id_f ]; - index_array[ id_f ] = i; - - c.pop_back(); - Node node(c.begin(), c.end(), c.begin(), id); - down_heap(node, comp, index_array); + void pop() + { + value_type tmp = c.back(); + c.back() = c.front(); + c.front() = tmp; + + size_type id_f = get(id, c.back()); + size_type id_b = get(id, tmp); + size_type i = index_array[id_b]; + index_array[id_b] = index_array[id_f]; + index_array[id_f] = i; + + c.pop_back(); + Node node(c.begin(), c.end(), c.begin(), id); + down_heap(node, comp, index_array); } - void push(const IndexedType& x) { - c.push_back(x); - /*set index-array*/ - index_array[ get(id, x) ] = c.size()-1; - Node node(c.begin(), c.end(), c.end() - 1, id); - up_heap(node, comp, index_array); + void push(const IndexedType& x) + { + c.push_back(x); + /*set index-array*/ + index_array[get(id, x)] = c.size() - 1; + Node node(c.begin(), c.end(), c.end() - 1, id); + up_heap(node, comp, index_array); } - void update(const IndexedType& x) { - size_type current_pos = index_array[ get(id, x) ]; - c[current_pos] = x; + void update(const IndexedType& x) + { + size_type current_pos = index_array[get(id, x)]; + c[current_pos] = x; - Node node(c.begin(), c.end(), c.begin()+current_pos, id); - update_heap(node, comp, index_array); + Node node(c.begin(), c.end(), c.begin() + current_pos, id); + update_heap(node, comp, index_array); } value_type& front() { return c.front(); } @@ -122,13 +131,12 @@ namespace boost { } #endif - protected: +protected: IndexArray index_array; Compare comp; RandomAccessContainer c; ID id; - }; - +}; } diff --git a/include/boost/pending/property.hpp b/include/boost/pending/property.hpp index e63a2d203..8e98e84ea 100644 --- a/include/boost/pending/property.hpp +++ b/include/boost/pending/property.hpp @@ -13,256 +13,365 @@ #include #include -namespace boost { +namespace boost +{ - struct no_property {}; +struct no_property +{ +}; - template - struct property { +template < class Tag, class T, class Base = no_property > struct property +{ typedef Base next_type; typedef Tag tag_type; typedef T value_type; - property(const T& v = T()) : m_value(v) { } - property(const T& v, const Base& b) : m_value(v), m_base(b) { } + property(const T& v = T()) : m_value(v) {} + property(const T& v, const Base& b) : m_value(v), m_base(b) {} // copy constructor and assignment operator will be generated by compiler T m_value; Base m_base; - }; +}; - // Kinds of properties - namespace graph_introspect_detail { +// Kinds of properties +namespace graph_introspect_detail +{ BOOST_MPL_HAS_XXX_TRAIT_DEF(kind) - template struct get_kind {typedef void type;}; - template struct get_kind {typedef typename T::kind type;}; - } - - // Having a default is to make this trait work for any type, not just valid - // properties, to work around VC++ <= 10 bugs related to SFINAE in - // compressed_sparse_row_graph's get functions and similar - template - struct property_kind: - graph_introspect_detail::get_kind::value> - {}; - - // Some standard properties defined independently of Boost.Graph: - enum vertex_all_t {vertex_all}; - enum edge_all_t {edge_all}; - enum graph_all_t {graph_all}; - enum vertex_bundle_t {vertex_bundle}; - enum edge_bundle_t {edge_bundle}; - enum graph_bundle_t {graph_bundle}; - - // Code to look up one property in a property list: - template - struct lookup_one_property_internal {BOOST_STATIC_CONSTANT(bool, found = false); typedef void type;}; - - // Special-case properties (vertex_all, edge_all, graph_all) -#define BGL_ALL_PROP(tag) \ - template \ - struct lookup_one_property_internal { \ - BOOST_STATIC_CONSTANT(bool, found = true); \ - typedef T type; \ - static T& lookup(T& x, tag) {return x;} \ - static const T& lookup(const T& x, tag) {return x;} \ - }; \ - template \ - struct lookup_one_property_internal, tag> { /* Avoid ambiguity */ \ - BOOST_STATIC_CONSTANT(bool, found = true); \ - typedef property type; \ - static type& lookup(type& x, tag) {return x;} \ - static const type& lookup(const type& x, tag) {return x;} \ - }; - - BGL_ALL_PROP(vertex_all_t) - BGL_ALL_PROP(edge_all_t) - BGL_ALL_PROP(graph_all_t) + template < typename T, bool Cond > struct get_kind + { + typedef void type; + }; + template < typename T > struct get_kind< T, true > + { + typedef typename T::kind type; + }; +} + +// Having a default is to make this trait work for any type, not just valid +// properties, to work around VC++ <= 10 bugs related to SFINAE in +// compressed_sparse_row_graph's get functions and similar +template < class PropertyTag > +struct property_kind +: graph_introspect_detail::get_kind< PropertyTag, + graph_introspect_detail::has_kind< PropertyTag >::value > +{ +}; + +// Some standard properties defined independently of Boost.Graph: +enum vertex_all_t +{ + vertex_all +}; +enum edge_all_t +{ + edge_all +}; +enum graph_all_t +{ + graph_all +}; +enum vertex_bundle_t +{ + vertex_bundle +}; +enum edge_bundle_t +{ + edge_bundle +}; +enum graph_bundle_t +{ + graph_bundle +}; + +// Code to look up one property in a property list: +template < typename PList, typename PropName, typename Enable = void > +struct lookup_one_property_internal +{ + BOOST_STATIC_CONSTANT(bool, found = false); + typedef void type; +}; + +// Special-case properties (vertex_all, edge_all, graph_all) +#define BGL_ALL_PROP(tag) \ + template < typename T > struct lookup_one_property_internal< T, tag > \ + { \ + BOOST_STATIC_CONSTANT(bool, found = true); \ + typedef T type; \ + static T& lookup(T& x, tag) { return x; } \ + static const T& lookup(const T& x, tag) { return x; } \ + }; \ + template < typename Tag, typename T, typename Base > \ + struct lookup_one_property_internal< property< Tag, T, Base >, tag > \ + { /* Avoid ambiguity */ \ + BOOST_STATIC_CONSTANT(bool, found = true); \ + typedef property< Tag, T, Base > type; \ + static type& lookup(type& x, tag) { return x; } \ + static const type& lookup(const type& x, tag) { return x; } \ + }; + +BGL_ALL_PROP(vertex_all_t) +BGL_ALL_PROP(edge_all_t) +BGL_ALL_PROP(graph_all_t) #undef BGL_ALL_PROP - // *_bundled; these need to be macros rather than inheritance to resolve ambiguities - #define BGL_DO_ONE_BUNDLE_TYPE(kind) \ - template \ - struct lookup_one_property_internal { \ - BOOST_STATIC_CONSTANT(bool, found = true); \ - typedef T type; \ - static T& lookup(T& x, BOOST_JOIN(kind, _bundle_t)) {return x;} \ - static const T& lookup(const T& x, BOOST_JOIN(kind, _bundle_t)) {return x;} \ - }; \ - \ - template \ - struct lookup_one_property_internal, BOOST_JOIN(kind, _bundle_t)>: lookup_one_property_internal { \ - private: \ - typedef lookup_one_property_internal base_type; \ - public: \ - template \ - static typename lazy_enable_if_c<(base_type::found && (is_same::value)), \ - add_reference >::type \ - lookup(property& p, BundleTag) {return base_type::lookup(p.m_base, BOOST_JOIN(kind, _bundle_t)());} \ - template \ - static typename lazy_enable_if_c<(base_type::found && (is_same::value)), \ - add_reference >::type \ - lookup(const property& p, BundleTag) {return base_type::lookup(p.m_base, BOOST_JOIN(kind, _bundle_t)());} \ - }; \ - - BGL_DO_ONE_BUNDLE_TYPE(vertex) - BGL_DO_ONE_BUNDLE_TYPE(edge) - BGL_DO_ONE_BUNDLE_TYPE(graph) +// *_bundled; these need to be macros rather than inheritance to resolve +// ambiguities +#define BGL_DO_ONE_BUNDLE_TYPE(kind) \ + template < typename T > \ + struct lookup_one_property_internal< T, BOOST_JOIN(kind, _bundle_t) > \ + { \ + BOOST_STATIC_CONSTANT(bool, found = true); \ + typedef T type; \ + static T& lookup(T& x, BOOST_JOIN(kind, _bundle_t)) { return x; } \ + static const T& lookup(const T& x, BOOST_JOIN(kind, _bundle_t)) \ + { \ + return x; \ + } \ + }; \ + \ + template < typename Tag, typename T, typename Base > \ + struct lookup_one_property_internal< property< Tag, T, Base >, \ + BOOST_JOIN(kind, _bundle_t) > \ + : lookup_one_property_internal< Base, BOOST_JOIN(kind, _bundle_t) > \ + { \ + private: \ + typedef lookup_one_property_internal< Base, \ + BOOST_JOIN(kind, _bundle_t) > \ + base_type; \ + \ + public: \ + template < typename BundleTag > \ + static typename lazy_enable_if_c< \ + (base_type::found \ + && (is_same< BundleTag, \ + BOOST_JOIN(kind, _bundle_t) >::value)), \ + add_reference< typename base_type::type > >::type \ + lookup(property< Tag, T, Base >& p, BundleTag) \ + { \ + return base_type::lookup(p.m_base, BOOST_JOIN(kind, _bundle_t)()); \ + } \ + template < typename BundleTag > \ + static typename lazy_enable_if_c< \ + (base_type::found \ + && (is_same< BundleTag, \ + BOOST_JOIN(kind, _bundle_t) >::value)), \ + add_reference< const typename base_type::type > >::type \ + lookup(const property< Tag, T, Base >& p, BundleTag) \ + { \ + return base_type::lookup(p.m_base, BOOST_JOIN(kind, _bundle_t)()); \ + } \ + }; + +BGL_DO_ONE_BUNDLE_TYPE(vertex) +BGL_DO_ONE_BUNDLE_TYPE(edge) +BGL_DO_ONE_BUNDLE_TYPE(graph) #undef BGL_DO_ONE_BUNDLE_TYPE - // Normal old-style properties; second case also handles chaining of bundled property accesses - template - struct lookup_one_property_internal, Tag> { +// Normal old-style properties; second case also handles chaining of bundled +// property accesses +template < typename Tag, typename T, typename Base > +struct lookup_one_property_internal< boost::property< Tag, T, Base >, Tag > +{ BOOST_STATIC_CONSTANT(bool, found = true); - typedef property prop; + typedef property< Tag, T, Base > prop; typedef T type; - template - static typename enable_if, T&>::type - lookup(U& prop, const Tag&) {return prop.m_value;} - template - static typename enable_if, const T&>::type - lookup(const U& prop, const Tag&) {return prop.m_value;} - }; - - template - struct lookup_one_property_internal, PropName>: lookup_one_property_internal { - private: - typedef lookup_one_property_internal base_type; - public: - template - static typename lazy_enable_if >, - add_reference >::type - lookup(PL& prop, const PropName& tag) { - return base_type::lookup(prop.m_base, tag); + template < typename U > + static typename enable_if< is_same< prop, U >, T& >::type lookup( + U& prop, const Tag&) + { + return prop.m_value; + } + template < typename U > + static typename enable_if< is_same< prop, U >, const T& >::type lookup( + const U& prop, const Tag&) + { + return prop.m_value; } - template - static typename lazy_enable_if >, - add_reference >::type - lookup(const PL& prop, const PropName& tag) { - return base_type::lookup(prop.m_base, tag); +}; + +template < typename Tag, typename T, typename Base, typename PropName > +struct lookup_one_property_internal< boost::property< Tag, T, Base >, PropName > +: lookup_one_property_internal< Base, PropName > +{ +private: + typedef lookup_one_property_internal< Base, PropName > base_type; + +public: + template < typename PL > + static + typename lazy_enable_if< is_same< PL, boost::property< Tag, T, Base > >, + add_reference< typename base_type::type > >::type + lookup(PL& prop, const PropName& tag) + { + return base_type::lookup(prop.m_base, tag); } - }; + template < typename PL > + static + typename lazy_enable_if< is_same< PL, boost::property< Tag, T, Base > >, + add_reference< const typename base_type::type > >::type + lookup(const PL& prop, const PropName& tag) + { + return base_type::lookup(prop.m_base, tag); + } +}; - // Pointer-to-member access to bundled properties +// Pointer-to-member access to bundled properties #ifndef BOOST_GRAPH_NO_BUNDLED_PROPERTIES - template - struct lookup_one_property_internal >::type> { +template < typename T, typename TMaybeBase, typename R > +struct lookup_one_property_internal< T, R TMaybeBase::*, + typename enable_if< is_base_of< TMaybeBase, T > >::type > +{ BOOST_STATIC_CONSTANT(bool, found = true); typedef R type; - static R& lookup(T& x, R TMaybeBase::*ptr) {return x.*ptr;} - static const R& lookup(const T& x, R TMaybeBase::*ptr) {return x.*ptr;} - }; + static R& lookup(T& x, R TMaybeBase::*ptr) { return x.*ptr; } + static const R& lookup(const T& x, R TMaybeBase::*ptr) { return x.*ptr; } +}; #endif - // Version of above handling const property lists properly - template - struct lookup_one_property: lookup_one_property_internal {}; - - template - struct lookup_one_property { - BOOST_STATIC_CONSTANT(bool, found = (lookup_one_property_internal::found)); - typedef const typename lookup_one_property_internal::type type; - template - static typename lazy_enable_if, - add_reference::type> >::type - lookup(const U& p, Tag tag) { - return lookup_one_property_internal::lookup(p, tag); +// Version of above handling const property lists properly +template < typename T, typename Tag > +struct lookup_one_property : lookup_one_property_internal< T, Tag > +{ +}; + +template < typename T, typename Tag > struct lookup_one_property< const T, Tag > +{ + BOOST_STATIC_CONSTANT( + bool, found = (lookup_one_property_internal< T, Tag >::found)); + typedef const typename lookup_one_property_internal< T, Tag >::type type; + template < typename U > + static typename lazy_enable_if< is_same< T, U >, + add_reference< const typename lookup_one_property_internal< T, + Tag >::type > >::type + lookup(const U& p, Tag tag) + { + return lookup_one_property_internal< T, Tag >::lookup(p, tag); } - }; +}; - // The BGL properties specialize property_kind and - // property_num, and use enum's for the Property type (see - // graph/properties.hpp), but the user may want to use a class - // instead with a nested kind type and num. Also, we may want to - // switch BGL back to using class types for properties at some point. +// The BGL properties specialize property_kind and +// property_num, and use enum's for the Property type (see +// graph/properties.hpp), but the user may want to use a class +// instead with a nested kind type and num. Also, we may want to +// switch BGL back to using class types for properties at some point. - template - struct has_property : boost::mpl::true_ {}; - template <> - struct has_property : boost::mpl::false_ {}; +template < class P > struct has_property : boost::mpl::true_ +{ +}; +template <> struct has_property< no_property > : boost::mpl::false_ +{ +}; } // namespace boost #include -namespace boost { +namespace boost +{ - template - struct property_value: lookup_one_property {}; +template < class PropertyList, class Tag > +struct property_value : lookup_one_property< PropertyList, Tag > +{ +}; - template - inline typename lookup_one_property::type& - get_property_value(PropertyList& p, Tag tag) { - return lookup_one_property::lookup(p, tag); - } +template < class PropertyList, class Tag > +inline typename lookup_one_property< PropertyList, Tag >::type& +get_property_value(PropertyList& p, Tag tag) +{ + return lookup_one_property< PropertyList, Tag >::lookup(p, tag); +} - template - inline const typename lookup_one_property::type& - get_property_value(const PropertyList& p, Tag tag) { - return lookup_one_property::lookup(p, tag); - } +template < class PropertyList, class Tag > +inline const typename lookup_one_property< PropertyList, Tag >::type& +get_property_value(const PropertyList& p, Tag tag) +{ + return lookup_one_property< PropertyList, Tag >::lookup(p, tag); +} - namespace detail { +namespace detail +{ - /** This trait returns true if T is no_property. */ - template - struct is_no_property - : mpl::bool_::value> - { }; + /** This trait returns true if T is no_property. */ + template < typename T > + struct is_no_property : mpl::bool_< is_same< T, no_property >::value > + { + }; - template - class lookup_one_property_f; + template < typename PList, typename Tag > class lookup_one_property_f; - template struct lookup_one_property_f_result; + template < typename PList, typename Tag, typename F > + struct lookup_one_property_f_result; - template - struct lookup_one_property_f_result(PList)> { - typedef typename lookup_one_property::type type; + template < typename PList, typename Tag > + struct lookup_one_property_f_result< PList, Tag, + const lookup_one_property_f< PList, Tag >(PList) > + { + typedef typename lookup_one_property< PList, Tag >::type type; }; - template - struct lookup_one_property_f_result(PList&)> { - typedef typename lookup_one_property::type& type; + template < typename PList, typename Tag > + struct lookup_one_property_f_result< PList, Tag, + const lookup_one_property_f< PList, Tag >(PList&) > + { + typedef typename lookup_one_property< PList, Tag >::type& type; }; - template - struct lookup_one_property_f_result(const PList&)> { - typedef const typename lookup_one_property::type& type; + template < typename PList, typename Tag > + struct lookup_one_property_f_result< PList, Tag, + const lookup_one_property_f< PList, Tag >(const PList&) > + { + typedef const typename lookup_one_property< PList, Tag >::type& type; }; - template - class lookup_one_property_f { - Tag tag; - public: - lookup_one_property_f(Tag tag): tag(tag) {} - template struct result: lookup_one_property_f_result {}; - - typename lookup_one_property_f_result::type - operator()(PList& pl) const { - return lookup_one_property::lookup(pl, tag); - } + template < typename PList, typename Tag > class lookup_one_property_f + { + Tag tag; + + public: + lookup_one_property_f(Tag tag) : tag(tag) {} + template < typename F > + struct result : lookup_one_property_f_result< PList, Tag, F > + { + }; + + typename lookup_one_property_f_result< PList, Tag, + const lookup_one_property_f(PList&) >::type + operator()(PList& pl) const + { + return lookup_one_property< PList, Tag >::lookup(pl, tag); + } }; } // namespace detail -namespace detail { - // Stuff for directed_graph and undirected_graph to skip over their first - // vertex_index and edge_index properties when providing vertex_all and - // edge_all; make sure you know the exact structure of your properties if you - // use there. - struct remove_first_property { - template - struct result { - typedef typename boost::function_traits::arg1_type a1; - typedef typename boost::remove_reference::type non_ref; - typedef typename non_ref::next_type nx; - typedef typename boost::mpl::if_, boost::add_const, nx>::type with_const; - typedef typename boost::add_reference::type type; +namespace detail +{ + // Stuff for directed_graph and undirected_graph to skip over their first + // vertex_index and edge_index properties when providing vertex_all and + // edge_all; make sure you know the exact structure of your properties if + // you use there. + struct remove_first_property + { + template < typename F > struct result + { + typedef typename boost::function_traits< F >::arg1_type a1; + typedef typename boost::remove_reference< a1 >::type non_ref; + typedef typename non_ref::next_type nx; + typedef typename boost::mpl::if_< boost::is_const< non_ref >, + boost::add_const< nx >, nx >::type with_const; + typedef typename boost::add_reference< with_const >::type type; + }; + template < typename Prop > + typename Prop::next_type& operator()(Prop& p) const + { + return p.m_base; + } + template < typename Prop > + const typename Prop::next_type& operator()(const Prop& p) const + { + return p.m_base; + } }; - template - typename Prop::next_type& operator()(Prop& p) const {return p.m_base;} - template - const typename Prop::next_type& operator()(const Prop& p) const {return p.m_base;} - }; } } // namesapce boost diff --git a/include/boost/pending/property_serialize.hpp b/include/boost/pending/property_serialize.hpp index 06cf2927a..cbdc163a4 100644 --- a/include/boost/pending/property_serialize.hpp +++ b/include/boost/pending/property_serialize.hpp @@ -11,18 +11,20 @@ #include #include -namespace boost { - template - inline void serialize(Archive&, no_property&, const unsigned int) { } - - template - void - serialize(Archive& ar, property& prop, - const unsigned int /*version*/) - { - ar & serialization::make_nvp( "property_value" , prop.m_value ); - ar & serialization::make_nvp( "property_base" , prop.m_base ); - } +namespace boost +{ +template < class Archive > +inline void serialize(Archive&, no_property&, const unsigned int) +{ +} + +template < class Archive, class Tag, class T, class Base > +void serialize( + Archive& ar, property< Tag, T, Base >& prop, const unsigned int /*version*/) +{ + ar& serialization::make_nvp("property_value", prop.m_value); + ar& serialization::make_nvp("property_base", prop.m_base); +} #ifdef BOOST_GRAPH_USE_MPI @@ -40,46 +42,58 @@ namespace boost { // of boost::adjacency_list in the non-MPI case, and could potentially // break software that reads files serialized with an older release. - namespace mpi { +namespace mpi +{ // forward declaration, to avoid including mpi - template struct is_mpi_datatype; - - template - struct is_mpi_datatype > - : mpl::and_, - is_mpi_datatype > { }; - } - - namespace serialization { - template - struct is_bitwise_serializable > - : mpl::and_, - is_bitwise_serializable > { }; - - template - struct implementation_level > - : mpl::int_ {} ; - - template - struct tracking_level > - : mpl::int_ {} ; - - } + template < typename T > struct is_mpi_datatype; + + template < typename Tag, typename T, typename Base > + struct is_mpi_datatype< property< Tag, T, Base > > + : mpl::and_< is_mpi_datatype< T >, is_mpi_datatype< Base > > + { + }; +} + +namespace serialization +{ + template < typename Tag, typename T, typename Base > + struct is_bitwise_serializable< property< Tag, T, Base > > + : mpl::and_< is_bitwise_serializable< T >, is_bitwise_serializable< Base > > + { + }; + + template < typename Tag, typename T, typename Base > + struct implementation_level< property< Tag, T, Base > > + : mpl::int_< object_serializable > + { + }; + + template < typename Tag, typename T, typename Base > + struct tracking_level< property< Tag, T, Base > > : mpl::int_< track_never > + { + }; + +} #endif // BOOST_GRAPH_USE_MPI - + } // end namespace boost #ifdef BOOST_GRAPH_USE_MPI -namespace boost { namespace mpi { - template<> - struct is_mpi_datatype : mpl::true_ { }; +namespace boost +{ +namespace mpi +{ + template <> struct is_mpi_datatype< boost::no_property > : mpl::true_ + { + }; -} } // end namespace boost::mpi +} +} // end namespace boost::mpi BOOST_IS_BITWISE_SERIALIZABLE(boost::no_property) -BOOST_CLASS_IMPLEMENTATION(boost::no_property,object_serializable) -BOOST_CLASS_TRACKING(boost::no_property,track_never) +BOOST_CLASS_IMPLEMENTATION(boost::no_property, object_serializable) +BOOST_CLASS_TRACKING(boost::no_property, track_never) #endif // BOOST_GRAPH_USE_MPI #endif // BOOST_PROPERTY_SERIALIZE_HPP diff --git a/include/boost/pending/queue.hpp b/include/boost/pending/queue.hpp index f5f5b6336..bf4879b86 100644 --- a/include/boost/pending/queue.hpp +++ b/include/boost/pending/queue.hpp @@ -1,4 +1,4 @@ -// (C) Copyright Jeremy Siek 2004 +// (C) Copyright Jeremy Siek 2004 // Distributed under the Boost Software License, Version 1.0. (See // accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) @@ -9,109 +9,109 @@ #include #include -namespace boost { - -template > -class queue; +namespace boost +{ -template -inline bool operator==(const queue<_Tp, _Seq>&, const queue<_Tp, _Seq>&); +template < class _Tp, class _Sequence = std::deque< _Tp > > class queue; -template -inline bool operator<(const queue<_Tp, _Seq>&, const queue<_Tp, _Seq>&); +template < class _Tp, class _Seq > +inline bool operator==(const queue< _Tp, _Seq >&, const queue< _Tp, _Seq >&); +template < class _Tp, class _Seq > +inline bool operator<(const queue< _Tp, _Seq >&, const queue< _Tp, _Seq >&); -template -class queue { +template < class _Tp, class _Sequence > class queue +{ #ifndef BOOST_NO_MEMBER_TEMPLATE_FRIENDS - template - friend bool operator== (const queue<_Tp1, _Seq1>&, - const queue<_Tp1, _Seq1>&); - template - friend bool operator< (const queue<_Tp1, _Seq1>&, - const queue<_Tp1, _Seq1>&); + template < class _Tp1, class _Seq1 > + friend bool operator==( + const queue< _Tp1, _Seq1 >&, const queue< _Tp1, _Seq1 >&); + template < class _Tp1, class _Seq1 > + friend bool operator<( + const queue< _Tp1, _Seq1 >&, const queue< _Tp1, _Seq1 >&); #endif public: - typedef typename _Sequence::value_type value_type; - typedef typename _Sequence::size_type size_type; - typedef _Sequence container_type; + typedef typename _Sequence::value_type value_type; + typedef typename _Sequence::size_type size_type; + typedef _Sequence container_type; - typedef typename _Sequence::reference reference; - typedef typename _Sequence::const_reference const_reference; + typedef typename _Sequence::reference reference; + typedef typename _Sequence::const_reference const_reference; #ifndef BOOST_NO_MEMBER_TEMPLATE_FRIENDS protected: #endif - _Sequence c; + _Sequence c; + public: - queue() : c() {} - explicit queue(const _Sequence& __c) : c(__c) {} - - bool empty() const { return c.empty(); } - size_type size() const { return c.size(); } - reference front() { return c.front(); } - const_reference front() const { return c.front(); } - reference top() { return c.front(); } - const_reference top() const { return c.front(); } - reference back() { return c.back(); } - const_reference back() const { return c.back(); } - void push(const value_type& __x) { c.push_back(__x); } - void pop() { c.pop_front(); } - - void swap(queue& other) - { - using std::swap; - swap(c, other.c); - } + queue() : c() {} + explicit queue(const _Sequence& __c) : c(__c) {} + + bool empty() const { return c.empty(); } + size_type size() const { return c.size(); } + reference front() { return c.front(); } + const_reference front() const { return c.front(); } + reference top() { return c.front(); } + const_reference top() const { return c.front(); } + reference back() { return c.back(); } + const_reference back() const { return c.back(); } + void push(const value_type& __x) { c.push_back(__x); } + void pop() { c.pop_front(); } + + void swap(queue& other) + { + using std::swap; + swap(c, other.c); + } }; -template -bool -operator==(const queue<_Tp, _Sequence>& __x, const queue<_Tp, _Sequence>& __y) +template < class _Tp, class _Sequence > +bool operator==( + const queue< _Tp, _Sequence >& __x, const queue< _Tp, _Sequence >& __y) { - return __x.c == __y.c; + return __x.c == __y.c; } -template -bool -operator<(const queue<_Tp, _Sequence>& __x, const queue<_Tp, _Sequence>& __y) +template < class _Tp, class _Sequence > +bool operator<( + const queue< _Tp, _Sequence >& __x, const queue< _Tp, _Sequence >& __y) { - return __x.c < __y.c; + return __x.c < __y.c; } -template -bool -operator!=(const queue<_Tp, _Sequence>& __x, const queue<_Tp, _Sequence>& __y) +template < class _Tp, class _Sequence > +bool operator!=( + const queue< _Tp, _Sequence >& __x, const queue< _Tp, _Sequence >& __y) { - return !(__x == __y); + return !(__x == __y); } -template -bool -operator>(const queue<_Tp, _Sequence>& __x, const queue<_Tp, _Sequence>& __y) +template < class _Tp, class _Sequence > +bool operator>( + const queue< _Tp, _Sequence >& __x, const queue< _Tp, _Sequence >& __y) { - return __y < __x; + return __y < __x; } -template -bool -operator<=(const queue<_Tp, _Sequence>& __x, const queue<_Tp, _Sequence>& __y) +template < class _Tp, class _Sequence > +bool operator<=( + const queue< _Tp, _Sequence >& __x, const queue< _Tp, _Sequence >& __y) { - return !(__y < __x); + return !(__y < __x); } -template -bool -operator>=(const queue<_Tp, _Sequence>& __x, const queue<_Tp, _Sequence>& __y) +template < class _Tp, class _Sequence > +bool operator>=( + const queue< _Tp, _Sequence >& __x, const queue< _Tp, _Sequence >& __y) { - return !(__x < __y); + return !(__x < __y); } -template -inline void -swap(queue<_Tp, _Sequence>& __x, queue<_Tp, _Sequence>& __y) -{ __x.swap(__y); } +template < class _Tp, class _Sequence > +inline void swap(queue< _Tp, _Sequence >& __x, queue< _Tp, _Sequence >& __y) +{ + __x.swap(__y); +} } /* namespace boost */ diff --git a/include/boost/pending/relaxed_heap.hpp b/include/boost/pending/relaxed_heap.hpp index f7523eb1b..c9e914706 100644 --- a/include/boost/pending/relaxed_heap.hpp +++ b/include/boost/pending/relaxed_heap.hpp @@ -6,7 +6,8 @@ // Authors: Douglas Gregor // Andrew Lumsdaine -#warning "Use of relaxed_heap is depreciated; please use the standard heap functions." +#warning \ + "Use of relaxed_heap is depreciated; please use the standard heap functions." #ifndef BOOST_RELAXED_HEAP_HEADER #define BOOST_RELAXED_HEAP_HEADER @@ -21,630 +22,723 @@ BOOST_HEADER_DEPRECATED("the standard heap functions") #include #ifdef BOOST_RELAXED_HEAP_DEBUG -# include +#include #endif // BOOST_RELAXED_HEAP_DEBUG #if defined(BOOST_MSVC) -# pragma warning(push) -# pragma warning(disable:4355) // complaint about using 'this' to -#endif // initialize a member +#pragma warning(push) +#pragma warning(disable : 4355) // complaint about using 'this' to +#endif // initialize a member -namespace boost { +namespace boost +{ -template, - typename ID = identity_property_map> +template < typename IndexedType, typename Compare = std::less< IndexedType >, + typename ID = identity_property_map > class relaxed_heap { - struct group; + struct group; - typedef relaxed_heap self_type; - typedef std::size_t rank_type; + typedef relaxed_heap self_type; + typedef std::size_t rank_type; public: - typedef IndexedType value_type; - typedef rank_type size_type; + typedef IndexedType value_type; + typedef rank_type size_type; private: - /** - * The kind of key that a group has. The actual values are discussed - * in-depth in the documentation of the @c kind field of the @c group - * structure. Note that the order of the enumerators *IS* important - * and must not be changed. - */ - enum group_key_kind { smallest_key, stored_key, largest_key }; - - struct group { - explicit group(group_key_kind kind = largest_key) - : kind(kind), parent(this), rank(0) { } - - /** The value associated with this group. This value is only valid - * when @c kind!=largest_key (which indicates a deleted - * element). Note that the use of boost::optional increases the - * memory requirements slightly but does not result in extraneous - * memory allocations or deallocations. The optional could be - * eliminated when @c value_type is a model of - * DefaultConstructible. - */ - ::boost::optional value; - /** - * The kind of key stored at this group. This may be @c - * smallest_key, which indicates that the key is infinitely small; - * @c largest_key, which indicates that the key is infinitely - * large; or @c stored_key, which means that the key is unknown, - * but its relationship to other keys can be determined via the - * comparison function object. + * The kind of key that a group has. The actual values are discussed + * in-depth in the documentation of the @c kind field of the @c group + * structure. Note that the order of the enumerators *IS* important + * and must not be changed. */ - group_key_kind kind; - - /// The parent of this group. Will only be NULL for the dummy root group - group* parent; + enum group_key_kind + { + smallest_key, + stored_key, + largest_key + }; - /// The rank of this group. Equivalent to the number of children in - /// the group. - rank_type rank; + struct group + { + explicit group(group_key_kind kind = largest_key) + : kind(kind), parent(this), rank(0) + { + } - /** The children of this group. For the dummy root group, these are - * the roots. This is an array of length log n containing pointers - * to the child groups. - */ - group** children; - }; - - size_type log_base_2(size_type n) // log2 is a macro on some platforms - { - size_type leading_zeroes = 0; - do { - size_type next = n << 1; - if (n == (next >> 1)) { - ++leading_zeroes; - n = next; - } else { - break; - } - } while (true); - return sizeof(size_type) * CHAR_BIT - leading_zeroes - 1; - } + /** The value associated with this group. This value is only valid + * when @c kind!=largest_key (which indicates a deleted + * element). Note that the use of boost::optional increases the + * memory requirements slightly but does not result in extraneous + * memory allocations or deallocations. The optional could be + * eliminated when @c value_type is a model of + * DefaultConstructible. + */ + ::boost::optional< value_type > value; + + /** + * The kind of key stored at this group. This may be @c + * smallest_key, which indicates that the key is infinitely small; + * @c largest_key, which indicates that the key is infinitely + * large; or @c stored_key, which means that the key is unknown, + * but its relationship to other keys can be determined via the + * comparison function object. + */ + group_key_kind kind; + + /// The parent of this group. Will only be NULL for the dummy root group + group* parent; + + /// The rank of this group. Equivalent to the number of children in + /// the group. + rank_type rank; + + /** The children of this group. For the dummy root group, these are + * the roots. This is an array of length log n containing pointers + * to the child groups. + */ + group** children; + }; + + size_type log_base_2(size_type n) // log2 is a macro on some platforms + { + size_type leading_zeroes = 0; + do + { + size_type next = n << 1; + if (n == (next >> 1)) + { + ++leading_zeroes; + n = next; + } + else + { + break; + } + } while (true); + return sizeof(size_type) * CHAR_BIT - leading_zeroes - 1; + } public: - relaxed_heap(size_type n, const Compare& compare = Compare(), - const ID& id = ID()) - : compare(compare), id(id), root(smallest_key), groups(n), - smallest_value(0) - { - if (n == 0) { - root.children = new group*[1]; - return; - } + relaxed_heap( + size_type n, const Compare& compare = Compare(), const ID& id = ID()) + : compare(compare), id(id), root(smallest_key), groups(n), smallest_value(0) + { + if (n == 0) + { + root.children = new group*[1]; + return; + } - log_n = log_base_2(n); - if (log_n == 0) log_n = 1; - size_type g = n / log_n; - if (n % log_n > 0) ++g; - size_type log_g = log_base_2(g); - size_type r = log_g; - - // Reserve an appropriate amount of space for data structures, so - // that we do not need to expand them. - index_to_group.resize(g); - A.resize(r + 1, 0); - root.rank = r + 1; - root.children = new group*[(log_g + 1) * (g + 1)]; - for (rank_type i = 0; i < r+1; ++i) root.children[i] = 0; - - // Build initial heap - size_type idx = 0; - while (idx < g) { - root.children[r] = &index_to_group[idx]; - idx = build_tree(root, idx, r, log_g + 1); - if (idx != g) - r = static_cast(log_base_2(g-idx)); + log_n = log_base_2(n); + if (log_n == 0) + log_n = 1; + size_type g = n / log_n; + if (n % log_n > 0) + ++g; + size_type log_g = log_base_2(g); + size_type r = log_g; + + // Reserve an appropriate amount of space for data structures, so + // that we do not need to expand them. + index_to_group.resize(g); + A.resize(r + 1, 0); + root.rank = r + 1; + root.children = new group*[(log_g + 1) * (g + 1)]; + for (rank_type i = 0; i < r + 1; ++i) + root.children[i] = 0; + + // Build initial heap + size_type idx = 0; + while (idx < g) + { + root.children[r] = &index_to_group[idx]; + idx = build_tree(root, idx, r, log_g + 1); + if (idx != g) + r = static_cast< size_type >(log_base_2(g - idx)); + } } - } - - ~relaxed_heap() { delete [] root.children; } - - void push(const value_type& x) - { - groups[get(id, x)] = x; - update(x); - } - - void update(const value_type& x) - { - group* a = &index_to_group[get(id, x) / log_n]; - if (!a->value - || *a->value == x - || compare(x, *a->value)) { - if (a != smallest_value) smallest_value = 0; - a->kind = stored_key; - a->value = x; - promote(a); + + ~relaxed_heap() { delete[] root.children; } + + void push(const value_type& x) + { + groups[get(id, x)] = x; + update(x); } - } - - void remove(const value_type& x) - { - group* a = &index_to_group[get(id, x) / log_n]; - assert(groups[get(id, x)]); - a->value = x; - a->kind = smallest_key; - promote(a); - smallest_value = a; - pop(); - } - - value_type& top() - { - find_smallest(); - assert(smallest_value->value != none); - return *smallest_value->value; - } - - const value_type& top() const - { - find_smallest(); - assert(smallest_value->value != none); - return *smallest_value->value; - } - - bool empty() const - { - find_smallest(); - return !smallest_value || (smallest_value->kind == largest_key); - } - - bool contains(const value_type& x) const { - return static_cast(groups[get(id, x)]); - } - - void pop() - { - // Fill in smallest_value. This is the group x. - find_smallest(); - group* x = smallest_value; - smallest_value = 0; - - // Make x a leaf, giving it the smallest value within its group - rank_type r = x->rank; - group* p = x->parent; + + void update(const value_type& x) { - assert(x->value != none); - - // Find x's group - size_type start = get(id, *x->value) - get(id, *x->value) % log_n; - size_type end = start + log_n; - if (end > groups.size()) end = groups.size(); - - // Remove the smallest value from the group, and find the new - // smallest value. - groups[get(id, *x->value)].reset(); - x->value.reset(); - x->kind = largest_key; - for (size_type i = start; i < end; ++i) { - if (groups[i] && (!x->value || compare(*groups[i], *x->value))) { - x->kind = stored_key; - x->value = groups[i]; + group* a = &index_to_group[get(id, x) / log_n]; + if (!a->value || *a->value == x || compare(x, *a->value)) + { + if (a != smallest_value) + smallest_value = 0; + a->kind = stored_key; + a->value = x; + promote(a); } - } } - x->rank = 0; - - // Combine prior children of x with x - group* y = x; - for (size_type c = 0; c < r; ++c) { - group* child = x->children[c]; - if (A[c] == child) A[c] = 0; - y = combine(y, child); + + void remove(const value_type& x) + { + group* a = &index_to_group[get(id, x) / log_n]; + assert(groups[get(id, x)]); + a->value = x; + a->kind = smallest_key; + promote(a); + smallest_value = a; + pop(); } - // If we got back something other than x, let y take x's place - if (y != x) { - y->parent = p; - p->children[r] = y; + value_type& top() + { + find_smallest(); + assert(smallest_value->value != none); + return *smallest_value->value; + } - assert(r == y->rank); - if (A[y->rank] == x) - A[y->rank] = do_compare(y, p)? y : 0; + const value_type& top() const + { + find_smallest(); + assert(smallest_value->value != none); + return *smallest_value->value; } - } -#ifdef BOOST_RELAXED_HEAP_DEBUG - /************************************************************************* - * Debugging support * - *************************************************************************/ - void dump_tree() { dump_tree(std::cout); } - void dump_tree(std::ostream& out) { dump_tree(out, &root); } - - void dump_tree(std::ostream& out, group* p, bool in_progress = false) - { - if (!in_progress) { - out << "digraph heap {\n" - << " edge[dir=\"back\"];\n"; + bool empty() const + { + find_smallest(); + return !smallest_value || (smallest_value->kind == largest_key); } - size_type p_index = 0; - if (p != &root) while (&index_to_group[p_index] != p) ++p_index; - - for (size_type i = 0; i < p->rank; ++i) { - group* c = p->children[i]; - if (c) { - size_type c_index = 0; - if (c != &root) while (&index_to_group[c_index] != c) ++c_index; - - out << " "; - if (p == &root) out << 'p'; else out << p_index; - out << " -> "; - if (c == &root) out << 'p'; else out << c_index; - if (A[c->rank] == c) out << " [style=\"dotted\"]"; - out << ";\n"; - dump_tree(out, c, true); - - // Emit node information - out << " "; - if (c == &root) out << 'p'; else out << c_index; - out << " [label=\""; - if (c == &root) out << 'p'; else out << c_index; - out << ":"; - size_type start = c_index * log_n; - size_type end = start + log_n; - if (end > groups.size()) end = groups.size(); - while (start != end) { - if (groups[start]) { - out << " " << get(id, *groups[start]); - if (*groups[start] == *c->value) out << "(*)"; - } - ++start; + bool contains(const value_type& x) const + { + return static_cast< bool >(groups[get(id, x)]); + } + + void pop() + { + // Fill in smallest_value. This is the group x. + find_smallest(); + group* x = smallest_value; + smallest_value = 0; + + // Make x a leaf, giving it the smallest value within its group + rank_type r = x->rank; + group* p = x->parent; + { + assert(x->value != none); + + // Find x's group + size_type start = get(id, *x->value) - get(id, *x->value) % log_n; + size_type end = start + log_n; + if (end > groups.size()) + end = groups.size(); + + // Remove the smallest value from the group, and find the new + // smallest value. + groups[get(id, *x->value)].reset(); + x->value.reset(); + x->kind = largest_key; + for (size_type i = start; i < end; ++i) + { + if (groups[i] && (!x->value || compare(*groups[i], *x->value))) + { + x->kind = stored_key; + x->value = groups[i]; + } + } + } + x->rank = 0; + + // Combine prior children of x with x + group* y = x; + for (size_type c = 0; c < r; ++c) + { + group* child = x->children[c]; + if (A[c] == child) + A[c] = 0; + y = combine(y, child); } - out << '"'; - if (do_compare(c, p)) { - out << " "; - if (c == &root) out << 'p'; else out << c_index; - out << ", style=\"filled\", fillcolor=\"gray\""; + // If we got back something other than x, let y take x's place + if (y != x) + { + y->parent = p; + p->children[r] = y; + + assert(r == y->rank); + if (A[y->rank] == x) + A[y->rank] = do_compare(y, p) ? y : 0; } - out << "];\n"; - } else { - assert(p->parent == p); - } - } - if (!in_progress) out << "}\n"; - } - - bool valid() - { - // Check that the ranks in the A array match the ranks of the - // groups stored there. Also, the active groups must be the last - // child of their parent. - for (size_type r = 0; r < A.size(); ++r) { - if (A[r] && A[r]->rank != r) return false; - - if (A[r] && A[r]->parent->children[A[r]->parent->rank-1] != A[r]) - return false; } - // The root must have no value and a key of -Infinity - if (root.kind != smallest_key) return false; - - return valid(&root); - } - - bool valid(group* p) - { - for (size_type i = 0; i < p->rank; ++i) { - group* c = p->children[i]; - if (c) { - // Check link structure - if (c->parent != p) return false; - if (c->rank != i) return false; - - // A bad group must be active - if (do_compare(c, p) && A[i] != c) return false; - - // Check recursively - if (!valid(c)) return false; - } else { - // Only the root may - if (p != &root) return false; - } - } - return true; - } +#ifdef BOOST_RELAXED_HEAP_DEBUG + /************************************************************************* + * Debugging support * + *************************************************************************/ + void dump_tree() { dump_tree(std::cout); } + void dump_tree(std::ostream& out) { dump_tree(out, &root); } -#endif // BOOST_RELAXED_HEAP_DEBUG + void dump_tree(std::ostream& out, group* p, bool in_progress = false) + { + if (!in_progress) + { + out << "digraph heap {\n" + << " edge[dir=\"back\"];\n"; + } -private: - size_type - build_tree(group& parent, size_type idx, size_type r, size_type max_rank) - { - group& this_group = index_to_group[idx]; - this_group.parent = &parent; - ++idx; - - this_group.children = root.children + (idx * max_rank); - this_group.rank = r; - for (size_type i = 0; i < r; ++i) { - this_group.children[i] = &index_to_group[idx]; - idx = build_tree(this_group, idx, i, max_rank); - } - return idx; - } - - void find_smallest() const - { - group** roots = root.children; - - if (!smallest_value) { - std::size_t i; - for (i = 0; i < root.rank; ++i) { - if (roots[i] && - (!smallest_value || do_compare(roots[i], smallest_value))) { - smallest_value = roots[i]; + size_type p_index = 0; + if (p != &root) + while (&index_to_group[p_index] != p) + ++p_index; + + for (size_type i = 0; i < p->rank; ++i) + { + group* c = p->children[i]; + if (c) + { + size_type c_index = 0; + if (c != &root) + while (&index_to_group[c_index] != c) + ++c_index; + + out << " "; + if (p == &root) + out << 'p'; + else + out << p_index; + out << " -> "; + if (c == &root) + out << 'p'; + else + out << c_index; + if (A[c->rank] == c) + out << " [style=\"dotted\"]"; + out << ";\n"; + dump_tree(out, c, true); + + // Emit node information + out << " "; + if (c == &root) + out << 'p'; + else + out << c_index; + out << " [label=\""; + if (c == &root) + out << 'p'; + else + out << c_index; + out << ":"; + size_type start = c_index * log_n; + size_type end = start + log_n; + if (end > groups.size()) + end = groups.size(); + while (start != end) + { + if (groups[start]) + { + out << " " << get(id, *groups[start]); + if (*groups[start] == *c->value) + out << "(*)"; + } + ++start; + } + out << '"'; + + if (do_compare(c, p)) + { + out << " "; + if (c == &root) + out << 'p'; + else + out << c_index; + out << ", style=\"filled\", fillcolor=\"gray\""; + } + out << "];\n"; + } + else + { + assert(p->parent == p); + } } - } - for (i = 0; i < A.size(); ++i) { - if (A[i] && (!smallest_value || do_compare(A[i], smallest_value))) - smallest_value = A[i]; - } + if (!in_progress) + out << "}\n"; } - } - bool do_compare(group* x, group* y) const - { - return (x->kind < y->kind - || (x->kind == y->kind - && x->kind == stored_key - && compare(*x->value, *y->value))); - } - - void promote(group* a) - { - assert(a != 0); - rank_type r = a->rank; - group* p = a->parent; - assert(p != 0); - if (do_compare(a, p)) { - // s is the rank + 1 sibling - group* s = p->rank > r + 1? p->children[r + 1] : 0; - - // If a is the last child of p - if (r == p->rank - 1) { - if (!A[r]) A[r] = a; - else if (A[r] != a) pair_transform(a); - } else { - assert(s != 0); - if (A[r + 1] == s) active_sibling_transform(a, s); - else good_sibling_transform(a, s); - } - } - } - - group* combine(group* a1, group* a2) - { - assert(a1->rank == a2->rank); - if (do_compare(a2, a1)) do_swap(a1, a2); - a1->children[a1->rank++] = a2; - a2->parent = a1; - clean(a1); - return a1; - } - - void clean(group* q) - { - if (2 > q->rank) return; - group* qp = q->children[q->rank-1]; - rank_type s = q->rank - 2; - group* x = q->children[s]; - group* xp = qp->children[s]; - assert(s == x->rank); - - // If x is active, swap x and xp - if (A[s] == x) { - q->children[s] = xp; - xp->parent = q; - qp->children[s] = x; - x->parent = qp; - } - } + bool valid() + { + // Check that the ranks in the A array match the ranks of the + // groups stored there. Also, the active groups must be the last + // child of their parent. + for (size_type r = 0; r < A.size(); ++r) + { + if (A[r] && A[r]->rank != r) + return false; + + if (A[r] && A[r]->parent->children[A[r]->parent->rank - 1] != A[r]) + return false; + } - void pair_transform(group* a) - { -#if defined(BOOST_RELAXED_HEAP_DEBUG) && BOOST_RELAXED_HEAP_DEBUG > 1 - std::cerr << "- pair transform\n"; -#endif - rank_type r = a->rank; + // The root must have no value and a key of -Infinity + if (root.kind != smallest_key) + return false; - // p is a's parent - group* p = a->parent; - assert(p != 0); + return valid(&root); + } - // g is p's parent (a's grandparent) - group* g = p->parent; - assert(g != 0); + bool valid(group* p) + { + for (size_type i = 0; i < p->rank; ++i) + { + group* c = p->children[i]; + if (c) + { + // Check link structure + if (c->parent != p) + return false; + if (c->rank != i) + return false; + + // A bad group must be active + if (do_compare(c, p) && A[i] != c) + return false; + + // Check recursively + if (!valid(c)) + return false; + } + else + { + // Only the root may + if (p != &root) + return false; + } + } + return true; + } - // a' <- A(r) - assert(A[r] != 0); - group* ap = A[r]; - assert(ap != 0); +#endif // BOOST_RELAXED_HEAP_DEBUG - // A(r) <- nil - A[r] = 0; +private: + size_type build_tree( + group& parent, size_type idx, size_type r, size_type max_rank) + { + group& this_group = index_to_group[idx]; + this_group.parent = &parent; + ++idx; + + this_group.children = root.children + (idx * max_rank); + this_group.rank = r; + for (size_type i = 0; i < r; ++i) + { + this_group.children[i] = &index_to_group[idx]; + idx = build_tree(this_group, idx, i, max_rank); + } + return idx; + } - // let a' have parent p' - group* pp = ap->parent; - assert(pp != 0); + void find_smallest() const + { + group** roots = root.children; + + if (!smallest_value) + { + std::size_t i; + for (i = 0; i < root.rank; ++i) + { + if (roots[i] + && (!smallest_value + || do_compare(roots[i], smallest_value))) + { + smallest_value = roots[i]; + } + } + for (i = 0; i < A.size(); ++i) + { + if (A[i] + && (!smallest_value || do_compare(A[i], smallest_value))) + smallest_value = A[i]; + } + } + } - // let a' have grandparent g' - group* gp = pp->parent; - assert(gp != 0); + bool do_compare(group* x, group* y) const + { + return (x->kind < y->kind + || (x->kind == y->kind && x->kind == stored_key + && compare(*x->value, *y->value))); + } - // Remove a and a' from their parents - assert(ap == pp->children[pp->rank-1]); // Guaranteed because ap is active - --pp->rank; + void promote(group* a) + { + assert(a != 0); + rank_type r = a->rank; + group* p = a->parent; + assert(p != 0); + if (do_compare(a, p)) + { + // s is the rank + 1 sibling + group* s = p->rank > r + 1 ? p->children[r + 1] : 0; + + // If a is the last child of p + if (r == p->rank - 1) + { + if (!A[r]) + A[r] = a; + else if (A[r] != a) + pair_transform(a); + } + else + { + assert(s != 0); + if (A[r + 1] == s) + active_sibling_transform(a, s); + else + good_sibling_transform(a, s); + } + } + } - // Guaranteed by caller - assert(a == p->children[p->rank-1]); - --p->rank; + group* combine(group* a1, group* a2) + { + assert(a1->rank == a2->rank); + if (do_compare(a2, a1)) + do_swap(a1, a2); + a1->children[a1->rank++] = a2; + a2->parent = a1; + clean(a1); + return a1; + } - // Note: a, ap, p, pp all have rank r - if (do_compare(pp, p)) { - do_swap(a, ap); - do_swap(p, pp); - do_swap(g, gp); + void clean(group* q) + { + if (2 > q->rank) + return; + group* qp = q->children[q->rank - 1]; + rank_type s = q->rank - 2; + group* x = q->children[s]; + group* xp = qp->children[s]; + assert(s == x->rank); + + // If x is active, swap x and xp + if (A[s] == x) + { + q->children[s] = xp; + xp->parent = q; + qp->children[s] = x; + x->parent = qp; + } } - // Assuming k(p) <= k(p') - // make p' the rank r child of p - assert(r == p->rank); - p->children[p->rank++] = pp; - pp->parent = p; + void pair_transform(group* a) + { +#if defined(BOOST_RELAXED_HEAP_DEBUG) && BOOST_RELAXED_HEAP_DEBUG > 1 + std::cerr << "- pair transform\n"; +#endif + rank_type r = a->rank; + + // p is a's parent + group* p = a->parent; + assert(p != 0); + + // g is p's parent (a's grandparent) + group* g = p->parent; + assert(g != 0); + + // a' <- A(r) + assert(A[r] != 0); + group* ap = A[r]; + assert(ap != 0); + + // A(r) <- nil + A[r] = 0; + + // let a' have parent p' + group* pp = ap->parent; + assert(pp != 0); + + // let a' have grandparent g' + group* gp = pp->parent; + assert(gp != 0); + + // Remove a and a' from their parents + assert(ap + == pp->children[pp->rank - 1]); // Guaranteed because ap is active + --pp->rank; + + // Guaranteed by caller + assert(a == p->children[p->rank - 1]); + --p->rank; + + // Note: a, ap, p, pp all have rank r + if (do_compare(pp, p)) + { + do_swap(a, ap); + do_swap(p, pp); + do_swap(g, gp); + } + + // Assuming k(p) <= k(p') + // make p' the rank r child of p + assert(r == p->rank); + p->children[p->rank++] = pp; + pp->parent = p; - // Combine a, ap into a rank r+1 group c - group* c = combine(a, ap); + // Combine a, ap into a rank r+1 group c + group* c = combine(a, ap); - // make c the rank r+1 child of g' - assert(gp->rank > r+1); - gp->children[r+1] = c; - c->parent = gp; + // make c the rank r+1 child of g' + assert(gp->rank > r + 1); + gp->children[r + 1] = c; + c->parent = gp; #if defined(BOOST_RELAXED_HEAP_DEBUG) && BOOST_RELAXED_HEAP_DEBUG > 1 - std::cerr << "After pair transform...\n"; - dump_tree(); + std::cerr << "After pair transform...\n"; + dump_tree(); #endif - if (A[r+1] == pp) A[r+1] = c; - else promote(c); - } + if (A[r + 1] == pp) + A[r + 1] = c; + else + promote(c); + } - void active_sibling_transform(group* a, group* s) - { + void active_sibling_transform(group* a, group* s) + { #if defined(BOOST_RELAXED_HEAP_DEBUG) && BOOST_RELAXED_HEAP_DEBUG > 1 - std::cerr << "- active sibling transform\n"; + std::cerr << "- active sibling transform\n"; #endif - group* p = a->parent; - group* g = p->parent; - - // remove a, s from their parents - assert(s->parent == p); - assert(p->children[p->rank-1] == s); - --p->rank; - assert(p->children[p->rank-1] == a); - --p->rank; - - rank_type r = a->rank; - A[r+1] = 0; - a = combine(p, a); - group* c = combine(a, s); - - // make c the rank r+2 child of g - assert(g->children[r+2] == p); - g->children[r+2] = c; - c->parent = g; - if (A[r+2] == p) A[r+2] = c; - else promote(c); - } - - void good_sibling_transform(group* a, group* s) - { + group* p = a->parent; + group* g = p->parent; + + // remove a, s from their parents + assert(s->parent == p); + assert(p->children[p->rank - 1] == s); + --p->rank; + assert(p->children[p->rank - 1] == a); + --p->rank; + + rank_type r = a->rank; + A[r + 1] = 0; + a = combine(p, a); + group* c = combine(a, s); + + // make c the rank r+2 child of g + assert(g->children[r + 2] == p); + g->children[r + 2] = c; + c->parent = g; + if (A[r + 2] == p) + A[r + 2] = c; + else + promote(c); + } + + void good_sibling_transform(group* a, group* s) + { #if defined(BOOST_RELAXED_HEAP_DEBUG) && BOOST_RELAXED_HEAP_DEBUG > 1 - std::cerr << "- good sibling transform\n"; + std::cerr << "- good sibling transform\n"; #endif - rank_type r = a->rank; - group* c = s->children[s->rank-1]; - assert(c->rank == r); - if (A[r] == c) { + rank_type r = a->rank; + group* c = s->children[s->rank - 1]; + assert(c->rank == r); + if (A[r] == c) + { #if defined(BOOST_RELAXED_HEAP_DEBUG) && BOOST_RELAXED_HEAP_DEBUG > 1 - std::cerr << "- good sibling pair transform\n"; + std::cerr << "- good sibling pair transform\n"; #endif - A[r] = 0; - group* p = a->parent; + A[r] = 0; + group* p = a->parent; - // Remove c from its parent - --s->rank; + // Remove c from its parent + --s->rank; - // Make s the rank r child of p - s->parent = p; - p->children[r] = s; + // Make s the rank r child of p + s->parent = p; + p->children[r] = s; - // combine a, c and let the result by the rank r+1 child of p - assert(p->rank > r+1); - group* x = combine(a, c); - x->parent = p; - p->children[r+1] = x; + // combine a, c and let the result by the rank r+1 child of p + assert(p->rank > r + 1); + group* x = combine(a, c); + x->parent = p; + p->children[r + 1] = x; - if (A[r+1] == s) A[r+1] = x; - else promote(x); + if (A[r + 1] == s) + A[r + 1] = x; + else + promote(x); #if defined(BOOST_RELAXED_HEAP_DEBUG) && BOOST_RELAXED_HEAP_DEBUG > 1 - dump_tree(std::cerr); + dump_tree(std::cerr); #endif - // pair_transform(a); - } else { - // Clean operation - group* p = a->parent; - s->children[r] = a; - a->parent = s; - p->children[r] = c; - c->parent = p; - - promote(a); + // pair_transform(a); + } + else + { + // Clean operation + group* p = a->parent; + s->children[r] = a; + a->parent = s; + p->children[r] = c; + c->parent = p; + + promote(a); + } } - } - - static void do_swap(group*& x, group*& y) - { - group* tmp = x; - x = y; - y = tmp; - } - - /// Function object that compares two values in the heap - Compare compare; - - /// Mapping from values to indices in the range [0, n). - ID id; - - /** The root group of the queue. This group is special because it will - * never store a value, but it acts as a parent to all of the - * roots. Thus, its list of children is the list of roots. - */ - group root; - - /** Mapping from the group index of a value to the group associated - * with that value. If a value is not in the queue, then the "value" - * field will be empty. - */ - std::vector index_to_group; - - /** Flat data structure containing the values in each of the - * groups. It will be indexed via the id of the values. The groups - * are each log_n long, with the last group potentially being - * smaller. - */ - std::vector< ::boost::optional > groups; - - /** The list of active groups, indexed by rank. When A[r] is null, - * there is no active group of rank r. Otherwise, A[r] is the active - * group of rank r. - */ - std::vector A; - - /** The group containing the smallest value in the queue, which must - * be either a root or an active group. If this group is null, then we - * will need to search for this group when it is needed. - */ - mutable group* smallest_value; - - /// Cached value log_base_2(n) - size_type log_n; -}; + static void do_swap(group*& x, group*& y) + { + group* tmp = x; + x = y; + y = tmp; + } + + /// Function object that compares two values in the heap + Compare compare; + + /// Mapping from values to indices in the range [0, n). + ID id; + + /** The root group of the queue. This group is special because it will + * never store a value, but it acts as a parent to all of the + * roots. Thus, its list of children is the list of roots. + */ + group root; + + /** Mapping from the group index of a value to the group associated + * with that value. If a value is not in the queue, then the "value" + * field will be empty. + */ + std::vector< group > index_to_group; + + /** Flat data structure containing the values in each of the + * groups. It will be indexed via the id of the values. The groups + * are each log_n long, with the last group potentially being + * smaller. + */ + std::vector< ::boost::optional< value_type > > groups; + + /** The list of active groups, indexed by rank. When A[r] is null, + * there is no active group of rank r. Otherwise, A[r] is the active + * group of rank r. + */ + std::vector< group* > A; + + /** The group containing the smallest value in the queue, which must + * be either a root or an active group. If this group is null, then we + * will need to search for this group when it is needed. + */ + mutable group* smallest_value; + + /// Cached value log_base_2(n) + size_type log_n; +}; } // end namespace boost #if defined(BOOST_MSVC) -# pragma warning(pop) +#pragma warning(pop) #endif #endif // BOOST_RELAXED_HEAP_HEADER diff --git a/include/boost/pending/stringtok.hpp b/include/boost/pending/stringtok.hpp index 3b8e5e324..f64a4c45d 100644 --- a/include/boost/pending/stringtok.hpp +++ b/include/boost/pending/stringtok.hpp @@ -1,4 +1,4 @@ -// (C) Copyright Jeremy Siek 2004 +// (C) Copyright Jeremy Siek 2004 // Distributed under the Boost Software License, Version 1.0. (See // accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) @@ -55,27 +55,24 @@ * -end example] * * pedwards@jaj.com May 1999 -*/ - + */ #include -#include // for strchr - +#include // for strchr /***************************************************************** * This is the only part of the implementation that I don't like. * It can probably be improved upon by the reader... -*/ - - inline bool - isws (char c, char const * const wstr) - { - using namespace std; - return (strchr(wstr,c) != NULL); - } + */ +inline bool isws(char c, char const* const wstr) +{ + using namespace std; + return (strchr(wstr, c) != NULL); +} -namespace boost { +namespace boost +{ /***************************************************************** * Simplistic and quite Standard, but a bit slow. This should be @@ -84,33 +81,36 @@ namespace boost { * I had hoped that "whitespace" would be a trait, but it isn't, so * the user must supply it. Enh, this lets them break up strings on * different things easier than traits would anyhow. -*/ -template -void -stringtok (Container &l, std::string const &s, char const * const ws = " \t\n") + */ +template < typename Container > +void stringtok( + Container& l, std::string const& s, char const* const ws = " \t\n") { - typedef std::string::size_type size_type; - const size_type S = s.size(); - size_type i = 0; + typedef std::string::size_type size_type; + const size_type S = s.size(); + size_type i = 0; - while (i < S) { + while (i < S) + { // eat leading whitespace - while ((i < S) && (isws(s[i],ws))) ++i; - if (i == S) return; // nothing left but WS + while ((i < S) && (isws(s[i], ws))) + ++i; + if (i == S) + return; // nothing left but WS // find end of word - size_type j = i+1; - while ((j < S) && (!isws(s[j],ws))) ++j; + size_type j = i + 1; + while ((j < S) && (!isws(s[j], ws))) + ++j; // add word - l.push_back(s.substr(i,j-i)); + l.push_back(s.substr(i, j - i)); // set up for next loop - i = j+1; + i = j + 1; } } - } // namespace boost #endif // BOOST_STRINGTOK_HPP diff --git a/index.html b/index.html index b452ee921..be9e08221 100644 --- a/index.html +++ b/index.html @@ -14,8 +14,8 @@ doc/index.html.

    © Copyright Beman Dawes, 2001

    -

    Distributed under the Boost Software License, Version 1.0. (See accompanying -file LICENSE_1_0.txt or copy +

    Distributed under the Boost Software License, Version 1.0. (See accompanying +file LICENSE_1_0.txt or copy at www.boost.org/LICENSE_1_0.txt)

    \ No newline at end of file diff --git a/src/graphml.cpp b/src/graphml.cpp index 302d03a56..72f54cf9d 100644 --- a/src/graphml.cpp +++ b/src/graphml.cpp @@ -21,138 +21,190 @@ using namespace boost; -namespace { +namespace +{ class graphml_reader { public: - graphml_reader(mutate_graph& g) - : m_g(g) { } + graphml_reader(mutate_graph& g) : m_g(g) {} - static boost::property_tree::ptree::path_type path(const std::string& str) { - return boost::property_tree::ptree::path_type(str, '/'); + static boost::property_tree::ptree::path_type path(const std::string& str) + { + return boost::property_tree::ptree::path_type(str, '/'); } void get_graphs(const boost::property_tree::ptree& top, - size_t desired_idx /* or -1 for all */, bool is_root, - std::vector& result) { - using boost::property_tree::ptree; - size_t current_idx = 0; - bool is_first = is_root; - BOOST_FOREACH(const ptree::value_type& n, top) { - if (n.first == "graph") { - if (current_idx == desired_idx || desired_idx == (size_t)(-1)) { - result.push_back(&n.second); - if(is_first) + size_t desired_idx /* or -1 for all */, bool is_root, + std::vector< const boost::property_tree::ptree* >& result) + { + using boost::property_tree::ptree; + size_t current_idx = 0; + bool is_first = is_root; + BOOST_FOREACH (const ptree::value_type& n, top) + { + if (n.first == "graph") { - is_first = false; - BOOST_FOREACH(const ptree::value_type& attr, n.second) { - if (attr.first != "data") - continue; - std::string key = attr.second.get(path("/key")); - std::string value = attr.second.get_value(""); - handle_graph_property(key, value); - } + if (current_idx == desired_idx || desired_idx == (size_t)(-1)) + { + result.push_back(&n.second); + if (is_first) + { + is_first = false; + BOOST_FOREACH (const ptree::value_type& attr, n.second) + { + if (attr.first != "data") + continue; + std::string key = attr.second.get< std::string >( + path("/key")); + std::string value = attr.second.get_value(""); + handle_graph_property(key, value); + } + } + + get_graphs(n.second, (size_t)(-1), false, result); + if (desired_idx != (size_t)(-1)) + break; + } + ++current_idx; } - - get_graphs(n.second, (size_t)(-1), false, result); - if (desired_idx != (size_t)(-1)) break; - } - ++current_idx; } - } } - + void run(std::istream& in, size_t desired_idx) { - using boost::property_tree::ptree; - ptree pt; - read_xml(in, pt, boost::property_tree::xml_parser::no_comments | boost::property_tree::xml_parser::trim_whitespace); - ptree gml = pt.get_child(path("graphml")); - // Search for attributes - BOOST_FOREACH(const ptree::value_type& child, gml) { - if (child.first != "key") continue; - std::string id = child.second.get(path("/id"), ""); - std::string for_ = child.second.get(path("/for"), ""); - std::string name = child.second.get(path("/attr.name"), ""); - std::string type = child.second.get(path("/attr.type"), ""); - key_kind kind = all_key; - if (for_ == "graph") kind = graph_key; - else if (for_ == "node") kind = node_key; - else if (for_ == "edge") kind = edge_key; - else if (for_ == "hyperedge") kind = hyperedge_key; - else if (for_ == "port") kind = port_key; - else if (for_ == "endpoint") kind = endpoint_key; - else if (for_ == "all") kind = all_key; - else if (for_ == "graphml") kind = graphml_key; - else {BOOST_THROW_EXCEPTION(parse_error("Attribute for is not valid: " + for_));} - m_keys[id] = kind; - m_key_name[id] = name; - m_key_type[id] = type; - boost::optional default_ = child.second.get_optional(path("default")); - if (default_) m_key_default[id] = default_.get(); - } - // Search for graphs - std::vector graphs; - handle_graph(); - get_graphs(gml, desired_idx, true, graphs); - BOOST_FOREACH(const ptree* gr, graphs) { - // Search for nodes - BOOST_FOREACH(const ptree::value_type& node, *gr) { - if (node.first != "node") continue; - std::string id = node.second.get(path("/id")); - handle_vertex(id); - BOOST_FOREACH(const ptree::value_type& attr, node.second) { - if (attr.first != "data") continue; - std::string key = attr.second.get(path("/key")); - std::string value = attr.second.get_value(""); - handle_node_property(key, id, value); - } + using boost::property_tree::ptree; + ptree pt; + read_xml(in, pt, + boost::property_tree::xml_parser::no_comments + | boost::property_tree::xml_parser::trim_whitespace); + ptree gml = pt.get_child(path("graphml")); + // Search for attributes + BOOST_FOREACH (const ptree::value_type& child, gml) + { + if (child.first != "key") + continue; + std::string id = child.second.get(path("/id"), ""); + std::string for_ = child.second.get(path("/for"), ""); + std::string name + = child.second.get(path("/attr.name"), ""); + std::string type + = child.second.get(path("/attr.type"), ""); + key_kind kind = all_key; + if (for_ == "graph") + kind = graph_key; + else if (for_ == "node") + kind = node_key; + else if (for_ == "edge") + kind = edge_key; + else if (for_ == "hyperedge") + kind = hyperedge_key; + else if (for_ == "port") + kind = port_key; + else if (for_ == "endpoint") + kind = endpoint_key; + else if (for_ == "all") + kind = all_key; + else if (for_ == "graphml") + kind = graphml_key; + else + { + BOOST_THROW_EXCEPTION( + parse_error("Attribute for is not valid: " + for_)); + } + m_keys[id] = kind; + m_key_name[id] = name; + m_key_type[id] = type; + boost::optional< std::string > default_ + = child.second.get_optional< std::string >(path("default")); + if (default_) + m_key_default[id] = default_.get(); + } + // Search for graphs + std::vector< const ptree* > graphs; + handle_graph(); + get_graphs(gml, desired_idx, true, graphs); + BOOST_FOREACH (const ptree* gr, graphs) + { + // Search for nodes + BOOST_FOREACH (const ptree::value_type& node, *gr) + { + if (node.first != "node") + continue; + std::string id + = node.second.get< std::string >(path("/id")); + handle_vertex(id); + BOOST_FOREACH (const ptree::value_type& attr, node.second) + { + if (attr.first != "data") + continue; + std::string key + = attr.second.get< std::string >(path("/key")); + std::string value = attr.second.get_value(""); + handle_node_property(key, id, value); + } + } } - } - BOOST_FOREACH(const ptree* gr, graphs) { - bool default_directed = gr->get(path("/edgedefault")) == "directed"; - // Search for edges - BOOST_FOREACH(const ptree::value_type& edge, *gr) { - if (edge.first != "edge") continue; - std::string source = edge.second.get(path("/source")); - std::string target = edge.second.get(path("/target")); - std::string local_directed = edge.second.get(path("/directed"), ""); - bool is_directed = (local_directed == "" ? default_directed : local_directed == "true"); - if (is_directed != m_g.is_directed()) { - if (is_directed) { - BOOST_THROW_EXCEPTION(directed_graph_error()); - } else { - BOOST_THROW_EXCEPTION(undirected_graph_error()); + BOOST_FOREACH (const ptree* gr, graphs) + { + bool default_directed + = gr->get< std::string >(path("/edgedefault")) + == "directed"; + // Search for edges + BOOST_FOREACH (const ptree::value_type& edge, *gr) + { + if (edge.first != "edge") + continue; + std::string source + = edge.second.get< std::string >(path("/source")); + std::string target + = edge.second.get< std::string >(path("/target")); + std::string local_directed + = edge.second.get(path("/directed"), ""); + bool is_directed + = (local_directed == "" ? default_directed + : local_directed == "true"); + if (is_directed != m_g.is_directed()) + { + if (is_directed) + { + BOOST_THROW_EXCEPTION(directed_graph_error()); + } + else + { + BOOST_THROW_EXCEPTION(undirected_graph_error()); + } + } + size_t old_edges_size = m_edge.size(); + handle_edge(source, target); + BOOST_FOREACH (const ptree::value_type& attr, edge.second) + { + if (attr.first != "data") + continue; + std::string key + = attr.second.get< std::string >(path("/key")); + std::string value = attr.second.get_value(""); + handle_edge_property(key, old_edges_size, value); + } } - } - size_t old_edges_size = m_edge.size(); - handle_edge(source, target); - BOOST_FOREACH(const ptree::value_type& attr, edge.second) { - if (attr.first != "data") continue; - std::string key = attr.second.get(path("/key")); - std::string value = attr.second.get_value(""); - handle_edge_property(key, old_edges_size, value); - } } - } } private: /// The kinds of keys. Not all of these are supported - enum key_kind { - graph_key, - node_key, + enum key_kind + { + graph_key, + node_key, edge_key, hyperedge_key, port_key, - endpoint_key, + endpoint_key, all_key, graphml_key }; - void - handle_vertex(const std::string& v) + void handle_vertex(const std::string& v) { bool is_new = false; @@ -164,8 +216,9 @@ class graphml_reader if (is_new) { - std::map::iterator iter; - for (iter = m_key_default.begin(); iter != m_key_default.end(); ++iter) + std::map< std::string, std::string >::iterator iter; + for (iter = m_key_default.begin(); iter != m_key_default.end(); + ++iter) { if (m_keys[iter->first] == node_key) handle_node_property(iter->first, v, iter->second); @@ -173,14 +226,9 @@ class graphml_reader } } - any - get_vertex_descriptor(const std::string& v) - { - return m_vertex[v]; - } + any get_vertex_descriptor(const std::string& v) { return m_vertex[v]; } - void - handle_edge(const std::string& u, const std::string& v) + void handle_edge(const std::string& u, const std::string& v) { handle_vertex(u); handle_vertex(v); @@ -192,14 +240,15 @@ class graphml_reader any edge; bool added; boost::tie(edge, added) = m_g.do_add_edge(source, target); - if (!added) { + if (!added) + { BOOST_THROW_EXCEPTION(bad_parallel_edge(u, v)); } size_t e = m_edge.size(); m_edge.push_back(edge); - - std::map::iterator iter; + + std::map< std::string, std::string >::iterator iter; for (iter = m_key_default.begin(); iter != m_key_default.end(); ++iter) { if (m_keys[iter->first] == edge_key) @@ -207,48 +256,52 @@ class graphml_reader } } - void - handle_graph() + void handle_graph() { - std::map::iterator iter; - for (iter = m_key_default.begin(); iter != m_key_default.end(); ++iter) - { - if (m_keys[iter->first] == graph_key) - handle_graph_property(iter->first, iter->second); - } + std::map< std::string, std::string >::iterator iter; + for (iter = m_key_default.begin(); iter != m_key_default.end(); ++iter) + { + if (m_keys[iter->first] == graph_key) + handle_graph_property(iter->first, iter->second); + } } - void handle_graph_property(const std::string& key_id, const std::string& value) + void handle_graph_property( + const std::string& key_id, const std::string& value) { - m_g.set_graph_property(m_key_name[key_id], value, m_key_type[key_id]); + m_g.set_graph_property(m_key_name[key_id], value, m_key_type[key_id]); } - void handle_node_property(const std::string& key_id, const std::string& descriptor, const std::string& value) + void handle_node_property(const std::string& key_id, + const std::string& descriptor, const std::string& value) { - m_g.set_vertex_property(m_key_name[key_id], m_vertex[descriptor], value, m_key_type[key_id]); + m_g.set_vertex_property(m_key_name[key_id], m_vertex[descriptor], value, + m_key_type[key_id]); } - void handle_edge_property(const std::string& key_id, size_t descriptor, const std::string& value) + void handle_edge_property( + const std::string& key_id, size_t descriptor, const std::string& value) { - m_g.set_edge_property(m_key_name[key_id], m_edge[descriptor], value, m_key_type[key_id]); + m_g.set_edge_property( + m_key_name[key_id], m_edge[descriptor], value, m_key_type[key_id]); } mutate_graph& m_g; - std::map m_keys; - std::map m_key_name; - std::map m_key_type; - std::map m_key_default; - std::map m_vertex; - std::vector m_edge; + std::map< std::string, key_kind > m_keys; + std::map< std::string, std::string > m_key_name; + std::map< std::string, std::string > m_key_type; + std::map< std::string, std::string > m_key_default; + std::map< std::string, any > m_vertex; + std::vector< any > m_edge; }; } namespace boost { -void BOOST_GRAPH_DECL -read_graphml(std::istream& in, mutate_graph& g, size_t desired_idx) -{ +void BOOST_GRAPH_DECL read_graphml( + std::istream& in, mutate_graph& g, size_t desired_idx) +{ graphml_reader reader(g); reader.run(in, desired_idx); } diff --git a/src/read_graphviz_new.cpp b/src/read_graphviz_new.cpp index 3c9a70915..f4162eae5 100644 --- a/src/read_graphviz_new.cpp +++ b/src/read_graphviz_new.cpp @@ -17,7 +17,7 @@ // http://www.graphviz.org/doc/info/lang.html // and page 34 or http://www.graphviz.org/pdf/dotguide.pdf // -// See documentation for this code at: +// See documentation for this code at: // http://www.boost.org/libs/graph/doc/read_graphviz.html // @@ -49,759 +49,1132 @@ #include #include -namespace boost { - -namespace read_graphviz_detail { - struct token { - enum token_type { - kw_strict, - kw_graph, - kw_digraph, - kw_node, - kw_edge, - kw_subgraph, - left_brace, - right_brace, - semicolon, - equal, - left_bracket, - right_bracket, - comma, - colon, - dash_greater, - dash_dash, - plus, - left_paren, - right_paren, - at, - identifier, - quoted_string, // Only used internally in tokenizer - eof, - invalid +namespace boost +{ + +namespace read_graphviz_detail +{ + struct token + { + enum token_type + { + kw_strict, + kw_graph, + kw_digraph, + kw_node, + kw_edge, + kw_subgraph, + left_brace, + right_brace, + semicolon, + equal, + left_bracket, + right_bracket, + comma, + colon, + dash_greater, + dash_dash, + plus, + left_paren, + right_paren, + at, + identifier, + quoted_string, // Only used internally in tokenizer + eof, + invalid + }; + token_type type; + std::string normalized_value; // May have double-quotes removed and/or + // some escapes replaced + token(token_type type, const std::string& normalized_value) + : type(type), normalized_value(normalized_value) + { + } + token() : type(invalid), normalized_value("") {} + friend std::ostream& operator<<(std::ostream& o, const token& t) + { + switch (t.type) + { + case token::kw_strict: + o << ""; + break; + case token::kw_graph: + o << ""; + break; + case token::kw_digraph: + o << ""; + break; + case token::kw_node: + o << ""; + break; + case token::kw_edge: + o << ""; + break; + case token::kw_subgraph: + o << ""; + break; + case token::left_brace: + o << ""; + break; + case token::right_brace: + o << ""; + break; + case token::semicolon: + o << ""; + break; + case token::equal: + o << ""; + break; + case token::left_bracket: + o << ""; + break; + case token::right_bracket: + o << ""; + break; + case token::comma: + o << ""; + break; + case token::colon: + o << ""; + break; + case token::dash_greater: + o << ""; + break; + case token::dash_dash: + o << ""; + break; + case token::plus: + o << ""; + break; + case token::left_paren: + o << ""; + break; + case token::right_paren: + o << ""; + break; + case token::at: + o << ""; + break; + case token::identifier: + o << ""; + break; + case token::quoted_string: + o << ""; + break; + case token::eof: + o << ""; + break; + default: + o << ""; + break; + } + o << " '" << t.normalized_value << "'"; + return o; + } }; - token_type type; - std::string normalized_value; // May have double-quotes removed and/or some escapes replaced - token(token_type type, const std::string& normalized_value) - : type(type), normalized_value(normalized_value) {} - token(): type(invalid), normalized_value("") {} - friend std::ostream& operator<<(std::ostream& o, const token& t) { - switch (t.type) { - case token::kw_strict: o << ""; break; - case token::kw_graph: o << ""; break; - case token::kw_digraph: o << ""; break; - case token::kw_node: o << ""; break; - case token::kw_edge: o << ""; break; - case token::kw_subgraph: o << ""; break; - case token::left_brace: o << ""; break; - case token::right_brace: o << ""; break; - case token::semicolon: o << ""; break; - case token::equal: o << ""; break; - case token::left_bracket: o << ""; break; - case token::right_bracket: o << ""; break; - case token::comma: o << ""; break; - case token::colon: o << ""; break; - case token::dash_greater: o << ""; break; - case token::dash_dash: o << ""; break; - case token::plus: o << ""; break; - case token::left_paren: o << ""; break; - case token::right_paren: o << ""; break; - case token::at: o << ""; break; - case token::identifier: o << ""; break; - case token::quoted_string: o << ""; break; - case token::eof: o << ""; break; - default: o << ""; break; - } - o << " '" << t.normalized_value << "'"; - return o; - } - }; - bad_graphviz_syntax lex_error(const std::string& errmsg, char bad_char) { - if (bad_char == '\0') { - return bad_graphviz_syntax(errmsg + " (at end of input)"); - } else { - return bad_graphviz_syntax(errmsg + " (char is '" + bad_char + "')"); + bad_graphviz_syntax lex_error(const std::string& errmsg, char bad_char) + { + if (bad_char == '\0') + { + return bad_graphviz_syntax(errmsg + " (at end of input)"); + } + else + { + return bad_graphviz_syntax( + errmsg + " (char is '" + bad_char + "')"); + } } - } - - bad_graphviz_syntax parse_error(const std::string& errmsg, const token& bad_token) { - return bad_graphviz_syntax(errmsg + " (token is \"" + boost::lexical_cast(bad_token) + "\")"); - } - - struct tokenizer { - std::string::const_iterator begin, end; - std::vector lookahead; - // Precomputed regexes - boost::regex stuff_to_skip; - boost::regex basic_id_token; - boost::regex punctuation_token; - boost::regex number_token; - boost::regex quoted_string_token; - boost::regex xml_tag_token; - boost::regex cdata; - - tokenizer(const std::string& str) : begin(str.begin()), end(str.end()) + + bad_graphviz_syntax parse_error( + const std::string& errmsg, const token& bad_token) { - std::string end_of_token = "(?=(?:\\W))"; - std::string whitespace = "(?:\\s+)"; - std::string slash_slash_comment = "(?://.*?$)"; - std::string slash_star_comment = "(?:/\\*.*?\\*/)"; - std::string hash_comment = "(?:^#.*?$)"; - std::string backslash_newline = "(?:[\\\\][\\n])"; - stuff_to_skip = "\\A(?:" + whitespace + "|" + - slash_slash_comment + "|" + - slash_star_comment + "|" + - hash_comment + "|" + - backslash_newline + ")*"; - basic_id_token = "\\A([[:alpha:]_](?:\\w*))"; - punctuation_token = "\\A([][{};=,:+()@]|[-][>-])"; - number_token = "\\A([-]?(?:(?:\\.\\d+)|(?:\\d+(?:\\.\\d*)?)))"; - quoted_string_token = "\\A(\"(?:[^\"\\\\]|(?:[\\\\].))*\")"; - xml_tag_token = "\\A<(/?)(?:[^!?'\"]|(?:'[^']*?')|(?:\"[^\"]*?\"))*?(/?)>"; - cdata = "\\A\\Q\\E"; + return bad_graphviz_syntax(errmsg + " (token is \"" + + boost::lexical_cast< std::string >(bad_token) + "\")"); } - void skip() { - boost::match_results results; + struct tokenizer + { + std::string::const_iterator begin, end; + std::vector< token > lookahead; + // Precomputed regexes + boost::regex stuff_to_skip; + boost::regex basic_id_token; + boost::regex punctuation_token; + boost::regex number_token; + boost::regex quoted_string_token; + boost::regex xml_tag_token; + boost::regex cdata; + + tokenizer(const std::string& str) : begin(str.begin()), end(str.end()) + { + std::string end_of_token = "(?=(?:\\W))"; + std::string whitespace = "(?:\\s+)"; + std::string slash_slash_comment = "(?://.*?$)"; + std::string slash_star_comment = "(?:/\\*.*?\\*/)"; + std::string hash_comment = "(?:^#.*?$)"; + std::string backslash_newline = "(?:[\\\\][\\n])"; + stuff_to_skip = "\\A(?:" + whitespace + "|" + slash_slash_comment + + "|" + slash_star_comment + "|" + hash_comment + "|" + + backslash_newline + ")*"; + basic_id_token = "\\A([[:alpha:]_](?:\\w*))"; + punctuation_token = "\\A([][{};=,:+()@]|[-][>-])"; + number_token = "\\A([-]?(?:(?:\\.\\d+)|(?:\\d+(?:\\.\\d*)?)))"; + quoted_string_token = "\\A(\"(?:[^\"\\\\]|(?:[\\\\].))*\")"; + xml_tag_token + = "\\A<(/?)(?:[^!?'\"]|(?:'[^']*?')|(?:\"[^\"]*?\"))*?(/?)>"; + cdata = "\\A\\Q\\E"; + } + + void skip() + { + boost::match_results< std::string::const_iterator > results; #ifndef NDEBUG - bool found = + bool found = #endif - boost::regex_search(begin, end, results, stuff_to_skip); + boost::regex_search(begin, end, results, stuff_to_skip); #ifndef NDEBUG - BOOST_ASSERT (found); + BOOST_ASSERT(found); #endif - boost::sub_match sm1 = results.suffix(); - BOOST_ASSERT (sm1.second == end); - begin = sm1.first; - } + boost::sub_match< std::string::const_iterator > sm1 + = results.suffix(); + BOOST_ASSERT(sm1.second == end); + begin = sm1.first; + } - token get_token_raw() { - if (!lookahead.empty()) { - token t = lookahead.front(); - lookahead.erase(lookahead.begin()); - return t; - } - skip(); - if (begin == end) return token(token::eof, ""); - // Look for keywords first - bool found; - boost::match_results results; - found = boost::regex_search(begin, end, results, basic_id_token); - if (found) { - std::string str = results[1].str(); - std::string str_lower = boost::algorithm::to_lower_copy(str); - begin = results.suffix().first; - if (str_lower == "strict") { - return token(token::kw_strict, str); - } else if (str_lower == "graph") { - return token(token::kw_graph, str); - } else if (str_lower == "digraph") { - return token(token::kw_digraph, str); - } else if (str_lower == "node") { - return token(token::kw_node, str); - } else if (str_lower == "edge") { - return token(token::kw_edge, str); - } else if (str_lower == "subgraph") { - return token(token::kw_subgraph, str); - } else { - return token(token::identifier, str); - } - } - found = boost::regex_search(begin, end, results, punctuation_token); - if (found) { - std::string str = results[1].str(); - begin = results.suffix().first; - switch (str[0]) { - case '[': return token(token::left_bracket, str); - case ']': return token(token::right_bracket, str); - case '{': return token(token::left_brace, str); - case '}': return token(token::right_brace, str); - case ';': return token(token::semicolon, str); - case '=': return token(token::equal, str); - case ',': return token(token::comma, str); - case ':': return token(token::colon, str); - case '+': return token(token::plus, str); - case '(': return token(token::left_paren, str); - case ')': return token(token::right_paren, str); - case '@': return token(token::at, str); - case '-': { - switch (str[1]) { - case '-': return token(token::dash_dash, str); - case '>': return token(token::dash_greater, str); - default: BOOST_ASSERT (!"Definition of punctuation_token does not match switch statement"); - } - } - default: BOOST_ASSERT (!"Definition of punctuation_token does not match switch statement"); - } - } - found = boost::regex_search(begin, end, results, number_token); - if (found) { - std::string str = results[1].str(); - begin = results.suffix().first; - return token(token::identifier, str); - } - found = boost::regex_search(begin, end, results, quoted_string_token); - if (found) { - std::string str = results[1].str(); - begin = results.suffix().first; - // Remove the beginning and ending quotes - BOOST_ASSERT (str.size() >= 2); - str.erase(str.begin()); - str.erase(str.end() - 1); - // Unescape quotes in the middle, but nothing else (see format spec) - for (size_t i = 0; i + 1 < str.size() /* May change */; ++i) { - if (str[i] == '\\' && str[i + 1] == '"') { - str.erase(str.begin() + i); - // Don't need to adjust i - } else if (str[i] == '\\' && str[i + 1] == '\n') { - str.erase(str.begin() + i); - str.erase(str.begin() + i); - --i; // Invert ++ that will be applied - } - } - return token(token::quoted_string, str); - } - if (*begin == '<') { - std::string::const_iterator saved_begin = begin; - int counter = 0; - do { - if (begin == end) throw_lex_error("Unclosed HTML string"); - if (*begin != '<') { - ++begin; - continue; - } - found = boost::regex_search(begin, end, results, xml_tag_token); - if (found) { - begin = results.suffix().first; - if (results[1].str() == "/") { // Close tag - --counter; - } else if (results[2].str() == "/") { // Empty tag - } else { // Open tag - ++counter; - } - continue; - } - found = boost::regex_search(begin, end, results, cdata); - if (found) { - begin = results.suffix().first; - continue; - } - throw_lex_error("Invalid contents in HTML string"); - } while (counter > 0); - return token(token::identifier, std::string(saved_begin, begin)); - } else { - throw_lex_error("Invalid character"); - return token(); - } - } + token get_token_raw() + { + if (!lookahead.empty()) + { + token t = lookahead.front(); + lookahead.erase(lookahead.begin()); + return t; + } + skip(); + if (begin == end) + return token(token::eof, ""); + // Look for keywords first + bool found; + boost::match_results< std::string::const_iterator > results; + found = boost::regex_search(begin, end, results, basic_id_token); + if (found) + { + std::string str = results[1].str(); + std::string str_lower = boost::algorithm::to_lower_copy(str); + begin = results.suffix().first; + if (str_lower == "strict") + { + return token(token::kw_strict, str); + } + else if (str_lower == "graph") + { + return token(token::kw_graph, str); + } + else if (str_lower == "digraph") + { + return token(token::kw_digraph, str); + } + else if (str_lower == "node") + { + return token(token::kw_node, str); + } + else if (str_lower == "edge") + { + return token(token::kw_edge, str); + } + else if (str_lower == "subgraph") + { + return token(token::kw_subgraph, str); + } + else + { + return token(token::identifier, str); + } + } + found = boost::regex_search(begin, end, results, punctuation_token); + if (found) + { + std::string str = results[1].str(); + begin = results.suffix().first; + switch (str[0]) + { + case '[': + return token(token::left_bracket, str); + case ']': + return token(token::right_bracket, str); + case '{': + return token(token::left_brace, str); + case '}': + return token(token::right_brace, str); + case ';': + return token(token::semicolon, str); + case '=': + return token(token::equal, str); + case ',': + return token(token::comma, str); + case ':': + return token(token::colon, str); + case '+': + return token(token::plus, str); + case '(': + return token(token::left_paren, str); + case ')': + return token(token::right_paren, str); + case '@': + return token(token::at, str); + case '-': + { + switch (str[1]) + { + case '-': + return token(token::dash_dash, str); + case '>': + return token(token::dash_greater, str); + default: + BOOST_ASSERT(!"Definition of punctuation_token does " + "not match switch statement"); + } + } + default: + BOOST_ASSERT(!"Definition of punctuation_token does not " + "match switch statement"); + } + } + found = boost::regex_search(begin, end, results, number_token); + if (found) + { + std::string str = results[1].str(); + begin = results.suffix().first; + return token(token::identifier, str); + } + found + = boost::regex_search(begin, end, results, quoted_string_token); + if (found) + { + std::string str = results[1].str(); + begin = results.suffix().first; + // Remove the beginning and ending quotes + BOOST_ASSERT(str.size() >= 2); + str.erase(str.begin()); + str.erase(str.end() - 1); + // Unescape quotes in the middle, but nothing else (see format + // spec) + for (size_t i = 0; i + 1 < str.size() /* May change */; ++i) + { + if (str[i] == '\\' && str[i + 1] == '"') + { + str.erase(str.begin() + i); + // Don't need to adjust i + } + else if (str[i] == '\\' && str[i + 1] == '\n') + { + str.erase(str.begin() + i); + str.erase(str.begin() + i); + --i; // Invert ++ that will be applied + } + } + return token(token::quoted_string, str); + } + if (*begin == '<') + { + std::string::const_iterator saved_begin = begin; + int counter = 0; + do + { + if (begin == end) + throw_lex_error("Unclosed HTML string"); + if (*begin != '<') + { + ++begin; + continue; + } + found = boost::regex_search( + begin, end, results, xml_tag_token); + if (found) + { + begin = results.suffix().first; + if (results[1].str() == "/") + { // Close tag + --counter; + } + else if (results[2].str() == "/") + { // Empty tag + } + else + { // Open tag + ++counter; + } + continue; + } + found = boost::regex_search(begin, end, results, cdata); + if (found) + { + begin = results.suffix().first; + continue; + } + throw_lex_error("Invalid contents in HTML string"); + } while (counter > 0); + return token( + token::identifier, std::string(saved_begin, begin)); + } + else + { + throw_lex_error("Invalid character"); + return token(); + } + } - token peek_token_raw() { - if (lookahead.empty()) { - token t = get_token_raw(); - lookahead.push_back(t); - } - return lookahead.front(); - } + token peek_token_raw() + { + if (lookahead.empty()) + { + token t = get_token_raw(); + lookahead.push_back(t); + } + return lookahead.front(); + } - token get_token() { // Handle string concatenation - token t = get_token_raw(); - if (t.type != token::quoted_string) return t; - std::string str = t.normalized_value; - while (peek_token_raw().type == token::plus) { - get_token_raw(); - token t2 = get_token_raw(); - if (t2.type != token::quoted_string) { - throw_lex_error("Must have quoted string after string concatenation"); - } - str += t2.normalized_value; - } - return token(token::identifier, str); // Note that quoted_string does not get passed to the parser - } + token get_token() + { // Handle string concatenation + token t = get_token_raw(); + if (t.type != token::quoted_string) + return t; + std::string str = t.normalized_value; + while (peek_token_raw().type == token::plus) + { + get_token_raw(); + token t2 = get_token_raw(); + if (t2.type != token::quoted_string) + { + throw_lex_error( + "Must have quoted string after string concatenation"); + } + str += t2.normalized_value; + } + return token( + token::identifier, str); // Note that quoted_string does not get + // passed to the parser + } - void throw_lex_error(const std::string& errmsg) { - boost::throw_exception(lex_error(errmsg, (begin == end ? '\0' : *begin))); - } - }; - - struct edge_endpoint { - bool is_subgraph; - node_and_port node_ep; - subgraph_name subgraph_ep; - - static edge_endpoint node(const node_and_port& ep) { - edge_endpoint r; - r.is_subgraph = false; - r.node_ep = ep; - return r; - } + void throw_lex_error(const std::string& errmsg) + { + boost::throw_exception( + lex_error(errmsg, (begin == end ? '\0' : *begin))); + } + }; - static edge_endpoint subgraph(const subgraph_name& ep) { - edge_endpoint r; - r.is_subgraph = true; - r.subgraph_ep = ep; - return r; - } - }; - - struct node_or_subgraph_ref { - bool is_subgraph; - std::string name; // Name for subgraphs or nodes, "___root___" for root graph - }; - - static node_or_subgraph_ref noderef(const node_name& n) { - node_or_subgraph_ref r; - r.is_subgraph = false; - r.name = n; - return r; - } - - static node_or_subgraph_ref subgraphref(const subgraph_name& n) { - node_or_subgraph_ref r; - r.is_subgraph = true; - r.name = n; - return r; - } - - typedef std::vector subgraph_member_list; - - struct subgraph_info { - properties def_node_props; - properties def_edge_props; - subgraph_member_list members; - }; - - struct parser { - tokenizer the_tokenizer; - std::vector lookahead; - parser_result& r; - std::map subgraphs; - std::string current_subgraph_name; - int sgcounter; // Counter for anonymous subgraphs - std::set > existing_edges; // Used for checking in strict graphs - - subgraph_info& current() {return subgraphs[current_subgraph_name];} - properties& current_graph_props() {return r.graph_props[current_subgraph_name];} - subgraph_member_list& current_members() {return current().members;} - - parser(const std::string& gr, parser_result& result) - : the_tokenizer(gr), lookahead(), r(result), sgcounter(0) { - current_subgraph_name = "___root___"; - current() = subgraph_info(); // Initialize root graph - current_graph_props().clear(); - current_members().clear(); - } + struct edge_endpoint + { + bool is_subgraph; + node_and_port node_ep; + subgraph_name subgraph_ep; - token get() { - if (lookahead.empty()) { - token t = the_tokenizer.get_token(); - return t; - } else { - token t = lookahead.front(); - lookahead.erase(lookahead.begin()); - return t; - } - } + static edge_endpoint node(const node_and_port& ep) + { + edge_endpoint r; + r.is_subgraph = false; + r.node_ep = ep; + return r; + } - token peek() { - if (lookahead.empty()) { - lookahead.push_back(the_tokenizer.get_token()); - } - return lookahead.front(); - } + static edge_endpoint subgraph(const subgraph_name& ep) + { + edge_endpoint r; + r.is_subgraph = true; + r.subgraph_ep = ep; + return r; + } + }; - void error(const std::string& str) { - boost::throw_exception(parse_error(str, peek())); - } + struct node_or_subgraph_ref + { + bool is_subgraph; + std::string + name; // Name for subgraphs or nodes, "___root___" for root graph + }; - void parse_graph(bool want_directed) { - bool is_strict = false; - bool is_directed = false; - std::string name; - if (peek().type == token::kw_strict) {get(); is_strict = true;} - switch (peek().type) { - case token::kw_graph: is_directed = false; break; - case token::kw_digraph: is_directed = true; break; - default: error("Wanted \"graph\" or \"digraph\""); - } - r.graph_is_directed = is_directed; // Used to check edges - r.graph_is_strict = is_strict; - if (want_directed != r.graph_is_directed) { - if (want_directed) { - boost::throw_exception(boost::undirected_graph_error()); - } else { - boost::throw_exception(boost::directed_graph_error()); - } - } - get(); - switch (peek().type) { - case token::identifier: name = peek().normalized_value; get(); break; - case token::left_brace: break; - default: error("Wanted a graph name or left brace"); - } - if (peek().type == token::left_brace) get(); else error("Wanted a left brace to start the graph"); - parse_stmt_list(); - if (peek().type == token::right_brace) get(); else error("Wanted a right brace to end the graph"); - if (peek().type == token::eof) {} else error("Wanted end of file"); + static node_or_subgraph_ref noderef(const node_name& n) + { + node_or_subgraph_ref r; + r.is_subgraph = false; + r.name = n; + return r; } - void parse_stmt_list() { - while (true) { - if (peek().type == token::right_brace) return; - parse_stmt(); - if (peek().type == token::semicolon) get(); - } + static node_or_subgraph_ref subgraphref(const subgraph_name& n) + { + node_or_subgraph_ref r; + r.is_subgraph = true; + r.name = n; + return r; } - void parse_stmt() { - switch (peek().type) { - case token::kw_node: - case token::kw_edge: - case token::kw_graph: parse_attr_stmt(); break; - case token::kw_subgraph: - case token::left_brace: - case token::identifier: { - token id = get(); - if (id.type == token::identifier && peek().type == token::equal) { // Graph property + typedef std::vector< node_or_subgraph_ref > subgraph_member_list; + + struct subgraph_info + { + properties def_node_props; + properties def_edge_props; + subgraph_member_list members; + }; + + struct parser + { + tokenizer the_tokenizer; + std::vector< token > lookahead; + parser_result& r; + std::map< subgraph_name, subgraph_info > subgraphs; + std::string current_subgraph_name; + int sgcounter; // Counter for anonymous subgraphs + std::set< std::pair< node_name, node_name > > + existing_edges; // Used for checking in strict graphs + + subgraph_info& current() { return subgraphs[current_subgraph_name]; } + properties& current_graph_props() + { + return r.graph_props[current_subgraph_name]; + } + subgraph_member_list& current_members() { return current().members; } + + parser(const std::string& gr, parser_result& result) + : the_tokenizer(gr), lookahead(), r(result), sgcounter(0) + { + current_subgraph_name = "___root___"; + current() = subgraph_info(); // Initialize root graph + current_graph_props().clear(); + current_members().clear(); + } + + token get() + { + if (lookahead.empty()) + { + token t = the_tokenizer.get_token(); + return t; + } + else + { + token t = lookahead.front(); + lookahead.erase(lookahead.begin()); + return t; + } + } + + token peek() + { + if (lookahead.empty()) + { + lookahead.push_back(the_tokenizer.get_token()); + } + return lookahead.front(); + } + + void error(const std::string& str) + { + boost::throw_exception(parse_error(str, peek())); + } + + void parse_graph(bool want_directed) + { + bool is_strict = false; + bool is_directed = false; + std::string name; + if (peek().type == token::kw_strict) + { + get(); + is_strict = true; + } + switch (peek().type) + { + case token::kw_graph: + is_directed = false; + break; + case token::kw_digraph: + is_directed = true; + break; + default: + error("Wanted \"graph\" or \"digraph\""); + } + r.graph_is_directed = is_directed; // Used to check edges + r.graph_is_strict = is_strict; + if (want_directed != r.graph_is_directed) + { + if (want_directed) + { + boost::throw_exception(boost::undirected_graph_error()); + } + else + { + boost::throw_exception(boost::directed_graph_error()); + } + } get(); - if (peek().type != token::identifier) error("Wanted identifier as right side of ="); - token id2 = get(); - current_graph_props()[id.normalized_value] = id2.normalized_value; - } else { - edge_endpoint ep = parse_endpoint_rest(id); - if (peek().type == token::dash_dash || peek().type == token::dash_greater) { // Edge - parse_edge_stmt(ep); - } else { - if (!ep.is_subgraph) { // Only nodes can have attribute lists - // This node already exists because of its first mention - // (properties set to defaults by parse_node_and_port, called - // by parse_endpoint_rest) - properties this_node_props; - if (peek().type == token::left_bracket) { - parse_attr_list(this_node_props); + switch (peek().type) + { + case token::identifier: + name = peek().normalized_value; + get(); + break; + case token::left_brace: + break; + default: + error("Wanted a graph name or left brace"); + } + if (peek().type == token::left_brace) + get(); + else + error("Wanted a left brace to start the graph"); + parse_stmt_list(); + if (peek().type == token::right_brace) + get(); + else + error("Wanted a right brace to end the graph"); + if (peek().type == token::eof) + { + } + else + error("Wanted end of file"); + } + + void parse_stmt_list() + { + while (true) + { + if (peek().type == token::right_brace) + return; + parse_stmt(); + if (peek().type == token::semicolon) + get(); + } + } + + void parse_stmt() + { + switch (peek().type) + { + case token::kw_node: + case token::kw_edge: + case token::kw_graph: + parse_attr_stmt(); + break; + case token::kw_subgraph: + case token::left_brace: + case token::identifier: + { + token id = get(); + if (id.type == token::identifier && peek().type == token::equal) + { // Graph property + get(); + if (peek().type != token::identifier) + error("Wanted identifier as right side of ="); + token id2 = get(); + current_graph_props()[id.normalized_value] + = id2.normalized_value; } - for (properties::const_iterator i = this_node_props.begin(); - i != this_node_props.end(); ++i) { - // Override old properties with same names - r.nodes[ep.node_ep.name][i->first] = i->second; + else + { + edge_endpoint ep = parse_endpoint_rest(id); + if (peek().type == token::dash_dash + || peek().type == token::dash_greater) + { // Edge + parse_edge_stmt(ep); + } + else + { + if (!ep.is_subgraph) + { // Only nodes can have attribute lists + // This node already exists because of its first + // mention (properties set to defaults by + // parse_node_and_port, called by + // parse_endpoint_rest) + properties this_node_props; + if (peek().type == token::left_bracket) + { + parse_attr_list(this_node_props); + } + for (properties::const_iterator i + = this_node_props.begin(); + i != this_node_props.end(); ++i) + { + // Override old properties with same names + r.nodes[ep.node_ep.name][i->first] = i->second; + } + current_members().push_back( + noderef(ep.node_ep.name)); + } + else + { + current_members().push_back( + subgraphref(ep.subgraph_ep)); + } + } } - current_members().push_back(noderef(ep.node_ep.name)); - } else { - current_members().push_back(subgraphref(ep.subgraph_ep)); - } + break; + } + default: + error("Invalid start token for statement"); } - } - break; } - default: error("Invalid start token for statement"); - } - } - void parse_attr_stmt() { - switch (get().type) { - case token::kw_graph: parse_attr_list(current_graph_props()); break; - case token::kw_node: parse_attr_list(current().def_node_props); break; - case token::kw_edge: parse_attr_list(current().def_edge_props); break; - default: BOOST_ASSERT (!"Bad attr_stmt case"); - } - } + void parse_attr_stmt() + { + switch (get().type) + { + case token::kw_graph: + parse_attr_list(current_graph_props()); + break; + case token::kw_node: + parse_attr_list(current().def_node_props); + break; + case token::kw_edge: + parse_attr_list(current().def_edge_props); + break; + default: + BOOST_ASSERT(!"Bad attr_stmt case"); + } + } - edge_endpoint parse_endpoint() { - switch (peek().type) { - case token::kw_subgraph: - case token::left_brace: - case token::identifier: { - token first = get(); - return parse_endpoint_rest(first); + edge_endpoint parse_endpoint() + { + switch (peek().type) + { + case token::kw_subgraph: + case token::left_brace: + case token::identifier: + { + token first = get(); + return parse_endpoint_rest(first); + } + default: + { + error("Wanted \"subgraph\", \"{\", or identifier to start node " + "or subgraph"); + return edge_endpoint(); + } + } } - default: { - error("Wanted \"subgraph\", \"{\", or identifier to start node or subgraph"); - return edge_endpoint(); + + edge_endpoint parse_endpoint_rest(const token& first_token) + { + switch (first_token.type) + { + case token::kw_subgraph: + case token::left_brace: + return edge_endpoint::subgraph(parse_subgraph(first_token)); + default: + return edge_endpoint::node(parse_node_and_port(first_token)); + } } - } - } - edge_endpoint parse_endpoint_rest(const token& first_token) { - switch (first_token.type) { - case token::kw_subgraph: - case token::left_brace: return edge_endpoint::subgraph(parse_subgraph(first_token)); - default: return edge_endpoint::node(parse_node_and_port(first_token)); - } - } + subgraph_name parse_subgraph(const token& first_token) + { + std::string name; + bool is_anonymous = true; + if (first_token.type == token::kw_subgraph) + { + if (peek().type == token::identifier) + { + name = get().normalized_value; + is_anonymous = false; + } + } + if (is_anonymous) + { + name = "___subgraph_" + + boost::lexical_cast< std::string >(++sgcounter); + } + if (subgraphs.find(name) == subgraphs.end()) + { + subgraphs[name] + = current(); // Initialize properties and defaults + subgraphs[name].members.clear(); // Except member list + } + if (first_token.type == token::kw_subgraph + && peek().type != token::left_brace) + { + if (is_anonymous) + error("Subgraph reference needs a name"); + return name; + } + subgraph_name old_sg = current_subgraph_name; + current_subgraph_name = name; + if (peek().type == token::left_brace) + get(); + else + error("Wanted left brace to start subgraph"); + parse_stmt_list(); + if (peek().type == token::right_brace) + get(); + else + error("Wanted right brace to end subgraph"); + current_subgraph_name = old_sg; + return name; + } - subgraph_name parse_subgraph(const token& first_token) { - std::string name; - bool is_anonymous = true; - if (first_token.type == token::kw_subgraph) { - if (peek().type == token::identifier) { - name = get().normalized_value; - is_anonymous = false; - } - } - if (is_anonymous) { - name = "___subgraph_" + - boost::lexical_cast(++sgcounter); - } - if (subgraphs.find(name) == subgraphs.end()) { - subgraphs[name] = current(); // Initialize properties and defaults - subgraphs[name].members.clear(); // Except member list - } - if (first_token.type == token::kw_subgraph && peek().type != token::left_brace) { - if (is_anonymous) error("Subgraph reference needs a name"); - return name; - } - subgraph_name old_sg = current_subgraph_name; - current_subgraph_name = name; - if (peek().type == token::left_brace) get(); else error("Wanted left brace to start subgraph"); - parse_stmt_list(); - if (peek().type == token::right_brace) get(); else error("Wanted right brace to end subgraph"); - current_subgraph_name = old_sg; - return name; - } + node_and_port parse_node_and_port(const token& name) + { + // A node ID is a node name, followed optionally by a port angle and + // a port location (in either order); a port location is either :id, + // :id:id, or :(id,id); the last two forms are treated as equivalent + // although I am not sure about that. + node_and_port id; + id.name = name.normalized_value; + parse_more: + switch (peek().type) + { + case token::at: + { + get(); + if (peek().type != token::identifier) + error("Wanted identifier as port angle"); + if (id.angle != "") + error("Duplicate port angle"); + id.angle = get().normalized_value; + goto parse_more; + } + case token::colon: + { + get(); + if (!id.location.empty()) + error("Duplicate port location"); + switch (peek().type) + { + case token::identifier: + { + id.location.push_back(get().normalized_value); + switch (peek().type) + { + case token::colon: + { + get(); + if (peek().type != token::identifier) + error("Wanted identifier as port location"); + id.location.push_back(get().normalized_value); + goto parse_more; + } + default: + goto parse_more; + } + } + case token::left_paren: + { + get(); + if (peek().type != token::identifier) + error("Wanted identifier as first element of port " + "location"); + id.location.push_back(get().normalized_value); + if (peek().type != token::comma) + error("Wanted comma between parts of port location"); + get(); + if (peek().type != token::identifier) + error("Wanted identifier as second element of port " + "location"); + id.location.push_back(get().normalized_value); + if (peek().type != token::right_paren) + error( + "Wanted right parenthesis to close port location"); + get(); + goto parse_more; + } + default: + error("Wanted identifier or left parenthesis as start of " + "port location"); + } + } + default: + break; + } + if (r.nodes.find(id.name) == r.nodes.end()) + { // First mention + r.nodes[id.name] = current().def_node_props; + } + return id; + } - node_and_port parse_node_and_port(const token& name) { - // A node ID is a node name, followed optionally by a port angle and a - // port location (in either order); a port location is either :id, - // :id:id, or :(id,id); the last two forms are treated as equivalent - // although I am not sure about that. - node_and_port id; - id.name = name.normalized_value; - parse_more: - switch (peek().type) { - case token::at: { - get(); - if (peek().type != token::identifier) error("Wanted identifier as port angle"); - if (id.angle != "") error("Duplicate port angle"); - id.angle = get().normalized_value; - goto parse_more; - } - case token::colon: { - get(); - if (!id.location.empty()) error("Duplicate port location"); - switch (peek().type) { - case token::identifier: { - id.location.push_back(get().normalized_value); - switch (peek().type) { - case token::colon: { - get(); - if (peek().type != token::identifier) error("Wanted identifier as port location"); - id.location.push_back(get().normalized_value); - goto parse_more; + void parse_edge_stmt(const edge_endpoint& lhs) + { + std::vector< edge_endpoint > nodes_in_chain(1, lhs); + while (true) + { + bool leave_loop = true; + switch (peek().type) + { + case token::dash_dash: + { + if (r.graph_is_directed) + error("Using -- in directed graph"); + get(); + nodes_in_chain.push_back(parse_endpoint()); + leave_loop = false; + break; } - default: goto parse_more; - } - } - case token::left_paren: { - get(); - if (peek().type != token::identifier) error("Wanted identifier as first element of port location"); - id.location.push_back(get().normalized_value); - if (peek().type != token::comma) error("Wanted comma between parts of port location"); - get(); - if (peek().type != token::identifier) error("Wanted identifier as second element of port location"); - id.location.push_back(get().normalized_value); - if (peek().type != token::right_paren) error("Wanted right parenthesis to close port location"); - get(); - goto parse_more; - } - default: error("Wanted identifier or left parenthesis as start of port location"); - } - } - default: break; - } - if (r.nodes.find(id.name) == r.nodes.end()) { // First mention - r.nodes[id.name] = current().def_node_props; - } - return id; - } + case token::dash_greater: + { + if (!r.graph_is_directed) + error("Using -> in undirected graph"); + get(); + nodes_in_chain.push_back(parse_endpoint()); + leave_loop = false; + break; + } + default: + leave_loop = true; + break; + } + if (leave_loop) + break; + } + properties this_edge_props = current().def_edge_props; + if (peek().type == token::left_bracket) + parse_attr_list(this_edge_props); + BOOST_ASSERT(nodes_in_chain.size() + >= 2); // Should be in node parser otherwise + for (size_t i = 0; i + 1 < nodes_in_chain.size(); ++i) + { + do_orig_edge( + nodes_in_chain[i], nodes_in_chain[i + 1], this_edge_props); + } + } - void parse_edge_stmt(const edge_endpoint& lhs) { - std::vector nodes_in_chain(1, lhs); - while (true) { - bool leave_loop = true; - switch (peek().type) { - case token::dash_dash: { - if (r.graph_is_directed) error("Using -- in directed graph"); - get(); - nodes_in_chain.push_back(parse_endpoint()); - leave_loop = false; - break; - } - case token::dash_greater: { - if (!r.graph_is_directed) error("Using -> in undirected graph"); - get(); - nodes_in_chain.push_back(parse_endpoint()); - leave_loop = false; - break; - } - default: leave_loop = true; break; - } - if (leave_loop) break; - } - properties this_edge_props = current().def_edge_props; - if (peek().type == token::left_bracket) parse_attr_list(this_edge_props); - BOOST_ASSERT (nodes_in_chain.size() >= 2); // Should be in node parser otherwise - for (size_t i = 0; i + 1 < nodes_in_chain.size(); ++i) { - do_orig_edge(nodes_in_chain[i], nodes_in_chain[i + 1], this_edge_props); - } - } + // Do an edge from the file, the edge may need to be expanded if it + // connects to a subgraph + void do_orig_edge(const edge_endpoint& src, const edge_endpoint& tgt, + const properties& props) + { + std::set< node_and_port > sources = get_recursive_members(src); + std::set< node_and_port > targets = get_recursive_members(tgt); + for (std::set< node_and_port >::const_iterator i = sources.begin(); + i != sources.end(); ++i) + { + for (std::set< node_and_port >::const_iterator j + = targets.begin(); + j != targets.end(); ++j) + { + do_edge(*i, *j, props); + } + } + } - // Do an edge from the file, the edge may need to be expanded if it connects to a subgraph - void do_orig_edge(const edge_endpoint& src, const edge_endpoint& tgt, const properties& props) { - std::set sources = get_recursive_members(src); - std::set targets = get_recursive_members(tgt); - for (std::set::const_iterator i = sources.begin(); i != sources.end(); ++i) { - for (std::set::const_iterator j = targets.begin(); j != targets.end(); ++j) { - do_edge(*i, *j, props); + // Get nodes in an edge_endpoint, recursively + std::set< node_and_port > get_recursive_members( + const edge_endpoint& orig_ep) + { + std::set< node_and_port > result; + std::vector< edge_endpoint > worklist(1, orig_ep); + std::set< subgraph_name > done; + while (!worklist.empty()) + { + edge_endpoint ep = worklist.back(); + worklist.pop_back(); + if (ep.is_subgraph) + { + if (done.find(ep.subgraph_ep) == done.end()) + { + done.insert(ep.subgraph_ep); + std::map< subgraph_name, subgraph_info >::const_iterator + info_i + = subgraphs.find(ep.subgraph_ep); + if (info_i != subgraphs.end()) + { + const subgraph_member_list& members + = info_i->second.members; + for (subgraph_member_list::const_iterator i + = members.begin(); + i != members.end(); ++i) + { + node_or_subgraph_ref ref = *i; + if (ref.is_subgraph) + { + worklist.push_back( + edge_endpoint::subgraph(ref.name)); + } + else + { + node_and_port np; + np.name = ref.name; + worklist.push_back(edge_endpoint::node(np)); + } + } + } + } + } + else + { + result.insert(ep.node_ep); + } + } + return result; } - } - } - // Get nodes in an edge_endpoint, recursively - std::set get_recursive_members(const edge_endpoint& orig_ep) { - std::set result; - std::vector worklist(1, orig_ep); - std::set done; - while (!worklist.empty()) { - edge_endpoint ep = worklist.back(); - worklist.pop_back(); - if (ep.is_subgraph) { - if (done.find(ep.subgraph_ep) == done.end()) { - done.insert(ep.subgraph_ep); - std::map::const_iterator - info_i = subgraphs.find(ep.subgraph_ep); - if (info_i != subgraphs.end()) { - const subgraph_member_list& members = info_i->second.members; - for (subgraph_member_list::const_iterator i = members.begin(); - i != members.end(); ++i) { - node_or_subgraph_ref ref = *i; - if (ref.is_subgraph) { - worklist.push_back(edge_endpoint::subgraph(ref.name)); - } else { - node_and_port np; - np.name = ref.name; - worklist.push_back(edge_endpoint::node(np)); + // Do a fixed-up edge, with only nodes as endpoints + void do_edge(const node_and_port& src, const node_and_port& tgt, + const properties& props) + { + if (r.graph_is_strict) + { + if (src.name == tgt.name) + return; + std::pair< node_name, node_name > tag(src.name, tgt.name); + if (existing_edges.find(tag) != existing_edges.end()) + { + return; // Parallel edge } - } + existing_edges.insert(tag); } - } - } else { - result.insert(ep.node_ep); + edge_info e; + e.source = src; + e.target = tgt; + e.props = props; + r.edges.push_back(e); } - } - return result; - } - // Do a fixed-up edge, with only nodes as endpoints - void do_edge(const node_and_port& src, const node_and_port& tgt, const properties& props) { - if (r.graph_is_strict) { - if (src.name == tgt.name) return; - std::pair tag(src.name, tgt.name); - if (existing_edges.find(tag) != existing_edges.end()) { - return; // Parallel edge - } - existing_edges.insert(tag); - } - edge_info e; - e.source = src; - e.target = tgt; - e.props = props; - r.edges.push_back(e); - } + void parse_attr_list(properties& props) + { + while (true) + { + if (peek().type == token::left_bracket) + get(); + else + error("Wanted left bracket to start attribute list"); + while (true) + { + switch (peek().type) + { + case token::right_bracket: + break; + case token::identifier: + { + std::string lhs = get().normalized_value; + std::string rhs = "true"; + if (peek().type == token::equal) + { + get(); + if (peek().type != token::identifier) + error( + "Wanted identifier as value of attribute"); + rhs = get().normalized_value; + } + props[lhs] = rhs; + break; + } + default: + error("Wanted identifier as name of attribute"); + } + if (peek().type == token::comma + || peek().type == token::semicolon) + get(); + else if (peek().type == token::right_bracket) + break; + } + if (peek().type == token::right_bracket) + get(); + else + error("Wanted right bracket to end attribute list"); + if (peek().type != token::left_bracket) + break; + } + } + }; - void parse_attr_list(properties& props) { - while (true) { - if (peek().type == token::left_bracket) get(); else error("Wanted left bracket to start attribute list"); - while (true) { - switch (peek().type) { - case token::right_bracket: break; - case token::identifier: { - std::string lhs = get().normalized_value; - std::string rhs = "true"; - if (peek().type == token::equal) { - get(); - if (peek().type != token::identifier) error("Wanted identifier as value of attribute"); - rhs = get().normalized_value; - } - props[lhs] = rhs; - break; - } - default: error("Wanted identifier as name of attribute"); - } - if (peek().type == token::comma || peek().type == token::semicolon) get(); - else if(peek().type == token::right_bracket) break; - } - if (peek().type == token::right_bracket) get(); else error("Wanted right bracket to end attribute list"); - if (peek().type != token::left_bracket) break; - } - } - }; - - void parse_graphviz_from_string(const std::string& str, parser_result& result, bool want_directed) { - parser p(str, result); - p.parse_graph(want_directed); - } - - // Some debugging stuff - std::ostream& operator<<(std::ostream& o, const node_and_port& n) { - o << n.name; - for (size_t i = 0; i < n.location.size(); ++i) { - o << ":" << n.location[i]; - } - if (!n.angle.empty()) o << "@" << n.angle; - return o; - } - - // Can't be operator<< because properties is just an std::map - std::string props_to_string(const properties& props) { - std::string result = "["; - for (properties::const_iterator i = props.begin(); i != props.end(); ++i) { - if (i != props.begin()) result += ", "; - result += i->first + "=" + i->second; + void parse_graphviz_from_string( + const std::string& str, parser_result& result, bool want_directed) + { + parser p(str, result); + p.parse_graph(want_directed); } - result += "]"; - return result; - } - - void translate_results_to_graph(const parser_result& r, ::boost::detail::graph::mutate_graph* mg) { - typedef boost::detail::graph::edge_t edge; - for (std::map::const_iterator i = r.nodes.begin(); i != r.nodes.end(); ++i) { - // std::cerr << i->first << " " << props_to_string(i->second) << std::endl; - mg->do_add_vertex(i->first); - for (properties::const_iterator j = i->second.begin(); j != i->second.end(); ++j) { - mg->set_node_property(j->first, i->first, j->second); - } + + // Some debugging stuff + std::ostream& operator<<(std::ostream& o, const node_and_port& n) + { + o << n.name; + for (size_t i = 0; i < n.location.size(); ++i) + { + o << ":" << n.location[i]; + } + if (!n.angle.empty()) + o << "@" << n.angle; + return o; } - for (std::vector::const_iterator i = r.edges.begin(); i != r.edges.end(); ++i) { - const edge_info& ei = *i; - // std::cerr << ei.source << " -> " << ei.target << " " << props_to_string(ei.props) << std::endl; - edge e = edge::new_edge(); - mg->do_add_edge(e, ei.source.name, ei.target.name); - for (properties::const_iterator j = ei.props.begin(); j != ei.props.end(); ++j) { - mg->set_edge_property(j->first, e, j->second); - } + + // Can't be operator<< because properties is just an std::map + std::string props_to_string(const properties& props) + { + std::string result = "["; + for (properties::const_iterator i = props.begin(); i != props.end(); + ++i) + { + if (i != props.begin()) + result += ", "; + result += i->first + "=" + i->second; + } + result += "]"; + return result; } - std::map::const_iterator root_graph_props_i = r.graph_props.find("___root___"); - BOOST_ASSERT (root_graph_props_i != r.graph_props.end()); // Should not happen - const properties& root_graph_props = root_graph_props_i->second; - // std::cerr << "ending graph " << props_to_string(root_graph_props) << std::endl; - for (properties::const_iterator i = root_graph_props.begin(); i != root_graph_props.end(); ++i) { - mg->set_graph_property(i->first, i->second); + + void translate_results_to_graph( + const parser_result& r, ::boost::detail::graph::mutate_graph* mg) + { + typedef boost::detail::graph::edge_t edge; + for (std::map< node_name, properties >::const_iterator i + = r.nodes.begin(); + i != r.nodes.end(); ++i) + { + // std::cerr << i->first << " " << props_to_string(i->second) << + // std::endl; + mg->do_add_vertex(i->first); + for (properties::const_iterator j = i->second.begin(); + j != i->second.end(); ++j) + { + mg->set_node_property(j->first, i->first, j->second); + } + } + for (std::vector< edge_info >::const_iterator i = r.edges.begin(); + i != r.edges.end(); ++i) + { + const edge_info& ei = *i; + // std::cerr << ei.source << " -> " << ei.target << " " << + // props_to_string(ei.props) << std::endl; + edge e = edge::new_edge(); + mg->do_add_edge(e, ei.source.name, ei.target.name); + for (properties::const_iterator j = ei.props.begin(); + j != ei.props.end(); ++j) + { + mg->set_edge_property(j->first, e, j->second); + } + } + std::map< subgraph_name, properties >::const_iterator root_graph_props_i + = r.graph_props.find("___root___"); + BOOST_ASSERT( + root_graph_props_i != r.graph_props.end()); // Should not happen + const properties& root_graph_props = root_graph_props_i->second; + // std::cerr << "ending graph " << props_to_string(root_graph_props) << + // std::endl; + for (properties::const_iterator i = root_graph_props.begin(); + i != root_graph_props.end(); ++i) + { + mg->set_graph_property(i->first, i->second); + } + mg->finish_building_graph(); } - mg->finish_building_graph(); - } } // end namespace read_graphviz_detail -namespace detail { - namespace graph { +namespace detail +{ + namespace graph + { - BOOST_GRAPH_DECL bool read_graphviz_new(const std::string& str, boost::detail::graph::mutate_graph* mg) { - read_graphviz_detail::parser_result parsed_file; - read_graphviz_detail::parse_graphviz_from_string(str, parsed_file, mg->is_directed()); - read_graphviz_detail::translate_results_to_graph(parsed_file, mg); - return true; - } + BOOST_GRAPH_DECL bool read_graphviz_new( + const std::string& str, boost::detail::graph::mutate_graph* mg) + { + read_graphviz_detail::parser_result parsed_file; + read_graphviz_detail::parse_graphviz_from_string( + str, parsed_file, mg->is_directed()); + read_graphviz_detail::translate_results_to_graph(parsed_file, mg); + return true; + } - } // end namespace graph + } // end namespace graph } // end namespace detail } // end namespace boost diff --git a/test/Jamfile.v2 b/test/Jamfile.v2 index 25f058bf9..85dbb6612 100644 --- a/test/Jamfile.v2 +++ b/test/Jamfile.v2 @@ -7,8 +7,10 @@ # Define SGB (stanford graph base top level directory) and # LEDA (also top level directory) at the command line of jam using -s -import modules ; +import testing ; import path ; +import pch ; + path-constant TEST_DIR : . ; @@ -18,144 +20,141 @@ path-constant CYCLE_RATIO_INPUT_FILE : ./cycle_ratio_s382.90.dot ; path-constant METIS_INPUT_FILE : ./weighted_graph.gr ; +# project : requirements gcc clang ; + + +local pchs ; + +for local hpp in [ glob-tree *.hpp ] { + cpp-pch $(hpp:B) : $(hpp) : include ; + explicit $(hpp:B) ; + pchs += $(hpp:B) ; +} +alias headers : $(pchs) ; + + alias graph_test_regular : # test_graphs will eventually defined a framework for testing the structure # and implementation of graph data structures and adaptors. - [ run test_graphs.cpp ] - [ run index_graph.cpp ] # TODO: Make this part of the test_graphs framework - [ run labeled_graph.cpp ] - [ run finish_edge_bug.cpp ] - - [ run transitive_closure_test.cpp ] - [ run transitive_closure_test2.cpp ] - [ compile adj_list_cc.cpp ] - - #[ run adj_list_invalidation.cpp ] - [ run adj_list_edge_list_set.cpp ] - [ run adj_list_loops.cpp ] - [ compile adj_matrix_cc.cpp ] - [ run bfs.cpp ../../test/build//boost_test_exec_monitor ] - [ compile bfs_cc.cpp ] - [ run bellman-test.cpp ] - [ run betweenness_centrality_test.cpp : 100 ] - [ run bidir_remove_edge.cpp ] - [ run bipartite_test.cpp ] - [ run csr_graph_test.cpp : : : : : release ] - [ run dag_longest_paths.cpp ] - [ run dfs.cpp ../../test/build//boost_test_exec_monitor ] - [ run undirected_dfs.cpp ../../test/build//boost_test_exec_monitor ] - [ compile dfs_cc.cpp ] - [ compile dijkstra_cc.cpp ] - [ run dijkstra_heap_performance.cpp : 10000 ] - [ run dijkstra_no_color_map_compare.cpp : 10000 ] - [ run disjoint_set_test.cpp ] - [ run dominator_tree_test.cpp ] + [ run $(headers) test_graphs.cpp ] + [ run $(headers) index_graph.cpp ] # TODO: Make this part of the test_graphs framework + [ run $(headers) labeled_graph.cpp ] + [ run $(headers) finish_edge_bug.cpp ] + + [ run $(headers) transitive_closure_test.cpp /boost/timer//boost_timer ] + [ run $(headers) transitive_closure_test2.cpp ] + [ compile $(headers) adj_list_cc.cpp ] + + #[ run $(headers) adj_list_invalidation.cpp ] + [ run $(headers) adj_list_edge_list_set.cpp ] + [ run $(headers) adj_list_loops.cpp ] + [ compile $(headers) adj_matrix_cc.cpp ] + [ run $(headers) bfs.cpp ] + [ compile $(headers) bfs_cc.cpp ] + [ run $(headers) bellman-test.cpp ] + [ run $(headers) betweenness_centrality_test.cpp : 100 ] + [ run $(headers) bidir_remove_edge.cpp ] + [ run $(headers) bipartite_test.cpp ] + [ run $(headers) csr_graph_test.cpp : : : : : release ] + [ run $(headers) dag_longest_paths.cpp ] + [ run $(headers) dfs.cpp ] + [ run $(headers) undirected_dfs.cpp ] + [ compile $(headers) dfs_cc.cpp ] + [ compile $(headers) dijkstra_cc.cpp ] + [ run $(headers) dijkstra_heap_performance.cpp /boost/timer//boost_timer : 10000 ] + [ run $(headers) dijkstra_no_color_map_compare.cpp : 10000 ] + [ run $(headers) disjoint_set_test.cpp ] + [ run $(headers) dominator_tree_test.cpp ] # Unused and deprecated. - #[ run relaxed_heap_test.cpp : 5000 15000 ] - - [ compile edge_list_cc.cpp ] - [ compile filtered_graph_cc.cpp ] - [ run filter_graph_vp_test.cpp ] - [ run generator_test.cpp ] - [ run graph.cpp : : : TEST=1 : graph_1 ] - [ run graph.cpp : : : TEST=2 : graph_2 ] - [ run graph.cpp : : : TEST=3 : graph_3 ] - [ run graph.cpp : : : TEST=4 : graph_4 ] - [ run graph.cpp : : : TEST=5 : graph_5 ] - [ run graph.cpp : : : TEST=6 : graph_6 ] - [ run graph.cpp : : : TEST=7 : graph_7 ] - [ run graph.cpp : : : TEST=8 : graph_8 ] - [ run graph.cpp : : : TEST=9 : graph_9 ] - [ compile graph_concepts.cpp ] - [ run graphviz_test.cpp + #[ run $(headers) relaxed_heap_test.cpp : 5000 15000 ] + + [ compile $(headers) edge_list_cc.cpp ] + [ compile $(headers) filtered_graph_cc.cpp ] + [ run $(headers) filter_graph_vp_test.cpp ] + [ run $(headers) generator_test.cpp ] + [ run $(headers) graph.cpp ] + [ compile $(headers) graph_concepts.cpp ] + [ run $(headers) graphviz_test.cpp /boost/test//boost_test_exec_monitor/static ../build//boost_graph ../../regex/build//boost_regex : --log_level=all ] - [ run metis_test.cpp : $(METIS_INPUT_FILE) ] - [ run gursoy_atun_layout_test.cpp ] - [ run layout_test.cpp : : : always_show_run_output intel:off ] + [ run $(headers) metis_test.cpp : $(METIS_INPUT_FILE) ] + [ run $(headers) gursoy_atun_layout_test.cpp ] + [ run $(headers) layout_test.cpp : : : always_show_run_output intel:off ] - [ run serialize.cpp + [ run $(headers) serialize.cpp ../../serialization/build//boost_serialization : : : ] - [ compile reverse_graph_cc.cpp ] - [ run sequential_vertex_coloring.cpp ] + [ compile $(headers) reverse_graph_cc.cpp ] + [ run $(headers) sequential_vertex_coloring.cpp ] # TODO: Merge these into a single test framework. - [ run subgraph.cpp ../../test/build//boost_test_exec_monitor ] - [ run subgraph_bundled.cpp ] - [ run subgraph_add.cpp ../../test/build//boost_unit_test_framework/static : $(TEST_DIR) ] - [ run subgraph_props.cpp ] - - [ run isomorphism.cpp ../../test/build//boost_test_exec_monitor ] - [ run adjacency_matrix_test.cpp ] - [ compile vector_graph_cc.cpp ] - [ compile copy.cpp ] - [ compile swap.cpp ] - [ compile property_iter.cpp : TEST=1 : property_iter_1 ] - [ compile property_iter.cpp : TEST=2 : property_iter_2 ] - [ compile property_iter.cpp : TEST=3 : property_iter_3 ] - [ compile property_iter.cpp : TEST=4 : property_iter_4 ] - [ compile property_iter.cpp : TEST=5 : property_iter_5 ] - [ compile property_iter.cpp : TEST=6 : property_iter_6 ] - [ compile property_iter.cpp : TEST=7 : property_iter_7 ] - [ compile property_iter.cpp : TEST=8 : property_iter_8 ] - [ compile property_iter.cpp : TEST=9 : property_iter_9 ] - [ run bundled_properties.cpp ] - [ run floyd_warshall_test.cpp ] - [ run astar_search_test.cpp ] - [ run biconnected_components_test.cpp ] - [ run min_degree_empty.cpp ] - [ run cuthill_mckee_ordering.cpp ] - [ run king_ordering.cpp ] - [ run matching_test.cpp ] - [ run weighted_matching_test.cpp ] - [ run max_flow_test.cpp ] - [ run boykov_kolmogorov_max_flow_test.cpp ] - [ run cycle_ratio_tests.cpp ../build//boost_graph ../../regex/build//boost_regex : $(CYCLE_RATIO_INPUT_FILE) ] - [ run basic_planarity_test.cpp ] - [ run make_connected_test.cpp ] - [ run make_bicon_planar_test.cpp ] - [ run make_maximal_planar_test.cpp ] - [ run named_vertices_test.cpp ] - [ run r_c_shortest_paths_test.cpp ] - [ run rcsp_custom_vertex_id.cpp ] - [ run is_straight_line_draw_test.cpp ] - [ run metric_tsp_approx.cpp : metric_tsp_approx.graph ] - [ compile dimacs.cpp ] - [ run bron_kerbosch_all_cliques.cpp ] - [ run tiernan_all_cycles.cpp ] - [ run closeness_centrality.cpp ] - [ run degree_centrality.cpp ] - [ run mean_geodesic.cpp ] - [ run eccentricity.cpp ] - [ run clustering_coefficient.cpp ] - [ run core_numbers_test.cpp ] - [ run read_propmap.cpp ] - [ run mcgregor_subgraphs_test.cpp ../build//boost_graph ] - [ compile grid_graph_cc.cpp ] - [ run grid_graph_test.cpp ] - [ run incremental_components_test.cpp ] - [ run two_graphs_common_spanning_trees_test.cpp ] - [ run random_spanning_tree_test.cpp ../build//boost_graph ] - [ run random_matching_test.cpp : 1000 1020 ] - [ run graphml_test.cpp ../build//boost_graph : : "graphml_test.xml" ] - [ run mas_test.cpp ../../test/build//boost_unit_test_framework/static : $(TEST_DIR) ] - [ run stoer_wagner_test.cpp ../../test/build//boost_unit_test_framework/static : $(TEST_DIR) ] - [ compile filtered_graph_properties_dijkstra.cpp ] - [ run vf2_sub_graph_iso_test.cpp ] - [ run vf2_sub_graph_iso_test_2.cpp ] - [ run hawick_circuits.cpp ] - [ run successive_shortest_path_nonnegative_weights_test.cpp ../../test/build//boost_unit_test_framework/static ] - [ run cycle_canceling_test.cpp ../../test/build//boost_unit_test_framework/static ] - [ run strong_components_test.cpp ] - [ run find_flow_cost_bundled_properties_and_named_params_test.cpp ../../test/build//boost_unit_test_framework/static ] - [ run max_flow_algorithms_bundled_properties_and_named_params.cpp ../../test/build//boost_unit_test_framework/static ] - [ run delete_edge.cpp ] - [ run johnson-test.cpp ] - [ run lvalue_pmap.cpp ] + [ run $(headers) subgraph.cpp ] + [ run $(headers) subgraph_bundled.cpp ] + [ run $(headers) subgraph_add.cpp ../../test/build//boost_unit_test_framework/static : $(TEST_DIR) ] + [ run $(headers) subgraph_props.cpp ] + + [ run $(headers) isomorphism.cpp ] + [ run $(headers) adjacency_matrix_test.cpp ] + [ compile $(headers) vector_graph_cc.cpp ] + [ compile $(headers) copy.cpp ] + [ compile $(headers) swap.cpp ] + [ compile $(headers) property_iter.cpp ] + [ run $(headers) bundled_properties.cpp ] + [ run $(headers) floyd_warshall_test.cpp ] + [ run $(headers) astar_search_test.cpp ] + [ run $(headers) biconnected_components_test.cpp ] + [ run $(headers) min_degree_empty.cpp ] + [ run $(headers) cuthill_mckee_ordering.cpp ] + [ run $(headers) king_ordering.cpp ] + [ run $(headers) matching_test.cpp ] + [ run $(headers) weighted_matching_test.cpp ] + [ run $(headers) max_flow_test.cpp ] + [ run $(headers) boykov_kolmogorov_max_flow_test.cpp ] + [ run $(headers) cycle_ratio_tests.cpp ../build//boost_graph ../../regex/build//boost_regex : $(CYCLE_RATIO_INPUT_FILE) ] + [ run $(headers) basic_planarity_test.cpp ] + [ run $(headers) make_connected_test.cpp ] + [ run $(headers) make_bicon_planar_test.cpp ] + [ run $(headers) make_maximal_planar_test.cpp ] + [ run $(headers) named_vertices_test.cpp ] + [ run $(headers) r_c_shortest_paths_test.cpp ] + [ run $(headers) rcsp_custom_vertex_id.cpp ] + [ run $(headers) is_straight_line_draw_test.cpp ] + [ run $(headers) metric_tsp_approx.cpp /boost/timer//boost_timer : metric_tsp_approx.graph : : ] + [ compile $(headers) dimacs.cpp ] + [ run $(headers) bron_kerbosch_all_cliques.cpp ] + [ run $(headers) tiernan_all_cycles.cpp ] + [ run $(headers) closeness_centrality.cpp ] + [ run $(headers) degree_centrality.cpp ] + [ run $(headers) mean_geodesic.cpp ] + [ run $(headers) eccentricity.cpp ] + [ run $(headers) clustering_coefficient.cpp ] + [ run $(headers) core_numbers_test.cpp ] + [ run $(headers) read_propmap.cpp ] + [ run $(headers) mcgregor_subgraphs_test.cpp ../build//boost_graph ] + [ compile $(headers) grid_graph_cc.cpp ] + [ run $(headers) grid_graph_test.cpp ] + [ run $(headers) incremental_components_test.cpp ] + [ run $(headers) two_graphs_common_spanning_trees_test.cpp ] + [ run $(headers) random_spanning_tree_test.cpp ../build//boost_graph ] + [ run $(headers) random_matching_test.cpp : 1000 1020 ] + [ run $(headers) graphml_test.cpp ../build//boost_graph : : "graphml_test.xml" ] + [ run $(headers) mas_test.cpp ../../test/build//boost_unit_test_framework/static : $(TEST_DIR) ] + [ run $(headers) stoer_wagner_test.cpp ../../test/build//boost_unit_test_framework/static : $(TEST_DIR) ] + [ compile $(headers) filtered_graph_properties_dijkstra.cpp ] + [ run $(headers) vf2_sub_graph_iso_test.cpp ] + [ run $(headers) vf2_sub_graph_iso_test_2.cpp ] + [ run $(headers) hawick_circuits.cpp ] + [ run $(headers) successive_shortest_path_nonnegative_weights_test.cpp ../../test/build//boost_unit_test_framework/static ] + [ run $(headers) cycle_canceling_test.cpp ../../test/build//boost_unit_test_framework/static ] + [ run $(headers) strong_components_test.cpp ] + [ run $(headers) find_flow_cost_bundled_properties_and_named_params_test.cpp ../../test/build//boost_unit_test_framework/static ] + [ run $(headers) max_flow_algorithms_bundled_properties_and_named_params.cpp ../../test/build//boost_unit_test_framework/static ] + [ run $(headers) delete_edge.cpp ] + [ run $(headers) johnson-test.cpp ] + [ run $(headers) lvalue_pmap.cpp ] ; alias graph_test_with_filesystem : : @@ -166,11 +165,11 @@ alias graph_test_with_filesystem : : ; alias graph_test_with_filesystem : - [ run all_planar_input_files_test.cpp + [ run $(headers) all_planar_input_files_test.cpp ../../filesystem/build ../../system/build : $(PLANAR_INPUT_FILES) ] - [ run parallel_edges_loops_test.cpp + [ run $(headers) parallel_edges_loops_test.cpp ../../filesystem/build ../../system/build : $(PLANAR_INPUT_FILES) ] diff --git a/test/adj_list_cc.cpp b/test/adj_list_cc.cpp index 32de32863..6bcb64d8b 100644 --- a/test/adj_list_cc.cpp +++ b/test/adj_list_cc.cpp @@ -11,232 +11,225 @@ #include #include -int main(int,char*[]) +int main(int, char*[]) { - using namespace boost; - // Check adjacency_list with properties - { - typedef adjacency_list, - property - > Graph; - typedef graph_traits::vertex_descriptor Vertex; - typedef graph_traits::edge_descriptor Edge; - BOOST_CONCEPT_ASSERT(( VertexListGraphConcept )); - BOOST_CONCEPT_ASSERT(( EdgeListGraphConcept )); - BOOST_CONCEPT_ASSERT(( IncidenceGraphConcept )); - BOOST_CONCEPT_ASSERT(( AdjacencyGraphConcept )); - BOOST_CONCEPT_ASSERT(( MutableIncidenceGraphConcept )); - BOOST_CONCEPT_ASSERT(( MutableEdgeListGraphConcept )); - BOOST_CONCEPT_ASSERT(( VertexMutablePropertyGraphConcept )); - BOOST_CONCEPT_ASSERT(( EdgeMutablePropertyGraphConcept )); - BOOST_CONCEPT_ASSERT(( - ReadablePropertyGraphConcept )); - BOOST_CONCEPT_ASSERT(( - LvaluePropertyGraphConcept )); - BOOST_CONCEPT_ASSERT(( - LvaluePropertyGraphConcept )); - } - { - typedef adjacency_list, - property - > Graph; - typedef graph_traits::vertex_descriptor Vertex; - typedef graph_traits::edge_descriptor Edge; - BOOST_CONCEPT_ASSERT(( VertexListGraphConcept )); - BOOST_CONCEPT_ASSERT(( EdgeListGraphConcept )); - BOOST_CONCEPT_ASSERT(( IncidenceGraphConcept )); - BOOST_CONCEPT_ASSERT(( AdjacencyGraphConcept )); - BOOST_CONCEPT_ASSERT(( BidirectionalGraphConcept )); - BOOST_CONCEPT_ASSERT(( MutableBidirectionalGraphConcept )); - BOOST_CONCEPT_ASSERT(( MutableEdgeListGraphConcept )); - BOOST_CONCEPT_ASSERT(( VertexMutablePropertyGraphConcept )); - BOOST_CONCEPT_ASSERT(( EdgeMutablePropertyGraphConcept )); - BOOST_CONCEPT_ASSERT(( - ReadablePropertyGraphConcept )); - BOOST_CONCEPT_ASSERT(( - LvaluePropertyGraphConcept )); - BOOST_CONCEPT_ASSERT(( - LvaluePropertyGraphConcept )); - } - { - typedef adjacency_list< listS, listS, directedS, - property, - property - > Graph; - typedef graph_traits::vertex_descriptor Vertex; - typedef graph_traits::edge_descriptor Edge; - BOOST_CONCEPT_ASSERT(( VertexListGraphConcept )); - BOOST_CONCEPT_ASSERT(( EdgeListGraphConcept )); - BOOST_CONCEPT_ASSERT(( IncidenceGraphConcept )); - BOOST_CONCEPT_ASSERT(( AdjacencyGraphConcept )); - BOOST_CONCEPT_ASSERT(( MutableIncidenceGraphConcept )); - BOOST_CONCEPT_ASSERT(( MutableEdgeListGraphConcept )); - BOOST_CONCEPT_ASSERT(( VertexMutablePropertyGraphConcept )); - BOOST_CONCEPT_ASSERT(( EdgeMutablePropertyGraphConcept )); - BOOST_CONCEPT_ASSERT(( - LvaluePropertyGraphConcept )); - BOOST_CONCEPT_ASSERT(( - LvaluePropertyGraphConcept )); - } - { - typedef adjacency_list< listS, listS, undirectedS, - property, - property - > Graph; - typedef graph_traits::vertex_descriptor Vertex; - typedef graph_traits::edge_descriptor Edge; - BOOST_CONCEPT_ASSERT(( VertexListGraphConcept )); - BOOST_CONCEPT_ASSERT(( EdgeListGraphConcept )); - BOOST_CONCEPT_ASSERT(( IncidenceGraphConcept )); - BOOST_CONCEPT_ASSERT(( AdjacencyGraphConcept )); - BOOST_CONCEPT_ASSERT(( MutableBidirectionalGraphConcept )); - BOOST_CONCEPT_ASSERT(( MutableEdgeListGraphConcept )); - BOOST_CONCEPT_ASSERT(( VertexMutablePropertyGraphConcept )); - BOOST_CONCEPT_ASSERT(( EdgeMutablePropertyGraphConcept )); - BOOST_CONCEPT_ASSERT(( - LvaluePropertyGraphConcept )); - BOOST_CONCEPT_ASSERT(( - LvaluePropertyGraphConcept )); - } - // Checking adjacency_list with EdgeList=setS - { - typedef adjacency_list, - property - > Graph; - typedef graph_traits::vertex_descriptor Vertex; - typedef graph_traits::edge_descriptor Edge; - BOOST_CONCEPT_ASSERT(( VertexListGraphConcept )); - BOOST_CONCEPT_ASSERT(( EdgeListGraphConcept )); - BOOST_CONCEPT_ASSERT(( IncidenceGraphConcept )); - BOOST_CONCEPT_ASSERT(( AdjacencyGraphConcept )); - BOOST_CONCEPT_ASSERT(( BidirectionalGraphConcept )); - BOOST_CONCEPT_ASSERT(( MutableBidirectionalGraphConcept )); - BOOST_CONCEPT_ASSERT(( MutableEdgeListGraphConcept )); - BOOST_CONCEPT_ASSERT(( VertexMutablePropertyGraphConcept )); - BOOST_CONCEPT_ASSERT(( EdgeMutablePropertyGraphConcept )); - BOOST_CONCEPT_ASSERT(( - ReadablePropertyGraphConcept )); - BOOST_CONCEPT_ASSERT(( - LvaluePropertyGraphConcept )); - BOOST_CONCEPT_ASSERT(( - LvaluePropertyGraphConcept )); - } - { - typedef adjacency_list< setS, listS, directedS, - property, - property - > Graph; - typedef graph_traits::vertex_descriptor Vertex; - typedef graph_traits::edge_descriptor Edge; - BOOST_CONCEPT_ASSERT(( VertexListGraphConcept )); - BOOST_CONCEPT_ASSERT(( EdgeListGraphConcept )); - BOOST_CONCEPT_ASSERT(( IncidenceGraphConcept )); - BOOST_CONCEPT_ASSERT(( AdjacencyGraphConcept )); - BOOST_CONCEPT_ASSERT(( MutableIncidenceGraphConcept )); - BOOST_CONCEPT_ASSERT(( MutableEdgeListGraphConcept )); - BOOST_CONCEPT_ASSERT(( VertexMutablePropertyGraphConcept )); - BOOST_CONCEPT_ASSERT(( EdgeMutablePropertyGraphConcept )); - BOOST_CONCEPT_ASSERT(( - LvaluePropertyGraphConcept )); - BOOST_CONCEPT_ASSERT(( - LvaluePropertyGraphConcept )); - } - { - typedef adjacency_list< setS, listS, undirectedS, - property, - property - > Graph; - typedef graph_traits::vertex_descriptor Vertex; - typedef graph_traits::edge_descriptor Edge; - BOOST_CONCEPT_ASSERT(( VertexListGraphConcept )); - BOOST_CONCEPT_ASSERT(( EdgeListGraphConcept )); - BOOST_CONCEPT_ASSERT(( IncidenceGraphConcept )); - BOOST_CONCEPT_ASSERT(( AdjacencyGraphConcept )); - BOOST_CONCEPT_ASSERT(( MutableBidirectionalGraphConcept )); - BOOST_CONCEPT_ASSERT(( MutableEdgeListGraphConcept )); - BOOST_CONCEPT_ASSERT(( VertexMutablePropertyGraphConcept )); - BOOST_CONCEPT_ASSERT(( EdgeMutablePropertyGraphConcept )); - BOOST_CONCEPT_ASSERT(( - LvaluePropertyGraphConcept )); - BOOST_CONCEPT_ASSERT(( - LvaluePropertyGraphConcept )); - } - // Check adjacency_list without any properties - { - typedef adjacency_list Graph; - typedef graph_traits::vertex_descriptor Vertex; - BOOST_CONCEPT_ASSERT(( VertexListGraphConcept )); - BOOST_CONCEPT_ASSERT(( EdgeListGraphConcept )); - BOOST_CONCEPT_ASSERT(( IncidenceGraphConcept )); - BOOST_CONCEPT_ASSERT(( AdjacencyGraphConcept )); - BOOST_CONCEPT_ASSERT(( MutableIncidenceGraphConcept )); - BOOST_CONCEPT_ASSERT(( MutableEdgeListGraphConcept )); - BOOST_CONCEPT_ASSERT(( VertexMutablePropertyGraphConcept )); - BOOST_CONCEPT_ASSERT(( EdgeMutablePropertyGraphConcept )); - BOOST_CONCEPT_ASSERT(( - ReadablePropertyGraphConcept )); - } - { - typedef adjacency_list Graph; - typedef graph_traits::vertex_descriptor Vertex; - BOOST_CONCEPT_ASSERT(( VertexListGraphConcept )); - BOOST_CONCEPT_ASSERT(( EdgeListGraphConcept )); - BOOST_CONCEPT_ASSERT(( IncidenceGraphConcept )); - BOOST_CONCEPT_ASSERT(( AdjacencyGraphConcept )); - BOOST_CONCEPT_ASSERT(( BidirectionalGraphConcept )); - BOOST_CONCEPT_ASSERT(( MutableBidirectionalGraphConcept )); - BOOST_CONCEPT_ASSERT(( MutableEdgeListGraphConcept )); - BOOST_CONCEPT_ASSERT(( - ReadablePropertyGraphConcept )); - } - { - typedef adjacency_list< listS, listS, directedS> Graph; - BOOST_CONCEPT_ASSERT(( VertexListGraphConcept )); - BOOST_CONCEPT_ASSERT(( EdgeListGraphConcept )); - BOOST_CONCEPT_ASSERT(( IncidenceGraphConcept )); - BOOST_CONCEPT_ASSERT(( AdjacencyGraphConcept )); - BOOST_CONCEPT_ASSERT(( MutableIncidenceGraphConcept )); - BOOST_CONCEPT_ASSERT(( MutableEdgeListGraphConcept )); - } - { - typedef adjacency_list< listS, listS, undirectedS> Graph; - BOOST_CONCEPT_ASSERT(( VertexListGraphConcept )); - BOOST_CONCEPT_ASSERT(( EdgeListGraphConcept )); - BOOST_CONCEPT_ASSERT(( IncidenceGraphConcept )); - BOOST_CONCEPT_ASSERT(( AdjacencyGraphConcept )); - BOOST_CONCEPT_ASSERT(( MutableBidirectionalGraphConcept )); - BOOST_CONCEPT_ASSERT(( MutableEdgeListGraphConcept )); - } - // Checking EdgeList=setS with no properties - { - typedef adjacency_list Graph; - typedef graph_traits::vertex_descriptor Vertex; - BOOST_CONCEPT_ASSERT(( VertexListGraphConcept )); - BOOST_CONCEPT_ASSERT(( EdgeListGraphConcept )); - BOOST_CONCEPT_ASSERT(( IncidenceGraphConcept )); - BOOST_CONCEPT_ASSERT(( AdjacencyGraphConcept )); - BOOST_CONCEPT_ASSERT(( BidirectionalGraphConcept )); - BOOST_CONCEPT_ASSERT(( MutableBidirectionalGraphConcept )); - BOOST_CONCEPT_ASSERT(( MutableEdgeListGraphConcept )); - BOOST_CONCEPT_ASSERT(( ReadablePropertyGraphConcept )); - } - { - typedef adjacency_list< setS, listS, directedS> Graph; - BOOST_CONCEPT_ASSERT(( MutableIncidenceGraphConcept )); - BOOST_CONCEPT_ASSERT(( MutableEdgeListGraphConcept )); - } - { - typedef adjacency_list< setS, listS, undirectedS> Graph; - BOOST_CONCEPT_ASSERT(( VertexListGraphConcept )); - BOOST_CONCEPT_ASSERT(( EdgeListGraphConcept )); - BOOST_CONCEPT_ASSERT(( IncidenceGraphConcept )); - BOOST_CONCEPT_ASSERT(( AdjacencyGraphConcept )); - BOOST_CONCEPT_ASSERT(( MutableBidirectionalGraphConcept )); - BOOST_CONCEPT_ASSERT(( MutableEdgeListGraphConcept )); - } - return 0; + using namespace boost; + // Check adjacency_list with properties + { + typedef adjacency_list< vecS, vecS, directedS, + property< vertex_color_t, int >, property< edge_weight_t, int > > + Graph; + typedef graph_traits< Graph >::vertex_descriptor Vertex; + typedef graph_traits< Graph >::edge_descriptor Edge; + BOOST_CONCEPT_ASSERT((VertexListGraphConcept< Graph >)); + BOOST_CONCEPT_ASSERT((EdgeListGraphConcept< Graph >)); + BOOST_CONCEPT_ASSERT((IncidenceGraphConcept< Graph >)); + BOOST_CONCEPT_ASSERT((AdjacencyGraphConcept< Graph >)); + BOOST_CONCEPT_ASSERT((MutableIncidenceGraphConcept< Graph >)); + BOOST_CONCEPT_ASSERT((MutableEdgeListGraphConcept< Graph >)); + BOOST_CONCEPT_ASSERT((VertexMutablePropertyGraphConcept< Graph >)); + BOOST_CONCEPT_ASSERT((EdgeMutablePropertyGraphConcept< Graph >)); + BOOST_CONCEPT_ASSERT( + (ReadablePropertyGraphConcept< Graph, Vertex, vertex_index_t >)); + BOOST_CONCEPT_ASSERT( + (LvaluePropertyGraphConcept< Graph, Vertex, vertex_color_t >)); + BOOST_CONCEPT_ASSERT( + (LvaluePropertyGraphConcept< Graph, Edge, edge_weight_t >)); + } + { + typedef adjacency_list< vecS, vecS, bidirectionalS, + property< vertex_color_t, int >, property< edge_weight_t, int > > + Graph; + typedef graph_traits< Graph >::vertex_descriptor Vertex; + typedef graph_traits< Graph >::edge_descriptor Edge; + BOOST_CONCEPT_ASSERT((VertexListGraphConcept< Graph >)); + BOOST_CONCEPT_ASSERT((EdgeListGraphConcept< Graph >)); + BOOST_CONCEPT_ASSERT((IncidenceGraphConcept< Graph >)); + BOOST_CONCEPT_ASSERT((AdjacencyGraphConcept< Graph >)); + BOOST_CONCEPT_ASSERT((BidirectionalGraphConcept< Graph >)); + BOOST_CONCEPT_ASSERT((MutableBidirectionalGraphConcept< Graph >)); + BOOST_CONCEPT_ASSERT((MutableEdgeListGraphConcept< Graph >)); + BOOST_CONCEPT_ASSERT((VertexMutablePropertyGraphConcept< Graph >)); + BOOST_CONCEPT_ASSERT((EdgeMutablePropertyGraphConcept< Graph >)); + BOOST_CONCEPT_ASSERT( + (ReadablePropertyGraphConcept< Graph, Vertex, vertex_index_t >)); + BOOST_CONCEPT_ASSERT( + (LvaluePropertyGraphConcept< Graph, Vertex, vertex_color_t >)); + BOOST_CONCEPT_ASSERT( + (LvaluePropertyGraphConcept< Graph, Edge, edge_weight_t >)); + } + { + typedef adjacency_list< listS, listS, directedS, + property< vertex_color_t, int >, property< edge_weight_t, int > > + Graph; + typedef graph_traits< Graph >::vertex_descriptor Vertex; + typedef graph_traits< Graph >::edge_descriptor Edge; + BOOST_CONCEPT_ASSERT((VertexListGraphConcept< Graph >)); + BOOST_CONCEPT_ASSERT((EdgeListGraphConcept< Graph >)); + BOOST_CONCEPT_ASSERT((IncidenceGraphConcept< Graph >)); + BOOST_CONCEPT_ASSERT((AdjacencyGraphConcept< Graph >)); + BOOST_CONCEPT_ASSERT((MutableIncidenceGraphConcept< Graph >)); + BOOST_CONCEPT_ASSERT((MutableEdgeListGraphConcept< Graph >)); + BOOST_CONCEPT_ASSERT((VertexMutablePropertyGraphConcept< Graph >)); + BOOST_CONCEPT_ASSERT((EdgeMutablePropertyGraphConcept< Graph >)); + BOOST_CONCEPT_ASSERT( + (LvaluePropertyGraphConcept< Graph, Vertex, vertex_color_t >)); + BOOST_CONCEPT_ASSERT( + (LvaluePropertyGraphConcept< Graph, Edge, edge_weight_t >)); + } + { + typedef adjacency_list< listS, listS, undirectedS, + property< vertex_color_t, int >, property< edge_weight_t, int > > + Graph; + typedef graph_traits< Graph >::vertex_descriptor Vertex; + typedef graph_traits< Graph >::edge_descriptor Edge; + BOOST_CONCEPT_ASSERT((VertexListGraphConcept< Graph >)); + BOOST_CONCEPT_ASSERT((EdgeListGraphConcept< Graph >)); + BOOST_CONCEPT_ASSERT((IncidenceGraphConcept< Graph >)); + BOOST_CONCEPT_ASSERT((AdjacencyGraphConcept< Graph >)); + BOOST_CONCEPT_ASSERT((MutableBidirectionalGraphConcept< Graph >)); + BOOST_CONCEPT_ASSERT((MutableEdgeListGraphConcept< Graph >)); + BOOST_CONCEPT_ASSERT((VertexMutablePropertyGraphConcept< Graph >)); + BOOST_CONCEPT_ASSERT((EdgeMutablePropertyGraphConcept< Graph >)); + BOOST_CONCEPT_ASSERT( + (LvaluePropertyGraphConcept< Graph, Vertex, vertex_color_t >)); + BOOST_CONCEPT_ASSERT( + (LvaluePropertyGraphConcept< Graph, Edge, edge_weight_t >)); + } + // Checking adjacency_list with EdgeList=setS + { + typedef adjacency_list< setS, vecS, bidirectionalS, + property< vertex_color_t, int >, property< edge_weight_t, int > > + Graph; + typedef graph_traits< Graph >::vertex_descriptor Vertex; + typedef graph_traits< Graph >::edge_descriptor Edge; + BOOST_CONCEPT_ASSERT((VertexListGraphConcept< Graph >)); + BOOST_CONCEPT_ASSERT((EdgeListGraphConcept< Graph >)); + BOOST_CONCEPT_ASSERT((IncidenceGraphConcept< Graph >)); + BOOST_CONCEPT_ASSERT((AdjacencyGraphConcept< Graph >)); + BOOST_CONCEPT_ASSERT((BidirectionalGraphConcept< Graph >)); + BOOST_CONCEPT_ASSERT((MutableBidirectionalGraphConcept< Graph >)); + BOOST_CONCEPT_ASSERT((MutableEdgeListGraphConcept< Graph >)); + BOOST_CONCEPT_ASSERT((VertexMutablePropertyGraphConcept< Graph >)); + BOOST_CONCEPT_ASSERT((EdgeMutablePropertyGraphConcept< Graph >)); + BOOST_CONCEPT_ASSERT( + (ReadablePropertyGraphConcept< Graph, Vertex, vertex_index_t >)); + BOOST_CONCEPT_ASSERT( + (LvaluePropertyGraphConcept< Graph, Vertex, vertex_color_t >)); + BOOST_CONCEPT_ASSERT( + (LvaluePropertyGraphConcept< Graph, Edge, edge_weight_t >)); + } + { + typedef adjacency_list< setS, listS, directedS, + property< vertex_color_t, int >, property< edge_weight_t, int > > + Graph; + typedef graph_traits< Graph >::vertex_descriptor Vertex; + typedef graph_traits< Graph >::edge_descriptor Edge; + BOOST_CONCEPT_ASSERT((VertexListGraphConcept< Graph >)); + BOOST_CONCEPT_ASSERT((EdgeListGraphConcept< Graph >)); + BOOST_CONCEPT_ASSERT((IncidenceGraphConcept< Graph >)); + BOOST_CONCEPT_ASSERT((AdjacencyGraphConcept< Graph >)); + BOOST_CONCEPT_ASSERT((MutableIncidenceGraphConcept< Graph >)); + BOOST_CONCEPT_ASSERT((MutableEdgeListGraphConcept< Graph >)); + BOOST_CONCEPT_ASSERT((VertexMutablePropertyGraphConcept< Graph >)); + BOOST_CONCEPT_ASSERT((EdgeMutablePropertyGraphConcept< Graph >)); + BOOST_CONCEPT_ASSERT( + (LvaluePropertyGraphConcept< Graph, Vertex, vertex_color_t >)); + BOOST_CONCEPT_ASSERT( + (LvaluePropertyGraphConcept< Graph, Edge, edge_weight_t >)); + } + { + typedef adjacency_list< setS, listS, undirectedS, + property< vertex_color_t, int >, property< edge_weight_t, int > > + Graph; + typedef graph_traits< Graph >::vertex_descriptor Vertex; + typedef graph_traits< Graph >::edge_descriptor Edge; + BOOST_CONCEPT_ASSERT((VertexListGraphConcept< Graph >)); + BOOST_CONCEPT_ASSERT((EdgeListGraphConcept< Graph >)); + BOOST_CONCEPT_ASSERT((IncidenceGraphConcept< Graph >)); + BOOST_CONCEPT_ASSERT((AdjacencyGraphConcept< Graph >)); + BOOST_CONCEPT_ASSERT((MutableBidirectionalGraphConcept< Graph >)); + BOOST_CONCEPT_ASSERT((MutableEdgeListGraphConcept< Graph >)); + BOOST_CONCEPT_ASSERT((VertexMutablePropertyGraphConcept< Graph >)); + BOOST_CONCEPT_ASSERT((EdgeMutablePropertyGraphConcept< Graph >)); + BOOST_CONCEPT_ASSERT( + (LvaluePropertyGraphConcept< Graph, Vertex, vertex_color_t >)); + BOOST_CONCEPT_ASSERT( + (LvaluePropertyGraphConcept< Graph, Edge, edge_weight_t >)); + } + // Check adjacency_list without any properties + { + typedef adjacency_list< vecS, vecS, directedS > Graph; + typedef graph_traits< Graph >::vertex_descriptor Vertex; + BOOST_CONCEPT_ASSERT((VertexListGraphConcept< Graph >)); + BOOST_CONCEPT_ASSERT((EdgeListGraphConcept< Graph >)); + BOOST_CONCEPT_ASSERT((IncidenceGraphConcept< Graph >)); + BOOST_CONCEPT_ASSERT((AdjacencyGraphConcept< Graph >)); + BOOST_CONCEPT_ASSERT((MutableIncidenceGraphConcept< Graph >)); + BOOST_CONCEPT_ASSERT((MutableEdgeListGraphConcept< Graph >)); + BOOST_CONCEPT_ASSERT((VertexMutablePropertyGraphConcept< Graph >)); + BOOST_CONCEPT_ASSERT((EdgeMutablePropertyGraphConcept< Graph >)); + BOOST_CONCEPT_ASSERT( + (ReadablePropertyGraphConcept< Graph, Vertex, vertex_index_t >)); + } + { + typedef adjacency_list< vecS, vecS, bidirectionalS > Graph; + typedef graph_traits< Graph >::vertex_descriptor Vertex; + BOOST_CONCEPT_ASSERT((VertexListGraphConcept< Graph >)); + BOOST_CONCEPT_ASSERT((EdgeListGraphConcept< Graph >)); + BOOST_CONCEPT_ASSERT((IncidenceGraphConcept< Graph >)); + BOOST_CONCEPT_ASSERT((AdjacencyGraphConcept< Graph >)); + BOOST_CONCEPT_ASSERT((BidirectionalGraphConcept< Graph >)); + BOOST_CONCEPT_ASSERT((MutableBidirectionalGraphConcept< Graph >)); + BOOST_CONCEPT_ASSERT((MutableEdgeListGraphConcept< Graph >)); + BOOST_CONCEPT_ASSERT( + (ReadablePropertyGraphConcept< Graph, Vertex, vertex_index_t >)); + } + { + typedef adjacency_list< listS, listS, directedS > Graph; + BOOST_CONCEPT_ASSERT((VertexListGraphConcept< Graph >)); + BOOST_CONCEPT_ASSERT((EdgeListGraphConcept< Graph >)); + BOOST_CONCEPT_ASSERT((IncidenceGraphConcept< Graph >)); + BOOST_CONCEPT_ASSERT((AdjacencyGraphConcept< Graph >)); + BOOST_CONCEPT_ASSERT((MutableIncidenceGraphConcept< Graph >)); + BOOST_CONCEPT_ASSERT((MutableEdgeListGraphConcept< Graph >)); + } + { + typedef adjacency_list< listS, listS, undirectedS > Graph; + BOOST_CONCEPT_ASSERT((VertexListGraphConcept< Graph >)); + BOOST_CONCEPT_ASSERT((EdgeListGraphConcept< Graph >)); + BOOST_CONCEPT_ASSERT((IncidenceGraphConcept< Graph >)); + BOOST_CONCEPT_ASSERT((AdjacencyGraphConcept< Graph >)); + BOOST_CONCEPT_ASSERT((MutableBidirectionalGraphConcept< Graph >)); + BOOST_CONCEPT_ASSERT((MutableEdgeListGraphConcept< Graph >)); + } + // Checking EdgeList=setS with no properties + { + typedef adjacency_list< setS, vecS, bidirectionalS > Graph; + typedef graph_traits< Graph >::vertex_descriptor Vertex; + BOOST_CONCEPT_ASSERT((VertexListGraphConcept< Graph >)); + BOOST_CONCEPT_ASSERT((EdgeListGraphConcept< Graph >)); + BOOST_CONCEPT_ASSERT((IncidenceGraphConcept< Graph >)); + BOOST_CONCEPT_ASSERT((AdjacencyGraphConcept< Graph >)); + BOOST_CONCEPT_ASSERT((BidirectionalGraphConcept< Graph >)); + BOOST_CONCEPT_ASSERT((MutableBidirectionalGraphConcept< Graph >)); + BOOST_CONCEPT_ASSERT((MutableEdgeListGraphConcept< Graph >)); + BOOST_CONCEPT_ASSERT( + (ReadablePropertyGraphConcept< Graph, Vertex, vertex_index_t >)); + } + { + typedef adjacency_list< setS, listS, directedS > Graph; + BOOST_CONCEPT_ASSERT((MutableIncidenceGraphConcept< Graph >)); + BOOST_CONCEPT_ASSERT((MutableEdgeListGraphConcept< Graph >)); + } + { + typedef adjacency_list< setS, listS, undirectedS > Graph; + BOOST_CONCEPT_ASSERT((VertexListGraphConcept< Graph >)); + BOOST_CONCEPT_ASSERT((EdgeListGraphConcept< Graph >)); + BOOST_CONCEPT_ASSERT((IncidenceGraphConcept< Graph >)); + BOOST_CONCEPT_ASSERT((AdjacencyGraphConcept< Graph >)); + BOOST_CONCEPT_ASSERT((MutableBidirectionalGraphConcept< Graph >)); + BOOST_CONCEPT_ASSERT((MutableEdgeListGraphConcept< Graph >)); + } + return 0; } diff --git a/test/adj_list_edge_list_set.cpp b/test/adj_list_edge_list_set.cpp index 2d65bb03f..d2f956bbb 100644 --- a/test/adj_list_edge_list_set.cpp +++ b/test/adj_list_edge_list_set.cpp @@ -9,17 +9,17 @@ // Make sure adjacency_list works with EdgeListS=setS #include -#include using namespace boost; -typedef adjacency_list GraphType; +typedef adjacency_list< vecS, vecS, undirectedS, no_property, no_property, + no_property, setS > + GraphType; -int test_main(int,char*[]) +int main(int, char*[]) { - GraphType g(10); - add_vertex(g); - add_edge(0, 5, g); - return 0; + GraphType g(10); + add_vertex(g); + add_edge(0, 5, g); + return 0; } diff --git a/test/adj_list_invalidation.cpp b/test/adj_list_invalidation.cpp index 8d63d6d4f..3ee7bcc26 100644 --- a/test/adj_list_invalidation.cpp +++ b/test/adj_list_invalidation.cpp @@ -6,7 +6,7 @@ /*********************************************************** -IMPORTANT: this file should not be tested - it creates invalid graphs/sequences +IMPORTANT: this file should not be tested - it creates invalid graphs/sequences which *do* crash at runtime - this seems to be the intent, but it's not clear why or whether the file should be retained. @@ -24,34 +24,32 @@ using namespace boost; // The purpose of this test is simply to provide a testing ground for the // invalidation of iterators and descriptors. -template -void make_graph(Graph& g) +template < typename Graph > void make_graph(Graph& g) { // Build a simple (barbell) graph. - typedef typename graph_traits::vertex_descriptor Vertex; + typedef typename graph_traits< Graph >::vertex_descriptor Vertex; Vertex u = add_vertex(10, g); Vertex v = add_vertex(20, g); add_edge(u, v, 100, g); } // Invalid iterators and descriptors will cause a segfault. -template +template < typename Graph, typename Iterator, typename Descriptor > void test(Graph& g, Iterator i, Descriptor d, string const& str) { int x; cout << "... " << str << " iter" << endl; x = g[*i]; -// cout << "... " << x << endl; + // cout << "... " << x << endl; cout << "... " << str << " desc" << endl; x = g[d]; -// cout << "... " << x << endl; + // cout << "... " << x << endl; } -template -void invalidate_edges() +template < typename Graph > void invalidate_edges() { - typedef typename graph_traits::edge_descriptor Edge; - typedef typename graph_traits::edge_iterator EdgeIterator; + typedef typename graph_traits< Graph >::edge_descriptor Edge; + typedef typename graph_traits< Graph >::edge_iterator EdgeIterator; Graph g; make_graph(g); @@ -65,11 +63,10 @@ void invalidate_edges() test(g, i, e, "edges"); }; -template -void invalidate_vertices() +template < typename Graph > void invalidate_vertices() { - typedef typename graph_traits::vertex_descriptor Vertex; - typedef typename graph_traits::vertex_iterator VertexIterator; + typedef typename graph_traits< Graph >::vertex_descriptor Vertex; + typedef typename graph_traits< Graph >::vertex_iterator VertexIterator; Graph g; make_graph(g); @@ -83,11 +80,10 @@ void invalidate_vertices() test(g, i, v, "vertices"); } -template -void invalidate_out_edges() +template < typename Graph > void invalidate_out_edges() { - typedef typename graph_traits::edge_descriptor Edge; - typedef typename graph_traits::out_edge_iterator OutIterator; + typedef typename graph_traits< Graph >::edge_descriptor Edge; + typedef typename graph_traits< Graph >::out_edge_iterator OutIterator; Graph g; make_graph(g); @@ -101,11 +97,10 @@ void invalidate_out_edges() test(g, i, e, "out edges"); } -template -void invalidate_adj_verts() +template < typename Graph > void invalidate_adj_verts() { - typedef typename graph_traits::vertex_descriptor Vertex; - typedef typename graph_traits::adjacency_iterator AdjIterator; + typedef typename graph_traits< Graph >::vertex_descriptor Vertex; + typedef typename graph_traits< Graph >::adjacency_iterator AdjIterator; Graph g; make_graph(g); @@ -119,39 +114,37 @@ void invalidate_adj_verts() test(g, i, v, "adjacent vertices"); } - int main() { - typedef adjacency_list VVU; + typedef adjacency_list< vecS, vecS, undirectedS, int, int > VVU; cout << "vecS vecS undirectedS" << endl; - invalidate_vertices(); - invalidate_edges(); - invalidate_out_edges(); - invalidate_adj_verts(); + invalidate_vertices< VVU >(); + invalidate_edges< VVU >(); + invalidate_out_edges< VVU >(); + invalidate_adj_verts< VVU >(); - typedef adjacency_list VVB; + typedef adjacency_list< vecS, vecS, bidirectionalS, int, int > VVB; cout << "vecS vecS bidirectionals" << endl; - invalidate_vertices(); - invalidate_edges(); - invalidate_out_edges(); - invalidate_adj_verts(); + invalidate_vertices< VVB >(); + invalidate_edges< VVB >(); + invalidate_out_edges< VVB >(); + invalidate_adj_verts< VVB >(); // If you comment out the tests before this, then adj_verts test will // run without segfaulting - at least under gcc-4.3. Not really sure why, // but I'm guessing it's still not generating valid results, and shouldn't // be taken as an indicator of stability. - typedef adjacency_list VVD; + typedef adjacency_list< vecS, vecS, directedS, int, int > VVD; cout << "vecS vecS directedS" << endl; - invalidate_vertices(); -// invalidate_edges(); -// invalidate_out_edges(); -// invalidate_adj_verts(); + invalidate_vertices< VVD >(); + // invalidate_edges(); + // invalidate_out_edges(); + // invalidate_adj_verts(); - typedef adjacency_list LVD; + typedef adjacency_list< listS, vecS, directedS, int, int > LVD; cout << "listS vecS directedS" << endl; - invalidate_vertices(); -// invalidate_edges(); -// invalidate_out_edges(); -// invalidate_adj_verts(); + invalidate_vertices< LVD >(); + // invalidate_edges(); + // invalidate_out_edges(); + // invalidate_adj_verts(); } - diff --git a/test/adj_list_loops.cpp b/test/adj_list_loops.cpp index cd7b0896d..452ecbe8b 100644 --- a/test/adj_list_loops.cpp +++ b/test/adj_list_loops.cpp @@ -13,10 +13,9 @@ using namespace boost; // TODO: Integrate this into a larger adj_list test suite. -template -void test_graph_nonloop() +template < typename Graph > void test_graph_nonloop() { - typedef typename graph_traits::vertex_descriptor Vertex; + typedef typename graph_traits< Graph >::vertex_descriptor Vertex; // Build a graph with 1 edge and turn it into a loop. Graph g(5); @@ -27,14 +26,11 @@ void test_graph_nonloop() BOOST_ASSERT(num_edges(g) == 1); remove_edge(u, v, g); BOOST_ASSERT(num_edges(g) == 0); - } - -template -void test_multigraph_nonloop() +template < typename Graph > void test_multigraph_nonloop() { - typedef typename graph_traits::vertex_descriptor Vertex; + typedef typename graph_traits< Graph >::vertex_descriptor Vertex; // Build a graph with 1 edge and turn it into a loop. Graph g(5); @@ -46,13 +42,11 @@ void test_multigraph_nonloop() BOOST_ASSERT(num_edges(g) == 2); remove_edge(u, v, g); BOOST_ASSERT(num_edges(g) == 0); - } -template -void test_graph_loop() +template < typename Graph > void test_graph_loop() { - typedef typename graph_traits::vertex_descriptor Vertex; + typedef typename graph_traits< Graph >::vertex_descriptor Vertex; Graph g(5); Vertex v = *next(vertices(g).first, 2); @@ -63,10 +57,9 @@ void test_graph_loop() BOOST_ASSERT(num_edges(g) == 0); } -template -void test_multigraph_loop() +template < typename Graph > void test_multigraph_loop() { - typedef typename graph_traits::vertex_descriptor Vertex; + typedef typename graph_traits< Graph >::vertex_descriptor Vertex; Graph g(5); Vertex v = *next(vertices(g).first, 2); @@ -78,37 +71,35 @@ void test_multigraph_loop() BOOST_ASSERT(num_edges(g) == 0); } -template -void test() +template < typename Kind > void test() { typedef no_property na; - typedef adjacency_list VVL; - typedef adjacency_list LVL; - typedef adjacency_list SVL; - typedef adjacency_list MVL; - - test_graph_nonloop(); - test_graph_nonloop(); - test_graph_nonloop(); - test_graph_nonloop(); - test_multigraph_nonloop(); - test_multigraph_nonloop(); - test_multigraph_nonloop(); - test_graph_loop(); - test_graph_loop(); - test_graph_loop(); - test_graph_loop(); - test_multigraph_loop(); - test_multigraph_loop(); - test_multigraph_loop(); + typedef adjacency_list< vecS, vecS, Kind, na, na, na, listS > VVL; + typedef adjacency_list< listS, vecS, Kind, na, na, na, listS > LVL; + typedef adjacency_list< setS, vecS, Kind, na, na, na, listS > SVL; + typedef adjacency_list< multisetS, vecS, Kind, na, na, na, listS > MVL; + + test_graph_nonloop< VVL >(); + test_graph_nonloop< LVL >(); + test_graph_nonloop< SVL >(); + test_graph_nonloop< MVL >(); + test_multigraph_nonloop< VVL >(); + test_multigraph_nonloop< LVL >(); + test_multigraph_nonloop< MVL >(); + test_graph_loop< VVL >(); + test_graph_loop< LVL >(); + test_graph_loop< SVL >(); + test_graph_loop< MVL >(); + test_multigraph_loop< VVL >(); + test_multigraph_loop< LVL >(); + test_multigraph_loop< MVL >(); } - int main() { - test(); - test(); - test(); + test< undirectedS >(); + test< directedS >(); + test< bidirectionalS >(); return 0; } diff --git a/test/adj_matrix_cc.cpp b/test/adj_matrix_cc.cpp index ae8060145..9457a70c8 100644 --- a/test/adj_matrix_cc.cpp +++ b/test/adj_matrix_cc.cpp @@ -11,64 +11,68 @@ #include #include -int main(int,char*[]) +int main(int, char*[]) { - using namespace boost; - // Check adjacency_matrix without properties - { - typedef adjacency_matrix Graph; - BOOST_CONCEPT_ASSERT(( VertexListGraphConcept )); - BOOST_CONCEPT_ASSERT(( EdgeListGraphConcept )); - BOOST_CONCEPT_ASSERT(( IncidenceGraphConcept )); - BOOST_CONCEPT_ASSERT(( AdjacencyGraphConcept )); - BOOST_CONCEPT_ASSERT(( MutableGraphConcept )); - BOOST_CONCEPT_ASSERT(( AdjacencyMatrixConcept )); - } - { - typedef adjacency_matrix Graph; - BOOST_CONCEPT_ASSERT(( VertexListGraphConcept )); - BOOST_CONCEPT_ASSERT(( EdgeListGraphConcept )); - BOOST_CONCEPT_ASSERT(( IncidenceGraphConcept )); - BOOST_CONCEPT_ASSERT(( AdjacencyGraphConcept )); - BOOST_CONCEPT_ASSERT(( MutableGraphConcept )); - BOOST_CONCEPT_ASSERT(( AdjacencyMatrixConcept )); - } - // Check adjacency_matrix with properties - { - typedef adjacency_matrix, - property > Graph; - typedef graph_traits::vertex_descriptor Vertex; - typedef graph_traits::edge_descriptor Edge; - BOOST_CONCEPT_ASSERT(( VertexListGraphConcept )); - BOOST_CONCEPT_ASSERT(( EdgeListGraphConcept )); - BOOST_CONCEPT_ASSERT(( IncidenceGraphConcept )); - BOOST_CONCEPT_ASSERT(( AdjacencyGraphConcept )); - BOOST_CONCEPT_ASSERT(( AdjacencyMatrixConcept )); - BOOST_CONCEPT_ASSERT(( VertexMutablePropertyGraphConcept )); - BOOST_CONCEPT_ASSERT(( EdgeMutablePropertyGraphConcept )); - BOOST_CONCEPT_ASSERT(( ReadablePropertyGraphConcept )); - BOOST_CONCEPT_ASSERT(( PropertyGraphConcept )); - BOOST_CONCEPT_ASSERT(( PropertyGraphConcept )); - } - { - typedef adjacency_matrix, - property > Graph; - typedef graph_traits::vertex_descriptor Vertex; - typedef graph_traits::edge_descriptor Edge; - BOOST_CONCEPT_ASSERT(( VertexListGraphConcept )); - BOOST_CONCEPT_ASSERT(( EdgeListGraphConcept )); - BOOST_CONCEPT_ASSERT(( IncidenceGraphConcept )); - BOOST_CONCEPT_ASSERT(( AdjacencyGraphConcept )); - BOOST_CONCEPT_ASSERT(( AdjacencyMatrixConcept )); - BOOST_CONCEPT_ASSERT(( VertexMutablePropertyGraphConcept )); - BOOST_CONCEPT_ASSERT(( EdgeMutablePropertyGraphConcept )); - BOOST_CONCEPT_ASSERT(( ReadablePropertyGraphConcept )); - BOOST_CONCEPT_ASSERT(( PropertyGraphConcept )); - BOOST_CONCEPT_ASSERT(( PropertyGraphConcept )); - } - return 0; + using namespace boost; + // Check adjacency_matrix without properties + { + typedef adjacency_matrix< directedS > Graph; + BOOST_CONCEPT_ASSERT((VertexListGraphConcept< Graph >)); + BOOST_CONCEPT_ASSERT((EdgeListGraphConcept< Graph >)); + BOOST_CONCEPT_ASSERT((IncidenceGraphConcept< Graph >)); + BOOST_CONCEPT_ASSERT((AdjacencyGraphConcept< Graph >)); + BOOST_CONCEPT_ASSERT((MutableGraphConcept< Graph >)); + BOOST_CONCEPT_ASSERT((AdjacencyMatrixConcept< Graph >)); + } + { + typedef adjacency_matrix< undirectedS > Graph; + BOOST_CONCEPT_ASSERT((VertexListGraphConcept< Graph >)); + BOOST_CONCEPT_ASSERT((EdgeListGraphConcept< Graph >)); + BOOST_CONCEPT_ASSERT((IncidenceGraphConcept< Graph >)); + BOOST_CONCEPT_ASSERT((AdjacencyGraphConcept< Graph >)); + BOOST_CONCEPT_ASSERT((MutableGraphConcept< Graph >)); + BOOST_CONCEPT_ASSERT((AdjacencyMatrixConcept< Graph >)); + } + // Check adjacency_matrix with properties + { + typedef adjacency_matrix< directedS, property< vertex_color_t, int >, + property< edge_weight_t, float > > + Graph; + typedef graph_traits< Graph >::vertex_descriptor Vertex; + typedef graph_traits< Graph >::edge_descriptor Edge; + BOOST_CONCEPT_ASSERT((VertexListGraphConcept< Graph >)); + BOOST_CONCEPT_ASSERT((EdgeListGraphConcept< Graph >)); + BOOST_CONCEPT_ASSERT((IncidenceGraphConcept< Graph >)); + BOOST_CONCEPT_ASSERT((AdjacencyGraphConcept< Graph >)); + BOOST_CONCEPT_ASSERT((AdjacencyMatrixConcept< Graph >)); + BOOST_CONCEPT_ASSERT((VertexMutablePropertyGraphConcept< Graph >)); + BOOST_CONCEPT_ASSERT((EdgeMutablePropertyGraphConcept< Graph >)); + BOOST_CONCEPT_ASSERT( + (ReadablePropertyGraphConcept< Graph, Vertex, vertex_index_t >)); + BOOST_CONCEPT_ASSERT( + (PropertyGraphConcept< Graph, Vertex, vertex_color_t >)); + BOOST_CONCEPT_ASSERT( + (PropertyGraphConcept< Graph, Edge, edge_weight_t >)); + } + { + typedef adjacency_matrix< undirectedS, property< vertex_color_t, int >, + property< edge_weight_t, float > > + Graph; + typedef graph_traits< Graph >::vertex_descriptor Vertex; + typedef graph_traits< Graph >::edge_descriptor Edge; + BOOST_CONCEPT_ASSERT((VertexListGraphConcept< Graph >)); + BOOST_CONCEPT_ASSERT((EdgeListGraphConcept< Graph >)); + BOOST_CONCEPT_ASSERT((IncidenceGraphConcept< Graph >)); + BOOST_CONCEPT_ASSERT((AdjacencyGraphConcept< Graph >)); + BOOST_CONCEPT_ASSERT((AdjacencyMatrixConcept< Graph >)); + BOOST_CONCEPT_ASSERT((VertexMutablePropertyGraphConcept< Graph >)); + BOOST_CONCEPT_ASSERT((EdgeMutablePropertyGraphConcept< Graph >)); + BOOST_CONCEPT_ASSERT( + (ReadablePropertyGraphConcept< Graph, Vertex, vertex_index_t >)); + BOOST_CONCEPT_ASSERT( + (PropertyGraphConcept< Graph, Vertex, vertex_color_t >)); + BOOST_CONCEPT_ASSERT( + (PropertyGraphConcept< Graph, Edge, edge_weight_t >)); + } + return 0; } diff --git a/test/adjacency_matrix_test.cpp b/test/adjacency_matrix_test.cpp index 43c75d425..3e888eaf0 100644 --- a/test/adjacency_matrix_test.cpp +++ b/test/adjacency_matrix_test.cpp @@ -40,7 +40,7 @@ */ #include -#include +#include #include #include // For std::sort @@ -48,235 +48,252 @@ #include -template -void run_test() +template < typename Graph1, typename Graph2 > void run_test() { - typedef typename boost::property_map::type - IndexMap1; - typedef typename boost::property_map::type - IndexMap2; - - Graph1 g1(24); - Graph2 g2(24); - -boost::add_edge(boost::vertex(1, g1), boost::vertex(2, g1), g1); - boost::add_edge(boost::vertex(1, g2), boost::vertex(2, g2), g2); - boost::add_edge(boost::vertex(2, g1), boost::vertex(10, g1), g1); - boost::add_edge(boost::vertex(2, g2), boost::vertex(10, g2), g2); - boost::add_edge(boost::vertex(2, g1), boost::vertex(5, g1), g1); - boost::add_edge(boost::vertex(2, g2), boost::vertex(5, g2), g2); - boost::add_edge(boost::vertex(3, g1), boost::vertex(10, g1), g1); - boost::add_edge(boost::vertex(3, g2), boost::vertex(10, g2), g2); - boost::add_edge(boost::vertex(3, g1), boost::vertex(0, g1), g1); - boost::add_edge(boost::vertex(3, g2), boost::vertex(0, g2), g2); - boost::add_edge(boost::vertex(4, g1), boost::vertex(5, g1), g1); - boost::add_edge(boost::vertex(4, g2), boost::vertex(5, g2), g2); - boost::add_edge(boost::vertex(4, g1), boost::vertex(0, g1), g1); - boost::add_edge(boost::vertex(4, g2), boost::vertex(0, g2), g2); - boost::add_edge(boost::vertex(5, g1), boost::vertex(14, g1), g1); - boost::add_edge(boost::vertex(5, g2), boost::vertex(14, g2), g2); - boost::add_edge(boost::vertex(6, g1), boost::vertex(3, g1), g1); - boost::add_edge(boost::vertex(6, g2), boost::vertex(3, g2), g2); - boost::add_edge(boost::vertex(7, g1), boost::vertex(17, g1), g1); - boost::add_edge(boost::vertex(7, g2), boost::vertex(17, g2), g2); - boost::add_edge(boost::vertex(7, g1), boost::vertex(11, g1), g1); - boost::add_edge(boost::vertex(7, g2), boost::vertex(11, g2), g2); - boost::add_edge(boost::vertex(8, g1), boost::vertex(17, g1), g1); - boost::add_edge(boost::vertex(8, g2), boost::vertex(17, g2), g2); - boost::add_edge(boost::vertex(8, g1), boost::vertex(1, g1), g1); - boost::add_edge(boost::vertex(8, g2), boost::vertex(1, g2), g2); - boost::add_edge(boost::vertex(9, g1), boost::vertex(11, g1), g1); - boost::add_edge(boost::vertex(9, g2), boost::vertex(11, g2), g2); - boost::add_edge(boost::vertex(9, g1), boost::vertex(1, g1), g1); - boost::add_edge(boost::vertex(9, g2), boost::vertex(1, g2), g2); - boost::add_edge(boost::vertex(10, g1), boost::vertex(19, g1), g1); - boost::add_edge(boost::vertex(10, g2), boost::vertex(19, g2), g2); - boost::add_edge(boost::vertex(10, g1), boost::vertex(15, g1), g1); - boost::add_edge(boost::vertex(10, g2), boost::vertex(15, g2), g2); - boost::add_edge(boost::vertex(10, g1), boost::vertex(8, g1), g1); - boost::add_edge(boost::vertex(10, g2), boost::vertex(8, g2), g2); - boost::add_edge(boost::vertex(11, g1), boost::vertex(19, g1), g1); - boost::add_edge(boost::vertex(11, g2), boost::vertex(19, g2), g2); - boost::add_edge(boost::vertex(11, g1), boost::vertex(15, g1), g1); - boost::add_edge(boost::vertex(11, g2), boost::vertex(15, g2), g2); - boost::add_edge(boost::vertex(11, g1), boost::vertex(4, g1), g1); - boost::add_edge(boost::vertex(11, g2), boost::vertex(4, g2), g2); - boost::add_edge(boost::vertex(12, g1), boost::vertex(19, g1), g1); - boost::add_edge(boost::vertex(12, g2), boost::vertex(19, g2), g2); - boost::add_edge(boost::vertex(12, g1), boost::vertex(8, g1), g1); - boost::add_edge(boost::vertex(12, g2), boost::vertex(8, g2), g2); - boost::add_edge(boost::vertex(12, g1), boost::vertex(4, g1), g1); - boost::add_edge(boost::vertex(12, g2), boost::vertex(4, g2), g2); - boost::add_edge(boost::vertex(13, g1), boost::vertex(15, g1), g1); - boost::add_edge(boost::vertex(13, g2), boost::vertex(15, g2), g2); - boost::add_edge(boost::vertex(13, g1), boost::vertex(8, g1), g1); - boost::add_edge(boost::vertex(13, g2), boost::vertex(8, g2), g2); - boost::add_edge(boost::vertex(13, g1), boost::vertex(4, g1), g1); - boost::add_edge(boost::vertex(13, g2), boost::vertex(4, g2), g2); - boost::add_edge(boost::vertex(14, g1), boost::vertex(22, g1), g1); - boost::add_edge(boost::vertex(14, g2), boost::vertex(22, g2), g2); - boost::add_edge(boost::vertex(14, g1), boost::vertex(12, g1), g1); - boost::add_edge(boost::vertex(14, g2), boost::vertex(12, g2), g2); - boost::add_edge(boost::vertex(15, g1), boost::vertex(22, g1), g1); - boost::add_edge(boost::vertex(15, g2), boost::vertex(22, g2), g2); - boost::add_edge(boost::vertex(15, g1), boost::vertex(6, g1), g1); - boost::add_edge(boost::vertex(15, g2), boost::vertex(6, g2), g2); - boost::add_edge(boost::vertex(16, g1), boost::vertex(12, g1), g1); - boost::add_edge(boost::vertex(16, g2), boost::vertex(12, g2), g2); - boost::add_edge(boost::vertex(16, g1), boost::vertex(6, g1), g1); - boost::add_edge(boost::vertex(16, g2), boost::vertex(6, g2), g2); - boost::add_edge(boost::vertex(17, g1), boost::vertex(20, g1), g1); - boost::add_edge(boost::vertex(17, g2), boost::vertex(20, g2), g2); - boost::add_edge(boost::vertex(18, g1), boost::vertex(9, g1), g1); - boost::add_edge(boost::vertex(18, g2), boost::vertex(9, g2), g2); - boost::add_edge(boost::vertex(19, g1), boost::vertex(23, g1), g1); - boost::add_edge(boost::vertex(19, g2), boost::vertex(23, g2), g2); - boost::add_edge(boost::vertex(19, g1), boost::vertex(18, g1), g1); - boost::add_edge(boost::vertex(19, g2), boost::vertex(18, g2), g2); - boost::add_edge(boost::vertex(20, g1), boost::vertex(23, g1), g1); - boost::add_edge(boost::vertex(20, g2), boost::vertex(23, g2), g2); - boost::add_edge(boost::vertex(20, g1), boost::vertex(13, g1), g1); - boost::add_edge(boost::vertex(20, g2), boost::vertex(13, g2), g2); - boost::add_edge(boost::vertex(21, g1), boost::vertex(18, g1), g1); - boost::add_edge(boost::vertex(21, g2), boost::vertex(18, g2), g2); - boost::add_edge(boost::vertex(21, g1), boost::vertex(13, g1), g1); - boost::add_edge(boost::vertex(21, g2), boost::vertex(13, g2), g2); - boost::add_edge(boost::vertex(22, g1), boost::vertex(21, g1), g1); - boost::add_edge(boost::vertex(22, g2), boost::vertex(21, g2), g2); - boost::add_edge(boost::vertex(23, g1), boost::vertex(16, g1), g1); - boost::add_edge(boost::vertex(23, g2), boost::vertex(16, g2), g2); - - IndexMap1 index_map1 = boost::get(boost::vertex_index_t(), g1); - IndexMap2 index_map2 = boost::get(boost::vertex_index_t(), g2); - typename boost::graph_traits::vertex_iterator vi1, vend1; - typename boost::graph_traits::vertex_iterator vi2, vend2; - - typename boost::graph_traits::adjacency_iterator ai1, aend1; - typename boost::graph_traits::adjacency_iterator ai2, aend2; - - for (boost::tie(vi1, vend1) = boost::vertices(g1), boost::tie(vi2, vend2) =boost::vertices(g2); vi1 != vend1; ++vi1, ++vi2) - { - BOOST_CHECK(boost::get(index_map1, *vi1) == boost::get(index_map2, *vi2)); - - for (boost::tie(ai1, aend1) = boost::adjacent_vertices(*vi1, g1), - boost::tie(ai2, aend2) = boost::adjacent_vertices(*vi2, g2); - ai1 != aend1; - ++ai1, ++ai2) - { - BOOST_CHECK(boost::get(index_map1, *ai1) == boost::get(index_map2, *ai2)); - } - } - - typename boost::graph_traits::out_edge_iterator ei1, eend1; - typename boost::graph_traits::out_edge_iterator ei2, eend2; - - for (boost::tie(vi1, vend1) = boost::vertices(g1), - boost::tie(vi2, vend2) = boost::vertices(g2); vi1 != vend1; ++vi1, ++vi2) - { - BOOST_CHECK(boost::get(index_map1, *vi1) == boost::get(index_map2, *vi2)); - - for (boost::tie(ei1, eend1) = boost::out_edges(*vi1, g1), - boost::tie(ei2, eend2) = boost::out_edges(*vi2, g2); - ei1 != eend1; - ++ei1, ++ei2) - { - BOOST_CHECK(boost::get(index_map1, boost::target(*ei1, g1)) == boost::get(index_map2, boost::target(*ei2, g2))); - } - } - - typename boost::graph_traits::in_edge_iterator iei1, ieend1; - typename boost::graph_traits::in_edge_iterator iei2, ieend2; - - for (boost::tie(vi1, vend1) = boost::vertices(g1), - boost::tie(vi2, vend2) = boost::vertices(g2); vi1 != vend1; ++vi1, ++vi2) - { - BOOST_CHECK(boost::get(index_map1, *vi1) == boost::get(index_map2, *vi2)); - - for (boost::tie(iei1, ieend1) = boost::in_edges(*vi1, g1), - boost::tie(iei2, ieend2) = boost::in_edges(*vi2, g2); - iei1 != ieend1; - ++iei1, ++iei2) - { - BOOST_CHECK(boost::get(index_map1, boost::target(*iei1, g1)) == boost::get(index_map2, boost::target(*iei2, g2))); - } - } - - // Test construction from a range of pairs - std::vector > edge_pairs_g1; - BGL_FORALL_EDGES_T(e, g1, Graph1) { - edge_pairs_g1.push_back( - std::make_pair(get(index_map1, source(e, g1)), - get(index_map1, target(e, g1)))); - } - Graph2 g3(edge_pairs_g1.begin(), edge_pairs_g1.end(), num_vertices(g1)); - BOOST_CHECK(num_vertices(g1) == num_vertices(g3)); - std::vector > edge_pairs_g3; - IndexMap2 index_map3 = boost::get(boost::vertex_index_t(), g3); - BGL_FORALL_EDGES_T(e, g3, Graph2) { - edge_pairs_g3.push_back( - std::make_pair(get(index_map3, source(e, g3)), - get(index_map3, target(e, g3)))); - } - // Normalize the edge pairs for comparison - if (boost::is_convertible::directed_category*, boost::undirected_tag*>::value || boost::is_convertible::directed_category*, boost::undirected_tag*>::value) { - for (size_t i = 0; i < edge_pairs_g1.size(); ++i) { - if (edge_pairs_g1[i].first < edge_pairs_g1[i].second) { - std::swap(edge_pairs_g1[i].first, edge_pairs_g1[i].second); - } - } - for (size_t i = 0; i < edge_pairs_g3.size(); ++i) { - if (edge_pairs_g3[i].first < edge_pairs_g3[i].second) { - std::swap(edge_pairs_g3[i].first, edge_pairs_g3[i].second); - } - } - } - std::sort(edge_pairs_g1.begin(), edge_pairs_g1.end()); - std::sort(edge_pairs_g3.begin(), edge_pairs_g3.end()); - edge_pairs_g1.erase(std::unique(edge_pairs_g1.begin(), edge_pairs_g1.end()), edge_pairs_g1.end()); - edge_pairs_g3.erase(std::unique(edge_pairs_g3.begin(), edge_pairs_g3.end()), edge_pairs_g3.end()); - BOOST_CHECK(edge_pairs_g1 == edge_pairs_g3); + typedef typename boost::property_map< Graph1, boost::vertex_index_t >::type + IndexMap1; + typedef typename boost::property_map< Graph2, boost::vertex_index_t >::type + IndexMap2; + + Graph1 g1(24); + Graph2 g2(24); + + boost::add_edge(boost::vertex(1, g1), boost::vertex(2, g1), g1); + boost::add_edge(boost::vertex(1, g2), boost::vertex(2, g2), g2); + boost::add_edge(boost::vertex(2, g1), boost::vertex(10, g1), g1); + boost::add_edge(boost::vertex(2, g2), boost::vertex(10, g2), g2); + boost::add_edge(boost::vertex(2, g1), boost::vertex(5, g1), g1); + boost::add_edge(boost::vertex(2, g2), boost::vertex(5, g2), g2); + boost::add_edge(boost::vertex(3, g1), boost::vertex(10, g1), g1); + boost::add_edge(boost::vertex(3, g2), boost::vertex(10, g2), g2); + boost::add_edge(boost::vertex(3, g1), boost::vertex(0, g1), g1); + boost::add_edge(boost::vertex(3, g2), boost::vertex(0, g2), g2); + boost::add_edge(boost::vertex(4, g1), boost::vertex(5, g1), g1); + boost::add_edge(boost::vertex(4, g2), boost::vertex(5, g2), g2); + boost::add_edge(boost::vertex(4, g1), boost::vertex(0, g1), g1); + boost::add_edge(boost::vertex(4, g2), boost::vertex(0, g2), g2); + boost::add_edge(boost::vertex(5, g1), boost::vertex(14, g1), g1); + boost::add_edge(boost::vertex(5, g2), boost::vertex(14, g2), g2); + boost::add_edge(boost::vertex(6, g1), boost::vertex(3, g1), g1); + boost::add_edge(boost::vertex(6, g2), boost::vertex(3, g2), g2); + boost::add_edge(boost::vertex(7, g1), boost::vertex(17, g1), g1); + boost::add_edge(boost::vertex(7, g2), boost::vertex(17, g2), g2); + boost::add_edge(boost::vertex(7, g1), boost::vertex(11, g1), g1); + boost::add_edge(boost::vertex(7, g2), boost::vertex(11, g2), g2); + boost::add_edge(boost::vertex(8, g1), boost::vertex(17, g1), g1); + boost::add_edge(boost::vertex(8, g2), boost::vertex(17, g2), g2); + boost::add_edge(boost::vertex(8, g1), boost::vertex(1, g1), g1); + boost::add_edge(boost::vertex(8, g2), boost::vertex(1, g2), g2); + boost::add_edge(boost::vertex(9, g1), boost::vertex(11, g1), g1); + boost::add_edge(boost::vertex(9, g2), boost::vertex(11, g2), g2); + boost::add_edge(boost::vertex(9, g1), boost::vertex(1, g1), g1); + boost::add_edge(boost::vertex(9, g2), boost::vertex(1, g2), g2); + boost::add_edge(boost::vertex(10, g1), boost::vertex(19, g1), g1); + boost::add_edge(boost::vertex(10, g2), boost::vertex(19, g2), g2); + boost::add_edge(boost::vertex(10, g1), boost::vertex(15, g1), g1); + boost::add_edge(boost::vertex(10, g2), boost::vertex(15, g2), g2); + boost::add_edge(boost::vertex(10, g1), boost::vertex(8, g1), g1); + boost::add_edge(boost::vertex(10, g2), boost::vertex(8, g2), g2); + boost::add_edge(boost::vertex(11, g1), boost::vertex(19, g1), g1); + boost::add_edge(boost::vertex(11, g2), boost::vertex(19, g2), g2); + boost::add_edge(boost::vertex(11, g1), boost::vertex(15, g1), g1); + boost::add_edge(boost::vertex(11, g2), boost::vertex(15, g2), g2); + boost::add_edge(boost::vertex(11, g1), boost::vertex(4, g1), g1); + boost::add_edge(boost::vertex(11, g2), boost::vertex(4, g2), g2); + boost::add_edge(boost::vertex(12, g1), boost::vertex(19, g1), g1); + boost::add_edge(boost::vertex(12, g2), boost::vertex(19, g2), g2); + boost::add_edge(boost::vertex(12, g1), boost::vertex(8, g1), g1); + boost::add_edge(boost::vertex(12, g2), boost::vertex(8, g2), g2); + boost::add_edge(boost::vertex(12, g1), boost::vertex(4, g1), g1); + boost::add_edge(boost::vertex(12, g2), boost::vertex(4, g2), g2); + boost::add_edge(boost::vertex(13, g1), boost::vertex(15, g1), g1); + boost::add_edge(boost::vertex(13, g2), boost::vertex(15, g2), g2); + boost::add_edge(boost::vertex(13, g1), boost::vertex(8, g1), g1); + boost::add_edge(boost::vertex(13, g2), boost::vertex(8, g2), g2); + boost::add_edge(boost::vertex(13, g1), boost::vertex(4, g1), g1); + boost::add_edge(boost::vertex(13, g2), boost::vertex(4, g2), g2); + boost::add_edge(boost::vertex(14, g1), boost::vertex(22, g1), g1); + boost::add_edge(boost::vertex(14, g2), boost::vertex(22, g2), g2); + boost::add_edge(boost::vertex(14, g1), boost::vertex(12, g1), g1); + boost::add_edge(boost::vertex(14, g2), boost::vertex(12, g2), g2); + boost::add_edge(boost::vertex(15, g1), boost::vertex(22, g1), g1); + boost::add_edge(boost::vertex(15, g2), boost::vertex(22, g2), g2); + boost::add_edge(boost::vertex(15, g1), boost::vertex(6, g1), g1); + boost::add_edge(boost::vertex(15, g2), boost::vertex(6, g2), g2); + boost::add_edge(boost::vertex(16, g1), boost::vertex(12, g1), g1); + boost::add_edge(boost::vertex(16, g2), boost::vertex(12, g2), g2); + boost::add_edge(boost::vertex(16, g1), boost::vertex(6, g1), g1); + boost::add_edge(boost::vertex(16, g2), boost::vertex(6, g2), g2); + boost::add_edge(boost::vertex(17, g1), boost::vertex(20, g1), g1); + boost::add_edge(boost::vertex(17, g2), boost::vertex(20, g2), g2); + boost::add_edge(boost::vertex(18, g1), boost::vertex(9, g1), g1); + boost::add_edge(boost::vertex(18, g2), boost::vertex(9, g2), g2); + boost::add_edge(boost::vertex(19, g1), boost::vertex(23, g1), g1); + boost::add_edge(boost::vertex(19, g2), boost::vertex(23, g2), g2); + boost::add_edge(boost::vertex(19, g1), boost::vertex(18, g1), g1); + boost::add_edge(boost::vertex(19, g2), boost::vertex(18, g2), g2); + boost::add_edge(boost::vertex(20, g1), boost::vertex(23, g1), g1); + boost::add_edge(boost::vertex(20, g2), boost::vertex(23, g2), g2); + boost::add_edge(boost::vertex(20, g1), boost::vertex(13, g1), g1); + boost::add_edge(boost::vertex(20, g2), boost::vertex(13, g2), g2); + boost::add_edge(boost::vertex(21, g1), boost::vertex(18, g1), g1); + boost::add_edge(boost::vertex(21, g2), boost::vertex(18, g2), g2); + boost::add_edge(boost::vertex(21, g1), boost::vertex(13, g1), g1); + boost::add_edge(boost::vertex(21, g2), boost::vertex(13, g2), g2); + boost::add_edge(boost::vertex(22, g1), boost::vertex(21, g1), g1); + boost::add_edge(boost::vertex(22, g2), boost::vertex(21, g2), g2); + boost::add_edge(boost::vertex(23, g1), boost::vertex(16, g1), g1); + boost::add_edge(boost::vertex(23, g2), boost::vertex(16, g2), g2); + + IndexMap1 index_map1 = boost::get(boost::vertex_index_t(), g1); + IndexMap2 index_map2 = boost::get(boost::vertex_index_t(), g2); + typename boost::graph_traits< Graph1 >::vertex_iterator vi1, vend1; + typename boost::graph_traits< Graph2 >::vertex_iterator vi2, vend2; + + typename boost::graph_traits< Graph1 >::adjacency_iterator ai1, aend1; + typename boost::graph_traits< Graph2 >::adjacency_iterator ai2, aend2; + + for (boost::tie(vi1, vend1) = boost::vertices(g1), + boost::tie(vi2, vend2) = boost::vertices(g2); + vi1 != vend1; ++vi1, ++vi2) + { + BOOST_TEST( + boost::get(index_map1, *vi1) == boost::get(index_map2, *vi2)); + + for (boost::tie(ai1, aend1) = boost::adjacent_vertices(*vi1, g1), + boost::tie(ai2, aend2) + = boost::adjacent_vertices(*vi2, g2); + ai1 != aend1; ++ai1, ++ai2) + { + BOOST_TEST( + boost::get(index_map1, *ai1) == boost::get(index_map2, *ai2)); + } + } + + typename boost::graph_traits< Graph1 >::out_edge_iterator ei1, eend1; + typename boost::graph_traits< Graph2 >::out_edge_iterator ei2, eend2; + + for (boost::tie(vi1, vend1) = boost::vertices(g1), + boost::tie(vi2, vend2) = boost::vertices(g2); + vi1 != vend1; ++vi1, ++vi2) + { + BOOST_TEST( + boost::get(index_map1, *vi1) == boost::get(index_map2, *vi2)); + + for (boost::tie(ei1, eend1) = boost::out_edges(*vi1, g1), + boost::tie(ei2, eend2) + = boost::out_edges(*vi2, g2); + ei1 != eend1; ++ei1, ++ei2) + { + BOOST_TEST(boost::get(index_map1, boost::target(*ei1, g1)) + == boost::get(index_map2, boost::target(*ei2, g2))); + } + } + + typename boost::graph_traits< Graph1 >::in_edge_iterator iei1, ieend1; + typename boost::graph_traits< Graph2 >::in_edge_iterator iei2, ieend2; + + for (boost::tie(vi1, vend1) = boost::vertices(g1), + boost::tie(vi2, vend2) = boost::vertices(g2); + vi1 != vend1; ++vi1, ++vi2) + { + BOOST_TEST( + boost::get(index_map1, *vi1) == boost::get(index_map2, *vi2)); + + for (boost::tie(iei1, ieend1) = boost::in_edges(*vi1, g1), + boost::tie(iei2, ieend2) + = boost::in_edges(*vi2, g2); + iei1 != ieend1; ++iei1, ++iei2) + { + BOOST_TEST(boost::get(index_map1, boost::target(*iei1, g1)) + == boost::get(index_map2, boost::target(*iei2, g2))); + } + } + + // Test construction from a range of pairs + std::vector< std::pair< int, int > > edge_pairs_g1; + BGL_FORALL_EDGES_T(e, g1, Graph1) + { + edge_pairs_g1.push_back(std::make_pair( + get(index_map1, source(e, g1)), get(index_map1, target(e, g1)))); + } + Graph2 g3(edge_pairs_g1.begin(), edge_pairs_g1.end(), num_vertices(g1)); + BOOST_TEST(num_vertices(g1) == num_vertices(g3)); + std::vector< std::pair< int, int > > edge_pairs_g3; + IndexMap2 index_map3 = boost::get(boost::vertex_index_t(), g3); + BGL_FORALL_EDGES_T(e, g3, Graph2) + { + edge_pairs_g3.push_back(std::make_pair( + get(index_map3, source(e, g3)), get(index_map3, target(e, g3)))); + } + // Normalize the edge pairs for comparison + if (boost::is_convertible< + typename boost::graph_traits< Graph1 >::directed_category*, + boost::undirected_tag* >::value + || boost::is_convertible< + typename boost::graph_traits< Graph2 >::directed_category*, + boost::undirected_tag* >::value) + { + for (size_t i = 0; i < edge_pairs_g1.size(); ++i) + { + if (edge_pairs_g1[i].first < edge_pairs_g1[i].second) + { + std::swap(edge_pairs_g1[i].first, edge_pairs_g1[i].second); + } + } + for (size_t i = 0; i < edge_pairs_g3.size(); ++i) + { + if (edge_pairs_g3[i].first < edge_pairs_g3[i].second) + { + std::swap(edge_pairs_g3[i].first, edge_pairs_g3[i].second); + } + } + } + std::sort(edge_pairs_g1.begin(), edge_pairs_g1.end()); + std::sort(edge_pairs_g3.begin(), edge_pairs_g3.end()); + edge_pairs_g1.erase(std::unique(edge_pairs_g1.begin(), edge_pairs_g1.end()), + edge_pairs_g1.end()); + edge_pairs_g3.erase(std::unique(edge_pairs_g3.begin(), edge_pairs_g3.end()), + edge_pairs_g3.end()); + BOOST_TEST(edge_pairs_g1 == edge_pairs_g3); } -template -void test_remove_edges() +template < typename Graph > void test_remove_edges() { using namespace boost; // Build a 2-vertex graph Graph g(2); add_edge(vertex(0, g), vertex(1, g), g); - BOOST_CHECK(num_vertices(g) == 2); - BOOST_CHECK(num_edges(g) == 1); + BOOST_TEST(num_vertices(g) == 2); + BOOST_TEST(num_edges(g) == 1); remove_edge(vertex(0, g), vertex(1, g), g); - BOOST_CHECK(num_edges(g) == 0); + BOOST_TEST(num_edges(g) == 0); // Make sure we don't decrement the edge count if the edge doesn't actually // exist. remove_edge(vertex(0, g), vertex(1, g), g); - BOOST_CHECK(num_edges(g) == 0); + BOOST_TEST(num_edges(g) == 0); } - -int test_main(int, char*[]) +int main(int, char*[]) { - // Use setS to keep out edges in order, so they match the adjacency_matrix. - typedef boost::adjacency_list - UGraph1; - typedef boost::adjacency_matrix - UGraph2; - run_test(); - - // Use setS to keep out edges in order, so they match the adjacency_matrix. - typedef boost::adjacency_list - BGraph1; - typedef boost::adjacency_matrix - BGraph2; - run_test(); - - test_remove_edges(); - test_remove_edges(); - - return 0; + // Use setS to keep out edges in order, so they match the adjacency_matrix. + typedef boost::adjacency_list< boost::setS, boost::vecS, + boost::undirectedS > + UGraph1; + typedef boost::adjacency_matrix< boost::undirectedS > UGraph2; + run_test< UGraph1, UGraph2 >(); + + // Use setS to keep out edges in order, so they match the adjacency_matrix. + typedef boost::adjacency_list< boost::setS, boost::vecS, + boost::bidirectionalS > + BGraph1; + typedef boost::adjacency_matrix< boost::directedS > BGraph2; + run_test< BGraph1, BGraph2 >(); + + test_remove_edges< UGraph2 >(); + test_remove_edges< BGraph2 >(); + + return boost::report_errors(); } - diff --git a/test/all_planar_input_files_test.cpp b/test/all_planar_input_files_test.cpp index e918f1f84..9af6dfff2 100644 --- a/test/all_planar_input_files_test.cpp +++ b/test/all_planar_input_files_test.cpp @@ -26,14 +26,12 @@ This test needs to be linked against Boost.Filesystem. #include #include - #include #include #include #include #include -#include - +#include #include #include @@ -49,238 +47,197 @@ This test needs to be linked against Boost.Filesystem. #include #include - - - - - using namespace boost; struct coord_t { - std::size_t x; - std::size_t y; + std::size_t x; + std::size_t y; }; - - -template +template < typename Graph > void read_dimacs(Graph& g, const std::string& filename) { - typedef typename graph_traits::vertex_descriptor vertex_t; - std::vector vertices_by_index; - - std::ifstream in(filename.c_str()); - - while (!in.eof()) + typedef typename graph_traits< Graph >::vertex_descriptor vertex_t; + std::vector< vertex_t > vertices_by_index; + + std::ifstream in(filename.c_str()); + + while (!in.eof()) { - char buffer[256]; - in.getline(buffer, 256); - std::string s(buffer); - - if (s.size() == 0) - continue; - - std::vector v; - split(v, buffer, is_any_of(" \t\n")); - - if (v[0] == "p") + char buffer[256]; + in.getline(buffer, 256); + std::string s(buffer); + + if (s.size() == 0) + continue; + + std::vector< std::string > v; + split(v, buffer, is_any_of(" \t\n")); + + if (v[0] == "p") { - //v[1] == "edge" - g = Graph(boost::lexical_cast(v[2].c_str())); - std::copy(vertices(g).first, - vertices(g).second, - std::back_inserter(vertices_by_index) - ); + // v[1] == "edge" + g = Graph(boost::lexical_cast< std::size_t >(v[2].c_str())); + std::copy(vertices(g).first, vertices(g).second, + std::back_inserter(vertices_by_index)); } - else if (v[0] == "e") + else if (v[0] == "e") { - add_edge(vertices_by_index - [boost::lexical_cast(v[1].c_str())], - vertices_by_index - [boost::lexical_cast(v[2].c_str())], - g); + add_edge(vertices_by_index[boost::lexical_cast< std::size_t >( + v[1].c_str())], + vertices_by_index[boost::lexical_cast< std::size_t >( + v[2].c_str())], + g); } } } +int test_graph(const std::string& dimacs_filename) +{ + typedef adjacency_list< listS, vecS, undirectedS, + property< vertex_index_t, int >, property< edge_index_t, int > > + graph; + + typedef graph_traits< graph >::edge_descriptor edge_t; + typedef graph_traits< graph >::edge_iterator edge_iterator_t; + typedef graph_traits< graph >::vertex_iterator vertex_iterator_t; + typedef graph_traits< graph >::edges_size_type e_size_t; + typedef graph_traits< graph >::vertex_descriptor vertex_t; + typedef edge_index_update_visitor< + property_map< graph, edge_index_t >::type > + edge_visitor_t; + + vertex_iterator_t vi, vi_end; + edge_iterator_t ei, ei_end; + + graph g; + read_dimacs(g, dimacs_filename); + + // Initialize the interior edge index + property_map< graph, edge_index_t >::type e_index = get(edge_index, g); + e_size_t edge_count = 0; + for (boost::tie(ei, ei_end) = edges(g); ei != ei_end; ++ei) + put(e_index, *ei, edge_count++); + + // Initialize the interior vertex index - not needed if the vertices + // are stored with a vecS + /* + property_map::type v_index = get(vertex_index, g); + v_size_t vertex_count = 0; + for(boost::tie(vi, vi_end) = vertices(g); vi != vi_end; ++vi) + put(v_index, *vi, vertex_count++); + */ + + // This edge_updater will automatically update the interior edge + // index of the graph as edges are created. + edge_visitor_t edge_updater(get(edge_index, g), num_edges(g)); + + // The input graph may not be maximal planar, but the Chrobak-Payne straight + // line drawing needs a maximal planar graph as input. So, we make a copy of + // the original graph here, then add edges to the graph to make it maximal + // planar. When we're done creating a drawing of the maximal planar graph, + // we can use the same mapping of vertices to points on the grid to embed + // the original, non-maximal graph. + graph g_copy(g); + + // Add edges to make g connected, if it isn't already + make_connected(g, get(vertex_index, g), edge_updater); + + std::vector< graph_traits< graph >::edge_descriptor > kuratowski_edges; + + typedef std::vector< std::vector< edge_t > > edge_permutation_storage_t; + typedef boost::iterator_property_map< edge_permutation_storage_t::iterator, + property_map< graph, vertex_index_t >::type > + edge_permutation_t; + + edge_permutation_storage_t edge_permutation_storage(num_vertices(g)); + edge_permutation_t perm( + edge_permutation_storage.begin(), get(vertex_index, g)); + + // Test for planarity, computing the planar embedding or the kuratowski + // subgraph. + if (!boyer_myrvold_planarity_test(boyer_myrvold_params::graph = g, + boyer_myrvold_params::embedding = perm, + boyer_myrvold_params::kuratowski_subgraph + = std::back_inserter(kuratowski_edges))) + { + std::cout << "Not planar. "; + BOOST_TEST(is_kuratowski_subgraph( + g, kuratowski_edges.begin(), kuratowski_edges.end())); + return 0; + } + // If we get this far, we have a connected planar graph. + make_biconnected_planar(g, perm, get(edge_index, g), edge_updater); + // Compute the planar embedding of the (now) biconnected planar graph + BOOST_TEST(boyer_myrvold_planarity_test(boyer_myrvold_params::graph = g, + boyer_myrvold_params::embedding = perm)); -int test_graph(const std::string& dimacs_filename) -{ + // If we get this far, we have a biconnected planar graph + make_maximal_planar( + g, perm, get(vertex_index, g), get(edge_index, g), edge_updater); - typedef adjacency_list, - property > graph; - - typedef graph_traits::edge_descriptor edge_t; - typedef graph_traits::edge_iterator edge_iterator_t; - typedef graph_traits::vertex_iterator vertex_iterator_t; - typedef graph_traits::edges_size_type e_size_t; - typedef graph_traits::vertex_descriptor vertex_t; - typedef edge_index_update_visitor::type> - edge_visitor_t; - - vertex_iterator_t vi, vi_end; - edge_iterator_t ei, ei_end; - - graph g; - read_dimacs(g, dimacs_filename); - - // Initialize the interior edge index - property_map::type e_index = get(edge_index, g); - e_size_t edge_count = 0; - for(boost::tie(ei, ei_end) = edges(g); ei != ei_end; ++ei) - put(e_index, *ei, edge_count++); - - // Initialize the interior vertex index - not needed if the vertices - // are stored with a vecS - /* - property_map::type v_index = get(vertex_index, g); - v_size_t vertex_count = 0; - for(boost::tie(vi, vi_end) = vertices(g); vi != vi_end; ++vi) - put(v_index, *vi, vertex_count++); - */ - - // This edge_updater will automatically update the interior edge - // index of the graph as edges are created. - edge_visitor_t edge_updater(get(edge_index, g), num_edges(g)); - - // The input graph may not be maximal planar, but the Chrobak-Payne straight - // line drawing needs a maximal planar graph as input. So, we make a copy of - // the original graph here, then add edges to the graph to make it maximal - // planar. When we're done creating a drawing of the maximal planar graph, - // we can use the same mapping of vertices to points on the grid to embed the - // original, non-maximal graph. - graph g_copy(g); - - // Add edges to make g connected, if it isn't already - make_connected(g, get(vertex_index, g), edge_updater); - - std::vector::edge_descriptor> kuratowski_edges; - - typedef std::vector< std::vector > edge_permutation_storage_t; - typedef boost::iterator_property_map - < edge_permutation_storage_t::iterator, - property_map::type - > - edge_permutation_t; - - edge_permutation_storage_t edge_permutation_storage(num_vertices(g)); - edge_permutation_t perm(edge_permutation_storage.begin(), - get(vertex_index,g) - ); - - // Test for planarity, computing the planar embedding or the kuratowski - // subgraph. - if (!boyer_myrvold_planarity_test(boyer_myrvold_params::graph = g, - boyer_myrvold_params::embedding = perm, - boyer_myrvold_params::kuratowski_subgraph - = std::back_inserter(kuratowski_edges) - ) - ) - { - std::cout << "Not planar. "; - BOOST_REQUIRE(is_kuratowski_subgraph(g, - kuratowski_edges.begin(), - kuratowski_edges.end() - ) - ); - - return 0; - } + // Now the graph is triangulated - we can compute the final planar embedding + BOOST_TEST(boyer_myrvold_planarity_test(boyer_myrvold_params::graph = g, + boyer_myrvold_params::embedding = perm)); - // If we get this far, we have a connected planar graph. - make_biconnected_planar(g, perm, get(edge_index, g), edge_updater); - - // Compute the planar embedding of the (now) biconnected planar graph - BOOST_CHECK (boyer_myrvold_planarity_test(boyer_myrvold_params::graph = g, - boyer_myrvold_params::embedding = - perm - ) - ); - - // If we get this far, we have a biconnected planar graph - make_maximal_planar(g, perm, get(vertex_index,g), get(edge_index,g), - edge_updater - ); - - // Now the graph is triangulated - we can compute the final planar embedding - BOOST_CHECK (boyer_myrvold_planarity_test(boyer_myrvold_params::graph = g, - boyer_myrvold_params::embedding = - perm - ) - ); - - // Compute a planar canonical ordering of the vertices - std::vector ordering; - planar_canonical_ordering(g, perm, std::back_inserter(ordering)); - - BOOST_CHECK(ordering.size() == num_vertices(g)); - - typedef std::vector< coord_t > drawing_storage_t; - typedef boost::iterator_property_map - < drawing_storage_t::iterator, property_map::type > - drawing_map_t; - - drawing_storage_t drawing_vector(num_vertices(g)); - drawing_map_t drawing(drawing_vector.begin(), get(vertex_index,g)); - - // Compute a straight line drawing - chrobak_payne_straight_line_drawing(g, - perm, - ordering.begin(), - ordering.end(), - drawing - ); - - std::cout << "Planar. "; - BOOST_REQUIRE (is_straight_line_drawing(g, drawing)); - - return 0; -} + // Compute a planar canonical ordering of the vertices + std::vector< vertex_t > ordering; + planar_canonical_ordering(g, perm, std::back_inserter(ordering)); + BOOST_TEST(ordering.size() == num_vertices(g)); + typedef std::vector< coord_t > drawing_storage_t; + typedef boost::iterator_property_map< drawing_storage_t::iterator, + property_map< graph, vertex_index_t >::type > + drawing_map_t; + drawing_storage_t drawing_vector(num_vertices(g)); + drawing_map_t drawing(drawing_vector.begin(), get(vertex_index, g)); + // Compute a straight line drawing + chrobak_payne_straight_line_drawing( + g, perm, ordering.begin(), ordering.end(), drawing); + std::cout << "Planar. "; + BOOST_TEST(is_straight_line_drawing(g, drawing)); + return 0; +} -int test_main(int argc, char* argv[]) +int main(int argc, char* argv[]) { - std::string input_directory_str = "planar_input_graphs"; - if (argc > 1) + std::string input_directory_str = "planar_input_graphs"; + if (argc > 1) { - input_directory_str = std::string(argv[1]); + input_directory_str = std::string(argv[1]); } - std::cout << "Reading planar input files from " << input_directory_str - << std::endl; + std::cout << "Reading planar input files from " << input_directory_str + << std::endl; - filesystem::path input_directory = - filesystem::system_complete(filesystem::path(input_directory_str)); - const std::string dimacs_extension = ".dimacs"; + filesystem::path input_directory + = filesystem::system_complete(filesystem::path(input_directory_str)); + const std::string dimacs_extension = ".dimacs"; - filesystem::directory_iterator dir_end; - for( filesystem::directory_iterator dir_itr(input_directory); - dir_itr != dir_end; ++dir_itr) - { - - if (dir_itr->path().extension() != dimacs_extension) - continue; + filesystem::directory_iterator dir_end; + for (filesystem::directory_iterator dir_itr(input_directory); + dir_itr != dir_end; ++dir_itr) + { - std::cout << "Testing " << dir_itr->path().leaf() << "... "; - BOOST_REQUIRE (test_graph(dir_itr->path().string()) == 0); + if (dir_itr->path().extension() != dimacs_extension) + continue; - std::cout << std::endl; - } + std::cout << "Testing " << dir_itr->path().leaf() << "... "; + BOOST_TEST(test_graph(dir_itr->path().string()) == 0); - return 0; + std::cout << std::endl; + } + return boost::report_errors(); } diff --git a/test/astar_search_test.cpp b/test/astar_search_test.cpp index 72f29150d..756f0cdca 100644 --- a/test/astar_search_test.cpp +++ b/test/astar_search_test.cpp @@ -10,7 +10,6 @@ //======================================================================= // - #include #include #include @@ -19,205 +18,227 @@ #include #include #include -#include // for sqrt +#include // for sqrt #include using namespace boost; using namespace std; - // auxiliary types struct location { - float y, x; // lat, long + float y, x; // lat, long +}; +struct my_float +{ + float v; + explicit my_float(float v = float()) : v(v) {} }; -struct my_float {float v; explicit my_float(float v = float()): v(v) {}}; typedef my_float cost; -ostream& operator<<(ostream& o, my_float f) {return o << f.v;} -my_float operator+(my_float a, my_float b) {return my_float(a.v + b.v);} -bool operator==(my_float a, my_float b) {return a.v == b.v;} -bool operator<(my_float a, my_float b) {return a.v < b.v;} +ostream& operator<<(ostream& o, my_float f) { return o << f.v; } +my_float operator+(my_float a, my_float b) { return my_float(a.v + b.v); } +bool operator==(my_float a, my_float b) { return a.v == b.v; } +bool operator<(my_float a, my_float b) { return a.v < b.v; } -template -class city_writer { +template < class Name, class LocMap > class city_writer +{ public: - city_writer(Name n, LocMap l, float _minx, float _maxx, - float _miny, float _maxy, - unsigned int _ptx, unsigned int _pty) - : name(n), loc(l), minx(_minx), maxx(_maxx), miny(_miny), - maxy(_maxy), ptx(_ptx), pty(_pty) {} - template - void operator()(ostream& out, const Vertex& v) const { - float px = 1 - (loc[v].x - minx) / (maxx - minx); - float py = (loc[v].y - miny) / (maxy - miny); - out << "[label=\"" << name[v] << "\", pos=\"" - << static_cast(ptx * px) << "," - << static_cast(pty * py) - << "\", fontsize=\"11\"]"; - } + city_writer(Name n, LocMap l, float _minx, float _maxx, float _miny, + float _maxy, unsigned int _ptx, unsigned int _pty) + : name(n) + , loc(l) + , minx(_minx) + , maxx(_maxx) + , miny(_miny) + , maxy(_maxy) + , ptx(_ptx) + , pty(_pty) + { + } + template < class Vertex > + void operator()(ostream& out, const Vertex& v) const + { + float px = 1 - (loc[v].x - minx) / (maxx - minx); + float py = (loc[v].y - miny) / (maxy - miny); + out << "[label=\"" << name[v] << "\", pos=\"" + << static_cast< unsigned int >(ptx * px) << "," + << static_cast< unsigned int >(pty * py) << "\", fontsize=\"11\"]"; + } + private: - Name name; - LocMap loc; - float minx, maxx, miny, maxy; - unsigned int ptx, pty; + Name name; + LocMap loc; + float minx, maxx, miny, maxy; + unsigned int ptx, pty; }; -template -class time_writer { +template < class WeightMap > class time_writer +{ public: - time_writer(WeightMap w) : wm(w) {} - template - void operator()(ostream &out, const Edge& e) const { - out << "[label=\"" << wm[e] << "\", fontsize=\"11\"]"; - } + time_writer(WeightMap w) : wm(w) {} + template < class Edge > void operator()(ostream& out, const Edge& e) const + { + out << "[label=\"" << wm[e] << "\", fontsize=\"11\"]"; + } + private: - WeightMap wm; + WeightMap wm; }; - // euclidean distance heuristic -template -class distance_heuristic : public astar_heuristic +template < class Graph, class CostType, class LocMap > +class distance_heuristic : public astar_heuristic< Graph, CostType > { public: - typedef typename graph_traits::vertex_descriptor Vertex; - distance_heuristic(LocMap l, Vertex goal) - : m_location(l), m_goal(goal) {} - CostType operator()(Vertex u) - { - float dx = m_location[m_goal].x - m_location[u].x; - float dy = m_location[m_goal].y - m_location[u].y; - return CostType(::sqrt(dx * dx + dy * dy)); - } + typedef typename graph_traits< Graph >::vertex_descriptor Vertex; + distance_heuristic(LocMap l, Vertex goal) : m_location(l), m_goal(goal) {} + CostType operator()(Vertex u) + { + float dx = m_location[m_goal].x - m_location[u].x; + float dy = m_location[m_goal].y - m_location[u].y; + return CostType(::sqrt(dx * dx + dy * dy)); + } + private: - LocMap m_location; - Vertex m_goal; + LocMap m_location; + Vertex m_goal; }; - -struct found_goal {}; // exception for termination +struct found_goal +{ +}; // exception for termination // visitor that terminates when we find the goal -template +template < class Vertex > class astar_goal_visitor : public boost::default_astar_visitor { public: - astar_goal_visitor(Vertex goal) : m_goal(goal) {} - template - void examine_vertex(Vertex u, Graph&) { - if(u == m_goal) - throw found_goal(); - } + astar_goal_visitor(Vertex goal) : m_goal(goal) {} + template < class Graph > void examine_vertex(Vertex u, Graph&) + { + if (u == m_goal) + throw found_goal(); + } + private: - Vertex m_goal; + Vertex m_goal; }; - -int main(int, char **) +int main(int, char**) { - - // specify some types - typedef adjacency_list > mygraph_t; - typedef property_map::type WeightMap; - typedef mygraph_t::vertex_descriptor vertex; - typedef mygraph_t::edge_descriptor edge_descriptor; - typedef std::pair edge; - - // specify data - enum nodes { - Troy, LakePlacid, Plattsburgh, Massena, Watertown, Utica, - Syracuse, Rochester, Buffalo, Ithaca, Binghamton, Woodstock, - NewYork, N - }; - const char *name[] = { - "Troy", "Lake Placid", "Plattsburgh", "Massena", - "Watertown", "Utica", "Syracuse", "Rochester", "Buffalo", - "Ithaca", "Binghamton", "Woodstock", "New York" - }; - location locations[] = { // lat/long - {42.73, 73.68}, {44.28, 73.99}, {44.70, 73.46}, - {44.93, 74.89}, {43.97, 75.91}, {43.10, 75.23}, - {43.04, 76.14}, {43.17, 77.61}, {42.89, 78.86}, - {42.44, 76.50}, {42.10, 75.91}, {42.04, 74.11}, - {40.67, 73.94} - }; - edge edge_array[] = { - edge(Troy,Utica), edge(Troy,LakePlacid), - edge(Troy,Plattsburgh), edge(LakePlacid,Plattsburgh), - edge(Plattsburgh,Massena), edge(LakePlacid,Massena), - edge(Massena,Watertown), edge(Watertown,Utica), - edge(Watertown,Syracuse), edge(Utica,Syracuse), - edge(Syracuse,Rochester), edge(Rochester,Buffalo), - edge(Syracuse,Ithaca), edge(Ithaca,Binghamton), - edge(Ithaca,Rochester), edge(Binghamton,Troy), - edge(Binghamton,Woodstock), edge(Binghamton,NewYork), - edge(Syracuse,Binghamton), edge(Woodstock,Troy), - edge(Woodstock,NewYork) - }; - unsigned int num_edges = sizeof(edge_array) / sizeof(edge); - cost weights[] = { // estimated travel time (mins) - my_float(96), my_float(134), my_float(143), my_float(65), my_float(115), my_float(133), my_float(117), my_float(116), my_float(74), my_float(56), - my_float(84), my_float(73), my_float(69), my_float(70), my_float(116), my_float(147), my_float(173), my_float(183), my_float(74), my_float(71), my_float(124) - }; - - - // create graph - mygraph_t g(N); - WeightMap weightmap = get(edge_weight, g); - for(std::size_t j = 0; j < num_edges; ++j) { - edge_descriptor e; bool inserted; - boost::tie(e, inserted) = add_edge(edge_array[j].first, - edge_array[j].second, g); - weightmap[e] = weights[j]; - } - - - // pick random start/goal - boost::minstd_rand gen(time(0)); - vertex start = gen() % num_vertices(g); - vertex goal = gen() % num_vertices(g); - - - cout << "Start vertex: " << name[start] << endl; - cout << "Goal vertex: " << name[goal] << endl; - - vector p(num_vertices(g)); - vector d(num_vertices(g)); - - boost::property_map::const_type - idx = get(boost::vertex_index, g); - - try { - // call astar named parameter interface - astar_search - (g, start, - distance_heuristic - (locations, goal), - predecessor_map(make_iterator_property_map(p.begin(), idx)). - distance_map(make_iterator_property_map(d.begin(), idx)). - visitor(astar_goal_visitor(goal)).distance_inf(my_float((std::numeric_limits::max)()))); - - - } catch(found_goal fg) { // found a path to the goal - list shortest_path; - for(vertex v = goal;; v = p[v]) { - shortest_path.push_front(v); - if(p[v] == v) - break; + + // specify some types + typedef adjacency_list< listS, vecS, undirectedS, no_property, + property< edge_weight_t, cost > > + mygraph_t; + typedef property_map< mygraph_t, edge_weight_t >::type WeightMap; + typedef mygraph_t::vertex_descriptor vertex; + typedef mygraph_t::edge_descriptor edge_descriptor; + typedef std::pair< int, int > edge; + + // specify data + enum nodes + { + Troy, + LakePlacid, + Plattsburgh, + Massena, + Watertown, + Utica, + Syracuse, + Rochester, + Buffalo, + Ithaca, + Binghamton, + Woodstock, + NewYork, + N + }; + const char* name[] = { "Troy", "Lake Placid", "Plattsburgh", "Massena", + "Watertown", "Utica", "Syracuse", "Rochester", "Buffalo", "Ithaca", + "Binghamton", "Woodstock", "New York" }; + location locations[] = { // lat/long + { 42.73, 73.68 }, { 44.28, 73.99 }, { 44.70, 73.46 }, { 44.93, 74.89 }, + { 43.97, 75.91 }, { 43.10, 75.23 }, { 43.04, 76.14 }, { 43.17, 77.61 }, + { 42.89, 78.86 }, { 42.44, 76.50 }, { 42.10, 75.91 }, { 42.04, 74.11 }, + { 40.67, 73.94 } + }; + edge edge_array[] + = { edge(Troy, Utica), edge(Troy, LakePlacid), edge(Troy, Plattsburgh), + edge(LakePlacid, Plattsburgh), edge(Plattsburgh, Massena), + edge(LakePlacid, Massena), edge(Massena, Watertown), + edge(Watertown, Utica), edge(Watertown, Syracuse), + edge(Utica, Syracuse), edge(Syracuse, Rochester), + edge(Rochester, Buffalo), edge(Syracuse, Ithaca), + edge(Ithaca, Binghamton), edge(Ithaca, Rochester), + edge(Binghamton, Troy), edge(Binghamton, Woodstock), + edge(Binghamton, NewYork), edge(Syracuse, Binghamton), + edge(Woodstock, Troy), edge(Woodstock, NewYork) }; + unsigned int num_edges = sizeof(edge_array) / sizeof(edge); + cost weights[] = { // estimated travel time (mins) + my_float(96), my_float(134), my_float(143), my_float(65), my_float(115), + my_float(133), my_float(117), my_float(116), my_float(74), my_float(56), + my_float(84), my_float(73), my_float(69), my_float(70), my_float(116), + my_float(147), my_float(173), my_float(183), my_float(74), my_float(71), + my_float(124) + }; + + // create graph + mygraph_t g(N); + WeightMap weightmap = get(edge_weight, g); + for (std::size_t j = 0; j < num_edges; ++j) + { + edge_descriptor e; + bool inserted; + boost::tie(e, inserted) + = add_edge(edge_array[j].first, edge_array[j].second, g); + weightmap[e] = weights[j]; + } + + // pick random start/goal + boost::minstd_rand gen(time(0)); + vertex start = gen() % num_vertices(g); + vertex goal = gen() % num_vertices(g); + + cout << "Start vertex: " << name[start] << endl; + cout << "Goal vertex: " << name[goal] << endl; + + vector< mygraph_t::vertex_descriptor > p(num_vertices(g)); + vector< cost > d(num_vertices(g)); + + boost::property_map< mygraph_t, boost::vertex_index_t >::const_type idx + = get(boost::vertex_index, g); + + try + { + // call astar named parameter interface + astar_search(g, start, + distance_heuristic< mygraph_t, cost, location* >(locations, goal), + predecessor_map(make_iterator_property_map(p.begin(), idx)) + .distance_map(make_iterator_property_map(d.begin(), idx)) + .visitor(astar_goal_visitor< vertex >(goal)) + .distance_inf(my_float((std::numeric_limits< float >::max)()))); + } + catch (found_goal fg) + { // found a path to the goal + list< vertex > shortest_path; + for (vertex v = goal;; v = p[v]) + { + shortest_path.push_front(v); + if (p[v] == v) + break; + } + cout << "Shortest path from " << name[start] << " to " << name[goal] + << ": "; + list< vertex >::iterator spi = shortest_path.begin(); + cout << name[start]; + for (++spi; spi != shortest_path.end(); ++spi) + cout << " -> " << name[*spi]; + cout << endl << "Total travel time: " << d[goal] << endl; + return 0; } - cout << "Shortest path from " << name[start] << " to " - << name[goal] << ": "; - list::iterator spi = shortest_path.begin(); - cout << name[start]; - for(++spi; spi != shortest_path.end(); ++spi) - cout << " -> " << name[*spi]; - cout << endl << "Total travel time: " << d[goal] << endl; + + cout << "Didn't find a path from " << name[start] << "to" << name[goal] + << "!" << endl; return 0; - } - - cout << "Didn't find a path from " << name[start] << "to" - << name[goal] << "!" << endl; - return 0; - } diff --git a/test/basic_planarity_test.cpp b/test/basic_planarity_test.cpp index 21ae969a6..434178aab 100644 --- a/test/basic_planarity_test.cpp +++ b/test/basic_planarity_test.cpp @@ -11,249 +11,211 @@ #include #include #include -#include - +#include using namespace boost; - struct VertexIndexUpdater { - template - void reset(Graph& g) - { - typename property_map::type index = get(vertex_index, g); - typename graph_traits::vertex_iterator vi, vi_end; - typename graph_traits::vertices_size_type cnt = 0; - for(boost::tie(vi,vi_end) = vertices(g); vi != vi_end; ++vi) - put(index, *vi, cnt++); - } + template < typename Graph > void reset(Graph& g) + { + typename property_map< Graph, vertex_index_t >::type index + = get(vertex_index, g); + typename graph_traits< Graph >::vertex_iterator vi, vi_end; + typename graph_traits< Graph >::vertices_size_type cnt = 0; + for (boost::tie(vi, vi_end) = vertices(g); vi != vi_end; ++vi) + put(index, *vi, cnt++); + } }; struct NoVertexIndexUpdater { - template void reset(Graph&) {} + template < typename Graph > void reset(Graph&) {} }; - - -template +template < typename Graph, typename VertexIndexUpdater > void test_K_5(VertexIndexUpdater vertex_index) { - typedef typename graph_traits::vertex_descriptor vertex_t; - - Graph g; - vertex_t v1 = add_vertex(g); - vertex_t v2 = add_vertex(g); - vertex_t v3 = add_vertex(g); - vertex_t v4 = add_vertex(g); - vertex_t v5 = add_vertex(g); - vertex_index.reset(g); - - BOOST_CHECK(boyer_myrvold_planarity_test(g)); - add_edge(v1, v2, g); - BOOST_CHECK(boyer_myrvold_planarity_test(g)); - add_edge(v1, v3, g); - BOOST_CHECK(boyer_myrvold_planarity_test(g)); - add_edge(v1, v4, g); - BOOST_CHECK(boyer_myrvold_planarity_test(g)); - add_edge(v1, v5, g); - BOOST_CHECK(boyer_myrvold_planarity_test(g)); - add_edge(v2, v3, g); - BOOST_CHECK(boyer_myrvold_planarity_test(g)); - add_edge(v2, v4, g); - BOOST_CHECK(boyer_myrvold_planarity_test(g)); - add_edge(v2, v5, g); - BOOST_CHECK(boyer_myrvold_planarity_test(g)); - add_edge(v3, v4, g); - BOOST_CHECK(boyer_myrvold_planarity_test(g)); - add_edge(v3, v5, g); - BOOST_CHECK(boyer_myrvold_planarity_test(g)); - - //This edge should make the graph non-planar - add_edge(v4, v5, g); - BOOST_CHECK(!boyer_myrvold_planarity_test(g)); - + typedef typename graph_traits< Graph >::vertex_descriptor vertex_t; + + Graph g; + vertex_t v1 = add_vertex(g); + vertex_t v2 = add_vertex(g); + vertex_t v3 = add_vertex(g); + vertex_t v4 = add_vertex(g); + vertex_t v5 = add_vertex(g); + vertex_index.reset(g); + + BOOST_TEST(boyer_myrvold_planarity_test(g)); + add_edge(v1, v2, g); + BOOST_TEST(boyer_myrvold_planarity_test(g)); + add_edge(v1, v3, g); + BOOST_TEST(boyer_myrvold_planarity_test(g)); + add_edge(v1, v4, g); + BOOST_TEST(boyer_myrvold_planarity_test(g)); + add_edge(v1, v5, g); + BOOST_TEST(boyer_myrvold_planarity_test(g)); + add_edge(v2, v3, g); + BOOST_TEST(boyer_myrvold_planarity_test(g)); + add_edge(v2, v4, g); + BOOST_TEST(boyer_myrvold_planarity_test(g)); + add_edge(v2, v5, g); + BOOST_TEST(boyer_myrvold_planarity_test(g)); + add_edge(v3, v4, g); + BOOST_TEST(boyer_myrvold_planarity_test(g)); + add_edge(v3, v5, g); + BOOST_TEST(boyer_myrvold_planarity_test(g)); + + // This edge should make the graph non-planar + add_edge(v4, v5, g); + BOOST_TEST(!boyer_myrvold_planarity_test(g)); } - - - - -template +template < typename Graph, typename VertexIndexUpdater > void test_K_3_3(VertexIndexUpdater vertex_index) { - typedef typename graph_traits::vertex_descriptor vertex_t; - - Graph g; - vertex_t v1 = add_vertex(g); - vertex_t v2 = add_vertex(g); - vertex_t v3 = add_vertex(g); - vertex_t v4 = add_vertex(g); - vertex_t v5 = add_vertex(g); - vertex_t v6 = add_vertex(g); - vertex_index.reset(g); - - BOOST_CHECK(boyer_myrvold_planarity_test(g)); - add_edge(v1, v4, g); - BOOST_CHECK(boyer_myrvold_planarity_test(g)); - add_edge(v1, v5, g); - BOOST_CHECK(boyer_myrvold_planarity_test(g)); - add_edge(v1, v6, g); - BOOST_CHECK(boyer_myrvold_planarity_test(g)); - add_edge(v2, v4, g); - BOOST_CHECK(boyer_myrvold_planarity_test(g)); - add_edge(v2, v5, g); - BOOST_CHECK(boyer_myrvold_planarity_test(g)); - add_edge(v2, v6, g); - BOOST_CHECK(boyer_myrvold_planarity_test(g)); - add_edge(v3, v4, g); - BOOST_CHECK(boyer_myrvold_planarity_test(g)); - add_edge(v3, v5, g); - BOOST_CHECK(boyer_myrvold_planarity_test(g)); - - //This edge should make the graph non-planar - add_edge(v3, v6, g); - BOOST_CHECK(!boyer_myrvold_planarity_test(g)); - + typedef typename graph_traits< Graph >::vertex_descriptor vertex_t; + + Graph g; + vertex_t v1 = add_vertex(g); + vertex_t v2 = add_vertex(g); + vertex_t v3 = add_vertex(g); + vertex_t v4 = add_vertex(g); + vertex_t v5 = add_vertex(g); + vertex_t v6 = add_vertex(g); + vertex_index.reset(g); + + BOOST_TEST(boyer_myrvold_planarity_test(g)); + add_edge(v1, v4, g); + BOOST_TEST(boyer_myrvold_planarity_test(g)); + add_edge(v1, v5, g); + BOOST_TEST(boyer_myrvold_planarity_test(g)); + add_edge(v1, v6, g); + BOOST_TEST(boyer_myrvold_planarity_test(g)); + add_edge(v2, v4, g); + BOOST_TEST(boyer_myrvold_planarity_test(g)); + add_edge(v2, v5, g); + BOOST_TEST(boyer_myrvold_planarity_test(g)); + add_edge(v2, v6, g); + BOOST_TEST(boyer_myrvold_planarity_test(g)); + add_edge(v3, v4, g); + BOOST_TEST(boyer_myrvold_planarity_test(g)); + add_edge(v3, v5, g); + BOOST_TEST(boyer_myrvold_planarity_test(g)); + + // This edge should make the graph non-planar + add_edge(v3, v6, g); + BOOST_TEST(!boyer_myrvold_planarity_test(g)); } - - - - // This test creates a maximal planar graph on num_vertices vertices, // then, if num_vertices is at least 5, adds an additional edge to // create a non-planar graph. -template -void test_maximal_planar(VertexIndexUpdater vertex_index, std::size_t num_vertices) +template < typename Graph, typename VertexIndexUpdater > +void test_maximal_planar( + VertexIndexUpdater vertex_index, std::size_t num_vertices) { - typedef typename graph_traits::vertex_descriptor vertex_t; + typedef typename graph_traits< Graph >::vertex_descriptor vertex_t; - Graph g; - std::vector vmap; - for(std::size_t i = 0; i < num_vertices; ++i) - vmap.push_back(add_vertex(g)); + Graph g; + std::vector< vertex_t > vmap; + for (std::size_t i = 0; i < num_vertices; ++i) + vmap.push_back(add_vertex(g)); - vertex_index.reset(g); + vertex_index.reset(g); - BOOST_CHECK(boyer_myrvold_planarity_test(g)); - //create a cycle - for(std::size_t i = 0; i < num_vertices; ++i) + BOOST_TEST(boyer_myrvold_planarity_test(g)); + // create a cycle + for (std::size_t i = 0; i < num_vertices; ++i) { - add_edge(vmap[i], vmap[(i+1) % num_vertices], g); - BOOST_CHECK(boyer_myrvold_planarity_test(g)); + add_edge(vmap[i], vmap[(i + 1) % num_vertices], g); + BOOST_TEST(boyer_myrvold_planarity_test(g)); } - //triangulate the interior of the cycle. - for(std::size_t i = 2; i < num_vertices - 1; ++i) + // triangulate the interior of the cycle. + for (std::size_t i = 2; i < num_vertices - 1; ++i) { - add_edge(vmap[0], vmap[i], g); - BOOST_CHECK(boyer_myrvold_planarity_test(g)); + add_edge(vmap[0], vmap[i], g); + BOOST_TEST(boyer_myrvold_planarity_test(g)); } - //triangulate the exterior of the cycle. - for(std::size_t i = 3; i < num_vertices; ++i) + // triangulate the exterior of the cycle. + for (std::size_t i = 3; i < num_vertices; ++i) { - add_edge(vmap[1], vmap[i], g); - BOOST_CHECK(boyer_myrvold_planarity_test(g)); + add_edge(vmap[1], vmap[i], g); + BOOST_TEST(boyer_myrvold_planarity_test(g)); } - //Now add an additional edge, forcing the graph to be non-planar. - if (num_vertices > 4) + // Now add an additional edge, forcing the graph to be non-planar. + if (num_vertices > 4) { - add_edge(vmap[2], vmap[4], g); - BOOST_CHECK(!boyer_myrvold_planarity_test(g)); + add_edge(vmap[2], vmap[4], g); + BOOST_TEST(!boyer_myrvold_planarity_test(g)); } - } - - - - -int test_main(int, char* []) +int main(int, char*[]) { - typedef adjacency_list - - > - VVgraph_t; - - typedef adjacency_list - - > - VLgraph_t; - - typedef adjacency_list - - > - LVgraph_t; - - typedef adjacency_list - - > - LLgraph_t; - - typedef adjacency_list - - > - SSgraph_t; - - test_K_5(NoVertexIndexUpdater()); - test_K_3_3(NoVertexIndexUpdater()); - test_maximal_planar(NoVertexIndexUpdater(), 3); - test_maximal_planar(NoVertexIndexUpdater(), 6); - test_maximal_planar(NoVertexIndexUpdater(), 10); - test_maximal_planar(NoVertexIndexUpdater(), 20); - test_maximal_planar(NoVertexIndexUpdater(), 50); - - test_K_5(VertexIndexUpdater()); - test_K_3_3(VertexIndexUpdater()); - test_maximal_planar(VertexIndexUpdater(), 3); - test_maximal_planar(VertexIndexUpdater(), 6); - test_maximal_planar(VertexIndexUpdater(), 10); - test_maximal_planar(VertexIndexUpdater(), 20); - test_maximal_planar(VertexIndexUpdater(), 50); - - test_K_5(NoVertexIndexUpdater()); - test_K_3_3(NoVertexIndexUpdater()); - test_maximal_planar(NoVertexIndexUpdater(), 3); - test_maximal_planar(NoVertexIndexUpdater(), 6); - test_maximal_planar(NoVertexIndexUpdater(), 10); - test_maximal_planar(NoVertexIndexUpdater(), 20); - test_maximal_planar(NoVertexIndexUpdater(), 50); - - test_K_5(VertexIndexUpdater()); - test_K_3_3(VertexIndexUpdater()); - test_maximal_planar(VertexIndexUpdater(), 3); - test_maximal_planar(VertexIndexUpdater(), 6); - test_maximal_planar(VertexIndexUpdater(), 10); - test_maximal_planar(VertexIndexUpdater(), 20); - test_maximal_planar(VertexIndexUpdater(), 50); - - test_K_5(VertexIndexUpdater()); - test_K_3_3(VertexIndexUpdater()); - test_maximal_planar(VertexIndexUpdater(), 3); - test_maximal_planar(VertexIndexUpdater(), 6); - test_maximal_planar(VertexIndexUpdater(), 10); - test_maximal_planar(VertexIndexUpdater(), 20); - test_maximal_planar(VertexIndexUpdater(), 50); - - return 0; + typedef adjacency_list< vecS, vecS, undirectedS, + property< vertex_index_t, int > > + VVgraph_t; + + typedef adjacency_list< vecS, listS, undirectedS, + property< vertex_index_t, int > > + VLgraph_t; + + typedef adjacency_list< listS, vecS, undirectedS, + property< vertex_index_t, int > > + LVgraph_t; + + typedef adjacency_list< listS, listS, undirectedS, + property< vertex_index_t, int > > + LLgraph_t; + + typedef adjacency_list< setS, setS, undirectedS, + property< vertex_index_t, int > > + SSgraph_t; + + test_K_5< VVgraph_t >(NoVertexIndexUpdater()); + test_K_3_3< VVgraph_t >(NoVertexIndexUpdater()); + test_maximal_planar< VVgraph_t >(NoVertexIndexUpdater(), 3); + test_maximal_planar< VVgraph_t >(NoVertexIndexUpdater(), 6); + test_maximal_planar< VVgraph_t >(NoVertexIndexUpdater(), 10); + test_maximal_planar< VVgraph_t >(NoVertexIndexUpdater(), 20); + test_maximal_planar< VVgraph_t >(NoVertexIndexUpdater(), 50); + + test_K_5< VLgraph_t >(VertexIndexUpdater()); + test_K_3_3< VLgraph_t >(VertexIndexUpdater()); + test_maximal_planar< VLgraph_t >(VertexIndexUpdater(), 3); + test_maximal_planar< VLgraph_t >(VertexIndexUpdater(), 6); + test_maximal_planar< VLgraph_t >(VertexIndexUpdater(), 10); + test_maximal_planar< VLgraph_t >(VertexIndexUpdater(), 20); + test_maximal_planar< VLgraph_t >(VertexIndexUpdater(), 50); + + test_K_5< LVgraph_t >(NoVertexIndexUpdater()); + test_K_3_3< LVgraph_t >(NoVertexIndexUpdater()); + test_maximal_planar< LVgraph_t >(NoVertexIndexUpdater(), 3); + test_maximal_planar< LVgraph_t >(NoVertexIndexUpdater(), 6); + test_maximal_planar< LVgraph_t >(NoVertexIndexUpdater(), 10); + test_maximal_planar< LVgraph_t >(NoVertexIndexUpdater(), 20); + test_maximal_planar< LVgraph_t >(NoVertexIndexUpdater(), 50); + + test_K_5< LLgraph_t >(VertexIndexUpdater()); + test_K_3_3< LLgraph_t >(VertexIndexUpdater()); + test_maximal_planar< LLgraph_t >(VertexIndexUpdater(), 3); + test_maximal_planar< LLgraph_t >(VertexIndexUpdater(), 6); + test_maximal_planar< LLgraph_t >(VertexIndexUpdater(), 10); + test_maximal_planar< LLgraph_t >(VertexIndexUpdater(), 20); + test_maximal_planar< LLgraph_t >(VertexIndexUpdater(), 50); + + test_K_5< SSgraph_t >(VertexIndexUpdater()); + test_K_3_3< SSgraph_t >(VertexIndexUpdater()); + test_maximal_planar< SSgraph_t >(VertexIndexUpdater(), 3); + test_maximal_planar< SSgraph_t >(VertexIndexUpdater(), 6); + test_maximal_planar< SSgraph_t >(VertexIndexUpdater(), 10); + test_maximal_planar< SSgraph_t >(VertexIndexUpdater(), 20); + test_maximal_planar< SSgraph_t >(VertexIndexUpdater(), 50); + + return boost::report_errors(); } diff --git a/test/bellman-test.cpp b/test/bellman-test.cpp index a285b31d7..94e5332b2 100644 --- a/test/bellman-test.cpp +++ b/test/bellman-test.cpp @@ -1,4 +1,4 @@ -// (C) Copyright Jeremy Siek 2004 +// (C) Copyright Jeremy Siek 2004 // Distributed under the Boost Software License, Version 1.0. (See // accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) @@ -18,92 +18,107 @@ B: 2147483647 B #include #include #include -#include +#include -int test_main(int, char*[]) +int main(int, char*[]) { - using namespace boost; - - enum { A, B, Z }; - char const name[] = "ABZ"; - int const numVertex = static_cast(Z) + 1; - typedef std::pair Edge; - Edge edge_array[] = {Edge(B,A)}; - int const numEdges = sizeof(edge_array) / sizeof(Edge); - int const weight[numEdges] = {11}; - - typedef adjacency_list > Graph; - - Graph g(edge_array, edge_array + numEdges, numVertex); - - Graph::edge_iterator ei, ei_end; - property_map::type - weight_pmap = get(edge_weight, g); - - int i = 0; - for(boost::tie(ei, ei_end) = edges(g); ei != ei_end; ++ei, ++i) - weight_pmap[*ei] = weight[i]; - - std::vector parent(numVertex); - for(i = 0; i < numVertex; ++i) - parent[i] = i; - - int inf = (std::numeric_limits::max)(); - std::vector distance(numVertex, inf); - distance[A] = 0; // Set source distance to zero - - bool const r = bellman_ford_shortest_paths - (g, int (numVertex), - weight_pmap, - boost::make_iterator_property_map(parent.begin(), get(boost::vertex_index, g)), - boost::make_iterator_property_map(distance.begin(), get(boost::vertex_index, g)), - closed_plus(), - std::less(), - default_bellman_visitor()); - - if (r) { - for(int i = 0; i < numVertex; ++i) { - std::cout << name[i] << ": "; - if (distance[i] == inf) - std::cout << std::setw(3) << "inf"; - else - std::cout << std::setw(3) << distance[i]; - std::cout << " " << name[parent[i]] << std::endl; + using namespace boost; + + enum + { + A, + B, + Z + }; + char const name[] = "ABZ"; + int const numVertex = static_cast< int >(Z) + 1; + typedef std::pair< int, int > Edge; + Edge edge_array[] = { Edge(B, A) }; + int const numEdges = sizeof(edge_array) / sizeof(Edge); + int const weight[numEdges] = { 11 }; + + typedef adjacency_list< vecS, vecS, undirectedS, no_property, + property< edge_weight_t, int > > + Graph; + + Graph g(edge_array, edge_array + numEdges, numVertex); + + Graph::edge_iterator ei, ei_end; + property_map< Graph, edge_weight_t >::type weight_pmap + = get(edge_weight, g); + + int i = 0; + for (boost::tie(ei, ei_end) = edges(g); ei != ei_end; ++ei, ++i) + weight_pmap[*ei] = weight[i]; + + std::vector< int > parent(numVertex); + for (i = 0; i < numVertex; ++i) + parent[i] = i; + + int inf = (std::numeric_limits< int >::max)(); + std::vector< int > distance(numVertex, inf); + distance[A] = 0; // Set source distance to zero + + bool const r = bellman_ford_shortest_paths(g, int(numVertex), weight_pmap, + boost::make_iterator_property_map( + parent.begin(), get(boost::vertex_index, g)), + boost::make_iterator_property_map( + distance.begin(), get(boost::vertex_index, g)), + closed_plus< int >(), std::less< int >(), default_bellman_visitor()); + + if (r) + { + for (int i = 0; i < numVertex; ++i) + { + std::cout << name[i] << ": "; + if (distance[i] == inf) + std::cout << std::setw(3) << "inf"; + else + std::cout << std::setw(3) << distance[i]; + std::cout << " " << name[parent[i]] << std::endl; + } } - } else { - std::cout << "negative cycle" << std::endl; - } - -#if !(defined(__INTEL_COMPILER) && __INTEL_COMPILER <= 700) && !(defined(BOOST_MSVC) && BOOST_MSVC <= 1300) - graph_traits::vertex_descriptor s = vertex(A, g); - std::vector parent2(numVertex); - std::vector distance2(numVertex, 17); - bool const r2 = bellman_ford_shortest_paths - (g, - weight_map(weight_pmap). - distance_map(boost::make_iterator_property_map(distance2.begin(), get(boost::vertex_index, g))). - predecessor_map(boost::make_iterator_property_map(parent2.begin(), get(boost::vertex_index, g))). - root_vertex(s)); - if (r2) { - for(int i = 0; i < numVertex; ++i) { - std::cout << name[i] << ": "; - if (distance2[i] == inf) - std::cout << std::setw(3) << "inf"; - else - std::cout << std::setw(3) << distance2[i]; - std::cout << " " << name[parent2[i]] << std::endl; + else + { + std::cout << "negative cycle" << std::endl; + } + +#if !(defined(__INTEL_COMPILER) && __INTEL_COMPILER <= 700) \ + && !(defined(BOOST_MSVC) && BOOST_MSVC <= 1300) + graph_traits< Graph >::vertex_descriptor s = vertex(A, g); + std::vector< int > parent2(numVertex); + std::vector< int > distance2(numVertex, 17); + bool const r2 = bellman_ford_shortest_paths(g, + weight_map(weight_pmap) + .distance_map(boost::make_iterator_property_map( + distance2.begin(), get(boost::vertex_index, g))) + .predecessor_map(boost::make_iterator_property_map( + parent2.begin(), get(boost::vertex_index, g))) + .root_vertex(s)); + if (r2) + { + for (int i = 0; i < numVertex; ++i) + { + std::cout << name[i] << ": "; + if (distance2[i] == inf) + std::cout << std::setw(3) << "inf"; + else + std::cout << std::setw(3) << distance2[i]; + std::cout << " " << name[parent2[i]] << std::endl; + } + } + else + { + std::cout << "negative cycle" << std::endl; + } + + BOOST_TEST(r == r2); + if (r && r2) + { + BOOST_TEST(parent == parent2); + BOOST_TEST(distance == distance2); } - } else { - std::cout << "negative cycle" << std::endl; - } - - BOOST_CHECK(r == r2); - if (r && r2) { - BOOST_CHECK(parent == parent2); - BOOST_CHECK(distance == distance2); - } #endif - return boost::exit_success; + return boost::report_errors(); } diff --git a/test/betweenness_centrality_test.cpp b/test/betweenness_centrality_test.cpp index 9fb69cf70..8a2a02453 100644 --- a/test/betweenness_centrality_test.cpp +++ b/test/betweenness_centrality_test.cpp @@ -13,7 +13,7 @@ #include #include #include -#include +#include #include #include #include @@ -22,499 +22,492 @@ using namespace boost; const double error_tolerance = 0.001; -typedef property > EdgeProperties; +typedef property< edge_weight_t, double, property< edge_index_t, std::size_t > > + EdgeProperties; -struct weighted_edge +struct weighted_edge { - int source, target; - double weight; + int source, target; + double weight; }; -template -void -run_weighted_test(Graph*, int V, weighted_edge edge_init[], int E, - double correct_centrality[]) +template < typename Graph > +void run_weighted_test(Graph*, int V, weighted_edge edge_init[], int E, + double correct_centrality[]) { - Graph g(V); - typedef typename graph_traits::vertex_descriptor Vertex; - typedef typename graph_traits::vertex_iterator vertex_iterator; - typedef typename graph_traits::edge_descriptor Edge; - - std::vector vertices(V); - { - vertex_iterator v, v_end; - int index = 0; - for (boost::tie(v, v_end) = boost::vertices(g); v != v_end; ++v, ++index) { - put(vertex_index, g, *v, index); - vertices[index] = *v; + Graph g(V); + typedef typename graph_traits< Graph >::vertex_descriptor Vertex; + typedef typename graph_traits< Graph >::vertex_iterator vertex_iterator; + typedef typename graph_traits< Graph >::edge_descriptor Edge; + + std::vector< Vertex > vertices(V); + { + vertex_iterator v, v_end; + int index = 0; + for (boost::tie(v, v_end) = boost::vertices(g); v != v_end; + ++v, ++index) + { + put(vertex_index, g, *v, index); + vertices[index] = *v; + } + } + + std::vector< Edge > edges(E); + for (int e = 0; e < E; ++e) + { + edges[e] = add_edge( + vertices[edge_init[e].source], vertices[edge_init[e].target], g) + .first; + put(edge_weight, g, edges[e], 1.0); + } + + std::vector< double > centrality(V); + brandes_betweenness_centrality(g, + centrality_map(make_iterator_property_map( + centrality.begin(), get(vertex_index, g), double())) + .vertex_index_map(get(vertex_index, g)) + .weight_map(get(edge_weight, g))); + + for (int v = 0; v < V; ++v) + { + BOOST_TEST(centrality[v] == correct_centrality[v]); } - } - - std::vector edges(E); - for (int e = 0; e < E; ++e) { - edges[e] = add_edge(vertices[edge_init[e].source], - vertices[edge_init[e].target], - g).first; - put(edge_weight, g, edges[e], 1.0); - } - - std::vector centrality(V); - brandes_betweenness_centrality( - g, - centrality_map( - make_iterator_property_map(centrality.begin(), get(vertex_index, g), - double())) - .vertex_index_map(get(vertex_index, g)).weight_map(get(edge_weight, g))); - - - for (int v = 0; v < V; ++v) { - BOOST_CHECK(centrality[v] == correct_centrality[v]); - } } -struct unweighted_edge +struct unweighted_edge { - int source, target; + int source, target; }; -template -void -run_unweighted_test(Graph*, int V, unweighted_edge edge_init[], int E, - double correct_centrality[], - double* correct_edge_centrality = 0) +template < typename Graph > +void run_unweighted_test(Graph*, int V, unweighted_edge edge_init[], int E, + double correct_centrality[], double* correct_edge_centrality = 0) { - Graph g(V); - typedef typename graph_traits::vertex_descriptor Vertex; - typedef typename graph_traits::vertex_iterator vertex_iterator; - typedef typename graph_traits::edge_descriptor Edge; - - std::vector vertices(V); - { - vertex_iterator v, v_end; - int index = 0; - for (boost::tie(v, v_end) = boost::vertices(g); v != v_end; ++v, ++index) { - put(vertex_index, g, *v, index); - vertices[index] = *v; + Graph g(V); + typedef typename graph_traits< Graph >::vertex_descriptor Vertex; + typedef typename graph_traits< Graph >::vertex_iterator vertex_iterator; + typedef typename graph_traits< Graph >::edge_descriptor Edge; + + std::vector< Vertex > vertices(V); + { + vertex_iterator v, v_end; + int index = 0; + for (boost::tie(v, v_end) = boost::vertices(g); v != v_end; + ++v, ++index) + { + put(vertex_index, g, *v, index); + vertices[index] = *v; + } } - } - - std::vector edges(E); - for (int e = 0; e < E; ++e) { - edges[e] = add_edge(vertices[edge_init[e].source], - vertices[edge_init[e].target], - g).first; - put(edge_weight, g, edges[e], 1.0); - put(edge_index, g, edges[e], e); - } - - std::vector centrality(V); - std::vector edge_centrality1(E); - - brandes_betweenness_centrality( - g, - centrality_map( - make_iterator_property_map(centrality.begin(), get(vertex_index, g), - double())) - .edge_centrality_map( - make_iterator_property_map(edge_centrality1.begin(), - get(edge_index, g), double())) - .vertex_index_map(get(vertex_index, g))); - - std::vector centrality2(V); - std::vector edge_centrality2(E); - brandes_betweenness_centrality( - g, - vertex_index_map(get(vertex_index, g)).weight_map(get(edge_weight, g)) - .centrality_map( - make_iterator_property_map(centrality2.begin(), get(vertex_index, g), - double())) - .edge_centrality_map( - make_iterator_property_map(edge_centrality2.begin(), - get(edge_index, g), double()))); - - std::vector edge_centrality3(E); - brandes_betweenness_centrality( - g, - edge_centrality_map( - make_iterator_property_map(edge_centrality3.begin(), - get(edge_index, g), double()))); - - for (int v = 0; v < V; ++v) { - BOOST_CHECK(centrality[v] == centrality2[v]); - - double relative_error = - correct_centrality[v] == 0.0? centrality[v] - : (centrality[v] - correct_centrality[v]) / correct_centrality[v]; - if (relative_error < 0) relative_error = -relative_error; - BOOST_CHECK(relative_error < error_tolerance); - } - - for (int e = 0; e < E; ++e) { - BOOST_CHECK(edge_centrality1[e] == edge_centrality2[e]); - BOOST_CHECK(edge_centrality1[e] == edge_centrality3[e]); - - if (correct_edge_centrality) { - double relative_error = - correct_edge_centrality[e] == 0.0? edge_centrality1[e] - : (edge_centrality1[e] - correct_edge_centrality[e]) - / correct_edge_centrality[e]; - if (relative_error < 0) relative_error = -relative_error; - BOOST_CHECK(relative_error < error_tolerance); - - if (relative_error >= error_tolerance) { - std::cerr << "Edge " << e << " has edge centrality " - << edge_centrality1[e] << ", should be " - << correct_edge_centrality[e] << std::endl; - } + + std::vector< Edge > edges(E); + for (int e = 0; e < E; ++e) + { + edges[e] = add_edge( + vertices[edge_init[e].source], vertices[edge_init[e].target], g) + .first; + put(edge_weight, g, edges[e], 1.0); + put(edge_index, g, edges[e], e); } - } -} -template -void -run_wheel_test(Graph*, int V) -{ - typedef typename graph_traits::vertex_descriptor Vertex; - typedef typename graph_traits::vertex_iterator vertex_iterator; - typedef typename graph_traits::edge_descriptor Edge; - - Graph g(V); - Vertex center = *boost::vertices(g).first; - - std::vector vertices(V); - { - vertex_iterator v, v_end; - int index = 0; - for (boost::tie(v, v_end) = boost::vertices(g); v != v_end; ++v, ++index) { - put(vertex_index, g, *v, index); - vertices[index] = *v; - if (*v != center) { - Edge e = add_edge(*v, center, g).first; - put(edge_weight, g, e, 1.0); - } + std::vector< double > centrality(V); + std::vector< double > edge_centrality1(E); + + brandes_betweenness_centrality(g, + centrality_map(make_iterator_property_map( + centrality.begin(), get(vertex_index, g), double())) + .edge_centrality_map(make_iterator_property_map( + edge_centrality1.begin(), get(edge_index, g), double())) + .vertex_index_map(get(vertex_index, g))); + + std::vector< double > centrality2(V); + std::vector< double > edge_centrality2(E); + brandes_betweenness_centrality(g, + vertex_index_map(get(vertex_index, g)) + .weight_map(get(edge_weight, g)) + .centrality_map(make_iterator_property_map( + centrality2.begin(), get(vertex_index, g), double())) + .edge_centrality_map(make_iterator_property_map( + edge_centrality2.begin(), get(edge_index, g), double()))); + + std::vector< double > edge_centrality3(E); + brandes_betweenness_centrality(g, + edge_centrality_map(make_iterator_property_map( + edge_centrality3.begin(), get(edge_index, g), double()))); + + for (int v = 0; v < V; ++v) + { + BOOST_TEST(centrality[v] == centrality2[v]); + + double relative_error = correct_centrality[v] == 0.0 + ? centrality[v] + : (centrality[v] - correct_centrality[v]) / correct_centrality[v]; + if (relative_error < 0) + relative_error = -relative_error; + BOOST_TEST(relative_error < error_tolerance); } - } - - std::vector centrality(V); - brandes_betweenness_centrality( - g, - make_iterator_property_map(centrality.begin(), get(vertex_index, g), - double())); - - std::vector centrality2(V); - brandes_betweenness_centrality( - g, - centrality_map( - make_iterator_property_map(centrality2.begin(), get(vertex_index, g), - double())) - .vertex_index_map(get(vertex_index, g)).weight_map(get(edge_weight, g))); - - relative_betweenness_centrality( - g, - make_iterator_property_map(centrality.begin(), get(vertex_index, g), - double())); - - relative_betweenness_centrality( - g, - make_iterator_property_map(centrality2.begin(), get(vertex_index, g), - double())); - - for (int v = 0; v < V; ++v) { - BOOST_CHECK(centrality[v] == centrality2[v]); - BOOST_CHECK((v == 0 && centrality[v] == 1) - || (v != 0 && centrality[v] == 0)); - } - - double dominance = - central_point_dominance( - g, - make_iterator_property_map(centrality2.begin(), get(vertex_index, g), - double())); - BOOST_CHECK(dominance == 1.0); -} -template -void randomly_add_edges(MutableGraph& g, double edge_probability) -{ - typedef typename graph_traits::directed_category - directed_category; - - minstd_rand gen; - uniform_01 rand_gen(gen); - - typedef typename graph_traits::vertex_descriptor vertex; - typename graph_traits::vertex_iterator vi, vi_end; - for (boost::tie(vi, vi_end) = vertices(g); vi != vi_end; ++vi) { - vertex v = *vi; - typename graph_traits::vertex_iterator wi - = is_same::value ? vi : vertices(g).first; - while (wi != vi_end) { - vertex w = *wi++; - if (v != w) { - if (rand_gen() < edge_probability) add_edge(v, w, g); - } + for (int e = 0; e < E; ++e) + { + BOOST_TEST(edge_centrality1[e] == edge_centrality2[e]); + BOOST_TEST(edge_centrality1[e] == edge_centrality3[e]); + + if (correct_edge_centrality) + { + double relative_error = correct_edge_centrality[e] == 0.0 + ? edge_centrality1[e] + : (edge_centrality1[e] - correct_edge_centrality[e]) + / correct_edge_centrality[e]; + if (relative_error < 0) + relative_error = -relative_error; + BOOST_TEST(relative_error < error_tolerance); + + if (relative_error >= error_tolerance) + { + std::cerr << "Edge " << e << " has edge centrality " + << edge_centrality1[e] << ", should be " + << correct_edge_centrality[e] << std::endl; + } + } } - } } - -template -void -simple_unweighted_betweenness_centrality(const Graph& g, VertexIndexMap index, - CentralityMap centrality) +template < typename Graph > void run_wheel_test(Graph*, int V) { - typedef typename boost::graph_traits::vertex_descriptor vertex; - typedef typename boost::graph_traits::vertex_iterator vertex_iterator; - typedef typename boost::graph_traits::adjacency_iterator adjacency_iterator; - typedef typename boost::graph_traits::vertices_size_type vertices_size_type; - typedef typename boost::property_traits::value_type centrality_type; - - vertex_iterator vi, vi_end; - for (boost::tie(vi, vi_end) = vertices(g); vi != vi_end; ++vi) - put(centrality, *vi, 0); - - vertex_iterator si, si_end; - for (boost::tie(si, si_end) = vertices(g); si != si_end; ++si) { - vertex s = *si; - - // S <-- empty stack - std::stack S; - - // P[w] <-- empty list, w \in V - typedef std::vector Predecessors; - std::vector predecessors(num_vertices(g)); - - // sigma[t] <-- 0, t \in V - std::vector sigma(num_vertices(g), 0); - - // sigma[s] <-- 1 - sigma[get(index, s)] = 1; - - // d[t] <-- -1, t \in V - std::vector d(num_vertices(g), -1); - - // d[s] <-- 0 - d[get(index, s)] = 0; - - // Q <-- empty queue - std::queue Q; + typedef typename graph_traits< Graph >::vertex_descriptor Vertex; + typedef typename graph_traits< Graph >::vertex_iterator vertex_iterator; + typedef typename graph_traits< Graph >::edge_descriptor Edge; + + Graph g(V); + Vertex center = *boost::vertices(g).first; + + std::vector< Vertex > vertices(V); + { + vertex_iterator v, v_end; + int index = 0; + for (boost::tie(v, v_end) = boost::vertices(g); v != v_end; + ++v, ++index) + { + put(vertex_index, g, *v, index); + vertices[index] = *v; + if (*v != center) + { + Edge e = add_edge(*v, center, g).first; + put(edge_weight, g, e, 1.0); + } + } + } - // enqueue s --> Q - Q.push(s); + std::vector< double > centrality(V); + brandes_betweenness_centrality(g, + make_iterator_property_map( + centrality.begin(), get(vertex_index, g), double())); + + std::vector< double > centrality2(V); + brandes_betweenness_centrality(g, + centrality_map(make_iterator_property_map( + centrality2.begin(), get(vertex_index, g), double())) + .vertex_index_map(get(vertex_index, g)) + .weight_map(get(edge_weight, g))); + + relative_betweenness_centrality(g, + make_iterator_property_map( + centrality.begin(), get(vertex_index, g), double())); + + relative_betweenness_centrality(g, + make_iterator_property_map( + centrality2.begin(), get(vertex_index, g), double())); + + for (int v = 0; v < V; ++v) + { + BOOST_TEST(centrality[v] == centrality2[v]); + BOOST_TEST( + (v == 0 && centrality[v] == 1) || (v != 0 && centrality[v] == 0)); + } - while (!Q.empty()) { - // dequeue v <-- Q - vertex v = Q.front(); Q.pop(); + double dominance = central_point_dominance(g, + make_iterator_property_map( + centrality2.begin(), get(vertex_index, g), double())); + BOOST_TEST(dominance == 1.0); +} - // push v --> S - S.push(v); +template < typename MutableGraph > +void randomly_add_edges(MutableGraph& g, double edge_probability) +{ + typedef typename graph_traits< MutableGraph >::directed_category + directed_category; - adjacency_iterator wi, wi_end; - for (boost::tie(wi, wi_end) = adjacent_vertices(v, g); wi != wi_end; ++wi) { - vertex w = *wi; + minstd_rand gen; + uniform_01< minstd_rand, double > rand_gen(gen); - // w found for the first time? - if (d[get(index, w)] < 0) { - // enqueue w --> Q - Q.push(w); - - // d[w] <-- d[v] + 1 - d[get(index, w)] = d[get(index, v)] + 1; + typedef typename graph_traits< MutableGraph >::vertex_descriptor vertex; + typename graph_traits< MutableGraph >::vertex_iterator vi, vi_end; + for (boost::tie(vi, vi_end) = vertices(g); vi != vi_end; ++vi) + { + vertex v = *vi; + typename graph_traits< MutableGraph >::vertex_iterator wi + = is_same< directed_category, undirected_tag >::value + ? vi + : vertices(g).first; + while (wi != vi_end) + { + vertex w = *wi++; + if (v != w) + { + if (rand_gen() < edge_probability) + add_edge(v, w, g); + } } + } +} - // shortest path to w via v? - if (d[get(index, w)] == d[get(index, v)] + 1) { - // sigma[w] = sigma[w] + sigma[v] - sigma[get(index, w)] += sigma[get(index, v)]; +template < typename Graph, typename VertexIndexMap, typename CentralityMap > +void simple_unweighted_betweenness_centrality( + const Graph& g, VertexIndexMap index, CentralityMap centrality) +{ + typedef typename boost::graph_traits< Graph >::vertex_descriptor vertex; + typedef + typename boost::graph_traits< Graph >::vertex_iterator vertex_iterator; + typedef typename boost::graph_traits< Graph >::adjacency_iterator + adjacency_iterator; + typedef typename boost::graph_traits< Graph >::vertices_size_type + vertices_size_type; + typedef typename boost::property_traits< CentralityMap >::value_type + centrality_type; + + vertex_iterator vi, vi_end; + for (boost::tie(vi, vi_end) = vertices(g); vi != vi_end; ++vi) + put(centrality, *vi, 0); + + vertex_iterator si, si_end; + for (boost::tie(si, si_end) = vertices(g); si != si_end; ++si) + { + vertex s = *si; + + // S <-- empty stack + std::stack< vertex > S; + + // P[w] <-- empty list, w \in V + typedef std::vector< vertex > Predecessors; + std::vector< Predecessors > predecessors(num_vertices(g)); + + // sigma[t] <-- 0, t \in V + std::vector< vertices_size_type > sigma(num_vertices(g), 0); + + // sigma[s] <-- 1 + sigma[get(index, s)] = 1; + + // d[t] <-- -1, t \in V + std::vector< int > d(num_vertices(g), -1); + + // d[s] <-- 0 + d[get(index, s)] = 0; + + // Q <-- empty queue + std::queue< vertex > Q; + + // enqueue s --> Q + Q.push(s); + + while (!Q.empty()) + { + // dequeue v <-- Q + vertex v = Q.front(); + Q.pop(); + + // push v --> S + S.push(v); + + adjacency_iterator wi, wi_end; + for (boost::tie(wi, wi_end) = adjacent_vertices(v, g); wi != wi_end; + ++wi) + { + vertex w = *wi; + + // w found for the first time? + if (d[get(index, w)] < 0) + { + // enqueue w --> Q + Q.push(w); + + // d[w] <-- d[v] + 1 + d[get(index, w)] = d[get(index, v)] + 1; + } + + // shortest path to w via v? + if (d[get(index, w)] == d[get(index, v)] + 1) + { + // sigma[w] = sigma[w] + sigma[v] + sigma[get(index, w)] += sigma[get(index, v)]; + + // append v --> P[w] + predecessors[get(index, w)].push_back(v); + } + } + } - // append v --> P[w] - predecessors[get(index, w)].push_back(v); + // delta[v] <-- 0, v \in V + std::vector< centrality_type > delta(num_vertices(g), 0); + + // S returns vertices in order of non-increasing distance from s + while (!S.empty()) + { + // pop w <-- S + vertex w = S.top(); + S.pop(); + + const Predecessors& w_preds = predecessors[get(index, w)]; + for (typename Predecessors::const_iterator vi = w_preds.begin(); + vi != w_preds.end(); ++vi) + { + vertex v = *vi; + // delta[v] <-- delta[v] + (sigma[v]/sigma[w])*(1 + delta[w]) + delta[get(index, v)] += ((centrality_type)sigma[get(index, v)] + / sigma[get(index, w)]) + * (1 + delta[get(index, w)]); + } + + if (w != s) + { + // C_B[w] <-- C_B[w] + delta[w] + centrality[w] += delta[get(index, w)]; + } } - } } - // delta[v] <-- 0, v \in V - std::vector delta(num_vertices(g), 0); - - // S returns vertices in order of non-increasing distance from s - while (!S.empty()) { - // pop w <-- S - vertex w = S.top(); S.pop(); - - const Predecessors& w_preds = predecessors[get(index, w)]; - for (typename Predecessors::const_iterator vi = w_preds.begin(); - vi != w_preds.end(); ++vi) { - vertex v = *vi; - // delta[v] <-- delta[v] + (sigma[v]/sigma[w])*(1 + delta[w]) - delta[get(index, v)] += - ((centrality_type)sigma[get(index, v)]/sigma[get(index, w)]) - * (1 + delta[get(index, w)]); - } - - if (w != s) { - // C_B[w] <-- C_B[w] + delta[w] - centrality[w] += delta[get(index, w)]; - } - } - } - - typedef typename graph_traits::directed_category directed_category; - const bool is_undirected = - is_same::value; - if (is_undirected) { - vertex_iterator v, v_end; - for(boost::tie(v, v_end) = vertices(g); v != v_end; ++v) { - put(centrality, *v, get(centrality, *v) / centrality_type(2)); + typedef typename graph_traits< Graph >::directed_category directed_category; + const bool is_undirected + = is_same< directed_category, undirected_tag >::value; + if (is_undirected) + { + vertex_iterator v, v_end; + for (boost::tie(v, v_end) = vertices(g); v != v_end; ++v) + { + put(centrality, *v, get(centrality, *v) / centrality_type(2)); + } } - } } -template -void random_unweighted_test(Graph*, int n) +template < typename Graph > void random_unweighted_test(Graph*, int n) { - Graph g(n); - - { - typename graph_traits::vertex_iterator v, v_end; - int index = 0; - for (boost::tie(v, v_end) = boost::vertices(g); v != v_end; ++v, ++index) { - put(vertex_index, g, *v, index); + Graph g(n); + + { + typename graph_traits< Graph >::vertex_iterator v, v_end; + int index = 0; + for (boost::tie(v, v_end) = boost::vertices(g); v != v_end; + ++v, ++index) + { + put(vertex_index, g, *v, index); + } } - } - - randomly_add_edges(g, 0.20); - - std::cout << "Random graph with " << n << " vertices and " - << num_edges(g) << " edges.\n"; - - std::cout << " Direct translation of Brandes' algorithm..."; - std::vector centrality(n); - simple_unweighted_betweenness_centrality(g, get(vertex_index, g), - make_iterator_property_map(centrality.begin(), get(vertex_index, g), - double())); - std::cout << "DONE.\n"; - - std::cout << " Real version, unweighted..."; - std::vector centrality2(n); - brandes_betweenness_centrality(g, - make_iterator_property_map(centrality2.begin(), get(vertex_index, g), - double())); - std::cout << "DONE.\n"; - - if (!std::equal(centrality.begin(), centrality.end(), - centrality2.begin())) { - for (std::size_t v = 0; v < centrality.size(); ++v) { - double relative_error = - centrality[v] == 0.0? centrality2[v] - : (centrality2[v] - centrality[v]) / centrality[v]; - if (relative_error < 0) relative_error = -relative_error; - BOOST_CHECK(relative_error < error_tolerance); + + randomly_add_edges(g, 0.20); + + std::cout << "Random graph with " << n << " vertices and " << num_edges(g) + << " edges.\n"; + + std::cout << " Direct translation of Brandes' algorithm..."; + std::vector< double > centrality(n); + simple_unweighted_betweenness_centrality(g, get(vertex_index, g), + make_iterator_property_map( + centrality.begin(), get(vertex_index, g), double())); + std::cout << "DONE.\n"; + + std::cout << " Real version, unweighted..."; + std::vector< double > centrality2(n); + brandes_betweenness_centrality(g, + make_iterator_property_map( + centrality2.begin(), get(vertex_index, g), double())); + std::cout << "DONE.\n"; + + if (!std::equal(centrality.begin(), centrality.end(), centrality2.begin())) + { + for (std::size_t v = 0; v < centrality.size(); ++v) + { + double relative_error = centrality[v] == 0.0 + ? centrality2[v] + : (centrality2[v] - centrality[v]) / centrality[v]; + if (relative_error < 0) + relative_error = -relative_error; + BOOST_TEST(relative_error < error_tolerance); + } } - } - - std::cout << " Real version, weighted..."; - std::vector centrality3(n); - - for (typename graph_traits::edge_iterator ei = edges(g).first; - ei != edges(g).second; ++ei) - put(edge_weight, g, *ei, 1); - - brandes_betweenness_centrality(g, - weight_map(get(edge_weight, g)) - .centrality_map( - make_iterator_property_map(centrality3.begin(), get(vertex_index, g), - double()))); - std::cout << "DONE.\n"; - - if (!std::equal(centrality.begin(), centrality.end(), - centrality3.begin())) { - for (std::size_t v = 0; v < centrality.size(); ++v) { - double relative_error = - centrality[v] == 0.0? centrality3[v] - : (centrality3[v] - centrality[v]) / centrality[v]; - if (relative_error < 0) relative_error = -relative_error; - BOOST_CHECK(relative_error < error_tolerance); + + std::cout << " Real version, weighted..."; + std::vector< double > centrality3(n); + + for (typename graph_traits< Graph >::edge_iterator ei = edges(g).first; + ei != edges(g).second; ++ei) + put(edge_weight, g, *ei, 1); + + brandes_betweenness_centrality(g, + weight_map(get(edge_weight, g)) + .centrality_map(make_iterator_property_map( + centrality3.begin(), get(vertex_index, g), double()))); + std::cout << "DONE.\n"; + + if (!std::equal(centrality.begin(), centrality.end(), centrality3.begin())) + { + for (std::size_t v = 0; v < centrality.size(); ++v) + { + double relative_error = centrality[v] == 0.0 + ? centrality3[v] + : (centrality3[v] - centrality[v]) / centrality[v]; + if (relative_error < 0) + relative_error = -relative_error; + BOOST_TEST(relative_error < error_tolerance); + } } - } } -int test_main(int argc, char* argv[]) +int main(int argc, char* argv[]) { - int random_test_num_vertices = 300; - if (argc >= 2) random_test_num_vertices = boost::lexical_cast(argv[1]); - typedef adjacency_list, EdgeProperties> - Graph; - typedef adjacency_list, EdgeProperties> - Digraph; - - struct unweighted_edge ud_edge_init1[5] = { - { 0, 1 }, - { 0, 3 }, - { 1, 2 }, - { 3, 2 }, - { 2, 4 } - }; - double ud_centrality1[5] = { 0.5, 1.0, 3.5, 1.0, 0.0 }; - run_unweighted_test((Graph*)0, 5, ud_edge_init1, 5, ud_centrality1); - - // Example borrowed from the JUNG test suite - struct unweighted_edge ud_edge_init2[10] = { - { 0, 1 }, - { 0, 6 }, - { 1, 2 }, - { 1, 3 }, - { 2, 4 }, - { 3, 4 }, - { 4, 5 }, - { 5, 8 }, - { 7, 8 }, - { 6, 7 }, - }; - double ud_centrality2[9] = { - 0.2142 * 28, - 0.2797 * 28, - 0.0892 * 28, - 0.0892 * 28, - 0.2797 * 28, - 0.2142 * 28, - 0.1666 * 28, - 0.1428 * 28, - 0.1666 * 28 - }; - double ud_edge_centrality2[10] = { - 10.66666, - 9.33333, - 6.5, - 6.5, - 6.5, - 6.5, - 10.66666, - 9.33333, - 8.0, - 8.0 - }; - - run_unweighted_test((Graph*)0, 9, ud_edge_init2, 10, ud_centrality2, - ud_edge_centrality2); - - weighted_edge dw_edge_init1[6] = { - { 0, 1, 1.0 }, - { 0, 3, 1.0 }, - { 1, 2, 0.5 }, - { 3, 1, 1.0 }, - { 3, 4, 1.0 }, - { 4, 2, 0.5 } - }; - double dw_centrality1[5] = { 0.0, 1.5, 0.0, 1.0, 0.5 }; - run_weighted_test((Digraph*)0, 5, dw_edge_init1, 6, dw_centrality1); - - run_wheel_test((Graph*)0, 15); - - random_unweighted_test((Graph*)0, random_test_num_vertices); - - return 0; + int random_test_num_vertices = 300; + if (argc >= 2) + random_test_num_vertices = boost::lexical_cast< int >(argv[1]); + typedef adjacency_list< listS, listS, undirectedS, + property< vertex_index_t, int >, EdgeProperties > + Graph; + typedef adjacency_list< listS, listS, directedS, + property< vertex_index_t, int >, EdgeProperties > + Digraph; + + struct unweighted_edge ud_edge_init1[5] + = { { 0, 1 }, { 0, 3 }, { 1, 2 }, { 3, 2 }, { 2, 4 } }; + double ud_centrality1[5] = { 0.5, 1.0, 3.5, 1.0, 0.0 }; + run_unweighted_test((Graph*)0, 5, ud_edge_init1, 5, ud_centrality1); + + // Example borrowed from the JUNG test suite + struct unweighted_edge ud_edge_init2[10] = { + { 0, 1 }, + { 0, 6 }, + { 1, 2 }, + { 1, 3 }, + { 2, 4 }, + { 3, 4 }, + { 4, 5 }, + { 5, 8 }, + { 7, 8 }, + { 6, 7 }, + }; + double ud_centrality2[9] + = { 0.2142 * 28, 0.2797 * 28, 0.0892 * 28, 0.0892 * 28, 0.2797 * 28, + 0.2142 * 28, 0.1666 * 28, 0.1428 * 28, 0.1666 * 28 }; + double ud_edge_centrality2[10] = { 10.66666, 9.33333, 6.5, 6.5, 6.5, 6.5, + 10.66666, 9.33333, 8.0, 8.0 }; + + run_unweighted_test( + (Graph*)0, 9, ud_edge_init2, 10, ud_centrality2, ud_edge_centrality2); + + weighted_edge dw_edge_init1[6] = { { 0, 1, 1.0 }, { 0, 3, 1.0 }, + { 1, 2, 0.5 }, { 3, 1, 1.0 }, { 3, 4, 1.0 }, { 4, 2, 0.5 } }; + double dw_centrality1[5] = { 0.0, 1.5, 0.0, 1.0, 0.5 }; + run_weighted_test((Digraph*)0, 5, dw_edge_init1, 6, dw_centrality1); + + run_wheel_test((Graph*)0, 15); + + random_unweighted_test((Graph*)0, random_test_num_vertices); + + return boost::report_errors(); } - diff --git a/test/bfs.cpp b/test/bfs.cpp index 615999a9f..a3dfad126 100644 --- a/test/bfs.cpp +++ b/test/bfs.cpp @@ -7,7 +7,7 @@ // http://www.boost.org/LICENSE_1_0.txt) //======================================================================= -#include +#include #include #include #include @@ -20,178 +20,196 @@ using namespace boost; #endif -template +template < typename DistanceMap, typename ParentMap, typename Graph, + typename ColorMap > class bfs_testing_visitor { - typedef typename boost::graph_traits::vertex_descriptor Vertex; - typedef typename boost::graph_traits::edge_descriptor Edge; - typedef typename boost::color_traits< - typename boost::property_traits::value_type - > Color; + typedef typename boost::graph_traits< Graph >::vertex_descriptor Vertex; + typedef typename boost::graph_traits< Graph >::edge_descriptor Edge; + typedef typename boost::color_traits< + typename boost::property_traits< ColorMap >::value_type > + Color; + public: + bfs_testing_visitor(Vertex s, DistanceMap d, ParentMap p, ColorMap c) + : current_distance(0), distance(d), parent(p), color(c), src(s) + { + } - bfs_testing_visitor(Vertex s, DistanceMap d, ParentMap p, ColorMap c) - : current_distance(0), distance(d), parent(p), color(c), src(s) { } - - void initialize_vertex(const Vertex& u, const Graph& ) const { - BOOST_CHECK(get(color, u) == Color::white()); - } - void examine_vertex(const Vertex& u, const Graph& ) const { - current_vertex = u; - // Ensure that the distances monotonically increase. - BOOST_CHECK( distance[u] == current_distance - || distance[u] == current_distance + 1 ); - if (distance[u] == current_distance + 1) // new level - ++current_distance; - } - void discover_vertex(const Vertex& u, const Graph& ) const { - BOOST_CHECK( get(color, u) == Color::gray() ); - if (u == src) { - current_vertex = src; - } else { - BOOST_CHECK( parent[u] == current_vertex ); - BOOST_CHECK( distance[u] == current_distance + 1 ); - BOOST_CHECK( distance[u] == distance[parent[u]] + 1 ); + void initialize_vertex(const Vertex& u, const Graph&) const + { + BOOST_TEST(get(color, u) == Color::white()); + } + void examine_vertex(const Vertex& u, const Graph&) const + { + current_vertex = u; + // Ensure that the distances monotonically increase. + BOOST_TEST(distance[u] == current_distance + || distance[u] == current_distance + 1); + if (distance[u] == current_distance + 1) // new level + ++current_distance; + } + void discover_vertex(const Vertex& u, const Graph&) const + { + BOOST_TEST(get(color, u) == Color::gray()); + if (u == src) + { + current_vertex = src; + } + else + { + BOOST_TEST(parent[u] == current_vertex); + BOOST_TEST(distance[u] == current_distance + 1); + BOOST_TEST(distance[u] == distance[parent[u]] + 1); + } + } + void examine_edge(const Edge& e, const Graph& g) const + { + BOOST_TEST(source(e, g) == current_vertex); + } + void tree_edge(const Edge& e, const Graph& g) const + { + BOOST_TEST(get(color, target(e, g)) == Color::white()); + Vertex u = source(e, g), v = target(e, g); + BOOST_TEST(distance[u] == current_distance); + parent[v] = u; + distance[v] = distance[u] + 1; } - } - void examine_edge(const Edge& e, const Graph& g) const { - BOOST_CHECK( source(e, g) == current_vertex ); - } - void tree_edge(const Edge& e, const Graph& g) const { - BOOST_CHECK( get(color, target(e, g)) == Color::white() ); - Vertex u = source(e, g), v = target(e, g); - BOOST_CHECK( distance[u] == current_distance ); - parent[v] = u; - distance[v] = distance[u] + 1; - } - void non_tree_edge(const Edge& e, const Graph& g) const { - BOOST_CHECK( color[target(e, g)] != Color::white() ); - - if (boost::is_directed(g)) - // cross or back edge - BOOST_CHECK(distance[target(e, g)] <= distance[source(e, g)] + 1); - else { - // cross edge (or going backwards on a tree edge) - BOOST_CHECK(distance[target(e, g)] == distance[source(e, g)] - || distance[target(e, g)] == distance[source(e, g)] + 1 - || distance[target(e, g)] == distance[source(e, g)] - 1 - ); + void non_tree_edge(const Edge& e, const Graph& g) const + { + BOOST_TEST(color[target(e, g)] != Color::white()); + + if (boost::is_directed(g)) + // cross or back edge + BOOST_TEST(distance[target(e, g)] <= distance[source(e, g)] + 1); + else + { + // cross edge (or going backwards on a tree edge) + BOOST_TEST(distance[target(e, g)] == distance[source(e, g)] + || distance[target(e, g)] == distance[source(e, g)] + 1 + || distance[target(e, g)] == distance[source(e, g)] - 1); + } } - } - void gray_target(const Edge& e, const Graph& g) const { - BOOST_CHECK( color[target(e, g)] == Color::gray() ); - } + void gray_target(const Edge& e, const Graph& g) const + { + BOOST_TEST(color[target(e, g)] == Color::gray()); + } - void black_target(const Edge& e, const Graph& g) const { - BOOST_CHECK( color[target(e, g)] == Color::black() ); + void black_target(const Edge& e, const Graph& g) const + { + BOOST_TEST(color[target(e, g)] == Color::black()); - // All vertices adjacent to a black vertex must already be discovered - typename boost::graph_traits::adjacency_iterator ai, ai_end; - for (boost::tie(ai, ai_end) = adjacent_vertices(target(e, g), g); - ai != ai_end; ++ai) - BOOST_CHECK( color[*ai] != Color::white() ); - } - void finish_vertex(const Vertex& u, const Graph& ) const { - BOOST_CHECK( color[u] == Color::black() ); + // All vertices adjacent to a black vertex must already be discovered + typename boost::graph_traits< Graph >::adjacency_iterator ai, ai_end; + for (boost::tie(ai, ai_end) = adjacent_vertices(target(e, g), g); + ai != ai_end; ++ai) + BOOST_TEST(color[*ai] != Color::white()); + } + void finish_vertex(const Vertex& u, const Graph&) const + { + BOOST_TEST(color[u] == Color::black()); + } - } private: - mutable Vertex current_vertex; - mutable typename boost::property_traits::value_type - current_distance; - DistanceMap distance; - ParentMap parent; - ColorMap color; - Vertex src; + mutable Vertex current_vertex; + mutable typename boost::property_traits< DistanceMap >::value_type + current_distance; + DistanceMap distance; + ParentMap parent; + ColorMap color; + Vertex src; }; - -template -struct bfs_test +template < class Graph > struct bfs_test { - typedef boost::graph_traits Traits; - typedef typename Traits::vertices_size_type - vertices_size_type; - static void go(vertices_size_type max_V) { - typedef typename Traits::vertex_descriptor vertex_descriptor; - typedef boost::color_traits Color; - - vertices_size_type i; - typename Traits::edges_size_type j; - typename Traits::vertex_iterator ui, ui_end; - - boost::mt19937 gen; - - for (i = 0; i < max_V; ++i) - for (j = 0; j < i*i; ++j) { - Graph g; - boost::generate_random_graph(g, i, j, gen); - - // declare the "start" variable - vertex_descriptor start = boost::random_vertex(g, gen); - - // vertex properties - std::vector distance(i, (std::numeric_limits::max)()); - distance[start] = 0; - std::vector parent(i); - for (boost::tie(ui, ui_end) = vertices(g); ui != ui_end; ++ui) - parent[*ui] = *ui; - std::vector color(i); - - // Get vertex index map - typedef typename boost::property_map::const_type idx_type; - idx_type idx = get(boost::vertex_index, g); - - // Make property maps from vectors - typedef - boost::iterator_property_map::iterator, idx_type> - distance_pm_type; - distance_pm_type distance_pm(distance.begin(), idx); - typedef - boost::iterator_property_map::iterator, idx_type> - parent_pm_type; - parent_pm_type parent_pm(parent.begin(), idx); - typedef - boost::iterator_property_map::iterator, idx_type> - color_pm_type; - color_pm_type color_pm(color.begin(), idx); - - // Create the testing visitor. - bfs_testing_visitor - vis(start, distance_pm, parent_pm, color_pm); - - boost::breadth_first_search(g, start, - visitor(vis). - color_map(color_pm)); - - // All white vertices should be unreachable from the source. - for (boost::tie(ui, ui_end) = vertices(g); ui != ui_end; ++ui) - if (color[*ui] == Color::white()) { - std::vector color2(i, Color::white()); - BOOST_CHECK(!boost::is_reachable(start, *ui, g, color_pm_type(color2.begin(), idx))); - } - - // The shortest path to a child should be one longer than - // shortest path to the parent. - for (boost::tie(ui, ui_end) = vertices(g); ui != ui_end; ++ui) - if (parent[*ui] != *ui) // *ui not the root of the bfs tree - BOOST_CHECK(distance[*ui] == distance[parent[*ui]] + 1); - } - } + typedef boost::graph_traits< Graph > Traits; + typedef typename Traits::vertices_size_type vertices_size_type; + static void go(vertices_size_type max_V) + { + typedef typename Traits::vertex_descriptor vertex_descriptor; + typedef boost::color_traits< boost::default_color_type > Color; + + vertices_size_type i; + typename Traits::edges_size_type j; + typename Traits::vertex_iterator ui, ui_end; + + boost::mt19937 gen; + + for (i = 0; i < max_V; ++i) + for (j = 0; j < i * i; ++j) + { + Graph g; + boost::generate_random_graph(g, i, j, gen); + + // declare the "start" variable + vertex_descriptor start = boost::random_vertex(g, gen); + + // vertex properties + std::vector< int > distance( + i, (std::numeric_limits< int >::max)()); + distance[start] = 0; + std::vector< vertex_descriptor > parent(i); + for (boost::tie(ui, ui_end) = vertices(g); ui != ui_end; ++ui) + parent[*ui] = *ui; + std::vector< boost::default_color_type > color(i); + + // Get vertex index map + typedef typename boost::property_map< Graph, + boost::vertex_index_t >::const_type idx_type; + idx_type idx = get(boost::vertex_index, g); + + // Make property maps from vectors + typedef boost::iterator_property_map< + std::vector< int >::iterator, idx_type > + distance_pm_type; + distance_pm_type distance_pm(distance.begin(), idx); + typedef boost::iterator_property_map< + typename std::vector< vertex_descriptor >::iterator, + idx_type > + parent_pm_type; + parent_pm_type parent_pm(parent.begin(), idx); + typedef boost::iterator_property_map< + std::vector< boost::default_color_type >::iterator, + idx_type > + color_pm_type; + color_pm_type color_pm(color.begin(), idx); + + // Create the testing visitor. + bfs_testing_visitor< distance_pm_type, parent_pm_type, Graph, + color_pm_type > + vis(start, distance_pm, parent_pm, color_pm); + + boost::breadth_first_search( + g, start, visitor(vis).color_map(color_pm)); + + // All white vertices should be unreachable from the source. + for (boost::tie(ui, ui_end) = vertices(g); ui != ui_end; ++ui) + if (color[*ui] == Color::white()) + { + std::vector< boost::default_color_type > color2( + i, Color::white()); + BOOST_TEST(!boost::is_reachable( + start, *ui, g, color_pm_type(color2.begin(), idx))); + } + + // The shortest path to a child should be one longer than + // shortest path to the parent. + for (boost::tie(ui, ui_end) = vertices(g); ui != ui_end; ++ui) + if (parent[*ui] != *ui) // *ui not the root of the bfs tree + BOOST_TEST(distance[*ui] == distance[parent[*ui]] + 1); + } + } }; - -int test_main(int argc, char* argv[]) +int main(int argc, char* argv[]) { - using namespace boost; - int max_V = 7; - if (argc > 1) - max_V = atoi(argv[1]); - - bfs_test< adjacency_list >::go(max_V); - bfs_test< adjacency_list >::go(max_V); - return 0; + using namespace boost; + int max_V = 7; + if (argc > 1) + max_V = atoi(argv[1]); + + bfs_test< adjacency_list< vecS, vecS, directedS > >::go(max_V); + bfs_test< adjacency_list< vecS, vecS, undirectedS > >::go(max_V); + return boost::report_errors(); } diff --git a/test/bfs_cc.cpp b/test/bfs_cc.cpp index 465dec30b..13f20cd46 100644 --- a/test/bfs_cc.cpp +++ b/test/bfs_cc.cpp @@ -13,42 +13,49 @@ int main() { - using namespace boost; - typedef default_constructible_archetype< - sgi_assignable_archetype< - equality_comparable_archetype<> > > vertex_t; - { - typedef incidence_graph_archetype IncidenceGraph; - typedef vertex_list_graph_archetype graph_t; - graph_t& g = static_object::get(); - vertex_t s; - read_write_property_map_archetype color; - breadth_first_search(g, s, color_map(color)); - } - { - typedef incidence_graph_archetype IncidenceGraph; - typedef vertex_list_graph_archetype graph_t; - graph_t& g = static_object::get(); - vertex_t s; - readable_property_map_archetype v_index; - breadth_first_search(g, s, vertex_index_map(v_index)); - } - { - typedef incidence_graph_archetype IncidenceGraph; - typedef vertex_list_graph_archetype Graph; - typedef property_graph_archetype - graph_t; - graph_t& g = static_object::get(); - vertex_t s; - bfs_visitor<> v; - buffer_archetype b; - breadth_first_search(g, s, visitor(v).buffer(b)); - } - return 0; + using namespace boost; + typedef default_constructible_archetype< + sgi_assignable_archetype< equality_comparable_archetype<> > > + vertex_t; + { + typedef incidence_graph_archetype< vertex_t, directed_tag, + allow_parallel_edge_tag > + IncidenceGraph; + typedef vertex_list_graph_archetype< vertex_t, directed_tag, + allow_parallel_edge_tag, IncidenceGraph > + graph_t; + graph_t& g = static_object< graph_t >::get(); + vertex_t s; + read_write_property_map_archetype< vertex_t, color_value_archetype > + color; + breadth_first_search(g, s, color_map(color)); + } + { + typedef incidence_graph_archetype< vertex_t, directed_tag, + allow_parallel_edge_tag > + IncidenceGraph; + typedef vertex_list_graph_archetype< vertex_t, directed_tag, + allow_parallel_edge_tag, IncidenceGraph > + graph_t; + graph_t& g = static_object< graph_t >::get(); + vertex_t s; + readable_property_map_archetype< vertex_t, std::size_t > v_index; + breadth_first_search(g, s, vertex_index_map(v_index)); + } + { + typedef incidence_graph_archetype< vertex_t, undirected_tag, + allow_parallel_edge_tag > + IncidenceGraph; + typedef vertex_list_graph_archetype< vertex_t, undirected_tag, + allow_parallel_edge_tag, IncidenceGraph > + Graph; + typedef property_graph_archetype< Graph, vertex_index_t, std::size_t > + graph_t; + graph_t& g = static_object< graph_t >::get(); + vertex_t s; + bfs_visitor<> v; + buffer_archetype< vertex_t > b; + breadth_first_search(g, s, visitor(v).buffer(b)); + } + return 0; } diff --git a/test/biconnected_components_test.cpp b/test/biconnected_components_test.cpp index 6ec321a9f..0990b4ed6 100644 --- a/test/biconnected_components_test.cpp +++ b/test/biconnected_components_test.cpp @@ -8,7 +8,7 @@ // Andrew Lumsdaine #include #include -#include +#include #include #include #include @@ -23,126 +23,132 @@ using namespace boost; struct EdgeProperty { - std::size_t component; + std::size_t component; }; static bool any_errors = false; -template -void -check_articulation_points(const Graph& g, std::vector art_points) +template < typename Graph, typename Vertex > +void check_articulation_points(const Graph& g, std::vector< Vertex > art_points) { - std::vector components(num_vertices(g)); - int basic_comps = - connected_components(g, - make_iterator_property_map(components.begin(), - get(vertex_index, g), - int())); - - std::vector art_points_check; - - typename graph_traits::vertex_iterator vi, vi_end; - for (boost::tie(vi, vi_end) = vertices(g); vi != vi_end; ++vi) { - Graph g_copy(g); - Vertex victim = vertex(get(vertex_index, g, *vi), g_copy); - clear_vertex(victim, g_copy); - remove_vertex(victim, g_copy); - - int copy_comps = - connected_components - (g_copy, - make_iterator_property_map(components.begin(), - get(vertex_index, g_copy), - int())); - - if (copy_comps > basic_comps) - art_points_check.push_back(*vi); - } - - std::sort(art_points.begin(), art_points.end()); - std::sort(art_points_check.begin(), art_points_check.end()); - - BOOST_CHECK(art_points == art_points_check); - if (art_points != art_points_check) { - std::cerr << "ERROR!" << std::endl; - std::cerr << "\tComputed: "; - std::size_t i; - for (i = 0; i < art_points.size(); ++i) - std::cout << art_points[i] << ' '; - std::cout << std::endl << "\tExpected: "; - for (i = 0; i < art_points_check.size(); ++i) - std::cout << art_points_check[i] << ' '; - std::cout << std::endl; - any_errors = true; - } else std::cout << "OK." << std::endl; + std::vector< int > components(num_vertices(g)); + int basic_comps = connected_components(g, + make_iterator_property_map( + components.begin(), get(vertex_index, g), int())); + + std::vector< Vertex > art_points_check; + + typename graph_traits< Graph >::vertex_iterator vi, vi_end; + for (boost::tie(vi, vi_end) = vertices(g); vi != vi_end; ++vi) + { + Graph g_copy(g); + Vertex victim = vertex(get(vertex_index, g, *vi), g_copy); + clear_vertex(victim, g_copy); + remove_vertex(victim, g_copy); + + int copy_comps = connected_components(g_copy, + make_iterator_property_map( + components.begin(), get(vertex_index, g_copy), int())); + + if (copy_comps > basic_comps) + art_points_check.push_back(*vi); + } + + std::sort(art_points.begin(), art_points.end()); + std::sort(art_points_check.begin(), art_points_check.end()); + + BOOST_TEST(art_points == art_points_check); + if (art_points != art_points_check) + { + std::cerr << "ERROR!" << std::endl; + std::cerr << "\tComputed: "; + std::size_t i; + for (i = 0; i < art_points.size(); ++i) + std::cout << art_points[i] << ' '; + std::cout << std::endl << "\tExpected: "; + for (i = 0; i < art_points_check.size(); ++i) + std::cout << art_points_check[i] << ' '; + std::cout << std::endl; + any_errors = true; + } + else + std::cout << "OK." << std::endl; } -typedef adjacency_list Graph; -typedef graph_traits::vertex_descriptor Vertex; +typedef adjacency_list< listS, vecS, undirectedS, no_property, EdgeProperty > + Graph; +typedef graph_traits< Graph >::vertex_descriptor Vertex; -bool test_graph(Graph& g) { // Returns false on failure - std::vector art_points; +bool test_graph(Graph& g) +{ // Returns false on failure + std::vector< Vertex > art_points; - std::cout << "Computing biconnected components & articulation points... "; - std::cout.flush(); + std::cout << "Computing biconnected components & articulation points... "; + std::cout.flush(); - std::size_t num_comps = - biconnected_components(g, - get(&EdgeProperty::component, g), - std::back_inserter(art_points)).first; - - std::cout << "done.\n\t" << num_comps << " biconnected components.\n" - << "\t" << art_points.size() << " articulation points.\n" - << "\tTesting articulation points..."; - std::cout.flush(); + std::size_t num_comps = biconnected_components( + g, get(&EdgeProperty::component, g), std::back_inserter(art_points)) + .first; - check_articulation_points(g, art_points); + std::cout << "done.\n\t" << num_comps << " biconnected components.\n" + << "\t" << art_points.size() << " articulation points.\n" + << "\tTesting articulation points..."; + std::cout.flush(); - if (any_errors) { - std::ofstream out("biconnected_components_test_failed.dot"); + check_articulation_points(g, art_points); - out << "graph A {\n" << " node[shape=\"circle\"]\n"; + if (any_errors) + { + std::ofstream out("biconnected_components_test_failed.dot"); - for (std::size_t i = 0; i < art_points.size(); ++i) { - out << art_points[i] << " [ style=\"filled\" ];" << std::endl; + out << "graph A {\n" + << " node[shape=\"circle\"]\n"; + + for (std::size_t i = 0; i < art_points.size(); ++i) + { + out << art_points[i] << " [ style=\"filled\" ];" << std::endl; + } + + graph_traits< Graph >::edge_iterator ei, ei_end; + for (boost::tie(ei, ei_end) = edges(g); ei != ei_end; ++ei) + out << source(*ei, g) << " -- " << target(*ei, g) << "[label=\"" + << g[*ei].component << "\"]\n"; + out << "}\n"; } - - graph_traits::edge_iterator ei, ei_end; - for (boost::tie(ei, ei_end) = edges(g); ei != ei_end; ++ei) - out << source(*ei, g) << " -- " << target(*ei, g) - << "[label=\"" << g[*ei].component << "\"]\n"; - out << "}\n"; - } - - return any_errors; + + return any_errors; } - -int test_main(int argc, char* argv[]) + +int main(int argc, char* argv[]) { - std::size_t n = 100; - std::size_t m = 500; - std::size_t seed = 1; - - if (argc > 1) n = lexical_cast(argv[1]); - if (argc > 2) m = lexical_cast(argv[2]); - if (argc > 3) seed = lexical_cast(argv[3]); - - { - Graph g(n); - minstd_rand gen(seed); - generate_random_graph(g, n, m, gen); - if (test_graph(g)) return 1; - } - - { - Graph g(4); - add_edge(2, 3, g); - add_edge(0, 3, g); - add_edge(0, 2, g); - add_edge(1, 0, g); - if (test_graph(g)) return 1; - } - - return 0; + std::size_t n = 100; + std::size_t m = 500; + std::size_t seed = 1; + + if (argc > 1) + n = lexical_cast< std::size_t >(argv[1]); + if (argc > 2) + m = lexical_cast< std::size_t >(argv[2]); + if (argc > 3) + seed = lexical_cast< std::size_t >(argv[3]); + + { + Graph g(n); + minstd_rand gen(seed); + generate_random_graph(g, n, m, gen); + if (test_graph(g)) + return 1; + } + + { + Graph g(4); + add_edge(2, 3, g); + add_edge(0, 3, g); + add_edge(0, 2, g); + add_edge(1, 0, g); + if (test_graph(g)) + return 1; + } + + return boost::report_errors(); } diff --git a/test/bidir_remove_edge.cpp b/test/bidir_remove_edge.cpp index ebd48b752..8fae1702a 100644 --- a/test/bidir_remove_edge.cpp +++ b/test/bidir_remove_edge.cpp @@ -1,4 +1,4 @@ -// (C) Copyright Jeremy Siek 2004 +// (C) Copyright Jeremy Siek 2004 // Distributed under the Boost Software License, Version 1.0. (See // accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) @@ -8,39 +8,44 @@ #include #include -struct edge_prop { - int weight; +struct edge_prop +{ + int weight; }; -int -main(int, char*[]) +int main(int, char*[]) { - { - typedef boost::adjacency_list graph; - typedef boost::graph_traits::edge_descriptor edge; + { + typedef boost::adjacency_list< boost::vecS, boost::vecS, + boost::bidirectionalS, boost::no_property, edge_prop > + graph; + typedef boost::graph_traits< graph >::edge_descriptor edge; - graph g(2); + graph g(2); - edge_prop p = { 42 }; - edge e; bool b; - boost::tie(e, b) = add_edge(0, 1, p, g); - BOOST_TEST( num_edges(g) == 1 ); - BOOST_TEST( g[e].weight == 42 ); - remove_edge(e, g); - BOOST_TEST( num_edges(g) == 0 ); - } - { - typedef boost::adjacency_list graph; - typedef boost::graph_traits::edge_descriptor edge; + edge_prop p = { 42 }; + edge e; + bool b; + boost::tie(e, b) = add_edge(0, 1, p, g); + BOOST_TEST(num_edges(g) == 1); + BOOST_TEST(g[e].weight == 42); + remove_edge(e, g); + BOOST_TEST(num_edges(g) == 0); + } + { + typedef boost::adjacency_list< boost::vecS, boost::vecS, + boost::bidirectionalS > + graph; + typedef boost::graph_traits< graph >::edge_descriptor edge; - graph g(2); + graph g(2); - edge e; bool b; - boost::tie(e, b) = add_edge(0, 1, g); - BOOST_TEST( num_edges(g) == 1 ); - remove_edge(e, g); - BOOST_TEST( num_edges(g) == 0 ); - } - return boost::report_errors(); + edge e; + bool b; + boost::tie(e, b) = add_edge(0, 1, g); + BOOST_TEST(num_edges(g) == 1); + remove_edge(e, g); + BOOST_TEST(num_edges(g) == 0); + } + return boost::report_errors(); } diff --git a/test/bidir_vec_remove_edge.cpp b/test/bidir_vec_remove_edge.cpp index 732eae708..ae662b124 100644 --- a/test/bidir_vec_remove_edge.cpp +++ b/test/bidir_vec_remove_edge.cpp @@ -1,4 +1,4 @@ -// (C) Copyright 2004 Douglas Gregor and Jeremy Siek +// (C) Copyright 2004 Douglas Gregor and Jeremy Siek // Distributed under the Boost Software License, Version 1.0. (See // accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) @@ -9,49 +9,50 @@ #include #include -#include +#include -struct edge_prop { - int weight; +struct edge_prop +{ + int weight; }; -int -test_main(int, char*[]) +int main(int, char*[]) { - { - typedef boost::adjacency_list graph; - typedef boost::graph_traits::edge_descriptor edge; - - graph g(2); - - edge_prop p1 = { 42 }; - edge_prop p2 = { 17 }; - add_edge(0, 1, p1, g); - add_edge(1, 0, p2, g); - - edge e1 = boost::edge(0, 1, g).first; - edge e2 = boost::edge(1, 0, g).first; - BOOST_CHECK( num_edges(g) == 2 ); - BOOST_CHECK( g[e1].weight == 42 ); - BOOST_CHECK( g[e2].weight == 17 ); - remove_edge(e1, g); - BOOST_CHECK( num_edges(g) == 1 ); - - // e2 has been invalidated, so grab it again - bool b2; - boost::tie(e2, b2) = boost::edge(1, 0, g); - BOOST_CHECK( b2 ); - BOOST_CHECK( g[e2].weight == 17 ); - - /* Now remove the other edge. Here, the fact that - * stored_ra_edge_iterator keeps an index but does not update it - * when edges are removed. So, this will be incorrect but the - * error may not always show up (use an STL debug mode to see the - * error for sure.) - */ - remove_edge(e2, g); - - } - return boost::exit_success; + { + typedef boost::adjacency_list< boost::vecS, boost::vecS, + boost::bidirectionalS, boost::no_property, edge_prop, + boost::no_property, boost::vecS > + graph; + typedef boost::graph_traits< graph >::edge_descriptor edge; + + graph g(2); + + edge_prop p1 = { 42 }; + edge_prop p2 = { 17 }; + add_edge(0, 1, p1, g); + add_edge(1, 0, p2, g); + + edge e1 = boost::edge(0, 1, g).first; + edge e2 = boost::edge(1, 0, g).first; + BOOST_TEST(num_edges(g) == 2); + BOOST_TEST(g[e1].weight == 42); + BOOST_TEST(g[e2].weight == 17); + remove_edge(e1, g); + BOOST_TEST(num_edges(g) == 1); + + // e2 has been invalidated, so grab it again + bool b2; + boost::tie(e2, b2) = boost::edge(1, 0, g); + BOOST_TEST(b2); + BOOST_TEST(g[e2].weight == 17); + + /* Now remove the other edge. Here, the fact that + * stored_ra_edge_iterator keeps an index but does not update it + * when edges are removed. So, this will be incorrect but the + * error may not always show up (use an STL debug mode to see the + * error for sure.) + */ + remove_edge(e2, g); + } + return boost::report_errors(); } diff --git a/test/bipartite_test.cpp b/test/bipartite_test.cpp index 30ab5c72d..7260c925e 100644 --- a/test/bipartite_test.cpp +++ b/test/bipartite_test.cpp @@ -12,178 +12,201 @@ #include #include -#include +#include #include /// Verifies a 2-coloring -template -void check_two_coloring (const Graph& g, const ColorMap color_map) +template < typename Graph, typename ColorMap > +void check_two_coloring(const Graph& g, const ColorMap color_map) { - typedef boost::graph_traits traits; - typename traits::edge_iterator edge_iter, edge_end; - - for (boost::tie (edge_iter, edge_end) = boost::edges (g); edge_iter != edge_end; ++edge_iter) - { - typename traits::vertex_descriptor source, target; - source = boost::source (*edge_iter, g); - target = boost::target (*edge_iter, g); - BOOST_REQUIRE (boost::get(color_map, source) != boost::get(color_map, target)); - } + typedef boost::graph_traits< Graph > traits; + typename traits::edge_iterator edge_iter, edge_end; + + for (boost::tie(edge_iter, edge_end) = boost::edges(g); + edge_iter != edge_end; ++edge_iter) + { + typename traits::vertex_descriptor source, target; + source = boost::source(*edge_iter, g); + target = boost::target(*edge_iter, g); + BOOST_TEST( + boost::get(color_map, source) != boost::get(color_map, target)); + } } /// Tests for a vertex sequence to define an odd cycle -template -void check_odd_cycle (const Graph& g, RandomAccessIterator first, RandomAccessIterator beyond) +template < typename Graph, typename RandomAccessIterator > +void check_odd_cycle( + const Graph& g, RandomAccessIterator first, RandomAccessIterator beyond) { - typedef boost::graph_traits traits; + typedef boost::graph_traits< Graph > traits; - typename traits::vertex_descriptor first_vertex, current_vertex, last_vertex; + typename traits::vertex_descriptor first_vertex, current_vertex, + last_vertex; - BOOST_CHECK ((beyond - first) % 2 == 1); + BOOST_TEST((beyond - first) % 2 == 1); - // std::cout << "odd_cycle: " << int(*first) << std::endl; + // std::cout << "odd_cycle: " << int(*first) << std::endl; - for (first_vertex = current_vertex = *first++; first != beyond; ++first) - { - // std::cout << "odd_cycle: " << int(*first) << std::endl; + for (first_vertex = current_vertex = *first++; first != beyond; ++first) + { + // std::cout << "odd_cycle: " << int(*first) << std::endl; - last_vertex = current_vertex; - current_vertex = *first; + last_vertex = current_vertex; + current_vertex = *first; - BOOST_REQUIRE (boost::lookup_edge (current_vertex, last_vertex, g).second); - } + BOOST_TEST(boost::lookup_edge(current_vertex, last_vertex, g).second); + } - BOOST_REQUIRE (boost::lookup_edge (first_vertex, current_vertex, g).second); + BOOST_TEST(boost::lookup_edge(first_vertex, current_vertex, g).second); } /// Call the is_bipartite and find_odd_cycle functions and verify their results. -template -void check_bipartite (const Graph& g, IndexMap index_map, bool is_bipartite) +template < typename Graph, typename IndexMap > +void check_bipartite(const Graph& g, IndexMap index_map, bool is_bipartite) { - typedef boost::graph_traits traits; - typedef std::vector partition_t; - typedef std::vector vertex_vector_t; - typedef boost::iterator_property_map partition_map_t; - - partition_t partition (boost::num_vertices (g)); - partition_map_t partition_map (partition.begin (), index_map); - - vertex_vector_t odd_cycle (boost::num_vertices (g)); - - bool first_result = boost::is_bipartite (g, index_map, partition_map); - - BOOST_REQUIRE (first_result == boost::is_bipartite(g, index_map)); - - if (first_result) - check_two_coloring (g, partition_map); - - BOOST_CHECK (first_result == is_bipartite); - - typename vertex_vector_t::iterator second_first = odd_cycle.begin (); - typename vertex_vector_t::iterator second_beyond = boost::find_odd_cycle (g, index_map, partition_map, second_first); - - if (is_bipartite) - { - BOOST_CHECK (second_beyond == second_first); - check_two_coloring (g, partition_map); - } - else - { - check_odd_cycle (g, second_first, second_beyond); - } - - second_beyond = boost::find_odd_cycle (g, index_map, second_first); - if (is_bipartite) - { - BOOST_CHECK (second_beyond == second_first); - } - else - { - check_odd_cycle (g, second_first, second_beyond); - } + typedef boost::graph_traits< Graph > traits; + typedef std::vector< boost::default_color_type > partition_t; + typedef std::vector< typename traits::vertex_descriptor > vertex_vector_t; + typedef boost::iterator_property_map< partition_t::iterator, IndexMap > + partition_map_t; + + partition_t partition(boost::num_vertices(g)); + partition_map_t partition_map(partition.begin(), index_map); + + vertex_vector_t odd_cycle(boost::num_vertices(g)); + + bool first_result = boost::is_bipartite(g, index_map, partition_map); + + BOOST_TEST(first_result == boost::is_bipartite(g, index_map)); + + if (first_result) + check_two_coloring(g, partition_map); + + BOOST_TEST(first_result == is_bipartite); + + typename vertex_vector_t::iterator second_first = odd_cycle.begin(); + typename vertex_vector_t::iterator second_beyond + = boost::find_odd_cycle(g, index_map, partition_map, second_first); + + if (is_bipartite) + { + BOOST_TEST(second_beyond == second_first); + check_two_coloring(g, partition_map); + } + else + { + check_odd_cycle(g, second_first, second_beyond); + } + + second_beyond = boost::find_odd_cycle(g, index_map, second_first); + if (is_bipartite) + { + BOOST_TEST(second_beyond == second_first); + } + else + { + check_odd_cycle(g, second_first, second_beyond); + } } -int test_main (int argc, char **argv) +int main(int argc, char** argv) { - typedef boost::adjacency_list vector_graph_t; - typedef boost::adjacency_list list_graph_t; - typedef std::pair E; - - typedef std::map ::vertex_descriptor, size_t> index_map_t; - typedef boost::associative_property_map index_property_map_t; - - /** - * Create the graph drawn below. - * - * 0 - 1 - 2 - * | | - * 3 - 4 - 5 - 6 - * / \ / - * | 7 - * | | - * 8 - 9 - 10 - **/ - - E bipartite_edges[] = { E (0, 1), E (0, 4), E (1, 2), E (2, 6), E (3, 4), E (3, 8), E (4, 5), E (4, 7), E (5, 6), E ( - 6, 7), E (7, 10), E (8, 9), E (9, 10) }; - vector_graph_t bipartite_vector_graph (&bipartite_edges[0], - &bipartite_edges[0] + sizeof(bipartite_edges) / sizeof(E), 11); - list_graph_t - bipartite_list_graph (&bipartite_edges[0], &bipartite_edges[0] + sizeof(bipartite_edges) / sizeof(E), 11); - - /** - * Create the graph drawn below. - * - * 2 - 1 - 0 - * | | - * 3 - 6 - 5 - 4 - * / \ / - * | 7 - * | / - * 8 ---- 9 - * - **/ - - E non_bipartite_edges[] = { E (0, 1), E (0, 4), E (1, 2), E (2, 6), E (3, 4), E (3, 8), E (4, 5), E (4, 7), E (5, 6), - E (6, 7), E (7, 9), E (8, 9) }; - vector_graph_t non_bipartite_vector_graph (&non_bipartite_edges[0], &non_bipartite_edges[0] - + sizeof(non_bipartite_edges) / sizeof(E), 10); - list_graph_t non_bipartite_list_graph (&non_bipartite_edges[0], &non_bipartite_edges[0] + sizeof(non_bipartite_edges) - / sizeof(E), 10); - - /// Create index maps - - index_map_t bipartite_index_map, non_bipartite_index_map; - boost::graph_traits ::vertex_iterator vertex_iter, vertex_end; - size_t i = 0; - for (boost::tie (vertex_iter, vertex_end) = boost::vertices (bipartite_list_graph); vertex_iter != vertex_end; ++vertex_iter) - { - bipartite_index_map[*vertex_iter] = i++; - } - index_property_map_t bipartite_index_property_map = index_property_map_t (bipartite_index_map); - - i = 0; - for (boost::tie (vertex_iter, vertex_end) = boost::vertices (non_bipartite_list_graph); vertex_iter != vertex_end; ++vertex_iter) - { - non_bipartite_index_map[*vertex_iter] = i++; - } - index_property_map_t non_bipartite_index_property_map = index_property_map_t (non_bipartite_index_map); - - /// Call real checks - - check_bipartite (bipartite_vector_graph, boost::get (boost::vertex_index, bipartite_vector_graph), true); - check_bipartite (bipartite_list_graph, bipartite_index_property_map, true); - - check_bipartite (non_bipartite_vector_graph, boost::get (boost::vertex_index, non_bipartite_vector_graph), false); - check_bipartite (non_bipartite_list_graph, non_bipartite_index_property_map, false); - - /// Test some more interfaces - - BOOST_REQUIRE (is_bipartite (bipartite_vector_graph)); - BOOST_REQUIRE (!is_bipartite (non_bipartite_vector_graph)); - - return 0; + typedef boost::adjacency_list< boost::vecS, boost::vecS, + boost::undirectedS > + vector_graph_t; + typedef boost::adjacency_list< boost::listS, boost::listS, + boost::undirectedS > + list_graph_t; + typedef std::pair< int, int > E; + + typedef std::map< boost::graph_traits< list_graph_t >::vertex_descriptor, + size_t > + index_map_t; + typedef boost::associative_property_map< index_map_t > index_property_map_t; + + /** + * Create the graph drawn below. + * + * 0 - 1 - 2 + * | | + * 3 - 4 - 5 - 6 + * / \ / + * | 7 + * | | + * 8 - 9 - 10 + **/ + + E bipartite_edges[] + = { E(0, 1), E(0, 4), E(1, 2), E(2, 6), E(3, 4), E(3, 8), E(4, 5), + E(4, 7), E(5, 6), E(6, 7), E(7, 10), E(8, 9), E(9, 10) }; + vector_graph_t bipartite_vector_graph(&bipartite_edges[0], + &bipartite_edges[0] + sizeof(bipartite_edges) / sizeof(E), 11); + list_graph_t bipartite_list_graph(&bipartite_edges[0], + &bipartite_edges[0] + sizeof(bipartite_edges) / sizeof(E), 11); + + /** + * Create the graph drawn below. + * + * 2 - 1 - 0 + * | | + * 3 - 6 - 5 - 4 + * / \ / + * | 7 + * | / + * 8 ---- 9 + * + **/ + + E non_bipartite_edges[] = { E(0, 1), E(0, 4), E(1, 2), E(2, 6), E(3, 4), + E(3, 8), E(4, 5), E(4, 7), E(5, 6), E(6, 7), E(7, 9), E(8, 9) }; + vector_graph_t non_bipartite_vector_graph(&non_bipartite_edges[0], + &non_bipartite_edges[0] + sizeof(non_bipartite_edges) / sizeof(E), 10); + list_graph_t non_bipartite_list_graph(&non_bipartite_edges[0], + &non_bipartite_edges[0] + sizeof(non_bipartite_edges) / sizeof(E), 10); + + /// Create index maps + + index_map_t bipartite_index_map, non_bipartite_index_map; + boost::graph_traits< list_graph_t >::vertex_iterator vertex_iter, + vertex_end; + size_t i = 0; + for (boost::tie(vertex_iter, vertex_end) + = boost::vertices(bipartite_list_graph); + vertex_iter != vertex_end; ++vertex_iter) + { + bipartite_index_map[*vertex_iter] = i++; + } + index_property_map_t bipartite_index_property_map + = index_property_map_t(bipartite_index_map); + + i = 0; + for (boost::tie(vertex_iter, vertex_end) + = boost::vertices(non_bipartite_list_graph); + vertex_iter != vertex_end; ++vertex_iter) + { + non_bipartite_index_map[*vertex_iter] = i++; + } + index_property_map_t non_bipartite_index_property_map + = index_property_map_t(non_bipartite_index_map); + + /// Call real checks + + check_bipartite(bipartite_vector_graph, + boost::get(boost::vertex_index, bipartite_vector_graph), true); + check_bipartite(bipartite_list_graph, bipartite_index_property_map, true); + + check_bipartite(non_bipartite_vector_graph, + boost::get(boost::vertex_index, non_bipartite_vector_graph), false); + check_bipartite( + non_bipartite_list_graph, non_bipartite_index_property_map, false); + + /// Test some more interfaces + + BOOST_TEST(is_bipartite(bipartite_vector_graph)); + BOOST_TEST(!is_bipartite(non_bipartite_vector_graph)); + + return boost::report_errors(); } diff --git a/test/boykov_kolmogorov_max_flow_test.cpp b/test/boykov_kolmogorov_max_flow_test.cpp index 1f0ce5892..44ce8f86f 100644 --- a/test/boykov_kolmogorov_max_flow_test.cpp +++ b/test/boykov_kolmogorov_max_flow_test.cpp @@ -35,7 +35,7 @@ #include #include -#include +#include #include #include @@ -47,419 +47,464 @@ using namespace boost; -template -std::pair< typename graph_traits::vertex_descriptor,typename graph_traits::vertex_descriptor> -fill_random_max_flow_graph(Graph& g, CapacityMap cap, ReverseEdgeMap rev, typename graph_traits::vertices_size_type n_verts, - typename graph_traits::edges_size_type n_edges, std::size_t seed) +template < typename Graph, typename CapacityMap, typename ReverseEdgeMap > +std::pair< typename graph_traits< Graph >::vertex_descriptor, + typename graph_traits< Graph >::vertex_descriptor > +fill_random_max_flow_graph(Graph& g, CapacityMap cap, ReverseEdgeMap rev, + typename graph_traits< Graph >::vertices_size_type n_verts, + typename graph_traits< Graph >::edges_size_type n_edges, std::size_t seed) { - typedef typename graph_traits::edge_descriptor edge_descriptor; - typedef typename graph_traits::vertex_descriptor vertex_descriptor; - const int cap_low = 1; - const int cap_high = 1000; - - //init random numer generator - minstd_rand gen(seed); - //generate graph - generate_random_graph(g, n_verts, n_edges, gen); - - //init an uniform distribution int generator - typedef variate_generator > tIntGen; - tIntGen int_gen(gen, uniform_int(cap_low, cap_high)); - //randomize edge-capacities - //randomize_property (g,int_gen); //we cannot use this, as we have no idea how properties are stored, right? - typename graph_traits::edge_iterator ei, e_end; - for(boost::tie(ei,e_end) = edges(g); ei != e_end; ++ei) - cap[*ei] = int_gen(); - - //get source and sink node - vertex_descriptor s = random_vertex(g, gen); - vertex_descriptor t = graph_traits::null_vertex(); - while(t == graph_traits::null_vertex() || t == s) - t = random_vertex(g, gen); - - //add reverse edges (ugly... how to do better?!) - std::list edges_copy; - boost::tie(ei, e_end) = edges(g); - std::copy(ei, e_end, std::back_insert_iterator< std::list >(edges_copy)); - while(!edges_copy.empty()){ - edge_descriptor old_edge = edges_copy.front(); - edges_copy.pop_front(); - vertex_descriptor source_vertex = target(old_edge, g); - vertex_descriptor target_vertex = source(old_edge, g); - bool inserted; - edge_descriptor new_edge; - boost::tie(new_edge,inserted) = add_edge(source_vertex, target_vertex, g); - assert(inserted); - rev[old_edge] = new_edge; - rev[new_edge] = old_edge ; - cap[new_edge] = 0; - } - return std::make_pair(s,t); + typedef typename graph_traits< Graph >::edge_descriptor edge_descriptor; + typedef typename graph_traits< Graph >::vertex_descriptor vertex_descriptor; + const int cap_low = 1; + const int cap_high = 1000; + + // init random numer generator + minstd_rand gen(seed); + // generate graph + generate_random_graph(g, n_verts, n_edges, gen); + + // init an uniform distribution int generator + typedef variate_generator< minstd_rand, uniform_int< int > > tIntGen; + tIntGen int_gen(gen, uniform_int< int >(cap_low, cap_high)); + // randomize edge-capacities + // randomize_property (g,int_gen); //we + // cannot use this, as we have no idea how properties are stored, right? + typename graph_traits< Graph >::edge_iterator ei, e_end; + for (boost::tie(ei, e_end) = edges(g); ei != e_end; ++ei) + cap[*ei] = int_gen(); + + // get source and sink node + vertex_descriptor s = random_vertex(g, gen); + vertex_descriptor t = graph_traits< Graph >::null_vertex(); + while (t == graph_traits< Graph >::null_vertex() || t == s) + t = random_vertex(g, gen); + + // add reverse edges (ugly... how to do better?!) + std::list< edge_descriptor > edges_copy; + boost::tie(ei, e_end) = edges(g); + std::copy(ei, e_end, + std::back_insert_iterator< std::list< edge_descriptor > >(edges_copy)); + while (!edges_copy.empty()) + { + edge_descriptor old_edge = edges_copy.front(); + edges_copy.pop_front(); + vertex_descriptor source_vertex = target(old_edge, g); + vertex_descriptor target_vertex = source(old_edge, g); + bool inserted; + edge_descriptor new_edge; + boost::tie(new_edge, inserted) + = add_edge(source_vertex, target_vertex, g); + assert(inserted); + rev[old_edge] = new_edge; + rev[new_edge] = old_edge; + cap[new_edge] = 0; + } + return std::make_pair(s, t); } -long test_adjacency_list_vecS(int n_verts, int n_edges, std::size_t seed){ - typedef adjacency_list_traits tVectorTraits; - typedef adjacency_list > > >, - property > > > tVectorGraph; - - tVectorGraph g; - - graph_traits::vertex_descriptor src,sink; - boost::tie(src,sink) = fill_random_max_flow_graph(g, get(edge_capacity,g), get(edge_reverse, g), n_verts, n_edges, seed); - - return boykov_kolmogorov_max_flow(g, get(edge_capacity, g), - get(edge_residual_capacity, g), - get(edge_reverse, g), - get(vertex_predecessor, g), - get(vertex_color, g), - get(vertex_distance, g), - get(vertex_index, g), - src, sink); +long test_adjacency_list_vecS(int n_verts, int n_edges, std::size_t seed) +{ + typedef adjacency_list_traits< vecS, vecS, directedS > tVectorTraits; + typedef adjacency_list< vecS, vecS, directedS, + property< vertex_index_t, long, + property< vertex_predecessor_t, tVectorTraits::edge_descriptor, + property< vertex_color_t, boost::default_color_type, + property< vertex_distance_t, long > > > >, + property< edge_capacity_t, long, + property< edge_residual_capacity_t, long, + property< edge_reverse_t, tVectorTraits::edge_descriptor > > > > + tVectorGraph; + + tVectorGraph g; + + graph_traits< tVectorGraph >::vertex_descriptor src, sink; + boost::tie(src, sink) = fill_random_max_flow_graph( + g, get(edge_capacity, g), get(edge_reverse, g), n_verts, n_edges, seed); + + return boykov_kolmogorov_max_flow(g, get(edge_capacity, g), + get(edge_residual_capacity, g), get(edge_reverse, g), + get(vertex_predecessor, g), get(vertex_color, g), + get(vertex_distance, g), get(vertex_index, g), src, sink); } -long test_adjacency_list_listS(int n_verts, int n_edges, std::size_t seed){ - typedef adjacency_list_traits tListTraits; - typedef adjacency_list > > >, - property > > > tListGraph; - - tListGraph g; - - graph_traits::vertex_descriptor src,sink; - boost::tie(src,sink) = fill_random_max_flow_graph(g, get(edge_capacity,g), get(edge_reverse, g), n_verts, n_edges, seed); - - //initialize vertex indices - graph_traits::vertex_iterator vi,v_end; - graph_traits::vertices_size_type index = 0; - for(boost::tie(vi, v_end) = vertices(g); vi != v_end; ++vi){ - put(vertex_index, g, *vi, index++); - } - return boykov_kolmogorov_max_flow(g, get(edge_capacity, g), - get(edge_residual_capacity, g), - get(edge_reverse, g), - get(vertex_predecessor, g), - get(vertex_color, g), - get(vertex_distance, g), - get(vertex_index, g), - src, sink); +long test_adjacency_list_listS(int n_verts, int n_edges, std::size_t seed) +{ + typedef adjacency_list_traits< listS, listS, directedS > tListTraits; + typedef adjacency_list< listS, listS, directedS, + property< vertex_index_t, long, + property< vertex_predecessor_t, tListTraits::edge_descriptor, + property< vertex_color_t, boost::default_color_type, + property< vertex_distance_t, long > > > >, + property< edge_capacity_t, long, + property< edge_residual_capacity_t, long, + property< edge_reverse_t, tListTraits::edge_descriptor > > > > + tListGraph; + + tListGraph g; + + graph_traits< tListGraph >::vertex_descriptor src, sink; + boost::tie(src, sink) = fill_random_max_flow_graph( + g, get(edge_capacity, g), get(edge_reverse, g), n_verts, n_edges, seed); + + // initialize vertex indices + graph_traits< tListGraph >::vertex_iterator vi, v_end; + graph_traits< tListGraph >::vertices_size_type index = 0; + for (boost::tie(vi, v_end) = vertices(g); vi != v_end; ++vi) + { + put(vertex_index, g, *vi, index++); + } + return boykov_kolmogorov_max_flow(g, get(edge_capacity, g), + get(edge_residual_capacity, g), get(edge_reverse, g), + get(vertex_predecessor, g), get(vertex_color, g), + get(vertex_distance, g), get(vertex_index, g), src, sink); } -template - struct Node{ - boost::default_color_type vertex_color; - long vertex_distance; - EdgeDescriptor vertex_predecessor; +template < typename EdgeDescriptor > struct Node +{ + boost::default_color_type vertex_color; + long vertex_distance; + EdgeDescriptor vertex_predecessor; }; -template - struct Link{ - long edge_capacity; - long edge_residual_capacity; - EdgeDescriptor edge_reverse; +template < typename EdgeDescriptor > struct Link +{ + long edge_capacity; + long edge_residual_capacity; + EdgeDescriptor edge_reverse; }; -long test_bundled_properties(int n_verts, int n_edges, std::size_t seed){ - typedef adjacency_list_traits tTraits; - typedef Node tVertex; - typedef Link tEdge; - typedef adjacency_list tBundleGraph; - - tBundleGraph g; - - graph_traits::vertex_descriptor src,sink; - boost::tie(src,sink) = fill_random_max_flow_graph(g, get(&tEdge::edge_capacity,g), get(&tEdge::edge_reverse, g), n_verts, n_edges, seed); - return boykov_kolmogorov_max_flow(g, get(&tEdge::edge_capacity, g), - get(&tEdge::edge_residual_capacity, g), - get(&tEdge::edge_reverse, g), - get(&tVertex::vertex_predecessor, g), - get(&tVertex::vertex_color, g), - get(&tVertex::vertex_distance, g), - get(vertex_index, g), - src, sink); +long test_bundled_properties(int n_verts, int n_edges, std::size_t seed) +{ + typedef adjacency_list_traits< vecS, vecS, directedS > tTraits; + typedef Node< tTraits::edge_descriptor > tVertex; + typedef Link< tTraits::edge_descriptor > tEdge; + typedef adjacency_list< vecS, vecS, directedS, tVertex, tEdge > + tBundleGraph; + + tBundleGraph g; + + graph_traits< tBundleGraph >::vertex_descriptor src, sink; + boost::tie(src, sink) + = fill_random_max_flow_graph(g, get(&tEdge::edge_capacity, g), + get(&tEdge::edge_reverse, g), n_verts, n_edges, seed); + return boykov_kolmogorov_max_flow(g, get(&tEdge::edge_capacity, g), + get(&tEdge::edge_residual_capacity, g), get(&tEdge::edge_reverse, g), + get(&tVertex::vertex_predecessor, g), get(&tVertex::vertex_color, g), + get(&tVertex::vertex_distance, g), get(vertex_index, g), src, sink); } -long test_overloads(int n_verts, int n_edges, std::size_t seed){ - typedef adjacency_list_traits tTraits; - typedef property > >tEdgeProperty; - typedef adjacency_list tGraph; - - tGraph g; - - graph_traits::vertex_descriptor src,sink; - boost::tie(src,sink) = fill_random_max_flow_graph(g, get(edge_capacity,g), get(edge_reverse, g), n_verts, n_edges, seed); - - std::vector::edge_descriptor> predecessor_vec(n_verts); - std::vector color_vec(n_verts); - std::vector::vertices_size_type> distance_vec(n_verts); - - long flow_overload_1 = - boykov_kolmogorov_max_flow(g, - get(edge_capacity,g), - get(edge_residual_capacity,g), - get(edge_reverse,g), - get(vertex_index,g), - src, sink); - - long flow_overload_2 = - boykov_kolmogorov_max_flow(g, - get(edge_capacity,g), - get(edge_residual_capacity,g), - get(edge_reverse,g), - boost::make_iterator_property_map( - color_vec.begin(), get(vertex_index, g)), - get(vertex_index,g), - src, sink); - - BOOST_CHECK(flow_overload_1 == flow_overload_2); - return flow_overload_1; +long test_overloads(int n_verts, int n_edges, std::size_t seed) +{ + typedef adjacency_list_traits< vecS, vecS, directedS > tTraits; + typedef property< edge_capacity_t, long, + property< edge_residual_capacity_t, long, + property< edge_reverse_t, tTraits::edge_descriptor > > > + tEdgeProperty; + typedef adjacency_list< vecS, vecS, directedS, no_property, tEdgeProperty > + tGraph; + + tGraph g; + + graph_traits< tGraph >::vertex_descriptor src, sink; + boost::tie(src, sink) = fill_random_max_flow_graph( + g, get(edge_capacity, g), get(edge_reverse, g), n_verts, n_edges, seed); + + std::vector< graph_traits< tGraph >::edge_descriptor > predecessor_vec( + n_verts); + std::vector< default_color_type > color_vec(n_verts); + std::vector< graph_traits< tGraph >::vertices_size_type > distance_vec( + n_verts); + + long flow_overload_1 = boykov_kolmogorov_max_flow(g, get(edge_capacity, g), + get(edge_residual_capacity, g), get(edge_reverse, g), + get(vertex_index, g), src, sink); + + long flow_overload_2 = boykov_kolmogorov_max_flow(g, get(edge_capacity, g), + get(edge_residual_capacity, g), get(edge_reverse, g), + boost::make_iterator_property_map( + color_vec.begin(), get(vertex_index, g)), + get(vertex_index, g), src, sink); + + BOOST_TEST(flow_overload_1 == flow_overload_2); + return flow_overload_1; } -template +template < class Graph, class EdgeCapacityMap, class ResidualCapacityEdgeMap, + class ReverseEdgeMap, class PredecessorMap, class ColorMap, + class DistanceMap, class IndexMap > class boykov_kolmogorov_test - : public detail::bk_max_flow< - Graph, EdgeCapacityMap, ResidualCapacityEdgeMap, ReverseEdgeMap, - PredecessorMap, ColorMap, DistanceMap, IndexMap - > +: public detail::bk_max_flow< Graph, EdgeCapacityMap, ResidualCapacityEdgeMap, + ReverseEdgeMap, PredecessorMap, ColorMap, DistanceMap, IndexMap > { - typedef typename graph_traits::edge_descriptor tEdge; - typedef typename graph_traits::vertex_descriptor tVertex; - typedef typename property_traits< typename property_map::const_type>::value_type tEdgeVal; - typedef typename graph_traits::vertex_iterator tVertexIterator; - typedef typename graph_traits::out_edge_iterator tOutEdgeIterator; - typedef typename property_traits::value_type tColorValue; - typedef color_traits tColorTraits; - typedef typename property_traits::value_type tDistanceVal; - typedef typename detail::bk_max_flow< - Graph, EdgeCapacityMap, ResidualCapacityEdgeMap, ReverseEdgeMap, - PredecessorMap, ColorMap, DistanceMap, IndexMap - > tSuper; - public: - boykov_kolmogorov_test(Graph& g, - typename graph_traits::vertex_descriptor src, - typename graph_traits::vertex_descriptor sink) - : tSuper(g, get(edge_capacity,g), get(edge_residual_capacity,g), - get(edge_reverse, g), get(vertex_predecessor, g), - get(vertex_color, g), get(vertex_distance, g), - get(vertex_index, g), src, sink) - { } - - void invariant_four(tVertex v) const{ - //passive nodes in S or T - if(v == tSuper::m_source || v == tSuper::m_sink) + typedef typename graph_traits< Graph >::edge_descriptor tEdge; + typedef typename graph_traits< Graph >::vertex_descriptor tVertex; + typedef typename property_traits< typename property_map< Graph, + edge_capacity_t >::const_type >::value_type tEdgeVal; + typedef typename graph_traits< Graph >::vertex_iterator tVertexIterator; + typedef typename graph_traits< Graph >::out_edge_iterator tOutEdgeIterator; + typedef typename property_traits< ColorMap >::value_type tColorValue; + typedef color_traits< tColorValue > tColorTraits; + typedef typename property_traits< DistanceMap >::value_type tDistanceVal; + typedef typename detail::bk_max_flow< Graph, EdgeCapacityMap, + ResidualCapacityEdgeMap, ReverseEdgeMap, PredecessorMap, ColorMap, + DistanceMap, IndexMap > + tSuper; + +public: + boykov_kolmogorov_test(Graph& g, + typename graph_traits< Graph >::vertex_descriptor src, + typename graph_traits< Graph >::vertex_descriptor sink) + : tSuper(g, get(edge_capacity, g), get(edge_residual_capacity, g), + get(edge_reverse, g), get(vertex_predecessor, g), get(vertex_color, g), + get(vertex_distance, g), get(vertex_index, g), src, sink) + { + } + + void invariant_four(tVertex v) const + { + // passive nodes in S or T + if (v == tSuper::m_source || v == tSuper::m_sink) return; - typename std::list::const_iterator it = find(tSuper::m_orphans.begin(), tSuper::m_orphans.end(), v); - // a node is active, if its in the active_list AND (is has_a_parent, or its already in the orphans_list or its the sink, or its the source) - bool is_active = (tSuper::m_in_active_list_map[v] && (tSuper::has_parent(v) || it != tSuper::m_orphans.end() )); - if(this->get_tree(v) != tColorTraits::gray() && !is_active){ - typename graph_traits::out_edge_iterator ei,e_end; - for(boost::tie(ei, e_end) = out_edges(v, tSuper::m_g); ei != e_end; ++ei){ - const tVertex& other_node = target(*ei, tSuper::m_g); - if(this->get_tree(other_node) != this->get_tree(v)){ - if(this->get_tree(v) == tColorTraits::black()) - BOOST_CHECK(tSuper::m_res_cap_map[*ei] == 0); - else - BOOST_CHECK(tSuper::m_res_cap_map[tSuper::m_rev_edge_map[*ei]] == 0); - } - } - } - } - - void invariant_five(const tVertex& v) const{ - BOOST_CHECK(this->get_tree(v) != tColorTraits::gray() || tSuper::m_time_map[v] <= tSuper::m_time); + typename std::list< tVertex >::const_iterator it + = find(tSuper::m_orphans.begin(), tSuper::m_orphans.end(), v); + // a node is active, if its in the active_list AND (is has_a_parent, or + // its already in the orphans_list or its the sink, or its the source) + bool is_active = (tSuper::m_in_active_list_map[v] + && (tSuper::has_parent(v) || it != tSuper::m_orphans.end())); + if (this->get_tree(v) != tColorTraits::gray() && !is_active) + { + typename graph_traits< Graph >::out_edge_iterator ei, e_end; + for (boost::tie(ei, e_end) = out_edges(v, tSuper::m_g); ei != e_end; + ++ei) + { + const tVertex& other_node = target(*ei, tSuper::m_g); + if (this->get_tree(other_node) != this->get_tree(v)) + { + if (this->get_tree(v) == tColorTraits::black()) + BOOST_TEST(tSuper::m_res_cap_map[*ei] == 0); + else + BOOST_TEST( + tSuper::m_res_cap_map[tSuper::m_rev_edge_map[*ei]] + == 0); + } + } } - - void invariant_six(const tVertex& v) const{ - if(this->get_tree(v) == tColorTraits::gray() || tSuper::m_time_map[v] != tSuper::m_time) + } + + void invariant_five(const tVertex& v) const + { + BOOST_TEST(this->get_tree(v) != tColorTraits::gray() + || tSuper::m_time_map[v] <= tSuper::m_time); + } + + void invariant_six(const tVertex& v) const + { + if (this->get_tree(v) == tColorTraits::gray() + || tSuper::m_time_map[v] != tSuper::m_time) return; - else{ + else + { tVertex current_node = v; tDistanceVal distance = 0; tColorValue color = this->get_tree(v); - tVertex terminal = (color == tColorTraits::black()) ? tSuper::m_source : tSuper::m_sink; - while(current_node != terminal){ - BOOST_CHECK(tSuper::has_parent(current_node)); - tEdge e = this->get_edge_to_parent(current_node); - ++distance; - current_node = (color == tColorTraits::black())? source(e, tSuper::m_g) : target(e, tSuper::m_g); - if(distance > tSuper::m_dist_map[v]) - break; + tVertex terminal = (color == tColorTraits::black()) + ? tSuper::m_source + : tSuper::m_sink; + while (current_node != terminal) + { + BOOST_TEST(tSuper::has_parent(current_node)); + tEdge e = this->get_edge_to_parent(current_node); + ++distance; + current_node = (color == tColorTraits::black()) + ? source(e, tSuper::m_g) + : target(e, tSuper::m_g); + if (distance > tSuper::m_dist_map[v]) + break; } - BOOST_CHECK(distance == tSuper::m_dist_map[v]); - } + BOOST_TEST(distance == tSuper::m_dist_map[v]); } + } - void invariant_seven(const tVertex& v) const{ - if(this->get_tree(v) == tColorTraits::gray()) + void invariant_seven(const tVertex& v) const + { + if (this->get_tree(v) == tColorTraits::gray()) return; - else{ + else + { tColorValue color = this->get_tree(v); long time = tSuper::m_time_map[v]; tVertex current_node = v; - while(tSuper::has_parent(current_node)){ - tEdge e = this->get_edge_to_parent(current_node); - current_node = (color == tColorTraits::black()) ? source(e, tSuper::m_g) : target(e, tSuper::m_g); - BOOST_CHECK(tSuper::m_time_map[current_node] >= time); + while (tSuper::has_parent(current_node)) + { + tEdge e = this->get_edge_to_parent(current_node); + current_node = (color == tColorTraits::black()) + ? source(e, tSuper::m_g) + : target(e, tSuper::m_g); + BOOST_TEST(tSuper::m_time_map[current_node] >= time); } - } - }//invariant_seven + } + } // invariant_seven - void invariant_eight(const tVertex& v) const{ - if(this->get_tree(v) == tColorTraits::gray()) - return; - else{ + void invariant_eight(const tVertex& v) const + { + if (this->get_tree(v) == tColorTraits::gray()) + return; + else + { tColorValue color = this->get_tree(v); long time = tSuper::m_time_map[v]; tDistanceVal distance = tSuper::m_dist_map[v]; tVertex current_node = v; - while(tSuper::has_parent(current_node)){ - tEdge e = this->get_edge_to_parent(current_node); - current_node = (color == tColorTraits::black()) ? source(e, tSuper::m_g) : target(e, tSuper::m_g); - if(tSuper::m_time_map[current_node] == time) - BOOST_CHECK(tSuper::m_dist_map[current_node] < distance); + while (tSuper::has_parent(current_node)) + { + tEdge e = this->get_edge_to_parent(current_node); + current_node = (color == tColorTraits::black()) + ? source(e, tSuper::m_g) + : target(e, tSuper::m_g); + if (tSuper::m_time_map[current_node] == time) + BOOST_TEST(tSuper::m_dist_map[current_node] < distance); } - } - }//invariant_eight + } + } // invariant_eight - void check_invariants(){ - tVertexIterator vi, v_end; - for(boost::tie(vi, v_end) = vertices(tSuper::m_g); vi != v_end; ++vi){ + void check_invariants() + { + tVertexIterator vi, v_end; + for (boost::tie(vi, v_end) = vertices(tSuper::m_g); vi != v_end; ++vi) + { invariant_four(*vi); invariant_five(*vi); invariant_six(*vi); invariant_seven(*vi); invariant_eight(*vi); - } } - - tEdgeVal test(){ - this->add_active_node(this->m_sink); - this->augment_direct_paths(); - check_invariants(); - //start the main-loop - while(true){ + } + + tEdgeVal test() + { + this->add_active_node(this->m_sink); + this->augment_direct_paths(); + check_invariants(); + // start the main-loop + while (true) + { bool path_found; tEdge connecting_edge; - boost::tie(connecting_edge, path_found) = this->grow(); //find a path from source to sink - if(!path_found){ - //we're finished, no more paths were found - break; + boost::tie(connecting_edge, path_found) + = this->grow(); // find a path from source to sink + if (!path_found) + { + // we're finished, no more paths were found + break; } check_invariants(); this->m_time++; - this->augment(connecting_edge); //augment that path + this->augment(connecting_edge); // augment that path check_invariants(); - this->adopt(); //rebuild search tree structure + this->adopt(); // rebuild search tree structure check_invariants(); - } + } - //check if flow is the sum of outgoing edges of src - tOutEdgeIterator ei, e_end; - tEdgeVal src_sum = 0; - for(boost::tie(ei, e_end) = out_edges(this->m_source, this->m_g); ei != e_end; ++ei){ + // check if flow is the sum of outgoing edges of src + tOutEdgeIterator ei, e_end; + tEdgeVal src_sum = 0; + for (boost::tie(ei, e_end) = out_edges(this->m_source, this->m_g); + ei != e_end; ++ei) + { src_sum += this->m_cap_map[*ei] - this->m_res_cap_map[*ei]; - } - BOOST_CHECK(this->m_flow == src_sum); - //check if flow is the sum of ingoing edges of sink - tEdgeVal sink_sum = 0; - for(boost::tie(ei, e_end) = out_edges(this->m_sink, this->m_g); ei != e_end; ++ei){ + } + BOOST_TEST(this->m_flow == src_sum); + // check if flow is the sum of ingoing edges of sink + tEdgeVal sink_sum = 0; + for (boost::tie(ei, e_end) = out_edges(this->m_sink, this->m_g); + ei != e_end; ++ei) + { tEdge in_edge = this->m_rev_edge_map[*ei]; sink_sum += this->m_cap_map[in_edge] - this->m_res_cap_map[in_edge]; - } - BOOST_CHECK(this->m_flow == sink_sum); - return this->m_flow; } + BOOST_TEST(this->m_flow == sink_sum); + return this->m_flow; + } }; long test_algorithms_invariant(int n_verts, int n_edges, std::size_t seed) { - typedef adjacency_list_traits tVectorTraits; - typedef adjacency_list > > >, - property > > > tVectorGraph; - - tVectorGraph g; - - graph_traits::vertex_descriptor src, sink; - boost::tie(src,sink) = fill_random_max_flow_graph(g, get(edge_capacity,g), get(edge_reverse, g), n_verts, n_edges, seed); - - typedef property_map::type tEdgeCapMap; - typedef property_map::type tEdgeResCapMap; - typedef property_map::type tRevEdgeMap; - typedef property_map::type tVertexPredMap; - typedef property_map::type tVertexColorMap; - typedef property_map::type tDistanceMap; - typedef property_map::type tIndexMap; - typedef boykov_kolmogorov_test< - tVectorGraph, tEdgeCapMap, tEdgeResCapMap, tRevEdgeMap, tVertexPredMap, - tVertexColorMap, tDistanceMap, tIndexMap - > tKolmo; - tKolmo instance(g, src, sink); - return instance.test(); + typedef adjacency_list_traits< vecS, vecS, directedS > tVectorTraits; + typedef adjacency_list< vecS, vecS, directedS, + property< vertex_index_t, long, + property< vertex_predecessor_t, tVectorTraits::edge_descriptor, + property< vertex_color_t, default_color_type, + property< vertex_distance_t, long > > > >, + property< edge_capacity_t, long, + property< edge_residual_capacity_t, long, + property< edge_reverse_t, tVectorTraits::edge_descriptor > > > > + tVectorGraph; + + tVectorGraph g; + + graph_traits< tVectorGraph >::vertex_descriptor src, sink; + boost::tie(src, sink) = fill_random_max_flow_graph( + g, get(edge_capacity, g), get(edge_reverse, g), n_verts, n_edges, seed); + + typedef property_map< tVectorGraph, edge_capacity_t >::type tEdgeCapMap; + typedef property_map< tVectorGraph, edge_residual_capacity_t >::type + tEdgeResCapMap; + typedef property_map< tVectorGraph, edge_reverse_t >::type tRevEdgeMap; + typedef property_map< tVectorGraph, vertex_predecessor_t >::type + tVertexPredMap; + typedef property_map< tVectorGraph, vertex_color_t >::type tVertexColorMap; + typedef property_map< tVectorGraph, vertex_distance_t >::type tDistanceMap; + typedef property_map< tVectorGraph, vertex_index_t >::type tIndexMap; + typedef boykov_kolmogorov_test< tVectorGraph, tEdgeCapMap, tEdgeResCapMap, + tRevEdgeMap, tVertexPredMap, tVertexColorMap, tDistanceMap, tIndexMap > + tKolmo; + tKolmo instance(g, src, sink); + return instance.test(); } -int test_main(int argc, char* argv[]) +int main(int argc, char* argv[]) { - int n_verts = 10; - int n_edges = 500; - std::size_t seed = 1; - - if (argc > 1) n_verts = lexical_cast(argv[1]); - if (argc > 2) n_edges = lexical_cast(argv[2]); - if (argc > 3) seed = lexical_cast(argv[3]); - - //we need at least 2 vertices to create src and sink in random graphs - //this case is also caught in boykov_kolmogorov_max_flow - if (n_verts<2) - n_verts = 2; - - // below are checks for different calls to boykov_kolmogorov_max_flow and different graph-types - - //checks support of vecS storage - long flow_vecS = test_adjacency_list_vecS(n_verts, n_edges, seed); - std::cout << "vecS flow: " << flow_vecS << std::endl; - //checks support of listS storage (especially problems with vertex indices) - long flow_listS = test_adjacency_list_listS(n_verts, n_edges, seed); - std::cout << "listS flow: " << flow_listS << std::endl; - BOOST_CHECK(flow_vecS == flow_listS); - //checks bundled properties - long flow_bundles = test_bundled_properties(n_verts, n_edges, seed); - std::cout << "bundles flow: " << flow_bundles << std::endl; - BOOST_CHECK(flow_listS == flow_bundles); - //checks overloads - long flow_overloads = test_overloads(n_verts, n_edges, seed); - std::cout << "overloads flow: " << flow_overloads << std::endl; - BOOST_CHECK(flow_bundles == flow_overloads); - - // excessive test version where Boykov-Kolmogorov's algorithm invariants are - // checked - long flow_invariants = test_algorithms_invariant(n_verts, n_edges, seed); - std::cout << "invariants flow: " << flow_invariants << std::endl; - BOOST_CHECK(flow_overloads == flow_invariants); - return 0; + int n_verts = 10; + int n_edges = 500; + std::size_t seed = 1; + + if (argc > 1) + n_verts = lexical_cast< int >(argv[1]); + if (argc > 2) + n_edges = lexical_cast< int >(argv[2]); + if (argc > 3) + seed = lexical_cast< std::size_t >(argv[3]); + + // we need at least 2 vertices to create src and sink in random graphs + // this case is also caught in boykov_kolmogorov_max_flow + if (n_verts < 2) + n_verts = 2; + + // below are checks for different calls to boykov_kolmogorov_max_flow and + // different graph-types + + // checks support of vecS storage + long flow_vecS = test_adjacency_list_vecS(n_verts, n_edges, seed); + std::cout << "vecS flow: " << flow_vecS << std::endl; + // checks support of listS storage (especially problems with vertex indices) + long flow_listS = test_adjacency_list_listS(n_verts, n_edges, seed); + std::cout << "listS flow: " << flow_listS << std::endl; + BOOST_TEST(flow_vecS == flow_listS); + // checks bundled properties + long flow_bundles = test_bundled_properties(n_verts, n_edges, seed); + std::cout << "bundles flow: " << flow_bundles << std::endl; + BOOST_TEST(flow_listS == flow_bundles); + // checks overloads + long flow_overloads = test_overloads(n_verts, n_edges, seed); + std::cout << "overloads flow: " << flow_overloads << std::endl; + BOOST_TEST(flow_bundles == flow_overloads); + + // excessive test version where Boykov-Kolmogorov's algorithm invariants are + // checked + long flow_invariants = test_algorithms_invariant(n_verts, n_edges, seed); + std::cout << "invariants flow: " << flow_invariants << std::endl; + BOOST_TEST(flow_overloads == flow_invariants); + return boost::report_errors(); } diff --git a/test/bron_kerbosch_all_cliques.cpp b/test/bron_kerbosch_all_cliques.cpp index d3b6bbb9c..37f5a200e 100644 --- a/test/bron_kerbosch_all_cliques.cpp +++ b/test/bron_kerbosch_all_cliques.cpp @@ -26,19 +26,20 @@ using namespace boost; struct clique_validator { - clique_validator() - { } + clique_validator() {} - template - inline void - clique(const Clique& c, Graph& g) + template < typename Clique, typename Graph > + inline void clique(const Clique& c, Graph& g) { // Simply assert that each vertex in the clique is connected // to all others in the clique. typename Clique::const_iterator i, j, end = c.end(); - for(i = c.begin(); i != end; ++i) { - for(j = c.begin(); j != end; ++j) { - if(i != j) { + for (i = c.begin(); i != end; ++i) + { + for (j = c.begin(); j != end; ++j) + { + if (i != j) + { BOOST_ASSERT(edge(*i, *j, g).second); } } @@ -46,10 +47,9 @@ struct clique_validator } }; -template -void test() +template < typename Graph > void test() { - typedef erdos_renyi_iterator er; + typedef erdos_renyi_iterator< boost::minstd_rand, Graph > er; // Generate random graphs with 15 vertices and 15% probability // of edge connection. @@ -64,15 +64,14 @@ void test() bron_kerbosch_all_cliques(g, clique_validator()); } -int -main(int, char *[]) +int main(int, char*[]) { typedef undirected_graph<> Graph; typedef directed_graph<> DiGraph; std::cout << "*** undirected ***\n"; - test(); + test< Graph >(); std::cout << "*** directed ***\n"; - test(); + test< DiGraph >(); } diff --git a/test/bundled_properties.cpp b/test/bundled_properties.cpp index 50a741ee5..c5193d1be 100644 --- a/test/bundled_properties.cpp +++ b/test/bundled_properties.cpp @@ -5,7 +5,7 @@ // 1.0. (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) -#include +#include #include #include #include @@ -23,214 +23,230 @@ using namespace boost; struct City { - City() {} - City(const std::string& name, int pop, int zipcode) : name(name), population(pop) - { - zipcodes.push_back(zipcode); - } + City() {} + City(const std::string& name, int pop, int zipcode) + : name(name), population(pop) + { + zipcodes.push_back(zipcode); + } - string name; - int population; - vector zipcodes; + string name; + int population; + vector< int > zipcodes; }; std::ostream& operator<<(std::ostream& out, const City& city) { - out << city.name << ' ' << city.population << ' '; - copy(city.zipcodes.begin(), city.zipcodes.end(), - ostream_iterator(out, " ")); - out << -1; - return out; + out << city.name << ' ' << city.population << ' '; + copy(city.zipcodes.begin(), city.zipcodes.end(), + ostream_iterator< int >(out, " ")); + out << -1; + return out; } std::istream& operator>>(std::istream& in, City& city) { - if (in >> city.name >> city.population) { - int zip; - city.zipcodes.clear(); - while (in >> zip && zip != -1) - city.zipcodes.push_back(zip); - } - return in; + if (in >> city.name >> city.population) + { + int zip; + city.zipcodes.clear(); + while (in >> zip && zip != -1) + city.zipcodes.push_back(zip); + } + return in; } bool operator==(const City& c1, const City& c2) { - return (c1.name == c2.name && c1.population == c2.population - && c1.zipcodes == c2.zipcodes); + return (c1.name == c2.name && c1.population == c2.population + && c1.zipcodes == c2.zipcodes); } struct Highway { - Highway() {} - Highway(const string& name, double miles, int speed_limit = 65, int lanes = 4, bool divided = true) - : name(name), miles(miles), speed_limit(speed_limit), lanes(lanes), divided(divided) {} + Highway() {} + Highway(const string& name, double miles, int speed_limit = 65, + int lanes = 4, bool divided = true) + : name(name) + , miles(miles) + , speed_limit(speed_limit) + , lanes(lanes) + , divided(divided) + { + } - string name; - double miles; - int speed_limit; - int lanes; - bool divided; + string name; + double miles; + int speed_limit; + int lanes; + bool divided; }; std::ostream& operator<<(std::ostream& out, const Highway& highway) { - return out << highway.name << ' ' << highway.miles << ' ' << highway.miles - << ' ' << highway.speed_limit << ' ' << highway.lanes - << ' ' << highway.divided; + return out << highway.name << ' ' << highway.miles << ' ' << highway.miles + << ' ' << highway.speed_limit << ' ' << highway.lanes << ' ' + << highway.divided; } std::istream& operator>>(std::istream& in, Highway& highway) { - return in >> highway.name >> highway.miles >> highway.miles - >> highway.speed_limit >> highway.lanes - >> highway.divided; + return in >> highway.name >> highway.miles >> highway.miles + >> highway.speed_limit >> highway.lanes >> highway.divided; } bool operator==(const Highway& h1, const Highway& h2) { - return (h1.name == h2.name && h1.miles == h2.miles - && h1.speed_limit == h2.speed_limit && h1.lanes == h2.lanes - && h1.divided == h2.divided); + return (h1.name == h2.name && h1.miles == h2.miles + && h1.speed_limit == h2.speed_limit && h1.lanes == h2.lanes + && h1.divided == h2.divided); } -template struct truth {}; +template < bool > struct truth +{ +}; -template -typename boost::graph_traits::vertex_descriptor -do_add_vertex(Map& map, VertexIterator, const Bundle& bundle, truth) +template < typename Map, typename VertexIterator, typename Bundle > +typename boost::graph_traits< Map >::vertex_descriptor do_add_vertex( + Map& map, VertexIterator, const Bundle& bundle, truth< true >) { - return add_vertex(bundle, map); + return add_vertex(bundle, map); } -template -typename boost::graph_traits::vertex_descriptor -do_add_vertex(Map& map, VertexIterator& vi, const Bundle& bundle, truth) +template < typename Map, typename VertexIterator, typename Bundle > +typename boost::graph_traits< Map >::vertex_descriptor do_add_vertex( + Map& map, VertexIterator& vi, const Bundle& bundle, truth< false >) { - get(boost::vertex_bundle, map)[*vi] = bundle; - return *vi++; + get(boost::vertex_bundle, map)[*vi] = bundle; + return *vi++; } -template -void test_io(adjacency_list& map, int) -{ - typedef adjacency_list Map; - - ostringstream out; - cout << write(map); - out << write(map); - - istringstream in(out.str()); - adjacency_list map2; - in >> read(map2); - typename graph_traits >::vertex_iterator - v2 = vertices(map2).first; - BGL_FORALL_VERTICES_T(v, map, Map) { - BOOST_CHECK(map[v] == map2[*v2]); - typename graph_traits >::out_edge_iterator - e2 = out_edges(*v2, map2).first; - BGL_FORALL_OUTEDGES_T(v, e, map, Map) { - BOOST_CHECK(map[e] == map[*e2]); - ++e2; +template < class EL, class VL, class D, class VP, class EP, class GP > +void test_io(adjacency_list< EL, VL, D, VP, EP, GP >& map, int) +{ + typedef adjacency_list< EL, VL, D, VP, EP, GP > Map; + + ostringstream out; + cout << write(map); + out << write(map); + + istringstream in(out.str()); + adjacency_list< EL, VL, D, VP, EP, GP > map2; + in >> read(map2); + typename graph_traits< + adjacency_list< EL, VL, D, VP, EP, GP > >::vertex_iterator v2 + = vertices(map2).first; + BGL_FORALL_VERTICES_T(v, map, Map) + { + BOOST_TEST(map[v] == map2[*v2]); + typename graph_traits< + adjacency_list< EL, VL, D, VP, EP, GP > >::out_edge_iterator e2 + = out_edges(*v2, map2).first; + BGL_FORALL_OUTEDGES_T(v, e, map, Map) + { + BOOST_TEST(map[e] == map[*e2]); + ++e2; + } + ++v2; } - ++v2; - } } -template -void test_io(const Map&, long) +template < typename Map > void test_io(const Map&, long) { - // Nothing to test + // Nothing to test } -template -void test_bundled_properties(Map*, truth can_add_vertex) -{ - typedef typename boost::graph_traits::vertex_iterator vertex_iterator; - typedef typename boost::graph_traits::vertex_descriptor vertex_descriptor; - typedef typename boost::graph_traits::edge_descriptor edge_descriptor; - - Map map(CanAddVertex? 2 : 3); - - vertex_iterator vi = vertices(map).first; - vertex_descriptor v = *vi; - map[v].name = "Troy"; - map[v].population = 49170; - map[v].zipcodes.push_back(12180); - - ++vi; - vertex_descriptor u = *vi++; - map[u].name = "Albany"; - map[u].population = 95658; - map[u].zipcodes.push_back(12201); - - // Try adding a vertex with a property value - vertex_descriptor bloomington = do_add_vertex(map, vi, City("Bloomington", 39000, 47401), - can_add_vertex); - BOOST_CHECK(get(boost::vertex_bundle, map)[bloomington].zipcodes[0] == 47401); - - edge_descriptor e = add_edge(v, u, map).first; - map[e].name = "I-87"; - map[e].miles = 10; - map[e].speed_limit = 65; - map[e].lanes = 4; - map[e].divided = true; - - edge_descriptor our_trip = add_edge(v, bloomington, Highway("Long", 1000), map).first; - BOOST_CHECK(get(boost::edge_bundle, map, our_trip).miles == 1000); - - BOOST_CHECK(get(get(&City::name, map), v) == "Troy"); - BOOST_CHECK(get(get(&Highway::name, map), e) == "I-87"); - BOOST_CHECK(get(&City::name, map, u) == "Albany"); - BOOST_CHECK(get(&Highway::name, map, e) == "I-87"); - put(&City::population, map, v, 49168); - BOOST_CHECK(get(&City::population, map)[v] == 49168); - - boost::filtered_graph fmap(map, boost::keep_all()); - BOOST_CHECK(get(boost::edge_bundle, map, our_trip).miles == 1000); - - BOOST_CHECK(get(get(&City::name, fmap), v) == "Troy"); - BOOST_CHECK(get(get(&Highway::name, fmap), e) == "I-87"); - BOOST_CHECK(get(&City::name, fmap, u) == "Albany"); - BOOST_CHECK(get(&Highway::name, fmap, e) == "I-87"); - put(&City::population, fmap, v, 49169); - BOOST_CHECK(get(&City::population, fmap)[v] == 49169); - - test_io(map, 0); +template < typename Map, bool CanAddVertex > +void test_bundled_properties(Map*, truth< CanAddVertex > can_add_vertex) +{ + typedef + typename boost::graph_traits< Map >::vertex_iterator vertex_iterator; + typedef typename boost::graph_traits< Map >::vertex_descriptor + vertex_descriptor; + typedef + typename boost::graph_traits< Map >::edge_descriptor edge_descriptor; + + Map map(CanAddVertex ? 2 : 3); + + vertex_iterator vi = vertices(map).first; + vertex_descriptor v = *vi; + map[v].name = "Troy"; + map[v].population = 49170; + map[v].zipcodes.push_back(12180); + + ++vi; + vertex_descriptor u = *vi++; + map[u].name = "Albany"; + map[u].population = 95658; + map[u].zipcodes.push_back(12201); + + // Try adding a vertex with a property value + vertex_descriptor bloomington = do_add_vertex( + map, vi, City("Bloomington", 39000, 47401), can_add_vertex); + BOOST_TEST( + get(boost::vertex_bundle, map)[bloomington].zipcodes[0] == 47401); + + edge_descriptor e = add_edge(v, u, map).first; + map[e].name = "I-87"; + map[e].miles = 10; + map[e].speed_limit = 65; + map[e].lanes = 4; + map[e].divided = true; + + edge_descriptor our_trip + = add_edge(v, bloomington, Highway("Long", 1000), map).first; + BOOST_TEST(get(boost::edge_bundle, map, our_trip).miles == 1000); + + BOOST_TEST(get(get(&City::name, map), v) == "Troy"); + BOOST_TEST(get(get(&Highway::name, map), e) == "I-87"); + BOOST_TEST(get(&City::name, map, u) == "Albany"); + BOOST_TEST(get(&Highway::name, map, e) == "I-87"); + put(&City::population, map, v, 49168); + BOOST_TEST(get(&City::population, map)[v] == 49168); + + boost::filtered_graph< Map, boost::keep_all > fmap(map, boost::keep_all()); + BOOST_TEST(get(boost::edge_bundle, map, our_trip).miles == 1000); + + BOOST_TEST(get(get(&City::name, fmap), v) == "Troy"); + BOOST_TEST(get(get(&Highway::name, fmap), e) == "I-87"); + BOOST_TEST(get(&City::name, fmap, u) == "Albany"); + BOOST_TEST(get(&Highway::name, fmap, e) == "I-87"); + put(&City::population, fmap, v, 49169); + BOOST_TEST(get(&City::population, fmap)[v] == 49169); + + test_io(map, 0); } void test_subgraph_bundled_properties() { - typedef boost::subgraph< - boost::adjacency_list > > SubMap; - typedef boost::graph_traits::vertex_descriptor Vertex; - typedef boost::graph_traits::vertex_iterator vertex_iterator; - - SubMap map(3); - vertex_iterator vi = vertices(map).first; - Vertex troy = *vi++; - map[troy].name = "Troy"; - map[*vi++].name = "Bloomington"; - map[*vi++].name = "Endicott"; - - SubMap& g1 = map.create_subgraph(); - Vertex troy1 = add_vertex(*vertices(map).first, g1); - BOOST_CHECK(map[troy1].name == g1[troy1].name); + typedef boost::subgraph< + boost::adjacency_list< boost::vecS, boost::vecS, boost::bidirectionalS, + City, boost::property< boost::edge_index_t, int, Highway > > > + SubMap; + typedef boost::graph_traits< SubMap >::vertex_descriptor Vertex; + typedef boost::graph_traits< SubMap >::vertex_iterator vertex_iterator; + + SubMap map(3); + vertex_iterator vi = vertices(map).first; + Vertex troy = *vi++; + map[troy].name = "Troy"; + map[*vi++].name = "Bloomington"; + map[*vi++].name = "Endicott"; + + SubMap& g1 = map.create_subgraph(); + Vertex troy1 = add_vertex(*vertices(map).first, g1); + BOOST_TEST(map[troy1].name == g1[troy1].name); } -int test_main(int, char*[]) +int main(int, char*[]) { - typedef boost::adjacency_list< - boost::listS, boost::vecS, boost::bidirectionalS, - City, Highway> Map1; - typedef boost::adjacency_matrix Map2; - - test_bundled_properties(static_cast(0), truth()); - test_bundled_properties(static_cast(0), truth()); - test_subgraph_bundled_properties(); - return 0; + typedef boost::adjacency_list< boost::listS, boost::vecS, + boost::bidirectionalS, City, Highway > + Map1; + typedef boost::adjacency_matrix< boost::directedS, City, Highway > Map2; + + test_bundled_properties(static_cast< Map1* >(0), truth< true >()); + test_bundled_properties(static_cast< Map2* >(0), truth< false >()); + test_subgraph_bundled_properties(); + return boost::report_errors(); } diff --git a/test/closeness_centrality.cpp b/test/closeness_centrality.cpp index 62b65de1a..d9a2dd315 100644 --- a/test/closeness_centrality.cpp +++ b/test/closeness_centrality.cpp @@ -20,19 +20,18 @@ using namespace boost; // number of vertices in the graph static const unsigned N = 5; -template -struct vertex_vector +template < typename Graph > struct vertex_vector { - typedef graph_traits traits; - typedef vector type; + typedef graph_traits< Graph > traits; + typedef vector< typename traits::vertex_descriptor > type; }; -template -void build_graph(Graph& g, - typename vertex_vector::type& v) +template < typename Graph > +void build_graph(Graph& g, typename vertex_vector< Graph >::type& v) { // add vertices - for(size_t i = 0; i < N; ++i) { + for (size_t i = 0; i < N; ++i) + { v[i] = add_vertex(g); } @@ -44,25 +43,23 @@ void build_graph(Graph& g, add_edge(v[4], v[0], g); } - -template -void test_undirected() +template < typename Graph > void test_undirected() { - typedef typename graph_traits::vertex_descriptor Vertex; - typedef typename graph_traits::edge_descriptor Edge; + typedef typename graph_traits< Graph >::vertex_descriptor Vertex; + typedef typename graph_traits< Graph >::edge_descriptor Edge; - typedef exterior_vertex_property CentralityProperty; + typedef exterior_vertex_property< Graph, double > CentralityProperty; typedef typename CentralityProperty::container_type CentralityContainer; typedef typename CentralityProperty::map_type CentralityMap; - typedef exterior_vertex_property DistanceProperty; + typedef exterior_vertex_property< Graph, int > DistanceProperty; typedef typename DistanceProperty::matrix_type DistanceMatrix; typedef typename DistanceProperty::matrix_map_type DistanceMatrixMap; - typedef constant_property_map WeightMap; + typedef constant_property_map< Edge, int > WeightMap; Graph g; - vector v(N); + vector< Vertex > v(N); build_graph(g, v); CentralityContainer centralities(num_vertices(g)); @@ -76,31 +73,30 @@ void test_undirected() floyd_warshall_all_pairs_shortest_paths(g, dm, weight_map(wm)); all_closeness_centralities(g, dm, cm); - BOOST_ASSERT(cm[v[0]] == double(1)/5); - BOOST_ASSERT(cm[v[1]] == double(1)/7); - BOOST_ASSERT(cm[v[2]] == double(1)/7); - BOOST_ASSERT(cm[v[3]] == double(1)/9); - BOOST_ASSERT(cm[v[4]] == double(1)/6); + BOOST_ASSERT(cm[v[0]] == double(1) / 5); + BOOST_ASSERT(cm[v[1]] == double(1) / 7); + BOOST_ASSERT(cm[v[2]] == double(1) / 7); + BOOST_ASSERT(cm[v[3]] == double(1) / 9); + BOOST_ASSERT(cm[v[4]] == double(1) / 6); } -template -void test_directed() +template < typename Graph > void test_directed() { - typedef typename graph_traits::vertex_descriptor Vertex; - typedef typename graph_traits::edge_descriptor Edge; + typedef typename graph_traits< Graph >::vertex_descriptor Vertex; + typedef typename graph_traits< Graph >::edge_descriptor Edge; - typedef exterior_vertex_property CentralityProperty; + typedef exterior_vertex_property< Graph, double > CentralityProperty; typedef typename CentralityProperty::container_type CentralityContainer; typedef typename CentralityProperty::map_type CentralityMap; - typedef exterior_vertex_property DistanceProperty; + typedef exterior_vertex_property< Graph, int > DistanceProperty; typedef typename DistanceProperty::matrix_type DistanceMatrix; typedef typename DistanceProperty::matrix_map_type DistanceMatrixMap; - typedef constant_property_map WeightMap; + typedef constant_property_map< Edge, int > WeightMap; Graph g; - vector v(N); + vector< Vertex > v(N); build_graph(g, v); CentralityContainer centralities(num_vertices(g)); @@ -117,16 +113,15 @@ void test_directed() BOOST_ASSERT(cm[v[0]] == double(0)); BOOST_ASSERT(cm[v[1]] == double(0)); BOOST_ASSERT(cm[v[2]] == double(0)); - BOOST_ASSERT(cm[v[3]] == double(1)/10); + BOOST_ASSERT(cm[v[3]] == double(1) / 10); BOOST_ASSERT(cm[v[4]] == double(0)); } -int -main(int, char *[]) +int main(int, char*[]) { typedef undirected_graph<> Graph; typedef directed_graph<> Digraph; - test_undirected(); - test_directed(); + test_undirected< Graph >(); + test_directed< Digraph >(); } diff --git a/test/clustering_coefficient.cpp b/test/clustering_coefficient.cpp index a4de0417d..41a43fc51 100644 --- a/test/clustering_coefficient.cpp +++ b/test/clustering_coefficient.cpp @@ -17,18 +17,18 @@ using namespace boost; // number of vertices in the graph static const unsigned N = 5; -template -struct vertex_vector +template < typename Graph > struct vertex_vector { - typedef graph_traits traits; - typedef vector type; + typedef graph_traits< Graph > traits; + typedef vector< typename traits::vertex_descriptor > type; }; -template -void build_graph(Graph& g, typename vertex_vector::type& v) +template < typename Graph > +void build_graph(Graph& g, typename vertex_vector< Graph >::type& v) { // add vertices - for(size_t i = 0; i < N; ++i) { + for (size_t i = 0; i < N; ++i) + { v[i] = add_vertex(g); } @@ -40,17 +40,16 @@ void build_graph(Graph& g, typename vertex_vector::type& v) add_edge(v[4], v[0], g); } -template -void test_undirected() +template < typename Graph > void test_undirected() { - typedef typename graph_traits::vertex_descriptor Vertex; + typedef typename graph_traits< Graph >::vertex_descriptor Vertex; - typedef exterior_vertex_property ClusteringProperty; + typedef exterior_vertex_property< Graph, double > ClusteringProperty; typedef typename ClusteringProperty::container_type ClusteringContainer; typedef typename ClusteringProperty::map_type ClusteringMap; Graph g; - vector v(N); + vector< Vertex > v(N); build_graph(g, v); ClusteringContainer cc(num_vertices(g)); @@ -92,14 +91,13 @@ void test_undirected() BOOST_ASSERT((coef - (7.0f / 15.0f)) < 1e-7f); } -int -main(int, char *[]) +int main(int, char*[]) { typedef undirected_graph<> Graph; // typedef directed_graph<> Digraph; // TODO: write a test for directed clustering coefficient. - test_undirected(); + test_undirected< Graph >(); // test(); } diff --git a/test/copy.cpp b/test/copy.cpp index a4ba54926..d54ab534a 100644 --- a/test/copy.cpp +++ b/test/copy.cpp @@ -8,16 +8,19 @@ using namespace boost; -class copier { +class copier +{ public: - template - void operator()(const V1&, const V2&) const {} + template < class V1, class V2 > void operator()(const V1&, const V2&) const + { + } }; int main() { - adjacency_list > g1, g2; - adjacency_list > g3; + adjacency_list< vecS, vecS, directedS, property< vertex_root_t, int > > g1, + g2; + adjacency_list< vecS, setS, directedS, property< vertex_index_t, int > > g3; copy_graph(g1, g2); copier c; diff --git a/test/core_numbers_test.cpp b/test/core_numbers_test.cpp index 3af081160..24c4e1120 100644 --- a/test/core_numbers_test.cpp +++ b/test/core_numbers_test.cpp @@ -14,141 +14,181 @@ using namespace boost; const char* errstr = ""; -int test_1() { +int test_1() +{ // core numbers of sample graph - typedef adjacency_list Graph; + typedef adjacency_list< vecS, vecS, undirectedS > Graph; Graph G(21); - add_edge(0,1,G); - add_edge(1,2,G); - add_edge(1,3,G); - add_edge(2,3,G); - add_edge(1,4,G); - add_edge(3,4,G); - add_edge(4,5,G); - add_edge(4,6,G); - add_edge(5,6,G); - add_edge(4,7,G); - add_edge(5,7,G); - add_edge(6,7,G); - add_edge(7,8,G); - add_edge(3,9,G); - add_edge(8,9,G); - add_edge(8,10,G); - add_edge(9,10,G); - add_edge(10,11,G); - add_edge(10,12,G); - add_edge(3,13,G); - add_edge(9,13,G); - add_edge(3,14,G); - add_edge(9,14,G); - add_edge(13,14,G); - add_edge(16,17,G); - add_edge(16,18,G); - add_edge(17,19,G); - add_edge(18,19,G); - add_edge(19,20,G); - - std::vector core_nums(num_vertices(G)); - core_numbers(G, - make_iterator_property_map(core_nums.begin(), get(vertex_index,G))); - - for (size_t i=0; i core_nums(num_vertices(G)); + core_numbers( + G, make_iterator_property_map(core_nums.begin(), get(vertex_index, G))); + + for (size_t i = 0; i < num_vertices(G); ++i) + { printf("vertex %3lu : %i\n", (unsigned long)i, core_nums[i]); } - int correct[21]={1,2,2,3,3,3,3,3,2,3,2,1,1,3,3,0,2,2,2,2,1}; - for (size_t i=0; i > graph_t; + typedef adjacency_list< listS, vecS, undirectedS, no_property, + property< edge_weight_t, int > > + graph_t; int num_nodes = 3; - typedef std::pair Edge; + typedef std::pair< int, int > Edge; - Edge edge_array[] = { Edge(0,1), Edge(0,2), Edge(1,2) }; - int weights[] = {-1, -2, -2}; + Edge edge_array[] = { Edge(0, 1), Edge(0, 2), Edge(1, 2) }; + int weights[] = { -1, -2, -2 }; int num_arcs = sizeof(edge_array) / sizeof(Edge); graph_t G(edge_array, edge_array + num_arcs, weights, num_nodes); - std::vector core_nums(num_vertices(G)); - weighted_core_numbers(G, - make_iterator_property_map(core_nums.begin(), get(vertex_index,G))); + std::vector< int > core_nums(num_vertices(G)); + weighted_core_numbers( + G, make_iterator_property_map(core_nums.begin(), get(vertex_index, G))); - for (size_t i=0; i graph_t; + typedef adjacency_list< vecS, vecS, directedS > graph_t; int num_nodes = 5; - typedef std::pair Edge; + typedef std::pair< int, int > Edge; - Edge edge_array[] = { Edge(0,1),Edge(1,2),Edge(2,3),Edge(3,4),Edge(4,0) }; + Edge edge_array[] + = { Edge(0, 1), Edge(1, 2), Edge(2, 3), Edge(3, 4), Edge(4, 0) }; int num_arcs = sizeof(edge_array) / sizeof(Edge); graph_t G(edge_array, edge_array + num_arcs, num_nodes); - std::vector core_nums(num_vertices(G)); - core_numbers(G, - make_iterator_property_map(core_nums.begin(), get(vertex_index,G))); + std::vector< int > core_nums(num_vertices(G)); + core_numbers( + G, make_iterator_property_map(core_nums.begin(), get(vertex_index, G))); - for (size_t i=0; i #include #include -#include +#include // Algorithms to test against #include #include typedef boost::adjacency_list<> GraphT; -typedef boost::erdos_renyi_iterator ERGen; +typedef boost::erdos_renyi_iterator< boost::minstd_rand, GraphT > ERGen; struct VertexData { - int index; + int index; }; struct EdgeData { - int index_e; + int index_e; }; -typedef boost::compressed_sparse_row_graph - CSRGraphT; - -typedef boost::compressed_sparse_row_graph - BidirCSRGraphT; - -template -void assert_graphs_equal(const G1& g1, const VI1& vi1, - const G2& g2, const VI2& vi2, - const IsomorphismMap& iso) { - using boost::out_degree; - - BOOST_CHECK (num_vertices(g1) == num_vertices(g2)); - BOOST_CHECK (num_edges(g1) == num_edges(g2)); - - typedef typename boost::graph_traits::vertex_iterator vertiter1; - { - vertiter1 i, iend; - for (boost::tie(i, iend) = vertices(g1); i != iend; ++i) { - typename boost::graph_traits::vertex_descriptor v1 = *i; - typename boost::graph_traits::vertex_descriptor v2 = iso[v1]; - - BOOST_CHECK (vi1[v1] == vi2[v2]); - - BOOST_CHECK (out_degree(v1, g1) == out_degree(v2, g2)); - std::vector edges1(out_degree(v1, g1)); - typename boost::graph_traits::out_edge_iterator oe1, oe1end; - for (boost::tie(oe1, oe1end) = out_edges(v1, g1); oe1 != oe1end; ++oe1) { - BOOST_CHECK (source(*oe1, g1) == v1); - edges1.push_back(vi1[target(*oe1, g1)]); - } - std::vector edges2(out_degree(v2, g2)); - typename boost::graph_traits::out_edge_iterator oe2, oe2end; - for (boost::tie(oe2, oe2end) = out_edges(v2, g2); oe2 != oe2end; ++oe2) { - BOOST_CHECK (source(*oe2, g2) == v2); - edges2.push_back(vi2[target(*oe2, g2)]); - } - - std::sort(edges1.begin(), edges1.end()); - std::sort(edges2.begin(), edges2.end()); - if (edges1 != edges2) { - std::cerr << "For vertex " << v1 << std::endl; - std::cerr << "edges1:"; - for (size_t i = 0; i < edges1.size(); ++i) std::cerr << " " << edges1[i]; - std::cerr << std::endl; - std::cerr << "edges2:"; - for (size_t i = 0; i < edges2.size(); ++i) std::cerr << " " << edges2[i]; - std::cerr << std::endl; - } - BOOST_CHECK (edges1 == edges2); +typedef boost::compressed_sparse_row_graph< boost::directedS, VertexData, + EdgeData > + CSRGraphT; + +typedef boost::compressed_sparse_row_graph< boost::bidirectionalS, VertexData, + EdgeData > + BidirCSRGraphT; + +template < class G1, class VI1, class G2, class VI2, class IsomorphismMap > +void assert_graphs_equal(const G1& g1, const VI1& vi1, const G2& g2, + const VI2& vi2, const IsomorphismMap& iso) +{ + using boost::out_degree; + + BOOST_TEST(num_vertices(g1) == num_vertices(g2)); + BOOST_TEST(num_edges(g1) == num_edges(g2)); + + typedef typename boost::graph_traits< G1 >::vertex_iterator vertiter1; + { + vertiter1 i, iend; + for (boost::tie(i, iend) = vertices(g1); i != iend; ++i) + { + typename boost::graph_traits< G1 >::vertex_descriptor v1 = *i; + typename boost::graph_traits< G2 >::vertex_descriptor v2 = iso[v1]; + + BOOST_TEST(vi1[v1] == vi2[v2]); + + BOOST_TEST(out_degree(v1, g1) == out_degree(v2, g2)); + std::vector< std::size_t > edges1(out_degree(v1, g1)); + typename boost::graph_traits< G1 >::out_edge_iterator oe1, oe1end; + for (boost::tie(oe1, oe1end) = out_edges(v1, g1); oe1 != oe1end; + ++oe1) + { + BOOST_TEST(source(*oe1, g1) == v1); + edges1.push_back(vi1[target(*oe1, g1)]); + } + std::vector< std::size_t > edges2(out_degree(v2, g2)); + typename boost::graph_traits< G2 >::out_edge_iterator oe2, oe2end; + for (boost::tie(oe2, oe2end) = out_edges(v2, g2); oe2 != oe2end; + ++oe2) + { + BOOST_TEST(source(*oe2, g2) == v2); + edges2.push_back(vi2[target(*oe2, g2)]); + } + + std::sort(edges1.begin(), edges1.end()); + std::sort(edges2.begin(), edges2.end()); + if (edges1 != edges2) + { + std::cerr << "For vertex " << v1 << std::endl; + std::cerr << "edges1:"; + for (size_t i = 0; i < edges1.size(); ++i) + std::cerr << " " << edges1[i]; + std::cerr << std::endl; + std::cerr << "edges2:"; + for (size_t i = 0; i < edges2.size(); ++i) + std::cerr << " " << edges2[i]; + std::cerr << std::endl; + } + BOOST_TEST(edges1 == edges2); + } + } + + { + std::vector< std::pair< std::size_t, std::size_t > > all_edges1; + std::vector< std::pair< std::size_t, std::size_t > > all_edges2; + typename boost::graph_traits< G1 >::edge_iterator ei1, ei1end; + for (boost::tie(ei1, ei1end) = edges(g1); ei1 != ei1end; ++ei1) + all_edges1.push_back( + std::make_pair(vi1[source(*ei1, g1)], vi1[target(*ei1, g1)])); + typename boost::graph_traits< G2 >::edge_iterator ei2, ei2end; + for (boost::tie(ei2, ei2end) = edges(g2); ei2 != ei2end; ++ei2) + all_edges2.push_back( + std::make_pair(vi2[source(*ei2, g2)], vi2[target(*ei2, g2)])); + std::sort(all_edges1.begin(), all_edges1.end()); + std::sort(all_edges2.begin(), all_edges2.end()); + BOOST_TEST(all_edges1 == all_edges2); } - } - - { - std::vector > all_edges1; - std::vector > all_edges2; - typename boost::graph_traits::edge_iterator ei1, ei1end; - for (boost::tie(ei1, ei1end) = edges(g1); ei1 != ei1end; ++ei1) - all_edges1.push_back(std::make_pair(vi1[source(*ei1, g1)], - vi1[target(*ei1, g1)])); - typename boost::graph_traits::edge_iterator ei2, ei2end; - for (boost::tie(ei2, ei2end) = edges(g2); ei2 != ei2end; ++ei2) - all_edges2.push_back(std::make_pair(vi2[source(*ei2, g2)], - vi2[target(*ei2, g2)])); - std::sort(all_edges1.begin(), all_edges1.end()); - std::sort(all_edges2.begin(), all_edges2.end()); - BOOST_CHECK (all_edges1 == all_edges2); - } } -template -void check_consistency_one(const Structure& g) { - // Do a bunch of tests on the graph internal data - // Check that m_rowstart entries are valid, and that entries after - // m_last_source + 1 are all zero - BOOST_CHECK(g.m_rowstart[0] == 0); - for (size_t i = 0; - i < g.m_rowstart.size() - 1; - ++i) { - BOOST_CHECK(g.m_rowstart[i + 1] >= g.m_rowstart[i]); - BOOST_CHECK(g.m_rowstart[i + 1] <= g.m_rowstart.back()); - } - // Check that m_column entries are within range - for (size_t i = 0; i < g.m_rowstart.back(); ++i) { - BOOST_CHECK(g.m_column[i] < g.m_rowstart.size() - 1); - } +template < typename Structure > void check_consistency_one(const Structure& g) +{ + // Do a bunch of tests on the graph internal data + // Check that m_rowstart entries are valid, and that entries after + // m_last_source + 1 are all zero + BOOST_TEST(g.m_rowstart[0] == 0); + for (size_t i = 0; i < g.m_rowstart.size() - 1; ++i) + { + BOOST_TEST(g.m_rowstart[i + 1] >= g.m_rowstart[i]); + BOOST_TEST(g.m_rowstart[i + 1] <= g.m_rowstart.back()); + } + // Check that m_column entries are within range + for (size_t i = 0; i < g.m_rowstart.back(); ++i) + { + BOOST_TEST(g.m_column[i] < g.m_rowstart.size() - 1); + } } -template -void check_consistency_dispatch(const Graph& g, - boost::incidence_graph_tag) { - check_consistency_one(g.m_forward); +template < typename Graph > +void check_consistency_dispatch(const Graph& g, boost::incidence_graph_tag) +{ + check_consistency_one(g.m_forward); } -template -void assert_bidir_equal_in_both_dirs(const G& g) { - BOOST_CHECK (g.m_forward.m_rowstart.size() == g.m_backward.m_rowstart.size()); - BOOST_CHECK (g.m_forward.m_column.size() == g.m_backward.m_column.size()); - typedef typename boost::graph_traits::vertex_descriptor Vertex; - typedef typename boost::graph_traits::edges_size_type EdgeIndex; - std::vector > edges_forward, edges_backward; - for (Vertex i = 0; i < g.m_forward.m_rowstart.size() - 1; ++i) { - for (EdgeIndex j = g.m_forward.m_rowstart[i]; - j < g.m_forward.m_rowstart[i + 1]; ++j) { - edges_forward.push_back(boost::make_tuple(j, i, g.m_forward.m_column[j])); +template < class G > void assert_bidir_equal_in_both_dirs(const G& g) +{ + BOOST_TEST(g.m_forward.m_rowstart.size() == g.m_backward.m_rowstart.size()); + BOOST_TEST(g.m_forward.m_column.size() == g.m_backward.m_column.size()); + typedef typename boost::graph_traits< G >::vertex_descriptor Vertex; + typedef typename boost::graph_traits< G >::edges_size_type EdgeIndex; + std::vector< boost::tuple< EdgeIndex, Vertex, Vertex > > edges_forward, + edges_backward; + for (Vertex i = 0; i < g.m_forward.m_rowstart.size() - 1; ++i) + { + for (EdgeIndex j = g.m_forward.m_rowstart[i]; + j < g.m_forward.m_rowstart[i + 1]; ++j) + { + edges_forward.push_back( + boost::make_tuple(j, i, g.m_forward.m_column[j])); + } } - } - for (Vertex i = 0; i < g.m_backward.m_rowstart.size() - 1; ++i) { - for (EdgeIndex j = g.m_backward.m_rowstart[i]; - j < g.m_backward.m_rowstart[i + 1]; ++j) { - edges_backward.push_back(boost::make_tuple(g.m_backward.m_edge_properties[j], g.m_backward.m_column[j], i)); + for (Vertex i = 0; i < g.m_backward.m_rowstart.size() - 1; ++i) + { + for (EdgeIndex j = g.m_backward.m_rowstart[i]; + j < g.m_backward.m_rowstart[i + 1]; ++j) + { + edges_backward.push_back( + boost::make_tuple(g.m_backward.m_edge_properties[j], + g.m_backward.m_column[j], i)); + } } - } - std::sort(edges_forward.begin(), edges_forward.end()); - std::sort(edges_backward.begin(), edges_backward.end()); - BOOST_CHECK (edges_forward == edges_backward); + std::sort(edges_forward.begin(), edges_forward.end()); + std::sort(edges_backward.begin(), edges_backward.end()); + BOOST_TEST(edges_forward == edges_backward); } -template -void check_consistency_dispatch(const Graph& g, - boost::bidirectional_graph_tag) { - check_consistency_one(g.m_forward); - check_consistency_one(g.m_backward); - assert_bidir_equal_in_both_dirs(g); +template < typename Graph > +void check_consistency_dispatch(const Graph& g, boost::bidirectional_graph_tag) +{ + check_consistency_one(g.m_forward); + check_consistency_one(g.m_backward); + assert_bidir_equal_in_both_dirs(g); } -template -void check_consistency(const Graph& g) { - check_consistency_dispatch(g, typename boost::graph_traits::traversal_category()); +template < typename Graph > void check_consistency(const Graph& g) +{ + check_consistency_dispatch( + g, typename boost::graph_traits< Graph >::traversal_category()); } -template -void graph_test(const OrigGraph& g) +template < typename OrigGraph > void graph_test(const OrigGraph& g) { - // Check copying of a graph - CSRGraphT g2(g); - check_consistency(g2); - BOOST_CHECK((std::size_t)std::distance(edges(g2).first, edges(g2).second) - == num_edges(g2)); - assert_graphs_equal(g, boost::identity_property_map(), - g2, boost::identity_property_map(), - boost::identity_property_map()); - - // Check constructing a graph from iterators - CSRGraphT g3(boost::edges_are_sorted, - boost::make_transform_iterator(edges(g2).first, - boost::detail::make_edge_to_index_pair(g2)), - boost::make_transform_iterator(edges(g2).second, - boost::detail::make_edge_to_index_pair(g2)), - num_vertices(g)); - check_consistency(g3); - BOOST_CHECK((std::size_t)std::distance(edges(g3).first, edges(g3).second) - == num_edges(g3)); - assert_graphs_equal(g2, boost::identity_property_map(), - g3, boost::identity_property_map(), - boost::identity_property_map()); - - // Check constructing a graph using in-place modification of vectors - { - std::vector sources(num_edges(g2)); - std::vector targets(num_edges(g2)); - std::size_t idx = 0; - // Edges actually sorted - BGL_FORALL_EDGES(e, g2, CSRGraphT) { - sources[idx] = source(e, g2); - targets[idx] = target(e, g2); - ++idx; - } - CSRGraphT g3a(boost::construct_inplace_from_sources_and_targets, - sources, - targets, - num_vertices(g2)); - check_consistency(g3a); - assert_graphs_equal(g2, boost::identity_property_map(), - g3a, boost::identity_property_map(), - boost::identity_property_map()); - } - { - std::vector sources(num_edges(g2)); - std::vector targets(num_edges(g2)); - std::size_t idx = 0; - // Edges reverse-sorted - BGL_FORALL_EDGES(e, g2, CSRGraphT) { - sources[num_edges(g2) - 1 - idx] = source(e, g2); - targets[num_edges(g2) - 1 - idx] = target(e, g2); - ++idx; + // Check copying of a graph + CSRGraphT g2(g); + check_consistency(g2); + BOOST_TEST((std::size_t)std::distance(edges(g2).first, edges(g2).second) + == num_edges(g2)); + assert_graphs_equal(g, boost::identity_property_map(), g2, + boost::identity_property_map(), boost::identity_property_map()); + + // Check constructing a graph from iterators + CSRGraphT g3(boost::edges_are_sorted, + boost::make_transform_iterator( + edges(g2).first, boost::detail::make_edge_to_index_pair(g2)), + boost::make_transform_iterator( + edges(g2).second, boost::detail::make_edge_to_index_pair(g2)), + num_vertices(g)); + check_consistency(g3); + BOOST_TEST((std::size_t)std::distance(edges(g3).first, edges(g3).second) + == num_edges(g3)); + assert_graphs_equal(g2, boost::identity_property_map(), g3, + boost::identity_property_map(), boost::identity_property_map()); + + // Check constructing a graph using in-place modification of vectors + { + std::vector< std::size_t > sources(num_edges(g2)); + std::vector< std::size_t > targets(num_edges(g2)); + std::size_t idx = 0; + // Edges actually sorted + BGL_FORALL_EDGES(e, g2, CSRGraphT) + { + sources[idx] = source(e, g2); + targets[idx] = target(e, g2); + ++idx; + } + CSRGraphT g3a(boost::construct_inplace_from_sources_and_targets, + sources, targets, num_vertices(g2)); + check_consistency(g3a); + assert_graphs_equal(g2, boost::identity_property_map(), g3a, + boost::identity_property_map(), boost::identity_property_map()); } - CSRGraphT g3a(boost::construct_inplace_from_sources_and_targets, - sources, - targets, - num_vertices(g2)); - check_consistency(g3a); - assert_graphs_equal(g2, boost::identity_property_map(), - g3a, boost::identity_property_map(), - boost::identity_property_map()); - } - { - std::vector sources(num_edges(g2)); - std::vector targets(num_edges(g2)); - std::size_t idx = 0; - // Edges scrambled using Fisher-Yates shuffle (Durstenfeld variant) from - // Wikipedia - BGL_FORALL_EDGES(e, g2, CSRGraphT) { - sources[idx] = source(e, g2); - targets[idx] = target(e, g2); - ++idx; + { + std::vector< std::size_t > sources(num_edges(g2)); + std::vector< std::size_t > targets(num_edges(g2)); + std::size_t idx = 0; + // Edges reverse-sorted + BGL_FORALL_EDGES(e, g2, CSRGraphT) + { + sources[num_edges(g2) - 1 - idx] = source(e, g2); + targets[num_edges(g2) - 1 - idx] = target(e, g2); + ++idx; + } + CSRGraphT g3a(boost::construct_inplace_from_sources_and_targets, + sources, targets, num_vertices(g2)); + check_consistency(g3a); + assert_graphs_equal(g2, boost::identity_property_map(), g3a, + boost::identity_property_map(), boost::identity_property_map()); } - boost::minstd_rand gen(1); - if (num_edges(g) != 0) { - for (std::size_t i = num_edges(g) - 1; i > 0; --i) { - std::size_t scrambled = boost::uniform_int<>(0, i)(gen); - if (scrambled == i) continue; - using std::swap; - swap(sources[i], sources[scrambled]); - swap(targets[i], targets[scrambled]); - } + { + std::vector< std::size_t > sources(num_edges(g2)); + std::vector< std::size_t > targets(num_edges(g2)); + std::size_t idx = 0; + // Edges scrambled using Fisher-Yates shuffle (Durstenfeld variant) from + // Wikipedia + BGL_FORALL_EDGES(e, g2, CSRGraphT) + { + sources[idx] = source(e, g2); + targets[idx] = target(e, g2); + ++idx; + } + boost::minstd_rand gen(1); + if (num_edges(g) != 0) + { + for (std::size_t i = num_edges(g) - 1; i > 0; --i) + { + std::size_t scrambled = boost::uniform_int<>(0, i)(gen); + if (scrambled == i) + continue; + using std::swap; + swap(sources[i], sources[scrambled]); + swap(targets[i], targets[scrambled]); + } + } + CSRGraphT g3a(boost::construct_inplace_from_sources_and_targets, + sources, targets, num_vertices(g2)); + check_consistency(g3a); + assert_graphs_equal(g2, boost::identity_property_map(), g3a, + boost::identity_property_map(), boost::identity_property_map()); } - CSRGraphT g3a(boost::construct_inplace_from_sources_and_targets, - sources, - targets, - num_vertices(g2)); - check_consistency(g3a); - assert_graphs_equal(g2, boost::identity_property_map(), - g3a, boost::identity_property_map(), - boost::identity_property_map()); - } - - CSRGraphT::edge_iterator ei, ei_end; - - // Check edge_from_index (and implicitly the edge_index property map) for - // each edge in g2 - std::size_t last_src = 0; - for (boost::tie(ei, ei_end) = edges(g2); ei != ei_end; ++ei) { - BOOST_CHECK(edge_from_index(get(boost::edge_index, g2, *ei), g2) == *ei); - std::size_t src = get(boost::vertex_index, g2, source(*ei, g2)); - (void)(std::size_t)get(boost::vertex_index, g2, target(*ei, g2)); - BOOST_CHECK(src >= last_src); - last_src = src; - } - - // Check out edge iteration and vertex iteration for sortedness - CSRGraphT::vertex_iterator vi, vi_end; - std::size_t last_vertex = 0; - bool first_iter = true; - for (boost::tie(vi, vi_end) = vertices(g2); vi != vi_end; ++vi) { - std::size_t v = get(boost::vertex_index, g2, *vi); - BOOST_CHECK(first_iter || v > last_vertex); - last_vertex = v; - first_iter = false; - - CSRGraphT::out_edge_iterator oei, oei_end; - for (boost::tie(oei, oei_end) = out_edges(*vi, g2); oei != oei_end; ++oei) { - BOOST_CHECK(source(*oei, g2) == *vi); + + CSRGraphT::edge_iterator ei, ei_end; + + // Check edge_from_index (and implicitly the edge_index property map) for + // each edge in g2 + std::size_t last_src = 0; + for (boost::tie(ei, ei_end) = edges(g2); ei != ei_end; ++ei) + { + BOOST_TEST(edge_from_index(get(boost::edge_index, g2, *ei), g2) == *ei); + std::size_t src = get(boost::vertex_index, g2, source(*ei, g2)); + (void)(std::size_t) get(boost::vertex_index, g2, target(*ei, g2)); + BOOST_TEST(src >= last_src); + last_src = src; } - // Find a vertex for testing - CSRGraphT::vertex_descriptor test_vertex = vertex(num_vertices(g2) / 2, g2); - int edge_count = 0; - CSRGraphT::out_edge_iterator oei2, oei2_end; - for (boost::tie(oei2, oei_end) = out_edges(*vi, g2); oei2 != oei_end; ++oei2) { - if (target(*oei2, g2) == test_vertex) - ++edge_count; + // Check out edge iteration and vertex iteration for sortedness + CSRGraphT::vertex_iterator vi, vi_end; + std::size_t last_vertex = 0; + bool first_iter = true; + for (boost::tie(vi, vi_end) = vertices(g2); vi != vi_end; ++vi) + { + std::size_t v = get(boost::vertex_index, g2, *vi); + BOOST_TEST(first_iter || v > last_vertex); + last_vertex = v; + first_iter = false; + + CSRGraphT::out_edge_iterator oei, oei_end; + for (boost::tie(oei, oei_end) = out_edges(*vi, g2); oei != oei_end; + ++oei) + { + BOOST_TEST(source(*oei, g2) == *vi); + } + + // Find a vertex for testing + CSRGraphT::vertex_descriptor test_vertex + = vertex(num_vertices(g2) / 2, g2); + int edge_count = 0; + CSRGraphT::out_edge_iterator oei2, oei2_end; + for (boost::tie(oei2, oei_end) = out_edges(*vi, g2); oei2 != oei_end; + ++oei2) + { + if (target(*oei2, g2) == test_vertex) + ++edge_count; + } } - } - - // Run brandes_betweenness_centrality, which touches on a whole lot - // of things, including VertexListGraph and IncidenceGraph - using namespace boost; - std::vector vertex_centralities(num_vertices(g3)); - std::vector edge_centralities(num_edges(g3)); - brandes_betweenness_centrality - (g3, - make_iterator_property_map(vertex_centralities.begin(), - get(boost::vertex_index, g3)), - make_iterator_property_map(edge_centralities.begin(), - get(boost::edge_index, g3))); + + // Run brandes_betweenness_centrality, which touches on a whole lot + // of things, including VertexListGraph and IncidenceGraph + using namespace boost; + std::vector< double > vertex_centralities(num_vertices(g3)); + std::vector< double > edge_centralities(num_edges(g3)); + brandes_betweenness_centrality(g3, + make_iterator_property_map( + vertex_centralities.begin(), get(boost::vertex_index, g3)), + make_iterator_property_map( + edge_centralities.begin(), get(boost::edge_index, g3))); // Extra qualifications for aCC - // Invert the edge centralities and use these as weights to - // Kruskal's MST algorithm, which will test the EdgeListGraph - // capabilities. - double max_val = (std::numeric_limits::max)(); - for (std::size_t i = 0; i < num_edges(g3); ++i) - edge_centralities[i] = - edge_centralities[i] == 0.0? max_val : 1.0 / edge_centralities[i]; - - typedef boost::graph_traits::edge_descriptor edge_descriptor; - std::vector mst_edges; - mst_edges.reserve(num_vertices(g3)); - kruskal_minimum_spanning_tree - (g3, std::back_inserter(mst_edges), - weight_map(make_iterator_property_map(edge_centralities.begin(), - get(boost::edge_index, g3)))); + // Invert the edge centralities and use these as weights to + // Kruskal's MST algorithm, which will test the EdgeListGraph + // capabilities. + double max_val = (std::numeric_limits< double >::max)(); + for (std::size_t i = 0; i < num_edges(g3); ++i) + edge_centralities[i] = edge_centralities[i] == 0.0 + ? max_val + : 1.0 / edge_centralities[i]; + + typedef boost::graph_traits< CSRGraphT >::edge_descriptor edge_descriptor; + std::vector< edge_descriptor > mst_edges; + mst_edges.reserve(num_vertices(g3)); + kruskal_minimum_spanning_tree(g3, std::back_inserter(mst_edges), + weight_map(make_iterator_property_map( + edge_centralities.begin(), get(boost::edge_index, g3)))); } void graph_test(int nnodes, double density, int seed) { - boost::minstd_rand gen(seed); - std::cout << "Testing " << nnodes << " density " << density << std::endl; - GraphT g(ERGen(gen, nnodes, density), ERGen(), nnodes); - graph_test(g); + boost::minstd_rand gen(seed); + std::cout << "Testing " << nnodes << " density " << density << std::endl; + GraphT g(ERGen(gen, nnodes, density), ERGen(), nnodes); + graph_test(g); } void test_graph_properties() { - using namespace boost; + using namespace boost; - typedef compressed_sparse_row_graph > - CSRGraphT; + typedef compressed_sparse_row_graph< directedS, no_property, no_property, + property< graph_name_t, std::string > > + CSRGraphT; - CSRGraphT g; - BOOST_CHECK(get_property(g, graph_name) == ""); - set_property(g, graph_name, "beep"); - BOOST_CHECK(get_property(g, graph_name) == "beep"); + CSRGraphT g; + BOOST_TEST(get_property(g, graph_name) == ""); + set_property(g, graph_name, "beep"); + BOOST_TEST(get_property(g, graph_name) == "beep"); } struct Vertex { - double centrality; + double centrality; }; struct Edge { - Edge(double weight) : weight(weight), centrality(0.0) { } + Edge(double weight) : weight(weight), centrality(0.0) {} - double weight; - double centrality; + double weight; + double centrality; }; void test_vertex_and_edge_properties() { - using namespace boost; - typedef compressed_sparse_row_graph - CSRGraphWithPropsT; - - typedef std::pair E; - E edges_init[6] = { E(0, 1), E(0, 3), E(1, 2), E(3, 1), E(3, 4), E(4, 2) }; - double weights[6] = { 1.0, 1.0, 0.5, 1.0, 1.0, 0.5 }; - double centrality[5] = { 0.0, 1.5, 0.0, 1.0, 0.5 }; - - CSRGraphWithPropsT g(boost::edges_are_sorted, &edges_init[0], &edges_init[0] + 6, &weights[0], 5, 6); - brandes_betweenness_centrality - (g, - centrality_map(get(&Vertex::centrality, g)). - weight_map(get(&Edge::weight, g)). - edge_centrality_map(get(&Edge::centrality, g))); - - BGL_FORALL_VERTICES(v, g, CSRGraphWithPropsT) - BOOST_CHECK(g[v].centrality == centrality[v]); + using namespace boost; + typedef compressed_sparse_row_graph< directedS, Vertex, Edge > + CSRGraphWithPropsT; + + typedef std::pair< int, int > E; + E edges_init[6] = { E(0, 1), E(0, 3), E(1, 2), E(3, 1), E(3, 4), E(4, 2) }; + double weights[6] = { 1.0, 1.0, 0.5, 1.0, 1.0, 0.5 }; + double centrality[5] = { 0.0, 1.5, 0.0, 1.0, 0.5 }; + + CSRGraphWithPropsT g(boost::edges_are_sorted, &edges_init[0], + &edges_init[0] + 6, &weights[0], 5, 6); + brandes_betweenness_centrality(g, + centrality_map(get(&Vertex::centrality, g)) + .weight_map(get(&Edge::weight, g)) + .edge_centrality_map(get(&Edge::centrality, g))); + + BGL_FORALL_VERTICES(v, g, CSRGraphWithPropsT) + BOOST_TEST(g[v].centrality == centrality[v]); } -int test_main(int argc, char* argv[]) +int main(int argc, char* argv[]) { - // Optionally accept a seed value - int seed = int(std::time(0)); - if (argc > 1) seed = boost::lexical_cast(argv[1]); + // Optionally accept a seed value + int seed = int(std::time(0)); + if (argc > 1) + seed = boost::lexical_cast< int >(argv[1]); + + std::cout << "Seed = " << seed << std::endl; + { + std::cout << "Testing empty graph" << std::endl; + CSRGraphT g; + graph_test(g); + } + // graph_test(1000, 0.05, seed); + // graph_test(1000, 0.0, seed); + // graph_test(1000, 0.1, seed); + graph_test(1000, 0.001, seed); + graph_test(1000, 0.0005, seed); + + test_graph_properties(); + test_vertex_and_edge_properties(); + + { + std::cout << "Testing CSR graph built from unsorted edges" << std::endl; + std::pair< int, int > unsorted_edges[] = { std::make_pair(5, 0), + std::make_pair(3, 2), std::make_pair(4, 1), std::make_pair(4, 0), + std::make_pair(0, 2), std::make_pair(5, 2) }; + CSRGraphT g(boost::edges_are_unsorted, unsorted_edges, + unsorted_edges + sizeof(unsorted_edges) / sizeof(*unsorted_edges), + 6); + + // Test vertex and edge bundle access + boost::ignore_unused_variable_warning( + (VertexData&)get(get(boost::vertex_bundle, g), vertex(0, g))); + boost::ignore_unused_variable_warning((const VertexData&)get( + get(boost::vertex_bundle, (const CSRGraphT&)g), vertex(0, g))); + boost::ignore_unused_variable_warning( + (VertexData&)get(boost::vertex_bundle, g, vertex(0, g))); + boost::ignore_unused_variable_warning((const VertexData&)get( + boost::vertex_bundle, (const CSRGraphT&)g, vertex(0, g))); + put(boost::vertex_bundle, g, vertex(0, g), VertexData()); + boost::ignore_unused_variable_warning( + (EdgeData&)get(get(boost::edge_bundle, g), *edges(g).first)); + boost::ignore_unused_variable_warning((const EdgeData&)get( + get(boost::edge_bundle, (const CSRGraphT&)g), *edges(g).first)); + boost::ignore_unused_variable_warning( + (EdgeData&)get(boost::edge_bundle, g, *edges(g).first)); + boost::ignore_unused_variable_warning((const EdgeData&)get( + boost::edge_bundle, (const CSRGraphT&)g, *edges(g).first)); + put(boost::edge_bundle, g, *edges(g).first, EdgeData()); + + CSRGraphT g2(boost::edges_are_unsorted_multi_pass, unsorted_edges, + unsorted_edges + sizeof(unsorted_edges) / sizeof(*unsorted_edges), + 6); + graph_test(g); + graph_test(g2); + assert_graphs_equal(g, boost::identity_property_map(), g2, + boost::identity_property_map(), boost::identity_property_map()); + std::cout << "Testing bidir CSR graph built from unsorted edges" + << std::endl; + BidirCSRGraphT g2b(boost::edges_are_unsorted_multi_pass, unsorted_edges, + unsorted_edges + sizeof(unsorted_edges) / sizeof(*unsorted_edges), + 6); + graph_test(g2b); + assert_graphs_equal(g, boost::identity_property_map(), g2b, + boost::identity_property_map(), boost::identity_property_map()); + // Check in edge access + typedef boost::graph_traits< BidirCSRGraphT >::in_edge_iterator + in_edge_iterator; + std::pair< in_edge_iterator, in_edge_iterator > ie( + in_edges(vertex(0, g2b), g2b)); + // quiet unused variable warning + ie.first = ie.second; + + std::cout << "Testing CSR graph built using add_edges" << std::endl; + // Test building a graph using add_edges on unsorted lists + CSRGraphT g3(boost::edges_are_unsorted, unsorted_edges, unsorted_edges, + 6); // Empty range + add_edges(unsorted_edges, unsorted_edges + 3, g3); + EdgeData edge_data[3]; + add_edges(unsorted_edges + 3, unsorted_edges + 6, edge_data, + edge_data + 3, g3); + graph_test(g3); + assert_graphs_equal(g, boost::identity_property_map(), g3, + boost::identity_property_map(), boost::identity_property_map()); + } - std::cout << "Seed = " << seed << std::endl; - { - std::cout << "Testing empty graph" << std::endl; - CSRGraphT g; - graph_test(g); - } - // graph_test(1000, 0.05, seed); - // graph_test(1000, 0.0, seed); - // graph_test(1000, 0.1, seed); - graph_test(1000, 0.001, seed); - graph_test(1000, 0.0005, seed); - - test_graph_properties(); - test_vertex_and_edge_properties(); - - { - std::cout << "Testing CSR graph built from unsorted edges" << std::endl; - std::pair unsorted_edges[] = {std::make_pair(5, 0), std::make_pair(3, 2), std::make_pair(4, 1), std::make_pair(4, 0), std::make_pair(0, 2), std::make_pair(5, 2)}; - CSRGraphT g(boost::edges_are_unsorted, unsorted_edges, unsorted_edges + sizeof(unsorted_edges) / sizeof(*unsorted_edges), 6); - - // Test vertex and edge bundle access - boost::ignore_unused_variable_warning( - (VertexData&)get(get(boost::vertex_bundle, g), vertex(0, g))); - boost::ignore_unused_variable_warning( - (const VertexData&)get(get(boost::vertex_bundle, (const CSRGraphT&)g), vertex(0, g))); - boost::ignore_unused_variable_warning( - (VertexData&)get(boost::vertex_bundle, g, vertex(0, g))); - boost::ignore_unused_variable_warning( - (const VertexData&)get(boost::vertex_bundle, (const CSRGraphT&)g, vertex(0, g))); - put(boost::vertex_bundle, g, vertex(0, g), VertexData()); - boost::ignore_unused_variable_warning( - (EdgeData&)get(get(boost::edge_bundle, g), *edges(g).first)); - boost::ignore_unused_variable_warning( - (const EdgeData&)get(get(boost::edge_bundle, (const CSRGraphT&)g), *edges(g).first)); - boost::ignore_unused_variable_warning( - (EdgeData&)get(boost::edge_bundle, g, *edges(g).first)); - boost::ignore_unused_variable_warning( - (const EdgeData&)get(boost::edge_bundle, (const CSRGraphT&)g, *edges(g).first)); - put(boost::edge_bundle, g, *edges(g).first, EdgeData()); - - CSRGraphT g2(boost::edges_are_unsorted_multi_pass, unsorted_edges, unsorted_edges + sizeof(unsorted_edges) / sizeof(*unsorted_edges), 6); - graph_test(g); - graph_test(g2); - assert_graphs_equal(g, boost::identity_property_map(), - g2, boost::identity_property_map(), - boost::identity_property_map()); - std::cout << "Testing bidir CSR graph built from unsorted edges" << std::endl; - BidirCSRGraphT g2b(boost::edges_are_unsorted_multi_pass, unsorted_edges, unsorted_edges + sizeof(unsorted_edges) / sizeof(*unsorted_edges), 6); - graph_test(g2b); - assert_graphs_equal(g, boost::identity_property_map(), - g2b, boost::identity_property_map(), - boost::identity_property_map()); - // Check in edge access - typedef boost::graph_traits::in_edge_iterator in_edge_iterator; - std::pair ie(in_edges(vertex(0, g2b), g2b)); - // quiet unused variable warning - ie.first = ie.second; - - std::cout << "Testing CSR graph built using add_edges" << std::endl; - // Test building a graph using add_edges on unsorted lists - CSRGraphT g3(boost::edges_are_unsorted, unsorted_edges, unsorted_edges, 6); // Empty range - add_edges(unsorted_edges, unsorted_edges + 3, g3); - EdgeData edge_data[3]; - add_edges(unsorted_edges + 3, unsorted_edges + 6, edge_data, edge_data + 3, g3); - graph_test(g3); - assert_graphs_equal(g, boost::identity_property_map(), - g3, boost::identity_property_map(), - boost::identity_property_map()); - } - - return 0; + return boost::report_errors(); } diff --git a/test/cuthill_mckee_ordering.cpp b/test/cuthill_mckee_ordering.cpp index 085ae9d64..b7880713a 100644 --- a/test/cuthill_mckee_ordering.cpp +++ b/test/cuthill_mckee_ordering.cpp @@ -20,111 +20,118 @@ Sample Output original bandwidth: 8 Reverse Cuthill-McKee ordering starting at: 6 - 8 3 0 9 2 5 1 4 7 6 + 8 3 0 9 2 5 1 4 7 6 bandwidth: 4 Reverse Cuthill-McKee ordering starting at: 0 - 9 1 4 6 7 2 8 5 3 0 + 9 1 4 6 7 2 8 5 3 0 bandwidth: 4 Reverse Cuthill-McKee ordering: - 0 8 5 7 3 6 4 2 1 9 + 0 8 5 7 3 6 4 2 1 9 bandwidth: 4 */ -int main(int , char* []) +int main(int, char*[]) { - using namespace boost; - using namespace std; - typedef adjacency_list > > Graph; - typedef graph_traits::vertex_descriptor Vertex; - typedef graph_traits::vertices_size_type size_type; + using namespace boost; + using namespace std; + typedef adjacency_list< vecS, vecS, undirectedS, + property< vertex_color_t, default_color_type, + property< vertex_degree_t, int > > > + Graph; + typedef graph_traits< Graph >::vertex_descriptor Vertex; + typedef graph_traits< Graph >::vertices_size_type size_type; - typedef std::pair Pair; - Pair edges[14] = { Pair(0,3), //a-d - Pair(0,5), //a-f - Pair(1,2), //b-c - Pair(1,4), //b-e - Pair(1,6), //b-g - Pair(1,9), //b-j - Pair(2,3), //c-d - Pair(2,4), //c-e - Pair(3,5), //d-f - Pair(3,8), //d-i - Pair(4,6), //e-g - Pair(5,6), //f-g - Pair(5,7), //f-h - Pair(6,7) }; //g-h - - Graph G(10); - for (int i = 0; i < 14; ++i) - add_edge(edges[i].first, edges[i].second, G); + typedef std::pair< std::size_t, std::size_t > Pair; + Pair edges[14] = { Pair(0, 3), // a-d + Pair(0, 5), // a-f + Pair(1, 2), // b-c + Pair(1, 4), // b-e + Pair(1, 6), // b-g + Pair(1, 9), // b-j + Pair(2, 3), // c-d + Pair(2, 4), // c-e + Pair(3, 5), // d-f + Pair(3, 8), // d-i + Pair(4, 6), // e-g + Pair(5, 6), // f-g + Pair(5, 7), // f-h + Pair(6, 7) }; // g-h - graph_traits::vertex_iterator ui, ui_end; + Graph G(10); + for (int i = 0; i < 14; ++i) + add_edge(edges[i].first, edges[i].second, G); - property_map::type deg = get(vertex_degree, G); - for (boost::tie(ui, ui_end) = vertices(G); ui != ui_end; ++ui) - deg[*ui] = degree(*ui, G); + graph_traits< Graph >::vertex_iterator ui, ui_end; - property_map::type - index_map = get(vertex_index, G); + property_map< Graph, vertex_degree_t >::type deg = get(vertex_degree, G); + for (boost::tie(ui, ui_end) = vertices(G); ui != ui_end; ++ui) + deg[*ui] = degree(*ui, G); - std::cout << "original bandwidth: " << bandwidth(G) << std::endl; + property_map< Graph, vertex_index_t >::type index_map + = get(vertex_index, G); - std::vector inv_perm(num_vertices(G)); - std::vector perm(num_vertices(G)); - { - Vertex s = vertex(6, G); - //reverse cuthill_mckee_ordering - cuthill_mckee_ordering(G, s, inv_perm.rbegin(), get(vertex_color, G), - get(vertex_degree, G)); - cout << "Reverse Cuthill-McKee ordering starting at: " << s << endl; - cout << " "; - for (std::vector::const_iterator i = inv_perm.begin(); - i != inv_perm.end(); ++i) - cout << index_map[*i] << " "; - cout << endl; + std::cout << "original bandwidth: " << bandwidth(G) << std::endl; - for (size_type c = 0; c != inv_perm.size(); ++c) - perm[index_map[inv_perm[c]]] = c; - std::cout << " bandwidth: " - << bandwidth(G, make_iterator_property_map(&perm[0], index_map, perm[0])) - << std::endl; - } - { - Vertex s = vertex(0, G); - //reverse cuthill_mckee_ordering - cuthill_mckee_ordering(G, s, inv_perm.rbegin(), get(vertex_color, G), - get(vertex_degree, G)); - cout << "Reverse Cuthill-McKee ordering starting at: " << s << endl; - cout << " "; - for (std::vector::const_iterator i=inv_perm.begin(); - i != inv_perm.end(); ++i) - cout << index_map[*i] << " "; - cout << endl; + std::vector< Vertex > inv_perm(num_vertices(G)); + std::vector< size_type > perm(num_vertices(G)); + { + Vertex s = vertex(6, G); + // reverse cuthill_mckee_ordering + cuthill_mckee_ordering(G, s, inv_perm.rbegin(), get(vertex_color, G), + get(vertex_degree, G)); + cout << "Reverse Cuthill-McKee ordering starting at: " << s << endl; + cout << " "; + for (std::vector< Vertex >::const_iterator i = inv_perm.begin(); + i != inv_perm.end(); ++i) + cout << index_map[*i] << " "; + cout << endl; - for (size_type c = 0; c != inv_perm.size(); ++c) - perm[index_map[inv_perm[c]]] = c; - std::cout << " bandwidth: " - << bandwidth(G, make_iterator_property_map(&perm[0], index_map, perm[0])) - << std::endl; - } + for (size_type c = 0; c != inv_perm.size(); ++c) + perm[index_map[inv_perm[c]]] = c; + std::cout << " bandwidth: " + << bandwidth(G, + make_iterator_property_map( + &perm[0], index_map, perm[0])) + << std::endl; + } + { + Vertex s = vertex(0, G); + // reverse cuthill_mckee_ordering + cuthill_mckee_ordering(G, s, inv_perm.rbegin(), get(vertex_color, G), + get(vertex_degree, G)); + cout << "Reverse Cuthill-McKee ordering starting at: " << s << endl; + cout << " "; + for (std::vector< Vertex >::const_iterator i = inv_perm.begin(); + i != inv_perm.end(); ++i) + cout << index_map[*i] << " "; + cout << endl; - { - //reverse cuthill_mckee_ordering - cuthill_mckee_ordering(G, inv_perm.rbegin()); - - cout << "Reverse Cuthill-McKee ordering:" << endl; - cout << " "; - for (std::vector::const_iterator i=inv_perm.begin(); - i != inv_perm.end(); ++i) - cout << index_map[*i] << " "; - cout << endl; + for (size_type c = 0; c != inv_perm.size(); ++c) + perm[index_map[inv_perm[c]]] = c; + std::cout << " bandwidth: " + << bandwidth(G, + make_iterator_property_map( + &perm[0], index_map, perm[0])) + << std::endl; + } - for (size_type c = 0; c != inv_perm.size(); ++c) - perm[index_map[inv_perm[c]]] = c; - std::cout << " bandwidth: " - << bandwidth(G, make_iterator_property_map(&perm[0], index_map, perm[0])) - << std::endl; - } - return 0; + { + // reverse cuthill_mckee_ordering + cuthill_mckee_ordering(G, inv_perm.rbegin()); + + cout << "Reverse Cuthill-McKee ordering:" << endl; + cout << " "; + for (std::vector< Vertex >::const_iterator i = inv_perm.begin(); + i != inv_perm.end(); ++i) + cout << index_map[*i] << " "; + cout << endl; + + for (size_type c = 0; c != inv_perm.size(); ++c) + perm[index_map[inv_perm[c]]] = c; + std::cout << " bandwidth: " + << bandwidth(G, + make_iterator_property_map( + &perm[0], index_map, perm[0])) + << std::endl; + } + return 0; } diff --git a/test/cycle_canceling_test.cpp b/test/cycle_canceling_test.cpp index d2acc802b..f136388c6 100644 --- a/test/cycle_canceling_test.cpp +++ b/test/cycle_canceling_test.cpp @@ -1,6 +1,6 @@ //======================================================================= // Copyright 2013 University of Warsaw. -// Authors: Piotr Wygocki +// Authors: Piotr Wygocki // // Distributed under the Boost Software License, Version 1.0. (See // accompanying file LICENSE_1_0.txt or copy at @@ -16,9 +16,9 @@ #include "min_cost_max_flow_utils.hpp" - -BOOST_AUTO_TEST_CASE(cycle_canceling_def_test) { - boost::SampleGraph::vertex_descriptor s,t; +BOOST_AUTO_TEST_CASE(cycle_canceling_def_test) +{ + boost::SampleGraph::vertex_descriptor s, t; boost::SampleGraph::Graph g; boost::SampleGraph::getSampleGraph(g, s, t); @@ -29,35 +29,42 @@ BOOST_AUTO_TEST_CASE(cycle_canceling_def_test) { BOOST_CHECK_EQUAL(cost, 29); } -BOOST_AUTO_TEST_CASE(path_augmentation_def_test2) { - boost::SampleGraph::vertex_descriptor s,t; - boost::SampleGraph::Graph g; +BOOST_AUTO_TEST_CASE(path_augmentation_def_test2) +{ + boost::SampleGraph::vertex_descriptor s, t; + boost::SampleGraph::Graph g; boost::SampleGraph::getSampleGraph2(g, s, t); boost::edmonds_karp_max_flow(g, s, t); boost::cycle_canceling(g); - int cost = boost::find_flow_cost(g); + int cost = boost::find_flow_cost(g); BOOST_CHECK_EQUAL(cost, 7); } -BOOST_AUTO_TEST_CASE(cycle_canceling_test) { - boost::SampleGraph::vertex_descriptor s,t; +BOOST_AUTO_TEST_CASE(cycle_canceling_test) +{ + boost::SampleGraph::vertex_descriptor s, t; typedef boost::SampleGraph::Graph Graph; - boost::SampleGraph::Graph g; + boost::SampleGraph::Graph g; boost::SampleGraph::getSampleGraph(g, s, t); int N = num_vertices(g); - std::vector dist(N); - typedef boost::graph_traits::edge_descriptor edge_descriptor; - std::vector pred(N); + std::vector< int > dist(N); + typedef boost::graph_traits< Graph >::edge_descriptor edge_descriptor; + std::vector< edge_descriptor > pred(N); - boost::property_map::const_type idx = get(boost::vertex_index, g); + boost::property_map< Graph, boost::vertex_index_t >::const_type idx + = get(boost::vertex_index, g); boost::edmonds_karp_max_flow(g, s, t); - boost::cycle_canceling(g, boost::distance_map(boost::make_iterator_property_map(dist.begin(), idx)).predecessor_map(boost::make_iterator_property_map(pred.begin(), idx)).vertex_index_map(idx)); + boost::cycle_canceling(g, + boost::distance_map( + boost::make_iterator_property_map(dist.begin(), idx)) + .predecessor_map( + boost::make_iterator_property_map(pred.begin(), idx)) + .vertex_index_map(idx)); int cost = boost::find_flow_cost(g); BOOST_CHECK_EQUAL(cost, 29); } - diff --git a/test/cycle_ratio_tests.cpp b/test/cycle_ratio_tests.cpp index 5448c87b5..0b20b7427 100644 --- a/test/cycle_ratio_tests.cpp +++ b/test/cycle_ratio_tests.cpp @@ -14,7 +14,7 @@ #include #include -#include +#include /** * @author Dmitry Bufistov @@ -22,8 +22,8 @@ */ /*! -* The graph has two equal cycles with ratio 2/3 -*/ + * The graph has two equal cycles with ratio 2/3 + */ static const char test_graph1[] = "digraph G {\ edge [w1=1, w2=1];\ 1->2\ @@ -37,14 +37,15 @@ static const char test_graph1[] = "digraph G {\ }"; /*! -* The graph has no cycles -*/ -static const std::string test_graph2 = "digraph G {edge [w1=1]; 1->3 [w2=1]; 1->2 [w2=2]; 1->4 [w2=7]; }"; + * The graph has no cycles + */ +static const std::string test_graph2 + = "digraph G {edge [w1=1]; 1->3 [w2=1]; 1->2 [w2=2]; 1->4 [w2=7]; }"; /*! -* Example from the paper "Nunerical computation of spectral elements" -* Maximum cycle ratio is 5.5 -*/ + * Example from the paper "Nunerical computation of spectral elements" + * Maximum cycle ratio is 5.5 + */ static const char test_graph3[] = "\ digraph article {\ edge [w2 =2];\ @@ -60,9 +61,9 @@ digraph article {\ }"; /*! -* Simple multigraph. -* Maximum cycle ratio is 2.5, minimum 0.5 -*/ + * Simple multigraph. + * Maximum cycle ratio is 2.5, minimum 0.5 + */ static const char test_graph4[] = "digraph G {\ edge [w2=1];\ a->b [w1=1];\ @@ -72,19 +73,20 @@ b->a [w1=3];\ }"; /*! -* The big graph with two equal cycles -*/ -static const char test_graph5[]= "digraph G { edge [w2=1, w1=1]; n94->n8; n95->n8; n93->n8; n93->n9; n42->n9; n23->n13;\ + * The big graph with two equal cycles + */ +static const char test_graph5[] + = "digraph G { edge [w2=1, w1=1]; n94->n8; n95->n8; n93->n8; n93->n9; n42->n9; n23->n13;\ n29->n13; n95->n14; n37->n14; n95->n19; n37->n19; n94->n23; n60->n26; n76->n26; n94->n29; n9->n33 [w1=0]; n80->n33;\ n14->n34 [w1=0];n19->n34; n94->n37; n94->n42; n95->n42; n8->n60; n26->n60; n26->n76; n106->n76; n93->n80; n42->n80;\ n33->n93; n60->n93; n13->n94; n60->n94; n34->n95; n60->n95; n94->n106; n95->n106; n93->n106;\ }"; /*! -* Random graph generated by hands. -* Maximum cycle ratio is 3.58, minimum is 0.294118 -*/ -static const char test_graph6[]= "digraph test_graph6 {\ + * Random graph generated by hands. + * Maximum cycle ratio is 3.58, minimum is 0.294118 + */ +static const char test_graph6[] = "digraph test_graph6 {\ 16;\ 17;\ \ @@ -130,218 +132,215 @@ static const char test_graph6[]= "digraph test_graph6 {\ }"; using namespace boost; -typedef property > vertex_props_t; -template struct Graph +typedef property< vertex_index_t, int, + property< boost::vertex_name_t, std::string > > + vertex_props_t; +template < typename TW1, typename TW2 > struct Graph { - typedef typename boost::property< - boost::edge_weight_t, TW1, - typename boost::property< - boost::edge_weight2_t, TW2, property - > - > edge_props_t; - typedef typename boost::adjacency_list< - boost::listS, boost::listS, boost::directedS, vertex_props_t, - edge_props_t> - type; + typedef typename boost::property< boost::edge_weight_t, TW1, + typename boost::property< boost::edge_weight2_t, TW2, + property< boost::edge_index_t, int > > > + edge_props_t; + typedef typename boost::adjacency_list< boost::listS, boost::listS, + boost::directedS, vertex_props_t, edge_props_t > + type; }; -typedef Graph::type diGraphInt; -typedef Graph::type diGraphReal; +typedef Graph< int, int >::type diGraphInt; +typedef Graph< double, double >::type diGraphReal; -template -struct CEdgeProps +template < typename TW1, typename TW2 > struct CEdgeProps { - CEdgeProps(TW1 w1 = 1, TW2 w2 = 2) : - m_w1(w1), m_w2(w2), m_edge_index((std::numeric_limits::max)()) - {} - TW1 m_w1; - TW2 m_w2; - int m_edge_index; + CEdgeProps(TW1 w1 = 1, TW2 w2 = 2) + : m_w1(w1), m_w2(w2), m_edge_index((std::numeric_limits< int >::max)()) + { + } + TW1 m_w1; + TW2 m_w2; + int m_edge_index; }; -typedef adjacency_matrix > GraphMInt; +typedef adjacency_matrix< directedS, no_property, CEdgeProps< int, int > > + GraphMInt; -///Create "tokens_map" for reading graph properties from .dot file -template -void make_dynamic_properties(TG &g, dynamic_properties &p) +/// Create "tokens_map" for reading graph properties from .dot file +template < typename TG > +void make_dynamic_properties(TG& g, dynamic_properties& p) { - p.property("node_id", get(vertex_name, g)); - p.property("label", get(edge_weight, g)); - p.property("w1", get(edge_weight, g)); - p.property("w2", get(edge_weight2, g)); + p.property("node_id", get(vertex_name, g)); + p.property("label", get(edge_weight, g)); + p.property("w1", get(edge_weight, g)); + p.property("w2", get(edge_weight2, g)); } -template -void read_data1(std::istream &is, TG &g) +template < typename TG > void read_data1(std::istream& is, TG& g) { - dynamic_properties p; - make_dynamic_properties(g, p); - read_graphviz(is, g, p); - std::cout << "Number of vertices: " << num_vertices(g) << std::endl; - std::cout << "Number of edges: " << num_edges(g) << std::endl; - int i = 0; - BGL_FORALL_VERTICES_T(vd, g, TG) - { - put(vertex_index, g, vd, i++); - } - i=0; - BGL_FORALL_EDGES_T(ed, g, TG) - { - put(edge_index, g, ed, i++); - } + dynamic_properties p; + make_dynamic_properties(g, p); + read_graphviz(is, g, p); + std::cout << "Number of vertices: " << num_vertices(g) << std::endl; + std::cout << "Number of edges: " << num_edges(g) << std::endl; + int i = 0; + BGL_FORALL_VERTICES_T(vd, g, TG) { put(vertex_index, g, vd, i++); } + i = 0; + BGL_FORALL_EDGES_T(ed, g, TG) { put(edge_index, g, ed, i++); } } -template -void read_data(const char *file, TG &g) +template < typename TG > void read_data(const char* file, TG& g) { - std::cout << "Reading data from file: " << file << std::endl; - std::ifstream ifs(file); - BOOST_REQUIRE(ifs.good()); - read_data1(ifs, g); + std::cout << "Reading data from file: " << file << std::endl; + std::ifstream ifs(file); + BOOST_TEST(ifs.good()); + read_data1(ifs, g); } struct my_float : boost::mcr_float<> { - static double infinity() - { - return 1000; - } + static double infinity() { return 1000; } }; struct my_float2 : boost::mcr_float<> { - static double infinity() { return 2; } + static double infinity() { return 2; } }; -int test_main(int argc, char* argv[]) +int main(int argc, char* argv[]) { - assert (argc >= 2); - using std::endl; using std::cout; - const double epsilon = 0.005; - double min_cr, max_cr; ///Minimum and maximum cycle ratio - typedef std::vector::edge_descriptor> ccInt_t; - typedef std::vector::edge_descriptor> ccReal_t; - ccInt_t cc; ///critical cycle - - diGraphInt tg; - property_map::type vim = get(vertex_index, tg); - property_map::type ew1m = get(edge_weight, tg); - property_map::type ew2m = get(edge_weight2, tg); - - + assert(argc >= 2); + using std::cout; + using std::endl; + const double epsilon = 0.005; + double min_cr, max_cr; /// Minimum and maximum cycle ratio + typedef std::vector< graph_traits< diGraphInt >::edge_descriptor > ccInt_t; + typedef std::vector< graph_traits< diGraphReal >::edge_descriptor > + ccReal_t; + ccInt_t cc; /// critical cycle + + diGraphInt tg; + property_map< diGraphInt, vertex_index_t >::type vim + = get(vertex_index, tg); + property_map< diGraphInt, edge_weight_t >::type ew1m = get(edge_weight, tg); + property_map< diGraphInt, edge_weight2_t >::type ew2m + = get(edge_weight2, tg); - { - std::istringstream iss(test_graph1); - assert(iss.good()); - read_data1(iss, tg); - max_cr = maximum_cycle_ratio(tg, vim, ew1m, ew2m); - cout << "Maximum cycle ratio is " << max_cr << endl; - BOOST_CHECK(std::abs( max_cr - 0.666666666) < epsilon ); - tg.clear(); - } + { + std::istringstream iss(test_graph1); + assert(iss.good()); + read_data1(iss, tg); + max_cr = maximum_cycle_ratio(tg, vim, ew1m, ew2m); + cout << "Maximum cycle ratio is " << max_cr << endl; + BOOST_TEST(std::abs(max_cr - 0.666666666) < epsilon); + tg.clear(); + } - { - std::istringstream iss(test_graph2); - read_data1(iss, tg); - // TODO: This is causing a failuire, but I'm not really sure what it's doing per se. - // Commented out for now. - // BOOST_CHECK(std::abs(maximum_cycle_ratio(tg, vim, ew1m, ew2m) + (std::numeric_limits::max)()) < epsilon ); - BOOST_CHECK(std::abs(boost::maximum_cycle_ratio(tg, vim, ew1m, ew2m, - static_cast(0), my_float()) + 1000) < epsilon ); - tg.clear(); - } + { + std::istringstream iss(test_graph2); + read_data1(iss, tg); + // TODO: This is causing a failuire, but I'm not really sure what it's + // doing per se. Commented out for now. + // BOOST_TEST(std::abs(maximum_cycle_ratio(tg, vim, ew1m, ew2m) + + // (std::numeric_limits::max)()) < epsilon ); + BOOST_TEST(std::abs(boost::maximum_cycle_ratio(tg, vim, ew1m, ew2m, + static_cast< ccInt_t* >(0), my_float()) + + 1000) + < epsilon); + tg.clear(); + } - { - std::istringstream iss(test_graph3); - diGraphInt tgi; - read_data1(iss, tgi); - double max_cr = maximum_cycle_ratio(tgi, vim, ew1m, ew2m, - static_cast(0)); - cout << "Maximum cycle ratio is " << max_cr << endl; - BOOST_CHECK(std::abs( max_cr - 2.75) < epsilon ); - double maxmc = maximum_cycle_mean(tgi, vim, ew1m, get(edge_index, tgi)); - cout << "Maximum cycle mean is " << maxmc << endl; - BOOST_CHECK(std::abs( maxmc - 5.5) < epsilon ); - tg.clear(); - } + { + std::istringstream iss(test_graph3); + diGraphInt tgi; + read_data1(iss, tgi); + double max_cr = maximum_cycle_ratio( + tgi, vim, ew1m, ew2m, static_cast< ccInt_t* >(0)); + cout << "Maximum cycle ratio is " << max_cr << endl; + BOOST_TEST(std::abs(max_cr - 2.75) < epsilon); + double maxmc = maximum_cycle_mean(tgi, vim, ew1m, get(edge_index, tgi)); + cout << "Maximum cycle mean is " << maxmc << endl; + BOOST_TEST(std::abs(maxmc - 5.5) < epsilon); + tg.clear(); + } - { - std::istringstream iss(test_graph4); - read_data1(iss, tg); - max_cr = maximum_cycle_ratio(tg, vim, ew1m, ew2m); - cout << "Maximum cycle ratio is " << max_cr << endl; - BOOST_CHECK(std::abs( max_cr - 2.5) < epsilon ); - min_cr = minimum_cycle_ratio(tg, vim, ew1m, ew2m); - cout << "Minimum cycle ratio is " << min_cr << endl; - BOOST_CHECK(std::abs( min_cr - 0.5) < epsilon ); - tg.clear(); - } + { + std::istringstream iss(test_graph4); + read_data1(iss, tg); + max_cr = maximum_cycle_ratio(tg, vim, ew1m, ew2m); + cout << "Maximum cycle ratio is " << max_cr << endl; + BOOST_TEST(std::abs(max_cr - 2.5) < epsilon); + min_cr = minimum_cycle_ratio(tg, vim, ew1m, ew2m); + cout << "Minimum cycle ratio is " << min_cr << endl; + BOOST_TEST(std::abs(min_cr - 0.5) < epsilon); + tg.clear(); + } - { - std::istringstream iss(test_graph5); - read_data1(iss, tg); - min_cr = minimum_cycle_ratio(tg, vim, ew1m, ew2m, &cc, my_float()); - BOOST_CHECK(std::abs( min_cr - 0.666666666) < epsilon ); - cout << "Minimum cycle ratio is " << min_cr << endl; - cout << "Critical cycle is:\n"; - for (ccInt_t::iterator itr = cc.begin(); itr != cc.end(); ++itr) { - cout << "(" << get(vertex_name, tg, source(*itr, tg)) << - "," << get(vertex_name, tg, target(*itr, tg)) << ") "; + std::istringstream iss(test_graph5); + read_data1(iss, tg); + min_cr = minimum_cycle_ratio(tg, vim, ew1m, ew2m, &cc, my_float()); + BOOST_TEST(std::abs(min_cr - 0.666666666) < epsilon); + cout << "Minimum cycle ratio is " << min_cr << endl; + cout << "Critical cycle is:\n"; + for (ccInt_t::iterator itr = cc.begin(); itr != cc.end(); ++itr) + { + cout << "(" << get(vertex_name, tg, source(*itr, tg)) << "," + << get(vertex_name, tg, target(*itr, tg)) << ") "; + } + cout << endl; + tg.clear(); } - cout << endl; - tg.clear(); - } - { - read_data(argv[1], tg); - min_cr = boost::minimum_cycle_ratio(tg, vim, ew1m, ew2m, &cc, my_float2()); - cout << "Minimum cycle ratio is " << min_cr << endl; - BOOST_CHECK(std::abs(min_cr - 0.33333333333) < epsilon ); - cout << "Critical cycle is:" << endl; - for (ccInt_t::iterator it = cc.begin(); it != cc.end(); ++it) { - cout << "(" << get(vertex_name, tg, source(*it, tg)) << "," << - get(vertex_name, tg, target(*it, tg)) << ") "; + read_data(argv[1], tg); + min_cr + = boost::minimum_cycle_ratio(tg, vim, ew1m, ew2m, &cc, my_float2()); + cout << "Minimum cycle ratio is " << min_cr << endl; + BOOST_TEST(std::abs(min_cr - 0.33333333333) < epsilon); + cout << "Critical cycle is:" << endl; + for (ccInt_t::iterator it = cc.begin(); it != cc.end(); ++it) + { + cout << "(" << get(vertex_name, tg, source(*it, tg)) << "," + << get(vertex_name, tg, target(*it, tg)) << ") "; + } + cout << endl; + tg.clear(); } - cout << endl; - tg.clear(); - } - { - diGraphReal tgr; - ccReal_t cc1; - std::istringstream iss(test_graph6); - read_data1(iss, tgr); - max_cr = maximum_cycle_ratio(tgr, get(vertex_index, tgr), get(edge_weight, tgr), get(edge_weight2, tgr)); - cout << "Maximum cycle ratio is " << max_cr << endl; - min_cr = minimum_cycle_ratio(tgr, get(vertex_index, tgr), get(edge_weight, tgr), - get(edge_weight2, tgr), &cc); - cout << "Minimal cycle ratio is " << min_cr << endl; - std::pair cr(.0,.0); - cout << "Critical cycle is:\n"; - for (ccReal_t::iterator itr = cc.begin(); itr != cc.end(); ++itr) { - cr.first += get(edge_weight, tgr, *itr); cr.second += get(edge_weight2, tgr, *itr); - cout << "(" << get(vertex_name, tgr, source(*itr, tgr)) << "," << - get(vertex_name, tgr, target(*itr, tgr)) << ") "; + diGraphReal tgr; + ccReal_t cc1; + std::istringstream iss(test_graph6); + read_data1(iss, tgr); + max_cr = maximum_cycle_ratio(tgr, get(vertex_index, tgr), + get(edge_weight, tgr), get(edge_weight2, tgr)); + cout << "Maximum cycle ratio is " << max_cr << endl; + min_cr = minimum_cycle_ratio(tgr, get(vertex_index, tgr), + get(edge_weight, tgr), get(edge_weight2, tgr), &cc); + cout << "Minimal cycle ratio is " << min_cr << endl; + std::pair< double, double > cr(.0, .0); + cout << "Critical cycle is:\n"; + for (ccReal_t::iterator itr = cc.begin(); itr != cc.end(); ++itr) + { + cr.first += get(edge_weight, tgr, *itr); + cr.second += get(edge_weight2, tgr, *itr); + cout << "(" << get(vertex_name, tgr, source(*itr, tgr)) << "," + << get(vertex_name, tgr, target(*itr, tgr)) << ") "; + } + BOOST_TEST(std::abs(cr.first / cr.second - min_cr) < epsilon); + cout << endl; } - BOOST_CHECK(std::abs(cr.first / cr.second - min_cr) < epsilon); - cout << endl; - } - { - GraphMInt gm(10); - typedef graph_traits::vertex_iterator VertexItM; - VertexItM vi1, vi2, vi_end; - for (boost::tie(vi1, vi_end) = vertices(gm); vi1 != vi_end; ++vi1) { - for (vi2 = vertices(gm).first; vi2 != vi_end; ++vi2) - add_edge(*vi1, *vi2, gm); + GraphMInt gm(10); + typedef graph_traits< GraphMInt >::vertex_iterator VertexItM; + VertexItM vi1, vi2, vi_end; + for (boost::tie(vi1, vi_end) = vertices(gm); vi1 != vi_end; ++vi1) + { + for (vi2 = vertices(gm).first; vi2 != vi_end; ++vi2) + add_edge(*vi1, *vi2, gm); + } + max_cr = maximum_cycle_ratio(gm, get(vertex_index, gm), + get(&CEdgeProps< int, int >::m_w1, gm), + get(&CEdgeProps< int, int >::m_w2, gm)); + BOOST_TEST(std::abs(max_cr - 0.5) < epsilon); } - max_cr = maximum_cycle_ratio(gm, get(vertex_index, gm), - get(&CEdgeProps::m_w1, gm), get(&CEdgeProps::m_w2, gm)); - BOOST_CHECK(std::abs(max_cr - 0.5) < epsilon); - } - return 0; + return boost::report_errors(); } - diff --git a/test/cycle_test.hpp b/test/cycle_test.hpp index 537044733..f68bafbf6 100644 --- a/test/cycle_test.hpp +++ b/test/cycle_test.hpp @@ -20,61 +20,66 @@ #include #include +namespace cycle_test_detail +{ +using namespace boost; -namespace cycle_test_detail { - using namespace boost; - - struct cycle_validator { - explicit cycle_validator(std::size_t& number_of_cycles) - : cycles(number_of_cycles) - { } +struct cycle_validator +{ + explicit cycle_validator(std::size_t& number_of_cycles) + : cycles(number_of_cycles) + { + } - template - void cycle(Path const& p, Graph const& g) { - ++cycles; - // Check to make sure that each of the vertices in the path - // is truly connected and that the back is connected to the - // front - it's not validating that we find all paths, just - // that the paths are valid. - typename Path::const_iterator i, j, last = prior(p.end()); - for (i = p.begin(); i != last; ++i) { - j = boost::next(i); - BOOST_ASSERT(edge(*i, *j, g).second); - } - BOOST_ASSERT(edge(p.back(), p.front(), g).second); + template < typename Path, typename Graph > + void cycle(Path const& p, Graph const& g) + { + ++cycles; + // Check to make sure that each of the vertices in the path + // is truly connected and that the back is connected to the + // front - it's not validating that we find all paths, just + // that the paths are valid. + typename Path::const_iterator i, j, last = prior(p.end()); + for (i = p.begin(); i != last; ++i) + { + j = boost::next(i); + BOOST_ASSERT(edge(*i, *j, g).second); } + BOOST_ASSERT(edge(p.back(), p.front(), g).second); + } - std::size_t& cycles; - }; + std::size_t& cycles; +}; - template - void test_one(Algorithm algorithm) { - typedef erdos_renyi_iterator er; +template < typename Graph, typename Algorithm > +void test_one(Algorithm algorithm) +{ + typedef erdos_renyi_iterator< minstd_rand, Graph > er; - // Generate random graphs with 15 vertices and 15% probability - // of edge connection. - static std::size_t const N = 20; - static double const P = 0.1; - minstd_rand rng; + // Generate random graphs with 15 vertices and 15% probability + // of edge connection. + static std::size_t const N = 20; + static double const P = 0.1; + minstd_rand rng; - Graph g(er(rng, N, P), er(), N); - renumber_indices(g); - print_edges(g, get(vertex_index, g)); + Graph g(er(rng, N, P), er(), N); + renumber_indices(g); + print_edges(g, get(vertex_index, g)); - std::size_t cycles = 0; - cycle_validator vis(cycles); - algorithm(g, vis); - std::cout << "# cycles: " << vis.cycles << "\n"; - } + std::size_t cycles = 0; + cycle_validator vis(cycles); + algorithm(g, vis); + std::cout << "# cycles: " << vis.cycles << "\n"; +} } // end namespace cycle_test_detail -template -void cycle_test(Algorithm const& algorithm) { +template < typename Algorithm > void cycle_test(Algorithm const& algorithm) +{ std::cout << "*** undirected ***\n"; - cycle_test_detail::test_one >(algorithm); + cycle_test_detail::test_one< boost::undirected_graph<> >(algorithm); std::cout << "*** directed ***\n"; - cycle_test_detail::test_one >(algorithm); + cycle_test_detail::test_one< boost::directed_graph<> >(algorithm); } #endif // !BOOST_GRAPH_TEST_CYCLE_TEST_HPP diff --git a/test/dag_longest_paths.cpp b/test/dag_longest_paths.cpp index 4b5151b32..f45f8aa4c 100644 --- a/test/dag_longest_paths.cpp +++ b/test/dag_longest_paths.cpp @@ -7,17 +7,18 @@ #include #include #include -#include +#include using namespace boost; #include using namespace std; -int test_main(int, char*[]) +int main(int, char*[]) { - typedef adjacency_list > Graph; + typedef adjacency_list< vecS, vecS, directedS, no_property, + property< edge_weight_t, int > > + Graph; Graph graph; @@ -27,7 +28,7 @@ int test_main(int, char*[]) (void)add_vertex(graph); Graph::edge_descriptor e; - + e = add_edge(0, 1, graph).first; put(edge_weight, graph, e, 1); @@ -37,20 +38,17 @@ int test_main(int, char*[]) e = add_edge(3, 1, graph).first; put(edge_weight, graph, e, 5); - vector_property_map distance; + vector_property_map< int > distance; dag_shortest_paths(graph, 0, - distance_map(distance) - .distance_compare(std::greater()) - .distance_inf((std::numeric_limits::min)()) - .distance_zero(0)); + distance_map(distance) + .distance_compare(std::greater< int >()) + .distance_inf((std::numeric_limits< int >::min)()) + .distance_zero(0)); cout << distance[2] << "\n"; - BOOST_CHECK(distance[2] == 2); + BOOST_TEST(distance[2] == 2); - return 0; + return boost::report_errors(); } - - - diff --git a/test/degree_centrality.cpp b/test/degree_centrality.cpp index 42adb5b11..6f35e105f 100644 --- a/test/degree_centrality.cpp +++ b/test/degree_centrality.cpp @@ -18,12 +18,13 @@ using namespace boost; // number of vertices in the graph static const unsigned N = 5; -template -void build_graph(Graph& g, - vector::vertex_descriptor>& v) +template < typename Graph > +void build_graph( + Graph& g, vector< typename graph_traits< Graph >::vertex_descriptor >& v) { // add vertices - for(size_t i = 0; i < N; ++i) { + for (size_t i = 0; i < N; ++i) + { v[i] = add_vertex(g); } @@ -35,17 +36,16 @@ void build_graph(Graph& g, add_edge(v[4], v[0], g); } -template -void test_undirected() +template < typename Graph > void test_undirected() { - typedef typename graph_traits::vertex_descriptor Vertex; + typedef typename graph_traits< Graph >::vertex_descriptor Vertex; - typedef exterior_vertex_property CentralityProperty; + typedef exterior_vertex_property< Graph, unsigned > CentralityProperty; typedef typename CentralityProperty::container_type CentralityContainer; typedef typename CentralityProperty::map_type CentralityMap; Graph g; - vector v(N); + vector< Vertex > v(N); build_graph(g, v); CentralityContainer cents(num_vertices(g)); @@ -59,18 +59,17 @@ void test_undirected() BOOST_ASSERT(cm[v[4]] == 2); } -template -void test_influence() +template < typename Graph > void test_influence() { - typedef typename graph_traits::vertex_descriptor Vertex; + typedef typename graph_traits< Graph >::vertex_descriptor Vertex; - typedef exterior_vertex_property CentralityProperty; + typedef exterior_vertex_property< Graph, unsigned > CentralityProperty; typedef typename CentralityProperty::container_type CentralityContainer; typedef typename CentralityProperty::map_type CentralityMap; Graph g; - vector v(N); + vector< Vertex > v(N); build_graph(g, v); CentralityContainer cents(num_vertices(g)); @@ -84,18 +83,17 @@ void test_influence() BOOST_ASSERT(cm[v[4]] == 1); } -template -void test_prestige() +template < typename Graph > void test_prestige() { - typedef typename graph_traits::vertex_descriptor Vertex; + typedef typename graph_traits< Graph >::vertex_descriptor Vertex; - typedef exterior_vertex_property CentralityProperty; + typedef exterior_vertex_property< Graph, unsigned > CentralityProperty; typedef typename CentralityProperty::container_type CentralityContainer; typedef typename CentralityProperty::map_type CentralityMap; Graph g; - vector v(N); + vector< Vertex > v(N); build_graph(g, v); CentralityContainer cents(num_vertices(g)); @@ -109,13 +107,12 @@ void test_prestige() BOOST_ASSERT(cm[v[4]] == 1); } -int -main(int, char *[]) +int main(int, char*[]) { typedef undirected_graph<> Graph; typedef directed_graph<> Digraph; - test_undirected(); - test_influence(); - test_prestige(); + test_undirected< Graph >(); + test_influence< Digraph >(); + test_prestige< Digraph >(); } diff --git a/test/delete_edge.cpp b/test/delete_edge.cpp index ebc11228c..f2ab4ee52 100644 --- a/test/delete_edge.cpp +++ b/test/delete_edge.cpp @@ -12,21 +12,22 @@ #include #include -#include +#include -int test_main(int argc, char* argv[]) +int main(int argc, char* argv[]) { typedef int Vertex; typedef int Edge; - typedef boost::adjacency_list Graph_t; + typedef boost::adjacency_list< boost::setS, // Container type for edges + boost::vecS, // Container type for vertices + boost::directedS, // Param for + // directed/undirected/bidirectional + // graph + Vertex, // Type for the vertices + Edge // Type for the edges + > + Graph_t; typedef Graph_t::edge_descriptor EdgeDesc; typedef Graph_t::vertex_descriptor VertexType; @@ -42,7 +43,7 @@ int test_main(int argc, char* argv[]) boost::tie(ed1, inserted1) = boost::add_edge(v3, v1, m_graph); - BOOST_REQUIRE(inserted1); + BOOST_TEST(inserted1); static const int EDGE_VAL = 1234; @@ -52,7 +53,7 @@ int test_main(int argc, char* argv[]) std::cout << "ed1 " << m_graph[ed1] << std::endl; - BOOST_REQUIRE(m_graph[ed1] == EDGE_VAL); + BOOST_TEST(m_graph[ed1] == EDGE_VAL); - return 0; + return boost::report_errors(); } diff --git a/test/dfs.cpp b/test/dfs.cpp index d958ba441..64d500f9a 100644 --- a/test/dfs.cpp +++ b/test/dfs.cpp @@ -8,7 +8,7 @@ //======================================================================= #include -#include +#include #include #include @@ -19,174 +19,188 @@ #include -template -class dfs_test_visitor { - typedef typename boost::property_traits::value_type ColorValue; - typedef typename boost::color_traits Color; +template < typename ColorMap, typename ParentMap, typename DiscoverTimeMap, + typename FinishTimeMap > +class dfs_test_visitor +{ + typedef typename boost::property_traits< ColorMap >::value_type ColorValue; + typedef typename boost::color_traits< ColorValue > Color; + public: - dfs_test_visitor(ColorMap color, ParentMap p, DiscoverTimeMap d, - FinishTimeMap f) - : m_color(color), m_parent(p), - m_discover_time(d), m_finish_time(f), m_time(0) { } - - template - void initialize_vertex(Vertex u, Graph&) { - BOOST_CHECK( boost::get(m_color, u) == Color::white() ); - } - template - void start_vertex(Vertex u, Graph&) { - BOOST_CHECK( boost::get(m_color, u) == Color::white() ); - } - template - void discover_vertex(Vertex u, Graph&) { - using namespace boost; - BOOST_CHECK( get(m_color, u) == Color::gray() ); - BOOST_CHECK( get(m_color, get(m_parent, u)) == Color::gray() ); - - put(m_discover_time, u, m_time++); - } - template - void examine_edge(Edge e, Graph& g) { - using namespace boost; - BOOST_CHECK( get(m_color, source(e, g)) == Color::gray() ); - } - template - void tree_edge(Edge e, Graph& g) { - using namespace boost; - BOOST_CHECK( get(m_color, target(e, g)) == Color::white() ); - - put(m_parent, target(e, g), source(e, g)); - } - template - void back_edge(Edge e, Graph& g) { - using namespace boost; - BOOST_CHECK( get(m_color, target(e, g)) == Color::gray() ); - } - template - void forward_or_cross_edge(Edge e, Graph& g) { - using namespace boost; - BOOST_CHECK( get(m_color, target(e, g)) == Color::black() ); - } - template - void finish_edge(Edge e, Graph& g) { - using namespace boost; - BOOST_CHECK( get(m_color, target(e, g)) == Color::gray() || - get(m_color, target(e, g)) == Color::black() ); - } - template - void finish_vertex(Vertex u, Graph&) { - using namespace boost; - BOOST_CHECK( get(m_color, u) == Color::black() ); - - put(m_finish_time, u, m_time++); - } + dfs_test_visitor( + ColorMap color, ParentMap p, DiscoverTimeMap d, FinishTimeMap f) + : m_color(color) + , m_parent(p) + , m_discover_time(d) + , m_finish_time(f) + , m_time(0) + { + } + + template < class Vertex, class Graph > + void initialize_vertex(Vertex u, Graph&) + { + BOOST_TEST(boost::get(m_color, u) == Color::white()); + } + template < class Vertex, class Graph > void start_vertex(Vertex u, Graph&) + { + BOOST_TEST(boost::get(m_color, u) == Color::white()); + } + template < class Vertex, class Graph > + void discover_vertex(Vertex u, Graph&) + { + using namespace boost; + BOOST_TEST(get(m_color, u) == Color::gray()); + BOOST_TEST(get(m_color, get(m_parent, u)) == Color::gray()); + + put(m_discover_time, u, m_time++); + } + template < class Edge, class Graph > void examine_edge(Edge e, Graph& g) + { + using namespace boost; + BOOST_TEST(get(m_color, source(e, g)) == Color::gray()); + } + template < class Edge, class Graph > void tree_edge(Edge e, Graph& g) + { + using namespace boost; + BOOST_TEST(get(m_color, target(e, g)) == Color::white()); + + put(m_parent, target(e, g), source(e, g)); + } + template < class Edge, class Graph > void back_edge(Edge e, Graph& g) + { + using namespace boost; + BOOST_TEST(get(m_color, target(e, g)) == Color::gray()); + } + template < class Edge, class Graph > + void forward_or_cross_edge(Edge e, Graph& g) + { + using namespace boost; + BOOST_TEST(get(m_color, target(e, g)) == Color::black()); + } + template < class Edge, class Graph > void finish_edge(Edge e, Graph& g) + { + using namespace boost; + BOOST_TEST(get(m_color, target(e, g)) == Color::gray() + || get(m_color, target(e, g)) == Color::black()); + } + template < class Vertex, class Graph > void finish_vertex(Vertex u, Graph&) + { + using namespace boost; + BOOST_TEST(get(m_color, u) == Color::black()); + + put(m_finish_time, u, m_time++); + } + private: - ColorMap m_color; - ParentMap m_parent; - DiscoverTimeMap m_discover_time; - FinishTimeMap m_finish_time; - typename boost::property_traits::value_type m_time; + ColorMap m_color; + ParentMap m_parent; + DiscoverTimeMap m_discover_time; + FinishTimeMap m_finish_time; + typename boost::property_traits< DiscoverTimeMap >::value_type m_time; }; -template -struct dfs_test +template < typename Graph > struct dfs_test { - typedef boost::graph_traits Traits; - typedef typename Traits::vertices_size_type - vertices_size_type; - - static void go(vertices_size_type max_V) { - using namespace boost; - typedef typename Traits::vertex_descriptor vertex_descriptor; - typedef typename boost::property_map::type ColorMap; - typedef typename boost::property_traits::value_type ColorValue; - typedef typename boost::color_traits Color; - - vertices_size_type i, k; - typename Traits::edges_size_type j; - typename Traits::vertex_iterator vi, vi_end, ui, ui_end; - - boost::mt19937 gen; - - for (i = 0; i < max_V; ++i) - for (j = 0; j < i*i; ++j) { - Graph g; - generate_random_graph(g, i, j, gen); - - ColorMap color = get(boost::vertex_color, g); - std::vector parent(num_vertices(g)); - for (k = 0; k < num_vertices(g); ++k) - parent[k] = k; - std::vector discover_time(num_vertices(g)), - finish_time(num_vertices(g)); - - // Get vertex index map - typedef typename boost::property_map::const_type idx_type; - idx_type idx = get(boost::vertex_index, g); - + typedef boost::graph_traits< Graph > Traits; + typedef typename Traits::vertices_size_type vertices_size_type; + + static void go(vertices_size_type max_V) + { + using namespace boost; + typedef typename Traits::vertex_descriptor vertex_descriptor; typedef - boost::iterator_property_map::iterator, idx_type> - parent_pm_type; - parent_pm_type parent_pm(parent.begin(), idx); + typename boost::property_map< Graph, boost::vertex_color_t >::type + ColorMap; typedef - boost::iterator_property_map::iterator, idx_type> - time_pm_type; - time_pm_type discover_time_pm(discover_time.begin(), idx); - time_pm_type finish_time_pm(finish_time.begin(), idx); - - dfs_test_visitor - vis(color, parent_pm, - discover_time_pm, finish_time_pm); - - boost::depth_first_search(g, visitor(vis).color_map(color)); - - // all vertices should be black - for (boost::tie(vi, vi_end) = vertices(g); vi != vi_end; ++vi) - BOOST_CHECK(get(color, *vi) == Color::black()); - - // check parenthesis structure of discover/finish times - // See CLR p.480 - for (boost::tie(ui, ui_end) = vertices(g); ui != ui_end; ++ui) - for (boost::tie(vi, vi_end) = vertices(g); vi != vi_end; ++vi) { - vertex_descriptor u = *ui, v = *vi; - if (u != v) { - BOOST_CHECK( finish_time[u] < discover_time[v] - || finish_time[v] < discover_time[u] - || (discover_time[v] < discover_time[u] - && finish_time[u] < finish_time[v] - && boost::is_descendant(u, v, parent_pm)) - || (discover_time[u] < discover_time[v] - && finish_time[v] < finish_time[u] - && boost::is_descendant(v, u, parent_pm)) - ); + typename boost::property_traits< ColorMap >::value_type ColorValue; + typedef typename boost::color_traits< ColorValue > Color; + + vertices_size_type i, k; + typename Traits::edges_size_type j; + typename Traits::vertex_iterator vi, vi_end, ui, ui_end; + + boost::mt19937 gen; + + for (i = 0; i < max_V; ++i) + for (j = 0; j < i * i; ++j) + { + Graph g; + generate_random_graph(g, i, j, gen); + + ColorMap color = get(boost::vertex_color, g); + std::vector< vertex_descriptor > parent(num_vertices(g)); + for (k = 0; k < num_vertices(g); ++k) + parent[k] = k; + std::vector< int > discover_time(num_vertices(g)), + finish_time(num_vertices(g)); + + // Get vertex index map + typedef typename boost::property_map< Graph, + boost::vertex_index_t >::const_type idx_type; + idx_type idx = get(boost::vertex_index, g); + + typedef boost::iterator_property_map< + typename std::vector< vertex_descriptor >::iterator, + idx_type > + parent_pm_type; + parent_pm_type parent_pm(parent.begin(), idx); + typedef boost::iterator_property_map< + std::vector< int >::iterator, idx_type > + time_pm_type; + time_pm_type discover_time_pm(discover_time.begin(), idx); + time_pm_type finish_time_pm(finish_time.begin(), idx); + + dfs_test_visitor< ColorMap, parent_pm_type, time_pm_type, + time_pm_type > + vis(color, parent_pm, discover_time_pm, finish_time_pm); + + boost::depth_first_search(g, visitor(vis).color_map(color)); + + // all vertices should be black + for (boost::tie(vi, vi_end) = vertices(g); vi != vi_end; ++vi) + BOOST_TEST(get(color, *vi) == Color::black()); + + // check parenthesis structure of discover/finish times + // See CLR p.480 + for (boost::tie(ui, ui_end) = vertices(g); ui != ui_end; ++ui) + for (boost::tie(vi, vi_end) = vertices(g); vi != vi_end; + ++vi) + { + vertex_descriptor u = *ui, v = *vi; + if (u != v) + { + BOOST_TEST(finish_time[u] < discover_time[v] + || finish_time[v] < discover_time[u] + || (discover_time[v] < discover_time[u] + && finish_time[u] < finish_time[v] + && boost::is_descendant(u, v, parent_pm)) + || (discover_time[u] < discover_time[v] + && finish_time[v] < finish_time[u] + && boost::is_descendant(v, u, parent_pm))); + } + } } - } - } - - } + } }; - // usage: dfs.exe [max-vertices=15] -int test_main(int argc, char* argv[]) +int main(int argc, char* argv[]) { - int max_V = 7; - if (argc > 1) - max_V = atoi(argv[1]); - - // Test directed graphs. - dfs_test< boost::adjacency_list > - >::go(max_V); - // Test undirected graphs. - dfs_test< boost::adjacency_list > - >::go(max_V); - - return 0; + int max_V = 7; + if (argc > 1) + max_V = atoi(argv[1]); + + // Test directed graphs. + dfs_test< boost::adjacency_list< boost::vecS, boost::vecS, boost::directedS, + boost::property< boost::vertex_color_t, + boost::default_color_type > > >::go(max_V); + // Test undirected graphs. + dfs_test< + boost::adjacency_list< boost::vecS, boost::vecS, boost::undirectedS, + boost::property< boost::vertex_color_t, + boost::default_color_type > > >::go(max_V); + + return boost::report_errors(); } - diff --git a/test/dfs_cc.cpp b/test/dfs_cc.cpp index b41f2f67e..6d45e8e09 100644 --- a/test/dfs_cc.cpp +++ b/test/dfs_cc.cpp @@ -13,38 +13,45 @@ int main() { - using namespace boost; - typedef default_constructible_archetype< - sgi_assignable_archetype< - equality_comparable_archetype<> > > vertex_t; - { - typedef incidence_graph_archetype IncidenceGraph; - typedef vertex_list_graph_archetype graph_t; - graph_t& g = static_object::get(); - read_write_property_map_archetype color; - depth_first_search(g, color_map(color)); - } - { - typedef incidence_graph_archetype IncidenceGraph; - typedef vertex_list_graph_archetype graph_t; - graph_t& g = static_object::get(); - readable_property_map_archetype v_index; - depth_first_search(g, vertex_index_map(v_index)); - } - { - typedef incidence_graph_archetype IncidenceGraph; - typedef vertex_list_graph_archetype Graph; - typedef property_graph_archetype - graph_t; - graph_t& g = static_object::get(); - dfs_visitor<> v; - depth_first_search(g, visitor(v)); - } - return 0; + using namespace boost; + typedef default_constructible_archetype< + sgi_assignable_archetype< equality_comparable_archetype<> > > + vertex_t; + { + typedef incidence_graph_archetype< vertex_t, directed_tag, + allow_parallel_edge_tag > + IncidenceGraph; + typedef vertex_list_graph_archetype< vertex_t, directed_tag, + allow_parallel_edge_tag, IncidenceGraph > + graph_t; + graph_t& g = static_object< graph_t >::get(); + read_write_property_map_archetype< vertex_t, color_value_archetype > + color; + depth_first_search(g, color_map(color)); + } + { + typedef incidence_graph_archetype< vertex_t, directed_tag, + allow_parallel_edge_tag > + IncidenceGraph; + typedef vertex_list_graph_archetype< vertex_t, directed_tag, + allow_parallel_edge_tag, IncidenceGraph > + graph_t; + graph_t& g = static_object< graph_t >::get(); + readable_property_map_archetype< vertex_t, std::size_t > v_index; + depth_first_search(g, vertex_index_map(v_index)); + } + { + typedef incidence_graph_archetype< vertex_t, undirected_tag, + allow_parallel_edge_tag > + IncidenceGraph; + typedef vertex_list_graph_archetype< vertex_t, undirected_tag, + allow_parallel_edge_tag, IncidenceGraph > + Graph; + typedef property_graph_archetype< Graph, vertex_index_t, std::size_t > + graph_t; + graph_t& g = static_object< graph_t >::get(); + dfs_visitor<> v; + depth_first_search(g, visitor(v)); + } + return 0; } diff --git a/test/dijkstra_cc.cpp b/test/dijkstra_cc.cpp index 89705174d..c5467a914 100644 --- a/test/dijkstra_cc.cpp +++ b/test/dijkstra_cc.cpp @@ -14,17 +14,20 @@ #include typedef boost::default_constructible_archetype< - boost::sgi_assignable_archetype<> > dist_value; + boost::sgi_assignable_archetype<> > + dist_value; // So generate_infinity works... -namespace std { - template <> - class numeric_limits { - public: - static dist_value max BOOST_PREVENT_MACRO_SUBSTITUTION () { - return boost::static_object::get(); +namespace std +{ +template <> class numeric_limits< dist_value > +{ +public: + static dist_value max BOOST_PREVENT_MACRO_SUBSTITUTION() + { + return boost::static_object< dist_value >::get(); } - }; +}; } dist_value abs(const dist_value& x) { return x; } @@ -32,105 +35,105 @@ std::size_t abs(std::size_t x) { return x; } int main() { - using namespace boost; - typedef default_constructible_archetype< - sgi_assignable_archetype< - equality_comparable_archetype<> > > vertex_t; - { - typedef incidence_graph_archetype IncidenceGraph; - typedef vertex_list_graph_archetype graph_t; - graph_t& g = static_object::get(); - vertex_t s; - typedef graph_traits::edge_descriptor edge_t; - readable_property_map_archetype weight; - readable_property_map_archetype index; - read_write_property_map_archetype distance; - dijkstra_shortest_paths(g, s, - vertex_index_map(index). - weight_map(weight). - distance_map(distance)); + using namespace boost; + typedef default_constructible_archetype< + sgi_assignable_archetype< equality_comparable_archetype<> > > + vertex_t; + { + typedef incidence_graph_archetype< vertex_t, directed_tag, + allow_parallel_edge_tag > + IncidenceGraph; + typedef vertex_list_graph_archetype< vertex_t, directed_tag, + allow_parallel_edge_tag, IncidenceGraph > + graph_t; + graph_t& g = static_object< graph_t >::get(); + vertex_t s; + typedef graph_traits< graph_t >::edge_descriptor edge_t; + readable_property_map_archetype< edge_t, std::size_t > weight; + readable_property_map_archetype< vertex_t, int > index; + read_write_property_map_archetype< vertex_t, std::size_t > distance; + dijkstra_shortest_paths(g, s, + vertex_index_map(index).weight_map(weight).distance_map(distance)); - dijkstra_shortest_paths_no_color_map(g, s, - vertex_index_map(index). - weight_map(weight). - distance_map(distance)); - } - { - typedef incidence_graph_archetype IncidenceGraph; - typedef vertex_list_graph_archetype Graph; - vertex_t s; - typedef graph_traits::edge_descriptor edge_t; - readable_property_map_archetype weight; - typedef property_graph_archetype - graph_t; - graph_t& g = static_object::get(); - read_write_property_map_archetype pred; - dijkstra_shortest_paths(g, s, - predecessor_map(pred). - weight_map(weight)); + dijkstra_shortest_paths_no_color_map(g, s, + vertex_index_map(index).weight_map(weight).distance_map(distance)); + } + { + typedef incidence_graph_archetype< vertex_t, directed_tag, + allow_parallel_edge_tag > + IncidenceGraph; + typedef vertex_list_graph_archetype< vertex_t, directed_tag, + allow_parallel_edge_tag, IncidenceGraph > + Graph; + vertex_t s; + typedef graph_traits< Graph >::edge_descriptor edge_t; + readable_property_map_archetype< edge_t, std::size_t > weight; + typedef property_graph_archetype< Graph, vertex_index_t, std::size_t > + graph_t; + graph_t& g = static_object< graph_t >::get(); + read_write_property_map_archetype< vertex_t, vertex_t > pred; + dijkstra_shortest_paths(g, s, predecessor_map(pred).weight_map(weight)); - dijkstra_shortest_paths_no_color_map(g, s, - predecessor_map(pred). - weight_map(weight)); - } - { - typedef incidence_graph_archetype IncidenceGraph; - typedef vertex_list_graph_archetype Graph; - vertex_t s; - typedef property_graph_archetype - graph_t; - graph_t& g = static_object::get(); - read_write_property_map_archetype pred; - readable_property_map_archetype index; - dijkstra_shortest_paths(g, s, - predecessor_map(pred). - vertex_index_map(index)); + dijkstra_shortest_paths_no_color_map( + g, s, predecessor_map(pred).weight_map(weight)); + } + { + typedef incidence_graph_archetype< vertex_t, directed_tag, + allow_parallel_edge_tag > + IncidenceGraph; + typedef vertex_list_graph_archetype< vertex_t, directed_tag, + allow_parallel_edge_tag, IncidenceGraph > + Graph; + vertex_t s; + typedef property_graph_archetype< Graph, edge_weight_t, std::size_t > + graph_t; + graph_t& g = static_object< graph_t >::get(); + read_write_property_map_archetype< vertex_t, vertex_t > pred; + readable_property_map_archetype< vertex_t, int > index; + dijkstra_shortest_paths( + g, s, predecessor_map(pred).vertex_index_map(index)); - dijkstra_shortest_paths_no_color_map(g, s, - predecessor_map(pred). - vertex_index_map(index)); - } - { - typedef incidence_graph_archetype IncidenceGraph; - typedef vertex_list_graph_archetype graph_t; - graph_t& g = static_object::get(); - vertex_t s; - typedef graph_traits::edge_descriptor edge_t; - readable_property_map_archetype weight; - readable_property_map_archetype index; - read_write_property_map_archetype color; - read_write_property_map_archetype distance; - typedef binary_function_archetype - Combine; - Combine combine = static_object::get(); - typedef binary_predicate_archetype - Compare; - Compare compare = static_object::get(); - dijkstra_visitor<> vis; + dijkstra_shortest_paths_no_color_map( + g, s, predecessor_map(pred).vertex_index_map(index)); + } + { + typedef incidence_graph_archetype< vertex_t, directed_tag, + allow_parallel_edge_tag > + IncidenceGraph; + typedef vertex_list_graph_archetype< vertex_t, directed_tag, + allow_parallel_edge_tag, IncidenceGraph > + graph_t; + graph_t& g = static_object< graph_t >::get(); + vertex_t s; + typedef graph_traits< graph_t >::edge_descriptor edge_t; + readable_property_map_archetype< edge_t, dist_value > weight; + readable_property_map_archetype< vertex_t, int > index; + read_write_property_map_archetype< vertex_t, color_value_archetype > + color; + read_write_property_map_archetype< vertex_t, dist_value > distance; + typedef binary_function_archetype< dist_value, dist_value, dist_value > + Combine; + Combine combine = static_object< Combine >::get(); + typedef binary_predicate_archetype< dist_value, dist_value > Compare; + Compare compare = static_object< Compare >::get(); + dijkstra_visitor<> vis; - dijkstra_shortest_paths(g, s, color_map(color). - vertex_index_map(index). - weight_map(weight). - distance_map(distance). - distance_combine(combine). - distance_compare(compare). - visitor(vis)); + dijkstra_shortest_paths(g, s, + color_map(color) + .vertex_index_map(index) + .weight_map(weight) + .distance_map(distance) + .distance_combine(combine) + .distance_compare(compare) + .visitor(vis)); - dijkstra_shortest_paths_no_color_map(g, s, - vertex_index_map(index). - weight_map(weight). - distance_map(distance). - distance_combine(combine). - distance_compare(compare). - visitor(vis)); - } - return 0; + dijkstra_shortest_paths_no_color_map(g, s, + vertex_index_map(index) + .weight_map(weight) + .distance_map(distance) + .distance_combine(combine) + .distance_compare(compare) + .visitor(vis)); + } + return 0; } diff --git a/test/dijkstra_heap_performance.cpp b/test/dijkstra_heap_performance.cpp index 8e290224b..945782158 100644 --- a/test/dijkstra_heap_performance.cpp +++ b/test/dijkstra_heap_performance.cpp @@ -7,7 +7,7 @@ // Authors: Douglas Gregor // Andrew Lumsdaine #ifndef BOOST_GRAPH_DIJKSTRA_TESTING_DIETMAR -# define BOOST_GRAPH_DIJKSTRA_TESTING +#define BOOST_GRAPH_DIJKSTRA_TESTING #endif #include @@ -16,7 +16,7 @@ #include #include #include -#include +#include #include #include @@ -35,140 +35,136 @@ using namespace boost; struct show_events_visitor : dijkstra_visitor<> { - template - void discover_vertex(Vertex v, const Graph&) - { - std::cerr << "on_discover_vertex(" << v << ")\n"; - } - - template - void examine_vertex(Vertex v, const Graph&) - { - std::cerr << "on_discover_vertex(" << v << ")\n"; - } -}; + template < typename Vertex, typename Graph > + void discover_vertex(Vertex v, const Graph&) + { + std::cerr << "on_discover_vertex(" << v << ")\n"; + } + template < typename Vertex, typename Graph > + void examine_vertex(Vertex v, const Graph&) + { + std::cerr << "on_discover_vertex(" << v << ")\n"; + } +}; -template +template < typename Graph, typename Kind > void run_test(const Graph& g, const char* name, Kind kind, - const std::vector& correct_distances) + const std::vector< double >& correct_distances) { - std::vector distances(num_vertices(g)); + std::vector< double > distances(num_vertices(g)); - std::cout << "Running Dijkstra's with " << name << "..."; - std::cout.flush(); - timer t; - dijkstra_heap_kind = kind; + std::cout << "Running Dijkstra's with " << name << "..."; + std::cout.flush(); + boost::timer::cpu_timer t; + t.start(); + dijkstra_heap_kind = kind; - dijkstra_shortest_paths(g, vertex(0, g), - distance_map(&distances[0]). - visitor(show_events_visitor())); - double run_time = t.elapsed(); - std::cout << run_time << " seconds.\n"; + dijkstra_shortest_paths(g, vertex(0, g), + distance_map(&distances[0]).visitor(show_events_visitor())); + double run_time = t.stop(); + std::cout << t.format() << " seconds.\n"; - BOOST_TEST(distances == correct_distances); + BOOST_TEST(distances == correct_distances); - if (distances != correct_distances) + if (distances != correct_distances) { - std::cout << "Expected: "; - std::copy(correct_distances.begin(), correct_distances.end(), - std::ostream_iterator(std::cout, " ")); - std::cout << "\nReceived: "; - std::copy(distances.begin(), distances.end(), - std::ostream_iterator(std::cout, " ")); - std::cout << std::endl; + std::cout << "Expected: "; + std::copy(correct_distances.begin(), correct_distances.end(), + std::ostream_iterator< double >(std::cout, " ")); + std::cout << "\nReceived: "; + std::copy(distances.begin(), distances.end(), + std::ostream_iterator< double >(std::cout, " ")); + std::cout << std::endl; } } #endif int main(int argc, char* argv[]) { - unsigned n = (argc > 1? lexical_cast(argv[1]) : 10000u); - unsigned m = (argc > 2? lexical_cast(argv[2]) : 10*n); - int seed = (argc > 3? lexical_cast(argv[3]) : 1); - - // Build random graph - typedef adjacency_list > Graph; - std::cout << "Generating graph..."; - std::cout.flush(); - minstd_rand gen(seed); - double p = double(m)/(double(n)*double(n)); - Graph g(erdos_renyi_iterator(gen, n, p), - erdos_renyi_iterator(), - n); - std::cout << n << " vertices, " << num_edges(g) << " edges.\n"; - uniform_real rand01(0.0, 1.0); - graph_traits::edge_iterator ei, ei_end; - for (boost::tie(ei, ei_end) = edges(g); ei != ei_end; ++ei) - put(edge_weight, g, *ei, rand01(gen)); - - std::vector binary_heap_distances(n); - std::vector relaxed_heap_distances(n); - std::vector no_color_map_distances(n); - - // Run binary or d-ary heap version - std::cout << "Running Dijkstra's with binary heap..."; - std::cout.flush(); - timer t; - - dijkstra_shortest_paths(g, vertex(0, g), - distance_map( - boost::make_iterator_property_map( - binary_heap_distances.begin(), get(boost::vertex_index, g)))); - double binary_heap_time = t.elapsed(); - std::cout << binary_heap_time << " seconds.\n"; - - - std::cout << "Running Dijkstra's with d-ary heap (d=4)..."; - std::cout.flush(); - t.restart(); - - dijkstra_shortest_paths(g, vertex(0, g), - distance_map( - boost::make_iterator_property_map( - relaxed_heap_distances.begin(), get(boost::vertex_index, g)))); - double relaxed_heap_time = t.elapsed(); - std::cout << relaxed_heap_time << " seconds.\n" - << "Speedup = " << (binary_heap_time / relaxed_heap_time) << ".\n"; - - // Verify that the results are equivalent - BOOST_TEST(binary_heap_distances == relaxed_heap_distances); - - // Run Michael's no-color-map version - - std::cout << "Running Dijkstra's (no color map) with d-ary heap (d=4)..."; - std::cout.flush(); - t.restart(); - - dijkstra_shortest_paths_no_color_map - (g, vertex(0, g), - boost::dummy_property_map(), - boost::make_iterator_property_map(no_color_map_distances.begin(), - get(boost::vertex_index, g), - 0.), - get(boost::edge_weight, g), - get(boost::vertex_index, g), - std::less(), - boost::closed_plus(), - (std::numeric_limits::max)(), - 0, - make_dijkstra_visitor(null_visitor()) - ); - double no_color_map_time = t.elapsed(); - std::cout << no_color_map_time << " seconds.\n" - << "Speedup = " << (binary_heap_time / no_color_map_time) << ".\n"; - - // Verify that the results are equivalent - BOOST_TEST(binary_heap_distances == no_color_map_distances); + unsigned n = (argc > 1 ? lexical_cast< unsigned >(argv[1]) : 10000u); + unsigned m = (argc > 2 ? lexical_cast< unsigned >(argv[2]) : 10 * n); + int seed = (argc > 3 ? lexical_cast< int >(argv[3]) : 1); + + // Build random graph + typedef adjacency_list< vecS, vecS, directedS, no_property, + property< edge_weight_t, double > > + Graph; + std::cout << "Generating graph..."; + std::cout.flush(); + minstd_rand gen(seed); + double p = double(m) / (double(n) * double(n)); + Graph g(erdos_renyi_iterator< minstd_rand, Graph >(gen, n, p), + erdos_renyi_iterator< minstd_rand, Graph >(), n); + std::cout << n << " vertices, " << num_edges(g) << " edges.\n"; + uniform_real< double > rand01(0.0, 1.0); + graph_traits< Graph >::edge_iterator ei, ei_end; + for (boost::tie(ei, ei_end) = edges(g); ei != ei_end; ++ei) + put(edge_weight, g, *ei, rand01(gen)); + + std::vector< double > binary_heap_distances(n); + std::vector< double > relaxed_heap_distances(n); + std::vector< double > no_color_map_distances(n); + + // Run binary or d-ary heap version + std::cout << "Running Dijkstra's with binary heap..."; + std::cout.flush(); + boost::timer::cpu_timer t; + t.start(); + + dijkstra_shortest_paths(g, vertex(0, g), + distance_map(boost::make_iterator_property_map( + binary_heap_distances.begin(), get(boost::vertex_index, g)))); + t.stop(); + boost::timer::cpu_times binary_heap_time = t.elapsed(); + std::cout << boost::timer::format(binary_heap_time) << " seconds.\n"; + + std::cout << "Running Dijkstra's with d-ary heap (d=4)..."; + std::cout.flush(); + t.start(); + + dijkstra_shortest_paths(g, vertex(0, g), + distance_map(boost::make_iterator_property_map( + relaxed_heap_distances.begin(), get(boost::vertex_index, g)))); + boost::timer::cpu_times relaxed_heap_time = t.elapsed(); + std::cout << boost::timer::format(relaxed_heap_time) << " seconds.\n" + << "Speedup = " + << (binary_heap_time.user / relaxed_heap_time.user) << ".\n"; + + // Verify that the results are equivalent + BOOST_TEST(binary_heap_distances == relaxed_heap_distances); + + // Run Michael's no-color-map version + + std::cout << "Running Dijkstra's (no color map) with d-ary heap (d=4)..."; + std::cout.flush(); + + t.start(); + dijkstra_shortest_paths_no_color_map(g, vertex(0, g), + boost::dummy_property_map(), + boost::make_iterator_property_map( + no_color_map_distances.begin(), get(boost::vertex_index, g), 0.), + get(boost::edge_weight, g), get(boost::vertex_index, g), + std::less< double >(), boost::closed_plus< double >(), + (std::numeric_limits< double >::max)(), 0, + make_dijkstra_visitor(null_visitor())); + boost::timer::cpu_times no_color_map_time = t.elapsed(); + std::cout << boost::timer::format(no_color_map_time) << " seconds.\n" + << "Speedup = " + << (binary_heap_time.user / no_color_map_time.user) << ".\n"; + + // Verify that the results are equivalent + BOOST_TEST(binary_heap_distances == no_color_map_distances); #ifdef BOOST_GRAPH_DIJKSTRA_TESTING_DIETMAR - run_test(g, "d-ary heap (d=2)", dijkstra_d_heap_2, binary_heap_distances); - run_test(g, "d-ary heap (d=3)", dijkstra_d_heap_3, binary_heap_distances); - run_test(g, "Fibonacci heap", dijkstra_fibonacci_heap, binary_heap_distances); - run_test(g, "Lazy Fibonacci heap", dijkstra_lazy_fibonacci_heap, binary_heap_distances); - run_test(g, "Pairing heap", dijkstra_pairing_heap, binary_heap_distances); - run_test(g, "Splay heap", dijkstra_splay_heap, binary_heap_distances); + run_test(g, "d-ary heap (d=2)", dijkstra_d_heap_2, binary_heap_distances); + run_test(g, "d-ary heap (d=3)", dijkstra_d_heap_3, binary_heap_distances); + run_test( + g, "Fibonacci heap", dijkstra_fibonacci_heap, binary_heap_distances); + run_test(g, "Lazy Fibonacci heap", dijkstra_lazy_fibonacci_heap, + binary_heap_distances); + run_test(g, "Pairing heap", dijkstra_pairing_heap, binary_heap_distances); + run_test(g, "Splay heap", dijkstra_splay_heap, binary_heap_distances); #endif - return boost::report_errors(); + return boost::report_errors(); } diff --git a/test/dijkstra_no_color_map_compare.cpp b/test/dijkstra_no_color_map_compare.cpp index 89a4bcc70..e4709a39b 100644 --- a/test/dijkstra_no_color_map_compare.cpp +++ b/test/dijkstra_no_color_map_compare.cpp @@ -14,7 +14,7 @@ #ifdef BOOST_MSVC // Without disabling this we get hard errors about initialialized pointers: -#pragma warning(disable:4703) +#pragma warning(disable : 4703) #endif #include @@ -24,7 +24,7 @@ #include #include #include -#include +#include #include #define INITIALIZE_VERTEX 0 @@ -35,92 +35,97 @@ #define EDGE_NOT_RELAXED 5 #define FINISH_VERTEX 6 - -template -void run_dijkstra_test(const Graph& graph) +template < typename Graph > void run_dijkstra_test(const Graph& graph) { - using namespace boost; - - // Set up property maps - typedef typename graph_traits::vertex_descriptor vertex_t; - - typedef typename std::map vertex_map_t; - typedef associative_property_map predecessor_map_t; - vertex_map_t default_vertex_map, no_color_map_vertex_map; - predecessor_map_t default_predecessor_map(default_vertex_map), - no_color_map_predecessor_map(no_color_map_vertex_map); - - typedef typename std::map vertex_double_map_t; - typedef associative_property_map distance_map_t; - vertex_double_map_t default_vertex_double_map, no_color_map_vertex_double_map; - distance_map_t default_distance_map(default_vertex_double_map), - no_color_map_distance_map(no_color_map_vertex_double_map); - - // Run dijkstra algoirthms - dijkstra_shortest_paths(graph, vertex(0, graph), - predecessor_map(default_predecessor_map) - .distance_map(default_distance_map)); - - dijkstra_shortest_paths_no_color_map(graph, vertex(0, graph), - predecessor_map(no_color_map_predecessor_map) - .distance_map(no_color_map_distance_map)); - - // Verify that predecessor maps are equal - BOOST_CHECK(std::equal(default_vertex_map.begin(), default_vertex_map.end(), - no_color_map_vertex_map.begin())); - - // Verify that distance maps are equal - BOOST_CHECK(std::equal(default_vertex_double_map.begin(), default_vertex_double_map.end(), - no_color_map_vertex_double_map.begin())); + using namespace boost; + + // Set up property maps + typedef typename graph_traits< Graph >::vertex_descriptor vertex_t; + + typedef typename std::map< vertex_t, vertex_t > vertex_map_t; + typedef associative_property_map< vertex_map_t > predecessor_map_t; + vertex_map_t default_vertex_map, no_color_map_vertex_map; + predecessor_map_t default_predecessor_map(default_vertex_map), + no_color_map_predecessor_map(no_color_map_vertex_map); + + typedef typename std::map< vertex_t, double > vertex_double_map_t; + typedef associative_property_map< vertex_double_map_t > distance_map_t; + vertex_double_map_t default_vertex_double_map, + no_color_map_vertex_double_map; + distance_map_t default_distance_map(default_vertex_double_map), + no_color_map_distance_map(no_color_map_vertex_double_map); + + // Run dijkstra algoirthms + dijkstra_shortest_paths(graph, vertex(0, graph), + predecessor_map(default_predecessor_map) + .distance_map(default_distance_map)); + + dijkstra_shortest_paths_no_color_map(graph, vertex(0, graph), + predecessor_map(no_color_map_predecessor_map) + .distance_map(no_color_map_distance_map)); + + // Verify that predecessor maps are equal + BOOST_TEST(std::equal(default_vertex_map.begin(), default_vertex_map.end(), + no_color_map_vertex_map.begin())); + + // Verify that distance maps are equal + BOOST_TEST(std::equal(default_vertex_double_map.begin(), + default_vertex_double_map.end(), + no_color_map_vertex_double_map.begin())); } -int test_main(int argc, char* argv[]) +int main(int argc, char* argv[]) { - using namespace boost; - - int vertices_to_create = 10; - int edges_to_create = 500; - std::size_t random_seed = time(0); - - if (argc > 1) { - vertices_to_create = lexical_cast(argv[1]); - } - - if (argc > 2) { - edges_to_create = lexical_cast(argv[2]); - } - - if (argc > 3) { - random_seed = lexical_cast(argv[3]); - } - - minstd_rand generator(random_seed); - - // Set up graph - typedef adjacency_list, - property > graph_t; - - graph_t graph; - generate_random_graph(graph, vertices_to_create, edges_to_create, generator); - - // Set up property maps - typedef property_map::type index_map_t; - index_map_t index_map = get(vertex_index, graph); - int vertex_index = 0; - - BGL_FORALL_VERTICES(current_vertex, graph, graph_t) { - put(index_map, current_vertex, vertex_index++); - } - - randomize_property(graph, generator); - - // Run comparison test with original dijkstra_shortest_paths - std::cout << "Running dijkstra shortest paths test with " << num_vertices(graph) << - " vertices and " << num_edges(graph) << " edges " << std::endl; - - run_dijkstra_test(graph); - - return 0; -} + using namespace boost; + + int vertices_to_create = 10; + int edges_to_create = 500; + std::size_t random_seed = time(0); + + if (argc > 1) + { + vertices_to_create = lexical_cast< int >(argv[1]); + } + + if (argc > 2) + { + edges_to_create = lexical_cast< int >(argv[2]); + } + + if (argc > 3) + { + random_seed = lexical_cast< std::size_t >(argv[3]); + } + + minstd_rand generator(random_seed); + + // Set up graph + typedef adjacency_list< listS, listS, directedS, + property< vertex_index_t, int >, property< edge_weight_t, double > > + graph_t; + graph_t graph; + generate_random_graph( + graph, vertices_to_create, edges_to_create, generator); + + // Set up property maps + typedef property_map< graph_t, vertex_index_t >::type index_map_t; + index_map_t index_map = get(vertex_index, graph); + int vertex_index = 0; + + BGL_FORALL_VERTICES(current_vertex, graph, graph_t) + { + put(index_map, current_vertex, vertex_index++); + } + + randomize_property< edge_weight_t >(graph, generator); + + // Run comparison test with original dijkstra_shortest_paths + std::cout << "Running dijkstra shortest paths test with " + << num_vertices(graph) << " vertices and " << num_edges(graph) + << " edges " << std::endl; + + run_dijkstra_test(graph); + + return boost::report_errors(); +} diff --git a/test/dimacs.cpp b/test/dimacs.cpp index 7cad5ec07..56fd0a4b4 100644 --- a/test/dimacs.cpp +++ b/test/dimacs.cpp @@ -10,7 +10,4 @@ // This is obviously just a stub test. It's currently only used as a compile // check to make sure that the includes are appropriate. -int main() -{ - return 0; -} +int main() { return 0; } diff --git a/test/disjoint_set_test.cpp b/test/disjoint_set_test.cpp index cd588396d..929de7010 100644 --- a/test/disjoint_set_test.cpp +++ b/test/disjoint_set_test.cpp @@ -4,73 +4,71 @@ // http://www.boost.org/LICENSE_1_0.txt) #include -#include +#include #include -template -struct test_disjoint_set { - static void do_test() - { - // The following tests are pretty lame, just a basic sanity check. - // Industrial strength tests still need to be written. - +template < typename DisjointSet > struct test_disjoint_set +{ + static void do_test() + { + // The following tests are pretty lame, just a basic sanity check. + // Industrial strength tests still need to be written. + #if !defined(__MWERKS__) || __MWERKS__ > 0x3003 - std::size_t elts[] + std::size_t elts[] #else - std::size_t elts[4] -#endif - = { 0, 1, 2, 3 }; - - const int N = sizeof(elts)/sizeof(*elts); - - DisjointSet ds(N); + std::size_t elts[4] +#endif + = { 0, 1, 2, 3 }; + + const int N = sizeof(elts) / sizeof(*elts); - ds.make_set(elts[0]); - ds.make_set(elts[1]); - ds.make_set(elts[2]); - ds.make_set(elts[3]); + DisjointSet ds(N); - BOOST_CHECK(ds.find_set(0) != ds.find_set(1)); - BOOST_CHECK(ds.find_set(0) != ds.find_set(2)); - BOOST_CHECK(ds.find_set(0) != ds.find_set(3)); - BOOST_CHECK(ds.find_set(1) != ds.find_set(2)); - BOOST_CHECK(ds.find_set(1) != ds.find_set(3)); - BOOST_CHECK(ds.find_set(2) != ds.find_set(3)); + ds.make_set(elts[0]); + ds.make_set(elts[1]); + ds.make_set(elts[2]); + ds.make_set(elts[3]); + BOOST_TEST(ds.find_set(0) != ds.find_set(1)); + BOOST_TEST(ds.find_set(0) != ds.find_set(2)); + BOOST_TEST(ds.find_set(0) != ds.find_set(3)); + BOOST_TEST(ds.find_set(1) != ds.find_set(2)); + BOOST_TEST(ds.find_set(1) != ds.find_set(3)); + BOOST_TEST(ds.find_set(2) != ds.find_set(3)); - ds.union_set(0, 1); - ds.union_set(2, 3); - BOOST_CHECK(ds.find_set(0) != ds.find_set(3)); - int a = ds.find_set(0); - BOOST_CHECK(a == ds.find_set(1)); - int b = ds.find_set(2); - BOOST_CHECK(b == ds.find_set(3)); + ds.union_set(0, 1); + ds.union_set(2, 3); + BOOST_TEST(ds.find_set(0) != ds.find_set(3)); + int a = ds.find_set(0); + BOOST_TEST(a == ds.find_set(1)); + int b = ds.find_set(2); + BOOST_TEST(b == ds.find_set(3)); - ds.link(a, b); - BOOST_CHECK(ds.find_set(a) == ds.find_set(b)); - BOOST_CHECK(1 == ds.count_sets(elts, elts + N)); + ds.link(a, b); + BOOST_TEST(ds.find_set(a) == ds.find_set(b)); + BOOST_TEST(1 == ds.count_sets(elts, elts + N)); - ds.normalize_sets(elts, elts + N); - ds.compress_sets(elts, elts + N); - BOOST_CHECK(1 == ds.count_sets(elts, elts + N)); - } + ds.normalize_sets(elts, elts + N); + ds.compress_sets(elts, elts + N); + BOOST_TEST(1 == ds.count_sets(elts, elts + N)); + } }; -int -test_main(int, char*[]) +int main(int, char*[]) { - using namespace boost; - { - typedef - disjoint_sets_with_storage ds_type; - test_disjoint_set::do_test(); - } - { - typedef - disjoint_sets_with_storage ds_type; - test_disjoint_set::do_test(); - } - return boost::exit_success; + using namespace boost; + { + typedef disjoint_sets_with_storage< identity_property_map, + identity_property_map, find_with_path_halving > + ds_type; + test_disjoint_set< ds_type >::do_test(); + } + { + typedef disjoint_sets_with_storage< identity_property_map, + identity_property_map, find_with_full_path_compression > + ds_type; + test_disjoint_set< ds_type >::do_test(); + } + return boost::report_errors(); } diff --git a/test/dominator_tree_test.cpp b/test/dominator_tree_test.cpp index b10538e6c..86835cf0f 100644 --- a/test/dominator_tree_test.cpp +++ b/test/dominator_tree_test.cpp @@ -5,7 +5,7 @@ // accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) //======================================================================= -#include +#include #include #include #include @@ -15,283 +15,274 @@ using namespace std; struct DominatorCorrectnessTestSet { - typedef pair edge; + typedef pair< int, int > edge; - int numOfVertices; - vector edges; - vector correctIdoms; + int numOfVertices; + vector< edge > edges; + vector< int > correctIdoms; }; using namespace boost; -typedef adjacency_list< - listS, - listS, - bidirectionalS, - property, no_property> G; +typedef adjacency_list< listS, listS, bidirectionalS, + property< vertex_index_t, std::size_t >, no_property > + G; -int test_main(int, char*[]) +int main(int, char*[]) { - typedef DominatorCorrectnessTestSet::edge edge; + typedef DominatorCorrectnessTestSet::edge edge; - DominatorCorrectnessTestSet testSet[7]; + DominatorCorrectnessTestSet testSet[7]; - // Tarjan's paper - testSet[0].numOfVertices = 13; - testSet[0].edges.push_back(edge(0, 1)); - testSet[0].edges.push_back(edge(0, 2)); - testSet[0].edges.push_back(edge(0, 3)); - testSet[0].edges.push_back(edge(1, 4)); - testSet[0].edges.push_back(edge(2, 1)); - testSet[0].edges.push_back(edge(2, 4)); - testSet[0].edges.push_back(edge(2, 5)); - testSet[0].edges.push_back(edge(3, 6)); - testSet[0].edges.push_back(edge(3, 7)); - testSet[0].edges.push_back(edge(4, 12)); - testSet[0].edges.push_back(edge(5, 8)); - testSet[0].edges.push_back(edge(6, 9)); - testSet[0].edges.push_back(edge(7, 9)); - testSet[0].edges.push_back(edge(7, 10)); - testSet[0].edges.push_back(edge(8, 5)); - testSet[0].edges.push_back(edge(8, 11)); - testSet[0].edges.push_back(edge(9, 11)); - testSet[0].edges.push_back(edge(10, 9)); - testSet[0].edges.push_back(edge(11, 0)); - testSet[0].edges.push_back(edge(11, 9)); - testSet[0].edges.push_back(edge(12, 8)); - testSet[0].correctIdoms.push_back((numeric_limits::max)()); - testSet[0].correctIdoms.push_back(0); - testSet[0].correctIdoms.push_back(0); - testSet[0].correctIdoms.push_back(0); - testSet[0].correctIdoms.push_back(0); - testSet[0].correctIdoms.push_back(0); - testSet[0].correctIdoms.push_back(3); - testSet[0].correctIdoms.push_back(3); - testSet[0].correctIdoms.push_back(0); - testSet[0].correctIdoms.push_back(0); - testSet[0].correctIdoms.push_back(7); - testSet[0].correctIdoms.push_back(0); - testSet[0].correctIdoms.push_back(4); + // Tarjan's paper + testSet[0].numOfVertices = 13; + testSet[0].edges.push_back(edge(0, 1)); + testSet[0].edges.push_back(edge(0, 2)); + testSet[0].edges.push_back(edge(0, 3)); + testSet[0].edges.push_back(edge(1, 4)); + testSet[0].edges.push_back(edge(2, 1)); + testSet[0].edges.push_back(edge(2, 4)); + testSet[0].edges.push_back(edge(2, 5)); + testSet[0].edges.push_back(edge(3, 6)); + testSet[0].edges.push_back(edge(3, 7)); + testSet[0].edges.push_back(edge(4, 12)); + testSet[0].edges.push_back(edge(5, 8)); + testSet[0].edges.push_back(edge(6, 9)); + testSet[0].edges.push_back(edge(7, 9)); + testSet[0].edges.push_back(edge(7, 10)); + testSet[0].edges.push_back(edge(8, 5)); + testSet[0].edges.push_back(edge(8, 11)); + testSet[0].edges.push_back(edge(9, 11)); + testSet[0].edges.push_back(edge(10, 9)); + testSet[0].edges.push_back(edge(11, 0)); + testSet[0].edges.push_back(edge(11, 9)); + testSet[0].edges.push_back(edge(12, 8)); + testSet[0].correctIdoms.push_back((numeric_limits< int >::max)()); + testSet[0].correctIdoms.push_back(0); + testSet[0].correctIdoms.push_back(0); + testSet[0].correctIdoms.push_back(0); + testSet[0].correctIdoms.push_back(0); + testSet[0].correctIdoms.push_back(0); + testSet[0].correctIdoms.push_back(3); + testSet[0].correctIdoms.push_back(3); + testSet[0].correctIdoms.push_back(0); + testSet[0].correctIdoms.push_back(0); + testSet[0].correctIdoms.push_back(7); + testSet[0].correctIdoms.push_back(0); + testSet[0].correctIdoms.push_back(4); - // Appel. p441. figure 19.4 - testSet[1].numOfVertices = 7; - testSet[1].edges.push_back(edge(0, 1)); - testSet[1].edges.push_back(edge(1, 2)); - testSet[1].edges.push_back(edge(1, 3)); - testSet[1].edges.push_back(edge(2, 4)); - testSet[1].edges.push_back(edge(2, 5)); - testSet[1].edges.push_back(edge(4, 6)); - testSet[1].edges.push_back(edge(5, 6)); - testSet[1].edges.push_back(edge(6, 1)); - testSet[1].correctIdoms.push_back((numeric_limits::max)()); - testSet[1].correctIdoms.push_back(0); - testSet[1].correctIdoms.push_back(1); - testSet[1].correctIdoms.push_back(1); - testSet[1].correctIdoms.push_back(2); - testSet[1].correctIdoms.push_back(2); - testSet[1].correctIdoms.push_back(2); + // Appel. p441. figure 19.4 + testSet[1].numOfVertices = 7; + testSet[1].edges.push_back(edge(0, 1)); + testSet[1].edges.push_back(edge(1, 2)); + testSet[1].edges.push_back(edge(1, 3)); + testSet[1].edges.push_back(edge(2, 4)); + testSet[1].edges.push_back(edge(2, 5)); + testSet[1].edges.push_back(edge(4, 6)); + testSet[1].edges.push_back(edge(5, 6)); + testSet[1].edges.push_back(edge(6, 1)); + testSet[1].correctIdoms.push_back((numeric_limits< int >::max)()); + testSet[1].correctIdoms.push_back(0); + testSet[1].correctIdoms.push_back(1); + testSet[1].correctIdoms.push_back(1); + testSet[1].correctIdoms.push_back(2); + testSet[1].correctIdoms.push_back(2); + testSet[1].correctIdoms.push_back(2); - // Appel. p449. figure 19.8 - testSet[2].numOfVertices = 13, - testSet[2].edges.push_back(edge(0, 1)); - testSet[2].edges.push_back(edge(0, 2)); - testSet[2].edges.push_back(edge(1, 3)); - testSet[2].edges.push_back(edge(1, 6)); - testSet[2].edges.push_back(edge(2, 4)); - testSet[2].edges.push_back(edge(2, 7)); - testSet[2].edges.push_back(edge(3, 5)); - testSet[2].edges.push_back(edge(3, 6)); - testSet[2].edges.push_back(edge(4, 7)); - testSet[2].edges.push_back(edge(4, 2)); - testSet[2].edges.push_back(edge(5, 8)); - testSet[2].edges.push_back(edge(5, 10)); - testSet[2].edges.push_back(edge(6, 9)); - testSet[2].edges.push_back(edge(7, 12)); - testSet[2].edges.push_back(edge(8, 11)); - testSet[2].edges.push_back(edge(9, 8)); - testSet[2].edges.push_back(edge(10, 11)); - testSet[2].edges.push_back(edge(11, 1)); - testSet[2].edges.push_back(edge(11, 12)); - testSet[2].correctIdoms.push_back((numeric_limits::max)()); - testSet[2].correctIdoms.push_back(0); - testSet[2].correctIdoms.push_back(0); - testSet[2].correctIdoms.push_back(1); - testSet[2].correctIdoms.push_back(2); - testSet[2].correctIdoms.push_back(3); - testSet[2].correctIdoms.push_back(1); - testSet[2].correctIdoms.push_back(2); - testSet[2].correctIdoms.push_back(1); - testSet[2].correctIdoms.push_back(6); - testSet[2].correctIdoms.push_back(5); - testSet[2].correctIdoms.push_back(1); - testSet[2].correctIdoms.push_back(0); + // Appel. p449. figure 19.8 + testSet[2].numOfVertices = 13, testSet[2].edges.push_back(edge(0, 1)); + testSet[2].edges.push_back(edge(0, 2)); + testSet[2].edges.push_back(edge(1, 3)); + testSet[2].edges.push_back(edge(1, 6)); + testSet[2].edges.push_back(edge(2, 4)); + testSet[2].edges.push_back(edge(2, 7)); + testSet[2].edges.push_back(edge(3, 5)); + testSet[2].edges.push_back(edge(3, 6)); + testSet[2].edges.push_back(edge(4, 7)); + testSet[2].edges.push_back(edge(4, 2)); + testSet[2].edges.push_back(edge(5, 8)); + testSet[2].edges.push_back(edge(5, 10)); + testSet[2].edges.push_back(edge(6, 9)); + testSet[2].edges.push_back(edge(7, 12)); + testSet[2].edges.push_back(edge(8, 11)); + testSet[2].edges.push_back(edge(9, 8)); + testSet[2].edges.push_back(edge(10, 11)); + testSet[2].edges.push_back(edge(11, 1)); + testSet[2].edges.push_back(edge(11, 12)); + testSet[2].correctIdoms.push_back((numeric_limits< int >::max)()); + testSet[2].correctIdoms.push_back(0); + testSet[2].correctIdoms.push_back(0); + testSet[2].correctIdoms.push_back(1); + testSet[2].correctIdoms.push_back(2); + testSet[2].correctIdoms.push_back(3); + testSet[2].correctIdoms.push_back(1); + testSet[2].correctIdoms.push_back(2); + testSet[2].correctIdoms.push_back(1); + testSet[2].correctIdoms.push_back(6); + testSet[2].correctIdoms.push_back(5); + testSet[2].correctIdoms.push_back(1); + testSet[2].correctIdoms.push_back(0); - testSet[3].numOfVertices = 8, - testSet[3].edges.push_back(edge(0, 1)); - testSet[3].edges.push_back(edge(1, 2)); - testSet[3].edges.push_back(edge(1, 3)); - testSet[3].edges.push_back(edge(2, 7)); - testSet[3].edges.push_back(edge(3, 4)); - testSet[3].edges.push_back(edge(4, 5)); - testSet[3].edges.push_back(edge(4, 6)); - testSet[3].edges.push_back(edge(5, 7)); - testSet[3].edges.push_back(edge(6, 4)); - testSet[3].correctIdoms.push_back((numeric_limits::max)()); - testSet[3].correctIdoms.push_back(0); - testSet[3].correctIdoms.push_back(1); - testSet[3].correctIdoms.push_back(1); - testSet[3].correctIdoms.push_back(3); - testSet[3].correctIdoms.push_back(4); - testSet[3].correctIdoms.push_back(4); - testSet[3].correctIdoms.push_back(1); - - // Muchnick. p256. figure 8.21 - testSet[4].numOfVertices = 8, - testSet[4].edges.push_back(edge(0, 1)); - testSet[4].edges.push_back(edge(1, 2)); - testSet[4].edges.push_back(edge(2, 3)); - testSet[4].edges.push_back(edge(2, 4)); - testSet[4].edges.push_back(edge(3, 2)); - testSet[4].edges.push_back(edge(4, 5)); - testSet[4].edges.push_back(edge(4, 6)); - testSet[4].edges.push_back(edge(5, 7)); - testSet[4].edges.push_back(edge(6, 7)); - testSet[4].correctIdoms.push_back((numeric_limits::max)()); - testSet[4].correctIdoms.push_back(0); - testSet[4].correctIdoms.push_back(1); - testSet[4].correctIdoms.push_back(2); - testSet[4].correctIdoms.push_back(2); - testSet[4].correctIdoms.push_back(4); - testSet[4].correctIdoms.push_back(4); - testSet[4].correctIdoms.push_back(4); + testSet[3].numOfVertices = 8, testSet[3].edges.push_back(edge(0, 1)); + testSet[3].edges.push_back(edge(1, 2)); + testSet[3].edges.push_back(edge(1, 3)); + testSet[3].edges.push_back(edge(2, 7)); + testSet[3].edges.push_back(edge(3, 4)); + testSet[3].edges.push_back(edge(4, 5)); + testSet[3].edges.push_back(edge(4, 6)); + testSet[3].edges.push_back(edge(5, 7)); + testSet[3].edges.push_back(edge(6, 4)); + testSet[3].correctIdoms.push_back((numeric_limits< int >::max)()); + testSet[3].correctIdoms.push_back(0); + testSet[3].correctIdoms.push_back(1); + testSet[3].correctIdoms.push_back(1); + testSet[3].correctIdoms.push_back(3); + testSet[3].correctIdoms.push_back(4); + testSet[3].correctIdoms.push_back(4); + testSet[3].correctIdoms.push_back(1); - // Muchnick. p253. figure 8.18 - testSet[5].numOfVertices = 8, - testSet[5].edges.push_back(edge(0, 1)); - testSet[5].edges.push_back(edge(0, 2)); - testSet[5].edges.push_back(edge(1, 6)); - testSet[5].edges.push_back(edge(2, 3)); - testSet[5].edges.push_back(edge(2, 4)); - testSet[5].edges.push_back(edge(3, 7)); - testSet[5].edges.push_back(edge(5, 7)); - testSet[5].edges.push_back(edge(6, 7)); - testSet[5].correctIdoms.push_back((numeric_limits::max)()); - testSet[5].correctIdoms.push_back(0); - testSet[5].correctIdoms.push_back(0); - testSet[5].correctIdoms.push_back(2); - testSet[5].correctIdoms.push_back(2); - testSet[5].correctIdoms.push_back((numeric_limits::max)()); - testSet[5].correctIdoms.push_back(1); - testSet[5].correctIdoms.push_back(0); + // Muchnick. p256. figure 8.21 + testSet[4].numOfVertices = 8, testSet[4].edges.push_back(edge(0, 1)); + testSet[4].edges.push_back(edge(1, 2)); + testSet[4].edges.push_back(edge(2, 3)); + testSet[4].edges.push_back(edge(2, 4)); + testSet[4].edges.push_back(edge(3, 2)); + testSet[4].edges.push_back(edge(4, 5)); + testSet[4].edges.push_back(edge(4, 6)); + testSet[4].edges.push_back(edge(5, 7)); + testSet[4].edges.push_back(edge(6, 7)); + testSet[4].correctIdoms.push_back((numeric_limits< int >::max)()); + testSet[4].correctIdoms.push_back(0); + testSet[4].correctIdoms.push_back(1); + testSet[4].correctIdoms.push_back(2); + testSet[4].correctIdoms.push_back(2); + testSet[4].correctIdoms.push_back(4); + testSet[4].correctIdoms.push_back(4); + testSet[4].correctIdoms.push_back(4); - // Cytron's paper, fig. 9 - testSet[6].numOfVertices = 14, - testSet[6].edges.push_back(edge(0, 1)); - testSet[6].edges.push_back(edge(0, 13)); - testSet[6].edges.push_back(edge(1, 2)); - testSet[6].edges.push_back(edge(2, 3)); - testSet[6].edges.push_back(edge(2, 7)); - testSet[6].edges.push_back(edge(3, 4)); - testSet[6].edges.push_back(edge(3, 5)); - testSet[6].edges.push_back(edge(4, 6)); - testSet[6].edges.push_back(edge(5, 6)); - testSet[6].edges.push_back(edge(6, 8)); - testSet[6].edges.push_back(edge(7, 8)); - testSet[6].edges.push_back(edge(8, 9)); - testSet[6].edges.push_back(edge(9, 10)); - testSet[6].edges.push_back(edge(9, 11)); - testSet[6].edges.push_back(edge(10, 11)); - testSet[6].edges.push_back(edge(11, 9)); - testSet[6].edges.push_back(edge(11, 12)); - testSet[6].edges.push_back(edge(12, 2)); - testSet[6].edges.push_back(edge(12, 13)); - testSet[6].correctIdoms.push_back((numeric_limits::max)()); - testSet[6].correctIdoms.push_back(0); - testSet[6].correctIdoms.push_back(1); - testSet[6].correctIdoms.push_back(2); - testSet[6].correctIdoms.push_back(3); - testSet[6].correctIdoms.push_back(3); - testSet[6].correctIdoms.push_back(3); - testSet[6].correctIdoms.push_back(2); - testSet[6].correctIdoms.push_back(2); - testSet[6].correctIdoms.push_back(8); - testSet[6].correctIdoms.push_back(9); - testSet[6].correctIdoms.push_back(9); - testSet[6].correctIdoms.push_back(11); - testSet[6].correctIdoms.push_back(0); + // Muchnick. p253. figure 8.18 + testSet[5].numOfVertices = 8, testSet[5].edges.push_back(edge(0, 1)); + testSet[5].edges.push_back(edge(0, 2)); + testSet[5].edges.push_back(edge(1, 6)); + testSet[5].edges.push_back(edge(2, 3)); + testSet[5].edges.push_back(edge(2, 4)); + testSet[5].edges.push_back(edge(3, 7)); + testSet[5].edges.push_back(edge(5, 7)); + testSet[5].edges.push_back(edge(6, 7)); + testSet[5].correctIdoms.push_back((numeric_limits< int >::max)()); + testSet[5].correctIdoms.push_back(0); + testSet[5].correctIdoms.push_back(0); + testSet[5].correctIdoms.push_back(2); + testSet[5].correctIdoms.push_back(2); + testSet[5].correctIdoms.push_back((numeric_limits< int >::max)()); + testSet[5].correctIdoms.push_back(1); + testSet[5].correctIdoms.push_back(0); - for (size_t i = 0; i < sizeof(testSet)/sizeof(testSet[0]); ++i) - { - const int numOfVertices = testSet[i].numOfVertices; + // Cytron's paper, fig. 9 + testSet[6].numOfVertices = 14, testSet[6].edges.push_back(edge(0, 1)); + testSet[6].edges.push_back(edge(0, 13)); + testSet[6].edges.push_back(edge(1, 2)); + testSet[6].edges.push_back(edge(2, 3)); + testSet[6].edges.push_back(edge(2, 7)); + testSet[6].edges.push_back(edge(3, 4)); + testSet[6].edges.push_back(edge(3, 5)); + testSet[6].edges.push_back(edge(4, 6)); + testSet[6].edges.push_back(edge(5, 6)); + testSet[6].edges.push_back(edge(6, 8)); + testSet[6].edges.push_back(edge(7, 8)); + testSet[6].edges.push_back(edge(8, 9)); + testSet[6].edges.push_back(edge(9, 10)); + testSet[6].edges.push_back(edge(9, 11)); + testSet[6].edges.push_back(edge(10, 11)); + testSet[6].edges.push_back(edge(11, 9)); + testSet[6].edges.push_back(edge(11, 12)); + testSet[6].edges.push_back(edge(12, 2)); + testSet[6].edges.push_back(edge(12, 13)); + testSet[6].correctIdoms.push_back((numeric_limits< int >::max)()); + testSet[6].correctIdoms.push_back(0); + testSet[6].correctIdoms.push_back(1); + testSet[6].correctIdoms.push_back(2); + testSet[6].correctIdoms.push_back(3); + testSet[6].correctIdoms.push_back(3); + testSet[6].correctIdoms.push_back(3); + testSet[6].correctIdoms.push_back(2); + testSet[6].correctIdoms.push_back(2); + testSet[6].correctIdoms.push_back(8); + testSet[6].correctIdoms.push_back(9); + testSet[6].correctIdoms.push_back(9); + testSet[6].correctIdoms.push_back(11); + testSet[6].correctIdoms.push_back(0); - G g( - testSet[i].edges.begin(), testSet[i].edges.end(), - numOfVertices); + for (size_t i = 0; i < sizeof(testSet) / sizeof(testSet[0]); ++i) + { + const int numOfVertices = testSet[i].numOfVertices; - typedef graph_traits::vertex_descriptor Vertex; - typedef property_map::type IndexMap; - typedef - iterator_property_map::iterator, IndexMap> - PredMap; + G g(testSet[i].edges.begin(), testSet[i].edges.end(), numOfVertices); - vector domTreePredVector, domTreePredVector2; - IndexMap indexMap(get(vertex_index, g)); - graph_traits::vertex_iterator uItr, uEnd; - int j = 0; - for (boost::tie(uItr, uEnd) = vertices(g); uItr != uEnd; ++uItr, ++j) - { - put(indexMap, *uItr, j); - } + typedef graph_traits< G >::vertex_descriptor Vertex; + typedef property_map< G, vertex_index_t >::type IndexMap; + typedef iterator_property_map< vector< Vertex >::iterator, IndexMap > + PredMap; - // Lengauer-Tarjan dominator tree algorithm - domTreePredVector = - vector(num_vertices(g), graph_traits::null_vertex()); - PredMap domTreePredMap = - make_iterator_property_map(domTreePredVector.begin(), indexMap); + vector< Vertex > domTreePredVector, domTreePredVector2; + IndexMap indexMap(get(vertex_index, g)); + graph_traits< G >::vertex_iterator uItr, uEnd; + int j = 0; + for (boost::tie(uItr, uEnd) = vertices(g); uItr != uEnd; ++uItr, ++j) + { + put(indexMap, *uItr, j); + } - lengauer_tarjan_dominator_tree(g, vertex(0, g), domTreePredMap); + // Lengauer-Tarjan dominator tree algorithm + domTreePredVector = vector< Vertex >( + num_vertices(g), graph_traits< G >::null_vertex()); + PredMap domTreePredMap + = make_iterator_property_map(domTreePredVector.begin(), indexMap); - vector idom(num_vertices(g)); - for (boost::tie(uItr, uEnd) = vertices(g); uItr != uEnd; ++uItr) - { - if (get(domTreePredMap, *uItr) != graph_traits::null_vertex()) - idom[get(indexMap, *uItr)] = - get(indexMap, get(domTreePredMap, *uItr)); - else - idom[get(indexMap, *uItr)] = (numeric_limits::max)(); - } + lengauer_tarjan_dominator_tree(g, vertex(0, g), domTreePredMap); - copy(idom.begin(), idom.end(), ostream_iterator(cout, " ")); - cout << endl; + vector< int > idom(num_vertices(g)); + for (boost::tie(uItr, uEnd) = vertices(g); uItr != uEnd; ++uItr) + { + if (get(domTreePredMap, *uItr) != graph_traits< G >::null_vertex()) + idom[get(indexMap, *uItr)] + = get(indexMap, get(domTreePredMap, *uItr)); + else + idom[get(indexMap, *uItr)] = (numeric_limits< int >::max)(); + } - // dominator tree correctness test - BOOST_CHECK(std::equal(idom.begin(), idom.end(), testSet[i].correctIdoms.begin())); + copy(idom.begin(), idom.end(), ostream_iterator< int >(cout, " ")); + cout << endl; - // compare results of fast version and slow version of dominator tree - domTreePredVector2 = - vector(num_vertices(g), graph_traits::null_vertex()); - domTreePredMap = - make_iterator_property_map(domTreePredVector2.begin(), indexMap); + // dominator tree correctness test + BOOST_TEST(std::equal( + idom.begin(), idom.end(), testSet[i].correctIdoms.begin())); - iterative_bit_vector_dominator_tree(g, vertex(0, g), domTreePredMap); + // compare results of fast version and slow version of dominator tree + domTreePredVector2 = vector< Vertex >( + num_vertices(g), graph_traits< G >::null_vertex()); + domTreePredMap + = make_iterator_property_map(domTreePredVector2.begin(), indexMap); - vector idom2(num_vertices(g)); - for (boost::tie(uItr, uEnd) = vertices(g); uItr != uEnd; ++uItr) - { - if (get(domTreePredMap, *uItr) != graph_traits::null_vertex()) - idom2[get(indexMap, *uItr)] = - get(indexMap, get(domTreePredMap, *uItr)); - else - idom2[get(indexMap, *uItr)] = (numeric_limits::max)(); - } + iterative_bit_vector_dominator_tree(g, vertex(0, g), domTreePredMap); - copy(idom2.begin(), idom2.end(), ostream_iterator(cout, " ")); - cout << endl; + vector< int > idom2(num_vertices(g)); + for (boost::tie(uItr, uEnd) = vertices(g); uItr != uEnd; ++uItr) + { + if (get(domTreePredMap, *uItr) != graph_traits< G >::null_vertex()) + idom2[get(indexMap, *uItr)] + = get(indexMap, get(domTreePredMap, *uItr)); + else + idom2[get(indexMap, *uItr)] = (numeric_limits< int >::max)(); + } - size_t k; - for (k = 0; k < num_vertices(g); ++k) - BOOST_CHECK(domTreePredVector[k] == domTreePredVector2[k]); - } + copy(idom2.begin(), idom2.end(), ostream_iterator< int >(cout, " ")); + cout << endl; + + size_t k; + for (k = 0; k < num_vertices(g); ++k) + BOOST_TEST(domTreePredVector[k] == domTreePredVector2[k]); + } - return 0; + return boost::report_errors(); } diff --git a/test/eccentricity.cpp b/test/eccentricity.cpp index 2c04c7d63..96c3d1e60 100644 --- a/test/eccentricity.cpp +++ b/test/eccentricity.cpp @@ -13,26 +13,24 @@ #include #include - using namespace std; using namespace boost; // number of vertices in the graph static const unsigned N = 5; -template -struct vertex_vector +template < typename Graph > struct vertex_vector { - typedef graph_traits traits; - typedef vector type; + typedef graph_traits< Graph > traits; + typedef vector< typename traits::vertex_descriptor > type; }; -template -void build_graph(Graph& g, - typename vertex_vector::type& v) +template < typename Graph > +void build_graph(Graph& g, typename vertex_vector< Graph >::type& v) { // add vertices - for(size_t i = 0; i < N; ++i) { + for (size_t i = 0; i < N; ++i) + { v[i] = add_vertex(g); } @@ -44,25 +42,23 @@ void build_graph(Graph& g, add_edge(v[4], v[0], g); } - -template -void test_undirected() +template < typename Graph > void test_undirected() { - typedef typename graph_traits::vertex_descriptor Vertex; - typedef typename graph_traits::edge_descriptor Edge; + typedef typename graph_traits< Graph >::vertex_descriptor Vertex; + typedef typename graph_traits< Graph >::edge_descriptor Edge; - typedef exterior_vertex_property EccentricityProperty; + typedef exterior_vertex_property< Graph, int > EccentricityProperty; typedef typename EccentricityProperty::container_type EccentricityContainer; typedef typename EccentricityProperty::map_type EccentricityMap; - typedef exterior_vertex_property DistanceProperty; + typedef exterior_vertex_property< Graph, int > DistanceProperty; typedef typename DistanceProperty::matrix_type DistanceMatrix; typedef typename DistanceProperty::matrix_map_type DistanceMatrixMap; - typedef constant_property_map WeightMap; + typedef constant_property_map< Edge, int > WeightMap; Graph g; - vector v(N); + vector< Vertex > v(N); build_graph(g, v); EccentricityContainer eccs(num_vertices(g)); @@ -87,24 +83,23 @@ void test_undirected() BOOST_ASSERT(dia == 3); } -template -void test_directed() +template < typename Graph > void test_directed() { - typedef typename graph_traits::vertex_descriptor Vertex; - typedef typename graph_traits::edge_descriptor Edge; + typedef typename graph_traits< Graph >::vertex_descriptor Vertex; + typedef typename graph_traits< Graph >::edge_descriptor Edge; - typedef exterior_vertex_property EccentricityProperty; + typedef exterior_vertex_property< Graph, int > EccentricityProperty; typedef typename EccentricityProperty::container_type EccentricityContainer; typedef typename EccentricityProperty::map_type EccentricityMap; - typedef exterior_vertex_property DistanceProperty; + typedef exterior_vertex_property< Graph, int > DistanceProperty; typedef typename DistanceProperty::matrix_type DistanceMatrix; typedef typename DistanceProperty::matrix_map_type DistanceMatrixMap; - typedef constant_property_map WeightMap; + typedef constant_property_map< Edge, int > WeightMap; Graph g; - vector v(N); + vector< Vertex > v(N); build_graph(g, v); EccentricityContainer eccs(num_vertices(g)); @@ -120,7 +115,7 @@ void test_directed() int rad = radius(g, em); int dia = diameter(g, em); - int inf = numeric_values::infinity(); + int inf = numeric_values< int >::infinity(); BOOST_ASSERT(em[v[0]] == inf); BOOST_ASSERT(em[v[1]] == inf); BOOST_ASSERT(em[v[2]] == inf); @@ -130,13 +125,11 @@ void test_directed() BOOST_ASSERT(dia == inf); } - -int -main(int, char *[]) +int main(int, char*[]) { typedef undirected_graph<> Graph; typedef directed_graph<> Digraph; - test_undirected(); - test_directed(); + test_undirected< Graph >(); + test_directed< Digraph >(); } diff --git a/test/edge_list_cc.cpp b/test/edge_list_cc.cpp index 18d34e050..c98c849f2 100644 --- a/test/edge_list_cc.cpp +++ b/test/edge_list_cc.cpp @@ -13,22 +13,24 @@ #include #include -int main(int,char*[]) +int main(int, char*[]) { // Check edge_list { using namespace boost; - - typedef std::pair E; - - typedef edge_list EdgeList; - - typedef graph_traits::edge_descriptor Edge; - - BOOST_CONCEPT_ASSERT(( EdgeListGraphConcept )); - - BOOST_CONCEPT_ASSERT(( ReadablePropertyGraphConcept )); + + typedef std::pair< int, int > E; + + typedef edge_list< E*, E, std::ptrdiff_t, + std::random_access_iterator_tag > + EdgeList; + + typedef graph_traits< EdgeList >::edge_descriptor Edge; + + BOOST_CONCEPT_ASSERT((EdgeListGraphConcept< EdgeList >)); + + BOOST_CONCEPT_ASSERT( + (ReadablePropertyGraphConcept< EdgeList, Edge, edge_index_t >)); } return 0; } diff --git a/test/filter_graph_vp_test.cpp b/test/filter_graph_vp_test.cpp index 9b8535ba5..fe3ddd65c 100644 --- a/test/filter_graph_vp_test.cpp +++ b/test/filter_graph_vp_test.cpp @@ -16,8 +16,7 @@ using namespace boost; struct NotMuchOfAFilter { - template bool operator()(Vertex key) - const { return true; } + template < class Vertex > bool operator()(Vertex key) const { return true; } }; int main() diff --git a/test/filtered_graph_cc.cpp b/test/filtered_graph_cc.cpp index 9b39dee56..3526165bd 100644 --- a/test/filtered_graph_cc.cpp +++ b/test/filtered_graph_cc.cpp @@ -12,39 +12,42 @@ #include #include -int main(int,char*[]) +int main(int, char*[]) { - using namespace boost; - // Check filtered_graph - { - typedef adjacency_list > Graph; - typedef property_map::type ResCapMap; - typedef filtered_graph > ResGraph; - typedef graph_traits::edge_descriptor Edge; + using namespace boost; + // Check filtered_graph + { + typedef adjacency_list< vecS, vecS, directedS, no_property, + property< edge_residual_capacity_t, long > > + Graph; + typedef property_map< Graph, edge_residual_capacity_t >::type ResCapMap; + typedef filtered_graph< Graph, is_residual_edge< ResCapMap > > ResGraph; + typedef graph_traits< ResGraph >::edge_descriptor Edge; - BOOST_CONCEPT_ASSERT(( VertexListGraphConcept )); - BOOST_CONCEPT_ASSERT(( EdgeListGraphConcept )); - BOOST_CONCEPT_ASSERT(( IncidenceGraphConcept )); - BOOST_CONCEPT_ASSERT(( AdjacencyGraphConcept )); - BOOST_CONCEPT_ASSERT(( PropertyGraphConcept )); - } - // Check filtered_graph with bidirectional adjacency_list - { - typedef adjacency_list > Graph; - typedef property_map::type ResCapMap; - typedef filtered_graph > ResGraph; - BOOST_CONCEPT_ASSERT(( BidirectionalGraphConcept )); - } - // Check filtered_graph with undirected adjacency_list - { - typedef adjacency_list > Graph; - typedef property_map::type ResCapMap; - typedef filtered_graph > ResGraph; - BOOST_CONCEPT_ASSERT(( BidirectionalGraphConcept )); - } - return 0; + BOOST_CONCEPT_ASSERT((VertexListGraphConcept< ResGraph >)); + BOOST_CONCEPT_ASSERT((EdgeListGraphConcept< ResGraph >)); + BOOST_CONCEPT_ASSERT((IncidenceGraphConcept< ResGraph >)); + BOOST_CONCEPT_ASSERT((AdjacencyGraphConcept< ResGraph >)); + BOOST_CONCEPT_ASSERT( + (PropertyGraphConcept< ResGraph, Edge, edge_residual_capacity_t >)); + } + // Check filtered_graph with bidirectional adjacency_list + { + typedef adjacency_list< vecS, vecS, bidirectionalS, no_property, + property< edge_residual_capacity_t, long > > + Graph; + typedef property_map< Graph, edge_residual_capacity_t >::type ResCapMap; + typedef filtered_graph< Graph, is_residual_edge< ResCapMap > > ResGraph; + BOOST_CONCEPT_ASSERT((BidirectionalGraphConcept< ResGraph >)); + } + // Check filtered_graph with undirected adjacency_list + { + typedef adjacency_list< vecS, vecS, undirectedS, no_property, + property< edge_residual_capacity_t, long > > + Graph; + typedef property_map< Graph, edge_residual_capacity_t >::type ResCapMap; + typedef filtered_graph< Graph, is_residual_edge< ResCapMap > > ResGraph; + BOOST_CONCEPT_ASSERT((BidirectionalGraphConcept< ResGraph >)); + } + return 0; } diff --git a/test/filtered_graph_properties_dijkstra.cpp b/test/filtered_graph_properties_dijkstra.cpp index 54b8c4cbd..ecb2931f0 100644 --- a/test/filtered_graph_properties_dijkstra.cpp +++ b/test/filtered_graph_properties_dijkstra.cpp @@ -7,48 +7,43 @@ #include #include -namespace boost { +namespace boost +{ - enum edge_info_t { edge_info = 114 }; +enum edge_info_t +{ + edge_info = 114 +}; - BOOST_INSTALL_PROPERTY( edge, info ); +BOOST_INSTALL_PROPERTY(edge, info); } -template< typename EdgeInfo, - typename Directed > -class Graph +template < typename EdgeInfo, typename Directed > class Graph { public: typedef boost::property< boost::edge_info_t, EdgeInfo > tEdge_property; - typedef boost::adjacency_list< boost::setS, - boost::vecS, - Directed, - boost::no_property, - tEdge_property > tGraph; + typedef boost::adjacency_list< boost::setS, boost::vecS, Directed, + boost::no_property, tEdge_property > + tGraph; typedef typename boost::graph_traits< tGraph >::vertex_descriptor tNode; - typedef typename boost::graph_traits< tGraph >::edge_descriptor tEdge; + typedef typename boost::graph_traits< tGraph >::edge_descriptor tEdge; protected: - - tGraph m_Graph; + tGraph m_Graph; }; class DataEdge; -class UndirectedGraph - : public Graph< DataEdge*, - boost::undirectedS > +class UndirectedGraph : public Graph< DataEdge*, boost::undirectedS > { public: - - template< class Evaluator, class Filter > - void dijkstra( Evaluator const&, - Filter const& ) const; + template < class Evaluator, class Filter > + void dijkstra(Evaluator const&, Filter const&) const; }; -template< typename Graph, typename Derived > +template < typename Graph, typename Derived > struct Evaluator : public boost::put_get_helper< int, Derived > { typedef int value_type; @@ -56,56 +51,56 @@ struct Evaluator : public boost::put_get_helper< int, Derived > typedef int reference; typedef boost::readable_property_map_tag category; - explicit Evaluator( Graph const* pGraph ); + explicit Evaluator(Graph const* pGraph); }; - -template< typename Graph > -struct LengthEvaluator : public Evaluator< Graph, LengthEvaluator > +template < typename Graph > +struct LengthEvaluator : public Evaluator< Graph, LengthEvaluator< Graph > > { - explicit LengthEvaluator( Graph const* pGraph ); + explicit LengthEvaluator(Graph const* pGraph); - typedef typename Evaluator >::reference reference; - typedef typename Evaluator >::key_type key_type; + typedef typename Evaluator< Graph, LengthEvaluator< Graph > >::reference + reference; + typedef typename Evaluator< Graph, LengthEvaluator< Graph > >::key_type + key_type; - virtual reference operator[] ( key_type const& edge ) const; + virtual reference operator[](key_type const& edge) const; }; -template< class Graph > -struct EdgeFilter +template < class Graph > struct EdgeFilter { typedef typename Graph::tEdge key_type; EdgeFilter(); - explicit EdgeFilter( Graph const*); + explicit EdgeFilter(Graph const*); - bool operator()( key_type const& ) const; + bool operator()(key_type const&) const; private: - const Graph* m_pGraph; + const Graph* m_pGraph; }; - -template< class Evaluator, class Filter > -void -UndirectedGraph::dijkstra( Evaluator const& rEvaluator, - Filter const& rFilter ) const +template < class Evaluator, class Filter > +void UndirectedGraph::dijkstra( + Evaluator const& rEvaluator, Filter const& rFilter) const { tNode nodeSource = vertex(0, m_Graph); - std::vector< tNode > predecessors( num_vertices(m_Graph) ); + std::vector< tNode > predecessors(num_vertices(m_Graph)); - boost::filtered_graph< tGraph, Filter > filteredGraph( m_Graph, rFilter ); + boost::filtered_graph< tGraph, Filter > filteredGraph(m_Graph, rFilter); - boost::dijkstra_shortest_paths( filteredGraph, - nodeSource, - boost::predecessor_map( &predecessors[0] ) - .weight_map( rEvaluator ) ); + boost::dijkstra_shortest_paths(filteredGraph, nodeSource, + boost::predecessor_map(&predecessors[0]).weight_map(rEvaluator)); } // explicit instantiation -template void UndirectedGraph::dijkstra( LengthEvaluator const&, - EdgeFilter const& ) const; +template void UndirectedGraph::dijkstra( + LengthEvaluator< UndirectedGraph > const&, + EdgeFilter< UndirectedGraph > const&) const; -int main(int, char**) {return 0;} // Tests above will fail to compile if anything is broken +int main(int, char**) +{ + return 0; +} // Tests above will fail to compile if anything is broken diff --git a/test/find_flow_cost_bundled_properties_and_named_params_test.cpp b/test/find_flow_cost_bundled_properties_and_named_params_test.cpp index efc762066..d21f5470c 100644 --- a/test/find_flow_cost_bundled_properties_and_named_params_test.cpp +++ b/test/find_flow_cost_bundled_properties_and_named_params_test.cpp @@ -1,79 +1,103 @@ -#define BOOST_TEST_MODULE find_flow_cost_bundled_properties_and_named_params_test +#define BOOST_TEST_MODULE \ + find_flow_cost_bundled_properties_and_named_params_test #include #include #include #include "min_cost_max_flow_utils.hpp" -typedef boost::adjacency_list_traits traits; -struct edge_t { - double capacity; - float cost; - float residual_capacity; - traits::edge_descriptor reversed_edge; +typedef boost::adjacency_list_traits< boost::vecS, boost::vecS, + boost::directedS > + traits; +struct edge_t +{ + double capacity; + float cost; + float residual_capacity; + traits::edge_descriptor reversed_edge; }; -struct node_t { - traits::edge_descriptor predecessor; - int dist; - int dist_prev; - boost::vertex_index_t id; +struct node_t +{ + traits::edge_descriptor predecessor; + int dist; + int dist_prev; + boost::vertex_index_t id; }; -typedef boost::adjacency_list Graph; +typedef boost::adjacency_list< boost::listS, boost::vecS, boost::directedS, + node_t, edge_t > + Graph; // Unit test written in order to fails (at compile time) if the find_flow_cost() // is not properly handling bundled properties BOOST_AUTO_TEST_CASE(using_bundled_properties_with_find_max_flow_test) { - Graph g; - traits::vertex_descriptor s,t; - - boost::property_map::type capacity = get(&edge_t::capacity, g); - boost::property_map::type cost = get(&edge_t::cost, g); - boost::property_map::type residual_capacity = get(&edge_t::residual_capacity, g); - boost::property_map::type rev = get(&edge_t::reversed_edge, g); - boost::property_map::type pred = get(&node_t::predecessor, g); - boost::property_map::type vertex_indices = get(boost::vertex_index, g); - boost::property_map::type dist = get(&node_t::dist, g); - boost::property_map::type dist_prev = get(&node_t::dist_prev, g); + Graph g; + traits::vertex_descriptor s, t; + boost::property_map< Graph, double edge_t::* >::type capacity + = get(&edge_t::capacity, g); + boost::property_map< Graph, float edge_t::* >::type cost + = get(&edge_t::cost, g); + boost::property_map< Graph, float edge_t::* >::type residual_capacity + = get(&edge_t::residual_capacity, g); + boost::property_map< Graph, traits::edge_descriptor edge_t::* >::type rev + = get(&edge_t::reversed_edge, g); + boost::property_map< Graph, traits::edge_descriptor node_t::* >::type pred + = get(&node_t::predecessor, g); + boost::property_map< Graph, boost::vertex_index_t >::type vertex_indices + = get(boost::vertex_index, g); + boost::property_map< Graph, int node_t::* >::type dist + = get(&node_t::dist, g); + boost::property_map< Graph, int node_t::* >::type dist_prev + = get(&node_t::dist_prev, g); - boost::SampleGraph::getSampleGraph(g,s,t,capacity,residual_capacity,cost,rev); + boost::SampleGraph::getSampleGraph( + g, s, t, capacity, residual_capacity, cost, rev); - boost::successive_shortest_path_nonnegative_weights(g,s,t, - capacity,residual_capacity,cost,rev,vertex_indices, - pred,dist,dist_prev); + boost::successive_shortest_path_nonnegative_weights(g, s, t, capacity, + residual_capacity, cost, rev, vertex_indices, pred, dist, dist_prev); - // The "bundled properties" version (producing errors) - int flow_cost = boost::find_flow_cost(g,capacity,residual_capacity,cost); - BOOST_CHECK_EQUAL(flow_cost, 29); + // The "bundled properties" version (producing errors) + int flow_cost = boost::find_flow_cost(g, capacity, residual_capacity, cost); + BOOST_CHECK_EQUAL(flow_cost, 29); } // Unit test written in order to fails (at compile time) if the find_flow_cost() // is not properly handling bundled properties -BOOST_AUTO_TEST_CASE(using_named_params_and_bundled_properties_with_find_max_flow_test) +BOOST_AUTO_TEST_CASE( + using_named_params_and_bundled_properties_with_find_max_flow_test) { - Graph g; - traits::vertex_descriptor s,t; + Graph g; + traits::vertex_descriptor s, t; - boost::property_map::type capacity = get(&edge_t::capacity, g); - boost::property_map::type cost = get(&edge_t::cost, g); - boost::property_map::type residual_capacity = get(&edge_t::residual_capacity, g); - boost::property_map::type rev = get(&edge_t::reversed_edge, g); - boost::property_map::type pred = get(&node_t::predecessor, g); - boost::property_map::type vertex_indices = get(boost::vertex_index, g); - boost::property_map::type dist = get(&node_t::dist, g); - boost::property_map::type dist_prev = get(&node_t::dist_prev, g); + boost::property_map< Graph, double edge_t::* >::type capacity + = get(&edge_t::capacity, g); + boost::property_map< Graph, float edge_t::* >::type cost + = get(&edge_t::cost, g); + boost::property_map< Graph, float edge_t::* >::type residual_capacity + = get(&edge_t::residual_capacity, g); + boost::property_map< Graph, traits::edge_descriptor edge_t::* >::type rev + = get(&edge_t::reversed_edge, g); + boost::property_map< Graph, traits::edge_descriptor node_t::* >::type pred + = get(&node_t::predecessor, g); + boost::property_map< Graph, boost::vertex_index_t >::type vertex_indices + = get(boost::vertex_index, g); + boost::property_map< Graph, int node_t::* >::type dist + = get(&node_t::dist, g); + boost::property_map< Graph, int node_t::* >::type dist_prev + = get(&node_t::dist_prev, g); - boost::SampleGraph::getSampleGraph(g,s,t,capacity,residual_capacity,cost,rev); + boost::SampleGraph::getSampleGraph( + g, s, t, capacity, residual_capacity, cost, rev); - boost::successive_shortest_path_nonnegative_weights(g,s,t, - capacity,residual_capacity,cost,rev,vertex_indices, - pred,dist,dist_prev); + boost::successive_shortest_path_nonnegative_weights(g, s, t, capacity, + residual_capacity, cost, rev, vertex_indices, pred, dist, dist_prev); - // The "named parameters" version (with "bundled properties"; producing errors) - int flow_cost = boost::find_flow_cost(g, - boost::capacity_map(capacity) - .residual_capacity_map(residual_capacity) - .weight_map(cost)); - BOOST_CHECK_EQUAL(flow_cost, 29); + // The "named parameters" version (with "bundled properties"; producing + // errors) + int flow_cost = boost::find_flow_cost(g, + boost::capacity_map(capacity) + .residual_capacity_map(residual_capacity) + .weight_map(cost)); + BOOST_CHECK_EQUAL(flow_cost, 29); } diff --git a/test/finish_edge_bug.cpp b/test/finish_edge_bug.cpp index cc31f0b9e..34b9530bb 100644 --- a/test/finish_edge_bug.cpp +++ b/test/finish_edge_bug.cpp @@ -12,71 +12,73 @@ #include #include -template -struct TalkativeVisitor - : boost::dfs_visitor<> +template < typename graph_t > struct TalkativeVisitor : boost::dfs_visitor<> { - typedef typename boost::graph_traits::vertex_descriptor vertex_descriptor; - typedef typename boost::graph_traits::edge_descriptor edge_descriptor; + typedef typename boost::graph_traits< graph_t >::vertex_descriptor + vertex_descriptor; + typedef typename boost::graph_traits< graph_t >::edge_descriptor + edge_descriptor; - // // Commented out to avoid clutter of the output. - // void discover_vertex(vertex_descriptor u, const graph_t&) { // check! - // std::cout << "discover_vertex: " << u << std::endl; - // } - // void finish_vertex(vertex_descriptor u, const graph_t&) { // check! - // std::cout << "finish_vertex: " << u << std::endl; - // } - // void initialize_vertex(vertex_descriptor u, const graph_t&) { // check! - // std::cout << "initialize_vertex: " << u << std::endl; - // } - // void start_vertex(vertex_descriptor u, const graph_t&) { // check! - // std::cout << "start_vertex: " << u << std::endl; - // } - // void examine_edge(edge_descriptor u, const graph_t&) { // check! - // std::cout << "examine_edge: " << u << std::endl; - // } - // void tree_edge(edge_descriptor u, const graph_t&) { // check! - // std::cout << "tree_edge: " << u << std::endl; - // } - // void back_edge(edge_descriptor u, const graph_t&) { // check! - // std::cout << "back_edge: " << u << std::endl; - // } - // void forward_or_cross_edge(edge_descriptor u, const graph_t&) { // check! - // std::cout << "forward_or_cross_edge: " << u << std::endl; - // } - void finish_edge(edge_descriptor u, const graph_t&) { // uncalled! - std::cout << "finish_edge: " << u << std::endl; - } + // // Commented out to avoid clutter of the output. + // void discover_vertex(vertex_descriptor u, const graph_t&) { // check! + // std::cout << "discover_vertex: " << u << std::endl; + // } + // void finish_vertex(vertex_descriptor u, const graph_t&) { // check! + // std::cout << "finish_vertex: " << u << std::endl; + // } + // void initialize_vertex(vertex_descriptor u, const graph_t&) { // check! + // std::cout << "initialize_vertex: " << u << std::endl; + // } + // void start_vertex(vertex_descriptor u, const graph_t&) { // check! + // std::cout << "start_vertex: " << u << std::endl; + // } + // void examine_edge(edge_descriptor u, const graph_t&) { // check! + // std::cout << "examine_edge: " << u << std::endl; + // } + // void tree_edge(edge_descriptor u, const graph_t&) { // check! + // std::cout << "tree_edge: " << u << std::endl; + // } + // void back_edge(edge_descriptor u, const graph_t&) { // check! + // std::cout << "back_edge: " << u << std::endl; + // } + // void forward_or_cross_edge(edge_descriptor u, const graph_t&) { // check! + // std::cout << "forward_or_cross_edge: " << u << std::endl; + // } + void finish_edge(edge_descriptor u, const graph_t&) + { // uncalled! + std::cout << "finish_edge: " << u << std::endl; + } }; -template -std::ostream &operator<<(std::ostream &os, const std::pair &x) { - return os << "(" << x.first << ", " << x.second << ")"; +template < typename t > +std::ostream& operator<<(std::ostream& os, const std::pair< t, t >& x) +{ + return os << "(" << x.first << ", " << x.second << ")"; } - int main(int, char*[]) { - using namespace boost; + using namespace boost; - typedef adjacency_list Graph; - Graph G; + typedef adjacency_list< vecS, vecS, directedS > Graph; + Graph G; - typedef graph_traits >::vertex_descriptor Vertex; - Vertex a = add_vertex(G); - Vertex b = add_vertex(G); - Vertex c = add_vertex(G); + typedef graph_traits< + adjacency_list< vecS, vecS, directedS > >::vertex_descriptor Vertex; + Vertex a = add_vertex(G); + Vertex b = add_vertex(G); + Vertex c = add_vertex(G); - add_edge(a, b, G); - add_edge(b, c, G); - add_edge(c, a, G); - add_edge(a, c, G); + add_edge(a, b, G); + add_edge(b, c, G); + add_edge(c, a, G); + add_edge(a, c, G); - std::cout << "The example graph:" << std::endl; - print_graph(G); + std::cout << "The example graph:" << std::endl; + print_graph(G); - std::vector color(num_vertices(G)); - depth_first_search(G, visitor(TalkativeVisitor())); + std::vector< default_color_type > color(num_vertices(G)); + depth_first_search(G, visitor(TalkativeVisitor< Graph >())); - return 0; + return 0; } diff --git a/test/floyd_warshall_test.cpp b/test/floyd_warshall_test.cpp index fcb606720..0cc99ca9f 100644 --- a/test/floyd_warshall_test.cpp +++ b/test/floyd_warshall_test.cpp @@ -17,376 +17,426 @@ #include #include #include -#include +#include #include using namespace boost; -template -inline const T& my_min(const T& x, const T& y) -{ return x < y? x : y; } - -template -bool acceptance_test(Graph& g, int vec, int e) +template < typename T > inline const T& my_min(const T& x, const T& y) { - boost::minstd_rand ran(vec); - - { - typename boost::property_map::type index = - boost::get(boost::vertex_name, g); - typename boost::graph_traits::vertex_iterator firstv, lastv, - firstv2, lastv2; - int x = 0; - for(boost::tie(firstv, lastv) = boost::vertices(g); firstv != lastv; - firstv++){ - boost::put(index, *firstv, x); - x++; - } - - - for(int i = 0; i < e; i++){ - boost::add_edge(index[ran() % vec], index[ran() % vec], g); - } - - - typename boost::graph_traits::edge_iterator first, last; - typename boost::property_map::type - local_edge_map = boost::get(boost::edge_weight, g); - for(boost::tie(first, last) = boost::edges(g); first != last; first++){ - if (ran() % vec != 0){ - boost::put(local_edge_map, *first, ran() % 100); - } else { - boost::put(local_edge_map, *first, 0 - (ran() % 100)); - } - } + return x < y ? x : y; +} - int int_inf = - std::numeric_limits::max BOOST_PREVENT_MACRO_SUBSTITUTION(); - typedef typename boost::graph_traits::vertex_descriptor vertex_des; - std::map matrixRow; - std::map > matrix; - typedef typename boost::property_map::type - distance_type; - distance_type distance_row = boost::get(boost::vertex_distance, g); - for(boost::tie(firstv, lastv) = boost::vertices(g); firstv != lastv; - firstv++){ - boost::put(distance_row, *firstv, int_inf); - matrixRow[*firstv] = int_inf; - } - for(boost::tie(firstv, lastv) = boost::vertices(g); firstv != lastv; - firstv++){ - matrix[*firstv] = matrixRow; - } - for(boost::tie(firstv, lastv) = boost::vertices(g); firstv != lastv; - firstv++){ - matrix[*firstv][*firstv] = 0; - } - std::map > matrix3(matrix); - std::map > matrix4(matrix); - for(boost::tie(first, last) = boost::edges(g); first != last; first++){ - if (matrix[boost::source(*first, g)][boost::target(*first, g)] != int_inf) - { - matrix[boost::source(*first, g)][boost::target(*first, g)] = - my_min - (boost::get(local_edge_map, *first), - matrix[boost::source(*first, g)][boost::target(*first, g)]); - } else { - matrix[boost::source(*first, g)][boost::target(*first, g)] = - boost::get(local_edge_map, *first); - } - } - bool is_undirected = - boost::is_same::directed_category, - boost::undirected_tag>::value; - if (is_undirected){ - for(boost::tie(first, last) = boost::edges(g); first != last; first++){ - if (matrix[boost::target(*first, g)][boost::source(*first, g)] != int_inf) +template < typename Graph > bool acceptance_test(Graph& g, int vec, int e) +{ + boost::minstd_rand ran(vec); + + { + typename boost::property_map< Graph, boost::vertex_name_t >::type index + = boost::get(boost::vertex_name, g); + typename boost::graph_traits< Graph >::vertex_iterator firstv, lastv, + firstv2, lastv2; + int x = 0; + for (boost::tie(firstv, lastv) = boost::vertices(g); firstv != lastv; + firstv++) { - matrix[boost::target(*first, g)][boost::source(*first, g)] = - my_min - (boost::get(local_edge_map, *first), - matrix[boost::target(*first, g)][boost::source(*first, g)]); - } else { - matrix[boost::target(*first, g)][boost::source(*first, g)] = - boost::get(local_edge_map, *first); + boost::put(index, *firstv, x); + x++; } - } - } + for (int i = 0; i < e; i++) + { + boost::add_edge(index[ran() % vec], index[ran() % vec], g); + } - bool bellman, floyd1, floyd2, floyd3; - floyd1 = - boost::floyd_warshall_initialized_all_pairs_shortest_paths - (g, - matrix, weight_map(boost::get(boost::edge_weight, g)). - distance_inf(int_inf). distance_zero(0)); + typename boost::graph_traits< Graph >::edge_iterator first, last; + typename boost::property_map< Graph, boost::edge_weight_t >::type + local_edge_map + = boost::get(boost::edge_weight, g); + for (boost::tie(first, last) = boost::edges(g); first != last; first++) + { + if (ran() % vec != 0) + { + boost::put(local_edge_map, *first, ran() % 100); + } + else + { + boost::put(local_edge_map, *first, 0 - (ran() % 100)); + } + } - floyd2 = - boost::floyd_warshall_all_pairs_shortest_paths - (g, matrix3, - weight_map(local_edge_map). - distance_inf(int_inf). distance_zero(0)); + int int_inf = std::numeric_limits< int >::max + BOOST_PREVENT_MACRO_SUBSTITUTION(); + typedef + typename boost::graph_traits< Graph >::vertex_descriptor vertex_des; + std::map< vertex_des, int > matrixRow; + std::map< vertex_des, std::map< vertex_des, int > > matrix; + typedef typename boost::property_map< Graph, + boost::vertex_distance_t >::type distance_type; + distance_type distance_row = boost::get(boost::vertex_distance, g); + for (boost::tie(firstv, lastv) = boost::vertices(g); firstv != lastv; + firstv++) + { + boost::put(distance_row, *firstv, int_inf); + matrixRow[*firstv] = int_inf; + } + for (boost::tie(firstv, lastv) = boost::vertices(g); firstv != lastv; + firstv++) + { + matrix[*firstv] = matrixRow; + } + for (boost::tie(firstv, lastv) = boost::vertices(g); firstv != lastv; + firstv++) + { + matrix[*firstv][*firstv] = 0; + } + std::map< vertex_des, std::map< vertex_des, int > > matrix3(matrix); + std::map< vertex_des, std::map< vertex_des, int > > matrix4(matrix); + for (boost::tie(first, last) = boost::edges(g); first != last; first++) + { + if (matrix[boost::source(*first, g)][boost::target(*first, g)] + != int_inf) + { + matrix[boost::source(*first, g)][boost::target(*first, g)] + = my_min(boost::get(local_edge_map, *first), + matrix[boost::source(*first, g)] + [boost::target(*first, g)]); + } + else + { + matrix[boost::source(*first, g)][boost::target(*first, g)] + = boost::get(local_edge_map, *first); + } + } + bool is_undirected = boost::is_same< + typename boost::graph_traits< Graph >::directed_category, + boost::undirected_tag >::value; + if (is_undirected) + { + for (boost::tie(first, last) = boost::edges(g); first != last; + first++) + { + if (matrix[boost::target(*first, g)][boost::source(*first, g)] + != int_inf) + { + matrix[boost::target(*first, g)][boost::source(*first, g)] + = my_min(boost::get(local_edge_map, *first), + matrix[boost::target(*first, g)] + [boost::source(*first, g)]); + } + else + { + matrix[boost::target(*first, g)][boost::source(*first, g)] + = boost::get(local_edge_map, *first); + } + } + } - floyd3 = boost::floyd_warshall_all_pairs_shortest_paths(g, matrix4); + bool bellman, floyd1, floyd2, floyd3; + floyd1 = boost::floyd_warshall_initialized_all_pairs_shortest_paths(g, + matrix, + weight_map(boost::get(boost::edge_weight, g)) + .distance_inf(int_inf) + .distance_zero(0)); + floyd2 = boost::floyd_warshall_all_pairs_shortest_paths(g, matrix3, + weight_map(local_edge_map).distance_inf(int_inf).distance_zero(0)); - boost::dummy_property_map dummy_map; - std::map > matrix2; - for(boost::tie(firstv, lastv) = vertices(g); firstv != lastv; firstv++){ - boost::put(distance_row, *firstv, 0); - bellman = - boost::bellman_ford_shortest_paths - (g, vec, - weight_map(boost::get(boost::edge_weight, g)). - distance_map(boost::get(boost::vertex_distance, g)). - predecessor_map(dummy_map)); - distance_row = boost::get(boost::vertex_distance, g); - for(boost::tie(firstv2, lastv2) = vertices(g); firstv2 != lastv2; - firstv2++){ - matrix2[*firstv][*firstv2] = boost::get(distance_row, *firstv2); - boost::put(distance_row, *firstv2, int_inf); - } - if(bellman == false){ - break; - } - } + floyd3 = boost::floyd_warshall_all_pairs_shortest_paths(g, matrix4); + boost::dummy_property_map dummy_map; + std::map< vertex_des, std::map< vertex_des, int > > matrix2; + for (boost::tie(firstv, lastv) = vertices(g); firstv != lastv; firstv++) + { + boost::put(distance_row, *firstv, 0); + bellman = boost::bellman_ford_shortest_paths(g, vec, + weight_map(boost::get(boost::edge_weight, g)) + .distance_map(boost::get(boost::vertex_distance, g)) + .predecessor_map(dummy_map)); + distance_row = boost::get(boost::vertex_distance, g); + for (boost::tie(firstv2, lastv2) = vertices(g); firstv2 != lastv2; + firstv2++) + { + matrix2[*firstv][*firstv2] = boost::get(distance_row, *firstv2); + boost::put(distance_row, *firstv2, int_inf); + } + if (bellman == false) + { + break; + } + } - if (bellman != floyd1 || bellman != floyd2 || bellman != floyd3){ - std::cout << - "A negative cycle was detected in one algorithm but not the others. " - << std::endl; - return false; - } - else if (bellman == false && floyd1 == false && floyd2 == false && - floyd3 == false){ - return true; - } - else { - typename boost::graph_traits::vertex_iterator first1, first2, - last1, last2; - for (boost::tie(first1, last1) = boost::vertices(g); first1 != last1; - first1++){ - for (boost::tie(first2, last2) = boost::vertices(g); first2 != last2; - first2++){ - if (matrix2[*first1][*first2] != matrix[*first1][*first2]){ - std::cout << "Algorithms do not match at matrix point " - << index[*first1] << " " << index[*first2] - << " Bellman results: " << matrix2[*first1][*first2] - << " floyd 1 results " << matrix[*first1][*first2] - << std::endl; - return false; - } - if (matrix2[*first1][*first2] != matrix3[*first1][*first2]){ - std::cout << "Algorithms do not match at matrix point " - << index[*first1] << " " << index[*first2] - << " Bellman results: " << matrix2[*first1][*first2] - << " floyd 2 results " << matrix3[*first1][*first2] - << std::endl; - return false; - } - if (matrix2[*first1][*first2] != matrix4[*first1][*first2]){ - std::cout << "Algorithms do not match at matrix point " - << index[*first1] << " " << index[*first2] - << " Bellman results: " << matrix2[*first1][*first2] - << " floyd 3 results " << matrix4[*first1][*first2] + if (bellman != floyd1 || bellman != floyd2 || bellman != floyd3) + { + std::cout << "A negative cycle was detected in one algorithm but " + "not the others. " << std::endl; return false; - } } - } + else if (bellman == false && floyd1 == false && floyd2 == false + && floyd3 == false) + { + return true; + } + else + { + typename boost::graph_traits< Graph >::vertex_iterator first1, + first2, last1, last2; + for (boost::tie(first1, last1) = boost::vertices(g); + first1 != last1; first1++) + { + for (boost::tie(first2, last2) = boost::vertices(g); + first2 != last2; first2++) + { + if (matrix2[*first1][*first2] != matrix[*first1][*first2]) + { + std::cout + << "Algorithms do not match at matrix point " + << index[*first1] << " " << index[*first2] + << " Bellman results: " << matrix2[*first1][*first2] + << " floyd 1 results " << matrix[*first1][*first2] + << std::endl; + return false; + } + if (matrix2[*first1][*first2] != matrix3[*first1][*first2]) + { + std::cout + << "Algorithms do not match at matrix point " + << index[*first1] << " " << index[*first2] + << " Bellman results: " << matrix2[*first1][*first2] + << " floyd 2 results " << matrix3[*first1][*first2] + << std::endl; + return false; + } + if (matrix2[*first1][*first2] != matrix4[*first1][*first2]) + { + std::cout + << "Algorithms do not match at matrix point " + << index[*first1] << " " << index[*first2] + << " Bellman results: " << matrix2[*first1][*first2] + << " floyd 3 results " << matrix4[*first1][*first2] + << std::endl; + return false; + } + } + } + } } - - } - return true; + return true; } -template -bool acceptance_test2(Graph& g, int vec, int e) +template < typename Graph > bool acceptance_test2(Graph& g, int vec, int e) { - boost::minstd_rand ran(vec); - - { + boost::minstd_rand ran(vec); - typename boost::property_map::type index = - boost::get(boost::vertex_name, g); - typename boost::graph_traits::vertex_iterator firstv, lastv, - firstv2, lastv2; - int x = 0; - for(boost::tie(firstv, lastv) = boost::vertices(g); firstv != lastv; - firstv++){ - boost::put(index, *firstv, x); - x++; - } - - boost::generate_random_graph(g, vec, e, ran, true); + { - typename boost::graph_traits::edge_iterator first, last; - typename boost::property_map::type - local_edge_map = boost::get(boost::edge_weight, g); - for(boost::tie(first, last) = boost::edges(g); first != last; first++){ - if (ran() % vec != 0){ - boost::put(local_edge_map, *first, ran() % 100); - } else { - boost::put(local_edge_map, *first, 0 - (ran() % 100)); - } - } - - int int_inf = - std::numeric_limits::max BOOST_PREVENT_MACRO_SUBSTITUTION(); - typedef typename boost::graph_traits::vertex_descriptor vertex_des; - std::map matrixRow; - std::map > matrix; - typedef typename boost::property_map::type - distance_type; - distance_type distance_row = boost::get(boost::vertex_distance, g); - for(boost::tie(firstv, lastv) = boost::vertices(g); firstv != lastv; - firstv++){ - boost::put(distance_row, *firstv, int_inf); - matrixRow[*firstv] = int_inf; - } - for(boost::tie(firstv, lastv) = boost::vertices(g); firstv != lastv; - firstv++){ - matrix[*firstv] = matrixRow; - } - for(boost::tie(firstv, lastv) = boost::vertices(g); firstv != lastv; - firstv++){ - matrix[*firstv][*firstv] = 0; - } - std::map > matrix3(matrix); - std::map > matrix4(matrix); - for(boost::tie(first, last) = boost::edges(g); first != last; first++){ - if (matrix[boost::source(*first, g)][boost::target(*first, g)] != int_inf) - { - matrix[boost::source(*first, g)][boost::target(*first, g)] = - my_min - (boost::get(local_edge_map, *first), - matrix[boost::source(*first, g)][boost::target(*first, g)]); - } else { - matrix[boost::source(*first, g)][boost::target(*first, g)] = - boost::get(local_edge_map, *first); - } - } - bool is_undirected = - boost::is_same::directed_category, - boost::undirected_tag>::value; - if (is_undirected){ - for(boost::tie(first, last) = boost::edges(g); first != last; first++){ - if (matrix[boost::target(*first, g)][boost::source(*first, g)] - != int_inf){ - matrix[boost::target(*first, g)][boost::source(*first, g)] = - my_min - (boost::get(local_edge_map, *first), - matrix[boost::target(*first, g)][boost::source(*first, g)]); - } else { - matrix[boost::target(*first, g)][boost::source(*first, g)] = - boost::get(local_edge_map, *first); + typename boost::property_map< Graph, boost::vertex_name_t >::type index + = boost::get(boost::vertex_name, g); + typename boost::graph_traits< Graph >::vertex_iterator firstv, lastv, + firstv2, lastv2; + int x = 0; + for (boost::tie(firstv, lastv) = boost::vertices(g); firstv != lastv; + firstv++) + { + boost::put(index, *firstv, x); + x++; } - } - } + boost::generate_random_graph(g, vec, e, ran, true); - bool bellman, floyd1, floyd2, floyd3; - floyd1 = - boost::floyd_warshall_initialized_all_pairs_shortest_paths - (g, - matrix, weight_map(boost::get(boost::edge_weight, g)). - distance_inf(int_inf). distance_zero(0)); + typename boost::graph_traits< Graph >::edge_iterator first, last; + typename boost::property_map< Graph, boost::edge_weight_t >::type + local_edge_map + = boost::get(boost::edge_weight, g); + for (boost::tie(first, last) = boost::edges(g); first != last; first++) + { + if (ran() % vec != 0) + { + boost::put(local_edge_map, *first, ran() % 100); + } + else + { + boost::put(local_edge_map, *first, 0 - (ran() % 100)); + } + } - floyd2 = - boost::floyd_warshall_all_pairs_shortest_paths - (g, matrix3, - weight_map(local_edge_map). - distance_inf(int_inf). distance_zero(0)); + int int_inf = std::numeric_limits< int >::max + BOOST_PREVENT_MACRO_SUBSTITUTION(); + typedef + typename boost::graph_traits< Graph >::vertex_descriptor vertex_des; + std::map< vertex_des, int > matrixRow; + std::map< vertex_des, std::map< vertex_des, int > > matrix; + typedef typename boost::property_map< Graph, + boost::vertex_distance_t >::type distance_type; + distance_type distance_row = boost::get(boost::vertex_distance, g); + for (boost::tie(firstv, lastv) = boost::vertices(g); firstv != lastv; + firstv++) + { + boost::put(distance_row, *firstv, int_inf); + matrixRow[*firstv] = int_inf; + } + for (boost::tie(firstv, lastv) = boost::vertices(g); firstv != lastv; + firstv++) + { + matrix[*firstv] = matrixRow; + } + for (boost::tie(firstv, lastv) = boost::vertices(g); firstv != lastv; + firstv++) + { + matrix[*firstv][*firstv] = 0; + } + std::map< vertex_des, std::map< vertex_des, int > > matrix3(matrix); + std::map< vertex_des, std::map< vertex_des, int > > matrix4(matrix); + for (boost::tie(first, last) = boost::edges(g); first != last; first++) + { + if (matrix[boost::source(*first, g)][boost::target(*first, g)] + != int_inf) + { + matrix[boost::source(*first, g)][boost::target(*first, g)] + = my_min(boost::get(local_edge_map, *first), + matrix[boost::source(*first, g)] + [boost::target(*first, g)]); + } + else + { + matrix[boost::source(*first, g)][boost::target(*first, g)] + = boost::get(local_edge_map, *first); + } + } + bool is_undirected = boost::is_same< + typename boost::graph_traits< Graph >::directed_category, + boost::undirected_tag >::value; + if (is_undirected) + { + for (boost::tie(first, last) = boost::edges(g); first != last; + first++) + { + if (matrix[boost::target(*first, g)][boost::source(*first, g)] + != int_inf) + { + matrix[boost::target(*first, g)][boost::source(*first, g)] + = my_min(boost::get(local_edge_map, *first), + matrix[boost::target(*first, g)] + [boost::source(*first, g)]); + } + else + { + matrix[boost::target(*first, g)][boost::source(*first, g)] + = boost::get(local_edge_map, *first); + } + } + } - floyd3 = boost::floyd_warshall_all_pairs_shortest_paths(g, matrix4); + bool bellman, floyd1, floyd2, floyd3; + floyd1 = boost::floyd_warshall_initialized_all_pairs_shortest_paths(g, + matrix, + weight_map(boost::get(boost::edge_weight, g)) + .distance_inf(int_inf) + .distance_zero(0)); + floyd2 = boost::floyd_warshall_all_pairs_shortest_paths(g, matrix3, + weight_map(local_edge_map).distance_inf(int_inf).distance_zero(0)); - boost::dummy_property_map dummy_map; - std::map > matrix2; - for(boost::tie(firstv, lastv) = vertices(g); firstv != lastv; firstv++){ - boost::put(distance_row, *firstv, 0); - bellman = - boost::bellman_ford_shortest_paths - (g, vec, - weight_map(boost::get(boost::edge_weight, g)). - distance_map(boost::get(boost::vertex_distance, g)). - predecessor_map(dummy_map)); - distance_row = boost::get(boost::vertex_distance, g); - for(boost::tie(firstv2, lastv2) = vertices(g); firstv2 != lastv2; - firstv2++){ - matrix2[*firstv][*firstv2] = boost::get(distance_row, *firstv2); - boost::put(distance_row, *firstv2, int_inf); - } - if(bellman == false){ - break; - } - } + floyd3 = boost::floyd_warshall_all_pairs_shortest_paths(g, matrix4); + boost::dummy_property_map dummy_map; + std::map< vertex_des, std::map< vertex_des, int > > matrix2; + for (boost::tie(firstv, lastv) = vertices(g); firstv != lastv; firstv++) + { + boost::put(distance_row, *firstv, 0); + bellman = boost::bellman_ford_shortest_paths(g, vec, + weight_map(boost::get(boost::edge_weight, g)) + .distance_map(boost::get(boost::vertex_distance, g)) + .predecessor_map(dummy_map)); + distance_row = boost::get(boost::vertex_distance, g); + for (boost::tie(firstv2, lastv2) = vertices(g); firstv2 != lastv2; + firstv2++) + { + matrix2[*firstv][*firstv2] = boost::get(distance_row, *firstv2); + boost::put(distance_row, *firstv2, int_inf); + } + if (bellman == false) + { + break; + } + } - if (bellman != floyd1 || bellman != floyd2 || bellman != floyd3){ - std::cout << - "A negative cycle was detected in one algorithm but not the others. " - << std::endl; - return false; - } - else if (bellman == false && floyd1 == false && floyd2 == false && - floyd3 == false){ - return true; - } - else { - typename boost::graph_traits::vertex_iterator first1, first2, - last1, last2; - for (boost::tie(first1, last1) = boost::vertices(g); first1 != last1; - first1++){ - for (boost::tie(first2, last2) = boost::vertices(g); first2 != last2; - first2++){ - if (matrix2[*first1][*first2] != matrix[*first1][*first2]){ - std::cout << "Algorithms do not match at matrix point " - << index[*first1] << " " << index[*first2] - << " Bellman results: " << matrix2[*first1][*first2] - << " floyd 1 results " << matrix[*first1][*first2] - << std::endl; - return false; - } - if (matrix2[*first1][*first2] != matrix3[*first1][*first2]){ - std::cout << "Algorithms do not match at matrix point " - << index[*first1] << " " << index[*first2] - << " Bellman results: " << matrix2[*first1][*first2] - << " floyd 2 results " << matrix3[*first1][*first2] - << std::endl; - return false; - } - if (matrix2[*first1][*first2] != matrix4[*first1][*first2]){ - std::cout << "Algorithms do not match at matrix point " - << index[*first1] << " " << index[*first2] - << " Bellman results: " << matrix2[*first1][*first2] - << " floyd 3 results " << matrix4[*first1][*first2] + if (bellman != floyd1 || bellman != floyd2 || bellman != floyd3) + { + std::cout << "A negative cycle was detected in one algorithm but " + "not the others. " << std::endl; return false; - } } - } + else if (bellman == false && floyd1 == false && floyd2 == false + && floyd3 == false) + { + return true; + } + else + { + typename boost::graph_traits< Graph >::vertex_iterator first1, + first2, last1, last2; + for (boost::tie(first1, last1) = boost::vertices(g); + first1 != last1; first1++) + { + for (boost::tie(first2, last2) = boost::vertices(g); + first2 != last2; first2++) + { + if (matrix2[*first1][*first2] != matrix[*first1][*first2]) + { + std::cout + << "Algorithms do not match at matrix point " + << index[*first1] << " " << index[*first2] + << " Bellman results: " << matrix2[*first1][*first2] + << " floyd 1 results " << matrix[*first1][*first2] + << std::endl; + return false; + } + if (matrix2[*first1][*first2] != matrix3[*first1][*first2]) + { + std::cout + << "Algorithms do not match at matrix point " + << index[*first1] << " " << index[*first2] + << " Bellman results: " << matrix2[*first1][*first2] + << " floyd 2 results " << matrix3[*first1][*first2] + << std::endl; + return false; + } + if (matrix2[*first1][*first2] != matrix4[*first1][*first2]) + { + std::cout + << "Algorithms do not match at matrix point " + << index[*first1] << " " << index[*first2] + << " Bellman results: " << matrix2[*first1][*first2] + << " floyd 3 results " << matrix4[*first1][*first2] + << std::endl; + return false; + } + } + } + } } - - } - return true; + return true; } -int test_main(int, char*[]) +int main(int, char*[]) { - typedef boost::adjacency_list > , - boost::property > Digraph; - Digraph adjlist_digraph; - BOOST_CHECK(acceptance_test2(adjlist_digraph, 100, 2000)); - - typedef boost::adjacency_matrix > , - boost::property > Graph; - Graph matrix_graph(100); - BOOST_CHECK(acceptance_test(matrix_graph, 100, 2000)); - - return 0; + typedef boost::adjacency_list< boost::listS, boost::listS, boost::directedS, + boost::property< boost::vertex_distance_t, int, + boost::property< boost::vertex_name_t, int > >, + boost::property< boost::edge_weight_t, int > > + Digraph; + Digraph adjlist_digraph; + BOOST_TEST(acceptance_test2(adjlist_digraph, 100, 2000)); + + typedef boost::adjacency_matrix< boost::undirectedS, + boost::property< boost::vertex_distance_t, int, + boost::property< boost::vertex_name_t, int > >, + boost::property< boost::edge_weight_t, int > > + Graph; + Graph matrix_graph(100); + BOOST_TEST(acceptance_test(matrix_graph, 100, 2000)); + + return boost::report_errors(); } diff --git a/test/generator_test.cpp b/test/generator_test.cpp index 15f474082..340d1954d 100644 --- a/test/generator_test.cpp +++ b/test/generator_test.cpp @@ -8,7 +8,7 @@ // Andrew Lumsdaine #include -#include +#include #include #include @@ -20,105 +20,118 @@ using namespace boost; -int test_main(int argc, char** argv) { +int main(int argc, char** argv) +{ - typedef rand48 RandomGenerator; + typedef rand48 RandomGenerator; - typedef adjacency_list Graph; + typedef adjacency_list< vecS, vecS, directedS > Graph; - RandomGenerator gen; + RandomGenerator gen; - size_t N = 100; - size_t M = 1000; - double p = 0.05; + size_t N = 100; + size_t M = 1000; + double p = 0.05; - // Test Erdos-Renyi generator - { - erdos_renyi_iterator start(gen, N, p); - erdos_renyi_iterator end; + // Test Erdos-Renyi generator + { + erdos_renyi_iterator< RandomGenerator, Graph > start(gen, N, p); + erdos_renyi_iterator< RandomGenerator, Graph > end; - while (start != end) ++start; + while (start != end) + ++start; - BOOST_CHECK(start == end); - } + BOOST_TEST(start == end); + } - { - sorted_erdos_renyi_iterator start(gen, N, p); - sorted_erdos_renyi_iterator end; + { + sorted_erdos_renyi_iterator< RandomGenerator, Graph > start(gen, N, p); + sorted_erdos_renyi_iterator< RandomGenerator, Graph > end; - while (start != end) ++start; + while (start != end) + ++start; - BOOST_CHECK(start == end); - } + BOOST_TEST(start == end); + } - // Test Small World generator - { - small_world_iterator start(gen, N, M, p); - small_world_iterator end; - - while (start != end) ++start; + // Test Small World generator + { + small_world_iterator< RandomGenerator, Graph > start(gen, N, M, p); + small_world_iterator< RandomGenerator, Graph > end; - BOOST_CHECK(start == end); - } + while (start != end) + ++start; - // Test SSCA generator - { - ssca_iterator start(gen, N, 5, 0.5, 5, p); - ssca_iterator end; + BOOST_TEST(start == end); + } - while (start != end) ++start; + // Test SSCA generator + { + ssca_iterator< RandomGenerator, Graph > start(gen, N, 5, 0.5, 5, p); + ssca_iterator< RandomGenerator, Graph > end; - BOOST_CHECK(start == end); - } + while (start != end) + ++start; - // Test Mesh generator - { - mesh_iterator start(N, N); - mesh_iterator end; + BOOST_TEST(start == end); + } - while (start != end) ++start; + // Test Mesh generator + { + mesh_iterator< Graph > start(N, N); + mesh_iterator< Graph > end; - BOOST_CHECK(start == end); - } + while (start != end) + ++start; - // Test R-MAT generator - double a = 0.57, b = 0.19, c = 0.19, d = 0.05; + BOOST_TEST(start == end); + } - { - rmat_iterator start(gen, N, M, a, b, c, d); - rmat_iterator end; + // Test R-MAT generator + double a = 0.57, b = 0.19, c = 0.19, d = 0.05; - while (start != end) ++start; + { + rmat_iterator< RandomGenerator, Graph > start(gen, N, M, a, b, c, d); + rmat_iterator< RandomGenerator, Graph > end; - BOOST_CHECK(start == end); - } + while (start != end) + ++start; - { - unique_rmat_iterator start(gen, N, M, a, b, c, d); - unique_rmat_iterator end; + BOOST_TEST(start == end); + } - while (start != end) ++start; + { + unique_rmat_iterator< RandomGenerator, Graph > start( + gen, N, M, a, b, c, d); + unique_rmat_iterator< RandomGenerator, Graph > end; - BOOST_CHECK(start == end); - } + while (start != end) + ++start; - { - sorted_unique_rmat_iterator start(gen, N, M, a, b, c, d); - sorted_unique_rmat_iterator end; + BOOST_TEST(start == end); + } - while (start != end) ++start; + { + sorted_unique_rmat_iterator< RandomGenerator, Graph > start( + gen, N, M, a, b, c, d); + sorted_unique_rmat_iterator< RandomGenerator, Graph > end; - BOOST_CHECK(start == end); - } + while (start != end) + ++start; - { - sorted_unique_rmat_iterator start(gen, N, M, a, b, c, d, true); - sorted_unique_rmat_iterator end; + BOOST_TEST(start == end); + } - while (start != end) ++start; + { + sorted_unique_rmat_iterator< RandomGenerator, Graph > start( + gen, N, M, a, b, c, d, true); + sorted_unique_rmat_iterator< RandomGenerator, Graph > end; - BOOST_CHECK(start == end); - } + while (start != end) + ++start; - return 0; + BOOST_TEST(start == end); + } + + return boost::report_errors(); } diff --git a/test/graph.cpp b/test/graph.cpp index 08428f20c..614b84193 100644 --- a/test/graph.cpp +++ b/test/graph.cpp @@ -21,19 +21,25 @@ #include #include #include +#include #include - -enum vertex_id_t { vertex_id = 500 }; -enum edge_id_t { edge_id = 501 }; -namespace boost { - BOOST_INSTALL_PROPERTY(vertex, id); - BOOST_INSTALL_PROPERTY(edge, id); +enum vertex_id_t +{ + vertex_id = 500 +}; +enum edge_id_t +{ + edge_id = 501 +}; +namespace boost +{ +BOOST_INSTALL_PROPERTY(vertex, id); +BOOST_INSTALL_PROPERTY(edge, id); } - -#include "graph_type.hpp" // this provides a typedef for Graph +#include using namespace boost; @@ -41,444 +47,387 @@ using namespace boost; This program tests models of the MutableGraph concept. */ +using std::cerr; using std::cout; using std::endl; -using std::cerr; using std::find; - -template +template < class Graph, class Vertex, class ID > bool check_vertex_cleared(Graph& g, Vertex v, ID id) { - typename graph_traits::vertex_iterator vi, viend; - for (boost::tie(vi,viend) = vertices(g); vi != viend; ++vi) { - typename graph_traits::adjacency_iterator ai, aiend, found; - boost::tie(ai, aiend) = adjacent_vertices(*vi, g); - boost::indirect_cmp > cmp(id); + typename graph_traits< Graph >::vertex_iterator vi, viend; + for (boost::tie(vi, viend) = vertices(g); vi != viend; ++vi) + { + typename graph_traits< Graph >::adjacency_iterator ai, aiend, found; + boost::tie(ai, aiend) = adjacent_vertices(*vi, g); + boost::indirect_cmp< ID, std::equal_to< std::size_t > > cmp(id); #if (defined(BOOST_MSVC) && BOOST_MSVC <= 1300) && defined(__SGI_STL_PORT) - // seeing internal compiler errors when using std::find_if() - found = aiend; - for ( ; ai != aiend; ++ai) - if (cmp(*ai, v)) { - found = ai; - break; - } + // seeing internal compiler errors when using std::find_if() + found = aiend; + for (; ai != aiend; ++ai) + if (cmp(*ai, v)) + { + found = ai; + break; + } #elif defined(BOOST_NO_CXX98_BINDERS) - found = std::find_if(ai, aiend, std::bind(cmp,v,std::placeholders::_1)); + found + = std::find_if(ai, aiend, std::bind(cmp, v, std::placeholders::_1)); #else - found = std::find_if(ai, aiend, std::bind1st(cmp,v)); + found = std::find_if(ai, aiend, std::bind1st(cmp, v)); #endif - if ( found != aiend ) { + if (found != aiend) + { #if VERBOSE - std::cerr << "should not have found vertex " << id[*found] << std::endl; + std::cerr << "should not have found vertex " << id[*found] + << std::endl; #endif - return false; + return false; + } } - } - return true; + return true; } -template -bool check_edge_added(Graph& g, Edge e, - typename graph_traits::vertex_descriptor a, - typename graph_traits::vertex_descriptor b, - EdgeID edge_id, std::size_t correct_id, - bool inserted) +template < class Graph, class Edge, class EdgeID > +bool check_edge_added(Graph& g, Edge e, + typename graph_traits< Graph >::vertex_descriptor a, + typename graph_traits< Graph >::vertex_descriptor b, EdgeID edge_id, + std::size_t correct_id, bool inserted) { - if (! (source(e, g) == a)) { + if (!(source(e, g) == a)) + { #if VERBOSE - cerr << " Failed, vertex a not source of e."<< endl; + cerr << " Failed, vertex a not source of e." << endl; #endif - return false; - } else if (! (target(e, g) == b)) { + return false; + } + else if (!(target(e, g) == b)) + { #if VERBOSE - cerr << " Failed, vertex b not source of e."<< endl; + cerr << " Failed, vertex b not source of e." << endl; #endif - return false; - } else if (! is_adjacent(g, a, b)) { + return false; + } + else if (!is_adjacent(g, a, b)) + { #if VERBOSE - cerr << " Failed, not adj."<< endl; + cerr << " Failed, not adj." << endl; #endif - return false; - } else if (! in_edge_set(g,e)) { + return false; + } + else if (!in_edge_set(g, e)) + { #if VERBOSE - cerr << " Failed, not in edge set."<< endl; + cerr << " Failed, not in edge set." << endl; #endif - return false; - } else if (inserted && edge_id[e] != correct_id) { + return false; + } + else if (inserted && edge_id[e] != correct_id) + { #if VERBOSE - cerr << " Failed, invalid edge property."<< endl; + cerr << " Failed, invalid edge property." << endl; #endif - return false; - } else if (!inserted && edge_id[e] != edge_id[edge(a, b, g).first]) { + return false; + } + else if (!inserted && edge_id[e] != edge_id[edge(a, b, g).first]) + { #if VERBOSE - cerr << " Failed, invalid edge property."<< endl; + cerr << " Failed, invalid edge property." << endl; #endif - return false; - } else if (num_edges(g) != count_edges(g)) { + return false; + } + else if (num_edges(g) != count_edges(g)) + { #if VERBOSE - cerr << " Failed, invalid number of edges."<< endl; + cerr << " Failed, invalid number of edges." << endl; #endif - return false; - } - return true; + return false; + } + return true; } - -template -std::size_t count_edges(Graph& g) +template < class Graph > std::size_t count_edges(Graph& g) { - std::size_t e = 0; - typename boost::graph_traits::edge_iterator ei,ei_end; - for (boost::tie(ei,ei_end) = edges(g); ei != ei_end; ++ei) - ++e; - return e; + std::size_t e = 0; + typename boost::graph_traits< Graph >::edge_iterator ei, ei_end; + for (boost::tie(ei, ei_end) = edges(g); ei != ei_end; ++ei) + ++e; + return e; } - -int main(int, char* []) +template < typename test_type_T, typename directed_type_T > void test_instance() { - int ret = 0; - std::size_t N = 5, E = 0; - std::size_t old_N; - typedef ::Graph Graph; - Graph g; - typedef boost::graph_traits::vertex_descriptor Vertex; - typedef boost::graph_traits::edge_descriptor Edge; + typedef typename boost::adjacency_list< test_type_T, test_type_T, + directed_type_T, boost::property< vertex_id_t, std::size_t >, + boost::property< edge_id_t, std::size_t > > + Graph; + typedef typename boost::property< edge_id_t, std::size_t > EdgeID; - int i, j; - std::size_t current_vertex_id = 0; - std::size_t current_edge_id = 0; + std::size_t N = 5, E = 0; + std::size_t old_N; - bool is_failed = false; + Graph g; + typedef typename boost::graph_traits< Graph >::vertex_descriptor Vertex; + typedef typename boost::graph_traits< Graph >::edge_descriptor Edge; - property_map::type vertex_id_map = get(vertex_id, g); + int i, j; + std::size_t current_vertex_id = 0; + std::size_t current_edge_id = 0; - property_map::type edge_id_map = get(edge_id, g); + typename property_map< Graph, vertex_id_t >::type vertex_id_map + = get(vertex_id, g); - for (std::size_t k = 0; k < N; ++k) - add_vertex(current_vertex_id++, g); + typename property_map< Graph, edge_id_t >::type edge_id_map + = get(edge_id, g); - // also need to test EdgeIterator graph constructor -JGS - mt19937 gen; - - for (j=0; j < 10; ++j) { + for (std::size_t k = 0; k < N; ++k) + add_vertex(current_vertex_id++, g); - // add_edge -#if VERBOSE - cerr << "Testing add_edge ..." << endl; -#endif - for (i=0; i < 6; ++i) { - Vertex a, b; - a = random_vertex(g, gen); - do { - b = random_vertex(g, gen); - } while ( a == b ); // don't do self edges -#if VERBOSE - cerr << "add_edge(" << vertex_id_map[a] << "," << vertex_id_map[b] <<")" << endl; -#endif - Edge e; - bool inserted; - boost::tie(e, inserted) = add_edge(a, b, current_edge_id++, g); -#if VERBOSE - std::cout << "inserted: " << inserted << std::endl; - std::cout << "source(e,g)" << source(e,g) << endl; - std::cout << "target(e,g)" << target(e,g) << endl; - std::cout << "edge_id[e] = " << edge_id_map[e] << std::endl; - print_edges2(g, vertex_id_map, edge_id_map); - print_graph(g, vertex_id_map); - std::cout << "finished printing" << std::endl; - // print_in_edges(g, vertex_id_map); -#endif - if (! check_edge_added(g, e, a, b, edge_id_map, - current_edge_id - 1, inserted)) { - ret = -1; - break; - } - ++E; - } + // also need to test EdgeIterator graph constructor -JGS + mt19937 gen; - // remove_edge(u, v, g) -#if VERBOSE - cerr << "Testing remove_edge(u, v, g) ..." << endl; is_failed = false; -#endif - for (i = 0; i < 2; ++i) { -#if VERBOSE - print_edges(g, vertex_id_map); -#endif - Vertex a, b; - - Edge e = random_edge(g, gen); - boost::tie(a,b) = boost::incident(e, g); - --E; -#if VERBOSE - cerr << "remove_edge(" << vertex_id_map[a] << "," << vertex_id_map[b] << ")" << endl; -#endif - remove_edge(a, b, g); -#if VERBOSE - print_graph(g, vertex_id_map); - // print_in_edges(g, vertex_id_map); - print_edges(g, vertex_id_map); -#endif - is_failed = is_failed || is_adjacent(g, a, b) || in_edge_set(g, a, b) - || num_edges(g) != count_edges(g); - if (is_failed) - break; - } - if ( is_failed ) { - ret = -1; -#if VERBOSE - cerr << " Failed."<< endl; -#endif - } else { -#if VERBOSE - cerr << " Passed."<< endl; -#endif - } + for (j = 0; j < 10; ++j) + { - // remove_edge(e, g) -#if VERBOSE - cerr << "Testing remove_edge(e, g) ..." << endl; is_failed = false; -#endif - for (i = 0; i < 2; ++i) { -#if VERBOSE - print_edges(g, vertex_id_map); -#endif - Vertex a, b; - Edge e = random_edge(g, gen); - boost::tie(a,b) = boost::incident(e, g); - --E; + // add_edge +#if VERBOSE + cerr << "Testing add_edge ..." << endl; +#endif + for (i = 0; i < 6; ++i) + { + Vertex a, b; + a = random_vertex(g, gen); + do + { + b = random_vertex(g, gen); + } while (a == b); // don't do self edges +#if VERBOSE + cerr << "add_edge(" << vertex_id_map[a] << "," << vertex_id_map[b] + << ")" << endl; +#endif + Edge e; + bool inserted; + boost::tie(e, inserted) = add_edge(a, b, current_edge_id++, g); +#if VERBOSE + std::cout << "inserted: " << inserted << std::endl; + std::cout << "source(e,g)" << source(e, g) << endl; + std::cout << "target(e,g)" << target(e, g) << endl; + std::cout << "edge_id[e] = " << edge_id_map[e] << std::endl; + print_edges2(g, vertex_id_map, edge_id_map); + print_graph(g, vertex_id_map); + std::cout << "finished printing" << std::endl; + // print_in_edges(g, vertex_id_map); +#endif + BOOST_ASSERT(check_edge_added( + g, e, a, b, edge_id_map, current_edge_id - 1, inserted)); + ++E; + } + + // remove_edge(u, v, g) #if VERBOSE - cerr << "remove_edge(" << vertex_id_map[a] << "," << vertex_id_map[b] << ")" << endl; + cerr << "Testing remove_edge(u, v, g) ..." << endl; + is_failed = false; #endif - graph_traits::edges_size_type old_E = num_edges(g); - remove_edge(e, g); - + for (i = 0; i < 2; ++i) + { #if VERBOSE - print_graph(g, vertex_id_map); - // print_in_edges(g, vertex_id_map); - print_edges(g, vertex_id_map); + print_edges(g, vertex_id_map); #endif + Vertex a, b; - is_failed = is_failed || old_E != num_edges(g) + 1 - || num_edges(g) != count_edges(g); - if (is_failed) - break; - } - if ( is_failed ) { - ret = -1; + Edge e = random_edge(g, gen); + boost::tie(a, b) = boost::incident(e, g); + --E; #if VERBOSE - cerr << " Failed."<< endl; + cerr << "remove_edge(" << vertex_id_map[a] << "," + << vertex_id_map[b] << ")" << endl; #endif - } else { + remove_edge(a, b, g); #if VERBOSE - cerr << " Passed."<< endl; + print_graph(g, vertex_id_map); + // print_in_edges(g, vertex_id_map); + print_edges(g, vertex_id_map); #endif - } - - // add_vertex -#if VERBOSE - cerr << "Testing add_vertex ..." << endl; is_failed = false; -#endif - old_N = num_vertices(g); - graph_traits::vertex_descriptor vid = add_vertex(g), - vidp1 = add_vertex(g); - vertex_id_map[vid] = current_vertex_id++; - vertex_id_map[vidp1] = current_vertex_id++; + BOOST_ASSERT(!is_adjacent(g, a, b)); + BOOST_ASSERT(!in_edge_set(g, a, b)); + BOOST_ASSERT(num_edges(g) == count_edges(g)); + } #if VERBOSE - print_vertices(g,vertex_id_map); - print_graph(g,vertex_id_map); - // print_in_edges(g,vertex_id_map); - print_edges(g,vertex_id_map); + cerr << "Testing remove_edge(e, g) ..." << endl; + is_failed = false; #endif - // make sure the two added vertices are in the graph's vertex set - { - if (!in_vertex_set(g, vid)) { + for (i = 0; i < 2; ++i) + { #if VERBOSE - cerr << " Failed, " << vertex_id_map[vid] << " not in vertices(g)" << endl; + print_edges(g, vertex_id_map); #endif - ret = -1; - break; - } - if (!in_vertex_set(g, vidp1)) { + Vertex a, b; + Edge e = random_edge(g, gen); + boost::tie(a, b) = boost::incident(e, g); + --E; #if VERBOSE - cerr << " Failed, " << vertex_id_map[vidp1] << " not in vertices(g)" << endl; + cerr << "remove_edge(" << vertex_id_map[a] << "," + << vertex_id_map[b] << ")" << endl; #endif - ret = -1; - break; - } - } + typename graph_traits< Graph >::edges_size_type old_E + = num_edges(g); + remove_edge(e, g); - // make sure the vertices do not have any out edges yet - { - graph_traits::out_edge_iterator e, e_end; - boost::tie(e,e_end) = out_edges(vid,g); - if (e != e_end) { #if VERBOSE - cerr << " Failed, " << vertex_id_map[vid] - << " should not have any out-edges yet" << endl; + print_graph(g, vertex_id_map); + // print_in_edges(g, vertex_id_map); + print_edges(g, vertex_id_map); #endif - ret = -1; - break; - } - boost::tie(e,e_end) = out_edges(vidp1,g); - if (e != e_end) { -#if VERBOSE - cerr << " Failed, " << vertex_id_map[vidp1] - << " should not have any out-edges yet" << endl; -#endif - ret = -1; - break; - } - } - // make sure the vertices do not yet appear in any of the edges - { - graph_traits::edge_iterator e, e_end; - for (boost::tie(e, e_end) = edges(g); e != e_end; ++e) { - if (source(*e,g) == vid || target(*e,g) == vid) { -#if VERBOSE - cerr << " Failed, " << vertex_id_map[vid] - << " should not have any edges" << endl; -#endif - ret = -1; - break; + BOOST_ASSERT(old_E == num_edges(g) + 1); + BOOST_ASSERT(num_edges(g) == count_edges(g)); } - if (source(*e,g) == vidp1 || target(*e,g) == vidp1) { -#if VERBOSE - cerr << " Failed, " << vertex_id_map[vidp1] - << " should not have any edges" << endl; -#endif - ret = -1; - break; + + // add_vertex +#if VERBOSE + cerr << "Testing add_vertex ..." << endl; + is_failed = false; +#endif + old_N = num_vertices(g); + typename graph_traits< Graph >::vertex_descriptor vid = add_vertex(g), + vidp1 = add_vertex(g); + vertex_id_map[vid] = current_vertex_id++; + vertex_id_map[vidp1] = current_vertex_id++; + +#if VERBOSE + print_vertices(g, vertex_id_map); + print_graph(g, vertex_id_map); + // print_in_edges(g,vertex_id_map); + print_edges(g, vertex_id_map); +#endif + // make sure the two added vertices are in the graph's vertex set + BOOST_ASSERT(in_vertex_set(g, vid)); + BOOST_ASSERT(in_vertex_set(g, vidp1)); + + // make sure the vertices do not have any out edges yet + typename graph_traits< Graph >::out_edge_iterator e, e_end; + boost::tie(e, e_end) = out_edges(vid, g); + BOOST_ASSERT(e == e_end); + boost::tie(e, e_end) = out_edges(vidp1, g); + BOOST_ASSERT(e == e_end); + + // make sure the vertices do not yet appear in any of the edges + { + typename graph_traits< Graph >::edge_iterator e, e_end; + for (boost::tie(e, e_end) = edges(g); e != e_end; ++e) + { + BOOST_ASSERT(source(*e, g) != vid); + BOOST_ASSERT(target(*e, g) != vid); + BOOST_ASSERT(source(*e, g) != vidp1); + BOOST_ASSERT(target(*e, g) != vidp1); + } } - } - } - // Make sure num_vertices(g) has been updated - N = num_vertices(g); - if ( (N - 2) != old_N ) { - ret = -1; -#if VERBOSE - cerr << " Failed. N = " << N - << " but should be " << old_N + 2 << endl; -#endif - break; - } else { -#if VERBOSE - cerr << " Passed."<< endl; -#endif - } - // add_edge again -#if VERBOSE - cerr << "Testing add_edge after add_vertex ..." << endl; is_failed = false; -#endif + // Make sure num_vertices(g) has been updated + N = num_vertices(g); + BOOST_ASSERT((N - 2) == old_N); - for (i=0; i<2; ++i) { - Vertex a = random_vertex(g, gen), b = random_vertex(g, gen); - while ( a == vid ) a = random_vertex(g, gen); - while ( b == vidp1 ) b = random_vertex(g, gen); - Edge e; - bool inserted; + // add_edge again #if VERBOSE - cerr << "add_edge(" << vertex_id_map[vid] << "," << vertex_id_map[a] <<")" << endl; + cerr << "Testing add_edge after add_vertex ..." << endl; + is_failed = false; #endif - boost::tie(e,inserted) = add_edge(vid, a, EdgeID(current_edge_id++), g); - - if (! check_edge_added(g, e, vid, a, edge_id_map, current_edge_id - 1, - inserted)) { - ret = -1; - break; - } + for (i = 0; i < 2; ++i) + { + Vertex a = random_vertex(g, gen), b = random_vertex(g, gen); + while (a == vid) + a = random_vertex(g, gen); + while (b == vidp1) + b = random_vertex(g, gen); + Edge e; + bool inserted; #if VERBOSE - cerr << "add_edge(" << vertex_id_map[b] << "," << vertex_id_map[vidp1] <<")" << endl; -#endif - // add_edge without plugin - boost::tie(e,inserted) = add_edge(b, vidp1, g); - if (inserted) - edge_id_map[e] = current_edge_id; - ++current_edge_id; - - if (! check_edge_added(g, e, b, vidp1, edge_id_map, - current_edge_id - 1, inserted)) { - ret = -1; - break; - } - } - - // clear_vertex - Vertex c = random_vertex(g, gen); -#if VERBOSE - cerr << "Testing clear vertex ..." << endl; is_failed = false; - print_graph(g, vertex_id_map); - // print_in_edges(g, vertex_id_map); - cerr << "clearing vertex " << vertex_id_map[c] << endl; -#endif - clear_vertex(c, g); -#if VERBOSE - print_graph(g, vertex_id_map); - // print_in_edges(g, vertex_id_map); - print_edges(g, vertex_id_map); -#endif - if (check_vertex_cleared(g, c, vertex_id_map) && num_edges(g) == count_edges(g)) { -#if VERBOSE - cerr << " Passed."<< endl; -#endif - } else { -#if VERBOSE - cerr << "**** Failed" << endl; + cerr << "add_edge(" << vertex_id_map[vid] << "," << vertex_id_map[a] + << ")" << endl; #endif - ret = -1; - break; - } + boost::tie(e, inserted) + = add_edge(vid, a, EdgeID(current_edge_id++), g); + + BOOST_ASSERT(check_edge_added( + g, e, vid, a, edge_id_map, current_edge_id - 1, inserted)); #if VERBOSE - cerr << "Testing remove vertex ..." << endl; is_failed = false; - cerr << "removing vertex " << vertex_id_map[c] << endl; + cerr << "add_edge(" << vertex_id_map[b] << "," + << vertex_id_map[vidp1] << ")" << endl; #endif + // add_edge without plugin + boost::tie(e, inserted) = add_edge(b, vidp1, g); + if (inserted) + edge_id_map[e] = current_edge_id; + ++current_edge_id; + + BOOST_ASSERT(check_edge_added( + g, e, b, vidp1, edge_id_map, current_edge_id - 1, inserted)); + } - old_N = num_vertices(g); - remove_vertex(c, g); + // clear_vertex + Vertex c = random_vertex(g, gen); #if VERBOSE - print_graph(g,vertex_id_map); - // print_in_edges(g,vertex_id_map); - print_edges(g, vertex_id_map); + cerr << "Testing clear vertex ..." << endl; + is_failed = false; + print_graph(g, vertex_id_map); + // print_in_edges(g, vertex_id_map); + cerr << "clearing vertex " << vertex_id_map[c] << endl; #endif - // can't check in_vertex_set here because the vertex_descriptor c - // is no longer valid, we'll just make sure the vertex set has - // one fewer vertex - { - graph_traits::vertex_iterator v, v_end; - boost::tie(v, v_end) = vertices(g); - for (N = 0; v != v_end; ++v) ++N; // N = std::distance(v, v_end); - if (N != old_N - 1) { - ret = -1; + clear_vertex(c, g); #if VERBOSE - cerr << " Failed. N = " << N - << " but should be " << old_N - 1 << endl; + print_graph(g, vertex_id_map); + // print_in_edges(g, vertex_id_map); + print_edges(g, vertex_id_map); #endif - } - } + BOOST_ASSERT(check_vertex_cleared(g, c, vertex_id_map) + && num_edges(g) == count_edges(g)); - N = num_vertices(g); - if (N != old_N - 1) { - ret = -1; #if VERBOSE - cerr << " Failed. N = " << N - << " but should be " << old_N - 1 << endl; + cerr << "Testing remove vertex ..." << endl; + is_failed = false; + cerr << "removing vertex " << vertex_id_map[c] << endl; #endif - } else { + + old_N = num_vertices(g); + remove_vertex(c, g); #if VERBOSE - cerr << " Passed."<< endl; + print_graph(g, vertex_id_map); + // print_in_edges(g,vertex_id_map); + print_edges(g, vertex_id_map); #endif + // can't check in_vertex_set here because the vertex_descriptor c + // is no longer valid, we'll just make sure the vertex set has + // one fewer vertex + { + typename graph_traits< Graph >::vertex_iterator v, v_end; + boost::tie(v, v_end) = vertices(g); + for (N = 0; v != v_end; ++v) + ++N; // N = std::distance(v, v_end); + BOOST_ASSERT(N == old_N - 1); + } + + N = num_vertices(g); + BOOST_ASSERT(N == old_N - 1); } - } - if (ret == 0) - std::cout << "tests passed" << std::endl; +} + +int main(int, char*[]) +{ - return ret; + test_instance< boost::vecS, boost::bidirectionalS >(); + test_instance< boost::vecS, boost::directedS >(); + test_instance< boost::vecS, boost::undirectedS >(); + test_instance< boost::listS, boost::bidirectionalS >(); + test_instance< boost::listS, boost::directedS >(); + test_instance< boost::listS, boost::undirectedS >(); + test_instance< boost::setS, boost::bidirectionalS >(); + test_instance< boost::setS, boost::directedS >(); + test_instance< boost::setS, boost::undirectedS >(); + + return 0; } diff --git a/test/graph_concepts.cpp b/test/graph_concepts.cpp index c2edc342e..5292d000c 100644 --- a/test/graph_concepts.cpp +++ b/test/graph_concepts.cpp @@ -10,32 +10,39 @@ #include #include -int main(int,char*[]) +int main(int, char*[]) { - using namespace boost; - - // Check graph concepts againt their archetypes - typedef default_constructible_archetype< - sgi_assignable_archetype< equality_comparable_archetype<> > > Vertex; - - typedef incidence_graph_archetype Graph1; - BOOST_CONCEPT_ASSERT(( IncidenceGraphConcept )); - - typedef adjacency_graph_archetype Graph2; - BOOST_CONCEPT_ASSERT(( AdjacencyGraphConcept )); - - typedef vertex_list_graph_archetype Graph3; - BOOST_CONCEPT_ASSERT(( VertexListGraphConcept )); - - BOOST_CONCEPT_ASSERT(( ColorValueConcept )); - - typedef incidence_graph_archetype G; - typedef property_graph_archetype - Graph4; - BOOST_CONCEPT_ASSERT(( PropertyGraphConcept )); - - return 0; + using namespace boost; + + // Check graph concepts againt their archetypes + typedef default_constructible_archetype< + sgi_assignable_archetype< equality_comparable_archetype<> > > + Vertex; + + typedef incidence_graph_archetype< Vertex, directed_tag, + allow_parallel_edge_tag > + Graph1; + BOOST_CONCEPT_ASSERT((IncidenceGraphConcept< Graph1 >)); + + typedef adjacency_graph_archetype< Vertex, directed_tag, + allow_parallel_edge_tag > + Graph2; + BOOST_CONCEPT_ASSERT((AdjacencyGraphConcept< Graph2 >)); + + typedef vertex_list_graph_archetype< Vertex, directed_tag, + allow_parallel_edge_tag > + Graph3; + BOOST_CONCEPT_ASSERT((VertexListGraphConcept< Graph3 >)); + + BOOST_CONCEPT_ASSERT((ColorValueConcept< color_value_archetype >)); + + typedef incidence_graph_archetype< Vertex, directed_tag, + allow_parallel_edge_tag > + G; + typedef property_graph_archetype< G, vertex_color_t, color_value_archetype > + Graph4; + BOOST_CONCEPT_ASSERT( + (PropertyGraphConcept< Graph4, Vertex, vertex_color_t >)); + + return 0; } diff --git a/test/graph_test.hpp b/test/graph_test.hpp index 69d89f34f..4f8c29716 100644 --- a/test/graph_test.hpp +++ b/test/graph_test.hpp @@ -11,7 +11,7 @@ #define BOOST_GRAPH_TEST_HPP #include -#include +#include #include #include #include @@ -20,187 +20,205 @@ #include #include +// UNDER CONSTRUCTION -// UNDER CONSTRUCTION - -namespace boost { - - template - struct graph_test - { - - typedef typename graph_traits::vertex_descriptor vertex_t; - typedef typename graph_traits::edge_descriptor edge_t; - typedef typename graph_traits::vertices_size_type v_size_t; - typedef typename graph_traits::degree_size_type deg_size_t; - typedef typename graph_traits::edges_size_type e_size_t; - typedef typename graph_traits::out_edge_iterator out_edge_iter; - typedef typename property_map::type index_map_t; - typedef iterator_property_map::iterator, - index_map_t,vertex_t,vertex_t&> IsoMap; - - struct ignore_vertex { - ignore_vertex() { } - ignore_vertex(vertex_t v) : v(v) { } - bool operator()(vertex_t x) const { return x != v; } - vertex_t v; +namespace boost +{ + +template < typename Graph > struct graph_test +{ + + typedef typename graph_traits< Graph >::vertex_descriptor vertex_t; + typedef typename graph_traits< Graph >::edge_descriptor edge_t; + typedef typename graph_traits< Graph >::vertices_size_type v_size_t; + typedef typename graph_traits< Graph >::degree_size_type deg_size_t; + typedef typename graph_traits< Graph >::edges_size_type e_size_t; + typedef typename graph_traits< Graph >::out_edge_iterator out_edge_iter; + typedef typename property_map< Graph, vertex_index_t >::type index_map_t; + typedef iterator_property_map< typename std::vector< vertex_t >::iterator, + index_map_t, vertex_t, vertex_t& > + IsoMap; + + struct ignore_vertex + { + ignore_vertex() {} + ignore_vertex(vertex_t v) : v(v) {} + bool operator()(vertex_t x) const { return x != v; } + vertex_t v; }; - struct ignore_edge { - ignore_edge() { } - ignore_edge(edge_t e) : e(e) { } - bool operator()(edge_t x) const { return x != e; } - edge_t e; + struct ignore_edge + { + ignore_edge() {} + ignore_edge(edge_t e) : e(e) {} + bool operator()(edge_t x) const { return x != e; } + edge_t e; }; - struct ignore_edges { - ignore_edges(vertex_t s, vertex_t t, const Graph& g) - : s(s), t(t), g(g) { } - bool operator()(edge_t x) const { - return !(source(x, g) == s && target(x, g) == t); - } - vertex_t s; vertex_t t; const Graph& g; + struct ignore_edges + { + ignore_edges(vertex_t s, vertex_t t, const Graph& g) : s(s), t(t), g(g) + { + } + bool operator()(edge_t x) const + { + return !(source(x, g) == s && target(x, g) == t); + } + vertex_t s; + vertex_t t; + const Graph& g; }; //========================================================================= // Traversal Operations - void test_incidence_graph - (const std::vector& vertex_set, - const std::vector< std::pair >& edge_set, + void test_incidence_graph(const std::vector< vertex_t >& vertex_set, + const std::vector< std::pair< vertex_t, vertex_t > >& edge_set, const Graph& g) { - typedef typename std::vector::const_iterator vertex_iter; - typedef typename std::vector< std::pair > - ::const_iterator edge_iter; - typedef typename graph_traits::out_edge_iterator out_edge_iter; - - for (vertex_iter ui = vertex_set.begin(); ui != vertex_set.end(); ++ui) { - vertex_t u = *ui; - std::vector adj; - for (edge_iter e = edge_set.begin(); e != edge_set.end(); ++e) - if (e->first == u) - adj.push_back(e->second); - - std::pair p = out_edges(u, g); - BOOST_CHECK(out_degree(u, g) == adj.size()); - BOOST_CHECK(deg_size_t(std::distance(p.first, p.second)) - == out_degree(u, g)); - for (; p.first != p.second; ++p.first) { - edge_t e = *p.first; - BOOST_CHECK(source(e, g) == u); - BOOST_CHECK(container_contains(adj, target(e, g)) == true); + typedef typename std::vector< vertex_t >::const_iterator vertex_iter; + typedef typename std::vector< + std::pair< vertex_t, vertex_t > >::const_iterator edge_iter; + typedef typename graph_traits< Graph >::out_edge_iterator out_edge_iter; + + for (vertex_iter ui = vertex_set.begin(); ui != vertex_set.end(); ++ui) + { + vertex_t u = *ui; + std::vector< vertex_t > adj; + for (edge_iter e = edge_set.begin(); e != edge_set.end(); ++e) + if (e->first == u) + adj.push_back(e->second); + + std::pair< out_edge_iter, out_edge_iter > p = out_edges(u, g); + BOOST_TEST(out_degree(u, g) == adj.size()); + BOOST_TEST(deg_size_t(std::distance(p.first, p.second)) + == out_degree(u, g)); + for (; p.first != p.second; ++p.first) + { + edge_t e = *p.first; + BOOST_TEST(source(e, g) == u); + BOOST_TEST(container_contains(adj, target(e, g)) == true); + } } - } } - void test_bidirectional_graph - (const std::vector& vertex_set, - const std::vector< std::pair >& edge_set, - const Graph& g) + void test_bidirectional_graph(const std::vector< vertex_t >& vertex_set, + const std::vector< std::pair< vertex_t, vertex_t > >& edge_set, + const Graph& g) { - typedef typename std::vector::const_iterator vertex_iter; - typedef typename std::vector< std::pair > - ::const_iterator edge_iter; - typedef typename graph_traits::in_edge_iterator in_edge_iter; - - for (vertex_iter vi = vertex_set.begin(); vi != vertex_set.end(); ++vi) { - vertex_t v = *vi; - std::vector inv_adj; - for (edge_iter e = edge_set.begin(); e != edge_set.end(); ++e) - if (e->second == v) - inv_adj.push_back(e->first); - - std::pair p = in_edges(v, g); - BOOST_CHECK(in_degree(v, g) == inv_adj.size()); - BOOST_CHECK(deg_size_t(std::distance(p.first, p.second)) - == in_degree(v, g)); - for (; p.first != p.second; ++p.first) { - edge_t e = *p.first; - BOOST_CHECK(target(e, g) == v); - BOOST_CHECK(container_contains(inv_adj, source(e, g)) == true); + typedef typename std::vector< vertex_t >::const_iterator vertex_iter; + typedef typename std::vector< + std::pair< vertex_t, vertex_t > >::const_iterator edge_iter; + typedef typename graph_traits< Graph >::in_edge_iterator in_edge_iter; + + for (vertex_iter vi = vertex_set.begin(); vi != vertex_set.end(); ++vi) + { + vertex_t v = *vi; + std::vector< vertex_t > inv_adj; + for (edge_iter e = edge_set.begin(); e != edge_set.end(); ++e) + if (e->second == v) + inv_adj.push_back(e->first); + + std::pair< in_edge_iter, in_edge_iter > p = in_edges(v, g); + BOOST_TEST(in_degree(v, g) == inv_adj.size()); + BOOST_TEST(deg_size_t(std::distance(p.first, p.second)) + == in_degree(v, g)); + for (; p.first != p.second; ++p.first) + { + edge_t e = *p.first; + BOOST_TEST(target(e, g) == v); + BOOST_TEST(container_contains(inv_adj, source(e, g)) == true); + } } - } } - void test_adjacency_graph - (const std::vector& vertex_set, - const std::vector< std::pair >& edge_set, - const Graph& g) + void test_adjacency_graph(const std::vector< vertex_t >& vertex_set, + const std::vector< std::pair< vertex_t, vertex_t > >& edge_set, + const Graph& g) { - typedef typename std::vector::const_iterator vertex_iter; - typedef typename std::vector > - ::const_iterator edge_iter; - typedef typename graph_traits::adjacency_iterator adj_iter; - - for (vertex_iter ui = vertex_set.begin(); ui != vertex_set.end(); ++ui) { - vertex_t u = *ui; - std::vector adj; - for (edge_iter e = edge_set.begin(); e != edge_set.end(); ++e) - if (e->first == u) - adj.push_back(e->second); - - std::pair p = adjacent_vertices(u, g); - BOOST_CHECK(deg_size_t(std::distance(p.first, p.second)) == adj.size()); - for (; p.first != p.second; ++p.first) { - vertex_t v = *p.first; - BOOST_CHECK(container_contains(adj, v) == true); + typedef typename std::vector< vertex_t >::const_iterator vertex_iter; + typedef typename std::vector< + std::pair< vertex_t, vertex_t > >::const_iterator edge_iter; + typedef typename graph_traits< Graph >::adjacency_iterator adj_iter; + + for (vertex_iter ui = vertex_set.begin(); ui != vertex_set.end(); ++ui) + { + vertex_t u = *ui; + std::vector< vertex_t > adj; + for (edge_iter e = edge_set.begin(); e != edge_set.end(); ++e) + if (e->first == u) + adj.push_back(e->second); + + std::pair< adj_iter, adj_iter > p = adjacent_vertices(u, g); + BOOST_TEST( + deg_size_t(std::distance(p.first, p.second)) == adj.size()); + for (; p.first != p.second; ++p.first) + { + vertex_t v = *p.first; + BOOST_TEST(container_contains(adj, v) == true); + } } - } - } + } - void test_vertex_list_graph - (const std::vector& vertex_set, const Graph& g) + void test_vertex_list_graph( + const std::vector< vertex_t >& vertex_set, const Graph& g) { - typedef typename graph_traits::vertex_iterator v_iter; - std::pair p = vertices(g); - BOOST_CHECK(num_vertices(g) == vertex_set.size()); - v_size_t n = (size_t)std::distance(p.first, p.second); - BOOST_CHECK(n == num_vertices(g)); - for (; p.first != p.second; ++p.first) { - vertex_t v = *p.first; - BOOST_CHECK(container_contains(vertex_set, v) == true); - } + typedef typename graph_traits< Graph >::vertex_iterator v_iter; + std::pair< v_iter, v_iter > p = vertices(g); + BOOST_TEST(num_vertices(g) == vertex_set.size()); + v_size_t n = (size_t)std::distance(p.first, p.second); + BOOST_TEST(n == num_vertices(g)); + for (; p.first != p.second; ++p.first) + { + vertex_t v = *p.first; + BOOST_TEST(container_contains(vertex_set, v) == true); + } } - void test_edge_list_graph - (const std::vector& vertex_set, - const std::vector< std::pair >& edge_set, - const Graph& g) + void test_edge_list_graph(const std::vector< vertex_t >& vertex_set, + const std::vector< std::pair< vertex_t, vertex_t > >& edge_set, + const Graph& g) { - typedef typename graph_traits::edge_iterator e_iter; - std::pair p = edges(g); - BOOST_CHECK(num_edges(g) == edge_set.size()); - e_size_t m = std::distance(p.first, p.second); - BOOST_CHECK(m == num_edges(g)); - for (; p.first != p.second; ++p.first) { - edge_t e = *p.first; - BOOST_CHECK(find_if(edge_set, connects(source(e, g), target(e, g), g)) != boost::end(edge_set)); - BOOST_CHECK(container_contains(vertex_set, source(e, g)) == true); - BOOST_CHECK(container_contains(vertex_set, target(e, g)) == true); - } + typedef typename graph_traits< Graph >::edge_iterator e_iter; + std::pair< e_iter, e_iter > p = edges(g); + BOOST_TEST(num_edges(g) == edge_set.size()); + e_size_t m = std::distance(p.first, p.second); + BOOST_TEST(m == num_edges(g)); + for (; p.first != p.second; ++p.first) + { + edge_t e = *p.first; + BOOST_TEST( + find_if(edge_set, connects(source(e, g), target(e, g), g)) + != boost::end(edge_set)); + BOOST_TEST(container_contains(vertex_set, source(e, g)) == true); + BOOST_TEST(container_contains(vertex_set, target(e, g)) == true); + } } - void test_adjacency_matrix - (const std::vector& vertex_set, - const std::vector< std::pair >& edge_set, - const Graph& g) + void test_adjacency_matrix(const std::vector< vertex_t >& vertex_set, + const std::vector< std::pair< vertex_t, vertex_t > >& edge_set, + const Graph& g) { - std::pair p; - for (typename std::vector > - ::const_iterator i = edge_set.begin(); - i != edge_set.end(); ++i) { - p = edge(i->first, i->second, g); - BOOST_CHECK(p.second == true); - BOOST_CHECK(source(p.first, g) == i->first); - BOOST_CHECK(target(p.first, g) == i->second); - } - typename std::vector::const_iterator j, k; - for (j = vertex_set.begin(); j != vertex_set.end(); ++j) - for (k = vertex_set.begin(); k != vertex_set.end(); ++k) { - p = edge(*j, *k, g); - if (p.second == true) - BOOST_CHECK(find_if(edge_set, - connects(source(p.first, g), target(p.first, g), g)) != boost::end(edge_set)); + std::pair< edge_t, bool > p; + for (typename std::vector< + std::pair< vertex_t, vertex_t > >::const_iterator i + = edge_set.begin(); + i != edge_set.end(); ++i) + { + p = edge(i->first, i->second, g); + BOOST_TEST(p.second == true); + BOOST_TEST(source(p.first, g) == i->first); + BOOST_TEST(target(p.first, g) == i->second); } + typename std::vector< vertex_t >::const_iterator j, k; + for (j = vertex_set.begin(); j != vertex_set.end(); ++j) + for (k = vertex_set.begin(); k != vertex_set.end(); ++k) + { + p = edge(*j, *k, g); + if (p.second == true) + BOOST_TEST( + find_if(edge_set, + connects(source(p.first, g), target(p.first, g), g)) + != boost::end(edge_set)); + } } //========================================================================= @@ -208,174 +226,177 @@ namespace boost { void test_add_vertex(Graph& g) { - Graph cpy; - std::vector iso_vec(num_vertices(g)); - IsoMap iso_map(iso_vec.begin(), get(vertex_index, g)); - copy_graph(g, cpy, orig_to_copy(iso_map)); + Graph cpy; + std::vector< vertex_t > iso_vec(num_vertices(g)); + IsoMap iso_map(iso_vec.begin(), get(vertex_index, g)); + copy_graph(g, cpy, orig_to_copy(iso_map)); + + BOOST_TEST((verify_isomorphism(g, cpy, iso_map))); - BOOST_CHECK((verify_isomorphism(g, cpy, iso_map))); + vertex_t v = add_vertex(g); - vertex_t v = add_vertex(g); - - BOOST_CHECK(num_vertices(g) == num_vertices(cpy) + 1); + BOOST_TEST(num_vertices(g) == num_vertices(cpy) + 1); - BOOST_CHECK(out_degree(v, g) == 0); + BOOST_TEST(out_degree(v, g) == 0); - // Make sure the rest of the graph stayed the same - BOOST_CHECK((verify_isomorphism - (make_filtered_graph(g, keep_all(), ignore_vertex(v)), cpy, - iso_map))); + // Make sure the rest of the graph stayed the same + BOOST_TEST((verify_isomorphism( + make_filtered_graph(g, keep_all(), ignore_vertex(v)), cpy, + iso_map))); } - + void test_add_edge(vertex_t u, vertex_t v, Graph& g) { - Graph cpy; - std::vector iso_vec(num_vertices(g)); - IsoMap iso_map(iso_vec.begin(), get(vertex_index, g)); - copy_graph(g, cpy, orig_to_copy(iso_map)); - - bool parallel_edge_exists = container_contains(adjacent_vertices(u, g), v); - - std::pair p = add_edge(u, v, g); - edge_t e = p.first; - bool added = p.second; - - if (is_undirected(g) && u == v) // self edge - BOOST_CHECK(added == false); - else if (parallel_edge_exists) - BOOST_CHECK(allows_parallel_edges(g) && added == true - || !allows_parallel_edges(g) && added == false); - else - BOOST_CHECK(added == true); - - if (p.second == true) { // edge added - BOOST_CHECK(num_edges(g) == num_edges(cpy) + 1); - - BOOST_CHECK(container_contains(out_edges(u, g), e) == true); - - BOOST_CHECK((verify_isomorphism - (make_filtered_graph(g, ignore_edge(e)), cpy, iso_map))); - } - else { // edge not added - if (! (is_undirected(g) && u == v)) { - // e should be a parallel edge - BOOST_CHECK(source(e, g) == u); - BOOST_CHECK(target(e, g) == v); + Graph cpy; + std::vector< vertex_t > iso_vec(num_vertices(g)); + IsoMap iso_map(iso_vec.begin(), get(vertex_index, g)); + copy_graph(g, cpy, orig_to_copy(iso_map)); + + bool parallel_edge_exists + = container_contains(adjacent_vertices(u, g), v); + + std::pair< edge_t, bool > p = add_edge(u, v, g); + edge_t e = p.first; + bool added = p.second; + + if (is_undirected(g) && u == v) // self edge + BOOST_TEST(added == false); + else if (parallel_edge_exists) + BOOST_TEST(allows_parallel_edges(g) && added == true + || !allows_parallel_edges(g) && added == false); + else + BOOST_TEST(added == true); + + if (p.second == true) + { // edge added + BOOST_TEST(num_edges(g) == num_edges(cpy) + 1); + + BOOST_TEST(container_contains(out_edges(u, g), e) == true); + + BOOST_TEST((verify_isomorphism( + make_filtered_graph(g, ignore_edge(e)), cpy, iso_map))); + } + else + { // edge not added + if (!(is_undirected(g) && u == v)) + { + // e should be a parallel edge + BOOST_TEST(source(e, g) == u); + BOOST_TEST(target(e, g) == v); + } + // The graph should not be changed. + BOOST_TEST((verify_isomorphism(g, cpy, iso_map))); } - // The graph should not be changed. - BOOST_CHECK((verify_isomorphism(g, cpy, iso_map))); - } } // test_add_edge() - void test_remove_edge(vertex_t u, vertex_t v, Graph& g) { - Graph cpy; - std::vector iso_vec(num_vertices(g)); - IsoMap iso_map(iso_vec.begin(), get(vertex_index, g)); - copy_graph(g, cpy, orig_to_copy(iso_map)); - - deg_size_t occurances = count(adjacent_vertices(u, g), v); - - remove_edge(u, v, g); - - BOOST_CHECK(num_edges(g) + occurances == num_edges(cpy)); - BOOST_CHECK((verify_isomorphism - (g, make_filtered_graph(cpy, ignore_edges(u,v,cpy)), - iso_map))); + Graph cpy; + std::vector< vertex_t > iso_vec(num_vertices(g)); + IsoMap iso_map(iso_vec.begin(), get(vertex_index, g)); + copy_graph(g, cpy, orig_to_copy(iso_map)); + + deg_size_t occurances = count(adjacent_vertices(u, g), v); + + remove_edge(u, v, g); + + BOOST_TEST(num_edges(g) + occurances == num_edges(cpy)); + BOOST_TEST((verify_isomorphism( + g, make_filtered_graph(cpy, ignore_edges(u, v, cpy)), iso_map))); } void test_remove_edge(edge_t e, Graph& g) { - Graph cpy; - std::vector iso_vec(num_vertices(g)); - IsoMap iso_map(iso_vec.begin(), get(vertex_index, g)); - copy_graph(g, cpy, orig_to_copy(iso_map)); - - vertex_t u = source(e, g), v = target(e, g); - deg_size_t occurances = count(adjacent_vertices(u, g), v); - - remove_edge(e, g); - - BOOST_CHECK(num_edges(g) + 1 == num_edges(cpy)); - BOOST_CHECK(count(adjacent_vertices(u, g), v) + 1 == occurances); - BOOST_CHECK((verify_isomorphism - (g, make_filtered_graph(cpy, ignore_edge(e)), - iso_map))); + Graph cpy; + std::vector< vertex_t > iso_vec(num_vertices(g)); + IsoMap iso_map(iso_vec.begin(), get(vertex_index, g)); + copy_graph(g, cpy, orig_to_copy(iso_map)); + + vertex_t u = source(e, g), v = target(e, g); + deg_size_t occurances = count(adjacent_vertices(u, g), v); + + remove_edge(e, g); + + BOOST_TEST(num_edges(g) + 1 == num_edges(cpy)); + BOOST_TEST(count(adjacent_vertices(u, g), v) + 1 == occurances); + BOOST_TEST((verify_isomorphism( + g, make_filtered_graph(cpy, ignore_edge(e)), iso_map))); } void test_clear_vertex(vertex_t v, Graph& g) { - Graph cpy; - std::vector iso_vec(num_vertices(g)); - IsoMap iso_map(iso_vec.begin(), get(vertex_index, g)); - copy_graph(g, cpy, orig_to_copy(iso_map)); - - clear_vertex(v, g); - - BOOST_CHECK(out_degree(v, g) == 0); - BOOST_CHECK(num_vertices(g) == num_vertices(cpy)); - BOOST_CHECK((verify_isomorphism - (g, make_filtered_graph(cpy, keep_all(), ignore_vertex(v)), - iso_map))); + Graph cpy; + std::vector< vertex_t > iso_vec(num_vertices(g)); + IsoMap iso_map(iso_vec.begin(), get(vertex_index, g)); + copy_graph(g, cpy, orig_to_copy(iso_map)); + + clear_vertex(v, g); + + BOOST_TEST(out_degree(v, g) == 0); + BOOST_TEST(num_vertices(g) == num_vertices(cpy)); + BOOST_TEST((verify_isomorphism(g, + make_filtered_graph(cpy, keep_all(), ignore_vertex(v)), iso_map))); } //========================================================================= // Property Map - template - void test_readable_vertex_property_graph - (const std::vector& vertex_prop, PropertyTag tag, const Graph& g) + template < typename PropVal, typename PropertyTag > + void test_readable_vertex_property_graph( + const std::vector< PropVal >& vertex_prop, PropertyTag tag, + const Graph& g) { - typedef typename property_map::const_type const_Map; - const_Map pmap = get(tag, g); - typename std::vector::const_iterator i = vertex_prop.begin(); - - for (typename boost::graph_traits::vertex_iterator - bgl_first_9 = vertices(g).first, bgl_last_9 = vertices(g).second; - bgl_first_9 != bgl_last_9; bgl_first_9 = bgl_last_9) - for (typename boost::graph_traits::vertex_descriptor v; - bgl_first_9 != bgl_last_9 ? (v = *bgl_first_9, true) : false; - ++bgl_first_9) { - //BGL_FORALL_VERTICES_T(v, g, Graph) { - typename property_traits::value_type - pval1 = get(pmap, v), pval2 = get(tag, g, v); - BOOST_CHECK(pval1 == pval2); - BOOST_CHECK(pval1 == *i++); - } + typedef + typename property_map< Graph, PropertyTag >::const_type const_Map; + const_Map pmap = get(tag, g); + typename std::vector< PropVal >::const_iterator i = vertex_prop.begin(); + + for (typename boost::graph_traits< Graph >::vertex_iterator bgl_first_9 + = vertices(g).first, + bgl_last_9 = vertices(g).second; + bgl_first_9 != bgl_last_9; bgl_first_9 = bgl_last_9) + for (typename boost::graph_traits< Graph >::vertex_descriptor v; + bgl_first_9 != bgl_last_9 ? (v = *bgl_first_9, true) : false; + ++bgl_first_9) + { + // BGL_FORALL_VERTICES_T(v, g, Graph) { + typename property_traits< const_Map >::value_type pval1 + = get(pmap, v), + pval2 = get(tag, g, v); + BOOST_TEST(pval1 == pval2); + BOOST_TEST(pval1 == *i++); + } } - template - void test_vertex_property_graph - (const std::vector& vertex_prop, PropertyTag tag, Graph& g) + template < typename PropVal, typename PropertyTag > + void test_vertex_property_graph( + const std::vector< PropVal >& vertex_prop, PropertyTag tag, Graph& g) { - typedef typename property_map::type PMap; - PMap pmap = get(tag, g); - typename std::vector::const_iterator i = vertex_prop.begin(); - for (typename boost::graph_traits::vertex_iterator - bgl_first_9 = vertices(g).first, bgl_last_9 = vertices(g).second; - bgl_first_9 != bgl_last_9; bgl_first_9 = bgl_last_9) - for (typename boost::graph_traits::vertex_descriptor v; - bgl_first_9 != bgl_last_9 ? (v = *bgl_first_9, true) : false; - ++bgl_first_9) - // BGL_FORALL_VERTICES_T(v, g, Graph) - put(pmap, v, *i++); - - test_readable_vertex_property_graph(vertex_prop, tag, g); - - BGL_FORALL_VERTICES_T(v, g, Graph) + typedef typename property_map< Graph, PropertyTag >::type PMap; + PMap pmap = get(tag, g); + typename std::vector< PropVal >::const_iterator i = vertex_prop.begin(); + for (typename boost::graph_traits< Graph >::vertex_iterator bgl_first_9 + = vertices(g).first, + bgl_last_9 = vertices(g).second; + bgl_first_9 != bgl_last_9; bgl_first_9 = bgl_last_9) + for (typename boost::graph_traits< Graph >::vertex_descriptor v; + bgl_first_9 != bgl_last_9 ? (v = *bgl_first_9, true) : false; + ++bgl_first_9) + // BGL_FORALL_VERTICES_T(v, g, Graph) + put(pmap, v, *i++); + + test_readable_vertex_property_graph(vertex_prop, tag, g); + + BGL_FORALL_VERTICES_T(v, g, Graph) put(pmap, v, vertex_prop[0]); - - typename std::vector::const_iterator j = vertex_prop.begin(); - BGL_FORALL_VERTICES_T(v, g, Graph) + + typename std::vector< PropVal >::const_iterator j = vertex_prop.begin(); + BGL_FORALL_VERTICES_T(v, g, Graph) put(tag, g, v, *j++); - - test_readable_vertex_property_graph(vertex_prop, tag, g); - } - - - }; + test_readable_vertex_property_graph(vertex_prop, tag, g); + } +}; } // namespace boost diff --git a/test/graph_type.hpp b/test/graph_type.hpp deleted file mode 100644 index f3597680f..000000000 --- a/test/graph_type.hpp +++ /dev/null @@ -1,48 +0,0 @@ -//======================================================================= -// Copyright 2002 Indiana University. -// Authors: Andrew Lumsdaine, Lie-Quan Lee, Jeremy G. Siek -// -// Distributed under the Boost Software License, Version 1.0. (See -// accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) -//======================================================================= - -// -// The following test permutations are extracted from the old adj_list_test.cpp -// which generated code on the fly, but was never run as part of the regular tests. -// -#if TEST == 1 -#define TEST_TYPE vecS -#define DIRECTED_TYPE bidirectionalS -#elif TEST == 2 -#define TEST_TYPE vecS -#define DIRECTED_TYPE directedS -#elif TEST == 3 -#define TEST_TYPE vecS -#define DIRECTED_TYPE undirectedS -#elif TEST == 4 -#define TEST_TYPE listS -#define DIRECTED_TYPE bidirectionalS -#elif TEST == 5 -#define TEST_TYPE listS -#define DIRECTED_TYPE directedS -#elif TEST == 6 -#define TEST_TYPE listS -#define DIRECTED_TYPE undirectedS -#elif TEST == 7 -#define TEST_TYPE setS -#define DIRECTED_TYPE bidirectionalS -#elif TEST == 8 -#define TEST_TYPE setS -#define DIRECTED_TYPE directedS -#elif TEST == 9 -#define TEST_TYPE setS -#define DIRECTED_TYPE undirectedS -#else -#error "No test combination specified - define macro TEST to the value 1 - 9." -#endif - -#include -typedef boost::adjacency_list, boost::property > Graph; -typedef boost::property VertexId; -typedef boost::property EdgeID; diff --git a/test/graphml_test.cpp b/test/graphml_test.cpp index 617938a25..86bdb4b67 100644 --- a/test/graphml_test.cpp +++ b/test/graphml_test.cpp @@ -28,43 +28,46 @@ #include #include -#include +#include #include #include #include - using namespace std; using namespace boost; -int test_main(int argc, char** argv) +int main(int argc, char** argv) { - typedef adjacency_list >, - property, - property > graph_t; + typedef adjacency_list< vecS, vecS, directedS, + property< vertex_color_t, int, property< vertex_name_t, string > >, + property< edge_weight_t, double >, property< graph_name_t, string > > + graph_t; graph_t g; dynamic_properties dp; - dp.property("foo",get(vertex_color_t(),g)); - dp.property("weight",get(edge_weight_t(),g)); - dp.property("name",get(vertex_name_t(),g)); - boost::ref_property_map - gname(get_property(g, graph_name)); - dp.property("description",gname); + dp.property("foo", get(vertex_color_t(), g)); + dp.property("weight", get(edge_weight_t(), g)); + dp.property("name", get(vertex_name_t(), g)); + boost::ref_property_map< graph_t*, std::string > gname( + get_property(g, graph_name)); + dp.property("description", gname); ifstream ifile(argv[1]); read_graphml(ifile, g, dp); ifile.close(); - BOOST_CHECK(num_vertices(g) == 9); - BOOST_CHECK(num_edges(g) == 9); - BOOST_CHECK(get(vertex_color_t(), g, vertex(2,g)) == 100); - BOOST_CHECK(get(vertex_color_t(), g, vertex(3,g)) == 42); - BOOST_CHECK(std::abs(get(edge_weight_t(), g, edge(vertex(0,g),vertex(1,g),g).first) - 0.0) < 0.00001); - BOOST_CHECK(std::abs(get(edge_weight_t(), g, edge(vertex(1,g),vertex(2,g),g).first) - 0.8) < 0.00001); - BOOST_CHECK(get("description", dp, &g) == "Root graph."); - + BOOST_TEST(num_vertices(g) == 9); + BOOST_TEST(num_edges(g) == 9); + BOOST_TEST(get(vertex_color_t(), g, vertex(2, g)) == 100); + BOOST_TEST(get(vertex_color_t(), g, vertex(3, g)) == 42); + BOOST_TEST(std::abs(get(edge_weight_t(), g, + edge(vertex(0, g), vertex(1, g), g).first) + - 0.0) + < 0.00001); + BOOST_TEST(std::abs(get(edge_weight_t(), g, + edge(vertex(1, g), vertex(2, g), g).first) + - 0.8) + < 0.00001); + BOOST_TEST(get("description", dp, &g) == "Root graph."); ofstream ofile("graphml_test_out.xml"); write_graphml(ofile, g, dp); @@ -72,27 +75,30 @@ int test_main(int argc, char** argv) graph_t g2; dynamic_properties dp2; - dp2.property("foo",get(vertex_color_t(),g2)); - dp2.property("weight",get(edge_weight_t(),g2)); - dp2.property("name",get(vertex_name_t(),g2)); - boost::ref_property_map - gname2(get_property(g2, graph_name)); - dp2.property("description",gname2); + dp2.property("foo", get(vertex_color_t(), g2)); + dp2.property("weight", get(edge_weight_t(), g2)); + dp2.property("name", get(vertex_name_t(), g2)); + boost::ref_property_map< graph_t*, std::string > gname2( + get_property(g2, graph_name)); + dp2.property("description", gname2); ifile.open("graphml_test_out.xml"); read_graphml(ifile, g2, dp2); ifile.close(); - BOOST_CHECK(num_vertices(g) == num_vertices(g2)); - BOOST_CHECK(num_edges(g) == num_edges(g2)); - BOOST_CHECK(get("description", dp, &g) == get("description", dp2, &g2)); + BOOST_TEST(num_vertices(g) == num_vertices(g2)); + BOOST_TEST(num_edges(g) == num_edges(g2)); + BOOST_TEST(get("description", dp, &g) == get("description", dp2, &g2)); - graph_traits::vertex_iterator v, v_end; - for (boost::tie(v,v_end) = vertices(g); v != v_end; ++v) - BOOST_CHECK(get(vertex_color_t(), g, *v) == get(vertex_color_t(), g2, *v)); + graph_traits< graph_t >::vertex_iterator v, v_end; + for (boost::tie(v, v_end) = vertices(g); v != v_end; ++v) + BOOST_TEST( + get(vertex_color_t(), g, *v) == get(vertex_color_t(), g2, *v)); - graph_traits::edge_iterator e, e_end; - for (boost::tie(e,e_end) = edges(g); e != e_end; ++e) - BOOST_CHECK(std::abs(get(edge_weight_t(), g, *e) - get(edge_weight_t(), g2, *e)) < 0.00001); + graph_traits< graph_t >::edge_iterator e, e_end; + for (boost::tie(e, e_end) = edges(g); e != e_end; ++e) + BOOST_TEST( + std::abs(get(edge_weight_t(), g, *e) - get(edge_weight_t(), g2, *e)) + < 0.00001); - return 0; + return boost::report_errors(); } diff --git a/test/graphml_test.xml b/test/graphml_test.xml index 467d29bbd..1933b1f20 100644 --- a/test/graphml_test.xml +++ b/test/graphml_test.xml @@ -1,7 +1,7 @@ b -b --> a c -c --> b +a --> b +b --> a c +c --> b Vertex a is in component 0 and has root 0 Vertex b is in component 0 and has root 0 @@ -29,87 +29,97 @@ Vertex c is in component 0 and has root 0 int main(int, char*[]) { - using namespace boost; + using namespace boost; - adjacency_list G; + adjacency_list< vecS, vecS, directedS > G; - typedef graph_traits >::vertex_descriptor Vertex; - Vertex a = add_vertex(G); - Vertex b = add_vertex(G); - Vertex c = add_vertex(G); - - add_edge(a, b, G); - add_edge(b, a, G); + typedef graph_traits< + adjacency_list< vecS, vecS, directedS > >::vertex_descriptor Vertex; + Vertex a = add_vertex(G); + Vertex b = add_vertex(G); + Vertex c = add_vertex(G); - add_edge(c, b, G); - add_edge(b, c, G); + add_edge(a, b, G); + add_edge(b, a, G); + + add_edge(c, b, G); + add_edge(b, c, G); #if VERBOSE - std::cout << "The example graph:" << std::endl; - const char* name = "abc"; - print_graph(G, name); - std::cout << std::endl; + std::cout << "The example graph:" << std::endl; + const char* name = "abc"; + print_graph(G, name); + std::cout << std::endl; #endif - - std::vector component(num_vertices(G)), discover_time(num_vertices(G)); - std::vector color(num_vertices(G)); - std::vector root(num_vertices(G)); - strong_components(G, make_iterator_property_map(component.begin(), get(vertex_index, G)), - root_map(make_iterator_property_map(root.begin(), get(vertex_index, G))). - color_map(make_iterator_property_map(color.begin(), get(vertex_index, G))). - discover_time_map(make_iterator_property_map(discover_time.begin(), get(vertex_index, G)))); - + + std::vector< int > component(num_vertices(G)), + discover_time(num_vertices(G)); + std::vector< default_color_type > color(num_vertices(G)); + std::vector< Vertex > root(num_vertices(G)); + strong_components(G, + make_iterator_property_map(component.begin(), get(vertex_index, G)), + root_map(make_iterator_property_map(root.begin(), get(vertex_index, G))) + .color_map( + make_iterator_property_map(color.begin(), get(vertex_index, G))) + .discover_time_map(make_iterator_property_map( + discover_time.begin(), get(vertex_index, G)))); + #if VERBOSE - for (std::vector::size_type i = 0; i != component.size(); ++i) - std::cout << "Vertex " << name[i] - << " is in component " << component[i] - << " and has root " << root[i] << std::endl; + for (std::vector< int >::size_type i = 0; i != component.size(); ++i) + std::cout << "Vertex " << name[i] << " is in component " << component[i] + << " and has root " << root[i] << std::endl; #endif - + #if VERBOSE - bool test_failed; + bool test_failed; #endif - int ret = 0; - - ////////// + int ret = 0; + + ////////// #if VERBOSE - test_failed = false; - std::cerr << "Testing component-computation of strong_components ..." << std::endl; + test_failed = false; + std::cerr << "Testing component-computation of strong_components ..." + << std::endl; #endif - for (std::vector::size_type i = 0; i != component.size(); ++i) { - if(component[i] != 0) { + for (std::vector< int >::size_type i = 0; i != component.size(); ++i) + { + if (component[i] != 0) + { #if VERBOSE - test_failed = true; + test_failed = true; #endif - ret = -1; - break; + ret = -1; + break; + } } - } #if VERBOSE - std::cerr << (test_failed ? " **** Failed." : " Passed.") << std::endl; + std::cerr << (test_failed ? " **** Failed." : " Passed.") << std::endl; #endif - ////////// - - ////////// + ////////// + + ////////// #if VERBOSE - test_failed = false; - std::cerr << "Testing root_map-computation of strong_components ..." << std::endl; + test_failed = false; + std::cerr << "Testing root_map-computation of strong_components ..." + << std::endl; #endif - for (std::vector::size_type i = 0; i != component.size(); ++i) { - if(root[i] != 0) { + for (std::vector< int >::size_type i = 0; i != component.size(); ++i) + { + if (root[i] != 0) + { #if VERBOSE - test_failed = true; + test_failed = true; #endif - ret = -1; - break; + ret = -1; + break; + } } - } #if VERBOSE - std::cerr << (test_failed ? " **** Failed." : " Passed.") << std::endl; + std::cerr << (test_failed ? " **** Failed." : " Passed.") << std::endl; #endif - ////////// - - if (ret == 0) - std::cout << "tests passed" << std::endl; - return ret; + ////////// + + if (ret == 0) + std::cout << "tests passed" << std::endl; + return ret; } diff --git a/test/subgraph.cpp b/test/subgraph.cpp index f41aefadb..50168a7a0 100644 --- a/test/subgraph.cpp +++ b/test/subgraph.cpp @@ -5,7 +5,7 @@ #include -#include +#include #include #include @@ -18,196 +18,202 @@ // UNDER CONSTRUCTION - // This is a helper function to recusively compare two subgraphs, // including the index for every local edges and their children. -template -void sub_cmp(subgraph_t const &g1, subgraph_t const &g2) +template < typename subgraph_t > +void sub_cmp(subgraph_t const& g1, subgraph_t const& g2) { - BOOST_CHECK(g1.is_root() == g2.is_root()); - BOOST_CHECK(num_vertices(g1) == num_vertices(g2)); - BOOST_CHECK(num_edges(g1) == num_edges(g2)); + BOOST_TEST(g1.is_root() == g2.is_root()); + BOOST_TEST(num_vertices(g1) == num_vertices(g2)); + BOOST_TEST(num_edges(g1) == num_edges(g2)); typename subgraph_t::edge_iterator e1_i, e1_i_end, e2_i, e2_i_end; boost::tie(e1_i, e1_i_end) = edges(g1); boost::tie(e2_i, e2_i_end) = edges(g2); - for(; e1_i != e1_i_end; ++e1_i, ++e2_i) + for (; e1_i != e1_i_end; ++e1_i, ++e2_i) { - BOOST_CHECK(get(boost::edge_index, g1, *e1_i) - == get(boost::edge_index, g2, *e2_i)); + BOOST_TEST(get(boost::edge_index, g1, *e1_i) + == get(boost::edge_index, g2, *e2_i)); } typename subgraph_t::const_children_iterator g1_i, g1_i_end, g2_i, g2_i_end; boost::tie(g1_i, g1_i_end) = g1.children(); boost::tie(g2_i, g2_i_end) = g2.children(); - for(; g1_i != g1_i_end && g2_i != g2_i_end; ++g1_i, ++g2_i) + for (; g1_i != g1_i_end && g2_i != g2_i_end; ++g1_i, ++g2_i) { sub_cmp(*g1_i, *g2_i); } - BOOST_CHECK(g1_i == g1_i_end && g2_i == g2_i_end); + BOOST_TEST(g1_i == g1_i_end && g2_i == g2_i_end); } -int test_main(int, char*[]) +int main(int, char*[]) { - using namespace boost; - typedef adjacency_list, - property > - > graph_t; - typedef subgraph subgraph_t; - typedef graph_traits::vertex_descriptor vertex_t; - - mt19937 gen; - for (int t = 0; t < 100; t += 5) { - subgraph_t g; - int N = t + 2; - std::vector vertex_set; - std::vector< std::pair > edge_set; - generate_random_graph(g, N, N * 2, gen, - std::back_inserter(vertex_set), - std::back_inserter(edge_set)); - - graph_test< subgraph_t > gt; - - gt.test_incidence_graph(vertex_set, edge_set, g); - gt.test_bidirectional_graph(vertex_set, edge_set, g); - gt.test_adjacency_graph(vertex_set, edge_set, g); - gt.test_vertex_list_graph(vertex_set, g); - gt.test_edge_list_graph(vertex_set, edge_set, g); - gt.test_adjacency_matrix(vertex_set, edge_set, g); - - std::vector sub_vertex_set; - std::vector sub_global_map; - std::vector global_sub_map(num_vertices(g)); - std::vector< std::pair > sub_edge_set; - - subgraph_t& g_s = g.create_subgraph(); - - const std::set::size_type Nsub = N/2; - - // Collect a set of random vertices to put in the subgraph - std::set verts; - while (verts.size() < Nsub) - verts.insert(random_vertex(g, gen)); - - for (std::set::iterator it = verts.begin(); - it != verts.end(); ++it) { - vertex_t v_global = *it; - vertex_t v = add_vertex(v_global, g_s); - sub_vertex_set.push_back(v); - sub_global_map.push_back(v_global); - global_sub_map[v_global] = v; - } - - // compute induced edges - BGL_FORALL_EDGES(e, g, subgraph_t) - if (container_contains(sub_global_map, source(e, g)) - && container_contains(sub_global_map, target(e, g))) - sub_edge_set.push_back(std::make_pair(global_sub_map[source(e, g)], - global_sub_map[target(e, g)])); - - gt.test_incidence_graph(sub_vertex_set, sub_edge_set, g_s); - gt.test_bidirectional_graph(sub_vertex_set, sub_edge_set, g_s); - gt.test_adjacency_graph(sub_vertex_set, sub_edge_set, g_s); - gt.test_vertex_list_graph(sub_vertex_set, g_s); - gt.test_edge_list_graph(sub_vertex_set, sub_edge_set, g_s); - gt.test_adjacency_matrix(sub_vertex_set, sub_edge_set, g_s); - - if (num_vertices(g_s) == 0) - return 0; - std::vector weights; - for (unsigned i = 0; i < num_vertices(g_s); ++i) - weights.push_back(i*2); - gt.test_vertex_property_graph(weights, vertex_color_t(), g_s); - - // A regression test: the copy constructor of subgraph did not - // copy one of the members, so local_edge->global_edge mapping - // was broken. + using namespace boost; + typedef adjacency_list< vecS, vecS, bidirectionalS, + property< vertex_color_t, int >, + property< edge_index_t, std::size_t, property< edge_weight_t, int > > > + graph_t; + typedef subgraph< graph_t > subgraph_t; + typedef graph_traits< subgraph_t >::vertex_descriptor vertex_t; + + mt19937 gen; + for (int t = 0; t < 100; t += 5) { subgraph_t g; - graph_t::vertex_descriptor v1, v2; - v1 = add_vertex(g); - v2 = add_vertex(g); - add_edge(v1, v2, g); + int N = t + 2; + std::vector< vertex_t > vertex_set; + std::vector< std::pair< vertex_t, vertex_t > > edge_set; + generate_random_graph(g, N, N * 2, gen, std::back_inserter(vertex_set), + std::back_inserter(edge_set)); - subgraph_t sub = g.create_subgraph(vertices(g).first, vertices(g).second); + graph_test< subgraph_t > gt; - graph_t::edge_iterator ei, ee; - for (boost::tie(ei, ee) = edges(sub); ei != ee; ++ei) { - // This used to segfault. - get(edge_weight, sub, *ei); - } - } + gt.test_incidence_graph(vertex_set, edge_set, g); + gt.test_bidirectional_graph(vertex_set, edge_set, g); + gt.test_adjacency_graph(vertex_set, edge_set, g); + gt.test_vertex_list_graph(vertex_set, g); + gt.test_edge_list_graph(vertex_set, edge_set, g); + gt.test_adjacency_matrix(vertex_set, edge_set, g); - // This block generates a complete graph with 8 vertices, - // and puts the first and last four of the vertices into two children. - // Do these again to the children, so there are 4 grandchildren with 2 vertices for each. - // Use the copy constructor to generate a copy and compare with the original one. - { - subgraph_t g1; + std::vector< vertex_t > sub_vertex_set; + std::vector< vertex_t > sub_global_map; + std::vector< vertex_t > global_sub_map(num_vertices(g)); + std::vector< std::pair< vertex_t, vertex_t > > sub_edge_set; + + subgraph_t& g_s = g.create_subgraph(); + + const std::set< vertex_t >::size_type Nsub = N / 2; - for(size_t i = 0; i < 8; i ++) + // Collect a set of random vertices to put in the subgraph + std::set< vertex_t > verts; + while (verts.size() < Nsub) + verts.insert(random_vertex(g, gen)); + + for (std::set< vertex_t >::iterator it = verts.begin(); + it != verts.end(); ++it) { - add_vertex(g1); + vertex_t v_global = *it; + vertex_t v = add_vertex(v_global, g_s); + sub_vertex_set.push_back(v); + sub_global_map.push_back(v_global); + global_sub_map[v_global] = v; } - subgraph_t::vertex_iterator vi_start, vi, vi_end, vj_start, vj, vj_end; - for(tie(vi, vi_end) = vertices(g1); vi != vi_end; ++vi) + + // compute induced edges + BGL_FORALL_EDGES(e, g, subgraph_t) + if (container_contains(sub_global_map, source(e, g)) + && container_contains(sub_global_map, target(e, g))) + sub_edge_set.push_back(std::make_pair( + global_sub_map[source(e, g)], global_sub_map[target(e, g)])); + + gt.test_incidence_graph(sub_vertex_set, sub_edge_set, g_s); + gt.test_bidirectional_graph(sub_vertex_set, sub_edge_set, g_s); + gt.test_adjacency_graph(sub_vertex_set, sub_edge_set, g_s); + gt.test_vertex_list_graph(sub_vertex_set, g_s); + gt.test_edge_list_graph(sub_vertex_set, sub_edge_set, g_s); + gt.test_adjacency_matrix(sub_vertex_set, sub_edge_set, g_s); + + if (num_vertices(g_s) == 0) + return 0; + std::vector< int > weights; + for (unsigned i = 0; i < num_vertices(g_s); ++i) + weights.push_back(i * 2); + gt.test_vertex_property_graph(weights, vertex_color_t(), g_s); + + // A regression test: the copy constructor of subgraph did not + // copy one of the members, so local_edge->global_edge mapping + // was broken. { - for(tie(vj, vj_end) = vertices(g1); vj != vj_end; ++vj) + subgraph_t g; + graph_t::vertex_descriptor v1, v2; + v1 = add_vertex(g); + v2 = add_vertex(g); + add_edge(v1, v2, g); + + subgraph_t sub + = g.create_subgraph(vertices(g).first, vertices(g).second); + + graph_t::edge_iterator ei, ee; + for (boost::tie(ei, ee) = edges(sub); ei != ee; ++ei) { - if(*vi != *vj) - { - add_edge(*vi, *vj, g1); - } + // This used to segfault. + get(edge_weight, sub, *ei); } } - tie(vi_start, vi_end) = vertices(g1); - vi = vi_start; - for(size_t i = 0; i < 4; i++) + + // This block generates a complete graph with 8 vertices, + // and puts the first and last four of the vertices into two children. + // Do these again to the children, so there are 4 grandchildren with 2 + // vertices for each. Use the copy constructor to generate a copy and + // compare with the original one. { - ++vi; + subgraph_t g1; + + for (size_t i = 0; i < 8; i++) + { + add_vertex(g1); + } + subgraph_t::vertex_iterator vi_start, vi, vi_end, vj_start, vj, + vj_end; + for (tie(vi, vi_end) = vertices(g1); vi != vi_end; ++vi) + { + for (tie(vj, vj_end) = vertices(g1); vj != vj_end; ++vj) + { + if (*vi != *vj) + { + add_edge(*vi, *vj, g1); + } + } + } + tie(vi_start, vi_end) = vertices(g1); + vi = vi_start; + for (size_t i = 0; i < 4; i++) + { + ++vi; + } + g1.create_subgraph(vi_start, vi); + g1.create_subgraph(++vi, vi_end); + subgraph_t::children_iterator gi1, gi2; + gi2 = g1.children().first; + gi1 = gi2++; + tie(vi_start, vi_end) = vertices(*gi1); + vi = vi_start; + tie(vj_start, vj_end) = vertices(*gi2); + vj = vj_start; + for (size_t i = 0; i < 2; i++) + { + ++vi; + ++vj; + } + (*gi1).create_subgraph(vi_start, vi); + (*gi1).create_subgraph(++vi, vi_end); + (*gi2).create_subgraph(vj_start, vj); + (*gi2).create_subgraph(++vj, vj_end); + subgraph_t g2(g1); + sub_cmp(g1, g2); } - g1.create_subgraph(vi_start, vi); - g1.create_subgraph(++vi, vi_end); - subgraph_t::children_iterator gi1, gi2; - gi2 = g1.children().first; - gi1 = gi2++; - tie(vi_start, vi_end) = vertices(*gi1); - vi = vi_start; - tie(vj_start, vj_end) = vertices(*gi2); - vj = vj_start; - for(size_t i = 0; i < 2; i++) + + // Bootstrap the test_graph framework. + // TODO: Subgraph is fundamentally broken for property types. + // TODO: Under construction. { - ++vi; - ++vj; + using namespace boost; + typedef property< edge_index_t, size_t, EdgeBundle > EdgeProp; + typedef adjacency_list< vecS, vecS, directedS, VertexBundle, + EdgeProp > + BaseGraph; + typedef subgraph< BaseGraph > Graph; + typedef graph_traits< Graph >::vertex_descriptor Vertex; + Graph g; + Vertex v = add_vertex(g); + + typedef property_map< Graph, int VertexBundle::* >::type BundleMap; + BundleMap map = get(&VertexBundle::value, g); + get(map, v); + // put(map, v, 5); + // BOOST_ASSERT(get(map, v) == 5); + + // test_graph(g); + return boost::report_errors(); } - (*gi1).create_subgraph(vi_start, vi); - (*gi1).create_subgraph(++vi, vi_end); - (*gi2).create_subgraph(vj_start, vj); - (*gi2).create_subgraph(++vj, vj_end); - subgraph_t g2(g1); - sub_cmp(g1, g2); - } - - // Bootstrap the test_graph framework. - // TODO: Subgraph is fundamentally broken for property types. - // TODO: Under construction. - { - using namespace boost; - typedef property EdgeProp; - typedef adjacency_list BaseGraph; - typedef subgraph Graph; - typedef graph_traits::vertex_descriptor Vertex; - Graph g; - Vertex v = add_vertex(g); - - typedef property_map::type BundleMap; - BundleMap map = get(&VertexBundle::value, g); - get(map, v); -// put(map, v, 5); -// BOOST_ASSERT(get(map, v) == 5); - -// test_graph(g); - return 0; } - } - return 0; + return boost::report_errors(); } diff --git a/test/subgraph_add.cpp b/test/subgraph_add.cpp index a6a3d3644..f6482f4ee 100644 --- a/test/subgraph_add.cpp +++ b/test/subgraph_add.cpp @@ -1,4 +1,5 @@ -/* This file is a boost.test unit test and provides tests the internal dependency graph +/* This file is a boost.test unit test and provides tests the internal + * dependency graph * * Created on: 06.10.2015 * Author: Stefan Hammer @@ -24,17 +25,27 @@ using namespace boost; -BOOST_AUTO_TEST_CASE(simpleGraph) { +BOOST_AUTO_TEST_CASE(simpleGraph) +{ BOOST_TEST_MESSAGE("simple subgraph"); - typedef subgraph< adjacency_list< vecS, vecS, directedS, - no_property, property< edge_index_t, int > > > Graph; + typedef subgraph< adjacency_list< vecS, vecS, directedS, no_property, + property< edge_index_t, int > > > + Graph; const int N = 6; Graph G0(N); - enum { A, B, C, D, E, F}; // for conveniently refering to vertices in G0 + enum + { + A, + B, + C, + D, + E, + F + }; // for conveniently refering to vertices in G0 Graph& G1 = G0.create_subgraph(); Graph& G2 = G1.create_subgraph(); @@ -42,8 +53,18 @@ BOOST_AUTO_TEST_CASE(simpleGraph) { BOOST_CHECK(&G1.parent() == &G0); BOOST_CHECK(&G2.parent() == &G1); - enum { A1, B1, C1 }; // for conveniently refering to vertices in G1 - enum { A2, B2, C2 }; // for conveniently refering to vertices in G2 + enum + { + A1, + B1, + C1 + }; // for conveniently refering to vertices in G1 + enum + { + A2, + B2, + C2 + }; // for conveniently refering to vertices in G2 add_vertex(C, G1); // global vertex C becomes local A1 for G1 add_vertex(E, G1); // global vertex E becomes local B1 for G1 @@ -78,12 +99,14 @@ BOOST_AUTO_TEST_CASE(simpleGraph) { BOOST_CHECK(num_vertices(G2) == 2); } -BOOST_AUTO_TEST_CASE(addVertices) { +BOOST_AUTO_TEST_CASE(addVertices) +{ BOOST_TEST_MESSAGE("subgraph add edges"); - typedef subgraph< adjacency_list< vecS, vecS, directedS, - no_property, property< edge_index_t, int > > > Graph; + typedef subgraph< adjacency_list< vecS, vecS, directedS, no_property, + property< edge_index_t, int > > > + Graph; typedef Graph::vertex_descriptor Vertex; const int N = 3; @@ -98,26 +121,38 @@ BOOST_AUTO_TEST_CASE(addVertices) { Vertex n1 = add_vertex(0, G2); Vertex n2 = add_vertex(1, G2); // check if the global vertex 2 is equal to the returned local vertex - if (G2.find_vertex(0).second) { + if (G2.find_vertex(0).second) + { BOOST_CHECK(G2.find_vertex(0).first == n1); - } else { - BOOST_ERROR( "vertex not found!" ); } - if (G2.find_vertex(1).second) { + else + { + BOOST_ERROR("vertex not found!"); + } + if (G2.find_vertex(1).second) + { BOOST_CHECK(G2.find_vertex(1).first == n2); - } else { - BOOST_ERROR( "vertex not found!" ); + } + else + { + BOOST_ERROR("vertex not found!"); } // and check if this vertex is also present in G1 - if (G1.find_vertex(0).second) { + if (G1.find_vertex(0).second) + { BOOST_CHECK(G1.local_to_global(G1.find_vertex(0).first) == 0); - } else { - BOOST_ERROR( "vertex not found!" ); } - if (G1.find_vertex(0).second) { + else + { + BOOST_ERROR("vertex not found!"); + } + if (G1.find_vertex(0).second) + { BOOST_CHECK(G1.local_to_global(G1.find_vertex(1).first) == 1); - } else { - BOOST_ERROR( "vertex not found!" ); + } + else + { + BOOST_ERROR("vertex not found!"); } // num_vertices stays the same @@ -128,10 +163,13 @@ BOOST_AUTO_TEST_CASE(addVertices) { // add vertices to G1 Vertex n3 = add_vertex(2, G1); // check if the global vertex 2 is equal to the returned local vertex - if (G1.find_vertex(2).second) { + if (G1.find_vertex(2).second) + { BOOST_CHECK(G1.find_vertex(2).first == n3); - } else { - BOOST_ERROR( "vertex not found!" ); + } + else + { + BOOST_ERROR("vertex not found!"); } // num_vertices stays the same BOOST_CHECK(num_vertices(G0) == 3); @@ -163,28 +201,34 @@ BOOST_AUTO_TEST_CASE(addVertices) { BOOST_CHECK(num_vertices(G1) == 4); BOOST_CHECK(num_vertices(G2) == 2); - typedef std::map::vertex_descriptor, graph_traits::vertex_descriptor>::iterator v_itr; + typedef std::map< graph_traits< Graph::graph_type >::vertex_descriptor, + graph_traits< Graph::graph_type >::vertex_descriptor >::iterator v_itr; std::cerr << "All G0 vertices: " << std::endl; - for(v_itr v = G0.m_local_vertex.begin(); v != G0.m_local_vertex.end(); ++v) { + for (v_itr v = G0.m_local_vertex.begin(); v != G0.m_local_vertex.end(); ++v) + { std::cerr << G0.local_to_global(v->first) << std::endl; } std::cerr << "All G1 vertices: " << std::endl; - for(v_itr v = G1.m_local_vertex.begin(); v != G1.m_local_vertex.end(); ++v) { + for (v_itr v = G1.m_local_vertex.begin(); v != G1.m_local_vertex.end(); ++v) + { std::cerr << G1.local_to_global(v->first) << std::endl; } std::cerr << "All G2 vertices: " << std::endl; - for(v_itr v = G2.m_local_vertex.begin(); v != G2.m_local_vertex.end(); ++v) { + for (v_itr v = G2.m_local_vertex.begin(); v != G2.m_local_vertex.end(); ++v) + { std::cerr << G2.local_to_global(v->first) << std::endl; } } -BOOST_AUTO_TEST_CASE(addEdge) { +BOOST_AUTO_TEST_CASE(addEdge) +{ BOOST_TEST_MESSAGE("subgraph add edges"); - typedef subgraph< adjacency_list< vecS, vecS, directedS, - no_property, property< edge_index_t, int > > > Graph; + typedef subgraph< adjacency_list< vecS, vecS, directedS, no_property, + property< edge_index_t, int > > > + Graph; typedef Graph::vertex_descriptor Vertex; const int N = 3; @@ -246,30 +290,37 @@ BOOST_AUTO_TEST_CASE(addEdge) { BOOST_CHECK(num_vertices(G1) == 3); BOOST_CHECK(num_vertices(G2) == 3); - typedef std::map::vertex_descriptor, graph_traits::vertex_descriptor>::iterator v_itr; + typedef std::map< graph_traits< Graph::graph_type >::vertex_descriptor, + graph_traits< Graph::graph_type >::vertex_descriptor >::iterator v_itr; std::cerr << "All G0 vertices: " << std::endl; - for(v_itr v = G0.m_local_vertex.begin(); v != G0.m_local_vertex.end(); ++v) { + for (v_itr v = G0.m_local_vertex.begin(); v != G0.m_local_vertex.end(); ++v) + { std::cerr << G0.local_to_global(v->first) << std::endl; } std::cerr << "All G1 vertices: " << std::endl; - for(v_itr v = G1.m_local_vertex.begin(); v != G1.m_local_vertex.end(); ++v) { + for (v_itr v = G1.m_local_vertex.begin(); v != G1.m_local_vertex.end(); ++v) + { std::cerr << G1.local_to_global(v->first) << std::endl; } std::cerr << "All G2 vertices: " << std::endl; - for(v_itr v = G2.m_local_vertex.begin(); v != G2.m_local_vertex.end(); ++v) { + for (v_itr v = G2.m_local_vertex.begin(); v != G2.m_local_vertex.end(); ++v) + { std::cerr << G2.local_to_global(v->first) << std::endl; } std::cerr << "All G0 edges: " << std::endl; - BGL_FORALL_EDGES(e, G0, Graph) { + BGL_FORALL_EDGES(e, G0, Graph) + { std::cerr << source(e, G0) << "->" << target(e, G0) << std::endl; } std::cerr << "All G1 edges: " << std::endl; - BGL_FORALL_EDGES(e, G1, Graph) { + BGL_FORALL_EDGES(e, G1, Graph) + { std::cerr << source(e, G1) << "->" << target(e, G1) << std::endl; } std::cerr << "All G2 edges: " << std::endl; - BGL_FORALL_EDGES(e, G2, Graph) { + BGL_FORALL_EDGES(e, G2, Graph) + { std::cerr << source(e, G2) << "->" << target(e, G2) << std::endl; } } diff --git a/test/subgraph_bundled.cpp b/test/subgraph_bundled.cpp index 9a4d8e742..14bf527e4 100644 --- a/test/subgraph_bundled.cpp +++ b/test/subgraph_bundled.cpp @@ -25,112 +25,114 @@ struct arc { int weight; }; -typedef property arc_prop; +typedef property< edge_index_t, std::size_t, arc > arc_prop; -typedef adjacency_list< - vecS, vecS, bidirectionalS, - node, arc_prop -> Graph; +typedef adjacency_list< vecS, vecS, bidirectionalS, node, arc_prop > Graph; -typedef subgraph Subgraph; -typedef graph_traits::vertex_descriptor Vertex; -typedef graph_traits::edge_descriptor Edge; -typedef graph_traits::vertex_iterator VertexIter; -typedef graph_traits::edge_iterator EdgeIter; +typedef subgraph< Graph > Subgraph; +typedef graph_traits< Subgraph >::vertex_descriptor Vertex; +typedef graph_traits< Subgraph >::edge_descriptor Edge; +typedef graph_traits< Subgraph >::vertex_iterator VertexIter; +typedef graph_traits< Subgraph >::edge_iterator EdgeIter; -int test_main(int, char*[]) +int main(int, char*[]) { - mt19937 gen; - for (int t = 0; t < 100; t += 5) { - Subgraph g; - int N = t + 2; - std::vector vertex_set; - std::vector< std::pair > edge_set; - - generate_random_graph(g, N, N * 2, gen, - std::back_inserter(vertex_set), - std::back_inserter(edge_set)); - graph_test< Subgraph > gt; - - gt.test_incidence_graph(vertex_set, edge_set, g); - gt.test_bidirectional_graph(vertex_set, edge_set, g); - gt.test_adjacency_graph(vertex_set, edge_set, g); - gt.test_vertex_list_graph(vertex_set, g); - gt.test_edge_list_graph(vertex_set, edge_set, g); - gt.test_adjacency_matrix(vertex_set, edge_set, g); - - std::vector sub_vertex_set; - std::vector sub_global_map; - std::vector global_sub_map(num_vertices(g)); - std::vector< std::pair > sub_edge_set; - - Subgraph& g_s = g.create_subgraph(); - - const std::set::size_type Nsub = N/2; - - // Collect a set of random vertices to put in the subgraph - std::set verts; - while (verts.size() < Nsub) - verts.insert(random_vertex(g, gen)); - - for (std::set::iterator it = verts.begin(); - it != verts.end(); ++it) { - Vertex v_global = *it; - Vertex v = add_vertex(v_global, g_s); - sub_vertex_set.push_back(v); - sub_global_map.push_back(v_global); - global_sub_map[v_global] = v; - } - - // compute induced edges - BGL_FORALL_EDGES(e, g, Subgraph) - if (container_contains(sub_global_map, source(e, g)) - && container_contains(sub_global_map, target(e, g))) - sub_edge_set.push_back(std::make_pair(global_sub_map[source(e, g)], - global_sub_map[target(e, g)])); - - gt.test_incidence_graph(sub_vertex_set, sub_edge_set, g_s); - gt.test_bidirectional_graph(sub_vertex_set, sub_edge_set, g_s); - gt.test_adjacency_graph(sub_vertex_set, sub_edge_set, g_s); - gt.test_vertex_list_graph(sub_vertex_set, g_s); - gt.test_edge_list_graph(sub_vertex_set, sub_edge_set, g_s); - gt.test_adjacency_matrix(sub_vertex_set, sub_edge_set, g_s); - - if (num_vertices(g_s) == 0) - return 0; - - // Test property maps for vertices. - typedef property_map::type ColorMap; - ColorMap colors = get(&node::color, g_s); - for(std::pair r = vertices(g_s); r.first != r.second; ++r.first) - colors[*r.first] = 0; - - // Test property maps for edges. - typedef property_map::type WeightMap; - WeightMap weights = get(&arc::weight, g_s); - for(std::pair r = edges(g_s); r.first != r.second; ++r.first) { - weights[*r.first] = 12; - } - - // A regression test: the copy constructor of subgraph did not - // copy one of the members, so local_edge->global_edge mapping - // was broken. + mt19937 gen; + for (int t = 0; t < 100; t += 5) { Subgraph g; - graph_traits::vertex_descriptor v1, v2; - v1 = add_vertex(g); - v2 = add_vertex(g); - add_edge(v1, v2, g); + int N = t + 2; + std::vector< Vertex > vertex_set; + std::vector< std::pair< Vertex, Vertex > > edge_set; + + generate_random_graph(g, N, N * 2, gen, std::back_inserter(vertex_set), + std::back_inserter(edge_set)); + graph_test< Subgraph > gt; + + gt.test_incidence_graph(vertex_set, edge_set, g); + gt.test_bidirectional_graph(vertex_set, edge_set, g); + gt.test_adjacency_graph(vertex_set, edge_set, g); + gt.test_vertex_list_graph(vertex_set, g); + gt.test_edge_list_graph(vertex_set, edge_set, g); + gt.test_adjacency_matrix(vertex_set, edge_set, g); + + std::vector< Vertex > sub_vertex_set; + std::vector< Vertex > sub_global_map; + std::vector< Vertex > global_sub_map(num_vertices(g)); + std::vector< std::pair< Vertex, Vertex > > sub_edge_set; + + Subgraph& g_s = g.create_subgraph(); + + const std::set< Vertex >::size_type Nsub = N / 2; + + // Collect a set of random vertices to put in the subgraph + std::set< Vertex > verts; + while (verts.size() < Nsub) + verts.insert(random_vertex(g, gen)); + + for (std::set< Vertex >::iterator it = verts.begin(); it != verts.end(); + ++it) + { + Vertex v_global = *it; + Vertex v = add_vertex(v_global, g_s); + sub_vertex_set.push_back(v); + sub_global_map.push_back(v_global); + global_sub_map[v_global] = v; + } - Subgraph sub = g.create_subgraph(vertices(g).first, vertices(g).second); + // compute induced edges + BGL_FORALL_EDGES(e, g, Subgraph) + if (container_contains(sub_global_map, source(e, g)) + && container_contains(sub_global_map, target(e, g))) + sub_edge_set.push_back(std::make_pair( + global_sub_map[source(e, g)], global_sub_map[target(e, g)])); + + gt.test_incidence_graph(sub_vertex_set, sub_edge_set, g_s); + gt.test_bidirectional_graph(sub_vertex_set, sub_edge_set, g_s); + gt.test_adjacency_graph(sub_vertex_set, sub_edge_set, g_s); + gt.test_vertex_list_graph(sub_vertex_set, g_s); + gt.test_edge_list_graph(sub_vertex_set, sub_edge_set, g_s); + gt.test_adjacency_matrix(sub_vertex_set, sub_edge_set, g_s); + + if (num_vertices(g_s) == 0) + return 0; + + // Test property maps for vertices. + typedef property_map< Subgraph, int node::* >::type ColorMap; + ColorMap colors = get(&node::color, g_s); + for (std::pair< VertexIter, VertexIter > r = vertices(g_s); + r.first != r.second; ++r.first) + colors[*r.first] = 0; + + // Test property maps for edges. + typedef property_map< Subgraph, int arc::* >::type WeightMap; + WeightMap weights = get(&arc::weight, g_s); + for (std::pair< EdgeIter, EdgeIter > r = edges(g_s); + r.first != r.second; ++r.first) + { + weights[*r.first] = 12; + } - graph_traits::edge_iterator ei, ee; - for (boost::tie(ei, ee) = edges(sub); ei != ee; ++ei) { - // This used to segfault. - get(&arc::weight, sub, *ei); + // A regression test: the copy constructor of subgraph did not + // copy one of the members, so local_edge->global_edge mapping + // was broken. + { + Subgraph g; + graph_traits< Graph >::vertex_descriptor v1, v2; + v1 = add_vertex(g); + v2 = add_vertex(g); + add_edge(v1, v2, g); + + Subgraph sub + = g.create_subgraph(vertices(g).first, vertices(g).second); + + graph_traits< Graph >::edge_iterator ei, ee; + for (boost::tie(ei, ee) = edges(sub); ei != ee; ++ei) + { + // This used to segfault. + get(&arc::weight, sub, *ei); + } } } - - } - return 0; + return boost::report_errors(); } diff --git a/test/subgraph_props.cpp b/test/subgraph_props.cpp index bdee65340..acf4a880b 100644 --- a/test/subgraph_props.cpp +++ b/test/subgraph_props.cpp @@ -11,22 +11,23 @@ using namespace boost; -struct TestProps { - typedef property VertexProp; - typedef property EdgeName; - typedef property EdgeProp; - - typedef adjacency_list< - vecS, vecS, bidirectionalS, VertexProp, EdgeProp - > Graph; - - typedef subgraph Subgraph; - typedef graph_traits::vertex_descriptor Vertex; - typedef graph_traits::edge_descriptor Edge; - typedef graph_traits::vertex_iterator VertexIter; - typedef std::pair VertexRange; - - static void run() { +struct TestProps +{ + typedef property< vertex_name_t, std::size_t > VertexProp; + typedef property< edge_name_t, std::size_t > EdgeName; + typedef property< edge_index_t, std::size_t, EdgeName > EdgeProp; + + typedef adjacency_list< vecS, vecS, bidirectionalS, VertexProp, EdgeProp > + Graph; + + typedef subgraph< Graph > Subgraph; + typedef graph_traits< Subgraph >::vertex_descriptor Vertex; + typedef graph_traits< Subgraph >::edge_descriptor Edge; + typedef graph_traits< Subgraph >::vertex_iterator VertexIter; + typedef std::pair< VertexIter, VertexIter > VertexRange; + + static void run() + { // Create a graph with some vertices. Subgraph g(5); VertexRange r = vertices(g); @@ -35,14 +36,14 @@ struct TestProps { Subgraph& sg = g.create_subgraph(); Vertex v = add_vertex(*r.first, sg); - typedef property_map::type DefaultMap; + typedef property_map< Subgraph, vertex_name_t >::type DefaultMap; DefaultMap map = get(vertex_name, g); BOOST_ASSERT(get(map, v) == 0); put(map, v, 5); BOOST_ASSERT(get(map, v) == 5); - typedef global_property GlobalProp; - typedef property_map::type GlobalVertMap; + typedef global_property< vertex_name_t > GlobalProp; + typedef property_map< Subgraph, GlobalProp >::type GlobalVertMap; GlobalVertMap groot = get(global(vertex_name), g); GlobalVertMap gsub = get(global(vertex_name), sg); BOOST_ASSERT(get(groot, v) == 5); @@ -52,45 +53,47 @@ struct TestProps { BOOST_ASSERT(get(gsub, v) == 10); BOOST_ASSERT(get(map, v) == 10); - typedef local_property LocalProp; - typedef property_map::type LocalVertMap; + typedef local_property< vertex_name_t > LocalProp; + typedef property_map< Subgraph, LocalProp >::type LocalVertMap; LocalVertMap lroot = get(local(vertex_name), g); // Actually global! LocalVertMap lsub = get(local(vertex_name), sg); - BOOST_ASSERT(get(lroot, v) == 10); // Recall it's 10 from above! + BOOST_ASSERT(get(lroot, v) == 10); // Recall it's 10 from above! BOOST_ASSERT(get(lsub, v) == 0); put(lsub, v, 5); BOOST_ASSERT(get(lsub, v) == 5); - BOOST_ASSERT(get(lroot, v) == 10); // Don't change the root prop - BOOST_ASSERT(get(map, v) == 10); // Don't change the root prop + BOOST_ASSERT(get(lroot, v) == 10); // Don't change the root prop + BOOST_ASSERT(get(map, v) == 10); // Don't change the root prop -// typedef detail::subgraph_local_pmap::bind_ PM; -// std::cout << typestr() << "\n"; -// std::cout << typestr() << "\n"; + // typedef detail::subgraph_local_pmap::bind_ PM; std::cout << typestr() << + // "\n"; std::cout << typestr() << "\n"; } }; -struct TestBundles { - struct Node { - Node() : value(-1) { } +struct TestBundles +{ + struct Node + { + Node() : value(-1) {} int value; }; - struct Arc { - Arc() : value(-1) { } + struct Arc + { + Arc() : value(-1) {} int value; }; - typedef property EdgeProp; + typedef property< edge_index_t, std::size_t, Arc > EdgeProp; - typedef adjacency_list< - vecS, vecS, bidirectionalS, Node, EdgeProp - > Graph; + typedef adjacency_list< vecS, vecS, bidirectionalS, Node, EdgeProp > Graph; - typedef subgraph Subgraph; - typedef graph_traits::vertex_descriptor Vertex; - typedef graph_traits::edge_descriptor Edge; - typedef graph_traits::vertex_iterator VertexIter; - typedef std::pair VertexRange; + typedef subgraph< Graph > Subgraph; + typedef graph_traits< Subgraph >::vertex_descriptor Vertex; + typedef graph_traits< Subgraph >::edge_descriptor Edge; + typedef graph_traits< Subgraph >::vertex_iterator VertexIter; + typedef std::pair< VertexIter, VertexIter > VertexRange; - static void run() { + static void run() + { // Create a graph with some vertices. Subgraph g(5); VertexRange r = vertices(g); @@ -109,15 +112,13 @@ struct TestBundles { BOOST_ASSERT(sg[global(v)].value == 1); BOOST_ASSERT(sg[v].value == 1); - typedef property_map< - Subgraph, local_property - >::type LocalVertMap; + typedef property_map< Subgraph, local_property< int Node::* > >::type + LocalVertMap; LocalVertMap lvm = get(local(&Node::value), sg); BOOST_ASSERT(get(lvm, v) == 5); - typedef property_map< - Subgraph, global_property - >::type GlobalVertMap; + typedef property_map< Subgraph, global_property< int Node::* > >::type + GlobalVertMap; GlobalVertMap gvm = get(global(&Node::value), sg); BOOST_ASSERT(get(gvm, v) == 1); } diff --git a/test/successive_shortest_path_nonnegative_weights_test.cpp b/test/successive_shortest_path_nonnegative_weights_test.cpp index cf9fe50c1..f8b6ea755 100644 --- a/test/successive_shortest_path_nonnegative_weights_test.cpp +++ b/test/successive_shortest_path_nonnegative_weights_test.cpp @@ -1,6 +1,6 @@ //======================================================================= // Copyright 2013 University of Warsaw. -// Authors: Piotr Wygocki +// Authors: Piotr Wygocki // // Distributed under the Boost Software License, Version 1.0. (See // accompanying file LICENSE_1_0.txt or copy at @@ -16,52 +16,55 @@ #include "min_cost_max_flow_utils.hpp" - -BOOST_AUTO_TEST_CASE(path_augmentation_def_test) { - boost::SampleGraph::vertex_descriptor s,t; - boost::SampleGraph::Graph g; +BOOST_AUTO_TEST_CASE(path_augmentation_def_test) +{ + boost::SampleGraph::vertex_descriptor s, t; + boost::SampleGraph::Graph g; boost::SampleGraph::getSampleGraph(g, s, t); boost::successive_shortest_path_nonnegative_weights(g, s, t); - int cost = boost::find_flow_cost(g); + int cost = boost::find_flow_cost(g); BOOST_CHECK_EQUAL(cost, 29); } -BOOST_AUTO_TEST_CASE(path_augmentation_def_test2) { - boost::SampleGraph::vertex_descriptor s,t; - boost::SampleGraph::Graph g; +BOOST_AUTO_TEST_CASE(path_augmentation_def_test2) +{ + boost::SampleGraph::vertex_descriptor s, t; + boost::SampleGraph::Graph g; boost::SampleGraph::getSampleGraph2(g, s, t); boost::successive_shortest_path_nonnegative_weights(g, s, t); - int cost = boost::find_flow_cost(g); + int cost = boost::find_flow_cost(g); BOOST_CHECK_EQUAL(cost, 7); } -BOOST_AUTO_TEST_CASE(path_augmentation_test) { - boost::SampleGraph::vertex_descriptor s,t; +BOOST_AUTO_TEST_CASE(path_augmentation_test) +{ + boost::SampleGraph::vertex_descriptor s, t; typedef boost::SampleGraph::Graph Graph; Graph g; boost::SampleGraph::getSampleGraph(g, s, t); int N = boost::num_vertices(g); - std::vector dist(N); - std::vector dist_prev(N); - typedef boost::graph_traits::edge_descriptor edge_descriptor; - std::vector pred(N); - - boost::property_map::const_type - idx = get(boost::vertex_index, g); - - boost::successive_shortest_path_nonnegative_weights(g, s, t, - boost::distance_map(boost::make_iterator_property_map(dist.begin(), idx)). - predecessor_map(boost::make_iterator_property_map(pred.begin(), idx)). - distance_map2(boost::make_iterator_property_map(dist_prev.begin(), idx)). - vertex_index_map(idx)); - - int cost = boost::find_flow_cost(g); + std::vector< int > dist(N); + std::vector< int > dist_prev(N); + typedef boost::graph_traits< Graph >::edge_descriptor edge_descriptor; + std::vector< edge_descriptor > pred(N); + + boost::property_map< Graph, boost::vertex_index_t >::const_type idx + = get(boost::vertex_index, g); + + boost::successive_shortest_path_nonnegative_weights(g, s, t, + boost::distance_map( + boost::make_iterator_property_map(dist.begin(), idx)) + .predecessor_map( + boost::make_iterator_property_map(pred.begin(), idx)) + .distance_map2( + boost::make_iterator_property_map(dist_prev.begin(), idx)) + .vertex_index_map(idx)); + + int cost = boost::find_flow_cost(g); BOOST_CHECK_EQUAL(cost, 29); } - - diff --git a/test/swap.cpp b/test/swap.cpp index f47b234fa..cd2b8bc54 100644 --- a/test/swap.cpp +++ b/test/swap.cpp @@ -6,16 +6,15 @@ #include #include -template -void test_member_swap() +template < typename Graph > void test_member_swap() { - Graph lhs, rhs; - lhs.swap(rhs); + Graph lhs, rhs; + lhs.swap(rhs); } int main() { - test_member_swap >(); - test_member_swap >(); - test_member_swap >(); + test_member_swap< boost::adjacency_list<> >(); + test_member_swap< boost::directed_graph<> >(); + test_member_swap< boost::undirected_graph<> >(); } diff --git a/test/test_construction.hpp b/test/test_construction.hpp index 0243f6d2b..cf0a26111 100644 --- a/test/test_construction.hpp +++ b/test/test_construction.hpp @@ -8,7 +8,11 @@ #define TEST_CONSTRUCTION_HPP #include +#include #include +#include + +#include "test_graph.hpp" /** @name Build Graph * Build the standard graph structure used in the remaining tests. Depending @@ -18,34 +22,39 @@ */ //@{ // This will basically catch adjacency matrices, which don't get built. -template +template < typename Graph, typename Add, typename Label > void build_graph(Graph& g, Add, Label) -{ } +{ +} // This matches MutableGraph, so just add some vertices. -template -void build_graph(Graph& g, boost::mpl::true_, boost::mpl::false_) { +template < typename Graph > +void build_graph(Graph& g, boost::mpl::true_, boost::mpl::false_) +{ using namespace boost; - BOOST_CONCEPT_ASSERT((VertexListGraphConcept)); - BOOST_CONCEPT_ASSERT((VertexMutableGraphConcept)); + BOOST_CONCEPT_ASSERT((VertexListGraphConcept< Graph >)); + BOOST_CONCEPT_ASSERT((VertexMutableGraphConcept< Graph >)); std::cout << "...build_normal\n"; - for(std::size_t i = 0; i < N; ++i) { + for (std::size_t i = 0; i < N; ++i) + { add_vertex(g); } BOOST_ASSERT(num_vertices(g) == N); } // This will match labeled graphs. -template -void build_graph(Graph& g, boost::mpl::false_, boost::mpl::true_) { +template < typename Graph > +void build_graph(Graph& g, boost::mpl::false_, boost::mpl::true_) +{ using namespace boost; - BOOST_CONCEPT_ASSERT((VertexListGraphConcept)); + BOOST_CONCEPT_ASSERT((VertexListGraphConcept< Graph >)); // BOOST_CONCEPT_ASSERT((VertexMutableGraphConcept)); std::cout << "...build_labeled\n"; // Add each vertex labeled with the number i. - for(std::size_t i = 0; i < N; ++i) { + for (std::size_t i = 0; i < N; ++i) + { add_vertex(i, g); } BOOST_ASSERT(num_vertices(g) == N); @@ -58,15 +67,17 @@ void build_graph(Graph& g, boost::mpl::false_, boost::mpl::true_) { * labeled graphs since that's actually done in build_graph above. */ //@{ -template +template < typename Graph, typename Add, typename Label > void build_property_graph(Graph const& g, Add, Label) -{ } +{ +} -template -void build_property_graph(Graph const&, boost::mpl::true_, boost::mpl::false_) { +template < typename Graph > +void build_property_graph(Graph const&, boost::mpl::true_, boost::mpl::false_) +{ using namespace boost; - BOOST_CONCEPT_ASSERT((VertexMutablePropertyGraphConcept)); - typedef typename vertex_property_type::type VertexProp; + BOOST_CONCEPT_ASSERT((VertexMutablePropertyGraphConcept< Graph >)); + typedef typename vertex_property_type< Graph >::type VertexProp; std::cout << "...build mutable\n"; @@ -77,7 +88,6 @@ void build_property_graph(Graph const&, boost::mpl::true_, boost::mpl::false_) { } //@} - /** @name Connect Graph * Given a constructed graph, connect the edges to create a the standard * testing graph. To facilitate ease of use, we pass a vector of vertices @@ -86,15 +96,17 @@ void build_property_graph(Graph const&, boost::mpl::true_, boost::mpl::false_) { * normal or labled graphs. */ //@{ -template -void connect_graph(Graph& g, VertexSet const& verts, boost::mpl::false_) { +template < typename Graph, typename VertexSet > +void connect_graph(Graph& g, VertexSet const& verts, boost::mpl::false_) +{ using namespace boost; - BOOST_CONCEPT_ASSERT((AdjacencyMatrixConcept)); - BOOST_CONCEPT_ASSERT((EdgeMutableGraphConcept)); + BOOST_CONCEPT_ASSERT((AdjacencyMatrixConcept< Graph >)); + BOOST_CONCEPT_ASSERT((EdgeMutableGraphConcept< Graph >)); std::cout << "...connect_normal\n"; Pair *f, *l; - for(boost::tie(f, l) = edge_pairs(); f != l; ++f) { + for (boost::tie(f, l) = edge_pairs(); f != l; ++f) + { Pair const& e = *f; add_edge(verts[e.first], verts[e.second], g); } @@ -104,10 +116,11 @@ void connect_graph(Graph& g, VertexSet const& verts, boost::mpl::false_) { BOOST_ASSERT(edge(verts[5], verts[0], g).second == false); } -template -void connect_graph(Graph& g, VertexSet const& verts, boost::mpl::true_) { +template < typename Graph, typename VertexSet > +void connect_graph(Graph& g, VertexSet const& verts, boost::mpl::true_) +{ using namespace boost; - BOOST_CONCEPT_ASSERT((AdjacencyMatrixConcept)); + BOOST_CONCEPT_ASSERT((AdjacencyMatrixConcept< Graph >)); // BOOST_CONCEPT_ASSERT((EdgeMutableGraphConcept)); std::cout << "...connect_labeled\n"; @@ -115,7 +128,8 @@ void connect_graph(Graph& g, VertexSet const& verts, boost::mpl::true_) { // rather than looking up the correct vertex index. This is because the // vertices are already mapped to indices. Pair* p = edge_pairs().first; - for(std::size_t i = 0; i < M; ++i) { + for (std::size_t i = 0; i < M; ++i) + { Pair const& e = p[i]; add_edge_by_label(e.first, e.second, g); } diff --git a/test/test_destruction.hpp b/test/test_destruction.hpp index 8cdfa1b67..e9c6defc4 100644 --- a/test/test_destruction.hpp +++ b/test/test_destruction.hpp @@ -8,23 +8,31 @@ #define TEST_DESTRUCTION_HPP #include +#include +#include #include +#include + +#include "test_graph.hpp" /** @name Destroy Graph * Destroy the graph by removing vertices (if possible). */ //@{ // This will basically catch adjacency matrices, which don't get torn down. -template +template < typename Graph, typename VertexSet, typename Remove, typename Label > void destroy_graph(Graph&, VertexSet const&, Remove, Label) -{ } +{ +} // This matches MutableGraph, so just remove a vertex and then clear. -template -void destroy_graph(Graph& g, VertexSet const& verts, boost::mpl::true_, boost::mpl::false_) { +template < typename Graph, typename VertexSet > +void destroy_graph( + Graph& g, VertexSet const& verts, boost::mpl::true_, boost::mpl::false_) +{ using namespace boost; - BOOST_CONCEPT_ASSERT((VertexListGraphConcept)); - BOOST_CONCEPT_ASSERT((VertexMutableGraphConcept)); + BOOST_CONCEPT_ASSERT((VertexListGraphConcept< Graph >)); + BOOST_CONCEPT_ASSERT((VertexMutableGraphConcept< Graph >)); std::cout << "...destroy_normal\n"; // Remove the roof vertex @@ -33,10 +41,12 @@ void destroy_graph(Graph& g, VertexSet const& verts, boost::mpl::true_, boost::m } // This will match labeled graphs. -template -void destroy_graph(Graph& g, VertexSet const&, boost::mpl::false_, boost::mpl::true_) { +template < typename Graph, typename VertexSet > +void destroy_graph( + Graph& g, VertexSet const&, boost::mpl::false_, boost::mpl::true_) +{ using namespace boost; - BOOST_CONCEPT_ASSERT((VertexListGraphConcept)); + BOOST_CONCEPT_ASSERT((VertexListGraphConcept< Graph >)); // BOOST_CONCEPT_ASSERT(( VeretexMutableGraphConcept )); std::cout << "...destroy_labeled\n"; @@ -46,7 +56,6 @@ void destroy_graph(Graph& g, VertexSet const&, boost::mpl::false_, boost::mpl::t } //@} - /** @name Disconnect Graph * Disconnect edges in the graph. Note that this doesn't fully disconnect the * graph. It simply determines if we can disconnect an edge or two and verify @@ -57,14 +66,15 @@ void destroy_graph(Graph& g, VertexSet const&, boost::mpl::false_, boost::mpl::t */ //@{ -template -void disconnect_graph(Graph& g, VertexSet const& verts, boost::mpl::false_) { +template < typename Graph, typename VertexSet > +void disconnect_graph(Graph& g, VertexSet const& verts, boost::mpl::false_) +{ using namespace boost; - BOOST_CONCEPT_ASSERT((EdgeListGraphConcept)); - BOOST_CONCEPT_ASSERT((EdgeMutableGraphConcept)); + BOOST_CONCEPT_ASSERT((EdgeListGraphConcept< Graph >)); + BOOST_CONCEPT_ASSERT((EdgeMutableGraphConcept< Graph >)); std::cout << "...disconnect_normal\n"; - typedef typename graph_traits::edge_descriptor Edge; + typedef typename graph_traits< Graph >::edge_descriptor Edge; // Disconnect the "lollipop" from the house. Edge e = edge(verts[5], verts[3], g).first; @@ -84,14 +94,15 @@ void disconnect_graph(Graph& g, VertexSet const& verts, boost::mpl::false_) { BOOST_ASSERT(num_edges(g) == M - 4); } -template -void disconnect_graph(Graph& g, VertexSet const&, boost::mpl::true_) { +template < typename Graph, typename VertexSet > +void disconnect_graph(Graph& g, VertexSet const&, boost::mpl::true_) +{ using namespace boost; - BOOST_CONCEPT_ASSERT((EdgeListGraphConcept)); + BOOST_CONCEPT_ASSERT((EdgeListGraphConcept< Graph >)); // BOOST_CONCEPT_ASSERT((EdgeMutableGraphConcept)); std::cout << "...disconnect_labeled\n"; - typedef typename boost::graph_traits::edge_descriptor Edge; + typedef typename boost::graph_traits< Graph >::edge_descriptor Edge; // Disconnect the "lollipop" from the house. Edge e = boost::edge_by_label(5, 3, g).first; diff --git a/test/test_direction.hpp b/test/test_direction.hpp index 1084c06b9..8b764c62e 100644 --- a/test/test_direction.hpp +++ b/test/test_direction.hpp @@ -10,24 +10,32 @@ #include #include #include +#include +#include +#include + +#include "test_graph.hpp" /** @name Test Out-Directed Graph * Test all graphs that have directed out edges. */ //@{ -template -void test_outdirected_graph(Graph const& g, VertexSet const& verts, boost::mpl::true_) { +template < typename Graph, typename VertexSet > +void test_outdirected_graph( + Graph const& g, VertexSet const& verts, boost::mpl::true_) +{ using namespace boost; - BOOST_CONCEPT_ASSERT((IncidenceGraphConcept)); + BOOST_CONCEPT_ASSERT((IncidenceGraphConcept< Graph >)); std::cout << "...test_outdirected_graph\n"; - typedef typename graph_traits::out_edge_iterator OutIter; - typedef std::pair OutRange; - typedef std::vector OutSet; + typedef typename graph_traits< Graph >::out_edge_iterator OutIter; + typedef std::pair< OutIter, OutIter > OutRange; + typedef std::vector< OutRange > OutSet; // Collect all of the out edge ranges from the graph. OutSet outs(verts.size()); - for(size_t i = 0; i < verts.size(); ++i) { + for (size_t i = 0; i < verts.size(); ++i) + { outs[i] = out_edges(verts[i], g); } @@ -49,28 +57,32 @@ void test_outdirected_graph(Graph const& g, VertexSet const& verts, boost::mpl:: BOOST_ASSERT(has_target(g, *outs[5].first, verts[3])); } -template +template < typename Graph, typename VertexSet > void test_outdirected_graph(Graph const&, VertexSet const&, boost::mpl::false_) -{ } +{ +} //@} /** @name Test In-Directed Graph * Test all graphs that support in-directed edges. */ //@{ -template -void test_indirected_graph(Graph const& g, VertexSet const& verts, boost::mpl::true_) { +template < typename Graph, typename VertexSet > +void test_indirected_graph( + Graph const& g, VertexSet const& verts, boost::mpl::true_) +{ using namespace boost; - BOOST_CONCEPT_ASSERT((BidirectionalGraphConcept)); + BOOST_CONCEPT_ASSERT((BidirectionalGraphConcept< Graph >)); std::cout << "...test_indirected_graph\n"; - typedef typename graph_traits::in_edge_iterator InIter; - typedef std::pair InRange; - typedef std::vector InSet; + typedef typename graph_traits< Graph >::in_edge_iterator InIter; + typedef std::pair< InIter, InIter > InRange; + typedef std::vector< InRange > InSet; // Collect all of the in edges from the graph. InSet ins(verts.size()); - for(size_t i = 0; i < verts.size(); ++i) { + for (size_t i = 0; i < verts.size(); ++i) + { ins[i] = in_edges(verts[i], g); } @@ -88,27 +100,31 @@ void test_indirected_graph(Graph const& g, VertexSet const& verts, boost::mpl::t BOOST_ASSERT(has_source(g, *ins[4].first, verts[3])); } -template +template < typename Graph, typename VertexSet > void test_indirected_graph(Graph const&, VertexSet const&, boost::mpl::false_) -{ } +{ +} //@} /** @name Undirected Graphs * Test all graphs that have undirected edges. */ -template -void test_undirected_graph(Graph const& g, VertexSet const& verts, boost::mpl::true_) { +template < typename Graph, typename VertexSet > +void test_undirected_graph( + Graph const& g, VertexSet const& verts, boost::mpl::true_) +{ using namespace boost; - BOOST_CONCEPT_ASSERT((IncidenceGraphConcept)); + BOOST_CONCEPT_ASSERT((IncidenceGraphConcept< Graph >)); std::cout << "...test_undirected_graph\n"; - typedef typename graph_traits::out_edge_iterator OutIter; - typedef std::pair OutRange; - typedef std::vector OutSet; + typedef typename graph_traits< Graph >::out_edge_iterator OutIter; + typedef std::pair< OutIter, OutIter > OutRange; + typedef std::vector< OutRange > OutSet; // The set of out edges is the same as the set of incident edges. OutSet outs(verts.size()); - for(size_t i = 0; i < verts.size(); ++i) { + for (size_t i = 0; i < verts.size(); ++i) + { outs[i] = out_edges(verts[i], g); } @@ -122,9 +138,10 @@ void test_undirected_graph(Graph const& g, VertexSet const& verts, boost::mpl::t BOOST_ASSERT(distance(outs[5]) == 1); } -template +template < typename Graph, typename VertexSet > void test_undirected_graph(Graph const&, VertexSet const&, boost::mpl::false_) -{ } +{ +} //@} #endif diff --git a/test/test_graph.hpp b/test/test_graph.hpp index f12230426..72c23c9cc 100644 --- a/test/test_graph.hpp +++ b/test/test_graph.hpp @@ -28,32 +28,35 @@ #define BOOST_META_ASSERT(x) BOOST_ASSERT(x::value) -typedef std::pair Pair; +typedef std::pair< std::size_t, std::size_t > Pair; static const std::size_t N = 6; static const std::size_t M = 7; // A helper function that globally defines the graph being constructed. Note // that this graph shown here: http://en.wikipedia.org/wiki/Graph_theory. -std::pair edge_pairs() { - static Pair pairs[] = { - Pair(5, 3), Pair(3, 4), Pair(3, 2), Pair(4, 0), Pair(4, 1), - Pair(2, 1), Pair(1, 0) - }; +std::pair< Pair*, Pair* > edge_pairs() +{ + static Pair pairs[] = { Pair(5, 3), Pair(3, 4), Pair(3, 2), Pair(4, 0), + Pair(4, 1), Pair(2, 1), Pair(1, 0) }; Pair* f = &pairs[0]; Pair* l = f + M; return std::make_pair(f, l); } // Return true if the vertex v is the target of the edge e. -template +template < typename Graph, typename Edge, typename Vertex > bool has_target(Graph const& g, Edge e, Vertex v) -{ return boost::target(e, g) == v; } +{ + return boost::target(e, g) == v; +} // Return true if the vertex v is the source of the edge e. -template +template < typename Graph, typename Edge, typename Vertex > bool has_source(Graph const& g, Edge e, Vertex v) -{ return boost::source(e, g) == v; } +{ + return boost::source(e, g) == v; +} /** @name Property Bundles * Support testing with bundled properties. Note that the vertex bundle and @@ -63,13 +66,15 @@ bool has_source(Graph const& g, Edge e, Vertex v) //@{ // This is really just a place holder to make sure that bundled graph // properties actually work. There are no semantics to this type. -struct GraphBundle { - int value; +struct GraphBundle +{ + int value; }; -struct VertexBundle { - VertexBundle() : value() { } - VertexBundle(int n) : value(n) { } +struct VertexBundle +{ + VertexBundle() : value() {} + VertexBundle(int n) : value(n) {} bool operator==(VertexBundle const& x) const { return value == x.value; } bool operator<(VertexBundle const& x) const { return value < x.value; } @@ -77,9 +82,10 @@ struct VertexBundle { int value; }; -struct EdgeBundle { - EdgeBundle() : value() { } - EdgeBundle(int n) : value(n) { } +struct EdgeBundle +{ + EdgeBundle() : value() {} + EdgeBundle(int n) : value(n) {} bool operator==(EdgeBundle const& x) const { return value == x.value; } bool operator<(EdgeBundle const& x) const { return value < x.value; } @@ -94,20 +100,20 @@ struct EdgeBundle { #include "test_direction.hpp" #include "test_properties.hpp" -template -void test_graph(Graph& g) { +template < typename Graph > void test_graph(Graph& g) +{ using namespace boost; - BOOST_CONCEPT_ASSERT((GraphConcept)); + BOOST_CONCEPT_ASSERT((GraphConcept< Graph >)); std::cout << typestr(g) << "\n"; // Define a bunch of tags for the graph. - typename graph_has_add_vertex::type can_add_vertex; - typename graph_has_remove_vertex::type can_remove_vertex; - typename is_labeled_graph::type is_labeled; - typename is_directed_unidirectional_graph::type is_directed; - typename is_directed_bidirectional_graph::type is_bidirectional; - typename is_undirected_graph::type is_undirected; + typename graph_has_add_vertex< Graph >::type can_add_vertex; + typename graph_has_remove_vertex< Graph >::type can_remove_vertex; + typename is_labeled_graph< Graph >::type is_labeled; + typename is_directed_unidirectional_graph< Graph >::type is_directed; + typename is_directed_bidirectional_graph< Graph >::type is_bidirectional; + typename is_undirected_graph< Graph >::type is_undirected; // Test constrution and vertex list. build_graph(g, can_add_vertex, is_labeled); @@ -116,11 +122,12 @@ void test_graph(Graph& g) { test_vertex_list_graph(g); // Collect the vertices for an easy method of "naming" them. - typedef typename graph_traits::vertex_descriptor Vertex; - typedef typename graph_traits::vertex_iterator VertexIterator; - std::vector verts; - std::pair rng = vertices(g); - for( ; rng.first != rng.second; ++rng.first) { + typedef typename graph_traits< Graph >::vertex_descriptor Vertex; + typedef typename graph_traits< Graph >::vertex_iterator VertexIterator; + std::vector< Vertex > verts; + std::pair< VertexIterator, VertexIterator > rng = vertices(g); + for (; rng.first != rng.second; ++rng.first) + { verts.push_back(*rng.first); } @@ -142,5 +149,4 @@ void test_graph(Graph& g) { destroy_graph(g, verts, can_remove_vertex, is_labeled); } - #endif diff --git a/test/test_graphs.cpp b/test/test_graphs.cpp index 2f0965238..81c489bb5 100644 --- a/test/test_graphs.cpp +++ b/test/test_graphs.cpp @@ -24,178 +24,185 @@ using namespace boost; int main() { - // Bootstrap all of the tests by declaring a kind graph and asserting some - // basic properties about it. - { - typedef undirected_graph Graph; - BOOST_META_ASSERT(is_undirected_graph); - BOOST_META_ASSERT(is_multigraph); - BOOST_META_ASSERT(is_incidence_graph); - BOOST_META_ASSERT(is_bidirectional_graph); - BOOST_META_ASSERT(has_vertex_property); - BOOST_META_ASSERT(has_bundled_vertex_property); - BOOST_META_ASSERT(has_edge_property); - BOOST_META_ASSERT(has_bundled_edge_property); - BOOST_META_ASSERT(is_mutable_graph); - BOOST_META_ASSERT(is_mutable_property_graph); - Graph g; - test_graph(g); - } - { - typedef directed_graph Graph; - BOOST_META_ASSERT(is_directed_graph); - BOOST_META_ASSERT(is_multigraph); - BOOST_META_ASSERT(is_incidence_graph); - BOOST_META_ASSERT(is_bidirectional_graph); - BOOST_META_ASSERT(is_directed_bidirectional_graph); - BOOST_META_ASSERT(has_vertex_property); - BOOST_META_ASSERT(has_bundled_vertex_property); - BOOST_META_ASSERT(has_edge_property); - BOOST_META_ASSERT(has_bundled_edge_property); - BOOST_META_ASSERT(is_mutable_graph); - BOOST_META_ASSERT(is_mutable_property_graph); - Graph g; - test_graph(g); - } - { - typedef adjacency_list Graph; - BOOST_META_ASSERT(is_undirected_graph); - BOOST_META_ASSERT(is_multigraph); - BOOST_META_ASSERT(is_incidence_graph); - BOOST_META_ASSERT(is_bidirectional_graph); - BOOST_META_ASSERT(has_vertex_property); - BOOST_META_ASSERT(has_bundled_vertex_property); - BOOST_META_ASSERT(has_edge_property); - BOOST_META_ASSERT(has_bundled_edge_property); - BOOST_META_ASSERT(is_add_only_property_graph); - Graph g; - test_graph(g); - } - { - typedef adjacency_list Graph; - Graph g; - BOOST_META_ASSERT(is_directed_graph); - BOOST_META_ASSERT(is_multigraph); - BOOST_META_ASSERT(is_incidence_graph); - BOOST_META_ASSERT(!is_bidirectional_graph); - BOOST_META_ASSERT(is_directed_unidirectional_graph); - BOOST_META_ASSERT(has_vertex_property); - BOOST_META_ASSERT(has_bundled_vertex_property); - BOOST_META_ASSERT(has_edge_property); - BOOST_META_ASSERT(has_bundled_edge_property); - BOOST_META_ASSERT(is_add_only_property_graph); - test_graph(g); - } - { - // Common bidi adjlist - typedef adjacency_list Graph; - BOOST_META_ASSERT(is_directed_graph); - BOOST_META_ASSERT(is_multigraph); - BOOST_META_ASSERT(is_incidence_graph); - BOOST_META_ASSERT(is_bidirectional_graph); - BOOST_META_ASSERT(is_directed_bidirectional_graph); - BOOST_META_ASSERT(has_vertex_property); - BOOST_META_ASSERT(has_bundled_vertex_property); - BOOST_META_ASSERT(has_edge_property); - BOOST_META_ASSERT(has_bundled_edge_property); - BOOST_META_ASSERT(is_add_only_property_graph); - Graph g; - test_graph(g); - } - { - // Same as above, but testing VL==listS - typedef adjacency_list Graph; - BOOST_META_ASSERT(is_directed_graph); - BOOST_META_ASSERT(is_multigraph); - BOOST_META_ASSERT(is_incidence_graph); - BOOST_META_ASSERT(is_bidirectional_graph); - BOOST_META_ASSERT(is_directed_bidirectional_graph); - BOOST_META_ASSERT(has_vertex_property); - BOOST_META_ASSERT(has_bundled_vertex_property); - BOOST_META_ASSERT(has_edge_property); - BOOST_META_ASSERT(has_bundled_edge_property); - BOOST_META_ASSERT(is_mutable_property_graph); - Graph g; - test_graph(g); - } - { - typedef adjacency_matrix Graph; - BOOST_META_ASSERT(is_directed_graph); - BOOST_META_ASSERT(!is_multigraph); - BOOST_META_ASSERT(has_vertex_property); - BOOST_META_ASSERT(has_bundled_vertex_property); - BOOST_META_ASSERT(has_edge_property); - BOOST_META_ASSERT(has_bundled_edge_property); - BOOST_META_ASSERT(is_mutable_edge_graph); - BOOST_META_ASSERT(is_mutable_edge_property_graph); - Graph g(N); - test_graph(g); - } - { - typedef adjacency_matrix Graph; - BOOST_META_ASSERT(is_directed_graph); - BOOST_META_ASSERT(!is_multigraph); - BOOST_META_ASSERT(has_vertex_property); - BOOST_META_ASSERT(has_bundled_vertex_property); - BOOST_META_ASSERT(has_edge_property); - BOOST_META_ASSERT(has_bundled_edge_property); - BOOST_META_ASSERT(is_mutable_edge_graph); - BOOST_META_ASSERT(is_mutable_edge_property_graph); - Graph g(N); - test_graph(g); - } - { - typedef labeled_graph, unsigned> Graph; - BOOST_META_ASSERT(is_directed_graph); - BOOST_META_ASSERT(is_multigraph); - BOOST_META_ASSERT(is_incidence_graph); - BOOST_META_ASSERT(is_bidirectional_graph); - BOOST_META_ASSERT(is_directed_bidirectional_graph); - BOOST_META_ASSERT(is_labeled_mutable_property_graph); - BOOST_META_ASSERT(is_labeled_graph); - BOOST_META_ASSERT(!has_vertex_property); - BOOST_META_ASSERT(!has_bundled_vertex_property); - BOOST_META_ASSERT(!has_edge_property); - BOOST_META_ASSERT(!has_bundled_edge_property); - BOOST_META_ASSERT(is_labeled_mutable_graph); - Graph g; - test_graph(g); - } + // Bootstrap all of the tests by declaring a kind graph and asserting some + // basic properties about it. + { + typedef undirected_graph< VertexBundle, EdgeBundle, GraphBundle > Graph; + BOOST_META_ASSERT(is_undirected_graph< Graph >); + BOOST_META_ASSERT(is_multigraph< Graph >); + BOOST_META_ASSERT(is_incidence_graph< Graph >); + BOOST_META_ASSERT(is_bidirectional_graph< Graph >); + BOOST_META_ASSERT(has_vertex_property< Graph >); + BOOST_META_ASSERT(has_bundled_vertex_property< Graph >); + BOOST_META_ASSERT(has_edge_property< Graph >); + BOOST_META_ASSERT(has_bundled_edge_property< Graph >); + BOOST_META_ASSERT(is_mutable_graph< Graph >); + BOOST_META_ASSERT(is_mutable_property_graph< Graph >); + Graph g; + test_graph(g); + } + { + typedef directed_graph< VertexBundle, EdgeBundle, GraphBundle > Graph; + BOOST_META_ASSERT(is_directed_graph< Graph >); + BOOST_META_ASSERT(is_multigraph< Graph >); + BOOST_META_ASSERT(is_incidence_graph< Graph >); + BOOST_META_ASSERT(is_bidirectional_graph< Graph >); + BOOST_META_ASSERT(is_directed_bidirectional_graph< Graph >); + BOOST_META_ASSERT(has_vertex_property< Graph >); + BOOST_META_ASSERT(has_bundled_vertex_property< Graph >); + BOOST_META_ASSERT(has_edge_property< Graph >); + BOOST_META_ASSERT(has_bundled_edge_property< Graph >); + BOOST_META_ASSERT(is_mutable_graph< Graph >); + BOOST_META_ASSERT(is_mutable_property_graph< Graph >); + Graph g; + test_graph(g); + } + { + typedef adjacency_list< vecS, vecS, undirectedS, VertexBundle, + EdgeBundle, GraphBundle > + Graph; + BOOST_META_ASSERT(is_undirected_graph< Graph >); + BOOST_META_ASSERT(is_multigraph< Graph >); + BOOST_META_ASSERT(is_incidence_graph< Graph >); + BOOST_META_ASSERT(is_bidirectional_graph< Graph >); + BOOST_META_ASSERT(has_vertex_property< Graph >); + BOOST_META_ASSERT(has_bundled_vertex_property< Graph >); + BOOST_META_ASSERT(has_edge_property< Graph >); + BOOST_META_ASSERT(has_bundled_edge_property< Graph >); + BOOST_META_ASSERT(is_add_only_property_graph< Graph >); + Graph g; + test_graph(g); + } + { + typedef adjacency_list< vecS, vecS, directedS, VertexBundle, EdgeBundle, + GraphBundle > + Graph; + Graph g; + BOOST_META_ASSERT(is_directed_graph< Graph >); + BOOST_META_ASSERT(is_multigraph< Graph >); + BOOST_META_ASSERT(is_incidence_graph< Graph >); + BOOST_META_ASSERT(!is_bidirectional_graph< Graph >); + BOOST_META_ASSERT(is_directed_unidirectional_graph< Graph >); + BOOST_META_ASSERT(has_vertex_property< Graph >); + BOOST_META_ASSERT(has_bundled_vertex_property< Graph >); + BOOST_META_ASSERT(has_edge_property< Graph >); + BOOST_META_ASSERT(has_bundled_edge_property< Graph >); + BOOST_META_ASSERT(is_add_only_property_graph< Graph >); + test_graph(g); + } + { + // Common bidi adjlist + typedef adjacency_list< vecS, vecS, bidirectionalS, VertexBundle, + EdgeBundle, GraphBundle > + Graph; + BOOST_META_ASSERT(is_directed_graph< Graph >); + BOOST_META_ASSERT(is_multigraph< Graph >); + BOOST_META_ASSERT(is_incidence_graph< Graph >); + BOOST_META_ASSERT(is_bidirectional_graph< Graph >); + BOOST_META_ASSERT(is_directed_bidirectional_graph< Graph >); + BOOST_META_ASSERT(has_vertex_property< Graph >); + BOOST_META_ASSERT(has_bundled_vertex_property< Graph >); + BOOST_META_ASSERT(has_edge_property< Graph >); + BOOST_META_ASSERT(has_bundled_edge_property< Graph >); + BOOST_META_ASSERT(is_add_only_property_graph< Graph >); + Graph g; + test_graph(g); + } + { + // Same as above, but testing VL==listS + typedef adjacency_list< vecS, listS, bidirectionalS, VertexBundle, + EdgeBundle, GraphBundle > + Graph; + BOOST_META_ASSERT(is_directed_graph< Graph >); + BOOST_META_ASSERT(is_multigraph< Graph >); + BOOST_META_ASSERT(is_incidence_graph< Graph >); + BOOST_META_ASSERT(is_bidirectional_graph< Graph >); + BOOST_META_ASSERT(is_directed_bidirectional_graph< Graph >); + BOOST_META_ASSERT(has_vertex_property< Graph >); + BOOST_META_ASSERT(has_bundled_vertex_property< Graph >); + BOOST_META_ASSERT(has_edge_property< Graph >); + BOOST_META_ASSERT(has_bundled_edge_property< Graph >); + BOOST_META_ASSERT(is_mutable_property_graph< Graph >); + Graph g; + test_graph(g); + } + { + typedef adjacency_matrix< directedS, VertexBundle, EdgeBundle, + GraphBundle > + Graph; + BOOST_META_ASSERT(is_directed_graph< Graph >); + BOOST_META_ASSERT(!is_multigraph< Graph >); + BOOST_META_ASSERT(has_vertex_property< Graph >); + BOOST_META_ASSERT(has_bundled_vertex_property< Graph >); + BOOST_META_ASSERT(has_edge_property< Graph >); + BOOST_META_ASSERT(has_bundled_edge_property< Graph >); + BOOST_META_ASSERT(is_mutable_edge_graph< Graph >); + BOOST_META_ASSERT(is_mutable_edge_property_graph< Graph >); + Graph g(N); + test_graph(g); + } + { + typedef adjacency_matrix< directedS, VertexBundle, EdgeBundle > Graph; + BOOST_META_ASSERT(is_directed_graph< Graph >); + BOOST_META_ASSERT(!is_multigraph< Graph >); + BOOST_META_ASSERT(has_vertex_property< Graph >); + BOOST_META_ASSERT(has_bundled_vertex_property< Graph >); + BOOST_META_ASSERT(has_edge_property< Graph >); + BOOST_META_ASSERT(has_bundled_edge_property< Graph >); + BOOST_META_ASSERT(is_mutable_edge_graph< Graph >); + BOOST_META_ASSERT(is_mutable_edge_property_graph< Graph >); + Graph g(N); + test_graph(g); + } + { + typedef labeled_graph< directed_graph<>, unsigned > Graph; + BOOST_META_ASSERT(is_directed_graph< Graph >); + BOOST_META_ASSERT(is_multigraph< Graph >); + BOOST_META_ASSERT(is_incidence_graph< Graph >); + BOOST_META_ASSERT(is_bidirectional_graph< Graph >); + BOOST_META_ASSERT(is_directed_bidirectional_graph< Graph >); + BOOST_META_ASSERT(is_labeled_mutable_property_graph< Graph >); + BOOST_META_ASSERT(is_labeled_graph< Graph >); + BOOST_META_ASSERT(!has_vertex_property< Graph >); + BOOST_META_ASSERT(!has_bundled_vertex_property< Graph >); + BOOST_META_ASSERT(!has_edge_property< Graph >); + BOOST_META_ASSERT(!has_bundled_edge_property< Graph >); + BOOST_META_ASSERT(is_labeled_mutable_graph< Graph >); + Graph g; + test_graph(g); + } - // FIXME: CSR doesn't have mutability traits so we can't generalize the - // constructions of the required graph. Just assert the properties for now. - // NOTE: CSR graphs are also atypical in that they don't have "normal" - // vertex and edge properties. They're "abnormal" in the sense that they have - // a valid bundled type, but the property types are no_property. - { - typedef compressed_sparse_row_graph< - directedS, VertexBundle, EdgeBundle, GraphBundle - > Graph; - BOOST_META_ASSERT(is_directed_graph); - BOOST_META_ASSERT(is_multigraph); - BOOST_META_ASSERT(has_graph_property); - BOOST_META_ASSERT(has_bundled_graph_property); - BOOST_META_ASSERT(!has_vertex_property); - BOOST_META_ASSERT(has_bundled_vertex_property); - BOOST_META_ASSERT(!has_edge_property); - BOOST_META_ASSERT(has_bundled_edge_property); - } - { - typedef compressed_sparse_row_graph< - bidirectionalS, VertexBundle, EdgeBundle, GraphBundle - > Graph; - BOOST_META_ASSERT(is_directed_graph); - BOOST_META_ASSERT(is_multigraph); - BOOST_META_ASSERT(has_graph_property); - BOOST_META_ASSERT(has_bundled_graph_property); - BOOST_META_ASSERT(!has_vertex_property); - BOOST_META_ASSERT(has_bundled_vertex_property); - BOOST_META_ASSERT(!has_edge_property); - BOOST_META_ASSERT(has_bundled_edge_property); - } - - - // TODO: What other kinds of graphs do we have here... + // FIXME: CSR doesn't have mutability traits so we can't generalize the + // constructions of the required graph. Just assert the properties for now. + // NOTE: CSR graphs are also atypical in that they don't have "normal" + // vertex and edge properties. They're "abnormal" in the sense that they + // have a valid bundled type, but the property types are no_property. + { + typedef compressed_sparse_row_graph< directedS, VertexBundle, + EdgeBundle, GraphBundle > + Graph; + BOOST_META_ASSERT(is_directed_graph< Graph >); + BOOST_META_ASSERT(is_multigraph< Graph >); + BOOST_META_ASSERT(has_graph_property< Graph >); + BOOST_META_ASSERT(has_bundled_graph_property< Graph >); + BOOST_META_ASSERT(!has_vertex_property< Graph >); + BOOST_META_ASSERT(has_bundled_vertex_property< Graph >); + BOOST_META_ASSERT(!has_edge_property< Graph >); + BOOST_META_ASSERT(has_bundled_edge_property< Graph >); + } + { + typedef compressed_sparse_row_graph< bidirectionalS, VertexBundle, + EdgeBundle, GraphBundle > + Graph; + BOOST_META_ASSERT(is_directed_graph< Graph >); + BOOST_META_ASSERT(is_multigraph< Graph >); + BOOST_META_ASSERT(has_graph_property< Graph >); + BOOST_META_ASSERT(has_bundled_graph_property< Graph >); + BOOST_META_ASSERT(!has_vertex_property< Graph >); + BOOST_META_ASSERT(has_bundled_vertex_property< Graph >); + BOOST_META_ASSERT(!has_edge_property< Graph >); + BOOST_META_ASSERT(has_bundled_edge_property< Graph >); + } + // TODO: What other kinds of graphs do we have here... } - diff --git a/test/test_iteration.hpp b/test/test_iteration.hpp index 7842dd39c..6ce9e4b7d 100644 --- a/test/test_iteration.hpp +++ b/test/test_iteration.hpp @@ -8,21 +8,23 @@ #define TEST_ITERATION_HPP #include +#include #include +#include "test_graph.hpp" + /** @name Test Vertex List * Test the vertex list interface. Note that there are currently no graphs that * do not expose this interface. */ //@{ -template -void test_vertex_list_graph(Graph const& g) { +template < typename Graph > void test_vertex_list_graph(Graph const& g) +{ using namespace boost; - BOOST_CONCEPT_ASSERT((VertexListGraphConcept)); + BOOST_CONCEPT_ASSERT((VertexListGraphConcept< Graph >)); - std::cout << "...test_vertex_list_graph\n"; - typedef typename graph_traits::vertex_iterator Iterator; - typedef std::pair Range; + typedef typename graph_traits< Graph >::vertex_iterator Iterator; + typedef std::pair< Iterator, Iterator > Range; Range rng = vertices(g); BOOST_ASSERT(num_vertices(g) == N); @@ -36,14 +38,13 @@ void test_vertex_list_graph(Graph const& g) { * do not expose this interface. */ //@{ -template -void test_edge_list_graph(Graph const& g) { +template < typename Graph > void test_edge_list_graph(Graph const& g) +{ using namespace boost; - BOOST_CONCEPT_ASSERT((EdgeListGraphConcept)); + BOOST_CONCEPT_ASSERT((EdgeListGraphConcept< Graph >)); - std::cout << "...test_edge_list_graph\n"; - typedef typename graph_traits::edge_iterator Iterator; - typedef std::pair Range; + typedef typename graph_traits< Graph >::edge_iterator Iterator; + typedef std::pair< Iterator, Iterator > Range; Range rng = edges(g); BOOST_ASSERT(num_edges(g) == M); diff --git a/test/test_properties.hpp b/test/test_properties.hpp index 751a838dd..f36e14267 100644 --- a/test/test_properties.hpp +++ b/test/test_properties.hpp @@ -7,63 +7,74 @@ #ifndef TEST_PROPERTIES_HPP #define TEST_PROPERTIES_HPP +#include #include +#include -template T const& as_const(T& x) { return x; } -template void ignore(T const&) { } +#include "test_graph.hpp" -template -void test_graph_bundle(Graph& g, boost::mpl::true_) { - using namespace boost; - std::cout << "...test_graph_bundle\n"; +template < typename T > T const& as_const(T& x) { return x; } +template < typename T > void ignore(T const&) {} - GraphBundle& b1 = g[graph_bundle]; - GraphBundle& b2 = get_property(g); - ignore(b1); ignore(b2); +template < typename Graph > void test_graph_bundle(Graph& g, boost::mpl::true_) +{ + using namespace boost; + std::cout << "...test_graph_bundle\n"; + + GraphBundle& b1 = g[graph_bundle]; + GraphBundle& b2 = get_property(g); + ignore(b1); + ignore(b2); - GraphBundle const& cb1 = ::as_const(g)[graph_bundle]; - GraphBundle const& cb2 = get_property(g); - ignore(cb1); ignore(cb2); + GraphBundle const& cb1 = ::as_const(g)[graph_bundle]; + GraphBundle const& cb2 = get_property(g); + ignore(cb1); + ignore(cb2); } -template -void test_graph_bundle(Graph& g, boost::mpl::false_) -{ } +template < typename Graph > void test_graph_bundle(Graph& g, boost::mpl::false_) +{ +} /** @name Test Vertex Bundle * Exercise the vertex bundle. Note that this is expected to be of type * VertexBundle. */ //@{ -template -void test_vertex_bundle(Graph& g, VertexSet const& verts, boost::mpl::true_) { - using namespace boost; - BOOST_CONCEPT_ASSERT((GraphConcept)); - typedef typename graph_traits::vertex_descriptor Vertex; - BOOST_CONCEPT_ASSERT((PropertyGraphConcept)); +template < typename Graph, typename VertexSet > +void test_vertex_bundle(Graph& g, VertexSet const& verts, boost::mpl::true_) +{ + using namespace boost; + BOOST_CONCEPT_ASSERT((GraphConcept< Graph >)); + typedef typename graph_traits< Graph >::vertex_descriptor Vertex; + BOOST_CONCEPT_ASSERT( + (PropertyGraphConcept< Graph, Vertex, vertex_bundle_t >)); // Test bundling via the graph object on the lollipop vertex. - Vertex v = verts[5]; - VertexBundle& b = g[v]; - b.value = 10; - BOOST_ASSERT(g[v].value == 10); - - // Test bundling via the property map. - typedef typename property_map::type BundleMap; - BOOST_CONCEPT_ASSERT((ReadWritePropertyMapConcept)); - BundleMap map = get(&VertexBundle::value, g); - put(map, v, 5); - BOOST_ASSERT(get(map, v) == 5); - - typedef typename property_map::const_type ConstBundleMap; - BOOST_CONCEPT_ASSERT((ReadablePropertyMapConcept)); - ConstBundleMap cmap = get(&VertexBundle::value, (Graph const&)g); - BOOST_ASSERT(get(cmap, v) == 5); + Vertex v = verts[5]; + VertexBundle& b = g[v]; + b.value = 10; + BOOST_ASSERT(g[v].value == 10); + + // Test bundling via the property map. + typedef typename property_map< Graph, int VertexBundle::* >::type BundleMap; + BOOST_CONCEPT_ASSERT((ReadWritePropertyMapConcept< BundleMap, Vertex >)); + BundleMap map = get(&VertexBundle::value, g); + put(map, v, 5); + BOOST_ASSERT(get(map, v) == 5); + + typedef typename property_map< Graph, int VertexBundle::* >::const_type + ConstBundleMap; + BOOST_CONCEPT_ASSERT( + (ReadablePropertyMapConcept< ConstBundleMap, Vertex >)); + ConstBundleMap cmap = get(&VertexBundle::value, (Graph const&)g); + BOOST_ASSERT(get(cmap, v) == 5); } -template +template < typename Graph, typename VertexSet > void test_vertex_bundle(Graph&, VertexSet const&, boost::mpl::false_) -{ } +{ +} //@} /** @name Test Edge Bundle @@ -71,12 +82,13 @@ void test_vertex_bundle(Graph&, VertexSet const&, boost::mpl::false_) * EdgeBundle. */ //@{ -template -void test_edge_bundle(Graph& g, VertexSet const& verts, boost::mpl::true_) { +template < typename Graph, typename VertexSet > +void test_edge_bundle(Graph& g, VertexSet const& verts, boost::mpl::true_) +{ using namespace boost; - BOOST_CONCEPT_ASSERT((GraphConcept)); - typedef typename boost::graph_traits::edge_descriptor Edge; - BOOST_CONCEPT_ASSERT((PropertyGraphConcept)); + BOOST_CONCEPT_ASSERT((GraphConcept< Graph >)); + typedef typename boost::graph_traits< Graph >::edge_descriptor Edge; + BOOST_CONCEPT_ASSERT((PropertyGraphConcept< Graph, Edge, edge_bundle_t >)); std::cout << "...test_edge_bundle\n"; @@ -87,21 +99,24 @@ void test_edge_bundle(Graph& g, VertexSet const& verts, boost::mpl::true_) { BOOST_ASSERT(g[e].value == 10); // Test bundling via the property map. - typedef typename boost::property_map::type BundleMap; - BOOST_CONCEPT_ASSERT((ReadWritePropertyMapConcept)); + typedef typename boost::property_map< Graph, int EdgeBundle::* >::type + BundleMap; + BOOST_CONCEPT_ASSERT((ReadWritePropertyMapConcept< BundleMap, Edge >)); BundleMap map = get(&EdgeBundle::value, g); put(map, e, 5); BOOST_ASSERT(get(map, e) == 5); - typedef typename boost::property_map::const_type ConstBundleMap; - BOOST_CONCEPT_ASSERT((ReadablePropertyMapConcept)); + typedef typename boost::property_map< Graph, int EdgeBundle::* >::const_type + ConstBundleMap; + BOOST_CONCEPT_ASSERT((ReadablePropertyMapConcept< BundleMap, Edge >)); ConstBundleMap cmap = get(&EdgeBundle::value, (Graph const&)g); BOOST_ASSERT(get(cmap, e) == 5); } -template +template < typename Graph, typename VertexSet > void test_edge_bundle(Graph&, VertexSet const&, boost::mpl::false_) -{ } +{ +} //@} /** @@ -109,17 +124,18 @@ void test_edge_bundle(Graph&, VertexSet const&, boost::mpl::false_) * bundled or not. This test could also be expanded to test non-bundled * properties. This just bootstraps the tests. */ -template -void test_properties(Graph& g, VertexSet const& verts) { - using namespace boost; +template < typename Graph, typename VertexSet > +void test_properties(Graph& g, VertexSet const& verts) +{ + using namespace boost; - typename has_bundled_graph_property::type graph_bundled; - typename has_bundled_vertex_property::type vertex_bundled; - typename has_bundled_edge_property::type edge_bundled; + typename has_bundled_graph_property< Graph >::type graph_bundled; + typename has_bundled_vertex_property< Graph >::type vertex_bundled; + typename has_bundled_edge_property< Graph >::type edge_bundled; - test_graph_bundle(g, graph_bundled); - test_vertex_bundle(g, verts, vertex_bundled); - test_edge_bundle(g, verts, edge_bundled); + test_graph_bundle(g, graph_bundled); + test_vertex_bundle(g, verts, vertex_bundled); + test_edge_bundle(g, verts, edge_bundled); } //@} diff --git a/test/tiernan_all_cycles.cpp b/test/tiernan_all_cycles.cpp index 0e77c784c..75ac47ad4 100644 --- a/test/tiernan_all_cycles.cpp +++ b/test/tiernan_all_cycles.cpp @@ -19,11 +19,9 @@ using namespace boost; struct cycle_validator { - cycle_validator(size_t& c) - : cycles(c) - { } + cycle_validator(size_t& c) : cycles(c) {} - template + template < typename Path, typename Graph > void cycle(const Path& p, const Graph& g) { ++cycles; @@ -32,7 +30,8 @@ struct cycle_validator // front - it's not validating that we find all paths, just // that the paths are valid. typename Path::const_iterator i, j, last = prior(p.end()); - for(i = p.begin(); i != last; ++i) { + for (i = p.begin(); i != last; ++i) + { j = boost::next(i); BOOST_ASSERT(edge(*i, *j, g).second); } @@ -42,10 +41,9 @@ struct cycle_validator size_t& cycles; }; -template -void test() +template < typename Graph > void test() { - typedef erdos_renyi_iterator er; + typedef erdos_renyi_iterator< boost::minstd_rand, Graph > er; // Generate random graphs with 15 vertices and 15% probability // of edge connection. @@ -63,15 +61,14 @@ void test() cout << "# cycles: " << vis.cycles << "\n"; } -int -main(int, char *[]) +int main(int, char*[]) { typedef undirected_graph<> Graph; typedef directed_graph<> DiGraph; std::cout << "*** undirected ***\n"; - test(); + test< Graph >(); std::cout << "*** directed ***\n"; - test(); + test< DiGraph >(); } diff --git a/test/transitive_closure_test.cpp b/test/transitive_closure_test.cpp index cdae591dc..8698a928e 100644 --- a/test/transitive_closure_test.cpp +++ b/test/transitive_closure_test.cpp @@ -13,144 +13,167 @@ #include #include #include -#include +#include using namespace std; using namespace boost; -void generate_graph(int n, double p, vector< vector >& r1) +void generate_graph(int n, double p, vector< vector< int > >& r1) { - static class { - public: - double operator()() { - return double(rand())/RAND_MAX; - } - } gen; - r1.clear(); - r1.resize(n); - for (int i = 0; i < n; ++i) - for (int j = 0; j < n; ++j) - if (gen() < p) - r1[i].push_back(j); + static class + { + public: + double operator()() { return double(rand()) / RAND_MAX; } + } gen; + r1.clear(); + r1.resize(n); + for (int i = 0; i < n; ++i) + for (int j = 0; j < n; ++j) + if (gen() < p) + r1[i].push_back(j); } -template -typename graph_traits::degree_size_type -num_incident(typename graph_traits::vertex_descriptor u, - typename graph_traits::vertex_descriptor v, - const Graph& g) +template < class Graph > +typename graph_traits< Graph >::degree_size_type num_incident( + typename graph_traits< Graph >::vertex_descriptor u, + typename graph_traits< Graph >::vertex_descriptor v, const Graph& g) { - typename graph_traits::degree_size_type d = 0; - typename graph_traits::out_edge_iterator i, i_end; - for (boost::tie(i, i_end) = out_edges(u, g); i != i_end; ++i) - if (target(*i, g) == v) - ++d; - return d; + typename graph_traits< Graph >::degree_size_type d = 0; + typename graph_traits< Graph >::out_edge_iterator i, i_end; + for (boost::tie(i, i_end) = out_edges(u, g); i != i_end; ++i) + if (target(*i, g) == v) + ++d; + return d; } - // (i,j) is in E' iff j is reachable from i // Hmm, is_reachable does not detect when there is a non-trivial path // from i to i. It always returns true for is_reachable(i,i). // This needs to be fixed/worked around. -template +template < typename Graph, typename GraphTC > bool check_transitive_closure(Graph& g, GraphTC& tc) { - typename graph_traits::vertex_iterator i, i_end; - for (boost::tie(i, i_end) = vertices(g); i != i_end; ++i) { - typename graph_traits::vertex_iterator j, j_end; - for (boost::tie(j, j_end) = vertices(g); j != j_end; ++j) { - bool g_has_edge; - typename graph_traits::edge_descriptor e_g; - typename graph_traits::degree_size_type num_tc; - boost::tie (e_g, g_has_edge) = edge(*i, *j, g); - num_tc = num_incident(*i, *j, tc); - if (*i == *j) { - if (g_has_edge) { - if (num_tc != 1) - return false; - } else { - bool can_reach = false; - typename graph_traits::adjacency_iterator k, k_end; - for (boost::tie(k, k_end) = adjacent_vertices(*i, g); k != k_end; ++k) { - std::vector color_map_vec(num_vertices(g)); - if (is_reachable(*k, *i, g, boost::make_iterator_property_map(color_map_vec.begin(), get(boost::vertex_index, g)))) { - can_reach = true; - break; + typename graph_traits< Graph >::vertex_iterator i, i_end; + for (boost::tie(i, i_end) = vertices(g); i != i_end; ++i) + { + typename graph_traits< Graph >::vertex_iterator j, j_end; + for (boost::tie(j, j_end) = vertices(g); j != j_end; ++j) + { + bool g_has_edge; + typename graph_traits< Graph >::edge_descriptor e_g; + typename graph_traits< Graph >::degree_size_type num_tc; + boost::tie(e_g, g_has_edge) = edge(*i, *j, g); + num_tc = num_incident(*i, *j, tc); + if (*i == *j) + { + if (g_has_edge) + { + if (num_tc != 1) + return false; + } + else + { + bool can_reach = false; + typename graph_traits< Graph >::adjacency_iterator k, k_end; + for (boost::tie(k, k_end) = adjacent_vertices(*i, g); + k != k_end; ++k) + { + std::vector< default_color_type > color_map_vec( + num_vertices(g)); + if (is_reachable(*k, *i, g, + boost::make_iterator_property_map( + color_map_vec.begin(), + get(boost::vertex_index, g)))) + { + can_reach = true; + break; + } + } + if (can_reach) + { + if (num_tc != 1) + { + std::cout << "1. " << *i << std::endl; + return false; + } + } + else + { + if (num_tc != 0) + { + std::cout << "2. " << *i << std::endl; + return false; + } + } + } } - } - if (can_reach) { - if (num_tc != 1) { - std::cout << "1. " << *i << std::endl; - return false; + else + { + std::vector< default_color_type > color_map_vec( + num_vertices(g)); + if (is_reachable(*i, *j, g, + boost::make_iterator_property_map(color_map_vec.begin(), + get(boost::vertex_index, g)))) + { + if (num_tc != 1) + return false; + } + else + { + if (num_tc != 0) + return false; + } } - } else { - if (num_tc != 0) { - std::cout << "2. " << *i << std::endl; - return false; - } - } - } - } else { - std::vector color_map_vec(num_vertices(g)); - if (is_reachable(*i, *j, g, boost::make_iterator_property_map(color_map_vec.begin(), get(boost::vertex_index, g)))) { - if (num_tc != 1) - return false; - } else { - if (num_tc != 0) - return false; } - } } - } - return true; + return true; } bool test(int n, double p) { - vector< vector > g1, g1_tc; - generate_graph(n, p, g1); - cout << "Created graph with " << n << " vertices.\n"; + vector< vector< int > > g1, g1_tc; + generate_graph(n, p, g1); + cout << "Created graph with " << n << " vertices.\n"; - vector< vector > g1_c(g1); + vector< vector< int > > g1_c(g1); - { - progress_timer t; - cout << "transitive_closure" << endl; - transitive_closure(g1, g1_tc, vertex_index_map(get(boost::vertex_index, g1))); - } + { + boost::timer::auto_cpu_timer t; + cout << "transitive_closure" << endl; + transitive_closure( + g1, g1_tc, vertex_index_map(get(boost::vertex_index, g1))); + } - if(check_transitive_closure(g1, g1_tc)) - return true; - else { - cout << "Original graph was "; - print_graph(g1, get(boost::vertex_index, g1)); - cout << "Result is "; - print_graph(g1_tc, get(boost::vertex_index, g1_tc)); - return false; - } + if (check_transitive_closure(g1, g1_tc)) + return true; + else + { + cout << "Original graph was "; + print_graph(g1, get(boost::vertex_index, g1)); + cout << "Result is "; + print_graph(g1_tc, get(boost::vertex_index, g1_tc)); + return false; + } } - int main() { - srand(time(0)); - static class { - public: - double operator()() { - return double(rand())/RAND_MAX; - } - } gen; - - - for (size_t i = 0; i < 100; ++i) { - int n = 0 + int(20*gen()); - double p = gen(); - if (!test(n, p)) { - cout << "Failed." << endl; - return 1; + srand(time(0)); + static class + { + public: + double operator()() { return double(rand()) / RAND_MAX; } + } gen; + + for (size_t i = 0; i < 100; ++i) + { + int n = 0 + int(20 * gen()); + double p = gen(); + if (!test(n, p)) + { + cout << "Failed." << endl; + return 1; + } } - } - cout << "Passed." << endl; + cout << "Passed." << endl; } - diff --git a/test/transitive_closure_test2.cpp b/test/transitive_closure_test2.cpp index 02d38f36e..8b7127918 100644 --- a/test/transitive_closure_test2.cpp +++ b/test/transitive_closure_test2.cpp @@ -11,26 +11,28 @@ using namespace std; using namespace boost; typedef adjacency_list<> graph_t; -int main(int argc, char *argv[]) { - graph_t g(5),g_TC; +int main(int argc, char* argv[]) +{ + graph_t g(5), g_TC; - add_edge(0,2,g); - add_edge(1,0,g); - add_edge(1,2,g); - add_edge(1,4,g); - add_edge(3,0,g); - add_edge(3,2,g); - add_edge(4,2,g); - add_edge(4,3,g); + add_edge(0, 2, g); + add_edge(1, 0, g); + add_edge(1, 2, g); + add_edge(1, 4, g); + add_edge(3, 0, g); + add_edge(3, 2, g); + add_edge(4, 2, g); + add_edge(4, 3, g); - transitive_closure(g,g_TC); + transitive_closure(g, g_TC); - cout << "original graph: 0->2, 1->0, 1->2, 1->4, 3->0, 3->2, 4->2, 4->3" - << endl; - cout << "transitive closure: "; - graph_t::edge_iterator i,iend; - for(boost::tie(i,iend) = edges(g_TC);i!=iend;++i) { - cout << source(*i,g_TC) << "->" << target(*i,g_TC) << " "; - } - cout << endl; + cout << "original graph: 0->2, 1->0, 1->2, 1->4, 3->0, 3->2, 4->2, 4->3" + << endl; + cout << "transitive closure: "; + graph_t::edge_iterator i, iend; + for (boost::tie(i, iend) = edges(g_TC); i != iend; ++i) + { + cout << source(*i, g_TC) << "->" << target(*i, g_TC) << " "; + } + cout << endl; } diff --git a/test/two_graphs_common_spanning_trees_test.cpp b/test/two_graphs_common_spanning_trees_test.cpp index 741845a39..af641bd65 100644 --- a/test/two_graphs_common_spanning_trees_test.cpp +++ b/test/two_graphs_common_spanning_trees_test.cpp @@ -8,141 +8,124 @@ // Efficient Algorithm for Common Spanning Tree Problem // Electron. Lett., 28 April 1983, Volume 19, Issue 9, p.346-347 - #include #include #include #include #include -#include +#include #include #include using namespace boost::assign; - namespace boost { +typedef boost::adjacency_list< boost::vecS, // OutEdgeList + boost::vecS, // VertexList + boost::undirectedS, // Directed + boost::no_property, // VertexProperties + boost::no_property, // EdgeProperties + boost::no_property, // GraphProperties + boost::listS // EdgeList + > + Graph; -typedef -boost::adjacency_list - < - boost::vecS, // OutEdgeList - boost::vecS, // VertexList - boost::undirectedS, // Directed - boost::no_property, // VertexProperties - boost::no_property, // EdgeProperties - boost::no_property, // GraphProperties - boost::listS // EdgeList - > -Graph -; - -typedef -boost::graph_traits::vertex_descriptor -vertex_descriptor; +typedef boost::graph_traits< Graph >::vertex_descriptor vertex_descriptor; -typedef -boost::graph_traits::edge_descriptor -edge_descriptor; +typedef boost::graph_traits< Graph >::edge_descriptor edge_descriptor; -typedef -boost::graph_traits::vertex_iterator -vertex_iterator; +typedef boost::graph_traits< Graph >::vertex_iterator vertex_iterator; -typedef -boost::graph_traits::edge_iterator -edge_iterator; +typedef boost::graph_traits< Graph >::edge_iterator edge_iterator; - -template < typename Coll, typename Seq > -struct check_edge +template < typename Coll, typename Seq > struct check_edge { public: - BOOST_CONCEPT_ASSERT((RandomAccessContainer)); - BOOST_CONCEPT_ASSERT((RandomAccessContainer)); - - typedef typename Coll::value_type coll_value_type; - typedef typename Seq::value_type seq_value_type; + BOOST_CONCEPT_ASSERT((RandomAccessContainer< Coll >)); + BOOST_CONCEPT_ASSERT((RandomAccessContainer< Seq >)); - BOOST_STATIC_ASSERT((is_same::value)); - BOOST_STATIC_ASSERT((is_same::value)); + typedef typename Coll::value_type coll_value_type; + typedef typename Seq::value_type seq_value_type; - void operator()(Coll& coll, Seq& seq) - { - bool found = false; + BOOST_STATIC_ASSERT((is_same< coll_value_type, Seq >::value)); + BOOST_STATIC_ASSERT((is_same< seq_value_type, bool >::value)); - for(typename Coll::iterator iterator = coll.begin(); - !found && iterator != coll.end(); ++iterator) + void operator()(Coll& coll, Seq& seq) { - Seq& coll_seq = *iterator; + bool found = false; - BOOST_REQUIRE(coll_seq.size() == seq.size()); + for (typename Coll::iterator iterator = coll.begin(); + !found && iterator != coll.end(); ++iterator) + { + Seq& coll_seq = *iterator; - found = true; - for(typename Seq::size_type pos = 0; found && pos < seq.size(); ++pos) { - found &= coll_seq[pos] == seq[pos]; - } - } + BOOST_TEST(coll_seq.size() == seq.size()); - BOOST_REQUIRE(found); - } -}; + found = true; + for (typename Seq::size_type pos = 0; found && pos < seq.size(); + ++pos) + { + found &= coll_seq[pos] == seq[pos]; + } + } + BOOST_TEST(found); + } +}; void two_graphs_common_spanning_trees_test() { - Graph iG, vG; - std::vector< edge_descriptor > iG_o; - std::vector< edge_descriptor > vG_o; - - iG_o.push_back(boost::add_edge(0, 1, iG).first); - iG_o.push_back(boost::add_edge(1, 3, iG).first); - iG_o.push_back(boost::add_edge(3, 2, iG).first); - iG_o.push_back(boost::add_edge(1, 5, iG).first); - iG_o.push_back(boost::add_edge(5, 4, iG).first); - iG_o.push_back(boost::add_edge(5, 6, iG).first); - iG_o.push_back(boost::add_edge(5, 3, iG).first); - iG_o.push_back(boost::add_edge(3, 1, iG).first); - iG_o.push_back(boost::add_edge(1, 3, iG).first); - - vG_o.push_back(boost::add_edge(0, 2, vG).first); - vG_o.push_back(boost::add_edge(0, 4, vG).first); - vG_o.push_back(boost::add_edge(0, 5, vG).first); - vG_o.push_back(boost::add_edge(5, 1, vG).first); - vG_o.push_back(boost::add_edge(5, 3, vG).first); - vG_o.push_back(boost::add_edge(5, 6, vG).first); - vG_o.push_back(boost::add_edge(5, 4, vG).first); - vG_o.push_back(boost::add_edge(5, 2, vG).first); - vG_o.push_back(boost::add_edge(2, 6, vG).first); - - std::vector< std::vector > coll; - boost::tree_collector< - std::vector< std::vector >, std::vector - > collector(coll); - std::vector inL(iG_o.size(), false); - - boost::two_graphs_common_spanning_trees(iG, iG_o, vG, vG_o, collector, inL); - - check_edge< std::vector< std::vector >, std::vector > checker; - std::vector check; - - check.clear(); - check += true, true, true, true, true, true, false, false, false; - checker(coll, check); - - check.clear(); - check += true, true, true, true, true, true, false, false, false; - checker(coll, check); + Graph iG, vG; + std::vector< edge_descriptor > iG_o; + std::vector< edge_descriptor > vG_o; + + iG_o.push_back(boost::add_edge(0, 1, iG).first); + iG_o.push_back(boost::add_edge(1, 3, iG).first); + iG_o.push_back(boost::add_edge(3, 2, iG).first); + iG_o.push_back(boost::add_edge(1, 5, iG).first); + iG_o.push_back(boost::add_edge(5, 4, iG).first); + iG_o.push_back(boost::add_edge(5, 6, iG).first); + iG_o.push_back(boost::add_edge(5, 3, iG).first); + iG_o.push_back(boost::add_edge(3, 1, iG).first); + iG_o.push_back(boost::add_edge(1, 3, iG).first); + + vG_o.push_back(boost::add_edge(0, 2, vG).first); + vG_o.push_back(boost::add_edge(0, 4, vG).first); + vG_o.push_back(boost::add_edge(0, 5, vG).first); + vG_o.push_back(boost::add_edge(5, 1, vG).first); + vG_o.push_back(boost::add_edge(5, 3, vG).first); + vG_o.push_back(boost::add_edge(5, 6, vG).first); + vG_o.push_back(boost::add_edge(5, 4, vG).first); + vG_o.push_back(boost::add_edge(5, 2, vG).first); + vG_o.push_back(boost::add_edge(2, 6, vG).first); + + std::vector< std::vector< bool > > coll; + boost::tree_collector< std::vector< std::vector< bool > >, + std::vector< bool > > + collector(coll); + std::vector< bool > inL(iG_o.size(), false); + + boost::two_graphs_common_spanning_trees(iG, iG_o, vG, vG_o, collector, inL); + + check_edge< std::vector< std::vector< bool > >, std::vector< bool > > + checker; + std::vector< bool > check; + + check.clear(); + check += true, true, true, true, true, true, false, false, false; + checker(coll, check); + + check.clear(); + check += true, true, true, true, true, true, false, false, false; + checker(coll, check); } - } - -int test_main ( int argc, char** argv ) +int main(int argc, char** argv) { - boost::two_graphs_common_spanning_trees_test(); - return EXIT_SUCCESS; + boost::two_graphs_common_spanning_trees_test(); + return boost::report_errors(); } diff --git a/test/typestr.hpp b/test/typestr.hpp index 77fd47941..e32c655cd 100644 --- a/test/typestr.hpp +++ b/test/typestr.hpp @@ -15,7 +15,9 @@ #include #endif -template struct type_name { }; +template < typename T > struct type_name +{ +}; /** * Return a string that describes the type of the given template parameter. @@ -23,16 +25,16 @@ template struct type_name { }; * * @todo Rewrite this so that demangle will dynamically allocate the memory. */ -template -std::string typestr() { +template < typename T > std::string typestr() +{ #if defined(__GNUC__) std::size_t const BUFSIZE = 8192; std::size_t n = BUFSIZE; char buf[BUFSIZE]; - abi::__cxa_demangle(typeid(type_name).name(), buf, &n, 0); + abi::__cxa_demangle(typeid(type_name< T >).name(), buf, &n, 0); return std::string(buf, ::strlen(buf)); #else - return typeid(type_name).name(); + return typeid(type_name< T >).name(); #endif } @@ -40,8 +42,9 @@ std::string typestr() { * Return a string that describes the type of the given parameter. The type * name depends on the results of the typeid operator. */ -template -inline std::string typestr(T const&) -{ return typestr(); } +template < typename T > inline std::string typestr(T const&) +{ + return typestr< T >(); +} #endif diff --git a/test/undirected_dfs.cpp b/test/undirected_dfs.cpp index 74e7d3884..8d2f86465 100644 --- a/test/undirected_dfs.cpp +++ b/test/undirected_dfs.cpp @@ -8,7 +8,7 @@ //======================================================================= #include -#include +#include #include #include @@ -19,184 +19,197 @@ #include -template -class dfs_test_visitor { - typedef typename boost::property_traits::value_type ColorValue; - typedef typename boost::color_traits Color; +template < typename ColorMap, typename ParentMap, typename DiscoverTimeMap, + typename FinishTimeMap > +class dfs_test_visitor +{ + typedef typename boost::property_traits< ColorMap >::value_type ColorValue; + typedef typename boost::color_traits< ColorValue > Color; + public: - dfs_test_visitor(ColorMap color, ParentMap p, DiscoverTimeMap d, - FinishTimeMap f) - : m_color(color), m_parent(p), - m_discover_time(d), m_finish_time(f), m_time(0) { } - - template - void initialize_vertex(Vertex u, Graph&) { - BOOST_CHECK( boost::get(m_color, u) == Color::white() ); - } - template - void start_vertex(Vertex u, Graph&) { - BOOST_CHECK( boost::get(m_color, u) == Color::white() ); - } - template - void discover_vertex(Vertex u, Graph&) { - using namespace boost; - BOOST_CHECK( get(m_color, u) == Color::gray() ); - BOOST_CHECK( get(m_color, get(m_parent, u)) == Color::gray() ); - - put(m_discover_time, u, m_time++); - } - template - void examine_edge(Edge e, Graph& g) { - using namespace boost; - BOOST_CHECK( get(m_color, source(e, g)) == Color::gray() ); - } - template - void tree_edge(Edge e, Graph& g) { - using namespace boost; - BOOST_CHECK( get(m_color, target(e, g)) == Color::white() ); - - put(m_parent, target(e, g), source(e, g)); - } - template - void back_edge(Edge e, Graph& g) { - using namespace boost; - BOOST_CHECK( get(m_color, target(e, g)) == Color::gray() ); - } - template - void forward_or_cross_edge(Edge e, Graph& g) { - using namespace boost; - BOOST_CHECK( get(m_color, target(e, g)) == Color::black() ); - } - template - void finish_edge(Edge e, Graph& g) { - using namespace boost; - BOOST_CHECK( - (get(m_color, target(e, g)) == Color::gray()) - || (get(m_color, target(e, g)) == Color::black()) - ); - } - template - void finish_vertex(Vertex u, Graph&) { - using namespace boost; - BOOST_CHECK( get(m_color, u) == Color::black() ); - - put(m_finish_time, u, m_time++); - } + dfs_test_visitor( + ColorMap color, ParentMap p, DiscoverTimeMap d, FinishTimeMap f) + : m_color(color) + , m_parent(p) + , m_discover_time(d) + , m_finish_time(f) + , m_time(0) + { + } + + template < class Vertex, class Graph > + void initialize_vertex(Vertex u, Graph&) + { + BOOST_TEST(boost::get(m_color, u) == Color::white()); + } + template < class Vertex, class Graph > void start_vertex(Vertex u, Graph&) + { + BOOST_TEST(boost::get(m_color, u) == Color::white()); + } + template < class Vertex, class Graph > + void discover_vertex(Vertex u, Graph&) + { + using namespace boost; + BOOST_TEST(get(m_color, u) == Color::gray()); + BOOST_TEST(get(m_color, get(m_parent, u)) == Color::gray()); + + put(m_discover_time, u, m_time++); + } + template < class Edge, class Graph > void examine_edge(Edge e, Graph& g) + { + using namespace boost; + BOOST_TEST(get(m_color, source(e, g)) == Color::gray()); + } + template < class Edge, class Graph > void tree_edge(Edge e, Graph& g) + { + using namespace boost; + BOOST_TEST(get(m_color, target(e, g)) == Color::white()); + + put(m_parent, target(e, g), source(e, g)); + } + template < class Edge, class Graph > void back_edge(Edge e, Graph& g) + { + using namespace boost; + BOOST_TEST(get(m_color, target(e, g)) == Color::gray()); + } + template < class Edge, class Graph > + void forward_or_cross_edge(Edge e, Graph& g) + { + using namespace boost; + BOOST_TEST(get(m_color, target(e, g)) == Color::black()); + } + template < class Edge, class Graph > void finish_edge(Edge e, Graph& g) + { + using namespace boost; + BOOST_TEST((get(m_color, target(e, g)) == Color::gray()) + || (get(m_color, target(e, g)) == Color::black())); + } + template < class Vertex, class Graph > void finish_vertex(Vertex u, Graph&) + { + using namespace boost; + BOOST_TEST(get(m_color, u) == Color::black()); + + put(m_finish_time, u, m_time++); + } + private: - ColorMap m_color; - ParentMap m_parent; - DiscoverTimeMap m_discover_time; - FinishTimeMap m_finish_time; - typename boost::property_traits::value_type m_time; + ColorMap m_color; + ParentMap m_parent; + DiscoverTimeMap m_discover_time; + FinishTimeMap m_finish_time; + typename boost::property_traits< DiscoverTimeMap >::value_type m_time; }; -template -struct dfs_test +template < typename Graph > struct dfs_test { - typedef boost::graph_traits Traits; - typedef typename Traits::vertices_size_type - vertices_size_type; - - static void go(vertices_size_type max_V) { - using namespace boost; - typedef typename Traits::vertex_descriptor vertex_descriptor; - typedef typename boost::property_map::type ColorMap; - typedef typename boost::property_traits::value_type ColorValue; - typedef typename boost::color_traits Color; - typedef typename boost::property_map::type EColorMap; - typedef typename boost::property_traits::value_type EColorValue; - typedef typename boost::color_traits EColor; - - vertices_size_type i, k; - typename Traits::edges_size_type j; - typename Traits::vertex_iterator vi, vi_end, ui, ui_end; - typename Traits::edge_iterator ei, ei_end; - - boost::mt19937 gen; - - for (i = 0; i < max_V; ++i) - for (j = 0; j < i*i; ++j) { - Graph g; - generate_random_graph(g, i, j, gen); - - ColorMap color = get(boost::vertex_color, g); - EColorMap e_color = get(boost::edge_color, g); - std::vector parent(num_vertices(g)); - for (k = 0; k < num_vertices(g); ++k) - parent[k] = k; - std::vector discover_time(num_vertices(g)), - finish_time(num_vertices(g)); - - // Get vertex index map - typedef typename boost::property_map::const_type idx_type; - idx_type idx = get(boost::vertex_index, g); - + typedef boost::graph_traits< Graph > Traits; + typedef typename Traits::vertices_size_type vertices_size_type; + + static void go(vertices_size_type max_V) + { + using namespace boost; + typedef typename Traits::vertex_descriptor vertex_descriptor; typedef - boost::iterator_property_map::iterator, idx_type> - parent_pm_type; - parent_pm_type parent_pm(parent.begin(), idx); + typename boost::property_map< Graph, boost::vertex_color_t >::type + ColorMap; typedef - boost::iterator_property_map::iterator, idx_type> - time_pm_type; - time_pm_type discover_time_pm(discover_time.begin(), idx); - time_pm_type finish_time_pm(finish_time.begin(), idx); - - dfs_test_visitor - vis(color, parent_pm, - discover_time_pm, finish_time_pm); - - boost::undirected_dfs(g, visitor(vis).color_map(color) - .edge_color_map(e_color)); - - // all vertices should be black - for (boost::tie(vi, vi_end) = vertices(g); vi != vi_end; ++vi) - BOOST_CHECK(get(color, *vi) == Color::black()); - - // all edges should be black - for (boost::tie(ei, ei_end) = edges(g); ei != ei_end; ++ei) - BOOST_CHECK(get(e_color, *ei) == EColor::black()); - - // check parenthesis structure of discover/finish times - // See CLR p.480 - for (boost::tie(ui, ui_end) = vertices(g); ui != ui_end; ++ui) - for (boost::tie(vi, vi_end) = vertices(g); vi != vi_end; ++vi) { - vertex_descriptor u = *ui, v = *vi; - if (u != v) { - BOOST_CHECK( finish_time[u] < discover_time[v] - || finish_time[v] < discover_time[u] - || (discover_time[v] < discover_time[u] - && finish_time[u] < finish_time[v] - && boost::is_descendant(u, v, parent_pm)) - || (discover_time[u] < discover_time[v] - && finish_time[v] < finish_time[u] - && boost::is_descendant(v, u, parent_pm)) - ); + typename boost::property_traits< ColorMap >::value_type ColorValue; + typedef typename boost::color_traits< ColorValue > Color; + typedef typename boost::property_map< Graph, boost::edge_color_t >::type + EColorMap; + typedef typename boost::property_traits< EColorMap >::value_type + EColorValue; + typedef typename boost::color_traits< EColorValue > EColor; + + vertices_size_type i, k; + typename Traits::edges_size_type j; + typename Traits::vertex_iterator vi, vi_end, ui, ui_end; + typename Traits::edge_iterator ei, ei_end; + + boost::mt19937 gen; + + for (i = 0; i < max_V; ++i) + for (j = 0; j < i * i; ++j) + { + Graph g; + generate_random_graph(g, i, j, gen); + + ColorMap color = get(boost::vertex_color, g); + EColorMap e_color = get(boost::edge_color, g); + std::vector< vertex_descriptor > parent(num_vertices(g)); + for (k = 0; k < num_vertices(g); ++k) + parent[k] = k; + std::vector< int > discover_time(num_vertices(g)), + finish_time(num_vertices(g)); + + // Get vertex index map + typedef typename boost::property_map< Graph, + boost::vertex_index_t >::const_type idx_type; + idx_type idx = get(boost::vertex_index, g); + + typedef boost::iterator_property_map< + typename std::vector< vertex_descriptor >::iterator, + idx_type > + parent_pm_type; + parent_pm_type parent_pm(parent.begin(), idx); + typedef boost::iterator_property_map< + std::vector< int >::iterator, idx_type > + time_pm_type; + time_pm_type discover_time_pm(discover_time.begin(), idx); + time_pm_type finish_time_pm(finish_time.begin(), idx); + + dfs_test_visitor< ColorMap, parent_pm_type, time_pm_type, + time_pm_type > + vis(color, parent_pm, discover_time_pm, finish_time_pm); + + boost::undirected_dfs( + g, visitor(vis).color_map(color).edge_color_map(e_color)); + + // all vertices should be black + for (boost::tie(vi, vi_end) = vertices(g); vi != vi_end; ++vi) + BOOST_TEST(get(color, *vi) == Color::black()); + + // all edges should be black + for (boost::tie(ei, ei_end) = edges(g); ei != ei_end; ++ei) + BOOST_TEST(get(e_color, *ei) == EColor::black()); + + // check parenthesis structure of discover/finish times + // See CLR p.480 + for (boost::tie(ui, ui_end) = vertices(g); ui != ui_end; ++ui) + for (boost::tie(vi, vi_end) = vertices(g); vi != vi_end; + ++vi) + { + vertex_descriptor u = *ui, v = *vi; + if (u != v) + { + BOOST_TEST(finish_time[u] < discover_time[v] + || finish_time[v] < discover_time[u] + || (discover_time[v] < discover_time[u] + && finish_time[u] < finish_time[v] + && boost::is_descendant(u, v, parent_pm)) + || (discover_time[u] < discover_time[v] + && finish_time[v] < finish_time[u] + && boost::is_descendant(v, u, parent_pm))); + } + } } - } - } - - } + } }; - // usage: undirected_dfs.exe [max-vertices=15] -int test_main(int argc, char* argv[]) +int main(int argc, char* argv[]) { - int max_V = 7; - if (argc > 1) - max_V = atoi(argv[1]); - - // Test undirected graphs. - dfs_test< boost::adjacency_list, - boost::property > - >::go(max_V); - - return 0; + int max_V = 7; + if (argc > 1) + max_V = atoi(argv[1]); + + // Test undirected graphs. + dfs_test< boost::adjacency_list< boost::vecS, boost::vecS, + boost::undirectedS, + boost::property< boost::vertex_color_t, boost::default_color_type >, + boost::property< boost::edge_color_t, boost::default_color_type > > >:: + go(max_V); + + return boost::report_errors(); } - diff --git a/test/vector_graph_cc.cpp b/test/vector_graph_cc.cpp index f9b1cfac5..10478824d 100644 --- a/test/vector_graph_cc.cpp +++ b/test/vector_graph_cc.cpp @@ -19,15 +19,15 @@ #include #include -int main(int,char*[]) +int main(int, char*[]) { - using namespace boost; - // Check "vector as graph" - { - typedef std::vector< std::list > Graph; - BOOST_CONCEPT_ASSERT(( VertexListGraphConcept )); - BOOST_CONCEPT_ASSERT(( IncidenceGraphConcept )); - BOOST_CONCEPT_ASSERT(( AdjacencyGraphConcept )); - } - return 0; + using namespace boost; + // Check "vector as graph" + { + typedef std::vector< std::list< int > > Graph; + BOOST_CONCEPT_ASSERT((VertexListGraphConcept< Graph >)); + BOOST_CONCEPT_ASSERT((IncidenceGraphConcept< Graph >)); + BOOST_CONCEPT_ASSERT((AdjacencyGraphConcept< Graph >)); + } + return 0; } diff --git a/test/vf2_sub_graph_iso_test.cpp b/test/vf2_sub_graph_iso_test.cpp index e5d154364..32cb8574f 100644 --- a/test/vf2_sub_graph_iso_test.cpp +++ b/test/vf2_sub_graph_iso_test.cpp @@ -10,15 +10,15 @@ //======================================================================= // Revision History: -// 8 April 2013: Fixed a typo in random_functor. (Flavio De Lorenzi) +// 8 April 2013: Fixed a typo in random_functor. (Flavio De Lorenzi) #include #include #include #include #include -#include -#include +#include +#include #include #include #include @@ -41,291 +41,336 @@ typedef boost::mt19937 random_generator_type; using namespace boost; #ifndef BOOST_NO_CXX98_RANDOM_SHUFFLE -template -struct random_functor { - random_functor(Generator& g) : g(g) { } - std::size_t operator()(std::size_t n) { - boost::uniform_int distrib(0, n-1); - boost::variate_generator > - x(g, distrib); - return x(); - } - Generator& g; +template < typename Generator > struct random_functor +{ + random_functor(Generator& g) : g(g) {} + std::size_t operator()(std::size_t n) + { + boost::uniform_int< std::size_t > distrib(0, n - 1); + boost::variate_generator< Generator&, + boost::uniform_int< std::size_t > > + x(g, distrib); + return x(); + } + Generator& g; }; #endif -template -void randomly_permute_graph(Graph1& g1, const Graph2& g2) { - BOOST_REQUIRE(num_vertices(g1) <= num_vertices(g2)); - BOOST_REQUIRE(num_edges(g1) == 0); - - typedef typename graph_traits::vertex_descriptor vertex1; - typedef typename graph_traits::vertex_descriptor vertex2; - typedef typename graph_traits::vertex_iterator vertex_iterator; - typedef typename graph_traits::edge_iterator edge_iterator; - - random_generator_type gen; +template < typename Graph1, typename Graph2 > +void randomly_permute_graph(Graph1& g1, const Graph2& g2) +{ + BOOST_TEST(num_vertices(g1) <= num_vertices(g2)); + BOOST_TEST(num_edges(g1) == 0); + + typedef typename graph_traits< Graph1 >::vertex_descriptor vertex1; + typedef typename graph_traits< Graph2 >::vertex_descriptor vertex2; + typedef typename graph_traits< Graph1 >::vertex_iterator vertex_iterator; + typedef typename graph_traits< Graph2 >::edge_iterator edge_iterator; + + random_generator_type gen; #ifndef BOOST_NO_CXX98_RANDOM_SHUFFLE - random_functor rand_fun(gen); + random_functor< random_generator_type > rand_fun(gen); #endif - - // Decide new order - std::vector orig_vertices; - std::copy(vertices(g2).first, vertices(g2).second, std::back_inserter(orig_vertices)); + + // Decide new order + std::vector< vertex2 > orig_vertices; + std::copy(vertices(g2).first, vertices(g2).second, + std::back_inserter(orig_vertices)); #ifndef BOOST_NO_CXX98_RANDOM_SHUFFLE - std::random_shuffle(orig_vertices.begin(), orig_vertices.end(), rand_fun); + std::random_shuffle(orig_vertices.begin(), orig_vertices.end(), rand_fun); #else - std::shuffle(orig_vertices.begin(), orig_vertices.end(), gen); + std::shuffle(orig_vertices.begin(), orig_vertices.end(), gen); #endif - std::map vertex_map; - - std::size_t i = 0; - for (vertex_iterator vi = vertices(g1).first; - vi != vertices(g1).second; ++i, ++vi) { - vertex_map[orig_vertices[i]] = *vi; - put(vertex_name_t(), g1, *vi, get(vertex_name_t(), g2, orig_vertices[i])); - } - - for (edge_iterator ei = edges(g2).first; ei != edges(g2).second; ++ei) { - typename std::map::iterator si = vertex_map.find(source(*ei, g2)), - ti = vertex_map.find(target(*ei, g2)); - if ((si != vertex_map.end()) && (ti != vertex_map.end())) - add_edge(si->second, ti->second, get(edge_name_t(), g2, *ei), g1); - } + std::map< vertex2, vertex1 > vertex_map; + + std::size_t i = 0; + for (vertex_iterator vi = vertices(g1).first; vi != vertices(g1).second; + ++i, ++vi) + { + vertex_map[orig_vertices[i]] = *vi; + put(vertex_name_t(), g1, *vi, + get(vertex_name_t(), g2, orig_vertices[i])); + } + + for (edge_iterator ei = edges(g2).first; ei != edges(g2).second; ++ei) + { + typename std::map< vertex2, vertex1 >::iterator si + = vertex_map.find(source(*ei, g2)), + ti = vertex_map.find(target(*ei, g2)); + if ((si != vertex_map.end()) && (ti != vertex_map.end())) + add_edge(si->second, ti->second, get(edge_name_t(), g2, *ei), g1); + } } +template < typename Graph > +void generate_random_digraph(Graph& g, double edge_probability, + int max_parallel_edges, double parallel_edge_probability, int max_edge_name, + int max_vertex_name) +{ -template -void generate_random_digraph(Graph& g, double edge_probability, - int max_parallel_edges, double parallel_edge_probability, - int max_edge_name, int max_vertex_name) { - - BOOST_REQUIRE((0 <= edge_probability) && (edge_probability <= 1)); - BOOST_REQUIRE((0 <= parallel_edge_probability) && (parallel_edge_probability <= 1)); - BOOST_REQUIRE(0 <= max_parallel_edges); - BOOST_REQUIRE(0 <= max_edge_name); - BOOST_REQUIRE(0 <= max_vertex_name); - - typedef typename graph_traits::vertex_iterator vertex_iterator; - random_generator_type random_gen; - boost::uniform_real dist_real(0.0, 1.0); - boost::variate_generator > - random_real_dist(random_gen, dist_real); - - for (vertex_iterator u = vertices(g).first; u != vertices(g).second; ++u) { - for (vertex_iterator v = vertices(g).first; v != vertices(g).second; ++v) { - if (random_real_dist() <= edge_probability) { - add_edge(*u, *v, g); - for (int i = 0; i < max_parallel_edges; ++i) { - if (random_real_dist() <= parallel_edge_probability) - add_edge(*u, *v, g); + BOOST_TEST((0 <= edge_probability) && (edge_probability <= 1)); + BOOST_TEST( + (0 <= parallel_edge_probability) && (parallel_edge_probability <= 1)); + BOOST_TEST(0 <= max_parallel_edges); + BOOST_TEST(0 <= max_edge_name); + BOOST_TEST(0 <= max_vertex_name); + + typedef typename graph_traits< Graph >::vertex_iterator vertex_iterator; + random_generator_type random_gen; + boost::uniform_real< double > dist_real(0.0, 1.0); + boost::variate_generator< random_generator_type&, + boost::uniform_real< double > > + random_real_dist(random_gen, dist_real); + + for (vertex_iterator u = vertices(g).first; u != vertices(g).second; ++u) + { + for (vertex_iterator v = vertices(g).first; v != vertices(g).second; + ++v) + { + if (random_real_dist() <= edge_probability) + { + add_edge(*u, *v, g); + for (int i = 0; i < max_parallel_edges; ++i) + { + if (random_real_dist() <= parallel_edge_probability) + add_edge(*u, *v, g); + } + } } - } } - } - - { - boost::uniform_int dist_int(0, max_edge_name); - boost::variate_generator > - random_int_dist(random_gen, dist_int); - randomize_property(g, random_int_dist); - } - - { - boost::uniform_int dist_int(0, max_vertex_name); - boost::variate_generator > - random_int_dist(random_gen, dist_int); - - randomize_property(g, random_int_dist); - } + { + boost::uniform_int< int > dist_int(0, max_edge_name); + boost::variate_generator< random_generator_type&, + boost::uniform_int< int > > + random_int_dist(random_gen, dist_int); + randomize_property< vertex_name_t >(g, random_int_dist); + } + + { + boost::uniform_int< int > dist_int(0, max_vertex_name); + boost::variate_generator< random_generator_type&, + boost::uniform_int< int > > + random_int_dist(random_gen, dist_int); + + randomize_property< edge_name_t >(g, random_int_dist); + } } +template < typename Graph1, typename Graph2, typename EdgeEquivalencePredicate, + typename VertexEquivalencePredicate > +struct test_callback +{ -template -struct test_callback { - - test_callback(const Graph1& graph1, const Graph2& graph2, - EdgeEquivalencePredicate edge_comp, - VertexEquivalencePredicate vertex_comp, bool output) - : graph1_(graph1), graph2_(graph2), edge_comp_(edge_comp), vertex_comp_(vertex_comp), - output_(output) {} - - template - bool operator()(CorrespondenceMap1To2 f, CorrespondenceMap2To1) { - - bool verified; - BOOST_CHECK(verified = verify_vf2_subgraph_iso(graph1_, graph2_, f, edge_comp_, vertex_comp_)); - - // Output (sub)graph isomorphism map - if (!verified || output_) { - std::cout << "Verfied: " << std::boolalpha << verified << std::endl; - std::cout << "Num vertices: " << num_vertices(graph1_) << ' ' << num_vertices(graph2_) << std::endl; - BGL_FORALL_VERTICES_T(v, graph1_, Graph1) - std::cout << '(' << get(vertex_index_t(), graph1_, v) << ", " - << get(vertex_index_t(), graph2_, get(f, v)) << ") "; - - std::cout << std::endl; + test_callback(const Graph1& graph1, const Graph2& graph2, + EdgeEquivalencePredicate edge_comp, + VertexEquivalencePredicate vertex_comp, bool output) + : graph1_(graph1) + , graph2_(graph2) + , edge_comp_(edge_comp) + , vertex_comp_(vertex_comp) + , output_(output) + { } - - return true; - } - + + template < typename CorrespondenceMap1To2, typename CorrespondenceMap2To1 > + bool operator()(CorrespondenceMap1To2 f, CorrespondenceMap2To1) + { + + bool verified; + BOOST_TEST(verified = verify_vf2_subgraph_iso( + graph1_, graph2_, f, edge_comp_, vertex_comp_)); + + // Output (sub)graph isomorphism map + if (!verified || output_) + { + std::cout << "Verfied: " << std::boolalpha << verified << std::endl; + std::cout << "Num vertices: " << num_vertices(graph1_) << ' ' + << num_vertices(graph2_) << std::endl; + BGL_FORALL_VERTICES_T(v, graph1_, Graph1) + std::cout << '(' << get(vertex_index_t(), graph1_, v) << ", " + << get(vertex_index_t(), graph2_, get(f, v)) << ") "; + + std::cout << std::endl; + } + + return true; + } + private: - const Graph1& graph1_; - const Graph2& graph2_; - EdgeEquivalencePredicate edge_comp_; - VertexEquivalencePredicate vertex_comp_; - bool output_; + const Graph1& graph1_; + const Graph2& graph2_; + EdgeEquivalencePredicate edge_comp_; + VertexEquivalencePredicate vertex_comp_; + bool output_; }; -// we pretend this is something more complicated which calculates indices somehow -template -struct IndirectIndexMap { - typedef std::size_t value_type; - typedef value_type reference; - typedef typename boost::graph_traits::vertex_descriptor key_type; - typedef boost::readable_property_map_tag category; - explicit IndirectIndexMap(const G &g) : g(g) {} +// we pretend this is something more complicated which calculates indices +// somehow +template < typename G > struct IndirectIndexMap +{ + typedef std::size_t value_type; + typedef value_type reference; + typedef typename boost::graph_traits< G >::vertex_descriptor key_type; + typedef boost::readable_property_map_tag category; + explicit IndirectIndexMap(const G& g) : g(g) {} + public: - const G &g; + const G& g; }; -template -std::size_t get(const IndirectIndexMap &map, typename boost::graph_traits::vertex_descriptor v) { - // we pretend this is something more complicated which calculates indices somehow - return get(vertex_index_t(), map.g, v); +template < typename G > +std::size_t get(const IndirectIndexMap< G >& map, + typename boost::graph_traits< G >::vertex_descriptor v) +{ + // we pretend this is something more complicated which calculates indices + // somehow + return get(vertex_index_t(), map.g, v); } -void test_vf2_sub_graph_iso(int n1, int n2, double edge_probability, - int max_parallel_edges, double parallel_edge_probability, - int max_edge_name, int max_vertex_name, bool output) { - - typedef property edge_property; - typedef property > vertex_property; - - typedef adjacency_list graph1; - typedef adjacency_list graph2; - - graph1 g1(n1); - graph2 g2(n2); - generate_random_digraph(g2, edge_probability, max_parallel_edges, parallel_edge_probability, - max_edge_name, max_vertex_name); - randomly_permute_graph(g1, g2); - - int v_idx = 0; - for (graph_traits::vertex_iterator vi = vertices(g1).first; - vi != vertices(g1).second; ++vi) { - put(vertex_index_t(), g1, *vi, v_idx++); - } - - - // Create vertex and edge predicates - typedef property_map::type vertex_name_map1; - typedef property_map::type vertex_name_map2; - - typedef property_map_equivalent vertex_predicate; - vertex_predicate vertex_comp = - make_property_map_equivalent(get(vertex_name, g1), get(vertex_name, g2)); - - typedef property_map::type edge_name_map1; - typedef property_map::type edge_name_map2; - - typedef property_map_equivalent edge_predicate; - edge_predicate edge_comp = - make_property_map_equivalent(get(edge_name, g1), get(edge_name, g2)); - - - std::clock_t start = std::clock(); - - // Create callback - test_callback - callback(g1, g2, edge_comp, vertex_comp, output); - - std::cout << std::endl; - BOOST_CHECK(vf2_subgraph_iso(g1, g2, callback, vertex_order_by_mult(g1), - edges_equivalent(edge_comp).vertices_equivalent(vertex_comp))); - BOOST_CHECK(vf2_subgraph_iso(g1, g2, callback, - IndirectIndexMap(g1), - IndirectIndexMap(g2), - vertex_order_by_mult(g1), - edge_comp, vertex_comp)); - - std::clock_t end1 = std::clock(); - std::cout << "vf2_subgraph_iso: elapsed time (clock cycles): " << (end1 - start) << std::endl; - - if (num_vertices(g1) == num_vertices(g2)) { +void test_vf2_sub_graph_iso(int n1, int n2, double edge_probability, + int max_parallel_edges, double parallel_edge_probability, int max_edge_name, + int max_vertex_name, bool output) +{ + + typedef property< edge_name_t, int > edge_property; + typedef property< vertex_name_t, int, property< vertex_index_t, int > > + vertex_property; + + typedef adjacency_list< listS, listS, bidirectionalS, vertex_property, + edge_property > + graph1; + typedef adjacency_list< vecS, vecS, bidirectionalS, vertex_property, + edge_property > + graph2; + + graph1 g1(n1); + graph2 g2(n2); + generate_random_digraph(g2, edge_probability, max_parallel_edges, + parallel_edge_probability, max_edge_name, max_vertex_name); + randomly_permute_graph(g1, g2); + + int v_idx = 0; + for (graph_traits< graph1 >::vertex_iterator vi = vertices(g1).first; + vi != vertices(g1).second; ++vi) + { + put(vertex_index_t(), g1, *vi, v_idx++); + } + + // Create vertex and edge predicates + typedef property_map< graph1, vertex_name_t >::type vertex_name_map1; + typedef property_map< graph2, vertex_name_t >::type vertex_name_map2; + + typedef property_map_equivalent< vertex_name_map1, vertex_name_map2 > + vertex_predicate; + vertex_predicate vertex_comp = make_property_map_equivalent( + get(vertex_name, g1), get(vertex_name, g2)); + + typedef property_map< graph1, edge_name_t >::type edge_name_map1; + typedef property_map< graph2, edge_name_t >::type edge_name_map2; + + typedef property_map_equivalent< edge_name_map1, edge_name_map2 > + edge_predicate; + edge_predicate edge_comp + = make_property_map_equivalent(get(edge_name, g1), get(edge_name, g2)); + + std::clock_t start = std::clock(); + + // Create callback + test_callback< graph1, graph2, edge_predicate, vertex_predicate > callback( + g1, g2, edge_comp, vertex_comp, output); + std::cout << std::endl; - BOOST_CHECK(vf2_graph_iso(g1, g2, callback, vertex_order_by_mult(g1), - edges_equivalent(edge_comp).vertices_equivalent(vertex_comp))); - - std::clock_t end2 = std::clock(); - std::cout << "vf2_graph_iso: elapsed time (clock cycles): " << (end2 - end1) << std::endl; - } - - if (output) { - std::fstream file_graph1("graph1.dot", std::fstream::out); - write_graphviz(file_graph1, g1, - make_label_writer(get(boost::vertex_name, g1)), - make_label_writer(get(boost::edge_name, g1))); - - std::fstream file_graph2("graph2.dot", std::fstream::out); - write_graphviz(file_graph2, g2, - make_label_writer(get(boost::vertex_name, g2)), - make_label_writer(get(boost::edge_name, g2))); - } + BOOST_TEST(vf2_subgraph_iso(g1, g2, callback, vertex_order_by_mult(g1), + edges_equivalent(edge_comp).vertices_equivalent(vertex_comp))); + BOOST_TEST(vf2_subgraph_iso(g1, g2, callback, + IndirectIndexMap< graph1 >(g1), IndirectIndexMap< graph2 >(g2), + vertex_order_by_mult(g1), edge_comp, vertex_comp)); + + std::clock_t end1 = std::clock(); + std::cout << "vf2_subgraph_iso: elapsed time (clock cycles): " + << (end1 - start) << std::endl; + + if (num_vertices(g1) == num_vertices(g2)) + { + std::cout << std::endl; + BOOST_TEST(vf2_graph_iso(g1, g2, callback, vertex_order_by_mult(g1), + edges_equivalent(edge_comp).vertices_equivalent(vertex_comp))); + + std::clock_t end2 = std::clock(); + std::cout << "vf2_graph_iso: elapsed time (clock cycles): " + << (end2 - end1) << std::endl; + } + + if (output) + { + std::fstream file_graph1("graph1.dot", std::fstream::out); + write_graphviz(file_graph1, g1, + make_label_writer(get(boost::vertex_name, g1)), + make_label_writer(get(boost::edge_name, g1))); + + std::fstream file_graph2("graph2.dot", std::fstream::out); + write_graphviz(file_graph2, g2, + make_label_writer(get(boost::vertex_name, g2)), + make_label_writer(get(boost::edge_name, g2))); + } } -int test_main(int argc, char* argv[]) { - - int num_vertices_g1 = 10; - int num_vertices_g2 = 20; - double edge_probability = 0.4; - int max_parallel_edges = 2; - double parallel_edge_probability = 0.4; - int max_edge_name = 5; - int max_vertex_name = 5; - bool output = false; - - if (argc > 1) { - num_vertices_g1 = boost::lexical_cast(argv[1]); - } - - if (argc > 2) { - num_vertices_g2 = boost::lexical_cast(argv[2]); - } - - if (argc > 3) { - edge_probability = boost::lexical_cast(argv[3]); - } - - if (argc > 4) { - max_parallel_edges = boost::lexical_cast(argv[4]); - } - - if (argc > 5) { - parallel_edge_probability = boost::lexical_cast(argv[5]); - } - - if (argc > 6) { - max_edge_name = boost::lexical_cast(argv[6]); - } - - if (argc > 7) { - max_vertex_name = boost::lexical_cast(argv[7]); - } - - if (argc > 8) { - output = boost::lexical_cast(argv[8]); - } - - test_vf2_sub_graph_iso(num_vertices_g1, num_vertices_g2, edge_probability, - max_parallel_edges, parallel_edge_probability, - max_edge_name, max_vertex_name, output); - - return 0; +int main(int argc, char* argv[]) +{ + + int num_vertices_g1 = 10; + int num_vertices_g2 = 20; + double edge_probability = 0.4; + int max_parallel_edges = 2; + double parallel_edge_probability = 0.4; + int max_edge_name = 5; + int max_vertex_name = 5; + bool output = false; + + if (argc > 1) + { + num_vertices_g1 = boost::lexical_cast< int >(argv[1]); + } + + if (argc > 2) + { + num_vertices_g2 = boost::lexical_cast< int >(argv[2]); + } + + if (argc > 3) + { + edge_probability = boost::lexical_cast< double >(argv[3]); + } + + if (argc > 4) + { + max_parallel_edges = boost::lexical_cast< int >(argv[4]); + } + + if (argc > 5) + { + parallel_edge_probability = boost::lexical_cast< double >(argv[5]); + } + + if (argc > 6) + { + max_edge_name = boost::lexical_cast< int >(argv[6]); + } + + if (argc > 7) + { + max_vertex_name = boost::lexical_cast< int >(argv[7]); + } + + if (argc > 8) + { + output = boost::lexical_cast< bool >(argv[8]); + } + + test_vf2_sub_graph_iso(num_vertices_g1, num_vertices_g2, edge_probability, + max_parallel_edges, parallel_edge_probability, max_edge_name, + max_vertex_name, output); + + return boost::report_errors(); } diff --git a/test/vf2_sub_graph_iso_test_2.cpp b/test/vf2_sub_graph_iso_test_2.cpp index c5c7664ae..437150a85 100644 --- a/test/vf2_sub_graph_iso_test_2.cpp +++ b/test/vf2_sub_graph_iso_test_2.cpp @@ -2,7 +2,8 @@ // Boost.Graph library vf2_sub_graph_iso test 2 // Test of return value and behaviour with empty graphs // -// Copyright (C) 2013 Jakob Lykke Andersen, University of Southern Denmark (jlandersen@imada.sdu.dk) +// Copyright (C) 2013 Jakob Lykke Andersen, University of Southern Denmark +// (jlandersen@imada.sdu.dk) // // Distributed under the Boost Software License, Version 1.0. (See // accompanying file LICENSE_1_0.txt or copy at @@ -10,185 +11,199 @@ //======================================================================= #include -#include +#include #include #include -struct test_callback { - test_callback(bool &got_hit, bool stop) : got_hit(got_hit), stop(stop) { } +struct test_callback +{ + test_callback(bool& got_hit, bool stop) : got_hit(got_hit), stop(stop) {} - template - bool operator()(Map1To2 map1to2, Map2To1 map2to1) { - got_hit = true; - return stop; - } + template < typename Map1To2, typename Map2To1 > + bool operator()(Map1To2 map1to2, Map2To1 map2to1) + { + got_hit = true; + return stop; + } - bool &got_hit; - bool stop; + bool& got_hit; + bool stop; }; -struct false_predicate { - template - bool operator()(VertexOrEdge1 ve1, VertexOrEdge2 ve2) const { - return false; - } +struct false_predicate +{ + template < typename VertexOrEdge1, typename VertexOrEdge2 > + bool operator()(VertexOrEdge1 ve1, VertexOrEdge2 ve2) const + { + return false; + } }; -void test_empty_graph_cases() { - typedef boost::adjacency_list Graph; - Graph gEmpty, gLarge; - add_vertex(gLarge); +void test_empty_graph_cases() +{ + typedef boost::adjacency_list< boost::vecS, boost::vecS, + boost::bidirectionalS > + Graph; + Graph gEmpty, gLarge; + add_vertex(gLarge); - { // isomorphism + { // isomorphism + bool got_hit = false; + test_callback callback(got_hit, true); + bool exists = vf2_graph_iso(gEmpty, gEmpty, callback); + BOOST_TEST(exists); + BOOST_TEST(got_hit); // even empty matches are reported + } + { // subgraph isomorphism (induced) + { // empty vs. empty + bool got_hit = false; + test_callback callback(got_hit, true); + bool exists = vf2_subgraph_iso(gEmpty, gEmpty, callback); + BOOST_TEST(exists); + BOOST_TEST(got_hit); // even empty matches are reported +} +{ // empty vs. non-empty bool got_hit = false; test_callback callback(got_hit, true); - bool exists = vf2_graph_iso(gEmpty, gEmpty, callback); - BOOST_CHECK(exists); - BOOST_CHECK(got_hit); // even empty matches are reported - } - { // subgraph isomorphism (induced) - { // empty vs. empty - bool got_hit = false; - test_callback callback(got_hit, true); - bool exists = vf2_subgraph_iso(gEmpty, gEmpty, callback); - BOOST_CHECK(exists); - BOOST_CHECK(got_hit); // even empty matches are reported - } - { // empty vs. non-empty - bool got_hit = false; - test_callback callback(got_hit, true); - bool exists = vf2_subgraph_iso(gEmpty, gLarge, callback); - BOOST_CHECK(exists); - BOOST_CHECK(got_hit); // even empty matches are reported - } - } - { // subgraph monomorphism (non-induced subgraph isomorphism) + bool exists = vf2_subgraph_iso(gEmpty, gLarge, callback); + BOOST_TEST(exists); + BOOST_TEST(got_hit); // even empty matches are reported +} +} +{ // subgraph monomorphism (non-induced subgraph isomorphism) { // empty vs. empty - bool got_hit = false; - test_callback callback(got_hit, true); - bool exists = vf2_subgraph_mono(gEmpty, gEmpty, callback); - BOOST_CHECK(exists); - BOOST_CHECK(got_hit); // even empty matches are reported + bool got_hit = false; + test_callback callback(got_hit, true); + bool exists = vf2_subgraph_mono(gEmpty, gEmpty, callback); + BOOST_TEST(exists); + BOOST_TEST(got_hit); // even empty matches are reported } { // empty vs. non-empty - bool got_hit = false; - test_callback callback(got_hit, true); - bool exists = vf2_subgraph_mono(gEmpty, gLarge, callback); - BOOST_CHECK(exists); - BOOST_CHECK(got_hit); // even empty matches are reported + bool got_hit = false; + test_callback callback(got_hit, true); + bool exists = vf2_subgraph_mono(gEmpty, gLarge, callback); + BOOST_TEST(exists); + BOOST_TEST(got_hit); // even empty matches are reported } - } +} } -void test_return_value() { - typedef boost::adjacency_list Graph; - typedef boost::graph_traits::vertex_descriptor Vertex; - Graph gSmall, gLarge; - add_vertex(gSmall); - Vertex v1 = add_vertex(gLarge); - Vertex v2 = add_vertex(gLarge); - add_edge(v1, v2, gLarge); +void test_return_value() +{ + typedef boost::adjacency_list< boost::vecS, boost::vecS, + boost::bidirectionalS > + Graph; + typedef boost::graph_traits< Graph >::vertex_descriptor Vertex; + Graph gSmall, gLarge; + add_vertex(gSmall); + Vertex v1 = add_vertex(gLarge); + Vertex v2 = add_vertex(gLarge); + add_edge(v1, v2, gLarge); - { // isomorphism - { // no morphism due to sizes - bool got_hit = false; - test_callback callback(got_hit, true); - bool exists = vf2_graph_iso(gSmall, gLarge, callback); - BOOST_CHECK(!exists); - BOOST_CHECK(!got_hit); - } - { // no morphism due to vertex mismatches - bool got_hit = false; - test_callback callback(got_hit, true); - false_predicate pred; - bool exists = vf2_graph_iso(gLarge, gLarge, callback, vertex_order_by_mult(gLarge), - boost::edges_equivalent(pred).vertices_equivalent(pred)); - BOOST_CHECK(!exists); - BOOST_CHECK(!got_hit); - } - { // morphism, find all - bool got_hit = false; - test_callback callback(got_hit, false); - bool exists = vf2_graph_iso(gLarge, gLarge, callback); - BOOST_CHECK(exists); - BOOST_CHECK(got_hit); - } - { // morphism, stop after first hit - bool got_hit = false; - test_callback callback(got_hit, true); - bool exists = vf2_graph_iso(gLarge, gLarge, callback); - BOOST_CHECK(exists); - BOOST_CHECK(got_hit); - } - } - { // subgraph isomorphism (induced) + { // isomorphism + { // no morphism due to sizes + bool got_hit = false; + test_callback callback(got_hit, true); + bool exists = vf2_graph_iso(gSmall, gLarge, callback); + BOOST_TEST(!exists); + BOOST_TEST(!got_hit); +} +{ // no morphism due to vertex mismatches + bool got_hit = false; + test_callback callback(got_hit, true); + false_predicate pred; + bool exists + = vf2_graph_iso(gLarge, gLarge, callback, vertex_order_by_mult(gLarge), + boost::edges_equivalent(pred).vertices_equivalent(pred)); + BOOST_TEST(!exists); + BOOST_TEST(!got_hit); +} +{ // morphism, find all + bool got_hit = false; + test_callback callback(got_hit, false); + bool exists = vf2_graph_iso(gLarge, gLarge, callback); + BOOST_TEST(exists); + BOOST_TEST(got_hit); +} +{ // morphism, stop after first hit + bool got_hit = false; + test_callback callback(got_hit, true); + bool exists = vf2_graph_iso(gLarge, gLarge, callback); + BOOST_TEST(exists); + BOOST_TEST(got_hit); +} +} +{ // subgraph isomorphism (induced) { // no morphism due to sizes - bool got_hit = false; - test_callback callback(got_hit, true); - bool exists = vf2_subgraph_iso(gLarge, gSmall, callback); - BOOST_CHECK(!exists); - BOOST_CHECK(!got_hit); - } - { // no morphism due to vertex mismatches - bool got_hit = false; - test_callback callback(got_hit, true); - false_predicate pred; - bool exists = vf2_subgraph_iso(gLarge, gLarge, callback, vertex_order_by_mult(gLarge), - boost::edges_equivalent(pred).vertices_equivalent(pred)); - BOOST_CHECK(!exists); - BOOST_CHECK(!got_hit); - } - { // morphism, find all - bool got_hit = false; - test_callback callback(got_hit, false); - bool exists = vf2_subgraph_iso(gLarge, gLarge, callback); - BOOST_CHECK(exists); - BOOST_CHECK(got_hit); - } - { // morphism, stop after first hit - bool got_hit = false; - test_callback callback(got_hit, true); - bool exists = vf2_subgraph_iso(gLarge, gLarge, callback); - BOOST_CHECK(exists); - BOOST_CHECK(got_hit); - } - } - { // subgraph monomorphism (non-induced subgraph isomorphism) + bool got_hit = false; +test_callback callback(got_hit, true); +bool exists = vf2_subgraph_iso(gLarge, gSmall, callback); +BOOST_TEST(!exists); +BOOST_TEST(!got_hit); +} +{ // no morphism due to vertex mismatches + bool got_hit = false; + test_callback callback(got_hit, true); + false_predicate pred; + bool exists = vf2_subgraph_iso(gLarge, gLarge, callback, + vertex_order_by_mult(gLarge), + boost::edges_equivalent(pred).vertices_equivalent(pred)); + BOOST_TEST(!exists); + BOOST_TEST(!got_hit); +} +{ // morphism, find all + bool got_hit = false; + test_callback callback(got_hit, false); + bool exists = vf2_subgraph_iso(gLarge, gLarge, callback); + BOOST_TEST(exists); + BOOST_TEST(got_hit); +} +{ // morphism, stop after first hit + bool got_hit = false; + test_callback callback(got_hit, true); + bool exists = vf2_subgraph_iso(gLarge, gLarge, callback); + BOOST_TEST(exists); + BOOST_TEST(got_hit); +} +} +{ // subgraph monomorphism (non-induced subgraph isomorphism) { // no morphism due to sizes - bool got_hit = false; - test_callback callback(got_hit, true); - bool exists = vf2_subgraph_mono(gLarge, gSmall, callback); - BOOST_CHECK(!exists); - BOOST_CHECK(!got_hit); + bool got_hit = false; + test_callback callback(got_hit, true); + bool exists = vf2_subgraph_mono(gLarge, gSmall, callback); + BOOST_TEST(!exists); + BOOST_TEST(!got_hit); } { // no morphism due to vertex mismatches - bool got_hit = false; - test_callback callback(got_hit, true); - false_predicate pred; - bool exists = vf2_subgraph_mono(gLarge, gLarge, callback, vertex_order_by_mult(gLarge), - boost::edges_equivalent(pred).vertices_equivalent(pred)); - BOOST_CHECK(!exists); - BOOST_CHECK(!got_hit); + bool got_hit = false; + test_callback callback(got_hit, true); + false_predicate pred; + bool exists = vf2_subgraph_mono(gLarge, gLarge, callback, + vertex_order_by_mult(gLarge), + boost::edges_equivalent(pred).vertices_equivalent(pred)); + BOOST_TEST(!exists); + BOOST_TEST(!got_hit); } { // morphism, find all - bool got_hit = false; - test_callback callback(got_hit, false); - bool exists = vf2_subgraph_mono(gLarge, gLarge, callback); - BOOST_CHECK(exists); - BOOST_CHECK(got_hit); + bool got_hit = false; + test_callback callback(got_hit, false); + bool exists = vf2_subgraph_mono(gLarge, gLarge, callback); + BOOST_TEST(exists); + BOOST_TEST(got_hit); } { // morphism, stop after first hit - bool got_hit = false; - test_callback callback(got_hit, true); - bool exists = vf2_subgraph_mono(gLarge, gLarge, callback); - BOOST_CHECK(exists); - BOOST_CHECK(got_hit); + bool got_hit = false; + test_callback callback(got_hit, true); + bool exists = vf2_subgraph_mono(gLarge, gLarge, callback); + BOOST_TEST(exists); + BOOST_TEST(got_hit); } - } +} } -int test_main(int argc, char* argv[]) { - test_empty_graph_cases(); - test_return_value(); - return 0; +int main(int argc, char* argv[]) +{ + test_empty_graph_cases(); + test_return_value(); + return boost::report_errors(); } diff --git a/test/weighted_matching_test.cpp b/test/weighted_matching_test.cpp index b5be858bb..2baa0adcf 100644 --- a/test/weighted_matching_test.cpp +++ b/test/weighted_matching_test.cpp @@ -15,91 +15,112 @@ #include #include #include -#include +#include using namespace boost; -typedef property > EdgeProperty; +typedef property< edge_weight_t, float, property< edge_index_t, int > > + EdgeProperty; -typedef adjacency_list, EdgeProperty> undirected_graph; -typedef adjacency_list, EdgeProperty> undirected_list_graph; -typedef adjacency_matrix, EdgeProperty> undirected_adjacency_matrix_graph; +typedef adjacency_list< vecS, vecS, undirectedS, + property< vertex_index_t, int >, EdgeProperty > + undirected_graph; +typedef adjacency_list< listS, listS, undirectedS, + property< vertex_index_t, int >, EdgeProperty > + undirected_list_graph; +typedef adjacency_matrix< undirectedS, property< vertex_index_t, int >, + EdgeProperty > + undirected_adjacency_matrix_graph; -template -struct vertex_index_installer +template < typename Graph > struct vertex_index_installer { static void install(Graph&) {} }; -template <> -struct vertex_index_installer +template <> struct vertex_index_installer< undirected_list_graph > { static void install(undirected_list_graph& g) { - typedef graph_traits::vertex_iterator vertex_iterator_t; - typedef graph_traits::vertices_size_type v_size_t; - + typedef graph_traits< undirected_list_graph >::vertex_iterator + vertex_iterator_t; + typedef graph_traits< undirected_list_graph >::vertices_size_type + v_size_t; + vertex_iterator_t vi, vi_end; v_size_t i = 0; - for (boost::tie(vi,vi_end) = vertices(g); vi != vi_end; ++vi, ++i) + for (boost::tie(vi, vi_end) = vertices(g); vi != vi_end; ++vi, ++i) put(vertex_index, g, *vi, i); } }; -template -void print_graph(const Graph& g) +template < typename Graph > void print_graph(const Graph& g) { - typedef typename graph_traits::edge_iterator edge_iterator_t; + typedef typename graph_traits< Graph >::edge_iterator edge_iterator_t; edge_iterator_t ei, ei_end; std::cout << std::endl << "The graph is: " << std::endl; - for (boost::tie(ei,ei_end) = edges(g); ei != ei_end; ++ei) - std::cout << "add_edge(" << source(*ei, g) << ", " << target(*ei, g) << ", EdgeProperty(" << get(edge_weight, g, *ei) << "), );" << std::endl; + for (boost::tie(ei, ei_end) = edges(g); ei != ei_end; ++ei) + std::cout << "add_edge(" << source(*ei, g) << ", " << target(*ei, g) + << ", EdgeProperty(" << get(edge_weight, g, *ei) << "), );" + << std::endl; } -template -void weighted_matching_test(const Graph& g, - typename property_traits::type>::value_type answer) +template < typename Graph > +void weighted_matching_test(const Graph& g, + typename property_traits< typename property_map< Graph, + edge_weight_t >::type >::value_type answer) { - typedef typename property_map::type vertex_index_map_t; - typedef vector_property_map< typename graph_traits::vertex_descriptor, vertex_index_map_t > mate_t; + typedef + typename property_map< Graph, vertex_index_t >::type vertex_index_map_t; + typedef vector_property_map< + typename graph_traits< Graph >::vertex_descriptor, vertex_index_map_t > + mate_t; mate_t mate(num_vertices(g)); maximum_weighted_matching(g, mate); bool same_result = (matching_weight_sum(g, mate) == answer); - BOOST_CHECK(same_result); + BOOST_TEST(same_result); if (!same_result) { mate_t max_mate(num_vertices(g)); brute_force_maximum_weighted_matching(g, max_mate); - std::cout << std::endl << "Found a weighted matching of weight sum " << matching_weight_sum(g, mate) << std::endl - << "While brute-force search found a weighted matching of weight sum " << matching_weight_sum(g, max_mate) << std::endl; - - typedef typename graph_traits::vertex_iterator vertex_iterator_t; + std::cout << std::endl + << "Found a weighted matching of weight sum " + << matching_weight_sum(g, mate) << std::endl + << "While brute-force search found a weighted matching of " + "weight sum " + << matching_weight_sum(g, max_mate) << std::endl; + + typedef + typename graph_traits< Graph >::vertex_iterator vertex_iterator_t; vertex_iterator_t vi, vi_end; - + print_graph(g); - + std::cout << std::endl << "The algorithmic matching is:" << std::endl; - for (boost::tie(vi,vi_end) = vertices(g); vi != vi_end; ++vi) - if (mate[*vi] != graph_traits::null_vertex() && *vi < mate[*vi]) - std::cout << "{" << *vi << ", " << mate[*vi] << "}" << std::endl; - + for (boost::tie(vi, vi_end) = vertices(g); vi != vi_end; ++vi) + if (mate[*vi] != graph_traits< Graph >::null_vertex() + && *vi < mate[*vi]) + std::cout << "{" << *vi << ", " << mate[*vi] << "}" + << std::endl; + std::cout << std::endl << "The brute-force matching is:" << std::endl; - for (boost::tie(vi,vi_end) = vertices(g); vi != vi_end; ++vi) - if (max_mate[*vi] != graph_traits::null_vertex() && *vi < max_mate[*vi]) - std::cout << "{" << *vi << ", " << max_mate[*vi] << "}" << std::endl; - + for (boost::tie(vi, vi_end) = vertices(g); vi != vi_end; ++vi) + if (max_mate[*vi] != graph_traits< Graph >::null_vertex() + && *vi < max_mate[*vi]) + std::cout << "{" << *vi << ", " << max_mate[*vi] << "}" + << std::endl; + std::cout << std::endl; } } -template -Graph make_graph(typename graph_traits::vertices_size_type num_v, - typename graph_traits::edges_size_type num_e, - std::deque input_edges) +template < typename Graph > +Graph make_graph(typename graph_traits< Graph >::vertices_size_type num_v, + typename graph_traits< Graph >::edges_size_type num_e, + std::deque< std::size_t > input_edges) { Graph g(num_v); - vertex_index_installer::install(g); + vertex_index_installer< Graph >::install(g); for (std::size_t i = 0; i < num_e; ++i) { std::size_t src_v, tgt_v, edge_weight; @@ -109,12 +130,13 @@ Graph make_graph(typename graph_traits::vertices_size_type num_v, input_edges.pop_front(); edge_weight = input_edges.front(); input_edges.pop_front(); - add_edge(vertex(src_v, g), vertex(tgt_v, g), EdgeProperty(edge_weight), g); + add_edge( + vertex(src_v, g), vertex(tgt_v, g), EdgeProperty(edge_weight), g); } return g; } -int test_main(int, char*[]) +int main(int, char*[]) { std::ifstream in_file("weighted_matching.dat"); std::string line; @@ -124,16 +146,19 @@ int test_main(int, char*[]) std::size_t answer, num_v, num_e; in_graph >> answer >> num_v >> num_e; - std::deque input_edges; + std::deque< std::size_t > input_edges; std::size_t i; while (in_graph >> i) input_edges.push_back(i); - - weighted_matching_test(make_graph(num_v, num_e, input_edges), answer); - weighted_matching_test(make_graph(num_v, num_e, input_edges), answer); - weighted_matching_test(make_graph(num_v, num_e, input_edges), answer); + + weighted_matching_test( + make_graph< undirected_graph >(num_v, num_e, input_edges), answer); + weighted_matching_test( + make_graph< undirected_list_graph >(num_v, num_e, input_edges), + answer); + weighted_matching_test(make_graph< undirected_adjacency_matrix_graph >( + num_v, num_e, input_edges), + answer); } - return 0; + return boost::report_errors(); } - - diff --git a/utility/ci/codecov/coverage.sh b/utility/ci/codecov/coverage.sh new file mode 100755 index 000000000..7dff89517 --- /dev/null +++ b/utility/ci/codecov/coverage.sh @@ -0,0 +1,49 @@ +#! /bin/bash +# +# Copyright 2017 - 2019 James E. King III +# Distributed under the Boost Software License, Version 1.0. +# (See accompanying file LICENSE_1_0.txt or copy at +# http://www.boost.org/LICENSE_1_0.txt) +# +# Bash script to run in travis to perform codecov.io integration +# + +# assumes cwd is the top level directory of the boost project +# assumes an environment variable $SELF is the boost project name + +set -exv + +. utility/ci/enforce_b2_env.sh + +if [ "${B2_TOOLSET%%-*}" == "gcc" ]; then + ver="${B2_TOOLSET#*-}" +fi + +B2_VARIANT=debug +utility/ci/travis/install.sh cxxflags=-fprofile-arcs cxxflags=-ftest-coverage linkflags=-fprofile-arcs linkflags=-ftest-coverage + +# switch back to the original source code directory +cd $TRAVIS_BUILD_DIR + +# get the version of lcov +lcov --version + +# coverage files are in ../../b2 from this location +lcov --rc lcov_branch_coverage=1 --base-directory "$BOOST_ROOT/libs/$SELF" --directory "$BOOST_ROOT" --capture --output-file all.info + +# all.info contains all the coverage info for all projects - limit to ours +# first we extract the interesting headers for our project then we use that list to extract the right things +for f in `for f in include/boost/*; do echo $f; done | cut -f2- -d/`; do echo "*/$f*"; done > /tmp/interesting +echo headers that matter: +cat /tmp/interesting +xargs -L 999999 -a /tmp/interesting lcov --rc lcov_branch_coverage=1 --extract all.info {} "*/libs/$SELF/src/*" --output-file coverage.info + +# dump a summary on the console - helps us identify problems in pathing +lcov --rc lcov_branch_coverage=1 --list coverage.info + +# +# upload to codecov.io +# +curl -s https://codecov.io/bash > .codecov +chmod +x .codecov +./.codecov -f coverage.info -X gcov -x gcov diff --git a/utility/ci/coverty/coverage.sh b/utility/ci/coverty/coverage.sh new file mode 100755 index 000000000..ec4c57403 --- /dev/null +++ b/utility/ci/coverty/coverage.sh @@ -0,0 +1,45 @@ +#! /bin/bash +# +# Copyright 2017 - 2019 James E. King III +# Distributed under the Boost Software License, Version 1.0. +# (See accompanying file LICENSE_1_0.txt or copy at +# http://www.boost.org/LICENSE_1_0.txt) +# +# Bash script to run in travis to perform a Coverity Scan build +# To skip the coverity integration download (which is huge) if +# you already have it from a previous run, add --skipdownload +# + +# +# Environment Variables +# +# COVERITY_SCAN_NOTIFICATION_EMAIL - email address to notify +# COVERITY_SCAN_TOKEN - the Coverity Scan token (should be secure) +# SELF - the boost libs directory name + +set -exv + +sudo wget -nv https://entrust.com/root-certificates/entrust_l1k.cer -O /tmp/scanca.cer + +pushd /tmp +if [[ "$1" != "--skipdownload" ]]; then + rm -rf coverity_tool.tgz cov-analysis* + curl --cacert /tmp/scanca.cer -L -d "token=$COVERITY_SCAN_TOKEN&project=$TRAVIS_REPO_SLUG" -X POST https://scan.coverity.com/download/linux64 -o coverity_tool.tgz + tar xzf coverity_tool.tgz +fi +COVBIN=$(echo $(pwd)/cov-analysis*/bin) +export PATH=$COVBIN:$PATH +popd + +utility/ci/travis/install.sh clean +rm -rf cov-int/ +cov-build --dir cov-int utility/ci/travis/install.sh +tail -50 cov-int/build-log.txt +tar cJf cov-int.tar.xz cov-int/ +curl --cacert /tmp/scanca.cer \ + --form token="$COVERITY_SCAN_TOKEN" \ + --form email="$COVERITY_SCAN_NOTIFICATION_EMAIL" \ + --form file=@cov-int.tar.xz \ + --form version="$BOOST_BRANCH" \ + --form description="$TRAVIS_REPO_SLUG" \ + https://scan.coverity.com/builds?project="$TRAVIS_REPO_SLUG" diff --git a/utility/ci/enforce_b2_env.sh b/utility/ci/enforce_b2_env.sh new file mode 100755 index 000000000..e72ac644f --- /dev/null +++ b/utility/ci/enforce_b2_env.sh @@ -0,0 +1,46 @@ +#! /bin/bash +# +# Copyright 2017 - 2019 James E. King III +# Distributed under the Boost Software License, Version 1.0. +# (See accompanying file LICENSE_1_0.txt or copy at +# http://www.boost.org/LICENSE_1_0.txt) +# +# Enforce B2 build variables understood by boost-ci scripts. +# + +set -ev + +function enforce_b2 +{ + local old_varname=$1 + local new_varname=B2_${old_varname} + + if [ -z "${!new_varname}" ]; then + if [ ! -z "${!old_varname}" ]; then + echo + echo "WARNING: Your .travis.yml file needs to be updated:" + echo " use ${new_varname} instead of ${old_varname}" + echo + export ${new_varname}="${!old_varname}" + unset ${old_varname} + fi + fi +} + +enforce_b2 "CXXFLAGS" +enforce_b2 "CXXSTD" +enforce_b2 "DEFINES" +enforce_b2 "LINKFLAGS" +enforce_b2 "TESTFLAGS" +enforce_b2 "TOOLSET" + +# default language level: C++03 +if [ -z "$B2_CXXSTD" ]; then + export B2_CXXSTD=03 +fi + +# default parallel build jobs: number of CPUs available + 1 +if [ -z "${B2_JOBS}" ]; then + cpus=$(cat /proc/cpuinfo | grep 'processor' | wc -l) + export B2_JOBS=$((cpus + 1)) +fi diff --git a/utility/ci/travis/build.sh b/utility/ci/travis/build.sh new file mode 100755 index 000000000..1e6787689 --- /dev/null +++ b/utility/ci/travis/build.sh @@ -0,0 +1,14 @@ +#!/bin/bash + +# echo "using $TOOLSET : : $COMPILER ;" > ~/user-config.jam +# IFS=',' +# for CXXLOCAL in $CXXSTD; do (cd libs/config/test && ../../../b2 config_info_travis_install toolset=$TOOLSET cxxstd=$CXXLOCAL && ./config_info_travis && rm ./config_info_travis) done +# unset IFS + +set -exv + +. $(dirname "${BASH_SOURCE[0]}")/../enforce_b2_env.sh + +cd $BOOST_ROOT/libs/$SELF + +$BOOST_ROOT/b2 ./test/ toolset=$B2_TOOLSET $B2_CXXSTD $COPTS $B2_DEFINES $B2_INCLUDE $LOPTS $B2_TESTFLAGS $B2_ADDRESS_MODEL $B2_LINK $B2_THREADING $B2_VARIANT -j${B2_JOBS} $* diff --git a/utility/ci/travis/cppcheck.sh b/utility/ci/travis/cppcheck.sh new file mode 100755 index 000000000..b9a8e8aa9 --- /dev/null +++ b/utility/ci/travis/cppcheck.sh @@ -0,0 +1,26 @@ +#! /bin/bash +# +# Copyright 2018 - 2019 James E. King III +# Distributed under the Boost Software License, Version 1.0. +# (See accompanying file LICENSE_1_0.txt or copy at +# http://www.boost.org/LICENSE_1_0.txt) +# +# Bash script to run in travis to perform a cppcheck +# cwd should be $BOOST_ROOT before running +# + +set -exv + +. $(dirname "${BASH_SOURCE[0]}")/../enforce_b2_env.sh || exit 1 + + +STANDARDS= +while IFS=',' read -ra ADDR; do + for i in "${ADDR[@]}"; do + # process "$i" + STANDARDS="${STANDARDS} --std=c++${i}" + done +done <<< "$B2_CXXSTD" + +cppcheck -I. ${STANDARDS} --enable=all --error-exitcode=1 \ + --force --check-config . || exit 1 diff --git a/utility/ci/travis/format-check.sh b/utility/ci/travis/format-check.sh new file mode 100755 index 000000000..caa0f2eaa --- /dev/null +++ b/utility/ci/travis/format-check.sh @@ -0,0 +1,19 @@ +#!/bin/bash -ue + +set -o errexit +set -o pipefail +set -o nounset +set -ev + +echo "Using $(clang-format-8 --version)" + +find . -type f -name '*.h' -o -name '*.cpp' | xargs -I{} -P "$(nproc)" clang-format-8 -i -style=file {} + +dirty=$(git ls-files --modified) + +if [[ $dirty ]]; then +echo "The following files have been modified:" +echo "$dirty" + +exit 1 +fi \ No newline at end of file diff --git a/utility/ci/travis/install.sh b/utility/ci/travis/install.sh new file mode 100755 index 000000000..acb29877a --- /dev/null +++ b/utility/ci/travis/install.sh @@ -0,0 +1,86 @@ +#!/bin/bash +# +# + +set -exv + +if [ "$TRAVIS_OS_NAME" == "osx" ]; then + unset -f cd +fi + + +./utility/ci/enforce_b2_env.sh +# ${TRAVIS_BUILD_DIR}/utility/ci/enforce_b2_env.sh + +# function show_bootstrap_log +# { +# cat bootstrap.log +# } + +CALLED_FROM_DIR="$(pwd)" + +export SELF=`basename $TRAVIS_BUILD_DIR` +cd .. + +if [ "$TRAVIS_BRANCH" == "master" ]; then + export BOOST_BRANCH="master" +else + export BOOST_BRANCH="develop" +fi + + + + +git clone -b $BOOST_BRANCH --depth 1 https://github.com/boostorg/boost.git boost-root +cd boost-root + +git submodule update --init +git submodule update --init libs/headers +git submodule update --init tools/boost_install +git submodule update --init tools/boostdep +git submodule update --init tools/build +git submodule update --init libs/config +rm -rf libs/$SELF +cp -r $TRAVIS_BUILD_DIR libs/$SELF + +export BOOST_ROOT="$(pwd)" +export PATH="`pwd`":$PATH + +python tools/boostdep/depinst/depinst.py $SELF + + +# If clang was installed from LLVM APT it will not have a /usr/bin/clang++ +# so we need to add the correctly versioned llvm bin path to the PATH +if [ "${B2_TOOLSET%%-*}" == "clang" ]; then + ver="${B2_TOOLSET#*-}" + export PATH=/usr/lib/llvm-${ver}/bin:$PATH + ls -ls /usr/lib/llvm-${ver}/bin || true + hash -r || true + which clang || true + which clang++ || true + + # Additionally, if B2_TOOLSET is clang variant but CXX is set to g++ + # (it is on Travis CI) then boost build silently ignores B2_TOOLSET and + # uses CXX instead + if [ "${CXX}" != "clang"* ]; then + echo "CXX is set to ${CXX} in this environment which would override" + echo "the setting of B2_TOOLSET=clang, therefore we clear CXX here." + export CXX= + fi +fi + + +# trap show_bootstrap_log ERR +if [[ "${B2_TOOLSET}" == "gcc-"* ]] || [[ "${B2_TOOLSET}" == "clang-"* ]]; then + ./bootstrap.sh --with-toolset=${B2_TOOLSET%%-*} +else + ./bootstrap.sh --with-toolset=${B2_TOOLSET} +fi +# trap - ERR + +./b2 headers + +# ./b2 + +cd "$CALLED_FROM_DIR" + diff --git a/utility/ci/travis/valgrind.sh b/utility/ci/travis/valgrind.sh new file mode 100755 index 000000000..e37ced709 --- /dev/null +++ b/utility/ci/travis/valgrind.sh @@ -0,0 +1,29 @@ +#!/bin/bash +# +# Copyright 2018 - 2019 James E. King III +# Distributed under the Boost Software License, Version 1.0. +# (See accompanying file LICENSE_1_0.txt or copy at +# http://www.boost.org/LICENSE_1_0.txt) +# +# Bash script to run in travis to perform a cppcheck +# cwd should be $BOOST_ROOT before running +# + +set -exv + +# valgrind on travis (xenial) is 3.11 which is old +# using valgrind 3.14 but we have to build it + +pushd /tmp +git clone -b VALGRIND_3_14_0 git://sourceware.org/git/valgrind.git +cd valgrind + +./autogen.sh +./configure --prefix=/tmp/vg +make -j3 +make -j3 install +popd + +export PATH=/tmp/vg/bin:$PATH +export B2_INCLUDE=include=/tmp/vg/include +