public void Test() { Span <byte> span = stackalloc byte[256]; var pack = new BinPack(span); var value1 = 128; pack.Write(value1); var value2 = 0xffffffffffffffffUL; pack.Write(value2); var value3 = DateTime.MaxValue; pack.Write(value3); var value4 = new Guid("deadbeef-1234-5678-9012-abcdef012345"); pack.Write(value4); var value5 = "test"; pack.Write(value5); var value6 = ""; pack.Write(value6); var unpack = new BinUnpack(span); Assert.AreEqual(value1, unpack.ReadInt32()); Assert.AreEqual(value2, unpack.ReadUInt64()); Assert.AreEqual(value3, unpack.ReadDateTime()); Assert.AreEqual(value4, unpack.ReadGuid()); Assert.AreEqual(value5, unpack.ReadString()); Assert.AreEqual(value6, unpack.ReadString()); }
/// <summary> /// 정해진 bin들의 남는 공간이 최소가 되게 stuff를 배치하고, [bin][stuff]의 초기 입력순 리스트로 반환합니다. /// </summary> public static List <List <double> > PackToBins(List <double> stuffs, List <double> bins, out List <List <int> > stuffIndex) { //scale List <double> scaledStuff = new List <double>(); double binTotal = bins.Sum(); double stuffTotal = stuffs.Sum(); if (binTotal < stuffTotal) { scaledStuff = ScaleToNewSum(binTotal, stuffs); } else { scaledStuff = stuffs; } //set List <Stuff> stuffList = new List <Stuff>(); for (int i = 0; i < scaledStuff.Count; i++) { Stuff eachStuff = new Stuff(scaledStuff[i], i); stuffList.Add(eachStuff); } List <BinPack> binList = new List <BinPack>(); for (int i = 0; i < bins.Count; i++) { BinPack eachBinPack = new BinPack(bins[i], i); binList.Add(eachBinPack); } //initial sorting stuffList.Sort((a, b) => - a.Volume.CompareTo(b.Volume)); foreach (Stuff i in stuffList) { binList.Sort((a, b) => BinPackComparer(a, b, i)); binList.First().StuffIncluded.Add(i); } //balancing BalanceBinPack(binList); binList.Sort((a, b) => (a.IndexInitial.CompareTo(b.IndexInitial))); //output List <List <double> > packedStuff = new List <List <double> >(); List <List <int> > packedIndex = new List <List <int> >(); foreach (BinPack i in binList) { List <double> currentPack = new List <double>(); List <int> currentIndexPack = new List <int>(); i.StuffIncluded.Sort((a, b) => a.Index.CompareTo(b.Index)); foreach (Stuff j in i.StuffIncluded) { currentPack.Add(j.Volume); currentIndexPack.Add(j.Index); } packedStuff.Add(currentPack); packedIndex.Add(currentIndexPack); } stuffIndex = packedIndex; return(packedStuff); }
private static int BinPackComparer(BinPack a, BinPack b, Stuff s) { //tolerance double nearDecidingRate = 1.2; //binPackSet double aVolume = a.Volume; double bVolume = b.Volume; double aRemain = a.GetRemain(); double bRemain = b.GetRemain(); double aCost = Math.Abs(a.GetRemain() - s.Volume); double bCost = Math.Abs(b.GetRemain() - s.Volume); double sVolume = s.Volume; //decider bool IsAMoreProper = aCost < bCost; //compare //seive: subzero bin if (aVolume <= 0) { if (bVolume <= 0) { if (IsAMoreProper) { return(-1); } return(1); } if (bRemain >= sVolume) { return(1); } else { if (IsAMoreProper) { return(-1); } return(1); } } if (bVolume <= 0) { if (aRemain >= sVolume) { return(-1); } else { if (IsAMoreProper) { return(-1); } return(1); } } //actual comparer if (aRemain <= sVolume) { if (bRemain <= sVolume) { if (IsAMoreProper) { return(-1); } return(1); } if (aRemain * nearDecidingRate >= sVolume) { return(-1); } return(1); } if (bRemain <= sVolume) { if (bRemain * nearDecidingRate >= sVolume) { return(1); } return(-1); } if (IsAMoreProper) { return(-1); } return(1); }
private static int BinPackComparer(BinPack a, BinPack b, Stuff s) { //tolerance double nearDecidingRate = 1.2; //binPackSet double aVolume = a.Volume; double bVolume = b.Volume; double aCost = a.GetCost(); double bCost = b.GetCost(); double aProperity = Math.Abs(a.GetCost() - s.Volume); double cProperity = Math.Abs(b.GetCost() - s.Volume); double sVolume = s.Volume; //decider bool IsAMoreProper = aProperity < cProperity; // if (aVolume <= 0) { if (bVolume <= 0) { if (IsAMoreProper) { return(-1); } return(1); } if (bCost >= sVolume) { return(1); } else { if (IsAMoreProper) { return(-1); } return(1); } } else { if (bVolume <= 0) { if (aCost >= sVolume) { return(-1); } else { if (IsAMoreProper) { return(-1); } return(1); } } if (aCost <= sVolume) { if (bCost <= sVolume) { if (IsAMoreProper) { return(-1); } return(1); } if (aCost * nearDecidingRate >= sVolume) { return(-1); } return(1); } if (bCost <= sVolume) { if (bCost * nearDecidingRate >= sVolume) { return(1); } return(-1); } if (IsAMoreProper) { return(-1); } return(1); } }