You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

三维空间原子节点精确连接3个最近邻的实现问题

解决方法:构建3-正则无向邻接矩阵(基于距离优先级)

看起来你需要的是一个无向的3-正则图——每个节点恰好有3个双向连接的邻居,且邻居选择严格遵循距离由近到远的优先级。当前的实现只保证了出度为3,但忽略了双向性,导致出现单向边和入度不一致的问题,下面是针对性的解决方案:

核心思路

我们需要先为每个节点初始化最近邻,然后遍历所有单向边,按照你提出的规则调整:

  • 若节点A的邻居包含B,但B的邻居不含A:优先让A移除B,从候选列表中找下一个最近的未连接节点
  • 若A无法找到可替换的节点(极端情况),则让B将其当前邻居中距离最远的那个替换为A,确保距离优先级

代码实现

import numpy as np

# 假设dist_mat是已预处理好的31×31原子距离矩阵
n_nodes = dist_mat.shape[0]
target_degree = 3  # 每个节点的目标入度/出度

# 步骤1:为每个节点生成按距离从小到大排序的邻居候选列表(排除自身)
sorted_neighbor_candidates = []
for node in range(n_nodes):
    # 收集所有非自身节点的索引和对应距离
    neighbor_dist_pairs = [(other_node, dist_mat[node][other_node]) 
                          for other_node in range(n_nodes) 
                          if other_node != node]
    # 按距离升序排序,只保留节点索引
    neighbor_dist_pairs.sort(key=lambda x: x[1])
    sorted_neighbor_candidates.append([pair[0] for pair in neighbor_dist_pairs])

# 步骤2:初始化邻接矩阵和节点邻居集合(方便快速查询)
adj_matrix = np.zeros((n_nodes, n_nodes), dtype=int)
node_neighbor_sets = [set() for _ in range(n_nodes)]

# 先给每个节点分配前3个最近的邻居
for node in range(n_nodes):
    for neighbor in sorted_neighbor_candidates[node][:target_degree]:
        adj_matrix[node][neighbor] = 1
        node_neighbor_sets[node].add(neighbor)

# 步骤3:处理单向边,调整连接以满足双向性和度数要求
for node_a in range(n_nodes):
    # 复制当前邻居列表,避免遍历过程中修改集合导致的异常
    current_neighbors = list(node_neighbor_sets[node_a])
    for node_b in current_neighbors:
        # 检测单向边:node_a连node_b,但node_b没连node_a
        if adj_matrix[node_b][node_a] != 1:
            # 尝试让node_a替换node_b,找下一个候选邻居
            replacement_success = False
            for candidate in sorted_neighbor_candidates[node_a]:
                if candidate not in node_neighbor_sets[node_a]:
                    # 移除旧邻居node_b,添加新候选
                    adj_matrix[node_a][node_b] = 0
                    node_neighbor_sets[node_a].remove(node_b)
                    adj_matrix[node_a][candidate] = 1
                    node_neighbor_sets[node_a].add(candidate)
                    replacement_success = True
                    break
            # 如果node_a找不到可替换的候选(极端情况),让node_b替换最远邻居为node_a
            if not replacement_success:
                # 找到node_b当前邻居中距离最远的节点
                farthest_neighbor = max(node_neighbor_sets[node_b], 
                                       key=lambda x: dist_mat[node_b][x])
                # 替换操作
                adj_matrix[node_b][farthest_neighbor] = 0
                node_neighbor_sets[node_b].remove(farthest_neighbor)
                adj_matrix[node_b][node_a] = 1
                node_neighbor_sets[node_b].add(node_a)

# 验证结果
print("每个节点的出度:", np.sum(adj_matrix, axis=1))
print("每个节点的入度:", np.sum(adj_matrix, axis=0))

关键细节说明

  1. 排序候选列表:预先生成按距离排序的邻居列表,确保我们始终按照距离优先级选择新邻居
  2. 集合存储邻居:用set来存储每个节点的邻居,能快速判断某个节点是否已被连接,提升调整效率
  3. 单向边处理逻辑:严格遵循你提出的优先级——先调整发起单向边的节点,只有当无法调整时才修改被连接节点的邻居,保证距离优先的原则

运行完代码后,你会得到一个无向的邻接矩阵,每个节点的入度和出度都会严格等于3,且所有连接都是双向的。

内容的提问来源于stack exchange,提问作者WhySoSerious

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.09 16:32:50