I'm trying to transpose a sparse matrix in c++. I'm struggling with the traversal of the new transposed matrix. I want to enter everything from the first row of the matrix to the first column of the new matrix.
Each row has the column index the number should be in and the number itself.
Input:
colInd num colInd num colInd num
Input:
1 1 2 2 3 3
1 4 2 5 3 6
1 7 2 8 3 9
Output:
1 1 2 4 3 7
1 2 2 5 3 8
1 3 2 6 3 9
How do I make the list traverse down the first column inserting the first element as it goes then go back to the top inserting down the second column. Apologies if this is two hard to follow. But all I want help with is traversing the Transposed matrix to be in the right place at the right time inserting a nz(non zero) object in the right place.
Here is my code
list<singleRow> tran;
//Finshed reading so transpose
for (int i = 0; i < rows.size(); i++){ // Initialize transposed matrix
singleRow trow;
tran.push_back(trow);
}
list<singleRow>::const_iterator rit;
list<singleRow>::const_iterator trowit;
int rowind;
for (rit = rows.begin(), rowind = 1; rit != rows.end(); rit++, rowind++){//rit = row iterator
singleRow row = *rit;
singleRow::const_iterator nzit;
trowit = tran.begin(); //Start at the beginning of the list of rows
trow = *trowit;
for (nzit = row.begin(); nzit != row.end(); nzit++){//nzit = non zero iterator
int col = nzit->getCol();
double val = nzit->getVal();
trow.push_back(nz(rowind,val)); //How do I attach this to tran so that it goes in the right place?
trowit++;
}
}
Your representation of the matrix is inefficient: it doesn't use the fact that the matrix is sparse. I say so because it includes all the rows of the matrix, even if most of them are zero (empty), like it usually happens with sparse matrices.
Your representation is also hard to work with. So i suggest converting the representation first (to a regular 2-D array), transposing the matrix, and convert back.
(Edited:)
Alternatively, you can change the representation, for example, like this:
Input: rowInd colInd num
1 1 1
1 2 2
1 2 3
2 1 4
2 2 5
2 3 6
3 1 7
3 2 8
3 3 9
Output:
1 1 1
2 1 2
3 1 3
1 2 4
2 2 5
3 2 6
1 3 7
2 3 8
3 3 9
The code would be something like this:
struct singleElement {int row, col; double val;};
list<singleElement> matrix_input, matrix_output;
...
// Read input matrix from file or some such
list<singleElement>::const_iterator i;
for (i = matrix_input.begin(); i != matrix_input.end(); ++i)
{
singleElement e = *i;
std::swap(e.row, e.col);
matrix_output.push_back(e);
}
Your choice of list-of-list representation for a sparse matrix is poor for transposition. Sometimes, when considering algorithms and data structures, the best thing to do is to take the hit for transforming your data structure into one better suited for your algorithm than to mangle your algorithm to work with the wrong data structure.
In this case you could, for example, read your matrix into a coordinate list representation which would be very easy to transpose, then write into whatever representation you like. If space is a challenge, then you might need to do this chunk by chunk, allocating new columns in your target representation 1 by 1 and deallocating columns in your old representation as you go.
Related
I need to construct a tree given its depth and postorder traversal, and then I need to generate the corresponding preorder traversal. Example:
Depth: 2 1 3 3 3 2 2 1 1 0
Postorder: 5 2 8 9 10 6 7 3 4 1
Preorder(output): 1 2 5 3 6 8 9 10 7 4
I've defined two arrays that contain the postorder sequence and depth. After that, I couldn't come up with an algorithm to solve it.
Here's my code:
int postorder[1000];
int depth[1000];
string postorder_nums;
getline(cin, postorder_nums);
istringstream token1(postorder_nums);
string tokenString1;
int idx1 = 0;
while (token1 >> tokenString1) {
postorder[idx1] = stoi(tokenString1);
idx1++;
}
string depth_nums;
getline(cin, depth_nums);
istringstream token2(depth_nums);
string tokenString2;
int idx2 = 0;
while (token2 >> tokenString2) {
depth[idx2] = stoi(tokenString2);
idx2++;
}
Tree tree(1);
You can do this actually without constructing a tree.
First note that if you reverse the postorder sequence, you get a kind of preorder sequence, but with the children visited in opposite order. So we'll use this fact and iterate over the given arrays from back to front, and we will also store values in the output from back to front. This way at least the order of siblings will come out right.
The first value we get from the input will thus always be the root value. Obviously we cannot store this value at the end of the output array, as it really should come first. But we will put this value on a stack until all other values have been processed. The same will happen for any value that is followed by a "deeper" value (again: we are processing the input in reversed order). But as soon as we find a value that is not deeper, we flush a part of the stack into the output array (also filling it up from back to front).
When all values have been processed, we just need to flush the remaining values from the stack into the output array.
Now, we can optimise our space usage here: as we fill the output array from the back, we have free space at its front to use as the stack space for this algorithm. This has as nice consequence that when we arrive at the end we don't need to flush the stack anymore, because it is already there in the output, with every value where it should be.
Here is the code for this algorithm where I did not include the input collection, which apparently you already have working:
// Input example
int depth[] = {2, 1, 3, 3, 3, 2, 2, 1, 1, 0};
int postorder[] = {5, 2, 8, 9, 10, 6, 7, 3, 4, 1};
// Number of values in the input
int n = sizeof(depth)/sizeof(int);
int preorder[n]; // This will contain the ouput
int j = n; // index where last value was stored in preorder
int stackSize = 0; // how many entries are used as stack in preorder
for (int i = n - 1; i >= 0; i--) {
while (depth[i] < stackSize) {
preorder[--j] = preorder[--stackSize]; // flush it
}
preorder[stackSize++] = postorder[i]; // stack it
}
// Output the result:
for (int i = 0; i < n; i++) {
std::cout << preorder[i] << " ";
}
std::cout << "\n";
This algorithm has an auxiliary space complexity of O(1) -- so not counting the memory needed for the input and the output -- and has a time complexity of O(n).
I won't give you the code, but some hints how to solve the problem.
First, for postorder graph processing you first visit the children, then print (process) the value of the node. So, the tree or subtree parent is the last thing that is processed in its (sub)tree. I replace 10 with 0 for better indentation:
2 1 3 3 3 2 2 1 1 0
--------------------
5 2 8 9 0 6 7 3 4 1
As explained above, node of depth 0, or the root, is the last one. Let's lower all other nodes 1 level down:
2 1 3 3 3 2 2 1 1 0
-------------------
1
5 2 8 9 0 6 7 3 4
Now identify all nodes of depth 1, and lower all that is not of depth 0 or 1:
2 1 3 3 3 2 2 1 1 0
-------------------
1
2 3 4
5 8 9 0 6 7
As you can see, (5,2) is in a subtree, (8,9,10,6,7,3) in another subtree, (4) is a single-node subtree. In other words, all that is to the left of 2 is its subtree, all to the right of 2 and to the left of 3 is in the subtree of 3, all between 3 and 4 is in the subtree of 4 (here: empty).
Now lets deal with depth 3 in a similar way:
2 1 3 3 3 2 2 1 1 0
-------------------
1
2 3 4
5 6 7
8 9 0
2 is the parent for 2;
6 is the parent for 8, 8, 10;
3 is ahe parent for 6,7;
or very explicitly:
2 1 3 3 3 2 2 1 1 0
-------------------
1
/ / /
2 3 4
/ / /
5 6 7
/ / /
8 9 0
This is how you can construct a tree from the data you have.
EDIT
Clearly, this problem can be solved easily by recursion. In each step you find the lowest depth, print the node, and call the same function recursively for each of its subtrees as its argument, where the subtree is defined by looking for current_depth + 1. If the depth is passed as another argument, it can save the necessity of computing the lowest depth.
We are given array-'a' and array-'b' consisting of positive integers.
How can I count all the permutation of array 'a' which are strictly lexicographically smaller than array-'b'?
Arrays can contain as many as 10^5 integers(positive)
Example:
1 2 3 is lexicographically smaller than 3 1 2
1 2 3 is lexicographically smaller than 1 4 5.
I would like the solution to be in C++.
Input : 3
1 2 3
2 1 3
Output : 2
Only permutations 1,2,3 and 1,3,2 are lexicographically smaller than 2 1 3
Let's just tackle the algorithm. Once you get that figured out, the implementation should be pretty straightforward. Does this look like it does what you're looking for?
Pseudo code:
function get_perms(a,b)
#count the number of digits in a that are <b[0]
count = sum(a<b[0])
Nperms = (len(a)-1)! #modify this formula as needed
N = count*Nperms
if sum(a==b[0]) > 0
remove 1 b[0] from a
# repeat the process with the substring assuming a[0]==b[0]
N += sum(a==b[0])*get_perms(a,b[1:end])
return N
main()
get_perms(a,b)
Edit: I did a little searching. I believe that this is what you are looking for.
I am using the Eigen library in C++.
I need to insert a row and column to an existing matrix at specific index.
For example, say I need to insert a 0 row and 0 column at the 2nd index...
ORIGINAL MATRIX (A)
1 2 3
1 2 3
1 2 3
NEW MATRIX (B)
1 2 0 3
1 2 0 3
0 0 0 0
1 2 0 3
Thanks for the help in advance!
The new matrix B can be constructed from the original matrix A by using the block operations .topRows() and .bottomRows():
MatrixXd B = MatrixXd::Zero(4, 3);
B.topRows(2) = A.topRows(2);
B.bottomRows(1) = A.bottomRows(1);
This will insert a row of zeros between the second and third row. Analogous operations with .rightCols() and .leftCols() can be used to insert a column of zeros.
In SAS/IML, I'm doing the following:
matrix = {1 2 3 4 5, 2 3 1 2 3, 8 4 8 1 1};
empty = j(5,5);
do i=1 to 5;
empty[i,] = matrix[1,];
end;
So I want to replace the ith row of "empty" with the first row of matrix, but this code doesn't work. How can I replace entire rows of a matrix like this?
If you are trying to replace every row of 'empty' with matrix[1,], I don't see any thing wrong with the code.
How to effectively generate permutations of a number (or chars in word), if i need some char/digit on specified place?
e.g. Generate all numbers with digit 3 at second place from the beginning and digit 1 at second place from the end of the number. Each digit in number has to be unique and you can choose only from digits 1-5.
4 3 2 1 5
4 3 5 1 2
2 3 4 1 5
2 3 5 1 4
5 3 2 1 4
5 3 4 1 2
I know there's a next_permutation function, so i can prepare an array with numbers {4, 2, 5} and post this in cycle to this function, but how to handle the fixed positions?
Generate all permutations of 2 4 5 and insert 3 and 1 in your output routine. Just remember the positions were they have to be:
int perm[3] = {2, 4, 5};
const int N = sizeof(perm) / sizeof(int);
std::map<int,int> fixed; // note: zero-indexed
fixed[1] = 3;
fixed[3] = 1;
do {
for (int i=0, j=0; i<5; i++)
if (fixed.find(i) != fixed.end())
std::cout << " " << fixed[i];
else
std::cout << " " << perm[j++];
std::cout << std::endl;
} while (std::next_permutation(perm, perm + N));
outputs
2 3 4 1 5
2 3 5 1 4
4 3 2 1 5
4 3 5 1 2
5 3 2 1 4
5 3 4 1 2
I've read the other answers and I believe they are better than mine for your specific problem. However I'm answering in case someone needs a generalized solution to your problem.
I recently needed to generate all permutations of the 3 separate continuous ranges [first1, last1) + [first2, last2) + [first3, last3). This corresponds to your case with all three ranges being of length 1 and separated by only 1 element. In my case the only restriction is that distance(first3, last3) >= distance(first1, last1) + distance(first2, last2) (which I'm sure could be relaxed with more computational expense).
My application was to generate each unique permutation but not its reverse. The code is here:
http://howardhinnant.github.io/combinations.html
And the specific applicable function is combine_discontinuous3 (which creates combinations), and its use in reversible_permutation::operator() which creates the permutations.
This isn't a ready-made packaged solution to your problem. But it is a tool set that could be used to solve generalizations of your problem. Again, for your exact simple problem, I recommend the simpler solutions others have already offered.
Remember at which places you want your fixed numbers. Remove them from the array.
Generate permutations as usual. After every permutation, insert your fixed numbers to the spots where they should appear, and output.
If you have a set of digits {4,3,2,1,5} and you know that 3 and 1 will not be permutated, then you can take them out of the set and just generate a powerset for {4, 2, 5}. All you have to do after that is just insert 1 and 3 in their respective positions for each set in the power set.
I posted a similar question and in there you can see the code for a powerset.