<?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-11T06:05:41+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">Catalan Sayıları: Parantezlerden İkili Ağaçlara Uzanan Sayma Macerası</title><link href="https://program.sonsuz.us/posts/catalan-sayilari-parantezlerden-ikili-agaclara-uzanan-sayma-macerasi/" rel="alternate" type="text/html" title="Catalan Sayıları: Parantezlerden İkili Ağaçlara Uzanan Sayma Macerası" /><published>2026-10-11T00:00:00+00:00</published><updated>2026-10-11T00:00:00+00:00</updated><id>https://program.sonsuz.us/posts/catalan-sayilari-parantezlerden-ikili-agaclara-uzanan-sayma-macerasi</id><content type="html" xml:base="https://program.sonsuz.us/posts/catalan-sayilari-parantezlerden-ikili-agaclara-uzanan-sayma-macerasi/"><![CDATA[<p>Bazı sayı dizileri matematiğin gizli aktörleri gibidir: Farklı görünen problemlerde tekrar tekrar sahneye çıkarlar. Catalan sayıları da dengeli parantezlerden çokgenlere, ikili arama ağaçlarından dağ yollarına kadar şaşırtıcı sayıda yapıyı sayar. İlk terimleri $1, 1, 2, 5, 14, 42, 132$ olan bu dizi, “Kaç farklı geçerli yapı oluşturabilirim?” sorusunun en renkli cevaplarından biridir.
``</p>

<h2 id="catalan-sayısının-matematiksel-tanımı">Catalan sayısının matematiksel tanımı</h2>

<p>Sıfırıncı Catalan sayısı $C_0=1$ kabul edilir. Genel formül şöyledir:</p>

\[C_n = \frac{1}{n+1}\binom{2n}{n} = \frac{(2n)!}{(n+1)!n!}\]

<p>Buradaki merkezi binom katsayısı, $2n$ konum içinden $n$ tanesini seçer. Ancak seçilen her dizilim geçerli değildir. Örneğin açılan parantez sayısının hiçbir noktada kapanan parantez sayısından az olmaması gerekir. Formüldeki $n+1$ bölümü, bu geçersiz düzenlemeleri ayıklayan kombinatorik düzeltmedir.</p>

<p>Catalan sayıları özyinelemeli olarak da hesaplanabilir:</p>

\[C_{n+1}=\sum_{i=0}^{n} C_iC_{n-i}\]

<p>Bu bağıntının arkasındaki fikir bölüp birleştirmedir. Bir yapı kökünden iki parçaya ayrılıyorsa sol tarafta $i$, sağ tarafta $n-i$ eleman bulunabilir. Olasılıkların çarpılması ve bütün bölünmelerin toplanması Catalan sonucunu verir.</p>

<table>
  <thead>
    <tr>
      <th style="text-align: right">$n$</th>
      <th style="text-align: right">$C_n$</th>
      <th style="text-align: right">Dengeli parantez çifti sayısı</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td style="text-align: right">0</td>
      <td style="text-align: right">1</td>
      <td style="text-align: right">Boş dizi</td>
    </tr>
    <tr>
      <td style="text-align: right">1</td>
      <td style="text-align: right">1</td>
      <td style="text-align: right"><code class="language-plaintext highlighter-rouge">()</code></td>
    </tr>
    <tr>
      <td style="text-align: right">2</td>
      <td style="text-align: right">2</td>
      <td style="text-align: right"><code class="language-plaintext highlighter-rouge">(())</code>, <code class="language-plaintext highlighter-rouge">()()</code></td>
    </tr>
    <tr>
      <td style="text-align: right">3</td>
      <td style="text-align: right">5</td>
      <td style="text-align: right">Beş farklı dizilim</td>
    </tr>
    <tr>
      <td style="text-align: right">4</td>
      <td style="text-align: right">14</td>
      <td style="text-align: right">On dört farklı dizilim</td>
    </tr>
  </tbody>
</table>

<h2 id="dengeli-parantezler-neden-catalan-sayısıdır">Dengeli parantezler neden Catalan sayısıdır?</h2>

<p>$n$ çift açma ve kapama parantezi içeren bir dizide toplam $2n$ karakter vardır. Geçerli bir dizilim iki kurala uyar:</p>

<ol>
  <li>Toplam açma ve kapama parantezi sayıları eşittir.</li>
  <li>Soldan sağa ilerlerken kapanan parantez sayısı, açılanlardan fazla olamaz.</li>
</ol>

<p>Örneğin <code class="language-plaintext highlighter-rouge">(()())</code> geçerliyken <code class="language-plaintext highlighter-rouge">())(()</code> geçersizdir. İkinci dizi toplamda eşit sayıda parantez içerse bile üçüncü karakterde henüz açılmamış bir parantezi kapatmaya çalışır. Matematik bile “Önce aç, sonra kapat!” der.</p>

<h2 id="i̇kili-ağaçlarla-bağlantısı">İkili ağaçlarla bağlantısı</h2>

<p>$n$ düğümlü farklı ikili ağaç biçimlerinin sayısı da $C_n$ değeridir. Kök düğümü seçtikten sonra kalan düğümler sol ve sağ alt ağaçlar arasında dağıtılır. Sol alt ağaçta $i$ düğüm varsa sağ tarafta $n-1-i$ düğüm bulunur.</p>

<table>
  <thead>
    <tr>
      <th>Problem</th>
      <th>Ayrıştırma biçimi</th>
      <th style="text-align: right">Sonuç</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Dengeli parantez</td>
      <td>Dış parantezin içi ve sonrası</td>
      <td style="text-align: right">$C_n$</td>
    </tr>
    <tr>
      <td>İkili ağaç</td>
      <td>Sol ve sağ alt ağaç</td>
      <td style="text-align: right">$C_n$</td>
    </tr>
    <tr>
      <td>Çokgen üçgenleme</td>
      <td>Seçilen üçgenin iki yanı</td>
      <td style="text-align: right">$C_{n-2}$</td>
    </tr>
    <tr>
      <td>Izgara yolu</td>
      <td>Köşegeni aşmayan yollar</td>
      <td style="text-align: right">$C_n$</td>
    </tr>
  </tbody>
</table>

<p>Aynı sayıların ortaya çıkmasının nedeni, bu problemlerin yüzeyde farklı olsa da aynı özyinelemeli bölünme yapısını taşımasıdır.</p>

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

<p>Aşağıdaki dinamik programlama yaklaşımı, özyinelemeli bağıntıyı kullanır. <code class="language-plaintext highlighter-rouge">dp[k]</code>, $k$ boyutundaki yapıların sayısını saklar:</p>

<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">def</span> <span class="nf">catalan</span><span class="p">(</span><span class="n">n</span><span class="p">):</span>
    <span class="n">dp</span> <span class="o">=</span> <span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">*</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">dp</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">=</span> <span class="mi">1</span>

    <span class="k">for</span> <span class="n">boyut</span> <span class="ow">in</span> <span class="nf">range</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="n">n</span> <span class="o">+</span> <span class="mi">1</span><span class="p">):</span>
        <span class="k">for</span> <span class="n">sol</span> <span class="ow">in</span> <span class="nf">range</span><span class="p">(</span><span class="n">boyut</span><span class="p">):</span>
            <span class="n">sag</span> <span class="o">=</span> <span class="n">boyut</span> <span class="o">-</span> <span class="mi">1</span> <span class="o">-</span> <span class="n">sol</span>
            <span class="n">dp</span><span class="p">[</span><span class="n">boyut</span><span class="p">]</span> <span class="o">+=</span> <span class="n">dp</span><span class="p">[</span><span class="n">sol</span><span class="p">]</span> <span class="o">*</span> <span class="n">dp</span><span class="p">[</span><span class="n">sag</span><span class="p">]</span>

    <span class="k">return</span> <span class="n">dp</span><span class="p">[</span><span class="n">n</span><span class="p">]</span>

<span class="nf">print</span><span class="p">([</span><span class="nf">catalan</span><span class="p">(</span><span class="n">i</span><span class="p">)</span> <span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nf">range</span><span class="p">(</span><span class="mi">8</span><span class="p">)])</span>
<span class="c1"># [1, 1, 2, 5, 14, 42, 132, 429]
</span></code></pre></div></div>

<p>Algoritmanın zaman karmaşıklığı $O(n^2)$, alan karmaşıklığı ise $O(n)$ olur. Yalnızca tek bir $C_n$ değeri gerekiyorsa faktöriyel formülü daha hızlı olabilir; dinamik programlama ise dizinin tüm ara terimlerini üretmek ve mantığı görmek için daha öğreticidir.</p>

<p>Catalan sayıları, farklı problemlerin ortak matematiksel iskeletini fark etmenin harika bir örneğidir. Bir soruda dengeli parantez, ikili ağaç, köşegeni aşmayan yol veya çokgen üçgenleme görürseniz, sahne arkasında bir Catalan sayısının kostümünü giymekte olabileceğini unutmayın.</p>

<p><img src="/img/catalan-sayilari-parantezlerden-39.svg" alt="catalan-sayilari-parantezlerden-39" /></p>]]></content><author><name>Sonsuz Us</name></author><category term="Bilgi" /><category term="catalan sayıları" /><category term="kombinatorik" /><category term="algoritma" /><category term="dinamik programlama" /><category term="ikili ağaç" /><category term="python" /><summary type="html"><![CDATA[Bazı sayı dizileri matematiğin gizli aktörleri gibidir: Farklı görünen problemlerde tekrar tekrar sahneye çıkarlar. Catalan sayıları da dengeli parantezlerden çokgenlere, ikili arama ağaçlarından dağ yollarına kadar şaşırtıcı sayıda yapıyı sayar. İlk terimleri $1, 1, 2, 5, 14, 42, 132$ olan bu dizi, “Kaç farklı geçerli yapı oluşturabilirim?” sorusunun en renkli cevaplarından biridir.]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://program.sonsuz.us/img/catalan-sayilari-parantezlerden-39.png" /><media:content medium="image" url="https://program.sonsuz.us/img/catalan-sayilari-parantezlerden-39.png" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">K-Elemanlı Alt Kümeleri Sistematik Olarak Üretme</title><link href="https://program.sonsuz.us/posts/k-elemanli-alt-kumeleri-sistematik-olarak-uretme/" rel="alternate" type="text/html" title="K-Elemanlı Alt Kümeleri Sistematik Olarak Üretme" /><published>2026-10-11T00:00:00+00:00</published><updated>2026-10-11T00:00:00+00:00</updated><id>https://program.sonsuz.us/posts/k-elemanli-alt-kumeleri-sistematik-olarak-uretme</id><content type="html" xml:base="https://program.sonsuz.us/posts/k-elemanli-alt-kumeleri-sistematik-olarak-uretme/"><![CDATA[<p>Bir kümeden tam olarak $k$ eleman seçmenin kaç farklı yolu olduğunu bilmek kolaydır; asıl eğlence, bu seçimlerin tamamını eksiksiz, tekrarsız ve belirli bir sırada üretmekle başlar. Kombinasyon üretimi; arama algoritmalarından test verisi hazırlamaya, takım oluşturmadan özellik seçimine kadar pek çok alanda karşımıza çıkar. Bu yazıda k-elemanlı alt kümeleri üretmenin üç sistematik yöntemini inceleyeceğiz.</p>

<p>``</p>

<h2 id="önce-matematik-kaç-sonuç-bekliyoruz">Önce matematik: Kaç sonuç bekliyoruz?</h2>

<p>$n$ elemanlı bir kümenin $k$ elemanlı alt kümelerinin sayısı binom katsayısıyla hesaplanır:</p>

\[{n \choose k}=\frac{n!}{k!(n-k)!}\]

<p>Örneğin $A={a,b,c,d}$ ve $k=2$ için toplam sonuç sayısı</p>

\[{4 \choose 2}=6\]

<p>olur. Üretilecek alt kümeler şunlardır: ${a,b}$, ${a,c}$, ${a,d}$, ${b,c}$, ${b,d}$ ve ${c,d}$.</p>

<p>Bir algoritmanın doğru olduğunu sınarken bu formül iyi bir kontrol mekanizmasıdır. Algoritma tam olarak ${n \choose k}$ sonuç vermeli ve hiçbir sonucu iki kez üretmemelidir.</p>

<h2 id="1-özyinelemeli-geri-izleme">1. Özyinelemeli geri izleme</h2>

<p>En anlaşılır yaklaşım, her adımda bir elemanı seçip seçmemeye karar vermektir. Ancak yalnızca seçme dalını açıkça dolaşarak gereksiz adımları azaltabiliriz.</p>

<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">def</span> <span class="nf">kombinasyonlar</span><span class="p">(</span><span class="n">elemanlar</span><span class="p">,</span> <span class="n">k</span><span class="p">):</span>
    <span class="n">sonuc</span> <span class="o">=</span> <span class="p">[]</span>

    <span class="k">def</span> <span class="nf">ara</span><span class="p">(</span><span class="n">baslangic</span><span class="p">,</span> <span class="n">secilenler</span><span class="p">):</span>
        <span class="c1"># İstenen büyüklüğe ulaştığımızda kopyayı kaydet.
</span>        <span class="k">if</span> <span class="nf">len</span><span class="p">(</span><span class="n">secilenler</span><span class="p">)</span> <span class="o">==</span> <span class="n">k</span><span class="p">:</span>
            <span class="n">sonuc</span><span class="p">.</span><span class="nf">append</span><span class="p">(</span><span class="n">secilenler</span><span class="p">.</span><span class="nf">copy</span><span class="p">())</span>
            <span class="k">return</span>

        <span class="n">gereken</span> <span class="o">=</span> <span class="n">k</span> <span class="o">-</span> <span class="nf">len</span><span class="p">(</span><span class="n">secilenler</span><span class="p">)</span>
        <span class="n">son_indeks</span> <span class="o">=</span> <span class="nf">len</span><span class="p">(</span><span class="n">elemanlar</span><span class="p">)</span> <span class="o">-</span> <span class="n">gereken</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">baslangic</span><span class="p">,</span> <span class="n">son_indeks</span> <span class="o">+</span> <span class="mi">1</span><span class="p">):</span>
            <span class="n">secilenler</span><span class="p">.</span><span class="nf">append</span><span class="p">(</span><span class="n">elemanlar</span><span class="p">[</span><span class="n">i</span><span class="p">])</span>
            <span class="nf">ara</span><span class="p">(</span><span class="n">i</span> <span class="o">+</span> <span class="mi">1</span><span class="p">,</span> <span class="n">secilenler</span><span class="p">)</span>
            <span class="n">secilenler</span><span class="p">.</span><span class="nf">pop</span><span class="p">()</span>  <span class="c1"># Geri dön ve başka adayı dene.
</span>
    <span class="nf">ara</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="p">[])</span>
    <span class="k">return</span> <span class="n">sonuc</span>

