Имея
- v = (vd + vb) / 2
- srr = (vd-vb) / v
- vd = 2 * pi * Rd* nd
- vb = 2 * pi * Rb * nb
возможные формулы (я удалил некоторые, не требующие ни одной дополнительной переменной (ей), такие как v = (vd-vb)/srr
, когда уже естьv = (vd+vb)/2
без необходимости срр ):
так что есть только 10 формул, если вам нравится программирование по данным:
#include <string>
#include <vector>
#include <iostream>
const double pi = 3.141592653589793;
// index in the vector of variables
enum VARS { VD, VB, V, SSR, RD, RB, ND, NB, NVARS };
// manages a var
struct Var {
std::string name;
bool set;
double value;
};
struct Formula {
bool (*pf)(std::vector<Var> & vars); // the function to do the work
VARS r; // the var set by the formula
std::vector<VARS> used; // the vars used by the formula
};
// the functions doing computations, one per formula
// they are called only when the used vars are set
// return false if divide by 0
bool fvd1(std::vector<Var> & vars)
{
vars[VD].value = 2*pi*vars[RD].value*vars[ND].value;
return true;
}
bool fvd2(std::vector<Var> & vars)
{
vars[VD].value = 2*vars[V].value - vars[VB].value;
return true;
}
bool fvb1(std::vector<Var> & vars)
{
vars[VB].value = 2*pi*vars[RB].value*vars[NB].value;
return true;
}
bool fvb2(std::vector<Var> & vars)
{
vars[VB].value = 2*vars[V].value - vars[VD].value;
return true;
}
bool fv(std::vector<Var> & vars)
{
vars[V].value = (vars[VD].value + vars[VB].value)/2;
return true;
}
bool fssr(std::vector<Var> & vars)
{
if (vars[V].value == 0)
return false;
vars[SSR].value = (vars[VD].value - vars[VB].value) / vars[V].value;
return true;
}
bool fRd(std::vector<Var> & vars)
{
if (vars[ND].value == 0)
return false;
vars[RD].value = vars[VD].value/(2 *pi * vars[ND].value);
return true;
}
bool fRb(std::vector<Var> & vars)
{
if (vars[NB].value == 0)
return false;
vars[RB].value = vars[VB].value/(2 *pi * vars[NB].value);
return true;
}
bool fnd(std::vector<Var> & vars)
{
if (vars[RD].value == 0)
return false;
vars[ND].value = vars[VD].value/(2 *pi * vars[RD].value);
return true;
}
bool fnb(std::vector<Var> & vars)
{
if (vars[RB].value == 0)
return false;
vars[NB].value = vars[VD].value/(2 *pi * vars[RB].value);
return true;
}
const std::vector<Formula> Formulas = {
{ &fvd1, VD, { RD, ND } }, // to compute VD by fvd1 the needed vars are RD and ND
{ &fvd2, VD, { V, VB } },
{ &fvb1, VD, { RD, NB } },
{ &fvb2, VD, { V, VD } },
{ &fv, V, { VD, VB } },
{ &fssr, SSR, { VD, VB, V } },
{ &fRd, RD, { VD, ND } },
{ &fRb, RB, { VB, NB } },
{ &fnd, ND, { VD, RD } },
{ &fnb, NB, { VB, RB } }
};
// try to apply the formulas
// do in a loop in the case newly computed var(s) allows
// to set other(s) and that independently of the order
// of the formulas
bool formulas(std::vector<Var> & vars, int & knownVars)
{
bool modified;
do {
modified = false;
for (const Formula & f : Formulas) {
if (!vars[f.r].set) {
bool ok = true;
for (VARS v : f.used) {
if (!vars[v].set) {
ok = false;
break;
}
}
if (ok) {
if (! (*f.pf)(vars))
return false;
vars[f.r].set = true;
modified = true;
knownVars += 1;
}
}
}
} while (modified);
return true;
}
// to do in a terminal without graphic
int main()
{
std::vector<Var> vars(NVARS);
vars[VD] = { "vd", false, 0 };
vars[VB] = { "vb", false, 0 };
vars[V] = { "v", false, 0 };
vars[SSR] = { "ssr", false, 0 };
vars[RD] = { "Rd", false, 0 };
vars[RB] = { "Rb", false, 0 };
vars[ND] = { "nd", false, 0 };
vars[NB] = { "nb", false, 0 };
int knownVars = 0;
do {
std::cout << "enter var ( ";
for (const Var & v : vars) {
if (!v.set)
std::cout << v.name << ' ';
}
std::cout << " ) ? ";
std::string s;
if (! (std::cin >> s)) {
// EOF
return -1;
}
std::vector<Var>::iterator it;
for (it = vars.begin(); it != vars.end(); ++it) {
if (!it->set && (it->name == s))
break;
}
if (it == vars.end())
std::cerr << "invalid name" << std::endl;
else if (std::cout << "enter value ? ", ! (std::cin >> it->value)) {
std::cerr << "invalid value" << std::endl;
std::cin.clear();
if (! (std::cin >> s)) {
// EOF
return -1;
}
}
else {
it->set = true;
knownVars += 1;
if (!formulas(vars, knownVars)) {
std::cerr << "divide by 0, abort" << std::endl;
return -1;
}
}
} while (knownVars != NVARS);
std::cout << "Done :";
for (const Var & v : vars)
std::cout << ' ' << v.name << '=' << v.value;
std::cout << std::endl;
return 0;
}
Я не использую Qt, но стандартную C ++ string / vector / IO, но это не меняет алгоритм
Компиляция и исполнение:
pi@raspberrypi:/tmp $ g++ -g -pedantic -Wextra -Wall f.cc
pi@raspberrypi:/tmp $ ./a.out
enter var ( vd vb v ssr Rd Rb nd nb ) ? vd
enter value ? 1
enter var ( vb v ssr Rd Rb nd nb ) ? nb
enter value ? 12
enter var ( vb v ssr Rd Rb nd ) ? vb
enter value ? 2
enter var ( Rd nd ) ? Rd
enter value ? 3
Done : vd=1 vb=2 v=1.5 ssr=-0.666667 Rd=3 Rb=0.0265258 nd=0.0530516 nb=12
pi@raspberrypi:/tmp $