2014年8月28日星期四

[Course Review]: Algorithms II by Tim Roughgarden

I was just watching House of Cards, and I am at the episode that Peter Rosso was killed. I am so sad, I like that guy. I was hoping he would turn down that girl, I was hoping he never touches that whiskey, and I was hoping he never raises another bottle again. I was just thinking that how stupid he is to give up that easily, and trust somebody he shouldn't. Then I thought about myself, having my days filled with small stuffs, abusing my time on social network and TV. I might as well stop taking the "drink" myself.

Back to the algorithm course I want to talk about. The course ended last week, I cannot say I am doing great at this course, but I am happy with a grade that allows me to pass. This made it the first course that I passed from Coursera. It is not easy for me at all. I had only vague memory about my data structure and graph theory course, and this lecture forced me to review most of them. I choose C++ to be the programming language for the exercise, and this is particularly painful since my last time dealing with pointers is 6 years ago. And I started it when I was writing my master thesis (I finished the whole thesis thing 3 weeks before this course ended, otherwise I don't know if I can pass). So I think I am allowed to be proud that I passed.

There is a lot of compliment for this course online and they are speaking of my opinion. Hard content, nice structure, great lectures, and tough exercises. What I also see is that there is a lot effort in this course, I don't know exactly how much, but I know there is a lot. I occasionally view the Algorithm I archive because I haven't taken it. I can tell that there is a lot of progresses in Part II from Part I, although they come from the same professor, and really are close in time. This is a team that really works to make the course better and better. The TAs in the forum are awesome, I am very surprised at how well they know about algorithms and how devoted they are to answering questions from the students.

So what do I learn from the course. First, I got adapted to C++ though the exercises. I am far from an expert, but I am comfortable using C++. I also got a better sense on the memory that a program might use, partly thanks to my 2GB RAM. On the contrary, I care less about time. It is not to say that time is not important, but a large part of it has been taken care of by those "blazingly fast" algorithms we learned. For me, the bottleneck is always the memory.

Second, and I think more importantly, I have a better sense about algorithm. I used to view algorithms, or at least the algorithms course as just one part of computer science. You have to take it so you know how to program. But what I learned from the course is that single algorithm does not matter (of course, it would matter for a specific problem, but I mean to the knowledge of a person). I watched the course, I did the exam, I implemented the algorithms, but I am sure that I will forget most of the details right away if I don't use them. But that's not a problem. We will only use a few of the algorithms if ever, and we can always look them up when we need. The real issue is, through these examples, we know how to properly design an algorithm for a new problem, where should we start, what's the possible hint.

Third, about the designing paradigms, greedy algorithm, divide and conquer, dynamic programming. Greedy algorithm is, well, greedy. I think it would be the least useful in the real world since you have the make the right call every turn, there is no turning back and correct. Divide and conquer and dynamic programming are in themselves the same. The key issue is to break a problem down into smaller problems. The difference is that divide and conquer has much smaller subproblems, usually half the size of the original one, that's why in the running time there is always a log(n). I think it is always a nice way to think when we encounter a problem, can we break it down to smaller easier problems.

Fourth, the NP-complete. One third of this course is devoted to NP-complete. And this is the part that I least understand. I like the philosophical explanation for the P != NP, which is that checking if the answer is correct should be strictly much easier than finding the answer. I am also glad that this is still an open question. I always thought NP stands for N particles, which is also an unsolvable (or unsolved) issue, I wonder how they would connect. Among the 3 ways to deal with the NP-complete problem that Professor Roughbgarden proposed, I like the second one best which is instead of an accurate answer, we look for a "nearly the best" or even "not so bad" one with reasonable amount of resources. It outlines how people usually work with their problems. For real problems, I mean real problems in the real world, no one is doing brute-force search to find the best choice, this is usually unacceptably expensive if it is ever possible. Instead, people relies a lot on experience, on intuition. Nobody can say that they make the best decision overall, but usually people are doing OK, right? We want computer to think like human, maybe we should start by making it less good at math.

I couldn't help but think about the link between physics and algorithms. Is physics itself an algorithm? Is Newton's laws just the best algorithm for predicting the trajectories of stars, how we could approach this task otherwise, is there other maybe less efficient algorithms? What about the time axis that a physics problem usually have, does it make any difference to the algorithms we are learning? If the world is deterministic (this is an abandoned idea because of the finding of quantum physics and chaos, but nobody can actually know this for sure), meaning we have full prediction of the future if we have enough information about the present, does this lead to an algorithm solving the "Halting" problem? Or, does the restriction on the algorithms reflect the unpredictability in the real world?

Finally, thanks to the team of this course, I benefit a lot from it.

2014年8月21日星期四

Small tricks

This to keep track of the small tricks I run into that may be useful.

1. pause in C++
system("pause"): this is not a very good way to pause in C++ because it relies on the platform you compile and run. It does not work for my ubuntu system. Basically, system() will run the shell command.
cin.ignore(); This works out for me. I think this has the effect of "press any key to continue".

2014年8月19日星期二

Something about Latin

For a non-native English speaker, it is hard enough to get used to English. BUT, it seems that some abbreviations come from Latin, which is  impossible to guess. I ran into one today, and that remind me of another one. Just use this to keep in track. It might be fun.

Q.E.D.
This is the one I ran into today. I've seen it a couple of times, I know what it means, I don't know where it comes from. Guess what, they are the initial letters of Latin quod erat demonstrandum, just means "is proved" like I guessed.

e.g.
A common phrase, I always thought it means "example given", which is a bit wired. It also comes from Latin exemplī grātiā, which is more or less like what I'm guessing (I don't know how to type the letters, so just copied from Wiki).

