我正在执行统计分析,以确定是否可以通过在特定时间范围内将其分解为较小的事务来隐藏更大的事务.我正在做的是将较大的数据集分解为较小的子集(此时为12的数组),然后在每个子集上运行一系列循环,以确定这些元素的任何组合是否在目标范围内累加.
这是我目前的代码:
amounts_matrix = [1380.54,9583.33,37993.04,3240.96...] matrix_amounts = amounts_matrix.length total_permutations = 0; total_hits = 0; target_range = 1 target = 130000 low_threshold = target - target_range high_threshold = target + target_range entries = [] range = 12 for(x = 0; x< matrix_amounts-(range-1); x++){ amounts = amounts_matrix.slice(x,x+range) total_amounts = range for(i = 0; i< total_amounts; i++){ entries.push(amounts[i]) totalcheck(entries) entries = [] } for(i = 0; i< total_amounts; i++){ for(j = i+1; j< total_amounts; j++){ entries.push(amounts[i]) entries.push(amounts[j]) totalcheck(entries) entries = [] } } ... for(i = 0; i< total_amounts; i++){ for(j = i+1; j< total_amounts; j++){ for(k = j+1; k< total_amounts; k++){ for(l = k+1; l< total_amounts; l++){ for(m = l+1; m< total_amounts; m++){ for(n = m+1; n< total_amounts; n++){ for(o = n+1; o< total_amounts; o++){ for(p = o+1; p< total_amounts;p++){ for(q = p+1; q< total_amounts;q++){ for(r = q+1; r< total_amounts;r++){ for(s = r+1; s< total_amounts;s++){ for(t = s+1; t< total_amounts;t++){ entries.push(amounts[i]) entries.push(amounts[j]) entries.push(amounts[k]) entries.push(amounts[l]) entries.push(amounts[m]) entries.push(amounts[n]) entries.push(amounts[o]) entries.push(amounts[p]) entries.push(amounts[q]) entries.push(amounts[r]) entries.push(amounts[s]) entries.push(amounts[t]) totalcheck(entries) entries = [] } } } } } } } } } } } } } function totalcheck(array){ total_permutations += 1; sum_amount = 0 for(z = 0; z < array.length; z++){ sum_amount += array[z] } if(sum_amount > low_threshold && sum_amount < high_threshold){ total_hits += 1 console.log(array) console.log(sum_amount.toFixed(2)) console.log("---------------") } } console.log("overall total hits = " + total_hits) console.log("overall total permutations = " + total_permutations)
我对这些for循环的广泛性感到非常尴尬,我想用一个函数来概括它,我可以告诉它运行X循环,而不是像这样构建它们.我发现的排列函数对我来说并不可行,因为它们都构建了充满可能性的数组;我想要检查目标,因为我要避免使用巨大的阵列并遇到内存问题.如何构建一个递归循环来执行此操作?
解决方法
您可以构建要检查的索引列表:
const positions = Array.from({length: 12},(_,i) => i);
现在我们需要获取最高指数,增加它,当我们到达上面的数组边界时,我们增加第二高指数,依此类推,所以我们慢慢地检查所有组合:
function next(){ for(let i = positions.length - 1; i >= 0; i--){ if(positions[i] < amounts.length){ positions[i]++; return true; } if(i == 0) return false; positions[i] = positions[i - 1] + 2; } }
如果这看起来很怪异,try it here
现在我们已经获得了索引,我们只需要总结它们引用的数组值,直到找到我们的目标为止:
do { const sum = positions.reduce((sum,pos) => sum + amounts[pos],0); if(sum === target) break; } while(next())
要获得具有不同长度的所有排列和,只需使用不同长度多次运行整个事物.