2016-07-25 11 views
0

私はアーキテクチャ/機能に関する質問があります:継承のすべてのパラメータの組み合わせのアーキテクチャ

問題を解決するアルゴリズムがあります。ジェネリック型のいくつかのインスタンス変数を含むオブジェクトによって表される一定量の情報を使用できます。実際、関連するn個の変数がありますが、アルゴリズムは未知のサブセットで問題を解決するかもしれません。そのサブセットを見つけるために、私は可能なすべての変数の組み合わせをアルゴリズムに渡したいと思っています。ですから、可能な限り少ない労力で情報タイプを切り替えることができる構造が必要です。

特に、現在調査されている変数のサブセットのみが等しい場合は、2つの情報オブジェクトが同じである必要があります。だから、私はequalsを上書きする必要があるようだ。これは、すべての可能なサブセットに対してクラスを書くことを意味し、合計2^nのクラスにつながります。

これを行うもっとエレガントな方法はありますか?そして2^nクラスでなければならない場合、どのように継承を設計しますか?

アンディターナーとmellowmaroonsコメントに応答して

:私は、ソルバーは関数fであることを想像する:S - 正しい動作(0または1)指定された状態のために私に指示> {0,1} 。状態sは、長さkのベクトルによって与えられる。それを簡単に保つために、S = Z^kと仮定する。整数。しかし、S = Z^l、l < kにつながる変数の未知のサブセットを持つステータスルームを構築すれば十分かもしれません。可能なサブセットをテストするには、アルゴリズムをそれぞれ対応するステータスルームのオブジェクトで実行させる必要があります。したがって、処理中にステータスルームのオブジェクトが生成され、ソルバーオブジェクトに渡されます。ソルバはそれらを受け入れることができ、既に存在する状態を認識できる必要があります。 一般的には、これを構造化する方法は何ですか?


は、ここに私の現在のアプローチ

//abstract superclass to wrap the information types 

    public abstract class Information { 

    } 

// concrete class that contains 1st and 2nd parameters 

    public class InformationA extends Information{ 

     int size; 
     int weight; 

    // two InformationA objects are equal if only 1st and 2nd parameter are equal 

    public boolean equals(Object o){ 
     if(o instanceof InformationA){ 
      InformationA info = (InformationA) o; 
      return info.size == size && info.weight == weight; 
     } 
     return false 
    } 

// concrete class that contains 2nd and 3rd Parameters 

    public class InformationB extends Information { 

     int weight; 
     int color; 

     //another equals method with the same structure than before 

    } 

import java.util.HashMap; 
import java.util.Random; 

// the solver class contains the solve function 
// It associates an action with every possible status/information 

public class Solver { 

    HashMap<Information, Boolean> solveFunction; 

    // If a status/information has been treated already return the value 
    // else generate a random value 

    public Boolean getAction(Information i){ 
     if(solveFunction.containsKey(i)) return solveFunction.get(i); 
     solveFunction.put(i, new Random().nextInt(2) == 0); 
     return solveFunction.get(i); 
    } 

    public void solve(Problem problem){ 
//  while(!problem.isSolved()){ 
//##  somehow extract only the needed status Parameters 
//   pass them to getAction method and invoke the response on the problem 
//  } 
    } 

} 

public class Problem { 

// public boolean isSolved(){ 
//  return some signal 
// } 

// public void process(Boolean action){ 
//  the process develops according to the action and reaches a new state 
//  } 

//## public getStatus(){ 
//  return the status in a way that the solver can extract the needed subset of information 
// } 

} 

public class Controller { 

// generate the problem and the solver 
//##somehow tell the solver which Information type to use 
// Let the solver solve the problem  

    public static void main(String[] args){ 
     Problem problem = new Problem(); 
     new Solver().solve(problem); 
    } 

} 

それは、このアプローチが必要なサブセットを生成し、ソルバーに渡すの問題につながることは明らかだの例です。これは解決可能かもしれません。しかし、依然として、さまざまなパラメータの組み合わせを持つすべての情報クラスを作成するという問題があります。

+1

なぜ継承はすべての組み合わせをモデル化する正しい方法だと思いますか?ジェネリックソルバーをお持ちの場合は、一般的に機能するタイプが必要です。これらの「パラメータタイプ」のすべてが共通のインタフェースを持っていない限り、それを行うことはできません。 –

+0

私はあなたが何を求めているのかを明確にすべきだと思います。また、オブジェクト指向の概念はJavaだけに限定されず、質問がOOP全体に関係する場合は、タグを修正することができます。 – mellowmaroon

+0

現在の実装アイデアで2つの異なるサブセットクラスを示すコードサンプルがありますか?この問題はあまりにも一般的に説明されており、実際の詳細は欠落しています。 – plalx

答えて

0

よく質問はかなり古いです。私はそれを解決するためにいくつかの進歩を遂げたと思うので、いくつかのフィードバックや改善を期待して私のアプローチを投稿しています。

異なるパラメータの組み合わせを切り替えるために、スーパークラス "情報"のサブクラスを使用しようとしました。代わりに、私は今、情報クラスの1つのインスタンスを表すためにHashMapを使用し、それらのHashMapのHashMapは、すべての情報インスタンスにアクションを割り当てる関数fを表します。

// the class that represents first parameter 

public class A{ 
    //can be a selfmade class or a String or some generic type 
} 

// same for parameters B,C,D,E... 

import java.util.HashMap; 
import java.util.Random; 

// the solver class fills the solveFunction HashMap 
// It associates an action with every possible status/information 

public class Solver { 

    HashMap<HashMap<String,Object>, Boolean> solveFunction; 

    // If a status/information has been treated already return the value 
    // else generate a random value 

    public Boolean getAction(HashMap<String, Object> info){ 
     if(solveFunction.containsKey(info)) return solveFunction.get(info); 
     solveFunction.put(info, new Random().nextInt(2) == 0); 
     return solveFunction.get(info); 
    } 

    public HashMap<HashMap<String, Object>, Boolean> solve(Problem problem, HashMap<HashMap<String, Object>, Boolean> solveFunction){ 
     this.solveFunction = solveFunction; 
     while(!problem.isSolved()){ 
      problem.process(getAction(problem.getStatus())); 
     } 
    } 

} 

public class Problem { 

String[] usedParameters; 

public Problem(String[] usedParameters){ 
    this.usedParameters = usedParameters; 
} 

    public boolean isSolved(){ 
//  return a signal 
    } 

    public void process(Boolean action){ 
//  the process develops according to the action and reaches a new state 
     } 

public getStatus(){ 
    HashMap<String, Object> status = new HashMap(); 
    for(String s : usedParameters){ 
     switch(s){ 
      case "A": status.add("A", new Object()); 
      case "B": status.add("B", new Object()); 
      case "C": status.add("C", new Object()); 
// and so on 
     } 
    } 
    return status; 
} 
} 

public class Controller { 

// generate the problem and the solver 
// Let the solver solve the problem  

    public static void main(String[] args){ 
     String[] usedParameters = {"A","C"}; 
     HashMap<HashMap<String, Object>, Boolean> solveFunction = new HashMap(); 
     Problem problem = new Problem(usedParameters); 
     new Solver().solve(problem, solveFunction); 
    } 

} 

上記のコードは、もちろん動作しませんが、アイデアを与えるだけです。 ランダムに生成された解答関数が失敗する場合は、キャッチする必要があります。コードの残りの部分は一般性を失うことなく完了できないと私は思う。

関連する問題