home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Collection of Education
/
collectionofeducationcarat1997.iso
/
COMPUSCI
/
HOPFIELD.ZIP
/
HOPFIELD.PAS
< prev
next >
Wrap
Pascal/Delphi Source File
|
1989-07-27
|
11KB
|
350 lines
{$R+}
PROGRAM traveling_salesperson ;
(* Copyright 1987 - Knowledge Garden Inc.
473A Malden Bridge Rd.
R.D. 2
Nassau, NY 12123 *)
(* TSP solves a series of differential equations which simulate a neural
net solution of the traveling salesperson problem. The problem and
the equations are described in the article "Computing with Neurons" in
the July 1987 issue of AI Expert Magazine.
This program has been tested using Turbo ver 3.01A on an IBM PC/AT. It has
been run under both DOS 3.2 and Concurrent 5.0 .
We would be pleased to hear your comments, good or bad, or any applications
and modifications of the program. Contact us at:
AI Expert
500 Howard St.
San Francisco, CA 94105
Bill and Bev Thompson *)
(* Uses Turbo3, CRT; *) (* To compile with later versions of Turbo Pascal *)
CONST
max_city = 'E' ; (* max_city and max_position are the size of the *)
max_position = 5 ; (* neural net. They must match. Cities run from *)
(* A to max_city *)
a = 500.0 ; (* these are the weighting constants described *)
b = 500.0 ; (* in the article. By changing then you can *)
c = 200.0 ; (* get different types of solutions *)
d = 300.0 ; (* d seems to have the most effect, increasing *)
(* it produces shorter distance routes, but *)
(* they aren't necessarily real tours. *)
u0 = 0.02 ; (* This parameter effects the output voltage of *)
(* the amplifiers. Increasing it gives a broader *)
(* curve. *)
n = 7 ; (* This term affects global inhibition of the *)
(* network. By setting it slightly larger than *)
(* the number of cities, we seem to get better *)
(* results *)
h = 0.01 ; (* The time step *)
TYPE
cities = 'A' .. max_city ;
positions = 1 .. max_position ;
VAR
u : ARRAY [cities,positions] OF real ; (* Input voltages *)
dist : ARRAY [cities,cities] OF real ; (* Distances between cities *)
FUNCTION v(city : cities ; position : positions) : real ;
(* This function calculates the output voltage from an amplifier
tanh calculates the hyperbolic tangent which gives the shape
of the output curve described in the article *)
FUNCTION tanh(r : real) : real ;
VAR
r1,r2 : real ;
BEGIN
IF r > 20.0
THEN tanh := 1.0
ELSE IF r < -20.0
THEN tanh := -1.0
ELSE
BEGIN
r1 := exp(r) ;
r2 := exp(-r) ;
tanh := (r1 - r2) / (r1 + r2) ;
END ;
END ; (* tanh *)
BEGIN
v := (1.0 + tanh(u[city,position] / u0)) / 2.0 ;
END ; (* v *)
FUNCTION f(city : cities ; position : positions) : real ;
(* This function calculates the right hand side of the differential
equations described in the article. It is not optimized for anything
and is pretty slow. *)
FUNCTION col_sum(cty : cities) : real ;
(* column inhibition. This function helps keep the number of
output items in each column small *)
VAR
col : positions ;
sum : real ;
BEGIN
sum := 0.0 ;
FOR col := 1 TO max_position DO
IF col <> position
THEN sum := sum + v(cty,col) ;
col_sum := sum ;
END ; (* col_sum *)
FUNCTION row_sum(p : positions) : real ;
(* row inhibition. This function helps keep the number of
output items in each row small *)
VAR
row : cities ;
sum : real ;
BEGIN
sum := 0.0 ;
FOR row := 'A' TO max_city DO
IF row <> city
THEN sum := sum + v(row,p) ;
row_sum := sum ;
END ; (* row_sum *)
FUNCTION matrix_sum : real ;
(* global inhibition. This function keeps the total number of cities
visited small *)
VAR
row : cities ;
col : positions ;
sum : real ;
BEGIN
sum := 0.0 ;
FOR row := 'A' TO max_city DO
FOR col := 1 TO max_position DO
sum := sum + v(row,col) ;
matrix_sum := sum ;
END ; (* matrix_sum *)
FUNCTION dist_sum : real ;
(* distance inhibition. The inhibition is larger for longer tours.
Note that neuron (X,max_position) is connected to neuron (X,1),
in other words, the net is circular *)
VAR
c : cities ;
sum : real ;
BEGIN
sum := 0.0 ;
IF position = max_position
THEN
FOR c := 'A' TO max_city DO
sum := sum + dist[city,c] * (v(c,1) + v(c,position - 1))
ELSE IF position = 1
THEN
FOR c := 'A' TO max_city DO
sum := sum + dist[city,c] * (v(c,position + 1) + v(c,max_position))
ELSE
FOR c := 'A' TO max_city DO
sum := sum + dist[city,c] * (v(c,position + 1) + v(c,position - 1)) ;
dist_sum := sum ;
END ; (* dist_sum *)
BEGIN
f := -u[city,position] - a * col_sum(city) - b * row_sum(position) - c * (matrix_sum - n) - d * dist_sum ;
END ; (* f *)
PROCEDURE iterate ;
(* The basic solution process. This is a terrible way to solve differential
equations. Don't use it for anything serious, it performs poorly
when the number of cities gets larger than 7 or 8.
We keep iterating until the norm is less than tol or until the user
gets bored and presses the space bar. *)
CONST
tol = 1.0E-05 ;
VAR
step : integer ;
c1 : cities ;
i : positions ;
nr : real ;
u_old : ARRAY [cities,positions] OF real ;
ch : char ;
FUNCTION norm : real ;
(* The norm is a measure of how much change there has been between
solutions. This is an infinity norm, calculated as the maximum
absolute value of the difference between components of the
solution vectors. We calculate the relative norm as:
N(u_new - u) / N(u). *)
VAR
cx : cities ;
ix : positions ;
max,max_comp : real ;
BEGIN
max := 0.0 ;
FOR cx := 'A' TO max_city DO
FOR ix := 1 TO max_position DO
BEGIN
IF abs(u_old[cx,ix] - u[cx,ix]) > max
THEN max := abs(u_old[cx,ix] - u[cx,ix]) ;
IF abs(u[cx,ix]) > max_comp
THEN max_comp := abs(u[cx,ix]) ;
END ;
norm := max / max_comp ;
END ; (* norm *)
PROCEDURE print_matrix ;
(* Every so often, we print the input and output matrices so that
you can see what is going on. If the output matrix describes a
valid tour, we print that also. *)
VAR
c1 : cities ;
i : positions ;
vv : real ;
t : ARRAY [1 .. max_position] OF char ;
t_count : integer ;
PROCEDURE write_tour ; VAR
i : positions ;
t_dist : real ;
BEGIN
t_dist := 0.0 ;
FOR i := 1 TO max_position - 1 DO
t_dist := t_dist + dist[t[i],t[i+1]] ;
t_dist := t_dist + dist[t[max_position],t[1]] ;
write(output,'Tour: ') ;
FOR i := 1 TO max_position DO
write(output,t[i]) ;
writeln(output,' dist = ',t_dist) ;
END ; (* write_tour *)
PROCEDURE matrix_heading ;
VAR
i : positions ;
BEGIN
write(output,' ') ;
FOR i := 1 TO max_position DO
write(output,i : 12) ;
writeln ;
END ; (* matrix_heading *)
BEGIN
t_count := 0 ;
FOR i := 1 TO max_position DO
t[i] := chr(0) ;
writeln(output) ;
writeln(output,'Step: ',step,' norm = ',nr) ;
writeln(output) ;
writeln(output,'Input Voltages') ;
matrix_heading ;
FOR c1 := 'A' TO max_city DO
BEGIN
write(output,c1,' ') ;
FOR i := 1 TO max_position DO
write(output,u[c1,i] : 12 : 5) ;
writeln(output) ;
END ;
writeln(output) ;
writeln(output,'Output Voltages') ;
matrix_heading ;
FOR c1 := 'A' TO max_city DO
BEGIN
write(output,c1,' ') ;
FOR i := 1 TO max_position DO
BEGIN
vv := v(c