#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
#include <time.h>
#include <math.h>

#include "PomFce.h"


#define C_VelTabPravd 5050
#define LOG_SOUBOR "log.txt"
#define VYST_SOUBOR  "vystup.txt"
#define C_Logovani 0//logovani 1=logujeme, 0=nelogujeme
#define C_Vypisy 0 //vypisy do okna 1=true, 0=false


//FILE *test;

//----------------------------------------------------------------------------
// FUNKCE
//----------------------------------------------------------------------------
//----------------------------------------------------------------------------
// Spocita Tau0 - Tau0 = 1/(pocet_mest * delka cesty urcena heuristikou nejblizsiho souseda)
//----------------------------------------------------------------------------
double SpoctiTau0(double ***V_TabHran, int C_VelTabHran, int C_NeexistujiciHrana)
{
	int *V_Pole;
	int i, j;
	int V_Min[2], V_AktMesto;
	double V_Max, V_Delka = 0;//delka cesty


	V_Pole = (int *) malloc(C_VelTabHran * sizeof(int));//alokace tabulky
	for (i = 0; i < C_VelTabHran; i++) V_Pole[i] = i;

	j = 0;
	V_AktMesto = 0;
	V_Pole[0] = -1;
	V_Max = 0;

	for (i = 0; i < C_VelTabHran; i++)
	{ 
		V_Min[0] = C_NeexistujiciHrana+1;
		for (j = 0; j < C_VelTabHran; j++)
		{
			if (V_Max < V_TabHran[V_AktMesto][j][0]) V_Max = V_TabHran[V_AktMesto][j][0];
			if((V_Min[0] > V_TabHran[V_AktMesto][j][0]) && (V_Pole[j] != -1)) 
			{ 
				V_Min[0] = (int)V_TabHran[V_AktMesto][j][0];
				V_Min[1] = j;
			} 
		
		}
			V_Pole[V_Min[1]] = -1;
			V_AktMesto = V_Min[1];
			if(V_Min[0] < C_NeexistujiciHrana) V_Delka = V_Delka + V_Min[0];			
	}

return(V_Max/(C_VelTabHran * V_Delka));
}


