---
# System prepended metadata

title: ЗАДАЧА СОПОСТАВЛЕНИЯ АВТОМОБИЛЕЙ И ЛЮДЕЙ ПО ДАННЫМ ВИДЕОНАБЛЮДЕНИЯ
tags: [Old, R&D]

---

 # ЗАДАЧА СОПОСТАВЛЕНИЯ АВТОМОБИЛЕЙ И ЛЮДЕЙ ПО ДАННЫМ ВИДЕОНАБЛЮДЕНИЯ
_Комментарий к исходным данным задачи и построению алгоритма (метода) решения_  
 
 [TOC]
 
 ## Основные источники информации  
 Основным источником информации, по которой строятся и данные профайлов машин и персон  и должна строится таблица соответствия между машинами и персонами, являются события, регистрируемые в пунктах наблюдения и предварительно распознаваемые  с использованием обученных нейросетей.  Эта информация в виде последовательности событий записывается в Mongo.db, сейчас имеющей название okko. Эта последовательность за определенный интервал времени сбрасывается  в виде файлов okko_export_records.bson   
  Вот фрагменты из этого потока (разделенные нами на два отдельных потока - событий для машин и событий для персон):
### а) Пример данных событий машин
```python
{car:
   { car_id: '70ef2d80-57cb-412d-a6b0-d14f23a0827d',
     registrationId: 'AB0164BT',
     mark: 'ISUZU  NLR 85AL',
     model: 'NLR 85AL',
     color: 'БІЛИЙ',
     fuel: 'ДИЗЕЛЬНЕ ПАЛИВО',
     url_foto:      '/okko/vehicle/recognize/2021/03/09/11/27-15.150989-9b15c4cd-3044-4d3a-9ce4-a8b1b042e73d.jpg' },
  event_id: '9b15c4cd-3044-4d3a-9ce4-a8b1b042e73d',
  place_code: '33f0b671-a756-411b-be5a-7036ffd17c61',
  event_type_code: 'Enter',
  event_begin: '2021-03-09T11:27:17.896Z',
  event_end: '2021-03-09T11:27:17.896Z',
  url_foto:   '/okko/vehicle/recognize/2021/03/09/11/27-15.150989-9b15c4cd-3044-4d3a-9ce4-a8b1b042e73d.jpg' }
,
{ car:
   { car_id: '9e60436c-caef-44b8-98c0-da0cb4928fa8',
     registrationId: '0342',
     mark: '',
     model: '',
     color: '',
     fuel: '',
     url_foto:      '/okko/vehicle/recognize/2021/03/09/11/27-27.781143-fa723ea6-9849-41ea-9919-22a92497fbef.jpg' },
  event_id: 'fa723ea6-9849-41ea-9919-22a92497fbef',
  place_code: 'bb523908-f718-45c8-8aa7-bc2d2946b213',
  event_type_code: 'Exit',
  event_begin: '2021-03-09T11:27:34.527Z',
  event_end: '2021-03-09T11:27:34.527Z',
  url_foto:   '/okko/vehicle/recognize/2021/03/09/11/27-27.781143-fa723ea6-9849-41ea-9919-22a92497fbef.jpg' }, …….
```


### б) Пример данных событий персон
```elm
{ customer_event:
   { customer:
      { customer_id: 'c7ba561e-6e74-4e19-b85c-c9d5e6032081',
        gender: 'Male',
        age: 'Child',
        url_foto: '/okko/faces/recognize/2021/03/09/11/25-38.750000-c406a59b-5ded-4454-a30b-50c7723d5572.jpg' },
     event_id: 'c406a59b-5ded-4454-a30b-50c7723d5572',
     place_code: '2dad4312-ac7d-41f7-83c8-2e537ceb5548',
     event_type_code: 'faceEnter',
     event_begin: '2021-03-09T11:25:37.250Z',
     event_end: '2021-03-09T11:25:38.951Z',
     url_foto: '/okko/faces/recognize/2021/03/09/11/25-38.750000-c406a59b-5ded-4454-a30b-50c7723d5572.jpg' } }
,
{ customer_event:
   { customer:
      { customer_id: '887fecea-a384-44d8-9932-47828eeb95c5',
        gender: 'Male',
        age: 'Adult',
        url_foto:         '/okko/faces/recognize/2021/03/09/11/26-04.250000-019bc324-b39d-423c-9cb9-8fdc724c7262.jpg' },
     event_id: '019bc324-b39d-423c-9cb9-8fdc724c7262',
     place_code: '2dad4312-ac7d-41f7-83c8-2e537ceb5548',
     event_type_code: 'faceEnter',
     event_begin: '2021-03-09T11:26:03.249Z',
     event_end: '2021-03-09T11:26:04.818Z',
     url_foto:      '/okko/faces/recognize/2021/03/09/11/26-04.250000-019bc324-b39d-423c-9cb9-8fdc724c7262.jpg' } }
, ……
```

