void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
{
	// Verify input
	char* inputError = "Expected 4 parameters\n N - number of nodes\n from - 1xM vector of indices\n to - 1xM vector of indices\n weight - 1xM vector of edge weights\n Example: [value, matches] = lemon_maxweightedperfectmatching(n, from, to, weight);";
	
	if (nrhs != 4 ||  !mxIsNumeric(prhs[0]) || !mxIsNumeric(prhs[1]) || !mxIsNumeric(prhs[2]) || !mxIsNumeric(prhs[3]))
		mexErrMsgTxt(inputError);
	
	mwSize m = mxGetN(prhs[1]);
	double* x = mxGetPr(prhs[1]);
	double* y = mxGetPr(prhs[2]);
	double* w = mxGetPr(prhs[3]);
	mwSize n = (mwSize)mxGetScalar(prhs[0]);
	
	if (mxGetM(prhs[1]) != 1 || mxGetM(prhs[2]) != 1 || mxGetM(prhs[3]) != 1 || mxGetN(prhs[2]) != m || mxGetN(prhs[3]) != m)
		mexErrMsgTxt(inputError);
	
	// Read input
	SmartGraph g;
	g.reserveNode(n);
	g.reserveEdge(m);
	
	typedef SmartGraph::EdgeMap<double> EdgeMap;
	EdgeMap weight(g);
	
	for (mwIndex i = 0; i < n; i++)
		g.addNode();
	
	for (mwIndex i = 0; i < m; i++)
	{
		SmartGraph::Edge edge = g.addEdge(g.nodeFromId(x[i] - 1), g.nodeFromId(y[i] - 1));
		weight[edge] = w[i];
	}
	
	// Do stuff
	MaxWeightedPerfectMatching<SmartGraph, EdgeMap> mwpm(g, weight);
	mwpm.run();
	
	// Create output
	if (nlhs > 0)
	{
		plhs[0] = mxCreateDoubleMatrix(1, 1, mxREAL);
		double *value = mxGetPr(plhs[0]);
		value[0] = mwpm.matchingWeight();
	}
	if (nlhs > 1)
	{
		const SmartGraph::NodeMap<SmartGraph::Arc> &matchingMap = mwpm.matchingMap();
		plhs[1] = mxCreateDoubleMatrix(1, n, mxREAL);
		double *matches = mxGetPr(plhs[1]);
		for (mwIndex i = 0; i < n; i++)
		{
			SmartGraph::Arc arc = matchingMap[g.nodeFromId(i)];
			matches[i] = g.id(g.target(arc)) + 1;
		}
	}
	
	return;
}
示例#2
0
void writeEGDot(SmartGraph& g, SmartGraph::EdgeMap<double>& length,
		ostream& out, SmartGraph::NodeMap<IndexPair>& edgePairs,
		boost::unordered_set<unsigned>& matched)
{
	out << "graph name {" << endl;
	out << "  node [ shape=ellipse, fontname=Helvetica, fontsize=10 ];" << endl;
	for (SmartGraph::NodeIt n(g); n != INVALID; ++n)
	{
		IndexPair p = edgePairs[n];
		if(p.first != p.second)
			out << "  n" << g.id(n) << " [ label=\"" << p.first << ":" << p.second << "\" ]; " << endl;
		else
			out << "  n" << g.id(n) << " [ shape=triangle, label=\"" << p.first << "\" ]; \n";
	}
	out << "  edge [ shape=ellipse, fontname=Helvetica, fontsize=10 ];" << endl;
	for (SmartGraph::EdgeIt e(g); e != INVALID; ++e)
	{
		string extra = "";
		if(matched.count(g.id(e)))
			extra = "style = bold, ";
		out << "  n" << g.id(g.u(e)) << " -- " << " n" << g.id(g.v(e))
				<< " [ " << extra << "label=\"" << length[e] << "\" ]; " << endl;
	}
	out << "}" << endl;
}
示例#3
0
//write dot file from graph
void writeDot(SmartGraph& g, SmartGraph::EdgeMap<double>& length,
		SmartGraph::NodeMap<unsigned>& index,
		ostream& out)
{
	out << "graph name {" << endl;
	out << "  node [ shape=ellipse, fontname=Helvetica, fontsize=10 ];" << endl;
	for (SmartGraph::NodeIt n(g); n != INVALID; ++n)
	{
		out << "  n" << g.id(n) << " [ label=\"" << index[n] << "\" ]; " << endl;
	}
	out << "  edge [ shape=ellipse, fontname=Helvetica, fontsize=10 ];" << endl;
	for (SmartGraph::EdgeIt e(g); e != INVALID; ++e)
	{
		out << "  n" << g.id(g.u(e)) << " -- " << " n" << g.id(g.v(e))
				<< " [ label=\"" << length[e] << "\" ]; " << endl;
	}
	out << "}" << endl;

}
示例#4
0
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
{
	// Verify input
	char* inputError = "Expected 4 parameters\n N - number of nodes\n from - 1xM vector of indices\n to - 1xM vector of indices\n cost - 1xM vector of edge costs\n Example: [mst] = lemon_kruskal(n, from, to, cost);";
	
	if (nrhs != 4 ||  !mxIsNumeric(prhs[0]) || !mxIsNumeric(prhs[1]) || !mxIsNumeric(prhs[2]) || !mxIsNumeric(prhs[3]))
		mexErrMsgTxt(inputError);
	
	mwSize m = mxGetN(prhs[1]);
	double* x = mxGetPr(prhs[1]);
	double* y = mxGetPr(prhs[2]);
	double* c = mxGetPr(prhs[3]);
	mwSize n = (mwSize)mxGetScalar(prhs[0]);
	
	if (mxGetM(prhs[1]) != 1 || mxGetM(prhs[2]) != 1 || mxGetM(prhs[3]) != 1 || mxGetN(prhs[2]) != m || mxGetN(prhs[3]) != m)
		mexErrMsgTxt(inputError);
	
	// Read input
	SmartGraph g;
	g.reserveNode(n);
	g.reserveEdge(m);
	
	typedef SmartGraph::EdgeMap<double> EdgeMap;
	EdgeMap cost(g);
	
	for (mwIndex i = 0; i < n; i++)
		g.addNode();
	
	for (mwIndex i = 0; i < m; i++)
	{
		SmartGraph::Edge edge = g.addEdge(g.nodeFromId(x[i] - 1), g.nodeFromId(y[i] - 1));
		cost[edge] = c[i];
	}
	
	// Do stuff
	EdgeMap tree(g);
	kruskal(g, cost, tree);
	
	// Create output
	if (nlhs > 0)
	{
		plhs[0] = mxCreateLogicalMatrix(1, m);
		bool *mst = mxGetLogicals(plhs[0]);
		for (mwIndex i = 0; i < m; i++)
			mst[i] =  tree[g.edgeFromId(i)];
	}
	
	return;
}
示例#5
0
/* find the pseudo-optimal matching of every pair of clusters
 * use the knn graph instead of the full graph
 * maxSz is what the largest current cluster should be
 */
