2014 dxdy logo

Научный форум dxdy

Математика, Физика, Computer Science, Machine Learning, LaTeX, Механика и Техника, Химия,
Биология и Медицина, Экономика и Финансовая Математика, Гуманитарные науки




Начать новую тему Ответить на тему
 
 Резисторы
Сообщение14.02.2010, 23:46 


27/10/09
13
Радиолюбитель Петя решил собрать детекторный приемник. Ему понадобился резистор с сопротивлением R Ом. В распоряжении Пети есть набор из n резисторов, сопротивления которых равны r1, r2, ... , rn Ом соответственно. Петя помнит, как вычисляется сопротивление последовательного соединений двух резисторов Rnew = R1 + R2 и параллельного соединения двух резисторов Rnew = (R1 * R2) / (R1 + R2). Петя хочет спаять некоторую последовательно-параллельную схему из имеющегося набора резисторов такую, что ее сопротивление ближе всего к R Ом (то есть абсолютная величина разности значений должна быть минимальна).
Напомним, что схема, составленная из одного резистора, -- последовательно-параллельная схема. Любая схема, полученная последовательным соединением двух последовательно-параллельных схем, -- последовательно-параллельная, также любая схема, полученная параллельным соединением двух последовательно-параллельных схем, -- последовательно-параллельная.
Разумеется, Петя не обязан использовать для изготовления схемы все имеющиеся резисторы.

Входные данные
В первой строке входного файла заданы числа n, R (1 <= n <= 7; 10 <= R <= 3000). Число R - вещественное, заданное не более чем с 4 знаками после запятой. Во второй строке содержится последовательность сопротивлений имеющихся в наличии резисторов r1, r2, ... , rn. Значения всех сопротивлений могут быть вещественными числами от 10 до 3000.

Выходные данные
В выходной файл необходимо вывести сопротивление такой схемы, сопротивление которой меньше всего отличается от R. Сопротивление выведите не менее чем с 6 знаками после десятичной точки.

Пример

Ввод
3 1.66
1 2 1

Вывод
1.666666666666666
Код:
#include "stdafx.h"
#include <iostream>
#include <cmath>
using namespace std;

double b[20],a[20];
int n,k;
double rx,r0,result=1e20;

void brute (double r,int pos) //процедура рекурсивного перебора
{
   if (pos==k)
   {
      if (fabs(r0-r)<result) {result=fabs(r0-r);rx=r;}
    }
   else
   {   
      brute(r+a[pos],pos+1);

      brute(r*a[pos]/(a[pos]+r),pos+1);
   }
}

int main()
{
   cin>>n>>r0;

   for (int i=0;i<n;i++) cin>>b[i];

   for (int i=0;i<(1<<n);i++)
   {
      for(k=0;k<n;k++) a[k]=0;

      k=0;

      for (int j=0;j<n;j++)
      {
         if ((i & (1<<j))!=0) {a[k]=b[j];k++;} //выбираю из заданного набора некоторое подмножество
      }

      if (k!=0)
      {
         brute(a[0],1); //пробегаю по подмножеству и ищу сопротивление, наиболее близкое к заданному
      }
   }
   
   cout.precision (10);
   
   cout<<fixed<<rx<<endl;
   
   return 0;
}

Программа перебирает далеко не все возможные варианты соединения резисторов, поэтому вопрос: как лучше переделать программу, чтобы она полноценно работала?

 Профиль  
                  
 
 Re: Резисторы
Сообщение15.02.2010, 12:55 


27/10/09
13
Слышал, что можно сделать следующим образом: ищем все подмножества для набора резисторов, потом делаем разбиение каждого подмножества еще на 2 не пересекающихся. Но вот что дальше делать не понял, есть идеи, господа?

 Профиль  
                  
 
 Re: Резисторы
Сообщение15.02.2010, 14:52 


02/07/08
322
В порядке увеличения числа резисторов в подмножестве проходим по ним и записываем все возможные сопротивления, которые из них можно получить. Чтобы не плодить одни и те же результаты, нужно или ввести структуру данных типа дерева поиска, или сперва всё записывать в массив, потом его сортировать и потом удалять дубликаты (при этом в силу погрешностей при работе с числами с плавающей запятой сравнивать нужно не на равенство, а, например, на то, что модуль разности не более $10^{-10}$).

 Профиль  
                  
 
 Re: Резисторы
Сообщение15.02.2010, 15:00 


27/10/09
13
Cave в сообщении #289242 писал(а):
Записываем все возможные сопротивления, которые из них можно получить.

А как считать эти самые всевозможные сопротивления? Для 7 резисторов, например, существует большое количество всевозможных комбинаций, как рассмотреть их все?

 Профиль  
                  
 
 Re: Резисторы
Сообщение15.02.2010, 22:38 


02/07/08
322
Вы же сами написали: перебрать всевозможные разбиения на два непересекающихся подмножества. Для каждого из них ответ посчитан. Все варианты для них нужно соединить поочерёдно последовательно и параллельно.
Сложность алгоритма с ходу не скажу, тут непросто подсчитать число различных вариантов для каждого подмножества.

 Профиль  
                  
 
 Re: Резисторы
Сообщение15.02.2010, 23:17 


27/10/09
13
Cave в сообщении #289365 писал(а):
Вы же сами написали: перебрать всевозможные разбиения на два непересекающихся подмножества.

Проблема была с реализацией этого разбиения, но она уже решена.
Спасибо всем отписавшимся.

 Профиль  
                  
Показать сообщения за:  Поле сортировки  
Начать новую тему Ответить на тему  [ Сообщений: 6 ] 

Модераторы: Karan, Toucan, PAV, maxal, Супермодераторы



Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group