1. 程式人生 > >演算法實踐-任務排程-最小懲罰演算法-貪心演算法

演算法實踐-任務排程-最小懲罰演算法-貪心演算法

package com.greedy;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class TaskReschedule {
	private List<Task> taskList=new ArrayList<Task>();
	private List<Task> schedulList=new ArrayList<Task>();
	private Map<List<Task>,Integer>memory;
	private int total;
	
	public TaskReschedule(int []ids,int[] finals,int[]punishs)throws Exception{
		if(ids.length!=finals.length&&finals.length!=punishs.length){
			throw new Exception("資料錯誤");
		}
		total=ids.length;
		for(int i=0;i<ids.length;i++){
			Task task=new Task();
			task.id=ids[i];
			task.end=finals[i];
			task.punish=punishs[i];
			taskList.add(task);
		}
		memory=new HashMap<List<Task>,Integer>();
	}
	public int reschedule()throws Exception{
		 return innerReschedul(1);
	}
	public void printOrder(){
		for(int i=0;i<schedulList.size();i++){
			System.out.print(schedulList.get(i).getId());
		}
		System.out.println();
	}
	private int innerReschedul(int time)throws Exception{
		int index=0;
		Task tmp=null;
		int punish=Integer.MAX_VALUE;
		for(int k=0;k<taskList.size();k++){
			tmp=taskList.get(k);
			if(tmp.getEnd()<time){
				continue;
			}
			taskList.remove(k);
			int p=punish(time+1);
			if(punish>p){
				index=k;
				punish=p;
			}
			taskList.add(k, tmp);
		}
		if(taskList.size()==0){
			return punish;
		}
		schedulList.add(taskList.get(index));
		taskList.remove(index);
		innerReschedul(time+1);
		return punish;
	}
	private int punish(int time)throws Exception{
		if(taskList.size()+time!=total+1){
			throw new Exception("error");
		}
		if(memory.get(taskList)!=null){
			return memory.get(taskList);
		}

		boolean restPunish=true;
		for(int i=0;i<taskList.size();i++){
			//System.out.println("taskList.get(i).getEnd()<time:"+taskList.get(i).getId()+"-"+taskList.get(i).getEnd()+"-"+time);
			if(taskList.get(i).getEnd()>=time){
				restPunish=false;
				break;
			}
		}
		
		//System.out.println("=========");
		if(restPunish){
			//System.out.println("punishment-start");
			int punish=0;
			for(int i=0;i<taskList.size();i++){
				//System.out.print(taskList.get(i).getId());
				punish+=taskList.get(i).getPunish();
			}
			//System.out.println();
			//System.out.println("punishment-end");
			return punish;
		}
		Task tmp=null;
		int punish=Integer.MAX_VALUE;
		for(int k=0;k<taskList.size();k++){
			tmp=taskList.get(k);
			if(tmp.getEnd()<time){
				continue;
			}
			taskList.remove(k);
			int p= punish(time+1);
			//System.out.println(time);
			//System.out.println("punish:"+p);
			if(punish>p){
				punish=p;
			}
			taskList.add(k,tmp);
		}
		memory.put(taskList, punish);
		//System.out.println(time);
		//System.out.println("punishTotal:"+punish);
		return punish;
	}
	private static class Task{
		private int id;
		private int end;
		private int punish;
		public int getId() {
			return id;
		}
		public void setId(int id) {
			this.id = id;
		}
		public int getEnd() {
			return end;
		}
		public void setEnd(int end) {
			this.end = end;
		}
		public int getPunish() {
			return punish;
		}
		public void setPunish(int punish) {
			this.punish = punish;
		}
		
		
	}
	public static void main(String[] args)throws Exception {
		int [] id=new int[]{1,2,3,4,5,6,7};
		int []finall=new int[]{4,2,4,3,1,4,6};
		int []punish=new int[]{70,60,50,40,30,20,10};
		TaskReschedule taskReschdule=new TaskReschedule(id,finall,punish);
		System.out.println(taskReschdule.reschedule());
		taskReschdule.printOrder();
	}

}