2016-04-05 38 views
-1

我有可以通過它的一個被分成3個不同的組的陣列的屬性:排列不同組的陣列,以便它的元素沒有鄰居相似的組

$shuffleMeGood = array(
    0 => array('id' => '1', 'group' => 'banana'), 
    1 => array('id' => '2', 'group' => 'banana'), 
    2 => array('id' => '3', 'group' => 'banana'), 
    3 => array('id' => '4', 'group' => 'airplane'), 
    4 => array('id' => '5', 'group' => 'coconut'), 
    5 => array('id' => '6', 'group' => 'coconut') 
    ... 
); 

基團的大小可以變化,可能有7個椰子元素和5個飛機元素等等。我怎樣才能以這樣一種方式對數組進行洗牌,即同一組的鄰居沒有發生或發生的可能性最小?

我試圖將它們分成3個不同的數組,然後再根據它們的大小按比例重新合併它們。但是對於接近比例的團隊,我最終會得到一組團隊。

+0

我使用PHP 5.2.6 – Kana

+0

這不是PHP,這是JSON。 – Anthony

+2

這不是https://en.wikipedia.org/wiki/Graph_coloring的變體嗎? – Tibrogargan

回答

0

編輯:根據OP對他如何處理剩餘物品的評論調整了答案。在下面保留我原來的答案。

<?php 
// Your array changed to PHP with some added items 
$a = array(
    array(
     'id'=>1, 
     'group'=>'banana' 
    ), 
    array(
     'id'=>2, 
     'group'=>'banana' 
    ), 
    array(
     'id'=>3, 
     'group'=>'banana' 
    ), 
    array(
     'id'=>4, 
     'group'=>'airplane' 
    ), 
    array(
     'id'=>5, 
     'group'=>'coconut' 
    ), 
    array(
     'id'=>6, 
     'group'=>'coconut' 
    ), 
    array(
     'id'=>7, 
     'group'=>'coconut' 
    ), 
    array(
     'id'=>8, 
     'group'=>'coconut' 
    ), 
    array(
     'id'=>9, 
     'group'=>'coconut' 
    ), 
    array(
     'id'=>10, 
     'group'=>'coconut' 
    ), 
); 

// We want to know each of group there are 
// We also want to arrange the items in a new "perGroup" array. 
$counts = array(); 
$perGroup = array(); 
foreach($a as $key=>$value){ 
    // Avoid PHP undefined notices 
    if(isset($counts[$value['group']])){ 
     $counts[$value['group']]++; 

    }else{ 
     $counts[$value['group']] = 1; 
    } 

    // Avoid PHP undefined notices 
    if(isset($perGroup[$value['group']])){ 
     $perGroup[$value['group']][] = $value; 
    }else{ 
     $perGroup[$value['group']] = array(); 
     $perGroup[$value['group']][] = $value; 
    } 
} 

// Sort the count from largest to lowest 
arsort($counts); 
// Get all the group names 
$keys = array_keys($counts); 
// We'll have as many unique groups as the SECOND largest item. 
$nbOfUniques = $counts[$keys[1]]; 
// Calculate how many of the largest we need to put in each unique 
$nbOfLargestPerUnique = ceil($counts[$keys[0]]/$nbOfUniques); 
// Get the largest group name for easier use 
$largestGroupName = $keys[0]; 

$finalArray = array(); 
// Loop for how many unique groups we have 
for ($i = 1; $i <= $nbOfUniques; $i++) { 
    // For each group... 
    foreach($keys as $k=>$v){ 
     // If its the largest 
     if($v == $largestGroupName){ 
      // Add as many as needed 
      for ($j = 1; $j <= $nbOfLargestPerUnique; $j++) { 
       // Make sure we actually have an item, as the number is not always exact. 
       // Using array_shift() to reduce our array 
       if(($item = array_shift($perGroup[$v])) !== NULL){ 
        $finalArray[] = $item; 
       } 
      } 
     }else{ 
      // Not the largest group, just add one 
      if(($item = array_shift($perGroup[$v])) !== NULL){ 
       $finalArray[] = $item; 
      } 
     } 
    } 
} 

echo '<pre>'; 
var_dump($finalArray); 
echo '</pre>'; 
?> 

ORIGINAL: 我會用一個遞歸函數

我們會均勻地塗抹在對方通過計算,我們多少可以把每使用一些中間陣列分配的最大羣體兩個數組:最後一個,初始一個得到的拷貝越來越小,直到我們處理這一切:

<?php 
// Your array changed to PHP with some added items 
$a = array(
    array(
     'id'=>1, 
     'group'=>'banana' 
    ), 
    array(
     'id'=>2, 
     'group'=>'banana' 
    ), 
    array(
     'id'=>3, 
     'group'=>'banana' 
    ), 
    array(
     'id'=>4, 
     'group'=>'airplane' 
    ), 
    array(
     'id'=>5, 
     'group'=>'coconut' 
    ), 
    array(
     'id'=>6, 
     'group'=>'coconut' 
    ), 
    array(
     'id'=>7, 
     'group'=>'coconut' 
    ), 
    array(
     'id'=>8, 
     'group'=>'coconut' 
    ), 
    array(
     'id'=>9, 
     'group'=>'coconut' 
    ), 
    array(
     'id'=>10, 
     'group'=>'coconut' 
    ), 
); 

// Our recursive function 
// $array is the array to be ordered (in our case, $a) 
// $orderedArray is needed for the recusivity part 
function orderArray($array, $orderedArray = array()){ 
    // Remember the last processed group 
    $lastGroup = ''; 

    // Loop on all $array's items 
    foreach($array as $key=>$value){ 
     // If NOT the same as the last group 
     if($value['group'] != $lastGroup){ 
      // Add it to our orderedArray 
      $orderedArray[] = $value; 
      // Remember its group 
      $lastGroup = $value['group']; 
      // Remove it from the original array, as it has already been processed 
      unset($array[$key]); 
     } 
    } 
    // There are still items to be processed 
    if(count($array) > 0){ 
     // Call ourselves again, with the same arrays 
     return orderArray($array, $orderedArray); 
    }else{ 
     // Done processing, return the $orderedArray 
     return $orderedArray; 
    } 
} 

echo '<pre>'; 
var_dump(orderArray($a)); 
echo '</pre>'; 
?> 

然而,如果一組清晰地租稅其他人(如c在我的例子中是oconut),最後你會得到一堆椰子。

希望它有幫助。

+0

謝謝,但是它的結果幾乎與我的版本相同。正如我所說,我也結束了與最後一組的塊.. – Kana

+0

那麼真的沒有辦法避免它,如果你有一個組超過其他人。你想用附加物品做什麼? – Growiel

+0

它們應該在陣列中均勻分佈。相反的: 椰子 - 飛機 - 香蕉 - 椰子 - 香蕉 - 椰子 - 香蕉 - 椰子 - 椰子 - 椰子 ......應該導致: 椰子 - 飛機 - 椰子 - 香蕉 - 椰子 - 椰子 - 椰子香蕉 - 椰子 - 香蕉 – Kana

相關問題