1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
| Public Class MainForm
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Dim cf As New CalcForm
cf.Show()
Me.Hide()
End Sub
Private Sub ВыходToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ВыходToolStripMenuItem.Click
Application.Exit()
End Sub
Private Sub ТитульныйЛистToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ТитульныйЛистToolStripMenuItem.Click
Dim tf As New TitulForm
tf.ShowDialog()
End Sub
Private Sub ОПрограммеToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ОПрограммеToolStripMenuItem.Click
Dim af As New AboutForm
af.ShowDialog()
End Sub
Private Sub ИнструкцияToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ИнструкцияToolStripMenuItem.Click
Dim hf As New HelpForm
hf.ShowDialog()
End Sub
End Class
2. CalcForm.vb
Public Class CalcForm
Dim n, m As Int32
Dim ls As LinearSystem
Dim kh As KholeckySolve
Dim inputArray(,) As Double
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
n = Int32.Parse(TextBox1.Text)
m = Int32.Parse(TextBox2.Text)
CreateDataGrid(n, m)
End Sub
'создание таблицы
Private Sub CreateDataGrid(ByVal ro As Int32, ByVal co As Int32)
DGV.Columns.Clear()
For i = 0 To co - 1
DGV.Columns.Add(i.ToString, i.ToString)
DGV.Columns(i).Width = 50
Next i
DGV.Rows.Add(ro)
DGV.ColumnHeadersVisible = False
DGV.RowHeadersVisible = False
DGV.Font = New Font(FontFamily.GenericSansSerif, 10, FontStyle.Regular, GraphicsUnit.Pixel)
For i = 0 To ro - 1
For j = 0 To co - 1
DGV.Rows(i).Cells(j).Value = 0
Next j
Next i
End Sub
'закрытие формы
Private Sub CalcForm_FormClosed(ByVal sender As System.Object, ByVal e As System.Windows.Forms.FormClosedEventArgs) Handles MyBase.FormClosed
Application.Exit()
End Sub
'изменение значения выделенных ячеек
Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
For i = 0 To DGV.SelectedCells.Count - 1
DGV.SelectedCells(i).Value = TextBox3.Text
Next i
End Sub
'вычисление значений в ячейках
Private Sub Button3_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button3.Click
Dim array(n - 1, m - 1) As Double, ar_c(n - 1, m - 1) As Double
'Заполняем значением -1 все поля которые не участвуют в вычислении
For i = 0 To n - 1
Dim j As Int32 = 0, k As Int32 = m - 1 ' слева направо
While ((DGV.Rows(i).Cells(j).Value.ToString.Equals("0")) And (j < m - 1))
DGV.Rows(i).Cells(j).Value = -1
DGV.Rows(i).Cells(j).Style.BackColor = Color.LightGray
j += 1
End While
While ((DGV.Rows(i).Cells(k).Value.ToString.Equals("0")) And (k >= 0))
DGV.Rows(i).Cells(k).Value = -1 'справа налево
DGV.Rows(i).Cells(k).Style.BackColor = Color.LightGray
k -= 1
End While
Next i
For i = 0 To m - 1
Dim j As Int32 = 0, k As Int32 = n - 1 ' сверху вниз
While ((DGV.Rows(j).Cells(i).Value.ToString.Equals("0") Or DGV.Rows(j).Cells(i).Value.ToString.Equals("-1")) And (j < n - 1))
DGV.Rows(j).Cells(i).Value = -1
DGV.Rows(j).Cells(i).Style.BackColor = Color.LightGray
j += 1
End While
While ((DGV.Rows(k).Cells(i).Value.ToString.Equals("0") Or DGV.Rows(k).Cells(i).Value.ToString.Equals("-1")) And (k > 0))
DGV.Rows(k).Cells(i).Value = -1 'справа налево
DGV.Rows(k).Cells(i).Style.BackColor = Color.LightGray
k -= 1
End While
Next i
Dim count As Int32 = 0 'кол-во неизвестных
'считаем количество неизвестных, заполняем массив ar_c номерами неизвестных
For i = 0 To n - 1
For j = 0 To m - 1
array(i, j) = Double.Parse(DGV.Rows(i).Cells(j).Value.ToString)
If (array(i, j) = 0) Then
ar_c(i, j) = count
count += 1
End If
Next j
Next i
'массив коэффициентов и массив значений, для СЛАУ
Dim a(count - 1, count - 1) As Double, b(count - 1) As Double, nul(count - 1) As Double
'теперь мы будем обходить массив array и в зависимости от значения в конкретном поле будем
'смотреть соседние поля и заполнять массив коэффициентов и массив значений для СЛАУ
For i = 0 To n - 1
For j = 0 To m - 1
If (array(i, j) = 0) Then
'заполняем матрицу значений
b(ar_c(i, j)) = 0.25 * (array(i + 1, j) + array(i - 1, j) + array(i, j + 1) + array(i, j - 1))
a(ar_c(i, j), ar_c(i, j)) = 1
If (array(i - 1, j) = 0) Then 'верхний элемент
a(ar_c(i, j), ar_c(i - 1, j)) = -0.25
End If
If (array(i, j + 1) = 0) Then 'элемент справа
a(ar_c(i, j), ar_c(i, j + 1)) = -0.25
End If
If (array(i + 1, j) = 0) Then 'элемент снизу
a(ar_c(i, j), ar_c(i + 1, j)) = -0.25
End If
If (array(i, j - 1) = 0) Then 'элемент слева
a(ar_c(i, j), ar_c(i, j - 1)) = -0.25
End If
End If
Next j
Next i
Methods.a_st = a.Clone()
Methods.b_st = b.Clone()
Dim k_x(b.Length - 1) As Double
kh = New KholeckySolve
kh.KholeckySolve(a, b, k_x)
Dim z As Int32 = 0
For i = 0 To n - 1
For j = 0 To m - 1
If (Double.Parse(DGV.Rows(i).Cells(j).Value.ToString) > 0) Then
DGV.Rows(i).Cells(j).Style.BackColor = Color.Orange
End If
If (DGV.Rows(i).Cells(j).Value.ToString.Equals("0")) Then
DGV.Rows(i).Cells(j).Value = k_x(z).ToString("0.00")
DGV.Rows(i).Cells(j).Style.BackColor = Color.LightGreen
z += 1
End If
Next j
Next i
End Sub
'отображение СЛАУ
Private Sub Button4_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button4.Click
Dim lsv As New LinSysView
lsv.ShowDialog()
End Sub
'открытие диалога для выбора файлов
Private Sub Button5_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button5.Click
OpenFileDialog1.ShowDialog()
End Sub
'выбор файла
Private Sub OpenFileDialog1_FileOk(ByVal sender As System.Object, ByVal e As System.ComponentModel.CancelEventArgs) Handles OpenFileDialog1.FileOk
filePathTB.Text = OpenFileDialog1.FileName
End Sub
'считывание из файла
Private Sub Button6_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button6.Click
Dim inputString As String = ""
Dim x() As Double
Dim i As Int32 = 0
Dim file As New IO.StreamReader(filePathTB.Text) 'объявляем файл с которым будем работать
Dim myList As New ArrayList()
While (Not file.EndOfStream)
inputString = file.ReadLine 'считываем числа как строчку
inputString = Methods.SpaceDeleter(inputString)
x = Methods.StringToDouble(inputString.Split(" "))
myList.Add(x)
End While
file.Close()
n = myList.Count
x = myList.Item(0)
m = x.Length
CreateDataGrid(n, m)
For i = 0 To n - 1
For j = 0 To m - 1
x = myList.Item(i)
DGV.Rows(i).Cells(j).Value = x(j)
Next
Next
End Sub
Private Sub Button7_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button7.Click
Dim file As New IO.StreamWriter(Environment.CurrentDirectory + "/output.txt")
For i = 0 To k_x_r.Length - 1
file.WriteLine(k_x_r(i).ToString("0.00000"))
Next
file.Close()
End Sub
End Class
3. LinSysView.vb
Public Class LinSysView
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Me.Close()
End Sub
Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
Dim k As Int32 = 0
Try
For i = 0 To Methods.b_st.Length - 1
k = 0
For j = 0 To Methods.b_st.Length - 1
If (Methods.a_st(i, j) <> 0) Then
If (Methods.a_st(i, j) > 0 And k > 0) Then
TextBox1.Text += "+"
End If
TextBox1.Text += Methods.a_st(i, j).ToString("0.00") + "Х" + j.ToString + " "
k += 1
End If
Next j
TextBox1.Text += "=" + Methods.b_st(i).ToString("0.000") + Environment.NewLine
Next i
Catch ex As Exception
MessageBox.Show(ex.Message)
End Try
End Sub
End Class
4. Methods.vb
Public Class Methods
Public Shared a_st(,), b_st() As Double
'Функция конвертирующая массив типа String в тип Double
Public Shared Function StringToDouble(ByVal str() As String) As Double()
Dim out(str.Length - 1) As Double 'объявляем массив чисел размерностью входного массива
Dim i As Int32 'счетчик для цикла и индекс для элементов массива
Try
For i = 0 To str.Length - 1 'для всех элементов выполняем Parse (преобразование строки в число)
out(i) = Double.Parse(str(i))
Next i
Catch ex As ExecutionEngineException
MessageBox.Show(ex.Message) 'в случае возникновения исключения выводим информацию о нем
End Try
Return out 'возвращаем итоговый массив
End Function
'Удаляет во входной строке лишние пробелы, в конце и в начале тоже
Public Shared Function SpaceDeleter(ByVal s As String) As String
Dim st As String = "" 'иначально строка пуста
Dim i As Int32 = 0 'счетчик
Dim b As Boolean = False
Try 'всё выполняем в try чтобы программа не вылетала и мы перехватывали исключительные ситуации
If (Char.IsDigit(s, i) Or s(i) = "-" Or s(i) = ",") Then 'если первый символ это цифра либо знак минуса
st += s(i) 'то прибавляем его к строчке st и увеличиваем счетчик
i += 1
Else
While ((Not Char.IsDigit(s, i) Or s(i) = "-") And (i < s.Length))
i += 1 'иначе до тех пор пока не встретится цифра либо знак минуса будем увеличивать счетчик
b = True 'переменная необходимая для учета пробелов, чтобы ставили ровно 1 раз
End While
End If
'если метод не завершился, то i указывает на цифру в строке
While (i < s.Length) 'пока не дошли до конца строки при встрече минуса и цифры будем прибавлять
If (Char.IsDigit(s, i) Or s(i) = "-" Or s(i) = ",") Then 'его к строке st и ставить один пробел
If (b) Then
st += " "
b = False
End If
st += s(i)
i += 1
Else 'если же попался другой символ то увеличиваем счетчик
i += 1
b = True
End If
End While
Catch ex As Exception
MessageBox.Show(ex.Message + "i=" + i.ToString)
End Try
Return st 'возвращаем строку
End Function
End Class
5. KholeckySolve.vb
Public Class KholeckySolve
Sub KholeckySolve(ByVal a(,) As Double, ByVal b_vector() As Double, ByRef x_vector() As Double)
Dim n As Integer
Dim sum As Double
n = b_vector.Length
Dim p(n - 1) As Double
For i = 0 To n - 1
For j = i To n - 1
sum = a(i, j)
For k = i - 1 To 0 Step -1
sum -= a(i, k) * a(j, k)
Next
If i = j Then
p(i) = Math.Sqrt(sum)
a(i, i) = p(i)
Else
a(j, i) = sum / p(i)
End If
Next
Next
For i = 0 To n - 1
sum = b_vector(i)
For k = i - 1 To 0 Step -1
sum -= a(i, k) * x_vector(k)
Next
x_vector(i) = sum / p(i)
Next
For i = n - 1 To 0 Step -1
sum = x_vector(i)
For k = i + 1 To n - 1
sum -= a(k, i) * x_vector(k)
Next
x_vector(i) = sum / p(i)
Next
End Sub
End Class |