题目
现有若干家工厂,若干个顾客。每个顾客有不同的需求量,每家工厂有不同的容量、不同的开厂成本,对每个顾客也有不同的分派成本。给出这些数据,求关于顾客选择的工厂的一个解,使得总的开厂成本、分派成本尽可能地小。
数据结构
Data
从文件中读取并存放顾客需求量、工厂容量、开厂成本、分派成本等数据。
import java.io.*;
import java.util.Scanner;
public class Data {
int facNum;
int cusNum;
int[] capacity;
int[] openingCost;
int[] demand;
int[][] assignmentCost;
public Data(String filepath) {
try{
if(filepath == null) {
filepath = "assets/p1";
}
File file = new File(filepath);
BufferedReader reader = new BufferedReader(new FileReader(file));
String line;
line = reader.readLine();
Scanner scanner = new Scanner(line);
facNum = scanner.nextInt();
cusNum = scanner.nextInt();
capacity = new int[facNum];
openingCost = new int[facNum];
demand = new int[cusNum];
assignmentCost = new int[cusNum][facNum];
for(int i = 0; i < facNum; i++) {
line = reader.readLine();
Scanner s = new Scanner(line);
capacity[i] = s.nextInt();
openingCost[i] = s.nextInt();
s.close();
}
scanner.close();
scanner = new Scanner(reader);
for(int i = 0; i < cusNum; i++) {
demand[i] = (int)scanner.nextDouble();
}
for(int i = 0; i < facNum; i++) {
for(int j = 0; j < cusNum; j++) {
assignmentCost[j][i] = (int)scanner.nextDouble();
}
}
scanner.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
Solution
代表一个解,除了这个解的数据来源 data
,还包括工厂的开设情况 open
、顾客选择的工厂 assignment
、每家工厂剩余的容量 remain
、总费用 cost
。
import java.util.Arrays;
public class Solution {
Data data;
int cost;
int[] open;
int[] assignment;
int[] remain;
public Solution(Data d) {
data = d;
cost = 0;
open = new int[data.facNum];
for(int i = 0; i < data.facNum; i++) {
open[i] = 0;
}
assignment = new int[data.cusNum];
remain = Arrays.copyOf(data.capacity, data.capacity.length);
}
public Solution(Solution other) {
data = other.data;
cost = other.cost;
open = Arrays.copyOf(other.open, other.open.length);
assignment = Arrays.copyOf(other.assignment, other.assignment.length);
remain = Arrays.copyOf(other.remain, other.remain.length);
}
public boolean assign(int cus, int fac) {
if(remain[fac] >= data.demand[cus]) {
assignment[cus] = fac;
remain[fac] -= data.demand[cus];
cost += data.assignmentCost[cus][fac];
if(open[fac] == 0) {
cost += data.openingCost[fac];
open[fac] = 1;
}
return true;
} else {
return false;
}
}
public boolean move(int cus, int fac) {
if(remain[fac] >= data.demand[cus]) {
assignment[cus] = fac;
int oldFac = assignment[cus];
remain[oldFac] += data.demand[cus];
cost -= data.assignmentCost[cus][oldFac];
if(remain[oldFac] == data.capacity[oldFac]) {
open[oldFac] = 0;
cost -= data.openingCost[oldFac];
}
remain[fac] -= data.demand[cus];
cost += data.assignmentCost[cus][fac];
if(open[fac] == 0) {
cost += data.openingCost[fac];
open[fac] = 1;
}
return true;
} else {
return false;
}
}
public boolean swap(int c1, int c2) {
if(c1 == c2) return false;
int fac1 = assignment[c1];
int fac2 = assignment[c2];
if(fac1 == fac2) return false;
if(remain[fac1] + data.demand[c1] >= data.demand[c2] && remain[fac2] + data.demand[c2] >= data.demand[c1]) {
//System.out.println(Arrays.toString(open) + " " + Arrays.toString(assignment));
//System.out.print("cost 1 " + cost + " " + data.assignmentCost[c1][fac1] + " " + data.assignmentCost[c2][fac2]);
remain[fac1] += data.demand[c1];
remain[fac2] += data.demand[c2];
cost -= data.assignmentCost[c1][fac1];
cost -= data.assignmentCost[c2][fac2];
remain[fac1] -= data.demand[c2];
remain[fac2] -= data.demand[c1];
cost += data.assignmentCost[c1][fac2];
cost += data.assignmentCost[c2][fac1];
assignment[c1] = fac2;
assignment[c2] = fac1;
//System.out.println("\tcost 2 " + cost + " " + data.assignmentCost[c1][fac2] + " " + data.assignmentCost[c2][fac1]);
//System.out.println(Arrays.toString(open) + " " + Arrays.toString(assignment));
return true;
} else {
return false;
}
}
public void print() {
System.out.println(cost);
System.out.println(check());
System.out.println(Arrays.toString(open));
System.out.println(Arrays.toString(assignment));
System.out.println();
}
public void calculate(int[