【问题标题】:Distribute list of resources equally平均分配资源列表
【发布时间】:2012-10-08 22:10:50
【问题描述】:

很难解释我遇到的问题,但让我们试一试:)

我正在开发的小游戏创建了一堆节点,其中充满了两种资源。
每个节点都有一个 iron 值和一个 gold 值。

我想将这些节点分成两个区域,因此两个区域的gold 数量大致相同。但是,iron 的差异可能不会大于某个数字(本例选择 50

顺便说一下,gold/iron 的比率几乎是随机的。这是一个例子:

  1. 金75铁30

  2. 金35铁70

  3. 金65铁35

上述情况的解决方案:13转到area12转到area2

我在尝试自动执行此过程时遇到了很多麻烦。我尝试遍历节点列表并始终将节点传递到具有较少iron 的区域,但这几乎永远不会奏效。
尝试从更丰富的区域重新分配一些节点也被证明是困难的,因为一些节点的值远高于50 iron
我不一定需要找到最佳解决方案(gold 中差异最小的解决方案),尽管那将是最佳解决方案。

感谢任何想法或意见。

【问题讨论】:

  • 您的最后一段听起来像是您只想将铁的差异保持在您的门槛以下,而黄金的数量无关紧要?
  • @Jan 不完全。黄金分配绝对应该是公平的,但它并不像将铁的差异保持在 50 或以下那么重要。编辑:分布区域 1:100 铁,200 黄金;区域2:50铁,200金优于:区域1:100铁,500金;区域2:100铁,200金。

标签: c# list distribution nodes


【解决方案1】:

我对此进行了一些尝试,这就是我到目前为止所得到的,应该是一个很好的起点。我随机生成了一个黄金和铁对列表(我使用了 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();
    }

结果:

【讨论】:

  • 非常感谢,这看起来很有前途!我现在就试试。
猜你喜欢
  • 1970-01-01
  • 2020-12-24
  • 2014-05-19
  • 2021-09-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多