/* *Copyright 2007, 2011 CCLS Columbia University (USA), LIFO University of Orl��ans (France), BRGM (France) * *Authors: Cyril Nortet, Xiangrong Kong, Ansaf Salleb-Aouissi, Christel Vrain, Daniel Cassard * *This file is part of QuantMiner. * *QuantMiner 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 any later version. * *QuantMiner 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 QuantMiner. If not, see <http://www.gnu.org/licenses/>. */ package src.geneticAlgorithm; import java.util.*; import src.apriori.*; import src.database.*; import src.solver.*; public class GeneticAlgo extends EvaluationBaseAlgorithm { private float m_fTauxCroisement = 0.0f; //crossover rate private float m_fTauxMutation = 0.0f; //mutation rate // Structures de donn�es pour l'optimisation des calculs : private short [] m_tIndicesAleatoiresCroisements = null; // Indices d'individus � croiser, d'apr�s un tir al�atoire dans un espace o� chaque individu de rang n a une chance de plus d'etre tir� qu'un �l�ment de taille n-1 private short m_compteurIndicesAleatoiresCroisements = 0; private void CalculerTableIndicesTirages() { int iTable = 0; int iTirage = 0; int iPlageRoulette; int iPlageRestante = 0; int iIndiceReglePotentielle = 0; m_tIndicesAleatoiresCroisements = new short [16384]; iPlageRoulette = (m_iNombreReglesPotentielles * (m_iNombreReglesPotentielles+1)) / 2; for (iTable=0; iTable<16384; iTable++) { iTirage = (int)(java.lang.Math.random() * (double)iPlageRoulette); // On d�termine l'indice de l'individu correspondant au r�sultat du tir al�atoire sur la plage iPlageRestante = iPlageRoulette - m_iNombreReglesPotentielles; iIndiceReglePotentielle = m_iNombreReglesPotentielles - 1; while (iTirage<iPlageRestante) { iPlageRestante -= iIndiceReglePotentielle; iIndiceReglePotentielle--; } m_tIndicesAleatoiresCroisements[iTable] = (short)iIndiceReglePotentielle; } m_compteurIndicesAleatoiresCroisements = 0; } /**Genetics Algorithm * @param iNombreIndividus number of individuals * @param gestionBD GestionnaireBaseDeDonnees obj */ public GeneticAlgo(int iNombreIndividus, DatabaseAdmin gestionBD) { super(iNombreIndividus, gestionBD); m_fTauxCroisement = 0.0f; m_fTauxMutation = 0.0f; CalculerTableIndicesTirages(); } /**Set Genetic parameters * @param fTauxCroisement Crossover rate * @param fTauxMutation Mutation rate */ public void SpecifierParametresGenetiques(float fTauxCroisement, float fTauxMutation) { m_fTauxCroisement = fTauxCroisement; m_fTauxMutation = fTauxMutation; } /**Do evolution*/ public void Evoluer() { int iIndiceReglePotentielle = 0; int iIndiceReglePotentiellePere = 0; int iIndiceReglePotentielleMere = 0; int iNombreReglesPotentiellesRemplacees = 0; int iPlageRoulette = 0; ReglePotentielle reglePotentielleEvolue = null; //The number of potential rules to be replaced iNombreReglesPotentiellesRemplacees = (int)((float)m_iNombreReglesPotentielles * m_fTauxCroisement); m_iNombreReglesPotentiellesAEvaluer = 0; for (iIndiceReglePotentielle = 0; iIndiceReglePotentielle < iNombreReglesPotentiellesRemplacees; iIndiceReglePotentielle++) { reglePotentielleEvolue = m_tReglesPotentielles[iIndiceReglePotentielle]; //Get father and mother rules iIndiceReglePotentiellePere = m_tIndicesAleatoiresCroisements[ (int)((m_compteurIndicesAleatoiresCroisements++)&0x3FFF) ]; iIndiceReglePotentielleMere = m_tIndicesAleatoiresCroisements[ (int)((m_compteurIndicesAleatoiresCroisements++)&0x3FFF) ]; // Ancienne technique de choix des parents : //iIndiceIndividuPere = iNombreIndividusRemplaces + (int)( (m_tRandomFloat[(int)((m_compteurRandomFloat++)&0xFFFF)]) * ((float)(m_iNombreIndividus-iNombreIndividusRemplaces)) ); //iIndiceIndividuMere = iNombreIndividusRemplaces + (int)( (m_tRandomFloat[(int)((m_compteurRandomFloat++)&0xFFFF)]) * ((float)(m_iNombreIndividus-iNombreIndividusRemplaces)) ); //Do crossover EffectuerCroisement(reglePotentielleEvolue, m_tReglesPotentielles[iIndiceReglePotentiellePere], m_tReglesPotentielles[iIndiceReglePotentielleMere]); //Do mutation if ( m_tRandomFloat[(int)((m_compteurRandomFloat++)&0xFFFF)] <= m_fTauxMutation) EffectuerMutation(reglePotentielleEvolue); m_tReglesPotentiellesAEvaluer[m_iNombreReglesPotentiellesAEvaluer] = reglePotentielleEvolue; m_iNombreReglesPotentiellesAEvaluer++; } //The rest potential rules that haven't been replaced by crossover for (iIndiceReglePotentielle = iNombreReglesPotentiellesRemplacees; iIndiceReglePotentielle < m_iNombreReglesPotentielles; iIndiceReglePotentielle++) //Do mutation if ( m_tRandomFloat[(int)((m_compteurRandomFloat++)&0xFFFF)] <= m_fTauxMutation) { reglePotentielleEvolue = m_tReglesPotentielles[iIndiceReglePotentielle]; EffectuerMutation(reglePotentielleEvolue); m_tReglesPotentiellesAEvaluer[m_iNombreReglesPotentiellesAEvaluer] = reglePotentielleEvolue; m_iNombreReglesPotentiellesAEvaluer++; } super.EvaluerReglesPotentielles(); } /** Perform Mutation * @param reglePotentielle Potential rules */ public void EffectuerMutation(ReglePotentielle reglePotentielle) { int iIndiceDimension = 0; int iIndiceDisjonction = 0; int iNombreValeursDomaine = 0; int iIndiceValeurDomaineMin, iIndiceValeurDomaineMax = 0; int iIndiceIntervalle = 0; DataColumn colonneDonnees = null; for (iIndiceDimension=0;iIndiceDimension<m_iDimension;iIndiceDimension++) { if ( ( m_bPrendreEnCompteQuantitatifsGauche && (iIndiceDimension<m_iNombreItemsQuantCond) ) ||( m_bPrendreEnCompteQuantitatifsDroite && (iIndiceDimension>=m_iNombreItemsQuantCond) ) ) { if (iIndiceDimension<m_iNombreItemsQuantCond) { colonneDonnees = m_tItemsQuantCond[ iIndiceDimension ].m_colonneDonnees; iIndiceIntervalle = iIndiceDimension * m_schemaRegleOptimale.m_iNombreDisjonctionsGauche + m_iDisjonctionGaucheCourante; iIndiceDisjonction = m_iDisjonctionGaucheCourante; } else { colonneDonnees = m_tItemsQuantObj[ iIndiceDimension-m_iNombreItemsQuantCond ].m_colonneDonnees; iIndiceIntervalle = m_iDebutIntervallesDroite + ((iIndiceDimension-m_iNombreItemsQuantCond)*m_schemaRegleOptimale.m_iNombreDisjonctionsDroite) + m_iDisjonctionDroiteCourante; iIndiceDisjonction = m_iDisjonctionDroiteCourante; } iNombreValeursDomaine = colonneDonnees.m_iNombreValeursReellesCorrectes; if ( m_tRandomFloat[(int)((m_compteurRandomFloat++)&0xFFFF)] > 0.5f) { iIndiceValeurDomaineMin = reglePotentielle.m_tIndiceMin[iIndiceIntervalle]; iIndiceValeurDomaineMax = reglePotentielle.m_tIndiceMax[iIndiceIntervalle]; iIndiceValeurDomaineMin += (int)( (m_tRandomFloat[(int)((m_compteurRandomFloat++)&0xFFFF)] - 0.4f) * ((float)iNombreValeursDomaine) * 0.05f); iIndiceValeurDomaineMax += (int)( (m_tRandomFloat[(int)((m_compteurRandomFloat++)&0xFFFF)] - 0.6f) * ((float)iNombreValeursDomaine) * 0.05f); VerifierEtAffecterBornesReglePotentielle(reglePotentielle, iIndiceDimension, iIndiceDisjonction, iIndiceValeurDomaineMin, iIndiceValeurDomaineMax); } } } } /**Create a new rule potentialRuleChild, child of the crossover of a father rule and a mother rule. * @param reglePotentielleFille potentialRuleChild * @param reglePotentiellePere potentialRuleFather * @param reglePotentielleMere potentialRuleMother */ public void EffectuerCroisement(ReglePotentielle reglePotentielleFille, ReglePotentielle reglePotentiellePere, ReglePotentielle reglePotentielleMere) { int iIndiceDimension = 0; int iIndiceIntervalle = 0; int iIndiceDisjonction = 0; int iResultatRoulette = 0; for (iIndiceDimension=0;iIndiceDimension<m_iDimension;iIndiceDimension++) { if ( ( m_bPrendreEnCompteQuantitatifsGauche && (iIndiceDimension<m_iNombreItemsQuantCond) ) ||( m_bPrendreEnCompteQuantitatifsDroite && (iIndiceDimension>=m_iNombreItemsQuantCond) ) ) { if (iIndiceDimension<m_iNombreItemsQuantCond) { iIndiceIntervalle = (iIndiceDimension*m_schemaRegleOptimale.m_iNombreDisjonctionsGauche) + m_iDisjonctionGaucheCourante; iIndiceDisjonction = m_iDisjonctionGaucheCourante; } else { iIndiceIntervalle = m_iDebutIntervallesDroite + ((iIndiceDimension-m_iNombreItemsQuantCond)*m_schemaRegleOptimale.m_iNombreDisjonctionsDroite) + m_iDisjonctionDroiteCourante; iIndiceDisjonction = m_iDisjonctionDroiteCourante; } iResultatRoulette = (int)(8.0f * m_tRandomFloat[(int)((m_compteurRandomFloat++)&0xFFFF)]); if (iResultatRoulette == 0) VerifierEtAffecterBornesReglePotentielle(reglePotentielleFille, iIndiceDimension, iIndiceDisjonction, reglePotentiellePere.m_tIndiceMin[iIndiceIntervalle], reglePotentiellePere.m_tIndiceMax[iIndiceIntervalle]); else if (iResultatRoulette == 1) VerifierEtAffecterBornesReglePotentielle(reglePotentielleFille, iIndiceDimension, iIndiceDisjonction, reglePotentielleMere.m_tIndiceMin[iIndiceIntervalle], reglePotentielleMere.m_tIndiceMax[iIndiceIntervalle]); else if (iResultatRoulette <= 4) VerifierEtAffecterBornesReglePotentielle(reglePotentielleFille, iIndiceDimension, iIndiceDisjonction, reglePotentiellePere.m_tIndiceMin[iIndiceIntervalle], reglePotentielleMere.m_tIndiceMax[iIndiceIntervalle]); else VerifierEtAffecterBornesReglePotentielle(reglePotentielleFille, iIndiceDimension, iIndiceDisjonction, reglePotentielleMere.m_tIndiceMin[iIndiceIntervalle], reglePotentiellePere.m_tIndiceMax[iIndiceIntervalle]); } } } }