<?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-14T09:37:07+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">A* Arama Algoritması: Sezgilerle En Kısa Yolu Bulmak</title><link href="https://program.sonsuz.us/posts/a-arama-algoritmasi-sezgilerle-en-kisa-yolu-bulmak/" rel="alternate" type="text/html" title="A* Arama Algoritması: Sezgilerle En Kısa Yolu Bulmak" /><published>2026-10-14T00:00:00+00:00</published><updated>2026-10-14T00:00:00+00:00</updated><id>https://program.sonsuz.us/posts/a-arama-algoritmasi-sezgilerle-en-kisa-yolu-bulmak</id><content type="html" xml:base="https://program.sonsuz.us/posts/a-arama-algoritmasi-sezgilerle-en-kisa-yolu-bulmak/"><![CDATA[<p>Bir labirentte çıkışı aradığınızı düşünün. Dijkstra algoritması, hedefin hangi yönde olduğunu önemsemeden çevresindeki yolları sabırla inceler. A* ise aynı işi yaparken hedefe doğru ne kadar yaklaştığını tahmin eden bir pusula kullanır. Bu sezgisel yaklaşım, doğru koşullarda en kısa yolu korurken gereksiz düğümleri ziyaret etmeyi azaltabilir.</p>

<p>``</p>

<h2 id="a-algoritmasının-temel-fikri">A* algoritmasının temel fikri</h2>

<p>A*, ağırlıklı bir graf üzerinde başlangıç düğümünden hedef düğüme giden en düşük maliyetli yolu arar. Her düğüm için üç önemli değer kullanır:</p>

\[f(n) = g(n) + h(n)\]

<ul>
  <li>$g(n)$: Başlangıçtan $n$ düğümüne kadar ödenen gerçek maliyettir.</li>
  <li>$h(n)$: $n$ düğümünden hedefe kalan maliyetin tahminidir.</li>
  <li>$f(n)$: Düğüm üzerinden geçen yolun tahmini toplam maliyetidir.</li>
</ul>

<p>Algoritma, sıradaki adım olarak $f(n)$ değeri en küçük olan düğümü seçer. Başka bir deyişle geçmişte ödediği maliyet ile gelecekte ödeyeceğini düşündüğü maliyeti birlikte değerlendirir.</p>

<table>
  <thead>
    <tr>
      <th>Algoritma</th>
      <th style="text-align: right">Kullanılan değer</th>
      <th>Hedef bilgisi</th>
      <th>Genel davranış</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Dijkstra</td>
      <td style="text-align: right">$g(n)$</td>
      <td>Kullanmaz</td>
      <td>Her yöne dengeli yayılır</td>
    </tr>
    <tr>
      <td>Greedy Best-First</td>
      <td style="text-align: right">$h(n)$</td>
      <td>Kullanır</td>
      <td>Hedefe koşar, en kısa yolu garanti etmeyebilir</td>
    </tr>
    <tr>
      <td>A*</td>
      <td style="text-align: right">$g(n)+h(n)$</td>
      <td>Kullanır</td>
      <td>Maliyet ile yön tahminini dengeler</td>
    </tr>
  </tbody>
</table>

<p><img src="/img/a-arama-algoritmasi-25.svg" alt="a-arama-algoritmasi-25" /></p>

<p>Aslında $h(n)=0$ seçilirse A<em>, Dijkstra algoritmasına dönüşür. Dolayısıyla A</em> için Dijkstra’nın hedef bilgisiyle güçlendirilmiş hâli denebilir.</p>

<h2 id="sezgisel-fonksiyon-nasıl-seçilir">Sezgisel fonksiyon nasıl seçilir?</h2>

<p>Kareli ve dört yönde hareket edilen bir haritada Manhattan uzaklığı kullanılabilir:</p>

\[h(n)=\vert x_n-x_h\vert +\vert y_n-y_h\vert\]

<p>Çapraz hareket mümkünse Öklid uzaklığı daha uygun olabilir. A*‘ın en kısa yolu garanti etmesi için sezgisel fonksiyonun gerçek kalan maliyeti aşmaması gerekir. Bu özelliğe <strong>kabul edilebilirlik</strong> denir. Ayrıca tutarlı bir sezgi için her kenarda şu koşul sağlanır:</p>

\[h(n) \leq c(n,m)+h(m)\]

<p>Tahmin çok küçükse algoritma güvenli fakat Dijkstra’ya yakın çalışır. Tahmin gereğinden büyükse daha hızlı görünebilir, ancak en kısa yol garantisi kaybolabilir.</p>

<h2 id="python-ile-a-uygulaması">Python ile A* uygulaması</h2>

<p>Aşağıdaki kod, sözlük biçiminde tanımlanmış ağırlıklı bir graf üzerinde çalışır. Öncelik kuyruğu, tahmini toplam maliyeti en düşük düğümü verimli biçimde seçer.</p>

<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kn">from</span> <span class="n">heapq</span> <span class="kn">import</span> <span class="n">heappush</span><span class="p">,</span> <span class="n">heappop</span>

<span class="k">def</span> <span class="nf">a_star</span><span class="p">(</span><span class="n">graph</span><span class="p">,</span> <span class="n">start</span><span class="p">,</span> <span class="n">goal</span><span class="p">,</span> <span class="n">heuristic</span><span class="p">):</span>
    <span class="c1"># Kuyruk elemanları: (f maliyeti, düğüm)
</span>    <span class="n">open_set</span> <span class="o">=</span> <span class="p">[(</span><span class="nf">heuristic</span><span class="p">(</span><span class="n">start</span><span class="p">,</span> <span class="n">goal</span><span class="p">),</span> <span class="n">start</span><span class="p">)]</span>
    <span class="n">came_from</span> <span class="o">=</span> <span class="p">{}</span>
    <span class="n">g_score</span> <span class="o">=</span> <span class="p">{</span><span class="n">start</span><span class="p">:</span> <span class="mi">0</span><span class="p">}</span>
    <span class="n">visited</span> <span class="o">=</span> <span class="nf">set</span><span class="p">()</span>

    <span class="k">while</span> <span class="n">open_set</span><span class="p">:</span>
        <span class="n">_</span><span class="p">,</span> <span class="n">current</span> <span class="o">=</span> <span class="nf">heappop</span><span class="p">(</span><span class="n">open_set</span><span class="p">)</span>

        <span class="k">if</span> <span class="n">current</span> <span class="ow">in</span> <span class="n">visited</span><span class="p">:</span>
            <span class="k">continue</span>
        <span class="k">if</span> <span class="n">current</span> <span class="o">==</span> <span class="n">goal</span><span class="p">:</span>
            <span class="n">path</span> <span class="o">=</span> <span class="p">[</span><span class="n">current</span><span class="p">]</span>
            <span class="k">while</span> <span class="n">current</span> <span class="ow">in</span> <span class="n">came_from</span><span class="p">:</span>
                <span class="n">current</span> <span class="o">=</span> <span class="n">came_from</span><span class="p">[</span><span class="n">current</span><span class="p">]</span>
                <span class="n">path</span><span class="p">.</span><span class="nf">append</span><span class="p">(</span><span class="n">current</span><span class="p">)</span>
            <span class="k">return</span> <span class="n">path</span><span class="p">[::</span><span class="o">-</span><span class="mi">1</span><span class="p">],</span> <span class="n">g_score</span><span class="p">[</span><span class="n">goal</span><span class="p">]</span>

        <span class="n">visited</span><span class="p">.</span><span class="nf">add</span><span class="p">(</span><span class="n">current</span><span class="p">)</span>

        <span class="k">for</span> <span class="n">neighbor</span><span class="p">,</span> <span class="n">edge_cost</span> <span class="ow">in</span> <span class="n">graph</span><span class="p">[</span><span class="n">current</span><span class="p">]:</span>
            <span class="n">tentative</span> <span class="o">=</span> <span class="n">g_score</span><span class="p">[</span><span class="n">current</span><span class="p">]</span> <span class="o">+</span> <span class="n">edge_cost</span>

            <span class="k">if</span> <span class="n">tentative</span> <span class="o">&lt;</span> <span class="n">g_score</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="nf">float</span><span class="p">(</span><span class="sh">"</span><span class="s">inf</span><span class="sh">"</span><span class="p">)):</span>
                <span class="n">came_from</span><span class="p">[</span><span class="n">neighbor</span><span class="p">]</span> <span class="o">=</span> <span class="n">current</span>
                <span class="n">g_score</span><span class="p">[</span><span class="n">neighbor</span><span class="p">]</span> <span class="o">=</span> <span class="n">tentative</span>
                <span class="n">f_score</span> <span class="o">=</span> <span class="n">tentative</span> <span class="o">+</span> <span class="nf">heuristic</span><span class="p">(</span><span class="n">neighbor</span><span class="p">,</span> <span class="n">goal</span><span class="p">)</span>
                <span class="nf">heappush</span><span class="p">(</span><span class="n">open_set</span><span class="p">,</span> <span class="p">(</span><span class="n">f_score</span><span class="p">,</span> <span class="n">neighbor</span><span class="p">))</span>

    <span class="k">return</span> <span class="bp">None</span><span class="p">,</span> <span class="nf">float</span><span class="p">(</span><span class="sh">"</span><span class="s">inf</span><span class="sh">"</span><span class="p">)</span>
</code></pre></div></div>

<p>Örnek olarak düğümlerin koordinatlarını ve bağlantılarını tanımlayabiliriz:</p>

<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><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="mi">2</span><span class="p">),</span> <span class="p">(</span><span class="sh">"</span><span class="s">C</span><span class="sh">"</span><span class="p">,</span> <span class="mi">4</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="mi">2</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="mi">3</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="mi">4</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="mi">1</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="mi">3</span><span class="p">),</span> <span class="p">(</span><span class="sh">"</span><span class="s">C</span><span class="sh">"</span><span class="p">,</span> <span class="mi">1</span><span class="p">),</span> <span class="p">(</span><span class="sh">"</span><span class="s">E</span><span class="sh">"</span><span class="p">,</span> <span class="mi">2</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="p">}</span>

<span class="n">coords</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="mi">0</span><span class="p">,</span> <span class="mi">0</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="mi">1</span><span class="p">,</span> <span class="mi">0</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="mi">0</span><span class="p">,</span> <span class="mi">1</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="mi">1</span><span class="p">,</span> <span class="mi">1</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="mi">2</span><span class="p">,</span> <span class="mi">1</span><span class="p">)</span>
<span class="p">}</span>

<span class="k">def</span> <span class="nf">manhattan</span><span class="p">(</span><span class="n">a</span><span class="p">,</span> <span class="n">b</span><span class="p">):</span>
    <span class="n">x1</span><span class="p">,</span> <span class="n">y1</span> <span class="o">=</span> <span class="n">coords</span><span class="p">[</span><span class="n">a</span><span class="p">]</span>
    <span class="n">x2</span><span class="p">,</span> <span class="n">y2</span> <span class="o">=</span> <span class="n">coords</span><span class="p">[</span><span class="n">b</span><span class="p">]</span>
    <span class="k">return</span> <span class="nf">abs</span><span class="p">(</span><span class="n">x1</span> <span class="o">-</span> <span class="n">x2</span><span class="p">)</span> <span class="o">+</span> <span class="nf">abs</span><span class="p">(</span><span class="n">y1</span> <span class="o">-</span> <span class="n">y2</span><span class="p">)</span>

<span class="n">path</span><span class="p">,</span> <span class="n">cost</span> <span class="o">=</span> <span class="nf">a_star</span><span class="p">(</span><span class="n">graph</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">E</span><span class="sh">"</span><span class="p">,</span> <span class="n">manhattan</span><span class="p">)</span>
<span class="nf">print</span><span class="p">(</span><span class="n">path</span><span class="p">,</span> <span class="n">cost</span><span class="p">)</span>
</code></pre></div></div>

<p>Bu uygulama yolu <code class="language-plaintext highlighter-rouge">A, B, D, E</code> veya aynı maliyetli uygun bir alternatif olarak döndürebilir. A* özellikle oyun haritaları, robot navigasyonu ve rota planlama sistemlerinde güçlüdür. Yine de hız avantajı otomatik değildir: kötü bir sezgisel fonksiyon, büyük bellek tüketimi veya düzensiz graf yapısı performansı azaltabilir. İyi bir $h(n)$ seçimi ise A*‘ın gerçek süper gücüdür.</p>]]></content><author><name>Sonsuz Us</name></author><category term="Program" /><category term="a-star" /><category term="arama-algoritmaları" /><category term="python" /><category term="yapay-zeka" /><category term="graf-teorisi" /><category term="algoritma" /><summary type="html"><![CDATA[Bir labirentte çıkışı aradığınızı düşünün. Dijkstra algoritması, hedefin hangi yönde olduğunu önemsemeden çevresindeki yolları sabırla inceler. A* ise aynı işi yaparken hedefe doğru ne kadar yaklaştığını tahmin eden bir pusula kullanır. Bu sezgisel yaklaşım, doğru koşullarda en kısa yolu korurken gereksiz düğümleri ziyaret etmeyi azaltabilir.]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://program.sonsuz.us/img/a-arama-algoritmasi-25.png" /><media:content medium="image" url="https://program.sonsuz.us/img/a-arama-algoritmasi-25.png" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">Amortize Analiz: Pahalı İşlemleri Uzun Vadede Ucuzlatmak</title><link href="https://program.sonsuz.us/posts/amortize-analiz-pahali-islemleri-uzun-vadede-ucuzlatmak/" rel="alternate" type="text/html" title="Amortize Analiz: Pahalı İşlemleri Uzun Vadede Ucuzlatmak" /><published>2026-10-14T00:00:00+00:00</published><updated>2026-10-14T00:00:00+00:00</updated><id>https://program.sonsuz.us/posts/amortize-analiz-pahali-islemleri-uzun-vadede-ucuzlatmak</id><content type="html" xml:base="https://program.sonsuz.us/posts/amortize-analiz-pahali-islemleri-uzun-vadede-ucuzlatmak/"><![CDATA[<p>Bir algoritmadaki tek bir işlemin pahalı olması, algoritmanın genel olarak verimsiz olduğu anlamına gelmez. Bazen nadiren gerçekleşen maliyetli işlemler, çok sayıdaki ucuz işlem arasında kaybolur. Amortize analiz, tam da bu tabloya bakarak bir işlem dizisinin uzun vadeli ortalama maliyetini hesaplamamızı sağlar.</p>

<p>``</p>

<h2 id="amortize-analiz-nedir">Amortize analiz nedir?</h2>

<p>Amortize analiz, bir işlemin olasılıksal ortalamasını değil, <strong>en kötü durumda oluşabilecek işlem dizisinin ortalama maliyetini</strong> inceler. Bu nedenle ortalama durum analizinden farklıdır: Kullanıcı davranışı veya rastgele veri dağılımı hakkında varsayım yapmaz.</p>

<p>$n$ işlemden oluşan bir dizinin toplam maliyeti $T(n)$ ise işlem başına amortize maliyet şöyle hesaplanır:</p>

\[A(n) = \frac{T(n)}{n}\]

<p>Örneğin toplam maliyet $T(n)=3n+10$ ise amortize maliyet:</p>

\[A(n)=\frac{3n+10}{n}=3+\frac{10}{n}=O(1)\]

<p>Burada bazı işlemler tek başına pahalı olsa bile uzun vadede her işlem sabit maliyetli kabul edilebilir.</p>

<table>
  <thead>
    <tr>
      <th>Analiz türü</th>
      <th>İncelenen durum</th>
      <th style="text-align: right">Varsayım gerekir mi?</th>
      <th style="text-align: right">Sonuç örneği</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>En iyi durum</td>
      <td>En avantajlı girdi</td>
      <td style="text-align: right">Hayır</td>
      <td style="text-align: right">$\Omega(1)$</td>
    </tr>
    <tr>
      <td>En kötü durum</td>
      <td>En maliyetli tek işlem</td>
      <td style="text-align: right">Hayır</td>
      <td style="text-align: right">$O(n)$</td>
    </tr>
    <tr>
      <td>Ortalama durum</td>
      <td>Olası girdilerin ortalaması</td>
      <td style="text-align: right">Evet</td>
      <td style="text-align: right">Beklenen maliyet</td>
    </tr>
    <tr>
      <td>Amortize analiz</td>
      <td>En kötü işlem dizisinin ortalaması</td>
      <td style="text-align: right">Hayır</td>
      <td style="text-align: right">İşlem başına $O(1)$</td>
    </tr>
  </tbody>
</table>

<h2 id="klasik-örnek-dinamik-dizi">Klasik örnek: Dinamik dizi</h2>

<p>Dinamik bir dizinin kapasitesi dolduğunda daha büyük bir alan ayrılır ve eski elemanlar yeni alana kopyalanır. Normal bir ekleme $O(1)$ sürerken yeniden boyutlandırma işlemi $O(n)$ maliyetli olabilir.</p>

<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">class</span> <span class="nc">DynamicArray</span><span class="p">:</span>
    <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="n">self</span><span class="p">):</span>
        <span class="n">self</span><span class="p">.</span><span class="n">capacity</span> <span class="o">=</span> <span class="mi">1</span>
        <span class="n">self</span><span class="p">.</span><span class="n">size</span> <span class="o">=</span> <span class="mi">0</span>
        <span class="n">self</span><span class="p">.</span><span class="n">data</span> <span class="o">=</span> <span class="p">[</span><span class="bp">None</span><span class="p">]</span> <span class="o">*</span> <span class="n">self</span><span class="p">.</span><span class="n">capacity</span>

    <span class="k">def</span> <span class="nf">append</span><span class="p">(</span><span class="n">self</span><span class="p">,</span> <span class="n">value</span><span class="p">):</span>
        <span class="k">if</span> <span class="n">self</span><span class="p">.</span><span class="n">size</span> <span class="o">==</span> <span class="n">self</span><span class="p">.</span><span class="n">capacity</span><span class="p">:</span>
            <span class="n">self</span><span class="p">.</span><span class="nf">_resize</span><span class="p">()</span>

        <span class="n">self</span><span class="p">.</span><span class="n">data</span><span class="p">[</span><span class="n">self</span><span class="p">.</span><span class="n">size</span><span class="p">]</span> <span class="o">=</span> <span class="n">value</span>
        <span class="n">self</span><span class="p">.</span><span class="n">size</span> <span class="o">+=</span> <span class="mi">1</span>

    <span class="k">def</span> <span class="nf">_resize</span><span class="p">(</span><span class="n">self</span><span class="p">):</span>
        <span class="n">self</span><span class="p">.</span><span class="n">capacity</span> <span class="o">*=</span> <span class="mi">2</span>
        <span class="n">new_data</span> <span class="o">=</span> <span class="p">[</span><span class="bp">None</span><span class="p">]</span> <span class="o">*</span> <span class="n">self</span><span class="p">.</span><span class="n">capacity</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">self</span><span class="p">.</span><span class="n">size</span><span class="p">):</span>
            <span class="n">new_data</span><span class="p">[</span><span class="n">i</span><span class="p">]</span> <span class="o">=</span> <span class="n">self</span><span class="p">.</span><span class="n">data</span><span class="p">[</span><span class="n">i</span><span class="p">]</span>

        <span class="n">self</span><span class="p">.</span><span class="n">data</span> <span class="o">=</span> <span class="n">new_data</span>
</code></pre></div></div>

<p>Bu kodda <code class="language-plaintext highlighter-rouge">_resize</code>, mevcut elemanları kopyalayarak kapasiteyi iki katına çıkarır. Boyutlandırmalar $1,2,4,8,\ldots$ elemanda gerçekleşir. $n$ ekleme boyunca yapılan toplam kopyalama sayısı:</p>

\[1+2+4+\cdots+\frac{n}{2}&lt;n\]

<p>Normal eklemelerin maliyeti de $n$ olduğundan toplam maliyet $2n$ civarındadır. Böylece işlem başına maliyet:</p>

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

<p>Tek bir ekleme $O(n)$ sürebilir; ancak <code class="language-plaintext highlighter-rouge">append</code> işleminin amortize maliyeti $O(1)$ olur. Pahalı taşınma masrafı, önceki ucuz eklemelere dağıtılmıştır.</p>

<h2 id="üç-temel-amortize-analiz-yöntemi">Üç temel amortize analiz yöntemi</h2>

<h3 id="1-toplam-maliyet-yöntemi">1. Toplam maliyet yöntemi</h3>

<p>Tüm işlem dizisinin gerçek maliyeti hesaplanır ve işlem sayısına bölünür. Dinamik dizi örneğinde kullandığımız yaklaşım budur.</p>

<h3 id="2-muhasebe-yöntemi">2. Muhasebe yöntemi</h3>

<p>Ucuz işlemlerden gerçek maliyetlerinden biraz daha fazla ücret alınır. Aradaki kredi, gelecekteki pahalı işlemleri karşılamak üzere saklanır. Bir eklemenin gerçek maliyeti $1$ olsa da ona $3$ kredi biçtiğimizi düşünebiliriz. Fazladan kalan krediler yeniden boyutlandırmayı öder; algoritma adeta kendi kumbarasını taşır.</p>

<h3 id="3-potansiyel-yöntemi">3. Potansiyel yöntemi</h3>

<p>Veri yapısında biriken gelecekteki işi matematiksel bir potansiyel fonksiyonuyla gösteririz. Amortize maliyet:</p>

\[\hat{c_i}=c_i+\Phi(D_i)-\Phi(D_{i-1})\]

<p>Burada $c_i$ gerçek maliyet, $\Phi(D_i)$ ise işlemden sonraki potansiyeldir. Potansiyel artıyorsa geleceğe kredi bırakılır; azalıyorsa biriktirilen kredi pahalı işlemi karşılar.</p>

<table>
  <thead>
    <tr>
      <th>Yöntem</th>
      <th>Temel fikir</th>
      <th>Kullanışlı olduğu durum</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Toplam</td>
      <td>Bütün maliyeti işlemlere böl</td>
      <td>Düzenli işlem dizileri</td>
    </tr>
    <tr>
      <td>Muhasebe</td>
      <td>Fazla ücretle kredi biriktir</td>
      <td>Sezgisel açıklamalar</td>
    </tr>
    <tr>
      <td>Potansiyel</td>
      <td>Veri yapısındaki enerjiyi ölç</td>
      <td>Karmaşık yapılar ve ispatlar</td>
    </tr>
  </tbody>
</table>

<p>Amortize analiz, tek bir kötü ana bakıp paniğe kapılmak yerine filmin tamamını izler. Dinamik diziler, hash tabloları, yığıt işlemleri ve birleşim-bulma yapıları bu yöntemle daha doğru değerlendirilir. Kısacası soru yalnızca “Bu işlem ne kadar pahalı?” değil, “Bu maliyet uzun bir yolculuk boyunca kaç işleme paylaşılıyor?” olmalıdır.</p>

