Implementation of Adjacent Matrix with 2D vectors c++ - c++

I am a beginner in c++ and I have worked on vectors just not on 2D vectors. I have surfed a lot, but data on internet is very specific related to 2D vectors.
I need to build a graph given an input file and then apply Kruskal's algorithm for minimum spanning tree.
My approach:
A1, A2, A3.....An would be the first row and col of my 2d Vectors and they will
contain name. I will read the input file and start matching the names.
And then at graph[i][j] I will put the weight.
A1 A2 A3......
A1 w w w .......
A2 w w w .......
A3 w w w .......
.
.
.
.
Now I am trying something like this:
struct mat{
string name;
}
int main(){
vector<vector<mat>> matrix;
// In order to insert
vector<mat> tempVec;
tempVec[0].name = "stack";
matrix.push_back(tempVec);
}
Now I have no idea that when I do tempVec[0].name, 0 indicates which row or col of Matrix. If it indicates row then how do I know which col is being accessed.
I mean vector.push_back(tempVec), assigns which position in my Matrix to data. I know I can access individual elements like Matrix[i][j]. But How can I assign weight to a particular row, col position and then access it.
Further do you think will be a good implementation for Kruskal's Method.
Please be simple in your code and explanatory.
And thanks in advance.

Using vector<vector<T>> is a fairly suboptimal way to represent matrices, even though it is often used. It would be better to make a one-dimensional vector<T> of size rows x cols. You can then index it as follows (assuming you follow C-style row major ordering):
vector<mat> matrix(rows*cols);
...
element_ij=matrix[i*cols+j];
In your current code, you never insert anything into matrix:
vector<vector<mat>> matrix;
// In order to insert
vector<mat> tempVec;
tempVec[0].name = "stack";
vector.push_back(tempVec);
I assume the last line should be matrix.push_back(tempVec);.

Related

How to generate a 100x6 matrix with different values in each column in C++

I'm a newbie programmer, almost zero experience with C++, in order to translate MATLAB code manually I need to generate a 100x6 matrix. According to what I investigated so far, I should use std::vector (vector of vectors). The problem is I don't know how to add values to the matrix in this way:
100 rows, then each column should have these values:
column 1: sin(2*pi*0.05)
column 2: cos(2*pi*0.05)
column 3: sin(4*pi*0.05)
column 4: cos(4*pi*0.05)
column 5: sin(6*pi*0.05)
column 6: cos(6*pi*0.05)
I've only found very basic examples with std:vector and nested for loops which I fail to adapt to this particular problem. Can someone give me a hint of how to solve this problem?.
std::vector<std::vector<double>> matrix;
matrix.resize(100);
for (auto & line : matrix) {
line.resize(6);
}
And then you can do:
matrix[x1][y1] = someValue;
otherValue = matrix[x2][y2];
etc.
But, if you know you will have a fixed size for your matrix, you can just do:
double matrix[100][6] = { 0.0 };
instead of creating the vectors.

How to drop rows of an SpMat<unsigned int> in Armadillo based on a condition on row totals?

Is there an efficient approach to only retain rows of an Armadillo sparse matrix that sum up to at least some level of total count across columns of the matrix? For instance, I would want to retain the ith row, if the sum of its values is >=C, where C is some chosen value. Armadillo's documentation says that only contiguous submatrix views are allowed with sparse matrices. So I am guessing this is not easily obtainable by sub-setting. Is there an alternative to plainly looping through elements and creating a new sparse matrix with new locations, values and colPtr settings that match the desired condition? Thanks!
It may well be that the fastest executing solution is the one you propose. If you want to take advantage of high-level armadillo functionality (i.e. faster to code but perhaps slower to run) you can build a std::vector of "bad" rows ids and then use shed_row(id). Take care with the indexing when shedding rows. This is accomplished here by always shedding from the bottom of the matrix.
auto mat = arma::sp_mat(rowind, colptr, values, n_rows, n_cols)
auto threshold_value = 0.01 * arma::accu(sp_mat); // Sum of all elements
std::vector<arma::uword> bad_ids; // The rows that we want to shed
auto row_sums = arma::sum(mat); // Row sums
// Iterate over rows in reverse order.
for (const arma::uword row_id = mat.nrows; i-- > 0; ) {
if (row_sum(row_id) < threshold_value) {
bad_ids.push_back(row_id);
}
}
// Shed the bad rows from the bottom of the matrix and up.
for (const auto &bad_id : bad_ids) {
matrix.shed_row(bad_id);
}

