#include #include #define MaxOdp 100 /* Velikost pole na odpory a jejich spojení */ #define MaxStr 300 /* Maximální délka zápisu zapojení */ #define Seriove 0 /* Odpor vznikl sériovým zapojením */ #define Paralelni 1 /* Odpor vznikl paralelním zapojením */ #define Dan 2 /* Odpor byl dán */ struct Odpor { /* Údaje o~jednom typu resistoru */ float Vel; /* Velikost odporu */ char Kolik; /* Počet odporů dané velikosti */ char Pouz; /* Počet použitých resistorů */ int Prvni; /* 1. resistor, který má cenu zkoušet spojovat */ int PocR; /* Počet resistorů potřebných k~vytvoření tohoto odporu */ int A, B; /* Čísla resistorů, z~nichž odpor vznikl */ char Typ; /* Typ zapojení */ }; struct Odpor Odpory[MaxOdp]; /* Odpory, kt. je možno poskládat */ int Poc; /* Počet odporů */ float Odp; /* Cílový odpor */ int MinOdp; /* Min. počet resistorů potřebný k~postavení výsl. odporu */ char Zapojeni[MaxStr]; /* Textové schéma výsl. zapojeni */ int ZapPos; /* Pozice v~předchozím poli */ float MaxR; /* Max. odpor, který je možno sestavit */ int Nacti (struct Odpor *Odpory) { /* Načte počáteční sadu odporů */ int i; int PocVel = 1; /* Počet počátečních velikostí odporů */ float R = 1; /* Velikost odporu */ printf ("Zadávej velikosti odporů resistorů, zadávání ukonči nulou...\nOdpor:"); scanf ("%f", &(Odpory[0].Vel)); if (!Odpory[0].Vel) return 0; /* Žádný odpor nebyl zadán */ Odpory[0].Kolik = 1; Odpory[0].Pouz = 0; Odpory[0].PocR = 1; Odpory[0].Typ = Dan; Odpory[0].Prvni = 0; Odpory[0].A = 0; Odpory[0].B = 0; MaxR = Odpory[0].Vel; while (R) { /* Načítej do zadání 0 */ printf ("Odpor :"); scanf ("%f", &R); for (i = 0; i < PocVel && Odpory[i].Vel != R; i++); /* Najdi odpor stejne velikosti */ if (i == PocVel) { /* Nebyl nalezen? */ Odpory[PocVel].Vel = R; /* Založí novou velikost odporu */ Odpory[PocVel].Kolik = 1; Odpory[PocVel].Pouz = 0; Odpory[PocVel].PocR = 1; Odpory[PocVel].Prvni = 0; Odpory[PocVel].A = 0; Odpory[PocVel].B = 0; Odpory[PocVel++].Typ = Dan; } else Odpory[i].Kolik++; /* Zvýší počet odporů dané velikosti */ MaxR += R; } return PocVel - 1; } void UlozZapoj (int Od) { /* Uložení zapojení odporu {\I Od} */ if (Odpory[Od].Typ == Dan) { /* Byl odpor dán? */ gcvt (Odpory[Od].Vel, 8, &Zapojeni[ZapPos]); /* Uloží velikost odporu zapojení do pole */ for (; Zapojeni[ZapPos]; ZapPos++); /* Nalezne konec řetězce */ } else { /* Uloží zapojení obou částí -- pro jistotu uzávorkuje */ Zapojeni[ZapPos++] = '('; UlozZapoj (Odpory[Od].A); if (Odpory[Od].Typ == Seriove) Zapojeni[ZapPos++] = '+'; else Zapojeni[ZapPos++] = '*'; UlozZapoj (Odpory[Od].B); Zapojeni[ZapPos++] = ')'; } } void Zapoj (int Pos) { /* Provede všechna zapojení odporu {\I Pos} */ int i; /* Odpor, se kterým se spojím */ int OPrvni; /* Původní odpor ke~spojení */ while (Odpory[Pos].Pouz == Odpory[Pos].Kolik) Pos++; /* 1. nepoužitý odpor */ if (Odpory[Pos].Vel == Odp && Odpory[Pos].PocR < MinOdp) { /* Dosáhl jsem cíloveho odporu použitím doposud nejmenšího počtu resistorů */ ZapPos = 0; UlozZapoj (Pos); /* Uloží zapojení */ Zapojeni[ZapPos] = '\0'; MinOdp = Odpory[Pos].PocR; /* Uschová nový minimální počet */ } if (Pos + 1 < Poc) Zapoj (Pos + 1); /* Ještě další odpor $\Rightarrow$ nejdříve se {\I Pos} nezapojí */ Odpory[Pos].Pouz++; /* Tento odpor bude použit */ Odpory[Poc++].A = Pos; /* Nový odpor vznikne z~tohoto a jiného */ OPrvni = Odpory[Pos].Prvni; /* Pouhé uchování pro pozdější obnovení */ for (i = Odpory[Pos].Prvni; i < Poc - 1; i++) { /* Najdi všechny odpory, s~nimiž lze {\I Pos} spojit */ if (Odpory[i].Pouz < Odpory[i].Kolik && (i >= Pos || (i < Odpory[Pos].A && i < Odpory[Pos].B))) { Odpory[Pos].Prvni = i + 1; /* S~odporem dané velikosti jsem už prozkoušel vše až do {\I První} */ Odpory[i].Pouz++; /* Odpor použiji k~zapojení */ Odpory[Poc - 1].Pouz = 0; /* Nový odpor ještě nepoužit */ Odpory[Poc - 1].Kolik = 1; /* Vytvoří se pouze jeden odpor */ Odpory[Poc - 1].PocR = Odpory[Pos].PocR + Odpory[i].PocR; /* Potřebný počet resistorů */ Odpory[Poc - 1].B = i; /* druhy odpor zapojeni je {\I i} */ Odpory[Poc - 1].Typ = Seriove; /* Typ zapojení je nejprve sériové */ Odpory[Poc - 1].Vel = Odpory[Pos].Vel + Odpory[i].Vel; /* Výsledný odpor zapojení */ Zapoj (Pos); /* Vzhůru na další odpory, ješte nejsme u~cíle */ Odpory[Poc - 1].Typ = Paralelni; /* Po návratu z~rekurze zkus paralelní zapojení */ Odpory[Poc - 1].Vel = Odpory[Pos].Vel * /* Velikost odporu paralel. zapojení */ Odpory[i].Vel / (Odpory[Pos].Vel + Odpory[i].Vel); MaxR = MaxR - Odpory[Pos].Vel - Odpory[i].Vel + Odpory[Poc - 1].Vel; /* Max. odpor, kterého je ještě možno dosáhnout */ if (MaxR >= Odp) Zapoj (Pos); /* Je-li šance dosáhnout výsledku, zkoušej dále */ MaxR = MaxR + Odpory[Pos].Vel + Odpory[i].Vel - Odpory[Poc - 1].Vel; /* Obnov {\I MaxR} */ Odpory[i].Pouz--; /* Odpor už nebude potřeba */ } } Odpory[Pos].Pouz--; /* Tento odpor nebude v~zapojení */ Poc--; /* Vytvářený odpor už byl všude v~kombinaci vyzkoušen */ Odpory[Pos].Prvni = OPrvni; /* Obnov původního prvního */ } int main (void) { Poc = Nacti (Odpory); printf ("Cílový odpor: "); scanf ("%f", &Odp); MinOdp = MaxOdp; Zapoj (0); if (MinOdp < MaxOdp) printf ("Zapojení: %s\n", Zapojeni); else printf ("Zapojení neexistuje. \n"); return 0; }