İçeriğe geç
academia.sh

Ders 09 / 11

Risk Odaklı Modelleme

Senaryo temelli modellemenin kapsama ölçümü: beş senaryonun 51 tehdit üretmesi, bunun 39'unun sistematik kümeyle kesişmesi ve 12'sinin hiçbir tek öğede tanımlı olmayan zincir tehdidi olması, senaryoların sistematik kümenin %63,9'unu kaçırması, kaçırılanın 24'ünün hizmet engelleme kategorisinde olması, senaryo yönteminin dakikada 0,234 tehditle sistematik üretimin 1,44 katı hızda çalışması ve iki yöntemin birleşiminin 120 tehdide çıkması.

İçindekiler

Sistematik üretim öğeden başlar: her kutuya, her oka ve her depoya aynı sorular sorulur. Yüz sekiz anlamlı tehdidin her biri bir öğe ile bir kategorinin kesişimidir; hiçbiri iki öğenin birlikte kullanılmasından doğmaz.

Oysa gerçek zarar çoğunlukla tek bir öğede değil, birkaç öğenin arka arkaya kullanılmasında oluşur. Bu kalemleri bulmanın yolu öğeden değil hedeften başlamaktır: saldıran taraf ne elde etmek ister ve oraya hangi yoldan gider. Bu ders senaryo temelli modellemeyi aynı çizgede koşturur ve tek soruyu sorar — senaryolar kaç tehdit buluyor, sistematik yöntemin bulduğunun kaçını kaçırıyor, ikisinin kesişimi ne.

Senaryo Bir Düğüm Dizisidir

Senaryo, saldırgan bakışıyla kurulan bir yoldur; Güvenlik Gereksinimleri dersindeki kötüye kullanım senaryosu ile aynı köktendir, ama orada gereksinim yazmak için kullanılırdı, burada tehdit üretmek için kullanılıyor.

Aşağıdaki senaryolar modeldir ve yalnızca hangi öğelerin kullanıldığını yazar; hiçbir adım nasıl yapıldığıyla anlatılmaz. Böyle bir senaryonun gerçek bir sistem üzerinde denenmesi, yazılı yetki ve tanımlı kapsam olmadan hem yasadışı hem meslek dışıdır.

TD13: senaryo, bir saldırgan profilinden bir hedefe varan düğüm dizisidir. TD14: senaryonun dokunduğu öğeler, dizideki düğümler ve aralarındaki akışlardır. TD15: senaryo iki tür tehdit doğurur — dokunulan öğede senaryonun kategorisiyle örtüşen öğe tehdidi, ve ardışık iki düğümün birlikte kullanılmasından doğan zincir tehdidi; ikincisi tek öğe üzerinde tanımlı olmadığı için sistematik üretimde karşılığı yoktur. TD16: senaryo kurmanın bedeli senaryo başına sabit süre artı dokunulan öğe başına süredir.

// tehdit/senaryo.mjs — ayni cizge, bu kez hedeften geriye kurulan senaryolarla (model).
// Senaryo yalnizca hangi ogelerin kullanildigini yazar; adimin nasil yapildigi yazilmaz.
// Gercek bir sistem, gercek bir uc ya da isleyen bir adim yoktur.

const BOLGE = { internet: 0, saha: 1, "dis-uc": 2, ic: 3, yonetim: 4, veri: 5 };
export const DUGUM = Object.fromEntries(`
  abone D internet | denetim-kurumu D internet | sayac-cihazi D saha | saha-ekibi D saha
  abone-portali S dis-uc | toplama-ucu S dis-uc | saha-uygulamasi S saha
  dogrulayici S ic | faturalama S ic | is-emri S ic | rapor-ureteci S ic | kimlik-servisi S ic
  yonetim-konsolu S yonetim | olcum-deposu P veri | fatura-deposu P veri
  kimlik-deposu P veri | denetim-gunlugu P veri`
  .trim().split(/\s*[|\n]\s*/).map((r) => {
    const [ad, tur, bolge] = r.trim().split(/\s+/);
    return [ad, { ad, tur, bolge, duzey: BOLGE[bolge] }];
  }));