Исходя из условий задачи, распознавание-идентификация автомобилей происходит с малой  долей ошибок и работает, как базовый источник информации по событиям машин. Распознавание  персон выполняется пока без однозначной идентификации (по, например, "паспортным данным").

## Оценка параметров пребывания автомобилей на заправке

Вот оценка некоторых параметров пребывания автомобилей на заправке по выборке из 1000 событий (по отфильтрованным нами данным -- брались в расчет вначале полностью идентифицированные события въезда и выезда распознанного автомобиля) 
:::info
Минимальное время пребывания на заправке $dt_{min} = 11$ sec (сценарий:  *въезд - просмотр цены или занятости - выезд*)
Медианное время  пребывания на заправке $dt_{med} = 349$ sec $\approx$ 6 min
Среднее время пребывания на заправке $dt_{avg} = 489$ sec $\approx$ 8 min
Максимальное время пребывания на заправке $dt_{max} = 2706$ sec $\approx$ 45 min (варианты: *отдых, очередь или...*)

Квантильные оценки:


| ¼ quantile               | mediana                | ¾ quantile             |
| --------                 | --------               | --------               |
| 218 sec $\approx$ 3.6 min| 349 sec $\approx$ 6 min|574 sec$\approx$ 9.5 min|
:::

Для 55%  событий, распознанных, как “Prk”,  нет предварительного события "въезда на заправку"... 

Кроме того, наблюдается и дублирование событий “Enter”, 
::: spoiler например:

```
  1f6354bd-ab1e-4606-b0c2-4267c5574f68 BT6849BK KIA  MAGENTIS ЧОРНИЙ Enter 2021-03-09T12:47:54.147Z
  for BT6849BK memorized  on enter event time=2021-03-09T12:47:54.147Z

    1f6354bd-ab1e-4606-b0c2-4267c5574f68 BT6849BK KIA  MAGENTIS ЧОРНИЙ Enter 2021-03-09T12:48:20.628Z
    doubled car BT6849BK  on enter .......................................time delta =26.481sec

    1f6354bd-ab1e-4606-b0c2-4267c5574f68 BT6849BK KIA  MAGENTIS ЧОРНИЙ Enter 2021-03-09T12:48:47.862Z
    doubled car BT6849BK  on enter .......................................time delta =53.715sec
```
:::


---


 И очень большое число событий “Exit” без предварительных событий “Enter” и “Prk”, 
::: spoiler например:
```
756_______________________________________________________________________________
                           e9ce05cf-d9f1-4510-a0c1-ee7027e22f6e BH2358IM BMW БІЛИЙ Exit 2021-03-09T12:48:35.111Z 2021-03-09T12:48:35.111Z
                           ?????????????????????????? car BH2358IM  exited without enter event??????????
757_______________________________________________________________________________
758_______________________________________________________________________________
759_______________________________________________________________________________
    1f6354bd-ab1e-4606-b0c2-4267c5574f68 BT6849BK KIA  MAGENTIS ЧОРНИЙ Enter 2021-03-09T12:48:47.862Z
    doubled car BT6849BK  on enter .......................................time delta =53.715sec
760_______________________________________________________________________________
761_______________________________________________________________________________
                           36569fc4-c350-41fb-8678-e20d915dafc3 BH9739AT   Exit 2021-03-09T12:49:28.545Z 2021-03-09T12:49:28.545Z
                           ?????????????????????????? car BH9739AT  exited without enter event??????????
762_______________________________________________________________________________
763_______________________________________________________________________________
764_______________________________________________________________________________
                           754e8b87-112c-4800-97df-c1a919a7c4bc BH0793KO AUDI БЕЖЕВИЙ Exit 2021-03-09T12:49:35.059Z 2021-03-09T12:49:35.059Z
                           ?????????????????????????? car BH0793KO  exited without enter event??????????
765_______________________________________________________________________________
766_______________________________________________________________________________
```
:::


