⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 chromosome.java

📁 clustering data for the different techniques of data mining
💻 JAVA
📖 第 1 页 / 共 3 页
字号:
/*
   Chromosome.java

   Definition of the class Chromosome

   (P)2002  Dana Cristofor

*/

/*

GAClust - Clustering categorical databases using genetic algorithms
Copyright (C) 2002  Dana Cristofor


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 2 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, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
USA

GAClust was written by Dana Cristofor (dana@cs.umb.edu).

*/

import java.util.*;

/**
 * Chromosome
 *
 * @version 	1.0
 * @author	Dana Cristofor
 */
public class Chromosome extends Partition
{
  protected int crossoverType;
  protected int mutationType;
  protected int distributionType;

  // crossover method types
  // random crossover
  static public final int CROSS_RAND              = 11;
  // exchanging two random classes
  static public final int CROSS_X_2RAND_CLASS     = 12;
  // exchanging best classes
  static public final int CROSS_AM_X_BEST_CLASS   = 13;
  // exchanging best worst classes
  static public final int CROSS_AM_X_BEST_WORST   = 14;
  // exchanging two random classes
  static public final int CROSS_AM_X_2RAND_CLASS  = 15;

  // mutation method types
  static public final int MUT_RAND      = 21;  // random mutation
  static public final int MUT_MOVE_ELEM = 22;  // move elements between classes
  static public final int MUT_SWAP_ELEM = 23;  // swap elements between classes

  // types of methods for distributing elements to classes
  static public final int DISTRIB_NONE    = 31;
  static public final int DISTRIB_RAND    = 32;
  static public final int DISTRIB_TO_EVEN = 33;  

  Chromosome(int size, int nc, int classFitnessType, 
	     int crossoverType, int mutationType, int distributionType)
  {
    super(size, nc, classFitnessType);
    this.crossoverType = crossoverType;
    this.mutationType = mutationType;
    this.distributionType = distributionType;
  }

  /** @return the crossover type */
  public int getCrossoverType()
  {
    return crossoverType;
  }

  /** @return the mutation type */
  public int getMutationType()
  {
    return mutationType;
  }

  /** @return the distribution type */
  public int getDistributionType()
  {
    return distributionType;
  }

  /** computes the fitness of the chromosome and the fitness of the
   * classes for chromosomes in the collection <code>c1</code>
   * relative to the partitions in the collection <code>c2</code>;
   * <code>N1</code> is the size of the collection <code>c1</code>;
   * <code>N2</code> represents the number of partitions in
   * <code>c2</code> **/
  static public void computeFitnessValues(Chromosome[] c1, int N1,
					  Partition[] c2, int N2, 
					  int entropyMeasure, 
					  int fitnessMeasure,
					  double[] weightDBTarget,
					  double[] weightTargetDB,
					  double[] weight)
  {
    for (int i = 0; i < N1; i++)
      c1[i].computeFitness(c2, N2, 
			   entropyMeasure, fitnessMeasure, 
			   weightDBTarget, weightTargetDB, weight);
  }

  /** computes fitness value of chromosomes in collection
   * <code>c1</code> based on the fitness value of chromosome
   * <code>chrom1</code> and on the intersection between
   * <code>chrom1</code> and the collection of <code>N</code>
   * partitions in <code>db</code> */
  static public void computeFitnessValues(Chromosome chrom1, 
					  Hashtable[] intersectMap,
					  Partition[] db, int N, 
					  Chromosome[] c1, int N1,
					  int entropyMeasure, 
					  int fitnessMeasure,
					  double[] weightDBTarget,
					  double[] weightTargetDB,
					  double[] weight)
  {
    for (int i = 0; i < N1; i++)
      {
	if (Global.ULTRA_VERBOSE == 1)
	  {
	    System.out.println("working on chromosome " + i);
	    System.out.println("best chrom fitness " + chrom1.getFitness());
	  }

	computeFitnessValue(chrom1, intersectMap,
			    db, N, c1[i],
			    entropyMeasure, fitnessMeasure, 
			    weightDBTarget, weightTargetDB, weight);
	
	if (Global.ULTRA_VERBOSE == 1)
	  System.out.println("chromosome " + i + " fitness: " 
			     + c1[i].getFitness());
      }
  }


  /** compute fitness value of chromosome <code>chrom2</code> based on
   * the fitness value of chromosome <code>chrom1</code> and on the
   * intersection between <code>chrom1</code> and the collection of
   * <code>N</code> partitions in <code>db</code> */
  static public void computeFitnessValue(Chromosome chrom1, 
					 Hashtable[] intersectMap,
					 Partition[] db, int N, 
					 Chromosome chrom2,
					 int entropyMeasure, 
					 int fitnessMeasure,
					 double[] weightDBTarget,
					 double[] weightTargetDB,
					 double[] weight)
  {
    if (Global.DEBUG == 1)
      if (chrom1.getSize() != chrom2.getSize())
	{
	  System.err.println("ERROR! Chromosome.computeFitnessValue():"
			     + "chromosomes have different size.");
	  System.exit(1);
	}

    int SIZE = chrom1.getSize();
    // <int, <int, int>>
    Hashtable[] localIntersectMap = new Hashtable[N];
    for (int i = 0; i < N; i++)
      {
	localIntersectMap[i] = new Hashtable();
	for (Enumeration classes = intersectMap[i].keys();
	     classes.hasMoreElements();)
	  {
	    Integer currClass = (Integer)classes.nextElement();
	    Hashtable map = (Hashtable)intersectMap[i].get(currClass);
	    localIntersectMap[i].put(currClass, new Hashtable(map));
	  }
      }

    if (Global.ULTRA_VERBOSE == 1)
      {
	System.out.println("chrom1 intersections with db");
	for (int i = 0; i < N; i++)
	  {
	    System.out.println("attr " + i);
	    for (Enumeration classes1 = localIntersectMap[i].keys();
		 classes1.hasMoreElements();)
	      {
		Integer currClass1 = (Integer)classes1.nextElement();
		System.out.print(currClass1 + " | ");
		Hashtable value1 = 
		  (Hashtable)localIntersectMap[i].get(currClass1);
		for (Enumeration classes2 = value1.keys(); 
		     classes2.hasMoreElements(); )
		  {
		    Integer currClass2 = (Integer)classes2.nextElement();
		    System.out.print(currClass2 + "(" 
				       + (Integer)value1.get(currClass2) 
				       + ") ");
		  }
		System.out.println();
	      }
	  }
      }
  
    int numModif = 0;

    // loop on all partitions from collection c
    for (int i = 0; i < N; i++)
      // loop on all rowids
      for (int rowid = 0; rowid < SIZE; rowid++)
	// if we have different values on position rowid
	if (chrom1.get(rowid) != chrom2.get(rowid))
	  {
	    numModif++;
	    // for class Cs1 = chrom1[rowid] modify
	    // class Bt = db[i] 
	    // if Cs1 x Bt is 1 delete Bt from the map
	    Integer Cs1 = new Integer(chrom1.get(rowid));
	    Integer Bt = new Integer(db[i].get(rowid));
	    Hashtable map = (Hashtable)localIntersectMap[i].get(Cs1);

	    int count = ((Integer)map.get(Bt)).intValue();
	    if (count == 1)
	      {
		map.remove(Bt);
		// if the map associated with Cs1 becomes empty, remove Cs1
		// from localIntersectMap[i]
		if (map.size() == 0)
		  localIntersectMap[i].remove(Cs1);
	      }
	    else
	      // decrementing Cs1 x Bt
	      map.put(Bt, new Integer(count - 1));
	    
	    // for class Cs2 = chrom2[rowid] modify
	    // class Bt = db[j] by incrementing Cs2 x Bt
	    Integer Cs2 = new Integer(chrom2.get(rowid));
	   
	    if (localIntersectMap[i].containsKey(Cs2))
	      {
		// if localIntersectMap[i] contains the key Cs2 get
		// the count of Bt and increment it
		map = (Hashtable)localIntersectMap[i].get(Cs2); 
		count = 0;
		if (map.containsKey(Bt) == true)
		  count = ((Integer)map.get(Bt)).intValue();
		map.put(Bt, new Integer(count + 1));
	      }
	    else
	      {
		// create a new map with <Bt, 1> and add the map <Cs2,
		// <Bt, 1>> to localIntersectMap[i]
		map = new Hashtable();
		map.put(Bt, new Integer(1));
		localIntersectMap[i].put(Cs2, map);
	      }
	  }
    
    if (Global.ULTRA_VERBOSE == 1)
      {
	System.out.println("final intersections");
	for (int i = 0; i < N; i++)
	  {
	    System.out.println("attr " + i);
	    for (Enumeration classes1 = localIntersectMap[i].keys();
		 classes1.hasMoreElements();)
	      {
		Integer currClass1 = (Integer)classes1.nextElement();
		System.out.print(currClass1 + " | ");
		Hashtable value1 = 
		  (Hashtable)localIntersectMap[i].get(currClass1);
		for (Enumeration classes2 = value1.keys(); 
		     classes2.hasMoreElements(); )
		  {
		    Integer currClass2 = (Integer)classes2.nextElement();
		    System.out.println(currClass2 + "(" 
				       + (Integer)value1.get(currClass2) 
				       + ") ");
		  }
		System.out.println();
	      }
	  }
    
	if (numModif > 0)
	  System.out.println("intersectMap has been modified " + numModif);
      }
  
    if (numModif > 0)
      // now in localIntersectMap we have the intersections between
      // chrom2 and the partitions in db
      // based on these intersections compute the fitness of chrom2
      chrom2.computeFitness(localIntersectMap,
			    db, N, 
			    entropyMeasure, fitnessMeasure, 
			    weightDBTarget, weightTargetDB, weight);
    else
      // chrom1 is identical with chrom2
      chrom2.set(chrom1);
  }

  ///////////////// CROSSOVER METHODS //////////////////////

  /** performs the crossover between this chromosome and the one
   * received as argument according to crossoverType */
  public void crossover(Chromosome c, Random rand)
  {
    // if the two partitions are equal return immediately
    if (isEqual(c))
      return;

    if (Global.VERBOSE == 1)
      System.out.print("C ");
    
    switch(crossoverType)
      {
      case CROSS_RAND:
	crossoverR(c, rand);
	break;
  
      case CROSS_X_2RAND_CLASS:
	crossoverXC(c, rand);
	break;
	
      case CROSS_AM_X_2RAND_CLASS:
      case CROSS_AM_X_BEST_CLASS:
      case CROSS_AM_X_BEST_WORST:
	crossoverAM(c, rand);
	break;
	
      default:
	System.err.println("ERROR! Chromosome.crossover():"
			   + "invalid crossover type " + crossoverType);
	System.exit(1);
      }
  }

  /** crosses over this chromosome with the chromosome received as
   * argument by randomly selecting a single cut point and exchanging
   * the last portion starting from the cut point between the two
   * chromosomes */
  private void crossoverR(Chromosome  c, Random rand)
  {
    if (Global.ULTRA_VERBOSE == 1)
      System.out.print("Crossover RANDOM ");
  
    // randomly select a position to cut the chromosomes
    // we will switch positions k to size-1
    // between the two parents
    // k can be a number between 1 and size-1
    int k = 1 + rand.nextInt(size-1);
    // save tail of v in a temp array
    int[] temp = new int[size - k];

    if (Global.ULTRA_VERBOSE == 1)
      {
	System.out.println(" first chromosome: ");
	for (int j = 0; j < size; j++)
	  System.out.print(v[j] + " ");
	System.out.println();

	System.out.println( " second chromosome: ");
	for (int j = 0; j < c.size; j++)
	  System.out.print(c.v[j] + " ");
	System.out.println();
  
	System.out.println("crossed over at position " + k);      
      }
    
    for (int i = k; i < size; i++)
      temp[i-k] = v[i];

    // copy tail of c.v instead
    for (int i = k; i < size; i++)
      set(i, c.v[i]);

    // copy temp over tail of c
    for (int i = k; i < size; i++)
      c.set(i, temp[i-k]);

    if (Global.ULTRA_VERBOSE == 1)
      {
	System.out.println(" first chromosome:");
	for (int j = 0; j < size; j++)
	  System.out.print(v[j] + " ");
	System.out.println();

	System.out.println(" second chromosome:");
	for (int j = 0; j < c.size; j++)
	  System.out.print(c.v[j] + " ");
	System.out.println();
      }
  }

  /** crosses over this chromosome with the one received as argument;
   * selects a random class and exchanges this class between the two
   * parent chromosomes */
  private void crossoverXC(Chromosome c, Random rand)
  {
    if (Global.ULTRA_VERBOSE == 1)
      System.out.print("Crossover XC ");

    if (getNoClasses() == 1 || c.getNoClasses() == 1)
      return;
  
    // randomly select a class to exchange between the chromosomes
    // k should be a number between 1 and the number of classes
    int noClasses = getNoClasses();
    int k = 1 + rand.nextInt(noClasses);

    if (Global.ULTRA_VERBOSE == 1)
      {
	System.out.println(" first chromosome:");
	for (int j = 0; j < size; j++)
	  System.out.print(v[j] + " ");
	System.out.println();

	System.out.println(" second chromosome:");
	for (int j = 0; j < c.size; j++)
	  System.out.print(c.v[j] + " ");
	System.out.println();
  
	System.out.println("exchanging the class " + k);      
      }

    // save partition c in a temp array
    int[] temp = new int[c.size];
    for (int j = 0; j < c.size; j++)
      temp[j] = c.v[j];

    // copy the class k from this chromosome into c
    // the old elements from c that belong to class k
    // are moved to other classes
    for (int j = 0; j < size; j++)
      {
	if (v[j] == k)
	  c.set(j, k);
	else if (c.v[j] == k)
	  {
	    // move old elements to other distinct classes
	    int new_k = 1 + rand.nextInt(noClasses);
	    while (new_k == k)
	      new_k = 1 + rand.nextInt(noClasses);
	    
	    c.set(j, new_k); 
	  }    
      }
  
    // copy the class k from temp into this chromosome
    // the old elements from v that belonged to class k
    // are moved to other classes
    for (int j = 0; j < size; j++)
      {
	if (temp[j] == k)
	  set(j, k);
	else if (v[j] == k)
	  {
	    // move old elements to other classes
	    int new_k = 1 + rand.nextInt(noClasses);
	    while (new_k == k)
	      new_k = 1 + rand.nextInt(noClasses);
	    
	    set(j, new_k); 
	  }
      }
  
    if (Global.ULTRA_VERBOSE == 1)
      {
	System.out.println(" first chromosome:");
	for (int j = 0; j < size; j++)
	  System.out.print(v[j] + " ");
	System.out.println();
  
	System.out.println(" second chromosome:");
	for (int j = 0; j < c.size; j++)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -