工时分摊算法

工时分摊算法

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()][]);
    }
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值