使用 igraph 库将数据的第一列作为源节点,第二列作为目标节点

本文介绍了如何使用 igraph 库将数据的第一列作为源节点,第二列作为目标节点来构建一个图形。代码示例展示了如何读取数据、构建节点映射、创建图形以及添加节点属性。

代码示例

#include <igraph/igraph.h>
#include <iostream>
#include <fstream>
#include <sstream>
#include <unordered_map>
#include <vector>

int main() {
    std::ifstream file("matrix.txt");
    std::string line;

    std::vector<int> edges;
    std::vector<double> weights;
    std::vector<std::string> node_names;

    std::unordered_map<std::string, int> node_map;
    int node_count = 0;

    while (std::getline(file, line)) {
        std::istringstream iss(line);
        std::string u, v;
        double w;

        if (!(iss >> u >> v >> w)) {
            break;  // error
        }

        if (node_map.find(u) == node_map.end()) {
            node_map[u] = node_count;
            node_names.push_back(u);
            node_count++;
        }

        if (node_map.find(v) == node_map.end()) {
            node_map[v] = node_count;
            node_names.push_back(v);
            node_count++;
        }

        edges.push_back(node_map[u]);
        edges.push_back(node_map[v]);
        weights.push_back(w);
    }

    igraph_t graph;
    igraph_set_attribute_table(&igraph_cattribute_table);
    igraph_empty(&graph, node_count, IGRAPH_UNDIRECTED); // Specify the number of vertices

    igraph_vector_int_t edge_vector;
    igraph_vector_int_init(&edge_vector, 0);

    for (auto &edge : edges) {
        igraph_vector_int_push_back(&edge_vector, node_map[node_names[edge]]);
    }

    igraph_strvector_t edge_strvector;
    igraph_vector_int_as_strvector(&edge_vector, &edge_strvector);
    igraph_add_edges(&graph, &edge_strvector, 0);

    igraph_vector_t weight_vector;
    igraph_vector_init(&weight_vector, 0);

    for (auto &weight : weights) {
        igraph_vector_push_back(&weight_vector, weight);
    }

    SETEANV(&graph, "weight", &weight_vector);

    for (size_t i = 0; i < node_names.size(); ++i) {
        SETVAS(&graph, "name", i, node_names[i].c_str());
    }

    FILE *outfile = fopen("gg.graphml", "w");
    igraph_write_graph_graphml(&graph, outfile, false);
    fclose(outfile);
    igraph_destroy(&graph);
    igraph_vector_int_destroy(&edge_vector);
    igraph_vector_destroy(&weight_vector);

    return 0;
}

代码解释

  1. 读取数据: 代码从 "matrix.txt" 文件中读取数据,每行包含三个值:源节点名称、目标节点名称和边权重。
  2. 构建节点映射: 代码使用 std::unordered_map 来存储节点名称和其对应的索引。
  3. 创建图形: 代码使用 igraph_empty 函数创建空图形,并指定节点数量。
  4. 添加边: 代码将数据的第一列作为源节点,第二列作为目标节点,并使用 igraph_add_edges 函数将边添加到图形中。
  5. 添加属性: 代码使用 SETEANV 函数添加边权重属性,使用 SETVAS 函数添加节点名称属性。
  6. 保存图形: 代码使用 igraph_write_graph_graphml 函数将图形保存为 GraphML 格式。

常见错误

  • 编译错误: "error: cannot convert ‘igraph_vector_t*’ to ‘const igraph_strvector_t*’" 这个问题是由于 igraph_add_edges 函数需要一个 igraph_strvector_t 类型的边向量。可以通过使用 igraph_vector_int_as_strvector 函数将 igraph_vector_int_t 转换为 igraph_strvector_t 来解决。
  • 段错误: "Segmentation fault" 错误通常是由于访问了无效内存导致的。例如,代码中使用 node_map[edge] 来获取节点索引,但是 edge 是一个整数,而 node_map 是一个 std::unordered_map,因此需要将 node_map[edge] 改为 node_map[node_names[edge]]

结论

本文介绍了如何使用 igraph 库将数据的第一列作为源节点,第二列作为目标节点来构建一个图形。代码示例提供了完整的解决方案,并解释了常见的错误以及解决方法。如果您在使用 igraph 库时遇到问题,请参考本文提供的代码和解释。

相关资源

  • igraph 库官方文档: https://igraph.org/c/doc/index.html
  • GraphML 格式文档: https://graphml.graphdrawing.org/specification.html

注意事项

  • 本文中的代码示例仅供参考,需要根据实际情况进行修改和调整。
  • 使用 igraph 库需要先安装该库。
  • 请确保您所使用的 igraph 库版本与代码示例中的版本一致。

希望本文能够帮助您解决问题,如果您还有其他问题,请随时提问。

igraph 图形库: 如何将数据的第一列作为源节点,第二列作为目标节点?

原文地址: https://www.cveoy.top/t/topic/fxOm 著作权归作者所有。请勿转载和采集!

免费AI点我,无需注册和登录