<span class="nf">print</span><span class="p">(</span><span class="nf">kombinasyonlar</span><span class="p">([</span><span class="sh">"</span><span class="s">a</span><span class="sh">"</span><span class="p">,</span> <span class="sh">"</span><span class="s">b</span><span class="sh">"</span><span class="p">,</span> <span class="sh">"</span><span class="s">c</span><span class="sh">"</span><span class="p">,</span> <span class="sh">"</span><span class="s">d</span><span class="sh">"</span><span class="p">],</span> <span class="mi">2</span><span class="p">))</span>
</code></pre></div></div>

<p><code class="language-plaintext highlighter-rouge">baslangic</code> değeri, daha önce kullanılan elemanlara geri dönülmesini engeller. Böylece hem tekrar oluşmaz hem de kombinasyonlar sözlük sırasına benzer bir düzende üretilir. <code class="language-plaintext highlighter-rouge">son_indeks</code> hesabı ise geride yeterli eleman kalmadığı bilinen dalları budar.</p>

<h2 id="2-i̇ndeksleri-sözlük-sırasıyla-ilerletmek">2. İndeksleri sözlük sırasıyla ilerletmek</h2>

<p>Bir kombinasyonu elemanların kendisi yerine indeks dizisiyle temsil edebiliriz. Örneğin <code class="language-plaintext highlighter-rouge">[0, 1, 3]</code>, kümenin birinci, ikinci ve dördüncü elemanlarını seçer. Her turda sağdan başlayarak artırılabilecek ilk indeks bulunur.</p>

<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">def</span> <span class="nf">sirali_k_alt_kumeler</span><span class="p">(</span><span class="n">veri</span><span class="p">,</span> <span class="n">k</span><span class="p">):</span>
    <span class="n">n</span> <span class="o">=</span> <span class="nf">len</span><span class="p">(</span><span class="n">veri</span><span class="p">)</span>
    <span class="k">if</span> <span class="n">k</span> <span class="o">&lt;</span> <span class="mi">0</span> <span class="ow">or</span> <span class="n">k</span> <span class="o">&gt;</span> <span class="n">n</span><span class="p">:</span>
        <span class="k">return</span>

    <span class="n">indeksler</span> <span class="o">=</span> <span class="nf">list</span><span class="p">(</span><span class="nf">range</span><span class="p">(</span><span class="n">k</span><span class="p">))</span>

    <span class="k">while</span> <span class="bp">True</span><span class="p">:</span>
        <span class="k">yield</span> <span class="p">[</span><span class="n">veri</span><span class="p">[</span><span class="n">i</span><span class="p">]</span> <span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="n">indeksler</span><span class="p">]</span>

        <span class="n">i</span> <span class="o">=</span> <span class="n">k</span> <span class="o">-</span> <span class="mi">1</span>
        <span class="k">while</span> <span class="n">i</span> <span class="o">&gt;=</span> <span class="mi">0</span> <span class="ow">and</span> <span class="n">indeksler</span><span class="p">[</span><span class="n">i</span><span class="p">]</span> <span class="o">==</span> <span class="n">i</span> <span class="o">+</span> <span class="n">n</span> <span class="o">-</span> <span class="n">k</span><span class="p">:</span>
            <span class="n">i</span> <span class="o">-=</span> <span class="mi">1</span>

        <span class="k">if</span> <span class="n">i</span> <span class="o">&lt;</span> <span class="mi">0</span><span class="p">:</span>
            <span class="k">return</span>

        <span class="n">indeksler</span><span class="p">[</span><span class="n">i</span><span class="p">]</span> <span class="o">+=</span> <span class="mi">1</span>
        <span class="k">for</span> <span class="n">j</span> <span class="ow">in</span> <span class="nf">range</span><span class="p">(</span><span class="n">i</span> <span class="o">+</span> <span class="mi">1</span><span class="p">,</span> <span class="n">k</span><span class="p">):</span>
            <span class="n">indeksler</span><span class="p">[</span><span class="n">j</span><span class="p">]</span> <span class="o">=</span> <span class="n">indeksler</span><span class="p">[</span><span class="n">j</span> <span class="o">-</span> <span class="mi">1</span><span class="p">]</span> <span class="o">+</span> <span class="mi">1</span>
</code></pre></div></div>

<p>Bu sürüm <code class="language-plaintext highlighter-rouge">yield</code> kullandığı için tüm sonuçları bellekte tutmaz. Büyük veri kümelerinde yalnızca sıradaki kombinasyona ihtiyaç duyulduğunda oldukça kullanışlıdır.</p>

<h2 id="3-bit-maskesi-yaklaşımı">3. Bit maskesi yaklaşımı</h2>

<p>Her elemanı bir bit ile temsil edebiliriz: <code class="language-plaintext highlighter-rouge">1</code> seçildiğini, <code class="language-plaintext highlighter-rouge">0</code> seçilmediğini gösterir. Örneğin <code class="language-plaintext highlighter-rouge">10110</code> maskesi üç eleman seçer. Dolayısıyla yalnızca içinde tam $k$ tane <code class="language-plaintext highlighter-rouge">1</code> bulunan maskeler kabul edilir.</p>

