
Turkish: 
Devamındaki
içerik sağlandı
 
Yaratıcı altında
Avukat lisansı.
Desteğiniz MIT'ye yardımcı olacak
OpenCourseWare devam ediyor
yüksek kalite sunmak
ücretsiz eğitim kaynakları.
Bağış yapmak veya
ek materyalleri görüntüle
Yüzlerce MIT dersinden,
ziyaret MIT OpenCourseWare
ocw.mit.edu adresinde
 
PROFESÖR: Başlayacağız
yepyeni, heyecan verici bir konu,
dinamik program.
AUDIENCE: Evet!
PROFESÖR: Evet!
Çok heyecanlı.
Aslında çok heyecanlıyım
çünkü dinamik programlama
en sevdiğim şey
dünya, algoritmalarda.
Ve olacak
sonraki dört ders
oldukça heyecan verici.
Çok farklı yönleri var.
Bu çok genel
güçlü tasarım tekniği.
Hakkında fazla konuşmayız
Bu sınıfta algoritma tasarımı,
ama dinamik programlama
çok önemli biri.
Ve ayrıca biraz alır
yerleşmek için
Enjekte etmeyi severiz
şimdi size, 006'da.

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: We're going to start
a brand new, exciting topic,
dynamic programming.
AUDIENCE: Yes!
PROFESSOR: Yeah!
So exciting.
Actually, I am really excited
because dynamic programming
is my favorite thing in
the world, in algorithms.
And it's going to be
the next four lectures,
it's so exciting.
It has lots of different facets.
It's a very general,
powerful design technique.
We don't talk a lot about
algorithm design in this class,
but dynamic programming is
one that's so important.
And also takes a little
while to settle in.
We like to injected it
into you now, in 006.

English: 
So in general, our motivation
is designing new algorithms
and dynamic programming,
also called DP,
is a great way-- or a
very general, powerful way
to do this.
It's especially good, and
intended for, optimization
problems, things
like shortest paths.
You want to find the
best way to do something.
Shortest path is you
want to find the shortest
path, the minimum-length path.
You want to minimize,
maximize something, that's
an optimization
problem, and typically
good algorithms to solve them
involve dynamic programming.
It's a bit of a broad statement.
You can also think of
dynamic programming

Turkish: 
Yani genel olarak, motivasyonumuz
yeni algoritmalar tasarlıyor
ve dinamik programlama,
ayrıca DP denir,
harika bir yol ya da
çok genel, güçlü bir yol
Bunu yapmak için.
 
Özellikle iyi ve
amaçlanan, optimizasyon
problemler, şeyler
en kısa yollar gibi.
Bulmak istiyorsun
bir şey yapmanın en iyi yolu.
En kısa yol sensin
en kısa bulmak istiyorum
yol, minimum uzunluktaki yol.
Küçültmek istiyorsan,
bir şeyi büyütmek
bir optimizasyon
sorun ve tipik olarak
bunları çözmek için iyi algoritmalar
dinamik programlama içerir.
Biraz geniş bir açıklama.
Ayrıca düşünebilirsiniz
dinamik program

English: 
as a kind of exhaustive search.
Which is usually
a bad thing to do
because it leads to
exponential time.
But if you do it in a clever
way, via dynamic programming,
you typically get
polynomial time.
So one perspective is
that dynamic programming
is approximately
careful brute force.
It's kind of a
funny combination.
A bit of an oxymoron.
But we take the idea of
brute force, which is,
try all possibilities
and you do it carefully
and you get it to
polynomial time.
There are a lot of
problems where essentially
the only known polynomial
time algorithm is
via dynamic programming.
It doesn't always work,
there's some problems
where we don't think there are
polynomial time algorithms,
but when it's possible
DP is a nice, sort of,
general approach to it.
And we're going to be talking a
lot about dynamic programming.
There's a lot of different
ways to think about it.

Turkish: 
bir tür ayrıntılı arama gibi.
Genellikle
yapılacak kötü bir şey
çünkü o yol açar
üstel zaman.
Ama akıllıca yaparsan
Dinamik programlama yoluyla,
genelde alırsın
polinom zamanı.
Yani bir bakış açısı
bu dinamik programlama
yaklaşık olarak
dikkatli kaba kuvvet.
Bir tür
eğlenceli bir kombinasyon.
Bir parça oksimoron.
Ama biz fikrini alırız
kaba kuvvet
tüm olasılıkları dene
ve dikkatlice yapıyorsun
ve sen onu almak
polinom zamanı.
Orada bir sürü
esasen problemler
bilinen tek polinom
zaman algoritması
dinamik programlama yoluyla.
Her zaman işe yaramıyor
bazı problemler var
olduğunu sanmadığımız yer
polinom zaman algoritmaları,
ama mümkün olduğunda
DP güzel, bir nevi
buna genel bir yaklaşım.
Ve biz konuşacağız
Dinamik programlama hakkında çok şey var.
Çok farklı var
düşünmenin yolları.

Turkish: 
Bugün birkaç tanesine bakacağız.
Bugün ısınacağız
bazı oldukça kolay problemlerle
biz zaten
nasıl çözüleceğini biliyor
yani hesaplama
Fibonacci sayıları.
Bu oldukça kolay.
Ve en kısa yolları hesaplamak için.
Ve sonra içinde
sonraki üç ders
alacağız
daha ilginç örnekler
nerede güzel
Yapabildiğin Şaşırtıcı
problemi çöz
polinom zamanında.
Muhtemelen ilk yanan
aklında soru,
ama neden bu
dinamik programlama denir mi?
Bu ne anlama geliyor?
Bende buna sahiptim
hakkında spiel
bilmek, programlama
anlamına gelir
İngilizler
kelimenin kavramı,
optimizasyon hakkında nerede.
Amerikan'da optimizasyon
İngilizce bir şeydir
programlama gibi
İngiliz İngilizcesinde
nerede istersen
programı kur
sizin için program
trenler veya başka bir şey
nerede programlama
başlangıçta geliyor.
Ama ben baktım
fiili tarihçesi,

English: 
We'll look at a few today.
We're going to warm up today
with some fairly easy problems
that we already
know how to solve,
namely computing
Fibonacci numbers.
It's pretty easy.
And computing shortest paths.
And then in the
next three lectures
we're going to get to
more interesting examples
where it's pretty
surprising that you can even
solve the problem
in polynomial time.
Probably the first burning
question on your mind,
though, is why is it
called dynamic programming?
What does that even mean?
And I used to have this
spiel about, well, you
know, programming
refers to the-- I think
it's the British
notion of the word,
where it's about optimization.
Optimization in American
English is something
like programming
in British English,
where you want to
set up the program--
the schedule for your
trains or something,
where programming
comes from originally.
But I looked up the
actual history of,

English: 
why is it called
dynamic programming.
Dynamic programming was invented
by a guy named Richard Bellman.
You may have heard of Bellman
in the Bellman-Ford algorithm.
So this is actually the
precursor to Bellman-Ford.
And we're going to see
Bellman-Ford come up naturally
in this setting.
So here's a quote about him.
It says, Bellman
explained that he
invented the name dynamic
programming to hide the fact
that he was doing
mathematical research.
He was working at this
place called Rand,
and under a secretary of defense
who had a pathological fear
and hatred for
the term research.
So he settled on the
term dynamic programming
because it would be
difficult to give
a pejorative meaning to it.
And because it was
something not even
a congressman could object to.
Basically, it sounded cool.
So that's the origin of the
name dynamic programming.
So why is the called that?
Who knows.
I mean, now you know.
But it's not--
it's a weird term.

Turkish: 
neden denir
dinamik program.
Dinamik programlama icat edildi
Richard Bellman adında biri tarafından.
Bellman'ı duymuş olabilirsin.
Bellman-Ford algoritmasında.
Yani bu aslında
Bellman-Ford habercisi.
Ve göreceğiz
Bellman-Ford doğal olarak gündeme geldi
bu ayarda.
Yani burada onun hakkında bir alıntı.
Diyor ki, Bellman
o açıkladı
dinamik adını icat etti
gerçeği gizlemek için programlama
yapıyordu
matematiksel araştırma.
Bu konuda çalışıyordu
Rand diye bir yer
ve savunma sekreteri altında
patolojik korkusu olan
ve nefret
araştırma terimi.
Böylece o yerleşti
dinamik programlama terimi
çünkü olacak
vermek zor
buna aşağılayıcı bir anlam.
Ve çünkü öyleydi
bir şey bile değil
Bir kongre üyesi itiraz edebilir.
Temel olarak, kulağa hoş geliyordu.
Yani bu kökeni
dinamik programlama adını verir.
Peki neden buna denir?
Kim bilir.
Yani, şimdi biliyorsun.
Ama değil--
bu garip bir terim.

Turkish: 
Sadece ne olduğu için al.
 
Bazı yapabilir
biraz mantıklı ama ...
Tamam.
Yani başlayacağız
bu örnekle nasıl
Fibonacci sayılarını hesaplamak.
Ve belki önce
aslında başlıyoruz
Sana vereceğim
ne gizlice bir zirve
düşünebilirsin
dinamik programlama olarak.
Ve bu denklem,
tabiri caizse
boyunca değişecek
bugünün dersi.
Sonunda biz
bir çeşit anlaşmaya varmak
daha doğru bir bakış açısı.
Temel fikir
dinamik program
sorun çıkarmak
alt problemlere ayır,
bu alt sorunları çözebilir,
ve çözümleri tekrar kullanın
senin alt problemlerine.
Geri dönüşüm dersi gibi.

English: 
Just take it for what it is.
It may make some
kind of sense, but--
All right.
So we are going to start
with this example of how
to compute Fibonacci numbers.
And maybe before
we actually start
I'm going to give you
a sneak peak of what
you can think of
dynamic programming as.
And this equation,
so to speak, is
going to change throughout
today's lecture.
In the end we'll
settle on a sort
of more accurate perspective.
The basic idea of
dynamic programming
is to take a problem,
split it into subproblems,
solve those subproblems,
and reuse the solutions
to your subproblems.
It's like a lesson in recycling.

