Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > IT форум > Помощь студентам
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 01.12.2022, 14:17   #1
Шляпадляменя
Пользователь
 
Регистрация: 01.12.2022
Сообщений: 18
По умолчанию Реализовать метод ветвей и границ

помогите написать программу по псевдокоду
Реализовать алгоритм, находящий оптимальное (точное) решение задачи коммивояжера с помощью метода ветвей и границ.
Решение методом ветвей и границ:
Код:
Length(Path) - возвращает длину маршрута Path
MinPath(P1, P2) - из двух маршрутов возвращает кратчайший маршрут
LowerBound(G, S) - возвращает нижнюю оценку длины маршрута в графе G для подмножества решений S
G - граф, start - стартовая вершина
TSP_BnB(G, start):
    BestPath = некоторое эвристическое решение или ∅
    Visited = {start} - список пройденных вершин
    Вернуть BnB(G, Visited, BestPath)
 
BnB(G, Visited, BestPath):
    Если Visited содержит все вершины графа G:        
        Вернуть MinPath(BestPath, Visited)
    Для каждой вершины v графа G не из Visited:
        VNext = Visited + {v}
Если LowerBound(VNext) < Length(BestPath):
Path = BnB(G, VNext, BestPath)
        BestPath = MinPath(BestPath, Path)
    Вернуть BestPath
где граф представлен в виде:
graph.h
Код:
#include <map>
#include <vector>
#include <tuple>
#include <initializer_list>

/**
 * Non-oriented weighted graph.
**/
class Graph {
public:
    Graph() {}
    Graph(std::initializer_list<std::tuple<int, int, double>> edges);

    /// Add single vertex to the graph.
    void add_vertex(int vertex);

    /// Add vertices (if necessary) and an edge between them to the graph.
    void add_edge(int start_vertex, int end_vertex, double weight = 1.0);

    /// Return all vertices of the graph.
    std::vector<int> get_vertices() const;

    /// Return all adjacent by edges vertices for the specified vertex.
    std::vector<int> get_adjacent_vertices(int src_vertex) const;

    /// Get adjacent edges for the vertex as vector of (end vertex, edge weight).
    std::vector<std::pair<int, double>> get_adjacent_edges(int src_vertex) const;

    /// Return true if the vertex exists in the graph, false otherwise.
    bool has_vertex(int vertex) const;

    /// Return true if vertices exist and have an edge between them, false otherwise.
    bool has_edge(int start_vertex, int end_vertex) const;

    /// Return weight of an edge between vertices (if there is any), throw an exception otherwise.
    double edge_weight(int start_vertex, int end_vertex) const;

    /// Remove the vertex and all its adjacent edges from the graph.
    void remove_vertex(int vertex);

    /// Remove the edge from the graph (but not the vertices).
    void remove_edge(int start_vertex, int end_vertex);

private:
    std::map<int, std::map<int, double>> vertices;
};
Код:
#include "graph.h"

#include <stdexcept>

using namespace std;

Graph::Graph(initializer_list<tuple<int, int, double>> edges) {
    for (const auto& e : edges) {
        add_edge(get<0>(e), get<1>(e), get<2>(e));
    }
}

void Graph::add_vertex(int vertex) {
    if (!has_vertex(vertex)) {
        vertices[vertex] = std::map<int, double>();
    }
}

void Graph::add_edge(int start_vertex, int end_vertex, double weight) {
    add_vertex(start_vertex);
    add_vertex(end_vertex);
    vertices[start_vertex][end_vertex] = weight;
    vertices[end_vertex][start_vertex] = weight;
}

std::vector<int> Graph::get_vertices() const {
    std::vector<int> result;
    for (const auto& p : vertices) {
        result.push_back(p.first);
    }
    return result;
}

std::vector<int> Graph::get_adjacent_vertices(int src_vertex) const {
    const auto it = vertices.find(src_vertex);
    if (it == vertices.end()) {
        return std::vector<int> {};
    }
    vector<int> result;
    for (const auto& p : it->second) {
        result.push_back(p.first);
    }
    return result;
}

vector<pair<int, double>> Graph::get_adjacent_edges(int src_vertex) const {
    const auto it = vertices.find(src_vertex);
    if (it == vertices.end()) {
        return vector<pair<int, double>> {};
    }
    vector<pair<int, double>> result;
    for (const auto& p : it->second) {
        result.push_back(make_pair(p.first, p.second));
    }
    return result;
}

bool Graph::has_vertex(int vertex) const {
    return (vertices.find(vertex) != vertices.end());
}

bool Graph::has_edge(int start_vertex, int end_vertex) const {
    const auto it = vertices.find(start_vertex);
    if (it == vertices.end()) {
        return false;
    }
    return (it->second.find(end_vertex) != it->second.end());
}

