вывод элементов массива по вероятностям

Статус
В этой теме нельзя размещать новые ответы.

SiMM

Новичок
Сдаётся мне, что задача вообще одной встроенной php-функцией решается. Но, разумеется, пока топикстартер не поставит задачу чётко можно только бессмысленно тратить время, гадая на кофейной гуще.
 

antonim

Новичок
Задача состоит в сортировке массива таким образом, чтобы адреса пользователей каждого из почтовых серверов были распределены равномерно по всему массиву. я упростил до a,b,c - типы адресов (mail.ri, ya.ru и т.д.)
 

Adelf

Administrator
Команда форума
Эх.. а я уж думал что-то сложное :)
Тут любой почти способ подойдет. даже array_rand
 

antonim

Новичок
array_rand

тут вобще никаким боком не будет работать. Вот, что сделал пока.


PHP:
$array['mail'] = array( '[email protected]','[email protected]','[email protected]','[email protected]','[email protected]', '[email protected]', '[email protected]', '[email protected]', 'sis@[email protected]', '[email protected]', '[email protected]', '[email protected]', '[email protected]');


$z=0;
foreach ($array['mail'] as $key => $v){
	
	$server = substr($v,strripos($v,"@") + 1,strlen($v) - strripos($v,"@"));
	
	$flag = 1;
	if ($z > 0)
	{
		foreach ($server_array['name'] as $index => $mail)
		{
			if ($mail == $server) {$flag = 0; $array['type'][$key] = $index;}
		}
	}
	if ($flag == 1){
		$server_array['name'][$z]=$server;
		$array['type'][$key] = $z;
		$z++;
	}
	
	echo $v."   type = ".$array['type'][$key]."<br>";
}

echo "<br><br>";

foreach ($server_array['name'] as $key => $v){
	
	$buf =0;	
	foreach ($array['type'] as $type){
		if ($type == $key) {$buf++;}
	}	
	$server_array['count'][$key] = $buf;
		
	echo $v." count = ".$server_array['count'][$key]."<br>";
}

$nod = min($server_array['count']);

foreach ($server_array['count'] as $key => $v){
	$server_array['count_period'][$key] = floor($v/$nod);
	$server_array['rest'][$key] =  $v%$nod;
	echo "DIV = ".$server_array['count_period'][$key]." MOD = ".$server_array['rest'][$key]."<br>"; 	
}
лока логика в том, что бью на повторяющиеся блоки. Теперь нужно сделать именно равномерное распределение внутри блока..

Вы говорите много способоа?? Покажите плз хоть один который рассортирует так как я показал в примере, буду ОЧЕНЬ признателен. Т.к. не догоняю... :(
 

dimagolov

Новичок
array_rand

тут вобще никаким боком не будет работать.
идея с array_rand в том, что если адресов много, то их случайное распределение даст относительную редкость повторов одних и тех же доменов.
 

antonim

Новичок
нужна четкая система. random не отделаешься...

вот рендом:

shuffle ($array['mail']);
foreach ($array['mail'] as $v){
echo $v."<br>";
}

но нужно чтобы готовый метод сортировал массив как я указал в примере. Именно так.
 

dimagolov

Новичок
antonim, ну и скажи, на реальных твоих данных, как часто оказываются подряд после shuffle адреса из одного и того же домена? можно сделать в цикле и посичтать число таких случаев на автомате. ИМХО если кол-во повторений будет < 5% то выдумывать что-то умнее нету смысла
 

SiMM

Новичок
antonim
Нарисуйте один из вариантов для примера a, a, a, a, b, c
 

antonim

Новичок
тут ничего т.к. их нечем "разбавить".
Всем спасибо наконец РОДИЛ алгоритм на котором прально работает все.

-~{}~ 21.08.09 22:09:

вот полная постановка задачи:
Имеется массив почтовых адресов пользователей, зарегистрированных на разных почтовых серверах (yahoo.com, msn.com, mail.ru и т.д.)

Порядок нахождения адресов в исходном массиве не определен. Задача состоит в сортировке массива таким образом, чтобы адреса пользователей каждого из почтовых серверов были распределены равномерно по всему массиву.

Если количество адресов для разных серверов сильно отличается (например @yahoo.com – 90, @msn.com = 10), то адреса @msn.com должны быть равномерно распределены среди адресов @yahoo.com, то есть среди каждых десяти адресов @yahoo.com должно находится не более одного адреса @msn.com

Пример:
Исходный массив:
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]

Отсортированный массив:
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]


вот мой скрипт:
PHP:
$array['mail'] = array( '[email protected]','[email protected]','[email protected]','[email protected]','[email protected]', '[email protected]', '[email protected]', '[email protected]', 'sis@[email protected]', '[email protected]', '[email protected]', '[email protected]', '[email protected]');


$z=0;
foreach ($array['mail'] as $key => $v){
	
	$server = substr($v,strripos($v,"@") + 1,strlen($v) - strripos($v,"@"));
	
	$flag = 1;
	if ($z > 0)
	{
		foreach ($server_array['name'] as $index => $mail)
		{
			if ($mail == $server) {$flag = 0; $array['type'][$key] = $index;}
		}
	}
	if ($flag == 1){
		$server_array['name'][$z]=$server;
		$server_array['type'][$z]=$z;
		$array['type'][$key] = $z;
		$z++;
	}
	
	echo $v."   type = ".$array['type'][$key]."<br>";
}

$sum = $key+1;

/* простое перемешивание
shuffle ($array['mail']);
foreach ($array['mail'] as $v){
	echo $v."<br>";
}
*/


echo "<br><br>";

foreach ($server_array['name'] as $key => $v){
	
	$buf = 0;	
	foreach ($array['type'] as $type){
		if ($type == $key) {$buf++;}
	}	
	$server_array['count'][$key] = $buf;
	$server_array['step'][$key] = round(($sum - $buf)/$buf+1,2);
			
	echo $v." count = ".$server_array['count'][$key]." step = ".$server_array['step'][$key]." type=".$server_array['type'][$key]."<br>";
}
echo "<br><br><br> sum=".$sum."<br><br><br>";


arsort($server_array['count']);

$new_array = array();
foreach ($server_array['count'] as $key => $v){
	
	//echo $v." name = ".$server_array['name'][$key]." step = ".$server_array['step'][$key]." type=".$server_array['type'][$key]."<br>";
 	
 	$step = 0;
	foreach ($array['type'] as $k => $val){
		if ($server_array['type'][$key] == $val){
			//echo $array['mail'][$k]."<br>";
			$round_step = round($step,0);
			
			$z=0; $n=1;
			
			
			
			$round_step_old = $round_step;
			while ($new_array[$round_step]){
				 
				if ($z==0){ if (($round_step_old + $n) < $sum) {$round_step = $round_step_old + $n;} $z=1; }
				elseif ($z==1){ if ( ($round_step_old - $n) >= 0) {$round_step = $round_step_old - $n;}  $z=0; $n++;}
				if ((($round_step_old + $n) >= $sum) AND (($round_step_old - $n) < 0)){
					//echo "ERROR!!! n=".$n."round_step_old=".$round_step_old."round_step=$round_step"."<br>"; 
					echo "ERROR!";
					continue;
				}
			}
					
			$new_array[$round_step] = $array['mail'][$k];
			$step = $step + $server_array['step'][$key];
		}
	}
}

for ($i=0; $i<$sum; $i++) {
	echo $new_array[$i]."<br>";
}
Все работает хорошо. Выслушаю критику по поводу сделанного мной. Спасибо.
 
Статус
В этой теме нельзя размещать новые ответы.
Сверху