首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >选择一组对,以最小化组的均方根。

选择一组对,以最小化组的均方根。
EN

Stack Overflow用户
提问于 2013-06-17 15:46:35
回答 4查看 164关注 0票数 4

简化问题

我有~40个电阻(所有的值都是+-5%),我需要选择其中的12个,使它们尽可能相似。

解决方案:我列出它们的顺序,并采取与最小均方根连续12个。

实际问题

我有~40个电阻(所有的值都是+-5%),我必须选择12对,使它们的电阻尽可能相似。

备注

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

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2013-06-17 16:38:29

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

代码语言:javascript
复制
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

这就是我绘制它的结果:

票数 1
EN

Stack Overflow用户

发布于 2013-06-17 19:26:58

这不是最优的,但应该会带来一些不错的结果。它的速度非常快,所以如果你需要从10000个电阻中选择1000对.

代码语言:javascript
复制
#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);
}
票数 1
EN

Stack Overflow用户

发布于 2013-06-17 16:31:11

排序,然后配对1与2,3与4,5与6,等等。找出每对之间的差异,然后重新排序,选择差异最小的12。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/17151628

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档