简单的索引合并压缩算法研究

索引合并压缩算法的思路是:

 

索引合并压缩算法有一种有损压缩,主要用于对包含一定噪音的整型数组进行合并压缩。算法原理就像下雨一样,每一滴都会溅射出一小片湿润区域,如果下一滴落在前面的湿润区域那么 就加强该区域,并且重新计算湿润中心;如果两片区域重叠 那么就将两片合并,并且重新计算湿润中心。

 

算法描述:

 

前段时间研究红外遥控器学习模型,由于学习过程中采集到的红外码是一个整型数组且在数值上很不规范,有可能是噪声的原因,获得的整型数组会有很微小的波动偏差,使得垃圾数据含量很大。导致红外码存储,传输,分析都十分困难。雨滴算法,就是把数值上十分接近的码值合并成一个,并用所有修正后的码值建立索引表,之后把所有码值使用索引表的下标表示,经过分析观察,发现所有经过索引的码值均在16的范围之内,于是进一步把该值压缩到半个字节了也就是半个byte或者char内,然后把索引表附到变形后的数组之前,共同组成加密后的红外码。经过这些校正和压缩,新的码值数组长度为以前数据长度的八分之一加上索引表的长度。


java算法如下:

import java.util.LinkedList;
import java.util.List;

public class XiaoMiAlgRainEncode2 {
	static final short  ALG_RAIN_MAGIC =(short) 0xA567;
	static final int  WET_NUM =16;
	static final int SAMPLE_NUM= 1000;
	static final int SOAK_RANGE = 26; //39//80
	
	public class AlgRain {
		public int avr;
		public int total;
		public int min;
		public int max;
		public int cnt;
		public short idx;
		public AlgRain(int val, int min, int max) {
			super();
			this.avr = val;
			this.total = val;
			this.min = min;
			this.max = max;
			this.cnt = 1;

		}
		
		

		public AlgRain() {
			super();
			this.avr = 0;
			this.total = 0;
			this.min = 0;
			this.max = 0;
			this.cnt = 0;
		}
		@Override
		public String toString() {
			return "AlgRain [avr=" + avr + ", total=" + total + ", min=" + min
					+ ", max=" + max + ", cnt=" + cnt + ", idx=" + idx + "]";
		}
	}
	public class AlgRainTable {
		public short m_ver = 0;
		public short num = 0;
		public int[] val= new int[WET_NUM];
		public AlgRainTable() {
			super();
			this.m_ver = ALG_RAIN_MAGIC;
			this.num = 0;
			//System.arraycopy(val, 0, 0x00, 0, 1);
			for (int i = 0; i < WET_NUM; i++)
			{
				val[i] = 0;
			}
		}
	}

	
	private List<AlgRain> mWets = new LinkedList<AlgRain>();
	private AlgRainTable mArt = new AlgRainTable();
	private static boolean isCross(AlgRain w, AlgRain ref)
	{
		return (Math.max(w.min, ref.min) <= Math.min(w.max, ref.max));
	}

	private void soak()
	{
		
		for (int i = 0; i < mWets.size(); i++)
		{
			AlgRain w1 = mWets.get(i);
			for (int j = i+1; j < mWets.size(); j++)
			{
				AlgRain w2 = mWets.get(j);
				if (isCross(w1, w2))
				{
					(mWets.get(i)).total += w2.total;
					(mWets.get(i)).cnt += w2.cnt;
					(mWets.get(i)).avr = (mWets.get(i)).total/(mWets.get(i)).cnt;
					
					(mWets.get(i)).max = Math.max((mWets.get(i)).max, w2.max);
					(mWets.get(i)).min = Math.max((mWets.get(i)).min, w2.min);
					mWets.remove(j);
				}
			}
		}
	}


	private void alg_rain_reset()
	{
		mWets.clear();
	}

	private int alg_rain_feed(int sample)
	{
		
		AlgRain w = new AlgRain(sample, sample - SOAK_RANGE/2, sample + SOAK_RANGE/2);
		for (AlgRain ww: mWets)
		{
			if (isCross(ww, w))
			{
				ww.total += w.total;
				ww.cnt += w.cnt;
				ww.avr = ww.total/ww.cnt;
				
				ww.max = Math.max(ww.max, w.max);
				ww.min = Math.max(ww.min, w.min);
				return 0;
			}
			
		}
		mWets.add(w);
		//soak();
		return 0;
	}


	private int alg_rain_feed_finish()
	{
		short idx = 0;
		int cnt = 0;
		soak();	
		for (AlgRain w: mWets)
		{
			w.idx = idx;
			mArt.val[idx] = w.avr;
			cnt += w.cnt;
			idx++;
		}
		mArt.num = (short) cnt;
		mArt.m_ver= ALG_RAIN_MAGIC;
		
		for (int i = 0; i < mWets.size(); i++)
		{
			System.out.println("AAAAA mWets["+i+"].avr="+mWets.get(i).toString());

		}
		
	    return cnt;
	}


	private int get_alg_rain_table_encode(int sample)
	{
		System.out.println("AAAAA sample="+sample);
		for (AlgRain w: mWets)
		{
			System.out.println("AAAAA w="+w.toString());
			if((sample > w.min) && (sample < w.max))
			{
				return w.idx;
			}
		}
		return -1;
	}
	private int get_alg_rain_table_decode(int idx, byte code)
	{
		byte value; 
		
		if(idx%2 == 0)
		{
			value = (byte)(0x0F & code);
		}
		else
		{
			value = (byte)(0x0F & code >> 4);
		}

		return mArt.val[value];
	}
	private byte[] alg_rain_table_encode(AlgRainTable a)
	{
		int size = 2 + 2 + 4*WET_NUM ;
		byte[] bb = new byte[size];
		System.arraycopy(XiaoMiBigLittle.little_intToByte(a.m_ver, 2), 0, bb, 0,  2);
		System.arraycopy(XiaoMiBigLittle.little_intToByte(a.num, 2), 0, bb, 2, 2);
		for (int i = 0; i < WET_NUM; i++)
		{
			byte[] b = XiaoMiBigLittle.little_intToByte(a.val[i], 4);
			for (int j = 0; j < b.length; j++)
			{
				System.out.println("AAAAA bbbb["+j+"]="+b[j]);
				//System.arraycopy(b[j], 0, bb, 4+i*4+j, 1);
				bb[4+i*4+j] = b[j];
			}
			//System.arraycopy(b, 0, bb, 4+i, 4);
		}
		
		return bb;
	}
	private AlgRainTable alg_rain_table_decode(byte[] b)
	{
		byte[] b1= new byte[2];
		byte[] b2= new byte[4];
		AlgRainTable a = new AlgRainTable();
		
		System.arraycopy(b, 0, b1, 0,  2);
		a.m_ver = (short)XiaoMiBigLittle.little_bytesToInt(b1);
		
		System.arraycopy(b, 2, b1, 0, 2);
		a.num = (short)XiaoMiBigLittle.little_bytesToInt(b1);
		
		for (int i = 0; i < WET_NUM; i++)
		{
			System.arraycopy(b, 4 + i*4, b2, 0, 4);
			a.val[i] = XiaoMiBigLittle.little_bytesToInt(b2);
		}

		return a;
	}
	public byte[] get_alg_rain_encode(int[] inSample)
	{
		int size = 2 + 2 + 4*WET_NUM ;
		System.out.println("AAAAA size"+size);
		byte [] outCode = new byte[inSample.length+size];
		
		System.out.println("AAAAA inSample.length+size"+inSample.length+size);
		for (int i : inSample)
		{
			alg_rain_feed(i);
		}
		
		alg_rain_feed_finish();
		
		//int[] tmp = new int[68];
		System.arraycopy(alg_rain_table_encode(mArt), 0, outCode, 0, size);
		
		byte b2=0, b1=0;
		for (int i = 0; i< inSample.length; i++)
		{
			b2 = (byte)get_alg_rain_table_encode(inSample[i]);
			System.out.println("AAAAA b2="+b2+"inSample[i]="+inSample[i]);
			if(i%2 == 0)	//even low nibble
			{
				b1 = b2;
			}
			else{		//odd high nibble
				b1 |= b2 << 4;
				System.out.println("AAAAA b1="+b1);
				outCode[size+i/2] = b1;
			}
		}
	    return outCode;
	}
	public int[] get_alg_rain_decode(byte[] inCode)
	{
		int size = 2 + 2 + 4*WET_NUM ;
		AlgRainTable a = alg_rain_table_decode(inCode);
		int[] outSmaple = new int[a.num];
		
		System.out.println("AAAAA a.num="+a.num);
		for (int i = 0; i < outSmaple.length; i++)
		{
			if ((i%2) == 0)
			{
				outSmaple[i] = a.val[inCode[size+(i/2)]&0x0f];
			}else
			{
				outSmaple[i] = a.val[(inCode[size+(i/2)]>>4)&0x0f];
			}
			
		}
		return outSmaple;
	}

	public static void main(String[] args) {
		// init array
		short a1[] = new short[100];

		for (int i = 0; i < a1.length; i++) {
			a1[i] = (short) ((i % 16) * 100 + 20);
			System.out.println("AAAAA a1[" + i + "]=" + a1[i]);
		}
		// trans int
		int a[] = new int[100];

		for (int i = 0; i < a1.length; i++) {
			if ((a1[i] & 0x8000) != 0) {
				a[i] = 100 * (int) (a1[i] & 0x7FFF);
			} else {
				a[i] = a1[i];
			}
			System.out.println("AAAAA a[" + i + "]=" + a[i]);
		}

		// rain Encode
		XiaoMiAlgRainEncode2 are = new XiaoMiAlgRainEncode2();

		byte[] b = are.get_alg_rain_encode(a);

		for (int i = 0; i < b.length; i++) {
			System.out.println("AAAAA b[" + i + "]=" + b[i]);
		}
		// base64 Encode
		byte[] eb64 = XiaoMiBase64.Base64Encode(b, b.length);

		for (int i = 0; i < eb64.length; i++) {
			System.out.println("AAAAA eb64[" + i + "]=" + eb64[i]);
		}
		// base64 decode
		byte[] db64 = XiaoMiBase64.Base64Decode(eb64, eb64.length);
		for (int i = 0; i < db64.length; i++) {
			System.out.println("AAAAA db64[" + i + "]=" + db64[i]);
		}
		// rain decode
		int[] c = are.get_alg_rain_decode(b);

		for (int i = 0; i < c.length; i++) {
			System.out.println("AAAAA c[" + i + "]=" + c[i]);
		}
		// trans short

		for (int i = 0; i < c.length; i++) {
			if (c[i] > 0x8000) {
				a1[i] = (short) ((c[i] / 100) | 0x8000);
			} else {
				a1[i] = (short) c[i];
			}
			System.out.println("AAAAA a1[" + i + "]=" + a1[i]);
		}
		System.out.println("AAAAA the mechine is big ="
				+ XiaoMiBigLittle.isBigendian());
	}
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值