您好,我在编程方面相对较新,需要指导。
我们正在种植。我有许多字段包含不同数量的树。在每个字段上都必须完成一组任务。任务相同但时间不同,因为字段大小不同。我想生成一个与最佳工作时间相匹配的任务列表。
我认为这是一个Job Shop调度问题(NP-hard),但据我所知,它可以通过强力搜索解决,因为数据集很小。如何在指定时间内生成所有组合并返回最佳拟合?我试着看一些伪代码,但坦率地说我很丢失,而且我的尝试很差:
//暴力搜索
// 1. first(P): generate a first candidate solution for P.
// 2. next(P,c): generate the next candidate for P after the current one c.
// 3. valid(P,c): check whether candidate c is a solution for P-
// 4. output(P,c): use the solution c of P as appropriate to the application.
public static ArrayList<Task> generatedList2(int totalTime) {
ArrayList<Task> bestFit = new ArrayList<>();
ArrayList<Task> tmpFit = new ArrayList<>();
int tmpTime = 0;
int bestFitTime = -1;
Task testTask = new Task("TestTask", 0);
bestFit.add(testTask); //1
for(Field f : fields) { //2
for(Task t : f.getUndoneTasks()) {
if(f.getTaskTime(t) < totalTime) {
tmpFit.add(t);
tmpTime += f.getTaskTime(t);
totalTime -= f.getTaskTime(t);
}
}
if(tmpTime < bestFitTime) { //3
bestFit = new ArrayList<Task>(tmpFit);
bestFitTime = tmpTime;
tmpFit.clear();
}
else {
tmpFit.clear();
}
}
return bestFit; //4
}
更新了解决方案:
public static ArrayList<Task> RecursivelyGetAnswer(ArrayList<Task> listSoFar,
ArrayList<Task> masterList, ArrayList<Task> bestList, int limit, int index) {
for (int i = index; i < masterList.size(); i++) {
Task task = masterList.get(i);
double listSoFarTotal = getTotal(listSoFar) + task.getTaskLength();
if (listSoFarTotal <= limit) {
int bestListTotal = getTotal(bestList);
listSoFar.add(task);
if (listSoFarTotal > bestListTotal) {
bestList = new ArrayList<Task>(listSoFar);
}
else if(100 - ((float) (limit - bestListTotal)/bestListTotal * 100) > 95) {
break;
}
bestList = RecursivelyGetAnswer(listSoFar, masterList, bestList, limit, i+1);
listSoFar.remove(task);
}
}
return bestList;
}
答案 0 :(得分:1)
我想出了一个递归解决方案。出于我的解决方案的目的,我假设您只有一个任务列表,而不是字段内的任务。
import java.util.ArrayList;
class Task
{
public int taskLength;
public Task(int taskLength)
{
this.taskLength = taskLength;
}
@Override
public String toString()
{
return "T" + taskLength;
}
}
public class Answers
{
public static void main(String args[])
{
ArrayList masterList = new ArrayList();
//Add some sample data
masterList.add(new Task(555));
masterList.add(new Task(1054));
masterList.add(new Task(888));
masterList.add(new Task(5923));
masterList.add(new Task(2342));
masterList.add(new Task(6243));
masterList.add(new Task(9227));
masterList.add(new Task(4111));
masterList.add(new Task(4322));
masterList.add(new Task(782));
final int limit = 9999;
ArrayList<Task> bestList = RecursivelyGetAnswer(new ArrayList<>(), masterList, new ArrayList<>(), limit, 0);
System.out.println(bestList.toString());
System.out.println(getTotal(bestList));
}
public static ArrayList<Task> RecursivelyGetAnswer(ArrayList<Task> listSoFar, ArrayList<Task> masterList, ArrayList<Task> bestList, int limit, int index)
{
for (int i = index; i < masterList.size(); i++)
{
Task task = masterList.get(i);
if (getTotal(listSoFar) + task.taskLength <= limit)
{
listSoFar.add(task);
if (getTotal(listSoFar) > getTotal(bestList))
{
bestList = new ArrayList(listSoFar);
}
bestList = RecursivelyGetAnswer(listSoFar, masterList, bestList, limit, i+1);
listSoFar.remove(task);
}
}
return bestList;
}
// Given a list of tasks, get the sum of the lengths of the tasks.
public static int getTotal(ArrayList<Task> myList)
{
int sum = 0;
for (Task t:myList)
sum += t.taskLength;
return sum;
}
}