ソート並べ替えアルゴリズムのコレクション

MVector.hpp

#ifndef MVector_hpp
#define MVector_hpp

#include <vector>
#include <cassert>
#include <ostream>
#include <cstdlib>
#include <ctime>

// Class that represents a mathematical vector
class MVector
{
public:
    // constructors
    MVector() {}
    explicit MVector(int n) : v(n) {}
    MVector(int n, double x) : v(n, x) {}
    MVector(std::initializer_list<double> l) : v(l) {}
    
    
    // access element (lvalue) (see example sheet 5, q5.6)
    double &operator[](size_t index)
    {
        // assert(index >=0 && index < size());
        return v[index];
    }
    
    // access element (rvalue) (see example sheet 5, q5.7)
    double operator[](size_t index) const {
        // assert(index >= 0 && index < size());
        return v[index];
    }
    
    size_t size() const { return v.size(); } // number of elements
    
    void swap(int i, int j) {
        auto temp = v[i];
        v[i] = v[j];
        v[j] = temp;
    }
    
    void initialise_random(double xmin, double xmax) {
        std::srand(std::time(NULL));
        size_t s = v.size();
        for (size_t i=0; i<s; i++) {
            v[i] = xmin + (xmax-xmin) * rand()/static_cast<double>(RAND_MAX);
        }
    }
    
    friend std::ostream& operator <<(std::ostream& stream, const MVector v) {
        for (size_t i = 0; i < v.size() - 1; ++i) {
            stream << v[i] << ", ";
        }
        stream << v[v.size() - 1] << std::endl;
        return stream;
    }
    
private:
    std::vector<double> v;
};

#endif /* MVector_hpp */

並べ替え.hpp

#ifndef sort_h
#define sort_h

#include <iostream>
#include <fstream>
#include <string>
#include <ctime>
#include <cmath>

#include "MVector.hpp"

// bubble sort
namespace BubbleSort{
void bubble(MVector &v) {
    const size_t n = v.size();
    for (int i=0; i<n; ++i) {
        for (int j=0; j<n; ++j) {
            if (v[i] < v[j]) {
                v.swap(i, j);
            }
        }
    }
};
} // namespace BubbleSort

// quick sort
namespace QuickSort{
int partition(MVector &v, int low, int high) {
    auto pivot = v[high];
    int idx = low - 1;
    for (int j = low; j < high; j++) {
        if (v[j] <= pivot) {
            ++idx;
            v.swap(idx, j);
        }
    }
    v.swap(idx + 1, high);
    return idx + 1;
}
void quick_recursive(MVector &v, int start, int end) {
    if (start < end) {
        auto i = partition(v, start, end);
        quick_recursive(v, start, i-1);
        quick_recursive(v, i+1, end);
    }
}

void quick(MVector &v) { quick_recursive(v, 0, v.size()-1); }
} // namespace QuickSort

// heap sort
namespace HeapSort {
void heap_from_root(MVector& v, int i, int n) {
    int largest = i;
    int l = 2 * i + 1, r = 2 * i + 2;
    if (l < n && v[l] > v[largest]) {
        largest = l;
    }
    if (r < n && v[r] > v[largest]) {
        largest = r;
    }
    if (largest != i) {
        v.swap(largest, i);
        heap_from_root(v, largest, n);
    }
}

void heap(MVector &v) {
    const int n = v.size();
    for (int i = n / 2 - 1; i >= 0; --i) {
        heap_from_root(v, i, n);
    }
    
    for (int i = n - 1; i > 0; --i) {
        v.swap(0, i);
        heap_from_root(v, 0, i);
    }
}
} // namespace HeapSort

enum SortMethod {
    bubble,
    quick,
    heap
};

void Benchmark(std::vector<std::vector<MVector>> Vecs, const std::string path, const SortMethod &method) {
    // TODO: modify output stream
    std::fstream file_stream;
    file_stream.open(path, std::fstream::out);
    file_stream << std::fixed;
    file_stream << std::setprecision(6);
    file_stream << "size,"
        << "time"
        << std::endl;

    size_t iter = Vecs[0].size();
    for (auto &Vec : Vecs) {
        if (method == bubble && Vec[0].size() > 5000) continue;
        double t = 0.0;
        auto t1 = std::clock();
        for (auto &v : Vec){
            switch (method) {
                case bubble:
                    BubbleSort::bubble(v);
                    break;
                case quick:
                    QuickSort::quick(v);
                    break;
                case heap:
                    HeapSort::heap(v);
                    break;
            }
            t += (double) (std::clock() - t1) / CLOCKS_PER_SEC;
        }
        
        file_stream << Vec[0].size() << ','
            << t / iter << std::endl;
    }
    
    file_stream.close();
}

