Algorithm 在矩阵中找到一个位置,使每个移动到该位置的成本最小
有一个矩阵,m×n。几组人分布在某些特定地点。在下面的示例中,有三个组,数字4表示此组中有四个人。现在,我们想在矩阵中找到一个集合点,这样所有团队移动到该点的成本都是最小的。至于如何计算将一个组移动到另一个点的成本,请参见以下示例 第一组:(0,1),4 第2组:(1,3),3 第三组:(2,0),5 如果这三个组全部移动到(1,1),则成本为: 4*((1-0)+(1-1))+5*((2-1)+(1-0))+3*((1-1)+(3-1)) 我的想法是: 首先,这个二维问题可以简化为两个一维问题。 在一维问题中,我可以证明最好的点必须是这些群中的一个。 这样,我可以给出一个O(G^2)算法(G是群的个数) 使用迭代器的示例进行说明: {(-100,0100),(100,0100),(0,1,1)},(x,y,人口) 对于x,{(-100100)、(100100)、(0,1)},0是最好的 对于y,{(0100),(0100),(1,1)},0是最好的 所以是(0,0)Algorithm 在矩阵中找到一个位置,使每个移动到该位置的成本最小,algorithm,Algorithm,有一个矩阵,m×n。几组人分布在某些特定地点。在下面的示例中,有三个组,数字4表示此组中有四个人。现在,我们想在矩阵中找到一个集合点,这样所有团队移动到该点的成本都是最小的。至于如何计算将一个组移动到另一个点的成本,请参见以下示例 第一组:(0,1),4 第2组:(1,3),3 第三组:(2,0),5 如果这三个组全部移动到(1,1),则成本为: 4*((1-0)+(1-1))+5*((2-1)+(1-0))+3*((1-1)+(3-1)) 我的想法是: 首先,这个二维问题可以简化为两个一维问题
这个问题有没有更好的解决办法。我喜欢这样的想法,即目标函数可以分解为两个一维问题的和。剩下的问题在我看来很像加权中值(注意“在中解决以下优化问题”http://www.stat.ucl.ac.be/ISdidactique/Rhelp/library/R.basic/html/weighted.median.html“或者考虑当你远离加权中值时,目标函数发生了什么情况。 上面的URL似乎说加权中值需要时间n log n,我想这意味着你可以通过对数据进行排序,然后通过线性传递计算出加权中值来实现他们的要求。你必须排序的数字在[0,m]和[0,n]之间因此,从理论上讲,如果m和n很小,或者——当然——如果给你预先排序的数据,你可以做得更好
仔细想想,我不明白为什么你不能用线性时间随机化算法找到加权中位数,类似于用来找到中位数的算法(http://en.wikibooks.org/wiki/Algorithms/Randomization#find-中位数)-重复选取一个随机元素,用它来划分剩余的项目,并计算出加权中值的一半应该在其中。这会给你预期的线性时间。你的算法很好,并将问题划分为两个一维问题。时间复杂度为O(nlogn) 您只需将每组人员划分为n个单独的人员,因此每个人员向左、向右、向上或向下的每个移动都是1。我们只需找到(n+1)/2个人分别代表行和列的位置 考虑你的样本。{(-100,0100),(100,0100),(0,1,1)} 让我们把行号去掉,它是{(-100100),(100100),(0,1)},这意味着100人站在-100,100人站在100,1人站在0 按x排序,它是{(-100100),(0,1),(100100)}。总共有201人,所以我们只需要将位置设置为第101人所在的位置。它是0,这就是答案 列号采用相同的算法。{(0100),(0100),(1,1)},并对其进行排序。第101人为0,因此列的答案也是0 答案是(0,0)。我可以想到一维问题的O(n)解,这反过来意味着你可以用O(n+m+G)解原始问题 假设人们是这样站着的,a_0,a_1,…a_n-1:a_0人在点0,a_1在点1。那么伪代码中的解决方案是
cur_result = sum(i*a_i, i = 1..n-1)
cur_r = sum(a_i, i = 1..n-1)
cur_l = a_0
for i = 1:n-1
cur_result = cur_result - cur_r + cur_l
cur_r = cur_r - a_i
cur_l = cur_l + a_i
end
您需要找到cur_结果最小的点。所以你需要O(n)+O(m)来解决一维问题+O(G)来构建它们,这意味着总的复杂性是O(n+m+G)。
或者,你也可以用同样的方法在O(G*log G)中求解1d(或者,如果数据已排序,则为O(G))。从预期的组数中选择一个。你可以在O(G log G)时间内求解此问题,方法是将其简化为两个一维问题,如你所述 至于如何在一个维度上求解,只需对它们进行排序,并逐一进行检查,然后计算移动到该点的成本。该计算可以在O(1)个时间点内完成。
如果您的x和y坐标足够小,可以使用桶/基数排序,那么您也可以避免日志(G)分量。灵感来源于kilotaras的想法。似乎有一个O(G)解决方案可以解决此问题。 既然大家都同意二维问题可以简化为二维一维问题,我就不再重复了,我只关注如何解决一维问题 带O(G)
假设人们是这样站着的,a[0],a[1],…a[n-1]。有a[i]人站在点i。有G个点有人(G我认为这可以在O(n>m?n:m)时间和O(n>m?n:m)空间中解决。 我们必须找到k点中x坐标的中值和所有y坐标的中值,答案是(x_中值,y_中值) 假设此函数接受以下输入:
int k=4+3+5=12;
struct coord_t c[12] = {(0,1),(0,1),(0,1), (0,1), (1,3), (1,3),(1,3),(2,0),(2,0),(2,0),(2,0),(2,0)};
c.int size = n>m ? n:m;
struct coord_t {
int x;
int y;
};
1. My idea is to create an array of size = n>m?n:m;
2. int array[size] = {0} ; //initialize all the elements in the array to zero
for(i=0;i<k;i++)
{
array[c[i].x] = +1;
count++;
}
int tempCount =0;
for(i=0;i<k;i++)
{
if(array[i]!=0)
{
tempCount += array[i];
}
if(tempCount >= count/2)
{
break;
}
}
int x_median = i;
//similarly with y coordinate.
int array[size] = {0} ; //initialize all the elements in the array to zero
for(i=0;i<k;i++)
{
array[c[i].y] = +1;
count++;
}
int tempCount =0;
for(i=0;i<k;i++)
{
if(array[i]!=0)
{
tempCount += array[i];
}
if(tempCount >= count/2)
{
break;
}
}
int y_median = i;
coord_t temp;
temp.x = x_median;
temp.y= y_median;
return temp;
结构协调{
int x;
int-y;
};
1.我的想法是创建一个size=n>m?n:m的数组;
2.int-array[size]={0};//将数组中的所有元素初始化为零
对于(i=0;iYou应该在中发布:这与Mathematica无关-这是一个算法问题…对于OP:是否要求其中一个组不移动,即所有组移动到初始位置之一的位置?例如:{(-100,0100),(100,0100),(0,1,1)},对于(X,Y,Population)-最佳集合点似乎是(0,0)。是的,如果是最佳地点,其中一个小组可以保持静止。但我
struct coord_t c[12] = {(0,1),(0,1),(0,1), (0,1), (1,3), (1,3),(1,3),(2,0),(2,0),(2,0),(2,0),(2,0)};
c.int size = n>m ? n:m;
struct coord_t {
int x;
int y;
};
1. My idea is to create an array of size = n>m?n:m;
2. int array[size] = {0} ; //initialize all the elements in the array to zero
for(i=0;i<k;i++)
{
array[c[i].x] = +1;
count++;
}
int tempCount =0;
for(i=0;i<k;i++)
{
if(array[i]!=0)
{
tempCount += array[i];
}
if(tempCount >= count/2)
{
break;
}
}
int x_median = i;
//similarly with y coordinate.
int array[size] = {0} ; //initialize all the elements in the array to zero
for(i=0;i<k;i++)
{
array[c[i].y] = +1;
count++;
}
int tempCount =0;
for(i=0;i<k;i++)
{
if(array[i]!=0)
{
tempCount += array[i];
}
if(tempCount >= count/2)
{
break;
}
}
int y_median = i;
coord_t temp;
temp.x = x_median;
temp.y= y_median;
return temp;
#include<stdio.h>
#include<stdlib.h>
typedef struct coord_struct {
int x;
int y;
}coord_struct;
typedef struct distance {
int count;
}distance;
coord_struct toFindTheOptimalDistance (int N, int M, coord_struct input[])
{
coord_struct z ;
z.x=0;
z.y=0;
int i,j;
distance * array_dist;
array_dist = (distance*)(malloc(sizeof(distance)*M));
for(i=0;i<M;i++)
{
array_dist[i].count =0;
}
for(i=0;i<N;i++)
{
array_dist[input[i].x].count +=1;
printf("%d and %d\n",input[i].x,array_dist[input[i].x].count);
}
j=0;
for(i=0;i<=N/2;)
{
printf("%d\n",i);
if(array_dist[j].count !=0)
i+=array_dist[j].count;
j++;
}
printf("x coordinate = %d",j-1);
int x= j-1;
for(i=0;i<M;i++)
array_dist[i].count =0;
for(i=0;i<N;i++)
{
array_dist[input[i].y].count +=1;
}
j=0;
for(i=0;i<N/2;)
{
if(array_dist[j].count !=0)
i+=array_dist[j].count;
j++;
}
int y =j-1;
printf("y coordinate = %d",j-1);
z.x=x;
z.y =y;
return z;
}
int main()
{
coord_struct input[5];
input[0].x =1;
input[0].y =2;
input[1].x =1;
input[1].y =2;
input[2].x =4;
input[2].y =1;
input[3].x = 5;
input[3].y = 2;
input[4].x = 5;
input[4].y = 2;
int size = m>n?m:n;
coord_struct x = toFindTheOptimalDistance(5,size,input);
}