使用事务(计数)和分配约束进行优化

时间:2013-05-22 20:58:29

标签: r

我已经为我正在努力解决的优化问题创建了一些示例代码。我的想法是,我有一个长度为100的向量,代表各种资产。每个资产都有一个与之相关的因素。有一个流动资产的载体及其分配百分比。由于这是预算较高的一部分,因此该分配总和低于100%。目标是移动资产,使得分配(此问题中的70%)保持不变,并且尽可能接近目标加权平均因子值。另一个限制是可以进行不超过5个事务。这意味着您可以减少一个资产并添加另一个资产,这将是2个事务。

问题是当我运行此优化时,它会产生初始权重。我怀疑这是因为一旦进行了更改,就会违反value_constraint。有没有人对如何处理这个问题有任何建议?

这是您可以用来运行模型的代码,我已经包含了一个组合方案(测试用例),其中两个资产交换为2个不同的,如果它没有帮助你可以随意忽略它,但是这个场景满足两个约束,并且种子(1)产生更差的结果。

set.seed(1)

number_of_assets <- 100
max_transactions <- 5
sum_of_assets_value <- 0.70

factors <- runif(number_of_assets, 0, 10)

current_weights <- c(rep(sum_of_assets_value/5, 5), rep(0, number_of_assets-5))
current_factor <- current_weights %*% factors

lower_bound <- -current_weights
upper_bound <- rep(sum_of_assets_value, number_of_assets)


#test model manually with simple scenario
weights <- c(rep(0, 2), rep(sum_of_assets_value/5, 5), rep(0, number_of_assets-7)) #test case for functionality
change_count_constraint <- sum((current_weights^2 - weights^2)^2 > 0) <= max_transactions #constraint should be met with only 4 assets changed
total_value_constraint <- sum(weights) == sum_of_assets_value # constraint is met since weights sum to desired amount
new_factor <- weights %*% factors #new factor from the test case
target_factor <- 1.5 #target factor for testing
difference <- (target_factor - new_factor)^2 #square the difference, since we are attempting to minimize the absolute value of the difference
#end test case


 #this is the function for the optimization, includes the two constraints and assigns a penalty if violated
evalFunc <- function(optweights){
  new_factor <- optweights %*% factors

  count_constraint <- sum((current_weights^2 - optweights^2)^2 > 0) <= max_transactions
  value_constraint <- sum(optweights) == sum_of_assets_value
  if(count_constraint == FALSE | value_constraint == FALSE){penalty <- 100000}

  result <- (target_factor - new_factor)^2 + penalty
  result
}


optimization <- optim(current_weights, #starting weights
                      evalFunc, 
                      lower=lower_bound, upper=upper_bound, 
                      method="L-BFGS-B", 
                      control= list(maxit=5000))

0 个答案:

没有答案