约束n维空间的高效随机采样

发布于 2024-09-28 10:28:39 字数 425 浏览 1 评论 0原文

我即将优化由 n 个(n>=1,通常 n=4)个非负变量定义的问题。这不是一个 n 维问题,因为所有变量的总和需要为 1。

最直接的方法是对每个 x_i 扫描整个范围 0<=x_i<1,然后将所有值归一化为总和所有 x 的。然而,这种方法引入了冗余,这对于许多依赖解空间随机采样的优化算法(遗传算法、禁忌搜索等)来说是一个问题。是否有任何替代算法可以执行此任务?

冗余是什么意思?

以二维情况为例。如果没有约束,这将是一个二维问题,需要优化两个变量。然而,由于要求 X1 + X2 == 0,因此只需要优化一个变量,因为 X2 由 X1 决定,反之亦然。如果决定独立扫描 X1 和 X2 并将它们归一化为 1,那么许多候选解决方案对于问题来说都是相同的。例如(X1==0.1,X2==0.1)与(X1==0.5,X2==0.5)相同。

I'm about to optimize a problem that is defined by n (n>=1, typically n=4) non-negative variables. This is not a n-dimensional problem since the sum of all the variables needs to be 1.

The most straightforward approach would be for each x_i to scan the entire range 0<=x_i<1, and then normalizing all the values to the sum of all the x's. However, this approach introduces redundancy, which is a problem for many optimization algorithms that rely on stochastic sampling of the solution space (genetic algorithm, taboo search and others). Is there any alternative algorithm that can perform this task?

What do I mean by redundancy?

Take two dimensional case as an example. Without the constrains, this would be a two-dimensional problem which would require optimizing two variables. However, due to the requirement that X1 + X2 == 0, one only needs to optimize one variable, since X2 is determined by X1 and vice versa. Had one decided to scan X1 and X2 independently and normalizing them to the sum of 1, then many solution candidates would have been identical vis-a-vis the problem. For example (X1==0.1, X2==0.1) is identical to (X1==0.5, X2==0.5).

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

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

发布评论

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

评论(2

萌︼了一个春 2024-10-05 10:28:39

如果您处理的是实值变量,则不太可能获得两个相同的样本。但是,您确实存在样品不均匀的问题。您更有可能选择 (0.5, 0.5) 而不是 (1.0, 0)。解决这个问题的一种方法是二次采样。基本上,你所做的就是当你沿着某个点缩小空间时,你就缩小了选择它的概率。

所以基本上你要做的就是映射单位立方体内满足同一方向的所有点,映射到单个点。这些点在同一方向上形成一条线。线越长,您选择投影点的概率就越大。因此,您希望通过该线的长度的倒数来偏置选择点的概率。

下面是可以做到这一点的代码(假设您正在寻找 x_is 的总和为 1):

while(true) {
      maximum = 0;
      norm = 0;
      sum = 0;
      for (i = 0; i < N; i++) {
         x[i] = random(0,1);
         maximum = max(x[i], max);
         sum += x[i];
         norm += x[i] * x[i];
      }
      norm = sqrt(norm);
      length_of_line = norm/maximum;
      sample_probability = 1/length_of_line;

      if (sum == 0 || random(0,1) > sample_probability) {
        continue;
      } else {
      for (i = 0; i < N; i++) {
         x[i] = x[i] /sum;
      } 
      return x;
    }

If you are dealing with real valued variables then arriving with 2 samples that become identical is quite unlikely. However you do have the problem that your samples would not be uniform. You are much more likely to choose (0.5, 0.5) than (1.0, 0). Oneway of fixing this is subsampling. Basically what you do is that when you are shrinking space along a certain point, you shrink the probability of choosing it.

So basically what you are doing is mapping all the points that are inside the unit cube that satisfy that are in the same direction, map to a single points. These points in the same direction form a line. The longer the line, the larger the probability that you will choose the projected point. Hence you want to bias the probability of choosing a point by the inverse of the length of that line.

Here is the code that can do it(Assuming you are looking for x_is to sum up to 1):

while(true) {
      maximum = 0;
      norm = 0;
      sum = 0;
      for (i = 0; i < N; i++) {
         x[i] = random(0,1);
         maximum = max(x[i], max);
         sum += x[i];
         norm += x[i] * x[i];
      }
      norm = sqrt(norm);
      length_of_line = norm/maximum;
      sample_probability = 1/length_of_line;

      if (sum == 0 || random(0,1) > sample_probability) {
        continue;
      } else {
      for (i = 0; i < N; i++) {
         x[i] = x[i] /sum;
      } 
      return x;
    }
月隐月明月朦胧 2024-10-05 10:28:39

这是之前提供的相同的函数Amit Prakash,翻译为 python

import numpy as np

def f(N):
    while(True):
        count += 1
        x = np.random.rand(N)
        mxm = np.max(x)
        theSum = np.sum(x)
        nrm = np.sqrt(np.sum(x * x))
        length_of_line = nrm / mxm
        sample_probability = 1 / length_of_line
        if theSum == 0 or rand() > sample_probability:
            continue
        else:
            x = x / theSum
        return x

Here is the same function provided earlier by Amit Prakash, translated to python

import numpy as np

def f(N):
    while(True):
        count += 1
        x = np.random.rand(N)
        mxm = np.max(x)
        theSum = np.sum(x)
        nrm = np.sqrt(np.sum(x * x))
        length_of_line = nrm / mxm
        sample_probability = 1 / length_of_line
        if theSum == 0 or rand() > sample_probability:
            continue
        else:
            x = x / theSum
        return x
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文