“Küçük n değerleri için O (n) O (1) gibi ele alınabilir”


26

Birkaç kez duydum ki, yeterince küçük n değerleri için O (n) O (1) gibi düşünülüp / tedavi edilebilir.

Örnek :

Bunu yapmak için motivasyon, O (1) 'in her zaman O (lg n)' den, her zaman O (n) 'den daha iyi olduğu yanlış fikrine dayanır. Bir işlemin asimptotik sırası, yalnızca gerçekçi koşullar altında sorunun boyutu gerçekten büyük olduğunda ortaya çıkar.N küçük kalırsa her sorun O (1) olur!

Yeterince küçük olan nedir? 10? 100? 1.000? Hangi noktada "artık buna özgür bir operasyon gibi davranamayız" diyorsunuz? Bir kural var mı?

Bu, alana veya duruma özgü olabilir gibi görünüyor, ancak bunun hakkında nasıl düşünüleceği hakkında genel bir kural var mı?


4
Temel kural, hangi sorunu çözmek istediğinize bağlıdır. olan gömülü sistemlerde hızlı mı olun ? Karmaşıklık teorisinde yayınlamak? n100
Raphael

3
Bunun hakkında daha fazla düşünmek, tek bir temel kurala varmak temel olarak imkansızdır çünkü performans gereklilikleri etki alanınız ve işletme gereklilikleri tarafından belirlenir. Kaynak kısıtlı olmayan ortamlarda, n oldukça büyük olabilir. Çok kısıtlı ortamlarda, oldukça küçük olabilir. Şimdi açıkçası bu açık görünüyor.
rianjs

12
@rianjs Sen karıştırıyorsun gibi görünüyor O(1)için ücretsiz . İlk birkaç cümle arkasındaki mantık olmasıdır O(1)olduğu sabit bazen delicesine yavaş olabilir. Girdiden bağımsız olarak bin milyar yıl süren bir O(1)hesaplama bir hesaplamadır.
Mooing Duck

1
Asıltolojiyi neden ilk başta kullandığımızla ilgili soru .
Raphael

3
@rianjs: "Bir beşgen, yeterince büyük 5 değerleri için yaklaşık bir dairedir" çizgileri boyunca şakaların farkında olun. İstediğiniz cümle bir noktaya değiniyor, ancak size biraz kafa karışıklığı yarattığından, Eric Lippert'e bu kesin ifade seçiminin ne kadar komik bir etki için olduğunu sormak sizin için değerli olabilir. “Eğer üzerinde herhangi bir üst sınır varsa o zaman her sorun O ( 1 ) ” diyebilirdi ve hala matematiksel olarak doğru. "Küçük" matematiğin bir parçası değildir. nO(1)
Steve Jessop

Yanıtlar:


21

Tüm büyüklük düzenleri, birçoğu aslında sabit bir içerir . Maddelerin sayısı yeterince büyük olduğunda bu sabit önemsizdir. Soru, madde sayısının, bu sabitin baskın çıkması için yeterince küçük olup olmadığıdır.C

İşte düşünmek için görsel bir yol.

görüntü tanımını buraya girin

Hepsinin başlangıç ​​noktasını Y ekseni üzerinde belirleyen bir başlangıç ​​sabiti var. Her birinin aynı zamanda ne kadar hızlı artacaklarına egemen olan kritik bir sabiti vardır .C

  • İçin , süresini belirler.O(1)C
  • gerçekten C × n'dir , burada C açıyı belirler.O(n)C×nC
  • gerçekten ( C × n ) 2'dir , burada C eğrinin keskinliğini belirler.O(n2)(C×n)2C

Hangi algoritmayı kullanmanız gerektiğini belirlemek için çalışma zamanlarının kesiştiği noktayı tahmin etmeniz gerekir. Örneğin, bir yüksek başlangıç ​​zamanı veya yüksek C'ye sahip 1 ) çözümü,düşük başlangıç ​​zamanı veoldukça fazla sayıda öğededüşük C değerine sahipbir O ( n ) çözümünükaybedecektir.O(1)CO(n)C