<p><img src="/img/amortize-analiz-pahali-93.svg" alt="amortize-analiz-pahali-93" /></p>]]></content><author><name>Sonsuz Us</name></author><category term="Bilgi" /><category term="amortize analiz" /><category term="algoritma" /><category term="veri yapıları" /><category term="zaman karmaşıklığı" /><category term="dinamik dizi" /><summary type="html"><![CDATA[Bir algoritmadaki tek bir işlemin pahalı olması, algoritmanın genel olarak verimsiz olduğu anlamına gelmez. Bazen nadiren gerçekleşen maliyetli işlemler, çok sayıdaki ucuz işlem arasında kaybolur. Amortize analiz, tam da bu tabloya bakarak bir işlem dizisinin uzun vadeli ortalama maliyetini hesaplamamızı sağlar.]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://program.sonsuz.us/img/amortize-analiz-pahali-93.png" /><media:content medium="image" url="https://program.sonsuz.us/img/amortize-analiz-pahali-93.png" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">Aynı Seçim, Farklı Kazanan: Borda ve Condorcet Yöntemleri</title><link href="https://program.sonsuz.us/posts/ayni-secim-farkli-kazanan-borda-ve-condorcet-yontemleri/" rel="alternate" type="text/html" title="Aynı Seçim, Farklı Kazanan: Borda ve Condorcet Yöntemleri" /><published>2026-10-14T00:00:00+00:00</published><updated>2026-10-14T00:00:00+00:00</updated><id>https://program.sonsuz.us/posts/ayni-secim-farkli-kazanan-borda-ve-condorcet-yontemleri</id><content type="html" xml:base="https://program.sonsuz.us/posts/ayni-secim-farkli-kazanan-borda-ve-condorcet-yontemleri/"><![CDATA[<p>Bir seçimde en çok oyu alan adayın kazanacağını düşünmek doğaldır. Ancak seçmenler yalnızca tek aday belirtmek yerine adayları tercih sırasına koyduğunda işler değişir. Oyları nasıl puanladığımız veya adayları nasıl karşılaştırdığımız, aynı tercihlerden farklı kazananlar çıkarabilir. Borda ve Condorcet yöntemleri, bu şaşırtıcı durumun en güzel örneklerindendir.</p>

<p>``</p>

<h2 id="tercihli-oylamanın-temel-fikri">Tercihli oylamanın temel fikri</h2>

<p>Üç adayımız olsun: Ada, Bora ve Ceren. Seçmenlerden adayları en beğendiklerinden en az beğendiklerine doğru sıralamalarını isteyelim. Sonuçlar şöyle olsun:</p>

<table>
  <thead>
    <tr>
      <th style="text-align: right">Seçmen sayısı</th>
      <th>1. tercih</th>
      <th>2. tercih</th>
      <th>3. tercih</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td style="text-align: right">4</td>
      <td>Ada</td>
      <td>Bora</td>
      <td>Ceren</td>
    </tr>
    <tr>
      <td style="text-align: right">3</td>
      <td>Bora</td>
      <td>Ceren</td>
      <td>Ada</td>
    </tr>
    <tr>
      <td style="text-align: right">2</td>
      <td>Ceren</td>
      <td>Bora</td>
      <td>Ada</td>
    </tr>
  </tbody>
</table>

<p><img src="/img/ayni-secim-farkli-60.svg" alt="ayni-secim-farkli-60" /></p>

<p>Burada yalnızca birinci tercihlere bakarsak Ada 4, Bora 3, Ceren 2 oy alır. Basit çoğulluk yöntemi Ada’yı kazanan ilan eder. Fakat sıralamanın geri kalanını da hesaba katarsak sonuç değişebilir.</p>

<h2 id="borda-sayımı-her-sıraya-puan">Borda sayımı: Her sıraya puan</h2>

<p>Borda yönteminde adaylar bulundukları sıraya göre puan kazanır. $m$ aday varsa birinci sıraya $m-1$, ikinci sıraya $m-2$ ve son sıraya $0$ puan verilebilir. Üç aday için puanlar sırasıyla $2$, $1$ ve $0$ olur.</p>

<p>Bir adayın toplam Borda puanı şu şekilde ifade edilir:</p>

\[B(a)=\sum_{i=1}^{n} p_i(a)\]

<p>Burada $p_i(a)$, $i$ numaralı seçmenin $a$ adayına verdiği sıra puanıdır. Örneğimizde puanlar şöyledir:</p>

<table>
  <thead>
    <tr>
      <th>Aday</th>
      <th>Puan hesabı</th>
      <th style="text-align: right">Toplam</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Ada</td>
      <td>$4\times2+3\times0+2\times0$</td>
      <td style="text-align: right">8</td>
    </tr>
    <tr>
      <td>Bora</td>
      <td>$4\times1+3\times2+2\times1$</td>
      <td style="text-align: right">12</td>
    </tr>
    <tr>
      <td>Ceren</td>
      <td>$4\times0+3\times1+2\times2$</td>
      <td style="text-align: right">7</td>
    </tr>
  </tbody>
</table>

<p>Borda kazananı Bora’dır. Ada daha fazla seçmenin ilk tercihi olmasına rağmen birçok seçmen tarafından son sıraya konmuştur. Bora ise geniş bir uzlaşma sağlamıştır. Borda, güçlü sevgiyi ödüllendirirken genel kabulü de önemser.</p>

<h2 id="condorcet-bire-bir-düello">Condorcet: Bire bir düello</h2>

<p>Condorcet yaklaşımı puan toplamak yerine adayları ikili karşılaştırır. Bir aday, diğer bütün adayları bire bir seçimlerde yeniyorsa <strong>Condorcet kazananı</strong> olur.</p>

<p>Örneğin Bora ile Ada karşılaştırıldığında ilk gruptaki 4 seçmen Ada’yı, diğer 5 seçmen Bora’yı üstün tutar. Bora, Ada’yı $5$–$4$ yener. Bora ile Ceren karşılaşmasında ise ilk iki grup, yani 7 seçmen Bora’yı Ceren’in önüne koyar. Böylece Bora yine kazanır ve Condorcet kazananı olur.</p>

<table>
  <thead>
    <tr>
      <th>Yöntem</th>
      <th>Neye odaklanır?</th>
      <th>Bu örnekte kazanan</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Basit çoğulluk</td>
      <td>Birinci tercihler</td>
      <td>Ada</td>
    </tr>
    <tr>
      <td>Borda</td>
      <td>Tüm sıraların puanı</td>
      <td>Bora</td>
    </tr>
    <tr>
      <td>Condorcet</td>
      <td>İkili karşılaşmalar</td>
      <td>Bora</td>
    </tr>
  </tbody>
</table>

<p>Borda ve Condorcet her zaman aynı sonucu vermez. Ayrıca Condorcet kazananı bulunmayabilir: Ada Bora’yı, Bora Ceren’i, Ceren de Ada’yı yenebilir. Bu duruma <strong>Condorcet döngüsü</strong> denir; tercihler taş-kâğıt-makas oyununa dönüşür.</p>

<h2 id="küçük-bir-python-uygulaması">Küçük bir Python uygulaması</h2>

<p>Aşağıdaki kod, sıralı oyların Borda puanlarını hesaplar:</p>

<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kn">from</span> <span class="n">collections</span> <span class="kn">import</span> <span class="n">defaultdict</span>

<span class="n">oylar</span> <span class="o">=</span> <span class="p">[</span>
    <span class="p">(</span><span class="mi">4</span><span class="p">,</span> <span class="p">[</span><span class="sh">"</span><span class="s">Ada</span><span class="sh">"</span><span class="p">,</span> <span class="sh">"</span><span class="s">Bora</span><span class="sh">"</span><span class="p">,</span> <span class="sh">"</span><span class="s">Ceren</span><span class="sh">"</span><span class="p">]),</span>
    <span class="p">(</span><span class="mi">3</span><span class="p">,</span> <span class="p">[</span><span class="sh">"</span><span class="s">Bora</span><span class="sh">"</span><span class="p">,</span> <span class="sh">"</span><span class="s">Ceren</span><span class="sh">"</span><span class="p">,</span> <span class="sh">"</span><span class="s">Ada</span><span class="sh">"</span><span class="p">]),</span>
    <span class="p">(</span><span class="mi">2</span><span class="p">,</span> <span class="p">[</span><span class="sh">"</span><span class="s">Ceren</span><span class="sh">"</span><span class="p">,</span> <span class="sh">"</span><span class="s">Bora</span><span class="sh">"</span><span class="p">,</span> <span class="sh">"</span><span class="s">Ada</span><span class="sh">"</span><span class="p">]),</span>
<span class="p">]</span>

<span class="n">puanlar</span> <span class="o">=</span> <span class="nf">defaultdict</span><span class="p">(</span><span class="nb">int</span><span class="p">)</span>
<span class="n">aday_sayisi</span> <span class="o">=</span> <span class="nf">len</span><span class="p">(</span><span class="n">oylar</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="k">for</span> <span class="n">secmen</span><span class="p">,</span> <span class="n">siralama</span> <span class="ow">in</span> <span class="n">oylar</span><span class="p">:</span>
    <span class="k">for</span> <span class="n">sira</span><span class="p">,</span> <span class="n">aday</span> <span class="ow">in</span> <span class="nf">enumerate</span><span class="p">(</span><span class="n">siralama</span><span class="p">):</span>
        <span class="n">puanlar</span><span class="p">[</span><span class="n">aday</span><span class="p">]</span> <span class="o">+=</span> <span class="n">secmen</span> <span class="o">*</span> <span class="p">(</span><span class="n">aday_sayisi</span> <span class="o">-</span> <span class="n">sira</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">dict</span><span class="p">(</span><span class="n">puanlar</span><span class="p">))</span>
<span class="nf">print</span><span class="p">(</span><span class="sh">"</span><span class="s">Kazanan:</span><span class="sh">"</span><span class="p">,</span> <span class="nf">max</span><span class="p">(</span><span class="n">puanlar</span><span class="p">,</span> <span class="n">key</span><span class="o">=</span><span class="n">puanlar</span><span class="p">.</span><span class="n">get</span><span class="p">))</span>
</code></pre></div></div>

<p>Döngü, her adayın sıra puanını o tercihi paylaşan seçmen sayısıyla çarpar. Çıktıda Bora 12 puanla kazanır.</p>

<p>Sonuç olarak seçim yöntemi tarafsız bir ayrıntı değil, sonucun parçasıdır. Basit çoğulluk güçlü birinci tercihleri, Borda genel memnuniyeti, Condorcet ise bire bir üstünlüğü ölçer. Bu nedenle “Kim kazandı?” sorusundan önce “Oyları hangi kuralla saydık?” diye sormak gerekir.</p>]]></content><author><name>Sonsuz Us</name></author><category term="Bilgi" /><category term="oylama" /><category term="borda" /><category term="condorcet" /><category term="sosyal-seçim" /><category term="algoritma" /><category term="matematik" /><summary type="html"><![CDATA[Bir seçimde en çok oyu alan adayın kazanacağını düşünmek doğaldır. Ancak seçmenler yalnızca tek aday belirtmek yerine adayları tercih sırasına koyduğunda işler değişir. Oyları nasıl puanladığımız veya adayları nasıl karşılaştırdığımız, aynı tercihlerden farklı kazananlar çıkarabilir. Borda ve Condorcet yöntemleri, bu şaşırtıcı durumun en güzel örneklerindendir.]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://program.sonsuz.us/img/ayni-secim-farkli-60.png" /><media:content medium="image" url="https://program.sonsuz.us/img/ayni-secim-farkli-60.png" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">Josephus Problemi: Dairede Kim, Ne Zaman Elenecek?</title><link href="https://program.sonsuz.us/posts/josephus-problemi-dairede-kim-ne-zaman-elenecek/" rel="alternate" type="text/html" title="Josephus Problemi: Dairede Kim, Ne Zaman Elenecek?" /><published>2026-10-14T00:00:00+00:00</published><updated>2026-10-14T00:00:00+00:00</updated><id>https://program.sonsuz.us/posts/josephus-problemi-dairede-kim-ne-zaman-elenecek</id><content type="html" xml:base="https://program.sonsuz.us/posts/josephus-problemi-dairede-kim-ne-zaman-elenecek/"><![CDATA[<p>Bir grup insanın daire şeklinde dizildiğini, belirli aralıklarla bir kişinin elendiğini ve bu işlemin yalnızca tek kişi kalana kadar sürdüğünü düşünün. Kulağa biraz acımasız bir sandalye kapmaca oyunu gibi gelen <strong>Josephus Problemi</strong>, döngüsel yapıları, indeks hesaplarını ve algoritmik düşünmeyi öğrenmek için kullanılan klasik bir bilgisayar bilimi problemidir.</p>

<p><img src="/img/josephus-problemi-dairede-42.svg" alt="josephus-problemi-dairede-42" /></p>

<p>``</p>

<h2 id="problemin-kuralları">Problemin kuralları</h2>

<p>Dairede $n$ kişi bulunsun. Saymaya birinci kişiden başlayalım ve her $k$ adımda ulaşılan kişiyi eleyelim. Elenen kişinin hemen yanındaki kişiyle saymaya yeniden devam edelim. Amaç iki farklı sonucu hesaplamak olabilir:</p>

<ol>
  <li>Kişilerin elenme sırası,</li>
  <li>Oyunda hayatta kalan son kişi.</li>
</ol>

<p>Örneğin $n=7$ ve $k=3$ olsun. Kişiler <code class="language-plaintext highlighter-rouge">1, 2, 3, 4, 5, 6, 7</code> biçiminde numaralandırılır. İlk elenen kişi 3, sonraki kişi 6 olur. Dairenin sonuna gelindiğinde sayma başa döner.</p>

<table>
  <thead>
    <tr>
      <th style="text-align: right">Tur</th>
      <th>Dairede kalanlar</th>
      <th style="text-align: right">Elenen kişi</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td style="text-align: right">1</td>
      <td>1, 2, 4, 5, 6, 7</td>
      <td style="text-align: right">3</td>
    </tr>
    <tr>
      <td style="text-align: right">2</td>
      <td>1, 2, 4, 5, 7</td>
      <td style="text-align: right">6</td>
    </tr>
    <tr>
      <td style="text-align: right">3</td>
      <td>1, 2, 4, 5</td>
      <td style="text-align: right">2</td>
    </tr>
    <tr>
      <td style="text-align: right">4</td>
      <td>1, 4, 5</td>
      <td style="text-align: right">7</td>
    </tr>
    <tr>
      <td style="text-align: right">5</td>
      <td>1, 4</td>
      <td style="text-align: right">5</td>
    </tr>
    <tr>
      <td style="text-align: right">6</td>
      <td>4</td>
      <td style="text-align: right">1</td>
    </tr>
  </tbody>
</table>

<p>Böylece elenme sırası $[3,6,2,7,5,1]$, kazanan ise 4 olur.</p>

<h2 id="matematiksel-düşünce">Matematiksel düşünce</h2>

<p>Yalnızca kazananı arıyorsak problemi daha küçük problemlere indirebiliriz. Sıfır tabanlı indeks kullanan Josephus bağıntısı şöyledir:</p>

\[J(1,k)=0\]

\[J(n,k)=(J(n-1,k)+k) \bmod n\]

<p>Buradaki mod işlemi, dairenin sonundan sonra tekrar başa dönmemizi sağlar. İnsanları 1’den başlayarak numaralandırmak istediğimiz için nihai sonuca 1 ekleriz:</p>

\[\text{kazanan}=J(n,k)+1\]

<p>Bu yaklaşım $O(n)$ zamanda ve $O(1)$ ek bellekte çalışır. Ancak yalnızca kazananı verir; bütün elenme sırasını öğrenmek için daireyi ayrıca simüle etmeliyiz.</p>

<table>
  <thead>
    <tr>
      <th>Yaklaşım</th>
      <th>Ürettiği sonuç</th>
      <th style="text-align: right">Zaman</th>
      <th style="text-align: right">Ek bellek</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Matematiksel bağıntı</td>
      <td>Son kalan kişi</td>
      <td style="text-align: right">$O(n)$</td>
      <td style="text-align: right">$O(1)$</td>
    </tr>
    <tr>
      <td>Kuyruk simülasyonu</td>
      <td>Tüm elenme sırası</td>
      <td style="text-align: right">Uygulamaya bağlı</td>
      <td style="text-align: right">$O(n)$</td>
    </tr>
  </tbody>
</table>

<h2 id="python-ile-daireyi-simüle-etmek">Python ile daireyi simüle etmek</h2>

<p>Python’daki <code class="language-plaintext highlighter-rouge">deque</code>, iki uçtan hızlı ekleme ve çıkarma yapabilen bir kuyruktur. <code class="language-plaintext highlighter-rouge">rotate</code> metodu sayesinde sıradaki kişiyi kuyruğun başına taşıyabiliriz.</p>

<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kn">from</span> <span class="n">collections</span> <span class="kn">import</span> <span class="n">deque</span>


<span class="k">def</span> <span class="nf">josephus_sirasi</span><span class="p">(</span><span class="n">kisi_sayisi</span><span class="p">,</span> <span class="n">adim</span><span class="p">):</span>
    <span class="k">if</span> <span class="n">kisi_sayisi</span> <span class="o">&lt;</span> <span class="mi">1</span> <span class="ow">or</span> <span class="n">adim</span> <span class="o">&lt;</span> <span class="mi">1</span><span class="p">:</span>
        <span class="k">raise</span> <span class="nc">ValueError</span><span class="p">(</span><span class="sh">"</span><span class="s">Kişi sayısı ve adım pozitif olmalıdır.</span><span class="sh">"</span><span class="p">)</span>

    <span class="n">daire</span> <span class="o">=</span> <span class="nf">deque</span><span class="p">(</span><span class="nf">range</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="n">kisi_sayisi</span> <span class="o">+</span> <span class="mi">1</span><span class="p">))</span>
    <span class="n">elenenler</span> <span class="o">=</span> <span class="p">[]</span>

    <span class="k">while</span> <span class="nf">len</span><span class="p">(</span><span class="n">daire</span><span class="p">)</span> <span class="o">&gt;</span> <span class="mi">1</span><span class="p">:</span>
        <span class="c1"># İlk kişi zaten birinci sayıldığı için k-1 konum ilerliyoruz.
</span>        <span class="n">daire</span><span class="p">.</span><span class="nf">rotate</span><span class="p">(</span><span class="o">-</span><span class="p">(</span><span class="n">adim</span> <span class="o">-</span> <span class="mi">1</span><span class="p">))</span>
        <span class="n">elenenler</span><span class="p">.</span><span class="nf">append</span><span class="p">(</span><span class="n">daire</span><span class="p">.</span><span class="nf">popleft</span><span class="p">())</span>

    <span class="k">return</span> <span class="n">elenenler</span><span class="p">,</span> <span class="n">daire</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span>


<span class="n">elenenler</span><span class="p">,</span> <span class="n">kazanan</span> <span class="o">=</span> <span class="nf">josephus_sirasi</span><span class="p">(</span><span class="mi">7</span><span class="p">,</span> <span class="mi">3</span><span class="p">)</span>
<span class="nf">print</span><span class="p">(</span><span class="sh">"</span><span class="s">Elenenler:</span><span class="sh">"</span><span class="p">,</span> <span class="n">elenenler</span><span class="p">)</span>
<span class="nf">print</span><span class="p">(</span><span class="sh">"</span><span class="s">Kazanan:</span><span class="sh">"</span><span class="p">,</span> <span class="n">kazanan</span><span class="p">)</span>
</code></pre></div></div>

<p>Programın çıktısı şöyledir:</p>

<div class="language-text highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Elenenler: [3, 6, 2, 7, 5, 1]
Kazanan: 4
</code></pre></div></div>

<p><code class="language-plaintext highlighter-rouge">rotate(-(adim - 1))</code> işlemi kuyruğu sola döndürür. Böylece elenecek kişi başa gelir; <code class="language-plaintext highlighter-rouge">popleft()</code> da onu daireden çıkarır. Negatif döndürme miktarı büyük olsa bile <code class="language-plaintext highlighter-rouge">deque</code>, döngüsel davranışı korur.</p>

<h2 id="yalnızca-kazananı-bulmak">Yalnızca kazananı bulmak</h2>

<p>Büyük girişlerde elenme listesini saklamak istemiyorsak bağıntıyı döngüyle uygulayabiliriz:</p>

<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">def</span> <span class="nf">josephus_kazanan</span><span class="p">(</span><span class="n">n</span><span class="p">,</span> <span class="n">k</span><span class="p">):</span>
    <span class="n">konum</span> <span class="o">=</span> <span class="mi">0</span>
    <span class="k">for</span> <span class="n">mevcut_boyut</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="n">n</span> <span class="o">+</span> <span class="mi">1</span><span class="p">):</span>
        <span class="n">konum</span> <span class="o">=</span> <span class="p">(</span><span class="n">konum</span> <span class="o">+</span> <span class="n">k</span><span class="p">)</span> <span class="o">%</span> <span class="n">mevcut_boyut</span>
    <span class="k">return</span> <span class="n">konum</span> <span class="o">+</span> <span class="mi">1</span>
</code></pre></div></div>

<p>Josephus Problemi küçük bir oyun gibi görünse de modüler aritmetik, kuyruklar, yinelemeli bağıntılar ve performans karşılaştırmaları için güçlü bir örnektir. Adım değerini veya başlangıç kişisini değiştirerek farklı senaryolar üretmek, algoritmanın döngüsel mantığını iyice pekiştirir.</p>]]></content><author><name>Sonsuz Us</name></author><category term="Program" /><category term="josephus problemi" /><category term="python" /><category term="algoritma" /><category term="veri yapıları" /><category term="matematik" /><category term="simülasyon" /><summary type="html"><![CDATA[Bir grup insanın daire şeklinde dizildiğini, belirli aralıklarla bir kişinin elendiğini ve bu işlemin yalnızca tek kişi kalana kadar sürdüğünü düşünün. Kulağa biraz acımasız bir sandalye kapmaca oyunu gibi gelen Josephus Problemi, döngüsel yapıları, indeks hesaplarını ve algoritmik düşünmeyi öğrenmek için kullanılan klasik bir bilgisayar bilimi problemidir.]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://program.sonsuz.us/img/josephus-problemi-dairede-42.png" /><media:content medium="image" url="https://program.sonsuz.us/img/josephus-problemi-dairede-42.png" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">Soyut Veri Tipleri: İçeriyi Gizle, Güvenli Arayüzler Tasarla</title><link href="https://program.sonsuz.us/posts/soyut-veri-tipleri-iceriyi-gizle-guvenli-arayuzler-tasarla/" rel="alternate" type="text/html" title="Soyut Veri Tipleri: İçeriyi Gizle, Güvenli Arayüzler Tasarla" /><published>2026-10-14T00:00:00+00:00</published><updated>2026-10-14T00:00:00+00:00</updated><id>https://program.sonsuz.us/posts/soyut-veri-tipleri-iceriyi-gizle-guvenli-arayuzler-tasarla</id><content type="html" xml:base="https://program.sonsuz.us/posts/soyut-veri-tipleri-iceriyi-gizle-guvenli-arayuzler-tasarla/"><![CDATA[<p>Bir kahve makinesini kullanmak için içindeki pompanın basıncını veya ısıtıcının devresini bilmemiz gerekmez; düğmeye basar, kahvemizi alırız. Soyut Veri Tipleri de benzer biçimde çalışır: Kullanıcıya <strong>ne yapılabileceğini</strong> gösterirken bunun <strong>nasıl yapıldığını</strong> gizler. Böylece veri yapıları daha güvenli, değiştirilebilir ve anlaşılır hâle gelir.
``</p>
<h2 id="soyut-veri-tipi-nedir">Soyut Veri Tipi nedir?</h2>

<p>Soyut Veri Tipi veya kısaca <strong>ADT (Abstract Data Type)</strong>, bir veri koleksiyonunu yalnızca değerleri ve izin verilen işlemleri üzerinden tanımlar. ADT, doğrudan bir sınıf ya da belirli bir kod parçası değildir; daha çok uygulanması gereken davranışsal bir sözleşmedir.</p>

<p>Bir ADT kabaca şu bileşenlerle ifade edilebilir:</p>

\[ADT = (D, O, A)\]

<p>Burada $D$ olası değerler kümesini, $O$ sunulan işlemleri, $A$ ise bu işlemlerin uyması gereken kuralları belirtir. Örneğin yığın ADT’sinde <code class="language-plaintext highlighter-rouge">push</code>, <code class="language-plaintext highlighter-rouge">pop</code>, <code class="language-plaintext highlighter-rouge">peek</code> ve <code class="language-plaintext highlighter-rouge">isEmpty</code> işlemleri bulunur. Ancak elemanların bir diziyle mi, bağlı listeyle mi tutulduğu sözleşmenin parçası değildir.</p>

<table>
  <thead>
    <tr>
      <th>Kavram</th>
      <th>Cevapladığı soru</th>
      <th>Yığın örneği</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Arayüz</td>
      <td>Ne yapabilirim?</td>
      <td><code class="language-plaintext highlighter-rouge">push</code>, <code class="language-plaintext highlighter-rouge">pop</code>, <code class="language-plaintext highlighter-rouge">peek</code></td>
    </tr>
    <tr>
      <td>Uygulama</td>
      <td>Nasıl yapılıyor?</td>
      <td>Dizi veya bağlı liste</td>
    </tr>
    <tr>
      <td>Değişmez</td>
      <td>Her zaman ne doğru kalmalı?</td>
      <td>Eleman sayısı negatif olamaz</td>
    </tr>
    <tr>
      <td>İstemci</td>
      <td>ADT’yi kim kullanır?</td>
      <td>Uygulama kodu</td>
    </tr>
  </tbody>
</table>

<p><img src="/img/soyut-veri-tipleri-24.svg" alt="soyut-veri-tipleri-24" /></p>

<h2 id="temsil-bağımsızlığı-ve-kapsülleme">Temsil bağımsızlığı ve kapsülleme</h2>

<p>ADT tasarımının süper gücü <strong>temsil bağımsızlığıdır</strong>. İstemci kodu iç depolama biçimine erişemiyorsa uygulama daha sonra değiştirilebilir. Başlangıçta dizi kullanan bir yığın, performans ihtiyacı nedeniyle bağlı listeye geçirilebilir; arayüz aynı kaldığı sürece kullanıcı bunu fark etmez.</p>

<p>İç veriyi doğrudan dışarı açmak ise değişmezlerin bozulmasına yol açar. Örneğin istemci yığının eleman dizisini temizleyip sayaç değerini değiştirmezse nesne tutarsız hâle gelir. Bu nedenle veri <code class="language-plaintext highlighter-rouge">private</code>, güvenli işlemler ise <code class="language-plaintext highlighter-rouge">public</code> tutulmalıdır.</p>

<div class="language-typescript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kr">interface</span> <span class="nx">Stack</span><span class="o">&lt;</span><span class="nx">T</span><span class="o">&gt;</span> <span class="p">{</span>
  <span class="nf">push</span><span class="p">(</span><span class="na">value</span><span class="p">:</span> <span class="nx">T</span><span class="p">):</span> <span class="k">void</span><span class="p">;</span>
  <span class="nf">pop</span><span class="p">():</span> <span class="nx">T</span><span class="p">;</span>
  <span class="nf">peek</span><span class="p">():</span> <span class="nx">T</span><span class="p">;</span>
  <span class="nf">isEmpty</span><span class="p">():</span> <span class="nx">boolean</span><span class="p">;</span>
  <span class="nf">size</span><span class="p">():</span> <span class="kr">number</span><span class="p">;</span>
<span class="p">}</span>

<span class="kd">class</span> <span class="nc">ArrayStack</span><span class="o">&lt;</span><span class="nx">T</span><span class="o">&gt;</span> <span class="k">implements</span> <span class="nx">Stack</span><span class="o">&lt;</span><span class="nx">T</span><span class="o">&gt;</span> <span class="p">{</span>
  <span class="k">private</span> <span class="na">items</span><span class="p">:</span> <span class="nx">T</span><span class="p">[]</span> <span class="o">=</span> <span class="p">[];</span>

  <span class="nf">push</span><span class="p">(</span><span class="na">value</span><span class="p">:</span> <span class="nx">T</span><span class="p">):</span> <span class="k">void</span> <span class="p">{</span>
    <span class="k">this</span><span class="p">.</span><span class="nx">items</span><span class="p">.</span><span class="nf">push</span><span class="p">(</span><span class="nx">value</span><span class="p">);</span>
  <span class="p">}</span>

  <span class="nf">pop</span><span class="p">():</span> <span class="nx">T</span> <span class="p">{</span>
    <span class="k">if </span><span class="p">(</span><span class="k">this</span><span class="p">.</span><span class="nf">isEmpty</span><span class="p">())</span> <span class="p">{</span>
      <span class="k">throw</span> <span class="k">new</span> <span class="nc">Error</span><span class="p">(</span><span class="dl">"</span><span class="s2">Boş yığından eleman çıkarılamaz</span><span class="dl">"</span><span class="p">);</span>
    <span class="p">}</span>
    <span class="k">return</span> <span class="k">this</span><span class="p">.</span><span class="nx">items</span><span class="p">.</span><span class="nf">pop</span><span class="p">()</span> <span class="kd">as </span><span class="nx">T</span><span class="p">;</span>
  <span class="p">}</span>

  <span class="nf">peek</span><span class="p">():</span> <span class="nx">T</span> <span class="p">{</span>
    <span class="k">if </span><span class="p">(</span><span class="k">this</span><span class="p">.</span><span class="nf">isEmpty</span><span class="p">())</span> <span class="p">{</span>
      <span class="k">throw</span> <span class="k">new</span> <span class="nc">Error</span><span class="p">(</span><span class="dl">"</span><span class="s2">Boş yığının tepesi yoktur</span><span class="dl">"</span><span class="p">);</span>
    <span class="p">}</span>
    <span class="k">return</span> <span class="k">this</span><span class="p">.</span><span class="nx">items</span><span class="p">[</span><span class="k">this</span><span class="p">.</span><span class="nx">items</span><span class="p">.</span><span class="nx">length</span> <span class="o">-</span> <span class="mi">1</span><span class="p">];</span>
  <span class="p">}</span>

  <span class="nf">isEmpty</span><span class="p">():</span> <span class="nx">boolean</span> <span class="p">{</span>
    <span class="k">return</span> <span class="k">this</span><span class="p">.</span><span class="nx">items</span><span class="p">.</span><span class="nx">length</span> <span class="o">===</span> <span class="mi">0</span><span class="p">;</span>
  <span class="p">}</span>

  <span class="nf">size</span><span class="p">():</span> <span class="kr">number</span> <span class="p">{</span>
    <span class="k">return</span> <span class="k">this</span><span class="p">.</span><span class="nx">items</span><span class="p">.</span><span class="nx">length</span><span class="p">;</span>
  <span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>

<p>Bu kodda <code class="language-plaintext highlighter-rouge">Stack&lt;T&gt;</code> davranış sözleşmesini, <code class="language-plaintext highlighter-rouge">ArrayStack&lt;T&gt;</code> ise dizi tabanlı uygulamayı temsil eder. <code class="language-plaintext highlighter-rouge">items</code> alanının özel olması, istemcinin yığını kuralları atlayarak değiştirmesini engeller.</p>

<h2 id="ön-koşullar-son-koşullar-ve-değişmezler">Ön koşullar, son koşullar ve değişmezler</h2>

<p>Güvenli bir arayüz tasarlanırken her işlem için üç soru sorulabilir:</p>

<ul>
  <li><strong>Ön koşul:</strong> İşlem çağrılmadan önce ne doğru olmalı?</li>
  <li><strong>Son koşul:</strong> İşlem tamamlandığında ne garanti edilir?</li>
  <li><strong>Değişmez:</strong> Nesnenin ömrü boyunca hangi kural korunur?</li>
</ul>

<p>Yığın için <code class="language-plaintext highlighter-rouge">pop</code> işleminin ön koşulu $size &gt; 0$ olabilir. Başarılı işlemden sonra:</p>

\[size_{sonra} = size_{önce} - 1\]

<p>Ayrıca LIFO kuralı gereği son eklenen eleman ilk çıkar. Ön koşul sağlanmadığında sessizce <code class="language-plaintext highlighter-rouge">undefined</code> döndürmek yerine açık bir hata üretmek, hatanın kaynağını görünür kılar.</p>

<table>
  <thead>
    <tr>
      <th>Zayıf tasarım</th>
      <th>Güvenli ADT tasarımı</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>İç koleksiyonu dışarı açar</td>
      <td>Kontrollü metotlar sunar</td>
    </tr>
    <tr>
      <td>Belirsiz hata davranışı vardır</td>
      <td>Hata sözleşmesi tanımlıdır</td>
    </tr>
    <tr>
      <td>Uygulamaya bağımlıdır</td>
      <td>Temsil bağımsızdır</td>
    </tr>
    <tr>
      <td>Her işi tek metotta toplar</td>
      <td>Küçük ve anlamlı işlemler kullanır</td>
    </tr>
  </tbody>
</table>

<h2 id="i̇yi-bir-adt-için-kısa-kontrol-listesi">İyi bir ADT için kısa kontrol listesi</h2>

<p>Arayüzü mümkün olduğunca küçük tutun, metotlara niyet belirten adlar verin ve iç nesnelerin değiştirilebilir kopyalarını dışarı sızdırmayın. Geçersiz durumları mümkünse oluşturulamaz hâle getirin; mümkün değilse girişleri doğrulayın. Son olarak testleri iç diziye göre değil, gözlemlenebilir davranışa göre yazın.</p>

<p>Özetle ADT tasarlamak yalnızca veriyi saklamak değildir. Asıl amaç, yanlış kullanımı zorlaştıran ve uygulama ayrıntılarının özgürce değişmesine izin veren bir sözleşme kurmaktır. İyi bir ADT, kullanıcıya düğmeleri gösterir; kablo karmaşasını ise kapağın altında bırakır.</p>]]></content><author><name>Sonsuz Us</name></author><category term="Bilgi" /><category term="soyut veri tipleri" /><category term="adt" /><category term="veri yapıları" /><category term="kapsülleme" /><category term="arayüz tasarımı" /><category term="typescript" /><summary type="html"><![CDATA[Bir kahve makinesini kullanmak için içindeki pompanın basıncını veya ısıtıcının devresini bilmemiz gerekmez; düğmeye basar, kahvemizi alırız. Soyut Veri Tipleri de benzer biçimde çalışır: Kullanıcıya ne yapılabileceğini gösterirken bunun nasıl yapıldığını gizler. Böylece veri yapıları daha güvenli, değiştirilebilir ve anlaşılır hâle gelir.]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://program.sonsuz.us/img/soyut-veri-tipleri-24.png" /><media:content medium="image" url="https://program.sonsuz.us/img/soyut-veri-tipleri-24.png" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">Bézier Eğrileri: Kontrol Noktalarından Vektörel Tasarıma</title><link href="https://program.sonsuz.us/posts/bezier-egrileri-kontrol-noktalarindan-vektorel-tasarima/" rel="alternate" type="text/html" title="Bézier Eğrileri: Kontrol Noktalarından Vektörel Tasarıma" /><published>2026-10-13T00:00:00+00:00</published><updated>2026-10-13T00:00:00+00:00</updated><id>https://program.sonsuz.us/posts/bezier-egrileri-kontrol-noktalarindan-vektorel-tasarima</id><content type="html" xml:base="https://program.sonsuz.us/posts/bezier-egrileri-kontrol-noktalarindan-vektorel-tasarima/"><![CDATA[<p>Bir logodaki kusursuz kıvrımın veya bir yazı karakterindeki zarif yayın arkasında çoğu zaman Bézier eğrileri vardır. Bu eğriler, yüzlerce pikseli tek tek yerleştirmek yerine birkaç kontrol noktasıyla akıcı şekiller oluşturmamızı sağlar. Üstelik yalnızca Illustrator, Figma ve Inkscape gibi tasarım araçlarında değil; animasyonlardan fontlara, oyunlardan robot hareketlerine kadar geniş bir alanda kullanılır.</p>

<p>``</p>

<h2 id="eğriyi-oluşturan-temel-fikir">Eğriyi oluşturan temel fikir</h2>

<p>Bézier eğrisi, Fransız mühendis Pierre Bézier tarafından otomobil gövdelerinin modellenmesinde yaygınlaştırıldı. Temel yaklaşım şaşırtıcı derecede basittir: Eğrinin başlangıç ve bitiş noktalarını belirler, araya da eğriyi kendilerine doğru çeken kontrol noktaları koyarız.</p>

<p>En basit tür olan doğrusal Bézier eğrisinde iki nokta bulunur:</p>

\[B(t)=(1-t)P_0+tP_1, \quad 0 \leq t \leq 1\]

<p>Burada $t$, başlangıçtan sona doğru ilerlemeyi temsil eder. $t=0$ olduğunda $P_0$, $t=1$ olduğunda ise $P_1$ noktasındayız. Aslında bu, iki nokta arasında yapılan doğrusal enterpolasyondur.</p>

<p>Grafik yazılımlarında sık karşılaştığımız kübik Bézier eğrisi ise dört nokta kullanır:</p>

\[B(t)=(1-t)^3P_0+3(1-t)^2tP_1+3(1-t)t^2P_2+t^3P_3\]

<p>$P_0$ ve $P_3$ eğrinin uçlarıdır. $P_1$ ve $P_2$ ise çoğu tasarım aracında tutamaç olarak gördüğümüz kontrol noktalarıdır. Eğri genellikle bu kontrol noktalarının üzerinden geçmez; yalnızca onların etkisiyle yön değiştirir. Kontrol noktasını çektiğinizde eğrinin lastik gibi uzaması bundandır.</p>

<table>
  <thead>
    <tr>
      <th>Eğri türü</th>
      <th style="text-align: right">Nokta sayısı</th>
      <th>Kullanım alanı</th>
      <th>Esneklik</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Doğrusal</td>
      <td style="text-align: right">2</td>
      <td>Düz çizgiler</td>
      <td>Düşük</td>
    </tr>
    <tr>
      <td>Kuadratik</td>
      <td style="text-align: right">3</td>
      <td>Basit kıvrımlar, fontlar</td>
      <td>Orta</td>
    </tr>
    <tr>
      <td>Kübik</td>
      <td style="text-align: right">4</td>
      <td>İllüstrasyon, SVG, animasyon</td>
      <td>Yüksek</td>
    </tr>
  </tbody>
</table>

<h2 id="yumuşaklık-nasıl-sağlanır">Yumuşaklık nasıl sağlanır?</h2>

<p>Birden fazla Bézier parçası uç uca eklenerek karmaşık yollar oluşturulur. Ancak parçaların yalnızca aynı noktada buluşması yeterli değildir. Keskin bir köşe istemiyorsak, birleşim noktasındaki kontrol kollarının aynı doğrultuda olması gerekir. Böylece eğrilerin teğetleri uyumlu olur ve gözümüz geçişi pürüzsüz algılar.</p>

<table>
  <thead>
    <tr>
      <th>Süreklilik</th>
      <th>Anlamı</th>
      <th>Görsel sonuç</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>$C^0$</td>
      <td>Parçalar aynı noktada buluşur</td>
      <td>Kopukluk yoktur, köşe olabilir</td>
    </tr>
    <tr>
      <td>$C^1$</td>
      <td>Birinci türevler eşittir</td>
      <td>Yön ve hız yumuşaktır</td>
    </tr>
    <tr>
      <td>$C^2$</td>
      <td>İkinci türevler de eşittir</td>
      <td>Eğrilik daha doğal değişir</td>
    </tr>
  </tbody>
</table>

<p>Tasarım programlarındaki simetrik tutamaçlar, iki kolu aynı doğrultuda ve çoğunlukla eşit uzunlukta tutar. Köşe noktası seçildiğinde ise kollar bağımsız hareket eder; böylece sivri dönüşler üretilebilir.</p>

<h2 id="canvas-üzerinde-bir-bézier-eğrisi">Canvas üzerinde bir Bézier eğrisi</h2>

<p>Aşağıdaki JavaScript kodu, HTML Canvas üzerinde kübik bir eğri çizer. Kırmızı noktalar başlangıç ve bitişi, mavi noktalar ise eğrinin yönünü belirleyen kontrol noktalarını gösterir.</p>

<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">const</span> <span class="nx">canvas</span> <span class="o">=</span> <span class="nb">document</span><span class="p">.</span><span class="nf">querySelector</span><span class="p">(</span><span class="dl">'</span><span class="s1">canvas</span><span class="dl">'</span><span class="p">);</span>
<span class="kd">const</span> <span class="nx">ctx</span> <span class="o">=</span> <span class="nx">canvas</span><span class="p">.</span><span class="nf">getContext</span><span class="p">(</span><span class="dl">'</span><span class="s1">2d</span><span class="dl">'</span><span class="p">);</span>

<span class="kd">const</span> <span class="nx">points</span> <span class="o">=</span> <span class="p">[</span>
  <span class="p">{</span> <span class="na">x</span><span class="p">:</span> <span class="mi">40</span><span class="p">,</span>  <span class="na">y</span><span class="p">:</span> <span class="mi">180</span> <span class="p">},</span>  <span class="c1">// başlangıç</span>
  <span class="p">{</span> <span class="na">x</span><span class="p">:</span> <span class="mi">100</span><span class="p">,</span> <span class="na">y</span><span class="p">:</span> <span class="mi">20</span> <span class="p">},</span>   <span class="c1">// kontrol 1</span>
  <span class="p">{</span> <span class="na">x</span><span class="p">:</span> <span class="mi">240</span><span class="p">,</span> <span class="na">y</span><span class="p">:</span> <span class="mi">260</span> <span class="p">},</span>  <span class="c1">// kontrol 2</span>
  <span class="p">{</span> <span class="na">x</span><span class="p">:</span> <span class="mi">320</span><span class="p">,</span> <span class="na">y</span><span class="p">:</span> <span class="mi">80</span> <span class="p">}</span>    <span class="c1">// bitiş</span>
<span class="p">];</span>

<span class="nx">ctx</span><span class="p">.</span><span class="nf">beginPath</span><span class="p">();</span>
<span class="nx">ctx</span><span class="p">.</span><span class="nf">moveTo</span><span class="p">(</span><span class="nx">points</span><span class="p">[</span><span class="mi">0</span><span class="p">].</span><span class="nx">x</span><span class="p">,</span> <span class="nx">points</span><span class="p">[</span><span class="mi">0</span><span class="p">].</span><span class="nx">y</span><span class="p">);</span>
<span class="nx">ctx</span><span class="p">.</span><span class="nf">bezierCurveTo</span><span class="p">(</span>
  <span class="nx">points</span><span class="p">[</span><span class="mi">1</span><span class="p">].</span><span class="nx">x</span><span class="p">,</span> <span class="nx">points</span><span class="p">[</span><span class="mi">1</span><span class="p">].</span><span class="nx">y</span><span class="p">,</span>
  <span class="nx">points</span><span class="p">[</span><span class="mi">2</span><span class="p">].</span><span class="nx">x</span><span class="p">,</span> <span class="nx">points</span><span class="p">[</span><span class="mi">2</span><span class="p">].</span><span class="nx">y</span><span class="p">,</span>
  <span class="nx">points</span><span class="p">[</span><span class="mi">3</span><span class="p">].</span><span class="nx">x</span><span class="p">,</span> <span class="nx">points</span><span class="p">[</span><span class="mi">3</span><span class="p">].</span><span class="nx">y</span>
<span class="p">);</span>
<span class="nx">ctx</span><span class="p">.</span><span class="nx">strokeStyle</span> <span class="o">=</span> <span class="dl">'</span><span class="s1">#222</span><span class="dl">'</span><span class="p">;</span>
<span class="nx">ctx</span><span class="p">.</span><span class="nx">lineWidth</span> <span class="o">=</span> <span class="mi">4</span><span class="p">;</span>
<span class="nx">ctx</span><span class="p">.</span><span class="nf">stroke</span><span class="p">();</span>

<span class="nx">points</span><span class="p">.</span><span class="nf">forEach</span><span class="p">((</span><span class="nx">p</span><span class="p">,</span> <span class="nx">index</span><span class="p">)</span> <span class="o">=&gt;</span> <span class="p">{</span>
  <span class="nx">ctx</span><span class="p">.</span><span class="nf">beginPath</span><span class="p">();</span>
  <span class="nx">ctx</span><span class="p">.</span><span class="nf">arc</span><span class="p">(</span><span class="nx">p</span><span class="p">.</span><span class="nx">x</span><span class="p">,</span> <span class="nx">p</span><span class="p">.</span><span class="nx">y</span><span class="p">,</span> <span class="mi">6</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="nb">Math</span><span class="p">.</span><span class="nx">PI</span> <span class="o">*</span> <span class="mi">2</span><span class="p">);</span>
  <span class="nx">ctx</span><span class="p">.</span><span class="nx">fillStyle</span> <span class="o">=</span> <span class="nx">index</span> <span class="o">===</span> <span class="mi">0</span> <span class="o">||</span> <span class="nx">index</span> <span class="o">===</span> <span class="mi">3</span> <span class="p">?</span> <span class="dl">'</span><span class="s1">red</span><span class="dl">'</span> <span class="p">:</span> <span class="dl">'</span><span class="s1">blue</span><span class="dl">'</span><span class="p">;</span>
  <span class="nx">ctx</span><span class="p">.</span><span class="nf">fill</span><span class="p">();</span>
<span class="p">});</span>
</code></pre></div></div>

<p>Kodda <code class="language-plaintext highlighter-rouge">bezierCurveTo</code>, iki kontrol noktasıyla bitiş noktasını alır. Noktaları fareyle sürüklenebilir hâle getirerek küçük bir vektörel çizim aracı bile geliştirebilirsiniz.</p>

<h2 id="neden-vektörel-tasarımın-yıldızıdır">Neden vektörel tasarımın yıldızıdır?</h2>

<p>Bézier eğrileri çözünürlükten bağımsızdır. Bir logo kartvizit boyutundan bina cephesine büyütülse bile matematiksel tanımı değişmez; eğri yeni ölçekte tekrar hesaplanır. Raster görsellerdeki pikselleşmenin görülmemesi bu yüzdendir.</p>

<p>SVG dosyalarındaki <code class="language-plaintext highlighter-rouge">C</code> komutu, fontların dış hatları ve CSS animasyonlarındaki zamanlama fonksiyonları aynı düşünceden yararlanır. Kısacası kontrol noktaları yalnızca çizgileri bükmez; dijital tasarımın ölçeklenebilir, düzenlenebilir ve şaşırtıcı derecede zarif olmasını sağlar.</p>

<p><img src="/img/bézier-egrileri-kontrol-15.svg" alt="bézier-egrileri-kontrol-15" /></p>]]></content><author><name>Sonsuz Us</name></author><category term="Bilgi" /><category term="bezier" /><category term="vektörel-tasarım" /><category term="bilgisayar-grafikleri" /><category term="matematik" /><category term="javascript" /><category term="svg" /><summary type="html"><![CDATA[Bir logodaki kusursuz kıvrımın veya bir yazı karakterindeki zarif yayın arkasında çoğu zaman Bézier eğrileri vardır. Bu eğriler, yüzlerce pikseli tek tek yerleştirmek yerine birkaç kontrol noktasıyla akıcı şekiller oluşturmamızı sağlar. Üstelik yalnızca Illustrator, Figma ve Inkscape gibi tasarım araçlarında değil; animasyonlardan fontlara, oyunlardan robot hareketlerine kadar geniş bir alanda kullanılır.]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://program.sonsuz.us/img/b%C3%A9zier-egrileri-kontrol-15.png" /><media:content medium="image" url="https://program.sonsuz.us/img/b%C3%A9zier-egrileri-kontrol-15.png" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">Boole Cebri ve Mantık Devreleri: Dijital Dünyanın Üç Temel Kapısı</title><link href="https://program.sonsuz.us/posts/boole-cebri-ve-mantik-devreleri-dijital-dunyanin-uc-temel-kapisi/" rel="alternate" type="text/html" title="Boole Cebri ve Mantık Devreleri: Dijital Dünyanın Üç Temel Kapısı" /><published>2026-10-13T00:00:00+00:00</published><updated>2026-10-13T00:00:00+00:00</updated><id>https://program.sonsuz.us/posts/boole-cebri-ve-mantik-devreleri-dijital-dunyanin-uc-temel-kapisi</id><content type="html" xml:base="https://program.sonsuz.us/posts/boole-cebri-ve-mantik-devreleri-dijital-dunyanin-uc-temel-kapisi/"><![CDATA[<p>Bilgisayarlar, telefonlar ve oyun konsolları dışarıdan son derece karmaşık görünür. Ancak bu cihazların derinliklerine indiğimizde karşımıza yalnızca iki değer çıkar: 0 ve 1. Boole cebri, bu iki değer arasındaki ilişkileri matematiksel olarak açıklarken AND, OR ve NOT kapıları da aynı işlemleri elektronik devrelerde gerçekleştirir. Kısacası milyarlarca transistörün düzenlediği dijital konser, üç temel notayla başlar.</p>

<p>``</p>

<h2 id="boole-cebri-nedir">Boole cebri nedir?</h2>

<p>George Boole tarafından geliştirilen Boole cebrinde değişkenler yalnızca iki değer alır. Genellikle 0 değeri <strong>yanlış</strong>, 1 değeri ise <strong>doğru</strong> anlamına gelir. Elektronik devrelerde bunlar düşük ve yüksek gerilim seviyelerini temsil eder.</p>

<p>Klasik cebirde $2 + 2 = 4$ gibi işlemler yaparken Boole cebrinde sonuçlar doğruluk durumlarına göre belirlenir. Temel işlemler şöyle gösterilebilir:</p>

<ul>
  <li>AND: $A \cdot B$</li>
  <li>OR: $A + B$</li>
  <li>NOT: $\overline{A}$</li>
</ul>

<p>Buradaki toplama ve çarpma sembolleri bildiğimiz aritmetik işlemler değildir. Örneğin Boole cebrinde $1 + 1 = 1$ olur; çünkü iki doğru ifadenin OR sonucu yine doğrudur.</p>

<h2 id="üç-temel-mantık-kapısı">Üç temel mantık kapısı</h2>

<table>
  <thead>
    <tr>
      <th>Kapı</th>
      <th>Sözel anlamı</th>
      <th>Çıkışın 1 olma koşulu</th>
      <th>Günlük hayat benzetmesi</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>AND</td>
      <td>VE</td>
      <td>Tüm girişler 1 ise</td>
      <td>İki anahtar da açıksa lamba yanar</td>
    </tr>
    <tr>
      <td>OR</td>
      <td>VEYA</td>
      <td>En az bir giriş 1 ise</td>
      <td>Kapılardan biri açılırsa alarm çalar</td>
    </tr>
    <tr>
      <td>NOT</td>
      <td>DEĞİL</td>
      <td>Giriş 0 ise</td>
      <td>Karanlık olduğunda gece lambası yanar</td>
    </tr>
  </tbody>
</table>

<h3 id="and-kapısı">AND kapısı</h3>

<p>AND kapısı seçici bir güvenlik görevlisi gibidir: Bütün koşullar sağlanmadan geçişe izin vermez. İki girişli bir AND kapısının denklemi $Y=A \cdot B$ biçimindedir.</p>

<table>
  <thead>
    <tr>
      <th style="text-align: right">A</th>
      <th style="text-align: right">B</th>
      <th style="text-align: right">Y</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td style="text-align: right">0</td>
      <td style="text-align: right">0</td>
      <td style="text-align: right">0</td>
    </tr>
    <tr>
      <td style="text-align: right">0</td>
      <td style="text-align: right">1</td>
      <td style="text-align: right">0</td>
    </tr>
    <tr>
      <td style="text-align: right">1</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: right">1</td>
      <td style="text-align: right">1</td>
    </tr>
  </tbody>
</table>

<p>Örneğin bir makinenin çalışması için hem güvenlik kapağının kapalı hem de başlatma düğmesinin basılı olması gerekiyorsa AND kapısı kullanılabilir.</p>

<h3 id="or-kapısı">OR kapısı</h3>

<p>OR kapısı daha hoşgörülüdür. Girişlerden en az biri doğruysa çıkış doğrudur. Denklem $Y=A+B$ şeklindedir. Yalnızca $A=0$ ve $B=0$ olduğunda çıkış 0 olur. Bir binada duman sensörü veya sıcaklık sensörü tehlike algıladığında alarmın çalışması buna örnektir.</p>

<h3 id="not-kapısı">NOT kapısı</h3>

<p>NOT kapısının tek girişi vardır ve aldığı değeri tersine çevirir:</p>

\[Y=\overline{A}\]

<p>Giriş 1 ise çıkış 0, giriş 0 ise çıkış 1 olur. Bu nedenle NOT kapısına <strong>invertör</strong> de denir. Otomatik yanan bir gece lambasında ışık sensörünün sonucu ters çevrilerek karanlıkta enerji verilmesi sağlanabilir.</p>

<h2 id="kapıları-birleştirince-ne-olur">Kapıları birleştirince ne olur?</h2>

<p>Asıl eğlence kapılar birlikte kullanıldığında başlar. Örneğin aşağıdaki ifade, A ve B girişleri doğruyken veya C girişi yanlışken çıkışı etkinleştirir:</p>

\[Y=(A \cdot B)+\overline{C}\]

<p>Bu ifadeler sadeleştirilerek daha az kapı kullanan devreler üretilebilir. De Morgan kuralları bu noktada oldukça önemlidir:</p>

\[\overline{A \cdot B}=\overline{A}+\overline{B}\]

<p>Daha az kapı; daha düşük maliyet, enerji tüketimi ve gecikme anlamına gelebilir.</p>

<h2 id="verilog-ile-küçük-bir-devre">Verilog ile küçük bir devre</h2>

<p>Mantık devreleri, donanım tanımlama dilleriyle kodlanabilir. Aşağıdaki Verilog modülü aynı birleşik ifadeyi gerçekleştirir:</p>

<div class="language-verilog highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">module</span> <span class="n">mantik_devresi</span> <span class="p">(</span>
    <span class="kt">input</span>  <span class="kt">wire</span> <span class="n">A</span><span class="p">,</span>
    <span class="kt">input</span>  <span class="kt">wire</span> <span class="n">B</span><span class="p">,</span>
    <span class="kt">input</span>  <span class="kt">wire</span> <span class="n">C</span><span class="p">,</span>
    <span class="kt">output</span> <span class="kt">wire</span> <span class="n">Y</span>
<span class="p">);</span>
    <span class="k">assign</span> <span class="n">Y</span> <span class="o">=</span> <span class="p">(</span><span class="n">A</span> <span class="o">&amp;</span> <span class="n">B</span><span class="p">)</span> <span class="o">|</span> <span class="o">~</span><span class="n">C</span><span class="p">;</span>
<span class="k">endmodule</span>
</code></pre></div></div>

<p>Burada <code class="language-plaintext highlighter-rouge">&amp;</code> AND, <code class="language-plaintext highlighter-rouge">|</code> OR, <code class="language-plaintext highlighter-rouge">~</code> ise NOT işlemini temsil eder. <code class="language-plaintext highlighter-rouge">assign</code> ifadesi girişlerdeki değişikliklerin çıkışa sürekli yansıtılmasını sağlar. Bu kod bir FPGA üzerinde gerçek fiziksel kapılara dönüştürülebilir.</p>

<p>AND, OR ve NOT kapıları tek başlarına basit görünse de toplayıcılar, işlemciler, bellek denetleyicileri ve karar mekanizmaları bu yapıların birleşiminden doğar. Dijital dünyanın görkemli gökdelenleri, aslında 0 ve 1 biçimindeki küçücük tuğlalar üzerine kuruludur.</p>

<p><img src="/img/boole-cebri-ve-29.svg" alt="boole-cebri-ve-29" /></p>]]></content><author><name>Sonsuz Us</name></author><category term="Bilgi" /><category term="boole cebri" /><category term="mantık devreleri" /><category term="and kapısı" /><category term="or kapısı" /><category term="not kapısı" /><category term="dijital elektronik" /><category term="verilog" /><summary type="html"><![CDATA[Bilgisayarlar, telefonlar ve oyun konsolları dışarıdan son derece karmaşık görünür. Ancak bu cihazların derinliklerine indiğimizde karşımıza yalnızca iki değer çıkar: 0 ve 1. Boole cebri, bu iki değer arasındaki ilişkileri matematiksel olarak açıklarken AND, OR ve NOT kapıları da aynı işlemleri elektronik devrelerde gerçekleştirir. Kısacası milyarlarca transistörün düzenlediği dijital konser, üç temel notayla başlar.]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://program.sonsuz.us/img/boole-cebri-ve-29.png" /><media:content medium="image" url="https://program.sonsuz.us/img/boole-cebri-ve-29.png" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">Domino Kaplama Problemi: Satranç Tahtasında Kombinatoriğin Gücü</title><link href="https://program.sonsuz.us/posts/domino-kaplama-problemi-satranc-tahtasinda-kombinatorigin-gucu/" rel="alternate" type="text/html" title="Domino Kaplama Problemi: Satranç Tahtasında Kombinatoriğin Gücü" /><published>2026-10-13T00:00:00+00:00</published><updated>2026-10-13T00:00:00+00:00</updated><id>https://program.sonsuz.us/posts/domino-kaplama-problemi-satranc-tahtasinda-kombinatorigin-gucu</id><content type="html" xml:base="https://program.sonsuz.us/posts/domino-kaplama-problemi-satranc-tahtasinda-kombinatorigin-gucu/"><![CDATA[<p>Bir satranç tahtasını boşluk bırakmadan domino taşlarıyla kaplamak ilk bakışta basit bir yapboz gibi görünür. Ancak tahtadan bazı kareler çıkarıldığında problem, kombinatoriğin en zarif sorularından birine dönüşür. Üstelik çözüm için her olasılığı denemek yerine boyama, değişmez ve graf teorisi gibi güçlü fikirlerden yararlanabiliriz.
``</p>
<h2 id="problemin-temel-modeli">Problemin temel modeli</h2>

<p>Standart bir satranç tahtası $8 \times 8 = 64$ kareden oluşur. Bir domino taşı yan yana bulunan tam iki kareyi örter. Dolayısıyla tahtanın tamamını kaplamak için</p>

\[\frac{64}{2}=32\]

<p>domino gerekir. Bu hesap bize gerekli bir koşul verir: Kaplanacak kare sayısı çift olmalıdır. Fakat çift olması, tek başına kaplanabilirlik garantisi değildir.</p>

<p>Örneğin tahtadan iki kare çıkarırsak geriye 62 kare kalır ve sayı hâlâ çifttir. Yine de çıkarılan karelerin konumu, kaplamayı imkânsız hâle getirebilir. İşin eğlenceli kısmı tam olarak burada başlar.</p>

<h2 id="siyah-beyaz-boyama-ve-değişmez-fikri">Siyah-beyaz boyama ve değişmez fikri</h2>

<p>Satranç tahtasında her yatay veya dikey komşu kare farklı renktedir. Bu nedenle yerleştirilen her domino mutlaka bir siyah ve bir beyaz kare kaplar. Başlangıçta tahtada 32 siyah ve 32 beyaz kare bulunur.</p>

<p>Karşılıklı iki köşe çıkarılsın. Bu köşeler aynı renktedir; örneğin ikisi de beyaz olsun. Geriye 32 siyah ve 30 beyaz kare kalır. Her domino renklerden birer tane tükettiği için bütün kareleri kaplamak mümkün değildir.</p>

<p>Bu argümanda korunan özelliğe <strong>değişmez</strong> denir. Domino hangi konuma yerleştirilirse yerleştirilsin kaplanan siyah ve beyaz kare sayıları eşittir.</p>

<table>
  <thead>
    <tr>
      <th>Tahta durumu</th>
      <th style="text-align: right">Siyah kare</th>
      <th style="text-align: right">Beyaz kare</th>
      <th>Sonuç</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Tam $8 \times 8$ tahta</td>
      <td style="text-align: right">32</td>
      <td style="text-align: right">32</td>
      <td>Kaplanabilir</td>
    </tr>
    <tr>
      <td>Zıt renkli iki kare çıkarılmış</td>
      <td style="text-align: right">31</td>
      <td style="text-align: right">31</td>
      <td>Renk testi engel oluşturmaz</td>
    </tr>
    <tr>
      <td>Aynı renkli iki köşe çıkarılmış</td>
      <td style="text-align: right">32</td>
      <td style="text-align: right">30</td>
      <td>Kaplanamaz</td>
    </tr>
  </tbody>
</table>

<p><img src="/img/domino-kaplama-problemi-91.svg" alt="domino-kaplama-problemi-91" /></p>

<p>Burada önemli bir ayrıntı vardır: Renk sayılarının eşitliği gerekli koşuldur, fakat her zaman yeterli değildir. Bazı düzensiz bölgelerde renkler dengeli olsa bile geometrik sıkışmalar kaplamayı engelleyebilir.</p>

<h2 id="problem-bir-grafa-nasıl-dönüşür">Problem bir grafa nasıl dönüşür?</h2>

<p>Her kareyi bir düğüm, kenar paylaşan iki kareyi de bir bağlantı olarak düşünelim. Siyah kareler bir grubu, beyaz kareler diğer grubu oluşturur. Böylece <strong>iki parçalı graf</strong> elde edilir.</p>

<p>Bir domino, bağlı bir siyah-beyaz düğüm çiftini seçer. Tüm tahtayı kaplamak ise her düğümün tam bir kez kullanıldığı <strong>mükemmel eşleşme</strong> bulmakla aynıdır.</p>

<table>
  <thead>
    <tr>
      <th>Kaplama kavramı</th>
      <th>Graf teorisindeki karşılığı</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Kare</td>
      <td>Düğüm</td>
    </tr>
    <tr>
      <td>Komşu iki kare</td>
      <td>Kenar</td>
    </tr>
    <tr>
      <td>Bir domino</td>
      <td>Eşleşme kenarı</td>
    </tr>
    <tr>
      <td>Tam kaplama</td>
      <td>Mükemmel eşleşme</td>
    </tr>
  </tbody>
</table>

<p>Bu bakış açısı sayesinde problem yalnızca satranç tahtaları için değil, delikli ve düzensiz bölgeler için de algoritmik olarak incelenebilir. Hopcroft–Karp algoritması iki parçalı graflarda eşleşmeyi yaklaşık $O(E\sqrt{V})$ zamanda bulur.</p>

<h2 id="küçük-tahtalarda-python-ile-arama">Küçük tahtalarda Python ile arama</h2>

<p>Aşağıdaki geri izleme kodu, verilen bölgenin kaplanabilir olup olmadığını sınar. Kod ilk boş kareyi seçer, sağa veya aşağıya domino koymayı dener ve çıkmazda önceki seçime döner.</p>

<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">def</span> <span class="nf">kaplanabilir</span><span class="p">(</span><span class="n">kareler</span><span class="p">):</span>
    <span class="n">kareler</span> <span class="o">=</span> <span class="nf">set</span><span class="p">(</span><span class="n">kareler</span><span class="p">)</span>

    <span class="k">def</span> <span class="nf">ara</span><span class="p">(</span><span class="n">kalan</span><span class="p">):</span>
        <span class="k">if</span> <span class="ow">not</span> <span class="n">kalan</span><span class="p">:</span>
            <span class="k">return</span> <span class="bp">True</span>

        <span class="n">r</span><span class="p">,</span> <span class="n">c</span> <span class="o">=</span> <span class="nf">min</span><span class="p">(</span><span class="n">kalan</span><span class="p">)</span>
        <span class="k">for</span> <span class="n">komsu</span> <span class="ow">in</span> <span class="p">[(</span><span class="n">r</span> <span class="o">+</span> <span class="mi">1</span><span class="p">,</span> <span class="n">c</span><span class="p">),</span> <span class="p">(</span><span class="n">r</span><span class="p">,</span> <span class="n">c</span> <span class="o">+</span> <span class="mi">1</span><span class="p">)]:</span>
            <span class="k">if</span> <span class="n">komsu</span> <span class="ow">in</span> <span class="n">kalan</span><span class="p">:</span>
                <span class="n">yeni</span> <span class="o">=</span> <span class="n">kalan</span> <span class="o">-</span> <span class="p">{(</span><span class="n">r</span><span class="p">,</span> <span class="n">c</span><span class="p">),</span> <span class="n">komsu</span><span class="p">}</span>
                <span class="k">if</span> <span class="nf">ara</span><span class="p">(</span><span class="n">yeni</span><span class="p">):</span>
                    <span class="k">return</span> <span class="bp">True</span>
        <span class="k">return</span> <span class="bp">False</span>

    <span class="k">return</span> <span class="nf">ara</span><span class="p">(</span><span class="n">kareler</span><span class="p">)</span>

<span class="n">bolge</span> <span class="o">=</span> <span class="p">{(</span><span class="n">r</span><span class="p">,</span> <span class="n">c</span><span class="p">)</span> <span class="k">for</span> <span class="n">r</span> <span class="ow">in</span> <span class="nf">range</span><span class="p">(</span><span class="mi">4</span><span class="p">)</span> <span class="k">for</span> <span class="n">c</span> <span class="ow">in</span> <span class="nf">range</span><span class="p">(</span><span class="mi">4</span><span class="p">)}</span>
<span class="nf">print</span><span class="p">(</span><span class="nf">kaplanabilir</span><span class="p">(</span><span class="n">bolge</span><span class="p">))</span>  <span class="c1"># True
</span></code></pre></div></div>

<p>Bu yöntem öğreticidir ancak olası yerleşimlerin sayısı hızla büyüdüğü için büyük tahtalarda pahalıdır. Önce renk dengesi gibi ucuz testleri uygulamak, ardından eşleşme algoritmasına geçmek daha akıllıcadır.</p>

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

<p>Domino kaplama problemi, basit görünen bir sorunun nasıl sayma, boyama ve graf teorisine açıldığını gösterir. En değerli ders şudur: Bazen çözümü inşa etmekten önce, çözümün neden var olamayacağını kanıtlamak çok daha kolaydır. Birkaç renk ve doğru seçilmiş bir değişmez, milyarlarca denemenin yerini tutabilir.</p>]]></content><author><name>Sonsuz Us</name></author><category term="Bilgi" /><category term="kombinatorik" /><category term="domino" /><category term="satranç tahtası" /><category term="graf teorisi" /><category term="algoritma" /><category term="python" /><summary type="html"><![CDATA[Bir satranç tahtasını boşluk bırakmadan domino taşlarıyla kaplamak ilk bakışta basit bir yapboz gibi görünür. Ancak tahtadan bazı kareler çıkarıldığında problem, kombinatoriğin en zarif sorularından birine dönüşür. Üstelik çözüm için her olasılığı denemek yerine boyama, değişmez ve graf teorisi gibi güçlü fikirlerden yararlanabiliriz.]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://program.sonsuz.us/img/domino-kaplama-problemi-91.png" /><media:content medium="image" url="https://program.sonsuz.us/img/domino-kaplama-problemi-91.png" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">Ebedi Takvim Algoritmaları: Bir Tarihin Haftanın Gününü Hesaplamak</title><link href="https://program.sonsuz.us/posts/ebedi-takvim-algoritmalari-bir-tarihin-haftanin-gununu-hesaplamak/" rel="alternate" type="text/html" title="Ebedi Takvim Algoritmaları: Bir Tarihin Haftanın Gününü Hesaplamak" /><published>2026-10-13T00:00:00+00:00</published><updated>2026-10-13T00:00:00+00:00</updated><id>https://program.sonsuz.us/posts/ebedi-takvim-algoritmalari-bir-tarihin-haftanin-gununu-hesaplamak</id><content type="html" xml:base="https://program.sonsuz.us/posts/ebedi-takvim-algoritmalari-bir-tarihin-haftanin-gununu-hesaplamak/"><![CDATA[<p>Takvim uygulamasına bakmadan 29 Ekim 1923’ün hangi güne denk geldiğini bulabilir misiniz? Ebedi takvim algoritmaları, geçmişteki veya gelecekteki bir tarihin haftanın gününü yalnızca aritmetik işlemlerle hesaplar. İşin içinde artık yıllar, ayların farklı uzunlukları ve modüler aritmetik olsa da temel fikir şaşırtıcı derecede düzenlidir.</p>

<p><img src="/img/ebedi-takvim-algoritmalari-99.svg" alt="ebedi-takvim-algoritmalari-99" /></p>

<p>``</p>

<h2 id="takvim-neden-matematikle-hesaplanabilir">Takvim neden matematikle hesaplanabilir?</h2>

<p>Hafta, yedi günde bir kendini tekrar eden döngüdür. Bu nedenle hesaplamaların kalbinde <strong>modüler aritmetik</strong> bulunur. Bir günün sayısal değerini $d$ kabul edersek sonraki gün şu şekilde yazılabilir:</p>

\[yeni\_gun = (d + 1) \bmod 7\]

<p>Örneğin pazartesiye 0 değerini verirsek 10 gün sonrası $(0+10) \bmod 7=3$, yani perşembe olur. Takvim algoritmaları da belirli bir başlangıçtan itibaren geçen günleri hesaplayıp sonucu 7’ye böler.</p>

<p>Ancak yıl uzunluğu tam olarak 365 gün değildir. Gregoryen takviminde artık yıl kuralları şöyledir:</p>

<ul>
  <li>4’e bölünen yıllar artık yıldır.</li>
  <li>100’e bölünen yıllar artık yıl değildir.</li>
  <li>400’e bölünen yıllar yeniden artık yıldır.</li>
</ul>

<p>Buna göre 2000 artık yılken 1900 değildir. Bu düzeltme, takvimin mevsimlerden uzaklaşmasını önler.</p>

<table>
  <thead>
    <tr>
      <th style="text-align: right">Yıl</th>
      <th style="text-align: center">4’e bölünür</th>
      <th style="text-align: center">100’e bölünür</th>
      <th style="text-align: center">400’e bölünür</th>
      <th>Sonuç</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td style="text-align: right">2024</td>
      <td style="text-align: center">Evet</td>
      <td style="text-align: center">Hayır</td>
      <td style="text-align: center">Hayır</td>
      <td>Artık yıl</td>
    </tr>
    <tr>
      <td style="text-align: right">1900</td>
      <td style="text-align: center">Evet</td>
      <td style="text-align: center">Evet</td>
      <td style="text-align: center">Hayır</td>
      <td>Normal yıl</td>
    </tr>
    <tr>
      <td style="text-align: right">2000</td>
      <td style="text-align: center">Evet</td>
      <td style="text-align: center">Evet</td>
      <td style="text-align: center">Evet</td>
      <td>Artık yıl</td>
    </tr>
    <tr>
      <td style="text-align: right">2023</td>
      <td style="text-align: center">Hayır</td>
      <td style="text-align: center">Hayır</td>
      <td style="text-align: center">Hayır</td>
      <td>Normal yıl</td>
    </tr>
  </tbody>
</table>

<h2 id="zeller-bağıntısı">Zeller bağıntısı</h2>

<p>En tanınmış ebedi takvim yöntemlerinden biri <strong>Zeller bağıntısıdır</strong>. Gregoryen takvimi için formül şöyledir:</p>

\[h=\left(q+\left\lfloor\frac{13(m+1)}{5}\right\rfloor+K+\left\lfloor\frac{K}{4}\right\rfloor+\left\lfloor\frac{J}{4}\right\rfloor+5J\right)\bmod 7\]

<p>Buradaki değişkenler:</p>

<table>
  <thead>
    <tr>
      <th>Sembol</th>
      <th>Anlamı</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>$q$</td>
      <td>Ayın günü</td>
    </tr>
    <tr>
      <td>$m$</td>
      <td>Ay numarası; mart 3, …, aralık 12, ocak 13, şubat 14</td>
    </tr>
    <tr>
      <td>$K$</td>
      <td>Yılın yüzyıl içindeki kısmı: $y \bmod 100$</td>
    </tr>
    <tr>
      <td>$J$</td>
      <td>Sıfır tabanlı yüzyıl: $\lfloor y/100 \rfloor$</td>
    </tr>
    <tr>
      <td>$h$</td>
      <td>Haftanın günü; 0 cumartesi, 1 pazar, …, 6 cuma</td>
    </tr>
  </tbody>
</table>

<p>Buradaki küçük numara hilesi önemlidir: Ocak ve şubat, önceki yılın 13. ve 14. ayı sayılır. Böylece artık gün düzeltmesi formüle daha doğal biçimde katılır. Örneğin Şubat 2024 hesaplanırken yıl 2023 kabul edilir.</p>

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

<p>Aşağıdaki fonksiyon formülü doğrudan uygular ve sayısal sonucu okunabilir bir gün adına dönüştürür:</p>

<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">def</span> <span class="nf">haftanin_gunu</span><span class="p">(</span><span class="n">gun</span><span class="p">,</span> <span class="n">ay</span><span class="p">,</span> <span class="n">yil</span><span class="p">):</span>
    <span class="c1"># Zeller'de ocak ve şubat önceki yılın aylarıdır.
</span>    <span class="k">if</span> <span class="n">ay</span> <span class="o">&lt;</span> <span class="mi">3</span><span class="p">:</span>
        <span class="n">ay</span> <span class="o">+=</span> <span class="mi">12</span>
        <span class="n">yil</span> <span class="o">-=</span> <span class="mi">1</span>

    <span class="n">K</span> <span class="o">=</span> <span class="n">yil</span> <span class="o">%</span> <span class="mi">100</span>
    <span class="n">J</span> <span class="o">=</span> <span class="n">yil</span> <span class="o">//</span> <span class="mi">100</span>

    <span class="n">h</span> <span class="o">=</span> <span class="p">(</span>
        <span class="n">gun</span>
        <span class="o">+</span> <span class="p">(</span><span class="mi">13</span> <span class="o">*</span> <span class="p">(</span><span class="n">ay</span> <span class="o">+</span> <span class="mi">1</span><span class="p">))</span> <span class="o">//</span> <span class="mi">5</span>
        <span class="o">+</span> <span class="n">K</span>
        <span class="o">+</span> <span class="n">K</span> <span class="o">//</span> <span class="mi">4</span>
        <span class="o">+</span> <span class="n">J</span> <span class="o">//</span> <span class="mi">4</span>
        <span class="o">+</span> <span class="mi">5</span> <span class="o">*</span> <span class="n">J</span>
    <span class="p">)</span> <span class="o">%</span> <span class="mi">7</span>

    <span class="n">gunler</span> <span class="o">=</span> <span class="p">[</span>
        <span class="sh">"</span><span class="s">Cumartesi</span><span class="sh">"</span><span class="p">,</span> <span class="sh">"</span><span class="s">Pazar</span><span class="sh">"</span><span class="p">,</span> <span class="sh">"</span><span class="s">Pazartesi</span><span class="sh">"</span><span class="p">,</span> <span class="sh">"</span><span class="s">Salı</span><span class="sh">"</span><span class="p">,</span>
        <span class="sh">"</span><span class="s">Çarşamba</span><span class="sh">"</span><span class="p">,</span> <span class="sh">"</span><span class="s">Perşembe</span><span class="sh">"</span><span class="p">,</span> <span class="sh">"</span><span class="s">Cuma</span><span class="sh">"</span>
    <span class="p">]</span>
    <span class="k">return</span> <span class="n">gunler</span><span class="p">[</span><span class="n">h</span><span class="p">]</span>

<span class="nf">print</span><span class="p">(</span><span class="nf">haftanin_gunu</span><span class="p">(</span><span class="mi">29</span><span class="p">,</span> <span class="mi">10</span><span class="p">,</span> <span class="mi">1923</span><span class="p">))</span>  <span class="c1"># Pazartesi
</span><span class="nf">print</span><span class="p">(</span><span class="nf">haftanin_gunu</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">2000</span><span class="p">))</span>    <span class="c1"># Cumartesi
</span></code></pre></div></div>

<p>Tam sayı bölmesi için <code class="language-plaintext highlighter-rouge">//</code> kullanılması kritiktir; formüldeki taban fonksiyonu $\lfloor x \rfloor$, ondalık kısmın atılmasını ister. <code class="language-plaintext highlighter-rouge">% 7</code> işlemi ise büyük toplamı haftanın yedi olası gününden birine indirger.</p>

<h2 id="hangi-yaklaşım-ne-zaman-kullanılmalı">Hangi yaklaşım ne zaman kullanılmalı?</h2>

<table>
  <thead>
    <tr>
      <th>Yaklaşım</th>
      <th>Avantaj</th>
      <th>Dezavantaj</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Zeller bağıntısı</td>
      <td>Hızlı, sabit zamanlı ve öğretici</td>
      <td>Ay numaralandırması alışılmadık</td>
    </tr>
    <tr>
      <td>Günleri tek tek saymak</td>
      <td>Mantığı kolay anlaşılır</td>
      <td>Uzak tarihlerde verimsiz</td>
    </tr>
    <tr>
      <td>Dilin tarih kütüphanesi</td>
      <td>Güvenilir ve pratiktir</td>
      <td>Matematiksel süreci gizler</td>
    </tr>
  </tbody>
</table>

<p>Algoritmanın çalışma süresi $O(1)$’dir; tarih ne kadar uzak olursa olsun yalnızca birkaç aritmetik işlem yapılır. Yine de tarihsel tarihlerde dikkat gerekir: Bu formül <strong>ileriye ve geriye uzatılmış Gregoryen takvimi</strong> varsayar. Gregoryen takvimine geçilmeden önce kullanılan Jülyen takvimi veya ülkelerin farklı geçiş tarihleri hesaba katılacaksa ayrıca dönüşüm kuralları uygulanmalıdır. Kısacası ebedi takvim, matematiğin zamanı küçük bir mod 7 döngüsüne nasıl sığdırabildiğinin zarif bir örneğidir.</p>]]></content><author><name>Sonsuz Us</name></author><category term="Bilgi" /><category term="algoritma" /><category term="matematik" /><category term="takvim" /><category term="python" /><category term="zeller" /><category term="tarih-hesaplama" /><summary type="html"><![CDATA[Takvim uygulamasına bakmadan 29 Ekim 1923’ün hangi güne denk geldiğini bulabilir misiniz? Ebedi takvim algoritmaları, geçmişteki veya gelecekteki bir tarihin haftanın gününü yalnızca aritmetik işlemlerle hesaplar. İşin içinde artık yıllar, ayların farklı uzunlukları ve modüler aritmetik olsa da temel fikir şaşırtıcı derecede düzenlidir.]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://program.sonsuz.us/img/ebedi-takvim-algoritmalari-99.png" /><media:content medium="image" url="https://program.sonsuz.us/img/ebedi-takvim-algoritmalari-99.png" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">kD-Ağaçlarla Çok Boyutlu Yakın Komşu Araması</title><link href="https://program.sonsuz.us/posts/kd-agaclarla-cok-boyutlu-yakin-komsu-aramasi/" rel="alternate" type="text/html" title="kD-Ağaçlarla Çok Boyutlu Yakın Komşu Araması" /><published>2026-10-13T00:00:00+00:00</published><updated>2026-10-13T00:00:00+00:00</updated><id>https://program.sonsuz.us/posts/kd-agaclarla-cok-boyutlu-yakin-komsu-aramasi</id><content type="html" xml:base="https://program.sonsuz.us/posts/kd-agaclarla-cok-boyutlu-yakin-komsu-aramasi/"><![CDATA[<p><img src="/img/kd-agaclarla-cok-42.svg" alt="kd-agaclarla-cok-42" /></p>

<p>Bir haritadaki en yakın kafeyi, renk uzayındaki en benzer tonu veya oyun dünyasında karaktere en yakın nesneyi bulmak istediğinizi düşünün. Tüm noktaları tek tek karşılaştırmak kolaydır; ancak veri büyüdüğünde işlem kısa sürede kaplumbağa hızına iner. kD-ağacı, çok boyutlu noktaları akıllıca bölerek arama sırasında ilgisiz bölgeleri elememizi sağlayan uzamsal bir veri yapısıdır.</p>

<p>``</p>

<h2 id="kd-ağacının-temel-fikri">kD-ağacının temel fikri</h2>

<p>Buradaki <strong>k</strong>, noktaların boyut sayısını ifade eder. İki boyutlu bir nokta $(x,y)$, üç boyutlu bir nokta $(x,y,z)$ biçimindedir. Ağaç oluşturulurken her seviyede farklı bir eksen kullanılır. Örneğin iki boyutta kök düğüm $x$ eksenine, çocukları $y$ eksenine, sonraki seviye yeniden $x$ eksenine göre ayrılır.</p>

<p>Derinliği $d$ olan bir düğümün bölme ekseni şöyle seçilebilir:</p>

\[eksen = d \bmod k\]

<p>Dengeli bir ağaç kurmak için noktalar ilgili eksene göre sıralanır ve ortanca nokta düğüm yapılır. Ortancadan küçük değerler sol, büyük değerler sağ alt ağaca gider. Böylece uzay, iç içe geçmiş dikdörtgensel bölgelere ayrılır.</p>

<table>
  <thead>
    <tr>
      <th>Yaklaşım</th>
      <th style="text-align: right">Kurulum</th>
      <th style="text-align: right">Ortalama sorgu</th>
      <th>Güçlü yanı</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Doğrusal tarama</td>
      <td style="text-align: right">$O(1)$</td>
      <td style="text-align: right">$O(n)$</td>
      <td>Basit ve küçük veride etkili</td>
    </tr>
    <tr>
      <td>Dengeli kD-ağacı</td>
      <td style="text-align: right">$O(n\log n)$</td>
      <td style="text-align: right">Yaklaşık $O(\log n)$</td>
      <td>Düşük boyutlarda hızlı</td>
    </tr>
    <tr>
      <td>Hash tablosu</td>
      <td style="text-align: right">$O(n)$</td>
      <td style="text-align: right">Yaklaşık $O(1)$</td>
      <td>Tam eşleşmede başarılı</td>
    </tr>
  </tbody>
</table>

<p>Hash tablosu yakınlık kavramını doğal olarak desteklemez. kD-ağacının avantajı ise geometrik uzaklıktan yararlanmasıdır. Öklid uzaklığının karesi hesaplanarak gereksiz karekök işleminden kaçınılabilir:</p>

\[d^2(p,q)=\sum_{i=1}^{k}(p_i-q_i)^2\]

<h2 id="python-ile-ağacı-oluşturalım">Python ile ağacı oluşturalım</h2>

<p>Aşağıdaki kod, noktaları ortanca değer çevresinde bölerek dengeli sayılabilecek bir kD-ağacı kurar:</p>

<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">class</span> <span class="nc">Node</span><span class="p">:</span>
    <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="n">self</span><span class="p">,</span> <span class="n">point</span><span class="p">,</span> <span class="n">axis</span><span class="p">,</span> <span class="n">left</span><span class="o">=</span><span class="bp">None</span><span class="p">,</span> <span class="n">right</span><span class="o">=</span><span class="bp">None</span><span class="p">):</span>
        <span class="n">self</span><span class="p">.</span><span class="n">point</span> <span class="o">=</span> <span class="n">point</span>
        <span class="n">self</span><span class="p">.</span><span class="n">axis</span> <span class="o">=</span> <span class="n">axis</span>
        <span class="n">self</span><span class="p">.</span><span class="n">left</span> <span class="o">=</span> <span class="n">left</span>
        <span class="n">self</span><span class="p">.</span><span class="n">right</span> <span class="o">=</span> <span class="n">right</span>


<span class="k">def</span> <span class="nf">build_kdtree</span><span class="p">(</span><span class="n">points</span><span class="p">,</span> <span class="n">depth</span><span class="o">=</span><span class="mi">0</span><span class="p">):</span>
    <span class="k">if</span> <span class="ow">not</span> <span class="n">points</span><span class="p">:</span>
        <span class="k">return</span> <span class="bp">None</span>

    <span class="n">k</span> <span class="o">=</span> <span class="nf">len</span><span class="p">(</span><span class="n">points</span><span class="p">[</span><span class="mi">0</span><span class="p">])</span>
    <span class="n">axis</span> <span class="o">=</span> <span class="n">depth</span> <span class="o">%</span> <span class="n">k</span>
    <span class="n">points</span> <span class="o">=</span> <span class="nf">sorted</span><span class="p">(</span><span class="n">points</span><span class="p">,</span> <span class="n">key</span><span class="o">=</span><span class="k">lambda</span> <span class="n">p</span><span class="p">:</span> <span class="n">p</span><span class="p">[</span><span class="n">axis</span><span class="p">])</span>
    <span class="n">middle</span> <span class="o">=</span> <span class="nf">len</span><span class="p">(</span><span class="n">points</span><span class="p">)</span> <span class="o">//</span> <span class="mi">2</span>

    <span class="k">return</span> <span class="nc">Node</span><span class="p">(</span>
        <span class="n">point</span><span class="o">=</span><span class="n">points</span><span class="p">[</span><span class="n">middle</span><span class="p">],</span>
        <span class="n">axis</span><span class="o">=</span><span class="n">axis</span><span class="p">,</span>
        <span class="n">left</span><span class="o">=</span><span class="nf">build_kdtree</span><span class="p">(</span><span class="n">points</span><span class="p">[:</span><span class="n">middle</span><span class="p">],</span> <span class="n">depth</span> <span class="o">+</span> <span class="mi">1</span><span class="p">),</span>
        <span class="n">right</span><span class="o">=</span><span class="nf">build_kdtree</span><span class="p">(</span><span class="n">points</span><span class="p">[</span><span class="n">middle</span> <span class="o">+</span> <span class="mi">1</span><span class="p">:],</span> <span class="n">depth</span> <span class="o">+</span> <span class="mi">1</span><span class="p">)</span>
    <span class="p">)</span>