<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">def</span> <span class="nf">bitmask_kombinasyonlari</span><span class="p">(</span><span class="n">veri</span><span class="p">,</span> <span class="n">k</span><span class="p">):</span>
    <span class="n">n</span> <span class="o">=</span> <span class="nf">len</span><span class="p">(</span><span class="n">veri</span><span class="p">)</span>
    <span class="k">for</span> <span class="n">maske</span> <span class="ow">in</span> <span class="nf">range</span><span class="p">(</span><span class="mi">1</span> <span class="o">&lt;&lt;</span> <span class="n">n</span><span class="p">):</span>
        <span class="k">if</span> <span class="n">maske</span><span class="p">.</span><span class="nf">bit_count</span><span class="p">()</span> <span class="o">==</span> <span class="n">k</span><span class="p">:</span>
            <span class="k">yield</span> <span class="p">[</span><span class="n">veri</span><span class="p">[</span><span class="n">i</span><span class="p">]</span> <span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nf">range</span><span class="p">(</span><span class="n">n</span><span class="p">)</span> <span class="k">if</span> <span class="n">maske</span> <span class="o">&amp;</span> <span class="p">(</span><span class="mi">1</span> <span class="o">&lt;&lt;</span> <span class="n">i</span><span class="p">)]</span>
</code></pre></div></div>

<p>Kod son derece kısa olsa da $0$ ile $2^n-1$ arasındaki bütün maskeleri inceler. Bu nedenle özellikle $k$, $n$ değerine göre küçükken çok sayıda gereksiz maske kontrol edilir.</p>

<h2 id="yöntemlerin-karşılaştırması">Yöntemlerin karşılaştırması</h2>

<table>
  <thead>
    <tr>
      <th>Yöntem</th>
      <th style="text-align: right">Üretim maliyeti</th>
      <th style="text-align: right">Ek bellek</th>
      <th>Güçlü yönü</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Geri izleme</td>
      <td style="text-align: right">$O(k{n \choose k})$</td>
      <td style="text-align: right">$O(k)$</td>
      <td>Kolay uyarlanır ve budanabilir</td>
    </tr>
    <tr>
      <td>İndeks ilerletme</td>
      <td style="text-align: right">$O(k{n \choose k})$</td>
      <td style="text-align: right">$O(k)$</td>
      <td>Tembel ve sıralı üretim sağlar</td>
    </tr>
    <tr>
      <td>Bit maskesi</td>
      <td style="text-align: right">$O(n2^n)$</td>
      <td style="text-align: right">$O(k)$</td>
      <td>Basit, düşük seviyeli işlemlere uygun</td>
    </tr>
  </tbody>
</table>

<p><img src="/img/k-elemanli-alt-29.svg" alt="k-elemanli-alt-29" /></p>

<p>Pratikte genel amaçlı kullanım için indeks ilerletme yöntemi iyi bir dengedir. Seçimlere özel kurallar eklenecekse geri izleme daha esnektir. Bit maskesi ise küçük kümelerde, bit düzeyindeki temsiller zaten problemin parçasıysa parlamaya başlar. Hangi yolu seçerseniz seçin, sonuç sayısını ${n \choose k}$ ile doğrulamak algoritmik pusulanız olacaktır.</p>]]></content><author><name>Sonsuz Us</name></author><category term="Program" /><category term="algoritma" /><category term="kombinasyon" /><category term="python" /><category term="bitmask" /><category term="özyineleme" /><summary type="html"><![CDATA[Bir kümeden tam olarak $k$ eleman seçmenin kaç farklı yolu olduğunu bilmek kolaydır; asıl eğlence, bu seçimlerin tamamını eksiksiz, tekrarsız ve belirli bir sırada üretmekle başlar. Kombinasyon üretimi; arama algoritmalarından test verisi hazırlamaya, takım oluşturmadan özellik seçimine kadar pek çok alanda karşımıza çıkar. Bu yazıda k-elemanlı alt kümeleri üretmenin üç sistematik yöntemini inceleyeceğiz.]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://program.sonsuz.us/img/k-elemanli-alt-29.png" /><media:content medium="image" url="https://program.sonsuz.us/img/k-elemanli-alt-29.png" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">Nesneler Kutulara Nasıl Dağıtılır? Dört Temel Kombinatorik Senaryo</title><link href="https://program.sonsuz.us/posts/nesneler-kutulara-nasil-dagitilir-dort-temel-kombinatorik-senaryo/" rel="alternate" type="text/html" title="Nesneler Kutulara Nasıl Dağıtılır? Dört Temel Kombinatorik Senaryo" /><published>2026-10-11T00:00:00+00:00</published><updated>2026-10-11T00:00:00+00:00</updated><id>https://program.sonsuz.us/posts/nesneler-kutulara-nasil-dagitilir-dort-temel-kombinatorik-senaryo</id><content type="html" xml:base="https://program.sonsuz.us/posts/nesneler-kutulara-nasil-dagitilir-dort-temel-kombinatorik-senaryo/"><![CDATA[<p><img src="/img/nesneler-kutulara-nasil-44.svg" alt="nesneler-kutulara-nasil-44" /></p>

<p>Bir çekmecedeki çorapları bölmelere, sunucudaki görevleri işlemcilere veya şekerleri çocuklara dağıttığımızı düşünelim. Bu örneklerin hepsi aynı soruya dönüşür: $n$ nesne, $m$ kutuya kaç farklı biçimde yerleştirilebilir? Ancak cevabı bulmadan önce nesnelerin ve kutuların ayırt edilip edilmediğini bilmeliyiz. Küçük bir ayrıntı gibi görünen bu özellik, sonucu üstel sayılardan bölüşüm sayılarına kadar değiştirebilir.
``</p>
<h2 id="problemin-iki-kritik-sorusu">Problemin iki kritik sorusu</h2>

<p>Bir nesnenin ayırt edilebilir olması, ona bir kimlik verebilmemiz demektir. Örneğin Ali’nin kitabı ile Ece’nin kitabı farklıdır. Özdeş bilyeler ise ayırt edilemez. Benzer biçimde numaralandırılmış dolaplar ayırt edilebilirken aynı türden isimsiz kutular ayırt edilemez.</p>

<p>İkinci karar, boş kutulara izin verilip verilmediğidir. “Her kutuda en az bir nesne bulunmalı” koşulu, özellikle dahil etme–hariç tutma ve Stirling sayıları gibi araçları sahneye çıkarır.</p>

<table>
  <thead>
    <tr>
      <th>Nesneler</th>
      <th>Kutular</th>
      <th style="text-align: right">Boş kutu serbestse</th>
      <th style="text-align: right">Boş kutu yasaksa</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Ayırt edilebilir</td>
      <td>Ayırt edilebilir</td>
      <td style="text-align: right">$m^n$</td>
      <td style="text-align: right">$m!S(n,m)$</td>
    </tr>
    <tr>
      <td>Ayırt edilemez</td>
      <td>Ayırt edilebilir</td>
      <td style="text-align: right">$\binom{n+m-1}{m-1}$</td>
      <td style="text-align: right">$\binom{n-1}{m-1}$</td>
    </tr>
    <tr>
      <td>Ayırt edilebilir</td>
      <td>Ayırt edilemez</td>
      <td style="text-align: right">$\sum_{k=1}^{m}S(n,k)$</td>
      <td style="text-align: right">$S(n,m)$</td>
    </tr>
    <tr>
      <td>Ayırt edilemez</td>
      <td>Ayırt edilemez</td>
      <td style="text-align: right">En fazla $m$ parçalı tamsayı bölüşümü</td>
      <td style="text-align: right">Tam $m$ parçalı tamsayı bölüşümü</td>
    </tr>
  </tbody>
</table>

<p>Buradaki $S(n,m)$, ikinci tür Stirling sayısıdır.</p>

<h2 id="her-şeyin-etiketi-varsa">Her şeyin etiketi varsa</h2>

<p>Nesneler ve kutular ayırt edilebiliyorsa her nesnenin önünde $m$ bağımsız seçim bulunur. Çarpma ilkesiyle sonuç:</p>

\[m \cdot m \cdots m=m^n\]

<p>Örneğin üç farklı dosyayı iki farklı sunucuya dağıtmanın $2^3=8$ yolu vardır. Her sunucunun en az bir dosya alması istenirse, boş kalan kutuları çıkarmalıyız:</p>

\[\sum_{i=0}^{m}(-1)^i\binom{m}{i}(m-i)^n=m!S(n,m)\]

<p>Bu ifade örten fonksiyonların sayısıdır. Ayrıca $n&lt;m$ ise bütün kutuları doldurmak imkânsızdır ve sonuç sıfır olur.</p>

<h2 id="yıldızlar-ve-çubuklar">Yıldızlar ve çubuklar</h2>

<p>Nesneler özdeş, kutular etiketliyse dağılım şu denklemin negatif olmayan tam sayı çözümlerini saymaya dönüşür:</p>

\[x_1+x_2+\cdots+x_m=n\]

<p>Nesneleri yıldız, kutu sınırlarını çubuk olarak gösteririz. $n$ yıldız ile $m-1$ çubuğun sıralanması sonucu $\binom{n+m-1}{m-1}$ elde edilir. Her kutu dolu olacaksa önce her kutuya birer nesne koyarız; kalan $n-m$ nesne dağıtılır ve sonuç $\binom{n-1}{m-1}$ olur.</p>

<h2 id="kutuların-etiketi-kaybolursa">Kutuların etiketi kaybolursa</h2>

<p>Farklı nesneleri isimsiz ve boş olmayan kutulara ayırmak, bir kümenin $m$ gruba bölünmesidir. Bu nedenle cevap $S(n,m)$ olur. Stirling sayıları şu bağıntıyla hesaplanabilir:</p>

\[S(n,m)=mS(n-1,m)+S(n-1,m-1)\]

<p>İlk terim yeni nesnenin mevcut gruplardan birine girmesini, ikinci terim tek başına yeni bir grup oluşturmasını temsil eder.</p>

<p>Hem nesneler hem kutular özdeşse artık sıradan kombinasyon formülleri yetmez. Örneğin dört bilyeyi en fazla iki kutuya dağıtmak, $4$ ve $3+1$ ile $2+2$ bölüşümlerini verir. Kutuların yerini değiştirmek yeni sonuç üretmez. Bu alan, tamsayı bölüşümleriyle ilgilidir.</p>

<h2 id="python-ile-stirling-hesabı">Python ile Stirling hesabı</h2>

<p>Aşağıdaki dinamik programlama kodu, farklı nesnelerin isimsiz ve boş olmayan kutulara dağılımını hesaplar:</p>

<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">def</span> <span class="nf">stirling</span><span class="p">(</span><span class="n">n</span><span class="p">,</span> <span class="n">m</span><span class="p">):</span>
    <span class="n">dp</span> <span class="o">=</span> <span class="p">[[</span><span class="mi">0</span><span class="p">]</span> <span class="o">*</span> <span class="p">(</span><span class="n">m</span> <span class="o">+</span> <span class="mi">1</span><span class="p">)</span> <span class="k">for</span> <span class="n">_</span> <span class="ow">in</span> <span class="nf">range</span><span class="p">(</span><span class="n">n</span> <span class="o">+</span> <span class="mi">1</span><span class="p">)]</span>
    <span class="n">dp</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="o">=</span> <span class="mi">1</span>

    <span class="k">for</span> <span class="n">objects</span> <span class="ow">in</span> <span class="nf">range</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="n">n</span> <span class="o">+</span> <span class="mi">1</span><span class="p">):</span>
        <span class="k">for</span> <span class="n">boxes</span> <span class="ow">in</span> <span class="nf">range</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="nf">min</span><span class="p">(</span><span class="n">objects</span><span class="p">,</span> <span class="n">m</span><span class="p">)</span> <span class="o">+</span> <span class="mi">1</span><span class="p">):</span>
            <span class="n">dp</span><span class="p">[</span><span class="n">objects</span><span class="p">][</span><span class="n">boxes</span><span class="p">]</span> <span class="o">=</span> <span class="p">(</span>
                <span class="n">boxes</span> <span class="o">*</span> <span class="n">dp</span><span class="p">[</span><span class="n">objects</span> <span class="o">-</span> <span class="mi">1</span><span class="p">][</span><span class="n">boxes</span><span class="p">]</span>
                <span class="o">+</span> <span class="n">dp</span><span class="p">[</span><span class="n">objects</span> <span class="o">-</span> <span class="mi">1</span><span class="p">][</span><span class="n">boxes</span> <span class="o">-</span> <span class="mi">1</span><span class="p">]</span>
            <span class="p">)</span>
    <span class="k">return</span> <span class="n">dp</span><span class="p">[</span><span class="n">n</span><span class="p">][</span><span class="n">m</span><span class="p">]</span>

<span class="nf">print</span><span class="p">(</span><span class="nf">stirling</span><span class="p">(</span><span class="mi">5</span><span class="p">,</span> <span class="mi">3</span><span class="p">))</span>  <span class="c1"># 25
</span></code></pre></div></div>

<p>Dağıtım sorularında altın kural formül ezberlemek değil, önce “Kimlerin etiketi var?” ve “Boş kutu mümkün mü?” sorularını sormaktır. Doğru model seçildiğinde kutuların içindeki kombinatorik karmaşa hızla düzene girer.</p>]]></content><author><name>Sonsuz Us</name></author><category term="Bilgi" /><category term="kombinatorik" /><category term="matematik" /><category term="sayma" /><category term="algoritma" /><category term="python" /><category term="olasılık" /><summary type="html"><![CDATA[Bir çekmecedeki çorapları bölmelere, sunucudaki görevleri işlemcilere veya şekerleri çocuklara dağıttığımızı düşünelim. Bu örneklerin hepsi aynı soruya dönüşür: $n$ nesne, $m$ kutuya kaç farklı biçimde yerleştirilebilir? Ancak cevabı bulmadan önce nesnelerin ve kutuların ayırt edilip edilmediğini bilmeliyiz. Küçük bir ayrıntı gibi görünen bu özellik, sonucu üstel sayılardan bölüşüm sayılarına kadar değiştirebilir.]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://program.sonsuz.us/img/nesneler-kutulara-nasil-44.png" /><media:content medium="image" url="https://program.sonsuz.us/img/nesneler-kutulara-nasil-44.png" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">Stirling ve Bell Sayılarıyla Küme Parçalanmasının Matematiği</title><link href="https://program.sonsuz.us/posts/stirling-ve-bell-sayilariyla-kume-parcalanmasinin-matematigi/" rel="alternate" type="text/html" title="Stirling ve Bell Sayılarıyla Küme Parçalanmasının Matematiği" /><published>2026-10-11T00:00:00+00:00</published><updated>2026-10-11T00:00:00+00:00</updated><id>https://program.sonsuz.us/posts/stirling-ve-bell-sayilariyla-kume-parcalanmasinin-matematigi</id><content type="html" xml:base="https://program.sonsuz.us/posts/stirling-ve-bell-sayilariyla-kume-parcalanmasinin-matematigi/"><![CDATA[<p>Bir sınıftaki öğrencileri takımlara, sunucuları kümelere veya görevleri bağımsız gruplara ayırdığınızı düşünün. Grupların sırası önemli değilse ve her eleman tam olarak bir gruba katılacaksa karşımıza <strong>küme parçalanması</strong> çıkar. Bu parçalanmaları belirli sayıda grup için Stirling, toplam olarak ise Bell sayılarıyla hesaplayabiliriz.</p>

<p>``</p>

<h2 id="küme-parçalanması-nedir">Küme parçalanması nedir?</h2>

<p>Bir kümenin parçalanması; boş olmayan, birbirinden ayrık alt kümelerden oluşan ve birleşimleri başlangıç kümesini veren bir koleksiyondur. Örneğin $A={a,b,c}$ kümesinin bazı parçalanmaları şunlardır:</p>

<ul>
  <li>${{a,b,c}}$</li>
  <li>${{a},{b,c}}$</li>
  <li>${{a,b},{c}}$</li>
  <li>${{a},{b},{c}}$</li>
</ul>

<p>Burada grupların sırası önemli değildir. Dolayısıyla ${{a},{b,c}}$ ile ${{b,c},{a}}$ aynı parçalanmadır. Kombinatorikteki küçük ama kritik ayrıntı budur; aksi hâlde gereksiz yere aynı sonucu birkaç kez sayarız.</p>

<h2 id="i̇kinci-tür-stirling-sayıları">İkinci tür Stirling sayıları</h2>

<p>$n$ elemanlı bir kümeyi tam olarak $k$ tane boş olmayan gruba ayırma sayısı <strong>ikinci tür Stirling sayısı</strong> olarak adlandırılır ve $S(n,k)$ biçiminde gösterilir.</p>

<table>
  <thead>
    <tr>
      <th>İfade</th>
      <th>Anlamı</th>
      <th style="text-align: right">Değeri</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>$S(3,1)$</td>
      <td>Üç elemanı tek gruba ayırma</td>
      <td style="text-align: right">1</td>
    </tr>
    <tr>
      <td>$S(3,2)$</td>
      <td>Üç elemanı iki gruba ayırma</td>
      <td style="text-align: right">3</td>
    </tr>
    <tr>
      <td>$S(3,3)$</td>
      <td>Her elemanı ayrı gruba koyma</td>
      <td style="text-align: right">1</td>
    </tr>
    <tr>
      <td>$S(n,0)$</td>
      <td>Pozitif sayıda elemanı sıfır gruba ayırma</td>
      <td style="text-align: right">0</td>
    </tr>
    <tr>
      <td>$S(0,0)$</td>
      <td>Boş kümeyi sıfır gruba ayırma</td>
      <td style="text-align: right">1</td>
    </tr>
  </tbody>
</table>

<p><img src="/img/stirling-ve-bell-71.svg" alt="stirling-ve-bell-71" /></p>

<p>Bu sayıların temel bağıntısı şöyledir:</p>

\[S(n,k)=kS(n-1,k)+S(n-1,k-1)\]

<p>Bağıntının mantığını anlamak için yeni eklenen $n$’inci elemana odaklanalım. Bu eleman mevcut $k$ gruptan birine yerleşirse $kS(n-1,k)$ olasılık elde edilir. Tek başına yeni bir grup oluşturursa geriye kalan elemanların $k-1$ gruba ayrılması gerekir; bu da $S(n-1,k-1)$ seçenektir.</p>

<p>Kapalı form da kullanılabilir:</p>

\[S(n,k)=\frac{1}{k!}\sum_{i=0}^{k}(-1)^{k-i}\binom{k}{i}i^n\]

<p>Ancak programlamada özyinelemeli bağıntıyı dinamik programlamayla uygulamak çoğu zaman daha kolay ve güvenlidir.</p>

<h2 id="bell-sayıları-kaç-grup-olduğunu-bilmiyorsak">Bell sayıları: Kaç grup olduğunu bilmiyorsak</h2>

<p>Grup sayısı önceden belirtilmiyorsa tüm olası $k$ değerlerini toplarız. Elde edilen sonuç <strong>Bell sayısı</strong>dır:</p>

\[B_n=\sum_{k=0}^{n}S(n,k)\]

<p>Örneğin $B_3=1+3+1=5$ olur. Yani üç elemanlı bir küme toplam beş farklı biçimde parçalanabilir. İlk değerler $B_0=1$, $B_1=1$, $B_2=2$, $B_3=5$, $B_4=15$ ve $B_5=52$ şeklindedir. Sayılar hızlı büyür; kümeler kalabalıklaştıkça kombinatorik parti kontrolden çıkar!</p>

<table>
  <thead>
    <tr>
      <th>Dizi</th>
      <th>Sabit grup sayısı var mı?</th>
      <th>Hesaplanan şey</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Stirling $S(n,k)$</td>
      <td>Evet, $k$ grup</td>
      <td>Belirli sayıdaki parçalanmalar</td>
    </tr>
    <tr>
      <td>Bell $B_n$</td>
      <td>Hayır</td>
      <td>Bütün parçalanmaların toplamı</td>
    </tr>
  </tbody>
</table>

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

<p>Aşağıdaki fonksiyon bir tablo oluşturarak Stirling sayılarını hesaplar, ardından ilgili satırı toplayıp Bell sayısını verir:</p>

<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">def</span> <span class="nf">stirling_ve_bell</span><span class="p">(</span><span class="n">n</span><span class="p">):</span>
    <span class="n">dp</span> <span class="o">=</span> <span class="p">[[</span><span class="mi">0</span><span class="p">]</span> <span class="o">*</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="k">for</span> <span class="n">_</span> <span class="ow">in</span> <span class="nf">range</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">dp</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="o">=</span> <span class="mi">1</span>

    <span class="k">for</span> <span class="n">eleman</span> <span class="ow">in</span> <span class="nf">range</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="n">n</span> <span class="o">+</span> <span class="mi">1</span><span class="p">):</span>
        <span class="k">for</span> <span class="n">grup</span> <span class="ow">in</span> <span class="nf">range</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="n">eleman</span> <span class="o">+</span> <span class="mi">1</span><span class="p">):</span>
            <span class="n">dp</span><span class="p">[</span><span class="n">eleman</span><span class="p">][</span><span class="n">grup</span><span class="p">]</span> <span class="o">=</span> <span class="p">(</span>
                <span class="n">grup</span> <span class="o">*</span> <span class="n">dp</span><span class="p">[</span><span class="n">eleman</span> <span class="o">-</span> <span class="mi">1</span><span class="p">][</span><span class="n">grup</span><span class="p">]</span>
                <span class="o">+</span> <span class="n">dp</span><span class="p">[</span><span class="n">eleman</span> <span class="o">-</span> <span class="mi">1</span><span class="p">][</span><span class="n">grup</span> <span class="o">-</span> <span class="mi">1</span><span class="p">]</span>
            <span class="p">)</span>

    <span class="k">return</span> <span class="n">dp</span><span class="p">[</span><span class="n">n</span><span class="p">],</span> <span class="nf">sum</span><span class="p">(</span><span class="n">dp</span><span class="p">[</span><span class="n">n</span><span class="p">])</span>

