2

二項関係と推移関係の洗練されたインターフェイスを定義したいと思います。私は二項関係を対の集合、ある集合 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>SetMultimapgetInverselyRelated(T to): Set<F>SetMultimap

この問題には、多数の代替アプローチがあります。たとえばBinaryRelation、拡張として定義できますSetMultimap。または、完全に非表示にすることを避けてSetMultimap、 経由でアクセスできるようにすることもできますBinaryRelation#asSetMultimap()。そうすれば、すべての素敵なメソッド インターフェイスを取得できます。または、特定のインターフェースのアイデアを完全に放棄し、 のSetMultimap代わりに を使用することもできますBinaryRelation。その場合、リバース トラバーサル操作は特定のクラスで利用できるがインターフェース レベルでは利用できない最適化機能であると考えられます。または、SetMultimap 以外のものを設計の基礎として使用することもできます。

したがって、私の質問 (最後に!): 私のアプローチについてどう思いますか? 他のアプローチを考えていただけますか?私が見落としたいくつかの問題?私が使用できる既存のソリューション?

可能なリンク

いくつかのグラフ ライブラリ ( JUNGJGraphTBlueprint ) を使用することを考えましたが、それらは私のニーズに合わないと思います。私の謙虚な意見では、これらすべてEdgeに複雑さを追加するクラス (または Edge 型パラメーター) があり、インターフェイスと実装を提供するものはありません。ユーザーマニュアルにあるように、 Grphは頂点のオブジェクトを提供しません。私は何かを見逃しているかもしれませんが、同意できない場合は教えてください。SetMultimap

(編集) Xaerxess が述べたように、このグアバの問題は、ここで BiSetMultimap と呼ぶものを Guava に追加することを提案しています。

4

1 に答える 1