-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathbfs.c
134 lines (119 loc) · 3.95 KB
/
bfs.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
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* bfs.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: advardon <[email protected]> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2019/08/11 11:53:27 by advardon #+# #+# */
/* Updated: 2019/08/19 17:53:25 by advardon ### ########.fr */
/* */
/* ************************************************************************** */
#include "../includes/lem_in.h"
/*
** Ascending from Descending
** When we come from a room whch is not in a valid path AND we enter a room that
** IS in a valid path, the ONLY neighbor we can visit is the neigbhor with a
** connexion of -1.
** Until the end of this bfs, this neigboring room is not consider in a valid
** path anymore (hence we set the in_path bool of this neigbhor to 0).
** Return 1 if we can queue the neighbor connected by a flow of -1
*/
int asc_f_dsc(t_anthill *anthill, t_connex *neigh, t_room *actual, t_queue *q)
{
t_room *check_room;
check_room = &anthill->tab_room[neigh->room_id];
if (check_room->visited != anthill->round && neigh->value == -1)
{
check_room->visited = anthill->round;
check_room->in_path = 0;
check_room->parent_id = actual->id;
enqueue(q, &anthill->tab_room[neigh->room_id]);
return (1);
}
return (0);
}
/*
** Enqueue this neighbor if he has a connection of 0 or -1.
** Return 1 if we reach the end room, 0 if not.
*/
int check_neigh(t_anthill *anthill, t_connex *neigh, t_room *actual, t_queue *q)
{
t_room *check_room;
check_room = &anthill->tab_room[neigh->room_id];
if (check_room->visited != anthill->round && neigh->value != 1)
{
check_room->visited = anthill->round;
check_room->parent_id = actual->id;
enqueue(q, &anthill->tab_room[neigh->room_id]);
if (neigh->room_id == anthill->id_end)
return (1);
}
return (0);
}
int find_connex(t_anthill *anthill, t_room *actual)
{
t_connex *neighbour;
neighbour = anthill->graph->array[actual->id].next;
while (neighbour)
{
if (neighbour->room_id == actual->parent_id)
{
if (neighbour->value == 1)
return (-neighbour->value);
else
return (1);
}
neighbour = neighbour->next;
}
return (1);
}
/*
** Process through all neighbour of actual and add a valid neighbour to queue
** To test if we had to add neighbour to the queue we used:
** Dir == 1 if we come from a room that is not yet in a valid path
** (connex between rooms == 0). Dir == -1 if we come from a room that
** is already in a valid path (connex between rooms == -1).
** First we test the case where
** Return 1 if the BFS reach the end room, 0 if not.
*/
int process_neighbours(t_anthill *anthill, t_room *actual, t_queue *q)
{
t_connex *neighbour;
int dir;
neighbour = anthill->graph->array[actual->id].next;
dir = find_connex(anthill, actual);
while (neighbour)
{
if (actual->in_path && dir == 1)
{
if (asc_f_dsc(anthill, neighbour, actual, q))
if (neighbour->room_id == anthill->id_end)
return (1);
}
else if (check_neigh(anthill, neighbour, actual, q))
return (1);
neighbour = neighbour->next;
}
return (0);
}
/*
** Use of breadth first search algorithm for searching the shortest path
** between room start and room end.
*/
int bfs(t_anthill *anthill)
{
t_queue *q;
t_room *actual;
anthill->round++;
q = createqueue(anthill);
enqueue(q, &anthill->tab_room[anthill->id_start]);
anthill->tab_room[anthill->id_start].visited = anthill->round;
while (q->front != NULL)
{
actual = dequeue(q);
if (process_neighbours(anthill, actual, q))
return (1);
}
return (0);
}