Beispiel #1
0
void srcfss(stack *st, value cur) {

	#ifdef TREEDOT
	st->id = count;
	printf("ID = %zu\n", st->id);
	if (st->id) fprintf(st->dot, "\t%zu -> %zu;\n", (st - 1)->id, st->id);
	printcs(st);
	#endif
	count++;

	if (cur < min) { min = cur; sol = *st; }

	#ifdef LIMIT
	if (!stop) {
		gettimeofday(&t2, NULL);
		if ((double)(t2.tv_usec - t1.tv_usec) / 1e6 + t2.tv_sec - t1.tv_sec > LIMIT) stop = true;
	}
	#ifndef COMPLETEFRONTIER
	else return;
	#endif
	#endif

	#ifdef BOUND
	const value b = bound(st);
	#ifdef LIMIT
	if (stop) { if (b < bou) bou = b; return; }
	else
	#endif
	if (b >= min - MINGAIN) return;
	#endif

	chunk tmp[C], rt[C];
	memcpy(tmp, st->c, sizeof(chunk) * C);
	MASKAND(tmp, st->r, tmp, C);
	edge popc = MASKPOPCNT(tmp, C);

	for (edge i = 0, e = MASKFFS(tmp, C); !stop && i < popc; i++, e = MASKCLEARANDFFS(tmp, e, C)) {

		agent v1 = X(st->a, e);
		agent v2 = Y(st->a, e);

		// At least one of the two coalitions must be a car
		if (!(st->dr[v1] + st->dr[v2])) continue;

		memcpy(rt, st->r, sizeof(chunk) * C);
		CLEAR(st->r, st->g[v1 * N + v2]);
		CLEAR(tmp, st->g[v1 * N + v2]);

		// Must not exceed the number of seats and the maximum number of drivers
		if (X(st->s, v1) + X(st->s, v2) > K || st->dr[v1] + st->dr[v2] > MAXDRIVERS) continue;

		CLEAR(st->c, st->g[v1 * N + v2]);
		st[1] = st[0];
		memcpy(st[1].r, rt, sizeof(chunk) * C);
		merge(st + 1, v1, v2);
		contract(st + 1, v1, v2);
		st[1].l[v1] = minpath(st[1].cs + Y(st[1].s, v1), X(st[1].s, v1), st[1].dr[v1], st->sp);
		srcfss(st + 1, cur + COST(v1, st[1].dr, st[1].l) - COST(v1, st->dr, st->l) - COST(v2, st->dr, st->l));
	}
}
Beispiel #2
0
enqueue(pqueue *q, node * x)
{
		int parent, leaf;
		node value, temp;

		if (q->count >= PQUEUESIZE)
		{
			printf("Warning: pqueue overflow enpqueue x=%dn",x);
			return;
		}
	   
		q->count++;
		leaf = q->count - 1;		
		q->q[leaf] = *x;			

		// percolate up
		parent = PARENT(leaf);
		value = q->q[leaf];
		while(leaf > 0 && (COST(q->q[leaf]) < COST(q->q[parent])))
		{
			temp = q->q[leaf];
			q->q[leaf] = q->q[parent];
			q->q[parent] = temp;
			leaf = parent;
			parent = PARENT(leaf);
		}
		q->q[leaf] = value;
}
Beispiel #3
0
void
cmcostinit (struct tty_display_info *tty)
{
    char *p;

#define	COST(x,e)	(x ? (cost = 0, tputs (x, 1, e), cost) : BIG)
#define CMCOST(x,e)	((x == 0) ? BIG : (p = tgoto(x, 0, 0), COST(p ,e)))

    tty->Wcm->cc_up =	 COST (tty->Wcm->cm_up, evalcost);
    tty->Wcm->cc_down =	 COST (tty->Wcm->cm_down, evalcost);
    tty->Wcm->cc_left =	 COST (tty->Wcm->cm_left, evalcost);
    tty->Wcm->cc_right = COST (tty->Wcm->cm_right, evalcost);
    tty->Wcm->cc_home =	 COST (tty->Wcm->cm_home, evalcost);
    tty->Wcm->cc_cr =	 COST (tty->Wcm->cm_cr, evalcost);
    tty->Wcm->cc_ll =	 COST (tty->Wcm->cm_ll, evalcost);
    tty->Wcm->cc_tab =	 tty->Wcm->cm_tabwidth ? COST (tty->Wcm->cm_tab, evalcost) : BIG;

    /*
     * These last three are actually minimum costs.  When (if) they are
     * candidates for the least-cost motion, the real cost is computed.
     * (Note that "0" is the assumed to generate the minimum cost.
     * While this is not necessarily true, I have yet to see a terminal
     * for which is not; all the terminals that have variable-cost
     * cursor motion seem to take straight numeric values.  --ACT)
     */

    tty->Wcm->cc_abs =  CMCOST (tty->Wcm->cm_abs, evalcost);
    tty->Wcm->cc_habs = CMCOST (tty->Wcm->cm_habs, evalcost);
    tty->Wcm->cc_vabs = CMCOST (tty->Wcm->cm_vabs, evalcost);

#undef CMCOST
#undef COST
}
Beispiel #4
0
node dequeue(pqueue *q)
{
		int heapsize, root, childpos;
		node minVal, temp;
		node value;

		minVal = q->q[0];
		q->q[0] = q->q[q->count-1];		// take last element and put on root of tree
		q->count--;						// adjust size

		root = 0;
		if(q->count > 1)
		{
			// percolate down
			heapsize = q->count;
			value = q->q[root];			// get root
			while(root < heapsize)
			{
				childpos = LEFT(root);
				if(childpos < heapsize)
				{
					if((RIGHT(root) < heapsize) &&
						(COST(q->q[childpos+1]) <
						 COST(q->q[childpos])))
					{
						childpos++;
					}
					if(COST(q->q[childpos]) < COST(q->q[root]))
					{
						temp = q->q[root];
						q->q[root] = q->q[childpos];
						q->q[childpos] = temp;
						root = childpos;
					}
					else
					{
						q->q[root] = value;
						break;
					}
				}
				else
				{
					q->q[root] = value;
					break;
				}
			}
		}
		return minVal;
}
Beispiel #5
0
void printcs(const stack *st) {

	const agent *p = st->n + N + 1;
	agent m = st->n[N];

	do {
		agent i = *(p++);
		printf("{ ");
		for (agent j = 0; j < X(st->s, i); j++)
			printf("%s%u%s%s ", i == st->cs[Y(st->s, i) + j] ? "<" : "", 
			       st->cs[Y(st->s, i) + j], i == st->cs[Y(st->s, i) + j] ? ">" : "", j < st->dr[i] ? "*" : "");
		printf("} (%um) = %.2f€\n", st->l[i], EURO(COST(i, st->dr, st->l)));
	} while (--m);
}
Beispiel #6
0
int main(int argc, char *argv[]) {

	// Allocate stack

	stack st[N];

	// Create shortest paths matrix

	const unsigned seed = atoi(argv[1]);
	st->sp = createsp(seed);

	// Generate random set of drivers

	for (agent i = 0; i < D; i++)
		st->dr[i] = 1;

	memset(st->dr + D, 0, sizeof(agent) * (N - D));
	shuffle(st->dr, N, sizeof(agent));
	memcpy(drg, st->dr, N * sizeof(agent));

	// Initialise n, s, and cs data structures

	st->n[N] = N;

	for (agent i = 0; i < N; i++) {
		X(sg, i) = X(st->s, i) = 1;
		Y(sg, i) = Y(st->s, i) = csg[i] = st->cs[i] = i;
		st->l[i] = st->sp[4 * i * N + 2 * i + 1];
		min += COST(i, st->dr, st->l);
		st->n[st->n[i] = N + i + 1] = i;
	}

	// Initialise c and r bitmasks

	ONES(st->c, E + 1, C);
	CLEAR(st->c, 0);
	ONES(st->r, E + 1, C);
	CLEAR(st->r, 0);

	// Create graph

	#ifdef M
	init(seed);
	memset(st->g, 0, sizeof(edge) * N * N);
	scalefree(st->g, st->a);
	#else
	FILE *f = fopen(argv[2], "r");
	for (agent e = 1; e <= E; e++) {
		agent v1, v2;
		fscanf(f, "%u %u", &v1, &v2);
		createedge(st->g, st->a, v1, v2, e);
	}
	fclose(f);
	#endif

	// Reorder (eventually)

	#ifdef REORDER
	edge go[N * N] = {0};
	agent ao[2 * (E + 1)];
	#ifdef METIS
	idx_t options[METIS_NOPTIONS];
	METIS_SetDefaultOptions(options);
	options[METIS_OPTION_OBJTYPE] = METIS_OBJTYPE_CUT;
	options[METIS_OPTION_SEED] = seed;
	real_t tpwgts[2] = {0.5, 0.5}, ubvec = TOLERANCE;
	agent map[N];
	edge e = 1;
	for (agent i = 0; i < N; i++) map[i] = i;
	reorderedges(st->g, map, N, E, go, ao, &e, tpwgts, &ubvec, options);
	#else
	driversbfs(st->a, st->dr, go, ao);
	#endif
	memcpy(st->g, go, sizeof(edge) * N * N);
	memcpy(st->a, ao, sizeof(agent) * 2 * (E + 1));
	#endif

	#ifdef TREEDOT
	st->dot = fopen(TREEDOT, "w+");
	fprintf(st->dot, "digraph TREE {\n");
	fprintf(st->dot, "\tnode [color = none; shape = plaintext, width = 0.2, height = 0.2];\n");
	#endif

	// Solve

	sol = *st;
	#ifdef LIMIT
	value bou = bound(st);
	#endif
	gettimeofday(&t1, NULL);
	srcfss(st, min);
	gettimeofday(&t2, NULL);

	// Print solution

	#ifdef TREEDOT
	printf("SOLUTION = %zu\n", sol.id);
	fprintf(st->dot, "\t%zu [shape = circle, style = filled, fillcolor = green];\n", sol.id);
	#endif

	#ifdef PK
	FILE *pk = fopen(PK, "w+");
	fprintf(pk, "%u\n%u\n%u\n", N, K, seed);
	printg(st->g, pk);
	printpk(&sol, pk);
	fclose(pk);
	#endif

	#ifdef CSV
	printf("%u,%u,%s,%.2f,%f,%zu\n", N, E, argv[1], 0.01 * min, 
	       (double)(t2.tv_usec - t1.tv_usec) / 1e6 + t2.tv_sec - t1.tv_sec, count);
	#else
	printcs(&sol);
	printf("Visited nodes = %zu\n", count);
	printf("Elapsed time = %f\n", (double)(t2.tv_usec - t1.tv_usec) / 1e6 + t2.tv_sec - t1.tv_sec);
	printf("Solution = %.2f€\n", 0.01 * min);
	#ifdef LIMIT
	printf("Bound = %.2f€\n", 0.01 * bou);
	#endif
	#endif

	// Free data structures

	#ifdef TREEDOT
	fprintf(st->dot, "}");
	fclose(st->dot);
	#endif
	free(st->sp);

	return 0;
}
Beispiel #7
0
__attribute__((always_inline)) inline
value bound(const stack *st) {

	stack tst = *st;
	agent i, m = st->n[N];
	const agent *p = st->n + N + 1;
	value b = 0;

	agent cars[N] = {0};
	agentpath mp[N];
	meter et[2 * N];

	memcpy(tst.dr, drg, sizeof(agent) * N);
	memcpy(tst.cs, csg, sizeof(agent) * N);
	memcpy(tst.s, sg, sizeof(agent) * 2 * N);

	do {
		i = *(p++);
		cars[i] = (st->dr[i] > 0);
	} while (--m);

	connect(&tst, cars);
	p = tst.n + N + 1;
	m = tst.n[N];

	do if (X(tst.s, i = *(p++)) == 1) b += COST(i, st->dr, st->l);
	else {
		agent cy, ck, tr = 0, ccx = X(tst.s, i);
		value pc, b1 = 0, b2 = 0;

		for (agent j = 0; j < ccx; j++)
			for (agent k = 0; k < X(st->s, cy = tst.cs[Y(tst.s, i) + j]); k++) {
				ck = st->cs[Y(st->s, cy) + k];
				if (st->dr[ck]) b1 += PATHCOST(st->l[ck]);
				mp[tr].a = ck;
				mp[tr].d = st->dr[cy];
				mp[tr].p = 0;
				tr++;
			}

		agent as = cars[i] * K;
		b += cars[i] * CARCOST + ((tr > as) ? (tr - as) * TICKETCOST : 0);

		if (cars[i]) {
			for (agent j = 0; j < tr; j++) {
				for (agent k = 0; k < tr; k++) {
					X(et, k) = st->sp[2 * mp[j].a * 2 * N + 2 * mp[k].a];
					Y(et, k) = st->sp[2 * mp[j].a * 2 * N + 2 * mp[k].a + 1];
				}
				QSORT(meter, et, 2 * tr, LT);
				mp[j].p += et[0] + (st->dr[mp[j].a] ? 0 : et[1]);
				for (agent k = 0; k < tr; k++) {
					X(et, k) = st->sp[(2 * mp[j].a + 1) * 2 * N + 2 * mp[k].a];
					Y(et, k) = st->sp[(2 * mp[j].a + 1) * 2 * N + 2 * mp[k].a + 1];
				}
				QSORT(meter, et, 2 * tr, LT);
				mp[j].p += et[0] + (st->dr[mp[j].a] ? 0 : et[1]);
				mp[j].p /= 2;
			}

			#define LTMP(a, b) ( ((*(a)).d != (*(b)).d) ? ((*(a)).d > (*(b)).d) : ((*(a)).p < (*(b)).p) )
			QSORT(agentpath, mp, tr, LTMP);

			for (agent j = 0; j < (tr < as ? tr : as); j++) {
				pc = PATHCOST(mp[j].p);
				b2 += (pc > TICKETCOST) ? TICKETCOST : pc;
			}

			b += b1 > b2 ? b1 : b2;
		}
		//else b += tr * TICKETCOST;
	} while (--m);

	return b;
}