我想计算混合比率,但我遇到运行时问题, 似乎7个精度为4%的组件是PHP的限制... 所以我试图找到一种方法来避免多余的循环,以便更快地计算。
我有成分和限制(这里6)。我想找到所有的组合 在一个有限的步骤(这里没有显示)我只是订购这些 点击价格后。我想找到最便宜的组合 ingredient_x低于6。
我尝试了两种方法,做到这一点,只需简单地总结成分,然后一步一步地提前中止循环(到安全循环)。
<?php
$beginn = microtime(true);
$loops = 0;
$hits = 0;
$m = array();
// 1. TEST
$component[0]['ingredient_x'] = 6.95;
$component[1]['ingredient_x'] = 65.7;
$component[2]['ingredient_x'] = '';
$component[3]['ingredient_x'] = 2;
$component[4]['ingredient_x'] = '';
$component[5]['ingredient_x'] = '';
$component[6]['ingredient_x'] = '';
/*
Results:
With abort Loops
Loops: 285.188
Hits: 285.077
Seconds: 1,707 sec.
Without:
Loops: 736.281
Hits: 285.077
Seconds: 6,582 sec.
*/
// 2. TEST
$component[0]['ingredient_x'] = 6.95;
$component[1]['ingredient_x'] = 6.7;
$component[2]['ingredient_x'] = '';
$component[3]['ingredient_x'] = 2;
$component[4]['ingredient_x'] = '';
$component[5]['ingredient_x'] = '';
$component[6]['ingredient_x'] = '';
/*
Results:
With abort Loops
Loops: 735.244
Hits: 735.167
Seconds: 4,467 sec.
Without:
Loops: 736.281
Hits: 735.167
Seconds: 3,191 sec.
*/
$abort_loops = 1;
for ($m[0] = 0; $m[0] <= 100; $m[0] += 4) {
for ($m[1] = 0; $m[1] <= (100 - $m[0]); $m[1] += 4) {
for ($m[2] = 0; $m[2] <= (100 - $m[0] - $m[1]); $m[2] += 4) {
for ($m[3] = 0; $m[3] <= (100 - $m[0] - $m[1] - $m[2]); $m[3] += 4) {
for ($m[4] = 0; $m[4] <= (100 - $m[0] - $m[1] - $m[2] - $m[3]); $m[4] += 4) {
for ($m[5] = 0; $m[5] <= (100 - $m[0] - $m[1] - $m[2] - $m[3] - $m[4]); $m[5] += 4) {
$m[6] = (100 - $m[0] - $m[1] - $m[2] - $m[3] - $m[4] - $m[5]);
$loops++;
if ($abort_loops) {
$r = 0;
$do_break = 0;
// Checking ingredient_x sum, component by component
for ($i = 0; $i <= 6; $i++) {
$r += ($m[$i] * ($component[$i]['ingredient_x'] / 100));
// If Limit is reached, end all following loops
if ($r > 6) {
$m[$i] = 100;
// Cant break here, because of inner loop ...
$do_break = 1;
}
}
// ... so do it outside
if ($do_break) {
break;
}
$hits++;
} else {
// just sum ingredient_x
$r = ($m[0] * ($component[0]['ingredient_x'] / 100)) +
($m[1] * ($component[1]['ingredient_x'] / 100)) +
($m[2] * ($component[2]['ingredient_x'] / 100)) +
($m[3] * ($component[3]['ingredient_x'] / 100)) +
($m[4] * ($component[4]['ingredient_x'] / 100)) +
($m[5] * ($component[5]['ingredient_x'] / 100)) +
($m[6] * ($component[6]['ingredient_x'] / 100));
if ($r <= 6) {
$hits++;
}
}
}
}
}
}
}
}
print('Loops: ' . number_format($loops, 0, '', '.') . '<br>');
print('Hits: ' . number_format($hits, 0, '', '.') . '<br>');
print('Seconds: ' . number_format((microtime(true) - $beginn), 3, ',', '') . ' sec.');
?>
但这取决于成分。正如您在测试1中看到的那样 (中止循环快5倍)和测试2(简单的求和方式更快)。
是否有可能使这些循环更快?更好&#34;中止循环&#34;码? 有没有更快的方法找到最便宜的组合?
答案 0 :(得分:0)
一种方法是使用简单的数学来改进你的总结:
// just sum ingredient_x
$r = (
$m[0] * $component[0]['ingredient_x'] +
$m[1] * $component[1]['ingredient_x'] +
$m[2] * $component[2]['ingredient_x'] +
$m[3] * $component[3]['ingredient_x'] +
$m[4] * $component[4]['ingredient_x'] +
$m[5] * $component[5]['ingredient_x'] +
$m[6] * $component[6]['ingredient_x']
);
;
if ($r <= 600) {
$hits++;
}
如果你只是将限制提高到你的限制的100倍,那么所有的除以100的除数就可以完全放弃。
a0 / 100 + a1 / 100 + a2/100 + ... a6/100
与
相同(a0 + a1 + a2 + ... + a6) /100
这只需要一个师而不是7个。
如果您将限制调整为100 *您的限制,即使是这种划分也是可以的。
我的机器的速度提升约为10-15%。