export const AKIS = `
  abone            abone-portali    kimlik      | abone-portali   kimlik-servisi  kimlik
  kimlik-servisi   kimlik-deposu    kimlik      | abone-portali   faturalama      fatura
  faturalama       fatura-deposu    fatura      | faturalama      abone-portali   fatura
  sayac-cihazi     toplama-ucu      olcum       | toplama-ucu     dogrulayici     olcum
  dogrulayici      olcum-deposu     olcum       | dogrulayici     faturalama      olcum
  saha-ekibi       saha-uygulamasi  kimlik      | saha-uygulamasi is-emri         emir
  is-emri          saha-uygulamasi  emir        | is-emri         olcum-deposu    olcum
  saha-uygulamasi  toplama-ucu      olcum       | yonetim-konsolu dogrulayici     ayar
  yonetim-konsolu  toplama-ucu      ayar        | yonetim-konsolu kimlik-servisi  ayar
  rapor-ureteci    olcum-deposu     olcum       | rapor-ureteci   fatura-deposu   fatura
  denetim-kurumu   rapor-ureteci    kimlik      | rapor-ureteci   denetim-kurumu  fatura
  faturalama       denetim-gunlugu  kayit       | kimlik-servisi  denetim-gunlugu kayit
  is-emri          denetim-gunlugu  kayit       | faturalama      is-emri         emir`
  .trim().split(/\s*[|\n]\s*/).map((r) => {
    const [kaynak, hedef, sinif] = r.trim().split(/\s+/);
    return { kaynak, hedef, sinif, ad: `${kaynak}->${hedef}` };
  });

// Onceki dersin sistematik uretimi ayni kurallarla yeniden turetiliyor.
const gelen = (d) => AKIS.filter((a) => a.hedef === d);
const giden = (d) => AKIS.filter((a) => a.kaynak === d);
const komsu = (d) => [...gelen(d), ...giden(d)];
const gizliSinif = (s) => s === "kimlik" || s === "fatura";
const isSinif = (s) => s === "olcum" || s === "fatura" || s === "emir";
export const OGE = Object.fromEntries([
  ...Object.values(DUGUM).map((d) => [d.ad, { ad: d.ad, tur: d.tur,
    disaAcik: d.tur === "D" ? giden(d.ad).length > 0
      : gelen(d.ad).some((a) => DUGUM[a.kaynak].duzey < d.duzey),
    gizli: komsu(d.ad).some((a) => gizliSinif(a.sinif)),
    kritik: komsu(d.ad).some((a) => isSinif(a.sinif)),
    cokRol: new Set(gelen(d.ad).map((a) => DUGUM[a.kaynak].bolge)).size >= 2,
    islem: d.tur === "P" || (d.tur === "D" ? giden(d.ad).length > 0
      : giden(d.ad).some((a) => DUGUM[a.hedef].tur === "P")) }]),
  ...AKIS.map((a) => [a.ad, { ad: a.ad, tur: "A",
    disaAcik: DUGUM[a.kaynak].bolge !== DUGUM[a.hedef].bolge,
    gizli: gizliSinif(a.sinif), kritik: isSinif(a.sinif), cokRol: false, islem: false }]),
]);
export const KATEGORI = ["kimlik-taklidi", "kurcalama", "inkar", "bilgi-ifsasi",
  "hizmet-engelleme", "yetki-yukseltme"];
const UYGULANIR = { D: ["kimlik-taklidi", "inkar"], S: KATEGORI,
  P: ["kurcalama", "inkar", "bilgi-ifsasi", "hizmet-engelleme"],
  A: ["kurcalama", "bilgi-ifsasi", "hizmet-engelleme"] };
const GECERLI = { "kimlik-taklidi": (o) => o.disaAcik,
  "kurcalama": (o) => o.tur !== "A" || o.disaAcik,
  "inkar": (o) => o.islem, "bilgi-ifsasi": (o) => o.gizli,
  "hizmet-engelleme": (o) => o.kritik, "yetki-yukseltme": (o) => o.cokRol };
export const anlamli = (o, k) => UYGULANIR[o.tur].includes(k) && GECERLI[k](o);
export const SISTEMATIK = new Set(Object.values(OGE).flatMap((o) =>
  KATEGORI.filter((k) => anlamli(o, k)).map((k) => `${o.ad}|${k}`)));

// TD13: senaryo, bir saldirgan profilinden bir hedefe varan dugum dizisidir. Dizi yalnizca
// hangi ogenin kullanildigini soyler; adimin nasil yapildigi yazilmaz.
export const SENARYO = [
  { ad: "abone-hesabi-devralma", profil: "dis", hedef: "kimlik-deposu",
    dizi: ["abone", "abone-portali", "kimlik-servisi", "kimlik-deposu"],
    kategori: ["kimlik-taklidi", "bilgi-ifsasi"] },
  { ad: "fatura-tutarini-degistirme", profil: "abone", hedef: "fatura-deposu",
    dizi: ["abone", "abone-portali", "faturalama", "fatura-deposu"],
    kategori: ["kurcalama", "yetki-yukseltme"] },
  { ad: "sahte-olcum-kaydi", profil: "saha", hedef: "olcum-deposu",
    dizi: ["sayac-cihazi", "toplama-ucu", "dogrulayici", "olcum-deposu"],
    kategori: ["kimlik-taklidi", "kurcalama"] },
  { ad: "denetim-izini-bozma", profil: "ic-yetkili", hedef: "denetim-gunlugu",
    dizi: ["yonetim-konsolu", "kimlik-servisi", "denetim-gunlugu"],
    kategori: ["kurcalama", "inkar"] },
  { ad: "toplu-fatura-verisi-cikarma", profil: "dis-kurum", hedef: "fatura-deposu",
    dizi: ["denetim-kurumu", "rapor-ureteci", "fatura-deposu"],
    kategori: ["kimlik-taklidi", "bilgi-ifsasi"] },
];

// TD14: senaryonun dokundugu ogeler, dizideki dugumler ve aralarindaki akislardir.
export function dokunulan(s) {
  const ler = [...s.dizi];
  for (let i = 0; i + 1 < s.dizi.length; i++) ler.push(`${s.dizi[i]}->${s.dizi[i + 1]}`);
  return ler;
}

// TD15: senaryo iki tur tehdit dogurur. Oge tehdidi, dokunulan ogede senaryonun kategorisiyle
// ortusen ve orada anlamli olan tehdittir. Zincir tehdidi ardisik iki dugumun birlikte
// kullanilmasindan dogar; tek oge uzerinde tanimli olmadigi icin sistematik karsiligi yoktur.
export const ogeTehditleri = (s) => dokunulan(s)
  .flatMap((a) => s.kategori.filter((k) => anlamli(OGE[a], k)).map((k) => `${a}|${k}`));
export const zincirTehditleri = (s) => s.dizi.slice(0, -1)
  .map((d, i) => `${d}=>${s.dizi[i + 1]}|zincir`);

// TD16: senaryo kurmanin bedeli senaryo basina sabit sure arti dokunulan oge basina suredir.
export const SENARYO_DK = 25, OGE_DK = 3;

// Sistematik uretimin suresi de ayni girdilerden turetiliyor.
export const HAM_SAYI = Object.values(OGE).reduce((a, o) => a + UYGULANIR[o.tur].length, 0);
export const ELEME_DK = 1.5, YAZIM_DK = 4;
// tehdit/kapsama.mjs — senaryo temelli uretim kac tehdit buluyor, sistematik uretimin
// bulduklarinin kacini kaciriyor, ikisinin kesisimi ne.
import { OGE, KATEGORI, SENARYO, SISTEMATIK, dokunulan, ogeTehditleri, zincirTehditleri,
  SENARYO_DK, OGE_DK, HAM_SAYI, ELEME_DK, YAZIM_DK } from "./senaryo.mjs";

const yaz = (g, ...s) => console.log(s.map((v, i) =>
  (g[i] < 0 ? String(v).padEnd(-g[i]) : String(v).padStart(g[i]))).join(""));
const OGE_T = new Set(SENARYO.flatMap(ogeTehditleri));
const ZINCIR = new Set(SENARYO.flatMap(zincirTehditleri));
const SENARYO_KUME = new Set([...OGE_T, ...ZINCIR]);
const KESISIM = [...OGE_T].filter((t) => SISTEMATIK.has(t));
const YALNIZ_S = [...SISTEMATIK].filter((t) => !OGE_T.has(t));
const SENARYO_DAKIKA = SENARYO.length * SENARYO_DK +
  SENARYO.reduce((a, s) => a + dokunulan(s).length, 0) * OGE_DK;

console.log(`${SENARYO.length} senaryo; senaryo kumesi ${SENARYO_KUME.size} tehdit ` +
  `(${OGE_T.size} oge tehdidi + ${ZINCIR.size} zincir tehdidi), sistematik kume ` +
  `${SISTEMATIK.size}; kesisim ${KESISIM.length}`);

