Table of Contents

Johanna's Journal

Preface Summary



Due to the often detail-muddled nature of algorithmic problems, the formation of algorithms has two components. First one must find the mathematical wording of the problem that makes it solvable through algorithms. Then one must identify the proper algorithm design techniques that befit the problem. I don't really have any questions about the preface, but I am interested to see throughout the course and the book what type of detail we go into when solving problems regarding real cs implementation (i.e. specificity of control structures and collection types, etc.).

Chapter 1.1 Summary



This chapter begins by introducing the problem which inspired the Gale-Shapley Stable Matching Algorithm. Initially the problem is a question of matching applicants with companies in a way that stops applicants from leaving their new employer for a preferred employer that will take them. In a word, we want the pairing of applicants and employers to be “self-enforcing”. This question can also be applied to matching residents with hospitals.
The first step in coming up with an algorithm to solve this problem is formulating the problem. We can simplify it by not worrying about companies looking for multiple applicants. Instead we will just consider n companies each searching for one of n applicants. This representation of the problem is applicable to a broader, extended case as well. Now this problem is the exact problem we solved in class with matching n men and n women.
In order to design the algorithm, we must explore certain fundamental ideas motivating it. The components of our problem are a set of single men, a set of single women, a list of each woman’s ranked preferences in men, and a list of each man’s ranked preferences in women. Note that initially everyone is unmarried and the goal is to marry everyone stably. The initial step will involve an unmarried man choosing his highest ranked woman and proposing to her. We will use engagement as an intermediate step between singleness and marriage because it is dangerous for this woman to reject this man in case no other man proposes to her but she is not fully committed until every other man is engaged. Now consider a state where some men and women are still not engaged and some are engaged. It would make sense to have a random single man choose the highest ranked woman on his list and propose to her. If she is engaged and prefers her current man, she will reject this arbitrary man. If she is engaged and prefers the arbitrary man, she will break her current engagement and accept the proposal. Then her ex will become single. If she is single, she will automatically accept his proposal. The algorithm terminates when no one is free anymore.
The next step is analyzing the algorithm to see if it returns a stable matching, and even a perfect matching. As discussed in class, we know a woman w becomes engaged and does not go back to being single. Her current partner can only improve in terms of her preference list. We know that a man m starts single and can get engaged but can still go back to being single. Each time he gets engaged, his current partner will get worse and worse in terms of his preference list. As proven in class, we know that the algorithm terminates after at most n2 iterations. Since we have already discussed proofs 1.3, 1.4, 1.5, 1.6 in class, I will not go into the details here.
Upon evaluation of the algorithm, it is clear that the G-S algorithm is not fair to one of the two groups represented depending on who does the “proposing”. In the marriage example, men are favored because they propose. If they all list different women as their highest ranked woman, they each get married to their favorite woman regardless of the women’s preference lists. Therefore, the algorithm favors whoever does the proposing.
All executions of the G-S algorithm yield the same matching. A woman w is a valid partner for man m if there exists a stable matching that contains the pair (m, w). W is the best valid partner for m if w is m’s highest ranked woman who is a valid partner. According to proof 1.7, every matching created by the G-S algorithm results in the set of pairs where each man is matched with his best valid partner. This can be proven by way of contradiction. In this same way, we find that women are always paired with their worst valid partner.
In the future, will we discuss the idea of algorithm “fairness” in more detail? It seems like in all the possible uses of the G-S algorithm discussed here, fairness is a very important factor so I can't imagine we will continue to settle for “unfair” solutions?
I found this chapter to be a 3 because we already discussed most of the information in very great detail in class.

Chapter 2.1 Summary