English: 
So we'll see that in
Fibonacci numbers.
So you remember
Fibonacci numbers, right?
The number of rabbits you have
on day n, if they reproduce.
We've mentioned them before,
we're talking about AVL trees,
I think.
So this is the
usual-- you can think
of it as a recursive definition
or recurrence on Fibonacci
numbers.
It's the definition of what
the nth Fibonacci number is.
So let's suppose our goal--
an algorithmic problem is,
compute the nth
Fibonacci number.
And I'm going to assume here
that that fits in a word.
And so basic
arithmetic, addition,
whatever's constant
time per operation.
So how do we do it?
You all know how to do it.
Anyways-- but I'm going to give
you the dynamic programming
perspective on things.

Turkish: 
Yani bunu göreceğiz
Fibonacci sayıları.
Yani hatırlıyorsun
Fibonacci sayıları, değil mi?
Sahip olduğun tavşan sayısı
çoğalırlarsa n günü.
 
Onlardan daha önce bahsettik,
AVL ağaçları hakkında konuşuyoruz
Bence.
Yani bu
her zamanki gibi düşünebilirsin
özyinelemeli bir tanım olarak
veya Fibonacci'de nüks
sayılar.
Neyin tanımı
nt Fibonacci sayısı.
Diyelim ki hedefimiz ...
algoritmik bir problem
nth'yi hesapla
Fibonacci numarası.
Ve burada varsayılacağım
bir kelimeye uyan şey.
Ve çok basit
aritmetik, toplama
her ne ise sabit
operasyon başına süre.
Peki nasıl yapıyoruz?
Hepiniz nasıl yapılacağını biliyorsunuz.
Her neyse-- ama ben vereceğim
sen dinamik programlama
şeylere bakış açısı.

English: 
So this will seem
kind of obvious,
but it is-- we're going to apply
exactly the same principles
that we will apply over and
over in dynamic programming.
But here it's in a
very familiar setting.
So we're going to start with
the naive recursive algorithm.
And that is, if you want to
compute the nth Fibonacci
number, you check whether
you're in the base case.
I'm going to write it this way.
So f is just our return value.
You'll see why I write
it this way in a moment.

Turkish: 
Yani bu görünecek
biraz açık,
ama bu-- biz başvuracağız
tam olarak aynı ilkeler
uygulayacağımız ve
dinamik programlamada bitti.
Ama burada bir
çok tanıdık ayar.
Yani başlayacağız
saf özyinelemeli algoritması.
 
Ve eğer istersen
nt Fibonacci'yi hesaplar
numarayı kontrol edip etmediğini kontrol et.
Ana davamdasın.
 
Bunu bu şekilde yazacağım.
 
Öyleyse f, sadece dönüş değerimizdir.
Neden yazdığımı anlayacaksın
bir dakika içinde bu şekilde.

English: 
Then you return f.
In the base case
it's 1, otherwise
you recursively call
Fibonacci of n minus 1.
You recursively call
Fibonacci of n minus 2.
Add them together, return that.
This is a correct algorithm.
Is it a good algorithm?
No.
It's very bad.
Exponential time.
How do we know it's
exponential time,
other than from experience?
Well, we can write the
running time as recurrence.
T of n represents the time
to compute the nth Fibonacci
number.
How can I write the recurrence?
You're gonna throwback to
the early lectures, divide
and conquer.
I hear whispers.
Yeah?
AUDIENCE: [INAUDIBLE].
PROFESSOR: Yeah.

Turkish: 
O zaman f.
Temel durumda
1, aksi takdirde
özyinelemeli arama
N eksi 1'in Fibonacci'si.
Özyinelemeli çağrı
N eksi 2 Fibonacci.
Onları topla, geri ver.
Bu doğru bir algoritma.
İyi bir algoritma mı?
Yok hayır.
Bu çok kötü.
Üstel zaman.
 
Bunu nasıl biliyoruz?
üstel zaman,
deneyimden başka?
Peki, biz yazabiliriz
tekrarlama olarak çalışma süresi.
N nin T zamanı gösterir
F Fibonacci’yi hesaplamak
numara.
Nüksü nasıl yazabilirim?
Geri çekileceksin
erken dersler, böl
ve fethetmek.
 
Fısıltılar duyuyorum.
Evet?
Seyirci: [duyulmuyor].
 
PROFESÖR: Evet.

English: 
T of n minus 1 plus t of
n minus 2 plus constant.
I don't know how
many you have by now.
So to create the
nth Fibonacci number
we have to compute the n
minus first Fibonacci number,
and the n minus second
Fibonacci number.
That's these two recursions.
And then we take
constant time otherwise.
We do constant number of
additions, comparisons.
Return all these operations--
take constant time.
So that's a recurrence.
How do we solve this recurrence?
Well one way is to see this
is the Fibonacci recurrence.
So it's the same thing.
There's this plus whatever.
But in particular, this is at
least the nth Fibonacci number.
And if you know
Fibonacci stuff, that's
about the golden ratio
to the nth power.
Which is bad.
We had a similar
recurrence in AVL trees.
And so another way
to solve it-- it's
just good review--
say, oh well, that's

Turkish: 
N eksi 1 artı t
n eksi 2 artı sabit.
 
Nasıl bilmiyorum
Şimdiye kadar sahip olduğunuz birçok kişi.
 
Yani oluşturmak için
Fibonacci sayısı
n'yi hesaplamamız gerekiyor
eksi ilk Fibonacci sayısı,
ve n eksi ikinci
Fibonacci numarası.
Bu iki özyineleme.
Ve sonra alırız
Aksi halde sabit zaman.
Sabit sayı yapıyoruz
ilaveler, karşılaştırmalar.
Bütün bu işlemleri iade et.
sabit zaman ayırın.
Yani bu bir nüks.
Bu nüksü nasıl çözeriz?
Bunu görmenin en iyi yolu
Fibonacci nüksü.
Yani aynı şey.
Bu artı her neyse var.
Ama özellikle, bu
en az nt Fibonacci sayısı.
Ve eğer biliyorsan
Fibonacci olayı, bu
Altın oran hakkında
Nihai güce.
Hangi kötü.
Biz benzer
AVL ağaçlarında tekrarlama.
Ve böylece başka bir yol
Bunu çözmek için--
sadece iyi bir inceleme ...
de ki, ah peki, bu

Turkish: 
en az 2 kez t n eksi 2.
Çünkü gidiyor
monoton olmak.
Büyük n,
yapman gereken daha çok iş.
Çünkü yapmak için
en çok sahip olduğun şey
n eksi ilk şey yapmak için.
Böylece sadece t azaltmak
n eksi 1 ila t n eksi 2.
Bu bize daha düşük bir sınır verecek.
Ve şimdi bu iki terim-- şimdi
Bu kolay bir şey.
Görüyorsun
her seferinde 2 ile çarpma.
Çıkarıyorsun
Her seferinde n'den 2.
Kaç kere
2'yi n'den çıkarırım?
N / 2 kez, benden önce
bir sabite inmek.
Ve bu eşittir
2'den n'ye 2-
Yani, bazı zamanlar
sabit olan
ne alıyorsun
temel durumda.
Sanırım teta demeliyim.
Bu şey şu.
TAMAM.
Yani en azından o kadar büyük.
Ve doğru sabit phi.
Üstelik üssü.
TAMAM.

English: 
at least 2 times t of n minus 2.
Because it's going
to be monotone.
The bigger n is, the
more work you have to do.
Because to do the
nth thing you have
to do the n minus first thing.
So we could just reduce t of
n minus 1 to t of n minus 2.
That will give us a lower bound.
And now these two terms-- now
this is sort of an easy thing.
You see that you're
multiplying by 2 each time.
You're subtracting
2 from n each time.
How many times can
I subtract 2 from n?
N/2 times, before I
get down to a constant.
And so this is equal
to 2 to the n over 2--
I mean, times some
constant, which
is what you get
in the base case.
So I guess I should say theta.
This thing is theta that.
OK.
So it's at least that big.
And the right constant is phi.
And the base of the exponent.
OK.

English: 
So that's a bad algorithm.
We all know it's
a bad algorithm.
But I'm going to give you a
general approach for making
bad algorithms like this good.
And that general approach
is called memoization.
We'll go over here.
And this is a technique
of dynamic programming.
So I'm going to call this the
memoized dynamic programming
algorithm.
So did I settle on
using memo in the notes?
Yeah.
The idea is simple.
Whenever we compute
a Fibonacci number
we put it in a dictionary.
And then when we need to
compute the nth Fibonacci
number we check, is it
already in the dictionary?

Turkish: 
Yani bu kötü bir algoritma.
Hepimiz biliyoruz ki
Kötü bir algoritma.
Ama sana bir tane vereceğim
genel yaklaşım
Bunun gibi kötü algoritmalar.
Ve bu genel yaklaşım
memoization denir.
 
Buraya gideceğiz.
 
Ve bu bir tekniktir
Dinamik programlama.
 
Yani bunu arayacağım
hafızaya alınmış dinamik programlama
algoritması.
 
Ben de anlaştım
notlarda not kullanımı?
Evet.
 
Fikir basit.
Ne zaman hesaplarsak
bir Fibonacci numarası
bir sözlüğe koyduk.
Ve sonra ihtiyacımız olduğunda
nt Fibonacci'yi hesaplar
kontrol ettiğimiz numara, öyle mi
zaten sözlükte

Turkish: 
Biz zaten yaptık
bu problemi çöz?
Eğer öyleyse, o cevabı geri gönder.
Aksi takdirde, bilgisayar.
Dönüşüm göreceksiniz
çok basit.
 
TAMAM.

English: 
Did we already
solve this problem?
If so, return that answer.
Otherwise, computer it.
You'll see the transformation
is very simple.
OK.

English: 
These two lines are
identical to these two lines.
So you can see how
the transformation
works in general.
You could do this with
any recursive algorithm.
The memoization transformation
on that algorithm--
which is, we initially make an
empty dictionary called memo.
And before we actually do
the computation we say,
well, check whether this version
of the Fibonacci problem,
computing f of n, is
already in our dictionary.
So if that key is already
in the dictionary,
we return the corresponding
value in the dictionary.
And then once we've computed
the nth Fibonacci number,
if we bothered to do this,
if this didn't apply,
then we store it
in the memo table.
So we say well, if you ever
need to compute f of n again,
here it is.
And then we return that value.
So this is a general procedure.

Turkish: 
Bu iki satır
bu iki çizgi ile aynı.
Böylece nasıl olduğunu görebilirsiniz
dönüşüm
genel olarak çalışır.
Bunu ile yapabilirsin
herhangi bir özyinelemeli algoritma.
Notlama dönüşümü
Bu algoritmada ...
yani başlangıçta bir
boş sözlük notu denir.
Ve biz gerçekten yapmadan önce
söylediğimiz hesaplama,
iyi, bu sürüm olup olmadığını kontrol edin
Fibonacci sorununun
n'nin hesaplanması,
zaten bizim sözlüğümüzde.
Yani bu anahtar zaten ise
sözlükte,
biz karşılık geliriz
sözlükteki değer.
 
Ve sonra bir kere hesapladık
fibonacci sayısı
eğer bunu yapmak için uğraştıysak,
eğer bu geçerli değilse,
sonra depolarız
Not tablosunda.
Öyleyse iyi diyoruz, eğer hiç
n'den f değerini tekrar hesaplamamız gerekiyor,
işte burada.
Ve sonra bu değeri döndürürüz.
Yani bu genel bir prosedür.

Turkish: 
Herhangi bir için geçerli olabilir
özyinelemeli algoritma
yan etkisi yok
Teknik olarak sanırım.
Ve çıkıyor, bu
algoritma verimli.
Şimdi çok yol var
neden etkili olduğunu görmek için.
 
Genel olarak, belki yardımcı olur
özyineleme hakkında düşünmek
ağacı.
Öyleyse hesaplamak istiyorsan
eski algoritmada fn,
fn eksi hesaplıyoruz
1 ve fn eksi iki
tamamen ayrı.
Fn eksi 1 hesaplamak için
fn eksi 2 ve fn eksi 3.
Fn eksi 2'yi hesaplamak için hesaplıyoruz
fn eksi 3 ve fn eksi 4.
Ve bunun gibi.
Ve neden olduğunu görebilirsiniz
bu üstel
Çünkü biz sadece azalıyoruz
n her seferinde bir veya iki ile.
Ama sonra gözlemlersin, hey,
bu fn eksi 3'ler aynıdır.
Gerçekten sadece sahip olmalıyım
onları bir kez hesaplamak için.
Ve bu ne
burada yapıyoruz.
İlk aradığınızda
eksi 3'te, sen iş yaparsın.
Ama bir kere bittikten sonra sen git
bu diğer özyineli üzerinde

English: 
It can apply to any
recursive algorithm
with no side effects
I guess, technically.
And it turns out, this makes
the algorithm efficient.
Now there's a lot of ways
to see why it's efficient.
In general, maybe it's helpful
to think about the recursion
tree.
So if you want to compute
fn in the old algorithm,
we compute fn minus
1 and fn minus two
completely separately.
To compute fn minus 1 we compute
fn minus 2 and fn minus 3.
To compute fn minus 2 we compute
fn minus 3 and fn minus 4.
And so on.
And you can see why
that's exponential in n.
Because we're only decrementing
n by one or two each time.
But then you observe, hey,
these fn minus 3's are the same.
I should really only have
to compute them once.
And that's what
we're doing here.
The first time you call
fn minus 3, you do work.
But once it's done and you go
over to this other recursive

English: 
call, this will
just get cut off.
There's no tree here.
Here we might have
some recursive calling.
Here we won't, because it's
already in the memo table.
In fact, this already
happens with fn minus 2.
This whole tree disappears
because fn minus 2
has already been done.
OK.
So it's clear why
it improves things.
So in fact you can argue
that this call will be free
because you already
did the work in here.
But I want to give you a very
particular way of thinking
about why this is efficient,
which is following.

Turkish: 
ara, bu olacak
sadece kes gitsin.
Burada ağaç yok.
Burada olabilir
bazı özyinelemeli arama.
İşte yapmayacağız, çünkü o
zaten not tablosunda.
Aslında, bu zaten
fn eksi 2 ile olur.
Bütün bu ağaç kayboluyor
çünkü fn eksi 2
zaten yapıldı.
TAMAM.
Yani neden belli
şeyleri iyileştirir.
Yani aslında tartışabilirsin
bu çağrının ücretsiz olacağını
çünkü sen zaten
işi burada yaptım.
Ama sana çok vermek istiyorum
özel düşünme yolu
Bunun neden etkili olduğu hakkında,
takip ediyor.

Turkish: 
 
Böylece bir yazabilirsiniz
çalışma süresinin tekrarı
İşte.
Fakat bir anlamda nüks
doğru yol değil mi
hakkında düşünme
bu çünkü özyineleme
Bu nadir bir şey.
Sen arıyorsan
Bir değere sahip Fibonacci, k,
sadece yapacaksın
özyinelemeli ilk kez aramalar
K of Fibonacci'yi ara.
Çünkü bundan böyle,
sen koydun
not tablosunda
tekrar etmeyeceksin.
Yani düşünebilirsin
iki versiyon var
of Fibonacci'yi
İlk defa var, ki
Notlandırılmamış sürüm
özyineleme yapar-- bazı işler yapar.
Ve sonra her zaman
bundan böyle sen
memoized aramalar yapmak
of Fibonacci
ve bu sabit zaman maliyeti.
Yani hafızadaki aramalar
sabit maliyet süresi.

English: 
So you could write down a
recurrence for the running time
here.
But in some sense recurrences
aren't quite the right way
of thinking about
this because recursion
is kind of a rare thing.
If you're calling
Fibonacci of some value, k,
you're only going to make
recursive calls the first time
you call Fibonacci of k.
Because henceforth,
you've put it
in the memo table
you will not recurse.
So you can think of
there being two versions
of calling Fibonacci of k.
There's the first time, which
is the non-memoized version that
does recursion-- does some work.
And then every time
henceforth you're
doing memoized calls
of Fibonacci of k,
and those cost constant time.
So the memoized calls
cost constant time.

Turkish: 
Böylece düşünebiliriz
Onları temelde ücretsiz.
O zaman aradın
N eksi 2 Fibonacci,
çünkü bu bir
faturasız arama, gerçekten
bunun için hiçbir şey ödeme.
Demek istediğim, sen zaten
sabit zaman ödeme
ekleme yapmak ve her neyse.
Yani zorunda değilsin
zaman için endişeleniyorum.
Burada tekrarlama yok.
Ve sonra ne umurumuzda
yaklaşık bu sayı
hafızaya alınmayan aramalardan
hangisi ilk
k of Fibonacci, n.
Hiçbir teta gerekli değildir.
Gidiyoruz
1 numaradan Fibonacci'yi arayın.
Bir noktada gidiyoruz
2 Fibonacci'yi arayacak
bir noktada ve orijinal
çağrı, N'nin Fibonacci'sidir.
Bunların hepsi olacak
bir noktada çağrılmak.
Bunu görmek oldukça kolay.
Ama özellikle,
kesinlikle en fazla bu
asla aramadık
N artı Fibonacci 1
Fibonacci'yi n.
Bu yüzden en n aramaları.

English: 
So we can think of
them as basically free.
That's when you call
Fibonacci of n minus 2,
because that's a
memoized call, you really
don't pay anything for it.
I mean, you're already
paying constant time
to do addition and whatever.
So you don't have to
worry about the time.
There's no recursion here.
And then what we care
about is that the number
of non-memorized calls,
which is the first time you
call Fibonacci of k, is n.
No theta is even necessary.
We are going to
call Fibonacci of 1.
At some point we're going
to call Fibonacci of 2
at some point, and the original
call is Fibonacci of n.
All of those things will
be called at some point.
That's pretty easy to see.
But in particular,
certainly at most this,
we never call
Fibonacci of n plus 1
to compute Fibonacci of n.
So it's at most n calls.

English: 
Indeed it will be exactly n
calls that are not memoized.
Those ones we have to pay for.
How much do we have to pay?
Well, if you don't count
the recursion-- which
is what this recurrence
does-- if you ignore
recursion then the total amount
of work done here is constant.
So I will say the non-recursive
work per call is constant.
And therefore I claim
that the running time is
constant-- I'm sorry, is linear.
Constant would be
pretty amazing.
This is actually not the
best algorithm-- as an aside.
The best algorithm for computing
the nth Fibonacci number
uses log n arithmetic
operations.
So you can do better,
but if you want
to see that you
should take 6046.
OK.
We're just going to get
to linear today, which

Turkish: 
Gerçekten de tam olarak n olacak
not alınmayan aramalar.
Bu paraları ödemek zorundayız.
Ne kadar ödemek zorundayız?
Şey, saymazsan
özyineleme-- ki
bu nüks nedir
görmezden gelirsen
özyineleme ardından toplam tutar
Burada yapılan iş sabittir.
 
Böylece özyinelemeli olmayan diyeceğim
arama başına iş sabittir.
Ve bu yüzden iddia ediyorum
çalışma süresi
sürekli-- üzgünüm, doğrusal.
Sabit olurdu
oldukça Muhteşem.
Bu aslında değil
En iyi algoritma-- bir kenara.
Bilgi işlem için en iyi algoritma
nt Fibonacci sayısı
log n aritmetik kullanır
operasyonlar.
Yani daha iyisini yapabilirsin
fakat istiyorsan
seni görmek için
6046 almalı.
TAMAM.
Sadece alacağız
bugün doğrusal olan

English: 
is a lot better
than exponential.
So why linear?
Because there's n non-memoize
calls, and each of them
cost constant.
So it's the product
of those two numbers.
This is an important idea.
And it's so important
I'm going to write it
down again in a slightly
more general framework.
In general, in
dynamic programming--
I didn't say why it's
called memoization.
The idea is you have
this memo pad where
you write down all
your scratch work.
That's this memo dictionary.
And to memoize is to write
down on your memo pad.
I didn't make it up.
Another crazy term.
It means remember.
And then you remember all the
solutions that you've done.

Turkish: 
çok daha iyi
üstel.
Peki neden doğrusal?
Çünkü faturasızlık yok
aramalar ve her biri
maliyet sabiti.
Yani ürün
bu iki sayının.
Bu önemli bir fikir.
Ve bu çok önemli
Ben yazacağım
tekrar biraz aşağıya
daha genel bir çerçeve.
Genel olarak, içinde
dinamik program--
Neden olduğunu söylemedim
faturalama denir.
Fikir senin
bu bloknot nerede
hepsini yaz
çizik işin.
Bu not defteri sözlüğü.
Ve hatırlamak yazmaktır
not defterinizde aşağı.
Ben yapmadım.
Bir başka çılgın terim.
Hatırlamak demek oluyor.
Ve sonra hepsini hatırlarsın.
Yaptığınız çözümler.

English: 
And then you reuse
those solutions.
Now these solutions are
not really a solution
to the problem
that I care about.
The problem I care about is
computing the nth Fibonacci
number.
To get there I had to compute
other Fibonacci numbers.
Why?
Because I had a
recursive formulation.
This is not always the
way to solve a problem.
But usually when you're
solving something
you can split it into parts,
into subproblems, we call them.
They're not always
of the same flavor
as your original goal
problem, but there's
some kind of related parts.
And this is the big challenge
in designing a dynamic program,
is to figure out what
are the subproblems.
Let's say, the
first thing I want
to know about a dynamic program,
is what are the subproblems.
Somehow they are designed to
help solve your actual problem.

Turkish: 
Ve sonra tekrar kullanıyorsun
bu çözümler.
Şimdi bu çözümler
tam bir çözüm değil
soruna
Ben umursuyorum.
Önemsediğim sorun
nt Fibonacci'nin hesaplanması
numara.
Oraya ulaşmak için hesaplamak zorunda kaldım
diğer Fibonacci sayıları.
Niye ya?
Çünkü ben bir
özyinelemeli formülasyon.
Bu her zaman değil
bir sorunu çözmenin yolu.
Ama genellikle sen
bir şey çözme
parçalara bölebilirsiniz,
Alt problemlere, onları diyoruz.
Onlar her zaman değil
aynı tadın
asıl amacın olarak
sorun var ama var
Bir çeşit ilgili parça.
Ve bu büyük zorluk
Dinamik bir program tasarlarken,
ne olduğunu bulmak
alt problemler.
Diyelim ki,
istediğim ilk şey
Dinamik bir program hakkında bilmek,
Alt sorunlar nelerdir.
 
Her nasılsa onlar için tasarlanmış
Asıl sorununuzu çözmenize yardımcı olur.
 

English: 
And the idea of memoization is,
once you solve a subproblem,
write down the answer.
If you ever need to solve
that same problem again
you reuse the answer.
So that is the core idea.
And so in this sense
dynamic programming
is essentially recursion
plus memoization.
And so in this case these
are the subproblems.
Fibonacci of 1 through
Fibonacci of n.
The one we care about
is Fibonacci of n.
But to get there we solve
these other subproblems.
In all cases, if this
is the situation-- so
for any dynamic program,
the running time
is going to be equal to the
number of different subproblems
you might have to solve,
or that you do solve,
times the amount of time
you spend per subproblem.

Turkish: 
Ve not alma fikri,
Bir alt problemi çözdükten sonra,
cevabı yaz.
Çözmen gerekirse
yine aynı problem
cevabı tekrar kullandın.
Demek ki ana fikir bu.
Ve böylece bu anlamda
dinamik program
aslında özyinelemektir
artı notlandırma.
 
Ve böylece bu durumda bunlar
alt problemler.
1'den Fibonacci'ye
N 'nin Fibonacci'si
Umurumuzda olan
N'nin Fibonacci'si.
Ama oraya ulaşmak için çözeriz
bu diğer alt problemler.
 
Her durumda, eğer bu
durum bu
Herhangi bir dinamik program için,
koşu zamanı
eşit olacak
farklı alt problemlerin sayısı
çözmek zorunda kalabilirsiniz
veya çözersen,
zaman miktarının
Alt problem için harcıyorsun.

English: 
OK.
In this situation we
had n subproblems.
And for each of them
we spent constant time.
And when I measure the
time per subproblem
which, in the Fibonacci
case I claim is constant,
I ignore recursive calls.
That's the key.
We don't have to
solve recurrences
with dynamic programming.
Yay.
No recurrences necessary.
OK.
Don't count recursions.
Obviously, don't count
memoized recursions.
The reason is, I only
need to count them once.
After the first time
I do it, it's free.
So I count how many different
subproblems do I need to do?
These are they going to be
the expensive recursions where
I do work, I do
some amount of work,
but I don't count the
recursions because otherwise I'd
be double counting.
I only want to count
each subproblem once,
and then this will solve it.

Turkish: 
 
TAMAM.
Bu durumda biz
n alt sorunu vardı.
Ve her biri için
sabit zaman harcadık.
Ve ölçtüğümde
Alt problem başına süre
hangi, Fibonacci içinde
iddia ettiğim dava sabittir
Özyinelemeli aramaları görmezden geliyorum.
Anahtar bu.
Zorunda değiliz
yinelemeleri çöz
dinamik programlama ile.
Yuppi.
Tekrarlama gerekli değil.
TAMAM.
Özyinelemeleri saymayın.
 
Açıkçası, sayma
kaydedilmiş özyinelemeler.
Sebebi sadece ben
onları bir kez saymam gerek.
İlk defadan sonra
Yaparım, ücretsiz.
Bu yüzden kaç farklı sayılır
alt sorunları yapmam gerekiyor mu?
Bunlar onlar olacak
pahalı özyineler nerede
Çalışıyorum
bir miktar iş,
ama ben saymıyorum
özyinelemeler çünkü aksi takdirde
çift ​​saymak.
Sadece saymak istiyorum
her alt problem bir kere,
ve sonra bu çözecektir.

English: 
So a simple idea.
In general, dynamic programming
is a super simple idea.
It's nothing fancy.
It's basically just memoization.
There is one extra trick
we're going to pull out,
but that's the idea.
All right.
Let me tell you
another perspective.
This is the one maybe
most commonly taught.
Is to think of-- but I'm
not a particular fan of it.
I really like memoization.
I think it's a simple idea.
And as long as you
remember this formula here,
it's really easy to work with.
But some people like to
think of it this way.
And so you can pick whichever
way you find most intuitive.
Instead of thinking of a
recursive algorithm, which
in some sense starts at the
top of what you want to solve
and works its way down,
you could do the reverse.

Turkish: 
Yani basit bir fikir.
Genel olarak, dinamik programlama
süper basit bir fikir.
Fantezi bir şey değil.
Temel olarak sadece notlandırma.
Fazladan bir numara var.
biz çekeceğiz
ama bu fikir.
Tamam.
Sana söyleyeyim
başka bir bakış açısı.
Bu belki olanıdır
En sık öğretilen.
Düşünmek lazım-- ama ben
belirli bir hayranı değil.
Gerçekten not almayı seviyorum.
Bence basit bir fikir.
Ve sen sürece
buradaki bu formülü hatırla
çalışmak gerçekten kolay.
 
Ancak bazı insanlar gibi
bu şekilde düşün.
Ve hangisini seçersen seç
en sezgisel bulmanın yolu.
Düşünmek yerine
özyinelemeli algoritma, hangi
bir anlamda,
çözmek istediğiniz şeyin üst kısmı
ve aşağıya iniyor
tersini yapabilirsin.

Turkish: 
Başlayabilirsin
aşağı ve yukarı doğru çalışın.
Ve bu muhtemelen
normalde nasılsın
hesaplama hakkında düşün
Fibonacci sayıları
veya daha önce nasıl öğrendin.
Ben yazacağım
biraz komik bir şekilde.
 
Nokta yapmak istiyorum
bu dönüşüm
Naiften yapıyorum
özyinelemeli algoritma,
hafızaya alınmış algoritmaya,
aşağıdan yukarıya doğru bir algoritma
tamamen otomatik.
Düşünmüyorum
Ben sadece yapıyorum.
TAMAM.
Bu kolay.
Bu kod tam olarak
bu kodla aynı
ve bu kod hariç
N'yi k ile değiştirdim.
Sadece bir çifte ihtiyacım olduğu için
Burada farklı n değerleri.

English: 
You could start at the
bottom and work your way up.
And this is probably
how you normally
think about computing
Fibonacci numbers
or how you learned it before.
I'm going to write it
in a slightly funny way.
The point I want to make
is that the transformation
I'm doing from the naive
recursive algorithm,
to the memoized algorithm,
to the bottom-up algorithm
is completely automated.
I'm not thinking,
I'm just doing.
OK.
It's easy.
This code is exactly
the same as this code
and as that code, except
I replaced n by k.
Just because I needed a couple
of different n values here.

Turkish: 
Veya yinelemek istiyorum
n değerinin üzerinde.
 
Ve sonra bu var
bu kodun etrafındakiler
bu sadece formül.
 
Biraz düşünce
döngü için bu içine gider,
ama bu kadar.
TAMAM.
Bu tamamen aynı şeyi yapar
hafızaya alınmış algoritma olarak bir şey.
 
Belki bir
biraz düşünme
farkına varmak, hepsini açmak
gerçekleşen özyineleme
buraya ve sadece yaz
sırayla dışarı,
tam olarak bu
ne oluyor.
Bu kod tam olarak
tam olarak aynı ilaveler
bununla aynı hesaplamalar.
Tek fark
oraya nasıl gideceksin.
Burada bir döngü kullanıyoruz
burada özyineleme kullanıyoruz.
Ama aynı şeyler
aynı sırada olur.
Gerçekten fark yok
kod arasında.
Bu kod muhtemelen gidiyor
Daha verimli bir uygulama olmak
çünkü sen yapmıyorsun
işlev çok çağırıyor.
Aslında ben bir
Burada küçük bir hata.
Bu bir ... Değil
işlev çağrısı, bu
sadece bir masaya bir arama.

English: 
Or I want to iterate
over n values.
And then there's this
stuff around that code
which is just formulaic.
A little bit of thought
goes into this for loop,
but that's it.
OK.
This does exactly the same
thing as the memoized algorithm.
Maybe it takes a
little bit of thinking
to realize, if you unroll all
the recursion that's happening
here and just write
it out sequentially,
this is exactly
what's happening.
This code does exactly the
same additions, exactly
the same computations as this.
The only difference
is how you get there.
Here we're using a loop,
here we're using recursion.
But the same things
happen in the same order.
It's really no difference
between the code.
This code's probably going
to be more efficient practice
because you don't make
function calls so much.
In fact I made a
little mistake here.
This is not a
function call, it's
just a lookup into a table.

