暴民挑选 - 随机选择多个项目,每个项目都有一个成本,给定一个花费范围

发布于 2024-12-02 20:01:58 字数 771 浏览 1 评论 0原文

我正在考虑实时策略游戏的随机模式。

在这种模式下,计算机对手需要生成一组随机的攻击者(暴民)来攻击玩家。每个可能的攻击者都有相关的创建成本,并且每个回合都有一定的最大花费金额。为了避免让它变得无趣,对手应该总是花费至少一半的金额。

支出金额是高度动态的,而创建成本是动态的,但变化较慢。

我正在寻找以下形式的例程:

void randomchoice( int N, int * selections, int * costs, int minimum, int maximum )

这样给定:

N = 5 (for example, I expect it to be around 20 or so)
selections is an empty array of 5 positions
costs is the array {11, 13, 17, 19, 23}
minimum and maximum are 83 and 166 

将返回:

83 <= selection[0]*11 + selection[1]*13 + selection[2]*17 + selection[3]*19 + selection[4]*23 <= 166

最重要的是,我想要一个统一的随机选择 - 我尝试过的所有方法主要导致一些最大的攻击者和小型攻击者的“虫族”太罕见了。

虽然我更喜欢 C/C++ 系列中的解决方案,但任何算法提示都会受到欢迎。

I am considering a random mode for a real-time strategy game.

In this mode, the computer opponent needs to generate a random group of attackers (the mob) which will come at the player. Each possible attacker has an associated creation cost, and each turn there is a certain maximum amount to spend. To avoid making it uninteresting, the opponent should always spend at least half of that amount.

The amount to spend is highly dynamic, while creation costs are dynamic but change slower.

I am seeking a routine of the form:

void randomchoice( int N, int * selections, int * costs, int minimum, int maximum )

Such that given:

N = 5 (for example, I expect it to be around 20 or so)
selections is an empty array of 5 positions
costs is the array {11, 13, 17, 19, 23}
minimum and maximum are 83 and 166 

Would return:

83 <= selection[0]*11 + selection[1]*13 + selection[2]*17 + selection[3]*19 + selection[4]*23 <= 166

Most importantly, I want an uniformly random selection - all approaches I've tried result mostly in a few of the largest attackers, and "zergs" of the small ones are too rare.

While I would prefer solutions in the C/C++ family, any algorithmic hints would be welcome.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

江湖正好 2024-12-09 20:01:58

首先,我建议您在最小和最大数字之间创建一个随机数r,我们将尝试在成本上接近该数字,以简化一点。,所以min <= r <= 最大值

接下来创建一个符合您派遣部队喜好的统一方案。如果我理解正确的话,它会是这样的:

如果一个单位 A 的成本 c,那么 m_a = r / c 就是您最多可以购买的此类单位的大致数量。现在我们有其他类型的单位 - BC,它们有自己的成本和编号 m_bm_c > 等。令 S = m_a + m_b + ...。生成 0 到 S 之间的随机数 U。找到最小的 i,使得 S = m_a + ... m_i 大于 U。然后创建一个 i 类型的单位,并从 r 中减去单位成本。当 r > 时重复0 。

直观上似乎很清楚,应该有一种更有效的方法而无需重新计算,但对于单词uniform的给定含义,这是可以接受的。

Firstly I suggest you create a random number r between your min and max number, and we'll try to approach that number in cost, to simplify this a bit., so min <= r <= max.

Next create a scheme that is uniform to your liking in dispatching your units. If I understand correctly, it would be something like this:

If a unit A has a cost c, then m_a = r / c is the rough number of such units you can maximally buy. Now we have units of other types - B, C, with their own costs, and own number m_b, m_c, etc. Let S = m_a + m_b + .... Generate a random number U between 0 and S. Find the smallest i, such that S = m_a + ... m_i is larger than U. Then create a unit of type i, and subtract the units cost from r. Repeat while r > 0.

It seems intuitively clear, that there should be a more efficient method without recomputations, but for a given meaning of the word uniform, this is passable.

孤独患者 2024-12-09 20:01:58

真的统一吗?如果单位类型的数量(N = 20?)和成本与最大支出比率相对较小,则有效可能性的搜索空间相当小,您可能只能暴力破解这一点。 Java 式的,抱歉(对我来说更自然,应该很容易移植。

List<Integer> choose(int[] costs, int min, int max) {
   List<List<Integer>> choices = enumerate(costs, min, max);
   return choices.get(new Random().nextInt(choices.size()));
}

// Recursively computes the valid possibilities.
List<List<Integer>> enumerate(int[] costs, int min, int max) {
   List<List<Integer>> possibilities = new ArrayList<List<List<Integer>>();

    // Base case
    if (costs.length == 1) { 
       for (int i = min / costs[0]; i < max / costs[0]; i++) {
           List<Integer> p = new ArrayList<Integer>();
           p.add(i);
           possibilities.add(p); 
       }   
       return possibilities;
    }

    // Recursive case - iterate through all possible options for this unit, recursively find
    // all remaining solutions. 
    for (int i = 0; i < max / costs[0]; i++) {
        // Pythonism because I'm lazy - your recursive call should be a subarray of the
        // cost array from 1-end, since we handled the costs[0] case here.

        List<List<Integer>> partial = enumerate(costs[1:], min - (costs[0] * i), max - (costs[0] * i));
        for (List<Integer> li : partial) {
          possibilities.add(li.add(0, i));
        }
    }

    return possibilities;
}

Truly uniform? If the number of types of units (N=20?) and cost to max spend ratio is relatively small, the search space for valid possibilities is fairly small and you can probably just brute force this one. Java-esque, sorry (more natural for me, should be easy to port.

List<Integer> choose(int[] costs, int min, int max) {
   List<List<Integer>> choices = enumerate(costs, min, max);
   return choices.get(new Random().nextInt(choices.size()));
}

// Recursively computes the valid possibilities.
List<List<Integer>> enumerate(int[] costs, int min, int max) {
   List<List<Integer>> possibilities = new ArrayList<List<List<Integer>>();

    // Base case
    if (costs.length == 1) { 
       for (int i = min / costs[0]; i < max / costs[0]; i++) {
           List<Integer> p = new ArrayList<Integer>();
           p.add(i);
           possibilities.add(p); 
       }   
       return possibilities;
    }

    // Recursive case - iterate through all possible options for this unit, recursively find
    // all remaining solutions. 
    for (int i = 0; i < max / costs[0]; i++) {
        // Pythonism because I'm lazy - your recursive call should be a subarray of the
        // cost array from 1-end, since we handled the costs[0] case here.

        List<List<Integer>> partial = enumerate(costs[1:], min - (costs[0] * i), max - (costs[0] * i));
        for (List<Integer> li : partial) {
          possibilities.add(li.add(0, i));
        }
    }

    return possibilities;
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文