blob: 52e7e85cbf3042668695ee85a72a10b1480c6f0d (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
|
/*
fuzzylite (R), a fuzzy logic control library in C++.
Copyright (C) 2010-2017 FuzzyLite Limited. All rights reserved.
Author: Juan Rada-Vilela, Ph.D. <jcrada@fuzzylite.com>
This file is part of fuzzylite.
fuzzylite is free software: you can redistribute it and/or modify it under
the terms of the FuzzyLite License included with the software.
You should have received a copy of the FuzzyLite License along with
fuzzylite. If not, see <http://www.fuzzylite.com/license/>.
fuzzylite is a registered trademark of FuzzyLite Limited.
*/
#include "fl/activation/Lowest.h"
#include "fl/rule/RuleBlock.h"
#include "fl/rule/Rule.h"
#include "fl/Operation.h"
#include <queue>
namespace fl {
Lowest::Lowest(int numberOfRules) : Activation(), _numberOfRules(numberOfRules) { }
Lowest::~Lowest() { }
std::string Lowest::className() const {
return "Lowest";
}
std::string Lowest::parameters() const {
return Op::str(getNumberOfRules());
}
void Lowest::configure(const std::string& parameters) {
setNumberOfRules((int) Op::toScalar(parameters));
}
int Lowest::getNumberOfRules() const {
return this->_numberOfRules;
}
void Lowest::setNumberOfRules(int activatedRules) {
this->_numberOfRules = activatedRules;
}
Complexity Lowest::complexity(const RuleBlock* ruleBlock) const {
//Cost of priority_queue:
//http://stackoverflow.com/questions/2974470/efficiency-of-the-stl-priority-queue
Complexity result;
const TNorm* conjunction = ruleBlock->getConjunction();
const SNorm* disjunction = ruleBlock->getDisjunction();
const TNorm* implication = ruleBlock->getImplication();
Complexity meanFiring;
for (std::size_t i = 0; i < ruleBlock->numberOfRules(); ++i) {
const Rule* rule = ruleBlock->getRule(i);
result.comparison(2);
result += rule->complexityOfActivation(conjunction, disjunction);
meanFiring += rule->complexityOfFiring(implication);
}
meanFiring.divide(scalar(ruleBlock->numberOfRules()));
//Complexity of push is O(log n)
result += Complexity().function(1).multiply(ruleBlock->numberOfRules()
* std::log(scalar(ruleBlock->numberOfRules())));
result += Complexity().comparison(2).arithmetic(1).multiply(getNumberOfRules());
result += meanFiring.multiply(getNumberOfRules());
//Complexity of pop is 2 * O(log n)
result += Complexity().function(1).multiply(getNumberOfRules() *
2 * std::log(scalar(ruleBlock->numberOfRules())));
return result;
}
struct Ascending {
bool operator()(const Rule* a, const Rule* b) {
return a->getActivationDegree() > b->getActivationDegree();
}
};
void Lowest::activate(RuleBlock* ruleBlock) {
FL_DBG("Activation: " << className() << " " << parameters());
const TNorm* conjunction = ruleBlock->getConjunction();
const SNorm* disjunction = ruleBlock->getDisjunction();
const TNorm* implication = ruleBlock->getImplication();
std::priority_queue<Rule*, std::vector<Rule*>, Ascending> rulesToActivate;
for (std::size_t i = 0; i < ruleBlock->numberOfRules(); ++i) {
Rule* rule = ruleBlock->getRule(i);
rule->deactivate();
if (rule->isLoaded()) {
scalar activationDegree = rule->activateWith(conjunction, disjunction);
if (Op::isGt(activationDegree, 0.0))
rulesToActivate.push(rule);
}
}
int activated = 0;
while (rulesToActivate.size() > 0 and activated++ < _numberOfRules) {
Rule* rule = rulesToActivate.top();
rule->trigger(implication);
rulesToActivate.pop();
}
}
Lowest* Lowest::clone() const {
return new Lowest(*this);
}
Activation* Lowest::constructor() {
return new Lowest;
}
}
|