Skip to content

Instantly share code, notes, and snippets.

@MisterTimur
Last active February 6, 2019 07:24
Show Gist options
  • Save MisterTimur/5ce27c777c4038d5c19a861fcf59954c to your computer and use it in GitHub Desktop.
Save MisterTimur/5ce27c777c4038d5c19a861fcf59954c to your computer and use it in GitHub Desktop.
// ConsoleApplication31.cpp : Этот файл содержит функцию "main". Здесь начинается и заканчивается выполнение программы.
// Абдулов ТИмур 2019
#pragma region ===================== Зависимости .
#include "pch.h"
#include <ctype.h>
#include <stdlib.h>
#include <stdio.h>
#include <conio.h>
#include <time.h>
#include <windows.h> // Это тока в Windows
#pragma warning(disable : 4996) // Это для VS си++
//#define ESC "\033" // Спец символ для вывода в консоль указания координаты в GNU
#pragma endregion
#pragma region ===================== Константы .
const int Max_Str=1024 ;// Максимально доупстимая длина строки
const int Max_Len=32 ;// Реально используемая длина строки
const int Max_Tei=1024*64;// Максимальное Количество нейронов в одном слое
const int Max_Mem=777 ;// Максимальная длина памяти в циклах
#pragma endregion
#pragma region ===================== Типы .
typedef unsigned char uchar ; // 1 байтовый без занка
typedef unsigned short ushort; // 2 байтовый без знака
typedef unsigned int uint ; // 4 байтовый без знака
#pragma endregion
#pragma region ===================== Строки .
// Переводит из кодировки cp1251 cp866
void cp1251_cp866(char *S) {
int i = 0;
if (S != NULL)
for (i = 0; S[i] != 0; i++)
if (((uchar)S[i] >= 192) && ((uchar)S[i] <= 223))
S[i] = S[i] - 64;
else if (((uchar)S[i] >= 224) && ((uchar)S[i] <= 239))
S[i] = S[i] - 64;
else if (((uchar)S[i] >= 240) && ((uchar)S[i] <= 255))
S[i] = S[i] - 16;
else if ((uchar)S[i] == 168)
S[i] = (uchar)240;
else if ((uchar)S[i] == 184)
S[i] = (uchar)241;
}
// Сдвигает строку на 1 символ влево и в конце строки добавлет пробел
void Sle_Str(char*iStr) {
int f;
for (f=0;f<Max_Len;f++) iStr[f]=iStr[f+1];
iStr[Max_Len-1]=' ';
iStr[Max_Len ]= 0 ;
}
// Замена символов форматирования на пробелы
void Del_For(char *S) {
int i = 0;
for (i = 0; S[i] != 0; i++)
if ((uchar)S[i] < 32) S[i] = ' ';
}
// Удаление символа из строки
void Del_Cha(char *iStr,int iPos){
int f;int Len=strlen(iStr);
for (f=iPos;f<=Len;f++)
iStr[f]=iStr[f+1];
}
// Удаление повторяющихся пробелов
void Del_Spa(char *iStr) {
int i = 1;
while (iStr[i] != 0)
if ((iStr[i]==' ')&& // Если это пробел
(iStr[i-1]==iStr[i])) Del_Cha(iStr,i);else i++;
}
// Устанавливаем длину строки
void Set_Len(char*iStr,int iLen){
// Установить длину строки iStrравной iLen
// Если строка меньше iLen добаить пробелы
// Если больше то обрезать
int f;
for (f=strlen(iStr);f<iLen;f++) iStr[f]='+';
iStr[iLen]=0;
}
// Устанавливает курсов в консоли
void Set_Pos(int x,int y) {
// установка крусора в консоли в заданых координатах
COORD position = {y,x}; //позиция x и y
HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
SetConsoleCursorPosition(hConsole, position);
}
// Читает строку из файла
char* Get_Str_Fro_Fil(const char* iNam,int iPos,int iLen) {
// НЕ забываем освободить выделеную строку
// Выбирает из файла iNam строку с заданой позиции iPos
// Длиной iLen
char* res=(char*)malloc(iLen+1); // Результирующая строка
FILE*f; // Структура описывающая файл
if ((f = fopen(iNam,"rb")) != NULL){ // Открытие и Проверка на
int len=0;// Размер файла в байтах
int RBy=0;// количество реально прочитаных байт
fseek(f, 0, SEEK_END);// перемещаемся в конец файла
len = ftell(f);// ПОлучаем размер файла в байтах
iPos=iPos%len;
fseek(f, iPos, SEEK_SET);// Перемещаемся в iPos файл
if (len>0)
while (RBy<iLen)
if (fread(&res[RBy], 1, 1, f)==0)
fseek(f, 0, SEEK_SET); //если конец файла то В начало файла
else RBy++;// ИНче увеличиваем количество прочитаных символов
fclose(f); // закрываем файл
res[iLen-1]=0;// Ставим признак кончания строки
}
return res;
}
// Генерация случаного числа
int Rand(int iMax){
int res = rand()%iMax;
return res;
}
// Создает строку для рецептора
char* Cre_Str(){
char*res=(char*)malloc(Max_Str);
int f=0;
for (f=0;f<Max_Len;f++) res[f]=' ';
res[f]=0;
return res;
}
#pragma endregion
#pragma region ===================== TNeiron .
typedef struct TNeiron { /* Структура описвающая нейрон */
double Koof ; // Коофицент Ошибок
int KolG ; // Время жизни нейрона для вычисления коофицента ошибок
int KolP ; // Количество Простоя не срабатывает когда
int KolT ; // Количество Верных предположений
int KolE ; // Количество ошибок
int KolW ; // Количество Сколько нейрон Реально использовался сработал
int SO ;// Текущие состояние Тейрона выходной результат
int SI ;// Текущие состояние Тейрона входной результат
int SB ;// Состояие выхода нейрон B
int SA ;// Состояие входа Нейрон A
bool CH ;// Для обхода деревьев
bool EX ;// Выходнйой нейрон не мож быть источником сигнала
struct TNeiron*NA;// ссылка на нейрон A
struct TNeiron*NB;// ссылка на нейрон B
struct TNeiron*NC;// Управляющий нейрон
} TNeiron ;
void Sign(struct TNeiron*iTei) {
// Если нейрон оказался не прав
if ((iTei->NA->SO==iTei->SA)&&
(iTei->NB->SO!=iTei->SB))iTei->SO=0;
// Если нейрон в работе и казался прав
if ((iTei->NA->SO==iTei->SA)&&
(iTei->NB->SO==iTei->SB))iTei->SO=1;
// Если нейрон в простое не делает предположения
if (iTei->NA->SO!=iTei->SA) iTei->SO=2;
}
void Lear(struct TNeiron*iTei) { // Обучение нейрона
if (iTei->SO==0) iTei->KolE++;// Сколько раз нейрон был не прав
if (iTei->SO==1) iTei->KolT++;// Сколько раз нейрон был прав
if (iTei->SO==2) iTei->KolP++;// Сколько раз нейрон был в простое не работал
// Считаем Время жизни нейрона
iTei->KolG=iTei->KolG+1;
// Подсчитываем коофицент ошибок
if (iTei->KolE+iTei->KolT==0) iTei->Koof=0 ; else
iTei->Koof=((double)1/((double)iTei->KolE+(double)iTei->KolT))*(double)iTei->KolE;
}
void Work(struct TNeiron*iTei) { // Работа нейрона
iTei->NC=NULL;
if (iTei->NA->SO==iTei->SA)
if ((iTei->NB->NC==NULL)||(iTei->NB->NC->Koof>iTei->Koof)) {
iTei->NB->SI=iTei->SB;// Записываем свое предположение
iTei->NB->NC=iTei ;// Указываем кто сделал такое предположение
}
}
void Save(struct TNeiron*iTei){
iTei->CH=true;// отмечаем что тут уже прошли
iTei->KolW=iTei->KolW+1;// Считаем сколько раз нейрон сработал
if ((iTei->NA!=NULL)&&(iTei->NA->CH==false)) Save(iTei->NA);
if ((iTei->NB!=NULL)&&(iTei->NB->CH==false)) Save(iTei->NB);
}
void Clea(struct TNeiron*iTei) {
iTei->Koof=0 ; // Коофицент ошибок
iTei->KolG=0 ; // Время жизни
iTei->KolP=0 ; // Количество ПРостоев
iTei->KolT=0 ; // Количество Сколкьо раз был прав
iTei->KolE=0 ; // Количество Ошибок
iTei->KolW=0 ; // Количество использований
iTei->SA=' ' ;// Текущие состояние Тейрона выходной результат
iTei->SB=' ' ;// Текущие состояние Тейрона входной результат
iTei->SO=' ' ;// Состояие выхода
iTei->SI=' ' ;// Состояие входа
iTei->CH=false;// ДЛя обхода деревьев нейрона что бы 2 раза не обходить
iTei->EX=false;//Выходнйо нейрон не можетб ыть источником сигнала
iTei->NA=NULL;// НЕйрон источник сигнала
iTei->NB=NULL;// Нейрон Управляемый тут выдвигаем предположение
iTei->NC=NULL;// Управляющий нейрон
}
#pragma endregion
#pragma region ===================== TIAM .
typedef struct TIAM { // Информационо аналитическая матрица
struct TNeiron*Teirons[Max_Tei];
} TIAM ;
TIAM*IAM ; // Слой неросети
char*Rez ; // Результат работы нейросети
char*Rec ; // Строка рецептор входные данные для нейросети
char*Mus ; // Строка мускул результат работы нейро сети
int G_Pos; // Шлобальная позиция в читаемом файле
int S_New; // Количество созданых нейронов за 1 цикл
int S_Tim; // Счетчик циклов
int S_Kof; // Коофицент ошибок за 1 интервал времени
void Iam_Cre(TIAM*iSlo){
// Создаю все нейроны в масиве
int f ;
for (f=0;f<Max_Tei;f++) {
iSlo->Teirons[f]=(TNeiron*)malloc(sizeof(TNeiron));
Clea(iSlo->Teirons[f]);}
}
void Iam_Rec(TIAM*iSlo,char*iStr){ // Читает входящие данные в нейросеть
// Рецептор для ходящих данных
int f ;
for (f=0;f<Max_Len;f++) {
// Записываем коды символов из строки в нейроны
iSlo->Teirons[f]->SO=iStr[f];
iSlo->Teirons[f]->NC=NULL ;
iSlo->Teirons[f]->SI=' ' ;
iSlo->Teirons[f]->EX=false ;
}
}
void Iam_Mus(TIAM*iSlo,char*iStr){ // Выводит данные из нейросети
int f;
for (f=0;f<Max_Len;f++){
// Записываем коды символов из нейросети в строку
iStr[f]=iSlo->Teirons[f]->SI;
}
}
void Iam_Gen(TIAM*iSlo,int iNom,TNeiron*iTei){ // ПереГененрация новго нейрона
// Увеличиваю счетчик созданых нейронов
S_New=S_New+1;
// ОТключаем от нейронов к котрым были соеденены
iTei->NA=NULL;
iTei->NB=NULL;
iTei->NC=NULL;
// ПОдключаем новые связи
// Сключаем подключение к одному и тому же нейрону
Clea(iTei);
while (
(iTei->NA==iSlo->Teirons[Max_Len-1])|| // ОТвет не может быть источником сигнала
(iTei->NA==iTei->NB)|| // Если и вход и выход один и тот же нейрон
(iTei->NB->EX)
) // Если Нейрон Б Выходнйо то перегенерируем
{
// Крепим 2 ноги нейрона к нижлещим нейронам
// До iNom граница нижлежащия
iTei->NA=iSlo->Teirons[Rand(iNom/16)];
if (Rand(3)==1) iTei->NB=iSlo->Teirons[Max_Len-1];
else iTei->NB=iSlo->Teirons[Rand(iNom/16)];
}
if (iTei->NB==iSlo->Teirons[Max_Len-1]) iTei->EX=true;
else iTei->EX=false;
// Запоминмаем состояние на момент создания нейрона
// Запоминаю правило работы нейрона это его предположение
iTei->SO=1;
iTei->SA=iTei->NA->SO;// Запоминаем состояние нейрона A
iTei->SB=iTei->NB->SO;// Запоминаем состояние нейрона B
}
void Iam_Reg(TIAM*iSlo){ // Регенерация Заменяет не используемые нейроны новыми
int f;S_New=0;// Сбрасываю счтчик созданых нейронов
for (f=Max_Len;f<Max_Tei;f++){
// Перегененрация удалённых нейронов
if (iSlo->Teirons[f]->KolG==0) Iam_Gen(iSlo,f,iSlo->Teirons[f]);
if (iSlo->Teirons[f]->KolG>Max_Mem+Rand(Max_Mem))
if (iSlo->Teirons[f]->KolW<1)
Iam_Gen(iSlo,f,iSlo->Teirons[f]);
Sign(iSlo->Teirons[f]);// Проводка сигналов
}
}
void Iam_Sig(TIAM*iSlo) { // проводит сигналы
int f;
for (f=Max_Len;f<Max_Tei;f++)
Sign(iSlo->Teirons[f]);
}
void Iam_Lea(TIAM*iSlo) { // Обучать нейроны в слое
int f;
for (f=Max_Len;f<Max_Tei;f++)
Lear(iSlo->Teirons[f]);
}
void Iam_Wor(TIAM*iSlo) { // Работать нейроны в слое
int f;
for (f=Max_Len;f<Max_Tei;f++)
Work(iSlo->Teirons[f]);
}
void Ima_Sav(TIAM*iSlo) { // Сохарняет структуру
int f;// ОТмечаем нейроны что мы по ним не проходили
for(f=Max_Len;f<Max_Tei;f++) IAM->Teirons[f]->CH=false;
// ОТмечаем сработавшие нейроны ка крсаботавгие
if (iSlo->Teirons[Max_Len-1]->SO==
iSlo->Teirons[Max_Len-1]->SI)
if (iSlo->Teirons[Max_Len-1]->NC)
Save(iSlo->Teirons[Max_Len-1]->NC);
}
void Nex_Cha() { // Сдвиг строки
char*LAst_Rec=strdup(Rec);
do { // Пропускаем пробелы
G_Pos=G_Pos+1;
free(Rec);
Rec=Get_Str_Fro_Fil("test.txt",G_Pos,Max_Str);
cp1251_cp866(Rec);// Переводим в кодировку консоли
Del_For(Rec);// Удаляем спец символы
Del_Spa(Rec);// Удаляем пробелы
Set_Len(Rec,Max_Len);// Устанавливаем длину строки
} while (strcmp(LAst_Rec,Rec)==0);
free(LAst_Rec);
}
#pragma endregion
int main()
{
//-----------------------------------------------------------------
int lS_Kof=0;// ЛОкальный счетчик ошибок
//-----------------------------------------------------------------
IAM=(TIAM*)malloc(sizeof(TIAM));// Сздаем Масив с нейронами
for(int f=0;f<Max_Tei;f++)IAM->Teirons[f]=NULL;
Rec=Cre_Str();// Создаем строку рецептор
Mus=Cre_Str();// Создаем строку мускул
Rez=Cre_Str();// Создаем строку резальутат работы нейросети
G_Pos=0 ;// Устанавлвиаем указатель на начало текстового файла
S_Tim=0 ;// Глобальный счетчик циклов
S_Kof=Max_Mem;// Количество ошибок за интервал времни
//-----------------------------------------------------------------
Iam_Cre(IAM) ;// Создаем болванки нейронов
int f=0;bool Re_Gen=true;
while (true) {
//--------------------------------------------------------------
Iam_Rec(IAM,Rec);// Чтение данных в нейросеть
if (Re_Gen) Iam_Reg(IAM) ;// Удаление стрых нейронов и создание новых
else Iam_Sig(IAM) ;
Iam_Lea(IAM) ;// Обучение нейросети
//--------------------------------------------------------------
Nex_Cha();// сдвигаем бегущию строку на 1 символ след состояние
//--------------------------------------------------------------
Iam_Rec(IAM,Rec);// Чтение данных в нейросеть
Iam_Sig(IAM) ;// проводим сигналы
Iam_Wor(IAM) ;// Работа нейросети
Iam_Mus(IAM,Mus);// Вывод данных из нейросети
Ima_Sav(IAM) ;// Сохраняет сработавшие нейроны
//--------------------------------------------------------------
// Сдесь считаем ошибки
Re_Gen=false;
if (IAM->Teirons[Max_Len-1]->SO!=
IAM->Teirons[Max_Len-1]->SI ) {lS_Kof=lS_Kof+1;Re_Gen=true;}
if ((S_Tim%Max_Mem)==0){S_Kof=lS_Kof;lS_Kof=0;}
S_Tim=S_Tim+1 ;// Счетчик циклов
//--------------------------------------------------------------
//if ((S_Tim%500)==1){
Set_Pos(10,10);printf ("%s",Rez );// Результат работы нейросети
Set_Pos(11,10);printf ("%s",Rec );// Текущие состояние
Set_Pos(12,10);printf ("%s",Mus );// Будущие состояние состояние
Set_Pos(13,10);
printf (" G_Pos=%d ",G_Pos);// Текущие положение в тексте
printf (" New=%d ",S_New);// Количество созданых
printf (" Kof=%d ",S_Kof);// Коофицент ошибок
//}
//--------------------------------------------------------------
Rez[Max_Len-1]=Mus[Max_Len-1];// Заменю проб на рез раб нейросети
Sle_Str(Rez);// Сдвигаю бегущию строку влево справа доабвляеться пробел
//--------------------------------------------------------------
Sleep(100);
}
}
Copy link

ghost commented Feb 4, 2019

This is more sophisticated code for not noobs, but for not lamers, it's MUST have code!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment