I'm trying to understand how a skip list works for insertion, but when I draw it out, it doesn't work out.
|-inf<---------------------------->+inf|0
|-inf<--------->4<---------------->+inf|1
|-inf<--------->4<--->9<--->11<--->+inf|2
|-inf<--->1<--->4<--->9<--->11<--->+inf|3
So I want to insert 5 on the above linked list.
Start on row 0: Start at -inf, compare 5 to +inf, move to next row.
Move to row 1:
Is 5 <= 4, no. Compare to what's on the right, +inf. Move down from the element 4 to row 2.
Move to row 2:
Now we're traversing between 4 and 9, so the comparison would be something like is 5 <= 4? No. Is 5 <= 9? Yes. Insert between 4 and 9.
But now 5 doesn't show up on row 3?
What am I doing wrong?
When you see that 5 <= 9, you have to keep going down until you reach the bottom. There could be any number between 4 and 9 still in one of the lower levels. When you determine its location in the bottom row, you insert it there, and then start inserting it one row higher depending on the outcome of an RNG. The full sequence for your insertion is then something like:
5 > +inf? No: move down.
5 > 4? Yes: move to right.
5 > +inf? No: move down.
5 > 9? No: move down.
5 > 9? No: move down.
Couldn't move down in previous step, so insert between 4 and 9 at bottom level.
Probabilistically add 5 to higher rows.
Related
Is there a rule for how to split the node in 2-3-4 tree?
E.g. If I insert 3, 7, 4, 9 into the 2-3-4 tree:
Will it be split like this (yellow) or that (green) as shown here:
Are both valid?
Green. You need to consider the algorithm steps. Check out the the wikipedia page for insertion steps. The key part is to split a 4-node (which has 3 values) by moving the middle value up a level before considering the next insert.
1. Insert 3 into blank. Result: 3 (a 2-node)
2. Insert 7. Result: 3 - 7 (a 3-node)
3. Insert 4. Result: 3 - 4 - 7 (a 4-node)
5. Insert 9. There is already a 4-node, so this must be split.
The split will be to move 4 up a level, and 3 and 7 are now child nodes of 4
(like your green diagram). 9 is then added next to the 7.
I'm trying to learn designing a btree.
Here are the values to develop a btree of order 5.
1,12,8,2,25,6,14,28,17,7,52,16,48,68,3,26,29,53,55,45,67.
When I insert 25, it breaks into child nodes
8
/ \
1 2 12 25
may I I know on what basis 8 comes up as parent ? Why not any other number ? What if the order of btree would be 4 ?
In a B-tree of order 5 each node (except the root) must have 2 to 4 values in it.
At the point you enter 25, the node has the values 1,2,8,12. In order to have at least 2 values in each new child (1,2) and (12,25) you have to split at 8.
Before inserting 25, the node state is like this:
Full node: 1, 2, 8, 12. Items in node are always sorted in B-tree.
When you insert the new item 25, the sequence becomes: 1, 2, 8, 12, 25.
In this sequence the middle item is the one that is promoted up.
A node split divides the data items equally: Half go to the newly created node,
and half remain in the old one and the middle one goes up. This is the reason why 8 goes upward.
The following figures contain a B-tree of order 5 and should help understand this situation better although the data inserted is different. In the sequence on right-side, the arrow indicates the item to be promoted upward.
Using a list of 15 numbers, I need to give a list representing the best and worst case scenario. It says "q.s. uses the first item in the list as the pivot item". I'm not sure if I pick the first item as pivot every time, but that's what I'm assuming....
For best case scenario.. I came up with (bold for pivot, italic for bigger and smaller than markers):
8 1 3 2 6 5 7 4 12 9 11 10 14 13 15
4 1 3 2 6 5 7--8--12 9 11 10 14 13 15
2 1 3 --4--6 5 7........8........10 9 11--12--14 13 15
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
Hope someone can here can verify my work and if it's wrong, point out to me how and why.
A condition for the best case for Quicksort is that the pivot always goes right smack in the middle (except perhaps in the very last stages), so much is definitely correct. On top of that you want as few swaps as possible, the precise configurations for that depend on the implementation details.
One common implementation is to first swap the pivot into the last place, then arrange the others so that the elements smaller than (or equal to) the pivot come before the larger elements and finally swap the pivot (from last place) with the first of the larger elements (then recur).
Another method is to put the pivot into the first slot before arranging and swap it with the last not exceeding the pivot after.
For the absolute best case, these strategies require different configurations. For example,
4 1 3 5 6 7 2
is a best case scenario for the 'swap pivot into last place' variant, while
4 1 3 2 6 5 7
is a best case for 'pivot stays put'.
The worst case scenario is when the pivot always goes to one of the ends of the array, precise details again depend on the implementation, but sorted or reverse sorted are usually worst cases.
It looks correct to me. If you are using quicksort with first element as the pivot then you want the first element to be the middle value of the array. The ideal pivot has an even amount of elements on each side.
I have a row with numbers 1:n. I'm looking to add a second row also with the numbers 1:n but these should be in a random order while satisfying the following:
No positions have the same number in both rows
No combination of numbers occurs twice
For example, in the following
Row 1: 1 2 3 4 5 6 7 ...
Row 2: 3 6 15 8 13 12 7 ...
the number 7 occurs at the same position in both rows 1 and 2 (namely position 7; thereby not satisfying rule 1)
while in the following
Row 1: 1 2 3 4 5 6 7 ...
Row 2: 3 7 15 8 13 12 2 ...
the combination of 2+7 appears twice (in positions 2 and 7; thereby not satisfying rule 2).
It would perhaps be possible – but unnecessarily time-consuming – to do this by hand (at least up until a reasonable number), but there must be quite an elegant solution for this in MATLAB.
This problem is called a derangment of a permutation.
Use the function randperm, in order to find a random permutation of your data.
x = [1 2 3 4 5 6 7];
y = randperm(x);
Then, you can check that the sequence is legal. If not, do it again and again..
You have a probability of about 0.3 each time to succeed, which means that you need roughly 10/3 times to try until you find it.
Therefore you will find the answer really quickly.
Alternatively, you can use this algorithm to create a random derangment.
Edit
If you want to have only cycles of size > 2, this is a generalization of the problem.
In it is written that the probability
in that case is smaller, but big enough to find it in a fixed amount of steps. So the same approach is still valid.
This is fairly straightforward. Create a random permutation of the nodes, but interpret the list as follows: Interpret it as a random walk around the nodes, and if node 'b' appears after node 'a', it means that node 'b' appears below node 'a' in the lists:
So if your initial random permutation is
3 2 5 1 4
Then the walk in this case is 3 -> 2 -> 5 -> 1 -> 4 and you creates the rows as follows:
Row 1: 1 2 3 4 5
Row 2: 4 5 2 3 1
This random walk will satisfy both conditions.
But do you wish to allow more than one cycle in your network? I know you don't want two people to have each other's hat. But what about 7 people, where 3 of them have each other's hats and the other 4 have each other's hats? Is this acceptable and/or desirable?
Andrey has already pointed you to randperm and the rejection-sampling-like approach. After generating a permutation p, an easy way to check whether it has fixed point is any(p==1:n). An easy way to check whether it contains cycles of length 2 is any(p(p)==1:n).
So this gets permutations p of 1:n fulfilling your requirements:
p=[];
while (isempty(p))
p=randperm(n);
if any(p==1:n), p=[];
elseif any(p(p)==1:n), p=[];
end
end
Surrounding this with a for loop and for each counting the iterations of the while loop, it seems that one needs to generate on average 4.5 permutations for every "valid" one (and 6.2 if cycles of length three are not allowed, either). Very interesting.
There is a matrix with m rows and n columns. The task is to find the maximum sum choosing a single element from each row and column. I came up with a solution, which finds the maximum from the whole matrix and then sets that row and column as zero adds it to the sum and proceeds with finding the next max. This repeats m times.
But the problem with this approach was if there is repetitive elements. I'll try to explain it with an example. Here is the matrix..
3 6 5 3
9 4 9 2
8 1 4 3
4 7 2 5
Now, if I follow the above method.. sum will be 9 + 7 + 5 + 3 whereas it should be 9 + 8 + 7 + 3. How to solve this problem.. I'm stuck
Update: The columns are cost of seats which can be assigned to a person and the rows are number of persons. We want to assign them in such a way, so that we get the max cost.
Isn't this just http://en.wikipedia.org/wiki/Assignment_problem, typically solved by http://en.wikipedia.org/wiki/Hungarian_algorithm? Obviously, you want a maximum rather than a minimum, but surely you can achieve that by maximising for costs that are -(the real cost) or, if you are worried about -ve costs, (Max cost in matrix) - (real cost).
Your algorithm is wrong - consider a slight change in the matrix, where the second 9 is 8:
3 6 5 3
9 4 8 2
8 1 4 3
4 7 2 5
Then your algorithm has no problem in finding 9, 7, 5, 3 (no duplicates), but the correct answer is still 8, 8, 7, 3.
You can brute force it, by trying all combinations. One good way to put that into code is to use a recursive function, that solves the problem for any matrix:
In it you would iterate through say the first row and call the function for the submatrix obtained by deleting the correspondent row and column. Then you would pick the highest sum.
That, of course, will be too slow for large matrixes. The complexity is O(N!).