Генерация графика с использованием библиотеки Boost, позволяя пользователю выбирать количество вершин

Я хотел бы создать график с использованием библиотеки boost, которая позволила бы пользователю вводить количество ребер и вершин. То, что я в основном хочу сделать, это,

  1. Я бы хотел, чтобы пользователь ввел количество вершин и пронумеровал каждую вершину.
  2. Я бы дал пользователю право выбирать вершину в качестве главной вершины, используя цифру в качестве ссылки.
  3. Я хотел бы, чтобы пользователь указал в консоли количество ребер из каждой вершины, и ребра могут быть случайными.

Можно ли это как-то реализовать с помощью BGL? Если да, то было бы неплохо начать с примера.

Большое спасибо заранее,

Ваше здоровье!!


person Spaniard89    schedule 15.09.2012    source источник
comment
Казалось бы, для этого даже не нужен BGL.   -  person Kerrek SB    schedule 15.09.2012
comment
Является ли здесь единственной целью построить случайный граф с заданными валентностями вершин?   -  person Kerrek SB    schedule 15.09.2012
comment
@KerrekSB Нет, создание графа - это только начальный шаг, на нем будут выполняться различные алгоритмы поиска, начиная с главного узла. Есть ли в Интернете пример или что-то, что соответствует моим критериям?   -  person Spaniard89    schedule 16.09.2012
comment
Алгоритм не так уж и сложен. Вам нужно просто описание высокого уровня или вам нужна помощь и с основами C++?   -  person Kerrek SB    schedule 16.09.2012
comment
@KerrekSB Я хочу сгенерировать граф с описанными требованиями, в основном это сгенерировать топологию сети. Я новичок в C++ и BGL. Мне просто нужен пример начального состояния для начала, и я хочу использовать BGL для работы с сгенерированным графом топологии. Большое спасибо за ваш ответ и помощь.   -  person Spaniard89    schedule 16.09.2012


Ответы (1)


Предполагая, что вы знаете а) базовый C++ и б) базовый BGL, вот простой алгоритм для построения случайного неориентированного графа с заданными валентностями вершин:

  1. Прочитайте количество желаемых вершин; назовите это N. У нас есть набор вершин [0, N).

  2. Для каждого i в[0, N) прочтите желаемую валентность v[i] (для хранения, например, в контейнере, таком как std::vector<int>).

  3. Теперь самое интересное: пройдитесь по каждой вершине и добавьте произвольное ребро, насколько это возможно. Вот некоторый псевдокод, похожий на C++, с пробелами, которые вы должны заполнить.

    for (i = 0; i != N; ++i)
    {
        if (i + 1 == N && v[i] > 0)
        {
            Error: The user input was impossible to satisfy
            Abort program
        }
    
        while (v[i] > 0)
        {
            pick a random j in [i + 1, N)
    
            if (v[j] > 0)
            {
                Add edge i <-> j
                --v[i];
                --v[j];
            }
        }
    }
    
    If we haven't aborted, we now have a random graph.
    

Оставьте комментарий, если вы хотите, чтобы какая-либо часть этого была расширена.


Обновление: вот пример реализации. Будут пробелы; это просто схема.

#include <iostream>
#include <sstream>
#include <string>
#include <vector>
#include <cstdio>
#include <cstdlib>

int read_int(std::string const & initmsg, std::string const & repeatmsg)
{
    std::cout << initmsg;

    for (std::string line; std::getline(std::cin, line); )
    {
        std::istringstream iss(line);
        int res;

        if (iss >> res >> std::ws && iss.get() == EOF) { return res; }

        std::cout << repeatmsg;
    }

    std::cerr << "Unexpected end of input! Aborting.\n";
    std::exit(1);
}

std::string read_string(std::string const & msg)
{
    std::string res;
    std::cout << msg;

    if (std::getline(std::cin, res)) { return res; }

    std::cerr << "Unexpected end of input! Aborting.\n";
    std::exit(1);
}

