Public Class Form1

    Structure Cont_param
        Dim Type As Integer
        Dim dist As Integer
        Dim K_dist As Single
        Dim cicl As Boolean
        Dim range As Integer
    End Structure

    ' Типы контекста
    ' 0 - категориальный
    ' 1 - натуральный интервальный 
    ' 2 - натуральный циклический

    Public Context_set() As Cont_param

    Public G_codes() As longbit


    Public N_Cont As Integer
    Public N_range As Integer


    Public N_W As Integer = 4
    Public N_bit As Integer = 64 * N_W ' Разрядность кода входного описания
    Public N_1 As Integer = 4 ' Количество единиц в простом признаке
    Public N_sec_neuron As Integer = 8 ' Количество дендритных секций на один нейрон
    Public N_Fact As Integer = 64
    Public N_min_DS_A As Integer = N_sec_neuron * 0.75



    ' Зависимость вклада воспоминания в меру близости от количества совпавших контекстов
    Public W_prox() As Integer = {1, 1, 1, 1} '{0, 0.15, 0.4, 1} '


    Dim X_C As Integer = 48
    Dim Y_C As Integer = 48

    Dim R_mem As Integer = 5
    Dim R_avg As Integer = 2

    Dim Cortex(X_C - 1, Y_C - 1) As column

    Dim field(X_C - 1, Y_C - 1) As Single

    Dim Color_arr()() As Color

    Dim N_Fields As Integer = 2

    ' Радиус распространения активности.
    Dim RA As Integer = 3

    Dim sigma2(N_Fields - 1) As Single

    ' шаблон распределения активности
    Dim NLocalAM = 2 * RA + 1
    Dim LocalAM(NLocalAM - 1, NLocalAM - 1, N_Fields - 1)

    Dim hash_codes As New Dictionary(Of Integer, longbit)
    Dim Img_from_hash As New Dictionary(Of Integer, String)

    Dim PB_cont_Array() As PictureBox

    Dim CorrArray(,) As Double


    Dim Time_ID As Integer = 0


    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load

        For ix = 0 To X_C - 1
            For iy = 0 To Y_C - 1

                Cortex(ix, iy) = New column

            Next
        Next


        PictureBox2.Image = My.Resources.Resource1.spectrum




        ' Сумма всех точек дает единицу. Это позволяет устанавливать пороги для полей в процентах задействованных нейронов
        Dim dx, dy As Single

        sigma2(0) = 1.0 ^ 2
        sigma2(1) = 0.5 ^ 2

        For k = 0 To N_Fields - 1

            For ix = 0 To NLocalAM - 1
                For iy = 0 To NLocalAM - 1

                    dx = ix - RA
                    dy = iy - RA


                    LocalAM(ix, iy, k) = (1 / (2 * Math.PI * sigma2(k))) * Math.Exp(-1 / (2 * sigma2(k)) * (dx ^ 2 + dy ^ 2))

                Next
            Next

        Next


    End Sub

    Private Sub Colorset()

        ReDim Color_arr(N_Cont - 1)

        For j = 0 To N_Cont - 1

            Dim a As Double = (My.Resources.Resource1.spectrum.Width - 1) / Context_set(j).range

            ReDim Color_arr(j)(Context_set(j).range - 1)

            For i = 0 To Context_set(j).range - 1

                Color_arr(j)(i) = My.Resources.Resource1.spectrum.GetPixel(Int(a * i), 0)

            Next

        Next
    End Sub

    Public Function mem_hash(ByRef Info As Integer()) As Integer

        mem_hash = Info(N_Cont - 1)

        If N_Cont > 1 Then

            For i = N_Cont - 2 To 0 Step -1

                mem_hash = mem_hash * Context_set(i).range + Info(i)

            Next

        End If

    End Function

    'Public Function set_from_hash(ByRef h As Integer) As Integer()

    '    Dim a() As Integer

    '    For i = N_Cont - 1 To 0 Step -1

    '        a(i) = h Mod type_of_Cont(i).range

    '    Next

    '    set_from_hash = a

    'End Function

    Public Structure mem_point

        Public X As Integer
        Public Y As Integer
        Public ID As Integer

    End Structure

    Private Function E() As Double

        E = 0

        For ix = 0 To X_C - 1
            For iy = 0 To Y_C - 1

                For Each m In Cortex(ix, iy).mem_main



                Next

            Next
        Next

    End Function

    Private Sub set_G_codes()
        'type_of_Cont = {New Cont_param With {.Type = 2, .cicl = True, .dist = 2, .K_dist = 0.5, .range = 8},
        'New Cont_param With {.Type = 1, .cicl = False, .dist = 2, .K_dist = 0.5, .range = 8},
        'New Cont_param With {.Type = 1, .cicl = False, .dist = 2, .K_dist = 0.5, .range = 8}}

        ' PB_cont_Array = {PictureBox1,PictureBox3,PictureBox4}


        Context_set = {New Cont_param With {.Type = 2, .cicl = True, .dist = 1, .K_dist = 0.2, .range = 8}}






    End Sub



    Private Sub organize(sender As Object, e As EventArgs) Handles Button1.Click

        Dim j As Integer


        'type_of_Cont = {New Cont_param With {.Type = 2, .cicl = True, .dist = 2, .K_dist = 0.5, .range = 8},
        'New Cont_param With {.Type = 1, .cicl = False, .dist = 2, .K_dist = 0.5, .range = 8},
        'New Cont_param With {.Type = 1, .cicl = False, .dist = 2, .K_dist = 0.5, .range = 8}}

        ' PB_cont_Array = {PictureBox1,PictureBox3,PictureBox4}


        Context_set = {New Cont_param With {.Type = 2, .cicl = True, .dist = 1, .K_dist = 0.2, .range = 8}}

        PB_cont_Array = {PictureBox1}


        N_Cont = Context_set.Count
        N_range = Context_set(0).range


        Colorset()


        Dim Data_Source As New Info_Sourse

        Dim info As Info_item

        Dim r2, s As Single

        Dim info_hash As Integer

        Dim max_x, max_y As Integer


        ' Начальный случайный наброс
        For i = 1 To 1

            info = Data_Source.get_rundom_info()

            max_x = Int(Rnd() * X_C)
            max_y = Int(Rnd() * Y_C)


            Cortex(max_x, max_y).mem_main.Add(Time_ID, New mem_item With {.DATA = info.DATA})

            Time_ID += 1

        Next



        For i = 0 To 100

            ' Запоминание

            If Time_ID < 2000 Then

                For j = 1 To 500

                    info = Data_Source.get_rundom_info()

                    'memory_add(Time_ID, info)
                    memory_add_max(Time_ID, info)

                    Label1.Text = Time_ID.ToString
                    Label1.Update()

                    Time_ID += 1

                Next

            End If


            ' Реконсолидация

            Dim ID As Integer
            Dim nn As Integer = 0



            ' Создание случайной последовательности памяти для реконсолидации

            Dim seq_list As New List(Of mem_point)
            Dim seq() As mem_point


            For ix = 0 To X_C - 1
                For iy = 0 To Y_C - 1

                    For Each m In Cortex(ix, iy).mem_main

                        seq_list.Add(New mem_point With {.X = ix, .Y = iy, .ID = m.Key})

                    Next

                Next

            Next



            seq = seq_list.ToArray
            Dim pp1, pp2 As mem_point

            For k = 0 To seq.Count - 1
                j = Int(Rnd() * seq.Count)
                pp1 = seq(k)
                pp2 = seq(j)
                seq(k) = pp2
                seq(j) = pp1
            Next



            For Each pp In seq

                ID = pp.ID

                memory_recons(pp.X, pp.Y, ID)

                Label1.Text = "Реконс. - " & nn.ToString
                Label1.Update()

                nn += 1



            Next

        Next


    End Sub

    Private Sub memory_add_max(ID As Integer, info As Info_item)

        Dim max_R As Single = 0

        Dim max_x, max_y As Integer

        For ix = 0 To X_C - 1
            For iy = 0 To Y_C - 1

                Cortex(ix, iy).R(0) = Cortex(ix, iy).proximity(info.DATA)
                Cortex(ix, iy).R(1) = Cortex(ix, iy).mem_main.Count

            Next
        Next


        ' Запоминаем опыт


        Clear_Field()

        Calc_Field(0, 1, 0)
        'Calc_Field(1, -0.3, 1)

        max_R = 0



        For ix = 0 To X_C - 1
            For iy = 0 To Y_C - 1

                If field(ix, iy) > max_R Then

                    max_R = field(ix, iy)
                    max_x = ix
                    max_y = iy

                End If

            Next
        Next


        Cortex(max_x, max_y).mem_main.Add(ID, New mem_item With {.DATA = info.DATA})

        If ID Mod 10 = 0 Then

            For i = 0 To N_Cont - 1
                draw_cont(i, PB_cont_Array(i))
            Next

        End If

        If ID Mod 10 = 0 Then
            draw_field(PictureBox5)
        End If


    End Sub

    Private Sub memory_add(ID As Integer, info As Info_item)


        For ix = 0 To X_C - 1
            For iy = 0 To Y_C - 1

                Cortex(ix, iy).R(0) = Cortex(ix, iy).proximity(info.DATA)
                Cortex(ix, iy).R(1) = Cortex(ix, iy).mem_main.Count

                'If Cortex(ix, iy).R(0) > 0 Then
                '    ID = ID
                'End If

            Next
        Next


        ' Запоминаем опыт


        Clear_Field()

        Calc_Field(0, 1, 0)
        'Calc_Field(1, -0.1, 1)



        Dim sum As Single = 0

        For ix = 0 To X_C - 1
            For iy = 0 To Y_C - 1

                If field(ix, iy) < 0 Then
                    field(ix, iy) = 0
                End If

                sum += field(ix, iy)
            Next
        Next

        ' Подготовка границ интервалов. Длина интервалов пропорциональна вероятности отнесения к соответствующей колонке

        Dim d As Double = 0
        Dim delta_d As Double

        For ix = 0 To X_C - 1
            For iy = 0 To Y_C - 1

                delta_d = field(ix, iy) / sum

                Cortex(ix, iy).d1 = d
                d += delta_d
                Cortex(ix, iy).d2 = d
            Next
        Next

        ' Запоминаем опыт на случайной колонке. Вероятность выбора колонки пропорциональна плотности поля в ней

        d = Rnd()

        For ix = 0 To X_C - 1
            For iy = 0 To Y_C - 1

                If Cortex(ix, iy).d1 <= d And Cortex(ix, iy).d2 >= d Then

                    'Dim new_mem_item As New mem_item

                    Cortex(ix, iy).mem_main.Add(ID, New mem_item With {.DATA = info.DATA})

                    If ID Mod 50 = 0 Then

                        For i = 0 To N_Cont - 1
                            draw_cont(i, PB_cont_Array(i))
                        Next

                    End If

                    If ID Mod 10 = 0 Then
                        draw_field(PictureBox5)
                    End If

                    Exit Sub

                End If

            Next
        Next





    End Sub

    Private Sub memory_recons(ix_s As Integer, iy_s As Integer, ID As Integer)

        Dim info As New Info_item


        info.DATA = Cortex(ix_s, iy_s).mem_main(ID).DATA



        For ix = 0 To X_C - 1
            For iy = 0 To Y_C - 1

                Cortex(ix, iy).R(0) = Cortex(ix, iy).proximity(info.DATA)
                Cortex(ix, iy).R(1) = Cortex(ix, iy).mem_main.Count

            Next
        Next


        ' Запоминаем опыт


        Clear_Field()

        Calc_Field(0, 1, 0)
        'Calc_Field(1, -0.3, 1)



        Dim sum As Single = 0

        For ix = 0 To X_C - 1
            For iy = 0 To Y_C - 1

                If field(ix, iy) < 0 Then
                    field(ix, iy) = 0
                End If

                sum += field(ix, iy)

            Next
        Next



        ' Подготовка границ интервалов. Длина интервалов пропорциональна вероятности отнесения к соответствующей колонке

        Dim d As Double = 0
        Dim delta_d As Double

        For ix = 0 To X_C - 1
            For iy = 0 To Y_C - 1

                delta_d = field(ix, iy) / sum

                Cortex(ix, iy).d1 = d
                d += delta_d
                Cortex(ix, iy).d2 = d

            Next
        Next

        ' Запоминаем опыт на случайной колонке. Вероятность выбора колонки пропорциональна плотности поля в ней

        d = Rnd()

        For ix = 0 To X_C - 1
            For iy = 0 To Y_C - 1

                If Cortex(ix, iy).d1 <= d And Cortex(ix, iy).d2 >= d Then

                    'Dim new_mem_item As New mem_item

                    If field(ix_s, iy_s) > field(ix, iy) Then

                        If iy = 0 Then
                            ID = ID
                        End If

                        Cortex(ix_s, iy_s).mem_main.Remove(ID)

                        Cortex(ix, iy).mem_main.Add(ID, New mem_item With {.DATA = info.DATA})

                        If ID Mod 50 = 0 Then

                            For i = 0 To N_Cont - 1
                                draw_cont(i, PB_cont_Array(i))
                            Next

                        End If

                        If ID Mod 10 = 0 Then
                            draw_field(PictureBox5)
                        End If

                        Exit Sub

                    End If
                End If

            Next
        Next




    End Sub


    Private Sub Clear_Field()

        For ix = 0 To X_C - 1
            For iy = 0 To Y_C - 1

                field(ix, iy) = 0

            Next
        Next

    End Sub

    Private Sub Calc_Field(ByRef N As Integer, ByRef K As Single, NR As Integer)

        Dim x, y As Integer
        Dim s As Single


        For ix = 0 To X_C - 1
            For iy = 0 To Y_C - 1

                s = Cortex(ix, iy).R(NR)

                If s > 0 Then

                    For ix1 = 0 To NLocalAM - 1
                        For iy1 = 0 To NLocalAM - 1

                            x = ix + ix1 - RA
                            y = iy + iy1 - RA

                            If x >= 0 And y >= 0 And x < X_C And y < Y_C Then
                                field(x, y) += LocalAM(ix1, iy1, N) * s * K
                            End If

                        Next
                    Next

                End If

            Next
        Next



    End Sub

    Private Sub draw_field(ByRef pb As PictureBox)

        Dim pic1 As New Bitmap(X_C, Y_C)

        Dim Y As Integer

        Dim max As Single = 0

        For ix = 0 To X_C - 1
            For iy = 0 To Y_C - 1

                If Math.Abs(field(ix, iy)) > max Then

                    max = Math.Abs(field(ix, iy))

                End If

            Next
        Next

        If max > 0 Then

            For ix = 0 To X_C - 1
                For iy = 0 To Y_C - 1

                    Y = field(ix, iy) / max * 255
                    'If Y > 255 Then Y = 255
                    If Y < -255 Then Y = -255

                    If Y >= 0 Then
                        pic1.SetPixel(ix, iy, Color.FromArgb(Y, 0, 0))
                    Else
                        pic1.SetPixel(ix, iy, Color.FromArgb(0, 0, -Y))
                    End If

                Next
            Next

        End If

        pb.Image = pic1
        pb.Update()

    End Sub

    Private Sub draw_cont(ByRef N As Integer, ByRef pb As PictureBox, Optional ByRef need_set_cont As Boolean = True)

        Dim pic1 As New Bitmap(X_C, Y_C)

        Dim Y As Integer

        For ix = 0 To X_C - 1
            For iy = 0 To Y_C - 1

                If need_set_cont Then
                    Cortex(ix, iy).set_pref_cont()
                End If

                If Cortex(ix, iy).pref_cont IsNot Nothing Then

                    Y = Cortex(ix, iy).pref_cont(N)
                    pic1.SetPixel(ix, iy, Color_arr(N)(Y))
                Else

                    pic1.SetPixel(ix, iy, Color.Gray)

                End If

            Next
        Next

        pb.Image = pic1
        pb.Update()

    End Sub

    'Private Sub draw_mem(ByRef info() As Integer)

    '    Dim pic1 As New Bitmap(X_C, Y_C)

    '    Dim Y As Integer

    '    Dim info_hash As Integer = mem_hash(info)

    '    For ix = 0 To X_C - 1
    '        For iy = 0 To Y_C - 1


    '            'Cortex(ix, iy).set_pref_cont()

    '            If Cortex(ix, iy).mem_second.ContainsKey(info_hash) Then
    '                Y = Cortex(ix, iy).mem_second(info_hash).N

    '                If Y > 255 Then Y = 255

    '                pic1.SetPixel(ix, iy, Color.FromArgb(Y, Y, Y))
    '            Else

    '                pic1.SetPixel(ix, iy, Color.Gray)

    '            End If




    '        Next
    '    Next

    '    PictureBox3.Image = pic1
    '    PictureBox3.Update()

    'End Sub

    Private Sub Draw_column(sender As Object, e As MouseEventArgs) Handles PictureBox1.Click


        Dim ix As Integer = e.X / PictureBox1.Width * X_C - 1
        Dim iy As Integer = e.Y / PictureBox1.Height * Y_C - 1



    End Sub

    Private Sub Draw_A(maxA As Single)

        Dim pic1 As New Bitmap(X_C, Y_C)

        Dim Y As Integer


        For ix = 0 To X_C - 1
            For iy = 0 To Y_C - 1

                Y = Cortex(ix, iy).mem_A / maxA * 255

                pic1.SetPixel(ix, iy, Color.FromArgb(Y, Y, Y))

            Next
        Next

        PictureBox3.Image = pic1
        PictureBox3.Update()

    End Sub


    Private Sub Learn_direct(sender As Object, e As EventArgs) Handles Button2.Click

        Context_set = {New Cont_param With {.Type = 2, .cicl = True, .dist = 2, .K_dist = 0.5, .range = 8}}
        N_Cont = Context_set.Count
        N_range = Context_set(0).range
        Colorset()


        X_C = Context_set(0).range
        Y_C = 1

        ReDim Cortex(X_C - 1, Y_C - 1)

        Dim h1 As Integer

        Dim h2 As New longbit
        Dim h_bloom As New longbit

        Dim cur_img_set As New List(Of longbit)

        Dim str_ar(N_range - 1) As Char

        For i = 0 To N_range - 1
            str_ar(i) = "_"
        Next

        Dim str As String

        For ix = 0 To X_C - 1
            For iy = 0 To Y_C - 1

                Cortex(ix, iy) = New column

                Cortex(ix, iy).pref_cont = {ix}

            Next
        Next

        Set_hash_text()

        Dim info_s As New Info_Sourse

        Dim Cur_info As Info_item

        Time_ID = 0


        For i = 0 To 100000

            Cur_info = info_s.get_next_info()

            h1 = ch_pos_hash(Cur_info.DATA(0), Cur_info.Img)

            h2 = hash_codes(h1)

            cur_img_set.Add(h2)

            str_ar(Cur_info.DATA(0)) = Cur_info.ch

            If cur_img_set.Count > N_range Then

                cur_img_set.RemoveAt(0)

            End If

            h_bloom.reset()

            For Each h In cur_img_set

                h_bloom.OR_(h)

            Next


            Time_ID += 1


            ' проверяем резонанс памяти в каждом из контекстов

            Dim max As Single = 0

            Dim maxx, maxy As Integer
            Dim k As Integer

            Dim mI As mem_item

            For ix = 0 To X_C - 1
                For iy = 0 To Y_C - 1

                    With Cortex(ix, iy)

                        .mem_A = Rnd() * 0.01

                        For Each m In .mem_main

                            k = m.Value.bin.prox_1(h_bloom)

                            mI = .mem_main(m.Key)

                            mI.A = k

                            If k >= N_1 Then
                                .mem_A += k

                            End If

                        Next


                        If .mem_A > max Then

                            max = .mem_A
                            maxx = ix
                            maxy = iy

                        End If

                    End With

                Next
            Next


            str = ""
            For Each ch In str_ar
                str &= ch
            Next

            Label1.Text = str
            Label1.Update()

            ' Запоминаем в позиции наибольшего резонанса
            Cortex(maxx, maxy).mem_main.Add(Time_ID, New mem_item With {.bin = h_bloom, .str = str})

            Draw_A(max)

            Draw_mem_text()

            ' Считаем фактор 
            'Cortex(maxx, maxy).calc_F(h_bloom)

            'Draw_F(maxx, maxy)

        Next









    End Sub

    Private Sub Draw_mem_text()

        Dim blank As String = "___________________________".Substring(0, N_range)

        Dim str(N_range - 1) As List(Of String)

        Dim box As String = ""

        Dim max As Integer = 0

        For i = 0 To N_range - 1

            str(i) = New List(Of String)

            For Each m In Cortex(i, 0).mem_main

                str(i).Add(m.Value.str & " " & m.Value.A.ToString)

            Next

            If str(i) IsNot Nothing AndAlso str(i).Count > max Then

                max = str(i).Count

            End If



        Next

        For i = 0 To max - 1

            For j = 0 To N_range - 1

                If str(j) IsNot Nothing AndAlso i < str(j).Count Then

                    box &= str(j)(i)


                Else
                    box &= blank

                End If

                box &= "--" & vbTab

            Next

            box &= vbCrLf

        Next

        TextBox1.Text = box
        TextBox1.Update()


    End Sub

    Private Function prox_1(ByVal h1 As ULong, ByVal h2 As ULong) As Integer

        prox_1 = 0

        For i = 0 To 63

            prox_1 += (h1 Mod 2) And (h2 Mod 2)

            h1 = h1 >> 1
            h2 = h2 >> 1
        Next

    End Function

    Private Sub Set_hash_text()

        Dim h1 As Integer

        Dim h2 As New longbit

        For p = 0 To Context_set(0).range - 1

            For i = 0 To 32

                h1 = ch_pos_hash(p, i)

                h2.get_random_hash(N_1)

                hash_codes.Add(h1, h2)

                If i = 0 Then
                    Img_from_hash.Add(h1, " " & "_" & p.ToString)
                Else
                    Img_from_hash.Add(h1, Chr(Asc("а"c) + i - 1) & "_" & p.ToString)
                End If


            Next

        Next


    End Sub

    Private Function ch_pos_hash(p As Integer, i As Integer) As Integer
        ch_pos_hash = p * 33 + i
    End Function

    Private Sub Button3_Click(sender As Object, e As EventArgs) Handles Button3.Click
        set_G_codes()
    End Sub

    Private Function id(ByRef P() As Integer) As Integer

        id = P(0)

        If Context_set.Count > 1 Then

            For i = 1 To Context_set.Count - 1

                id = id * Context_set(i).range + P(i)

            Next

        End If

    End Function

    Public Function corr_cont(ByRef P1 As Integer(), P2 As Integer()) As Double

        corr_cont = 0

        Dim s As Double

        Dim d, r, x As Double

        s = 0

        If P2 IsNot Nothing Then

            r = 0

            For i = 0 To Context_set.Count - 1

                d = Math.Abs(P1(i) - P2(i))

                Select Case Context_set(i).Type
                    Case 0
                        If d = 0 Then
                            x = 0
                        Else
                            x = 0.2
                        End If

                    Case 1
                        x = Math.Abs(P1(i) - P2(i)) / Context_set(i).dist
                    Case 2
                        x = Math.Min(d, Context_set(i).range - d) / Context_set(i).dist
                End Select


                r += x * x

            Next

            r = Math.Sqrt(r)

            If r <= 1 Then

                s = (1 - r)
                corr_cont = s

            End If


        End If



    End Function

    Private Sub Button4_Click(sender As Object, e As EventArgs) Handles Button4.Click

        Context_set = {New Cont_param With {.Type = 2, .cicl = True, .dist = 8, .K_dist = 0.0, .range = 12},
        New Cont_param With {.Type = 1, .cicl = False, .dist = 3, .K_dist = 0.0, .range = 5},
        New Cont_param With {.Type = 1, .cicl = False, .dist = 3, .K_dist = 0.0, .range = 5},
        New Cont_param With {.Type = 0, .cicl = False, .dist = 0, .K_dist = 0.0, .range = 2}}



        ' Пинвелы с глазодоминантностью
        'Context_set = {New Cont_param With {.Type = 2, .cicl = True, .dist = 8, .K_dist = 0.0, .range = 18},
        'New Cont_param With {.Type = 1, .cicl = False, .dist = 3, .K_dist = 0.0, .range = 8},
        'New Cont_param With {.Type = 1, .cicl = False, .dist = 3, .K_dist = 0.0, .range = 8},
        'New Cont_param With {.Type = 0, .cicl = False, .dist = 0, .K_dist = 0.0, .range = 2}}

        'Context_set = {New Cont_param With {.Type = 2, .cicl = True, .dist = 4, .K_dist = 0.0, .range = 6},
        'New Cont_param With {.Type = 1, .cicl = False, .dist = 5, .K_dist = 0.0, .range = 9},
        'New Cont_param With {.Type = 1, .cicl = False, .dist = 5, .K_dist = 0.0, .range = 9}} ',
        ''New Cont_param With {.Type = 0, .cicl = False, .dist = 0, .K_dist = 0.0, .range = 2}}

        'Context_set = {New Cont_param With {.Type = 2, .cicl = True, .dist = 2, .K_dist = 0.0, .range = 8},
        'New Cont_param With {.Type = 2, .cicl = True, .dist = 2, .K_dist = 0.0, .range = 8},
        'New Cont_param With {.Type = 1, .cicl = False, .dist = 2, .K_dist = 0.0, .range = 8}} ',
        ''New Cont_param With {.Type = 0, .cicl = False, .dist = 0, .K_dist = 0.0, .range = 2}}

        PB_cont_Array = {PictureBox1, PictureBox3, PictureBox4, PictureBox5}

        Dim maxid As Integer = id({Context_set(0).range - 1, Context_set(1).range - 1, Context_set(2).range - 1, Context_set(3).range - 1})

        ReDim CorrArray(maxid, maxid)

        Dim id_c As Integer

        Dim id1, id2 As Integer

        Dim p1(), p2() As Integer

        For i1 = 0 To Context_set(0).range - 1
            For i2 = 0 To Context_set(1).range - 1
                For i3 = 0 To Context_set(2).range - 1
                    For i4 = 0 To Context_set(3).range - 1

                        p1 = {i1, i2, i3, i4}
                        id1 = id(p1)

                        For j1 = 0 To Context_set(0).range - 1
                            For j2 = 0 To Context_set(1).range - 1
                                For j3 = 0 To Context_set(2).range - 1
                                    For j4 = 0 To Context_set(3).range - 1

                                        p2 = {j1, j2, j3, j4}
                                        id2 = id(p2)

                                        CorrArray(id1, id2) = corr_cont(p1, p2)

                                    Next
                                Next
                            Next
                        Next
                    Next

                Next

            Next
        Next


        Dim E_old_1, E_old_2, E_new As Double
        Dim max_delta, delta As Double
        Dim ix_m, iy_m As Integer


        N_Cont = Context_set.Count

        Colorset()

        Dim len_space As Integer = 1

        For Each T In Context_set
            len_space = T.range * len_space
        Next

        Dim P(N_Cont - 1) As Integer

        Dim ix, iy As Integer

        Dim seq(len_space - 1) As Integer

        For i = 0 To len_space - 1
            seq(i) = i
        Next

        Dim k, nn As Integer

        For j = 0 To len_space - 1

            k = Int(Rnd() * len_space)
            nn = seq(j)
            seq(j) = seq(k)
            seq(k) = nn

        Next



        For pos = 0 To len_space - 1

            P = coord(seq(pos), N_Cont)

            Do
                ix = Int(Rnd() * X_C)
                iy = Int(Rnd() * Y_C)

            Loop Until Cortex(ix, iy).pref_cont Is Nothing

            Cortex(ix, iy).pref_cont = P
            Cortex(ix, iy).id_cont = id(P)














            For j = 0 To 100



                ix = Int(Rnd() * X_C)
                iy = Int(Rnd() * Y_C)

                If Cortex(ix, iy).pref_cont IsNot Nothing Then



                    max_delta = 0



                    If Rnd() > 1 Then

                        For iix = 0 To X_C
                            For iiy = 0 To Y_C

                                If iix >= 0 And iix < X_C And iiy >= 0 And iiy < Y_C And Not (iix = ix And iiy = iy) Then

                                    E_old_1 = E_node(Cortex(ix, iy).pref_cont, ix, iy, iix, iiy)
                                    E_old_2 = E_node(Cortex(iix, iiy).pref_cont, iix, iiy, ix, iy)

                                    E_new = E_node(Cortex(ix, iy).pref_cont, iix, iiy, ix, iy) +
                                    E_node(Cortex(iix, iiy).pref_cont, ix, iy, iix, iiy)

                                    delta = E_old_1 + E_old_2 - E_new

                                    If delta > max_delta Then

                                        max_delta = delta
                                        ix_m = iix
                                        iy_m = iiy

                                    End If

                                End If

                            Next
                        Next


                    Else


                        For iix = ix - 1 To ix + 1
                            For iiy = iy - 1 To iy + 1

                                If iix >= 0 And iix < X_C And iiy >= 0 And iiy < Y_C And Not (iix = ix And iiy = iy) Then

                                    E_old_1 = E_node(Cortex(ix, iy).pref_cont, ix, iy, iix, iiy)
                                    E_old_2 = E_node(Cortex(iix, iiy).pref_cont, iix, iiy, ix, iy)

                                    E_new = E_node(Cortex(ix, iy).pref_cont, iix, iiy, ix, iy) +
                                            E_node(Cortex(iix, iiy).pref_cont, ix, iy, iix, iiy)

                                    delta = E_old_1 + E_old_2 - E_new

                                    If delta > max_delta Then

                                        max_delta = delta
                                        ix_m = iix
                                        iy_m = iiy

                                    End If

                                End If

                            Next
                        Next



                    End If








                    If max_delta > 0 Then

                        P = Cortex(ix, iy).pref_cont
                        Cortex(ix, iy).pref_cont = Cortex(ix_m, iy_m).pref_cont
                        Cortex(ix_m, iy_m).pref_cont = P

                        id_c = Cortex(ix, iy).id_cont
                        Cortex(ix, iy).id_cont = Cortex(ix_m, iy_m).id_cont
                        Cortex(ix_m, iy_m).id_cont = id_c


                    End If


                    If j Mod 25 = 0 Then

                        For i = 0 To N_Cont - 1
                            draw_cont(i, PB_cont_Array(i), False)

                            'draw_CLOSE_AREA(X_C / 2, Y_C / 2)



                        Next

                        Label1.Text = j
                        Label1.Update()

                    End If

                End If



            Next





















        Next

        For i = 0 To N_Cont - 1
            draw_cont(i, PB_cont_Array(i), False)
        Next




        For j = 0 To 1000000



            ix = Int(Rnd() * X_C)
            iy = Int(Rnd() * Y_C)

            If Cortex(ix, iy).pref_cont IsNot Nothing Then



                max_delta = 0



                If Rnd() > 1 Then

                    For iix = 0 To X_C
                        For iiy = 0 To Y_C

                            If iix >= 0 And iix < X_C And iiy >= 0 And iiy < Y_C And Not (iix = ix And iiy = iy) Then

                                E_old_1 = E_node(Cortex(ix, iy).pref_cont, ix, iy, iix, iiy)
                                E_old_2 = E_node(Cortex(iix, iiy).pref_cont, iix, iiy, ix, iy)

                                E_new = E_node(Cortex(ix, iy).pref_cont, iix, iiy, ix, iy) +
                                E_node(Cortex(iix, iiy).pref_cont, ix, iy, iix, iiy)

                                delta = E_old_1 + E_old_2 - E_new

                                If delta > max_delta Then

                                    max_delta = delta
                                    ix_m = iix
                                    iy_m = iiy

                                End If

                            End If

                        Next
                    Next


                Else


                    For iix = ix - 1 To ix + 1
                        For iiy = iy - 1 To iy + 1

                            If iix >= 0 And iix < X_C And iiy >= 0 And iiy < Y_C And Not (iix = ix And iiy = iy) Then

                                E_old_1 = E_node(Cortex(ix, iy).pref_cont, ix, iy, iix, iiy)
                                E_old_2 = E_node(Cortex(iix, iiy).pref_cont, iix, iiy, ix, iy)

                                E_new = E_node(Cortex(ix, iy).pref_cont, iix, iiy, ix, iy) +
                                        E_node(Cortex(iix, iiy).pref_cont, ix, iy, iix, iiy)

                                delta = E_old_1 + E_old_2 - E_new

                                If delta > max_delta Then

                                    max_delta = delta
                                    ix_m = iix
                                    iy_m = iiy

                                End If

                            End If

                        Next
                    Next



                End If








                If max_delta > 0 Then

                        P = Cortex(ix, iy).pref_cont
                        Cortex(ix, iy).pref_cont = Cortex(ix_m, iy_m).pref_cont
                        Cortex(ix_m, iy_m).pref_cont = P

                        id_c = Cortex(ix, iy).id_cont
                        Cortex(ix, iy).id_cont = Cortex(ix_m, iy_m).id_cont
                        Cortex(ix_m, iy_m).id_cont = id_c


                    End If


                    If j Mod 25 = 0 Then

                        For i = 0 To N_Cont - 1
                            draw_cont(i, PB_cont_Array(i), False)

                        'draw_CLOSE_AREA(X_C / 2, Y_C / 2)



                    Next

                        Label1.Text = j
                        Label1.Update()

                    End If

                End If



        Next




    End Sub

    ' Энергия узла
    Private Function E_node(ByRef P() As Integer, ix_n As Integer, iy_n As Integer, ix_p As Integer, iy_p As Integer) As Double

        E_node = 0
        Dim R As Double

        If P Is Nothing Then Exit Function

        For ix = 0 To X_C - 1
            For iy = 0 To Y_C - 1

                If Cortex(ix, iy).pref_cont IsNot Nothing Then


                    If Not ((ix = ix_n And iy = iy_n) Or (ix = ix_p And iy = iy_p)) Then

                        R = Math.Sqrt((ix_n - ix) ^ 2 + (iy_n - iy) ^ 2)


                        'E_node += Cortex(ix, iy).proximity_pref_EEE(P) * R
                        E_node += CorrArray(id(P), Cortex(ix, iy).id_cont) * R


                    End If

                End If
            Next
        Next


    End Function



    Private Function coord_D(ByVal pos As Integer, N_dim As Integer, ByRef D() As Integer) As Integer()

        Dim c(N_dim - 1) As Integer




        For j = N_dim - 1 To 0 Step -1

            If j > 0 Then

                c(j) = pos Mod D(j)

                pos = Int(pos / D(j))
            Else

                c(0) = pos

            End If

        Next


        coord_D = c

    End Function

    Private Function coord(ByVal pos As Integer, N_dim As Integer) As Integer()

        Dim c(N_dim - 1) As Integer


        For j = N_dim - 1 To 0 Step -1

            c(j) = pos Mod Context_set(j).range
            pos = Int(pos / Context_set(j).range)

        Next


        coord = c

    End Function

    Private Sub PictureBox5_Click(sender As Object, e As MouseEventArgs) Handles PictureBox5.Click

        Dim x As Integer = e.X / PictureBox6.Width * X_C
        Dim y As Integer = e.Y / PictureBox6.Height * Y_C

        draw_CLOSE_AREA(x, y)



    End Sub

    Private Sub draw_CLOSE_AREA(x As Integer, y As Integer)

        Dim pic1 As New Bitmap(X_C, Y_C)

        If Cortex(x, y).pref_cont IsNot Nothing Then



            Dim YY As Integer

            For ix = 0 To X_C - 1
                For iy = 0 To Y_C - 1

                    If x = ix And y = iy Then

                        pic1.SetPixel(ix, iy, Color.Red)

                    Else


                        If Cortex(ix, iy).pref_cont IsNot Nothing Then

                            YY = Cortex(ix, iy).proximity_pref_0(Cortex(x, y).pref_cont) * 100
                            If YY > 255 Then YY = 255
                            pic1.SetPixel(ix, iy, Color.FromArgb(YY, YY, YY))


                        Else

                            pic1.SetPixel(ix, iy, Color.Black)

                        End If

                    End If
                Next
            Next

        End If

        PictureBox5.Image = pic1
        PictureBox5.Update()

    End Sub




    ' Private Function get_random_hash() As ULong


    'Dim k As Integer

    'Do

    '    get_random_hash = 0

    '    Dim L As New List(Of Integer)

    '    For i = 1 To N_1

    '        Do

    '            k = Int(Rnd() * N_H)

    '        Loop Until Not L.Contains(k)

    '        L.Add(k)

    '    Next

    '    For i = 0 To N_1 - 1

    '        get_random_hash += 2 ^ L(i)

    '    Next

    'Loop Until Not all_hashs.Contains(get_random_hash)

    'all_hashs.Add(get_random_hash)

    'End Function

