1

Я ищу простую реализацию алгоритма планировщика/поиска, реализованного в качестве шаблонов времени компиляции C++. Приложение для такой вещи частично академическое, отчасти обусловленное практическими потребностями в проверке кода.Многопользовательский аргумент в шаблонах C++

Вот сущность того, что я ищу: Представьте алгоритм поиска для планирования действий из состояния «Пуск» в состояние «Конец».

template<A, B> struct Step{ 
    //all steps have: 
    static void doAction(); 
} 


struct Start{}; 
struct State1{}; 
struct State2{}; 
struct End{}; 


//Transition between neighbor-states is known: 

template<> struct<Start, State1>{ 
    static void doAction(){ 
     std::cout << "Start -> State1" << std::endl; 
    } 
}; 

template<> struct<State1, State2>{ 
    static void doAction(){ 
     std::cout << "State1 -> State2" << std::endl; 
    } 
}; 

template<> struct<State2, End>{ 
    static void doAction(){ 
     std::cout << "State2 -> End" << std::endl; 
    } 
}; 

Теперь я хотел бы использовать магию шаблонов, чтобы найти последовательность шагов (с использованием SFINAE или другие приемы). Как можно добиться следующего?

//TODO: Implement a reasoner: 
template<typename A, typename B, typename C> struct Step<A,C>{ 
    typedef Step<A,B> S1; 
    typedef Step<B,C> S2; 

    static void doAction(){ 
     S1::doAction(); 
     S2::doAction(); 
    } 
}; 


// Code using it: 
Step<Start, State1>::doAction(); //Expect: "Start -> State1" 

Step<Start, State2>::doAction(); // Expect: "Start -> State1" 
           //   "State1 -> State2" 

Step<Start, End>::doAction(); // Expect: "Start -> State1" 
           //   "State1 -> State2" 
           //   "State2 -> End" 
+0

Несмотря на все ваши усилия, вопрос выглядит еще туманны. Но интригующе. Попробуем уточнить его. Как выглядит «результат»? – marom

+0

Нахождение единственного уникального решения, вероятно, выполнимо (грубая сила). «Самое короткое» решение звучит как кошмар. – MSalters

+0

Единственное уникальное решение подходит для счета. Его не нужно оптимизировать. Идея состоит в том, чтобы убедиться в некоторых свойствах во время компиляции. – user1362700

ответ

0

Это, вероятно, лучше всего решить в обратном направлении. Определите Path<End>::cost == 0 и рассуждая назад Path<State2,End>::cost==Path<End>::cost + 1, потому что есть Step<State2,End>.

Ваш PathFinder алгоритм потребуется список всех государств рассмотреть, хотя: он не может обнаружить их дали свое определение состояний и Step<>

+0

Если есть большой набор состояний и несколько переходов между ними, то компилятор должен иметь возможность ответить если можно перейти из одного состояния в другое государство. Можете ли вы рассказать о том, как достичь этого, используя свой подход? Спасибо за вашу помощь! – user1362700

+0

@ user1362700: Идея состоит в том, что два пути связаны тогда и только тогда, когда есть класс «Путь <начало, ..., конец>». Вот почему вам нужен этот список состояний. Учитывая 'Path <..., S1>', вы определяете 'Path <...,S1,S2>' if 'Step ' существует. В качестве оптимизации вы можете удалить состояния из открытого списка, как только вы их достигнете. Это довольно простое функциональное программирование. – MSalters

Смежные вопросы