银行家算法(java)

来源:互联网 发布:新闻小偷源码 编辑:程序博客网 时间:2024/05/22 05:28
package com.liuyang.banker;import java.util.Arrays;import java.util.Collections;import java.util.Formatter;import java.util.Iterator;import java.util.LinkedHashMap;import java.util.LinkedList;import java.util.List;import java.util.Map;import java.util.Scanner;import java.util.Set;public class Banker {/**  *//** each sum of source list */private List<Integer> eachNumOfSrc = new LinkedList<Integer>();/** process name and process map */private Map<String, Process> processes = new LinkedHashMap<String, Process>();private List<String> proIdKeys = new LinkedList<String>();/** the current number of available source */private List<Integer> available = new LinkedList<Integer>();//private List<String> SrcNames = new LinkedList<String>();/** the current safe sequence */private List<Integer> safeSequeue = new LinkedList<Integer>();private int numOfSrc; //资源总类数private int numOfPro; // the number of processes/** use the Formatter to control the format of the output */private Formatter formatter = new Formatter(System.out);/** 设置资源总数 */public void setResource(String id, int assign) {eachNumOfSrc.add(assign);available.add(assign);//SrcNames.add(id);numOfSrc++;}/** 设置进程的 Allocation */public void setAllocation(String id, Integer... assign) {for(int i = 0; i < available.size(); i++) {available.set(i, available.get(i) - assign[i]);}List<Integer> list = processes.get(id).getAllocation();Collections.addAll(list, assign);}/** 设置进程的 Max */public void setMax(String id, Integer... assign) {List<Integer> maxlist = new LinkedList<Integer>();Collections.addAll(maxlist, assign);List<Integer> needList = new LinkedList<Integer>();Collections.addAll(needList, assign);Process p = new Process();p.setMax(maxlist);p.setNeed(needList);processes.put(id, p);proIdKeys.add(id);numOfPro++;}/** 进程请求资源 */public boolean request(String id, Integer... requestArray) {Process requestProcess = processes.get(id);if(requestProcess.isCompleted()) {System.err.println("该进程以经完成!\n--------------------------------");return false;}List<Integer> requestLink = new LinkedList<Integer>();Collections.addAll(requestLink, requestArray);System.out.println("请求资源:" + id + " " + requestLink);if(isBeyondNeed(requestProcess.getNeed(), requestLink)) {System.err.println("分配错误:分配大于所需!\n--------------------------------");return false;}if(!isLarge(available, Arrays.asList(requestArray))) {System.err.println("分配错误:可用小于请求!\n--------------------------------");return false;}// is the sum resource of request equals to the need boolean isEqualsNeed = isEqualsNeed(processes.get(id).getNeed(), requestLink);List<Integer> allocation = requestProcess.getAllocation();/** copy the allocation of process and available as temporary lists */List<Integer> tempAllocation = new LinkedList<Integer>(allocation);List<Integer> tempAvailable = new LinkedList<Integer>(available);// tempAva 用来存放式分配后的 available.if(isEqualsNeed) {// flag the process to be completed.requestProcess.setCompleted(true);for(int i = 0; i < available.size(); i++) { //available.set(i, tempAva.get(i)); available.set(i, available.get(i) + requestProcess.getAllocation().get(i)); allocation.set(i, 0); }} else {for(int i = 0; i < available.size(); i++) {available.set(i, available.get(i) - requestArray[i]); allocation.set(i, allocation.get(i) + requestArray[i]); }} if(!isSafe()) { // roll back requestProcess.setCompleted(false); /** is not safe and roll back to the original status */ requestProcess.setAllocation(tempAllocation); available = tempAvailable;  System.out.println("没有找到一个安全序列, 不安全, 没有分配/n--------------------------------");  describeAssigned(null, null, false);return false;} describeAssigned(id, requestLink, true);return true;}// 安全检查,used to terrible, maybe a little better now/** check whether the current is safe */public boolean isSafe() {safeSequeue.clear();boolean[] finish = new boolean[numOfPro];//boolean[] isTempAssign = new boolean[numOfPro];updateNeed();List<Integer> tempMaxAva = new LinkedList<Integer>(available);// god know numOfProfor(int z = 0; z < numOfPro; z++) {for(int i = 0; i < numOfPro; i++) {Process p = processes.get(proIdKeys.get(i));if(finish[i] == false) {//updateNeed();List<Integer> need = p.getNeed();if(isLarge(tempMaxAva, need)) {finish[i] = true;if(!p.isCompleted()) safeSequeue.add(i);updateTempMaxAva(tempMaxAva, p.getAllocation());//isTempAssign[i] = true;}}}}if(!isAllTrue(finish)) {return false;}return true;}/** assert the need resource is equals to the request * @param need resource * @param request resource * @return if equals return true, else return false */private boolean isEqualsNeed(List<Integer> need, List<Integer> request) {for(int i = 0; i < need.size(); i++) {if(need.get(i) != request.get(i)) return false;}return true;}/** print the safe sequence */private void showSafeSequence() {for(int i = 0; i < safeSequeue.size(); i++) {Process p = processes.get(proIdKeys.get(safeSequeue.get(i)));if(!p.isCompleted()) System.out.print(proIdKeys.get(safeSequeue.get(i)));}System.out.println();}/** assert is the sum of request resource is beyond the sum of request * @param need need * @param request request * @return return true if request is bigger than need */private boolean isBeyondNeed(List<Integer> need, List<Integer> request) {for(int i = 0; i < need.size(); i++) {if(need.get(i) < request.get(i)) return true;}return false;}/** update all need of all processes */private void updateNeed() {for(int i = 0; i < numOfPro; i++) {Process process = processes.get(proIdKeys.get(i));for(int j = 0; j < numOfSrc; j++) {int temp = process.getMax().get(j) - process.getAllocation().get(j);process.getNeed().set(j, temp);}}}/** scan is there a safe sequence */private boolean isAllTrue(boolean[] avaSequence) {for(int i = 0; i < avaSequence.length; i++) {if(avaSequence[i] == false) return false;}return true;}/** find a appropriate need resource and update available resource */private void updateTempMaxAva(List<Integer> tempMaxAva, List<Integer> list) {for(int i = 0; i < tempMaxAva.size(); i++) {tempMaxAva.set(i, tempMaxAva.get(i) + list.get(i));}}/** 判断第一个资源是否大于第二个资源 */private boolean isLarge(List<Integer> hopeLarge, List<Integer> hopeSmall) {for(int i = 0; i < hopeLarge.size(); i++) {if(hopeLarge.get(i) < hopeSmall.get(i)) return false;}return true;}/** 打印分配后的状况表, use a Formatter.format is better */private void describe() {int space = numOfSrc*3 > 10 ? numOfSrc*3 + 3 : 15;updateNeed();formatter.format("\t资源情况表:\n%-8.8s %-" + space + "s %-" + space + "s %-" + space + "s\n", "Name", "Max", "Allocation", "Need");formatter.format("%-8.8s %-" + space + "s %-" + space + "s %-" + space + "s\n", "----", "---", "----------", "----");Set<String> set = processes.keySet();for(Iterator<String> it = set.iterator(); it.hasNext();) {String id = it.next();Process process = processes.get(id);if(!process.isCompleted()) {formatter.format("%-8.8s %-" + space + "s %-" + space + "s %-" + space + "s\n", id, process.getMax(), process.getAllocation(), process.getNeed());}}System.out.println("available:" + available);System.out.println("-------------------------------------------------------------------------------------" +"------------------------------------------------------------------------------------");}/** 打印试分配的安全序列表, use a Formatter.format is better */private void describeAssigned(String id, List<Integer> list, boolean isRequest) {int space = numOfSrc*3 > 17 ? numOfSrc*3 + 3 : 17;System.out.print("找到一个安全序列为:"); showSafeSequence(); if(isRequest) System.out.println("分配了一个资源给:" + id + " " + list);formatter.format("\t安全分配表:\n%-8.8s %-" + space + "s %-" + space + "s %-" + space + "s %-" + space + "s %-" + space + "s\n", "Name", "Max", "Allocation", "Need", "Work", "Work + Allocation");formatter.format("%-8.8s %-" + space + "s %-" + space + "s %-" + space + "s %-" + space + "s %-" + space + "s\n", "----", "---", "----------", "----", "----", "-----------------");List<Integer> work = null;List<Integer> workPlusAllo = new LinkedList<Integer>(available);for(int i = 0; i < safeSequeue.size(); i++) {String lId = proIdKeys.get(safeSequeue.get(i));Process process = processes.get(lId);if(!process.isCompleted()) {work = new LinkedList<Integer>(workPlusAllo);for(int j = 0; j < numOfSrc; j++) {workPlusAllo.set(j, workPlusAllo.get(j) + process.getAllocation().get(j));}}if(!process.isCompleted()) {formatter.format("%-8.8s %-" + space + "s %-" + space + "s %-" + space + "s %-" + space + "s %-" + space + "s\n", lId, process.getMax(), process.getAllocation(), process.getNeed(), work, workPlusAllo);}}describe();}/** the entity of process, inner class */private class Process {private String id; private boolean isCompleted = false;private List<Integer> max = new LinkedList<Integer>();private List<Integer> allocation = new LinkedList<Integer>();private List<Integer> need = new LinkedList<Integer>();public String getId() {return id;}public void setId(String id) {this.id = id;}public boolean isCompleted() {return isCompleted;}public void setCompleted(boolean isCompleted) {this.isCompleted = isCompleted;}public List<Integer> getMax() {return max;}public void setMax(List<Integer> max) {this.max = max;}public List<Integer> getAllocation() {return allocation;}public void setAllocation(List<Integer> allocation) {this.allocation = allocation;}public List<Integer> getNeed() {return need;}public void setNeed(List<Integer> need) {this.need = need;}public String toString() {return max.toString() + allocation.toString() + need.toString();}}public static void main(String[] args) {Banker banker = new Banker();Scanner scanner = new Scanner(System.in);System.out.println("请输入资源个数");int src = scanner.nextInt();System.out.println("请输入资源名, 资源个数, 如:\na 7\tb 8\tc 9\td 10 ...");for(int i = 0; i < src; i++) {String id = scanner.next();int assign = scanner.nextInt();banker.setResource(id, assign);}System.out.println("请输入进程名\t请求最大资源数\t分配资源数如:\nA\t\t8 9 5 9\t\t5 3 4 3");while(true) {String name = scanner.next();if("quit".equals(name)) break;Integer[] maxArray = new Integer[src];Integer[] allArray = new Integer[src];for(int i = 0; i < src; i++) {maxArray[i] = scanner.nextInt();}for(int i = 0; i < src; i++) {allArray[i] = scanner.nextInt();}banker.setMax(name, maxArray);banker.setAllocation(name, allArray);}if(banker.isSafe()) {banker.describe();banker.describeAssigned(null, null, false);}while(true) {String id = scanner.next();if("quit".equals(id)) break;Integer[] request = new Integer[src];for(int i = 0; i < src; i++) {request[i] = scanner.nextInt();}banker.request(id, request);}//banker.setResource("q", 10);//banker.setResource("w", 5);//banker.setResource("e", 7);//banker.setMax("A", 7, 5, 3);//banker.setAllocation("A", 0, 1, 0);//banker.setMax("B", 3, 2, 2);//banker.setAllocation("B", 2, 0, 0);//banker.setMax("C", 9, 0, 2);//banker.setAllocation("C", 3, 0, 2);//banker.setMax("D", 2, 2, 2);//banker.setAllocation("D", 2, 1, 1);//banker.setMax("E", 4, 3, 3);//banker.setAllocation("E", 0, 0, 2);//if(banker.isSafe()) {//banker.describe();//banker.describeAssigned(null, null, false);//}//banker.request("B", 1, 0, 2);//System.out.println();////banker.request("B", 0, 2, 0);////banker.request("D", 0, 1, 0);//banker.request("E", 4, 2, 1);//banker.request("D", 0, 0, 1);//banker.request("E", 0, 1, 0);//banker.request("A", 7, 4, 3);}}

原创粉丝点击