我很难解释我遇到的问题,但让我们试一试:)
我正在制作的小游戏创建了一堆充满两种资源的节点
每个节点都有 iron
值和 gold
值。
我想将这些节点划分为两个区域,因此两个区域的大约相同的gold
。但是, iron
的差异可能不会超过某个数字(在本例中我们选择 50
)
顺便提一句,gold/iron
比率几乎是随机的。这是一个例子:
金75铁30
金35铁70
gold 65 iron 35
针对上述情况的解决方案:1
和3
转到area1
,2
转到area2
。
我在尝试自动执行此过程时遇到了很多麻烦。我已经尝试迭代节点列表并始终将节点传递到iron
量较小的区域,但这几乎不起作用。
尝试从较富裕的区域重新分配一些节点也证明是困难的,因为一些节点远高于50 iron
。
我不一定需要找到最佳解决方案(gold
中差异最小的解决方案),尽管这样做是最佳的。
赞赏任何想法或意见。
答案 0 :(得分:3)
我有一点玩这个,这是我到目前为止,应该给出一个很好的起点。我已经随机生成了一对黄金和铁对(我使用了Point因为它对我来说更简单,但任何工作都可以。)
这个想法是拿一组小价值黄金,并用另一个名单中的一个较大价值的黄金交换它们。在大多数情况下,这会讨论相当数量的黄金,但将较大的铁价换成较小的黄金。
private void button2_Click(object sender, EventArgs e)
{
var GoldIron = new List<Point>(
new Point[]{
new Point(16,23),new Point(16,28),new Point(19,44),new Point(21,29),
new Point(23,16),new Point(24,82),new Point(27,85),new Point(31,63),
new Point(31,78),new Point(32,65),new Point(41,23),new Point(43,79),
new Point(44,76),new Point(45,23),new Point(47,16),new Point(50,15),
new Point(50,37),new Point(52,28),new Point(52,58),new Point(52,71),
new Point(61,39),new Point(61,75),new Point(63,59),new Point(68,25),
new Point(68,61),new Point(70,24),new Point(71,75),new Point(74,78),
new Point(77,59),new Point(82,27)}
);
listBox1.DataSource = GoldIron;
//Split into 2 lists based on the gold amount
var Left = new List<Point>();
var Right = new List<Point>();
var SumGold = GoldIron.Sum(P => P.X);
var SumIron = GoldIron.Sum(P => P.Y);
label2.Text = SumGold.ToString();
label1.Text = SumIron.ToString();
var LeftGold = 0;
Int32 i = 0;
while (LeftGold < SumGold / 2)
{
LeftGold += GoldIron[i].X;
Left.Add(GoldIron[i++]);
}
while (i < GoldIron.Count)
{
Right.Add(GoldIron[i++]);
}
Int32 LIndex = 0;
//Start Algorithm
Int32 LeftIron = Left.Sum(P => P.Y);
Int32 RightIron = Right.Sum(P => P.Y);
while (LeftIron - RightIron > 50 || RightIron - LeftIron > 50)
{
if (LeftIron < RightIron)
{
List<Point> TempList = Left;
Left = Right;
Right = TempList;
LIndex = 0;
}
Int32 SmallestRight = Right[LIndex].X;
LeftGold = 0;
i = 0;
while (LeftGold < SmallestRight)
{
LeftGold += Right[i++].X;
}
Point Temp = Right[LIndex];
Right.RemoveAt(LIndex);
Right.AddRange(Left.Take(i));
Left.RemoveRange(0, i);
Left.Add(Temp);
LIndex += i;
//Sort
Left.Sort(CompareGold);
Right.Sort(CompareGold);
LeftIron = Left.Sum(P => P.Y);
RightIron = Right.Sum(P => P.Y);
}
listBox2.DataSource = Left;
SumGold = Left.Sum(P => P.X);
SumIron = Left.Sum(P => P.Y);
label4.Text = SumGold.ToString();
label3.Text = SumIron.ToString();
listBox3.DataSource = Right;
SumGold = Right.Sum(P => P.X);
SumIron = Right.Sum(P => P.Y);
label6.Text = SumGold.ToString();
label5.Text = SumIron.ToString();
}
结果: