¿Ya hay una estructura de datos implementada en la biblioteca .NET que actúa como matriz dispersa (donde la mayoría de los índices están vacíos) con O (1) acceso por índice y O (1) acceso al siguiente elemento (y anterior)?¿Hay una implementación de matriz dispersa en la biblioteca .NET?
Respuesta
No sé de ningún recipiente incorporados como usted quiere, pero como solución alternativa se puede utilizar un Dictionary
de los siguientes elementos:
class Entry<T>
{
int previdx, nextidx;
T data;
}
(diccionario en .NET tiene O (1) búsqueda, ya que está basada en hashtats). Para que la inserción sea O (log n), necesitamos mantener una lista ordenada de los índices ya existentes (esto no existe de fábrica, pero can be easily emulated)
Agradable, pero creo que no es tan fácil de implementar. Bueno, supongo que en mi caso solo usaré la lista de nodos enlazados que almacena su índice, inserto la ordenación y la simple búsqueda de matriz (o diccionario). La inserción de O (n) me está molestando un poco, pero no creo que se pueda hacer algo al respecto, ni tampoco está tan mal después de todo. – mrpyo
@mrpyo: Me acabo de dar cuenta de que para una inserción rápida necesitamos una lista ordenada de índices, para que pueda verificar en el tiempo O (log n) qué índice será el siguiente/anterior del nuevo índice. – Vlad
Configuré un list of the lists in dotnet por un tiempo hace. No hay una lista dispersa allí.
Lo menciono de todos modos porque puede ser de ayuda si decide desarrollar uno usted mismo.
Gracias por compartir. – NoChance
Aquí hay una matriz dispersa basada en un diccionario (en su mayoría no probado, acabo de poner juntos después de leer esta pregunta):
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
namespace NobleTech.Products.Library.Linq
{
public class SparseList<T> : IList<T>
{
private T defaultValue;
private Dictionary<int, T> dict;
private IEqualityComparer<T> comparer;
public SparseList(T DefaultValue = default(T))
: this(DefaultValue, EqualityComparer<T>.Default)
{
}
public SparseList(IEqualityComparer<T> Comparer)
: this(default(T), Comparer)
{
}
public SparseList(T DefaultValue, IEqualityComparer<T> Comparer)
{
defaultValue = DefaultValue;
dict = new Dictionary<int, T>();
comparer = Comparer;
}
public int IndexOf(T item)
{
if (comparer.Equals(item, defaultValue))
return LinqUtils.Generate().First(i => !dict.ContainsKey(i));
return dict.Where(kvp => comparer.Equals(item, kvp.Value))
.Select(kvp => (int?)kvp.Key).FirstOrDefault() ?? -1;
}
public void Insert(int index, T item)
{
if (index < 0)
throw new ArgumentOutOfRangeException("index", index, "index must be non-negative");
if (index < Count)
dict = dict.ToDictionary(kvp => kvp.Key < index ? kvp.Key : kvp.Key + 1, kvp => kvp.Value);
this[index] = item;
}
public void RemoveAt(int index)
{
if (index < 0)
throw new ArgumentOutOfRangeException("index", index, "index must be non-negative");
dict.Remove(index);
if (index < Count)
dict = dict.ToDictionary(kvp => kvp.Key < index ? kvp.Key : kvp.Key - 1, kvp => kvp.Value);
}
public T this[int index]
{
get
{
if (index < 0)
throw new ArgumentOutOfRangeException("index", index, "index must be non-negative");
if (dict.ContainsKey(index))
return dict[index];
return defaultValue;
}
set
{
if (index < 0)
throw new ArgumentOutOfRangeException("index", index, "index must be non-negative");
dict[index] = value;
}
}
public void Add(T item) { this[Count] = item; }
public void Clear() { dict.Clear(); }
public bool Contains(T item)
{
return comparer.Equals(item, defaultValue) || dict.Values.Contains(item, comparer);
}
public void CopyTo(T[] array, int arrayIndex)
{
if (array == null)
throw new ArgumentNullException("array");
if (arrayIndex < 0)
throw new ArgumentOutOfRangeException("arrayIndex", arrayIndex, "arrayIndex must be non-negative");
for (int i = 0; i < array.Length - arrayIndex; ++i)
array[arrayIndex + i] = this[i];
}
public int Count { get { return (dict.Keys.Max(i => (int?)i) ?? -1) + 1; } }
public bool IsReadOnly { get { return false; } }
public bool Remove(T item)
{
int index = IndexOf(item);
if (index < 0)
return false;
RemoveAt(index);
return true;
}
public IEnumerator<T> GetEnumerator()
{
return LinqUtils.Generate(i => this[i]).GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); }
}
}
La implementación de LinqUtils.Generate
se deja como ejercicio para el lector :-)
Hace un par de años (lo siento, llegué tarde a esta pregunta!) Implementé una colección dispersa basada en mi "AList" concept. Se llama SparseAList, y es probablemente mejor que cualquier solución "simple" que pueda rodar usted mismo. Por ejemplo, la solución de @NathanPhilips tiene Insert
y RemoveAt
métodos que llaman al ToDictionary
. Enumerable.ToDictionary
es un método O (N) - regenera todo el diccionario "desde cero" - por lo que no es eficiente.
SparseAList, por el contrario, se basa en el B+ tree, por lo que tiene inserciones O (log N) eficientes, búsquedas y eliminaciones, y también utiliza la memoria de manera eficiente. Se incluye en Loyc.Collections.dll en LoycCore, disponible en NuGet y GitHub.
- 1. La mejor manera de almacenar una matriz dispersa en .NET
- 2. Matriz dispersa multidimensional o bibliotecas de matriz en .NET
- 3. Crear una matriz diagonal dispersa a partir de la fila de una matriz dispersa
- 4. Volcar una matriz dispersa en un archivo
- 5. matriz triangular dispersa Scipy?
- 6. Cómo transformar numpy.matrix o una matriz en una matriz dispersa dispersa
- 7. ¿Hay una biblioteca .NET FastCGI?
- 8. Operaciones de matriz dispersa en CUDA
- 9. Cómo hacer una matriz dispersa en Cocoa
- 10. SVD para matriz dispersa en R
- 11. Soporte de matriz dispersa en HDF5
- 12. Algoritmo para multiplicación matricial de matriz cuadrática con matriz dispersa
- 13. ¿Hay una implementación de Python en .net Automapper?
- 14. Aplicar PCA en matriz dispersa muy grande
- 15. elementos de multiplicarse en una matriz dispersa en la matriz con filas
- 16. csv a matriz dispersa en python
- 17. Almacenamiento de la matriz numpy dispersa en HDF5 (PyTables)
- 18. Javascript iteración a través de matriz dispersa
- 19. Manera eficiente de normalizar una matriz dispersa de Scipy
- 20. ¿Hay una biblioteca incorporada de naipes en .Net?
- 21. manera eficiente para crear una matriz dispersa en diagonal
- 22. Obtener el primer elemento de una matriz de JavaScript dispersa
- 23. ¿Cómo calculo la varianza de una columna de una matriz dispersa en Scipy?
- 24. ¿Hay una implementación gratuita de printf para .net?
- 25. Cargar matriz dispersa desde el archivo npy
- 26. ¿Hay alguna biblioteca DECAPTCHA en .NET?
- 27. ¿Hay una biblioteca para notificación/alerta en .NET?
- 28. Computing matriz de distancia dispersa por pares en R
- 29. ¿Cuál es la idea principal de implementación detrás de la tabla hash dispersa?
- 30. Encuentra la sub matriz subnsa "más grande" en una gran matriz dispersa
Ver http://stackoverflow.com/questions/756329/best-way-to-store-a-sparse-matrix-in-net. O puede probar Math.Net: http://numerics.mathdotnet.com/ –