forked from zenbaku/hungarian
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathhungarian.cpp
executable file
·115 lines (99 loc) · 2.74 KB
/
hungarian.cpp
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
/*
hungarian
Harold Cooper <[email protected]>
hungarian.cpp 2004-09-02
*/
#include "Python.h"
#include "numpy/arrayobject.h"
#include "asp.h"
static PyObject *
hungarian(PyObject *self, PyObject *args)
//hungarian(costs)
{
PyObject *ocosts;
PyArrayObject *costs;
int n;
npy_intp n2;
long *rowsol;
long *colsol;
cost *buf,**ccosts;
npy_intp *strides;
PyObject * rowo;
PyObject * colo;
if (!PyArg_ParseTuple(args, "O", &ocosts))
return NULL;
costs = (PyArrayObject*)PyArray_FromAny(
ocosts,PyArray_DescrFromType(COST_TYPE_NPY),2,2,
NPY_CONTIGUOUS|NPY_ALIGNED|NPY_FORCECAST,0
);
if (costs->nd!=2)
{
PyErr_SetString(PyExc_ValueError,"lap() requires a 2-D matrix");
goto error;
}
n = costs->dimensions[0];
n2 = costs->dimensions[0];
if (costs->dimensions[1]!=n)
{
PyErr_SetString(PyExc_ValueError,"lap() requires a square matrix");
goto error;
}
//get inputted matrix as a 1-D C array:
buf = (cost*)PyArray_DATA(costs);
//copy inputted matrix into a 2-dimensional C array:
strides = PyArray_STRIDES(costs);
assert(strides[1] == sizeof(cost));
ccosts = (cost **)malloc(sizeof(cost *)*n);
if(!ccosts)
{
PyErr_NoMemory();
free(ccosts);
goto error;
}
for(int i=0;i<n;i++)
ccosts[i] = buf+i*(strides[0]/sizeof(cost));
//allocate data for the output array
rowo = PyArray_SimpleNew(1, &n2, NPY_LONG);
colo = PyArray_SimpleNew(1, &n2, NPY_LONG);
rowsol = (long *) PyArray_DATA(rowo);
colsol = (long *) PyArray_DATA(colo);
if(!(rowsol&&colsol))
{
PyErr_NoMemory();
free(ccosts);
goto error;
}
//run hungarian!:
asp(n,ccosts,rowsol,colsol);
//NA_InputArray() incremented costs, but now we're done with it, so let it get GC'ed:
Py_XDECREF(costs);
free(ccosts);
return Py_BuildValue("(NN)",
rowo, colo
);
error:
Py_XDECREF(costs);
return NULL;
}
static PyMethodDef HungarianMethods[] = {
{"lap", hungarian, METH_VARARGS,
"Solves the linear assignment problem using the Hungarian\nalgorithm.\n\nhungarian() takes a single argument - a square cost matrix - and returns a\ntuple of the form\n(row_assigns,col_assigns)."},
{NULL, NULL, 0, NULL} /* Sentinel (terminates structure) */
};
PyMODINIT_FUNC
inithungarian(void)
{
(void) Py_InitModule("hungarian", HungarianMethods);
import_array();
}
int
main(int argc, char *argv[])
{
/* Pass argv[0] to the Python interpreter */
Py_SetProgramName(argv[0]);
/* Initialize the Python interpreter. Required. */
Py_Initialize();
/* Add a static module */
inithungarian();
return 0;
}