ファジー推論ルールを使用した選択肢の多基準選択。 パート1/3:理論
選択するには、対応するファジー論理関数(Functionインターフェイスを実装)のセットと特定の形式化された入力データ(最初はdouble要素の2次元配列を表す)を含むルールセット(Ruleインターフェイス)が必要です。
便宜上、Ruleクラス内のデータ(double要素の1次元配列)は、Skillラッパークラスに保存されます。
次に、ルールはFacadeクラスに渡され、ファジーサブセットからファジーサブセットが作成されます。そのサイズは、調査するオブジェクトの数と必要な精度(静的変数クラスで指定)に依存します。
このサブセットシステムの一般的な機能ソリューション(calcDメソッド)を見つけた後、単位間隔で結果のファジーサブセットを比較する手順を適用して、最適なソリューション(calcCメソッド)を取得します。 このために、レベルセットのデータのカーディナリティとそれらのポイント推定値が計算されます(calcSメソッド)。 このアルゴリズムでは、要素の必要なソートを容易にするために、Numクラス構造が使用されます。
作業の最後に、各オブジェクトのポイント推定値が取得されます。この値の大きい方が最適な選択に対応します(getBestメソッド)。
1.データの提示。
計算の精度に影響する行列Dの次元は、変数クラスによって設定されます
package Variables; public class Variables { private static int SIZE_OF_D = 11; private static double STEP_OF_D = (double)1/(SIZE_OF_D-1); public static int SIZE_OF_D();/* SIZE_OF_D*/ public static double STEP_OF_D();/* STEP_OF_D*/ }
トリッキーなソートを簡単にするnumクラス:
package Support; public class Num { public double x; public double u; public Num(double x, double u); // x u }
関数-興味深いものは何もありません。ただ1つのメソッドと識別子を含むインターフェースです。
package Support; public abstract class Function { public String ID; public abstract double getY(double x); }
Skillクラスは、各オブジェクトのパラメーターを説明するために似ています:
package Support; public class Skill { public double[] skill; public Skill(double[] skill);/* skill */ }
マトリックスを操作するために、Matrixクラスが記述されています。
package Support; public class Matrix { private double matrix[][]; public int ROWS; public int COLUMNS; public Matrix(int rows, int columns); // public Matrix(double[][] m); // public double[][] getMatrix(); // public static Matrix findMin(Matrix[] Arr) throws Exception()/* , — */ { int rows = Arr[0].getMatrix().length; int cols = Arr[0].getMatrix()[0].length; for (int i=0;i<Arr.length;i++) if ((Arr[i].getMatrix().length != rows) || (Arr[i].getMatrix()[0].length != cols)) throw new Exception("Incorrect size of matrix"); double[][] min = new double[rows][cols]; for (int i=0;i<rows;i++) for (int j=0;j<cols;j++) min[i][j]=Double.MAX_VALUE; for (int i=0;i<rows;i++) for (int j=0;j<cols;j++) for (int k=0;k<Arr.length;k++) if (Arr[k].getMatrix()[i][j]<min[i][j]) min[i][j]=Arr[k].getMatrix()[i][j]; return new Matrix(min); } public double[] getRow(int row); // public void output(); // }
ルール-ルールの説明:
package Support; public class Rule{ public Skill[] u; private Function function; public double[] m; public Rule(Skill[] u, Function function) throws Exception{ this.u = u; this.function = function; m = findMin(u); } public double[] findMin(Skill[] arr) throws Exception /* ( — )*/ { int size=arr[0].skill.length; for (int i=0;i<arr.length;i++) if (arr[i].skill.length != size) throw new Exception("Incorrect skill"); double[] min = new double[size]; for (int i=0;i<min.length;i++) min[i] = Integer.MAX_VALUE; for (int i=0;i<arr.length;i++) for (int j=0;j<size;j++) if (arr[i].skill[j]< min[j]) min[j] = arr[i].skill[j]; return min; } public double getF(double x){ /* , */ return function.getY(x); } }
SubsetD-各ルールの行列D(i)の形成に使用
package Support; import Variables.Variables; public class SubsetD { private final boolean DEBUG = false; public double[][] d_arr; public SubsetD(Rule rule) throws Exception{ d_arr = makeD(rule); } /* - */ public double[][] makeD(Rule rule) throws Exception{ d_arr = new double[rule.m.length][Variables.SIZE_OF_D()]; for (int i=0;i<rule.m.length;i++) for (int j=0;j<Variables.SIZE_OF_D();j++){ /* D, — findMin*/ d_arr[i][j]=findMin(1-rule.m[i]+rule.getF(j*Variables.STEP_OF_D())); if (DEBUG) System.out.print("m["+i+"]="+rule.m[i]+"\tj*Variables.STEP_OF_D()="+j*Variables.STEP_OF_D()+"\tY="+rule.getF(j*Variables.STEP_OF_D())+"\n"); } return d_arr; } private double findMin(double x){ if (x>1) return 1; return x; } }
データ入力を担当する主なクラスの1つは入力です:
package Support; public abstract class Input { protected Rule[] rl = null; protected Function[] func = null; public int PARAMS_CNT = -1; public int FUNC_CNT = -1; public abstract Rule[] makeRules(double[][] arr) throws Exception; // public abstract void initFunc(Function[] func); // public Function[] getFunctions(); // }
2.ファサード
必要な計算をすべて実行するアルゴリズムの王冠。
package FLO_Engine; import Variables.Variables; import Support.Matrix; import Support.Rule; import Support.SubsetD; import Support.Num; public class Facade { boolean DEBUG_D = false; boolean DEBUG_C = false; boolean DEBUG_LM = false; Facade(boolean debug_d, boolean debug_c, boolean debug_lm){} /* */ public Matrix calcD(Rule[] rules) throws Exception{ /* */ //page 97 Rule[] M = rules; //page 98 SubsetD[] sD = new SubsetD[M.length]; for (int i=0;i<M.length;i++) sD[i] = new SubsetD(M[i]); Matrix[] matr = new Matrix[sD.length]; for (int i=0;i<sD.length;i++){ matr[i]=new Matrix(sD[i].d_arr); if (DEBUG_D) ; /* D(i)*/ } Matrix min = Matrix.findMin(matr); /* D*/ if (DEBUG_D) min.output(); return min; } public double[] calcC(Matrix D){ /* */ int len = D.COLUMNS; double[] c = new double[D.ROWS]; /* , */ double[] x = getX(); /* X */ for (int i=0;i<D.ROWS;i++){ double[] u = D.getRow(i); Num[] arr = new Num[len]; for (int j=0;j<len;j++) arr[j]= new Num(x[j],u[j]); for (int j=0;j<len;j++) /* , i- , — */ for (int k=j;k<len;k++) if (arr[k].u<arr[j].u){ Num temp = arr[k]; arr[k] = arr[j]; arr[j] = temp; } c[i] = calcS(arr); /* i- */ } return c; } public int getBest(double[] C){} // private double[] getX(){ /* X D*/ double[] temp = new double[Variables.SIZE_OF_D()]; for (int i=0;i<temp.length;i++) temp[i]=Variables.STEP_OF_D()*i; return temp; } private double calcS(num[] arr){ /* */ int size = arr.length; double[] x = new double[size]; double[] u = new double[size]; for (int i=0;i<size;i++){ /* */ x[i]=arr[i].x; u[i]=arr[i].u; } double max = findMax(u); /* */ double s = 0.0; double[] m = new double[size]; double[] lbd = new double[size]; for (int i=0;i<size;i++){ /* */ if (i==0){ lbd[i]=u[0]; m[i]=calcM(x,0); } else{ lbd[i] = u[i]-u[i-1]; m[i] = calcM(x,i); } } for (int i=0;i<size;i++) /* */ s+=(double)lbd[i]*m[i]; return (double)s/max; // } private double findMax(double[] arr){} /* */ private double calcM(double[] x, int first){ /* */ double s = 0.0; for (int i=first;i<x.length;i++) s+=x[i]; return (double)s/(x.length-first); } }
前述の使用例はこの部分には当てはまらないため、説明を改める必要があります。 3番目の記事では、説明付きの本の例、コードと著者の計算の比較、および関数とルールの記述について説明します。
このアルゴリズムの便利なテストのために、すぐにGUIとアダプターを作成しました。これにより、一連のルールと関数をコードに縫い付けるのではなく、外部からロードできます(クラスローダーも個別にロードする必要がありました)。記事の一部は、デスクトップバージョンでのリンクになります。 ソースが含まれています。
ファジー推論ルールを使用した選択肢の多基準選択。 Java実装。 パート3/3:例