
Korean: 
이 강의의 한국어자막은 www.snow.or.kr 자원활동가들에 의해 작성되었습니다.
이 강의의 한국어자막은 www.snow.or.kr 자원활동가들에 의해 작성되었습니다. 오픈 콘텐츠가 저작권을 적용하여 
제공되고 있습니다.
여러분의 지원이 MIT OpenCourseWare가 계속해서  
높은 품질의 교육 자료를 무료로 제공할 수 있게 합니다.
또 다른 MIT의 수업을 시청하고 
싶으시면 MIT OpenCourseWare 로 
방문해 주세요.
교수 : 화요일 강의 끝부분에, 많은 분들이 적어도 몇 가지 
부분에서 제가 명확하지 못했던 것을 명확하게 
해주는 질문을 저와 Grimson교수님께 질문 해 주셨더군요. 
그래서 저는 저번 수업 끝부분에 우리가 얘기했던 
몇몇 것들에 대해서 다시 
논의해보고 싶습니다.
여러분은 제가 이 판단 트리를 그렸던 것을 기억하실 겁니다. 

English: 
The following content is
provided under a Creative
Commons license.
Your support will help MIT
OpenCourseWare continue to
offer high quality educational
resources for free.
To make a donation or view
additional materials from
hundreds of MIT courses, visit
MIT OpenCourseWare at
ocw.mit.edu.
PROFESSOR: I want to take a few
minutes at the start of
today's lecture to wrap
up a few more
things about debugging.
And then I'll move on
to the main event.
Just a few small points.
First of all, keep in mind that
the bug is probably not
where you think it is.
Because if a bug were there,
you'd have already found it.
There are some simple things
that you should always look at
when you're looking for bugs.
Reversed order of arguments.

Korean: 
부분적으로 중요한 개념이기 때문에 여러분이 판단 트리의 
개념과 이용하는 방법을 이해하기 바랍니다. 
눈에 보이게 몇몇 것들은 다이나믹한 
프로그래밍과 연관되어 있습니다. 
그래서 우리는 이 판단 트리안에 weight vector를 가지고 있습니다. 
아주 간단한 것 [5,3,2]를 줘 보겠습니다. 
그럼 우리는 아주 간단한 값 벡터, [9,7,8]을 얻을 수 있죠. 
그리고 나서 우리가 트리를 그렸던 방법은 꼭대기부터 시작합니다.  
좋아요 우리는 물론 우리 아이템들의 리스트 중 
세번 째 아이템이었던 아이템 넘버 2부터 처음 보겠습니다.

English: 
You might have a function that
takes to floats and you just
passed them in the
wrong order.
You may have noticed that when
Professor Grimson and I used
examples in class, we were
pretty careful how we name our
parameters.
And I often end up using the
same names for the actuals and
the formals.
And this just helps me not get
confused about what order to
do things in.
Spelling.
These are just dumb little
things to look for.
Did you spell all the
identifiers the way
you think you did.
The problem is, when you
read code you see what
you expect to see.
And if you've typed in l when
you should've typed a 1, or a
1 when you should've typed an
l, you're likely to miss it.
If you've made a mistake with
upper and lower case.
Things like that.
So just be very careful
looking at that.

Korean: 
물론, 우리는 우리의 배낭이 버틸 수 있는 무게의 
5파운드가 남아있고 현재는 0의 값을 갖습니다.
그리고 나서 우리는 결정을 내립니다. 가방에 마지막 아이템을 놓지 않기로요.
그리고 만약 우리가 결정을 내린다면, 고려해야하는 다음 아이템은 1입니다.
여전히 5 파운드가 이용가능 하고, 
여전히 가능한 무게 0이네요.
이제 다음으로 고려해봐야 하는 아이템은 아이템1입니다. 
하지만 정말 제가 의미하는 것은 그 리스트 안에서    
아이템1 과 모든 아이템의 과정입니다.
이것은 아이템 서브1을 포함하고 목록 작성하는 것을 말하는 
일종의 그것을 생각해보는 보통의 방법을 일컫는 제 약칭입니다. 

English: 
Initialization.
A very common bug is to
initialize a variable.
Go through a loop, and then
forget to reinitialize it when
it needs to be reinitialized
again.
So it's initialized outside
the loop when it should be
initialized inside the loop.
Or conversely, inside the
loop when it should
be outside the loop.
So look carefully at when
variables are being
initialized.
Object versus value equality.
Particularly when you use double
equals, are you asking
whether you've got the same
object or the same value?
They mean very different things,
as we have seen.
Keep track of that.

Korean: 
우리가 그 트리를  만들고 나서, 처음으로 첫 단계를 남겨두었을 때, 
가지가 없는 모든 것을 보면, 0,5,0 그리고 나서 끝나죠.  
가지 하나였죠.
그리고 나서 다시 돌아옵니다. 그리고 yes를 한번 봅시다. 
우리는 아이템 숫자 1을 포함하게 되겠죠. 
좋아요, 만약 우리가 그것을 포함한다면 여기서 무슨일이 일어나나요 ? 
그것은 모든 가능한 weight를 모두 다 쓰고 우리에게 9의 값을 줍니다.
학생들 : 이해할수없는
교수 : 뭐라구요?
학생 : 바닥의 가지를 없애고 싶습니다.
교수 : 네. 1로서요.
단지 1만을 백트랙 했기 때문에 

English: 
Related to that is aliasing.
And you'll see that, by the way,
on the problem set that
we're posting tomorrow.
Where we're going to ask you
to just look at some code,
that there's some issues there
with the fact that you alias
things, maybe on purpose,
maybe on accident.
And by that I mean two different
ways to get to the
same value, the same object.
Frequently that introduces
bugs into the program.
A particular instance of that
is deep versus shallow copy.
When you decide to make a copy
of something like a list, you
have to think hard about are you
only copying the top level
of the list, but if it's, say,
a list that contains a list,
are you also getting
a new copy of

Korean: 
이 가지를 제거하고 싶었는데요. 감사합니다. 
그리고  나서 이 가지까지 백트랙 하겠습니다. 
그리고 여기부터 우리는 0,2,7을 갖죠. 
그리고 여기서 여러분을 위해 나머지 트리를 그리진 않겠어요. 
왜냐하면 저번에 그려줬었고, 
트리 전체를 볼 필요는 없기 때문이죠.  
모든 노드에서 제가 만들고 싶은 점은 잎을 제외하구요.  
잎은 이 경우에 트리의 뿌리 쪽입니다. 
컴퓨터 과학자들은 이상해요. 
그들은 뿌리를 트리의 꼭대기에 그리고 잎을 바닥 쪽에 그려요.
저도 왜인지 모르지만 아주 예전부터 
컴퓨터 과학자들이 트리를 그리는 방법이예요.  
이것이 우리가 생물학자가 아닌 이유죠. 
우리는 이것들을 이해하지 않습니다.
하지만 제가 여러분들이 알았으면 하고 원하는 것은 각기 가지들이지 잎이 아닙니다.

English: 
everything it contains?
It doesn't matter if it's a list
of integers or a list of
strings or a list of tuples, but
it matters a lot if it's a
list of lists.
Or a list of anything that
could be mutable.
So when you copy, what
are you getting?
When you copy a dictionary,
for example.
Think through all of that.
And again, a related problem
that people run into is
side-effects.
You call a function and it
returns a value, but maybe it,
on purpose or on accident,
modifies one of the actual
parameters.
So you could each make
a list of things.
Every experienced programmer
over time develops a personal
model of the mistakes
they make.
I know the kinds of things
I get wrong.

English: 
And so when I'm looking for a
bug, I always say, oh, have
you done this dumb thing
you always do.
So be a little bit
introspective.
Keep track of the mistakes
you make.
And if your program doesn't
work, that should be your
first guess.
Couple of other hints.
Keep a record of what
you've tried.
People will look at things and
they'll come in and that'll
talk to a TA, and the TA will
say, did you try this?
And the person will
say, I don't know.
That leads you to end up
doing the same thing
over and over again.
This gets back to my main theme
of Tuesday, which is be
systematic.
Know what you've already tried,
don't waste your time
trying it again.

Korean: 
왜냐하면 그 해결책들은  그 밑에 가지들의 다른 
해결책으로부터 얻어 질 수 있기 때문입니다. 
그래서 이 가지들의 해결책을 살펴보기 위해서, 
저는 그 해결책 밑의 가지들을 살펴봐야 합니다. 
이 부분에 있다면 a혹은 b가 최선의 해결책입니다. 
물론, 이것이 2가지 해결책들보다 더 낫습니다. 
만약 이 노드를 본다면  이 노드의 더 나은 
해결책으로서 이것의 해결책을 선택할 것입니다. 
전체 문제의 가장 좋은 해결책을 선택해야만 
하는 곳인 꼭대기까지의 모든 방법은 
오른쪽 노드와 왼쪽 노드 모두가 
가장 좋은 방법입니다.
이것은 이진법 판단 트리가 되기 위해 일어납니다. 

English: 
Think about reconsidering
your assumptions.
A huge one is, are you actually
running the code
you're looking at
in your editor.
This is a mistake I make
all the time in Python.
I sit there in idle, and
I edit some code.
I then click on the shell,
rather than hitting F5, try
and run it and say, it's
not doing what I
thought I should do.
And I'll sit there staring at
the output, staring at the
code, not realizing that
that output was not
produced by that code.
It's a mistake I've learned
that I make.
It's an easy one to
make in Python.
Lots of assumptions like that.
You thought you knew what the
built-in function sort did,

