Beispiel #1
0
tqt::tqt(const char* filename)
// Constructor.  Open the file and read the table of contents.  Keep
// the stream open in order to load textures on demand.
{
	m_source = SDL_RWFromFile(filename, "rb");
	if (m_source == NULL) {
		throw "tqt::tqt() can't open file.";
	}

	// Read header.
	tqt_header_info	info = read_tqt_header_info(m_source);
	if (info.m_version != TQT_VERSION) {
		m_source = NULL;
		throw "tqt::tqt() incorrect file version.";
		return; // Hm.
	}

	m_depth = info.m_tree_depth;
	m_tile_size = info.m_tile_size;

	// Read table of contents.  Each entry is the offset of the
	// index'ed tile's JPEG data, relative to the start of the file.
	m_toc.resize(node_count(m_depth));
	for (int i = 0; i < node_count(m_depth); i++) {
		m_toc[i] = SDL_ReadLE32(m_source);
	}
}
std::vector<MCF_graph::node_elt> MCF_graph::get_Bellman_Ford(int source_node) const{
    std::vector<node_elt> accessibles(node_count(), node_elt(max_int, -1));
    accessibles[source_node] = node_elt(0, -1);
    for(int i=0; i<=node_count(); ++i){
        bool found_relaxation = false;
        for(int e=0; e<edges.size(); ++e){
            edge const E = edges[e];
            int forward_cost = accessibles[E.source].cost + E.cost;
            if(forward_cost < accessibles[E.dest].cost){
                accessibles[E.dest] = node_elt(forward_cost, e, accessibles[E.source].max_flow);
                found_relaxation = true;
            }
            int backward_cost = accessibles[E.dest].cost - E.cost;
            if(backward_cost < accessibles[E.source].cost and E.flow > 0){
                accessibles[E.source] = node_elt(backward_cost, e, std::min(accessibles[E.dest].max_flow, E.flow));
                found_relaxation = true;
            }
        }
        if(not found_relaxation) break;
        else if(i == node_count() or accessibles[source_node].cost < 0){
            accessibles[source_node] = node_elt(-1, -1);
            break;
        }
    }
    return accessibles;
}
Beispiel #3
0
int node_count(Node node){
	if(!node)
		return 0;
	else if(is_leaf(node))
		return 1;
	else return(1 + node_count(node->left) + node_count(node->right));
}
std::vector<int> const MCF_graph::get_potentials() const{
    if(node_count() == 0) return std::vector<int>();
    std::vector<node_elt> accessibles = get_Bellman_Ford(0);
    assert(accessibles[0].cost == 0);
    std::vector<int> ret;
    for(node_elt const N : accessibles) ret.push_back(N.cost);
    return ret;
}
Beispiel #5
0
int main() {
	PNODE h = (PNODE)malloc(sizeof(Node));
	PNODE p = (PNODE)malloc(sizeof(Node));
	h->next = p;
	h->data = 0;
	PNODE r;
	for (int i = 1; i <= 10; i++) {
		r = (PNODE)malloc(sizeof(Node));
		if (i < 5)
			p->data = 1;
		else
			p->data = i;
		p->next = r;
		p = p->next;
	}
	p->next = NULL;

	//(1)
	int cot = -1;
	node_count(h, cot);
	printf("%d个节点\n", cot);

	//(2)
	printf("正向输出:");
	L_display(h); printf("\n");
	
	//(3)
	printf("反向输出:");
	R_display(h); printf("\n");

	//(4)
	del_elem_once(h->next, 1);
	printf("删除第一个值为1的节点后:");
	L_display(h); printf("\n");

	//(5)
	del_elem_all(h->next, 1);
	printf("删除所有值为1的节点后:");
	L_display(h); printf("\n");

	//(6)
	int max = -100, min = 200;

	disp_max(h,max);
	printf("max = %d\n", max);

	//(7)
	disp_min(h, min);
	printf("min = %d\n", min);
	return 0;
}
Beispiel #6
0
void dump_stats(guint32 diff_msecs)
{
  gchar *status_string;
  long ipc=ipcache_active_entries();
  status_string = g_strdup_printf (
    _("Nodes: %d (on canvas: %d, shown: %u), Links: %d, Conversations: %ld, "
      "names %ld, protocols %ld. Total Packets seen: %lu (in memory: %ld, "
      "on list %ld). IP cache entries %ld. Canvas objs: %ld. Refreshed: %u ms"),
                                   node_count(), 
                                   g_tree_nnodes(canvas_nodes), displayed_nodes, 
                                   links_catalog_size(), active_conversations(), 
                                   active_names(), protocol_summary_size(),
                                   appdata.n_packets, appdata.total_mem_packets, 
                                   packet_list_item_count(), ipc,
                                   canvas_obj_count,
                                   (unsigned int) diff_msecs);
  
  g_my_info ("%s", status_string);
  g_free(status_string);
}
Beispiel #7
0
/*
 * Avoid nodes being stuck helplessly due to completely stale caches.
 * @return TRUE if an UHC may be contact, FALSE if it's not permissable.
 */
