Selecteren waarden met minimale afwijking

Wiskunde is niet alleen een vak op school. Kom je ergens in de praktijk (bijvoorbeeld tijdens je werk) een wiskundig probleem tegen dan kun je hier om hulp vragen.
Plaats reactie
Simotion
Vast lid
Vast lid
Berichten: 32
Lid geworden op: 22 dec 2017, 21:46

Selecteren waarden met minimale afwijking

Bericht door Simotion » 03 okt 2021, 11:56

Voor een applicatie in een plc-besturingssysteem (dus geen pc-applicatie met bv. .net, maar wel de mogelijkheid
voor for, while, repeat lussen, if then, case, etc) moet ik uit 100 real variabelen de reeksen selecteren waar de variabelen binnen de reeks maximaal 1 éénheid vershillen (+- 1.0), dit geldt voor alle punten binnen de reeks. Zo zullen er mogelijks meerdere reeksen zijn, sommige met veel elementen, anderen met weinig elementen. Daar moet ik dan de reeks uitnemen met het meeste aantal elementen.
Er zijn wellicht verschillende manieren om dit te verwezelijken, maar omdat het plc-besturingssyteem maar beperkte rekenkracht heeft en de totale procestijd voor de functie toch beperkt moet blijven zou ik het snelste algoritme willen hebben om de reeksen uit te filteren.

arie
Moderator
Moderator
Berichten: 3911
Lid geworden op: 09 mei 2008, 09:19

Re: Selecteren waarden met minimale afwijking

Bericht door arie » 03 okt 2021, 16:05

Hier een heel algemeen programma:

Code: Selecteer alles

{
\\ VOORBEELD GETALLEN:
v=[0.78710, 2.0464, 2.9453, 0.048800, 3.4080, 1.2216, 2.4379, 3.9994, 4.4943, 1.5962, 0.33975, 1.8827, 2.9213, 0.31175, 3.2336, 4.4324, 4.1455, 1.1574, 3.9799, 4.5904, 4.8235, 3.5870, 3.7028, 2.3964, 4.6110, 0.77320, 4.6411, 4.9266, 0.42505, 1.5840, 0.33115, 2.8721, 4.6812, 4.1242, 4.7687, 0.73365, 2.0784, 4.8475, 3.7770, 4.6459, 2.3144, 3.4483, 0.86690, 2.5208, 2.8527, 1.7433, 4.5119, 0.93355, 0.99545, 2.3146, 0.72210, 1.2286, 3.6239, 4.9980, 3.9486, 1.1596, 2.2891, 1.8746, 3.9969, 4.1665, 4.8027, 3.6323, 2.9758, 3.2086, 1.4786, 2.3687, 1.2872, 0.71440, 3.3130, 0.26275, 1.1152, 0.81410, 2.9272, 4.8303, 1.2977, 1.9857, 1.4847, 1.3971, 2.7991, 1.0927, 3.3238, 0.34365, 0.53565, 3.1976, 2.8031, 2.5942, 0.66560, 3.9512, 1.8631, 4.2909, 4.7266, 3.5087, 3.1087, 0.91515, 1.1742, 2.3245, 0.46100, 2.3230, 3.7992, 3.3701];
nwaarden=length(v);  \\ aantal waarden in v[] (in dit voorbeeld 100)
w=vector(nwaarden);  \\ definieer vector w[] waarin reekslengtes komen

\\ BEREKENING REEKSLENGTES: 
langstereeks=0;
for(i=1,nwaarden,
  j=1;
  while(i+j<=nwaarden && -1.0<=v[i]-v[i+j] && v[i]-v[i+j]<=1.0,
    j+=1;
    );
  w[i]=j;
  if(j>langstereeks, langstereeks = j);
  );

\\ OUTPUT:
nvoorkomens=0;  \\ aantal keer dat de maximale reekslengte voorkomt in v[]
print("i   w[i]   v[i]");
for(i=1,nwaarden,
  if(w[i]==langstereeks,
    print(i,"    ",w[i]," *  ",v[i]);
    nvoorkomens+=1;
    ,\\ELSE:
    print(i,"    ",w[i],"    ",v[i]);
    );
  );
print("langste reeks = ", langstereeks,"; aantal voorkomens = ",nvoorkomens);
}
Je doorloopt voor i = 1 t/m n(=100) alle getallen \(v\begin{bmatrix}i\end{bmatrix}\), en kijkt steeds hoe lang de reeks is die start op positie i.
Resultaat van bovenstaande code:

Code: Selecteer alles

i   w[i]   v[i]
1    1    0.78710
2    2    2.0464
3    1    2.9453
4    1    0.048800
5    1    3.4080
6    1    1.2216
7    1    2.4379
8    2    3.9994
9    1    4.4943
10    1    1.5962
11    1    0.33975
12    1    1.8827
13    1    2.9213
14    1    0.31175
15    1    3.2336
16    2    4.4324
17    1    4.1455
18    1    1.1574
19    5 *  3.9799
20    2    4.5904
21    1    4.8235
22    2    3.5870
23    1    3.7028
24    1    2.3964
25    1    4.6110
26    1    0.77320
27    2    4.6411
28    1    4.9266
29    1    0.42505
30    1    1.5840
31    1    0.33115
32    1    2.8721
33    3    4.6812
34    2    4.1242
35    1    4.7687
36    1    0.73365
37    1    2.0784
38    1    4.8475
39    2    3.7770
40    1    4.6459
41    1    2.3144
42    1    3.4483
43    1    0.86690
44    3    2.5208
45    1    2.8527
46    1    1.7433
47    1    4.5119
48    2    0.93355
49    1    0.99545
50    1    2.3146
51    2    0.72210
52    1    1.2286
53    1    3.6239
54    1    4.9980
55    1    3.9486
56    1    1.1596
57    2    2.2891
58    1    1.8746
59    4    3.9969
60    3    4.1665
61    1    4.8027
62    3    3.6323
63    2    2.9758
64    1    3.2086
65    4    1.4786
66    1    2.3687
67    2    1.2872
68    1    0.71440
69    1    3.3130
70    3    0.26275
71    2    1.1152
72    1    0.81410
73    1    2.9272
74    1    4.8303
75    4    1.2977
76    5 *  1.9857
77    2    1.4847
78    1    1.3971
79    1    2.7991
80    1    1.0927
81    1    3.3238
82    2    0.34365
83    1    0.53565
84    3    3.1976
85    2    2.8031
86    1    2.5942
87    1    0.66560
88    1    3.9512
89    1    1.8631
90    3    4.2909
91    1    4.7266
92    2    3.5087
93    1    3.1087
94    2    0.91515
95    1    1.1742
96    1    2.3245
97    1    0.46100
98    1    2.3230
99    2    3.7992
100    1    3.3701
langste reeks = 5; aantal voorkomens = 2
De twee langste reekswaarden (reekslengte = 5) zijn gemarkeerd met een sterretje:
i=19 geeft de reeks: 3.9799, 4.5904, 4.8235, 3.5870, 3.7028
i=76 geeft de reeks: 1.9857, 1.4847, 1.3971, 2.7991, 1.0927

Bedoel je zoiets?
Of heeft je data-set nog bijzondere eigenschappen die we kunnen benutten?

Plaats reactie