English: 
Here I'm using a hash
table to be simple,
but of course you
could use an array.
But they're both constant
time with good hashing.
All right.
So is it clear
what this is doing?
I think so.
I think I made a little typo.
So we have to compute--
oh, another typo.
We have to compute f1 up to
fn, which in python is that.
And we compute it
exactly how we used to.
Except now, instead
of recursing,
I know that when I'm computing
the k Fibonacci number-- man.
So many typos.
AUDIENCE: [LAUGHTER]
PROFESSOR: You
guys are laughing.
When I compute the
kth Fibonacci number
I know that I've already
computed the previous two.
Why?
Because I'm doing them
in increasing order.
Nothing fancy.
Then I can just do
this and the solutions
will just be waiting there.
If they work, I'd
get a key error.

Turkish: 
Burada bir karma kullanıyorum
tablonun basit olması
ama elbette sen
bir dizi kullanabilirsiniz.
 
Ama ikisi de sabittir
iyi karma ile zaman.
Tamam.
Çok açık
bu ne yapıyor
Ben de öyle düşünüyorum.
Galiba küçük bir yazım hatası yaptım.
Öyleyse hesaplamalıyız--
oh, başka bir yazım hatası.
F1'e kadar hesaplamalıyız.
fn, hangi python içinde budur.
Ve biz onu hesaplıyoruz
eskisi gibi.
Şimdi hariç
özyineleme,
Bunu hesaplarken biliyorum
k Fibonacci numarası--
Çok fazla yazım hatası var.
Seyirci: [kahkaha]
PROFESÖR: Siz
erkekler gülüyor.
Hesapladığımda
kth Fibonacci numarası
Biliyorum zaten
önceki ikisini hesapladı.
Niye ya?
Çünkü ben onları yapıyorum
artan sırada.
Hiçbir şey fantezi.
O zaman sadece yapabilirim
bu ve çözümler
sadece orada bekliyor olacağım.
Eğer çalışırlarsa
önemli bir hata al.

Turkish: 
Böylece bir böcek olduğunu bilirim.
Ama aslında, yapmayacağım
önemli bir hata al.
Her zaman hesaplamış olacağım
bunlar zaten.
Sonra masamda saklıyorum.
Sonra yineliyorum.
Sonunda hepsini çözdüm
fpro ile fn arasındaki alt problemler.
Ve umursadığım
yaklaşık nt biriydi.
TAMAM.
Çok basit.
Bunu yapıyorum çünkü
Gerçekten istemiyorum
geçmek zorunda olmak
bu dönüşüm
Yaptığımız her problem için.
Fibonacci'de yapıyorum
çünkü süper kolay
kodu yazmak için
açıkça.
Ama herkes için yapabilirsin
dinamik programların
içinde bulunduğumuz
sonraki dört ders.
TAMAM.
Sana vereceğim
şimdi genel durum.
Bu özel oldu
Fibonacci versiyonu.
Genelde aşağıdan yukarıya doğru
tam olarak aynı hesaplama
hafızaya alınmış bir sürüm olarak.
 
Ve yaptığımız şey
aslında bir topolojik sıralama

English: 
So I'd know that there's a bug.
But in fact, I won't
get a key error.
I will have always computed
these things already.
Then I store it in my table.
Then I iterate.
Eventually I've solved all the
subproblems, f1 through fn.
And the one I cared
about was the nth one.
OK.
So straightforward.
I do this because
I don't really want
to have to go through
this transformation
for every single problem we do.
I'm doing it in Fibonacci
because it's super easy
to write the code
out explicitly.
But you can do it for all
of the dynamic programs
that we cover in the
next four lectures.
OK.
I'm going to give you
now the general case.
This was the special
Fibonacci version.
In general, the bottom-up does
exactly the same computation
as the memoized version.
And what we're doing is
actually a topological sort

Turkish: 
alt problemin
bağımlılık DAG.
 
Yani bu durumda,
bağımlılık DAG çok basittir.
Hesaplamak için--
Bunu geriye doğru yapacağım.
Fn'yi hesaplamak için,
Fn eksi 1 bilmem gerekiyor
ve fn eksi 2.
Eğer bunları biliyorsam
Fn'yi hesaplayabilirim.
Sonra fn var
eksi 3, ki
bunu hesaplamak için gerekli
bir, ve o, ve diğerleri.
Yani ne görüyorsun
Bu DAG benziyor.
Şimdi çizdim
elverişli yani
tüm kenarlar soldan sağa gider.
Yani bu bir topolojik
soldan sağa sıralayın.
Ve bu yüzden sadece yapmam gerek
f1, f2, sırasıyla fn 'a kadar.
Genellikle tamamen
ne sipariş belli
Alt problemleri çözmek için.
Ama genel olarak, ne
aklında olmalısın

English: 
of the subproblem
dependency DAG.
So in this case, the
dependency DAG is very simple.
In order to compute--
I'll do it backwards.
In order to compute fn,
I need to know fn minus 1
and fn minus 2.
If I know those
I can compute fn.
Then there's fn
minus 3, which is
necessary to compute this
one, and that one, and so on.
So you see what
this DAG looks like.
Now, I've drawn
it conveniently so
all the edges go left to right.
So this is a topological
order from left to right.
And so I just need to do
f1, f2, up to fn in order.
Usually it's totally
obvious what order
to solve the subproblems in.
But in general, what
you should have in mind

English: 
is that we are doing
a topological sort.
Here we just did it in our
heads because it's so easy.
And usually it's so easy.
It's just a for loop.
Nothing fancy.
All right.
I'm missing an arrow.
All right.
Let's do something a little
more interesting, shall we?
All right.
One thing you can do from
this bottom-up perspective
is you can save space.
Storage space in the algorithm.
We don't usually worry
about space in this class,
but it matters in reality.
So here we're
building a table size,
n, but in fact we
really only need

Turkish: 
yapıyoruz
topolojik bir sıralama.
İşte biz sadece yaptım bizim
çünkü çok kolay.
Ve genellikle çok kolaydır.
Bu sadece bir döngü için.
Hiçbir şey fantezi.
 
Tamam.
 
Bir okunu özlüyorum.
 
Tamam.
Biraz bir şeyler yapalım
daha ilginç, olur mu?
 
Tamam.
Yapabileceğin bir şey var
bu aşağıdan yukarıya bakış açısı
yerden tasarruf edebilirsiniz.
 
Algoritmadaki depolama alanı.
Genelde endişelenmiyoruz
Bu sınıftaki alan hakkında
ama gerçekte önemli.
Yani buradayız
masa boyutu oluşturmak,
n, ama aslında biz
gerçekten sadece ihtiyaç

English: 
to remember the last two values.
So you could just store
the last two values,
and each time you make a
new one delete the oldest.
so by thinking a
little bit here you
realize you only
need constant space.
Still linear time,
but constant space.
And that's often the case.
From the bottom-up
perspective you
see what you really
need to store,
what you need to keep track of.
All right.
I guess another nice thing
about this perspective
is, the running time
is totally obvious.
This is clearly constant time.
So this is clearly linear time.
Whereas, in this
memoized algorithm
you have to think
about, when's it
going to be memoized,
when is it not?
I still like this perspective
because, with this rule,
just multiply a
number of subproblems
by time per subproblem,
you get the answer.
But it's a little less
obvious than code like this.
So choose however you
like to think about it.

Turkish: 
son iki değeri hatırlamak için.
Böylece sadece saklayabilirsin
son iki değer
ve her defasında
yenisi en eskisini siler.
yani bir düşünerek
biraz burda sen
sadece seni anlıyorum
sürekli alana ihtiyaç duymak.
Hala doğrusal zaman,
ama sabit alan.
Ve bu çoğu durumda.
Yukardan aşağa
perspektif sana
gerçekten ne olduğunu gör
saklamak gerekir
neleri takip etmeniz gerekiyor.
 
Tamam.
Başka güzel bir şey sanırım
bu bakış açısı hakkında
, çalışan zaman
tamamen açık.
Bu açıkça sabit bir zamandır.
Yani bu açıkça doğrusal bir zamandır.
Oysa bunun içinde
hafızaya alınmış algoritma
düşünmelisin
hakkında, ne zaman
Not edilecek
ne zaman değil
Bu perspektifi hala seviyorum
çünkü bu kural ile
Sadece bir çarpın
alt sorun sayısı
Alt problem başına zamana göre,
cevabı alırsın.
Ama biraz daha az
Bunun gibi bir koddan daha açık.
Öyleyse sen seç
düşünmeyi seviyorum.

Turkish: 
 
Tamam.
En kısa yollara ilerliyoruz.
 
Yani yine, her zamanki gibi düşünüyorum
Tek kaynaklı en kısa hakkında
yolları.
Yani biz hesaplamak istiyoruz
s 'den en kısa yol
herkes için v. Tamam
Bunu başlangıçta yazmak istiyorum
saf özyinelemeli algoritması olarak,
hangi sonra faturası olabilir,
hangi daha sonra aşağıdan yukarıya olabilir.
Ben uydurdum.
Peki bunu nasıl yazabilirim?
saf özyinelemeli bir algoritma?
Çok açık değil.

English: 
All right.
We move onto shortest paths.
So I'm again, as usual, thinking
about single-source shortest
paths.
So we want to compute the
shortest pathway from s
to v for all v. OK.
I'd like to write this initially
as a naive recursive algorithm,
which I can then memoize,
which I can then bottom-upify.
I just made that up.
So how could I write this as
a naive recursive algorithm?
It's not so obvious.

Turkish: 
Ama önce sana söyleyeceğim
nasıl, bir kehanetin söylediği gibi
sen, işte yapman gereken şey.
Ama sonra düşüneceğiz
hakkında-- geri dön, geri çekil.
Aslında sana bağlı.
Sana söyleyebilirim
cevap ve sonra
anlayabiliriz
oraya nasıl gittik
ya da sadece yapabiliriz
cevabı bul.
Tercihler?
 
Bir yolunu bul.
Tamam.
İyi.
İlahi ilham alınmasına izin yok.
Öyleyse sana bir araç vereyim.
Aracı tahmin ediyor.
 
Bu saçma gelebilir, ama
çok güçlü bir araçtır.
 