static gboolean
host_cache_allow_bypass(void)
{
	static time_t last_try;

	if (node_count() > 0)
		return FALSE;

	/* Wait at least 2 minutes after starting up */
	if (delta_time(tm_time(), GNET_PROPERTY(start_stamp)) < 2 * 60)
		return FALSE;

	/*
	 * Allow again after 12 hours, useful after unexpected network outage
	 * or downtime.
	 */

	if (last_try && delta_time(tm_time(), last_try) < 12 * 3600)
		return FALSE;

	last_try = tm_time();
	return TRUE;
}
Beispiel #8
0
/**
 * Periodic host heartbeat timer.
 */
void
host_timer(void)
{
    guint count;
	int missing;
	host_addr_t addr;
	guint16 port;
	host_type_t htype;
	guint max_nodes;
	gboolean empty_cache = FALSE;

	if (in_shutdown || !GNET_PROPERTY(online_mode))
		return;

	max_nodes = settings_is_leaf() ?
		GNET_PROPERTY(max_ultrapeers) : GNET_PROPERTY(max_connections);
	count = node_count();			/* Established + connecting */
	missing = node_keep_missing();

	if (GNET_PROPERTY(host_debug) > 1)
		g_debug("host_timer - count %u, missing %u", count, missing);

	/*
	 * If we are not connected to the Internet, apparently, make sure to
	 * connect to at most one host, to avoid using all our hostcache.
	 * Also, we don't connect each time we are called.
	 */

	if (!GNET_PROPERTY(is_inet_connected)) {
		static time_t last_try;

		if (last_try && delta_time(tm_time(), last_try) < 20)
			return;
		last_try = tm_time();

		if (GNET_PROPERTY(host_debug))
			g_debug("host_timer - not connected, trying to connect");
	}

	/*
	 * Allow more outgoing connections than the maximum amount of
	 * established Gnet connection we can maintain, but not more
	 * than quick_connect_pool_size   This is the "greedy mode".
	 */

	if (count >= GNET_PROPERTY(quick_connect_pool_size)) {
		if (GNET_PROPERTY(host_debug) > 1)
			g_debug("host_timer - count %u >= pool size %u",
				count, GNET_PROPERTY(quick_connect_pool_size));
		return;
	}

	if (count < max_nodes)
		missing -= whitelist_connect();

	/*
	 * If we are under the number of connections wanted, we add hosts
	 * to the connection list
	 */

	htype = HOST_ULTRA;

	if (
        settings_is_ultra() &&
        GNET_PROPERTY(node_normal_count) < GNET_PROPERTY(normal_connections) &&
        GNET_PROPERTY(node_ultra_count) >=
			(GNET_PROPERTY(up_connections) - GNET_PROPERTY(normal_connections))
	) {
		htype = HOST_ANY;
    }

	if (hcache_size(htype) == 0)
		htype = HOST_ANY;

	if (hcache_size(htype) == 0)
		empty_cache = TRUE;

	if (GNET_PROPERTY(host_debug) && missing > 0)
		g_debug("host_timer - missing %d host%s%s",
			missing, missing == 1 ? "" : "s",
			empty_cache ? " [empty caches]" : "");

    if (!GNET_PROPERTY(stop_host_get)) {
        if (missing > 0) {
			static time_t last_try;
            unsigned fan, max_pool, to_add;

            max_pool = MAX(GNET_PROPERTY(quick_connect_pool_size), max_nodes);
            fan = (missing * GNET_PROPERTY(quick_connect_pool_size))/ max_pool;
			fan = MAX(1, fan);
            to_add = GNET_PROPERTY(is_inet_connected) ? fan : (guint) missing;

			/*
			 * Every so many calls, attempt to ping all our neighbours to
			 * get fresh pongs, in case our host cache is not containing
			 * sufficiently fresh hosts and we keep getting connection failures.
			 */

			if (
				0 == last_try ||
				delta_time(tm_time(), last_try) >= HOST_PINGING_PERIOD
			) {
				ping_all_neighbours();
				last_try = tm_time();
			}

            /*
             * Make sure that we never use more connections then the
             * quick pool or the maximum number of hosts allow.
             */
            if (to_add + count > max_pool)
                to_add = max_pool - count;

            if (GNET_PROPERTY(host_debug) > 2) {
                g_debug("host_timer - connecting - "
					"add: %d fan:%d miss:%d max_hosts:%d count:%d extra:%d",
					 to_add, fan, missing, max_nodes, count,
					 GNET_PROPERTY(quick_connect_pool_size));
            }

            missing = to_add;

			if (missing > 0 && (0 == connected_nodes() || host_low_on_pongs)) {
				gnet_host_t host[HOST_DHT_MAX];
				int hcount;
				int i;

				hcount = dht_fill_random(host,
					MIN(UNSIGNED(missing), G_N_ELEMENTS(host)));

				missing -= hcount;

				for (i = 0; i < hcount; i++) {
					addr = gnet_host_get_addr(&host[i]);
					port = gnet_host_get_port(&host[i]);
					if (!hcache_node_is_bad(addr)) {
						if (GNET_PROPERTY(host_debug) > 3) {
							g_debug("host_timer - UHC pinging and connecting "
								"to DHT node at %s",
								host_addr_port_to_string(addr, port));
						}
						/* Try to use the host as an UHC before connecting */
						udp_send_ping(NULL, addr, port, TRUE);
						if (!host_gnutella_connect(addr, port)) {
							missing++;	/* Did not use entry */
						}
					} else {
						missing++;	/* Did not use entry */
					}
				}
			}

			while (hcache_size(htype) && missing-- > 0) {
				if (hcache_get_caught(htype, &addr, &port)) {
					if (!(hostiles_check(addr) || hcache_node_is_bad(addr))) {
						if (!host_gnutella_connect(addr, port)) {
							missing++;	/* Did not use entry */
						}
					} else {
						missing++;	/* Did not use entry */
					}
				}
			}

			if (missing > 0 && (empty_cache || host_cache_allow_bypass())) {
				if (!uhc_is_waiting()) {
					if (GNET_PROPERTY(host_debug))
						g_debug("host_timer - querying UDP host cache");
					uhc_get_hosts();	/* Get new hosts from UHCs */
				}
			}
		}

	} else if (GNET_PROPERTY(use_netmasks)) {
		/* Try to find better hosts */
		if (hcache_find_nearby(htype, &addr, &port)) {
			if (node_remove_worst(TRUE))
				node_add(addr, port, 0);
			else
				hcache_add_caught(htype, addr, port, "nearby host");
		}
	}
}
Beispiel #9
0
/*
 * 	+-----------------------------------------------+
 * 	| 	5 	| 	7 	| 	9 	|
 * 	+-----------------------------------------------+
 * 				|
 * 			+---------------+
 * 			|  60 | 61 | 62 |
 * 			+---------------+
 *
 * 	+---------------------------------------------------------------+
 * 	|  	5 	| 	60	 |	7 	| 	9 	|
 * 	+---------------------------------------------------------------+
 * 				|		|
 * 			    +--------+	    +---------+
 * 			    |   60   |	    | 61 | 62 |
 * 			    +--------+	    +---------+
 *
 *
 * ENTER:
 *	- node is already locked(L_WRITE)
 * EXITS:
 *	- a is locked(L_WRITE)
 *	- b is locked(L_WRITE)
 */