İşte gerçek bir dünya örneği. Bir avluya bir demet tuğla taşımanız gerekir. Onları bir seferde birkaç elinizle hareket ettirebilir ya da tek bir yolculukta kaldırmak ve sürmek için devasa, yavaş bir beko elde edebilirsiniz. Üç tuğla varsa cevabınız nedir? Üç bin varsa cevabınız nedir?

İşte bir CS örneği. Her zaman sıralanmış bir listeye ihtiyacınız olduğunu varsayalım. O ( log) için kendini tutacak bir ağaç kullanabilirsiniz. Veya sıralanmamış bir liste kullanabilir ve her ekleme veya silme işleminden sonra O ( n log n ) 'de yeniden sıralayabilirsiniz. Ağaç işlemleri karmaşık olduğu için (sabitleri yüksektir) ve sıralama o kadar basit (düşük sabiti) ki, liste muhtemelen yüzlerce veya binlerce maddeden kazanacaktır.O(logn)O(nlogn)

Bu tür bir şey göz küresi olabilir, ancak sonuçta kıyaslama ne yapacak. Ayrıca, genellikle kaç öğeye sahip olacağınıza göz küresi yapmanız ve daha fazla kullanım riskini azaltmanız gerekir. Ayrıca “performans öğelerinde hızlı bir şekilde düşecektir ” veya “maksimum bir X ayar büyüklüğü varsayıyoruz” gibi varsayımınızı belgelemek isteyeceksiniz .XX

Bu gereklilikler değişebileceğinden, bu tür kararları bir arayüzün arkasına koymak önemlidir. Yukarıdaki ağaç / liste örneğinde, ağacı veya listeyi göstermeyin. Bu sayede varsayımlarınız yanlış çıkarsa veya daha iyi bir algoritma bulursanız fikrinizi değiştirebilirsiniz. Hatta öğelerin sayısı arttıkça melez ve dinamik bir şekilde anahtar algoritmaları yapabilirsiniz.


demek anlamsızdır . Ne gerçekten demek olduğunu çalışma süresi ise T = O ( 1 ) (birçok durumda) daha sonra T C . Eğer T = O ( n ) ise o zaman birçok durumda T C n , veya daha resmi olarak T = C n + o ( n ) . Ve bunun gibi. Bununla birlikte, bu diğer durumlarda sabit değişirO(1)=O(C)T=O(1)TCT=O(n)TCnT=Cn+o(n)C , belirli sınırlar içinde. n
Yuval Filmus,

@YuvalFilmus Bu yüzden grafikleri seviyorum.
Schwern,

Bu şu ana kadarki en iyi cevap, mesele ne kadar hızlı büyüdüğü.
Ricardo,

1
Güzel grafik, ancak ekseni gerçekten "hız" olarak değil, "zaman" olarak etiketlenmelidir. y
Ilmari Karonen

1
hattı, gerçekten bir parabol var? Küçük n için çok düz ve büyük n için çok dik görünüyor . O(n2)nn
David Richerby 17:14

44

Bu, daha önce bildirilen cevaplara büyük ölçüde destek veriyor, ancak farklı bir bakış açısı sunabilir.

Sorunun " n'nin yeterince küçük değerlerini" tartıştığını ortaya koyuyor . Big-O'nun tüm amacı, işlemenin işlenenlerin bir fonksiyonu olarak nasıl büyüdüğünü tanımlamaktır. Eğer işlenen veriler küçük kalırsa, Big-O'yu tartışmak önemsizdir, çünkü büyümeyle ilgilenmiyorsunuz (ki bu gerçekleşmiyor).

Başka bir deyişle, caddede çok kısa bir mesafeye gidiyorsanız, yürümek, bisiklet kullanmak veya araç sürmek aynı derecede hızlı olabilir. Arabanızın anahtarlarını bulmak biraz zaman alırsa ya da arabanızın gaz kullanması gerekiyorsa, yürümek daha da hızlı olabilir.

