About matrix of edge in graph using c++ - c++

I confuse how to define the program that will find the matrix of edge in a graph.
The problem is if one inputs the value of adjacency matrix that give information about connection of vertices in a graph, example : there are 3 vertices, then V1 connected to V2 but not with V3, then V2 connected to V3, it gives :
0 1 0
1 0 1
0 1 0
now, with that information, I want to make the program which find the connection of edge to edge, example there are 3 edges : 1-2 edge, 2-3 edge, and its output is :
0 1
1 0
I know to make the first output "Adjacency matrix", but the second.
Thanks in advance.

An adjacency matrix is used to represent a graph which means you have both vertices and edges in it. So if the input is :
0 1 1
1 0 1
1 1 0
It means your graph is complete. If you read it with putting numbers on your matrix:
X 1 2 3
1 0 1 1
2 1 0 1
3 1 1 0
You can see that:
V1 connects to V2 and V3
V2 connects to V1 and V3
V3 connects to V1 and V2
By reading row n you see which vertice Vn connects to and by reading column n you can see which vertices are connected to Vn.
In your example, your graph is non-oriented because your matrix is diagonal.
If your aim is to find what are the edges of your graph, you already have the information in the adjacency matrix. If you want to see what vertices are "double connected" you need to find if for vertices Vi and Vj the M[i][j] and the M[j][i] members of your matrix both have the value 1 (It is always the case in non-oriented graph). A possible algorithm for that is just a double loop on your matrix representation (generally two vectors/lists/arrays).

Related

CGAL read_OFF discards face depending on vertex order

When reading an off-file with cgal it appears that the vertex order of a face decides whether or not it is read in by read_OFF. But the off-file definition does not say anything about the vertex order of a face.
I am reading in self generated off-files using the read_OFF method of cgal:
using Kernel = CGAL::Exact_predicates_inexact_constructions_kernel;
using Point_3 = typename Kernel::Point_3;
...
CGAL::Surface_mesh<Point_3> test_mash;
CGAL::IO::read_OFF(file_name, test_mash);
std::cout << "Number of vertices: " << test_mash.vertices().size()
<< ", Number of faces: " << test_mash.faces().size() << std::endl;
two_faces_read.off:
OFF
4 2 0
1 1 1
2 -2 2
3 3 -3
-4 4 4
3 0 1 2
3 0 3 1
one_face_read.off:
OFF
4 2 0
1 1 1
2 -2 2
3 3 -3
-4 4 4
3 0 1 2
3 0 1 3
Reading two_faces_read.off works as expected, printing:
Number of vertices: 4, Number of faces: 2.
But when i read one_face_read.off i get Number of vertices: 4, Number of faces: 1. The only difference between these two files is the last line, the vertex order of the second face is different. After trying all possible combinations it seems that with 031, 103, 310 2 faces are read in, while with 013, 130, 301 only 1 face is read in.
The off-file specification referenced by cgal does not mention any rules concerning the vertex order of a face.
Why does this happen and how can i ensure that all faces are read in?
one_face_read.off does not define a valid surface mesh has the orientation of the two faces are not compatible. You can use the following function to read points and faces and call CGAL::Polygon_mesh_processing::is_polygon_soup_a_polygon_mesh() to check if the input is a valid surface mesh. The function CGAL::Polygon_mesh_processing::orient_polygon_soup() can be used to fix orientations. CGAL::Polygon_mesh_processing::polygon_soup_to_polygon_mesh() can be used to create the mesh.

Create random adjacency matrix with each node having a minimum degree of 'k'

