1

問題

グラフで機能し、ノードが類似しているかどうかを示すノードペアのスコアを返すアルゴリズムをいくつか実装したいと考えています。アルゴリズムは、単一のノード ペアとすべての可能なノード ペアで機能する必要があります。後者の場合、コレクション/マトリックスが返されます。

私のアプローチ

アルゴリズムはから派生します

class SimilarityAlgorithm {
public:
  Base(const Graph& G);

  virtual double run(node u, node v) = 0; // indices for nodes in the graph

  virtual ScoreCollection& runAll() = 0;
}

現在、アルゴリズムはメモリ使用量が異なります。一部のアルゴリズムは対称的であり、(u, v) と (v, u) のスコアは同一です。これには、返されるさまざまな ScoreCollection タイプが必要です。例としては、疎行列と三角行列があり、どちらも から派生しScoreCollectionます。

これは、共変の戻り値の型に要約されます。

class SpecificAlgorithm : SimilarityAlgorithm {
public:
  double run(node u, node v);

  // The specific algorithm is symmetric and thus uses a symmetric matrix to save memory
  SymmetricScoreCollection& runAll();
}

質問

  • この設計アプローチは、この問題に適していますか?
  • コレクションがすべて行列として実装されているという事実を公開する必要がありますか?
4

1 に答える 1

0

あなたのデザインは、あなたが説明する問題に適しているようです。

問題:

SpecificAlgorithmただし、 : runAll()は基本クラスの仮想関数と同じ型を返さないという問題があります。したがって、呼び出されません (または、仮想関数がないためにコードがコンパイルされない可能性が高くなります)。

解決:

の派生クラスをScoreCollection作成することにより、 のポリモーフィック アプローチも使用します 。 SymmetricScoreCollectionScoreCollection

class SymetricScoreCollection: public ScoreCollection {
//define the member functions to access the values virtual
...
}; 

class SpecificAlgorithm : public SimilarityAlgorithm {
public:
  double run(node u, node v);

  // The specific algorithm is symmetric and thus uses a symmetric matrix to save memory
  ScoreCollection& runAll();
};    

実際、これはファクトリ メソッド patternのアプリケーションであり、次の役割があります。

  • SimilarityAlgorithm はファクトリであり、
  • SpecificAlgorithm は具体的なファクトリです
  • ScoreCollection は製品です
  • SymetricScoreCollection は具体的な製品です

追記:

ScoreCollectionfromへの参照を返すことにrunAll()は、いくつかのリスクが伴います。特定 saのアルゴリズムであるとします。

次のステートメントでは:

ScoreCollection sc = sa.runAll();

sa.runAll()への参照を返しますが、参照されたSymetricScoreCollectionオブジェクトを sc にコピーして、それを ScoreCollection にします。 スライスが発生し、ポリモーフィズムが機能しなくなります。

ただし、次のステートメントは成功します。

ScoreCollection& rsc = sa.runAll();

rsc は参照であり、SymetricScoreCollectionによって返された元のオブジェクトを引き続き参照しsa.runAll()、すべてが設計どおりに機能するためです。

参照を返すときに見過ごされがちなミスがあることがわかります。参照ではなくポインタを返すことをお勧めします。

于 2015-02-01T17:04:45.717 に答える