Реализация псевдокода с использованием матрицы: - PullRequest
0 голосов
/ 10 апреля 2020

Мне нужно реализовать следующий код в виде матрицы. Мне нужно получить исходную вершину и случайным образом сгенерировать связанный граф. Тем не менее, псевдокод находится в форме списка, и я не уверен, правильно ли я преобразовал его в матричную форму, для вывода по какой-то причине я продолжаю получать все узлы, которые будут полностью исследованы, или цвет их всех становится черным ?

D представляет расстояние

π представляет родителей

цвет = белый не посещен / серый посещен / черный все соседи исследованы

enter image description here

     #include <iostream>
#include <limits>
#include <queue>
#include <stdlib.h>     /* srand, rand */

using namespace std;



enum  Color {white , gray, black};
struct vertex{

    Color color =white ;
   int relationship =0;
   int distance =abs(numeric_limits<int>::max());
   int parent =0;

};

void BFS(int size ,int s)
{
   //no need for first loop to initializer to defaults since they are already
    vertex g [size][size];
    int random;
    for(int i=0;i<size;i++)
    {
        for(int j=0;j<size;j++)
        {
            random =rand()%(size);
            if(j!=i and random!=i) //to make it undirected
            {
                g[i][random].relationship=1;
                g[random][i].relationship=1;

            }

        }

    }
   ///
   g[s][0].color =gray;
   g[s][0].distance=0;
   g[s][0].parent=0;
    queue <int> q;
    q.push(s);

    int u;
    while(!q.empty())
    {
        u=q.front();
        q.pop();
        g[u][0].color=black;
        for(int v=0;v<size;v++)
        {
            if (g[u][v].relationship==1 and g[v][0].color==white) {
                g[v][0].color = gray;
                g[v][0].distance = g[u][0].distance+1;
                g[v][0].parent = u;
                q.push(v);
            }


        }
    }


    for(int i = 0; i<size;i++)
    {

       for(int j =0;j<size;j++)
       {
           cout<<g[i][j].relationship <<" ";
       }
       cout<<endl;

    }
for(int i = 0; i<size;i++)
{

    cout<<" Distance of node: " << i<<" from the source is: ";
    cout<< g[i][0].distance<<" ";
    if(g[i][0].color==white)
    {
        cout<<" Color of node: " << i<<" is white";

    }
    if(g[i][0].color==gray)
    {
        cout<<" Color of node: " << i<<" is gray";

    }

    if(g[i][0].color==black){
        cout<<" Color of node: " << i<<" is black";

  }
    cout<<" parent of node: " << i<<" ";
    cout<< g[i][0].parent<<" "<<" ";
    cout<<endl;
   }

}
int main() {


    int vertices;
    cout<<"Please enter the number of vertices: "<<endl;
    cin>>vertices;
    int source;
    cout<<"Please enter the source  "<<endl;
    cin>>source;
    BFS(vertices,source);




    return 0;
}

Ответы [ 2 ]

1 голос
/ 10 апреля 2020

Вы, похоже, иногда ошибаетесь с v и не принимаете во внимание идентификацию из псевдокода.

            q.pop();
            g[v][0].color=black;

должен был быть после for. Кроме того, вы сделали

g[v][0].color=black

вместо

g[u][0].color=black

с вами. Опять же, та же ошибка ранее:

                g[v][0].distance = g[v][0].distance+1;

, когда вы должны были написать это (с u):

                g[v][0].distance = g[u][0].distance+1;

с u вместо v. Это на самом деле не имеет никакого смысла в противном случае.

Я настоятельно рекомендую прочитать логи c за BFS. https://www.geeksforgeeks.org/breadth-first-search-or-bfs-for-a-graph/

Если вы действительно знаете логику c, стоящую за BFS, и только что совершили эти ошибки, вот два совета по отладке, которые помогли мне понять, что происходит неправильно:

  1. , если ваша программа должна выводить некоторые значения, но это не так, скорее всего, будет oop. Обычно при отладке рекомендуется использовать cout на промежуточных этапах, посмотрите, соответствует ли результат ожидаемому. Вы можете сделать аналогичные вещи в случае al oop, чтобы заметить, где находится l oop и, возможно, даже почему.

    1.1. И если каким-то образом, независимо от того, где вы разместили cout, вы все равно не получаете вывод, возможно, произошла ошибка сегментации (в определенных средах кодирования это скажет ошибка сегментации, иногда вы увидите, что это займет некоторое время, прежде чем сказать что-то вроде «процесс завершен, возвращено некоторое число, которое не равно 0», возможно, «процесс завершен, возвращен -243» в консоли. Ошибка сегментации - когда вы обращаетесь к некоторой памяти, которую вы не должны (один из элементов, которые вы Попытка доступа к массиву выходит за границы, или вы удалили этот элемент из списка, и вы пытаетесь получить к нему доступ.)

  2. После того, как q.pop () была решена, вы заметил отрицательный и большой вывод (что обычно было невозможно). Это означает, что где-то произошло переполнение. Вы начали с максимального расстояния почти для всех узлов, кроме источника, переполнение имело смысл, как-то добавляя к узлам, которые имеют максимум.

Правка: о случайной генерации, как есть сейчас это не так уж случайно. Вы должны использовать генератор случайных чисел с начальным числом, таким как текущее время, чтобы каждый раз получать новое дерево.

В c ++ есть srand, и здесь вы можете увидеть быстрый пример из https://www.cplusplus.com/reference/cstdlib/srand/ о получении действительных случайных чисел из srand (простая инициализация без аргумента заставит его каждый раз выбирать одно и то же начальное число и, следовательно, давать тот же результат. Однако мы можем исправить это с получением текущего времени, так как текущее время будет всегда отличаться и использовать его как семя):

/* srand example */
#include <stdio.h>      /* printf, NULL */
#include <stdlib.h>     /* srand, rand */
#include <time.h>       /* time */

int main ()
{
  printf ("First number: %d\n", rand()%100);
  srand (time(NULL));
  printf ("Random number: %d\n", rand()%100);
  srand (1);
  printf ("Again the first number: %d\n", rand()%100);

  return 0;
}
0 голосов
/ 10 апреля 2020

Ваш q.pop() находится не в том месте. Поскольку он находится в середине вашего значения для l oop, вы удаляете size записей из очереди для каждой вершины, обрабатываемой из очереди. То, что вы хотите сделать, это переместить q.pop() сразу после u=q.front().

u = q.front();
q.pop();
for(int v = 0; v < size; v++)
...