⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 decisiontable.cpp

📁 粗糙集应用软件
💻 CPP
📖 第 1 页 / 共 5 页
字号:
	// Get integral contents.
	int value = GetEntry(object_no, attribute_no, masked);

	// If we don't want to or cannot use the dictionary, return the integral contents themselves.
	if (!HasDictionary() || !use_dictionary) {
		if (value == Undefined::Integer())
			return Undefined::String();
		dummy = String::Format(value);
		return dummy;
	}

	int unmasked;

	if (masked)
		unmasked = GetUnmaskedAttribute(attribute_no);
	else
		unmasked = attribute_no;

	return GetDictionary()->GetEntry(unmasked, value);

}

//-------------------------------------------------------------------
// Method........: GetEntry
// Author........: Aleksander 豩rn
// Date..........:
// Description...: Returns a requested table entry, mapped (both ways)
//                 through the associated dictionary.
//
//                 Ineffiecient (but occasionally convenient) way of
//                 getting an entry, allowing e.g. constructs like:
//
//                   if (table->GetEntry(4, "color") == "blue") {
//                     ...
//                   }
//
// Comments......: Could be made faster by eliminating the attribute
//                 index search by introducing an index cache.
// Revisions.....:
//===================================================================

const String &
DecisionTable::GetEntry(int object_no, const String &attribute_name, bool masked) const {

	// Is a dictionary present?
	if (dictionary_ == NULL)
		return Undefined::String();

  bool case_sensitive = true;

	// Get the specified attribute.  If names are non-unique, return the first match found.
	int attribute_no = GetAttributeIndex(attribute_name, case_sensitive, masked);

	// Was a matching attribute not found?
	if (attribute_no == Undefined::Integer())
		return Undefined::String();

	// Get the integral table entry.
	int entry = GetEntry(object_no, attribute_no, masked);

	int unmasked;

	if (masked)
		unmasked = GetUnmaskedAttribute(attribute_no);
	else
		unmasked = attribute_no;

	// Return the entry, mapped through the dictionary.
	return dictionary_->GetEntry(unmasked, entry);

}

//-------------------------------------------------------------------
// Method........: SetEntry
// Author........: Aleksander 豩rn
// Date..........:
// Description...: Sets a specified table entry, mapped through the
//                 associated dictionary.
//
//                 Inefficient (but occasionally convenient) way of
//                 setting an entry, allowing e.g. constructs like:
//
//                   table->SetEntry(4, "color", "blue");
//
// Comments......: Could be made faster by eliminating the attribute
//                 index search by introducing an index cache.
// Revisions.....:
//===================================================================

bool
DecisionTable::SetEntry(int object_no, const String &attribute_name, const String &value, bool masked) {

	// Is a dictionary present?
	if (dictionary_ == NULL)
		return false;

  bool case_sensitive = true;

	// Get the specified attribute.  If names are non-unique, return the first match found.
	int attribute_no = GetAttributeIndex(attribute_name, case_sensitive, masked);

	// Was a matching attribute not found?
	if (attribute_no == Undefined::Integer())
		return false;

	// Is the entry deliberately set as undefined/missing?
	if (value == Undefined::String())
		return SetEntry(object_no, attribute_no, Undefined::Integer(), masked);

	int unmasked;

	if (masked)
		unmasked = GetUnmaskedAttribute(attribute_no);
	else
		unmasked = attribute_no;

	// Suggest an integral entry for the given textual value.
	int entry = dictionary_->SuggestEntry(unmasked, value);

	// Could a suggestion be made?
	if (entry == Undefined::Integer())
		return false;

	// Set dictionary entry.
	if (!dictionary_->SetEntry(unmasked, entry, value))
		return false;

	// Set integral table entry.
	if (!SetEntry(object_no, attribute_no, entry, masked))
		return false;

	return true;

}

//-------------------------------------------------------------------
// Method........: GetEntries
// Author........: Aleksander 豩rn
// Date..........:
// Description...: Returns (in-place) a vector representation of a
//                 table column. If specified, leaves out missing
//                 values.
// Comments......:
// Revisions.....:
//===================================================================

bool
DecisionTable::GetEntries(Vector(int) &entries, int attribute_no, bool masked, bool missing) const {

	// Is the index in range?
	if ((attribute_no < 0) || (attribute_no >= GetNoAttributes(masked)))
		return false;

	int i, no_objects = GetNoObjects(masked);

	entries.erase(entries.begin(), entries.end());
	entries.reserve(no_objects);

	// Extract values.
	for (i = 0; i < no_objects; i++) {
		if (!missing && IsMissing(i, attribute_no, masked))
			continue;
		entries.push_back(GetEntry(i, attribute_no, masked));
	}

	return true;

}

//-------------------------------------------------------------------
// Method........: GetEntries
// Author........: Aleksander 豩rn
// Date..........:
// Description...: Returns (in-place) vectors representation two table
//                 columns. If specified, leaves out values for objects
//                 that have a missing value for one of the columns
//                 specified.
// Comments......:
// Revisions.....:
//===================================================================

bool
DecisionTable::GetEntries(Vector(int) &entries1, Vector(int) &entries2, int attribute_no1, int attribute_no2, bool masked, bool missing) const {

	// Is the index in range?
	if ((attribute_no1 < 0) || (attribute_no1 >= GetNoAttributes(masked)))
		return false;

	if ((attribute_no2 < 0) || (attribute_no2 >= GetNoAttributes(masked)))
		return false;

	int i, no_objects = GetNoObjects(masked);

	entries1.erase(entries1.begin(), entries1.end());
	entries2.erase(entries2.begin(), entries2.end());

	entries1.reserve(no_objects);
	entries2.reserve(no_objects);

	// Extract values.
	for (i = 0; i < no_objects; i++) {
		if (!missing && (IsMissing(i, attribute_no1, masked) || IsMissing(i, attribute_no2, masked)))
			continue;
		entries1.push_back(GetEntry(i, attribute_no1, masked));
		entries2.push_back(GetEntry(i, attribute_no2, masked));
	}

	return true;

}

//-------------------------------------------------------------------
// Method........: GetEntries
// Author........: Aleksander 豩rn
// Date..........:
// Description...: Returns (in-place) a vector representation of a
//                 table column.  If specified, leaves out missing
//                 values and/or converts the value via a scaling
//                 exponent.
// Comments......:
// Revisions.....:
//===================================================================

bool
DecisionTable::GetEntries(Vector(float) &entries, int attribute_no, bool masked, bool missing, bool use_dictionary) const {

	// Is the index in range?
	if ((attribute_no < 0) || (attribute_no >= GetNoAttributes(masked)))
		return false;

	int i, no_objects = GetNoObjects(masked);

	entries.erase(entries.begin(), entries.end());
	entries.reserve(no_objects);

	// Extract values.
	for (i = 0; i < no_objects; i++) {
		if (!missing && IsMissing(i, attribute_no, masked))
			continue;
		entries.push_back(GetEntry(i, attribute_no, masked));
	}

	// We're done if the specified attribute is not a float attribute, or conversion is not wanted.
	if (!IsFloat(attribute_no, masked) || !use_dictionary)
		return true;

	return StaticRescaleEntries(entries, *this, attribute_no, masked);

}

//-------------------------------------------------------------------
// Method........: GetEntries
// Author........: Aleksander 豩rn
// Date..........:
// Description...: Returns (in-place) vectors representation two table
//                 columns. If specified, leaves out values for objects
//                 that have a missing value for one of the columns
//                 specified. Value can be converted via scaling
//                 exponents.
// Comments......:
// Revisions.....:
//===================================================================

bool
DecisionTable::GetEntries(Vector(float) &entries1, Vector(float) &entries2, int attribute_no1, int attribute_no2, bool masked, bool missing, bool use_dictionary) const {

	// Is the index in range?
	if ((attribute_no1 < 0) || (attribute_no1 >= GetNoAttributes(masked)))
		return false;

	if ((attribute_no2 < 0) || (attribute_no2 >= GetNoAttributes(masked)))
		return false;

	int i, no_objects = GetNoObjects(masked);

	entries1.erase(entries1.begin(), entries1.end());
	entries2.erase(entries2.begin(), entries2.end());

	entries1.reserve(no_objects);
	entries2.reserve(no_objects);

	// Extract values.
	for (i = 0; i < no_objects; i++) {
		if (!missing && (IsMissing(i, attribute_no1, masked) || IsMissing(i, attribute_no2, masked)))
			continue;
		entries1.push_back(GetEntry(i, attribute_no1, masked));
		entries2.push_back(GetEntry(i, attribute_no2, masked));
	}

	// Rescale entries via dictionary?
	if (IsFloat(attribute_no1, masked) && use_dictionary) {
		if (!StaticRescaleEntries(entries1, *this, attribute_no1, masked))
			return false;
	}

	if (IsFloat(attribute_no2, masked) && use_dictionary) {
		if (!StaticRescaleEntries(entries2, *this, attribute_no2, masked))
			return false;
	}

	return true;

}

