二項関係と推移関係の洗練されたインターフェイスを定義したいと思います。私は二項関係を対の集合、ある集合 X × Y の部分集合と考えています。実際には主に推移関係を扱うつもりですが、一般的な二項関係が必要になることもあります。これは主に私自身の使用のためですが、他のユーザー向けに FLOSS ライブラリとして公開することになるかもしれません。これらのクラスの使用に関する正確な要件がまだないため、私の定義が一般的なレベルで意味を成すことを望みます: 科学研究に関連する実験作業のために必要です。現在いくつかのアイデアがありますが、どのような種類かはまだ不明です研究をしているうちに、より多くのアイデアが生まれるので、私が必要とする実験の数。
一般的なアイデア
私が(私が思うに)必要なものの核心は次のとおりです。
/**
* @param <F>
* the type used for the “from” elements.
* @param <T>
* the type used for the “to” elements.
*
*/
public interface BinaryRelationTentative<F, T> {
/**
* @return a view of the domain of this relation: all the elements x such that for some y, (x, y) is in the
* relation.
*/
public Set<F> getFromSet();
/**
* @return a view of the range of this relation: all the elements y such that for some x, (x, y) is in the relation.
*/
public Set<T> getToSet();
/**
* @return the number of pairs that this relation contains.
*/
public int size();
/**
* @return <code>true</code> iff the relation has empty from and to sets.
*/
public boolean isEmpty();
/**
* A binary relation equals an other one iff they have equal from and to sets and for each (x, y) contained in one,
* (x, y) is contained in the other one.
*/
@Override
public boolean equals(Object obj);
/**
* @return whether the given <code>from</code> element is in relation with the <code>to</code> element.
*/
public boolean contains(F from, T to);
/**
* Optional operation.
*/
public boolean add(F from, T to);
}
(これはコア機能にすぎないので、私の言いたいことが分かるように — トラバーサルなどのより良い機能は歓迎されます。以下を参照してください。) 次に、TransitiveRelation<E>
を拡張BinaryRelation<E, E>
し、 を実装するのadd
ではなく、 を提供する を定義しますaddTransitive(F from, T to)
。
古典的なコレクションの再利用
もちろん、古典的なコレクション インターフェイスを可能な限り再利用したいと考えています。Guava のSetMultimap
( javadoc、ユーザー ガイド) には、私が必要とするコア機能が含まれているようです。ユーザー ガイドでは、ラベルのない有向グラフの使用例についても言及しています。直接使用する際に見られる1つの問題SetMultimap
二項関係の場合に「キー」と「値」について話すのは奇妙です。さらに、何かが欠けています。SetMultimap (キーから値に移動するように設計されている) には意味のある非対称性がありますが、バイナリ関係ではあまり意味がありません。SetMultimap には、"from" 要素が与えられた場合に、それに関連する "to" 要素を効率的に (つまり、リレーション全体をトラバースすることなく) 反復できるインターフェイス (および実装) があります。同様に、「to」要素を使用して、対応する「from」要素を効率的に反復できるようにしたいと考えています。そのため、BiSetMultimap ( aMap<K, Set<V>>
と a の両方に対応Map<V, Set<K>>
) と呼ばれるものが必要です。Javaの世界ではそのようなものを見つけることができませんでした。
したがって、私は現在、へのファサードBinaryRelation<F, T>
として定義することを考えています。次に、より適切な名前のメソッドをインターフェイスに作成し (概念的には のメソッドと同等)、 "from" 要素を提供するメソッドを追加できます。1つは関係を表し、もう 1 つはその逆を表します。SetMultimap<F, T>
SetMultimap
getInverselyRelated(T to): Set<F>
SetMultimap
この問題には、多数の代替アプローチがあります。たとえばBinaryRelation
、拡張として定義できますSetMultimap
。または、完全に非表示にすることを避けてSetMultimap
、 経由でアクセスできるようにすることもできますBinaryRelation#asSetMultimap()
。そうすれば、すべての素敵なメソッド インターフェイスを取得できます。または、特定のインターフェースのアイデアを完全に放棄し、 のSetMultimap
代わりに を使用することもできますBinaryRelation
。その場合、リバース トラバーサル操作は特定のクラスで利用できるがインターフェース レベルでは利用できない最適化機能であると考えられます。または、SetMultimap 以外のものを設計の基礎として使用することもできます。
したがって、私の質問 (最後に!): 私のアプローチについてどう思いますか? 他のアプローチを考えていただけますか?私が見落としたいくつかの問題?私が使用できる既存のソリューション?
可能なリンク
いくつかのグラフ ライブラリ ( JUNG、JGraphT、Blueprint ) を使用することを考えましたが、それらは私のニーズに合わないと思います。私の謙虚な意見では、これらすべてEdge
に複雑さを追加するクラス (または Edge 型パラメーター) があり、インターフェイスと実装を提供するものはありません。ユーザーマニュアルにあるように、 Grphは頂点のオブジェクトを提供しません。私は何かを見逃しているかもしれませんが、同意できない場合は教えてください。SetMultimap
(編集) Xaerxess が述べたように、このグアバの問題は、ここで BiSetMultimap と呼ぶものを Guava に追加することを提案しています。