Korean: 
Knapsack problem에 있어서 거기에 오직 두 노드만 되는 것에는 
어떤 마법적인 일도 없습니다. 그것은 단지 답을 
알아내는 방법입니다. 하지만 네 아니오보다 더 많은 것을  
만들어 내는 복합적인 판단 트리가 있을 수 있는 다른 문제들이 있습니다. 
하지만 이 부분 경우에는 항상 우리가 저번시간에 
얘기했던 것으로  어떤 것이 있죠? 
Optimal sub structure입니다. 
저번 시간에 제가 정의한 것과 같이, 그것은 더 작은 
서브 문제들의 최적인 해결책을 찾는 것으로서  
문제들을 풀 수 있다는 뜻입니다.
전형적인 divide와 conquers는 우리가 
몇 번이고 학기 중에 본 것이죠. 

Korean: 
어려운 문제를  가지면, 음, 2가지 더 작은 문제들을 풀고 그것들의 솔루션을 합 함으로써 그것을 풀 수 있습니다. 
그리고 이 경우에는 이 합하는 과정이 가장 
좋은 것을 고르는 것입니다.  a나 b죠. 
그리고 나서 그 문제를 생각하는 그 방법에서 
이 간단한 것으로 즉시 가겠습니다. 
이 슬라이드의 윗 부분, 여러분의 프린트 물 윗부분에 있습니다. 
어제와 오늘 모두, 최대 값의 간단한 수행은 
기본적으로 이것을 했습니다. 
그리고 여러분이 아마 추측했던 것과 같이, 여러분이 이런 비슷한 종류의 
일을 행할 때, 재귀 호출은 그것을 수행하는 데 아주 자연스러운 방법입니다. 
그리고 나서 이것을 실행시켜 봅니다. 

English: 
method sort did.
Well, does it do what
you think it does?
Does append do what
you think it does?
Go back and say, alright,
I've obviously, some
assumption is not right.
When you're debugging somebody
else's code, debug the code,
not the comments.
I've often made the mistake
of believing the comments
somebody wrote in your code
about what some function does.
Sometimes it's good
to believe it.
But sometimes you
have to read it.
Important thing.
When it gets really
tough, get help.
Swallow your pride.
Any one of my graduate students
will tell you that
from time to time I walk into
their office and say, do you

Korean: 
우리가 정답이 무엇인지 알만한 충분히 작은 문제의 
정답이라는 게 증명되었습니다. 그것을 큰 문제에 실행시켜 봅니다. 
우리가 정답이라고 생각했던 것이 맞네요. 하지만 우리는 우리 머리로 
그것을 확인할 좋은 방법이 없습니다. 하지만 실행시키는 데 오랜 시간이 걸리는 걸 주목하세요. 
그리고 나서 우리는 우리 스스로에게 질문해봅니다. 실행시키는데 왜 이렇게 오랜 
시간이 걸리나요? 그리고 우리가 statement 프린트에 
중심을 둘 때, 우리가 보는 것은 같은 것이 계속 반복해서 실행되기 때문입니다. 
왜냐하면, 우리가 가진 많은 서브 문제들은 같기 때문이죠.   
그것은 마치 우리가 이 검색 트리를 살펴볼 때 우리가 바닥 
쪽에 무엇이 있는지 전혀 기억하지 못하는 것과 같습니다. 
그리고 우리는 계속 반복하여 다시 산출해 내겠죠. 
그래서 그것은 우리가  다이나믹 프로그래밍의 핵심 아이디어의 

English: 
have a minute?
And if they foolishly say yes,
I drag them back to my office
and say I'm stuck on this bug,
what am I doing wrong?
And it's amazing what -- well,
a, they're smarter than I am
which helps.
But even if they weren't smarter
than I am, just a
fresh set of eyes.
I've read through the same thing
twenty times and I've
missed something obvious.
Someone who's never seen it
before looks at and says, did
you really mean to do this?
Are you sure you didn't want to
do for i in range of list,
rather than for i in list?
That sort of thing.
Makes a big difference to just
get that set of eyes.
And in particular, try and
explain to somebody else what
you think the program
is doing.
So I'll sit there with the
student and I'll say, I'm

Korean: 
종류인 memoization을 보도록 이끕니다. 그것은 우리가 했던 일들을 
기억하고 모든 것을 다시 해보지 않도록 합니다. 
우리는 그 메모를 시행하기 위해 사전을 사용합니다. 
그리고 그것은 우리에게 빠른 max val 0으로부터 불려지는 max val을 주죠. 
왜냐하면 저는 사용자들이 심지어 존재하는 것조차 모르는
(problem statement부분이 아니라, 시행의 부분이기 때문에) 
이 메모를 소개함으로써 max val의 특이성을 
바꾸지 않았음을 확인하고 싶었기 때문 입니다. 
그것을 행하고, 제가 했던 모든 것은, 제가 했던 것의 트랙을 
유지하고, 근본적 코드를 갖습니다. 그리고 
이 값을 전에 산출해냈는지 말합니다. 
만약 그렇다면, 다시 산출하지 않죠. 그리고  그것이 여러분이 다이나믹 
프로그래밍을 가지고 계속해서 보게 될 핵심 아이디어입니다. 

English: 
going to try and explain to
you why what I think this
program is doing.
And probably 80% of the time,
halfway through my
explanation, I say,
oh, never mind.
I'm embarrassed.
And I send them away.
Because just the act of
explaining it to him or her
has helped me understand it.
So when you're really stuck,
just get somebody.
And try and explain to them why
you think your program is
doing what it's doing.
Another good thing to do
when you're really
stuck is walk away.
Take a break.
Come back and look at it with
fresh eyes of your own.
Effectively, what you're doing
here is perhaps trading
latency for efficiency.
It may, if you go back, come
back and two hours later,
maybe you'll, it'll take you
at least two hours to have

English: 
found the bugs, because you've
been away for two hours.
And maybe if you'd stayed there
and worked really hard
you'd have found it an hour
and fifty eight minutes.
But is it really worth
the two minutes?
This is another reason, by
the way, to start it
long before it's due.
That you actually have the
leisure to walk away.
All right.
What do you do when you've
found the bug and
you need to fix it?
Remember the old saw,
haste makes waste.
I don't know this but I'll bet
Benjamin Franklin said this.
Don't rush into anything.
Think about the fix, don't make
the first change that
comes to mind and
see if it works.
Ask yourself, will it fix all
of the symptoms you've seen?
Or if not, are the symptoms
independent, will at least fix
some of them?
What are the ramifications
of the proposed change.

Korean: 
그리고 말하길, 이미 이 문제를 해결했다면, 
그 답을 보게 해달라 하겠죠. 
만약 해결하지 못했다면, 
나중의 참조를 위해 답을 저장해 놓습니다.
여러분이 여기서 봐 왔듯, 아주 간단한 아이디어와 다이나믹 프로그래밍의 
전형적인 아름다움은 단지 아이디어가 간단한 것에 있을 뿐만 아니라, 
심지어 시행도 간단하다는 데에 있습니다. 
아주 많은 복잡한 알고리즘 아이디어가 있는 데, 
다이나믹 프로그램은 그것들 중 하나가 아닙니다. 
그것이 바로 우리가 이것을 배우고 있는 이유 중 하나죠. 
다른 이유는 간단하면서도 믿기 힘들 
정도로 쓸모 있다는 것입니다. 
그것은 아마도 복잡한 문제를 푸는 데에 있어서 
가장 쓸모있는 아이디어들의 공통점이겠죠.
좋습니다. 이제 한번 보도록 합시다. 
여기에 우리가 저번 시간에 봤던 가장 빠른 버전이 있습니다. 

English: 
Will it break other things?
That's a big issue.
You can fix one thing, you
break something else.
So think through what this
change might break.
Does it allow you to tidy
up other things?
This is important, I
think, that code
should not always grow.
We all have a tendency to
fix code by adding code.
And the program just gets bigger
and bigger and bigger.
The more code you have, the
harder it is to get it right.
So, sometimes, what you need
to, so you just pull back.
And say, well, let me
just tidy things up.
That, by the way, is also
a good debugging tool.
Sometimes when I'm really stuck,
I say, alright let me
stop looking for the bug.

Korean: 
저는 그것의 세부사항들을 다시 살펴봄으로써 
여러분을 지루하게 만드는 대신 실행시켜보도록 하겠습니다. 
이것은 우리가 저번 시간에 봤던 가장 큰 예입니다. 
우리가 선택하여 집어 넣을 수 있는 30개의 아이템이 있어서 우리가 실행할 때 
기하급수적으로  해야만 했죠. 2에서 30까지로 보이네요. 
146
00:11:25,279 --> 00:11:33,289
아주 큰 숫자죠. 하지만 우리가 이것을 실행시켜 보면, 답을 찾을 수 있습니다. 
1805번이 걸리네요. 
저는 이 결과에 아주 흥미를 느낍니다. 
왜냐하면 저에겐 정말 놀라운 것이거든요. 
명백히 지수로 나타낸 문제를 그렇게 풀었다는 것이요. 
그리고 사실, 선택할 수 있는 아이템의 
숫자를 두배로 해도, 여전히 실행됩니다. 

