İçeriğe geç
academia.sh

Ders 17 / 22

Görev Başarımı ve Adım Verimliliğinin Ayrı Ölçülmesi

Tek bir başarım oranının dört ayrı durumu üst üste yığdığının adım üzerinde gösterilmesi: yirmi dört görevlik kurgu kümede araçsız tek adımlı taban 0,2917 çıkıyor ve bu oranın tamamı yanlış dizi ile doğru yanıt kutusunda, çünkü yedi belge görevinin hepsi hiçbir araç çağrılmadan yanıtlanıyor. Dar bütçede döngü 0,8750, kurs bütçesinde 0,9583 veriyor; kurs bütçesinde tek başarısızlık doğru dizi ile yanlış yanıt kutusunda ve dizisi eksiksiz tamamlanmış bir görevin arada kalan fazla bir çağrıyla bozulmasından geliyor. Doğru yanıt başına adım tabanda 3,4286, kurs bütçesinde 4,2174 çıkıyor, yani verimlilik tek başına okunduğunda hiçbir aracı çağırmayan tabanı kazandırıyor; araç gerektiren on yedi görevde taban sıfır doğru yanıt veriyor. İki koşum farkı tabanda 0,0000, dar bütçede 0,0417.

İçindekiler

On altı derste bir ajan kuruldu ve donatıldı: döngü yazıldı, nerede duracağı belirlendi, yan etkili çağrılar onaya bağlandı, araçlar tanımlandı, yürütüldü ve yetkileri sınırlandı, belleği pencereye sığdırıldı, kalıcı kayıtları yazıldı, sıkıştırıldı ve eskitildi. Bir soru hiç sorulmadı: bu ajanın çalıştığını nereden biliyoruz.

Bir ajan koşumundan geriye genellikle tek bir oran kalır: kaç görev doğru yanıtlandı. Bu dersin iddiası, o oranın dört ayrı durumu üst üste yığdığı ve yığının içinden ajanın işi yaparak mı yoksa yapmadan mı doğru bulduğunun okunamadığıdır. Aynı ayrım M28/K04 Gömme Vektörleri ve Erişim Artırılmış Üretim kursunda doğru parça ile doğru yanıt üzerinde kurulmuştu; yordamı orada kaldı ve burada tekrarlanmaz. Buraya taşınan yalnız ayrımın kendisidir, bu kez adım üzerinde.

  • KL1. Abone kayıtları, belge dağarcığı, beş araç, yirmi dört görev ve ajan döngüsü kurgudur ve ders içinde üretilir. Gerçek bir model uç noktası ya da araç sunucusu çağrılmaz; araç seçimi derinliğe bağlı tek bir çekilişten gelir.
  • KL2. Taban çizgisi tek adımlı, araçsız çağrıdır; benzetici yalnız istek metnini görür.
  • KL3. Dizi ölçüsü: adım izinde görevin beklenen araç dizisi sırasıyla ve hatasız geçiyorsa dizi doğrudur; araya giren fazla çağrı diziyi bozmaz.
  • KL4. Yanıt ölçüsü: döngünün bıraktığı sonuç doğru yanıta birebir eşitse yanıt doğrudur.
  • KL5. Adım verimliliği doğru yanıt başına adımdır; bedelin öbür birimleri araç çağrısı ve belirteçtir, süre yazılmaz.
  • KL6. Her ölçü iki koşumda basılır (tohum 20260218 ve 20260219). İki koşum farkının altında kalan fark ölçülmemiş sayılır.

Kurgu Ortam, Beş Araç ve Ajan Döngüsü

Beş araç sayaç okur, tüketim hesaplar, tarife uygular, belge arar ve kayıt yazar; sonuncusu yan etkilidir. Her görev bilinen bir dizi ile çözülür.

# KURGUDUR. Abone kayitlari, belge dagarcigi, arac kumesi, gorev kumesi ve ajan
# dongusu ders icinde uretilir; gercek bir uc nokta ya da arac sunucusu cagrilmaz.
TOHUM, M32 = 20260218, 0xFFFFFFFF


