public int[] kleinberg(int cluster, double[] data, double dataMin, double dataMax, int max_itr){ //Kleinberg̃o[XgmASYɂNX^O
		stopWatch("Clustering by Kleinberg Algorithm..");
		
		int size = data.length;
		
		//frequency map
		double range = dataMax - dataMin;
		//int pitch = 10; //pxz̋ԁij
		int pitch = 10*60; //pxz̋ԁibj
		int arraySize = 1 + (int)range / pitch;
		int[] dataFreq = new int[arraySize];
		int[] state = new int[arraySize];
		for(int a=0; a<arraySize; a++) {
			dataFreq[a] = 0;
			state[a] = 0;
		}
		for(int i=0; i<size; i++){
			int index = (int)(((int)data[i] - (int)dataMin) / pitch);
			dataFreq[index]++;
		}
		int maxFreq = 0;
		int minFreq = Integer.MAX_VALUE;
		double avgFreq = 0.0;
		for(int a=0; a<arraySize; a++){
			avgFreq += dataFreq[a];
			if(dataFreq[a] > maxFreq) maxFreq = dataFreq[a];
			if(dataFreq[a] < minFreq) minFreq = dataFreq[a];
		}
		avgFreq /= arraySize;
		
		//kleinberg
		int[] initCluster = new int[size];

		//double level = 1.0;
		double gamma = 1.0;
		double numer = avgFreq - minFreq;
		double denom = maxFreq - minFreq;
		int denomInt = 10;
		double level = (denom / numer - 1) / stateMax;
		//double level = (denom / numer) / stateMax;
		//if(level > denom/numer) level = denom / numer;
		double normal = numer / denom;
		double[] stateCost = new double[stateMax];
		for (int s=0; s<stateMax; s++) {
			stateCost[s] = normal * (1 + level * s);
			//stateCost[s] = normal * (level * s);
		}
		
		double sequentialCost = 0.0;		
		for(int a=0; a<arraySize; a++){
			int freqInt = (int) (denomInt * (dataFreq[a] - minFreq) / denom);
			//ԃRXg
			double[] candidateCost = new double[stateMax];
			for(int s=0; s<stateMax; s++){
				candidateCost[s] = - Math.log(Math.pow(stateCost[s], freqInt) * Math.pow(1 - stateCost[s], denomInt - freqInt) * combination(denomInt, freqInt))
						+ sequentialCost;
				if(a>1 && state[a-1] < s) candidateCost[s] += (s - state[a-1]) * gamma; //ԑJڃRXg
			}

			double lowestCost = Double.MAX_VALUE;
			int lowestCostState = 0;
			for(int s=0; s<stateMax; s++){
				if(candidateCost[s] < lowestCost) {
					lowestCost = candidateCost[s];
					lowestCostState = s;
				}
			}
			sequentialCost = lowestCost;
			state[a] = lowestCostState;
		}
		
		ArrayList<Integer> burstPoints = new ArrayList<Integer>();
		burstPoints.add(0);
		boolean bursting = false;
		if (state[0] > 0) bursting = true;
		for(int a=1; a<arraySize; a++){
			if(state[a] > state[a-1] && !bursting) {
				if(!burstPoints.contains(a-1)) burstPoints.add(a-1);
				bursting = true;
			}else if(state[a] < state[a-1] && bursting){
				bursting = false;
			}
		}
		
		for(int k=0; k<burstPoints.size(); k++){
			for(int i=0; i<size; i++){
				if(data[i] - dataMin >= burstPoints.get(k) * pitch) initCluster[i] = k;
			}
		}
		
		kleinbergCluster = burstPoints.size();
		
		return initCluster;
	}