Программа для поиска количества гамильтоновых путей в графе с учетом начальной и конечной точек

Учитывая граф с n² узлов пути и учитывая, что начальный узел всегда находится в правом верхнем углу (точка A), а конечный узел всегда находится в правом нижнем углу (точка B), мне нужно написать программу на C #, которая будет определить количество гамильтоновых путей от A до B для данного n (при условии, что n ‹= 10). Другими словами, мне нужно найти каждый путь, начинающийся в A и заканчивающийся в B, где каждый узел посещается один раз и только один раз, а перемещение между узлами ограничено влево, вправо, вверх, вниз (без диагоналей).

Например, если n = 5, то одним из возможных путей будет путь, показанный на этом изображении:

image

В идеале я хотел бы разработать интеллектуальный алгоритм, использующий некоторые эвристики, но пока мне просто нужно для начала разработать метод грубой силы. Я предполагаю, что использую поиск в ширину, но я действительно не знаю, с чего начать, чтобы реализовать это с помощью C #.


person Steve Holt    schedule 08.08.2012    source источник
comment
Какая-либо конкретная часть проблемы, которая вас больше всего озадачила? Попросить кого-нибудь просто решить проблему, вероятно, не будет слишком удачным решением.   -  person Kevin DiTraglia    schedule 08.08.2012
comment
Этот вопрос очень похож на алгоритмы stackoverflow.com/questions/5333161/ Однако разница в том, что он уже придумал решение методом грубой силы. Мне нужно сначала добраться до этой точки. Будем очень признательны за любые ссылки или псевдокод, которые помогут мне. Мне просто нужен толчок в правильном направлении.   -  person Steve Holt    schedule 09.08.2012


Ответы (1)


Какая-то штука грубой силы

Постройте график. Создайте бегун Graph. Кэшировать всю информацию о запуске. Заставьте бегуна перезапустить график и исключить все решения из информации о прогоне. Когда бегун больше не может работать, отфильтруйте кешированные данные и подсчитайте результат.

Реализация на C #

Установите тестовый фреймворк, например, nunit. напишите список необходимых вам функций.

повторяйте, пока список функций не станет пустым:

  • выберите самый мелкий объект
  • написать неудачный тест
  • написать код для прохождения теста
  • убедиться, что все тесты пройдены
  • рефакторинг, чтобы сделать притирку
  • удалить элемент из списка возможностей

Выполнено


Отредактировано, чтобы ответить на некоторые вопросы в комментариях

  • Вы можете загрузить nunit из Интернета. Распакуйте его в любую папку по вашему выбору.
  • Создайте пустое консольное приложение.
  • Изучите каталог NUnit, чтобы найти фреймворк, добавьте его в свой проект.
  • Изучите каталог NUnit, найдите GUI Runner и добавьте его в свой проект.
  • На самом деле мы не хотим запускать проект с помощью консоли, мы просто не хотим, чтобы форма автоматически создавалась, открывала свойства и повторно объявляла ваш проект как приложение Windows.
  • замените свой program.cs приведенным ниже кодом.
  • скомпилировать и запустить. нажмите "Выполнить" в графическом интерфейсе и нажмите F5, если возникнут исключения
  • поздравляю - вы только что использовали nunit

Вот программа:

using System;
using NUnit.Framework;
namespace EC_Connect_Test
{
    class Program
    {
        [STAThread]
        static void Main(string[] args)
        {
            string fullPath = System.Reflection.Assembly.GetAssembly(typeof(Program)).Location;
            NUnit.Gui.AppEntry.Main(new string[] { fullPath });
        }
    }
        public class MathClass
        {
            internal static double Divide(int A, int B)
            {
                if (B == 0) throw new DivideByZeroException();
                return (Double)A / (Double)B;
            }
        }

        [TestFixture]
        class MyFirstTestClass
        {
            [Test]
            public void DividingTwoIntegersResultIsDouble()
            {
                Double expected = 3.3;
                Double actual = MathClass.Divide(33, 10);
                Assert.AreEqual(expected, actual);
            }

            [Test]
            public void DividingByZeroShouldThrow()
            {
                Assert.Throws<DivideByZeroException>(
                    () => { MathClass.Divide(33, 0); }
                );
            }
        }

    }

Вы также можете запустить Nunit извне и передать ему свой отладочный проект в виде каталога. Таким образом, исключения не возникают, и тестирование становится проще.

Список возможностей - это просто то, что вы хотите, чтобы ваше программное обеспечение выполняло. В вашем случае вам предоставляется данный график в некоторой форме. Это может быть файл или лист бумаги. Итак, одна из функций - загрузить эту информацию и построить из нее график. Следующая особенность, о которой вы упомянули, заключается в том, что ваша программа должна проверять n ‹= 10 и отказываться работать, если это не так, это тоже особенность. Другой - вернуть результаты через заданный интерфейс. И последнее, что не менее важно, - это возможность найти все связи. Если вы перечислите их для себя, вы можете выбрать тот, который, по вашему мнению, самый простой, и начать с него.

При тестировании не забывайте создавать сквозные тесты для известных случаев. так фиксированный график на входе, известное количество на выходе.

Используя дикое предположение, ваш график находится в текстовом файле, в каждой строке которого перечислены его соединения с другими строками, вы можете написать такие тесты:

    [TestFixture]
    class graphloadingSpex
    {
        String[] lines = new String[] {
        "2,3,4",
        "1",
        "1,4",
        "1,3"
        };

        [Test]
        public void ShouldShowConnectionsAfterLoading()
        {
            Graph tested = new Graph(lines);
            Assert.AreEqual(new String[] { "2", "3", "4" }, tested["1"].GetConnextions());
            Assert.AreEqual(new String[] { "1"}, tested["2"].GetConnextions());
            Assert.AreEqual(new String[] { "1", "4" }, tested["3"].GetConnextions());
            Assert.AreEqual(new String[] { "1", "3" }, tested["4"].GetConnextions());
        }
    }

Это не будет компилироваться, поскольку Graph еще не существует. Но его компиляция и прохождение теста удовлетворили бы вашу первую функцию, и вы могли бы продолжить реализацию следующей, написав сначала тест.

person Johannes    schedule 08.08.2012
comment
Я никогда раньше не использовал какие-либо тестовые среды, поэтому я не знаком с nunit и никогда не слышал о списках функций. Что подразумевается под выбором самого маленького объекта? Каков будет процесс неудачного теста? Каков будет процесс прохождения теста? - person Steve Holt; 08.08.2012
comment
Спасибо, Йоханнес. Я попробую. - person Steve Holt; 09.08.2012