目錄
使用的方法
加權乘積的改進Dijkstra演算法
演算法
範例
輸出
修改後的帶有加權乘積的Bellman-Ford演算法
結論
首頁 後端開發 C++ 具有權重大於等於1的邊的最小乘積路徑

具有權重大於等於1的邊的最小乘積路徑

Aug 30, 2023 am 11:37 AM
權重 路徑

具有權重大於等於1的邊的最小乘積路徑

為了發現具有權重大於或等於1的最小邊的路徑,我們可以使用稍作修改的Dijkstra演算法。首先,我們將來源節點的權重設為1,將其他節點的權重設為無限大。在演算法執行過程中,我們不再更新距離,而是更新權重的乘積。這樣可以確保選擇具有最小權重的路徑。透過在每一步選擇權重最小的節點,我們迭代地發現最短路徑,直到達到目標節點。最後,沿著這條路徑的權重乘積將是最小的,滿足給定的條件。

使用的方法

  • 修改後的Dijkstra演算法,帶有加權乘積

  • 修改的Bellman-Ford演算法,帶有加權乘積

加權乘積的改進Dijkstra演算法

在修改後的Dijkstra演算法中,我們首先將來源節點的權重設為無窮大,將所有其他節點的權重也設為無限大。在執行計算的過程中,我們不是用所有權重來更新距離,而是用到目前為止遇到的權重的乘積來更新它們。在每一步中,我們選擇具有最小權重的節點,並以相同的方式更新其相鄰節點的權重。這個過程一直持續到達目標節點。最終,沿著這條路徑的權重乘積將表示最小可能值,滿足權重大於或等於1的條件。

演算法

  • 將所有中心權重初始化為無限大,除了來源中心,其權重設為0。

  • 建立一個清除集合來追蹤已刪除的節點。

  • 當存在未存取的節點時,

    • 選擇未存取節點中權重最小的中心。

    • 將所選中心標記為已存取。

    • 對於每個未訪問的相鄰樞紐:

    • 計算目前中心節點的權重和與之相連的邊的權重。

    • 如果計算出的項小於相鄰中心的權重,則以計算的乘積取代其權重。

  • 重複步驟3,直到目標中心消失或所有中心都被存取。

  • 目標中心的重量反映了從源頭到目標點沿途最小的物品重量。

範例

#include <bits/stdc++.h>
using namespace std;

// Function to return the smallest product of edges
double modifiedDijkstra(int source, int destination, vector<vector<pair<int, double> > > graph)
{
    // If the source is equal to the destination
    if (source == destination)
        return 0;

    // Initialize the priority queue
    set<pair<double, int>> pq;
    pq.insert({1, source});

    // Visited array
    bool visited[graph.size()] = {0};

    // While the priority queue is not empty
    while (!pq.empty())
    {
        // Current node
        int current = pq.begin()->second;

        // Current product of weights
        double product = pq.begin()->first;

        // Pop the top-most element
        pq.erase(pq.begin());

        // If already visited, continue
        if (visited[current])
            continue;

        // Mark the node as visited
        visited[current] = true;

        // If it is a destination node
        if (current == destination)
            return product;

        // Traverse the neighbors of the current node
        for (auto neighbor : graph[current])
        {
            int neighborNode = neighbor.first;
            double weight = neighbor.second;

            // Calculate the product of weights
            double newProduct = product * weight;

            // Insert the new product and neighbor into the priority queue
            pq.insert({newProduct, neighborNode});
        }
    }

    // If no path exists
    return -1;
}

// Function to add an edge to the graph
void addEdge(vector<vector<pair<int, double>>>& graph, int u, int v, double weight)
{
    graph[u].push_back({v, weight});
}

// Function to print the graph
void printGraph(const vector<vector<pair<int, double>>>& graph)
{
    for (int i = 1; i < graph.size(); i++)
    {
        cout << "Node " << i << ": ";
        for (auto neighbor : graph[i])
        {
            cout << "(" << neighbor.first << ", " << neighbor.second << ") ";
        }
        cout << endl;
    }
}

// Driver code
int main()
{
    int numNodes = 3;

    // Graph as adjacency list
    vector<vector<pair<int, double>>> graph(numNodes + 1);

    // Input edges
    addEdge(graph, 1, 3, 9);
    addEdge(graph, 2, 3, 1);
    addEdge(graph, 1, 2, 5);

    // Source and destination
    int source = 1, destination = 3;

    // Modified Dijkstra
    double smallestProduct = modifiedDijkstra(source, destination, graph);

    // Print the result
    cout << "Smallest product of weights: " << smallestProduct << endl;

    // Print the graph
    cout << "Graph: " << endl;
    printGraph(graph);

    return 0;
}
登入後複製

輸出

Smallest product of weights: 5
Graph: 
Node 1: (3, 9) (2, 5) 
Node 2: (3, 1) 
Node 3: 
登入後複製

修改後的帶有加權乘積的Bellman-Ford演算法

在帶有加權物件的調整後的Bellman-Ford演算法中,我們透過將來源中心的負載設為1,將所有其他中心的負載設為無窮大來開始。在每個循環中,透過比較目前節點的權重和連接它們到目標中心的邊的負載來解開所有邊。如果計算得到的權重比目標中心的負載小,我們將其權重增加計算得到的權重。重複這個過程V-1次,其中V是中心的總數,以確保考慮到所有可能的路徑。目標中心的權重表示從源頭到目標的路徑上最小的權重。

演算法

  • 除了源中心之外,所有其他中心的權重應為無窮大。

  • 重複執行上述步驟 V−1 次,其中 V 是節點的總數:

    • 對於圖表中的每條邊,計算目前中心的項目權重以及與它們相連的邊的權重。

    • 如果計算出的物品小於目標中心的重量,則用計算出的乘積升級其重量。

  • 經過V−1個週期,所有中心節點的權重將被確定。

  • 在計算過程中,如果圖表中存在負權重循環,將會區分出一個額外的循環。如果在此過程中有任何權重被修正,這表示存在一個負權重循環的存在。

  • 目標中心的重量反映了從源頭到目標點沿途最小的物品重量。

  • 貪婪著色演算法基於可用顏色和鄰居頂點使用的顏色,以貪婪的方式為頂點分配顏色。雖然它可能不會總是使用最少數量的顏色來完成圖表著色,但它提供了一種快速且有效率的頂點著色方法。

範例

#include <iostream>
#include <vector>
#include <limits>

struct Edge {
    int source, destination;
    double weight;
};

// Function to find the smallest product of weights using the modified Bellman-Ford algorithm
double findSmallestProduct(int numNodes, int source, int destination, std::vector<Edge>& edges) {
    std::vector<double> weights(numNodes, std::numeric_limits<double>::infinity());
    weights[source] = 1;

    for (int i = 1; i < numNodes; i++) {
        for (const auto& edge : edges) {
            double newWeight = weights[edge.source] * edge.weight;
            if (newWeight < weights[edge.destination]) {
                weights[edge.destination] = newWeight;
            }
        }
    }

    for (const auto& edge : edges) {
        double newWeight = weights[edge.source] * edge.weight;
        if (newWeight < weights[edge.destination]) {
            return -1.0; // Negative-weight cycle detected
        }
    }

    return weights[destination];
}

int main() {
    int numNodes = 4;

    std::vector<Edge> edges = {
        {0, 1, 2.0},
        {1, 2, 0.5},
        {2, 3, 1.5},
        {0, 3, 1.2},
        {1, 3, 0.8}
    };

    int source = 0, destination = 3;

    double smallestProduct = findSmallestProduct(numNodes, source, destination, edges);

    if (smallestProduct < std::numeric_limits<double>::infinity()) {
        std::cout << "The smallest product of weights along the path from node " << source
                  << " to node " << destination << " is: " << smallestProduct << std::endl;
    } else {
        std::cout << "A negative-weight cycle is detected. No valid path exists." << std::endl;
    }

    return 0;
}
登入後複製

輸出

The smallest product of weights along the path from node 0 to node 3 is: 1.2
登入後複製

結論

本文闡明如何找到具有權重大於或等於1的最小邊的路徑。它介紹了兩個演算法,即改進的Dijkstra演算法和改進的Bellman-Ford演算法,用於解決這個問題。改進的Dijkstra演算法在每一步選擇具有最小權重的節點,而改進的Bellman-Ford演算法迭代地解開邊以更新權重。文章提供了這兩個演算法在C語言中的實現,並用測試輸入說明了它們的使用。輸出結果是從來源節點到目標節點的路徑上的最小權重。

以上是具有權重大於等於1的邊的最小乘積路徑的詳細內容。更多資訊請關注PHP中文網其他相關文章!

本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

主題背景位於 Windows 11 中的什麼位置? 主題背景位於 Windows 11 中的什麼位置? Aug 01, 2023 am 09:29 AM

Windows11具有如此多的自訂選項,包括一系列主題和桌布。雖然這些主題以自己的方式是美學,但有些用戶仍然想知道他們在Windows11上的後台位置。本指南將展示造訪Windows11主題背景位置的不同方法。什麼是Windows11預設主題背景? Windows11預設主題背景是一朵盛開的抽象寶藍色花朵,背景為天藍色。這種背景是最受歡迎的背景之一,這要歸功於作業系統發布之前的預期。但是,作業系統還附帶了一系列其他背景。因此,您可以隨時變更Windows11桌面主題背景。主題背景儲存在Windo

斜線和反斜線在檔案路徑中的不同使用 斜線和反斜線在檔案路徑中的不同使用 Feb 26, 2024 pm 04:36 PM

檔案路徑是作業系統中用於識別和定位檔案或資料夾的字串。在檔案路徑中,常見的有兩種符號分隔路徑,即正斜線(/)和反斜線()。這兩個符號在不同的作業系統中有不同的使用方式和意義。正斜線(/)是Unix和Linux系統中常用的路徑分隔符號。在這些系統中,檔案路徑是以根目錄(/)為起始點,每個目錄之間使用正斜線進行分隔。例如,路徑/home/user/Docume

如何修復錯誤:在Java中找不到或載入主類 如何修復錯誤:在Java中找不到或載入主類 Oct 26, 2023 pm 11:17 PM

由於技術錯誤,無法播放此影片。 (錯誤代碼:102006)本指南提供了針對此常見問題的簡單修復,並繼續您的編碼之旅。我們還將討論Java錯誤的原因以及將來如何防止它。什麼是Java中的「錯誤:找不到或載入主類別」? Java是一種強大的程式語言,使開發人員能夠創建廣泛的應用程式。然而,它的多功能性和效率伴隨著開發過程中可能發生的一系列常見錯誤。其中一個中斷是錯誤:找不到或載入主類別user_jvm_args.txt,當Java虛擬機器(JVM)找不到主類別來執行程式時會出現這種情況。此錯誤充當了障礙,甚至在

Win11系統中「我的電腦」路徑有何不同?快速找方法! Win11系統中「我的電腦」路徑有何不同?快速找方法! Mar 29, 2024 pm 12:33 PM

Win11系統中「我的電腦」路徑有何不同?快速找方法!隨著Windows系統的不斷更新,最新的Windows11系統也帶來了一些新的變化和功能。其中一個常見的問題是使用者在Win11系統中找不到「我的電腦」的路徑,這在先前的Windows系統中通常是很簡單的操作。本文將介紹Win11系統中「我的電腦」的路徑有何不同,以及快速尋找的方法。在Windows1

使用path/filepath.Dir函數取得檔案路徑的目錄部分 使用path/filepath.Dir函數取得檔案路徑的目錄部分 Jul 27, 2023 am 09:06 AM

使用path/filepath.Dir函數取得檔案路徑的目錄部分在我們的日常開發過程中,經常會涉及到檔案路徑的處理。有時候,我們需要取得檔案路徑的目錄部分,也就是檔案所在資料夾的路徑。在Go語言中,可以使用path/filepath套件提供的Dir函數來實現這個功能。 Dir函數的簽章如下:funcDir(pathstring)stringDir函式接收一個字

Linux核心原始碼存放路徑解析 Linux核心原始碼存放路徑解析 Mar 14, 2024 am 11:45 AM

Linux內核是一個開源的作業系統內核,其原始碼儲存在一個專門的程式碼倉庫中。在本文中,我們將詳細解析Linux核心原始碼的存放路徑,並透過具體的程式碼範例來幫助讀者更好地理解。 1.Linux核心原始碼存放路徑Linux核心原始碼儲存在一個名為linux的Git倉庫中,該倉庫託管在[https://github.com/torvalds/linux](http

Python 3.x 中如何使用os.path模組來取得檔案路徑的各個部分 Python 3.x 中如何使用os.path模組來取得檔案路徑的各個部分 Jul 30, 2023 pm 02:57 PM

Python3.x中如何使用os.path模組來取得檔案路徑的各個部分在日常的Python程式設計中,我們經常需要對檔案路徑進行操作,例如取得路徑的檔案名稱、檔案目錄、副檔名等等。在Python中,可以使用os.path模組來進行這些操作。本文將介紹如何使用os.path模組來取得檔案路徑的各個部分,以便更好地操作檔案。 os.path模組提供了一系

如何查找Linux系統中RPM檔案的儲存路徑? 如何查找Linux系統中RPM檔案的儲存路徑? Mar 14, 2024 pm 04:42 PM

在Linux系統中,RPM(RedHatPackageManager)是一種常見的軟體套件管理工具,用於安裝、升級和移除軟體套件。有時候我們需要找到某個已安裝的RPM檔案的儲存路徑,以便進行尋找或其他操作。以下將介紹在Linux系統中如何找到RPM檔案的儲存路徑,同時提供具體的程式碼範例。首先,我們可以使用rpm指令來尋找已安裝的RPM套件及其儲存路徑。打開

See all articles