【问题标题】:Algorithm to map an interval to a smaller interval将区间映射到较小区间的算法
【发布时间】:2012-10-07 12:31:34
【问题描述】:

我尝试搜索,但由于我的问题的性质,我无法找到令人满意的内容。

我的问题如下:我正在尝试将范围从 0 到 2000 的数字(尽管理想情况下上限可以调整)映射到从 10 到 100 的更小的区间。上限将映射 (2000-> 100) 以及下限。除此之外,比区间 [0;2000] 中的另一个条目大的条目理想情况下会大于 [0;100] 中的映射条目

我认为这个问题不是特定于语言的,但如果您想知道,我今天正在使用 Javascript。

【问题讨论】:

  • 您的范围是整数还是实数/浮点数/小数?您是否需要源中的不同条目来映射到目标中的不同条目?
  • 刚输入这个问题后,我想出了一个(对我而言)可接受的解决方案:我计算了第一个条目在其区间内的百分比值,然后将该百分比转换为新区间。

标签: algorithm mapping distribution


【解决方案1】:

使用 Python 中的 Numpy 的答案:

import numpy as np  

# [A, B]: old interval
# [a, b] new interval
new_value = np.interp(old_value, [A, B], [a, b])
print(new_value)

【讨论】:

    【解决方案2】:

    我认为与其给你一个直接映射的公式,更好的方法是解释它背后的想法:

    假设我们要将区间 [0,1] 映射到区间 [1,3],这可以看作是找到 f(x) = Ax + B 的问题,使得从区间 [0, 1],将导致 f(x) 处于/导致区间 [1,3]。

    从这个角度,我们已经知道了一些价值观:

    1. x = 0 & f(0) = 1 => f(0) = A*0 + B = 1 => B = 1
    2. x = 1 & f(1) = 3 => f(1) = A*1 + B = 3 A + 1 = 3 => A=2

    从(1)和(2)我们可以得出,区间[0,1]到[1,3]的映射函数是f(x) = 2x + 1。

    就您而言,您现在应该具备将 [0,2000] 区间映射到 [10,100] 的所有必要知识。

    【讨论】:

      【解决方案3】:

      这可能是映射 x 数据的优化方法, 此伪代码向您展示了 map 函数的主要思想 那:

      • 避免 x 值超出 b1 - b2 范围的问题。
      • 处理数组映射

        function map(var x, var b1, var b2, var s1, var s2)
        {
            var i;
            var result;
        
            i = 0;
            while(i < sizeof(s2))
                if(x < b1)
                    result[i++] = s1;
                else if (x > b2)
                    result[i++] = s2;
                else
                    result[i] = (x - b1) / (b2 - b1 ) * (s2[i] - s1[i]) + s1[i++];
            return (result);
        }
        

      【讨论】:

        【解决方案4】:
        // Given a value from intervalA, returns a mapped value from intervalB.
        function intervalicValueMap(intervalA, intervalB, valueIntervalA) {
            var valueIntervalB = (valueIntervalA - intervalA[0]) * (intervalB[1] - intervalB[0]) 
                                    / (intervalA[1] - intervalA[0]) + intervalB[0];
        
            valueIntervalB = Math.round(valueIntervalB); // Ommit rounding if not needed.
            return valueIntervalB;
        }
        
        var intervalA = [100, 200];
        var intervalB = [1, 10];
        var valueIntervalA = 170;
        var valueIntervalB = intervalicValueMap(intervalA, intervalB, valueIntervalA);
        
        console.log(valueIntervalB); // Logs 7
        

        【讨论】:

          【解决方案5】:
          To map
          [A, B] --> [a, b]
          
          use this formula
          (val - A)*(b-a)/(B-A) + a
          

          正如另一个答案中正确提到的那样,它是线性映射。

          基本上

          y = m*x + c
          
          c = intersection at y-axis
          m = slope determined by two known point (A, a), (B, b) = (b-a)/(B-A)
          

          【讨论】:

          • 我最终做了一些看起来非常相似的事情。上面有描述,但是脚本在这里:(nMinValue是B,nMaxFontSize是a)var nPercentage = ((modifier-nMinValue)/(nMaxValue - nMinValue))*100; var nFontSize = parseInt((nBiggestFont-nSmallestFont)*(nPercentage/100)+nSmallestFont);
          【解决方案6】:

          一个简单的线性映射会将x 映射到x*90/2000+10

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2021-11-12
            • 2018-12-30
            • 1970-01-01
            • 1970-01-01
            • 2020-03-13
            • 2017-10-08
            相关资源
            最近更新 更多