How to create a grid in C++ that will allow me to set each index as a vector to later manipulate that vector and then plot it?

I am doing a project for a class where I have to find the 5 Lagrange points of 2 bodies in space. This project is supposed to be an exercise in root-finding but I am having trouble coming up with a plan for the grid part of this project.
I don't know what the best approach is to building some sort of grid and then have each cell in that grid contain 2 data points, an x direction and magnitude and a y direction and magnitude.
I then want to use these values and plot a vector from it. i.e if there was a cell at (x,y)=(-5,0) with the values (0,-2) it would be to the left of the origin 5 spaces and point straight down 2 spaces.
I am not looking for someone to write my code here I just need some help with how I would go about doing this.
One way is to use std::pair<int, int> to represent a point.
Default std::pair operator= should handle comparison properly for int.
Say each point has a raw value in double. The code may look like
typedef std::pair<int, int> Point;
std::map<Point, double> raw_data;
for (int row = -5; row <= 5; ++row) {
for (int col = -5; col <= 5; ++col) {
raw_data.emplace(Point(row, col), 10000000);
}
}
std::cout << raw_data.at(Point(3, 2)) << std::endl;

Read in a matrix and build a graph

I have a rectangular room; its' floor is coverd with floor boards, some of them are broken.
The dimensions of the room are N and M: 1 <=N,M<=300.
I read N and M from stdin, and then I read N strings of length M, which look like this:
..**.***....*.**...**.***
.**......**...***..***...
and so on, where . is a good floor board and * is a broken one.
I intend to replace the broken floor boards with new one, and I only have two types of those: two-by-ones and one-by-ones. I can't cut the two-by-ones into two one-by-ones.
To find a way to do this, I paint the floor like a checkerboard, so that the halves of a broken two-by-one are of different color.
Then I mean to build a bipartite graph (consisting of a white and a black part) from the resulting matrix, and I'd like to build and analyse it with this code.
What's the best way to do that?
I think that I shouldn't keep all the matrix in memory (since it can be rather large). Ideally I should be able to read in strings and update the graph on the run.
EDIT:
My code should like this:
int main()
{
int N, M;
std::cin >> N;
assert (( N >=1) && (N <=300));
std::cin >> M;
assert (( M >=1) && (M <=300));
for (int i = 0; i < N; ++i)
std::cin >> // that's where I have to read the string
//...and the next string
// use these 2 strings to update a graph
// with prGraph.AddEdge()
return 0;
}
If it is really so important not to store the entire matrix in memory, you can read it line by line and store only the current and the previous line because it is sufficient to construct a graph properly.
A naive graph construction using an adjacency matrix would take 300x300 ^2, which is tough to fit in memory.
You can take advantage of the fact that each vertex can have at most 4 edges - you would only need space on order of 300 x 300 x 4 using adjacency lists for your maxflow instead, as long as you change the graph traversal accordingly.

How to auto-generate and assign variables corresponding to elements in a matrix?

I am working on a binary linear program problem.
I am not really familiar with any computer language(just learned Java and C++ for a few months), but I may have to use computer anyway since the problem is quite complicated.
The first step is to declare variables m_ij for every entry in (at least 8 X 8) a matrix M.
Then I assign corresponding values of each element of a matrix to each of these variables.
The next is to generate other sets of variables, x_ij1, x_ij2, x_ij3, x_ij4, and x_ij5, whenever the value of m_ij is not 0.
The value of x_ijk variable is either 0 or 1, and I do not have to assign values for x_ijk variables.
Probably the simplest way to do it is to declare and assign a value to each variable, e.g.
int* m_11 = 5, int* m_12 = 2, int* m_13 = 0, ... int* m_1n = 1
int* m_21 = 3, int* m_12 = 1, int* m_13 = 2, ... int* m_2n = 3
and then pick variables, the value of which is not 0, and declare x_ij1 ~ x_ij5 accordingly.
But this might be too much work, especially since I am going to consider many different matrices for this problem.
Is there any way to do this automatically?
I know a little bit of Java and C++, and I am considering using lp_solve package in C++(to solve binary integer linear program problem), but I am willing to use any other language or program if I could do this easily.
I am sure there must be some way to do this(probably using loops, I guess?), and this is a very simple task, but I just don't know about it because I do not have much programming language.
One of my cohort wrote a program for generating a random matrix satisfying some condition we need, so if I could use that matrix as my input, it might be ideal, but just any way to do this would be okay as of now.
Say, if there is a way to do it with MS excel, like putting matrix entries to the cells in an excel file, and import it to C++ and automatically generate variables and assign values to them, then this would simplify the task by a great deal!
Matlab indeed seems very suitable for the task. Though the example offered by #Dr_Sam will indeed create the matrices on the fly, I would recommend you to initialize them before you assign the values. This way your code still ends up with the right variable if something with the same name already existed in the workspace and also your variable will always have the expected size.
Assuming you want to define a square 8x8 matrix:
m = zeros(8)
Now in general, if you want to initialize a three dimensional matrixh of size imax,jmax,kmax:
imax = 8;
jmax = 8;
kmax = 5;
x = zeros(imax,jmax,kmax);
Now assigning to or reading from these matrices is very easy, note that length and with of m have been chosen the same as the first dimensions of x:
m(3,4) = 4; %Assign a value
myvalue = m(3,4) %read the value
m(:,1) = 1:8 *Assign the values 1 through 8 to the first column
x(2,4,5) = 12; %Assign a single value to the three dimensional matrix
x(:,:,2) = m+1; Assign the entire matrix plus one to one of the planes in x.
In C++ you could use a std::vector of vectors, like
std::vector<std::vector<int>> matrix;
You don't need to use separate variables for the matrix values, why would you when you have the matrix?
I don't understand the reason you need to get all values where you evaluate true or false. Instead just put directly into a std::vector the coordinates where your condition evaluates to true:
std::vector<std::pair<int, int> true_values;
for (int i = 0; i < matrix.size(); i++)
{
for (int j = 0; j < matrix[i].size(); j++)
{
if (some_condition_for_this_matrix_value(matrix[i][j], i, j) == true)
true_values.emplace_back(std::make_pair(i, j));
}
}
Now you have a vector of all matrix coordinates where your condition is true.
If you really want to have both true and false values, you could use a std::unordered_map with a std::pair containing the matrix coordinates as key and bool as value:
// Create a type alias, as this type will be used multiple times
typedef std::map<std::pair<int, int>, bool> bool_map_type;
bool_map_type bool_map;
Insert into this map all values from the matrix, with the coordinates of the matrix as the key, and the map value as true or false depending on whatever condition you have.
To get a list of all entries from the bool_map you can remove any false entries with std::remove_if:
std::remove_if(bool_map.begin(), bool_map.end(),
[](const bool_map_type::value_type& value) {
return value.second == false;
};
Now you have a map containing only entries with their value as true. Iterate over this map to get the coordinates to the matrix
Of course, I may totally have misunderstood your problem, in which case you of course are free to disregard this answer. :)
I know both C++ and Matlab (not Python) and in your case, I would really go for Matlab because it's way easier to use when you start programming (but don't forget to come back to C++ when you will find the limitations to Matlab).
In Matlab, you can define matrices very easily: just type the name of the matrix and the index you want to set:
m(1,1) = 1
m(2,2) = 1
gives you a 2x2 identity matrix (indices start with 1 in Matlab and entries are 0 by default). You can also define 3d matrices the same way:
x(1,2,3) = 2
For the import from Excel, it is possible if you save your excel file in CSV format, you can use the function dlmread to read it in Matlab. You could also try later to implement your algorithm directly in Matlab.
Finally, if you want to solve your binary integer programm, there is already a built-in function in Matlab, called bintprog which can solve it for you.
Hope it helps!