---

## [Диаграмма пересечения интервалов автомобилей и событий персон](#)  

Горизонтально идущие сегменты - интервалы машин по исходным данным. Засечка вверх - старт, засечка вниз - выезд. Изгибы и изломы - распознанные события машин на заправке - prk.
Вертикальные линии (узкие прямоугольники) - события персон (вход в магазин, кассы). Одинаковые цвета вертикальных событий означают распознанного одного и того же  человека.
Каждое событие имеет справа подпись (для автомобилей размер шрифта чуть больше)
Время идет слева направо (1 пиксел - 6 секунд, периодически повторяющиеся вертикальные зеленые события - интервалы примерно в 30 минут)

<iframe src="https://cars-persons-vis.glitch.me" width=1250 height=1250></iframe>
 
 

 
 >Диаграмма интервалов демонстрирует неприятный факт - существуют большие промежутки времени ( светлое время суток), когда на заправке нет “чистых” неперекрытых интервалов (среднее количество одновременно присутствующих автомобилей - 10).  Это существенно осложняет проверку корректности алгоритмов соответствия. Возможно, понадобится натурный эксперимент…. 
 
В отличие от ненадежных интервальных данных для машин, интервалы  для персон определяются четко и имеют длительность в несколько секунд. Однако сама идентификация персон выполняется с дублированием. Т.е. один и тот же человек в различных ракурсах может идентифицироваться разными профилями.

 # Модель 

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

 ## Базовые матрицы и функции модели 
 Исходя из этого, необходимо итеративно строить и уточнять: 
 1) Адаптивную функцию (матрицу) соответствия событий $H$ для персон $h$ с  событиями $V$ для машин $v$ (индексированными интервалами -- определенными и недоопределенными) 
$$ P : V\times H \to [ 0; 1 ] $$

 2) Оценку близости  идентифицированных персон $h_i$ и $h_j$ (возможного соответствия между дублями и/или близко связанных персон)
$$ D : h\times h \to [ 0; 1 ]. $$
>Функция (матрица) $P_{v,h}$ является принципиально асимметричной и, наоборот, функция (матрица) $D_{i,j}$ является симметричной.

 3) Функцию соответствия $f:h \to v$ используя информацию матрицы $P$ с учетом ограничений на домены и дополнительных внешних ограничений.

 ## Ограничения на домены
 При этом надо учитывать естественные ограничения на домены этих функций, 
а именно: 

a) один человек вряд ли приедет на двух машинах, а вот на одной машине могут приехать несколько (в зависимости от класса машины) человек; 

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

в) среднее количество зафиксированных лиц, приходящихся на один зафиксированный автомобиль, находится между 1 и 2.

## Итерации и обновления матриц модели
Ограничение а) позволяет ставить задачу построения функции правдоподобия владения и использовать на первом этапе, например, варианты различных жадных алгоритмов и/или динамики.
На каждой итерации мы должны обновлять функции (матрицы) $D: [0;1]^{h\times h}$ и $P: [0;1]^{V\times H}$  
 После каждого обновления матрицы $D$ может происходить отождествление индексов лиц $i$ и $j$ (ликвидация дублей) и соответствующее обновление (объединение столбцов) матрицы $P$.
Выбирая элементы с максимальными долями в строках матрицы $P$, с учетом ограничения (в), мы получаем очередной вариант функции $f:h \to v$.
Полученную функцию $f$ мы  можем использовать для последующей минимизации дублей с учетом ограничения (б)
Работа цепочки итераций должна останавливаться при отсутствии значимых изменений в матрицах $D$, $P$ и функции $f$

# Компоненты алгоритма

##  Обнаружение интервала присутствия машины
>Метод обнаружения интервала присутствия машины из последовательности отдельных событий кажется интутивно понятным и простым. Но лучше поставить эту  задачу достаточно формально, чтобы можно было обсуждать возможные тонкие моменты этой процедуры

Поскольку некоторые события могут отсутствовать в потоке данных, необходимо это учесть при обнаружении интервала и определения его параметров.
Рассмотрим определение интервала $I$ в виде контекстно свободной грамматики с $\epsilon$ правилами и дополнительным символом $\tau$, обозначающим время недопустимой задержки:

