328 lines
8.8 KiB
C
328 lines
8.8 KiB
C
/*******************************************************************************
|
|
*
|
|
* LHMatch: A library to compute 'LH Matchings', a generalization of ordinary
|
|
* bipartite matchings.
|
|
*
|
|
* Authors: Nicholas Harvey and Laszlo Lovasz
|
|
*
|
|
* Developed: Nov 2000 - July 2001
|
|
*
|
|
* Problem Description:
|
|
*
|
|
* Let G=(U \union V, E) be a bipartite graph. We define an assignment
|
|
* to be a set of edges, M \subset E, such that every u \member U has
|
|
* deg_M(u)=1. For v \member V, deg_M(v) is unrestricted. An LH Matching is
|
|
* an assignment for which the variance of {deg_M(v):v \member V} is
|
|
* minimized.
|
|
*
|
|
* Note that it is easy to compute an ordinary maximum cardinality bipartite
|
|
* matching from a optimum relaxed matching: at each RHS-vertex, throw away
|
|
* all of its matching edges but one.
|
|
*
|
|
*******************************************************************************/
|
|
|
|
|
|
/***** Type Definitions *****/
|
|
typedef void* LHGRAPH;
|
|
|
|
|
|
/***** Graph Statistics *****/
|
|
typedef struct {
|
|
/* numEdges: The total number of edges in the graph */
|
|
int numEdges;
|
|
|
|
/* numMatchingEdges: The total number of matching edges */
|
|
int numMatchingEdges;
|
|
|
|
/* matchingCost: The total cost of the current matching. The total cost
|
|
* is defined to be the sum of the load of the matching on each of the
|
|
* right-hand vertices. If a right-hand vertex has c matching partners,
|
|
* the load at this vertex is c*(c+1)/2. */
|
|
int matchingCost;
|
|
|
|
/* bipMatchingSize: If the current LH Matching were converted into a
|
|
* bipartite matching, this would be the size of the bipartite matching. */
|
|
int bipMatchingSize;
|
|
} LHSTATS;
|
|
|
|
|
|
/***** Error Codes *****/
|
|
#define LH_SUCCESS 0
|
|
#define LH_INTERNAL_ERR -1
|
|
#define LH_PARAM_ERR -2
|
|
#define LH_MEM_ERR -3
|
|
#define LH_MATCHING_ERR -4
|
|
#define LH_EDGE_EXISTS -5
|
|
|
|
|
|
/***** Algorithm Types *****/
|
|
/* The LHMatch library actually includes two algorithms to compute
|
|
* LH Matchings: LHOnline, LHBFS.
|
|
*
|
|
* LHOnline is the simpler algorithm and also the slower one. It cannot
|
|
* incrementally improve an initial matching. Instead, it computes an optimal
|
|
* matching from scratch each time it runs.
|
|
*
|
|
* LHBFS is faster than LHOnline but the implementation is more
|
|
* complicated. It can take an existing matching as input and incrementally
|
|
* improve it until it becomes optimal.
|
|
*/
|
|
typedef enum {
|
|
LH_ALG_ONLINE,
|
|
LH_ALG_BFS
|
|
} LHALGTYPE;
|
|
#define LH_ALG_DEFAULT LH_ALG_BFS
|
|
|
|
|
|
/***** LHCreateGraph *****/
|
|
/*
|
|
* Description:
|
|
*
|
|
* Create a graph structure on which which to compute the matching.
|
|
*
|
|
* Parameters:
|
|
*
|
|
* IN numLHSVtx The number of vertices on the left-hand side of
|
|
* the bipartite graph.
|
|
*
|
|
* IN numRHSVtx The number of vertices on the right-hand side of
|
|
* the bipartite graph.
|
|
*
|
|
* OUT pGraph On successful completion, pGraph will contain a
|
|
* valid graph structure.
|
|
*
|
|
* Return Value:
|
|
*
|
|
* Error Code
|
|
*/
|
|
int LHCreateGraph( int numLHSVtx, int numRHSVtx, LHGRAPH* pGraph );
|
|
|
|
|
|
/***** LHAddEdge *****/
|
|
/*
|
|
* Description:
|
|
*
|
|
* Add an edge to the graph connecting lhsVtx and rhsVtx
|
|
*
|
|
* Parameters:
|
|
*
|
|
* IN graph A graph successfully created by LHGraphCreate.
|
|
*
|
|
* IN lhsVtx The ID of the left-hand vertex. Legal values are
|
|
* 0 <= lhsVtx < numLHSVtx
|
|
*
|
|
* IN rhsVtx The ID of the right-hand vertex. Legal values are
|
|
* 0 <= rhsVtx < numRHSVtx
|
|
*
|
|
* Return Value:
|
|
*
|
|
* Error Code
|
|
*/
|
|
int LHAddEdge( LHGRAPH graph, int lhsVtx, int rhsVtx );
|
|
|
|
|
|
/***** LHSetMatchingEdge *****/
|
|
/*
|
|
* Description:
|
|
*
|
|
* Set the edge connecting lhsVtx and rhsVtx in the graph to be
|
|
* a matching edge. The edge (lhsVtx,rhsVtx) must have already been
|
|
* created with a call to LHVtxAddEdge.
|
|
*
|
|
* Left-hand vertices may only have one matching edge. If lhsVtx
|
|
* already has a matching edge, that edge will be demoted from a
|
|
* matching edge to a normal edge. Right-hand vertices may have
|
|
* multiple matching edges.
|
|
*
|
|
* Parameters:
|
|
*
|
|
* IN graph A graph successfully created by LHGraphCreate.
|
|
*
|
|
* IN lhsVtx The ID of the left-hand vertex. Legal values are
|
|
* 0 <= lhsVtx < numLHSVtx
|
|
*
|
|
* IN rhsVtx The ID of the right-hand vertex. Legal values are
|
|
* 0 <= rhsVtx < numRHSVtx
|
|
*
|
|
* Return Value:
|
|
*
|
|
* Error Code
|
|
*/
|
|
int LHSetMatchingEdge( LHGRAPH graph, int lhsVtx, int rhsVtx );
|
|
|
|
|
|
/***** LHGetDegree *****/
|
|
/*
|
|
* Description:
|
|
*
|
|
* Get the degree (number of neighbours) of a vertex.
|
|
*
|
|
* Parameters:
|
|
*
|
|
* IN graph A graph successfully created by LHGraphCreate.
|
|
*
|
|
* IN vtxID The ID of the vertex to examine.
|
|
*
|
|
* IN left If the vertex to examine is a left-vertex, this
|
|
* parameter should be TRUE. If the vertex is a right-
|
|
* vertex, this parameter should be FALSE.
|
|
*
|
|
* Return Value:
|
|
*
|
|
* >=0 The number of neighbours
|
|
*
|
|
* <0 Error Code
|
|
*/
|
|
int LHGetDegree( LHGRAPH graph, int vtxID, char left );
|
|
|
|
|
|
/***** LHGetMatchedDegree *****/
|
|
/*
|
|
* Description:
|
|
*
|
|
* Get the matched degree (number of matched neighbours) of a
|
|
* right-hand vertex.
|
|
*
|
|
* Parameters:
|
|
*
|
|
* IN graph A graph successfully created by LHGraphCreate.
|
|
*
|
|
* IN vtxID The ID of the right hand vertex to examine.
|
|
*
|
|
* Return Value:
|
|
*
|
|
* >=0 The number of neighbours
|
|
*
|
|
* <0 Error Code
|
|
*/
|
|
int LHGetMatchedDegree( LHGRAPH graph, int vtxID );
|
|
|
|
|
|
/***** LHGetNeighbour *****/
|
|
/*
|
|
* Description:
|
|
*
|
|
* Get the n'th neighbour of the vertex specified by vtxID.
|
|
*
|
|
* Parameters:
|
|
*
|
|
* IN graph A graph successfully created by LHGraphCreate.
|
|
*
|
|
* IN vtxID The ID of the vertex to examine.
|
|
*
|
|
* IN left If the vertex to examine is a left-vertex, this
|
|
* parameter should be TRUE. If the vertex is a right-
|
|
* vertex, this parameter should be FALSE.
|
|
*
|
|
* IN n The index of the neighbour to retrieve. Legal values
|
|
* are 0 <= n < Degree(vtxID).
|
|
*
|
|
* Return Value:
|
|
*
|
|
* >=0 The vertex ID of the n'th neighbour. If 'left' is TRUE,
|
|
* this ID refers to a right-hand vertex. Conversely, if
|
|
* 'left' is FALSE, this ID refers to a left-hand vertex.
|
|
*
|
|
* <0 Error Code
|
|
*/
|
|
int LHGetNeighbour( LHGRAPH graph, int vtxID, char left, int n );
|
|
|
|
|
|
/***** LHFindLHMatching *****/
|
|
/*
|
|
* Description:
|
|
*
|
|
* Find an optimal matching in the graph.
|
|
*
|
|
* Parameters:
|
|
*
|
|
* IN graph A graph successfully created by LHGraphCreate,
|
|
* to which edges have been added using LHAddEdge.
|
|
*
|
|
* IN alg Specifies which algorithm to use. For most purposes,
|
|
* LH_ALG_DEFAULT is fine.
|
|
*
|
|
* Return Value:
|
|
*
|
|
* Error Code
|
|
*/
|
|
int LHFindLHMatching( LHGRAPH graph, LHALGTYPE alg );
|
|
|
|
|
|
/***** LHGetMatchedVtx *****/
|
|
/*
|
|
* Description:
|
|
*
|
|
* Determine which vertex on the right-hand side is matched to a
|
|
* given vertex on the left-hand side.
|
|
*
|
|
* Parameters:
|
|
*
|
|
* IN graph A graph successfully created by LHGraphCreate,
|
|
* to which edges have been added using LHAddEdge.
|
|
*
|
|
* IN lhsVtx The left-hand vertex to query.
|
|
*
|
|
* Return Value:
|
|
*
|
|
* >=0 The index of the right-hand vertex that is matched
|
|
* with lhsVtx.
|
|
*
|
|
* <0 Error Code. If LH_MATCHING_ERR is returned, then
|
|
* lhsVtx is not matched with any right-hand vertex.
|
|
*/
|
|
int LHGetMatchedVtx( LHGRAPH graph, int lhsVtx );
|
|
|
|
|
|
/***** LHGetStatistics *****/
|
|
/*
|
|
* Description:
|
|
*
|
|
* Obtain statistics about the current matching.
|
|
*
|
|
* Parameters:
|
|
*
|
|
* IN graph A graph for which an LH Matching has been
|
|
* computed using LHFindLHMatching().
|
|
*
|
|
* Return Value:
|
|
*
|
|
* Error Code
|
|
*/
|
|
int LHGetStatistics( LHGRAPH graph, LHSTATS *stats );
|
|
|
|
|
|
/***** LHClearMatching *****/
|
|
/*
|
|
* Description:
|
|
*
|
|
* Clear the current matching. All edges are demoted to normal edges.
|
|
*
|
|
* Parameters:
|
|
*
|
|
* IN graph A graph successfully created by LHGraphCreate,
|
|
* to which edges have been added using LHAddEdge.
|
|
*
|
|
* Return Value:
|
|
*
|
|
* Error Code
|
|
*/
|
|
int LHClearMatching( LHGRAPH graph );
|
|
|
|
|
|
/***** LHDestroyGraph *****/
|
|
/*
|
|
* Description:
|
|
*
|
|
* Destroy the current graph.
|
|
*
|
|
* Parameters:
|
|
*
|
|
* IN graph A graph successfully created by LHGraphCreate.
|
|
*
|
|
* Return Value:
|
|
*
|
|
* Error Code
|
|
*/
|
|
int LHDestroyGraph( LHGRAPH graph );
|