/***********************************************************************
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/
**********************************************************************/
package keel.Algorithms.UnsupervisedLearning.AssociationRules.IntervalRuleLearning.MOPNAR;
/**
* <p>
* @author Written by Diana Mart�n (dmartin@ceis.cujae.edu.cu)
* @version 1.1
* @since JDK1.6
* </p>
*/
import java.io.PrintWriter;
import java.math.BigDecimal;
import java.util.*;
import org.core.Randomize;
public class MOPNARProcess {
/**
* <p>
* It provides the implementation of the algorithm to be run in a process
* </p>
*/
private final int UPDATE_SOLUTION_NEIGHBOR = 1;
private final int UPDATE_SOLUTION_WHOLEPOP = 2;
private String paretos;
private myDataset dataset;
private int numObjectives;
private int nTrials;
private int H;
private int T;
private double probDelta;
private int nr;
private double pm;
private double af;
private int max_rank;
private int updatePop;
private double minSupport;
private double percentUpdate;
private int nAttr;
private int nTrans;
private int trials;
private ArrayList<Chromosome> uPop;
private ArrayList<Chromosome> EP; //an external population (EP), which is used to store non dominated solutions found during the search
private double [] Z; // Z= (z1,z2...zm) where Zi is the best (max) value found for objective fi
private double [] Z_min; // Z_min= (z1,z2...zm) where Zi is the min value found for objective fi
/**
* <p>
* It creates a new process for the algorithm by setting up its parameters
* </p>
* @param dataset The instance of the dataset for dealing with its records
* @param numObjectives The number of objectives to be optimized
* @param nTrials The maximum number of generations to reach before completing the whole evolutionary learning
* @param H The parameter to control the population size and weight vectors
* @param T The number of the weight vectors in the neighborhood
* @param probDelta The probability that parent solutions are selected from the neighborhood
* @param nr The maximal number of solutions replaced by each child solution
* @param pm The probability for the mutation operator
* @param af The factor of amplitude for each attribute of the dataset
* @param percentUpdate The difference threshold to restart the population
*/
public MOPNARProcess (myDataset dataset, int numObjectives, int nTrials, int H, int T, double probDelta, int nr, double pm, double af, double percentUpdate) {
this.dataset = dataset;
this.nTrials = nTrials;
this.H = H;
this.T = T;
this.probDelta = probDelta;
this.nr = nr;
this.pm = pm;
this.af = af;
this.minSupport = 0.01;
this.percentUpdate = percentUpdate;
this.numObjectives = numObjectives;
this.nAttr = this.dataset.getnVars();
this.nTrans = this.dataset.getnTrans();
this.trials = 0;
this.paretos = new String("");
this.uPop = new ArrayList<Chromosome>();
this.EP = new ArrayList<Chromosome>();
this.Z = new double [this.numObjectives];
this.Z_min = new double [this.numObjectives];
}
/**
* <p>
* It runs the evolutionary learning for mining association rules
* </p>
*/
public void run(){
int nGn = 0;
this.trials = 0;
this.paretos = new String("");
System.out.println("Initialization");
this.initializePopulation();
do {
System.out.println("Computing Generation " + (nGn + 1));
this.updatePop = 0;
this.diffEvolution();
this.verifyRestartPop();
nGn++;
} while (this.trials < this.nTrials);
this.removeRedundant(this.EP);
printPareto();
System.out.println("done.\n");
}
private void verifyRestartPop(){
double percentUpdate = (this.uPop.size() * this.percentUpdate) / 100.0;
if(this.updatePop < percentUpdate){
this.restartPop();
}
}
/**
* Non-domination Selection procedure to filter out the dominated
* individuals from the given list.
*
* @param collection the collection of Chromosome object need to be filtered.
* @return the reference copy of the non-dominating individuals
*/
private ArrayList<Chromosome> nonDominateSelection( ArrayList<Chromosome> collection) {
int counter = 1, dominance;
Chromosome chromosome1, chromosome2;
ArrayList<Chromosome> result;
result = new ArrayList<Chromosome>();
result.add(collection.get(0));
out: while (counter < collection.size()) {
int jj = 0;
chromosome2 = collection.get(counter);
int resultsize = result.size();
boolean remove[] = new boolean[resultsize];
while (jj < resultsize) {
chromosome1 = result.get(jj);
dominance = check_dominance(chromosome2, chromosome1);
if (dominance == 1) { //chromosome2 dominates chromosome1
remove[jj] = true;
} else if (dominance == -1) { //chromosome1 dominates chromosome2
counter++;
continue out;
}
jj++;
}
for (int i = remove.length - 1; i >= 0; i--) {
if (remove[i])
result.remove(i);
}
result.add(chromosome2);
counter++;
}
return result;
}
/**
* Non-domination Selection procedure to filter out the dominated
* individuals from the given list.
*
* @param collection the collection of Chromosome object need to be filtered.
* @return the reference copy of the non-dominating individuals
*/
private void updateEP (Chromosome child) {
int i, dominance;
Chromosome chromosome1;
boolean add = true;
for (i=0; i < this.EP.size(); i++) {
chromosome1 = this.EP.get(i);
dominance = check_dominance(child, chromosome1);
if (dominance == 1) this.EP.remove(i); //child dominates chromosome1
else if (dominance == -1) add = false; //chromosome1 dominates child
}
if (add) {
if(!this.equalChromotoPop (child, this.EP)) this.EP.add(child);
}
}
private void diffEvolution(){
int i, type;
for(i=0; i < this.uPop.size(); i++){
if (Randomize.Rand() < this.probDelta) type = this.UPDATE_SOLUTION_NEIGHBOR;
else type = this.UPDATE_SOLUTION_WHOLEPOP;
this.crossover(this.uPop.get(i), this.uPop.get(this.matingselection(i,type)), type, i);
}
//update EP
for(i= 0; i < this.uPop.size(); i++) this.updateEP(this.uPop.get(i));
this.removeRedundant(this.EP);
}
private void crossover(Chromosome dad, Chromosome mom, int type, int pos_chromo) {
int i;
Gene[] genesSon1;
Gene[] genesSon2;
Chromosome son1, son2;
genesSon1 = new Gene[this.nAttr];
genesSon2 = new Gene[this.nAttr];
for (i=0; i < this.nAttr; i++) {
if ((dad.getGene(i).getActAs() == Gene.CONSEQUENT) || (mom.getGene(i).getActAs() == Gene.CONSEQUENT)) {
genesSon1[i] = dad.getGene(i).copy();
genesSon2[i] = mom.getGene(i).copy();
}
}
for (i=0; i < this.nAttr; i++) {
if ((dad.getGene(i).getActAs() != Gene.CONSEQUENT) && (mom.getGene(i).getActAs() != Gene.CONSEQUENT)) {
if (Randomize.Rand() < 0.5) {
genesSon1[i] = dad.getGene(i).copy();
genesSon2[i] = mom.getGene(i).copy();
}
else {
genesSon1[i] = mom.getGene(i).copy();
genesSon2[i] = dad.getGene(i).copy();
}
}
}
son1 = new Chromosome(genesSon1, this.numObjectives, this.T);
son2 = new Chromosome(genesSon2, this.numObjectives, this.T);
if (Randomize.Rand() < this.pm) this.mutate (son1);
if (Randomize.Rand() < this.pm) this.mutate (son2);
son1.forceConsistency();
son2.forceConsistency();
son1.computeObjetives (this.dataset);
son2.computeObjetives (this.dataset);
this.trials += 2;
if((!this.equalChromotoPop(son1, this.uPop)) && (son1.getSupport() > this.minSupport) && (!(son1.getSupport() > (1.0 - this.minSupport))) && (son1.getCF() > 0)){
this.update_Z(son1);
this.updateSolutions(son1, type, pos_chromo);
}
if((!this.equalChromotoPop(son2, this.uPop)) && (son2.getSupport() > this.minSupport) && (!(son2.getSupport() > 1.0 - this.minSupport)) && (son2.getCF() > 0)){
this.update_Z(son2);
this.updateSolutions(son2, type, pos_chromo);
}
}
private void mutate (Chromosome chr) {
int i;
double type_attr, min_attr, max_attr, top;
Gene gene;
i = Randomize.Randint(0, this.nAttr);
gene = chr.getGene(i);
type_attr = this.dataset.getAttributeType(i);
min_attr = this.dataset.getMin(i);
max_attr = this.dataset.getMax(i);
if (type_attr != myDataset.NOMINAL) {
if (type_attr == myDataset.REAL) {
if (Randomize.Rand() < 0.5) {
if (Randomize.Rand() < 0.5) {
top = Math.max(gene.getUpperBound() - (this.dataset.getAmplitude(i) / this.af), min_attr);
gene.setLowerBound(Randomize.RanddoubleClosed(top, gene.getLowerBound()));
}
else gene.setLowerBound(Randomize.Randdouble(gene.getLowerBound(), gene.getUpperBound()));
}
else {
if (Randomize.Rand() < 0.5) {
top = Math.min(gene.getLowerBound() + (this.dataset.getAmplitude(i) / this.af), max_attr);
gene.setUpperBound(Randomize.RanddoubleClosed(gene.getUpperBound(), top));
}
else gene.setUpperBound(Randomize.RanddoubleClosed(gene.getLowerBound()+0.0001, gene.getUpperBound()));
}
}
else {
if (Randomize.Rand() < 0.5) {
if (Randomize.Rand() < 0.5) {
top = Math.max(gene.getUpperBound() - (this.dataset.getAmplitude(i) / this.af), min_attr);
gene.setLowerBound(Randomize.RandintClosed((int)top, (int)gene.getLowerBound()));
}
else gene.setLowerBound(Randomize.Randint((int)gene.getLowerBound(), (int)gene.getUpperBound()));
}
else {
if (Randomize.Rand() < 0.5) {
top = Math.min(gene.getLowerBound() + (this.dataset.getAmplitude(i) / this.af), max_attr);
gene.setUpperBound(Randomize.RandintClosed((int)gene.getUpperBound(), (int)top));
}
else gene.setUpperBound(Randomize.RandintClosed((int)gene.getLowerBound() + 1, (int)gene.getUpperBound()));
}
}
}
else {
top = Randomize.RandintClosed((int)min_attr, (int)max_attr);
gene.setLowerBound(top);
gene.setUpperBound(top);
}
gene.setIsPositiveInterval ((Randomize.RandintClosed(0, 1) == 1) ? true : false);
gene.setActAs (gene.randAct());
}
private int matingselection(int pos_chr, int type){
// pos_chr : the id of current subproblem
// type : 1 - neighborhood; otherwise - whole population
if (type == this.UPDATE_SOLUTION_NEIGHBOR) return (Randomize.Randint(0, this.T));
else return (Randomize.Randint(0, this.uPop.size()));
}
private int[] random_permutation(int size) {
int i, j, tmp;
int[] index = new int[size];
for(i=0; i < size; i++) index[i] = i;
for(i=0; i < size; i++) {
j = Randomize.Randint(0, size);
tmp = index[i];
index[i] = index[j];
index[j] = tmp;
}
return index;
}
private void setWeightVectorsToEachChromo(){
int i,j;
double[] weightVector;
Chromosome chr;
Gene[] rnd_genes;
rnd_genes = new Gene[this.nAttr];
weightVector = new double [this.numObjectives];
for(i=0; i < this.nAttr; i++) rnd_genes[i] = new Gene();
for(i=0; i <= this.H; i++){
for(j=0; j <= (this.H - i); j++) {
weightVector[0] = (1.0 * i) / (1.0 * this.H);
weightVector[1] = (1.0 * j) / (1.0 * this.H);
weightVector[2] = (1.0 * (this.H - i - j)) / (1.0 * this.H);
chr = new Chromosome(rnd_genes, this.numObjectives, this.T);
chr.setWeightVector(weightVector);
this.uPop.add(chr);
}
}
}
/**
* Compute euclidean distance between any two weight vector to find
the number of closet weight vectors(neighbors vectors) to each weight vector
*/
private double[][] computeEuclidean() {
double[][] distance = new double[this.uPop.size()][this.uPop.size()];
for(int i=0; i < this.uPop.size(); i++) distance[i][i] = 0.0;
for(int i=0; i < this.uPop.size(); i++){
for(int j=i+1; j < this.uPop.size(); j++){
distance[i][j] = distance[j][i] = this.uPop.get(i).computeDistance(this.uPop.get(j).getWeightVector());
}
}
return (distance);
}
private int [] closestVector (double[] dist, int vector) {
int i, j, temp;
int [] closest = new int[this.T];
int [] index = new int[dist.length];
for (i=0; i < index.length; i++) index[i] = i;
for (i=1; i < index.length; i++) {
for (j=0; j < index.length-i; j++) {
if (dist[index[j+1]] < dist[index[j]]) {
temp = index[j+1];
index[j+1] = index[j];
index[j] = temp;
}
}
}
for (i=0, j=0; i < this.T; j++) {
if (index[j] != vector) {
closest[i] = index[j];
i++;
}
}
return (closest);
}
private void computeWeightVectorsNeighbors(){
double [][] distance;
distance = this.computeEuclidean();
for (int i=0; i < this.uPop.size(); i++)
this.uPop.get(i).setVectorsNeighbors(this.closestVector(distance[i], i));
}
private double bestObjectiveValue(int numberObj){
int i=0;
double bestValue;
if (numberObj > 0) bestValue = 1.0;
else{
bestValue = this.uPop.get(0).getObjective(numberObj);
for(i=1; i < this.uPop.size(); i++) {
if(bestValue < this.uPop.get(i).getObjective(numberObj)) bestValue = this.uPop.get(i).getObjective(numberObj);
}
}
return bestValue;
}
private double minObjectiveValue(int numberObj){
double minValue;
if (numberObj == 1) minValue = -1.0;
else minValue = 0.0;
return minValue;
}
private void initialize_Z(){
for(int i=0; i < this.numObjectives; i++){
this.Z[i] = this.bestObjectiveValue(i);
this.Z_min[i] = this.minObjectiveValue(i);
}
}
private void initializePopulation() {
int i, k, pos;
ArrayList<Integer> tr_not_marked;
Chromosome chromo;
this.uPop.clear();
this.setWeightVectorsToEachChromo();
this.computeWeightVectorsNeighbors();
//initialize population
tr_not_marked = new ArrayList<Integer> ();
this.trials = 0;
for(i=0; i < this.nTrans; i++) tr_not_marked.add(i);
k = 0;
while(k < this.uPop.size()) {
if(tr_not_marked.size() == 0)
for(i=0; i<this.nTrans; i++) tr_not_marked.add(i);
pos = tr_not_marked.get(Randomize.Randint(0, tr_not_marked.size()));
chromo = this.generateChromoCoveredPosNeg(pos);
chromo.setWeightVector(this.uPop.get(k).getWeightVector());
chromo.setVectorsNeighbors(this.uPop.get(k).getVectorsNeighbors());
if((!this.equalChromotoPop(chromo, this.uPop)) && (chromo.getSupport() > this.minSupport) && (!(chromo.getSupport() > (1.0 - this.minSupport))) && (chromo.getCF() > 0)) {
this.uPop.set(k, chromo.copy());
this.deleteTransCovered(this.uPop.get(k), tr_not_marked);
k++;
}
}
this.initialize_Z();
this.EP = this.nonDominateSelection(this.uPop);
}
private Chromosome generateChromoCoveredPosNeg(int pos_example){
int i, j,tmp, nAnts;
double lb, ub, value;
double[] example;
int[] sample;
Gene[] rnd_genes;
Chromosome chromo;
example = this.dataset.getExample(pos_example);
rnd_genes = new Gene[this.nAttr];
sample = new int[this.nAttr];
for(i=0; i < this.nAttr; i++) rnd_genes[i] = new Gene();
for(i=0; i < this.nAttr; i++) sample[i] = i;
//create chromo
rnd_genes = new Gene[this.nAttr];
for(i=0; i < this.nAttr; i++) rnd_genes[i] = new Gene();
for(i=0; i < this.nAttr; i++) {
j = Randomize.Randint(0, this.nAttr);
tmp = sample[i];
sample[i] = sample[j];
sample[j] = tmp;
}
nAnts = Randomize.Randint(1, this.nAttr);
// Antecedent
for (i=0; i < nAnts; i++) {
rnd_genes[sample[i]].setAttr (sample[i]);
rnd_genes[sample[i]].setActAs (Gene.ANTECEDENT);
rnd_genes[sample[i]].setIsPositiveInterval((Randomize.RandintClosed(0, 1) == 1) ? true : false);
value = example[sample[i]];
if (this.dataset.getAttributeType(sample[i]) != myDataset.NOMINAL) {
if (this.dataset.getAttributeType(sample[i]) == myDataset.REAL) {
if(rnd_genes[sample[i]].getIsPositiveInterval()){
lb = Math.max(value - (this.dataset.getAmplitude(sample[i]) / (this.af * 4)), this.dataset.getMin(sample[i]));
ub = Math.min(value + (this.dataset.getAmplitude(sample[i]) / (this.af * 4)), this.dataset.getMax(sample[i]));
}
else{ //is negative
if((value - this.dataset.getMin(sample[i])) > (this.dataset.getMax(sample[i]) - value)) { // left of the value
lb = value - ((value - this.dataset.getMin(sample[i])) - this.dataset.getAmplitude(sample[i]) / (this.af * 4));
ub = this.dataset.getMin(sample[i]) + ((value - this.dataset.getMin(sample[i])) - this.dataset.getAmplitude(sample[i]) / (this.af * 4));
}
else { // right of the value
lb = this.dataset.getMax(sample[i]) - ((this.dataset.getMax(sample[i]) - value) - this.dataset.getAmplitude(sample[i]) / (this.af * 4));
ub = value + ((this.dataset.getMax(sample[i]) - value) - this.dataset.getAmplitude(sample[i]) / (this.af * 4));
}
}
}
else {
if(rnd_genes[sample[i]].getIsPositiveInterval()){
lb = Math.max((int) (value - (this.dataset.getAmplitude(sample[i]) / (this.af * 4))), this.dataset.getMin(sample[i]));
ub = Math.min((int) (value + (this.dataset.getAmplitude(sample[i]) / (this.af * 4))), this.dataset.getMax(sample[i]));
}
else{ //is negative
if((value - this.dataset.getMin(sample[i])) > (this.dataset.getMax(sample[i]) - value)) { // left of the value
lb = (int) value - ((value - this.dataset.getMin(sample[i])) - this.dataset.getAmplitude(sample[i]) / (this.af * 4));
ub = (int) this.dataset.getMin(sample[i]) + ((value - this.dataset.getMin(sample[i])) - this.dataset.getAmplitude(sample[i]) / (this.af * 4));
}
else { // right of the value
lb = (int) this.dataset.getMax(sample[i]) - ((this.dataset.getMax(sample[i]) - value) - this.dataset.getAmplitude(sample[i]) / (this.af * 4));
ub = (int) value + ((this.dataset.getMax(sample[i]) - value) - this.dataset.getAmplitude(sample[i]) / (this.af * 4));
}
}
}
}
else lb = ub = (int) value;
rnd_genes[sample[i]].setLowerBound(lb);
rnd_genes[sample[i]].setUpperBound(ub);
rnd_genes[sample[i]].setType(this.dataset.getAttributeType(sample[i]));
rnd_genes[sample[i]].setMin_attr(this.dataset.getMin(sample[i]));
rnd_genes[sample[i]].setMax_attr(this.dataset.getMax(sample[i]));
}
// Consequent
rnd_genes[sample[i]].setAttr (sample[i]);
rnd_genes[sample[i]].setActAs (Gene.CONSEQUENT);
value = example[sample[i]];
if (this.dataset.getAttributeType(sample[i]) != myDataset.NOMINAL) {
if (this.dataset.getAttributeType(sample[i]) == myDataset.REAL) {
lb = Math.max(value - (this.dataset.getAmplitude(sample[i]) / (this.af * 4)), this.dataset.getMin(sample[i]));
ub = Math.min(value + (this.dataset.getAmplitude(sample[i]) / (this.af * 4)), this.dataset.getMax(sample[i]));
}
else {
lb = Math.max((int) (value - (this.dataset.getAmplitude(sample[i]) / (this.af * 4))), this.dataset.getMin(sample[i]));
ub = Math.min((int) (value + (this.dataset.getAmplitude(sample[i]) / (this.af * 4))), this.dataset.getMax(sample[i]));
}
}
else lb = ub = (int) value;
rnd_genes[sample[i]].setLowerBound(lb);
rnd_genes[sample[i]].setUpperBound(ub);
rnd_genes[sample[i]].setType(this.dataset.getAttributeType(sample[i]));
rnd_genes[sample[i]].setMin_attr(this.dataset.getMin(sample[i]));
rnd_genes[sample[i]].setMax_attr(this.dataset.getMax(sample[i]));
rnd_genes[sample[i]].setIsPositiveInterval((Randomize.RandintClosed(0, 1) == 1) ? true : false);
// Rest of the rule
for (i = nAnts + 1; i < this.nAttr; i++) {
rnd_genes[sample[i]].setAttr (sample[i]);
rnd_genes[sample[i]].setActAs (Gene.NOT_INVOLVED);
if (this.dataset.getAttributeType(sample[i]) != myDataset.NOMINAL) {
if (this.dataset.getAttributeType(sample[i]) == myDataset.REAL) {
value = Randomize.RanddoubleClosed (this.dataset.getMin(sample[i]), this.dataset.getMax(sample[i]));
lb = Math.max(value - (this.dataset.getAmplitude(sample[i]) / (this.af * 4)), this.dataset.getMin(sample[i]));
ub = Math.min(value + (this.dataset.getAmplitude(sample[i]) / (this.af * 4)), this.dataset.getMax(sample[i]));
}
else {
value = Randomize.RandintClosed ((int) this.dataset.getMin(sample[i]), (int) this.dataset.getMax(sample[i]));
lb = (int) Math.max((int) (value - (this.dataset.getAmplitude(sample[i])) / (this.af * 4)), this.dataset.getMin(sample[i]));
ub = (int) Math.min((int) (value + (this.dataset.getAmplitude(sample[i])) / (this.af * 4)), this.dataset.getMax(sample[i]));
}
}
else {
value = Randomize.RandintClosed ((int) this.dataset.getMin(sample[i]), (int) this.dataset.getMax(sample[i]));
lb = ub = (int) value;
}
rnd_genes[sample[i]].setLowerBound(lb);
rnd_genes[sample[i]].setUpperBound(ub);
rnd_genes[sample[i]].setType(this.dataset.getAttributeType(sample[i]));
rnd_genes[sample[i]].setMin_attr(this.dataset.getMin(sample[i]));
rnd_genes[sample[i]].setMax_attr(this.dataset.getMax(sample[i]));
rnd_genes[sample[i]].setIsPositiveInterval((Randomize.RandintClosed(0, 1) == 1) ? true : false);
}
chromo = new Chromosome(rnd_genes, this.numObjectives, this.T);
chromo.computeObjetives(this.dataset);
this.trials++;
return chromo;
}
private void deleteTransCovered (Chromosome chromo, ArrayList<Integer> tr_not_marked){
int i;
double [] example;
for (i = tr_not_marked.size()-1; i >= 0; i--) {
example = this.dataset.getExample(tr_not_marked.get(i));
if (chromo.isCovered(example)) tr_not_marked.remove(i);
}
}
private ArrayList<Integer> tr_notCovered_NoDominateSolutions(){
int i;
ArrayList<Integer> tr_not_marked = new ArrayList<Integer> ();
for(i=0; i < this.nTrans; i++) tr_not_marked.add(i);
for(i=0; i < this.EP.size(); i++) this.deleteTransCovered(this.EP.get(i), tr_not_marked);
return tr_not_marked;
}
private void restartPop(){
int i, k, pos, cont;
ArrayList<Integer> tr_not_marked;
Chromosome chromo;
tr_not_marked = this.tr_notCovered_NoDominateSolutions();
this.uPop.clear();
this.setWeightVectorsToEachChromo();
this.computeWeightVectorsNeighbors();
//initialize population
k = 0;
cont = 0;
while(k < this.uPop.size()) {
if(tr_not_marked.size() == 0)
for(i=0; i < this.nTrans; i++) tr_not_marked.add(i);
//create chromo
pos = tr_not_marked.get(Randomize.Randint(0, tr_not_marked.size()));
chromo = this.generateChromoCoveredPosNeg(pos);
chromo.setWeightVector(this.uPop.get(k).getWeightVector());
chromo.setVectorsNeighbors(this.uPop.get(k).getVectorsNeighbors());
if((!this.equalChromotoPop(chromo, this.uPop)) && (chromo.getSupport() > this.minSupport) && (!(chromo.getSupport() > (1.0 - this.minSupport))) && (chromo.getCF() > 0)) {
this.uPop.set(k, chromo.copy());
this.deleteTransCovered(this.uPop.get(k), tr_not_marked);
this.update_Z(chromo);
this.updateEP(chromo);
k++;
cont = 0;
}
else if (cont > 1000) {
tr_not_marked.clear();
cont = 0;
}
else cont++;
}
}
private void update_Z(Chromosome chr){
int i;
for(i=0; i < this.numObjectives; i++) {
if(this.Z[i] < chr.getObjective(i)) this.Z[i] = chr.getObjective(i);
if(this.Z_min[i] > chr.getObjective(i)) this.Z_min[i] = chr.getObjective(i);
}
}
private void updateSolutions(Chromosome child, int type, int r1){
int i, c, l, numIndP;
int[] perm;
if(type == this.UPDATE_SOLUTION_NEIGHBOR) numIndP = this.T;
else numIndP = this.uPop.size();
perm = random_permutation(numIndP);
for (i=0, c=0; (c <= this.nr) && (i < numIndP); i++) {
if(type == this.UPDATE_SOLUTION_NEIGHBOR) l = this.uPop.get(r1).getVectorsNeighbors(perm[i]);
else l = perm[i];
child.setWeightVector (this.uPop.get(l).getWeightVector());
child.setVectorsNeighbors (this.uPop.get(l).getVectorsNeighbors());
if(this.tchebycheffApproach(child) <= this.tchebycheffApproach(this.uPop.get(l))) {
this.uPop.set(l, child.copy());
c++;
}
}
if (c > 0) this.updatePop++;
}
private double tchebycheffApproach(Chromosome chr){
double g_max, g;
int i;
g_max = chr.getWeightVector(0) * (Math.abs(this.Z[0] - chr.getObjective(0)) / (this.Z[0] - this.Z_min[0]));
for(i=1; i < this.numObjectives; i++){
g = chr.getWeightVector(i) * (Math.abs(this.Z[i] - chr.getObjective(i)) / (this.Z[i] - this.Z_min[i]));
if(g > g_max) g_max = g;
}
return g_max;
}
private boolean equalChromotoPop(Chromosome chromo, ArrayList<Chromosome> pop) {
int i;
Chromosome aux;
boolean value = false;
for (i=0; (!value) && (i < pop.size()); i++) {
aux = pop.get(i);
if(chromo.equals(aux)) value = true;
}
return value;
}
static double roundDouble(double number, int decimalPlace){
double numberRound;
if(!Double.isInfinite(number)&&(!Double.isNaN(number))){
BigDecimal bd = new BigDecimal(number);
bd = bd.setScale(decimalPlace, BigDecimal.ROUND_UP);
numberRound = bd.doubleValue();
return numberRound;
}else return number;
}
public void saveReport(ArrayList<AssociationRule> rules,PrintWriter w) {
int i, j, r, cnt_cov_rec;
double avg_sup = 0.0, avg_conf = 0.0, avg_ant_length = 0.0, avg_lift = 0.0, avg_conv = 0.0, avg_CF = 0.0, avg_netConf = 0.0, avg_yulesQ = 0.0;
int[] covered;
AssociationRule rule;
covered = new int[this.nTrans];
for (i=0; i < this.nTrans; i++) covered[i] = 0;
for (r=0; r < rules.size(); r++) {
rule = rules.get(r);
avg_sup += rule.getSupport();
avg_conf += rule.getConfidence();
avg_lift += rule.getLift();
avg_ant_length += (rule.getnAnts()+1);
avg_conv += rule.getConv();
avg_CF += rule.getCF();
avg_netConf += rule.getNetConf();
avg_yulesQ += rule.getYulesQ();
for (j=0; j < this.nTrans; j++) {
if (covered[j] < 1) {
if (rule.isCovered(this.dataset.getExample(j))) covered[j] = 1;
}
}
}
cnt_cov_rec = 0;
for (i=0; i < this.nTrans; i++) cnt_cov_rec += covered[i];
w.println("\nNumber of Frequent Itemsets found: " + "-");
System.out.println("\nNumber of Frequent Itemsets found: " + "-");
w.println("\nNumber of Association Rules generated: " + rules.size());
System.out.println("Number of Association Rules generated: " + rules.size());
if (! rules.isEmpty()) {
w.println("Average Support: " + roundDouble(( avg_sup / rules.size() ),2));
System.out.println("Average Support: " + roundDouble(( avg_sup / rules.size() ),2));
w.println("Average Confidence: " + roundDouble(( avg_conf / rules.size() ),2));
System.out.println("Average Confidence: " + roundDouble(( avg_conf / rules.size() ),2));
w.println("Average Lift: " + roundDouble(( avg_lift / rules.size() ),2));
System.out.println("Average Lift: " + roundDouble(( avg_lift / rules.size() ),2));
w.println("Average Conviction: " + roundDouble(( avg_conv / rules.size() ),2));
System.out.println("Average Conviction: " + roundDouble(( avg_conv/ rules.size() ),2));
w.println("Average Certain Factor: " + roundDouble(( avg_CF/ rules.size() ),2));
System.out.println("Average Certain Factor: " + roundDouble(( avg_CF/ rules.size()),2));
w.println("Average Netconf: " + roundDouble(( avg_netConf/ rules.size() ),2));
System.out.println("Average Netconf: " + roundDouble(( avg_netConf/ rules.size()),2));
w.println("Average YulesQ: " + roundDouble(( avg_yulesQ/ rules.size() ),2));
System.out.println("Average YulesQ: " + roundDouble(( avg_yulesQ/ rules.size()),2));
w.println("Average Number of Antecedents: " + roundDouble(( avg_ant_length / rules.size() ),2));
System.out.println("Average Number of Antecedents: " + roundDouble(( avg_ant_length / rules.size() ),2));
w.println("Number of Covered Records (%): " + roundDouble((100.0 * cnt_cov_rec) / this.nTrans, 2));
System.out.println("Number of Covered Records (%): " + roundDouble((100.0 * cnt_cov_rec) / this.nTrans, 2));
}
}
public void removeRedundant (ArrayList<Chromosome> upop) {
int i, j;
boolean stop;
Chromosome chromo1, chromo2;
Collections.sort(upop);
for (i=0; i < upop.size(); i++) {
stop = false;
for (j = upop.size()-1; j >=0 && !stop; j--) {
if (j != i) {
chromo1 = upop.get(i);
chromo2 = upop.get(j);
if (chromo1.getnAnts() == chromo2.getnAnts()) {
if (chromo1.isSubChromo(chromo2)) {
if (chromo1.getCF() >= chromo2.getCF()) {
upop.remove(j);
if (j < i) i--;
}
else {
upop.remove(i);
i--;
stop = true;
}
}
}
else if (chromo1.getnAnts() > chromo2.getnAnts()) stop = true;
}
}
}
}
public void printPareto() {
int i;
boolean stop;
Chromosome chromo;
stop = false;
this.paretos += "";
this.paretos += ("Support\tantecedent_support\tconsequent_support\tConfidence\tLift\tConv\tCF\tNetConf\tYulesQ\tnAttributes\n");
for (i=0; i < this.EP.size() && !stop; i++) {
chromo = this.EP.get(i);
this.paretos += ("" + roundDouble(chromo.getSupport(),2) + "\t" + roundDouble(chromo.getAntsSupport(),2) + "\t" + roundDouble(chromo.getConsSupport(),2) + "\t" + roundDouble(chromo.getConfidence(),2) + "\t" + roundDouble(chromo.getObjective(0),2) + "\t" + roundDouble(chromo.getConv(),2) + "\t" + roundDouble(chromo.getCF(),2) + "\t" + roundDouble(chromo.getNetConf(),2) + "\t" + roundDouble(chromo.getYulesQ(),2) + "\t" + (chromo.getnAnts()+1) + "\n");
}
}
public ArrayList<AssociationRule> generateRulesPareto() {
int i;
Chromosome chromo;
ArrayList<AssociationRule> rulesPareto = new ArrayList<AssociationRule>();
for (i=0; i < this.EP.size(); i++) {
chromo = this.EP.get(i);
rulesPareto.add (new AssociationRule(chromo));
}
return rulesPareto;
}
public String getParetos() {
return (this.paretos);
}
private int check_dominance (Chromosome a, Chromosome b){
int i;
int flag1;
int flag2;
flag1 = 0;
flag2 = 0;
for (i=0; i < this.numObjectives; i++){
if (a.getObjective(i) > b.getObjective(i)) flag1 = 1;
else if (a.getObjective(i) < b.getObjective(i)) flag2 = 1;
}
if ((flag1 == 1) && (flag2 == 0)) return (1);
else if ((flag1 == 0) && (flag2 == 1)) return (-1);
else return (0);
}
}