Задать вопрос
  • Как задать метод перебора всех возможных сочетаний элементов?

    @webymax Автор вопроса
    Не знал, как подступиться к проблеме, но благодаря вашим советам решил задачу, по крайней мере, полным перебором :) Спасибо!
    Правда, явно требуется оптимизация, т.к. если цилиндров 9, уже начинает тормозить. Но как вклинить хотя бы один из советов Boris Korobkov...

    // факториал числа $n - кол-во перестановок элементов массива
    function factorial($n) {
        if ($n <= 1) 
            return 1; 
        return $n * factorial($n - 1);
    }
    
    // возвращает перестановку элементов в массиве по ее порядковому номеру (код Лехмера)
    function permutation($arr, $arr_keys, $arr_size, $index) {
        for ($i = 0; $i < $arr_size; $i ++) {
            $item = $index % ($arr_size - $i);
            $index = floor($index / ($arr_size - $i));
            $permutation[$arr_keys[$item]] = $arr[$item];
            array_splice($arr, $item, 1);
            array_splice($arr_keys, $item, 1);
        }
        return $permutation;
    }
    
    // распределение элементов по группам
    function divide_into_groups($num_groups, $arr, $arr_size, $ideal_height) {
        $arr_keys = array_keys($arr); // для сохранения ключей
        $arr = array_combine(range(0, $arr_size - 1), $arr); // переводим ключи в числа по порядку для оптимизации цикла ниже: "for ($j = $start..."
        
        $groups = []; // многомерный массив распределения элементов по группам
        $heights = []; // высоты групп
        $start = 0;
        for ($i = 0; $i < $num_groups; $i ++) { // перебираем группы
            for ($j = $start; $j < $arr_size; $j ++) { // перебираем элементы
                $start = $j + 1; // последний перебранный элемент
                $groups[$i][$arr_keys[$j]] = $arr[$j]; // дополняем многомерный массив
                $heights[$i] = !isset($heights[$i]) ? $arr[$j] : $heights[$i] + $arr[$j]; // увеличиваем высоту группы
                if ($heights[$i] >= $ideal_height) // достигли ИМВВ, идём в следующую группу
                    break;
            }
        }
        
        return [$groups, max($heights)];
    }
    
    
    
    $num_groups   = 3; // кол-во групп
    $arr          = array(100, 110, 150, 160, 180, 185, 200, 205, 300); // высоты (просто из головы)
    $arr_keys     = array_keys($arr); // вспомогательный массив для сохранения ключей
    $arr_size     = count($arr); // длина массива
    $num_variants = factorial($arr_size); // количество перестановок элементов массива
    $ideal_height = max(array_sum($arr) / $num_groups, max($arr), min($arr)); // ИМВВ
    
    $min_groups_height = array_sum($arr); // минимально возможная общая высота групп (начинаем просто с суммарной высоты всех элементов)
    $optimal_variant = []; // оптимальный вариант распределения по группам
    
    for ($i = 0; $i < $num_variants; $i ++) {
        // очередная перестановка элементов в массиве
        $permutation = permutation($arr, $arr_keys, $arr_size, $i);
        
        // распределение элементов по группам
        list($groups_arr, $groups_height) = divide_into_groups($num_groups, $permutation, $arr_size, $ideal_height);
        
        // если этот вариант лучше других, сохраняем его в качестве оптимального на текущий момент
        if ($min_groups_height > $groups_height) {
            $min_groups_height = $groups_height;
            $optimal_variant = $groups_arr;
        }
    }
    
    echo 'ИМВВ - '.$ideal_height.'<br /><br />';
    echo 'Оптимальный вариант распределения элементов: <pre>'.print_r($optimal_variant, true).'</pre>';
    echo 'Минимально возможная общая высота групп - '.$min_groups_height;
    Ответ написан
  • Как запретить прокрутку к результатам поиска яндекса на сайте?

    @webymax Автор вопроса
    Сам решил задачу. Див с результатами яндекса поставил в display none и разместил в самом начале html, чтобы обработчик яндекса понял, что скролить некуда. Потом по событию window onload перебрасываю див яндекса в нужно место на странице и даю ему display block.
    Ответ написан
    Комментировать