CPLANS
======

cplans ist ein einfaches Planungsprogramm.
Dies ist eine sehr kurze Beschreibung von cplans version 0.2.

Die Aufgabe von cplans ist es, aus Angaben über zu bearbeitende
Aufgaben (tasks) und dafür zur Verfügung stehenden Bearbeitern
(Resources) einen Ablaufplan zu erstellen, das heisst jede Task
mit Anfangs- und Enddatum zu versehen.

cplans ist ein Kommandozeilenprogramm für Windows (Portierung
auf andere System sollte einfach sein), das aus den Daten einer
Eingabedatei eine Ausgabedatei erzeugt.

Aufruf:

cplans INPUT > OUTPUT.

INPUT steht für die Eingabedatei, OUTPUT für die Ausgabedatei
(das ">" is nötig, da die Ausgabe nach Stdout geschrieben wird,
d.h. "cplans INPUT" schreibt die Ausgabe auf die Konsole).

Die Eingabedatei ist eine normale Textdatei (ASCII), die
die zur Planung nötigen Angaben enthält, siehe unten.
Die Ausgabedatei hat genau die gleiche Syntax wie die Eingabedatei,
das heisst kann wiederum als Eingabe für cplans dienen.

Dies hat folgenden Sinn: Planung ist ein komplizierter Prozess
und kann oftmals nicht in einem Schritt erfolgen. Die cplans-
Ausgabedatei enthält alle Angaben aus der Eingabe, aber zusätzlich
schon Berechnungen von cplans, die helfen können, eine verfeinerte
Eingabedatei zu erstellen.


Eingabe- und Augabesyntax
-------------------------
Datumsangaben:
   Alle Daten werden in folgender Form angegeben:
   JJJJ-MM-TT
   Dabei muss gelten: 2000 <= JJJJ <= 2099.

Aufbau der Datei:
   Die Datei ist zeilenorientiert, d.h. jede Anweisung besteht aus
   genau einer Zeile. Leerzeichen dienen als Trennzeichen, das
   heisst zum Beispiel auch, dass innerhalb von Namen keine
   Leerzeichen stehen dürfen.

Kommentare:
  Es gibt zwei Arten von Kommentaren:
  # Text nach "#" bis zum Zeilenende wird ignoriert.
  note Eine note-Anweisung wird in die Ausgabe übernommen, hat aber
       sonst keinen Einfluss auf die Abarbeitung.

Anweisungen:
Im Folgenden ist DATE ein Datum im obigen Format.
Eckige Klammern geben optionale Teile der Anweisungen an
(d.h. die Klammern sind nicht Bestandteil der Anweisungen).


note text
   Kommentar, siehe oben.

project start DATE [end DATE]
   Genau eine project-Anweisung muss angegeben werden, das Ende-Datum
   kann in der Ausgabe verändert sein. Alle Tasks der Eingabedatei
   werden zusammengefasst als Projekt bezeichnet.

res RESID use USEFACTOR
   Hiermit wird eine Resource, also ein Arbeiter, definiert.
   RESID ist der Name.
   USEFACTOR gibt an, welcher Anteil der Arbeitszeit verplant werden
   darf. 1.0 entspricht 100%, 5 Tage pro Woche.
   Durch entsrechende Werte des use-Faktors können "Hintergrundtasks",
   die parallel ablaufen, modelliert werden.

task TASKID [prio PRIO] [res RESID] [effort EFFORT] [fixed] [start DATE] [end DATE]
   Mit task-Anweisungen werden die zu planenden Aufgaben definiert.
   Jede Task wird immer von genau einer Person (Resource) ausgeführt.

   TASKID ist der Name der Task. Er darf nicht mit einem @-Zeichen beginnen.

   PRIO ist eine nichtnegative Zahl, die angibt, wie "dringend" die Task ist
   (größere Zahl = "dringender")
   Die genaue Bedeutung dieser Priorität wird später erklärt.

   RESID ist die Resource, die diese Task ausführen soll.
   Für Meilensteine (s.u.) muss keine Resource angegeben werden.

   EFFORT ist der Aufwand für diese Task in Tagen, das heißt die
   Zeit, die eine Resource mit dem use-Faktor 1 benötigen würde, um
   sie auszuführen. Für Meilensteine und Urlaub ist der Aufwand 0 und
   braucht nicht angegeben zu werden.

   fixed  bedeutet: Diese Task darf nicht verschoben werden, in diesem
   Fall muss Start- oder Endedatum (oder beide) angegeben werden.

   Die Daten nach  start  bzw.  end  geben Start- und Endedatum an.
   Wenn die task kein fixed-Attribut hat, können diese Angaben in der
   Ausgabe verändert sein.

   Urlaub wird als fixed task mit Start- Endedatum angegeben, aber ohne
   effort.

   Eine Task mit einem Anfangsdatum gleich dem Enddatum einer anderen Task
   kollidiert nicht mit dieser anderen Task. cplans rechnet immer in
   ganzen Tagen, man stelle sich Anfang oder Ende immer am Abend des
   jeweiligen Tages vor. Wenn man also am 1. Juli 2006 frühmorgens
   in den Urlaub fahren will, gebe man "start 2006-06-30" an.

   Meilensteine sind keine echten Tasks, sondern Termine, die von
   anderen Tasks abhängen. Sie werden als Task mit effort 0 und
   start = end angegeben (eine der beiden Angaben start/end reicht).

dep TASK1 TASK2
   Diese Anweisung gibt die Abhängigkeit zwischen zwei Tasks an:
   TASK1 muss enden, erst dann kann TASK2 starten.

   TASK1 ist mindesten so "dringend", wie TASK2, deshalb wird die Priorität
   von TASK1 auf den Wert von TASK2 gesetzt, falls sie voher niedriger war.


