Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/337.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/search/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 快速关系搜索_C#_Search_Relation - Fatal编程技术网

C# 快速关系搜索

C# 快速关系搜索,c#,search,relation,C#,Search,Relation,存在多对多关系列表(N=1000000)。我需要尽可能快地确定列表中的关系索引,并枚举特定项的所有关系 我知道可以为from/to创建查找表(时间为O(1)),但它的大小太大(N*N)。我知道我可以使用二进制搜索(时间为O(log(N)),但它仍然非常慢。还有其他解决办法吗 C#代码: 公共类关系 { 公共int来自; 公共int至; } 公共类表 { 公共列表关系{get;}=new List(); 公共无效添加(int-from,int-to) { if(IndexOf(from,to)=-

存在多对多关系列表(N=1000000)。我需要尽可能快地确定列表中的关系索引,并枚举特定项的所有关系

我知道可以为from/to创建查找表(时间为O(1)),但它的大小太大(N*N)。我知道我可以使用二进制搜索(时间为O(log(N)),但它仍然非常慢。还有其他解决办法吗

C#代码:

公共类关系
{
公共int来自;
公共int至;
}
公共类表
{
公共列表关系{get;}=new List();
公共无效添加(int-from,int-to)
{
if(IndexOf(from,to)=-1)
{
Add(新关系(){From=From,To=To});
}
}
public int IndexOf(int-from,int-to)
{
//这个算法进行O(N)比较,但我需要O(1)
for(int i=0;i
以下是包含两个词典的版本:

public class Table
{
    public Dictionary<int, HashSet<int>> froms { get; } = new Dictionary<int, HashSet<int>>();
    public Dictionary<int, HashSet<int>> tos { get; } = new Dictionary<int, HashSet<int>>();

    public void Add(int from, int to)
    {
        if (!Contains(from, to))
        {
            if (!froms.ContainsKey(from))
            {
                froms.Add(from, new HashSet<int> { to });
            }
            else
            {
                froms[from].Add(to);
            }

            if (!tos.ContainsKey(to))
            {
                tos.Add(to, new HashSet<int> { from });
            }
            else
            {
                tos[to].Add(from);
            }
        }
    }

    public bool Contains(int from, int to)
    {
        if (!froms.ContainsKey(from))
            return false;

        if (!froms[from].Contains(to))
            return false;

        return true;
    }

    public IEnumerable<int> FromsOf(int to)
    {
        if(tos.ContainsKey(to))
            return tos[to];
        else
            return new List<int>();
    }
}

class Program
{
    static void Main(string[] args)
    {
        Random r = new Random();
        Table t = new Table();

        int N = 1000000;

        for (int i = 0; i < N; i++)
            t.Add(r.Next(N), r.Next(N));

        DateTime t1 = DateTime.Now;
        for (int i = 0; i < N; i++)
        {
            if (t.Contains(r.Next(N), r.Next(N)))
            {
                // do something
            }
        }

        DateTime t2 = DateTime.Now;
        for (int i = 0; i < N; i++)
        {
            foreach (int j in t.FromsOf(r.Next(N)))
            {
                // do something
            }
        }

        DateTime t3 = DateTime.Now;

        Console.WriteLine($"IndexOf speed = {(t2 - t1).TotalMilliseconds / N}ms");
        Console.WriteLine($"FromsOf speed = {(t3 - t2).TotalMilliseconds / N}ms");
        Console.ReadKey();
    }
}
公共类表
{
公共字典froms{get;}=new Dictionary();
公共字典tos{get;}=新字典();
公共无效添加(int-from,int-to)
{
如果(!包含(从,到))
{
如果(!froms.ContainsKey(from))
{
Add(from,新HashSet{to});
}
其他的
{
froms[from]。添加(到);
}
如果(!tos.ContainsKey(to))
{
Add(to,newhashset{from});
}
其他的
{
tos[to]。添加(从);
}
}
}
公共布尔包含(int-from,int-to)
{
如果(!froms.ContainsKey(from))
返回false;
如果(!froms[from].包含(到))
返回false;
返回true;
}
公共IEnumerable FromsOf(int-to)
{
如果(tos.ContainsKey(to))
返回到;
其他的
返回新列表();
}
}
班级计划
{
静态void Main(字符串[]参数)
{
随机r=新随机();
表t=新表();
int N=1000000;
对于(int i=0;i
输出:

速度指数=0.0003220099毫秒

FromsOf速度=0.0003799996ms


我在dictionary中尝试使用dictionary,它也非常快,但内存使用量大约为33*N(对于任务管理器132 Mb中的N=10000000内存使用量)

代码:

公共类关系
{
公共int来自;
公共int至;
}
公共类表
{
公共列表关系{get;}=new List();
公共字典FromDic=新字典();
公共无效添加(int-from,int-to)
{
if(IndexOf(from,to)=-1)
{
int index=关系。计数;
Add(新关系(){From=From,To=To});
词典;
如果(!FromDic.TryGetValue(from,out innerDic))
{
innerDic=新字典();
FromDic[from]=内部DIC;
}
innerDic[to]=索引;
}
}
public int IndexOf(int-from,int-to)
{
托迪奇词典;
整数指数;
if(FromDic.TryGetValue(from,out toDic)和&toDic.TryGetValue(to,out index))
收益指数;
返回-1;
}
公共IEnumerable TosOf(int-from)
{
词典;
if(FromDic.TryGetValue(from,out innerDic))返回innerDic.Keys;
返回新列表();
}
}
班级计划
{
静态void Main(字符串[]参数)
{
随机r=新随机();
表t=新表();
int N=100000;
DateTime t0=DateTime.Now;
对于(inti=0;ipublic class Table
{
    public Dictionary<int, HashSet<int>> froms { get; } = new Dictionary<int, HashSet<int>>();
    public Dictionary<int, HashSet<int>> tos { get; } = new Dictionary<int, HashSet<int>>();

    public void Add(int from, int to)
    {
        if (!Contains(from, to))
        {
            if (!froms.ContainsKey(from))
            {
                froms.Add(from, new HashSet<int> { to });
            }
            else
            {
                froms[from].Add(to);
            }

            if (!tos.ContainsKey(to))
            {
                tos.Add(to, new HashSet<int> { from });
            }
            else
            {
                tos[to].Add(from);
            }
        }
    }

    public bool Contains(int from, int to)
    {
        if (!froms.ContainsKey(from))
            return false;

        if (!froms[from].Contains(to))
            return false;

        return true;
    }

    public IEnumerable<int> FromsOf(int to)
    {
        if(tos.ContainsKey(to))
            return tos[to];
        else
            return new List<int>();
    }
}

class Program
{
    static void Main(string[] args)
    {
        Random r = new Random();
        Table t = new Table();

        int N = 1000000;

        for (int i = 0; i < N; i++)
            t.Add(r.Next(N), r.Next(N));

        DateTime t1 = DateTime.Now;
        for (int i = 0; i < N; i++)
        {
            if (t.Contains(r.Next(N), r.Next(N)))
            {
                // do something
            }
        }

        DateTime t2 = DateTime.Now;
        for (int i = 0; i < N; i++)
        {
            foreach (int j in t.FromsOf(r.Next(N)))
            {
                // do something
            }
        }

        DateTime t3 = DateTime.Now;

        Console.WriteLine($"IndexOf speed = {(t2 - t1).TotalMilliseconds / N}ms");
        Console.WriteLine($"FromsOf speed = {(t3 - t2).TotalMilliseconds / N}ms");
        Console.ReadKey();
    }
}
    public class Relation
{
    public int From;
    public int To;
}

public class Table
{
    public List<Relation> Relations { get; } = new List<Relation>();
    public Dictionary<int, Dictionary<int, int>> FromDic = new Dictionary<int, Dictionary<int, int>>();

    public void Add(int from, int to)
    {
        if (IndexOf(from, to) == -1)
        {
            int index = Relations.Count;
            Relations.Add(new Relation() { From = from, To = to });

            Dictionary<int, int> innerDic;
            if (!FromDic.TryGetValue(from, out innerDic))
            {
                innerDic = new Dictionary<int, int>();
                FromDic[from] = innerDic;
            }
            innerDic[to] = index;
        }
    }

    public int IndexOf(int from, int to)
    {
        Dictionary<int, int> toDic;
        int index;
        if (FromDic.TryGetValue(from, out toDic) && toDic.TryGetValue(to, out index))
            return index;
        return -1;
    }

    public IEnumerable<int> TosOf(int from)
    {
        Dictionary<int, int> innerDic;
        if (FromDic.TryGetValue(from, out innerDic)) return innerDic.Keys;
        return new List<int>();
    }
}

class Program
{
    static void Main(string[] args)
    {
        Random r = new Random();
        Table t = new Table();

        int N = 100000;

        DateTime t0 = DateTime.Now;

        for (int i = 0; i < N; i++) t.Add(r.Next(N), r.Next(N));

        DateTime t1 = DateTime.Now;
        Console.WriteLine($"Add speed = {(t1 - t0).TotalMilliseconds * 1000 / N}mks");
        for (int i = 0; i < N; i++)
        {
            if (t.IndexOf(r.Next(N), r.Next(N)) != -1)
            {
                // do something
            }
        }

        DateTime t2 = DateTime.Now;
        Console.WriteLine($"IndexOf speed = {(t2 - t1).TotalMilliseconds * 1000 / N}mks");

        for (int i = 0; i < N; i++)
        {
            foreach (int j in t.TosOf(r.Next(N)))
            {
                // do something
            }
        }

        DateTime t3 = DateTime.Now;
        Console.WriteLine($"TosOf speed = {(t3 - t2).TotalMilliseconds * 1000 / N}mks");

        Console.ReadKey();
    }
}