Algorithm 以最小移动量将n个对象分布到n个不同位置的算法

Algorithm 以最小移动量将n个对象分布到n个不同位置的算法,algorithm,optimization,Algorithm,Optimization,有n个房间排列成一个圆圈,n个对象。在流程结束时,每个房间中应该只有一个对象。最初,每个房间可以有从0到n的随机数量的对象,但所有房间中所有对象的总和为n。移动这些对象的算法是什么?假设将对象从一个房间顺时针移动到其旁边的房间算作一次移动,而不可能进行其他移动,则每个房间只有一个移动次数最少的对象 示例: n=5 初始情况: 房间1=5 房间2:0 房间3:0 房间4:0 房间5:0 解决方案:1+2+3+4=10算法似乎非常简单: 按顺时针顺序遍历所有房间 对于每个房间,将多余的对象移动到下

有n个房间排列成一个圆圈,n个对象。在流程结束时,每个房间中应该只有一个对象。最初,每个房间可以有从0到n的随机数量的对象,但所有房间中所有对象的总和为n。移动这些对象的算法是什么?假设将对象从一个房间顺时针移动到其旁边的房间算作一次移动,而不可能进行其他移动,则每个房间只有一个移动次数最少的对象

示例:
n=5
初始情况:
房间1=5
房间2:0
房间3:0
房间4:0
房间5:0

解决方案:1+2+3+4=10

算法似乎非常简单:

  • 按顺时针顺序遍历所有房间
  • 对于每个房间,将多余的对象移动到下一个房间
  • 继续运行,直到所有房间都有一个对象,最多需要
    2*房间数量-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;
    }
}
int n=5;
int-rooms[5]={5,0,0,0,0};
int过量=0;
int-total=0;
对于(int i=0;i<2*n-1;i++){
超额=房间[i%n]-1;
如果(超额>0){
总数+=超额;
房间[i%n]=1;
房间[(i+1)%n]+=超额;
}
}

我只是想谈谈如何解决这个问题

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

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

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

其他房间(只有一个对象的房间)不受影响,这些房间不包括在计算中

现在,根据与房间的距离构建优先级队列。那就是,

filledRooms--emptyRooms--distance

你的例子很简单,让我们举个例子

房间号1->2->3->4->5
房间对象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
4 3

现在让我们填充房间,直到我们用完房间对象(意味着只剩下一个对象)

因此,将1个对象从1移动到2。(我们已经用尽了1)
将1个对象从1移动到3(不能这样做,我们已经耗尽了1号房间)
将1个对象从4移动到2
将1个对象从4移动到3


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

您能给出一些测试用例,以便验证答案吗?还有,你是在哪里发现或面对这个问题的?你说这些房间都排成一个圆圈。那么答案不是1+2+2+1=6吗?因为房间是这样排列的,5->0->0->0->0->5,所以按循环顺序排列效率更高。@S_kar只允许顺时针移动。除非您需要一个程序来计算答案,否则最好在math stackexchange上问这个问题