WeightedTriangleLinkPredictor::WeightedTriangleLinkPredictor( const WeightedNetwork& network, int selection = -1 ) : LinkPredictor( network ), selection( selection ) {
	if( this->selection > -1 ) {
		return;
	}
	weight_t allCounts[graphlets] = {0};
	for( vertex_t vertex = 0; vertex < network.vertexCount(); ++vertex ) {
		const neighbor_set_t& outNeighbors = network.outNeighbors( vertex );
		for( neighbor_set_t::const_iterator neighborIterator = outNeighbors.begin(); neighborIterator != outNeighbors.end(); ++neighborIterator ) {
			const vertex_t neighbor = neighborIterator->first;
			weight_t vCounts[graphlets] = {0};
			this->edgeProfile( vertex, neighbor, vCounts );
			for( size_t i = 0; i < graphlets; ++i ) {
				allCounts[i] += vCounts[i];
			}
		}
	}
	for( size_t i = 0; i < graphlets; ++i ) {
		this->counts[i] = (weight_t)allCounts[i] / network.edgeCount();
	}
}
int main( int argc, char* argv[] ) {
	char c;
	while( (c = getopt( argc, argv, "+h" )) >= 0 ) {
		if( c == 'h' ) {
			usage( argv[0] );
			return 0;
		}
	}
	if( argc != optind + 1 ) {
		usage( argv[0] );
		return 1;
	}
	unsigned int distance = atoi( argv[optind++] );
	
	WeightedNetwork network = WeightedNetwork::readNetwork( cin );
	for( vertex_t vertex = 0; vertex < network.vertexCount(); vertex++ ) {
		WeightedNetwork snowball = network.snowballSample( vertex, distance ).removeIsolates();
		cout << snowball.vertexCount() << " " << snowball.edgeCount() << "\n";
	}
	
	return 0;
}