Exemplo n.º 1
0
BddNodeHandle BddManager::find_or_insert(BddNodeHandle pBddNode) {
    assert(pBddNode.valid());
    if (pBddNode->isTerminal())
        return pBddNode;

    hash_type::iterator it = _hashBddNode.end();
    if ((it = try_find(pBddNode)) != _hashBddNode.end()) {
        return *it;
    }

    BddNodeHandle pPos = pBddNode->getPosHandle();
    BddNodeHandle pNeg = pBddNode->getNegHandle();
    BddNodeHandle pNewPos = find_or_insert(pPos);
    BddNodeHandle pNewNeg = find_or_insert(pNeg);

    BddNodeHandle pNew = BddNode::makeBddNode(pBddNode->getCurDecisionLevel(), pNewPos, pNewNeg);

    if ((it = try_find(pNew)) != _hashBddNode.end()) {
        return *it;
    }
    else {
        _hashBddNode.insert(pNew);
        if (verbose) {
            DEBUG_EXPR(pNew->toString());
            DEBUG_EXPR(pNew->hashFunction());
            std::cerr << std::endl;
        }
        assert(try_find(pNew) != _hashBddNode.end());
        return pNew;
    }
}
Exemplo n.º 2
0
void add_roads_and_connect_cities(Graph& graph,
            RoadTupleVector const& roads,
            CityTupleVector& cities)
{
    typedef typename boost::range_value<RoadTupleVector>::type road_type;
    typedef typename boost::tuples::element<0, road_type>::type line_type;
    typedef typename boost::geometry::point_type<line_type>::type point_type;

    typedef typename boost::graph_traits<Graph>::vertex_descriptor vertex_type;

    // Define a map to be used during graph filling
    // Maps from point to vertex-id's
    typedef std::map<point_type, vertex_type, boost::geometry::less<point_type> > map_type;
    map_type map;


    // Fill the graph
    BOOST_FOREACH(road_type const& road, roads)
    {
        line_type const& line = road.template get<0>();
        // Find or add begin/end point of these line
        vertex_type from = find_or_insert(map, line.front(), graph);
        vertex_type to = find_or_insert(map, line.back(), graph);
        boost::add_edge(from, to, bg_edge_property<line_type>(line), graph);
    }
Exemplo n.º 3
0
BddNodeHandle BddManager::makeBddNode(int curDecisionLevel, BddNodeHandle pPos, BddNodeHandle pNeg) {
    if (!(curDecisionLevel > 0)) {
        LOG(ERROR) << "curDecisionLevel : " << curDecisionLevel;
    }
    assert(curDecisionLevel > 0);
    BddNodeHandle pBddNode = BddNode::makeBddNode(curDecisionLevel, pPos, pNeg);

    return find_or_insert(pBddNode);
}
Exemplo n.º 4
0
EC_API EcBool ec_hash_set( ec_hash table, EcAny key, EcAny value )
{
	ec_hash_entry entry;
	EcAny invkey;

	ENTERF;
	ASSERT(table);

	if ((H_CAPACITY(table) == 0) && (! hash_expand( table )))
		return FALSE;

	invkey = H_INVKEY(table);

	entry = find_or_insert( table, key );
	if (! entry) return FALSE;
	if (EC_HASH_ENTRY_KEY(entry) == invkey)
	{
		/* fresh slot */

		EC_HASH_ENTRY_KEY(entry)   = H_DEF(table).key_copy   ? H_KEYCOPY(table, key)   : key;
		EC_HASH_ENTRY_VALUE(entry) = H_DEF(table).value_copy ? H_VALCOPY(table, value) : value;

		H_ENTRIES(table)++;

		/* In case we exceeded the load factor, expand the table */
		ASSERT(H_CAPACITY(table));
		if (((H_ENTRIES(table) << SHIFTAMOUNT) / H_CAPACITY(table)) >= H_HILOAD(table))
			hash_expand( table );

		ASSERT( verify( table, key, value ) );
		return TRUE;
	}
	else
	{
		/* already occupied slot */

		if (H_DEF(table).value_destroy && (EC_HASH_ENTRY_VALUE(entry) != H_INVVAL(table)))
			H_VALDESTROY(table, EC_HASH_ENTRY_VALUE(entry));
		EC_HASH_ENTRY_VALUE(entry) = H_DEF(table).value_copy ? H_VALCOPY(table, value) : value;

		ASSERT( verify( table, key, value ) );
		return TRUE;
	}

	ASSERT(0);													/* We couldn't get here */
	return FALSE;
}
Exemplo n.º 5
0
void bfs_bbr(int upper_bound)
/*
   1. This function uses breadth first search (BFS) branch bound and remember (BBR) to find an optimal solution
	  for the simple assembly line balancing problem.
   2. upper_bound = upper bound on the number of stations needed.  Search for a solution with fewer than upper_bound stations.
   3. Written 3/3/06.
*/
{
   char     LB;
   int      count, i, j, index, LB1, level, n_eligible, status, t_sum;
   double   cpu;
   clock_t  start_time;

   start_time = clock();

   UB = upper_bound;

   initialize_hash_table();
   reinitialize_states();

   // Add the root problem to the hash table and the list of states.

   t_sum = 0;
   for(i = 1; i <= n_tasks; i++) {
	  count = 0;
	  t_sum += t[i];
	  for(j = 1; j <= n_tasks; j++) {
		 if(predecessor_matrix[j][i] == 1) count++;
	  }
	  degrees[i] = count;
   }
   LB1 = (int) ceil((double) t_sum / (double) cycle);
   if(LB1 < UB) {
	  LB = (char) LB1;
	  index = find_or_insert(0.0, degrees, 0, LB, 0, 0, -1, 0, &status);
   }
   if(bin_pack_flag == -1) bin_pack_flag = bin_pack_lb;

   // Main loop
   // Modified 5/19/09 to call gen_loads iff states[index].open = 1.

   index = get_state();
   level = 0;
   count = 0;
   while( index >= 0) {
	  cpu = (double) (clock() - search_info.start_time) / CLOCKS_PER_SEC;
		if (cpu > CPU_LIMIT) {
		   printf("Time limit reached\n");
			verified_optimality = 0;;
		   break;
		}
	  if(state_space_exceeded == 1) {
		 verified_optimality = 0;
		 break;
	  }

	  if (states[index].n_stations > level) {
		 level = states[index].n_stations;
		 printf("%2d %10d %10d\n", level, count, last_state - first_state + 2);
		 count = 0;
		 //prn_states(level);
		 //if(level >= 3) return;
	  }

	  if(states[index].open == 1) {
		 states[index].open = 0;
		 count++;
		 search_info.n_explored++;
		 station = states[index].n_stations + 1;
		 idle = states[index].idle;
		 hash_value = states[index].hash_value;
		 previous = states[index].previous;
		 for(i = 1; i <= n_tasks; i++) degrees[i] = states[index].degrees[i];
		 n_eligible = 0;
		 for(i = 1; i <= n_tasks; i++) {
			assert((-1 <= degrees[i]) && (degrees[i] <= n_tasks));
			if(degrees[i] == 0) {
			   eligible[++n_eligible] = i;
			}
		 }

		 gen_loads(1, cycle, 1, n_eligible);

	  } else {
		 states[index].open = 0;
	  }
	  
	  index = get_state();
   }

   search_info.bfs_bbr_cpu += (double) (clock() - start_time) / CLOCKS_PER_SEC;
   free_hash_table();
}
Exemplo n.º 6
0
void gen_loads(int depth, int remaining_time, int start, int n_eligible)
/*
   1. This function recursively generates full loads for a workstation.
*/
{
   char     LB;
   int      full_load, i, ii, j, jj, LB1, LB2, LB3, LB_bin, n, n_sub_eligible, status, stop, sub_idle, sub_remaining_time, t_unassigned;
   std::uint64_t sub_hash_value;    //changed by AS 2013/06/06
   short    *list_of_items;
   double   LB2_unassigned, LB3_unassigned;

   assert((1 <= depth) && (depth <= n_tasks));

   full_load = 1;
   for(ii = start; ii <= n_eligible; ii++) {
	  i = eligible[ii];
	  assert((1 <= i) && (i <= n_tasks) && (degrees[i] == 0));
	  if(t[i] <= remaining_time) {
		 tasks[depth] = i;
		 degrees[i] = -1;
		 n_sub_eligible = n_eligible;
		 full_load = 0;
		 stop = successors[i][0];
		 for(jj = 1; jj <= stop; jj++) {
			j = successors[i][jj];
			assert((1 <= j) && (j <= n_tasks) && (degrees[j] > 0));
			degrees[j]--;
			if(degrees[j] == 0) {
			   eligible[++n_sub_eligible] = j;
			}
		 }
	  
		 sub_remaining_time = remaining_time - t[i];
	  
		 gen_loads(depth+1, sub_remaining_time,  ii + 1, n_sub_eligible);
	  
		 // Remove previously assigned task.
	   
		 tasks[depth] = -1;
		 degrees[i] = 0;
		
		 // Increment the degree of every successor of i.
	  
		 stop = successors[i][0];
		 for(jj = 1; jj <= stop; jj++) {
			j = successors[i][jj];
			degrees[j]++;
		 }
	  }
   }

   if(full_load == 1) {

	  // If there are no tasks assigned to this station, then return.

	  if(depth == 1) return;

	  //prn_load(depth);

	  // Ignore this load if it can be pruned by a simple lower bound.
	  // Ignore this load if another task can be added.
   
	  search_info.n_generated++;
	  t_unassigned = 0;
	  LB2_unassigned = 0;
	  LB3_unassigned = 0;
	  for(i = 1; i <= n_tasks; i++) {
		 if(degrees[i] >= 0) {
			t_unassigned += t[i];
			LB2_unassigned += LB2_values[i];
			LB3_unassigned += LB3_values[i];
			if((degrees[i] == 0) && (t[i] <= remaining_time)) return;
		 }
	  }

	  // LB1

	  LB1 = (int) (station + ceil((double) t_unassigned / (double) cycle));
	  if(LB1 >= UB) {
		 return;
	  }

	  // LB2 from Sholl and Becker (2006).

	  LB2 = (int) (station + ceil(LB2_unassigned));
	  if(LB2 >= UB) {
		 return;
	  }

	  // LB3 from Sholl and Becker (2006).

	  LB3 = (int) (station + ceil(LB3_unassigned));
	  if(LB3 >= UB) {
		 return;
	  }

	  LB = (char) LB1;
	  if(LB2 > LB) LB = (char) LB2;
	  if(LB3 > LB) LB = (char) LB3;

	  // Check if a task in this station is potentially dominated by an available task.
	  // Modified 5/19/09 to call find_or_insert if a task is potentially dominated.
	  //    This reduced the number of branches, but increased the number of states stored,
	  //    so I changed it back.
   
	  for(i = 1; i <= n_tasks; i++) {
		 if(degrees[i] == 0) {
			for(jj = 1; jj <= depth-1; jj++) {
			   j = tasks[jj];
			   if((potentially_dominates[i][j] == 1) && (t[i] - t[j] <= remaining_time)) {
				  //sub_idle = idle + remaining_time;
				  //sub_hash_value = hash_value;
				  //for(i = 1; i <= depth-1; i++) sub_hash_value += hash_values[tasks[i]];
				  //sub_hash_value = sub_hash_value % HASH_SIZE;
				  //index = find_or_insert(0.0, degrees, station, LB, sub_idle, sub_hash_value, previous, 0, &status);
				  //if(status != 1) {
				  //   states[index].open = 0;
				  //}
				  return;
			   }
			}
		 }
	  }

	  // Check if there exists a task in the station that has a successor.
	  // Note: This code is not complete.  Before the load can be pruned, must also check that at least
	  // one unassigned task has a successor.
	  // Modified 5/21/09.  Do not return immediately.  Call find_or_insert first, and then set the open
	  //    status to 0 if the state was not strictly dominated.
	  //    This reduced the number of branches, but increased the number of states stored,
	  //    so I changed it back.

	  ii = 0;
	  for(jj = 1; jj <= depth-1; jj++) {
		 j = tasks[jj];
		 if(successors[j][0] > 0) {
			ii = 1;
			break;
		 }
	  }
	  if(ii == 0) {
		 for(i = 1; i <= n_tasks; i++) {
			if(degrees[i] >= 0) {
			   if(successors[i][0] > 0) {
				  ii = 1;
				  break;
			   }
			}
		 }
		 if(ii == 1) return;
	  }
 
	  sub_idle = idle + remaining_time;
	  sub_hash_value = hash_value;
	  for(i = 1; i <= depth-1; i++) sub_hash_value += hash_values[tasks[i]];
	  sub_hash_value = sub_hash_value % HASH_SIZE;
	  index = find_or_insert(0.0, degrees, station, LB, sub_idle, sub_hash_value, previous, 0, &status);
	  //if((ii == 0) && (status != 1)) {
	  //   states[index].open = 0;
	  //}
	  //if status >= 1 fprintf(1, '%2d: ', station); prnintvec(sort(find(degrees == -1)), 2); prnint(tasks, 2); end
	  assert(check_state(index) == 1);

	  // If this state has not been seen before or if it strictly dominates an existing state, then
	  // compute the bin packing lower bound.

	  if(((status == 0) || (status == 3)) && (bin_pack_flag == 1)) {
		 MALLOC(list_of_items, n_tasks+1,  short);
		 n = 0;
		 for(i = 1; i <= n_tasks; i++) {
			j = descending_order[i];
			if(degrees[j] >= 0) {
			   list_of_items[++n] = j;
			}
		 }
		 list_of_items[0] = n;
		 LB_bin = bin_dfs_bbr(list_of_items);
		 if(LB_bin < 0) bin_pack_flag = 0;
		 LB_bin += station;
		 if(LB_bin > LB) {
			LB = (char) LB_bin;
			states[index].LB = LB;
			if(LB >= UB) {
			   //prn_dfs_bbr_info(list_of_items, 0, 0, 0);
			   states[index].open = 0;
			}
		 }
		 free(list_of_items);
	  }

   }