-
Notifications
You must be signed in to change notification settings - Fork 892
/
Copy pathbipartite_graph.h
165 lines (149 loc) · 5.79 KB
/
bipartite_graph.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
/*
* Copyright (c) 2014-2022 Cisco Systems, Inc. All rights reserved
* Copyright (c) 2017-2019 Amazon.com, Inc. or its affiliates. All Rights
* reserved.
* $COPYRIGHT$
*
* Additional copyrights may follow
*
* $HEADER$
*/
/* Implements an adjacency-list-based weighted directed graph (digraph),
* focused on supporting bipartite digraphs and flow-network problems.
*
* Note that some operations might be more efficient if this structure were
* converted to use an adjacency matrix instead of an adjacency list. OTOH
* that complicates other pieces of the implementation (specifically, adding
* and removing edges). */
#ifndef OPAL_BP_GRAPH_H
#define OPAL_BP_GRAPH_H
struct opal_bp_graph_vertex_t;
struct opal_bp_graph_edge_t;
struct opal_bp_graph_t;
typedef struct opal_bp_graph_vertex_t opal_bp_graph_vertex_t;
typedef struct opal_bp_graph_edge_t opal_bp_graph_edge_t;
typedef struct opal_bp_graph_t opal_bp_graph_t;
/**
* callback function pointer type for cleaning up user data associated with a
* vertex or edge */
typedef void (*opal_bp_graph_cleanup_fn_t)(void *user_data);
/**
* create a new empty graph
*
* Any new vertices will have NULL user data associated.
*
* @param[in] v_data_cleanup_fn cleanup function to use for vertex user data
* @param[in] e_data_cleanup_fn cleanup function to use for edge user data
* @param[out] g_out the created graph
*
* @returns OPAL_SUCCESS or an OMPI error code
*/
int opal_bp_graph_create(opal_bp_graph_cleanup_fn_t v_data_cleanup_fn,
opal_bp_graph_cleanup_fn_t e_data_cleanup_fn, opal_bp_graph_t **g_out);
/**
* free the given graph
*
* Any user data associated with vertices or edges in the graph will have
* the given edge/vertex cleanup callback invoked in some arbitrary order.
*
* @returns OPAL_SUCCESS or an OMPI error code
*/
int opal_bp_graph_free(opal_bp_graph_t *g);
/**
* clone (deep copy) the given graph
*
* Note that copy_user_data==true is not currently supported (requires the
* addition of a copy callback for user data).
*
* @param[in] g the graph to clone
* @param[in] copy_user_data if true, copy vertex/edge user data to the new
* graph
* @param[in] g_clone_out the resulting cloned graph
* @returns OPAL_SUCCESS or an OMPI error code
*/
int opal_bp_graph_clone(const opal_bp_graph_t *g, bool copy_user_data,
opal_bp_graph_t **g_clone_out);
/**
* return the number of edges for which this vertex is a destination
*
* @param[in] g the graph to query
* @param[in] vertex the vertex id to query
* @returns the number of edges for which this vertex is a destination
*/
int opal_bp_graph_indegree(const opal_bp_graph_t *g, int vertex);
/**
* return the number of edges for which this vertex is a source
*
* @param[in] g the graph to query
* @param[in] vertex the vertex id to query
* @returns the number of edges for which this vertex is a source
*/
int opal_bp_graph_outdegree(const opal_bp_graph_t *g, int vertex);
/**
* add an edge to the given graph
*
* @param[in] from source vertex ID
* @param[in] to target vertex ID
* @param[in] cost cost value for this edge (lower is better)
* @param[in] capacity maximum flow transmissible on this edge
* @param[in] e_data caller data to associate with this edge, useful for
* debugging or minimizing state shared across components
*
* @returns OPAL_SUCCESS or an OMPI error code
*/
int opal_bp_graph_add_edge(opal_bp_graph_t *g, int from, int to, int64_t cost, int capacity,
void *e_data);
/**
* add a vertex to the given graph
*
* @param[in] g graph to manipulate
* @param[in] v_data data to associate with the new vertex
* @param[out] index_out integer index of the new vertex. May be NULL.
*
* @returns OPAL_SUCCESS or an OMPI error code
*/
int opal_bp_graph_add_vertex(opal_bp_graph_t *g, void *v_data, int *index_out);
/**
* Get a pointer to the vertex data given the graph and vertex index
* associated with the vertex.
*
* @param[in] g graph the vertex belongs to
* @param[in] v_index integer index of the vertex
* @param[out] v_data_out data associated with the new vertex, may be NULL.
*
* @returns OPAL_SUCCESS or an OMPI error code
*/
int opal_bp_graph_get_vertex_data(opal_bp_graph_t *g, int v_index, void **v_data_out);
/**
* compute the order of a graph (number of vertices)
*
* @param[in] g the graph to query
*/
int opal_bp_graph_order(const opal_bp_graph_t *g);
/**
* This function solves the "assignment problem":
* https://en.wikipedia.org/wiki/Assignment_problem
*
* The goal is to find a maximum cardinality, minimum cost matching in a
* weighted bipartite graph. Maximum cardinality takes priority over minimum
* cost.
*
* Capacities in the given graph are ignored (assumed to be 1 at the start).
* It is also assumed that the graph only contains edges from one vertex set
* to the other and that no edges exist in the reverse direction ("forward"
* edges only).
*
* The algorithm(s) used will be deterministic. That is, given the exact same
* graph, two calls to this routine will result in the same matching result.
*
* @param[in] g an acyclic bipartite directed graph for
* which a matching is sought
* @param[out] num_match_edges_out number edges found in the matching
* @param[out] match_edges_out an array of (u,v) vertex pairs indicating
* which edges are in the matching
*
* @returns OPAL_SUCCESS or an OMPI error code
*/
int opal_bp_graph_solve_bipartite_assignment(const opal_bp_graph_t *g, int *num_match_edges_out,
int **match_edges_out);
#endif /* OPAL_BP_GRAPH_H */