Генератор массива на 14 000 000 строк. Сохранение

politonius

Новичок
Доброго времени.
Есть скрипт генерирует комбинации лото.
$masInit = range(1, 49);
$result = [];
$combination = [];

function combinations([$myArray], $choose) {
global $result, $combination;

$n = count($myArray);

function inner ($start, $choose_, $arr, $n) {
global $result, $combination;

if ($choose_ == 0){
array_push($result,$combination);
}
else for ($i = $start; $i <= $n - $choose_; ++$i) {
array_push($combination, $arr[$i]);
inner($i + 1, $choose_ - 1, $arr, $n);
array_pop($combination);
}
}
inner(0, $choose, $myArray, $n);
return $result;
}

print_r(combinations($masInit, 6));
6 из 36 - еще выводит в массив. Записываю в файл
$masInit = range(1, 36);
$result = [];
$combination = [];

function combinations($myArray, $choose) {
global $result, $combination;

$n = count($myArray);

function inner ($start, $choose_, $arr, $n) {
global $result, $combination;

if ($choose_ == 0){
array_push($result,$combination);
} else{
for ($i = $start; $i <= $n - $choose_; ++$i) {
array_push($combination, $arr[$i]);
inner($i + 1, $choose_ - 1, $arr, $n);
array_pop($combination);
}
}
}
inner(0, $choose, $myArray, $n);
return $result;
}
$rm= combinations($masInit, 6);
unset($masInit);
$comb=[];
foreach ($rm as $v) {
$n=implode(",", $v);
//print_r ($n);
array_push($comb, $n);
}
file_put_contents('5_36.txt', print_r($comb, true));
Как разбить выполнение скрипта. на 49 не хватает памяти вообще.
И попутный вопрос, как лучше хранить эти данные в бд или же в файлах.
Возможно есть другая логика хранения этих данных.
 

ksnk

прохожий
А накой? Зачем нужно генерировать? (ответ я еще могу себе вообразить) Зачем нужно хранить готовые комбинации, если их можно перегенерировать в любой момент ? 14кк записей - это уже bigdata, там совсем другой уровень знаний предполагается.
 
  • Like
Реакции: AmdY

politonius

Новичок
Зачем нужно хранить готовые комбинации, если их можно перегенерировать в любой момент ? 14кк записей - это уже bigdata, там совсем другой уровень знаний предполагается.
Нужна раздача комбинаций пользователям рандомно из полученного массива. Но при этом исключая повторные!
Может подкинете идею реализации?
5 из 36 я получаю и сохраняю. Теперь могу работать с данным массивом по своему усмотрению.
В частности исключить из массива комбинации с последовательностью чисел до 4 или даже до трех(пример комбинации "1,2,3,4,5","1,2,3,4,28","2,3,4,5,6","2,3,4,15,35"...)
А вот на обработку 6 из 49 не хватает ресурсов.
 
Последнее редактирование:

Тугай

Новичок
Храни в базе данных, сохраняй не все скопом, а по одному сочетанию. Исключай повторы флажками какими нибудь в таблице бд. :)
 

AmdY

Пью пиво
Команда форума
Выше писали что не надо генерировать все последовательности её можно легко получить из обычного числа-номера делением по базе. надо лишь гранить эти номера комбинаций для проверки уникальности.
 

ksnk

прохожий
@politonius, Нужно определить, что на самом деле требуется в задаче.
Нужна раздача комбинаций пользователям рандомно из полученного массива. Но при этом исключая повторные!
Может подкинете идею реализации?
Для этой формулировки совсем не обязательно хранить все комбинации в базе. Достаточно хранить только те, которые уже были выданы ранее.
Схематично - решение будет таким - генерируем случайную комбинацию, проверяем, что эта комбинация подходит нам по правилам лото. Если номер не подходит - генерируем новый. С полученным номером уже лезем в базу выданных ранее комбинаций и проверяем ее на уникальность. Тут тоже может быт тонкость, например комбинации 1,2,3,4,5 и 5,4,3,2,1 с точки зрения аппарата, выдающего номера - разные, а с точки зрения человека-угадывателя номеров - одинаковые.
 

politonius

Новичок
@politonius, Нужно определить, что на самом деле требуется в задаче.

Для этой формулировки совсем не обязательно хранить все комбинации в базе. Достаточно хранить только те, которые уже были выданы ранее.
Схематично - решение будет таким - генерируем случайную комбинацию, проверяем, что эта комбинация подходит нам по правилам лото. Если номер не подходит - генерируем новый. С полученным номером уже лезем в базу выданных ранее комбинаций и проверяем ее на уникальность. Тут тоже может быт тонкость, например комбинации 1,2,3,4,5 и 5,4,3,2,1 с точки зрения аппарата, выдающего номера - разные, а с точки зрения человека-угадывателя номеров - одинаковые.
сгенерирую, допустим 10млн строк. Потом же генератор может повторять до бесконечности пока в оставшиеся 4 попадет + проверка, этож времени куча
 

AmdY

Пью пиво
Команда форума
Тебе надо просто генерировать число, если такое занято, то берёшь следующее свободное. Дальше число преобразуешь в комбинацию деля по базе. Это школьный курс информатики, преобразование десятичного числа в другую систему.
 

WMix

герр M:)ller
Партнер клуба
Код:
$ composer require drupol/phpermutations
PHP:
include './vendor/autoload.php';

$c = new \drupol\phpermutations\Generators\Combinations(range(1, 49), 7);
foreach($c->generator() as $x ) {
   //$db->insert( ..., implode(',',$x) );
}
по окончанию должно быть порядка 49! / 7! * (49-7)! = 85.900.584 записей
 
Сверху