关于通过标签取得相关文章的算法
比如有10000篇文章,每篇可能有0-10个标签,不同的标签共有1000个,用什么算法能最快地获取与指定文章相关度最高的其它文章?
用一个1000bit(归约为1024bit)数据类型来记录每篇文章包含了哪些标签,然后对这个数据进行与运算,以结果里出现的1的个数为标准排序即可。
规模大约为:
数据传输:1024bit=128Byte, 128Byte*10000=128B*10K=1MB(可以缓存,不是太大)
数据运算:比较次数为10000,每次比较1024bit。
得写个示例程序测试一下可行性。
1K Tags * 10K articles: 00:00:00.4684715
2K Tags * 20K articles: 00:00:01.7932927
3K tags * 30K articles: 00:00:04.0203271
10K tags * 100K articles: 00:00:44.2125127
基本上与问题规模成线性比例。
规模小于1K*10K时可以即时运算;
大一点可以提供后台运行的服务,异步延迟加载;
大于3K*30K就得在数据库里缓存结果了。
用一个1000bit(归约为1024bit)数据类型来记录每篇文章包含了哪些标签,然后对这个数据进行与运算,以结果里出现的1的个数为标准排序即可。
规模大约为:
数据传输:1024bit=128Byte, 128Byte*10000=128B*10K=1MB(可以缓存,不是太大)
数据运算:比较次数为10000,每次比较1024bit。
得写个示例程序测试一下可行性。
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
public class Test
{
static readonly int tagsCount=3000;
static readonly int articleCount=30000;
static List<BitArray> articleTags=new List<BitArray>(articleCount);
public static void Main()
{
Stopwatch sw=new Stopwatch();
sw.Start();
for(int i=0; i<articleCount; i++)
{
articleTags.Add(new BitArray(tagsCount));
}
List<CountAndIndex> countsAndIndex=new List<CountAndIndex>(articleCount);
for(int i=0; i<articleCount; i++)
{
countsAndIndex.Add(new CountAndIndex(Count(articleTags[0].And(articleTags[i])), i));
}
countsAndIndex.Sort();
sw.Stop();
Console.WriteLine(sw.Elapsed);
}
static int Count(BitArray bits)
{
int result=0;
foreach(bool bit in bits)
{
if(bit)
++result;
}
return result;
}
}
struct CountAndIndex : IComparable<CountAndIndex>
{
public int Count;
public int Index;
public CountAndIndex(int count, int index)
{
Count=count;
Index=index;
}
public int CompareTo(CountAndIndex other)
{
return this.Count.CompareTo(other.Count);
}
}
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
public class Test
{
static readonly int tagsCount=3000;
static readonly int articleCount=30000;
static List<BitArray> articleTags=new List<BitArray>(articleCount);
public static void Main()
{
Stopwatch sw=new Stopwatch();
sw.Start();
for(int i=0; i<articleCount; i++)
{
articleTags.Add(new BitArray(tagsCount));
}
List<CountAndIndex> countsAndIndex=new List<CountAndIndex>(articleCount);
for(int i=0; i<articleCount; i++)
{
countsAndIndex.Add(new CountAndIndex(Count(articleTags[0].And(articleTags[i])), i));
}
countsAndIndex.Sort();
sw.Stop();
Console.WriteLine(sw.Elapsed);
}
static int Count(BitArray bits)
{
int result=0;
foreach(bool bit in bits)
{
if(bit)
++result;
}
return result;
}
}
struct CountAndIndex : IComparable<CountAndIndex>
{
public int Count;
public int Index;
public CountAndIndex(int count, int index)
{
Count=count;
Index=index;
}
public int CompareTo(CountAndIndex other)
{
return this.Count.CompareTo(other.Count);
}
}
1K Tags * 10K articles: 00:00:00.4684715
2K Tags * 20K articles: 00:00:01.7932927
3K tags * 30K articles: 00:00:04.0203271
10K tags * 100K articles: 00:00:44.2125127
基本上与问题规模成线性比例。
规模小于1K*10K时可以即时运算;
大一点可以提供后台运行的服务,异步延迟加载;
大于3K*30K就得在数据库里缓存结果了。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· 从HTTP原因短语缺失研究HTTP/2和HTTP/3的设计差异
· 三行代码完成国际化适配,妙~啊~