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

如何在AGE源码中创建GRAPH_global_context实现Barabási-Albert图生成

在AGE中使用GRAPH_global_context实现Barabási-Albert图生成

GRAPH_global_context是AGE中管理图全局状态的核心结构,它维护了顶点表、边表、哈希索引等元数据,所有需要访问顶点/边详细信息的操作(比如你提到的get_vertex_entry、get_vertex_entry_edges_out)都依赖它。以下是在图生成逻辑中正确创建和使用该结构的步骤:

1. 初始化GRAPH_global_context

首先需要调用AGE提供的初始化函数创建实例,这个函数会完成内部哈希表、锁资源的初始化:

#include "age_graph.h"

GRAPH_global_context *ggctx = init_graph_global_context();
if (!ggctx) {
    // 处理初始化失败(比如内存分配错误)
    return NULL;
}

2. 结合Barabási-Albert生成流程使用

Barabási-Albert图的核心是偏好依附规则,需要频繁获取现有顶点的边数,这正好依赖GRAPH_global_context提供的接口。以下是简化的生成逻辑框架:

步骤1:生成初始顶点集

先创建初始的m0个顶点,并将它们连接成完全图:

// 示例:初始3个顶点
graphid initial_vids[3];
for (int i = 0; i < 3; i++) {
    // create_vertex会自动将顶点注册到ggctx的顶点表中
    initial_vids[i] = create_vertex(ggctx, "BA_Vertex", NULL);
}

// 连接初始顶点为完全图
for (int i = 0; i < 3; i++) {
    for (int j = i + 1; j < 3; j++) {
        create_edge(ggctx, initial_vids[i], initial_vids[j], "Connects", NULL);
    }
}

步骤2:新增顶点并按偏好依附规则连接

对每个新增顶点,遍历现有顶点,通过get_vertex_entry和get_vertex_entry_edges_out获取顶点度数,计算连接概率:

const int total_nodes = 100; // 目标总顶点数
const int m = 2; // 每个新顶点连接2个现有顶点

// 维护现有顶点ID列表(也可通过ggctx遍历顶点表实现)
ListGraphId *existing_vids = list_graphid_create();
for (int i = 0; i < 3; i++) {
    list_graphid_append(existing_vids, initial_vids[i]);
}

for (int i = 3; i < total_nodes; i++) {
    graphid new_vid = create_vertex(ggctx, "BA_Vertex", NULL);
    list_graphid_append(existing_vids, new_vid);

    // 计算所有现有顶点的总度数
    int total_degree = 0;
    for (int k = 0; k < existing_vids->length - 1; k++) {
        vertex_entry *ve = get_vertex_entry(ggctx, existing_vids->elements[k]);
        ListGraphId *out_edges = get_vertex_entry_edges_out(ve);
        total_degree += out_edges->length;
        free_list_graphid(out_edges); // 释放临时列表
    }

    // 按偏好依附选择m个顶点连接
    int connected = 0;
    while (connected < m) {
        int rand_idx = rand() % (existing_vids->length - 1);
        graphid target_vid = existing_vids->elements[rand_idx];
        
        vertex_entry *target_ve = get_vertex_entry(ggctx, target_vid);
        ListGraphId *target_edges = get_vertex_entry_edges_out(target_ve);
        float attach_prob = (float)target_edges->length / total_degree;
        free_list_graphid(target_edges);

        // 随机判定是否连接
        if ((float)rand() / RAND_MAX < attach_prob) {
            create_edge(ggctx, new_vid, target_vid, "Connects", NULL);
            connected++;
        }
    }
}

free_list_graphid(existing_vids);

3. 清理资源

图生成完成后,必须调用清理函数释放GRAPH_global_context的所有资源,避免内存泄漏:

free_graph_global_context(ggctx);

关键注意事项

  • 生命周期一致性:所有依赖ggctx的操作(如get_vertex_entry、create_edge)必须在init_graph_global_context之后、free_graph_global_context之前执行。
  • 临时资源释放:调用get_vertex_entry_edges_out返回的ListGraphId必须用free_list_graphid手动释放,否则会造成内存泄漏。
  • PostgreSQL环境适配:如果是在PostgreSQL扩展中开发图生成函数,GRAPH_global_context通常由AGE的上层查询框架管理,无需手动初始化,但需要从查询上下文(如QueryDesc)中获取实例。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.23 05:47:32