#endif /* sort_h */

main.hpp

#include <unordered_map>

#include "MVector.hpp"
#include "sort.hpp"

void WriteMVec(const std::string &file_path, const MVector &v) {
    std::fstream file_stream;
    file_stream.open(file_path, std::fstream::out);
    file_stream << v;
    file_stream.close();
}

// for Task 4.2.1 & Task 4.2.2
void T() {
    MVector v(100000);
    v.initialise_random(1, 100000);
    std::cout << v;
    WriteMVec("Mvec.txt", v); // change for the path of output
};

int main(int argc, const char * argv[]) {
//    T(); // for Task 4.2.1 & Task 4.2.2
    
    // Task 4.2.3 begins
    // create test cases with various lengths 
    int iter = 10;
    std::vector<int> test_sizes;
    for (int i = 100; i <= 20000; i += 100) {
        test_sizes.push_back(i);
    }

    // randomly initialise vecs
    std::vector<std::vector<MVector>> Vecs;
    for (auto &size : test_sizes) {
        std::vector<MVector> Vec(iter);
        for (int i=0; i<iter; ++i) {
            MVector v(size);
            v.initialise_random(0, 1000);
            Vec[i] = std::move(v);
        }
        Vecs.emplace_back(Vec);
    }
    
    std::string path = "./"; // change for your own

    std::unordered_map<SortMethod, std::string> method = {
        {quick, "quick"},
        {heap, "heap"},
        {bubble, "bubble"}
    };
    
    // Benchmark time costs
    for (auto &[k, v] : method) {
        auto f = path + v + ".txt";
        std::cout << f << std::endl;
        Benchmark(Vecs, f, k);
    }
    // Task 4.3.2 ends
}

サブプロット.py

import os
from matplotlib import pyplot as plt
import seaborn as sns
import numpy as np

def plot():
  output_file = filter(lambda x: x.endswith(".txt") and not x.startswith("MV"), os.listdir())
  
  for i, f in enumerate(output_file):
    fig, ax = plt.subplots(1, 1, figsize=(10, 7))
    with open(f, 'r') as file:
      lines = []
      for l, line in enumerate(file.readlines()):
        if l == 0: continue
        lines.append(list(map(float, line.split(','))))
    x, y = zip(*lines)

    # if i == 0:
    #   ax[0, 1].plot(x, y)
    #   ax[0, 1].set_title(f.split('.')[0]) 
    # elif i == 1:
    #   ax[1, 0].plot(x, y)
    #   ax[1, 0].set_title(f.split('.')[0]) 
    # else:
    #   ax[1, 1].plot(x, y)
    #   ax[1, 1].set_title(f.split('.')[0])    
    
    ax.plot(x, y, label=f.split('.')[0])
    ax.set_title(f.split('.')[0])
    ax.set_xlabel(r"$n$")
    ax.set_ylabel("time/s")
#   ax.legend()
    # plt.show()
    fig.savefig(os.path.join(os.getcwd(), f"{f.split('.')[0]}.png"))
  
  
def scatter():
  output_file = filter(lambda x: x.endswith(".txt") and not x.startswith("MV"), os.listdir())
  
  for i, f in enumerate(output_file):
    fig, ax = plt.subplots(1, 1, figsize=(10, 7))
    with open(f, 'r') as file:
      lines = []
      for l, line in enumerate(file.readlines()):
        if l == 0: continue
        lines.append(list(map(float, line.split(','))))
    x, y = zip(*lines)

    # if i == 0:
    #   ax[0, 1].plot(x, y)
    #   ax[0, 1].set_title(f.split('.')[0]) 
    # elif i == 1:
    #   ax[1, 0].plot(x, y)
    #   ax[1, 0].set_title(f.split('.')[0]) 
    # else:
    #   ax[1, 1].plot(x, y)
    #   ax[1, 1].set_title(f.split('.')[0])    
    
    sns.regplot(x=np.array(x)**2 if 'bubble' in f else np.array(x)*np.log(np.array(x)), y=np.array(y))
    ax.set_title(f.split('.')[0])
    ax.set_xlabel(r"$n^2$" if "bubble" in f else r"$nlogn$")
    ax.set_ylabel("time/s")
#   ax.legend()
    # plt.show()
    fig.savefig(os.path.join(os.getcwd(), f"{f.split('.')[0]}_scatter.png"))
  
if __name__ == "__main__":
  plot()
  scatter()

おすすめ

転載: blog.csdn.net/m0_48707860/article/details/129519920