伪代码:随机置换

时间:2017-04-20 15:33:52

标签: java pseudocode

我有一个伪代码,我已经翻译成java代码,但是无论何时我运行代码,我得到一个空的arraylist作为结果,但它应该给我一个随机的整数列表。 这是伪代码:

Algorithm 1. RandPerm(N)
Input: Number of cities N
1) Let P = list of length N, (|P|=N) where pi=i
2) Let T = an empty list
3) While |P| > 0
4)    Let i = UI(1,|P|)
5)    Add pi to the end of T
6)    Delete the ith element (pi) from P
7) End While
Output: Random tour T

这是java代码:

public static ArrayList<Integer> RandPerm(int n)
    {
        ArrayList<Integer> P = new ArrayList<>(n);
        ArrayList<Integer> T = new ArrayList<>();
        int i;

        while(P.size() > 0)
        {
            i = CS2004.UI(1, P.size());// generate random numbers between 1 and the size of P
            T.add(P.get(i));
            P.remove(P.get(i));
        }   
        return T;
    }

我不知道自己做错了什么。

2 个答案:

答案 0 :(得分:1)

  ArrayList<Integer> p = new ArrayList<>(n);

...创建一个空列表初始容量n

所有这一切都告诉ArrayList要初始化为支持存储的大小数组 - 大多数情况下,通过指定它来实现无用的任务。

因此while(p.size() > 0)运行零次,因为p.size()在开始时为零。

在伪代码中,“pi = i”在我看来,你想要像这样初始化列表:

  for(int i=0;i<n;i++) {
     p.add(i)
  }

(我已经小写了你的变量名 - 在Java中,惯例是变量startWithALowerCaseLetter - 只有类名StartWithUpperCase。它也是赋予变量描述性名称的Java约定,所以也许cityIdentifiers

答案 1 :(得分:0)

您可能想知道,即使您解决了P始终为空的问题,您的实施还会遇到两个问题。

一个是P.remove(P.get(i))如果列表具有相等的值项,则不一定会删除第i个项。它从头开始扫描并删除第一次出现的项目。见ArrayList.remove(Object obj)。您应该使用P.remove(i)代替正确的结果。

然后表现为O(n ^ 2)。原因是ArrayList通过将所有后续项目向左移动一个槽来移除项目,这是O(n)操作。为了获得更好的性能,您可以通过将项目交换到最后来实现自己的“删除”操作。生成下一个随机索引时,请在[0, beginning index of the removed items at the end)范围内生成它。交换为O(1),整体性能为O(n)。顺便说一下,这叫做Knuth Shuffle。