$$
   I \to B P E             \\
   B \to b \tau | bB | \epsilon  \\
   P \to p \tau | pP | \epsilon  \\
   E \to e \tau | eE | \epsilon 
$$

Здесь маленькими буквами записываются терминальные символы грамматики, обозначающими конкретные события, а большими буквами - нетерминалы, обозначающие блоки и последовательности событий.

$I$  - нетерминал, означающий полностью построенный интервал из отдельных событий. Интервал в идеале должен состоять из начала ( B ), событий prk  ( P ) и окончания ( E ). Однако в реальности из всех этих трех частей может присутствовать, например, только одна.
$B$  - нетерминал, означающий начало интервала $I$. Это начало может состоять из одного или нескольких подряд идущих событий $b$ (begin_event), расстояние между которыми во времени не должно превышать $\tau$.
$P$  - нетерминал, означающий последовательность событий prk внутри интервала $I$.
$E$  - нетерминал, означающий выезд машины с заправки и завершение интервала $I$. 
Выезд также может состоять из одного или нескольких подряд идущих событий $e$ (exit_event), расстояние между которыми во времени не должно превышать $\tau$.

 $\epsilon$ правила в этой грамматике нужны для учета выпадания какой-то части событий из определения интервала. Для написания кода распознавания интервала надо избавиться от $\epsilon$ правил. После процедуры избавления от $\epsilon$ правил и добавления атрибутивных действий грамматика принимает вид:
 

$$
   I \to B   \quad \{ \text{ I.recoveryFromB() }  \}\\
   I \to P    \quad \{ \text{I.recoveryFromP() }  \} \\
   I \to E   \quad \{ \text{I.recoveryFromE() }  \}  \\
   I \to  BP \quad \{ \text{I.recoveryFromBP() }  \}   \\
   I \to  BE \quad \{ \text{I.recoveryFromBE() }  \}   \\
   I \to  PE \quad \{ \text{I.recoveryFromPE() }  \}   \\
   I \to  B P E  \quad \{ \text{ I.contsructFromBPE() }  \}     \\
   B \to b\tau     \quad \{ \text{I.close()}  \} \\
   P \to p\tau     \quad \{ \text{I.close()}  \} \\
   E \to e\tau     \quad \{ \text{I.close()}  \} \\
   B \to bB        \quad \{ \text{I.push} \, (b, t_b ) \}  \\
   P \to pP  \quad \{ \text{I.push} \, (p, t_p ) \}  \\
   E \to eE  \quad \{ \text{I.push} \, (e, t_e ) \} 
$$

  Время $\tau$ недопустимой задержки  может задаваться одним значением для всех событий интервала, либо  для каждого типа события  своим значением. 
В процессе распознавания необходимо формировать список событий интервала $I$ со штампами времени.  Эта работа обозначается  действиями в фигурных скобках, сопоставленных соответствующим правилам вывода.
По окончании распознавания интервала, необходимо обработать сформированный список элементарных событий интервала и сформировать  границы  и важные внутренние точки как полностью (*I.contsructFrom(B,P,E)*), так и частично  определенного интервала (*I.recoveryFrom( B ), I.recoveryFrom( P ), ...*). Также необходимо принять решение, что делать с событиями, нарушающими естественную (и поэтому жестко закрепленную в грамматике) последовательность событий интервала.

## Группировка событий
Желательно обрабатывать события, сгруппировав их относительно идентификаторов машин.

:::spoiler Примеры предварительной обработки событий

 Выполнив следующий запрос, мы получим таблицу, удобную для обработки процедурными языками (например c++ или процедурами и функциями SQL)
```sql=
/****** Script for Select N Rows of car events for subsequent  interval interval detection******/
DECLARE @startDate           as DateTime
     SET @startDate = CAST('2021-03-09' as date)
SELECT TOP (1000000)
       [car_id],
       [place_id],
       [event_type_id],
             DATEDIFF(MILLISECOND,@startDate,event_begin)/1000.0 
       [t],
             DATEDIFF(MILLISECOND,event_begin,event_end)/1000.0  
       [dt]
  FROM cars_events
  group by car_id,event_begin,event_end,place_id,event_type_id
  order by car_id,event_begin
```