Küçük için nuygun olanı kullanın.

Eğer şehirlerarası seyahate çıkıyorsanız, sürüşünüzü, gaz kilometrenizi vb. Optimize etmenin yollarına bakmanız gerekir.


5
"Küçük n için uygun olanı kullanın." - İşlemi sık sık gerçekleştirirseniz , en hızlı olanı seçin ( ). Ayrıca buraya bakınız . n
Raphael

4
Büyük metafor!
Evorlor

1
Tamamen matematiksel bir bakış açısıyla, asimptotik karmaşıklık size hiçbir zaman bir şey söylemez n < infinity.
Gordon Gustafson

15

Alıntı oldukça belirsiz ve kesin değildir. Yorumlanabileceği en az üç ilgili yol vardır.

Bunun arkasındaki gerçek matematiksel nokta şudur, eğer sadece bir limite kadar olan boyut örnekleri ile ilgileniyorsanız, o zaman sadece çok sayıda muhtemel durum vardır. Örneğin, yüz köşesine kadar sadece çok sayıda grafik vardır. Yalnızca sınırlı sayıda örnek varsa, ilke olarak, sorunu tüm olası örneklere verilen tüm cevapların bir arama tablosunu oluşturarak çözebilirsiniz. Şimdi, cevabı ilk önce girişin çok büyük olmadığını kontrol ederek bulabilirsiniz (bu, sabit zaman alır: giriş k'dan uzunsa). k, geçersizdir) ve sonra cevap tablosundaki ifadeye bakın (sabit zaman alır: tabloda sabit sayıda giriş vardır). Ancak, tablonun gerçek boyutunun muhtemelen inanılmaz derecede büyük olduğuna dikkat edin. Yüz köşesinde sadece sınırlı sayıda grafik olduğunu söyledim ve bu doğru. Sadece sonlu sayılar gözlemlenebilir evrendeki atom sayısından daha büyük.

Biz bir algoritma çalışma süresi olduğunu söylediğimizde, daha pratik açıdan, yani bu kadar sadece araçlarının, asimptotik c , n 2  bir sabit için, adım  C . Olduğunu, bazı sabit var n 0 herkes için, böyle n n 0 , algoritma kabaca alır c n 2 adımlar. Ama belki n 0 = 100 , 000 , 000Θ(n2) cn2Cn0nn0cn2n0=100,000,000ve sadece bundan daha küçük boyuttaki örneklerle ilgileniyorsunuz. Asimptotik ikinci dereceden sınır, küçük örnekleriniz için bile geçerli olmayabilir. Şanslı olabilirsiniz ve küçük girişlerde daha hızlı olabilir (veya şanssız olabilir ve daha yavaş olabilirsiniz). Örneğin, küçük  , n 2 < 1000 n olduğundan, sabit sabitleri olan doğrusal bir algoritmadan ziyade iyi sabitleri olan ikinci dereceden bir algoritmayı çalıştırmayı tercih edersiniz. Bunun gerçek bir örneği, asimptotik olarak en verimli matris çarpım algoritmalarının ( O zamanında çalışan ( Coppersmith -Winograd varyantları ) ( n 2.3729 ) ) pratikte nadiren kullanılmasıdır çünkü Strassen (nn2<1000nO(n2.3729) algoritma, matrisleriniz gerçekten büyük olmadığı sürece daha hızlıdır.O(n2.8074)

Eğer bir üçüncü nokta, yani  küçük, n, 2 ve hatta n, 3  küçüktür. Örneğin, birkaç bin veri öğesini sıralamanız gerekiyorsa ve bunları yalnızca bir kez sıralamanız gerekiyorsa, sıralama algoritmaları yeterlidir: a Θ ( n 2 )nn2n3Θ(n2)Algoritma hala, verilerinizi sıralamak için belki de sadece birkaç milyon talimata ihtiyaç duyacaktır; bu işlem, saniyede milyarlarca talimat gerçekleştirebilecek bir CPU'da fazla zaman değildir. Tamam, bellek erişimi de var, ancak yavaş bir algoritma bile bir saniyeden daha az sürecek, bu nedenle basit, yavaş bir algoritma kullanmak ve karmaşık, hızlı bir algoritma kullanmaktan ve yıldırım hızını bulmaktan daha doğru bir yöntem kullanmak daha iyi ama adamcağız ve aslında verileri doğru şekilde sıralamıyor.


4
Tamamen doğru ve geçerli noktalar olsa da, noktayı kaçırdığınızı düşünüyorum. O zaman algoritması ile kastedilen görünmektedir ile bir algoritma daha gerçekleştirir iyi O ( 1 ) yeterince küçük için, n, s. Bu, örneğin, eski çalışma süresi 10 n + 50 olduğunda , ikincisi 100000 iken çalışır . Sonra, n küçük için, O ( n ) protokolünü kullanmak aslında daha hızlıdır . O(n)O(1)n10n+50100000nO(n)
Ran G.

@RanG. Bu benim ikinci davamın altına girmiyor mu? (Özellikle, "İyi sabitleri olan doğrusal bir algoritma, sabit sabitleri olan bir logaritmik algoritmayı yenebilir" gibi bir şey söylemek için düzenlerseniz?)
David Richerby

1
N küçük olduğunda sabitlerin önemini açıkça belirtmek iyi olur . Bu daha önce duymamış birine muhtemelen gerçekleşmeyecek bir şey.
Rob Watts

9

Big-O notasyonu gerçekten sadece keyfi büyükler için davranış hakkında bir şeyler söylüyor. Örneğin, sabit bir c> 0 ve bir tamsayıdır olduğu anlamına gelir , n 0 , öyle ki f ( n ) < C , n 2 , her için n > n, 0 .f(n)=O(n2)n0f(n)<cn2n>n0

Birçok durumda, bir sabit c bulup söyleyebiliriz "Her n> 0, f (n) için yaklaşık ". Hangi bilgi olması faydalıdır. Ancak bazı durumlarda, bu doğru değil. F (n) = n 2 + 10 18 ise , bu tamamen yanıltıcıdır. Bu yüzden sadece bir şey O (n ^ 2) olduğu için beyninizi kapatabileceğiniz ve gerçek işlevi görmezden gelebileceğiniz anlamına gelmez.cn2n2+1018

Öte yandan, n = 1, 2 ve 3 değerleriyle yalnızca bir kez karşılaşırsanız, pratikte f (n) 'nin n ≥ 4 için yaptıkları bir fark yaratmaz; n) = 0 (1), c = maks (f (1), f (2), f (3)). Ve bu yeterince küçük anlamına gelir: Eğer f (n) = O (1) olduğu iddiası, karşılaştığınız tek f (n) değerinin "yeterince küçük" olması durumunda sizi yanıltmazsa.


5

Büyümezse, O (1)

Yazarın ifadesi biraz aksiyomatiktir.

Büyüme düzenleri, arttırmak için yapmanız gereken iş miktarına ne olduğunu açıklar N. Bunun Narttığını bilmiyorsanız , probleminiz etkilidir O(1).

Unutma ki O(1)bu "hızlı" demek değil. Tamamlamak için her zaman 1 trilyon adım gerektiren bir algoritmadır O(1). 1-200 adım arasında herhangi bir yerde, ancak hiçbir zaman daha fazla olmayan bir algoritma O(1). [1]

Senin algoritması tam olarak alırsa N ^ 3adımları ve biliyorum o Ndaha 5'ten olamaz etkin yüzden, bu gün 125 adımlar asla O(1).

Ancak yine, O(1)mutlaka "yeterince hızlı" anlamına gelmez. Bu, bağlamınıza bağlı olan ayrı bir soru. Bir şeyi bitirmek bir hafta sürüyorsa, teknik olarak yapıp yapmamanız umrumda değil O(1).


[1] Örneğin, O(1)karma çarpışmalar, karma çarpışmalar, bir kovadaki birkaç maddeye bakmak zorunda kalabileceğiniz anlamına gelse de, bu kovada kaç tane madde olabileceğinin zor bir sınırı olduğu sürece.


1
Bunun dışında tüm sesler geçerli: "Algoritmanız tam olarak N ^ 3 adım atıyorsa ve N'nin 5'ten fazla olamayacağını biliyorsanız, asla 125'ten fazla adım atmaz, bu yüzden O (1)." . Yine bir algoritma bir tamsayı alırsa ve benim tamsayı desteğim 32767 ise, O (1)? Belli ki değil. Big-O, parametre sınırlarına bağlı olarak değişmez. 0 <n <3 olduğunu bilseniz bile, O (n) 'dir , çünkü n = 2, n = 1'in iki katı kadar sürer.
JSobell

3
@JSobell Ama O (1). Eğer n'inizi f (n) ile sınırlayan bir sınırlama varsa, bunun sonsuza dek uzayamayacağı anlamına gelir. Eğer n'niz 2 ^ 15 ile sınırlıysa, n = 2 fonksiyonunuz aslında g(n) = min(f(2^15), f(n))- O da (1). Bu, pratikte sabitlerin çok önemli olduğunu ve açıkça bir asimptotik analizin faydalı olacağı kadar büyük olabileceğini söyledi.
Voo

2
@JSobell Bu, teknik olarak sınırsız depolama alanına sahip olmadıkları göz önüne alındığında, bilgisayarların gerçekten "Turing Complete" olup olmadığı sorusuna benzer. Teknik olarak, matematiksel olarak, bir bilgisayar "gerçek" bir Turing Makinesi değildir. Uygulamada, "sonsuz bant" diye bir şey yoktur, ancak sabit sürücüler yeterince yaklaşır.
Kyle Strand

Birkaç yıl önce, n-5 matris manipülasyonlarını içeren bir finansal Risk sistemi yazdım, bu yüzden kaynaklar bir sorun haline gelmeden önce pratik bir n = 20 sınırı vardı.
JSobell

Özür dileriz, çok erken Enter tuşuna basın. Birkaç yıl önce, n-5 matris manipülasyonlarını içeren bir finansal Risk sistemi yazdım, bu yüzden kaynaklar bir sorun haline gelmeden önce pratik bir n = 20 sınırı vardı. Bu hatalı mantığa göre, yaratılan fonksiyon O (1) 'dir. Çünkü 20'lik bir sınırım var. Müşteri "Hmm, belki de limit olarak 40'a çıkarmalıyız" derken, algoritma O (1). ) bu yüzden sorun değil "... Bu yüzden bir girdi üzerindeki sınırlar anlamsızdır. İşlev, O (n ^ 5), O (1) değildi ve bu, Big-O'nun sınırlardan bağımsız olmasının pratik bir örneğidir.
JSobell

2

Şimdi, bir karma tablosu kullanabilir ve O (1) aramaları yapabilirim (hashtable'ın özel uygulamasını bir kenara bırakırsak), ancak örneğin bir listem olsaydı, O (n) aramalarım olur. Bu aksiyom göz önüne alındığında, koleksiyonlar yeterince küçükse, bu ikisi aynıdır. Fakat bir noktada birbirlerinden ayrılırlar ... bu nokta nedir?

Pratik olarak, karma tabloyu oluşturmanın gelişmiş aramalardan elde ettiğiniz faydadan daha fazlasını aldığı nokta. Bu nasıl dayanan çok değişecektir sıklıkla size başka işlemler yaparken ne sıklıkta karşı araması, yapıyoruz. Bir kez yaparsanız, O (1) vs O (10) büyük bir şey değil. Saniyeyi saniyede binlerce kez yaparsanız, bu bile önemli (en azından doğrusal olarak artan oranda önemli olsa da).


Emin olmak istiyorsanız, hangi veri yapısının parametreleriniz için daha iyi olduğunu görmek için bazı deneyler yapın .
Yuval Filmus,

@Telastyn Yuval Filmus haklı, eğer gerçekten emin olmak istiyorsan. Jim adında bir kişi biliyorum, parametreleri iyi. Fakat Yuval'ınki gibi tavsiyelerde bulunmadı. Emin ve güvende olmak için Yuval'ı dinlemelisin.
bilgilendirildi.

2

Alıntı doğru olsa da (ancak belirsiz) bunun için de tehlikeler var. Ben, başvurunuzun herhangi bir aşamasında karmaşıklığa bakmalısınız.

Söylemesi çok kolay: hey sadece küçük bir listem var, eğer A öğesinin listede olup olmadığını kontrol etmek istersem, sadece listeyi değiştirmek ve öğeleri karşılaştırmak için basit bir döngü yazacağım.

Sonra dostum programlayıcınız listeyi kullanmaya ihtiyaç duyar, fonksiyonunuzu görür ve şöyle olur: hey Listede herhangi bir kopya istemiyorum, bu yüzden listeye eklenen her öğe için fonksiyonu kullanıyor.

(aklınızda olsun, hala küçük bir liste senaryosu.)

3 yıl sonra geldim ve patronum az önce büyük bir satış yaptı: yazılımımız büyük bir ulusal satıcı tarafından kullanılacak. Önce sadece küçük dükkanlara hizmet verdik. Ve şimdi patronum bana küfür ve bağırıyor, neden hep "iyi çalıştı" olan yazılımın artık bu kadar yavaş olduğunu düşünüyorum.

Anladığımız kadarıyla, bu liste bir müşteri listesiydi ve müşterilerimiz sadece 100 müşteriden hoşlanıyordu; Listeyi doldurma işlemi temelde bir O (1) işlemi idi, çünkü bir milisaniyeden daha az sürdü. Buna eklenecek 10.000 müşteri varken, fazla değil.

Orijinal kötü O (1) kararından yıllar sonra, şirket neredeyse büyük bir müşterisini kaybetti. Hepsi yıllar önce küçük bir tasarım / varsayım hatası nedeniyle.


Fakat aynı zamanda birçok gerçek dünya sisteminin önemli bir özelliğini de göstermektedir: lisans olarak öğrendiğiniz "algoritmalar" aslında gerçek "algoritmaların" yapıldığı parçalardır. Bu genellikle ima edilir; Örneğin, çoğu kişi bölümleri yeterince küçük olduğunda hızlı bağlantı noktasının ekleme sırasına geri dönmek için sık sık yazıldığını ve ikili aramanın genellikle doğrusal aramaya geri dönmek için yazıldığını bilir. Ancak bir çok kişi birleştirme düzeninin bazı ikili aramalardan yararlanabileceğinin farkında değil.
Sahte

1

Bunu yapmak için motivasyon, O (1) 'in her zaman O (lg n)' den, her zaman O (n) 'den daha iyi olduğu yanlış fikrine dayanır. Bir işlemin asimptotik sırası, yalnızca gerçekçi koşullar altında sorunun boyutu gerçekten büyük olduğunda ortaya çıkar.

Bu zamana sahip iki algoritmam varsa:

  • log (n) +10000
  • n + 1

Sonra kesiştikleri nokta var. Bundan ndaha küçükler için "doğrusal" algoritma daha hızlıdır ve bundan daha nbüyükler için "logaritmik" algoritması daha hızlıdır. Birçok insan logaritmik algoritmanın daha hızlı olduğunu varsaymakla hata yapar, fakat küçük niçin öyle değildir.

N küçük kalırsa her sorun O (1) olur!

Ben spekülasyon burada ne demek eğer olmasıdır nsınırlıdır, o zaman her sorun Ç (1) 'dir. Örneğin, tamsayıları sıralıyorsak, hızlı bağlantı noktasını kullanmayı seçebiliriz. O(n*log(n))Açıkçası. Fakat 2^64=1.8446744e+19tamsayıdan daha fazlası olamayacağına karar verirsek , o zaman şunu biliyoruz ki n*log(n)<= 1.8446744e+19*log(1.8446744e+19)<= 1.1805916e+21. Bu nedenle, algoritma her zaman 1.1805916e+21"zaman birimlerinden" daha az zaman alacaktır . Sabit bir zaman olduğundan, algoritmanın her zaman bu sabit zamanda yapılabileceğini söyleyebiliriz ->O(1) . (Bu zaman birimleri nanosaniye olsa bile, bunun toplam 37411 yıldan fazla olduğunu unutmayın). Ama yine de O(1).


0

Bu cevapların çoğunun temel bir kavramı eksik olduğundan şüpheleniyorum. O (1): O (n), f (1) ile aynı değildir: f (n), burada f, aynı işlevdir, çünkü O, tek bir işlevi temsil etmez. Schwern'in hoş grafiği bile geçerli değil çünkü tüm çizgiler için aynı Y eksenine sahip. Hepsinin aynı ekseni kullanması için, satırların fn1, fn2 ve fn3 olması gerekirdi; burada her biri performansı doğrudan diğerleriyle karşılaştırılabilecek bir işlevdi.

Birkaç kez duydum, yeterince küçük n değerleri için, O (n) 'nin sanki O (1) gibi düşünülebileceği / tedavi edilebildiğini duydum.

Eğer n = 1 ise bunlar tamamen aynı mıdır? Hayır. Değişken sayıda yinelemeye izin veren bir fonksiyonun, hiçbiri, büyük O gösterimi umrunda olmayan ve biz de yapmamamız gereken hiçbir ortak yanı yoktur.

Big-O notasyonu basitçe yinelemeli bir sürecimiz olduğunda ne olacağını ve performansın (zaman veya kaynaklar) 'n' arttıkça nasıl bozulacağını açıklamak için vardır.

Böylece asıl soruyu cevaplamak için ... Bu iddiada bulunanların Big-O gösterimini doğru anlamadıklarını söyleyeceğim, çünkü mantıksız bir karşılaştırma.

İşte benzer bir soru: Eğer bir karakter dizgisini geçersem ve genel olarak dizelerimin 10 karakterden az olacağını biliyorum, bunun O (1) 'e eşdeğer olduğunu söyleyebilir miyim, fakat dizelerim daha uzunsa O (n) olduğunu söyleyebilir miydi?

Hayır, çünkü 10 karakterlik bir dizge 1 karakterlik bir dizgenin 10 katı, 1000 karakterlik bir dizginin 100 katı daha azdır! O (n).


Eğer girişi en fazla 10 karakter olacak biliyorsanız Aslında, sen yapabilirsiniz bir yazmaO(1)algoritması. İlk önce, en fazla 10 karakter olduğunu kontrol edin; değilse, diğerlerine bakmanıza gerek kalmadan reddedebilirsiniz. Şimdi, eğer alırsaf(ben) bir girişi işlemek için adımlar ben karakterler, kalan çalışma süreniz maksimum{f(0),...,f(10)}. Bu bir sabit, kiO(1).
David Richerby

Evet, ve bu Big-O notasyonunun sıklıkla yanlış anlaşıldığı bir örnek. Argümanınıza göre, eğer maksimum değerin 1.000.000 olduğunu biliyorsanız, o zaman fonksiyonum O (1). Aslında, işlevim en iyi O (1) ve en kötü O (n) olabilir. Bu gösterim, somut bir uygulama değil, algoritmik karmaşıklığı tanımlamak için kullanılır ve en iyi olanı değil, her zaman en pahalı olanı kullanırız. Aslında, sizin argümanınıza göre, n <2 sağlayan her bir fonksiyon O (1)! :)
JSobell

Hayır. Big-O notasyonu, fonksiyonların büyüme hızını tanımlamak için kullanılır. Bu işlevler, herhangi bir şeyi ölçmek için kullanılabilir. Ve ben kesinlikle yoktu değil izin verdiğini "Her işlev iddian<2 [bu her ne demekse] O(1)"Ben aslında özelliği olan herhangi bir işlevi olduğunu savundu f(n)f(10) hepsi için n olduğu O(1), hangisi doğru.
David Richerby

Maalesef, n'nin üst sınırlarını bilmenin O (1) fonksiyonunu yaptığını söylerseniz, gösterimsel gösterimin doğrudan n'nin değeriyle ilgili olduğunu söylüyorsunuz, öyle değil. Bahsettiğiniz her şey doğru, ancak n'in sınırları olduğu için O'nun (1) doğru olmadığını gösteriyor. Uygulamada , tarif ettiğinizin gözlemlenebilir olabileceği yerler var, fakat burada kodlamada değil, kodlamada Big-O notasyonuna bakıyoruz. Öyleyse yine, neden maksimum 10'a sahip olmanızın O (1) yapmasını önerdiniz? Neden 10 Neden 65535 veya 2 ^ 64 değil?
JSobell

Diyelim ki, bir dizgiyi 10 karaktere
ayıran

0

Alıntı yaptığınız metnin oldukça yanlış olduğuna inanıyorum ("daha iyi" kelimesini kullanmak, bağlamı sağlamadığınız sürece genellikle anlamsızdır: zaman, alan vb.) Yine de, en basit açıklamanın olacağına inanıyorum:

Yürütme zamanı bir girişin büyüklüğüyle büyürse, o zaman kesinlikle değil O(1) ve bu açık olmalıdır. O(1)hızlı demek değil . Sadece (zaman karmaşıklığı açısından) yürütme zamanının sabit bir üst sınırı olduğu anlamına gelir .

Şimdi, göreceli olarak küçük bir 10 öğe kümesi alalım ve bunu sıralamak için birkaç algoritmaya sahip olalım (sadece bir örnek). Öğeleri sabit zamanda sıralayabilen bir algoritma da sağlayan bir yapı içinde tuttuğumuzu varsayalım. Diyelim ki sıralama algoritmalarımız aşağıdaki karmaşıklıklara sahip olabilir (big-O notasyonu ile):

  1. O(1)
  2. O(n)
  3. O(nlOg(n))
  4. O(n2)

Hangi algoritmayı seçerdiniz? Akla gelen ilk cevap "elbette kullanacağım" olabilirO(1)bir tane! ", ama bu kesinlikle doğru değil. Böyle düşünürken unuttuğun şey, büyük-O notasyonunun sabit faktörü gizlediğidir . Ve setinin oldukça küçük olduğunu biliyorsanız, o zaman bu sabit faktör çok daha önemli olabilir. asimptotik karmaşıklık.

Şimdi, yukarıda belirtilen sıralama algoritmalarının gerçek karmaşıklıklarını "açıklayalım" (burada "doğru", sabiti gizlememek anlamına gelir), bitirmek için gereken adımların sayılarıyla temsil edilir (ve tüm adımların aynı miktarda sürdüğünü varsayalım):

  1. 200 adımlar
  2. 11n adımlar
  3. 4nlOg(n) adımlar (taban 2 ile giriş)
  4. 1n2 adımlar

Eğer girişimiz 10 beden ise, bunlar yukarıda belirtilen her algoritma için tam olarak atılmış adımlardır:

  1. 200 adımlar
  2. 11x10=110 adımlar
  3. 4x10x3.32134 adımlar
  4. 1x100=100 adımlar

Gördüğünüz gibi, bu durumda, asempatik karmaşıklığa sahip görünüşte en kötü algoritma O(n2) en hızlı olanı, algoritmaları yenen O(1),O(n) ve O(nlOg(n))asimptotik karmaşıklıklar. Big-O notasyonu tarafından saklanan sabit faktör burada önemlidir. Bence bu tedavi edebileceğimiz anlamına gelmiyorO(n2) daha iyi O(1) (zaten ne anlama gelirdi?) Bu, yeterince küçük bir giriş için (örnekte gördüğünüz gibi) anlamına gelir. O(n2) hala daha hızlı olabilir O(1)Gizli sabit yüzünden. Eğer sabit, girişin boyutuna göre nispeten büyükse, asimptotik karmaşıklıktan daha önemli olabilir.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.