1. 电路如何列出矩阵
当年第一次接触到用矩阵来处理线方程时(就是大一的时候啦),就觉得矩阵这东西真有创意。 最近在为当年补课,在看麻省理工的公开课。当看到用矩阵来处理图论这一课时,又给了我一些开启。当然,这篇博客的主要内容也是参考的这一节课。
现在假设有一个电路如下。
X
其实有1,2,3,4四个结点。有5条边(连线),都标上序号了。
现在用矩阵来表示这个图。
这个矩阵有5行4列。其实就是对应上图的5条连线4个结点。第一行表示的是第一条连线的信息,第1列为-1,第3列为1。表示这条连线是从结点1接连到结点3,这里用1或者-1来标记,可以区分是起点还是终点,加起来就相当于:终点-起点,很符合向量的思维形式(其实就是这点带来后面的优势,如果有权重的需求,先不急,你会发现这样很值得)。
依此类推来理解第2行,第3行。。。
这个矩阵叫邻接矩阵。用邻接矩阵来表示这个电路是思路的关键。
我原来想到的是用一个4行4列的矩阵表示。例如对于上图的第一条边是从结点1到结点3的。我就在第1行,第3列打上1,或者是别的数(权重)。这样的表示我自己也没有看到多大的优势。所以用矩阵解析这类问题的方法没有太吸引我。
2. 在ROM存储器中必须有什么电路
rom是英文"read-only
memory"的简称,意思是只读存储器.其特点:是只能从该存储器读取数据,而不能向该存储器写数据,里面已写入的数据可长期保留.
3. c++利用邻接矩阵存储方法实现图的存储与输出。
复制粘贴即可
#include <iostream>
using namespace std;
//*****stack.h
#define STACK_INIT_SIZE 100
#define STACKINCREMENT 10
typedef int Status;
template<class QElemType>
class stack
{
public:
void InitStack();
void DestroyStack();
void ClearStack();
Status StackEmpty();
Status StackLength();
void GetTop(QElemType & e);
void Push(QElemType e);
void Pop(QElemType & e);
private:
struct SqStack{
QElemType *base;
QElemType *top;
int stacksize;
}S;
};
//******stack.cpp------
template<class QElemType>
void stack<QElemType>::InitStack()
{
S.base = (QElemType *)malloc(STACK_INIT_SIZE * sizeof(QElemType));
if(!S.base) exit(0);
S.top = S.base;
S.stacksize = STACK_INIT_SIZE;
}
template <class QElemType>
void stack<QElemType>::DestroyStack()
{
free(S.base);
}
template <class QElemType>
void stack<QElemType>::ClearStack()
{
S.top = S.base;
}
template <class QElemType>
Status stack<QElemType>::StackEmpty()
{
if(S.top == S.base) return 1;
else return 0;
}
template <class QElemType>
Status stack<QElemType>::StackLength()
{
return (S.top - S.base);
}
template <class QElemType>
void stack<QElemType>::GetTop(QElemType & e)
{
if(S.top != S.base)
e = *(S.top - 1);
else cout << "ERROR" << endl;
}
template <class QElemType>
void stack<QElemType>::Push(QElemType e)
{
if(S.top - S.base >= S.stacksize)
{
S.base = (QElemType *)realloc(S.base,(S.stacksize + STACKINCREMENT) * sizeof(QElemType));
if(!S.base) exit(0);
S.top = S.base + S.stacksize;
S.stacksize += STACKINCREMENT;
}
*S.top++ = e;
}
template <class QElemType>
void stack<QElemType>::Pop(QElemType & e)
{
if(S.top == S.base) cout << "ERROR" << endl;
else
e = * --S.top;
}
//**********stack.cpp End
template <class TElemType>
class Graph
{
public:
void CreateUDN();
void DestroyUDN();
void CreateAlgraph();
void DestroyAlgraph();
void DFS(int v,bool *visited);
void DFSTraverse();
void Minispantree_prim(); //PRIM算法求最小生成树
void Shortestpath_DIJ(TElemType data1,TElemType data2); //对环不适用,如从V1到V1就不适用
void Shortestpath_FLOYD(TElemType data1,TElemType data2);
private:
template <class TElemType>
struct Mgraph{
int vexnum;
int arcnum;
TElemType *vertex;
int **AdjMatrix;
};
Mgraph<TElemType> gph; //邻接矩阵存储
struct Arcnode
{
int adjvex;
Arcnode *nextarc;
float weight;
};
template <class TElemType>
struct Vexnode
{
TElemType data;
Arcnode *firarc;
};
struct ALgraph
{
int vexnum;
int arcnum;
bool kind;
Vexnode<TElemType> *vex;
};
ALgraph algraph; //邻接表存储
};
//*********Graph.cpp
template <class TElemType>
void Graph<TElemType>::CreateUDN()
{
cout << "输入无向网的顶点数和边数:" << endl;
cin >> gph.vexnum >> gph.arcnum;
gph.vertex = (TElemType *)malloc(gph.vexnum * sizeof(TElemType));
int i,j,m,n; //m,n表示顶点信息对应的序号,w是权值
int w;
TElemType v1,v2;
cout << "输入顶点信息:" << endl;
for(i = 0;i < gph.vexnum;i++)
cin >> gph.vertex[i];
gph.AdjMatrix = (int **)malloc(gph.vexnum * sizeof(int *));
for(i = 0;i < gph.vexnum;i++)
gph.AdjMatrix[i] = (int *)malloc(gph.vexnum * sizeof(int));
for(i = 0;i < gph.vexnum;i++)
for(j = 0;j < gph.vexnum;j++)
gph.AdjMatrix[i][j] = INT_MAX; //INT_MAX
cout << "输入一条边依附的两点及权值:" << endl;
for(int k = 0;k < gph.arcnum;k++)
{
cin >> v1 >> v2 >> w;
for(i = 0;i < gph.vexnum;i++)
{
if(v1 == gph.vertex[i]) m = i;
if(v2 == gph.vertex[i]) n = i;
}
gph.AdjMatrix[m][n] = gph.AdjMatrix[n][m] = w;
}
}
template <class TElemType>
void Graph<TElemType>::DestroyUDN()
{
free(gph.vertex);
for(int i = 0;i < gph.vexnum;i++)
free(gph.AdjMatrix[i]);
free(gph.AdjMatrix);
}
template <class TElemType>
void Graph<TElemType>::CreateAlgraph()
{
int i,j,m,n;
float w;
TElemType v1,v2;
Arcnode *p;
cout << "输入图类型(1是无向图,0是有向图):" << endl;
cin >> algraph.kind;
cout << "输入顶点数和边数:" << endl;
cin >> algraph.vexnum >> algraph.arcnum;
algraph.vex = (Vexnode<TElemType> *)malloc(algraph.vexnum * sizeof(Vexnode<TElemType>));
cout << "输入顶点信息:" << endl;
for(i = 0;i < algraph.vexnum;i++)
{
cin >> algraph.vex[i].data;
algraph.vex[i].firarc = NULL;
}
if(algraph.kind)
{
cout << "输入各边依附的两点和权值:" << endl;
for(i = 0;i < algraph.arcnum;i++)
{
cin >> v1 >> v2 >>w;
for(j = 0;j < algraph.vexnum;j++)
{
if(v1 == algraph.vex[j].data) m = j;
if(v2 == algraph.vex[j].data) n = j;
}
p = (Arcnode *)malloc(2*sizeof(Arcnode));
p[0].adjvex = n;p[0].weight = w;
p[1].adjvex = m;p[1].weight = w;
p[0].nextarc = algraph.vex[m].firarc;algraph.vex[m].firarc = p;
p[1].nextarc = algraph.vex[n].firarc;algraph.vex[n].firarc = ++p;
}
}
else
{
cout << "输入各边的弧尾与弧头结点及有向边的权值:" << endl;
for(i = 0;i < algraph.arcnum;i++)
{
cin >> v1 >> v2 >> w;
for(j = 0;j < algraph.vexnum;j++)
{
if(v1 == algraph.vex[j].data) m = j;
if(v2 == algraph.vex[j].data) n = j;
}
p = (Arcnode *)malloc(sizeof(Arcnode));
p->adjvex = n;p->weight = w;
p->nextarc = algraph.vex[m].firarc;algraph.vex[m].firarc = p;
}
}
} //构造完成
template <class TElemType>
void Graph<TElemType>::DestroyAlgraph()
{
int i;
Arcnode *p,*q;
for(i = 0;i < algraph.vexnum;i++)
{
p = algraph.vex[i].firarc;
if(p)
{
q = p->nextarc;
while(q)
{
free(p);
p = q;
q = q->nextarc;
}
free(p);
}
}
free(algraph.vex);
}
template <class TElemType>
void Graph<TElemType>::DFS(int v,bool *visited)
{
cout << algraph.vex[v].data << endl;
visited[v] = true;
Arcnode *p;
int v1;
for(p = algraph.vex[v].firarc;p;p = p->nextarc)
{
v1 = p->adjvex;
if(!visited[v1]) DFS(v1,visited);
}
}
template <class TElemType>
void Graph<TElemType>::DFSTraverse()
{
int i,v;
bool *visited = (bool *)malloc(algraph.vexnum * sizeof(bool));
for(i = 0;i < algraph.vexnum;i++)
visited[i] = false;
for(v = 0;v < algraph.vexnum;v++)
if(!visited[v]) DFS(v,visited);
free(visited);
} //EndDFSTraverse
template <class TElemType>
void Graph<TElemType>::Minispantree_prim()
{
struct closedge
{
int adjvex;
int lowcost;
};
closedge *edge = (closedge *)malloc(gph.vexnum * sizeof(closedge));
int i,j,k = 0,u;
int min;
for(i = 0;i < gph.vexnum;i++)
{
if(i != k)
{
edge[i].adjvex = 0;
edge[i].lowcost = gph.AdjMatrix[k][i];
}
}
edge[k].lowcost = 0;
cout << "最小生成树的边如下:" << endl;
for(i = 1;i < gph.vexnum;i++)
{
min = INT_MAX;
for(j = 0;j < gph.vexnum;j++)
if(edge[j].lowcost != INT_MAX &&edge[j].lowcost != 0 && edge[j].lowcost < min)
{
min = edge[j].lowcost;
k = j;
}
u = edge[k].adjvex;
edge[k].lowcost = 0;
cout << "(" << gph.vertex[u] << "," << gph.vertex[k] << ")" << " ";
for(j = 0;j < gph.vexnum;j++)
if(gph.AdjMatrix[j][k] < edge[j].lowcost)
{
edge[j].lowcost = gph.AdjMatrix[j][k];
edge[j].adjvex = k;
}
}
free(edge);
cout << endl;
}
template <class TElemType>
void Graph<TElemType>::Shortestpath_DIJ(TElemType data1,TElemType data2)
{
int i,j,v,u,k,min;
stack<int> S;
S.InitStack();
int *spath = (int *)malloc(gph.vexnum * sizeof(int));
int *pathrecord = (int *)malloc(gph.vexnum * sizeof(int));
bool *visited = (bool *)malloc(gph.vexnum * sizeof(bool));
for(i = 0;i < gph.vexnum;i++) visited[i] = false;
for(i = 0;i < gph.vexnum;i++)
{
if(data1 == gph.vertex[i]) v = i;
if(data2 == gph.vertex[i]) u = i;
}
for(i = 0;i < gph.vexnum;i++)
{
spath[i] = gph.AdjMatrix[v][i];
pathrecord[i] = v;
}
spath[v] = 0;visited[v] = true;pathrecord[v] = -1;
for(i = 1;i < gph.vexnum;i++)
{
min = INT_MAX;
for(j = 0;j < gph.vexnum;j++)
{
if(!visited[j])
{
if(spath[j] < min) {min = spath[j];k = j;}
}
}
visited[k] = true;
for(j = 0;j < gph.vexnum;j++)
if(!visited[j] && gph.AdjMatrix[k][j] < INT_MAX && spath[k]+gph.AdjMatrix[k][j] < spath[j])
{
spath[j] = spath[k]+gph.AdjMatrix[k][j];
pathrecord[j] = k;
}
}
free(visited);
cout << spath[u] << endl;
S.Push(u);
for(v = pathrecord[u];v != -1;v = pathrecord[v])
S.Push(v);
while(!S.StackEmpty())
{
S.Pop(i);
cout << gph.vertex[i] << " ";
}
cout << endl;
S.DestroyStack();
free(spath);
free(pathrecord);
}
template <class TElemType>
void Graph<TElemType>::Shortestpath_FLOYD(TElemType data1,TElemType data2)
{
int i,j,k,v,u,m;
int **D = (int **)malloc(gph.vexnum * sizeof(int *));
bool ***path = (bool ***)malloc(gph.vexnum * sizeof(bool **));
for(i = 0;i < gph.vexnum;i++)
{
D[i] = (int *)malloc(gph.vexnum * sizeof(int));
path[i] = (bool **)malloc(gph.vexnum * sizeof(bool *));
if(data1 == gph.vertex[i]) v = i;
if(data2 == gph.vertex[i]) u = i;
}
for(i = 0;i < gph.vexnum;i++)
for(j = 0;j < gph.vexnum;j++)
path[i][j] = (bool *)malloc(gph.vexnum *sizeof(bool));
for(i = 0;i < gph.vexnum;i++)
for(j = 0;j < gph.vexnum;j++)
{
D[i][j] = gph.AdjMatrix[i][j];
for(k = 0;k < gph.vexnum;k++)
path[i][j][k] = false;
if(D[i][j] < INT_MAX)
{
path[i][j][i] = true;path[i][j][j] = true;
}
}
for(k = 0;k < gph.vexnum;k++)
for(i = 0;i < gph.vexnum;i++)
for(j = 0;j < gph.vexnum;j++)
if(D[i][k] != INT_MAX && D[k][j] != INT_MAX && D[i][k]+D[k][j] < D[i][j])
{
D[i][j] = D[i][k] + D[k][j];
for(m = 0;m < gph.vexnum;m++)
path[i][j][m] = path[i][k][m] || path[k][j][m];
}
cout << "从" << gph.vertex[v] << "到" << gph.vertex[u] << "的最短路径及经过的点如下:" << endl;
cout << D[v][u] << endl;
for(i = 0;i < gph.vexnum;i++)
if(path[v][u][i] == true) cout << i << " ";
cout << endl;
for(i = 0;i < gph.vexnum;i++)
{
free(D[i]);
free(path[i]);
}
free(D);
free(path);
}
//***********end Graph
int main()
{
Graph<int> gph;
gph.CreateUDN();
gph.Minispantree_prim();
int data1,data2;
cout << "输入起点和终点:" << endl;
cin >> data1 >> data2;
gph.Shortestpath_DIJ(data1,data2);
//gph.Shortestpath_FLOYD(data1,data2);
gph.DestroyUDN();
return 0;
}
功能函数都实现了,可以自己在源程序中调用函数实现各种功能。
4. C语言对矩阵的存储与读取如何进行
这个要你自己实现一个串化和反串化的类。Mfc你可以使用Archive对象做,c的话要自己实现过程。
5. 矩阵的电路原理
切换原理上就是选择,选择的方式有很多种,最简单的就是 将信号线直接接在一起,比如接线板,利用人工将输出信号线跳接在输入信号线上,也可完成选择,或利用琴键开关完成接通与断开,当然这是人工操作的,机械的,不存在指标等技术问题,故不作为矩阵切换讨论。第二种方式,利用继电器也可完成选择,利用电平控制继电器的通断,可完成输出线与输入信号之间的断开与联接,也可完成信号的选择,第三种方式是根据电路原理,利用芯片内部电路的导通与关闭进行接通与关断,并可通过电平进行控制完成信号的选择。
继电器方式与芯片方式各有优缺点。
继电器方式:如果不考虑输入匹配与输出驱动的电路部分的话,它与联线方式一致,是靠物理接触进行接通与断开,从这个角度上讲,是没有什么指标概念的(最多有接触电阻和反应时间),因此技术指标好且价格低廉,其缺点在于稳定性较差,毕竟是靠物理接触,继电器有一定寿命,原则上讲,有8万次平均无故障操作且操作时有声响,由于线路板走线原因,不能做的规模较大,显得不够高档。
芯片方式:由于靠电路进行接通与关断,芯片本身存在技术指标(在输入匹配与输出驱动一样的情况下),因此要保障技术指标,就要选择专用的切换芯片,因此价格较高,但稳定性好,可形成的矩阵规模较大。
矩阵切换应保证的技术指标
矩阵切换器根据不同的应用领域,所要求的技术指标也不同。以广电行业为例,为保证终端的显示质量,广电行业将整个信号传输过程,从摄像头开始到电视机为止,都进行了技术指标分配,对模拟矩阵切换和分配,所定的技术指标如表:GB/T14236-93与本公司KT-128*32实例指标:
6. 静态RAM基本存储电路
那个T3,T4是有源负载,相当于电阻,T3是T1的负载电阻,T4是T2的负载电阻,都是导通的,为T1,T2提供漏极电压的。而真正导通和截止形成反相的,有两个稳定状态的是T1,T2。因为在集成电路内部不方便做电阻,所以,就用这种电路做电阻了。
7. 用存储器见组成内存时,为什么总是采用矩阵形式
存储器分类 存储器是计算机系统中的记忆设备,用来存放程序和数据。
构成存储器的存储介质,目前主要采用半导体器件和磁性材料。存储器中最小的存储单位就是一个双稳态半导体电路或一个CMOS晶体管或磁性材料的存储元,它可存储一个二进制代码。由。
8. 存储电路是如何工作的
存储器分为RAM(数据存储器)和ROM(程序存储器),他们工作原理都是一样的,即实现对电平0和1的存储。
存储电路的工作原理见下图,你可以把它看懂用自己的语言描述出来,这样你的报告就可以写出来了,然后大规模的存储电路集成起来可以构成存储器。
如果是应付写报告,我给你概括下吧,存储电路的工作原理是:存储电路是把送来的地址信号通过地址译码电路,在存储矩阵中选中相应的存储单元,将该单元存储的数据送到输出端口,为了实现存储器的扩展往往在存储器上加使能信号EN.大规模的存储电路集成封装起来就组成存储器。
9. A是原始矩阵 求它的转置矩阵,还是放在A里输出 (要求:只能用一个存储变量)
业务组合规划工具,用于多业务公司的整体发展战略 - 定向政策矩阵(DPM),是由荷兰皇家壳牌集团开发。与一般的矩阵来选择不同的量化指标,定向政策矩阵更直接地精的业务组合,并以达到真实性的商业区采取星级评定的方式可以量化的指标进行比较。
特点是只在:
我们1,矩阵是? - 三经三矩阵,描绘了公司的竞争力和企业的发展前景;有限公司2,定位每一个企业都采取了一些变量,方法类似于通用电气公司A中的竞争地位 - 市场吸引力矩阵
3,初次使用的技术细节特别适用于石化行业,但这种模式也广泛适用于任何多元化的客户
4,这是基于对业务增长和提前时间为基础的新的生产。
页5,指导性政策矩阵是?本质上是外部环境和内部环境归结在一起下来,并做出判断,其中企业的战略地位,并提出了指导性的战略规划。
10. 简述存储器和寄存器在电路结构和工作原理上有何不同
存储器是能存储大量二值信息的半导体器件,它由地址译码器、存储矩阵、输入/输出电路三部分组成;每个存储单元不直接引出输入/输出端,采用公共输入/输出总线结构。
寄存器是用于寄存一组二值代码(信息),由时钟触发器组成;每个存储单元直接引出输入/输出端。