```cpp=
car_id p_id e_type	t	          dt
16289	7	2	41237.896000	0.000000
16289	13	6	41444.473000	283.640000
16289	5	4	41709.313000	0.000000
16290	5	4	41254.526000	0.000000
16291	7	2	41259.686000	0.000000
16291	7	2	138807.900000	0.000000
16291	7	2	138871.210000	0.000000
16291	7	2	138919.190000	0.000000
16291	7	2	299098.353000	0.000000
16291	7	2	299136.466000	0.000000
16291	7	2	299172.373000	0.000000
16291	7	2	299203.056000	0.000000
16291	7	2	299231.240000	0.000000
16291	7	2	299255.866000	0.000000
16291	7	2	299283.246000	0.000000
16292	7	2	41264.860000	0.000000
16292	5	4	42957.183000	0.000000
16293	5	4	41272.776000	0.000000
16294	16	6	41281.440000	414.140000
16294	5	4	41715.470000	0.000000
16294	23	6	1327696.476000	727.987000
16294	5	4	1328491.446000	0.000000
16295	18	6	41284.326000	38.854000
16295	5	4	41351.570000	0.000000

```

Аналогично, выполнив следующий запрос, мы получим таблицу, удобную для обработки процедурными языками (например c++ или процедурами и функциями SQL)
```sql=
/****** Script for Select N Rows of customer events for subsequent  interval interval detection******/
DECLARE @startDate           as DateTime
     SET @startDate = CAST('2021-03-09' as date)

SELECT TOP (1000000) 
      [customer_id]
      ,[place_id]
      ,[event_type_id]
     -- ,[event_begin]
     -- ,[event_end]
	  ,       DATEDIFF(MILLISECOND,@startDate,event_begin)/1000.0 
       [t],
             DATEDIFF(MILLISECOND,event_begin,event_end)/1000.0  
       [dt]
  FROM customer_events
  group by customer_id,event_begin,event_end,place_id,event_type_id
  order by customer_id,event_begin
```


```cpp=
cust_id p_id e_type	t	          dt
28316	3	3	41137.250000	1.700000
28317	3	3	41163.250000	1.566000
28318	3	3	41197.250000	6.700000
28318	3	3	42766.583000	1.933000
28318	3	3	44335.353000	0.633000
28318	3	3	46255.150000	0.500000
28318	3	3	1075574.626000	1.300000
28318	3	3	1077769.726000	1.200000
28318	3	3	1244268.510000	0.366000
28318	3	3	1249386.156000	5.100000
28318	3	3	1702511.180000	1.300000
28319	4	5	41173.426000	49.790000
28319	4	5	41238.210000	20.516000
28319	4	5	41274.200000	4.680000
28319	4	5	41283.796000	23.634000
```
:::


##  Функции начальной оценки принадлежности лица интервалу машины

>Функции оценки принадлежности человека интервалу машины служат для начальной оценки связи персоны и машины на ее интервале присутствия на заправке. 
Поскольку для одного профиля человека могут присутствовать несколько его событий на одном и том же интервале, то необходимо уточнить процедуру использования этих функций.
А именно, если на данном интервале все события одного человека попадают в "зеленую зону" (ненулевые значения), то из оценок выбирается максимальное значение. Если хотя бы одно из событий находится вне "зеленой" зоны, то оценка всего множества событий персоны равна 0 (профиль человека просто не учитывается для данного интервала).

В порядке неубывания количества параметров можно рассматривать следующие варианты функции оценки принадлежности к интервалу:
1) Треугольная симметричная: $\mu_0$ - вершина над центром допустимой части интервала (два параметра - $d_s$ и $d_e$)
<iframe src="https://www.desmos.com/calculator/hjzvwdaqxi?embed" width="500px" height="150px" style="border: 1px solid #ccc" frameborder=0></iframe>
 
 2) Треугольная, зависящая от времени события prk: $\mu_1$ - вершина над первым событием prk (также два параметра - $d_s$ и $d_e$)
<iframe src="https://www.desmos.com/calculator/ugzd4yy6hw?embed" width="500px" height="150px" style="border: 1px solid #ccc" frameborder=0></iframe>

 3) Трапециевидная $\mu_2$, обобщающая простые функции $\mu_0$ и $\mu_1$ (четыре параметра - $d_s$ и $d_e$, $d_0$ и $d_3$)
