这是我生活中的一个小问题~
我是某门课的助教,现在老师想让同学们把课本(只有英文版)翻译一下。要求每个同学翻译两段不同的地方,每个同学每段需要大致相等。
比如说要从书本的start = 16页开始翻译,结束问end = 578。共有n = end - start页,共有m=107个人。所以如果只翻译一段的话每个人平均翻译interval = n / m页,但要求每个人翻译两段,而且这两段不同。
我采用的方法就是生成两个随机序列。处在bonus = n % m前面的人需要多翻译一页interval + 1,处在bonus后面的人只需要翻译interval页。这个方法可能有漏洞的地方在于两个随机序列可能需要很长的时间才能确保没有任何位置是相同的。还有一种方案是第二个随机序列由第一个随机序列生成,即m - 第一个随机序列中的值i,但是这样处于中间的人两次都只翻译interval页,而处于两端的人(具体来说是2 * bonus个)会一次翻译interval页,一次翻译interval + 1页。
import java.util.Random;
public class AllocateAssignment {
static int start = 16;
static int end = 578;
static int m = 107;
static int n = end - start + 1;
static int interval = n / m;
static int bonus = n % m;
public static void main(String[] args) {
if (n < m) {
System.out.println("input error! n can not be smaller than m.");
return;
}
int[] randArray = new int[m];
int[] randArray2 = new int[m];
Random random = new Random();
// 初始化顺序数组
for (int i = 1; i <= m; i++) {
randArray[i - 1] = i;
randArray2[i - 1] = i;
}
// 生成随机排列
for (int i = 0; i < m; i++) {
int pos = Math.abs(random.nextInt() % (m - i)) + i;
int t = randArray[i];
randArray[i] = randArray[pos];
randArray[pos] = t;
// 确保两个随机序列没有任何位置是相同的,这一步可能话费很多时间。
do {
pos = Math.abs(random.nextInt() % (m - i)) + i;
t = randArray2[pos];
} while (t == randArray[i]);
randArray2[pos] = randArray2[i];
randArray2[i] = t;
}
System.out.println("task1:");
output(randArray);
// 下面的注释对应不平等方案
// for (int i = 0; i < m; i++) {
// randArray[i] = m - randArray[i] + 1;
// }
System.out.println("task2:");
output(randArray2);
}
private static void output(int[] randArray) {
for (int i = 1; i <= m; i++) {
if (randArray[i - 1] <= bonus) {
int thisStart = (randArray[i - 1] - 1) * (interval + 1) + start;
int thisEnd = (randArray[i - 1]) * (interval + 1) + start - 1;
System.out.println(i + " : " + (interval + 1) + ", from " + thisStart + " to " + thisEnd);
} else {
int thisStart = (randArray[i - 1] - bonus - 1) * (interval) + start + bonus * (interval + 1);
int thisEnd = (randArray[i - 1] - bonus) * (interval) + start - 1 + bonus * (interval + 1);
System.out.println(i + " : " + interval + ", from " + thisStart + " to " + thisEnd);
}
}
}
}