The GA Procedure

 
Defining a User Initialization Routine

For problems with simple constant bounds or simple sequencing problems it is not necessary to define a user initialization subroutine; simply specify 'DEFAULT' in the Initialize call. Defining a routine is necessary only if you need to satisfy more complicated constraints or apply some initial heuristics or local optimizations. A user initialization routine is specified with an Initialize call, as follows:

  call Initialize('name', size);

where name is the name of your initialize routine. The first parameter of the subroutine you define must be a numeric array. When the GA procedure calls your subroutine, it passes information in the first parameter, referred to as the selection parameter, which designates the member selected for initialization. Your subroutine should generate one solution and write the values of the solution elements with a WriteMember call, using the selection parameter passed to your subroutine. The random number functions from BASE SAS are available to your subroutine, if needed. You can define as many other parameters to your subroutine as you need; they are filled in with values from variables of the same name created in your global program. The array used to write the generated solution to the population must be numeric and declared with the /NOSYMBOLS option, as well as any arrays passed as parameters into your subroutine.

The following sample statements illustrate how to define an initialization routine. The feasible region is a triangle with vertices (0,0), (0,1) and (1,1).

   call SetEncoding('R2');
   
   /* set vertices of triangle (0,0), (0,1), and (1,1) */
   array vertex1[2] /nosym (0,0);
   array vertex2[2] /nosym (0,1);
   array vertex3[2] /nosym (1,1);
   
   subroutine triangle(selected[*], vertex1[2], vertex2[2], vertex3[2]);
   
   array x[2] /nosym;
   
   /* select 3 random numbers 0 < r < 1 */
   r1 = rand('uniform');
   r2 = rand('uniform');
   r3 = rand('uniform');
   
   /* normalize so r1 + r2 + r3 = 1 */
   sumr = r1 + r2 + r3;
   r1 = r1 / sumr;
   r2 = r2 / sumr;
   r3 = r3 / sumr;
   
   /* form a convex combination of vertices in x */
   do i = 1 to 2;
     x[i] = r1 * vertex1[i] + r2 * vertex2[i] + r3 * vertex3[i];
   end;

   /* write x out to the selected population member, to segment 1 */
   call WriteMember(selected, 1, x);
   endsub;
   
   [other programming statements]
   
   call Initialize('triangle',100);

In this example, the triangle initialization subroutine generates a solution that is a random convex combination of three points, which places it in the interior of the triangular region defined by the points. Note the use of the BASE SAS RAND() function to get random numbers uniformly distributed between 0 and 1. The random numbers are then normalized so that their sum is 1. In the loop, they are used to compute a convex linear combination of the vertices, and the WriteMember call writes the solution to the selected population member. The encoding specified a single segment, so the WriteMember call specifies segment 1 as the target. When the GA procedure executes the Initialize call, it executes the triangle routine 100 times, once for each member of the initial population.