Поиск подмножеств массива в PHP

У меня есть реляционная схема с атрибутами (A B C D). У меня тоже есть набор функциональных зависимостей.

теперь мне нужно определить закрытие для всех возможных подмножеств атрибутов R. Вот где я застрял. Мне нужно научиться находить подмножества (неповторяющиеся) в PHP.

мой массив хранится следующим образом.

$ATTRIBUTES = ('A', 'B', 'C', 'D').

поэтому мои подмножества должны быть

$SUBSET = ('A', 'B', 'C', 'D', 'AB', 'AC', AD', 'BC', 'BD', 'CD', 'ABC', 'ABD', 'BCD', 'ABCD')

код не должен быть чем-то большим, но по какой-то причине я не могу постараюсь не думать об этом.

3 ответов


вы желаете для набора силы $attributes? Вот что подразумевает ваш вопрос.

пример можно найти здесь (цитата Для полноты)

<?php 
/** 
* Returns the power set of a one dimensional array, a 2-D array. 
* [a,b,c] -> [ [a], [b], [c], [a, b], [a, c], [b, c], [a, b, c] ]
*/ 
function powerSet($in,$minLength = 1) { 
   $count = count($in); 
   $members = pow(2,$count); 
   $return = array(); 
   for ($i = 0; $i < $members; $i++) { 
      $b = sprintf("%0".$count."b",$i); 
      $out = array(); 
      for ($j = 0; $j < $count; $j++) { 
         if ($b{$j} == '1') $out[] = $in[$j]; 
      } 
      if (count($out) >= $minLength) { 
         $return[] = $out; 
      } 
   } 
   return $return; 
} 

используя php array_merge, мы можем иметь хорошую короткую функцию powerSet

function powerSet($array) {
    // add the empty set
    $results = array(array());

    foreach ($array as $element) {
        foreach ($results as $combination) {
            $results[] = array_merge(array($element), $combination);
        }
    }

    return $results;
}

вот обратное решение.

учитывая функцию, которая возвращает все подмножества L-длины входного набора, найдите все подмножества L-длины от L = 2 до длины входного набора данных

<?php

function subsets($S,$L) {
    $a = $b = 0;
    $subset = [];
    $result = [];
    while ($a < count($S)) {
        $current = $S[$a++];
        $subset[] = $current;
        if (count($subset) == $L) {
            $result[] = json_encode($subset);
            array_pop($subset);
        }
        if ($a == count($S)) {
            $a = ++$b;
            $subset = [];
        }
    }
    return $result;
}



$S = [ 'A', 'B', 'C', 'D'];
$L = 2;


// L = 1 -> no need to do anything
print_r($S);

for ($i = 2; $i <= count($S); $i++)
    print_r(subsets($S,$i));