📄 reductcostfilter.cpp
字号:
//-------------------------------------------------------------------// Author........: Aleksander 豩rn// Date..........:// Description...:// Revisions.....://===================================================================#include <stdafx.h> // Precompiled headers.#include <copyright.h>#include <kernel/algorithms/reductcostfilter.h>#include <kernel/algorithms/keyword.h>#include <kernel/structures/reduct.h>#include <kernel/structures/reducts.h>#include <kernel/structures/decisiontable.h>#include <kernel/utilities/iokit.h>#include <kernel/utilities/mathkit.h>#include <kernel/basic/algorithm.h>#include <kernel/basic/message.h>#include <kernel/system/fstream.h>//-------------------------------------------------------------------// Methods for class ReductCostFilter.//===================================================================//-------------------------------------------------------------------// Constructors/destructor.//===================================================================ReductCostFilter::ReductCostFilter() { SetCostFilename(Undefined::String()); SetThreshold(100.0); SetDefaultCost(0.0); SetLogFilename(Undefined::String());}ReductCostFilter::~ReductCostFilter() {}//-------------------------------------------------------------------// Methods inherited from Identifier.//===================================================================IMPLEMENTIDMETHODS(ReductCostFilter, REDUCTCOSTFILTER, ReductFilter)//-------------------------------------------------------------------// Methods inherited from Algorithm.//===================================================================//-------------------------------------------------------------------// Method........: GetParameters// Author........: Aleksander 豩rn// Date..........:// Description...:// Comments......:// Revisions.....://===================================================================StringReductCostFilter::GetParameters() const { String parameters; // Cost, filename. parameters += Keyword::Cost() + Keyword::Dot() + Keyword::Filename(); parameters += Keyword::Assignment(); parameters += GetCostFilename(); parameters += Keyword::Separator(); // Default. parameters += Keyword::Default(); parameters += Keyword::Assignment(); parameters += String::Format(GetDefaultCost()); parameters += Keyword::Separator(); // Threshold. parameters += Keyword::Threshold(); parameters += Keyword::Assignment(); parameters += String::Format(GetThreshold()); parameters += Keyword::Separator(); // Log, filename. parameters += Keyword::Log() + Keyword::Dot() + Keyword::Filename(); parameters += Keyword::Assignment(); parameters += GetLogFilename(); parameters += Keyword::Separator(); return parameters + ReductFilter::GetParameters();}//-------------------------------------------------------------------// Method........: SetParameter// Author........: Aleksander 豩rn// Date..........:// Description...:// Comments......:// Revisions.....://===================================================================boolReductCostFilter::SetParameter(const String &keyword, const String &value) { // Cost, filename, if (keyword == Keyword::Cost() + Keyword::Dot() + Keyword::Filename()) return SetCostFilename(value); // Cost, filename (for backwards compatibility). if (keyword == Keyword::Filename()) return SetCostFilename(value); // Threshold. if (keyword == Keyword::Threshold() && value.IsFloat()) return SetThreshold(value.GetFloat()); // Default. if (keyword == Keyword::Default() && value.IsFloat()) return SetDefaultCost(value.GetFloat()); // Log, filename, if (keyword == Keyword::Log() + Keyword::Dot() + Keyword::Filename()) return SetLogFilename(value); return ReductFilter::SetParameter(keyword, value);}//-------------------------------------------------------------------// Method........: GetOutputFilenames// Author........: Aleksander 豩rn// Date..........:// Description...:// Comments......:// Revisions.....://===================================================================boolReductCostFilter::GetOutputFilenames(Vector(String) &filenames) const { if (!Algorithm::GetOutputFilenames(filenames)) return false; filenames.push_back(GetLogFilename()); return true;}//-------------------------------------------------------------------// Method........: Apply// Author........: Aleksander 豩rn// Date..........:// Description...:// Comments......:// Revisions.....://===================================================================Structure *ReductCostFilter::Apply(Structure &structure) const { // This method is conceptually const only. ReductCostFilter *self = const_cast(ReductCostFilter *, this); Handle<DecisionTable> table = dynamic_cast(DecisionTable *, structure.FindParent(DECISIONTABLE)); // Load cost information. if (!self->costs_.Load(GetCostFilename(), *table, GetDefaultCost())) { Message::Error("Failed to load cost information."); return NULL; } // Erase mutable bookkeeping stuff. (self->statistics_).erase((self->statistics_).begin(), (self->statistics_).end()); (self->rankings_).erase((self->rankings_).begin(), (self->rankings_).end()); (self->reducts_).erase((self->reducts_).begin(), (self->reducts_).end()); (self->statistics_).reserve(structure.GetNoStructures()); (self->rankings_).reserve(structure.GetNoStructures()); (self->reducts_).reserve(structure.GetNoStructures()); // Do the filtering. Handle<Structure> result = Filter::Apply(structure); // Save log, calculate and print statistics. if (!self->SaveLog(*table)) Message::Warning("Failed to save log file."); // Clean up in general. (self->statistics_).erase((self->statistics_).begin(), (self->statistics_).end()); (self->rankings_).erase((self->rankings_).begin(), (self->rankings_).end()); (self->reducts_).erase((self->reducts_).begin(), (self->reducts_).end()); return result.Release();}//-------------------------------------------------------------------// Methods inherited from Filter.//===================================================================//-------------------------------------------------------------------// Method........: Remove// Author........: Aleksander 豩rn// Date..........:// Description...: Returns true if the specified reduct should be removed// from the reduct set.// Comments......:// Revisions.....://===================================================================boolReductCostFilter::Remove(const Structures &structures, int i) const { if (!structures.IsA(REDUCTS)) return false; Handle<Reducts> reducts = dynamic_cast(Reducts *, const_cast(Structures *, &structures)); Handle<Reduct> reduct = reducts->GetReduct(i); // Compute total cost. float cost = costs_.GetCost(*reduct); String formatted; bool masked = true; // Format reduct. if (!reduct->Format(formatted, dynamic_cast(DecisionTable *, reducts->FindParent(DECISIONTABLE)), masked)) formatted = Undefined::String(); // Update bookkeeping structures. ReductCostFilter *self = const_cast(ReductCostFilter *, this); // Update bookkeeping structures. (self->statistics_).push_back(cost); (self->rankings_).push_back(std::make_pair(i, cost)); (self->reducts_).push_back(ISPair(i, formatted) /* std::make_pair(i, formatted) */); // Return removal decision. return (cost > GetThreshold());}//-------------------------------------------------------------------// Local methods.//===================================================================//-------------------------------------------------------------------// Method........: SaveLog// Author........: Aleksander 豩rn// Date..........:// Description...:// Comments......:// Revisions.....://===================================================================boolReductCostFilter::SaveLog(const DecisionTable &table) const { // Compute statistics. float mean = MathKit::Mean(statistics_); float median = MathKit::Median(statistics_); float stddev = MathKit::StandardDeviation(statistics_); float minimum = MathKit::Minimum(statistics_); float maximum = MathKit::Maximum(statistics_); Message message; // Output to user. message.Notify("Cost.Mean = " + (mean == Undefined::Float() ? Undefined::String() : String::Format(mean))); message.Notify("Cost.Median = " + (median == Undefined::Float() ? Undefined::String() : String::Format(median))); message.Notify("Cost.StdDev = " + (stddev == Undefined::Float() ? Undefined::String() : String::Format(stddev))); message.Notify("Cost.Minimum = " + (minimum == Undefined::Float() ? Undefined::String() : String::Format(minimum))); message.Notify("Cost.Maximum = " + (maximum == Undefined::Float() ? Undefined::String() : String::Format(maximum))); ofstream stream; if (!IOKit::Open(stream, GetLogFilename())) { Message::Error("Failed to open " + GetLogFilename() + "."); return false; } bool masked = true; // Save log header. stream << "% Output from ROSETTA, " + SystemKit::GetUser() + " " + SystemKit::GetTimestamp() << endl; stream << "%" << endl; stream << "% " + IdHolder::GetClassname(GetId()) << endl; stream << "% {" + GetParameters() + "}" << endl; stream << "%" << endl; stream << "% Note that the indices below are 0-based." << endl; stream << "%" << endl; int i, longest = 0; for (i = 0; i < table.GetNoAttributes(masked); i++) { /* if (costs_.GetCost(i) == GetDefaultCost()) continue; */ String name = table.GetAttributeName(i, masked); if (name.GetLength() > longest) longest = name.GetLength(); } for (i = 0; i < table.GetNoAttributes(masked); i++) { /* if (costs_.GetCost(i) == GetDefaultCost()) continue; */ String name = table.GetAttributeName(i, masked); name = "Cost(" + name + ")"; name.Pad(' ', longest + 6); stream << "% " << name << " = " << costs_.GetCost(i) << endl; } stream << endl; // Save cost statistics. stream << "Cost.Mean = " << (mean == Undefined::Float() ? Undefined::String() : String::Format(mean)) << endl; stream << "Cost.Median = " << (median == Undefined::Float() ? Undefined::String() : String::Format(median)) << endl; stream << "Cost.StdDev = " << (stddev == Undefined::Float() ? Undefined::String() : String::Format(stddev)) << endl; stream << "Cost.Minimum = " << (minimum == Undefined::Float() ? Undefined::String() : String::Format(minimum)) << endl; stream << "Cost.Maximum = " << (maximum == Undefined::Float() ? Undefined::String() : String::Format(maximum)) << endl << endl; // We need to update (sort) the mutable bookkeeping stuff. ReductCostFilter *self = const_cast(ReductCostFilter *, this); IFPairCompareSecondDescending comparator1; ISPairCompareFirstAscending comparator2; message.Notify("Sorting costs..."); // Sort rankings and formatted reducts. std::sort((self->rankings_).begin(), (self->rankings_).end(), comparator1); std::sort((self->reducts_).begin(), (self->reducts_).end(), comparator2); message.Notify("Saving costs to log..."); // Save rankings. for (i = 0; i < rankings_.size(); i++) { int index = rankings_[i].first; float value = rankings_[i].second; String formatted_i; String formatted_v; String formatted_r; // Format output. formatted_i = "Reduct #" + String::Format(index); formatted_v = (value == Undefined::Float()) ? Undefined::String() : String::Format(value); formatted_v.Pad(' ', 11); formatted_r = reducts_[index].second; // Save to stream. stream << formatted_v << formatted_i << " = " << formatted_r << endl; } return true;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -