.. _program_listing_file_src_smp.hpp: Program Listing for File smp.hpp ================================ |exhale_lsh| :ref:`Return to documentation for file ` (``src/smp.hpp``) .. |exhale_lsh| unicode:: U+021B0 .. UPWARDS ARROW WITH TIP LEFTWARDS .. code-block:: cpp /* This file is part of brille. Copyright © 2019,2020 Greg Tucker brille is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. brille is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with brille. If not, see . */ /* An implementation of a solver for the stable matching problem */ #ifndef BRILLE_SMP_HPP_ #define BRILLE_SMP_HPP_ #include namespace brille::assignment { template void smp_pmat(const T dim, const P *restrict tp){ for (T i=0; i void smp_pvec(const T dim, const P *restrict tp){ for (T j=0; j int smp(const T dim, const P *restrict prefs, T *restrict rsol, T *restrict csol, const bool verbose){ T nsel=0; auto rpref = std::unique_ptr(new T[dim*dim]); auto cpref = std::unique_ptr(new T[dim*dim]); P min; auto tmp = std::unique_ptr(new P[dim]); auto inv = std::unique_ptr(new T[dim]); // Create the preference lists. for (T i=0; i::max)(); } // cpref are based on the columns of pref for (T j=0; j::max)(); } /* cpref contains the row indexes in preferrential order, but it needs to contain the prefferential index in row order. */ for (T j=0; j(new bool[dim]); auto cmatched = std::unique_ptr(new bool[dim]); auto rproposed = std::unique_ptr(new T[dim]); // intialize: no proposed matchings, all rows and columns try for their preferred match for (T i=0; i= dim) throw std::runtime_error("last choice was rejected?!"); // find its preferred column of non-rejected proposals thisc = rpref[i*dim + rproposed[i]]; // if the preferred column has a proposed match if (cmatched[thisc]){ // and if the column prefers this row over the proposed row if (cpref[i*dim + i] < cpref[i*dim + csol[thisc]]){ // unmatch the other row rmatched[csol[thisc]] = false; rsol[csol[thisc]] = T(0); // make sure it moves on to its next choice rproposed[csol[thisc]]++; // and match this one rmatched[i] = true; csol[thisc] = i; rsol[i] = thisc; } else { // othwerwise move on to the next preferred column rproposed[i]++; } } else { // the column hasn't been proposed yet, so tentatively accept rsol[i] = thisc; csol[thisc] = i; rmatched[i] = true; cmatched[thisc] = true; nsel++; // we have one more match than before } } } } bool ok=true; for (size_t i=0; i