Форум программистов, компьютерный форум CyberForum.ru

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
Рейтинг: Рейтинг темы: голосов - 25, средняя оценка - 5.00
krvnk
13 / 13 / 1
Регистрация: 01.04.2010
Сообщений: 166
#1

Матрица смежности графа - поиск в глубину - C++

11.05.2014, 19:13. Просмотров 4173. Ответов 7
Метки нет (Все метки)

Здравствуйте дорогие форумчане. У меня тут небольшая ошибка. Никак не могу понять что к чему. Объясните пожалуйста.
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
#include <iostream>
#include <vector>
#include <conio.h>
using namespace std;
const int n=5;
int i, j;
//матрица смежности графа
int GM[n][n] =
{
{0, 1, 0, 0, 1},
{1, 0, 1, 1, 0},
{0, 1, 0, 0, 1},
{0, 1, 0, 0, 1},
{1, 0, 1, 1, 0}
};
vector < vector <int> > g(n);
vector <int> used(n);
void dfs2 (int v){
    used[v] = 1; // ставим метку, что посетили данную вершину
    for (i = 0; i < (int)g[v].size(); i++){ // проходим по все ребрам.
        if (!used[g[v][i]]){ // смотрим были ли мы в вершине раньше
            //cout<<g[v][i]+1<<" "<<v<<" "<<i<<endl;
                 dfs2(g[v][i]); // если нет, то запускаемся из нее.
        }
    }
}
void main()
{
setlocale(LC_ALL, "Rus");
    int start;
    cout<<"Стартовая вершина >> "; cin>>start;
for(i = 0; i < n; ++i)
    {
        for (j=0;j<n;j++)
            if (GM[i][j]==1) k++;
        g[i].resize(k);
        for (j=0;j<n;j++)
            if (GM[i][j]==1) 
            {
                g[i][l] = j+1;
                l++;
            }
     l=0;k=0;
    }
    for (i=0; i<n; i++)
    {
        for (j=0; j<(int)g[i].size(); j++)
        {
            
            cout<<" "<<g[i][j];
        }
        cout<<endl;
    }
cout<<"Порядок обхода в глубину: ";
    dfs2(start-1);
}
Добавлено через 34 минуты
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
#include <iostream>
#include <ctime>
#include <vector>
//#include <algorithm>
#include <conio.h>
using namespace std;
const int n=5;
int i, j;
//матрица смежности графа
int GM[n][n] =
{
{0, 1, 0, 0, 1},
{1, 0, 1, 1, 0},
{0, 1, 0, 0, 1},
{0, 1, 0, 0, 1},
{1, 0, 1, 1, 0}
};
vector < vector <int> > g(n);
vector <int> used(n); // массив меток. в начале его нужно заполнить 0.
//vector <int> tin, tout; // время входа и выхода для каждой вершины.
//int timer = 0; // данная переменная поможет нам определять время входа и выхода.
 
bool *visited=new bool[n];
//int main()
//{ 
//  unsigned int start_time =  clock();
//  unsigned int end_time = clock();
//  cout << "runtime N^2 = " << (end_time-start_time)/1000.0 <<" N="<<N<< endl;
    
//}
 