const A = [-28, -12, -17, 6, 11, 8, 10, 8];
console.log("\n1. senaryolar ve urettikleri");
yaz(A, "senaryo", "profil", "hedef", "adim", "dokunulan", "oge t.", "zincir t.", "dakika");
for (const s of SENARYO) {
  const d = dokunulan(s);
  yaz(A, s.ad, s.profil, s.hedef, s.dizi.length, d.length, ogeTehditleri(s).length,
    zincirTehditleri(s).length, SENARYO_DK + d.length * OGE_DK);
}

const B = [-22, 10, 16, 18];
console.log("\n2. iki yontemin kapsamasi");
yaz(B, "kume", "tehdit", "sistematigin %", "sistematige oran");
for (const [ad, n, p] of [
  ["sistematik kume", SISTEMATIK.size, "-"],
  ["senaryo kumesi", SENARYO_KUME.size, "-"],
  ["kesisim", KESISIM.length, (KESISIM.length / SISTEMATIK.size * 100).toFixed(1)],
  ["yalniz senaryoda", SENARYO_KUME.size - KESISIM.length, "-"],
  ["yalniz sistematikte", YALNIZ_S.length, (YALNIZ_S.length / SISTEMATIK.size * 100).toFixed(1)],
  ["birlesim", SISTEMATIK.size + SENARYO_KUME.size - KESISIM.length, "-"],
]) yaz(B, ad, n, p === "-" ? "-" : p + " %", (n / SISTEMATIK.size).toFixed(2) + " x");

const C = [-20, 9, 10, 12, 12];
console.log("\n3. dakika basina bulunan tehdit");
yaz(C, "yontem", "tehdit", "dakika", "tehdit/dk", "kacirdigi");
const SISTEMATIK_DK = HAM_SAYI * ELEME_DK + SISTEMATIK.size * YAZIM_DK;
for (const [ad, n, dk, kacan] of [
  ["sistematik uretim", SISTEMATIK.size, SISTEMATIK_DK, ZINCIR.size],
  ["senaryo temelli", SENARYO_KUME.size, SENARYO_DAKIKA, YALNIZ_S.length],
  ["ikisi birlikte", SISTEMATIK.size + SENARYO_KUME.size - KESISIM.length,
    SISTEMATIK_DK + SENARYO_DAKIKA, 0],
]) yaz(C, ad, n, dk.toFixed(1), (n / dk).toFixed(3), kacan);

const D = [-13, 12, 10, 11, 13];
console.log("\n4. senaryolarin kacirdigi tehditler nerede duruyor");
yaz(D, "oge turu", "sistematik", "kesisim", "kacirilan", "kacirilan %");
const TUR = { D: "dis varlik", S: "surec", P: "veri deposu", A: "veri akisi" };
for (const t of ["D", "S", "P", "A"]) {
  const s = [...SISTEMATIK].filter((x) => OGE[x.split("|")[0]].tur === t);
  const k = s.filter((x) => !OGE_T.has(x));
  yaz(D, TUR[t], s.length, s.length - k.length, k.length,
    ((k.length / s.length) * 100).toFixed(1));
}
const kat = KATEGORI.map((k) => ({ k, n: YALNIZ_S.filter((x) => x.endsWith("|" + k)).length }))
  .sort((a, b) => b.n - a.n);
console.log(`kacirilan ${YALNIZ_S.length} tehdidin kategori dagilimi: ` +
  kat.map((x) => `${x.k} ${x.n}`).join(", "));
console.log(`${ZINCIR.size} zincir tehdidinin hicbiri sistematik uretimde yoktur; ` +
  `bunlar tek oge uzerinde tanimli degildir`);
5 senaryo; senaryo kumesi 51 tehdit (39 oge tehdidi + 12 zincir tehdidi), sistematik kume 108; kesisim 39

1. senaryolar ve urettikleri
senaryo                     profil      hedef              adim  dokunulan  oge t. zincir t.  dakika
abone-hesabi-devralma       dis         kimlik-deposu         4          7       9         3      46
fatura-tutarini-degistirme  abone       fatura-deposu         4          7       8         3      46
sahte-olcum-kaydi           saha        olcum-deposu          4          7       9         3      46
denetim-izini-bozma         ic-yetkili  denetim-gunlugu       3          5       7         2      40
toplu-fatura-verisi-cikarma dis-kurum   fatura-deposu         3          5       6         2      40