static void _node_split(struct tree *t,
                        struct node *node,
                        struct node **a,
                        struct node **b,
                        struct msg **split_key)
{
	int i;
	int pivots_old;
	int pivots_in_a;
	int pivots_in_b;
	struct node *nodea;
	struct node *nodeb;
	struct msg *spk;

	__DEBUG("nonleaf split begin, NID %"PRIu64""
	        ", nodesz %d"
	        ", nodec %d"
	        ", children %d"
	        , node->nid
	        , node_size(node)
	        , node_count(node)
	        , node->n_children);

	nodea = node;
	pivots_old = node->n_children - 1;
	nassert(pivots_old > 2);

	pivots_in_a = pivots_old / 2;
	pivots_in_b = pivots_old - pivots_in_a;

	/* node a */
	nodea->n_children = pivots_in_a + 1;

	/* node b */
	NID nid = hdr_next_nid(t->hdr);
	node_create_light(nid, node->height > 0 ? 1 : 0, pivots_in_b + 1, t->hdr->version, t->e, &nodeb);
	cache_put_and_pin(t->cf, nid, nodeb);

	for (i = 0; i < (pivots_in_b); i++)
		nodeb->pivots[i] = nodea->pivots[pivots_in_a + i];

	for (i = 0; i < (pivots_in_b + 1); i++)
		nodeb->parts[i] = nodea->parts[pivots_in_a + i];

	/* the rightest partition of nodea */
	struct child_pointer *ptr = &nodea->parts[pivots_in_a].ptr;

	if (nodea->height > 0)
		ptr->u.nonleaf = create_nonleaf(t->e);
	else
		ptr->u.leaf = create_leaf(t->e);


	/* split key */
	spk = msgdup(&node->pivots[pivots_in_a - 1]);

	node_set_dirty(nodea);
	node_set_dirty(nodeb);

	__DEBUG("nonleaf split end, nodea NID %"PRIu64""
	        ", nodesz %d"
	        ", nodec %d"
	        ", children %d"
	        , nodea->nid
	        , node_size(nodea)
	        , node_count(nodea)
	        , nodea->n_children);

	__DEBUG("nonleaf split end, nodeb NID %"PRIu64""
	        ", nodesz %d"
	        ", nodec %d"
	        ", children %d"
	        , nodeb->nid
	        , node_size(nodeb)
	        , node_count(nodeb)
	        , nodeb->n_children);

	*a = nodea;
	*b = nodeb;
	*split_key = spk;
}
Beispiel #10
0
/*
 * EFFECT:
 *	- split leaf&lmb into two leaves:a & b
 *	  a&b are both the half of the lmb
 *
 * PROCESS:
 *	- leaf:
 *		+-----------------------------------+
 *		|  0  |  1  |  2  |  3  |  4  |  5  |
 *		+-----------------------------------+
 *
 *	- split:
 *				   root
 *				 +--------+
 *				 |   2    |
 *				 +--------+
 *	  	                /          \
 *	    	+-----------------+	 +------------------+
 *	    	|  0  |  1  |  2  |	 |  3  |  4  |  5   |
 *	    	+-----------------+	 +------------------+
 *	    	      nodea			nodeb
 *
 * ENTER:
 *	- leaf is already locked (L_WRITE)
 * EXITS:
 *	- a is locked
 *	- b is locked
 */
static void _leaf_and_lmb_split(struct tree *t,
                                struct node *leaf,
                                struct node **a,
                                struct node **b,
                                struct msg **split_key)
{
	struct child_pointer *cptra;
	struct child_pointer *cptrb;
	struct node *leafa;
	struct node *leafb;
	struct lmb *mb;
	struct lmb *mba;
	struct lmb *mbb;
	struct msg *sp_key = NULL;