End Class


Public Class mem_item

    Public bin As longbit
    Public str As String
    Public DATA As Integer()
    Public A As Integer

End Class

Public Class column

    Structure mem_N
        Dim Info As Integer()
        Dim N As Single
    End Structure




    Public mem_main As New Dictionary(Of Integer, mem_item)

    'Public mem_second As New Dictionary(Of Integer, mem_N)
    Public pref_cont As Integer()
    Public id_cont As Integer

    Public d1, d2 As Double

    Public mem_A As Single

    Public R(0 To 1) As Single
    ' 0 - Масса притяжения
    ' 1 - Масса отталкивания

    Public R_avg As Single

    Public F As New factor(Form1.N_bit, Form1.N_sec_neuron)

    ' Расчет кода фактора для заданного образа
    Public Sub calc_F(ByRef img As longbit)






    End Sub

    ' Близость
    Public Function proximity(ByRef info As Integer()) As Double

        proximity = 0

        Dim s As Double

        Dim d As Double

        For Each m In mem_main

            Dim n = 0

            s = 1

            For i = 0 To Form1.N_Cont - 1

                Select Case Form1.Context_set(i).Type

                    Case 0

                        If info(i) = m.Value.DATA(i) Then
                            n += 1
                        End If

                    Case 1

                        d = Math.Abs(info(i) - m.Value.DATA(i))

                        If d <= Form1.Context_set(i).dist Then

                            n += 1

                            s = s * (1 - d / Form1.Context_set(i).dist * (1 - Form1.Context_set(i).K_dist))

                        End If

                    Case 2

                        d = Math.Abs(info(i) - m.Value.DATA(i))

                        d = Math.Min(d, Form1.Context_set(i).range - d)

                        If d <= Form1.Context_set(i).dist Then

                            n += 1

                            s = s * (1 - (d / Form1.Context_set(i).dist) * (1 - Form1.Context_set(i).K_dist))

                        End If



                End Select


            Next

            If n > 0 Then
                proximity += s * Form1.W_prox(n)
            Else
                'proximity -= 0.1
            End If


        Next

    End Function


    Public Function proximity_pref_0(ByRef cont As Integer()) As Double

        proximity_pref_0 = 0

        Dim s As Double

        Dim d As Double

        If pref_cont IsNot Nothing Then


            Dim n = 0

            s = 0

            For i = 0 To Form1.N_Cont - 1


                Select Case Form1.Context_set(i).Type

                    Case 0

                        If cont(i) = pref_cont(i) Then
                            n += 1
                            s += 1
                        End If

                    Case 1

                        d = Math.Abs(cont(i) - pref_cont(i))

                        If d <= Form1.Context_set(i).dist Then

                            n += 1

                            s += (1 - d / Form1.Context_set(i).dist * (1 - Form1.Context_set(i).K_dist))

                        End If

                    Case 2

                        d = Math.Abs(cont(i) - pref_cont(i))

                        d = Math.Min(d, Form1.Context_set(i).range - d)

                        If d <= Form1.Context_set(i).dist Then

                            n += 1

                            s += (1 - (d / Form1.Context_set(i).dist) * (1 - Form1.Context_set(i).K_dist))

                        End If



                End Select


            Next

            'If n > 0 Then
            '    proximity_pref += s * Form1.W_prox(n)
            'Else
            '    'proximity_pref -= 0.1
            'End If

            proximity_pref_0 = s

        End If



    End Function

    Public Function proximity_pref_EEE(ByRef cont As Integer()) As Double

        proximity_pref_EEE = 0

        Dim s As Double

        Dim d, r, x, y, z As Double

        s = 0

        If pref_cont IsNot Nothing Then

            d = Math.Abs(cont(0) - pref_cont(0))
            z = Math.Min(d, Form1.Context_set(0).range - d) / Form1.Context_set(0).dist

            x = Math.Abs(cont(1) - pref_cont(1)) / Form1.Context_set(1).dist

            y = Math.Abs(cont(2) - pref_cont(2)) / Form1.Context_set(2).dist


            r = Math.Sqrt(x * x + y * y + z * z)

            If r <= 1 Then

                s = (1 - r)
                proximity_pref_EEE = s

            End If


        End If



    End Function

    Public Function proximity_pref_3_par(ByRef cont As Integer()) As Double

        proximity_pref_3_par = 0

        Dim s As Double

        Dim d, r, x, y, z As Double

        s = 0

        If pref_cont IsNot Nothing Then

            d = Math.Abs(cont(0) - pref_cont(0))
            z = Math.Min(d, Form1.Context_set(0).range - d) / Form1.Context_set(0).dist

            x = Math.Abs(cont(1) - pref_cont(1)) / Form1.Context_set(1).dist

            y = Math.Abs(cont(2) - pref_cont(2)) / Form1.Context_set(2).dist


            r = Math.Sqrt(x * x + y * y + z * z)

            If r <= 1 Then

                s = (1 - r)

            End If


            proximity_pref_3_par = s

        End If



    End Function



    Public Function proximity_pref_3_par_scal(ByRef cont As Integer()) As Double

        proximity_pref_3_par_scal = 0

        Dim s As Double

        Dim d, r, x, y, z As Double

        s = 0

        If pref_cont IsNot Nothing Then

            d = Math.Abs(cont(0) - pref_cont(0))
            z = Math.Min(d, Form1.Context_set(0).range - d) / Form1.Context_set(0).dist

            x = Math.Abs(cont(1) - pref_cont(1)) / Form1.Context_set(1).dist

            y = Math.Abs(cont(2) - pref_cont(2)) / Form1.Context_set(2).dist

            If z <= 1 And x <= 1 And y <= 1 Then

                r = Math.Sqrt(x ^ 2 + y ^ 2 + z ^ 2)

                s = (1 - r)

            End If


            proximity_pref_3_par_scal = s

        End If



    End Function

    Public Function proximity_pref_line_R(ByRef cont As Integer()) As Single

        proximity_pref_line_R = 0

        Dim s As Single

        Dim d As Single

        If pref_cont IsNot Nothing Then


            Dim n = 0

            s = 0

            For i = 0 To Form1.N_Cont - 1


                Select Case Form1.Context_set(i).Type

                    Case 0

                        If cont(i) = pref_cont(i) Then
                            n += 1
                            s += 1
                        End If

                    Case 1

                        d = Math.Abs(cont(i) - pref_cont(i))

                        If d <= Form1.Context_set(i).dist Then

                            n += 1

                            s += 1

                        End If

                    Case 2

                        d = Math.Abs(cont(i) - pref_cont(i))

                        d = Math.Min(d, Form1.Context_set(i).range - d)

                        If d <= Form1.Context_set(i).dist Then

                            n += 1

                            s += 1

                        End If



                End Select


            Next

            'If n > 0 Then
            '    proximity_pref += s * Form1.W_prox(n)
            'Else
            '    'proximity_pref -= 0.1
            'End If

            proximity_pref_line_R = s

        End If



    End Function



    Public Sub set_pref_cont()

        Dim max As Integer = 0
        Dim max_h As Integer

        Dim h As Integer

        Dim s As New Dictionary(Of Integer, Integer)
        Dim s_info As New Dictionary(Of Integer, Integer())

        pref_cont = Nothing

        For Each m In mem_main

            h = Form1.mem_hash(m.Value.DATA)

            If s.ContainsKey(h) Then

                s.Item(h) = s(h) + 1

            Else

                s.Add(h, 1)
                s_info.Add(h, m.Value.DATA)

            End If

        Next

        For Each n In s

            If n.Value > max Then

                max = n.Value

                max_h = n.Key

            End If

        Next

        If max > 0 Then

            pref_cont = s_info(max_h)

        End If

    End Sub