2. iki yontemin kapsamasi
kume                      tehdit  sistematigin %  sistematige oran
sistematik kume              108               -            1.00 x
senaryo kumesi                51               -            0.47 x
kesisim                       39          36.1 %            0.36 x
yalniz senaryoda              12               -            0.11 x
yalniz sistematikte           69          63.9 %            0.64 x
birlesim                     120               -            1.11 x

3. dakika basina bulunan tehdit
yontem                 tehdit    dakika   tehdit/dk   kacirdigi
sistematik uretim         108     666.0       0.162          12
senaryo temelli            51     218.0       0.234          69
ikisi birlikte            120     884.0       0.136           0

4. senaryolarin kacirdigi tehditler nerede duruyor
oge turu       sistematik   kesisim  kacirilan  kacirilan %
dis varlik              8         3          5         62.5
surec                  40        17         23         57.5
veri deposu            12         6          6         50.0
veri akisi             48        13         35         72.9
kacirilan 69 tehdidin kategori dagilimi: hizmet-engelleme 24, kurcalama 19, inkar 11, bilgi-ifsasi 7, yetki-yukseltme 5, kimlik-taklidi 3
12 zincir tehdidinin hicbiri sistematik uretimde yoktur; bunlar tek oge uzerinde tanimli degildir

Sayılar ölçüm sınıfındadır; girdileri TD13–TD16’dır.

Beş Senaryo, Elli Bir Tehdit

Birinci tablo senaryoların kendi ölçüsünü verir. Beş senaryonun üçü dört adımlık, ikisi üç adımlıktır; dokunulan öğe sayısı yedi ile beş arasında değişir. Toplam 51 tehdit çıkar ve bu sayının bileşimi asıl bulgudur: 39 öğe tehdidi ve 12 zincir tehdidi.

Kırk altı ile kırk dakika arasında değişen senaryo süreleri toplam 218 dakika eder. Sistematik üretimin 666 dakikasıyla karşılaştırıldığında bu, yaklaşık üçte birdir. Senaryolar daha az öğeye dokunur çünkü hedefe giden yol çizgenin tamamını dolaşmaz: beş senaryo birlikte 43 öğenin ancak bir bölümünü kullanır.

Kesişim, Fark ve Birleşim

İkinci tablo bu dersin ana ölçümüdür. Sistematik küme 108, senaryo kümesi 51 tehdittir. Kesişim 39’dur — yani senaryoların bulduğu öğe tehditlerinin tamamı zaten sistematik kümededir. Bu beklenen bir sonuçtur: senaryo bir öğeye dokunduğunda o öğede anlamlı olan kategoriyi üretir, sistematik yöntem ise zaten bütün öğelerde bütün anlamlı kategorileri üretmiştir.

Yalnız senaryoda olan 12 tehdidin hepsi zincir tehdididir. Bunlar iki düğümün birlikte kullanılmasından doğar ve tek öğe üzerinde tanımlı olmadıkları için sistematik üretimde hiçbir satıra düşmezler. Yöntemin yapısı gereği düşemezler de: soru “bu öğede ne olabilir” olduğu sürece “bu öğede elde edilenin şu öğede geçerli olması” hiç sorulmaz.

Yalnız sistematikte olan 69 tehdit ise senaryoların gördüğü kümenin dışındadır ve sistematik kümenin %63,9’unu oluşturur. Beş senaryo çizgenin üçte birinden azına dokunur; geri kalanı hiç bakılmamış olarak kalır.

Birleşim 120 tehdittir — sistematik kümenin 1,11 katı. İki yöntem birbirinin yerine geçmez; birleşimin sistematik kümeden büyük olmasının tek sebebi 12 zincir tehdididir.

Neyi Kaçırıyor

Dördüncü tablo kaçırılanın nerede durduğunu ayırır. Kaçırma oranı veri akışı öğelerinde en yüksektir: 48 tehdidin 35’i kaçar (%72,9). Veri depolarında en düşüktür (%50,0), çünkü beş senaryonun beşi de bir depoda biter ve depolar senaryoların hedefidir.

Kategori dağılımı daha keskindir. Kaçırılan 69 tehdidin 24’ü hizmet engelleme, 19’u kurcalama, 11’i inkârdır; kimlik taklidi yalnız üç tehditle en az kaçırılan kategoridir. Sebep senaryo kurmanın kendi doğasındadır: senaryo bir hedefe ulaşmayı anlatır, hizmet engelleme ise hedefe ulaşmayı değil hizmeti durdurmayı amaçlar. Saldırgan bakışıyla kurulan senaryolar erişim peşindedir; erişim istemeyen tehdit sınıfı senaryo listesinde kendiliğinden yer almaz.

Bu, senaryo yönteminin ölçülebilir kör noktasıdır. “Saldırganın gözünden bakalım” cümlesi kulağa kapsayıcı gelir, ama ölçüldüğünde bir kategoriyi neredeyse tamamen dışarıda bırakır.

Dakika Başına Bulunan Tehdit

Üçüncü tablo iki yöntemi aynı birimde karşılaştırır. Sistematik üretim 666 dakikada 108 tehdit bulur: dakikada 0,162. Senaryo temelli üretim 218 dakikada 51 tehdit bulur: dakikada 0,234, yani 1,44 kat daha hızlı.

Bu oran tek başına okunduğunda yanıltıcıdır. Senaryo yönteminin verimli görünmesinin sebebi eleme yükünün olmamasıdır: senaryo hedeften geriye kurulduğu için ürettiği her tehdit zaten bir yolun üstündedir ve atılacak satır çıkmaz. Sistematik üretim ise 48 geçersiz tehdit için 72 dakika harcar. Verimliliği yaratan şey yöntemin zekâsı değil, arama alanının küçüklüğüdür.

Son sütun bunun bedelini yazar. Sistematik üretim tek başına kullanıldığında 12 zincir tehdidini kaçırır; senaryo temelli üretim tek başına kullanıldığında 69 tehdit kaçırır. İkisi birlikte 884 dakikada 120 tehdit verir — dakikada 0,136, yani her iki yöntemden de yavaş. Kapsamanın tamamlanması dakika verimliliğini düşürür ve bu, ölçümün kendisinin verdiği karardır: hızlı olan yöntem eksik olandır.

Özet

  • Senaryo, saldırgan profilinden hedefe uzanan bir düğüm dizisidir; beş senaryo 43 öğenin bir bölümüne dokunur ve 218 dakikada 51 tehdit üretir.
  • Elli bir tehdidin 39’u öğe tehdidi, 12’si zincir tehdididir; zincir tehditleri iki düğümün birlikte kullanılmasından doğar ve sistematik üretimde hiçbir karşılığı yoktur.
  • Kesişim 39’dur; senaryoların bulduğu öğe tehditlerinin tamamı sistematik kümenin içindedir. Senaryolar sistematik kümenin %63,9’unu (69 tehdit) kaçırır.
  • Kaçırılanın kategori dağılımı düzgün değildir: 24’ü hizmet engellemedir, yalnız 3’ü kimlik taklididir. Senaryo erişim peşinde olduğu için erişim istemeyen tehdit sınıfını dışarıda bırakır.
  • Senaryo yöntemi dakikada 0,234 tehditle sistematik üretimin 1,44 katı hızdadır, ama bu hız arama alanının küçüklüğünden gelir; ikisi birlikte 884 dakikada 120 tehdit verir.

Sonraki Adım

Zincir tehditleri bu dersin en dikkat çekici bulgusuydu: on iki kalem, hiçbir tek öğede tanımlı değil ve yalnız yol üzerinde görünüyor. Ama bu ders yolları yalnız saydı, aralarında bir sıralama yapmadı. Beş senaryonun beşi de listede eşit ağırlıkta durur.

Gerçekte yollar eşit değildir. Bir hedefe birden çok yoldan gidilebilir ve bu yolların bazıları diğerlerinden ucuzdur; savunmanın ilgilendiği şey en pahalı yol değil, en ucuz yoldur. Bunu sayabilmek için senaryoyu düz bir dizi olarak değil, hedeften geriye dallanan bir yapı olarak yazmak gerekir: kök hedef, alt hedefler ve önkoşullarıyla maliyetleri yazılmış yaprak adımlar. Sonraki ders bu yapıyı kurar, en ucuz yolun maliyetini hesaplar ve tek soruyu sorar: bir düğümü kapatmak ağacın maliyetini kaç kat artırır.

İlerlemeni kaydetmek ve not almak için Giriş yap

Notlarım

Not almak için giriş yapmalısın.

Aramak için yazmaya başlayın.

↑↓ Esc gezin · aç · kapat