# -*- 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