Sorting Network Search
Backtracking for Small Sorting Networks
Level2Search.cpp
Go to the documentation of this file.
1
3
4// MIT License
5//
6// Copyright (c) 2023 Ian Parberry
7//
8// Permission is hereby granted, free of charge, to any person obtaining a copy
9// of this software and associated documentation files (the "Software"), to
10// deal in the Software without restriction, including without limitation the
11// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
12// sell copies of the Software, and to permit persons to whom the Software is
13// furnished to do so, subject to the following conditions:
14//
15// The above copyright notice and this permission notice shall be included in
16// all copies or substantial portions of the Software.
17//
18// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
23// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
24// IN THE SOFTWARE.
25
26#include <algorithm>
27#include <iostream>
28#include <fstream>
29
30#include "Level2Search.h"
31
34
36 size_t m_nCurIndex = 0; //index of current matching - no need to call GetIndex
37
38 CMatching curMatching; //current matching
39 curMatching.Initialize();
40
41 do{ //for each matching
42 //if(odd(m_nWidth))curMatching[m_nWidth] = m_nWidth; //dummy last channel for odd width networks
43 CMatching copy(curMatching);
44
45 if(m_stlUsed.find(m_nCurIndex) == m_stlUsed.end()){ //if it is not used
46 const size_t minIndex = std::min(m_nCurIndex, Permute(copy, m_nWidth/2)); //all pairwise permutations used also
47
48 if(m_stlUsed.find(minIndex) == m_stlUsed.end()){ //if it is not used
49 m_stlResults.push_back(curMatching); //insert into results
50 m_stlUsed.insert(minIndex); //mark it used
51 } //if
52 } //if
53
54 m_nCurIndex++; //index of next matching
55 }while(curMatching.Next()); //get next matching, exit if there is none
56
57 //normalize the resulting matchings
58
59 for(auto m: m_stlResults)
60 m.Normalize();
61
62 std::cout << m_stlResults.size() << " second levels found out of ";
63 std::cout << m_nCurIndex << " matchings" << std::endl;
64 Save(); //save results to file
65} //constructor
66
71
73 size_t index = 0; //the index value to be returned
74 size_t b = GetNumMatchings(m_nWidth)/(oddfloor(m_nWidth)); //block size to be skipped
75
76 int nCopy[MAXINPUTS + 1] = {0}; //integer copy of matching.
77
78 //grab a copy of matching into the array m
79
80 for(size_t i=0; i<=m_nWidth; i++)
81 nCopy[i] = (int)matching[i];
82
83 //make sure that each comparator is listed in ascending order
84
85 for(size_t i=0; i<m_nWidth; i+=2)
86 if(nCopy[i] > nCopy[i+1])
87 std::swap(nCopy[i], nCopy[i+1]);
88
89 //compute index
90
91 for(size_t n=evenceil(m_nWidth); n>2; n-=2){ //for each comparator
92 size_t max = 1; //the index of the largest channel on the max side of a comparator
93
94 for(size_t i=1; i<=m_nWidth; i+=2)
95 if(nCopy[i] > nCopy[max])
96 max = i;
97
98 //skip over the matchings that have max matching to something smaller
99 //than max is matching to in the current matching, which is m[max - 1]
100
101 index += b*(n - 2 - nCopy[max - 1]);
102
103 //remove m_nCopy[max - 1] from the matching
104
105 for(size_t j=0; j<m_nWidth; j++)
106 if(nCopy[j] > nCopy[max - 1])
107 nCopy[j]--;
108
109 //prepare for next iteration
110
111 b /= n - 3; //block size to be skipped is now smaller
112 nCopy[max] = 0; //remove channel max from consideration
113 } //for
114
115 return index;
116} //GetIndex
117
123
124size_t CLevel2Search::Permute(CMatching& matching, const size_t n){
125 size_t nMinIndex = 99999; //minimum matching index found
126
127 for(size_t i=0; i<n; i++){
128 if(n > 2) //recurse on sub-permutation
129 nMinIndex = std::min(nMinIndex, Permute(matching, n - 1));
130
131 if(i < n - 1){ //base of recursion
132 matching.Swap(odd(n)? 0: i, n - 1); //swap to new candidate
133 nMinIndex = std::min(nMinIndex, GetIndex(matching));
134 } //if
135 } //for
136
137 return nMinIndex;
138} //Permute
139
142
143const std::vector<CMatching>& CLevel2Search::GetMatchings() const{
144 return m_stlResults;
145} //GetMatchings
146
156
157const size_t CLevel2Search::GetNumMatchings(const size_t n) const{
158 size_t result = 1;
159
160 for(size_t i = oddfloor(n); i>1; i-=2)
161 result *= i;
162
163 return result;
164} //GetNumMatchings
165
168
170 const std::string fname = "level2-" + std::to_string(m_nWidth) + ".txt";
171 std::ofstream outfile(fname); //output file
172
173 if(outfile.is_open()) //file opened correctly
174 for(const CMatching& m: m_stlResults) //for each matching
175 outfile << std::string(m) << std::endl; //print matching as string
176
177 outfile.close(); //end of file
178} //Save
#define evenceil(n)
If odd, round up to make even.
Definition: Defines.h:38
#define MAXINPUTS
Maximum width, that is, number of inputs.
Definition: Defines.h:29
#define oddfloor(n)
If even, round down to make odd.
Definition: Defines.h:35
#define odd(n)
Oddness test.
Definition: Defines.h:32
Interface for the Level 2 search CLevel2Search.
const std::vector< CMatching > & GetMatchings() const
Get matching vector.
size_t GetIndex(CMatching &)
Get the index of a matching.
const size_t GetNumMatchings(const size_t) const
Number of matchings.
std::vector< CMatching > m_stlResults
Results.
Definition: Level2Search.h:83
void Save() const
Save results to log file for debugging purposes.
size_t Permute(CMatching &, const size_t)
Permute the matching.
std::set< size_t > m_stlUsed
Set of indices of used matchings.
Definition: Level2Search.h:82
CLevel2Search()
Constructor.
Perfect matching.
Definition: Matching.h:39
bool Next()
Advance to next matching.
Definition: Matching.cpp:62
void Initialize()
Initialize.
Definition: Matching.cpp:50
void Swap(const size_t, const size_t)
Swap.
Definition: Matching.cpp:148
static size_t m_nWidth
Comparator network width.
Definition: Settings.h:39