# Table of Contents
# -----------------
# 1) Imported modules
# 2) Task
# 3) Project
# 4) Writer
# 5) Reader
# 6) Calculator
# 7) Main
# 1) Imported modules
# -------------------
import string
import sys
import re
INFINITY = 100000
# 2) Task
# -------
class Task:
def __init__(self, code):
self.code = code
self.description = ""
self.predecessors = []
self.successors = []
self.duration = 0
self.earlyStart = None
self.earlyFinish = None
self.lateStart = None
self.lateFinish = None
self.slack = None
self.flag = None
# 3) Project
# -----------
class Project:
def __init__(self):
self.tasks = dict()
self.fakeSource = self.NewTask("source")
self.fakeTarget = self.NewTask("target")
def GetTask(self, code):
return self.tasks.get(code,None)
def NewTask(self, code):
task = Task(code)
self.tasks[code] = task
return task
def DeleteTask(self, task):
predecessors = task.predecessors[:]
for predecessor in predecessors:
self.RemovePrecedence(predecessor, task)
successors = task.successors[:]
for successor in successors:
self.RemovePrecedence(task, successor)
del self.tasks[task.code]
def AddPrecedence(self, source, target):
source.successors.append(target)
target.predecessors.append(source)
def RemovePrecedence(self, source, target):
source.successors.remove(target)
target.predecessors.remove(source)
def AddFakeSourceDependencies(self):
for task in self.tasks.values():
if task!=self.fakeSource and len(task.predecessors)==0:
self.AddPrecedence(self.fakeSource, task)
def AddFakeTargetDependencies(self):
for task in self.tasks.values():
if task!=self.fakeTarget and len(task.successors)==0:
self.AddPrecedence(task, self.fakeTarget)
def GetLastDate(self):
lastDate = 0
for task in self.tasks.values():
if task.lateFinish!=None and task.lateFinish>lastDate:
lastDate = task.lateFinish
return lastDate
# 4) Writer
# ----------
class Writer:
def ExportProject(self, project, fileName):
try:
output = open(fileName, "w")
except:
sys.stderr.write('Unable to open file "%s"\n' % fileName)
sys.stderr.flush()
return
self.WriteProject(project, output)
output.close()
def WriteProject(self, project, output):
output.write("code;description;predecessors;duration;early start;early finish;late start;late finish;slack\n")
for task in project.tasks.values():
self.WriteTask(task, output)
output.flush()
def WriteTask(self, task, output):
output.write("%s" % task.code)
output.write(";")
output.write("%s" % task.description)
output.write(";")
self.WritePredecessors(task, output)
output.write(";")
output.write("%s" % task.duration)
output.write(";")
if task.earlyStart!=None:
output.write("%s" % task.earlyStart)
output.write(";")
if task.earlyFinish!=None:
output.write("%s" % task.earlyFinish)
output.write(";")
if task.lateStart!=None:
output.write("%s" % task.lateStart)
output.write(";")
if task.lateFinish!=None:
output.write("%s" % task.lateFinish)
output.write(";")
if task.slack!=None:
output.write("%s" % task.slack)
output.write("\n")
def WritePredecessors(self, task, output):
first = True
for predecessor in task.predecessors:
if first:
first = False
else:
output.write(", ")
output.write("%s" % predecessor.code)
# 5) Reader
# ---------
class Reader:
def ImportProject(self, fileName):
try:
input = open(fileName, "r")
except:
sys.stderr.write('Unable to open file "%s"\n' % fileName)
sys.stderr.flush()
return
project = self.ReadProject(input)
input.close()
return project
def ReadProject(self, input):
project = Project()
line = input.next()
for line in input:
line = line.rstrip('\r\n')
cells = line.split(';')
task = project.GetTask(cells[0])
if task==None:
task = project.NewTask(cells[0])
if len(cells)>1 and cells[1]!="":
task.description = cells[1]
if len(cells)>2 and cells[2]!="":
self.ReadPredecessors(project, task, cells[2])
if len(cells)>3 and cells[3]!="":
task.duration = int(cells[3])
if len(cells)>4 and cells[4]!="":
task.earlyStart = int(cells[4])
if len(cells)>5 and cells[5]!="":
task.earlyFinish = int(cells[5])
if len(cells)>6 and cells[6]!="":
task.lateStart = int(cells[6])
if len(cells)>7 and cells[7]!="":
task.lateFinish = int(cells[7])
if len(cells)>8 and cells[8]!="":
task.slack = int(cells[8])
project.AddFakeSourceDependencies()
project.AddFakeTargetDependencies()
self.DetectLoops(project)
return project
def ReadPredecessors(self, project, task, text):
codes = re.split("[\t ]*,[\t ]*", text)
for code in codes:
predecessor = project.GetTask(code)
if predecessor==None:
predecessor = project.NewTask(code)
# self.RaiseError("In predecessors of task %s: task %s undefined\n" % (task.code, code))
project.AddPrecedence(predecessor, task)
def DetectLoops(self, project):
# To be removed for the PC
for task in project.tasks.values():
task.flag = "to-visit"
self._DetectLoops(project.fakeSource, [])
for task in project.tasks.values():
task.flag = None
# ------------------------
# pass
# To be removed for the PC
def _DetectLoops(self, task, stack):
if task.flag=="to-visit":
task.flag = "on-stack"
stack.append(task)
for successor in task.successors:
self._DetectLoops(successor, stack)
stack.pop()
task.flag = "visited"
elif task.flag=="on-stack":
started = False
message = "loop detected:"
for t in stack:
if t==task:
started = True
message = message + " " + t.code
elif started:
message = message + " -> " + t.code
message = message + " -> " + task.code + "\n"
self.RaiseError(message)
# ------------------------
def RaiseError(self, message):
sys.stderr.write(message)
sys.stderr.flush()
sys.exit()
# 6) Calculator
# -------------
class Calculator:
def CalculateDates(self, project):
self.CalculateEarlyDates(project)
self.CalculateLateDates(project)
# To be removed for the PC
self.DetectCriticalTasks(project)
# ---------------------------
return
def CalculateEarlyDates(self, project):
# To be removed for the PC
for task in project.tasks.values():
task.earlyStart = 0
task.earlyFinish = task.earlyStart + task.duration
stabilized = False
while not stabilized:
stabilized = True
for task in project.tasks.values():
for predecessor in task.predecessors:
if predecessor.earlyFinish > task.earlyStart:
stabilized = False
task.earlyStart = predecessor.earlyFinish
task.earlyFinish = task.earlyStart + task.duration
# ---------------------------
# pass
def CalculateLateDates(self, project):
# To be removed for the PC
target = project.fakeTarget
target.lateFinish = target.earlyStart
target.lateStart = target.lateFinish
for task in project.tasks.values():
if task!=target:
task.lateFinish = target.lateFinish
task.lateStart = task.lateFinish - task.duration
stabilized = False
while not stabilized:
stabilized = True
for task in project.tasks.values():
for successor in task.successors:
if successor.lateStart < task.lateFinish:
stabilized = False
task.lateFinish = successor.lateStart
task.lateStart = task.lateFinish - task.duration
# ---------------------------
# pass
def DetectCriticalTasks(self, project):
# ---------------------------
for task in project.tasks.values():
task.slack = task.lateStart - task.earlyStart
# ---------------------------
# pass
# 7) Main
# -------
#if len(sys.argv)<2:
# inputFileName = "pert.csv"
#else:
# inputFileName = sys.argv[1]
#if len(sys.argv)<3:
# outputFileName = "pert.csv"
#else:
# outputFileName = sys.argv[2]
inputFileName = 'maison2.csv'
outputFileName = 'test2.csv'
reader = Reader()
project = reader.ImportProject(inputFileName)
calculator = Calculator()
calculator.CalculateDates(project)
writer = Writer()
writer.ExportProject(project, outputFileName)
工序网络图
最新推荐文章于 2024-01-06 16:57:08 发布