Ich versuche, boots prims Algorithmus zu verwenden, um den minimalen Spannbaum mit Kantengewicht und einer ID-Nummer statt nur Kantengewicht zu finden.C++ Boost Prim-Algorithmus mit benutzerdefinierten Gewichten?
Zum Beispiel, wenn beide Kantengewichte 1 wären, würde die ID verglichen werden, je nachdem was weniger war, würde die Krawatte brechen.
Ich habe eine EdgeWeight-Klasse erstellt und die Operatoren < und + überladen, um dies zu tun, und dann die Eigenschaft edge_weight_t von int in EdgeWeight geändert, in der Hoffnung, dass es funktioniert.
// TestPrim.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include <boost/config.hpp>
#include <iostream>
#include <boost/graph/adjacency_list.hpp>
#include <boost/graph/prim_minimum_spanning_tree.hpp>
using namespace std;
class EdgeWeight{
public:
EdgeWeight(){}
EdgeWeight(int weightIn, int destinationIdIn){
weight = weightIn;
destinationId = destinationIdIn;
}
bool operator<(const EdgeWeight& rhs) const {
if (weight < rhs.weight)
return true;
else if(weight == rhs.weight){
if (destinationId < rhs.destinationId)
return true;
else
return false;
}
else
return false;
}
EdgeWeight operator+(const EdgeWeight& rhs) const {
EdgeWeight temp;
temp.weight = weight + rhs.weight;
temp.destinationId = destinationId + rhs.destinationId;
return temp;
}
int weight;
int destinationId;
};
int _tmain(int argc, _TCHAR* argv[])
{
using namespace boost;
typedef adjacency_list < vecS, vecS, undirectedS, property<vertex_distance_t, EdgeWeight>, property < edge_weight_t, EdgeWeight > > Graph;
typedef std::pair < int, int >E;
const int num_nodes = 5;
E edges[] = { E(0, 2), E(1, 3), E(1, 4), E(2, 1), E(2, 3),
E(3, 4), E(4, 0)
};
EdgeWeight weights[] = { EdgeWeight(1, 2), EdgeWeight(1, 3), EdgeWeight(2, 4),
EdgeWeight(7, 1), EdgeWeight(3, 3), EdgeWeight(1, 4), EdgeWeight(1, 0) };
Graph g(edges, edges + sizeof(edges)/sizeof(E), weights, num_nodes);
property_map<Graph, edge_weight_t>::type weightmap = get(edge_weight, g);
std::vector < graph_traits <Graph>::vertex_descriptor > p(num_vertices(g));
prim_minimum_spanning_tree(g, &p[0]);
for (std::size_t i = 0; i != p.size(); ++i)
if (p[i] != i)
std::cout << "parent[" << i << "] = " << p[i] << std::endl;
else
std::cout << "parent[" << i << "] = no parent" << std::endl;
return EXIT_SUCCESS;
}
ich einen Fehler habe, „c: \ Programme (x86) \ Microsoft Visual Studio 10.0 \ vc \ include \ Grenzen (92): Fehler C2440: '': Konvertierung von 'int' zu ' D ' 1> Kein Konstruktor könnte den Quelltyp verwenden, oder Konstruktor Überladung Auflösung war mehrdeutig "
Mache ich das den richtigen Weg? Gibt es einen besseren Weg, dies zu tun?
http://www.boost.org/doc/libs/1_38_0/libs/graph/doc/prim_minimum_spanning_tree.html http://www.boost.org/doc/libs/1_38_0/boost/graph/prim_minimum_spanning_tree.hpp
edit: ok so implementiert ich die Gewichte für jetzt cjm die gestörte Methode verwendet, aber in die Zukunft, die ich glaube, ich werde das obige Verfahren irgendwie verwenden haben, immer noch fragen, wie es
edit2 tun: basierend auf Jeremias reponse änderte ich den vertex_distance_t von int nach EdgeWeight bekam aber den gleichen Fehler
Es scheint nicht, wie diese Fehler etwas mit dem Algorithmus zu tun? Was ist in Zeile 92 dieser Datei? Können Sie herausfinden, wo dieser Fehler auftritt? –
Ich denke, ein einfacherer Weg, um Bindungen zu brechen, ist nur die Kantengewichte durch eine sehr kleine Anzahl zu stören. Z.B. Wenn Ihre Kantengewichte anfänglich ganzzahlig sind, dann müssen Sie für zwei Kanten mit einem Gewicht von 5 ein Gewicht von 4,9 und ein Gewicht von 5,1 haben. Wie du die Dinge störst, hängt natürlich davon ab, wie viele Bindungen du erwartest/der Bereich deiner Kantengewichte. – cjm
Ich könnte das tun, denke ich. Ich habe versucht, es mit Arten "richtig" zu machen. – stack356