</code></pre></div></div>

<p><code class="language-plaintext highlighter-rouge">axis</code>, düğümün uzayı hangi koordinata göre böldüğünü saklar. Her çağrıda veri iki parçaya ayrılır; bu da sonraki sorgularda bütün noktaları dolaşma ihtiyacını azaltır.</p>

<h2 id="en-yakın-komşuyu-aramak">En yakın komşuyu aramak</h2>

<p>Arama önce hedefin bulunduğu tarafa ilerler. Ardından hedef ile bölme düzlemi arasındaki fark, mevcut en iyi uzaklıktan küçükse diğer dal da incelenir. Bu adıma <strong>geri izleme</strong> denir.</p>

<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">def</span> <span class="nf">nearest</span><span class="p">(</span><span class="n">node</span><span class="p">,</span> <span class="n">target</span><span class="p">,</span> <span class="n">best</span><span class="o">=</span><span class="bp">None</span><span class="p">):</span>
    <span class="k">if</span> <span class="n">node</span> <span class="ow">is</span> <span class="bp">None</span><span class="p">:</span>
        <span class="k">return</span> <span class="n">best</span>

    <span class="n">distance</span> <span class="o">=</span> <span class="nf">sum</span><span class="p">((</span><span class="n">a</span> <span class="o">-</span> <span class="n">b</span><span class="p">)</span> <span class="o">**</span> <span class="mi">2</span>
                   <span class="k">for</span> <span class="n">a</span><span class="p">,</span> <span class="n">b</span> <span class="ow">in</span> <span class="nf">zip</span><span class="p">(</span><span class="n">node</span><span class="p">.</span><span class="n">point</span><span class="p">,</span> <span class="n">target</span><span class="p">))</span>

    <span class="k">if</span> <span class="n">best</span> <span class="ow">is</span> <span class="bp">None</span> <span class="ow">or</span> <span class="n">distance</span> <span class="o">&lt;</span> <span class="n">best</span><span class="p">[</span><span class="mi">1</span><span class="p">]:</span>
        <span class="n">best</span> <span class="o">=</span> <span class="p">(</span><span class="n">node</span><span class="p">.</span><span class="n">point</span><span class="p">,</span> <span class="n">distance</span><span class="p">)</span>

    <span class="n">axis</span> <span class="o">=</span> <span class="n">node</span><span class="p">.</span><span class="n">axis</span>
    <span class="n">difference</span> <span class="o">=</span> <span class="n">target</span><span class="p">[</span><span class="n">axis</span><span class="p">]</span> <span class="o">-</span> <span class="n">node</span><span class="p">.</span><span class="n">point</span><span class="p">[</span><span class="n">axis</span><span class="p">]</span>

    <span class="n">near</span> <span class="o">=</span> <span class="n">node</span><span class="p">.</span><span class="n">left</span> <span class="k">if</span> <span class="n">difference</span> <span class="o">&lt;</span> <span class="mi">0</span> <span class="k">else</span> <span class="n">node</span><span class="p">.</span><span class="n">right</span>
    <span class="n">far</span> <span class="o">=</span> <span class="n">node</span><span class="p">.</span><span class="n">right</span> <span class="k">if</span> <span class="n">difference</span> <span class="o">&lt;</span> <span class="mi">0</span> <span class="k">else</span> <span class="n">node</span><span class="p">.</span><span class="n">left</span>

    <span class="n">best</span> <span class="o">=</span> <span class="nf">nearest</span><span class="p">(</span><span class="n">near</span><span class="p">,</span> <span class="n">target</span><span class="p">,</span> <span class="n">best</span><span class="p">)</span>

    <span class="k">if</span> <span class="n">difference</span> <span class="o">**</span> <span class="mi">2</span> <span class="o">&lt;</span> <span class="n">best</span><span class="p">[</span><span class="mi">1</span><span class="p">]:</span>
        <span class="n">best</span> <span class="o">=</span> <span class="nf">nearest</span><span class="p">(</span><span class="n">far</span><span class="p">,</span> <span class="n">target</span><span class="p">,</span> <span class="n">best</span><span class="p">)</span>

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


