如何将项目{a_0,.,a_N}合并为K个组,以便合并过程成本最低

本文关键字:合并 个组 过程 项目 | 更新日期: 2023-09-27 17:59:50

让我举一个例子来说明我的意思。假设我有N=3{ A, B, C },并希望将它们合并到K组(0 < K < N)中。例如,将它们合并到K=2组中可能会产生结果

{ {A, B}, {C} }

我有一个函数Cost(X, Y) >= 0,它返回将项目X合并为项目Y的成本。例如,如果Cost(A, B) = 10Cost(B, C) = 15产生

{ {A, B}, {C} }

成本10和生产

{ {A}, {B, C} }

成本为CCD_ 12。

代价函数不是可交换的(Cost(X, Y) = Cost(Y, X)并不总是成立的)。

我想做的是找到一种将成本最低的合并到K组中的算法。

例如,假设成本是

Cost(A, B) = 12
Cost(B, A) = 4
Cost(A, C) = 5
Cost(C, A) = 11
Cost(B, C) = 3
Cost(C, B) = 20

我想合并成CCD_ 15组。成本最低的是

B -> C
A -> C

代价为CCD_ 16。

我正试图找出一个如何确定这一点的概括方法。

我认为它应该如何开始是订购所有成本:

Cost(B, C) = 3
Cost(B, A) = 4
Cost(A, C) = 5
Cost(C, A) = 11
Cost(A, B) = 12
Cost(C, B) = 20

以上列表中的项目将始终是合并过程中的一个移动:

B -> C

现在,我怀疑需要进行的是遍历列表的其余部分,看看是否每次合并。

列表中的下一项是B -> A。由于我已经将B移到了C,所以跳过这个。

下一项是A -> C。由于A尚未合并为一个组,因此这是一个有效的合并。

现在我们已经完成了,因为我们有了K=1组,{ {A, B, C} }

我想知道如何编写这个算法。

更具体地说,这里有一个C#设置:

using System;
using System.Collections.Generic;
using System.Linq;
public class Widget
{
    public int Distance { get; set; }
    public int Weight { get; set; } 
    public static int Cost(Widget w1, Widget w2)
    {
        // returns the cost of consolidating w1 into w2
        return Math.Abs(w1.Distance - w2.Distance) * w1.Weight; 
    }
}
public class Program
{
    public static void Main()
    {
        var widgets = new List<Widget>() 
        {
            new Widget() { Distance = 10, Weight = 1 },
            new Widget() { Distance = 20, Weight = 1 },
            new Widget() { Distance = 30, Weight = 1 },
        };
        var tuples = from x in widgets
                     from y in widgets
                     where !x.Equals(y)
                     select Tuple.Create(x,y);
        var ordered = from t in tuples
                      orderby Widget.Cost(t.Item1, t.Item2)
                      select t;
        int K = 2;
        int sum = 0; 
        // ... What to do here??? 
        Console.WriteLine(sum); // should write 10
    }
}

仅供参考,这不是家庭作业问题或其他问题。我这么做是为了好玩。

如何将项目{a_0,.,a_N}合并为K个组,以便合并过程成本最低

您可以构建一个可能性图(树),其中每条边表示合并函数在一组元素上的应用,每个节点存储有待合并的元素。

例如,您有{A,B,C}和成本(A,B)=10,成本(C)=15,成本(A、B、C)=30。

你可以构建这样的树:

        {A,B,C}
     10 /    ' 30
      {C}    { }
   15 /        
    { }

当你构建树时,你可以把空节点看作它的叶子,然后你可以进行横向预购,计算每个级别的成本,当你到达终端时,你会发现这是否是一个比你以前看到的更好的选择(只需在横向之前初始化一个值非常高的全局变量"best",当你到达终端时,你会做best=min(best,cost))

我把它作为一个答案发布,因为从技术上讲,它是一个答案,但它的目的不是为了实现,而是为了警告不要试图证明NP的硬度。

将合并成本解释为加权完全有向图。我们正在寻找N-K弧的最轻集合,使得(i)每个顶点最多是属于该集合的一个弧的尾部(ii)忽略方向,该集合不包含循环。条件(i)定义了拟阵,条件(ii)定义了一个拟阵。我们通过声明具有N-K个以上元素的集合是相关的(截断)来获得新的拟阵,然后将多项式时间算法应用于拟阵相交问题。