Ejemplo n.º 1
0
int FindMinWeightBridge(const UndirectedGraph& graph) {

    vector<Color> colors(graph.Order(), WHITE);
    DFSVisitor visitor(graph.Order());
    Edge impossible_edge(0, 0, 0, -1);

    DepthFirstSearch(graph, 0, impossible_edge, &colors, &visitor);

    return visitor.MinWeight();
}
TEST(Graph, adjaent) {
  UndirectedGraph graph {20};
  graph.addEdge(0, 1);
  graph.addEdge(0, 2);
  graph.addEdge(0, 5);
  Iterator<int>* iter = graph.adjacent(0);
  EXPECT_EQ(5, iter->next());
  EXPECT_EQ(2, iter->next());
  EXPECT_EQ(1, iter->next());
}
Ejemplo n.º 3
0
int main(int argc, char** argv) {
    int i;

    if (argc != 2) {
        cout << "Spatny pocet parametru" << endl;
        cout << "binarka nazev-souboru" << endl;
        cout << std::endl << "Arguments:" << endl;
        exit(EXIT_FAILURE);
    }

    UndirectedGraph *graph = readGraphFromFile(argv[1]);
    cout << "vertex count=" << graph->vertexCount() << endl;

    DFSSolver *solver = new DFSSolver(graph);

    //time start
    //time_t start = time(NULL);
    //TimeTool(time(NULL)) start;
    TimeTool start(time(NULL));
    //hledani reseni
    pair<vector<Edge> *, int>  *result = solver->findBestSolution();
    //time end
    //time_t end = time(NULL);
    TimeTool end(time(NULL));

    vector<Edge> *solution = result->first;
    int solutionPrice = result->second;
    if (solution != NULL) {
        cout << "Best solution:" << endl;
        for (i = 0; i < solution->size(); i++) {
            cout << (*solution)[i] << endl;
        }
		cout << "Spanning tree degree: " << solutionPrice << endl;
    }

    //Celkovy cas vypoctu
    //double dif = difftime(end, start);
    //int h = dif/3600;
    //int m = dif /60;
    //int s = dif - (h * 3600) - (m * 60);

    //cout << "DIFF:" << dif << "s" << endl;
    //cout << "TIME:" << h << ":" << m << ":" << s << " input file " << argv[1] << endl;

    TimeTool dif (difftime(end.time, start.time));
    //cout << "TIME: " << dif << " input file " << argv[1] << " START:" << start <<" END:" << end << endl;
    cout << "TIME: " << dif << " input file " << argv[1] << endl;

    delete graph;
    delete solution;
    delete result;
    delete solver; // tady to umre

    return 0;
}
Ejemplo n.º 4
0
TEST_F(UndirectedGraphFixture, canBeCopied)
{
    g_.addEdge(0, 1, 7);
    g_.addEdge(3, 2, 123);
    UndirectedGraph copy { g_ };
    ASSERT_EQ(g_.getWeightOfEdge(0, 1), copy.getWeightOfEdge(0, 1));
    ASSERT_EQ(g_.getWeightOfEdge(2, 3), copy.getWeightOfEdge(2, 3));
    ASSERT_EQ(g_.getNumberOfEdges(), copy.getNumberOfEdges());
    ASSERT_EQ(g_.getNumberOfVertices(), copy.getNumberOfVertices());
    ASSERT_EQ(g_.getSumOfWeights(), copy.getSumOfWeights());
}
Ejemplo n.º 5
0
UndirectedGraph* GreedyHeuristic::getICTree(UndirectedGraph* t1, UndirectedGraph* t2, list<Edge*>* iset, UndirectedGraph* ug) {

  int cardinality = ((*t1).vertices).size() - 1;
  UndirectedGraph* greedyTree = new UndirectedGraph();
  //cout << "iset size: " << iset->size() << endl;
  Edge* minE = getMinEdge(iset);
  greedyTree->addVertex(minE->fromVertex());
  greedyTree->addVertex(minE->toVertex());
  greedyTree->addEdge(minE);
  generateUCNeighborhoodFor(ug,minE);
  for (int k = 2; k < ((*ug).vertices).size(); k++) {
    Edge* newEdge = getICNeighbor(iset);
    Vertex* newVertex = NULL;
    if (greedyTree->contains(newEdge->fromVertex())) {
      newVertex = newEdge->toVertex();
    }
    else {
      newVertex = newEdge->fromVertex();
    }
    greedyTree->addVertex(newVertex);
    greedyTree->addEdge(newEdge);
    adaptUCNeighborhoodFor(newEdge,newVertex,greedyTree,ug);
  }
  if ((greedyTree->vertices).size() > (cardinality + 1)) {
    shrinkTree(greedyTree,cardinality);
  }
  greedyTree->setWeight(weightOfSolution(greedyTree));
  return greedyTree;
}
Ejemplo n.º 6
0
bool dfs(int v, int c, UndirectedGraph& g, int* color){

    color[v] = c;

    for(vector<int>::iterator it=g.edge_list_begin(v); it !=g.edge_list_end(v); it++){
        int dst = *it;
        if(color[dst] == c)return false;
        if(color[dst] == 0)
        {
            if(!dfs(dst, -c, g, color))return false;
        }
    }

    return true;
}
int main(int argc, char **argv) {
    if (argc != 2) {
        std::cout << "Usage: " << argv[0] << "||||| Should be: <MAXIMUM_NUMBER_OF_VERTICES>" << std::endl;
        return 0;
    }
    std::cout << "The maximus number of vertices is " << argv[1] << std::endl;
    
    
    // Try to translate MAXIMUM_NUMBER_OF_VERTICES
    // to size_t in order to determine the number of vertices.
    try {
        long num_of_nodes = std::stoi(argv[1]);
        if (num_of_nodes < 0) {
            std::cout << "Invalid argument for MAXIMUM_NUMBER_OF_NODES::Must be a positive integer!::TERMINATING PROGRAM\n";
            exit(1);
        }
        
        const size_t max_val = num_of_nodes;
        UndirectedGraph<size_t> testGraph;
        DisjointSet<size_t> testDS;
        
        size_t counter = 1;
        while (counter <= num_of_nodes) {
            testGraph.AddVertex(counter);
            testDS.AddNewNode(counter);
            ++counter;
        }

        srand(time(0)); //use current time as seed for random generator
        while (testDS.Size() > 1) {
            int i1 = rand() % max_val + 1;
            int i2 = rand() % max_val + 1;
            if (testGraph.AddEdge(i1, i2)) {
                testDS.Union(i1, i2);
            }
        }
        
//        testGraph.printGraph();
        testGraph.PrintGraphStats();
        
    } catch (std::invalid_argument) {
        std::cout << "Invalid argument for MAXIMUM_NUMBER_OF_NODES::Must be a positive integer::TERMINATING PROGRAM\n";
        exit(1);
    }
    
    
    return 0;
}
Ejemplo n.º 8
0
void GreedyHeuristic::getGreedyHeuristicResult(UndirectedGraph* aTree, int cardinality, string ls_type) {

  UndirectedGraph* greedyTree = new UndirectedGraph();
  bool started = false;
  for (list<Edge*>::iterator anEdge = ((*graph).edges).begin(); anEdge != ((*graph).edges).end(); anEdge++) {
    greedyTree->clear();
    greedyTree->addVertex((*anEdge)->fromVertex());
    greedyTree->addVertex((*anEdge)->toVertex());
    greedyTree->addEdge(*anEdge);
    generateNeighborhoodFor(*anEdge);
    for (int k = 1; k < cardinality; k++) {
      Edge* kctn = getMinNeighbor();
      Vertex* nn = determineNeighborNode(kctn,greedyTree);
      greedyTree->addVertex(nn);
      greedyTree->addEdge(kctn);
      adaptNeighborhoodFor(kctn,nn,greedyTree);
    }
    if (!(ls_type == "no")) {
      
      /* application of local search */
      if (ls_type == "leafs") {
	LocalSearch lsm(graph,greedyTree);
	lsm.run(ls_type);
      }
      else {
	if (ls_type == "cycles_leafs") {
	  //cout << *greedyTree << endl;
	  LocalSearchB lsm;
	  lsm.run(graph,greedyTree);
	}
      }
      /* end local search */
      /*
      if (!isConnectedTree(greedyTree)) {
	cout << "non-connected tree" << endl;
      }
      */

    }
    greedyTree->setWeight(weightOfSolution(greedyTree));
    if (started == false) {
      started = true;
      aTree->copy(greedyTree);
    }
    else {
      if ((greedyTree->weight()) < (aTree->weight())) {
	aTree->copy(greedyTree);
      }
    }
  }
  delete(greedyTree);
}
Ejemplo n.º 9
0
int main(void)
{
	using namespace alg;
	srand(time(NULL));
	int NVERTEX = 10;
	UndirectedGraph * g = UndirectedGraph::randgraph(NVERTEX);
	g->printdot();
	printf("Generating Kruskal's Graph: \n");
	Kruskal pg(*g);
	pg.print();


	printf("Generating Minimal spanning tree: \n");
	Graph * mst = pg.run();
	mst->printdot();
	delete mst;
	delete g;
	return 0;
}
Ejemplo n.º 10
0
UndirectedGraph* DirectedGraph::convertToUndirectedGraph() {
	UndirectedGraph* result = new UndirectedGraph(maxNodeId);
	for (int i = 0; i != maxNodeId + 1; i++) {
		if (!hasNode(i))
			continue;
		ListType* neighborsList = inNeighborsTable[i];
		for (ListType::iterator neighbor = neighborsList->begin();
				neighbor != neighborsList->end(); neighbor++) {
			result->addEdge(*neighbor, i);
		}
		neighborsList = outNeighborsTable[i];
		for (ListType::iterator neighbor = neighborsList->begin();
				neighbor != neighborsList->end(); neighbor++) {
			result->addEdge(*neighbor, i);
		}
	}
	result->sort();
	return result;
}
Ejemplo n.º 11
0
int main( int argc, char **argv ) {

    if ( argc < 2 ) {
        print_help();
        exit(1);
    }
    else {
        read_parameters(argc,argv);
    }

    // initialize random number generator

    rnd = new Random((unsigned) time(&t));

    // initialize and read instance from file

    graph = new UndirectedGraph(i_file);
    GreedyHeuristic gho(graph);

    for (int i = cardb; i <= carde; i++) {
        cardinality = i;
        if ((cardinality == cardb) || (cardinality == carde) || ((cardinality % cardmod) == 0)) {
            Timer timer;

            UndirectedGraph* greedyTree = new UndirectedGraph();
            if (type == "edge_based") {
                gho.getGreedyHeuristicResult(greedyTree,cardinality,ls);
            }
            else {
                if (type == "vertex_based") {
                    gho.getVertexBasedGreedyHeuristicResult(greedyTree,cardinality,ls);
                }
            }

            printf("%d\t%f\t%f\n",cardinality,greedyTree->weight(),timer.elapsed_time(Timer::VIRTUAL));

            delete(greedyTree);
        }
    }
    delete(graph);
    delete rnd;
}
Ejemplo n.º 12
0
UndirectedGraph * readGraphFromFile(char * filename) {
    char token;
    int x=0, y=0, i=0;
    int nodes_count = 0;
    UndirectedGraph *graph;
    
    FILE *file = fopen(filename, (const char *)"r");
    if (file == NULL) {
        std::cout << "Neexistujici soubor:" << filename << endl;
        exit(EXIT_FAILURE);
    }

    if (fscanf(file, "%d", &nodes_count) != 1) {
        std:cout << "Nelze nacist prvni radek vstupniho souboru" <<endl;
        exit(EXIT_FAILURE);
    }
    
    graph = new UndirectedGraph(nodes_count);
    while (fscanf(file, "%c", &token) == 1) {
        if (token == '\r') {
            continue;
        }
        if (token == '\n') {
            //printf("\n");
            if (i > 0) {
                x=0;
                y++;
            }
            
            continue;
        }
        if(token == '1') {
            graph->addEdge(x,y);
        }
        x++;
        i++;
    }
	fclose(file);
    return graph;
}
/**
 * Removes all edges from the graph except those necessary to
 * form a minimum cost spanning tree of all vertices using Prim's
 * algorithm.
 *
 * The graph must be in a state where such a spanning tree
 * is possible. To call this method when a spanning tree is
 * impossible is undefined behavior.
 */
