Reputation: 101
I'm trying to port a few functions over to r from cpp using rcpp directly using sourceCpp. I'm a total novice so apologies for poorly used language or post. Trying to port over the Bellman Ford algorithm (from Gupte, Shankar, Li, Muthukrishnan, Iftode).
I'm getting two errors:
I'm guessing this is something to do with class types, wrapping functions, not being able to use pointers or something like that in the very first line. Please let me know how I might adjust this code to correctly export this function to r.
Thank you.
#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);
}
Upvotes: 2
Views: 158
Reputation: 522
use std::vector<int>
instead of int *
use Rcpp::Rcout
instead of std::ofstream
The following code should compile:
#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;
}
Upvotes: 4