<span class="n">points</span> <span class="o">=</span> <span class="p">[(</span><span class="mi">2</span><span class="p">,</span> <span class="mi">3</span><span class="p">),</span> <span class="p">(</span><span class="mi">5</span><span class="p">,</span> <span class="mi">4</span><span class="p">),</span> <span class="p">(</span><span class="mi">9</span><span class="p">,</span> <span class="mi">6</span><span class="p">),</span> <span class="p">(</span><span class="mi">4</span><span class="p">,</span> <span class="mi">7</span><span class="p">),</span> <span class="p">(</span><span class="mi">8</span><span class="p">,</span> <span class="mi">1</span><span class="p">),</span> <span class="p">(</span><span class="mi">7</span><span class="p">,</span> <span class="mi">2</span><span class="p">)]</span>
<span class="n">tree</span> <span class="o">=</span> <span class="nf">build_kdtree</span><span class="p">(</span><span class="n">points</span><span class="p">)</span>
<span class="n">point</span><span class="p">,</span> <span class="n">squared_distance</span> <span class="o">=</span> <span class="nf">nearest</span><span class="p">(</span><span class="n">tree</span><span class="p">,</span> <span class="p">(</span><span class="mi">6</span><span class="p">,</span> <span class="mi">3</span><span class="p">))</span>
<span class="nf">print</span><span class="p">(</span><span class="n">point</span><span class="p">,</span> <span class="n">squared_distance</span><span class="p">)</span>
</code></pre></div></div>

