<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" ><generator uri="https://jekyllrb.com/" version="4.4.1">Jekyll</generator><link href="https://program.sonsuz.us/feed.xml" rel="self" type="application/atom+xml" /><link href="https://program.sonsuz.us/" rel="alternate" type="text/html" /><updated>2026-10-12T18:05:46+00:00</updated><id>https://program.sonsuz.us/feed.xml</id><title type="html">SonsuzUs</title><subtitle>Programlama ve Yazılım</subtitle><author><name>Sonsuz Us</name></author><entry><title type="html">Altın Oran: Doğanın, Sanatın ve Mimarinin Matematiksel Ritmi</title><link href="https://program.sonsuz.us/posts/altin-oran-doganin-sanatin-ve-mimarinin-matematiksel-ritmi/" rel="alternate" type="text/html" title="Altın Oran: Doğanın, Sanatın ve Mimarinin Matematiksel Ritmi" /><published>2026-10-12T00:00:00+00:00</published><updated>2026-10-12T00:00:00+00:00</updated><id>https://program.sonsuz.us/posts/altin-oran-doganin-sanatin-ve-mimarinin-matematiksel-ritmi</id><content type="html" xml:base="https://program.sonsuz.us/posts/altin-oran-doganin-sanatin-ve-mimarinin-matematiksel-ritmi/"><![CDATA[<p><img src="/img/altin-oran-doganin-52.svg" alt="altin-oran-doganin-52" /></p>

<p>Bir ayçiçeğinin merkezine, çam kozalağının pullarına veya yüzyıllardır hayranlık uyandıran bir tabloya baktığımızda benzer bir düzen hissedebiliriz. Bu düzenin arkasındaki en ünlü matematiksel adaylardan biri altın orandır. Yaklaşık $1.618$ değerindeki bu sayı; geometriyi, Fibonacci dizisini ve estetik tartışmalarını aynı masada buluşturan büyüleyici bir köprüdür.</p>

<p>``</p>

<h2 id="altın-oran-nedir">Altın oran nedir?</h2>

<p>Bir doğru parçasını uzun ve kısa olmak üzere iki parçaya ayıralım. Bütün uzunluğun uzun parçaya oranı, uzun parçanın kısa parçaya oranına eşitse altın oran ortaya çıkar. Uzun parça $a$, kısa parça $b$ olmak üzere:</p>

\[(a+b)/a = a/b = φ\]

<p>Bu eşitlik çözüldüğünde pozitif kök şöyledir:</p>

\[φ = (1 + √5)/2 ≈ 1.6180339887\]

<p>Altın oranın ilginç özelliklerinden biri, karesi ve tersiyle kurduğu sade ilişkilerdir:</p>

\[φ^2 = φ + 1\]

\[1/φ = φ - 1\]

<p>Sanki sayı kendi içinde küçük bir matematiksel yapboz taşıyor!</p>

<h2 id="fibonacci-dizisiyle-bağlantısı">Fibonacci dizisiyle bağlantısı</h2>

<p>Fibonacci dizisinde her sayı kendisinden önce gelen iki sayının toplamıdır:</p>

\[0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, ...\]

<p>Ardışık Fibonacci sayılarının büyük olanını küçük olana böldüğümüzde sonuç giderek altın orana yaklaşır. Örneğin $13/8 = 1.625$, $34/21 ≈ 1.619$ ve $89/55 ≈ 1.618$ olur. Bu yakınlaşma, altın oranın doğadaki spiral düzenlerle ilişkilendirilmesinin temel nedenlerinden biridir.</p>

<table>
  <thead>
    <tr>
      <th>Fibonacci oranı</th>
      <th style="text-align: right">Yaklaşık değer</th>
      <th style="text-align: right">Altın orana uzaklık</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>$5/3$</td>
      <td style="text-align: right">1.6667</td>
      <td style="text-align: right">0.0486</td>
    </tr>
    <tr>
      <td>$13/8$</td>
      <td style="text-align: right">1.6250</td>
      <td style="text-align: right">0.0070</td>
    </tr>
    <tr>
      <td>$34/21$</td>
      <td style="text-align: right">1.6190</td>
      <td style="text-align: right">0.0010</td>
    </tr>
    <tr>
      <td>$89/55$</td>
      <td style="text-align: right">1.6182</td>
      <td style="text-align: right">0.0001</td>
    </tr>
  </tbody>
</table>

<p>Bu yakınsamayı Python ile gözlemleyebiliriz:</p>

<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1"># Fibonacci sayıları arasındaki oranların
# altın orana nasıl yaklaştığını gösterir.
</span><span class="n">a</span><span class="p">,</span> <span class="n">b</span> <span class="o">=</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">1</span>

<span class="k">for</span> <span class="n">adim</span> <span class="ow">in</span> <span class="nf">range</span><span class="p">(</span><span class="mi">2</span><span class="p">,</span> <span class="mi">12</span><span class="p">):</span>
    <span class="n">a</span><span class="p">,</span> <span class="n">b</span> <span class="o">=</span> <span class="n">b</span><span class="p">,</span> <span class="n">a</span> <span class="o">+</span> <span class="n">b</span>
    <span class="n">oran</span> <span class="o">=</span> <span class="n">b</span> <span class="o">/</span> <span class="n">a</span>
    <span class="nf">print</span><span class="p">(</span><span class="sa">f</span><span class="sh">'</span><span class="si">{</span><span class="n">adim</span><span class="si">}</span><span class="s">. adım: </span><span class="si">{</span><span class="n">b</span><span class="si">}</span><span class="s">/</span><span class="si">{</span><span class="n">a</span><span class="si">}</span><span class="s"> = </span><span class="si">{</span><span class="n">oran</span><span class="si">:</span><span class="p">.</span><span class="mi">8</span><span class="n">f</span><span class="si">}</span><span class="sh">'</span><span class="p">)</span>
</code></pre></div></div>

<p>Döngü her adımda yeni Fibonacci sayısını üretir ve ardışık iki değerin oranını yazdırır. Çıktıda oranların bir süre altın değerin üstüne ve altına geçtiğini, ardından $1.618$ çevresinde dengelendiğini görürüz.</p>

<h2 id="doğadaki-izleri">Doğadaki izleri</h2>

<p>Ayçiçeği çekirdekleri ve çam kozalağı pulları, çoğu zaman birbirine zıt yönlerde ilerleyen spiral aileleri oluşturur. Bu spirallerin sayıları sıklıkla $34$, $55$ veya $89$ gibi Fibonacci sayılarına yakındır. Böyle bir yerleşim, bitkinin sınırlı alana çok sayıda tohum ya da yaprak sığdırmasına yardımcı olabilir.</p>

<p>Yaprakların gövde çevresindeki dizilimi de güneş ışığına erişimi artıran açılar oluşturabilir. Altın açı olarak bilinen değer yaklaşık olarak:</p>

\[360°/φ^2 ≈ 137.5°\]

<p>Ancak her spiral altın spiral değildir. Nautilus kabuğu sıkça kusursuz örnek olarak sunulsa da gerçek kabukların büyüme oranları türden türe değişir. Doğa cetvelle çizilmiş tek bir formülden çok, çevresel koşulların ve biyolojik süreçlerin birlikte çalıştığı esnek bir sistemdir.</p>

<h2 id="sanat-ve-mimaride-altın-oran">Sanat ve mimaride altın oran</h2>

<p>Altın dikdörtgenin kısa kenarı $1$ ise uzun kenarı yaklaşık $1.618$ olur. Bu biçimin Mona Lisa, Parthenon ve çeşitli Rönesans eserlerinde kullanıldığı sıkça ileri sürülür. Bazı tasarımlarda oran bilinçli biçimde uygulanmış olsa da tarihsel kanıt bulunmayan örnekler de vardır.</p>

<table>
  <thead>
    <tr>
      <th>Alan</th>
      <th>Olası kullanım</th>
      <th>Dikkat edilmesi gereken</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Resim</td>
      <td>Kompozisyon ve odak yerleşimi</td>
      <td>Sonradan yapılan ölçümler seçici olabilir</td>
    </tr>
    <tr>
      <td>Mimari</td>
      <td>Cephe ve oda oranları</td>
      <td>Yapının farklı bölümleri farklı sonuç verir</td>
    </tr>
    <tr>
      <td>Grafik tasarım</td>
      <td>Izgara, boşluk ve boyutlandırma</td>
      <td>Estetiğin tek formülü değildir</td>
    </tr>
    <tr>
      <td>Doğa</td>
      <td>Yaprak ve tohum dizilimleri</td>
      <td>Yaklaşık değerler görülür</td>
    </tr>
  </tbody>
</table>

