Metadata-Version: 2.1
Name: mlo-optimizer
Version: 0.3.0
Summary: 
License: Apache-2.0
Keywords: matrix,optimization,genetic,keyboard
Author: Jaskier
Author-email: borody.maxim@gmail.com
Requires-Python: >=3.9,<3.12
Classifier: License :: OSI Approved :: Apache Software License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Requires-Dist: deap (>=1.3.3,<2.0.0)
Requires-Dist: nltk (>=3.8.1,<4.0.0)
Requires-Dist: numpy (>=1.24.2,<2.0.0)
Requires-Dist: pandas (>=2.0.0,<3.0.0)
Requires-Dist: tqdm (>=4.65.0,<5.0.0)
Description-Content-Type: text/markdown

# Matrix Optimization of Object Locations

## Описание

Библиотека mlo-optimizer содержит класс-оптимизатор для решения разного рода задач на подбор оптимального расположения 
объектов в матрицах

Примеры таких задач:
 - подбор оптимальной раскладки клавиатуры
 - задача составления расписания
 - поиск оптимальных маршрутов в графах

## Преимущества

Для решения задачи достаточно только реализовать целевую функцию, получающую на вход индивида и возвращающую оценку 
приспособленности для данного индивида

В оптимизаторе реализован генетический алгоритм со всеми необходимыми компонентами:
- создание случайного индивида
- скрещивание (упорядоченное скрещивание)
- мутация (мутация перестановкой)
- отбор (турнирный)
- элитизм

Индивиды могут иметь любую размерность (вектор, матрица, 3-х мерные тензоры и т.д)

Для решения задач элементы можно разделать на 2 множества:
 1. Множество учитываемых элементов (учитываются в целевой функции)
 2. Множество переставляемых элементов (меняют матричные положения в скрещивании и мутации)

Для задач подбора оптимальных раскладок реализован пайплайн, решающий данную задачу (см. раздел 'Подбор оптимальной 
раскладки')

## Установка

```
pip install mlo-optimizer
```

## Использование

Все действия происходят из класса Optimizer
```
from mlo_optimizer.optimizer import Optimizer
```

Создаем экземпляр класса с некоторыми обязательными значениями
```
optimizer = Optimizer(
    init_matrix,
    counted_elems,
    permutable_elems,
    fitness_func,
)
```

init_matrix - начальная матрица с любыми элементами, например:
```
[
    ['inv', 'lang', None, None, None, None, '?123'],
    ['settings', None, None, None, None, None, 'backspace'],
    ['inv', None, None, None, None, None, None],
    [None, None, None, 'space', None, None, 'enter'],
    ['inv', None, None, None, None, None, None],
    ['move', None, None, None, None, None, 'capslock'],
    ['inv', 'exit', None, None, None, None, 'shift'],
]
```

Места None займут элементы из permutable_elems

counted_elems - учитываемые элементы, например:
```
['a', 'b', 'c', 'd', 'e', 'f', 'space', 'enter']
```

permutable_elems - переставляемые элементы, например:
```
['a', 'b', 'c', 'd', 'e', 'f']
```

fitness_func - целевая функция, получающая на вход матрицу-индивида и возвращающую **кортеж** из оценок 
приспособленности, например:
```
def test_fitness_func(individual):
    if individual[0][0] == 'a':
        return (2.5,)
    return (-2.5,)
```
Также можно прописать именованные аргументы в fitness_func_kwargs

В конце выполняем оптимизацию
```
best_matrix = optimizer.optimize()
```

## Подбор оптимальной раскладки

Для задач из этой области можно использовать отдельный пайплайн, который состоит из нескольких шагов:
1. Создание оптимизатора
2. Вычисление весов биграмм
3. Запуск оптимизатора

Первым делом создаем оптимизатор
```
optimizer = Optimizer(
        INIT_HEX_KEYBOARD,
        EN_COUNTED_ELEMS,
        EN_PERMUTABLE_ELEMS,
        fitness_func='square',
)
```
Для этой задачи возможно получить решения для клавиатур с квадратными клавишами (fitness_func='square') и с
гексагональными (fitness_func='hex')

Также можно указать размеры клавиш с помощью следующих параметров:
- a_s (по-умолчанию 0.5): половина стороны квадратной клавиши
- a_h (по-умолчанию 0.537634): расстояние от середины гексагональной клавиши до середины ее стороны
- b_h (по-умолчанию 0.930605): расстояния от середины гексагональной клавиши до середины стороны нижестоящей клавиши

Далее запускаем fit_bigrams с указанием пути до папки с файлами формата .txt. Это необходимо для оценки важности 
близкого расположения одних пар клавиш по отношению к другим
```
lang_base_part = '../data/en/'

optimizer.fit_bigrams(lang_base_part)
```

И оптимизируем
```
best_matrix = optimizer.optimize()
```

## Параметры

При создании экземпляра класса Optimizer можно прописать следующие параметры:
- minimization (по-умолчанию True): минимизация или максимизация оценки приспособленности
- population_size (по-умолчанию 50): размер популяции в одном поколении
- max_generation (по умолчанию 50): максимальное количество поколений
- p_crossover (по-умолчанию 0.9): вероятность скрещивания
- p_mutation (по-умолчанию 0.2): вероятность мутации
- tourn_size (по-умолчанию 3): размер выборки для турнирного отбора
- hall_of_fame_size (по-умолчанию 1): количество лучших индивидов, полученных после завершения оптимизации

## Лицензия

Прям тут: [LICENSE](LICENSE)