post hoc, ergo propter hoc
This might be less common, I saw this on the West Wing, one of my favorite TV series. It means "after this, therefore because of this", this is supposed to be a common logical error, but sometimes it is the best assumption we can make, and it really has some sense to it. Think about time series, people analyze time series all the time, what's the point of doing this if the relation cannot be build from the fact they are consecutive in time? OK, a bit too far. I haven't been clear about this issue. I planned to use this phrase somewhere in my thesis just to show off, but ...

To be continued (hopefully)...

2014年8月16日星期六

Bugs & Fix

Here to keep track of the bugs I ran into and how to fix them.

"relocation truncated to fit: R_X86_64_32S against '.bss'"
This happen when the program needs more than 2GB of data.
Compile with -mcmodel=medium/large.
see http://amiatypist.blogspot.de/2010/05/relocation-truncated-to-fit-rx866432s.html

"Warning: ignoring incorrect section type for .lbss"
This follows last error, I did not find how to solve this. According to a post, this is because that the physical memory in computer is not enough.
see https://answers.launchpad.net/mg5amcnlo/+question/219687

"error: ‘exit’ was not declared in this scope "
This maybe a stupid error, but since it may happen for a new C++ user like me.
Including <iostream> and adding 'using namespace std' are not enough, need to add '#include <cstdlib>' to fix this.

" no matching function for call to 'sort(std::vector<Solution::Interval>::iterator, std::vector<Solution::Interval>::iterator, <unresolved overloaded function type>)"
Get this when I was trying to use std::sort. I defined my own comp() function, the problem is that it is defined as a member function within a class, so there is a 'this' parameter. Add 'static' or define the function outside the body of the class.

declaration of ‘std::stack<char> s’ shadows a parameter
stupid error caused by using the same name for different variables.

java STL like List and Map are abstract classes, and when using HashMap, it is better to use containsKey() to check if a key value exists.

java StringBuffer can be initialized with String and int, but not char. The char value will be converted to int, so the compiler does not say anything, but in reality the char is converted to integer.

org.apache.catalina.core.ContainerBase   : A child container failed during start
Spring or Tomcat just breaks all of a sudden. The problem I think is answered in
http://stackoverflow.com/questions/28102134/a-child-container-failed-during-start-java-util-concurrent-executionexception
, where an answer points out that we shouldn't inculde `servlet-api.jar` in WEB-INF/lib.
Although I did use providedCompile for servlet-api, it somehow finds its way to the /lib.