ignite-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From ch...@apache.org
Subject [2/3] ignite git commit: IGNITE-6899: Adding GA Grid to Apache Ignite ML module.
Date Sun, 04 Mar 2018 15:08:04 GMT
http://git-wip-us.apache.org/repos/asf/ignite/blob/0cdded31/modules/ml/src/main/java/org/apache/ignite/ml/genetic/GAGrid.java
----------------------------------------------------------------------
diff --git a/modules/ml/src/main/java/org/apache/ignite/ml/genetic/GAGrid.java b/modules/ml/src/main/java/org/apache/ignite/ml/genetic/GAGrid.java
new file mode 100644
index 0000000..56895f7
--- /dev/null
+++ b/modules/ml/src/main/java/org/apache/ignite/ml/genetic/GAGrid.java
@@ -0,0 +1,454 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.ml.genetic;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Random;
+
+import javax.cache.Cache.Entry;
+
+import org.apache.ignite.Ignite;
+import org.apache.ignite.IgniteCache;
+import org.apache.ignite.IgniteLogger;
+import org.apache.ignite.cache.query.QueryCursor;
+import org.apache.ignite.cache.query.SqlFieldsQuery;
+import org.apache.ignite.cache.query.SqlQuery;
+
+import org.apache.ignite.ml.genetic.cache.GeneCacheConfig;
+import org.apache.ignite.ml.genetic.cache.PopulationCacheConfig;
+import org.apache.ignite.ml.genetic.parameter.GAConfiguration;
+import org.apache.ignite.ml.genetic.parameter.GAGridConstants;
+import org.apache.ignite.ml.genetic.utils.GAGridUtils;
+
+/**
+ * Central class responsible for orchestrating distributive Genetic Algorithm.
+ *
+ * This class accepts a GAConfigriation and Ignite instance.
+ */
+public class GAGrid {
+
+    IgniteLogger igniteLogger = null;
+    /** GAConfiguraton */
+    private GAConfiguration config = null;
+    /** Ignite instance */
+    private Ignite ignite = null;
+    /** Population cache */
+    private IgniteCache<Long, Chromosome> populationCache = null;
+    /** Gene cache */
+    private IgniteCache<Long, Gene> geneCache = null;
+    /** population keys */
+    private List<Long> populationKeys = new ArrayList();
+
+    /**
+     * @param config GAConfiguration
+     * @param ignite Ignite
+     */
+    public GAGrid(GAConfiguration config, Ignite ignite) {
+        this.ignite = ignite;
+        this.config = config;
+        this.ignite = ignite;
+        this.igniteLogger = ignite.log();
+
+        // Get/Create cache
+        populationCache = this.ignite.getOrCreateCache(PopulationCacheConfig.populationCache());
+        populationCache.clear();
+
+        // Get/Create cache
+        geneCache = this.ignite.getOrCreateCache(GeneCacheConfig.geneCache());
+        geneCache.clear();
+    }
+
+    /**
+     * Calculate average fitness value
+     *
+     * @return Average fitness score
+     */
+
+    private Double calculateAverageFitness() {
+
+        double avgFitnessScore = 0;
+
+        IgniteCache<Long, Gene> cache = ignite.cache(GAGridConstants.POPULATION_CACHE);
+
+        // Execute query to get names of all employees.
+        SqlFieldsQuery sql = new SqlFieldsQuery("select AVG(FITNESSSCORE) from Chromosome");
+
+        // Iterate over the result set.
+        try (QueryCursor<List<?>> cursor = cache.query(sql)) {
+            for (List<?> row : cursor)
+                avgFitnessScore = (Double)row.get(0);
+        }
+
+        return avgFitnessScore;
+    }
+
+    /**
+     * Calculate fitness each Chromosome in population
+     *
+     * @param chromosomeKeys List of chromosome primary keys
+     */
+    private void calculateFitness(List<Long> chromosomeKeys) {
+        Boolean boolValue = this.ignite.compute().execute(new FitnessTask(this.config), chromosomeKeys);
+    }
+
+    /**
+     * @param fittestKeys List of chromosome keys that will be copied from
+     * @param selectedKeys List of chromosome keys that will be overwritten evenly by fittestKeys
+     * @return Boolean value
+     */
+    private Boolean copyFitterChromosomesToPopulation(List<Long> fittestKeys, List<Long> selectedKeys) {
+        double truncatePercentage = this.config.getTruncateRate();
+
+        int totalSize = this.populationKeys.size();
+
+        int truncateCount = (int)(truncatePercentage * totalSize);
+
+        int numberOfCopies = selectedKeys.size() / truncateCount;
+
+        Boolean boolValue = this.ignite.compute()
+            .execute(new TruncateSelectionTask(this.config, fittestKeys, numberOfCopies), selectedKeys);
+
+        return Boolean.TRUE;
+
+    }
+
+    /**
+     * create a Chromsome
+     *
+     * @param numberOfGenes Number of Genes in resepective Chromosome
+     * @return Chromosome
+     */
+    private Chromosome createChromosome(int numberOfGenes) {
+        long[] genes = new long[numberOfGenes];
+        List<Long> keys = new ArrayList();
+        int k = 0;
+        while (k < numberOfGenes) {
+            long key = selectGene(k);
+
+            if (!(keys.contains(key))) {
+                genes[k] = key;
+                keys.add(key);
+                k = k + 1;
+            }
+        }
+        Chromosome aChromsome = new Chromosome(genes);
+        return aChromsome;
+    }
+
+    /**
+     * Perform crossover
+     *
+     * @param leastFitKeys List of primary keys for Chromsomes that are considered 'least fit'
+     */
+    private void crossover(List<Long> leastFitKeys) {
+        Boolean boolValue = this.ignite.compute().execute(new CrossOverTask(this.config), leastFitKeys);
+    }
+
+    /**
+     * Evolve the population
+     *
+     * @return Fittest Chromosome
+     */
+    public Chromosome evolve() {
+        // keep track of current generation
+        int generationCount = 1;
+
+        Chromosome fittestChomosome = null;
+
+        initializeGenePopulation();
+
+        intializePopulation();
+
+        // Calculate Fitness
+        calculateFitness(this.populationKeys);
+
+        // Retrieve chromosomes in order by fitness value
+        List<Long> keys = getChromosomesByFittest();
+
+        // Calculate average fitness value of population
+        double averageFitnessScore = calculateAverageFitness();
+
+        fittestChomosome = populationCache.get(keys.get(0));
+
+        List<Gene> genes = GAGridUtils.getGenesForChromosome(ignite, fittestChomosome);
+
+        // while NOT terminateCondition met
+        while (!(config.getTerminateCriteria().isTerminationConditionMet(fittestChomosome, averageFitnessScore,
+            generationCount))) {
+            generationCount = generationCount + 1;
+
+            // We will crossover/mutate over chromosomes based on selection method
+
+            List<Long> selectedKeysforCrossMutaton = selection(keys);
+
+            // Cross Over
+            crossover(selectedKeysforCrossMutaton);
+
+            // Mutate
+            mutation(selectedKeysforCrossMutaton);
+
+            // Calculate Fitness
+            calculateFitness(selectedKeysforCrossMutaton);
+
+            // Retrieve chromosomes in order by fitness value
+            keys = getChromosomesByFittest();
+
+            // Retreive the first chromosome from the list
+            fittestChomosome = populationCache.get(keys.get(0));
+
+            // Calculate average fitness value of population
+            averageFitnessScore = calculateAverageFitness();
+
+            // End Loop
+
+        }
+        return fittestChomosome;
+    }
+
+    /**
+     * helper routine to retrieve Chromosome keys in order of fittest
+     *
+     * @return List of primary keys for chromosomes.
+     */
+    private List<Long> getChromosomesByFittest() {
+        List<Long> orderChromKeysByFittest = new ArrayList();
+        String orderDirection = "desc";
+
+        if(config.isHigherFitnessValueFitter()==false)
+         {
+                orderDirection = "asc";
+         }
+        String fittestSQL = "select _key from Chromosome order by fitnessScore " + orderDirection;
+
+        // Execute query to retrieve keys for ALL Chromosomes by fittnessScore
+        QueryCursor<List<?>> cursor = populationCache.query(new SqlFieldsQuery(fittestSQL));
+
+        List<List<?>> res = cursor.getAll();
+
+        for (List row : res) {
+            Long key = (Long)row.get(0);
+            orderChromKeysByFittest.add(key);
+        }
+
+        return orderChromKeysByFittest;
+    }
+
+    /**
+     * @param keys List of primary keys for respective Chromosomes
+     * @return List of keys for respective Chromosomes
+     */
+    private List<Long> getFittestKeysForTruncation(List<Long> keys) {
+        double truncatePercentage = this.config.getTruncateRate();
+
+        int truncateCount = (int)(truncatePercentage * keys.size());
+
+        List<Long> selectedKeysToRetain = keys.subList(0, truncateCount);
+
+        return selectedKeysToRetain;
+    }
+
+    /**
+     * initialize the Gene pool
+     */
+    void initializeGenePopulation() {
+        geneCache.clear();
+
+        List<Gene> genePool = config.getGenePool();
+
+        for (Gene gene : genePool) {
+            geneCache.put(gene.id(), gene);
+        }
+    }
+
+    /**
+     * Initialize the population of Chromosomes
+     */
+    void initializePopulation() {
+        int populationSize = config.getPopulationSize();
+        populationCache.clear();
+
+        for (int j = 0; j < populationSize; j++) {
+            Chromosome chromosome = createChromosome(config.getChromosomeLength());
+            populationCache.put(chromosome.id(), chromosome);
+            populationKeys.add(chromosome.id());
+        }
+
+    }
+
+    /**
+     * initialize the population of Chromosomes based on GAConfiguration
+     */
+    void intializePopulation() {
+        int populationSize = config.getPopulationSize();
+        populationCache.clear();
+
+        for (int j = 0; j < populationSize; j++) {
+            Chromosome chromosome = createChromosome(config.getChromosomeLength());
+            populationCache.put(chromosome.id(), chromosome);
+            populationKeys.add(chromosome.id());
+        }
+
+    }
+
+    /**
+     * Perform mutation
+     *
+     * @param leastFitKeys List of primary keys for Chromosomes that are considered 'least fit'.
+     */
+    private void mutation(List<Long> leastFitKeys) {
+        Boolean boolValue = this.ignite.compute().execute(new MutateTask(this.config), leastFitKeys);
+    }
+
+    /**
+     * select a gene from the Gene pool
+     *
+     * @return Primary key of respective Gene
+     */
+    private long selectAnyGene() {
+        int idx = selectRandomIndex(config.getGenePool().size());
+        Gene gene = config.getGenePool().get(idx);
+        return gene.id();
+    }
+
+    /**
+     * For our implementation we consider 'best fit' chromosomes, by selecting least fit chromosomes for crossover and
+     * mutation
+     *
+     * As result, we are interested in least fit chromosomes.
+     *
+     * @param keys List of primary keys for respective Chromsomes
+     * @return List of primary Keys for respective Chromosomes that are considered least fit
+     */
+    private List<Long> selectByElitism(List<Long> keys) {
+        int elitismCount = this.config.getElitismCount();
+        List<Long> leastFitKeys = keys.subList(elitismCount, keys.size());
+        return leastFitKeys;
+    }
+
+    /**
+     * Truncation selection simply retains the fittest x% of the population. These fittest individuals are duplicated so
+     * that the population size is maintained.
+     *
+     * @param keys
+     * @return List of keys
+     */
+
+    private List<Long> selectByTruncation(List<Long> keys) {
+        double truncatePercentage = this.config.getTruncateRate();
+
+        int truncateCount = (int)(truncatePercentage * keys.size());
+
+        List<Long> selectedKeysForCrossOver = keys.subList(truncateCount, keys.size());
+
+        return selectedKeysForCrossOver;
+    }
+
+    /**
+     * @param k Gene index in Chromosome.
+     * @return Primary key of respective Gene chosen
+     */
+    private long selectGene(int k) {
+        if (config.getChromosomeCriteria() == null) {
+            return (selectAnyGene());
+        }
+        else {
+            return (selectGeneByChromsomeCriteria(k));
+        }
+    }
+
+    /**
+     * method assumes ChromosomeCriteria is set.
+     *
+     * @param k Gene index in Chromosome
+     * @return Primary key of respective Gene
+     */
+    private long selectGeneByChromsomeCriteria(int k) {
+        List<Gene> genes = new ArrayList();
+
+        StringBuffer sbSqlClause = new StringBuffer("_val like '");
+        sbSqlClause.append("%");
+        sbSqlClause.append(config.getChromosomeCriteria().getCriteria().get(k));
+        sbSqlClause.append("%'");
+
+        IgniteCache<Long, Gene> cache = ignite.cache(GAGridConstants.GENE_CACHE);
+
+        SqlQuery sql = new SqlQuery(Gene.class, sbSqlClause.toString());
+
+        try (QueryCursor<Entry<Long, Gene>> cursor = cache.query(sql)) {
+            for (Entry<Long, Gene> e : cursor)
+                genes.add(e.getValue());
+        }
+
+        int idx = selectRandomIndex(genes.size());
+
+        Gene gene = genes.get(idx);
+        return gene.id();
+    }
+
+    /**
+     * @param sizeOfGenePool Size of Gene pool
+     * @return Index
+     */
+    private int selectRandomIndex(int sizeOfGenePool) {
+        Random randomGenerator = new Random();
+        int index = randomGenerator.nextInt(sizeOfGenePool);
+        return index;
+    }
+
+    /**
+     * Select chromosomes
+     *
+     * @param chromosomeKeys List of population primary keys for respective Chromsomes
+     * @return List of primary keys for respective Chromsomes
+     */
+    private List<Long> selection(List<Long> chromosomeKeys) {
+        List<Long> selectedKeys = new ArrayList();
+
+        GAGridConstants.SELECTION_METHOD selectionMethod = config.getSelectionMethod();
+
+        switch (selectionMethod) {
+            case SELECTON_METHOD_ELETISM:
+                selectedKeys = selectByElitism(chromosomeKeys);
+                break;
+            case SELECTION_METHOD_TRUNCATION:
+                selectedKeys = selectByTruncation(chromosomeKeys);
+
+                List<Long> fittestKeys = getFittestKeysForTruncation(chromosomeKeys);
+
+                Boolean boolValue = copyFitterChromosomesToPopulation(fittestKeys, selectedKeys);
+
+                // copy more fit keys to rest of population
+                break;
+
+            default:
+                break;
+        }
+
+        return selectedKeys;
+    }
+
+    /**
+     * Get primary keys for Chromosomes
+     *
+     * @return List of Chromosome primary keys
+     */
+    List<Long> getPopulationKeys() {
+        return populationKeys;
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/0cdded31/modules/ml/src/main/java/org/apache/ignite/ml/genetic/Gene.java
----------------------------------------------------------------------
diff --git a/modules/ml/src/main/java/org/apache/ignite/ml/genetic/Gene.java b/modules/ml/src/main/java/org/apache/ignite/ml/genetic/Gene.java
new file mode 100644
index 0000000..e793547
--- /dev/null
+++ b/modules/ml/src/main/java/org/apache/ignite/ml/genetic/Gene.java
@@ -0,0 +1,86 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.ml.genetic;
+
+import java.util.concurrent.atomic.AtomicLong;
+
+import org.apache.ignite.cache.query.annotations.QuerySqlField;
+
+/**
+ * Represents the discrete parts of a potential solution (ie: Chromosome)
+ *
+ * <p>
+ *
+ * Gene is a container for a POJO that developer will implement. <br/>
+ *
+ * For the Movie Fitness example, the Movie object is the POJO contained within Gene. <br/> NOTE: Gene resides in cache:
+ * 'geneCache'. This cache is replicated.
+ *
+ *
+ * </p>
+ */
+public class Gene {
+
+    private static final AtomicLong ID_GEN = new AtomicLong();
+
+    /** Id (indexed). */
+    @QuerySqlField(index = true)
+    private Long id;
+
+    /** value used to model an individual Gene. */
+    private Object value;
+
+    /**
+     * object Object  parameter.
+     *
+     * @param object
+     */
+    public Gene(Object object) {
+        id = ID_GEN.incrementAndGet();
+        this.value = object;
+    }
+
+    /**
+     * @return value for Gene
+     */
+    public Object getValue() {
+        return value;
+    }
+
+    /**
+     * Set the Gene value
+     *
+     * @param object Value for Gene
+     */
+    public void setValue(Object object) {
+        this.value = object;
+    }
+
+    /**
+     * @return Primary key for Gene
+     */
+    public Long id() {
+        return id;
+    }
+
+    @Override
+    public String toString() {
+        return "Gene [id=" + id + ", value=" + value + "]";
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/0cdded31/modules/ml/src/main/java/org/apache/ignite/ml/genetic/IFitnessFunction.java
----------------------------------------------------------------------
diff --git a/modules/ml/src/main/java/org/apache/ignite/ml/genetic/IFitnessFunction.java b/modules/ml/src/main/java/org/apache/ignite/ml/genetic/IFitnessFunction.java
new file mode 100644
index 0000000..ef031ec
--- /dev/null
+++ b/modules/ml/src/main/java/org/apache/ignite/ml/genetic/IFitnessFunction.java
@@ -0,0 +1,39 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.ml.genetic;
+
+import java.util.List;
+
+/**
+ * Fitness function are used to determine how optimal a particular solution is relative to other solutions.
+ *
+ * <p> The evaluate() method should be implemented for this interface. The fitness function is provided list of Genes.
+ *
+ * The evaluate method should return a positive double value that reflects fitness score.
+ *
+ * </p>
+ */
+
+public interface IFitnessFunction {
+
+    /**
+     * @param genes Genes within an individual Chromosome
+     * @return Fitness score
+     */
+    public double evaluate(List<Gene> genes);
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/0cdded31/modules/ml/src/main/java/org/apache/ignite/ml/genetic/MutateJob.java
----------------------------------------------------------------------
diff --git a/modules/ml/src/main/java/org/apache/ignite/ml/genetic/MutateJob.java b/modules/ml/src/main/java/org/apache/ignite/ml/genetic/MutateJob.java
new file mode 100644
index 0000000..ed3f0d9
--- /dev/null
+++ b/modules/ml/src/main/java/org/apache/ignite/ml/genetic/MutateJob.java
@@ -0,0 +1,94 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.ml.genetic;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.ignite.Ignite;
+import org.apache.ignite.IgniteCache;
+import org.apache.ignite.IgniteException;
+import org.apache.ignite.compute.ComputeJobAdapter;
+import org.apache.ignite.resources.IgniteInstanceResource;
+import org.apache.ignite.transactions.Transaction;
+
+import org.apache.ignite.ml.genetic.parameter.GAGridConstants;
+
+/**
+ * Responsible for applying mutation on respective Chromosome based on mutation Rate
+ */
+public class MutateJob extends ComputeJobAdapter {
+
+    /** primary key of Chromosome to mutate **/
+    private Long key;
+
+    /** primary keys of genes to be used in mutation **/
+    private List<Long> mutatedGeneKeys;
+
+    @IgniteInstanceResource
+    private Ignite ignite = null;
+
+    /** Mutation Rate **/
+    private double mutationRate;
+
+    /**
+     * @param key Primary key of chromosome
+     * @param mutatedGeneKeys Primary keys of genes to be used in mutation
+     * @param mutationRate Mutation rate
+     */
+    public MutateJob(Long key, List<Long> mutatedGeneKeys, double mutationRate) {
+        this.key = key;
+        this.mutationRate = mutationRate;
+        this.mutatedGeneKeys = mutatedGeneKeys;
+    }
+
+    /**
+     * Perform mutation
+     *
+     * @return Boolean value
+     */
+    public Boolean execute() throws IgniteException {
+        // TODO Auto-generated method stub
+
+        IgniteCache<Long, Chromosome> populationCache = ignite.cache(GAGridConstants.POPULATION_CACHE);
+
+        Chromosome chromosome = populationCache.localPeek(key);
+
+        long[] geneKeys = chromosome.getGenes();
+
+        for (int k = 0; k < this.mutatedGeneKeys.size(); k++) {
+            // Mutate gene based on MutatonRate
+            if (this.mutationRate > Math.random()) {
+                geneKeys[k] = this.mutatedGeneKeys.get(k);
+            }
+        }
+
+        chromosome.setGenes(geneKeys);
+
+        Transaction tx = ignite.transactions().txStart();
+
+        populationCache.put(chromosome.id(), chromosome);
+
+        tx.commit();
+
+        return Boolean.TRUE;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/0cdded31/modules/ml/src/main/java/org/apache/ignite/ml/genetic/MutateTask.java
----------------------------------------------------------------------
diff --git a/modules/ml/src/main/java/org/apache/ignite/ml/genetic/MutateTask.java b/modules/ml/src/main/java/org/apache/ignite/ml/genetic/MutateTask.java
new file mode 100644
index 0000000..c72a73a
--- /dev/null
+++ b/modules/ml/src/main/java/org/apache/ignite/ml/genetic/MutateTask.java
@@ -0,0 +1,191 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.ml.genetic;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Random;
+
+import javax.cache.Cache.Entry;
+
+import org.apache.ignite.Ignite;
+import org.apache.ignite.IgniteCache;
+import org.apache.ignite.IgniteException;
+import org.apache.ignite.cache.affinity.Affinity;
+import org.apache.ignite.cache.query.QueryCursor;
+import org.apache.ignite.cache.query.SqlQuery;
+import org.apache.ignite.cluster.ClusterNode;
+import org.apache.ignite.compute.ComputeJob;
+import org.apache.ignite.compute.ComputeJobResult;
+import org.apache.ignite.compute.ComputeJobResultPolicy;
+import org.apache.ignite.compute.ComputeTaskAdapter;
+import org.apache.ignite.resources.IgniteInstanceResource;
+
+import org.apache.ignite.ml.genetic.parameter.GAConfiguration;
+import org.apache.ignite.ml.genetic.parameter.GAGridConstants;
+
+/**
+ * Responsible for applying mutation on respective chromosomes.  <br/>
+ *
+ * MutateTask leverages Ignite's data affinity capabilities for routing MutateJobs to primary IgniteNode where <br/>
+ * chromosomes reside.<br/>
+ */
+public class MutateTask extends ComputeTaskAdapter<List<Long>, Boolean> {
+
+    @IgniteInstanceResource
+    private Ignite ignite = null;
+
+    private GAConfiguration config = null;
+
+    /**
+     * @param config GAConfiguration
+     */
+    public MutateTask(GAConfiguration config) {
+        this.config = config;
+    }
+
+    /**
+     * choose mutated genes.
+     *
+     * @return Gene primary keys
+     */
+    private List<Long> getMutatedGenes() {
+        List<Long> mutatedGenes = new ArrayList();
+        config.getChromosomeLength();
+
+        for (int i = 0; i < config.getChromosomeLength(); i++) {
+            // Gene gene=config.getGenePool().get(selectRandomIndex(config.getGenePool().size()));
+            mutatedGenes.add(selectGene(i));
+        }
+
+        return mutatedGenes;
+    }
+
+    /**
+     * @param nodes List of ClusterNode
+     * @param chromosomeKeys Primary keys for respective chromosomes
+     */
+    public Map map(List<ClusterNode> nodes, List<Long> chromosomeKeys) throws IgniteException {
+
+        Map<ComputeJob, ClusterNode> map = new HashMap<>();
+        Affinity affinity = ignite.affinity(GAGridConstants.POPULATION_CACHE);
+
+        for (Long key : chromosomeKeys) {
+            MutateJob ajob = new MutateJob(key, getMutatedGenes(), this.config.getMutationRate());
+            ClusterNode primary = affinity.mapKeyToNode(key);
+            map.put(ajob, primary);
+        }
+        return map;
+    }
+
+    /**
+     * We return TRUE if success, else Exection is thrown.
+     *
+     * @param list List of ComputeJobResult
+     * @return Boolean value
+     */
+    public Boolean reduce(List<ComputeJobResult> list) throws IgniteException {
+        return Boolean.TRUE;
+    }
+
+    /**
+     * @param res ComputeJobResult
+     * @param rcvd List of ComputeJobResult
+     * @return ComputeJobResultPolicy
+     */
+    public ComputeJobResultPolicy result(ComputeJobResult res, List<ComputeJobResult> rcvd) {
+        IgniteException err = res.getException();
+
+        if (err != null)
+            return ComputeJobResultPolicy.FAILOVER;
+
+        // If there is no exception, wait for all job results.
+        return ComputeJobResultPolicy.WAIT;
+
+    }
+
+    /**
+     * select a gene from the Gene pool
+     *
+     * @return Primary key of Gene
+     */
+    private long selectAnyGene() {
+        int idx = selectRandomIndex(config.getGenePool().size());
+        Gene gene = config.getGenePool().get(idx);
+        return gene.id();
+    }
+
+    /**
+     * select a gene based from the Gene pool
+     *
+     * @param k Gene index in Chromosome.
+     * @return Primary key of Gene
+     */
+    private long selectGene(int k) {
+        if (config.getChromosomeCriteria() == null) {
+            return (selectAnyGene());
+        }
+        else {
+            return (selectGeneByChromsomeCriteria(k));
+        }
+    }
+
+    /**
+     * method assumes ChromosomeCriteria is set.
+     *
+     * @param k Gene index in Chromosome.
+     * @return Primary key of Gene
+     */
+    private long selectGeneByChromsomeCriteria(int k) {
+        List<Gene> genes = new ArrayList();
+
+        StringBuffer sbSqlClause = new StringBuffer("_val like '");
+        sbSqlClause.append("%");
+        sbSqlClause.append(config.getChromosomeCriteria().getCriteria().get(k));
+        sbSqlClause.append("%'");
+
+        IgniteCache<Long, Gene> cache = ignite.cache(GAGridConstants.GENE_CACHE);
+
+        SqlQuery sql = new SqlQuery(Gene.class, sbSqlClause.toString());
+
+        try (QueryCursor<Entry<Long, Gene>> cursor = cache.query(sql)) {
+            for (Entry<Long, Gene> e : cursor)
+                genes.add(e.getValue());
+        }
+
+        int idx = selectRandomIndex(genes.size());
+
+        Gene gene = genes.get(idx);
+        return gene.id();
+    }
+
+    /**
+     * select an index at random
+     *
+     * @param sizeOfGenePool Size of gene pool
+     * @return Index of Gene to be selected
+     */
+    private int selectRandomIndex(int sizeOfGenePool) {
+        Random randomGenerator = new Random();
+        int index = randomGenerator.nextInt(sizeOfGenePool);
+        return index;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/0cdded31/modules/ml/src/main/java/org/apache/ignite/ml/genetic/TruncateSelectionJob.java
----------------------------------------------------------------------
diff --git a/modules/ml/src/main/java/org/apache/ignite/ml/genetic/TruncateSelectionJob.java b/modules/ml/src/main/java/org/apache/ignite/ml/genetic/TruncateSelectionJob.java
new file mode 100644
index 0000000..4404e5c
--- /dev/null
+++ b/modules/ml/src/main/java/org/apache/ignite/ml/genetic/TruncateSelectionJob.java
@@ -0,0 +1,88 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.ml.genetic;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.ignite.Ignite;
+import org.apache.ignite.IgniteCache;
+import org.apache.ignite.IgniteException;
+import org.apache.ignite.compute.ComputeJobAdapter;
+import org.apache.ignite.resources.IgniteInstanceResource;
+import org.apache.ignite.transactions.Transaction;
+
+import org.apache.ignite.ml.genetic.parameter.GAGridConstants;
+
+/**
+ * Responsible for performing truncate selection
+ */
+public class TruncateSelectionJob extends ComputeJobAdapter {
+
+    /** primary key of Chromosome to mutate */
+    private Long key;
+
+    /** primary keys of genes to be used in mutation */
+    private List<Long> mutatedGeneKeys;
+
+    @IgniteInstanceResource
+    private Ignite ignite = null;
+
+    /**
+     * @param key Primary key of Chromosome to mutate
+     * @param mutatedGeneKeys Primary keys of genes to be used in mutation
+     */
+    public TruncateSelectionJob(Long key, List<Long> mutatedGeneKeys) {
+        this.key = key;
+        this.mutatedGeneKeys = mutatedGeneKeys;
+    }
+
+    /**
+     * Perform mutation
+     *
+     * @return Boolean value
+     */
+    public Boolean execute() throws IgniteException {
+        // TODO Auto-generated method stub
+
+        IgniteCache<Long, Chromosome> populationCache = ignite.cache(GAGridConstants.POPULATION_CACHE);
+
+        Chromosome chromosome = populationCache.localPeek(key);
+
+        long[] geneKeys = chromosome.getGenes();
+
+        for (int k = 0; k < this.mutatedGeneKeys.size(); k++) {
+            {
+                geneKeys[k] = this.mutatedGeneKeys.get(k);
+            }
+        }
+
+        chromosome.setGenes(geneKeys);
+
+        Transaction tx = ignite.transactions().txStart();
+
+        populationCache.put(chromosome.id(), chromosome);
+
+        tx.commit();
+
+        return Boolean.TRUE;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/0cdded31/modules/ml/src/main/java/org/apache/ignite/ml/genetic/TruncateSelectionTask.java
----------------------------------------------------------------------
diff --git a/modules/ml/src/main/java/org/apache/ignite/ml/genetic/TruncateSelectionTask.java b/modules/ml/src/main/java/org/apache/ignite/ml/genetic/TruncateSelectionTask.java
new file mode 100644
index 0000000..7a5817f
--- /dev/null
+++ b/modules/ml/src/main/java/org/apache/ignite/ml/genetic/TruncateSelectionTask.java
@@ -0,0 +1,173 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.ml.genetic;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import javax.cache.Cache.Entry;
+
+import org.apache.ignite.Ignite;
+import org.apache.ignite.IgniteCache;
+import org.apache.ignite.IgniteException;
+import org.apache.ignite.cache.affinity.Affinity;
+import org.apache.ignite.cache.query.QueryCursor;
+import org.apache.ignite.cache.query.SqlQuery;
+import org.apache.ignite.cluster.ClusterNode;
+import org.apache.ignite.compute.ComputeJob;
+import org.apache.ignite.compute.ComputeJobResult;
+import org.apache.ignite.compute.ComputeJobResultPolicy;
+import org.apache.ignite.compute.ComputeTaskAdapter;
+import org.apache.ignite.resources.IgniteInstanceResource;
+
+import org.apache.ignite.ml.genetic.parameter.GAConfiguration;
+import org.apache.ignite.ml.genetic.parameter.GAGridConstants;
+
+/**
+ * Responsible for performing truncate selection.
+ */
+
+public class TruncateSelectionTask extends ComputeTaskAdapter<List<Long>, Boolean> {
+
+    @IgniteInstanceResource
+    private Ignite ignite = null;
+
+    /** GAConfiguraiton */
+    private GAConfiguration config = null;
+
+    /** fittest keys */
+    private List<Long> fittestKeys = null;
+
+    /** number of Copies */
+    private int numberOfCopies = 0;
+
+    /**
+     * @param config GAConfiguration
+     * @param fittestKeys List of long
+     * @param numberOfCopies Number of Copies
+     */
+    public TruncateSelectionTask(GAConfiguration config, List<Long> fittestKeys, int numberOfCopies) {
+        this.config = config;
+        this.fittestKeys = fittestKeys;
+        this.numberOfCopies = numberOfCopies;
+    }
+
+    /**
+     * Retrieve a chromosome
+     *
+     * @param key Primary key of chromosome
+     * @return Chromosome
+     */
+    private Chromosome getChromosome(Long key) {
+        IgniteCache<Long, Chromosome> cache = ignite.cache(GAGridConstants.POPULATION_CACHE);
+        StringBuffer sbSqlClause = new StringBuffer();
+        sbSqlClause.append("_key IN (");
+        sbSqlClause.append(key);
+        sbSqlClause.append(")");
+
+        Chromosome chromosome = null;
+
+        SqlQuery sql = new SqlQuery(Chromosome.class, sbSqlClause.toString());
+
+        try (QueryCursor<Entry<Long, Chromosome>> cursor = cache.query(sql)) {
+            for (Entry<Long, Chromosome> e : cursor)
+                chromosome = (e.getValue())
+
+                    ;
+        }
+
+        return chromosome;
+    }
+
+    /**
+     * Return a List of lists containing keys
+     *
+     * @return List of lists containing keys
+     */
+    private List<List<Long>> getEnhancedPopulation() {
+        List<List<Long>> list = new ArrayList();
+
+        for (Long key : fittestKeys) {
+            Chromosome copy = getChromosome(key);
+            for (int i = 0; i < numberOfCopies; i++) {
+                long[] thegenes = copy.getGenes();
+                List<Long> geneList = new ArrayList();
+                for (int k = 0; k < copy.getGenes().length; k++) {
+                    geneList.add(thegenes[k]);
+                }
+                list.add(geneList);
+            }
+        }
+
+        return list;
+    }
+
+    /**
+     * @param nodes List of ClusterNode
+     * @param chromosomeKeys Primary keys for respective chromosomes
+     * @return Map of nodes to jobs
+     */
+    public Map map(List<ClusterNode> nodes, List<Long> chromosomeKeys) throws IgniteException {
+        Map<ComputeJob, ClusterNode> map = new HashMap<>();
+        Affinity affinity = ignite.affinity(GAGridConstants.POPULATION_CACHE);
+
+        // Retrieve enhanced population
+        List<List<Long>> enhancedPopulation = getEnhancedPopulation();
+
+        int k = 0;
+        for (Long key : chromosomeKeys) {
+            TruncateSelectionJob ajob = new TruncateSelectionJob(key, (List)enhancedPopulation.get(k));
+            ClusterNode primary = affinity.mapKeyToNode(key);
+            map.put(ajob, primary);
+            k = k + 1;
+        }
+        return map;
+
+    }
+
+    /**
+     * We return TRUE if success, else Exception is thrown.
+     *
+     * @param list List of ComputeJobResult
+     * @return Boolean value
+     */
+    public Boolean reduce(List<ComputeJobResult> list) throws IgniteException {
+        // TODO Auto-generated method stub
+        return Boolean.TRUE;
+    }
+
+    /**
+     * @param res ComputeJobResult
+     * @param rcvd List of ComputeJobResult
+     * @return ComputeJobResultPolicy
+     */
+    public ComputeJobResultPolicy result(ComputeJobResult res, List<ComputeJobResult> rcvd) {
+        IgniteException err = res.getException();
+
+        if (err != null)
+            return ComputeJobResultPolicy.FAILOVER;
+
+        // If there is no exception, wait for all job results.
+        return ComputeJobResultPolicy.WAIT;
+
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/0cdded31/modules/ml/src/main/java/org/apache/ignite/ml/genetic/cache/GeneCacheConfig.java
----------------------------------------------------------------------
diff --git a/modules/ml/src/main/java/org/apache/ignite/ml/genetic/cache/GeneCacheConfig.java b/modules/ml/src/main/java/org/apache/ignite/ml/genetic/cache/GeneCacheConfig.java
new file mode 100644
index 0000000..1976941
--- /dev/null
+++ b/modules/ml/src/main/java/org/apache/ignite/ml/genetic/cache/GeneCacheConfig.java
@@ -0,0 +1,52 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.ml.genetic.cache;
+
+import org.apache.ignite.cache.CacheMode;
+import org.apache.ignite.cache.CacheRebalanceMode;
+import org.apache.ignite.configuration.CacheConfiguration;
+
+import org.apache.ignite.ml.genetic.Gene;
+import org.apache.ignite.ml.genetic.functions.GAGridFunction;
+import org.apache.ignite.ml.genetic.parameter.GAGridConstants;
+
+/**
+ * Cache configuration for GAGridConstants.GENE_CACHE
+ *
+ * cache maintains full population of genes.
+ */
+
+public class GeneCacheConfig {
+
+    /**
+     * @return Cache Configuration
+     */
+    public static CacheConfiguration<Long, Gene> geneCache() {
+
+        CacheConfiguration<Long, Gene> cfg = new CacheConfiguration<>(GAGridConstants.GENE_CACHE);
+        cfg.setIndexedTypes(Long.class, Gene.class);
+        cfg.setCacheMode(CacheMode.REPLICATED);
+        cfg.setRebalanceMode(CacheRebalanceMode.SYNC);
+        cfg.setStatisticsEnabled(true);
+        cfg.setBackups(1);
+        cfg.setSqlFunctionClasses(GAGridFunction.class);
+        return cfg;
+
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/0cdded31/modules/ml/src/main/java/org/apache/ignite/ml/genetic/cache/PopulationCacheConfig.java
----------------------------------------------------------------------
diff --git a/modules/ml/src/main/java/org/apache/ignite/ml/genetic/cache/PopulationCacheConfig.java b/modules/ml/src/main/java/org/apache/ignite/ml/genetic/cache/PopulationCacheConfig.java
new file mode 100644
index 0000000..bc7fcd6
--- /dev/null
+++ b/modules/ml/src/main/java/org/apache/ignite/ml/genetic/cache/PopulationCacheConfig.java
@@ -0,0 +1,53 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.ml.genetic.cache;
+
+import org.apache.ignite.cache.CacheAtomicityMode;
+import org.apache.ignite.cache.CacheMode;
+import org.apache.ignite.cache.CacheRebalanceMode;
+import org.apache.ignite.configuration.CacheConfiguration;
+
+import org.apache.ignite.ml.genetic.Chromosome;
+import org.apache.ignite.ml.genetic.parameter.GAGridConstants;
+
+/**
+ * Cache configuration for GAGridConstants.POPULATION_CACHE
+ *
+ * cache population of chromosomes (ie: potential solutions)
+ */
+
+public class PopulationCacheConfig {
+
+    /**
+     * @return Cache Configuration
+     */
+    public static CacheConfiguration<Long, Chromosome> populationCache() {
+
+        CacheConfiguration<Long, Chromosome> cfg = new CacheConfiguration<>(GAGridConstants.POPULATION_CACHE);
+        cfg.setIndexedTypes(Long.class, Chromosome.class);
+        cfg.setCacheMode(CacheMode.PARTITIONED);
+        cfg.setRebalanceMode(CacheRebalanceMode.SYNC);
+        cfg.setAtomicityMode(CacheAtomicityMode.TRANSACTIONAL);
+        cfg.setStatisticsEnabled(true);
+        cfg.setBackups(1);
+
+        return cfg;
+
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/0cdded31/modules/ml/src/main/java/org/apache/ignite/ml/genetic/cache/package-info.java
----------------------------------------------------------------------
diff --git a/modules/ml/src/main/java/org/apache/ignite/ml/genetic/cache/package-info.java b/modules/ml/src/main/java/org/apache/ignite/ml/genetic/cache/package-info.java
new file mode 100644
index 0000000..cb13b7c
--- /dev/null
+++ b/modules/ml/src/main/java/org/apache/ignite/ml/genetic/cache/package-info.java
@@ -0,0 +1,21 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * Contains cache configurations for GA Grid
+ */
+package org.apache.ignite.ml.genetic.cache;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ignite/blob/0cdded31/modules/ml/src/main/java/org/apache/ignite/ml/genetic/functions/GAGridFunction.java
----------------------------------------------------------------------
diff --git a/modules/ml/src/main/java/org/apache/ignite/ml/genetic/functions/GAGridFunction.java b/modules/ml/src/main/java/org/apache/ignite/ml/genetic/functions/GAGridFunction.java
new file mode 100644
index 0000000..3848b68
--- /dev/null
+++ b/modules/ml/src/main/java/org/apache/ignite/ml/genetic/functions/GAGridFunction.java
@@ -0,0 +1,132 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.ml.genetic.functions;
+
+import java.sql.SQLException;
+import java.sql.Types;
+import java.util.List;
+
+import org.apache.ignite.Ignite;
+import org.apache.ignite.Ignition;
+import org.apache.ignite.cache.query.annotations.QuerySqlFunction;
+import org.h2.tools.SimpleResultSet;
+
+import org.apache.ignite.ml.genetic.Chromosome;
+import org.apache.ignite.ml.genetic.Gene;
+import org.apache.ignite.ml.genetic.parameter.GAConfiguration;
+import org.apache.ignite.ml.genetic.utils.GAGridUtils;
+
+/**
+ * Responsible for providing custom SQL functions to retrieve optimization results
+ */
+public class GAGridFunction {
+
+    /** GAConfiguration **/
+    private GAConfiguration config = null;
+
+    /**
+     * @param config GA Configuration
+     */
+    public GAGridFunction(GAConfiguration config) {
+        this.config = config;
+    }
+
+    /**
+     * Retrieve solutions in descending order based on fitness score
+     *
+     * @return Result set
+     * @throws SQLException
+     */
+    @QuerySqlFunction
+    public static SimpleResultSet getSolutionsDesc() {
+        return (getChromosomes("order by fitnessScore desc"));
+    }
+
+    /**
+     * Retrieve solutions in ascending order based on fitness score
+     *
+     * @return Result set
+     * @throws SQLException
+     */
+    @QuerySqlFunction
+    public static SimpleResultSet getSolutionsAsc() throws SQLException {
+        return (getChromosomes("order by fitnessScore asc"));
+    }
+
+    /**
+     * Retrieve and individual solution by Chromosome key
+     *
+     * @param key Primary key of Chromosome
+     * @return SimpleResultSet
+     * @throws SQLException
+     */
+    @QuerySqlFunction
+    public static SimpleResultSet getSolutionById(int key) throws SQLException {
+        StringBuffer sbSqlClause = new StringBuffer();
+        sbSqlClause.append("_key IN");
+        sbSqlClause.append("(");
+        sbSqlClause.append(key);
+        sbSqlClause.append(")");
+        return (getChromosomes(sbSqlClause.toString()));
+    }
+
+    /**
+     * Helper routine to return 'pivoted' results using the provided query param
+     *
+     * @param query Sql
+     * @return Result set
+     */
+    private static SimpleResultSet getChromosomes(String query) {
+        Ignite ignite = Ignition.localIgnite();
+
+        List<Chromosome> chromosomes = GAGridUtils.getChromosomes(ignite, query);
+
+        SimpleResultSet rs2 = new SimpleResultSet();
+
+        Chromosome aChrom = chromosomes.get(0);
+        int genesCount = aChrom.getGenes().length;
+
+        rs2.addColumn("Chromosome Id", Types.INTEGER, 0, 0);
+        rs2.addColumn("Fitness Score", Types.DOUBLE, 0, 0);
+
+        for (int i = 0; i < genesCount; i++) {
+            int columnIndex = i + 1;
+            rs2.addColumn("Gene " + columnIndex, Types.VARCHAR, 0, 0);
+        }
+
+        for (Chromosome rowChrom : chromosomes) {
+
+            Object[] row = new Object[genesCount + 2];
+            row[0] = rowChrom.id();
+            row[1] = rowChrom.getFitnessScore();
+
+            List<Gene> genes = GAGridUtils.getGenesInOrderForChromosome(ignite, rowChrom);
+            int i = 2;
+
+            for (Gene gene : genes) {
+                row[i] = gene.getValue().toString();
+                i = i + 1;
+            }
+            //Add a row for an individual Chromosome
+            rs2.addRow(row);
+        }
+
+        return rs2;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/0cdded31/modules/ml/src/main/java/org/apache/ignite/ml/genetic/functions/package-info.java
----------------------------------------------------------------------
diff --git a/modules/ml/src/main/java/org/apache/ignite/ml/genetic/functions/package-info.java b/modules/ml/src/main/java/org/apache/ignite/ml/genetic/functions/package-info.java
new file mode 100644
index 0000000..152cd49
--- /dev/null
+++ b/modules/ml/src/main/java/org/apache/ignite/ml/genetic/functions/package-info.java
@@ -0,0 +1,21 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * Contains functions used for GA Grid
+ */
+package org.apache.ignite.ml.genetic.functions;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ignite/blob/0cdded31/modules/ml/src/main/java/org/apache/ignite/ml/genetic/package-info.java
----------------------------------------------------------------------
diff --git a/modules/ml/src/main/java/org/apache/ignite/ml/genetic/package-info.java b/modules/ml/src/main/java/org/apache/ignite/ml/genetic/package-info.java
new file mode 100644
index 0000000..33217ec
--- /dev/null
+++ b/modules/ml/src/main/java/org/apache/ignite/ml/genetic/package-info.java
@@ -0,0 +1,21 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * Root GA package (GA Grid)
+ */
+package org.apache.ignite.ml.genetic;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ignite/blob/0cdded31/modules/ml/src/main/java/org/apache/ignite/ml/genetic/parameter/ChromosomeCriteria.java
----------------------------------------------------------------------
diff --git a/modules/ml/src/main/java/org/apache/ignite/ml/genetic/parameter/ChromosomeCriteria.java b/modules/ml/src/main/java/org/apache/ignite/ml/genetic/parameter/ChromosomeCriteria.java
new file mode 100644
index 0000000..ffffd43
--- /dev/null
+++ b/modules/ml/src/main/java/org/apache/ignite/ml/genetic/parameter/ChromosomeCriteria.java
@@ -0,0 +1,50 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.ml.genetic.parameter;
+
+import java.util.ArrayList;
+
+import java.util.List;
+
+/**
+ * Responsible for describing the characteristics of an individual Chromosome.
+ */
+public class ChromosomeCriteria {
+
+    /** List of criteria for a Chromosome */
+    private List<String> criteria = new ArrayList();
+
+    /**
+     * Retrieve criteria
+     *
+     * @return List of strings
+     */
+    public List getCriteria() {
+        return criteria;
+    }
+
+    /**
+     * Set criteria
+     *
+     * @param criteria List of criteria to be applied for a Chromosome ;Use format "name=value", ie: "coinType=QUARTER"
+     */
+    public void setCriteria(List criteria) {
+        this.criteria = criteria;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/0cdded31/modules/ml/src/main/java/org/apache/ignite/ml/genetic/parameter/GAConfiguration.java
----------------------------------------------------------------------
diff --git a/modules/ml/src/main/java/org/apache/ignite/ml/genetic/parameter/GAConfiguration.java b/modules/ml/src/main/java/org/apache/ignite/ml/genetic/parameter/GAConfiguration.java
new file mode 100644
index 0000000..c66044e
--- /dev/null
+++ b/modules/ml/src/main/java/org/apache/ignite/ml/genetic/parameter/GAConfiguration.java
@@ -0,0 +1,333 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.ml.genetic.parameter;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.ignite.ml.genetic.Gene;
+import org.apache.ignite.ml.genetic.IFitnessFunction;
+
+/**
+ * Maintains configuration parameters to be used in genetic algorithm
+ *
+ * <br/>
+ *
+ * <p>
+ *
+ * NOTE: Default selectionMethod is SELECTION_METHOD_TRUNCATION
+ *
+ * Default truncateRate is .10
+ *
+ * More selectionMethods will be introduced in future releases.
+ *
+ * </p>
+ */
+public class GAConfiguration {
+
+    private GAGridConstants.SELECTION_METHOD selectionMethod = null;
+
+    /** Criteria used to describe a chromosome */
+    private ChromosomeCriteria chromosomeCriteria = null;
+    /**
+     * Percentage of most fit chromosomes to be maintained and utilized to copy into new population.
+     *
+     * NOTE: This parameter is only considered when selectionMethod is SELECTION_METHOD_TRUNCATION
+     *
+     * Accepted values between 0 and 1
+     */
+    private double truncateRate;
+    /**
+     * Elitism is the concept that the strongest members of the population will be preserved from generation to
+     * generation. <br/>
+     *
+     * No crossovers or mutations will be performed for elite chromosomes.
+     *
+     * NOTE: This parameter is only considered when selectionMethod is SELECTON_METHOD_ELETISM.
+     */
+    private int elitismCount = 0;
+
+    /**
+     * Indicates how chromosome fitness values should be evaluated. </br> A chromosome with
+     * isHigherFitnessValueFitter=true is considered fittest.
+     */
+    private boolean isHigherFitnessValueFitter = true;
+    /**
+     * Population size represents the number of potential solutions (ie: chromosomes) between each generation Default
+     * size is 500
+     *
+     * </br> NOTE: The population size remains fixed between each generation
+     */
+    private int populationSize = 500;
+
+    /** Gene pool is the sum of ALL genes utilized to create chromsomes */
+    private List<Gene> genePool = new ArrayList();
+
+    /** Number of genes within a chromosome */
+    private int chromosomeLength = 0;
+    /**
+     * Crossover rate is the probability that two chromosomes will breed with each other. offspring with traits of each
+     * of the parents.
+     *
+     * Accepted values are between 0 and 1
+     */
+    private double crossOverRate = .50;
+    /**
+     * Mutation rate is the probability that a chromosome will be mutated offspring with traits of each of the parents.
+     *
+     *
+     * Accepted values are between 0 and 1
+     */
+    private double mutationRate = .50;
+    /**
+     * Call back interface used to terminate Genetic algorithm.
+     *
+     * Implement this interface based on particular use case.
+     */
+    private ITerminateCriteria terminateCriteria = null;
+
+    /**
+     * Represents a fitness function. Implement the IFitnessFunction to satisfy your particular use case.
+     */
+    private IFitnessFunction fitnessFunction = null;
+
+    public GAConfiguration() {
+        this.setSelectionMethod(GAGridConstants.SELECTION_METHOD.SELECTION_METHOD_TRUNCATION);
+        this.setTruncateRate(.10);
+    }
+
+    /**
+     * retrieve the ChromosomeCriteria
+     *
+     * @return Chromosome criteria
+     */
+    public ChromosomeCriteria getChromosomeCriteria() {
+        return chromosomeCriteria;
+    }
+
+    /**
+     * set value for ChromosomeCriteria
+     *
+     * @param chromosomeCriteria Chromosome criteria
+     */
+
+    public void setChromosomeCriteria(ChromosomeCriteria chromosomeCriteria) {
+        this.chromosomeCriteria = chromosomeCriteria;
+    }
+
+    /**
+     * set Boolean value indicating how fitness values should be evaluated
+     *
+     * @param isHigherFitnessValueFitter Boolean value indicating how fitness values should be evaluated
+     */
+    public void setIsHigherFitnessValueFitter(boolean isHigherFitnessValueFitter) {
+        this.isHigherFitnessValueFitter = isHigherFitnessValueFitter;
+    }
+
+    /**
+     * @return Boolean value indicating how fitness values should be evaluated.
+     */
+    public boolean isHigherFitnessValueFitter() {
+        return this.isHigherFitnessValueFitter;
+    }
+
+    /**
+     * Retrieve the chromosome length
+     *
+     * @return Size of Chromosome
+     */
+    public int getChromosomeLength() {
+        return chromosomeLength;
+    }
+
+    /**
+     * Set the Chromsome length
+     *
+     * @param chromosomeLength Size of Chromosome
+     */
+    public void setChromosomeLength(int chromosomeLength) {
+        this.chromosomeLength = chromosomeLength;
+    }
+
+    /**
+     * Retrieve the cross over rate
+     *
+     * @return Cross over rate
+     */
+    public double getCrossOverRate() {
+        return crossOverRate;
+    }
+
+    /**
+     * Set the cross over rate.
+     *
+     * @param crossOverRate Cross over rate
+     */
+    public void setCrossOverRate(double crossOverRate) {
+        this.crossOverRate = crossOverRate;
+    }
+
+    /**
+     * Retrieve the elitism count
+     *
+     * @return Elitism count
+     */
+    public int getElitismCount() {
+        return elitismCount;
+    }
+
+    /**
+     * Set the elitism count.
+     *
+     * @param elitismCount Elitism count
+     */
+    public void setElitismCount(int elitismCount) {
+        this.elitismCount = elitismCount;
+    }
+
+    /**
+     * Retrieve IFitnessFunction
+     *
+     * @return Fitness function
+     */
+    public IFitnessFunction getFitnessFunction() {
+        return fitnessFunction;
+    }
+
+    /**
+     * Set IFitnessFunction
+     *
+     * @param fitnessFunction Fitness function
+     */
+    public void setFitnessFunction(IFitnessFunction fitnessFunction) {
+        this.fitnessFunction = fitnessFunction;
+    }
+
+    /**
+     * Retrieve the gene pool
+     *
+     * @return List of Genes
+     */
+    public List<Gene> getGenePool() {
+        return (this.genePool);
+    }
+
+    /**
+     * Set the gene pool.
+     *
+     * NOTE: When Apache Ignite is started the gene pool is utilized to initialize the distributed
+     * GAGridConstants.GENE_CACHE.
+     *
+     * @param genePool List of Genes
+     */
+    public void setGenePool(List<Gene> genePool) {
+        this.genePool = genePool;
+    }
+
+    /**
+     * Retrieve the mutation rate.
+     *
+     * @return Mutation Rate
+     */
+    public double getMutationRate() {
+        return mutationRate;
+    }
+
+    /**
+     * Set the mutation rate.
+     *
+     * @param mutationRate Mutation Rate
+     */
+    public void setMutationRate(double mutationRate) {
+        this.mutationRate = mutationRate;
+    }
+
+    /**
+     * Retrieve the population size
+     *
+     * @return Population size
+     */
+
+    public int getPopulationSize() {
+        return populationSize;
+    }
+
+    /**
+     * Set the population size
+     *
+     * @param populationSize Size of population
+     */
+    public void setPopulationSize(int populationSize) {
+        this.populationSize = populationSize;
+    }
+
+    /**
+     * Get the selection method
+     *
+     * @return Selection method
+     */
+    public GAGridConstants.SELECTION_METHOD getSelectionMethod() {
+        return selectionMethod;
+    }
+
+    /**
+     * Set the selection method
+     *
+     * @param selectionMethod Selection method
+     */
+    public void setSelectionMethod(GAGridConstants.SELECTION_METHOD selectionMethod) {
+        this.selectionMethod = selectionMethod;
+    }
+
+    /**
+     * Retreive the termination criteria
+     *
+     * @return  Termination Criteria
+     */
+    public ITerminateCriteria getTerminateCriteria() {
+        return terminateCriteria;
+    }
+
+    /**
+     * Set the termination criteria.
+     *
+     * @param terminateCriteria Termination Criteria
+     */
+    public void setTerminateCriteria(ITerminateCriteria terminateCriteria) {
+        this.terminateCriteria = terminateCriteria;
+    }
+
+    /**
+     * Retrieve truncateRate
+     *
+     * @return Truncate Rate
+     */
+    public double getTruncateRate() {
+        return truncateRate;
+    }
+
+    /**
+     * Set truncatePercentage
+     *
+     * @param truncateRate Truncate rate
+     */
+    public void setTruncateRate(double truncateRate) {
+        this.truncateRate = truncateRate;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/0cdded31/modules/ml/src/main/java/org/apache/ignite/ml/genetic/parameter/GAGridConstants.java
----------------------------------------------------------------------
diff --git a/modules/ml/src/main/java/org/apache/ignite/ml/genetic/parameter/GAGridConstants.java b/modules/ml/src/main/java/org/apache/ignite/ml/genetic/parameter/GAGridConstants.java
new file mode 100644
index 0000000..41be973
--- /dev/null
+++ b/modules/ml/src/main/java/org/apache/ignite/ml/genetic/parameter/GAGridConstants.java
@@ -0,0 +1,37 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.ml.genetic.parameter;
+
+/**
+ * GAGridConstants
+ */
+public interface GAGridConstants {
+
+    /** populationCache constant */
+    public static final String POPULATION_CACHE = "populationCache";
+
+    /** populationCache constant */
+    public static final String GENE_CACHE = "geneCache";
+
+    /** Selection Method type **/
+    public static enum SELECTION_METHOD {
+        SELECTON_METHOD_ELETISM, SELECTION_METHOD_TRUNCATION
+    }
+
+    ;
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/0cdded31/modules/ml/src/main/java/org/apache/ignite/ml/genetic/parameter/ITerminateCriteria.java
----------------------------------------------------------------------
diff --git a/modules/ml/src/main/java/org/apache/ignite/ml/genetic/parameter/ITerminateCriteria.java b/modules/ml/src/main/java/org/apache/ignite/ml/genetic/parameter/ITerminateCriteria.java
new file mode 100644
index 0000000..5868b3d
--- /dev/null
+++ b/modules/ml/src/main/java/org/apache/ignite/ml/genetic/parameter/ITerminateCriteria.java
@@ -0,0 +1,39 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.ml.genetic.parameter;
+
+import org.apache.ignite.ml.genetic.Chromosome;
+
+/**
+ * Represents the terminate condition for a genetic algorithm.
+ *
+ * <p>
+ *
+ * Implement this interface for your respective use case.
+ *
+ * </p>
+ */
+public interface ITerminateCriteria {
+    /**
+     * @param fittestChromosome Fittest chromosome as of the nth generation
+     * @param averageFitnessScore Average fitness score
+     * @param generation Current number of generations
+     * @return Boolean value to determine when to stop evolution
+     */
+    public boolean isTerminationConditionMet(Chromosome fittestChromosome, double averageFitnessScore, int generation);
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/0cdded31/modules/ml/src/main/java/org/apache/ignite/ml/genetic/parameter/package-info.java
----------------------------------------------------------------------
diff --git a/modules/ml/src/main/java/org/apache/ignite/ml/genetic/parameter/package-info.java b/modules/ml/src/main/java/org/apache/ignite/ml/genetic/parameter/package-info.java
new file mode 100644
index 0000000..d646ef5
--- /dev/null
+++ b/modules/ml/src/main/java/org/apache/ignite/ml/genetic/parameter/package-info.java
@@ -0,0 +1,21 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * Contains parameters used for GA Grid
+ */
+package org.apache.ignite.ml.genetic.parameter;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ignite/blob/0cdded31/modules/ml/src/main/java/org/apache/ignite/ml/genetic/utils/GAGridUtils.java
----------------------------------------------------------------------
diff --git a/modules/ml/src/main/java/org/apache/ignite/ml/genetic/utils/GAGridUtils.java b/modules/ml/src/main/java/org/apache/ignite/ml/genetic/utils/GAGridUtils.java
new file mode 100644
index 0000000..d951ea3
--- /dev/null
+++ b/modules/ml/src/main/java/org/apache/ignite/ml/genetic/utils/GAGridUtils.java
@@ -0,0 +1,124 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.ml.genetic.utils;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import javax.cache.Cache.Entry;
+
+import org.apache.ignite.Ignite;
+import org.apache.ignite.IgniteCache;
+import org.apache.ignite.cache.query.QueryCursor;
+import org.apache.ignite.cache.query.SqlFieldsQuery;
+import org.apache.ignite.cache.query.SqlQuery;
+
+import org.apache.ignite.ml.genetic.Chromosome;
+import org.apache.ignite.ml.genetic.Gene;
+import org.apache.ignite.ml.genetic.cache.PopulationCacheConfig;
+import org.apache.ignite.ml.genetic.parameter.GAConfiguration;
+import org.apache.ignite.ml.genetic.parameter.GAGridConstants;
+
+/**
+ * GA Grid Helper routines
+ */
+public class GAGridUtils {
+
+    /**
+     * Retrieve chromosomes
+     *
+     * @param ignite Ignite
+     * @param query Sql
+     * @return List of Chromosomes
+     */
+    public static List<Chromosome> getChromosomes(Ignite ignite, String query) {
+        List<Chromosome> chromosomes = new ArrayList();
+
+        IgniteCache<Long, Chromosome> populationCache = ignite.getOrCreateCache(PopulationCacheConfig.populationCache());
+
+        SqlQuery sql = new SqlQuery(Chromosome.class, query);
+
+        try (QueryCursor<Entry<Long, Chromosome>> cursor = populationCache.query(sql)) {
+            for (Entry<Long, Chromosome> e : cursor)
+                chromosomes.add(e.getValue());
+        }
+
+        return chromosomes;
+    }
+
+    /**
+     * @param ignite Ignite
+     * @param chromosome Chromosome
+     * @return List of Genes
+     */
+    public static List<Gene> getGenesForChromosome(Ignite ignite, Chromosome chromosome) {
+        List<Gene> genes = new ArrayList();
+        IgniteCache<Long, Gene> cache = ignite.cache(GAGridConstants.GENE_CACHE);
+        StringBuffer sbSqlClause = new StringBuffer();
+        sbSqlClause.append("_key IN ");
+        String sqlInClause = Arrays.toString(chromosome.getGenes());
+
+        sqlInClause = sqlInClause.replace("[", "(");
+        sqlInClause = sqlInClause.replace("]", ")");
+
+        sbSqlClause.append(sqlInClause);
+
+        SqlQuery sql = new SqlQuery(Gene.class, sbSqlClause.toString());
+
+        try (QueryCursor<Entry<Long, Gene>> cursor = cache.query(sql)) {
+            for (Entry<Long, Gene> e : cursor)
+                genes.add(e.getValue());
+        }
+
+        return genes;
+    }
+
+    /**
+     * Retrieve genes in order
+     *
+     * @param ignite Ignite
+     * @param chromosome Chromosome
+     * @return List of Genes
+     */
+
+    public static List<Gene> getGenesInOrderForChromosome(Ignite ignite, Chromosome chromosome) {
+        List<Gene> genes = new ArrayList();
+        IgniteCache<Long, Gene> cache = ignite.cache(GAGridConstants.GENE_CACHE);
+
+        long[] primaryKeys = chromosome.getGenes();
+
+        for (int k = 0; k < primaryKeys.length; k++) {
+
+            StringBuffer sbSqlClause = new StringBuffer();
+            sbSqlClause.append("_key IN ");
+            sbSqlClause.append("(");
+            sbSqlClause.append(primaryKeys[k]);
+            sbSqlClause.append(")");
+
+            SqlQuery sql = new SqlQuery(Gene.class, sbSqlClause.toString());
+
+            try (QueryCursor<Entry<Long, Gene>> cursor = cache.query(sql)) {
+                for (Entry<Long, Gene> e : cursor)
+                    genes.add(e.getValue());
+            }
+        }
+
+        return genes;
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/0cdded31/modules/ml/src/main/java/org/apache/ignite/ml/genetic/utils/package-info.java
----------------------------------------------------------------------
diff --git a/modules/ml/src/main/java/org/apache/ignite/ml/genetic/utils/package-info.java b/modules/ml/src/main/java/org/apache/ignite/ml/genetic/utils/package-info.java
new file mode 100644
index 0000000..0d6a54e
--- /dev/null
+++ b/modules/ml/src/main/java/org/apache/ignite/ml/genetic/utils/package-info.java
@@ -0,0 +1,21 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * Contains utils for GA Grid
+ */
+package org.apache.ignite.ml.genetic.utils;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ignite/blob/0cdded31/modules/ml/src/test/java/org/apache/ignite/ml/IgniteMLTestSuite.java
----------------------------------------------------------------------
diff --git a/modules/ml/src/test/java/org/apache/ignite/ml/IgniteMLTestSuite.java b/modules/ml/src/test/java/org/apache/ignite/ml/IgniteMLTestSuite.java
index 7102d6a..e22a3a5 100644
--- a/modules/ml/src/test/java/org/apache/ignite/ml/IgniteMLTestSuite.java
+++ b/modules/ml/src/test/java/org/apache/ignite/ml/IgniteMLTestSuite.java
@@ -19,6 +19,7 @@ package org.apache.ignite.ml;
 
 import org.apache.ignite.ml.clustering.ClusteringTestSuite;
 import org.apache.ignite.ml.dataset.DatasetTestSuite;
+import org.apache.ignite.ml.genetic.GAGridTestSuite;
 import org.apache.ignite.ml.knn.KNNTestSuite;
 import org.apache.ignite.ml.math.MathImplMainTestSuite;
 import org.apache.ignite.ml.nn.MLPTestSuite;
@@ -47,8 +48,9 @@ import org.junit.runners.Suite;
     TrainersGroupTestSuite.class,
     OptimizationTestSuite.class,
     DatasetTestSuite.class,
-    PreprocessingTestSuite.class
+    PreprocessingTestSuite.class,
+    GAGridTestSuite.class
 })
 public class IgniteMLTestSuite {
     // No-op.
-}
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ignite/blob/0cdded31/modules/ml/src/test/java/org/apache/ignite/ml/genetic/GAGridCalculateFitnessTest.java
----------------------------------------------------------------------
diff --git a/modules/ml/src/test/java/org/apache/ignite/ml/genetic/GAGridCalculateFitnessTest.java b/modules/ml/src/test/java/org/apache/ignite/ml/genetic/GAGridCalculateFitnessTest.java
new file mode 100644
index 0000000..16e4dda
--- /dev/null
+++ b/modules/ml/src/test/java/org/apache/ignite/ml/genetic/GAGridCalculateFitnessTest.java
@@ -0,0 +1,141 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.ml.genetic;
+
+import java.util.ArrayList;
+import java.util.List;
+import org.apache.ignite.Ignite;
+import org.apache.ignite.IgniteCache;
+import org.apache.ignite.Ignition;
+import org.apache.ignite.cache.query.QueryCursor;
+import org.apache.ignite.cache.query.SqlFieldsQuery;
+import org.apache.ignite.ml.genetic.parameter.GAConfiguration;
+import org.apache.ignite.ml.genetic.parameter.GAGridConstants;
+import org.junit.After;
+
+import static org.junit.Assert.*;
+
+import org.junit.Before;
+import org.junit.Test;
+
+/**
+ * Calculate Fitness Test
+ */
+public class GAGridCalculateFitnessTest {
+
+    private Ignite ignite = null;
+    private GAGrid gaGrid = null;
+    private GAConfiguration gaConfig = null;
+
+    /**
+     * Setup test
+     */
+    @Before
+    public void initialize() {
+
+        try {
+
+            // Create an Ignite instance as you would in any other use case.
+            ignite = Ignition.start();
+
+            // Create GAConfiguration
+            gaConfig = new GAConfiguration();
+
+            // set Gene Pool
+            List<Gene> genes = this.getGenePool();
+            gaConfig.setGenePool(genes);
+
+            // set the Chromosome Length to '8' since password contains 8 characters.
+            gaConfig.setChromosomeLength(8);
+
+            // create and set Fitness function
+            PasswordFitnessFunction function = new PasswordFitnessFunction();
+            gaConfig.setFitnessFunction(function);
+
+            gaGrid = new GAGrid(gaConfig, ignite);
+            gaGrid.initializeGenePopulation();
+            gaGrid.initializePopulation();
+
+        }
+        catch (Exception e) {
+            System.out.println(e);
+        }
+    }
+
+    /**
+     * Test Calculate Fitness
+     */
+
+    @Test
+    public void testCalculateFitness() {
+        try {
+
+            List<Long> chromosomeKeys = gaGrid.getPopulationKeys();
+
+            Boolean boolValue = this.ignite.compute().execute(new FitnessTask(this.gaConfig), chromosomeKeys);
+
+            IgniteCache<Long, Chromosome> populationCache = ignite.cache(GAGridConstants.POPULATION_CACHE);
+
+            String sql = "select count(*) from Chromosome where fitnessScore>0";
+
+            // Execute query to keys for ALL Chromosomes by fitnessScore
+            QueryCursor<List<?>> cursor = populationCache.query(new SqlFieldsQuery(sql));
+
+            List<List<?>> res = cursor.getAll();
+
+            Long count = new Long(0);
+
+            for (List row : res) {
+                count = (Long)row.get(0);
+            }
+
+            assertEquals(500, count.longValue());
+        }
+
+        catch (Exception e) {
+            System.out.println(e);
+        }
+    }
+
+    /**
+     * Helper routine to initialize Gene pool
+     *
+     * @return List of Genes
+     */
+    private List<Gene> getGenePool() {
+        List<Gene> list = new ArrayList();
+
+        char[] chars = {
+            'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's',
+            't', 'u', 'v', 'w', 'x', 'y', 'z', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S',
+            'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '1', '2', '3', '4', '5', '6', '7', '8', '!', '"', '#', '$', '%', '&', '(', ')', '*', '+', '-', '.', '/', ':', ';', '<', '=', '>', '?', '@', '[', ']', '^'};
+
+        for (int i = 0; i < chars.length; i++) {
+            Gene gene = new Gene(new Character(chars[i]));
+            list.add(gene);
+        }
+        return list;
+    }
+
+    @After
+    public void tearDown() {
+
+        Ignition.stop(true);
+        ignite = null;
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/0cdded31/modules/ml/src/test/java/org/apache/ignite/ml/genetic/GAGridInitializePopulationTest.java
----------------------------------------------------------------------
diff --git a/modules/ml/src/test/java/org/apache/ignite/ml/genetic/GAGridInitializePopulationTest.java b/modules/ml/src/test/java/org/apache/ignite/ml/genetic/GAGridInitializePopulationTest.java
new file mode 100644
index 0000000..f4f9ca4
--- /dev/null
+++ b/modules/ml/src/test/java/org/apache/ignite/ml/genetic/GAGridInitializePopulationTest.java
@@ -0,0 +1,153 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.ml.genetic;
+
+import java.util.ArrayList;
+import java.util.List;
+import org.apache.ignite.Ignite;
+import org.apache.ignite.IgniteCache;
+import org.apache.ignite.Ignition;
+import org.apache.ignite.cache.query.QueryCursor;
+import org.apache.ignite.cache.query.SqlFieldsQuery;
+import org.apache.ignite.ml.genetic.parameter.GAConfiguration;
+import org.apache.ignite.ml.genetic.parameter.GAGridConstants;
+import org.junit.After;
+
+import static org.junit.Assert.*;
+
+import org.junit.Before;
+import org.junit.Test;
+
+/**
+ * Initialize Gene and Chromosome Test
+ */
+
+public class GAGridInitializePopulationTest {
+
+    private Ignite ignite = null;
+    private GAGrid gaGrid = null;
+    private GAConfiguration gaConfig = null;
+
+    @Before
+    public void initialize() {
+
+        try {
+
+            // Create an Ignite instance as you would in any other use case.
+            ignite = Ignition.start();
+
+            // Create GAConfiguration
+            gaConfig = new GAConfiguration();
+
+            // set Gene Pool
+            List<Gene> genes = this.getGenePool();
+
+            // set the Chromosome Length to '8' since password contains 8 characters.
+            gaConfig.setChromosomeLength(8);
+
+            gaConfig.setGenePool(genes);
+
+            gaGrid = new GAGrid(gaConfig, ignite);
+        }
+        catch (Exception e) {
+            System.out.println(e);
+        }
+    }
+
+    @Test
+    public void testInitializeGenes() {
+
+        try {
+            IgniteCache<Long, Gene> geneCache = ignite.cache(GAGridConstants.GENE_CACHE);
+            gaGrid.initializeGenePopulation();
+
+            String sql = "select count(*) from Gene";
+
+            // Execute query to keys for ALL Chromosomes by fittnessScore
+            QueryCursor<List<?>> cursor = geneCache.query(new SqlFieldsQuery(sql));
+
+            List<List<?>> res = cursor.getAll();
+
+            Long count = new Long(0);
+
+            for (List row : res) {
+                count = (Long)row.get(0);
+            }
+            assertEquals(83, count.longValue());
+        }
+
+        catch (Exception e) {
+            System.out.println(e);
+        }
+    }
+
+    @Test
+    public void testInitializePopulation() {
+        try {
+
+            IgniteCache<Long, Chromosome> populationCache = ignite.cache(GAGridConstants.POPULATION_CACHE);
+
+            gaGrid.initializePopulation();
+
+            String sql = "select count(*) from Chromosome";
+
+            // Execute query to keys for ALL Chromosomes by fittnessScore
+            QueryCursor<List<?>> cursor = populationCache.query(new SqlFieldsQuery(sql));
+
+            List<List<?>> res = cursor.getAll();
+
+            Long count = new Long(0);
+
+            for (List row : res) {
+                count = (Long)row.get(0);
+            }
+            assertEquals(500, count.longValue());
+        }
+
+        catch (Exception e) {
+            System.out.println(e);
+        }
+    }
+
+    /**
+     * Helper routine to initialize Gene pool
+     *
+     * @return List of Genes
+     */
+    private List<Gene> getGenePool() {
+        List<Gene> list = new ArrayList();
+
+        char[] chars = {
+            'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's',
+            't', 'u', 'v', 'w', 'x', 'y', 'z', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S',
+            'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '1', '2', '3', '4', '5', '6', '7', '8', '!', '"', '#', '$', '%', '&', '(', ')', '*', '+', '-', '.', '/', ':', ';', '<', '=', '>', '?', '@', '[', ']', '^'};
+
+        for (int i = 0; i < chars.length; i++) {
+            Gene gene = new Gene(new Character(chars[i]));
+            list.add(gene);
+        }
+        return list;
+    }
+
+    @After
+    public void tearDown() {
+
+        Ignition.stop(true);
+        ignite = null;
+    }
+}


Mime
View raw message