我最近将一些R代码转换为Rcpp函数。我正在模拟人们在停车场停车。我有一个功能,根据他们进入的门和停车场的完整性来选择一个人将要停放的地段。
#include <Rcpp.h>
#include <numeric>
#include <chrono>
// [[Rcpp::plugins(cpp11)]]
using namespace Rcpp;
// [[Rcpp::export]]
std::string pickLotcpp(std::string gate,DataFrame dist,DataFrame curr,NumericVector maxDist = 0.005) {
std::vector<std::string> gates = Rcpp::as<std::vector<std::string> >(dist["inGate"]);
std::vector<std::string> lots = Rcpp::as<std::vector<std::string> >(dist["lot"]);
NumericVector d = dist["dist"];
std::vector<std::string> currLots = Rcpp::as<std::vector<std::string> >(curr["Lot"]);
NumericVector cap = curr["Cap"];
NumericVector util = curr["Util"];
NumericVector percFree = (cap - util)/cap;
std::vector<std::string> relLot;
NumericVector relD;
int n = gates.size();
for(int i = 0; i < n; i++){
if(gates[i] == gate){
if(d[i] <= maxDist[0]){
relLot.push_back(lots[i]);
relD.push_back(pow(d[i],-2));
}
}
}
n = relLot.size();
int n2 = currLots.size();
NumericVector relPerc;
for(int i = 0; i < n; i++){
for(int j = 0; j < n2; j++){
if(relLot[i] == currLots[j]){
relPerc.push_back(percFree[j]);
}
}
}
relD = relD*relPerc;
NumericVector csV(relD.size());
std::partial_sum(relD.begin(), relD.end(), csV.begin());
NumericVector::iterator mv;
mv = std::max_element(csV.begin(),csV.end());
double maxV = *mv;
unsigned seed = std::chrono::system_clock::now().time_since_epoch().count();
std::mt19937 gen(seed);
std::uniform_real_distribution<> dis(0, maxV);
double rv = dis(gen);
int done = 0;
int i = 0;
std::string selGate;
while(done < 1){
if(csV[i] >= rv){
selGate = relLot[i];
done = 1;
}
i++;
}
return selGate;
}
在R:
中效果很好fakeDist = structure(list(inGate = c("A", "A", "B", "B"), lot = c("Y", "Z", "Y", "Z"), dist = c(0.001, 0.003, 0.003, 0.001)), .Names = c("inGate", "lot", "dist"), row.names = c(NA, 4L), class = c("tbl_df", "tbl", "data.frame"))
fakeStatus = structure(list(Lot = c("Y", "Z"), Cap = c(100, 100), Util = c(0, 0)), .Names = c("Lot", "Cap", "Util"), row.names = c(NA, 2L), class = c("tbl_df", "tbl", "data.frame"))
pickLotcpp("A",fakeDist,fakeStatus)
#> [1] "Y"
现在我正在尝试编写将遍历所有门活动并按顺序停放人的功能。所以我有这个Rcpp函数:
// [[Rcpp::export]]
List test(DataFrame records, DataFrame currentLoc, DataFrame dist,
DataFrame currentStatus, NumericVector times){
List out(times.size());
NumericVector recID = records["ID"];
NumericVector recTime = records["Time"];
NumericVector recDir = records["Dir"];
std::vector<std::string> Gate = Rcpp::as<std::vector<std::string> >(records["Gate"]);
NumericVector currState = currentLoc["State"];
std::vector<std::string> currLot = Rcpp::as<std::vector<std::string> >(currentLoc["Lot"]);
out[0] = pickLotcpp(Gate[0],dist,currentStatus);
return out;
}
这是在pickLotcpp下的同一个文件中。它编译得很好,但是当被调用导致R崩溃时。
fakeData = structure(list(ID = c(1, 2, 3), Time = c(1, 2, 3), Dir = c(1, 1, 1), Gate = c("A", "A", "B")), .Names = c("ID", "Time", "Dir", "Gate"), row.names = c(NA, 3L), class = c("tbl_df", "tbl", "data.frame"))
fakeLoc = structure(list(ID = c(1, 2, 3), State = c(0, 0, 0), Lot = c("", "", "")), .Names = c("ID", "State", "Lot"), row.names = c(NA, 3L), class = c("tbl_df", "tbl", "data.frame"))
a = test(fakeData, fakeLoc, fakeDist, fakeStatus, 10)
我已经编写了其他函数调用函数的Rcpp代码,它们工作正常。我唯一能想到的是,我传递的是一个直接输入到另一个函数的DataFrame,但我找不到任何我说不能的东西。我不是一位专业的C ++程序员 - 几周前我刚刚开始攻击它,这让我很难过。
如何从pickLotcpp
调用test
传递所需的距离和状态数据框?
答案 0 :(得分:1)
似乎与Rcpp无关。
你能仔细检查一下
selGate = relLot[i];
relLot
可能是空的。