CFLP

题目

现有若干家工厂,若干个顾客。每个顾客有不同的需求量,每家工厂有不同的容量、不同的开厂成本,对每个顾客也有不同的分派成本。给出这些数据,求关于顾客选择的工厂的一个解,使得总的开厂成本、分派成本尽可能地小。

数据结构

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[
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值