//////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////// // // Kohonen Feature Map processing code // // Written by Steve Bohrer Last Updated - 6/24/86 // //////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////// import java.awt.*; import java.applet.*; import java.util.*; import java.lang.*; public class KNN extends Thread { Graphics g; // Handle for area to draw in Dimension r; // Size of graphics area double data[][] = new double[1000][2]; // 1000 data points with X and Y coordinates double centroids[][][] = new double[10][10][2]; // 10x10 centroid array with X and Y // Used to generate random data Random newData = new Random(); // Creates new random data public void ResetData() { int i; for(i=0; i<1000; i++) { data[i][0] = newData.nextDouble(); // X coord data[i][1] = newData.nextDouble(); // Y coord } } // Creates new random clusters public void RandomizeClusters() { int i,j; for (i=0; i<10; i++) for (j=0; j<10; j++) { centroids[i][j][0] = newData.nextDouble(); centroids[i][j][1] = newData.nextDouble(); } } // Constructor public KNN(Graphics graphics, Dimension size) { int i,j; for (i=0; i<10; i++) for (j=0; j<10; j++) { centroids[i][j][0] = i*0.1 + .05; centroids[i][j][1] = j*0.1 + .05; } g = graphics; r = size; ResetData(); } // Utility routine to draw a circle at coordinates x and y // with height h and width w public void drawCircle(int x, int y, int h, int w) { g.drawOval(x-(w/2),y-(h/2),h,w); g.fillOval(x-(w/2),y-(h/2),h,w); } // Utility to draw a single point at x, y public void drawPoint(int x, int y) { g.drawLine(x,y,x,y); } // Paint the graphics area public void Paint() { int i,j; // Blank the output area g.setColor(Color.white); g.fillRect(247,47,306,306); // Draw the border g.setColor(Color.green); g.drawRect(250,50,300,300); g.setColor(Color.black); // Draw the data points for(i=0; i<1000; i++) { // Scale pixels to a 300x300 pixel square // drawCircle(((int)(data[i][0]*300)) + 250,((int)(data[i][1]*300)) + 50,2,2); drawPoint(((int)(data[i][0]*300)) + 250,((int)(data[i][1]*300)) + 50); } // Draw the centroids g.setColor(Color.red); for(i=0; i<10; i++) for(j=0; j<10; j++) drawCircle(((int)(centroids[i][j][0]*300)) + 250,((int)(centroids[i][j][1]*300)) + 50,4,4); } // Show the interconnections between centroids public void PaintGrid() { int i,j; for(i=0; i<9; i++) { for(j=0; j<9; j++) { g.drawLine(((int)(centroids[i][j][0]*300)) + 250,((int)(centroids[i][j][1]*300)) + 50, ((int)(centroids[i+1][j][0]*300)) + 250,((int)(centroids[i+1][j][1]*300)) + 50); g.drawLine(((int)(centroids[i][j][0]*300)) + 250,((int)(centroids[i][j][1]*300)) + 50, ((int)(centroids[i][j+1][0]*300)) + 250,((int)(centroids[i][j+1][1]*300)) + 50); } g.drawLine(((int)(centroids[i][9][0]*300)) + 250,((int)(centroids[i][9][1]*300)) + 50, ((int)(centroids[i+1][9][0]*300)) + 250,((int)(centroids[i+1][9][1]*300)) + 50); g.drawLine(((int)(centroids[9][i][0]*300)) + 250,((int)(centroids[9][i][1]*300)) + 50, ((int)(centroids[9][i+1][0]*300)) + 250,((int)(centroids[9][i+1][1]*300)) + 50); } } // Train the network public void Train(double lr) { int nearx, neary; // Identifies the winner centroid double distance,current; // distance to nearest centroid and current centroid for(int n=5; n>=0; n--) // Neighborhood decreases from 5 to 0 { // Blank status area g.setColor(Color.white); g.fillRect(690,50,30,35); g.setColor(Color.black); // g.drawRect(690,50,30,35); // Print updates to status area g.drawString("Neighborhood = " + Integer.toString(n),600,60); g.drawString("Completed = %",600,75); for(int i=0; i<1000; i++) // For each data point { // Update progress readout if((i%100) == 0) { // Blank status area g.setColor(Color.white); g.fillRect(690,65,15,10); g.setColor(Color.black); // g.drawRect(690,65,15,10); // Update status area g.drawString(Integer.toString(i/10),690,75); } // Set distance so that first centroid will become nearest centroid distance = 2.0; // Initialize nearest centroid to 0,0 nearx = neary = 0; for(int gridx=0; gridx<10; gridx++) // Search clusters for nearest for(int gridy=0; gridy<10; gridy++) // member { // Compute squared distance current = (data[i][0]-centroids[gridx][gridy][0])*(data[i][0]-centroids[gridx][gridy][0]) + (data[i][1]-centroids[gridx][gridy][1])*(data[i][1]-centroids[gridx][gridy][1]); // If we have a new winner, update nearx and neary if(current < distance) { distance = current; nearx = gridx; neary = gridy; } } // Update all centroids within neighborhood for(int x=Math.max(0,nearx-n); x