Hoffmann Montaj Hattı DengelemeHoffmann Assembly Line Balancing
SALBP-1 için Hoffmann'ın (1963) öncelik matrisi yöntemi: saf Python çekirdek, komut satırı aracı ve beş dilli Streamlit arayüzü. Ders ödevi olarak başladı; inceleme, kodun aslında Hoffmann olmadığını gösterince sıfırdan yazıldı.Hoffmann's (1963) precedence-matrix method for SALBP-1: a pure-Python core, a command-line tool and a five-language Streamlit UI. It started as coursework; when a review showed the code was not actually Hoffmann's method, it was rewritten from scratch.
- TestTests
- 127
- Arayüz diliUI languages
- EN · TR · DE · ES · FR
- DoğrulamaVerification
- brute-force + bitmask-DP
- SürümRelease
- v1.1.0
ProblemProblem
Montaj hattı dengeleme (SALBP-1): verilen çevrim süresi C için işleri öncelik kısıtlarını bozmadan en az sayıda istasyona dağıtmak. Projenin ilk sürümü bir ders ödeviydi: MATLAB'dan Python'a taşınmış, üstüne Tkinter arayüzü konmuştu ve "sonuç" üretiyordu.
Kod incelemesi, uygulanan döngünün Hoffmann yöntemi değil first-fit sezgiseli olduğunu gösterdi ("kodu sıfır olan ilk uygun işi al"). Alt küme sayımı olmadığı için optimumdan sapıyordu: [4, 4, 3, 3, 3, 3], C = 10 örneğinde 3 istasyon buluyordu, Hoffmann 2 bulur. Ayrıca öncelik döngüsünde sonsuz döngüye giriyor, ondalık süreleri reddediyor ve geçersiz girdiyi sessizce yutuyordu.
Assembly line balancing (SALBP-1): for a given cycle time C, assign tasks to the fewest stations without violating precedence. The first version was coursework: a MATLAB script ported to Python with a Tkinter GUI on top, and it did produce "results".
A code review showed the implemented loop was a first-fit heuristic, not Hoffmann's method ("take the first available task whose code is zero"). Without subset enumeration it deviated from the optimum: on [4, 4, 3, 3, 3, 3] with C = 10 it found 3 stations where Hoffmann finds 2. It also looped forever on precedence cycles, rejected fractional durations and silently dropped invalid input.
YaklaşımApproach
- Gerçek Hoffmann. Her istasyon için öncelik kısıtını sağlayan tüm iş alt kümeleri sayılır, boş süreyi en aza indiren seçilir. Eşitlik kuralı seçilebilir:
ORIGINAL,MOST_TASKS,MOST_FOLLOWERS. - Eski davranış korundu. First-fit döngüsü
greedy_first_fitolarak duruyor; arayüzde "eski yöntemle karşılaştır" iki çözümü yan yana gösterir. - Ölçütler. Verimlilik, denge kaybı, teorik alt sınır ⌈Σt/C⌉, düzgünlük indeksi (Moodie & Young).
- Gerçek girdiler. Türkçe Excel CSV'si (
;ayracı, ondalık virgül), Türkçe sütun başlıkları; hatalarBalancingErroraltında ve sorunlu iş kimliklerini söyler. - Üç arayüz, tek çekirdek. Python API, komut satırı (metin/JSON/CSV çıktı) ve Streamlit (tablo editörü, çevrim süresi taraması, CSV/JSON indirme). Çekirdeğin zorunlu bağımlılığı yok.
- Beş dil. Arayüz ve komut satırı EN/TR/DE/ES/FR; i18n bütünlüğü testle kilitli.
- Real Hoffmann. For every station, every task subset that satisfies precedence is enumerated and the one with minimum idle time is chosen. The tie-break rule is selectable:
ORIGINAL,MOST_TASKS,MOST_FOLLOWERS. - The old behaviour is preserved. The first-fit loop lives on as
greedy_first_fit; "compare with legacy method" shows both solutions side by side. - Metrics. Efficiency, balance delay, theoretical lower bound ⌈Σt/C⌉, smoothness index (Moodie & Young).
- Real inputs. Turkish Excel CSV (
;delimiter, decimal comma), Turkish column headers; errors derive fromBalancingErrorand name the offending task ids. - Three interfaces, one core. Python API, CLI (text/JSON/CSV output) and Streamlit (table editor, cycle-time sweep, CSV/JSON download). The core has no mandatory dependency.
- Five languages. UI and CLI in EN/TR/DE/ES/FR; i18n completeness is locked by a test.
Sonuç ve doğrulamaResult and verification
Ders örneği (12 iş, C = 18) komut satırından:
The course example (12 tasks, C = 18) from the command line:
$ python -m hoffmann_lb examples/course_example.csv --cycle 18 Method: hoffmann Cycle time: 18 Station 1: 1, 2 load 18 idle 0 Station 2: 3, 4, 5, 7, 9 load 18 idle 0 Station 3: 6, 8 load 17 idle 1 Station 4: 10, 11, 12 load 17 idle 1 Stations : 4 (equals lower bound) Efficiency (E) : 97.22 % Balance delay (D) : 2.78 % Smoothness (SI) : 1.4142
127 test: birim, uçtan uca CLI, Streamlit AppTest, i18n bütünlüğü ve rastgele DAG'lar üzerinde hypothesis özellik testleri. Ders örneğinin beklenen değerleri bağımsız bir brute-force oracle ve kesin bir bitmask-DP çözücü ile hesaplandı; Hoffmann test edilen her C için tam optimuma ulaşıyor. ORIGINAL kuralıyla 8 işe kadar rastgele graflarda oracle ile birebir aynı istasyon kümelerini veriyor. ruff, mypy --strict, CI (Python 3.11 / 3.12).
Sürümler: v0.1.0 çekirdek → v0.2.0 CSV/JSON + CLI → v1.0.0 Streamlit → v1.1.0 çok dilli arayüz. v1.0.0'a kadar MIT, sonrası Apache-2.0 (NOTICE dosyasında belirtildi).
127 tests: unit, end-to-end CLI, Streamlit AppTest, i18n completeness and hypothesis property tests on random DAGs. Expected values for the course example were computed with an independent brute-force oracle and an exact bitmask-DP solver; Hoffmann reaches the exact optimum for every tested C. With the ORIGINAL rule it yields exactly the same station sets as the oracle on random graphs up to 8 tasks. ruff, mypy --strict, CI on Python 3.11 / 3.12.
Releases: v0.1.0 core → v0.2.0 CSV/JSON + CLI → v1.0.0 Streamlit → v1.1.0 multilingual UI. MIT up to v1.0.0, Apache-2.0 afterwards (recorded in NOTICE).
ÖğrendiklerimWhat I learned
Çalışan kod ile doğru kod arasındaki fark ancak bağımsız bir doğrulayıcıyla görünür. Ödev sürümü de her girdide bir "sonuç" üretiyordu; brute-force oracle olmadan first-fit olduğu hiç anlaşılmayacaktı. Bir yöntemin adını taşıyan kodun o yöntemi gerçekten uyguladığını kanıtlamak, kodu yazmaktan daha değerli.
The difference between working code and correct code only shows up with an independent verifier. The coursework version produced a "result" for every input; without the brute-force oracle nobody would have noticed it was first-fit. Proving that code named after a method actually implements that method is worth more than writing the code.