Logo Search packages:      
Sourcecode: cdk version File versions  Download package

CrossoverMachine.java

/* $Revision$ $Author$ $Date$    
 * 
 * Copyright (C) 2000-2007  The Chemistry Development Kit (CDK) project
 * 
 * Contact: cdk-devel@lists.sourceforge.net
 * 
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public License
 * as published by the Free Software Foundation; either version 2.1
 * 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 Lesser General Public License for more details.
 * 
 * You should have received a copy of the GNU Lesser General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 
 */
package org.openscience.cdk.structgen.stochastic.operator;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import org.openscience.cdk.exception.CDKException;
import org.openscience.cdk.interfaces.IAtomContainer;
import org.openscience.cdk.interfaces.IBond;
import org.openscience.cdk.math.RandomNumbersTool;
import org.openscience.cdk.structgen.stochastic.PartialFilledStructureMerger;

/**
 * Modified molecular structures by applying crossover operator on a pair of parent structures 
 * and generate a pair of offspring structures. Each of the two offspring structures inherits 
 * a certain fragments from both of its parents.
 * 
 * @cdk.module structgen
 * @cdk.githash
 */
00041 public class CrossoverMachine  
{
      private IAtomContainer[] redChild,blueChild;
      private List redAtoms,blueAtoms;
      List children;    
      
      PartialFilledStructureMerger pfsm;
      
      /** selects a partitioning mode*/
00050       int splitMode = 2;      
      /** selects a partitioning scale*/  
00052       int numatoms = 5;
      /** Indicates that <code>crossover</code> is using SPLIT_MODE_RADNDOM mode. */
00054     public static final int SPLIT_MODE_RADNDOM = 0;
    /** Indicates that <code>crossover</code> is using SPLIT_MODE_DEPTH_FIRST mode. */
00056     public static final int SPLIT_MODE_DEPTH_FIRST = 1;     
    /** Indicates that <code>crossover</code> is using SPLIT_MODE_BREADTH_FIRST mode. */
00058     public static final int SPLIT_MODE_BREADTH_FIRST = 2;
      
    /**
     * Constructs a new CrossoverMachine operator.
     */
00063     public CrossoverMachine()
    {
          redChild = new IAtomContainer[2];
            blueChild = new IAtomContainer[2];
            
            redAtoms = new ArrayList();
            blueAtoms = new ArrayList();        
            children = new ArrayList(2);
            try
            {
                  pfsm = new PartialFilledStructureMerger();
            }
            catch(java.lang.Exception ex){ }          
    }
      
      /**
     * Performs the n point crossover of two <code>MolChromosome</code>
     * supplied by the <code>CrossInfo.parents</code> class and stores the resulting
     * chromosomes in <code>CrossInfo.children</code>.
     * 
     * @return an object storing information generated by the operator.
     * @exception IllegalArgumentException if some of the crosspoints defined are
     * greater than the size of the corresponding chromosome.
     */
00087     public List doCrossover(IAtomContainer dad, IAtomContainer mom) throws CDKException
    {
            int dim = dad.getAtomCount();
            
            /***randomly divide atoms into two parts: redAtoms and blueAtoms.***/
            redAtoms.clear();
            blueAtoms.clear();            
            
          if (splitMode==SPLIT_MODE_RADNDOM)
            {
                  /*better way to randomly divide atoms into two parts: redAtoms and blueAtoms.*/
                  for (int i = 0; i < dim; i++)
                        redAtoms.add(Integer.valueOf(i));
                  for (int i = 0; i < (dim - numatoms); i++)
                  {   int ranInt = RandomNumbersTool.randomInt(0,redAtoms.size()-1);
                        redAtoms.remove(ranInt);
                        blueAtoms.add(Integer.valueOf(ranInt));
                  }
                         
            }
            else
            {
                  /*split graph using depth/breadth first traverse*/
                  ChemGraph graph = new ChemGraph(dad);
                  graph.setNumAtoms(numatoms);
                  if (splitMode==SPLIT_MODE_DEPTH_FIRST)
                  {
                        redAtoms = graph.pickDFgraph();
                  }
                  else
                        redAtoms = graph.pickBFgraph();
                        
                  for (int i = 0; i < dim; i++){
                        Integer element = Integer.valueOf(i);
                        if (!(redAtoms.contains(element)))
                        {
                              blueAtoms.add(element);
                        }     
                  }
            }           
            /*** dividing over ***/
            
            
            redChild[0] = dad.getBuilder().newAtomContainer(dad); 
            blueChild[0] = dad.getBuilder().newAtomContainer(dad); 
            redChild[1] = dad.getBuilder().newAtomContainer(mom); 
            blueChild[1] = dad.getBuilder().newAtomContainer(mom); 
            
            
            for (int j = 0; j < blueAtoms.size(); j++)
            {
                  Iterator bonds = redChild[1].bonds().iterator();
                  while (bonds.hasNext()) {
                        IBond bond = (IBond)bonds.next();
                        if (bond.contains(redChild[0].getAtom(((Integer)blueAtoms.get(j)).intValue())))
                        {
                              redChild[0].removeBond(bond);
                        }
                  }
            }


            for (int j = 0; j < blueAtoms.size(); j++)
            {
                  Iterator bonds = redChild[1].bonds().iterator();
                  while (bonds.hasNext()) {
                        IBond bond = (IBond)bonds.next();
                        if (bond.contains(redChild[1].getAtom(((Integer)blueAtoms.get(j)).intValue())))
                        {
                              bonds.remove(); // this removes it from redChild[1] too
                        }
                  }
            }


            for (int j = 0; j < redAtoms.size(); j++)
            {
                  Iterator bonds = blueChild[0].bonds().iterator();
                  while (bonds.hasNext()) {
                        IBond bond = (IBond)bonds.next();
                        if (bond.contains(blueChild[0].getAtom(((Integer)redAtoms.get(j)).intValue())))
                        {
                              bonds.remove();
                        }
                  }
            }


            for (int j = 0; j < redAtoms.size(); j++) {
                  Iterator bonds = blueChild[1].bonds().iterator();
                  while (bonds.hasNext()) {
                        IBond bond = (IBond)bonds.next();
                        if (bond.contains(blueChild[1].getAtom(((Integer)redAtoms.get(j)).intValue())))
                        {
                              bonds.remove();
                        }
                  }
            }

            
            redChild[0].add(blueChild[1]);
            if (children.size()==2)
            {
                  redChild[1].add(blueChild[0]);
            }
            
            
            
            for (int f = 0; f < children.size(); f++)
            {
                  pfsm.setAtomContainer(redChild[f]);
                  children.add(f, pfsm.generate());
            }
        return children;                  
    } 
}

Generated by  Doxygen 1.6.0   Back to index