Genel fikir, varsayalım
bir şey bilmiyorsun
ama bunu bilmek istersin.
Peki cevap ne?
bu soruya
Bilmiyorum.
Dostum, gerçekten bir yastık istiyorum.
Nasıl gidiyorum
soruyu cevapla

English: 
But first I'm going to tell you
how, just as an oracle tells
you, here's what you should do.
But then we're going to think
about-- go back, step back.
Actually, it's up to you.
I could tell you
the answer and then
we could figure out
how we got there,
or we could just
figure out the answer.
Preferences?
Figure it out.
All right.
Good.
No divine inspiration allowed.
So let me give you a tool.
The tool is guessing.
This may sound silly, but
it's a very powerful tool.
The general idea is, suppose
you don't know something
but you'd like to know it.
So what's the answer
to this question?
I don't know.
Man, I really want a cushion.
How am I going to
answer the question?

English: 
Guess.
OK?
AUDIENCE: [LAUGHTER]
PROFESSOR: It's a
tried and tested method
for solving any problem.
I'm kind of belaboring
the point here.
The algorithmic concept is,
don't just try any guess.
Try them all.
OK?
AUDIENCE: [LAUGHTER]
PROFESSOR: Also pretty simple.
I said dynamic
programming was simple.
OK.
Try all guesses.
This is central to the
dynamic programming.
I know it sounds obvious, but if
I want to fix my equation here,
dynamic programming is roughly
recursion plus memoization.

Turkish: 
Tahmin.
TAMAM?
Seyirci: [kahkaha]
PROFESÖR: Bu bir
denenmiş ve test edilmiş yöntem
Herhangi bir problemi çözmek için.
 
Ben bir tür belaboring yapıyorum
buradaki nokta.
Algoritmik kavram,
sadece tahmin etmeye çalışmayın.
Hepsini dene.
TAMAM?
Seyirci: [kahkaha]
PROFESÖR: Ayrıca oldukça basit.
Dinamik dedim
programlama basitti.
TAMAM.
 
Tüm tahminleri dene.
Bu merkezi
dinamik program.
Kulağa açık geldiğini biliyorum ama
Denklemimi burada düzeltmek istiyorum.
dinamik programlama kabaca
özyineleme artı faturalama.

Turkish: 
Bu gerçekten olmalı
Olmak, artı tahmin etmek.
Belli ki
hangisinin açık olduğunu tahmin etmek,
temel kavramlar
dinamik programlamaya.
Ses çıkarmaya çalışıyorum
kolay çünkü genellikle insanlar
sorun yaşamak
dinamik program.
Kolay.
Tüm tahminleri dene.
Bu bir şey
bilgisayar harika yapabilir.
Bu kaba kuvvet kısmı.
TAMAM.
Ama biz gidiyoruz
dikkatlice yap.
Bu dikkatlice değil.
Yani biz sadece
tüm tahminleri deniyorum.
En iyisini al.
 
Bu önemli bir şey
birini seçebiliriz
en iyi şekilde aranmak.
Bu yüzden dinamik
programlama
optimizasyon problemleri için iyi.
Büyütmek istiyorsun
bir şey, bir şeyi küçültmek,
hepsini dene ve sonra sen
hepsini unutabilir
ve sadece azaltın
bir şey aşağı
en iyisi veya en iyisidir.
TAMAM.
Şimdi seni istiyorum
başvurmaya çalışmak
bu ilke
en kısa yollar.
Şimdi çizeceğim
yardımcı olabilecek resim.

English: 
This should really
be, plus guessing.
Memoization, which is obvious,
guessing which is obvious,
are the central concepts
to dynamic programming.
I'm trying to make it sound
easy because usually people
have trouble with
dynamic programming.
It is easy.
Try all the guesses.
That's something a
computer can do great.
This is the brute force part.
OK.
But we're going to
do it carefully.
Not that carefully.
I mean, we're just
trying all the guesses.
Take the best one.
That's kind of important
that we can choose one
to be called best.
That's why dynamic
programming is
good for optimization problems.
You want to maximize
something, minimize something,
you try them all and then you
can forget about all of them
and just reduce it
down to one thing which
is the best one, or a best one.
OK.
So now I want you
to try to apply
this principle to
shortest paths.
Now I'm going to draw a
picture which may help.

Turkish: 
Kaynağımız var,
bazı tepe noktalarımız var.
v. isteriz
en kısa olanı bul--
s'den v'ye en kısa yol
Diyelim ki bilmek istiyorum
Bu en kısa yol ne?
Diyelim ki bu öyleydi.
Zaten bir fikrin var mı?
Evet.
AUDIENCE: Yapabileceğin şey
her yere bakabilirsin
s'den gidebilirsin.
[INAUDIBLE] en kısa yol
bu notların her birinin
PROFESÖR: Güzel.
Böylece hepsine bakabilirim
s gidebileceğim yerler,
ve sonra en kısa olana bak
oradan oraya giden yollar
Böylece buna asal diyebiliriz.
İşte fikir.
Varsayımsal bazı var
en kısa yol.
Nerede bilmiyorum
önce o gider
bu yüzden tahmin edeceğim
ilk nereye gidiyor.
İlk ben biliyorum
kenar bir olmalı

English: 
We have the source, s,
we have some vertex,
v. We'd like to
find the shortest--
a shortest path from s to v.
Suppose I want to know
what this shortest path is.
Suppose this was it.
You have an idea already?
Yeah.
AUDIENCE: What you could do is
you could look at everywhere
you can go from s.
[INAUDIBLE] shortest path
of each of those notes.
PROFESSOR: Good.
So I can look at all the
places I could go from s,
and then look at the shortest
paths from there to v.
So we could call this s prime.
So here's the idea.
There's some hypothetical
shortest path.
I don't know where
it goes first,
so I will guess
where it goes first.
I know the first
edge must be one

Turkish: 
s'den giden kenarların sayısı.
Hangisini bilmiyorum.
Hepsini dene.
Çok basit bir fikir.
Sonra her birinden
onlar, eğer bir şekilde
en kısa olanı hesaplayabilir
oradan v yoluna,
sadece bunu yap ve
en iyi seçimi yap
o ilk kenarı neydi için.
Yani bu olurdu
birinci taraf yaklaşımını tahmin et.
 
Bu çok iyi bir fikir.
İstediğim tam olarak değil
çünkü maalesef
Bu s değiştirir.
Ve böylece bu olur
iş, sadece olur
biraz daha az ol
eğer verimli olursam
tek kaynaklı çözme
en kısa yollar.
Yani ince ayar yapacağım
bu fikir biraz
son kenarı tahmin ederek
ilk kenar yerine.
Gerçekten eşdeğerler.
Eğer bunu yapıyor olsaydım
Ben esasen
tek bir hedef çözme
en kısa yollar
daha önce konuştuğumuz şey.
Bu yüzden çizeceğim
Aynı resim
 
V ile ulaşmak istiyorum
son kenarı tahmin edeceğim

English: 
of the outgoing edges from s.
I don't know which one.
Try them all.
Very simple idea.
Then from each of
those, if somehow I
can compute the shortest
path from there to v,
just do that and
take the best choice
for what that first edge was.
So this would be the
guess first edge approach.
It's a very good idea.
Not quite the one I wanted
because unfortunately
that changes s.
And so this would
work, it would just
be slightly less
efficient if I'm
solving single-source
shortest paths.
So I'm going to tweak
that idea slightly
by guessing the last edge
instead of the first edge.
They're really equivalent.
If I was doing this
I'd essentially
be solving a single-target
shortest paths,
which we talked about before.
So I'm going to draw
the same picture.
I want to get to v. I'm
going to guess the last edge,

English: 
call it uv.
I know it's one of the incoming
edges to v-- unless s equals v,
then there's a special case.
As long as this path has
length of at least 1,
there's some last edge.
What is it?
I don't know.
Guess.
Guess all the possible
incoming edges to v, and then
recursively compute the
shortest path from s to u.
And then add on the edge v.
OK.
So what is this shortest path?
It's delta of s comma
u, which looks the same.
It's another subproblem
that I want to solve.
There's v subproblems
here I care about. .
So that's good.
I take that.
I add on the weight
of the edge uv.
And that should hopefully
give me delta of s comma v.
Well, if I was lucky and I
guessed the right choice of u.
In reality, I'm not lucky.

Turkish: 
onu ara
Bunun gelenlerden biri olduğunu biliyorum
kenarları v - s eşit olmadıkça
o zaman özel bir dava var.
Bu yolun olduğu sürece
en az 1 uzunluk,
son bir kenarı var.
Bu ne?
Bilmiyorum.
Tahmin.
Tüm mümkün sanırım
gelen kenarları v ve ardından
özyinelemeli hesaplamak
s'den u'ya en kısa yol.
Ve sonra kenara ekleyin v.
TAMAM.
Peki bu en kısa yol nedir?
S virgülün deltası
u, aynı görünüyor.
Başka bir alt problem
Bunu çözmek istiyorum.
V alt sorunları var
burada umurumda. .
Yani bu iyi.
Onu alıyorum.
Kilo eklerim
kenardan uv.
 
Ve umarım bu olmalı
bana virgül virgülü vermek
Şanslıysam ve ben
doğru seçimi tahmin etti.
Gerçekte, şanslı değilim.

Turkish: 
Bu yüzden küçültmek zorundayım
tüm kenarların üzerinden uv.
Demek bu ...
minimize ediyoruz
seçiminiz üzerinde.
Burada zaten V verilmiştir.
Bu yüzden en azını alıyorum
en kısa olanın tüm kenarları
s'den u'ya giden yol, artı
kenarın ağırlığı uv.
Bu bana en kısa vermeli
yol çünkü bu bana verdi
s'den u'ya giden en kısa yol.
Sonra kenarına ekledim
Oraya gitmem gerek.
Ve en kısa yol neresiyse
Bazı son kenarı kullanır, uv.
Başka bir seçenek olmalı.
senin, doğru olanı.
Bu iyi tahmin
ümit ettiğimizi.
Ne bilmiyoruz
iyi tahmin
bu yüzden hepsini denedik.
Ama her ne ise, bu olacak
bu yolun ağırlığı ol.
Alacak
s en iyi yolu
çünkü alt
yollar en kısa
yollar en kısa yollardır.
Optimal altyapı
Yani bu kısım olacak
su deltası olmak.
Bu bölüm açıkça uv.
Yani bu verecek
doğru cevap.
İnşallah.

