İçeriğe geç
academia.sh

Ders 03 / 10

Akış Tabanlı Yönetim

İş sınırlamanın ve akış ölçütlerinin ölçülmesi: teslim süresi, çevrim süresi ve iş çıkarma aynı koşumda tanımlanır, iş sınırı birden on altıya taranır, sınırın altında boş geçen kapasite ile üstünde geçişe giden iş gücü sayılır.

İçindekiler

Önceki dersin bütün ölçümleri bir ritim varsayımına dayanıyordu: iş kalemi ancak bir sonraki planlamada başlar, ancak yinelemenin sonunda kabul edilir. Ritim kaldırıldığında ortada bir parti kalmaz ve iş kalemi hazır olduğu anda çekilir. Geriye tek bir denetim aracı kalır — aynı anda kaç kalemin açık olduğu. Bu ders o sayıyı bir uçtan diğerine tarar.

Taramanın anlamlı olması için önce üç ölçütün ayrılması gerekir. Teslim süresi kalemin istendiği günden işletime geçtiği güne kadarki toplam süredir. Çevrim süresi kalemin çalışmaya alındığı günden bittiği güne kadarki süredir; teslim süresinin, kuyrukta beklenen kısmı çıkarılmış hâli. İş çıkarma birim zamanda biten kalem sayısıdır. Üçü aynı koşumdan çıkar ve üçü farklı bir karara işaret eder. İş sınırı bir geri basınç aracıdır; kuyruk mekaniği ile geri basınç bu müfredatta başka yerde ölçüldüğü için burada sayılan şey kuyruğun kendisi değil, sınırın insan akışındaki etkisidir. Through-line bölgesel kütüphane ağıdır ve kurgudur.

Üç Ölçüt Tek Koşumda

Aşağıdaki blok bir modeldir, ölçüm değil.

SM13 — altmış iş kalemi bir üreteçle türetilir, üreteç kendi yazılır ve tohum görünürdür. Her kalemin bir boyutu (2–8 adam-gün) ve bir geliş günü vardır; aynı küme bütün sınır değerlerinde kullanılır.

SM14 — bir kaleme günde en çok 1 adam-gün verilebilir, çünkü kalem üzerinde tek kişi çalışır. Bu, sınırın altında ne kaybedildiğini belirleyen kuraldır: dört kişilik ekip iki kalem açıkken günde en çok 2 adam-gün harcayabilir, kalan iki kişi boş kalır.

SM15 — açık kalem sayısı kişi sayısını aştığında gün bir bölümünü geçişe verir. Kişi başına düşen her fazladan açık kalem, günlük kapasitenin %15’ini götürür. Sınırın üstünde ne kaybedildiğini belirleyen kural budur.

SM16 — iş sınırı S açık kalem sayısını sınırlar. Sınır doluyken gelen kalem kuyrukta bekler ve bu bekleme teslim süresine girer, çevrim süresine girmez.

SM17 — kalemler geliş sırasına göre çekilir ve çalışmaya alınan kalem yarıda bırakılmaz. Öncelik sırası değişseydi teslim süresinin dağılımı değişirdi; sabit tutulması, taramada değişen tek şeyin sınırın kendisi olmasını sağlar.

// akis.mjs — is sinirlamali cekme sistemi (model); akis olcutleri tek sinirda tanimlanir
import { writeFileSync } from "node:fs";

const KISI = 4;        // ekip
const CEZA = 0.15;     // kisi basina her fazladan acik kalemin gunluk kaybi

// SM13: uretec kendi yazilir, tohum gorunur; ayni kalem kumesi butun sinirlarda kullanilir.
let tohum = 20250715;
const rast = () => (tohum = (tohum * 1103515245 + 12345) % 2147483648) / 2147483648;
let t = 0;
const KALEM = [...Array(60)].map((_, no) => {
  t += rast() < 0.35 ? 0 : 1;                    // gelisler yaklasik gunde 1,5 kalem
  return { no, boyut: 2 + Math.floor(rast() * 7), gelis: t };
});

