Szukam jakiejś rady, wskazówki do tego, w jaki sposób programowo wyznaczyć rezystancję (w uproszczeniu) zastępczą dowolnego układu. Jeśli będzie to ułatwieniem, to pominę wszelkie trójkąty.
To co mam, to ciągi elementów od punktu źródłowego do punktu docelowego, z tym że są one niezależne (nie widzą się wzajemnie, choć pokrywają w szeregu). Generalnie przemieszczać się po nich można tylko w jednym kierunku.
Czy ktoś wie, w jaki sposób w zasadzie symuluje się rezystancje obwodów?
(upraszczam z tymi rezystancjami bo generlanie chodzi o impedancje z uwzględnieniem transformatorów, ale to już nie problem).
Niestety - potrzebuję właśnie wyznaczyć prąd Konkretnie to mam dane reaktancje i rezystancje elementów oraz napięcie na elementach + przekładnie transformatorów. Potrzeba wyznaczenia m.in. prądu zwarciowego.
Odpowiem nieco nieporządnie, jak to w niedzielę po obiadku...
Najpierw co dla czystych rezystancji:
- startując z pierwszego wyróżnionego wierzchołka grafu (źródło, source) do drugiego wyróżnionego wierzchołka (zlew, sink);
- piszemy układ równań, numerujemy rezystory, numerujemy (losowo lub arbitralnie) końce rezystorów (1 lub 2) i dla każdego mamy równanko Vk2-Vk1=Rk*Ik
Dla każdego węzła gdzie spotyka się n elementów piszemy n-1 równań typu Vk1=Vp2, Vk1=Vp1 lub Vk2=Vp2. I jeszcze jedno równanie typu Ik+Ip+...+Id=0.
Wszystkie można zapamiętać jako warianty równania :
ΣAn•Vn=Σbn•In
gdzie An=(0,1,-1), Bn=(0,1,-1,Rn) stosownie do potrzeb
jeszcze trzeba dodać warunek na napięcie początkowego i końcowego i zmodyfikować prądy w startowym i końcowym węźle (bo tam z zewnątrz wpływa i wypływa).
Układ równań rozwiązać.
Dla reaktancji nieco trudniej:
1. może da się na zespolonych, ale jest niedziela i tego nie trenowałem
2. próbowałem za to metodą Gaussa
Ale teraz widzę że to jest raczej do rozwiązywania przypadku w Real Time gdy z zewnątrz jest podawany arbitralnie zmienny sygnał (prąd albo napięcie) a układ obliczeniowy ma zwracać drugi sygnał (napięcie albo prąd).
Mimo to napiszę
rozwiązuje się w kolejnych iteracjach co mały odstęp czasu dt
trzeba pozapamiętywać prądy, napięcia i ładunki w kondensatorach z jednaj iteracji i w następnej liczyć:
rezystancje jak wyżej,
indukcyjności U=-L•dI/dt zmienić w U=-L•(Inew-Iold)/dt
pojemności Q=∫I•dt , U=Q/C zmienić w Qnew=Qold+Inew•dt , U=Qnew/C
i metoda rachunkowa zbliżona do poprzedniej.
Z transformatorami nieco trudniej, ale to w zasadzie skomplikowanie rachunkowe.
Tą metodą można też spróbować wyznaczyć impedancję zastępczą, przeliczając kilka okresów danej częstotliwości (sinus) i dzieląc powiedzmy szczytowe napięcia oraz porównując fazy możemy wnioskować o impedancji.
W prostych przypadkach dokładność rozwiązania zwieksza się zmniejszając krok czasowy dt (zwiększając ilość obliczeń).
Problemy zaczną się gdy w układzie pojawią się elementy o dużym rozrzucie wartości (kilka i więcej rzędów wielkości) wtedy robi się z tego układ równań różniczkowych sztywnych i metoda Gaussa żle działa.
Trzebaby wtedy zatrudnić bardziej wyrafinowane metody, właśnie dedykowane do sztywnych układów. Takie problemy na przykład mogą wystąpić przy analizie efektów włączeniowych.
Ciekawe czy coś da się z tych niedzielnych rozważań zrozumieć?
Jeśli dobrze pamiętam, to metoda potencjałów węzłowych chyba to jest... (jej, 6 lat temu ostatnio to widziałem ) Notabene, jakoś w necie brakuje dobrych przykładów :/
Kłopot jeden w tym, że wygodniej byłoby liczyć od końca do źródeł. Ale to ujdzie... Ale pogubiłem się chyba w punkcie "napięcie początkowego i końcowego i zmodyfikować prądy w startowym i końcowym węźle".
Ale jeszcze co do równań - dla obwodu prądu zmiennego czy przypadkiem nie wchodzi gdzieś w te równania pierwiastek?
Do miejsca gdzie rozumiałeś było o sieci nie podłączonej do niczego.
trzeba dodać że dwa końce są pod napięciem i zmienić sumy prądów na wejściu i wyjściu, bo na wejściu wpuszczasz prąd, a na wyjściu wypuszczasz.
W zasadzie to tylko źródła będą pod napięciem - przypomnę, że chodzi o wyznaczenie prądu w stanie zwarciowym.
Najgorsze w tym wszystkim jest to, że o ile "ręcznie" nie ma problemów z liczeniem, to przeniesienie tego na komputer już niestety wymaga często niekonwencjonalnych rozwiązań i spojrzeń na problem.
Jeszcze tylko pytanie takie: Vk to potencjał na węźle, tak? a Vp?
To są przykładowe literki, w tym wypadku rezystor K jest połączony z rezystorem P więc koniec jednego ma ten sam potencjał co koniec drugiego.
Czy jest to wzorek z indeksami 1,1 1,2 2,1 czy 2,2 to już zależy od przyjętego sposobu numerowania końców.
Tylko pilnuj czy nie podłączysz obu końców razem...
Aha, to już rozumiem No cóż, dzięki za to... Będę zastanawiał się, co mi łatwiej będzie zaimplementować... Ale jeśli by ktoś znał być może jeszcze jakąś metodę ciekawą godną zastosowania w programie (złożoność obliczeniowa nie ma znaczenia, lecz łatwość przeniesienia (rozdział i/lub rekurentyzacja problemu) owszem
Może późno już i do tego niedziela, ale mimo wszystko za Chiny Ludowe nie bardzo wiem, jak z tego przejść do mojej rezystancji zastępczej. A poza tym jeśli mam idealne źródło napięciowe, to przechodząc na prądowe... no ale ja przecież dążę do wyznaczenia konkretnego prądu, więc nie mogę mieć idealnego źródła prądowego, czy tak? Chyba się gubię w tym wszystkim
No i jeszcze jeden problem - co z gałęziami o zerowym oporze? Konieczne będzie ich redukowanie?
Zdecyduj się na taki formalizm który rozumiesz, nie musisz pisać SPICA od nowa, ani wchodzić w cudze buty.
Używanie idealnego źródła służy temu żevbyś w trakcie rachunków ie rozmyślał o poziomie i temperaturze elektrolitu w akumulatorze.
Ja niestety jestem z trochę innej bajki, wymysły teoretyków elektryków nie zawsze w pełni do mnie trafiają.
Szczególnie że ostatnio muszę napięcia wyrażać w hektopascalach a prądy w litrach na minutę; no i cewka staje się już inertancją.
A swoją drogą to co rozumiesz przez prąd zwarciowy? Czy ma to być prąd ustalony po długim czasie przy podłączeniu napięcia stałego?
Sorry jest już trochę późno, niecałkiem niedziela i mam też niewco roboty.
Niestety w przyszłym tygodniu będę mało dostępny (od wtorku, konferencja).
Ale może pokaż jak skomplikowany jest ten układ (rodzina układów) którą masz liczyć...
Prąd zwarciowy to dla mnie tutaj wartość skuteczna prądu zwarciowego ustalonego w układzie prądu zmiennego (3-fazowego).
Wyliczany ze wzoru:
Ik"=(1.1*Un)/(√3*|Z|)
gdzie Un - poziom napięcia, na jakim wystąpiło zwarcie (teoretyzując - źródło napięciowe)
|Z| - moduł impedancji zastępczej sieci.
Dane są połączenia oraz wszystkie rezystancje i reaktancje elementów.
Układ do liczenia w założeniach jest nieograniczenie skomplikowany (użytkownik sam projektuje sobie układ w programie) Jedyne uproszczenia jakie można by przyjąć, to eliminacja trójkątów i gwiazd. No i operujemy wyłącznie na impedancjach - nie ma elementów indukcyjnych i pojemnościowych.
No to wychodzi na to że prawie dokładnie musisz tego Spica napisać.
Moje pomysły.
Na początek powinieneś zrobić układ czterech węzłów (fazy i zero, albo bez zera), i trzech źródeł i do tego trzy rezystancje nieskończone (jeśli możesz rachować na nieskończonych).
I to powinno się policzyć z wynikiem I=0.
Do tego teraz edytor schematów i tu już musisz przewidzieć kodowanie kolejnych elementów tak żeby łatwo potem tworzyć schemat obliczeniowy.
Przewidywałbym dwie typowe operacje:
- dodanie nowego węzła "w powietrzu",
- wstawienie dwójnika między dwa istniejące węzły.
I teraz mechanizm tworzeniaukładu równań itp. na konkretnych, ciągle jeszcze prostych danych typu trójkąt jednakowych rezystorów albo gwiazda z uziemionym środkiem, potem gwiazda z nierównych, potem bez uziemienia środka.
Jak to pójdzie to wtedy reaktancje i na koniec jakieś podłe rozbudowane schematy do sprawdzenia.
No nie zazdroszczę zajęcia...
Część graficzno-projektowa już jest wykonana Także reprezentacja w pamięci układu jest wykonana
Pokażę taki przykład (z Electronics WorkBench):
Generalnie macierz mi wychodzi taka (oznaczenia G równoznaczne z wartościami R):
Code:
[G2+G4 -G2-G4 ][V1] [I]
[-G2-G4 G2+G4+G6][V2]=[0]
V1 jest dane, prawda? (napięcie źródła) - w tym przypadku 6kV.
Mnożąc macierze i układając równanie można dojść m.in. do takiego wyniku:
V2=6I
Pozostaje to tlyko wyliczyć. I się nawet zgadza A potem zastępczna z prawa Ohma.
Założenia chyba mam poprawne, prawda? Kwestia to teraz przekształcić cały układ tak, aby wyznaczyć owe I. Myślalem tu o natychmiastowym tworzeniu układu równań (macierzowego) gdzie wyrazami wolnymi byłby potencjał V1, zaś niewiadomymi wektor prądów (pionowy: [I 0 0 ...]) i pozostałych potencjałów. Wyjdzie mniej więcej coś takiego chyba:
Code:
[-1 G12] [G11*E]
[0 G22]=[G21*E]
Teraz bo pozostało wyznaczyć wyznacznik główny oraz wyznacznik kolumny I i w ten sposób
I=W(I)/W
dobrze rozumuję?
Generalnie program mój (a w zasadzie to, co stworzone za jego pomocą - nie bardzo mogę udostępniać całość) i zadanie wygląda mniej więcej tak:
Czyli z danego schematu tworzy schemat reaktancyjny zastępczy. No i właśnie potrzeba wyznaczyć ową reaktancję zastępczą. Oczywiście przedstawiłem banalny przykład, bo uklady są bardziej skomplikowane
Zronbiłem przykład z EWB, miał 2 węzły z tego jeden uziemiony.
Jak dołożyłem węzeł w miejscu w którym dałeś masę to już nie wyszło, pewnie walnąłem błąd w znaku.
Zdarza się. Warto wyrobić nawyk kopiowania do schowka
qrdel wrote:
Zronbiłem przykład z EWB, miał 2 węzły z tego jeden uziemiony.
Jak dołożyłem węzeł w miejscu w którym dałeś masę to już nie wyszło, pewnie walnąłem błąd w znaku.
Chwilowo tyle mogłem...
Teoretycznie węzeł (3) nie powinien chyba wpływać na wyniki? A może się mylę, bo teoria mówi w zasadzie o węźle będącym punktem odniesienia, który w problemie rzeczywiście ma potencjał 0. No ja też zapisałem całą kartkę i aż się boję to przenosić do kompa, skoro przy dwóch już się można zgubić
Co do znaków, to gdzieś mi się raz obiło, że zaznacza się zgodnie ze strzałkowaniem do węzła końcowego (czyli prądy wchodzące do węzła powodują uwzględnianie przewodności dodatniej tej gałęzi, zaś dla wychodzących bierze się przewodność ze znakiem minus). No ale tutaj wyczytałem (dokument ten wcześniej podany) że dla wartości własnych węzła zawsze ze znakiem "+", zaś dla wzajemnych - zawsze ze znakiem "-". Choć może by na jedno wyszło?
A tak się zastanawiam, a może to zbieg okoliczności, że mi wyszło tylko przy tych dwóch węzłach Ale dłużej się zastanawiając, to jeśli potencjał (3) jest znany i wynosi 0, to nie ma sensu go uwzględniać w równaniu macierzowym, bo 3 kolumna i 3 wiersz konduktancji i tak zostanie przemnożony przez 0.
Pozwolę sobie napisać nowy post, bo w zasadzie jest to całkiem nowa myśl, jednak wciąż należąca do tematu.
Program już buduje pięknie macierz konduktancji i wylicza układ równań, ale... Nie zawsze.
Okazało się, że stosowanie na każdym elemencie jakiejś rezystancji, aby nie spowodować dzielenia przez 0 jest rozwiązaniem, które jednak mocno fałszuje wyniki. Problem sprowadził się więc do czegoś takiego:
Istnieje konieczność ponumerowania węzłów ale węzły, które łączy nieskończona konduktancja (brak rezystancji) muszą przyjąć ten sam numer.
Problem polega właśnie na tym, jak zrobić to zadanie na takiej strukturze:
Strzałki to kierunki po jakich można się poruszać, a jednocześnie odwrotności dróg jednokierunkowych pomiędzy źródłem a celem. W programie są to wskaźniki na kolejne elementy.
Czarne numery wskazują numery wyjść z węzła
Czerwone numery to oczekiwana numeracja węzłów (oczywiście chodzi tutaj wyłącznie o zgodność, aby węzły, których nie dzieli żaden element miały nadany ten sam numer, wartości nie muszą być w takiej kolejności zachowane)
Mnie już chyba z przemęczenia pomysłów brakuje A czas coraz bardziej goni.
No sorry, miałem 2 godziny w nocy to potrenowałem metodę, właśnie po to żeby spróbować zrozumieć.
A wyszło jak zwykle.
Ja zresztą mam tu cały czas na oku mój mały partykularny interes, czyli moje równania różniczkowe sztywne dla sieci RLC.
To teraz na temat.
Do zwijania/skracania sieci proponuję procedurę która inteligentnie przepisze strukturę sieci na nowo skracając co trzeba.
Ale wszystko jak w szkolnym programiku, chodzenie po drzewie i przepisywanie wartości na nowe drzewo.
I dopiero na to nowe drzewo napuszczać Twój znakomity algorytm.
A czy ostatecznie ma powstać produkt hadlowy czy raczej prca naukowa (dokładnie to czy będzie chroniony jakimś rodzajem tajemnicy, czy w miarę jawny)?
Bo jak jawny, to chętnie bym zobaczył opis/publikację jak będzie gotowe (sam produkt raczej do niczego mi się nie nada).
No tyle, że chodzenie inaczej, niż rekurencyjnie nie bardzo chyba się nadaje... w zasadzie czy skracanie (które nie do końca wchodzi w grę przez wzgląd na inne części programu), czy numeracja to chyba jedno... Tylko chodzenie po tym jest mało wygodne, bo wszystko zależny od stanu całości cały czas. A optymalnie byłoby najpierw przypisać te same numery połączeniom bezpośrednim, a dopiero później pośrednim... Tylko czasu mało, a im bardziej złożony algorytm tym więcej czasu na jego testowanie.
Chwilowo jest tak, że próbuję forsować nową numerację na połączeniach bezpośrednich niezależnie od nadanej do tej pory... (przykładowo - przejście z węzła 0 do 1 i przez drugi element wracamy na 0, ale że program nie widzi - nadaje mu numer 2. Dopiero później idąc drugą drogą nadpisuje... Ale jakoś nie jestem przekonany do tego algorytmu.
Osobiście chciałbym uczynić to produktem handlowym, ale promotorka strasznie naciska, aby program był edukacyjnym dla laboratoriów... Nie do końca się orientuję, czy politechnika nie położy łapy na prawach majątkowych do programu...
Na chwilę obecną przez wzgląd na system antyplagiatowy muszę utrzymywać program w miarę bezpiecznym otoczeniu, lecz po obronie z pewnością trochę informacji wypuszczę...
Pomyśleć, że za tego typu programy, jeszcze w dodatku z racji, że branżowy i to w wąskiej dziedzinie, można by nawet do 100000 zainkasować... A tu za darmo każą robić i jeszcze gonią i oczekują, że program będzie lepiej wiedział od uzytkownika, co ten chce zrobić
Rozumiem że w drzewku na węźle M masz zapisane :
- istnieje krewędź do węzała K, ma ona konduktancję Gmk
- istnieje jeszcze inna ...
- ...
- więcej krawędzi nie ma
Dowal do tego jeden albo i dwa bity na każdą gałąź i najpierw puść procedurkę zliczania numerków; w tablicy Mx2 (M ilość węzłów) w kolumnie 1 zapisujesz wszystkie węzły do których referencje napotkałeś, a w kolumnie 2 dopisujesz węzeł jeżeli jest z tym wpisanym po lewej połączony konduktancją nieskończoną.
Po każdym "sprawdzeniu" konduktancji zaznaczaj flagę, aż całe drzewo zaznaczysz.
Potem "pozbieraj" wszystkie utożsamienia węzłów i utwórz uporządkowane listy poutożsamianych węzłów.
Np.
"zasilanie" (1, 2, 3, 5, 7, 13, 21)
"masa" (0, 8, 9, 14, 15, 17, 23)
"x1" (4)
"x2" (6, 10)
"x3" (11)
...
I oczywiście zaczynasz przepisywać drzewko, tak jakby user od nowa wprowadzał dane tylko że:
- dane bierzesz z drzewka
- wpisujesz/użytkujesz tylko lewy skrajny numer z listy węzłów utożsamionych
- nieskończone konduktancje olewasz
- każdą obsłużoną konduktancję zaznaczasz drugą flagą
aż do zaznaczenia całego drzewka.
Co do produktu, to są pewne standardowe metody robienia dwóch wersji dydaktycznej i profesjonalnej; tylko je skopiować:
- w dydaktycznej nie działa funkcja save/load
- dydaktyczna ograniczona do 10 gałęzi
- dydaktyczna przed zmianą ekranu na 10 sek. wyświetla odp. napis, reklamówkę jak kupić
- profesjonalne są personalizowane, nazwa klienta wpisana dosłownie wszędzie, na ekranie, na wydrukach itp.
- ewentualnie jakieś hasła
- elementy typu: nazwisko autora, placówka autora, nazwa klienta wprute w program głęboko, kody CRC z obszaru napisów, zmiennych itp. są parametrami procedur obliczeniowych, lub warunkami realizacji kolejnego kroku (żeby zmiana napisu rozwalała program).
Co do tekstu to interesuje mnie ew. sam tekst doktoratu czy co to ma tam być.
Co do upraszczania sieci, to walor edukacyjny, może mieć zaprezentowanie klientowi schematu uproszczonego graficznie.
No i niestety, jak robisz to na uczelni państwowej czy czymś podobnym - to państwo chce mieć z tego korzyść; w Stanach wszystkie prace powstałe na grantach są bezpłatnie publicznie dostępne (przetestowałem to na NECu, udało mi się znaleźć oryginalną wersję, niestety Fortran).
Inne placówki też jeśli robisz coś na ich etacie albo używając ich zaplecza to mogą chcieć korzyści (albo forsa dla nich, albo ich studenc, pracownicyi wszystkie prawa) a Tobie goła pensja i uścisk dłoni prezesa.
Najsensowniej jest przewidzieć sytuację wcześniej i działalność rozpoczynać jako współpracę placówki z małą firmą (choćby jednoosobową) przy wyraźnej umowie o wkładzie sił i środków, oraz warunkach podziału zysków.
Typowe rozwiązania (dotyczy akurat sprzętu) to sprzedaż produktu w cenie wynikającej z: kosztów wynagrodzenia (godnego) autorów opracowań rozliczonego na małą serię produkcyjną (tyle co można przewidzieć do ssprzedania powiedzmy w pół roku), plus koszt materiałów, wynagrodzenia całego cyklu produkcyjnego i do tego sensowna marża zysku dla firmy, jeśli do sieci handlowej to jeszcze marża handlowa. Instytucja jest umieszczona na procencie marży firmy, albo konkretnie kwotowo (tutaj firma zewnętrzna produkuje i sprzedaje, a instytucja jest tylko wymieniana jako współautor i odcina zyski).
Często nawet kilkuzłotowy zysk jest dla instytucji wystarczający, bo załatwia im prestiżowo/sprawozdawczą potrzebę wykazania posiadania wdrożeń, efekt finansowy przede wszystkim musi istnieć, niekoniecznie wielki.
PRouteItem=^TRouteItem;
TRouteItem=record
NodeNum: Integer;
Element: PCircuitElement;
Next: array[0..3] of PRouteItem; //0 tworzy listę; 1-3 strukturę
end;
indeks 0 służy jedynie do liniowego przeglądania wszystkich elementów w drzewie, a 1-3 to odgałęzienia (więcej nie może być). Element to zaś wskazanie na obiekty posiadające rezystancję/reaktancję (w tym także elementy o nieskończonej konduktancji). Interpretuję to tak, że numer węzła na elemencie oznacza de facto węzeł przed elementem od strony, od której się "idzie". Problemy się zaczynają, gdy przez element można "przejść" z dwóch stron. Tak więc Generalnie reaktancja przypisana jest jednakowa do wszystkich krawędzi.
Tak czytam i do momentu utworzenia tabelki rozumiem (prawa kolumna musiałby mieć dynamiczny rozmiar na kolejne numery, tak?)
Dużo by Ci pracy zajęło podparcie tego rysunkiem? bo chyba łatwiej byłoby załapać...
Bo załóżmy, że na moim rysunku węzły będą mieć kolejne numery... Dla - powiedzmy pierwszych 4 węzłow tabelka by wyglądała tak:
1
2 1
3 2
4 3
?
czy może raczej powinienem przeszuiwać prawą kolumnę, i jeśli tam znajdę numer, to dopisuję w danym wierszu, a jeśli nie, to dopiero przeszukuję lewą kolumnę i dopisuję w znalezionym wierszu?
A na chwilę obecną to moje numerowanie to tak wygląda (wiem, stos cierpi ;P):
Code:
procedure NumRouteNodes(const StartPoint, PrevPoint: PRouteItem; CurrNum: Integer=0; const ForceNum: Boolean=False);
var
i: Byte;
Zero: Boolean;
begin
if (StartPoint^.NodeNum>=0) and not ForceNum then Exit;
StartPoint^.NodeNum:=CurrNum;
Zero:=(StartPoint^.Element^.CircuitElement.SimulationResult.X=0);
if not Zero then CurrNum:=GetFirstFreeNodeNumOnRoute; //zwraca wartość jeszcze niewystępującą w strukturze
for i:=1 to 3 do
if (StartPoint^.Next[i]<>nil) and (StartPoint^.Next[i]<>PrevPoint) then //PrevPoint zapobiega cofnięciu się
NumRouteNodes(StartPoint^.Next[i],StartPoint,CurrNum,Zero)
end;
Celem jest nadanie tych samych numerów węzłom połączonym nieskończoną konduktancją, dzięki czemu w macierz wartości trafiają we właściwe miejsce niezależnie od "fizycznych" połączeń na schemacie.
Ein moment
ja mam skończoną prędkość pisania
teraz muszę siąść i zrozumieć Twoje pointery
dobrze ze chociaż Pascal, bo z jednoliterowych to najlepiej mi idzie G a C to trochę jak przez mgłę (ale się staram)
udaję się, stwierdzę
Przede szystkim, wcale nie twierdzę że jestem tu od kogoś mądrzejszy, nie zamierzam nikogo pouczać bo sam się czuję nieco "na gruncie grzązkim". ale pewne pomysły i skojarzenia mam, to się nimi dzielę i może pomogą. Kategoryczny ton moich stwierdzeń wynika tylko z mniejszej dbałości o formę niż o treść w ograniczonym czasie.
założenie 1
każdy element ma swój zwrot, który determinuje potem kierunek prądu, liczenia napięć etc.
w związku z tym element dopisywany jest do "zasobów" węzła tylko tego w którym jest jego brzechwa (znaczy z którego prąd wypływa).
Na rysuneczku np. do wezła 5 trafi jeden rezystor do wezła 6 jeden, do węzła 4 dwa, a do węzła 2 żaden.
Skoro można numerować liniowo węzły, to można też elementy
Bezczelnie proponowałbym zmianę sposobu zapisu danych (niedynamiczne tablice elementów i listy jednokierunkowe, na dynamiczne listy elementów (po całości połączone w listę) i listy dwukierunkowe). Zawsze łatwiej zaproponować coś co tylko sami rozumiemy zamiast zrozumieć co ktoś wymyślił...
Moja propozycja:
(pisane w notepadzie - sprawdzać składnię)
Code:
type
PBranch=^TBranch;
PKnot:^TKnot;
TBranch= record
X:real; //(complex?)
ToKnot:integer;
Next:PBranch;
end;
TKnot= record
KnotNum:integer;
Branches:PBranch;
Next:PKnot
end;
to wersja "szkieletowa", proponuję jednak nieco wzbogaconą:
Code:
type
PBranch=^TBranch;
PKnot:^TKnot;
TBranch=record
X:real; //(complex?, moze jeszcze zrodlo)
ToKnot:integer;
FromKnot:integer;
Next:PBranch;
Prev:PBranch;
NextLin:PBranch; //liniowa lista wszystkich galezi zaczyna się od BranchesStart
PrevLin:PBranch;
BranchNum:integer;
test1,test2:boolean;
end;
TKnot= record
KnotNum:integer;
Branches:PBranch;
BranchesL:PBranch; //do wskazania ostatniej galezi
Next:PKnot;
Prev:PKnot;
end;
var
BranchesStart:PBranch=nil;
BranchesLast:PBranch=nil;
KnotsStart:PKnot=nil;
KnotsLast:PKnot=nil;
W tej wersji sprawdzenie i eliminacja węzłów wyglądałaby:
(pomijam dynamiczne rozszerzanie tablicy, równie dobrze można zedeklarować V[1000,2]of integer)
trochę zmieniłem tu użycie tablicy V w stosunku do tego co wcześniej pisałem
while not CurrentBranch=nil do
begin
if CurrentBranch.X=0 then //będzie co zaznaczać
begin
inc(NumRenumKnots); //o jeden węzeł typu From więcej na listę
V[NumRenumKnots,1]:=CurrentBranch.FromKnot;
V[NumRenumKnots,1]:=CurrentBranch.ToKnot;
end;
CurrentBranch := CurrentBranch.NextLin^; //do następnego elementu na liście wszystkich elementów
end;
//mamy tablicę par węzłów do połączenia
if NumRenumKnots>0 then
begin
for k:=1 to NumRenumKnots do
if (V[k,1]>V[k,2]) then swap (V[k,1]>V[k,2]);
sort_V1; //sortowanie tablicy V po 1 kolumnie
for k:=1 to NumRenumKnots do
for m:=k+1 to NumRenumKnots do
if (V[m,1]=V[k,2]) then V[m,1]:=V[k,1]; //w lewej kolumnie zostają tylko te numery węzłów które nie będą wykreślone z sieci
// teraz można uporządkować
sort_V2; //sortowanie tablicy V po 2 kolumnie
sort_V1; //sortowanie tablicy V po 1 kolumnie
// można pousuwać zapisy typu (7,7) {pojawia się gdy para wezłów będzie spięta dwiema impedancjami 0 "antyrównolegle"}
// można pousuwać powtarzające się zapisy identyczne np. z zapisów (3,9),(3,9),(3,9) wystarczy jeden {pojawia się gdy występują zera równoległe}
// oczywiście wartość NumRenumKnots mogła zostać powyżej zmieniona, ale nie wyzerowana (podczas usuwania powtórzen)
// i na koniec można pozamieniać w gałęziach
for k:=1 to NumRenumKnots do
begin
CurrentBranch := BranchesStart^;
while not CurrentBranch=nil do
begin
if CurrentBranch.FromKnot=V[k,2] then CurrentBranch.FromKnot=V[k,1]; //tu zamieniamy na jeden węzeł, ten o niższym numerze
if CurrentBranch.ToKnot=V[k,2] then CurrentBranch.ToKnot=V[k,1]; //tu też
CurrentBranch := CurrentBranch.NextLin^; //do następnego elementu na liście wszystkich elementów
end;
end;
//teraz w galeziach wystepuja tylko "wlasciwe" wezly
// pozostały do usunięcia "zle" wezly
for k:=1 to NumRenumKnots do
begin
CurrentKnot:=SzukajKnot(V[k,2]); //znajdz wskaznik do wezla ktory bedziemy likwidowac
if CurrentKnot.Prev=nil then //wycinam wezeł z listy w tył
KnotsStart:=CurrentKnot.Next
else
CurrentKnot.Prev^.Next:=CurrentKnot.Next;
if CurrentKnot.Next=nil then // i w przod
KnotsLast:=CurrentKnot.Prev
else
CurrentKnot.Next^.Prev:=CurrentKnot.Prev;
CurrentBranch:=SzukajKnot(V[k,1])^.Branches; //teraz przesadzanie gałezi z wezla do wezla, znajdujemy gałęzie "własciwego" wezła
while not CurrentBranch=nil do
CurrentBranch := CurrentBranch.Next^; //do następnego elementu na liście galezi wezla
//stoimy na ostatnim
CurrentBranch.Next:=CurrentKnot.Branches; //doczepiamy listę galezi z likwidowaneo wezla (byc moze pusta)
end;
//pozostalo usunac galezie o impedancji 0 zreszta zapetlone
CurrentBranch := BranchesStart^;
while not CurrentBranch=nil do
begin
if CurrentBranch.X=0 then //teraz usuwamy
begin
if CurrentBranch.Prev=nil then //wycinam wezeł z listy w tył (lista od wezla a nie globalna)
SzukajKnot(CurrentBranch.FromKnot)^.Branches:=CurrentBranch.Next
else
CurrentBranch.Prev^.Next:=CurrentBranch.Next;
if CurrentBranch.Next=nil then // i w przod
SzukajKnot(CurrentBranch.FromKnot)^.BranchesL:=CurrentBranch.Prev
else
CurrentBranch.Next^.Prev:=CurrentBranch.Prev;
end;
CurrentBranch := CurrentBranch.NextLin^; //do następnego elementu na liście wszystkich elementów
end;
A czy ja twierdziłem że ktokolwiek tu jest mądrzejszy? I tak wdzięczny Ci jestem za tą pomoc i wytrwałość. Nawet jeśli nie wprost, to czasami podsuwają ciekawe inne rozwiązania.
To ja się powgryzam jakiś czas teraz Z tą zmianą struktury tak łatwo niestety nie będzie, bo cały "mechanizm" jest w jeszcze kilku przypadkach wykorzystywany, a wolę oszczędzać na multiplikacji przypadków, bo dużo łatwiej operować nie mówiąc o funkcjach zwalniających pamięć. Ale jak dojdę do wniosku, że trzeba...
Najgorsze jednak to to, że mój algorytm - sam nie ufając mu do końca - działa na "przykładowych przykładach" Szkoda, że czas nie pozwala się bawić, a narzędzie powstaje faktycznie potężne (jak na jednego autora). Powoli sam już w kodach własnych zaczynam się gubić
No ale do rzeczy - może do końca weekendu przeanalizuje zaproponowane przez Ciebie rozwiązania i coś powstanie
No to właśnie popatrz na to jak na opis formalny procesu usuwania węzłów i elementów.
Oczywiście zapomniałem w kluczowych miejscach wstawić dISPOSE czy coś podobnego do zwalniania pamięci.
Starałem się natomiast zrobić to tak, żeby było możliwe wielokrotne powtórzenie.
Tzn. user maluje schemat w edytorze, program go upraszcza wywalając podwójne węzły, potem liczy rozkład prądów i potem znowu można domalować coś w edytorze (bo to ta sama struktura) i znów liczyć.
Przepraszam, może nie napisałem wyraźnie, ale wyszło to tak, że nie kopiuję struktury, tylko "oczyszczam" i "modyfikuję" jedną i tę samą.
Bo jak jawny, to chętnie bym zobaczył opis/publikację jak będzie gotowe (sam produkt raczej do niczego mi się nie nada).
To zgodnie z obietnicą trochę pozwolę sobie zdradzić część dotyczącą instrukcji obsługi. Co do algorytmów, nie udało mi się niestety zrobić wszystkiego tak, jakbym chciał - zbyt mało czasu. Obecnie trwa faza sporządzania specyfikacji wewnętrznej. I proszę wykorzystywać dokument co najwyżej do własnych informacji i wiadomości i nie wykorzystywać czy nie rozpowszechniać tego tekstu.
Osoby zainteresowane hasłem proszę na PW
Bardzo dziękuję za okazane zaufanie.
Praca zapowiada się bardzo ładnie.
Mnie tylko skręca, że młodzież ma teraz takie możliwości.
Gdyby to za moich czasów ...
Ale na szczęście, jak widać, mogą powstawać porządne, konkretne prace.
Bo ostatnio miałem ogólnie dość niskie mniemanie o poziomie wszelkiego rodzaju dyplomów generowanych głównie jako formalny wymóg dla zdobycia papierka.
Przeglądałem nieco po łbach i jak dotąd nie znalazłem żadnych błędów, literówek o których należałoby poinformować.
Dodam jeszcze, że od paru dni piszę własny edytor schematów.
Jak dotad mam grid i stawiam kropki na skrzyżowaniach.
Mam drobny problem z rysowaniem łamanej, albo coś źle działa, albo jest źle opisane.
U mnie jest nieco inaczej, program ma mi sprowadzić (metodą eliminacji Gaussa jak sądzę) wiadomy układ równań do układu w którym występują tylko równania z pochodnymi. Wszystkie równania typu suma prądów = 0, albo U=IR muszą zostać wyeliminowane, niestety algorytmem.
A co najlepsze to nie jest to moje najpilniejsze zadanie, tylko jakoś tak najbardziej mnie do niego ciągnie.
Powstaje to na dokładkę w LabView'ie co budzi zdumienie wszystkich znajomych.
Możliwości są dwie: wyjdzie coś, albo zagrzęznę na amen i porzucę w niesławie.
Na literówki to Word poradzi Na razie to jest wersja pierwsza jeszcze nie korygowana
NO ta moja praca to też się obawiam, czy jej nie porzucę... Choc przyznaję że ambicją spośród wszystkich tematów to przoduje - http://kenerg.po.opole.pl/tematy_prac.pdf (znajdziesz tam i mój). Osobiście to też jestem zdania że na jedną osobę to za dużo, ale zespołowo pracować nie lubię... Gdyby jeszcze czasu było więcej...
Dodano po 2 [minuty]:
A co do łamanej - w sensie wizualnym, czy w sensie algorytmicznym? Bo u mnie sam program robi łamaną
Siedzi burak albo w opisach, albo jednak w implementacji, albo mmoże ja coś pieprzę z danymi bo dane w LV potrafią wyglądać kłopotliwie.
Jest klocek MoveTo i klocek MultipleLine i normalny człowiek wsadza pierwszy punkt łamanej to MoveTo a pozostałe do MultipleLine. Testuję to na rezystorku (naszym, z prostokątem) który nie jest figurą unikursalną.
Ale problem jest z punktem startowym. Prawie zawsze pierwsza noga startuje gdzie ze środka rezystora, albo z drugiego końca.
To jest oczywisty pryszcz, mogę to namalować na piętnascie różnych sposobów lewą nogą, tylko wkurza mnie, że środowisko za dziesiątki tysięcy ma pluskwę w tak prostym miejscu jak malowanie linii.
Może w tygodniu posunę coś dalej, bo w weeekend poza jednym terminowym zadaniem to balujemy.