为什么我的Rcpp函数每次运行都返回不同的结果?

时间:2020-02-13 22:00:01

标签: r for-loop rcpp

我是Rcpp的新手,我正在尝试创建一个函数,该函数可以按顺序使移动器根据其偏好选择选项。一旦选件用完,其他搬家将不再可用。

这是输入数据的示例。 1)小标题,显示动子,移动顺序,每个选项的偏好以及每个选项所取的金额。 2)小标题显示每个选项的ID和容量(可移动的物体数量)。

library(tidyverse)
library(Rcpp)

move.tibble <- tibble(mover_id = str_c("m_", 1:10),
                      mover_order = 1:10,
                      mover_amount = 1,
                      mover_option_id = str_c("o_", 1:10),
                      mover_option_rank = 1:10) %>% 
  complete(nesting(mover_id, mover_order, mover_amount), nesting(mover_option_id, mover_option_rank)) %>% 
  arrange(mover_order)

capacities <- tibble(cap_option_id = str_c("o_", 1:10),
                     cap_option_cap = 2)

这是R中的实现:

choose_R <- function(mover_id = move.tibble$mover_id,
                     mover_order = move.tibble$mover_order,
                     mover_amount = move.tibble$mover_amount,
                     mover_option_id = move.tibble$mover_option_id,
                     mover_option_rank = move.tibble$mover_option_rank,
                     cap_option_id = capacities$cap_option_id,
                     cap_option_cap = capacities$cap_option_cap){


  mover_order_unique <- unique(mover_order)
  mover_choices <- character(length = length(mover_order_unique))



  for (i in mover_order_unique){

    mover_id_i <- mover_id[mover_order == i][1]
    mover_amount_i <- mover_amount[mover_order == i][1]

    cap_option_id_i <- cap_option_id[cap_option_cap >= mover_amount_i]

    mover_option_id_i <- mover_option_id[mover_order == i & mover_option_id %in% cap_option_id_i]
    mover_option_rank_i <- mover_option_rank[mover_order == i  & mover_option_id %in% cap_option_id_i]

    mover_choice_i <- mover_option_id_i[which.min(mover_option_rank_i)]
    mover_choices[i] <- mover_choice_i

    cap_option_cap[cap_option_id == mover_choice_i] <- cap_option_cap[cap_option_id == mover_choice_i] - mover_amount_i

  }

  return(mover_choices)


}

因此,该函数为每个mover_id返回一个cap_option_ids向量。由于每个选项可以容纳2个移动器,并且所有移动器都更喜欢选项1,然后选择2,然后选择3,依此类推。结果应该是前两个移动器获得选项1,接下来的2个获得选项2,依此类推。这就是我用R函数得到的。

choose_R(mover_id = move.tibble$mover_id,
                      mover_order = move.tibble$mover_order,
                      mover_amount = move.tibble$mover_amount,
                      mover_option_id = move.tibble$mover_option_id,
                      mover_option_rank = move.tibble$mover_option_rank,
                      cap_option_id = capacities$cap_option_id,
                      cap_option_cap = capacities$cap_option_cap)

"o_1" "o_1" "o_2" "o_2" "o_3" "o_3" "o_4" "o_4" "o_5" "o_5"

我尝试了以下Rcpp中的实现。我不确定发生了什么问题,因为它似乎无法产生正确的结果。更令人困惑的是,每次我运行该函数时,结果都会改变。知道发生了什么吗?我可能正在犯一些Rcpp新手错误...

choose_CPP <- cppFunction('CharacterVector Csim(
CharacterVector mover_id, 
IntegerVector mover_order, 
NumericVector mover_amount, 
CharacterVector mover_option_id, 
IntegerVector mover_option_rank,
CharacterVector cap_option_id,
NumericVector cap_option_cap_orig){

// [[Rcpp::plugins("cpp11")]]

NumericVector cap_option_cap = clone(cap_option_cap_orig);

IntegerVector mover_order_unique = sort_unique(mover_order);
CharacterVector mover_choices;

CharacterVector mover_id_i_multi;
String mover_id_i;

NumericVector mover_amount_i_multi;
double mover_amount_i;

CharacterVector cap_option_id_i;

CharacterVector mover_option_id_i;
IntegerVector mover_option_rank_i;

CharacterVector mover_choice_i;
String mover_choice_i_str;

IntegerVector cap_log;
int cap_log_int;
IntegerVector cap_option_cap_i;
int cap_option_cap_i_int;

 for(int i = 1; i != 10; ++i){

    mover_id_i_multi = mover_id[mover_order == i];
    mover_id_i = mover_id_i_multi[1];

    mover_amount_i_multi = mover_amount[mover_order == i];
    mover_amount_i = mover_amount_i_multi[1];

    cap_option_id_i = cap_option_id[cap_option_cap >= mover_amount_i];

    mover_option_id_i = mover_option_id[mover_order == i & in(mover_option_id, cap_option_id_i)];
    mover_option_rank_i = mover_option_rank[mover_order == i & in(mover_option_id, cap_option_id_i)];


    mover_choice_i = mover_option_id_i[which_min(mover_option_rank_i)];
    mover_choice_i_str = mover_option_id_i[which_min(mover_option_rank_i)];
    mover_choices.insert(i-1, mover_choice_i_str);

    cap_log = match(mover_choice_i, cap_option_id);
    cap_log_int = cap_log[1];
    (cap_option_cap[cap_log_int])) - (as<NumericVector>(mover_amount_i_multi[1]));
    cap_option_cap[cap_log_int] = cap_option_cap[cap_log_int] - mover_amount_i_multi[1];
 }

return mover_choices;

}')

正在运行rcpp函数...

choose_CPP(mover_id = move.tibble$mover_id,
         mover_order = move.tibble$mover_order,
         mover_amount = move.tibble$mover_amount,
         mover_option_id = move.tibble$mover_option_id,
         mover_option_rank = move.tibble$mover_option_rank,
         cap_option_id = capacities$cap_option_id,
         cap_option_cap_orig = capacities$cap_option_cap)

我正在使用Rcpp版本1.0.3。

0 个答案:

没有答案