bool MatcherPacker::knnMergeClusters(const DataViewer *D,
		vector<Cluster>& clusters, unsigned maxSz, DCache& dcache) const
{
	unsigned N = clusters.size();
	SmartGraph SG;
	SmartGraph::EdgeMap<double> Sweights(SG);
	SmartGraph::NodeMap<unsigned> Sindex(SG);
	vector<SmartGraph::Node> Snodes;

	ClusterCache ccache(clusters.size());
	makeKNNGraph(D, clusters, maxSz, dcache, ccache, SG, Sweights, Sindex,
			Snodes);

	Timer t;
	MaxWeightedMatching<SmartGraph, SmartGraph::EdgeMap<double> > matcher(SG,
			Sweights);
	matcher.run();
	//merge clusters that were matched
	vector<Cluster> newclusters;
	newclusters.reserve(N / 2 + 1);
	vector<bool> packed(N, false);
	bool didmerge = false;
	for (unsigned i = 0; i < N; i++)
	{
		if (!packed[i])
		{
			SmartGraph::Node m = matcher.mate(Snodes[i]);
			if (!SG.valid(m))
			{
				newclusters.push_back(Cluster());
				newclusters.back().moveInto(clusters[i]);
			}
			else
			{
				unsigned j = Sindex[m];

				if (clusters[i].size() + clusters[j].size() <= packSize) //merge
				{
					newclusters.push_back(Cluster());
					newclusters.back().mergeInto(clusters[i], clusters[j]);
					didmerge = true;
					packed[i] = true;
					packed[j] = true;
				}
				else
				{
					//didn't merge, keep clusters as is
					newclusters.push_back(Cluster());
					newclusters.back().moveInto(clusters[i]);
					newclusters.push_back(Cluster());
					newclusters.back().moveInto(clusters[j]);
					packed[i] = true;
					packed[j] = true;
				}
			}
		}
	}

	swap(clusters, newclusters);
	return didmerge;
}