Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Общие вопросы > Аккумуляция в нечеткой логике


Автор: hazamov 3.12.2009, 23:21
Здравствуйте. Прочел статью  "нечеткая логика в МВТУ" (http://reactors.ru/mvtu/mbtu_lab/FL/fuzzy_logic.htm). 
Подробно объясняется процедура активизации и аккумуляции, и создается блок, в котором обе эти процедуры осуществлены. Блок программируется

Код

function AccProb( x)
{    
    AccProb=action[1]*TriangleFM(x, a[0],b[0],c[0]);
    for ( i=2,N)
    {
        AccProb=MAX(AccProb,action[i]* TriangleFM(x, a[i],b[i],c[i]);
    }
}


А что за параметр x? 

Автор: MAKCim 4.12.2009, 09:37
по-моему, это не совсем с++ ;)

Автор: 17dufa 4.12.2009, 13:17
hazamov, x - это конкретное значение из интервала возможных значений выходной переменной.
то есть если выходная переменная принимает значения от MIN до MAX, используя функцию AccProb можно построить аккумулированный график "степени истинности" для каждого конкретного значения от MIN до MAX. 
*затем проводится дефазификация, например, у этой фигуры вычисляется центр масс и получается конкретное значение выходной переменной.

Автор: hazamov 4.12.2009, 18:14
ok, спасибо  17dufa.  Значит х в процедуре должен меняться от MIN до MAX?  Процедура AccProb соответствует операции,отмеченной коричневыми стрелками на прикрепленном рисунке, да? 

Автор: 17dufa 7.12.2009, 14:52
hazamov, на картинках приведен другой способ активизации. 
На картинках функция принадлежности B1 "обрубается" в соответствии с степенью истинности правила (A11 & A12 => B1). В приведенной Вами методичке используется другой метод: вся функция принадлежности B1 умножается на степень истинности правила (A11 & A12 => B1), то есть как бы опускается:
Допустим степень истинности правила равна 0.5, а функция принадлежности B1 равна 0, для X меньше 0.5, (X-0.5)*2 для X от 0,5 до 1, (1.5-X)*2 для X от 1 до 1.5, 0 для X больше 1.5 (треугольный горб вокруг 1). 
По правилу из рисунков результатом будет: 0, для X меньше 0, (X-0.5)*2 для X от 0.5 до 0.75, 0.5 для X от 0.75 до 1.25, (1.5-X)*2 для X от 1.25 до 1.5, 0 для X больше 1.5 (треугольному горбу сам горб срезали горизонтальной линией MF = 0.5)
А по методе после корректировки функции принадлежности в соответствии с степенью истинности правила, получим: 0 для X меньше 0.5, X-0.5 для X от 0.5 до 1, 1.5-X для X от 1 до 1.5, 0 для X больше 1.5 (тоже треугольный горб вокруг 1, но более пологий, максимум уменьшился с 1 до 0.5).
Советую эти 2 долгих объяснения нарисовать на бумаге, станет понятнее.

кроме того, степень истинности правила для операции && определяется по-разному:
в картинках - минимумом из 2 значений, 
в методе степень истинности правила равна произведению степеней принадлежности аргументов.

Функция делает 2 операции сразу: и отмеченные стрелками и суммирование графиков для формирования итоговой картинки справа внизу. Центра масс функция не вычисляет.

Автор: hazamov 10.12.2009, 09:21
Спасибо, 17dufa  За подробное объяснение. 
Различие между двумя методами понял. 


Но если перейти конкретно к функции AccProb( x).

Цитата

По правилу из рисунков результатом будет: 0, для X меньше 0, (X-0.5)*2 для X от 0.5 до 0.75, 0.5 для X от 0.75 до 1.25, (1.5-X)*2 для X от 1.25 до 1.5, 0 для X больше 1.5 (треугольному горбу сам горб срезали горизонтальной линией MF = 0.5)
 - как формируется выходная треугольная функция принадлежности B1 понятно.

А откуда берется значение Х ?  Это ведь конкретное значение из универсума,которое является базой для нечеткого множества B1. 
А конкретного значение мы вроде получаем только после вычисления центра масс. Не так?

Автор: 17dufa 10.12.2009, 13:07
hazamov, перебираются все значения, как бы строится итоговый график, который на рисунке справа внизу. То есть Функция AccProb позволяет для любого значения x получить значение этого итогового графика. Понять функцию AccProb оторвано сложно, лучше совместно с функцией дефазификации (вычисление центра масс):
Код

function ResultB()
{
   ResultB = 0;
   commonWeight = 0;
   stepLength = (MAX_B - MIN_B) / STEP_COUNT;
   for ( i=0,STEP_COUNT-1) //STEP_COUNT - на сколько частей мы разбиваем отрезок [MIN_B, MAX_B]
   {
       x = MIN_B + i * stepLength + 0.5 * stepLength; //середина i-ой части
       currentWeight = AccProb(x) * stepLength; /*получить значение итогового графика для значения x и 
умножить на величину шага для получения "массы", соответсвующей x*/
       ResultB += x * currentWeight;
       commonWeight += currentWeight;
   }
   ResultB /= commonWeight;
}

с функцией AccProb действительно не все в порядке: во-первых, она выполняет 2 действия (активация и аккумуляция); во-вторых, ее нельзя рассматривать отдельно от результирующей функции, которая использует AccProb.

*что-то у меня сомнения по поводу, не забыл ли я, как правильно считать центр масс. в частности чисто математически stepLength получается лишним, так как в дроби, описывающей ResultB он и в числителе и в знаменателе выносится за скобки и сокращается.

Автор: hazamov 10.12.2009, 19:39
Теперь всё понятно smile Спасибо большое!

А в материале по той же ссылке даётся деффазификация:
Код

float defuzzy()
{
    float cm=0, m=0.0000000001;
    L=AccProb(MinX);
    float dX=(MinX-MaxX)/IntCount;
    for (int i=MinX; i<Max; i+=dX)
    {
        R=AccProb(i+dX);
        cm=cm+dX*((i*L)+(i+dX)*R)/2;
        m=m+dX*(L+R)/2;
        L=R;
    }
    return cm/m;
}


Но то,что вы показали намного проще)

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)