<p>Altın oran, güzelliği otomatik olarak üreten sihirli bir düğme değildir. Asıl değeri; büyüme, oran, geometri ve görsel düzen arasındaki bağlantıları incelememizi sağlamasıdır. Kısacası $φ$, doğanın gizli şifresinden ziyade çevremizdeki örüntüleri okumak için kullanabileceğimiz zarif bir matematiksel mercektir.</p>]]></content><author><name>Sonsuz Us</name></author><category term="Bilgi" /><category term="altın oran" /><category term="matematik" /><category term="doğa" /><category term="sanat" /><category term="mimari" /><category term="fibonacci" /><category term="python" /><summary type="html"><![CDATA[Bir ayçiçeğinin merkezine, çam kozalağının pullarına veya yüzyıllardır hayranlık uyandıran bir tabloya baktığımızda benzer bir düzen hissedebiliriz. Bu düzenin arkasındaki en ünlü matematiksel adaylardan biri altın orandır. Yaklaşık $1.618$ değerindeki bu sayı; geometriyi, Fibonacci dizisini ve estetik tartışmalarını aynı masada buluşturan büyüleyici bir köprüdür.]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://program.sonsuz.us/img/altin-oran-doganin-52.png" /><media:content medium="image" url="https://program.sonsuz.us/img/altin-oran-doganin-52.png" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">Basamaklı Sıralama (Radix Sort): Karşılaştırmadan Sıralamanın Matematiği</title><link href="https://program.sonsuz.us/posts/basamakli-siralama-radix-sort-karsilastirmadan-siralamanin-matematigi/" rel="alternate" type="text/html" title="Basamaklı Sıralama (Radix Sort): Karşılaştırmadan Sıralamanın Matematiği" /><published>2026-10-12T00:00:00+00:00</published><updated>2026-10-12T00:00:00+00:00</updated><id>https://program.sonsuz.us/posts/basamakli-siralama-radix-sort-karsilastirmadan-siralamanin-matematigi</id><content type="html" xml:base="https://program.sonsuz.us/posts/basamakli-siralama-radix-sort-karsilastirmadan-siralamanin-matematigi/"><![CDATA[<p><img src="/img/basamakli-siralama-radix-16.svg" alt="basamakli-siralama-radix-16" /></p>

<p>Bir sayı listesini sıralarken ilk refleksimiz sayıları ikişer ikişer karşılaştırmaktır. Radix Sort ise masaya farklı bir fikir koyar: “Sayıların tamamını karşılaştırmak yerine basamaklarını sırayla incelesek?” Bu yaklaşım sayesinde uygun koşullarda karşılaştırmaya dayalı algoritmaların $O(n \log n)$ sınırını aşarak doğrusal zamana yaklaşabiliriz.</p>

<p>``</p>

<h2 id="temel-fikir-sayının-tamamına-değil-basamaklarına-bak">Temel fikir: Sayının tamamına değil, basamaklarına bak</h2>

<p>Basamaklı Sıralama, sayıları birler, onlar, yüzler gibi basamaklarına göre gruplandırır. En yaygın sürüm olan <strong>LSD Radix Sort</strong>, işleme en sağdaki, yani en az anlamlı basamaktan başlar.</p>

<p>Örneğin şu sayıları ele alalım:</p>

<p><code class="language-plaintext highlighter-rouge">170, 45, 75, 90, 802, 24, 2, 66</code></p>

<p>İlk turda birler basamağına, ikinci turda onlar basamağına, üçüncü turda yüzler basamağına bakılır. Her turun sonunda sayılar ilgili basamağa göre düzenlenir. Son basamak işlendiğinde liste tamamen sıralanmış olur.</p>

<table>
  <thead>
    <tr>
      <th>Tur</th>
      <th>İncelenen basamak</th>
      <th>Örnek sonuç</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>1</td>
      <td>Birler</td>
      <td>170, 90, 802, 2, 24, 45, 75, 66</td>
    </tr>
    <tr>
      <td>2</td>
      <td>Onlar</td>
      <td>802, 2, 24, 45, 66, 170, 75, 90</td>
    </tr>
    <tr>
      <td>3</td>
      <td>Yüzler</td>
      <td>2, 24, 45, 66, 75, 90, 170, 802</td>
    </tr>
  </tbody>
</table>

<p>Buradaki kritik ayrıntı, her basamak sıralamasının <strong>kararlı</strong> olmasıdır. Kararlı bir sıralama, aynı anahtar değerine sahip elemanların önceki göreli sırasını korur. Aksi hâlde önceki basamaklarda oluşturulan düzen bozulur ve algoritmanın sihri, pek de sihirli olmayan bir şekilde kaybolur.</p>

<h2 id="neden-doğrusal-olabilir">Neden doğrusal olabilir?</h2>

<p>$n$ eleman, en büyük sayıda $d$ basamak ve kullanılan sayı tabanında $b$ farklı rakam bulunsun. Her basamak için Counting Sort benzeri bir işlem uygulanırsa zaman karmaşıklığı şöyledir:</p>

\[T(n) = O(d(n+b))\]

<p>Ondalık sayılarda $b=10$ sabittir. Basamak sayısı $d$ de sınırlıysa karmaşıklık yaklaşık olarak $O(n)$ kabul edilir. Ancak sayıların basamak sayısı veri büyüklüğüyle birlikte ciddi biçimde artıyorsa “her zaman doğrusal” demek doğru değildir.</p>

<table>
  <thead>
    <tr>
      <th>Algoritma</th>
      <th style="text-align: right">Ortalama süre</th>
      <th>Karşılaştırma yapar mı?</th>
      <th style="text-align: right">Ek bellek</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Radix Sort</td>
      <td style="text-align: right">$O(d(n+b))$</td>
      <td>Hayır</td>
      <td style="text-align: right">$O(n+b)$</td>
    </tr>
    <tr>
      <td>Merge Sort</td>
      <td style="text-align: right">$O(n \log n)$</td>
      <td>Evet</td>
      <td style="text-align: right">$O(n)$</td>
    </tr>
    <tr>
      <td>Quick Sort</td>
      <td style="text-align: right">$O(n \log n)$</td>
      <td>Evet</td>
      <td style="text-align: right">Genellikle $O(\log n)$</td>
    </tr>
    <tr>
      <td>Counting Sort</td>
      <td style="text-align: right">$O(n+k)$</td>
      <td>Hayır</td>
      <td style="text-align: right">$O(k)$</td>
    </tr>
  </tbody>
</table>

<h2 id="python-ile-radix-sort">Python ile Radix Sort</h2>

<p>Aşağıdaki uygulama negatif olmayan tam sayıları LSD yaklaşımıyla sıralar. Her turda on adet kova oluşturulur; sayılar ilgili basamaklarına göre bu kovalara dağıtılır ve aynı sırayla yeniden birleştirilir.</p>

<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">def</span> <span class="nf">radix_sort</span><span class="p">(</span><span class="n">numbers</span><span class="p">):</span>
    <span class="k">if</span> <span class="ow">not</span> <span class="n">numbers</span><span class="p">:</span>
        <span class="k">return</span> <span class="p">[]</span>

    <span class="n">result</span> <span class="o">=</span> <span class="n">numbers</span><span class="p">.</span><span class="nf">copy</span><span class="p">()</span>
    <span class="n">maximum</span> <span class="o">=</span> <span class="nf">max</span><span class="p">(</span><span class="n">result</span><span class="p">)</span>
    <span class="n">place</span> <span class="o">=</span> <span class="mi">1</span>

    <span class="k">while</span> <span class="n">maximum</span> <span class="o">//</span> <span class="n">place</span> <span class="o">&gt;</span> <span class="mi">0</span><span class="p">:</span>
        <span class="n">buckets</span> <span class="o">=</span> <span class="p">[[]</span> <span class="k">for</span> <span class="n">_</span> <span class="ow">in</span> <span class="nf">range</span><span class="p">(</span><span class="mi">10</span><span class="p">)]</span>

        <span class="c1"># Sayıları mevcut basamağa göre kovalara dağıt.
</span>        <span class="k">for</span> <span class="n">number</span> <span class="ow">in</span> <span class="n">result</span><span class="p">:</span>
            <span class="n">digit</span> <span class="o">=</span> <span class="p">(</span><span class="n">number</span> <span class="o">//</span> <span class="n">place</span><span class="p">)</span> <span class="o">%</span> <span class="mi">10</span>
            <span class="n">buckets</span><span class="p">[</span><span class="n">digit</span><span class="p">].</span><span class="nf">append</span><span class="p">(</span><span class="n">number</span><span class="p">)</span>

        <span class="c1"># Kovaların sırası korunarak listeyi yeniden oluştur.
</span>        <span class="n">result</span> <span class="o">=</span> <span class="p">[</span><span class="n">number</span> <span class="k">for</span> <span class="n">bucket</span> <span class="ow">in</span> <span class="n">buckets</span> <span class="k">for</span> <span class="n">number</span> <span class="ow">in</span> <span class="n">bucket</span><span class="p">]</span>
        <span class="n">place</span> <span class="o">*=</span> <span class="mi">10</span>

    <span class="k">return</span> <span class="n">result</span>

<span class="n">values</span> <span class="o">=</span> <span class="p">[</span><span class="mi">170</span><span class="p">,</span> <span class="mi">45</span><span class="p">,</span> <span class="mi">75</span><span class="p">,</span> <span class="mi">90</span><span class="p">,</span> <span class="mi">802</span><span class="p">,</span> <span class="mi">24</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">66</span><span class="p">]</span>
<span class="nf">print</span><span class="p">(</span><span class="nf">radix_sort</span><span class="p">(</span><span class="n">values</span><span class="p">))</span>
</code></pre></div></div>

<p>Kovaların liste olarak kullanılması kararlılığı doğal biçimde sağlar. Aynı rakama sahip sayılar kovaya giriş sıralarını koruyarak çıkar.</p>

<h2 id="ne-zaman-tercih-edilmeli">Ne zaman tercih edilmeli?</h2>

<p>Radix Sort; kimlik numaraları, sabit uzunluktaki sayısal kodlar, IP adresleri veya çok sayıda tam sayı gibi yapılandırılmış verilerde oldukça etkilidir. Buna karşılık değişken uzunluklu veriler, ondalıklı sayılar ve negatif değerler ek uyarlamalar gerektirir. Negatif sayılar genellikle mutlak değerlerine göre ayrı sıralanıp ters çevrilerek pozitiflerle birleştirilir.</p>

<p>Kısacası Radix Sort, karşılaştırma yapmadan sıralamanın mümkün olduğunu gösteren zarif bir algoritmadır. Doğru veri türünde kullanıldığında basamakları tek tek tırmanır ve listenin zirvesine beklenmedik bir hızla ulaşır.</p>]]></content><author><name>Sonsuz Us</name></author><category term="Bilgi" /><category term="algoritma" /><category term="radix-sort" /><category term="sıralama" /><category term="veri-yapıları" /><category term="python" /><category term="karmaşıklık" /><summary type="html"><![CDATA[Bir sayı listesini sıralarken ilk refleksimiz sayıları ikişer ikişer karşılaştırmaktır. Radix Sort ise masaya farklı bir fikir koyar: “Sayıların tamamını karşılaştırmak yerine basamaklarını sırayla incelesek?” Bu yaklaşım sayesinde uygun koşullarda karşılaştırmaya dayalı algoritmaların $O(n \log n)$ sınırını aşarak doğrusal zamana yaklaşabiliriz.]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://program.sonsuz.us/img/basamakli-siralama-radix-16.png" /><media:content medium="image" url="https://program.sonsuz.us/img/basamakli-siralama-radix-16.png" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">Bitlerden Fraktala: Thue-Morse Ardışıklığının Şaşırtıcı Dünyası</title><link href="https://program.sonsuz.us/posts/bitlerden-fraktala-thue-morse-ardisikliginin-sasirtici-dunyasi/" rel="alternate" type="text/html" title="Bitlerden Fraktala: Thue-Morse Ardışıklığının Şaşırtıcı Dünyası" /><published>2026-10-12T00:00:00+00:00</published><updated>2026-10-12T00:00:00+00:00</updated><id>https://program.sonsuz.us/posts/bitlerden-fraktala-thue-morse-ardisikliginin-sasirtici-dunyasi</id><content type="html" xml:base="https://program.sonsuz.us/posts/bitlerden-fraktala-thue-morse-ardisikliginin-sasirtici-dunyasi/"><![CDATA[<p>Bir bilgisayara yalnızca “elindeki bitleri kopyala ve terslerini yanına ekle” deseydik, ortaya ne kadar karmaşık bir yapı çıkabilirdi? Thue-Morse ardışıklığı, son derece basit bu talimattan doğmasına rağmen öz-benzerlik, düzen ve kaos arasında gidip gelen büyüleyici bir dizidir. Üstelik matematikten müziğe, kombinatorikten algoritma tasarımına kadar pek çok alanda karşımıza çıkar.</p>

<p><img src="/img/bitlerden-fraktala-thue-22.svg" alt="bitlerden-fraktala-thue-22" /></p>

<p>``
Diziyi oluşturmaya tek bir <code class="language-plaintext highlighter-rouge">0</code> ile başlayalım. Her adımda mevcut bölümün bitlerini ters çevirip sonuna ekleyelim:</p>

<div class="language-text highlighter-rouge"><div class="highlight"><pre class="highlight"><code>0
01
0110
01101001
0110100110010110
</code></pre></div></div>

<p>Burada ters çevirme işlemi <code class="language-plaintext highlighter-rouge">0 → 1</code> ve <code class="language-plaintext highlighter-rouge">1 → 0</code> biçimindedir. Örneğin <code class="language-plaintext highlighter-rouge">0110</code> kelimesinin tümleyeni <code class="language-plaintext highlighter-rouge">1001</code> olur; ikisini birleştirince <code class="language-plaintext highlighter-rouge">01101001</code> elde edilir. Bu üretim kuralı matematiksel olarak</p>

\[T_{k+1} = T_k\,\overline{T_k}\]

<p>şeklinde yazılabilir. $\overline{T_k}$, $T_k$ içindeki bütün bitlerin tümleyenini temsil eder. Her turda uzunluk iki katına çıktığı için $k$ adımından sonra $2^k$ eleman bulunur.</p>

<h2 id="sayıların-ikili-gösterimiyle-bağlantısı">Sayıların ikili gösterimiyle bağlantısı</h2>

<p>Thue-Morse dizisinin yalnızca önceki parçayı kopyalayarak tanımlanması gerekmez. Sıfırdan başlayan $n$ indeksli terim, $n$ sayısının ikili gösterimindeki <code class="language-plaintext highlighter-rouge">1</code> sayısının tek veya çift olmasına göre hesaplanabilir.</p>

<p>$n$ içindeki <code class="language-plaintext highlighter-rouge">1</code> bitlerinin sayısına $s_2(n)$ dersek:</p>

\[t_n = s_2(n) \bmod 2\]

<p>Yani <code class="language-plaintext highlighter-rouge">1</code> sayısı çiftse sonuç <code class="language-plaintext highlighter-rouge">0</code>, tekse <code class="language-plaintext highlighter-rouge">1</code> olur.</p>

<table>
  <thead>
    <tr>
      <th style="text-align: right">$n$</th>
      <th style="text-align: center">İkili gösterim</th>
      <th style="text-align: right"><code class="language-plaintext highlighter-rouge">1</code> sayısı</th>
      <th style="text-align: right">$t_n$</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td style="text-align: right">0</td>
      <td style="text-align: center">0</td>
      <td style="text-align: right">0</td>
      <td style="text-align: right">0</td>
    </tr>
    <tr>
      <td style="text-align: right">1</td>
      <td style="text-align: center">1</td>
      <td style="text-align: right">1</td>
      <td style="text-align: right">1</td>
    </tr>
    <tr>
      <td style="text-align: right">2</td>
      <td style="text-align: center">10</td>
      <td style="text-align: right">1</td>
      <td style="text-align: right">1</td>
    </tr>
    <tr>
      <td style="text-align: right">3</td>
      <td style="text-align: center">11</td>
      <td style="text-align: right">2</td>
      <td style="text-align: right">0</td>
    </tr>
    <tr>
      <td style="text-align: right">4</td>
      <td style="text-align: center">100</td>
      <td style="text-align: right">1</td>
      <td style="text-align: right">1</td>
    </tr>
    <tr>
      <td style="text-align: right">5</td>
      <td style="text-align: center">101</td>
      <td style="text-align: right">2</td>
      <td style="text-align: right">0</td>
    </tr>
    <tr>
      <td style="text-align: right">6</td>
      <td style="text-align: center">110</td>
      <td style="text-align: right">2</td>
      <td style="text-align: right">0</td>
    </tr>
    <tr>
      <td style="text-align: right">7</td>
      <td style="text-align: center">111</td>
      <td style="text-align: right">3</td>
      <td style="text-align: right">1</td>
    </tr>
  </tbody>
</table>

<p>Bu tanımdan kullanışlı iki bağıntı çıkar:</p>

\[t_{2n}=t_n, \qquad t_{2n+1}=1-t_n\]

<p>Çift indeksler önceki değerleri tekrar ederken tek indeksler onların tersini taşır. Dizinin fraktal karakterinin cebirsel özeti tam olarak budur.</p>

<h2 id="neden-fraktala-benziyor">Neden fraktala benziyor?</h2>

<p>Fraktallarda bütünün daha küçük ölçekli kopyalarını görürüz. Thue-Morse dizisinde de her blok, daha önce oluşmuş bir bloğu ve onun renkleri değiştirilmiş hâlini içerir. Bitleri siyah ve beyaz kareler olarak çizersek farklı ölçeklerde yinelenen desenler ortaya çıkar. Ancak bu tekrar tam anlamıyla periyodik değildir.</p>

<table>
  <thead>
    <tr>
      <th>Özellik</th>
      <th>Periyodik dizi</th>
      <th>Thue-Morse dizisi</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Üretim</td>
      <td>Sabit blok tekrarı</td>
      <td>Blok ve tümleyenini birleştirme</td>
    </tr>
    <tr>
      <td>Tahmin edilebilirlik</td>
      <td>Kısa dönem yeterlidir</td>
      <td>İndeksin bit yapısı gerekir</td>
    </tr>
    <tr>
      <td>Öz-benzerlik</td>
      <td>Genellikle sınırlı</td>
      <td>Her iki kat ölçekte görünür</td>
    </tr>
    <tr>
      <td>Periyot</td>
      <td>Sonlu olabilir</td>
      <td>Sonsuz dizide yoktur</td>
    </tr>
  </tbody>
</table>

<p>Dizi deterministiktir; yani rastgele değildir. Buna karşın sonsuza kadar tekrar eden sabit bir periyoda da sahip değildir. Dahası, belirli türde aşırı tekrarları engelleyen <strong>overlap-free</strong> özelliğiyle kelime kombinatoriğinde önemli bir yere sahiptir.</p>

<h2 id="python-ile-üretelim">Python ile üretelim</h2>

<p>Aşağıdaki fonksiyon, her turun sonuna mevcut bitlerin tümleyenini ekler:</p>

<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">def</span> <span class="nf">thue_morse</span><span class="p">(</span><span class="n">iterations</span><span class="p">:</span> <span class="nb">int</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">str</span><span class="p">:</span>
    <span class="n">sequence</span> <span class="o">=</span> <span class="sh">"</span><span class="s">0</span><span class="sh">"</span>

    <span class="k">for</span> <span class="n">_</span> <span class="ow">in</span> <span class="nf">range</span><span class="p">(</span><span class="n">iterations</span><span class="p">):</span>
        <span class="n">complement</span> <span class="o">=</span> <span class="sh">""</span><span class="p">.</span><span class="nf">join</span><span class="p">(</span>
            <span class="sh">"</span><span class="s">1</span><span class="sh">"</span> <span class="k">if</span> <span class="n">bit</span> <span class="o">==</span> <span class="sh">"</span><span class="s">0</span><span class="sh">"</span> <span class="k">else</span> <span class="sh">"</span><span class="s">0</span><span class="sh">"</span>
            <span class="k">for</span> <span class="n">bit</span> <span class="ow">in</span> <span class="n">sequence</span>
        <span class="p">)</span>
        <span class="n">sequence</span> <span class="o">+=</span> <span class="n">complement</span>

    <span class="k">return</span> <span class="n">sequence</span>

<span class="nf">print</span><span class="p">(</span><span class="nf">thue_morse</span><span class="p">(</span><span class="mi">4</span><span class="p">))</span>
<span class="c1"># 0110100110010110
</span></code></pre></div></div>

<p>Tek bir terime ihtiyaç duyulduğunda bütün diziyi üretmek gereksizdir. Python’daki <code class="language-plaintext highlighter-rouge">bit_count()</code> yöntemi daha doğrudan bir çözüm sunar:</p>

<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">def</span> <span class="nf">thue_morse_term</span><span class="p">(</span><span class="n">n</span><span class="p">:</span> <span class="nb">int</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">int</span><span class="p">:</span>
    <span class="c1"># İkili gösterimdeki 1 sayısının paritesini döndürür.
</span>    <span class="k">return</span> <span class="n">n</span><span class="p">.</span><span class="nf">bit_count</span><span class="p">()</span> <span class="o">%</span> <span class="mi">2</span>

<span class="nf">print</span><span class="p">([</span><span class="nf">thue_morse_term</span><span class="p">(</span><span class="n">n</span><span class="p">)</span> <span class="k">for</span> <span class="n">n</span> <span class="ow">in</span> <span class="nf">range</span><span class="p">(</span><span class="mi">16</span><span class="p">)])</span>
</code></pre></div></div>

<p>İlk yöntem görsel deseni ve öz-benzerliği incelemek için, ikinci yöntemse büyük indekslerde hızlı sorgulama yapmak için uygundur.</p>

<p>Thue-Morse ardışıklığı, karmaşıklığın mutlaka karmaşık kurallardan doğmadığını gösteren zarif bir örnektir. Bir bit, bir tümleyen işlemi ve tekrar: Dijital dünyanın bu küçük tarifi, sonsuz ve periyotsuz bir matematik manzarası üretmeye yeter.</p>]]></content><author><name>Sonsuz Us</name></author><category term="Bilgi" /><category term="thue-morse" /><category term="algoritma" /><category term="matematik" /><category term="fraktal" /><category term="python" /><category term="bit işlemleri" /><summary type="html"><![CDATA[Bir bilgisayara yalnızca “elindeki bitleri kopyala ve terslerini yanına ekle” deseydik, ortaya ne kadar karmaşık bir yapı çıkabilirdi? Thue-Morse ardışıklığı, son derece basit bu talimattan doğmasına rağmen öz-benzerlik, düzen ve kaos arasında gidip gelen büyüleyici bir dizidir. Üstelik matematikten müziğe, kombinatorikten algoritma tasarımına kadar pek çok alanda karşımıza çıkar.]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://program.sonsuz.us/img/bitlerden-fraktala-thue-22.png" /><media:content medium="image" url="https://program.sonsuz.us/img/bitlerden-fraktala-thue-22.png" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">Euler Yolları ve Königsberg Köprüleri: Bir Şehir Gezintisinden Graf Teorisine</title><link href="https://program.sonsuz.us/posts/euler-yollari-ve-konigsberg-kopruleri-bir-sehir-gezintisinden-graf-teorisine/" rel="alternate" type="text/html" title="Euler Yolları ve Königsberg Köprüleri: Bir Şehir Gezintisinden Graf Teorisine" /><published>2026-10-12T00:00:00+00:00</published><updated>2026-10-12T00:00:00+00:00</updated><id>https://program.sonsuz.us/posts/euler-yollari-ve-konigsberg-kopruleri-bir-sehir-gezintisinden-graf-teorisine</id><content type="html" xml:base="https://program.sonsuz.us/posts/euler-yollari-ve-konigsberg-kopruleri-bir-sehir-gezintisinden-graf-teorisine/"><![CDATA[<p>Bir pazar yürüyüşüne çıktığınızı ve şehirdeki her köprüden yalnızca bir kez geçmek istediğinizi düşünün. Başladığınız yere dönmeniz şart olmayabilir; ancak hiçbir köprüyü ikinci kez kullanamazsınız. Kulağa eğlenceli bir rota bulmacası gibi gelen bu soru, 18. yüzyılda matematikçi Leonhard Euler’in elinde yepyeni bir alanın, yani graf teorisinin doğmasına yol açtı.</p>

<p><img src="/img/euler-yollari-ve-78.svg" alt="euler-yollari-ve-78" /></p>

<p>``</p>
<h2 id="königsberg-köprüleri-problemi">Königsberg Köprüleri Problemi</h2>

<p>Prusya’nın Königsberg şehri, Pregel Nehri’nin ayırdığı dört kara parçası ve bunları birbirine bağlayan yedi köprüden oluşuyordu. Şehir halkının sorusu basitti: Her köprüden tam bir kez geçilen bir yürüyüş yapılabilir miydi?</p>

<p>Euler, kara parçalarının şekli veya köprülerin uzunluğu gibi ayrıntıların önemsiz olduğunu fark etti. Her kara parçasını bir <strong>düğüm</strong>, her köprüyü ise iki düğümü bağlayan bir <strong>kenar</strong> olarak temsil etti. Böylece fiziksel şehir, matematiksel bir grafa dönüştü.</p>

<table>
  <thead>
    <tr>
      <th>Gerçek dünyadaki öğe</th>
      <th>Graf karşılığı</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Kara parçası</td>
      <td>Düğüm (vertex)</td>
    </tr>
    <tr>
      <td>Köprü</td>
      <td>Kenar (edge)</td>
    </tr>
    <tr>
      <td>Bir kara parçasındaki köprü sayısı</td>
      <td>Düğüm derecesi</td>
    </tr>
    <tr>
      <td>Köprüleri kullanan yürüyüş</td>
      <td>Graf üzerinde yol</td>
    </tr>
  </tbody>
</table>

<p>Aynı iki kara parçası arasında birden fazla köprü bulunabildiği için ortaya çıkan yapı teknik olarak bir <strong>çoklu graf</strong>tır.</p>

<h2 id="düğüm-derecesi-neden-önemlidir">Düğüm Derecesi Neden Önemlidir?</h2>

<p>Bir düğümün derecesi, o düğüme bağlı kenarların sayısıdır ve $\deg(v)$ ile gösterilir. Bir yol sırasında ara düğüme bir kenardan girip başka bir kenardan çıkmak gerekir. Dolayısıyla kullanılan kenarlar çiftler hâlinde eşleşir. Tek dereceli düğümler ise bu eşleşmenin bozulduğu başlangıç veya bitiş noktaları olabilir.</p>

<p>Grafın bütün düğüm dereceleri için şu önemli eşitlik geçerlidir:</p>

\[\sum_{v \in V} \deg(v) = 2\vert E\vert\]

<p>Her kenar iki uca sahip olduğundan dereceler toplamına iki katkı yapar. Bu sonuç, tek dereceli düğüm sayısının her zaman çift olduğunu da gösterir.</p>

<p>Königsberg grafındaki dört düğümün dereceleri $3, 3, 3$ ve $5$ idi. Yani dört düğüm de tek dereceliydi. Oysa her köprüden yalnızca bir kez geçen bir rota için tek dereceli düğüm sayısı en fazla iki olmalıdır. Sonuç: İstenen yürüyüş imkânsızdı!</p>

<h2 id="euler-yolu-ve-euler-devresi">Euler Yolu ve Euler Devresi</h2>

<table>
  <thead>
    <tr>
      <th>Kavram</th>
      <th>Koşul</th>
      <th>Başlangıç ve bitiş</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Euler devresi</td>
      <td>Tek dereceli düğüm yoktur</td>
      <td>Aynı düğüm</td>
    </tr>
    <tr>
      <td>Euler yolu</td>
      <td>Tam iki tek dereceli düğüm vardır</td>
      <td>Farklı düğümler</td>
    </tr>
    <tr>
      <td>İmkânsız durum</td>
      <td>İkiden fazla tek dereceli düğüm vardır</td>
      <td>Uygun rota yoktur</td>
    </tr>
  </tbody>
</table>

<p>Bu koşullarda grafın, izole düğümler göz ardı edildiğinde, bağlantılı olduğu kabul edilir. Euler yolu <strong>her kenarı</strong> tam bir kez kullanır. Bu nedenle her düğümü bir kez ziyaret etmeye çalışan Hamilton yoluyla karıştırılmamalıdır.</p>

<h2 id="python-ile-euler-yolu-kontrolü">Python ile Euler Yolu Kontrolü</h2>

<p>Aşağıdaki fonksiyon, komşuluk listesiyle verilen bağlantılı bir grafın Euler özelliğini dereceler üzerinden sınıflandırır:</p>

<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">def</span> <span class="nf">euler_durumu</span><span class="p">(</span><span class="n">graf</span><span class="p">):</span>
    <span class="n">tek_dereceliler</span> <span class="o">=</span> <span class="p">[]</span>

    <span class="k">for</span> <span class="n">dugum</span><span class="p">,</span> <span class="n">komsular</span> <span class="ow">in</span> <span class="n">graf</span><span class="p">.</span><span class="nf">items</span><span class="p">():</span>
        <span class="k">if</span> <span class="nf">len</span><span class="p">(</span><span class="n">komsular</span><span class="p">)</span> <span class="o">%</span> <span class="mi">2</span> <span class="o">==</span> <span class="mi">1</span><span class="p">:</span>
            <span class="n">tek_dereceliler</span><span class="p">.</span><span class="nf">append</span><span class="p">(</span><span class="n">dugum</span><span class="p">)</span>

    <span class="k">if</span> <span class="nf">len</span><span class="p">(</span><span class="n">tek_dereceliler</span><span class="p">)</span> <span class="o">==</span> <span class="mi">0</span><span class="p">:</span>
        <span class="k">return</span> <span class="sh">"</span><span class="s">Euler devresi var</span><span class="sh">"</span>
    <span class="k">elif</span> <span class="nf">len</span><span class="p">(</span><span class="n">tek_dereceliler</span><span class="p">)</span> <span class="o">==</span> <span class="mi">2</span><span class="p">:</span>
        <span class="k">return</span> <span class="sa">f</span><span class="sh">"</span><span class="s">Euler yolu var: </span><span class="si">{</span><span class="n">tek_dereceliler</span><span class="si">}</span><span class="sh">"</span>
    <span class="k">else</span><span class="p">:</span>
        <span class="k">return</span> <span class="sh">"</span><span class="s">Euler yolu yok</span><span class="sh">"</span>

<span class="n">sehir</span> <span class="o">=</span> <span class="p">{</span>
    <span class="sh">"</span><span class="s">A</span><span class="sh">"</span><span class="p">:</span> <span class="p">[</span><span class="sh">"</span><span class="s">B</span><span class="sh">"</span><span class="p">,</span> <span class="sh">"</span><span class="s">B</span><span class="sh">"</span><span class="p">,</span> <span class="sh">"</span><span class="s">C</span><span class="sh">"</span><span class="p">],</span>
    <span class="sh">"</span><span class="s">B</span><span class="sh">"</span><span class="p">:</span> <span class="p">[</span><span class="sh">"</span><span class="s">A</span><span class="sh">"</span><span class="p">,</span> <span class="sh">"</span><span class="s">A</span><span class="sh">"</span><span class="p">,</span> <span class="sh">"</span><span class="s">D</span><span class="sh">"</span><span class="p">],</span>
    <span class="sh">"</span><span class="s">C</span><span class="sh">"</span><span class="p">:</span> <span class="p">[</span><span class="sh">"</span><span class="s">A</span><span class="sh">"</span><span class="p">,</span> <span class="sh">"</span><span class="s">D</span><span class="sh">"</span><span class="p">,</span> <span class="sh">"</span><span class="s">D</span><span class="sh">"</span><span class="p">],</span>
    <span class="sh">"</span><span class="s">D</span><span class="sh">"</span><span class="p">:</span> <span class="p">[</span><span class="sh">"</span><span class="s">B</span><span class="sh">"</span><span class="p">,</span> <span class="sh">"</span><span class="s">C</span><span class="sh">"</span><span class="p">,</span> <span class="sh">"</span><span class="s">C</span><span class="sh">"</span><span class="p">,</span> <span class="sh">"</span><span class="s">D</span><span class="sh">"</span><span class="p">,</span> <span class="sh">"</span><span class="s">D</span><span class="sh">"</span><span class="p">]</span>
<span class="p">}</span>

<span class="nf">print</span><span class="p">(</span><span class="nf">euler_durumu</span><span class="p">(</span><span class="n">sehir</span><span class="p">))</span>
</code></pre></div></div>

<p>Listelerde aynı komşunun tekrarlanması paralel köprüleri temsil eder. Bir öz döngü ise düğüm derecesine iki katkı yaptığı için listede iki kez gösterilmiştir. Gerçek bir uygulamada ayrıca DFS veya BFS kullanarak grafın bağlantılı olup olmadığı doğrulanmalıdır.</p>

<p>Euler’in büyük başarısı belirli bir rotayı denemek değil, böyle bir rotanın var olup olamayacağını yapısal olarak kanıtlamaktı. Bugün aynı fikir; çöp toplama rotaları, ağ analizi, devre tasarımı ve DNA dizileme gibi pek çok alanda karşımıza çıkıyor. Bazen bir köprüden geçmeden önce dereceleri saymak, saatlerce dolaşmaktan çok daha akıllıcadır.</p>]]></content><author><name>Sonsuz Us</name></author><category term="Bilgi" /><category term="graf teorisi" /><category term="euler yolu" /><category term="königsberg" /><category term="algoritma" /><category term="python" /><summary type="html"><![CDATA[Bir pazar yürüyüşüne çıktığınızı ve şehirdeki her köprüden yalnızca bir kez geçmek istediğinizi düşünün. Başladığınız yere dönmeniz şart olmayabilir; ancak hiçbir köprüyü ikinci kez kullanamazsınız. Kulağa eğlenceli bir rota bulmacası gibi gelen bu soru, 18. yüzyılda matematikçi Leonhard Euler’in elinde yepyeni bir alanın, yani graf teorisinin doğmasına yol açtı.]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://program.sonsuz.us/img/euler-yollari-ve-78.png" /><media:content medium="image" url="https://program.sonsuz.us/img/euler-yollari-ve-78.png" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">Gezgin Satıcı Problemi: Açgözlü Algoritmalarla Kısa Yolu Aramak</title><link href="https://program.sonsuz.us/posts/gezgin-satici-problemi-acgozlu-algoritmalarla-kisa-yolu-aramak/" rel="alternate" type="text/html" title="Gezgin Satıcı Problemi: Açgözlü Algoritmalarla Kısa Yolu Aramak" /><published>2026-10-12T00:00:00+00:00</published><updated>2026-10-12T00:00:00+00:00</updated><id>https://program.sonsuz.us/posts/gezgin-satici-problemi-acgozlu-algoritmalarla-kisa-yolu-aramak</id><content type="html" xml:base="https://program.sonsuz.us/posts/gezgin-satici-problemi-acgozlu-algoritmalarla-kisa-yolu-aramak/"><![CDATA[<p><img src="/img/gezgin-satici-problemi-93.svg" alt="gezgin-satici-problemi-93" /></p>

<p>Bir satıcının ziyaret etmesi gereken şehirler, sınırlı yakıtı ve eve dönmeden önce yetişmesi gereken bir akşam yemeği olduğunu düşünün. Amaç, her şehre tam bir kez uğrayıp başlangıç noktasına dönen en kısa rotayı bulmaktır. Gezgin Satıcı Problemi, yani TSP, basit görünen kurallarının altında devasa bir arama uzayı saklayan klasik bir optimizasyon problemidir.</p>

<p>``</p>

<h2 id="tsp-neden-bu-kadar-zor">TSP neden bu kadar zor?</h2>

<p>Şehirleri düğüm, aralarındaki yolları da ağırlıklı kenar olarak gösterirsek problem bir grafik üzerinde tanımlanabilir. $n$ şehir için turun toplam maliyeti şöyle yazılır:</p>

\[C(\pi)=\sum_{i=1}^{n-1} d(\pi_i,\pi_{i+1})+d(\pi_n,\pi_1)\]

<p>Burada $\pi$, şehirlerin ziyaret sırasını; $d(a,b)$ ise iki şehir arasındaki uzaklığı temsil eder. Aradığımız sonuç, bütün olası sıralamalar içindeki minimum değerdir:</p>

\[C^*=\min_{\pi} C(\pi)\]

<p>Simetrik uzaklıklarda başlangıç ve yön tekrarları elendiğinde bile yaklaşık $(n-1)!/2$ farklı tur bulunur. Yalnızca 20 şehir için seçenek sayısı astronomik seviyeye çıkar. TSP’nin karar sürümü NP-tam, optimizasyon sürümü ise NP-zordur. Bu nedenle büyük girdilerde bütün turları denemek yerine hızlı ve yeterince iyi yaklaşık çözümler kullanılır.</p>

<table>
  <thead>
    <tr>
      <th>Yaklaşım</th>
      <th>Temel fikir</th>
      <th style="text-align: right">Hız</th>
      <th>Sonuç kalitesi</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Kaba kuvvet</td>
      <td>Bütün turları dener</td>
      <td style="text-align: right">Çok düşük</td>
      <td>Kesin optimum</td>
    </tr>
    <tr>
      <td>Dinamik programlama</td>
      <td>Alt problem sonuçlarını saklar</td>
      <td style="text-align: right">Düşük</td>
      <td>Kesin optimum</td>
    </tr>
    <tr>
      <td>En yakın komşu</td>
      <td>Her adımda en yakın şehri seçer</td>
      <td style="text-align: right">Yüksek</td>
      <td>Başlangıca bağlı</td>
    </tr>
    <tr>
      <td>Çoklu başlangıç + 2-opt</td>
      <td>Birkaç tur üretip iyileştirir</td>
      <td style="text-align: right">Orta</td>
      <td>Genellikle daha iyi</td>
    </tr>
  </tbody>
</table>

<h2 id="açgözlü-düşünce-ve-en-yakın-komşu">Açgözlü düşünce ve en yakın komşu</h2>

<p>Açgözlü algoritmalar, gelecekte oluşabilecek etkileri kapsamlı biçimde hesaplamadan o an en avantajlı seçimi yapar. TSP için en bilinen açgözlü yöntem <strong>en yakın komşu algoritmasıdır</strong>:</p>

<ol>
  <li>Bir başlangıç şehri seç.</li>
  <li>Ziyaret edilmemiş en yakın şehre git.</li>
  <li>Bütün şehirler bitene kadar işlemi tekrarla.</li>
  <li>Başlangıç şehrine dön.</li>
</ol>

<p>Bu strateji hızlıdır; ancak kısa adımların toplamı her zaman en kısa tur değildir. Algoritma ucuz yolları erkenden tüketip sona birbirinden çok uzak iki şehir bırakabilir. Başka bir deyişle, yerel olarak iyi karar küresel olarak kötü olabilir.</p>

<p>Aşağıdaki Python kodu uzaklık matrisi üzerinde yöntemi uygular:</p>

<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">def</span> <span class="nf">nearest_neighbor</span><span class="p">(</span><span class="n">distances</span><span class="p">,</span> <span class="n">start</span><span class="o">=</span><span class="mi">0</span><span class="p">):</span>
    <span class="n">n</span> <span class="o">=</span> <span class="nf">len</span><span class="p">(</span><span class="n">distances</span><span class="p">)</span>
    <span class="n">unvisited</span> <span class="o">=</span> <span class="nf">set</span><span class="p">(</span><span class="nf">range</span><span class="p">(</span><span class="n">n</span><span class="p">))</span>
    <span class="n">unvisited</span><span class="p">.</span><span class="nf">remove</span><span class="p">(</span><span class="n">start</span><span class="p">)</span>
    <span class="n">route</span> <span class="o">=</span> <span class="p">[</span><span class="n">start</span><span class="p">]</span>
    <span class="n">total</span> <span class="o">=</span> <span class="mi">0</span>
    <span class="n">current</span> <span class="o">=</span> <span class="n">start</span>

    <span class="k">while</span> <span class="n">unvisited</span><span class="p">:</span>
        <span class="n">next_city</span> <span class="o">=</span> <span class="nf">min</span><span class="p">(</span>
            <span class="n">unvisited</span><span class="p">,</span>
            <span class="n">key</span><span class="o">=</span><span class="k">lambda</span> <span class="n">city</span><span class="p">:</span> <span class="n">distances</span><span class="p">[</span><span class="n">current</span><span class="p">][</span><span class="n">city</span><span class="p">]</span>
        <span class="p">)</span>
        <span class="n">total</span> <span class="o">+=</span> <span class="n">distances</span><span class="p">[</span><span class="n">current</span><span class="p">][</span><span class="n">next_city</span><span class="p">]</span>
        <span class="n">route</span><span class="p">.</span><span class="nf">append</span><span class="p">(</span><span class="n">next_city</span><span class="p">)</span>
        <span class="n">unvisited</span><span class="p">.</span><span class="nf">remove</span><span class="p">(</span><span class="n">next_city</span><span class="p">)</span>
        <span class="n">current</span> <span class="o">=</span> <span class="n">next_city</span>

    <span class="n">total</span> <span class="o">+=</span> <span class="n">distances</span><span class="p">[</span><span class="n">current</span><span class="p">][</span><span class="n">start</span><span class="p">]</span>
    <span class="n">route</span><span class="p">.</span><span class="nf">append</span><span class="p">(</span><span class="n">start</span><span class="p">)</span>
    <span class="k">return</span> <span class="n">route</span><span class="p">,</span> <span class="n">total</span>
</code></pre></div></div>

<p><code class="language-plaintext highlighter-rouge">unvisited</code> henüz gidilmeyen şehirleri tutar. <code class="language-plaintext highlighter-rouge">min</code> işlemi mevcut konuma en yakın şehri seçer. Bu seçim her şehir için en fazla $O(n)$ karşılaştırma yaptığından toplam zaman karmaşıklığı $O(n^2)$, ek bellek ihtiyacı ise $O(n)$ olur.</p>

<h2 id="sonucu-biraz-daha-akıllandırmak">Sonucu biraz daha akıllandırmak</h2>

<p>Başlangıç şehri sonucu ciddi biçimde değiştirebilir. Bu nedenle algoritmayı her şehirden başlatıp en kısa turu seçmek, <strong>çoklu başlangıç</strong> adı verilen pratik bir iyileştirmedir. Ardından 2-opt uygulanabilir: Turdaki iki kenar kaldırılır, aradaki rota ters çevrilir ve toplam mesafe azalıyorsa değişiklik korunur.</p>

<p>Örneğin $(A,B)$ ve $(C,D)$ kenarları için şu karşılaştırma yapılır:</p>

\[d(A,C)+d(B,D) &lt; d(A,B)+d(C,D)\]

<p>Eşitsizlik doğruysa kenarlar değiştirilerek gereksiz çaprazlaşmalar giderilebilir. Böylece en yakın komşunun hızlı başlangıcı, yerel aramanın düzeltme yeteneğiyle birleşir.</p>

<p>TSP bize önemli bir algoritma dersi verir: Kusursuz çözüm her zaman pratik çözüm değildir. Navigasyon, lojistik, robot rotalama ve devre tasarımı gibi alanlarda birkaç saniyede bulunan kaliteli bir tur, yıllarca beklenecek optimum turdan çok daha değerlidir.</p>]]></content><author><name>Sonsuz Us</name></author><category term="Bilgi" /><category term="algoritma" /><category term="tsp" /><category term="np-zor" /><category term="açgözlü-algoritma" /><category term="en-yakın-komşu" /><category term="optimizasyon" /><category term="python" /><summary type="html"><![CDATA[Bir satıcının ziyaret etmesi gereken şehirler, sınırlı yakıtı ve eve dönmeden önce yetişmesi gereken bir akşam yemeği olduğunu düşünün. Amaç, her şehre tam bir kez uğrayıp başlangıç noktasına dönen en kısa rotayı bulmaktır. Gezgin Satıcı Problemi, yani TSP, basit görünen kurallarının altında devasa bir arama uzayı saklayan klasik bir optimizasyon problemidir.]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://program.sonsuz.us/img/gezgin-satici-problemi-93.png" /><media:content medium="image" url="https://program.sonsuz.us/img/gezgin-satici-problemi-93.png" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">Graf Renklendirme ve Welch-Powell Algoritması</title><link href="https://program.sonsuz.us/posts/graf-renklendirme-ve-welch-powell-algoritmasi/" rel="alternate" type="text/html" title="Graf Renklendirme ve Welch-Powell Algoritması" /><published>2026-10-12T00:00:00+00:00</published><updated>2026-10-12T00:00:00+00:00</updated><id>https://program.sonsuz.us/posts/graf-renklendirme-ve-welch-powell-algoritmasi</id><content type="html" xml:base="https://program.sonsuz.us/posts/graf-renklendirme-ve-welch-powell-algoritmasi/"><![CDATA[<p>Bir sınav programı hazırladığınızı, radyo frekanslarını dağıttığınızı veya birbirine komşu ülkeleri boyadığınızı düşünün. Çakışan öğelere aynı seçeneği vermemek gerekir. Graf renklendirme problemi, bu tür görevleri düğümler ve kenarlar üzerinden modelleyerek mümkün olduğunca az sayıda renk kullanmayı amaçlar. Welch-Powell algoritması ise hızlı ve anlaşılır bir sezgisel yaklaşım sunar.</p>

<p><img src="/img/graf-renklendirme-ve-10.svg" alt="graf-renklendirme-ve-10" /></p>

<p>``</p>

<h2 id="graf-renklendirme-nedir">Graf renklendirme nedir?</h2>

<p>Bir graf $G=(V,E)$ ile gösterilir. Burada $V$ düğüm kümesini, $E$ ise düğümler arasındaki kenarları temsil eder. Düğüm renklendirmede her $v \in V$ düğümüne bir renk atanır. Bir $(u,v) \in E$ kenarı varsa temel koşul şudur:</p>

\[c(u) \neq c(v)\]

<p>Buradaki $c(v)$, $v$ düğümünün rengidir. Grafı geçerli biçimde boyamak için gereken en küçük renk sayısına <strong>kromatik sayı</strong> denir ve $\chi(G)$ ile gösterilir.</p>

<table>
  <thead>
    <tr>
      <th>Graf türü</th>
      <th style="text-align: right">Kromatik sayı</th>
      <th>Açıklama</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Kenarsız graf</td>
      <td style="text-align: right">$1$</td>
      <td>Hiçbir düğüm çatışmaz</td>
    </tr>
    <tr>
      <td>İki parçalı graf</td>
      <td style="text-align: right">$2$</td>
      <td>Düğümler iki bağımsız kümeye ayrılır</td>
    </tr>
    <tr>
      <td>Tek uzunluklu çevrim</td>
      <td style="text-align: right">$3$</td>
      <td>İki renk son kenarda çatışır</td>
    </tr>
    <tr>
      <td>Tam graf $K_n$</td>
      <td style="text-align: right">$n$</td>
      <td>Her düğüm diğerleriyle komşudur</td>
    </tr>
  </tbody>
</table>

<p>Genel bir grafın kromatik sayısını kesin olarak bulmak hesaplama açısından zordur. Welch-Powell çoğu zaman az renk kullanan bir çözüm üretir; ancak her graf için gerçek minimumu garanti etmez. Dolayısıyla elde ettiği renk sayısı $k$ ise genellikle</p>

\[\chi(G) \leq k\]

<p>ifadesini söyleyebiliriz.</p>

<h2 id="welch-powell-nasıl-çalışır">Welch-Powell nasıl çalışır?</h2>

<p>Algoritmanın arkasındaki fikir, en fazla komşuya sahip düğümleri önce ele almaktır. Çünkü yüksek dereceli bir düğümü sona bırakmak, kullanılabilir renk seçeneklerini ciddi biçimde azaltabilir.</p>

<ol>
  <li>Düğümleri derecelerine göre azalan sırada diz.</li>
  <li>İlk boyanmamış düğüme yeni bir renk ata.</li>
  <li>Aynı renkle boyanmış düğümlere komşu olmayan diğer düğümlere de bu rengi ver.</li>
  <li>Boyanmamış düğüm kalmayana kadar yeni renklerle işlemi tekrarla.</li>
</ol>

<table>
  <thead>
    <tr>
      <th>Yaklaşım</th>
      <th>Avantaj</th>
      <th>Dezavantaj</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Welch-Powell</td>
      <td>Hızlı ve kolay uygulanır</td>
      <td>Minimum renk garantisi yoktur</td>
    </tr>
    <tr>
      <td>Kaba kuvvet</td>
      <td>Kesin sonucu bulabilir</td>
      <td>Büyük graflarda çok yavaştır</td>
    </tr>
    <tr>
      <td>Rastgele açgözlü</td>
      <td>Basittir</td>
      <td>Düğüm sırasına oldukça duyarlıdır</td>
    </tr>
  </tbody>
</table>

<h2 id="python-ile-uygulama">Python ile uygulama</h2>

<p>Aşağıdaki fonksiyon, grafı komşuluk kümelerinden oluşan bir sözlük olarak alır. Sonuçta her düğümün hangi renk numarasını aldığını döndürür:</p>

<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">def</span> <span class="nf">welch_powell</span><span class="p">(</span><span class="n">graph</span><span class="p">):</span>
    <span class="c1"># Düğümleri, komşu sayısına göre büyükten küçüğe sırala.
</span>    <span class="n">ordered</span> <span class="o">=</span> <span class="nf">sorted</span><span class="p">(</span><span class="n">graph</span><span class="p">,</span> <span class="n">key</span><span class="o">=</span><span class="k">lambda</span> <span class="n">node</span><span class="p">:</span> <span class="nf">len</span><span class="p">(</span><span class="n">graph</span><span class="p">[</span><span class="n">node</span><span class="p">]),</span> <span class="n">reverse</span><span class="o">=</span><span class="bp">True</span><span class="p">)</span>
    <span class="n">colors</span> <span class="o">=</span> <span class="p">{}</span>
    <span class="n">color_id</span> <span class="o">=</span> <span class="mi">0</span>

    <span class="k">while</span> <span class="nf">len</span><span class="p">(</span><span class="n">colors</span><span class="p">)</span> <span class="o">&lt;</span> <span class="nf">len</span><span class="p">(</span><span class="n">graph</span><span class="p">):</span>
        <span class="c1"># Her tur yeni bir renk grubunu temsil eder.
</span>        <span class="k">for</span> <span class="n">node</span> <span class="ow">in</span> <span class="n">ordered</span><span class="p">:</span>
            <span class="k">if</span> <span class="n">node</span> <span class="ow">in</span> <span class="n">colors</span><span class="p">:</span>
                <span class="k">continue</span>

            <span class="n">conflict</span> <span class="o">=</span> <span class="nf">any</span><span class="p">(</span>
                <span class="n">colors</span><span class="p">.</span><span class="nf">get</span><span class="p">(</span><span class="n">neighbor</span><span class="p">)</span> <span class="o">==</span> <span class="n">color_id</span>
                <span class="k">for</span> <span class="n">neighbor</span> <span class="ow">in</span> <span class="n">graph</span><span class="p">[</span><span class="n">node</span><span class="p">]</span>
            <span class="p">)</span>

            <span class="k">if</span> <span class="ow">not</span> <span class="n">conflict</span><span class="p">:</span>
                <span class="n">colors</span><span class="p">[</span><span class="n">node</span><span class="p">]</span> <span class="o">=</span> <span class="n">color_id</span>

        <span class="n">color_id</span> <span class="o">+=</span> <span class="mi">1</span>

    <span class="k">return</span> <span class="n">colors</span>


<span class="n">graph</span> <span class="o">=</span> <span class="p">{</span>
    <span class="sh">'</span><span class="s">A</span><span class="sh">'</span><span class="p">:</span> <span class="p">{</span><span class="sh">'</span><span class="s">B</span><span class="sh">'</span><span class="p">,</span> <span class="sh">'</span><span class="s">C</span><span class="sh">'</span><span class="p">},</span>
    <span class="sh">'</span><span class="s">B</span><span class="sh">'</span><span class="p">:</span> <span class="p">{</span><span class="sh">'</span><span class="s">A</span><span class="sh">'</span><span class="p">,</span> <span class="sh">'</span><span class="s">C</span><span class="sh">'</span><span class="p">,</span> <span class="sh">'</span><span class="s">D</span><span class="sh">'</span><span class="p">},</span>
    <span class="sh">'</span><span class="s">C</span><span class="sh">'</span><span class="p">:</span> <span class="p">{</span><span class="sh">'</span><span class="s">A</span><span class="sh">'</span><span class="p">,</span> <span class="sh">'</span><span class="s">B</span><span class="sh">'</span><span class="p">,</span> <span class="sh">'</span><span class="s">D</span><span class="sh">'</span><span class="p">},</span>
    <span class="sh">'</span><span class="s">D</span><span class="sh">'</span><span class="p">:</span> <span class="p">{</span><span class="sh">'</span><span class="s">B</span><span class="sh">'</span><span class="p">,</span> <span class="sh">'</span><span class="s">C</span><span class="sh">'</span><span class="p">,</span> <span class="sh">'</span><span class="s">E</span><span class="sh">'</span><span class="p">},</span>
    <span class="sh">'</span><span class="s">E</span><span class="sh">'</span><span class="p">:</span> <span class="p">{</span><span class="sh">'</span><span class="s">D</span><span class="sh">'</span><span class="p">}</span>
<span class="p">}</span>

<span class="n">result</span> <span class="o">=</span> <span class="nf">welch_powell</span><span class="p">(</span><span class="n">graph</span><span class="p">)</span>
<span class="nf">print</span><span class="p">(</span><span class="n">result</span><span class="p">)</span>
<span class="nf">print</span><span class="p">(</span><span class="sh">'</span><span class="s">Kullanılan renk:</span><span class="sh">'</span><span class="p">,</span> <span class="nf">len</span><span class="p">(</span><span class="nf">set</span><span class="p">(</span><span class="n">result</span><span class="p">.</span><span class="nf">values</span><span class="p">())))</span>
</code></pre></div></div>

<p><code class="language-plaintext highlighter-rouge">conflict</code> kontrolü, incelenen düğümün komşularından herhangi birinin mevcut rengi kullanıp kullanmadığını belirler. Çakışma yoksa aynı renk güvenle atanır. Sıralama yaklaşık $O(\vert V\vert \log \vert V\vert )$ maliyetindedir; komşuluk kontrolleriyle toplam süre kullanılan veri yapısına ve grafın yoğunluğuna bağlıdır.</p>

<h2 id="nerelerde-kullanılır">Nerelerde kullanılır?</h2>

<p>Graf renklendirme; sınavların aynı saate çakışmadan yerleştirilmesinde, işlemci yazmaçlarının dağıtılmasında, kablosuz ağ kanallarının atanmasında ve harita boyamada kullanılabilir. Welch-Powell özellikle hızlı, kabul edilebilir ve açıklanabilir bir çözüm gerektiğinde güçlü bir başlangıçtır. Daha iyi sonuç için farklı eşit derece sıralamaları denenebilir ve bulunan çözümler arasından en az renk kullanan seçilebilir.</p>]]></content><author><name>Sonsuz Us</name></author><category term="Program" /><category term="graf" /><category term="algoritma" /><category term="welch-powell" /><category term="python" /><category term="ayrık-matematik" /><category term="optimizasyon" /><summary type="html"><![CDATA[Bir sınav programı hazırladığınızı, radyo frekanslarını dağıttığınızı veya birbirine komşu ülkeleri boyadığınızı düşünün. Çakışan öğelere aynı seçeneği vermemek gerekir. Graf renklendirme problemi, bu tür görevleri düğümler ve kenarlar üzerinden modelleyerek mümkün olduğunca az sayıda renk kullanmayı amaçlar. Welch-Powell algoritması ise hızlı ve anlaşılır bir sezgisel yaklaşım sunar.]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://program.sonsuz.us/img/graf-renklendirme-ve-10.png" /><media:content medium="image" url="https://program.sonsuz.us/img/graf-renklendirme-ve-10.png" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">Grafların Bilgisayarda Gösterimi: Matris mi, Liste mi?</title><link href="https://program.sonsuz.us/posts/graflarin-bilgisayarda-gosterimi-matris-mi-liste-mi/" rel="alternate" type="text/html" title="Grafların Bilgisayarda Gösterimi: Matris mi, Liste mi?" /><published>2026-10-12T00:00:00+00:00</published><updated>2026-10-12T00:00:00+00:00</updated><id>https://program.sonsuz.us/posts/graflarin-bilgisayarda-gosterimi-matris-mi-liste-mi</id><content type="html" xml:base="https://program.sonsuz.us/posts/graflarin-bilgisayarda-gosterimi-matris-mi-liste-mi/"><![CDATA[<p>Bir sosyal ağdaki arkadaşlıkları, şehirler arasındaki yolları veya internet üzerindeki bağlantıları bilgisayarda nasıl saklarız? Matematikte birkaç nokta ve çizgiyle gösterilen graflar, belleğe yerleştirilirken biraz daha seçici olmamızı ister. En yaygın iki seçenek olan <strong>komşuluk matrisi</strong> ve <strong>komşuluk listesi</strong>, aynı grafı temsil etse de bellek tüketimi ve işlem performansı bakımından oldukça farklı davranır.</p>

<p>``</p>

<h2 id="önce-grafın-temelini-kuralım">Önce grafın temelini kuralım</h2>

<p>Bir graf, $G=(V,E)$ biçiminde tanımlanır. Burada $V$ düğümler, $E$ ise düğümler arasındaki kenarlardır. Düğüm sayısını $\vert V\vert =n$, kenar sayısını da $\vert E\vert =m$ ile gösterelim.</p>

<p>Bir grafın sahip olabileceği kenar sayısı, yönsüz ve öz döngüsüz durumda en fazla:</p>

\[m_{max}=\frac{n(n-1)}{2}\]

<p>olur. Eğer $m$, bu üst sınıra yakınsa grafa <strong>yoğun graf</strong>; kenar sayısı düğüm sayısına yakınsa <strong>seyrek graf</strong> denir. Temsil yöntemi seçilirken asıl belirleyici çoğu zaman bu yoğunluktur.</p>

<h2 id="komşuluk-matrisi">Komşuluk matrisi</h2>

<p>Komşuluk matrisi, $n \times n$ boyutunda iki boyutlu bir tablodur. <code class="language-plaintext highlighter-rouge">matris[i][j]</code> değeri, <code class="language-plaintext highlighter-rouge">i</code> ile <code class="language-plaintext highlighter-rouge">j</code> arasında kenar varsa <code class="language-plaintext highlighter-rouge">1</code>, yoksa <code class="language-plaintext highlighter-rouge">0</code> olur. Ağırlıklı graflarda bu hücreye kenarın ağırlığı yazılabilir.</p>

<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1"># Dört düğümlü yönsüz bir grafın komşuluk matrisi
</span><span class="n">matris</span> <span class="o">=</span> <span class="p">[</span>
    <span class="p">[</span><span class="mi">0</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">0</span><span class="p">],</span>
    <span class="p">[</span><span class="mi">1</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">1</span><span class="p">],</span>
    <span class="p">[</span><span class="mi">1</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">1</span><span class="p">],</span>
    <span class="p">[</span><span class="mi">0</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">0</span><span class="p">]</span>
<span class="p">]</span>

<span class="c1"># 0 ve 2 arasında doğrudan kenar var mı?
</span><span class="nf">print</span><span class="p">(</span><span class="n">matris</span><span class="p">[</span><span class="mi">0</span><span class="p">][</span><span class="mi">2</span><span class="p">]</span> <span class="o">==</span> <span class="mi">1</span><span class="p">)</span>
</code></pre></div></div>

<p>Bu yöntemin yıldız özelliği, iki düğüm arasında kenar bulunup bulunmadığını $O(1)$ zamanda söylemesidir. Ancak grafın yalnızca birkaç kenarı olsa bile bütün hücreler ayrılır. Dolayısıyla bellek karmaşıklığı her durumda $O(V^2)$ olur.</p>

<p>Bir düğümün tüm komşularını bulmak için ilgili satırın tamamı gezilir. Bu işlem $O(V)$ zaman alır. Matris, özellikle yoğun graflarda ve sık kenar sorgusu yapılan uygulamalarda güçlüdür.</p>

<h2 id="komşuluk-listesi">Komşuluk listesi</h2>

<p>Komşuluk listesinde her düğüm için yalnızca bağlantılı olduğu düğümler tutulur. Boş bağlantılar bellekte yer kaplamaz; yani kullanılmayan koltuklara bilet kesilmez.</p>

<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1"># Aynı grafın komşuluk listesi gösterimi
</span><span class="n">liste</span> <span class="o">=</span> <span class="p">{</span>
    <span class="mi">0</span><span class="p">:</span> <span class="p">[</span><span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">],</span>
    <span class="mi">1</span><span class="p">:</span> <span class="p">[</span><span class="mi">0</span><span class="p">,</span> <span class="mi">3</span><span class="p">],</span>
    <span class="mi">2</span><span class="p">:</span> <span class="p">[</span><span class="mi">0</span><span class="p">,</span> <span class="mi">3</span><span class="p">],</span>
    <span class="mi">3</span><span class="p">:</span> <span class="p">[</span><span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">]</span>
<span class="p">}</span>

<span class="c1"># 0 düğümünün komşularını dolaş
</span><span class="k">for</span> <span class="n">komsu</span> <span class="ow">in</span> <span class="n">liste</span><span class="p">[</span><span class="mi">0</span><span class="p">]:</span>
    <span class="nf">print</span><span class="p">(</span><span class="n">komsu</span><span class="p">)</span>
</code></pre></div></div>

<p>Bu yapının bellek maliyeti $O(V+E)$ düzeyindedir. Bir düğümün komşularını dolaşmak, düğümün derecesi $d(v)$ olmak üzere $O(d(v))$ sürer. Buna karşılık belirli iki düğümün komşu olup olmadığını aramak, kullanılan liste yapısına göre $O(d(v))$ zaman alabilir. Komşular bir <code class="language-plaintext highlighter-rouge">set</code> içinde saklanırsa ortalama sorgu süresi $O(1)$ seviyesine indirilebilir; fakat ek bellek maliyeti oluşur.</p>

<h2 id="hızlı-karşılaştırma">Hızlı karşılaştırma</h2>

<table>
  <thead>
    <tr>
      <th>Özellik</th>
      <th>Komşuluk matrisi</th>
      <th>Komşuluk listesi</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Bellek</td>
      <td>$O(V^2)$</td>
      <td>$O(V+E)$</td>
    </tr>
    <tr>
      <td>Kenar sorgusu</td>
      <td>$O(1)$</td>
      <td>$O(d(v))$</td>
    </tr>
    <tr>
      <td>Komşuları gezme</td>
      <td>$O(V)$</td>
      <td>$O(d(v))$</td>
    </tr>
    <tr>
      <td>Kenar ekleme</td>
      <td>$O(1)$</td>
      <td>Genellikle $O(1)$</td>
    </tr>
    <tr>
      <td>Uygun graf türü</td>
      <td>Yoğun</td>
      <td>Seyrek</td>
    </tr>
    <tr>
      <td>Uygulama kolaylığı</td>
      <td>Çok basit</td>
      <td>Biraz daha esnek</td>
    </tr>
  </tbody>
</table>

<p><img src="/img/graflarin-bilgisayarda-gosterimi-62.svg" alt="graflarin-bilgisayarda-gosterimi-62" /></p>

<h2 id="hangisini-seçmeliyiz">Hangisini seçmeliyiz?</h2>

<p>Grafınızda binlerce düğüm fakat az sayıda bağlantı varsa komşuluk listesi açık ara daha ekonomiktir. Örneğin yol ağları, web bağlantıları ve sosyal ağların büyük bölümü seyrektir. Bu yapılarda BFS ve DFS gibi algoritmalar listeyle $O(V+E)$ zamanda çalışır; matris kullanılırsa süre $O(V^2)$ seviyesine çıkabilir.</p>

<p>Düğüm sayısı küçükse, graf yoğunsa veya uygulama sürekli “Bu iki düğüm bağlı mı?” diye soruyorsa komşuluk matrisi daha pratik olabilir. Floyd–Warshall gibi matris tabanlı algoritmalar da doğal olarak bu gösterimle uyumludur.</p>

<p>Kısacası evrensel bir kazanan yoktur: <strong>matris sorgu hızını, liste ise bellek verimliliğini öne çıkarır</strong>. Doğru seçim, grafın yoğunluğuna ve en sık yapılacak işleme bağlıdır.</p>]]></content><author><name>Sonsuz Us</name></author><category term="Bilgi" /><category term="graf" /><category term="veri yapıları" /><category term="algoritma" /><category term="komşuluk matrisi" /><category term="komşuluk listesi" /><category term="python" /><summary type="html"><![CDATA[Bir sosyal ağdaki arkadaşlıkları, şehirler arasındaki yolları veya internet üzerindeki bağlantıları bilgisayarda nasıl saklarız? Matematikte birkaç nokta ve çizgiyle gösterilen graflar, belleğe yerleştirilirken biraz daha seçici olmamızı ister. En yaygın iki seçenek olan komşuluk matrisi ve komşuluk listesi, aynı grafı temsil etse de bellek tüketimi ve işlem performansı bakımından oldukça farklı davranır.]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://program.sonsuz.us/img/graflarin-bilgisayarda-gosterimi-62.png" /><media:content medium="image" url="https://program.sonsuz.us/img/graflarin-bilgisayarda-gosterimi-62.png" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">Horner Şeması: Polinomları En Az İşlemle Hesaplama</title><link href="https://program.sonsuz.us/posts/horner-semasi-polinomlari-en-az-islemle-hesaplama/" rel="alternate" type="text/html" title="Horner Şeması: Polinomları En Az İşlemle Hesaplama" /><published>2026-10-12T00:00:00+00:00</published><updated>2026-10-12T00:00:00+00:00</updated><id>https://program.sonsuz.us/posts/horner-semasi-polinomlari-en-az-islemle-hesaplama</id><content type="html" xml:base="https://program.sonsuz.us/posts/horner-semasi-polinomlari-en-az-islemle-hesaplama/"><![CDATA[<p><img src="/img/horner-semasi-polinomlari-20.svg" alt="horner-semasi-polinomlari-20" /></p>

<p>Bir polinomun belirli bir noktadaki değerini hesaplamak ilk bakışta yalnızca üsleri, çarpımları ve toplamları sırayla uygulamak gibi görünür. Ancak derece büyüdükçe klasik yöntem gereksiz işlem kalabalığına dönüşür. Horner şeması, polinomu akıllıca parantezleyerek aynı sonucu daha az çarpma işlemiyle bulur. Üstelik yöntem hem kâğıt üzerinde hem de bilgisayar programlarında son derece kullanışlıdır.</p>

<p>``</p>

<h2 id="temel-fikir-polinomu-iç-içe-geçirmek">Temel fikir: Polinomu iç içe geçirmek</h2>

<p>Derecesi $n$ olan genel bir polinomu şöyle yazabiliriz:</p>

\[P(x)=a_nx^n+a_{n-1}x^{n-1}+\cdots+a_1x+a_0\]

<p>Doğrudan hesaplamada $x^2$, $x^3$ ve diğer kuvvetler ayrı ayrı üretilebilir. Horner şeması ise ortak $x$ çarpanlarını dışarı alarak polinomu şu biçime dönüştürür:</p>

\[P(x)=(((a_nx+a_{n-1})x+a_{n-2})x+\cdots)x+a_0\]

<p>Bu ifade biraz matruşka bebeğine benzer: Her parantezin içinden başka bir çarpma ve toplama çıkar. İşleme en yüksek dereceli katsayıdan başlanır; mevcut sonuç $x$ ile çarpılır ve sıradaki katsayı eklenir.</p>

<p>Örneğin</p>

\[P(x)=2x^3-6x^2+2x-1\]

<p>polinomunu Horner biçiminde yazalım:</p>

\[P(x)=((2x-6)x+2)x-1\]

<p>$x=3$ için adımlar şöyledir:</p>

<ol>
  <li>İlk katsayıyla başla: $2$</li>
  <li>$2\cdot3-6=0$</li>
  <li>$0\cdot3+2=2$</li>
  <li>$2\cdot3-1=5$</li>
</ol>

<p>Dolayısıyla $P(3)=5$ bulunur. Küp veya kareyi ayrıca hesaplamaya hiç gerek kalmaz.</p>

<h2 id="i̇şlem-sayısı-neden-azalır">İşlem sayısı neden azalır?</h2>

<p>Standart yaklaşımda her terimin kuvveti bağımsız hesaplanırsa çok sayıda çarpma yapılabilir. Horner yönteminde derece $n$ olan bir polinom için tam olarak $n$ çarpma ve $n$ toplama yeterlidir. Bu nedenle zaman karmaşıklığı $O(n)$ olur.</p>

<table>
  <thead>
    <tr>
      <th>Özellik</th>
      <th style="text-align: right">Doğrudan hesaplama</th>
      <th style="text-align: right">Horner şeması</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Çarpma sayısı</td>
      <td style="text-align: right">Uygulamaya göre $O(n^2)$ olabilir</td>
      <td style="text-align: right">$n$</td>
    </tr>
    <tr>
      <td>Toplama sayısı</td>
      <td style="text-align: right">Yaklaşık $n$</td>
      <td style="text-align: right">$n$</td>
    </tr>
    <tr>
      <td>Ek kuvvet hesabı</td>
      <td style="text-align: right">Gerekebilir</td>
      <td style="text-align: right">Gerekmez</td>
    </tr>
    <tr>
      <td>Kod yapısı</td>
      <td style="text-align: right">Daha dağınık</td>
      <td style="text-align: right">Tek döngü</td>
    </tr>
    <tr>
      <td>Sayısal davranış</td>
      <td style="text-align: right">Daha fazla ara işlem</td>
      <td style="text-align: right">Genellikle daha kararlı</td>
    </tr>
  </tbody>
</table>

<p>Kuvvetlerin önceden verimli biçimde hesaplanması doğrudan yöntemi iyileştirebilir. Yine de Horner şeması sade yapısı ve düşük sabit maliyeti sayesinde çoğu durumda daha avantajlıdır.</p>

<h2 id="python-ile-uygulama">Python ile uygulama</h2>

<p>Katsayıları en yüksek dereceden sabit terime doğru saklayabiliriz. Aşağıdaki fonksiyon, birikmiş sonucu her adımda $x$ ile çarpıp yeni katsayıyı ekler:</p>

<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">def</span> <span class="nf">horner</span><span class="p">(</span><span class="n">katsayilar</span><span class="p">,</span> <span class="n">x</span><span class="p">):</span>
    <span class="n">sonuc</span> <span class="o">=</span> <span class="mi">0</span>

    <span class="k">for</span> <span class="n">katsayi</span> <span class="ow">in</span> <span class="n">katsayilar</span><span class="p">:</span>
        <span class="n">sonuc</span> <span class="o">=</span> <span class="n">sonuc</span> <span class="o">*</span> <span class="n">x</span> <span class="o">+</span> <span class="n">katsayi</span>

    <span class="k">return</span> <span class="n">sonuc</span>

<span class="n">katsayilar</span> <span class="o">=</span> <span class="p">[</span><span class="mi">2</span><span class="p">,</span> <span class="o">-</span><span class="mi">6</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="o">-</span><span class="mi">1</span><span class="p">]</span>
<span class="nf">print</span><span class="p">(</span><span class="nf">horner</span><span class="p">(</span><span class="n">katsayilar</span><span class="p">,</span> <span class="mi">3</span><span class="p">))</span>  <span class="c1"># 5
</span></code></pre></div></div>

<p>Buradaki <code class="language-plaintext highlighter-rouge">sonuc</code>, işlenmiş katsayıların oluşturduğu ara polinomun değeridir. Döngü değişmezi olarak düşünüldüğünde algoritmanın doğruluğu daha net görülür: Her tur sonunda bir derece daha polinoma dâhil edilir.</p>

<p>Ara değerleri görmek istersek fonksiyonu biraz genişletebiliriz:</p>

<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">def</span> <span class="nf">horner_adimlari</span><span class="p">(</span><span class="n">katsayilar</span><span class="p">,</span> <span class="n">x</span><span class="p">):</span>
    <span class="n">sonuc</span> <span class="o">=</span> <span class="n">katsayilar</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span>
    <span class="nf">print</span><span class="p">(</span><span class="n">sonuc</span><span class="p">)</span>

    <span class="k">for</span> <span class="n">katsayi</span> <span class="ow">in</span> <span class="n">katsayilar</span><span class="p">[</span><span class="mi">1</span><span class="p">:]:</span>
        <span class="n">sonuc</span> <span class="o">=</span> <span class="n">sonuc</span> <span class="o">*</span> <span class="n">x</span> <span class="o">+</span> <span class="n">katsayi</span>
        <span class="nf">print</span><span class="p">(</span><span class="n">sonuc</span><span class="p">)</span>

    <span class="k">return</span> <span class="n">sonuc</span>
</code></pre></div></div>

<p>Bu sürüm eğitim ve hata ayıklama için yararlıdır; ekrana sırasıyla $2$, $0$, $2$ ve $5$ yazdırır.</p>

<h2 id="sadece-değer-hesaplamakla-kalmaz">Sadece değer hesaplamakla kalmaz</h2>

<p>Horner şeması polinom bölmede de kullanılabilir. $P(x)$ polinomunu $(x-r)$ ifadesine sentetik bölme ile böldüğümüzde oluşan son değer $P(r)$, yani kalandır. Bu ilişki kalan teoreminden gelir:</p>

\[P(x)=(x-r)Q(x)+P(r)\]

<p>Sonuç sıfırsa $r$ polinomun köküdür. Böylece aynı kısa algoritma; değer hesaplama, kök denetleme ve sentetik bölme gibi farklı görevlerde kullanılabilir. Horner şeması, iyi bir algoritmanın yalnızca hızlı değil, aynı zamanda fikren zarif olabileceğini gösteren klasik örneklerden biridir.</p>]]></content><author><name>Sonsuz Us</name></author><category term="Bilgi" /><category term="horner şeması" /><category term="polinom" /><category term="algoritma" /><category term="matematik" /><category term="python" /><category term="sayısal hesaplama" /><summary type="html"><![CDATA[Bir polinomun belirli bir noktadaki değerini hesaplamak ilk bakışta yalnızca üsleri, çarpımları ve toplamları sırayla uygulamak gibi görünür. Ancak derece büyüdükçe klasik yöntem gereksiz işlem kalabalığına dönüşür. Horner şeması, polinomu akıllıca parantezleyerek aynı sonucu daha az çarpma işlemiyle bulur. Üstelik yöntem hem kâğıt üzerinde hem de bilgisayar programlarında son derece kullanışlıdır.]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://program.sonsuz.us/img/horner-semasi-polinomlari-20.png" /><media:content medium="image" url="https://program.sonsuz.us/img/horner-semasi-polinomlari-20.png" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">İki Parçalı Graflarda Eşleştirme: Evlenme Problemini Python ile Çözmek</title><link href="https://program.sonsuz.us/posts/iki-parcali-graflarda-eslestirme-evlenme-problemini-python-ile-cozmek/" rel="alternate" type="text/html" title="İki Parçalı Graflarda Eşleştirme: Evlenme Problemini Python ile Çözmek" /><published>2026-10-12T00:00:00+00:00</published><updated>2026-10-12T00:00:00+00:00</updated><id>https://program.sonsuz.us/posts/iki-parcali-graflarda-eslestirme-evlenme-problemini-python-ile-cozmek</id><content type="html" xml:base="https://program.sonsuz.us/posts/iki-parcali-graflarda-eslestirme-evlenme-problemini-python-ile-cozmek/"><![CDATA[<p>Bir tarafta adaylar, diğer tarafta işler olduğunu düşünün. Her aday yalnızca belirli işleri yapabiliyor ve herkes en fazla bir işle eşleştirilebiliyor. Amaç, mümkün olduğunca çok adayı uygun bir işe yerleştirmek. Romantik adıyla <strong>Evlenme Problemi</strong>, gerçekte iş dağıtımından üniversite tercih sistemlerine kadar pek çok yerde karşımıza çıkan klasik bir graf problemidir.</p>

<p><img src="/img/iki-parcali-graflarda-73.svg" alt="iki-parcali-graflarda-73" /></p>

<p>``</p>

<h2 id="i̇ki-parçalı-graf-nedir">İki parçalı graf nedir?</h2>

<p>Bir grafın düğümleri, kendi içlerinde bağlantı bulunmayan iki ayrı kümeye ayrılabiliyorsa bu grafa <strong>iki parçalı graf</strong> denir. Grafı</p>

\[G=(L \cup R, E)\]

<p>şeklinde gösterebiliriz. Burada $L$ sol grubu, $R$ sağ grubu, $E$ ise iki grup arasındaki uygunluk bağlantılarını temsil eder. Örneğin $L$ adaylar, $R$ işler olabilir.</p>

<p>Bir <strong>eşleştirme</strong>, hiçbir düğümün birden fazla seçilmiş kenarda yer almadığı kenarlar kümesidir. Aradığımız <strong>maksimum eşleştirme</strong>, mümkün olan en fazla kenarı içeren eşleştirmedir.</p>

<table>
  <thead>
    <tr>
      <th>Kavram</th>
      <th>Anlamı</th>
      <th>Örnek</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Kenar</td>
      <td>İki öğenin uyumlu olması</td>
      <td>Ayşe, Python işini yapabilir</td>
    </tr>
    <tr>
      <td>Eşleştirme</td>
      <td>Çakışmayan bağlantılar</td>
      <td>Ayşe–Python, Can–Java</td>
    </tr>
    <tr>
      <td>Maksimum eşleştirme</td>
      <td>En çok çifti oluşturan sonuç</td>
      <td>4 adaydan 4’ünü yerleştirmek</td>
    </tr>
    <tr>
      <td>Mükemmel eşleştirme</td>
      <td>Her düğümün eşleşmesi</td>
      <td>Kimse açıkta kalmaz</td>
    </tr>
  </tbody>
</table>

<h2 id="hall-evlenme-teoremi">Hall Evlenme Teoremi</h2>

<p>Teorinin kalbinde <strong>Hall Teoremi</strong> bulunur. Sol gruptaki herhangi bir $S$ alt kümesinin erişebildiği sağ düğümler $N(S)$ ile gösterilsin. Sol taraftaki herkesin eşleşebilmesi için şu koşul gereklidir ve yeterlidir:</p>

\[\vert N(S)\vert  \geq \vert S\vert\]

<p>Yani üç adayın toplamda yalnızca iki uygun işe erişimi varsa üçünü birden yerleştirmek imkânsızdır. Sandalye kapmaca oyununda üç kişinin önüne iki sandalye koymak gibi: algoritma çok zeki olabilir ama yeni sandalye üretemez.</p>

<h2 id="artırma-yolu-yaklaşımı">Artırma yolu yaklaşımı</h2>

<p>Kuhn algoritması her sol düğüm için uygun bir sağ düğüm arar. İstenen sağ düğüm boşsa eşleşme kurulur. Doluysa, mevcut eşleşmenin başka bir yere taşınıp taşınamayacağı derinlik öncelikli arama ile kontrol edilir. Böylece eşleşme sayısını bir artıran <strong>artırma yolu</strong> bulunabilir.</p>

<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">def</span> <span class="nf">maksimum_eslesme</span><span class="p">(</span><span class="n">graf</span><span class="p">):</span>
    <span class="c1"># sag_eslesme[is] = o işe yerleştirilen aday
</span>    <span class="n">sag_eslesme</span> <span class="o">=</span> <span class="p">{}</span>

    <span class="k">def</span> <span class="nf">yer_bul</span><span class="p">(</span><span class="n">aday</span><span class="p">,</span> <span class="n">ziyaret</span><span class="p">):</span>
        <span class="k">for</span> <span class="n">is_adi</span> <span class="ow">in</span> <span class="n">graf</span><span class="p">.</span><span class="nf">get</span><span class="p">(</span><span class="n">aday</span><span class="p">,</span> <span class="p">[]):</span>
            <span class="k">if</span> <span class="n">is_adi</span> <span class="ow">in</span> <span class="n">ziyaret</span><span class="p">:</span>
                <span class="k">continue</span>

            <span class="n">ziyaret</span><span class="p">.</span><span class="nf">add</span><span class="p">(</span><span class="n">is_adi</span><span class="p">)</span>
            <span class="n">mevcut_aday</span> <span class="o">=</span> <span class="n">sag_eslesme</span><span class="p">.</span><span class="nf">get</span><span class="p">(</span><span class="n">is_adi</span><span class="p">)</span>

            <span class="c1"># İş boşsa veya mevcut aday başka işe taşınabiliyorsa
</span>            <span class="k">if</span> <span class="n">mevcut_aday</span> <span class="ow">is</span> <span class="bp">None</span> <span class="ow">or</span> <span class="nf">yer_bul</span><span class="p">(</span><span class="n">mevcut_aday</span><span class="p">,</span> <span class="n">ziyaret</span><span class="p">):</span>
                <span class="n">sag_eslesme</span><span class="p">[</span><span class="n">is_adi</span><span class="p">]</span> <span class="o">=</span> <span class="n">aday</span>
                <span class="k">return</span> <span class="bp">True</span>

        <span class="k">return</span> <span class="bp">False</span>

    <span class="k">for</span> <span class="n">aday</span> <span class="ow">in</span> <span class="n">graf</span><span class="p">:</span>
        <span class="nf">yer_bul</span><span class="p">(</span><span class="n">aday</span><span class="p">,</span> <span class="nf">set</span><span class="p">())</span>

    <span class="k">return</span> <span class="p">{</span><span class="n">aday</span><span class="p">:</span> <span class="n">is_adi</span> <span class="k">for</span> <span class="n">is_adi</span><span class="p">,</span> <span class="n">aday</span> <span class="ow">in</span> <span class="n">sag_eslesme</span><span class="p">.</span><span class="nf">items</span><span class="p">()}</span>


<span class="n">graf</span> <span class="o">=</span> <span class="p">{</span>
    <span class="sh">"</span><span class="s">Ayşe</span><span class="sh">"</span><span class="p">:</span> <span class="p">[</span><span class="sh">"</span><span class="s">Python</span><span class="sh">"</span><span class="p">,</span> <span class="sh">"</span><span class="s">Veri</span><span class="sh">"</span><span class="p">],</span>
    <span class="sh">"</span><span class="s">Can</span><span class="sh">"</span><span class="p">:</span> <span class="p">[</span><span class="sh">"</span><span class="s">Python</span><span class="sh">"</span><span class="p">,</span> <span class="sh">"</span><span class="s">Java</span><span class="sh">"</span><span class="p">],</span>
    <span class="sh">"</span><span class="s">Ece</span><span class="sh">"</span><span class="p">:</span> <span class="p">[</span><span class="sh">"</span><span class="s">Veri</span><span class="sh">"</span><span class="p">],</span>
    <span class="sh">"</span><span class="s">Mert</span><span class="sh">"</span><span class="p">:</span> <span class="p">[</span><span class="sh">"</span><span class="s">Java</span><span class="sh">"</span><span class="p">,</span> <span class="sh">"</span><span class="s">DevOps</span><span class="sh">"</span><span class="p">]</span>
<span class="p">}</span>

<span class="nf">print</span><span class="p">(</span><span class="nf">maksimum_eslesme</span><span class="p">(</span><span class="n">graf</span><span class="p">))</span>
</code></pre></div></div>

<p>Buradaki <code class="language-plaintext highlighter-rouge">ziyaret</code> kümesi, aynı arama sırasında bir işe tekrar gidilmesini önleyerek döngüleri ve gereksiz denemeleri engeller. Her aday için yeni bir küme oluşturulur; çünkü sonraki aday alternatif yolları yeniden değerlendirebilmelidir.</p>

<h2 id="karmaşıklık-ve-doğru-algoritma-seçimi">Karmaşıklık ve doğru algoritma seçimi</h2>

<p>Bu DFS tabanlı çözümün zaman karmaşıklığı yaklaşık olarak</p>

\[O(\vert L\vert  \cdot \vert E\vert )\]

<p>olur. Küçük ve orta ölçekli problemler için anlaşılır ve yeterince hızlıdır.</p>

<table>
  <thead>
    <tr>
      <th>Yöntem</th>
      <th style="text-align: right">Yaklaşık karmaşıklık</th>
      <th>Kullanım alanı</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Kuhn</td>
      <td style="text-align: right">$O(VE)$</td>
      <td>Eğitim, küçük ve orta graflar</td>
    </tr>
    <tr>
      <td>Hopcroft–Karp</td>
      <td style="text-align: right">$O(E\sqrt{V})$</td>
      <td>Büyük iki parçalı graflar</td>
    </tr>
    <tr>
      <td>Macar algoritması</td>
      <td style="text-align: right">$O(n^3)$</td>
      <td>Ağırlıklı, maliyetli atamalar</td>
    </tr>
  </tbody>
</table>

<p>Önemli ayrım şudur: Kuhn algoritması <strong>eşleşen çift sayısını</strong> büyütür; tercih puanlarının toplamını optimize etmez. Her bağlantının puanı veya maliyeti varsa ağırlıklı eşleştirme algoritmaları kullanılmalıdır. Böylece “en fazla kaç çift?” ile “toplamda en iyi çiftler hangileri?” sorularını birbirine karıştırmamış oluruz.</p>]]></content><author><name>Sonsuz Us</name></author><category term="Program" /><category term="graf" /><category term="algoritma" /><category term="python" /><category term="eşleştirme" /><category term="hall-teoremi" /><category term="veri-yapıları" /><summary type="html"><![CDATA[Bir tarafta adaylar, diğer tarafta işler olduğunu düşünün. Her aday yalnızca belirli işleri yapabiliyor ve herkes en fazla bir işle eşleştirilebiliyor. Amaç, mümkün olduğunca çok adayı uygun bir işe yerleştirmek. Romantik adıyla Evlenme Problemi, gerçekte iş dağıtımından üniversite tercih sistemlerine kadar pek çok yerde karşımıza çıkan klasik bir graf problemidir.]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://program.sonsuz.us/img/iki-parcali-graflarda-73.png" /><media:content medium="image" url="https://program.sonsuz.us/img/iki-parcali-graflarda-73.png" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">Klasik Sıralama Algoritmaları Arenada: Kabarcık, Seçmeli, Yerleştirmeli ve Shell</title><link href="https://program.sonsuz.us/posts/klasik-siralama-algoritmalari-arenada-kabarcik-secmeli-yerlestirmeli-ve-shell/" rel="alternate" type="text/html" title="Klasik Sıralama Algoritmaları Arenada: Kabarcık, Seçmeli, Yerleştirmeli ve Shell" /><published>2026-10-12T00:00:00+00:00</published><updated>2026-10-12T00:00:00+00:00</updated><id>https://program.sonsuz.us/posts/klasik-siralama-algoritmalari-arenada-kabarcik-secmeli-yerlestirmeli-ve-shell</id><content type="html" xml:base="https://program.sonsuz.us/posts/klasik-siralama-algoritmalari-arenada-kabarcik-secmeli-yerlestirmeli-ve-shell/"><![CDATA[<p>Bir sayı listesini sıralamak basit görünebilir; ancak kullanılan yöntem, veri büyüdükçe saniyeleri dakikalara dönüştürebilir. Bu yazıda kabarcık, seçmeli, yerleştirmeli ve Shell sıralamasını aynı arenaya çıkarıyor; teorik karmaşıklıklarını, bellek davranışlarını ve farklı veri boyutlarındaki pratik performanslarını karşılaştırıyoruz.
``</p>

<h2 id="önce-temel-kavram-karmaşıklık">Önce temel kavram: Karmaşıklık</h2>

<p>Bir algoritmanın çalışma süresini yalnızca saniyeyle ölçmek yanıltıcıdır; işlemci, programlama dili ve sistem yükü sonucu etkiler. Bu nedenle girdi boyutu $n$ arttığında işlem sayısının nasıl değiştiğini anlatan <strong>asimptotik karmaşıklık</strong> kullanılır.</p>

<p>Örneğin iç içe iki döngü yaklaşık</p>

\[T(n) = \frac{n(n-1)}{2}\]

<p>karşılaştırma yapıyorsa baskın terim $n^2$ olur ve karmaşıklık $O(n^2)$ şeklinde yazılır. Veri miktarını iki katına çıkarmak, çalışma süresini kabaca dört katına çıkarabilir. Küçük listelerde önemsiz görünen bu fark, $n=100.000$ olduğunda algoritmik bir drama dönüşür.</p>

<table>
  <thead>
    <tr>
      <th>Algoritma</th>
      <th style="text-align: right">En iyi</th>
      <th style="text-align: right">Ortalama</th>
      <th style="text-align: right">En kötü</th>
      <th style="text-align: right">Ek bellek</th>
      <th>Kararlı mı?</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Kabarcık</td>
      <td style="text-align: right">$O(n)$</td>
      <td style="text-align: right">$O(n^2)$</td>
      <td style="text-align: right">$O(n^2)$</td>
      <td style="text-align: right">$O(1)$</td>
      <td>Evet</td>
    </tr>
    <tr>
      <td>Seçmeli</td>
      <td style="text-align: right">$O(n^2)$</td>
      <td style="text-align: right">$O(n^2)$</td>
      <td style="text-align: right">$O(n^2)$</td>
      <td style="text-align: right">$O(1)$</td>
      <td>Genellikle hayır</td>
    </tr>
    <tr>
      <td>Yerleştirmeli</td>
      <td style="text-align: right">$O(n)$</td>
      <td style="text-align: right">$O(n^2)$</td>
      <td style="text-align: right">$O(n^2)$</td>
      <td style="text-align: right">$O(1)$</td>
      <td>Evet</td>
    </tr>
    <tr>
      <td>Shell</td>
      <td style="text-align: right">Aralık dizisine bağlı</td>
      <td style="text-align: right">Yaklaşık $O(n^{1.3})$–$O(n^2)$</td>
      <td style="text-align: right">Genellikle $O(n^2)$</td>
      <td style="text-align: right">$O(1)$</td>
      <td>Hayır</td>
    </tr>
  </tbody>
</table>

<p><img src="/img/klasik-siralama-algoritmalari-48.svg" alt="klasik-siralama-algoritmalari-48" /></p>

<h2 id="dört-algoritmanın-çalışma-mantığı">Dört algoritmanın çalışma mantığı</h2>

<p><strong>Kabarcık sıralaması</strong>, komşu elemanları karşılaştırır ve yanlış sıradaysalar yer değiştirir. Büyük değerler her turda listenin sonuna doğru “kabarcık” gibi yükselir. Takas yapılmayan turda durdurulursa sıralı veride $O(n)$ performans gösterebilir; fakat rastgele büyük verilerde çok fazla karşılaştırma ve takas üretir.</p>

<p><strong>Seçmeli sıralama</strong>, her turda sıralanmamış bölümün en küçük elemanını bulup başa taşır. Karşılaştırma sayısı veri zaten sıralı olsa bile pek değişmez. Buna karşılık az takas yapması, yazma maliyetinin yüksek olduğu özel ortamlarda avantaj sağlayabilir.</p>

<p><strong>Yerleştirmeli sıralama</strong>, iskambil kâğıtlarını elde dizerken kullandığımız yönteme benzer. Her yeni elemanı soldaki sıralı bölümde uygun konuma yerleştirir. Neredeyse sıralı verilerde az kaydırma yaptığı için oldukça hızlıdır. Bu nedenle gelişmiş sıralama algoritmalarında küçük alt dizileri işlemek amacıyla sıkça kullanılır.</p>

<p><strong>Shell sıralaması</strong> ise yerleştirmeli sıralamanın sabırsız kuzenidir. Önce birbirinden uzak elemanları belirli aralıklarla sıralar, ardından aralığı küçültür. Son aşamada aralık $1$ olur; fakat liste önceden büyük ölçüde düzenlendiği için işlem hızlanır.</p>

<h2 id="python-ile-karşılaştırmalı-deney">Python ile karşılaştırmalı deney</h2>

<p>Aşağıdaki kod, algoritmaları aynı rastgele verinin kopyaları üzerinde çalıştırır. Böylece bir algoritmanın sıraladığı listenin diğerlerini haksız biçimde avantajlı duruma getirmesi önlenir.</p>

<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kn">import</span> <span class="n">random</span>
<span class="kn">import</span> <span class="n">time</span>

<span class="k">def</span> <span class="nf">insertion_sort</span><span class="p">(</span><span class="n">a</span><span class="p">):</span>
    <span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nf">range</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="nf">len</span><span class="p">(</span><span class="n">a</span><span class="p">)):</span>
        <span class="n">value</span> <span class="o">=</span> <span class="n">a</span><span class="p">[</span><span class="n">i</span><span class="p">]</span>
        <span class="n">j</span> <span class="o">=</span> <span class="n">i</span> <span class="o">-</span> <span class="mi">1</span>
        <span class="k">while</span> <span class="n">j</span> <span class="o">&gt;=</span> <span class="mi">0</span> <span class="ow">and</span> <span class="n">a</span><span class="p">[</span><span class="n">j</span><span class="p">]</span> <span class="o">&gt;</span> <span class="n">value</span><span class="p">:</span>
            <span class="n">a</span><span class="p">[</span><span class="n">j</span> <span class="o">+</span> <span class="mi">1</span><span class="p">]</span> <span class="o">=</span> <span class="n">a</span><span class="p">[</span><span class="n">j</span><span class="p">]</span>
            <span class="n">j</span> <span class="o">-=</span> <span class="mi">1</span>
        <span class="n">a</span><span class="p">[</span><span class="n">j</span> <span class="o">+</span> <span class="mi">1</span><span class="p">]</span> <span class="o">=</span> <span class="n">value</span>
    <span class="k">return</span> <span class="n">a</span>

<span class="k">def</span> <span class="nf">shell_sort</span><span class="p">(</span><span class="n">a</span><span class="p">):</span>
    <span class="n">gap</span> <span class="o">=</span> <span class="nf">len</span><span class="p">(</span><span class="n">a</span><span class="p">)</span> <span class="o">//</span> <span class="mi">2</span>
    <span class="k">while</span> <span class="n">gap</span> <span class="o">&gt;</span> <span class="mi">0</span><span class="p">:</span>
        <span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nf">range</span><span class="p">(</span><span class="n">gap</span><span class="p">,</span> <span class="nf">len</span><span class="p">(</span><span class="n">a</span><span class="p">)):</span>
            <span class="n">value</span><span class="p">,</span> <span class="n">j</span> <span class="o">=</span> <span class="n">a</span><span class="p">[</span><span class="n">i</span><span class="p">],</span> <span class="n">i</span>
            <span class="k">while</span> <span class="n">j</span> <span class="o">&gt;=</span> <span class="n">gap</span> <span class="ow">and</span> <span class="n">a</span><span class="p">[</span><span class="n">j</span> <span class="o">-</span> <span class="n">gap</span><span class="p">]</span> <span class="o">&gt;</span> <span class="n">value</span><span class="p">:</span>
                <span class="n">a</span><span class="p">[</span><span class="n">j</span><span class="p">]</span> <span class="o">=</span> <span class="n">a</span><span class="p">[</span><span class="n">j</span> <span class="o">-</span> <span class="n">gap</span><span class="p">]</span>
                <span class="n">j</span> <span class="o">-=</span> <span class="n">gap</span>
            <span class="n">a</span><span class="p">[</span><span class="n">j</span><span class="p">]</span> <span class="o">=</span> <span class="n">value</span>
        <span class="n">gap</span> <span class="o">//=</span> <span class="mi">2</span>
    <span class="k">return</span> <span class="n">a</span>

<span class="k">for</span> <span class="n">size</span> <span class="ow">in</span> <span class="p">(</span><span class="mi">100</span><span class="p">,</span> <span class="mi">1000</span><span class="p">,</span> <span class="mi">5000</span><span class="p">):</span>
    <span class="n">data</span> <span class="o">=</span> <span class="p">[</span><span class="n">random</span><span class="p">.</span><span class="nf">randint</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="mi">100000</span><span class="p">)</span> <span class="k">for</span> <span class="n">_</span> <span class="ow">in</span> <span class="nf">range</span><span class="p">(</span><span class="n">size</span><span class="p">)]</span>
    <span class="k">for</span> <span class="n">function</span> <span class="ow">in</span> <span class="p">(</span><span class="n">insertion_sort</span><span class="p">,</span> <span class="n">shell_sort</span><span class="p">):</span>
        <span class="n">sample</span> <span class="o">=</span> <span class="n">data</span><span class="p">.</span><span class="nf">copy</span><span class="p">()</span>
        <span class="n">start</span> <span class="o">=</span> <span class="n">time</span><span class="p">.</span><span class="nf">perf_counter</span><span class="p">()</span>
        <span class="nf">function</span><span class="p">(</span><span class="n">sample</span><span class="p">)</span>
        <span class="n">elapsed</span> <span class="o">=</span> <span class="n">time</span><span class="p">.</span><span class="nf">perf_counter</span><span class="p">()</span> <span class="o">-</span> <span class="n">start</span>
        <span class="nf">print</span><span class="p">(</span><span class="n">size</span><span class="p">,</span> <span class="n">function</span><span class="p">.</span><span class="n">__name__</span><span class="p">,</span> <span class="n">elapsed</span><span class="p">)</span>
</code></pre></div></div>

<p><code class="language-plaintext highlighter-rouge">perf_counter()</code> kısa süreleri hassas ölçer; <code class="language-plaintext highlighter-rouge">copy()</code> ise deney adaletini korur. Güvenilir sonuç için her testi birçok kez çalıştırıp ortalama veya medyan almak gerekir.</p>

<table>
  <thead>
    <tr>
      <th>Veri durumu</th>
      <th>Mantıklı tercih</th>
      <th>Neden?</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Çok küçük liste</td>
      <td>Yerleştirmeli</td>
      <td>Düşük ek maliyet</td>
    </tr>
    <tr>
      <td>Neredeyse sıralı</td>
      <td>Yerleştirmeli</td>
      <td>Az sayıda kaydırma</td>
    </tr>
    <tr>
      <td>Orta boy rastgele veri</td>
      <td>Shell</td>
      <td>Uzak elemanları erken düzenler</td>
    </tr>
    <tr>
      <td>Takas sayısı önemli</td>
      <td>Seçmeli</td>
      <td>En fazla yaklaşık $n$ takas</td>
    </tr>
    <tr>
      <td>Eğitim ve görselleştirme</td>
      <td>Kabarcık</td>
      <td>Mantığı son derece açık</td>
    </tr>
  </tbody>
</table>

<h2 id="sonuç">Sonuç</h2>

<p>Kabarcık sıralaması öğretici, seçmeli sıralama az takaslı, yerleştirmeli sıralama küçük veya düzenli veride çevik, Shell sıralaması ise orta ölçekli rastgele veride güçlüdür. Yine de büyük gerçek dünya verilerinde $O(n\log n)$ sınıfındaki hızlı sıralama, birleştirmeli sıralama veya dilin yerleşik sıralama fonksiyonu genellikle daha doğrudur. Kısacası kazanan tek bir algoritma değil; verinin yapısını tanıyıp doğru aracı seçen programcıdır.</p>]]></content><author><name>Sonsuz Us</name></author><category term="Bilgi" /><category term="algoritma" /><category term="sıralama" /><category term="python" /><category term="performans" /><category term="karmaşıklık" /><category term="veri yapıları" /><summary type="html"><![CDATA[Bir sayı listesini sıralamak basit görünebilir; ancak kullanılan yöntem, veri büyüdükçe saniyeleri dakikalara dönüştürebilir. Bu yazıda kabarcık, seçmeli, yerleştirmeli ve Shell sıralamasını aynı arenaya çıkarıyor; teorik karmaşıklıklarını, bellek davranışlarını ve farklı veri boyutlarındaki pratik performanslarını karşılaştırıyoruz.]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://program.sonsuz.us/img/klasik-siralama-algoritmalari-48.png" /><media:content medium="image" url="https://program.sonsuz.us/img/klasik-siralama-algoritmalari-48.png" xmlns:media="http://search.yahoo.com/mrss/" /></entry></feed>