jsp中DBSCAN演算法實現執行個體

來源:互聯網
上載者:User

DBSCAN是一種基於密度的聚類演算法,它的基本原理就是給定兩個參數,ξ和minp,其中 ξ可以理解為半徑,演算法將在這個半徑內尋找樣本,minp是一個以ξ為半徑尋找到的樣本個數n的限制條件,只要n>=minp,尋找到的樣本點就是核心樣本點,演算法的具體描述見參考檔案1,下邊是這個演算法的java實現:
  首先定義一個Point類,代表樣本點

  <!--[endif]-->

  

package com.sunzhenxing;

  public class Point {

  private int x;

  private int y;

  private boolean isKey;

  private boolean isClassed;

  public boolean isKey() {

  return isKey;

  }

  public void setKey(boolean isKey) {

  this.isKey = isKey;

  this.isClassed=true;

  }

  public boolean isClassed() {

  return isClassed;

  }

  public void setClassed(boolean isClassed) {

  this.isClassed = isClassed;

  }

  public int getX() {

  return x;

  }

  public void setX(int x) {

  this.x = x;

  }

  public int getY() {

  return y;

  }

  public void setY(int y) {

  this.y = y;

  }

  public Point(){

  x=0;

  y=0;

  }

  public Point(int x,int y){

  this.x=x;

  this.y=y;

  }

  public Point(String str){

  String[] p=str.split(",");

  this.x=Integer.parseInt(p[0]);

  this.y=Integer.parseInt(p[1]);

  }

  public String print(){

  return "<"+this.x+","+this.y+">";

  }

  }

  然後定義一個工具類,為演算法的實現服務:

  package com.sunzhenxing;

  import java.io.BufferedReader;

  import java.io.FileReader;

  import java.io.IOException;

  import java.util.*;

  public class Utility {

  /**

  * 測試兩個點之間的距離

  * @param p 點

  * @param q 點

  * @return 返回兩個點之間的距離

  */

  public static double getDistance(Point p,Point q){

  int dx=p.getX()-q.getX();

  int dy=p.getY()-q.getY();

  double distance=Math.sqrt(dx*dx+dy*dy);

  return distance;

  }
   /**
  * 檢查給定點是不是核心點

  * @param lst 存放點的鏈表

  * @param p 待測試的點

  * @param e e半徑

  * @param minp 密度閾值

  * @return 暫時存放訪問過的點

  */

  public static List<Point> isKeyPoint(List<Point> lst,Point p,int e,int minp){

  int count=0;

  List<Point> tmpLst=new ArrayList<Point>();

  for(Iterator<Point> it=lst.iterator();it.hasNext();){

  Point q=it.next();

  if(getDistance(p,q)<=e){

  ++count;

  if(!tmpLst.contains(q)){

  tmpLst.add(q);

  }

  }

  }

  if(count>=minp){

  p.setKey(true);

  return tmpLst;

  }

  return null;

  }

  public static void setListClassed(List<Point> lst){

  for(Iterator<Point> it=lst.iterator();it.hasNext();){

  Point p=it.next();

  if(!p.isClassed()){

  p.setClassed(true);

  }

  }

  }

  /**

  * 如果b中含有a中包含的元素,則把兩個集合

合并

  * @param a

  * @param b

  * @return a

  */

  public static boolean mergeList(List<Point> a,List<Point> b){

  boolean merge=false;

  for(int index=0;index<b.size();++index){

  if(a.contains(b.get(index))){

  merge=true;

  break;

  }

  }

  if(merge){

  for(int index=0;index<b.size();++index){

  if(!a.contains(b.get(index))){

  a.add(b.get(index));

  }

  }

  }

  return merge;

  }

  /**

  * 返迴文本中的點集合

  * @return 返迴文本中點的集合

  * @throws IOException

  */

  public static List<Point> getPointsList() throws IOException{

  List<Point> lst=new ArrayList<Point>();

  String txtPath="src\com\sunzhenxing\points.txt";

  BufferedReader br=new BufferedReader(new FileReader(txtPath));

  String str="";

  while((str=br.readLine())!=null && str!=""){

  lst.add(new Point(str));

  }

  br.close();

  return lst;

  }

  }

  最後在主程式中實現演算法,如下所示:

  package com.sunzhenxing;

  import java.io.*;

  import java.util.*;

  public class Dbscan {

  private static List<Point> pointsList=new ArrayList<Point>();//儲存所有點的集合

  private static List<List<Point>> resultList=new ArrayList<List<Point>>();//儲存DBSCAN演算法返回的結果集

  private static int e=2;//e半徑

  private static int minp=3;//密度閾值

  /**

  * 提取文本中的的所有點並儲存在pointsList中

  * @throws IOException

  */

  private static void display(){

  int index=1;

  for(Iterator<List<Point>> it=resultList.iterator();it.hasNext();){

  List<Point> lst=it.next();

  if(lst.isEmpty()){

  continue;

  }
  System.out.println("-----第"+index+"個聚類-----");
  for(Iterator<Point> it1=lst.iterator();it1.hasNext();){

  Point p=it1.next();

  System.out.println(p.print());

  }

  index++;

  }

  }

  //找出所有可以直達的聚類

  private static void applyDbscan(){

  try {

  pointsList=Utility.getPointsList();

  for(Iterator<Point> it=pointsList.iterator();it.hasNext();){

  Point p=it.next();

  if(!p.isClassed()){

  List<Point> tmpLst=new ArrayList<Point>();

  if((tmpLst=Utility.isKeyPoint(pointsList, p, e, minp)) != null){

  //為所有聚類完畢的點做標示

  Utility.setListClassed(tmpLst);

  resultList.add(tmpLst);

  }

  }

  }

  } catch (IOException e) {

  // TODO Auto-generated catch block

  e.printStackTrace();

  }

  }

  //對所有可以直達的聚類進行合并,即找出間接可達的點並進行合并

  private static List<List<Point>> getResult(){

  applyDbscan();//找到所有直達的聚類

  int length=resultList.size();

  for(int i=0;i<length;++i){

  for(int j=i+1;j<length;++j){

  if(Utility.mergeList(resultList.get(i), resultList.get(j))){

  resultList.get(j).clear();

  }

  }

  }

  return resultList;

  }

  /**

  * 程式主函數

  * @param args

  */

  public static void main(String[] args) {

  getResult();

  display();

  //System.out.println(Utility.getDistance(new Point(0,0), new Point(0,2)));

  }

  }

  

下邊是一個小測試, 即使用src\com\sunzhenxing\points.txt檔案的內容進行測試,points.txt的檔案內容是:

 

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.