如何使舍入误差最小的百分比分布

How to make percentage distribution with least rounding error

本文关键字:百分比 分布 何使 舍入误差      更新时间:2023-09-26

我正在处理一个问题,我必须分配一个特定的投资组合预算来购买股票。股票价格和分配给每只股票的预算百分比是已知的,我们假设预算是10万美元。下面给出的是我目前使用的一个通用百分比计算:

data = [
  {stock: 'INFY', price: 1122.9, percent: 0.304},
  {stock: 'SUNPHARMA', price: 890.95, percent: 0.177},
  {stock: 'TCS', price: 2597.7, percent: 0.123},
  {stock: 'HCLTECH', price: 856, percent: 0.117},
  {stock: 'LUPIN', price: 2019, percent: 0.112},
  {stock: 'DIVISLAB', price: 1097, percent: 0.085}, 
  {stock: 'CADILAHC', price: 409.4, percent: 0.082}   
];
  
var budget = 100000;
var actual = 0;
for ( var i = 0; i < data.length; i++ in data ) {
  shares = Math.floor((budget * data[i].percent) / data[i].price);
  document.write( data[i].stock + ': ' );
  document.write( shares );
  document.write( '<br />' );
  spent = shares * data[i].price;
  actual += spent;  
}
document.write( '<hr />' );
document.write( 'Budget: ' + budget );
document.write( '<br />' );
document.write( 'Actual spent: ' + actual );

找到使用预算的最佳方式的方法/算法/代码应该是:

  • 预算与实际支出差异最小
  • 实际支出不应超过预算

为了满足上述两个条件,可以偏离分配给每种库存的预算百分比,但偏差应该尽可能小

再增加一个重要变量minPrice

根据百分比完成初始分配后,您可以创建一个额外的while循环,该循环在剩余股份大于或等于最低价格时继续添加股份。

var budget = 100000;
var actual = 0;
var minPrice = Infinity;
for ( var i = 0; i < data.length; i++ in data ) {
  data[i].shares = Math.floor((budget * data[i].percent) / data[i].price);    
  actual +=  data[i].shares * data[i].price;
  minPrice  = data[i].price < minPrice ? data[i].price : minPrice;    
}

var remain = budget - actual;
// attempts to add 1 share each iteration until not enough left to buy any shares
while( remain >= minPrice){
    for(var i =0; i < data.length; i++){
        if(data[i].price <= minPrice){
            data[i].shares +=1;
            remain -= data[i].price;
            actual += data[i].price
        }
    }    
}

由于初始数据按最高投资组合百分比排序,如果其价格小于预算的剩余部分,则优先级较高的股票将自动优先获得更多股票