私は、何度か、またいくつかの雇用主のために、独自のグラフ データ構造を実装する理由がありました。アクセスの完全な柔軟性のために、Node
クラスとクラスの 2 つのクラスを使用してこれを実装する必要があることがよくありEdge
ます。
ノードには一連の発信エッジ (およびおそらく着信エッジ) があり、エッジにはソースとシンク (両方ともノードへのマネージド ポインター) があります。多くの場合、これらのグラフにはサイクルがあります。
私の質問は、特にグラフを変換および変更するときに、そのようなグラフのデータ構造でメモリを管理する最良の方法は何ですか? 循環が存在するため、参照カウントには向いていません (ウィーク ポインターを使用しようとしても、循環がどこにあるのか、したがってどこにウィーク リンクを配置するのかが明確でないことがよくあります)。
私のさまざまな実装では、グラフおよびグラフへのエントリ ポイントのリストとは別に、割り当てられたすべてのノードとエッジを追跡することがよくありました。次に、実際には単純なガベージ コレクターを実装しました。一定の間隔で、さまざまなグラフ変換 (いくつかのノード/エッジのリンク解除を含む) を適用して、以下を含む gc を実行します。
- エントリ ポイント ノードから開始し、そこからグラフを介して到達可能なすべてのノードとエッジをアクティブとしてマークします (BFS/DFS 経由)。
- 完全なセット内のすべてのノードとエッジを繰り返し処理し、前の手順でマークされていないものを削除します。
これはうまく機能します (そして、マーク/スイープの単純な実装です)。しかし、それはいつも少し不器用に見えてしまいます。誰かがこの問題、またはより良い代替ソリューションについての洞察を持っていますか?