c++ - R-->cpp 如何获取 C++ 指针以与 sourceCpp 一起使用(贝尔曼福特算法)

标签 c++ r rcpp

我正在尝试直接使用sourceCpp使用rcpp将一些函数从cpp移植到r。我完全是新手,所以对语言或帖子使用不当表示歉意。尝试移植 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 行长)

我猜测这与类类型、包装函数、无法在第一行中使用指针或类似的内容有关。请让我知道如何调整此代码以正确将此函数导出到 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;
}

关于c++ - R-->cpp 如何获取 C++ 指针以与 sourceCpp 一起使用(贝尔曼福特算法),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50915227/

相关文章:

c++ - 更改 win32 的单选按钮文本颜色

c++ - 如何在 C++ 中创建临时对象

r - dygraphs 不显示超过 10,000 个数据点的线条

r - 如何通过多个for循环使Rcpp代码高效?

c++ - 从文件中读取、清除、写入

c++ - 将 shared_ptr 与对象数组一起使用

r - 在行内的顺序中调整很少的频率来计算频率

r - 订购 1 :17 by perfect square pairs

RcppRoll 或 CumSum 滞后于动态窗口

r - 使用 RcppParallel 分组求和