algorytm.org

Implementacja w Delphi/Pascal



Baza Wiedzy
wersja offline serwisu przeznaczona na urządzenia z systemem Android
Darowizny
darowiznaWspomóż rozwój serwisu
Nagłówki RSS
Artykuły
Implementacje
Komentarze
Forum
Bookmarki






Sonda
Implementacji w jakim języku programowania poszukujesz?

Algorytm Prima - Implementacja w Delphi/Pascal
Ocena użytkownikóww: *****  / 10
SłabyŚwietny
Nadesłany przez Michał Knasiecki, 09 sierpnia 2005 01:00
Kod przedstawiony poniżej przedstawia główną część rozwiązania problemu.
Pobierz pełne rozwiązanie.

Jeżeli nie odpowiada Ci sposób formatowania kodu przez autora skorzystaj z pretty printer'a i dostosuj go automatycznie do siebie.

prim_d/Unit1.pas:
//Program pobrany ze strony www.algorytm.org
//Opracowal Michal Knasiecki

//UWAGA!!!!!!!!!!!

{Przykladowy graf jest zapisany w pliku graf.txt
Struktura pliku jest następująca:

Rozmiar
:waga:waga:...waga:
:waga:waga:...Waga:
...................
:waga:waga:...Waga:



Gdzie liczba kolumn i wierszy macierzy jest równa rozmiarowi.
Jesli waga=0 to nie istnieje krawędź lącząca odpowiednie wierzcholki}

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  Menus, StdCtrls;

type
  TForm1 = class(TForm)
    MainMenu1: TMainMenu;
    Plik1: TMenuItem;
    Wczytajlist1: TMenuItem;
    Wyczy1: TMenuItem;
    N1: TMenuItem;
    Zakocz1: TMenuItem;
    ListBox1: TListBox;
    Button1: TButton;
    Memo1: TMemo;
    OpenDialog1: TOpenDialog;
    Button2: TButton;
    Label1: TLabel;
    SaveDialog1: TSaveDialog;
    N2: TMenuItem;
    Zapiszraport1: TMenuItem;
    Label2: TLabel;
    Label3: TLabel;
    procedure Button1Click(Sender: TObject);
    procedure Wczytajlist1Click(Sender: TObject);
    procedure Wyczy1Click(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure Button2Click(Sender: TObject);
    procedure Zakocz1Click(Sender: TObject);
    procedure Zapiszraport1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;
           wsk=^list;
        list=record
                vert:integer;
                waga:integer;
                next:wsk;
                end;

         EdgeList=^edge;
         edge=record
                pop:integer;
                nast:integer;
                waga:integer;
                next:edgelist;
                end;
       TCzas=class
        start,stop:Tdatetime;
        function Podaj:Tdatetime;
        function Oblicz:integer;
        end;

var
Form1: TForm1;
first:edgelist;
tablica:array of wsk;
current:wsk;
currlist:edgelist;
time,id,n:integer;
czas:tczas;
d,p,f:array of integer;
connected:boolean;
globalX,globalY,globalW:integer;
tree:array of boolean;
treeN:integer;
koszt:integer;
implementation

{$R *.DFM}
function tczas.Podaj:TDateTime;
begin
Result:=Now;
end;
function Tczas.Oblicz:integer;
begin
result:=trunc(TimeStampToMSecs(DateTimeToTimeStamp(czas.stop))-
TimeStampToMSecs(DateTimeToTimeStamp(czas.start)));
end;

procedure AddToList(tab:integer;vert:integer;waga:integer;var current:wsk);
var prev,next:wsk;
t:boolean;
begin
t:=false;
if tablica[tab]=nil then t:=true;
if tablica[tab]<>nil then
        begin
        prev:=current;
        next:=current^.next;
        end else
        begin
        prev:=nil;
        next:=nil;
        end;
new(current);
current^.vert:=vert;
current^.waga:=waga;
current^.next:=next;
if prev<>nil then prev^.next:=current;
if t=true then tablica[tab]:=current;
end;
procedure Removeall2;
var tmp,next:edgelist;
begin
tmp:=first;
while tmp<>nil do
begin
next:=tmp^.next;
dispose(tmp);
tmp:=next;
end;
end;

procedure Removeall(tab:integer);
var next:wsk;
begin
if tablica[tab]<>nil then begin
next:=tablica[tab];
repeat
if next<>nil then current:=next;
{if current=tablica[tab]
then form1.listbox1.items.add('Wierzcholek: '+inttostr(current^.vert)) else
form1.listbox1.items.add(inttostr(current^.vert));}
next:=current^.next;
{if remove=true then}
if current<>tablica[tab] then dispose(current) else tablica[tab]:=nil;
until next=nil;
end;
end;
procedure Wypisz(tab:integer);
var next:wsk;
begin
if tablica[tab]<>nil then begin
next:=tablica[tab];
repeat
if next<>nil then current:=next;
if form1.ListBox1.Items.Capacity<32000 then
if current=tablica[tab]
then form1.listbox1.items.add('Wierzcholek: '+inttostr(current^.vert)) else
form1.listbox1.items.add(inttostr(current^.vert)+' ['+inttostr(current^.waga)+']');
next:=current^.next;
until next=nil;
end;
end;
procedure TForm1.Button1Click(Sender: TObject);
var i:integer;
begin
listbox1.clear;
for i:=1 to n do wypisz(i);
end;
function podajwage(s:string;i:integer):integer;
var p,j:integer;
c:string[1];
tmp:string;
begin
j:=0;
p:=1;
repeat
c:=s[p];
inc(p);
if c=':' then inc(j);
until j=i;
tmp:='';
repeat
c:=s[p];
inc(p);
if c<>':' then tmp:=tmp+c;
until c=':';
result:=strtoint(tmp);
end;
procedure TForm1.Wczytajlist1Click(Sender: TObject);
var f:textfile;
 s:string;
 waga,i,j:integer;
begin
if opendialog1.execute then
 begin
 assignfile(f,opendialog1.filename);
 reset(f);
 readln(f,s);
 n:=strtoint(s);
 setlength(tablica,n+1);
 current:=nil;
 for i:=1 to n do
        begin
        readln(f,s);
        for j:=1 to n do
        begin
        if j=1 then addtolist(i,i,0,current); {***********}
        waga:=podajwage(s,j);
        if waga>0 then addtolist(i,j,waga,current);
//        if strtoint(s[j])>0 then addtolist(i,j,waga,current);
        end;
        end;
 closefile(f);
 memo1.lines.add('> Graf wczytany...');
 memo1.lines.add('> Liczba wierzchołków:  '+inttostr(n));
 memo1.lines.add('> Liczba krawędzi:  '+inttostr(round((n+(n*(n-3)/2))*0.6)));
 end;
end;

procedure TForm1.Wyczy1Click(Sender: TObject);
var i:integer;
begin
for i:=1 to n do removeall(i);
removeall2;
finalize(tablica);
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
czas:=tczas.create;
end;
function next(w:wsk):integer;
begin
if w^.next<>nil then
        begin
        current:=w^.next;
        result:=current^.vert;
        end
        else
        result:=0;
end;

  procedure Visit(v: Integer);    {proc. rekurencyjnego odwiedzania wierzch.}
  var i:integer;
  begin
    if id<>1 then connected:=false;
    D[v]:=time;    {przydzielenie numerka w numeracji pre-order}
    Inc(time);
      current:=tablica[v];
      repeat
      i:=next(current);
      if i>0 then
      begin
       if D[i]=-1 then    {jesli wierzch. i jest bialy to ...}
       begin
        P[i]:=v;    {zaznaczamy, ze to z wierzch. v przechozimy do i}
        Visit(i);   {przechodzimy rekurencyjnie do wierzch. i}
       end
       end;
      until i=0;
    F[v]:=time;    {przydzielenie numerka w numeracji post-order}
    Inc(time);
  end;

  procedure DFS;
  var i:integer;
  begin
    for i:=1 to N do
    begin
      D[i]:=-1;F[i]:=-1;    {oznaczamy wszystkie wierzcholki jako biale}
      {Uwaga! wierzch. biale maja obie wartosci rowne -1;
              czarne - obie rozne od -1; szare - D rozne od -1, F rowne -1}
    end;
    time:=1;    {zmienna potrzebna do numeracji}

    for i:=1 to N do
      if D[i]=-1 then    {jesli wierzch. i jest bialy to ...}
      begin
        id:=i;
        P[i]:=-1;    {zaznaczamy, ze wierzch. i jest jednym z wierzch. startowych}
        Visit(i);    {przechodzimy do wierzch. i}
      end;
  end;
procedure usun(x,y:integer);
var tmp,prev,next:wsk;
begin
tmp:=tablica[x];
repeat
prev:=tmp;
tmp:=tmp^.next;
until tmp^.vert=y;
next:=tmp^.next;
prev^.next:=next;
dispose(tmp);
end;
//Procedury Listy krawędzi
procedure AddToEdgeList(pop,nast,waga:integer{;var current:edgelist});
var prev,next:edgelist;
begin
if currlist<>nil then
begin
prev:=currlist;
next:=currlist^.next;
end else
begin
prev:=nil;
next:=nil;
end;
new(currlist);
currlist^.pop:=pop;
currlist^.nast:=nast;
currlist^.waga:=waga;
currlist^.next:=next;
if first=nil then first:=currlist;
if prev<>nil then prev^.next:=currlist;
end;
procedure findLess(waga:integer{;var first,current:edgelist});
var tmp,next:edgelist;
begin
if first<>nil then
begin
next:=first;
tmp:=next;
repeat
if (next^.next<>nil) then begin
tmp:=next;
next:=next^.next
end;
until (next^.next=nil)or(next.waga>waga);
if next.waga>waga then currlist:=tmp else currlist:=next;
end;
end;
procedure addtotree(v:integer;w:integer);
var tmp:wsk;
begin
if tree[v]=false then
        begin
//showmessage(inttostr(v)+':'+inttostr(w));
        inc(treen);
//        form1.listbox2.items.add(inttostr(v));
        tree[v]:=true;
        inc(koszt,w);
        tmp:=tablica[v]^.next;
                while tmp<>nil do
                begin
//                showmessage(inttostr(tmp^.vert));
                findless(tmp^.waga);
                addtoedgelist(v,tmp^.vert,tmp^.waga);
                tmp:=tmp^.next;
                end;
//        findless();
        end;
end;
procedure pobierz;
var tmp:edgelist;
f:edgelist;
begin
f:=first^.next;
if f{irst}<>nil then begin
globalx:=f{irst}^.pop;
globalY:=f{irst}^.nast;
GlobalW:=f{irst}^.waga;
tmp:=f{irst}^.next;
dispose(f{irst});
first^.next:=tmp;
end else
begin
globalx:=0;
globaly:=0;
globalw:=0;
end;
end;
procedure TForm1.Button2Click(Sender: TObject);
var i:integer;
//next:edgelist;
begin
//Spójnosc
setlength(p,n+1);
setlength(d,n+1);
setlength(f,n+1);
connected:=true;
memo1.lines.add('> Badanie spójności grafu...');
dfs;
finalize(p);
finalize(d);
finalize(f);
if connected=false then memo1.lines.add('> Graf nie jest spójny') else
memo1.lines.add('> Graf jest spójny');
begin
memo1.lines.add('> Budowanie listy krawędzi...');
//Przepisanie listy sąsiedztwa do listy krawędzi
memo1.lines.Add('> Szukanie drzewa...');
setlength(tree,n+1);
for i:=1 to n do tree[i]:=false;
first:=nil;
currLIST:=nil;
addtoedgelist(0,0,0);
currLIST:=nil;
treen:=0;
koszt:=0;
czas.start:=czas.podaj;
addtotree(1,0);
repeat
pobierz;
addtotree(globaly,globalw);
until treen=n;
czas.stop:=czas.podaj;
finalize(tree);
memo1.lines.Add('> Znaleziono w '+inttostr(czas.oblicz)+' [ms]');
memo1.lines.Add('> Minimalny koszt wynosi '+inttostr(koszt));
end;
end;
procedure TForm1.Zakocz1Click(Sender: TObject);
begin
application.terminate;
end;

procedure TForm1.Zapiszraport1Click(Sender: TObject);
begin
if savedialog1.execute then
begin
memo1.lines.SaveToFile(savedialog1.filename);
end;
end;

end.
Komentarze
photo
0 # bezbek123 2013-01-04 13:49
człowieku a gdzie wcięcia?
Odpowiedz | Odpowiedz z cytatem | Cytować
Dodaj komentarz