//_______________________________________
void BFS(bool *passed, int unit)
{
    //очередь
    int *queue=new int[n];
    //указатели очереди
    int count, head;
    for (i=0; i<n; i++) queue[i]=0;
    count=0; head=0;
    queue[count++]=unit;
    passed[unit]=true;
    while (head<count)
    {
        unit=queue[head++];
        cout<<unit+1<<" ";
        for (i=0; i<n; i++)
            if (GM[unit][i] && !passed[i])
            {
                queue[count++]=i;
                passed[i]=true;
            }
    }
    delete []queue;
}
void DFS(int st)
{
    int r;
    cout<<st+1<<" ";
    visited[st]=true;
    for (r=0; r<=n; r++)
        if ((GM[st][r]!=0) && (!visited[r]))
    DFS(r);
}
void dfs2 (int v){
    used[v] = 1; // ставим метку, что посетили данную вершину
    for (i = 0; i < (int)g[v].size(); i++){ // проходим по все ребрам.
        
        if (!used[g[v][i]]){ // смотрим были ли мы в вершине раньше
            cout<<v+1<<" "<<g[v][i]<<""<<endl;
            dfs2(g[v][i]-1); // если нет, то запускаемся из нее.
        }
    }
    
}
//_______________________________________
//Главная функция
void main()
{
    setlocale(LC_ALL, "Rus");
    int start;
    cout<<"Стартовая вершина >> "; cin>>start;
    //массив посещенных вершин
    bool *vis=new bool[n];
    cout<<"Матрица смежности графа: "<<endl;
    int l,k;
    l=k=0;
    for (i=0; i<n; i++)
    {
        used[i]=0;
        visited[i]=false;
        vis[i]=false;
        for (j=0; j<n; j++)
        {
            
            cout<<" "<<GM[i][j];
        }
        cout<<endl;
    }
    for(i = 0; i < n; ++i)
    {
        for (j=0;j<n;j++)
            if (GM[i][j]==1) k++;
        g[i].resize(k);
        for (j=0;j<n;j++)
            if (GM[i][j]==1) 
            {
                g[i][l] = j+1;
                l++;
            }
     l=0;k=0;
    }
    for (i=0; i<n; i++)
    {
        for (j=0; j<(int)g[i].size(); j++)
        {
            
            cout<<" "<<g[i][j];
        }
        cout<<endl;
    }
    cout<<"Порядок обхода в ширину: ";
    BFS(vis, start-1);
    cout<<"Порядок обхода в глубину: ";
    DFS(start-1);
    cout<<"Порядок обхода в глубину: \n";
    dfs2(start-1);
    delete []visited;
    delete []vis;
    system("pause>>void");
}
Вообщем весь код. Наполовину работает.
Лучшие ответы (1)
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
11.05.2014, 19:13     Матрица смежности графа - поиск в глубину
Посмотрите здесь:
C++ Матрица/связные_списки смежности для ориентированного графа
C++ По заданной квадратной матрице из нулей и единиц определите, может ли данная матрица быть матрицей смежности простого неориентированного графа
C++ Графы, матрица смежности, поиск петель
заданно матрицу смежности простого графа. Построить каркас этого графа с использованием поиска вширь C++
Обход графа в глубину C++
C++ Обход графа в глубину
Обход графа в глубину C++
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
Tulosba
:)
Эксперт С++
4393 / 3236 / 297
Регистрация: 19.02.2013
Сообщений: 9,045
11.05.2014, 19:29     Матрица смежности графа - поиск в глубину #2
Цитата Сообщение от krvnk Посмотреть сообщение
Никак не могу понять что к чему.
Что-то конкретно к чему, или к чему это всё?
P.S. тег кода должен быть C++
krvnk
13 / 13 / 1
Регистрация: 01.04.2010
Сообщений: 166
11.05.2014, 22:38  [ТС]     Матрица смежности графа - поиск в глубину #3
C++
1
2
3
4
5
6
7
8
9
10
11
void dfs2 (int v){
    used[v] = 1; // ставим метку, что посетили данную вершину
    for (i = 0; i < (int)g[v].size(); i++){ // проходим по все ребрам.
        cout<<"вершина="<<v<<" i="<<i<<" размер="<<(int)g[v].size()<<" вершина="<<g[v][i]<<" res="<<!used[g[v][i]]<<endl;
        if (!used[g[v][i]-1]){ // смотрим были ли мы в вершине раньше
            cout<<v+1<<" "<<g[v][i]<<""<<endl;
            dfs2(g[v][i]-1); // если нет, то запускаемся из нее.
        }
    }
    
}
Цитата Сообщение от Tulosba Посмотреть сообщение
Что-то конкретно к чему, или к чему это всё?
Интересует этот момент. При запуске всё время выдаёт ошибку

Добавлено через 4 минуты