//-------------------------------------------------------------------
// Method........: GetGeneralizedDecisions
// Author........: Aleksander 豩rn
// Date..........:
// Description...: Returns (in-place) the generalized decision value
//                 for each object.
//
// Comments......: Slightly suboptimal, but code reuse is given a
//                 higher priority than a marginal speed gain.
//
//                 For some unknown reason, the current compiler
//                 complains (deep down in STL) if I use a reference
//                 instead of a pointer for the vector of generalized
//                 decisions... Hmmf.
// Revisions.....:
//===================================================================

bool
DecisionTable::GetGeneralizedDecisions(GeneralizedDecision::Handles &decisions, const Discerner &discerner, bool masked) const {

	bool all         = false;
	int  cardinality = 0;
	int  names       = Undefined::Integer();

	IndiscernibilityGraph graph;

	return graph.Create(*this, masked, discerner, all, cardinality, names, &decisions);

}

//-------------------------------------------------------------------
// Row/column administration.
//===================================================================

//-------------------------------------------------------------------
// Method........: AppendObject
// Author........: Aleksander 豩rn
// Date..........:
// Description...:
// Comments......: Default implementation.
//
//                 Ignores the masking and appends to the very end
//                 of the table (the end is the end, regardless of
//                 the masking).  The masking argument is for
//                 interface completeness/uniformity reasons.
// Revisions.....:
//===================================================================

bool
DecisionTable::AppendObject(bool /*masked*/) {
	return InsertObject(GetNoObjects(false), false);
}

//-------------------------------------------------------------------
// Method........: SwapObjects
// Author........: Aleksander 豩rn
// Date..........:
// Description...: Swaps objects i and j in the table.  Swaps entries
//                 for all attributes (disabled or not) to avoid creating
//                 inconsistencies in the table.
// Comments......: Swapping of associated object masks not implemented.
// Revisions.....:
//===================================================================

bool
DecisionTable::SwapObjects(int i, int j, bool masked) {

	if (i == j)
		return true;

	int no_attributes = GetNoAttributes(false);

	int unmasked_i;
	int unmasked_j;

	if (masked) {
		unmasked_i = GetUnmaskedObject(i);
		unmasked_j = GetUnmaskedObject(j);
	}
	else {
		unmasked_i = i;
		unmasked_j = j;
	}

	int k;

	// Swap table entries.
	for (k = 0; k < no_attributes; k++) {
		int tmp = GetEntry(unmasked_i, k, false);
		if (!SetEntry(unmasked_i, k, GetEntry(unmasked_j, k, false), false))
			return false;
		if (!SetEntry(unmasked_j, k, tmp, false))
			return false;
	}

	// Swap object masks.
	// ...

	return true;

}

//-------------------------------------------------------------------
// Method........: SortObjects
// Author........: Aleksander 豩rn
// Date..........:
// Description...: Sorts the objects according to the integral value of
//                 the specified attribute.
// Comments......: Quick and dirty solution, very ineffiecient.
// Revisions.....:
//===================================================================

bool
DecisionTable::SortObjects(int attribute_no, bool masked) {

	Message message;

	int no_attributes = GetNoAttributes(masked);
	int no_objects    = GetNoObjects(masked);

	// Check index validity.
	if ((attribute_no < 0) || (attribute_no >= no_attributes)) {
		Message::Error("Attribute index out of range.");
		return false;
	}

	message.Notify("Sorting objects...");

	int i, j;

	// Do a dumb bubble sort.
	for (i = 0; i < no_objects; i++) {
		for (j = i + 1; j < no_objects; j++) {
			if (GetEntry(i, attribute_no, masked) > GetEntry(j, attribute_no, masked)) {
				if (!SwapObjects(i, j, masked))
					return false;
			}
		}
	}

	return true;

}

//-------------------------------------------------------------------
// Method........: SwapAttributes
// Author........: Aleksander 豩rn
// Date..........:
// Description...: Swaps attributes i and j in the table, and in the
//                 dictionary if this is present.  Swaps entries
//                 for all objects (disabled or not) to avoid creating
//                 inconsistencies in the table.

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -