/*********************************************************************/ /// <summary> /// Sucht nach einem Attribut, welches für den Knoten optimal ist /// </summary> /// <param name="vertex">Vertex für den der Typ gefunden werden soll</param> /// <returns>gefundener AttributTyp</returns> private CAttributeType findBestAttribute(CTreeVertex vertex) { double bestEntropy = double.MaxValue; CAttributeType bestAttrType = null; List <CAttributeType> attrTypeList = mTableLogic.getAttributeTypes(); foreach (CAttributeType type in attrTypeList) { if ((type.Used == true) && (type.TargetAttribute == false) && (mTreeLogic.isAttributeUsedByParent(vertex, type) == false)) { mTreeLogic.setVertexAttribute(vertex, type); mTreeLogic.updateVertexValues(); // Verhindern das ein Kindknoten alle Einträge enthält wie der Parent, // dann können wir uns das auch sparen if (childDoesOwnAllParentObjects(vertex) == false) { double entropy = calculateWeightedEntropy(vertex); if (entropy < bestEntropy) { bestEntropy = entropy; bestAttrType = type; } } } } return(bestAttrType); }
/*********************************************************************/ /// <summary> /// gibt ein Liste mit Childknoten zurück, die vom übergebenen /// Vertex ausgehen /// </summary> /// <param name="vertexToIdentify">Knoten der Identifiziert werden /// soll</param> /// <returns>Liste mit Childknoten</returns> public CValueList getDataforChildVertices(CTreeVertex vertexToIdentify) { if (vertexToIdentify == null) { return(null); } string sSqlCommand = "SELECT DISTINCT " + vertexToIdentify.AttributeType.InternalName + " FROM " + CTableConstants.TABLE_ATTRIBUTES; SQLiteDataReader reader; CValueList entryList = new CValueList(); if (mConnection.sqlRequestStatement(sSqlCommand, out reader) == true) { CTableEntry tableEntry; while (getNextTableEntry(reader, out tableEntry) == true) { entryList.addValue(new CAttributeValue(vertexToIdentify.AttributeType, "2", tableEntry.Index)); } closeReader(reader); } return(entryList); }
/*********************************************************************/ /// <summary> /// Konstruktor /// </summary> /// <param name="vertexToIdentify">Knoten der Identifiziert werden /// soll</param> public IdentificationWindow(CTreeVertex vertexToIdentify, bool bInteractiveView) { // Sichergehen das nur ein Identifikationsfenster geöffnet ist checkSingleIndentificationWindow(); InitializeComponent(); mVertexToIdentify = vertexToIdentify; mTableEntryList = mBusinessLogic.getFilterdTableData(mVertexToIdentify); filteredDataGrid.DataContext = this; // die Spalten der Tabelle hinzufügen, abhängig von den Verwendeten Typen List <CAttributeType> attrTypeList = mBusinessLogic.getAttributeTypes(); foreach (CAttributeType type in attrTypeList) { if (type.Used == true) { DataGridTextColumn column = new CTableColumn(type); filteredDataGrid.Columns.Add(column); } } highlightSelectedAttributeColumn(); // Nur für die Interaktive Ansicht soll der Button eingeblendet werden showButtonBar(bInteractiveView); }
/*********************************************************************/ /// <summary> /// Setzt für einen Vertex das Attribut welches dieser Repräsentiert /// </summary> /// <param name="vertex">Vertex dessen Attribut geändert werden soll</param> /// <param name="attributeType">neues Attribut des Vertex</param> public bool setVertexAttribute(CTreeVertex vertex, CAttributeType attributeType) { if (mTreeLogic.setVertexAttribute(vertex, attributeType) == true) { mTreeLogic.updateVertexValues(); return(true); } return(false); }
internal void createGraph() { mTreeLogic.resetActiveTree(); CTreeVertex rootNode = mTreeLogic.getRootNode(); doTDIDT(rootNode); mTreeLogic.updateVertexValues(); }
/*********************************************************************/ /// <summary> /// gibt ein Liste mit Datensätzen zurück die von dem übergebenen /// Knoten repräsentiert werden. /// </summary> /// <param name="vertexToIdentify">Knoten der Identifiziert werden /// soll</param> /// <returns>Liste mit Datensätzen des Knotens</returns> public CTableEntryList getFilteredTableData(CTreeVertex vertexToIdentify) { if (vertexToIdentify == null) { return(null); } // sollte der Knoten kein Parent-Knoten haben (Root-Knoten) geben // wir alle Einträge zurück if (vertexToIdentify.ParentVertex == null) { return(getAllEntries()); } string sSqlCommand = "SELECT * FROM " + CTableConstants.TABLE_ATTRIBUTES + " WHERE "; // Den SQL-Befehl um die Filter erweitert. Dabei wird vom zu übergebenen Knoten while (vertexToIdentify.ParentVertex != null) { CTreeVertex parent = vertexToIdentify.ParentVertex; CTreeEdge parentEdge = vertexToIdentify.ParentEdge; sSqlCommand += parent.AttributeType.InternalName; sSqlCommand += "="; sSqlCommand += "'" + parentEdge.EdgeValue + "'"; // den Nächsten Knotne auswählen vertexToIdentify = parent; if (vertexToIdentify.ParentVertex != null) { sSqlCommand += " AND "; } } SQLiteDataReader reader; CTableEntryList entryList = new CTableEntryList(); if (mConnection.sqlRequestStatement(sSqlCommand, out reader) == true) { CTableEntry tableEntry; while (getNextTableEntry(reader, out tableEntry) == true) { entryList.Add(tableEntry); } closeReader(reader); } return(entryList); }
/*********************************************************************/ /// <summary> /// Setzt für einen Vertex das Attribut welches dieser Repräsentiert /// </summary> /// <param name="vertex">Vertex dessen Attribut geändert werden soll</param> /// <param name="attributeType">neues Attribut des Vertex</param> internal bool setVertexAttribute(CTreeVertex vertex, CAttributeType attributeType) { // sollte das Attribut bereits von einem Parent-Knoten verwendet werden // darf der Benutzer dieser Attribut nicht verwenden if (isAttributeUsedByParent(vertex, attributeType) == true) { return(false); } // wenn das Attribut bereits das ist welches der Vertex repräsentiert, // müssen wir nichts machen. if (vertex.AttributeType != attributeType) { mTreeHandler.removeChildVertices(vertex); // Attribut des Vertex setzen vertex.AttributeType = attributeType; if (vertex.AttributeType != null) { // TODO Kindknoten erzeugen und Verbindungen anlegen: //diskreter Wert (Splitwerte zurzeit nicht verfügbar -> ||true) if (attributeType.DataType.Equals(E_DATATYPE.E_STRING) || true) { //alte Children löschen mTreeHandler.removeChildVertices(vertex); //Werte für die Kindknoten erhalten CValueList childVertices = mTableLogic.getChildVertices(vertex); //Knoten und Verbindungen hinzufügen foreach (CAttributeValue value in childVertices) { CTreeVertex childVertex = addVertex(vertex, null); childVertex.ParentEdge = addEdge(vertex, childVertex, value); } } else //stetiger Wert { //Splitwert abfragen //Datenbankabfrage, GROUP BY? // } } return(true); } return(false); }
private bool childDoesOwnAllParentObjects(CTreeVertex parentVertex) { foreach (CTreeVertex child in parentVertex.ChildList) { if (child.CountObjects == parentVertex.CountObjects) { return(true); } if (child.CountObjects > 0) { return(false); } } return(false); }
private void nodeDoubleClicked(object sender, RoutedEventArgs e) { if (sender is VertexControl) { VertexControl control = sender as VertexControl; CTreeVertex vertex = control.Vertex as CTreeVertex; bool bInteractiveView = true; if (mCurrentView != E_VIEW.E_TREE_INTERACTIVE_VIEW) { bInteractiveView = false; } IdentificationWindow identWindow = new IdentificationWindow(vertex, bInteractiveView); identWindow.Show(); } }
/*********************************************************************/ /// <summary> /// Prüft ob ein AttributType bereits von ein ParentKnoten des /// übergebenen Kontens verwendet wird /// </summary> /// <param name="vertex">Vertex dessen Parentes geprüft werden</param> /// <param name="type">zu Prüfender Type</param> /// <returns>True - wird von Parent benutzt, False - sonst</returns> public bool isAttributeUsedByParent(CTreeVertex vertex, CAttributeType type) { // Durch alle Parentelemente des Knotenes gehen und prüfen ob dieses Attribut // nicht schon verwendet wurde CTreeVertex parent = vertex.ParentVertex; while (parent != null) { if (parent.AttributeType == type) { return(true); } parent = parent.ParentVertex; } return(false); }
/*********************************************************************/ /// <summary> /// führt den TDIDT Algorithmus für einen Knoten durch und sucht nach /// dem Optimalen Attribut für diesen Knoten und seine Kindknoten /// </summary> /// <param name="vertex"></param> private void doTDIDT(CTreeVertex vertex) { mTreeLogic.updateVertexValues(); if (stopCriteriaMet(vertex) == false) { // wir suchen das Optimale Attribut für diesen Knoten CAttributeType bestType = findBestAttribute(vertex); // nur wenn noch Attribute vorhanden sind machen wir weiter // if (bestType != null) { mTreeLogic.setVertexAttribute(vertex, bestType); foreach (CTreeVertex child in vertex.ChildList) { doTDIDT(child); } } } }
private bool stopCriteriaMet(CTreeVertex vertex) { if (vertex.CountObjects == 0) { return(true); } if (vertex.CountObjectsPerClass[CTreeVertex.YES_INDEX] == 0) { return(true); } if (vertex.CountObjectsPerClass[CTreeVertex.NO_INDEX] == 0) { return(true); } if (vertex.CountObjects <= mMinObjectsPerVertex) { return(true); } return(false); }
private double calculateWeightedEntropy(CTreeVertex vertex) { double sumEntropy = 0.0; // für jedes Kind die Teilentropie berechnen lassen foreach (CTreeVertex child in vertex.ChildList) { double childEntityFactor = (double)child.CountObjects / (double)vertex.CountObjects; double childYesFactor = (double)child.CountObjectsPerClass[CTreeVertex.YES_INDEX] / child.CountObjects; double childNoFactor = (double)child.CountObjectsPerClass[CTreeVertex.NO_INDEX] / child.CountObjects; // sichergehen das wir kein NaN oder sonstiges auf sumEntropy aufaddieren if ((childYesFactor != 0) && (double.IsNaN(childYesFactor) == false) && (childNoFactor != 0) && (double.IsNaN(childNoFactor) == false)) { sumEntropy += childEntityFactor * (-childYesFactor * Math.Log(childYesFactor, 2) - childNoFactor * Math.Log(childNoFactor, 2)); } } return(sumEntropy); }
/*********************************************************************/ /// <summary> /// gibt ein Liste mit Datensätzen zurück die von dem übergebenen /// Knoten repräsentiert werden. /// </summary> /// <param name="vertexToIdentify">Knoten der Identifiziert werden /// soll</param> /// <returns>Liste mit Datensätzen des Knotens</returns> public CTableEntryList getFilterdTableData(CTreeVertex vertexToIdentify) { return(mTableLogic.getFilteredTableData(vertexToIdentify)); }
/*********************************************************************/ /// <summary> /// gibt ein Liste mit Datensätzen zurück die von dem übergebenen /// Knoten repräsentiert werden. /// </summary> /// <param name="vertexToIdentify">Knoten der Identifiziert werden /// soll</param> /// <returns>Liste mit Datensätzen des Knotens</returns> internal CTableEntryList getFilteredTableData(CTreeVertex vertexToIdentify) { return(mDBAccess.getFilteredTableData(vertexToIdentify)); }
protected bool removeVertex(CTreeVertex vertex) { return(mTreeHandler.removeVertex(vertex)); }
protected CTreeVertex addVertex(CTreeVertex parent, CAttributeType type = null) { return(mTreeHandler.addVertex(parent, type)); }
public CValueList getChildVertices(CTreeVertex vertex) { return(mDBAccess.getDataforChildVertices(vertex)); }
protected CTreeEdge addEdge(CTreeVertex parent, CTreeVertex child, CAttributeValue attributeValue) { return(mTreeHandler.addEdge(parent, child, attributeValue)); }