最大匹配算法
‘壹’ 为什么中文分词的几大主流分词技术,没有用逆向最大匹配或者双向最大匹配分词算法的呢
速度是关键,逆向最大匹配需要专门创建逆向匹配索引。操作维护比较麻烦
‘贰’ 二分图最大匹配Matlab程序(在线等,感激不尽!)
第一个问题比较简单,这里懒得对着你的图片敲数据,用随机数代替
long=100;
A=0.1*rand(long,1);
B=0.15*rand(long,1);
[AA BB]=meshgrid(A,B);
gg=0.5017*AA-0.65*BB;
g=gg>=-0.03&gg<=0.03; %这就是gij矩阵,相当于二分图的连接矩阵
[num h] = maxnum(g);%第二个问题就是求二分图的最大匹配问题,这里
%调用了一个自己写maxnum函数,返回num就是最大值,h是hij(不唯一)
以下是maxnum.m的内容,用的是匈牙利算法
其中还用了一个递归的incpath函数,寻找增广路径
function[numh]=maxnum(g)
s=size(g);
globalG_h;%矩阵hij记录选中
globalG_g;%矩阵gij记录匹配
globalG_v;%记录当前一次路径访问过的节点
G_h=false(s);%矩阵hij初始为空
G_g=g;%矩阵gij就是传递进来的参数g
fori=1:s(1)
G_v=false(1,s(2));%每次初始化径访问过的节点为空
incpath(i);%从Ai开始寻找增广路径
end
h=G_h;num=sum(h(:));%输出最大匹配数,和匹配矩阵h
clearglobal'G_h';clearglobal'G_g';
end
functionOK=incpath(i)%从Ai开始
globalG_h;globalG_g;globalG_v;OK=false;
j=find(~G_h(i,:)&G_g(i,:)&~G_v,1);%寻找合条件的Bj
ifisempty(j),return;end%找不到返回false
G_v(j)=true;%找到了,标记Bj为以访问节点
ii=find(G_h(:,j));%寻找Bj在原来匹配中
ifisempty(ii)%如果不在原匹配中
G_h(i,j)=true;OK=true;return;end%找到增广路径末端,返回true
ok=incpath(ii);%如果在原来的匹配中,根据匹配对应的Aii递归调用incpath寻找
ifok%如果递归寻找返回成功
G_h(i,j)=~G_h(i,j);G_h(ii,j)=~G_h(ii,j);OK=true;return;end%路径反色返回true
end
‘叁’ 求一般图的最大权匹配的算法(最好详细一些,注意数最大权匹配),高分求助!
Algorithmus 3.3 Kruskal's Algorithm 时间复杂度 O(mlog n)
m边数 n点数
输入: 图 G = (V;E) 和 权c : E -》R.
输出: 一棵最优树 T.
begin
把所有边以权的大小按从小到大排序
T := (VG,ET ) := (VG, 空);
for i = 1 to m do
if T + ei 没有圈 then
T := (VG;ET 并上 {ei});
if end
for end
end
或者 Algorithmus 3.5 Prim's Algorithm 时间复杂度O(m+n log n)
‘肆’ 用匈牙利算法求最大匹配唯一么
不惟一。扩张的顺序不同,枚举顶点的顺序不同,解就不一定相同
‘伍’ 图的最大匹配算法的c或c++实现
匈牙利算法
#include<iostream>
#include<string>
#include<vector>
using namespace std;
bool mark1[100],mark2[100];
int list[100];
int n,m,edge,num;c
ector<vector<int> > v;
bool dfs(int to)
{
register int i,point,s = list[to];
for(i=0;i<v[s].size();i++)
{
point = v[s][i];
if(!mark2[point])
continue;
mark2[point] = false;
if(list[point]==-1 || dfs(point)){
list[point] = s;
return true;
}
}
return false;
}
void Solve()
{
int i,j,point;
bool flog = false;
memset(mark1,true,sizeof(mark1));
memset(list,-1,sizeof(list));
num=0;
for(i=0;i<n;i++)
{
for(j=0;j<v[i].size();j++)
if(list[v[i][j]] == -1)
{
mark1[i] = false;
list[v[i][j]] = i;
num++;
if(i==0) flog = true;
break;
}
}
for(i=0;i<n;i++)
{
if(mark1[i])
{
if(!v[i].empty()){
memset(mark2,true,sizeof(mark2));
for(j=0;j<v[i].size();j++)
{
point = v[i][j];
if(!mark2[point]) continue;
mark2[point] = false;
if(list[point] == -1 || dfs(point))
{
list[point] = i;
num++;
break;
}
}
}mark1[i] = false;
}
}
if(flog || list[0] != -1)
cout << num-1 << endl;
else cout << num << endl;
}
int main()
{
int i,j,s,d;
while(cin>>n)
{
if(n == 0)break;
v.clear();
v.resize(n);
cin >> m >> edge;
for(i=0;i<edge;i++)
{
cin >> j >> s >> d;
v[s].push_back(d);
}
Solve();
}
return 0;
}
‘陆’ 最大匹配算法中,如何组织和存储词典
主要看你的词表结构了,最大词长的初始值,查词典的次数和匹配的次数,然后得出时间复杂度,原始hash算法复杂度没记错的话应该是2.89,11年看过一个文献,提出一种改进的算法时间复杂度是2.291…… 另外
‘柒’ 中文分词中正向最大匹配算法的分词速度是多少准确率大概为多少
主要看你的词表结构了,最大词长的初始值,查词典的次数和匹配的次数,然后得出时间复杂度,原始hash算法复杂度没记错的话应该是2.89,11年看过一个文献,提出一种改进的算法时间复杂度是2.291……
另外,分词算法并不是原封不动的,比如有些搜索引擎的词表结构就采用tire树结构,这样不用设置最大词长,不过内存空间方面就要有取舍,甚至还有采用减少查典次数增加匹配次数的搜索引擎……
所以单纯的给你一个189.3m/M纯内存分词速度,但是这算法换个台更高配置的服务器却变成了497.6ms/M,这没有任何意义……
记得哪个文献上有人说,分词本身不是目的,而是后续处理过程的必要阶段,所以,除非你是研究算法的,否则单纯追求这东西的速度和准确率没什么太大意义
‘捌’ matlab用正向最大匹配算法实现中文分词!急!!!
sqlConnection con = new SqlConnection
con.Open();
string sqlstr = "sql语句";
SqlDataAdapter da = new SqlDataAdapter(sqlstr, con);
DataSet ds= new DataSet();
da.Fill(ds);
dataGridView1.DataSource = ds.Tables[0];
con.Close();
‘玖’ 什么叫正向最大匹配算法,反向最大匹配算法
分词算法里的吧
比如 我是一个好人
由于 词语很多,所以分词中先设定一个可能的,最长的词组的词数
比如说,我认定最长的词组是3个字,那在比对中,会将句子3个字为始进行比对
正向匹配算法好象是从左到右 反向区域算法是从右到左,具体忘记了
以 “我是一个好人” 为例
正向的顺序为
我是一
我是
我 ===> 得到一个词
是一个
是一
是 ===>得到一个词
一个好
一个===> 得到一个词
好人===>得到一个词
结果 我、是、一个、好人
反向算法
个好人
好人==> 好人
是一个
一个==> 一个
我是
是==> 是
我==> 我
结果 我、是、一个、好人
‘拾’ 求二分图最大匹配的最大流算法,附Pascal程序
program bgf;
const maxn=402;
var map:array[1..maxn,1..maxn]of longint;
hash:array[1..maxn]of boolean;
n,m,ans:longint;
procere init;
var i,j,x,s:longint;
begin
readln(n,m);
fillchar(map,sizeof(map),0);
for i:=2 to n+1 do map[1,i]:=1;
for i:=1 to n do
begin
read(s);
for j:=1 to s do
begin
read(x);
map[i+1,x+n+1]:=1;
end;{for}
readln;
end;{for}
for i:=n+2 to n+m+1 do map[i,n+m+2]:=1;
n:=n+m+2;
end;{init}
function min(a,b:longint):longint;
begin
if a<b then exit(a)
else exit(b);
end;{min}
function DFS(u,low:longint):longint;
var i,num:longint;
begin
if u=n then exit(low);
if hash[u] then exit(0);
hash[u]:=true;
for i:=1 to n do
if (map[u,i]>0)and(not hash[i]) then
begin
num:=DFS(i,min(low,map[u,i]));
if num>0 then
begin
dec(map[u,i],num);
inc(map[i,u],num);
exit(num);
end;{if}
end;{if}
exit(0);
end;{DFS}
procere calc;
var flow:longint;
begin
ans:=0;
repeat
fillchar(hash,sizeof(hash),0);
flow:=DFS(1,maxint);
if flow>0 then ans:=ans+flow;
until flow<=0;
end;{calc}
procere print;
begin
writeln(ans);
end;{print}
begin{main}
init;
calc;
print;
end.