Матрица смежности графа - поиск в глубину
Tulosba
:)
Эксперт С++
4393 / 3236 / 297
Регистрация: 19.02.2013
Сообщений: 9,045
11.05.2014, 23:50     Матрица смежности графа - поиск в глубину #4
Сообщение было отмечено автором темы, экспертом или модератором как ответ
Когда было так:
C++
1
if (!used[g[v][i]]){
, то выходили за границу вектора used. Но в последнем сообщении исправлено уже:
C++
1
if (!used[g[v][i]-1]){
При каких входных данных ошибка проявляется?
Кстати, старайтесь избегать дублирования в коде. Например, под g[v][i] можно завести переменную в теле цикла и пользоваться ею в дальнейших операциях.
krvnk
13 / 13 / 1
Регистрация: 01.04.2010
Сообщений: 166
12.05.2014, 02:12  [ТС]     Матрица смежности графа - поиск в глубину #5
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
#include <iostream>
#include <ctime>
#include <vector>
#include <queue>  
//#include <algorithm>
#include <conio.h>
using namespace std;
 
const int n=10000;
int i, j;
int GM[n][n];
//матрица смежности графа
/*int GM[n][n] =
{
{0, 1, 0, 0, 1},
{1, 0, 1, 1, 0},
{0, 1, 0, 0, 1},
{0, 1, 0, 0, 1},
{1, 0, 1, 1, 0}
};*/
 
bool *vis=new bool[n];
bool *visited=new bool[n];
 
vector < vector <int> > g(n);
vector <int> used(n); // массив меток. в начале его нужно заполнить 0.
 
//  unsigned int end_time = clock();
//  cout << "runtime N^2 = " << (end_time-start_time)/1000.0 <<" N="<<N<< endl;
    
//сложность n^2
void BFS(bool *passed, int unit)
{
    //очередь
    int *posl=new int[n];
    //указатели очереди
    int count, head;
    for (i=0; i<n; i++) posl[i]=0;
    count=0; head=0;
    posl[count++]=unit;
    passed[unit]=true;
    while (head<count)
    {
        unit=posl[head++];
        //cout<<unit+1<<" ";
        for (i=0; i<n; i++)
            if (GM[unit][i] && !passed[i])
            {
                posl[count++]=i;
                passed[i]=true;
            }
    }
    delete []posl;
}
//сложность n+m
void bfs2 (int s)
{
queue<int> q;
q.push (s);
//cout<<s+1<<" ";
vector<bool> used (n);
used[s] = true;
while (!q.empty()) {
    int v = q.front();
    q.pop();
    for (vector<int>::iterator i=g[v].begin(); i!=g[v].end(); ++i)
        if (!used[*i-1])
        {
            used[*i-1]=true;
            q.push(*i-1);
            //cout<<*i<<" ";
        }
}
}
//сложность n^2
void DFS(int st)
{
    int r;
    //cout<<st+1<<" ";
    visited[st]=true;
    for (r=0; r<=n; r++)
        if ((GM[st][r]!=0) && (!visited[r]))
    DFS(r);
}
//сложность n+m
void dfs2 (int v) {
    used[v] = true;
    //cout<<v+1<<" ";
    for (vector<int>::iterator i=g[v].begin(); i!=g[v].end(); ++i)
        if (!used[*i-1])
        {
            dfs2 (*i-1);
            
        }
    
}
 
void main()
{
    srand (time(NULL));
    setlocale(LC_ALL, "Rus");
    int start;
    cout<<"Стартовая вершина >> "; cin>>start;
    cout<<"Матрица смежности графа: "<<endl;
 
    for (i=0;i<n;i++)
        for (j=i;j<n;j++)
        {
            GM[i][j]=rand() % 2;
            GM[j][i]=GM[i][j];
        }
    for (i=0;i<n;i++)
        GM[i][i]=0;
    int l,k;
    l=k=0;
    for (i=0; i<n; i++)
    {
        used[i]=0;
        visited[i]=false;
        vis[i]=false;
        for (j=0; j<n; j++)
        {
            
            //cout<<" "<<GM[i][j];
        }
        cout<<endl;
    }
    for(i = 0; i < n; ++i)
    {
        for (j=0;j<n;j++)
            if (GM[i][j]==1) k++;
        g[i].resize(k);
        for (j=0;j<n;j++)
            if (GM[i][j]==1) 
            {
                g[i][l] = j+1;
                l++;
            }
     l=0;k=0;
    }
    cout<<"Матрица векторная: "<<endl;
    for (i=0; i<n; i++)
    {
        for (j=0; j<(int)g[i].size(); j++)
        {
            
            //cout<<" "<<g[i][j];
        }
    }
    cout<<"Порядок обхода в ширину N^2: \n";
    unsigned int start_time =  clock();
    BFS(vis, start-1);
    //cout<<endl;
    unsigned int end_time = clock();
    cout << "runtime N^2 = " << (end_time-start_time)/1000.0 <<" N="<<n<< endl;
    cout<<endl;
 
    cout<<"Порядок обхода в ширину N+M: \n";
    start_time =  clock();
    bfs2(start-1);
    end_time =  clock();
    //cout<<endl;
    cout << "runtime N^2 = " << (end_time-start_time)/1000.0 <<" N="<<n<< endl;
    cout<<endl;
 
    cout<<"Порядок обхода в глубину N^2: \n";
    start_time =  clock();
    DFS(start-1);
    end_time =  clock();
    //cout<<endl;
    cout << "runtime N^2 = " << (end_time-start_time)/1000.0 <<" N="<<n<< endl;
    cout<<endl;
 
    cout<<"Порядок обхода в глубину M+N: \n";
    start_time =  clock();
    dfs2(start-1);
    end_time =  clock();
    //cout<<endl;
    cout << "runtime N^2 = " << (end_time-start_time)/1000.0 <<" N="<<n<< endl;
    delete []visited;
    delete []vis;
    system("pause>>void");
}
всё работает спасибо.
но тут вопрос, а почему с вектором и с очередью дольше выполняется программа, чем просто с массивом? Слишком много обращений да?
И как упростить, чтобы быстрее чем с матрицами выполнялось? Что нужно использовать?
Tulosba
:)
Эксперт С++
4393 / 3236 / 297
Регистрация: 19.02.2013
Сообщений: 9,045
12.05.2014, 07:47     Матрица смежности графа - поиск в глубину #6
krvnk, когда стоит вопрос оптимизации по скорости, имеет смысл начинать использование профилировщиков. Это специальная програма для определения "узких" мест в программе. Но уже неворуженным взглядом видно, что лучше исключить при каждом вызове функции динамическое выделения памяти (строки 35,53,59,70).
krvnk
13 / 13 / 1
Регистрация: 01.04.2010
Сообщений: 166
13.05.2014, 22:16  [ТС]     Матрица смежности графа - поиск в глубину #7
Цитата Сообщение от Tulosba Посмотреть сообщение
исключить при каждом вызове функции динамическое выделения памяти
А как это сделать? Например в 70 строке
C++
1
q.push(*i-1);
На что заменить?

Прочитал в Левитине что если использовать связанные списки, вместо матрицы смежности сложность уменьшится с О(n^m) до О(n+m). Но связный список тоже по моему использует динамическое выделение памяти?
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
13.05.2014, 22:32     Матрица смежности графа - поиск в глубину
Еще ссылки по теме:
Обход неориентированного графа в глубину C++
C++ Многопоточный обход графа в глубину
Компоненты связности графа поиском в глубину C++
C++ Обход вершин графа в глубину стеком
Список смежности для графа C++

Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
Tulosba
:)
Эксперт С++
4393 / 3236 / 297
Регистрация: 19.02.2013
Сообщений: 9,045
13.05.2014, 22:32     Матрица смежности графа - поиск в глубину #8
Цитата Сообщение от krvnk Посмотреть сообщение
А как это сделать? Например в 70 строке
Однозначно сказать сложно. Но можно попробовать например задаться максимальным размером, т.е. выделить память один раз, вместо того, чтобы выделять несколько.
Yandex
Объявления
13.05.2014, 22:32     Матрица смежности графа - поиск в глубину
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru