N X 3 matrix shorting and unique element matrix extraction - c++

I am facing problem with a 2D matrix consist of 3 column and N rows. Now I wanted to sort the matrix in such a way that the smallest of the first row is the first element, and so on. The first element of the second row is the smallest number with the smallest value of the first row. and similar to 3rd row. For example,
A B C
5 2 6
6 5 8
2 9 4
4 5 8
2 3 5
2 9 2
so the sorted matrix will be
A B C
2 3 5
2 9 2
2 9 4
4 5 8
5 2 6
6 5 8
Also, it will store the index of them such that
A_i B_i C_i
5 5 5
6 6 6
3 3 3
and so on...
I implemented this using C++ which is not computationally efficient and takes so much time for a very big matrix. How I can Implement this a computationally efficient way and fast?
My current C++ code for the same is as follow
for(int tii=0; tii<f_sizee; tii++){
track_index(tii)=tii+1;
}
for(int chkhk=0;chkhk<f_sizee;chkhk++){
if(check_index(chkhk)==1){
for(int chkhk1=chkhk+1;chkhk1<f_sizee;chkhk1++){
if((Va_mat(chkhk,0)==Va_mat(chkhk1,0))&&(Va_mat(chkhk,1)==Va_mat(chkhk1,1))&&(Va_mat(chkhk,2)==Va_mat(chkhk1,2))){
check_index(chkhk1)=0;
track_index(chkhk1)=seed_ind;
}
else track_index(chkhk)=seed_ind;
}
seed_ind=seed_ind+1;
}
}
int new_dim=sum(check_index);
int new_count=0;
mat unsort_vmat=zeros(new_dim,Va_mat.n_cols);
for(int iij=0; iij<f_sizee; iij++){
if(check_index(iij)==1){
unsort_vmat.row(new_count)=Va_mat.row(iij);
new_count++;
}
}
mat sort_vmat=zeros(new_dim,Va_mat.n_cols);
uvec indices = stable_sort_index(unsort_vmat.col(0));
int contrrS=0;
for(int sort_f=0; sort_f < new_dim; sort_f++){
for(uword sort_f2=0; sort_f2 < Va_mat.n_cols; sort_f2++){
contrrS=indices(sort_f);
sort_vmat(sort_f,sort_f2)=unsort_vmat(contrrS,sort_f2);
}
}
mat sort_vmat2 = zeros(new_dim,Va_mat.n_cols);
sort_vmat2 = sort_vmat ;
double element_tmp=0;
for(int iitr=0; iitr < new_dim; iitr++){
for(int iitk=iitr; iitk < new_dim; iitk++){
if(sort_vmat(iitk,0)==sort_vmat(iitr,0)){
if(sort_vmat(iitk,1)>sort_vmat(iitr,1)){///if error, delete this brace
element_tmp=sort_vmat(iitr,1);
sort_vmat(iitr,1)=sort_vmat(iitk,1);
sort_vmat(iitk,1)=element_tmp;
}
}
}
}
vec new_ind=zeros(f_sizee);
int start_ind=0;
for(int new_index=0; new_index<f_sizee; new_index++){
new_ind(new_index)=start_ind;
start_ind++;
}
int itr_count=0;
for(uword itr1=0; itr1<Va_mat.n_rows; itr1++){
for(int itr2=0; itr2<new_dim; itr2++){
if((Va_mat(itr1,0)==sort_vmat2(itr2,0))&&(Va_mat(itr1,1)==sort_vmat2(itr2,1))&&(Va_mat(itr1,2)==sort_vmat2(itr2,2))){
new_ind(itr_count)=itr2+1;
itr_count++;
}
}
}
int funda=0;
for(unsigned int Faa=0; Faa<Fa_mat.n_rows; Faa++){
for(unsigned int Fab=0; Fab<Fa_mat.n_cols; Fab++){
Fa_mat(Faa, Fab)=new_ind(funda);
funda++;
}
}

Related

Matrix multiplying method gives out additional column filled with zeros