	__DEBUG("leaf split begin, NID %"PRIu64""
	        ", nodesz %d"
	        ", nodec %d"
	        ", children %d"
	        , leaf->nid
	        , node_size(leaf)
	        , node_count(leaf)
	        , leaf->n_children);

	leafa = leaf;
	cptra = &leafa->parts[0].ptr;

	/* split lmb of leaf to mba & mbb */
	mb = cptra->u.leaf->buffer;
	lmb_split(mb, &mba, &mbb, &sp_key);
	lmb_free(mb);

	/* reset leafa buffer */
	cptra->u.leaf->buffer = mba;

	/* new leafb */
	NID nid = hdr_next_nid(t->hdr);
	node_create(nid, 0, 1, t->hdr->version, t->e, &leafb);
	cache_put_and_pin(t->cf, nid, leafb);

	cptrb = &leafb->parts[0].ptr;
	lmb_free(cptrb->u.leaf->buffer);
	cptrb->u.leaf->buffer = mbb;

	/* set dirty */
	node_set_dirty(leafa);
	node_set_dirty(leafb);

	__DEBUG("leaf split end, leafa NID %"PRIu64""
	        ", nodesz %d"
	        ", nodec %d"
	        ", children %d"
	        , leafa->nid
	        , node_size(leafa)
	        , node_count(leafa)
	        , leafa->n_children);

	__DEBUG("leaf split end, leafb NID %"PRIu64""
	        ", nodesz %d"
	        ", nodec %d"
	        ", children %d"
	        , leafb->nid
	        , node_size(leafb)
	        , node_count(leafb)
	        , leafb->n_children);

	*a = leafa;
	*b = leafb;
	*split_key = sp_key;
	status_increment(&t->e->status->tree_leaf_split_nums);
}
void MCF_graph::add_edge(int esource, int edestination, int ecost){
    assert(esource != edestination and esource < node_count() and edestination < node_count() and esource >= 0 and edestination >= 0);
    int sent_flow=0;

    // Handling of redundant edges
    for(auto it = edges.begin(); it != edges.end(); ){
        if(it->source == esource and it->dest == edestination){
            if(it->cost > ecost){
                sent_flow += it->flow;
                cost -= it->flow * (ecost - it->cost);
                it = edges.erase(it);
            }
            else{
                assert(sent_flow == 0);
                return;
            }
        }
        else{
            ++it;
        }
    }

    bool maybe_cycle = bounded;
    while(maybe_cycle){
        // Perform Bellman-Ford algorithm
        // Find a path from the edge's *destination* to its *source* to make a cycle
        std::vector<node_elt> accessibles = get_Bellman_Ford(edestination);
        assert(accessibles[edestination].cost == 0); // If we found a negative cost cycle, then our previous solution was not optimal

        // If the cycle has negative cost, send flow along this cycle
        int path_cost = accessibles[esource].cost;
        if(path_cost < max_int and path_cost + ecost < 0){ // Reachable and negative cost cycle
            int cycle_cost = path_cost + ecost;
            // std::cout << "Found an improving cycle" << std::endl;
            // Find the maximum flow along the cycle
            int max_flow = accessibles[esource].max_flow;
            if(max_flow >= max_int){
                bounded = false;
                break;
            }
            int cur_node=esource;
            // TODO: detect negative cost cycles with a single edge in the opposite direction; this edge may be safely removed
            while(cur_node != edestination){
                int e = accessibles[cur_node].incoming_edge;
                assert(e >= 0);
                if(cur_node == edges[e].source){
                    edges[e].flow -= max_flow;
                    cur_node = edges[e].dest;
                }else{
                    assert(cur_node == edges[e].dest);
                    edges[e].flow += max_flow;
                    cur_node = edges[e].source;
                }
            }
            cost -= (max_flow * cycle_cost);
            sent_flow += max_flow;
        }
        else{ // Ok, no more cycle, optimal solution, we can just exit
            maybe_cycle = false;
        }
    }
 
    edges.emplace_back(esource, edestination, ecost, sent_flow);
    //reorder_edges();
    assert(not bounded or check_optimal());
    selfcheck();
}
MCF_graph::MCF_graph(int node_cnt, std::vector<MCF_graph::edge> edge_list) : edges(edge_list), nb_nodes(node_cnt), bounded(true), cost(0){
    for(int e=0; e<edges.size(); ++e){
        edge cur = edges[e];
        assert(cur.source < node_count() and cur.dest < node_count());
    }
}
// returns the total number of nodes
int BinarySearchTree::node_count() {
	return node_count(root);
}
/*
 * Calculates the Silhouette index for a graph. Returns a vector
 * with the SI for the whole graph in position 0 and for each cluster
 * in the position of it's identifier.
 */
