我按特定顺序拥有一定数量的方框,并按特定顺序拥有多个权重。重量可以具有不同的重量(即一个可以重1kg,另一个重2kg等)。 我想把重量放在盒子里,以便它们尽可能均匀分布。我必须按照给出的顺序取重量,我必须按照给出的顺序填充方框。也就是说,如果我把重量放在方框n + 1中,我不能将重量放在方框n中,我不能将重量m + 1放在一个方框中,直到我第一次将重量m放在一个方框中。
我需要找到一个算法来解决任何数量的框和任何权重集的问题。
使用xUnit在C#中进行一些测试(Distribute是应该解决问题的方法):
[Fact]
public void ReturnsCorrectNumberOfBoxes()
{
int[] populatedColumns = Distribute(new int[0], 4);
Assert.Equal<int>(4, populatedColumns.Length);
}
[Fact]
public void Test1()
{
int[] weights = new int[] { 1, 1, 1, 1 };
int[] boxes = Distribute(weights, 4);
Assert.Equal<int>(weights[0], boxes[0]);
Assert.Equal<int>(weights[1], boxes[1]);
Assert.Equal<int>(weights[2], boxes[2]);
Assert.Equal<int>(weights[3], boxes[3]);
}
[Fact]
public void Test2()
{
int[] weights = new int[] { 1, 1, 17, 1, 1 };
int[] boxes = Distribute(weights, 4);
Assert.Equal<int>(2, boxes[0]);
Assert.Equal<int>(17, boxes[1]);
Assert.Equal<int>(1, boxes[2]);
Assert.Equal<int>(1, boxes[3]);
}
[Fact]
public void Test3()
{
int[] weights = new int[] { 5, 4, 6, 1, 5 };
int[] boxes = Distribute(weights, 4);
Assert.Equal<int>(5, boxes[0]);
Assert.Equal<int>(4, boxes[1]);
Assert.Equal<int>(6, boxes[2]);
Assert.Equal<int>(6, boxes[3]);
}
非常感谢任何帮助!
答案 0 :(得分:3)
请参阅下面的解决方案。
干杯,
马拉什
public static int[] Distribute(int[] weights, int boxesNo)
{
if (weights.Length == 0)
{
return new int[boxesNo];
}
double average = weights.Average();
int[] distribution = new int[weights.Length];
for (int i = 0; i < distribution.Length; i++)
{
distribution[i] = 0;
}
double avDeviation = double.MaxValue;
List<int> bestResult = new List<int>(boxesNo);
while (true)
{
List<int> result = new List<int>(boxesNo);
for (int i = 0; i < boxesNo; i++)
{
result.Add(0);
}
for (int i = 0; i < weights.Length; i++)
{
result[distribution[i]] += weights[i];
}
double tmpAvDeviation = 0;
for (int i = 0; i < boxesNo; i++)
{
tmpAvDeviation += Math.Pow(Math.Abs(average - result[i]), 2);
}
if (tmpAvDeviation < avDeviation)
{
bestResult = result;
avDeviation = tmpAvDeviation;
}
if (distribution[weights.Length - 1] < boxesNo - 1)
{
distribution[weights.Length - 1]++;
}
else
{
int index = weights.Length - 1;
while (distribution[index] == boxesNo - 1)
{
index--;
if (index == -1)
{
return bestResult.ToArray();
}
}
distribution[index]++;
for (int i = index; i < weights.Length; i++)
{
distribution[i] = distribution[index];
}
}
}
}
答案 1 :(得分:2)
第二次尝试:我认为A *(发音为“a star”)算法在这里运行良好,即使它会占用大量内存。如果有的话,你可以得到最佳答案。
您正在搜索的每个“节点”都是框中权重的可能组合。第一个节点应该是您随机挑选的任何重量,放入一个盒子。我建议随机选择新的重量。
不幸的是,A *很复杂,我没有时间在这里解释。通过自己阅读很容易理解,但如上所述将其映射到这个问题会更加困难。如果您选择此路线,请回复相关问题。