Алгоритм Каргера
Рандомизированный алгоритм для эффективного нахождения минимального разреза в связанном графе. Изобретен Девидом Каргером и опубликован в 1993 году. Листинг кода программы, его реализация. Определение количества рёбер графа. Примеры работы программы.
Рубрика | Программирование, компьютеры и кибернетика |
Вид | практическая работа |
Язык | русский |
Дата добавления | 11.06.2020 |
Размер файла | 197,2 K |
Отправить свою хорошую работу в базу знаний просто. Используйте форму, расположенную ниже
Студенты, аспиранты, молодые ученые, использующие базу знаний в своей учебе и работе, будут вам очень благодарны.
Размещено на http://www.allbest.ru/
Алгоритм Каргера
Постановка задачи:
Алгоритм Каргера - это рандомизированный алгоритм для эффективного нахождения минимального разреза в связанном графе.
Я решила реализовать его через задачу поиска минимального разреза графа, написанную на языке Java. В виде таблицы смежности в текстовый файл пользователем задаётся исходный граф. Программа проводит нужные вычисления и выводит в консоль минимальный разрез графа.
Описание алгоритма:
Алгоритм Каргера - это вероятностный алгоритм в информатике и теории графов, позволяющий найти минимальный разрез связного графа. Сам алгоритм изобретен Девидом Каргером, опубликован в 1993 году. Идея данного алгоритма основана на стягивании ребра в неориентированном графе. Во время стягивания ребра происходит объединение двух вершин в одну, что уменьшает количество вершин графа на единицу. Все рёбра стягиваемых вершин соединяются со вновь образованной вершиной, порождая мультиграф. Алгоритм Каргера итеративно выбирает случайные рёбра и выполняет операцию до тех пор, пока не останется две вершины, которые и представляют собой разрез изначального графа. Если повторять алгоритм достаточное количество раз, то с высокой вероятностью может быть найден минимальный разрез.
Псевдокод:
повторить n ? 2 раза
выбрать случайно ребро e
стянуть ребро e
результат число рёбер между двумя последними вершинами
Пояснение к псевдокоду:
Для нахождения минимального разреза связного графа, алгоритм выбирает случайное ребро, стягивает две вершины этого ребра в одну вершину и повторяет это действие пока не останется две вершины. Количество рёбер между последними двумя вершинами и будет являться минимальным разрезом. Однако так как алгоритм Каргера является вероятностным алгоритмом, то его следует повторять большое количество раз для получение наиболее точного ответа.
Рис.1 Иллюстрация стягивания двух вершин ребра в одну.
Рис.2 Пошаговая иллюстрация работы алгоритма.
Реализация:
Листинг кода программы с комментариями:
package com.company;
import java.io.IOException;
import java.io.File;
import java.util.Random;
import java.util.HashMap;
import java.util.ArrayList;
import java.io.FileReader;
import java.io.BufferedReader;
public class Main {
public static int Karger(HashMap<Integer, ArrayList<Integer" database, ArrayList<Integer> tops)
{
//mark для сжатых ребер
int mark = database.size() + 1;
while (tops.size() > 2)//Перебираем граф, пока не останется 2 вершины
{
int numOfEdges = NumberOfEdges(database, tops); //Количество рёбер
int[][] edges = EdgesMatrix(numOfEdges, database, tops); //Определяем двумерный массив рёбер
Random rand = new Random();
int num = rand.nextInt(edges.length); //Случайно выбираем ребро графа
//Первая вершина случайного ребра
int top1 = edges[num][0];
//Вторая вершина случайного ребра
int top2 = edges[num][1];
ArrayList<Integer> arrayTop1 = database.get(top1);
ArrayList<Integer> arrayTop2 = database.get(top2);
arrayTop1.addAll(arrayTop2);
tops.remove((Integer) top2);
database.remove(top2);
// Присвоим top1 новую mark и меняем все mark вершины 1 или вершины 2 на новые
for (Integer top : tops) {
ArrayList<Integer> values = database.get(top);
for (int j = 0; j < values.size(); j++) {
if (values.get(j) == top1)
values.set(j, mark);
if (values.get(j) == top2)
values.set(j, mark);
}
}
//Изменим mark ключевого узла top1 в таблице смежности
ArrayList<Integer> values = database.get(top1);
database.remove(top1);
database.put(mark, values);
//Изменить mark top1 в вершинах массива ArrayList
int index = tops.indexOf(top1);
tops.set(index, mark);
//Удалим петли
int position = 0;
int length = database.get(mark).size();
while (position < length)
{
if(database.get(mark).get(position) == mark)
{
database.get(mark).remove(position);
length--;
}
else
position++;
}
mark++;
}
return database.get(tops.get(0)).size();
}
public static void ReadDataBase(HashMap<Integer, ArrayList<Integer" database, ArrayList<Integer> tops) throws IOException
{
File file = new File(System.getProperty("user.dir") + "/database.txt");
try (BufferedReader input = new BufferedReader(new FileReader(file))) {
String line = input.readLine();
while (line != null) {
String[] vector = line.split(" ");
int key = Integer.parseInt(vector[0]);
tops.add(key);
//Перевод строк файла в числа для списка рёбер
ArrayList<Integer> edges = new ArrayList<>();
for (int i = 0; i < vector.length - 1; i++)
if (Integer.parseInt(vector[i + 1]) != key)
edges.add(Integer.parseInt(vector[i + 1]));
//Сохраняем в "базу данных"(таблица смежности) значения полученные из фала
database.put(key, edges);
line = input.readLine();
}
}
}
public static void main(String[] arg) throws IOException
{
HashMap<Integer, ArrayList<Integer" database = new HashMap<>();
ArrayList<Integer> tops = new ArrayList<>();
ReadDataBase(database, tops);
//В начале основной минимум равен n * n, где n = колличество узлов в графе
int finalMinimum = database.size() * database.size();
for(int i = 0; i < database.size(); i++)
{
int minimumCut = Karger(database, tops);
int iTry = i+1;
System.out.println("Попытка номер " + iTry + ": " + minimumCut);
if(minimumCut < finalMinimum)
finalMinimum = minimumCut;
//Очищаем "базу данных"(таблицу смежности) и массив вершин
database.clear();
tops.clear();
ReadDataBase(database, tops);
}
System.out.println("\n Минимальный разрез: " + finalMinimum);
}
//Зная число рёбер графа, таблицу смежности и его вершины, определяем рёбра графа
public static int[][] EdgesMatrix(int numOfEdges, HashMap<Integer, ArrayList<Integer" database, ArrayList<Integer> tops)
{
int k = 0;
int[][] edges = new int[numOfEdges][2];
for (Integer top : tops) {
ArrayList<Integer> vector = database.get(top);
for (Integer integer : vector) {
edges[k][0] = top;
edges[k][1] = integer;
k++;
}
}
return edges;
}
//Зная таблицу смежности и вершины, определяем колличество рёбер графа
public static int NumberOfEdges(HashMap<Integer, ArrayList<Integer" database, ArrayList<Integer> tops)
{
int numOfEdges = 0;
for (Integer top : tops) {
ArrayList<Integer> vector = database.get(top);
numOfEdges += vector.size();
}
return numOfEdges;
}
}
Примеры работы программы:
Рис.3 Исходный граф, представленный в виде таблицы смежности в текстовом файле.
Рис.4 Вывод программы в консоль результатов 8 попыток использования алгоритма Каргера на исходном графе и вывод ответа - минимального разреза
Можно сравнить результат работы программы со своими собственными вычислениями (найти минимальный разрез графа любым другим способом). Ответ оказался верным, действительно минимальный разрез для исходного графа равен 2. программа код алгоритм
Вывод:
В данной работе я познакомилась с вероятностным алгоритмом Каргера, реализовав его на Java. Я использовала текстовый ввод графа в виде таблицы смежности и после вычислений программа вывела в консоль значение минимального разреза. Алгоритм довольно эффективный и простой в реализации.
Список использованной литературы
1. https://e-maxx.ru/algo/stoer_wagner_mincut
2. https://neerc.ifmo.ru/wiki/index.php?title=%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%9A%D0%B0%D1%80%D0%B3%D0%B5%D1%80%D0%B0_%D0%B4%D0%BB%D1%8F_%D0%BD%D0%B0%D1%85%D0%BE%D0%B6%D0%B4%D0%B5%D0%BD%D0%B8%D1%8F_%D0%BC%D0%B8%D0%BD%D0%B8%D0%BC%D0%B0%D0%BB%D1%8C%D0%BD%D0%BE%D0%B3%D0%BE_%D1%80%D0%B0%D0%B7%D1%80%D0%B5%D0%B7%D0%B0
3. http://ru.knowledgr.com/04287640/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC%D0%9A%D0%B0%D1%80%D0%B3%D0%B5%D1%80%D0%B0
4. https://www.geeksforgeeks.org/kargers-algorithm-for-minimum-cut-set-1-introduction-and-implementation/
5. https://ru.wikipedia.org/wiki/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%9A%D0%B0%D1%80%D0%B3%D0%B5%D1%80%D0%B0
6. https://medium.com/@dev.elect.iitd/kargers-algorithm-d8067eb1b790
Размещено на Allbest.ru
...Подобные документы
Приемы программирования в Delphi. Алгоритм поиска альфа-бета отсечения, преимущества. Описание программного средства. Разработка программы, реализующая алгоритм игры "реверси". Руководство пользователя. Листинг программы. Навыки реализации алгоритмов.
курсовая работа [357,1 K], добавлен 28.02.2011Создание системы, осуществляющей запуск программы по расписанию, которое хранится в реестре. Методы и средства взаимодействия с аппаратными и программными средствами, типы интерфейсов. Алгоритм работы и листинг программы, проверка ее работоспособности.
курсовая работа [78,6 K], добавлен 13.11.2009Характеристика программы на языке VBA, которая вводит исходные данные, выполняет расчеты и выводит результаты на экран. Описание переменных в программе, ее блок-схема и алгоритм работы. Листинг программы. Описание входных данных и результат вычислений.
курсовая работа [721,4 K], добавлен 10.11.2010Понятие и сущность графы, методы решения задач по поиску кратчайших путей в ней. Особенности составления программного кода на языке программирования Pascal с использованием алгоритма Форда-Беллмана, а также порядок ее тестирования с ручным просчетом.
курсовая работа [1,2 M], добавлен 31.07.2010Составление алгоритма и программы для факторизации целого числа N с помощью ро-метода Полларда. Краткое описание данного метода: составление последовательности, вычисление разности и наибольшего общего делителя. Алгоритм работы и листинг программы.
курсовая работа [12,1 K], добавлен 24.06.2010Методы решения задачи о ранце. Алгоритм неявного лексикографического перебора. Разработка структуры данных, реализация алгоритма с её использованием, программная реализация. Проведение тестовой проверки. Входной и выходной файл, листинг программы.
курсовая работа [408,8 K], добавлен 22.10.2012Области применения теории графов. Алгоритм решения задачи поиска инвариантного и полного графа. Реализация программы с графическим интерфейсом пользователя на основе алгоритма. Реализация редактора графа и вывод полученных результатов в понятной форме.
курсовая работа [493,3 K], добавлен 27.12.2008Разработка алгоритма реализации на ЭВМ процесса поиска кратчайшего пути в графе методом Дейкстры. Программная реализация алгоритма поиска кратчайшего пути между двумя любыми вершинами графа. Проверка работоспособности программы на тестовых примерах.
реферат [929,8 K], добавлен 23.09.2013Особенности языка "Си шарп". Содержательная постановка программы. Описание классов и структур. Алгоритм и логики работы программы, переменные. Тестирование, инструкция пользователю. Пример удаления записи о читателе. Общий вид листинга программы.
курсовая работа [360,3 K], добавлен 21.11.2013Разработка программы для работы с последовательностью прописных латинских букв. Алгоритм программы, результаты ее работы и вывод о работоспособности. Поиск количества вхождений элементов одной строки в другую. Тестирование программы, ее результаты.
лабораторная работа [858,0 K], добавлен 23.11.2014Теория графов и её применения. Разработка программного продукта для решения задач нахождения минимального пути. Анализ надежности и качества ПП "метода Дейкстры". Математическая модель задачи. Алгоритмы Дейкстры на языке программирования Turbo Pascal.
курсовая работа [1,6 M], добавлен 26.03.2013Теоретическое обоснование теории графов. Методы нахождения медиан графа. Задача оптимального размещения насосной станции для полива полей. Алгоритм Флойда, поиск суммарного расстояния до вершин. Функция нахождения индекса минимального значения в массиве.
курсовая работа [336,8 K], добавлен 28.05.2016Описание языка программирования Java: общие характеристики, главные свойства, краткий обзор. Надежность и безопасность, производительность и базовая система программы. Разработка программы поиска по словарю, алгоритм её работы. Общий вид кода программы.
курсовая работа [20,3 K], добавлен 28.10.2012Написание программы, реализующей алгоритм RLE, позволяющий кодировать, декодировать файлы любого формата и размера, предоставлять пользователю информацию о степени их сжатия. Анализ эффективности кода. Экспериментальная оценка алгоритма программы.
контрольная работа [151,7 K], добавлен 29.05.2013Алгоритм работы программы, которая выполняет записи в log-файл действий, идентифицированных как попытки атаки на страницу авторизации пользователей условного ресурса. Макет веб-сайта, листинги файлов программы и процесс ее взаимодействия с СУБД MySQL.
курсовая работа [1,3 M], добавлен 22.06.2015Разработка программы игры в крестики-нолики. Примеры игровой ситуации на игровом поле. Описание входных и выходных данных, переменных и функций программы. Реализация алгоритма работы программы на языке C++. Текст программы и примеры ее выполнения.
курсовая работа [352,8 K], добавлен 14.04.2011Анализ алгоритмов нахождения кратчайших маршрутов в графе без отрицательных циклов: Дейкстры, Беллмана-Форда и Флойда-Уоршалла. Разработка интерфейса программы на языке C++. Доказательство "правильности" работы алгоритма с помощью математической индукции.
курсовая работа [1,5 M], добавлен 26.07.2013Особенности разработки программы и выбор методов решения задачи. Составление алгоритма, распределение регистров программы и формирование файлов. Описание процедуры очистки памяти, сложения, вычитания, умножения. Тестирование и листинг программы.
лабораторная работа [51,2 K], добавлен 14.05.2011Практическое использование алгоритмов для нахождения минимального пути в лабиринте. Разработка программы на языке С++ и в среде Visual C++. Основные способы поиска пути: метод волны и приоритетов. Описание разработанных функций и инструкция пользователя.
дипломная работа [54,3 K], добавлен 16.03.2012Программа на языке VBA, которая выводит исходные данные на экран и выполняет расчеты и предназначена для учета на складе мастерской индивидуального пошива. Описание переменных и алгоритма программы. Листинг программы, примеры произведенных расчетов.
реферат [25,4 K], добавлен 10.12.2010