Korean: 
음 – 전 손가락을 빨리 움직이는 걸 아주 못하네요- 
그리고 그것은 여전히 빨리 실행됩니다. 
좋아요, 이제 질문이 있습니다.  선형 시간 안에 본질적인 지수로 
나타내어진 문제를 해결할 방법을 찾았나요? 
왜냐하면 여기에서 우리가 보게 될 것과 저번 시간에 
살짝 봤던 것은 제가 아이템의 수를 2배로 늘리면서 실행시간이 대략 
2배가 되었다는 것을 봤었기 때문입니다.
어마어마하게 조용하네요.  
이제 끝났습니까?
네, 저도 그러길 바랍니다. 
그렇게 된다면 저는 아주 유명하겠고 저희 부장님은 
제 봉급인상을 해주시면서 좋은 것들이 따라왔겠죠. 
하지만 전 유명하지 않고, 문제를 해결하지도 못했습니다. 
무엇이 남았나요?
네, 이 까다로운 알고리즘은 대략 (다시 까다로운 질문으로 돌아와보자면) 

English: 
Let me just clean up the
code a little bit.
Make my program prettier.
And in the process of tidying it
up and making it prettier,
I'll often by accident
find the bug.
So it's a good trick
to remember.
Finally, and this is very
important, make sure that you
can revert.
There's nothing more frustrating
then spending four
hours debugging, and realizing
at the end of four hours your
program is worse than it
was when you started.
And you can't get back to where
it was when you started.
So if you look at one of my
directories, you'll find that

English: 
I've been pretty anal about
saving old versions.
I can always pretty much get
back to some place I've been.
So if I've made a set of changes
and I realize I've
broken something that used to
work, I can find a version of
the code in which it used to
work, and figure out what was
going on there.
Disk space is cheap.
Don't hesitate to save
your old versions.
It's a good thing.
Alright, that's the end of my,
maybe sermon is the right word
on debugging.
Polemic, I don't know.
I hope it will be helpful.
And I hope you'll remember some
of these things as you
try and get your programs
to work.
I now want to get back to
algorithms. And where we've
sort of been for a while,
and where we
will stay for a while.
More fundamentally, I want to
get back to what I think of as

Korean: 
(n,s) 타임을 주문합니다. 
N은 리스트안의 아이템 숫자를 의미하고  
s는 대략 말해보자면 배낭의 사이즈를 의미합니다.
또한 우리가 봐야 하는 것은 그것은 s 공간을 주문한다는 것입니다. 
왜냐하면 이 모든 값들을 저장하기엔 충분하지 않기 때문입니다. 
그래서 처음 레벨에서 제가 하는 것은 공간을 위한 시간을 트레이드하는 것입니다. 
저장할 어떤 공간을 사용하기 때문에 
더 빠르게 실행될 수 있습니다. 

Korean: 
그래서 이 경우에는, 우리는 30개의 아이템을 가지고, 대기하는 아이템은 40으로, 
우리가 있어야 할 곳의 종류를 1200가지로 줍니다. 
그리고 제가 사용하고 있는 가능한 공간은 배낭 안에 
딱 맞는 아이템들의 숫자의 대행으로 쓰고 있기 때문에 
이 부분에서 강조하고 싶습니다. 
왜냐하면 이 알고리즘의 실제 공간과 이것의 실제 실행 시간은  
흥미롭게도 아주 충분하게 지배되고 있습니다. 
문제의 크기 하나로 뿐만 아니라 
해결책의 크기까지 말입니다. 
그리고 그것으로 다시 돌아가보겠습니다.

English: 
the main theme of 6.00, which
is taking a problem and
finding some way to formulate
the problem so that we can use
computing to help us
get an answer.
And in particular, we're going
to spend the next few lectures
looking at a class of problems
known as optimization
problems. In general,
every optimization
problem is the same.
It has two parts.
Some function that you're either
attempting to maximize
or minimize the value of.

English: 
And these are duals.
And some set of constraints
that must be honored.
Possibly an empty set
of constraints.
So what are some of the classic
optimization problems?
Well one of the most well-known
is the so-called
shortest path problem.
Probably almost every one
of you has used a
shortest path algorithm.
For example, if you go to
Mapquest, or Google Maps and
ask how do I get from
here to there.
You give it the function,
probably in this case to
minimize, and it gives you
a choice of functions.
Minimize time, minimize
distance.
And maybe you give it a
set of constraints.

Korean: 
그래서 실행하는데 얼마나 걸리느냐는 결국 냅색안에 얼마나 많은 아이템이 
들어갈 수 있는지 와 연관되어 있습니다. 
만약 여러분들이 그것에 대해 생각해 본다면, 이해됩니다.
하나의 아이템과 가능한 사이즈의 한 쌍을 생각할 때마다 
메모 안에 입구가 만들어지게 됩니다. 
가능한 크기가 0애 가까워 지면 더 이상 메모 안에 들어갈 
수 있는 아이템이 없다는 것을 알게 됩니다. 그렇죠? 
그래서 수많은 아이템을 기억하는 것이 냅색 안에 들어갈 수 
있는 아이템의 개수와 연관되어 있다는 것입니다. 
그리고 물론, 실행시간의 길이는 정확히 내가 기억해야 하는 
아이템의 개수와 일치합니다. 
거의 일치해요. 그렇죠? 

Korean: 
그러니까 여러분들은  개략적으로 생각해 보면 왜 여기서 
해야 하는 일이 양이 넣을 수 있는 
아이템의 개수와 비례하는지 알 수 있답니다.
즉, 그것이 바로 해결의 크기를 말하는 것이죠.
이건 지금 우리가 복잡성에 대해 이야기 하는 방식이 아닙니다. 
명령에 대해 또는 big O에 대해 이야기할 때  
우리는 계속해서 문제에 대해 써 나가기 때문에 우리는 문제의 크기에 
대해 이야기 하는 척 하는 겁니다. 
그리고 그것은 일반적으로 우리가 그것을 해결할 때까지는 해결책의 크기가 
얼만큼 큰지 알지 못하기 때문에 말이 됩니다. 
그래서 우리는 입력갑에 대해 big O 라고 정의하는 편이 낫습니다. 
우리가 여기서 보아야 할 것은 pseudo-허위 라고 

English: 
I don't want to drive
on highways.
And it tries to find the
shortest way, subject to those
constraints, to get from Point
A to Point B. And there are
many, many other instances
of this kind of thing.
And tomorrow it's recitation,
we'll spend quite a bit of
time on shortest
path problems.
Another classic optimization
problem is
the traveling salesman.
Actually, I should probably,
be modern, call it the
traveling salesperson, the
traveling salesperson problem.
So the problem here, roughly, is
given, a number of cities,
and say the cost of traveling
from city to city by airplane,
what's the least cost round
trip that you can find?

Korean: 
불리는 다항식 알고리즘 이예요. 
다항식 알고리즘이란 입력갑 크기가 
다항식인 알고리즘이라고 했던 것을 기억하겠죠?  
허위 다항식을 보기 이전에 여기 다항식이 
해결책 크기인 알고리즘이 있습니다. 
조금 더 형식적으로 보면 이것은 모든 세부사항을  
포함할 정도로 중요한 것은 아닙니다.
숫자 알고리즘에 대해 생각해 본다면, 

English: 
So you start at one place, you
have to go to a number of
other places.
End up where you started.
It's not quite the same as the
shortest path, and figure out
the way to do that
that involves
spending the least money.
Or the least time, or
something else.
What are some of the other
classic optimization problems?
There's bin packing.
Filling up some container with
objects of varying size and,
perhaps, shape.
So you've got the trunk of
your car and you've got a
bunch of luggage.
More luggage than can
actually fit in.
And you're trying to figure
out what order
to put things in.
And which ones you can put in.
How to fill up that bin.
Very important in shipping.

English: 
People use bin packing
algorithms to figure out, for
example, how to load
up container ships.
Things of that nature.
Moving vans, all sorts of
things of that nature.
In biology and in natural
language processing and many
other things, we see a lot of
sequence alignment problems.
For example, aligning DNA
sequences, or RNA sequences.
And, one we'll spend a fair
amount of time on today and
Tuesday is the knapsack
problem.
In the old days people used to
call backpacks knapsacks.
So we old folks sometimes even
still make that mistake.
And the problem there is, you've
got a bunch of things.
More than will fit into the
knapsack, and you're trying to

Korean: 
허위다항식 알고리즘의 실행 시간은 입력값 수치 정도입니다. 
훨씬 이야기하기 쉽기 때문에 
나는 숫자 알고리즘을 예로 들어 사용합니다. 
그러니깐 그것을 계승의 이행이라고 하고 
실행시간은 계승한 숫자의 수치에 
비례한다고 합니다.
내가 8승을 입력하면 8승이 계산되고 
내가 10승을 입력하면 10승이 계산되죠.
여기서 조금 더 생각해 보아야 할 문제는 
이러한 것들을 볼 때 우리가 보아야 할 것은 
만약 우리가 수치값을 본다면 

English: 
figure out which things to
take and which things to
leave. As you plan
your hiking trip.
How much water should
you take.
How many blankets?
How much food?
And you're trying to optimize
the value of the objects you
can take subject to the
constraint that the backpack
is of finite size.
Now, why am I telling
you all of this at
this lightning speed?
It's because I want you to think
about it, going forward,
about the issue of problem
reduction.
We'll come back to this.
What this basically means is,
you're given some problem to
solve, that you've never
seen before.

Korean: 
우리는 수많은 숫자들의 지수를 알게 됩니다. 
그것이 바로 생각해 보아야 할 열쇠 같은 것입니다. 
좋아요.  
형식적으로 우리가 컴퓨터의 복잡한- 
입력값이 코딩 사이즈라고 할- big O 를 볼 때 
문제를 인식할 수 있습니다. 
컴퓨터에 입력값을 
나타내야 합니다. 

English: 
And the first thing you do is
ask is it an instance of some
problem that other people
have already solved?
So when the folks at Mapquest
sat down to do their program,
I guarantee you somebody opened
an algorithms book and
said, what have other
people done to solve
shortest path problems?
I'll rely on fifty years of
clever people rather than
trying to invent my own.
And so frequently what we try
and do is, we take a new
problem and map it onto an old
problem so that we can use an
old solution.
In order to be able to do that,
it's nice to have in our
heads an inventory of previously
solved problems. To
which we can reduce the
current problem.
So as we go through this
semester, we'll look at,
briefly or not so briefly,
different previously solved

Korean: 
그리고 어떤 지수를 이야기할 때 
우리는 그것을 나타내기 위해 그것에 대해 이야기합니다.
이제, 이 모든 것을 해 온 이유는 아마도 내가 pseudo이론
-허위 이론 -이라는 단어를 사용하기 위해서였어요. 
그것은 매우 미묘하기 때문에 우리가 복잡성에 대해 
이야기 하기 시작했을 때 여러분이 이해해주길 바랬었죠. 
그리고 여러분은 무엇을 의미하는지 매우 주의 깊게 생각하지 않으면 
실행되는데 걸리는 시간이나 사용되는 공간을 
보고 놀랄수도 있지요. 
그리고 또한 여러분은 해결책의 크기나 
문제의 크기에 대한 수행에 대해, 
둘 사이의 차이점을 이해해야 합니다. 
문제의 크기에 대해 이야기할 때 
그것의 배열의 길이, 배열요소의 크기, 

Korean: 
그리고 그것이 문제가 될 수 있는지 살펴보아야 합니다. 
그래서 퀴즈의 예로 효율성에 대해 물어보았을 때 
n 스퀘어의 순서만 쓰는 것이 아니라 
n이 무엇인지도 
주의 깊게 써야 합니다. 
예를 들어보면 목록에서 요소의 개수죠.
만약 목록들 중 목록에 대해서 문제가 나오면 
목록의 요소 개수만 쓰면 안되고 
요소란 무엇인지를 써야 한다는 겁니다. 
이러한 문제들은 매우 주의 깊게 생각해 보고 
쓰라고 알려주는 겁니다. 좋아요.
나는 마술을 다 보여주지 않았어요. 단지, 여러분에게 배낭 문제를 

English: 
problems in the hope that at
some time in your future, when
you have a problem to deal
with, you'll say, I know
that's really like
shortest path, or
really like graph coloring.
Let me just take my problem and
turn it into that problem,
and use an existing solution.
So we'll start looking in detail
at one problem, and
that's the knapsack problem.
Let's see.
Where do I want to start?
Oh yes, OK.
So far, we've been looking
at problems that
have pretty fast solutions.
Most optimization problems do
not have fast solutions.
That is to say, when you're
dealing with a large set of
things, it takes a while to
get the right answer.
Consequently, you have to
be clever about it.

Korean: 
해결할 정말 빠른 대책을 알려주었을 뿐이죠. 하지만 여전히 지수문제에 대해서 
더 깊게 들어가 보아야 해요. 
좋아요, 아직 보지 못한 또 다른 종류의 문제를 볼 수 있는 기회가 있는데 
그것은 역학 프로그래밍에 의해 해결되는 것입니다. 
많은 종류들이 있죠. 
배낭 문제를 보기 전에 
2분정도 변형된 문제를 
조금 보고 가도록 하죠.
자, 이거 한 번 봅시다. 
배낭에 아이템의 총 무게뿐 아니라 
부피에도 한계가 있다고 
가정해 봅시다. 
좋아요. 만약 내가 풍선 한 상자를 주었다면 그것은 무게가 
나가지 않는다고 여러분이 그 상자에 아무것도 넣을 수 없는 것은 아니에요. 
배낭 안에 많은 풍선들을 넣을 수 있어요. 그렇죠? 
때로는 무게가 아니라 부피가 문제가 될 수 있고 
때로는 둘 다 문제가 되죠. 

English: 
Typically up till now, we've
looked at things that can be
done in sublinear time.
Or, at worst, polynomial time.
We'll now look at a problem that
does not fall into that.
And we'll start with
what's called the
continuous knapsack problem.
So here's the classic
formulation.
Assume that you are a burglar.
And you have a backpack that
holds, say, eight pounds'
worth of stuff.
And you've now broken into a
house and you're trying to
decide what to take.
Well, let's assume in the
continuous world, what you is
you walk into the house and you
see something like four
pounds of gold dust. And you
see three pounds of silver

Korean: 
만약 최고치 무게가 있을 뿐 아니라 최고치 부피도 있다고 
가정한다면 이 문제를 어떻게 
해결할 수 있을까요? 
자, 우리가 어떤 수학 공식을 쓰면서 
처음에 해 보았던 정확한 방법으로 
돌아가 봅시다. 
우리가 그것을 보았을 때를 기억하죠? 
우리가 문제가 x아래에는 I, I아래에는 p 등등 I에서 n까지의 합이 
극대화 된다는 것이라고 했었죠.  n 마이너스 1이 되었어야 했지만 
우리는 크게 신경 쓰지 않았어요.
그리고 우리는 I 곱하기 x 가 x가 나온다면 
맞는 것이고 1이 나온다면 
틀린 것이라고 
1에서 n 까지의 합을  

English: 
dust, and maybe ten
pounds of raisins.
And I don't actually
know the periodic
table entry for raisins.
So I'll have to write it out.
Well, how would you solve
this problem?
First, let's say, what
is the problem?
How can we formulate it?
Well, let's assume that what
we want to do is, we have
something we want to optimize.
So we're looking for
a function to
maximize, in this case.
What might that function be?
Well, let's say it's some number
of, some amount of, the
cost of the value of gold.

Korean: 
제약을 두었어야 했어요.
부피를 더 크게 하고 싶다면 무엇을 해야 할까요? 
문제? 이것을 바꿔야 할까요? 
목표를 바꿔야 할까요?   
대답해 보세요.
아무도 대답하지 않고 고개만 흔듭니다.
학생 : 아니요.
교수 : 네 아닙니다.
목표는 바뀌지 않습니다. 똑 같은 목표죠. 
무엇이 바뀌어야 할까요? 
학생 : 제약이요.
교수 : 맞았어요. 다른 것을 바꿀 수는 없죠. 
제약을 바꾸어야 합니다. 
제약를 더해보았죠. 
내가 어떻게 더했을까요? 
누구 아는 사람? 
학생 : 배낭에 들어갈 부피를 
초과 시킬 수 없습니다.
교수 : 맞았어요. 하지만 그렇게 하는 
방법을 정확하게 쓸 수 있어요? 
학생들 이해되지않는.
교수 :I 부터의 합은 1에서 n 까지와 같죠.
학생들 이해되지않는.
교수 : i 아래에 v , x아래에 i가 있다고 가정해 봅시다. 
그것들은 같거나 더 적어요. 허용되는 총 부피를 k라고 할거에요. 

English: 
Times however many
pounds of gold.
Plus the cost of silver times
however many - no, gold, is a
g, isn't it.
Pounds of silver, plus the
cost of raisins times the
number of pounds of raisins.
So that's the function
I want to optimize.
I want to maximize
that function.
And the constraint is what?
It's that the pounds of gold
plus the pounds of silver plus
the pounds of raisins is
no greater than eight.
So I've got a function to
maximize and a constraint that
must be obeyed.

English: 
Now, the strategy here
is pretty clear.
As often is for the continuous
problem.
What's the strategy?
I pour in the gold till
I run out of gold.
I pour in the silver until
I run out of silver.
And then I take as many raisins
as will fit in and I
leave. Right?
I hope almost every one of you
could figure out that was the
right strategy.
If not, you're not well suited
to a life of crime.
What I just described is an
instance of a greedy algorithm.
In a greedy algorithm, at
every step you do what
maximizes your value
at that step.
So there's no planning ahead.
You just do what's ever best.
It's like when someone gets

Korean: 
정확하게. 
여기서 알아야 할 것은 우리가 아주 조금 
간단하게 바꾸었다는 것이죠.
난 이 하나의 통제를 간단히 더했어요. 
이런 방법의 좋은 점에 대해 이야기 해 보면 그것은 생각하기가 쉽다는 거죠. 
그리고 만약 코드를 바꾸려고 할 때는 
무엇을 해야 할까요? 
절대 그렇게 하지는 않겠지만 만약 코드를 바꾼다고 
생각하면 어떻게 해야 할까요?
자, 간단한 버전이 더 쉬우니깐 
먼저 봅시다. 
무엇보다도, 
가장 기본적으로, 통제를 두었던 모든 곳을 다 찾아보고 
그것을 바꾸어야 하는 겁니다. 
새로운 통제를 포함하기 위해서죠. 
그리고 역학 프로그래밍 문제를 보았었을 때 

Korean: 
무엇을 해야 하고 무엇을 바꿔야 했었죠?
메모가 바뀌어야 했고 또한 체크도 바뀌어야 했어요. 그렇죠? 
어느 정도의 중량이 가능하지 
생각해야 할 뿐 아니라 부피 또한 얼마나 
가능한지 생각해 보아야 하죠. 
반면 그전에 나는 아이템과 
가능한 중량을 맵핑 했었어요. 
지금 중량과 부피의 투플을 만들어 보려고 해요. 
매우 작은 변화죠. 
우리가 알고리즘을 볼 때 여러분이 이해했으면 
하는 것 중 하나예요. 매우 일반적이고 문제를 어떻게 해결하는
지 한번쯤 여러분이 이해했던 것들입니다. 
여러분은 이러한 매우 간단한 축소로 
또 다른 문제를 종종 해결할 수 있답니다. 

English: 
their food and they start
by eating dessert.
Just to make sure they
get to the best part
before they're full.
In this case, a greedy algorithm
actually gives us
the best possible solution.
That's not always so.
Now, you've actually all
implemented a greedy algorithm.
Or are in the process thereof.
Where have we implemented a
greedy algorithm, or have been
asked to do a greedy
algorithm?
Well, there are not that many
things you guys have been
working on this semester.
Yeah?
STUDENT: [INAUDIBLE]
PROFESSOR: Exactly right.

English: 
So what you were doing there,
it was a really good throw.
But it was a really good answer
you gave. So I'll
forgive you the bad hands.
You were asked to choose
the word that gave
you the maximum value.
And then do it again with
whatever letters you had left.
Was that guaranteed to win?
To give you the best
possible scores?
No.
Suppose, for example, you had
the letters this, doglets.
Well, the highest scoring word
might have been something like
Doges, these guys used to rule
Venice, but if you did that
you'd been left with the letters
l and t, which are
kind of hard to use.

Korean: 
좋아요, 질문 있나요? 
네?
학생 : 저는 교수님이 방금 전에 말씀 하신 것에 
대해 질문이 있습니다. 
교수 : 유사 다항 시간 알고리즘 말인가요? 
학생 : 네. 
교수 : 좋아요. 
학생 : 그래서, 교수님은 교수님이 어떤 것을 사용해야 하는지에 
대한 결론을 어떻게 내리나요, 만약 교수님이 해결책에서 크기 기반, 
또는 입력에 기반한 것으로 결정할 수 있다면, 그러면 어떻게 교수님은 결정 하나요? 
교수 : 좋은 질문입니다.
그래서 질문은, 여러분이 어떻게 알고리즘을 선택 하는지, 왜 제가 유사 다항 시간 
알고리즘을 사용하길 선택 했는지 입니다. 
제가 해결책이 얼마나 클지 모를 때요. 저는 그것에 대해 생각하는 
것이 한 가지 방법이라고 생각 합니다. 
자, 그래서 만약 우리가 배낭 문제에 대해 생각하면, 우리는 그것을 볼 수 있습니다, 
그리고 우리는 우리 스스로에게 질문 할 수 있습니다. 
자 무엇 보다도 우리는 지수적인 해결책이 아이템의 수가 커지면 
실패가 될 것이라는 외면할 수 없는 힘을 알아야 합니다. 
근본적으로 이 경우에서, 제가 볼 수 있는 것은 배낭 크기의 

Korean: 
아이템 수의 비율 입니다, 
저는 선택 할 많은 아이템들을 가지고 있습니다, 
저는 아마 그것들을 모두 집어 넣지 않을 것 입니다. 
그러나 심지어 제가 그렇게 하더라도, 
그것은 여전히 그들 중 오직 30 이 될 것 입니다, 그렇죠? 
그것은 어렵습니다.
전형적으로 우리가 발견할 것은 유사 다항 시간 알고리즘이 보통 낫다는 것 입니다, 
그리고 이 경우에서, 절대 더 나쁘지 않습니다. 
그래서 이것은 그 외면할 수 없는 힘 보다 더 나쁘지 않습니다. 
제가 정말 불행 하다면, 저는 그것의 같은 수를 검사하는 것으로 끝날 것 입니다, 
그러나 저는 정말 그래야 합니다, 
그것은 문제에 대한 매우 이상한 구조여야 합니다. 
그래서 그것은 거의 항상 그 경우 입니다, 

English: 
So you've optimized
the first step.
But now you're stuck
with something
that's not very useful.
Whereas in fact, maybe you would
have been better to go
with dog, dogs, and let.
So what we see here is an
example of something very
important and quite general.
Which was that locally optimal
decisions do not always lead

English: 
to a global optimums. So you
can't just repeatedly do the
apparently local thing
and expect to
necessarily get to it.
Now, as it happens with the
continuous knapsack problem as
we've formulated it,
greedy is good.
But let's look for a slight
variant of it, where greedy is
not so good.
And that's what's called the
zero-one knapsack problem.
This is basically a discrete
version of

Korean: 
만약 여러분이 동적 프로그래밍을 사용하는 해결책을 찾으면, 
그것은 그 외면할 수 없는 힘 보다 더 좋을 것 입니다, 그리고 확실히 그렇지 않더라도, 
자, 아마 더 많은 공간을 사용하겠지만, 더 많은 시간을 사용하지 않을 것 입니다.
그러나 여기, 마법은 없습니다, 그리고 이 학생이 질문 했던 것은 
매우 좋은 질문 입니다.
그리고 그것은 때때로 실제 삶에서 여러분이 실제로 방대한 수를 
계산하게 되는 데이터에 대해 어떤 알고리즘이 더 좋은지 
여러분이 모르는 경우 입니다. 
그리고 여러분은 여러분의 돈을 지물하고 여러분의 기회를 갖습니다, 그렇죠? 
그리고 만약 데이터가 그것이 그렇게 될 것이라고 
여러분이 생각하는 것이 아니라면, 여러분은 여러분의 선택에서 틀릴 것 입니다, 
그래서 여러분은 전형적으로 그것에 대해 생각하는데 보내는 어떤 시간을 가져야 합니다, 
데이터가 실제로 어떻게 보일지를 말합니다.
매우 좋은 질문 입니다.
또 다른 질문 있나요? 
좋아요, 우리가 이것을 떠나기 전에 마무리 짓는 몇 가지 포인트는, 
제가 여러분이 기억하길 바라는 것 입니다.

English: 
the knapsack problem.
The formulation is that we have
n items and at every step
we have to either take
the whole item
or none of the item.
In the continuous problem, the
gold dust was assumed to be
infinitely small.
And so you could take as much
of it as you wanted.
Here it's as if you
had gold bricks.
You get to take the whole brick
or no brick at all.
Each item has a weight and a
value, and we're trying to
optimize it as before.
So let's look at an example of
a zero-one knapsack problem.
Again we'll go back
to our burglar.

Korean: 
동적 프로그래밍에서, 계속 되는 것들 중 하나는 
우리가 공간을 위해 시간을 거래 하는 것 입니다. 
동적 프로그래밍은 우리가 그것을 하는 유일한 시간이 아닙니다. 
우리는 많은 문재들을 그런 방법으로 풀었습니다, 
사실, 공간을 위한 시간을 거래 하면서요. 
예를 들어, 표순람은, 만약 여러분이 깨끗한 테이블들을 가지면, 
여러분은 그들 모두를 즉시 계산하고 나서 
그것을 찾길 원할 수도 있습니다. 
그래서 그것이 한 가지 입니다. 
두 번째는, 지수적인 문제들에 의해 겁을 내지 마세요. 

Korean: 
사람들이 다음과 같이 말하는 경향이 있습니다,
오 이 문제는 지수야, 나는 이 문제를 풀 수 없어. 
자, 저는 2 또는 3 지수 문제를 매일 
아침 식사 전에 풉니다.
여러분은 이런 것을 알 것 입니다, 욕실에 대한 제 방법을 찾는 것은 
선천적으로 지수적 입니다, 그러나 저는 그것을 어쨌든 풀어 냅니다. 
겁먹지 마세요. 
그것이 명백히 지수적이라 할지라도, 많은 시간에 여러분은 실제로 그것을 
더욱, 더욱 더 빠르게 풀 수 있습니다. 
다른 이슈들 입니다. 
세 번째 입니다 : 동적 프로그래밍은 널리 유용 합니다. 
여러분이 자연적인 순환 해결책을 갖는 것으로 보이는 

English: 
So the burglar breaks into the
house and finds the following
items available.
And you'll see in your handout
a list of items and their
value and how much,
what they weight.
Finds a watch, a nice Bose
radio, a beautiful Tiffany
vase, and a large
velvet Elvis.
And now this burglar finds, in
fact, two of each of those.
Person is a real velvet Elvis
fan and needed two
copies of this one.
Alright, and now he's trying
to decide what to take.
Well if the knapsack were large
enough the thief would
take it all and run, but let's
assume that it can only hold
eight pounds, as before.
And therefore the thief
has choices to make.
Well, there are three types of
thieves I want to consider:
the greedy thief, the
slow thief, and you.

