Pseudo-code from some MIT courseware - pseudocode

I've never had much need for writing large quantities of formal pseudo-code but the need has arisen, so I thought I'd pick some standards in order to stay consistent across code.
To that effect I picked up some "iTunes U" courseware videos, amongst other things the 6.046J / 18.410J Introduction to Algorithms (SMA 5503).
In the very first lecture video, the lecturer writes Insertion Sort on the blackboard, and he writes this:
Insertion-Sort(A, N) // Sorts A[1..n]
for j ← 2 to n
do key ← A[j]
i ← j-1
while i > 0 and A[i] > key
do A[i+1] ← A[i]
i ← i-1
A[i+1] ← key
So, my questions:
Why i ← j-1 when A[i+1] = key? That is, why ← in some cases, and = in another? Note that in the above code, the ← is used for the latter too, but in the handouts, available on the web, = is used, is this simply a typo? (I assume so)
More important, why do key ← A[j] when i ← j-1? What is so special that it requires a do command like that, and an indentation?
In other words, why isn't the above pseudo-code written like this (with my highlights):
Insertion-Sort(A, N) // Sorts A[1..n]
for j ← 2 to n
key ← A[j] <-- lost the do here
i ← j-1 <-- no indentation
while i > 0 and A[i] > key
A[i+1] ← A[i] <-- lost the do here
i ← i-1 <-- no indentation
A[i+1] ← key
Final question: Does anyone have a code standard for pseudo-code handy somewhere? My main goal is consistency, so that I only have to "teach" the recipients once.

Structured English is a 'standardised' pseudo-code language.

the arrow serve as = in normal code.
equal sign in pseudo serve as == in normal code
so j <- 1 mean j = 1
and j = 1 mean if( j == 1)

Related

Insertion Sort INVALID DIMENSION error in BASIC

I'm tearing my hair our trying to understand why the following insertion sort program in TI-BASIC works sometimes but gives a dimension error other times.
0→dim(L₁ // clear the list L1
randIntNoRep(1,5,5)→L₁
For(I,2,5)
L₁(I)→K
I-1→J
While J>0 and L₁(J)>K
L₁(J)→L₁(J+1)
J-1→J
End // end while
K→L₁(J+1)
End // end for
Disp L₁
As far as I can tell the code is a faithful implementation of Insertion Sort based on this pseudocode:
for i ← 2 to n
key ← A[i]
j ← i − 1
while j > 0 and A[j] > key do
A[j + 1] ← A[j]
j ← j − 1
A[j + 1] ← key
I've tried stepping through the code manually and it looks like the BASIC version does the same as the pseudocode. What am I missing please?
OK I see the problem. TI-BASIC doesn't appear to do short circuit Boolean evaluation, so it sometimes tries to access the list at index 0, and fails. Refactoring in TI-BASIC is a real pain as there isn't even a break statement.

Why does j = n + 1 in the termination loop invariant of the insertion sort algorithm?

I am currently reading chapter 2 of the TCRC Introduction to Algorithms 3rd edition textbook and I am reading the author's interpretation of the loop invariant of this algorithm. I understand the author's logic for both the initialization and the maintenance. However, the termination is what I am kind of bogged up on. The author claims that at termination, j = n + 1. However, in the pseudocode of the algorithm, j loops from 2 to n. So shouldn't j = n - 1?
EDIT: The book's pseudo-code for insertion sort is:
for j = 2 to A.length
key = A[j]
// Insert A[j] into sorted sequence A[1...j - 1]
i = j - 1
while i > 0 and A[i] > key
A[i + 1] = A[i]
i = i - 1
A[i + 1] = key
EDIT: After reading it carefully, I have finally understood why j = n + 1 during termination. It's because the for loop goes from 2 to n (inclusively), so after j exceeds n, the loop terminates, hence why j = n + 1 at termination. I appreciate the help.
Disclaimer: this can be totally incorrect... It is just a brain spit.
Side note: since j is incremented during this loop, the starting point is irrelevant for the end condition.
for j = 2 to A.length //A.length = n in your question
There is a bit of ambiguity in this pseudo code.
First of all, we assume j is defined outside this for loop and will have an end value when the loop is terminated. see #Dukeling's comment
Second, your code is targeting an array, using the j as indexer: A[j]
The ambiguity exist with the word to in for j = 2 to A.length, is it including or excluding A.length? and there is this indexer A[j]
In common cases, for the indexer in A[j], the valid range for j is [0...A.length -1]
Some languages uses another range, namely: [1...A.length] I think this is intended by the author because A[0] is not being hit at all.
If that's the case.... and the for condition increments j before it breaks the loop (to test the condition and see that it is false), then... you'll get j = A.length + 1.
As a side note:
In common C like languages, arrays have a valid range from [0...A.length -1].
And in this C example, c has the value of A.length after termination:
int c = 0;
for (c = 3; c < A.length; c++)
{
}
//c = A.length after the loop is completed.

Understanding confusing algorithm notation

I'm having trouble understanding the notation used by a book in describing a prng testing algorithm. Here are some of the snippets in question:
My confusion is: what is the significance of of j? It's not well defined at all. Is it supposed to be the index of the vectors? How does it not start from 0 then?
Continuing on:
I get that the left arrow is assignment. But again the algorithm is referring to j and only referring to j0 and j1. Again, it seems like it would be the indices of j. But then I'm especially confused by the line, "Then for j <- j, j1 - 1 ..., j0 " because it seems like it's referring to deincrementing the index of j, but it's subtracting from j itself and not the subscript.
Any help much appreciated, thanks.
It appears to me that there are multiple independent uses of j here. This is typical of CS texts written by mathematicians, who -- you might be surprised to learn -- are often very sloppy indeed about their notation, expecting the reader to glark all sorts of things from implicature and context.
In the first paragraph, the author uses V[j] to refer to an arbitrary element of an array of 20-element vectors (and j does start from zero). They are defining how to fill this array of fixed-width vectors (you might find it more comfortable to think of this as a 2-dimensional array) from a 1-dimensional stream of random numbers. Maybe it helps if I write out the first two rows of the array explicitly?
V0 = (Y0, Y1, Y2, ... Y19)
V1 = (Y20, Y21, Y22, ... Y39)
⋮
Vj = (Y[j*20], Y[j*20+1], ... Y[j*20+19])
In the second paragraph, A[j] is again an arbitrary element of an array, but it's a different, unrelated, array of floating-point numbers.
In the third and fourth paragraphs, j, j0, and j1 appear to be three separate index variables, and the situation is made more confusing by cramming an algorithm into prose. The author ought to have used pseudocode and chosen better variable names. Here is an attempt to produce a pseudocode version - I deliberately kept the bad variable names, though, so you can see the correspondence.
Algorithm_S (m, n):
# S1: Initialize.
var A: float[n+1]
var j, j0, j1: int
for j in 0, 1, ..., n:
A[j] ← 0
A[1] ← 1
# S2: Update probabilities.
j0 ← 1
j1 ← 1
repeat n-1 times:
j1 ← j1 + 1
for j in j1, j1 - 1, ..., j0:
A[j] ← (j/m)*A[j] + (1 + 1/m - j/m)*A[j-1]
if A[j] < 1e-20:
A[j] ← 0
if j = j1: j1 ← j1 - 1
if j = j0: j0 ← j0 + 1
# S3: ...
I'm not sure this is correct, because it doesn't make a whole lot of sense to me even after unpacking it like that. The problem is probably that you only quoted the first two steps of the algorithm, so I don't know what this "auxiliary array of probabilities" will be used for and I can't tell if the code should do what it's doing. Don't worry about it.
In summary: you are confused because this book is confusing. It is not your fault. I would recommend you find a book that is less confusing, and maybe come back to this one when you have had a good deal more practice reading math journal articles.
j is a dummy variable. When you write A[j] for j0 <= j <= j1 it serves as a placeholder to denote all the elements of A at indexes between j0 and j1.
When you will program the algorithm, you will probably declare one or more loop variables to reflect this.

Get random values without replacement given a probability distribution

Given a probability distribution – a mapping of objects to their probability – I want an algorithm that selects random objects from the map and is without replacement (the probability distribution is updated per selection). However, the algorithm must have an O(1) space complexity and have high quality randomness. I tried searching for implementations, but none of them seemed to have both of these properties.
EDIT:
Probability without replacement:
You have a bag of objects, each object has a probability of being selected. Once you select an object, you remove it from the bag. All objects now a different probability of being selected.
With O(1) space complexity, we are not storing a list with objects repeated according to their probability of being selected. Instead, we are only storing a probability distribution and iterating over a permutation (but not storing that permutation).
I would try variation of Fisher-Yates-Knuth shuffle (in Durstenfeld implementation it is O(1))
Original:
for i from 0 to n − 1 do
j ← random integer such that 0 ≤ j ≤ i
if j ≠ i
a[i] ← a[j]
a[j] ← source[i]
Modified to fulfill requirements:
for i from 0 to n − 1 do
p ← probabilities(n-i)
j ← random integer via probabilities(n-i) such that 0 ≤ j ≤ i
if j ≠ i
a[i] ← a[j]
a[j] ← source[i]
So at each step you would update probabilities and use them to sample index. After that it's just FYK shuffle.

Partition method

I am trying to understand exactly what this method does, it say its suppose to
"Keep swapping the outer-most wrongly-positioned pairs". I put this into a program
and tried different array but the result make no sense to me, what exactly does this do
partition(A, p)
A: array of size n, p: integer s.t. 0 <= p < n
1. swap(A[0],A[p])
2. i <- 1, j <- n − 1
3. while i < j do
4. while A[i] <= A[0] and i < n do
5. i <- i + 1
6. while A[j] > A[0] and j > 0 do
7. j <- j − 1
8. if i < j then
9. swap(A[i], A[j])
10. swap(A[0], A[j])
11. return j
The algorithm this pseudocode implements is the partitioning phase of the quicksort sorting algorithm. It will arrange the array so that all values smaller than or equal to A[p] are at the left and all larger values at the right. It returns the index j that is the last index of the left side for which A[j] equals A[p].
If you are not familiar with quicksort, the intent is to use this partition algorithm to split the array into "small" and "large" parts and recursively sort each part. Since the small ones had been arranged to come before the large ones in the array, the array gets sorted. If p is picked appropriately so that A[p] is close to the middle of the values in A, this is a very fast sorting method.

Resources