<iframe src="https://www.desmos.com/calculator/e85f3cyokm?embed" width="500px" height="150px" style="border: 1px solid #ccc" frameborder=0></iframe>

Более сложные варианты можно проверять после сравнительной проверки  $\mu_0$,$\mu_1$ и $\mu_2$ по эффективности первоначальных фильтрации и взвешивания событий персон.  

##  Матрица *P* соответствия машин и персон 

Функции принадлежности интервалу позволяют строить начальную матрицу соответствия. 
    $$ P : V\times H \to [ 0; 1 ] $$
 
 Эта матрица должна  индексироваться:
 по оси $V$ - парой (идентификатор авто,  номер в порядке повторного посещения заправки),
по оси $H$ - парой (код персоны, номер в порядке повторного распознавания вне одного интервала) 
 
 Для адаптивной каузальной коррекции элементов матрицы необходимо выполнять нормировки строк и столбцов и поддерживать следующие ограничения:
     $$ 
        S_v = \sum_h P_{v,h} = 1 \\
        S_h = \sum_v P_{v,h} = 1 
     $$
     
 Элементы строки $v$ матрицы $P$ могут быть проинтерпретированы как **оценки правдоподобия владения персонами $h$ машины $v$** или как оценка использования персонами машины $v$.
  Элементы столбца $h$  матрицы $P$ могут интерпретироваться как **оценки правдоподобия принадлежности машин $v$ персоне $h$** (для машин из множества, присутствующих одновременно с этой персоной на заправке).
 
 >При сортировке строк матрицы в порядке возрастания времени начал интервалов машин мы получим (учитывая вид функций принадлежности к интервалу) верхнюю треугольную матрицу ленточного типа, состоящую из  последовательно идущих лент, разделенных в местах отсутствия перекрытий событий (например, ночью).
 
 
> Такая форма матрицы позволяет применять оптимизированные методы обновления и поддержки ограничений субквадратичной сложности.

##  Матрица *D* близости идентификаторов персон

1) Диагональ $D_{i,i}$  заполняется единицами

2) Заполнение недиагональных элементов $D_{i,j}$ выполняется для лиц, попавших на один интервал $I$, и зависит от данных распознавания (мужчина/женщина, взрослый/ребенок) и расстояния по времени между ними, например,  по формуле:

     $$ D_{i,j} = \max_{\text{all}\, I}  c_{i,j}\left(1-\min_{I}\frac{|t_i-t_j|}{|I|} \right),$$
     
     где  $t_i$ и $t_j$ - моменты времени распознавания лиц $i$ и $j$  во время пребывания в одном интервале $I$,   $\; \;  0\le c_{i,j} \le 1$ - коррелятор распознанных признаков лиц $i$ и $j$.

##  Корректоры весов  при повторных посещениях автомобилем заправки
 
 ###  Корректор весов матрицы *D* 
 
 Пусть $a$ - номер интервала одного посещения машиной заправки, $b$  - номер любого другого и, соответственно,  $i_a$ - индекс лица $i$ при посещении $a$, а $j_b$  - индекс лица $j$  при посещении $b$.
 
 
 Тогда  
       $$ D'_{i,j} = \max_{a,b} \left(1 -(1-D_{i_a,j_b})^n \right),$$
       где $1\lt n$ - параметр алгоритма.
 Этот корректор не изменяет диагональ матрицы $D$, но изменяет (быстро увеличивает) ненулевые веса, если на множестве повторных интервалов встречается хотя бы одна пара близких персон. При достижении определенного порога может происходить отождествление индексов лиц $i$ и $j$ (при соответвующем корреляторе распознанных признаков) или внесение лиц $i$ и $j$ в список близких людей.    
      
 ###  Корректоры элементов матрицы *P* 
 
 1) Для всех пар $I_a$, $I_b$ - номеров интервалов повторного посещения машиной заправки, для которых встречается событие персоны $j=j_a=j_b$ :       
  
  $$ P'_{I_a,j_a}= P'_{I_b,j_b} = \max \left( 
  1 -(1-P_{I_a,j_a})^m, 1 -(1-P_{I_b,j_b})^m    
  \right),$$
       где $1\lt m$ -- параметр алгоритма.

 2) Если для всех пар $I_a$, $I_b$ - номеров интервалов повторного посещения машиной заправки - нет повторного события персоны $j=j_a=j_b$, то   

  $$ P'_{I_a,j_a} =  P_{I_a,j_a}/l \\      P'_{I_b,j_b} =  P_{I_b,j_b}/l$$

 где $1\lt l$ -- параметр алгоритма.
 
 3) После шагов (1)  и (2)  выполняется нормировка измененных строк матрицы $P$.  
 
 
 # Алгоритм
 
 
