void print_cut(int p[],int n){ int profit = memo_init(p,n); while(n>0){ printf("%d ",path[n]); n -= path[n]; } printf("%d\n",profit); }
uint32_t zdd_intersection() { vmax_check(); if (darray_count(stack) == 0) return 0; if (darray_count(stack) == 1) return (uint32_t) darray_last(stack); uint32_t z0 = (uint32_t) darray_at(stack, darray_count(stack) - 2); uint32_t z1 = (uint32_t) darray_remove_last(stack); struct node_template_s { uint16_t v; // NULL means this template have been instantiated. // Otherwise it points to the LO template. memo_it lo; union { // Points to HI template when template is not yet instantiated. memo_it hi; // During template instantiation we set n to the pool index // of the newly created node. uint32_t n; }; }; typedef struct node_template_s *node_template_ptr; typedef struct node_template_s node_template_t[1]; node_template_t top, bot; bot->v = 0; bot->lo = NULL; bot->n = 0; top->v = 1; top->lo = NULL; top->n = 1; // Naive implementation with two tries. One stores templates, the other // unique nodes. See Knuth for how to meld using just memory allocated // for a pool of nodes. memo_t tab; memo_init(tab); memo_it insert_template(uint32_t k0, uint32_t k1) { uint32_t key[2]; // Taking advantage of symmetry of intersection appears to help a tiny bit. if (k0 < k1) { key[0] = k0; key[1] = k1; } else { key[0] = k1; key[1] = k0; } memo_it it; int just_created = memo_it_insert_u(&it, tab, (void *) key, 8); if (!just_created) return it; if (!k0 || !k1) { memo_it_put(it, bot); return it; } if (k0 == 1 && k1 == 1) { memo_it_put(it, top); return it; } node_ptr n0 = pool[k0]; node_ptr n1 = pool[k1]; if (n0->v == n1->v) { node_template_ptr t = malloc(sizeof(*t)); t->v = n0->v; if (n0->lo == n0->hi && n1->lo == n0->hi) { t->lo = t->hi = insert_template(n0->lo, n1->lo); } else { t->lo = insert_template(n0->lo, n1->lo); t->hi = insert_template(n0->hi, n1->hi); } memo_it_put(it, t); return it; } else if (n0->v < n1->v) { memo_it it2 = insert_template(n0->lo, k1); memo_it_put(it, memo_it_data(it2)); return it2; } else { memo_it it2 = insert_template(k0, n1->lo); memo_it_put(it, memo_it_data(it2)); return it2; } }