<span class="n">stirling_satiri</span><span class="p">,</span> <span class="n">bell</span> <span class="o">=</span> <span class="nf">stirling_ve_bell</span><span class="p">(</span><span class="mi">5</span><span class="p">)</span>
<span class="nf">print</span><span class="p">(</span><span class="n">stirling_satiri</span><span class="p">)</span>  <span class="c1"># [0, 1, 15, 25, 10, 1]
</span><span class="nf">print</span><span class="p">(</span><span class="n">bell</span><span class="p">)</span>             <span class="c1"># 52
</span></code></pre></div></div>

<p>Algoritma $O(n^2)$ zamanda ve $O(n^2)$ bellekte çalışır. Yalnızca Bell sayısı veya son satır gerekiyorsa bellek kullanımı iki satır saklanarak $O(n)$ seviyesine indirilebilir.</p>

<p>Bu diziler yalnızca teorik oyuncaklar değildir. Veri kümeleme, eşdeğerlik sınıfları, ağ bölümlendirme, görev gruplama ve dağıtık sistem tasarımı gibi alanlarda ortaya çıkar. Stirling sayıları “tam kaç grup?”, Bell sayıları ise “toplam kaç farklı düzen?” sorusunun zarif cevabıdır.</p>]]></content><author><name>Sonsuz Us</name></author><category term="Bilgi" /><category term="stirling sayıları" /><category term="bell sayıları" /><category term="kombinatorik" /><category term="küme teorisi" /><category term="dinamik programlama" /><summary type="html"><![CDATA[Bir sınıftaki öğrencileri takımlara, sunucuları kümelere veya görevleri bağımsız gruplara ayırdığınızı düşünün. Grupların sırası önemli değilse ve her eleman tam olarak bir gruba katılacaksa karşımıza küme parçalanması çıkar. Bu parçalanmaları belirli sayıda grup için Stirling, toplam olarak ise Bell sayılarıyla hesaplayabiliriz.]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://program.sonsuz.us/img/stirling-ve-bell-71.png" /><media:content medium="image" url="https://program.sonsuz.us/img/stirling-ve-bell-71.png" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">Tekrarlı Permütasyon ve Kombinasyon: Aynı Elemanlar Oyuna Girerse</title><link href="https://program.sonsuz.us/posts/tekrarli-permutasyon-ve-kombinasyon-ayni-elemanlar-oyuna-girerse/" rel="alternate" type="text/html" title="Tekrarlı Permütasyon ve Kombinasyon: Aynı Elemanlar Oyuna Girerse" /><published>2026-10-11T00:00:00+00:00</published><updated>2026-10-11T00:00:00+00:00</updated><id>https://program.sonsuz.us/posts/tekrarli-permutasyon-ve-kombinasyon-ayni-elemanlar-oyuna-girerse</id><content type="html" xml:base="https://program.sonsuz.us/posts/tekrarli-permutasyon-ve-kombinasyon-ayni-elemanlar-oyuna-girerse/"><![CDATA[<p><img src="/img/tekrarli-permutasyon-ve-37.svg" alt="tekrarli-permutasyon-ve-37" /></p>

<p>Bir çekmecede birbirinden ayırt edilemeyen çoraplar, bir şifrede tekrar kullanılabilen rakamlar veya dağıtılmayı bekleyen özdeş şekerler varsa klasik sayma formülleri tek başına yeterli olmayabilir. Çünkü tekrar eden elemanlar bazı düzenlemeleri aynı hâle getirirken, tekrar seçimine izin verilmesi yeni olasılıklar doğurur. İsimleri benzese de <strong>tekrarlı permütasyon</strong> ile <strong>tekrarlı kombinasyon</strong> farklı problemlere cevap verir.
``</p>
<h2 id="önce-klasik-durumu-hatırlayalım">Önce klasik durumu hatırlayalım</h2>

<p>Birbirinden farklı $n$ elemanın tamamı sıralanıyorsa klasik permütasyon formülü şöyledir:</p>

\[P(n)=n!\]

<p>Örneğin A, B ve C harfleri $3!=6$ farklı şekilde sıralanabilir. Sıra önemli değilse ve bu elemanlardan $r$ tanesi seçilecekse kombinasyon kullanılır:</p>

\[\binom{n}{r}=\frac{n!}{r!(n-r)!}\]

<p>Buradaki gizli kahraman, elemanların <strong>ayırt edilebilir</strong> olmasıdır. Elemanlar aynı görünmeye veya seçim sırasında yeniden kullanılmaya başladığında hikâye değişir.</p>

<h2 id="tekrarlı-permütasyon-aynı-elemanlar-yer-değiştirirse">Tekrarlı permütasyon: Aynı elemanlar yer değiştirirse</h2>

<p>$ n $ elemanlı bir dizide bazı elemanlar özdeşse, bunların kendi aralarındaki yer değişimleri yeni bir düzen üretmez. Birinci türden $n_1$, ikinci türden $n_2$ ve devamında $n_k$ adet aynı eleman bulunduğunda:</p>

\[\frac{n!}{n_1!n_2!\cdots n_k!}\]

<p>Örneğin <strong>KAKAO</strong> kelimesinde 5 harf vardır; K ve A ikişer kez, O ise bir kez geçer. Bütün harfleri farklı saysaydık $5!$ düzen bulurduk. Ancak iki K’nin ve iki A’nın yer değiştirmesi sonucu değiştirmez:</p>

\[\frac{5!}{2!2!}=30\]

<p>Paydadaki faktöriyeller, yanlışlıkla birden fazla saydığımız özdeş düzenlemeleri temizleyen birer matematik süpürgesi gibidir.</p>

<blockquote>
  <p>Dikkat: Şifre oluştururken aynı karakterin yeniden kullanılabilmesi farklı bir durumdur. $n$ seçenekle $r$ basamaklı ve sıralı bir kod oluşturuluyorsa sonuç $n^r$ olur. Bu da bazen “tekrarlı permütasyon” diye adlandırılır; fakat özdeş elemanların dizilmesinden kavramsal olarak ayrılır.</p>
</blockquote>

<h2 id="tekrarlı-kombinasyon-seç-istersen-yine-seç">Tekrarlı kombinasyon: Seç, istersen yine seç</h2>

<p>Sıranın önemsiz olduğu ve aynı türün birden fazla seçilebildiği problemlerde tekrarlı kombinasyon kullanılır. $n$ farklı türden toplam $r$ seçim yapmanın sayısı:</p>

\[\binom{n+r-1}{r}=\binom{n+r-1}{n-1}\]

<p>Örneğin çikolata, vanilya ve çilek olmak üzere 3 dondurma çeşidinden 4 top seçelim. Dört topun tamamı çikolata olabilir; tekrar serbesttir. Sonuç:</p>

\[\binom{3+4-1}{4}=\binom{6}{4}=15\]

<p>Bu formülün arkasında <strong>yıldız ve çubuklar</strong> yöntemi bulunur. Dört topu yıldızlarla, üç çeşidi ayıran iki sınırı çubuklarla gösteririz: <code class="language-plaintext highlighter-rouge">**|*|*</code>. Toplam altı konumdan iki çubuğun yerlerini seçmek, dağılımı belirlemeye yeterlidir.</p>

<table>
  <thead>
    <tr>
      <th>Problem türü</th>
      <th style="text-align: right">Sıra önemli mi?</th>
      <th style="text-align: right">Tekrar var mı?</th>
      <th style="text-align: right">Formül</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Klasik permütasyon</td>
      <td style="text-align: right">Evet</td>
      <td style="text-align: right">Hayır</td>
      <td style="text-align: right">$n!$</td>
    </tr>
    <tr>
      <td>Özdeş elemanlı permütasyon</td>
      <td style="text-align: right">Evet</td>
      <td style="text-align: right">Elemanlar zaten tekrar eder</td>
      <td style="text-align: right">$\frac{n!}{n_1!\cdots n_k!}$</td>
    </tr>
    <tr>
      <td>Klasik kombinasyon</td>
      <td style="text-align: right">Hayır</td>
      <td style="text-align: right">Hayır</td>
      <td style="text-align: right">$\binom{n}{r}$</td>
    </tr>
    <tr>
      <td>Tekrarlı kombinasyon</td>
      <td style="text-align: right">Hayır</td>
      <td style="text-align: right">Evet</td>
      <td style="text-align: right">$\binom{n+r-1}{r}$</td>
    </tr>
    <tr>
      <td>Tekrarlı sıralı seçim</td>
      <td style="text-align: right">Evet</td>
      <td style="text-align: right">Evet</td>
      <td style="text-align: right">$n^r$</td>
    </tr>
  </tbody>
</table>

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

<p>Aşağıdaki fonksiyonlar özdeş elemanlı permütasyonu ve tekrarlı kombinasyonu doğrudan hesaplar:</p>

<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kn">from</span> <span class="n">math</span> <span class="kn">import</span> <span class="n">factorial</span><span class="p">,</span> <span class="n">comb</span>

<span class="k">def</span> <span class="nf">ozdes_perm</span><span class="p">(</span><span class="o">*</span><span class="n">adetler</span><span class="p">):</span>
    <span class="n">toplam</span> <span class="o">=</span> <span class="nf">sum</span><span class="p">(</span><span class="n">adetler</span><span class="p">)</span>
    <span class="n">sonuc</span> <span class="o">=</span> <span class="nf">factorial</span><span class="p">(</span><span class="n">toplam</span><span class="p">)</span>
    <span class="k">for</span> <span class="n">adet</span> <span class="ow">in</span> <span class="n">adetler</span><span class="p">:</span>
        <span class="n">sonuc</span> <span class="o">//=</span> <span class="nf">factorial</span><span class="p">(</span><span class="n">adet</span><span class="p">)</span>
    <span class="k">return</span> <span class="n">sonuc</span>

<span class="k">def</span> <span class="nf">tekrarli_kombinasyon</span><span class="p">(</span><span class="n">tur_sayisi</span><span class="p">,</span> <span class="n">secim_sayisi</span><span class="p">):</span>
    <span class="k">return</span> <span class="nf">comb</span><span class="p">(</span><span class="n">tur_sayisi</span> <span class="o">+</span> <span class="n">secim_sayisi</span> <span class="o">-</span> <span class="mi">1</span><span class="p">,</span> <span class="n">secim_sayisi</span><span class="p">)</span>

<span class="nf">print</span><span class="p">(</span><span class="nf">ozdes_perm</span><span class="p">(</span><span class="mi">2</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="c1"># KAKAO: 30
</span><span class="nf">print</span><span class="p">(</span><span class="nf">tekrarli_kombinasyon</span><span class="p">(</span><span class="mi">3</span><span class="p">,</span> <span class="mi">4</span><span class="p">))</span>   <span class="c1"># Dondurma seçimi: 15
</span></code></pre></div></div>

<p>İlk fonksiyon toplam eleman sayısının faktöriyelini hesaplayıp her özdeş grubun faktöriyeline böler. İkinci fonksiyon ise Python’ın <code class="language-plaintext highlighter-rouge">comb</code> aracılığıyla yıldız ve çubuklar formülünü uygular.</p>

<p>Bir soruda formüle atlamadan önce üç soru sorun: <strong>Sıra önemli mi, elemanlar ayırt edilebilir mi, tekrar seçimine izin var mı?</strong> Bu küçük kontrol listesi, benzer görünen sayma problemlerini birbirinden ayırır ve faktöriyeller arasında kaybolmanızı önler.</p>]]></content><author><name>Sonsuz Us</name></author><category term="Bilgi" /><category term="matematik" /><category term="permütasyon" /><category term="kombinasyon" /><category term="algoritma" /><category term="python" /><summary type="html"><![CDATA[Bir çekmecede birbirinden ayırt edilemeyen çoraplar, bir şifrede tekrar kullanılabilen rakamlar veya dağıtılmayı bekleyen özdeş şekerler varsa klasik sayma formülleri tek başına yeterli olmayabilir. Çünkü tekrar eden elemanlar bazı düzenlemeleri aynı hâle getirirken, tekrar seçimine izin verilmesi yeni olasılıklar doğurur. İsimleri benzese de tekrarlı permütasyon ile tekrarlı kombinasyon farklı problemlere cevap verir.]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://program.sonsuz.us/img/tekrarli-permutasyon-ve-37.png" /><media:content medium="image" url="https://program.sonsuz.us/img/tekrarli-permutasyon-ve-37.png" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">Akıllı Bir Kelime Öğrenme Sistemi Nasıl Tasarlanır?</title><link href="https://program.sonsuz.us/posts/akilli-bir-kelime-ogrenme-sistemi-nasil-tasarlanir/" rel="alternate" type="text/html" title="Akıllı Bir Kelime Öğrenme Sistemi Nasıl Tasarlanır?" /><published>2026-10-10T00:00:00+00:00</published><updated>2026-10-10T00:00:00+00:00</updated><id>https://program.sonsuz.us/posts/akilli-bir-kelime-ogrenme-sistemi-nasil-tasarlanir</id><content type="html" xml:base="https://program.sonsuz.us/posts/akilli-bir-kelime-ogrenme-sistemi-nasil-tasarlanir/"><![CDATA[<p>Bir kelimeyi bugün öğrenip yarın unutmak beynimizin küçük bir şakasıdır; kötü hafızadan çok, yanlış zamanda tekrar yapmanın sonucudur. AnkiWeb, Mochi ve Mnemosyne gibi sistemler bu sorunu <strong>aralıklı tekrar</strong> algoritmalarıyla çözer. Gelin benzer bir uygulamanın arkasındaki teoriyi, araçların farklı yaklaşımlarını ve çalışır durumdaki basit bir zamanlama algoritmasını birlikte inceleyelim.</p>

<p><img src="/img/akilli-bir-kelime-63.svg" alt="akilli-bir-kelime-63" /></p>

<p>``</p>

<h2 id="aralıklı-tekrar-neden-işe-yarar">Aralıklı tekrar neden işe yarar?</h2>

<p>Hermann Ebbinghaus’un unutma eğrisi, bir bilginin hatırlanma gücünün zamanla üstel biçimde azaldığını öne sürer. Basitleştirilmiş bir model şöyledir:</p>

\[R(t) = e^{-t/S}\]

<p>Burada $R(t)$ hatırlama olasılığını, $t$ son çalışmadan beri geçen süreyi, $S$ ise anının dayanıklılığını temsil eder. Aynı kelimeyi başarıyla hatırladıkça $S$ büyür; böylece tekrarlar arasındaki süre uzatılabilir.</p>

<p>Örneğin “serendipity” kelimesini ilk gün öğrendiğimizi düşünelim. İlk tekrar bir gün sonra, sonraki tekrar üç gün sonra, ardından sekiz veya on gün sonra yapılabilir. Amaç, kartı tamamen unutmadan hemen önce göstermektir. Çok erken tekrar zaman kaybettirir, çok geç tekrar ise öğrenme sürecini başa sarar.</p>

<h2 id="ankiweb-mochi-ve-mnemosyne-karşılaştırması">AnkiWeb, Mochi ve Mnemosyne karşılaştırması</h2>

<p>Bu araçların ortak hedefi aynı olsa da kullanıcı deneyimleri ve veri modelleri farklıdır:</p>

<table>
  <thead>
    <tr>
      <th>Sistem</th>
      <th>Güçlü yönü</th>
      <th>İçerik yaklaşımı</th>
      <th>Kimler için uygun?</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>AnkiWeb</td>
      <td>Geniş eklenti ve deste sistemi</td>
      <td>Ön yüz, arka yüz ve alanlar</td>
      <td>Ayrıntılı kontrol isteyenler</td>
    </tr>
    <tr>
      <td>Mochi</td>
      <td>Temiz arayüz ve Markdown desteği</td>
      <td>Notlar arasında bağlantılar</td>
      <td>Not alma ile ezberi birleştirenler</td>
    </tr>
    <tr>
      <td>Mnemosyne</td>
      <td>Araştırma odaklı sade yapı</td>
      <td>Klasik soru-cevap kartları</td>
      <td>Dikkat dağıtmayan araç arayanlar</td>
    </tr>
  </tbody>
</table>

<p>Anki ekosistem ve özelleştirme konusunda öne çıkar. Mochi, kartları birbirine bağlayarak kişisel bilgi ağı kurmayı kolaylaştırır. Mnemosyne ise daha sade ve akademik bir yaklaşım sunar. Kısacası Anki bir kontrol paneli, Mochi dijital bahçe, Mnemosyne ise sakin bir çalışma masası gibidir.</p>

<h2 id="temel-veri-modeli">Temel veri modeli</h2>

<p>Kendi sistemimizde her kart için kelime, anlam, örnek cümle, tekrar tarihi, kolaylık katsayısı ve tekrar sayısı saklanabilir. Ayrıca öğrenme yönünü değiştirmek yararlıdır: “apple → elma” kartı tanımayı, “elma → apple” kartı ise aktif hatırlamayı ölçer.</p>

<p>Basit bir kart modeli şu alanları içerebilir:</p>

<ul>
  <li><code class="language-plaintext highlighter-rouge">front</code>: Sorulan kelime veya ipucu</li>
  <li><code class="language-plaintext highlighter-rouge">back</code>: Anlam ve örnek cümle</li>
  <li><code class="language-plaintext highlighter-rouge">interval</code>: Bir sonraki tekrara kalan gün</li>
  <li><code class="language-plaintext highlighter-rouge">ease</code>: Kartın kişisel zorluk katsayısı</li>
  <li><code class="language-plaintext highlighter-rouge">due</code>: Gösterileceği tarih</li>
</ul>

<h2 id="basitleştirilmiş-sm-2-zamanlayıcısı">Basitleştirilmiş SM-2 zamanlayıcısı</h2>

<p>Aşağıdaki Python fonksiyonu, kullanıcının 0 ile 5 arasındaki cevabına göre yeni tekrar aralığını hesaplar:</p>

<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">def</span> <span class="nf">schedule_card</span><span class="p">(</span><span class="n">quality</span><span class="p">,</span> <span class="n">repetitions</span><span class="p">,</span> <span class="n">interval</span><span class="p">,</span> <span class="n">ease</span><span class="p">):</span>
    <span class="c1"># 3'ten düşük puan, kartın hatırlanamadığını gösterir.
</span>    <span class="k">if</span> <span class="n">quality</span> <span class="o">&lt;</span> <span class="mi">3</span><span class="p">:</span>
        <span class="n">repetitions</span> <span class="o">=</span> <span class="mi">0</span>
        <span class="n">interval</span> <span class="o">=</span> <span class="mi">1</span>
    <span class="k">else</span><span class="p">:</span>
        <span class="n">repetitions</span> <span class="o">+=</span> <span class="mi">1</span>

        <span class="k">if</span> <span class="n">repetitions</span> <span class="o">==</span> <span class="mi">1</span><span class="p">:</span>
            <span class="n">interval</span> <span class="o">=</span> <span class="mi">1</span>
        <span class="k">elif</span> <span class="n">repetitions</span> <span class="o">==</span> <span class="mi">2</span><span class="p">:</span>
            <span class="n">interval</span> <span class="o">=</span> <span class="mi">6</span>
        <span class="k">else</span><span class="p">:</span>
            <span class="n">interval</span> <span class="o">=</span> <span class="nf">round</span><span class="p">(</span><span class="n">interval</span> <span class="o">*</span> <span class="n">ease</span><span class="p">)</span>

    <span class="c1"># Başarılı cevap kolaylığı artırır, zor cevap azaltır.
</span>    <span class="n">ease</span> <span class="o">+=</span> <span class="mf">0.1</span> <span class="o">-</span> <span class="p">(</span><span class="mi">5</span> <span class="o">-</span> <span class="n">quality</span><span class="p">)</span> <span class="o">*</span> <span class="p">(</span><span class="mf">0.08</span> <span class="o">+</span> <span class="p">(</span><span class="mi">5</span> <span class="o">-</span> <span class="n">quality</span><span class="p">)</span> <span class="o">*</span> <span class="mf">0.02</span><span class="p">)</span>
    <span class="n">ease</span> <span class="o">=</span> <span class="nf">max</span><span class="p">(</span><span class="mf">1.3</span><span class="p">,</span> <span class="n">ease</span><span class="p">)</span>

    <span class="k">return</span> <span class="n">repetitions</span><span class="p">,</span> <span class="n">interval</span><span class="p">,</span> <span class="n">ease</span>

<span class="nf">print</span><span class="p">(</span><span class="nf">schedule_card</span><span class="p">(</span><span class="mi">4</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">6</span><span class="p">,</span> <span class="mf">2.5</span><span class="p">))</span>
</code></pre></div></div>

<p>Fonksiyon kart unutulduğunda programı sıfırlar; doğru cevaplarda ise mevcut aralığı kolaylık katsayısıyla büyütür. $I_{yeni} = I_{eski} \times E$ ilişkisi, uzun vadede tekrar sayısını ciddi biçimde azaltır. Gerçek bir uygulamada saat dilimi, günlük kart sınırı, gecikmiş tekrarlar ve kullanıcı alışkanlıkları da hesaba katılmalıdır.</p>

<h2 id="i̇yi-bir-sistemin-sırrı">İyi bir sistemin sırrı</h2>

<p>Algoritma tek başına mucize yaratmaz. Kartlar kısa olmalı, tek bir bilgiyi sınamalı ve kelimeyi bağlam içinde göstermelidir. Görsel, ses kaydı ve gerçek bir örnek cümle hatırlamayı güçlendirir. En iyi araç; en gelişmiş formüle sahip olan değil, her gün açmayı unutmadığınız araçtır. Beş dakikalık düzenli tekrar, pazar gecesi yapılan iki saatlik kelime maratonunu çoğu zaman rahatça yener.</p>]]></content><author><name>Sonsuz Us</name></author><category term="Proje" /><category term="kelime öğrenme" /><category term="aralıklı tekrar" /><category term="anki" /><category term="mochi" /><category term="mnemosyne" /><category term="python" /><summary type="html"><![CDATA[Bir kelimeyi bugün öğrenip yarın unutmak beynimizin küçük bir şakasıdır; kötü hafızadan çok, yanlış zamanda tekrar yapmanın sonucudur. AnkiWeb, Mochi ve Mnemosyne gibi sistemler bu sorunu aralıklı tekrar algoritmalarıyla çözer. Gelin benzer bir uygulamanın arkasındaki teoriyi, araçların farklı yaklaşımlarını ve çalışır durumdaki basit bir zamanlama algoritmasını birlikte inceleyelim.]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://program.sonsuz.us/img/akilli-bir-kelime-63.png" /><media:content medium="image" url="https://program.sonsuz.us/img/akilli-bir-kelime-63.png" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">Bulmacaların Gizli Anahtarı: Problem Çözümünde İkili Sayı Sistemi</title><link href="https://program.sonsuz.us/posts/bulmacalarin-gizli-anahtari-problem-cozumunde-ikili-sayi-sistemi/" rel="alternate" type="text/html" title="Bulmacaların Gizli Anahtarı: Problem Çözümünde İkili Sayı Sistemi" /><published>2026-10-10T00:00:00+00:00</published><updated>2026-10-10T00:00:00+00:00</updated><id>https://program.sonsuz.us/posts/bulmacalarin-gizli-anahtari-problem-cozumunde-ikili-sayi-sistemi</id><content type="html" xml:base="https://program.sonsuz.us/posts/bulmacalarin-gizli-anahtari-problem-cozumunde-ikili-sayi-sistemi/"><![CDATA[<p><img src="/img/bulmacalarin-gizli-anahtari-13.svg" alt="bulmacalarin-gizli-anahtari-13" /></p>

<p>Bilgisayarların yalnızca sıfır ve birlerle çalışması ilk bakışta teknolojik bir sınırlama gibi görünebilir. Oysa ikili sayı sistemi, klasik mantık bulmacalarında bilgiyi düzenlemek, olasılıkları kodlamak ve en az sayıda işlemle sonuca ulaşmak için kullanılan son derece güçlü bir araçtır. Zehirli şişelerden ağırlık tartma sorularına kadar pek çok problem, doğru açıdan bakıldığında aslında gizlenmiş birer ikili kodlama egzersizidir.</p>

<p>``</p>

<h2 id="i̇kili-sistem-neden-bu-kadar-kullanışlı">İkili sistem neden bu kadar kullanışlı?</h2>

<p>Onluk sistemde her basamak 0 ile 9 arasında değer alırken ikili sistemde yalnızca iki durum bulunur: <strong>0</strong> ve <strong>1</strong>. Bunlar hayır–evet, kapalı–açık, başarısız–başarılı veya hafif–ağır gibi iki seçenekli durumları temsil edebilir.</p>

<p>Bir ikili sayının değeri şöyle hesaplanır:</p>

\[N = b_0 2^0 + b_1 2^1 + b_2 2^2 + ... + b_k 2^k\]

<p>Burada her $b_i$ yalnızca 0 veya 1 olabilir. Örneğin $1011_2$ sayısı:</p>

\[1 × 2^3 + 0 × 2^2 + 1 × 2^1 + 1 × 2^0 = 11\]

<p>Bu gösterimin problem çözmedeki asıl avantajı, $k$ adet iki durumlu gözlemle $2^k$ farklı olasılığı ayırt edebilmesidir.</p>

<table>
  <thead>
    <tr>
      <th style="text-align: right">Gözlem sayısı</th>
      <th style="text-align: right">Kodlanabilen olasılık</th>
      <th>Örnek kodlar</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td style="text-align: right">1</td>
      <td style="text-align: right">$2^1 = 2$</td>
      <td>0, 1</td>
    </tr>
    <tr>
      <td style="text-align: right">2</td>
      <td style="text-align: right">$2^2 = 4$</td>
      <td>00, 01, 10, 11</td>
    </tr>
    <tr>
      <td style="text-align: right">3</td>
      <td style="text-align: right">$2^3 = 8$</td>
      <td>000–111</td>
    </tr>
    <tr>
      <td style="text-align: right">10</td>
      <td style="text-align: right">$2^{10} = 1024$</td>
      <td>0000000000–1111111111</td>
    </tr>
  </tbody>
</table>

<h2 id="zehirli-şişe-bulmacası">Zehirli şişe bulmacası</h2>

<p>Klasik soruyu düşünelim: <strong>1000 şişeden biri zehirli ve yalnızca 10 test şeridimiz var. Tek turda zehirli şişeyi nasıl buluruz?</strong> Her şişeyi ayrı ayrı test etmek mümkün değildir. Fakat $2^{10}=1024$ olduğu için 10 şerit, 1024 farklı sonucu kodlayabilir.</p>

<p>Şişeleri 0 ile 999 arasında numaralandırır ve numaraları 10 bitlik ikili biçimde yazarız. Bir şişenin ikili gösterimindeki hangi bitler 1 ise o şişeden ilgili test şeritlerine örnek damlatırız. Örneğin 13 numaralı şişenin kodu <code class="language-plaintext highlighter-rouge">0000001101</code> olur; dolayısıyla 1 değerine sahip bitlerin karşılık geldiği şeritlere eklenir.</p>

<p>Bekleme sonunda pozitif çıkan şeritler 1, negatif çıkanlar 0 kabul edilir. Ortaya çıkan ikili sayı doğrudan zehirli şişenin numarasıdır. Buradaki sihir aslında sihir değil, her şişeye benzersiz bir <strong>bit deseni</strong> vermektir.</p>

<h2 id="ağırlıklarla-ölçme-bulmacası">Ağırlıklarla ölçme bulmacası</h2>

<p>Elimizde 1, 2, 4 ve 8 kilogramlık ağırlıklar varsa 1 ile 15 kilogram arasındaki her tam değeri ölçebiliriz. Çünkü bu ağırlıklar ikinin kuvvetleridir:</p>

\[1 + 2 + 4 + 8 = 15\]

<p>Örneğin 13 kilogram, $1101_2$ biçimindedir. Bu nedenle 8, 4 ve 1 kilogramlık ağırlıklar kullanılır; 2 kilogramlık ağırlık kullanılmaz.</p>

<table>
  <thead>
    <tr>
      <th>İkili basamak</th>
      <th style="text-align: right">Ağırlık</th>
      <th>13 kg için durum</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>$2^3$</td>
      <td style="text-align: right">8 kg</td>
      <td>Kullan</td>
    </tr>
    <tr>
      <td>$2^2$</td>
      <td style="text-align: right">4 kg</td>
      <td>Kullan</td>
    </tr>
    <tr>
      <td>$2^1$</td>
      <td style="text-align: right">2 kg</td>
      <td>Kullanma</td>
    </tr>
    <tr>
      <td>$2^0$</td>
      <td style="text-align: right">1 kg</td>
      <td>Kullan</td>
    </tr>
  </tbody>
</table>

<h2 id="aynı-fikri-python-ile-görmek">Aynı fikri Python ile görmek</h2>

<p>Aşağıdaki kod, bir sayıyı oluşturmak için hangi ikinin kuvvetlerinin seçilmesi gerektiğini bulur:</p>

<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">def</span> <span class="nf">secilen_agirliklar</span><span class="p">(</span><span class="n">hedef</span><span class="p">):</span>
    <span class="n">agirliklar</span> <span class="o">=</span> <span class="p">[]</span>
    <span class="n">bit</span> <span class="o">=</span> <span class="mi">0</span>

    <span class="k">while</span> <span class="n">hedef</span> <span class="o">&gt;</span> <span class="mi">0</span><span class="p">:</span>
        <span class="k">if</span> <span class="n">hedef</span> <span class="o">&amp;</span> <span class="mi">1</span><span class="p">:</span>
            <span class="n">agirliklar</span><span class="p">.</span><span class="nf">append</span><span class="p">(</span><span class="mi">2</span> <span class="o">**</span> <span class="n">bit</span><span class="p">)</span>
        <span class="n">hedef</span> <span class="o">&gt;&gt;=</span> <span class="mi">1</span>
        <span class="n">bit</span> <span class="o">+=</span> <span class="mi">1</span>

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

<span class="nf">print</span><span class="p">(</span><span class="nf">secilen_agirliklar</span><span class="p">(</span><span class="mi">13</span><span class="p">))</span>  <span class="c1"># [1, 4, 8]
</span></code></pre></div></div>

<p><code class="language-plaintext highlighter-rouge">hedef &amp; 1</code> işlemi en sağdaki bitin 1 olup olmadığını denetler. <code class="language-plaintext highlighter-rouge">hedef &gt;&gt;= 1</code> ise sayıyı bir bit sağa kaydırarak sıradaki basamağa geçer. Böylece algoritma, sayının ikili gösterimini doğrudan seçilecek ağırlıklara dönüştürür.</p>

<h2 id="bulmacalarda-ikili-düşünme-yöntemi">Bulmacalarda ikili düşünme yöntemi</h2>

<p>Bir soruda çok sayıda aday ve yalnızca iki sonuç üreten testler varsa şu adımlar uygulanabilir:</p>

<ol>
  <li>Olasılık sayısını $n$ olarak belirle.</li>
  <li>$2^k ≥ n$ koşulunu sağlayan en küçük $k$ değerini bul.</li>
  <li>Her adaya benzersiz bir $k$ bitlik kod ata.</li>
  <li>Her testi kodun bir basamağıyla ilişkilendir.</li>
  <li>Sonuç bitlerini birleştirerek doğru adayı belirle.</li>
</ol>

<p>Kısacası ikili sistem yalnızca bilgisayarların dili değildir; sınırlı gözlemlerden maksimum bilgi çıkarma yöntemidir. Bir bulmacada “açık veya kapalı”, “doğru veya yanlış” gibi iki durumlu sonuçlar görüyorsanız, çözümün bir köşesinde büyük olasılıkla ikinin kuvvetleri gülümsüyordur.</p>]]></content><author><name>Sonsuz Us</name></author><category term="Bilgi" /><category term="ikili sistem" /><category term="algoritma" /><category term="problem çözme" /><category term="matematik" /><category term="bulmaca" /><category term="python" /><summary type="html"><![CDATA[Bilgisayarların yalnızca sıfır ve birlerle çalışması ilk bakışta teknolojik bir sınırlama gibi görünebilir. Oysa ikili sayı sistemi, klasik mantık bulmacalarında bilgiyi düzenlemek, olasılıkları kodlamak ve en az sayıda işlemle sonuca ulaşmak için kullanılan son derece güçlü bir araçtır. Zehirli şişelerden ağırlık tartma sorularına kadar pek çok problem, doğru açıdan bakıldığında aslında gizlenmiş birer ikili kodlama egzersizidir.]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://program.sonsuz.us/img/bulmacalarin-gizli-anahtari-13.png" /><media:content medium="image" url="https://program.sonsuz.us/img/bulmacalarin-gizli-anahtari-13.png" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">Büyük O, Teta ve Omega: Algoritma Karmaşıklığının Üç Farklı Yüzü</title><link href="https://program.sonsuz.us/posts/buyuk-o-teta-ve-omega-algoritma-karmasikliginin-uc-farkli-yuzu/" rel="alternate" type="text/html" title="Büyük O, Teta ve Omega: Algoritma Karmaşıklığının Üç Farklı Yüzü" /><published>2026-10-10T00:00:00+00:00</published><updated>2026-10-10T00:00:00+00:00</updated><id>https://program.sonsuz.us/posts/buyuk-o-teta-ve-omega-algoritma-karmasikliginin-uc-farkli-yuzu</id><content type="html" xml:base="https://program.sonsuz.us/posts/buyuk-o-teta-ve-omega-algoritma-karmasikliginin-uc-farkli-yuzu/"><![CDATA[<p>Bir algoritmanın hızlı olduğunu söylemek tek başına pek anlamlı değildir. Hangi girdide, ne kadar hızlı ve büyüyen veri karşısında nasıl davranıyor? İşte Büyük O, Teta ve Omega notasyonları bu soruları matematiksel sınırlarla yanıtlar. Ancak yaygın inanışın aksine Büyük O doğrudan “en kötü”, Omega “en iyi”, Teta da “ortalama” durum demek değildir. Durum analizi ile asimptotik sınır, birbiriyle ilişkili ama farklı kavramlardır.</p>

<p>``</p>

<h2 id="önce-asimptotik-analiz-nedir">Önce asimptotik analiz nedir?</h2>

<p>Asimptotik analiz, girdi boyutu $n$ büyürken algoritmanın zaman veya bellek ihtiyacının nasıl değiştiğini inceler. Donanım, programlama dili ve birkaç milisaniyelik sabit farklar yerine büyüme eğilimine odaklanır.</p>

<p>Örneğin çalışma süresi</p>

\[T(n)=3n^2+5n+20\]

<p>olan bir algoritmada, büyük $n$ değerleri için $n^2$ terimi baskındır. Sabit katsayılar ve düşük dereceli terimler göz ardı edildiğinde büyüme $n^2$ ile ifade edilir.</p>

<h2 id="üç-notasyonun-temel-farkı">Üç notasyonun temel farkı</h2>

<table>
  <thead>
    <tr>
      <th>Notasyon</th>
      <th>Anlamı</th>
      <th>Verdiği sınır</th>
      <th>Basit yorum</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>$O(g(n))$</td>
      <td>En fazla bu hızda büyür</td>
      <td>Üst sınır</td>
      <td>“Bundan daha kötü büyümez.”</td>
    </tr>
    <tr>
      <td>$\Omega(g(n))$</td>
      <td>En az bu hızda büyür</td>
      <td>Alt sınır</td>
      <td>“En az bunun kadar büyür.”</td>
    </tr>
    <tr>
      <td>$\Theta(g(n))$</td>
      <td>Aynı mertebede büyür</td>
      <td>Sıkı sınır</td>
      <td>“Büyüme hızı tam olarak budur.”</td>
    </tr>
  </tbody>
</table>

<p><img src="/img/buyuk-o-teta-62.svg" alt="buyuk-o-teta-62" /></p>

<h3 id="büyük-o-üst-sınır">Büyük O: Üst sınır</h3>

<p>$f(n)=O(g(n))$ diyebilmek için yeterince büyük $n$ değerlerinde</p>

\[0 \leq f(n) \leq c\,g(n)\]

<p>olacak pozitif bir $c$ sabiti bulunmalıdır. Örneğin $3n^2+5n+20$, hem $O(n^2)$ hem de teknik olarak $O(n^3)$ içindedir. Fakat $O(n^2)$ daha bilgilendirici ve daha sıkı bir üst sınırdır.</p>

<h3 id="omega-alt-sınır">Omega: Alt sınır</h3>

<p>$f(n)=\Omega(g(n))$, fonksiyonun en az $g(n)$ kadar hızlı büyüdüğünü belirtir:</p>

\[0 \leq c\,g(n) \leq f(n)\]

<p>Örneğin $3n^2+5n+20$, $\Omega(n^2)$ sınıfındadır. Bu notasyon algoritmanın belirli bir maliyetin altına inemeyeceğini anlatır.</p>

<h3 id="teta-sıkı-sınır">Teta: Sıkı sınır</h3>

<p>Teta, alt ve üst sınırın birleşimidir:</p>

\[c_1g(n) \leq f(n) \leq c_2g(n)\]

<p>Dolayısıyla $f(n)=\Theta(g(n))$ ise fonksiyon hem $O(g(n))$ hem de $\Omega(g(n))$ olur. Örneğimiz için en açıklayıcı ifade $T(n)=\Theta(n^2)$ biçimindedir.</p>

<h2 id="en-iyi-ortalama-ve-en-kötü-durum">En iyi, ortalama ve en kötü durum</h2>

<p>Durumlar, girdinin algoritmayı nasıl etkilediğini; notasyonlar ise seçilen durumdaki büyümeye ilişkin sınırı belirtir.</p>

<table>
  <thead>
    <tr>
      <th>Durum</th>
      <th>Doğrusal aramadaki örnek</th>
      <th>Karmaşıklık</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>En iyi</td>
      <td>Aranan değer ilk elemandır</td>
      <td>$\Theta(1)$</td>
    </tr>
    <tr>
      <td>Ortalama</td>
      <td>Değer genellikle listenin ortalarındadır</td>
      <td>$\Theta(n)$</td>
    </tr>
    <tr>
      <td>En kötü</td>
      <td>Değer sondadır veya hiç yoktur</td>
      <td>$\Theta(n)$</td>
    </tr>
  </tbody>
</table>

<p>Burada her durum için Teta kullanabildiğimize dikkat edin. “En kötü durum $O(n)$” doğrudur; fakat sıkı sınır biliniyorsa “en kötü durum $\Theta(n)$” daha güçlü bir ifadedir. Ortalama durum analizi ise girdilerin olasılık dağılımını gerektirir. Her girdinin eşit olasılıklı olduğunu varsaymak her zaman gerçekçi değildir.</p>

<h2 id="kod-üzerinde-görelim">Kod üzerinde görelim</h2>

<p>Aşağıdaki Python fonksiyonu, doğrusal arama yaparken kaç karşılaştırma gerçekleştirildiğini de döndürür:</p>

<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">def</span> <span class="nf">linear_search</span><span class="p">(</span><span class="n">values</span><span class="p">,</span> <span class="n">target</span><span class="p">):</span>
    <span class="n">comparisons</span> <span class="o">=</span> <span class="mi">0</span>

    <span class="k">for</span> <span class="n">index</span><span class="p">,</span> <span class="n">value</span> <span class="ow">in</span> <span class="nf">enumerate</span><span class="p">(</span><span class="n">values</span><span class="p">):</span>
        <span class="n">comparisons</span> <span class="o">+=</span> <span class="mi">1</span>
        <span class="k">if</span> <span class="n">value</span> <span class="o">==</span> <span class="n">target</span><span class="p">:</span>
            <span class="k">return</span> <span class="n">index</span><span class="p">,</span> <span class="n">comparisons</span>

    <span class="k">return</span> <span class="o">-</span><span class="mi">1</span><span class="p">,</span> <span class="n">comparisons</span>

<span class="n">numbers</span> <span class="o">=</span> <span class="p">[</span><span class="mi">8</span><span class="p">,</span> <span class="mi">3</span><span class="p">,</span> <span class="mi">12</span><span class="p">,</span> <span class="mi">7</span><span class="p">,</span> <span class="mi">21</span><span class="p">]</span>
<span class="nf">print</span><span class="p">(</span><span class="nf">linear_search</span><span class="p">(</span><span class="n">numbers</span><span class="p">,</span> <span class="mi">8</span><span class="p">))</span>   <span class="c1"># En iyi durum: 1 karşılaştırma
</span><span class="nf">print</span><span class="p">(</span><span class="nf">linear_search</span><span class="p">(</span><span class="n">numbers</span><span class="p">,</span> <span class="mi">21</span><span class="p">))</span>  <span class="c1"># En kötü durum: 5 karşılaştırma
</span></code></pre></div></div>

<p>İlk çağrıda maliyet girdi boyutundan bağımsızdır. İkinci çağrıda karşılaştırma sayısı $n$ ile birlikte doğrusal büyür.</p>

<h2 id="hangisini-kullanmalıyız">Hangisini kullanmalıyız?</h2>

<p>Bir algoritmayı tanıtırken analiz edilen durumu açıkça söylemek en güvenli yaklaşımdır: “en kötü durumda $\Theta(n^2)$” gibi. Yalnızca güvenli bir üst sınır biliniyorsa Büyük O, kaçınılmaz bir alt sınır gösteriliyorsa Omega, büyüme kesin biçimde sınırlandırılabiliyorsa Teta kullanılmalıdır. Kısacası notasyonlar yarışmıyor; algoritmanın performansını farklı açılardan aydınlatıyor.</p>]]></content><author><name>Sonsuz Us</name></author><category term="Bilgi" /><category term="algoritmalar" /><category term="büyük-o" /><category term="karmaşıklık" /><category term="performans" /><category term="veri-yapıları" /><category term="python" /><summary type="html"><![CDATA[Bir algoritmanın hızlı olduğunu söylemek tek başına pek anlamlı değildir. Hangi girdide, ne kadar hızlı ve büyüyen veri karşısında nasıl davranıyor? İşte Büyük O, Teta ve Omega notasyonları bu soruları matematiksel sınırlarla yanıtlar. Ancak yaygın inanışın aksine Büyük O doğrudan “en kötü”, Omega “en iyi”, Teta da “ortalama” durum demek değildir. Durum analizi ile asimptotik sınır, birbiriyle ilişkili ama farklı kavramlardır.]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://program.sonsuz.us/img/buyuk-o-teta-62.png" /><media:content medium="image" url="https://program.sonsuz.us/img/buyuk-o-teta-62.png" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">Dişli Çarklardan Silikon Çiplere: Bilgisayarın Gelişim Tarihi</title><link href="https://program.sonsuz.us/posts/disli-carklardan-silikon-ciplere-bilgisayarin-gelisim-tarihi/" rel="alternate" type="text/html" title="Dişli Çarklardan Silikon Çiplere: Bilgisayarın Gelişim Tarihi" /><published>2026-10-10T00:00:00+00:00</published><updated>2026-10-10T00:00:00+00:00</updated><id>https://program.sonsuz.us/posts/disli-carklardan-silikon-ciplere-bilgisayarin-gelisim-tarihi</id><content type="html" xml:base="https://program.sonsuz.us/posts/disli-carklardan-silikon-ciplere-bilgisayarin-gelisim-tarihi/"><![CDATA[<p>Bugün cebimizde taşıdığımız telefonlar, birkaç on yıl önce odaları dolduran bilgisayarlardan milyonlarca kat daha güçlü. Ancak bu teknolojik yolculuk bir anda başlamadı. Dişli çarklarla çalışan hesap makinelerinden vakum tüplerine, transistörlerden milyarlarca bileşen içeren işlemcilere uzanan bilgisayar tarihi; matematik, mühendislik ve insan merakının ortak ürünüdür.</p>

<p>``</p>

<h2 id="mekanik-hesaplamanın-doğuşu">Mekanik hesaplamanın doğuşu</h2>

<p>Bilgisayarların uzak atalarından biri, 1642 yılında Blaise Pascal tarafından geliştirilen <strong>Pascaline</strong> adlı mekanik hesap makinesiydi. Dişli çarklar kullanan bu cihaz toplama ve çıkarma yapabiliyordu. Gottfried Wilhelm Leibniz ise 1670’lerde sistemi geliştirerek çarpma ve bölme işlemlerini de mekanikleştirdi.</p>

<p>Bu makinelerin temel fikri, sayıları fiziksel konumlarla temsil etmekti. Örneğin bir çarkın on farklı konumu, 0 ile 9 arasındaki rakamlara karşılık geliyordu. Günümüzde aynı yaklaşım elektrik sinyalleriyle uygulanır; ancak on durum yerine çoğunlukla iki durum kullanılır:</p>

\[bit \in \{0,1\}\]

<p>Mekanik sistemlerde hareket eden parçalar bilgiyi taşırken modern bilgisayarlarda bu görevi gerilim seviyeleri üstlenir.</p>

<h2 id="programlanabilir-makine-fikri">Programlanabilir makine fikri</h2>

<p>1800’lerin başında Joseph Marie Jacquard, dokuma tezgâhlarını <strong>delikli kartlarla</strong> kontrol etti. Kartlardaki delikler bir tür komut dizisi oluşturuyordu. Charles Babbage bu fikirden etkilenerek 1837’de <strong>Analitik Makine</strong> tasarımını ortaya koydu.</p>

<p>Babbage’ın makinesi tamamlanamamış olsa da işlem birimi, bellek, giriş ve çıkış gibi modern bilgisayar bileşenlerini teorik olarak içeriyordu. Ada Lovelace ise makinenin Bernoulli sayılarını hesaplaması için bir algoritma hazırladı ve tarihin ilk bilgisayar programcısı kabul edildi.</p>

<h2 id="elektronik-bilgisayarlar-sahneye-çıkıyor">Elektronik bilgisayarlar sahneye çıkıyor</h2>

<p>1940’larda mekanik parçaların yerini röleler ve vakum tüpleri aldı. 1946’da tanıtılan <strong>ENIAC</strong>, yaklaşık 18.000 vakum tüpü kullanıyor ve saniyede binlerce işlem gerçekleştirebiliyordu. Ne var ki devasa boyutlu, enerji oburu ve arızaya yatkındı.</p>

<table>
  <thead>
    <tr>
      <th>Dönem</th>
      <th>Temel teknoloji</th>
      <th>Başlıca avantaj</th>
      <th>Başlıca sorun</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>1600–1800</td>
      <td>Dişli çarklar</td>
      <td>Hesabı otomatikleştirme</td>
      <td>Yavaşlık ve aşınma</td>
    </tr>
    <tr>
      <td>1940’lar</td>
      <td>Vakum tüpleri</td>
      <td>Elektronik hız</td>
      <td>Isınma ve yüksek enerji</td>
    </tr>
    <tr>
      <td>1950–1960</td>
      <td>Transistörler</td>
      <td>Küçük boyut, güvenilirlik</td>
      <td>Üretim maliyeti</td>
    </tr>
    <tr>
      <td>1970 sonrası</td>
      <td>Mikroişlemciler</td>
      <td>Yüksek entegrasyon</td>
      <td>Isı ve karmaşıklık</td>
    </tr>
    <tr>
      <td>Günümüz</td>
      <td>Çok çekirdekli çipler</td>
      <td>Paralel işlem</td>
      <td>Güç tüketimi sınırları</td>
    </tr>
  </tbody>
</table>

<h2 id="transistör-ve-mikroişlemci-devrimi">Transistör ve mikroişlemci devrimi</h2>

<p>1947’de transistörün geliştirilmesi bilgisayarları küçülttü, hızlandırdı ve daha güvenilir hâle getirdi. Ardından çok sayıda transistörün aynı yüzeye yerleştirildiği <strong>entegre devreler</strong> ortaya çıktı. 1971’de Intel 4004, ticari açıdan başarılı ilk mikroişlemcilerden biri oldu.</p>

<p>İşlemci performansı kabaca saat frekansı, çekirdek sayısı ve saat başına tamamlanan komut miktarıyla ilişkilendirilebilir:</p>

\[P \approx f \times C \times IPC\]

<p>Burada $f$ frekansı, $C$ çekirdek sayısını, $IPC$ ise döngü başına işlenen komut sayısını temsil eder. Gerçek performans bellek, önbellek ve yazılım tasarımından da etkilenir.</p>

<p>İkili sistemin temel mantığını küçük bir Python örneğiyle görebiliriz:</p>

<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">def</span> <span class="nf">ikili_topla</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="c1"># Metin biçimindeki ikili sayıları onlu sisteme çevirir.
</span>    <span class="n">toplam</span> <span class="o">=</span> <span class="nf">int</span><span class="p">(</span><span class="n">a</span><span class="p">,</span> <span class="mi">2</span><span class="p">)</span> <span class="o">+</span> <span class="nf">int</span><span class="p">(</span><span class="n">b</span><span class="p">,</span> <span class="mi">2</span><span class="p">)</span>

    <span class="c1"># Sonucu yeniden ikili gösterime dönüştürür.
</span>    <span class="k">return</span> <span class="nf">bin</span><span class="p">(</span><span class="n">toplam</span><span class="p">)[</span><span class="mi">2</span><span class="p">:]</span>

<span class="nf">print</span><span class="p">(</span><span class="nf">ikili_topla</span><span class="p">(</span><span class="sh">"</span><span class="s">1010</span><span class="sh">"</span><span class="p">,</span> <span class="sh">"</span><span class="s">0111</span><span class="sh">"</span><span class="p">))</span>  <span class="c1"># 10001
</span></code></pre></div></div>

<p>Bu kod, işlemcideki gerçek mantık kapılarının yaptığı işi soyut düzeyde taklit eder. Donanımda toplama; AND, OR ve XOR gibi devrelerle gerçekleştirilir.</p>

<h2 id="günümüz-paralellik-ve-uzmanlaşma">Günümüz: Paralellik ve uzmanlaşma</h2>

<p>Transistör sayısının yaklaşık iki yılda bir artacağını öngören <strong>Moore Yasası</strong>, onlarca yıl boyunca sektöre yön verdi. Fiziksel küçülmenin zorlaşmasıyla üreticiler yalnızca frekansı artırmak yerine çok çekirdekli mimarilere yöneldi. GPU’lar grafik işlemlerinin yanında yapay zekâ ve bilimsel hesaplama için kullanılmaya başlandı. NPU gibi özel birimler ise belirli görevleri daha az enerjiyle tamamlıyor.</p>

<p>Kısacası bilgisayarın gelişimi, “daha hızlı hesaplama” arzusundan “doğru işi doğru donanımla yapma” anlayışına evrildi. Pascal’ın çarklarından modern işlemcilerin nanometre ölçeğindeki transistörlerine kadar değişmeyen temel amaç ise aynı kaldı: bilgiyi temsil etmek, kurallara göre işlemek ve anlamlı sonuç üretmek.</p>

<p><img src="/img/disli-carklardan-silikon-55.svg" alt="disli-carklardan-silikon-55" /></p>]]></content><author><name>Sonsuz Us</name></author><category term="Bilgi" /><category term="bilgisayar tarihi" /><category term="işlemci" /><category term="teknoloji" /><category term="programlama" /><category term="donanım" /><category term="yapay zeka" /><summary type="html"><![CDATA[Bugün cebimizde taşıdığımız telefonlar, birkaç on yıl önce odaları dolduran bilgisayarlardan milyonlarca kat daha güçlü. Ancak bu teknolojik yolculuk bir anda başlamadı. Dişli çarklarla çalışan hesap makinelerinden vakum tüplerine, transistörlerden milyarlarca bileşen içeren işlemcilere uzanan bilgisayar tarihi; matematik, mühendislik ve insan merakının ortak ürünüdür.]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://program.sonsuz.us/img/disli-carklardan-silikon-55.png" /><media:content medium="image" url="https://program.sonsuz.us/img/disli-carklardan-silikon-55.png" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">Ekleme-Çıkarma İlkesi: Kesişen Kümeleri Hatasız Sayma</title><link href="https://program.sonsuz.us/posts/ekleme-cikarma-ilkesi-kesisen-kumeleri-hatasiz-sayma/" rel="alternate" type="text/html" title="Ekleme-Çıkarma İlkesi: Kesişen Kümeleri Hatasız Sayma" /><published>2026-10-10T00:00:00+00:00</published><updated>2026-10-10T00:00:00+00:00</updated><id>https://program.sonsuz.us/posts/ekleme-cikarma-ilkesi-kesisen-kumeleri-hatasiz-sayma</id><content type="html" xml:base="https://program.sonsuz.us/posts/ekleme-cikarma-ilkesi-kesisen-kumeleri-hatasiz-sayma/"><![CDATA[<p>Bir etkinliğe katılanların kaçının kahve veya çay içtiğini bulmak kulağa kolay gelir: Kahve içenlerle çay içenleri topla! Fakat bazı kişiler ikisini de içiyorsa onları iki kez saymış oluruz. Ekleme-Çıkarma İlkesi, diğer adıyla Dahil Etme-Hariç Tutma İlkesi, tam olarak bu tür çakışmaları düzeltmek için kullanılan güçlü bir sayma yöntemidir.</p>

<p><img src="/img/ekleme-cikarma-ilkesi-26.svg" alt="ekleme-cikarma-ilkesi-26" /></p>

<p>``</p>

<h2 id="temel-fikir-önce-ekle-sonra-fazlalığı-çıkar">Temel fikir: Önce ekle, sonra fazlalığı çıkar</h2>

<p>İki sonlu küme düşünelim: $A$ ve $B$. Bu kümelerin birleşimi, en az birine ait olan elemanlardan oluşur. Yalnızca $\vert A\vert +\vert B\vert $ işlemini yaparsak $A \cap B$ kesişimindeki elemanları iki defa sayarız. Bu fazlalığı gidermek için kesişimin eleman sayısını bir kez çıkarmamız gerekir:</p>

\[\vert A \cup B\vert  = \vert A\vert  + \vert B\vert  - \vert A \cap B\vert\]

<p>Buradaki dikey çizgiler kümenin eleman sayısını ifade eder. İlkenin mantığı küçük bir muhasebe işlemine benzer: Her şeyi kasaya ekler, yanlışlıkla iki kez kaydedilenleri geri çıkarırız.</p>

<table>
  <thead>
    <tr>
      <th>Bölge</th>
      <th style="text-align: right">İlk toplamada sayılma sayısı</th>
      <th style="text-align: right">Düzeltme sonrası</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Yalnızca $A$</td>
      <td style="text-align: right">1</td>
      <td style="text-align: right">1</td>
    </tr>
    <tr>
      <td>Yalnızca $B$</td>
      <td style="text-align: right">1</td>
      <td style="text-align: right">1</td>
    </tr>
    <tr>
      <td>$A \cap B$</td>
      <td style="text-align: right">2</td>
      <td style="text-align: right">1</td>
    </tr>
    <tr>
      <td>İki kümenin de dışında</td>
      <td style="text-align: right">0</td>
      <td style="text-align: right">0</td>
    </tr>
  </tbody>
</table>

<h2 id="i̇ki-kümeli-örnek">İki kümeli örnek</h2>

<p>Bir sınıfta 24 öğrenci Python, 18 öğrenci JavaScript biliyor olsun. Her iki dili bilen 9 öğrenci varsa en az bir dili bilenlerin sayısı şöyledir:</p>

\[\vert P \cup J\vert  = 24 + 18 - 9 = 33\]

<p>Burada $24+18=42$ demek hatalıdır; çünkü iki dili bilen 9 öğrenci toplamın içinde iki kez görünür. Bu öğrencileri bir kez çıkardığımızda doğru sonuç olan 33’e ulaşırız.</p>

<p>Hiçbir dili bilmeyenlerin sayısı sorulursa evrensel kümeden yararlanabiliriz. Sınıfta toplam 40 öğrenci varsa:</p>

\[40-\vert P \cup J\vert =40-33=7\]

<p>Dolayısıyla 7 öğrenci iki dilden hiçbirini bilmemektedir.</p>

<h2 id="üç-kümede-neden-yeniden-ekleme-yapıyoruz">Üç kümede neden yeniden ekleme yapıyoruz?</h2>

<p>Üç küme söz konusu olduğunda önce tekil kümeler eklenir, ardından tüm ikili kesişimler çıkarılır. Ancak üç kümenin ortak bölgesi başlangıçta üç kez eklenmiş, ikili kesişimler çıkarılırken de üç kez çıkarılmış olur. Böylece hiç sayılmamış hale gelir. Onu bir kez yeniden eklemeliyiz:</p>

\[\vert A \cup B \cup C\vert  = \vert A\vert +\vert B\vert +\vert C\vert 
-\vert A \cap B\vert -\vert A \cap C\vert -\vert B \cap C\vert 
+\vert A \cap B \cap C\vert\]

<table>
  <thead>
    <tr>
      <th>Aşama</th>
      <th style="text-align: right">İşaret</th>
      <th>Amaç</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Tek kümeler</td>
      <td style="text-align: right">$+$</td>
      <td>Bütün adayları saymak</td>
    </tr>
    <tr>
      <td>İkili kesişimler</td>
      <td style="text-align: right">$-$</td>
      <td>Çift sayımları düzeltmek</td>
    </tr>
    <tr>
      <td>Üçlü kesişim</td>
      <td style="text-align: right">$+$</td>
      <td>Fazla çıkarılan ortak bölgeyi geri eklemek</td>
    </tr>
  </tbody>
</table>

<p>İşaretlerin sırayla artı ve eksi olması tesadüf değildir. Genel durumda tek sayıda kümenin kesişimleri eklenir, çift sayıda kümenin kesişimleri çıkarılır.</p>

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

<p>Aşağıdaki fonksiyon, üç kümenin birleşim büyüklüğünü gerçek küme işlemleriyle hesaplar ve formül sonucuyla karşılaş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">birlesim_sayisi</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">c</span><span class="p">):</span>
    <span class="n">formule_gore</span> <span class="o">=</span> <span class="p">(</span>
        <span class="nf">len</span><span class="p">(</span><span class="n">a</span><span class="p">)</span> <span class="o">+</span> <span class="nf">len</span><span class="p">(</span><span class="n">b</span><span class="p">)</span> <span class="o">+</span> <span class="nf">len</span><span class="p">(</span><span class="n">c</span><span class="p">)</span>
        <span class="o">-</span> <span class="nf">len</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="nf">len</span><span class="p">(</span><span class="n">a</span> <span class="o">&amp;</span> <span class="n">c</span><span class="p">)</span> <span class="o">-</span> <span class="nf">len</span><span class="p">(</span><span class="n">b</span> <span class="o">&amp;</span> <span class="n">c</span><span class="p">)</span>
        <span class="o">+</span> <span class="nf">len</span><span class="p">(</span><span class="n">a</span> <span class="o">&amp;</span> <span class="n">b</span> <span class="o">&amp;</span> <span class="n">c</span><span class="p">)</span>
    <span class="p">)</span>
    <span class="n">dogrudan</span> <span class="o">=</span> <span class="nf">len</span><span class="p">(</span><span class="n">a</span> <span class="o">|</span> <span class="n">b</span> <span class="o">|</span> <span class="n">c</span><span class="p">)</span>
    <span class="k">return</span> <span class="n">formule_gore</span><span class="p">,</span> <span class="n">dogrudan</span>

