mCRL2
Loading...
Searching...
No Matches
DeloopSolver.cpp
Go to the documentation of this file.
1// Copyright (c) 2009-2013 University of Twente
2// Copyright (c) 2009-2013 Michael Weber <michaelw@cs.utwente.nl>
3// Copyright (c) 2009-2013 Maks Verver <maksverver@geocities.com>
4// Copyright (c) 2009-2013 Eindhoven University of Technology
5//
6// Distributed under the Boost Software License, Version 1.0.
7// (See accompanying file LICENSE_1_0.txt or copy at
8// http://www.boost.org/LICENSE_1_0.txt)
9
11#include "mcrl2/pg/attractor.h"
12
14 const ParityGame &game, ParityGameSolverFactory &pgsf,
15 const verti *vmap, verti vmap_size )
16 : ParityGameSolver(game), pgsf_(pgsf), vmap_(vmap), vmap_size_(vmap_size)
17{
18 pgsf_.ref();
19}
20
22{
23 pgsf_.deref();
24}
25
27{
28 const verti V = game_.graph().V();
30
31 mCRL2log(mcrl2::log::verbose) << "Searching for winning loops..." << std::endl;
32 DenseSet<verti> solved(0, V);
33 for (int player = 0; player < 2; ++player)
34 {
35 verti old_solved = (verti)solved.size();
36 std::deque<verti> winning;
37 for (verti v = 0; v < V; ++v)
38 {
39 if ( static_cast<int>(game_.priority(v)%2) == player &&
40 game_.graph().outdegree(v) == 1 &&
41 *game_.graph().succ_begin(v) == v )
42 {
43 assert(solved.count(v) == 0);
44 strategy[v] = game_.player(v) == player ? v : NO_VERTEX;
45 winning.push_back(v);
46 solved.insert(v);
47 }
48 }
49
50 // Compute attractor set and associated strategy:
51 for ( std::deque<verti>::const_iterator it = winning.begin();
52 it != winning.end(); ++it ) solved.insert(*it);
54 solved, winning, strategy );
55
56 verti num_solved = (verti)solved.size() - old_solved;
57 mCRL2log(mcrl2::log::verbose) << "Found " << num_solved << " vertices won by " << (player == 0 ? "Even" : "Odd" ) << std::endl;
58 }
59
60 std::vector<verti> unsolved;
61 ParityGame subgame;
62 std::vector<verti> submap; // must survive subsolver!
63 std::unique_ptr<ParityGameSolver> subsolver;
64 ParityGame::Strategy substrat;
65
66 if (solved.empty())
67 {
68 // Don't construct a subgame if it is identical to the input game:
69 mCRL2log(mcrl2::log::verbose) << "Solving game." << std::endl;
70 subsolver.reset(pgsf_.create(game_, vmap_, vmap_size_));
71 strategy = subsolver->solve();
72 }
73 else
74 if (solved.size() != V)
75 {
76 const verti num_unsolved = V - (verti)solved.size();
77 mCRL2log(mcrl2::log::verbose) << "Creating subgame with " << num_unsolved << " vertices remaining..." << std::endl;
78
79 // Create game with remaining unsolved vertices:
80 unsolved.reserve(num_unsolved);
81 for (verti v = 0; v < V; ++v)
82 {
83 if (solved.count(v) == 0) unsolved.push_back(v);
84 }
85 assert(!unsolved.empty() && unsolved.size() == num_unsolved);
86
87 subgame.make_subgame(game_, unsolved.begin(), unsolved.end(), true);
88
89 // Construct solver:
90 if (vmap_size_ > 0)
91 {
92 // Need to create merged vertex map:
93 submap = unsolved;
94 merge_vertex_maps(submap.begin(), submap.end(), vmap_, vmap_size_);
95 subsolver.reset(pgsf_.create(subgame, &submap[0], submap.size()));
96 }
97 else
98 {
99 subsolver.reset(pgsf_.create(subgame, &unsolved[0], unsolved.size()));
100 }
101
102 mCRL2log(mcrl2::log::verbose) << "Solving..." << std::endl;
103 substrat = subsolver->solve();
104 if (!substrat.empty())
105 {
106 mCRL2log(mcrl2::log::verbose) << "Merging strategies..." << std::endl;
107 merge_strategies(strategy, substrat, unsolved);
108 }
109 }
110
111 return strategy;
112}
113
115 const verti *vertex_map, verti vertex_map_size )
116{
117 return new DeloopSolver(game, pgsf_, vertex_map, vertex_map_size);
118}
std::size_t verti
type used to number vertices
Definition Graph.h:24
#define NO_VERTEX
Definition Graph.h:27
void merge_vertex_maps(ForwardIterator begin, ForwardIterator end, const verti *old_map, verti old_map_size)
void merge_strategies(std::vector< verti > &strategy, const std::vector< verti > &substrat, const std::vector< verti > &vertex_map)
player_t
Definition ParityGame.h:35
void make_attractor_set(const ParityGame &game, ParityGame::Player player, SetT &vertices, StrategyT &strategy)
ParityGameSolverFactory & pgsf_
Factory used to create subsolvers.
ParityGameSolver * create(const ParityGame &game, const verti *vertex_map, verti vertex_map_size)
Create a new DeloopSolver instance.
DeloopSolver(const ParityGame &game, ParityGameSolverFactory &pgsf, const verti *vmap, verti vmap_size)
ParityGame::Strategy solve()
const verti * vmap_
Current vertex map.
const verti vmap_size_
Size of vertex map.
ParityGameSolverFactory & pgsf_
Solver factory to use.
bool empty() const
Definition DenseSet.h:113
size_type count(const Key &k) const
Definition DenseSet.h:166
std::pair< iterator, bool > insert(const Key &k)
Definition DenseSet.h:171
size_type size() const
Definition DenseSet.h:108
virtual ParityGameSolver * create(const ParityGame &game, const verti *vertex_map=NULL, verti vertex_map_size=0)=0
const ParityGame & game_
Game being solved.
priority_t priority(verti v) const
Definition ParityGame.h:259
void make_subgame(const ParityGame &game, ForwardIterator vertices_begin, ForwardIterator vertices_end, bool proper, StaticGraph::EdgeDirection edge_dir=StaticGraph::EDGE_NONE)
Player player(verti v) const
Definition ParityGame.h:262
const StaticGraph & graph() const
Definition ParityGame.h:256
std::vector< verti > Strategy
Definition ParityGame.h:97
void deref() const
Decrement reference count and delete the object if it becomes zero.
Definition RefCounted.h:39
void ref() const
Increment reference count.
Definition RefCounted.h:36
const_iterator succ_begin(verti v) const
Definition Graph.h:188
verti V() const
Definition Graph.h:179
edgei outdegree(verti v) const
Definition Graph.h:223
#define mCRL2log(LEVEL)
mCRL2log(LEVEL) provides the stream used to log.
Definition logger.h:391
@ verbose
Definition logger.h:37