1. メイン プログラム
メイン プログラムは主に、クリティカル パスと 7 フレーム図を計算するためのメソッドを含む Project クラスを実装します。具体的な実装方法は次のとおりです:
1. アクティビティ ID、名前、期間、即時タスク リストなどの属性を含む Activity クラスが定義されます。
2. Project クラスが定義されており、アクティビティ リスト、プロジェクト期間、ログなどの属性と、クリティカル パスの計算、7 フレーム ダイアグラムの計算、合計フロート時間の計算、およびフリーフロート時間を計算します。
3. JSON ファイルからアクティビティ情報を読み取り、Project オブジェクトを作成し、アクティビティを追加します。
4. Project オブジェクトの Calculate メソッドを呼び出して、各アクティビティの最早開始時刻、最遅開始時刻、その他のデータを計算します。
5. Project オブジェクトの Calculate_critical_path メソッドを呼び出して、クリティカル パスを計算します。
6. Project オブジェクトの Calculate_project_duration メソッドを呼び出して、プロジェクトの合計期間を計算します。
7. Jinja2 テンプレート エンジンを使用してプロジェクトのアクティビティ リストを生成し、キー パス
import json from datetime import datetime from typing import List import graphviz from jinja2 import Template from activity import Activity class Project: def __init__(self): self.activities: List[Activity] = [] self.duration = 0 self.logger = [] def log(self, log: str) -> None: self.logger.append(log) def add_activity(self, activity: Activity) -> None: """ 添加一个活动到项目中 :param activity: 待添加的活动 """ # 将活动添加到项目中 self.activities.append(activity) def calculate(self) -> None: """ 计算整个项目的关键信息 :return: None """ self.calculate_successor() self._calculate_forward_pass() # 计算正推法 self._calculate_backward_pass() # 计算倒推法 self._calculate_total_floats() # 计算总浮动时间 self._calculate_free_floats() # 计算自由浮动时间 def calculate_successor(self) -> None: self.log("开始计算紧后活动") for act in self.activities: for pred in act.predecessors: for act_inner in self.activities: if act_inner.id == pred: act_inner.successors.append(act.id) def _calculate_forward_pass(self) -> None: self.log("## 开始正推法计算") # 进入 while 循环,只有当所有活动的最早开始时间和最早完成时间都已经计算出来时,才会退出循环 while not self._is_forward_pass_calculated(): # 遍历每个活动 for activity in self.activities: # 如果活动的最早开始时间已经被计算过,则跳过 if activity.est is not None: continue # 如果活动没有前置活动, 则从1开始计算最早开始时间和最早结束时间 if not activity.predecessors: activity.est = 1 activity.eft = activity.est + activity.duration - 1 self.log( f"活动 {activity.name} 没有紧前活动,设定最早开始时间为1, 并根据工期计算最早结束时间为{activity.eft}") else: # 计算当前活动的所有前置活动的最早完成时间 predecessors_eft = [act.eft for act in self.activities if act.id in activity.predecessors and act.eft is not None] # 如果当前活动的所有前置活动的最早完成时间都已经计算出来,则计算当前活动的最早开始时间和最早完成时间 if len(predecessors_eft) == len(activity.predecessors): activity.est = max(predecessors_eft) + 1 activity.eft = activity.est + activity.duration - 1 self.log( f"活动 {activity.name} 紧前活动已完成正推法计算, 开始日期按最早开始时间里面最大的," + f"设定为{activity.est}并根据工期计算最早结束时间为{activity.eft}") # 更新项目总持续时间为最大最早完成时间 self.duration = max([act.eft for act in self.activities]) def _calculate_backward_pass(self) -> None: """ 计算倒推法 :return: None """ self.log("## 开始倒推法计算") # 输出提示信息 # 进入 while 循环,只有当所有活动的最晚开始时间和最晚完成时间都已经计算出来时,才会退出循环 while not self._is_backward_pass_calculated(): # 遍历每个活动 for act in reversed(self.activities): # 如果活动的最晚开始时间已经被计算过,则跳过 if act.lft is not None: continue # 如果活动没有后继活动, 则从总持续时间开始计算最晚开始时间和最晚结束时间 if not act.successors: act.lft = self.duration act.lst = act.lft - act.duration + 1 self.log(f"活动 {act.name} 没有紧后活动,按照正推工期设定最晚结束时间为{act.lft}," + f"并根据工期计算最晚开始时间为{act.lst}") else: # 计算当前活动的所有后继活动的最晚开始时间 successors_lst = self._calculate_lst(act) # 如果当前活动的所有后继活动的最晚开始时间都已经计算出来,则计算当前活动的最晚开始时间和最晚完成时间 if len(successors_lst) == len(act.successors): act.lft = min(successors_lst) - 1 act.lst = act.lft - act.duration + 1 self.log(f"活动 {act.name} 紧后活动计算完成,按照倒推工期设定最晚结束时间为{act.lft}," + f"并根据工期计算最晚开始时间为{act.lst}") # 更新项目总持续时间为最大最晚完成时间 self.duration = max([act.lft for act in self.activities]) def _calculate_lst(self, activity: Activity) -> List[int]: """计算某一活动的所有最晚开始时间 :param activity: 活动对象 :return: 最晚开始时间列表 """ rst = [] # 初始化结果列表 for act in activity.successors: # 遍历该活动的后继活动 for act2 in self.activities: # 遍历所有活动 if act2.id == act and act2.lst is not None: # 如果找到了该后继活动且其最晚开始时间不为空 rst.append(act2.lst) # 将最晚开始时间加入结果列表 return rst # 返回结果列表 def _is_forward_pass_calculated(self) -> bool: """ 判断整个项目正推法计算已经完成 :return: 若已计算正向传递则返回True,否则返回False """ for act in self.activities: # 遍历所有活动 if act.est is None or act.eft is None: # 如果该活动的最早开始时间或最早完成时间为空 return False # 则返回False,表示还未计算正向传递 return True # 如果所有活动的最早开始时间和最早完成时间都已计算,则返回True,表示已计算正向传递 def _is_backward_pass_calculated(self) -> bool: """ 判断整个项目倒推法计算已经完成 :return: 若已计算倒推法则返回True,否则返回False """ for act in self.activities: # 遍历所有活动 if act.lst is None or act.lft is None: # 如果该活动的最晚开始时间或最晚完成时间为空 return False # 则返回False,表示还未计算倒推法 return True # 如果所有活动的最晚开始时间和最晚完成时间都已计算,则返回True,表示已计算倒推法 def _calculate_total_floats(self) -> None: """ 计算所有活动的总浮动时间 :return: None """ self.log(f"## 开始计算项目所有活动的总浮动时间") for act in self.activities: # 遍历所有活动 if act.est is not None and act.lst is not None: # 如果该活动的最早开始时间和最晚开始时间都已计算 act.tf = act.lst - act.est # 则计算该活动的总浮动时间 self.log(f"计算{act.name}的总浮动时间" + f"最晚开始时间{act.lst} - 最早开始时间{act.est} = {act.tf}", ) else: # 如果该活动的最早开始时间或最晚开始时间为空 act.tf = None # 则将该活动的总浮动时间设为None def _calculate_free_floats(self) -> None: """ 计算所有活动的自由浮动时间 :return: None """ self.log(f"## 开始计算项目所有活动的自由浮动时间") # 输出提示信息 for act in self.activities: # 遍历所有活动 if act.tf == 0: # 如果该活动的总浮动时间为0 self.log(f"计算{act.name}的自由浮动时间" + f"因为{act.name}的总浮动时间为0,自由浮动时间为0") # 输出提示信息 act.ff = 0 # 则将该活动的自由浮动时间设为0 elif act.tf > 0: # 如果该活动的总浮动时间大于0 self.log(f"计算{act.name}的自由浮动时间") # 输出提示信息 self.log(f"- {act.name}的总浮动时间{act.tf} > 0,") # 输出提示信息 tmp = [] # 初始化临时列表 for act2 in self.activities: # 遍历所有活动 if act2.id in act.successors: # 如果该活动是该活动的紧后活动 self.log(f"- {act.name}的紧后活动{act2.name}的自由浮动动时间为{act2.tf}") # 输出提示信息 tmp.append(act2.tf) # 将该紧后活动的自由浮动时间加入临时列表 if len(tmp) != 0: # 如果临时列表不为空 act.ff = act.tf - max(tmp) # 则计算该活动的自由浮动时间 if act.ff < 0: act.ff = 0 self.log(f"- 用活动自己的总浮动{act.tf}减去多个紧后活动总浮动的最大值{max(tmp)} = {act.ff}") else: # 如果临时列表为空 act.ff = act.tf # 则将该活动的自由浮动时间设为总浮动时间 def calculate_critical_path(self) -> List[Activity]: """ 计算整个项目的关键路径 :return: 整个项目的关键路径 """ ctc_path = [] # 初始化关键路径列表 for act in self.activities: # 遍历所有活动 if act.tf == 0: # 如果该活动的总浮动时间为0 ctc_path.append(act) # 则将该活动加入关键路径列表 return ctc_path # 返回关键路径列表 def calculate_project_duration(self) -> int: """ 计算整个项目的持续时间 :return: 整个项目的持续时间 """ return max(activity.eft for activity in self.activities) # 返回所有活动的最早完成时间中的最大值,即整个项目的持续时间 # 从JSON文件中读取活动信息 with open('activities.json', 'r', encoding='utf-8') as f: activities_data = json.load(f) # 创建Project对象并添加活动 project = Project() for activity_data in activities_data: activity = Activity( activity_data['id'], activity_data['name'], activity_data['duration'], activity_data['predecessors'] ) project.add_activity(activity) # 计算每个活动的最早开始时间、最晚开始时间等数据 project.calculate() # 计算关键路径和项目总工期 critical_path = project.calculate_critical_path() project_duration = project.calculate_project_duration() # 生成项目的活动清单 with open('template.html', 'r', encoding='utf-8') as f: template = Template(f.read()) html = template.render( activities=project.activities, critical_path=critical_path, project_duration=project_duration, log=project.logger ) # 生成项目进度网络图 aon_graph = graphviz.Digraph(format='png', graph_attr={'rankdir': 'LR'}) for activity in project.activities: aon_graph.node(str(activity.id), activity.name) for predecessor in activity.predecessors: aon_graph.edge(str(predecessor), str(activity.id)) timestamp = datetime.now().strftime('%Y%m%d%H%M%S') aon_filename = f"aon_{timestamp}" aon_graph.render(aon_filename) # 将项目进度网络图插入到HTML文件中 aon_image = f'<img src="/static/imghwm/default1.png" data-src="{aon_filename}.png" class="lazy" alt="Precedence Diagramming Method: AON">' html = html.replace('<p>Precedence Diagramming Method: AON: <br/>[image]</p>', '<p>紧前关系绘图法: AON: <br/>' + aon_image + '</p>') filename = datetime.now().strftime('%Y%m%d%H%M%S') + '.html' with open(filename, 'w', encoding='utf-8') as f: f.write(html)
2. アクティビティ クラス
プログラム名: activity. py
class Activity: """ 活动类,用于表示项目中的一个活动。 Attributes: id (int): 活动的唯一标识符。 name (str): 活动的名称。 duration (int): 活动的持续时间。 predecessors (List[int]): 活动的前置活动列表,存储前置活动的id。 est (int): 活动的最早开始时间。 lst (int): 活动的最晚开始时间。 eft (int): 活动的最早完成时间。 lft (int): 活动的最晚完成时间。 tf (int): 活动的总浮动时间。 ff (int): 活动的自由浮动时间。 successors (List[int]): 活动的后继活动列表,存储后继活动的Activity对象。 """ def __init__(self, id: int, name: str, duration: int, predecessors: List[int]): """ 初始化活动对象。 Args: id (int): 活动的唯一标识符。 name (str): 活动的名称。 duration (int): 活动的持续时间。 predecessors (List[int]): 活动的前置活动列表,存储前置活动的id。 """ self.id = id self.name = name self.duration = duration self.predecessors = predecessors self.est = None self.lst = None self.eft = None self.lft = None self.tf = None self.ff = None self.successors = [] def __str__(self): return f"id: {self.id}, name: {self.name}, est: {self.est}, lst: {self.lst}, eft: {self.eft}, lft: {self.lft}," + f"successors: {self.successors}"
3. タスク リスト JSON ファイル
ファイル名: activities.json
[ { "id": 1, "name": "A", "duration": 2, "predecessors": [] }, { "id": 9, "name": "A2", "duration": 3, "predecessors": [] }, { "id": 10, "name": "A3", "duration": 2, "predecessors": [] }, { "id": 2, "name": "B", "duration": 3, "predecessors": [ 1, 9 ] }, { "id": 3, "name": "C", "duration": 4, "predecessors": [ 1 ] }, { "id": 4, "name": "D", "duration": 2, "predecessors": [ 2,10 ] }, { "id": 5, "name": "E", "duration": 3, "predecessors": [ 2 ] }, { "id": 6, "name": "F", "duration": 2, "predecessors": [ 3 ] }, { "id": 7, "name": "G", "duration": 3, "predecessors": [ 4, 5 ] }, { "id": 8, "name": "H", "duration": 2, "predecessors": [ 6, 7 ] }, { "id": 11, "name": "H2", "duration": 4, "predecessors": [ 6, 7 ] } ]
4. 出力テンプレート ファイル
リーリー以上がPython でクリティカル パスと 7 グリッド グラフの計算を実装する方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