End Class

Public Class Info_item

    Public Img As Integer
    Public DATA As Integer()
    Public ch As Char


End Class

Public Class Info_Sourse

    Dim TXT As String


    Dim Cur_Pos As Integer ' текущая позиция

    Dim Time_Id As Integer ' Кольцевой идентификатор времени (позиции)
    Public N_Time_ID As Integer = Form1.Context_set(0).range  ' Количество позиций во временном кольце



    Public Sub New()

        TXT = IO.File.ReadAllText("text.txt", System.Text.Encoding.GetEncoding(65001))

        Cur_Pos = 0
        Time_Id = 0

    End Sub

    Public Function get_rundom_info() As Info_item

        get_rundom_info = New Info_item

        ReDim get_rundom_info.DATA(Form1.N_Cont - 1)

        For i = 0 To Form1.N_Cont - 1
            get_rundom_info.DATA(i) = Int(Rnd() * Form1.Context_set(i).range)
        Next


    End Function

    Public Function get_next_info() As Info_item

        get_next_info = New Info_item

        Dim ch As Char = TXT(Cur_Pos).ToString.ToLower


        Cur_Pos += 1

        If (ch >= "а" And ch <= "я") Then

            get_next_info.Img = Asc(ch) - Asc("а"c) + 1
            get_next_info.ch = ch

        Else

            get_next_info.Img = 0
            get_next_info.ch = "_"

        End If

        get_next_info.DATA = {Time_Id}

        Time_Id += 1
        If Time_Id = N_Time_ID Then Time_Id = 0

    End Function

