Jest to model który używany jest w przypadku gdy w szeregu czasowym pojawia się: trend, wahania sezonowe (addytywne lub multiplikatywne) oraz wahania przypadkowe. Dla osób zainteresowanych tylko programem można go pobrać tutaj:
metoda-wintersa-wersja-1-2
(Program działa na systemach operacyjnych windows 7+)
Metod Wintersa jest pełną metodą wykorzystującą w prognozie wahania losowe, trend(liniowy) oraz sezonowość(addytywną lub multiplikatywną). Wygładzaniu ulegają zatem trzy elementy:
- Poziom zmiennej, reprezentowany przez parametr α (alfa) wygładza wahania przypadkowe, α∈<0,1>
- Przyrost, reprezentowany przez parametr β (beta) wygładza trend, β∈<0,1>
- Sezonowość, reprezentowany przez parametr γ (gamma) wygładza trend, γ ∈<0,1>
Jeśli chodzi o sezonowość możemy wybrać dwa warianty:
Wariant addytywny- wykorzystywany gdy efekt danego sezonu jest stały w czasie
Wariant multiplikatywny – gdy udział efektów sezonowości jest stały w wartości zmiennej
Zaczynamy standardowo od utworzenia nowego projektu. Elementy do lozlokowania podaje poniżej:
| Rodzaj elementu | Nazwa elementu | ustawienia |
|---|---|---|
| Form | ModelBrowna | Name: ModelBrowna Text: Model Browna Size: 1081; 716 |
| DataGridView | dgv_dane | Name: dgv_dane AllowUserToAddRows: False AllowUserToDeleteRows: False AllowUserToOrderColumn: True AllowUserToResizeColumns: False AllowUserToResizeRows: False AutoSizeColumnsMode: Fill Size: 566; 320 Location: 12; 29 |
| label | ie | Text: „0” Location: 105;380 Name: ie |
| label | SumaRoznic | Text: „0” Location: 105;407 Name: SumaRoznic |
| label | SumaKwadratow | Text: „0” Location: 105;435 Name: SumaKwadratow |
| label | Prognoza | Text: „0” Location: 105;380 Name: Prognoza |
| label | Mape | Text: „0” Location: 293;380 Name: Mape |
| label | Mse | Text: „0” Location: 293;409 Name: Mse |
| label | Rmse | Text: „0” Location: 293;436 Name: Rmse |
| label | WspTheila | Text: „0” Location: 293;460 Name: WspTheila |
| label | me_ | Text: „0” Location: 293;484 Name: me_ |
| label | Rmspe | Text: „0” Location: 293;508 Name: Rmspe |
| label | MAE | Text: „0” Location: 293; 547 Name: MAE |
| label | MPE | Text: „0” Location: 240; 572 Name: MPE |
| MenuStrip1 | MenuStrip1 | Name: MenuStrip1Dodano w menu: Dane – Dodaj dane – Zakończ |
| Textbox | FilePath | Name: FilePath Location: 123;3 Size: 560;20 |
| Button | Odswiez | Name: Odswiez Location: 108; 630 Size: 75; 37 Enabled: false |
| Chart | Wykres1 | Name: Wykres1 Location: 785; 35 Size: 268; 187 Ilość serii danych: 2 |
| OpenFileDialog | WczytajDane | Name: WczytajDane |
| Chart | wykres2 | Name: Wykres2 Location: 587; 228 Size: 466; 280 Ilość serii: 2 |
| Chart | wykres3 | Name: Wykres3 Location: 587; 514 Size: 466; 153 Ilość serii: 2 |
| label | Mape_dla_prognozy | Text: „0” Location: 411; 630 Name: Mape_dla_prognozy |
| TextBox | Beta | Name: Beta Location: 58; 539 Size: 43; 20 |
| TextBox | Alfa | Name: Alfa Location: 56; 498 Size: 43; 20 |
| TextBox | Gamma | Name: Gamma Location: 58; 575 Size: 43; 20 |
| TextBox | DlugoscCyklu | Name: DlugoscCyklu Location: 54; 639 Size: 43; 20 |
| RadioButton | MultiplikatywnyRB | Name: MultiplikatywnyRB Location: 414; 447 Text: Multiplikatywny |
| RadioButton | AddytywnyRB | Name: AddytywnyRB Location: 414; 471 Text: Addytywny |
Po rozłożeniu wszystkich elementów na formę powinna ona wyglądać tak:
Rozłożenie opisów zostawiam wam do zrobienia. Po dodaniu opisów forma powinna wyglądać tak jak na obrazku:
Należy pamiętać aby nasze dwa wykresy miały ustawione dwie serie danych, aby to zrobić wybieramy nasz wykres i w jego właściwościach znajdujemy „Series”:
Stronę graficzną mamy już z głowy. Zajmijmy się stroną techniczną. Na początek importujemy wymagane elementy i inicjujemy stałe zmienne:
Imports System.Windows.Forms.DataVisualization.Charting
Public Class Metoda_Wintersa
Private filename As String ''przechowuje ścieżkę naszego pliku
Dim wartoscAlfa As Double = 0.45 ''początkowa wartość Alfa
Dim wartoscBeta As Double = 0.8 ''początkowa wartość Beta
Dim wartoscGamma As Double = 0.19 ''początkowa wartość Gamma
Dim LiczbaFaz As Integer = 3 ''początkowa liczba faz
Dim dane As New List(Of Double) ''przechowuje nasze dane w formie tablicy
Dim kontroler As Boolean = True 'sprawdza czy dane są wczytane
(....)
Stworzymy teraz sobie obsługę przycisku wczytującego dane do programu z pliku *.txt, *.csv
Private Sub DodajDaneToolStripMenuItem_Click(sender As Object, e As EventArgs) Handles DodajDaneToolStripMenuItem.Click
Odswiez.Enabled = True 'Odblokowuje przycisk
MultiplikatywnyRB.Checked = True 'Wybiera rodzaj początkowego modelu
'filtr danych
WczytajDane.Filter = "csv files|;*.csv;*.txt"
WczytajDane.Title = "Select a csv file"
WczytajDane.FileName = ""
Try
With WczytajDane
If .ShowDialog() = DialogResult.OK Then
'' kontroler posłuży nam do zaznaczania czy dane są wczytanie czy też nie,
'' daje to możliwość załadowania innych danych jeśli te nam już nie będą potrzebna.
If kontroler = False Then 'jeśli jakieś dane są załadowane to ....
dane.Clear() 'czyści tablice
dgv_dane.Rows.Clear() 'czyści datagridview
filename = .FileName 'ładuje ścieżkę pliku do zmiennej string
FilePath.Text = filename 'wizualizuje ścieżkę pliku w textboxie
alfa.Text = wartoscAlfa.ToString ' wizualizuje wzsłczynnik alfa
Beta.Text = wartoscBeta.ToString ' wizualizuje wzsłczynnik beta
Gamma.Text = wartoscGamma.ToString ' wizualizuje wzsłczynnik Gamma
DlugoscCyklu.Text = LiczbaFaz '' wizualizuje ilość cykli
TworzTabele(filename) ' funkcja przetwarzająca nasze dane z
'pliku txt i ładujące je do tablicy (nie gotowa na tym etapie)
Metoda_Wintersa(wartoscAlfa, wartoscBeta, wartoscGamma, LiczbaFaz) ' funkcja tworząca metode Browna (nie gotowa na tym etapie)
tworz_wykres() ' funkcja ładująca dane do wykresu (nie gotowa na tym etapie)
Else
'pierwsze załadowanie danych
filename = .FileName
FilePath.Text = filename
alfa.Text = wartoscAlfa.ToString
Beta.Text = wartoscBeta.ToString
Gamma.Text = wartoscGamma.ToString
DlugoscCyklu.Text = LiczbaFaz
TworzTabele(filename)
Metoda_Wintersa(wartoscAlfa, wartoscBeta, wartoscGamma, LiczbaFaz)
tworz_wykres()
kontroler = False
End If
End If
End With
Catch ex As Exception
End Try
End Sub
Teraz należy nasze załadowane dane przenieść do tablicy „dane” robimy to za pomocą metody:
Private Sub TworzTabele(ByVal sciezkaDoPliku As String)
Dim i As Integer
Dim wartosc As String() 'przechowuje dane z pliku
Dim f As IO.File = Nothing
Dim rodzajkodu As New IO.StreamReader(sciezkaDoPliku, System.Text.Encoding.UTF8)
Try
wartosc = rodzajkodu.ReadLine().Split(ControlChars.Tab) 'rodzaj separatora w tym wypadku "Enter"
For i = 0 To wartosc.Length() - 1
dane.Add(wartosc(i).ToString)
Next
While rodzajkodu.Peek() <> -1
wartosc = rodzajkodu.ReadLine().Split()
For i = 0 To wartosc.Length() - 1
dane.Add(wartosc(i).ToString) 'Ładuje dane do tablicy dane
Next
End While
Catch ex As Exception
MsgBox("Error: " & ex.Message)
Finally
rodzajkodu.Close()
End Try
End Sub
Teraz Stworzymy sobie kod naszej metody:
Private Sub Metoda_Wintersa(ByVal alfa As Double, ByVal beta As Double, ByVal gamma As Double, ByVal r As Integer)
Dim dane1 As Double = 0
Dim dane2 As Double = 0
Dim dane3 As Double = 0
Dim dane4 As Double = 0
Dim dane5 As Double = 0
Dim dane6 As Double = 0
Dim dane7 As Double = 0
Dim Srednia As Double = 0
Dim PierwszyWyrazSt As Double = 0
Dim wartosciPoczatkowe As Double = 0
'Adby dodać wartości Ft i Ct
'Potrzebujemy zmiennych
'Średniej
For i As Integer = 0 To r - 1
Srednia += (dane(i))
Next
Srednia = Srednia / (r)
'Średnich z wyrazów r+1,r+2,....
For i As Integer = 0 To r - 1
PierwszyWyrazSt += dane(i + r)
Next
PierwszyWyrazSt = PierwszyWyrazSt / (r) - Srednia
Try
dgv_dane.ColumnCount = 10
dgv_dane.Columns(0).Name = "t"
dgv_dane.Columns(1).Name = "yt"
'Wygładzenia
dgv_dane.Columns(2).Name = "Ft"
dgv_dane.Columns(3).Name = "St"
dgv_dane.Columns(4).Name = "Ct"
'Prognozy wygasłe
dgv_dane.Columns(5).Name = "yt*"
'błąd bezwzględny
dgv_dane.Columns(6).Name = "yt-y*t"
'błąd do kwadratu
dgv_dane.Columns(7).Name = "(yt-y*t)^2"
'błąd względny
dgv_dane.Columns(8).Name = "|(yt-y*t)/yt|"
dgv_dane.Columns(9).Name = "yt^2"
'' Dodaje t (numeracje wierszy powiększoną o ilość cykli)
For i As Integer = 0 To dane.Count + r - 1
dgv_dane.Rows.Add() 'wypełnia datagridview wierszami
dgv_dane.Rows(i).Cells(0).Value = i + 1 ' dodaje numeracje
dgv_dane.Rows(i).Cells(0).Style.Alignment = DataGridViewContentAlignment.MiddleCenter
Next
'' Dodaje yt (nasze dane)
For i As Integer = 0 To dane.Count - 1
dgv_dane.Rows(i).Cells(1).Value = dane(i)
Next
'' Początkowe warości Ft,St,Ct
'' Ft, St i metoda Ct muszą być tworzone jednocześnie
'Wartość początkowa Ft
dgv_dane.Rows(r - 1).Cells(2).Value = Math.Round(Srednia, 2)
dgv_dane.Rows(r - 1).Cells(2).Style.BackColor = Color.Yellow 'kolor żółty dla pierwszego elementu
'Wartość początkowa St
dgv_dane.Rows(r - 1).Cells(3).Value = Math.Round(PierwszyWyrazSt, 2)
dgv_dane.Rows(r - 1).Cells(3).Style.BackColor = Color.Yellow 'kolor żółty dla pierwszego elementu
'Wartości początkowe Ct
For i As Integer = 0 To r - 1
wartosciPoczatkowe = 0
For j As Integer = 0 To r - 1
wartosciPoczatkowe += (dane(j + i))
Next
wartosciPoczatkowe = wartosciPoczatkowe / (r)
dgv_dane.Rows(i).Cells(4).Value = Math.Round(dane(i) / wartosciPoczatkowe, 4)
dgv_dane.Rows(i).Cells(4).Style.BackColor = Color.LightCoral 'kolor LightCoral dla pierwszych elementów
Next
''''''
'Reszta wartości Ft,St,Ct
For i As Integer = r To dane.Count - 1
'Ft
If MultiplikatywnyRB.Checked = True Then
dgv_dane.Rows(i).Cells(2).Value = Math.Round(wartoscAlfa * (dane(i) / dgv_dane.Rows(i - r).Cells(4).Value) + (1 - wartoscAlfa) * (dgv_dane.Rows(i - 1).Cells(2).Value + dgv_dane.Rows(i - 1).Cells(3).Value), 2)
dgv_dane.Rows(i).Cells(2).Style.BackColor = Color.LightSkyBlue
Else
dgv_dane.Rows(i).Cells(2).Value = Math.Round(wartoscAlfa * (dane(i) - dgv_dane.Rows(i - r).Cells(4).Value) + (1 - wartoscAlfa) * (dgv_dane.Rows(i - 1).Cells(2).Value + dgv_dane.Rows(i - 1).Cells(3).Value), 2)
dgv_dane.Rows(i).Cells(2).Style.BackColor = Color.LightPink
End If
'St
dgv_dane.Rows(i).Cells(3).Value = Math.Round(wartoscBeta * (dgv_dane.Rows(i).Cells(2).Value - dgv_dane.Rows(i - 1).Cells(2).Value) + (1 - wartoscBeta) * dgv_dane.Rows(i - 1).Cells(3).Value, 2)
dgv_dane.Rows(i).Cells(3).Style.BackColor = Color.LightSkyBlue
'Ct
If MultiplikatywnyRB.Checked = True Then
dgv_dane.Rows(i).Cells(4).Value = Math.Round(gamma * (dane(i) / dgv_dane.Rows(i).Cells(2).Value) + (1 - gamma) * dgv_dane.Rows(i - r).Cells(4).Value, 4)
dgv_dane.Rows(i).Cells(4).Style.BackColor = Color.LightGreen
Else
dgv_dane.Rows(i).Cells(4).Value = Math.Round(gamma * (dane(i) - dgv_dane.Rows(i).Cells(2).Value) + (1 - gamma) * dgv_dane.Rows(i - r).Cells(4).Value, 4)
dgv_dane.Rows(i).Cells(4).Style.BackColor = Color.LightPink
End If
Next
'' dodaje yt*
For i As Integer = r To dane.Count + r - 1
If MultiplikatywnyRB.Checked = True Then
If i > dane.Count - 1 Then
'Dodaje naszą prognoze
dgv_dane.Rows(i).Cells(5).Value = Math.Round((dgv_dane.Rows(dane.Count - 1).Cells(2).Value + (i + 1 - dane.Count) * dgv_dane.Rows(dane.Count - 1).Cells(3).Value) * dgv_dane.Rows(i - r).Cells(4).Value, 2)
dgv_dane.Rows(i).Cells(5).Style.BackColor = Color.LightGray
Else
'Dodaje prognozy wygasłe
dgv_dane.Rows(i).Cells(5).Value = Math.Round((dgv_dane.Rows(i - 1).Cells(2).Value + dgv_dane.Rows(i - 1).Cells(3).Value) * dgv_dane.Rows(i - r).Cells(4).Value, 2)
dgv_dane.Rows(i).Cells(5).Style.BackColor = Color.LightGray
End If
Else
If i > dane.Count - 1 Then
'Dodaje naszą prognoze
dgv_dane.Rows(i).Cells(5).Value = Math.Round(dgv_dane.Rows(dane.Count - 1).Cells(2).Value + (i + 1 - dane.Count) * dgv_dane.Rows(dane.Count - 1).Cells(3).Value + dgv_dane.Rows(i - r).Cells(4).Value, 2)
dgv_dane.Rows(i).Cells(5).Style.BackColor = Color.LightGray
Else
'Dodaje prognozy wygasłe
dgv_dane.Rows(i).Cells(5).Value = Math.Round(dgv_dane.Rows(i - 1).Cells(2).Value + dgv_dane.Rows(i - 1).Cells(3).Value + dgv_dane.Rows(i - r).Cells(4).Value, 2)
dgv_dane.Rows(i).Cells(5).Style.BackColor = Color.LightGray
End If
End If
Next
'' dodaje yt-y*t
For i As Integer = r To dane.Count - 1
dgv_dane.Rows(i).Cells(6).Value = Math.Round(dane(i) - dgv_dane.Rows(i).Cells(5).Value, 3)
Next
'' Dodaje (yt-y*t)^2
For i As Integer = r To dane.Count - 1
dgv_dane.Rows(i).Cells(7).Value = Math.Round(dgv_dane.Rows(i).Cells(6).Value ^ 2, 3)
Next
'' Dodaje |(yt-y*t)/yt|
For i As Integer = r To dane.Count - 1
dgv_dane.Rows(i).Cells(8).Value = Math.Round(Math.Abs(dgv_dane.Rows(i).Cells(6).Value / dane(i)), 6)
Next
'' Dodaje yt^2
For i As Integer = 0 To dane.Count - 1
dgv_dane.Rows(i).Cells(9).Value = Math.Round(dane(i) ^ 2, 3)
Next
''Przygotowanie zmiennych do Obliczeń
'' Suma (yt-y*t)
For i As Integer = 0 To dane.Count - 1
dane1 += dgv_dane.Rows(i).Cells(6).Value
Next
'' Suma (yt-y*t)^2
For i As Integer = 0 To dane.Count - 1
dane2 += dgv_dane.Rows(i).Cells(7).Value
Next
'' suma |(yt-y*t)/yt|
For i As Integer = 0 To dane.Count - 1
dane3 += dgv_dane.Rows(i).Cells(8).Value
Next
'' Suma ((yt-y*t)/yt)^2
For i As Integer = 0 To dane.Count - 1
dane4 += dgv_dane.Rows(i).Cells(8).Value ^ 2
Next
'' Suma yt^2
For i As Integer = 0 To dane.Count - 1
dane5 += dgv_dane.Rows(i).Cells(9).Value
Next
'suma ((yt-y*t)/yt)
For i As Integer = r To dane.Count - 1
dane6 += dgv_dane.Rows(i).Cells(6).Value / dane(i)
Next
'suma |(yt-y*t)|
For i As Integer = 0 To dane.Count - 1
dane7 += Math.Abs(dgv_dane.Rows(i).Cells(6).Value)
Next
''Wyświetlanie obliczeń
Rmspe.Text = Math.Round(Math.Sqrt(((1 / (dane.Count - r)) * (dane4))) * 100, 2) 'RMSPE
me_.Text = Math.Round((1 / (dane.Count - 1)) * dane1, 2) 'ME
Mse.Text = Math.Round((dane2) / (dane.Count - r), 2) ' MSE
MAE.Text = Math.Round((dane7) / (dane.Count - r), 2) ' MAE
Rmse.Text = Math.Round(Math.Sqrt(Mse.Text), 2) 'RMSE, musi być pod Mmse
MPE.Text = Math.Round((dane6) / (dane.Count - r) * 100, 2)
Mape.Text = Math.Round((((dane3) / (dane.Count - r))) * 100, 2) 'MAPE
ie.Text = dane.Count 'ilość elementów
SumaRoznic.Text = dane2 'suma (yt-y*t)^2
SumaKwadratow.Text = Math.Round(dane5, 2) 'suma yt^2
WspTheila.Text = Math.Round(SumaRoznic.Text / SumaKwadratow.Text, 6)
Mape_dla_prognozy1.Text = Math.Round(Rmse.Text / (dgv_dane.Rows(dgv_dane.Rows.Count - r + 1).Cells(5).Value) * 100, 2)
Catch ex As Exception
MsgBox("Error building datatable: " & ex.Message)
End Try
End Sub
Teraz dodamy metodę tworzącą wykresy naszego modelu:
Private Sub tworz_wykres()
'Wykres prezentujący nasze dane i prognoze
wykres2.ChartAreas(0).AxisX.MajorGrid.LineColor = Color.LightGray
wykres2.ChartAreas(0).AxisY.MajorGrid.LineColor = Color.LightGray
wykres2.Series(0).ChartType = DataVisualization.Charting.SeriesChartType.Line
wykres2.Series(0).Points.Clear()
wykres2.Series(0).Name = "yt"
wykres2.Series(0).BorderWidth = 2
For Count As Integer = 0 To dgv_dane.Rows.Count - 1
wykres2.Series(0).Points.AddXY(dgv_dane.Item(0, Count).Value, dgv_dane.Item(1, Count).Value)
Next
wykres2.Series(1).ChartType = DataVisualization.Charting.SeriesChartType.Line
wykres2.Series(1).Points.Clear()
wykres2.Series(1).Color = Color.Red
wykres2.Series(1).Name = "y*t"
wykres2.Series(1).BorderWidth = 2
For Count As Integer = 0 To dgv_dane.Rows.Count - 1
wykres2.Series(1).Points.AddXY(dgv_dane.Item(0, Count).Value, dgv_dane.Item(5, Count).Value)
Next
wykres2.Legends(0).Docking = Docking.Top
'wykres prezentujące ostatnie pięć zmiennych
Wykres1.ChartAreas(0).AxisX.MajorGrid.LineColor = Color.LightGray
Wykres1.ChartAreas(0).AxisY.MajorGrid.LineColor = Color.LightGray
Wykres1.Series(0).ChartType = DataVisualization.Charting.SeriesChartType.Line
Wykres1.Series(0).Points.Clear()
Wykres1.Series(0).Name = "yt"
Wykres1.Series(0).BorderWidth = 2
Wykres1.Series(0).IsValueShownAsLabel = True
Wykres1.Series(0).LabelBorderColor = Color.LightBlue
For Count As Integer = dgv_dane.Rows.Count - 8 To dgv_dane.Rows.Count - 1
Wykres1.Series(0).Points.AddXY(dgv_dane.Item(0, Count).Value, dgv_dane.Item(1, Count).Value)
Next
Wykres1.Series(1).ChartType = DataVisualization.Charting.SeriesChartType.Line
Wykres1.Series(1).Points.Clear()
Wykres1.Series(1).Color = Color.Red
Wykres1.Series(1).Name = "y*t"
Wykres1.Series(1).BorderWidth = 2
Wykres1.Series(1).IsValueShownAsLabel = True
Wykres1.Series(1).LabelBorderColor = Color.LightCoral
For Count As Integer = dgv_dane.Rows.Count - 8 To dgv_dane.Rows.Count - 1
Wykres1.Series(1).Points.AddXY(dgv_dane.Item(0, Count).Value, Math.Round(dgv_dane.Item(5, Count).Value))
Next
Wykres1.Legends(0).Docking = Docking.Top
'Wykres prezentujący sezonowość naszych danych
wykres3.Series(0).ChartType = DataVisualization.Charting.SeriesChartType.Line
wykres3.Series(0).Points.Clear()
wykres3.Series(0).Name = "Ct"
wykres3.Series(0).BorderWidth = 2
wykres3.ChartAreas(0).AxisX.MajorGrid.LineColor = Color.LightGray
wykres3.ChartAreas(0).AxisY.MajorGrid.LineColor = Color.LightGray
For Count As Integer = 0 To dgv_dane.Rows.Count - 5
wykres3.Series(0).Points.AddXY(dgv_dane.Item(0, Count).Value, dgv_dane.Item(4, Count).Value)
Next
wykres3.Legends(0).Docking = Docking.Top
End Sub
Następnie dodajemy funkcjonalność naszego przycisku „Odśwież”, dodałem tu taką właściwość przycisku, że jeśli do textboxa zostaną wpisane inne cyfry/litery niż te należące do zestawu liczb całkowitych dodatnich program wyświetli komunikat i ustawi tą wartość standardowo na 4:
Private Sub Odswiez_Click(sender As Object, e As EventArgs) Handles Odswiez.Click
If IsDBNull(DlugoscCyklu.Text) OrElse Not (IsNumeric(DlugoscCyklu.Text)) Or Not Integer.TryParse(DlugoscCyklu.Text, LiczbaFaz) Then
MsgBox("Możesz wpisać tylko liczba całkowite")
LiczbaFaz = 4
DlugoscCyklu.Text = LiczbaFaz
ElseIf DlugoscCyklu.Text <= 0 Or DlugoscCyklu.Text > dane.Count / 2 Then
MsgBox("Liczba faz nie może być taka duża/mała.")
LiczbaFaz = 4
DlugoscCyklu.Text = LiczbaFaz
End If
wartoscAlfa = alfa.Text
wartoscBeta = Beta.Text
wartoscGamma = Gamma.Text
LiczbaFaz = DlugoscCyklu.Text
dgv_dane.Rows.Clear()
Metoda_Wintersa(wartoscAlfa, wartoscBeta, wartoscGamma, LiczbaFaz)
tworz_wykres()
End Sub
Teraz dodamy sobie funkcjonalność klawiszy góra, dół które będą nam w zależności od textboxa w którym się znajdujemy zmieniać wartości alfa, beta, gamma o +0,01 albo -0,01.:
Private Sub alfa_KeyDown(sender As Object, e As KeyEventArgs) Handles alfa.KeyDown
Select Case e.KeyCode
Case Keys.Up
wartoscAlfa += 0.01
alfa.Text = wartoscAlfa
dgv_dane.Rows.Clear()
Metoda_Wintersa(wartoscAlfa, wartoscBeta, wartoscGamma, LiczbaFaz)
tworz_wykres()
Case Keys.Down
wartoscAlfa -= 0.01
alfa.Text = wartoscAlfa
dgv_dane.Rows.Clear()
Metoda_Wintersa(wartoscAlfa, wartoscBeta, wartoscGamma, LiczbaFaz)
tworz_wykres()
End Select
End Sub
Private Sub beta_KeyDown(sender As Object, e As KeyEventArgs) Handles Beta.KeyDown
Select Case e.KeyCode
Case Keys.Up
wartoscBeta += 0.01
Beta.Text = wartoscBeta
dgv_dane.Rows.Clear()
Metoda_Wintersa(wartoscAlfa, wartoscBeta, wartoscGamma, LiczbaFaz)
tworz_wykres()
Case Keys.Down
wartoscBeta -= 0.01
Beta.Text = wartoscBeta
dgv_dane.Rows.Clear()
Metoda_Wintersa(wartoscAlfa, wartoscBeta, wartoscGamma, LiczbaFaz)
tworz_wykres()
End Select
End Sub
Private Sub gamma_KeyDown(sender As Object, e As KeyEventArgs) Handles gamma.KeyDown
Select Case e.KeyCode
Case Keys.Up
wartoscGamma += 0.01
Gamma.Text = wartoscGamma
dgv_dane.Rows.Clear()
Metoda_Wintersa(wartoscAlfa, wartoscBeta, wartoscGamma, LiczbaFaz)
tworz_wykres()
Case Keys.Down
wartoscGamma -= 0.01
Gamma.Text = wartoscGamma
dgv_dane.Rows.Clear()
Metoda_Wintersa(wartoscAlfa, wartoscBeta, wartoscGamma, LiczbaFaz)
tworz_wykres()
End Select
End Sub
Następnie musimy dodać tylko obsługę RadioButtonów i wszystko będziemy mieli gotowe. Pierwszy RadioButton który przełącza na model multiplikatywny musi mieć dodaną dodatkową pętle if, ponieważ jego obsługa może być realizowana tylko wtedy gdy wykres jest już załadowany.
Private Sub MultiplikatywnaRB_CheckedChanged(sender As Object, e As EventArgs) Handles MultiplikatywnyRB.CheckedChanged
If kontroler = False Then
dgv_dane.Rows.Clear()
Metoda_Wintersa(wartoscAlfa, wartoscBeta, wartoscGamma, LiczbaFaz)
tworz_wykres()
End If
End Sub
Private Sub AddytywnaRB_CheckedChanged(sender As Object, e As EventArgs) Handles AddytywnyRB.CheckedChanged
dgv_dane.Rows.Clear()
Metoda_Wintersa(wartoscAlfa, wartoscBeta, wartoscGamma, LiczbaFaz)
tworz_wykres()
End Sub
To na tyle. Większość informacji tak jak widać udzieliłem w samym kodzie. Filmik z programem prezentuje poniżej:
Plik z kodem: Metoda_winters
Plik z danymi: multiplikatywny







