我正在研究一个包含三个部分的算法。第一种是递归方法,它将单词包装到具有最小惩罚的特定长度。第二种是算法,它是递归方法的动态实现。最后一个是问题的贪婪算法。我已经编写了Greedy编码,但我在Recursive解决方案上苦苦挣扎。我不太确定我的Recursive方法遇到了什么问题,但我知道它应该类似于Knuth-Plass算法。递归算法应该具有阶乘运行时间,并且更多地用于帮助动态解决方案。如果有人有一个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返回每行末尾的惩罚金额。
编辑:我还没有看到任何直接的解决方案。任何帮助,将不胜感激。
这看起来像Java,而在Java中没有隐式的复制构造函数。
ArrayList<String> temp1 = input;
不会创建具有相同内容的另一个对象,而是创建对同一对象的引用。
您需要将第4行和第5行更改为:
ArrayList<String> temp1 = new ArrayList<String>(input);
ArrayList<String> temp2 = new ArrayList<String>(input);
我没有找到任何其他错误,所以试试这个并更新问题,如果你有任何其他问题。
关于Knuth-Pass破解算法;您可以在http://oedipus.sourceforge.net/texlib/找到Python实现。我没有仔细看过它,但描述似乎是你正在寻找的。
我希望以下代码运行。在这里,我还添加了最后一行的成本。尽管文字处理器大多数时候都使用贪婪算法,但却忽略了最后一行的成本。如果您明白这一点,请告诉我。
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);
}