Алгоритм поиска наименьшего количества сделок между людьми

Я уже давно думаю над этим вопросом.

Допустим, есть список s, содержащий книги, которые продают люди. У меня есть книга в s, и я хочу обменять ее на книгу из s (чего у меня нет).

Каждый человек в этом сценарии продает одну книгу в s, а также хочет, чтобы одна книга была в s.

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

Пожалуйста, скажите мне, если это кажется запутанным (потому что, вероятно, так оно и есть).

Спасибо, что ответили на вопрос!

Обновлено: Список s может увеличиваться в любое время.

Я думаю, это также может зависеть от того, сколько людей там и какие книги они уже имеют или хотят ... можете ли вы это предоставить?

mettleap 16.11.2018 19:27

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

BrentR 16.11.2018 19:28

Гарантировано ли, что никакие два человека не продают одну и ту же книгу и что два человека не хотят одну и ту же книгу? (Другими словами: гарантировано ли, что есть способ поменять местами все книги, и каждый получит ту книгу, которую хочет?)

ruakh 16.11.2018 19:30

Можете ли вы предоставить примеры входных и ожидаемых результатов?

ggorlen 16.11.2018 19:57

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

Gautham Rajesh 16.11.2018 20:03

@BrentR что сбивает с толку? И причина, по которой я не предпринял попытки, в том, что я не знаю, с чего начать.

Gautham Rajesh 16.11.2018 20:04

Вы единственный человек в группе, который желает временно держать ненужную книгу? Что определяет, готов ли человек обменять книгу, которую он не хочет, в надежде в конечном итоге получить книгу, которую он хочет?

mypetlion 16.11.2018 20:08

Как они торгуют? Есть ли у книги себестоимость или продажная цена? Потому что в противном случае просто обмен.

nice_dev 16.11.2018 20:19

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

Gautham Rajesh 16.11.2018 20:24

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

Gautham Rajesh 16.11.2018 20:32

@GauthamRajesh пример ввода и вывода было бы лучше

nice_dev 16.11.2018 20:33

Определите, пожалуйста, «обмен» - два человека обмениваются книгами?

Prune 16.11.2018 20:37

@Prune да, это то, что я имею в виду под торговлей.

Gautham Rajesh 16.11.2018 20:38

Могут ли несколько человек предлагать одну и ту же книгу? Например, может ли в s быть три копии «Сильмариллиона»? Благодарим @btilly за этот момент.

Prune 16.11.2018 21:03

@Prune: да, несколько человек могут продавать одну и ту же книгу. Если на то пошло, несколько человек могут захотеть одну и ту же книгу.

Gautham Rajesh 16.11.2018 21:04

@GauthamRajesh: Спасибо; это полностью опровергает мой ответ. Исправление моего ответа делает его эквивалентным первому, поэтому я удаляю его.

Prune 16.11.2018 21:05

@Prune На самом деле, если вы посмотрите выше, ruakh первым заметил то же самое.

btilly 16.11.2018 21:10
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
3
17
126
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Обновлено: Этот ответ предполагает, что вы хотите, чтобы у всех была желанная книга в конце дня. Другой (-ые) ответ (-и) относится к случаю, когда все, что вас волнует, - это получение желаемой книги ваш.

Я считаю, что это эквивалентно минимальному количеству свопов для сортировки массива. Пронумеруйте книги от 1 до N и пронумеруйте людей от 1 до N так, чтобы человеку я понадобилась книга я. Теперь у нас есть такой массив:

Book:    2  1  4  3
Person:  1  2  3  4

т.е. у человека 1 есть книга 2, у человека 2 - книга 1 и т. д. Теперь сделка - это просто своп в этом массиве, поэтому нам просто нужно минимальное количество свопов для сортировки массива. Это известная проблема.

Если у вас может быть более одного человека, продающего данную книгу, или более одного человека, который хочет данную книгу, вы должны убедиться, что для каждой книги количество людей, которые хотят ее, равно количеству людей, которые ее продают. , иначе решения нет. Затем просто используйте несколько копий книги в массиве «book», снова сортируя людей по числовому значению книги, которую они хотят. Например, предположим, что у нас есть 4 человека и 2 книги, где два человека хотят книгу 1, а два человека хотят книгу 2; у нас было бы:

Book:    2  2  1  1
Person:  1  2  3  4

Опять же, мы хотим отсортировать массив «книжный» за наименьшее количество свопов.

Хорошее решение! :)

mettleap 16.11.2018 20:28

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

btilly 16.11.2018 20:51

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

arshajii 16.11.2018 21:05

@arshajii Прошу прощения за то, что запутал вопрос, хотя это не было моим намерением.

Gautham Rajesh 16.11.2018 21:07

Сообщение, на которое вы ссылаетесь, использует другую концепцию «свопа», которая не переключает два элемента массива. Ответы там не применимы к этой проблеме.

user2357112 supports Monica 16.11.2018 21:14

Ваш ответ довольно хорош и имеет смысл (я проголосовал за него), но я сделаю ответ @btilly принятым, потому что его ответ больше относится к моему случаю.

Gautham Rajesh 16.11.2018 21:17

@ user2357112 Спасибо, исправили.

arshajii 16.11.2018 22:15
Ответ принят как подходящий

Я бы превратил это в график следующим образом. Книги - это узлы графа. У вас есть направленный переход от книги A к книге B, если кто-то из S предлагает книгу B и хочет книгу A. Вы ищете кратчайший путь от книги, которая у вас есть, к книге, которая вам действительно нужна.

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

todo = [starting_book]
path = {starting_book: None}
while len(todo) and target_book not in path:
    book = list.pop(0)
    for next_book in neighbors(book):
        if next_book not in path:
            path[next_book] = book
            todo.append(next_book)
if target_book in path:
    solution = [target_book]
    while solution[-1] != starting_book:
        solution.append(path[solution[-1]])
else:
    solution = None

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

Это также не онлайн-решение - отслеживание кратчайших путей при добавлении / удалении вещей из s потребует много работы.

Это хорошее решение. Есть ли способ реализовать это на Java?

Gautham Rajesh 16.11.2018 21:32

@GauthamRajesh См. geeksforgeeks.org/breadth-first-search-or-bfs-for-a-graph для реализации Java поиска в ширину.

btilly 16.11.2018 23:43

Другие вопросы по теме