Реализовать алгоритм Краскала - Lisp

Узнай цену своей работы

Формулировка задачи:

Добрый день, друзьяшки. Помогите пожалуйста, кому не будет трудным Препод дал такое задание:
Напишите две компьютерные программы (На С++ и на lisp (или на F#)), решающие следующую задачу: Связный граф задан списком ребер. Каждое ребро представляет собой тройку (вершина, вершина, длина). Граф неориентированный. Найти минимальное остовное дерево (в виде списка образующих его ребер).
Сделал это задание на C++, но лисп вобще не знаю, можете пожалуйста написать?)
#include <iostream>
#include <list>
#include <limits>
#include <iomanip>
#include <algorithm>
#include <iterator>
#include <vector>
#include <windows.h>
using namespace std;
 
#ifdef max
#undef max
#endif
 
class Graph
{
    struct edge
    {
        unsigned vertex1, vertex2, length;
    };
 
    list<edge> graph;
    unsigned vertexes, highestVertex;
 
    void correctInput(unsigned& arg)
    {
        while (!(cin >> arg))
        {
            cout << "\nНекорректный ввод, повторите попытку:" << endl;
            cin.clear();
            cin.sync();
            cin.ignore(numeric_limits<streamsize>::max(), '\n');
        }
    }
 
    void addEdge(void)
    {
        edge tempObj;
        graph.push_back(tempObj);
        system("cls");
        cout << "Производится ввод " << graph.size()
            << "-ого ребра...\n" << endl;
        cout << "Введите 1-ую вершину:" << endl;
        correctInput(graph.back().vertex1);
        cout << "Введите 2-ую вершину:" << endl;
        correctInput(graph.back().vertex2);
        cout << "Введите вес ребра:" << endl;
        correctInput(graph.back().length);
        if (graph.back().vertex1 > highestVertex)
            highestVertex = graph.back().vertex1;
        if (graph.back().vertex2 > highestVertex)
            highestVertex = graph.back().vertex2;
        system("cls");
    }
 
public:
    static struct sortFunctor
    {
        bool operator() (const edge& arg1, const edge& arg2)
        {
            return arg1.length < arg2.length;
        }
    } sortObj;
 
    Graph(void) : vertexes(0), highestVertex(0)
    {   }
 
    Graph(unsigned arg) : vertexes(arg), highestVertex(0)
    {   }
 
    friend istream& operator>>(istream&, Graph&);
    friend ostream& operator<<(ostream&, const Graph&);
};
 
Graph::sortFunctor Graph::sortObj;
 
istream& operator>>(istream& arg1, Graph& arg2)
{
    if (!arg2.vertexes)
    {
        system("cls");
        cout << "Граф пустой, введите число его ребер:" << endl;
        arg2.correctInput(arg2.vertexes);
    }
    if (arg2.vertexes)
    {
        for (unsigned i(0); i < arg2.vertexes; i++)
            arg2.addEdge();
        system("cls");
        arg2.graph.sort(Graph::sortObj);
    }
    return arg1;
}
 
ostream& operator<<(ostream& arg1, const Graph& arg2)
{
    vector<bool> table(arg2.highestVertex, false);
    system("cls");
    cout << "Ребра минимального остовного дерева:\n" << endl;
    for (unsigned i(0); i++ < 45; cout.put('-'));
    cout.put('\n');
    cout << setw(15) << "Вершина 1" << setw(3) << '|'
        << setw(12) << "Вершина 2" << setw(7) << '|'
        << setw(8) << "Вес" << endl;
    for (unsigned i(0); i++ < 45; cout.put('-'));
    cout.put('\n');
    list<Graph::edge>::const_iterator iter(arg2.graph.begin());
    for (; iter != arg2.graph.end(); iter++)
    {
        static unsigned index1, index2;
        index1 = iter->vertex1 - 1;
        index2 = iter->vertex2 - 1;
        if (!table[index1] || !table[index2])
        {
            table[index1] = true;
            table[index2] = true;
            cout << setw(15) << iter->vertex1
                << setw(3) << '|' << setw(12) << iter->vertex2
                << setw(7) << '|' << setw(8) << iter->length << endl;
        }
    }
    for (unsigned i(0); i++ < 45; cout.put('-'));
    return arg1;
}
 
int main(void)
{
    SetConsoleCP(1251);
    SetConsoleOutputCP(1251);
    Graph gr(0);
    cin >> gr;
    cout << gr << endl;
    system("pause");
    return 0;
}

Решение задачи: «Реализовать алгоритм Краскала»

textual
Листинг программы
;; Проверить ребро
 
(defun chk-vert (v s)
  (let ((a1 (car v))
        (a2 (cadr v)))
    (not (forsome s (lambda (w) (and (member a1 w) (member a2 w)))))))
        
;; Добавление очередного ребра в "лес"        
        
(defun ins-vert (v w)        
  (let* ((a1 (car v))
         (a2 (cadr v))
         (w1 (car (remove-if-not (lambda (x) (member a1 x)) w)))
         (w2 (car (remove-if-not (lambda (x) (member a2 x)) w))))
    (cond ((and (null w1) (null w2)) (cons (butlast v) w))
          ((null w1) (cons (cons a1 w2) (remove-if (lambda (x) (member a2 x)) w)))
          ((null w2) (cons (cons a2 w1) (remove-if (lambda (x) (member a1 x)) w)))
          (t (cons (append w1 w2) (remove-if (lambda (x) (or (member a1 x) (member a2 x))) w))))))
 
 
;; Очередной шаг
    
(defun action (graph &optional (w nil) (r nil))
  (cond ((null graph) r)
        ((chk-vert (car graph) w) (action (cdr graph) (ins-vert (car graph) w) (append r (list (car graph))))) 
        (t (action (cdr graph) w r))))
        
(defun kruskal (graph)
  (let ((g (qsort-a graph (lambda (x) (nth 2 x)))))
     (action g)))

ИИ поможет Вам:


  • решить любую задачу по программированию
  • объяснить код
  • расставить комментарии в коде
  • и т.д
Попробуйте бесплатно

Оцени полезность:

8   голосов , оценка 3.5 из 5
Похожие ответы