Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 6 years ago.
Improve this question
Given adjacency relation like
3 -> 4
1-> 3
Etc..
How do I construct a graph of it. I want a easier implementation which can be understood by a beginner. I know about self referential structures. Please help
Why don't you use Adjacency Matrix, it's pretty simple and easy.
Adjacency matrices are matrices which define relations between the vertices of a graph.
See in the example above, you have an edge going from vertex 1 to 2, so there is a 1 at the index [1][2] of adjacency matrix, similar is the case with [1][3] and so on.
And you don't have any edge going from 1 to 5, so there is a 0 at index [1][5], and so on.
You can also use Adjacency List, now go ahead and google it to have some understanding of how to use Adjacency Matrices and Adjacency Lists, and come back with some real problem then.
EDIT
I see, you don't have any understanding of how to implement a graph, let me write some examples for you using Adjacency Matrix.
I'm assuming that you know how to allocate a 2D array in c++.
Now, if you want to create an adjacency matrix for a graph containing n vertices, simply create a 2D array of size n x n and initialize all of the elements in it with 0.
int** createAdjacencyMatrix(int n){
int** graph = new int*[n];
for (int i = 0; i < n; i++){
graph[i] = new int[n];
for (int j = 0; j < n; j++){
graph[i][j] = 0;
}
}
return graph;
}
There you go, call this function, and you've created yourself an Adjacency Matrix.
int** graph = createAdjacencyMatrix(5);
Now, you can do whatever you want to do with your graph (For now, it doesn't have any edges).
To have edges in it, simply place 1 wherever you want to put an edge.
void putEdge(int** graph, int startFrom, int endAt, int totalVertices){
if (startFrom >= 1 && startFrom <= totalVertices && endAt >= 1 && endAt <= totalVertices){
graph[startFrom - 1][endAt - 1] = 1; // Because c++ uses 0 based indexing, so 1 will be stored at 0, 2 at 1 and so on.
}
}
Now, simply call this function, and add some edges to your graph.
So i'm gonna put some edges and create the above shown graph in it.
putEdge(graph, 1, 2, 5);
putEdge(graph, 1, 3, 5);
putEdge(graph, 1, 4, 5);
putEdge(graph, 2, 3, 5);
putEdge(graph, 3, 2, 5);
putEdge(graph, 5, 2, 5);
putEdge(graph, 4, 4, 5);
Now, you can do whatever you want with your graph, like should we calculate how many outgoing edges vertex 1 has?
For this, you can simply loop through the row 1
int noOfOutgoingEdges(int** graph, int vetex, int totalVertices){
if (vertex < 1 || vertex > totalVertices)
return -1;
int count = 0;
for (int i = 0; i < totalVertices; i++){
if (graph[vertex - 1][i] == 1)
count++;
}
return count;
}
At the end, you should de-allocate the allocated memory for adjacency graph.
void deallocateGraph(int** graph, int totalVertices){
for (int i = 0; i < totalVertices; i++)
delete[] graph[i];
delete[] graph;
}
So, i think by now, you'd have much better understanding.
I've implemented the graph with using just the functions, and passing adjacency matrix to them (my bad), I strongly recommend to implement the Graph in a class, which handles all of the Graph stuff itself, and you don't have to pass adjacency matrix to it, you shouldn't even have to know whether the Graph class is implemented using Adjacency Matrix or some other method (of course when using the class, not implementing it)
You class should be like this:
class Graph{
int** adjMatrix;
int totalVertices;
public:
Graph(int totalVertices);
void putEdge(int startFrom, int endAt);
int noOfOutgoingEdges(int vertex);
int noOfIncomingEdges(int vertex);
~Graph();
};
Now, go ahead and implement this class and add whatever functions you want in there.
Use proper abstraction level. You want to represent each node as an int with a set of neightbours ?
map<int, set<int>> neighbours {
{ 1, { 2, 3, 4} },
{ 2, { 3 }},
{ 3, { 2 }},
{ 4, { 4 }},
{ 5, { 2 }}
};
Related
In our semester project we're attempting to make a small car which can search an area for metal in the ground. Each time it encounters an object in the ground, it has to mark down the coordinates for it, and find a path around it to visit all remaining nodes.
We've implemented a way in which we can get the area noted down in a grid, so we have it all in a x-y coordinate. We've considered using a modified version of a pathfinding algorithm (breadth-first, A* or other) to find our way through the system, but we're having trouble with the implementation of it.
Is it possible to modify any of these algorithms so instead of going from node A to B, it searches each coordinate, and "re-paths" if it encounters an object in the ground?
Logic
So first, we check all the squares if they contain metal. Then we store the squares with metal in a boolean grid.
Pseudo-Code
bool grid[10000][10000];
for (int i = 0; i < width; i++){
for(int j = 0; j < height; j++){
if (square is metal){
grid[i][j] = true; //means its visited.
}
}
}
//Conduct bfs here
typedef pair<int , int> pi; //introduce priority queues
typedef pair<pi, int> ppi;
int dx[8] = {-1,-2, 1 ,2 ,-1, -2, 1, 2};//introduce movement coordinates
int dy[8] = {-2,-1, -2,-1, 2, 1, 2, 1};
//Check if the coordinates of the grid is true(visited) or false(unvisited)
Hope this helps.
I am currently working on a 15 puzzle programming assignment. My question here is about how I would go about swapping the empty tile with an adjacent tile.
So, for example, let's go with the initial setup board.
I have:
int originalBoard[4][4] = {
{1 , 2, 3, 4},
{5 , 6, 7, 8},
{9 ,10,11,12},
{13,14,15, 0}};
So here, the locations of 12, 15, and 0 (the empty tile) in the array are [3][4], [4][3], and [4][4] respectively. What would be a method of swapping 0 out with either 12 or 15?
What I had in mind for this was creating a loop that would keep track of the empty tile every time I made a move.
I believe an optimal method would be to have two functions. 1 that would update the location of the empty tile, and 1 to make the move.
So, right off the top of my head I would have:
void locateEmptyTile(int& blankRow, int& blankColumn, int originalBoard[4][4])
{
for (int row = 0; row < 4; row++)
{
for (int col = 0; col < 4; col++)
{
if (originalBoard[row][col] == 0)
{
blankRow = row;
blankColumn = col;
}
}
}
}
void move(int& blankRow, int& blankColumn, int originalBoard[4][4])
{
}
And in my main function I would have the variables: int blankRow and int blankColumn
Now, how would I take that data from locateEmptyTile and apply it into the move function in the relevant practical manner? The process does not currently connect within my head.
I appreciate any little bits of help.
If you're just asking for swap function you can use std::swap:
#include <algorithm> // until c++11
#include <utility> // since c++11
...
int m[3][3];
...
//somewhere in the code
std::swap(m[i][j], m[j][i]); // this swaps contents of two matrix cells
...
Or you can just write where you want to swap contents of two variables (in example int a and int b):
int temp = a;
a = b;
b = temp;
As you can see swapping is the same as with normal arrays, c++ does not know if you are swapping two matrix cells or two array elements, it just knows that you are swapping two memory blocks with certain type.
A basic swap concept (pre-C++11) is hold a temporary variable. Simply...
template<typename T, typename U>
void swap(T& lhs, U& rhs) {
T t = lhs;
lhs = rhs;
rhs = t;
}
So, you don't need to reference blankRow and blankCol, you just need to reference the values on the grid. Lets say that you want to swap what you know is blank positioned at (2, 1) with (2, 2)...
swap(originalBoard[2][1], originalBoard[2][2]);
... will swap the values within originalBoard.
If you are using C++11 or later, just use std::swap() to swap positions. That's exactly what it does.
If you would like originalBoard to be immutable an result in a totally different board, just copy it first before applying the switch.
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 6 years ago.
Improve this question
A recursive puzzle You have been given a puzzle consisting of a row of squares each containing an integer, like this
The circle on the initial square is a marker that can move to other squares along the row. At each step in the puzzle, you may move the marker the number of squares indicated by the integer in the square it currently occupies. The marker may move either left or right along the row but may not move past either end. For example, the only legal first move is to move the marker three squares to the right because there is no room to move three spaces to the left. The goal of the puzzle is to move the marker to the 0 at the far end of the row. In this configuration, you can solve the puzzle by making the following set of moves:
https://i.stack.imgur.com/yUz3P.png
a. Write an algorithm void SolvePuzzle(int start, int squares[1..n]) that takes a starting position of the marker along with the array of squares. The algorithm should solve the puzzle from the starting configuration and display all moves required to reach the 0 at the end of the sequence. You may assume all the integers in the array are positive except for the last entry, the goal square, which is always zero. The values of the elements in the array must be the same after calling your function as they are beforehand, (which is to say if you change them during processing, you need to change them back!)
void SolvePuzzle(int start, int squares[]){
if(squares[start]==0)
return;
else{
cout<<squares[start]<<" ";
if(squares[start]%2==0)
SolvePuzzle( start+squares[start],squares);
else
SolvePuzzle( start-squares[start],squares);
}
}
int main(){
int arraytest[] = { 3, 6, 4, 1, 3, 4, 2, 5, 3, 0 };
SolvePuzzle(arraytest[0],arraytest);
return 0;
}
i solved like this but i need Correct mistakes in If statement
The problem you are facing, even if one could not really tell from your description, is that you don't really know if you have to move left or right to solve the puzzle.
The simplest approach is just try to go left, if it works you solved it, otherwise you go right. This means that you have to change your function, otherwise you cannot really return the right path or the answer.
It may appear like this:
#include <vector>
#include <iostream>
bool SolvePuzzle(int squares[], int size, int position,
std::vector<bool>& go_right_sol){
if(squares[position]==0){
return true;
}
int leftPos = position - squares[position];
int rightPos = position + squares[position];
if(rightPos < size && SolvePuzzle(squares, size, rightPos, go_right_sol)){
go_right_sol.insert(go_right_sol.begin(), true);
return true;
}
if(leftPos > 0 && SolvePuzzle(squares, size, leftPos, go_right_sol)){
go_right_sol.insert(go_right_sol.begin(), false);
return true;
}
return false;
}
int main(){
int arraytest[] = { 3, 6, 4, 1, 3, 4, 2, 5, 3, 0 };
int arraysize = 10;
std::vector<bool> solution;
SolvePuzzle(arraytest, arraysize, 0, solution);
for(int i = 0; i < solution.size(); i++){
std::cout << ((solution[i]) ? "right" : "left") << " - ";
}
std::cout << std::endl;
return 0;
}
So, I have the following case:
I declared a vector of vector of integers as vector < vector<int> > edges. Basically, I am trying to implement a graph using the above where graph is defined as follows:
class graph
{
public:
int vertices;
vector < vector<int> > edges;
};
Now, during the insertion of an edge, I take input as the starting vertex and ending vertex. Now, I want to do something like this:
void insert(int a, int b, graph *mygraph) // a is starting vertex and b is ending vertex
{
auto it = mygraph->edges.begin();
//int v = 1;
vector<int> foo;
foo.push_back(b);
if (mygraph->edges[a].size() != 0) // Question here?
mygraph->edges[a].push_back(b);
else
mygraph->edges.push_back(foo);
return;
}
Now, in the line marked with Question here, basically, I want to check if the vector for that particular entry exists or not? size is actually wrong because I am trying to call size operation on a vector which doesn't exists. In other words, I want to check, if there is a vector which exists at a particular location in vector of vectors. How can I do it? Something like, mygraph->edges[a] != NULL?
Simply check that a does not exceed size of the vector. If it does, then resize the outer vector.
void insert(int a, int b, graph &mygraph) { // a is starting vertex and b is ending vertex
if (a >= mygraph.edges.size())
mygraph.edges.resize(a+1);
mygraph.edges[a].push_back(b);
}
You can approach your problem in two different ways:
Initialize edges to the number of vertices, and don't allow other vertices to be inserted after that. Why is that?
std::vector< std::vector<int> > v = { {1}, {2} };
// now you need to add an edge between vertex 4 and vertex 5
std::vector<int> edges3;
v.push_back(edges3); // v = { {1}, {2}, {} }
std::vector<int> edges4 = {5};
v.push_back(edges4); // v = { {1}, {2}, {}, {5} }
If you don't want to do it like that, you'd have to do something like this first:
std::vector< std::vector<int> > v;
for (int i = 0; i < maxVertices; i++)
{
std::vector<int> w;
v.push_back(w);
}
// now you need to add an edge between vertex 4 and vertex 5
v[4].push_back(5);
Change the structure used for edges, probably to something better suited for sparse matrices (which looks like your case here, since probably not every vertex is connected to every other vertex). Try:
std::map< int, std::vector<int> > edges;
That way you can match a single vertex with a list of other vertices without the need to initialize edges to the maximum possible number of vertices.
std::vector<int> vertices = {5};
edges[4] = vertices;
Edges is a vector of vectors. Vectors are stored contiguously in memory. You insert elements into a vector from the end. If the size of vector is 10, all 10 members are contiguous and their indexes are going to range from 0-9. If you delete a middle vector, say 5th, all vectors from index 6-9 get shifted up by 1.
The point of saying all this is that you can't have a situation where edges would have an index that doesn't hold a vector. To answer your question, a vector for index a would exist if
a < mygraph->edges.size ();
I am trying to implement the Breadth-first search algorithm, in order to find the shortest distance between two vertices. I have developed a Queue object to hold and retrieve objects, and I have a two-dimensional array to hold the length of the edges between two given vertices. I am attempting to fill a two-dimensional array to hold the shortest distance between two vertices.
The problem I am having, however, is that no matter what two vertices I request the shortest distance of, 0 is returned. Here is my implementation of the algorithm; if you can set me on the right track and help me figure out my problem, that would be fantastic.
for (int i = 0; i < number_of_vertex; i++)
//For every vertex, so that we may fill the array
{
int[] dist = new int[number_of_vertex];
//Initialize a new array to hold the values for the distances
for (int j = 0; x < number_of_vertex; j++)
{
dist[j] = -1;
//All distance values will be set to -1 by default; this will be changed later on
}
dist[i] = 0; //The source node's distance is set to 0 (Pseudocode line 4)
myQueue.add(i); //Add the source node's number to the queue (Pseudocode line 3)
while (!myQueue.empty()) //Pseudocode line 5
{
int u = myQueue.eject(); //Pseudocode line 6
for (int y = 0; y < number_of_vertex; y++) //Pseudocode line 7
{
if (edge_distance(u,y) > 0)
{
if (dist[y] == -1)
{
myQueue.add(y);
dist[y] = dist[u] + 1;
shortest_distance[i][u] = dist[y];
}
}
}
}
}
Ok... i guess the problem is about the used algorithm and about used terms.
"In order to find the shortest distance between two vertices" you mean the shortest path between two vertices in a connected graph?
The algorithm you are trying to write is the Dijkstra's algorithm (this is the name).
http://www.cs.berkeley.edu/~vazirani/algorithms/chap4.pdf