📄 rule.cpp
字号:
//-------------------------------------------------------------------
// Author........: Aleksander 豩rn
// Date..........:
// Description...:
// Revisions.....:
//===================================================================
#include <stdafx.h> // Precompiled headers.
#include <copyright.h>
#include <kernel/structures/rule.h>
#include <kernel/structures/reduct.h>
#include <kernel/structures/decisiontable.h>
#include <kernel/structures/informationvector.h>
#include <kernel/utilities/mathkit.h>
#include <kernel/utilities/iokit.h>
#include <kernel/utilities/discerner.h>
#include <kernel/basic/interval.h>
//-------------------------------------------------------------------
// Static methods (file scope).
//===================================================================
//-------------------------------------------------------------------
// Method........: StaticLookup
// Author........:
// Date..........:
// Description...: Looks up a cardinality for a given decision,
// returns the cardinality in-place.
// Comments......: Simple linear implementation.
// Revisions.....:
//===================================================================
static bool
StaticLookup(int decision, const Vector(int) &decisions, const Vector(int) &cardinalities, int &cardinality) {
int i;
// Lookup.
for (i = 0; i < decisions.size(); i++) {
if (decisions[i] == decision)
break;
}
// Not found?
if (i == decisions.size())
return false;
// Return in-place.
cardinality = cardinalities[i];
return true;
}
//-------------------------------------------------------------------
// Method........: StaticFormatNumber
// Author........:
// Date..........:
// Description...: Used by StaticFormatPrologInterval.
// Comments......:
// Revisions.....:
//===================================================================
static String
StaticFormatNumber(float number) {
String formatted = String::Format(number);
// No special formatting needed?
if (!formatted.Contains('.'))
return formatted;
int n = formatted.GetLength();
// Delete all trailing zeros after the decimal point.
while (n > 0 && formatted[n - 1] == '0') {
formatted[n - 1] = '\0';
n--;
}
// Format "129.0" as "129".
if (formatted[n - 1] == '.')
formatted[n - 1] = '\0';
// Did we delete the whole string?
if (n == 1)
formatted = String("0");
return formatted;
}
//-------------------------------------------------------------------
// Method........: StaticFormatPrologInterval
// Author........:
// Date..........:
// Description...: Used by Rule::FormatProlog.
// Comments......:
// Revisions.....:
//===================================================================
static String
StaticFormatPrologInterval(const String &variablename, const Interval &interval, const String &indent) {
char lower_delimiter = interval.GetLowerDelimiter();
char upper_delimiter = interval.GetUpperDelimiter();
float lower_value = interval.GetLowerValue();
float upper_value = interval.GetUpperValue();
bool lower_is_infinity = (lower_value == -FLT_MAX);
bool upper_is_infinity = (upper_value == FLT_MAX);
String formatted;
// Don't write "infinity" values.
if (!lower_is_infinity) {
String lower_value_formatted = StaticFormatNumber(lower_value);
if (lower_delimiter == Interval::From())
formatted += indent + variablename + " > " + lower_value_formatted;
else
formatted += indent + variablename + " >= " + lower_value_formatted;
}
if (!lower_is_infinity && !upper_is_infinity)
formatted += ",\n";
// Don't write "infinity" values.
if (!upper_is_infinity) {
String upper_value_formatted = StaticFormatNumber(upper_value);
if (upper_delimiter == Interval::To())
formatted += indent + variablename + " < " + upper_value_formatted;
else
formatted += indent + variablename + " <= " + upper_value_formatted;
}
return formatted;
}
//-------------------------------------------------------------------
// Methods for class Rule.
//===================================================================
//-------------------------------------------------------------------
// Constructors/destructor.
//===================================================================
//-------------------------------------------------------------------
// Method........: Copy constructor
// Author........:
// Date..........:
// Description...:
// Comments......:
// Revisions.....:
//===================================================================
Rule::Rule(const Rule &/*in*/) {
}
//-------------------------------------------------------------------
// Method........: Constructor
// Author........:
// Date..........:
// Description...:
// Comments......:
// Revisions.....:
//===================================================================
Rule::Rule() {
}
//-------------------------------------------------------------------
// Method........: Destructor
// Author........:
// Date..........:
// Description...:
// Comments......: Be careful of "Handle loops", as this may cause
// memory leaks!
// Revisions.....:
//===================================================================
Rule::~Rule() {
}
//-------------------------------------------------------------------
// Methods inherited from Identifier.
//===================================================================
IMPLEMENTIDMETHODS(Rule, RULE, Structure)
//-------------------------------------------------------------------
// Methods inherited from Persistent
//===================================================================
//------------------------------------------------------------------
// Method........: Load
// Author........: Aleksander 豩rn
// Date..........:
// Description...:
// Comments......:
// Revisions.....:
//===================================================================
bool
Rule::Load(ifstream &stream) {
Clear();
int i, a, v, n, s;
if (!IOKit::Load(stream, n))
return false;
if (!ReserveLHS(n))
return false;
for (i = 0; i < n; i++) {
if (!IOKit::Load(stream, a) || !IOKit::Load(stream, v))
return false;
if (!AppendConditionDescriptor(a, v))
return false;
}
if (!IOKit::Load(stream, s) || !SetSupport(s))
return false;
if (!IOKit::Load(stream, a) || !SetDecisionAttribute(a))
return false;
if (!IOKit::Load(stream, n))
return false;
if (!ReserveRHS(n))
return false;
for (i = 0; i < n; i++) {
if (!IOKit::Load(stream, v) || !IOKit::Load(stream, s))
return false;
if (!AppendDecisionValue(v, s))
return false;
}
return true;
}
//------------------------------------------------------------------
// Method........: Save
// Author........: Aleksander 豩rn
// Date..........:
// Description...:
// Comments......:
// Revisions.....:
//===================================================================
bool
Rule::Save(ofstream &stream) const {
if (!IOKit::Save(stream, GetNoConditionDescriptors()))
return false;
int i;
for (i = 0; i < GetNoConditionDescriptors(); i++) {
if (!IOKit::Save(stream, GetConditionAttribute(i)))
return false;
if (!IOKit::Save(stream, GetConditionValue(i)))
return false;
}
if (!IOKit::Save(stream, GetSupport()))
return false;
if (!IOKit::Save(stream, GetDecisionAttribute()))
return false;
if (!IOKit::Save(stream, GetNoDecisionValues()))
return false;
for (i = 0; i < GetNoDecisionValues(); i++) {
if (!IOKit::Save(stream, GetDecisionValue(i)))
return false;
if (!IOKit::Save(stream, GetSupport(i)))
return false;
}
if (!IOKit::Save(stream, '\n'))
return false;
return true;
}
//-------------------------------------------------------------------
// Decision value management.
//===================================================================
//-------------------------------------------------------------------
// Method........: GetDominatingDecisionValue
// Author........: Aleksander 豩rn
// Date..........:
// Description...: Returns the dominating decision value (i.e. the
// decision value with the highest associated support
// count), and returns in-place both the support and
// the position index of this.
//
// Ties are resolved arbitrarily.
// Comments......:
// Revisions.....:
//===================================================================
int
Rule::GetDominatingDecisionValue(int &support, int &position_no) const {
int i, no_decision_values = GetNoDecisionValues();
// No decision values ?
if (no_decision_values == 0) {
// Return error values.
support = Undefined::Integer();
position_no = Undefined::Integer();
return Undefined::Integer();
}
int dominating = GetDecisionValue(0);
support = GetSupport(0);
position_no = 0;
for (i = 1; i < no_decision_values; i++) {
int current = GetSupport(i);
if (current > support) {
support = current;
position_no = i;
dominating = GetDecisionValue(i);
}
}
return dominating;
}
//-------------------------------------------------------------------
// Method........: GetAccuracy
// Author........: Aleksander 豩rn
// Date..........:
// Description...: An estimate of Pr(RHS(i) | LHS).
// Comments......:
// Revisions.....:
//===================================================================
float
Rule::GetAccuracy(int position_no) const {
int i, no_decision_values = GetNoDecisionValues();
// Safe-guard to avoid numerical quirks.
if ((position_no == 0) && (no_decision_values == 1))
return 1.0;
double term = 0.0;
double sum = 0.0;
for (i = 0; i < no_decision_values; i++) {
int support = GetSupport(i);
if (i == position_no)
term = support;
sum += support;
}
return (term / sum);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -