grafy - vector z listami sasiedztwa przekazywany do funkcji

0

Cześć mam problem. Zrobiłem projekt na studia którego zadaniem jest wczytać graf, sprawdzić jego dwudzielność i określić maksymalne skojarzenie w grafie. Graf przechowuje w ten sposób:

struct I
{
	int i;
	int nr;
};
...
vector<vector<I>> wierzcholki

dwudzielność określam prawidłowo, a do matchingu skorzystałem z algorytmu Hopcrofta-Karpa.
Zadanie muszę wrzucić na spoja i dla maksymalnie dużych danych wejściowych na moim komputerze wyniki są raczej na pewno prawidłowe i mieszczę się w czasach. Jednak na spoju przekracza mi czasy w połowie testów które prawdopodobnie wcale nie są nawet maksymalnie dużych rozmiarów i chyba domyślam się w czym tkwi problem. Muszę przekazywać graf wielokrotnie do jednej funkcji a wiec chce przekazać wierzchołki utworzone powyżej w funkcji main. Początkowo przekazywałem je w ten sposób:
bool Match(vector<vector<I>> wierzcholki) i już wtedy miałem problem z czasami dokładnie w tych samych testach. Program działał ale dość wolno dla większych testów mulił i doszedłem do wniosku, że to przez tą funkcję. Poszukałem trochę i znalazłem, że ludzie przekazują do funkcji vector raczej tak: bool Match(vector<vector<I>> &wierzcholki) tzn ze znaczkiem referencji. Po czym na moim komputerze program zaczął działać niesamowicie sprawniej jednak na spoju dalej mam problem z czasem w tych samych miejscach i jestem raczej prawie pewien, że problemem jest dalej to samo. Tak więc moje pytania brzmią skąd to spowolnienie, bo cały czas myślałem, że vector jest przekazywany jak tablica czyli zwykły wskaźnik, a tu klops... No i najważniejsze pytanie czy mogę przekazać te vectory w jakiś inny spoób? Prosił bym o konkretne propozycje bo korzystam z tego bardziej intuicyjnie i dość sprawnie ale jednak nie do końca pewnie. Tak więc czy istnieje jakiś inny możliwy zapis? zaczynając od typedef vec<vec< i>> choć gdy ja to napisałem to nie poszło i tez pytanie dlaczego :/... do najróżniejszych innych sposobów. Proszę o wszelkie pomysły. Dodatkowo chciał bym jeszcze spytać czy zamiana sposobu definicji vector<list< I>> zrobi jakąś konkretną różnicę? Czasową albo jaką kolwiek i czy przekazywać to wtedy ze znaczkiem referencji czy jakos inaczej?. Dzięki za wszelkie podpowiedzi i odpowiedz na pytania.
Pozdrawiam</i></i></i>

0

Nie, vector jest przekazywany na takich samych prawach jak int, double czy zwykly struct. Jesli nic nie na piszesz - kopia. Jesli napiszesz * lub & - to przez adres. Prawa te tycza sie wszystkich typow, nawet tablic, problem niezrozumienia tkwi w tym, ze tablice prawie na kazdym miejscu sa przez kompilator redukowane do wskaznika na pierwszy element, wiec w parametrach masz int* i on wskaznik jest kopiowany na prawach normalnego typu danych ==> stad w funkcji masz 'bezposrednie polaczenie' z tablica z zewnatrz.... Zaszlosc z C, mam nadzieje ze kiedys to w koncu wywala i tablice o znanej wielkosci da sie w koncu prezrzucac przez wartosc po ludzku...

Tak wiec, vector czy double, jesli nic nie napiszesz, zostanie zrobiona kopia. Twoj pomysl z & jest prawieże ok. Formalnie, powinno byc "vector<vector< I>> const & wierz", aby zagwarantowac sobie ze funkcja przypadkiem tego wektora nie zmieni, bo wtedy zmiana spropaguje sie na oryginal.

Jezeli danych jest duzo, wcale sie nie dziwie ze Ci nagle przyspieszylo strasznie:) Jednak na serwerze testujacym rowniez powinno bylo przyspieszyc, nie ma bata, tamże kopiowanie również musialo zostac pominiete.

kod z tydefem, np:

struct I { int i, nr; };
typedef vector<vector< I>> wierzcholki;
void funkcja( wierzcholki const & www );

Zamiana wewnetrznego vectora na list jest ogolnie mozliwa, pewnie nawet nie bedziesz musial kodu za bardzo modyfikowac. Jednak, o ile nie wykonujesz bardzo czesto operacji wstawienia-usuniecia elementow z tego srodkowego zestawu, to bedziesz mial gorsza wydajnosc. Ogolnie, listy maja szybkie wstawianie-usuwanie-przestawianie, wolne chodzenie i wyszukiwanie. Vectory: wolne wstawianie-usuwanie (chyba ze na/z konca, ale im blizej poczatku tym gorzej), a bardzo szybkie chodzenie i przeszukiwanie (random access!). Wybierz wlasciwe narzedzie do swoich potrzeb po prostu.

ps. uwazaj na forum z < >, gdyz takie np < i > wlacza kursywe. stawiaj spacje po < jesli nie chcesz zeby byla uznana za tag formatuajcy tekst

0

Dzięki za odpowiedź. Podobne też rozumowanie miałem w głowie tylko nie byłem przekonany co do typów z stl'a. Rozwiałeś wszelkie wątpliwości. Nie będę więc implementował też listy ponieważ nie zależy mi na drobnym przyspieszeniu, tym bardziej, że w moim przypadku faktycznie, co najwyżej mogła by ona tylko zwolnić wykonywanie programu w moim przypadku. Wszelkie wątpliwości rozwiane, jeszcze raz dzięki i pozdrawiam.

1 użytkowników online, w tym zalogowanych: 0, gości: 1