function [nn]=Kohonen_TSP(a,b,n,m)
[x,n]=generare(a,b,n); // generare date 
nn=tlist(["retea Kohonen","m", "X","W","Y"],m,zeros(2,1),zeros(m,2),zeros(m,1));
C=init(a,b,m); // etapa de initializare
nn.W=C';
//disp(nn.W,"W=");
eta=1.25; s=m/2;
for t=1:2000
  for i=1:n
  // determinare unitate invingatoare
     imin=winner(nn,x(:,i));
  // ajustare  
    for j=1:m
     nn.W(j,:)=nn.W(j,:)+eta*(x(:,i)'-nn.W(j,:))*lambda(nn,j,imin,s);
    end 
  end
//  eta=eta/log(t+1);
  eta=0.995*eta;
  if modulo(t,100) ==0 & s>1
      s=s/1.25;
  end    
//  disp(t,"t="); disp(eta,"eta=");
end

plot(x(1,:),x(2,:),'ko');
for k=1:nn.m-1 do
    plot([nn.W(k,1),nn.W(k+1,1)],[nn.W(k,2),nn.W(k+1,2)],'r*-');
end
plot([nn.W(nn.m,1),nn.W(1,1)],[nn.W(nn.m,2),nn.W(1,2)],'r*-');
endfunction

function imin=winner(nn,x)
        for k=1:nn.m
           d(k)=dist(x,nn.W(k,:)');
        end   
        imin=1;
        for k=2:nn.m
            if d(k)<d(imin)
                imin=k;
            end
        end     
endfunction    


// initializarea aleatoare a ponderilor
function C=init(a,b,m)
C=[];
for i=1:m
  //C=[C [grand(1,1,"unf",a,b);grand(1,1,"unf",a,b)]]; 
  alfa=grand(1,1,"unf",0,2*%pi);
  C=[C [(a+b)/2+0.5*cos(alfa);(a+b)/2+0.5*sin(alfa)]]; 
end   
endfunction

// calcul functie distanta
function d=dist(x,y)
n=length(x);
d=0;
for i=1:n
    d=d+(x(i,1)-y(i,1))^2;
end    
endfunction

// functie Lambda

function f=lambda(nn,i,imin,s)
if abs(i-imin)==nn.m-1
   f=exp(-1/(2*s^2));
else   
   f=exp(-(i-imin)^2/(2*s^2));
end   
endfunction

function [x,n]=generare(a,b,n)
x=[]; 
for k=1:n
    x=[x [grand(1,1,"unf",a,b);grand(1,1,"unf",a,b)]];
  
end
//plot(x(1,:),x(2,:),'ko');
endfunction

Kohonen_TSP(0,1,10,30)
