کلیدستان

نسخه‌ی کامل: تعیین قانون ترکیبی and o or با ابزار گرافیکی فازی
شما در حال مشاهده نسخه آرشیو هستید. برای مشاهده نسخه کامل کلیک کنید.
سلام عرض می کنم
این قانون رو چه طور میشه با
ابزار گرافیکی فازی در متلب تعیین کرد؟
if x=very low and (y= low or y =middle or y=high) then out=middle
یعنی ترکیب and o or dar yek ghanoon
نمی خوام در قالب دو قانون مجزا این کار رو انجام بدم-حتی الامکان می خوام ساده سازی بشه چون تعداد قانون هام زیاده
ممنون می شم اگه زود تر من رو کمک کنید...با تشکر
سلام .
ابتدا هر حالت را به یک عدد تبدیل می کنیم :
مقدار خیلی کم ارزش را با عدد 1 ، کم ارزش با 2 ، متوسط با 3 و با ارزش را با 4 نمایش می دهیم .

کدهای متلب به صورت زیر می باشند :

کد:
clear all
close all
clc

% 1--> very low value  2--> low value  3--> middle  4--> high value

output_values=cellstr(['very low ';'low      ';'middle   ';'high     ']);

output=0;
x=1;
y=3;
if (x==1 && (y==2 | y==3 | y==4))
    output=3;
end
output
output=output_values(output)

مقادیر x و y را به دلخواه تغییر بدید و نتیجه رو ببینید .
در واقع در همان عبارتی که نوشته بودید ، تنها علامت های مربوط به and و or را قرار داده ام . علامت | به عنوان or و علامت && به عنوان and به کار رفته است .
اما این جا یک نکته ای هست
قراره قوانین فازی واسه یک FIS نوشته شه
یعنی حالت عادی ما قوانین رو این شکلی می نویسم برای مثال با دو ورودی و یک خروجی به شکل ماتریس
1 : (1) 3 1- 2
که بیانگر
if x=middle and not y then out=high va vazn erule=1 va sotone akhar ham male amalgare AND has
یا مثلا این طوری می نویسسم که:

ruleList=[ ...
5 5, 5 1 1;
4 5, 5 1 1;
1 1, 1 1 1;
3 3, 3 1 1];
a =addrule(a,ruleList);
writefis(a, 'tipp.fis');

تکه کد شما واسه این مبحث قواینن اخه چه طوری من می تونم استفاده کنم؟؟
اون وقت اگه من به فرم کد بالا بنویسم چه طور باز معادل دستور زیر را کد نویسی کنم؟/
addrule رو ینویسم؟؟
در صورت امکان میشه بیشتر راهنمایی کنید؟ ممنون
بله حق با شماست .
من نگاهی به مثال های خود نرم افزار متلب انداختم ، شیوه تعریف rule در آنها یکسان و به صورت همان 5 عدد متوالی است . بنابراین بعید می دونم بتونید با یک قانون بنویسید .
با 3 قانون که به صورت زیر میشه :

کد:
ruleList=[ ...
1 2, 3 1 1;
1 3, 3 1 1;
1 4, 3 1 1];

که البته خودتون گفتید که می خواهید حتما یک قانون باشه .
خوب شاید بشه یک کارهایی قبل از دادن ورودی انجام داد Idea . مثلا فرض کنید ورودی دوم (y) بتونه 20 حالت داشته باشه (زیاد گفتم تا سودمندی روش پیشنهادی رو درک کنید) . حالا می خواهیم نتیجه and شدن x با 12 حالت y برابر یک خروجی و نتیجه and شدن x با 8 حالت از y برابر یک خروجی دیگر باشد . به جای اینکه بیاییم و برای هر حالت ، قانون هایی را بنویسیم ، ورودی y را تبدیل به یک ورودی دیگر می کنیم (مثلا با نام z) . به این صورت که z می تواند دو مقدار 1 و 2 داشته باشد که مقدار 1 از or شدن تمامی 12 حالت اول و مقدار 2 از or شدن تمامی 8 حالت دوم حاصل می شود . سپس قوانین منطق فازی را برای دو ورودی x و z خواهیم نوشت که تنها دو قانون نیاز دارد . دقت کنید که عملیاتی که گفتم بر روی y انجام می دهیم ، کاملا قبل از اعمال منطق فازی است و در واقع یک تبدیل متغیر می باشد . کد or رو هم که برای 12 یا 8 حالت به راحتی می توانید در یک خط بنویسید .
البته باید خودتون اجراش کنید و ببینید اون چیزی که خواستید هست یا نه .
امیدوارم مفید بوده باشه . Smile
با سلام و تشکر به خاطر ایده و راهنمایی که کردید...
یک سوال دیگر هم به وجود آمده در همین راستا:
با انجام کمی مطالعات بیشتر و خوندن دستور parsrule شاید امکان پذیر باشع نوشتن قانون هام بدین صورت که:
Syntax

