我思考这个问题已有一段时间了。
比方说,有一个列表{}
包含人们在卖的书。我有一本s
里的书,我想换一本s
中的书(我没有的东西)。
在这种情况下,每个人都在售s
中的一本书,并且还想要一本在s
中的图书。
是否有一种算法可以找出人与人之间获得我想要的书所需的最少交易量(并将书提供给想要的人)?
请告诉我这是否令人困惑(因为可能是这样)。
感谢您回答问题!
编辑:列表s
可以随时增长。
答案 0 :(得分:4)
编辑:该答案假设您希望所有人在一天结束时都拥有他们想要的书。其他答案可以解决您只关心获得您想要的书的情况。
我相信这相当于对数组进行排序的最小交换次数。对书籍1到N编号,对人员1到N编号,以使人 i 想要书籍 i 。现在我们有了一个像这样的数组:
Book: 2 1 4 3
Person: 1 2 3 4
即人1有书2,人2有书1,依此类推。现在,交易只是此数组中的掉期交易,因此我们只需要最小数量的掉期就可以对数组进行排序。 This is a known problem。
如果您可以有一个以上的人出售一本书,或者有一个以上的人想要一本书,那么您必须确保每本书的购买人数等于卖的人,否则没有解决方案。然后,只需在“ book”数组中使用该书的多个副本,然后再根据他们想要的书的数值对人们进行排序即可。例如,假设我们有4个人和2本书,其中两个人想要1本,两个人想要2本;我们会:
Book: 2 2 1 1
Person: 1 2 3 4
同样,我们希望以最少的交换次数对“ book”数组进行排序。
答案 1 :(得分:2)
我将其转变为如下图。书是图的节点。如果S中的某人正在提供书B并想要书A,则从书A到书B都有直接的优势。您正在寻找从拥有的书到想要的书的最短路径。
最短路径可以通过广度优先搜索来发现。您可以实现以下一种方法:
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
中或从中删除的最短路径将是很多工作。