Ok, so I have a problem that I am trying to solve. I currently have a bunch of vectors (like 200) that each have 1000-5000 elements. I am trying to find the Highest 'common' value among them.
First of all, every element in each vector cannot be greator than the vectors size. Secondly, the LCM of all vector sizes is known.
I think this is best illustrated with an example. Suppose I want to 'combine' the following vectors and find the 'highest' common value:
First Array is: [0] (Max size = 2)
Second Array is: [1] (Max size = 3)
Third array is: [2,3] (Max size = 4)
First, find the size of the combined vector: LCM(2,3,4)=12:
Thus (if I was combining these three vectors), I would then do something like this:
First array changes to: [0,2,4,6,8,10] (ie, all elements mod 2 = 0, as indicated in origianl vector)
Second array changes to [1,4,7,10] (ie, all elements mod 3 = 1, as indicated in origianl vector)
Third array changes to [2,3,6,7,10,11] (ie, all elements mod 4 = 2 or 3, as indicated in origianl vector)
Now, to combine them I simply pull out the common elements into a new (combined) array of size 12: [10].
So, basically, for each array you have a multiplier and element counter. When the multiplier is multiplied by the the array size ratio minus 1 (LCM/Array size -1: for the first array this would be 12/2 - 1 = 5) and the element which is specific by the element counter is added to this value it could be 0...Max size-1 (or, 0..11).
So, first starting out I set up all of the array multipliers:
First array: 12/2-1=5
Second array: 12/3-1=3
Third array: 12/4-1=2
Next the max counter value is found (simply the number of elements in the original vectors):
First array: 0
Second array: 0
Third array: 1
So, to get the highest common value, I multiply the first multiplier by the first array size and add the element counter.. I then check other arrays (by multiplying their multiplier and adding the element counter) to see if they are the same... if they are not then I first adjust the element counter then the multiplier.. I do this until this value is the same across all arrays (I don't care what the multipliers are and array counters are, I just want this highest 'common' value). Example:
TestNum=((5*2)+Array(0))=((5*2)+0)=10 (same as when j=0...)
j=0:
((5*2)+Array(0))=((5*2)+0)=10, which is equal to TestNum, so ++j
j=1:
((3*3)+Array(0))=((3*3)+1)=10, which is equal to TestNum, so ++j
j=2:
((2*4)+Array(1))=((2*4)+3)=11, which is great than TestNum, so start decrementing the element counter and try again:
((2*4)+Array(0))=((2*4)+2)=10, which is equal to TestNum, so ++j
If (j>Number of original vectors), then quit since we have found the highest 'common' value possible.
Since writing this version of the code, I have dropped the practice of decrementing the mltiplier and counter by one and started to divide the difference between testnum[j] and the base testnum and use that to change the multiplier by a value higher than 1 (hopefully). This speeds things up a little but, but I didn't know if anyone else knew of a faster way? I think I had thought of one (multiplying mult of vec(0), adding element(element_count(0)), and then mod'ing this value by all vector sizes... if this value was then found in each array, it would qualify as a common value - this might be faster since we could use binary search...).
Anyway, does this make sense? Does anyone know of a faster way to do this?
Thanks!
First of all, every element in each vector cannot be greator than the vectors size. Secondly, the LCM of all vector sizes is known.
I think this is best illustrated with an example. Suppose I want to 'combine' the following vectors and find the 'highest' common value:
First Array is: [0] (Max size = 2)
Second Array is: [1] (Max size = 3)
Third array is: [2,3] (Max size = 4)
First, find the size of the combined vector: LCM(2,3,4)=12:
Thus (if I was combining these three vectors), I would then do something like this:
First array changes to: [0,2,4,6,8,10] (ie, all elements mod 2 = 0, as indicated in origianl vector)
Second array changes to [1,4,7,10] (ie, all elements mod 3 = 1, as indicated in origianl vector)
Third array changes to [2,3,6,7,10,11] (ie, all elements mod 4 = 2 or 3, as indicated in origianl vector)
Now, to combine them I simply pull out the common elements into a new (combined) array of size 12: [10].
So, basically, for each array you have a multiplier and element counter. When the multiplier is multiplied by the the array size ratio minus 1 (LCM/Array size -1: for the first array this would be 12/2 - 1 = 5) and the element which is specific by the element counter is added to this value it could be 0...Max size-1 (or, 0..11).
So, first starting out I set up all of the array multipliers:
First array: 12/2-1=5
Second array: 12/3-1=3
Third array: 12/4-1=2
Next the max counter value is found (simply the number of elements in the original vectors):
First array: 0
Second array: 0
Third array: 1
So, to get the highest common value, I multiply the first multiplier by the first array size and add the element counter.. I then check other arrays (by multiplying their multiplier and adding the element counter) to see if they are the same... if they are not then I first adjust the element counter then the multiplier.. I do this until this value is the same across all arrays (I don't care what the multipliers are and array counters are, I just want this highest 'common' value). Example:
TestNum=((5*2)+Array(0))=((5*2)+0)=10 (same as when j=0...)
j=0:
((5*2)+Array(0))=((5*2)+0)=10, which is equal to TestNum, so ++j
j=1:
((3*3)+Array(0))=((3*3)+1)=10, which is equal to TestNum, so ++j
j=2:
((2*4)+Array(1))=((2*4)+3)=11, which is great than TestNum, so start decrementing the element counter and try again:
((2*4)+Array(0))=((2*4)+2)=10, which is equal to TestNum, so ++j
If (j>Number of original vectors), then quit since we have found the highest 'common' value possible.
Since writing this version of the code, I have dropped the practice of decrementing the mltiplier and counter by one and started to divide the difference between testnum[j] and the base testnum and use that to change the multiplier by a value higher than 1 (hopefully). This speeds things up a little but, but I didn't know if anyone else knew of a faster way? I think I had thought of one (multiplying mult of vec(0), adding element(element_count(0)), and then mod'ing this value by all vector sizes... if this value was then found in each array, it would qualify as a common value - this might be faster since we could use binary search...).
Anyway, does this make sense? Does anyone know of a faster way to do this?
Thanks!