<p>Kritik koşul <code class="language-plaintext highlighter-rouge">difference ** 2 &lt; best[1]</code> ifadesidir. Bölme düzlemi mevcut adaydan daha uzaktaysa karşı tarafta daha iyi bir nokta bulunamaz; dolayısıyla o dal budanır.</p>

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

<p>kD-ağaçları harita uygulamaları, çarpışma tespiti ve düşük boyutlu makine öğrenmesi verileri için uygundur. Ancak boyut sayısı yükseldikçe bölgeler birbirine benzemeye başlar ve daha az dal elenir. “Boyutluluk laneti” olarak bilinen bu durumda sorgu maliyeti yeniden $O(n)$ seviyesine yaklaşabilir. Çok yüksek boyutlarda yaklaşık komşu arama algoritmaları daha iyi bir seçimdir; fakat iki veya üç boyutlu dünyalarda kD-ağacı hâlâ oldukça çevik bir rehberdir.</p>]]></content><author><name>Sonsuz Us</name></author><category term="Proje" /><category term="kd-ağacı" /><category term="python" /><category term="algoritma" /><category term="veri-yapıları" /><category term="uzamsal-arama" /><category term="yakın-komşu" /><summary type="html"><![CDATA[Bir haritadaki en yakın kafeyi, renk uzayındaki en benzer tonu veya oyun dünyasında karaktere en yakın nesneyi bulmak istediğinizi düşünün. Tüm noktaları tek tek karşılaştırmak kolaydır; ancak veri büyüdüğünde işlem kısa sürede kaplumbağa hızına iner. kD-ağacı, çok boyutlu noktaları akıllıca bölerek arama sırasında ilgisiz bölgeleri elememizi sağlayan uzamsal bir veri yapısıdır.]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://program.sonsuz.us/img/kd-agaclarla-cok-42.png" /><media:content medium="image" url="https://program.sonsuz.us/img/kd-agaclarla-cok-42.png" xmlns:media="http://search.yahoo.com/mrss/" /></entry></feed>