I want to create a random adjacency matrix where each node is connected to 'k' other nodes. The graph represented by the adjacency matrix is undirected.
I started with 7 nodes in the adjacency matrix and each node is supposed to be connected to at least to 3 other nodes. So far I have been able to get this:
0 1 1 0 0 0 0
1 0 1 1 0 0 0
1 1 0 1 1 0 0
0 1 1 0 1 1 0
0 0 1 1 0 1 1
0 0 0 1 1 0 1
0 0 0 0 1 1 0
As can be seen from the matrix, the first and last row have less than three connections.
My implementation so far is:
for( int i= 0; i<7; i++){
for( int j= i+1; j<7; j++){
if(i==j){
topo[i][j]=0;
}
else{
for(int k=j; k<i+3 && k<7; k++){
int connectivity=0;
while(connectivity<3){
if(topo[i][k]!=1 && topo[k][i]!=1){
topo[i][k]=1;
topo[k][i]=1;
connectivity++;
}
else{
connectivity++;
}
}
}
}
}
}
I assume we are talking about directed graphs here.
Lets assume that v is a number of vertexes (nodes) and d of vertex A (degree, Your k) is a number of edges that are drown from A to other nodes.
If You look closer You can find out, that d value of k-th node is a number of 1 in kth row. So the only thing to do is to draw vector of 0s and 1s with v-1 (we don't connect node with itself) elements for each row.
You can draw random vector of zeros and ones by writing d ones to it and randomly permuting it.
Note for undirected graph - You can adopt this algorithm to upper-right matrix triangle, dynamically rewriting known values to lower-left one. Than for each row from up to down You can adopt algorithm, that draws rest of a raw.

Number of non zeros elements in Eigen sparse matrix after - binary operator not changing

SparseMatrix<int,RowMajor> sm(3,3),sm1;
sm.insert(0,0)=1;
sm.insert(1,1)=1;
sm.insert(2,2)=1;
sm.insert(1,2)=1;
sm.insert(2,1)=1;
SparseMatrix<int,RowMajor> I(3,3);
I.insert(0,0)=1;
I.insert(1,1)=1;
I.insert(2,2)=1;
cout<<"SM matrix \n"<<sm<<endl;
sm1=sm-I;
cout<<"SM1 Matrix"<<sm1<<endl;
cout<<"the number of nonzeros\n"<<sm1.nonZeros()<<endl;
Output
SM matrix
Nonzero entries:
(1,0) (_,_) (1,1) (1,2) (1,1) (1,2)
Outer pointers:
0 2 4 $
Inner non zeros:
1 2 2 $
1 0 0
0 1 1
0 1 1
SM1 MatrixNonzero entries:
(0,0) (0,1) (1,2) (1,1) (0,2)
Outer pointers:
0 1 3 $
0 0 0
0 0 1 `
0 1 0
the number of nonzeros
5
sm1.nonZeros() does not look at the values of the matrix, rather it returns the size of the inner array that was allocated to store values:
/** \returns the number of non zero coefficients */
inline Index nonZeros() const
{
if(m_innerNonZeros)
return innerNonZeros().sum();
return static_cast<Index>(m_data.size());
}
If you were to look at that array in a debugger or by accessing it via sm1.valuePtr() you would see something like this:
sm1.m_data.m_values == {0, 0, 1, 1, 0}
If it were a dense matrix, you could do something like (m1.array() != 0).count(), but that doesn't work with the sparse module. A workaround would be to use a map as follows:
cout<<"the number of nonzeros with comparison: \n"
<< (Eigen::Map<Eigen::VectorXi> (sm1.valuePtr(), sm1.nonZeros()).array() != 0).count()
<< endl;
which actually compares each value to 0 and outputs the correct answer.
If you're sure that you won't be adding modifying the newly zeroed values, you can prune the sparse matrix:
sm1.prune(1);
cout<<"the number of pruned nonzeros\n"<<sm1.nonZeros()<<endl;
This first removes the values below the threshold (1 in this case) and the data array looks like:
sm1.m_data.m_values == {1, 1}

Explore a matrix using Chebyshev distance

What is the fastest way of exploring an array from a point (i,j) , using Chebysev distance?
My aproach:
I am currently defining 2 one dimensional arrays that store the directions for the start then compute with a For what is left when radius > 1 ( radius is the "radius" of the chebysev circle I wanna explore the array) . I am finding I am exploring some elements twice . Is there an algorithm that shows what is the best aproach ?
Be 0 the distance between (i,j) and himself . I would want the matrix to be explored like this ( the numbers represent the distance between i,j and them). Ofcourse i,j is not always it the middle , it must be any point I choose .
2 2 2 2 2
2 1 1 1 2
2 1 0 1 2
2 1 1 1 2
2 2 2 2 2
Thank you and excuse my english :)
You can use the BFS algorithm. It is just a simple loop with a queue.
Your "edges" on are links between the position (i, j) and its 8 neighbors:
(i-1,j)
(i-1,j-1)
...
(i+1,j+1)

algorithm transfer one coin matrix to another coin matrix

Description:
There are m * n (m <= 100, n <=100) coins on the desktop forming a m row n column coin matrix. Every coin either face upward, or face backward, represented by 0 or 1.
Rules of the game are:
(1) every time, you are allowed to inverse one row of coins.
(2) every time, you are allowed to swap two columns.
Object:
from initial matrix -> target matrix
Input:
1. k the count of test caese
2. m n the count of rows and columns
3. the numbers of the inital matrix and the target matrix
Output
the least steps from initial matrix to target matrix, if it is not possible to transfer from initial to target, output -1.
sample intput
2
4 3
1 0 1
0 0 0
1 1 0
1 0 1
1 0 1
1 1 1
0 1 1
1 0 1
4 3
1 0 1
0 0 0
1 0 0
1 1 1
1 1 0
1 1 1
0 1 1
1 0 1
sample output
2
-1
I have coded one solution: mysolution.cc, which enumerate all posibilities and which is correct but it is too slow, could you provide a correct but fast solution.
Thanks.
The rows always stay in the same place, so if row r starts with k ones, it will always have either k ones or columns - k.
for each row, check if count_of_ones(initial,row) == count_of_ones(target,row), if yes, fine, else check if count_of_ones(initial,row) = columns - count_of_ones(target,row), if so, flip row, else output -1. As #maniek pointed out, it's not so easy when exactly half of the columns contain ones. Such rows would have to be treated in step 2 to try and form the required columns.
for each column, count the number of ones int the target and the working matrix (after flipping rows as appropriate). If the sequences of counts are not permutations of each other, output -1, otherwise try to find a permutation of columns that transforms working to target (any columns identical between working and target have to be kept fixed). If not possible, output -1, otherwise find minimum number of swaps necessary to achieve that permutation.
I will give you some thoughts. You compare row by row. If the i-th row of the first matrix has the same number of 1 as in the i-th row of the second matrix - then you don't inverse. If the i-th row of the first matrix has the same number of 1 as the 0 in the i-th row of the second matrix - then you must inverse. If neither of this is true, then there is no solution. This is all about inversing.
Now all columns are equal but in a different order(the second matrix has permuted columns from the first matrix). If the columns are not permutation of each other - return -1. This problem is equal to find the minimum number of swaps to convert a one permutation to other.