For using the igraph C library
These functions can write a graph to a file, or read a graph from a file.
They assume that the current locale uses a decimal point and not
a decimal comma. See igraph_enter_safelocale()
and
igraph_exit_safelocale()
for more information.
Note that as igraph uses the traditional C streams, it is possible to read/write files from/to memory, at least on GNU operating systems supporting “non-standard” streams.
igraph_read_graph_edgelist
— Reads an edge list from a file and creates a graph.igraph_write_graph_edgelist
— Writes the edge list of a graph to a file.igraph_read_graph_ncol
— Reads an .ncol
file used by LGL.igraph_write_graph_ncol
— Writes the graph to a file in .ncol
format.igraph_read_graph_lgl
— Reads a graph from an .lgl
file.igraph_write_graph_lgl
— Writes the graph to a file in .lgl
format.igraph_read_graph_dimacs_flow
— Read a graph in DIMACS format.igraph_write_graph_dimacs_flow
— Write a graph in DIMACS format.
igraph_error_t igraph_read_graph_edgelist(igraph_t *graph, FILE *instream, igraph_integer_t n, igraph_bool_t directed);
This format is simply a series of an even number of non-negative integers separated by whitespace. The integers represent vertex IDs. Placing each edge (i.e. pair of integers) on a separate line is not required, but it is recommended for readability. Edges of directed graphs are assumed to be in "from, to" order.
The largest vertex ID plus one, or the parameter n
determines the vertex count,
whichever is larger. See igraph_read_graph_ncol()
for reading files where
vertices are specified by name instead of by a numerical vertex ID.
Arguments:
|
Pointer to an uninitialized graph object. |
|
Pointer to a stream, it should be readable. |
|
The number of vertices in the graph. If smaller than the largest integer in the file it will be ignored. It is thus safe to supply zero here. |
|
Logical, if true the graph is directed, if false it will be undirected. |
Returns:
Error code:
|
Time complexity: O(|V|+|E|), the number of vertices plus the number of edges. It is assumed that reading an integer requires O(1) time.
igraph_error_t igraph_write_graph_edgelist(const igraph_t *graph, FILE *outstream);
Edges are represented as pairs of 0-based vertex indices. One edge is written per line, separated by a single space. For directed graphs edges are written in from, to order.
Arguments:
|
The graph object to write. |
|
Pointer to a stream, it should be writable. |
Returns:
Error code:
|
Time complexity: O(|E|), the number of edges in the graph. It is assumed that writing an integer to the file requires O(1) time.
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);
Also useful for creating graphs from “named” (and optionally weighted) edge lists.
This format is used by the Large Graph Layout program (https://lgl.sourceforge.net), and it is simply a symbolic weighted edge list. It is a simple text file with one edge per line. An edge is defined by two symbolic vertex names separated by whitespace. The vertex names themselves cannot contain whitespace. They may be followed by an optional number, the weight of the edge; the number can be negative and can be in scientific notation. If there is no weight specified to an edge it is assumed to be zero.
The resulting graph is always undirected. LGL cannot deal with files which contain multiple or loop edges, this is however not checked here, as igraph is happy with these.
Arguments:
|
Pointer to an uninitialized graph object. |
|
Pointer to a stream, it should be readable. |
|
Pointer to the symbolic names of the vertices in
the file. If |
|
Logical value, if |
|
Whether to add the weights of the edges to the
graph as an edge attribute called “weight”.
|
|
Whether to create a directed graph. As this format
was originally used only for undirected graphs there is no
information in the file about the directedness of the graph.
Set this parameter to |
Returns:
Error code:
|
Time complexity: O(|V|+|E|log(|V|)) if we neglect the time required by the parsing. As usual |V| is the number of vertices, while |E| is the number of edges.
See also:
igraph_error_t igraph_write_graph_ncol(const igraph_t *graph, FILE *outstream, const char *names, const char *weights);
.ncol
is a format used by LGL, see igraph_read_graph_ncol()
for details.
Note that having multiple or loop edges in an
.ncol
file breaks the LGL software but
igraph does not check for this condition.
This format cannot represent zero-degree vertices.
Arguments:
|
The graph to write. |
|
The stream object to write to, it should be writable. |
|
The name of a string vertex attribute, if symbolic names
are to be written to the file. Supply |
|
The name of a numerical edge attribute, which will be
written as weights to the file. Supply |
Returns:
Error code:
|
Time complexity: O(|E|), the number of edges. All file operations are expected to have time complexity O(1).
See also:
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);
The .lgl
format is used by the Large Graph
Layout visualization software
(https://lgl.sourceforge.net), it can
describe undirected optionally weighted graphs. From the LGL
manual:
The second format is the LGL file format (
.lgl
file suffix). This is yet another graph file format that tries to be as stingy as possible with space, yet keeping the edge file in a human readable (not binary) format. The format itself is like the following:# vertex1name vertex2name [optionalWeight] vertex3name [optionalWeight]Here, the first vertex of an edge is preceded with a pound sign '#'. Then each vertex that shares an edge with that vertex is listed one per line on subsequent lines.
LGL cannot handle loop and multiple edges or directed graphs, but in igraph it is not an error to have multiple and loop edges.
Arguments:
|
Pointer to an uninitialized graph object. |
|
A stream, it should be readable. |
|
Logical value, if |
|
Whether to add the weights of the edges to the
graph as an edge attribute called “weight”.
|
|
Whether to create a directed graph. As this format
was originally used only for undirected graphs there is no
information in the file about the directedness of the graph.
Set this parameter to |
Returns:
Error code:
|
Time complexity: O(|V|+|E|log(|V|)) if we neglect the time required by the parsing. As usual |V| is the number of vertices, while |E| is the number of edges.
See also:
Example 21.1. File 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
is a format used by LGL, see igraph_read_graph_lgl()
for details.
Note that having multiple or loop edges in an
.lgl
file breaks the LGL software but igraph
does not check for this condition.
Arguments:
|
The graph to write. |
|
The stream object to write to, it should be writable. |
|
The name of a string vertex attribute, if symbolic names
are to be written to the file. Supply |
|
The name of a numerical edge attribute, which will be
written as weights to the file. Supply |
|
Logical, if |
Returns:
Error code:
|
Time complexity: O(|E|), the number of edges if isolates
is false
,
O(|V|+|E|) otherwise. All file operations are expected to have
time complexity O(1).
See also:
Example 21.2. File 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);
This function reads the DIMACS file format, more specifically the version for network flow problems, see the files at http://archive.dimacs.rutgers.edu/pub/netflow/general-info/
This is a line-oriented text file (ASCII) format. The first
character of each line defines the type of the line. If the first
character is c
the line is a comment line and it is
ignored. There is one problem line (p
in the file), it
must appear before any node and arc descriptor lines. The problem
line has three fields separated by spaces: the problem type
(max
or edge
), the number of vertices,
and number of edges in the graph. In MAX problems,
exactly two node identification lines are expected
(n
), one for the source, and one for the target vertex.
These have two fields: the ID of the vertex and the type of the
vertex, either s
( = source) or t
( = target).
Arc lines start with a
and have three fields: the source vertex,
the target vertex and the edge capacity. In EDGE problems,
there may be a node line (n
) for each node. It specifies the
node index and an integer node label. Nodes for which no explicit
label was specified will use their index as label. In EDGE problems,
each edge is specified as an edge line (e
).
Within DIMACS files, vertex IDs are numbered from 1.
Arguments:
|
Pointer to an uninitialized graph object. |
|
The file to read from. |
|
If not |
|
If not |
|
Pointer to an integer, the ID of the source node will
be stored here. (The igraph vertex ID, which is one less than
the actual number in the file.) It is ignored if |
|
Pointer to an integer, the (igraph) ID of the target
node will be stored here. It is ignored if |
|
Pointer to an initialized vector, the capacity of the edges will be stored here if not \ NULL. |
|
Boolean, whether to create a directed graph. |
Returns:
Error code. |
Time complexity: O(|V|+|E|+c), the number of vertices plus the number of edges, plus the size of the file in characters.
See also:
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);
This function writes a graph to an output stream in DIMACS format, describing a maximum flow problem. See ftp://dimacs.rutgers.edu/pub/netflow/general-info/
This file format is discussed in the documentation of igraph_read_graph_dimacs_flow()
, see that for more information.
Arguments:
|
The graph to write to the stream. |
|
The stream. |
|
Integer, the id of the source vertex for the maximum flow. |
|
Integer, the id of the target vertex. |
|
Pointer to an initialized vector containing the edge capacity values. |
Returns:
Error code. |
Time complexity: O(|E|), the number of edges in the graph.
See also:
igraph_error_t igraph_read_graph_graphdb(igraph_t *graph, FILE *instream, igraph_bool_t directed);
This is a binary format, used in the ARG Graph Database for isomorphism testing. For more information, see https://mivia.unisa.it/datasets/graph-database/arg-database/
From the graph database homepage:
The graphs are stored in a compact binary format, one graph per file. The file is composed of 16 bit words, which are represented using the so-called little-endian convention, i.e. the least significant byte of the word is stored first.
Then, for each node, the file contains the list of edges coming out of the node itself. The list is represented by a word encoding its length, followed by a word for each edge, representing the destination node of the edge. Node numeration is 0-based, so the first node of the graph has index 0.
As of igraph 0.10, only unlabelled graphs are implemented.
Arguments:
|
Pointer to an uninitialized graph object. |
|
The stream to read from. It should be opened in binary mode. |
|
Whether to create a directed graph. |
Returns:
Error code. |
Time complexity: O(|V|+|E|), the number of vertices plus the number of edges.
Example 21.3. File 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 is an XML-based file format for representing various types of
graphs. Currently only the most basic import functionality is implemented
in igraph: it can read GraphML files without nested graphs and hyperedges.
Attributes of the graph are loaded only if an attribute interface
is attached, see igraph_set_attribute_table()
. String attrribute values
are returned in UTF-8 encoding.
Graph attribute names are taken from the attr.name
attributes of the
key
tags in the GraphML file. Since attr.name
is not mandatory,
igraph will fall back to the id
attribute of the key
tag if
attr.name
is missing.
Arguments:
|
Pointer to an uninitialized graph object. |
|
A stream, it should be readable. |
|
If the GraphML file contains more than one graph, the one specified by this index will be loaded. Indices start from zero, so supply zero here if your GraphML file contains only a single graph. |
Returns:
Error code:
|
Example 21.4. File 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 is an XML-based file format for representing various types of graphs. See the GraphML Primer (http://graphml.graphdrawing.org/primer/graphml-primer.html) for detailed format description.
When a numerical attribute value is NaN, it will be omitted from the file.
This function assumes that non-ASCII characters in attribute names and string attribute values are UTF-8 encoded. If this is not the case, the resulting XML file will be invalid.
Arguments:
|
The graph to write. |
|
The stream object to write to, it should be writable. |
|
Logical value, whether to put a prefix in front of the attribute names to ensure uniqueness if the graph has vertex and edge (or graph) attributes with the same name. |
Returns:
Error code:
|
Time complexity: O(|V|+|E|) otherwise. All file operations are expected to have time complexity O(1).
Example 21.5. File 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 is a simple textual format, see https://web.archive.org/web/20190207140002/http://www.fim.uni-passau.de/index.php?id=17297%26L=1 for details.
Although all syntactically correct GML can be parsed, we implement only a subset of this format. Some attributes might be ignored. Here is a list of all the differences:
Only attributes with a simple type are used: integer, real or
string. If an attribute is composite, i.e. an array or a record,
then it is ignored. When some values of the attribute are simple and
some compound, the composite ones are replaced with a default value
(NaN for numeric, ""
for string).
comment
fields are not ignored. They are treated as any
other field and converted to attributes.
Top level attributes except for Version
and the
first graph
attribute are completely ignored.
There is no maximum line length or maximum keyword length.
Only the quot
, amp
, apos
, lt
and gt
character entities
are supported. Any other entity is passed through unchanged by the reader
after issuing a warning, and is expected to be decoded by the user.
We allow inf
, -inf
and nan
(not a number) as a real number. This is case insensitive, so
nan
, NaN
and NAN
are equivalent.
Please contact us if you cannot live with these limitations of the GML parser.
Arguments:
|
Pointer to an uninitialized graph object. |
|
The stream to read the GML file from. |
Returns:
Error code. |
Time complexity: should be proportional to the length of the file.
See also:
|
Example 21.6. File 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 is a quite general textual format, see https://web.archive.org/web/20190207140002/http://www.fim.uni-passau.de/index.php?id=17297%26L=1 for details.
The graph, vertex and edges attributes are written to the
file as well, if they are numeric or string. Boolean attributes are converted
to numeric, with 0 and 1 used for false and true, respectively.
NaN values of numeric attributes are skipped, as NaN is not part of the GML
specification and other software may not be able to read files containing them.
This is consistent with igraph_read_graph_gml()
, which produces NaN
when an attribute value is missing. In contrast with NaN, infinite values
are retained. Ensure that none of the numeric attributes values are infinite
to produce a conformant GML file that can be read by other software.
As igraph is more forgiving about attribute names, it might be necessary to simplify the them before writing to the GML file. This way we'll have a syntactically correct GML file. The following simple procedure is performed on each attribute name: first the alphanumeric characters are extracted, the others are ignored. Then if the first character is not a letter then the attribute name is prefixed with “igraph”. Note that this might result identical names for two attributes, igraph does not check this.
The “id” vertex attribute is treated specially.
If the id
argument is not NULL
then it should be a numeric
vector with the vertex IDs and the “id” vertex attribute is
ignored (if there is one). If id
is NULL
and there is a
numeric “id” vertex attribute, it will be used instead. If ids
are not specified in either way then the regular igraph vertex IDs are used.
If some of the supplied id values are invalid (non-integer or NaN), all supplied
id are ignored and igraph vertex IDs are used instead.
Note that whichever way vertex IDs are specified, their uniqueness is not checked.
If the graph has edge attributes that become “source” or “target” after encoding, or the graph has an attribute that becomes “directed”, they will be ignored with a warning. GML uses these attributes to specify the edge endpoints, and the graph directedness, so we cannot write them to the file. Rename them before calling this function if you want to preserve them.
Arguments:
|
The graph to write to the stream. |
||||||
|
The stream to write the file to. |
||||||
|
Set of
|
||||||
|
Either |
||||||
|
An optional string to write to the stream in the creator line.
If |
Returns:
Error code. |
Time complexity: should be proportional to the number of characters written to the file.
See also:
|
Example 21.7. File 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);
Only a subset of the Pajek format is implemented. This is partially because there is no formal specification for this format, but also because igraph does not support some Pajek features, like mixed graphs.
Starting from version 0.6.1 igraph reads bipartite (two-mode)
graphs from Pajek files and adds the type
Boolean vertex attribute for
them. Warnings are given for invalid edges, i.e. edges connecting
vertices of the same type.
The list of the current limitations:
Only .net
files are supported, Pajek
project files (.paj
) are not.
Temporal networks (i.e. with time events) are not supported.
Graphs with both directed and non-directed edges are not supported, as they cannot be represented in igraph.
Only Pajek networks are supported; permutations, hierarchies, clusters and vectors are not.
Multi-relational networks (i.e. networks with multiple edge types) are not supported.
Unicode characters encoded as &#dddd;
, or newlines
encoded as \n
will not be decoded.
If an attribute handler is installed,
igraph also reads the vertex and edge attributes
from the file. Most attributes are renamed to be more informative:
color
instead of c
, xfact
instead of x_fact
,
yfact
instead of y_fact, labeldist
instead of lr
,
labeldegree2
instead of lphi
, framewidth
instead of bw
,
fontsize
instead of fos
, rotation
instead of phi
,
radius
instead of r
, diamondratio
instead of q
,
labeldegree
instead of la
,
color
instead of ic
, framecolor
instead of bc
,
labelcolor
instead of lc
; these belong to vertices.
Edge attributes are also renamed, s
to arrowsize
,
w
to edgewidth
, h1
to hook1
, h2
to hook2
,
a1
to angle1
, a2
to angle2
, k1
to
velocity1
, k2
to velocity2
, ap
to arrowpos
,
lp
to labelpos
, lr
to labelangle
,
lphi
to labelangle2
, la
to labeldegree
,
fos
to fontsize
, a
to arrowtype
, p
to linepattern
,
l
to label
, lc
to labelcolor
, c
to color
.
Unknown vertex or edge parameters are read as string vertex
or edge attributes. If the parameter name conflicts with one
the standard attribute names mentioned above, a _
character is appended to it to avoid conflict.
In addition the following vertex attributes might be added: name
is added
(with the same value) if there are vertex IDs in the file.
x
and y
, and potentially z
are also added if there are vertex
coordinates in the file.
The weight
edge attribute will be added if there are edge weights present.
See the Pajek homepage: http://vlado.fmf.uni-lj.si/pub/networks/pajek/ for more info on Pajek. The Pajek manual, http://vlado.fmf.uni-lj.si/pub/networks/pajek/doc/pajekman.pdf, and http://mrvar.fdv.uni-lj.si/pajek/DrawEPS.htm have information on the Pajek file format. There is additional useful information and sample files at http://mrvar.fdv.uni-lj.si/pajek/history.htm
Arguments:
|
Pointer to an uninitialized graph object. |
|
An already opened file handler. |
Returns:
Error code. |
Time complexity: O(|V|+|E|+|A|), |V| is the number of vertices, |E| the number of edges, |A| the number of attributes (vertex + edge) in the graph if there are attribute handlers installed.
See also:
|
Example 21.8. File 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);
Writes files in the native format of the Pajek software. This format is not recommended for data exchange or archival. It is meant solely for interoperability with Pajek.
The Pajek vertex and edge parameters (like color) are determined by
the attributes of the vertices and edges. Of course this requires
an attribute handler to be installed. The names of the
corresponding vertex and edge attributes are listed at igraph_read_graph_pajek()
, e.g. the color
vertex attributes
determines the color (c
in Pajek) parameter.
Vertex and edge attributes that do not correspond to any documented Pajek parameter are discarded.
As of version 0.6.1 igraph writes bipartite graphs into Pajek files correctly, i.e. they will be also bipartite when read into Pajek. As Pajek is less flexible for bipartite graphs (the numeric IDs of the vertices must be sorted according to vertex type), igraph might need to reorder the vertices when writing a bipartite Pajek file. This effectively means that numeric vertex IDs usually change when a bipartite graph is written to a Pajek file, and then read back into igraph.
Early versions of Pajek supported only Windows-style line endings
in Pajek files, but recent versions support both Windows and Unix
line endings. igraph therefore uses the platform-native line endings
when the input file is opened in text mode, and uses Unix-style
line endings when the input file is opened in binary mode. If you
are using an old version of Pajek, you are on Unix and you are having
problems reading files written by igraph on a Windows machine, convert the
line endings manually with a text editor or with unix2dos
or iconv
from the command line).
Pajek will only interpret UTF-8 encoded files if they contain a byte-order mark (BOM) at the beginning. igraph is agnostic of string attribute encodings and therefore it will never write a BOM. You need to add this manually if/when necessary.
Arguments:
|
The graph object to write. |
|
The file to write to. It should be opened and writable. |
Returns:
Error code. |
Time complexity: O(|V|+|E|+|A|), |V| is the number of vertices, |E| is the number of edges, |A| the number of attributes (vertex + edge) in the graph if there are attribute handlers installed.
See also:
|
Example 21.9. File 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, "name", &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);
This is a simple textual file format used by UCINET. See http://www.analytictech.com/networks/dataentry.htm for examples. All the forms described here are supported by igraph. Vertex names and edge weights are also supported and they are added as attributes. (If an attribute handler is attached.)
Note the specification does not mention whether the
format is case sensitive or not. For igraph DL files are case
sensitive, i.e. Larry
and larry
are not the same.
Arguments:
|
Pointer to an uninitialized graph object. |
|
The stream to read the DL file from. |
|
Boolean, whether to create a directed file. |
Returns:
Error code. |
Time complexity: linear in terms of the number of edges and vertices, except for the matrix format, which is quadratic in the number of vertices.
Example 21.10. File 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 is the format used by the widely known GraphViz software, see http://www.graphviz.org for details. The grammar of the DOT format can be found here: http://www.graphviz.org/doc/info/lang.html
This is only a preliminary implementation, no visualization information is written.
This format is meant solely for interoperability with Graphviz. It is not recommended for data exchange or archival.
Arguments:
|
The graph to write to the stream. |
|
The stream to write the file to. |
Time complexity: should be proportional to the number of characters written to the file.
See also:
|
Example 21.11. File 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);
This function writes a graph to an output stream in LEDA format. See http://www.algorithmic-solutions.info/leda_guide/graphs/leda_native_graph_fileformat.html
The support for the LEDA format is very basic at the moment; igraph writes only the LEDA graph section which supports one selected vertex and edge attribute and no layout information or visual attributes.
Arguments:
|
The graph to write to the stream. |
|
The stream. |
|
The name of the vertex attribute whose values
are to be stored in the output, or |
|
The name of the edge attribute whose values
are to be stored in the output, or |
Returns:
Error code. |
Time complexity: O(|V|+|E|), the number of vertices and edges in the graph.
igraph_error_t igraph_enter_safelocale(igraph_safelocale_t *loc);
This function is experimental and its signature is not considered final yet. We reserve the right to change the function signature without changing the major version of igraph. Use it at your own risk.
igraph's foreign format readers and writers require a locale that uses a
decimal point instead of a decimal comma. This is a convenience function
that temporarily sets the C locale so that readers and writers would work
correctly. It must be paired with a call to igraph_exit_safelocale()
,
otherwise a memory leak will occur.
This function tries to set the locale for the current thread only on a
best-effort basis. Restricting the locale change to a single thread is not
supported on all platforms. In these cases, this function falls back to using
the standard setlocale()
function, which affects the entire process
and is not safe to use from concurrent threads.
It is generally recommended to run igraph within a thread that has been permanently set to the C locale using system-specific means. This is a convenience function for situations when this is not easily possible because the programmer is not in control of the process, such as when developing plugins/extensions. Note that processes start up in the C locale by default, thus nothing needs to be done unless the locale has been changed away from the default.
Arguments:
|
Pointer to a variable of type |
Returns:
Error code. |
Example 21.12. File 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);
This function is experimental and its signature is not considered final yet. We reserve the right to change the function signature without changing the major version of igraph. Use it at your own risk.
Restores a locale saved by igraph_enter_safelocale()
and deallocates
all associated data. This function must be paired with a call to
igraph_enter_safelocale()
.
Arguments:
|
A variable of type |
← Chapter 20. Generating layouts for graph drawing | Chapter 22. Maximum flows, minimum cuts and related measures → |