Pamięć(?) - szeregowanie zadań

0

Dobry wieczór,

Napisałam program rozwiązujący problem szeregowania zadań korzystając z algorytmu genetycznego (mniej istotna część wstępu :) ). Pewna część programu jest powtarzana wielokrotnie i za którymś, chyba niezbyt określonym razem program się wysypuje (przy wcześniejszych iteracjach wszystko działa bez zarzutu), więc jedyna myśl, która przychodzi mi do głowy to problemy z pamięcią, ale że jestem początkującym programistą, to nie do końca się na tym znam.

Dlatego proszę o rzucenie okiem, czy wstawiony przeze mnie fragment kodu może generować jakieś problemy pod względem pamięciowym? W felernej iteracji pojawia się "d" ale "e" już nie.


    cout<<"d ";
    for (int y=0; y<10; y++)                       ///iteracja po 10 zadaniach
    {
        int masz=zadania[kolejnosc[y]].operacja1[0]-1;         //kazde zadanie=3 operacje
        long int kolumny2=0;
        if (zadania[kolejnosc[y]].operacja1[1]>0)       //dopoki operacja jeszcze nieskonczona
        {
            for(long int kolumny=0; kolumny<10000; kolumny++)
            {
                if (glowna[masz][kolumny]==0)
                {
                    if (zadania[kolejnosc[y]].operacja1[1]<=0)
                        break;
                    else
                    {
                     glowna[masz][kolumny]=1;       //w tablicy uporzadkowan wstawiam 1
                     zadania[kolejnosc[y]].operacja1[1]--;
                    }
                }
                else
                    if (glowna[masz][kolumny]==2)  //komorka zajeta przez maintenance
                    {
                        if (glowna[masz][kolumny-1]==1)   
                        {
                                kara+=int(ceil(0.3*zadania[kolejnosc[y]].operacja1[1]));
                        }                                             //naliczamy kare za przerwanie operacji
                    }
                            kolumny2=kolumny;
            }
        }
        kolumny2+=1;
        long int kolumny3=0;
        int masz2=zadania[kolejnosc[y]].operacja2[0]-1;

        if (zadania[kolejnosc[y]].operacja2[1]>0)
        {
            for(kolumny2; kolumny2<10000; kolumny2++)
            {
                if (glowna[masz2][kolumny2]==0)
                {
                    if (zadania[kolejnosc[y]].operacja2[1]<=0)
                        break;
                    else
                    {
                     glowna[masz2][kolumny2]=1;
                     zadania[kolejnosc[y]].operacja2[1]--;
                    }
                }
                else
                    if (glowna[masz2][kolumny2]==2)
                    {
                        if (glowna[masz2][kolumny2-1]==1)
                        {
                                kara+=int(ceil(0.3*zadania[kolejnosc[y]].operacja2[1]));
                        }
                    }
                            kolumny3=kolumny2;
            }
        }

        kolumny3++;
        int masz3=zadania[kolejnosc[y]].operacja3[0]-1;
        if (zadania[kolejnosc[y]].operacja3[1]>0)
        {
            for(kolumny3; kolumny3<10000; kolumny3++)
            {
                if (glowna[masz3][kolumny3]==0)
                {
                    if (zadania[kolejnosc[y]].operacja3[1]<=0)
                        break;
                    else
                    {
                     glowna[masz3][kolumny3]=1;
                     zadania[kolejnosc[y]].operacja3[1]--;
                    }
                }
                else
                    if (glowna[masz3][kolumny3]==2)
                    {
                        if (glowna[masz3][kolumny3-1]==1)
                        {
                                kara+=int(ceil(0.3*zadania[kolejnosc[y]].operacja3[1]));
                        }
                    }
            }
        }

     }
     cout<<"e ";

Każde zadanie ma 3 operacje, dlatego w powyższym kodzie jest praktycznie 3 razy to samo.

Czy ktoś jest w stanie znaleźć problem? Cały kod w załączniku (wszystkie deklaracje itp.)

Z góry dziękuję za odpowiedź

2

Wywal ten kod, bo do niczego innego się nie nadaje. Następnie przepisz w wersji dla ludzi. Tak zeby twoja mama potrafiła ten kod przeczytać. I nie, nie pisz "przecież tak sie nie da". Zaręczam że sie da.
Ja w tym kodzie widze tylko pętle, operacje matematyczne i zmienne o enigmatycznych nazwach. Nie widzę tu algorytmu. Ty zresztą też nie, stąd twój problem.
A gdyby ten kod wyglądał tak:

void cośtam(){
  for(int i=0;i<10;i++){
      przetwarzajZadanie(i);
  }
}

void przetwarzajZadanie(int n){
    przetwarzajOperacje1(n);
    przetwarzajOperacje2(n);
    przetwarzajOperacje3(n);
}

void przetwarzajOperacje1(int n){
    //jakaś magia
    if(operacjaNieSkonczona(n)){
        magiaZKolumnami();
    }
}

Widzisz pewną różnicę? Ten kod da się przeczytać. Z tego kodu nawet twoja mama będzie potrafiła zrozumieć do czego on służy.
Hint: jeśli musisz wstawić w kodzie komentarz który wyjaśnia "co się dzieje" to znaczy że powinna to być nowa funkcja z opisową nazwą.

1

Zawsze się da:


int kara=0;

void wszystkiezadania()
{
	for (int y=0; y<10; y++)
	{
		wstawdotabeli(y);
	}
}

void wstawdotabeli(int y)
{
	wstawoperacje1(y);
	wstawoperacje2(y);
	wstawoperacje3(y);
}



bool czyoperacjaskonczona(int y)
{
	if (zadania[kolejnosc[y]].operacja1[1]>0)
		return false;
	else
		return true;
}

void wstawoperacje1(int y)
{
	int maszynadlaoperacji1=zadania[kolejnosc[y]].operacja1[0]-1;
	long int kolumny2=0;
	if (czyoperacjaskonczona(y)==false)
		for (long int kolumny=0; kolumny<1000; kolumny++)
			badamyiuzupelniamy(y, kolumny, maszynadlaoperacji1);
}

void badamyiuzupelniamy (int y, int kolumny, int maszynadlaoperacji1)
{
	if (czykomorkapusta(kolumny, maszynadlaoperacji1)==true)
	{
		przypiszjednostkeoperacji1(maszynadlaoperacji1, kolumny);
		zmniejsziloscpozostalychjednostekoperacji1(y);
	}
	else
	{
		if (czykomorkazajetamaintenancem(kolumny, maszynadlaoperacji1) == 
			if (czykomorkawlewojestzadaniem(kolumny, maszynadlaoperacji1)==true)
				kara+= naliczkare(y);

	}
}

int naliczkare(int y)
{
	return int(ceil(0.3*zadania[kolejnosc[y]].operacja1[1]));
}

bool czykomorkawlewojestzadaniem(kolumny, maszynadlaoperacji1)
{
	if (glowna[maszynadlaoperacji1][kolumny-1]==1)
		return true;
	else
		return false;
}


bool czykomorkazajetamaintenancem(int kolumny, int maszynadlaoperacji1)
{
	if (glowna[maszynadlaoperacji1][kolumny]==2)
		return true;
	else
		return false;
}


bool czykomorkapusta(int kolumny, int maszynadlaoperacji1)
{
	if (glowna[maszynadlaoperacji1][kolumny]==0)
		return true;
	else
		return false;
}

void przypiszjednostkeoperacji1 (int maszynadlaoperacji1, kolumny)
{
	glowna[maszynadlaoperacji1][kolumny]=1;
}

void zmniejsziloscpozostalychjednostekoperacji1(y)
{
	zadania[kolejnosc[y]].operacja1[1]--;
}

Funkcje dla pozostałych 2 operacji analogiczne, główna to tablica dwuwymiarowa- zmienna globalna, zadania- wektor zawierający obiekty klasy Zadanie, kolejnosc- tablica określająca w jakiej kolejności mają być szeregowane zadania.

0

Obawiam się, że ta druga wersja jest teraz jeszcze bardziej nieczytelna niż ta pierwsza O_o - przynajmniej takie pierwsze wrażenie :]
Jeśli mogę coś poradzić to:
przed każdą wykonaną pętlą zrób sobie coś takiego:

cout << "check 1 (2,3,...n): pętla for ... y = " << y << "max rozmiar: " << nazwa_zmiennej_zamiast_10 << " -> jeszcze działa! ;D " << endl; //lub coś w tym stylu 

i zrób tak przed rozpoczęciem wykonania się każdej pętli/warunku etc.
W ten oto prosty sposób znajdziesz miejsce, gdzie Ci się program wywala -> bo do tego momentu będziesz miał wyświetlony każdy komunikat. Jeśli wyświetlisz sobie numer pętli oraz inne istotne informacje z kodu to znalezienie problemu to kwestia 5 minut.

Natomiast druga rada, która wynika z szybkiego zniechęcenia analizowania Twojego kodu to: używaj ludzkich zmiennych w pętlach a przede wszystkim nie używaj stałych w pętlach... tzn. nie rób tak:

for (int y=0; y<10; y++)

tylko np. tak:

for(int i=0; i<normalna_nazwa_zmiennej_reprezentujacej_ilosc_wykonywanych_obliczen; i++)
2

Jest lepiej niz było, ale jeszcze daleko z tym do dobrego kodu. Bo widzisz twój kod jest równie czytelny jak ten który pokazałem jako przykład, ale weź pod uwage że ja nie wiem co ten algorytm miał robić! Z mojego przykładowego kodu nie da sie tego wyczytać i niestety z twojego kodu też nie. Pytałaś swoją mamę/siostrę czy teraz rozumie ten kod? ;)

Jeśli chodzi o szukanie co się wysypało to ja bym to zwyczajnie odpalił z debugera. Jak się wysypie to debuger powie ci gdzie i co sie stało.

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