对于网络优化问题,有许多不同的算法可以解决。以下是一些常见的高效网络优化算法及其源代码:

  1. 最小生成树(MST)算法:Kruskal、Prim

Kruskal算法:

def kruskal(graph):
    parent = {}
    rank = {}

    def make_set(node):
        parent[node] = node
        rank[node] = 0

    def find(node):
        if parent[node] != node:
            parent[node] = find(parent[node])
        return parent[node]

    def union(node1, node2):
        root1 = find(node1)
        root2 = find(node2)
        if root1 != root2:
            if rank[root1] > rank[root2]:
                parent[root2] = root1
            else:
                parent[root1] = root2
                if rank[root1] == rank[root2]:
                    rank[root2] += 1

    for node in graph['vertices']:
        make_set(node)

    minimum_spanning_tree = set()
    edges = list(graph['edges'])
    edges.sort()
    for edge in edges:
        weight, node1, node2 = edge
        if find(node1) != find(node2):
            union(node1, node2)
            minimum_spanning_tree.add(edge)

    return minimum_spanning_tree

Prim算法:

import heapq

def prim(graph, start_node):
    visited = set()
    heap = [(0, start_node)]
    minimum_spanning_tree = set()

    while heap:
        (weight, current_node) = heapq.heappop(heap)
        if current_node not in visited:
            visited.add(current_node)
            minimum_spanning_tree.add((weight, current_node))
            for neighbor, neighbor_weight in graph[current_node].items():
                if neighbor not in visited:
                    heapq.heappush(heap, (neighbor_weight, neighbor))

    return minimum_spanning_tree
  1. 最短路径算法:Dijkstra、Bellman-Ford、Floyd-Warshall

Dijkstra算法:

import heapq

def dijkstra(graph, start_node):
    distances = {node: float('inf') for node in graph}
    distances[start_node] = 0
    heap = [(0, start_node)]

    while heap:
        (current_distance, current_node) = heapq.heappop(heap)

        if current_distance > distances[current_node]:
            continue

        for neighbor, weight in graph[current_node].items():
            distance = current_distance + weight

            if distance < distances[neighbor]:
                distances[neighbor] = distance
                heapq.heappush(heap, (distance, neighbor))

    return distances

Bellman-Ford算法:

def bellman_ford(graph, start_node):
    distances = {node: float('inf') for node in graph}
    distances[start_node] = 0

    for _ in range(len(graph) - 1):
        for node in graph:
            for neighbor, weight in graph[node].items():
                if distances[node] + weight < distances[neighbor]:
                    distances[neighbor] = distances[node] + weight

    # check for negative cycles
    for node in graph:
        for neighbor, weight in graph[node].items():
            if distances[node] + weight < distances[neighbor]:
                raise ValueError('Negative cycle detected')

    return distances

Floyd-Warshall算法:

def floyd_warshall(graph):
    distances = dict(graph)

    for k in graph:
        for i in graph:
            for j in graph:
                distances[i][j] = min(distances[i][j], distances[i][k] + distances[k][j])

    return distances
  1. 最大流算法:Ford-Fulkerson、Edmonds-Karp、Dinic

Ford-Fulkerson算法:

def ford_fulkerson(graph, source, sink):
    def bfs(graph, source, sink):
        visited = {node: False for node in graph}
        visited[source] = True
        queue = [source]

        while queue:
            node = queue.pop(0)
            for neighbor, capacity in graph[node].items():
                if not visited[neighbor] and capacity > 0:
                    visited[neighbor] = True
                    queue.append(neighbor)
                    if neighbor == sink:
                        return True

        return False

    flow = 0
    while bfs(graph, source, sink):
        path_flow = float('inf')
        node = sink
        while node != source:
            path_flow = min(path_flow, graph[parent[node]][node])
            node = parent[node]

        flow += path_flow
        node = sink
        while node != source:
            graph[parent[node]][node] -= path_flow
            graph[node][parent[node]] += path_flow
            node = parent[node]

    return flow

Edmonds-Karp算法:

def edmonds_karp(graph, source, sink):
    def bfs(graph, source, sink):
        parent = {node: None for node in graph}
        parent[source] = source
        queue = [source]

        while queue:
            node = queue.pop(0)
            for neighbor, capacity in graph[node].items():
                if parent[neighbor] is None and capacity > 0:
                    parent[neighbor] = node
                    queue.append(neighbor)
                    if neighbor == sink:
                        return parent

        return None

    max_flow = 0
    parent = bfs(graph, source, sink)
    while parent is not None:
        path_flow = float('inf')
        node = sink
        while node != source:
            path_flow = min(path_flow, graph[parent[node]][node])
            node = parent[node]

        max_flow += path_flow
        node = sink
        while node != source:
            graph[parent[node]][node] -= path_flow
            graph[node][parent[node]] += path_flow
            node = parent[node]

        parent = bfs(graph, source, sink)

    return max_flow

Dinic算法:

from collections import deque

def dinic(graph, source, sink):
    def bfs(graph, source, sink, level):
        queue = deque([source])
        level[source] = 0

        while queue:
            node = queue.popleft()
            for neighbor, capacity in graph[node].items():
                if level[neighbor] < 0 and capacity > 0:
                    level[neighbor] = level[node] + 1
                    queue.append(neighbor)

        return level[sink] >= 0

    def dfs(graph, source, sink, level, blocking_flow):
        if source == sink:
            return blocking_flow

        flow = 0
        for neighbor, capacity in graph[source].items():
            if level[neighbor] == level[source] + 1 and capacity > 0:
                current_flow = dfs(graph, neighbor, sink, level, min(blocking_flow, capacity))
                graph[source][neighbor] -= current_flow
                graph[neighbor][source] += current_flow
                flow += current_flow
                blocking_flow -= current_flow

                if blocking_flow == 0:
                    break

        return flow

    max_flow = 0
    level = [-1] * (len(graph) + 1)
    while bfs(graph, source, sink, level):
        current_flow = dfs(graph, source, sink, level, float('inf'))
        while current_flow > 0:
            max_flow += current_flow
            current_flow = dfs(graph, source, sink, level, float('inf'))

        level = [-1] * (len(graph) + 1)

    return max_flow
高效的网络优化算法源代码 - Kruskal、Prim、Dijkstra 等

原文地址: https://www.cveoy.top/t/topic/nCYT 著作权归作者所有。请勿转载和采集!

免费AI点我,无需注册和登录