Autor Zpráva
php
Profil
Zajímá mně, jestli se dá v PHP použít, když jo tak jestli ste se s ní už někdy setkaly v PHP a v jaké podobě, případně, jestli neexistuje nějaká knihova pro PHP na Fuzzy logiku, protože by se sní dal zjednodušit, v některých případech, skript. Když uvedu příklad tak je to něco takového:

Mám několik bedýnek ovoce s určitým počtem kusů ovoce, a chtěl bych vybrat všechny bedýnky ve kterých je střední počet kusů ovoce.
//klasický skript:
$bedynky = array("b1" => 24, "b2" => 25, "b3" => 30, "b4" => 35, "b5" => 50);
foreach($bedynky as $bedna => $kusu_ovoce ){
  if ( $kusu_ovoce >= 25 && $kusu_ovoce <= 35 ){
    /*výstupem mi sou tedy bedýnky b2, b3 a b4 a tady teda nastává problém, proč by nemohla být bedýnka b1,
       která obsahuje 24 kusů ovoce, taky zařazena mezi ty střední, takže problém je v určení hraničních bodů
    */
  }
}

//fuzzy skript:
foreach($bedynky as $bedna = $kusu_ovoce){
  if ( $kusu_ovoce == middle ){
    /*výstupem mi jsou bedýnky, podle stupně příslušnosti, který vyjadřuje míru příslušnosti prvku do fuzzy množiny.
       Něco jako kdybych každý bedýnce přiřadil skóre z intervalu <0,1>, přičemš čím blíž by se skóre blížilo k 1,
       tím je větší šance, že daná bedýnka taky patří mezi ty střední. Takže vlastně jediný co musím stanovit je hodnota,
       kdy požadujeme bedýnku za střední, v našem případě to je, když bedýnka obsahuje 30 kusů ovoce.
    */
  }
}
Joker
Profil
php:
jestli se dá v PHP použít, když jo tak jestli ste se s ní už někdy setkaly v PHP a v jaké podobě
Programátorek sem moc nechodí, dovolím si předpokládat, že setkaly je chyba a výrok platí i pro muže :-)

V uvedeném příkladu první skript bedýnku b1 vybere, protože 24 je větší než 10 a zároveň menší než 35.
Jinak za tím ale není žádná „magie“, prostě potřebuji:
1. Nějaký etalon, „ideálně prostřední bedýnku“. V příkladu to je 30, není řečeno kde se to číslo vzalo, ale asi to je medián vstupních hodnot.
Ten se zjistí snadno, přesně podle definice mediánu (hodnota která je v seznamu hodnot seřazených podle velikosti přesně uprostřed): Pole se seřadí podle velikosti a vezme se prostřední hodnota (velikost pole / 2)
2. Teď by šlo říct, že střední jsou etalon ± nějaký počet kusů a je to. Ale když budu „fuzzy“, určíme relativní odchylku od etalonu. K tomu potřebujeme ještě rozpětí vstupních hodnot. Z předchozího kroku je pole seřazené podle velikosti, takže triviální: poslední hodnota mínus první hodnota.
Relativní odchylka od střední hodnoty pak je: abs(<etalon> - <hodnota>) / <rozsah>
V uvedeném příkladu tedy relativní odchylky budou přibližně: 0,23; 0,19; 0; 0,19; 0,76
3. No a pak potřebujeme vědět míru tolerance, to musí být zadáno.

Všechno to jsou relativně jednoduché operace, na co nějaká knihovna?
php
Profil
Asi to neumím dostatečně (vůbec) vysvětlit, zkuste si přečíst tohle:
http://cs.wikipedia.org/wiki/Fuzzy_logika
http://en.wikipedia.org/wiki/Fuzzy_logic?oldid=166423699
http://www.rydval.cz/phprs/view.php?cisloclanku=2005061701
1) tu 10 sem opravil ještě když tu nebyl ani jeden komentář k tomu...
2) k tomu tvímu příkladu: furt potřebuju zapsat podmínku jako
if($x >= xy && $x <= yx ) //což neřeší problém hraničníh bodů
//a nemůžu použít
if($x == middle ) 

3) těch 30 se tam vzalo tak, že bedýnku, která obsahuje 30 kusů ovoce, považuju v příkladu za střední a nikoliv tak že by to byl medián vstupních hodnot
Joker
Profil
php:
Četl jsem.
Pořád si myslím, že tak jak jsem to popsal to bude fungovat.

2) k tomu tvímu příkladu: furt potřebuju zapsat podmínku
Právěže to nebude if((hodnota > něco) && (hodnota < něco)), ale if(odchylka < tolerance)

ad 3), v tom případě těch 30 je prostě další vstup.

Zkusím příklad:

//vstupy (pozn. neuvažuje se počet kusů < 0):
$bedynky = array("b1" => 24, "b2" => 25, "b3" => 30, "b4" => 35, "b5" => 50); 
$etalon = 30; // kolik považuji za střední počet
$tolerance = 0.2; // s jakou tolerancí
// Algoritmus:
sort($bedynky); // setřídění, pokud $bedynky vždycky bude setříděné, není potřeba
$rozsah = $bedynky[count($bedynky) - 1] - $bedynky[0]; // rozsah hodnot
foreach($bedynky as $bedna = $kusu)
{ 
  if((abs($etalon - $kusu) / $rozsah) < $tolerance)
  {
    // je to střední bedýnka
  }
}


Dodatek: Jen to nesplňuje to, aby se hodnocení blízko u etalonu měnilo pomaleji než daleko, tzn. aby např. změna o 1 kus blízko u etalonu vyvolala menší změnu hodnocení, než daleko od etalonu.
Kdyby se ale použila třeba druhá mocnina odchylky, splňovalo by to i tohle.

Vaše odpověď

Mohlo by se hodit


Prosím používejte diakritiku a interpunkci.

Ochrana proti spamu. Napište prosím číslo dvě-sta čtyřicet-sedm:

0