銀行家演算法

木人_朽月發表於2020-10-21

封裝類:BankArithmetic

package bank;

import java.io.File;
import java.io.FileInputStream;
import java.util.*;

public class BankArithmetic {

    private static List<Integer> defaultAvailable;
    private static Map<Integer, List<Integer>> need;
    private static Map<Integer, List<Integer>> allocation;
    private static Map<Integer, List<Integer>> max;
    private static int Pi,Ri;

    /**
     *  init
     */
    public static void openArithmetic() throws Exception {
        Properties pt = new Properties();
        pt.load(new FileInputStream(new File(BankArithmetic.class
                .getResource("/").getPath()+ "/bank/BankInput.properties")));

        // input Pi and Ri split by space
        Pi = Integer.valueOf(pt.getProperty("pi"));
        Ri = Integer.valueOf(pt.getProperty("ri"));

        //  input Pi allocation
        allocation = new HashMap<Integer, List<Integer>>();
        for(int i=0; i<Pi; i++){
            List<Integer> ri = new ArrayList<Integer>();
            for(int j=0; j<Ri; j++){
                ri.add(Integer.valueOf(pt.getProperty("p"+i+"allocation").split(",")[j]));
            }
            allocation.put(i,ri);
        }

        //  input Pi max
        max = new HashMap<Integer, List<Integer>>();
        for(int i=0; i<Pi; i++){
            List<Integer> ri = new ArrayList<Integer>();
            for(int j=0; j<Ri; j++){
                ri.add(Integer.valueOf(pt.getProperty("p"+i+"max").split(",")[j]));
            }
            max.put(i,ri);
        }

        //  input Ri residue
        List<Integer> available = new ArrayList<Integer>();
        for(int i=0; i<Ri; i++){
            available.add(Integer.valueOf(pt.getProperty("available").split(",")[i]));
        }

        defaultAvailable = new ArrayList<Integer>(available);

        invokeArithmetic(available);
    }

    /**
     *  prepare to execute
     */
    private static void invokeArithmetic(List<Integer> available){

        need = new HashMap<Integer, List<Integer>>();
        Map<Integer,Boolean> isVisited = new HashMap<Integer,Boolean>();

        //  calculate pi need
        List<Integer> piNeed,piMax,piAllocation;
        for(int pi=0; pi<Pi; pi++){
            isVisited.put(pi,false);
            piNeed = new ArrayList<Integer>();
            piMax = max.get(pi);
            piAllocation = allocation.get(pi);
            for(int ri = 0; ri < Ri; ri++){
                //  need_i = max_i - allocation_i
                piNeed.add(piMax.get(ri)-piAllocation.get(ri));
            }
            need.put(pi,piNeed);
        }

        Queue<Integer> array = new LinkedList<Integer>();

        //  execute
        executeArithmetic(available,array,isVisited);
    }

    /**
     *  bank arithmetic real method
     */
    private static void executeArithmetic(List<Integer> work,Queue<Integer> array
            ,Map<Integer,Boolean> isVisited){

        List<Integer> allow = new ArrayList<Integer>();

        //  find allow
        for(int pi = 0; pi<Pi; pi++){
            boolean isBig = false;
            for(int ri = 0; ri<Ri; ri++){
                //  ri > worki
                if(need.get(pi).get(ri) > work.get(ri)){
                    isBig = true;
                    break;
                }
            }
            if(!isBig && !isVisited.get(pi)){
                allow.add(pi);
            }
        }
        int allowSize = allow.size();
        if(allowSize == 0){
            displayArray(array);
        }
        //
        for(int i=0; i<allowSize; i++){
            int pi = allow.get(i);
            //  for(int ri = 0; ri)
            List<Integer> cwork = new ArrayList<Integer>();
            for (int ri=0; ri<Ri; ri++){
                //  work_i = work_i + allocation_i
                cwork.add(allocation.get(pi).get(ri)+work.get(ri));
            }

            Queue<Integer> carray = new LinkedList<Integer>(array);
            carray.add(pi);

            Map<Integer,Boolean> cisVisited = new HashMap<Integer,Boolean>(isVisited);
            cisVisited.put(pi,true);

            executeArithmetic(cwork,carray,cisVisited);
        }
    }

    /**
     *  display the process
     */
    private static void displayArray(Queue<Integer> array){
        int arraySize = array.size();
        int pi,workSize,needSize,allocationSize;
        List<Integer> work = new ArrayList<Integer>(defaultAvailable);
        System.out.println("Start");
        for(int i=0; i<arraySize; i++){
            pi = array.remove();

            System.out.println("P"+pi+": ");

            System.out.print("work: "+work+" "+"need: "+need.get(pi)+" "+"allocation: "+allocation.get(pi));
            System.out.print(" ");
            System.out.print("work+allocation: [");
            List<Integer> tempWork = new ArrayList<Integer>(work);
            workSize = tempWork.size();
            work.clear();
            for(int j=0; j<workSize; j++){
                System.out.print(tempWork.get(j)+allocation.get(pi).get(j));
                if(j != workSize-1)
                    System.out.print(", ");
                work.add(tempWork.get(j)+allocation.get(pi).get(j));
            }
            System.out.println("]");
        }
        System.out.println("END\n");
    }

}

properties檔案

# pi = $pi 表示有$pi個程式
pi = 5

# ri = $i 表示有$ri個資源
ri = 4

# p(i)allocation = $r0,$r1,$r2,$r3,... 表示pi已經分配了r0資源$r0,r1資源$r1,....

p0allocation = 3,0,1,4
p1allocation = 2,2,1,0
p2allocation = 3,1,2,1
p3allocation = 0,5,1,0
p4allocation = 4,2,1,2

# p(i)max = $r0,$r1,$r2,$r3,... 表示pi最多分配r0資源$r0,r1資源$r1,....

p0max = 5,1,1,7
p1max = 3,2,1,1
p2max = 3,3,2,1
p3max = 4,6,1,2
p4max = 6,3,2,5

# available = $r0,$r1,$r2,$r3,... 表示r0資源還剩下$r0,r1資源還剩下$r1,...
available = 1,0,0,2

目錄結構:
在這裡插入圖片描述

執行:
在這裡插入圖片描述

結果:

在這裡插入圖片描述

相關文章