/*********************************************************************** This file is part of KEEL-software, the Data Mining tool for regression, classification, clustering, pattern mining and so on. Copyright (C) 2004-2010 F. Herrera (herrera@decsai.ugr.es) L. S�nchez (luciano@uniovi.es) J. Alcal�-Fdez (jalcala@decsai.ugr.es) S. Garc�a (sglopez@ujaen.es) A. Fern�ndez (alberto.fernandez@ujaen.es) J. Luengo (julianlm@decsai.ugr.es) This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see http://www.gnu.org/licenses/ **********************************************************************/ /** * <p> * @author Written by Jaume Bacardit (La Salle, Ram�n Llull University - Barcelona) 28/03/2004 * @author Modified by Xavi Sol� (La Salle, Ram�n Llull University - Barcelona) 23/12/2008 * @version 1.1 * @since JDK1.2 * </p> */ package keel.Algorithms.Genetic_Rule_Learning.MPLCS; import keel.Algorithms.Genetic_Rule_Learning.MPLCS.Assistant.Discretizers.Basic.*; import keel.Dataset.*; import keel.Algorithms.Genetic_Rule_Learning.MPLCS.Assistant.Globals.*; public class AdaptiveAttribute { public static void constructor(int[] crm, int base, int attribute, InstanceWrapper ins) { if (Globals_ADI.types[attribute] == Attribute.REAL) { int disc = Rand.getInteger(0 , DiscretizationManager.getNumDiscretizers() - 1); int numMicroInt = DiscretizationManager.getDiscretizer(disc). getNumIntervals(attribute); int intervalOfSample; boolean done = false; if (ins != null) { intervalOfSample = ins.getDiscretizedValue(attribute, disc); } else { intervalOfSample = -1; done = true; } int numIntervals; int maxAllowedIntervals = Math.min(numMicroInt , Parameters.maxIntervals); if (maxAllowedIntervals > 2) { numIntervals = Rand.getInteger(2, maxAllowedIntervals); } else { numIntervals = maxAllowedIntervals; } crm[base] = numIntervals; crm[base + 1] = disc; int i, pos, max; int sum = 0; for (i = 0, pos = base + 2, max = numIntervals - 1; i < max; i++, pos += 2) { int microInt = Rand.getInteger(1 , numMicroInt - (numIntervals - i - 1)); sum += microInt; crm[pos] = sum; numMicroInt -= microInt; if (!done && intervalOfSample < sum) { done = true; crm[pos + 1] = 1; } else { if (Rand.getReal() < Parameters.probOne) { crm[pos + 1] = 1; } else { crm[pos + 1] = 0; } } } sum += numMicroInt; crm[pos] = sum; if (!done && intervalOfSample < sum) { crm[pos + 1] = 1; } else { if (Rand.getReal() < Parameters.probOne) { crm[pos + 1] = 1; } else { crm[pos + 1] = 0; } } } else { int valueIns; if (ins != null) { valueIns = ins.getNominalValue(attribute); } else { valueIns = -1; } crm[base] = crm[base + 1] = Globals_ADI.size[attribute] - 2; for (int i = 0, pos = base + 2, max = crm[base]; i < max; i++, pos++) { if (i != valueIns) { if (Rand.getReal() < Parameters.probOne) { crm[pos] = 1; } else { crm[pos] = 0; } } else { crm[pos] = 1; } } } } public static boolean doMatchReal(int[] crm, int base, int value) { int base2 = base + 2; for (int i = 0, max = crm[base]; i < max; i++) { if (value < crm[base2]) { return (crm[base2 + 1] == 1); } base2 += 2; } LogManager.printErr("Integrity error at AdaptiveAttribute.doMatchReal. " + crm[base] + " " + crm[base + 1] + " " + value); System.exit(1); return false; } public static boolean doMatchNominal(int[] crm, int base, int value) { return (crm[base + 2 + value] == 1); } public static String dumpPhenotype(int[] crm, int base, int attribute) { String str = ""; Attribute att = Attributes.getAttribute(attribute); String temp = "Att " + att.getName() + " is "; if (Globals_ADI.types[attribute] == Attribute.REAL) { double min = att.getMinAttribute(); double max = att.getMaxAttribute(); Discretizer d = DiscretizationManager.getDiscretizer(crm[base + 1]); if (crm[base] > 1) { int intervalCount = 0; int index = 0; int oldMicroInt = 0; while (index < crm[base]) { intervalCount++; int microInt = 0; int valueAct = crm[base + 3 + index * 2]; while (index < crm[base] && crm[base + index * 2 + 3] == valueAct) { microInt = crm[base + 2 + index * 2]; index++; } if (valueAct == 1) { if (oldMicroInt == 0) { if (index < crm[base]) { double maxInt = d.getCutPoint(attribute, microInt - 1); temp += "[<" + maxInt + "]"; } } else { double minInt = d.getCutPoint(attribute, oldMicroInt - 1); if (index == crm[base]) { temp += "[>" + minInt + "]"; } else { double maxInt = d.getCutPoint(attribute, microInt - 1); temp += "[" + minInt + "," + maxInt + "]"; } } } oldMicroInt = microInt; } if (intervalCount > 1) { str += temp; } } } else { boolean irr = true; boolean first = true; for (int i = 0; i < crm[base]; i++) { if (crm[base + i + 2] == 1) { if (first) { temp += att.getNominalValue(i); first = false; } else { temp += "," + att.getNominalValue(i); } } else { irr = false; } } if (!irr) { temp.replaceAll(",$", ""); str += temp; } } return str; } public static void mutation(int[] crm, int base, int attribute) { int value = Rand.getInteger(0, crm[base] - 1); int pos; if (Globals_ADI.types[attribute] == Attribute.REAL) { pos = base + value * 2 + 3; } else { pos = base + value + 2; } if (crm[pos] == 1) { crm[pos] = 0; } else { crm[pos] = 1; } } public static int doSplit(int[] crm, int base, int attribute, int interval) { if (Globals_ADI.types[attribute] != Attribute.REAL) { return 0; } int intervalPos = base + interval * 2 + 2; int size; if (interval == 0) { size = crm[intervalPos]; } else { size = crm[intervalPos] - crm[intervalPos - 2]; } if (size < 2 || crm[base] == Parameters.maxIntervals) { return 0; } int cutPoint = Rand.getInteger(0, size - 2); int size1 = cutPoint + 1; int size2 = size - size1; int pos = base + (crm[base] - 1) * 2 + 2; for (int i = crm[base] - 1; i >= interval; i--, pos -= 2) { crm[pos + 2] = crm[pos]; crm[pos + 3] = crm[pos + 1]; } crm[intervalPos] -= size2; crm[base]++; return +1; } public static int doMerge(int[] crm, int base, int attribute, int interval) { if (Globals_ADI.types[attribute] != Attribute.REAL) { return 0; } if (crm[base] == 1) { return 0; } int neighbour; if (interval == 0) { neighbour = 1; } else if (interval == crm[base] - 1) { neighbour = crm[base] - 2; } else { if (Rand.getReal() < 0.5) { neighbour = interval + 1; } else { neighbour = interval - 1; } } int pos1, pos2, nextInterval; if (neighbour < interval) { pos1 = base + neighbour * 2 + 2; nextInterval = interval + 1; } else { pos1 = base + interval * 2 + 2; nextInterval = neighbour + 1; } pos2 = pos1 + 2; int size1, size2; if (pos1 == base + 2) { size1 = crm[pos1]; } else { size1 = crm[pos1] - crm[pos1 - 2]; } size2 = crm[pos2] - crm[pos1]; int value; if (size1 > size2) { value = crm[pos1 + 1]; } else if (size2 > size1) { value = crm[pos2 + 1]; } else { if (Rand.getReal() < 0.5) { value = crm[pos1 + 1]; } else { value = crm[pos2 + 1]; } } crm[pos1] = crm[pos2]; crm[pos1 + 1] = value; for (int i = nextInterval, max = crm[base]; i < max; i++, pos2 += 2) { crm[pos2] = crm[pos2 + 2]; crm[pos2 + 1] = crm[pos2 + 3]; } crm[base]--; return -1; } public static void doReinitialize(int[] crm, int base, int attribute) { if (Globals_ADI.types[attribute] != Attribute.REAL) { return; } constructor(crm, base, attribute, null); } }