BookmarkSubscribeRSS Feed
🔒 This topic is solved and locked. Need further help from the community? Please sign in and ask a new question.
GabACM
Calcite | Level 5

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 !

1 ACCEPTED SOLUTION

Accepted Solutions
Rick_SAS
SAS Super FREQ

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");

View solution in original post

2 REPLIES 2
Rick_SAS
SAS Super FREQ

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");

GabACM
Calcite | Level 5

The first solution you gave works indeed, thank you Rick Wicklin.

sas-innovate-2024.png

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.

 

Register now!

Multiple Linear Regression in SAS

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.

From The DO Loop
Want more? Visit our blog for more articles like these.
Discussion stats
  • 2 replies
  • 993 views
  • 0 likes
  • 2 in conversation