稱重貨架 計算穩定後的值

公司項目有一個需求,通過稱重貨架來計算 物資的數量,在實際使用的過程中 人員每次從 稱重貨架上拿區的物品過程是 不穩定且確定性的
如果使用定時的方式獲取稱重貨架的值 可能取到的值是某個時間點的瞬時重量 不是實際的重量

現通過算法實現 獲取到的是稱重貨架 在穩定一個固定時間段 後返回的值


記錄一個時間點的穩定值,
下一次 變量波動後,
記錄第n次 後最終穩定下來的值 m5

實現方案

創建 StabeDataHandle 類


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

public class StabeDataHandle {
    /**
     * 指定時間範圍 t
     * 這個值需要大於秤盤發送數據的時間間隔
     */
    public final static Long dealyTime = 6L;
    /**
     * 誤差範圍
     */
    public final static Double scope = 10.00;

    public static Map<String, List<StabeDataModel>> lists = new HashMap<>();

    private static StabeDataHandle stabeDataUtil = new StabeDataHandle();

    private StabeDataHandle() {
    }

    public static StabeDataHandle getInstance() {
        return stabeDataUtil;
    }


    public Double[] getData(String id, Double val) {
        Double[] res = new Double[2]; //返回數組 上一次穩定值和當前穩定值
        Long time = System.currentTimeMillis() / 1000;

        List<StabeDataModel> data = lists.get(id);

        if (data == null) {
            //初始化
            data = new ArrayList<StabeDataModel>();
            data.add(new StabeDataModel(time, val,0L));
        } else {
            StabeDataModel original = data.get(0);
            Long dt = time - dealyTime;

            //先把當前傳過來的值 放到數組中,和以前的數據一起做處理
            data.add(new StabeDataModel(time, val,time-original.getTime()));

            //當前時間-指定時間 > 最開始時間  說明有足夠時間範圍,可以計算了
            if (dt >= original.getTime()) {

                //獲取指定時間範圍內的值 即A4點的數據
                int index = BinarySearch(data, dt);
                if(index == -1){
                    //沒找到 繼續添加值 (這個情況 可能是秤盤 壞了,沒有在固定時間內返回值給我)
                    System.out.println("沒找到 繼續添加;可能是秤盤 壞了,沒有在固定時間內發送值給我");
                    //data.add(new StabeDataModel(time, val,time-original.getTime()));
                }else{
                    //data.add(new StabeDataModel(time, val,time-original.getTime()));
                    //判斷這個時間範圍內的值 是否全部相等 (差值在一定誤差範圍內默認是相等的 )
                    boolean flag = stableVerify(data, index, scope);
                    if (flag) {
                        //如果相等,證明找到了 第二個穩定值
                        //重置 data
                        data = new ArrayList<StabeDataModel>();
                        data.add(new StabeDataModel(time, val,0L));

                        res[0] = original.getVal();
                        res[1] = val;
                    }
                }
            }
        }
        lists.put(id, data);
        testData(id);
        return res;
    }

    /**
     * 計算 某段時間範圍內的數據 是否都在誤差範圍內
     * @param datas
     * @param index 開始位置
     * @param scope 誤差範圍
     * @return
     */
    private static boolean stableVerify(List<StabeDataModel> datas, int index, Double scope) {

        Double max = datas.get(index).getVal();
        Double min = datas.get(index).getVal();

        //計算最值
        for (int i = index; i < datas.size(); i++) {
            if (datas.get(i).getVal() > max) {
                max = datas.get(i).getVal();
            }
            if (datas.get(i).getVal() < min) {
                min = datas.get(i).getVal();
            }
        }

        if (max - min <= scope) {
            return true;
        }
        return false;
    }


    /**
     * 二分法查找<br/>
     * ps: 如果 datas.size()==2 說明秤盤在穩定時間範圍外發給我的一條數據 將被認爲是有效數據 系統將進入第二次循環
     * @param datas,
     * @param val
     * @return
     */
    private static int BinarySearch(List<StabeDataModel> datas, Long val) {

        int min = 0;
        int max = datas.size() - 1;
        while (min <= max) {
            int middle = (min + max) / 2;

            //條件判斷
            if (val >= datas.get(middle).getTime()) {
                //int next = (middle + 1 > max)?max:middle + 1;
                if (val <= datas.get(middle + 1).getTime()) {
                    return middle;
                }
            }

            //二分判斷 val在中位的左邊還是右邊
            if (val > datas.get(middle).getTime()) {
                min = middle + 1;
            } else {
                max = middle - 1;
            }
        }
        return -1;
    }

    private void testData(String id) {
        System.out.println("------1-------");
        List<StabeDataModel> data = lists.get(id);
        for (StabeDataModel datum : data) {
            System.out.println(datum);
        }
        System.out.println("------2-------");

    }

}

實體類 StabeDataModel

package com.xue.util;

public class StabeDataModel {

    private String id;
    private Long key;
    private Double val;
    private Long time;

    public StabeDataModel(Long time, Double val, Long key) {
        this.key = key;
        this.val = val;
        this.time = time;
    }

    @Override
    public String toString() {
        return "StabeDataModel{" +
                "id='" + id + '\'' +
                ", key=" + key +
                ", val=" + val +
                ", time=" + time +
                '}';
    }

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public Long getKey() {
        return key;
    }

    public void setKey(Long key) {
        this.key = key;
    }

    public Double getVal() {
        return val;
    }

    public void setVal(Double val) {
        this.val = val;
    }

    public Long getTime() {
        return time;
    }

    public void setTime(Long time) {
        this.time = time;
    }
}

測試

	//測試
	@RequestMapping("/dataTest")
	@ResponseBody
	public Object dataTest(@RequestParam HashMap params){
		HashMap<String, Object> map = new HashMap<>();
		String id = (String) params.get("id");
		Double val = Double.valueOf(params.get("val").toString());
		Double[] res = StabeDataHandle.getInstance().getData(id, val);

		map.put("data",StabeDataHandle.lists);
		map.put("result",res);
		return map;
	}

結果

{
    "result": [
        null,
        null
    ],
    "data": {
        "123": [
            {
                "id": null,
                "key": 0,
                "val": 562,
                "time": 1573312026
            },
            {
                "id": null,
                "key": 6,
                "val": 2,
                "time": 1573312032
            },
            {
                "id": null,
                "key": 10,
                "val": 2,
                "time": 1573312036
            },
            {
                "id": null,
                "key": 13,
                "val": 255,
                "time": 1573312039
            },
            {
                "id": null,
                "key": 20,
                "val": 2524,
                "time": 1573312046
            },
            {
                "id": null,
                "key": 24,
                "val": 25247,
                "time": 1573312050
            },
            {
                "id": null,
                "key": 27,
                "val": 25247,
                "time": 1573312053
            }
        ]
    }
}

下一次 重置數據,並返回變化值

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章