In studying the creation of efficient algorithms, we look to study discrete problems without much irrelevant detail. The algorithms we work with will encompass vast combinatorial possibilities, like the Stable Matching Problem. Computational efficiency is paralleled by efficiency in running time, which is more measurable. We must also keep in mind memory/space, one of our other important resources when designing efficient algorithms.
It is hard to define efficiency without using arbitrary words like “quickly”. The proposed definition of efficiency leaves out the idea of how well an algorithm will scale as problem sizes grow as well as the idea of where the algorithm will be implemented. A good way to tell how impressive or efficient an algorithm is is to check it against the search space it defines. In the Stable Matching problem, the search space is n! because that is how many possible matches can be made between n men and n women, but it completes in O(n2) time, so that is pretty impressive!
So our new definition of efficiency, based off this new criteria, is “achieves qualitatively better worst-case performance, at an analytic level, than brute-force search”.
But now we have this vague term, “qualitatively better worst-case performance”. We can remedy this by considering polynomial running time. If a solution’s scaling behavior when the input size is increased is always a constant, the solution is efficient. This can be achieved by a polynomial-time algorithm or better. So the new definition of efficiency becomes “it has a polynomial running time.”
The greatest benefit of having such a specific definition of efficiency is that we can now definitively express whether or not an efficient solution exists to every problem. With our original ambiguous definition, this was not the case at all.
Is this final definition of efficiency the commonly observed rule among computer scientists? I feel like the rule of thumb for efficiency should really depend more on the problem at hand than anything. Polynomial-time is definitely good for large problems but it seems like a big generalization to say that this is always an efficient running time for an algorithm.
I give this chapter a 6 out of 10 because it presents some new information and it cracks a few solid jokes.

Chapter 2.2 Summary



So far we have determined that an algorithm’s worst-case running time on inputs of size n is bounded above by some function f(n). It is easier and more meaningful to speak of f(n) in terms of its greatest degree instead of as a complete function (i.e. it is better to say a function is O(n2) than to say that it took 16n2 + 3.5n + 8 steps). Our regular O notation is used to represent asymptotic upper bounds of algorithms, which we have already discussed plenty. Asymptotic upper bounds bound our algorithm’s steps (T(n)) from below, so it they are sort of underestimations of our algorithm’s run-time. They are meant to be simplified in the same way as regular O-notation. An asymptotically tight bound grows exactly the way our algorithm function does to within a constant factor. This function represents an instance in which our algorithm function’s asymptotic upper bound is equal to its asymptotic lower bound. The tight bound can be found by closing the gap between the upper bound and the lower bound and occasionally by finding the limit as n goes to infinity.
All of the aforementioned bounds share the property of transitivity. We discussed this in class too. To further expand upon the idea of polynomial-time algorithms, it is important to realize that polynomials do not always take the form of n to a degree d that is independent of n. An algorithm with T(n) of O(nlogn) is also polynomial-time, as is O(√n). Logarithmic-time algorithms are even slower-growing than polynomial-time algorithms and exponential-time algorithms are much larger than all polynomial and logarithmic-time algorithms over large input sizes. These generalizations are all hard to see with small input sizes, but as input size increases they hold true.
I know the text said we want to avoid coming up with O(f(n)) with super specific f(n) functions, but I am curious as to how one would even compute a long polynomial function for run-time to begin with.
5/10 for interesting-ness.

Chapter 2.3 Summary



Chapter 2.4 Summary

Chapter 2.5 Summary

Chapter 3.1 Summary

Chapter 3.2 Summary

Chapter 3.3 Summary

Chapter 3.4- 3.6 Summary

Chapter 4 Intro and 4.1 Summary

Chapter 4.2 Summary

Chapter 4.4 Summary

Chapter 4.5 Summary

Chapter 4.6 Summary

Chapter 4.7 Summary

Chapter 4.8 Summary

Chapter 5.1 Summary

Chapter 5.2 Summary

Chapter 5.3 Summary

Chapter 5.4 Summary

Chapter 6.1 Summary

Chapter 6.2 Summary

Chapter 6.3 Summary

Chapter 6.4 Summary

Chapter 7.1 Summary

Chapter 7.2 Summary