荔园在线
荔园之美,在春之萌芽,在夏之绽放,在秋之收获,在冬之沉淀
[回到开始]
[上一篇][下一篇]
发信人: Version (无题), 信区: Program
标 题: 用“综合优化”解决黄金图形源程序:{ backtracking
发信站: 荔园晨风BBS站 (Wed Jun 11 23:18:46 2003), 站内信件
【程 序】
一、用“综合优化”解决黄金图形源程序:{ backtracking method }
Const
input = 'golygon.dat';
output= 'golygon.out';
path : Array [1..4, 1..2] of integer =
((1, 0), (0, -1), (-1, 0), (0, 1));
head : Array [1..4] of char =
('e', 's', 'w', 'n');
clogs = 50; { m <= clogs }
ways = 24; { n <= ways }
Var
fp : text;
n, { 最长步数 }
m, { 障碍物数 }
o { 路径指针 }
: byte;
clog : Array [1..clogs] of { 储存障碍物坐标 }
Record x, y : integer End;
way : Array [0..ways] of byte;{ 储存路径 }
results : integer; { 路径数 }
Procedure _init; { 初始化 }
Var i : byte;
Begin
Assign(fp, input); Reset(fp);
Readln(fp, n); Readln(fp, m);
for i := 1 to m do
Readln(fp,clog[i].x, clog[i].y);
Close(fp);
Assign(fp, output); Rewrite(fp)
End;
Procedure _out; { 输出路径 }
Var i, j, t : byte; x, y : integer;
b : boolean;
Begin
for j := 1 to 4 do
Begin
x := 0; y := 0; b := TRUE;
for i := 1 to o do
Begin
x := x+path[way[i]][1]*i;
y := y+path[way[i]][2]*i;
for t := 1 to m do
if(x=clog[t].x) and((y-path[way[i]][2]*i<clog[t].y)
and(y >= clog[t].y) or (y-path[way[i]][2]*i >
clog[t].y)
and(y <= clog[t].y)) or (y = clog[t].y)
and((x-path[way[i]][1]*i < clog[t].x)
and(x >= clog[t].x) or (x-path[way[i]][1]*i >
clog[t].x)
and(x <= clog[t].x))
{ 如果通过障碍物 }
then Begin b := FALSE; Break End;
if not b then Break
End;
if b then
Begin
Inc(results);
for i := 1 to o do Write(fp, head[way[i]]);
Writeln(fp)
End;
for i := 1 to o do way[i] := way[i] mod 4 + 1 { 旋转路径 }
End
End;
Function _sum(step : integer) : integer;
Var i, r : integer;
Begin
r := 0;
for i := step+1 to n do Inc(r, i);
_sum := r
End;
Function _is_able_to_pass (x, y, i, step : integer) : boolean;
Var t : integer;
Begin
_is_able_to_pass := TRUE;
if (abs(x) > _sum(step)) or
(abs(y) > _sum(step)) or { 不能“回头”了? }
(i = way[o]) { 重复走同一个方向了? }
or (abs(i-way[o]) = 2){ 折返了? }
then _is_able_to_pass := FALSE
End;
Procedure _main(step, x, y : integer);
{ step – 第几步 x, y – 当前坐标 }
Var i : byte;
Begin
if (x = 0) and (y = 0) and (step = n+1)then
Begin
_out; { 若到达(0,0)则输出,回溯 } Exit
End;
if step > n then Exit; { 如果超过步数没有回到起点就回溯 }
for i := 1 to 4 do { 尝试每个方向 }
if _is_able_to_pass { 如果通行 }(x+path[i][1]*step,
y+path[i][2]*step, i, step) then
Begin
Inc(o); way[o] := i; { 存下路径 }
_main(step+1, { 走下一步 }
x+path[i][1]*step, y+path[i][2]*step); { 改变坐标
}
Dec(o) { 恢复原来的路径 }
End
End;
Procedure _exit;
Begin
Writeln(fp, 'Found ', results, ' golygon(s).');
Close(fp)
End;
Begin
_init;
o := 1; way[1] := 1;
_main(2, 1, 0);
_exit
End.
二、用动态规划求上界再搜索的迷宫问题源程序:(为了便于测试,没有输出路径
)
Const
input = 'trip.dat';
output= 'trip.out';
path : Array [1..4, 1..2] of shortint =
((-1, 0), (1, 0), (0, -1), (0, 1));
maxn = 30;
maxm = 30;
Var
fp : text;
n, m, x0, y0, x1, y1, all, o, results, xx : longint;
{ all – 路径总数;results – 上界 }
r : Array [1..maxn, 1..maxm] of shortint;
{ 迷宫,0-可行,-1 –障碍 }
way : Array [1..1000] of byte;{ 储存路径 }
l : Array [1..maxn, 1..maxm] of integer; { 动态规划的数组 }
Procedure _init;
Var a, b, x : byte;
Begin
Assign(fp, input); Reset(fp);
Readln(fp, n, m, x);
for x := x downto 1 do
Begin
Readln(fp, a, b);
r[a,b] := -1
End;
Readln(fp, x0, y0, x1, y1);
Close(fp);
Assign(fp, output); Rewrite(fp)
End;
Procedure _solve; { 动态规划 }
Var i, j, k : integer; b : boolean;
Begin
l[x0,y0] := 1;
Repeat
b:= TRUE;
for i := 1 to n do
for j := 1 to m do
for k := 1 to 4 do
if (l[i,j] > 0) then
if (i+path[k][1] > 0)
and (i+path[k][1] <= n)
and (j+path[k][2] > 0)
and (j+path[k][2] <= m) then { 没越界 }
if (r[i+path[k][1],j+path[k][2]] <>
-1) then { 不是障碍 }
if (l[i,j]+1 < l[i+path[k][1],
j+path[k][2]]) or
(l[i+path[k][1],
j+path[k][2]] = 0) then
Begin
l[i+path[k][1],
j+path[k][2]] := l[i,j] + 1;
{ 填数组,l[I,j]表示该
格的“估价值” }
b := FALSE
End
Until b; { 一直循环到不再修改数组 }
results := abs(l[x1,y1] - l[x0,y0]){ 得出上界 }
End;
Procedure _main(x, y : byte);
Var i : byte;
Begin
if abs(l[x1,y1]-l[x,y]) > results then Exit; { 如果超出上界就立刻回
溯 }
if (x = x1) and (y = y1) then
Begin Inc(all); Exit End; { 到达终点,输出 }
for i := 1 to 4 do
if (x+path[i][1] > 0) and (x+path[i][1] <= n)
and (y+path[i][2] > 0) and (y+path[i][2] <= m)
and (r[x+path[i][1],y+path[i][2]] <> -1)
{ 不越界,而且不遇到障碍 }
and (abs(l[x1,y1]-l[x+path[i][1],y+path[i][2]]) < abs(l[x1,
y1]-l[x,y]))
{如果那一格的“估价值”比当前这一格好才往那个方向走 }
then Begin
Inc(o);
way[o] := i; r[x,y] := -1; { 存储路径,把走过的格置成障碍 }
_main(x+path[i][1], y+path[i][2]);{ 搜索下一格 }
Dec(o); r[x,y] := 0
End
End;
Procedure _exit;
Var i, j : byte;
Begin
Writeln(fp, all);
Close(fp)
End;
Begin
_init;
_solve;
_main(x0, y0);
_exit
End.
--
*
* *
* *
no more to say
★ just wish you ★
good luck
※ 来源:·荔园晨风BBS站 bbs.szu.edu.cn·[FROM: 192.168.1.50]
[回到开始]
[上一篇][下一篇]
荔园在线首页 友情链接:深圳大学 深大招生 荔园晨风BBS S-Term软件 网络书店