Stanford ЩЕЛЧОК Это хорошо известный пакет для майнинга графов, имеющий как реализацию на Python, так и реализацию на C ++.
У меня есть некоторый код в Python для анализа графов с использованием SNAP. У меня также есть функция C ++, обрабатывающая граф оснастки. Теперь мне нужно написать оболочку, чтобы эту функцию C ++ можно было вызывать из Python.
Проблема в том, что я не знаю Как разобрать / разыменовать объект графа оснастки из Python в C ++.
Код Python выглядит следующим образом: (Дополнительные пояснения приводятся после примеров кода)
import my_module;
import snap;
G = snap.GenRndGnm(snap.PUNGraph, 100, 1000);
print(type(G));
A = my_module.CppFunction(G); # customized function
print(A);
Оболочка CPP my_module_in_cpp.cpp
похоже:
// module name: my_module, defined in the setup file
// function to be called from python: CppFunction
#include <Python.h>
//#include "my_file.h" // can be ignored in this minimal working example.
#include "Snap.h"
#include <iostream>
static PyObject *My_moduleError;
// module_name_function, THE CORE FUNCTION OF THIS QUESTION
static PyObject *my_module_CppFunction(PyObject *self, PyObject *args) {
PUNGraph G_py;
int parseOK = PyArg_ParseTuple(args, "O", &G_py);
if (!parseOK) return NULL;
std::cout << "N: " << G_py->GetNodes() << ", E: " << G_py->GetEdges() << std::endl;
fflush(stdout);
if ((G_py->GetNodes()!=100)||(G_py->GetEdges()!=1000)) {
PyErr_SetString(My_moduleError, "Graph reference incorrect.");
return NULL;
}
PyObject *PList = PyList_New(0);
PyList_Append(PList,Py_BuildValue("i",G_py->GetNodes()));
PyList_Append(PList,Py_BuildValue("i",G_py->GetEdges()));
return PList;
}
// To register the core function to python
static PyMethodDef CppFunctionMethod[] = {
{"CppFunction", my_module_CppFunction, METH_VARARGS, "To call CppFunction in C++"},
{NULL,NULL,0,NULL}
};
extern "C" PyMODINIT_FUNC initmy_module(void) {
PyObject *m = Py_InitModule("my_module",CppFunctionMethod);
if (m==NULL) return;
My_moduleError = PyErr_NewException("my_module.error", NULL, NULL);
Py_INCREF(My_moduleError);
PyModule_AddObject(m, "error", My_moduleError);
}
Я использую Ubuntu, Python-2.7. В случае, если кто-то захочет воспроизвести проблему, setup.py
файл также предоставляется.
from distutils.core import setup, Extension
module1 = Extension('my_module',\
include_dirs = ['/usr/include/python2.7/','/users/<my_local>/Snap-3.0/','/users/<my_local>/Snap-3.0/snap-core','/users/<my_local>/Snap-3.0/glib-core'],
library_dirs = ['/users/<my_local>/Snap-3.0/snap-core/'],
extra_objects = ['/users/<my_local>/Snap-3.0/snap-core/Snap.o'],
extra_compile_args=['-fopenmp','-std=c++11'],
extra_link_args=['-lgomp'],
sources = ['my_module_in_cpp.cpp'])
setup (name = 'NoPackageName', version = '0.1',\
description = 'No description.', ext_modules = [module1])
Каждый раз, когда я запускаю приведенный выше код Python, появляется сообщение об ошибке «Ссылка на график неверна». отображается.
По-видимому G_py->GetNodes()
а также G_py->GetEdges()
вызвать проблему. Это должно быть результатом G_py
не указывает на правильный адрес / в правильном формате. Я попытался использовать TUNGraph в коде cpp, он все еще не указывает на правильный адрес. Есть ли способ, которым указатель в C ++ может указывать на правильный адрес исходного объекта C ++?
Хотя вообще трудно разыменовать PythonObject из C ++, но в этом случае я думаю, что это выполнимо, так как Snap-Python также реализован на C ++. Нам просто нужно развернуть его оболочку Python. И авторы оснастки также предоставили SWIG файлы.
Конечно, мы можем записать файл графика на диск и прочитать с него, но это приведет к вводу-выводу и потребует дополнительного времени. И у группы пользователей Snap не так много трафика, как у стека overoverflow.
Кстати, есть networkx
а также stanford-nlp
теги, но нет stanford-snap
или похожий тег, ссылающийся на этот инструмент. Может кто-нибудь создать такой тег?
Задача ещё не решена.
Других решений пока нет …