private static double GetMaxDist(CabMetaData point,int cellId) { //获得网格左上角点坐标 double cellMinX = gridXLowBound + (cellId % gridTier) * gridLength; double cellMaxY = gridYUpperBound - (cellId / gridTier) * gridLength; //判断与网格相对位置 if (point.Longitude < cellMinX + gridLength * 0.5)//网格垂直平分线左边 { if (point.Latitude > cellMaxY - gridLength * 0.5)//网格水平平分线上边 { return Program.GetDistance(point.Latitude,point.Longitude, cellMaxY - gridLength,cellMinX + gridLength); } else//网格水平平分线下边 { return Program.GetDistance(point.Latitude,point.Longitude, cellMaxY,cellMinX + gridLength); } } else//网格垂直平分线右边 { if (point.Latitude > cellMaxY - gridLength * 0.5)//网格水平平分线上边 { return Program.GetDistance(point.Latitude,point.Longitude, cellMaxY - gridLength,cellMinX); } else//网格水平平分线下边 { return Program.GetDistance(point.Latitude,point.Longitude,cellMaxY,cellMinX); } } }
public void Add(CabMetaData point) { pointsList.Add(point); cabNameList.Add(point.CabName); point.clusterId = clusterId; cabInOrNotList.ChangeObjectStatus(point.CabName); }
public static bool Check(NewGrid grid, CabMetaData cab) { //Console.WriteLine("网格数(单边):"+gridTier); //Console.WriteLine("网格变长:"+gridLength); //Console.WriteLine("网格边界:"+gridXLowBound+" "+gridXUpperBound+" "+gridYLowBound+" "+gridYUpperBound); //int count = 0; //foreach (Cell cell in grid.cellList) //{ // count+=Cell.Check(cell); //} //Console.WriteLine(count); int i = 0, j = 0; foreach (List <Cell> list in grid.cellList) { foreach (Cell cell in list) { if (Cell.Check(cell, cab)) { Console.Write("(" + i + "," + j + ")"); return(true); } j++; } i++; } return(false); }
private static int LocateCell(CabMetaData cabMetaData) { double longitude = cabMetaData.Longitude; double latitude = cabMetaData.Latitude; int cellID = (int)(((gridYUpperBound - latitude) / gridLength) * gridTier) + (int)((longitude - gridXLowBound) / gridLength); return cellID; }
/*计算给定点和给定单元格的最大距离 * 方法:返回给定点和给定单元格四个顶点的距离最大者 */ private static double GetMaxDistBetweenPointAndCell(CabMetaData point, int indexX, int indexY) { double distLeftDown = Program.GetDistance(point.Latitude, point.Longitude, gridYLowBound + indexY * gridLength, gridXLowBound + indexX * gridLength); double distLeftUp = Program.GetDistance(point.Latitude, point.Longitude, gridYLowBound + (indexY + 1) * gridLength, gridXLowBound + indexX * gridLength); double distRightDown = Program.GetDistance(point.Latitude, point.Longitude, gridYLowBound + indexY * gridLength, gridXLowBound + (indexX + 1) * gridLength); double distRightUp = Program.GetDistance(point.Latitude, point.Longitude, gridYLowBound + (indexY + 1) * gridLength, gridXLowBound + (indexX + 1) * gridLength); return(Math.Max(Math.Max(distLeftDown, distLeftUp), Math.Max(distRightDown, distRightUp))); }
private List <int> LocateCell(CabMetaData cabMetaData) { double x = cabMetaData.Longitude; double y = cabMetaData.Latitude; List <int> result = new List <int>(2); result.Add((int)((x - gridXLowBound) / gridLength)); result.Add((int)((y - gridYLowBound) / gridLength)); return(result); }
public static bool Check(Cell cell, CabMetaData cab) { if (cell.points.Contains(cab, new CabMetaDataComparer())) { return(true); } else { return(false); } }
public CabMetaData(CabMetaData cabMetaData) { this.cabName = cabMetaData.cabName; this.cabMetaDataId = cabMetaData.cabMetaDataId; this.longitude = cabMetaData.longitude; this.latitude = cabMetaData.latitude; this.fare = cabMetaData.fare; this.timeStamp = cabMetaData.timeStamp; this.extension = ""; this.clusterId = cabMetaData.clusterId; }
public static bool Check(Grid grid,CabMetaData cab) { //Console.WriteLine("网格数(单边):"+gridTier); //Console.WriteLine("网格变长:"+gridLength); //Console.WriteLine("网格边界:"+gridXLowBound+" "+gridXUpperBound+" "+gridYLowBound+" "+gridYUpperBound); //int count = 0; //foreach (Cell cell in grid.cellList) //{ // count+=Cell.Check(cell); //} //Console.WriteLine(count); foreach (Cell cell in grid.cellList) { if (Cell.Check(cell, cab)) { return true; } } return false; }
public void insert(CabMetaData metadata) { points.Add(metadata); }
/*范围查询:给定查询点和查询范围,返回所有在查询范围中的网格上的点 * 方法:首先,根据查询范围得到要访问的网格上下左右界,使界不超过网格范围 * 然后,遍历在上述界内的所有点,对完全处在查询范围内的单元格,把其中所含的点全部加入结果集;否则,对每个单元格中的点再检查是否在查询范围内 */ public static List <CabMetaData> RangeQuery(NewGrid grid, CabMetaData queryPoint, double radious) { List <CabMetaData> result = new List <CabMetaData>();//结果集 //获取中心点所在单元格 //List<int> index = LocateCell(queryPoint); //要访问的网格上下左右界 int down, up, left, right; if (queryPoint.Longitude - radious >= gridXLowBound) { left = (int)((queryPoint.Longitude - radious - gridXLowBound) / gridLength); } else { left = 0; } if (queryPoint.Longitude + radious <= gridXUpperBound) { right = (int)((queryPoint.Longitude + radious - gridXLowBound) / gridLength); } else { right = gridTier - 1; } if (queryPoint.Latitude - radious >= gridYLowBound) { down = (int)((queryPoint.Latitude - radious - gridYLowBound) / gridLength); } else { down = 0; } if (queryPoint.Latitude + radious <= gridYUpperBound) { up = (int)((queryPoint.Latitude + radious - gridYLowBound) / gridLength); } else { up = gridTier - 1; } //遍历所有可能在查询范围内的单元格 for (int x = left; x <= right; x++) { for (int y = down; y <= up; y++) { //对完全处在查询范围内的单元格,把其中所含的点全部加入结果集 if (GetMaxDistBetweenPointAndCell(queryPoint, x, y) <= radious) { result.AddRange(grid.cellList[x][y].points); } else { //对于只有一部分在查询范围内的单元格,对其中的每个点再检查是否在查询范围内 foreach (CabMetaData point in grid.cellList[x][y].points) { if (Program.GetDistance(point.Latitude, point.Longitude, queryPoint.Latitude, queryPoint.Longitude) <= radious) { result.Add(point); } } } } } return(result); }
//判断是否是核心点 public static List <CabMetaData> IsKeyPoint(NewGrid grid, List <CabMetaData> lst, CabMetaData point) { List <CabMetaData> indexList = NewGrid.RangeQuery(grid, point, eps); if (indexList.Count >= minPts) { point.extension = "true"; return(indexList); } else { return(null); } }
public static double eps = 0.005; //ε半径 //dbscan过程(深度优先方法) public static List <DBscanCluster> ApplyDbscan(NewGrid grid, List <CabMetaData> pointsList) { List <DBscanCluster> resultList = new List <DBscanCluster>();// 存储最后的聚类结果 foreach (CabMetaData point in pointsList) { if (!point.extension.Equals("")) { continue; } else { List <CabMetaData> neighboursList = NewGrid.RangeQuery(grid, point, eps); if (neighboursList.Count >= minPts) { point.extension = "core"; resultList.Add(new DBscanCluster()); resultList[resultList.Count - 1].Add(point); Stack <CabMetaData> neighbourStack = new Stack <CabMetaData>(); foreach (CabMetaData neightbour in neighboursList) { if (!neightbour.CabMetaDataId.Equals(point.CabMetaDataId))//没必要把查询点也压入栈中(尽管不影响正确性),减少出栈次数 { neighbourStack.Push(neightbour); } } while (neighbourStack.Count > 0) { CabMetaData currentPoint = neighbourStack.Pop(); if (currentPoint.extension.Equals("") || currentPoint.extension.Equals("noice"))//如果标记为"core"或"neighbour",说明已经被处理过了 { resultList[resultList.Count - 1].Add(currentPoint); if (currentPoint.extension.Equals(""))//如果标记为"noice",说明肯定不是核心点 { List <CabMetaData> newNeighboursList = NewGrid.RangeQuery(grid, currentPoint, eps); if (neighboursList.Count >= minPts)//ε邻域大于密度阈值,标记为"core" { currentPoint.extension = "core"; foreach (CabMetaData neightbour in newNeighboursList) { if (!neightbour.CabMetaDataId.Equals(currentPoint.CabMetaDataId))//没必要把查询点也压入栈中(尽管不影响正确性),减少出栈次数 { neighbourStack.Push(neightbour); } } } else//ε邻域小于密度阈值,标记为"neighbour" { currentPoint.extension = "neighbour"; } } } } } else { point.extension = "noice"; } } } return(resultList); }
public static List<CabMetaData> RangeQuery(Grid grid, CabMetaData queryPoint, double radious, List<CabMetaData> cabLine) { List<CabMetaData> result = new List<CabMetaData>();//结果集 //获取中心点所在单元格,并计算向四个方向最多扩展的次数 int centerCell = LocateCell(queryPoint); int left = centerCell % gridTier; int right = gridTier - (centerCell % gridTier) - 1; int up = centerCell / gridTier; int down = gridTier - (centerCell / gridTier) - 1; Queue<CellItem> candidateCells=new Queue<CellItem>(); bool[] validArray = new bool[gridTier * gridTier];//对应网格是否已入队列,已入为true for (int i = 0;i!=gridTier*gridTier ;i++ ) { validArray[i] = false; } candidateCells.Enqueue(new CellItem(centerCell,0.0)); validArray[centerCell] = true; int times = 1;//扩散次数 while (candidateCells.Count > 0) { CellItem nextCell = candidateCells.Dequeue(); if (nextCell.minDist > radious)//网格完全在圆外面 { break; } double cellMaxDist = GetMaxDist(queryPoint, nextCell.cellId); List<CabMetaData> pointsOfCell = grid.cellList[nextCell.cellId].GetAllPoints(); if (cellMaxDist <= radious)//网格完全被圆包含 { foreach (CabMetaData point in pointsOfCell) { result.Add(point); } } else//网格与圆部分相交 { //检查网格每个点是否落于圆中 foreach (CabMetaData point in pointsOfCell) { if (Program.GetDistance(queryPoint.Latitude, queryPoint.Longitude, point.Latitude, point.Longitude) <= radious) { result.Add(point); } } } //扩散邻居网络 if (candidateCells.Count == 0) { if (times <= up)//未上溢出 { int upMidCell = centerCell - times * gridTier; if (!validArray[upMidCell]) { candidateCells.Enqueue(new CellItem(upMidCell,GetMinDist(queryPoint,upMidCell))); } for (int i = 1; i <= (times < left ? times : left); i++) { int nextCellInt = upMidCell - i; if (!validArray[nextCellInt]) { candidateCells.Enqueue(new CellItem(nextCellInt, GetMinDist(queryPoint, nextCellInt))); } } for (int i = 1; i <= (times < right ? times : right); i++) { int nextCellInt = upMidCell + i; if (!validArray[nextCellInt]) { candidateCells.Enqueue(new CellItem(nextCellInt,GetMinDist(queryPoint,nextCellInt))); } } } if (times <= down)//未下溢出 { int downMidCell = centerCell + times * gridTier; if (!validArray[downMidCell]) { candidateCells.Enqueue(new CellItem(downMidCell,GetMinDist(queryPoint,downMidCell))); } for (int i = 1; i <= (times < left ? times : left); i++) { int nextCellInt = downMidCell - i; if (!validArray[nextCellInt]) { candidateCells.Enqueue(new CellItem(nextCellInt, GetMinDist(queryPoint, nextCellInt))); } } for (int i = 1; i <= (times < right ? times : right); i++) { int nextCellInt = downMidCell + i; if (!validArray[nextCellInt]) { candidateCells.Enqueue(new CellItem(nextCellInt, GetMinDist(queryPoint, nextCellInt))); } } } if (times <= left)//未左溢出 { int leftMidCell = centerCell - times; if (!validArray[leftMidCell]) { candidateCells.Enqueue(new CellItem(leftMidCell, GetMinDist(queryPoint, leftMidCell))); } for (int i = 1; i <= (times<up?times:up); i++) { int nextCellInt = leftMidCell - gridTier * i; if (!validArray[nextCellInt]) { candidateCells.Enqueue(new CellItem(nextCell, GetMinDist(queryPoint, nextCellInt))); } } for (int i = 1; i <= (times<down?times:down); ++i) { int nextCellInt = leftMidCell +gridTier * i; if (!validArray[nextCellInt]) { candidateCells.Enqueue(new CellItem(nextCellInt, GetMinDist(queryPoint, nextCellInt))); } } } if (times <= right) //未右溢出 { int rightMidCell = centerCell + times; if (!validArray[rightMidCell]) { candidateCells.Enqueue(new CellItem(rightMidCell, GetMinDist(queryPoint, rightMidCell))); } for (int i = 1; i <= (times<up?times:up); ++i) { int nextCellInt = rightMidCell - gridTier * i; if (!validArray[nextCellInt]) { candidateCells.Enqueue(new CellItem(nextCell, GetMinDist(queryPoint, nextCellInt))); } } for (int i = 1; i <= (times<down?times:down); ++i) { int nextCellInt = rightMidCell + gridTier * i; if (!validArray[nextCellInt]) { candidateCells.Enqueue(new CellItem(nextCellInt, GetMinDist(queryPoint, nextCellInt))); } } } times++; } } return result; }
private static double GetMinDist(CabMetaData point, int cellId) { //获得网格左上角点坐标 double cellMinX = gridXLowBound + (cellId % gridTier) * gridLength; double cellMaxY = gridYUpperBound + (cellId / gridTier) * gridLength; //判断与网格相对位置 if (point.Longitude < cellMinX)//网格左边 { if (point.Latitude > cellMaxY)//左上 { return Program.GetDistance(point.Latitude, point.Longitude, cellMaxY, cellMinX); } else { if (point.Latitude >= cellMaxY - gridLength)//正左 { return Program.GetDistance(point.Latitude, point.Longitude, point.Latitude, cellMinX); } else//左下 { return Program.GetDistance(point.Latitude, point.Longitude, cellMaxY - gridLength, cellMinX); } } } else { if (point.Longitude < cellMinX + gridLength)//网格上中下 { if (point.Latitude > cellMaxY)//正上 { return point.Latitude - cellMaxY; } else { if (point.Latitude >= cellMaxY - gridLength)//正中 { return 0; } else//正下 { return cellMaxY - gridLength - point.Latitude; } } } else//网格右边 { if (point.Latitude > cellMaxY)//右上 { return Program.GetDistance(point.Latitude, point.Longitude, cellMaxY, cellMinX + gridLength); } else { if (point.Latitude >= cellMaxY - gridLength)//正右 { return Program.GetDistance(point.Latitude, point.Longitude, point.Latitude, cellMinX + gridLength); } else//右下 { return Program.GetDistance(point.Latitude,point.Longitude,cellMaxY-gridLength,cellMinX+gridLength); } } } } }