public static function FIND___Combinations__By_Sum($Array, $SUM___Limit) { // remove items greater than $SUM___Limit $Array_01 = array_filter($Array, function ($Value) use($SUM___Limit) { return $Value <= $SUM___Limit; }); rsort($Array_01); // the algorithm is usable if the number of elements is less than 20 (because set_time_limit) $N_Array_01 = count($Array_01); //The total number of possible combinations $Total_Combinations = pow(2, $N_Array_01); $Out = array(); // algorithm from http://r.je/php-find-every-combination.html // loop through each possible combination for ($i = 0; $i < $Total_Combinations; $i++) { $iCombination = array(); // for each combination check if each bit is set for ($j = 0; $j < $N_Array_01; $j++) { // is bit $j set in $i? if (pow(2, $j) & $i) { $iCombination[] = $Array_01[$j]; } } $SUM___Combination = array_sum($iCombination); $bAre_Equal = ccTXT__Type::FLOATS___Are_Equal($SUM___Combination, $SUM___Limit); if ($bAre_Equal === true) { $Out[] = $iCombination; } } return $Out; }
public function GET___NOT_Cancelled() { $SUM_Products = array(); foreach ($this->Rows as $iRow => $iProduct) { $iProduct_C0 = ccRow::SLICE___By_Cell($iProduct, 0); if (array_key_exists($iProduct_C0->Product__Id, $SUM_Products) === false) { $SUM_Products[$iProduct_C0->Product__Id] = new stdClass(); $SUM_Products[$iProduct_C0->Product__Id]->iRows = array(); } $SUM_Products[$iProduct_C0->Product__Id]->Value += $iProduct_C0->Value; $SUM_Products[$iProduct_C0->Product__Id]->iRows[] = $iRow; } $Products_NOT_Cancelled = new self(); foreach ($SUM_Products as $iProduct) { $bAre_Equal = ccTXT__Type::FLOATS___Are_Equal(0, $iProduct->Value); if ($bAre_Equal === true) { continue; } foreach ($iProduct->iRows as $iRow) { $Products_NOT_Cancelled->Rows[$iRow] = $this->Rows[$iRow]; } } return $Products_NOT_Cancelled; }