コード例 #1
0
/* call-seq:
 *    graph.decompose(mode,maxcomp=-1,minelem=1) -> Array
 * 
 * Create separate graph for each component of a graph. Returns an Array
 * of new IGraph object. mode specifies whether weakly and strongly connected 
 * components are returned. Right now only the former is implemented. maxcomp
 * limits the number of components returned. Leave at the default -1 to return
 * all components. minelements specifies the minimum number of vertices a
 * component should contain before it is returned. Default 1 returns all 
 * components.
 */
VALUE cIGraph_decompose(int argc, VALUE *argv, VALUE self){

  igraph_t *graph;
  igraph_t *n_graph;
  igraph_vector_ptr_t components;
  VALUE mode,maxcomp, minelem, components_a;
  VALUE n_graph_obj;
  int i;

  rb_scan_args(argc,argv,"12", &mode, &maxcomp, &minelem);

  if(maxcomp == Qnil)
    maxcomp = INT2NUM(-1);
  if(minelem == Qnil)
    minelem = INT2NUM(1);

  igraph_vector_ptr_init(&components,0);
  
  Data_Get_Struct(self, igraph_t, graph); 
  
  igraph_decompose(graph, &components, NUM2INT(mode), NUM2INT(maxcomp), NUM2INT(minelem));

  components_a = rb_ary_new();

  for(i=0; i<igraph_vector_ptr_size(&components); i++){
    n_graph = VECTOR(components)[i];
    n_graph_obj = Data_Wrap_Struct(cIGraph, cIGraph_mark, cIGraph_free, n_graph);
    rb_ary_push(components_a,n_graph_obj);
  } 

  igraph_vector_ptr_destroy(&components);

  return components_a;

}
コード例 #2
0
ファイル: LayoutBuilder.cpp プロジェクト: primotom/PeTe
void LayoutBuilder::produce(AbstractPetriNetBuilder *builder){
	if(!attrTableAttached){
		igraph_i_set_attribute_table(&igraph_cattribute_table);
		attrTableAttached = true;
	}
	size_t V = places.size() + transitions.size();
	size_t E = inArcs.size() + outArcs.size();
	igraph_t graph;
	// Create a directed graph
	igraph_empty(&graph, V, true);

	// Create vector with all edges
	igraph_vector_t edges;
	igraph_vector_init(&edges, E * 2);

	// Add edges to vector
	int i = 0;
	for(ArcIter it = inArcs.begin(); it != inArcs.end(); it++){
		VECTOR(edges)[i++] = numberFromName(it->start);
		VECTOR(edges)[i++] = numberFromName(it->end);
	}
	for(ArcIter it = outArcs.begin(); it != outArcs.end(); it++){
		VECTOR(edges)[i++] = numberFromName(it->start);
		VECTOR(edges)[i++] = numberFromName(it->end);
	}

	// Add the edges to graph
	igraph_add_edges(&graph, &edges, 0);

	// Delete the vector with edges
	igraph_vector_destroy(&edges);

	// Arrays to store result in
	double posx[V];
	double posy[V];

	// Provide current positions, if they're used at all
	if(startFromCurrentPositions){
		int i = 0;
		for(PlaceIter it = places.begin(); it != places.end(); it++){
			posx[i] = it->x;
			posy[i] = it->y;
			igraph_cattribute_VAN_set(&graph, "id", i, i);
			i++;
		}
		for(TransitionIter it = transitions.begin(); it != transitions.end(); it++){
			posx[i] = it->x;
			posy[i] = it->y;
			igraph_cattribute_VAN_set(&graph, "id", i, i);
			i++;
		}
	}

	// Decompose the graph, and layout subgraphs induvidually
	igraph_vector_ptr_t subgraphs;
	igraph_vector_ptr_init(&subgraphs, 0);
	igraph_decompose(&graph, &subgraphs, IGRAPH_WEAK, -1, 0);

	// Offset for places subgraphs
	double offsetx = 0;
	double offsety = 0;

	// Layout, translate and extract results for each subgraph
	for(int i = 0; i < igraph_vector_ptr_size(&subgraphs); i++){
		//Get the subgraph
		igraph_t* subgraph = (igraph_t*)VECTOR(subgraphs)[i];

		// Allocate result matrix
		igraph_matrix_t sublayout;
		igraph_matrix_init(&sublayout, 0, 0);

		// Vertex selector and iterator
		igraph_vs_t vs;
		igraph_vit_t vit;
		// Select all and create iterator
		igraph_vs_all(&vs);
		igraph_vit_create(subgraph, vs, &vit);

		// Initialize sublayout, using original positions
		if(startFromCurrentPositions){
			// Count vertices
			int vertices = 0;
			// Iterator over vertices to count them, hacked but it works
			while(!IGRAPH_VIT_END(vit)){
				vertices++;
				IGRAPH_VIT_NEXT(vit);
			}
			//Reset vertex iterator
			IGRAPH_VIT_RESET(vit);
			// Resize sublayout
			igraph_matrix_resize(&sublayout, vertices, 2);
			// Iterator over vertices
			while(!IGRAPH_VIT_END(vit)){
				int subindex = (int)IGRAPH_VIT_GET(vit);
				int index = (int)igraph_cattribute_VAN(subgraph, "id", subindex);
				MATRIX(sublayout, subindex, 0) = posx[index];
				MATRIX(sublayout, subindex, 1) = posy[index];
				IGRAPH_VIT_NEXT(vit);
			}
			//Reset vertex iterator
			IGRAPH_VIT_RESET(vit);
		}

		igraph_layout_kamada_kawai(subgraph, &sublayout, 1000, ((double)V)/4.0, 10, 0.99, V*V, startFromCurrentPositions);
		// Other layout algorithms with reasonable parameters
		//igraph_layout_kamada_kawai(subgraph, &sublayout, 1000, ((double)V)/4.0, 10, 0.99, V*V, startFromCurrentPositions);
		//igraph_layout_grid_fruchterman_reingold(subgraph, &sublayout, 500, V, V*V, 1.5, V*V*V, V*V/4, startFromCurrentPositions);
		//igraph_layout_fruchterman_reingold(subgraph, &sublayout, 500, V, V*V, 1.5, V*V*V, startFromCurrentPositions, NULL);
		//igraph_layout_lgl(subgraph, &sublayout, 150, V, V*V, 1.5, V*V*V, sqrt(V), -1);

		//Find min and max values:
		double minx = DBL_MAX,
			   miny = DBL_MAX,
			   maxx = -DBL_MAX,
			   maxy = -DBL_MAX;
		//Iterator over all vertices
		while(!IGRAPH_VIT_END(vit)){
			int subindex = (int)IGRAPH_VIT_GET(vit);
			double x = MATRIX(sublayout, subindex, 0) * factor;
			double y = MATRIX(sublayout, subindex, 1) * factor;
			minx = minx < x ? minx : x;
			miny = miny < y ? miny : y;
			maxx = maxx > x ? maxx : x;
			maxy = maxy > y ? maxy : y;
			IGRAPH_VIT_NEXT(vit);
		}
		//Reset vertex iterator
		IGRAPH_VIT_RESET(vit);

		// Compute translation
		double tx = margin - minx;
		double ty = margin - miny;
		// Decide whether to put it below or left of current content
		if(maxx - minx + offsetx < maxy - miny + offsety){
			tx += offsetx;
			offsetx += maxx - minx + margin;
			if(offsety < maxy - miny + margin)
				offsety = maxy - miny + margin;
		}else{
			ty += offsety;
			offsety += maxy - miny + margin;
			if(offsetx < maxx - minx + margin)
				offsetx = maxx - minx + margin;
		}
		// Translate and extract results
		while(!IGRAPH_VIT_END(vit)){
			int subindex = (int)IGRAPH_VIT_GET(vit);
			int index = (int)igraph_cattribute_VAN(subgraph, "id", subindex);
			double x = MATRIX(sublayout, subindex, 0) * factor;
			double y = MATRIX(sublayout, subindex, 1) * factor;
			posx[index] = x + tx;
			posy[index] = y + ty;
			IGRAPH_VIT_NEXT(vit);
		}
		// Destroy iterator and selector
		igraph_vit_destroy(&vit);
		igraph_vs_destroy(&vs);

		// Destroy the sublayout
		igraph_matrix_destroy(&sublayout);

		// Destroy subgraph
		igraph_destroy(subgraph);
		free(VECTOR(subgraphs)[i]);
	}

	// Remove the attributes
	igraph_cattribute_remove_v(&graph, "id");

	// Destroy the graph
	igraph_destroy(&graph);

	// Insert results
	i = 0;
	for(PlaceIter it = places.begin(); it != places.end(); it++){
		it->x = posx[i];
		it->y = posy[i];
		i++;
	}
	for(TransitionIter it = transitions.begin(); it != transitions.end(); it++){
		it->x = posx[i];
		it->y = posy[i];
		i++;
	}

	// Produce variables
	for(VarIter it = vars.begin(); it != vars.end(); it++)
		builder->addVariable(it->name, it->initialValue, it->range);

	for(BoolVarIter it = boolVars.begin(); it != boolVars.end(); it++)
		builder->addBoolVariable(it->name, it->initialValue);

	for(PlaceIter it = places.begin(); it != places.end(); it++)
		builder->addPlace(it->name, it->tokens, it->x, it->y);

	for(TransitionIter it = transitions.begin(); it != transitions.end(); it++)
		builder->addTransition(it->name, it->conditions, it->assignments, it->x, it->y);

	for(ArcIter it = inArcs.begin(); it != inArcs.end(); it++)
		builder->addInputArc(it->start, it->end, it->weight);

	for(ArcIter it = outArcs.begin(); it != outArcs.end(); it++)
		builder->addInputArc(it->start, it->end, it->weight);

	//Reset builder state (just in case some idoit decides to reuse it!
	vars.clear();
	boolVars.clear();
	places.clear();
	transitions.clear();
	inArcs.clear();
	outArcs.clear();
}
コード例 #3
0
int main(int argc, char** argv) {

	int response;
	igraph_t graph;
	igraph_vector_ptr_t complist;
	iclust_collection * collection = NULL;
	time_t time_start, time_end;

	/* turn on attribute handling */
	igraph_i_set_attribute_table(&igraph_cattribute_table);

	double minimal_weight;
	unsigned int maximal_steps_delimieter;
	char graphncol[1024], logconfig[1024];

	Config *cfg = ConfigNew();
	const char * configuration = getopt_configfile(argc, argv, "./graphtocluster.conf");
	massert((ConfigReadFile(configuration, &cfg) == CONFIG_OK), "Configuration file is not readable");
	ConfigReadString(cfg, "sources", "graphncol", graphncol, sizeof(graphncol), 0);
	ConfigReadString(cfg, "sources", "logconfig", logconfig, sizeof(logconfig), 0);
	ConfigReadDouble(cfg, "limits", "minimal_weight", &minimal_weight, 0);
	ConfigReadUnsignedInt(cfg, "limits", "maximal_steps_delimieter", &maximal_steps_delimieter, 1);
	massert((maximal_steps_delimieter > 0), "Delimiter can not be equal to zero");
	ConfigFree(cfg);

	logger_init(logconfig, "graphtocluster");
	logger_info("File:\t configuration %s", configuration);
	logger_info("File:\t configuration logger %s", logconfig);
	logger_info("File:\t ncol graph source %s", graphncol);
	logger_info("Min:\t edge weight %f", minimal_weight);
	logger_info("Max:\t step delimeter %u", maximal_steps_delimieter);

	FILE *graph_source = fopen(graphncol, "r");
	response = igraph_read_graph_ncol(&graph, graph_source, NULL, true, IGRAPH_ADD_WEIGHTS_YES, 0);
	massert((response == IGRAPH_SUCCESS), "Can not read a graph");
	logger_info("Count:\t edges at start: %d", igraph_ecount(&graph));
	fclose(graph_source);

	time(&time_start);
	igraph_edges_remove_by(&graph, "weight", minimal_weight, double_lt);
	time(&time_end);
	logger_info("Time:\t remove edges: %f", difftime(time_end, time_start));
	logger_info("Count:\t edges after remove: %d", igraph_ecount(&graph));

	response = igraph_vector_ptr_init(&complist, 0);
	massert((response == IGRAPH_SUCCESS), "Can not initialize vector pointer");

	response = igraph_decompose(&graph, &complist, IGRAPH_WEAK, -1, 0);
	massert((response == IGRAPH_SUCCESS), "Can not decompose graph");

	unsigned int n = igraph_vector_ptr_size(&complist);

	collection = iclust_collection_new();
	massert((collection != NULL), "Cluster collection object can not be empty");

	time(&time_start);
	for (unsigned int i = 0; i < n; i++) {

		igraph_t *subgraph = VECTOR(complist)[i];
		massert((subgraph != NULL), "Subgraph object can not be empty");

		iclust_collection_fill_leading_eigenvector(collection, subgraph, (i + 1), maximal_steps_delimieter);
		igraph_destroy(subgraph);
	}
	time(&time_end);

	logger_info("Time:\t cluster: %f", difftime(time_end, time_start));

	/* Sort collection by cluster id to be
	 * able to build a second column correct*/
	time(&time_start);
	iclust_collection_sort(collection);
	time(&time_end);

	logger_info("Time:\t cluster sorting: %f", difftime(time_end, time_start));

	unsigned long cluster_index = 1, cluster = 0;
	for (unsigned long i = 0; i < collection->length; i++) {

		iclust_collection_element * element = collection->collection[i];
		massert((element != NULL), "Cluster collection element object can not be empty");

		if (element->cluster != cluster) {
			cluster = element->cluster;
			cluster_index = 0;
		}

		printf("%lu\t%lu\t%s\n", cluster, ++cluster_index, element->name);
	}

	iclust_collection_destroy(collection);
	igraph_vector_ptr_destroy(&complist);
	igraph_destroy(&graph);
	logger_destroy();

	return EXIT_SUCCESS;
}