Intelligent Transportation

来源:互联网 发布:如何做到处事不惊 知乎 编辑:程序博客网 时间:2024/06/03 21:22
package cn.cas.siat.hpc.test;import java.io.BufferedReader;import java.io.IOException;import java.io.InputStreamReader;import java.util.ArrayList;import java.util.HashMap;import java.util.Iterator;import java.util.Map;/** *  * @author sy * @time 2014-12-02 * @description 输入:系统向参赛选手传递当前时段的流量,在args[0]中。 *              流量的格式为:TrafficLightID,FromID,Flow;TrafficLightID,FromID,Flow;.... *              交通图谱结构由参赛选手根据文档中的拓扑图自己构造。 *              如构造成格式为:TrafficLightID,FromID1,ToID1,ToID2,ToID3;TrafficLightID,FromID1,ToID1,ToID2,ToID3;...的字符串 *              输出:使用System.out.println()输出格式为:TrafficLightID,FromID1,leftStatus,rightStatus,straightStatus;TrafficLightID,FromID1,leftStatus,rightStatus,straightStatus;...的字符串 */public class Demo_v1 {//交通拓扑结构字符串,格式为:TrafficLightID,FromID1(来源),ToID1(左转),ToID2(右转),ToID3(直行);TrafficLightID,FromID1,ToID1,ToID2,ToID3;...,不能通行的用#表示private static String traffic_topo_str = "tl44,tl42,tl43,#,tl19;tl44,tl43,tl19,tl42,#;"+ "tl44,tl19,#,tl43,tl42;tl43,tl44,tl41,tl18,#;tl43,tl41,#,tl44,tl18;tl43,tl18,tl44,#,tl41;"+ "tl42,tl26,tl41,#,tl44;tl42,tl41,tl44,tl26,#;tl42,tl44,#,tl41,tl26;tl41,tl42,tl25,tl43,tl40;"+ "tl41,tl25,tl40,tl42,tl43;tl41,tl40,tl43,tl25,tl42;tl41,tl43,tl42,tl40,tl25;tl40,tl41,tl24,tl17,tl39;"+ "tl40,tl24,tl39,tl41,tl17;tl40,tl39,tl17,tl24,tl41;tl40,tl17,tl41,tl39,tl24;tl39,tl40,tl23,tl16,#;"+ "tl39,tl23,#,tl40,tl16;tl39,tl16,tl40,tl23,#;tl38,tl12,tl37,#,tl5;tl38,tl37,tl5,tl12,#;"+ "tl38,tl5,#,tl37,tl12;tl37,tl38,tl11,tl4,tl36;tl37,tl11,tl36,tl38,tl4;tl37,tl36,tl4,tl11,tl38;"+ "tl37,tl4,tl38,tl36,tl11;tl36,tl37,tl10,tl3,#;tl36,tl10,#,tl37,tl3;tl36,tl3,tl37,#,tl10;"+ "tl35,tl52,tl58,tl28,tl34;tl35,tl58,tl34,tl52,tl28;tl35,tl34,tl28,tl58,tl52;tl35,tl28,tl52,tl34,tl58;"+ "tl34,tl35,tl57,tl27,tl33;tl34,tl57,tl33,tl35,tl27;tl34,tl33,tl27,tl57,tl35;tl34,tl27,tl35,tl33,tl57;"+ "tl33,tl34,tl56,tl26,tl32;tl33,tl56,tl32,tl34,tl26;tl33,tl32,tl26,tl56,tl34;tl33,tl26,tl34,tl32,tl56;"+ "tl32,tl33,tl55,tl25,tl31;tl32,tl55,tl31,tl33,tl25;tl32,tl31,tl25,tl55,tl33;tl32,tl25,tl33,tl31,tl55;"+ "tl31,tl32,#,tl24,tl30;tl31,tl30,tl24,#,tl32;tl31,tl24,tl32,tl30,#;tl30,tl31,tl54,tl23,tl29;tl30,tl54,tl29,tl31,tl23;"+ "tl30,tl29,tl23,tl54,tl31;tl30,tl23,tl31,tl29,tl54;tl29,tl30,tl53,tl22,tl51;tl29,tl53,tl51,tl30,tl22;tl29,tl51,tl22,tl53,tl30;"+ "tl29,tl22,tl30,tl51,tl53;tl28,tl35,tl27,#,tl21;tl28,tl27,tl21,tl35,#;tl28,tl21,#,tl27,tl35;tl27,tl28,tl34,tl20,tl26;"+ "tl27,tl34,tl26,tl28,tl20;tl27,tl26,tl20,tl34,tl28;tl27,tl20,tl28,tl26,tl34;tl26,tl27,tl33,tl42,tl25;tl26,tl33,tl25,tl27,tl42;"+ "tl26,tl25,tl42,tl33,tl27;tl26,tl42,tl27,tl25,tl33;tl25,tl26,tl32,tl41,tl24;tl25,tl32,tl24,tl26,tl41;tl25,tl24,tl41,tl32,tl26;"+ "tl25,tl41,tl26,tl24,tl32;tl24,tl25,tl31,tl40,tl23;tl24,tl31,tl23,tl25,tl40;tl24,tl23,tl40,tl31,tl25;tl24,tl40,tl25,tl23,tl31;"+ "tl23,tl24,tl30,tl39,tl22;tl23,tl30,tl22,tl24,tl39;tl23,tl22,tl39,tl30,tl24;tl23,tl39,tl24,tl22,tl30;tl22,tl23,tl29,tl14,#;tl22,tl29,#,tl23,tl14;"+ "tl22,tl14,tl23,#,tl29;tl21,tl28,tl20,#,tl6;tl21,tl20,tl6,tl28,#;tl21,tl6,#,tl20,tl28;tl20,tl21,tl27,#,tl19;tl20,tl27,tl19,tl21,#;tl20,tl19,#,tl27,tl21;"+ "tl19,tl20,tl44,tl12,tl18;tl19,tl44,tl18,tl20,tl12;tl19,tl18,tl12,tl44,tl20;tl19,tl12,tl20,tl18,tl44;tl18,tl19,tl43,tl11,tl17;tl18,tl43,tl17,tl19,tl11;"+ "tl18,tl17,tl11,tl43,tl19;tl18,tl11,tl19,tl17,tl43;tl17,tl18,tl40,tl10,tl16;tl17,tl40,tl16,tl18,tl10;tl17,tl16,tl10,tl40,tl18;tl17,tl10,tl18,tl16,tl40;tl16,tl17,tl39,tl9,tl15;"+ "tl16,tl39,tl15,tl17,tl9;tl16,tl15,tl9,tl39,tl17;tl16,tl9,tl17,tl15,tl39;tl15,tl16,#,tl8,tl14;tl15,tl14,tl8,#,tl16;tl15,tl8,tl16,tl14,#;tl14,tl15,tl22,tl7,#;tl14,tl22,#,tl15,tl7;"+ "tl14,tl7,tl15,#,tl22;tl12,tl19,tl11,#,tl38;tl12,tl11,tl38,tl19,#;tl12,tl38,#,tl11,tl19;tl11,tl12,tl18,tl37,tl10;tl11,tl18,tl10,tl12,tl37;tl11,tl10,tl37,tl18,tl12;tl11,tl37,tl12,tl10,tl18;"+ "tl10,tl11,tl17,tl36,tl9;tl10,tl17,tl9,tl11,tl36;tl10,tl9,tl36,tl17,tl11;tl10,tl36,tl11,tl9,tl17;tl9,tl10,tl16,tl2,tl8;tl9,tl16,tl8,tl10,tl2;tl9,tl8,tl2,tl16,tl10;tl9,tl2,tl10,tl8,tl16;"+ "tl8,tl9,tl15,#,tl7;tl8,tl15,tl7,tl9,#;tl8,tl7,#,tl15,tl9;tl7,tl8,tl14,tl1,tl13;tl7,tl14,tl13,tl8,tl1;tl7,tl13,tl1,tl14,tl8;tl7,tl1,tl8,tl13,tl14;tl1,tl2,tl7,#,tl45;tl1,tl7,tl45,tl2,#;"+ "tl1,tl45,#,tl7,tl2;tl2,tl47,tl3,tl1,tl9;tl2,tl3,tl9,tl47,tl1;tl2,tl9,tl1,tl3,tl47;tl2,tl1,tl47,tl9,tl3;tl3,tl4,tl36,#,tl2;tl3,tl36,tl2,tl4,#;tl3,tl2,#,tl36,tl4;tl4,tl48,tl5,tl3,tl37;tl4,tl5,tl37,tl48,tl3;tl4,tl37,tl3,tl5,tl48;"+ "tl4,tl3,tl48,tl37,tl5;tl5,tl49,tl6,tl4,tl38;tl5,tl6,tl38,tl49,tl4;tl5,tl38,tl4,tl6,tl49;tl5,tl4,tl49,tl38,tl6;tl6,tl50,tl46,tl5,tl21;tl6,tl46,tl21,tl50,tl5;tl6,tl21,tl5,tl46,tl50;tl6,tl5,tl50,tl21,tl46;";    //交通节点信息表,该表每一项是一个交通十字路口(或者T字路口)格式为:TrafficLightID:[FromID1,FromID2,FromID3,FromID4]private static Map<String, String[]> traffic_light_nodes_table = new HashMap<String, String[]>();    //交通拓扑结构表,格式为:TrafficLightID:[FromID1,ToID1(左转),ToID2(右转),ToID3(直行)]private static Map<String, String[]> traffic_light_topo_table = new HashMap<String, String[]>();        //某个时段T(i)所有路口车辆的 转向概率:[左转,右转,直行],初赛写死private static double[] turn_rate = new double[]{0.1,0.1,0.8};    //某个时段T(i)所有路口车辆的 通过率:[左转,右转,直行],初赛写死private static int[] through_rate = new int[]{2,2,16};    //某个时段T(i)所有路口红 绿灯的状态:[左转,右转,直行] (红灯为0,绿等为1,缺失-1)private static Map<String, Integer[]> all_road_best_status = new HashMap<String,Integer[]>();      //某个小时内红绿灯的历史信息private static Map<String, ArrayList<Integer[]>> status_history = new HashMap<String,ArrayList<Integer[]>>();     //某个时段T(i)所有路口的流量private static Map<String, Integer> all_road_current_flow = new HashMap<String,Integer>();    //某个小时第几个时段private static int TIME_I = 0;    //使用随机搜索方式对每个交通路口进行状态搜索的次数private static int SEARCH_NUM = 200;    //违规惩罚系数,初赛写死private static double ZETA = 0.5;      //每一个时间段,系统都会调用一次参赛选手的main函数,以参数的形式向选手传递当前时间段每个路口的流量(args[0])  //按照TrafficLightID,FromID,Flow;TrafficLightID,FromID,Flow;....格式public static void main(String[] args) throws NumberFormatException, IOException{//加载交通拓扑结构loadTrafficTable();//获取当前时刻流量字符串BufferedReader br = new BufferedReader(new InputStreamReader(System.in));//获取某个时段T(i)整个交通输入流量String flows_str = br.readLine();while(!"end".equalsIgnoreCase(flows_str)){//清除上一时刻的状态all_road_best_status.clear();//清除上一时刻的流量all_road_current_flow.clear();//解析当前时刻流量字符串String[] flows = flows_str.trim().split(";");for(String flow:flows){String [] strs = flow.trim().split(",");String key = strs[0]+"-"+strs[1];all_road_current_flow.put(key, Integer.valueOf(strs[2]));}//初始化当前交通状态initCurrentStatus();//随机搜索,取其中最好的状态generateStatus();//获取下一个时间段的流量flows_str = br.readLine();++TIME_I;}}//从交通拓扑结构字符串中解析private static void loadTrafficTable(){String[] lights = traffic_topo_str.trim().split(";");for(String light:lights){String [] strs = light.trim().split(",");String key = strs[0]+"-"+strs[1];if(!traffic_light_nodes_table.containsKey(strs[0])){traffic_light_nodes_table.put(strs[0], new String[]{strs[1],strs[2],strs[3],strs[4]});}traffic_light_topo_table.put(key, new String[]{strs[2],strs[3],strs[4]});}    }//生成状态private static void generateStatus() throws IOException{//十字路口最好的状态Map<String, Integer[]> best_status = new HashMap<String, Integer[]>();// 当前十字或者T字路口各个路口灯的状态Map<String, Integer[]> current_traffic_status = new HashMap<String, Integer[]>();//遍历每个交通路口(十字路口或者T字路口)Iterator<?> iter1 = traffic_light_nodes_table.entrySet().iterator();while (iter1.hasNext()) {//该十字路口最好的状态的目标函数值double best_penalty = Integer.MAX_VALUE;//清空best_status.clear();//获取TrafficLightID,FromIDsMap.Entry<String, String[]> entry1 = (Map.Entry<String, String[]>) iter1.next();//获取交通路口中心idString traffic_light_id = (String) entry1.getKey();//获取各个方向idString[] from_ids = (String[]) entry1.getValue();//对每个十字路口使用随机搜索search_num次,选择最好的一次for (int search_i = 0; search_i < SEARCH_NUM; ++search_i) {current_traffic_status.clear();for(String from_id:from_ids){//有路的方向if(!"#".equals(from_id)){   //构造key   String key = traffic_light_id+"-"+from_id;   //该路口可以通向的三个方向,分别为左转、右转、直行   String[] destinations = traffic_light_topo_table.get(key);   //左转、右转、直行3个转态,0表示红灯,1表示绿灯,-1表示无路可走   Integer[] status = new Integer[3];   for (int idx = 0; idx < 3; ++idx) {    if ("#".equals(destinations[idx])) {    status[idx] = -1;    }    else {    if(idx==1){    //局部版本右转总是可以的        status[idx] = 1;    }else{    //随机,50%概率为绿灯        status[idx] = randomStatus();    }        }    }   //存储当前得到的转态   current_traffic_status.put(key, status);}}//更新状态表setStatus(current_traffic_status);//计算该转态下的目标值double penalty = computePenalty(current_traffic_status);//选择目标值最小的转态if (best_penalty > penalty) {best_penalty = penalty;for(String k:current_traffic_status.keySet()){best_status.put(k,current_traffic_status.get(k));}}}//更新状态表setStatus(best_status);Iterator<?> iter2 = best_status.entrySet().iterator();while(iter2.hasNext()){Map.Entry<String, Integer[]> entry2 = (Map.Entry<String, Integer[]>) iter2.next();all_road_best_status.put(entry2.getKey(), entry2.getValue());}}//输出状态printCurrentStatus();}    //产生随机状态private static int randomStatus(){        double rand = Math.random();        if(rand>=0.5){        return 1;        }        else{        return 0;        }    }    //根据status_history、all_road_current_flow计算T(i)时刻某路口滞留车辆数private static int computeStay(String key) {    //左转右转直行实际能够通过的车辆数  int left_through,right_through,straight_through;  left_through = right_through =  straight_through = 0;    //判断是十字路口还是T字路口,-1:三个方向都可以走的路口,0:不能左转的路口,1:不能右转的路口,2:不能直行的路口  int turn_flag = -1;      //绿灯时通过率才有效  int status = status_history.get(key).get(TIME_I)[0];  if (status==1) {  left_through = through_rate[0];  }else if(status==-1){  turn_flag = 0;  }  status = status_history.get(key).get(TIME_I)[0];  if (status_history.get(key).get(TIME_I)[1]==1) {  right_through = through_rate[1];  }else if(status==-1){  turn_flag = 1;  }  status = status_history.get(key).get(TIME_I)[0];  if (status_history.get(key).get(TIME_I)[2]==1) {  straight_through = through_rate[2];  }else if(status==-1){  turn_flag = 2;  }    //获取当前时段该路口的流量  int i_flow = all_road_current_flow.get(key);        //左转右转直行的滞留车辆  int left_stay,right_stay,straight_stay;  left_stay = right_stay = straight_stay = 0;    //如果是T字路口,则需要改变通行率  double left_rate = turn_rate[0];  double right_rate = turn_rate[1];  double straight_rate = turn_rate[2];  switch(turn_flag){      case 0:      right_rate += left_rate;      left_rate = 0;      break;      case 1:      left_rate += right_rate;      right_rate = 0;      break;      case 2:      left_rate += straight_rate*0.5;      right_rate += straight_rate*0.5;      straight_rate = 0;      break;      default:      break;  }  //上取整可能会导致流量增大一点  left_stay = Math.max(0, (int)Math.ceil(i_flow*left_rate) - left_through);  right_stay = Math.max(0, (int)Math.ceil(i_flow*right_rate) - right_through);  straight_stay = Math.max(0,(int)Math.ceil(i_flow*straight_rate)-straight_through);    //返回T(i)时刻滞留车辆数  return (left_stay + right_stay + straight_stay);  }      //根据currentStatus计算penalty,该方法只计算某一个十字路口(或则交通路口)private static double computePenalty(Map<String, Integer[]> current_traffic_status){      //代价      double penalty = 0;// 每个路口T(i)时刻penalty: 左转滞留+右转滞留+直行滞留;违反交通规则扣分;违反公平性原则扣分for (String key : current_traffic_status.keySet()) {// 更新,车辆滞留部分penalty += computeStay(key);// 更新,加上红绿灯违反交通规则的惩罚 a:直行垂直直行惩罚 b:直行垂直左转惩罚double a, b;a = b = 0;String[] lights = key.split("-");String left_key = lights[0] + "-" + traffic_light_topo_table.get(key)[0];String right_key = lights[0] + "-" + traffic_light_topo_table.get(key)[1];// 垂直方向不能同时直行if (current_traffic_status.get(key)[2] == 1 && ((current_traffic_status.containsKey(left_key) && current_traffic_status.get(left_key)[2] == 1) || (current_traffic_status.containsKey(right_key)&& current_traffic_status.get(right_key)[2] == 1))) {    a += ZETA * all_road_current_flow.get(key);if (current_traffic_status.containsKey(left_key)) {a += ZETA * all_road_current_flow.get(left_key);}if (current_traffic_status.containsKey(right_key)) {a += ZETA * all_road_current_flow.get(right_key);    }}// 直行时垂直方向右侧不能左转if (current_traffic_status.get(key)[2] == 1&& current_traffic_status.containsKey(right_key) && current_traffic_status.get(right_key)[0] == 1) {b += ZETA* (all_road_current_flow.get(right_key) +all_road_current_flow.get(key));} // 违规扣分penalty += (0.5*a + b);// 更新,加上违反公平原则扣分 v*sqrt(r-4)if (TIME_I > 3) {for (int j = 0; j < 3; j++) {if (status_history.get(key).get(TIME_I)[j] == 0) {int waitTime = 1;int waitStart = TIME_I;while (waitStart>0&&status_history.get(key).get(waitStart - 1)[j] == 0) {waitTime += 1;waitStart -= 1;}penalty += Math.ceil(all_road_current_flow.get(key)* Math.sqrt(Math.max(waitTime - 4, 0)));}}}}return penalty;    }  //输出当前整个交通状态字符串  //格式为:TrafficLightID,FromID,LeftStatus,RightStatus,StraightStatus;TrafficLightID,FromID,LeftStatus,RightStatus,StraightStatus;...private static void printCurrentStatus() throws IOException{  Iterator<Map.Entry<String, Integer[]>> it = all_road_best_status.entrySet().iterator();  StringBuilder sb = new StringBuilder();  while(it.hasNext()){  Map.Entry<String, Integer[]> entry = (Map.Entry<String, Integer[]>)it.next();  String[] keyStrs = entry.getKey().split("-");  Integer[] status = entry.getValue();      //TrafficLightID,FromID  sb.append(keyStrs[0]+","+keyStrs[1]);  for(int s:status){  sb.append(","+s);  }  sb.append(";");  }  String status_str = sb.toString();  System.out.println(status_str);  }          //初始化当前时间段的状态private static void initCurrentStatus(){    for(String key:traffic_light_topo_table.keySet()){    Integer[] status = new Integer[]{-1,-1,-1};    if(status_history.containsKey(key)){    status_history.get(key).add(status);    }else{    ArrayList<Integer[]> status_array = new ArrayList<Integer[]>();status_array.add(status);status_history.put(key, status_array);    }    }    }        //设置当前时间段某个交通灯(交通十字路口或者T字路口)的状态private static void setStatus(Map<String, Integer[]> aStatus) {for(String key :aStatus.keySet()){//左转status_history.get(key).get(TIME_I)[0] = aStatus.get(key)[0];//右转status_history.get(key).get(TIME_I)[1] = aStatus.get(key)[1];//直行status_history.get(key).get(TIME_I)[2] = aStatus.get(key)[2];}}    }
<pre name="code" class="java">package cn.cas.siat.hpc.test; /* *  * [贵州智慧交通]penalty计算及流量更新源代码  * 这份源代码包含了每个时刻流量更新和计算penalty的逻辑 * 方便大家理解赛题,同时官网没有详细说明的参数代码中 * 有明确设置包括:   1)每个路口的转向概率  turnRate [左转[font='Microsoft YaHei']α,右转β,直行γ]   2)每个路口的通过率  throughRate[左转,右转,直行]   3)交通违规惩罚倍数ZETA */import java.io.IOException;import java.util.ArrayList;import java.util.List;import java.util.Map;import java.util.concurrent.ConcurrentHashMap;import com.google.common.collect.Lists;public class Grade {//从Traffic_Light_Table.txt读取所有路口红绿灯位置关系信息static Map<String, String[]> trafficLightTable = new ConcurrentHashMap<String, String[]>();//所有路口某个小时的静态流量表和动态流量表(数组长度为120)static Map<String, Integer[]> staticFlowTable = new ConcurrentHashMap<String,Integer[]>();static Map<String, Integer[]> dynamicFlowTable = new ConcurrentHashMap<String,Integer[]>();//传出给选手参数:某个小时某个时段T(i)所有路口的车流量static Map<String, Integer> currentFlows = new ConcurrentHashMap<String,Integer>();//传出给选手参数:某个时段T(i)所有路口车辆的 转向概率:[左转,右转,直行]static Map<String, Double[]> turnRate = new ConcurrentHashMap<String,Double[]>();//传出给选手参数:某个时段T(i)所有路口车辆的 通过率:[左转,右转,直行]static Map<String, Integer[]> throughRate = new ConcurrentHashMap<String,Integer[]>();//选手传入参数:某个时段T(i)所有路口红 绿灯的状态:[左转,右转,直行] (红灯为0,绿等为1,缺失-1)static Map<String, Integer[]> currentStatus = new ConcurrentHashMap<String,Integer[]>();//某个小时内红绿灯的历史信息static Map<String, ArrayList<Integer[]>> statusHistory = new ConcurrentHashMap<String,ArrayList<Integer[]>>();//14个小时的penalty//所有taskId对应的penaltypublic static Map<String, Double[]> penaltyMap =  new ConcurrentHashMap<String, Double[]>();public static boolean inited = false;//初始化每个选手对应的penalty数组public static void initPenalty(String taskId) {Double[] penalty = {0.0,0.0,0.0,0.0,                             0.0,0.0,0.0,0.0,                             0.0,0.0,0.0,0.0,0.0,0.0};penaltyMap.put(taskId, penalty);}//从trafficLightTable读取红绿灯位置信息public static void setLightInfo(String taskId, Map<String, String[]> trafficLightMap){for (String aKey : trafficLightMap.keySet()) {String[] keyStrings = aKey.split("-");String taks_key = keyStrings[0] + "-" + keyStrings[1] + "-" + taskId;trafficLightTable.put(taks_key,trafficLightMap.get(aKey));}}// 第i个小时状态初始化public static void hourInit(String taskId, Map<String, Integer[]> trafficFlowMap,int i) throws NumberFormatException, IOException {for (String aKey : trafficFlowMap.keySet()) {String[] keyStrings = aKey.split("-");String taks_key = keyStrings[0] + "-" + keyStrings[1] + "-" + taskId;  Integer[] values = new Integer[120];  for (int i1 = 0; i1 < values.length; i1++) { values[i1] = trafficFlowMap.get(aKey)[i*120 + i1];}staticFlowTable.put(taks_key,values);dynamicFlowTable.put(taks_key,values.clone());}//初始化turnRate:[0.1,0.1,0.8]、throughRate:[2,2,16]、statusHistoryfor(String key : trafficLightTable.keySet()){if(!taskId.equals(key.split("-")[2])){continue;}//十字路口转向概率Double[] initTurnRate = {0.1,0.1,0.8};//丁字路口,无左转方向if (trafficLightTable.get(key)[0].equals("#")) {initTurnRate[1] += initTurnRate[0];initTurnRate[0] -= initTurnRate[0];}else if (trafficLightTable.get(key)[1].equals("#")) {//丁字路口,无右转方向initTurnRate[0] += initTurnRate[1];initTurnRate[1] -= initTurnRate[1];}else if (trafficLightTable.get(key)[2].equals("#")) {//丁字路口,无直行方向initTurnRate[0] += initTurnRate[2]*0.5;initTurnRate[1] += initTurnRate[2]*0.5;initTurnRate[2] -= initTurnRate[2];}Integer[] initThroughRate = {2,2,16};ArrayList<Integer[]> initStatusHistory = new ArrayList<Integer[]>();for (int j = 0; j < 120; j++) {Integer[] aStatus = {0,0,0};if ("#".equals(trafficLightTable.get(key)[0])) {aStatus[0] = -1;}else if ("#".equals(trafficLightTable.get(key)[1])) {aStatus[1] = -1;}else if ("#".equals(trafficLightTable.get(key)[2])) {aStatus[2] = -1;}initStatusHistory.add(aStatus);}turnRate.put(key, initTurnRate);throughRate.put(key, initThroughRate);statusHistory.put(key, initStatusHistory);}}//根据最近一段时间红绿历史状态表计算转向概率[ALPHA,BETA,GAMMA],初赛为固定值不更新public static void updateTurnRate() {/**for (String key : statusHistory.keySet()) {Double[] rate = {0.1,0.1,0.8};turnRate.put(key, rate);}*/}//根据路口车流量计算车辆通过率[TH1,TH2,TH3],初赛通过率固定值为不更新public static void updateThroughRate() {/**for(String key : currentFlows.keySet()){Integer[] rate = {5,5,20};throughRate.put(key, rate);}*/}//选手传入参数:第i时刻currentStatus,更新到statusHistorypublic static void setCurrentStatus(Map<String, Integer[]> aStatus,int i) {//currentStatus = aStatus;for(String key :aStatus.keySet()){if (statusHistory.containsKey(key)) {for (int j = 0; j < 3; j++) {if ("#".equals(trafficLightTable.get(key)[j])) {//如果路口不通,强制将灯设置为-1statusHistory.get(key).get(i)[j] = -1;} else {//如果路口是通的,不允许选手将灯设置为-1statusHistory.get(key).get(i)[j] = Math.max(0, aStatus.get(key)[j]);}}}}}//根据statusHistory(i)、dynamicFlowTable(i)计算T(i)时刻某路口滞留车辆数public static int computeStay(String key, int i) {//左转右转直行实际能够通过的车辆数int leftThrough,rightThrough,straightThrough;leftThrough=rightThrough=straightThrough = 0;//绿灯时通过率才有效if (statusHistory.get(key).get(i)[0]==1) {leftThrough = throughRate.get(key)[0];}if (statusHistory.get(key).get(i)[1]==1) {rightThrough = throughRate.get(key)[1];}if (statusHistory.get(key).get(i)[2]==1) {straightThrough = throughRate.get(key)[2];}//dynamicFlow(i)int iFlow = dynamicFlowTable.get(key)[i];//左转右转直行的滞留车辆int leftStay,rightStay,straightStay;leftStay = rightStay = straightStay = 0;double leftRate = turnRate.get(key)[0];double rihgtRate = turnRate.get(key)[1];double straightRate = turnRate.get(key)[2];//上取整可能会导致流量增大一点leftStay = Math.max(0, (int)Math.ceil(iFlow*leftRate) - leftThrough);rightStay = Math.max(0, (int)Math.ceil(iFlow*rihgtRate) - rightThrough);straightStay = Math.max(0,(int)Math.ceil(iFlow*straightRate)-straightThrough);//LOGGER.error("key="+key+",i="+i+",leftStay="+leftStay+",rightStay="+rightStay+",straightStay="+straightStay);//返回T(i)时刻滞留车辆数//System.out.println("allStay===" +(leftStay + rightStay + straightStay));return (leftStay + rightStay + straightStay);}/*根据红绿灯位置信息表、T(i-1)时段的:车流量、所有红绿灯状态、车辆转向概率、车辆通过率      *计算T(i)时刻车流量     *dynamicFlowTable(i)=LAMADA*staticFlowTable(i) + G(trafficLightTable,statusHistory(i-1),dynamicFlowTable(i-1),turnRate(i-1),throughRate(i-1))     */public static void updateDynamicFlowTable(String taskId, int i) {for(String key :dynamicFlowTable.keySet()){    String tId = key.split("-")[2];    if (tId.equals(taskId)) {if (i==0) {    dynamicFlowTable.get(key)[i] =  staticFlowTable.get(key)[i];} else {//观察值系数LAMADAdouble LAMADA = 0.5;//更新flow,加上系数LAMADA*staticFlow(i)dynamicFlowTable.get(key)[i] = (int)(Math.floor(LAMADA*staticFlowTable.get(key)[i]));//结合statusHistory(i-1)加上 dynamicFlow(i-1)的 左转滞留+右转滞留+直行滞留int allStay = 0;//优化代码用函数实现allStay = computeStay(key, i-1);//更新,加上滞留车辆dynamicFlowTable.get(key)[i] += allStay;//加上FromID从其他路口流入的车辆int flowIn1,flowIn2,flowIn3;flowIn1 = flowIn2 = flowIn3 = 0;//反向路径IDString[] keyStrings = key.split("-");String antiKey = keyStrings[1] + "-" + keyStrings[0] + "-" + taskId;//反向路径存在于trafficLightTable中才有意义if (trafficLightTable.containsKey(antiKey)) {//流入车辆的来源IDString antiLeftID = trafficLightTable.get(antiKey)[0];String antiRightID = trafficLightTable.get(antiKey)[1];String antiStraightID = trafficLightTable.get(antiKey)[2];String antiLeftKey = keyStrings[1]  + "-" + antiLeftID + "-" + keyStrings[2];String antiRightKey = keyStrings[1] + "-" + antiRightID + "-" + keyStrings[2];String antiStraightKey = keyStrings[1] + "-" + antiStraightID + "-" + keyStrings[2];//从 antiLeftID 右转流入if (!(trafficLightTable.get(antiLeftKey)==null)&&(statusHistory.get(antiLeftKey).get(i-1)[1]==1)) {flowIn1 = Math.min(throughRate.get(antiLeftKey)[1], (int)Math.ceil(dynamicFlowTable.get(antiLeftKey)[i-1]*turnRate.get(antiLeftKey)[1]));}//从 antiRightID 左转流入if (!(trafficLightTable.get(antiRightKey)==null)&&(statusHistory.get(antiRightKey).get(i-1)[0]==1)) {flowIn2 = Math.min(throughRate.get(antiRightKey)[0], (int)Math.ceil(dynamicFlowTable.get(antiRightKey)[i-1]*turnRate.get(antiRightKey)[0]));}//从 antiStraightKey 直行流入if(!(trafficLightTable.get(antiStraightKey)==null)&&(statusHistory.get(antiStraightKey).get(i-1)[2]==1)){flowIn3 = Math.min(throughRate.get(antiStraightKey)[2], (int)Math.ceil(dynamicFlowTable.get(antiStraightKey)[i-1]*turnRate.get(antiStraightKey)[2]));}}//更新,加上流入车辆dynamicFlowTable.get(key)[i] += flowIn1 + flowIn2 + flowIn3;//System.out.println("  " + key +"-" + i + " flow:" +dynamicFlowTable.get(key)[i] );}}}}//用 dynamicFlowTable 设置 currentFlow 传出给选手public static Map<String, Integer> getCurrentFlow(String taskId, int i){for(String key : dynamicFlowTable.keySet()){if (taskId.equals(key.split("-")[2])) {currentFlows.put(key, dynamicFlowTable.get(key)[i]);}}return currentFlows;}//根据currentStatus(i)更新第k个小时penaltypublic static void updatePenalty(String taskId,int i,int k){//每个路口T(i)时刻penalty: 左转滞留+右转滞留+直行滞留;违反交通规则扣分;违反公平性原则扣分for(String key : dynamicFlowTable.keySet()){String[] lights = key.split("-");if (taskId.equals(lights[2])) {//更新,车辆滞留部分penaltyMap.get(taskId)[k] += computeStay(key, i);//更新,加上红绿灯违反交通规则的惩罚 a:直行垂直直行惩罚 b:直行垂直左转惩罚double a,b;a=b=0.0;//交通违规的惩罚倍数double zeta =0.5;String leftKey = lights[0] + "-" + trafficLightTable.get(key)[0] + "-" + lights[2];String rightKey = lights[0] + "-" + trafficLightTable.get(key)[1] + "-" + lights[2];//垂直方向不能同时直行if (statusHistory.get(key).get(i)[2]==1 &&((statusHistory.containsKey(leftKey) && statusHistory.get(leftKey).get(i)[2]==1) || (statusHistory.containsKey(rightKey) && statusHistory.get(rightKey).get(i)[2]==1))) {a += zeta*dynamicFlowTable.get(key)[i];if (dynamicFlowTable.containsKey(leftKey)) {a += zeta*dynamicFlowTable.get(leftKey)[i];}if (dynamicFlowTable.containsKey(rightKey)) {a += zeta*dynamicFlowTable.get(rightKey)[i];}}//直行时垂直方向右侧不能左转if (statusHistory.get(key).get(i)[2]==1 && statusHistory.containsKey(rightKey) && statusHistory.get(rightKey).get(i)[0]==1) {b += zeta*(dynamicFlowTable.get(rightKey)[i] + dynamicFlowTable.get(key)[i]);}//违规扣分penaltyMap.get(taskId)[k] += 0.5*a + b;//更新,加上违反公平原则扣分 v*sqrt(r-4)if (i>3) {for (int j = 0; j < 3; j++) {if (statusHistory.get(key).get(i)[j]==0) {int waitTime = 1;int waitStart = i;//修改bugwhile ((waitStart>0) && statusHistory.get(key).get(waitStart-1)[j]==0) {waitTime += 1;waitStart -=1;}penaltyMap.get(taskId)[k] += (int)Math.ceil(dynamicFlowTable.get(key)[i]*Math.sqrt(Math.max(waitTime-4, 0)));}}}}}//System.out.println(k + "th hour" + i + "th Penalty======" + penaltyMap.get(taskId)[k]);}//清除某个用户的缓存数据public static void cleanCache(String taskId) {List<String> list = Lists.newArrayList(trafficLightTable.keySet());for(String key : list){String[] keyStrings = key.split("-");if (keyStrings[2].equals(taskId)) {trafficLightTable.remove(key);staticFlowTable.remove(key);dynamicFlowTable.remove(key);turnRate.remove(key);throughRate.remove(key);statusHistory.remove(key);}}penaltyMap.remove(taskId);}//输出选手最终得分public static int getGrade(String taskId) {if (penaltyMap.containsKey(taskId)) {int score = 0;for (int i = 0; i < penaltyMap.get(taskId).length; i++) {score += penaltyMap.get(taskId)[i];}            //清缓存数据cleanCache(taskId);            System.out.println("returnSumScore====" + score);return score;} else {//出异常的选手得分为-1return -1;}}}
<pre name="code" class="java">BaseStatus.java 
package cn.cas.siat.hpc.test;import java.io.BufferedReader;import java.io.BufferedWriter;import java.io.File;import java.io.FileWriter;import java.io.IOException;import java.io.InputStreamReader;import java.util.ArrayList;import java.util.HashMap;import java.util.Map;public class BaseStatus {//拓扑关系文件转化成的字符串private static String tupoString = "tl44,tl42,tl43,#,tl19;tl44,tl43,tl19,tl42,#;tl44,tl19,#,tl43,tl42;tl43,tl44,tl41,tl18,#;tl43,tl41,#,tl44,tl18;tl43,tl18,tl44,#,tl41;tl42,tl26,tl41,#,tl44;tl42,tl41,tl44,tl26,#;tl42,tl44,#,tl41,tl26;tl41,tl42,tl25,tl43,tl40;tl41,tl25,tl40,tl42,tl43;tl41,tl40,tl43,tl25,tl42;tl41,tl43,tl42,tl40,tl25;tl40,tl41,tl24,tl17,tl39;tl40,tl24,tl39,tl41,tl17;tl40,tl39,tl17,tl24,tl41;tl40,tl17,tl41,tl39,tl24;tl39,tl40,tl23,tl16,#;tl39,tl23,#,tl40,tl16;tl39,tl16,tl40,tl23,#;tl38,tl12,tl37,#,tl5;tl38,tl37,tl5,tl12,#;tl38,tl5,#,tl37,tl12;tl37,tl38,tl11,tl4,tl36;tl37,tl11,tl36,tl38,tl4;tl37,tl36,tl4,tl11,tl38;tl37,tl4,tl38,tl36,tl11;tl36,tl37,tl10,tl3,#;tl36,tl10,#,tl37,tl3;tl36,tl3,tl37,#,tl10;tl35,tl52,tl58,tl28,tl34;tl35,tl58,tl34,tl52,tl28;tl35,tl34,tl28,tl58,tl52;tl35,tl28,tl52,tl34,tl58;tl34,tl35,tl57,tl27,tl33;tl34,tl57,tl33,tl35,tl27;tl34,tl33,tl27,tl57,tl35;tl34,tl27,tl35,tl33,tl57;tl33,tl34,tl56,tl26,tl32;tl33,tl56,tl32,tl34,tl26;tl33,tl32,tl26,tl56,tl34;tl33,tl26,tl34,tl32,tl56;tl32,tl33,tl55,tl25,tl31;tl32,tl55,tl31,tl33,tl25;tl32,tl31,tl25,tl55,tl33;tl32,tl25,tl33,tl31,tl55;tl31,tl32,#,tl24,tl30;tl31,tl30,tl24,#,tl32;tl31,tl24,tl32,tl30,#;tl30,tl31,tl54,tl23,tl29;tl30,tl54,tl29,tl31,tl23;tl30,tl29,tl23,tl54,tl31;tl30,tl23,tl31,tl29,tl54;tl29,tl30,tl53,tl22,tl51;tl29,tl53,tl51,tl30,tl22;tl29,tl51,tl22,tl53,tl30;tl29,tl22,tl30,tl51,tl53;tl28,tl35,tl27,#,tl21;tl28,tl27,tl21,tl35,#;tl28,tl21,#,tl27,tl35;tl27,tl28,tl34,tl20,tl26;tl27,tl34,tl26,tl28,tl20;tl27,tl26,tl20,tl34,tl28;tl27,tl20,tl28,tl26,tl34;tl26,tl27,tl33,tl42,tl25;tl26,tl33,tl25,tl27,tl42;tl26,tl25,tl42,tl33,tl27;tl26,tl42,tl27,tl25,tl33;tl25,tl26,tl32,tl41,tl24;tl25,tl32,tl24,tl26,tl41;tl25,tl24,tl41,tl32,tl26;tl25,tl41,tl26,tl24,tl32;tl24,tl25,tl31,tl40,tl23;tl24,tl31,tl23,tl25,tl40;tl24,tl23,tl40,tl31,tl25;tl24,tl40,tl25,tl23,tl31;tl23,tl24,tl30,tl39,tl22;tl23,tl30,tl22,tl24,tl39;tl23,tl22,tl39,tl30,tl24;tl23,tl39,tl24,tl22,tl30;tl22,tl23,tl29,tl14,#;tl22,tl29,#,tl23,tl14;tl22,tl14,tl23,#,tl29;tl21,tl28,tl20,#,tl6;tl21,tl20,tl6,tl28,#;tl21,tl6,#,tl20,tl28;tl20,tl21,tl27,#,tl19;tl20,tl27,tl19,tl21,#;tl20,tl19,#,tl27,tl21;tl19,tl20,tl44,tl12,tl18;tl19,tl44,tl18,tl20,tl12;tl19,tl18,tl12,tl44,tl20;tl19,tl12,tl20,tl18,tl44;tl18,tl19,tl43,tl11,tl17;tl18,tl43,tl17,tl19,tl11;tl18,tl17,tl11,tl43,tl19;tl18,tl11,tl19,tl17,tl43;tl17,tl18,tl40,tl10,tl16;tl17,tl40,tl16,tl18,tl10;tl17,tl16,tl10,tl40,tl18;tl17,tl10,tl18,tl16,tl40;tl16,tl17,tl39,tl9,tl15;tl16,tl39,tl15,tl17,tl9;tl16,tl15,tl9,tl39,tl17;tl16,tl9,tl17,tl15,tl39;tl15,tl16,#,tl8,tl14;tl15,tl14,tl8,#,tl16;tl15,tl8,tl16,tl14,#;tl14,tl15,tl22,tl7,#;tl14,tl22,#,tl15,tl7;tl14,tl7,tl15,#,tl22;tl12,tl19,tl11,#,tl38;tl12,tl11,tl38,tl19,#;tl12,tl38,#,tl11,tl19;tl11,tl12,tl18,tl37,tl10;tl11,tl18,tl10,tl12,tl37;tl11,tl10,tl37,tl18,tl12;tl11,tl37,tl12,tl10,tl18;tl10,tl11,tl17,tl36,tl9;tl10,tl17,tl9,tl11,tl36;tl10,tl9,tl36,tl17,tl11;tl10,tl36,tl11,tl9,tl17;tl9,tl10,tl16,tl2,tl8;tl9,tl16,tl8,tl10,tl2;tl9,tl8,tl2,tl16,tl10;tl9,tl2,tl10,tl8,tl16;tl8,tl9,tl15,#,tl7;tl8,tl15,tl7,tl9,#;tl8,tl7,#,tl15,tl9;tl7,tl8,tl14,tl1,tl13;tl7,tl14,tl13,tl8,tl1;tl7,tl13,tl1,tl14,tl8;tl7,tl1,tl8,tl13,tl14;tl1,tl2,tl7,#,tl45;tl1,tl7,tl45,tl2,#;tl1,tl45,#,tl7,tl2;tl2,tl47,tl3,tl1,tl9;tl2,tl3,tl9,tl47,tl1;tl2,tl9,tl1,tl3,tl47;tl2,tl1,tl47,tl9,tl3;tl3,tl4,tl36,#,tl2;tl3,tl36,tl2,tl4,#;tl3,tl2,#,tl36,tl4;tl4,tl48,tl5,tl3,tl37;tl4,tl5,tl37,tl48,tl3;tl4,tl37,tl3,tl5,tl48;tl4,tl3,tl48,tl37,tl5;tl5,tl49,tl6,tl4,tl38;tl5,tl6,tl38,tl49,tl4;tl5,tl38,tl4,tl6,tl49;tl5,tl4,tl49,tl38,tl6;tl6,tl50,tl46,tl5,tl21;tl6,tl46,tl21,tl50,tl5;tl6,tl21,tl5,tl46,tl50;tl6,tl5,tl50,tl21,tl46" ;private static Map<String,String[]> trafficLightMap= new HashMap<String,String[]>();private static Map<String, Integer[]> trafficStatus= new HashMap<String,Integer[]>();private static Map<String, Integer[]> currentStatus= new HashMap<String,Integer[]>();public static void main(String[] args) throws NumberFormatException, IOException{int count = 0;initTrafficLightMap();initStatus();BufferedReader br = new BufferedReader(new InputStreamReader(System.in));String flows_str = br.readLine();while(!"end".equalsIgnoreCase(flows_str)){if (count%120==0) {//每个小时红绿灯状态复位currentStatus = trafficStatus;}else {//每个新的时刻,翻转红绿灯状态for (String aKey : currentStatus.keySet()) {for (int i = 0; i < 3; i++) {if (currentStatus.get(aKey)[i]==0) {currentStatus.get(aKey)[i] = 1;}else if (currentStatus.get(aKey)[i]==1) {currentStatus.get(aKey)[i] = 0;}}}}String statusString =  geneStatusString(currentStatus);System.out.println(statusString);flows_str = br.readLine();count += 1;}}//初始化拓扑关系表private static void initTrafficLightMap() {String[] pathStrings = tupoString.split(";");for (String aPathString : pathStrings) {String[] aStrings = aPathString.split(",");String aKey = aStrings[0] + "-" + aStrings[1];String[] aValue = {aStrings[2],aStrings[3],aStrings[4]};trafficLightMap.put(aKey, aValue);}}//通过多次扫描,在不违反交通规则的前提下,最大化绿灯个数,作为红绿灯初始状态表private static void initStatus() {for (String aKey : trafficLightMap.keySet()) {Integer[] aStatus = {0,0,0};if ("#".equals(trafficLightMap.get(aKey)[0])) {aStatus[0] = -1;}else if ("#".equals(trafficLightMap.get(aKey)[1])) {aStatus[1] = -1;}else if ("#".equals(trafficLightMap.get(aKey)[2])) {aStatus[2] = -1;}trafficStatus.put(aKey, aStatus);}//遍历 trafficStatus 10次,最大化红灯个数设置红绿灯初始状态表int refreshCount = 10;for (int i = 0; i < refreshCount; i++) {for (String aKey : trafficStatus.keySet()) {for (int j = 0; j < 3; j++) {if (trafficStatus.get(aKey)[j]==0) {trafficStatus.get(aKey)[j] = 1;if(!isLegal(trafficStatus)){trafficStatus.get(aKey)[j] = 0;}}}}}}//检查红绿灯设置状态是否合法private static boolean isLegal(Map<String, Integer[]> aStatus) {boolean flag = true;for (String aKey : aStatus.keySet()) {for (int i = 0; i < 3; i++) {if (aStatus.get(aKey)[i]==1) {String targetLight = aKey.split("-")[0];String leftLight = trafficLightMap.get(aKey)[0];String rightLight = trafficLightMap.get(aKey)[1];String leftKey = targetLight + "-" + leftLight;String rightKey = targetLight + "-" + rightLight;//违规情况:1)垂直方向不能同时直行2)垂直方向不可左转if ((aStatus.containsKey(leftKey)&&aStatus.get(leftKey)[2]==1)||(aStatus.containsKey(rightKey)&&(aStatus.get(rightKey)[2]==1||aStatus.get(rightKey)[0]==1))) {flag = false;return flag;}}}}return flag;}//由aStatus 生成 statusStringprivate static String geneStatusString(Map<String, Integer[]> aStatus) {ArrayList<String> records = new ArrayList<String>();for (String aKey : aStatus.keySet()) {String[] keyString = aKey.split("-");String aRecordString = keyString[0] + "," + keyString[1] + ","+ aStatus.get(aKey)[0] + "," + aStatus.get(aKey)[1] + ","+ aStatus.get(aKey)[2];records.add(aRecordString);}String statusString = String.join(";", records);return statusString;}}




0 0
原创粉丝点击