Was macht cplans ?
------------------
Zunächst wird für alle Tasks die Dauer berechnet. Diese ergibt sich zu
Dauer = 7/5 * effort / usefactor.
Mit Hilfe des Faktors 7/5 werden Wochenenden (gemittelt) berücksichtigt:
Eine task, die vom der Arbeit her 10 Tage dauern würde, dauert in Wirklichkeit
14, da zwei Wochenenden enthalten sind.

Wenn bei fixed Tasks Start- und Endedatum gegeben sind, dann wird
deren Differenz als Dauer genommen; die Resource ist dann eventuell
über- oder unterlastet.

Danach erfolgt die Planung in 2 Pässen:

Im Pass 1 werden die Tasks entsprechend ihrer Abhängigkeiten so geplant,
dass sich die minimale Gesamtdauer ergibt. Die Resourcezuordnungen
werden dabei außer acht gelassen. Es ergibt sich also die kürzestmögliche
Projektlaufzeit, wenn hinreichend viele Resourcen zur Verfügung ständen.

Es wird CPM = Critical Path Method verwendet, siehe zum Beispiel
 Biess, Graphentheorie, Mathematik fuer Ingenieure,
 Naturwissenschaftler, Ökonomen und Landwirte, Band 21/2.

Im Ergebnis treten möglicherwese Task-Kollisionen auf: Eine
Resource soll zwei oder mehr Tasks zur selben Zeit bearbeiten.
Wenn nicht, sind wir hier fertig.

Wenn doch, wird im Pass 2 versucht, diese Task-Kollisionen aufzulösen.
Dazu werden für jede Kollision die beteiligten Tasks nach ihrer
Priorität sortiert, hohe Werte zuerst (fixed Tasks erhalten einen
sehr hohen Wert).

Dann werden zusätzliche, künstliche Abhängigkeiten zwischen diesen Tasks
eingeführt, die bewirken, dass sie nacheinander ausgeführt werden.
Task hoher Priorität werden also - im Konfliktfall - vor den Tasks
niedrigerer Priorität ausgeführt.

Mit diesen neuen Abhängigkeiten wird erneut geplant. Wenn im Ergebnis
dieser Planung wieder eine Kollision entsteht, wird noch eine
Abhängigkeit hinzugefügt.

Falls mehrere Tasks dieselbe Priorität haben, dann werden alle
Permutationen dieser Tasks gebildet und für jede dieser Reihenfolgen
geplant. In diesem Fall wird von allen erfolgreichen Planungsversuchen
der ausgewählt, der die kürzeste Gesamtzeit ergibt.

Es gibt Fälle, in denen dieser Algorithmus keinen kollisionsfreien
Plan findet, dann wird eine Warnung ausgegeben.

In diesem Fall kann man versuchen, Task-Prioritäten zu ändern oder
fixed-Tasks verschieblich zu machen - oder die Resourcezuordnungen
zu ändern. Die unten angegbenen Aufrufoptionen können dabei helfen.


Aufrufoptionen
--------------
Beim Aufruf von cplans können vor der Eingabedatei noch ein oder mehrere
Optionen angegeben werden:
-f    - alle "fixed" Attribute werden ignoriert.
-p    - all Taskprioritäten werden ignoriert.
-r    - kein Resource-Scheduling, d.h. nach Pass 1 wird abgebrochen,
        Task-Kollisionen werden ignoriert.
-1    - nimm die erste Permutation, die funktioniert
-i..  - Menge der Zusatz-Informationen, die (als Kommentar) ausgegeben
        werden:
        -i0   - keine Zusatzinformationen (Default)
        -i1   - einige Zusatzinformationen
        -i2   - viele Zusatzinformationen


Ausgaben von cplans
-------------------
cplans gibt den ermittelten Plan in der genannten Syntax aus. Außerdem
werden (als #-Kommentar) unter Umständen weitere Meldungen ausgegeben:

# FATAL :    - Abbruch, der Programmlauf kann nicht fortgesetzt werden.
# ERROR :    - Fehler in der Eingabedatei, muss korrigiert werden.
# WARNING :  - Etwas Seltsames ist passiert, möglicherweise Hinweis
               auf einen Fehler in der Eingabedatei.
# hint :     - Ein wichtiger Hinweis des Programmes an den Benutzer.
# info :     - Eine mehr oder weniger wichtige Information.

Alle diese Meldungen erscheinen in der Ausgabedatei, die ersten
drei werden außerdem auch dann auf die Konsole ausgegeben, wenn
Stdout umgeleitet ist, mit anderen Worten, man sieht sie in jedem Fall
auf dem Bildschirm.

Eine der Informationen, die cplans ausgibt, ist der Resourcekalender.
Für jede Resource wird pro Projekt-Tag ein Zeichen ausgegeben:
.               : Resource ist frei.
@               : Task-Kollision.
anderes Zeichen : Task dieser Resource an diesem Tag. Es wird das
                  erste Zeichen der TaskID ausgegeben.

Exitcodes
---------
cplans gibt als Exitcode zurück:
0 - OK
1 - falsche Aufrufsyntax
2 - fataler Fehler (# FATAL - Meldung)
3 - Fehler in der Eingabedatei (# ERROR - Meldungen)


Beispiele
---------
cplans kommt mit einigen einfachen Beispielen (im sample-Unterverzeichnis).
Man probiere diese mit -i1 oder -i2, um einen Eindruck von der Arbeitsweise
von cplans zu bekommen.


Was fehlt ?
-----------
- graphische Ausgabe
- Wochen- und Feiertage werden nicht berücksichtigt (außer durch den
  Faktor 7/5).

Frank Reglin, 2005-2009