double Graph::edge_weight(int start_vertex, int end_vertex) const {
    const auto it_s = vertices.find(start_vertex);
    if (it_s == vertices.end()) {
        throw invalid_argument("Edge doesn't exist");
    }
    const auto it_e = it_s->second.find(end_vertex);
    if (it_e == it_s->second.end()) {
        throw invalid_argument("Edge doesn't exist");
    }
    return it_e->second;
}

void Graph::remove_vertex(int vertex) {
    /// Remove adjacent edges.
    auto adjacent_vertices = get_adjacent_vertices(vertex);
    for (const auto& adj_v : adjacent_vertices) {
        remove_edge(adj_v, vertex);
    }
    /// Remove the vertex itself.
    vertices.erase(vertex);
}

void Graph::remove_edge(int start_vertex, int end_vertex) {
    auto it_s = vertices.find(start_vertex);
    if (it_s != vertices.end()) {
        it_s->second.erase(end_vertex);
    }
    auto it_e = vertices.find(end_vertex);
    if (it_e != vertices.end()) {
        it_e->second.erase(start_vertex);
    }
}
Не понимаю как решать.Обращаюсь как к последней инстанции
Шляпадляменя вне форума Ответить с цитированием
Старый 08.12.2022, 12:41   #2
Шляпадляменя
Пользователь
 
Регистрация: 01.12.2022
Сообщений: 18
По умолчанию

Решение методом ветвей и границ:
Length(Path) - возвращает длину маршрута Path
MinPath(P1, P2) - из двух маршрутов возвращает кратчайший маршрут
LowerBound(G, S) - возвращает нижнюю оценку длины маршрута в графе G для подмножества решений S
G - граф, start - стартовая вершина
TSP_BnB(G, start):
BestPath = некоторое эвристическое решение или ∅
Visited = {start} - список пройденных вершин
Вернуть BnB(G, Visited, BestPath)

BnB(G, Visited, BestPath):
Если Visited содержит все вершины графа G:
Вернуть MinPath(BestPath, Visited)
Для каждой вершины v графа G не из Visited:
VNext = Visited + {v}
Если LowerBound(VNext) < Length(BestPath):
Path = BnB(G, VNext, BestPath)
BestPath = MinPath(BestPath, Path)
Вернуть BestPath

LowerBound(G, Visited):
Для каждой вершины графа G найти два смежных с ней ребра с минимальным весом, с учетом уже построенной части маршрута Visited: ребра, входящие в маршрут, рассматриваются в первую очередь
Вернуть сумму весов таких двух ребер для каждой вершины по всем вершинам графа G, поделенную на 2

Код:
vector<int>TSP_BnB(const Graph& G, int start) {
    vector<int>BestPath; // некоторое эвристическое решение или ∅;
   vector<int> Visited = { start }; //список пройденных вершин
        return BnB(G, Visited, BestPath);
}
vector<int> BnB(const Graph& G, vector<int>Visited, vector<int>BestPath) {
    vector<int> Path;
    if (find(Visited.begin(), Visited.end(), G.get_vertices()) != Visited.end())
        return MinPath(BestPath, Visited);
    vector<int>Q = G.get_vertices();
    for (int v = 0; v < Q.size(); v++)                //Для каждой вершины v графа G не из Visited :
        VNext = Visited + {v};
    if (LowerBound(VNext) < Length(BestPath)) {
        Path = BnB(G, VNext, BestPath);
        BestPath = MinPath(BestPath, Path);
    }
    return BestPath;
}
vector<int> LowerBound(const Graph& G, vector<int>Visited) {
    vector<int>Q = G.get_vertices();
    for (int i = 0; Q.size(); i++) {
        if()
    }
   // Для каждой вершины графа G найти два смежных с ней ребра с минимальным весом, с учетом уже построенной части маршрута Visited : 
   // ребра, входящие в маршрут, рассматриваются в первую очередь
        //Вернуть сумму весов таких двух ребер для каждой вершины по всем вершинам графа G, поделенную на 2
}
Шляпадляменя вне форума Ответить с цитированием
Старый 08.12.2022, 12:42   #3
Шляпадляменя
Пользователь
 
Регистрация: 01.12.2022
Сообщений: 18
По умолчанию

что такое "некоторое эвристическое решение или ∅" ?
Шляпадляменя вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
задача коммивояжера метод ветвей и границ alesya-san Помощь студентам 0 07.01.2017 18:30
Задача коммивояжера(метод ветвей и границ) merick Помощь студентам 5 16.06.2016 23:13
метод ветвей и границ в c# Альберт0 C# (си шарп) 1 24.03.2015 17:20
метод ветвей и границ на с++ kirillkucelap Помощь студентам 1 13.10.2014 22:09
Коммивояжера метод ветвей и границ kop Помощь студентам 2 21.10.2011 23:30