static void test13() {
        grid_size = 3;
        int num_generations = 1000;
        int num_atoms = 13;
        int population_size = 10;
        double max_potential;
        double min_potential;
        double[][][] population = new double[population_size][][];
        double[] fitness = new double[population_size];
        // seed the initial population
        for (int i = 0; i < population_size; i++) {
            double potential = 0;
            while (potential >= 0) {
                population[i] = generate_cluster(num_atoms);
                potential = get_potential(population[i]);
            }
        }
        System.out.println("initial seed complete");
        // get the potentials for each cluster individual
        for (int i = 0; i < population_size; i++) {
            fitness[i] = get_potential(population[i]);
        }
        max_potential = numutil.MathTools.max(fitness);
        min_potential = numutil.MathTools.min(fitness);
        // assign each individual a fitness rating
        for (int i = 0; i < population_size; i++) {
            fitness[i] = (max_potential - fitness[i]) / (max_potential - min_potential);
        }
        // reorder the individuals by fitness
        sort(population, fitness);
        numutil.MathTools.print_plain(population[0]);
        System.out.println(min_potential);
        // create generations
        for (int k = 0; k < num_generations; k++) {
            // get the potentials for each cluster individual
            for (int i = 0; i < population_size; i++) {
                fitness[i] = get_potential(population[i]);
            }
            max_potential = numutil.MathTools.max(fitness);
            min_potential = numutil.MathTools.min(fitness);
            // assign each individual a fitness rating
            for (int i = 0; i < population_size; i++) {
                fitness[i] = (max_potential - fitness[i]) / (max_potential - min_potential);
            }
            // reorder the individuals by fitness
            sort(population, fitness);

            /*
             * start genetic algorithm criteria
             */
            // keep most fit
            double[][] parentA = numutil.MathTools.copy(population[0]);
            // mutate the second most fit
            double[][] parentB = numutil.MathTools.copy(population[1]);
            // make a 1 point crossover between A and B
            splice(parentA, parentB);
            population[population_size - 1] = parentB;
            population[population_size - 2] = parentA;
            // change the others
            for (int i = 2; i < population_size - 2; i++) {
                parentA = numutil.MathTools.copy(population[0]);
                splice2(parentA, population[i]);
            }
            /*
             * end genetic algorithm criteria
             */
        }
        for (int i = 0; i < population_size; i++) {
            fitness[i] = get_potential(population[i]);
        }
        max_potential = numutil.MathTools.max(fitness);
        min_potential = numutil.MathTools.min(fitness);
        numutil.MathTools.print_plain(population[0]);
        System.out.println(min_potential);
        System.out.println(max_potential);
    }