Форум программистов, компьютерный форум, киберфорум
Наши страницы
С++ для начинающих
Войти
Регистрация
Восстановить пароль
 
Рейтинг 4.53/32: Рейтинг темы: голосов - 32, средняя оценка - 4.53
krvnk
13 / 13 / 10
Регистрация: 01.04.2010
Сообщений: 168
#1

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

11.05.2014, 19:13. Просмотров 5706. Ответов 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");
}
Вообщем весь код. Наполовину работает.
0
Лучшие ответы (1)
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
11.05.2014, 19:13
Ответы с готовыми решениями:

Матрица/связные_списки смежности для ориентированного графа
Скажите, пожалуйста, когда я создаю матрицу смежности для ориентированного...

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

Графы, матрица смежности, поиск петель
Добрый вечер! Задача: Задан граф в виде количества вершин n≤10 и...

По заданной матрице смежности простого графа построить каркас этого графа с использованием поиска в ширину
Задание: заданно матрицу смежности простого графа. Построить каркас этого...

Обход графа в глубину
Как сделать обход этого графа в глубину ?

7
Tulosba
:)
Эксперт С++
4747 / 3241 / 497
Регистрация: 19.02.2013
Сообщений: 9,046
11.05.2014, 19:29 #2
Цитата Сообщение от krvnk Посмотреть сообщение
Никак не могу понять что к чему.
Что-то конкретно к чему, или к чему это всё?
P.S. тег кода должен быть C++
0
krvnk
13 / 13 / 10
Регистрация: 01.04.2010
Сообщений: 168
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 минуты

Матрица смежности графа - поиск в глубину
0
Tulosba
:)
Эксперт С++
4747 / 3241 / 497
Регистрация: 19.02.2013
Сообщений: 9,046
11.05.2014, 23:50 #4
Лучший ответ Сообщение было отмечено krvnk как решение

Решение

Когда было так:
C++
1
if (!used[g[v][i]]){
, то выходили за границу вектора used. Но в последнем сообщении исправлено уже:
C++
1
if (!used[g[v][i]-1]){
При каких входных данных ошибка проявляется?
Кстати, старайтесь избегать дублирования в коде. Например, под g[v][i] можно завести переменную в теле цикла и пользоваться ею в дальнейших операциях.
1
krvnk
13 / 13 / 10
Регистрация: 01.04.2010
Сообщений: 168
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");
}
всё работает спасибо.
но тут вопрос, а почему с вектором и с очередью дольше выполняется программа, чем просто с массивом? Слишком много обращений да?
И как упростить, чтобы быстрее чем с матрицами выполнялось? Что нужно использовать?
0
Tulosba
:)
Эксперт С++
4747 / 3241 / 497
Регистрация: 19.02.2013
Сообщений: 9,046
12.05.2014, 07:47 #6
krvnk, когда стоит вопрос оптимизации по скорости, имеет смысл начинать использование профилировщиков. Это специальная програма для определения "узких" мест в программе. Но уже неворуженным взглядом видно, что лучше исключить при каждом вызове функции динамическое выделения памяти (строки 35,53,59,70).
1
krvnk
13 / 13 / 10
Регистрация: 01.04.2010
Сообщений: 168
13.05.2014, 22:16  [ТС] #7
Цитата Сообщение от Tulosba Посмотреть сообщение
исключить при каждом вызове функции динамическое выделения памяти
А как это сделать? Например в 70 строке
C++
1
q.push(*i-1);
На что заменить?

Прочитал в Левитине что если использовать связанные списки, вместо матрицы смежности сложность уменьшится с О(n^m) до О(n+m). Но связный список тоже по моему использует динамическое выделение памяти?
0
Tulosba
:)
Эксперт С++
4747 / 3241 / 497
Регистрация: 19.02.2013
Сообщений: 9,046
13.05.2014, 22:32 #8
Цитата Сообщение от krvnk Посмотреть сообщение
А как это сделать? Например в 70 строке
Однозначно сказать сложно. Но можно попробовать например задаться максимальным размером, т.е. выделить память один раз, вместо того, чтобы выделять несколько.
1
13.05.2014, 22:32
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
13.05.2014, 22:32

Обход графа в глубину
Покажите кто-нибудь как работает &quot;обход графа&quot; в графе в консоле А именно...

Обход графа в глубину
Помогите, пожалуйста! Необходимо написать программу, которая показывала бы...

Многопоточный обход графа в глубину
Доброго времени суток. Подскажите многопоточный алгоритм обхода графа в глубину...


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

Или воспользуйтесь поиском по форуму:
8
Ответ Создать тему
Опции темы

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