Алгоритм распределения комнаты с использованием PHP - PullRequest
0 голосов
/ 31 октября 2010

Мне нужна помощь с алгоритмом, чтобы распределять комнаты людям. Мне нужно перебрать список комнат, чтобы назначить комнату человеку, и после того, как четвертый человек назначен на комнату, он должен быть вне списка (должен быть недоступен). Мне еще не повезло с функциями перетасовки и сортировки PHP.

Любая помощь (указатели, ссылки и т. Д.) Будет принята с благодарностью.

Ответы [ 2 ]

3 голосов
/ 31 октября 2010

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

Как уже сказал Джек, попробуйте разработать свой алгоритм, прежде чем пытаться реализовать его в коде.Если вам сложно понять это, просто представьте сценарий и попробуйте написать простые правила для его решения в реальной жизни

Допустим, у меня есть прихожая с 10 комнатами.Каждая комната может вместить до 4 человек.Тогда 35 человек появляются и хотят быть назначенными на комнаты.Как бы я это сделал?

Я бы, вероятно, начал с начала коридора и заполнил первую комнату, затем заполнил следующую комнату и продолжал, пока у меня не закончились люди или комнаты (в зависимости от того, что наступило раньше).).Преимущество этого решения состоит в том, что не нужно ходить очень далеко по коридору, а в том, что нужно собирать 4 человек в одну комнату, а не распределять их равномерно.

Если вы решили распределить их равномерно, то вам нужнопоставить одну в первой комнате, затем одну во второй комнате и т. д. Делайте это до тех пор, пока не выйдете из комнат, а затем возвращайтесь в каждую комнату, помещая второго человека.

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

В PHP, если вам нужно несколько чисел, которые связаны и упорядочены (каккомнаты в прихожей будут) вы используете массив.Это верно, когда у вас есть несколько ЛЮБЫХ переменных, которые должны быть связаны друг с другом и поддерживать их соответствующий порядок.

$rooms = array(0, 0, 0, 0, 0); // 5 rooms, all with 0 people in them

Если ваша комната должна знать , кто находится вкомната (если им необходимо различать разных гостей), тогда вы можете рассматривать каждую отдельную комнату как массив из 4 элементов, каждый элемент которого представляет человека и может идентифицировать этого человека.

$rooms = array(
    array(null, null, null, null),
    array(null, null, null, null),
    array(null, null, null, null),
    array(null, null, null, null),
    array(null, null, null, null)
);

ПослеВы создали свои комнаты, у вас есть определенное количество людей, которые ждут, чтобы войти в комнату.Поскольку каждый человек считается только 1, если вам не нужно запоминать дополнительную информацию о каждом человеке (например, его имя, возраст и т. Д.), Вы сможете увидеть очень удобный способ представления людей.

$peopleNotInARoomYet = 10;

Если вам нужно необходимо запомнить дополнительную информацию об этих людях (предположим, после назначения комнат вам задают вопрос «В какой комнате Боб?»), Вам понадобится что-то гораздо более умное.Возможно, массив классов, каждый класс представляет человека.Если, конечно, человек должен быть представлен только одной переменной.Затем вы можете сварить их, используя только массив.

$peopleNotInARoomYet = array("Bob", "Sally", "Bill", "Mary");
//or
$peopleNotInARoomYet = array(new Person('Bob'), new Person('Sally'), new Person('Bill'), new Person('Mary'));

Обратите внимание, что второй метод требует, чтобы класс Person уже был определен, и он может стать очень запутанным, если вы не будете осторожны.

Как только у вас появится возможность представлять людей, вы захотите пройтись по каждому человеку, чтобы найти ему комнату.Если люди представлены одним числом, это будет выглядеть следующим образом:

while($peopleNotInARoomYet > 0){
    // Assign a room
    $peopleNotInARoomYet--;
}

Если люди представлены в виде массива, вы можете рассмотреть функцию PHP array_pop().

PHP.net array_pop manual

$nextPerson = array_pop($peopleNotInARoomYet){
while($nextPerson != NULL){
    // Assign a room
    $nextPerson = array_pop($peopleNotInARoomYet);
}

Теперь, имея возможность представлять комнаты и людей, ваша новая задача - взять наше определение назначения сверху и превратить его в код.Итак, давайте посмотрим на наш первый (и, возможно, более простой) метод.Мы помещаем людей в комнату, пока она не заполнится, затем идем в следующую комнату.

Это на самом деле создает несколько алгоритмических проблем.Во-первых, как вы «помещаете кого-то в комнату»?

Ответ на этот вопрос фактически зависит от того, какое определение комнаты мы использовали.Если у нас просто был массив целых чисел (случай, когда нам небезразлично, сколько людей находится в комнате, но не волнует , кто находится в комнате), то нам нужно добавить одно к этому целому числу.

Если у нас был массив из 4-х элементных массивов, то нам нужно найти первый пустой элемент и поместить человека в этот элемент.Помещение человека в непустой элемент заменит человека, который был там раньше.

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

Итак, вот наше определение комнаты, человека и начала нашего цикла:

<?php
    $rooms = array(0, 0, 0, 0, 0); // 5 empty rooms
    $peopleNotInRoomsYet = 14; // We'll choose a number that won't divide evenly

    while($peopleNotInRoomsYet > 0){
        // Assign a room
        $peopleNotInRoomsYet --;
    }
?>

И мы знаем, что после того, как мы выбрали, в какую комнату поместить кого-то, на самом деле их размещение включает в себя следующее:

$rooms[$roomNumber]++;

Так что теперь давайте вернемся к нашему первоначальному определению проблемыпосмотрим, где мы остановились.Мы хотим заполнить первую комнату, затем вторую, затем третью и т. Д.

Итак, сначала нам нужен был способ определить, как заполнить комнату.Хорошее заполнение комнаты включает в себя помещение людей (сделано), пока оно не заполнится (не сделано).Так что теперь нам нужен способ проверить и убедиться, что комната заполнена.

if($rooms[$roomNumber] == 4)

должно работать хорошо.Так что теперь у нас есть способ «заполнить комнату, пока она не заполнится» ... Но после этого нам нужно начать с следующей комнаты.Это означает, что мы должны всегда знать, какую комнату мы сейчас заполняем.Если есть что-то новое, что нам нужно знать, нам нужна новая переменная для этого.Давайте назовем эту переменную $roomNumber.Мы начнем с $roomNumber = 0; (первая комната в массиве) и продолжим до 5.Поскольку нет шестой комнаты (элемент 5), то, если $roomNumber когда-либо станет 5, у нас будет слишком много людей.

<?php
    $rooms = array(0, 0, 0, 0, 0); // 5 empty rooms
    $peopleNotInRoomsYet = 14; // We'll choose a number that won't divide evenly
    $roomNumber = 0;

    while($peopleNotInRoomsYet > 0){ // If there are people waiting...
        if($rooms[$roomNumber] == 4){ // If the room is full...
            $roomNumber ++; // Go to the next room
        }
        if($roomNumber == 5){ // If we are out of rooms...
            die("Too many people!!!"); // die
        }
        $rooms[$roomNumber] ++; // Otherwise, add someone to the room
        $peopleNotInRoomsYet --; // And remove them from the waiting list
    }
?>

Я знаю, что это было чрезвычайно длинно для небольшого количества кода, которым мы закончили,но я пытался объяснить процесс перехода от концепции к коду.Признайте простые правила, которым вы должны следовать, затем узнайте элементы, которые вы должны отслеживать.Также помните, что опубликованное мной решение работает только в самой простой ситуации: если вам не нужно знать , кто в комнате, сколько людей.Это также предполагает, что ни одна комната не начинается ни с кем в этом.Если вторая комната начала заполняться, то этот алгоритм развалился бы, так как я не проверял это.Читатель может внести множество изменений, но это должно указать вам правильное направление.

1 голос
/ 31 октября 2010

Это не вопрос PHP, вы должны сначала описать алгоритм, а затем попытаться его реализовать.

Насколько я понимаю, лучшим решением было бы сохранить список комнат, отсортированных по фактическим пустым местам.(поэтому в начале у вас будут пустые комнаты, затем комнаты с 1 человеком, затем комнаты с 2 и т. д.).

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

В любом случае вы можете хранить 2 списка комнат, один для неполных и один для полных комнат.Когда комната заполняется, потому что новичок заполняет ее, вы просто меняете ее в другой список.Когда вместо этого пользователь покидает полную комнату, вы переключаете его обратно в исходный список.

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...