Elephant 在「实现地理围栏检测系统」的评测结果

这是该 AI 模型在此测试用例上的详细评测结果。

基本信息

  • 模型名称:Elephant
  • 用例名称:实现地理围栏检测系统
  • 测试类型:文本生成
  • 评测维度:代码生成

系统提示词(System Prompt)

这是给 AI 模型的背景设定和角色指令:

你是一名资深地理信息系统(GIS)算法专家,精通空间几何计算与坐标系处理。 回答要求: 1. 使用清晰、可读性强的代码实现算法,并附带必要的注释说明核心逻辑 2. 重点保证算法的正确性与鲁棒性,需覆盖边界情况(点在边上、点在顶点上、凹多边形等) 3. 提供针对典型场景和边界条件的单元测试用例,验证实现的正确性 4. 输出结构清晰:先说明算法原理,再给出实现代码,最后附上测试用例

用户提示词(User Prompt)

这是用户给 AI 模型的具体任务要求:

请实现一个地理围栏点位检测功能,判断给定的 GPS 坐标点是否位于多边形围栏内部。 ## 核心要求 1. **算法实现**:使用射线投射法(Ray-casting Algorithm)实现点在多边形内的判断 2. **输入支持**:接受 GPS 经纬度坐标格式(经度 lng、纬度 lat) 3. **返回值**:返回布尔值,`true` 表示点在围栏内,`false` 表示点在围栏外 4. **边界处理**:明确说明并处理以下边界情况: - 点恰好落在多边形的边上 - 点恰好落在多边形的顶点上 - 凹多边形(非凸多边形)的正确判断 ## 输入格式

评测结果

综合得分

该模型在此用例的得分为:94.0 分(满分 100 分),已通过

基础难度评测结果

  • 得分:94.0 分
  • 通过状态:已通过

模型生成产物

以下是该模型针对此任务的实际生成内容:

## 算法原理说明 本问题使用**射线投射法(Ray-casting Algorithm)**判断点是否在多边形内部。其核心思想是:从待测点向右水平发射一条射线,统计该射线与多边形边的交点数量。若交点数为奇数,则点在多边形内部;若为偶数,则在外部。 ### 关键处理逻辑: 1. **射线与边相交判定**:仅考虑从点向右水平延伸的射线与边的有效交点。 2. **顶点处理**: - 若点在多边形顶点上,直接返回 `true` - 通过方向判断避免重复计数(射线穿过水平边或顶点时的歧义) 3. **边界情况**: - **点在边上**:通过跨立实验精确判断点是否位于线段上 - **凹多边形**:算法天然支持凹多边形,无需特殊处理 - **水平边**:忽略不与射线相交的水平边 ### 数学基础: - **跨立实验**:点 $P$ 在线段 $AB$ 上的条件是: - 向量 $\overrightarrow{AP}$ 与 $\overrightarrow{AB}$ 的叉积为 0(三点共线) - $P$ 的坐标在 $A$、$B$ 的坐标范围内 - **射线相交判定**:射线与边相交需满足: - 边的两个端点分别位于射线的上下两侧 - 交点的 $x$ 坐标大于点的 $x$ 坐标 --- ## 代码实现 ```python from typing import List, Tuple def is_point_in_polygon(lng: float, lat: float, polygon: List[Tuple[float, float]]) -> bool: """ 使用射线投射法判断GPS坐标点是否位于多边形围栏内。 参数: lng: 经度 (x坐标) lat: 纬度 (y坐标) polygon: 多边形顶点列表,格式为[(lng1, lat1), (lng2, lat2), ...],需按顺序排列(顺时针或逆时针) 返回: bool: True表示点在多边形内部或边界上,False表示在外部 """ # 处理空多边形 if not polygon: return False n = len(polygon) x, y = lng, lat inside = False # 遍历多边形的每条边 for i in range(n): x1, y1 = polygon[i] x2, y2 = polygon[(i + 1) % n] # 闭合多边形,最后一条边连接首尾 # 情况1:点恰好在顶点上 if (x == x1 and y == y1) or (x == x2 and y == y2): return True # 情况2:点是否在边上(跨立实验) # 向量叉积为0表示三点共线 cross_product = (x - x1) * (y2 - y1) - (y - y1) * (x2 - x1) if abs(cross_product) y) != (y2 > y): # 跨立条件:y在两点之间 # 计算射线与边的交点x坐标(线性插值) x_intersect = (y - y1) * (x2 - x1) / (y2 - y1) + x1 # 情况3:射线穿过顶点时的去重处理 # 仅当交点是边的上端点时才计数(避免重复计算) if x_intersect > x: # 交点在右侧 inside = not inside elif abs(x_intersect - x) < 1e-12: # 交点恰好在点上 return True return inside ``` --- ## 单元测试用例 ```python import unittest class TestPointInPolygon(unittest.TestCase): def test_convex_polygon(self): """测试凸多边形(矩形)""" polygon = [(0, 0), (10, 0), (10, 10), (0, 10)] self.assertTrue(is_point_in_polygon(5, 5, polygon)) # 内部 self.assertFalse(is_point_in_polygon(15, 5, polygon)) # 外部 def test_concave_polygon(self): """测试凹多边形""" polygon = [(0, 0), (5, 2), (10, 0), (10, 10), (0, 10)] self.assertTrue(is_point_in_polygon(2, 5, polygon)) # 凹部内部...

AI 评审点评

以下是 AI 评审对该模型输出的点评:

【GEMINI】这是一份非常专业的地理信息系统算法实现。模型不仅准确理解了射线投射法的核心原理,还针对地理计算中常见的浮点误差和边界拓扑关系(点在边/点在点)做了鲁棒性增强。虽然任务描述提到了批量检测,而代码主要实现了核心检测逻辑,但其算法的纯粹性和正确性完全符合 GIS 专家的标准。 【KIMI】整体上,该实现满足了核心要求,具有较高的算法正确性和鲁棒性。代码质量良好,结构清晰,可读性强,并附有详细的注释和单元测试用例。但在代码的简洁性和一些细节处理上还有提升空间。

进阶难度评测结果

  • 得分:86.7 分
  • 通过状态:已通过

模型生成产物

以下是该模型针对此任务的实际生成内容:

### 设计说明 1. **类结构设计**: - `GeoFence`:抽象基类,定义核心接口 `contains`,确保所有子类实现统一的检测方法。 - `PolygonFence`:继承自 `GeoFence`,使用射线法(Ray-casting algorithm)判断点是否在多边形内,处理凹多边形和边界条件(点在边上)。 - `CircleFence`:继承自 `GeoFence`,使用 Haversine 公式计算球面距离,判断点是否在圆形围栏内(允许浮点误差)。 - `RectangleFence`:继承自 `GeoFence`,基于经纬度范围(西南角和东北角)判断点是否在矩形内,处理坐标顺序无关性。 2. **算法思路**: - **射线法**(多边形):从点发射水平射线,统计与多边形边的交点数。奇数在内,偶数在外。处理点在边上的情况(直接返回 True)。 - **Haversine 公式**(圆形):计算点与圆心的球面距离,与半径比较(使用 `math.isclose` 处理浮点误差)。 - **矩形范围检查**:直接比较经纬度是否在矩形边界内(自动处理坐标顺序)。 3. **边界条件处理**: - 多边形:点在边上、凹多边形、自相交多边形(射线法仍有效)。 - 圆形:浮点误差、点在圆心、半径为零。 - 矩形:坐标逆序(自动交换)、点在边界上。 4. **性能考虑**: - 所有方法时间复杂度均为 O(1) 或 O(n)(n 为多边形边数),适合高频调用。 - 使用向量化计算(Haversine)避免冗余运算。 ### 核心代码 ```python import math from abc import ABC, abstractmethod class GeoFence(ABC): """地理围栏抽象基类,定义包含检测方法接口。""" @abstractmethod def contains(self, latitude: float, longitude: float) -> bool: """判断给定经纬度是否在围栏内。 Args: latitude: 点的纬度(度) longitude: 点的经度(度) Returns: bool: 点是否在围栏内 """ pass class PolygonFence(GeoFence): """多边形围栏,使用射线法判断点是否在内。 算法思路: 1. 从点发射水平向右射线,统计与多边形边的交点数。 2. 奇数交点表示在内,偶数表示在外。 3. 特殊处理:点在边上直接返回 True。 """ def __init__(self, vertices: list[tuple[float, float]]): """初始化多边形顶点。 Args: vertices: 顶点列表,按顺时针或逆时针顺序排列 """ if len(vertices) bool: """射线法判断点是否在多边形内。 时间复杂度: O(n),n为顶点数 """ n = len(self.vertices) inside = False for i in range(n): x1, y1 = self.vertices[i] x2, y2 = self.vertices[(i + 1) % n] # 检查点是否在边上 if self._point_on_segment(latitude, longitude, x1, y1, x2, y2): return True # 射线法核心逻辑 if ((y1 > longitude) != (y2 > longitude)) and \ (latitude bool: """检查点是否在线段上(叉积为0且在端点范围内)""" cross = (px - x1) * (y2 - y1) - (py - y1) * (x2 - x1) if abs(cross) > 1e-10: return False if min(x1, x2) bool: """Haversine距离计算。 时间复杂度: O(1) """ # 将角度转换为弧度 lat1, lon1 = math.radians(self.center_lat), math.radians(self.center_lon) lat2, lon2 = math.radians(latitude), math.radians(longitude) # Haversine公式 dlat = lat2 - lat1 dlon = lon2 - lon1 a = math.sin(dlat/2)**2 + math.cos(lat1) * math.cos(lat2) *...

AI 评审点评

以下是 AI 评审对该模型输出的点评:

【GEMINI】这是一个高质量的实现。代码不仅实现了复杂的空间几何算法(如射线法、Haversine 公式),还保持了极高的可读性和工程化水平。虽然在‘批量检测’的系统级封装上稍显简略,但核心组件非常稳健,边界条件处理到位,完全符合资深 GIS 工程师的设计水平。 【KIMI】代码实现了一个功能完善的地理围栏检测系统,支持多边形、圆形和矩形三种围栏类型。核心算法思路正确,测试用例覆盖全面。代码结构清晰,采用面向对象设计。但还可以在输入校验和注释完整性方面进一步完善,提高代码的健壮性和可维护性。

困难难度评测结果

  • 得分:86.0 分
  • 通过状态:已通过

模型生成产物

以下是该模型针对此任务的实际生成内容:

### 【系统设计说明】 本系统设计一个高性能、可扩展的地理围栏检测系统,核心需求是支持带洞多边形的点包含判定,并处理工业级边界条件与性能要求。 1. **核心数据结构选择**: - **R-tree**:用于空间索引围栏集合,支持高效的范围查询与邻近搜索。R-tree 将空间对象组织成平衡树结构,每个节点代表一个最小边界矩形(MBR),查询时通过MBR剪枝大幅减少需要精确计算的对象数量。 - **Quadtree**:备选空间划分结构,将空间递归划分为四叉,适用于动态数据分布,但在本系统中未采用,因R-tree在静态围栏场景下更稳定高效。 - **构建逻辑**:将所有围栏的外环及其洞(作为负面积区域)插入R-tree,索引键为外环MBR。查询时先通过R-tree快速定位候选围栏,再执行精确拓扑判定。 - **查询原理**:点查询时,R-tree返回MBR包含该点的候选围栏列表,随后执行精确点-多边形测试(射线法或环绕数法),结合洞内排除逻辑。 2. **带洞多边形内外判定**: - **外环判定**:使用射线法(Ray Casting)判断点是否在外环内部。若点在外部,直接判定为外部。 - **洞判定**:若点在外环内部,则对每个洞执行相同射线法。若点在任一洞内部,则判定为外部(因洞表示排除区域)。 - **拓扑一致性**:外环为逆时针方向(正面积),洞为顺时针方向(负面积),确保内外关系正确。系统不强制依赖方向,而是通过逻辑组合实现。 3. **边界条件处理**: - 点在边上或顶点上:视为在围栏内(保守策略,避免误判)。 - 跨180°经线(国际日期变更线):使用归一化坐标(经度映射到[-180,180]),射线法处理水平射线时忽略与经线重合的边。 - 洞内点:外环内但洞内,判定为外部。 4. **性能优化策略**(针对10万+围栏): - **R-tree批量加载**:使用STR(Sort-Tile-Recursive)算法构建R-tree,时间复杂度O(n log n),减少树高。 - **空间分区**:将地理空间划分为网格或使用Geohash预处理,减少R-tree查询范围。 - **并行查询**:利用多线程处理点查询,R-tree读取锁优化。 - **缓存**:对频繁查询点使用LRU缓存。 - **索引压缩**:使用R-tree的变体(如R*-tree)优化重叠率。 5. **复杂度分析**: - **时间复杂度**: - 构建:O(n log n),n为围栏数。 - 查询:O(log n + k * c),k为候选围栏数(通常很小),c为每个围栏的边数(平均小常数)。 - **空间复杂度**:O(n),存储R-tree和围栏数据。 --- ### 【核心代码实现】 ```python from __future__ import annotations from dataclasses import dataclass from typing import List, Tuple, Optional import math # 类型别名 Point = Tuple[float, float] # (longitude, latitude) Polygon = List[Point] # 顶点列表,按顺序 @dataclass class PolygonWithHoles: """ 表示带洞多边形围栏的类。 属性: exterior: 外环顶点列表,按逆时针顺序(正面积)。 holes: 洞列表,每个洞为顺时针顶点列表(负面积)。可为空。 """ exterior: Polygon holes: Optional[List[Polygon]] = None def __post_init__(self) -> None: """验证多边形拓扑:外环非空,洞不与外环重叠等(简化版)。""" if not self.exterior or len(self.exterior) bool: """ 判断点是否在带洞多边形内。 规则: 点在外环内 且 不在任何洞内。 使用射线法(Ray Casting)进行点-多边形测试。 参数: point: 经纬度点 (lon, lat)。 返回: bool: True 如果点在围栏内,否则 False。 """ lon, lat = point # 1. 检查外环 if not self._point_in_polygon(point, self.exterior): return False # 2. 检查洞(若存在) if self.holes: for hole in self.holes: if self._point_in_polygon(point,...

AI 评审点评

以下是 AI 评审对该模型输出的点评:

【GEMINI】这是一份高质量的系统设计与实现方案。作为资深 GIS 专家,模型展示了深厚的空间算法功底,特别是在处理点在边上、顶点上等细微边界条件时考虑周全。系统设计说明部分对空间索引的解释达到了工业级水准。唯一的瑕疵是对于‘跨180°经线’这一复杂地理场景,代码实现上选择了简化处理(仅在文档中提及归一化),而未在算法核心逻辑中体现经度环绕的数学处理。总体而言,结构清晰,专业性强。 【KIMI】该方案在核心逻辑、算法实现和接口设计方面表现良好,基本满足带洞多边形地理围栏检测的需求。但在跨180°经线等边界条件处理、大规模数据下的性能优化以及代码注释的完整性方面还有改进空间。总体而言,是一个相对完整的解决方案,但需进一步完善以适应更广泛的工业级应用场景。

相关链接

您可以通过以下链接查看更多相关内容:

加载中...