def uretec(t):
    x = ((t ^ (t >> 16)) * 2246822507) & M32
    x = ((x ^ (x >> 13)) * 3266489909) & M32
    s = [(x ^ (x >> 16)) & M32]

    def sonraki():
        s[0] = (s[0] * 1664525 + 1013904223) & M32
        return s[0] / 4294967296
    return sonraki


def ayrik(u, w):
    t = 0.0
    for i, x in enumerate(w):
        t += x
        if u < t:
            return i
    return len(w) - 1


def belirtecle(m):
    b = []
    for s in str(m).lower().replace(",", " , ").split():
        while len(s) > 5:
            b.append(s[:5])
            s = s[5:]
        b.append(s)
    return b


def izno(m):
    h = 2166136261
    for c in str(m):
        h = ((h ^ ord(c)) * 16777619) & M32
    return h


BOLGE = ["dogu", "bati", "kuzey", "guney", "merkez"]
TIP = ["mesken", "isyeri"]
ABONE = {}
for i in range(60):
    r = uretec(TOHUM + 31 * i)
    onceki = 10000 + int(r() * 80000)
    ABONE[f"A{i + 1:03d}"] = {"bolge": BOLGE[int(r() * 5)], "tip": TIP[int(r() * 2)],
                              "onceki": onceki, "simdiki": onceki + int(r() * 70)}
BASAMAK, USTU = ((10, 4), (25, 7), (40, 11)), 16
ISYERI_KAT = 2
BELGE = {"TR01": "tarife basamaklari 10 25 40 metrekup ve ustu",
         "TR02": "isyeri abonesinde birim ucret iki katidir",
         "SY01": "endeks farki tuketimi verir sayac donusu 100000 eklenir",
         "AR01": "ariza kaydi acildiginda saha ekibi iki gun icinde gider",
         "KS01": "planli kesinti duyurusu bir hafta once yayimlanir"}

CAGRI = [0]                              # arac cagri sayaci


def _bedel(m3, tip):
    kalan, alt, top = m3, 0, 0
    for ust, birim in BASAMAK:
        dilim = min(kalan, ust - alt)
        if dilim <= 0:
            break
        top += dilim * birim
        kalan -= dilim
        alt = ust
    top += kalan * USTU
    return top * (ISYERI_KAT if tip == "isyeri" else 1)


def t_sayac_oku(abone=None, **_):
    a = ABONE.get(abone)
    if a is None:
        return {"hata": "abone yok"}
    return {"onceki": a["onceki"], "simdiki": a["simdiki"], "tip": a["tip"], "bolge": a["bolge"]}


def t_tuketim(onceki=None, simdiki=None, **_):
    if onceki is None or simdiki is None:
        return {"hata": "eksik alan"}
    f = simdiki - onceki
    return {"m3": f + 100000 if f < 0 else f}


def t_tarife(m3=None, tip="mesken", **_):
    if m3 is None:
        return {"hata": "eksik alan"}
    return {"tutar": _bedel(m3, tip)}


def t_belge(anahtar=None, **_):
    if not anahtar:
        return {"hata": "eksik alan"}
    ab = set(belirtecle(anahtar))
    en, kod = -1, None
    for k, m in BELGE.items():
        o = len(ab & set(belirtecle(m)))
        if o > en:
            en, kod = o, k
    return {"kod": kod, "metin": BELGE[kod]} if en > 0 else {"hata": "bulunamadi"}


def t_kayit(abone=None, sutun=None, deger=None, **_):
    if not (abone and sutun and deger is not None):
        return {"hata": "eksik alan"}
    return {"yazildi": True, "abone": abone, "sutun": sutun, "deger": deger}