I wrote a method that multiplies matrices. It works fine, but gives additional column of zeros. The result of multiplying is correct. Here is the code of method:
Matrix Matrix::multiplyMatrix(Matrix second)
{
vector<vector<double> > sum(vec.size(), vector<double> (vec[0].size()));
if (vec[0].size()!=second.vec.size())
{
throw "Dimensions are not correct";
}
else
{
for (int i=0; i<vec.size(); i++)
{
for (int j=0; j<second.vec[0].size(); j++)
{
sum[i][j]=0;
for (int k=0; k<vec[0].size(); k++)
{
sum[i][j]+=vec[i][k]*second.vec[k][j];
}
}
}
Matrix out(vec.size(), vec[0].size());
out.vec=sum;
return out;
}
}
From main:
Matrix A("A.txt",3,4);
Matrix B("B.txt",4,3);
auto C=A.multiplyMatrix(B);
C.write("C.txt");
Matrices:
A:
2 3 4 4
1 2 4 6
1 1 0 1
and
B:
1 2 3
5 6 7
9 1 5
4 5 5
Instead of 3x3 matrix it gives:
69 46 67 0
71 48 67 0
10 13 15 0
Do you know what is the problem?
Thanks
Your matrix named "out" has the wrong dimensions, also, int the first line of your code, the sum has wrong dimensions too.
the first line should change to:
vector<vector<double> > sum(vec.size(), vector<double> (second.vec[0].size()));
the definition of out should change to:
Matrix out(vec.size(), second.vec[0].size());

Problem with my quicksort, it doesn't sort correctly

