工时分摊算法
package com.ime.tmgc.test;
import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;
public class Test17 {
//多条并行单据
static long[][][] x5=new long[][][]{
{{1,3},{6,7},{8,11}},
{{2,6},{6,11}},
{{1,4},{5,6},{6,10}},
{{5,7},{8,9}},
{{5,7},{8,9}}
};
static Map<String, Double> allocationTimeValue = new HashMap<>();
{
//每条单据下标+总工时
allocationTimeValue.put("0",6d);
allocationTimeValue.put("1",10d);
allocationTimeValue.put("2",8d);
allocationTimeValue.put("3",3d);
allocationTimeValue.put("4",3d);
}
public static void main(String[] args) {
Long min = 1L; //最小时间戳
Long max = 11L; //最大时间戳
Map<String, Integer[]> sectionMap = calculateBuilder(x5,min,max);
sectionMap.forEach((k1,v1)->{
String[] split = k1.split("-");
BigDecimal decimal = new BigDecimal((Long.parseLong(split[1]) - Long.parseLong(split[0])));
double l=(decimal.divide(new BigDecimal(v1.length), 2, BigDecimal.ROUND_HALF_UP)).doubleValue();
for (int i = 0; i < v1.length; i++) {
Double longIndex = allocationTimeValue.get(v1[i]+"")==null?0d:allocationTimeValue.get(v1[i]+"");
double a = new BigDecimal(longIndex).add((new BigDecimal(l))).setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();
allocationTimeValue.put(v1[i] + "", a);
}
});
allocationTimeValue.forEach((k,v)->{
System.out.println("下标:"+k+",分摊工时:"+v);
});
}
private static Map<String, Integer[]> calculateBuilder(long[][][] x5, Long min, Long max){
List<Long[]> x5s = new ArrayList<>();
Map<String, Integer[]> sectionMap = new LinkedHashMap<>();
for (int i = 0; i < x5.length; i++) {
Set<Long> integers = Arrays.stream(x5[i]).map(v -> Arrays.asList(v[0], v[1])).flatMap(Collection::stream).collect(Collectors.toSet());
x5s.add(integers.toArray(new Long[0]));
}
Long[][] longs2 = x5s.toArray(new Long[0][0]);
List<long[]> ints = new ArrayList<>();
long left = min;
long right = max;
while (left < right){
long start = left;
long end = right;
for (int i = 0; i < longs2.length; i++) {
Long asLong = Arrays.stream(longs2[i]).filter(v -> start < v).min(Long::compareTo).orElse(right);
if(asLong<end){
end=asLong;
}
}
left=end;
ints.add(new long[]{start,end});
}
long[][] longs = ints.toArray(new long[0][0]);
for (int i = 0; i < x5.length; i++) {
long[][] longs3=x5[i];
intervalIntersection(longs3,longs,sectionMap,i);
}
return sectionMap;
}
private static long[][] intervalIntersection(long[][] a, long[][] b, Map<String, Integer[]> sectionMap, int index){
List<long[]> ints = new ArrayList<>();
int i=0,j=0;
while (i< a.length&&j< b.length){
long lo=Math.max(a[i][0],b[j][0]);
long hi=Math.min(a[i][1],b[j][1]);
if(lo<hi){
ints.add(new long[]{lo,hi});
Integer[] integers = sectionMap.get(lo + "-" + hi);
ArrayList<Object> arrayList = new ArrayList<>();
if(integers!=null){
arrayList.addAll(Arrays.asList(integers));
}
arrayList.add(index);
sectionMap.put(lo+"-"+hi, new HashSet<>(arrayList).toArray(new Integer[]{}));
}
if(a[i][1]<b[j][1]){
i++;
}else {
j++;
}
}
return ints.toArray(new long[ints.size()][]);
}
}