Как использовать boost::connected_comComponents, когда есть вершина без ребер?

Пример в boost взят из документа

https://www.boost.org/doc/libs/1_85_0/libs/graph/example/connected_comComponents.cpp

//=======================================================================
// Copyright 1997, 1998, 1999, 2000 University of Notre Dame.
// 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)
//=======================================================================

#include <boost/config.hpp>
#include <iostream>
#include <vector>
#include <algorithm>
#include <utility>
#include <boost/graph/adjacency_list.hpp>
#include <boost/graph/connected_components.hpp>

/*

  This example demonstrates the usage of the connected_components
  algorithm on a undirected graph. The example graphs come from
  "Introduction to Algorithms", Cormen, Leiserson, and Rivest p. 87
  (though we number the vertices from zero instead of one).

  Sample output:

  Total number of components: 3
  Vertex 0 is in component 0
  Vertex 1 is in component 0
  Vertex 2 is in component 1
  Vertex 3 is in component 2
  Vertex 4 is in component 0
  Vertex 5 is in component 1

 */

using namespace std;

int main(int , char* []) 
{
  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;
}

Это работает нормально.

https://godbolt.org/z/3jYaEM9Ks

Однако есть одна загвоздка. А что насчет вершины, она не соединена ребрами с какой-либо другой вершиной. Он должен заканчиваться отдельным компонентом. Однако я не уверен, как изменить код, чтобы добиться этого?

Я попробовал добавить

 add_vertex(6, G);

но эта интуиция не работает.

Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
0
51
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Однако есть одна загвоздка. А что насчет вершины, она не соединена ребрами с какой-либо другой вершиной. Он должен заканчиваться отдельным компонентом.

В вашем примере такой вершиной является вершина №3. Это уже в своем компоненте. УСПЕХ!

Я пробовал добавить add_vertex(6, G);, но интуиция не работает.

Я понятия не имею, чего это должно добиться. Вы вызываете add_vertex с аргументом 6 для инициализации свойств вершины. Но у вас нет свойств вершин ¯\(ツ)/¯.

Если вы хотите добавить вершину, просто скажите auto descriptor = add_vertex(G);. Но, как вы видели выше, в этом нет необходимости, поскольку вершина 3 УЖЕ не соединена.

Если вы хотели убедиться, что существует 7 вершин (0,1,2,3,4,5,6), просто сделайте это так: Live On Coliru

Graph g(7);

Теперь он печатает, как вы и ожидали:

Total number of components: 4
Vertex 0 is in component 0
Vertex 1 is in component 0
Vertex 2 is in component 1
Vertex 3 is in component 2
Vertex 4 is in component 0
Vertex 5 is in component 1
Vertex 6 is in component 3

БОНУС

Если вас действительно смущают неявные индексы вершин в хранилище vecS, сравните с хранилищем listS:

Прямой эфир на Колиру

#include <boost/config.hpp>
#include <boost/graph/adjacency_list.hpp>
#include <boost/graph/connected_components.hpp>
#include <iostream>
#include <vector>

int main(int, char*[]) {
    using Graph = boost::adjacency_list<boost::vecS, boost::listS, boost::undirectedS>;
    using VDesc = Graph::vertex_descriptor;

    Graph g;
    std::array<VDesc, 7> vv;
    for (auto& v : vv)
        v = add_vertex(g);

    add_edge(vv[0], vv[1], g);
    add_edge(vv[1], vv[4], g);
    add_edge(vv[4], vv[0], g);
    add_edge(vv[2], vv[5], g);

    std::map<VDesc, int>    component;
    std::map<VDesc, size_t> index;

    auto compmap = boost::make_assoc_property_map(component);
    auto idmap   = boost::make_assoc_property_map(index);

    for (auto v : boost::make_iterator_range(vertices(g)))
        index.emplace(v, index.size());
    int num = connected_components( //
        g,                          //
        compmap,
        boost::vertex_index_map(idmap));

    std::cout << "Total number of components: " << num << std::endl;

    // Iterate vertices
    for (auto v : boost::make_iterator_range(vertices(g)))
        std::cout << "Vertex " << v << " (id " << idmap[v] << ") is in component " << compmap[v] << std::endl;

    // Iterate map
    std::cout << "Total number mappings: " << component.size() << std::endl;
    for (auto const& [v, comp] : component)
        std::cout << "Vertex " << v << " (id " << idmap[v] << ") is in component " << comp << std::endl;
    std::cout << std::endl;
}

Печать, например.

Total number of components: 4
Vertex 0x504000000050 (id 0) is in component 0
Vertex 0x504000000090 (id 1) is in component 0
Vertex 0x5040000000d0 (id 2) is in component 1
Vertex 0x504000000110 (id 3) is in component 2
Vertex 0x504000000150 (id 4) is in component 0
Vertex 0x504000000190 (id 5) is in component 1
Vertex 0x5040000001d0 (id 6) is in component 3
Total number mappings: 7
Vertex 0x504000000050 (id 0) is in component 0
Vertex 0x504000000090 (id 1) is in component 0
Vertex 0x5040000000d0 (id 2) is in component 1
Vertex 0x504000000110 (id 3) is in component 2
Vertex 0x504000000150 (id 4) is in component 0
Vertex 0x504000000190 (id 5) is in component 1
Vertex 0x5040000001d0 (id 6) is in component 3

Спасибо. Я не заметил вершину 3, как она себя вела и как работали неявные индексы вершин. Теперь это очевидно.

bradgonesurfing 18.04.2024 18:30

Ошибка в моем собственном коде заключалась в том, что я не инициализировал граф с начальным количеством вершин, и в моем случае у меня была только одна вершина, ни с чем не связанная. Инициализация графика как Graph graph(num_verticies) вместо Graph graph решила мою настоящую проблему.

bradgonesurfing 18.04.2024 18:40

Рад, что показал несколько аспектов проблемы :) С уважением.

sehe 18.04.2024 19:02

Другие вопросы по теме