[C#] Generowanie reguł bez wielu zagnieżdżonych pętli


(Marcin Obala) #1

Witam

Nie mam zielonego pojęcia na tytuł tematu. Mam taki problem a raczej zagwostkę. Wyobraźmy sobie że mamy jakieś pomiary, np. napięcia i natężenia prądu i przedziały akceptowalności

0.5 < I < 1.0

0.3 < U < 2.0

Chciałbym teraz wygenerować 4 reguły mianowicie

Rule "I" < 0.5

ex "U" < 0.3

Rule "I" < 0.5

ex "U" > 2.0

Rule "I" > 1.0

ex "U" < 0.3

Rule "I" > 1.0

ex "U" > 2.0

I wszystko fajnie. Jednak dochodzi kolejny pomiar np. 4 < T < 10 i reguły wyglądają tak

Rule "I" < 0.5

ex "U" < 0.3

ex "T" < 4

Rule "I" < 0.5

ex "U" > 2 .0

ex "T" > 10

Rule "I" < 0.5

ex "U" > 0.3

ex "T" > 10

itd. czyli łącznie 8 reguł

< < <

< < >

< > <

< > >

> < <

> < >

> > <

> > >

ale może dojść jeszcze kolejny pomiar. I tutaj jest ten problem, jak wygenerować reguły 2x, 3x, 4x, 5x bez dwóch, trzech, czterech czy pięciu pętli zagnieżdżonych. Może ma ktoś jakiś pomysł bo ja mam zaćmienie?


(Pablo_Wawa) #2

Dobrze byłoby, byś w tytule wątku podał choćby o jakim języku programowaniu mowa.


(Marcin Obala) #3

Mniej ważny jest język, bardziej koncepcja. Jednak jeśli potrzebny to ja piszę w C# jednak nie będzie dla mnie problemem przepisać z innego języka, chyba że to będzie Brainfuck :wink:


(Drobok) #4

A może napiszesz do czego ci to ?

Rozumiem, że masz 3 stany (albo 2 jak w przykładzie) Imo najlepiej sprawdzić po kolei, by zaoszczędzić na znakach można napisać funkcję czy procedurę. Np sprawdźmy pierw napięcie, potem natężenie, na końcu opór, potem coś tam jeszcze itd. Sprawdzamy wszystko 2x (większe, mniejsze, a jeśli nie to dobre) np:

private int c(float wart,float max,float min){

  if(wart>max)

    return 1;//zwracamy 1 jak za duże

  else if(wart
    return -1;//zwracamy -1 jak za małe

  else return 0;//zwracamy 0 jak w sam raz

}

Ew pasuje, albo nie:

private bool c(float wart,float max,float min){

  if(wartmin)

    return 1; //pasuje

  else return 0;//nie pasuje

}

Oczywiście można wyświetlać tekst zamiast zwracać wartość, ale wszystko zależy czy chcesz jakiegoś forma oznaczyć, czy co tam innego :slight_smile: Nie musisz sprawdzać wszystkich przypadków.


(Marcin Obala) #5

Niestety to taki format reguł wymyślili twórcy oprogramowania ale nie mają żadnego softu żeby pokazać na której regule coś się wysypało ani nie ma łatwej zmiany granic akceptowalności. Te reguły działają jeszcze na tej zasadzie że jeśli jeden pomiar z dwóch będzie dobry to wszystko nadal jest dobrze, co z tego że np. napięcie było 500 V a jest do 2. Nie mnie o tym myśleć. Po prostu żeby ułatwić sobie życie robię oprogramowanie w którym będę miał suwaki dla każdego z pomiarów. Np. 10 pomiarów i dla każdych dwóch z tych dziesięciu (kombinacja bez powtórzeń) muszę zrobić 4 reguły. Pliki które ja wygeneruje i tak będzie zewnętrzny soft interpretował więc niestety muszę coś takiego wygenerować.


(Pablo_Wawa) #6

Jeśli dobrze rozumiem, co chcesz uzyskać, to w tym przypadku chyba nie masz innej możliwości.

Dla 2 zmiennych (I oraz U) masz 4 reguły, jeśli dodajesz kolejną zmienną (T), to podwajasz istniejące reguły (jedna dla T poniżej zakresu i druga dla T powyżej zakresu).

Jeśli zakresy są parametrem wejściowym programu, ale liczba zmiennych jest stała, to musisz stworzyć sobie 3 pętle i generować w każdej z nich stosowną regułę (tj. w tej już najbardziej zagnieżdżonej).

Jeśli planujesz powiększyć liczbę zmiennych to warto napisać tak pętle, by iterowały po wszystkich parametrach - do tego zaś trzeba użyć np. tablicy.


(Marcin Obala) #7

Właśnie tego chciałem uniknąć. Mogę mieć 5 pomiarów:

1

2

3

4

5

i wybieram po dwa:

1,2

1,3

1,4

1,5

2,3

2,4

2,5

3,4

3,5

4,5

i dla każdej takiej kombinacji generuje 4 reguły (< ; ><; >>)

Później biorę po 3 pomiary

1,2,3

1,2,4

1,2,5

1,3,4

1,3,5

1,4,5

2,3,4

2,3,5

2,4,5

3,4,5

I dla tych po 8 reguł (<<<; <; <><; <>>; ><<>; >><; >>>). Później to samo z 4 pomiarami. Dla pomiarów 2x, 3x, 4x są inne granice akceptowalności bo ktoś mógłby pomyśleć że nie ma sensu czegoś takiego generować. Dlatego nie chciałem robić tyle pętli.


(Frankfurterium) #8

Nie wiem, jak języki dynamiczne działają na .NET, ale takim mógłbyś po prostu wygenerować odpowiedni kod i go wykonać. Może sprawdź, czy czegoś takiego nie mógłbyś zaimplementować np. w IronPythonie (naprawdę nietrudna sprawa) i dorzucić do projektu.


(Drobok) #9

Może cię trochę wkurzę, ale nadal tego nie kapuje :PP (pierwszy przykład był dla mnie bardziej czytelny)

0.5 < I < 1.0

0.3 < U < 2.0

Mam to na wejściu, więc każdy ma 2 stany np: 0.5 < i 1.0 > i 0.3 < u 2.0 > u I masz te stany mieszać w formacie tego:

Rule

ex

//dajej same ex

?


(Marcin Obala) #10

Tak masz pomieszać ale ze zmianą znaku czyli

Rule 0.5 > I

ex 0.3 > U