fis2 = parsrule(fis,txtRuleList)
This function parses the text that defines the rules (txtRuleList) for a MATLAB workspace FIS variable, fis, and returns a FIS structure with the appropriate rule list in place. If the original input FIS structure, fis, has any rules initially, they are replaced in the new structure, fis2.

The key language words in English are if, then, is, AND, OR, and NOT
مثال خود متلب:
a = readfis('tipper');
ruleTxt = 'if service is poor then tip is generous';
a2 = parsrule(a,ruleTxt,'verbose');
showrule(a2)
ans =
1. If (service is poor) then (tip is generous) (1)
اما اینجا مجددا سوالی برای من وجود اومده
که من اگر بخوام از طریق همین دستور همزمان چندین قانون رو در ruleTxt تعریف کنم و با parserule به متغیر فازی ام اضافه کنم چه طوری باید تعریف کنم قوانین رو؟
متشکرم

البته خودم فکر می کنم باید ماتریسی از رشته ها رو تعریف کرد و سپس این ماتریس رو به عنوان ورودی parserule پاس داد..پس فعلا این قضیه حله اما هنوز مشکلی که باقی می مونه این هست که من هر چی تلاش کردم این قانون مذکور رو به فرم text در همان رشته قرار دهم که قانون برای متغیر FIS در نظر کرفته شود خطا داد
د راین مورد اگر راه حلی دارید لطفا راهنمایی کنید
'ruletxt='if x=very low and y= low or y =middle or y=high then out=middle
a = parsrule(a,ruletxt,'verbose');
چرا از addrule استفاده نمی کنید ؟
طریقه استفاده به این صورته :

کد:
a = addrule(a,ruleList)

که در اون ، ruleList رو می تونید به همون شیوه ای که قبلا گفتید ، تعریف کنید :

کد:
ruleList=[
1 1 1 1 1
1 2 2 1 1];

می دونم منظورتون اینه که می خواهید چند or همزمان داشته باشید ولی آیا اطمینان دارید که دستور parsrule می تواند چندین or را در نظر بگیرد ؟
یک نکته مهم وجود داره و اینه که اگه دستور parsrule میتونه چند or رو در کنار هم در نظر بگیره ، چرا سازندگان نرم افزار متلب این امکان رو برای addrule به وجود نیاوردن که لیست قوانین رو به صورت عدد دریافت میکنه و نوشتن قوانین در اون میتونه خیلی ساده تر از parsrule باشه !
با تشکر و سپاس فراوان
اما این راه حل parsrule بدین خاطر خواستم استفاده کنم چون راحت می شه داخلش نوشت
'ruletxt='if x is low and y is not low then out is middle
yani y maghadire middle ya high ra mitavanad etekhaz konad
خواستم با همون شیوه همون قانون رو واسه حالت خاص که NOT داره که هر ورودی 5 تا تابع عضویت داره در نظر بگیرم اما خطا داد
علت هم فک کنم این باشه چون در کد دستور parserule function
lenght*.Fis)
رو اول حساب می کنه و اون وقت به تعداد ورودی ها ، رو چک می کنه با تعدادی که ما به عنوان "مقدم" در اون رشته به در قانون قرار دادیم
----------
راه حل هایی که تا بدین جا به ذهنم رسیده بود رو تست کردم اما در بیان
'if x=very low and y= low or y =middle or y=high then out=middle
راهی پیدا نکردم ...من که فعلا دیکه ناچارا از همون addrule و استفاده می کنم و ساده سازی هم نمی تونم کنم و محبورم همه حالاتو بنویسم
اما اگه باز هم راهی پیدا کردید ممنون میشم اطلاع بدهید