Example #1
0
/************************************************************************

  Expands the single multi path into all possible sequence variants.
  Since this turns out to be the time-limiting process for long de nvoo,
  this is implemented using a quick branch and bound that works on
  edge variant indices. The SeqPaths are created only for the final
  set of sequences.

*************************************************************************/
void PrmGraph::fast_expand_multi_path(const MultiPath& multi_path, 
									  vector<SeqPath>& seq_paths,
									  score_t min_score,
									  score_t forbidden_pair_penalty,
									  int max_num_paths) const
{
	const vector<AA_combo>& aa_edge_comobos = config->get_aa_edge_combos();
	vector<score_t> max_attainable_scores;

	const int num_edges = multi_path.edge_idxs.size();
	max_attainable_scores.resize(num_edges+1,0);
	
	int num_path_variants=1;
	int e;
	for (e=num_edges-1; e>=0; e--)
	{
		const int e_idx = multi_path.edge_idxs[e];
		const MultiEdge& edge = multi_edges[e_idx];

		max_attainable_scores[e]= max_attainable_scores[e+1] + 
			edge.max_variant_score + edge.c_break->score; 
		num_path_variants *= edge.variant_ptrs.size();
	}

	const score_t max_path_score =  multi_edges[multi_path.edge_idxs[0]].n_break->score + 
									max_attainable_scores[0];
	const score_t min_delta_allowed = min_score - max_path_score;

	if (min_delta_allowed>0)
		return; // this multipath won't help much

	if (num_path_variants == 0)
	{
		cout << "Error: had an edge with 0 variants!" <<endl;
		exit(1);
	}

	// perform expansion using a heap and condensed path representation
	vector<int> var_positions;				   // holds the edge idxs
	vector<int> num_vars;
	vector<int> var_edge_positions;
	vector< vector< score_t > > var_scores;
	var_scores.clear();
	var_positions.clear();
	num_vars.clear();
	int num_aas_in_multipath = 0;
	for (e=0; e<num_edges; e++)
	{
		const int e_idx = multi_path.edge_idxs[e];
		const MultiEdge& edge = multi_edges[e_idx];
		const int num_vars_in_edge = edge.variant_ptrs.size();
		vector<score_t> scores;

		num_aas_in_multipath+=edge.num_aa;

		if (num_vars_in_edge>1)
		{
			int i;
			for (i=0; i<num_vars_in_edge; i++)
				scores.push_back(edge.variant_scores[i]);
		
			var_scores.push_back(scores);
			var_positions.push_back(e);
			num_vars.push_back(num_vars_in_edge);
			var_edge_positions.push_back(num_aas_in_multipath-edge.num_aa);

		//	cout << e << "\t" << e_idx << "\t" << num_vars_in_edge << "\t" << edge.num_aa << endl;
		}	
	}

		// create the SeqPaths from the edge_combos...
	const int num_positions = num_aas_in_multipath+1;
	SeqPath template_path;				// holds common elements to all paths
	template_path.n_term_aa = multi_path.n_term_aa;
	template_path.c_term_aa = multi_path.c_term_aa;
	template_path.n_term_mass = multi_path.n_term_mass;
	template_path.c_term_mass = multi_path.c_term_mass;
	template_path.multi_path_rank = multi_path.original_rank;
	template_path.path_score = 0;
	template_path.prm_ptr = (PrmGraph *)this;
	template_path.positions.clear();
	template_path.positions.resize(num_positions);

	template_path.num_forbidden_nodes = multi_path.num_forbidden_nodes;
	template_path.path_score -= template_path.num_forbidden_nodes * forbidden_pair_penalty;

	int pos_idx=0;
	for (e=0; e<multi_path.edge_idxs.size(); e++)
	{
		const int e_idx = multi_path.edge_idxs[e];
		const MultiEdge& edge = get_multi_edge(e_idx);
		PathPos& pos = template_path.positions[pos_idx++];

		pos.breakage = edge.n_break;
		pos.edge_idx = e_idx;
		pos.mass =  edge.n_break->mass;
		pos.node_score = edge.n_break->score;
		pos.node_idx = edge.n_idx;
		template_path.path_score += pos.node_score;

		int *variant_ptr = edge.variant_ptrs[0];
		const int num_aa = *variant_ptr++;
		int *aas = variant_ptr;

		if (edge.variant_ptrs.size() == 1)
		{
			pos.edge_variant_score = edge.variant_scores[0];
			pos.aa = aas[0];
			template_path.path_score += pos.edge_variant_score;
		}

		if (edge.num_aa == 1)
			continue;
		
		int j;
		for (j=1; j<edge.num_aa; j++)
		{
			PathPos& pos = template_path.positions[pos_idx++];
			pos.breakage = NULL;
			pos.aa = aas[j];
		}
	}

	if (pos_idx != num_aas_in_multipath)
	{
		cout << "Error: mismatches between positions and multipath length!" << endl;
		exit(1);
	}
	
	PathPos& last_pos = template_path.positions[num_positions-1];
	const int last_e_idx = multi_path.edge_idxs[e-1];
	const MultiEdge& last_edge = get_multi_edge(last_e_idx);
	last_pos.breakage = last_edge.c_break;
	last_pos.edge_idx =-1;
	last_pos.mass = last_edge.c_break->mass;
	last_pos.node_idx = last_edge.c_idx;
	last_pos.node_score = last_edge.c_break->score;

	template_path.path_score += last_pos.node_score;

	const int num_multi_var_edges = var_positions.size();
	if (num_multi_var_edges == 0)
	{
		seq_paths.resize(1);
		seq_paths[0]=template_path;
		return;
	}

	vector<var_combo>      combo_heap;
	vector<int> idxs;
	idxs.resize(num_multi_var_edges,0);
	const int last_var_pos = num_multi_var_edges-1;
	const int last_var_val = num_vars[last_var_pos];
	const score_t needed_var_score = min_score - template_path.path_score;
	while (1)
	{
		score_t idxs_score = 0;
		int k;
		for (k=0; k<idxs.size(); k++)
			idxs_score += var_scores[k][idxs[k]];
		
		if (idxs_score>=needed_var_score)
		{
			if (combo_heap.size()<max_num_paths)
			{
				var_combo v;
				v.path_score = template_path.path_score + idxs_score;
				v.var_idxs = idxs;
				combo_heap.push_back(v);
				if (combo_heap.size()== max_num_paths)
					make_heap(combo_heap.begin(),combo_heap.end());
			}
			else
			{
				const score_t score = template_path.path_score + idxs_score;
				if (score>combo_heap[0].path_score)
				{
					pop_heap(combo_heap.begin(),combo_heap.end());
					combo_heap[max_num_paths-1].path_score = score;
					combo_heap[max_num_paths-1].var_idxs = idxs;
					push_heap(combo_heap.begin(),combo_heap.end());
				}
			}	
		}

		int j=0;
		while (j<num_multi_var_edges)
		{
			idxs[j]++;
			if (idxs[j]==num_vars[j])
			{
				idxs[j++]=0;
			}
			else
				break;
		}
		if (j==num_multi_var_edges)
			break;

	}

	seq_paths.clear();
	seq_paths.resize(combo_heap.size(),template_path);

	int i;
	for (i=0; i<combo_heap.size(); i++)
	{
		const var_combo& combo  = combo_heap[i];
		SeqPath& seq_path = seq_paths[i];

		// fill in info that changes with multi-variant edges
		int j;
		for (j=0; j<num_multi_var_edges; j++)
		{
			const int var_pos = var_positions[j];
			const int e_idx = multi_path.edge_idxs[var_pos];
			const MultiEdge& edge = get_multi_edge(e_idx);

			const int pos_idx = var_edge_positions[j];
		
			if (seq_path.positions[pos_idx].edge_idx !=  e_idx)
			{
				cout << "POS: " << pos_idx << endl;
				cout << "Error: mismatch in pos_idx and e_idx of a multipath!" << endl;
				cout << "looking for " << e_idx << endl;
				cout << "edge idxs:" << endl;
				int k;
				for (k=0; k<seq_path.positions.size(); k++)
					cout << k << "\t" << seq_path.positions[k].edge_idx << "\tnidx: " <<
					seq_path.positions[k].node_idx << endl;
				cout << endl;
				multi_path.print(config);

				this->print();

				exit(1);
			}

			PathPos& pos = seq_path.positions[pos_idx];
			const int variant_idx = combo.var_idxs[j];
			int *variant_ptr = edge.variant_ptrs[variant_idx];
			const int num_aa = *variant_ptr++;
			int *aas = variant_ptr;

			if (num_aa != edge.num_aa)
			{
				cout << "Error: edge and variant mixup!" << endl;
				exit(1);
			}

			pos.edge_variant_score = edge.variant_scores[variant_idx];
			pos.aa = aas[0];
		//	pos.edge_var_idx = variant_idx;

			if (edge.num_aa == 1)
				continue;

			int k;
			for (k=1; k<edge.num_aa; k++)
			{
				PathPos& pos = seq_path.positions[pos_idx+k];
				pos.aa = aas[k];
			}
		}

		//seq_path.path_score = max_path_score + combo.path_delta;
		seq_path.path_score=combo.path_score;
		seq_path.make_seq_str(config);
	}
}
Example #2
0
/************************************************************************

  Expands the single multi path into all possible sequence variants.
  Since this turns out to be the time-limiting process for long de nvoo,
  this is implemented using a quick branch and bound that works on
  edge variant indices. The SeqPaths are created only for the final
  set of sequences.

*************************************************************************/
void PrmGraph::fast_expand_multi_path_for_combo_scores(
									  AllScoreModels *model,
									  const MultiPath& multi_path, 
									  vector<SeqPath>& seq_paths,
									  score_t min_score,
									  score_t forbidden_pair_penalty,
									  int max_num_paths)
{
	const vector<AA_combo>& aa_edge_comobos = config->get_aa_edge_combos();
	vector<score_t> max_attainable_scores;

	const int num_edges = multi_path.edge_idxs.size();
	max_attainable_scores.resize(num_edges+1,0);
	
	int num_path_variants=1;
	int e;
	for (e=num_edges-1; e<num_edges; e++)
	{
		const int e_idx = multi_path.edge_idxs[e];
		const MultiEdge& edge = multi_edges[e_idx];
		num_path_variants *= edge.variant_ptrs.size();
	}


	if (num_path_variants == 0)
	{
		cout << "Error: had an edge with 0 variants!" <<endl;
		exit(1);
	}

	// re-check the max attainable scores, this time compute all combo scores along the path
	// this will give a more accurate max attainable score, and also allow quick computation
	// of the expanded scores

	max_attainable_scores.clear();
	max_attainable_scores.resize(num_edges+1,0);
	vector<score_t> max_node_scores;
	max_node_scores.resize(num_edges+1,NEG_INF);

	for (e=0; e<=num_edges; e++)
	{
		const int n_edge_idx = (e>0 ? multi_path.edge_idxs[e-1] : -1);
		const int c_edge_idx = (e<num_edges ? multi_path.edge_idxs[e] : -1);
		const int node_idx = (n_edge_idx>=0 ? multi_edges[n_edge_idx].c_idx : multi_edges[c_edge_idx].n_idx);
		const int num_n_vars = (e>0 ? multi_edges[n_edge_idx].variant_ptrs.size() : 1);
		const int num_c_vars = (e<num_edges ? multi_edges[c_edge_idx].variant_ptrs.size() : 1);

		int j,k;
		for (j=0; j<num_n_vars; j++)
			for (k=0; k<num_c_vars; k++)
			{
				score_t combo_score = model->get_node_combo_score(this,node_idx,n_edge_idx,j,c_edge_idx,k);
				if (max_node_scores[e]<combo_score)
					max_node_scores[e]=combo_score;
			}
	}

	max_attainable_scores[num_edges]=max_node_scores[num_edges];
	for (e=num_edges-1; e>=0; e--)
	{
		const int e_idx = multi_path.edge_idxs[e];
		const MultiEdge& edge = multi_edges[e_idx];

		max_attainable_scores[e]= max_attainable_scores[e+1] + 
			edge.max_variant_score + max_node_scores[e]; 
	}
	score_t max_path_score =  max_attainable_scores[0] - multi_path.num_forbidden_nodes * forbidden_pair_penalty;
	score_t min_delta_allowed = min_score - max_path_score;

	if (min_delta_allowed>0)
		return;

	// in this expansion method, all edges are stored (not only ones with more than one variant)
	// perform expansion using a heap and condensed path representation
	vector<int> var_positions;				   // holds the edge idxs
	vector<int> num_vars;
	vector<int> var_edge_positions;
	vector< vector< score_t > > var_scores;
	var_scores.clear();
	var_positions.clear();
	num_vars.clear();

	int num_aas_in_multipath = 0;
	for (e=0; e<num_edges; e++)
	{
		const int e_idx = multi_path.edge_idxs[e];
		const MultiEdge& edge = multi_edges[e_idx];
		const int num_vars_in_edge = edge.variant_ptrs.size();
		vector<score_t> scores;

		num_aas_in_multipath+=edge.num_aa;

		int i;
		for (i=0; i<num_vars_in_edge; i++)
			scores.push_back(edge.variant_scores[i]);
		
		var_scores.push_back(scores);
		var_positions.push_back(e);
		num_vars.push_back(num_vars_in_edge);
		var_edge_positions.push_back(num_aas_in_multipath-edge.num_aa);
	}

	// create the SeqPaths from the edge_combos...
	const int num_positions = num_aas_in_multipath+1;
	SeqPath template_path;				// holds common elements to all paths
	template_path.n_term_aa = multi_path.n_term_aa;
	template_path.c_term_aa = multi_path.c_term_aa;
	template_path.n_term_mass = multi_path.n_term_mass;
	template_path.c_term_mass = multi_path.c_term_mass;
	template_path.charge = charge;
	template_path.multi_path_rank = multi_path.original_rank;
	template_path.path_score = 0;
	template_path.prm_ptr = (PrmGraph *)this;
	template_path.positions.clear();
	template_path.positions.resize(num_positions);

	template_path.num_forbidden_nodes = multi_path.num_forbidden_nodes;
	template_path.path_score -= template_path.num_forbidden_nodes * forbidden_pair_penalty;

	int pos_idx=0;
	for (e=0; e<multi_path.edge_idxs.size(); e++)
	{
		const int e_idx = multi_path.edge_idxs[e];
		const MultiEdge& edge = get_multi_edge(e_idx);
		PathPos& pos = template_path.positions[pos_idx++];

		pos.breakage = edge.n_break;
		pos.edge_idx = e_idx;
		pos.mass =  edge.n_break->mass;
		pos.node_idx = edge.n_idx;
		
		int *variant_ptr = edge.variant_ptrs[0];
		const int num_aa = *variant_ptr++;
		int *aas = variant_ptr;

		if (edge.variant_ptrs.size() == 1)
		{
			pos.variant_ptr = edge.variant_ptrs[0];
			pos.edge_variant_score = edge.variant_scores[0];
			pos.aa = aas[0];
		}

		if (edge.num_aa == 1)
			continue;
		
		int j;
		for (j=1; j<edge.num_aa; j++)
		{
			PathPos& pos = template_path.positions[pos_idx++];
			pos.breakage = NULL;
			pos.aa = aas[j];
		}
	}

	if (pos_idx != num_aas_in_multipath)
	{
		cout << "Error: mismatches between positions and multipath length!" << endl;
		exit(1);
	}
	
	PathPos& last_pos = template_path.positions[num_positions-1];
	const int last_e_idx = multi_path.edge_idxs[e-1];
	const MultiEdge& last_edge = get_multi_edge(last_e_idx);
	last_pos.breakage = last_edge.c_break;
	last_pos.edge_idx =-1;
	last_pos.mass = last_edge.c_break->mass;
	last_pos.node_idx = last_edge.c_idx;
	

	const int num_multi_var_edges = var_positions.size();
	
	vector<var_combo>      combo_heap;
	vector<int> var_idxs;
	var_idxs.resize(num_multi_var_edges,0);
	const int last_var_pos = num_multi_var_edges-1;
	const int last_var_val = num_vars[last_var_pos];
	const score_t needed_var_score = min_score; // this is only the penalty for forbidden pairs
	while (1)
	{
		score_t idxs_score = 0;
		int k;
		for (k=0; k<var_idxs.size(); k++)
			idxs_score += var_scores[k][var_idxs[k]]; // this is the score for the edge variants (usually 0) 
		
		const vector<PathPos>& positions = template_path.positions;
		score_t path_score = idxs_score + template_path.path_score;
		
		// compute the node scores based on the edge variants
		// N-term node score
		vector<score_t> node_scores;
		node_scores.resize(var_idxs.size()+1,NEG_INF);

		node_scores[0] = model->get_node_combo_score(this,positions[0].node_idx,-1,0,
													positions[0].edge_idx,var_idxs[0]);
		path_score += node_scores[0];
		// middle nodes score
		int prev_edge_idx = positions[0].edge_idx;
		for (k=1; k<var_idxs.size(); k++)
		{
			const int p=var_edge_positions[k];
			const PathPos& pos = positions[p];
			node_scores[k] = model->get_node_combo_score(this,pos.node_idx,prev_edge_idx,var_idxs[k-1],
													pos.edge_idx,var_idxs[k]);
			path_score += node_scores[k];
			prev_edge_idx = pos.edge_idx;
		}

		// C-term node score
		node_scores[k] = model->get_node_combo_score(this,last_pos.node_idx,prev_edge_idx,var_idxs[k-1],-1,0);

		path_score += node_scores[k];
		
		if (path_score>=needed_var_score)
		{
			if (combo_heap.size()<max_num_paths)
			{
				var_combo v;
				v.path_score  = path_score;
				v.var_idxs    = var_idxs;
				v.node_scores = node_scores;
				combo_heap.push_back(v);
				if (combo_heap.size()== max_num_paths)
					make_heap(combo_heap.begin(),combo_heap.end());
			}
			else
			{
				const score_t score = path_score;
				if (score>combo_heap[0].path_score)
				{
					pop_heap(combo_heap.begin(),combo_heap.end());
					var_combo& combo  = combo_heap[max_num_paths-1];
					combo.path_score  = path_score;
					combo.var_idxs    = var_idxs;
					combo.node_scores = node_scores;
					push_heap(combo_heap.begin(),combo_heap.end());
				}
			}	
		}

		int j=0;
		while (j<num_multi_var_edges)
		{
			var_idxs[j]++;
			if (var_idxs[j]==num_vars[j])
			{
				var_idxs[j++]=0;
			}
			else
				break;
		}
		if (j==num_multi_var_edges)
			break;

	}


	seq_paths.clear();
	seq_paths.resize(combo_heap.size(),template_path);

	int i;
	for (i=0; i<combo_heap.size(); i++)
	{
		const var_combo& combo  = combo_heap[i];
		SeqPath& seq_path = seq_paths[i];

		// fill in info that changes with multi-variant edges
		int j;
		for (j=0; j<num_multi_var_edges; j++)
		{
			const int var_pos = var_positions[j];
			const int e_idx = multi_path.edge_idxs[var_pos];
			const MultiEdge& edge = get_multi_edge(e_idx);

			const int pos_idx = var_edge_positions[j];
		
			if (seq_path.positions[pos_idx].edge_idx !=  e_idx)
			{
				cout << "POS: " << pos_idx << endl;
				cout << "Error: mismatch in pos_idx and e_idx of a multipath!" << endl;
				cout << "looking for " << e_idx << endl;
				cout << "edge idxs:" << endl;
				int k;
				for (k=0; k<seq_path.positions.size(); k++)
					cout << k << "\t" << seq_path.positions[k].edge_idx << "\tnidx: " <<
					seq_path.positions[k].node_idx << endl;
				cout << endl;
				multi_path.print(config);

				this->print();

				exit(1);
			}

			PathPos& pos = seq_path.positions[pos_idx];
			const int variant_idx = combo.var_idxs[j];
			int *variant_ptr = edge.variant_ptrs[variant_idx];
			const int num_aa = *variant_ptr++;
			int *aas = variant_ptr;

			if (num_aa != edge.num_aa)
			{
				cout << "Error: edge and variant mixup!" << endl;
				exit(1);
			}

			pos.node_score = combo.node_scores[j];
			pos.edge_variant_score = edge.variant_scores[variant_idx];
			pos.variant_ptr = edge.variant_ptrs[variant_idx];
			pos.aa = aas[0];
	
			if (edge.num_aa == 1)
				continue;

			int k;
			for (k=1; k<edge.num_aa; k++)
			{
				PathPos& pos = seq_path.positions[pos_idx+k];
				pos.aa = aas[k];
			}
		}

		seq_path.positions[seq_path.positions.size()-1].node_score = combo.node_scores[num_multi_var_edges];
		seq_path.path_score=combo.path_score;
		float pen = seq_path.adjust_complete_sequence_penalty(this);

		seq_path.make_seq_str(config);
	}
}
Example #3
0
vector<int> maOrderingHeap(const vector<SplitEdge> &g, int s)
{
	vector<pair<int, int>> heap; //fst is key/incidence, snd is node ind (matched in MACompare)
	int addOne = cG(s, g) == 0 ? 1 : 0;
	int maxNodeInd = 0;
	for (unsigned i = 0; i < g.size(); i++)
		maxNodeInd = max(g[i].end0, max(g[i].end1, maxNodeInd));
	maxNodeInd++;
	vector<bool> usedNodes(maxNodeInd, false);
	for (unsigned i = 0; i < g.size(); i++)
	{
		usedNodes[g[i].end0] = true;
		usedNodes[g[i].end1] = true;
	}
	int numNodes = 0;
	for (unsigned i = 0; i < usedNodes.size(); i++)
		numNodes += usedNodes[i];
	vector<int> ordering;
	vector<bool> inOrdering(maxNodeInd, false);
	ordering.push_back(s);
	inOrdering[s] = true;

	vector<vector<pair<int, int>>> adjacency;
	adjacency.reserve(maxNodeInd);
	for (int i = 0; i < maxNodeInd; i++)
		adjacency.push_back(vector<pair<int, int>>());
	for (unsigned i = 0; i < g.size(); i++)
	{
		adjacency[g[i].end0].push_back(pair<int, int>(g[i].end1, g[i].weight));
		adjacency[g[i].end1].push_back(pair<int, int>(g[i].end0, g[i].weight));
	}

	heap.reserve(maxNodeInd);
	for (int i = 0; i < maxNodeInd; i++)
		heap.push_back(pair<int, int>(0, i));

	for (unsigned i = 0; i < g.size(); i++)
	{
		if (g[i].end0 == s)
			heap[g[i].end1].first += g[i].weight;
		else if (g[i].end1 == s)
			heap[g[i].end0].first += g[i].weight;
	}
	vector<int>realValue;
	for (unsigned i = 0; i < heap.size(); i++)
		realValue.push_back(heap[i].first);
	make_heap(heap.begin(), heap.end(), MACompare());
	while (ordering.size() != numNodes + addOne)
	{
		pair<int, int> next = heap.front();
		pop_heap(heap.begin(), heap.end());
		heap.pop_back();

		while (realValue[next.second] != next.first || inOrdering[next.second] || !usedNodes[next.second]) //i.e. this value was changed.
		{
			next = heap.front();
			pop_heap(heap.begin(), heap.end());
			heap.pop_back();
		}

		ordering.push_back(next.second);
		inOrdering[next.second] = true;

		for (unsigned i = 0; i < adjacency[next.second].size(); i++)
		{
			int n = adjacency[next.second][i].first;
			if (!inOrdering[n])
			{
				realValue[n] += adjacency[next.second][i].second;
				pair<int, int> p(realValue[n], n);
				heap.push_back(p);
				push_heap(heap.begin(), heap.end());
			}
		}
	}
	//verifyMAOrdering(g, ordering);
	return ordering;
}
Example #4
0
std::vector<int> Pathfinder::getPathFrom(int start) const
{
    if (goal_(start)) return {start};

    // Record shortest path costs for every node we examine.
    std::unordered_map<int, AstarNodePtr> nodes;
    // Maintain a heap of nodes to consider.
    std::vector<int> open;
    int goalLoc = -1;
    AstarNodePtr goalNode;

    // The heap functions confusingly use operator< to build a heap with the
    // *largest* element on top.  We want to get the node with the *least* cost,
    // so we have to order nodes in the opposite way.
    auto orderByCost = [&] (int lhs, int rhs)
    {
        return nodes[lhs]->estTotalCost > nodes[rhs]->estTotalCost;
    };

    nodes.emplace(start, make_astar_node(-1, 0, 0));
    open.push_back(start);

    // A* algorithm.  Decays to Dijkstra's if estimate function is always 0.
    while (!open.empty()) {
        auto loc = open.front();
        pop_heap(std::begin(open), std::end(open), orderByCost);
        open.pop_back();
        if (goal_(loc)) {
            goalLoc = loc;
            goalNode = nodes[loc];
            break;
        }

        auto &curNode = nodes[loc];
        curNode->visited = true;
        for (auto n : neighbors_(loc)) {
            auto nIter = nodes.find(n);
            auto step = stepCost_(loc, n);

            if (nIter != nodes.end()) {
                auto &nNode = nIter->second;
                if (nNode->visited) {
                    continue;
                }

                // Are we on a shorter path to the neighbor node than what
                // we've already seen?  If so, update the neighbor's node data.
                if (curNode->costSoFar + step < nNode->costSoFar) {
                    nNode->prev = loc;
                    nNode->costSoFar = curNode->costSoFar + step;
                    nNode->estTotalCost = nNode->costSoFar + estimate_(n);
                    make_heap(std::begin(open), std::end(open), orderByCost);
                }
            }
            else {
                // We haven't seen this node before.  Add it to the open list.
                nodes.emplace(n, make_astar_node(loc, curNode->costSoFar + step, 
                    curNode->costSoFar + step + estimate_(n)));
                open.push_back(n);
                push_heap(std::begin(open), std::end(open), orderByCost);
            }
        }
    }

    if (!goalNode) {
        return {};
    }

    // Build the path from the chain of nodes leading to the goal.
    std::vector<int> path = {goalLoc};
    auto n = goalNode;
    while (n->prev != -1) {
        path.push_back(n->prev);
        n = nodes[n->prev];
    }
    reverse(std::begin(path), std::end(path));
    assert(contains(path, start));
    return path;
}
Example #5
0
void SortAlgorithm::mergeNShortest(int n)
{
  assert(n>1);
  assert((int)runs.size() > 1);
  assert((int)runs.size() >= n);

  Tuple* t;
  int counter = 0;

  SortedRunCompareLengthGreater comp;

  // sort the runs according to their length in bytes
  // a minimum heap is created
  make_heap(runs.begin(), runs.end(), comp);

  // get the n shortest runs
  vector<SortedRun*> merge;

  for (int i = 0; i < n; i++)
  {
    // pops first array element and moves it to the end of the array
    // the heap condition is fullfilled afterwards
    pop_heap(runs.begin(), runs.end(), comp);

    // add the popped run to the merge array
    merge.push_back(runs.back());

    // delete run from runs array
    runs.pop_back();
  }

  // create the sorted run for merging
  SortedRun* result = new SortedRun( nextRunNumber++, attributes,
                                     spec, IO_BUFFER_SIZE );

  // append the sorted run to the end of the runs array
  runs.push_back(result);

  if ( traceModeExtended )
  {
    cmsg.info() << HLINE << endl
                << "Intermediate merge phase into Run "
                << result->GetRunNumber() << " with "
                << n << " runs." << endl;
  }

  // Get first tuple from each run and push it into the merge heap.
  for( size_t i = 0; i < merge.size(); i++ )
  {
    if( ( t = merge[i]->GetNextTuple() ) != 0 )
    {
      mergeQueue->Push(t,i);
    }

    if ( traceModeExtended )
    {
      cmsg.info() << merge[i]->GetRunNumber() << ": "
                  << "RunLength: " << merge[i]->GetRunLength() / 1024
                  << " (KBytes), Tuples: " << merge[i]->GetTupleCount() << endl;
    }
  }

  // merge runs
  while ( ( t = this->nextResultTuple(merge) ) != 0 )
  {
    result->AppendToDisk(t);

    progress->intTuplesProc++;

    // Check after a certain amount of tuples if a progress message is necessary
    // If we don't do this progress will freeze, because the query processors
    // eval method isn't called
    if ( ( counter++ % checkProgressAfter ) == 0)
    {
      qp->CheckProgress();
    }
  }

  // delete merged runs
  for ( size_t i = 0; i < merge.size(); i++)
  {
    if ( traceModeExtended )
    {
      cmsg.info() << "Deleting Run " << merge[i]->GetRunNumber() << endl;
      cmsg.send();
    }

    delete merge[i];
  }
  merge.clear();

  return;
}
Example #6
0
	void Mst::find(){

		// define priority queue (based on vector)
		std::vector<Vertex*> que;

		// define processed set
		std::unordered_set<int> processed;

		// set source's key = 0
		v[s]->setKey(0);

		// enqueue all vertices into queue
		for(int i=1;i<=v.size();i++){

			que.push_back(v[i]);
		}

		std::make_heap(que.begin(),que.end(), quecomp());

		// Repeat while	queue is not empty

		while(!que.empty())	{

			// remove vertex from queue
			std::pop_heap(que.begin(),que.end(),quecomp());
			Vertex *u = que.back();
			que.pop_back();

			// put u in processed set
			processed.insert(u->getName());

			// for all vertices in adjacency list of u
			for(auto x: adj[u->getName()]){

				// if x is not processed
				if(processed.find((x->v)->getName()) == processed.end() ){

					// If x's key is greater than weight of edge (u,x), update x's key and parent
					if((x->v)->getKey() > x->weight ){

						(x->v)->setKey(x->weight);
						(x->v)->setParent(u->getName());


						// reheapify queue

						make_heap(que.begin(),que.end(),quecomp());

					}


				}

			}




		}	


	}
