- 最后登录
- 2024-11-21
- 在线时间
- 9667 小时
- 阅读权限
- 100
- 注册时间
- 2007-12-26
- 积分
- 37843
- 帖子
- 34374
- 精华
- 15
- UID
- 16477
- 性别
- 保密
- 积分
- 37843
- 帖子
- 34374
- 精华
- 15
- UID
- 16477
- 性别
- 保密
|
这个是标准算法,抄的书上的程序,不用看了。
var
VeryBig:integer;
TempGr:BiGraph;
L:array[1..MaxBox*2] of integer;
SetX,SetY,MatchedX,MatchedY:Set of 1..MaxBox;
procedure MaxMatch(n,m:integer);
function Path(x:integer):boolean;
var
i,j:integer;
begin
Path:=false;
for i:=1 to m do
if not (i in SetY)and(Gr[x,i]<>0) then
begin
SetY:=SetY+;
if not (i in MatchedY) then
begin
Gr[x,i]:=-Gr[x,i];
MatchedY:=MatchedY+;
Path:=true;
exit;
end;
j:=1;
while (j<=m)and not (j in SetX) and (Gr[j,i]>=0) do inc(j);
if j<=m then
begin
SetX:=SetX+[j];
if Path(j) then
begin
Gr[x,i]:=-Gr[x,i];
Gr[j,i]:=-Gr[j,i];
Path:=true;
exit;
end;
end;
end;
end;
var
u,i,j,al:integer;
begin
Fillchar(L,sizeof(L),0);
TempGr:=Gr;
for i:=1 to n do
for j:=1 to m do
if L<Gr[i,j] then
L:=Gr[i,j];
u:=1; MatchedX:=[]; MatchedY:=[];
for i:=1 to n do
for j:=1 to m do
if L+L[n+j]=TempGr[i,j] then
Gr[i,j]:=1
else
Gr[i,j]:=0;
while u<=n do
begin
SetX:=; SetY:=[];
if not (u in MatchedX) then
begin
if not Path(u) then
begin
al:=Infinite;
for i:=1 to n do
for j:=1 to m do
if (i in SetX) and not (j in SetY) and (L+L[n+j]-TempGr[i,j]<al
) then
al:=L+L[n+j]-TempGr[i,j];
for i:=1 to n do if i in SetX then L:=L-al;
for i:=1 to m do if i in SetY then l[n+i]:=l[n+i]+al;
for i:=1 to n do
for j:=1 to m do
if l+l[n+j]=TempGr[i,j] then
Gr[i,j]:=1
else
Gr[i,j]:=0;
MatchedX:=[]; MatchedY:=[];
for i:=1 to n+m do
if l<-1000 then
exit;
end
else
MatchedX:=MatchedX+;
u:=0;
end;
inc(u);
end;
end;
var
i,j:integer;
Tot:integer;
begin
VeryBig:=0;
for i:=1 to BoxCount do
for j:=1 to BoxCount do
if (Gr[i,j]<Infinite)and(Gr[i,j]>VeryBig) then
VeryBig:=Gr[i,j];
inc(VeryBig);
for i:=1 to BoxCount do
for j:=1 to BoxCount do
if Gr[i,j]<Infinite then
Gr[i,j]:=VeryBig-Gr[i,j]
else
Gr[i,j]:=0;
这些语句是进行补集转化。
MaxMatch(BoxCount,BoxCount);
Tot:=0;
for i:=1 to BoxCount do
begin
for j:=1 to BoxCount do
if Gr[i,j]<0 then
begin
Tot:=Tot+VeryBig-TempGr[i,j];
break;
end;
if Gr[i,j]>=0 then
begin
MinMatch:=Infinite;
exit;
end;
end;
MinMatch:=Tot;
end;
function CalcHeuristicFunction(State:StateType):integer;
计算启发函数值
var
H,Min:integer;
i,j,p,Count,BoxCount,Cost:integer;
BoxPos:array[1..MaxBox] of integer;
Distance:BiGraph;
begin
p:=0;
for i:=1 to MaxPosition do
if GetBit(State.Boxes,i)>0 then
begin
inc(p);
BoxPos[p]:=i;
end;
for i:=1 to p do
for j:=1 to p do
Distance[i,j]:=MinPush(BoxPos,SokoMaze.GoalPosition[j]);
BoxCount:=SokoMaze.BoxCount;
H:=0;
for i:=1 to BoxCount do
begin
Count:=0;
for j:=1 to BoxCount do
if Distance[i,j]<Infinite then
inc(Count);
if Count=0 then
有一个箱子推不到任何目的地
begin
CalcHeuristicFunction:=Infinite;
exit;
end;
end;
H:=MinMatch(BoxCount, Distance);
CalcHeuristicFunction:=H;
end;
function HashFunction(State:StateType):integer;
var
i,h,p:integer;
begin
h:=0;
p:=0;
for i:=1 to MaxPosition do
if GetBit(State.Boxes,i)>0 then
begin
inc(p);
h:=(h+p*i) mod HashMask;
你可以自己换一个
end;
HashFunction:=h;
end;
function SameState(S1,S2:StateType):boolean;
var
i:integer;
begin
SameState:=false;
for i:=1 to MaxPosition do
if GetBit(S1.Boxes,i)<>GetBit(S2.Boxes,i) then
exit;
if not CanReach(S1,S2.ManPosition) then
注意只要两个状态人的位置是相通的就应该算同一个状态
exit;
SameState:=true;
end; |
|