Библиотека Generic классов - ошибки, описание, вопросы, особенности использования и предложения - страница 8

 

Вот код вместе с полем ввода. (Может кому то пригодится. Можно дорабатывать).

//+------------------------------------------------------------------+
//|                                                   Dictionary.mq5 |
//|                                                      Peter Konow |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Peter Konow"
#property link      ""
#property version   "1.00"
#property strict
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
#define Max_possible_collisions    100
#define Max_letters_in_word        100
#define All_letters_in_alphabet    255 
//------------------------------------
string Dictionary[Max_possible_collisions][All_letters_in_alphabet][Max_letters_in_word];
//-------------------------------------------------------------------
int OnInit()
  {
//---
   Create_text_box();
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
   ObjectDelete(0,"Text_box");
  }
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
//| ChartEvent function                                              |
//+------------------------------------------------------------------+
void OnChartEvent(const int id,
                  const long &lparam,
                  const double &dparam,
                  const string &sparam)
  {
    if(id == CHARTEVENT_OBJECT_ENDEDIT)
      { 
       //-----------------------
       string Text;     
       //---------------------
       ObjectGetString(0,"Text_box",OBJPROP_TEXT,0,Text);
       //-------------------------------------
       Add(Text);
      } 
  }
//+------------------------------------------------------------------+

void Add(string word)
{
 uchar First_letter = (uchar)StringGetCharacter(word,0) - 97;
 //-----------------------
 int All_letters_in_word = StringLen(word);
 //-----------------------
 for(int a1 = 0; a1 < Max_possible_collisions; a1++)
   {
     string word_inside = Dictionary[a1][First_letter][All_letters_in_word];
     //-----------------------   
    if(word_inside == NULL)
      {
       Dictionary[a1][First_letter][All_letters_in_word] = word;
       Print("Your word has been added to our dictionary!");
       break;
      }
    if(word_inside == word)
      {
       Print("This word already exists in our dictionary");
       break;
      } 
   }   
 //------------------------   
}
//--------------------------------------------------------------------+


//--------------------------------------------------------------------
void Create_text_box()
{
  ObjectCreate(0,"Text_box",OBJ_EDIT,0,0,0);
  ObjectSetInteger(0,"Text_box",OBJPROP_XDISTANCE,500);
  ObjectSetInteger(0,"Text_box",OBJPROP_YDISTANCE,250);
  ObjectSetInteger(0,"Text_box",OBJPROP_XSIZE,400);
  ObjectSetInteger(0,"Text_box",OBJPROP_YSIZE,30);
  ObjectSetString(0,"Text_box",OBJPROP_TEXT,"Please enter your word here...");
  ObjectSetString(0,"Text_box",OBJPROP_FONT,"TimesNewRoman");
  ObjectSetInteger(0,"Text_box",OBJPROP_STATE,1);
  //----------------------------------------------
  ObjectSetInteger(0,"Text_box",OBJPROP_FONTSIZE,12);
  ObjectSetInteger(0,"Text_box",OBJPROP_BGCOLOR,clrWhite);
  ObjectSetInteger(0,"Text_box",OBJPROP_COLOR,clrBlack);
  ObjectSetInteger(0,"Text_box",OBJPROP_BORDER_COLOR,clrBlack);
  ObjectSetInteger(0,"Text_box",OBJPROP_ALIGN,ALIGN_CENTER);
  //----------------------------------------------
  ObjectSetInteger(0,"Text_box",OBJPROP_CORNER,CORNER_LEFT_UPPER);
  ObjectSetInteger(0,"Text_box",OBJPROP_ANCHOR,ANCHOR_LEFT_UPPER);  
  //---------------------------------------------- 
}
//----------------------------------------------------------------------- 

Только почему то полноценно работает на четверке. На пятерке поле не возникает. Причину искал и так и не нашел.

 
fxsaber:

Т.е. нужно для каждой задачи нащупать золотую середину между размером словаря (RAM) и вычислительной сложностью хеш-функции (CPU).


