Hi everyone,
My data is stored in a two-dimensional array, which rows correspond to different products, and row elements correspond to product components. Product values are stored in a separate one-dimensional array.
I would like to retain only the products with highest value that consist of distinct and unique components, i.e. identify and retain the rows of the 2d array that differ on all elements. Here is an example:
// 2d array with product IDs
int [][] duplicate =
{{0, 1, 2, 3}, // retain
{0, 5, 6, 11}, // remove
{4, 1, 6, 3}, // remove
{8, 9, 10, 11}}; // retain
// 1d array with product values
int [] value = {10,4,9,15};
int rows =4;// number of components (a constant equal to 4)
// My objective is to filter out distinct products:
Int [][] distProd =
{{0, 1, 2, 3},
{8, 9, 10, 11}};
My idea was (1) to identify the product with the highest value, (2) check if other products overlap with the best one; (3) if products do not have overlapping components with the best one, they are stored in a new array. Here is the code:
int [][] duplicate =
{{0, 1, 2, 3}, // retain
{0, 5, 6, 11}, // remove
{4, 1, 6, 3}, // remove
{8, 9, 10, 11}}; // retain
// 1d array with product values
int [] value = {10,4,9,15};
int rows =4;// number of components (a constant equal to 4)
int [] maxval = new int [rows]; // product id with the max value of the fixed length
int max = max(value); // 15
for (int i=0;i<duplicate.length; i++){
if (value[i]==max) {
maxval = duplicate[i];
}
}
println(maxval); // 8, 9, 10, 11
// check if there are duplicates by substracting each array from an array with max value:
// if products consist of distinct cells neither of the cells in test array should be equal to zero
int [][] dup_test = new int [duplicate.length][rows];
for (int i=0;i<duplicate.length; i++){
for (int j=0; j<duplicate[i].length;j++){
dup_test[i][j]=maxval[j]-duplicate[i][j];
}
}
for (int i=0;i<duplicate.length; i++){
println(i);
println(dup_test[i]);
}
//initialise boolean array
boolean [][] isZero = new boolean [duplicate.length][rows];
for (int i = 0; i<duplicate.length; i++){
for (int j = 0; j<duplicate[i].length; j++){
isZero[i][j] = false;}
}
// check which positions are zeros
for (int i = 0; i<duplicate.length; i++){
for (int j = 0; j<duplicate[i].length; j++){
if (dup_test[i][j]==0) {isZero[i][j] = true;};
}
}
for (int i = 0; i<duplicate.length; i++){
println(i);
println(isZero[i]);
}
// count how many zeros in each product
int [] zeros = new int [isZero.length];
int count_null =0;
for (int i = 0; i<isZero.length; i++){
for (int j = 0; j<isZero[i].length;j++){
if ( isZero [i][j] == true) {count_null++;
}
} zeros [i] = count_null; count_null =0; // reset count for each row
}
for (int i = 0; i<zeros.length; i++){
println(zeros[i]);
}
// filter out distinct products (zeros [i]=0) and the product with max value (zeros[i]=4)
int [][] distinct = new int [duplicate.length][rows]; // temp array with excessive length
int count_dist =0;
for (int i = 0; i<duplicate.length; i++){
if (zeros[i] ==rows || zeros [i] == 0) {distinct[count_dist]=duplicate[i]; count_dist++;}
}
for (int i = 0; i<zeros.length; i++){
println(i);
println(distinct[i]);
}
// count how many distinct products (to input as a length of an array)
int count_cutoff =0;
for (int i =0; i<zeros.length; i++){
if (zeros[i] ==rows || zeros [i] == 0) {count_cutoff++;}
}
int [][] distProd = Arrays.copyOf(distinct,count_cutoff);
// prints: {{0, 1, 2, 3},
// {4, 1, 6, 3},
// {8, 9, 10, 11}};
Question 1: I was wondering if there is a shorter and more elegant way to arrive at the desired solution. Moreover, the current version uses Arrays.copyOf which is no longer available in more recent versions of Processing.
Question 2: The code only partially fulfills its purpose because although products may not have overlapping cells with the max value product (8, 9, 10, 11), they can still have common components between themselves (like in case of 0, 1, 2, 3 and 4, 1, 6, 3). I could just repeat the same algorithm comparing elements to the second best product in distProd, but maybe there is an easier way..
Thank you very much for your consideration!
Hi all!
I am new to Processing and I need help with the code. I am looking for a way to get all possible combinations of elements which are separated in two groups, for example for 4 elements it would look like this:
(AC) = (AD)(AE)(AF)
(AD) = (AC)(AE)(AF)
(AE) = (AC)(AD)(AF)
(AF) = (AC)(AD)(AE)
(AC)(AD) = (AE)(AF)
(AC)(AE) = (AD)(AF)
(AC)(AF) = (AD)(AE)
(AC)(AD)(AE)(AF)
Below I attach code in C++ which gives an idea of an algorithm, but I was just wondering if there is a way to create the same thing in processing. Maybe it would help.. thank you ver much in advance for any suggestions!
void
getCombination( int k, int n) //generation of combinations{
int* A=new int[k]; //array for group 1
int * B= new int [n-k]; //array for group 2char Companies[20][3]={"AB","AC","AD","AE","AF","BB","BC","BD","BE","BF","CB","CC","CD","CE","CF","DB","DC","DD","DE","DF"}; // companies names
if (k<n){
for ( int i=1;i<=k;i++) //initialis arrayA[i]=i;
// algorithm execution
int p=k;
while(p>=1 && res>0)
{
res--;
int z=1;
for(int ii=1; ii<=n;ii++)
{
bool ok=1;
for(int jj=1; jj<=k;jj++)
if (ii==A[jj])
ok=0;
if(ok)
B[z++]=ii;
}
cnt++;
for(int j=1;j<=k;j++)
{
cout << "(" << Companies[A[j]] << ")" ;
myfile << "(" << Companies[A[j]] << ")" ;
}
cout << " = ";
myfile << " = ";
for(int ii=1; ii<=(n-k);ii++)
{
cout << "(" << Companies[B[ii]] << ")";
myfile << "(" << Companies[B[ii]] << ")";
}
cout << "\n";
myfile << "\n";
if(A[k]==n)
p--;
else
p=k;
if (p>=1){
for ( int ii=k; ii>=p;ii--)A[ii]=A[p]+ii-p+1;
}
}
}
else //last combination (if all companies are in the same group){
cnt++;
for(int j=1;j<=k;j++)
{
cout << "(" << Companies[j] << ")" ; //to screen
myfile << "(" << Companies[j] << ")" ; //to file
}
cout << "\n";
myfile << "\n";
}
}
int
_tmain( int argc, _TCHAR* argv[]){
int keyCode=0;while(keyCode!=113 && keyCode!=81) //113 and 81 code for Q and q
{
cnt=0;
int maxval=0; while (maxval<2 || maxval>20) //limitations - no more than 20 and no less than 2 companies{
cout << "Number of companies[2-20]? \n";
cout << "===========================\n";
char tmp[100];
cin >> tmp;
maxval = atoi(tmp);
}res=pow(2,double(maxval-1))-1; //verification Steerling number
cout << "Summary: " << res + 1 << "\n"; // add 1 to account for the last combination when all companies are in the same group
myfile << "Summary: " << res + 1 << "\n";
myfile << "============================================\n";
for(int i=1;i<=maxval;i++)
{
getCombination(i,maxval);
}
cout << "----------\n";
cout << "Total: " << cnt << "\n";
myfile << "----------\n";
myfile << "Total: " << cnt << "\n";
cout << "Press any key to repeat or 'Q' for quit \n";
keyCode=_getch();
}
myfile.close();
return 0;
}