车辆伴随分析算法实现:代码拆分、注释详解
/**
-
车辆伴随分析类 */ public class VehicleFollowAnalysis {
/**
-
计算车辆伴随关系
-
@param records 过车记录集合
-
@param X 时间间隔阈值,单位为分钟
-
@param Y 连续通过设备阈值
-
@return 新的伴随关系集合 */ public List
calculateFollow(List records, int X, int Y) { // 按照车牌号和号牌种类进行分组 Map<String, List > groupByPlateNum = records.stream() .collect(Collectors.groupingBy(record -> record.getHpzl() + record.getHphm())); List
result = new ArrayList<>(); // 遍历每个车牌号,计算伴随关系 for (Map.Entry<String, List
> entry : groupByPlateNum.entrySet()) { List recordList = entry.getValue(); // 按照过车时间排序 Collections.sort(recordList, Comparator.comparing(AnalysisJudgmentVehiceFollowVO::getGcsj)); // 记录每个设备的通过时间,用于计算时间间隔 Map<String, String> lastPassTime = new HashMap<>(); // 遍历当前车牌号的所有过车记录,计算伴随关系 for (int i = 0; i < recordList.size(); i++) { AnalysisJudgmentVehiceFollowVO currentRecord = recordList.get(i); String currentDeviceId = currentRecord.getSbid(); // 记录当前设备的通过时间 lastPassTime.put(currentDeviceId, currentRecord.getGcsj()); // 遍历之后的所有过车记录,计算伴随关系 for (int j = i + 1; j < recordList.size(); j++) { AnalysisJudgmentVehiceFollowVO nextRecord = recordList.get(j); String nextDeviceId = nextRecord.getSbid(); long timeInterval = getTimeInterval(lastPassTime.get(nextDeviceId), nextRecord.getGcsj()); // 如果通过设备相同且时间间隔小于阈值,则视为伴随车 if (currentDeviceId.equals(nextDeviceId) && timeInterval < X * 60 * 1000) { // 获取当前车辆 String hpzl = currentRecord.getHpzl(); String hphm = currentRecord.getHphm(); // 获取伴随车辆 String bscHpzl = nextRecord.getHpzl(); String bscHphm = nextRecord.getHphm(); String bssj = String.valueOf(getTimeInterval(currentRecord.getGcsj(), nextRecord.getGcsj())); // 构造新的伴随关系对象 VehicleFollowVO vehicleFollowVO = new VehicleFollowVO(hpzl, hphm, bscHpzl, bscHphm, bssj); // 添加伴随设备 vehicleFollowVO.addDevice(currentDeviceId, currentRecord.getSbmc()); vehicleFollowVO.addDevice(nextDeviceId, nextRecord.getSbmc()); // 查找连续通过相同设备的记录 int count = 2; for (int k = j + 1; k < recordList.size(); k++) { AnalysisJudgmentVehiceFollowVO tempRecord = recordList.get(k); if (currentDeviceId.equals(tempRecord.getSbid())) { long tempTimeInterval = getTimeInterval(lastPassTime.get(currentDeviceId), tempRecord.getGcsj()); if (tempTimeInterval < X * 60 * 1000) { vehicleFollowVO.addDevice(currentDeviceId, tempRecord.getSbmc()); count++; } } else { break; } } // 如果连续通过相同设备的次数大于阈值,则添加到伴随关系集合中 if (count >= Y) { result.add(vehicleFollowVO); } } } }}
return result; }
/**
- 计算时间间隔
- @param startTime 起始时间,格式为yyyy-MM-dd HH:mm:ss
- @param endTime 终止时间,格式为yyyy-MM-dd HH:mm:ss
- @return 时间间隔,单位为毫秒 */ private long getTimeInterval(String startTime, String endTime) { SimpleDateFormat sdf = new SimpleDateFormat('yyyy-MM-dd HH:mm:ss'); long startMillis = 0; long endMillis = 0; try { startMillis = sdf.parse(startTime).getTime(); endMillis = sdf.parse(endTime).getTime(); } catch (ParseException e) { e.printStackTrace(); } return endMillis - startMillis; } }
-
/**
-
车辆伴随关系对象 */ class VehicleFollowVO { private String hpzl; // 车牌号码种类 private String hphm; // 车牌号码 private String bscHpzl; // 伴随车车牌号码种类 private String bscHphm; // 伴随车车牌号码 private String bssj; // 伴随时间,单位为分钟,字符串类型 private List
devices; // 伴随设备集合 public VehicleFollowVO(String hpzl, String hphm, String bscHpzl, String bscHphm, String bssj) { this.hpzl = hpzl; this.hphm = hphm; this.bscHpzl = bscHpzl; this.bscHphm = bscHphm; this.bssj = bssj; this.devices = new ArrayList<>(); }
/**
- 添加伴随设备
- @param sbid 设备id
- @param sbmc 设备名称 */ public void addDevice(String sbid, String sbmc) { VehDeviceVO device = new VehDeviceVO(sbid, sbmc); devices.add(device); }
// getter和setter方法省略 }
/**
-
伴随设备对象 */ class VehDeviceVO { private String sbid; // 设备id private String sbmc; // 设备名称
public VehDeviceVO(String sbid, String sbmc) { this.sbid = sbid; this.sbmc = sbmc; }
// getter和setter方法省略 }
原文地址: https://www.cveoy.top/t/topic/n1go 著作权归作者所有。请勿转载和采集!