ARAC = {
    "sayac_oku":  {"islev": t_sayac_oku, "alan": ("abone",), "yan_etki": False},
    "tuketim":    {"islev": t_tuketim, "alan": ("onceki", "simdiki"), "yan_etki": False},
    "tarife":     {"islev": t_tarife, "alan": ("m3", "tip"), "yan_etki": False},
    "belge_ara":  {"islev": t_belge, "alan": ("anahtar",), "yan_etki": False},
    "kayit_yaz":  {"islev": t_kayit, "alan": ("abone", "sutun", "deger"), "yan_etki": True},
}
ARAC_ADI = list(ARAC)


def cagir_arac(ad, durum):
    """Sema disindaki alanlar suzulur; eksik alan aracin kendi hatasidir."""
    CAGRI[0] += 1
    if ad not in ARAC:
        return {"hata": "arac yok"}
    kw = {a: durum[a] for a in ARAC[ad]["alan"] if a in durum}
    return ARAC[ad]["islev"](**kw)


GOREV = []
for i in range(24):
    r = uretec(TOHUM + 9973 * i)
    ab = f"A{1 + int(r() * 60):03d}"
    t = ayrik(r(), [0.30, 0.22, 0.20, 0.28])
    if t == 0:
        GOREV.append({"ad": f"G{i + 1:02d}", "tur": "bedel", "abone": ab,
                      "istek": f"{ab} abonesinin bu donem bedeli nedir",
                      "dizi": ("sayac_oku", "tuketim", "tarife")})
    elif t == 1:
        GOREV.append({"ad": f"G{i + 1:02d}", "tur": "tuketim", "abone": ab,
                      "istek": f"{ab} abonesinin bu donem tuketimi kac metrekup",
                      "dizi": ("sayac_oku", "tuketim")})
    elif t == 2:
        GOREV.append({"ad": f"G{i + 1:02d}", "tur": "belge", "abone": ab,
                      "istek": "sayac donusunde endeks farki nasil hesaplanir",
                      "dizi": ("belge_ara",)})
    else:
        GOREV.append({"ad": f"G{i + 1:02d}", "tur": "kayit", "abone": ab,
                      "istek": f"{ab} abonesinin bedelini hesapla ve kayda yaz",
                      "dizi": ("sayac_oku", "tuketim", "tarife", "kayit_yaz")})


def dogru_yanit(g):
    a = ABONE[g["abone"]]
    f = a["simdiki"] - a["onceki"]
    m3 = f + 100000 if f < 0 else f
    if g["tur"] == "tuketim":
        return m3
    if g["tur"] == "belge":
        return "SY01"
    return _bedel(m3, a["tip"])


def gorme(d):
    return max(0.34, 0.80 - 0.09 * (d - 1))       # dogru araci secme payi, derinlikle duser


def ajan(g, en_cok_adim=8, tohum=TOHUM, oz_elestiri=False, onay=False):
    """KURGU ajan dongusu. Gercek bir model cagrilmaz; arac secimi
    gorevin dizisine ve derinlige bagli tek bir cekilisten gelir."""
    r = uretec(tohum ^ izno(g["ad"]))
    alan = {"abone": g["abone"], "anahtar": g["istek"], "sutun": "bedel"}
    iz, adim, bel, hata = [], 0, 0, 0
    dizi, k = g["dizi"], 0
    while adim < en_cok_adim:
        adim += 1
        bel += 60 + 22 * len(iz)
        hedef = dizi[k] if k < len(dizi) else None
        if hedef is None:                          # is bitti , ajan durmali
            if r() < 0.88:
                return {"bitti": True, "adim": adim, "iz": iz, "belirtec": bel,
                        "hata": hata, "yanit": alan.get("sonuc"), "onay": alan.get("onay", 0)}
            sec = ARAC_ADI[int(r() * len(ARAC_ADI))]
        else:
            sec = hedef if r() < gorme(k + 1) else ARAC_ADI[int(r() * len(ARAC_ADI))]
        if ARAC[sec]["yan_etki"] and onay:
            alan["onay"] = alan.get("onay", 0) + 1
        if sec == "kayit_yaz":
            alan["deger"] = alan.get("sonuc")
        s = cagir_arac(sec, alan)
        iz.append((sec, "hata" in s))
        bel += 30
        if "hata" in s:
            hata += 1
            if oz_elestiri:
                bel += 40
            continue
        alan.update({kk: vv for kk, vv in s.items() if kk != "hata"})
        if sec == "tuketim":
            alan["sonuc"] = s["m3"]
        if sec == "tarife":
            alan["sonuc"] = s["tutar"]
        if sec == "belge_ara":
            alan["sonuc"] = s["kod"]
        if sec == hedef:
            k += 1
    return {"bitti": False, "adim": adim, "iz": iz, "belirtec": bel, "hata": hata,
            "yanit": alan.get("sonuc"), "onay": alan.get("onay", 0)}


TUR = ("bedel", "tuketim", "belge", "kayit")
sayim = {t: sum(1 for g in GOREV if g["tur"] == t) for t in TUR}
print(f"kurgu ortam {len(ABONE)} abone , {len(BELGE)} belge , {len(ARAC)} arac")
print("gorev", len(GOREV), ",", " , ".join(f"{k} {v}" for k, v in sayim.items()))
kurgu ortam 60 abone , 5 belge , 5 arac
gorev 24 , bedel 6 , tuketim 8 , belge 7 , kayit 3

Dizi ve Yanıt: İki Ayrı Sütun

Birinci sütun yanıta hiç bakmaz: adım izinde beklenen dizi sırasıyla ve hatasız geçti mi. İkinci sütun ize hiç bakmaz. İki sütun kesiştiğinde her görev dört kutudan birine düşer.

def aracsiz(g, tohum=TOHUM):
    """Taban cizgisi: tek adimli, araci olmayan cagri. Hicbir arac cagrilmaz;
    benzetici yalniz istek metnini gorur ve kod onekinden tahmin yurutur."""
    r = uretec(tohum ^ izno("tek" + g["ad"]))
    onek = {"sayac": "SY", "tarif": "TR", "ariza": "AR", "kesin": "KS"}
    b = set(belirtecle(g["istek"]))
    for k, p in onek.items():
        if k in b:
            aday = [c for c in BELGE if c.startswith(p)]
            return aday[int(r() * len(aday))]
    return 10 * int(r() * 20)


def dizi_dogru(g, iz):
    """Adim izinde beklenen arac dizisi sirasiyla ve hatasiz geciyor mu."""
    k = 0
    for ad, hatali in iz:
        if k < len(g["dizi"]) and ad == g["dizi"][k] and not hatali:
            k += 1
    return k == len(g["dizi"])


def dort_durum(gorevler, butce, tohum=TOHUM):
    """Butce sifirsa taban cizgisi, degilse dongu kosulur."""
    d = {"dd": 0, "dy": 0, "yd": 0, "yy": 0, "adim": 0, "bel": 0, "cagri": 0}
    c0 = CAGRI[0]
    for g in gorevler:
        s = ajan(g, en_cok_adim=butce, tohum=tohum) if butce else None
        iz, yanit, adim, bel = ((s["iz"], s["yanit"], s["adim"], s["belirtec"]) if s
                                else ([], aracsiz(g, tohum), 1, 60))
        dd, dy = dizi_dogru(g, iz), yanit == dogru_yanit(g)
        d["dd" if dd and dy else "dy" if dd else "yd" if dy else "yy"] += 1
        d["adim"] += adim
        d["bel"] += bel
    d["cagri"] = CAGRI[0] - c0
    return d


KURULUM = (("aracsiz", 0), ("butce 4", 4), ("butce 8", 8))
print("kurulum   d+d  d+y  y+d  y+y  basarim  2.kosum     fark  adim  cagri  belirtec  adim/dogru")
for ad, b in KURULUM:
    d, e = dort_durum(GOREV, b), dort_durum(GOREV, b, 20260219)
    n, m = (d["dd"] + d["yd"]) / 24, (e["dd"] + e["yd"]) / 24
    print(f"{ad:<9} {d['dd']:>3} {d['dy']:>4} {d['yd']:>4} {d['yy']:>4} {n:>8.4f} {m:>8.4f}"
          f" {m - n:>+8.4f} {d['adim']:>5} {d['cagri']:>6} {d['bel']:>9}"
          f" {d['adim'] / max(n * 24, 1):>11.4f}")

print("\ngorev turu dokumu (d+d / d+y / y+d / y+y)")
print(f"{'tur':<9} {'gorev':>6} {'aracsiz':>16} {'butce 8':>16}")
for tur in TUR:
    gs = [g for g in GOREV if g["tur"] == tur]
    sat = [" / ".join(str(dort_durum(gs, b)[k]) for k in ("dd", "dy", "yd", "yy"))
           for b in (0, 8)]
    print(f"{tur:<9} {len(gs):>6} {sat[0]:>16} {sat[1]:>16}")

ag = [g for g in GOREV if g["tur"] != "belge"]
print(f"\narac gerektiren {len(ag)} gorev , dogru yanit ve adim")
for ad, b in KURULUM:
    d = dort_durum(ag, b)
    print(f"{ad:<9} dogru {d['dd'] + d['yd']:>3} / {len(ag)}   adim {d['adim']:>4}")
kurulum   d+d  d+y  y+d  y+y  basarim  2.kosum     fark  adim  cagri  belirtec  adim/dogru
aracsiz     0    0    7   17   0.2917   0.2917  +0.0000    24      0      1440      3.4286
butce 4    20    0    1    3   0.8750   0.8333  -0.0417    84     64      9402      4.0000
butce 8    23    1    0    0   0.9583   0.9583  +0.0000    97     74     11978      4.2174

gorev turu dokumu (d+d / d+y / y+d / y+y)
tur        gorev          aracsiz          butce 8
bedel          6    0 / 0 / 0 / 6    6 / 0 / 0 / 0
tuketim        8    0 / 0 / 0 / 8    8 / 0 / 0 / 0
belge          7    0 / 0 / 7 / 0    7 / 0 / 0 / 0
kayit          3    0 / 0 / 0 / 3    2 / 1 / 0 / 0

arac gerektiren 17 gorev , dogru yanit ve adim
aracsiz   dogru   0 / 17   adim   17
butce 4   dogru  14 / 17   adim   64
butce 8   dogru  16 / 17   adim   77

Dört Bileşimin Okunması

İlk satır tabanı verir. Araçsız tek adım 0,2917 yapıyor ve bu oranın tamamı üçüncü kutudadır: yanlış dizi, doğru yanıt. Çağrı sütunu sıfırdır; yedi belge görevinin hepsi doğru gelmiştir, çünkü bu görevlerin isteği aynı metindir ve içindeki sayaç sözcüğü belge kodunun önekini ele verir. Tek sayı ajanın görevlerin dörtte birinden fazlasını çözdüğünü söyler; dört durum tablosu aynı satırda hiçbir işin yapılmadığını söyler.

Asıl gösterim son satırdadır. Sekiz adımlık bütçede tek başarısızlık ikinci kutudadır: doğru dizi, yanlış yanıt. Bir kayıt görevinde beklenen dört araç sırasıyla ve hatasız geçti, ama tarife ile kayıt arasında fazladan bir belge araması yapıldı ve o çağrı durumdaki sonucu bir belge koduyla değiştirdi. Ajan doğru işi doğru sırayla yaptı, sonra kendi sonucunu bozdu. Tablo burada hangi düzeltmenin gerektiğini yazar, çünkü araç seçimi kusuru ile durum bozulması kusuru ayrı yerlerde onarılır.

Dar bütçe satırı üçüncü kutunun döngüde de dolabildiğini gösterir. Bir kayıt görevinde doğru tutar bulundu, ama bütçe kayıt yazımına yetmedi: dizi eksik, yanıt doğru. Tek sayı bu görevi başarı sayar; oysa yan etkili adım hiç gerçekleşmemiştir. Tür dökümü tabanın yedi doğrusunun tamamını belge türünde, sekizlik bütçenin tek başarısızlığını kayıt türünde toplar.

Hangi farkın sayılabileceğini iki koşum söyler. Dar bütçede fark 0,0417, yani tek bir görev; tabanda ve sekizlik bütçede 0,0000. İki bütçe arasındaki 0,0833’lük yükseliş bandın iki katıdır ve sayılabilir; kutu geçişlerinin tek tek büyüklüğü ölçülmemiş sayılır.

Doğru Yanıt Başına Adım

İkinci ölçü bedeli başarıma bağlar. Sekizlik bütçede ajan 97 adım harcayıp 23 doğru yanıt üretiyor: adım başına 4,2174. Dar bütçede 84 adım ve 21 doğru yanıt, yani 4,0000.

Tuzak ilk satırdadır. Araçsız taban 24 adımda 7 doğru yanıt veriyor ve adım verimliliği 3,4286 çıkıyor, yani üç kurulumun en iyisi. Hiçbir araç çağırmayan, hiçbir hesap yapmayan kurulum verimlilik ölçüsünde kazanıyor, çünkü bu ölçü paydaya yalnız doğru yanıtları koyar ve hangi görevlerin çözülebildiğini hiç sormaz.

Son tablo paydayı düzeltir. Yalnız araç gerektiren on yedi görev sayıldığında taban 0 / 17 veriyor ve verimlilik bu alt kümede tanımsız kalıyor; dar bütçe 14, sekizlik bütçe 16 doğru yanıt veriyor. Ölçü bu yüzden tek başına okunmaz: hangi görev kümesinde ve hangi başarım düzeyinde ölçüldüğü yazılmadan, bir ajanı ucuzlatmanın en kestirme yolu çözebildiği görevleri azaltmaktır.

Özet

  • Tek bir başarım oranı dört durumu üst üste yığar: doğru dizi ile doğru yanıt, doğru dizi ile yanlış yanıt, yanlış dizi ile doğru yanıt, yanlış dizi ile yanlış yanıt.
  • Araçsız taban 0,2917 çıkar ve bu oranın tamamı yanlış dizi ile doğru yanıt kutusundadır; ajan hiçbir araç çağırmamıştır.
  • Sekiz adımlık bütçede başarım 0,9583’tür ve tek başarısızlık doğru dizi ile yanlış yanıt kutusundadır: dizi eksiksiz tamamlanmış, araya giren fazla bir çağrı sonucu bozmuştur.
  • Doğru yanıt başına adım tabanda 3,4286, sekizlik bütçede 4,2174’tür; ölçü tek başına okunduğunda tabanı kazandırır, çünkü araç gerektiren on yedi görevde taban sıfır doğru verir.
  • İki koşum farkı tabanda ve sekizlik bütçede 0,0000, dar bütçede 0,0417’dir; tek görevlik kutu geçişleri bu bandın altında kalır.

Sonraki Adım

Bu ders bir ajan koşumunun sayısını ikiye ayırdı: işin yapılıp yapılmadığı ve yanıtın doğru olup olmadığı. İkisi de bir şeyi varsayar: araçların kendisi doğrudur. Araçlardan biri yanlış hesap yapsaydı, eksik alanı sessizce yutsaydı ya da tanımı işlevine uymasaydı, tablo yine dolar ve hangi aracın bozuk olduğunu söylemezdi. Bir sonraki ders her aracı döngüden ayırıp tek tek sınar: beş araca konan kusurların kaçı bu sınamayla yakalanıyor ve hangi kusur sınıfı bu katmandan hiç görünmüyor.

İ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