Pythonは、自動化、スクリプト、およびタスク管理に優れています。 1)自動化:OSやShutilなどの標準ライブラリを介してファイルバックアップが実現されます。 2)スクリプトの書き込み:Psutilライブラリを使用してシステムリソースを監視します。 3)タスク管理:スケジュールライブラリを使用してタスクをスケジュールします。 Pythonの使いやすさと豊富なライブラリサポートにより、これらの分野で優先ツールになります。

限られた時間でPythonの学習効率を最大化するには、PythonのDateTime、時間、およびスケジュールモジュールを使用できます。 1. DateTimeモジュールは、学習時間を記録および計画するために使用されます。 2。時間モジュールは、勉強と休息の時間を設定するのに役立ちます。 3.スケジュールモジュールは、毎週の学習タスクを自動的に配置します。

PythonはゲームとGUI開発に優れています。 1)ゲーム開発は、2Dゲームの作成に適した図面、オーディオ、その他の機能を提供し、Pygameを使用します。 2)GUI開発は、TKINTERまたはPYQTを選択できます。 TKINTERはシンプルで使いやすく、PYQTは豊富な機能を備えており、専門能力開発に適しています。

Pythonは、データサイエンス、Web開発、自動化タスクに適していますが、Cはシステムプログラミング、ゲーム開発、組み込みシステムに適しています。 Pythonは、そのシンプルさと強力なエコシステムで知られていますが、Cは高性能および基礎となる制御機能で知られています。