English: 
So I have to minimize
over all edges uv.
So this is the--
we're minimizing
over the choice of u.
V is already given here.
So I take the minimum over
all edges of the shortest
path from s to u, plus
the weight of the edge uv.
That should give me the shortest
path because this gave me
the shortest path from s to u.
Then I added on the edge
I need to get there.
And wherever the shortest path
is, it uses some last edge, uv.
There's got to be some choice
of u that is the right one.
That's the good guess
that we're hoping for.
We don't know what
the good guess
is so we just try them all.
But whatever it is, this will
be the weight of that path.
It's going to take
the best path from s
to u because sub
paths are shortest
paths are shortest paths.
Optimal substructure.
So this part will
be delta of su.
This part is obviously w of uv.
So this will give
the right answer.
Hopefully.

English: 
OK.
It's certainly
going to-- I mean,
this is the analog of the
naive recursive algorithm
for Fibonacci.
So it's not going to be
efficient if I-- I mean,
this is an algorithm, right?
You could say-- this
is a recursive call.
We're going to treat this
as recursive call instead
of just a definition.
Then this is a
recursive algorithm.
How good or bad is this
recursive algorithm?
AUDIENCE: Terrible.
PROFESSOR: Terrible.
Very good.
Very bad, I should say.
It's definitely going
to be exponential
without memoization.
But we know.
We know how to make
algorithms better.
We memoize.
OK.
So I think you know how to write
this as a memoized algorithm.
To define the function delta
of sv, you first check,
is s comma v in the memo table?
If so return that value.
Otherwise, do this computation
where this is a recursive call

Turkish: 
TAMAM.
Kesinlikle
Gidiyorum-- Yani,
bu analog
saf özyinelemeli algoritma
Fibonacci için.
Yani olmayacak
verimli olsaydım ...
bu bir algoritma, değil mi?
Söyleyebilirsiniz-- bu
özyinelemeli bir çağrı.
Bunu tedavi edeceğiz
özyinelemeli arama yerine
sadece bir tanım.
O zaman bu bir
özyinelemeli algoritma.
Bu ne kadar iyi ya da kötü
özyinelemeli algoritma?
AUDIENCE: Korkunç.
PROFESÖR: Korkunç.
Çok iyi.
Çok kötü söylemeliyim.
 
Kesinlikle gidiyor
üstel olmak
faturalandırma olmadan.
Ama biz biliyoruz.
Nasıl yapılacağını biliyoruz
algoritmalar daha iyi.
Memoize ediyoruz.
TAMAM.
Bu yüzden nasıl yazılacağını bildiğini düşünüyorum.
bu hafızaya alınmış bir algoritma olarak.
Delta işlevini tanımlamak için
sv, önce sen kontrol et,
tablodaki virgül v nedir?
Öyleyse bu değeri döndür.
Aksi takdirde, bu hesaplamayı yapın
bu özyinelemeli arama nerede

English: 
and then stored it
in the memo table.
OK.
I don't think I need
to write that down.
It's just like the
memoized code over there.
Just there's now two
arguments instead of one.
In fact, s isn't changing.
So I only need to store
with v instead of s comma v.
Is that a good algorithm?
I claim memoization
makes everything faster.
Is that a fast algorithm?
Not so obvious, I guess.
Yes?
How many people think, yes,
that's a good algorithm?
AUDIENCE: Better.
PROFESSOR: Better.
Definitely better.
Can't be worse.

Turkish: 
ve sonra sakladı
Not tablosunda.
TAMAM.
İhtiyacım olduğunu sanmıyorum
Bunu yazmak için.
Aynı
orada kodlanmış bir kod var.
Sadece şimdi iki tane var
biri yerine argümanlar.
Aslında, s değişmiyor.
Bu yüzden sadece depolamak gerekir
s virgül yerine v ile
Bu iyi bir algoritma mı?
Dekontu talep ediyorum
her şeyi daha hızlı yapar.
Bu hızlı bir algoritma mı?
 
Çok açık değil sanırım.
 
Evet?
Kaç kişi düşünür, evet
Bu iyi bir algoritma mı?
AUDIENCE: Daha iyi.
PROFESÖR: Daha iyi.
Kesinlikle daha iyi.
 
Daha kötü olamaz.

English: 
How many people think it's
a bad algorithm still?
OK.
So three for yes, zero for no.
How many people aren't sure?
Including the yes votes?
Good.
All right.
It's not so tricky.
Let me draw you a graph.
Something like that.
So we wanted to commit
delta of s comma
v. Let me give these
guys names, a and b.
So we compute delta of
s comma v. To compute
that we need to know delta
of s comma a and delta
of s comma v. All right?
Those are the two ways-- sorry,
actually we just need one.
Only one incoming edge to v.
So its delta of s comma a.

Turkish: 
Kaç kişi olduğunu düşünüyorum
Hala kötü bir algoritma mı?
TAMAM.
Yani evet için üç, hayır için sıfır.
Kaç kişi emin değil?
Evet oyları dahil mi?
İyi.
 
Tamam.
O kadar zor değil.
Sana bir grafik çizeyim.
 
Bunun gibi bir şey.
Bu yüzden taahhüt etmek istedik
s virgül deltası
v. Bunları vereyim
erkek isimleri, a ve b.
Bu yüzden biz delta hesaplar
virgül v.
Delta'yı bilmemiz gerektiğini
s virgül a ve deltanın
s virgül v.
Bu iki yol-- özür dilerim.
Aslında sadece birine ihtiyacımız var.
Sadece bir gelen kenardan v.
Yani onun virgül s virgül bir.

Turkish: 
 
Üzgünüm-- olmalıyım
buraya da temel bir dava koy.
Virgül s deltası 0'a eşittir.
 
TAMAM.
S virgülün deltası
bir artı kenar.
TAMAM.
Biraz var
en kısa yol
Hesaplamak için
bizlere giden en kısa yol
hepsine bak
gelen kenarları a.
Sadece biri var.
Yani virgül deltası b.
Şimdi hesaplamak istiyorum
b 'den en kısa yollar
İki tane var
almak için yollar b.
Bunlardan biri s deltası
virgül b - üzgünüm, virgül s.
S den geldi.
Diğer yol s deltasıdır
virgül v. Bir problem mi gördün?
Evet.
S virgül v v
anlamaya çalışıyorduk.
 
Şimdi diyebilirsin, ah,
Sorun değil çünkü biz
memolaşacağız
delta virgülüne cevap v
ve sonra burada tekrar kullanabiliriz.
Ancak biz bitiremedik
s hesaplama deltası

English: 
Sorry-- I should have
put a base case here too.
Delta of s comma s equals 0.
OK.
Delta of s comma
a plus the edge.
OK.
There is some
shortest path to a.
To compute the
shortest path to a we
look at all the
incoming edges to a.
There's only one.
So delta of s comma b.
Now I want to compute the
shortest paths from b.
Well, there's two
ways to get to b.
One of them is delta of s
comma b-- sorry, s comma s.
Came from s.
The other way is delta of s
comma v. Do you see a problem?
Yeah.
Delta of s comma v is what
we were trying to figure out.
Now you might say, oh,
it's OK because we're
going to memoize our
answer to delta s comma v
and then we can reuse it here.
Except, we haven't finished
computing delta of s

Turkish: 
virgül v. Sadece koyabiliriz
not tablo bir kez bitti.
Yani bu çağrı olduğunda
not tablosu ayarlanmadı.
Ve biz gidiyoruz
aynı şeyi yap
Bir daha, bir daha ve bir defa daha.
Bu sonsuz bir algoritmadır.
Hata.
Çok sıcak değil.
 
Yani sonsuz olacak
çevrimleri olan grafiklerde zaman.
 
TAMAM.
DAG'ler için, asiklik grafikler için
Aslında v artı e zamanında çalışır.
Bu iyi bir durum.
Bu durumda biz
bu formülü kullanabilir.
Zaman eşittir
alt sorun sayısı
Alt problemin başına kalan süreyi
Sanırım düşünmeliyiz
Bu konuda biraz.
Kodum nerede?
İşte kodum.

English: 
comma v. We can only put it in
the memo table once we're done.
So when this call happens the
memo table has not been set.
And we're going to
do the same thing
over and over and over again.
This is an infinite algorithm.
Oops.
Not so hot.
So it's going to be infinite
time on graphs with cycles.
OK.
For DAGs, for acyclic graphs, it
actually runs in v plus e time.
This is the good case.
In this situation we
can use this formula.
The time is equal to the
number of subproblems
times the time per subproblem.
So I guess we have to think
about that a little bit.
Where's my code?
Here's my code.

Turkish: 
Alt problem sayısı
v. Var
v farklı alt problemler
Burada kullanıyorum.
Ben her zaman yeniden
delta formunun alt problemleri
virgül bir şey.
Bir şey olabilir
v köşelerinin herhangi biri.
Ne kadar zaman yaparım
Alt problem için harcama?
Bu biraz zor.
Sayı
gelen kenarların
v. Yani bir zaman
sv alt problem deltası
v.
gelen kenarların sayısı v.
Yani bu bağlıdır
v. Yani sadece yapamam
dürüst olmak
burada ürün.
Bu gerçekten ne
diyor ki sen
özetlemeli
tüm alt problemler
alt problem başına zamanın.
Yani toplam süre bitti toplamı
hepsi v ve v, v.

English: 
Number of subproblems
is v. There's
v different subproblems
that I'm using here.
I'm always reusing
subproblems of the form delta
s comma something.
The something could be
any of the v vertices.
How much time do I
spend per subproblem?
That's a little tricky.
It's the number
of incoming edges
to v. So time for a
sub problem delta of sv
is the indegree of v. The
number of incoming edges to v.
So this depends on
v. So I can't just
take a straightforward
product here.
What this is really
saying is, you
should sum up over
all sub problems
of the time per sub problem.
So total time is the sum over
all v and v, the indegree of v.