//----------------------------------------------------------------------------
// Inicializuje mravence. 
//----------------------------------------------------------------------------
T_Mravenec *InicializujMravence(int C_PocetMest)
{
	int i, VPom;
	T_Mravenec *V_Mravenec;
	T_NMesta *P_Prv, *P_Akt;
	
	V_Mravenec = (T_Mravenec *) malloc(sizeof(T_Mravenec));

	V_Mravenec->AktMesto = rand() % C_PocetMest;
	VPom = 0;
	if (V_Mravenec->AktMesto == 0) VPom = 1;//osetrni proti dvojitemu projiti nulteho mesta
	
	P_Prv = (T_NMesta *) malloc(sizeof(T_NMesta));
	P_Akt = P_Prv;
	V_Mravenec->NMesta = P_Prv;
	P_Prv->Mesto = VPom;
	for(i = VPom + 1; i < C_PocetMest; i++)
	{			
		if(i != V_Mravenec->AktMesto)
		{
			P_Akt->Dalsi = (T_NMesta *) malloc(sizeof(T_NMesta));
			P_Akt = P_Akt->Dalsi;
			P_Akt->Mesto = i;		
		}
	}
	P_Akt->Dalsi = NULL;
	
return(V_Mravenec);
}
//----------------------------------------------------------------------------
// Vytvoreni smerovaci tabulky. 
//----------------------------------------------------------------------------
int **VytvorSmerovaciTabulku(double ***V_TabHran, int **V_SmerTab, int C_VelTabHran, int C_MaxMest)
{
	int i, j;
	int **V_STabHran;

	
	
	V_STabHran = VytvorPole2(C_VelTabHran, 2);

	for(i = 0; i < C_VelTabHran; i++)//pro vsechna mesta v  SmerTab
	{		
		for(j = 0; j < C_VelTabHran; j++)//naplny tabulku k serazovani daty aktualniho sloupce
		{
		 	V_STabHran[j][0] = (int)V_TabHran[i][j][0];//hodnota hrany
			V_STabHran[j][1] = j;//mesto
		}
	
		QuickSort(V_STabHran, 0, C_VelTabHran-1);

		for(j = 0; j < C_MaxMest; j++)//pro vsechny polozky radky SmerTab
		{
			V_SmerTab[i][j] =  V_STabHran[j][1];
		}
	}
	Dealokuj2Pole(V_STabHran, C_VelTabHran);

return(V_SmerTab);
}
//----------------------------------------------------------------------------
//Určení města kam se mravenec vydá. Vrací ID města kam mravenec půjde
//----------------------------------------------------------------------------
int SmerovaniMravence(double ***V_TabHran, int **V_SmerTab, int C_VelTabHran, int C_MaxMest, T_Mravenec *V_Mravenec, double C_Beta, double C_q0, int C_NeexistujiciHrana, FILE *Pfw_Log)
{
	typedef struct MestPom
	{ 	
		int Mesto;
		double Prechod;
		struct MestPom *Dalsi;
	}T_MestPom;

	int i, j, k,  V_Pomocna, V_MestoJevSmerTab;
	double V_MaxPrechod[1], V_Jmenovatel;
    T_NMesta *P_Prv, *P_Akt;
	T_MestPom *P_PrvPom, *P_AktPom, *P_Ruseny;
	double V_Min, V_Max, V_Nahodna;
	int V_TabPravd[C_VelTabPravd];

	//inic promenych
    V_MestoJevSmerTab = 0;
	V_MaxPrechod[0] = V_MaxPrechod[1] = -1 ; 
	V_Pomocna = 0;
	V_Jmenovatel = 0;

	if(C_Logovani) Loguj(Pfw_Log, "Mravenec je ve meste cislo: ", V_Mravenec->AktMesto,'d',1);

	for(i = 0; i < C_MaxMest; i++)
	{
		//projed vsechna nenavstivena mesta
		//if nejake je ve smertab pridej ho do seznamu
		 P_Prv = V_Mravenec->NMesta;
		 for (P_Akt = P_Prv; P_Akt != NULL; P_Akt = P_Akt->Dalsi)
		 {
			 if (P_Akt->Mesto == V_SmerTab[V_Mravenec->AktMesto][i])//snad tu mam dobre indexy u SmerTab
			 {
				V_MestoJevSmerTab = 1;
				if (V_Pomocna == 0)//alokuji prvni polozku seznamu
				{
					P_PrvPom = (T_MestPom *) malloc(sizeof(T_MestPom));
					P_AktPom = P_PrvPom;
					P_AktPom->Mesto = P_Akt->Mesto;
					P_AktPom->Prechod = 0;
					P_AktPom->Dalsi = NULL;
					V_Pomocna = 1;
								
				}else		//alokuji jinou nez prvni polozku seznamu
				{
					P_AktPom->Dalsi = (T_MestPom *) malloc(sizeof(T_MestPom));
			 		P_AktPom = P_AktPom->Dalsi;
					P_AktPom->Mesto = P_Akt->Mesto;
					P_AktPom->Prechod = 0;
					P_AktPom->Dalsi = NULL;				
				}
				
			 } 
		 }

	}

    //najde kam ma mravenec jit
	if (V_MestoJevSmerTab == 1)
	{//rid se pravidly prechodu
		if (((double)rand() / ((double)(RAND_MAX)+(double)(1))) <= C_q0) //q0 porovnano s nahodnym cislem v rozmezi [0,1]
		{//dle vzorce jedna
			//vypocte prechod pro mesta vybrana ze SmerTab a najde nejvetsi
			if(C_Logovani)Loguj(Pfw_Log, "Pohyb Mravence dle vzorce 1", NULL,'t',1);
			for (P_AktPom = P_PrvPom; P_AktPom != NULL; P_AktPom = P_AktPom->Dalsi)
			{
				P_AktPom->Prechod = V_TabHran[V_Mravenec->AktMesto][P_AktPom->Mesto][1] * pow((1/(V_TabHran[V_Mravenec->AktMesto][P_AktPom->Mesto][0])),C_Beta); //feromon hrany * 1/hodnota hrany^Beta
				if (P_AktPom->Prechod > V_MaxPrechod[0]) 
				{
					V_MaxPrechod[0] = P_AktPom->Prechod;
					V_MaxPrechod[1] = P_AktPom->Mesto;
				}
			}
		}else
		{//dle vzorce dva
			if(C_Logovani)Loguj(Pfw_Log, "Pohyb Mravence dle vzorce 2", NULL,'t',1);
					
			for (P_AktPom = P_PrvPom; P_AktPom != NULL; P_AktPom = P_AktPom->Dalsi)
			{
				V_Jmenovatel = V_Jmenovatel + V_TabHran[V_Mravenec->AktMesto][P_AktPom->Mesto][1] * pow((1/(V_TabHran[V_Mravenec->AktMesto][P_AktPom->Mesto][0])),C_Beta);//vypocte jmenovatel zlomku(suma)
			}
			
			V_Min = 100;
			V_Max = 0;
			for (P_AktPom = P_PrvPom; P_AktPom != NULL; P_AktPom = P_AktPom->Dalsi)
			{
				P_AktPom->Prechod = (V_TabHran[V_Mravenec->AktMesto][P_AktPom->Mesto][1] * pow((1/(V_TabHran[V_Mravenec->AktMesto][P_AktPom->Mesto][0])),C_Beta)) /	V_Jmenovatel;//(feromon hrany * 1/hodnota hrany^Beta)/jmenovatel
				if (P_AktPom->Prechod < V_Min )	
					V_Min = P_AktPom->Prechod;
				if (P_AktPom->Prechod > V_Max )	
					V_Max = P_AktPom->Prechod;
			}
			for (P_AktPom = P_PrvPom; P_AktPom != NULL; P_AktPom = P_AktPom->Dalsi)
			{
				P_AktPom->Prechod = ((P_AktPom->Prechod - V_Min) / (V_Max - V_Min))*100;//normalizace
			}
			
			k = 0;
			i = 0;
			while(i<101)//vytvori pravdepodobnostni tabulku --- tim zmenim rozlozeni pravdepodobnosti...
			{ 
				for(j = 0; j < i; j++) 
				{ 
					V_TabPravd[k] = i; 
					k++;		
				} 
			i++;
			} 		
			
			
			V_Nahodna = V_TabPravd[rand()%C_VelTabPravd];
			V_MaxPrechod[0] = C_NeexistujiciHrana;//hledam min  

			for (P_AktPom = P_PrvPom; P_AktPom != NULL; P_AktPom = P_AktPom->Dalsi)
			{

				if ((P_AktPom->Prechod - V_Nahodna) < V_MaxPrechod[0])
				{
					V_MaxPrechod[0] = P_AktPom->Prechod - V_Nahodna;
					V_MaxPrechod[1] = P_AktPom->Mesto;
				}
				
			}
		}
		//dealokace pomocneho pole mest
		P_AktPom = P_PrvPom;
		while(P_AktPom != NULL)
		{
			P_Ruseny = P_AktPom;
			P_AktPom = P_AktPom->Dalsi;
			free(P_Ruseny);			
		}
	}else
	{// jdi do neblizsiho
		if(C_Logovani)Loguj(Pfw_Log, "Pohyb Mravence do nejblizsiho mesta", NULL,'t',1);
		V_MaxPrechod[0] = C_NeexistujiciHrana ; //hledam minimum 
		 for (P_Akt = P_Prv; P_Akt != NULL; P_Akt = P_Akt->Dalsi)
		 {
			 if(V_TabHran[V_Mravenec->AktMesto][P_Akt->Mesto][0] <= V_MaxPrechod[0])
			 {				
				 V_MaxPrechod[0] = V_TabHran[V_Mravenec->AktMesto][P_Akt->Mesto][0];
				 V_MaxPrechod[1] = P_Akt->Mesto;
			 }	
		 }	
	}
    
	if(C_Logovani)Loguj(Pfw_Log, "Mravenec smeruje do mesta: ", (int)V_MaxPrechod[1],'d',1);  
	
return((int)V_MaxPrechod[1]); 
}
//----------------------------------------------------------------------------
//Pohne mravencem(z výchozího města do cílového)
//----------------------------------------------------------------------------
int PohniMravencem(double ***V_TabHran, T_Mravenec *V_Mravenec, int C_CiloveMesto, double C_Ro, double C_Tau0, int *V_AktCesta, FILE *Pfw_Log)
{
	int i;
	double V_Pom;
	T_NMesta *P_Prv, *P_Akt, *P_Ruseny;	
		
	//ulozi feromon do tabulky hran
	V_Pom = V_TabHran[V_Mravenec->AktMesto][C_CiloveMesto][1];
	if(C_Logovani)Loguj(Pfw_Log, "L  Feromon: ", V_TabHran[V_Mravenec->AktMesto][C_CiloveMesto][1],'f',0);
	V_TabHran[V_Mravenec->AktMesto][C_CiloveMesto][1] = (1 - C_Ro) * V_TabHran[V_Mravenec->AktMesto][C_CiloveMesto][1] + C_Ro * C_Tau0;
	if(C_Logovani)Loguj(Pfw_Log, " ", V_TabHran[V_Mravenec->AktMesto][C_CiloveMesto][1],'f',0);
	if (V_Pom < V_TabHran[V_Mravenec->AktMesto][C_CiloveMesto][1])
	{
		if(C_Logovani)Loguj(Pfw_Log, "!!!!!!!!!!!!!!", NULL,'t',1);
	}else if(C_Logovani)Loguj(Pfw_Log, "", NULL,'t',1);
	//zmeni aktualni mesto
	V_Mravenec->AktMesto = C_CiloveMesto;
	//zapise navstivene Mesto do Aktualni cesty mravence
	i = 0;
	while(V_AktCesta[i] != -1)		
		i++;
	V_AktCesta[i] = C_CiloveMesto;
		
	//vymaze navstivene(aktualni) mesto ze seznamu dosud nenavstivenych mest
	P_Prv = V_Mravenec->NMesta;
	P_Akt = P_Prv;
	P_Ruseny = P_Akt;
	

	if (P_Ruseny->Mesto == C_CiloveMesto)//je ruseny clen prvni v seznamu?
	{
		if (P_Ruseny->Dalsi == NULL)//je prvni clen zaroven poslednim?
		{
			V_Mravenec->NMesta = NULL;
		}else
		{
			V_Mravenec->NMesta = P_Ruseny->Dalsi;
			free(P_Ruseny);
		}
	}else//rusime jiny  dalsi prvek
	{	
		P_Ruseny = P_Ruseny->Dalsi;
		while((P_Ruseny->Mesto != C_CiloveMesto) && (P_Ruseny->Dalsi != NULL))
		{
			P_Akt = P_Akt->Dalsi;
			P_Ruseny = P_Ruseny->Dalsi;
		}
		if (P_Ruseny->Dalsi == NULL) //rusim posledni prvek seznamu?
		{
			P_Akt->Dalsi = NULL;
			free(P_Ruseny);
		}else //rusim prvek uprostred seznamu
		{
			P_Akt->Dalsi = P_Ruseny->Dalsi;
			free(P_Ruseny);
		}
	}
return 0;//bez chyby
}
//----------------------------------------------------------------------------
//Spocte delku cesty, Vraci délku(cenu) cesty
//----------------------------------------------------------------------------
double SpoctiDelkuAktCesty(int *V_AktCesta, double ***V_TabHran, int C_VelTabHran)
{
	int i;
	double V_Delka;
	
	V_Delka = 0;
	for(i = 1; i < C_VelTabHran; i++)
	{
		V_Delka = V_Delka + V_TabHran[V_AktCesta[i-1]][V_AktCesta[i]][0];
	}
return(V_Delka);
}
//----------------------------------------------------------------------------
//Aktualizuje globalne feromon nejlepsi cesty
//----------------------------------------------------------------------------
int AktualizujGlobalneFeromon(double ***V_TabHran, int *V_MinCesta, int C_VelTabHran, double C_MinDelkaCesty, double C_Ro, FILE *Pfw_Log)
{
	int i;
	double V_Pom;

	for(i = 1; i < C_VelTabHran; i++)
	{
		V_Pom = V_TabHran[V_MinCesta[i-1]][V_MinCesta[i]][1];
		if(C_Logovani)Loguj(Pfw_Log, "G  Feromon: ", V_TabHran[V_MinCesta[i-1]][V_MinCesta[i]][1],'f',0);
		V_TabHran[V_MinCesta[i-1]][V_MinCesta[i]][1] = (1 - C_Ro) * V_TabHran[V_MinCesta[i-1]][V_MinCesta[i]][1] + C_Ro / C_MinDelkaCesty;
		if(C_Logovani)Loguj(Pfw_Log, " ", V_TabHran[V_MinCesta[i-1]][V_MinCesta[i]][1],'f',0);
		if (V_Pom > V_TabHran[V_MinCesta[i-1]][V_MinCesta[i]][1])
		{
			if(C_Logovani)Loguj(Pfw_Log, "!!!!!!!!!!!!!!", NULL,'t',1);
		}else if(C_Logovani)Loguj(Pfw_Log, "", NULL,'t',1);
	}

return 0;
}
//----------------------------------------------------------------------------
//ACO!!!tělo Ant Colony Algoritmu
//----------------------------------------------------------------------------
int *AntColony(int V_VelHrany, double ***V_Hrany, double V_Tau0, double C_Beta, double C_q0, double C_Ro, int C_NeexistujiciHrana, int C_MaxMest, int C_PocetIteraci, int C_PocetMravencu, FILE *Pfw_Log, FILE *Pfw_Vyst)
{
    int i,j,k;

	int **V_SmerovaciTabulka,
		V_MinIterace,
		*V_AktCesta, *V_MinCesta,
		V_SmerMravence;
	double V_AktDelkaCesty, V_MinDelkaCesty, V_MaxHrana;	
	T_Mravenec *V_Mravenec;	

 
   //osetreni na neex hranu- neex hrana nesmi byt mensi nez min hodnota ve SmerTab
	V_MaxHrana = C_NeexistujiciHrana;

	for(i = 0; i < V_VelHrany; i++)
	{
		for(j = 0; j < V_VelHrany; j++)
		{
			if (V_Hrany[i][j][0] > V_MaxHrana)
			{
				V_MaxHrana = (int)V_Hrany[i][j][0];
			}
		}
	}
    //pokud je nejvetsi hrana matice vetsi nez neexhrana
	if (V_MaxHrana != C_NeexistujiciHrana)
	{	
		//oprav hodnotu neexhrany v matici
		for(i = 0; i < V_VelHrany; i++)
		{	 
			for(j = 0; j < V_VelHrany; j++)
			{ 
				if (V_Hrany[i][j][0] == C_NeexistujiciHrana)
				{
					V_Hrany[i][j][0] = (int)V_MaxHrana+10;
				} 
			} 
		} 		
		//oprav hodnotu neexhrany
		C_NeexistujiciHrana = (int)V_MaxHrana+10;
		//upozorni na to....
		printf("Pozor! Velikost Neexistujici hrany je nastavena prilis nizko! Znacne riziko irelevantniho vysledku!\n");
		printf("Hodnota Neexistujici hrany byla automaticky prenastavena na: %d\n",C_NeexistujiciHrana);
		if(C_Logovani)Loguj(Pfw_Log, "Pozor! Velikost Neexistujici hrany je nastavena prilis nizko! Znacne riziko irelevantniho vysledku!", NULL,'t',1);		
	}
	
		
	V_Tau0 = SpoctiTau0(V_Hrany, V_VelHrany, C_NeexistujiciHrana);//inic Tau pomoci heuristyky neblizsiho souseda....toto lze modifikovat a pouzivat jako vstupni parametr...
	printf("V_Tau0: %f\n",V_Tau0);
	//nakupiruje zjistene V_Tau0 do tabulky hran --- driv to proste nejde udelat....
	for(i = 0; i < V_VelHrany; i++)
	{
		for(j = 0; j < V_VelHrany; j++)
		{
			V_Hrany[i][j][1] = V_Tau0;
		}
	}

	V_SmerovaciTabulka = VytvorPole2(V_VelHrany, C_MaxMest);//alokuje smerovaci tabulku
	V_SmerovaciTabulka = VytvorSmerovaciTabulku(V_Hrany, V_SmerovaciTabulka, V_VelHrany, C_MaxMest);//naplni smerovaci tabulku daty
	
	V_MinCesta = VytvorPole1(V_VelHrany);
	V_AktCesta = VytvorPole1(V_VelHrany);
	V_MinDelkaCesty = C_NeexistujiciHrana * V_VelHrany;
	
	if(C_Vypisy)printf("Iterace(*) a Mravenec(.):\n");
	for(i = 0; i < C_PocetIteraci; i++)//for vsechny iterace
	{
		if(C_Vypisy)printf("\n*(%d)*",i);
		if(C_Logovani)Loguj(Pfw_Log, "===========================================================\nIterace cislo ", i,'d',1);
		if(C_Logovani)Loguj(Pfw_Log, "===========================================================", NULL,'t',1);

		for(j = 0; j < C_PocetMravencu; j++)//for vsechny mravence
		{
			if(C_Vypisy)printf(".");
			if(C_Logovani)Loguj(Pfw_Log, "------------------------------------------------------\nMravenec cislo ", j,'d',1);
			if(C_Logovani)Loguj(Pfw_Log, "------------------------------------------------------", NULL,'t',1);

			V_Mravenec = InicializujMravence(V_VelHrany);
			//inicalizace aktualni delky a cesty
			V_AktDelkaCesty = 0;
			for(k = 0; k < V_VelHrany; k++) V_AktCesta[k] = -1;
			V_AktCesta[0] = V_Mravenec->AktMesto;


			for(k = 0; k < V_VelHrany-1; k++)//pro vsechna mesta(-1 protoze pri inicializaci pmravence je jiz jedno mesto navstoveno])
			{

				V_SmerMravence = SmerovaniMravence(V_Hrany, V_SmerovaciTabulka, V_VelHrany, C_MaxMest, V_Mravenec, C_Beta, C_q0, C_NeexistujiciHrana, Pfw_Log);	
				PohniMravencem(V_Hrany, V_Mravenec, V_SmerMravence, C_Ro, V_Tau0, V_AktCesta, Pfw_Log);
			}
		

			V_AktDelkaCesty = SpoctiDelkuAktCesty(V_AktCesta, V_Hrany, V_VelHrany);
			if(V_MinDelkaCesty > V_AktDelkaCesty)
			{
				for(k = 0; k < V_VelHrany; k++)
				{
					V_MinCesta[k] = V_AktCesta[k];
					V_MinDelkaCesty = V_AktDelkaCesty;
					V_MinIterace = i;//zapamatuje si v jake iteraci k tomu doslo
				}
			}
			if(C_Logovani)Loguj(Pfw_Log, "Aktualni delka cesty: ", V_AktDelkaCesty,'d',1);
		
			ZrusMravence(V_Mravenec);
		}
		//ulozeni globalniho feromonu 
		AktualizujGlobalneFeromon(V_Hrany, V_MinCesta, V_VelHrany, V_MinDelkaCesty, C_Ro, Pfw_Log);
	}//end iterace 

	 //kontrolni vypisy-------------------------------------------------------
	printf("\n");
		
	printf("Delka cesty: %f \n", V_MinDelkaCesty);
	printf("Dosazeno v iteraci: %d \n", V_MinIterace);
	
	if(C_Logovani)
	{
		Loguj(Pfw_Log, "Tau0: ", V_Tau0,'f',1);
		Loguj(Pfw_Log, "Minimalni delka cesty: ", V_MinDelkaCesty,'f',1);
		Loguj(Pfw_Log, "Minimum dosazeno v iteraci: ", V_MinIterace,'d',1);
		Loguj(Pfw_Log, "Minimalni cesta: ", NULL,'t',0);
		for (i = 0; i < V_VelHrany; i++)
		{ 
			(Pfw_Log, " ", V_MinCesta[i],'d',0);
		}  
		Loguj(Pfw_Log, "", NULL,'t',1);
	}

	Loguj(Pfw_Vyst, "Minimalni delka cesty: ", V_MinDelkaCesty,'f',1);
	Loguj(Pfw_Vyst, "Minimum dosazeno v iteraci: ", V_MinIterace,'d',1);
	Loguj(Pfw_Vyst, "Minimalni cesta: ", NULL,'t',1);
	for (i = 0; i < V_VelHrany; i++)
    {
		Loguj(Pfw_Vyst, " ", V_MinCesta[i],'d',1);
    } 
	Loguj(Pfw_Vyst, "", NULL,'t',1);


return(V_MinCesta);
}
//---------------------------------------------------------------------------------------------
//---------------------------------------------------------------------------------------------
// MAIN - příklad použití
//---------------------------------------------------------------------------------------------
//---------------------------------------------------------------------------------------------
int main(int argc, char* argv[]) {

 //Definice promenych-------------------------------------------------
 
 double ***V_Hrany, //musi byt double kvuli desetinym hodnotam feromonu
		C_Beta, C_q0, C_Ro, C_PocatecniFeromon, V_Tau0;
 char *VST_SOUBOR;

 int C_NeexistujiciHrana, C_MaxMest,
	 C_PocetMravencu, C_PocetIteraci,
	 V_VelHrany,
	 *V_MinCesta,
	 V_Err; //error counter

 FILE *Pfw_Log, *Pfw_Vyst;

 clock_t V_StartTime, V_EndTime; 

  //inicializace promenych-----------------------------------------------
 VST_SOUBOR = "input.txt";
 V_Err = 0;
 C_PocetIteraci = 1000;
 C_NeexistujiciHrana = 10000;//hodnota pro neexistujici hrany
 C_PocetMravencu = 10; 
 C_MaxMest = 15;//Parametr smerovaci tabulky(min 1...)
 C_Beta = 2;//omezeni dohlednosti
 C_q0 = 0.9;//omezeni vyzkumu
 C_Ro = 0.1;//rozklad feromonu
 C_PocatecniFeromon = 1; //počáteční feromon, uplatní se jen při zakometování výpočtové funkce v algoritmu ACO

 V_Tau0 = C_PocatecniFeromon;



//---------------------------------------------


 //nacteni vstupních parametrů----------------------------------------------------------------
 printf("Chcete spustit program s vychozimi parametry?(y/n):");
 
 if(getchar()=='n')
 {
	 printf("Pocet iteraci: ");
	 scanf("%d",&C_PocetIteraci);
	 printf("Cena Neexistujici hrany: ");
	 scanf("%d",&C_NeexistujiciHrana);
	 printf("Pocet mravencu: ");
	 scanf("%d",&C_PocetMravencu);
	 printf("Maximum mest ve smerovaci tabulce: ");
	 scanf("%d",&C_MaxMest);
	 printf("Beta(1 a vice): ");
	 scanf("%lf",&C_Beta);
	 printf("q0(0-1): ");
	 scanf("%lf",&C_q0);
	 printf("Ro(0-1): ");
	 scanf("%lf",&C_Ro);
	 printf("Pocatecni feromon(momentalne inaktivni!!!): ");
	 scanf("%lf",&C_PocatecniFeromon);
	 getchar();
 }
 
    printf("Spoustim ACO s naseldujicimi parametry\n");	
	printf("Pocet iteraci: %d\n",C_PocetIteraci);
	printf("Cena Neexistujici hrany: %d\n",C_NeexistujiciHrana);
	printf("Pocet mravencu: %d\n",C_PocetMravencu);
	printf("Maximum mest ve smerovaci tabulce: %d\n",C_MaxMest);
	printf("Beta: %f\n",C_Beta);
	printf("q0: %f\n",C_q0);
	printf("Ro: %f\n",C_Ro);
	printf("Pocatecni feromon: %f\n\n",C_PocatecniFeromon);



  if ((Pfw_Vyst = fopen(VYST_SOUBOR, "w")) == NULL) V_Err++;	 
  Loguj(Pfw_Vyst, "Pocet iteraci: ", C_PocetIteraci,'d',1);
  Loguj(Pfw_Vyst, "Cena Neexistujici hrany: ", C_NeexistujiciHrana,'d',1);
  Loguj(Pfw_Vyst, "Pocet mravencu: ", C_PocetMravencu,'d',1);
  Loguj(Pfw_Vyst, "Maximum mest ve smerovaci tabulce:", C_MaxMest,'d',1);
  Loguj(Pfw_Vyst, "Beta: ", C_Beta,'f',1);
  Loguj(Pfw_Vyst, "q0: ", C_q0,'f',1);
  Loguj(Pfw_Vyst, "Ro: ", C_Ro,'f',1);
  Loguj(Pfw_Vyst, "Pocatecni feromon: ", C_PocatecniFeromon,'f',1);
  
  
  
 if(C_Logovani)  
 {
	 if ((Pfw_Log = fopen(LOG_SOUBOR, "w")) == NULL) V_Err++;	 
 }
 
  srand((int)time(NULL)); //incializace pro rand()
 
 if ((V_Hrany = VytvorPole3(VST_SOUBOR, &V_VelHrany)) == 0) V_Err++;  //vytvori pole vstupu
 if ((NactiHrany(VST_SOUBOR, V_Hrany, V_VelHrany, C_NeexistujiciHrana, C_PocatecniFeromon)) == 0) V_Err++;  //vytvori pole vstupu   

 if(V_Err ==0){
	

 
	 V_StartTime = clock();
//ACO

	 V_MinCesta = AntColony(V_VelHrany, V_Hrany, V_Tau0, C_Beta, C_q0,  C_Ro, C_NeexistujiciHrana, C_MaxMest, C_PocetIteraci,  C_PocetMravencu, Pfw_Log, Pfw_Vyst);
		
	V_EndTime = clock();
	printf("\nCas zpracovani [ms]: \t %ld\n", (long int)(V_EndTime - V_StartTime)); 
	printf("Iterace cislo:%d\n",j);

	

	Loguj(Pfw_Vyst, "Cas vypoctu [ms]", (long int)(V_EndTime - V_StartTime),'d',1);
	
 }//endif error
 if(C_Logovani)Loguj(Pfw_Log, "Pocet chyb v programu", V_Err,'d',1);
 printf("Konec programu. Pro vice informaci v vysl.txt (popr.v log.txt)\nStiskene libovolnou klavesu\n");
 
 if(C_Logovani) fclose(Pfw_Log);
 fclose(Pfw_Vyst);



 getchar();
 return 0;
}