mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-08-18 01:19:16 +02:00
cody: lvlgraph: shuffle and apply best
git-svn-id: trunk@40420 -
This commit is contained in:
parent
7070a7dd26
commit
5f3d6729b0
@ -232,7 +232,7 @@ type
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
{$DEFINE CheckMinXGraph}
|
{off $DEFINE CheckMinXGraph}
|
||||||
type
|
type
|
||||||
TLvlGraph = class;
|
TLvlGraph = class;
|
||||||
TLvlGraphEdge = class;
|
TLvlGraphEdge = class;
|
||||||
@ -693,8 +693,10 @@ type
|
|||||||
TMinXGraph = class
|
TMinXGraph = class
|
||||||
private
|
private
|
||||||
FGraphNodeToNode: TPointerToPointerTree; // TLvlGraphNode to TMinXNode
|
FGraphNodeToNode: TPointerToPointerTree; // TLvlGraphNode to TMinXNode
|
||||||
procedure CreatePairs;
|
procedure UnbindPairs;
|
||||||
|
procedure BindPairs;
|
||||||
function ComputeCrossCount: integer;
|
function ComputeCrossCount: integer;
|
||||||
|
procedure StoreAsBest;
|
||||||
public
|
public
|
||||||
Graph: TLvlGraph;
|
Graph: TLvlGraph;
|
||||||
Levels: array of TMinXLevel;
|
Levels: array of TMinXLevel;
|
||||||
@ -706,8 +708,10 @@ type
|
|||||||
constructor Create(aGraph: TLvlGraph);
|
constructor Create(aGraph: TLvlGraph);
|
||||||
destructor Destroy; override;
|
destructor Destroy; override;
|
||||||
procedure InitSearch;
|
procedure InitSearch;
|
||||||
procedure StoreAsBest;
|
|
||||||
function FindBestPair: TMinXPair;
|
function FindBestPair: TMinXPair;
|
||||||
|
procedure SwitchCrossingPairs(MaxRun: int64; var Run: int64);
|
||||||
|
procedure Shuffle;
|
||||||
|
procedure SwitchAndShuffle(MaxSingleRun, MaxTotalRun: int64);
|
||||||
procedure SwitchPair(Pair: TMinXPair);
|
procedure SwitchPair(Pair: TMinXPair);
|
||||||
procedure Apply; // reorder Graph nodes
|
procedure Apply; // reorder Graph nodes
|
||||||
function GraphNodeToNode(GraphNode: TLvlGraphNode): TMinXNode; inline;
|
function GraphNodeToNode(GraphNode: TLvlGraphNode): TMinXNode; inline;
|
||||||
@ -717,19 +721,15 @@ type
|
|||||||
procedure LvlGraphMinimizeCrossings(Graph: TLvlGraph);
|
procedure LvlGraphMinimizeCrossings(Graph: TLvlGraph);
|
||||||
var
|
var
|
||||||
g: TMinXGraph;
|
g: TMinXGraph;
|
||||||
Pair: TMinXPair;
|
{%H-}Run: int64;
|
||||||
i: Integer;
|
|
||||||
begin
|
begin
|
||||||
if (Graph.LevelCount<2) or (Graph.NodeCount<3) then exit;
|
if (Graph.LevelCount<2) or (Graph.NodeCount<3) then exit;
|
||||||
g:=TMinXGraph.Create(Graph);
|
g:=TMinXGraph.Create(Graph);
|
||||||
try
|
try
|
||||||
g.InitSearch;
|
g.InitSearch;
|
||||||
for i:=1 to 100 do begin
|
Run:=0;
|
||||||
Pair:=g.FindBestPair;
|
g.SwitchAndShuffle(Graph.NodeCount*Graph.NodeCount div 3,
|
||||||
if Pair=nil then break;
|
Max(1000,Graph.NodeCount*Graph.NodeCount));
|
||||||
//debugln(['LvlGraphMinimizeCrossings ',Pair.AsString]);
|
|
||||||
g.SwitchPair(Pair);
|
|
||||||
end;
|
|
||||||
g.Apply;
|
g.Apply;
|
||||||
finally
|
finally
|
||||||
g.Free;
|
g.Free;
|
||||||
@ -1043,9 +1043,7 @@ begin
|
|||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
CreatePairs;
|
BindPairs;
|
||||||
|
|
||||||
CrossCount:=ComputeCrossCount;
|
|
||||||
|
|
||||||
{$IFDEF CheckMinXGraph}
|
{$IFDEF CheckMinXGraph}
|
||||||
ConsistencyCheck;
|
ConsistencyCheck;
|
||||||
@ -1067,37 +1065,52 @@ begin
|
|||||||
inherited Destroy;
|
inherited Destroy;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TMinXGraph.CreatePairs;
|
procedure TMinXGraph.UnbindPairs;
|
||||||
|
var
|
||||||
|
i: Integer;
|
||||||
|
begin
|
||||||
|
for i:=0 to length(Pairs)-1 do
|
||||||
|
Pairs[i].UnbindFromSwitchList;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TMinXGraph.BindPairs;
|
||||||
var
|
var
|
||||||
Cnt: Integer;
|
Cnt: Integer;
|
||||||
i: Integer;
|
i: Integer;
|
||||||
Level: TMinXLevel;
|
Level: TMinXLevel;
|
||||||
n: Integer;
|
n: Integer;
|
||||||
Pair: TMinXPair;
|
Pair: TMinXPair;
|
||||||
Crossing, SwitchedCrossing: integer;
|
First: Boolean;
|
||||||
begin
|
begin
|
||||||
|
First:=length(Pairs)=0;
|
||||||
|
if First then begin
|
||||||
|
Cnt:=0;
|
||||||
|
for i:=0 to length(Levels)-1 do
|
||||||
|
Cnt+=Max(0,length(Levels[i].Nodes)-1);
|
||||||
|
SetLength(Pairs,Cnt);
|
||||||
|
end;
|
||||||
Cnt:=0;
|
Cnt:=0;
|
||||||
for i:=0 to length(Levels)-1 do
|
|
||||||
Cnt+=Max(0,length(Levels[i].Nodes)-1);
|
|
||||||
SetLength(Pairs,Cnt);
|
|
||||||
Cnt:=0;
|
|
||||||
SameSwitchDiffPair0:=0;
|
|
||||||
for i:=0 to length(Levels)-1 do begin
|
for i:=0 to length(Levels)-1 do begin
|
||||||
Level:=Levels[i];
|
Level:=Levels[i];
|
||||||
SetLength(Level.Pairs,length(Level.Nodes)-1);
|
SetLength(Level.Pairs,length(Level.Nodes)-1);
|
||||||
for n:=0 to length(Level.Pairs)-1 do begin
|
for n:=0 to length(Level.Pairs)-1 do begin
|
||||||
Pair:=TMinXPair.Create(Level,n);
|
if First then begin
|
||||||
Pairs[Cnt]:=Pair;
|
Pair:=TMinXPair.Create(Level,n);
|
||||||
Level.Pairs[n]:=Pair;
|
Pairs[Cnt]:=Pair;
|
||||||
Pair.ComputeCrossingCount(Crossing,SwitchedCrossing);
|
Level.Pairs[n]:=Pair;
|
||||||
Pair.FSwitchDiff:=SwitchedCrossing-Crossing;
|
end else
|
||||||
SameSwitchDiffPair0:=Max(SameSwitchDiffPair0,Crossing+SwitchedCrossing);
|
Pair:=Pairs[Cnt];
|
||||||
|
Pair.FSwitchDiff:=Pair.ComputeSwitchDiff;
|
||||||
Cnt+=1;
|
Cnt+=1;
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
SetLength(SameSwitchDiffPairs,2*SameSwitchDiffPair0+1);
|
if First then begin
|
||||||
|
SameSwitchDiffPair0:=Graph.NodeCount;
|
||||||
|
SetLength(SameSwitchDiffPairs,2*SameSwitchDiffPair0+1);
|
||||||
|
end;
|
||||||
for i:=0 to length(Pairs)-1 do
|
for i:=0 to length(Pairs)-1 do
|
||||||
Pairs[i].BindToSwitchList;
|
Pairs[i].BindToSwitchList;
|
||||||
|
CrossCount:=ComputeCrossCount;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TMinXGraph.ComputeCrossCount: integer;
|
function TMinXGraph.ComputeCrossCount: integer;
|
||||||
@ -1135,8 +1148,7 @@ end;
|
|||||||
|
|
||||||
procedure TMinXGraph.InitSearch;
|
procedure TMinXGraph.InitSearch;
|
||||||
begin
|
begin
|
||||||
BestCrossCount:=-1;
|
StoreAsBest;
|
||||||
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TMinXGraph.StoreAsBest;
|
procedure TMinXGraph.StoreAsBest;
|
||||||
@ -1165,6 +1177,61 @@ begin
|
|||||||
Result:=nil;
|
Result:=nil;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
procedure TMinXGraph.SwitchCrossingPairs(MaxRun: int64; var Run: int64);
|
||||||
|
var
|
||||||
|
i: int64;
|
||||||
|
Pair: TMinXPair;
|
||||||
|
begin
|
||||||
|
for i:=1 to MaxRun do begin
|
||||||
|
Pair:=FindBestPair;
|
||||||
|
Run+=1;
|
||||||
|
if (Pair=nil) or (Pair.SwitchDiff=0) then exit;
|
||||||
|
SwitchPair(Pair);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TMinXGraph.Shuffle;
|
||||||
|
var
|
||||||
|
l: Integer;
|
||||||
|
Level: TMinXLevel;
|
||||||
|
n1: Integer;
|
||||||
|
n2: Integer;
|
||||||
|
Node: TMinXNode;
|
||||||
|
begin
|
||||||
|
{$IFDEF CheckMinXGraph}
|
||||||
|
ConsistencyCheck;
|
||||||
|
{$ENDIF}
|
||||||
|
UnbindPairs;
|
||||||
|
for l:=0 to length(Levels)-1 do begin
|
||||||
|
Level:=Levels[l];
|
||||||
|
for n1:=0 to length(Level.Nodes)-1 do begin
|
||||||
|
n2:=Random(length(Level.Nodes));
|
||||||
|
if n1=n2 then continue;
|
||||||
|
Node:=Level.Nodes[n1];
|
||||||
|
Level.Nodes[n1]:=Level.Nodes[n2];
|
||||||
|
Level.Nodes[n2]:=Node;
|
||||||
|
Level.Nodes[n1].IndexInLevel:=n1;
|
||||||
|
Level.Nodes[n2].IndexInLevel:=n2;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
BindPairs;
|
||||||
|
{$IFDEF CheckMinXGraph}
|
||||||
|
ConsistencyCheck;
|
||||||
|
{$ENDIF}
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TMinXGraph.SwitchAndShuffle(MaxSingleRun, MaxTotalRun: int64);
|
||||||
|
var
|
||||||
|
Run: int64;
|
||||||
|
begin
|
||||||
|
Run:=1;
|
||||||
|
repeat
|
||||||
|
SwitchCrossingPairs(MaxSingleRun,Run);
|
||||||
|
if Run>MaxTotalRun then exit;
|
||||||
|
Shuffle;
|
||||||
|
until false;
|
||||||
|
end;
|
||||||
|
|
||||||
procedure TMinXGraph.SwitchPair(Pair: TMinXPair);
|
procedure TMinXGraph.SwitchPair(Pair: TMinXPair);
|
||||||
|
|
||||||
procedure UpdateSwitchDiff(TargetOfNode1, TargetOfNode2: TMinXNode);
|
procedure UpdateSwitchDiff(TargetOfNode1, TargetOfNode2: TMinXNode);
|
||||||
@ -1229,6 +1296,9 @@ begin
|
|||||||
for j:=0 to length(Node2.InEdges)-1 do
|
for j:=0 to length(Node2.InEdges)-1 do
|
||||||
UpdateSwitchDiff(Node1.InEdges[i],Node2.InEdges[j]);
|
UpdateSwitchDiff(Node1.InEdges[i],Node2.InEdges[j]);
|
||||||
|
|
||||||
|
if (BestCrossCount<0) or (BestCrossCount>CrossCount) then
|
||||||
|
StoreAsBest;
|
||||||
|
|
||||||
{$IFDEF CheckMinXGraph}
|
{$IFDEF CheckMinXGraph}
|
||||||
ConsistencyCheck;
|
ConsistencyCheck;
|
||||||
{$ENDIF}
|
{$ENDIF}
|
||||||
@ -1239,14 +1309,11 @@ var
|
|||||||
i: Integer;
|
i: Integer;
|
||||||
Level: TMinXLevel;
|
Level: TMinXLevel;
|
||||||
j: Integer;
|
j: Integer;
|
||||||
Node: TMinXNode;
|
|
||||||
begin
|
begin
|
||||||
for i:=0 to length(Levels)-1 do begin
|
for i:=0 to length(Levels)-1 do begin
|
||||||
Level:=Levels[i];
|
Level:=Levels[i];
|
||||||
for j:=0 to length(Level.Nodes)-1 do begin
|
for j:=0 to length(Level.BestNodes)-1 do
|
||||||
Node:=Level.Nodes[j];
|
Level.BestNodes[j].IndexInLevel:=j;
|
||||||
Node.GraphNode.IndexInLevel:=Node.IndexInLevel;
|
|
||||||
end;
|
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user