End Class

Public Class longbit


    Public V(Form1.N_W - 1) As ULong

    Public Sub reset()

        For i = 0 To Form1.N_W - 1
            V(i) = 0
        Next

    End Sub

    Public Sub OR_(V2 As longbit)

        For i = 0 To Form1.N_W - 1
            V(i) = V(i) Or V2.V(i)
        Next

    End Sub



    Public Sub get_random_hash(N_1 As Integer)


        Dim k, n, m As Integer


        reset()

        Dim L As New List(Of Integer)

        For i = 1 To N_1

            Do

                k = Int(Rnd() * Form1.N_bit)

            Loop Until Not L.Contains(k)

            L.Add(k)

        Next

        For i = 0 To Form1.N_1 - 1

            n = Int(L(i) / 64)

            m = L(i) Mod 64

            V(n) += 2 ^ m

        Next


    End Sub

    Public Function prox_1(ByRef sh2 As longbit) As Integer

        Dim h1, h2 As ULong

        prox_1 = 0

        For j = 0 To Form1.N_W - 1

            h1 = V(j)
            h2 = sh2.V(j)

            For i = 0 To 63

                prox_1 += (h1 Mod 2) And (h2 Mod 2)

                h1 = h1 >> 1
                h2 = h2 >> 1
            Next

        Next

    End Function


End Class

Public Class factor

    ' Результирующее состояние
    Public A As longbit

    ' Битовые маски для каждого из нейронов (деревьев)
    Public W() As longbit

    Public random_forest() As List(Of Integer)

    Public Sub New(N_F As Integer, N_seg_con As Integer)

        ReDim W(N_F - 1)

        For i = 0 To N_F - 1

            W(i) = New longbit

            W(i).get_random_hash(N_seg_con)

        Next

    End Sub


End Class