Assignment 4 Code Review

17 April 2003 - CS 509


Assignment 4 Code Review


The Problem


Design


Generating All Subsets


Subset Generating Example


We've Been Here Before


Exhaustive Search

void place(
  uvec current, uvec & best, unsigned ctown)

  if ctown < map.size()
    place(current, best, ctown + 1)
    current.push_back(ctown)
    place(current, best, ctown + 1)

  else if best.size() < current.size()
          and ok(current)
    best = current


uvec maximal_placement()

  uvec towns
  place(uvec(), towns, 0)
  return towns


Battling Exponential Growth


Searching by Road Order


A Road Ordering


A Road-Ordering Search

place(uvec index, 
      uvec current, uvec & best, 
      unsigned ctown)

  if ctown < map.size()
    place(index, current, best, ctown + 1)
    current.push_back(index[ctown])
    if ok(current)
      if best.size() < current.size()
        best = current
      place(index, current, best, ctown + 1)


uvec maximal_placement()

  uvec towns

  uvec index(map.size())
  for (unsigned i = 0; i < map.size(); i++)
    index[i] = i
  std::sort(index.begin(), index.end(), 
            map_less(map))

  place(index, uvec(), towns, map.size())

  return towns


Road-Ordering Results


A Size-Pruning Search

void place(
  uvec current, uvec & best, unsigned ctown)

  const unsigned max = 
    current.size() + (map.size() - ctown)

  if max > best.size()
    place(current, best, ctown + 1)
    current.push_back(ctown)
    if ok(current)
      if best.size() < current.size()
        best = current
      place(current, best, ctown + 1)

uvec maximal_placement()

  uvec towns
  place(uvec(), towns, 0)
  return towns


Does Size-Pruning Help?


How about Pruning and Sorting?


Use All The Data


A Knockout Search

void place(
  flag_set valid, uvec current, uvec & best)

  const flags_iter
    b = valid.begin(),
    e = valid.end(),
    v = std::find(b, e, true)

  if (v == e) return

  *v = false
  place(valid, current, best)

  const unsigned i = v - b
  std::for_each(
    map.at(i).begin(), map.at(i).end(), 
    set_false(valid))

  current.push_back(i)
  place(valid, current, best)

  if best.size() < current.size()
    best = current


Knockout Search Details

typedef std::vector<bool>        flag_set
typedef flag_set::iterator       flags_iter
typedef flag_set::const_iterator flags_citer

struct set_false {

  flag_set & flags;

  set_false(flag_set & flags) 
    : flags(flags) { }

  void operator () (unsigned i) {
    flags.at(i) = false;
    }
  };


uvec maximal_placement(const umat & map)

  uvec towns
  flag_set valid(map.size(), true)

  place(valid, uvec(), towns)

  return towns


Does Knockout Help?


Knockout With Pruning


Knockout With Counting


Line Statistics - Newlines

000100300
01
101
20
301
402
5012
60
701
80
9011
Totals551


Line Statistics - Semicolons

000100
01
101
203
30
40
50
604
701
80
901
Totals101


Procedure Statistics

totalpages per procedure
procs1234
11
11
431
55
88
99


Watch Initialization


Use Generic Algorithms


Use Dynamic Memory Correctly


int findnext(umat map, int * actarrp, int sz)

 int *taarrp = new int [sz]

 townaffected(map, actarrp, sz, taarrp)

 for (i = 0; i < sz; i++)
   if actarrp[i] != ACTIVE
     continue
   if (taarrp[i] < mincnt) or (mincnt == 0)
     mincnt = taarrp[i]
     minidx = i

 return minidx;


uvec maximum_placement(umat map)

  int * actarrp = new int[mapsize]

  check_map(map)
  init(actarrp, mapsize)

  while findactivecnt(actarrp, mapsize) > 0
    idx = findnext(map, actarrp, mapsize)
    addtolist(map, actarrp, idx, townlist)

  return townlist


Duplicate Code is Bad Code


Points To Remember


This page last modified on 18 April 2003.