Algorithm 在矩阵中找到一个位置,使每个移动到该位置的成本最小

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)) 我的想法是: 首先,这个二维问题可以简化为两个一维问题

有一个矩阵,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)


这个问题有没有更好的解决办法。

我喜欢这样的想法,即目标函数可以分解为两个一维问题的和。剩下的问题在我看来很像加权中值(注意“在中解决以下优化问题”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;
    
  • 让坐标的输入是一个坐标数组。coord_t c[k]

    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);
    }