123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644 |
- /*!
- Temelia - Generic graph interface.
- This source file contains the implementation of the most known
- algorithms on graphs. Graph uses another layer consisting of the
- internal representation: adjacency matrix, adjacency list etc
- The representation can be user defined, see graph_matrix.h and
- graph_list.h for additional information.
- Copyright (C) 2008 Ceata (http://cod.ceata.org/proiecte/temelia).
- This program is free software; you can redistribute it and
- modify it under the terms of the GNU General Public License
- as published by the Free Software Foundation; either version 3
- of the License, or (at your option) any later version.
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
- #ifndef GRAPH_H_
- #define GRAPH_H_
- #include "common.h"
- #include "vertex.h"
- #include "edge.h"
- #include "linked_list.h"
- #include "vector.h"
- #include "matrix.h"
- /*!
- * @brief Common interface for graph implementation.
- * It contains pointers to functions; you may initialize
- * them with the values you want to hook in the library's
- * graph algorithms.
- *
- * Graph algorithms uses this interface to build generic
- * solution, instead of depending on the graph implementation.
- *
- * Temelia comes with two default implementations: adjacency matrix
- * and adjancency list. You can define your own implementation by
- * implementing the functions in this interface - look at
- * current solutions for details.
- *
- * The core concept is that at the upper layer I want to
- * work with unsigned int, instead of vertex_t; thus, the library
- * should automatically box/unbox unsigned int from/to vertex_t
- */
- struct _graph_implementation_t
- {
- // Returns an empty graph with given size
- void *(*new)(int size);
- // Frees the memory occupied by graph
- void (*delete)(void *graph);
- // Actualizes graph's size
- void (*resize)(void *graph, int size);
- /*!
- * @brief Loads source graph into destination graph.
- * The load operation should consists of edge references duplication.
- * Notice that this operation does not require any memory allocation.
- * @param Source graph
- * @param Destination graph
- */
- void (*load)(void *graph_src, void *graph_dest);
- /*!
- * @brief Duplicates source graph and returns the clone. In a common example,
- * the returned value, graph_dest, will be used to with load(graph_src, graph_dest).
- * @param Source graph
- */
- void *(*store)(void *graph_src);
- // Adds new edge to graph
- void (*add_edge)(void *graph, unsigned int vertex1, unsigned int vertex2,
- edge_t edge);
- // Removes edge from graph
- edge_t (*remove_edge)(void *graph, unsigned int vertex1,
- unsigned int vertex2);
- // Retrives the reference of edge from graph
- edge_t (*get_edge)(void *graph, unsigned int vertex1, unsigned int vertex2);
- // === [Start] Iterator over vertice's neighbors ===
- /*!
- * @brief Returns the first neighbor vertex of given vertex in graph
- * @param Graph implementation
- * @param Vertex
- * @param Pointer to context; here your implementation
- * may save a context (what's the current vertex, other references etc)
- */
- vertex_t (*first_vertex)(void *graph, unsigned int vertex, void **context);
- /*!
- * @brief Deteles the allocated context for iterating on neighbors;
- * you should call this function if you don't want full neighbors iterating.
- * At the end of iterating, next_vertex returns NULL, this function is automatically
- * called.
- * @param Context
- */
- void (*delete_vertex_context)(void **context);
- /*!
- * @brief Returns the next neighbor vertex of given vertex in graph
- * @param Graph implementation
- * @param Vertex
- * @param Pointer to context; information about the last visited
- * neighbor should be here and it may be actualized
- */
- vertex_t (*next_vertex)(void *graph, unsigned int vertex, void **context);
- // === [Stop] Iterator over vertice's neighbors ===
- // === [Start] Iterator over vertice's out edges ===
- /*!
- * @brief Returns the first out edge of given vertex in graph
- * @param Graph implementation
- * @param Vertex
- * @param Pointer to context; here your implementation
- * may save a context (what's the current vertex, other references etc)
- */
- edge_t (*first_edge)(void *graph, unsigned int vertex, void **context);
- /*!
- * @brief Deteles the allocated context for iterating on neighbors;
- * you should call this function if you don't want full neighbors iterating.
- * At the end of iterating, next_vertex returns NULL, this function is automatically
- * called.
- * @param Context
- */
- void (*delete_edge_context)(void **context);
- /*!
- * @brief Returns the next out edge of given vertex in graph
- * @param Graph implementation
- * @param Vertex
- * @param Pointer to context; information about the last visited
- * neighbor should be here and it may be actualized
- */
- edge_t (*next_edge)(void *graph, unsigned int vertex, void **context);
- // === [Stop] Iterator over out edge's ===
- /*!
- * @brief Iterates over the edges of graph
- * @param Graph
- * @param Edge iterating function
- * @param Iterating context
- */
- void (*iterate_edges)(void *graph, void edge_handler(edge_t e,
- void *context), void *context);
- /*!
- * @brief Transposes graph
- * @param Graph
- */
- void (*transpose)(void *graph);
- // == [Start] [Optimization] Optional functions ==
- /*!
- * Generic graph implementation computes, the results of
- * the following functions, if NULL pointers are in the structure.
- * Saving non-NULL pointers in the structure makes the library
- * call those functions, instead of the default implementation.
- */
- /*!
- * @brief Computes degree, in degree or out degree of a vertex
- * in graph.
- *
- * in degree(u) = count{ v | (v, u) is an edge}
- *
- * out degree(u) = count{ v | (u, v) is an edge}
- *
- * degree = in degree + out degree
- *
- * @param Graph
- * @param Vertex identifier
- */
- unsigned int (*vertex_degree)(void *graph, unsigned int vertex);
- unsigned int (*vertex_in_degree)(void *graph, unsigned int vertex);
- unsigned int (*vertex_out_degree)(void *graph, unsigned int vertex);
- /*!
- * @brief Computes the dimension of the graph - number of edges
- * @param Graph
- */
- unsigned int (*dimension)(void *graph);
- /*!
- * @brief Removes and deletes all the edges containing vertex
- * @param Graph
- * @param Vertex identifier
- * @param Edge destructor
- */
- void (*delete_vertex_edges)(void *graph, unsigned int vertex,
- void(*edge_delete)(edge_t edge));
- // == [Stop] [Optimization] Optional functions ==
- };
- typedef struct _graph_implementation_t *graph_implementation_t;
- struct _graph_t;
- typedef struct _graph_t *graph_t;
- /*!
- * @brief Constructor - returns an empty graph_t with maximum size.
- * Complexity O(1)
- *
- * @param Maximum vertices number
- * @param Implementation layer
- * @param Vertex destructor; if you pass NULL then vertex_delete will
- * be used
- * @param Edge destructor; if you pass NULL then edge_delete will be
- * used
- */
- DECLSPEC graph_t graph_new(unsigned int max, graph_implementation_t implementation,
- void(*m_vertex_delete)(vertex_t), void(*m_edge_delete)(edge_t));
- /*!
- * @brief Frees the memory occupied by graph_t. Remember it only frees the pointers allocated
- * by the library, none of your pointers, please free them in order to avoid memory leaks.
- * Complexity O(V + E)
- *
- * @param Graph
- */
- DECLSPEC void graph_delete(graph_t graph);
- /*!
- * @brief Adds new vertex with a given label.
- * Complexity O(V)
- *
- * @param Graph
- * @param Vertex label
- * @param Key stored in the label
- * @return Vertex identifier. In the future, use this instead of vertex label
- */
- DECLSPEC unsigned int graph_add_vertex(graph_t graph, char *label, void *key);
- /*!
- * @brief Removes vertex from graph_t by giving it's identifier.
- * Complexity O(1)
- *
- * @param Graph
- * @param Vertex identifier
- * @return Pointer to removed vertex; it's your job to free the memory occupied
- * by the container and by it's content: label and key
- */
- DECLSPEC vertex_t graph_remove_vertex(graph_t graph, unsigned int identifier);
- /*!
- * @brief Verifies if vertex given by it's identifier is in graph.
- * Complexity O(1)
- *
- * @param Graph
- * @param Vertex identifier
- * @return 1 if it's in the graph_t and 0 if not; -1 if an error occurred.
- */
- DECLSPEC int graph_is_vertex(graph_t graph, unsigned int identifier);
- /*!
- * @brief Returns the vertex structure associated with identifier.
- * Complexity O(1)
- *
- * @param Graph
- * @param Vertex identifier
- */
- DECLSPEC vertex_t graph_get_vertex(graph_t graph, unsigned int identifier);
- /*!
- * @brief Adds an edge between two vertices given by their identifiers.
- * Complexity depends on the graph implementation; it may be O(V) or O(1)
- *
- * @param Graph
- * @param First vertex identifier
- * @param Second vertex identifier
- * @param Edge cost
- * @param Edge label
- * @param Key stored in edge
- */
- DECLSPEC void graph_add_edge(graph_t graph, unsigned int vertex, unsigned int vertex2,
- double cost, char *label, void *key);
- /*!
- * @brief Removes an edge from graph.
- * Complexity depends on the graph implementation; it may be O(V) or O(1)
- *
- * @param Graph
- * @param First vertex
- * @param Second vertex
- * @return Pointer to removed edge; it's you job the free the memory allocated for the edge,
- * and for it's content: label and key
- */
- DECLSPEC edge_t graph_remove_edge(graph_t graph, unsigned int vertex1,
- unsigned int vertex2);
- /*!
- * @brief Verifies if there is an edge between two vertices.
- * Complexity depends on the graph implementation; it may be O(V) or O(1)
- *
- * @param Graph
- * @param First vertex identifier
- * @param Second vertex identifier
- * @return 1 if there exists an edge between vertices, 0 if not or -1 if an error occurred
- */
- DECLSPEC int graph_is_edge(graph_t graph, unsigned int vertex1, unsigned int vertex2);
- /*!
- * @brief Returns the edge structure associated with pair of identifiers.
- * Complexity depends on the graph implementation; it may be O(1) or O(V)
- *
- * @param Graph
- * @param Vertex1 identifier
- * @param Vertex2 identifier
- */
- DECLSPEC edge_t graph_get_edge(graph_t graph, unsigned int identifier1,
- unsigned int identifier2);
- /*!
- * @brief Verifies is graph_t is empty: it contains 0 vertices.
- * Complexity O(1)
- *
- * @param Graph
- * @return 1 if it's empty, 0 if not or -1 an error occurred
- */
- DECLSPEC int graph_is_empty(graph_t graph);
- /*!
- * @brief Returns graph's size (order): number of nodes.
- * Complexity O(1)
- *
- * @param Graph
- */
- DECLSPEC unsigned int graph_get_size(graph_t graph);
- /*!
- * @brief Returns graph's dimension : number of edges.
- * Complexity depends on the graph implementation; it may be O(E) or O(V*V)
- *
- * @param Graph
- */
- DECLSPEC unsigned int graph_get_dimension(graph_t graph);
- /*!
- * @brief Returns the degree of vertex given by it's identifier.
- * Complex O(V)
- *
- * @param Graph
- * @param Vertex identifier
- * @return Number of neighbors
- */
- DECLSPEC unsigned int graph_vertex_degree(graph_t graph, unsigned int identifier);
- /*!
- * @brief Returns the out degree of vertex given by it's identifier.
- * Complexity O(V)
- *
- * @param Graph
- * @param Vertex identifier
- * @return Number of edges from vertex to it's neighbors
- */
- DECLSPEC unsigned int graph_vertex_out_degree(graph_t graph, unsigned int identifier);
- /*!
- * @brief Returns the in degree of vertex given by it's identifier.
- * Complexity O(V)
- *
- * @param Graph
- * @param Vertex identifier
- * @return Number of edges from neighbors to vertex
- */
- DECLSPEC unsigned int graph_vertex_in_degree(graph_t graph, unsigned int identifier);
- /*!
- * @brief Iterates over graph's vertices and call the callback function for each entity.
- * Complexity O(V)
- *
- * @param Graph
- * @param Iterating function
- * @param Iterating context
- */
- DECLSPEC void graph_iterate_vertices(graph_t graph, void vertex_handler(vertex_t vertex,
- void *context), void *context);
- /*!
- * @brief Iterates over graph's edges and call the callback function for each entity.
- * Complexity depends on the graph implementation; it may be O(E) or O(V*V).
- *
- * @param Graph
- * @param Iterating function
- * @param Iterating context
- */
- DECLSPEC void graph_iterate_edges(graph_t graph, void edge_handler(edge_t edge,
- void *context), void *context);
- /*!
- * @brief Transposes the graph.
- * Complexity depends on the graph implementation; in general,
- * it's O(V*V)
- *
- * @param Graph
- */
- DECLSPEC void graph_transpose_graph(graph_t graph);
- /*!
- * @brief Synchronization methods. Get and sets the value of current time.
- */
- DECLSPEC void graph_set_current_time(unsigned int time);
- DECLSPEC int graph_get_current_time();
- /*!
- * @brief Checks if graph is undirected. User should know that his graph is directed or undirected
- * and should not access this function directly. It is used as an assert on algorithms applied
- * only to directed graphs, if the user wants this.
- * Complexity O(V*V)
- *
- * @param Graph
- */
- DECLSPEC int graph_is_undirected(graph_t graph);
- /*!
- * @brief Adjusts vertices parameters values by depth-first-search traveling this graph,
- * starting from start vertex, given by it's identifier. If the start vertex is -1
- * then the function does a complete DFS travel. The algorithm is picking nodes is lexicographic order, by
- * identifiers. The variable changing is the vector of vertices.
- * Complexity O(E) if vertex = -1 and O(V) is vertex is a valid identifier
- *
- * @param Graph
- * @param Start vertex
- */
- DECLSPEC void graph_dfs(graph_t graph, unsigned int start_vertex_identifier);
- /*!
- * @brief Adjusts vertices parameters values by breadth-first-search traveling this graph,
- * starting from start vertex, given by it's identifier. If the start vertex is -1
- * then the function does a complete DFS travel. The algorithm is picking nodes is lexicographic order, by
- * identifiers. The variable changing is the vector of vertices.
- * Complexity O(E) if vertex = -1 and O(V) is vertex is a valid identifier
- *
- * @param Graph
- * @param Start vertex
- */
- DECLSPEC void graph_bfs(graph_t graph, unsigned int start_vertex_identifier);
- /*!
- * @brief Classifies edges from DFS point of view.
- * Complexity O(E)
- *
- * @param Graph
- */
- DECLSPEC void graph_dfs_edges_classification(graph_t graph);
- /*!
- * @brief Classifies edges from BFS point of view.
- * Complexity O(E)
- *
- * @param Graph
- */
- DECLSPEC void graph_bfs_edges_classification(graph_t graph);
- /*!
- * @brief Reset vertices parameters to default values : unvisited, colored with white, not discovered,
- * travel not ended and parent nil (-1).
- * Complexity O(V)
- *
- * @param Graph
- */
- DECLSPEC void graph_reset_vertices(graph_t graph);
- /*!
- * @brief Checks if graph is bipartite : exists subgraphs A and B , A has nothing in common
- * with B, such that A U B = G. You should call this function with empty linked lists
- * as parameters because there is stored the result.
- * @param Graph
- * @param Pointer to first vertices set
- * @param Pointer to second vertices set
- * @return 0 if the graph_t is bipartite, 1 if not and -1 if an error occurred
- */
- DECLSPEC int graph_bipartite(graph_t graph, linked_list_t first_set,
- linked_list_t second_set);
- /*!
- * @brief Returns the diameter of graph.
- * @param Graph
- * @param Pointer to first node; here the function will store first node of diameter
- * @param Pointer to second node; here the function will store second node of diameter
- */
- DECLSPEC unsigned int graph_diameter(graph_t graph, unsigned int *first_node,
- unsigned int *second_node);
- /*!
- * @brief Calculates the articulation points.
- * @param Graph
- * @param Articulation points list
- */
- DECLSPEC void
- graph_articulation_points(graph_t graph, linked_list_t articulation_points);
- /*!
- * @brief Computes the bridges from graph. Each key of bridges is a pair of unsigned int, unsigned int.
- * @param Graph
- * @param Bridges list
- */
- DECLSPEC void graph_bridges(graph_t graph, linked_list_t bridges);
- /*!
- * @brief Computes the biconex components from graph. Each key of biconex_components is a
- * linked list of unsigned int.
- * @param Graph
- * @param Biconex components list
- */
- DECLSPEC void graph_biconex_components(graph_t graph, linked_list_t biconex_components);
- /*!
- * @brief Finds the simple cycles from graph.
- * @param Graph
- * @param Cycles list; each key of list is a linked list containing vertices identifiers
- * as keys
- */
- DECLSPEC void graph_cycles(graph_t graph, linked_list_t cycles);
- /*!
- * @brief Finds the connected components from graph. Depends on the last parameter, the function
- * will check is the given graph is undirected. After the function finishes the vertices parameters
- * will be reseted, because it's doing DFS travels for each unvisited vertices.
- * @param Graph
- * @param Linked list, which will contain the connected components; a connected component
- * is a linked list with vertices' identifiers as keys
- * @param 1 if you want to check the graph it's undirected and 0 if you know this in advance;
- * pay attention, this function works correctly only for undirected graphs
- */
- DECLSPEC void graph_connected_components(graph_t graph,
- linked_list_t connected_components, char check);
- /*!
- * @brief Finds the strongly connected components from graph
- * @param Graph
- * @param Linked list which will contain the result
- * @see graph_connected_components
- */
- DECLSPEC void graph_strongly_connected_components(graph_t graph,
- linked_list_t strongly_connected_components);
- /*!
- * @brief Sorts in topological order the keys of graph
- * and returns a linked list containing vertices in sorted order.
- * Your graph should be acyclic and direct (DAG - direct acyclic graph)
- * @param Graph
- * @param Linked list which will store the result
- * @return 0 if graph can be sorted this way and -1 if not
- */
- DECLSPEC char graph_topological_sort(graph_t graph, linked_list_t sort);
- /*!
- * @brief Executes Dijkstra's algorithm for computing minimum distance vector of graph
- * @param Graph
- * @param Source vertex
- * @param Minimum distances vector
- * @param Parents vector
- */
- DECLSPEC void graph_dijkstra(graph_t graph, unsigned int source, vector_t distances,
- vector_t parents);
- /*!
- * @brief Executes Bellman-Ford algorithm for computing minimum distance vector of graph
- * @param Pointer to graph
- * @param Source vertex
- * @param Reference to minimum distances vector
- * @param Reference to parents vector
- * @return 1 if success, 0 if not and -1 if an error occurred, negative
- * cycle detected for example
- */
- DECLSPEC int graph_bellman_ford(graph_t graph, unsigned int source, vector_t distances,
- vector_t parents);
- /*!
- * @brief Executes Floyd-Warshall algorithm for computing minimum distance matrix of graph
- * @param Graph
- * @param Reference to minimum distances matrix. Each key should be a valid double *
- * @param Reference to parents matrix
- */
- DECLSPEC void graph_floyd_warshall(graph_t graph, matrix_t distances, matrix_t parents);
- /*!
- * @brief Executes Johnson algorithm for computing minimum distance matrix of graph
- * @param Graph
- * @param Minimum distances matrix
- * @param Parents matrix
- * @return 1 if success, 0 if not and -1 if an error occurred - negative
- * cycle detected for example
- */
- DECLSPEC int graph_johnson(graph_t graph, matrix_t distances, matrix_t parents);
- /*!
- * @brief Executes Prim's algorithm for computing minimum spanning tree of graph
- * @param Graph
- * @param Starting vertex
- * @param Minimum spanning tree. The function will store here a linked list
- * of edges (pair of vertices).
- * @return The cost of the minimum spanning tree - the sum of edges cost.
- */
- DECLSPEC double graph_prim(graph_t graph, unsigned int start_vertex_identifier,
- linked_list_t minimum_spanning_tree);
- /*!
- * @brief Executes Kruskal's algorithm for computing minimum spanning tree of graph.
- * Minimum spanning tree is a linked list of vertices identifiers, where two
- * consecutive vertices form an edge. For example u1, u2, u3 => [u1, u2], [u2, u3]
- * @see graph_prim for more details
- */
- DECLSPEC double graph_kruskal(graph_t graph, unsigned int start_vertex_identifier,
- linked_list_t *minimum_spanning_tree);
- /*!
- * @brief Executes Ford-Fulkerson algorithm for computing max-flow in graph
- * It uses DFS travel for exploring possible flow increasing paths.
- * @param Graph
- * @param Source vertex
- * @param Destination vertex
- * @param Flow matrix where the result is written; the matrix should have allocated double pointers
- * @return Maximum flow in graph between source and destination
- */
- DECLSPEC double graph_ford_fulkerson(graph_t graph, unsigned int source,
- unsigned int destination, matrix_t max_flow);
- /*!
- * @brief Executes Edmonds-Karp algorithm for computing max-flow in graph.
- * It uses BFS travel for exploring possible flow increasing paths
- * @param Graph
- * @param Source vertex
- * @param Destination vertex
- * @param Reference to flow matrix, where the result is written
- * @return Maximum flow in graph_t between source and destination
- */
- DECLSPEC double graph_edmonds_karp(graph_t graph, unsigned int source,
- unsigned int destination, matrix_t max_flow);
- #endif /* GRAPH_H_ */
|