File: ConnectionMatrix.h

package info (click to toggle)
veroroute 2.38-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 6,044 kB
  • sloc: cpp: 21,512; xml: 89; sh: 65; lisp: 20; makefile: 5
file content (95 lines) | stat: -rw-r--r-- 3,016 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
/*
	VeroRoute - Qt based Veroboard/Perfboard/PCB layout & routing application.

	Copyright (C) 2017  Alex Lawrow    ( dralx@users.sourceforge.net )

	This program is free software: you can redistribute it and/or modify
	it under the terms of the GNU General Public License as published by
	the Free Software Foundation, either version 3 of the License, or
	(at your option) any later version.

	This program 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 General Public License for more details.

	You should have received a copy of the GNU General Public License
	along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

#pragma once

#include "Common.h"

// Keeps track of connectivity between a set of points (e.g. target pins in the routing algorithm)

// Quicker to use struct than a std::pair
struct CONNECTION
{
	CONNECTION(size_t a, size_t b) : first(a), second(b) {}
	size_t	first	= 0;
	size_t	second	= 0;
};

class ConnectionMatrix
{
public:
	ConnectionMatrix() {}
	~ConnectionMatrix() { DeAllocate(); }
	void Allocate(size_t N)
	{
		m_N				= N;
		const size_t N2	= m_N * m_N;
		m_p				= new bool[N2];
		m_pp			= new bool*[m_N];
		memset(m_p, 0, N2 * sizeof(bool));
		for (size_t i = 0; i < m_N; i++) m_pp[i] = m_p + i * m_N;
		for (size_t i = 0; i < m_N; i++) m_pp[i][i] = true;	// Each point is connected to itself
		m_cost = static_cast<unsigned int>(N2 - m_N);	// Cost = number of false values in the connection matrix
	}
	void DeAllocate()
	{
		if ( m_pp ) delete[] m_pp;
		if ( m_p  ) delete[] m_p;
		m_pp = nullptr;
		m_p	 = nullptr;
	}
	void Connect(size_t j, size_t k)
	{
		// Make j-k connection and enforce transitivity

		std::list<CONNECTION> list;		// Helper for updating the connection matrix
		list.push_back( CONNECTION(j,k) );
		while ( !list.empty() )
		{
			auto iter = list.begin();	// Read info from first list entry ...
			const auto a = iter->first;
			const auto b = iter->second;
			list.erase( iter );			// ... then remove the list entry

			if ( !m_pp[a][b] )	// If no a-b connection ...
			{
				m_pp[a][b] = m_pp[b][a] = true;	// Make a-b connection ...
				m_cost -= 2;					// Update cost
				for (size_t c = 0; c < m_N; c++)	// Update 1st-order transitive relations
				{
					if ( m_pp[a][c] )
					{
						if ( !m_pp[b][c] ) list.push_back( CONNECTION(b,c) );	// a-c connection ==> b-c connection
					}
					else
					{
						if (  m_pp[b][c] ) list.push_back( CONNECTION(a,c) );	// b-c connection ==> a-c connection
					}
				}
			}
		}
	}
	const bool& GetAreConnected(size_t j, size_t k) const { return m_pp[j][k]; }
	const unsigned int&	GetCost() const { return m_cost; }
private:
	size_t			m_N		= 0;		// Number of points in the set
	bool*			m_p		= nullptr;	//
	bool**			m_pp	= nullptr;	// m_pp[j][k] is true if points j and k are connected
	unsigned int	m_cost	= UINT_MAX; // Zero ==> all points are connected
};