R-->cpp 如何获取 C++ 指针以使用 sourceCpp(Bellman Ford 算法)

R-->cpp how to get C++ pointers to work with sourceCpp (Bellman Ford algorithm)

我正在尝试直接使用 sourceCpp 使用 rcpp 将一些函数从 cpp 移植到 r。我是一个完全的新手,所以对于使用不当的语言或 post 表示歉意。尝试移植 Bellman Ford 算法(来自 Gupte、Shankar、Li、Muthukrishnan、Iftode)。

我遇到两个错误:

  1. 无法在初始化中将 'SEXP' 转换为 'Rcpp::traits::input_parameter::type* {aka Rcpp::InputParameter*}
  2. 从 'Rcpp::traits::input_parameter::type {aka Rcpp::InputParameter}' 到 'int' 的无效用户定义转换 [-fpermissive]
  3. 奖金混乱:另外,R studio 显示代码范围外的行错误(第 600 行错误,但 Cpp 代码只有 500 行长)

我猜这与 class 类型、包装函数、无法在第一行中使用指针或类似内容有关。请告诉我如何调整此代码以将此函数正确导出到 r。

谢谢。

   #include <Rcpp.h> // added this
using namespace Rcpp; // added

#define MAXV 100000
 using namespace std; // commented this out...? don't, throws a lot of errors

struct edge { 
    int u, v, weight;
    edge(int _u, int _v) {
        u = _u, v = _v, weight = -1;
    }      
    edge(int _u, int _v, int _weight) {
        u = _u, v = _v, weight = _weight;
    }
};

// general stuff
int LPvalue; // value for the dual LP
int cycleCount;
int V, E;
vector <edge> edges;
vector <edge> original_edges;
ofstream results, summary;

// stuff for labeling
vector <int> edgesDAG; // edges left over from eulerian subgraph
vector <int> edgesEulerian; // maximal eulerian subgraph
set<int> adjDAG[MAXV]; // these adjacency lists still just keep edge indices
set<int> adjEulerian[MAXV];
bool inEulerian[MAXV];

// stuff for Bellman-Ford
int dist[MAXV];        // vertex -> distance

// [[Rcpp::export]] //ERRORS
void bellman_ford(int *pred) {

    for(int i = 0; i < V; i++) {
        dist[i] = V;
    pred[i] = -1;
    }

    dist[0] = 0;

    int i;
    for(i = 0; i < V; i++) {
        bool changed = false;
    //printf("%d",i);
        for(int j = 0; j < E; j++) {

            int u = edges[j].u;
            int v = edges[j].v;
            int w = edges[j].weight;
            if(dist[v] > dist[u] + w) {
                dist[v] = dist[u] + w;
                pred[v] = j;
                changed = true;
            }
        }

        if(dist[0] < 0) {
            break;
        }

        if(!changed) {
            printf("Bellman Ford done after %d of %d iters\n", i, V);
        //results << "Bellman-Ford done after " << i << " of " << V << " iters" << endl;
            break;
        }
    }
    printf("Bellman Ford took %d of %d iters\n", i+1, V);
}
  1. 使用std::vector<int>代替int *

  2. 使用Rcpp::Rcout代替std::ofstream

应编译以下代码:

#include <Rcpp.h> // added this
using namespace Rcpp; // added

#define MAXV 100000
using namespace std; // commented this out...? don't, throws a lot of errors

struct edge { 
  int u, v, weight;
  edge(int _u, int _v) {
    u = _u, v = _v, weight = -1;
  }      
  edge(int _u, int _v, int _weight) {
    u = _u, v = _v, weight = _weight;
  }
};

// general stuff
int LPvalue; // value for the dual LP
int cycleCount;
int V, E;
vector <edge> edges;
vector <edge> original_edges;

// stuff for labeling
vector <int> edgesDAG; // edges left over from eulerian subgraph
vector <int> edgesEulerian; // maximal eulerian subgraph
set<int> adjDAG[MAXV]; // these adjacency lists still just keep edge indices
set<int> adjEulerian[MAXV];
bool inEulerian[MAXV];

// stuff for Bellman-Ford
int dist[MAXV];        // vertex -> distance

// [[Rcpp::export]]
void bellman_ford(std::vector<int> pred) {

  for(int i = 0; i < V; i++) {
    dist[i] = V;
    pred[i] = -1;
  }

  dist[0] = 0;

  int i;
  for(i = 0; i < V; i++) {
    bool changed = false;
    //printf("%d",i);
    for(int j = 0; j < E; j++) {

      int u = edges[j].u;
      int v = edges[j].v;
      int w = edges[j].weight;
      if(dist[v] > dist[u] + w) {
        dist[v] = dist[u] + w;
        pred[v] = j;
        changed = true;
      }
    }

    if(dist[0] < 0) {
      break;
    }

    if(!changed) {
      Rcpp::Rcout << "Bellman-Ford done after " << i << " of " << V << " iters" << endl;
      break;
    }
  }
  Rcpp::Rcout << "Bellman Ford took" << i + 1 << " of " << V << " iters" << std::endl;
}