求个最短距离,CASE很简单,可头都大了也没搞定。 ( 积分: 200 )

  • 主题发起人 主题发起人 whaway
  • 开始时间 开始时间
W

whaway

Unregistered / Unconfirmed
GUEST, unregistred user!
如图,连线表示距离为1个单位。
(6)--(2)
| /
| /
(1)--(3)--(5)
|
|
(4)
我的数据是这样记录的:
1,3
1,4
-----
2,3
2,6
-----
3,1
3,2
3,5
3,6
-----
4,1
-----
5,3
-----
6,2
6,3
-----
当然也可以改为无冗余的记录形式:
1,3
1,4
-----
2,3
2,6
-----
3,5
3,6
-----------------
问题是求每个点到(1)点的最短距离,根据这些数据记录用什么遍历可以实现这个算法???
答案很明显:(1)-0,(2)-2,(3)-1,(4)-1,(5)-2,(6)-2
 
如图,连线表示距离为1个单位。
(6)--(2)
| /
| /
(1)--(3)--(5)
|
|
(4)
我的数据是这样记录的:
1,3
1,4
-----
2,3
2,6
-----
3,1
3,2
3,5
3,6
-----
4,1
-----
5,3
-----
6,2
6,3
-----
当然也可以改为无冗余的记录形式:
1,3
1,4
-----
2,3
2,6
-----
3,5
3,6
-----------------
问题是求每个点到(1)点的最短距离,根据这些数据记录用什么遍历可以实现这个算法???
答案很明显:(1)-0,(2)-2,(3)-1,(4)-1,(5)-2,(6)-2
 
你到运筹学的书上去找,这个是典型的最短路径搜索,有成熟的算法
 
program MinLen_Dijsktra;
{$APPTYPE CONSOLE}
uses
SysUtils;
const
MaxN = 6;
Graph: array [1..MaxN, 1..MaxN] of Integer = ((0, 0, 1, 1, 0, 0),
(0, 0, 1, 0, 0, 1),
(1, 1, 0, 0, 1, 1),
(1, 0, 0, 0, 0, 0),
(0, 0, 1, 0, 0, 0),
(0, 1, 1, 0, 0, 0));
type
TNode = record
MinLen: Integer;
Marked: Boolean
end;

var
Nodes: array [1..MaxN] of TNode;
i, j: Integer;
procedure Init;
var
i: Integer;
begin
for i:=1 to MaxNdo
begin
Nodes.MinLen:=MaxInt;
Nodes.Marked:=False
end;
Nodes[1].MinLen:=0
end;

function FindMinUnMarked: Integer;
var
i: Integer;
Min: Integer;
begin
Result:=0;
Min:=MaxInt;
for i:=1 to MaxNdo
if not Nodes.Marked then
if Nodes.MinLen<Min then
begin
Min:=Nodes.MinLen;
Result:=i
end
end;

begin
Init;
repeat
i:=FindMinUnMarked;
if i>0 then
begin
Nodes.Marked:=True;
for j:=2 to MaxNdo
if Graph[i, j]>0 then
if Nodes.MinLen+Graph[i, j]<Nodes[j].MinLen then
Nodes[j].MinLen:=Nodes.MinLen+Graph[i, j]
end
until i=0;
for i:=1 to MaxNdo
if Nodes.MinLen<MaxInt then
WriteLn(i, ' : ', Nodes.MinLen);
ReadLn
end.
 
这里给一个递归的程序,可以求任意两点间的最短路径,结果把最短距离以及中间的路径都显示出来。
给分吧,呵呵!
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls;
type
TForm1 = class(TForm)
Button1: TButton;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;

var
Form1: TForm1;
implementation
{$R *.DFM}
procedure TForm1.Button1Click(Sender: TObject);
const Map:array[1..12,1..2] of integer
=((1,3),
(1,4),
(2,3),
(2,6),
(3,1),
(3,2),
(3,5),
(3,6),
(4,1),
(5,3),
(6,2),
(6,3));
var StepNowArr:array[1..6] of integer;
StepOutArr:array[1..6] of integer;
StepOut:integer;
StepMin:integer;
//递归搜索指定来源到指定目标的最短路径
proceduredo
Search(FromIndex, ToIndex, iStep:integer);
var i,j:integer;
begin
if (FromIndex=ToIndex) and (iStep<StepMin) then
begin
//到达目标,并且当前路径小于所记录的最短路径,则记录本次路径
StepMin:=iStep;
for j:=1 to StepMindo
StepOutArr[j]:=StepNowArr[j];
exit;
end;
if (iStep>=StepMin) or (iStep>=5) then
exit;
for i:=1 to 12do
if (FromIndex=Map[i,1]) and //所选路径的来源正是当前节点
(iStep+1<StepMin) then
//如果继续走还小于当前最短路径
begin
StepNowArr[iStep+1]:=Map[i,2];
//记录当前节点的目标
do
Search(Map[i,2],ToIndex,iStep+1);
//则递归继续搜索
end;
end;

//输出结果
proceduredo
Result(FromIndex, ToIndex:integer);
var i:integer;
s:string;
begin
s:=IntToStr(FromIndex);
for i:=1 to StepMindo
s:=s+'-->'+IntToStr(StepOutArr);
s:=s+' : '+IntToStr(StepMin);
showmessage(s);
end;

begin
//1--1
StepMin:=999;
do
Search(1,1,0);
do
Result(1,1);
//2--1
StepMin:=999;
do
Search(2,1,0);
do
Result(2,1);
//3--1
StepMin:=999;
do
Search(3,1,0);
do
Result(3,1);
//4--1
StepMin:=999;
do
Search(4,1,0);
do
Result(4,1);
//5--1
StepMin:=999;
do
Search(5,1,0);
do
Result(5,1);
//6--1
StepMin:=999;
do
Search(6,1,0);
do
Result(6,1);
end;

end.
 
后退
顶部