Turkish: 
Ve bunu biliyoruz
kenar sayısıdır.
Bu gerçekten-- çok kaba
artı 1, son derece artı 1.
Yani bu v artı v. Tamam.
Tekrar el sıkışma.
TAMAM.
Şimdi zaten bir algoritma biliyorduk
en kısa yollar ve DAG'ler için.
Ve av artı e zaman koştu.
Yani bu başka bir yol
aynı şeyi yapmak için.
Düşünürsen
yeterince uzun
bu algoritma
faturasız, aslında
derinlemesine ilk arama yapmak
topolojik bir sıralama yapmak
bir tur atmak
Bellman-Ford’un
Bu yüzden topolojik sıralama vardı
artı bir tur Bellman-Ford.
Bu bir çeşit
hepsi bir arada.
Bu biraz benzemeli
Bellman Ford rahatlama
adım veya en kısa
yolları gevşeme adımı.
Bu.
Bu dk gerçekten
aynı şeyi yapıyorum.
Bu yüzden gerçekten
Aynı algoritma.
Ama biz bundan geliyoruz
farklı bir bakış açısı.
 
TAMAM.
Ama kullanabileceğimi iddia ediyorum
bu aynı yaklaşım
içindeki en kısa yolları çözmek için
Genel grafikler, hatta

English: 
And we know this
is number of edges.
It's really-- so indegree
plus 1, indegree plus 1.
So this is v plus v. OK.
Handshaking again.
OK.
Now we already knew an algorithm
for shortest paths and DAGs.
And it ran a v plus e time.
So it's another way
to do the same thing.
If you think about
it long enough,
this algorithm
memoized, is essentially
doing a depth first search
to do a topological sort
to run one round
of Bellman-Ford.
So we had topological sort
plus one round of Bellman-Ford.
This is kind of it
all rolled into one.
This should look kind of like
the Bellman Ford relaxation
step, or shortest
paths relaxation step.
It is.
This min is really
doing the same thing.
So it's really the
same algorithm.
But we come at it from
a different perspective.
OK.
But I claim I can use
this same approach
to solve shortest paths in
general graphs, even when they

Turkish: 
döngüleri var.
Bunu nasıl yapacağım?
DAG'ler iyi görünüyor-- ah, ne?
Ders burada öğrenildi mi?
Alınan ders
alt problem bağımlılıkları
asiklik olmalıdır.
Aksi takdirde, bir
sonsuz algoritma.
For memoization to work
this is what you need.
It's all you need.
 
TAMAM.
We've almost seen this already.
Because I said that, to
do a bottom up algorithm
you do a topological sort of
this subproblem dependency DAG.
I already said it
should be acyclic.
TAMAM.
We just forgot.
I didn't tell you yet.
So for that to work
it better be acyclic.
For DP to work, for memoization
to work, it better be acyclic.
If you're acyclic then
this is the running time.
So that's all general.

English: 
have cycles.
How am I going to do that?
DAGs seem fine-- oh, what
was the lesson learned here?
Lesson learned is that
subproblem dependencies
should be acyclic.
Otherwise, we get an
infinite algorithm.
For memoization to work
this is what you need.
It's all you need.
OK.
We've almost seen this already.
Because I said that, to
do a bottom up algorithm
you do a topological sort of
this subproblem dependency DAG.
I already said it
should be acyclic.
OK.
We just forgot.
I didn't tell you yet.
So for that to work
it better be acyclic.
For DP to work, for memoization
to work, it better be acyclic.
If you're acyclic then
this is the running time.
So that's all general.

Turkish: 
TAMAM.
So somehow I need to
take a cyclic graph
and make it acyclic.
 
We've actually done this
already in recitation.
 
So if I have a
graph-- let's take
a very simple cyclic graph.
TAMAM.
One thing I could do is explode
it into multiple layers.
We did this on quiz
two in various forms.
It's like the only cool thing
you can do with shortest paths,
I feel like.
If you want to make a
shortest path problem harder,
require that you reduce your
graph to k copies of the graph.
I'm going to do it
in a particular way
here-- which I think you've
seen in recitation-- which
is to think of this axis as
time, or however you want,
and make all of the
edges go from each layer
to the next layer.

English: 
OK.
So somehow I need to
take a cyclic graph
and make it acyclic.
We've actually done this
already in recitation.
So if I have a
graph-- let's take
a very simple cyclic graph.
OK.
One thing I could do is explode
it into multiple layers.
We did this on quiz
two in various forms.
It's like the only cool thing
you can do with shortest paths,
I feel like.
If you want to make a
shortest path problem harder,
require that you reduce your
graph to k copies of the graph.
I'm going to do it
in a particular way
here-- which I think you've
seen in recitation-- which
is to think of this axis as
time, or however you want,
and make all of the
edges go from each layer
to the next layer.

Turkish: 
 
This should be a
familiar technique.
So the idea is,
every time I follow
an edge I go down
to the next layer.
This makes any graph acyclic.
Bitti.
What in the world
does this mean?
What is it doing?
 
What does it mean?
Double rainbow.
Tamam.
AUDIENCE: [LAUGHTER]
PROFESSOR: So-- I
don't know how I've
gone so long in the
semester without referring
to double rainbow.
It used to be my favorite.
Tamam.
So here's what it means.
Delta sub k of sv.
I'm going to define
this first-- this
is a new kind of
subproblem-- which
is, what is the shortest-- what
is the weight of the shortest
s to v path that uses,
at most, k edges.
 

English: 
This should be a
familiar technique.
So the idea is,
every time I follow
an edge I go down
to the next layer.
This makes any graph acyclic.
Done.
What in the world
does this mean?
What is it doing?
What does it mean?
Double rainbow.
All right.
AUDIENCE: [LAUGHTER]
PROFESSOR: So-- I
don't know how I've
gone so long in the
semester without referring
to double rainbow.
It used to be my favorite.
All right.
So here's what it means.
Delta sub k of sv.
I'm going to define
this first-- this
is a new kind of
subproblem-- which
is, what is the shortest-- what
is the weight of the shortest
s to v path that uses,
at most, k edges.

English: 
So I want it to be shortest
in terms of total weight,
but I also want it to
use few edges total.
So this is going to be 0.
In some sense, if you
look at-- so here's s
and I'm always going
to make s this.
And then this is going to
be v in the zero situation.
This is going to be v
in the one situation,
v-- so if I look at this
v, I look at the shortest
path from s to v, that
is delta sub 0 of sv.
So maybe I'll call this v
sub 0, v sub 1, v sub 2.
OK.
Shortest path from
here to here is,
there's no way to
get there on 0 edges.
Shortest path from
here to here, that
is the best way to get there
with, at most, one edge.
Shortest path from
here to here--
well, if I add some
vertical edges too,
I guess, cheating a little bit.
Then this is the best
way to get from s
to v using at most two edges.
And then you get
a recurrence which
is the min over all last edges.
So I'm just copying
that recurrence,

Turkish: 
So I want it to be shortest
in terms of total weight,
but I also want it to
use few edges total.
So this is going to be 0.
In some sense, if you
look at-- so here's s
and I'm always going
to make s this.
And then this is going to
be v in the zero situation.
This is going to be v
in the one situation,
v-- so if I look at this
v, I look at the shortest
path from s to v, that
is delta sub 0 of sv.
So maybe I'll call this v
sub 0, v sub 1, v sub 2.
TAMAM.
Shortest path from
here to here is,
there's no way to
get there on 0 edges.
Shortest path from
here to here, that
is the best way to get there
with, at most, one edge.
Shortest path from
here to here--
well, if I add some
vertical edges too,
I guess, cheating a little bit.
Then this is the best
way to get from s
to v using at most two edges.
And then you get
a recurrence which
is the min over all last edges.
So I'm just copying
that recurrence,

English: 
but realizing that the s to
u part uses one fewer edge.
And then I use the edge uv.
OK.
That's our new recurrence.
By adding this k
parameter I've made
this recurrence on
subproblems acyclic.
Unfortunately, I've increased
the number of subproblems.
The number of subproblems
now is v squared.
Technically, v times v minus 1.
Because I really--
actually, v squared.
Sorry.
I start at 0.
And what I care about, my goal,
is delta sub v minus 1 of sv.
Because by
Bellman-Ford analysis I
know that I only care about
simple paths, paths of length
at most v minus 1.
I'm assuming here no
negative weight cycles.
I should've said that earlier.
If you assume that, then
this is what I care about.

Turkish: 
but realizing that the s to
u part uses one fewer edge.
And then I use the edge uv.
 
TAMAM.
That's our new recurrence.
By adding this k
parameter I've made
this recurrence on
subproblems acyclic.
Unfortunately, I've increased
the number of subproblems.
The number of subproblems
now is v squared.
Technically, v times v minus 1.
Because I really--
actually, v squared.
Sorry.
I start at 0.
And what I care about, my goal,
is delta sub v minus 1 of sv.
Because by
Bellman-Ford analysis I
know that I only care about
simple paths, paths of length
at most v minus 1.
I'm assuming here no
negative weight cycles.
I should've said that earlier.
If you assume that, then
this is what I care about.

Turkish: 
So k ranges from 0 to v minus 1.
So there are v choices for k.
There are v choices for v.
So the number of subproblems
is v squared.
How much time do I
spend per subproblem?
Well, the same as before.
The indegree-- where
did I write it?
Up here-- the indegree
of that problem.
So what I'm really
doing is summing
over all v of the indegree.
And then I multiply it by
v. So the running time,
total running time is ve.
Sound familiar?
This is Bellman-Ford's
algorithm again.
And this is actually where
Bellman-Ford algorithm
came from is this view
on dynamic programming.
So we're seeing yet another
way to do Bellman-Ford.
It may seem familiar.
But in the next
three lectures we're
going to see a whole
bunch of problems
that can succumb to
the same approach.
And that's super cool.

English: 
So k ranges from 0 to v minus 1.
So there are v choices for k.
There are v choices for v.
So the number of subproblems
is v squared.
How much time do I
spend per subproblem?
Well, the same as before.
The indegree-- where
did I write it?
Up here-- the indegree
of that problem.
So what I'm really
doing is summing
over all v of the indegree.
And then I multiply it by
v. So the running time,
total running time is ve.
Sound familiar?
This is Bellman-Ford's
algorithm again.
And this is actually where
Bellman-Ford algorithm
came from is this view
on dynamic programming.
So we're seeing yet another
way to do Bellman-Ford.
It may seem familiar.
But in the next
three lectures we're
going to see a whole
bunch of problems
that can succumb to
the same approach.
And that's super cool.
