// Input data format: // // SENTINEL // B (number of buckets) // x1 (data point 1) // x2 (data point 2) // ... // xn (data point n) // SENTINEL // /* =============================== Sample input: 99999 3 1 2 3 4 5 6 99999 =============================== */ import java.io.*; public class Jagadish { static double INF = 999999; static int MAX1 = 100; static int MAX2 = 100; static int n = 0; // # data points static int B = 2; // # Buckets static double SUM[][] = new double[2][MAX2+1]; // Only uses SUM[1][..] // SUM[1][i] = v1+v2+...+vi static double SQSUM[][] = new double[2][MAX2+1]; // Only uses SQSUM[1][..] // SQSUM[1][i] = v1^2+v2^2+...+vi^2 static double BestError[][] = new double[MAX1+1][MAX2+1]; //BestError[a][b] = SOL[a,b] // = smallest SqError value for a items using b buckets static int min_index[] = new int[MAX2+1]; public static double SqError(int a, int b) { double s1, s2; s2 = SQSUM[1][b] - SQSUM[1][a-1]; s1 = SUM[1][b] - SUM[1][a-1]; return (s2 - s1*s1/(double) (b-a+1) ); } public static double MIN(double a, double b) { if (a < b) return(a); else return(b); } public static void main(String[] args) { double Sentinel; double v; int i, j, k; Sentinel = In.getDouble(); B = In.getInt(); v = In.getDouble(); SUM[1][1] = v; SQSUM[1][1] = v*v; n = 1; i = 2; while ( (v = In.getDouble()) != Sentinel ) { SUM[1][i] = SUM[1][i-1] + v; SQSUM[1][i] = SQSUM[1][i-1] + v*v; i++; n++; } // -------------------------------------- // Print out the values for checking // -------------------------------------- for (i = 1; i <= n; i++) System.out.println("SUM[1.." + i + "] = " + SUM[1][i] + " SQSUM[1.." + i + "] = " + SQSUM[1][i] + " SqError[1.." + i + "] = " + SqError(1, i) + " SqError[" + i + ".." + n + "] = " + SqError(i, n) ); // -------------------------------------- // OK, here come the firework... // k = # buckets // i = current item (1..i) // -------------------------------------- System.out.println("\n\n"); min_index[1] = 1; for (k = 1; k <= B; k++) // k = # buckets { System.out.println("k = " + k); for (i = 1; i <= n; i++) // range 1..i { System.out.println("#buckets k = " + k + "; range 1..i = " + i); if ( k == 1 ) { BestError[i][k] = SqError(1,i); } else { BestError[i][k] = INF; for (j = 1; j <= i-1; j++) { double min; System.out.println( "j = " + j + ": " + "BestError[i][k] = " + BestError[i][k] + " <=> " + "BestError[j][(k-1)]("+ BestError[j][(k-1)] + ") + " + "SqError((j+1),i)(" + SqError((j+1),i) + ") " + (BestError[j][k-1] + SqError(j+1,i)) ); if ( BestError[j][k-1] + SqError(j+1,i) < BestError[i][k] ) { BestError[i][k] = BestError[j][k-1] + SqError(j+1,i); min_index[i] = j+1; } /* min = MIN( BestError[i][k], BestError[j][k-1] + SqError(j+1,i) ); if ( min < BestError[i][k] ) { min_index[i] = j+1; } BestError[i][k] = min; */ } } System.out.println("*** BestError["+i+"]["+k+"] = " + BestError[i][k]); System.out.println(); } } for (i = 1; i <= n; i++) System.out.println("min_index[" + i + "] = " + min_index[i]); System.out.println("\n\nInterval points for histogram:\n"); i = B; j = n; while (i >= 2) { int end_point; end_point = j; j = min_index[j]; System.out.println("[" + j + " .. " + end_point + "]"); j--; i--; } System.out.println("[" + 1 + " .. " + j + "]"); } }