<span class="n">A</span> <span class="o">=</span> <span class="p">{</span><span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">3</span><span class="p">,</span> <span class="mi">4</span><span class="p">}</span>
<span class="n">B</span> <span class="o">=</span> <span class="p">{</span><span class="mi">3</span><span class="p">,</span> <span class="mi">4</span><span class="p">,</span> <span class="mi">5</span><span class="p">}</span>
<span class="n">C</span> <span class="o">=</span> <span class="p">{</span><span class="mi">4</span><span class="p">,</span> <span class="mi">5</span><span class="p">,</span> <span class="mi">6</span><span class="p">}</span>

<span class="nf">print</span><span class="p">(</span><span class="nf">birlesim_sayisi</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">C</span><span class="p">))</span>  <span class="c1"># (6, 6)
</span></code></pre></div></div>

<p><code class="language-plaintext highlighter-rouge">&amp;</code> kesişimi, <code class="language-plaintext highlighter-rouge">|</code> ise birleşimi temsil eder. İki sonucun eşit çıkması, formülün aynı elemanı tekrar tekrar saymadan çalıştığını gösterir.</p>

<h2 id="sık-yapılan-hatalar">Sık yapılan hatalar</h2>

<p>En yaygın hata, kesişimleri hiç çıkarmamaktır. Bir diğer hata ise “yalnızca iki kümeye ait olanlar” ile “iki kümenin kesişimi” ifadelerini aynı sanmaktır. Örneğin $A \cap B$, aksi belirtilmedikçe $C$’de bulunan ortak elemanları da kapsar. Ayrıca “en az biri” birleşimi, “hepsi” kesişimi, “hiçbiri” ise birleşimin tümleyenini işaret eder.</p>

<p>Ekleme-Çıkarma İlkesi; anketlerden olasılığa, sayıların bölünebilirliğinden algoritma analizine kadar pek çok alanda kullanılır. Ana strateji basittir: Çakışmaları belirle, kaç kez sayıldıklarını izle ve artı-eksi düzeltmelerini sırayla uygula.</p>]]></content><author><name>Sonsuz Us</name></author><category term="Bilgi" /><category term="matematik" /><category term="kombinatorik" /><category term="kümeler" /><category term="sayma" /><category term="algoritma" /><category term="python" /><summary type="html"><![CDATA[Bir etkinliğe katılanların kaçının kahve veya çay içtiğini bulmak kulağa kolay gelir: Kahve içenlerle çay içenleri topla! Fakat bazı kişiler ikisini de içiyorsa onları iki kez saymış oluruz. Ekleme-Çıkarma İlkesi, diğer adıyla Dahil Etme-Hariç Tutma İlkesi, tam olarak bu tür çakışmaları düzeltmek için kullanılan güçlü bir sayma yöntemidir.]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://program.sonsuz.us/img/ekleme-cikarma-ilkesi-26.png" /><media:content medium="image" url="https://program.sonsuz.us/img/ekleme-cikarma-ilkesi-26.png" xmlns:media="http://search.yahoo.com/mrss/" /></entry></feed>