2時間以内にPythonの基本的なプログラミングの概念とスキルを学ぶことができます。 1.変数とデータ型、2。マスターコントロールフロー(条件付きステートメントとループ)、3。機能の定義と使用を理解する4。

Pythonは、Web開発、データサイエンス、機械学習、自動化、スクリプトの分野で広く使用されています。 1)Web開発では、DjangoおよびFlask Frameworksが開発プロセスを簡素化します。 2)データサイエンスと機械学習の分野では、Numpy、Pandas、Scikit-Learn、Tensorflowライブラリが強力なサポートを提供します。 3)自動化とスクリプトの観点から、Pythonは自動テストやシステム管理などのタスクに適しています。

2時間以内にPythonの基本を学ぶことができます。 1。変数とデータ型を学習します。2。ステートメントやループの場合などのマスター制御構造、3。関数の定義と使用を理解します。これらは、簡単なPythonプログラムの作成を開始するのに役立ちます。

10時間以内にコンピューター初心者プログラミングの基本を教える方法は?コンピューター初心者にプログラミングの知識を教えるのに10時間しかない場合、何を教えることを選びますか...


ホットAIツール

Undresser.AI Undress
リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover
写真から衣服を削除するオンライン AI ツール。

Undress AI Tool
脱衣画像を無料で

Clothoff.io
AI衣類リムーバー

AI Hentai Generator
AIヘンタイを無料で生成します。

人気の記事

ホットツール

AtomエディタMac版ダウンロード
最も人気のあるオープンソースエディター

ゼンドスタジオ 13.0.1
強力な PHP 統合開発環境

SublimeText3 中国語版
中国語版、とても使いやすい

PhpStorm Mac バージョン
最新(2018.2.1)のプロフェッショナル向けPHP統合開発ツール

SublimeText3 英語版
推奨: Win バージョン、コードプロンプトをサポート!
