我有~40个电阻(所有相同的值+ -5%),我需要选择其中的12个,以便它们尽可能相似。
解决方案:我按顺序列出它们,并以最小的RMS连续12次。
我有~40个电阻(所有相同的值+ -5%),我必须选择12个对,以便对的电阻尽可能相似。
该对(R1,R2)的电阻为R1 + R2。 我并不真正关心编程语言,但是我想说我正在寻找一种C ++或Python的解决方案,这是我最熟悉的两种语言。
答案 0 :(得分: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
这是我绘制时的结果:
答案 1 :(得分:1)
这不是最佳的,但应该给出一些不错的结果。如果您需要从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);
}
答案 2 :(得分:0)
对它们进行排序,然后将1与2,3配对,4与5配对,依此类推。找出每对之间的差异并再次排序,选择差异最小的12。
答案 3 :(得分:0)
这个解决方案肯定不会总是计算出最佳解决方案,但它可能已经足够好了。另一个想法是模拟退火,但这将是更多的工作,仍然不能保证找到最佳解决方案。