Hello again everyone,
I have a question regarding the Genetic Algorithm routines available in SAS/IML
One of the features of those routines is that the initial population is randomised within an interval of possible solutions given by the user: the syntax of the initialisation routine is the following
call gainit ( problem_id, pop_size, bounds, <modname>)
My question is: how can I specify SAS that I want 1 individual, whose coordinate I know, to belong to the initiale population ? Namely, I would like my first generation of individuals to contain one specific individual, whose fitness value is already high.
The documentation mentions the optional parameter <modname>, which is a user-written module to be called from Gainit to generate the initial population.
The problem is that I have no idea how to write such a module. What is the expected output from it ? A matrix ?
Thank you in advance for your help !
There are two ways to do this:
1) Since you only want to specify ONE initial member, you could just use the fitness subroutine. If you look at the chapter in the SAS/IML User's Guide on "Genetic Algorithms," there is a section on "Setting the Objective Function." That doc says, "The solution parameter passed into the routine is also written back out to the solution population when the module exits....It is permissible and may prove very effective to add logic to the module to improve the solution through some heuristic technique or local optimization, and deliberately pass that improved solution back to the solution population by updating the parameter before returning."
This suggests the following technique for a "warm start" initialization of the solution vector. I'll modify the example from the GASETUP doc:
FirstTime = 1; /* flag ON */
start EvalFitness( pop ) global ( dist, FirstTime );
if FirstTime then do;
pop[1,] = {6 4 12 7 13 15 8 9 11 5 2 14 10 3 1}; /* initially "fit" member */
FirstTime = 0; /* flag OFF */
end;
2) If you prefer to use a module to intialize the entire initial population, the structure of the module is documented at the end of the doc for the GAINIT call. Basically, you return the special member when the module is called the first time, and a random member for subsequent calls. For example, the example from the GASETUP doc would look like this:
FirstTime = 1; /* flag ON */
start FirstPop(member) global(FirstTime, NumCities);
if FirstTime then do;
member = {6 4 12 7 13 15 8 9 11 5 2 14 10 3 1};
FirstTime = 0; /* flag OFF */
end;
else
member = ranperm(NumCities);
finish;
...
call gainit(id, popSize, ,"FirstPop");
There are two ways to do this:
1) Since you only want to specify ONE initial member, you could just use the fitness subroutine. If you look at the chapter in the SAS/IML User's Guide on "Genetic Algorithms," there is a section on "Setting the Objective Function." That doc says, "The solution parameter passed into the routine is also written back out to the solution population when the module exits....It is permissible and may prove very effective to add logic to the module to improve the solution through some heuristic technique or local optimization, and deliberately pass that improved solution back to the solution population by updating the parameter before returning."
This suggests the following technique for a "warm start" initialization of the solution vector. I'll modify the example from the GASETUP doc:
FirstTime = 1; /* flag ON */
start EvalFitness( pop ) global ( dist, FirstTime );
if FirstTime then do;
pop[1,] = {6 4 12 7 13 15 8 9 11 5 2 14 10 3 1}; /* initially "fit" member */
FirstTime = 0; /* flag OFF */
end;
2) If you prefer to use a module to intialize the entire initial population, the structure of the module is documented at the end of the doc for the GAINIT call. Basically, you return the special member when the module is called the first time, and a random member for subsequent calls. For example, the example from the GASETUP doc would look like this:
FirstTime = 1; /* flag ON */
start FirstPop(member) global(FirstTime, NumCities);
if FirstTime then do;
member = {6 4 12 7 13 15 8 9 11 5 2 14 10 3 1};
FirstTime = 0; /* flag OFF */
end;
else
member = ranperm(NumCities);
finish;
...
call gainit(id, popSize, ,"FirstPop");
The first solution you gave works indeed, thank you Rick Wicklin.
Don't miss out on SAS Innovate - Register now for the FREE Livestream!
Can't make it to Vegas? No problem! Watch our general sessions LIVE or on-demand starting April 17th. Hear from SAS execs, best-selling author Adam Grant, Hot Ones host Sean Evans, top tech journalist Kara Swisher, AI expert Cassie Kozyrkov, and the mind-blowing dance crew iLuminate! Plus, get access to over 20 breakout sessions.
Learn how to run multiple linear regression models with and without interactions, presented by SAS user Alex Chaplin.
Find more tutorials on the SAS Users YouTube channel.