int main()
{
    int const N = read_int("Number of vertices: ",
                           "I did not understand, try again. Number of vertices: ");

    std::vector<unsigned int> valencies;
    std::vector<std::string> vertex_names;

    valencies.reserve(N);
    vertex_names.reserve(N);

    for (int i = 0; i != N; ++i)
    {
        std::string const msg1 = "Enter valency for vertex " + std::to_string(i) + ": ";
        std::string const msg2 = "Enter description for vertex " + std::to_string(i) + ": ";
        std::string const rep = "Sorry, say again: ";

        valencies.push_back(read_int(msg1, rep));
        vertex_names.push_back(read_string(msg2));
    }

    for (int i = 0; i != N; ++i)
    {
        std::cout << "Vertex " << i << " (\"" << vertex_names[i]
                  << "\") has valency " << valencies[i] << std::endl;
    }

    // Now run the above algorithm!
}
person Kerrek SB    schedule 16.09.2012
comment
Было бы очень полезно, если бы вы могли расширить приведенный выше пример, чтобы я мог его запустить. Я слишком новичок в программировании, и как только я получил код, я попытался бы разобраться в нем, и это действительно помогло бы мне. Заранее большое спасибо. - person Spaniard89; 17.09.2012
comment
Я получил этот код из примеров, представленных в библиотеке повышения: как только я введу количество вершин, как мне назначить числа или алфавит для каждой вершины? что-то подобное делает это в BGL:enum { A, B, C, D, E, N }; const int num_vertices = N; const char* name = "ABCDE"; Но в этом вершина предопределена так же, как и ребра. Как бы добиться этого случайным образом? - person Spaniard89; 17.09.2012
comment
@Kishorepandey: Подождите, я приведу пример. Метки вершин — неважная деталь. Просто считайте каждую вершину числом в [0, N). - person Kerrek SB; 17.09.2012
comment
Хорошо, приятель. Я подожду. Спасибо за помощь и ответ. - person Spaniard89; 17.09.2012
comment
@Kishorepandey: Хорошо, я добавил пример структуры, которая считывает количество вершин (N), а также валентности и имена для каждой вершины. Теперь к вам! - person Kerrek SB; 17.09.2012
comment
Большое спасибо, приятель. Но я получаю сообщение об ошибке: ошибка C2039: 'to_string': не является членом 'std'. Как я могу это решить? - person Spaniard89; 18.09.2012
comment
@Kishorepandey: to_string является новым в C++11, поэтому вам нужен современный компилятор (например, VC10 или VC11). В качестве альтернативы возьмите Boost и используйте boost::lexical_cast. В любом случае, это только для сообщения, не очень важно. - person Kerrek SB; 18.09.2012
comment
Большое спасибо, приятель. Это было действительно полезно. - person Spaniard89; 18.09.2012
comment
Как я могу просмотреть сгенерированный график? а я добавляю ребра в приведенном выше коде? Должен ли я добавить их? Я был бы очень признателен, если бы вы могли мне помочь! - person Spaniard89; 18.09.2012
comment
Как мне выбрать случайный J из [i+1, N)? какой метод С++ я могу использовать? и как добавить ребра? Какая функция в C++ делает это? или я должен использовать BOOST в этом случае? - person Spaniard89; 18.09.2012
comment
@Kishorepandey: чтобы построить график, добавьте ребра в свою собственную матрицу или список смежности; и чтобы просмотреть его, просто распечатайте эту матрицу или список любым удобным для вас способом. Генерация случайных чисел является стандартной; поищите в интернете одну минуту, чтобы узнать, как это сделать. - person Kerrek SB; 18.09.2012
comment
У меня есть небольшое сомнение, что, если я не дам свои валентности в качестве входных данных. Как будет выглядеть описанный выше алгоритм? И я все еще не хочу иметь более четырех ребер из каждой вершины. Я попробовал ваш алгоритм, генерируя случайное число и добавляя ребра, но не создаст ли он другой граф с другим запуском? Что делать, если я хочу создать график и запустить его несколько раз с одним и тем же результатом. Что я должен изменить в приведенном выше алгоритме? Большое спасибо заранее. - person Spaniard89; 19.09.2012
comment
@Kishorepandey: я не думаю, что вы четко понимаете, чего хотите. Вам нужен случайный график или вы ожидаете, что пользовательский ввод определит уникальный график? И почему не более 4, когда в вашем вопросе говорится, что количество ребер может быть случайным? - person Kerrek SB; 19.09.2012
comment
Я не очень ясно выразился в своем вопросе, который я разместил ранее, и, следовательно, я сделаю одно, я отправлю другой вопрос с точно моими требованиями. И я бы объяснил там, почему именно я хочу только 4 ребра. Как в комментарии, я ограничен несколькими сотнями чартеров, здесь я не могу разобраться :) - person Spaniard89; 19.09.2012
comment
Я разместил здесь еще один вопрос allow-u" title="создание графика с использованием boost и сохранение его в формате grpah viz, позволяя u">stackoverflow.com/questions/12501403/ - person Spaniard89; 19.09.2012
comment
@Kishorepandey: Хорошо, отдельный вопрос определенно подходит. Увидимся там! :-) - person Kerrek SB; 20.09.2012