function kostur(S) {
  const kuyruk = KALEM.map((k) => ({ ...k, kalan: k.boyut, bas: -1, bit: -1 }));
  const acik = [];
  let gun = 0, bosKapasite = 0, gecisKaybi = 0;
  while (kuyruk.some((k) => k.bit < 0)) {
    gun += 1;
    for (const k of kuyruk)                      // is sinirinin bosu kadar kalem cekilir
      if (acik.length < S && k.bas < 0 && k.gelis <= gun) { k.bas = gun; acik.push(k); }
    const n = acik.length;
    if (n === 0) { bosKapasite += KISI; continue; }
    // SM15: kisi basina birden cok acik kalem varsa gunun bir bolumu gecise gider
    const etkin = KISI * (1 - CEZA * Math.max(0, n / KISI - 1));
    gecisKaybi += KISI - etkin;
    const pay = Math.min(1, etkin / n);          // SM14: bir kaleme gunde en cok 1 adam-gun
    bosKapasite += Math.max(0, etkin - pay * n);
    for (const k of [...acik]) {
      k.kalan -= pay;
      if (k.kalan <= 1e-9) { k.bit = gun; acik.splice(acik.indexOf(k), 1); }
    }
  }
  const olcum = kuyruk.map((k) => ({
    no: k.no, boyut: k.boyut, teslim: k.bit - k.gelis + 1, cevrim: k.bit - k.bas + 1,
    bekleme: k.bit - k.bas + 1 - k.boyut, kuyrukta: k.bas - k.gelis,
  }));
  const ort = (f) => olcum.reduce((a, x) => a + f(x), 0) / olcum.length;
  return { S, gun, olcum,
    teslim: ort((x) => x.teslim), cevrim: ort((x) => x.cevrim), kuyrukta: ort((x) => x.kuyrukta),
    beklemePayi: ort((x) => x.bekleme) / ort((x) => x.cevrim),
    cikarma: KALEM.length / gun, bosKapasite: +bosKapasite.toFixed(1), gecisKaybi: +gecisKaybi.toFixed(1) };
}

const TARAMA = [1, 2, 3, 4, 5, 6, 8, 10, 12, 16].map(kostur);
writeFileSync("tarama.json", JSON.stringify(TARAMA.map(({ olcum, ...r }) => r)));

const bes = TARAMA[4];
console.log(`is kalemi: ${KALEM.length}, temel is: ${KALEM.reduce((a, k) => a + k.boyut, 0)} adam-gun, ` +
  `son gelis ${KALEM[KALEM.length - 1].gelis}. gun, ekip ${KISI} kisi (tohum ${20250715})`);
console.log(`\nis siniri ${bes.S}: uc olcut ilk sekiz kalemde (gun):`);
console.log(`${"kalem".padStart(6)}${"boyut".padStart(7)}${"kuyrukta".padStart(10)}` +
  `${"cevrim suresi".padStart(15)}${"bunun beklemesi".padStart(17)}${"teslim suresi".padStart(15)}`);
for (const x of bes.olcum.slice(0, 8))
  console.log(`${String(x.no).padStart(6)}${String(x.boyut).padStart(7)}${String(x.kuyrukta).padStart(10)}` +
    `${String(x.cevrim).padStart(15)}${String(x.bekleme).padStart(17)}${String(x.teslim).padStart(15)}`);
console.log(`\nteslim suresi = kuyrukta bekleme + cevrim suresi; cevrim suresi = calisma + bekleme`);
console.log(`ortalama: teslim ${bes.teslim.toFixed(1)}, cevrim ${bes.cevrim.toFixed(1)}, ` +
  `kuyrukta ${bes.kuyrukta.toFixed(1)} gun; bekleme payi %${(100 * bes.beklemePayi).toFixed(1)}; ` +
  `is cikarma ${bes.cikarma.toFixed(2)} kalem/gun`);
is kalemi: 60, temel is: 285 adam-gun, son gelis 40. gun, ekip 4 kisi (tohum 20250715)

is siniri 5: uc olcut ilk sekiz kalemde (gun):
 kalem  boyut  kuyrukta  cevrim suresi  bunun beklemesi  teslim suresi
     0      7         1              9                2             10
     1      7         0              9                2              9
     2      7         0              9                2              9
     3      5         0              7                2              7
     4      2         0              3                1              3
     5      2         2              3                1              5
     6      2         4              3                1              7
     7      3         3              4                1              7

teslim suresi = kuyrukta bekleme + cevrim suresi; cevrim suresi = calisma + bekleme
ortalama: teslim 21.9, cevrim 6.6, kuyrukta 15.3 gun; bekleme payi %27.8; is cikarma 0.74 kalem/gun

Altıncı kalem ölçütlerin neden ayrıldığını tek satırda gösterir: iki adam-günlük bir iş, çalışmaya alındıktan sonra üç günde biter, ama istendiği günden itibaren yedi gün sürer. Çevrim süresi kalemin üçte birlik bir bekleme taşıdığını söyler; teslim süresi ise sürenin dörtte üçünün iş başlamadan önce geçtiğini söyler. Bu iki ölçüt aynı koşumda birbirinin dört katı olabilir.

İş Sınırının Taranması

SM18 — üç ölçüt üç ayrı kararı verdirir ve taramanın amacı hangisinin hangi sınırı işaret ettiğini görmektir. Aşağıdaki blok sınırı birden on altıya kadar tarar.

// sinir.mjs — akis.mjs'in yazdigi tarama sonucunu okur; is siniri bastan sona taranir
import { readFileSync } from "node:fs";

const T = JSON.parse(readFileSync("tarama.json", "utf8"));
const TEMEL = 285;
const tablo = (baslik, satir, ust) => {
  const yaz = (h) => console.log(h.map((c, i) => String(c).padStart(baslik[i][1])).join(""));
  if (ust) { console.log(); console.log(ust); }
  yaz(baslik.map((b) => b[0])); satir.forEach(yaz);
};

tablo([["is siniri", 10], ["toplam gun", 12], ["teslim suresi", 15], ["cevrim suresi", 15],
       ["kuyrukta", 10], ["bekleme payi", 14], ["is cikarma", 12]],
  T.map((r) => [r.S, r.gun, r.teslim.toFixed(1), r.cevrim.toFixed(1), r.kuyrukta.toFixed(1),
                `%${(100 * r.beklemePayi).toFixed(1)}`, r.cikarma.toFixed(2)]));

tablo([["is siniri", 10], ["toplam kapasite", 17], ["temel is", 10], ["bos gecen", 11],
       ["gecise giden", 14], ["bos oran", 10]],
  T.map((r) => [r.S, 4 * r.gun, TEMEL, r.bosKapasite.toFixed(1), r.gecisKaybi.toFixed(1),
                `%${((100 * r.bosKapasite) / (4 * r.gun)).toFixed(1)}`]),
  "kapasitenin nereye gittigi (adam-gun):");

// SM18: uc olcut uc ayri karari verdirir; her biri baska bir siniri en iyi gosterir.
const enAz = (f) => T.reduce((a, b) => (f(b) < f(a) ? b : a));
const tepe = enAz((r) => -r.cikarma), son = T[T.length - 1];
console.log(`\nen kisa cevrim suresi sinir ${enAz((r) => r.cevrim).S}, ` +
  `en kisa teslim suresi sinir ${enAz((r) => r.teslim).S}, ` +
  `en yuksek is cikarma sinir ${tepe.S} (${tepe.cikarma.toFixed(2)} kalem/gun)`);
console.log(`is cikarma sinir ${tepe.S}'te tepe yapar, sonra duser: ` +
  `sinir ${son.S}'da ${son.cikarma.toFixed(2)} kalem/gun ve ${son.gecisKaybi.toFixed(1)} adam-gun gecise gider`);
console.log(`sinirin altinda kaybedilen: sinir 1'de kapasitenin ` +
  `%${((100 * T[0].bosKapasite) / (4 * T[0].gun)).toFixed(1)}'i, ` +
  `sinir ${tepe.S}'te %${((100 * tepe.bosKapasite) / (4 * tepe.gun)).toFixed(1)}'i bos gecer`);
 is siniri  toplam gun  teslim suresi  cevrim suresi  kuyrukta  bekleme payi  is cikarma
         1         285          118.5            4.8     113.8          %0.0        0.21
         2         143           51.0            4.8      46.3          %0.0        0.42
         3          98           28.4            4.8      23.7          %0.0        0.61
         4          72           17.3            4.8      12.5          %0.0        0.83
         5          81           21.9            6.6      15.3         %27.8        0.74
         6          83           23.8            8.1      15.7         %41.2        0.72
         8          89           27.6           11.3      16.3         %57.9        0.67
        10          94           31.4           14.6      16.8         %67.5        0.64
        12         102           36.7           18.9      17.9         %74.8        0.59
        16         123           51.0           29.9      21.1         %84.1        0.49

kapasitenin nereye gittigi (adam-gun):
 is siniri  toplam kapasite  temel is  bos gecen  gecise giden  bos oran
         1             1140       285      855.0           0.0     %75.0
         2              572       285      287.0           0.0     %50.2
         3              392       285      107.0           0.0     %27.3
         4              288       285        3.0           0.0      %1.0
         5              324       285        5.0          11.4      %1.5
         6              332       285        4.0          23.6      %1.2
         8              356       285        7.0          49.2      %2.0
        10              376       285        4.0          75.7      %1.1
        12              408       285        4.0         109.1      %1.0
        16              492       285        5.0         195.9      %1.0