Относительно да.
При небольших значениях элементов оптимальным будет словарь размером количество элементов в квадрате (это на сколько помню из курса 3-х годичной давности, но лучше всегда перепроверять).
Когда из-за большого количества элементов невозможно выбрать оптимальный размер, то берут размер словаря в несколько раз больше количества ожидаемых элементов и оптимизируют разруливание коллизий, например, через внутренние хеш-таблицы для каждой из коллизий.

Хеш стараются подобрать так, что бы искался как можно быстрее, но обеспечивал равномерность распределения полученных результатов по размеру словаря.
С равномерностью распределения связано использование простых чисел в хешах.

 
Реter Konow:
Пришлось увеличить размер массива, так как заглавные буквы имеют другой код и "выпадают" из массива.

Код символа "А" отличается от кода символа "а" ровно на 32. Соответственно все остальные так-же имеют разницу 32.

Может быть и не надо было увеличивать размер массива, а просто заменить первый символ.
 
Alexey Viktorov:

Код символа "А" отличается от кода символа "а" ровно на 32. Соответственно все остальные так-же имеют разницу 32.

Может быть и не надо было увеличивать размер массива, а просто заменить первый символ.

Согласен. В этом алгоритм недоработан.

Размер массива слишком большой. Вчера недоконца разобрался с кодами букв.

 
Реter Konow:

Вот код вместе с полем ввода. (Может кому то пригодится. Можно дорабатывать).

Только почему то полноценно работает на четверке. На пятерке поле не возникает. Причину искал и так и не нашел.

И ещё одно замечание: В примере Василия есть упоминание о массиве

Форум по трейдингу, автоматическим торговым системам и тестированию торговых стратегий

Библиотека Generic классов - ошибки, описание, вопросы, особенности использования и предложения

Vasiliy Sokolov, 2017.12.07 14:30

Максимально просто об ассоциативном массиве #1

Очень многие алгоритмы, которые представлены в Generic так или иначе базируются на ассоциативном массиве или словаре. К тому же это один из двух наиболее часто используемых алгоритмов. Думаю буду близок к истине, если скажу что 90% всех задач в программировании покрывается массивами и словарями. Прежде чем перейти к практике, опишем работу словаря максимально просто и доходчиво, намерено упрощая некоторые детали.

Разберем словарь мы на очень простом примере: обычном словаре слов. Предположим, что у нас есть всего несколько таких слов, и все они начинаются на разные буквы алфавита:

string words[] = {"apple", "cat", "fog", "dog", "walk", "zero"};

Английский алфавит содержит 26 символов. Создадим массив строк, размерностью 26 элементов:

string dictionary[26];

Теперь, если договориться хранить слова в индексах соответствующим их первой букве мы получим простейший словарь. Индексацию будем делать с нуля. Слово "apple" будет храниться у нас по индексу 0, потому что символ 'a' - первая буква алфавита, "cat" - по индексу 1, "dog" - по индексу 3, fog - будет занимать индекс  4, walk - индекс 24 и zero - последний 25 индекс. 

Замечу что индексы с 5 по 23 не будут использованы. Это дополнительный расход памяти, зато мы можем мгновенно обратиться например к слову "walk", потому что знаем, что если оно есть, то находится по индексу 24.

Напишем первый наш пустой словарь:



А в вашем примере

#define Max_possible_collisions    100
#define Max_letters_in_word        100
#define All_letters_in_alphabet    255 
//------------------------------------
string Dictionary[Max_possible_collisions][All_letters_in_alphabet][Max_letters_in_word];

3х мерный массив сколько памяти занимает? А если ещё придётся увеличить размерность?

 
Alexey Viktorov:

И ещё одно замечание: В примере Василия есть упоминание о массиве


А в вашем примере

3х мерный массив сколько памяти занимает? А если ещё придётся увеличить размерность?

Размер массива слишком большой потому что:

1. Я решил, что максимальное количество букв в слове может быть 100. Явно перебор. Можно снизить до 30.

2. Количество возможных букв тоже получилось чрезмерным. Я решил взять место для максимально большого количества разных символов. Можно уменьшить.

3. Количество "коллизий", то есть совпадений слов по первой букве и по количеству букв в слове, задано 100. Тоже многовато. Можно до 50 снизить.


