Distinct sum of 3 variable which ranges between 1-255

Hi, I am trying to retrieve array of sum of 3 numbers (x,y,z) each has a range of 1-255, in such a way that each sum is different from others. I have coded but I couldn't get 100% distinct sum, below result gives Average = 255, Max = 255 , MIN = (254 but I want 255 every time if possible). So each variable's value can be decoded back form the distinct sum. For example sum = 3 is only possible when we have (1+1+1) but for Sum = 4 we have 3 different possible and then it is not decodable; (1+1+2),(1+2+1),(2+1+1), sum = 4. I would be happy if anyone of you can debug this problem. Thank you.
%Updated.
%Input and Expected Output%
% Input Output
% [1,1,2] sum=>4
% [1,2,1] sum=>[different than above]
% [2,1,1] sum=>[distinct from others]
% [3,1,1] sum=>5
% ... ...
%Code%
clear;clc;
for n = 1:1000 %using Iteration to have 1000 different results that are stored in Difference(n,:) which gives Uniqueness values of each result.
Array = zeros(255,5);
Array(:,1:3) = randi(255,255,3);
for k = 1:length(Array);
Array(k,4) = sum(Array(k,1:3));
end
for l = 1:length(Array);
firstVal = Array(l,1)*0.7;
secondVal = Array(l,2)*0.9+firstVal;
thirdVal = Array(l,3)*1.4*secondVal;
Array(l,5) = sum([firstVal,secondVal,thirdVal]);
end
%253Avg
% first = Array(l,1)*0.7;
% second = Array(l,2)*0.9 + first;
% third = Array(l,3)*1.4 + second;
oldunique_Length = length(unique(Array(:,4)));
newunique_Length = length(unique(Array(:,5)));
Difference(n,:) = [oldunique_Length,newunique_Length];
end
%average no. of distinct sum = 255/255, Max value is 255 and MIN value is 254. It is still not 100% because I am getting 254 as a MIN. Everytime I should be able to get 255 (all rows must be different from others)
["OLD UniqueIds (AVG,MAX,MIN)",round(mean(Difference(:,1))),max(Difference(:,1)),min(Difference(:,1));"NEW UniqueIds (AVG,MAX,MIN)",round(mean(Difference(:,2))),max(Difference(:,2)),min(Difference(:,2))]

 Accepted Answer

As you recognize yourself, if you simply form the sum of three integers, you cannot then recover the original values from only that sum. Sufficient information is lost to recover the original components. Thus, given
2 + 1 + 1 == 1 + 2 + 1 == 1 + 1 + 2 == 4
if the sum was 4, then it is never possible to identify which of the three options caused that sum. Sorry, but that is simple fact. You cannot escape the laws of mathematics.
However, you CAN do something that allows recovery, if you use a proper encoding. Think of it as a base transformation, working in base 255. Given three integers, each in the range 1 - 255. I'll call them K, N, & M. Form an encoding as:
KNM = 255^2*(K-1) + 255*(N-1) + (M-1)
Thus for any values of K, N, M, we will get a distinct result, treating those numbers as effectively "digits" in base 255, then mapping the result to base 10. Try it out.
KNMencode = @(K,N,M) 255^2*(K-1) + 255*(N-1) + (M-1);
KNMencode(2,1,1)
ans =
65025
KNMencode(1,2,1)
ans =
255
KNMencode(1,1,2)
ans =
1
So we now get a distinct and unique result for any input combination in that range.
The reverse is true too. Now you can decode any possible integer value in the interval [0,16451834], back into the original set that created the number.
KNMencode(1,1,1)
ans =
0
KNMencode(255,255,255)
ans =
16451834
Again, this is just a case of a base conversion from base 10 back into base 255. Lets try it out.
KNMdecode = @(E) [mod(floor(E/255^2),255) + 1,mod(floor(E/255),255) + 1,mod(E,255) + 1];
KNMencode(1,2,3)
ans =
257
KNMdecode(257)
ans =
1 2 3
So any triple of integers (K,N,M) will result in a unique encoded value as needed, that can then be decoded, recovering the original values.

More Answers (1)

