Рекурсивный алгоритм переноса слов - PullRequest
0 голосов
/ 07 марта 2011

Я работаю над алгоритмом, который состоит из трех частей. Первый - это рекурсивный метод, который переносит слова на определенную длину с наименьшим штрафом. Вторым является алгоритм, который является динамической реализацией рекурсивного метода. Последний является жадным алгоритмом задачи. У меня уже есть код Greedy, но я борюсь за рекурсивное решение. Я не совсем уверен, где именно у меня возникла проблема с моим рекурсивным методом, но я знаю, что это должно быть что-то похожее на алгоритм Кнута-Пласса. Предполагается, что рекурсивный алгоритм имеет факториальное время выполнения и используется больше для помощи с динамическим решением. Если кто-то имеет ссылку на реализацию Knuth-Plass или может заметить что-то огромное в моем коде, любая помощь будет признательна.

Рекурсивный алгоритм:

public static ArrayList<String> recursive(ArrayList<String> input, int size) {
    if(input.size() <= 1)
        return input;
    ArrayList<String> temp1 = input;
    ArrayList<String> temp2 = input;
    for(int i = 0; i < input.size(); i++) {
        if(input.size() - 1 >= size)
            break;
        else {
            for(int j = 0; j < input.size(); j++) {
                temp1.set(j, temp1.get(j) + " " + temp1.get(j + 1));
                temp1.remove(j + 1);
                if(totalPenalty(blankChars(temp1, size)) < totalPenalty(blankChars(temp2, size))) {
                    input = recursive(temp1, size);
                } else {
                    input = recursive(temp2, size);
                }
            }
        }
    }
    return input;
}

totalPenalty () и blankChars возвращают сумму штрафа в конце каждой строки.

РЕДАКТИРОВАТЬ: Я все еще не вижу каких-либо немедленных решений. Любая помощь будет оценена.

Ответы [ 2 ]

2 голосов
/ 07 марта 2011

Это похоже на Java, а в Java нет неявного конструктора копирования.

ArrayList<String> temp1 = input; <- <em>не создаст другой объект с тем же содержимым, но вместо этого ссылку на тот же объект.

Вам необходимо изменить строки 4 и 5 на:

ArrayList<String> temp1 = new ArrayList<String>(input);
ArrayList<String> temp2 = new ArrayList<String>(input);

Я не искал других ошибок, поэтому попробуйте это и обновите вопрос, если у вас возникнут какие-либо проблемы.

Об алгоритме взлома Кнута-Пасс; Вы можете найти реализацию Python на http://oedipus.sourceforge.net/texlib/. Я не смотрел на это поближе, но описание, кажется, то, что вы ищете.

0 голосов
/ 16 ноября 2018

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

import java.lang.Math;

public int RCS(int[] l , int n , int m , int index) {

    // first base condition - if index gets beyond the array 'l' , then return 0;
    if (index > n - 1) return 0;

    // second base condition - if index is the last word i.e there is only one word left in the
    // array to be inserted in the line then return the cost if added in that line.
    if (index == n - 1) return (m - l[n - 1]) * (m - l[n - 1]) * (m - l[n - 1]);

    // make a global cost variable to be returned
    int cost = Integer.MAX_VALUE;

    // Here , we try to select words from the array and apply RCS on the rest of the array.
    // From index to last element , we iteratvely select first , or first two and so on.
    for (int i = index ; i < n ; i++) {
        int current_space_sum = 0 ;
        // we add the length of the selected word. We have selected words in array from index to i.
        for (int k = index ; k <= i ; k++) {
            current_space_sum = current_space_sum + l[k] ;
        }
        // Adding the space between the words choses. If 2 words are chosen , there is one space and so on
        current_space_sum = current_space_sum + i - index;
        // If the length of the chosen words is greater than the line can accept , no need of looking beyond.
        if (current_space_sum > m) break;
        // Iteratively find the minimum cost
        cost =  Math.min(cost , (m - current_space_sum) * (m - current_space_sum) * (m - current_space_sum) + RCS(l , n , m , i + 1));
    }
    return cost;
}



public static void main(String[] args) {
    WordWrap w = new WordWrap();
    int[] l = {3, 2 , 2 , 5};
    int n = l.length;
    int m = 6;
    int result = w.RCS(l , n , m , 0);

    System.out.println(result);
}
...