UndirectedGraph UndirectedGraph::minSpanningTree() {
  // Define based on the Wikipedia Pseudocode
  UndirectedGraph nug;
  
  std::priority_queue<Edge> edges;

  for (vertexmap::iterator vi = this->vertices.begin();
       vi != this->vertices.end();
       vi++)
    vi->second->setVisited(false);

  Vertex *cur = this->vertices.begin()->second;
  cur->setVisited(true);
  for (Vertex::edgemap::iterator ei = cur->edges.begin();
       ei != cur->edges.end();
       ei++)
    edges.push(ei->second);
  
  while (!edges.empty() && nug.vertices.size() < this->vertices.size()) {
    Edge small = edges.top();
    edges.pop();
    Vertex *to = small.getTo();
    
    if (to->wasVisited())
      continue;
    else {
      to->setVisited(true);
      nug.addEdge(small);
      for (Vertex::edgemap::iterator ei = to->edges.begin();
	   ei != to->edges.end();
	   ei++)
	if (!ei->second.getTo()->wasVisited())
	  edges.push(ei->second);
    }
  } // END WHILE

  return nug;
}
Ejemplo n.º 14
0
void DepthFirstSearch(const UndirectedGraph& graph, int vertex, const Edge& incoming_edge,
        vector<Color>* colors, DFSVisitor* visitor) {

    colors->at(vertex) = GREY;
    visitor->EnterVertex(vertex);

    UndirectedGraph::EdgeIterator edge;
    for (edge = graph.EdgesBegin(vertex); edge != graph.EdgesEnd(vertex); ++edge) {
        if (edge->id == incoming_edge.id) {
            continue;
        }

        if (colors->at(edge->head) == GREY) {
            visitor->BackEdge(*edge);
        }

        if (colors->at(edge->head) == WHITE) {
            DepthFirstSearch(graph, edge->head, *edge, colors, visitor);
            visitor->TreeEdge(*edge);
        }
    }
    colors->at(vertex) = BLACK;
}
      explicit ConnectedComponentsDecomposer(const UndirectedGraph<>& g) {
        int nVertices = g.num_vertices();
        vertexToComponent_.clear();
        vertexToComponent_.resize(nVertices);
        fill(begin(vertexToComponent_), end(vertexToComponent_), -1);

        int iComponent = 0;
        for (int i = 0; i < nVertices; ++i) {
            if (vertexToComponent_[i] >= 0)
                continue;  // Lies in processed component

            components_.push_back(std::vector<int>());
            dfs(g, {i}, [&](const GraphTraversalState& state, int index) {
                components_.back().push_back(index);
                vertexToComponent_[index] = iComponent;
                return IterationControl::Proceed;
            });
            iComponent++;
        }
    }
Ejemplo n.º 16
0
// check whether graph is a bigraph or not with dfs
bool bigraph(UndirectedGraph& g){
    int num_vertex = g.get_num_vertex();
    int* color = (int *)malloc(sizeof(int)*num_vertex);
    memset(color, 0, num_vertex*sizeof(int));

    bool result = true;

    for(int i=0;i<num_vertex;i++){
        if(color[i]==0){
            if(!dfs(i, 1, g, color)){
                result = false;
                break;
            }
        }
    }

    free(color);

    return result;
}
Ejemplo n.º 17
0
TEST_F(UndirectedGraphFixture, canBeMoved)
{
    g_.addEdge(0, 1, 7);
    g_.addEdge(3, 2, 123);
    UndirectedGraph moved { std::move(g_) };
    ASSERT_EQ(7, moved.getWeightOfEdge(0, 1));
    ASSERT_EQ(123, moved.getWeightOfEdge(2, 3));
    ASSERT_EQ(2, moved.getNumberOfEdges());
    ASSERT_EQ(5, moved.getNumberOfVertices());
    ASSERT_EQ(130, moved.getSumOfWeights());

    ASSERT_FALSE(g_.edgeExists(0, 1));
    ASSERT_FALSE(g_.edgeExists(1, 0));
    ASSERT_FALSE(g_.edgeExists(2, 3));
    ASSERT_FALSE(g_.edgeExists(3, 2));
    ASSERT_EQ(0, g_.getNumberOfEdges());
    ASSERT_EQ(0, g_.getNumberOfVertices());
    ASSERT_EQ(0, g_.getSumOfWeights());
}
Ejemplo n.º 18
0
UndirectedGraph* GreedyHeuristic::uniteOnCommonBase(UndirectedGraph* t1, UndirectedGraph* t2, list<Edge*>* is) {

  UndirectedGraph* ugh = new UndirectedGraph();
  for (list<Vertex*>::iterator v = ((*t1).vertices).begin(); v != ((*t1).vertices).end(); v++) {
    ugh->addVertex(*v);
  }
  for (list<Vertex*>::iterator v = ((*t2).vertices).begin(); v != ((*t2).vertices).end(); v++) {
    if (!(ugh->contains(*v))) {
      ugh->addVertex(*v);
    }
  }
  for (list<Edge*>::iterator e = ((*t1).edges).begin(); e != ((*t1).edges).end(); e++) {
    ugh->addEdge(*e);
  }
  for (list<Edge*>::iterator e = ((*t2).edges).begin(); e != ((*t2).edges).end(); e++) {
    if (!(ugh->contains(*e))) {
      ugh->addEdge(*e);
    }
    else {
      is->push_back(*e);
    }
  }
  return ugh;
}
Ejemplo n.º 19
0
inline void HexBoard::getNeighbors(const int index, vector<int> &neighbors)
{
  board.getNeighbors(index, neighbors);
}
Ejemplo n.º 20
0
inline HexBoardPiece HexBoard::get(const int index)
{
  return board.getNodeValue(index);
}
Ejemplo n.º 21
0
/**
 * Entry point into the netplan program.
 *
 * -Reads a file from the filesystem according to the specification for
 *  PA3, creating an UndirectedGraph.
 * -Finds the total cost & ping time of the graph as presented in the input
 *  file.
 * -Determines the minimum cost graph from the original graph.
 * -Finds the total cost & ping time of the minimum cost graph.
 * -Finds the change of cost & ping time from the original graph to the
 *  minimum cost graph.
 * -Prints the results to stdout.
 *
 * Usage:
 *   ./netplan infile
 *
 */
int main(int argc, char **argv) {
    // Data Structs to hold the variables
    vector<string> to;
    vector<string> from;
    vector<unsigned int> cost;
    vector<unsigned int> length;

    // if number of arguments passed in is not 2, print usage
    if (argc != 2) {
        std::cerr << "Usage: " << argv[0] << " infile" << std::endl;
        return EXIT_FAILURE;
    }
    
    std::ifstream in(argv[1]);
    if (!in) {
        std::cerr << "Unable to open file for reading." << std::endl;
        return EXIT_FAILURE;
    }

    // string and int variables for adding to the vectors
    string str;
    unsigned int i;

    /**
     * while file is not empty, parse input so that we can make a graph from
     * the input
     */
    while(true){
        in >> str;
        if(in.eof()) break;
        to.push_back(str);

        in >> str;
        from.push_back(str);

        in >> i;
        cost.push_back(i);

        in >> i;
        length.push_back(i);
    }

    /**
     * create undirected graph from the input file
     */
    UndirectedGraph *bob = new UndirectedGraph();
    for(unsigned int j = 0; j < to.size(); j++){
        bob->addEdge(to[j], from[j], cost[j], length[j]);
    }

    // get total edge cost of inital graph
    unsigned int totalCost = bob->totalEdgeCost();

    // get total distance of inital graph, by using Dijkstra's algorithm on 
    // all the vertices
    unsigned int totalTime = bob->totalDistance();

    // create minimum spanning tree of the inital graph, using Prim's algorithm
    bob->minSpanningTree();

    // get total edge cost of minimum spanning tree
    unsigned int mstCost = bob->totalEdgeCost();

    // get total distance of minimum spanning tree, using Dijkstra's algorithm
    // on all the vertices
    unsigned int mstTime = bob->totalDistance();

    // print out all the costs and distances
    cout << totalCost << endl;
    cout << mstCost << endl;
    cout << totalCost - mstCost << endl;
    cout << totalTime << endl;
    cout << mstTime << endl;
    cout << mstTime - totalTime << endl;

    // delete graph
    delete(bob);

    return EXIT_SUCCESS;
}
Ejemplo n.º 22
0
TEST(Graph, add) {
  UndirectedGraph graph {20};
  graph.addEdge(0, 1);
  EXPECT_EQ(1, graph.edges());
}
Ejemplo n.º 23
0
int main() {
    cout << "--------------GRAPHTESTERFILE-----------------" << endl;

    cout << "CREATING GRAPH" << endl;
    UndirectedGraph testG = UndirectedGraph();

    cout << "ADDING EDGE WITHOUT ANY VERTICES EXISTING" << endl;
    testG.addEdge("Yahoo","Google",13,13);

    cout << "total edge cost: ";
    cout << testG.totalEdgeCost() << endl;

    cout << "ADDING DUPLICATE" << endl;
    testG.addEdge("Yahoo","Google",9,9);

    cout << "total edge cost: ";
    cout << testG.totalEdgeCost() << endl;

    cout << "ADDING REVERSED DUPLICATE" << endl;
    testG.addEdge("Google","Yahoo",7,7);

    cout << "total edge cost: ";
    cout << testG.totalEdgeCost() << endl;    

    cout << "ADDING EDGE" << endl;
    testG.addEdge("Yahoo","Microsoft",71,71);
    cout << "total edge cost: ";    
    cout << testG.totalEdgeCost() << endl;

    cout << "ADDING UNCONNECTED EDGE" << endl;
    testG.addEdge("Netflix","Yelp",21,21);
    cout << "total edge cost: ";    
    cout << testG.totalEdgeCost() << endl;

    cout << "SETTING UP NON-MST" << endl;
    testG.addEdge("Google","Yahoo",2,2);
    testG.addEdge("Yahoo","Microsoft",3,3);
    testG.addEdge("Microsoft","Netflix",5,5);
    testG.addEdge("Netflix","Yelp",7,7);
    testG.addEdge("Yelp","Google",11,11);
    testG.addEdge("Netflix","Google",13,13);
    testG.addEdge("Google","Microsoft",17,17);

    cout << "total edge cost: ";    
    cout << testG.totalEdgeCost() << endl;

    cout << "CREATING MST" << endl;
    testG.minSpanningTree();
    cout << "total edge cost: ";        
    cout << testG.totalEdgeCost() << endl;

    cout << "TEST TOTAL DISTANCE" << endl;
    cout << "total distance: ";
    cout << testG.totalDistance("Google") << endl;

    cout << "TEST TOTAL DISTANCE NEW GRAPH" << endl;
    UndirectedGraph graphTwo = UndirectedGraph();
    graphTwo.addEdge("Google","Yahoo",2,2);
    graphTwo.addEdge("Yahoo","Microsoft",3,3);    
    cout << graphTwo.totalDistance("Google") << endl;
    cout << graphTwo.totalDistance("Yahoo") << endl;
    cout << graphTwo.totalDistance("Microsoft") << endl;
    cout << graphTwo.totalDistance() << endl;

    return 1;
}
Ejemplo n.º 24
0
TEST(Graph, size) {
  UndirectedGraph graph {20};
  EXPECT_EQ(20, graph.vertices());
}
Ejemplo n.º 25
0
inline double ShortestPath::pathCost()
{
  return currGraph->getNodeValue(currEndNode); // the cost at the target node
}
Ejemplo n.º 26
0
int main( int argc, char **argv ) {

    if ( argc < 2 ) {
        cout << "something wrong" << endl;
        exit(1);
    }
    else {
        read_parameters(argc,argv);
    }
    Timer initialization_timer;

    rnd = new Random((unsigned) time(&t));

    graph = new UndirectedGraph(i_file);

    init_pheromone_trail();

    register int i = 0;
    register int j = 0;
    register int k = 0;
    register int b = 0;

    cout << endl;
    for (int card_counter = cardb; card_counter <= carde; card_counter++) {
        cardinality = card_counter;
        if ((cardinality == cardb) || (cardinality == carde) || ((cardinality % cardmod) == 0)) {
            printf("begin cardinality %d\n",cardinality);

            if (tfile_is_given) {
                if (times.count(cardinality) == 1) {
                    time_limit = times[cardinality];
                }
            }
            vector<double> results;
            vector<double> times_best_found;
            double biar = 0.0;

            int n_of_ants = (int)(((double)((*graph).edges).size()) / ((double)cardinality));
            if (n_of_ants < 15) {
                n_of_ants = 15;
            }
            if (n_of_ants > 50) {
                n_of_ants = 50;
            }

            if (ants.size() > 0) {
                for (list<KCT_Ant*>::iterator anAnt = ants.begin(); anAnt != ants.end(); anAnt++) {
                    delete(*anAnt);
                }
            }
            ants.clear();

            for (i = 0; i < n_of_ants; i++) {
                KCT_Ant* ant = new KCT_Ant();
                ant->initialize(graph,rnd,pheromone,daemon_action);
                ants.push_back(ant);
            }

            for (int trial_counter = 1; trial_counter <= n_of_trials; trial_counter++) {
                printf("begin try %d\n",trial_counter);

                UndirectedGraph* best = NULL;
                UndirectedGraph* newSol = NULL;
                UndirectedGraph* restartBest = NULL;

                double ib_weight = 0.0;
                double rb_weight = 0.0;
                double gb_weight = 0.0;

                Timer timer;

                if ((!(card_counter == cardb)) || (!(trial_counter == 1))) {
                    reset_pheromone_trail();
                    for (list<KCT_Ant*>::iterator ant = ants.begin(); ant != ants.end(); ant++) {
                        (*ant)->restart_reset();
                    }
                }

                int iter = 1;
                double cf = 0.0;
                bool restart = false;
                bool program_stop = false;
                bool bs_update = false;

                while (program_stop == false) {

                    for (list<KCT_Ant*>::iterator ant = ants.begin(); ant != ants.end(); ant++) {
                        for (k = 0; k < cardinality; k++) {
                            (*ant)->step(0.8);
                        }
                        (*ant)->evaluate();
                    }

                    if (!(newSol == NULL)) {
                        delete(newSol);
                    }
                    if (elite_action == "no") {
                        newSol = getBestDaemonSolutionInIteration();
                    }
                    else {
                        KCT_Ant* bestAnt = getBestDaemonAntInIteration();
                        bestAnt->eliteAction();
                        newSol = new UndirectedGraph();
                        newSol->copy(bestAnt->getCurrentDaemonSolution());
                    }

                    if (iter == 1) {
                        best = new UndirectedGraph();
                        printf("best %f\ttime %f\n",newSol->weight(),timer.elapsed_time(Timer::VIRTUAL));
                        best->copy(newSol);
                        restartBest = new UndirectedGraph(newSol);
                        results.push_back(newSol->weight());
                        times_best_found.push_back(timer.elapsed_time(Timer::VIRTUAL));
                        if (trial_counter == 1) {
                            biar = newSol->weight();
                        }
                        else {
                            if (newSol->weight() < biar) {
                                biar = newSol->weight();
                            }
                        }
                    }
                    else {
                        if (restart) {
                            restart = false;
                            restartBest->copy(newSol);
                            if (newSol->weight() < best->weight()) {
                                printf("best %f\ttime %f\n",newSol->weight(),timer.elapsed_time(Timer::VIRTUAL));
                                best->copy(newSol);
                                results[trial_counter-1] = newSol->weight();
                                times_best_found[trial_counter-1] = timer.elapsed_time(Timer::VIRTUAL);
                                if (newSol->weight() < biar) {
                                    biar = newSol->weight();
                                }
                            }
                        }
                        else {
                            if (newSol->weight() < restartBest->weight()) {
                                restartBest->copy(newSol);
                            }
                            if (newSol->weight() < best->weight()) {
                                printf("best %f\ttime %f\n",newSol->weight(),timer.elapsed_time(Timer::VIRTUAL));
                                best->copy(newSol);
                                results[trial_counter-1] = newSol->weight();
                                times_best_found[trial_counter-1] = timer.elapsed_time(Timer::VIRTUAL);
                                if (newSol->weight() < biar) {
                                    biar = newSol->weight();
                                }
                            }
                        }
                    }

                    cf = get_cf(newSol);
                    //cout << "cf: " << cf << endl;

                    if (bs_update && (cf > 0.99)) {
                        //cout << "doing restart" << endl;
                        bs_update = false;
                        restart = true;
                        cf = 0.0;
                        reset_pheromone_trail();
                    }
                    else {

                        if (cf > 0.99) {
                            bs_update = true;
                        }

                        if (!bs_update) {
                            if (cf < 0.7) {
                                l_rate = 0.15;
                                ib_weight = 2.0/3.0;
                                rb_weight = 1.0/3.0;
                                gb_weight = 0.0;
                            }
                            if ((cf >= 0.7) && (cf < 0.95)) {
                                l_rate = 0.1;
                                ib_weight = 1.0 / 3.0;
                                rb_weight = 2.0 / 3.0;
                                gb_weight = 0.0;
                            }
                            if (cf >= 0.95) {
                                l_rate = 0.05;
                                ib_weight = 0.0;
                                rb_weight = 1.0;
                                gb_weight = 0.0;
                            }
                        }
                        else {
                            // if bs_update = TRUE we use the best_so_far solution for updating the pheromone values
                            l_rate = 0.1;
                            ib_weight = 0.0;
                            rb_weight = 0.0;
                            gb_weight = 1.0;
                        }

                        map<Edge*,double>* trans_best = translate_solution(best);
                        map<Edge*,double>* trans_newSol = translate_solution(newSol);
                        map<Edge*,double>* trans_restartBest = translate_solution(restartBest);
                        map<Edge*,double>* new_pd = new map<Edge*,double>;
                        for (list<Edge*>::iterator e = (graph->edges).begin(); e != (graph->edges).end(); e++) {
                            (*new_pd)[*e] = 0.0;
                            (*new_pd)[*e] = (*new_pd)[*e] + (ib_weight * (*trans_newSol)[*e]) + (rb_weight * (*trans_restartBest)[*e]) + (gb_weight * (*trans_best)[*e]);
                        }
                        for (list<Edge*>::iterator e = (graph->edges).begin(); e != (graph->edges).end(); e++) {
                            (*pheromone)[*e] = (*pheromone)[*e] + (l_rate * ((*new_pd)[*e] - (*pheromone)[*e]));
                            if ((*pheromone)[*e] > tau_max) {
                                (*pheromone)[*e] = tau_max;
                            }
                            if ((*pheromone)[*e] < tau_min) {
                                (*pheromone)[*e] = tau_min;
                            }
                        }
                        delete(trans_best);
                        delete(trans_newSol);
                        delete(trans_restartBest);
                        delete(new_pd);
                    }

                    for (list<KCT_Ant*>::iterator i = ants.begin(); i != ants.end(); i++) {
                        (*i)->reset();
                    }

                    iter = iter + 1;

                    if (tfile_is_given) {
                        if (timer.elapsed_time(Timer::VIRTUAL) > time_limit) {
                            program_stop = true;
                        }
                    }
                    else {
                        if (time_limit_given && iter_limit_given) {
                            if ((timer.elapsed_time(Timer::VIRTUAL) > time_limit) || (iter > n_of_iter)) {
                                program_stop = true;
                            }
                        }
                        else {
                            if (time_limit_given) {
                                if (timer.elapsed_time(Timer::VIRTUAL) > time_limit) {
                                    program_stop = true;
                                }
                            }
                            else {
                                if (iter > n_of_iter) {
                                    program_stop = true;
                                }
                            }
                        }
                    }
                }
                printf("end try %d\n",trial_counter);

                // eturetken 18.09.09. Write the best MST for this cardinality to the file.
                ////////////////////////////////////////////////////////////////////
                if( mstfile_is_given )
                {
                    string MSTFile(mst_file);
                    best->Write2File(concatIntToString(MSTFile, card_counter) + ".mst");
                }
                ////////////////////////////////////////////////////////////////////

                delete(best);
                delete(restartBest);
                delete(newSol);
            }

            double r_mean = 0.0;
            double t_mean = 0.0;
            for (int i = 0; i < results.size(); i++) {
                r_mean = r_mean + results[i];
                t_mean = t_mean + times_best_found[i];
            }
            r_mean = r_mean / ((double)results.size());
            t_mean = t_mean / ((double)times_best_found.size());
            double rsd = 0.0;
            double tsd = 0.0;
            for (int i = 0; i < results.size(); i++) {
                rsd = rsd + pow(results[i]-r_mean,2.0);
                tsd = tsd + pow(times_best_found[i]-t_mean,2.0);
            }
            rsd = rsd / ((double)(results.size()-1.0));
            if (rsd > 0.0) {
                rsd = sqrt(rsd);
            }
            tsd = tsd / ((double)(times_best_found.size()-1.0));
            if (tsd > 0.0) {
                tsd = sqrt(tsd);
            }
            if (output_file_given == true) {
                fout << cardinality << "\t" << r_mean << "\t" << rsd << "\t" << t_mean << "\t" << tsd << endl;
            }
            else {
                printf("statistics\t%d\t%g\t%f\t%f\t%f\t%f\n",cardinality,biar,r_mean,rsd,t_mean,tsd);
            }
            printf("end cardinality %d\n",cardinality);
        }
    }
    if (output_file_given == true) {
        fout.close();
    }
    delete(graph);
    delete rnd;
}