Размерность не вижу смысла еще увеличивать. Можно просто сделать еще словарь.

 
Реter Konow:

Размер массива слишком большой потому что:

1. Я решил, что максимальное количество букв в слове может быть 100. Явно перебор. Можно снизить до 30.

2. Количество возможных букв тоже получилось чрезмерным. Я решил взять место для максимально большого количества разных символов. Можно уменьшить.

3. Количество "коллизий", то есть совпадений слов по первой букве и по количеству букв в слове задано 100. Тоже многовато. Можно до 50 снизить.


Размерность не вижу смысла еще увеличивать. Можно просто сделать еще словарь.

Вопрос не в словаре. Словарь просто как пример построения алгоритма. И элементов может быть далеко не 100 как в вашем примере, а 1е10 и более... В таком случае какой размер массива будет???

К примеру, соберите в массив всю доступную историю тиков. В одну миллисекунду может быть не один тик, соответственно массив не может быть одномерным... а сколько максимально было тиков в одну миллисекунду??? Два или пять??? Какая размерность массива должна быть в этом случае??? Сколько памяти будет потрачено впустую?

 
Alexey Viktorov:

К примеру, соберите в массив всю доступную историю тиков.

После всего написанного подумалось, что нет практической задачи хранить тики обсуждаемым в ветке способом. Отсортированы они по времени и лежат в простом массиве.

Точно так же с History Orders/Deals. Храняться, судя по HistorySelect, они так же по времени в массиве. И чую, нет там (в текущей реализации) ничего из обсуждаемого, чтобы искать запись по тикету или ID.

А все потому, что нецелесообразно в случае с названной историей что-то городить. Простого массива для практики вполне хватает.

Поэтому интересны формулировки задач практического плана в области трейдинга.


ЗЫ Когда делали на порядок ускорение HistorySelect, то, уверен, решали вопрос через кеширование, не словари с хешами.

 
fxsaber:

После всего написанного подумалось, что нет практической задачи хранить тики обсуждаемым в ветке способом. Отсортированы они по времени и лежат в простом массиве.

Точно так же с History Orders/Deals. Храняться, судя по HistorySelect, они так же по времени в массиве. И чую, нет там (в текущей реализации) ничего из обсуждаемого, чтобы искать запись по тикету или ID.

А все потому, что нецелесообразно в случае с названной историей что-то городить. Простого массива для практики вполне хватает.

Поэтому интересны формулировки задач практического плана в области трейдинга.


ЗЫ Когда делали на порядок ускорение HistorySelect, то, уверен, решали вопрос через кеширование, не словари с хешами.

Не спорю, но если кому-то захочется реализовать какую-то задачу именно так, то и флаг ему в руки...

Кто-то считает что нет смысла, кому-то это не по силам освоить... И в том и другом случае есть более простые реализации. Но кто знает как будет развиваться трейдинг "завтра"... Наверное пусть лучше будет и останется невостребованным, чем необходим при отсутствии.

 
Alexey Viktorov:

Вопрос не в словаре. Словарь просто как пример построения алгоритма. И элементов может быть далеко не 100 как в вашем примере, а 1е10 и более... В таком случае какой размер массива будет???

К примеру, соберите в массив всю доступную историю тиков. В одну миллисекунду может быть не один тик, соответственно массив не может быть одномерным... а сколько максимально было тиков в одну миллисекунду??? Два или пять??? Какая размерность массива должна быть в этом случае??? Сколько памяти будет потрачено впустую?

Я решал задачу построения удобного словаря.

Тики или другие элементы имеют свои специфические свойства, которые можно удачно индексировать для быстрого доступа к месту хранения.

Суть задачи быстрого доступа к данным, заключается в выявлении нескольких классифицируемых свойств элемента и их индексации.

Берется элемент, находятся удобные свойства от которых можно получить индексы, и через индексы получается доступ к месту хранения.

Если индексов нехватает (например у слова можно индексировать первую букву и количество букв, но остальные свойства не дают удобного индекса), делаем прямой перебор элементов внутри окружающей его области.

Принцип универсальный, реализации могут варьироваться.

Причина обращения: