これが私が使用したコードです
/// <summary>
/// Defines an interface to calculate relevant
/// to the input complexity of a string
/// </summary>
public interface IStringComplexity
{
double GetCompressionRatio(string input);
double GetRelevantComplexity(double min, double max, double current);
}
そしてそれを実装するクラス
public class GZipStringComplexity : IStringComplexity
{
public double GetCompressionRatio(string input)
{
if (string.IsNullOrEmpty(input))
throw new ArgumentNullException();
byte[] inputBytes = Encoding.UTF8.GetBytes(input);
byte[] compressed;
using (MemoryStream outStream = new MemoryStream())
{
using (var zipStream = new GZipStream(
outStream, CompressionMode.Compress))
{
using (var memoryStream = new MemoryStream(inputBytes))
{
memoryStream.CopyTo(zipStream);
}
}
compressed = outStream.ToArray();
}
return (double)inputBytes.Length / compressed.Length;
}
/// <summary>
/// Returns relevant complexity of a string on a scale [0..1],
/// where <value>0</value> has very low complexity
/// and <value>1</value> has maximum complexity
/// </summary>
/// <param name="min">minimum compression ratio observed</param>
/// <param name="max">maximum compression ratio observed</param>
/// <param name="current">the value of compression ration
/// for which complexity is being calculated</param>
/// <returns>A relative complexity of a string</returns>
public double GetRelevantComplexity(double min, double max, double current)
{
return 1 - current / (max - min);
}
}
使用方法は次のとおりです
class Program
{
static void Main(string[] args)
{
IStringComplexity c = new GZipStringComplexity();
string input1 = "HHHFHHFFHHFHHFFHHFHHHFHAAAAHHHFHHFFHHFHHFFHHFHHHFHAAAAHHHFHHFFHHFHHFFHHFHHHFHAAAAHHHFHHFFHHFHHFFHHFHHHFH";
string input2 = "mlcllltlgvalvcgvpamdipqtkqdlelpklagtwhsmamatnnislmatlkaplrvhitsllptpednleivlhrwennscvekkvlgektenpkkfkinytvaneatlldtdydnflflclqdtttpiqsmmcqylarvlveddeimqgfirafrplprhlwylldlkqmeepcrf";
string inputMax = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
double ratio1 = c.GetCompressionRatio(input1); //2.9714285714285715
double ratio2 = c.GetCompressionRatio(input2); //1.3138686131386861
double ratioMax = c.GetCompressionRatio(inputMax); //7.5
double complexity1 = c.GetRelevantComplexity(1, ratioMax, ratio1); // ~ 0.54
double complexity2 = c.GetRelevantComplexity(1, ratioMax, ratio2); // ~ 0.80
}
}
役立つと思った追加情報。
7zip ライブラリの LZMA、LZMA2、または PPMD を試すことができます。これらは設定が比較的簡単で、インターフェイスがあれば、いくつかの圧縮アルゴリズムを実装できます。これらのアルゴリズムは GZip よりもはるかに優れた圧縮を実行することがわかりましたが、圧縮率をスケールに入れる場合、これは実際には問題ではありません。
たとえば 0 から 1 に正規化された値が必要な場合は、最初にすべてのシーケンスの圧縮率を計算する必要があります。これは、可能な最大圧縮率を確認できないためです。