📄 decisiontable.cpp
字号:
// Comments......:
// Revisions.....:
//===================================================================
bool
DecisionTable::SwapAttributes(int i, int j, bool masked) {
if (i == j)
return true;
// Does the decision table have any children?
if (HasChildren()) {
Message::Error("Cannot swap attributes, the decision table has children.");
return false;
}
int no_objects = GetNoObjects(false);
int unmasked_i;
int unmasked_j;
if (masked) {
unmasked_i = GetUnmaskedAttribute(i);
unmasked_j = GetUnmaskedAttribute(j);
}
else {
unmasked_i = i;
unmasked_j = j;
}
int k;
for (k = 0; k < no_objects; k++) {
int tmp = GetEntry(k, unmasked_i, false);
if (!SetEntry(k, unmasked_i, GetEntry(k, unmasked_j, false), false))
return false;
if (!SetEntry(k, unmasked_j, tmp, false))
return false;
}
// Swap attributes in dictionary, if present.
if (HasDictionary() && !GetDictionary()->SwapAttributes(unmasked_i, unmasked_j))
return false;
bool swap_ok = true;
// Swap attribute status fields.
Status tmp_status = GetStatus(i, masked);
if (!SetStatus(i, GetStatus(j, masked), masked))
swap_ok = false;
if (swap_ok && !SetStatus(j, tmp_status, masked))
swap_ok = false;
if (!swap_ok)
Message::Error("Attribute status fields not swapped.");
swap_ok = true;
// Swap attribute masks.
Mask tmp_mask = GetAttributeMask(unmasked_i);
if (!SetAttributeMask(unmasked_i, GetAttributeMask(unmasked_j)))
swap_ok = false;
if (swap_ok && !SetAttributeMask(unmasked_j, tmp_mask))
swap_ok = false;
if (!swap_ok)
Message::Error("Attribute masks not swapped.");
return true;
}
//-------------------------------------------------------------------
// Method........: InsertAttribute
// Author........: Aleksander 豩rn
// Date..........:
// Description...: Handles the dictionary part of attribute insertion.
// Can only be called from subclasses, since this
// method is abstract.
// Comments......:
// Revisions.....:
//===================================================================
bool
DecisionTable::InsertAttribute(int attribute_no, const Attribute *attribute, bool masked) {
int unmasked;
if (masked)
unmasked = GetUnmaskedAttribute(attribute_no);
else
unmasked = attribute_no;
// If there is no dictionary present and an attribute is supplied, something's wrong.
if (!HasDictionary() && (attribute != NULL)) {
Message::Error("There is no dictionary to insert the attribute in.");
return false;
}
// If there is no dictionary and no attribute is supplied, we're done.
if (!HasDictionary() && (attribute == NULL))
return true;
// If there is a dictionary present and no dictionary attribute is given, create a default one.
if (HasDictionary() && (attribute == NULL))
return GetDictionary()->InsertAttribute(Creator::IntegerAttribute(), unmasked);
return GetDictionary()->InsertAttribute(attribute, unmasked);
}
//-------------------------------------------------------------------
// Method........: AppendAttribute
// Author........: Aleksander 豩rn
// Date..........:
// Description...: Default implementation.
// Comments......: Ignores masking (irrelevant anyway for an append).
// Revisions.....:
//===================================================================
bool
DecisionTable::AppendAttribute(const Attribute *attribute, bool /*masked*/) {
return InsertAttribute(GetNoAttributes(false), attribute, false);
}
//-------------------------------------------------------------------
// Method........: RemoveAttribute
// Author........: Aleksander 豩rn
// Date..........:
// Description...: Handles the dictionary part of attribute removal.
// Can only be called from subclasses, since this
// method is abstract.
// Comments......:
// Revisions.....:
//===================================================================
bool
DecisionTable::RemoveAttribute(int attribute_no, bool masked) {
if (!HasDictionary())
return true;
int unmasked;
if (masked)
unmasked = GetUnmaskedAttribute(attribute_no);
else
unmasked = attribute_no;
// Remove dictionary attribute.
return GetDictionary()->RemoveAttribute(unmasked);
}
//-------------------------------------------------------------------
// Attribute status methods.
//===================================================================
//-------------------------------------------------------------------
// Method........: IsCondition
// Author........: Aleksander 豩rn
// Date..........:
// Description...:
// Comments......:
// Revisions.....:
//===================================================================
bool
DecisionTable::IsCondition(int attribute_no, bool masked) const {
return (GetStatus(attribute_no, masked) == STATUS_CONDITION);
}
//-------------------------------------------------------------------
// Method........: IsDecision
// Author........: Aleksander 豩rn
// Date..........:
// Description...:
// Comments......:
// Revisions.....:
//===================================================================
bool
DecisionTable::IsDecision(int attribute_no, bool masked) const {
return (GetStatus(attribute_no, masked) == STATUS_DECISION);
}
//-------------------------------------------------------------------
// Method........: GetDecisionAttribute
// Author........: Aleksander 豩rn
// Date..........:
// Description...: Returns the index of the attribute that is marked
// as the decision attribute. If more than one
// attribute has this marking, then the index of the
// first one encountered is returned. If no attribute
// has this marking, Undefined::Integer() is returned.
// Comments......:
// Revisions.....:
//===================================================================
int
DecisionTable::GetDecisionAttribute(bool masked) const {
int i, no_attributes = GetNoAttributes(masked);
// Loop backwards, since it's likely that the decision is at the end.
for (i = no_attributes - 1; i >= 0; i--) {
if (IsDecision(i, masked))
return i;
}
return Undefined::Integer();
}
//-------------------------------------------------------------------
// Attribute range methods.
//===================================================================
//-------------------------------------------------------------------
// Method........: GetValueSet
// Author........: Aleksander 豩rn
// Date..........:
// Description...: Returns (in-place) a vector of the values the
// given attribute takes on in the table, and their
// cardinalities.
// Comments......:
// Revisions.....:
//===================================================================
bool
DecisionTable::GetValueSet(Vector(int) &values, Vector(int) &cardinalities, int attribute_no, bool masked) const {
// Clear current contents.
values.erase(values.begin(), values.end());
cardinalities.erase(cardinalities.begin(), cardinalities.end());
// Do a sanity check.
if (attribute_no < 0 || attribute_no >= GetNoAttributes(masked))
return false;
int i, no_objects = GetNoObjects(masked);
// Make a convenient typedef.
typedef Map(int, int) EntryMap;
EntryMap entrymap;
// Fill the map.
for (i = 0; i < no_objects; i++) {
// Get entry value.
int entry = GetEntry(i, attribute_no, masked);
EntryMap::iterator iterator = entrymap.find(entry);
// Update map.
if (iterator == entrymap.end())
entrymap.insert(Pair(const int, int)(entry, 1));
else
(*iterator).second++;
}
// Reserve space to minimize allocations.
values.reserve(entrymap.size());
cardinalities.reserve(entrymap.size());
// This should be a const_iterator, but VC++ 6.0 won't let me...
EntryMap::iterator iterator = entrymap.begin();
// Fill the vectors.
while (!(iterator == entrymap.end())) {
// Get (entry, cardinality) pair.
int entry = (*iterator).first;
int cardinality = (*iterator).second;
// Update vectors.
values.push_back(entry);
cardinalities.push_back(cardinality);
iterator++;
}
return true;
}
//-------------------------------------------------------------------
// Missing values querying methods.
//===================================================================
//-------------------------------------------------------------------
// Method........: IsMissing
// Author........: Aleksander 豩rn
// Date..........:
// Description...: Returns true if the specified entry is marked as
// missing.
// Comments......:
// Revisions.....:
//===================================================================
bool
DecisionTable::IsMissing(int object_no, int attribute_no, bool masked) const {
return (GetEntry(object_no, attribute_no, masked) == Undefined::Integer());
}
//-------------------------------------------------------------------
// Method........: HasMissingEntries
// Author........: Aleksander 豩rn
// Date..........:
// Description...: Returns true if the decision table contains any
// missing values.
// Comments......:
// Revisions.....:
//===================================================================
bool
DecisionTable::HasMissingEntries(bool masked) const {
int i, no_attributes = GetNoAttributes(masked);
for (i = 0; i < no_attributes; i++) {
if (HasMissingEntries(i, masked))
return true;
}
return false;
}
//-------------------------------------------------------------------
// Method........: HasMissingEntries
// Author........: Aleksander 豩rn
// Date..........:
// Description...: Returns true if the specified attribute (i.e.
// column in the decision table) contains any
// missing values.
// Comments......:
// Revisions.....:
//===================================================================
bool
DecisionTable::HasMissingEntries(int attribute_no, bool masked) const {
int i, no_objects = GetNoObjects(masked);
for (i = 0; i < no_objects; i++) {
if (IsMissing(i, attribute_no, masked))
return true;
}
return false;
}
//-------------------------------------------------------------------
// Dictionary (meta-data) methods.
//===================================================================
//-------------------------------------------------------------------
// Method........: SetDictionary
// Author........: Aleksander 豩rn
// Date..........:
// Description...: Assigns a new dictionary to the decision table.
// No dimensionality checks are performed.
// Comments......:
// Revisions.....:
//===================================================================
bool
DecisionTable::SetDictionary(Dictionary *dictionary) {
dictionary_ = dictionary;
return true;
}
//-------------------------------------------------------------------
// Method........: GetDictionary
// Author........: Aleksander 豩rn
// Date..........:
// Description...: Returns a pointer to the associated dictionary.
// Comments......: Use judiciously, access the dictionary through the
// table instead.
// Revisions.....:
//===================================================================
Dictionary *
DecisionTable::GetDictionary() const {
return const_cast(Dictionary *, dictionary_.GetPointer());
}
//-------------------------------------------------------------------
// Method........: HasDictionary
// Author........: Aleksander 豩rn
// Date..........:
// Description...: Returns true if there is a dictionary associated
// with the decision table.
// Comments......:
// Revisions.....:
//===================================================================
bool
DecisionTable::HasDictionary() const {
return (GetDictionary() != NULL);
}
//-------------------------------------------------------------------
// Method........: GetAttributeName
// Author........: Aleksander 豩rn
// Date..........:
// Description...:
// Comments......:
// Revisions.....:
//===================================================================
const String &
DecisionTable::GetAttributeName(int attribute_no, bool masked) const {
// Static so we can return a reference.
static String dummy;
int unmasked;
if (masked)
unmasked = GetUnmaskedAttribute(attribute_no);
else
unmasked = attribute_no;
// Dictionary present?
if (!HasDictionary()) {
dummy = String::Format(unmasked);
return dummy;
}
return GetDictionary()->GetAttribute(unmasked)->GetName();
}
//-------------------------------------------------------------------
// Method........: SetAttributeName
// Author........: Aleksander 豩rn
// Date..........:
// Description...:
// Comments......:
// Revisions.....:
//===================================================================
bool
DecisionTable::SetAttributeName(int attribute_no, const String &name, bool masked) {
// No dictionary present.
if (!HasDictionary())
return false;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -