批处理作业调度不同于流水作业的地方在于要求所有作业完成的时间总和最小。

package test;

import java.util.ArrayList;
import java.util.List;

/**
 * Created by zuohao on 2018/12/9.
 * 批处理作业调度
 */
public class BatchJobSchedulingProblem {
    public static void main(String[] arg) {
        new BatchJobSchedulingProblem().backtracking();
    }

    /**
     * 回溯法
     */
    public void backtracking(){
        List<Task> taskList=new ArrayList<>();
        taskList.add(new Task("J1",2,1));
        taskList.add(new Task("J2",3,1));
        taskList.add(new Task("J3",2,3));
        Node root=new Node();
        root.setT1(0);
        root.setT2(0);
        root.setSt(0);
        Node best=new Node();
        best.setSt(Integer.MAX_VALUE);
        tree(root,taskList,best);
        for (Task task:best.getTaskList()){
            System.out.println(task.getName());
        }
        System.out.println(best.getSt());
    }
    public void tree(Node parentNode,List<Task> taskList,Node best){
        int t1=parentNode.getT1();
        int t2=parentNode.getT2();
        int st=parentNode.getSt();
        for (Task task:taskList){
            int nextt1=t1+task.getA();
            int nestt2=(t2-t1)>task.getA()?t2+task.getB():nextt1+task.getB();
            if (st+nestt2>best.getSt()){
                continue;
            }
            Node node=new Node();
            node.setTask(task);
            node.setT1(nextt1);
            node.setT2(nestt2);
            node.setSt(st+nestt2);
            node.getTaskList().addAll(parentNode.getTaskList());
            node.getTaskList().add(task);
            parentNode.getChildNodeList().add(node);
            List<Task> newTaskList=new ArrayList<>();
            newTaskList.addAll(taskList);
            newTaskList.remove(task);
            if (newTaskList.size()==0){
                best.setSt(node.getSt());
                best.setTaskList(node.getTaskList());
//                System.out.println(node.getSt());
            }
            tree(node,newTaskList,best);
        }
    }

    class Node{
        private Task task;
        private int t1;
        private int t2;
        private int st;
        //这里定义子节点只为根据概念上形成物理树结构,如果树在之后不再使用可以不定义子节点列表
        private List<Node> childNodeList=new ArrayList<>();
        private List<Task> taskList=new ArrayList<>();

        public List<Node> getChildNodeList() {
            return childNodeList;
        }

        public void setChildNodeList(List<Node> childNodeList) {
            this.childNodeList = childNodeList;
        }

        public Task getTask() {
            return task;
        }

        public void setTask(Task task) {
            this.task = task;
        }

        public int getT1() {
            return t1;
        }

        public void setT1(int t1) {
            this.t1 = t1;
        }

        public int getT2() {
            return t2;
        }

        public void setT2(int t2) {
            this.t2 = t2;
        }

        public int getSt() {
            return st;
        }

        public void setSt(int st) {
            this.st = st;
        }

        public List<Task> getTaskList() {
            return taskList;
        }

        public void setTaskList(List<Task> taskList) {
            this.taskList = taskList;
        }
    }

    class Task{
        private String name;
        private int a;
        private int b;

        public Task(String name, int a, int b) {
            this.name = name;
            this.a = a;
            this.b = b;
        }

        public String getName() {
            return name;
        }

        public void setName(String name) {
            this.name = name;
        }

        public int getA() {
            return a;
        }

        public void setA(int a) {
            this.a = a;
        }

        public int getB() {
            return b;
        }

        public void setB(int b) {
            this.b = b;
        }
    }
}