Initial commit.
Esse commit está contido em:
@@ -0,0 +1,226 @@
|
||||
/* -----------------------------------------------------------------------
|
||||
|
||||
Blueprint CSS Framework 0.7.1
|
||||
http://blueprintcss.googlecode.com
|
||||
|
||||
* Copyright (c) 2007-2008. See LICENSE for more info.
|
||||
* See README for instructions on how to use Blueprint.
|
||||
* For credits and origins, see AUTHORS.
|
||||
* This is a compressed file. See the sources in the 'src' directory.
|
||||
|
||||
----------------------------------------------------------------------- */
|
||||
|
||||
/* reset.css */
|
||||
html, body, div, span, object, iframe, h1, h2, h3, h4, h5, h6, p, blockquote, pre, a, abbr, acronym, address, code, del, dfn, em, img, q, dl, dt, dd, ol, ul, li, fieldset, form, label, legend, table, caption, tbody, tfoot, thead, tr, th, td {margin:0;padding:0;border:0;font-weight:inherit;font-style:inherit;font-size:100%;font-family:inherit;vertical-align:baseline;}
|
||||
body {line-height:1.5;}
|
||||
table {border-collapse:separate;border-spacing:0;}
|
||||
caption, th, td {text-align:left;font-weight:normal;}
|
||||
table, td, th {vertical-align:middle;}
|
||||
blockquote:before, blockquote:after, q:before, q:after {content:"";}
|
||||
blockquote, q {quotes:"" "";}
|
||||
a img {border:none;}
|
||||
|
||||
/* typography.css */
|
||||
body {font-size:75%;color:#222;background:#fff;font-family:"Helvetica Neue", Helvetica, Arial, sans-serif;}
|
||||
h1, h2, h3, h4, h5, h6 {font-weight:normal;color:#111;}
|
||||
h1 {font-size:3em;line-height:1;margin-bottom:0.5em;}
|
||||
h2 {font-size:2em;margin-bottom:0.75em;}
|
||||
h3 {font-size:1.5em;line-height:1;margin-bottom:1em;}
|
||||
h4 {font-size:1.2em;line-height:1.25;margin-bottom:1.25em;height:1.25em;}
|
||||
h5 {font-size:1em;font-weight:bold;margin-bottom:1.5em;}
|
||||
h6 {font-size:1em;font-weight:bold;}
|
||||
h1 img, h2 img, h3 img, h4 img, h5 img, h6 img {margin:0;}
|
||||
p {margin:0 0 1.5em;}
|
||||
p img {float:left;margin:1.5em 1.5em 1.5em 0;padding:0;}
|
||||
p img.right {float:right;margin:1.5em 0 1.5em 1.5em;}
|
||||
a:focus, a:hover {color:#000;}
|
||||
a {color:#009;text-decoration:underline;}
|
||||
blockquote {margin:1.5em;color:#666;font-style:italic;}
|
||||
strong {font-weight:bold;}
|
||||
em, dfn {font-style:italic;}
|
||||
dfn {font-weight:bold;}
|
||||
sup, sub {line-height:0;}
|
||||
abbr, acronym {border-bottom:1px dotted #666;}
|
||||
address {margin:0 0 1.5em;font-style:italic;}
|
||||
del {color:#666;}
|
||||
pre, code {margin:1.5em 0;white-space:pre;}
|
||||
pre, code, tt {font:1em 'andale mono', 'lucida console', monospace;line-height:1.5;}
|
||||
li ul, li ol {margin:0 1.5em;}
|
||||
ul, ol {margin:0 1.5em 1.5em 1.5em;}
|
||||
ul {list-style-type:disc;}
|
||||
ol {list-style-type:decimal;}
|
||||
dl {margin:0 0 1.5em 0;}
|
||||
dl dt {font-weight:bold;}
|
||||
dd {margin-left:1.5em;}
|
||||
table {margin-bottom:1.4em;width:100%;}
|
||||
th {font-weight:bold;background:#C3D9FF;}
|
||||
th, td {padding:4px 10px 4px 5px;}
|
||||
tr.even td {background:#E5ECF9;}
|
||||
tfoot {font-style:italic;}
|
||||
caption {background:#eee;}
|
||||
.small {font-size:.8em;margin-bottom:1.875em;line-height:1.875em;}
|
||||
.large {font-size:1.2em;line-height:2.5em;margin-bottom:1.25em;}
|
||||
.hide {display:none;}
|
||||
.quiet {color:#666;}
|
||||
.loud {color:#000;}
|
||||
.highlight {background:#ff0;}
|
||||
.added {background:#060;color:#fff;}
|
||||
.removed {background:#900;color:#fff;}
|
||||
.first {margin-left:0;padding-left:0;}
|
||||
.last {margin-right:0;padding-right:0;}
|
||||
.top {margin-top:0;padding-top:0;}
|
||||
.bottom {margin-bottom:0;padding-bottom:0;}
|
||||
|
||||
/* grid.css */
|
||||
.container {width:950px;margin:0 auto;}
|
||||
.showgrid {background:url(src/grid.png);}
|
||||
body {margin:1.5em 0;}
|
||||
div.span-1, div.span-2, div.span-3, div.span-4, div.span-5, div.span-6, div.span-7, div.span-8, div.span-9, div.span-10, div.span-11, div.span-12, div.span-13, div.span-14, div.span-15, div.span-16, div.span-17, div.span-18, div.span-19, div.span-20, div.span-21, div.span-22, div.span-23, div.span-24 {float:left;margin-right:10px;}
|
||||
div.last {margin-right:0;}
|
||||
.span-1 {width:30px;}
|
||||
.span-2 {width:70px;}
|
||||
.span-3 {width:110px;}
|
||||
.span-4 {width:150px;}
|
||||
.span-5 {width:190px;}
|
||||
.span-6 {width:230px;}
|
||||
.span-7 {width:270px;}
|
||||
.span-8 {width:310px;}
|
||||
.span-9 {width:350px;}
|
||||
.span-10 {width:390px;}
|
||||
.span-11 {width:430px;}
|
||||
.span-12 {width:470px;}
|
||||
.span-13 {width:510px;}
|
||||
.span-14 {width:550px;}
|
||||
.span-15 {width:590px;}
|
||||
.span-16 {width:630px;}
|
||||
.span-17 {width:670px;}
|
||||
.span-18 {width:710px;}
|
||||
.span-19 {width:750px;}
|
||||
.span-20 {width:790px;}
|
||||
.span-21 {width:830px;}
|
||||
.span-22 {width:870px;}
|
||||
.span-23 {width:910px;}
|
||||
.span-24, div.span-24 {width:950px;margin:0;}
|
||||
.append-1 {padding-right:40px;}
|
||||
.append-2 {padding-right:80px;}
|
||||
.append-3 {padding-right:120px;}
|
||||
.append-4 {padding-right:160px;}
|
||||
.append-5 {padding-right:200px;}
|
||||
.append-6 {padding-right:240px;}
|
||||
.append-7 {padding-right:280px;}
|
||||
.append-8 {padding-right:320px;}
|
||||
.append-9 {padding-right:360px;}
|
||||
.append-10 {padding-right:400px;}
|
||||
.append-11 {padding-right:440px;}
|
||||
.append-12 {padding-right:480px;}
|
||||
.append-13 {padding-right:520px;}
|
||||
.append-14 {padding-right:560px;}
|
||||
.append-15 {padding-right:600px;}
|
||||
.append-16 {padding-right:640px;}
|
||||
.append-17 {padding-right:680px;}
|
||||
.append-18 {padding-right:720px;}
|
||||
.append-19 {padding-right:760px;}
|
||||
.append-20 {padding-right:800px;}
|
||||
.append-21 {padding-right:840px;}
|
||||
.append-22 {padding-right:880px;}
|
||||
.append-23 {padding-right:920px;}
|
||||
.prepend-1 {padding-left:40px;}
|
||||
.prepend-2 {padding-left:80px;}
|
||||
.prepend-3 {padding-left:120px;}
|
||||
.prepend-4 {padding-left:160px;}
|
||||
.prepend-5 {padding-left:200px;}
|
||||
.prepend-6 {padding-left:240px;}
|
||||
.prepend-7 {padding-left:280px;}
|
||||
.prepend-8 {padding-left:320px;}
|
||||
.prepend-9 {padding-left:360px;}
|
||||
.prepend-10 {padding-left:400px;}
|
||||
.prepend-11 {padding-left:440px;}
|
||||
.prepend-12 {padding-left:480px;}
|
||||
.prepend-13 {padding-left:520px;}
|
||||
.prepend-14 {padding-left:560px;}
|
||||
.prepend-15 {padding-left:600px;}
|
||||
.prepend-16 {padding-left:640px;}
|
||||
.prepend-17 {padding-left:680px;}
|
||||
.prepend-18 {padding-left:720px;}
|
||||
.prepend-19 {padding-left:760px;}
|
||||
.prepend-20 {padding-left:800px;}
|
||||
.prepend-21 {padding-left:840px;}
|
||||
.prepend-22 {padding-left:880px;}
|
||||
.prepend-23 {padding-left:920px;}
|
||||
div.border {padding-right:4px;margin-right:5px;border-right:1px solid #eee;}
|
||||
div.colborder {padding-right:24px;margin-right:25px;border-right:1px solid #eee;}
|
||||
.pull-1 {margin-left:-40px;}
|
||||
.pull-2 {margin-left:-80px;}
|
||||
.pull-3 {margin-left:-120px;}
|
||||
.pull-4 {margin-left:-160px;}
|
||||
.pull-5 {margin-left:-200px;}
|
||||
.pull-6 {margin-left:-240px;}
|
||||
.pull-7 {margin-left:-280px;}
|
||||
.pull-8 {margin-left:-320px;}
|
||||
.pull-9 {margin-left:-360px;}
|
||||
.pull-10 {margin-left:-400px;}
|
||||
.pull-11 {margin-left:-440px;}
|
||||
.pull-12 {margin-left:-480px;}
|
||||
.pull-13 {margin-left:-520px;}
|
||||
.pull-14 {margin-left:-560px;}
|
||||
.pull-15 {margin-left:-600px;}
|
||||
.pull-16 {margin-left:-640px;}
|
||||
.pull-17 {margin-left:-680px;}
|
||||
.pull-18 {margin-left:-720px;}
|
||||
.pull-19 {margin-left:-760px;}
|
||||
.pull-20 {margin-left:-800px;}
|
||||
.pull-21 {margin-left:-840px;}
|
||||
.pull-22 {margin-left:-880px;}
|
||||
.pull-23 {margin-left:-920px;}
|
||||
.pull-24 {margin-left:-960px;}
|
||||
.pull-1, .pull-2, .pull-3, .pull-4, .pull-5, .pull-6, .pull-7, .pull-8, .pull-9, .pull-10, .pull-11, .pull-12, .pull-13, .pull-14, .pull-15, .pull-16, .pull-17, .pull-18, .pull-19, .pull-20, .pull-21, .pull-22, .pull-23, .pull-24 {float:left;position:relative;}
|
||||
.push-1 {margin:0 -40px 1.5em 40px;}
|
||||
.push-2 {margin:0 -80px 1.5em 80px;}
|
||||
.push-3 {margin:0 -120px 1.5em 120px;}
|
||||
.push-4 {margin:0 -160px 1.5em 160px;}
|
||||
.push-5 {margin:0 -200px 1.5em 200px;}
|
||||
.push-6 {margin:0 -240px 1.5em 240px;}
|
||||
.push-7 {margin:0 -280px 1.5em 280px;}
|
||||
.push-8 {margin:0 -320px 1.5em 320px;}
|
||||
.push-9 {margin:0 -360px 1.5em 360px;}
|
||||
.push-10 {margin:0 -400px 1.5em 400px;}
|
||||
.push-11 {margin:0 -440px 1.5em 440px;}
|
||||
.push-12 {margin:0 -480px 1.5em 480px;}
|
||||
.push-13 {margin:0 -520px 1.5em 520px;}
|
||||
.push-14 {margin:0 -560px 1.5em 560px;}
|
||||
.push-15 {margin:0 -600px 1.5em 600px;}
|
||||
.push-16 {margin:0 -640px 1.5em 640px;}
|
||||
.push-17 {margin:0 -680px 1.5em 680px;}
|
||||
.push-18 {margin:0 -720px 1.5em 720px;}
|
||||
.push-19 {margin:0 -760px 1.5em 760px;}
|
||||
.push-20 {margin:0 -800px 1.5em 800px;}
|
||||
.push-21 {margin:0 -840px 1.5em 840px;}
|
||||
.push-22 {margin:0 -880px 1.5em 880px;}
|
||||
.push-23 {margin:0 -920px 1.5em 920px;}
|
||||
.push-24 {margin:0 -960px 1.5em 960px;}
|
||||
.push-1, .push-2, .push-3, .push-4, .push-5, .push-6, .push-7, .push-8, .push-9, .push-10, .push-11, .push-12, .push-13, .push-14, .push-15, .push-16, .push-17, .push-18, .push-19, .push-20, .push-21, .push-22, .push-23, .push-24 {float:right;position:relative;}
|
||||
.box {padding:1.5em;margin-bottom:1.5em;background:#E5ECF9;}
|
||||
hr {background:#ddd;color:#ddd;clear:both;float:none;width:100%;height:.1em;margin:0 0 1.45em;border:none;}
|
||||
hr.space {background:#fff;color:#fff;}
|
||||
.clearfix:after, .container:after {content:".";display:block;height:0;clear:both;visibility:hidden;}
|
||||
.clearfix, .container {display:inline-block;}
|
||||
* html .clearfix, * html .container {height:1%;}
|
||||
.clearfix, .container {display:block;}
|
||||
.clear {clear:both;}
|
||||
|
||||
/* forms.css */
|
||||
label {font-weight:bold;}
|
||||
fieldset {padding:1.4em;margin:0 0 1.5em 0;border:1px solid #ccc;}
|
||||
legend {font-weight:bold;font-size:1.2em;}
|
||||
input.text, input.title, textarea, select {margin:0.5em 0;border:1px solid #bbb;}
|
||||
input.text:focus, input.title:focus, textarea:focus, select:focus {border:1px solid #666;}
|
||||
input.text, input.title {width:300px;padding:5px;}
|
||||
input.title {font-size:1.5em;}
|
||||
textarea {width:390px;height:250px;padding:5px;}
|
||||
.error, .notice, .success {padding:.8em;margin-bottom:1em;border:2px solid #ddd;}
|
||||
.error {background:#FBE3E4;color:#8a1f11;border-color:#FBC2C4;}
|
||||
.notice {background:#FFF6BF;color:#514721;border-color:#FFD324;}
|
||||
.success {background:#E6EFC2;color:#264409;border-color:#C6D880;}
|
||||
.error a {color:#8a1f11;}
|
||||
.notice a {color:#514721;}
|
||||
.success a {color:#264409;}
|
||||
@@ -0,0 +1,54 @@
|
||||
<?php
|
||||
/**
|
||||
* Implemen fuzzy logic for PAM without using MatLab
|
||||
* Example data:
|
||||
* [System]
|
||||
* Name='Method1'
|
||||
* Type='mamdani'
|
||||
* Version=2.0
|
||||
* NumInputs=7
|
||||
* NumOutputs=1
|
||||
* NumRules=165
|
||||
* AndMethod='min'
|
||||
* OrMethod='max'
|
||||
* ImpMethod='min'
|
||||
* AggMethod='max'
|
||||
* DefuzzMethod='centroid'
|
||||
*
|
||||
*/
|
||||
|
||||
require_once ('../fuzzy_logic.php');
|
||||
$impendance = 0;
|
||||
$pam_fuzzy = new PAM_Fuzzy_Logic();
|
||||
|
||||
|
||||
// iJab 2013/01/23: Input real data to calculate
|
||||
$input_params = isset($_GET['input_params']) ? $_GET['input_params'] : "1.191000000,2,0,3,0.122563,0.134468,0.224211";
|
||||
$inputs_v = explode(",", $input_params);
|
||||
|
||||
$impendance = $pam_fuzzy->cal_fuzzy($inputs_v);
|
||||
|
||||
?>
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
|
||||
"http://www.w3.org/TR/html4/strict.dtd">
|
||||
<html>
|
||||
<head>
|
||||
<title>Calculate PAM Impendance</title>
|
||||
<link href="css/screen.css" rel="stylesheet" type="text/css"/>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<div class="container">
|
||||
<h2 align="center">Calculate PAM Impendance</h2>
|
||||
<div class="span-16 prepend-4 append-4 last">
|
||||
<form>
|
||||
<label for="project_funding">Input params</>
|
||||
<input type="text" id="input_params" name="input_params" value="<?php echo $input_params;?>" /><br />
|
||||
<input type="submit" name="calculate" value="calculate" />
|
||||
<div style="height:18px;margin:1px;background-color:red;border: 1px solid #000"><?php echo $impendance;?></div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,201 @@
|
||||
<?php
|
||||
require_once ('../fuzzy-logic-class.php');
|
||||
$x = new Fuzzy_Logic();
|
||||
$x->clearMembers();
|
||||
$x->SetInputNames(array('project_funding','project_staffing'));
|
||||
$x->addMember($x->getInputName(0),'inadequate', 0, 20, 40 ,LINFINITY);
|
||||
$x->addMember($x->getInputName(0),'marginal' , 20, 50, 80 ,TRIANGLE);
|
||||
$x->addMember($x->getInputName(0),'adequate' , 60, 80, 100,RINFINITY);
|
||||
$x->addMember($x->getInputName(1),'small', 0, 30, 70,LINFINITY);
|
||||
$x->addMember($x->getInputName(1),'large',30, 70,100,RINFINITY);
|
||||
$x->SetOutputNames(array('risk'));
|
||||
$x->addMember($x->getOutputName(0),'low',0, 20 ,40 ,LINFINITY);
|
||||
$x->addMember($x->getOutputName(0),'normal',20, 50 ,80 ,TRIANGLE);
|
||||
$x->addMember($x->getOutputName(0),'high',60, 80 , 100 ,RINFINITY);
|
||||
$x->clearRules();
|
||||
$x->addRule('IF project_funding.adequate OR project_staffing.small THEN risk.low');
|
||||
$x->addRule('IF project_funding.marginal AND project_staffing.large THEN risk.normal');
|
||||
$x->addRule('IF project_funding.inadequate THEN risk.high');
|
||||
|
||||
$project_funding = (isset($_GET['project_funding'])) ? $_GET['project_funding'] : 35;
|
||||
$project_staffing = (isset($_GET['project_staffing'])) ? $_GET['project_staffing'] : 65;
|
||||
|
||||
$x->setRealInput('project_funding', $project_funding );
|
||||
$x->setRealInput('project_staffing' , $project_staffing );
|
||||
$fuzzy_arr = $x->calcFuzzy();
|
||||
$risk = $fuzzy_arr['risk'];
|
||||
$bar_width = 320;
|
||||
?>
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
|
||||
"http://www.w3.org/TR/html4/strict.dtd">
|
||||
<html>
|
||||
<head>
|
||||
<title>Calculate Risk Project</title>
|
||||
<link href="css/screen.css" rel="stylesheet" type="text/css"/>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<div class="container">
|
||||
<h2 align="center">Calculate Risk Project</h2>
|
||||
<div class="span-16 prepend-4 append-4 last">
|
||||
<form>
|
||||
<label for="project_funding">Project funding [0..100%]</>
|
||||
<input type="text" id="project_funding" name="project_funding" value="<?php echo $project_funding;?>" /><br />
|
||||
<label for="project_staffing">Project staffing [0..100%]</>
|
||||
<input type="text" id="project_staffing" name="project_staffing" value="<?php echo $project_staffing;?>" /><br />
|
||||
<input type="submit" name="calculate" value="calculate" />
|
||||
<div style="width: <?php echo $bar_width;?>px;height:22px;border: 1px solid #000;;text-align:center;">
|
||||
<div style="width: <?php echo round($risk*$bar_width/100); ?>px;height:18px;margin:1px;background-color:red;border: 1px solid #000"><?php echo sprintf("%3.1f %%",$risk);?></div>
|
||||
</div>
|
||||
</form>
|
||||
<br />
|
||||
<hr />
|
||||
<br />
|
||||
<h2>Help for use class Fuzzy_Logic</h2>
|
||||
<h3>Create new instance class</h3>
|
||||
<div class="success"><pre> $fuzzy = new Fuzzy_Logic();</pre></div>
|
||||
<h3>Clear all membership</h3>
|
||||
<div class="success"><pre> $fuzzy->clearMembers(); </pre></div>
|
||||
<h3>Build memberships</h3>
|
||||
<div class="box">
|
||||
<p>The linguistic variable "project_funding" in this system can be divided into a range of "states", such as: "inadequate", "marginal", "adequate". Defining the bounds of these states is a bit tricky. An arbitrary threshold might be set to divide "inadequate" from "marginal", but this would result in a discontinuous change when the input value passed over that threshold.(is fuzzy).
|
||||
The way around this is to make the states "fuzzy", that is, allow them to change gradually from one state to the next. You could define the input funding condition states using "membership functions" such as the following:</p>
|
||||
<p>The Fuzzy class are four types of membership functions of states:</p>
|
||||
<h3>memberships shapes defined in Fuzzy_Logic class :</h3>
|
||||
<pre>define ("LINFINITY" , -1 );
|
||||
define ("TRIANGLE" , 0 );
|
||||
define ("RINFINITY" , 1 );
|
||||
define ("TRAPEZOID" , 2 );</pre>
|
||||
<p>shapes this function is defined as points of shapes (in order and named) as: begin,middle,end</p>
|
||||
<ul>
|
||||
<li>LFINITY = Left Ended Trapezoid in example defined as points: 0,20,50</li>
|
||||
<li>TRIANGLE = defined in example as points: 20,50,80</li>
|
||||
<li>RFINITY = Right Ended Trapesoid in example defined as points : 50,80,100</li>
|
||||
<li>TRAPEZOID = may for example be defined as points: 20,array(40,60),80</li>
|
||||
</ul>
|
||||
<div align="center"> <img src="images/trapezoid.jpg" alt="available membership shapes" title="available membership shapes" /> </div>
|
||||
</div>
|
||||
<br />
|
||||
<hr />
|
||||
<br />
|
||||
<h3>add to class all inputs names :</h3>
|
||||
<div class="success"><pre>$fuzzy->SetInputNames(array('project_funding','project_staffing'));</pre></div>
|
||||
<br />
|
||||
<hr />
|
||||
<br />
|
||||
<h3>add members to input named "project_funding":</h3>
|
||||
<div class="success"><pre>$fuzzy->addMember('project_funding','inadequate', 0, 20, 40 ,LINFINITY);
|
||||
$fuzzy->addMember('project_funding','marginal' , 20, 50, 80 ,TRIANGLE);
|
||||
$fuzzy->addMember('project_funding','adequate' , 60, 80, 100,RINFINITY);</pre></div>
|
||||
<div align="center"> <img src="images/project_funding.jpg" alt="project funding membership" title="project_funding" /> </div>
|
||||
<br />
|
||||
<hr />
|
||||
<br />
|
||||
<h3>add members to input named "project_staffing":</h3>
|
||||
<div class="success"><pre>$fuzzy->addMember('project_staffing','small', 0, 30, 70,LINFINITY);
|
||||
$fuzzy->addMember('project_staffing','large',30, 70,100,RINFINITY);</pre></div>
|
||||
<div align="center"> <img src="images/project_staffing.jpg" alt="project staffing membership" title="project_staffing" /> </div>
|
||||
<br />
|
||||
<hr />
|
||||
<br />
|
||||
<h3>add to class all output names :</h3>
|
||||
<div class="success"><pre>$fuzzy->addMember('risk','low',0, 20 ,40 ,LINFINITY);
|
||||
$fuzzy->addMember('risk','normal',20, 50 ,80 ,TRIANGLE);
|
||||
$fuzzy->addMember('risk','high',60, 80 , 100 ,RINFINITY);</pre></div>
|
||||
<div align="center"> <img src="images/risk.jpg" alt="risk" title="risk" /> </div>
|
||||
<br />
|
||||
<hr />
|
||||
<br />
|
||||
<h3>clear all rules :</h3>
|
||||
<div class="success"><pre>$fuzzy->clearRules();</pre></div>
|
||||
<br />
|
||||
<hr />
|
||||
<br />
|
||||
<h3>add all rules :</h3>
|
||||
<div class="success"><pre>$fuzzy->addRule('IF project_funding.adequate OR project_staffing.small THEN risk.low');
|
||||
$fuzzy->addRule('IF project_funding.marginal AND project_staffing.large THEN risk.normal');
|
||||
$fuzzy->addRule('IF project_funding.inadequate THEN risk.high');</pre></div>
|
||||
<div class="box">
|
||||
<h2>Help for rules syntax :</h2>
|
||||
Rules is defined as text command : eg
|
||||
<pre> IF i1.m1 AND i2.n1 AND i3.k1 THEN o1.xx</pre>
|
||||
<p>where IF, AND, OR, NOT, THEN is available instruction words<br />
|
||||
</p>
|
||||
Command syntax (instruction words) :
|
||||
|
||||
<pre>IF, THEN - condition operators
|
||||
IF - always the first word in the command
|
||||
THEN - always precedes the output value pair
|
||||
OR, AND, NOT - logical operations.
|
||||
</pre>
|
||||
Input and output fuzzy fuzzy sets are supplied as a text concatenation:
|
||||
<pre>input_name.meber_name</pre>
|
||||
Separator is a dot character.<br />
|
||||
example:
|
||||
<pre>temperature.cold , dish.good</pre>
|
||||
|
||||
<ul>
|
||||
<li>The default operator is a logical AND operator.</li>
|
||||
<li>If the line there are two different logical operators they must be surrounded by parentheses.</li>
|
||||
<li>The NOT operator must always be surrounded by parenthesis.</li>
|
||||
<li>Not operator ALVAIS HAVE ONE ARGUMENT</li>
|
||||
<li>If the operations in brackets are nested, always calculated from the most nested operations.</li>
|
||||
<li>Operations in the parentheses are performed first.</li>
|
||||
</ul>
|
||||
<h3>Examples of valid commands:</h3>
|
||||
<pre>IF a.b AND c.d THEN x.y
|
||||
IF a.b AND (c.d OR g.h) THEN x.y
|
||||
IF a.b AND (c.d OR (g.h AND i.j)) THEN x.y
|
||||
IF a.b AND c.d AND g.h THEN x.y
|
||||
IF a.b AND (NOT c.d) THEN x.y
|
||||
</pre>
|
||||
<h3>Examples of bad commands:</h3>
|
||||
<pre>IF a.b AND c.d OR g.h THEN x.y
|
||||
IF a.b NOT c.d THEN x.y
|
||||
IF a.b AND c.d OR g.h AND i.j THEN x.y</pre>
|
||||
<h3>Logical calculate order example </h3>
|
||||
<pre>
|
||||
IF a.b AND (c.d OR (e.f AND i.j)) THEN g.h
|
||||
|
||||
order logic calculations :
|
||||
|
||||
1. (e.f AND i.j) = xx
|
||||
2. (c.d OR (xx)) = yy
|
||||
3. a.b AND yy
|
||||
|
||||
</pre>
|
||||
</div>
|
||||
<br />
|
||||
<hr />
|
||||
<br />
|
||||
<h3>set crisp input values to Fuzzy_Class inputs :</h3>
|
||||
<div class="success"><pre>$project_funding = 65;
|
||||
$project_staffing = 35;
|
||||
$fuzzy->setRealInput('project_funding', $project_funding );
|
||||
$fuzzy->setRealInput('project_staffing' , $project_staffing );</pre></div>
|
||||
|
||||
<br />
|
||||
<hr />
|
||||
<br />
|
||||
<h3>calculate Fuzzy Result :</h3>
|
||||
<div class="success"><pre>$fuzzy_output_array = $fuzzy->calcFuzzy();</pre></div>
|
||||
<br />
|
||||
<hr />
|
||||
<br />
|
||||
<div class="box"><p>Result is returned as associated as output names keys array. (eg $fuzzy_output_array)</p>
|
||||
<pre>
|
||||
array (
|
||||
[risk] = 35.6
|
||||
)
|
||||
</pre>
|
||||
</div>
|
||||
<br />
|
||||
<hr />
|
||||
<br />
|
||||
<br />
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,138 @@
|
||||
<?php
|
||||
require_once ('../fuzzy_logic.php');
|
||||
/*--------------------------- start tank demo controll --------*/
|
||||
$x = new Fuzzy_Logic();
|
||||
|
||||
$x->clearMembers();
|
||||
/* ---------- set input members ---------*/
|
||||
$x->setInputNames(array('ERROR','RATE'));
|
||||
|
||||
$x->addMember($x->getInputName(0),'E_NEG',-1 ,-0.9 , 0 ,LINFINITY);
|
||||
$x->addMember($x->getInputName(0),'E_OK' ,-0.1 , 0 , 0.1,TRIANGLE);
|
||||
$x->addMember($x->getInputName(0),'E_POS', 0 , 0.9 , 1 ,RINFINITY);
|
||||
|
||||
$x->addMember($x->GetInputName(1),'R_NEG',-0.10,-0.07 ,0 ,LINFINITY);
|
||||
$x->addMember($x->GetInputName(1),'R_OK', -0.07, 0 ,0.07 ,TRIANGLE);
|
||||
$x->addMember($x->GetInputName(1),'R_POS', 0 , 0.07 ,0.1 ,RINFINITY);
|
||||
|
||||
/* ---------- set output members ---------*/
|
||||
$x->setOutputNames(array('OUT'));
|
||||
|
||||
$x->addMember($x->getOutputName(0),'CF',-1.0, -0.9 ,-0.8 ,TRIANGLE);
|
||||
$x->addMember($x->getOutputName(0),'CS',-0.6, -0.5 ,-0.4 ,TRIANGLE);
|
||||
$x->addMember($x->getOutputName(0),'NC',-0.1, 0.0 , 0.1 ,TRIANGLE);
|
||||
$x->addMember($x->getOutputName(0),'OS', 0.4, 0.5 , 0.6 ,TRIANGLE);
|
||||
$x->addMember($x->getOutputName(0),'OF', 0.8, 0.9 , 1.0 ,TRIANGLE);
|
||||
/* ---------- set rule table ------------ */
|
||||
|
||||
/* ---------- set rule table ------------ */
|
||||
/* ---------- set rule table ------------ */
|
||||
$x->clearRules();
|
||||
|
||||
$x->addRule('IF ERROR.E_NEG THEN OUT.CF');
|
||||
$x->addRule('IF ERROR.E_OK THEN OUT.NC');
|
||||
$x->addRule('IF ERROR.E_POS THEN OUT.OF');
|
||||
$x->addRule('IF ERROR.E_OK AND RATE.R_POS THEN OUT.CS');
|
||||
$x->addRule('IF ERROR.E_OK AND RATE.R_NEG THEN OUT.OS');
|
||||
|
||||
$x->setFuzzyTable(array(
|
||||
// IN(0,0) IN(0,1) OUT(0)
|
||||
// ------ ------- -------
|
||||
array('E_NEG', NULL , 'CF'),
|
||||
array('E_OK' , NULL , 'NC'),
|
||||
array('E_POS', NULL , 'OF'),
|
||||
array('E_OK' , 'R_POS', 'CS'),
|
||||
array('E_OK' , 'R_NEG', 'OS')
|
||||
));
|
||||
|
||||
|
||||
/*------------ Tank parameters----------------*/
|
||||
$Theight = 1.0 ; // tank max level
|
||||
$TEmergencyRange = array(0.1,0.1,0.1,0.1);
|
||||
$Tinit = 0.1 ; // tank init
|
||||
$IitA = 0.1 ;
|
||||
$IitB = 0.1 ;
|
||||
$IitC = 0.1 ;
|
||||
$IitD = 0.1 ;
|
||||
$InputValve = 1.0 ;
|
||||
$Tdemand = 0.7 ; // tank demand level
|
||||
$Toverflow = 0.9 ; // tank overflow signal
|
||||
|
||||
|
||||
/*------------- Valve parameters -------------*/
|
||||
$Tout_stream = 0.03 ; // output stream by time period
|
||||
$Vinp_max = 0.05 ; // max input stream for power valve
|
||||
/*-------------- Initialise ------------------*/
|
||||
$Level = $Tinit;
|
||||
$LastLevel = $Level;
|
||||
$elevel = $Tinit;
|
||||
$erate = 0;
|
||||
$Vinput = 0;
|
||||
$Valve = 0;
|
||||
$Fuzzy = 0;
|
||||
$WaterInput = 0;
|
||||
echo "<pre>\n";
|
||||
echo "This is a simulation of fuzzy-logic controller. The controller controls the desired level of water in the tank.
|
||||
The controller closes the water inlet valve so as to offset the amount of water flowing from the water flowing.
|
||||
Parameters
|
||||
------------
|
||||
Valve adjustment range 0 to 1
|
||||
The amount of water input flowing per unit time: $Vinp_max
|
||||
The amount of water output flowing per unit time: $Tout_stream
|
||||
Startup water level: $Tinit
|
||||
Desired level of water: $Tdemand
|
||||
------------
|
||||
Plot Values:
|
||||
------------
|
||||
L - current level
|
||||
V - the level of the valve opening
|
||||
F - error output controller
|
||||
--------------
|
||||
";
|
||||
/* ----------- Controll Loop ----------------*/
|
||||
for ($i=1;$i<=80;$i++) {
|
||||
//if ($i>40) $Tout_stream = 0.0;
|
||||
|
||||
|
||||
//if ($i>40) $WaterInput = 0;
|
||||
list($erate,$elevel) = getLastErrors($Tdemand,$Level,$LastLevel);
|
||||
|
||||
$x->SetRealInput('ERROR', $elevel );
|
||||
$x->SetRealInput('RATE' , $erate );
|
||||
|
||||
//$fuzzy_arr = $x->calcFuzzyAlt();
|
||||
//
|
||||
//$Fuzzy = $fuzzy_arr[0];
|
||||
$fuzzy_arr = $x->calcFuzzy();
|
||||
|
||||
$Fuzzy = $fuzzy_arr['OUT'];
|
||||
|
||||
//print_r($fuzzy_arr);
|
||||
$LastLevel = $Level;
|
||||
$Level = $Level - $Tout_stream + $WaterInput;
|
||||
list($Valve,$WaterInput) = getValve($Fuzzy,$Valve,$Vinp_max,0,1);
|
||||
|
||||
$dotline = str_repeat('.',100);
|
||||
$dotline[round($Level*99)]='#';
|
||||
echo $dotline,sprintf("L:%1.3f F:%1.3f V:%1.3f",$Level,$Fuzzy,$Valve),"\n";
|
||||
}
|
||||
print_r($x->StateOutput);
|
||||
echo "</pre>\n";
|
||||
|
||||
/*---- required additional function ------------*/
|
||||
function getValve($Fuzzy,$Valve,$inpMax,$lb,$ub) {
|
||||
$xdot = $Valve+$Fuzzy;
|
||||
if ($xdot<=$lb) $Valve = $lb;
|
||||
elseif ($xdot>=$ub) $Valve = $ub;
|
||||
else $Valve=min(max($xdot,$lb),$ub);
|
||||
return array($Valve,$Valve * $inpMax);
|
||||
}
|
||||
|
||||
function getLastErrors($demandLevel,$currentLevel,$lastLevel) {
|
||||
$erate = $currentLevel-$lastLevel;
|
||||
if ($erate < -0.1) $erate =-0.1;
|
||||
if ($erate > 0.1) $erate = 0.1;
|
||||
$elevel = $demandLevel-$currentLevel ;
|
||||
return array($erate,$elevel);
|
||||
}
|
||||
?>
|
||||
@@ -0,0 +1,699 @@
|
||||
<?php
|
||||
error_reporting(5);
|
||||
define ("LINFINITY" , -1 );
|
||||
define ("TRIANGLE" , 0 );
|
||||
define ("RINFINITY" , 1 );
|
||||
define ("TRAPEZOID" , 2 );
|
||||
|
||||
/*---- required additional function ------------*/
|
||||
function getValve($Fuzzy,$Valve,$inpMax,$lb,$ub) {
|
||||
$xdot = $Valve+$Fuzzy;
|
||||
if ($xdot<=$lb) $Valve = $lb;
|
||||
elseif ($xdot>=$ub) $Valve = $ub;
|
||||
else $Valve=min(max($xdot,$lb),$ub);
|
||||
return array($Valve,$Valve * $inpMax);
|
||||
}
|
||||
|
||||
function getLastErrors($demandLevel,$currentLevel,$lastLevel) {
|
||||
$erate = $currentLevel-$lastLevel;
|
||||
if ($erate < -0.1) $erate =-0.1;
|
||||
if ($erate > 0.1) $erate = 0.1;
|
||||
$elevel = $demandLevel-$currentLevel ;
|
||||
return array($erate,$elevel);
|
||||
}
|
||||
|
||||
|
||||
class Member {
|
||||
|
||||
protected
|
||||
$FName, // Member Name
|
||||
$FMiddle, // Middle Member point
|
||||
$FA, // Start Member point
|
||||
$FB, // End member point
|
||||
$FType; // Member type TRIANGLE,LINFINITY,RFINFINITY, TRAPEZOID
|
||||
|
||||
public function __construct($Name=NULL,$start=NULL,$medium=NULL,$stop=NULL,$type=NULL){
|
||||
if($Name == NULL) return;
|
||||
$this->FName = $Name;
|
||||
$this->FMiddle = $medium;
|
||||
$this->FA = $start;
|
||||
$this->FB = $stop;
|
||||
$this->FType = $type;
|
||||
}
|
||||
|
||||
public function __toString(){
|
||||
return "Member\tname: $this->FName,
|
||||
middle: $this->FMiddle,
|
||||
start : $this->FA,
|
||||
fb : $this->FB,
|
||||
type : $this->FType";
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Calculates the ratio of belonging to a set of defined function shape.
|
||||
* $ratio = Fuzzification($pontX);
|
||||
* @param float $poinX
|
||||
* return float
|
||||
*/
|
||||
public function Fuzzification($P=0.0) {
|
||||
|
||||
if (($P<$this->FA) OR ($P>$this->FB)) return 0; //P is out this segment...
|
||||
|
||||
if ($P==$this->FMiddle) return 1;
|
||||
|
||||
if ($this->FType==LINFINITY) {
|
||||
if ($P<=$this->FMiddle) return 1;
|
||||
if (($P>$this->FMiddle) AND ($P<$this->FB)) return ($this->FB-$P)/($this->FB-$this->FMiddle);
|
||||
}
|
||||
|
||||
if ($this->FType==RINFINITY) {
|
||||
if ($P>=$this->FMiddle) return 1;
|
||||
if (($P<$this->FMiddle) AND ($P>$this->FA)) return ($P-$this->FA)/($this->FMiddle-$this->FA);
|
||||
}
|
||||
|
||||
if ($this->FType==TRIANGLE) {
|
||||
if(($P<$this->FMiddle) AND ($P>$this->FA)) return ($P-$this->FA)/($this->FMiddle-$this->FA);
|
||||
if(($P>$this->FMiddle) AND ($P<$this->FB)) return ($this->FB-$P)/($this->FB-$this->FMiddle);
|
||||
}
|
||||
|
||||
if ($this->FType==TRAPEZOID) {
|
||||
if(($P<$this->FMiddle[0]) AND ($P>$this->FA)) return ($P-$this->FA)/($this->FMiddle[0]-$this->FA);
|
||||
if(($P>$this->FMiddle[1]) AND ($P<$this->FB)) return ($this->FB-$P)/($this->FB-$this->FMiddle[1]);
|
||||
if (($P>=$this->FMiddle) and ($P<=$this->FMiddle)) return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
} // class Member
|
||||
|
||||
class Fuzzify extends Member {
|
||||
|
||||
protected $FMin = array();
|
||||
protected $FMax = array();
|
||||
protected $members = array();
|
||||
|
||||
public function setMinMax($idx,$A=0,$B=0) {
|
||||
If ($A<=$B) {
|
||||
$this->FMin[$idx] = $A;
|
||||
$this->FMax[$idx] = $B;
|
||||
} else {
|
||||
$this->FMin[$idx] = $B;
|
||||
$this->FMax[$idx] = $A;
|
||||
}
|
||||
}
|
||||
|
||||
public function clearMembers() {
|
||||
$this->members = NULL;
|
||||
}
|
||||
|
||||
public function addMember($idx,$Name='New',$start=0.0,$medium=0.0,$stop=0.0,$type=TRIANGLE) {
|
||||
$member = new Member($Name,$start,$medium,$stop,$type);
|
||||
if ($member->FA < (float)$this->FMin[$idx]) $this->setMinMax($idx, $member->FA ,(float)$this->FMax[$idx]);
|
||||
if ($member->FB > (float)$this->FMax[$idx]) $this->setMinMax($idx , (float)$this->FMin[$idx] , $member->FB);
|
||||
$this->members[$idx][] = $member;
|
||||
}
|
||||
|
||||
public function setMembers($idx,$m = array()) {
|
||||
$this->members[$idx] = $m;
|
||||
}
|
||||
|
||||
public function getMembers($idx,$id = NULL) {
|
||||
if ($id) return $this->members[$idx][$id];
|
||||
else return $this->members[$idx];
|
||||
}
|
||||
|
||||
public function getMembersIndex($idx,$value = NULL) {
|
||||
foreach ($this->members[$idx] as $idx => $member)
|
||||
if ($value==$member->FName) return $idx;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
public function getMemberByName($idx,$name = NULL) {
|
||||
foreach ($this->members[$idx] as $idx => $member)
|
||||
if ($name==$member->FName) return $member;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
} // end class fuzzify
|
||||
|
||||
class Rules extends Fuzzify{
|
||||
|
||||
public $FXValues = array();
|
||||
public $FYValues = array();
|
||||
public $FRealInput = array();
|
||||
public $FOutputs = array();
|
||||
|
||||
private $InputNames = NULL;
|
||||
private $OutputNames = NULL;
|
||||
private $rules = NULL;
|
||||
|
||||
/**
|
||||
* Set private properties $this->InputNames
|
||||
* example :
|
||||
* $fuzzy->setInputNames(array('Name1','Name2'));
|
||||
* @param array of string
|
||||
* return none
|
||||
**/
|
||||
|
||||
public function setInputNames($val) {
|
||||
$this->InputNames = $val;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set private properties $this->OutputNames
|
||||
* example :
|
||||
* $fuzzy->setOutputNames(array('Name1','Name2'));
|
||||
* @param array of string
|
||||
* return none
|
||||
**/
|
||||
|
||||
public function setOutputNames($val) {
|
||||
$this->OutputNames = $val;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return private properties $this->InputNames
|
||||
* example :
|
||||
* $names = $fuzzy->getInputNames();
|
||||
* @param none
|
||||
* return array of string
|
||||
**/
|
||||
|
||||
public function getInputNames() {
|
||||
return $this->InputNames;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return private properties $this->OutputNames
|
||||
* example :
|
||||
* $names = $fuzzy->getOututNames();
|
||||
* @param none
|
||||
* return array of string
|
||||
**/
|
||||
|
||||
public function getOutputNames() {
|
||||
return $this->OutputNames;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return private properties $this->InputNames[$idx]
|
||||
* example :
|
||||
* $names = $fuzzy->getInputNames($idx);
|
||||
* @param none
|
||||
* return string
|
||||
**/
|
||||
|
||||
public function getInputName($idx) {
|
||||
return $this->InputNames[$idx];
|
||||
}
|
||||
|
||||
/**
|
||||
* Return private properties $this->OutputNames[$idx]
|
||||
* example :
|
||||
* $names = $fuzzy->getOutputNames($idx);
|
||||
* @param none
|
||||
* return string
|
||||
**/
|
||||
|
||||
public function getOutputName($idx=0) {
|
||||
return $this->OutputNames[$idx];
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear all rules
|
||||
* example :
|
||||
* $fuzzy->clearRules();
|
||||
* @param none
|
||||
* return none
|
||||
**/
|
||||
|
||||
public function clearRules() {
|
||||
$this->rules = NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return array as Rules
|
||||
* example :
|
||||
* $fuzzy->getRules();
|
||||
* @param none
|
||||
* return array of string
|
||||
**/
|
||||
|
||||
public function getRules() {
|
||||
return $this->rules;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return Rule as String
|
||||
* example :
|
||||
* $fuzzy->getRule($id);
|
||||
* @param integer $id (key)
|
||||
* return string
|
||||
**/
|
||||
|
||||
public function getRule($id) {
|
||||
return $this->rules[$id];
|
||||
}
|
||||
|
||||
/**
|
||||
* Add Rule as String to private properties Rules Array
|
||||
* example :
|
||||
* $fuzzy->addRule('IF input1.High AND input2.Slow Then Out1.Run');
|
||||
* @param string
|
||||
* return none
|
||||
**/
|
||||
|
||||
public function addRule($val) {
|
||||
$this->rules[] = $val;
|
||||
}
|
||||
|
||||
/**
|
||||
* Find parenthis fragments of Rule as string
|
||||
* example :
|
||||
* $fragment = $this->rSplit('IF input1.High AND (input2.Slow OR input3.Fast) Then Out1.Run');
|
||||
* @param string
|
||||
* return string 'input2.Slow OR input3.Fast'
|
||||
**/
|
||||
|
||||
private function rSplit($string) {
|
||||
if (preg_match("/\((([^()]*|(?R))*)\)/",$string,$matches))
|
||||
return $matches[1];
|
||||
}
|
||||
/**
|
||||
* Get last nested parenthis fragments of Rule as string
|
||||
* example :
|
||||
* $fragment = $this->getLastParent('IF input1.High AND (input2.Slow OR (input3.Fast AND input4.Warm)) Then Out1.Run');
|
||||
* @param string
|
||||
* return string 'input3.Fast AND input4.Warm'
|
||||
**/
|
||||
private function getLastParent($a) {
|
||||
do {
|
||||
$a = $this->rSplit($a);
|
||||
if ($a) $ret=$a;
|
||||
} while($a);
|
||||
return $ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fuzzy Logic OR operation on array of values
|
||||
* example :
|
||||
* $val = $this->_FuzzyOR(array(1,0.5));
|
||||
* @param array float values
|
||||
* return float (max value) = 0.5
|
||||
**/
|
||||
|
||||
private function _FuzzyOR($arr) {
|
||||
return (max($arr));
|
||||
}
|
||||
|
||||
/**
|
||||
* Fuzzy Logic OR operation on array of values
|
||||
* example :
|
||||
* $val = $this->rSplit(array(1,0.5));
|
||||
* @param array float values
|
||||
* return float (min value) = 1
|
||||
**/
|
||||
private function _FuzzyAND($arr) {
|
||||
return (min($arr));
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate Rule.Parser And Interpreter for Rule.
|
||||
* Rule has text line example:
|
||||
* IF input1.High AND input2.Slow Then Out1.Run
|
||||
* Where
|
||||
* Operator : IF
|
||||
* Argument Input 1 : input1.High
|
||||
* where InputName = input1
|
||||
* DotSeparator = .
|
||||
* MemberName = Run
|
||||
* Operator : AND Operation for Arg1 , Arg 2 values
|
||||
* Argument Input 2 : input2.Slow
|
||||
* where InputName = input2
|
||||
* DotSeparator = .
|
||||
* MemberName = Slow
|
||||
* Operator : Then
|
||||
* Argument Output 1 : Out1.Run (InputName,DotSeparator,MemberName)
|
||||
*
|
||||
*
|
||||
* example :
|
||||
* $val = $fuzzy->processRule('IF input1.High AND input2.Slow Then Out1.Run');
|
||||
* @param string Rule
|
||||
* return float (calculated fuzzy value as Rule cryteria)
|
||||
**/
|
||||
|
||||
public function processRule($rule) {
|
||||
while ($in_parent = $this->getLastParent($rule)) {
|
||||
$pos=strpos($rule,$in_parent);
|
||||
$len=strlen($in_parent);
|
||||
$tmparr=array();
|
||||
$items=preg_split("/\s+/",$in_parent);
|
||||
$operation='and';
|
||||
foreach($items as $item) {
|
||||
$inp=strtolower($item);
|
||||
if (($inp=='or') or ($inp=='and')) $operation=$inp; else {
|
||||
list($inputName,$memberName) = preg_split("/\./",$item);
|
||||
// get value from
|
||||
$mem_idx = $this->getMembersIndex($inputName,$memberName);
|
||||
$tmparr[] =$this->FOutputs[$inputName][$mem_idx];
|
||||
}
|
||||
}
|
||||
$value1 = ($operation == 'or') ? $this->_FuzzyOR($tmparr) : $this->_FuzzyAND($tmparr);
|
||||
$rule=substr($rule,0,$pos-1).$value1.substr($rule,$pos+$len+1);
|
||||
}
|
||||
|
||||
$items=preg_split("/\s+/",$rule);
|
||||
$operation='and';
|
||||
$firstop = array_shift($items);
|
||||
$outitem = array_pop($items);
|
||||
$tmparr=array();
|
||||
foreach($items as $item) {
|
||||
$inp=strtolower($item);
|
||||
if (($inp=='or') or ($inp=='and')) $operation=$inp;
|
||||
elseif (($inp=='then') or ($inp=='for')) continue;
|
||||
else {
|
||||
// split names
|
||||
list($inputName,$memberName) = preg_split("/\./",$item);
|
||||
// get value from FOutputs
|
||||
$mem_idx = $this->getMembersIndex($inputName,$memberName);
|
||||
$tmparr[] =$this->FOutputs[$inputName][$mem_idx];
|
||||
}
|
||||
}
|
||||
|
||||
$value1 = ($operation == 'or') ? $this->_FuzzyOR($tmparr) : $this->_FuzzyAND($tmparr);
|
||||
return array($outitem,$value1);
|
||||
}
|
||||
|
||||
} //class Rules
|
||||
|
||||
class Fuzzy_Logic extends Rules {
|
||||
|
||||
protected $FuzzyTable = NULL;
|
||||
public $StateOutput = array();
|
||||
protected $AgregatePoints = 100;
|
||||
/*
|
||||
* Clear all solutions arrays in class and next calculations is Ready
|
||||
* example :
|
||||
* $this->ClearSolution();
|
||||
* @param none
|
||||
* return none
|
||||
*/
|
||||
private function ClearSolution() {
|
||||
$this->FXValues = array();
|
||||
$this->FYValues = array();
|
||||
}
|
||||
|
||||
/*
|
||||
* Set protected properties FuzzyTable
|
||||
* example :
|
||||
* $x->setFuzzyTable(array(
|
||||
* // IF input1 AND input2 Then Output
|
||||
* // For OR use pair input1 , NULL
|
||||
* // NULL , input 2
|
||||
* // ------ ------- -------
|
||||
* array('adequate', NULL , 'low'),
|
||||
* array(NULL , 'small' , 'low'),
|
||||
* array('marginal', 'large' , 'normal'),
|
||||
* array('inadequate' , NULL , 'high'),
|
||||
* ));
|
||||
* @param array
|
||||
* return none
|
||||
*/
|
||||
|
||||
|
||||
public function SetFuzzyTable($A = array()) {
|
||||
$this->FuzzyTable = $A;
|
||||
}
|
||||
|
||||
/*
|
||||
* Set Real Input Value =$X for Input named $idx
|
||||
* example :
|
||||
* $fuzzy->SetRealInput('input1',0.23);
|
||||
* @param string $idx
|
||||
* @param float $X
|
||||
* return none
|
||||
*/
|
||||
|
||||
public function SetRealInput($idx,$X = 0.0) {
|
||||
$this->FRealInput[$idx] = $X;
|
||||
$this->FOutputs[$idx] = array();
|
||||
For ($i=0;$i<count($this->members[$idx]);$i++) {
|
||||
$this->FOutputs[$idx][] = $this->members[$idx][$i]->Fuzzification($this->FRealInput[$idx]);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Agregate All Rules Result for Defuzification
|
||||
* example :
|
||||
* $fuzzy->FuzzyAgregate($outname,$Member,$AlphaCut=0.0)
|
||||
* @param string $output_name
|
||||
* @param object $member_object
|
||||
* @param float $calculate_rule_value
|
||||
* return none
|
||||
*/
|
||||
|
||||
public function FuzzyAgregate($outname,$Member,$AlphaCut=0.0) {
|
||||
foreach($this->FXValues[$outname] as $index=>$pointX) {
|
||||
if ($pointX<$Member->FA) continue;
|
||||
if ($pointX>$Member->FB) break;
|
||||
$ms = $Member->Fuzzification($pointX);
|
||||
$mem_val = min($ms,$AlphaCut);
|
||||
$this->FYValues[$outname][$index] = max($this->FYValues[$outname][$index],$mem_val);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Calculate Defuzification Fuzzy Result for method AVG (required set FuzzyTable)
|
||||
* example :
|
||||
* $fuzzy->calcFuzzy()
|
||||
* @param none
|
||||
* return array of outputs values (no associated keys)
|
||||
*/
|
||||
|
||||
public function calcFuzzyAlt() {
|
||||
$MaxAverage = 0;
|
||||
$this->ClearSolution();
|
||||
//$count_inputs = count($this->InputNames);
|
||||
$sum = 0;
|
||||
$tmpx=array();
|
||||
$sum = array();
|
||||
$cnt = array();
|
||||
// fill output agregate table
|
||||
foreach($this->getOutputNames() as $outname) {
|
||||
$AgregateDeltaX = ($this->FMax[$outname]-$this->FMin[$outname])/$this->AgregatePoints;
|
||||
$this->FXValues[$outname] = Range($this->FMin[$outname],$this->FMax[$outname],$AgregateDeltaX);
|
||||
$this->FYValues[$outname] = array_fill ( 0 , count($this->FXValues[$outname]), 0.0 );
|
||||
}
|
||||
|
||||
foreach ($this->FuzzyTable as $row_idx => $line_rule) {
|
||||
$sum = 0.0;
|
||||
$cnt = 0.0;
|
||||
$count_inputs = count($line_rule)-1; // last is output
|
||||
foreach ($line_rule as $col => $member_name) {
|
||||
$out_idx =$col - $count_inputs;
|
||||
$outname = $this->getOutputName($out_idx);
|
||||
if (!is_null($member_name)) {
|
||||
|
||||
if ($col<$count_inputs) { // is input
|
||||
$inp_name = $this->getInputName($col);
|
||||
$mem_idx = $this->getMembersIndex($inp_name,$member_name);
|
||||
$val =$this->FOutputs[$inp_name][$mem_idx]; // get members value
|
||||
if ($val>0) {
|
||||
$sum+=$val; // sum members values
|
||||
$cnt++;
|
||||
} else {
|
||||
//$sum=0;
|
||||
//$cnt=0;
|
||||
break;
|
||||
}
|
||||
} else { //is output
|
||||
|
||||
$member=$this->getMemberByName($outname,$member_name); // get OUTPUT member
|
||||
if ($cnt == 0) $avg_sum = 0; else $avg_sum = $sum/$cnt;
|
||||
$this->StateOutput[$member_name] = $avg_sum;
|
||||
if ($avg_sum>0) $this->FuzzyAgregate($outname,$member,$avg_sum);
|
||||
$sum = 0.0;
|
||||
$cnt = 0.0;
|
||||
}
|
||||
} // if $member_name
|
||||
} // foreach rule
|
||||
} // foreach rule_row
|
||||
|
||||
$result = array();
|
||||
|
||||
foreach($this->getOutputNames() as $outname) {
|
||||
$suma=0.0;
|
||||
$sumb=0.0;
|
||||
|
||||
foreach($this->FXValues[$outname] as $id=>$x) {
|
||||
$y=$this->FYValues[$outname][$id];
|
||||
if ($y>0) {
|
||||
$suma+=($x*$y);
|
||||
$sumb+=$y;
|
||||
}
|
||||
}
|
||||
if ($sumb == 0) $result[]= 0; else $result[] = $suma/$sumb;
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
/*
|
||||
* Calculate Defuzification Fuzzy Result for method MIN,MAX (required set Rules)
|
||||
* example :
|
||||
* $fuzzy->calcFuzzyAlt()
|
||||
* @param none
|
||||
* return array of outputs values (associated keys)
|
||||
*/
|
||||
|
||||
public function calcFuzzy() {
|
||||
$this->ClearSolution();
|
||||
|
||||
$sum = 0;
|
||||
$tmpx=array();
|
||||
$sum = array();
|
||||
$cnt = array();
|
||||
// fill output agregate table
|
||||
foreach($this->getOutputNames() as $outname) {
|
||||
$AgregateDeltaX = ($this->FMax[$outname]-$this->FMin[$outname])/$this->AgregatePoints;
|
||||
$this->FXValues[$outname] = Range($this->FMin[$outname],$this->FMax[$outname],$AgregateDeltaX);
|
||||
$this->FYValues[$outname] = array_fill ( 0 , count($this->FXValues[$outname]), 0.0 );
|
||||
}
|
||||
|
||||
$rules=$this->getRules();
|
||||
foreach ($rules as $key=>$rule) {
|
||||
list($outItem,$value) = $this->processRule($rule);
|
||||
list($outputName,$memberName) = preg_split("/\./",$outItem);
|
||||
$this->StateOutput[$memberName] = $value;
|
||||
$member=$this->getMemberByName($outputName,$memberName); // get OUTPUT member
|
||||
if ($value>0) $this->FuzzyAgregate($outputName,$member,$value);
|
||||
}
|
||||
|
||||
$result = array();
|
||||
|
||||
foreach($this->getOutputNames() as $outname) {
|
||||
$suma=0.0;
|
||||
$sumb=0.0;
|
||||
|
||||
foreach($this->FXValues[$outname] as $id=>$x) {
|
||||
$y=$this->FYValues[$outname][$id];
|
||||
if ($y>0) {
|
||||
$suma+=($x*$y);
|
||||
$sumb+=$y;
|
||||
}
|
||||
}
|
||||
if ($sumb == 0) $result[$outname]= 0; else $result[$outname] = $suma/$sumb;
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
} //class
|
||||
|
||||
|
||||
|
||||
/*--------------------------- start tank demo controll --------*/
|
||||
$x = new Fuzzy_Logic();
|
||||
|
||||
$x->clearMembers();
|
||||
/* ---------- set input members ---------*/
|
||||
$x->setInputNames(array('ERROR','RATE'));
|
||||
|
||||
$x->addMember($x->getInputName(0),'E_NEG',-1 ,-0.9 , 0 ,LINFINITY);
|
||||
$x->addMember($x->getInputName(0),'E_OK' ,-0.1 , 0 , 0.1,TRIANGLE);
|
||||
$x->addMember($x->getInputName(0),'E_POS', 0 , 0.9 , 1 ,RINFINITY);
|
||||
|
||||
$x->addMember($x->getInputName(1),'R_NEG',-0.10,-0.07 ,0 ,LINFINITY);
|
||||
$x->addMember($x->getInputName(1),'R_OK', -0.07, 0 ,0.07 ,TRIANGLE);
|
||||
$x->addMember($x->getInputName(1),'R_POS', 0 , 0.07 ,0.1 ,RINFINITY);
|
||||
|
||||
/* ---------- set output members ---------*/
|
||||
$x->setOutputNames(array('OUT'));
|
||||
|
||||
$x->addMember($x->getOutputName(0),'CF',-1.0, -0.9 ,-0.8 ,TRIANGLE);
|
||||
$x->addMember($x->getOutputName(0),'CS',-0.6, -0.5 ,-0.4 ,TRIANGLE);
|
||||
$x->addMember($x->getOutputName(0),'NC',-0.1, 0.0 , 0.1 ,TRIANGLE);
|
||||
$x->addMember($x->getOutputName(0),'OS', 0.4, 0.5 , 0.6 ,TRIANGLE);
|
||||
$x->addMember($x->getOutputName(0),'OF', 0.8, 0.9 , 1.0 ,TRIANGLE);
|
||||
|
||||
|
||||
/* ---------- set rules table ------------ */
|
||||
$x->clearRules();
|
||||
|
||||
$x->addRule('IF ERROR.E_NEG THEN OUT.CF');
|
||||
$x->addRule('IF ERROR.E_OK THEN OUT.NC');
|
||||
$x->addRule('IF ERROR.E_POS THEN OUT.OF');
|
||||
$x->addRule('IF ERROR.E_OK AND RATE.R_POS THEN OUT.CS');
|
||||
$x->addRule('IF ERROR.E_OK AND RATE.R_NEG THEN OUT.OS');
|
||||
|
||||
/*------------ Remote parameters----------------*/
|
||||
|
||||
|
||||
$get = $_GET['table'];
|
||||
|
||||
$tankLevel = $get["currTanksLevel"];
|
||||
$tankLastLevel = $get["lastTanksLevel"];
|
||||
$tankValve = $get["valveTanksInput"];
|
||||
|
||||
$set = $_GET['setmode'];
|
||||
|
||||
$InputMaxValve = $set["mainInput"];
|
||||
$OutputXMaxValve = $set["mainOutputX"];
|
||||
$OutputYMaxValve = $set["mainOutputY"];
|
||||
$tankDemandLevel = $set["demandTanksLevel"];
|
||||
$tankInpMax = $set["remoteTanksInput"];
|
||||
$tankOutMax = $set["remoteTanksOutput"];
|
||||
$tankMaxWorkLevel = $set["tankMaxWorkLevel"];
|
||||
$tankMinWorkLevel = $set["tankMinWorkLevel"];
|
||||
|
||||
|
||||
/*------------- Valve parameters -------------*/
|
||||
$ToutX_stream = 0.02 ; // output stream by time period
|
||||
$ToutY_stream = 0.03 ; // output stream by time period
|
||||
$Tinp_stream = 0.07 ;
|
||||
/*-------------- Initialise ------------------*/
|
||||
|
||||
$tankName = array('A', 'B', 'C', 'D', 'E', 'X' , 'Y' );
|
||||
$tankInputRefKey = array(-1 , 0 , 1 , 2 , 3 , 4 , 3 );
|
||||
$tankOutputRefKey = array(0 , 1 , 2 , 3 , 4 , -1 , 4 );
|
||||
|
||||
$tankMaxLevel = array(1.0,1.0,1.0,1.0,1.0,1.0,1.0);
|
||||
$tankInpDT = array(0.07,0.07,0.07,0.07,0.07,0.07,0.07);
|
||||
$tankOutDT = array(0.05,0.05,0.05,0.05,0.05,0.05,0.05);
|
||||
$tankFuzzy = array(0.0,0.0,0.0,0.0,0.0,0.0,0.0);
|
||||
|
||||
/* ----------- Fuzzy Controll Loop ----------------*/
|
||||
for($tank=0;$tank<7;$tank++) {
|
||||
$name=$tankName[$tank];
|
||||
list($erate,$elevel) = getLastErrors($tankDemandLevel[$tank],$tankLevel[$tank],$tankLastLevel[$tank]);
|
||||
$x->SetRealInput('ERROR', $elevel );
|
||||
$x->SetRealInput('RATE' , $erate );
|
||||
$fuzzy_arr = $x->calcFuzzy();
|
||||
$tankFuzzy[$tank] = $fuzzy_arr['OUT'];
|
||||
$tankLastLevel[$tank] = $tankLevel[$tank];
|
||||
$key_input_ref = $tankInputRefKey[$tank];
|
||||
if($key_input_ref>=0)
|
||||
$Vinp_max = $tankInpMax[$tank]*$tankInpDT[$tank]*(int)(($tankLevel[$tank]<=$tankMaxWorkLevel[$tank]) and ($tankLevel[$key_input_ref]>$tankMinWorkLevel[$key_input_ref]));
|
||||
else
|
||||
$Vinp_max = $InputMaxValve*$Tinp_stream *(int)($tankLevel[$tank]<$tankMaxWorkLevel[$tank]);
|
||||
|
||||
list($tankValve[$tank],$WaterInput) = getValve($tankFuzzy[$tank],$tankValve[$tank],$Vinp_max,0,1);
|
||||
|
||||
$key_output_ref = $tankOutputRefKey[$tank];
|
||||
|
||||
if($key_output_ref>=0)
|
||||
$VOut_max = $tankOutMax[$tank]*$tankOutDT[$tank]*(int)($tankLevel[$key_output_ref]>$tankMinWorkLevel[$key_output_ref]);
|
||||
else //-1
|
||||
$VOut_max = $OutputXMaxValve*$ToutX_stream*(int)($tankLevel[$tank]>$tankMinWorkLevel[$tank]);
|
||||
|
||||
$tankLevel[$tank] = min($tankMaxLevel[$tank],$tankLevel[$tank] - $VOut_max + $WaterInput);
|
||||
}
|
||||
|
||||
|
||||
$out =array(
|
||||
"currTanksLevel" => $tankLevel ,
|
||||
"lastTanksLevel" => $tankLastLevel ,
|
||||
"valveTanksInput" => $tankValve );
|
||||
|
||||
echo json_encode($out);
|
||||
|
||||
?>
|
||||
+3068
Diferenças do arquivo suprimidas por serem muito extensas
Carregar Diff
|
Depois Largura: | Altura: | Tamanho: 107 KiB |
@@ -0,0 +1,124 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html;charset=utf-8">
|
||||
<title>Hydro Demo</title>
|
||||
<link href="css/screen.css" rel="stylesheet" type="text/css"/>
|
||||
<link href="css/jquery.ui.core.css" rel="stylesheet" type="text/css" />
|
||||
<link href="css/jquery.ui.theme.css" rel="stylesheet" type="text/css" />
|
||||
<link href="css/jquery.ui.base.css" rel="stylesheet" type="text/css" />
|
||||
|
||||
<style>
|
||||
#header { text-align:center; }
|
||||
|
||||
#valveA,#valveB,#valveC,#valveD,#valveE,#valveX,#valveY { font-size:8px; }
|
||||
|
||||
#pbdiv { border-bottom :solid 1px #aaa; }
|
||||
|
||||
#sbdiv { padding-bottom:5px; border-bottom :solid 1px #aaa; }
|
||||
|
||||
.ui-dialog { opacity : 0.8; }
|
||||
.alt {
|
||||
color: #666666;
|
||||
font-family: "Warnock Pro","Goudy Old Style","Palatino","Book Antiqua",Georgia,serif;
|
||||
font-style: italic;
|
||||
font-weight: normal;
|
||||
|
||||
}
|
||||
|
||||
#demo-frame > div.demo { padding: 10px !important; }
|
||||
|
||||
#inputinfo, #outputinfox,#outputinfoy, #demandinfo {
|
||||
padding-top:3px;
|
||||
margin-top:5px;
|
||||
border-top :solid 1px #aaa;
|
||||
|
||||
padding-bottom:3px;
|
||||
margin-bottom:5px;
|
||||
border-bottom :solid 1px #aaa;
|
||||
}
|
||||
|
||||
#input, #outputx, #outputy, #demand {
|
||||
width: 150px;
|
||||
}
|
||||
|
||||
#input .ui-slider-range { background: #ef2929; }
|
||||
#input .ui-slider-handle { border-color: #ef2929; }
|
||||
#outputx .ui-slider-range { background: #8ae234; }
|
||||
#outputx .ui-slider-handle { border-color: #8ae234; }
|
||||
#outputy .ui-slider-range { background: #8ae234; }
|
||||
#outputy .ui-slider-handle { border-color: #8ae234; }
|
||||
#demand .ui-slider-range { background: #729fcf; }
|
||||
#demand .ui-slider-handle { border-color: #729fcf; }
|
||||
|
||||
#infotable {
|
||||
font-size:10px;
|
||||
margin: 0 15px 0 15px;
|
||||
}
|
||||
|
||||
td {
|
||||
style="font-family:Tahoma,Verdana;
|
||||
font-size:0.7em;"
|
||||
}
|
||||
</style>
|
||||
<link rel="stylesheet" href="/css/base.css" type="text/css" media="all" />
|
||||
<link rel="stylesheet" href="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.11/themes/base/jquery-ui.css" type="text/css" media="all" />
|
||||
<link rel="stylesheet" href="http://static.jquery.com/ui/css/demo-docs-theme/ui.theme.css" type="text/css" media="all" />
|
||||
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.5.1/jquery.min.js" type="text/javascript"></script>
|
||||
<script src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.11/jquery-ui.min.js" type="text/javascript"></script>
|
||||
<script src="http://jquery-ui.googlecode.com/svn/tags/latest/external/jquery.bgiframe-2.1.2.js" type="text/javascript"></script>
|
||||
<script src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.11/i18n/jquery-ui-i18n.min.js" type="text/javascript"></script>
|
||||
<script src="js/fuzzy-demo-min.js" type="text/javascript"></script>
|
||||
|
||||
</head>
|
||||
<body style="background-color:#d8d8d8;" onload="register_svg()">
|
||||
<div class="container" style="width:970px">
|
||||
<div id="header" class="span-24 last">
|
||||
<h3 class="alt">Fuzzy-Logic Demo - control valve 7 entrance station of water treatment tanks.</h3></div>
|
||||
<div id="pbdiv" class="span-24 last" style="text-align:right;">
|
||||
<div class="span-2">Valves(inp)</div>
|
||||
<div class="span-1 valtxt"><h3>A</h3></div>
|
||||
<div id="valveA" class="span-2"></div>
|
||||
<div class="span-1 valtxt"><h3>B</h3></div>
|
||||
<div id="valveB" class="span-2"></div>
|
||||
<div class="span-1 valtxt"><h3>C</h3></div>
|
||||
<div id="valveC" class="span-2"></div>
|
||||
<div class="span-1 valtxt"><h3>D</h3></div>
|
||||
<div id="valveD" class="span-2"></div>
|
||||
<div class="span-1 valtxt"><h3>E</h3></div>
|
||||
<div id="valveE" class="span-2"></div>
|
||||
<div class="span-1 valtxt"><h3>X</h3></div>
|
||||
<div id="valveX" class="span-2"></div>
|
||||
<div class="span-1 valtxt"><h3>Y</h3></div>
|
||||
<div id="valveY" class="span-2 last"></div>
|
||||
</div>
|
||||
<div class="span-24 last">
|
||||
<div align="center">
|
||||
<embed id="embed" src="hydro9x.svg" width="960" height="650" />
|
||||
</div>
|
||||
</div>
|
||||
<!-- remote tanks -->
|
||||
<div class="span-24 last">
|
||||
<div id="inputinfo" class="span-5 prepend-1">Water supply<span id="inp_val">100</span></div>
|
||||
<div id="outputinfox" class="span-5 prepend-1">Industrial consumption<span id="outx_val">50</span></div>
|
||||
<div id="outputinfoy" class="span-5 prepend-1">Municipal consumption<span id="outy_val">50</span></div>
|
||||
<div id="demandinfo" class="span-5 prepend-1 last">Desired tank(Y) level<span id="dem_val">85</span></div>
|
||||
</div>
|
||||
<div id="sbdiv" class="span-24 last">
|
||||
<div class="span-5 prepend-1 push-0"><div id="input"></div></div>
|
||||
<div class="span-5 prepend-1 push-0"><div id="outputx"></div></div>
|
||||
<div class="span-5 prepend-1 push-0"><div id="outputy"></div></div>
|
||||
<div class="span-5 prepend-1 push-0 last"><div id="demand"></div></div>
|
||||
</div>
|
||||
<div class="span-24 last">(c) wojtek jarzęcki 2011</div>
|
||||
|
||||
|
||||
<div id="remote_level" style="display:none;font-family:verdana;">
|
||||
<div id="remote_container">
|
||||
<div id="infotable"></div>
|
||||
</div>
|
||||
<div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
Arquivo binário não exibido.
|
Depois Largura: | Altura: | Tamanho: 22 KiB |
Arquivo binário não exibido.
|
Depois Largura: | Altura: | Tamanho: 21 KiB |
Arquivo binário não exibido.
|
Depois Largura: | Altura: | Tamanho: 21 KiB |
Arquivo binário não exibido.
|
Depois Largura: | Altura: | Tamanho: 15 KiB |
externo
+1
Diff do arquivo suprimido porque uma ou mais linhas são muito longas
@@ -0,0 +1,14 @@
|
||||
This class lets you build simple controllers, fuzzy-logic derived from the fields of artificial intelligence. Fuzzy-logic controllers are useful wherever the use of classical logic (YES NO) is unreliable.
|
||||
|
||||
WHAT IS FUZZY LOGIC?
|
||||
In this context, FL is a problem-solving control system methodology that lends itself to implementation in systems ranging from simple, small, embedded micro-controllers to large, networked, multi-channel PC or workstation-based data acquisition and control systems. It can be implemented in hardware, software, or a combination of both. FL provides a simple way to arrive at a definite conclusion based upon vague, ambiguous, imprecise, noisy, or missing input information. FL's approach to control problems mimics how a person would make decisions, only much faster.
|
||||
|
||||
HOW IS FL DIFFERENT FROM CONVENTIONAL CONTROL METHODS?
|
||||
FL incorporates a simple, rule-based IF X AND Y THEN Z approach to a solving control problem rather than attempting to model a system mathematically. The FL model is empirically-based, relying on an operator's experience rather than their technical understanding of the system. For example, rather than dealing with temperature control in terms such as "SP =500F", "T <1000F", or "210C <TEMP <220C", terms like "IF (process is too cool) AND (process is getting colder) THEN (add heat to the process)" or "IF (process is too hot) AND (process is heating rapidly) THEN (cool the process quickly)" are used. These terms are imprecise and yet very descriptive of what must actually happen. Consider what you do in the shower if the temperature is too cold: you will make the water comfortable very quickly with little trouble. FL is capable of mimicking this type of behavior but at very high rate.
|
||||
|
||||
Fuzzy logic has proved very useful in engineering applications, which is where the classical logic of classifying only criterion for true / false can not effectively cope with the many ambiguities and contradictions. Many applications, including electronic control systems (machines, vehicles and machines), Data Mining, or in the construction of expert systems.
|
||||
Methods of fuzzy logic along with evolutionary algorithms and neural networks are the modern tools for building intelligent systems with the ability of generalization of knowledge.
|
||||
|
||||
sources:
|
||||
http://www.seattlerobotics.org/encoder/mar98/fuz/fl_part1.html#WHAT IS FUZZY LOGIC?
|
||||
Wikipedia
|
||||
@@ -0,0 +1,697 @@
|
||||
<?php
|
||||
/***************************************************************
|
||||
*
|
||||
* (c) 2011 Wojtek Jarzęcki (lottocad(nospam)@gmail.com)
|
||||
* All rights reserved
|
||||
*
|
||||
* BSD Licence
|
||||
*
|
||||
* Date: 2013-01-22
|
||||
* Modified by: iJab(zhancaibaoATgmail.com)
|
||||
* Parse MatLab Rules of Fuzzy Logic
|
||||
*
|
||||
***************************************************************/
|
||||
error_reporting(5);
|
||||
define ("LINFINITY" , -1 );
|
||||
define ("TRIANGLE" , 0 );
|
||||
define ("RINFINITY" , 1 );
|
||||
define ("TRAPEZOID" , 2 );
|
||||
|
||||
class Member {
|
||||
|
||||
protected
|
||||
$FName, // Member Name
|
||||
$FMiddle, // Middle Member point
|
||||
$FA, // Start Member point
|
||||
$FB, // End member point
|
||||
$FType; // Member type TRIANGLE,LINFINITY,RFINFINITY, TRAPEZOID
|
||||
|
||||
public function __construct($Name=NULL,$start=NULL,$medium=NULL,$stop=NULL,$type=NULL){
|
||||
if(is_null($Name)) return;
|
||||
$this->FName = $Name;
|
||||
$this->FMiddle = $medium;
|
||||
$this->FA = $start;
|
||||
$this->FB = $stop;
|
||||
$this->FType = $type;
|
||||
}
|
||||
|
||||
public function __toString(){
|
||||
return "Member\tname: $this->FName,
|
||||
middle: $this->FMiddle,
|
||||
start : $this->FA,
|
||||
fb : $this->FB,
|
||||
type : $this->FType";
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Name of Membership funcitons.
|
||||
* $mf_name = getMemberName();
|
||||
* @param void
|
||||
* return string
|
||||
*/
|
||||
public function getMemberName() {
|
||||
return $this->FName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Type of Membership funcitons.
|
||||
* $mf_type = getMemberType();
|
||||
* @param void
|
||||
* return string
|
||||
*/
|
||||
public function getMemberType() {
|
||||
return $this->FType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates the ratio of belonging to a set of defined function shape.
|
||||
* $ratio = Fuzzification($pontX);
|
||||
* @param float $poinX
|
||||
* return float
|
||||
*/
|
||||
public function Fuzzification($P=0.0) {
|
||||
|
||||
if (($P<$this->FA) OR ($P>$this->FB)) return 0; //P is out this segment...
|
||||
|
||||
if ($P==$this->FMiddle) return 1;
|
||||
|
||||
if ($this->FType==LINFINITY) {
|
||||
if ($P<=$this->FMiddle) return 1;
|
||||
if (($P>$this->FMiddle) AND ($P<$this->FB)) return ($this->FB-$P)/($this->FB-$this->FMiddle);
|
||||
}
|
||||
|
||||
if ($this->FType==RINFINITY) {
|
||||
if ($P>=$this->FMiddle) return 1;
|
||||
if (($P<$this->FMiddle) AND ($P>$this->FA)) return ($P-$this->FA)/($this->FMiddle-$this->FA);
|
||||
}
|
||||
|
||||
if ($this->FType==TRIANGLE) {
|
||||
if(($P<$this->FMiddle) AND ($P>$this->FA)) return ($P-$this->FA)/($this->FMiddle-$this->FA);
|
||||
if(($P>$this->FMiddle) AND ($P<$this->FB)) return ($this->FB-$P)/($this->FB-$this->FMiddle);
|
||||
}
|
||||
|
||||
if ($this->FType==TRAPEZOID) {
|
||||
if(($P<$this->FMiddle[0]) AND ($P>$this->FA)) return ($P-$this->FA)/($this->FMiddle[0]-$this->FA);
|
||||
if(($P>$this->FMiddle[1]) AND ($P<$this->FB)) return ($this->FB-$P)/($this->FB-$this->FMiddle[1]);
|
||||
if (($P>=$this->FMiddle[0]) AND ($P<=$this->FMiddle[1])) return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
} // class Member
|
||||
|
||||
class Fuzzify extends Member {
|
||||
|
||||
protected $FMin = array();
|
||||
protected $FMax = array();
|
||||
protected $members = array();
|
||||
|
||||
public function setMinMax($idx,$A=0,$B=0) {
|
||||
If ($A<=$B) {
|
||||
$this->FMin[$idx] = $A;
|
||||
$this->FMax[$idx] = $B;
|
||||
} else {
|
||||
$this->FMin[$idx] = $B;
|
||||
$this->FMax[$idx] = $A;
|
||||
}
|
||||
}
|
||||
|
||||
public function clearMembers() {
|
||||
$this->members = NULL;
|
||||
}
|
||||
|
||||
public function addMember($idx,$Name='New',$start=0.0,$medium=0.0,$stop=0.0,$type=TRIANGLE) {
|
||||
$member = new Member($Name,$start,$medium,$stop,$type);
|
||||
if ($member->FA < (float)$this->FMin[$idx]) $this->setMinMax($idx, $member->FA ,(float)$this->FMax[$idx]);
|
||||
if ($member->FB > (float)$this->FMax[$idx]) $this->setMinMax($idx , (float)$this->FMin[$idx] , $member->FB);
|
||||
$this->members[$idx][] = $member;
|
||||
}
|
||||
|
||||
public function setMembers($idx,$m = array()) {
|
||||
$this->members[$idx] = $m;
|
||||
}
|
||||
|
||||
public function getMembers($idx,$id = NULL) {
|
||||
if(!is_null($id))
|
||||
{
|
||||
return $this->members[$idx][$id];
|
||||
}
|
||||
else if(!is_null($idx))
|
||||
{
|
||||
return $this->members[$idx];
|
||||
}
|
||||
else
|
||||
{
|
||||
return $this->members;
|
||||
}
|
||||
}
|
||||
|
||||
public function getMembersIndex($idx,$value = NULL) {
|
||||
foreach ($this->members[$idx] as $idx => $member)
|
||||
if ($value==$member->FName) return $idx;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
public function getMemberByName($idx,$name = NULL) {
|
||||
foreach ($this->members[$idx] as $idx => $member)
|
||||
if ($name==$member->FName) return $member;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
} // end class fuzzify
|
||||
|
||||
class Rules extends Fuzzify{
|
||||
|
||||
public $FXValues = array();
|
||||
public $FYValues = array();
|
||||
public $FRealInput = array();
|
||||
public $FInputRange = array();
|
||||
public $FOutputs = array();
|
||||
|
||||
private $InputNames = NULL;
|
||||
private $OutputNames = NULL;
|
||||
private $rules = NULL;
|
||||
|
||||
/**
|
||||
* Set private properties $this->InputNames
|
||||
* example :
|
||||
* $fuzzy->setInputNames(array('Name1','Name2'));
|
||||
* @param array of string
|
||||
* return none
|
||||
**/
|
||||
|
||||
public function setInputNames($val) {
|
||||
$this->InputNames = $val;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set private properties $this->OutputNames
|
||||
* example :
|
||||
* $fuzzy->setOutputNames(array('Name1','Name2'));
|
||||
* @param array of string
|
||||
* return none
|
||||
**/
|
||||
|
||||
public function setOutputNames($val) {
|
||||
$this->OutputNames = $val;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return private properties $this->InputNames
|
||||
* example :
|
||||
* $names = $fuzzy->getInputNames();
|
||||
* @param none
|
||||
* return array of string
|
||||
**/
|
||||
|
||||
public function getInputNames() {
|
||||
return $this->InputNames;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return private properties $this->OutputNames
|
||||
* example :
|
||||
* $names = $fuzzy->getOututNames();
|
||||
* @param none
|
||||
* return array of string
|
||||
**/
|
||||
|
||||
public function getOutputNames() {
|
||||
return $this->OutputNames;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return private properties $this->InputNames[$idx]
|
||||
* example :
|
||||
* $names = $fuzzy->getInputNames($idx);
|
||||
* @param $idx Integer
|
||||
* return string
|
||||
**/
|
||||
|
||||
public function getInputName($idx) {
|
||||
return $this->InputNames[$idx];
|
||||
}
|
||||
|
||||
/**
|
||||
* Return private properties $this->OutputNames[$idx]
|
||||
* example :
|
||||
* $names = $fuzzy->getOutputNames($idx);
|
||||
* @param none
|
||||
* return string
|
||||
**/
|
||||
|
||||
public function getOutputName($idx=0) {
|
||||
return $this->OutputNames[$idx];
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear all rules
|
||||
* example :
|
||||
* $fuzzy->clearRules();
|
||||
* @param none
|
||||
* return none
|
||||
**/
|
||||
|
||||
public function clearRules() {
|
||||
$this->rules = NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return array as Rules
|
||||
* example :
|
||||
* $fuzzy->getRules();
|
||||
* @param none
|
||||
* return array of string
|
||||
**/
|
||||
|
||||
public function getRules() {
|
||||
return $this->rules;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return Rule as String
|
||||
* example :
|
||||
* $fuzzy->getRule($id);
|
||||
* @param integer $id (key)
|
||||
* return string
|
||||
**/
|
||||
|
||||
public function getRule($id) {
|
||||
return $this->rules[$id];
|
||||
}
|
||||
|
||||
/**
|
||||
* Add Rule as String to private properties Rules Array
|
||||
* example :
|
||||
* $fuzzy->addRule('IF input1.High AND input2.Slow Then Out1.Run');
|
||||
* @param string
|
||||
* return none
|
||||
**/
|
||||
|
||||
public function addRule($val) {
|
||||
$this->rules[] = $val;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add Rules based on MatLab's Rule File
|
||||
* example :
|
||||
* $fuzzy->addRules(array("0 0 0 1 0 0 1, 1 (1) : 1",
|
||||
"0 0 0 1 0 0 2, 1 (1) : 1",));
|
||||
* @param array
|
||||
* return none
|
||||
**/
|
||||
|
||||
public function addRules($vals) {
|
||||
$ct_inputs = count($this->getInputNames());
|
||||
$ct_outputs = count($this->getOutputNames());
|
||||
|
||||
foreach($vals as $val)
|
||||
{
|
||||
// Parse each rule with MatLab format
|
||||
$a_rule = explode(',', $val);
|
||||
$input_rule = explode(' ', $a_rule[0]);
|
||||
$r_rule = explode(':', $a_rule[1]);
|
||||
$output_rule = explode('(', $r_rule[0]);
|
||||
$tmp = explode(')', $output_rule[1]);
|
||||
$oput_put_rule[1] = $tmp[0];
|
||||
$op_rule = $r_rule[1];
|
||||
|
||||
// Construct String Rule
|
||||
$rule_string = 'IF ';
|
||||
$op = intval($op_rule) == 1 ? "AND" : "OR";
|
||||
|
||||
// Parse input params
|
||||
for($ix = 0; $ix < count($input_rule); $ix++)
|
||||
{
|
||||
$mf_ix = intval($input_rule[$ix])-1;
|
||||
if($mf_ix < 0 ) continue;
|
||||
if($ix >= $ct_inputs ) break;
|
||||
|
||||
$input_name = $this->getInputName($ix);
|
||||
$input_mf = $this->getMembers($input_name, intval($input_rule[$ix])-1);
|
||||
|
||||
if($ix > 0)
|
||||
{
|
||||
$rule_string .= ' ' . $op . ' ';
|
||||
}
|
||||
$rule_string .= $input_name . "." . $input_mf->getMemberName();
|
||||
}
|
||||
|
||||
// Parse output params
|
||||
$rule_string .= ' Then ';
|
||||
$output_name = $this->getOutputName(intval($output_rule[1])-1);
|
||||
$output_mf = $this->getMembers($output_name, intval($output_rule[0])-1);
|
||||
$rule_string .= $output_name . "." . $output_mf->getMemberName();
|
||||
|
||||
$this->rules[] = $rule_string;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Find parenthis fragments of Rule as string
|
||||
* example :
|
||||
* $fragment = $this->rSplit('IF input1.High AND (input2.Slow OR input3.Fast) Then Out1.Run');
|
||||
* @param string
|
||||
* return string 'input2.Slow OR input3.Fast'
|
||||
**/
|
||||
|
||||
private function rSplit($string) {
|
||||
if (preg_match("/\((([^()]*|(?R))*)\)/",$string,$matches))
|
||||
return $matches[1];
|
||||
}
|
||||
/**
|
||||
* Get last nested parenthis fragments of Rule as string
|
||||
* example :
|
||||
* $fragment = $this->getLastParent('IF input1.High AND (input2.Slow OR (input3.Fast AND input4.Warm)) Then Out1.Run');
|
||||
* @param string
|
||||
* return string 'input3.Fast AND input4.Warm'
|
||||
**/
|
||||
private function getLastParent($a) {
|
||||
do {
|
||||
$a = $this->rSplit($a);
|
||||
if ($a) $ret=$a;
|
||||
} while($a);
|
||||
return $ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fuzzy Logic OR operation on array of values
|
||||
* example :
|
||||
* $val = $this->_FuzzyOR(array(1,0.5));
|
||||
* @param array float values
|
||||
* return float (max value) = 0.5
|
||||
**/
|
||||
|
||||
private function _FuzzyOR($arr) {
|
||||
return (max($arr));
|
||||
}
|
||||
|
||||
/**
|
||||
* Fuzzy Logic OR operation on array of values
|
||||
* example :
|
||||
* $val = $this->rSplit(array(1,0.5));
|
||||
* @param array float values
|
||||
* return float (min value) = 1
|
||||
**/
|
||||
private function _FuzzyAND($arr) {
|
||||
return (min($arr));
|
||||
}
|
||||
|
||||
/**
|
||||
* Fuzzy Logic NOT operation on array of values
|
||||
* example :
|
||||
* $val = $this->rSplit(array(1,0.5));
|
||||
* @param array float values
|
||||
* return float (min value) = 1
|
||||
**/
|
||||
private function _FuzzyNOT($arr) {
|
||||
return 1 - $arr[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate Rule.Parser And Interpreter for Rule.
|
||||
* Rule has text line example:
|
||||
* IF input1.High AND input2.Slow Then Out1.Run
|
||||
* Where
|
||||
* Operator : IF
|
||||
* Argument Input 1 : input1.High
|
||||
* where InputName = input1
|
||||
* DotSeparator = .
|
||||
* MemberName = Run
|
||||
* Operator : AND Operation for Arg1 , Arg 2 values
|
||||
* Argument Input 2 : input2.Slow
|
||||
* where InputName = input2
|
||||
* DotSeparator = .
|
||||
* MemberName = Slow
|
||||
* Operator : Then
|
||||
* Argument Output 1 : Out1.Run (InputName,DotSeparator,MemberName)
|
||||
*
|
||||
*
|
||||
* example :
|
||||
* $val = $fuzzy->processRule('IF input1.High AND input2.Slow Then Out1.Run');
|
||||
* @param string Rule
|
||||
* return float (calculated fuzzy value as Rule cryteria)
|
||||
**/
|
||||
|
||||
public function processRule($rule) {
|
||||
while ($in_parent = $this->getLastParent($rule)) {
|
||||
$pos=strpos($rule,$in_parent);
|
||||
$len=strlen($in_parent);
|
||||
$tmparr=array();
|
||||
$items=preg_split("/\s+/",$in_parent);
|
||||
$operation='and';
|
||||
foreach($items as $item) {
|
||||
$inp=strtolower($item);
|
||||
if (($inp=='or') or ($inp=='and') or ($inp=='not')) $operation=$inp; else {
|
||||
list($inputName,$memberName) = preg_split("/\./",$item);
|
||||
// get value from
|
||||
$mem_idx = $this->getMembersIndex($inputName,$memberName);
|
||||
$tmparr[] =$this->FOutputs[$inputName][$mem_idx];
|
||||
}
|
||||
}
|
||||
$value1 = ($operation == 'or') ? $this->_FuzzyOR($tmparr) :
|
||||
($operation == 'not') ? $this->_FuzzyNOT($tmparr) :$this->_FuzzyAND($tmparr);
|
||||
$rule=substr($rule,0,$pos-1).$value1.substr($rule,$pos+$len+1);
|
||||
}
|
||||
|
||||
$items=preg_split("/\s+/",$rule);
|
||||
$operation='and';
|
||||
$firstop = array_shift($items);
|
||||
$outitem = array_pop($items);
|
||||
$tmparr=array();
|
||||
foreach($items as $item) {
|
||||
$inp=strtolower($item);
|
||||
if (($inp=='or') or ($inp=='and') or ($inp=='not')) $operation=$inp;
|
||||
elseif (($inp=='then') or ($inp=='for')) continue;
|
||||
else {
|
||||
// split names
|
||||
list($inputName,$memberName) = preg_split("/\./",$item);
|
||||
// get value from FOutputs
|
||||
$mem_idx = $this->getMembersIndex($inputName,$memberName);
|
||||
$tmparr[] =$this->FOutputs[$inputName][$mem_idx];
|
||||
}
|
||||
}
|
||||
$value1 = ($operation == 'or') ? $this->_FuzzyOR($tmparr) :
|
||||
($operation == 'not') ? $this->_FuzzyNOT($tmparr) :$this->_FuzzyAND($tmparr);
|
||||
|
||||
return array($outitem,$value1);
|
||||
}
|
||||
|
||||
} //class Rules
|
||||
|
||||
class Fuzzy_Logic extends Rules {
|
||||
|
||||
protected $FuzzyTable = NULL;
|
||||
public $StateOutput = array();
|
||||
protected $AgregatePoints = 100;
|
||||
/*
|
||||
* Clear all solutions arrays in class and next calculations is Ready
|
||||
* example :
|
||||
* $this->clearSolution();
|
||||
* @param none
|
||||
* return none
|
||||
*/
|
||||
private function clearSolution() {
|
||||
$this->FXValues = array();
|
||||
$this->FYValues = array();
|
||||
}
|
||||
|
||||
/**
|
||||
* Set protected properties FuzzyTable
|
||||
* example :
|
||||
* $x->setFuzzyTable(array(
|
||||
* // IF input1 AND input2 Then Output
|
||||
* // For OR use pair input1 , NULL
|
||||
* // NULL , input 2
|
||||
* // ------ ------- -------
|
||||
* array('adequate', NULL , 'low'),
|
||||
* array(NULL , 'small' , 'low'),
|
||||
* array('marginal', 'large' , 'normal'),
|
||||
* array('inadequate' , NULL , 'high'),
|
||||
* ));
|
||||
* @param array
|
||||
* return none
|
||||
**/
|
||||
|
||||
|
||||
public function setFuzzyTable($A = array()) {
|
||||
$this->FuzzyTable = $A;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set Real Input Value @param2 for Input named @param1
|
||||
* example :
|
||||
* $fuzzy->setRealInput('input1',0.23);
|
||||
* @param1 string $idx
|
||||
* @param2 float $X
|
||||
* return none
|
||||
**/
|
||||
|
||||
public function setRealInput($idx,$X = 0.0) {
|
||||
$this->FRealInput[$idx] = $X;
|
||||
$this->FOutputs[$idx] = array();
|
||||
For ($i=0;$i<count($this->members[$idx]);$i++) {
|
||||
$this->FOutputs[$idx][] = $this->members[$idx][$i]->Fuzzification($this->FRealInput[$idx]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set Input Range @param2 for Input named @param1
|
||||
* example :
|
||||
* $fuzzy->setInputRange('input1',array(0,1));
|
||||
* @param1 string $idx
|
||||
* @param2 array $range
|
||||
* return none
|
||||
**/
|
||||
|
||||
public function setInputRange($idx,$range = array(0, 1)) {
|
||||
$this->FInputRange[$idx] = $range;
|
||||
}
|
||||
|
||||
/*
|
||||
* Agregate All Rules Result for Defuzification
|
||||
* example :
|
||||
* $fuzzy->fuzzyAgregate($outname,$Member,$AlphaCut=0.0)
|
||||
* @param string $output_name
|
||||
* @param object $member_object
|
||||
* @param float $calculate_rule_value
|
||||
* return none
|
||||
*/
|
||||
|
||||
public function fuzzyAgregate($outname,$Member,$AlphaCut=0.0) {
|
||||
foreach($this->FXValues[$outname] as $index=>$pointX) {
|
||||
if ($pointX<$Member->FA) continue;
|
||||
if ($pointX>$Member->FB) break;
|
||||
$ms = $Member->Fuzzification($pointX);
|
||||
$mem_val = min($ms,$AlphaCut);
|
||||
$this->FYValues[$outname][$index] = max($this->FYValues[$outname][$index],$mem_val);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Calculate Defuzification Fuzzy Result for method AVG (required set FuzzyTable)
|
||||
* example :
|
||||
* $fuzzy->calcFuzzy()
|
||||
* @param none
|
||||
* return array of outputs values (no associated keys)
|
||||
*/
|
||||
|
||||
public function calcFuzzyAlt() {
|
||||
$MaxAverage = 0;
|
||||
$this->clearSolution();
|
||||
//$count_inputs = count($this->InputNames);
|
||||
$sum = 0;
|
||||
$tmpx=array();
|
||||
$sum = array();
|
||||
$cnt = array();
|
||||
// fill output agregate table
|
||||
foreach($this->getOutputNames() as $outname) {
|
||||
$AgregateDeltaX = ($this->FMax[$outname]-$this->FMin[$outname])/$this->AgregatePoints;
|
||||
$this->FXValues[$outname] = Range($this->FMin[$outname],$this->FMax[$outname],$AgregateDeltaX);
|
||||
$this->FYValues[$outname] = array_fill ( 0 , count($this->FXValues[$outname]), 0.0 );
|
||||
}
|
||||
|
||||
foreach ($this->FuzzyTable as $row_idx => $line_rule) {
|
||||
$sum = 0.0;
|
||||
$cnt = 0.0;
|
||||
$count_inputs = count($line_rule)-1; // last is output
|
||||
foreach ($line_rule as $col => $member_name) {
|
||||
$out_idx =$col - $count_inputs;
|
||||
$outname = $this->getOutputName($out_idx);
|
||||
if (!is_null($member_name)) {
|
||||
|
||||
if ($col<$count_inputs) { // is input
|
||||
$inp_name = $this->getInputName($col);
|
||||
$mem_idx = $this->getMembersIndex($inp_name,$member_name);
|
||||
$val =$this->FOutputs[$inp_name][$mem_idx]; // get members value
|
||||
if ($val>0) {
|
||||
$sum+=$val; // sum members values
|
||||
$cnt++;
|
||||
} else {
|
||||
//$sum=0;
|
||||
//$cnt=0;
|
||||
break;
|
||||
}
|
||||
} else { //is output
|
||||
|
||||
$member=$this->getMemberByName($outname,$member_name); // get OUTPUT member
|
||||
if ($cnt == 0) $avg_sum = 0; else $avg_sum = $sum/$cnt;
|
||||
$this->StateOutput[$member_name] = $avg_sum;
|
||||
if ($avg_sum>0) $this->fuzzyAgregate($outname,$member,$avg_sum);
|
||||
$sum = 0.0;
|
||||
$cnt = 0.0;
|
||||
}
|
||||
} // if $member_name
|
||||
} // foreach rule
|
||||
} // foreach rule_row
|
||||
|
||||
$result = array();
|
||||
|
||||
foreach($this->getOutputNames() as $outname) {
|
||||
$suma=0.0;
|
||||
$sumb=0.0;
|
||||
|
||||
foreach($this->FXValues[$outname] as $id=>$x) {
|
||||
$y=$this->FYValues[$outname][$id];
|
||||
if ($y>0) {
|
||||
$suma+=($x*$y);
|
||||
$sumb+=$y;
|
||||
}
|
||||
}
|
||||
if ($sumb == 0) $result[]= 0; else $result[] = $suma/$sumb;
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
/*
|
||||
* Calculate Defuzification Fuzzy Result for method MIN,MAX (required set Rules)
|
||||
* example :
|
||||
* $fuzzy->calcFuzzyAlt()
|
||||
* @param none
|
||||
* return array of outputs values (associated keys)
|
||||
*/
|
||||
|
||||
public function calcFuzzy() {
|
||||
$this->clearSolution();
|
||||
|
||||
$sum = 0;
|
||||
$tmpx=array();
|
||||
$sum = array();
|
||||
$cnt = array();
|
||||
// fill output agregate table
|
||||
foreach($this->getOutputNames() as $outname) {
|
||||
$AgregateDeltaX = ($this->FMax[$outname]-$this->FMin[$outname])/$this->AgregatePoints;
|
||||
$this->FXValues[$outname] = Range($this->FMin[$outname],$this->FMax[$outname],$AgregateDeltaX);
|
||||
$this->FYValues[$outname] = array_fill ( 0 , count($this->FXValues[$outname]), 0.0 );
|
||||
}
|
||||
|
||||
$rules=$this->getRules();
|
||||
foreach ($rules as $key=>$rule) {
|
||||
list($outItem,$value) = $this->processRule($rule);
|
||||
list($outputName,$memberName) = preg_split("/\./",$outItem);
|
||||
$this->StateOutput[$memberName] = $value;
|
||||
$member=$this->getMemberByName($outputName,$memberName); // get OUTPUT member
|
||||
if ($value>0) $this->fuzzyAgregate($outputName,$member,$value);
|
||||
}
|
||||
|
||||
$result = array();
|
||||
|
||||
foreach($this->getOutputNames() as $outname) {
|
||||
$suma=0.0;
|
||||
$sumb=0.0;
|
||||
|
||||
foreach($this->FXValues[$outname] as $id=>$x) {
|
||||
$y=$this->FYValues[$outname][$id];
|
||||
if ($y>0) {
|
||||
$suma+=($x*$y);
|
||||
$sumb+=$y;
|
||||
}
|
||||
}
|
||||
if ($sumb == 0) $result[$outname]= 0; else $result[$outname] = $suma/$sumb;
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
} //class
|
||||
|
||||
?>
|
||||
Arquivo binário não exibido.
|
Depois Largura: | Altura: | Tamanho: 59 KiB |
+1106
Diferenças do arquivo suprimidas por serem muito extensas
Carregar Diff
Referência em uma Nova Issue
Bloquear um usuário