ianphil397
ianphil397

Reputation: 95

Pre-allocate an array of structures for use in genetic algorithm in Matlab

This is the code I have so far:

population = 50
individual = repmat(struct('genes',[], 'fitness', 0), population, 1);

So what I'm doing is creating a population of 50 individuals these individuals each have the component genes and fitness. What I can't seem to do correctly is set genes up to be a 50 cell array rather than just a single cell.

Can anyone shed some light on this for me please?

A further addition I'd like to make is to populate the genes array with random values (either 0 or 1). I imagine I could easily do this afterwards by iterating through the genes array of each member and using what ever random number generating functionality Matlab has available. However it would be more efficient to do when the structures are being pre-allocated.

Thanks

Upvotes: 1

Views: 60

Answers (4)

James Mertz
James Mertz

Reputation: 8789

Why not use a class instead of a struct? Creating a simple class person:

classdef person
    properties
        fitness = 0;
    end
    properties(SetAccess = private)
        genes
    end
    methods
        function obj = person()
            obj.genes = randi([0 1], 10, 1);
        end
    end
end

and then running the following script:

population = 50;

people = person.empty(population, 0);
people(1).fitness = 100;
people(2).fitness = 50;

people(1)
people(2)

produces the following console output:

ans = 

  person with properties:

    fitness: 100
      genes: [10x1 double]


ans = 

  person with properties:

    fitness: 50
      genes: [10x1 double]

Upvotes: 2

Rody Oldenhuis
Rody Oldenhuis

Reputation: 38042

Well, keeping to structs, here's a few ways:

% Your original method
clear all
tic
population = 50;
individual = repmat(struct('genes', false(50,1), 'fitness', 0), population, 1);
toc

% simple loop
clear all
tic
population = 50;
individual(population,1) = struct('genes', false(50,1), 'fitness', 0);
for ii = 1:population
    individual(ii).genes = false(50,1);
end
toc

% Third option
clear all
tic
population = 50;
individual = struct(...
    'genes'  , num2cell(false(50,population),2), ...
    'fitness', num2cell(zeros(population,1)));
toc

Results:

Elapsed time is 0.009887 seconds.  % your method
Elapsed time is 0.000475 seconds.  % loop
Elapsed time is 0.013252 seconds.  % init with cells

My suggestion: just use the loop :)

Upvotes: 1

m_power
m_power

Reputation: 3204

You can do something similar to this :

individual = repmat(struct('genes',{cell(1,50)}, 'fitness', 0), population, 1);

Upvotes: 0

Hugh Nolan
Hugh Nolan

Reputation: 2519

If you are looking to allocate different random values to each individual, then doing a repmat as an allocation isn't going to help, as this just replicates the same thing 50 times. You are better off just using a simple loop:

population=50;
individual=struct('genes',[],'fitness',0);
for m=1:50
    individual(m).genes=rand(1,50)>=0.5;
end

This is no less efficient than allocating all of them and then looping through - in each case the genes array is only allocated once. Moreover, allocating and reallocating 50 cells isn't going to be very slow - you will probably not notice much difference until you hit thousands or tens of thousands.

Upvotes: 1

Related Questions