package keel.Algorithms.UnsupervisedLearning.AssociationRules.FuzzyRuleLearning.Fingrams; import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.File; import java.io.FileNotFoundException; import java.io.FileReader; import java.io.FileWriter; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.text.DecimalFormat; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.Vector; public abstract class Fingrams { // /////////// VARIABLES ///////////// // Table with the examples. Each row is an example and the columns have the // attributes of the examples // protected List<List<Float>> examples; // 3 position vector with the operators used in the system // protected List<Integer> operators; // Matrix that stores the text of the rules protected List<String> textRules; // Matrix that stores the complete social network protected List<List<Double>> socialNetwork; // Matrix that stores the scaled social network protected List<List<Double>> scaledSocialNetwork; // List that stores the list of examples. Each row means a rule, the // length of rules varies // protected List<List<Integer>> listExamplesCoveredByRule; // Matrix that stores the examples that fire the rules // A 1 in position (i,j) means that example j+1 fires rule i protected byte[][] matrixRulesXExamples; protected double[][] matrixFiringDegreesRulesXExamples; // Vector that contains the total firing degrees of rules protected List<Double> totalFiringDegrees; // Number of rules of the system protected int numberRules; // Number of examples managed protected int numberExamples; // Number of antecedents of the rules protected List<Integer> numberAntecedents; // Set of label conclusions that can appear protected List<String> possibleLabelConclusions; // Rule identifier protected List<String> rulesIdentifiers; // Relation protected int relation; // Type of relation protected boolean relationDirected; // File location. This place will be used to store every file protected String fileLocation; // Variables to control the uncovered examples protected boolean ruleUncoveredExamples; protected int numberUncoveredExamples; protected List<Integer> uncoveredExamples; // ///////////// END VARIABLES /////////////// // ///////////// METHODS /////////////// // // // // BUILDERS // // // // public Fingrams() { textRules = new ArrayList<String>(); socialNetwork = new ArrayList<List<Double>>(); scaledSocialNetwork = new ArrayList<List<Double>>(); // listExamplesCoveredByRule = new ArrayList<List<Integer>>(); totalFiringDegrees = new ArrayList<Double>(); numberRules = 0; numberAntecedents = new ArrayList<Integer>(); possibleLabelConclusions = new ArrayList<String>(); rulesIdentifiers = new ArrayList<String>(); relation = 0; relationDirected = false; fileLocation = ""; } public Fingrams(int relation, String fileLocation) { textRules = new ArrayList<String>(); socialNetwork = new ArrayList<List<Double>>(); scaledSocialNetwork = new ArrayList<List<Double>>(); // listExamplesCoveredByRule = new ArrayList<List<Integer>>(); totalFiringDegrees = new ArrayList<Double>(); numberRules = 0; numberAntecedents = new ArrayList<Integer>(); possibleLabelConclusions = new ArrayList<String>(); rulesIdentifiers = new ArrayList<String>(); this.relation = relation; if (relation == 0) { relationDirected = false; } else { relationDirected = true; } this.fileLocation = fileLocation; } // // // // GETS & SETS // // // // public List<String> getTextRules() { return textRules; } public List<List<Double>> getSocialNetwork() { return socialNetwork; } public List<List<Double>> getScaledSocialNetwork() { return scaledSocialNetwork; } public byte[][] getMatrixRulesXExamples() { return matrixRulesXExamples; } public int getNumberRules() { return numberRules; } public int getNumberExamples() { return numberExamples; } public List<Integer> getNumberAntecedents() { return numberAntecedents; } public List<String> getPossibleLabelConclusions() { return possibleLabelConclusions; } public List<String> getRulesIdentifiers() { return rulesIdentifiers; } public int getTypeRelation() { return relation; } public List<Double> getTotalFiringDegrees() { return totalFiringDegrees; } public String getFileLocation() { return fileLocation; } // // // Abstract // // // // protected abstract InfoNode calculateInfoNode(int n); public abstract int loadInfoFromFS(); // // // Defined and fixed // // // // public void generateMatrix() { if (relation == 0) { generateUndirectedMatrix(); relationDirected = false; } else { if (relation > 0) { generateDirectedMatrix(); relationDirected = true; } } } // protected void writeToFileCompleteNetwork() {} public String buildConfGraphDotFile(String file) { String outputString; StringBuilder outputSB = new StringBuilder(); try { DecimalFormat df = new AdministrativeStaff().format(); Vector<Integer> origRules = new Vector<Integer>(); Vector<Integer> endRules = new Vector<Integer>(); Vector<Double> linkWeights = new Vector<Double>(); String inputString = (new AdministrativeStaff()) .readFileAsString(file); List<String> lines = Arrays.asList(inputString.split("\n")); for (int i = 0; i < lines.size(); i++) { String l = lines.get(i); // It iterates until it finds the *arcs or *edge marker if (l.startsWith("*arcs") || l.startsWith("*edges")) { i++; for (; i < lines.size(); i++) { // It reads next line l = lines.get(i); // Break the line getting the first number (rule) and // adding it to the origin of rules int ind1 = l.indexOf(" "); Integer r1 = new Integer(l.substring(0, ind1)); origRules.add(r1); // Read and store the end of the link (end rule) String aux = l.substring(ind1 + 1); int ind2 = aux.indexOf(" "); Integer r2 = new Integer(aux.substring(0, ind2)); endRules.add(r2); // Read and store the weight of the link Double lw = new Double(aux.substring(ind2 + 1)); linkWeights.add(lw); } } else if (l.startsWith("*matrix")) { String aux = ""; i++; for (int n = 0; n < numberRules && i < lines.size(); n++, i++) { // Read the first row aux = lines.get(i); // It splits the content by columns List<String> valuesRow = Arrays.asList(aux .split("[ ]+")); // Iterate along the values of the row for (int j = 0; j < valuesRow.size(); j++) { // Gets the next value of the actual row String value = valuesRow.get(j); if (Double.parseDouble(value) > 0) { origRules.add(n + 1); endRules.add(j + 1); linkWeights.add(Double.parseDouble(value)); } } // System.out.println(" -> matrix["+n+"]["+m+"]="+matrix[n][m]); } } } if (relationDirected) { outputSB.append("digraph \"\" {\n\t" + "name=FINGRAM; " + "ratio=auto; " + "size=\"10,10\"; " + "overlap=\"scale\"; " + "nodesep=0.3; " + "center=true; " + "truecolor=true;\n\n\t"); } else { outputSB.append("graph \"\" {\n\t" + "name=FINGRAM; " + "ratio=auto; " + "size=\"10,10\"; " + "overlap=\"scale\"; " + "nodesep=0.3; " + "center=true; " + "truecolor=true;\n\n\t"); } for (int n = 0; n < numberRules; n++) { // String ruleDesc = Rule[n]; if (isCoveringExamples(matrixRulesXExamples[n])) { String shape = "circle"; InfoNode in = calculateInfoNode(n); outputSB.append(rulesIdentifiers.get(n).replaceAll("\\s", "") + " [shape=" + shape + ",height=" + df.format(in.getNodeSize()) + ",width=" + df.format(in.getNodeSize()) + ",fixedsize=true" + ",peripheries=" + numberAntecedents.get(n) + ",color=\"" + in.getBorderColor() + "\",fillcolor=\"" + in.getNodeColor() + "\",fontsize=" + in.getFontSize() + ",fontcolor=" + in.getFontColor() + ",style=filled" + ",label=\"" + in.getNodeInfo() + "\"" + ",tooltip=\"" + in.getNodeInfoToolTipText() + "\"];\n\t"); } else { String shape = "circle"; outputSB.append(rulesIdentifiers.get(n).replaceAll("\\s", "") + " [shape=" + shape + ",height=" + df.format(1) + ",width=" + df.format(1) + ",fixedsize=true" + ",peripheries=" + numberAntecedents.get(n) + ",color=\"" + "red" + "\",fillcolor=\"" + "red" + "\",fontsize=" + 11.8f + ",fontcolor=" + "black" + ",style=filled" + ",label=\"" + "R" + rulesIdentifiers.get(n).substring(4) + "\\n" + " (cov=0.000" + ")" + "\"" + ",tooltip=\"" + "R" + rulesIdentifiers.get(n).substring(4) + "\\n" + " (cov=0.000" + ")" + "\"];\n\t"); } } if (hasRuleUncoveredExamples()) { outputSB.append(createNodeUncoveredExamples()); } if ((origRules.size() != endRules.size()) || (origRules.size() != linkWeights.size())) { System.out .println("ERROR reading and printing the edges of the graph"); } else { int numberEdges = origRules.size(); int[][] printEdges = null; boolean warn = false; outputString = outputSB.toString(); if ((outputString.contains(".ms.")) || (outputString.contains(".msc.")) || (outputString.contains(".msfd.")) || (outputString.contains(".msfdc."))) { printEdges = new int[numberRules][numberRules]; warn = true; } for (int n = 0; n < numberEdges; n++) { int origRule = origRules.get(n) - 1; int endRule = endRules.get(n) - 1; if (!warn || (warn && (printEdges[origRule - 1][endRule - 1] == 0) && (printEdges[endRule - 1][origRule - 1] == 0))) { String linkName = "\n\t" + rulesIdentifiers.get(origRule).replaceAll( "\\s", ""); String linkToolTipText = "R" + rulesIdentifiers.get(origRule).substring(4); if (relationDirected) { linkName = linkName + " -> "; linkToolTipText = linkToolTipText + " -> "; } else { linkName = linkName + " -- "; linkToolTipText = linkToolTipText + " -- "; } linkName = linkName + rulesIdentifiers.get(endRule).replaceAll( "\\s", ""); linkToolTipText = linkToolTipText + "R" + rulesIdentifiers.get(endRule).substring(4); String col = "black"; outputSB.append(" " + linkName); String linkDesc = linkToolTipText + " (" + df.format(linkWeights.get(n)) + ")"; outputSB.append(" [penwidth=" + df.format(1 + 10 * (linkWeights.get(n))) + ",weight=" + df.format(100 * (1 - linkWeights.get(n))) + ",color=" + col); // If we have a relation that produces directed // relations if (relationDirected) { outputSB.append(",arrowhead=normal"); } // If we have a relation that produces undirected // relations outputSB.append(",fontsize=15" + ",labelfontcolor=" + col + ",label=\"" + df.format(linkWeights.get(n)) + "\"" + ",tooltip=\"" + linkDesc + "\"" + ",title=" + "\"" + linkDesc + "\"];"); if (warn) { printEdges[origRule - 1][endRule - 1] = 1; } } } outputSB.append(""); } outputSB.append("}"); } catch (Exception e) { e.printStackTrace(); } outputString = outputSB.toString(); return outputString; } public void generateScaledNetwork(String origFile, String destFile, int q) { try { String command = "\"" + (new AdministrativeStaff()).obtainPathPathfinder() + "\" \"" + fileLocation + origFile + "\"" + " " + q; // System.out.println("\""+command+"\""); Runtime rt = Runtime.getRuntime(); Process p = rt.exec(command); BufferedReader input = new BufferedReader(new InputStreamReader( p.getInputStream())); String line = null; FileWriter fstream = new FileWriter(fileLocation + destFile); String salida = ""; while ((line = input.readLine()) != null) { salida += line + "\n"; } BufferedWriter out = new BufferedWriter(fstream); out.write(salida); // Close the output stream out.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } public void generateFingramImages(String nameFile, String output, String drawing) { // Generate .svg from .dot file for the scaled network String pathDot = "\"" + (new AdministrativeStaff()).obtainPathDot() + "\""; String command = pathDot + " -T" + output + " -K" + drawing + " " + "\"" + fileLocation + nameFile + ".dot\" -o \"" + fileLocation + nameFile + "." + output + "\""; // String auxOut = fileLocation + "aux.txt"; // System.out.println(command); // execute my command new AdministrativeStaff().runProcess(command); if (output.equals("svg")) { (new AdministrativeStaff()).writeParsedSVGBuffer(fileLocation + nameFile + ".svg"); } } public void writeToFileNetwork(List<List<Double>> parameterSocialNetwork, String nameFile, String nameFileAux) { try { StringBuilder entradaBuilder = new StringBuilder(); StringBuilder entradaBuilder2; // Construct the .ms file with all the links String entrada; entradaBuilder.append("*vertices " + parameterSocialNetwork.size() + "\n"); for (int i = 1; i <= parameterSocialNetwork.size(); i++) entradaBuilder .append(i + " \"" + i + "\" ellipse x_fact 1.22866290766363 y_fact 1.22866290766363 fos 3.5 bw 0.0 ic Emerald\n"); entradaBuilder.append("*matrix\n"); String entrada2 = ""; if (!relationDirected) { entradaBuilder2 = new StringBuilder(entradaBuilder); for (int i = 0; i < parameterSocialNetwork.size(); i++) { for (int j = 0; j < parameterSocialNetwork.size(); j++) { entradaBuilder2.append(parameterSocialNetwork.get(i) .get(j) + " "); if (i < j) entradaBuilder.append(parameterSocialNetwork.get(i) .get(j) + " "); else entradaBuilder.append("0 "); } entradaBuilder.append("\n"); entradaBuilder2.append("\n"); } } else { for (int i = 0; i < parameterSocialNetwork.size(); i++) { for (int j = 0; j < parameterSocialNetwork.size(); j++) { entradaBuilder.append(parameterSocialNetwork.get(i) .get(j) + " "); } entradaBuilder.append("\n"); } entradaBuilder2 = new StringBuilder(entradaBuilder); } // Write the information to file FileWriter fstream = new FileWriter(fileLocation + nameFile); BufferedWriter out = new BufferedWriter(fstream); out.write(entradaBuilder.toString()); // Close the output stream out.close(); // Write the information to file to be scaled FileWriter fstream2 = new FileWriter(fileLocation + nameFileAux); BufferedWriter out2 = new BufferedWriter(fstream2); out2.write(entradaBuilder2.toString()); // Close the output stream out2.close(); // return entrada; } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } /* * function generateUndirectedMatrix * * Need: The list of examples covered by each rule * * Produce: Nothing * * Modify: The social network with the information */ protected void generateUndirectedMatrix() { socialNetwork = new ArrayList<List<Double>>(numberRules); List<Integer> FRi = new ArrayList<Integer>(); /* * for (int i = 0; i < numberRules; i++) { socialNetwork.add(new * ArrayList<Double>()); for (int j = 0; j < numberRules; j++) { if (j * == i) socialNetwork.get(i).add(1.0); else * socialNetwork.get(i).add(0.0); } * FRi.add(listExamplesCoveredByRule.get(i).size()); } */ for (int i = 0; i < numberRules; i++) { socialNetwork.add(new ArrayList<Double>()); FRi.add(elementsInCommon(matrixRulesXExamples[i], matrixRulesXExamples[i])); for (int j = 0; j < numberRules; j++) { if (j == i) { socialNetwork.get(i).add(1.0); } else { socialNetwork.get(i).add( (double) elementsInCommon(matrixRulesXExamples[i], matrixRulesXExamples[j])); } } } /* * for (int i = 0; i < numberRules; i++) { for (int j : * listExamplesCoveredByRule.get(i)) { for (int k = i + 1; k < * numberRules; k++) { * * if (listExamplesCoveredByRule.get(k).contains(j)) { Double previous = * socialNetwork.get(i).get(k); socialNetwork.get(i).set(k, previous + * 1); socialNetwork.get(k).set(i, previous + 1); } } } * * } */ for (int i = 0; i < numberRules; i++) { for (int j = 0; j < numberRules; j++) { if (FRi.get(i) != 0 && FRi.get(j) != 0 && i != j) { socialNetwork.get(i) .set(j, socialNetwork.get(i).get(j) / (float) Math.sqrt(FRi.get(i) * FRi.get(j))); } } } } abstract protected void generateDirectedMatrix(); protected int elementsInCommon(byte[] rulei, byte[] rulej) { int count = 0; for (int i = 0; i < rulei.length; i++) { if (((byte) (rulei[i] & rulej[i])) == 1) { count++; } } return count; } protected boolean isCoveringExamples(byte[] rule) { for (int i = 0; i < rule.length; i++) { if (rule[i] == 1) { return true; } } return false; } abstract public void generateScienceMapFile(double MaxThr); abstract public String createNodeUncoveredExamples(); abstract public boolean hasRuleUncoveredExamples(); abstract public void printFingramsLegend(); }