Korean: 
문제를 볼 때 마다, 여러분이 그것을 동적 프로그래밍으로 
해결 할 수 있을지에 대해 생각해 보세요. 
만약 여러분이 이 최적의 하부 구조를 가진다면, 
그리고 하부 문제들을 겹쳐 놓으면, 여러분은 동적 프로그래밍을 사용할 수 있습니다. 
그래서 그것은 배낭 문제에 좋습니다, 그것은 가장 짧은 경로에 좋습니다, 
그것은 변화를 만들기에 좋습니다, 
그것은 전재의 다양한 문제들에 좋습니다
그리고 여러분의 공구 상자 안에 그것을 계속 지니세요, 
그리고 여러분이 풀기 어려운 문제를 가질 때, 여러분이 여러분 스스로에게 물을 수 있는 가장 
첫 번째 질문들 중 하나는, 내가 동적 프로그래밍을 사용할 수 있는가? 입니다. 
그것은 전체적인 다양한 string-matching 문제들을 푸는데 아주 좋습니다. 
그것은 매우 유용 합니다. 
그리고 마지막으로, 저는 여러분이 문제 감소의 
전체적인 개념을 명심하길 바랍니다.

English: 
We'll start with the
greedy thief.
Well, the greedy thief follows
the greedy algorithm.
What do you get if you follow
the greedy algorithm?
What's the first thing
the thief does?
Takes the most valuable item,
which is a watch.
And then what does
he do after that?
Takes another watch.
And then?
Pardon?
STUDENT: [INAUDIBLE]
PROFESSOR: And then?
STUDENT: [INAUDIBLE]
PROFESSOR: No.
Not unless he wants to break
the vase into little pieces
and stuff it in the corners.
The backpack is now
full, right?
There's no more room.
So the greedy thief take
that and leaves.
But it's not an optimal
solution.
What should the thief
have done?
What's the best thing
you can do?

English: 
Instead of taking that
one vase, the thief
could take two radios.
And get more value.
So the greedy thief, in some
sense, gets the wrong answer.
But maybe isn't so dumb.
While greedy algorithms are not
guaranteed to get you the
right answer all the
time, they're often
very good to use.
And what they're good about is,
they're easy to implement.
And they're fast to run.
You can imagine coding
the solution up
and it's pretty easy.
And when it runs, it's pretty
fast. Just takes the most
valuable, the next most
valuable, the next most
valuable, I'm done.
And the thief leaves,
and is gone.
So that's a good thing.
On the other hand, it's often
the case in the world that
that's not good enough.

Korean: 
저는 이 도둑의 냉소적인 묘사로 시작 했었습니다, 
그리고 말했습니다 : 자 이것은 정말로 배낭 문제 입니다. 
그리고 이제 저는 구글 배낭 문제로 가서 그것을 풀 코드를 찾을 것 입니다. 
여러분이 무언가를 이전의 해결 된 문제로 줄일 수 
있을 때 마다, 그것은 좋습니다. 
그리고 이것은 배워야 할 매우 중요한 내용 입니다. 
사람들은 다음을 깨닫지 못하는 경향이 있습니다,
여러분이 항상 여러분 스스로에게 질문해야 하는 첫 번째 질문은, 
이것이 정말 변형되어 잘 알려진 문제인가? 
그것이 최단 거리 문제 인가? 
그것이 가장 가까운 이웃 문제 인가? 
그것이 어떤 줄이 이 문제에 가장 유사한 것 인가? 
많은 잘 이해되는 문제들이 있습니다, 
그러나 오직 정말 많기는 하지만, 그것은 수천 가지는 아닙니다, 
그리고 여러분이 이 문제들의 어휘를 구축할 때마다, 
그리고 여러분이 여러분의 도메인에서 무엇을 볼 때마다, 

Korean: 
물리학 또는 생물학 또는 다른 것, 언어학 으로 하세요, 
여러분이 물어야 하는 질문은 내가 이것을 존재하는 문제로 변형 할 수 있을까? 입니다. 
좋아요, 이열 입니다. 
질문이 없으면 저는 주제에서 
엄청난 변화를 만들 것 입니다. 
우리는 이 소수만 이해하는 것에서 일시적으로 벗어나서,  
파이썬으로 돌아갈 것 입니다.
그리고 다음으로, 간헐적으로 다음 몇 주 동안, 
우리는 파이썬과 프로그래밍 조직에 대해 이야기 할 것 입니다. 
그리고 제가 이야기 하고 싶은 것은, 어떤 하나의 모듈들 입니다. 

English: 
And we're not looking for an OK
solution, but we're looking
for the best solution.
Optimal means best. And that's
what the slow thief does.
So the slow thief thinks
the following.
Well, what I'll do is I'll
put stuff in the
backpack until it's full.
I'll compute its value.
Then I'll empty the backpack
out, put another combination
of stuff compute its value,
try all possible ways of
filling up the backpack, and
then when I'm done, I'll know
which was the best. And that's
the one I'll do.
So he's packing and unpacking,
packing and unpacking, trying
all possible combinations of
objects that will obey the
constraint.
And then choosing the winner.
Well, this is like an algorithm
we've seen before.
It's not greedy.
What is this?
What category of algorithm
is that?

Korean: 
그리고 물론 그것은 우리가 흥미 있는 것이  
모듈 방식이기 때문 입니다.
우리가 어떻게 복잡한 프로그램을 할 수 있을 까요, 
다시, 분할하고 정복하세요, 저는 첫 번째 트릭 말 같이 느껴지는군요,
저는 같은 것을 계속 해서 다시 반복해서 말할 것 입니다. 
우리의 프로그램을 모듈적으로 만들기 위해 분할하고 정복하세요 
그래서 우리는 그것들을 어떤 시점에서 
작은 조각으로 쓸 수 있습니다 
그리고 그것들을 어떤 시점에서 작은 조각으로 이해할 수 있습니다. 
이제 저는 모듈을 관련 된 함수들의 집합으로 생각 합니다. 
우리는 이미 이것들을 보았습니다, 

English: 
Somebody?
Louder?
STUDENT: Brute force.
PROFESSOR: Brute force,
exhaustive
enumeration, exactly.
We're exhausting all
possibilities.
And then choosing the winner.
Well, that's what the
slow thief tried.
Unfortunately it took so long
that before he finished the
owner returned home, called the
police and the thief ended
up in jail.
It happens.
Fortunately, while sitting in
jail awaiting trial, the slow
thief decided to figure
what was wrong.
And, amazingly enough, he
had studied mathematics.
And had a blackboard
in the cell.
So he was able to work it out.
So he first said, well, let me
try and figure out what I was
really doing and why
it took so long.
So first, let's think about what
was the function the slow

English: 
thief was attempting
to maximize.
The summation, from i equals 1
to n, where n is the number of
items, so I might label watch
1-0, watch 2-2, I don't care
that they're both watches.
They're two separate items.
And then what I want to
maximize is the sum of the price
of item i times whether
or not I took x i.
So think of x as a vector
of 0's and 1's.
Hence the name of the problem.
If I'm going to keep that item,
item i, if I'm going to
take it, I give it a 1.

Korean: 
그리고 우리는 점 표기법을 사용해서 함수들을 언급할 것 입니다. 
우리는 이것을 모든 학기 마다 하고 있습니다, 그래요, 
아마 두 번째 강의 정도에 하죠, 우리는 math 를 import 하는 것을 말했습니다, 
그리고 나서 우리의 프로그램 어딘가에서 우리는 math 점(.) sqrt 11 
같은 것을 썼습니다. 또는 다른 수를 쓰기도 했고요. 
그리고 좋은 소식은 우리가 math 가 어떻게 제곱근 또는 
그와 같은 어떤 것을 하는지에 대해 걱정할 필요가 없다는 것 입니다, 
우리는 그것을 단지 가지고 사용하면 됩니다. 
이제 우리는 이름 충돌을 피하기 위해 점 표기법을 사용 합니다. 상상해 보세요
예를 들어, 제 프로그램에서 제가 import set 같은 것을 썼습니다, 

English: 
If I'm not going to take
it I give it a 0.
And so I just take the value of
that item times whether or
not it's 0 or 1.
So my goal here is to choose x
such that this is maximized.
Choose x such that that function
is maximized, subject
to a constraint.
And the constraint, is it the
sum from 1 to n of the weight
of the item, times x i, is less
than or equal to c, the

Korean: 
왜냐하면 누군가가 수학적인 set 들을 implement 하는 
모듈을 썼기 때문 입니다. 그리고 어딘가에서 저는 
import table 같은 것을 썼습니다, 왜냐하면 누군가가 어떤 표순람, 
예를 들어 사전 같은 것을 implement 하는 것을 
가지기 때문 입니다.
그리고 나서, 저는 멤버십 같은 것에 대해 물어보길 원했습니다. 
그것이 set에 있는 것 입니까, 아니면 table에 있는 것 입니까? 
자, 제가 썼던 것은 table 점 
멤버 같은 것 입니다. 
그리고 나서 요소 그리고 아마 table 입니다. 
그리고 점 표기법은 차이를 분명히 보여 주기 위해 사용되었습니다.
왜냐하면 제가 table 로부터 멤버 연산을 원하기 때문 입니다,
set 으로부터 멤버 연산을 원하는 것이 아니라요. 

English: 
maximum weight I'm allowed
to put in my backpack.
In this case it was eight.
So now I have a nice, tidy
mathematical formulation of
the problem.
And that's often the first step
in problem reduction.
Is to go from a problem that has
a bunch of words, and try
and write it down as a nice,
tight mathematical
formulation.
So now I know the formulation
is to find x, the vector x,
such that this constraint
is obeyed and
this function is maximized.
That make sense to everybody?
Any questions about that?
Great.
So as the thief had thought,
we can clearly solve this
problem by generating all
possible values of x and

Korean: 
이것은 중요 합니다 왜냐하면 table과 set 을 implement 하는 사람들은 
절대 서로 만나지 않았을 것이기 때문 입니다, 
그리고 그들은 우연이 어딘가에서 같은 이름을 사용하지 않은 것으로 
거의 기대 하지 않기 때문 입니다. 
그러므로 점 표기법을 사용해야 합니다. 
이제 저는 특정한 모듈에 대해 이야기 하고 싶군요,
그리고 그것들은 클래스를 포함하는 
또는 클래스인 모듈들 입니다. 
이것은 매우 중요한 개념 입니다 우리가 이제 볼 것 입니다, 
그것은 MIT 가 6.00 같은 것을 부르는 이유 입니다, 
그래서 그것들은 파이썬에서 클래스와 혼동되지 않습니다, 
그것은 우리가 정말 여기서 알아야 할 필요가 있는 것 입니다. 
이제 그것들은 다른 방식들로 사용될 수 있습니다, 그리고 그것들은 
역사적으로 다양한 방법들로 사용되어 왔습니다. 
이 물체에서 우리는 클래스를 사용하는 것을 강조할 것 입니다. 

English: 
seeing which one solves
this problem.
But now the thief started
scratching his head and said,
well, how many possible
values of x are there?
Well, how can we think
about that?
Well, a nice way to think
about that is to
say, I've got a vector.
So there's the vector with
eight 0's in it.
Three, four, five, six,
seven, eight.
Indicating I didn't take
any of the items.
There's the vector, and again
you'll see this in your
handout, says I only took
the first item.

Korean: 
소위 객체 지향 프로그래밍이라고 하는 것의 문맥에서요. 
그리고 여러분이 웹에서 파이썬 책을 찾아 본다면, 
또는 웹에서 자바 책을 찾아 보면, 그것들의 약 80% 는 그들의 제목에 
객체 지향 이라는 단어를 포함하고 있을 것 입니다. 
예를 들면 컴퓨터 게임을 위한 객체 지향 파이썬 프로그래밍 같은 것들이 있지요, 
또는 다른 것들이 있는지 누가 알겠어요. 
그리고 우리는 이 객체 지향 프로그래밍을 사용할 것 입니다, 
전형적으로 데이터 추상화로 불리는 것을 만들기 위해서요. 
그리고 다음 며칠 동안, 여러분은 이것에 의해 우리가 의미 하는 것이 
무엇인지 자세히 볼 수 있을 겁니다.  
이것의 유의어는 추상 데이터 타입 입니다.
여러분은 웹에서 도 용어가 모두 사용되는 것을 볼 것 입니다. 
그리고 그것을 동의어라고 생각하세요. 
이제 클래스의 이런 생각들, 객체 지향 프로그래밍, 

Korean: 
데이터 추상화, 이것들은 약 40 년 된 것 입니다,  
그것들은 새로운 생각이 아닙니다.
그러나 그것들은 10 에서 15 년 동안 정말 실용적으로  
넓게 받아 들여져 왔습니다.
그것은 70 년대 중반에 있었습니다, 사람들은 이 프로그래밍 스타일을 
옹호하는 기사들을 쓰기 시작했습니다, 그리고 실제로 프로그래밍 언어들을 만들면서,  
특히 MIT 에서 사실 스몰토크와 클루를 만들었어요, 
그것은 데이터 추상화와 객체 지향 프로그래밍의  
생각을 위한 언어학적 지원을 제공했습니다.
그러나 그것은 정말, 객체 지향 프로그래밍이 인기 있는 
관심을 끌게 된 도래인 자바 때  
까지는 그렇지 않았습니다.
그리고 나서 자바, C++ , 파이썬 등이 있지요. 

English: 
There's the one that says I
only took the second item.
There's the one that says
I took the first
and the second item.
And at the last,
I have all 1's.
This series look like anything
familiar to you?
These are binary
numbers, right?
Eight digit binary numbers.
Zero, one, two, three.
What's the biggest number
I can represent
with eight of these?
Somebody?
Well, suppose we had
decimal numbers.
And I said I'm giving you
three decimal digits.
What's the biggest number you
can represent with three
decimal digits?
Pardon?
STUDENT: [INAUDIBLE]
PROFESSOR: Right.
Which is roughly what?
10 to the?
STUDENT: [INAUDIBLE]
PROFESSOR: Right.
Yes.

English: 
STUDENT: [INAUDIBLE]
PROFESSOR: Right.
Exactly right.
So, in this case it's
2 to the 8th.
Because I have eight digits.
But exactly right.
More generally, it's
2 to the n.
Where n is the number of
possible items I have to
choose from.
Well, now that we've figured
that out, what we're seeing is
that the brute force algorithm
is exponential.
In the number of items we
have to choose from.
Not in the number that we take,
but the number we have
to think about taking.
Exponential growth
is a scary thing.

Korean: 
그리고 오늘날 어떤 방식에서 그것을 지원하지 않는 
프로그래밍 언어를 누구도 옹호하지 않습니다.  
그래서 이것이 모두 무엇에 대한 것 이지요?
객체 지향 프로그래밍에서 객체는 무엇 입니까? 
객체는 데이터와 함수의 집합 입니다. 
특히 데이터에서 연산하는 함수들이고, 아마  
다른 데이터에서도 또한 그렇습니다.

Korean: 
여기서 핵심적인 생각은 데이터와 그 데이터에서 연산하는 함수들을 
단일한 것으로 함께 묶는 것 입니다. 
이제 전형적으로 그것은 아마 여러분이 무엇에 대해 
생각 해 온 방식이 아닐 것 입니다. 
여러분이 int 또는 float 또는 dictionary 또는 list 에 대하여 생각 할 때, 
여러분은 그것들에 연산하는 함수들이 있다는 것을 
알고 있습니다. 
그러나 여러분이 인자 list 를 전해 줄 때, 여러분은 여러분이 
단지 list 를 전해주고 있다고 생각하지 않았습니다, 
여러분은 또한 list 에 연산하는 함수들을 전해 줍니다. 
사실 여러분이 그렇습니다. 그것은 종종 중요하지 않습니다, 
그러나 그것은 때때로 정말 그렇습니다. .
그것의 이점은, 여러분이 객체를 다른 프로그램의 
또 다른 부분으로 전해 줄 때, 프로그램의 그 부분은 또한 객체에서 

English: 
So now we can look at
these two graphs,
look at the top one.
So there, we've compared n
squared, quadratic growth,
which by the way Professor
Grimson told you was bad, to,
really bad, which is
exponential growth.
And in fact, if you look at
the top figure it looks as
exponential or, quadratic isn't
even growing at all.
You see how really fast
exponential growth is?
You get to fifteen items and
we're up at seventy thousand
already and counting.
The bottom graph has exactly
the same data.
But what I've done is, I've use
the logarithmic y-axis.
Later in the term, we'll spend
quite a lot of time talking
about how do we visualize
data.
How do we make sense of data.
I've done that because you can
see here that the quadratic
one is actually growing.

English: 
It's just growing a
lot more slowly.
So the moral here
is simple one.
Exponential algorithms are
typically not useful. n does
not have to get very big for
exponential to fail.
Now, imagine that you're trying
to pack a ship and
you've got ten thousand
items to choose from.
2 to the 10,000 is a
really big number.
So what we see immediately,
and the slow thief decided
just before being incarcerated
for years and years, was that
it wasn't possible to
do it that way.
He threw up his hands and
said, it's an unsolvable
problem, I should have been
greedy, there's no
good way to do this.
That gets us to the
smart thief.
Why is this thief smart?

Korean: 
연산을 수행할 수 있는 능력을 가진다는 것 입니다. 
이제 우리가 다루는 유일한 타입이 내장 타입일 때, 
프로그래밍 언어에 포함되는 것은, 
정말 중요하지 않습니다. 
왜냐하면, 자, 프로그래밍 언어는 모두가  
그 연산들에 접근할 수 있다는 것을 의미 합니다.
그러나 여기서 핵심 아이디어는 우리가 만들어 내는 
사용자 정의 타입이 되는 것 입니다, 우리는 새로운 타입을 만들 것 입니다, 
그리고 우리가 그것을 할 때 우리가 그 타입의 객체들을 전해 줄 때, 그
프로그래밍 언어가 우리에게 그 타입에서 
적절한 연산을 주는 지를 가정할 수 없습니다. 
그 데이터에서 데이터와 함수의 이 결합은 

Korean: 
객체 지향 프로그래밍의 본질 입니다. 
그것은 정말 그것을 정의하는 것 입니다. 
그리고 그것을 위해 종종 사용되는 단어는 캡슐화 입니다. 
그것을 우리가 캡슐을 가진다고 상상해 보세요, 알약이나 어떤 것을요, 
그리고 그 캡슐에서 우리는 데이터와 함수들의 다발을 갖습니다, 
그것은 우리가 이제 볼 것인데 메소드 라고 부르는 것 입니다. 
걱정하지 마세요, 그들이 메소드 라고 불리는 것은 중요하지 않아요, 
그것은 역사적인 인공물 입니다. 
좋아요, 그래서 이것의 예는 무엇이죠? 
자, 우리는 원의 객체를 만들 수 있습니다, 
그것은 원의 표현을 저장하고 또한 그것에 작동하는 메소드들을 제공 합니다, 

English: 
Because she took 600.
And she learned that in fact
there is a good way to solve
this problem.
And that's what we're going
to talk about next.
And that's something called
dynamic programming.
A lot of people think this is
a really hard and fancy
concept, and they teach in
advanced algorithms classes.
And they do, but in fact
as you'll see it's
really pretty simple.
A word of warning.
Don't try and figure out
why it's called dynamic
programming.
It makes no sense at all.
It was invented by a
mathematician called Bellman.
And he was at the time being
paid by the Defense Department
to work on something else.
And he didn't want them to
know what he was doing.
So he made up a name that he
was sure they would have no
clue what it meant.

English: 
Unfortunately, we now have
lived with it forever, so
don't think of it as actually
being anything dynamic
particularly.
It's just a name.
It's very useful, and why we
spend time on it for solving a
broad range of problems that
on their surface are
exponentially difficult.
And, in fact, getting very
fast solutions to them.
The key thing in dynamic
programming, and we'll return
to both of these, is you're
looking for a situation where
there are overlapping
sub-problems and what's called
optimal substructure.
Don't expect to know what
these mean yet.
Hopefully by the end of the day,
Tuesday, they will both
make great sense to you.
Let's first look at
the overlapping
sub-problems example.

Korean: 
예를 들어, 스크린에 원을 그립니다, 
원의 영역을 리턴 합니다, 그것을 사각형 안에 새깁니다, 
여러분이 그것으로 무엇을 하길 원하는지 누가 알겠어요. 
우리가 이것에 대해 이야기 할 때, 사람들이 이것이 대해 이야기 할 때, 
우리의 객체 지향 프로그래밍 문맥에서요, 
그들은 전형적으로 메시지 전달의 관점에서 그것에 대해 이야기 할 것 입니다, 
메시지 전달 은유 에서요. 
저는 그것이 단지 은유라고 언급하고 싶습니다, 
그것에 대해 단지 생각하는 방법이고, 그것은 여기서 매우 깊은 어떤 것이 아닙니다. 
그래서, 사람들이 이것에 대해 이야기 할 방법은, 

English: 
You have on your handout,
a recursive
implementation of Fibonacci.
Which we've seen before.
What I've done is I've augmented
it with this global
called num calls just so I can
keep track of how many times
it gets called.
And let's see what happens
if we call fib of 5.
Well, quite a few steps.

Korean: 
한 객체가 다른 객체로 메시지를 전달 할 수 있다는 것 입니다, 
그리고 객체에서 그것의 메소드들의 하나를 실행하는 
것에 의해 객체 응답을 받습니다. 
그래서 리스트에 대해 생각해 봅시다. 그
래서 l 이 리스트이면, 저는 s.sort, 
l.sort 같은 것으로 부를 수 있습니다. 
여러분은 이것을 보았습니다. 
이것은 말합니다, 객체 l 을 메시지 sort 에 전달 하라고, 
그리고 메시지는 메소드 sort 를 찾으라고 말합니다, 
그리고 그것을 객체 l 에 적용 합니다, 이 경우에 객체가 변형 됩니다 
그래서 요소들은 인제 순서대로 정렬되었습니다. 
만약 c 가 원 이면, 저는 c 점 area 와 같이 쓸 것 입니다. 
그리고 이것은 말합니다, 변수 c 를 의미하는 객체를 전해 주라고, 

English: 
What's the thing that you notice
about this output?
There's something here that
should tip us off that maybe
we're not doing this the most
efficient way possible.
I called fib with 5 and then
it calls it with 4.
And then that call
calls fib with 3.
So I'm doing 4, 3, 2, 2, 1, 0.
And I'm doing 1, 2.
Well, what we see is I'm calling
fib a lot of times
with the same argument.
And it makes sense.
Because I start with fib of 5,
and then I have to do fib of 4
and fib of 3.
Well, fib of 4 is going to also
have to do a fib of 3 and
a fib of 2 and a fib of
1, and a fib of 0.
And then the fib of 3 is going
to do a fib of 2 and a fib of
1 and a fib of 0.
And so I'm doing the same thing
over and over again.
That's because I have what
are called overlapping

Korean: 
메시지 area 에, 그것은 area 라는 메소드를 실행하라고 말합니다. 
그리고 이 경우에 메소드는 아마 실수를 리턴 할 것 입니다, 
부작용을 가지기 보다는요. 
이제 다시, 흥분하지 마세요, 저는 이 전체적인 메시지 전달 
패러다임에 대해 거의 이야기 하지 않았습니다, 
그러나 그것은 세계에 만연해 있어서 저는 여러분이 그것에 대해 
들을 필요가 있다고 느꼈습니다. 
그러나 그것은 매우 깊은 내용이 아닙니다, 
그리고 만약 여러분이 메시지에 대해 생각하길 원하지 않으면, 
그리고 단지 다음과 같이 생각 한다면, c 가 메소드 area 를 가지고, 원은 메소드 area 를 가지고, 
그리고 원으로써 c는 그것을 적용할 것이고 그것이 말하는 것을 할 것 입니다, 그렇게 생각해도, 여러분은 전혀 문제 될 것이 없습니다. 
이제 여기서 생각해 보아야 할 다음 개념은, 

Korean: 
인스턴스의 개념 입니다. 
그래서 우리는 이미 생각해 보았습니다, 우리는 인스턴스 타입들을 만듭니다, 
그래서 우리가 리스트를 볼 때, 그리고 우리가 에일리어싱 (컴퓨터 그래픽에서 해상도의
한계로 선 등이 우둘투둘하게 되는 현상) 을 볼 때, 우리는 인스턴스라은 단어를 사용 합니다, 
그리고 이것은 1 객체 라고 말합니다, 이것은 또 다른 객체 입니다, 
이 객체들의 각각은 타입 리스트들의 인스턴스 입니다. 
그래서 이제 그것은 우리를 클래스로 가져 갑니다. 
클래스는 공통된 특정을 가진  

English: 
sub-problems. I have used divide
and conquer, as we seen
before, to recursively break it
into smaller problems. But
the smaller problem of fib of
4 and the smaller problem of
fib of 3 overlap with
each other.
And that leads to a lot of
redundant computation.
And I've done fib of 5, which
is a small number.
If we look at some other things,
for example, let's get
rid of this.
Let's try see fib of 10.

English: 
Well, there's a reason I chose
10 rather than, say, 20.
Here fib got called 177 times.
Roughly speaking, the analysis
of fib is actually quite
complex, of a recursive fib.
And I won't go through it, but
what you can see is it's more
or less, it is in fact,
exponential.
But it's not 2 to
the something.
It's a more complicated thing.
But it grows quite quickly.
And the reason it does is
because of this overlapping.
On Tuesday we'll talk about a
different way to implement
Fibonacci, where the growth will
be much less dramatic.
Thank you.

Korean: 
객체들의 집합 입니다.
그래서 여러분은 클래스 리스트에 대해 생각할 수 있습니다. 
클래스 리스트의 모든 객체들이 공통적으로 가지고 있는, 
클래스 리스트의 모든 인스턴스들의 특징은 무엇 입니까? 
그것은 리스트에 적용될 수 있는 메소드들의 집합 입니다. 
sort, append, 다른 것들과 같은 메소드들을 말합니다. 
그래서 여러분은 우리가 이야기한 내장 타입의 모든 것을 
dictionaries, lists 등과 같은 
실제 내장 클래스로써 생각해야 합니다. 
여러분 스스로의 클래스를 정의할 수 있다는 것의 
아름다움은 여러분은 이제 언어를 늘려갈 수 있다는 것 입니다. 
그래서 만약, 예를 들어, 여러분이, 그런 일은 없을 것 이지만, 
오늘날 금융 소프트웨어를 쓰는 일에 종사하고 있다면, 여러분은 결정해야 합니다, 

Korean: 
여러분이 망한 주식 또는 나쁜 모기지 또는 그 모지기 같은 것이라 
불리는 클래스를 정말 가지고 싶습니까, 그렇나요? 
어떤 것이 많은 연산들을 가지고 있을까요, 
저는 그들이 그러한 것으로 들어가지 않을 것 입니다. 
그러나 여러분은 여러분의 프로그램을 floats 와 ints 와 lists 에 관하여 
쓰는 것이 아니라, 모기지, 그리고 CDO, 그리고 여러분이 신문에서 
읽는 것들의 모든 것, 여러분이 읽는 것의  
타입에 대하여 쓰고 싶습니다.
그리고 그래서 여러분은 여러분 스스로의 특별한 목적의 프로그래밍 언어를 
646
00:50:23,750 --> 00:50:26,980
구축해야 합니다. 그것은 여러분이 생물 또는 금융 또는 무엇이든 
여러분의 문제를 푸는 것을 도와 줍니다, 그리고 우리는 화요일에 여기서 다시 시작할 것 입니다