OK I am trying to make Prima algorithm so i need my edges array sorted, I tried to use quicksort here but it didn't work as I planned.
#include <iostream>
using namespace std;
void Sort (int arr[100][4], int m, int l) {
int i,j,x,v;
i=m;
j=l;
x=(i+j)/2;
do
{
while (((arr[i][3]<arr[x][3]))and(i<=l)) i++;
while (((arr[j][3]>arr[x][3]))and(j>=m)) j--;
if (i<=j)
{
v=arr[i][1];
arr[i][1]=arr[j][1];
arr[j][1]=v;
v=arr[i][2];
arr[i][2]=arr[j][2];
arr[j][2]=v;
v=arr[i][3];
arr[i][3]=arr[j][3];
arr[j][3]=v;
i++;
j--;
}
}
while (i<=j);
if (i<l) Sort(arr,i,l);
if (m<j) Sort(arr,m,j);
}
int main () {
int i,x,y,z,n,m;
int a[100][4];
fill(&a[0][0],&a[0][0]+400,0);
cout<<"Enter number of nodes and edges\n";
cin>>n>>m;
cout<<"Enter edges and their weights\n";
for (i=0;i<m;i++) {
cin>>x>>y>>z;
a[i][1]=min(x,y);
a[i][2]=max(x,y);
a[i][3]=z;
}
Sort (a,0,m-1);
for (i=0;i<m;i++) {
cout<<i+1<<") "<<a[i][1]<<' '<<a[i][2]<<' '<<a[i][3]<<endl;
}
return 0;
}
what I put is
5 10
1 2 4
1 3 7
4 1 5
5 1 8
2 3 3
2 4 6
2 5 6
3 4 8
3 5 2
4 5 4
what I get is
1) 3 5 2
2) 2 3 3
3) 1 4 5
4) 1 2 4
5) 4 5 4
6) 2 5 6
7) 2 4 6
8) 1 3 7
9) 1 5 8
10) 3 4 8
I don't understand why 5 is going ahead of 4's. Hope you could help.
You choose the pivot element in the middle of the (sub)array, which is fine, but you leave it in that position when you run the partitioning loop, and rely on it to stay there, which is not ok. With your approach, the pivot is likely to be swapped to a different position during the ordinary course of partitioning, after which the remainder of the partitioning will be based on the key swapped into the pivot's original position, which is likely to be different.
The usual approach is to start by swapping the pivot element to one end of the array or the other, partition the rest of the array, and then afterward swap the pivot into its correct position, as discovered via the partitioning process.
Change the code to use the pivot value instead of the pivot index, and some fixes to make it more like conventional Hoare partition scheme:
i=m-1;
j=l+1;
x=arr[(i+j)/2][3];
while(1)
{
while (arr[++i][3] < x);
while (arr[--j][3] > x);
if(i >= j)
return j;
// ...

Longest Increasing Sub sequence in a range

I have come across a problem where we want to tell the maximum size of the longest increasing sub-sequence.
an array A consisting of N integers.
M queries (Li, Ri)
for each query we wants to find the length of the longest increasing subsequence in
array A[Li], A[Li + 1], ..., A[Ri].
I implemented finding the sub-sequence using dp approach
// mind the REPN, LLD, these are macros I use for programming
// LLD = long long int
// REPN(i, a, b) = for (int i = a; i < b; ++i)
LLD a[n], dp[n];
REPN(i, 0, n)
{
scanf("%lld", &a[i]);
dp[i] = 1;
}
REPN(i, 1, n)
{
REPN(j, 0, i)
{
if(a[i] > a[j])
dp[i] = std::max(dp[j] + 1, dp[i]);
}
}
For example:
Array: 1 3 8 9 7 2 4 5 10 6
dplis: 1 2 3 4 3 1 3 4 5 5
max: 5
But if it was for range Li=2 & Ri=9
Then:
Array: 3 8 9 7 2 4 5 10
dplis: 1 2 3 2 1 2 3 4
max: 4
How can i determine the maximum longest increasing sub-sequence in a sub array?
PS: I don't want to recompute the whole dplis array, I want to use the original one because too much computation will kill the purpose of the question.
One of the approaches was to construct a complete 2D DP array that consists of sub-sequence from position i where range of i is from 0 to n, but it fails on many cases due to TLE(Time limit exceeded)
REPN(k,0,n) {
REPN(i,k+1,n) {
REPN(j,k,i) {
if(a[i]>a[j]) dp[k][i]=std::max(dp[k][j]+1, dp[k][i]);
}
}
}
REPN(i,0,q) {
read(l); read(r);
LLD max=-1;
REPN(i,0,r) {
if(max<dp[l-1][i]) max=dp[l-1][i];
}
printf("%lld\n", max);
}
If you have any new logic/implementation, I will gladly study it in-depth. Cheers.

Using recursion combinations to subset array [duplicate]

This question already exists:
Recursion all combinations of lower triangle C++
Closed 8 years ago.
I recently posted a poor question on how to use recursion to estimate all combinations of lower triangle in C++. I managed to find a recursive algorithm that given an array of size n, generates and prints all possible combinations of r elements in array. I've employed this function using Rcpp in R. I've then written a loop around this function to get all the subsets of combinations r to r + n.
#include <Rcpp.h>
using namespace Rcpp;
// [[Rcpp::export]]
int recursive(IntegerVector arr, IntegerVector data, int start, int end, int index, int r)
{
if (index == r)
{
for (int j=0; j<r; j++)
printf("%d ", data[j]);
printf("\n");
}
for (int i=start; i<=end && end-i+1 >= r-index; i++)
{
data[index] = arr[i];
recursive(arr, data, i+1, end, index+1, r);
}
}
R code with five groups:
Rcpp::sourceCpp('recursive2.cpp')
nComm <- 5
r <- c(2:nComm)
n <- nComm
arr <- c(1:nComm)
dat <- c(1:nComm)
for(i in 1:(n-1)){
recursive(arr, dat, 0, n-1, 0, r[i])
}
1 2
1 3
1 4
1 5
2 3
2 4
2 5
3 4
3 5
4 5
1 2 3
1 2 4
1 2 5
1 3 4
1 3 5
1 4 5
2 3 4
2 3 5
2 4 5
3 4 5
1 2 3 4
1 2 3 5
1 2 4 5
1 3 4 5
2 3 4 5
1 2 3 4 5
Currently, this just prints the subsets of combinations I need to estimate my dissimilarities. I'd like to be able to remove the loop and use it as a single Rcpp function/script. With the end goal to be able to use the subsets (currently printed combinations) as way to subset rows in an array. Which will be used to calculate the intersect between vectors. So 1 2 will be used to compare rows 1 and 2 in an array. And so forth.

How to display Non Diagonal 2D Array elements

I am successful in displaying Diagonal Array elements, but failed to display Non Diagonal array elements I tried a lot but unsuccessful. Here is the code what I am try with I am using Turbo C++ -
#include<conio.h>
#include<iostream.h>
void accept(int a[4][4],int size)
{
cout<<"Diagonal One:";
for (int i=0;i<size;i++)
for(int j=0;j<size;j++)
if (i!=j)
cout<<"\n"<<i <<" "<<j<<" "<<a[i][j];
}
void main()
{
int a[4][4]={{5,4,3,4},{6,7,9,1},{8,0,3,7},{2,4,5,9}};
clrscr();
accept(a,4);
getch();
}
Example : if the array content is
5 4 3 4
6 7 9 1
8 0 3 7
2 4 5 9
Output through the function should be :
4 3 6 1 8 7 4 5
Output is displaying some of the diagonal elements also.
The function skips all elements in the diagonal 5739 (i != j takes care of this), but, based on the desired output, you also wish to skip all elements in the diagonal 4902.
To also check for the other diagonal, replace
if (i != j)
with
if (i != j && i != size-j-1)
Test.