161 lines
4.2 KiB
C#
161 lines
4.2 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Text;
|
|
|
|
namespace BotSharp.MachineLearning.CRFLite
|
|
{
|
|
public class QueueElement
|
|
{
|
|
public Node node;
|
|
public QueueElement next;
|
|
public double fx;
|
|
public double gx;
|
|
};
|
|
|
|
public class Heap
|
|
{
|
|
public int capacity;
|
|
public int elem_size; //size of elem_list
|
|
public int size; // size of elem_ptr_list
|
|
public List<QueueElement> elem_ptr_list;
|
|
public List<QueueElement> elem_list;
|
|
};
|
|
|
|
public class BaseUtils
|
|
{
|
|
public const double eps = 1e-7;
|
|
|
|
|
|
public const int MINUS_LOG_EPSILON = 13;
|
|
public const int DEFAULT_CRF_MAX_WORD_NUM = 100;
|
|
|
|
public const int MODEL_TYPE_NORM = 100;
|
|
|
|
|
|
public const int ERROR_INVALIDATED_FEATURE = -8;
|
|
public const int ERROR_HEAP_SIZE_TOO_BIG = -7;
|
|
public const int ERROR_INSERT_HEAP_FAILED = -6;
|
|
public const int ERROR_EMPTY_FEATURE = -5;
|
|
public const int ERROR_INVALIDATED_PARAMETER = -4;
|
|
public const int ERROR_WRONG_STATUS = -3;
|
|
public const int ERROR_TOO_LONG_WORD = -2;
|
|
public const int ERROR_UNKNOWN = -1;
|
|
public const int ERROR_SUCCESS = 0;
|
|
|
|
public static Heap heap_init(int max_size)
|
|
{
|
|
Heap H;
|
|
|
|
H = new Heap();
|
|
H.capacity = max_size;
|
|
H.size = 0;
|
|
H.elem_size = 0;
|
|
|
|
H.elem_ptr_list = new List<QueueElement>(max_size + 1);
|
|
H.elem_list = new List<QueueElement>(max_size + 1);
|
|
|
|
for (var z = 0; z < max_size; z++)
|
|
{
|
|
H.elem_list.Add(new QueueElement());
|
|
H.elem_ptr_list.Add(null);
|
|
}
|
|
H.elem_list[0].fx = double.MinValue;
|
|
H.elem_ptr_list.Add(H.elem_list[0]);
|
|
|
|
return H;
|
|
}
|
|
|
|
public static QueueElement allc_from_heap(Heap H)
|
|
{
|
|
if (H.elem_size >= H.capacity)
|
|
{
|
|
return null;
|
|
}
|
|
else
|
|
{
|
|
return H.elem_list[++H.elem_size];
|
|
}
|
|
}
|
|
|
|
public static int heap_insert(QueueElement qe, Heap H)
|
|
{
|
|
if (H.size >= H.capacity)
|
|
{
|
|
return BaseUtils.ERROR_HEAP_SIZE_TOO_BIG;
|
|
}
|
|
var i = ++H.size;
|
|
while (i != 1 && H.elem_ptr_list[i / 2].fx > qe.fx)
|
|
{
|
|
H.elem_ptr_list[i] = H.elem_ptr_list[i / 2]; //此时i还没有进行i/2操作
|
|
i /= 2;
|
|
}
|
|
H.elem_ptr_list[i] = qe;
|
|
return 0;
|
|
}
|
|
|
|
public static QueueElement heap_delete_min(Heap H)
|
|
{
|
|
var min_elem = H.elem_ptr_list[1]; //堆是从第1号元素开始的
|
|
var last_elem = H.elem_ptr_list[H.size--];
|
|
int i = 1, ci = 2;
|
|
while (ci <= H.size)
|
|
{
|
|
if (ci < H.size && H.elem_ptr_list[ci].fx > H.elem_ptr_list[ci + 1].fx)
|
|
{
|
|
ci++;
|
|
}
|
|
if (last_elem.fx <= H.elem_ptr_list[ci].fx)
|
|
{
|
|
break;
|
|
}
|
|
H.elem_ptr_list[i] = H.elem_ptr_list[ci];
|
|
i = ci;
|
|
ci *= 2;
|
|
}
|
|
H.elem_ptr_list[i] = last_elem;
|
|
return min_elem;
|
|
}
|
|
|
|
public static bool is_heap_empty(Heap H)
|
|
{
|
|
return H.size == 0;
|
|
}
|
|
|
|
public static void heap_reset(Heap H)
|
|
{
|
|
if (H != null)
|
|
{
|
|
H.size = 0;
|
|
H.elem_size = 0;
|
|
}
|
|
}
|
|
|
|
public static double logsumexp(double x, double y, bool flg)
|
|
{
|
|
if (flg)
|
|
{
|
|
return y; // init mode
|
|
}
|
|
double vmin;
|
|
double vmax;
|
|
if (x > y)
|
|
{
|
|
vmin = y;
|
|
vmax = x;
|
|
}
|
|
else
|
|
{
|
|
vmin = x;
|
|
vmax = y;
|
|
}
|
|
|
|
if (vmax > vmin + MINUS_LOG_EPSILON)
|
|
{
|
|
return vmax;
|
|
}
|
|
return vmax + Math.Log(Math.Exp(vmin - vmax) + 1.0);
|
|
}
|
|
}
|
|
}
|