我有一个列表,偶数个节点(总是偶数)。我的任务是以最便宜的方式“匹配”所有节点。
所以我可以拥有listDegree(1,4,5,6)
,它代表我图中的所有奇数度节点。如何配对listDegree
中的节点,并将成本最低的组合保存到变量,例如int totalCost
。
这样的东西,我返回的totalCost
金额最少。
totalCost = (1,4) + (5,6)
totalCost = (1,5) + (4,6)
totalCost = (1,6) + (4,5)
---------------更多细节(或重写鞋面)---------------
我有一个类,它读取我的输入文件并存储我需要的所有信息,例如图形的costMatrix,边缘,边数和节点。
接下来我有一个DijkstrasShortestPath算法,它计算从我的图(costMatrix)到给定起始节点到给定终端节点的最短路径。
我还有一种方法可以检查图形(costMatrix)并将所有奇数度节点存储在列表中。
所以我正在寻找的是一些暗示我如何以最便宜的方式(最短路径)配对所有奇度节点。当我知道如何组合列表中的所有节点时,使用我拥有的数据很容易。
我不需要解决方案,这不是家庭作业。
我只需要一个提示就知道,如果你有一个列表,让我们说整数,你如何成对地组合所有整数。
希望这种言论更好......:D
答案 0 :(得分:0)
(如果没有关于费用的更多细节,我将假设cost(1,5) = 1-5
,并且您希望总和尽可能接近0。)
您正在描述偶数partition problem,即NP-Complete。
问题是:给定一个列表L
,找到两个列表A,B
,使sum(A) = sum(B)
和#elements(A)= #elements(B),每个元素来自L必须在A或B(而不是两者)。
问题的简化很简单,对中的每个左元素都会转到A,每对中的每个元素都会转到B.
因此,没有已知的多项式解决方案,但您可能想尝试指数穷举搜索方法(搜索所有可能的对,其中有Choose(2n,n) = (2n!)/(n!*n!)
个。< / p>
替代方案是pseudo-polynomial DP based solutions(小整数可行)。
答案 1 :(得分:0)
<击>也许:击>
<击>List<int> totalCosts = listDegree
.Select((num,index) => new{num,index})
.GroupBy(x => x.index / 2)
.Select(g => g.Sum(x => x.num))
.ToList();
击> <击> 撞击>
修改强>:
在您编辑问题后,我了解您的要求。您需要列表中所有元素的所有(成对)组合的总和。我会使用this combinatorics project这是非常有效率和信息量。
var listDegree = new[] { 1, 4, 5, 6 };
int lowerIndex = 2;
var combinations = new Facet.Combinatorics.Combinations<int>(
listDegree,
lowerIndex,
Facet.Combinatorics.GenerateOption.WithoutRepetition
);
// get total costs overall
int totalCosts = combinations.Sum(c => c.Sum());
// get a List<List<int>> of all combination (the inner list count is 2=lowerIndex since you want pairs)
List<List<int>> allLists = combinations.Select(c => c.ToList()).ToList();
// output the result for demo purposes
foreach (IList<int> combis in combinations)
{
Console.WriteLine(String.Join(" ", combis));
}