So I have a lab to implement Breadth First Search and Depth First Search using an adjacency matrix. The vertices of the graph to be searched are numbered 0-(V-1), so for example a graph with 10 vertices would have vertices numbered 0-9. Each vertex is also given a value.
In the example I am going to give, the number of each vertex is equal to it's value (for example, vertex 0 has value 0, vertex 1 has value 1, etc.). I store the values of each vertex in an array, where the position is the vertex and the item in the array is it's value, so finding the value of vertex 7 would look like:
value = matrix[7];
I am supposed to write a program that finds a certain value with Breadth First Search and reports the vertex it was found at, and how many "steps" it took to find it.
My program finds the value in each test case, but the problem is that the "steps" don't match. I think the problem must be within my BFS algorithm itself, but I can't find it.
For example, I am searching the following adjacency matrix for value 7, which is at vertex 7:
0 1 1 0 0 0 0 0 0 0
0 0 0 1 1 0 0 0 0 0
0 0 0 0 0 1 1 0 0 0
0 0 0 0 0 0 0 1 1 0
0 0 0 0 0 0 0 0 0 1
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
There are 10 nodes, numbered 0-9, node 0 is connected to nodes 1 and 2, node 1 is connected to nodes 3 and 4, node 2 is connected to nodes 5 and 6, node 3 is connected to nodes 7 and 8, and node 4 is connected to node 9.
As mentioned "vertices" is the array of vertex values. "matrix" is the adjacency matrix. "visited" is an array of bool to keep track of whether or not a vertex has been visited.
I am "walking" the graph with a deque container, which I am required to use.
Here is my BFS:
steps = 1;
int cur_v = 0;
int vertexFound = 0;
bool found = false;
bool *visited = new bool[V];
for (int i = 0; i < V; i++) {
visited[i] = false;
}
deque <int> q;
q.push_back(0);
visited[0] = true;
while (!q.empty()) {
if (found == false) {
steps++;
}
cur_v = q.front();
q.pop_front();
for (int n = 0; n < V; n++) {
if (matrix[cur_v][n] == 1) {
if (visited[n] == false) {
if (vertices[n] == search) {
vertexFound = n;
found = true;
}
visited[n] = true;
q.push_back(n);
}
}
}
}
if (found == true) {
cout << steps << endl;
}
The value I am searching for is "7", located at vertex 7. It is supposed to take 7 steps for me to get there, but my program says that it takes 5.
Another problem I am having is that when I give the program input that is supposed to make it search for value 8 in a graph with 8 vertices that go from values 0-7, it tells me that it found the value at vertex 0 in 9 steps.
Any help is very appreciated!
You shouldn't be updating vertexFound after the first time you find what you're looking for. (And indeed you could just stop searching immediately.)
Related
so I have 2 functions :
UPDATED
unordered_map<int, bool> visited2;
vector<vector<int>> elements2D;
bool DFSDetectCycle(int vertex){
s.push(vertex);
while(!s.empty()){
int np_vertex = s.top();
s.pop();
if (visited2[np_vertex] == true){
return true;
}
visited2[np_vertex] = true;
for (int i = 0; i<elements2D.size(); i++){
if(elements2D[np_vertex][i] != 0){
if(DFSDetectCycle(i)){
return true;
}
}
}
}
return false;
}
bool hasCycle(vector<vector<int>> v){
if (v.empty()){
return false;
}
for (int i = 0; i<v.size(); i++){
if (!visited2[i]){
if(DFSDetectCycle(i)){
return true;
}
}
}
return false;
}
And in my main function I call it like this:
if (hasCycle(elements2D)){
for (int i = 0; i<elements2D.size(); i++){
if (!visited2[i]){
DFSDetectCycle(i);
}
}
}else{
cout << "No cycles." << endl;
}
So basically, the input is going to look like this:
g++ -o GraphProcessor.o GraphProcessor.cpp -std=c++11
./GraphProcessor.o graph1.txt
And the output should look like this:
Connected components:
{0,1,2,4,7}
{3}
{5,6}
A cycle: 0 1 4 2
But my output looks like this:
Connected components:
{0,1,4,2,7}
{3}
{5,6}
No cycles.
graph1.txt looks like this:
0 2 6 0 0 0 0 3
2 0 0 0 4 0 0 1
6 0 0 0 3 0 0 2
0 0 0 0 0 0 0 0
0 4 3 0 0 0 0 0
0 0 0 0 0 0 7 0
0 0 0 0 0 7 0 0
3 1 2 0 0 0 0 0
Do not worry about the connected components part, that is not my problem right now. My problem is that my code is not properly detecting cycles in the graph and is not outputting them properly either. It seems as if my hasCycle() function is constantly giving a false statement, but I am not really sure why. elements2D is my matrix I am using, since it was read from a file, I needed somewhere to store it. For my visited2 function, I use an unordered_map in order to keep boolean values on whether or not I have visited the vertices or not. I know that if I have visited a vertex again, then I have a cycle. But I am not sure how to modify my algorithm in order to obtain a result like that.
Thanks again for any help.
You are calling DFSDetectCycle recursively without using it's return value. I suggest you check if recursive call return true, and return it is so.
You are specifically skipping the cycles because you filter the recursive calls with if(elements2D[np_vertex][i] != 0 && !visited2[i]) - which means you will not go into already visit vertexes, skipping the cycles.
In addition, there are no prints in the code that would yield the required output...
You should remove visited[i] checking from if(elements2D[np_vertex][i] != 0 && !visited2[i]), because if you already visited i, then removing this checking can detect it. And if it finds cycle, you should return it immediately.
if(elements2D[np_vertex][i] != 0){
if (DFSDetectCycle(i)) return true;
}
Another issue is if there exist edges 0->1 and 1->0, then they make a cycle. You need more work to find largest cycle.
I am trying to loop over a matrix and print its element, which should be a simple operation, but I experience some strange things...
I have a a null matrix :
cv::Mat accum = cv::Mat::zeros(3,5,CV_8U);
Doing this:
for(int i=0;i<accum.rows;i++)
{
for(int j=0;j<accum.cols;j++)
{
cout<<accum.at<int>(i,j) <<endl;
}
}
I get the following elements:
0
0
0
0
0
0
0
0
0
-536870912
0
0
0
2027945984
587217671
Why is there some random number at places where zero should be?
If I initialize the value of matrix at i=1,j=1 with number 1, I get the following
0
0
256
0
0
0
1
0
0
587202560
0
0
0
1931673600
587257437
I just dont understand those random values, I might do something wrong, but cant figure out what. Could you please help?
I have been stuck with this problem for two days and I still can't get it right.
Basically, I have a 2D array with relations between certain numbers (in given range):
0 = the order doesn't matter
1 = the first number (number in left column) should be first
2 = the second number (number in upper row) should be first
So, I have some 2D array, for example this:
0 1 2 3 4 5 6
0 0 0 1 0 0 0 2
1 0 0 2 0 0 0 0
2 2 1 0 0 1 0 0
3 0 0 0 0 0 0 0
4 0 0 2 0 0 0 0
5 0 0 0 0 0 0 0
6 1 0 0 0 0 0 0
And my goal is to create a new array of given numbers (0 - 6) in such a way that it is following the rules from the 2D array (e.g. 0 is before 2 but it is after 6). I probably also have to check if such array exists and then create the array. And get something like this:
6 0 2 1 4 5
My Code
(It doesn't really matter, but I prefer c++)
So far I tried to start with ordered array 0123456 and then swap elements according to the table (but that obviously can't work). I also tried inserting the number in front of the other number according to the table, but it doesn't seem to work either.
// My code example
// I have:
// relArr[n][n] - array of relations
// resArr = {1, 2, ... , n} - result array
for (int i = 0; i < n; i++) {
for (int x = 0; x < n; x++) {
if (relArr[i][x] == 1) {
// Finding indexes of first (i) and second (x) number
int iI = 0;
int iX = 0;
while (resArr[iX] != x)
iX++;
while (resArr[iI] != i)
iI++;
// Placing the (i) before (x) and shifting array
int tmp, insert = iX+1;
if (iX < iI) {
tmp = resArr[iX];
resArr[iX] = resArr[iI];
while (insert < iI+1) {
int tt = resArr[insert];
resArr[insert] = tmp;
tmp = tt;
insert++;
}
}
} else if (relArr[i][x] == 2) {
int iI = 0;
int iX = 0;
while (resArr[iX] != x)
iX++;
while (resArr[iI] != i)
iI++;
int tmp, insert = iX-1;
if (iX > iI) {
tmp = resArr[iX];
resArr[iX] = resArr[iI];
while (insert > iI-1) {
int tt = resArr[insert];
resArr[insert] = tmp;
tmp = tt;
insert--;
}
}
}
}
}
I probably miss correct way how to check whether or not it is possible to create the array. Feel free to use vectors if you prefer them.
Thanks in advance for your help.
You seem to be re-ordering the output at the same time as you're reading the input. I think you should parse the input into a set of rules, process the rules a bit, then re-order the output at the end.
What are the constraints of the problem? If the input says that 0 goes before 1:
| 0 1
--+----
0 | 1
1 |
does it also guarantee that it will say that 1 comes after 0?
| 0 1
--+----
0 |
1 | 2
If so you can forget about the 2s and look only at the 1s:
| 0 1 2 3 4 5 6
--+--------------
0 | 1
1 |
2 | 1 1
3 |
4 |
5 |
6 | 1
From reading the input I would store a list of rules. I'd use std::vector<std::pair<int,int>> for this. It has the nice feature that yourPair.first comes before yourPair.second :)
0 before 2
2 before 1
2 before 4
6 before 0
You can discard any rules where the second value is never the first value of a different rule.
0 before 2
6 before 0
This list would then need to be sorted so that "... before x" and "x before ..." are guaranteed to be in that order.
6 before 0
0 before 2
Then move 6, 0, and 2 to the front of the list 0123456, giving you 6021345.
Does that help?
Thanks for the suggestion.
As suggested, only ones 1 are important in 2D array. I used them to create vector of directed edges and then I implemented Topological Sort. I decide to use this Topological Sorting Algorithm. It is basically Topological Sort, but it also checks for the cycle.
This successfully solved my problem.
So I'm working on the life game, and so far I have come up with this http://ideone.com/QG4tsS I'm not sure exactly if I am on the right track or not. Basically I have a function putting out random values to try and test my code. But nothing seems to happen. I suspect my problem lies with the following code
int sum = 0;
for (int k = (i - 1); k <= (i + 1); k++) {
for (int l = (j - 1); l <= (j + 1); l++) {
sum += currentGen[k][l];
}
}
return sum;
So my result gives me a 2d array with all 0's but shouldn't I start to see some changes and patterns starting to form? I get one 1 and the rest are 0.
Output
0 0 0 0
0 0 0 0
0 0 0 0
0 0 0 0
0 0 0 0
0 0 0 0
0 0 0 1
0 0 0 0
0 0 0 0
0 0 0 0
0 0 0 0
0 0 0 0
0 0 0 0
0 0 0 0
0 0 0 0
0 0 0 0
0 0 0 0
0 0 0 0
I provide this answer based on the code you posted at http://ideone.com/QG4tsS . You really should consider adding that code to your original question, so that future folks who find this on StackOverflow have the full context.
Your RandomCells function only sets cells to 1 if they meet the RANDOM threshold. It doesn't clear them to 0 otherwise. Once you fix that, you'll be all set. ie.
void RandomCells(int currentGen[][CELLY]) {
for (int i = 0; i < CELLX; i++) {
for (int j = 0; j < CELLY; j++) {
if (rand() % 100 + 1 < RANDOM) {
currentGen[i][j] = 1;
} else
{
currentGen[i][j] = 0;
}
}
}
}
Without that else clause, I was seeing initial generations that looked like this:
0 0 4196155 1
1813657216 1 4197653 0
-870503576 1 4197584 1
Clearly, most of those cells were non-zero, and so Conway's Life algorithm would map them to 0 in the next generation because of "crowding".
The reason currentGen was filled with such 'random' values is that it was allocated as an automatic variable to main. Automatic variables do not get initialized to any particular value. You need to initialize them yourself. You can do that by modifying your algorithm (as I did above), or by adding an explicit bit of code to initialize the structure.
This differs from file-scope variables, which C and C++ define as initialized-to-zero on program start if they don't have initializers or default constructors. (Pedants will point out that even that has caveats.)
Once you make the required fixes, to truly see Conway's Life, you'll need to set CELLX and CELLY to larger values...
Hello everywhere there is an explanation by drawings hot to create graph out of adj. matrix. However, i need simple pseudo code or algorithym for that .... I know how to draw it out of adj. matrix and dont know why nobody no where explains how to actually put it in code. I dont mean actual code but at least algorithm ... Many say .. 1 is if there is an edge i know that.. I have created the adj. matrix and dont know how to transfer it to graph. My vertices dont have names they are just indexes of the matrix. for example 1-9 are the "names of my matrix"
1 2 3 4 5 6 7 8 9
1 0 1 0 0 1 0 0 0 0
2 1 0 1 0 0 0 0 0 0
3 0 1 0 1 0 0 0 0 0
4 0 0 1 0 0 1 0 0 0
5 1 0 0 0 0 0 1 0 0
6 0 0 0 1 0 0 0 0 1
7 0 0 0 0 1 0 0 1 0
8 0 0 0 0 0 0 1 0 0
9 0 0 0 0 0 1 0 0 0
that was originaly a maze ... have to mark row1 col4 as start and row7 col8 end ...
Nobody ever told me how to implement graph out of matrix (without pen) :Pp
thanks
Nature of symmetry
Adjancency matrix is a representation of a graph. For undirected graph, its matrix is symmetrical. For instance, if there is an edge from vertex i to vertex j, there must also be an edge from vertex j to vertex i. That is the same edge actually.
*
*
* A'
A *
*
*
Algorithm
Noticing this nature, you can implement your algorithm as simple as:
void drawGraph(vertices[nRows][nCols])
{
for (unsigned int i = 0; i < nRows; ++i)
{
for (unsigned int j = i; j < nCols; ++j)
{
drawLine(i, j);
}
}
}
You can convert a graph from an adjacency matrix representation to a node-based representation like this:
#include <iostream>
#include <vector>
using namespace std;
const int adjmatrix[9][9] = {
{0,1,0,0,1,0,0,0,0},
{1,0,1,0,0,0,0,0,0},
{0,1,0,1,0,0,0,0,0},
{0,0,1,0,0,1,0,0,0},
{1,0,0,0,0,0,1,0,0},
{0,0,0,1,0,0,0,0,1},
{0,0,0,0,1,0,0,1,0},
{0,0,0,0,0,0,1,0,0},
{0,0,0,0,0,1,0,0,0}
};
struct Node {
vector<Node*> neighbours;
/* optional additional node information */
};
int main (int argc, char const *argv[])
{
/* initialize nodes */
vector<Node> nodes(9);
/* add pointers to neighbouring nodes */
int i,j;
for (i=0;i<9;++i) {
for (j=0;j<9;++j) {
if (adjmatrix[i][j]==0) continue;
nodes[i].neighbours.push_back(&nodes[j]);
}
}
/* print number of neighbours */
for (i=0;i<9;++i) {
cout << "Node " << i
<< " has " << nodes[i].neighbours.size() <<" outbound edges." << endl;
}
return 0;
}
Here, the graph is represented as an array of nodes with pointers to reachable neighbouring nodes. After setting up the nodes and their neighbour pointers you use this data structure to perform the graph algorithms you want, in this (trivial) example print out the number of outbound directed edges each node has.