示例#1
0
map<char *, int> dijkstra(graph g, char* source_node) {
	int MAX_INT = 63356  ;
	// build the heap
	heap nodes_heap;
	// create a map with not visited nodes

	map<char *, int> m_not_visited;
	graph::iterator it;
	for( it = g.begin(); it != g.end(); it++)
	{
		if( strcmp(it->first, source_node) ){
			nodes_heap.push(make_pair(MAX_INT, it->first));
			m_not_visited.insert(make_pair(it->first, MAX_INT));
		}
	}

	m_not_visited.insert(make_pair(source_node, 0));
	// initialize the map that will store the shortest paths.

	map<char *, int> m_shortest_path;
	m_shortest_path.insert( make_pair(source_node , 0) );

	while(nodes_heap.size() > 0){
		pair<int, char*> node = nodes_heap.top();
		if( m_not_visited.find( node.second ) == m_not_visited.end() )
			continue;
		m_shortest_path[node.second] = node.first;
		update_heap(nodes_heap, g, source_node, m_not_visited, node.first);
		m_not_visited.erase(node.second);
	}
	return m_shortest_path;
}
示例#2
0
文件: p6b.cpp 项目: mossberg/eece3326
void kruskal(graph &g, graph &sf)
// from weighted graph g, set sf to minimum spanning forest
// uses a priority queue with edges sorted from large to min weight
// since top of queue is the back of underlying vector
// for every edge, add to sf, but if it creates cycle, then
// remove it and move to next edge
{
    g.clearMark();
    pqueue edges = getEdges(g);
    while (!edges.empty())
    {
        edgepair pair = edges.top();
        edges.pop();
        
        // add both edges to create undirected edges
        sf.addEdge(pair.i, pair.j, pair.cost);
        sf.addEdge(pair.j, pair.i, pair.cost);

        if (isCyclic(sf))
        {
            sf.removeEdge(pair.i, pair.j);
            sf.removeEdge(pair.j, pair.i);
        }
    }
}
示例#3
0
void mst::kruskal(graph g) {
    int num = g.num_of_vertices();
    vector< vector<float> > edges;
    union_find explored;
    reset();

    // put all connected vertices in "edges"
    for(int i=0; i<num; ++i) {
        for(int j=0; j<num; ++j) {
            float c = g.cost(i, j);
            if (c!=0) {
                vector<float> temp;
                temp.push_back(i);
                temp.push_back(j);
                temp.push_back(c);
                edges.push_back(temp);
            }
        }
    }
    sort(edges.begin(), edges.end(), kruskal_compare);

    for(vector<vector<float> >::iterator  p=edges.begin(); p!=edges.end(); ++p) {
        // both nodes in the closed set ==> detecting a cycle
        vector<float> temp = *p;
        int f1 = explored.find(temp[0]);
        int f2 = explored.find(temp[1]);
        if(f1!=-1 && f2!=-1 && f1==f2) continue;
        path_cost += temp[2];
        explored.insert(temp[0], temp[1]);
        //cout <<"From "<<temp[0]<<" To "<<temp[1]<<" -- Cost "<<temp[2]<<endl;
    }
    // ckeck if there are isolated nodes
    if (explored.num_of_unions() != 1) path_cost=-1;
}
示例#4
0
文件: 1486.cpp 项目: miskcoo/oicode
int main()
{
	std::freopen("circle.in", "r", stdin);
	std::freopen("circle.out", "w", stdout);
	int N, M;
	std::scanf("%d %d", &N, &M);
	gp.init(N);
	for(int i = 0; i != M; ++i)
	{
		int u, v;
		double w;
		std::scanf("%d %d %lf", &u, &v, &w);
		gp.add_edge(u, v, w);
	}

	double epsilon = 1.0e-9;
	double r = 1.0e8, l = -1.0e8;
	while(r - l > epsilon)
	{
		double m = (l + r) * 0.5;
		if(gp.has_neg_circle(m))
			r = m;
		else l = m;
	}
	std::printf("%.8f\n", l);
	return 0;
}
示例#5
0
void findCities(graph<int>& g, LList<int>& cities, int cityId, int p){
	elem_link1<int>* start = g.point(cityId);
	int dist[100];	// 100???
	bool visited[100];	// 100??? - nikoi ne garantira, che id-tata na cities shte sa posledovatelni chisla pod 100
	memset(dist, -1, 100);
	memset(visited, 0, 100);

	if (start){
		visited[start->inf] = true;
		dist[start->inf] = 0;
		queue<int> q;
		q.push(start->inf);
		while (!q.empty()){
			int current = q.front();
			q.pop();
			elem_link1<int>* p = g.point(current);
			p = p->link;
			while (p){
				if (!visited[p->inf]){
					visited[p->inf] = true;
					dist[p->inf] = dist[current] + 1;
					q.push(p->inf);
				}
				p = p->link;
			}

		}

		for (int i = 0; i < 100; i++){
			if (dist[i] >= 0 && dist[i] <= p){
				cities.toEnd(i);
			}
		}
	}
}
示例#6
0
// calculate the path using dijkstra's algo.
void dijkstra::path(graph g, int u, int v) {
    int num = g.num_of_vertices();
    minheap* candidates = new minheap(num);
    // reset the path_cost and clear the closed_set
    reset();

    // initialize the heap
    // the nodes in the heap are those of "open set"
    for (int i=0; i<num; ++i) {
        float c = g.cost(u, i);
        if (c!=0)
            candidates->update(c, i);
    }

    while (candidates->size()!=0) {
        heapitem t = candidates->pop();
        int node = t.get_node();
        // not record the duplicated probed nodes
        if (closed_set.find(node)!=closed_set.end())
            continue;
        closed_set.insert(node);
        path_cost = t.get_key();
        // terminated if arrives at the destination
        if (node == v)
            return;
        vector<int> n = g.neighbors(node);
        // update the heap with newly found nodes
        for(vector<int>::iterator i=n.begin(); i!=n.end(); ++i) {
            candidates->update(path_cost+g.cost(node,*i), *i);
        }
    }
    // after iteration, the v is not found
    path_cost = -1;
}
示例#7
0
vector<int> daiquistra(graph& g, int v){
	vector<int> dist(g.size(), INT_MAX);
	vector<int> prev(g.size(), -1);
	
	dist[v] = 0;
	set<pair<int, int> > q;
	for(int i = 0; i<g.size(); i++){
		q.insert(make_pair(dist[i], i));
	}
	
	while(!q.empty()){
		int u = q.begin()->second;
		int p = q.begin()->first;
		q.erase(q.begin());
		if(dist[u] == INT_MAX)
			break;
		
		for(int i = 0; i<g[u].size(); i++){
			int w = g[u][i].second;
			int alt = dist[u] + g[u][i].first;
			if(alt < dist[w]){
				q.erase(make_pair(dist[w], w));
				dist[w] = alt;
				prev[w] = u;
				q.insert(make_pair(dist[w], w));
			}
		}
	}
	
	return prev;	
}
示例#8
0
bool CDLib::read_edgelist(graph& g, const string& filepath) {
    g.clear();
    ifstream ifs;
    ifs.open(filepath.c_str());
    if (ifs.is_open()) {
        vector<string> units;
        double weight;
        while (!ifs.eof()) {
            weight = 1;
            string line;
            getline(ifs, line);
            if ((line.size() > 0) && (line[0] != '#')) {
                split(line, units);
                if (units.size() != 0) {
                    if ((units.size() < 2) || (units.size() > 3)) return false;
                    if (units.size() == 3) weight = str2T<double>(units[2]);
                    g.add_node(units[0]);
                    g.add_node(units[1]);
                    g.add_edge(units[0], units[1], weight);
                }
            }
        }
        g.set_graph_name(filename(filepath));
        return true;
    }
    return false;
}
示例#9
0
graph kruskal (graph &rede){

	graph result;
	int max_custo = 0;

	graph::iterator it;
	int no1, no2;
	vertice v;

	for (it = rede.begin(); it != rede.end(); it++){

		v = it->second;
		
		no1 = v.first;
		no2 = v.second;

		if (findset(no1) != findset(no2)){

			v = ordena (v.first, v.second);

			result.insert (make_pair (0, v));
			join (no1, no2);
			max_custo += it->first;
		}
		
		
	}

	cout << max_custo << endl;
	return result;
}
示例#10
0
int dijkstra::check(graph& G)
{
    if ((s == node()) || (!weights_set))
    {
	return GTL_ERROR;
    }

    bool source_found = false;
    graph::node_iterator node_it;
    graph::node_iterator nodes_end = G.nodes_end();
    for (node_it = G.nodes_begin(); node_it != nodes_end; ++node_it)
    {
	if (*node_it == s)
        {
	    source_found = true;
	    break;
	}
    }
    if (!source_found)
    {
	return(GTL_ERROR);
    }

    graph::edge_iterator edge_it;
    graph::edge_iterator edges_end = G.edges_end();
    for(edge_it = G.edges_begin(); edge_it != edges_end; ++edge_it)
    {
	if (weight[*edge_it] < 0.0)
	{
	    return false;
	}
    }

    return GTL_OK;
}
示例#11
0
bool circuit::goodCircuit()
{
    matrix<int> adj2 = circuit_graph.adjacency_matrix();
    adj2 = adj2*adj2;
    for(int i=0;i<circuit_graph.nVertices();i++) if(adj2(i,i)<2) return false;
    return circuit_graph.isConnected();
}
void path(town start, graph<town>& g, int p, LList<town> &visited){
	if (g.empty())return;
	int count = 0;
	queue<town> q;
	q.push(start);
	visited.toEnd(start);

	elem_link1<town> * f = g.point(start);
	f = f->link;
	while (!q.empty()){
		town t;
		q.pop(t);

		while (f){
			if (p == count)return;
			else if (!member(visited, f->inf)){

				q.push(f->inf);
				visited.toEnd(f->inf);
				count++;
			}

			f = f->link;
		}
	}
}
示例#13
0
文件: p6b.cpp 项目: tLiMiT/EECE-3326
void findCycle(int curr, int start, bool &found, graph &g)
	// checks for cycles in a graph
{
	g.mark(curr);

	vector<int> lst = getNeighbors(curr, g);

	for (int i = 0; i < lst.size(); i++)
	{
		if (start == lst[i])
		{
			continue;
		}
		if (g.isMarked(lst[i]))
		{
			found = true;
		}
		else if (!g.isVisited(lst[i]))
		{
			findCycle(lst[i], curr, found, g);
		}
	} // for

	g.unMark(curr);
	g.visit(curr);

} // findCycle
示例#14
0
文件: p6b.cpp 项目: tLiMiT/EECE-3326
void findSpanningForest(graph &g, graph &sf)
	// Create a graph sf that contains a spanning forest on the graph g.
{
	if (isConnected(g) && !isCyclic(g))
	{
		sf = g;
	}
	else
	{
		// add nodes to sf
		for (int i = 0; i < g.numNodes(); i++)
		{
			sf.addNode(g.getNode(i));
		}

		// build sf
		for (int i = 0; i < g.numNodes(); i++)
		{
			for (int j = 0; j < g.numNodes(); j++)
			{
				if (g.isEdge(i, j) && !sf.isEdge(i, j))
				{
					sf.addEdge(i, j, g.getEdgeWeight(i, j));
					sf.addEdge(j, i, g.getEdgeWeight(j, i));

					if(isCyclic(sf))
					{
						sf.removeEdge(j, i);
						sf.removeEdge(i, j);
					} // if
				} // if
			} // for
		} // for
	} // else
} // findSpanningForest
示例#15
0
void order_subgraphs_wrapper(vector<subgraph*> &sgorder, subgraph *sg, 
                             graph &g) {
	// simplify the call to the above order subgraphs
	deque<vertex> order;
  	map<vertex,subgraph*> new_sub;
  	map<vertex,vertex> new_old;
  	
  	if (sg == 0) {
  		vector<vertex> verts;
	  	for (unsigned int i = 0; i != g.num_vertices(); ++i)
	    	if (g.find_parent(i) == 0 && (g.adj(i).size() > 0 || g.inv_adj(i).size() > 0))
	      		verts.push_back(i);
	  	
	  	order_subgraphs(order, new_sub, new_old, 0, verts, g.subgraphs, g);
  	}
  	else {
  		order_subgraphs(order, new_sub, new_old, sg, sg->vertices, sg->subs, g);
  	}
  	
  	map<vertex,subgraph*>::iterator itr = new_sub.begin();
  	for (unsigned int i = 0; i < order.size(); i++) {
        map<vertex,subgraph*>::iterator iter = new_sub.find(order[i]);
    	if (iter != new_sub.end()) {
            sgorder.push_back(iter->second);
        }
    }
}
示例#16
0
int main() {
	
	int test; cin >> test;
	int a = 1;
	while(test--) {
		cin >> r >> c >> m >> n >> w;
		g.assign(r, vector<int>(c,0));
		visited.assign(r, vector<int>(c,0));

		for(int i = 0; i < w; i++) {
			int x, y; cin >> x >> y;
			g[x][y] = -1;
		}

		for(int i = 0; i < r; i++) {
			for(int j = 0; j < c; j++) {
				if(g[i][j] != -1)
					g[i][j] = connectedFields(i,j).size();
			}
		}
		
		even = 0; odd = 0;
		bfs();
		cout << "Case " << a << ": " << even << " " << odd << endl;
		a++;

	}

}
示例#17
0
void topo_sort(graph& g, deque<vertex>& order) 
{
    vector<bool> visited(g.num_vertices(), false);
    for (vertex i = 0; i != g.num_vertices(); ++i)
        if (! visited[i])
            topo_sort_r(i, g, order, visited);
}
示例#18
0
vector<string> vertex_cover(const graph g) {
	vector<connection> list;
	copy(g.begin(), g.end(), back_inserter(list));

	sort(list.begin(), list.end(), [](connection a, connection b) {
		return a.second.size() > b.second.size();
	});

	vector<string> cover;
	while (list.size()) {
		connection max = list.at(0);
		cover.push_back(max.first);

		list.erase(list.begin());

		for (string conc : max.second) {
			if (!list.size())
				break;

			auto to_remove = find_if(list.begin(), list.end(), [conc](connection c) {
				return c.first == conc;
			});

			if (to_remove != list.end()) {
				list.erase(to_remove);
			}
		}
	}

	return cover;
}
示例#19
0
void update_iters_sg(graph &g, subgraph *sg) {
	vector<iterOp_t>::iterator i;
	for (i = sg->sg_iterator.conditions.begin();
			i != sg->sg_iterator.conditions.end(); ++i) {

		vector<string> separate;
		boost::split(separate, i->right, boost::is_any_of("+"));

		string newString = g.get_iter_rep(separate[0]);
		for (unsigned int k=1; k < separate.size(); ++k) {
			newString += "+" + g.get_iter_rep(separate[k]);
		}
		i->right = newString;
	}

	for (i = sg->sg_iterator.updates.begin();
			i != sg->sg_iterator.updates.end(); ++i) {

		vector<string> separate;
		boost::split(separate, i->right, boost::is_any_of("+"));

		string newString = g.get_iter_rep(separate[0]);
		for (unsigned int k = 1; k < separate.size(); ++k) {
			newString += "+" + g.get_iter_rep(separate[k]);
		}
		i->right = newString;
	}

	for (auto i : sg->subs) {
		update_iters_sg(g, i);
	}
}
示例#20
0
void recursiveDFS(int curId, int dstId, graph &g,
                  stack<int> &path, bool &done)
// depth first search that uses the mem stack to search the graph g
{

    if (curId == dstId)
    {
        done = true;
        path.push(curId);
    }
    else
    {
        g.mark(curId);
        g.visit(curId);

        vector<int> lst = getNeighbors(curId, g);

        while (!lst.empty())
        {
            int current =  lst.back();
            lst.pop_back();

            if (!g.isVisited(current))
            {
                recursiveDFS(current, dstId, g, path, done);
            }
            if (done)
                // if we found our node then construct our path
            {
                path.push(curId);
                break;
            }
        }
    }
}
示例#21
0
    //------------------------------------------------------------------------
    void draw_dashes_draft()
    {
        pixfmt pixf(rbuf_window());
        base_renderer rb(pixf);
        primitives_renderer prim(rb);
        outline_rasterizer ras(prim);

        int i;
        for(i = 0; i < m_graph.get_num_edges(); i++)
        {
            graph::edge e  = m_graph.get_edge(i);
            graph::node n1 = m_graph.get_node(e.node1, width(), height());
            graph::node n2 = m_graph.get_node(e.node2, width(), height());
            curve c(n1.x, n1.y, n2.x, n2.y);
            dash_stroke_draft<curve> s(c, 6.0, 3.0, m_width.value());

            int r = rand() & 0x7F;
            int g = rand() & 0x7F;
            int b = rand() & 0x7F;
            int a = 255;
            if(m_translucent.status()) a = 80;
            prim.line_color(agg::srgba8(r, g, b, a));
            ras.add_path(s);
        }
    }
示例#22
0
bool maze::findShortestPath1(graph &g)
//finds the shortest path in the given graph using DFS
{

    g.clearVisit();
    g.clearMark();
    int start = getMap(0, 0);
    int end = getMap(numRows() - 1, numCols() - 1);
    vector< stack<int> > rpaths = nonRecursiveDFS(start, end, g);

    stack<int> reverse_path;

    for(int i = 0; i < rpaths.size(); i++)
        if (rpaths[i].size() > reverse_path.size())
            reverse_path = rpaths[i];

    stack<int> path;

    while (!reverse_path.empty())
    {
        int top = reverse_path.top();
        reverse_path.pop();
        if (g.isVisited(top))
        {
            path.push(top);
        }
    }

    printPath(path);

}
示例#23
0
template < class T1, class T2 > bool bfs (graph < T1, T2 > &g, const T1 s, const T1 d, int player)	// To find path connectivity b/w two nodes s and d
{
  queue < T1 > list;
  map < T1, bool > path;
  map < T1, bool > visited;
  vector < T1 > ver = g.get_nodes ();
  for (auto it = ver.begin (); it != ver.end (); it++)
    {
      path[*it] = false;
      visited[*it] = false;
    }
  list.push (s);
  visited[s] = true;
  while (!list.empty ())
    {
      T1 curr_node = list.front ();
      list.pop ();
      vector < T1 > adj_curr = g.adjecent (curr_node);
      for (auto it = adj_curr.begin (); it != adj_curr.end (); it++)
	{
	  if (g.get_val (*it) == player && !visited[*it])
	    {
	      path[*it] = true;
	      if (*it == d)
		return true;
	      list.push (*it);
	      visited[*it] = true;
	    }
	}
    }
  return false;
}
示例#24
0
void maze::findPathNonRecursive(graph &g)
// method for finding a path in the maze given a graph g representing the maze
// uses a stack based DFS
{
    g.clearVisit();
    g.clearMark();
    int start = getMap(0, 0);
    int end = getMap(numRows() - 1, numCols() - 1);
    vector< stack<int> > rpaths = nonRecursiveDFS(start, end, g);
    stack<int> reverse_path;

    for(int i = 0; i < rpaths.size(); i++)
        if (rpaths[i].size() > reverse_path.size())
            reverse_path = rpaths[i];

    stack<int> path;

    while (!reverse_path.empty())
    {
        int top = reverse_path.top();
        reverse_path.pop();
        if (g.isVisited(top))
        {
            path.push(top);
        }
    }

    printPath(path);
}
示例#25
0
文件: p6b.cpp 项目: mossberg/eece3326
bool dfsCyclic(graph &g, int current, int prev)
// depth first search to find cycles in graph
// first removes the preceeding node from vector of neighbors
// then if there is a visited node neighbor, there is a cycle
// returns true for there is a cycle, otherwise false
{
    g.visit(current);
    vector<int> neighbors = getNeighbors(g, current);

    // remove prev from neighbors
    // make sure neighbors is not empty so we dont erase from empty vector
    if (prev != NONE && !neighbors.empty())
    {
        int index = 0;
        for (int k = 0; k < (int) neighbors.size(); k++)
        {
            if (neighbors[k] == prev)
                index = k;
        }

        // at some index, it is the (index + 1)th element
        // so just have to do .begin() + index
        neighbors.erase(neighbors.begin() + index);
    }

    for (int i = 0; i < (int) neighbors.size(); i++)
    {
        if (g.isVisited(neighbors[i]))
            return true;
        else if (dfsCyclic(g, neighbors[i], current))
            return true;
    }
    return false; // ran through all neighbors and no cycles
}
示例#26
0
int dijkstra(const graph &g, int src, int forbidden, const vi &costTable, 
    int limitation) {
  pq queue;
  queue.push(make_pair(0, src));

  vi output(g.size());
  fill(output.begin(), output.end(), INF);
  while (!queue.empty() && output[g.size()-1] == INF) {
    pii p = queue.top();
    queue.pop();
    int cost = p.first;
    int index = p.second;
    if (output[index] != INF) {
      continue;
    }
    output[index] = cost;
    for (int i = 0; i < g[index].size(); i++) {
      int nextIndex = g[index][i];
      if (output[nextIndex] != INF) {
        continue;
      }
      if (index == src && nextIndex == forbidden) {
        continue;
      }
      if (cost+1+costTable[nextIndex] > limitation) {
        continue;
      }
      queue.push(make_pair(cost+1, nextIndex));
    }
  }
  return output[g.size()-1];
}
示例#27
0
void mst::prim(graph g) {
    int num = g.num_of_vertices();
    minheap* candidates = new minheap(num);
    reset();

    // find the starting point and initialize the heap
    int start_node = 0;
    while(candidates->size() == 0) {
        for(int i=0; i<num; ++i) {
            float c = g.cost(start_node, i);
            if (c != 0) candidates->update(c, i);
        }
        ++start_node;
    }
    closed_set.insert(start_node-1);

    while (candidates->size()!=0) {
        heapitem t = candidates->pop();
        int node = t.get_node();
        // not record the duplicated probed nodes
        if (closed_set.find(node)!=closed_set.end())
            continue;
        closed_set.insert(node);
        path_cost += t.get_key();
        vector<int> n = g.neighbors(node);
        // update the heap with newly found nodes and edges
        for(vector<int>::iterator i=n.begin(); i!=n.end(); ++i) {
            candidates->update(g.cost(node,*i), *i);
        }
    }
    // ckeck if there are isolated nodes
    if (closed_set.size() < num-1) path_cost=-1;
}
示例#28
0
void Foam::gnuplotGraph::write(const graph& g, Ostream& os) const
{
    os  << "#set term postscript color" << endl
        << "set output \"" << word(g.title()) << ".ps\"" << endl
        << "set title " << g.title() << " 0,0" << endl << "show title" << endl
        << "set xlabel " << g.xName() << " 0,0" << endl << "show xlabel" << endl
        << "set ylabel " << g.yName() << " 0,0" << endl << "show ylabel" << endl
        << "plot";

    bool firstField = true;

    forAllConstIter(graph, g, iter)
    {
        if (!firstField)
        {
            os << ',';
        }
        firstField = false;

        os  << "'-' title " << iter()->name() << " with lines";
    }
    os << "; pause -1" << endl;


    forAllConstIter(graph, g, iter)
    {
        os  << endl;
        writeXY(g.x(), *iter(), os);
    }
示例#29
0
/*
 * Given a graph and a decomposition, this checks whether or not each edge is
 * contained in at least one bag.  This has the side effect of removing from the
 * graph all those edges of the graph that are in fact contained in some bag.
 * The emptiness of the edge set of the resulting pruned graph is used to decide
 * whether the decomposition has this property.
 */
bool check_edge_coverage(tree_decomposition& T, graph& g)
{
  std::vector<std::pair<unsigned,unsigned> > to_remove;
  /*
   * We go through all bags, and for each vertex in each bag, we remove all its
   * incident edges.  If all the edges are indeed covered by at least one bag,
   * this will leave the graph with an empty edge-set, and it won't if they
   * aren't.
   */
  for(unsigned i = 0; i < T.bags.size() && g.num_edges > 0; i++){
    std::set<unsigned>& it_bag = T.get_bag(i);
    for (std::set<unsigned>::iterator head = it_bag.begin(); head != it_bag.end(); head++) {
      for(auto tail = g.neighbors(*head-1).begin(); tail != g.neighbors(*head-1).end(); tail++) {
        if(it_bag.find(*tail+1) != it_bag.end()) {
          to_remove.push_back(std::pair<unsigned, unsigned>(*head,*tail));
        }
      }
      for (std::vector<std::pair<unsigned, unsigned> >::iterator rem_it = to_remove.begin(); rem_it != to_remove.end(); rem_it++) {
        g.remove_edge(rem_it->first-1,rem_it->second);
      }
      to_remove.clear();
    }
  }

  return (g.num_edges == 0);
}
示例#30
0
unsigned int quality_exp::solve_instance(graph<int> &g1, graph<int> &g2) {
    graph<int>* large_graph, * small_graph;

    if (g1.n() <= g2.n()) {
        small_graph = &g1;
        large_graph = &g2;
    }
    else {
        small_graph = &g2;
        large_graph = &g1;
    }

    graph<pair<int, int>>* start_point = solve_greedy(*small_graph, *large_graph);
    solution_graph_ptr = solve_tabu(*small_graph,       // graph<int>& g1,
                                    *large_graph,       // graph<int>& g2,
                                    *start_point,       // graph<pair<int, int>>& start_point,
                                    1,                  // int neighbourhood_type,
                                    60,                  // unsigned int tabu_list_size,
                                    2000,                  // int iteration_limit,
                                    0.01,                // float neighbourhood_proportion,
                                    true,               // bool strict_comparisons,
                                    800,                  // int no_gain_iteration_limit,
                                    0.5,                // float edges_vs_time,
                                    0.1,                  // float time_delta,
                                    0.3);                 // float aspiration_threshold

    delete start_point;

    return solution_graph_ptr->m();
}