en kisa cevrim suresi sinir 1, en kisa teslim suresi sinir 4, en yuksek is cikarma sinir 4 (0.83 kalem/gun)
is cikarma sinir 4'te tepe yapar, sonra duser: sinir 16'da 0.49 kalem/gun ve 195.9 adam-gun gecise gider
sinirin altinda kaybedilen: sinir 1'de kapasitenin %75.0'i, sinir 4'te %1.0'i bos gecer

Hangi Ölçüt Hangi Kararı Verdirir

Tablonun en öğretici satırı birincisidir. İş sınırı bir olduğunda çevrim süresi 4,8 günle en kısadır ve bekleme payı tam olarak sıfırdır — açılan tek kalem hiç beklemeden, kesintisiz çalışılır. Aynı satırda teslim süresi 118,5 gündür ve kapasitenin %75’i boş geçer. Çevrim süresine bakarak yönetilen bir akış, mümkün olan en kötü sistemi kusursuz gösterir.

Sınır dörde çıktığında dört kişi dört kaleme dağılır, boş kapasite %75’ten %1’e iner, iş çıkarma 0,21’den 0,83 kalem/güne çıkar ve teslim süresi 118,5 günden 17,3 güne düşer. Bu noktaya kadar çevrim süresi hiç bozulmamıştır (4,8 gün), çünkü her kaleme hâlâ tam bir kişi düşmektedir.

Sınır beşten sonra ikinci mekanizma devreye girer. Kişi başına birden çok kalem düştüğü anda çevrim süresi 4,8’den 6,6 güne çıkar ve bekleme payı sıfırdan %27,8’e fırlar. On altıda çevrim süresi 29,9 gün, bekleme payı %84,1’dir: bir kalemin ömrünün altıda beşi, üstünde çalışılmadan geçer. İş çıkarma dörtte tepe yapar ve on altıda 0,49’a düşer; 195,9 adam-gün geçişe gider. Sınırı yükseltmek daha çok kalemi aynı anda açar, ama hiçbirini daha erken bitirmez.

Üç ölçüt üç ayrı karara bakar. Çevrim süresi işin kendi içindeki akışı ölçer ve sürecin neresinde bekleme biriktiğini gösterir; tek başına okunduğunda kuyruktaki her şeyi gizler. Teslim süresi talep verilen sözün ölçüsüdür ve kapasite kararını verdirir. İş çıkarma yeni iş kabul edilip edilemeyeceğini söyler ve doyduğu nokta sınırın üst ucunu belirler. Bu koşumda üçü sırasıyla bir, dört ve dört sınırını işaret eder; yalnız biri okunursa üçünden ikisi görülmez.

Özet

  • Teslim süresi, çevrim süresi ve iş çıkarma aynı koşumda tanımlandı; teslim süresi kuyrukta bekleme ile çevrim süresinin toplamı, çevrim süresi ise çalışma ile bekleme toplamıdır.
  • Sınır 1’de çevrim süresi en kısadır (4,8 gün) ve bekleme payı sıfırdır, ama teslim süresi 118,5 gündür ve kapasitenin %75’i boş geçer — çevrim süresi tek başına yanıltır.
  • Sınır 4’te boş kapasite %1’e iner, iş çıkarma 0,83 kalem/günle tepe yapar ve teslim süresi 17,3 güne düşer; bu noktaya kadar çevrim süresi hiç bozulmaz.
  • Sınır 4’ün üstünde bekleme payı sıfırdan %84,1’e çıkar, çevrim süresi 29,9 güne uzar, iş çıkarma 0,49’a düşer ve 195,9 adam-gün geçişe gider.
  • Üç ölçüt bu koşumda sırasıyla 1, 4 ve 4 sınırını işaret eder; üçü birlikte okunmadan sınır seçilemez.

Sonraki Adım

Bu dersin bütün ölçümleri tek bir ekip üzerinde yapıldı: dört kişi, tek bir biriktirme listesi ve tek bir iş sınırı. Bu varsayım kaldırıldığında yeni bir maliyet kalemi doğar. Bir iş kalemi birden çok ekibin dokunduğu bir değişiklik gerektirdiğinde, ekipler arasında bir eşgüdüm turu geçmesi gerekir ve bu tur ne çalışmadır ne de kuyrukta beklemedir. Sonraki ders çok ekipli eşgüdümün bedelini sayar: ekip sayısı arttıkça bağımlı iş kalemi başına kaç eşgüdüm turu düşüyor, ortak planlama turu kaça mal oluyor, eşgüdüm katmanının kendi gecikmesi ne kadar ve bu bedel ekip sayısına göre doğrusal mı yoksa karesel mi büyüyor. Aynı koşumda ikinci bir soru sorulur — hangi bağımlılık türü kaldırıldığında kaç tur kazanılı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