import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Scanner;
public class Test {
private int n;//工人和作业的数量
private int[] isworked;//记录对应的工作是否被做了
private int[][] time;//记录初始每个工人做每件工作所花费的时间,行对应工人,列对应工作
private int[][] record;//记录每次的分配情况
private ArrayList<Integer> counts = new ArrayList<>();//记录各次分配情况对应的总的时间花费
private int temp = 1;//记录分配的次数
public static void main(String[] args) throws IOException {
//输入测试编号
System.out.println("请输入要测试的数据编号:1~6");
Scanner input = new Scanner(System.in);
int number = input.nextInt();
Test test = new Test();
test.readInit(number);//读取相应数据并初始化
int count = 0;//初始的时间花费
test.work(0,count);//回溯求取各个分配方案
test.minCost();//求取各种分配方案的最小值即为所求
}
/**
* 读取数据并初始化各个数组
* @param number:文件的编号
* @throws IOException
*/
public void readInit(int number) throws IOException {
BufferedReader reader = new BufferedReader(new FileReader(".\\input_assign04_0"+number+".dat"));
this.n = Integer.parseInt(reader.readLine());//读取第一行的数据是作业或工人的个数
isworked = new int[n];
time = new int[n][n];
record = new int[n][n];
String line = "";
int i = 0;
System.out.println("每个工人做每项工作所需要花费的时间:");
//读取数据并初始化每个工人做每个作业的时间数组,其他数组初始化默认为0
while ((line = reader.readLine())!=null){
String[] t = line.split(" ");
for(int j=0;j<n;j++){
time[i][j] = Integer.parseInt(t[j]);
System.out.print(time[i][j]+" ");
}
i++;
System.out.println();
}
}
/**
* 回溯求取各种分配方案
* @param i:第i个工人
* @param count:求取到当前所用的时间花费
*/
public void work(int i,int count){
if(i>=n){//当所有工人都有工作分配时,这时已经形成了一种方案
this.counts.add(count);//将该方案的总花费添加到记录各种方案花费的数组中
System.out.println("第"+(temp++)+"次分配结果是:");//输出该种方案
for(int m = 0; m<record.length;m++){
for(int n = 0; n<record[m].length; n++){
System.out.print(record[m][n]+" ");
}
System.out.println();
}
System.out.println("此次花费为"+count);
return;
}
for(int j=0;j<n;j++){
if(isworked[j]==0){//如果当前的工作没有被分配
isworked[j] = 1;//就将该工作分配给当前的员工
record[i][j] = 1;//记录第i个员工做第j个工作
work(i+1,count+time[i][j]);//递归第(i+1)个员工分配工作
isworked[j] = 0;//将记录置0,便于寻找其他的方案
record[i][j] = 0;
}
}
}
/**
* 求取最小花费
*/
public void minCost(){
Collections.sort(counts);//将各种方案的花费从小到大排序
System.out.println("最少花费为:"+counts.get(0));//第一个值就是最小的时间花费
}
}
回溯——深度优先