ネットワークコンピューティング実習

1. URL
2. 担当教員
3. TA (ティーチングアシスタント)
4. ネットワークに関する疑問
5. 講義目的: 到達目標
6. 授業方法
7. 成績評価
8. スケジュール
9. 大崎が担当する科目に共通の連絡事項・アドバイス
10. Debian GNU/Linux のインストール
11. UNIX (UNIX とは、ユーザ権限、パッケージ管理)
12. Debian GNU/Linux セットアップ〜パッケージ管理
13. シェル (ファイル操作、リダイレクト、パイプ)
14. X ウィンドウシステム & ウィンドウマネージャ
15. エディタ (Emacs チュートリアル)
16. シミュレータ導入 (インストール、実行、可視化)
17. Python 言語 (1) (名前、変数、式)
18. Python 言語 (2) (文、スコープ、サブルーチン)
19. Python 言語 (3) (オブジェクト指向プログラミング)
20. 最終レポート課題 (実施報告書)
21. シミュレータ解説 (1) (概要、エージェント)
22. シミュレータ解説 (2) (モビリティ、可視化)
23. ソフトウェア設計・実装
24. オプション課題: 性能評価 (p% 配送遅延)

ソフトウェア設計・実装

実習の流れ

1. 解説 (10 分)
2. 実習 (課題 1、課題 2) (15 分)
3. 解説 (10 分)
4. 実習 (課題 3、課題 4) (45 分)
5. 成果発表 (10 分)
6. リフレクションシート記入 (10 分)

チーム分けの方針・態度目標

2025/09/24 のものと同じ。

https://lsnl.jp/~ohsaki/lecture/netcompx/2025/#10-7

内容目標

- DTN シミュレータを利用したミニプロジェクトの案を出せるようになる。

- DTN シミュレータに関して不明な点を明らかにできるようになる。

- ミニプロジェクトを設定し、文字や図を用いて説明できるようになる。

- 設定したミニプロジェクトを他者に説明し、フィードバックを得られるようになる。

課題

課題 1

ネットワークシミュレータ dtnsim をベースにして、 「やってみたいこと」、 「できると面白そうなこと」、 「できると楽しそうなこと」、 「できると便利そうなこと」をできるだけ多く列挙し、 以下のフォームの「課題1」のシートに記入せよ。 1 人 1 個以上必ず記入すること。

課題 1 および課題 2 記入フォーム
https://kwanseio365-my.sharepoint.com/:x:/g/personal/cta67712_nuc_kwansei_ac_jp/IQCTPIcXmoUYRJpBQpQS9Sv7ASnCdjokyZAFOdUZRYO6SXk?e=Tz4dZq

5W1H を意識して、何を (WHAT)、何のために (WHY)、どのように (HOW) するかを書くこと。

 例:
 WHAT: dtnsim のシミュレーション実行中に、統計情報 (平均メッセージ配送時間、平均重複メッセージ数など) をリアルタイムで表示させる
 WHY: シミュレーション実行中に特性が把握できたほうが便利だから
 HOW: 現時点では不明

 WHAT: Python で書かれている dtnsim を Node.js に移植する
 WHY: Python より Node.js のほうが好きだから
 HOW: AI の力を借りたらできそうな気がする

※ 今の場合、 いつ (WHEN)、 誰が (WHO) は明確 (それぞれ「最終レポート提出期限まで」および「記入者本人」) なので書く必要はない。

課題 2

ネットワークシミュレータ dtnsim について、 「知りたいこと」や「よくわかってないこと」をできるだけ多く列挙し、 上記のフォームの「課題 2」のシートに記入せよ。 一人一個以上必ず記入すること。

例:
dtnsim | cellx のように実行するので、dtnsim 側に print 文を埋め込んでデバッ
グすることができない (埋め込むと cellx 側でエラーになる)。解決法があれば知り
たい。

課題 3

課題 1 および課題 2 をふまえて、 ミニプロジェクトの案を作成せよ。 A4 の紙に、 以下の情報を記入せよ。

- 学生番号 4 桁
- 氏名
- ミニプロジェクトのタイトル
- ミニプロジェクトを説明する絵
- 背景
- 動機
- 目的
- 手法
- 予想される問題

ミニプロジェクトの例 (あくまで「例」です。みなさんの自由は発想を期待しています。)
- DTN 通信プロトコルの性能評価
  - ルーティングアルゴリズムの評価 ★
  - エピデミックブロードキャストアルゴリズムの評価 ★
- DTN 通信プロトコルの設計・実装
  - 既存の (高性能な) ルーティングアルゴリズムの実装 ★★
  - 既存の (高性能な) エピデミックブロードキャストアルゴリズムの実装 ★★
  - 既存のルーティングアルゴリズムの実装 ★★★
  - 既存のエピデミックルーティングアルゴリズムの実装 ★★★
  - 高性能なルーティングアルゴリズムの考案と実装 ★★★★
  - 高性能なエピデミックブロードキャストアルゴリズムの考案と実装 ★★★★
- ネットワークシミュレータ高度化
  - シミュレーション情報のリアルタイム表示機能の追加 ★
  - シミュレーション結果集計機能の追加 ★
  - monitor.Cell への機能追加 (わかりやすく、美しく) ★
  - 3D アニメーション機能の追加 ★★★
  - ネットワークシミュレータ高速化・最適化 ★★★
  - インタラクティブ操作機能の追加 ★★
  - 他のプラットフォーム (例: Windows、OS X、iOS、Andoroid) への移植 ★〜★★★
  - ネットワークシミュレータのバグ発見および修正 ★

課題 4

課題 3 で作成した紙を、 他の受講者 2 人に説明し、 フィードバックを得よ。 フィードバックにもとづいて、 必要であればミニプロジェクトの案を修正せよ。 フィードバックをもらった人は、 紙の右下にサインをもらうこと。

最後に、 ミニプロジェクトの説明を撮影し、 以下のページからアップロードせよ。 設問 1〜設問 4 は空白でよい。

講義「ネットワークコンピューティング実習」 答案提出フォーム
https://lsnl.jp/app/lecture/quiz/show/netcompx

実習中に完了しなかった場合は、 実習後にフィードバックをもらってからアップロードせよ。 その場合は、 受講者以外の人にフィードバックをもらっても構わない。

参考: Gemini にミニプロジェクトの案を提案してもらう例

プロンプト

 工学部情報工学課程の 3 年生です。
 「ネットワークコンピューティング実習」という授業の最終課題で、
 これまでに学んだ Debian GNU/Linux、Python、ネットワークシミュレータ dtnsim を応用したミニプロジェクトに取り組みます。
 ミニプロジェクトの課題は自分で自由に決めることができ、
 実施した内容を最終レポートとして報告します。

 担当教員からは、以下のようなミニプロジェクトの例が示されています。

 ミニプロジェクトの例 (あくまで「例」です。みなさんの自由は発想を期待しています。)
 - DTN 通信プロトコルの性能評価
   - ルーティングアルゴリズムの評価 ★
   - エピデミックブロードキャストアルゴリズムの評価 ★
 - DTN 通信プロトコルの設計・実装
   - 既存の (高性能な) ルーティングアルゴリズムの実装 ★★
   - 既存の (高性能な) エピデミックブロードキャストアルゴリズムの実装 ★★
   - 既存のルーティングアルゴリズムの実装 ★★★
   - 既存のエピデミックルーティングアルゴリズムの実装 ★★★
   - 高性能なルーティングアルゴリズムの考案と実装 ★★★★
   - 高性能なエピデミックブロードキャストアルゴリズムの考案と実装 ★★★★
 - ネットワークシミュレータ高度化
   - シミュレーション情報のリアルタイム表示機能の追加 ★
   - シミュレーション結果集計機能の追加 ★
   - monitor.Cell への機能追加 (わかりやすく、美しく) ★
   - 3D アニメーション機能の追加 ★★★
   - ネットワークシミュレータ高速化・最適化 ★★★
   - インタラクティブ操作機能の追加 ★★
   - 他のプラットフォーム (例: Windows、OS X、iOS、Andoroid) への移植 ★〜★★★
   - ネットワークシミュレータのバグ発見および修正 ★

 ただし、担当教員からは以下のようなアドバイスがありました。
 - 「自分のやりたいこと」、「自分がやってみたいこと」を重視してください
 - 「できて当然のことができた」より「難しいことに挑戦したがここまでしかできなかった」ことのほうがはるかに価値がある
 - 挑戦して、目標が達成できなかったら、「どう挑戦したか」「なぜダメだったか」を最終レポートに書けばよい (そういうレポートを期待している)
 - 「エージェントの色を変えました」、「シミュレータが表示する情報を増やしました」のような、取り組んでいる本人が「面白い」と思わないこと (レポート課題のための課題) はぜひ避けてほしい

 ___ 以下は自習の講義ページの全文です。

 実習の趣旨に沿った、面白く、挑戦的なミニプロジェクトの案を 20 個提案して。
 それぞれの案について、タイトル、何をするのか (WHAT)、何のためにするのか (WHY)、どのようにするのか (HOW)、難易度(10段階評価) を箇条書きで書いて。
 あなた (AI) が考える、おすすめの順にランキング形式で示して。

 ___
 [[~/public_html/lecture/netcompx/2025/index.pod]]

Gemini 3 の回答

https://lsnl.jp/~ohsaki/lecture/netcompx/2025/priv/75-netcompx.html

課題 2 の回答に対するコメント

- agent や mobility などの利用可能な新規クラス (例: agent.BioScatter, mobility.Patient ) を作成する手順が分からない。エージェントごとに異なる agent, mobility クラスを割り当てる方法が分からない。

既存のプログラムをコピーして、少しずつ変えるのが簡単です。例えば
mobility/randomwalk.py を mobility/myrandomwalk.py にコピーして、randomwalk
や RandomWalk が登場している箇所を真似てmyrandomwalk や MyRandomWalk を追加
します。まずは、dtnsim -m MyRandomWalk で通常のランダムウォークが実行できる
ようにします。

- dtnsimがどのようなグラフ構造(ノード、リンク)を前提としているのか分からないので、統計的に解析しようと思ってもどうすればいいのか良く分からない。

シミュレータなので、グラフは何でも構いません (何も前提を置いていません)。任
意のトポロジで構いませんが、各ノードの座標を指定する必要があります。グリッド
トポロジの path/grid.py あたりを読んでもらうと良いと思います。

- 災害時のような通信環境では、どのルーティングアルゴリズムが適しているのかがよく分からない。

何がいいんでしょうね。

- シミュレーション空間の大きさや境界条件がどこで定義されているのか分からず、エージェントが画面外に出たときの内部処理を理解できていない

mobility/fixed.py を見てください。width, height がフィールドの幅と高さです。
今の実装では、長さの単位は m (メートル) を想定した値を設定しています。

- dtnsimに先生が実装した移動モデルはなぜこれらの移動モデルなのか、調べていたら他にも移動モデルがあったので、理由(実際に使われている順で実装したなど)があったら教えて欲しい。

DTN の研究でよく使われる代表的な移動モデルを実装しています。

- ノード数を100や1000に増やした場合、Pythonの処理速度的にボトルネックになるのは「移動計算」ですか?それとも「ルーティング(経路探索)」ですか?

「シミュレータ解説 (1) (概要、エージェント)」の回の講義資料を見てください。

- dtnsimの実行中に、エージェントの動きや速さをリアルタイムで変更することはできますか?

はい。例えば dtnsim のメインループで以下のように書けば、実行中にエージェント
の移動がどんどん速くなります。

  # the main loop
  while sched.is_running():
      sched.cache_zones()
      for agent in sched.agents:
          agent.advance()
          # エージェントの速度を 5% 速くする
          agent.mobility.velocity *= 1.05
      for agent in sched.agents:
          agent.flush()
      monitor.display_status()
      monitor.update()
      sched.advance()
  monitor.close()

- ノード数を増やした際に計算できなくなることを避ける必要があるため、dtnsimの計算量はどの程度のオーダーなのかを知りたい。

「シミュレータ解説 (1) (概要、エージェント)」の回の講義資料を見てください。

- 現状のdtnsimにはバッテリー(エネルギー)の概念がないように見えます。「通信するたびに電池が減り、切れると動かなくなる」という機能を実装するには、AgentクラスとMobilityクラスのどちらに手を入れるのが適切ですか?

 「通信が原因でバッテリが消耗する」ならエージェントですね。agent/carryonly.py
 を以下のような方針で修正するとよいでしょう。

 class CarryOnly():
     def __init__(self,
                  id_=None,
                  scheduler=None,
                  mobility=None,
                  monitor=None,
                  range_=50):
         if id_ is None:
             id_ = len(scheduler.agents) + 1
         if not scheduler:
             die("Scheduler class must be specified.")
         if not mobility:
             die("Mobility class must be specified.")
         if not monitor:
             die("Monitor class must be specified.")
         if range_ > MAX_RANGE:
             die(f"range cannot exceed MAX_RANGE ({MAX_RANGE})")
         self.id_ = id_
         self.scheduler = scheduler
         self.mobility = mobility
         self.monitor = monitor
         self.range_ = range_

         self.last_neighbors = []
         self.received = defaultdict(int)
         self.receive_queue = defaultdict(int)
         self.delivered = defaultdict(int)
         self.tx_count = 0
         self.rx_count = 0
         self.dup_count = 0
         # 電池残量を初期化する。INITIAL_BATTERY は別途定義する必要がある。
         self.battery = INITIAL_BATTERY

         self.scheduler.add_agent(self)
       :
       :
     def sendmsg(self, agent, msg):
         """Send a message MSG to the agent AGENT."""
         agent.recvmsg(self, msg)
         self.tx_count += 1
         # 電池残量を減らす。TX_ENERGY は別途定義する必要がある。
         self.battery -= TX_ENERGY
         self.monitor.display_forward(self, agent, msg)
         self.monitor.change_agent_status(self)

     def recvmsg(self, agent, msg):
         """Receive a message MSG from the agent AGENT.  Note that the received
         message is temporally stored in the reception queue."""
         self.receive_queue[msg] += 1
         self.rx_count += 1
         # 電池残量を減らす。RX_ENERGY は別途定義する必要がある。
         self.battery -= RX_ENERGY
         if msg in self.received:
             self.dup_count += 1
         self.monitor.change_agent_status(self)

 何もしなくても電力を消費する、というのをモデル化するなら、経過時間に比例して
 self.battery を減少させるとよいでしょう。

- ノード同士の通信(遭遇)がどのように判定されているのかがあまり理解できていない。

「シミュレータ解説 (1) (概要、エージェント)」の回の講義資料を見てください。

- 端末同士が遭遇したと判定される距離や障害物の影響がどう計算されているか。

「今はユークリッド距離 <= 無線通信可能範囲」で判定しています。障害物はモデル
化していません (逆に言えば、何もない自由空間をモデル化しています)。

- エージェントの動きをシミュレーション実行中にキーボードなどで操作できるのか。

今のままでは無理ですが、改造すれば可能です。

- メッセージ配送成功・失敗の判定条件はどこで決まっているのか

配送完了は monitor/null.py の以下の箇所です。今の dtnsim には配送失敗という
概念はありません。

    def is_delivered(self, agent, msg):
        """Check if the destination of the message MSG is AGENT."""
        return agent.msg_dst(msg) == agent.id_
      :
      :
    def display_forward(self, src_agent, dst_agent, msg):
        """Update the statistics when the message MSG is forwarded from
        SRC_AGENT to DST_AGENT."""
        self.tx_total += 1
        self.rx_total += 1
        if self.is_duplicate(dst_agent, msg):
            self.dup_total += 1
        if self.is_delivered(dst_agent, msg):
            self.delivered_total += 1
        if self.is_delivered(dst_agent,
                             msg) and not dst_agent.received.get(msg, None):
            self.uniq_delivered_total += 1

- メッセージに優先度(緊急度)という新しい情報を追加するには、どのファイル(クラス)を修正すればよいのか。ノードのメッセージバッファが満杯になったときに、メッセージを捨てる処理が書かれているのは、コードのどの場所なのか。

 今の実装では、メッセージは 1-2-3 のような文字列です。agent/carryonly.py より:

     def msg_src(self, msg):
         src = msg.split('-')[0]
         return int(src)

     def msg_dst(self, msg):
         dst = msg.split('-')[1]
         return int(dst)

     def msg_id(self, msg):
         id_ = msg.split('-')[2]
         return int(id_)

 優先度を実装する単純な方法は、メッセージの最後に優先度を足して
 src-dst-id-prio とすることです。

 今のシミュレータではバッファの容量は無制限です。バッファの容量を考慮するなら、
 recvmsg でバッファの空きの有無をチェックして、空きがなければ廃棄するように書
 くとよいでしょう。

     def recvmsg(self, agent, msg):
         """Receive a message MSG from the agent AGENT.  Note that the received
         message is temporally stored in the reception queue."""
         self.receive_queue[msg] += 1
         self.rx_count += 1
         if msg in self.received:
             self.dup_count += 1
         self.monitor.change_agent_status(self)

- 自作の通信方式(CarryOnly と Epidemic の中間など)を実装できるか知りたい。

もちろんできます。

- 遅延の定義が曖昧なところ(どこまでの遅れで遅延といえるのか)。

普通は、

メッセージ配送遅延 = 受信者が受信できた時刻 - エージェントがメッセージ配送を開始した時刻

を用います。しかし、何を遅延と思うか (何の遅延に興味があるか) は問題や人によっ
ても変わります。従って、万人が納得する唯一の「遅延の定義」というものはありま
せん。

- 自作した移動モデルを実行時に使用するためのコマンドを新たに追加する方法が知りたいです。(-mの後にOriginalなどを入力することで自作の移動モデルを使えるようにしたいです)

上の質問への回答を見てください。

- dtnsim の構造(ノード配置や可視化方法)を自分で変えることができるのかどうかが分からない。また、どの程度まで変えることができるのか分からない。

変更できますし、(ソースコードがあるので) 何でもできます。物理法則に支配され
ますが、その範囲内であれば何でもできます。

- ランダムにリンクを張るのと格子状に張るのとで効率がどれぐらい変わるのかが予想できない。

そのためのシミュレータなので、ぜひ実験してみてください。

- dtnsim にアルゴリズムを適用できるのかどうか分からない。

どういう意味ですか?

- ノード同士が接触したとき、どのタイミングでメッセージ交換が行われるのかと同時に複数ノードと接触した場合の処理方法

agent/carryonly.py を読んでみてください。

    def forward(self):
        """Try to forward carrying messages to all encountered agents."""
        encounters = self.encounters()
        for agent in encounters:
            for msg in self.pending_messages():
                # forward carrying messages only to the destination
                dst = self.msg_dst(msg)
                if agent.id_ != dst:
                    continue
                self.sendmsg(agent, msg)
                del self.received[msg]
                self.delivered[msg] += 1

forward メソッドで、encounter と判定された時に sendmsg メソッドを呼び出して
メッセージが送信されます。

上記のコードは encouters リスト中のエージェントに順番に sendmsg を実行してい
るコードですが、実行順序に依存しないように、いったんキューに格納して最後にま
とめて反映する (flush する) 実装になっています。

詳しくは「シミュレータ解説 (1) (概要、エージェント)」の回の講義資料を見てください。

- 複数パラメータと乱数シードの組み合わせによる dtnsim の実行を自動化し、結果ログの集計とグラフ化を自動で行うようにする。

がんばってください。

- 再現性の高い客観的な統計的評価を効率的に実現したい。

特に「信頼区間」を調べてみてください。今日のオプション課題も参考になると思います。

オプション課題: 性能評価 (p% 配送遅延)
https://lsnl.jp/~ohsaki/lecture/netcompx/2025/24.html

- matplotlib/seabornで客観的な評価グラフを自動生成する。

いいですね。

- ノードの通信半径(通信距離)が、dtnsim のどのファイルや変数に設定されているのか。

 agent/carryonly.py を見てください。self.range が通信可能範囲 (デフォルトは
 50m) です。講義資料にも説明があります。

 class CarryOnly():
     def __init__(self,
                  id_=None,
                  scheduler=None,
                  mobility=None,
                  monitor=None,
                  range_=50):
         if id_ is None:
             id_ = len(scheduler.agents) + 1
         if not scheduler:
             die("Scheduler class must be specified.")
         if not mobility:
             die("Mobility class must be specified.")
         if not monitor:
             die("Monitor class must be specified.")
         if range_ > MAX_RANGE:
             die(f"range cannot exceed MAX_RANGE ({MAX_RANGE})")
         self.id_ = id_
         self.scheduler = scheduler
         self.mobility = mobility
         self.monitor = monitor
         self.range_ = range_

         self.last_neighbors = []
         self.received = defaultdict(int)
         self.receive_queue = defaultdict(int)
         self.delivered = defaultdict(int)
         self.tx_count = 0
         self.rx_count = 0
         self.dup_count = 0

         self.scheduler.add_agent(self)

- cellxの画面に、ノード(エージェント)以外の図形(円など)を追加で描画するには、monitor.Cell クラスのどのメソッドを使えばよいのか。

cellx の描画命令が標準出力に書き出されればいいので、どこで print しても動き
ます。ですが、一番キレイなのは monitor/cell.py の update メソッドあたりを変
更する方法でしょう。

例えば、以下のようにすると、フィールド中央に巨大な三角形が表示されます。

  def update(self):
      # 巨大な三角形を描画
      print('define dummy polygon 3 100')
      print('display')

- エピデミックルーティング の実装はソースコードのどのファイルでどのクラスにあり、転送の意思決定はどこで行われているのか知りたい。

agent/epidemic.py で、「encounter したらひたすら配る」という意思決定をしてい
ます。

class Epidemic(CarryOnly):
    def forward(self):
        """Try to deliver its carrying message to all encountered agents."""
        encounters = self.encounters()
        for agent in encounters:
            for msg in self.pending_messages():
                dst = self.msg_dst(msg)
                if agent.id_ == dst:
                    self.sendmsg(agent, msg)
                    del self.received[msg]
                    self.delivered[msg] += 1
                else:
                    self.sendmsg(agent, msg)

- テキスト1行と、高画質な写真は、dtnsimの中では同じ1個のメッセージとして扱われているのか

はい。上の質問への回答も見てください (単に src-dst-id という情報で表現しています)。

- ノード数を増やすと計算時間が増えるが、どの処理が鍵になっているのか

上の質問への回答を見てください。

- シミュレーションのスピードを速めることはできるのか。

描画を速くするだけなら

dtnsim | cellx -L 10000

で速くなります (デフォルトでは 60 frame/s で制限をかけています)。シミュレー
タ自体の高速化なら、プロファイリングして時間がかかっている箇所を特定し、そこ
を改善できるかを検討するとよいでしょう。

レポート課題 2025/12/17

「レポート課題 2025/09/24」と同じ。

https://lsnl.jp/~ohsaki/lecture/netcompx/2025/#10-7

[<22. シミュレータ解説 (2) (モビリティ、可視化)] [>24. オプション課題: 性能評価 (p% 配送遅延)]