Fix random_graph() not to generate dead states.
This is actually the third time I fix random_graph(). On 2007-02-06 I changed the function not to generated dead states, but in a way that made it non-deterministic. On 2010-01-20 I made the function deterministic again, but it started to generate dead states as a side effect. This time, I'm making sure that dead states won't come again with a test-case that we should have had from the beginning. * src/tgbaalgos/randomgraph.cc (random_graph): Add an extra indirection array, state_randomizer[], so that we can reorder states indices after a random selection without actually changing the value of the indices used by unreachable_states and nodes_to_process. * src/tgbatest/randtgba.test: New file. * src/tgbatest/Makefile.am: Add randtgba.test.
This commit is contained in:
parent
72b7deec12
commit
2183276008
4 changed files with 72 additions and 9 deletions
|
|
@ -108,6 +108,8 @@ namespace spot
|
|||
props[pi++] = dict->register_proposition(*i, res);
|
||||
|
||||
std::vector<tgba_explicit::state*> states(n);
|
||||
// Indirect access to state[] to help random selection of successors.
|
||||
std::vector<int> state_randomizer(n);
|
||||
|
||||
std::list<bdd> accs;
|
||||
bdd allneg = bddtrue;
|
||||
|
|
@ -134,11 +136,13 @@ namespace spot
|
|||
node_set unreachable_nodes;
|
||||
|
||||
states[0] = res->add_state(st(0));
|
||||
state_randomizer[0] = 0;
|
||||
nodes_to_process.insert(0);
|
||||
|
||||
for (int i = 1; i < n; ++i)
|
||||
{
|
||||
states[i] = res->add_state(st(i));
|
||||
state_randomizer[i] = i;
|
||||
unreachable_nodes.insert(i);
|
||||
}
|
||||
|
||||
|
|
@ -163,6 +167,8 @@ namespace spot
|
|||
int possibilities = n;
|
||||
while (nsucc--)
|
||||
{
|
||||
// No connection to unreachable successors so far. This
|
||||
// is our last chance, so force it now.
|
||||
if (nsucc == 0
|
||||
&& !saw_unreachable
|
||||
&& !unreachable_nodes.empty())
|
||||
|
|
@ -180,21 +186,23 @@ namespace spot
|
|||
}
|
||||
else
|
||||
{
|
||||
// Pick a random node.
|
||||
// Pick the index of a random node.
|
||||
int index = mrand(possibilities--);
|
||||
tgba_explicit::state* dest = states[index];
|
||||
|
||||
// Permute the state with states[possibilities], so we
|
||||
// cannot pick it again.
|
||||
states[index] = states[possibilities];
|
||||
states[possibilities] = dest;
|
||||
// Permute it with state_randomizer[possibilities], so
|
||||
// we cannot pick it again.
|
||||
int x = state_randomizer[index];
|
||||
state_randomizer[index] = state_randomizer[possibilities];
|
||||
state_randomizer[possibilities] = x;
|
||||
|
||||
tgba_explicit::state* dest = states[x];
|
||||
|
||||
random_labels(res, src, dest, props, props_n, t, accs, a);
|
||||
|
||||
node_set::iterator j = unreachable_nodes.find(possibilities);
|
||||
node_set::iterator j = unreachable_nodes.find(x);
|
||||
if (j != unreachable_nodes.end())
|
||||
{
|
||||
nodes_to_process.insert(possibilities);
|
||||
nodes_to_process.insert(x);
|
||||
unreachable_nodes.erase(j);
|
||||
saw_unreachable = true;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue