用于使用 igraph C 库
这些函数可以将图写入文件,或从文件读取图。
它们假设当前区域设置使用小数点而不是十进制逗号。 有关更多信息,请参见 igraph_enter_safelocale() 和 igraph_exit_safelocale()。
请注意,由于 igraph 使用传统的 C 流,因此可以从内存读取/写入文件,至少在支持 “非标准” 流的 GNU 操作系统上是这样。
igraph_read_graph_edgelist — 从文件读取边列表并创建图。igraph_write_graph_edgelist — 将图的边列表写入文件。igraph_read_graph_ncol — 读取 LGL 使用的 .ncol 文件。igraph_write_graph_ncol — 以 .ncol 格式将图写入文件。igraph_read_graph_lgl — 从 .lgl 文件读取图。igraph_write_graph_lgl — 以 .lgl 格式将图写入文件。igraph_read_graph_dimacs_flow — 以 DIMACS 格式读取图。igraph_write_graph_dimacs_flow — 以 DIMACS 格式写入图。
igraph_error_t igraph_read_graph_edgelist(igraph_t *graph, FILE *instream,
igraph_integer_t n, igraph_bool_t directed);
此格式只是一系列由空格分隔的偶数个非负整数。 这些整数表示顶点 ID。 不要求将每条边(即整数对)放在单独的一行上,但建议这样做以提高可读性。 有向图的边假定为“从,到”顺序。
最大顶点 ID 加一,或者参数 n 确定顶点计数,以较大者为准。 有关读取顶点通过名称而不是数字顶点 ID 指定的文件,请参见 igraph_read_graph_ncol()。
参数:
|
指向未初始化的图对象的指针。 |
|
指向流的指针,它应该是可读的。 |
|
图中的顶点数。 如果小于文件中的最大整数,则将被忽略。 因此,在此处提供零是安全的。 |
|
如果为 true,则图是有向的,如果为 false,则将是无向的。 |
返回值:
错误代码: |
时间复杂度: O(|V|+|E|),顶点数加边数。 假设读取一个整数需要 O(1) 时间。
igraph_error_t igraph_write_graph_edgelist(const igraph_t *graph, FILE *outstream);
边表示为基于 0 的顶点索引对。 每行写入一条边,用单个空格分隔。 对于有向图,边以“从,到”顺序写入。
参数:
|
要写入的图对象。 |
|
指向流的指针,它应该是可写的。 |
返回值:
错误代码: 如果写入文件时出现错误,则为 |
时间复杂度: O(|E|),图中的边数。 假设将整数写入文件需要 O(1) 时间。
igraph_error_t igraph_read_graph_ncol(igraph_t *graph, FILE *instream,
const igraph_strvector_t *predefnames,
igraph_bool_t names,
igraph_add_weights_t weights,
igraph_bool_t directed);
对于从 “命名”(以及可选的加权)边列表创建图也很有用。
此格式由大型图布局程序使用(https://lgl.sourceforge.net),它只是一个符号加权边列表。 它是一个简单的文本文件,每行一条边。 边由两个由空格分隔的符号顶点名称定义。 顶点名称本身不能包含空格。 它们后面可以跟一个可选数字,即边的权重; 该数字可以为负数,也可以采用科学计数法。 如果没有为边指定权重,则假定为零。
生成的图始终是无向的。 LGL 无法处理包含多个或环边的文件,但此处不进行检查,因为 igraph 对此很满意。
参数:
|
指向未初始化的图对象的指针。 |
|
指向流的指针,它应该是可读的。 |
|
指向文件中顶点的符号名称的指针。 如果此处给出了 |
|
布尔值。 如果 |
|
是否将边的权重作为名为 “权重” 的边属性添加到图中。 |
|
是否创建有向图。 由于此格式最初仅用于无向图,因此文件中没有关于图的方向性的信息。 将此参数设置为 |
返回值:
错误代码: |
时间复杂度: 如果我们忽略解析所需的时间,则为 O(|V|+|E|log(|V|))。 像往常一样,|V| 是顶点数,而 |E| 是边数。
另请参阅:
igraph_error_t igraph_write_graph_ncol(const igraph_t *graph, FILE *outstream,
const char *names, const char *weights);
.ncol 是 LGL 使用的格式,有关详细信息,请参见 igraph_read_graph_ncol()。
请注意,在 .ncol 文件中具有多个或环边会破坏 LGL 软件,但 igraph 不会检查此条件。
此格式无法表示零度顶点。
参数:
|
要写入的图。 |
|
要写入的流对象,它应该是可写的。 |
|
字符串顶点属性的名称,如果要将符号名称写入文件。 提供 |
|
数值边属性的名称,它将作为权重写入文件。 提供 |
返回值:
错误代码: 如果写入文件时出现错误,则为 |
时间复杂度: O(|E|),边数。 预计所有文件操作的时间复杂度为 O(1)。
另请参阅:
igraph_error_t igraph_read_graph_lgl(igraph_t *graph, FILE *instream,
igraph_bool_t names,
igraph_add_weights_t weights,
igraph_bool_t directed);
.lgl 格式由大型图布局可视化软件使用(https://lgl.sourceforge.net),它可以描述可选加权无向图。 来自 LGL 手册
第二种格式是 LGL 文件格式(
.lgl文件后缀)。 这是另一种图文件格式,它试图尽可能吝啬空间,同时保持边文件采用人类可读(非二进制)格式。 格式本身如下# vertex1name vertex2name [optionalWeight] vertex3name [optionalWeight]在此,边的第一个顶点以井号 '#' 开头。 然后,与该顶点共享边的每个顶点都将在后续行中逐行列出。
LGL 无法处理环和多条边或有向图,但在 igraph 中,具有多条边和环边不是错误。
参数:
|
指向未初始化的图对象的指针。 |
|
一个流,它应该是可读的。 |
|
布尔值,如果 |
|
是否将边的权重作为名为 “权重” 的边属性添加到图中。 |
|
是否创建有向图。 由于此格式最初仅用于无向图,因此文件中没有关于图的方向性的信息。 将此参数设置为 |
返回值:
错误代码: |
时间复杂度: 如果我们忽略解析所需的时间,则为 O(|V|+|E|log(|V|))。 像往常一样,|V| 是顶点数,而 |E| 是边数。
另请参阅:
示例 21.1. 文件 examples/simple/igraph_read_graph_lgl.c
#include <igraph.h> int main(void) { igraph_t g; FILE *input; /* Turn on attribute handling. */ igraph_set_attribute_table(&igraph_cattribute_table); /* Without names and weights */ input = fopen("igraph_read_graph_lgl-1.lgl", "r"); if (!input) { return 1; } igraph_read_graph_lgl(&g, input, 0, IGRAPH_ADD_WEIGHTS_NO, 1); fclose(input); if (!igraph_is_directed(&g)) { return 2; } igraph_write_graph_edgelist(&g, stdout); igraph_destroy(&g); /* With names and weights */ input = fopen("igraph_read_graph_lgl-2.lgl", "r"); if (!input) { return 3; } igraph_read_graph_lgl(&g, input, 0, IGRAPH_ADD_WEIGHTS_NO, 1); fclose(input); if (!igraph_is_directed(&g)) { return 4; } igraph_write_graph_ncol(&g, stdout, 0, 0); igraph_destroy(&g); /* Same graph, but forcing undirected mode */ input = fopen("igraph_read_graph_lgl-2.lgl", "r"); igraph_read_graph_lgl(&g, input, 0, IGRAPH_ADD_WEIGHTS_NO, 0); fclose(input); if (igraph_is_directed(&g)) { return 5; } igraph_write_graph_ncol(&g, stdout, 0, 0); igraph_destroy(&g); /* Erroneous LGL file (empty vertex name) */ input = fopen("igraph_read_graph_lgl-3.lgl", "r"); if (!input) { return 6; } igraph_set_error_handler(igraph_error_handler_ignore); if (igraph_read_graph_lgl(&g, input, 0, IGRAPH_ADD_WEIGHTS_NO, 1) != IGRAPH_PARSEERROR) { return 7; } fclose(input); return 0; }
igraph_error_t igraph_write_graph_lgl(const igraph_t *graph, FILE *outstream,
const char *names, const char *weights,
igraph_bool_t isolates);
.lgl 是 LGL 使用的格式,有关详细信息,请参见 igraph_read_graph_lgl()。
请注意,在 .lgl 文件中具有多个或环边会破坏 LGL 软件,但 igraph 不会检查此条件。
参数:
|
要写入的图。 |
|
要写入的流对象,它应该是可写的。 |
|
字符串顶点属性的名称,如果要将符号名称写入文件。 提供 |
|
数值边属性的名称,它将作为权重写入文件。 提供 |
|
如果 |
返回值:
错误代码: 如果写入文件时出现错误,则为 |
时间复杂度: 如果 isolates 为 false,则为 O(|E|),否则为 O(|V|+|E|)。 预计所有文件操作的时间复杂度为 O(1)。
另请参阅:
示例 21.2. 文件 examples/simple/igraph_write_graph_lgl.c
#include <igraph.h> int main(void) { igraph_t graph; igraph_strvector_t names; igraph_vector_t weights; igraph_integer_t i; igraph_integer_t vcount, ecount; igraph_set_attribute_table(&igraph_cattribute_table); igraph_small(&graph, 7, IGRAPH_UNDIRECTED, 0,1, 1,3, 1,2, 2,0, 4,2, 3,4, -1); vcount = igraph_vcount(&graph); ecount = igraph_ecount(&graph); printf("Output without isolates:\n"); igraph_write_graph_lgl(&graph, stdout, /*names*/ NULL, /*weights*/ NULL, /*isolates*/ 0); printf("\nOutput with isolates:\n"); igraph_write_graph_lgl(&graph, stdout, /*names*/ NULL, /*weights*/ NULL, /*isolates*/ 1); printf("\nOutput vertex and edge labels:\n"); igraph_strvector_init(&names, vcount); for (i = 0; i < vcount; i++) { char str[2] = " "; /* initialize to ensure presence of null terminator */ str[0] = 'A' + i; igraph_strvector_set(&names, i, str); } SETVASV(&graph, "names", &names); igraph_vector_init_range(&weights, 1, ecount + 1); SETEANV(&graph, "weights", &weights); igraph_write_graph_lgl(&graph, stdout, "names", "weights", /*isolates*/ 0); igraph_strvector_destroy(&names); igraph_vector_destroy(&weights); igraph_destroy(&graph); return 0; }
igraph_error_t igraph_read_graph_dimacs_flow(
igraph_t *graph, FILE *instream,
igraph_strvector_t *problem,
igraph_vector_int_t *label,
igraph_integer_t *source,
igraph_integer_t *target,
igraph_vector_t *capacity,
igraph_bool_t directed);
此函数读取 DIMACS 文件格式,更具体地说是用于网络流问题的版本,请参见 http://archive.dimacs.rutgers.edu/pub/netflow/general-info/ 中的文件
这是一个面向行的文本文件 (ASCII) 格式。 每行的第一个字符定义行的类型。 如果第一个字符是 c,则该行是注释行,将被忽略。 文件中有一个问题行(p),它必须出现在任何节点和弧描述符行之前。 问题行有三个字段,用空格分隔:问题类型(max 或 edge)、图中的顶点数和边数。 在 MAX 问题中,预计正好有两个节点标识行(n),一个用于源,一个用于目标顶点。 这些行有两个字段:顶点的 ID 和顶点的类型,可以是 s(= 源)或 t(= 目标)。 弧线以 a 开头,并有三个字段:源顶点、目标顶点和边容量。 在 EDGE 问题中,每个节点可能有一条节点线(n)。 它指定节点索引和整数节点标签。 没有明确指定标签的节点将使用其索引作为标签。 在 EDGE 问题中,每条边都指定为边线(e)。
在 DIMACS 文件中,顶点 ID 从 1 开始编号。
参数:
|
指向未初始化的图对象的指针。 |
|
要从中读取的文件。 |
|
如果不为 |
|
如果不为 |
|
指向整数的指针,源节点的 ID 将存储在此处。 (igraph 顶点 ID,比文件中的实际数字小一。) 如果 |
|
指向整数的指针,目标节点的(igraph)ID 将存储在此处。 如果 |
|
指向已初始化向量的指针,边的容量将存储在此处(如果不为 \ NULL)。 |
|
布尔值,是否创建有向图。 |
返回值:
错误代码。 |
时间复杂度: O(|V|+|E|+c),顶点数加边数,再加上文件中字符的大小。
另请参阅:
igraph_error_t igraph_write_graph_dimacs_flow(const igraph_t *graph, FILE *outstream,
igraph_integer_t source, igraph_integer_t target,
const igraph_vector_t *capacity);
此函数以 DIMACS 格式将图写入输出流,描述最大流问题。 请参见 ftp://dimacs.rutgers.edu/pub/netflow/general-info/
此文件格式在 igraph_read_graph_dimacs_flow() 的文档中讨论,有关更多信息,请参见该文档。
参数:
|
要写入流的图。 |
|
流。 |
|
整数,最大流的源顶点 ID。 |
|
整数,目标顶点的 ID。 |
|
指向包含边容量值的已初始化向量的指针。 |
返回值:
错误代码。 |
时间复杂度: O(|E|),图中的边数。
另请参阅:
igraph_error_t igraph_read_graph_graphdb(igraph_t *graph, FILE *instream,
igraph_bool_t directed);
这是一种二进制格式,用于 ARG 图数据库进行同构测试。 有关更多信息,请参见 https://mivia.unisa.it/datasets/graph-database/arg-database/
来自图数据库主页
图以紧凑的二进制格式存储,每个文件一张图。 该文件由 16 位字组成,这些字使用所谓的“小端”约定表示,即,字的最低有效字节首先存储。
然后,对于每个节点,文件包含从节点本身发出的边的列表。 该列表由一个对其长度进行编码的字表示,后跟每个边的字,表示边的目标节点。 节点编号是基于 0 的,因此图的第一个节点的索引为 0。
截至 igraph 0.10,仅实现了未标记的图。
参考
M. De Santo、P. Foggia、C. Sansone 和 M. Vento: 用于基准测试图同构算法的大型图数据库及其使用。 Pattern Recognition Letters,24(8),1067-1079 (2003)。 https://doi.org/10.1016/S0167-8655(02)00253-2
MIVIA ARG 数据集,https://zenodo.org/records/11204020, https://mivia.unisa.it/datasets/graph-database/arg-database/
参数:
|
指向未初始化的图对象的指针。 |
|
要从中读取的流。 它应该以二进制模式打开。 |
|
是否创建有向图。 |
返回值:
错误代码。 |
时间复杂度:O(|V|+|E|),顶点数加上边数。
示例 21.3. 文件 examples/simple/igraph_read_graph_graphdb.c
#include <igraph.h> int main(void) { igraph_t g; FILE *input; input = fopen("iso_b03_m1000.A00", "rb"); if (!input) { return 1; } igraph_read_graph_graphdb(&g, input, IGRAPH_DIRECTED); fclose(input); igraph_write_graph_edgelist(&g, stdout); igraph_destroy(&g); return 0; }
igraph_error_t igraph_read_graph_graphml(igraph_t *graph, FILE *instream, igraph_integer_t index);
GraphML 是一种基于 XML 的文件格式,用于表示各种类型的图。 目前,igraph 中仅实现了最基本的导入功能:它可以读取没有嵌套图和超边的 GraphML 文件。 仅当附加了属性接口时才会加载图的属性,请参见 igraph_set_attribute_table()。 字符串属性值以 UTF-8 编码返回。
图属性名称取自 GraphML 文件中 key 标记的 attr.name 属性。 由于 attr.name 不是强制性的,因此如果缺少 attr.name,igraph 将回退到 key 标记的 id 属性。
参数:
|
指向未初始化的图对象的指针。 |
|
一个流,它应该是可读的。 |
|
如果 GraphML 文件包含多个图,则将加载此索引指定的图。 索引从零开始,因此如果您的 GraphML 文件仅包含单个图,请在此处提供零。 |
返回值:
错误代码: |
示例 21.4. 文件 examples/simple/graphml.c
#include <igraph.h> #include <stdio.h> #include <unistd.h> /* unlink */ int main(void) { igraph_t graph; const char *infilename = "test.graphml"; const char *outfilename = "test2.graphml"; /* Set up attribute handling, so graph attributes can be imported * from the GraphML file. */ igraph_set_attribute_table(&igraph_cattribute_table); /* Problems in the GraphML file may cause igraph to print warnings. * If this is not desired, set a silent warning handler: */ igraph_set_warning_handler(&igraph_warning_handler_ignore); /* Read the contents of a GraphML file. */ /* GraphML */ FILE *infile = fopen("test.graphml", "r"); if (! infile) { fprintf(stderr, "Could not open input file '%s'.", infilename); exit(1); } /* GraphML support is an optional feature in igraph. If igraph was compiled * without GraphML support, igraph_read_graph_graphml() returns IGRAPH_UNIMPLEMENTED. * We temporarily disable the default error handler so we can test for this condition. */ igraph_error_handler_t *oldhandler = igraph_set_error_handler(igraph_error_handler_ignore); igraph_error_t ret = igraph_read_graph_graphml(&graph, infile, 0); if (ret == IGRAPH_UNIMPLEMENTED) { fprintf(stderr, "igraph was compiled without GraphML support."); exit(77); } if (ret != IGRAPH_SUCCESS) { fprintf(stderr, "Unexpected error while reading GraphML."); exit(1); } igraph_set_error_handler(oldhandler); fclose(infile); /* Write it back into another file. */ FILE *outfile = fopen(outfilename, "w"); if (outfile) { igraph_write_graph_graphml(&graph, outfile, true); fclose(outfile); /* Clean up after ourselves */ unlink(outfilename); } else { fprintf(stderr, "Could not write output file '%s'.", outfilename); } /* Destroy the graph */ igraph_destroy(&graph); return 0; }
igraph_error_t igraph_write_graph_graphml(const igraph_t *graph, FILE *outstream,
igraph_bool_t prefixattr);
GraphML 是一种基于 XML 的文件格式,用于表示各种类型的图。 有关详细的格式说明,请参见 GraphML 入门 (http://graphml.graphdrawing.org/primer/graphml-primer.html)。
当数值属性值为 NaN 时,将从文件中省略它。
此函数假定属性名称和字符串属性值中的非 ASCII 字符采用 UTF-8 编码。 如果不是这种情况,则生成的 XML 文件将无效。 不允许使用控制字符,即字符代码高达并包括 31(制表符、回车符和换行符除外)。
参数:
|
要写入的图。 |
|
要写入的流对象,它应该是可写的。 |
|
布尔值。 是否在属性名称前放置前缀,以确保如果图具有具有相同名称的顶点和边(或图)属性,则名称的唯一性。 |
返回值:
错误代码: 如果写入文件时出现错误,则为 |
时间复杂度: 否则为 O(|V|+|E|)。 预计所有文件操作的时间复杂度为 O(1)。
示例 21.5. 文件 examples/simple/graphml.c
#include <igraph.h> #include <stdio.h> #include <unistd.h> /* unlink */ int main(void) { igraph_t graph; const char *infilename = "test.graphml"; const char *outfilename = "test2.graphml"; /* Set up attribute handling, so graph attributes can be imported * from the GraphML file. */ igraph_set_attribute_table(&igraph_cattribute_table); /* Problems in the GraphML file may cause igraph to print warnings. * If this is not desired, set a silent warning handler: */ igraph_set_warning_handler(&igraph_warning_handler_ignore); /* Read the contents of a GraphML file. */ /* GraphML */ FILE *infile = fopen("test.graphml", "r"); if (! infile) { fprintf(stderr, "Could not open input file '%s'.", infilename); exit(1); } /* GraphML support is an optional feature in igraph. If igraph was compiled * without GraphML support, igraph_read_graph_graphml() returns IGRAPH_UNIMPLEMENTED. * We temporarily disable the default error handler so we can test for this condition. */ igraph_error_handler_t *oldhandler = igraph_set_error_handler(igraph_error_handler_ignore); igraph_error_t ret = igraph_read_graph_graphml(&graph, infile, 0); if (ret == IGRAPH_UNIMPLEMENTED) { fprintf(stderr, "igraph was compiled without GraphML support."); exit(77); } if (ret != IGRAPH_SUCCESS) { fprintf(stderr, "Unexpected error while reading GraphML."); exit(1); } igraph_set_error_handler(oldhandler); fclose(infile); /* Write it back into another file. */ FILE *outfile = fopen(outfilename, "w"); if (outfile) { igraph_write_graph_graphml(&graph, outfile, true); fclose(outfile); /* Clean up after ourselves */ unlink(outfilename); } else { fprintf(stderr, "Could not write output file '%s'.", outfilename); } /* Destroy the graph */ igraph_destroy(&graph); return 0; }
igraph_error_t igraph_read_graph_gml(igraph_t *graph, FILE *instream);
GML 是一种简单的文本格式,有关详细信息,请参见 https://web.archive.org/web/20190207140002/http://www.fim.uni-passau.de/index.php?id=17297%26L=1。
尽管可以解析所有在语法上正确的 GML,但我们仅实现了此格式的子集。 一些属性可能会被忽略。 这是所有差异的列表
仅使用具有简单类型的属性:整数、实数或字符串。 如果属性是复合的,即数组或记录,则将忽略它。 当属性的一些值为简单类型,而另一些为复合类型时,复合值将替换为默认值(数值为 NaN,字符串为 "")。
comment 字段不会被忽略。 它们被视为任何其他字段并转换为属性。
除了 Version 和第一个 graph 属性之外,顶层属性将被完全忽略。
没有最大行长度或最大关键字长度。
仅支持 quot、amp、apos、lt 和 gt 字符实体。 在发出警告后,任何其他实体都将由读取器不变地传递,并有望由用户解码。
我们允许 inf、-inf 和 nan(非数字)作为实数。 这不区分大小写,因此 nan、NaN 和 NAN 是等效的。
如果您无法忍受 GML 解析器的这些限制,请与我们联系。
参数:
|
指向未初始化的图对象的指针。 |
|
用于从中读取 GML 文件的流。 |
返回值:
错误代码。 |
时间复杂度: 应与文件的长度成正比。
另请参阅:
有关更现代的格式,请参见 |
示例 21.6. 文件 examples/simple/gml.c
#include <igraph.h> #include <stdio.h> int main(void) { igraph_t graph; FILE *ifile; ifile = fopen("karate.gml", "r"); if (ifile == 0) { return 1; } igraph_read_graph_gml(&graph, ifile); fclose(ifile); printf("The graph is %s.\n", igraph_is_directed(&graph) ? "directed" : "undirected"); /* Output as edge list */ printf("\n-----------------\n"); igraph_write_graph_edgelist(&graph, stdout); /* Output as GML */ printf("\n-----------------\n"); igraph_write_graph_gml(&graph, stdout,IGRAPH_WRITE_GML_DEFAULT_SW, 0, ""); igraph_destroy(&graph); return 0; }
igraph_error_t igraph_write_graph_gml(const igraph_t *graph, FILE *outstream,
igraph_write_gml_sw_t options,
const igraph_vector_t *id, const char *creator);
GML 是一种非常通用的文本格式,有关详细信息,请参见 https://web.archive.org/web/20190207140002/http://www.fim.uni-passau.de/index.php?id=17297%26L=1。
图、顶点和边属性也会写入文件,如果它们是数字或字符串。 布尔属性将转换为数字,其中 0 和 1 分别用于假和真。 数值属性的 NaN 值将被跳过,因为 NaN 不是 GML 规范的一部分,并且其他软件可能无法读取包含它们的文件。 这与 igraph_read_graph_gml() 一致,后者在缺少属性值时生成 NaN。 与 NaN 相比,无限值会被保留。 确保没有数值属性值为无限值以生成其他软件可以读取的符合 GML 的文件。
由于 igraph 对属性名称更加宽容,因此可能需要在写入 GML 文件之前简化它们。 这样,我们将有一个语法上正确的 GML 文件。 对每个属性名称执行以下简单过程:首先提取字母数字字符,其他字符将被忽略。 然后,如果第一个字符不是字母,则属性名称将带有前缀 “igraph”。 请注意,这可能会导致两个属性具有相同的名称,igraph 不会检查这一点。
“id” 顶点属性被特殊处理。 如果 id 参数不是 NULL,那么它应该是一个具有顶点 ID 的数值向量,并且 “id” 顶点属性将被忽略(如果存在)。 如果 id 是 NULL 并且存在数值 “id” 顶点属性,则将改用它。 如果未以任何方式指定 ID,则使用常规 igraph 顶点 ID。 如果提供的某些 ID 值无效(非整数或 NaN),则所有提供的 ID 将被忽略,并改用 igraph 顶点 ID。
请注意,无论以何种方式指定顶点 ID,都不会检查其唯一性。
如果图具有在编码后变为 “source” 或 “target” 的边属性,或者图具有变为 “directed” 的属性,则它们将被忽略并显示警告。 GML 使用这些属性来指定边端点和图的方向性,因此我们无法将它们写入文件。 如果要保留它们,请在调用此函数之前重命名它们。
参数:
|
要写入流的图。 |
||||||
|
用于将文件写入到的流。 |
||||||
|
用于写入 GML 文件的
|
||||||
|
可以是 |
||||||
|
一个可选字符串,用于写入到创建者行中的流。 如果 |
返回值:
错误代码。 |
时间复杂度: 应与写入文件的字符数成正比。
另请参阅:
有关读取 GML 文件,请参见 |
示例 21.7. 文件 examples/simple/gml.c
#include <igraph.h> #include <stdio.h> int main(void) { igraph_t graph; FILE *ifile; ifile = fopen("karate.gml", "r"); if (ifile == 0) { return 1; } igraph_read_graph_gml(&graph, ifile); fclose(ifile); printf("The graph is %s.\n", igraph_is_directed(&graph) ? "directed" : "undirected"); /* Output as edge list */ printf("\n-----------------\n"); igraph_write_graph_edgelist(&graph, stdout); /* Output as GML */ printf("\n-----------------\n"); igraph_write_graph_gml(&graph, stdout,IGRAPH_WRITE_GML_DEFAULT_SW, 0, ""); igraph_destroy(&graph); return 0; }
igraph_error_t igraph_read_graph_pajek(igraph_t *graph, FILE *instream);
仅实现了 Pajek 格式的一个子集。 这部分是因为此格式没有正式规范,但也因为 igraph 不支持某些 Pajek 功能,例如混合图。
从 0.6.1 版本开始,igraph 从 Pajek 文件中读取二分(双模)图,并为其添加 type 布尔顶点属性。 对于无效边,即连接相同类型的顶点的边,会发出警告。
当前限制列表
仅支持 .net 文件,不支持 Pajek 项目文件 (.paj)。
不支持时间网络(即具有时间事件的网络)。
不支持同时具有有向边和非有向边的图,因为它们无法在 igraph 中表示。
仅支持 Pajek 网络; 不支持排列、层次结构、集群和向量。
不支持多关系网络(即具有多个边类型的网络)。
不会解码编码为 &#dddd; 的 Unicode 字符或编码为 \n 的换行符。
如果安装了属性处理程序,则 igraph 还会从文件中读取顶点和边属性。 大多数属性都已重命名,以使其更具信息性:color 而不是 c、xfact 而不是 x_fact、yfact 而不是 y_fact、labeldist 而不是 lr、labeldegree2 而不是 lphi、framewidth 而不是 bw、fontsize 而不是 fos、rotation 而不是 phi、radius 而不是 r、diamondratio 而不是 q、labeldegree 而不是 la、color 而不是 ic、framecolor 而不是 bc、labelcolor 而不是 lc; 这些属于顶点。
边的属性也被重命名,s 改为 arrowsize,w 改为 edgewidth,h1 改为 hook1,h2 改为 hook2,a1 改为 angle1,a2 改为 angle2,k1 改为 velocity1,k2 改为 velocity2,ap 改为 arrowpos,lp 改为 labelpos,lr 改为 labelangle,lphi 改为 labelangle2,la 改为 labeldegree,fos 改为 fontsize,a 改为 arrowtype,p 改为 linepattern,l 改为 label,lc 改为 labelcolor,c 改为 color。
未知的顶点或边的参数会被读取为字符串类型的顶点或边属性。如果参数名称与上述标准属性名称冲突,则会在其后附加一个 _ 字符以避免冲突。
此外,可能会添加以下顶点属性:如果文件中存在顶点 ID,则会添加 id 和 name(具有相同的值)。id 已被弃用,推荐使用 name,未来版本的 igraph 将不再使用 id。如果文件中存在顶点坐标,则还会添加 x 和 y,以及可能的 z。
如果存在边的权重,则会添加 weight 边属性。
有关 Pajek 的更多信息,请参见 Pajek 主页:http://vlado.fmf.uni-lj.si/pub/networks/pajek/。Pajek 手册,http://vlado.fmf.uni-lj.si/pub/networks/pajek/doc/pajekman.pdf,以及 http://mrvar.fdv.uni-lj.si/pajek/DrawEPS.htm 包含有关 Pajek 文件格式的信息。在 http://mrvar.fdv.uni-lj.si/pajek/history.htm 上有更多有用的信息和示例文件
参数:
|
指向未初始化的图对象的指针。 |
|
一个已经打开的文件句柄。 |
返回值:
错误代码。 |
时间复杂度:O(|V|+|E|+|A|),|V| 是顶点数,|E| 是边数,|A| 是图中的属性数(顶点 + 边)(如果安装了属性处理程序)。
另请参阅:
用于写入 Pajek 文件的 |
示例 21.8. 文件 examples/simple/foreign.c
#include <igraph.h> #include <stdio.h> int main(void) { igraph_t g; FILE *ifile; /* Turn on attribute handling. */ igraph_set_attribute_table(&igraph_cattribute_table); /* Read a Pajek file. */ ifile = fopen("links.net", "r"); if (ifile == 0) { return 10; } igraph_read_graph_pajek(&g, ifile); fclose(ifile); /* Write it in edgelist format. */ printf("The graph:\n"); printf("Vertices: %" IGRAPH_PRId "\n", igraph_vcount(&g)); printf("Edges: %" IGRAPH_PRId "\n", igraph_ecount(&g)); printf("Directed: %i\n", igraph_is_directed(&g) ? 1 : 0); igraph_write_graph_edgelist(&g, stdout); igraph_destroy(&g); return 0; }
igraph_error_t igraph_write_graph_pajek(const igraph_t *graph, FILE *outstream);
以 Pajek 软件的本机格式写入文件。不建议将此格式用于数据交换或存档。它仅用于与 Pajek 的互操作性。
Pajek 顶点和边的参数(如颜色)由顶点和边的属性决定。当然,这需要安装属性处理程序。相应的顶点和边属性的名称在 igraph_read_graph_pajek() 中列出,例如,color 顶点属性决定颜色(Pajek 中的 c)参数。
与任何已记录的 Pajek 参数不对应的顶点和边属性将被丢弃。
从 0.6.1 版本开始,igraph 正确地将二分图写入 Pajek 文件,即,当读入 Pajek 时,它们也将是二分图。由于 Pajek 对于二分图的灵活性较低(顶点的数字 ID 必须按顶点类型排序),因此在写入二分 Pajek 文件时,igraph 可能需要重新排序顶点。这实际上意味着当二分图写入 Pajek 文件,然后读回 igraph 时,数字顶点 ID 通常会更改。
早期版本的 Pajek 仅支持 Pajek 文件中的 Windows 样式的行尾符,但最近的版本同时支持 Windows 和 Unix 行尾符。因此,当输入文件以文本模式打开时,igraph 使用平台本地行尾符,当输入文件以二进制模式打开时,使用 Unix 样式的行尾符。如果您使用的是旧版本的 Pajek,并且您在 Unix 上,并且在读取 igraph 在 Windows 机器上写入的文件时遇到问题,请使用文本编辑器或命令行中的 unix2dos 或 iconv 手动转换行尾符)。
Pajek 仅会在 UTF-8 编码的文件开头包含字节顺序标记 (BOM) 时才解释它们。igraph 不知道字符串属性编码,因此永远不会写入 BOM。如果/当需要时,您需要手动添加它。
参数:
|
要写入的图对象。 |
|
要写入的文件。它应该被打开并且可写。 |
返回值:
错误代码。 |
时间复杂度:O(|V|+|E|+|A|),|V| 是顶点数,|E| 是边数,|A| 是图中的属性数(顶点 + 边)(如果安装了属性处理程序)。
另请参阅:
用于读取 Pajek 图的 |
示例 21.9. 文件 examples/simple/igraph_write_graph_pajek.c
#include <igraph.h> int main(void) { igraph_t g; igraph_strvector_t names; igraph_set_attribute_table(&igraph_cattribute_table); /* save a simple ring graph */ igraph_ring(&g, 10, IGRAPH_DIRECTED, false /* mutual */, true /* circular */); igraph_write_graph_pajek(&g, stdout); /* add some vertex attributes */ igraph_strvector_init(&names, 0); igraph_strvector_push_back(&names, "A"); igraph_strvector_push_back(&names, "B"); igraph_strvector_push_back(&names, "C"); igraph_strvector_push_back(&names, "D"); igraph_strvector_push_back(&names, "E"); igraph_strvector_push_back(&names, "F"); igraph_strvector_push_back(&names, "G"); igraph_strvector_push_back(&names, "H"); igraph_strvector_push_back(&names, "I"); igraph_strvector_push_back(&names, "J"); SETVASV(&g, "id", &names); igraph_strvector_destroy(&names); /* save the graph with vertex names */ igraph_write_graph_pajek(&g, stdout); igraph_strvector_init(&names, 0); igraph_strvector_push_back(&names, "square"); igraph_strvector_push_back(&names, "square"); igraph_strvector_push_back(&names, "square"); igraph_strvector_push_back(&names, "square"); igraph_strvector_push_back(&names, "escaping spaces"); igraph_strvector_push_back(&names, "square"); igraph_strvector_push_back(&names, "square"); igraph_strvector_push_back(&names, "escaping\nnewline"); igraph_strvector_push_back(&names, "square"); igraph_strvector_push_back(&names, "encoding \"quotes\""); SETVASV(&g, "shape", &names); igraph_strvector_destroy(&names); /* save the graph with escaped shapes */ igraph_write_graph_pajek(&g, stdout); /* destroy the graph */ igraph_destroy(&g); return 0; }
igraph_error_t igraph_read_graph_dl(igraph_t *graph, FILE *instream,
igraph_bool_t directed);
这是 UCINET 使用的一种简单的文本文件格式。有关示例,请参见 http://www.analytictech.com/networks/dataentry.htm。igraph 支持此处描述的所有形式。还支持顶点名称和边权重,并将它们添加为属性。(如果附加了属性处理程序。)
请注意,规范没有提及该格式是否区分大小写。对于 igraph,DL 文件区分大小写,即 Larry 和 larry 不是同一个。
参数:
|
指向未初始化的图对象的指针。 |
|
从中读取 DL 文件的流。 |
|
布尔值,是否创建有向文件。 |
返回值:
错误代码。 |
时间复杂度:在边和顶点的数量方面是线性的,除了矩阵格式,它在顶点数量方面是二次的。
示例 21.10. 文件 examples/simple/igraph_read_graph_dl.c
#include <igraph.h> #include <stdio.h> #include <stdlib.h> int main(void) { const char *files[] = { "fullmatrix1.dl", "fullmatrix2.dl", "fullmatrix3.dl", "fullmatrix4.dl", "edgelist1.dl", "edgelist2.dl", "edgelist3.dl", "edgelist4.dl", "edgelist5.dl", "edgelist6.dl", "edgelist7.dl", "nodelist1.dl", "nodelist2.dl" }; igraph_t graph; FILE *infile; /* Turn on attribute handling. */ igraph_set_attribute_table(&igraph_cattribute_table); for (size_t i = 0; i < sizeof(files) / sizeof(files[0]); i++) { printf("Doing %s\n", files[i]); infile = fopen(files[i], "r"); if (!infile) { printf("Cannot open file: %s\n", files[i]); abort(); } igraph_read_graph_dl(&graph, infile, IGRAPH_DIRECTED); fclose(infile); igraph_write_graph_edgelist(&graph, stdout); igraph_destroy(&graph); } if (IGRAPH_FINALLY_STACK_SIZE() != 0) { return 1; } return 0; }
igraph_error_t igraph_write_graph_dot(const igraph_t *graph, FILE* outstream);
DOT 是广泛使用的 GraphViz 软件使用的格式,有关详细信息,请参见 https://graphviz.cn。DOT 格式的语法可以在这里找到:https://graphviz.cn/doc/info/lang.html
这只是一个初步实现,不会写入任何可视化信息。
此格式仅用于与 Graphviz 的互操作性。不建议将此格式用于数据交换或存档。
参数:
|
要写入流的图。 |
|
用于将文件写入到的流。 |
时间复杂度: 应与写入文件的字符数成正比。
另请参阅:
对于更现代的格式,请使用 |
示例 21.11. 文件 examples/simple/dot.c
#include <igraph.h> #include <stdio.h> int main(void) { igraph_t g; FILE *ifile; ifile = fopen("karate.gml", "r"); if (ifile == 0) { return 10; } igraph_read_graph_gml(&g, ifile); fclose(ifile); if (igraph_is_directed(&g)) { printf("directed\n"); } else { printf("undirected\n"); } igraph_write_graph_edgelist(&g, stdout); printf("-----------------\n"); igraph_write_graph_dot(&g, stdout); igraph_destroy(&g); return 0; }
igraph_error_t igraph_write_graph_leda(const igraph_t *graph, FILE *outstream,
const char *vertex_attr_name,
const char *edge_attr_name);
此函数以 LEDA 格式将图写入输出流。参见 http://www.algorithmic-solutions.info/leda_guide/graphs/leda_native_graph_fileformat.html
目前对 LEDA 格式的支持非常基本;igraph 仅写入 LEDA 图部分,该部分支持一个选定的顶点和边属性,并且没有布局信息或视觉属性。
参数:
|
要写入流的图。 |
|
流。 |
|
要将值存储在输出中的顶点属性的名称,如果没有顶点属性应该存储,则为 |
|
要将值存储在输出中的边属性的名称,如果没有边属性应该存储,则为 |
返回值:
错误代码。 |
时间复杂度:O(|V|+|E|),图中的顶点数和边数。
igraph_error_t igraph_enter_safelocale(igraph_safelocale_t *loc);
此函数是实验性的,其签名尚未被视为最终签名。我们保留更改函数签名的权利,而无需更改 igraph 的主要版本。使用它需要您自担风险。
igraph 的外部格式读取器和写入器需要使用小数点而不是逗号的区域设置。这是一个便利函数,用于临时设置 C 区域设置,以便读取器和写入器可以正常工作。它必须与对 igraph_exit_safelocale() 的调用配对,否则将发生内存泄漏。
此函数尝试仅在尽力而为的基础上为当前线程设置区域设置。并非所有平台都支持将区域设置更改限制为单个线程。在这些情况下,此函数会回退到使用标准的 setlocale() 函数,该函数会影响整个进程,并且从并发线程使用是不安全的。
通常建议在已使用特定于系统的方法永久设置为 C 区域设置的线程中运行 igraph。当由于程序员无法控制进程(例如,在开发插件/扩展时)而无法轻松实现时,这是一个便利函数。请注意,进程默认以 C 区域设置启动,因此除非区域设置已更改为非默认设置,否则无需执行任何操作。
参数:
|
指向类型为 |
返回值:
错误代码。 |
示例 21.12. 文件 examples/simple/safelocale.c
#include <igraph.h> #include <locale.h> #include <stdio.h> #include <string.h> int main(void) { const char *filename = "weighted.gml"; igraph_t graph; igraph_safelocale_t loc; /* Attempt to set a locale that uses a decimal comma. Locale names * differ between platforms, and not all locales are available, * so the locale change may not be successful. */ const char *locname = setlocale(LC_ALL, "de_DE"); struct lconv *lc = localeconv(); if (strcmp(lc->decimal_point, ",")) { /* If decimal point is not a comma, presumably because the requested * locale was not available, report locale information. */ fprintf(stderr, "setlocale() returned '%s', decimal point is '%s'\n", locname ? locname : "NULL", lc->decimal_point); } FILE *file = fopen(filename, "r"); if (! file) { fprintf(stderr, "Cannot open %s file.\n", filename); exit(1); } /* An attribute table is needed to read graph attributes. */ igraph_set_attribute_table(&igraph_cattribute_table); /* At this point, the current locale may use decimal commas. * We temporarily set a C locale using enter_safelocale() to * allow the GML reader and writer to work correctly.*/ igraph_enter_safelocale(&loc); if (igraph_read_graph_gml(&graph, file) != IGRAPH_SUCCESS) { fprintf(stderr, "Reading %s failed.\n", filename); abort(); } igraph_write_graph_gml(&graph, stdout, IGRAPH_WRITE_GML_DEFAULT_SW, NULL, ""); igraph_exit_safelocale(&loc); igraph_destroy(&graph); return 0; }
void igraph_exit_safelocale(igraph_safelocale_t *loc);
此函数是实验性的,其签名尚未被视为最终签名。我们保留更改函数签名的权利,而无需更改 igraph 的主要版本。使用它需要您自担风险。
恢复由 igraph_enter_safelocale() 保存的区域设置,并释放所有关联的数据。此函数必须与对 igraph_enter_safelocale() 的调用配对。
参数:
|
类型为 |
igraph_error_t igraph_read_graph_dimacs(igraph_t *graph, FILE *instream,
igraph_strvector_t *problem,
igraph_vector_int_t *label,
igraph_integer_t *source,
igraph_integer_t *target,
igraph_vector_t *capacity,
igraph_bool_t directed);
自 0.10.0 版本起已弃用。请不要在新代码中使用此函数;请改用 igraph_read_graph_dimacs_flow()。
igraph_error_t igraph_write_graph_dimacs(const igraph_t *graph, FILE *outstream,
igraph_integer_t source, igraph_integer_t target,
const igraph_vector_t *capacity);
自 0.10.0 版本起已弃用。请不要在新代码中使用此函数;请改用 igraph_write_graph_dimacs_flow()。
| ← 第 20. 章 图绘制的生成布局 | 第 22. 章 最大流、最小割及相关度量 → |