I'm writing a sparse matrix class in C++ in which every row and column are arrays of linked lists from a class I created (aptly named: LinkedList).
I want to write a class that is a "smart" pointer to one cell in this matrix.
In that class, let say LIPointer, I will implement a ++ operator function for moving in the linked lists of the matrix.
Is there an elegant way of doing this without moving the references of the matrix arrays and sized elements each time I create a linkedlistPointer?
I can't use stl::array etc. because I have to build them myself.
Here are the declarations:
class LinkedItem
{
private:
int Column, Row;
double Value;
LinkedItem* Right;
LinkedItem* Down;
public:
...
};
class SparseLinkedMatrix
{
private: //members
int ColSize;
int RowSize;
LinkedItem ** Columns;
LinkedItem ** Rows;
public: //functions
SparseLinkedMatrix();
...
};
class LIPointer;
private:
LinkedItem * CellPointer;
public:
LIPointer();
void operator++();//???
...
};
Any advice or direction would be appreciated.
Update: It needs to run on the whole matrix. That is why I think I need to move (by reference) the arrays and the size of the matrix. The intended effect is that this would from the last cell in the linked list of the first row to the first cell in the second row.
For compressed row matrices, I use something like:
std::vector<std::map<size_t, double> > matrix;
I can then add an entry using:
matrix[row][col] += val;
For each row, I can then iterate through the column entries in ascending order and read out the value.
Edit: The person posing the question does point out that they cannot use the STL. Perhaps they can use some kind of map versus a linked list. Otherwise I suggest using a vector of linked lists and keep adding entries to the end of each list. Then do a sort of each linked list when adding entries has been completed.
Can you please elaborate on exactly what you want operator++() to do?
For instance, to have LIPointer's operator++() go to the next right element:
void operator++()
{
if ( CellPointer != NULL )
CellPointer = CellPointer->Right;
}
It stops when it gets to the end, though.
Related
I have a std::vector<std::vector<type T>> matrix, I insert elements of type T to this matrix and I do some instructions by line on these elements. I need also at each iteration to delete the element with a minimum cost.
I created an std::priority_queue<Costelement, std::vector<Costelement>, Costelement::Comparekeys> Costvec; where:
struct Costelement
{
int row;
int column;
std::vector<double> cost;
struct CompareCosts
{
bool operator()(const Costelement &e1, const Costelement &e2)
{
return (e1.cost > e2.cost);
}
};
};
where row and column are the position of the element in matrix having the corresponding cost. However, when I delete the element with minimum key from matrix, the positions of the elements in the corresponding row change. I used std::min_element at each iteration on matrix but this was very costly. How can we model efficiently this case?
A std::priority_queue by default is just a std::vector that is kept in a sorted state. It can still be expensive to insert and remove elements from the queue, and as you noticed, you would potentially need to update all of the Costelements in the queue when you insert or remove an element from matrix in order to relect the new positions. However, you can make that a bit more efficient by making the priority queue two-dimensional as well, something that looks like:
std::priority_queue<std::priority_queue<Costelement, ...>, ...> cost_matrix;
Basically, the inner priority queue sort the cost of the columns of a single row, the outer priority queue should then sort the cost of whole rows. Let's create ColumnCost and RowCost structs:
struct ColumnCost {
int column;
double cost;
friend bool operator<(const ColumnCost &a, const ColumnCost &b) {
return a.cost > b.cost;
}
};
struct RowCost {
int row;
std::priority_queue<ColumnCost> columns;
friend bool operator<(const RowCost &a, const RowCost &b) {
return a.columns.top() > b.columns.top();
}
};
std::priority_queue<RowCost> cost_matrix;
Now you can easily get the lowest cost element from costmatrix, which returns the RowCost which contains the lowest cost element, and then you get the ColumnCost with the lowest cost from that one:
const auto &lowest_row = cost_matrix.top();
const auto &lowest_column = lowest_row.columns.top();
int row = lowest_row.row;
int column = lowest_column.column;
When you now insert or delete an element from matrix, you insert or delete from cost_matrix in the same way. You still need to update row or column coordinates, but now it is much less work. The only thing to be aware of is that if you update add or remove an element to the priority queue of a RowCost, you need to delete and re-insert that whole row from cost_matrix to ensure the outer priority queue is kept correctly sorted.
Another possible optimization is to use a std::priority_queue to keep the rows sorted, but use std::min_element() to keep track of the minimum of each individual row. This greatly reduces the amount of memory necessary to store the cost_matrix, and you would only need to call std::min_element() to recalculate the minimum cost element of a row when you change that row.
You may want to replace a row vector with a rope (see the rope data structure in Wikipedia).
It's a binary tree based structure, which allows quite efficient removing elements and searching for an n-th element ('indexing'), so you needn't update positions in all elements when you remove one of them.
Hello i know how couting sort works, how to implement it, But is it possible to implement it on a class who got 3 attributs and need to countSort the whole DisjointSet on a specific attribut.
If so, lets say i have this class:
class myStructure {
public:
int m_id = -1;
myStructure* m_parent = NULL;
int m_sortie = -1;
int m_echeance = -1;
myStructure() {}
myStructure(int id, myStructure* parent, int sortie, int echeance)
: m_id(id), m_parent(parent), m_sortie(sortie), m_echeance(echeance)
{ }
};
How can i implement the counting sort on the m_echance.
Thanks
Surely you can apply counting sort.
It is applicable to any field which can be mapped with integers. In general counting sort should be used if the range of values(in your case m_echeance) is small.
Below is high level approach to do that-
Let's say your objects are stored in array A[]
range of m_echeance is [0,R-1]
Make a count array.
loop through the array A to count frequencies of the objects with different m_echeance values.
something like count[A[i]->m_echeance + 1]++;
Get the cumulative frequencies for the count array.
Copy objects in auxiliary array based on cumulative frequencies.
Copy back objects from auxiliary array to original array.
Hope it helps!
I have a matrix class as follows (some parts are omitted for clarity):
template <typename T> class CMatrix{
protected:
vector<T>* m_matrix;
public:
void SetCellValue(unsigned int row,unsigned int col,T value){ m_matrix->at(row*m_column+col)=value;}
T& GetCellValue(unsigned int row,unsigned int column) const{return m_matrix->at(row*m_column+column);}
I would like to have a function to sort the matrix based on a chosen column. Say if the matrix is:
2 3
1 4
After sorting based on 1st column it should look like:
1 4
2 3
Basically, since 1<2 we performed a row exchange. I know if m_matrix was a 2D vector, then std::sort would have worked. Is it possible to achieve sorting 1D std::vector based matrix, based on a chosen column.
The following worked very well for a 1D data type but could not tweak it to work with a matrix:
template <typename T> class Sorter{
bool m_IsAscending;
public:
Sorter() {m_IsAscending=true;}
void SortAscending() {m_IsAscending=true;}
void SortDescending(){m_IsAscending=false;}
bool operator()(T i, T j){
if(m_IsAscending) return (i<j); else return (i>j);
}
};
The solution is very easy. Remember that std::sort takes begin and end iterators. So all you have to do is split your matrix into parts and sort them individually:
for(long i = 0; i < num_of_columns; i++)
{
std::sort(m_matrix->begin()+num_of_rows*i, m_matrix->begin()+num_of_rows*(i+1));
}
This will sort all individual columns independently. If you want to sort only one column, don't use a loop, and choose an i that is the column number you want to sort.
Caveats:
This will work if your matrix is flattened in column-major order. Otherwise, if it's in row-major, all you have to do is transpose the matrix, sort it with the code above, and transpose it back. I guess this is the only way to go if you want to avoid writing your own sorting function. However, if all you want is to sort a single column, and your matrix is in row-major order, then it's much cheaper to just copy that row to a new vector, sort it, and copy it back.
Btw, I don't understand why m_matrix is a pointer... that's very bad practice and is a welcome invitation to memory leaks (unless you're using a smart pointer to wrap it, such as std::unique_ptr).
Hope this helps. Cheers!
This question already has answers here:
Rationale of enforcing some operators to be members
(2 answers)
What are the basic rules and idioms for operator overloading?
(8 answers)
Closed 7 years ago.
I am working with Graphs, and writing code some well known algorithms. Currently I am working on the Dijkstra Algorithm.
So, I have made my own Heap class which works as a min-priority queue for the implementation of the Dijkstra algorithm. Since, in the Dijkstra algorithm, you need to update the distance of a vertex (which is already in the heap), from the source vertex in the Graph, if its distance is less than it's current distance, and then accordingly adjust the values in a Heap.
For this, I need to keep an int position[] array to keep a track of the positions at which the elements are currently in the Heap
This is my Vertex Class ::
class Node{
public:
int data;
int weight;
.....
friend int& operator [](int *a, Node i) {
return a[i.data];
}
};
My minPriorityQueue class ::
template <typename t>
class minPriorityQueue {
int size, currentPosition;
int *position;
t *data;
bool (*compare)(t data1, t data2);
public:
minPriorityQueue(int size, bool (*func1)(t data1, t data2), int *position) {
this->size = size;
currentPosition = 1;
data = new t[size];
compare = func1;
this->position = position;
}
........
void swapPositionValue(int parent, int temp) {
int tempPosition = position[data[parent]];
position[data[parent]] = position[data[temp]];
position[data[temp]] = tempPosition;
}
......
};
Since my vertices are 0,1,2,3, ... So, I try to overload the []operator of my Vertex class so that it returns me the data of the current vertex (which is one from 0,1,2,3 ..., so I can use it to access that index of the position array.
I get the compilation error :: error: 'int operator[](int*, graph::Vertex)' must be a nonstatic member function
Well, since I get this error I assume that it must have been specified in the standard that I cannot overload the []operator using a friend function, but why I cannot do it?? Does it lead to any ambiguity? I don't see what can be ambiguous in what I am currently using.
Secondly, is there any way I can swap the values in my position array? My minPriorityQueue class is a generic class which I am using at several other places at my code as well. In the function swapPositionValue if I change my swap statements to this ::
int tempPosition = position[data[parent].data];
position[data[parent].data] = position[data[temp].data];
position[data[temp].data] = tempPosition;
Then the whole idea of "generic" priority queue will be sacrificed! Since, it won't work with other classes!
Is there a way that I can achieve this functionality??
EDIT1 :: The complete Code :: http://ideone.com/GRQHHZ
(Using Ideone to paste the code, Because the code is still very large, containing 2 classes)
This is what I am trying to achieve :: http://www.geeksforgeeks.org/greedy-algorithms-set-7-dijkstras-algorithm-for-adjacency-list-representation/
(I am just using the algorithm)
Explanation of what is the functionality of operator[]::
In my Dijkstra implementation all the nodes are initially inserted into the Heap, with the start node, having the weight = 0, and all the other nodes with weight = INFINITY (which means I cannot reach the vertices) so start vertex is the topmost element of the heap! Now when I remove the topmost element, all the Node that have a path from the removed Node will get modified, their weight will be modified from INFINITY to some finite value. So, I need to update the Nodes in the Heap, and then I need to move them to their correct positions, according to their new weights!! To update their weights, I need to know at what position are the Nodes located in the Heap, and the position is decided by the data of the Node. So, overloading the []operator was just a small way out for me, so that when I do position[Node], I can access position[Node.data].
Why this is not a duplicate:: The linked question is a broad operator overloading post, it just mentions 1 point where it states that []operator can only be overloaded with member functions and not otherwise, does not state why! And this is a specific problem I am facing where I do not want to sacrifice the generic property of my self made Heap, and use it for the Dijkstra as well.
EDIT2 :: While writing this explanation I realize I had made a big mistake in my overloaded function. I have changed it! Please check it. Probably it makes more sense now. Apologies!!
The overloaded function now looks like ::
friend int& operator [](int *a, Node i) {
return a[i.data];
}
EDIT3 :: In implement my Graph class with Adjacency Matrix, and it is a boolean 2D array, because my current implementation is for Unweighted graphs, and accordingly the shortest path becomes the least number of edges traversed! (Just in case that mattered!)
Thanks for reading all of this huge question, and for any help! :)
I have an unsorted vector of eigenvalues and a related matrix of eigenvectors. I'd like to sort the columns of the matrix with respect to the sorted set of eigenvalues. (e.g., if eigenvalue[3] moves to eigenvalue[2], I want column 3 of the eigenvector matrix to move over to column 2.)
I know I can sort the eigenvalues in O(N log N) via std::sort. Without rolling my own sorting algorithm, how do I make sure the matrix's columns (the associated eigenvectors) follow along with their eigenvalues as the latter are sorted?
Typically just create a structure something like this:
struct eigen {
int value;
double *vector;
bool operator<(eigen const &other) const {
return value < other.value;
}
};
Alternatively, just put the eigenvalue/eigenvector into an std::pair -- though I'd prefer eigen.value and eigen.vector over something.first and something.second.
I've done this a number of times in different situations. Rather than sorting the array, just create a new array that has the sorted indices in it.
For example, you have a length n array (vector) evals, and a 2d nxn array evects. Create a new array index that has contains the values [0, n-1].
Then rather than accessing evals as evals[i], you access it as evals[index[i]] and instead of evects[i][j], you access it evects[index[i]][j].
Now you write your sort routine to sort the index array rather than the evals array, so instead of index looking like {0, 1, 2, ... , n-1}, the value in the index array will be in increasing order of the values in the evals array.
So after sorting, if you do this:
for (int i=0;i<n;++i)
{
cout << evals[index[i]] << endl;
}
you'll get a sorted list of evals.
this way you can sort anything that's associated with that evals array without actually moving memory around. This is important when n gets large, you don't want to be moving around the columns of the evects matrix.
basically the i'th smallest eval will be located at index[i] and that corresponds to the index[i]th evect.
Edited to add. Here's a sort function that I've written to work with std::sort to do what I just said:
template <class DataType, class IndexType>
class SortIndicesInc
{
protected:
DataType* mData;
public:
SortIndicesInc(DataType* Data) : mData(Data) {}
Bool operator()(const IndexType& i, const IndexType& j) const
{
return mData[i]<mData[j];
}
};
The solution purely relies on the way you store your eigenvector matrix.
The best performance while sorting will be achieved if you can implement swap(evector1, evector2) so that it only rebinds the pointers and the real data is left unchanged.
This could be done using something like double* or probably something more complicated, depends on your matrix implementation.
If done this way, swap(...) wouldn't affect your sorting operation performance.
The idea of conglomerating your vector and matrix is probably the best way to do it in C++. I am thinking about how I would do it in R and seeing if that can be translated to C++. In R it's very easy, simply evec<-evec[,order(eval)]. Unfortunately, I don't know of any built in way to perform the order() operation in C++. Perhaps someone else does, in which case this could be done in a similar way.