用蛮力搜索找到最好的装备

时间:2017-04-29 21:04:47

标签: java algorithm

您好,我在编程方面相对较新,需要指导。

我们正在种植。我有许多字段包含不同数量的树。在每个字段上都必须完成一组任务。任务相同但时间不同,因为字段大小不同。我想生成一个与最佳工作时间相匹配的任务列表。

我认为这是一个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;
}

1 个答案:

答案 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;
    }
}