分配作业问题

这是我生活中的一个小问题~

我是某门课的助教,现在老师想让同学们把课本(只有英文版)翻译一下。要求每个同学翻译两段不同的地方,每个同学每段需要大致相等。

比如说要从书本的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);
			}
		}
	}

}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值