用最少的移动将n个对象分布到n个不同位置的算法

时间:2016-02-20 14:25:00

标签: algorithm optimization

有n个房间排成一个圆圈和n个物体。在过程结束时,每个房间应该只有一个对象。最初,每个房间可以有0到n的随机数量的对象,但所有房间中所有对象的总和是n。什么是移动这些对象的算法,以便每个房间只有一个具有最小移动的对象,假设将一个对象从一个房间移动到旁边的一个对象,则计为1个移动,并且不可能进行其他移动。

例:
n = 5
初步情况:
房间1 = 5
房间2:0
房间3:0
房间4:0
房间5:0
解:1 + 2 + 3 + 4 = 10

2 个答案:

答案 0 :(得分:2)

我只是想知道如何解决这个问题。

首先让我们构建一个优先级队列。队列将根据最近距离排序。

首先,您需要找到具有额外对象的节点,这意味着它有多个对象。让我们称之为filledRooms

现在找到空房间,这意味着这些房间有0个对象。称之为emptyRooms

其他房间(仅有1个物体的房间)不受影响,这些房间不包括在计算中。

现在构建根据房间距离排序的优先级队列。所以它会是,

filledRooms -- emptyRooms -- distance

你的例子很简单,所以,举个例子。

房间号1-> 2-> 3-> 4-> 5
室obj 2-> 0-> 0-> 3-> 0

所以,填充的房间分别为1和4。 1到2的距离是1,1到3是2,4到5是1,4到2是2,4到3是2 让我们解决这个问题,

1 2 1
4 5 1
1 3 2
4 2 2
4 3 3

现在让我们填写房间,直到我们用尽了房间的物体(意味着只剩下一个物体)。

所以将1个物体从1移动到2.(我们已经筋疲力尽1)
将1个物体从1移动到3(不能这样做,我们已经耗尽了房间1)
将1个物体从4移动到2 将1个对象从4移动到3

加上费用。这是您的最佳答案。如果允许顺时针和逆时针两种运动,这也将起作用。

答案 1 :(得分:0)

算法看起来很简单:

  • 按顺时针顺序遍历所有房间。
  • 对于每个房间,将多余的物品移到下一个房间。
  • 继续前进,直到所有房间都有1个物体,最多可能需要2*number_of_rooms-1个步骤。

就是这样。

移动次数可以这样计算:

int n = 5;
int rooms[5] = { 5, 0, 0, 0, 0 };
int excess = 0;
int total = 0;

for (int i = 0; i < 2 * n - 1; i++) {
    excess = rooms[i % n] - 1;
    if (excess > 0) {
        total += excess;
        rooms[i % n] = 1;
        rooms[(i + 1) % n] += excess;
    }
}