You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ignite.apache.org by ch...@apache.org on 2018/03/04 15:08:04 UTC
[2/3] ignite git commit: IGNITE-6899: Adding GA Grid to Apache Ignite
ML module.
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;
+ }
+}