bool ompl::LTLVis::VRVPlanner::DijkstraSearch(const ompl::base::PlannerTerminationCondition &ptc, ompl::geometric::PathGeometric &solution)
{
  //update the value we use to check that a vertex has been initialized, or visited, in the current search
  ++crVisitation_;
  WorkingVertexVector pqueue;
  pqueue.clear();
  bool reachedGoal = false;
  bool goalDisconnected = false;

  ompl::LTLVis::tIndex goalIndexReached = 0;

  WorkingVertexVector pathCandidate;

  ompl::LTLVis::tIndex maxK = vertices_.size();
  for(ompl::LTLVis::tIndex k = 0; k < maxK; k++)
  {
    if(vertices_[k].getIsStart())
    {
      vertices_[k].setNegativeDistance(0);
      vertices_[k].setLastInitAlg(crVisitation_);
      pqueue.push_back(&vertices_[k]);
    }
  }
  make_heap(pqueue.begin(), pqueue.end(), VRVVertex::VRVVertexCompare);

  while(pqueue.size() && (ptc == false))
  {
    VRVVertex *cVertex(pqueue.front());
    pop_heap(pqueue.begin(), pqueue.end(), VRVVertex::VRVVertexCompare); pqueue.pop_back();

    if(cVertex->getLastVisitation() < crVisitation_)
    {
      cVertex->setLastVisitation(crVisitation_);
      if(cVertex->getIsGoal())
      {
        reachedGoal = true;
        goalIndexReached = cVertex->getIndex();
        break;
      }
      ompl::LTLVis::tIndex kMax = cVertex->getEdgeCount();
      for(ompl::LTLVis::tIndex k = 0; k < kMax; k++)
      {
        double weight;
        ompl::LTLVis::tIndex towards;
        cVertex->getEdge(k, weight, towards);
        VRVVertex *cTarget(&vertices_[towards]);
        if(cTarget->isInteresting())
        {
          //STL heap is a max heap, so we use negative edge weights to 'convert' it to a min-heap
          if(cTarget->getLastInitAlg() < crVisitation_)
          {
            cTarget->setLastInitAlg(crVisitation_);
            cTarget->setNegativeDistance(cVertex->getNegativeDistance() - weight - cTarget->getNodeCost());
            cTarget->setPreceding(cVertex->getIndex());
            cTarget->setPrecedingEdge(k);
            pqueue.push_back(cTarget); push_heap(pqueue.begin(), pqueue.end(), VRVVertex::VRVVertexCompare);
          }
          else
          {
            double negativeDist = cVertex->getNegativeDistance() - weight - cTarget->getNodeCost();
            if(negativeDist > cTarget->getNegativeDistance())
            {
              cTarget->setNegativeDistance(negativeDist);
              cTarget->setPreceding(cVertex->getIndex());
              cTarget->setPrecedingEdge(k);
              pqueue.push_back(cTarget); push_heap(pqueue.begin(), pqueue.end(), VRVVertex::VRVVertexCompare);
            }
          }
        }
      }
    }
  }

  if(reachedGoal)
  {
    pathCandidate.clear();
    ompl::LTLVis::tIndex cIndex = goalIndexReached;
    while(!vertices_[cIndex].getIsStart())
    {
      pathCandidate.push_back(&vertices_[cIndex]);
      cIndex = vertices_[cIndex].getPreceding();
    }
    pathCandidate.push_back(&vertices_[cIndex]);
    ompl::LTLVis::tIndex kMax = pathCandidate.size();
    for(ompl::LTLVis::tIndex k = 0, kPrev = 0; (k < kMax); k++)
    {
      if(0 < k)
      {
        if(0.000001 < si_->distance(pathCandidate[kMax - 1 - k]->getStateData(), pathCandidate[kMax - 1 - kPrev]->getStateData()))
        {
          solution.append(pathCandidate[kMax - 1 - k]->getStateData());
          kPrev = k;
        }
      }
      else
      {
        solution.append(pathCandidate[kMax - 1 - k]->getStateData());
      }
    }
    return true;
  }
  return false;
}
Example #8
0
bool GridWorld::computeShortestPath(){
	if (open.empty()){
		std::cout << "ERROR: No tiles to expand on... can't do anything" << std::endl;
		return false;
	}

	double currentRHS, otherG, previousG;

	while (!open.empty() && (compareKeys(open.front()->key, start->key = calculateKey(start)) || start->rhs != start->g)){
		Tile* current = open.front();
		//Notice that CURRENT wasn't pop/removed yet..

		KeyPair k_old = current->key;
		KeyPair k_new = calculateKey(current);

		currentRHS = current->rhs;
		otherG = current->g;

		/*std::cout << "Expanding:";
		current->info();
		std::cout << std::endl;*/

		if (compareKeys(k_old, k_new)){
			//This branch updates tile that were already in the OPEN list originally
			//This branch tends to execute AFTER the else branch
			current->key = k_new;
			make_heap(open.begin(), open.end(), GridWorld::compareTiles);

		}
		else if (otherG > currentRHS){
			//Majority of the execution will fall under this conditional branch as
			//it is undergoing normal A* pathfinding

			current->g = current->rhs;
			otherG = currentRHS;

			open.erase(open.begin());
			make_heap(open.begin(), open.end(), GridWorld::compareTiles);
			current->isOpen = false;

			std::vector<Tile*> neighbours(getNeighbours(current));
			for (int i = 0; i < neighbours.size(); i++){
				if (neighbours[i] != 0){
					if (neighbours[i] != goal){
						neighbours[i]->rhs = std::min(neighbours[i]->rhs, calculateC(current, neighbours[i]) + otherG);
					}
					updateVertex(neighbours[i]);
				}
			}

		}
		else {
			//Execution of this branch updates the tile during incremental search

			previousG = otherG;
			current->g = PF_INFINITY;

			//Update CURRENT'S RHS
			if (current != goal){
				current->rhs = getMinSuccessor(current).second;
			}
			updateVertex(current);

			//Update NEIGHBOUR'S RHS to their minimum successor
			std::vector<Tile*> neighbours(getNeighbours(current));
			for (int i = 0; i < neighbours.size(); i++){
				if (neighbours[i] != 0){
					if (neighbours[i]->rhs == (calculateC(current, neighbours[i]) + previousG) && neighbours[i] != goal){
						neighbours[i]->rhs = getMinSuccessor(neighbours[i]).second;
					}
					updateVertex(neighbours[i]);
				}
			}

		}
		//Uncomment this to see CURRENT'S new values
		//std::cout << "Expanded:";
		//current->info();
		//std::cout << std::endl;
	}
	return true;
}
Example #9
0
	static void make_heap(const RandomAccessIterator &first,
		const RandomAccessIterator &last)
	{
		make_heap(first, last, _std_less_comparer<RandomAccessIterator>);
	}