Математическая формула к рекурсивному методу

Мне нужно реализовать текущую формулу. Это для подсчета узлов в таксономии. В принципе, оценка node зависит от количества дочерних узлов и их результатов ((nodes(h+1)) - количество узлов на следующем уровне, а Cl(concept) - набор дочерних элементов).

Formula

В моем терминах использования частоты теперь определяются только для листьев. Я сделал реализацию, но проблема в том, что, когда для node есть 2 ребенка, реализация только идет в одну сторону.

Для данной таксономии:

     1
    / \
   2   3
   |   |
   4   17
  / \
 11 13

приведены частоты: freq(11) = 3, freq(13) = 5 и freq(17) = 10. Когда я пытаюсь получить оценку для node(1), результат 0.0, потому что рекурсия не переходит в descendent node(4), она извлекает только freq(17) и что она. Обычно результат должен быть равен 7.

Вот реализация:

public static float calcScore(int keyID, Map<Integer, Integer> frequencies, Map<Integer, Integer> subTaxonomy) {
    float res = 0f;
    int nodes = 0;
    if (frequencies.containsKey(keyID)) {
        return frequencies.get(keyID) + 0f;
    }

    for (Map.Entry<Integer, Integer> entry : subTaxonomy.entrySet()) {
        if (entry.getValue() - 1 == subTaxonomy.get(keyID)) {
            nodes++;
            res += calcScore(entry.getKey(), frequencies, subTaxonomy);
        }
    }
    return 1 / nodes * res;
}

Примечание:

subTaxonomy - хранит идентификатор узла и его уровень в таксономии

frequencies - сохранить частоты для листовых узлов.

Я также создал фрагмент в Ideone: Источник

Как мне изменить код, чтобы он проходил по всем дочерним элементам для данного node?

UPDATE

Итак, теперь, в обновленном источнике, он пересекает всю таксономию, но результат все равно 0.0.

Ответ 1

Ваша проблема находится в этой строке кода

if (entry.getValue() - 1 == subTaxonomy.get(keyID)) {

Левая часть вашего дерева не содержит вашего предполагаемого соглашения о том, что childs id (который не является листом дерева) следует формуле childs id = parents id - 1

Я бы предложил изменение вашей реализации, включая parents id в вашей таксономии вместо node level. Уровень может быть подсчитан во время повторного использования и передан как еще один параметр.

Новая подпись может выглядеть так:

public static float calcScore(int keyID, Map<Integer, Integer> frequencies, Map<Integer, Integer> subTaxonomy, int level)

далее вы можете отказаться от информации level от вашего кода, если это не способствует окончательному результату!

Ответ 2

Копия Ответ OPs, который был отправлен в вопрос

ПРАВИЛЬНЫЙ МЕТОД

public static float calcScore(int keyID, Map<Integer, Integer> frequencies, Map<Integer, Integer> subTax) {
    float res = 0f;
    int nodes = 1;
    if (frequencies.containsKey(keyID)) {
        return frequencies.get(keyID) + 0f;
    }

    for (Map.Entry<Integer, Integer> entry : subTax.entrySet()) {
        if (entry.getValue() == keyID) {
            res += calcScore(entry.getKey(), frequencies, subTax);
            nodes++;
        }
    }
    nodes--;
    return (float)1 / nodes * res;
}

Примечание

subTax - это карта, содержащая (child_id, parent_id)