# -*- coding: UTF-8 -*- import sys from math import * from random import * import numpy as np ############################ # クラスFuzzyの定義 # coded by Y.Suganuma ############################ class Fuzzy : ##################################### # コンストラクタ # name : 入力データファイル名 ##################################### def __init__(self, name) : in_f = open(name, "r") # 基本データの入力 s = in_f.readline().split() self.method = int(s[1]) # 推論方法 # =0 : and,or # =1 : *,or # =2 : *,+ self.n_rule = int(s[3]) # 規則の数 self.n_val = int(s[5]) # 変数の数 self.bun = int(s[7]) # 積分の分割数 # 領域の確保 self.omega = np.empty(self.n_rule, np.float) # ωの値 self.rule = np.empty((self.n_rule, self.n_val), np.int) # [i][j] =0 : i番目の規則はj番目の変数を使用しない # =1 : i番目の規則はj番目の変数を使用する self.right = np.empty((self.n_rule, 2), np.float) # [i][0] : 中心 # [i][1] : 幅 self.left = np.empty((self.n_rule, self.n_rule, 2), np.float) # [i][j][0] : 中心 # [i][j][1] : 幅 # 規則データの入力 for i1 in range(0, self.n_rule) : in_f.readline() # 左辺 for i2 in range(0, self.n_val) : s = in_f.readline().split() self.rule[i1][i2] = int(s[1]) if self.rule[i1][i2] > 0 : self.left[i1][i2][0] = float(s[3]) self.left[i1][i2][1] = float(s[4]) # 右辺 s = in_f.readline().split() self.right[i1][0] = float(s[1]) self.right[i1][1] = float(s[2]) in_f.close() ########################################### # 交点の計算 # x : x # c : 中心 # h : 幅 # r : <0 : 左辺のメンバーシップ関数 # >=0 : 右辺(ω) # return : 交点 ########################################### def Cross(self, x, c, h, r) : if x < c : x1 = c - h x2 = c y1 = 0.0 if r < 0.0 or (r >= 0.0 and self.method == 0) : y2 = 1.0 else : y2 = r else : x1 = c x2 = c + h if r < 0.0 or (r >= 0.0 and self.method == 0) : y1 = 1.0 else : y1 = r y2 = 0.0 y = y1 + (y2 - y1) * (x - x1) / (x2 - x1) if y < 0.0 : y = 0.0 else : if r >= 0.0 and self.method == 0 and y > r : y = r return y ############################################## # 右辺の計算 # x : 値 # om[i] : <0 : i番目の規則を使用しない # >=0 : ωの値 # return : xにおける右辺の値 ############################################## def Height(self, x, om) : y = 0.0 sw = 0 for i1 in range(0, self.n_rule) : if om[i1] >= 0.0 : y1 = self.Cross(x, self.right[i1][0], self.right[i1][1], om[i1]) if sw == 0 : y = y1 sw = 1 else : if self.method < 2 : if y1 > y : y = y1 else : y += y1 return y ########################## # 推論の実行 # x[i] : 各変数の値 # return : 推論値 ########################## def Inf(self, x) : # ωの計算 for i1 in range(0, self.n_rule) : self.omega[i1] = -1.0 for i2 in range(0, self.n_val) : if self.rule[i1][i2] > 0 : if x[i2] > self.left[i1][i2][0]-self.left[i1][i2][1] and x[i2] < self.left[i1][i2][0]+self.left[i1][i2][1] : x1 = self.Cross(x[i2], self.left[i1][i2][0], self.left[i1][i2][1], -1.0) else : x1 = 0.0 if self.omega[i1] < 0.0 : self.omega[i1] = x1 else : if self.method == 0 : if x1 < self.omega[i1] : self.omega[i1] = x1 else : self.omega[i1] *= x1 # 右辺の計算 y = self.Result(self.omega) return y ############################################## # 右辺による推論 # om[i] : <0 : i番目の規則を使用しない # >=0 : ωの値 # return : 推論値 ############################################## def Result(self, om) : max = 0.0 min = 0.0 y = 0.0 sw = 0 # 積分範囲と積分幅の計算 for i1 in range(0, self.n_rule) : if om[i1] >= 0.0 : x1 = self.right[i1][0] - self.right[i1][1] x2 = self.right[i1][0] + self.right[i1][1] if sw == 0 : min = x1 max = x2 sw = 1 else : if x1 < min : min = x1 if x2 > max : max = x2 h = (max - min) / self.bun if h < 1.0e-15 : print("***error invalid data (h = 0) ***") # 積分(重心の計算,台形則) z1 = self.Height(min, om) z2 = self.Height(max, om) y1 = 0.5 * (min * z1 + max * z2) y2 = 0.5 * (z1 + z2) x1 = min for i1 in range(0, self.bun-1) : x1 += h z1 = self.Height(x1, om) y1 += x1 * z1 y2 += z1 y1 *= h y2 *= h if abs(y2) > 1.0e-10 : y = y1 / y2 else : print("***error invalid data (y2 = 0) ***") return y ---------------------------------- # -*- coding: UTF-8 -*- import numpy as np import sys from math import * from random import * from function import Fuzzy ############################ # ファジイ推論 # coded by Y.Suganuma ############################ if len(sys.argv) == 4 : # オブジェクトの生成 fz = Fuzzy(sys.argv[1]) # 推論データの読み込み in_f = open(sys.argv[2], "r") s = in_f.readline().split() n_val = int(s[1]) n_d = int(s[3]) x = np.empty(n_val, np.float) xx = np.empty((n_val, n_d), np.float) for i1 in range(0, n_val) : s = in_f.readline().split() for i2 in range(0, n_d) : xx[i1][i2] = float(s[i2+1]) in_f.close() # 推論とその結果の出力 out = open(sys.argv[3], "w") for i1 in range(0, n_d) : for i2 in range(0, n_val) : x[i2] = xx[i2][i1] out.write(str(x[i2]) + " ") y = fz.Inf(x) # 推論 out.write(str(y) + "\n") out.close() else : print("***error 入力データファイル名を指定して下さい") ------------------------規則ファイル-------------- 推論方法 0 規則の数 3 変数の数 1 積分の分割数 100 規則1 変数1 1 中心と幅 1.0 1.0 右辺(中心と幅) 1.0 15.0 規則2 変数1 1 中心と幅 2.0 1.0 右辺(中心と幅) 11.0 15.0 規則3 変数1 1 中心と幅 3.0 1.0 右辺(中心と幅) 21.0 15.0 ------------------------推論ファイル-------------- 変数の数 1 データ数 21 変数1 1.0 1.1 1.2 1.3 1.4 1.5 1.6 1.7 1.8 1.9 2.0 2.1 2.2 2.3 2.4 2.5 2.6 2.7 2.8 2.9 3.0