【问题标题】:select a group of pairs in order to minimize rms of group选择一组对以最小化组的 rms
【发布时间】:2013-06-17 15:46:35
【问题描述】:

简化问题

我有大约 40 个电阻器(所有电阻值都相同 +-5%),我需要选择其中的 12 个,以便它们尽可能相似。

解决方案:我将它们按顺序列出,并以最小的 RMS 连续取 12 个。

实际问题

我有大约 40 个电阻器(所有电阻值都相同 +-5%),我必须选择其中的 12 个 ,以使这些对的电阻尽可能相似。

注意事项

对 (R1,R2) 的电阻为 R1+R2。 我并不真正关心编程语言,但假设我正在寻找 C++ 或 Python 的解决方案,这是我最熟悉的两种语言。

【问题讨论】:

  • 我能想到的唯一解决方案是计算所有 ~1600 对的电阻,订购它们,连续 12 个具有最小 RMS 并祈祷我没有选择两次相同的电阻。
  • 您想在...中执行此操作? MATLAB? C?
  • 加分:提出一个解决方案,用 12 个 triplets 电阻器解决相同的问题。
  • @RobertP。没关系,比方说 C++ 或 Python,我最熟悉的两种语言。
  • 如果一对是(R1,R2),该对的阻力是多少?您想最小化这 12 个成对电阻的 RMS 吗?还是您想选择 24 个电阻器并将其电阻的 RMS 降到最低?

标签: algorithm rms minimization


【解决方案1】:

这给出了相当好的结果(在 MATLAB 中)

a = ones(40,1) + rand(40,1)*0.1-0.05; % The resistors
vec = zeros(40,2);        % Initialize matrix
indices = zeros(40,2);    % Initialize matrix
a = sort(a);              % Sort vector of resistors
for ii = 1:length(a)
  vec(ii,:) = [a(ii) a(ii)];    % Assign resistor values to row ii of vec
  indices(ii,:) = [ii,ii];      % Corresponding resistor number (index)
  for jj = 1:length(a)
    if sum(abs((a(ii)+a(jj))-2*mean(a))) < abs(sum(vec(ii,:))-2*mean(a))
      vec(ii,:) =  [a(ii) a(jj)];    % Check if the new set is better than the
      indices(ii,:) = [ii, jj];      % previous, and update vec and indices if true.
    end
  end
end

[x, idx] = sort(sum(vec')');   % Sort the sum of the pairs 
final_list = indices(idx);     % The indices of the sorted pairs

这是我绘制它时的结果:

【讨论】:

  • 谢谢!我对 MATLAB 不太熟悉,你能描述一下你在做什么以便我可以实现它吗?
  • 抱歉,我没有时间...循环和 if 与 C++ 相同(语法除外)。第一部分只是内存分配和电阻列表的排序。对于所有电阻器,您将获得“最合适”的电阻器。那就是ii 最适合jjfinal_list 矩阵已排序,是您所追求的。
  • @muzzle:添加了一些 cmets。 sum, abs, mean, sort, length 等是 Matlab 中的内置函数,完全符合您的猜测。
【解决方案2】:

这不是最佳的,但应该会产生一些不错的结果。虽然它非常快,所以如果您需要从 10000 个电阻器中选择 1000 对...

#include <stdio.h>
#include <math.h>
#include <stdlib.h>
#include <time.h>

#define GROUPS 12
#define N 40

int compare (const void * a, const void * b)
{
  return ( *(int*)a - *(int*)b );
}

int main ()
{
    // generate random numbers 
    float *values = (float *)malloc(sizeof(float) * N);
    srand(time(0));
    for (int i = 0; i < N; i++)
        values[i] = 950 + rand()%101;

    qsort(values, N, sizeof(float), compare);

    // find "best" pairing
    float bestrms = -1;
    int beststart = -1;
    float bestmean = -1;
    for (int start = 0; start <= N - 2 * GROUPS; start++)
    {
        float sum = 0;
        for (int i = start; i < start + 2 * GROUPS; i++)
            sum += values[i];

        float mean = sum / GROUPS;

        float square = 0;
        for (int i = 0; i < GROUPS; i++)
        {
            int x = start + 2 * GROUPS - 1 - i;
            float first = values[start + i];
            // in a sorted sequence of 24 resistors, always pair 1st with 24th, 2nd with 23rd, etc
            float second = values[start + 2 * GROUPS - 1 - i];
            float err = mean - (first + second);
            square += err * err;
        }

        float rms = sqrt(square/GROUPS);       

        if (bestrms == -1 || rms < bestrms)
        {
            bestrms = rms;
            beststart = start;
            bestmean = mean;
        }
    }

    for (int i = 0; i < GROUPS; i++)
    {             
        float first = values[beststart + i];
        float second = values[beststart + 2 * GROUPS - 1 - i];
        float err = bestmean - (first + second);
        printf("(%f, %f) %f %f\n", first, second, first + second, err);
    }
    printf("mean %f rms %f\n", bestmean, bestrms);
    free(values);
}

【讨论】:

    【解决方案3】:

    对它们进行排序,然后将 1 与 2、3 与 4、5 与 6 配对,依此类推。找出每对之间的差异并再次排序,选择差异最小的 12 个。

    【讨论】:

      【解决方案4】:
      1. 按电阻排序
      2. 将 1 与 40、2 与 39 等配对,计算每对的 R1+R2 并选择 12 对的最佳集合(需要另一个排序步骤)。计算所有选择的平均值 (R1+R2)。
      3. 尝试将剩余的 16 个电阻之一插入所选的 24 个电阻中的一个,从而逐步完善此初始解决方案。如果新货币对的综合阻力比旧货币对的综合阻力更接近均值,则尝试会成功。重复此步骤,直到找不到任何进一步的改进为止。

      这个解决方案肯定不会总是计算出最佳解决方案,但它可能已经足够好了。另一个想法是模拟退火,但这需要更多的工作,并且仍然不能保证找到最佳解决方案。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2012-06-18
        • 1970-01-01
        • 2021-09-13
        • 1970-01-01
        • 1970-01-01
        • 2015-06-13
        • 1970-01-01
        • 2015-10-15
        相关资源
        最近更新 更多