2 komentarze
Dlaczego jak np wybiorę wartość dla r=5 ft liczone jest dopiero od dla 6 t .. Z tego co pamiętam i zawsze liczyłem dla np r=5 to Ft5 jest średnią średniej Ft1-5 ? czy robiłem to w sposób nieprawidłowy
Autor
Witam Pana, dziękuje za komentarz. Projekt umieszczony na stronie jest dosyć stary, dlatego może zawierać jakieś błędy. Nie do końca rozumiem w czym jest problem, ale jeśli jest Pan zainteresowany tylko programem do obliczania tej metody, to zapraszam na stronę:
https://visualmonsters.cba.pl/index.php/model-multiplikatywnyaddytywny-wintersa2/
W której dostępny jest program działający poprawnie. Jeśli dobrze zrozumiałem w czym jest problem, to jeśli model zaczynał by się tak jak Pan napisał wtedy nie został by wygenerowany pierwszy element Ct i nie dało by się wtedy obliczyć:
Ft = α *(yt-Ct-r)+(1-α)(Ft-1+St-1) // ponieważ dla C(1-1) element nie istnieje. Również dalsze elementy Ct były by niemożliwe do obliczenia, ponieważ nie istniałby by element C(1-1).
Z tego co zauważyłem to program opisany na stronie liczy źle ponieważ dla r=1 występuje błąd. Jednakże wszystko opisane jest w programie i łatwo można zmienić tą opcję.
Sprawdzę i poprawię wpis, dziękuje za czujność i komentarz.