std::vector<double> ClusterEvaluator::getSilhouetteIndex() {
     hmap_i_i::iterator it;
     hmap_i_i spaths;
     hmap::iterator node;
     //int ccount;
     double an = 0.0;
     int bn = MAXIMUM;
     hmap_i_i ccount;
     hmap_i_i acc;
     std::vector<double> silhouette(clusters->size()+1);
     std::vector<int> node_count(clusters->size()+1);
     // Initializing average counters
     for (int i = 0; i < clusters->size()+1; ++i) {
          silhouette[i] = 0.0;
          node_count[i] = 0;
     }
     // For each node n in the graph
     unsigned int mycluster;
     std::set<uint>* ctmp;
     std::set<uint>::iterator itcl;
     for (node = graph->graph_map.begin(); node != graph->graph_map.end();
               ++node){
          // We will not calculate the Silhouette index for the
          // cluster 0, as it is not really a cluster
          std::set<uint>::iterator sit;
          for (sit = node_cluster->find(node->first)->second->begin();
                    sit != node_cluster->find(node->first)->second->end();
                    ++sit) {
               //mycluster = (node_cluster->find(node->first)->second);
               mycluster = *sit;
               if (mycluster != 0) {
                    // Calculate the shortest paths for all nodes
                    spaths = graph->dijkstra(node->first);
                    acc.clear();
                    ccount.clear();
                    for (it = spaths.begin(); it != spaths.end(); ++it) {
                         if (it->first != node->first){
                              ctmp = node_cluster->find(it->first)->second;
                              // Iterate through all of its clusters
                              for (itcl = ctmp->begin(); itcl != ctmp->end();
                                        ++itcl) { 
                                   if (acc.find(*itcl) == acc.end()) {
                                        // New cluster!
                                        acc[*itcl] = it->second;
                                        ccount[*itcl] = 1;
                                   } else {
                                        // Already exists. Accumulate
                                        acc[*itcl] = acc[*itcl] + it->second;
                                        ccount[*itcl] = ccount[*itcl] + 1;
                                   }
                              }
                         }
                    }
                    // Calculate average cluster distances
                    an = 0.0;
                    bn = MAXIMUM;
                    for (it = acc.begin(); it != acc.end(); ++it) {
                         if (it->first == mycluster) {
                              // Average distance to own cluster
                              an = it->second/(double)ccount[it->first];
                         } else {
                              // Minimum average distance to other clusters
                              double btmp = it->second/
                                   (double)ccount[it->first];
                              if (btmp < bn) bn = btmp;
                         }
                    }
                    //an = an/(double)ccount;
                    // His Silhouette index is Sn = (bn - an)/max(an, bn)
                    silhouette[mycluster] += (bn - an)/
                         ((an > (double) bn)? an:(double)bn);
                    node_count[mycluster] += 1;
               }
          }
     }
     for (int i = 1; i < silhouette.size(); ++i) {
          // Average Silhouette index for cluster i
          silhouette[i] = silhouette[i]/(double)node_count[i];
          // Average silhouete index for the whole graph
          silhouette[0] += silhouette[i]/(double)(silhouette.size()-1);
     }
     return silhouette;
}