Levenshtein Edit Distance не вычисляет расстояние редактирования

Я пытаюсь заставить работать мой алгоритм Levenshtein Edit Distance, но по какой-то причине количество правок выходит неверным. Я не вижу, где моя ошибка, и мне было интересно, видит ли кто-нибудь, что я делаю неправильно.

Вход

5
ATCGTT
AGTTAC
ACGAAT
CCGTAAAT
TTACGACCAGT

ожидаемый результат

Strand A: ATCGTT--
Strand B: A--GTTAC
Edit Distance: 4

Strand A: ATCG-TT
Strand B: A-CGAAT
Edit Distance: 3

Strand A: ATCGT---T
Strand B: -CCGTAAAT
Edit Distance: 5

Strand A: AT-CG----TT
Strand B: TTACGACCAGT
Edit Distance: 7

Strand A: AGTTAC
Strand B: ACGAAT
Edit Distance: 4

Strand A: -AGT-TAC
Strand B: CCGTAAAT
Edit Distance: 5

Strand A: --A-G-TTA-C
Strand B: TTACGACCAGT
Edit Distance: 8

Strand A: ACG--AAT
Strand B: CCGTAAAT
Edit Distance: 3

Strand A: --ACGA--A-T
Strand B: TTACGACCAGT
Edit Distance: 5

Strand A: --CCG-TAAAT
Strand B: TTACGACCAGT
Edit Distance: 7

мой вывод

Strand A: ATCGT-
Strand B: AGTTAC
Edit Distance: 5

Strand A: ATC-T-
Strand B: ACGAAT
Edit Distance: 5

Strand A: ATC-T-
Strand B: CCGTAAAT
Edit Distance: 5

Strand A: A-C-T-
Strand B: TTACGACCAGT
Edit Distance: 10

Strand A: AGTTAC
Strand B: ACGAAT
Edit Distance: 5

Strand A: AG-TAC
Strand B: CCGTAAAT
Edit Distance: 6

Strand A: A--T-C
Strand B: TTACGACCAGT
Edit Distance: 7

Strand A: AC-AAT
Strand B: CCGTAAAT
Edit Distance: 7

Strand A: AC---T
Strand B: TTACGACCAGT
Edit Distance: 8

Strand A: CC-TAAAT
Strand B: TTACGACCAGT
Edit Distance: 8

найтиEditDistance

void EditDistance::findEditDistance()
{
    int upperValue, leftValue, diagonalValue;

    for (int i = 0; i < mLengthX; ++i)
    {
        table[i][0].stringLength = i;
    }

    for (int i = 0; i < mLengthY; ++i)
    {
        table[0][i].stringLength = i;
    }

    for (int i = 1; i < mLengthX; ++i)
    {
        for (int j = 1; j < mLengthY; ++j)
        {
            if (mStringX[i] == mStringY[j])
            {
                table[i][j].direction = DIAGONAL;
                table[i][j].stringLength = table[i - 1][j -1].stringLength;
            }
            else
            {
                upperValue = table[i - 1][j].stringLength;
                leftValue = table[i][j - 1].stringLength;
                diagonalValue = table[i - 1][j - 1].stringLength;

                if (upperValue < leftValue)
                {
                    if (upperValue < diagonalValue)
                    {
                        //upper is the lowest
                        table[i][j].stringLength = table[i - 1][j].stringLength + 1;
                        table[i][j].direction = UP;
                    }
                    else
                    {
                        //diagonal is lowest
                        table[i][j].stringLength = table[i - 1][j -1].stringLength + 1;
                        table[i][j].direction = DIAGONAL;
                    }
                }
                else if (leftValue < diagonalValue)
                {
                    //left is lowest
                    table[i][j].stringLength = table[i][j - 1].stringLength + 1;
                    table[i][j].direction = LEFT;
                }
                else
                {
                    //diagonal is lowest
                    table[i][j].stringLength = table[i - 1][j -1].stringLength + 1;
                    table[i][j].direction = DIAGONAL;
                }
            }
        }
    }   
}

получить расстояние

void EditDistance::getDistance()
{
    int i = mStringX.length() - 1;
    int j = mStringY.length() - 1;

    numEdits = 0;

    updateStrands (i, j);
}

updateStrands

void EditDistance::updateStrands (int i, int j)
{
    if (i == 0 || j == 0)
    {
        return;
    }

    if (table[i][j].direction == DIAGONAL)
    {
        ++numEdits;
        updateStrands (i - 1, j - 1);
    }
    else if (table[i][j].direction == UP)
    {
        mStringY[j] = '-';
        ++numEdits;
        updateStrands (i - 1, j);
    }
    else
    {
        mStringX[i] = '-';
        ++numEdits;
        updateStrands (i, j - 1);
    }
}

person Ryan Newman    schedule 28.04.2015    source источник
comment
Можете ли вы представить, каковы ваши входные и выходные данные по сравнению с ожидаемым результатом?   -  person kristianp    schedule 28.04.2015
comment
О да, я могу это сделать. Позвольте мне сделать это очень быстро   -  person Ryan Newman    schedule 28.04.2015
comment
Вы опубликовали только один набор результатов.   -  person samgak    schedule 28.04.2015
comment
Не могли бы вы сказать нам, какие из них неверны, и какие ответы должны были быть правильными? Это сэкономило бы нам время.   -  person Beta    schedule 28.04.2015
comment
Попробуйте распечатать всю таблицу расстояний - это поможет вам отладить процесс   -  person Ophir Yoktan    schedule 28.04.2015


Ответы (1)


Проблема с расстоянием редактирования заключается в вашем updateStrands. Диагональные ходы считаются за 1, хотя на самом деле диагональный ход может иметь расстояние 1 (замена) или 0 (совпадение). Вы могли бы исправить это в updateStrands, но на самом деле там вообще не нужно делать расчет, когда число уже находится в правом нижнем углу table.

Если вам нужны правильные «цепочки» (например, «ATCGTT--» и «A--GTTAC»), вам придется внести исправления в updateStrands (вы измените элементы строк, где вы должны < em>insert), getDistance (вы начинаете не с того места) и findEditDistance (вы пренебрегаете присвоением значений direction вдоль верхнего и левого краев, когда устанавливаете stringLength в i).

person Beta    schedule 28.04.2015