我需要一些帮助/方向来设置PHP脚本来随机配对数组中的项目。
每次都应该随机配对这些项目。
这些项目本身不匹配(第1-1项不应与第1-1项配对)
大多数项目都有配偶(即 item1-1和item1-2)。这些物品不应与其配偶配对。
我一直在玩the second script in this post但是,我无法取得任何进展。任何帮助表示赞赏。
答案 0 :(得分:2)
非常简单的方法,但希望对您有所帮助:
( mates ,如果按数组分组(例如数组('a1','a2')),则不会配对。)
function matchUp($array) {
$result = array();
while($el = array_pop($array)) {
shuffle($array);
if (sizeof($array) > 0) {
$candidate = array_pop($array);
$result[] = array(
array_pop($el),
array_pop($candidate)
);
if (sizeof($el) > 0) {
$array[] = $el;
}
if (sizeof($candidate) > 0) {
$array[] = $candidate;
}
}
else {
$result[] = array(array_pop($el));
}
}
return $result;
}
$array = array(
array('a1', 'a2'),
array('b1', 'b2'),
array('c1'),
array('d1'),
array('e1', 'e2'),
array('f1'),
array('g1', 'g2'),
);
<强>更新强>:
foreach(matchUp($array) as $pair) {
list($a, $b) = $pair + array(null, null);
echo '<div style="border: solid 1px #000000;">' . $a . ' + ' . $b . '</div>';
}
答案 1 :(得分:1)
随机性,无法保证将达到完整正确的解决方案。
某些问题集比其他问题更容易解决。有些是不可能的。
您可以配置尝试获得良好解决方案的次数。在指定的尝试次数之后,它将返回它可以找到的最佳解决方案。
function pairUp (array $subjectArray) {
// Config options
$tries = 50;
// Variables
$bestPaired = array();
$bestUnpaired = array();
for($try = 1; $try <= 50; $try++) {
$paired = array();
$unpaired = array();
$toBePaired = $subjectArray;
foreach($subjectArray as $subjectIndex => $subjectValue) {
// Create array without $thisValue anywhere, from the unpaired items
$cleanArray = array();
foreach($toBePaired as $index => $value) {
if($value != $subjectValue) {
array_push($cleanArray, array(
'index' => $index,
'value' => $value
));
}
}
sort($cleanArray); // reset indexes in array
// See if we have any different values left to match
if(count($cleanArray) == 0) {
array_push($unpaired, $subjectValue);
continue;
}
// Get a random item from the clean array
$randomIndex = rand(0,count($cleanArray)-1);
// Store this pair
$paired[$subjectIndex] = $subjectValue . '-' . $cleanArray[$randomIndex]['value'];
// This item has been paired, remove it from unpairedItems
unset($toBePaired[$cleanArray[$randomIndex]['index']]);
sort($toBePaired);
}
// Decide if this is our best try
if(count($paired) > count($bestPaired)) {
$bestPaired = $paired;
$bestUnpaired = $unpaired;
}
// If we had no failures, this was a perfect try - finish
if(count($unpaired) == 0) { $break; }
}
// We're done, send our array of pairs back.
return array(
'paired' => $bestPaired,
'unpaired' => $bestUnpaired
);
}
var_dump(pairUp(array('a','b','c','d','e','a','b','c','d','e')));
/*
Example output:
array(2) {
["paired"]=>
array(10) {
[0]=>
string(3) "a-b"
[1]=>
string(3) "b-c"
[2]=>
string(3) "c-d"
[3]=>
string(3) "d-e"
[4]=>
string(3) "e-a"
[5]=>
string(3) "a-b"
[6]=>
string(3) "b-e"
[7]=>
string(3) "c-d"
[8]=>
string(3) "d-c"
[9]=>
string(3) "e-a"
}
["unpaired"]=>
array(0) {
}
}
*/
答案 2 :(得分:1)
案例1:如果所有元素都有配偶
如果所有元素都有配对,则以下解决方案可行,但我不知道它是否完全随机(如所有可能的输出具有相同的概率):
随机播放元素列表,保持配偶
original list = (a1,a2),(b1,b2),(c1,c2),(d1,d2)
shuffled = (c1,c2),(d1,d2),(a1,a2),(b1,b2)
将第二个配合向右移动。比赛已经形成。
shifted = (c1,b2),(d1,c2),(a1,d2),(b1,a2)
(编辑1:如果完全按照描述应用,则a1
无法与b1
匹配。因此,在转移之前,您可能想要为每对配偶投掷一枚硬币来决定他们是否应该改变秩序。)
案例2:如果只有一些元素有配偶
因为在你的问题中只有一些元素会有配偶,我想有人可以提出以下内容:
任意配对那些没有配偶的元素。应该有偶数个这样的元素。否则,元素的总数将是奇数,因此首先不能进行匹配。
original list = (a1,a2),(b1,b2),c1,d1,e1,f1 // c1,d1,e1 and f1 don't have mates
list2 = (a1,a2),(b1,b2),(c1,d1),(e1,f1) // pair them up
如案例1中那样随机移动以形成匹配。
shuffled = (e1,f1),(a1,a2),(c1,d1),(b1,b2)
shifted = (e1,b2),(a1,f1),(c1,a2),(b1,d1)
同样,我不知道这是否完全随机,但我认为它应该有用。
(编辑2:简化解决方案)
(编辑3:如果元素的总数是奇数,有人将没有匹配,所以在开头随机选择一个元素将其遗漏,然后应用上面的算法。)