山野万里__ 2024-06-03 23:24 采纳率: 66.7%
浏览 4
已结题

算法!!广度优先搜索的遍历循环

写了两个广度优先搜索的遍历循环,得到的结果为什么不一样呢?以下是我实现的两个函数,找GPT4O也没解决掉这个问题,求解答,十分感谢!
函数一:

def detect_and_select_faces(wall_faces):
    """
    根据相邻性对面进行分组。

    Args:
    - wall_faces (list): 包含墙面对象的列表。

    Returns:
    - face_groups (list): 分组后的墙面列表。
    """
    face_groups = []  # 存储分组后的墙面
    for face0 in wall_faces:
        face_group = []  # 存储当前墙面相邻的墙面
        hasInGroup = False  # 判断当前墙面是否已经在某个组中
        # 遍历已分组的墙面组
        for idf, item in enumerate(face_groups):
            if face0 in item:
                hasInGroup = True
                # 如果当前墙面已经在组中,就检查该墙面周围的墙面是否也在同一组中
                for i, face in enumerate(wall_faces):
                    # 如果墙面在组中,就不需要再次求关系了
                    if face in item:
                        pass
                    # 如果墙面不在组中,就检查两个墙面是否垂直且相邻,是的话就添加到组中
                    else:
                        if are_planes_perpendicular(face.plane_normal, face0.plane_normal) and \
                                are_boxes_adjacent(face.box.get_box_points(), face0.box.get_box_points(), threshold_distance=300):
                            face_groups[idf].append(face)
        # 如果当前墙面已经在某个组中,则继续下一个墙面的分组
        if hasInGroup:
            continue
        else:
            # 如果当前墙面不在任何组中,就寻找与其相邻的其他墙面,将它们加入到同一组中
            for i, face in enumerate(wall_faces):
                if face.id != face0.id:  # 防止与自身比较
                    if are_planes_perpendicular(face.plane_normal, face0.plane_normal) and \
                            are_boxes_adjacent(face.box.get_box_points(), face0.box.get_box_points(), threshold_distance=300):
                        face_group.append(face)
            # 如果找到相邻的墙面,则将当前墙面加入到该组中
            if len(face_group) >= 1:
                face_group.append(face0)
                face_groups.append(sorted(face_group, key=lambda x: x.id))

    # 去除重复的墙面组
    for idx, face_group in enumerate(face_groups):
        face_groups[idx] = sorted(face_group, key=lambda x: x.id)
    face_groups = sorted(face_groups, key=lambda x: x[0].id)

    # 移除重复的组
    n = 0
    idxx = []
    for idx, face_group in enumerate(face_groups):
        if idx + 1 < len(face_groups):
            if face_group[0].id == face_groups[idx + 1][0].id:
                idxx.append(idx)
    n = 0
    for x in idxx:
        x -= n
        face_groups.remove(face_groups[x])
        n += 1

    # 打印每个组中的墙面id
    for idx, face_group in enumerate(face_groups):
        string = []
        for face in face_group:
            string.append(face.id)
        print(string)
    return face_groups

函数二:


```python

def detect_and_select_faces(wall_faces):
    """
    根据相邻性和垂直性对面进行分组。

    Args:
    - wall_faces (list): 包含墙面对象的列表。

    Returns:
    - face_groups (list): 分组后的墙面列表。
    """
    face_groups = []  # 存储分组后的墙面
    visited_faces = set()  # 记录已处理的面

    def find_adjacent_perpendicular_faces(face0):
        """找到与给定面相邻且垂直的所有面。"""
        adjacent_faces = []
        for face in wall_faces:
            if face.id != face0.id and face.id not in visited_faces:
                if are_planes_perpendicular(face.plane_normal, face0.plane_normal) and \
                        are_boxes_adjacent(face.box.get_box_points(), face0.box.get_box_points(), threshold_distance=300):
                    adjacent_faces.append(face)
        return adjacent_faces

    for face0 in wall_faces:
        if face0.id in visited_faces:
            continue
        face_group = [face0]  # 用于存储相邻墙面的列表
        visited_faces.add(face0.id)  # 标记此面已处理

        # 使用队列来处理相邻的面
        queue = [face0]
        while queue:
            current_face = queue.pop(0)
            adjacent_faces = find_adjacent_perpendicular_faces(current_face)
            for adj_face in adjacent_faces:
                if adj_face.id not in visited_faces:
                    face_group.append(adj_face)
                    visited_faces.add(adj_face.id)
                    queue.append(adj_face)

        face_groups.append(sorted(face_group, key=lambda x: x.id))
    face_groups = [group for group in face_groups if len(group) > 1]
    return face_groups

  • 写回答

2条回答 默认 最新

  • 阿里嘎多学长 2024-06-03 23:25
    关注

    以下内容由CHATGPT及阿里嘎多学长共同生成、有用望采纳:


    两个函数实现广度优先搜索(BFS)的逻辑存在一些差异,这些差异可能导致它们得到的结果不一致。下面我将分析两个函数的逻辑差异,并提供一些可能的改进建议。

    函数一的逻辑分析:

    1. 判断墙面是否垂直且相邻:通过are_planes_perpendicularare_boxes_adjacent函数来判断。
    2. 处理和存储分组后的墙面:使用嵌套循环,如果face0已经在某个组中,则跳过。否则,创建新的组并添加face0
    3. 避免重复处理墙面:通过hasInGroup标志来避免重复处理。
    4. 移除重复的组:通过比较组的第一个元素的id来移除重复的组。

    函数二的逻辑分析:

    1. 判断墙面是否垂直且相邻:与函数一相同。
    2. 处理和存储分组后的墙面:使用队列来实现BFS,通过visited_faces集合记录已处理的墙面。
    3. 避免重复处理墙面:通过visited_faces集合来避免重复处理。
    4. 移除重复的组:通过列表推导式移除只包含一个元素的组。

    逻辑差异:

    • 循环方式:函数一使用嵌套循环,而函数二使用队列实现BFS。
    • 存储方式:函数一使用列表,函数二使用集合visited_faces来记录已处理的墙面。
    • 去重逻辑:函数一在最后进行去重,而函数二在添加到face_group之前检查是否已处理。

    可能导致结果不一致的原因:

    1. 去重逻辑:函数一的去重逻辑可能不够健壮,因为它依赖于比较组的第一个元素的id,这可能无法正确处理所有重复情况。
    2. 循环方式:嵌套循环可能导致某些墙面被错误地分组或漏分组,尤其是在墙面关系复杂的情况下。
    3. 初始条件:函数一在遍历wall_faces时,如果face0已经在某个组中,则跳过,这可能导致某些墙面被遗漏。

    改进建议:

    • 统一去重逻辑:可以使用集合来记录已经添加到组中的墙面,这样可以更有效地避免重复。
    • 优化循环方式:考虑使用队列来实现BFS,这样可以更系统地处理墙面之间的关系。
    • 检查初始条件:确保在开始处理之前,所有墙面都未被分组。

    参考资料:

    希望这些分析和建议能帮助你理解两个函数的差异,并找到导致结果不一致的原因。如果需要进一步的帮助,请随时提问。

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论 编辑记录
查看更多回答(1条)

报告相同问题?

问题事件

  • 系统已结题 6月12日
  • 已采纳回答 6月4日
  • 创建了问题 6月3日

悬赏问题

  • ¥15 Windows Script Host 无法找到脚本文件"C:\ProgramData\Player800\Cotrl.vbs”
  • ¥15 matlab自定义损失函数
  • ¥15 35114 SVAC视频验签的问题
  • ¥15 impedancepy
  • ¥15 求往届大挑得奖作品(ppt…)
  • ¥15 如何在vue.config.js中读取到public文件夹下window.APP_CONFIG.API_BASE_URL的值
  • ¥50 浦育平台scratch图形化编程
  • ¥20 求这个的原理图 只要原理图
  • ¥15 vue2项目中,如何配置环境,可以在打完包之后修改请求的服务器地址
  • ¥20 微信的店铺小程序如何修改背景图