I didn't understand your way for making the sum unique. This dirty code gives you 255 (x,y,z) whose sums are unique.
sumArr=-1*ones(1,255); %Initialize with impossible sums
Array1=zeros(255,3);
for i=1:255
guess=randi([1 255],[1 3]);
while(sum(sumArr==sum(guess))~=0)
guess=randi(255,[1 3]); % guess unil sum is unique
end
sumArr(i)=sum(guess);
Array1(i,:)=guess;
end
if you just need (sum) array which is unique, use randperm instead of randi
unique_sumArr=randperm(255*3,255); %adjust the range

7 Comments

The above code can only generate unique sum but from this I wouldn't know what were x,y,z values for that specific unique sum. Inputs are just only current x,y,z values (no record for past). That is why in my code I was using If condition on z variable.
For example:
1 + 1 + 2 = 4;
2 + 1 + 1 = Z; %consider this Z to be distinct from all the sum values and such that from Z value I can decode x=2;y=1;z=1 => x+y+z = Z;
I still don't fully understand the problem.In number theory, there is some thing called partitions. How many ways I can split a number into?. your are interested in spliting numbers into three.
For example, I can write number 5 as sum of three non-zero positive integers in the following ways(ignoring the order).
(1+1+3),(1+2+2)
If the number has unique partitions/parts, then you can guess the partitions from the sum. In case of 5, there are two possibilities. so, you can't judge.
Say if the sum is 3 or 4,you can say the three numbers are 1+1+1 or 1+1+2 since there is just a single possiblity.
you want all such unique "3 numeber sum" if the individual number range is 1-255. Is that what you have in mind?
Sorry for inconvenience.
  1. Yes, I am interested in partition and I have 3 partitions (x,y,z) and each has range of 1-255.
  2. Each distinct sum can again be easily decoded its partitions. For example. 1+1+1 = 3. We know Sum = 3 can be made only by (x=1,y=1,z=1) but for 4 there are many posibilities and it is difficult to decode what are x and y and z because SUM IS NOT DISTINCT.
  3. Incase of 4 we have 3 different possibilities (1+1+2), (1+2+1),(2+1+1). Therefore It is difficult to understand or decode. Because SUM is my Y-axis and by looking at Y-axis I should be able to decode x,y,z if and only if SUM is distinct and decodable.
  4. When we will have distinct SUM which can also tell me it's ONLY possibility.
I will Update the question and code. Thank you again for your time.
As far as I know, this is not possible. If you want the order as well, then 3 and 255*3 are the only number you can decode by this method. Those two number you can decode are only because you have a prior (knowledge) of the range of individual numbers. With a single unknown you want to have three unknown with prior information(unique sum). Unfortunately, your prior adds no additional information as here is no unique sum other than those two.
  1. Correction: With a single known I want to have 3 unknowns which I think is possible when we can manipulate x,y,z with some constants because 3 unknowns are basically bounded by the range of 1-255.
In the above code which I have updated you will see the Array(:,5) is distinct sum array for each x,y,z.
Then why don't use something like.
Array(:,5)=Array(:,1)+Array(:,2)*1000+Array(:,3)*1000000;
I'm no expert in math. one way to find how many unique sums your expression can produce is by brute force. It is possible if your have enough memory(~16GB).
%permutation of all (x,y,z) with repetition
[x, y ,z]=ndgrid(1:255);
Array=[x(:)*0.7 y(:)*0.9+x(:)*0.7 z(:)*1.4.*(y(:)*0.9+x(:)*0.7 )];
sum_array=sum(Array,2).';
%sort for run length encoding
[sum_array,idx]=sort(sum_array);
Array=Array(idx,:);
% find unique elements by rle
% https://in.mathworks.com/matlabcentral/fileexchange/4955-rle-de-encoding
i = [ find(sum_array(1:end-1) ~= sum_array(2:end)) length(sum_array) ];
Nrep = diff([ 0 i ]);
elem = sum_array(i);
unique_sum=elem(Nrep==1);
xyz=Array(i,:);
unique_xyz=xyz(Nrep==1,:);
%check
assert(isequal(sum(unique_xyz,2).',unique_sum))
out of 16581375 permutation you have only 4278778 unique sums for your expression
Finally, don't use unique function. That is not what you need.
unique([1 1 1 2 3 4])
>> [1 2 3 4] % output of unique: not what you need
>> [ 2 3 4] % what you neeed
Thank you for your time. I will look at it and other different techniques to make it 100% unique values.

Sign in to comment.

Categories

Find more on Programming in Help Center and File Exchange

Products

Release

R2019b

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!