# HG changeset patch
# User beckerjc
# Date 1078341408 0
# Node ID 4b5210aa023961272304c27d05a64dce7a9b443c
# Parent  824c0438020cb76016de7f063fc696cda6157be6
Uni?-HolVan strukt?ra,
Kruskal algoritmus,
hozz?val? kis tesztf?jl ?s Makefile.

diff -r 824c0438020c -r 4b5210aa0239 src/work/johanna/.cvsignore
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/work/johanna/.cvsignore	Wed Mar 03 19:16:48 2004 +0000
@@ -0,0 +1,2 @@
+.depend
+kruskal_test
diff -r 824c0438020c -r 4b5210aa0239 src/work/johanna/Makefile
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/work/johanna/Makefile	Wed Mar 03 19:16:48 2004 +0000
@@ -0,0 +1,4 @@
+BINARIES = kruskal_test
+INCLUDEDIRS= -I. -I.. -I../../include
+include ../makefile
+
diff -r 824c0438020c -r 4b5210aa0239 src/work/johanna/kruskal.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/work/johanna/kruskal.h	Wed Mar 03 19:16:48 2004 +0000
@@ -0,0 +1,60 @@
+// -*- c++ -*- //
+#ifndef HUGO_KRUSKAL_H
+#define HUGO_KRUSKAL_H
+
+#include "unionfind.h"
+#include <algorithm>
+
+namespace hugo {
+
+  template <typename EdgeCostPair> static
+  bool comparePair(EdgeCostPair const& a, EdgeCostPair const& b) {
+    return a.second < b.second;
+  }
+
+
+  template <typename Graph, typename EdgeDoubleMap, typename EdgeBoolMap>
+
+  typename EdgeDoubleMap::ValueType 
+  MinCostTreeKruskal(Graph const& G, EdgeDoubleMap const& costmap, 
+		     EdgeBoolMap& treemap) 
+  {
+    
+    typedef typename EdgeDoubleMap::ValueType EDouble;
+    typedef typename Graph::EachEdgeIt EachEdgeIt;
+    typedef std::pair<EachEdgeIt, EDouble> EdgeCostPair;
+
+
+    typedef std::vector<EdgeCostPair> EdgeCostVector;
+    EdgeCostVector rank;
+
+    for (EachEdgeIt e=G.template first<EachEdgeIt>(); e.valid(); ++e) {
+      rank.push_back(make_pair(e, costmap.get(e)));
+    }
+
+    
+    std::sort(rank.begin(), rank.end(), comparePair<EdgeCostPair>);
+
+    typedef typename Graph::NodeMap<int> NodeIntMap;
+    typedef typename Graph::NodeIt NodeIt;
+    NodeIntMap comp_map(G, -1);
+    UnionFind<NodeIt,NodeIntMap> uf(comp_map); 
+
+    EDouble tot_cost = 0;
+    for (typename EdgeCostVector::iterator p = rank.begin(); 
+	 p!=rank.end(); ++p ) {
+      if ( uf.joinComponents(G.head(p->first), G.tail(p->first)) ) {
+	treemap.set(p->first, true);
+	tot_cost += p->second;
+      }
+      else {
+	treemap.set(p->first, false);
+      }
+    }
+    return tot_cost;
+  }
+
+
+} //namespace hugo
+
+#endif //HUGO_KRUSKAL_H
diff -r 824c0438020c -r 4b5210aa0239 src/work/johanna/kruskal_test.cc
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/work/johanna/kruskal_test.cc	Wed Mar 03 19:16:48 2004 +0000
@@ -0,0 +1,63 @@
+#include <string>
+#include <iostream>
+#include <map>
+
+#include <kruskal.h>
+#include <list_graph.hh>
+
+
+using namespace std;
+using namespace hugo;
+
+class string_int_map : public map<string,int> {
+public:
+  int get(const string &s) {
+    // Bocs, ez igy gaaaany, de nem volt kedvem utananezni, hogy
+    // hogy is mukodik ez a map :)
+    if( count(s) == 0 ) {
+      operator[](s) = -1;
+    }
+    return operator[](s);
+  }
+  void set(const string &s, int i) {
+      operator[](s) = i;
+  }
+};
+
+
+int main() {
+
+  typedef ListGraph::NodeIt NodeIt;
+  typedef ListGraph::EdgeIt EdgeIt;
+  typedef ListGraph::EachNodeIt EachNodeIt;
+  typedef ListGraph::EachEdgeIt EachEdgeIt;
+
+  ListGraph G;
+
+  NodeIt s=G.addNode();
+  NodeIt v1=G.addNode();
+  NodeIt v2=G.addNode();
+  NodeIt v3=G.addNode();
+  NodeIt v4=G.addNode();
+  NodeIt t=G.addNode();
+  
+  G.addEdge(s, v1);
+  G.addEdge(s, v2);
+  G.addEdge(v1, v2);
+  G.addEdge(v2, v1);
+  G.addEdge(v1, v3);
+  G.addEdge(v3, v2);
+  G.addEdge(v2, v4);
+  G.addEdge(v4, v3);
+  G.addEdge(v3, t);
+  G.addEdge(v4, t);
+
+  ListGraph::EdgeMap<double> edge_cost_map(G, 2);
+  ListGraph::EdgeMap<bool> tree_map(G);
+  
+  double k0lts = MinCostTreeKruskal(G, edge_cost_map, tree_map);
+
+  cout << k0lts << endl;
+
+  return 0;
+}
diff -r 824c0438020c -r 4b5210aa0239 src/work/johanna/unionfind.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/work/johanna/unionfind.h	Wed Mar 03 19:16:48 2004 +0000
@@ -0,0 +1,75 @@
+// -*- c++ -*- //
+#ifndef UNION_FIND_H
+#define UNION_FIND_H
+
+#include <vector>
+#include <utility>
+
+namespace hugo {
+
+  template <typename T, typename TIntMap>
+  class UnionFind {
+    
+  public:
+    typedef T ElementType;
+    typedef std::pair<int,int> PairType;
+
+  private:
+    std::vector<PairType> data;
+    TIntMap& map;
+
+  public:
+    UnionFind(TIntMap& m) : map(m) {}
+
+
+    int whichComponent(T a)
+    {
+      int comp0 = map.get(a);
+      if (comp0 < 0) {
+	return insertNewElement(a);
+      }
+      int comp = comp0;
+      int next;
+      while ( (next = data[comp].first) != comp) {
+	comp = next;
+      }
+      while ( (next = data[comp0].first) != comp) {
+	data[comp0].first = comp;
+	comp0 = next;
+      }
+
+      return comp;
+    }
+
+    int insertNewElement(T a)
+    {
+      int n = data.size();
+      data.push_back(make_pair(n, 1));
+      map.set(a,n);
+      return n;
+    }
+
+    bool joinComponents(T a, T b)
+    {
+      int ca = whichComponent(a);
+      int cb = whichComponent(b);
+
+      if ( ca == cb ) 
+	return false;
+
+      if ( data[ca].second > data[cb].second ) {
+	data[cb].first = ca;
+	data[ca].second += data[cb].second;
+      }
+      else {
+	data[ca].first = cb;
+	data[cb].second += data[ca].second;
+      }
+      return true;
+    }
+
+  };
+
+} //namespace hugo
+
+#endif //UNION_FIND_H