Linear Probing in Open Addressing - hash

I have an array with size m = 11 and my hash function is Division method : h(k) = k mod m
I have an integer k = 10 and 10 mod 11 is -1 so where should I put this key in the array? I should put this key in the slot which its index is 10?
please help me thanks
EDITED : for getting my answer well for example I have integers like k = 10,22,31,4,15,28,17,88,59
the array would be like this?thanks
10 9 8 7 6 5 4 3 2 1 0 index
10 31 59 17 28 4 15 88 22 keys

As it's usually done, 10 mod 11 is 10, so yes, you'd normally use index 10.
Edit: To generalize: at least as it's normally defined, given two positive inputs, a modulo will always produce a positive result. As such, your questions about what to do with negative results don't really make sense with respect to the normal definition.
If you really do have the possibility of getting a negative result, my immediate reaction would be to switch to some language that will produce a reasonable result. If you can't do that, then you'd probably want to move the value into the correct range by adding m to the negative number until you get a number in the range [0..m) so it fits the normal definition of mod, then use that as your index.

Related

MATLAB/OCTAVE - Branching loops? or parallel looping?

Still new to the programing game but I need a little help! I'm not exactly sure how to describe what I want to do but I'll give it my best shot. I have a set of numbers produced by an algorithm I've put together. e.g. :
....
10 10 10
11 11 11
12 1 2
13 3 4
14 12 13
15 6 7
16 5 15
17 8 9
....
Essentially what I want to do is assign these index numbers to groups. Lets say I start with the number 14 in the first column. It is going to belong to group 1, so I label it in a new column in row 14 "1" for group one. The second and the third column show other index numbers that are grouped with the index 14. So I use a code like:
FindLHS = find(matrix(:,1)==matrix(14,2));
and
FindRHS = find(matrix(:,1)==matrix(14,3));
so clearly this will produce the results of
FindLHS = 12
FindRHS = 13
I will then proceed to label both 12 and 13 as belonging to group "1" as I did for 14
now my problem is I want to do this same procedure for both 12 and 13 of finding and labelling the indexs for 12 and 13 being (1,2) and (3,4). Is there a way to repeat that code for both idx of 1,2,3 and 4? because the real dataset has over 5000 data points in it...
Do you understand what I mean?
Thanks
James
All you really want to do is find wherever matrix(:,1) contains one of the numbers you've already found, include the numbers in the second and third columns into your group list (presuming they aren't already there), and stop when that list stops growing, right? This may not be the most efficient way of doing it but it gives you the basic idea:
while ~(numel(oldnum)==numel(num))
oldnum = num;
idx = ismember(matrix(:,1),oldnum)
num = unique(matrix(idx,:))
end
Output:
num =
1
2
3
4
12
13
14
Now if your first column is literally just your numbers 1 through 5000 in order, you don't need to even find the index, you can just use your number list directly.
To do this for multiple groups you would just need an outer loop that stores the information for each group, then picks out the next unused number. I'm presuming that your individual groups are consistent so that no matter which of those numbers you pick you end up with the same result - e.g. starting at 2 or 14 gives you the same result (if not, it becomes more complex).

What is wrong with my simple matlab code

(X^2)(1,2)
X is a square matrix, I just want to get the element from position (1,2) from (X^2) why it does not work?
Indexing is syntactically not allowed in this case. The simplest workaround is to use getfield
X=magic(5)
X =
17 24 1 8 15
23 5 7 14 16
4 6 13 20 22
10 12 19 21 3
11 18 25 2 9
>> getfield(X^2,{1,3})
ans =
725
That's not how Matlab works. You need to assign the result of the matrix multiplication to another matrix, then use it:
A = X^2;
disp(A(1,2));
This is assuming that you really did mean to do matrix multiplication, and not multiply element by element. In the latter case you could have done
disp(X(1,2)^2)
And if you are interested in matrix multiplied result, then
disp(X(1,:)*X(:,2))
will do it, since that is how element (1,2) is calculated. This last solution has the advantage of being very efficient since you only calculate the element you need, instead of computing the entire matrix and throwing N^2-1 elements away just to keep the one. For bigger matrices that will make a difference. Of course it makes the code slightly less readable so I would always recommend writing a comment in your code when you do that - your future self will thank you...
edit take a look at http://www.mathworks.com/matlabcentral/newsreader/view_thread/235798 - that thread broadly agrees with my first statement, although it hints that the syntax you desire might be "part of a future release". But that was said 6 years ago, and it's still not here... It also shows some pretty obscure workarounds; I recommend not going that route (because all the workarounds do is hide the fact that you compute the matrix, then pick just one element. So the workload on the computer is no smaller.)

Accumarray how to set "fun" to use only last obs of each bin

Is there a way to let accumarray drop every observation but the last of each group?
What I had in mind was something similar:
lastobs=accumarray(bin,x,[],#(x){pick the observation with the max index in each group};
To give you an example, suppose I have the following:
bin=[1 2 3 3 3 4 4]; %#The bin where the observations should be put
x= [21 3 12 5 6 8 31]; %#The vector of observations
%#The output I would like is as follow
lastobs=[21 3 6 31];
I am actually thinking of accumarray only because I just used it to compute the mean of the observations for each bin. So every function that could make the trick would be fine for me.
Of course you can do this with accumarray. x(end) is the last observation in an array. Note that bin needs to be sorted for this to work, so if it isn't, run
[bin,sortIdx]=sort(bin);x = x(sortIdx); first.
lastobs = accumarray(bin(:),x(:),[],#(x)x(end)); %# bin, x, should be n-by-1
You already got your accumarray answer, but since you are looking for any solution that will do the job, consider the following application of unique.
Using unique with the 'legacy' option gives the index of the last occurrence of each value, as you need:
>> [~,ia] = unique(bin,'legacy')
ia =
1 2 5 7
>> lastobs = x(ia)
lastobs =
21 3 6 31
Now, I love accumarray, as many here are aware, but I actually prefer this solution.

MATLAB: Step through iterations of a vector

all.
I have a 15 element array = [1 2 3 4 5 6 7 8 9 10 11 12 13 14 15];.
I was wondering if there was a command such that it would step through iterations of the array without repeating itself. In other words, since there is a chance that randperm() will create the same matrix twice, I want to step through each permutation only once and perform a calculation.
I concede that there are factorial(15) permutations, but for my purposes, these two vectors (and similar) are identical and don't need to be counted twice:
[1 2 3 4 5 6 7 8 9 10 11 12 13 14 15]
[15 14 13 12 11 10 9 8 7 6 5 4 3 2 1]
Thus, is there any way to step through this?
Thanks.
I think what you are looking for is perms. randperm returns a single random permutation, you want all the permutations.
So use
my_permuations = perms([1:15]);
If forward-backward is the same as backward-foward then you can use the top half of the list only...
my_permutation_to_use = my_permutations(1:length(my_permutations)/2, :);
You may compare all permutations, but this would require to store all past permutations. Instead a local decision is better. I recommend this simple rule:
A permutation is valid, if the first element is smaller than the last element.
A permutation is redundant, if the first element is larger than the last element.
For small sizes, this could simply be done with this code:
%generate all permutations
x=perms(1:10)
%select only the valid lines, remove all redundant lines
x(x(:,1)<x(:,end),:)
Remains the problem, that generating x for 1:15 breaks all memory limits and would require about 100h.

Matlab general matrix indexing for accesing several rows

Edit for clarity:
I have two matrices, p.valor 2x1000 and p.clase 1x1000. p.valor consists of random numbers spanning from -6 to 6. p.clase contains, in order, 200 1:s, 200 2:s and 600 3:s. What I wan´t to do is
Print p.valor using a diferent color/prompt for each clase determined in p.clase, as in following figure.
I first wrote this, in order to find out which locations in p.valor represented where the 1,2 respective 3 where in p.clase
%identify the locations of all 1,2 respective 3 in p.clase
f1=find(p.clase==1);
f2=find(p.clase==2);
f3=find(p.clase==3);
%define vectors in p.valor representing the locations of 1,2,3 in p.clase
x1=p.valor(f1);
x2=p.valor(f2);
x3=p.valor(f3);
There is 200 ones (1) in p.valor, thus, is x1=(1:200). The problem is that each number one(1) (and, respectively 2 and 3) represents TWO elements in p.valor, since p.valor has 2 rows. So even though p.clase and thus x1 now only have one row, I need to include the elements in the same colums as all locations in f1.
So the different alternatives I have tried have not yet been succesfull. Examples:
plot(x1(:,1), x1(:,2),'ro')
hold on
plot(x2(:,1),x2(:,2),'k.')
hold on
plot(x3(:,1),x3(:,2),'b+')
and
y1=p.valor(201:400);
y2=p.valor(601:800);
y3=p.valor(1401:2000);
scatter(x1,y1,'k+')
hold on
scatter(x2,y1,'b.')
hold on
scatter(x3,y1,'ro')
and
y1=p.valor(201:400);
y2=p.valor(601:800);
y3=p.valor(1401:2000);
plot(x1,y1,'k+')
hold on
plot(x2,y2,'b.')
hold on
plot(x3,y3,'ro')
My figures have the axisies right, but the plotted values does not match the correct figure provided (see top of the question).
Ergo, my question is: how do I include tha values on the second row in p.valor in my plotted figure?
I hope this is clearer!
Values from both rows simultaneously can be accessed using this syntax:
X=p.value(:,findX)
In this case, resulting X matrix will be a matrix having 2 rows and length(findX) columns.
M = magic(5)
M =
17 24 1 8 15
23 5 7 14 16
4 6 13 20 22
10 12 19 21 3
11 18 25 2 9
M2 = M(1:2, :)
M2 =
17 24 1 8 15
23 5 7 14 16
Matlab uses column major indexing. So to get to the next row, you actually just have to add 1. Adding 2 to an index on M2 here gets you to the next column, or adding 5 to an index on M
e.g. M2(3) is 24. To get to the next row you just add one i.e. M2(4) returns 5.To get to the next column add the number of rows so M2(2 + 2) gets you 1. If you add the number of columns like you suggested you just get gibberish.
So your method is very wrong. Freude's method is 100% correct, it's much easier to use subscript indexing than linear indexing for this. But I just wanted to explain why what you were trying doesn't work in Matlab. (aside from the fact that X=p.value(findX findX+1000) gives you a syntax error, I assume you meant X=p.value([findX findX+1000]))