> Примечание. Параметры и функции алгоритма требуют настройки, однако гарантируется, что и без настроек алгоритм будет выдавать результаты с точностью не хуже наивного алгоритма поиска соответствия.

 ## Базовые этапы алгоритма
  

  ### 1. Инициализация
::: spoiler  
   На этом этапе происходит импорт (использование) данных таблиц событий для машин (car_events) и для людей (customer_events).
   Задаются начальные значения параметров алгоритма и выбирается функция начальной оценки принадлежности интервалу присутствия машины.
    С использованием выбранных параметров и функции оценки принадлежности, инициализируются матрицы $P$ и $D$.  
:::  

  ### 2. Начальная коррекция 
::: spoiler       
   На этом этапе происходит начальная коррекция   матриц $P$ и $D$. Эта работа выполняется на отдельном шаге в связи с тем, что она должна будет выполняться повторно при очередном получении нового блока событий  car_events и customer_events, дополняющего уже имеющиеся события. 
   Список откорректированных строк  и столбцов запоминается для дальнейшей работы.
:::

  ### 3. Определение близости и удаление дубликатов персон
::: spoiler       
   На этом этапе происходит оценка матрицы $D$ и производится попытка обнаружить дубликаты (с некоторой вероятностью) и при условии их обнаружения удалить дубликаты в матрицах $P$ и $D$.
   Строки матрицы $P$ после удаления элементов перенормируются.
:::   
   ### 4. Определение терминалов лент событий    
::: spoiler       
   На этом этапе происходит поиск терминалов (левых и правых краев) в лентах событий посещений автомобилями заправки. Для этих терминалов выполняется коррекция матриц $D$ и $P$ и происходит отметка строк матрицы $P$ с терминальными событиями 
:::   

   ### 5. Глобальная корректировка матрицы *P*     
::: spoiler       
   На этом этапе происходит корректировка матрицы *P* для удовлетворения глобальных нормировочных ограничений при фиксации маркированных строк. Ленточная структура матрицы *P* позволяет выполнить этот шаг за разумное время. 
:::   

   ### 6. Корректировка матрицы *D* и выдача варианта функции *f*    
::: spoiler     
   По  полученным данным нормализованной матрицы *P* корректируется матрица *D* (по максимальным весам строк матрицы *P*). По этим же данным и формируется вариант функции соответствия *f*
:::   

   ### 7. Адаптация и реинициализация
::: spoiler     
   На этом этапе должен выполняться процесс адаптации начальных параметров, возможный выбор альтернативных вариантов функции $\mu$ и параметров алгоритма. После этого должна проводиться реинициализация алгоритма. 
:::   


**При поступлении нового блока событий шаги, начиная с шага 2, повторяются.**

## Псевдокод
```javascript=

//step 1. Initialization
 import (car_events, customer_events)
 Initialize (function mu)
  Initialize(matrix P)
  Initialize(matrix D) 

repeat on new eventsBlocks (car_events, customer_events)
{
//step 2. Initial  сorrection
  getAddtionalEvents(car_events, customer_events)
   initialCorrection(D)
   initialCorrection(P)
    markCorrectedLinesOf(P)
    
//step 3. Reveal and Delete dublicates
    Hdup = revealDuplicate(D)
     deleteDuplicatesInH(Hdup)
      deleteDuplicatesInP(Hdup)
       markCorrectedLinesOf(P)
        normalizeCorrectedLinesOf(P)
        
 //step 4. Reveal and Mark CarEventsRibbon Terminals
      RevealTerminalsIn(P)
       correctByTerminals(P)
       correctByTerminals(D)
        markCorrectedLinesOf(P)
        
 //step 5. Global Correction of matrix P
      fixMarkedLines(P)
       GlobalCorectionOf(P)
 
 //step 6. Final correction D and yielding function f and  matrix D
      finalCorrectionOf(D)
       yield function f, matrix D
          
//step 7. Adaptation and reinitialization 
        adaptInitialParameters()
          reInitialize (function mu)          
 }      
        
```


