1

我将一些数据存储在 Math.net 向量中,因为我必须将其作为一个整体进行一些计算。该数据在收集时带有时间信息。例如:

Initial = 5, Time 2 = 7, Time 3 = 8, Time 4 = 10

因此,当我将数据存储在 Vector 中时,它看起来像这样。

stateVectorData = [5,7,8,10]

现在有时我需要提取向量的单个条目。但是我没有索引本身,而是一个时间信息。所以我尝试的是一个包含时间信息和 stateVector 中数据索引的字典。

Dictionary<int, int> stateDictionary = new Dictionary<int, int>(); //Dict(Time, index)

每次我得到新数据时,我都会在字典中添加一个条目(当然还有 stateVector)。所以在时间 2 我做了:

stateDictionary.Add(2,1);

现在只要我不改变我的向量,它就可以工作。不幸的是,当向量太旧时,我必须删除向量中的一个条目。假设时间 2 太旧,我删除第二个条目并得到一个结果向量:

stateVector = [5,8,10]

现在我的字典存储了错误的索引值。
我可以想到两种可能的解决方案来解决这个问题。

  1. 遍历字典并将每个值(key > 2)减 1。
  2. 我认为更优雅的是在字典中存储对向量条目的引用而不是索引。

所以像

Dictionary<int, ref int> stateDictionary =
    new Dictionary<int, ref int>(); //Dict(Time, reference to vectorentry)
stateDictionary.Add(2, ref stateVector[1]);

使用这样的东西,我不会关心删除向量中的一些条目,因为我仍然有对其余向量条目的引用。现在我知道不可能在 C# 中存储引用。

所以我的问题是,除了循环浏览整个字典还有其他选择吗?或者有没有我目前看不到的字典的另一种解决方案?

编辑回答 juharr:时间信息并不总是加一。取决于一些并行运行的过程以及需要多长时间。可能在 1 到 3 之间增加。但也可能更多。向量中有一些值永远不会被删除。我试图用保留在向量中的初始值 5 来展示这一点。

编辑 2:
向量存储至少 5000 到 6000 个元素。目前没有定义最大值,因为它受到我可以实时处理的元素的限制,所以在我的情况下,我有大约 0.01 秒的时间来进行进一步的计算。这就是我搜索有效方法的原因,因此我可以增加向量中的元素数量(或增加我的向量条目的最大“年龄”)。
我需要整个向量来计算大约是我需要添加一个值的数字的 3 倍。
我必须删除频率最低的条目。通过时间键找到单个值将是最常见的情况。也许每秒 30 到 100 次。

我知道这听起来很不确定,但是查找和删除部分的频率取决于另一个过程,这可能会有很大差异。

虽然希望你能帮助我。感谢到目前为止。

编辑3:
@Robinson
我需要整个向量的确切次数也取决于并行过程。每次迭代最小值为两次(因此在 0.01 秒内两次),最大值为每次迭代至少 4 到 6 次。
同样,向量的大小是我想要最大化的。所以假设非常大。

编辑解决方案:
首先感谢所有帮助过我的人。
经过一番试验,我正在使用以下结构。
我正在使用一个列表,我将索引保存在我的状态向量中。此外,我使用字典将我的时间键分配给列表条目。因此,当我删除状态向量中的某些内容时,我只循环遍历列表,这似乎比循环字典要快得多。

所以它是:

stateVectorData = [5,7,8,10]
IndexList = [1,2,3];
stateDictionary = { Time 2, indexInList = 0; Time 3, indexInList = 1; Time 4, indexInList = 2 }
TimeKey->stateDictionary->indexInList -> IndexList -> indexInStateVector -> data
4

1 回答 1

0

你可以试试这个:

public class Vector
{
    private List<int> _timeElements = new List<int>();

    public Vector(int[] times)
    {
        Add(times);
    }

    public void Add(int time)
    {
        _timeElements.Add(time);
    }

    public void Add(int[] times)
    {
        _timeElements.AddRange(time);
    }

    public void Remove(int time)
    {
        _timeElements.Remove(time);
        if (OnRemove != null)
            OnRemove(this, time);
    }

    public List<int> Elements { get { return _timeElements; } }

    public event Action<Vector, int> OnRemove;
}

public class Vectors
{
    private Dictionary<int, List<Vector>> _timeIndex;

    public Vectors(int maxTimeSize)
    {
        _timeIndex = new Dictionary<int, List<Vector>>(maxTimeSize);
        for (var i = 0; i < maxTimeSize; i++)
            _timeIndex.Add(i, new List<Vector>());

        List = new List<Vector>();
    }

    public List<Vector> FindVectorsByTime(int time)
    {
        return _timeIndex[time];
    }

    public List<Vector> List { get; private set; }

    public void Add(Vector vector)
    {
        List.Add(vector);
        vector.Elements.ForEach(element => _timeIndex[element].Add(vector));
            vector.OnRemove += OnRemove;
    }

    private void OnRemove(Vector vector, int time)
    {
        _timeIndex[time].Remove(vector);
    }
}

要使用:

var vectors = new Vectors(maxTimeSize: 6000);

var vector1 = new Vector(new[] { 5, 30, 8, 20 });
var vector2 = new Vector(new[] { 25, 5, 23, 11 });

vectors.Add(vector1);
vectors.Add(vector2);

var findsTwo = vectors.FindVectors(time: 5);

vector1.Remove(time: 5);

var findsOne = vectors.FindVectors(time: 5);

添加时间也可以这样做,代码也仅用于说明目的。

于 2015-03-13T05:12:37.183 回答