導航:首頁 > 源碼編譯 > choice演算法排名

choice演算法排名

發布時間:2022-05-14 14:32:33

⑴ c語言的綜合設計問題。。。。關於打分系統的排名次問題

case 2:
for(i=0;i<=9;i++) //在外層for循環用的是i變數,而第三層for循環又用到i變數,這兩個變數會沖突
for(m=0;m<9;m++)
for(i=0;i=9-m;i++) //應該把i變為j
if(playerscore[i]>playerscore[i+1])
{
a=playerscore[i];
playerscore[i]=playerscore[i+1];
playerscore[i+1]=a;
}
for(i=0;i<10;i++)
printf("%f",playerscore[i]);
break;

問題已經用注釋標注,我沒有編譯過,但是我發現了這個小問題,提出來,不知道得沒得

⑵ C語言數據結構中的幾種內部排序法,求解!高手速度來指導我。。

1.Shell排序(ShellSort)

Shell排序通過將數據分成不同的組,先對每一組進行排序,然後再對所有的元素進行一次插入排序,以減少數據交換和移動的次數。平均效率是O(nlogn)。其中分組的合理性會對演算法產生重要的影響。現在多用D.E.Knuth的分組方法。

Shell排序比冒泡排序快5倍,比插入排序大致快2倍。Shell排序比起QuickSort,MergeSort,HeapSort慢很多。但是它相對比較簡單,它適合於數據量在5000以下並且速度並不是特別重要的場合。它對於數據量較小的數列重復排序是非常好的。

2.快速排序(QuickSort)

快速排序是一個就地排序,分而治之,大規模遞歸的演算法。從本質上來說,它是歸並排序的就地版本。快速排序可以由下面四步組成。

(1) 如果不多於1個數據,直接返回。

(2) 一般選擇序列最左邊的值作為支點數據。

(3) 將序列分成2部分,一部分都大於支點數據,另外一部分都小於支點數據。

(4) 對兩邊利用遞歸排序數列。

快速排序比大部分排序演算法都要快。盡管我們可以在某些特殊的情況下寫出比快速排序快的演算法,但是就通常情況而言,沒有比它更快的了。快速排序是遞歸的,對於內存非常有限的機器來說,它不是一個好的選擇。

3堆排序(HeapSort)

堆排序適合於數據量非常大的場合(百萬數據)。

堆排序不需要大量的遞歸或者多維的暫存數組。這對於數據量非常巨大的序列是合適的。比如超過數百萬條記錄,因為快速排序,歸並排序都使用遞歸來設計演算法,在數據量非常大的時候,可能會發生堆棧溢出錯誤。

堆排序會將所有的數據建成一個堆,最大的數據在堆頂,然後將堆頂數據和序列的最後一個數據交換。接下來再次重建堆,交換數據,依次下去,就可以排序所有的數據。

下面是一個總的表格(這張表很重要),大致總結了我們常見的所有的排序演算法的特點。
排序法 平均時間 最差情形 穩定度 額外空間 備注
冒泡 O(n2) O(n2) 穩定 O(1) n小時較好
交換 O(n2) O(n2) 不穩定 O(1) n小時較好
選擇 O(n2) O(n2) 不穩定 O(1) n小時較好
插入 O(n2) O(n2) 穩定 O(1) 大部分已排序時較好
基數 O(logRB) O(logRB) 穩定 O(n)
B是真數(0-9),

R是基數(個十百)

Shell O(nlogn) O(ns) 1<s<2 不穩定 O(1) s是所選分組
快速 O(nlogn) O(n2) 不穩定 O(nlogn) n大時較好
歸並 O(nlogn) O(nlogn) 穩定 O(1) n大時較好
堆 O(nlogn) O(nlogn) 不穩定 O(1) n大時較好
備注:O(n2)表示雙重循環,即n^2

⑶ 程序設計問題-排序演算法

int lnitSqlist(Sqlist *L) 這個要用引用類型。

int lnitSqlist(Sqlist* &L)

不然你的指針裡面都是空的。

正常來說,是先聲明再寫定義 。你都定義好了,這個聲明就沒必要了。
去掉int lnitSqlist(Sqlist *L);
void Scanfsqlist();

⑷ C語言編程高手請進

這個是我以前編的,有些小錯誤,你參考一下:

#include"stdio.h"
#include"stdlib.h"
#include"malloc.h"
#include"string.h"

typedef struct stud
{
long int number;
char name[20];
int grade;
char other[30];
char sex[10];
struct stud *next;
}T;

T *creat()
{
T *p,*q,*head;
long int number;
int grade;
char name[20],other[30],sex[10];
head=(T *)malloc(sizeof(T));
q=head;

printf("Please input the data:(num,name,sex,grade,other,0:end)\n");
scanf("%ld",&number);fflush(stdin);
if(number)
{
gets(name);
gets(sex);
scanf("%d",&grade);fflush(stdin);
gets(other);
}

while(number)
{
p=(T *)malloc(sizeof(T));
q->number=number;
strcpy(q->name,name);
strcpy(q->sex,sex);
q->grade=grade;
strcpy(q->other,other);
q->next=p;
q=p;

scanf("%ld",&number);fflush(stdin);
if(number)
{
gets(name);
gets(sex);
scanf("%d",&grade);fflush(stdin);
gets(other);
}
}
q->next=NULL;

fflush(stdin);
return head;
}

void print(T *head)
{
T *p;

p=head;
if(p)
printf("Number name \tsex grade other\n");
while(p->next)
{
printf("%08ld %-15s%-6s %-8d %s\n",p->number,p->name,p->sex,p->grade,p->other);
p=p->next;
}
printf("\nEND!\n");
}

void fprint(T *head,FILE *fp)
{
T *p;

p=head;
if(p)
fprintf(fp,"Number name \tsex grade other\n");
while(p->next)
{
fprintf(fp,"%08ld %-15s%-6s %-8d %s\n",p->number,p->name,p->sex,p->grade,p->other);
p=p->next;
}
fprintf(fp,"\nEND!\n");
}

T *range(T *head)
{
T *p,*q,*s;
int key;

printf("Please input the key you want to range:\n1.number,2.name,3.sex,4.grade,5.other.\nYour choice:[ ]\b\b");
scanf("%d",&key);fflush(stdin);

s=q=head;
p=q->next;

switch(key)
{
case 1:
while(p)
{
if(s->number>p->number) s=p;
p=p->next;
}

if(s!=head)
{
s->next=head;
head=s;
}

for(s=q=head->next;s;s=q=s->next)
{
for(p=q->next;p;p=p->next)
if(s->grade>p->grade) s=p;

if(s!=q)
{
s->next=q;
q=s;
}
}

break;

case 2:
while(p)
{
if(strcmp(s->name,p->name)>0) s=p;
p=p->next;
}

if(s!=head)
{
s->next=head;
head=s;
}

for(s=q=head->next;s;s=q=s->next)
{
for(p=q->next;p;p=p->next)
if(s->grade>p->grade) s=p;

if(s!=q)
{
s->next=q;
q=s;
}
}

break;

case 3:

while(p)
{
if(strcmp(s->sex,p->sex)>0) s=p;
p=p->next;
}

if(s!=head)
{
s->next=head;
head=s;
}

for(s=q=head->next;s;s=q=s->next)
{
for(p=q->next;p;p=p->next)
if(s->grade>p->grade) s=p;

if(s!=q)
{
s->next=q;
q=s;
}
}

break;

case 4:
while(p)
{
if(s->grade>p->grade) s=p;
p=p->next;
}

if(s!=head)
{
s->next=head;
head=s;
}

for(s=q=head->next;s;s=q=s->next)
{
for(p=q->next;p;p=p->next)
if(s->grade>p->grade) s=p;

if(s!=q)
{
s->next=q;
q=s;
}
}

break;

case 5:
while(p)
{
if(strcmp(s->other,p->other)>0) s=p;
p=p->next;
}

if(s!=head)
{
s->next=head;
head=s;
}

for(s=q=head->next;s;s=q=s->next)
{
for(p=q->next;p;p=p->next)
if(s->grade>p->grade) s=p;

if(s!=q)
{
s->next=q;
q=s;
}
}

break;
}

return head;
}

T *range_1(T *head)
{
T *p,*q,*s;

s=q=head;
p=q->next;
while(p)
{
if(s->number>p->number) s=p;
p=p->next;
}

if(s!=head)
{
s->next=head;
head=s;
}

for(s=q=head->next;s;s=q=s->next)
{
for(p=q->next;p;p=p->next)
if(s->grade>p->grade) s=p;

if(s!=q)
{
s->next=q;
q=s;
}
}

return head;
}

T *insert(T *head)
{
T *p,*q,*s;

s=(T *)malloc(sizeof(T));
printf("Please input the insert data:(num,name,sex,grade,other)\n");
scanf("%ld",&s->number);fflush(stdin);
if(s->number==0)
{
printf("ERROR!\nPlease input number again.\n");
scanf("%ld",&s->number);fflush(stdin);
}
gets(s->name);
gets(s->sex);
scanf("%d",&s->grade);fflush(stdin);
gets(s->other);

q=head;
p=q->next;

if(q->number>s->number)
{
s->next=head;
head=s;
}

while(q->number<s->number&&p)
{
q=p;
p=q->next;
}

/*if(!q)
{
q->next=s;
s->next=NULL;
}
else
{
s->next=p;
q->next=s;
}*/

s->next=p;
q->next=s;

return head;
}

T *del(T *head)
{
T *p,*q;
long int x;
int key=2;

print(head);
printf("Please input the data you want to delete:(num)\n");
scanf("%ld",&x);fflush(stdin);
for(;key==2;)
{
printf("Are you sure?\n1.OK.\n2.Input new.\n3.Exit delete.\nYour choice:[ ]\b\b");
scanf("%d",&key);fflush(stdin);
if(key==3) return head;
if(key==2) scanf("%ld",&x);
}
q=head;
p=q->next;
if(q->number==x)
{head=p;return(head);}
while(q&&p->number!=x)
{
q=p;
p=q->next;
}

if(q)
{
q->next=p->next;
free(p);
}

else printf("NOT Found!!!\n");

return head;
}

void prt()
{
printf(" welcome to use!!! \t\t========================\n");
printf(" \t\t* Linklist Student *\n");
printf(" \t\t* by czj *\n");
printf(" \t\t* 2008 10 4 *\n");
printf(" \t\t========================\n");
}

void fprt(FILE *p)
{
fprintf(p," welcome to use!!! \t\t========================\n");
fprintf(p," \t\t* Linklist Student *\n");
fprintf(p," \t\t* by czj *\n");
fprintf(p," \t\t* 2008 10 4 *\n");
fprintf(p," \t\t========================\n");
}

void main()
{
T *head=NULL;
int key=1;
FILE *p;

prt();
head=creat();
print(head);

printf("1.INSERT.\n2.DLETE.\n3.CORRECT.\n4.RANGE.\n0.EXIT.\nYour choice[ ]\b\b");
scanf("%d",&key);fflush(stdin);
for(;key;)
{
system("cls");

prt();
if(key==1) insert(head);
if(key==2||key==3) del(head);
if(key==3) insert(head);
if(key==4) range(head);
print(head);
printf("1.INSERT.\n2.DELETE.\n3.CORRECT.\n4.RANGE.\n0.EXIT.\nYour choice[ ]\b\b");
scanf("%d",&key);fflush(stdin);
}

if((p=fopen("d:\\linklist1.dat","w"))==NULL)
{
printf("Can't open the file.\n");
exit(0);
}

fprt(p);
fprint(head,p);

fclose(p);
}

/*
最後一個節點不用。
fflush(stdin);清除緩存。
insert中輸入有問題,range。
*/

⑸ 桶排序演算法到底是個什麼意思

m#include <iostream>
#include <ctime>
#include <cmath>
using namespace std;
void main()

{

long choice;
long start,end;
MUNE: cout<<"桶排序:1.正常情況 2.最壞情況 3.退出"<<endl;
cin>>choice;

struct node //定義鏈表
{
double item;
node *next;
node(double x,node *n)
{
item=x;
next=n;
}
};
typedef node *link; //構造鏈表
const long ARRAYNUM=10000; //定義要求要求排序數組大小
const long BUCKETNUM=10000; //定義桶的數量
double *SortArray;
SortArray=new double[ARRAYNUM];//定義排序數組
link *Bucket;
Bucket=new link[BUCKETNUM]; //定義桶
link t=new node(0,NULL);
link newlink;
link templink=new node(0,NULL);
for (long x=0;x<BUCKETNUM;x++) //初始化桶
{
Bucket[x]=new node(0,NULL);
}

srand((unsigned) time(NULL)); //產生隨機數組
for (long i=0;i<ARRAYNUM;i++)
{
SortArray[i]=(double)rand()/RAND_MAX;

}

start=clock(); //設置時鍾起點
for(long j=0;j<ARRAYNUM;j++)
{
newlink=new node(SortArray[j],NULL);
switch(choice) //輸入選擇
{
case 1: t=Bucket[(long)(BUCKETNUM*SortArray[j])];break;
case 2: t=Bucket[0];break; //最壞情況,數據都在一個桶里
case 3: goto EXIT;break;
}
if(t->item==0) //如果桶為空,則把數據直接放入桶內
{
t->item=SortArray[j];
}
else

{
if(t->item>SortArray[j]) //桶不為空,待插入數據比原桶內第一個數據小情況
//即數據要插在第一個數據前面
{
templink=t; //前向指針,隨著t的編譯,templing->next=t
Bucket[(long)(BUCKETNUM*(newlink->item))]=newlink;
newlink->next=templink;
templink=NULL;
}
else
{
while(t!=NULL) //桶不為空,待插入數據比原桶內數據小情況
{
if(t->item<=SortArray[j]) //桶不為空,待插入數據比原桶內第二個及以後數據大情況,
{
templink=t;
t=t->next; //待插入數比桶內數大,鏈表後向遍歷

if(t==NULL) //鏈表編譯到原桶內最後一個數
{
templink->next=newlink;//將待插數據接在原鏈表最後
}
}
else //鏈表比當前數據小,插入數據
{

newlink->next=t;
templink->next=newlink;
t=NULL;
}

}
}
}

}
end=clock(); //設置時鍾終點
cout<<"所用時間為:"<<end-start<<endl;

goto MUNE;

EXIT:;
}簡單來說,就是把數據分組,放在一個個的桶中,然後對每個桶裡面的在進行排序。
例如要對大小為[1..1000]范圍內的n個整數A[1..n]排序
可以把桶設為大小為10的范圍,具體而言,設集合B[1]存儲[1..10]的整數,集合B[2]存儲
(10..20]的整數,……集合B[i]存儲( (i-1)*10, i*10]的整數,i = 1,2,..100。總共有
100個桶。
然後對A[1..n]從頭到尾掃描一遍,把每個A[i]放入對應的桶B[j]中。
然後再對這100個桶中每個桶里的數字排序,這時可用冒泡,選擇,乃至快排,一般來說任
何排序法都可以。最後依次輸出每個桶裡面的數字,且每個桶中的數字從小到大輸出,這
樣就得到所有數字排好序的一個序列了。
假設有n個數字,有m個桶,如果數字是平均分布的,則每個桶裡面平均有n/m個數字。如果
對每個桶中的數字採用快速排序,那麼整個演算法的復雜度是
O(m + m * n/m*log(n/m)) = O(m + nlogn - nlogm)
從上式看出,當m接近n的時候,桶排序復雜度接近O(n)
當然,以上復雜度的計算是基於輸入的n個數字是平均分布這個假設的。這個假設是很強的
,實際應用中效果並沒有這么好。如果所有的數字都落在同一個桶中,那就退化成一般的
排序了。

⑹ 銀行家演算法

#include<string.h>
#include<stdio.h>
#define M 5 //定義進程數
#define N 3 //定義資源數
#define False 0
#define True 1
int Max[5][3]={{7,5,3},{3,2,2},{9,0,2},{2,2,2},{4,3,3}}; //每個進程對每類資源的最大需求
int Allocation[5][3]={{0,1,0},{2,0,0},{3,0,2},{2,1,1},{0,0,2}};//系統已分配資源
int Avaliable[3]={3,3,2}; //系統可利用資源
int Need[5][3]={{7,4,3},{1,2,2},{6,0,0},{0,1,1},{4,3,1}};//還需要資源
int Request[3];
void showdata()//顯示資源矩陣
{
int i,j;
printf("系統目前可利用的資源數量:\n A,B,C\n");
printf("resouce: ");
for (j=0;j<N;j++)
printf("%d,",Avaliable[j]);//輸出分配資源
printf("\n");
printf("各進程的資源需求:\n");
for (i=0;i<M;i++)
{
printf("pr%d: ",i);
for (j=0;j<N;j++)
{
printf("%d,",Max[i][j]);//輸出最大需求資源數
}
printf("\n");
}
printf("各進程得到資源:\n");
for (i=0;i<M;i++)
{
printf("pr%d: ",i);
for(j=0;j<N;j++)
printf("%d,",Allocation[i][j]);//輸出已分配資源數
printf("\n");
}
printf("各進程還需求資源:\n");
for (i=0;i<M;i++)
{
printf("pr%d: ",i);
for(j=0;j<N;j++)
printf("%d,",Need[i][j]);//輸出還需要資源數
printf("\n");
}
}
void release(int i)//判斷是否安全,若不安全則釋放第i類資源
{
int j;
for (j=0;j<N;j++)
{
Avaliable[j]=Avaliable[j]+Request[j];
Allocation[i][j]=Allocation[i][j]-Request[j];
Need[i][j]=Need[i][j]+Request[j];
}
}
void distribute(int i)//若符合條件則對第i類資源進行分配
{
int j;
for (j=0;j<M;j++)
{
Avaliable[j]=Avaliable[j]-Request[j];
Allocation[i][j]=Allocation[i][j]+Request[j];
Need[i][j]=Need[i][j]-Request[j];
}
}
void safeAlgorithm()//安全性演算法
{
int Work[3],Finish[M]={0},result[M],run;
/* work:表示系統可提供給進程繼續運行的所需的各類資源數目
finish: 表示系統是否有足夠的資源分配給進程
result用來存放依次執行成功的線程 */
int i,j,k=0,m,demand;
for(i=0;i<3;i++)
{
Work[i]=Avaliable[i]; //開始的時候work=available
}
for(i=0;i<M;i++)
{
demand=0;
for(j=0;j<N;j++)
{
if (Finish[i]==False&&Need[i][j]<=Work[j])
{ demand++;
if(demand==3)//只有ABC三類資源都滿足才把相應的線程記入數組result中
{ for(m=0;m<N;m++)
Work[m]=Work[m]+Allocation[i][m];//重新分配第i類線程的當前可利用資源
Finish[i]=True;
result[k]=i;
i=-1;
k++;
}
}
else
if(Finish[i]==False)
{
if(i==M-1)
{ printf("系統不安全\n");//如果不成功,輸出系統不安全
run=False; }
break;
}
}
}
printf("系統資源分配成功!");//如果安全,輸出成功
printf("分配的序列:\n");
for(i=0;i<M;i++)//輸出運行進程數組
{
printf("pr%d ",result[i]);
}

}
void bankerAlgorithm()//利用銀行家演算法對申請資源對進行判定
{
int i,j,OK=1,run=True;
printf("\n請輸入第一個要求分配的資源進程號從(0 to 4):");
scanf("%d",&i);//輸入須申請的資源號
printf("請輸入進程 %d 申請的資源:\n",i);
for(j=0;j<3;j++)
{
printf("第 %d 個資源:",j+1);
scanf("%d",&Request[j]);//輸入需要申請的資源
}
for (j=0;j<N;j++)
{
if(Request[j]>Need[i][j])//判斷申請是否大於需求,若大於則出錯
{
printf("進程 %d 申請的資源大於它需要的資源",i);
printf(" error!\n");
OK=0;
break;
}
else
{ if(Request[j]>Avaliable[j]) //判斷申請是否大於當前資源,若大於則出錯
{
printf("進程 %d 申請的資源大於當前可利用資源",i);
printf(" error!\n");
OK=0;
break;
}
}
}
if(OK==1) //若都符合條件,則進行分配
{
distribute(i); //根據進程請求分配資源
showdata(); //顯示變換後的資源
safeAlgorithm(); //通過安全演算法判斷該序列是否安全
if(run==False) //若不安全,則進行釋放第I類資源
{ release(i); }
}
}

void main()//主函數
{ int choice;
showdata();
safeAlgorithm();
do
{ printf("\n輸入接下來你要進行的操作 1:分配資源 2:顯示資源 否則按任意鍵退出");
scanf("%d",&choice);
switch(choice)
{ case 1: bankerAlgorithm(); break;
case 2: showdata(); break;
default: break;
}
}while((choice==1)||(choice==2));
}

⑺ 拜占庭將軍問題的解決演算法

拜占庭問題的最初描述是:n 個將軍被分隔在不同的地方,忠誠的將軍希望通過某種協議達成某個命令的一致(比如一起進攻或者一起後退)。但其中一些背叛的將軍會通過發送錯誤的消息阻撓忠誠的將軍達成命令上的一致。Lamport 證明了在將軍總數大於3m ,背叛者為m 或者更少時,忠誠的將軍可以達成命令上的一致。
為了保證上面的需求,必須滿足下面兩個條件:
1. 每兩個忠誠的將軍必須收到相同的值 v(i)(v(i)是第i 個將軍的命令)
2. 如果第i 個將軍是忠誠的,那麼他發送的命令和每個忠誠將軍收到的v(i)相同
為了簡化以上模型,我們使用一個將軍發送命令給多個副官的形式來證明,發送命令的將軍稱為發令者,接收命令的將軍為副官,那麼上面的兩個條件可以表述為:
IC1. 所有忠誠的副官遵守相同的命令
IC2. 如果發出命令的將軍是忠誠的,那麼所有忠誠的副官遵守司令(發出命令的將軍)的命令
特別提示:發送命令的每次只有一個將軍,將其命令發送給n-1 個副官。m 代表叛國者的個數,因為將軍總數為n,所以副官總數為n-1 個。IC2 中副官遵守實際上是指忠誠的將軍能夠正確收到忠誠將軍的命令消息。 通過口頭消息傳遞達到一致,如果有m 個叛國將軍,則將軍們的總數必須為3m+1 個以上。下面是口頭消息傳遞過程中默認的一些條件:
A1. 每個被發送的消息都能夠被正確的投遞
A2. 信息接收者知道是誰發送的消息
A3. 能夠知道缺少的消息
A1 和A2 假設了兩個將軍之間通信沒有干擾,既不會有背叛者阻礙消息的發送(截斷)也不會有背叛者偽造消息的情況(偽造)。即是每個將軍都可以無誤地將自己的消息發送給其他每個將軍。(下一節中可以不需要這個必要條件)
我們定義口頭消息演算法OM(m) 。對於所有的非負整數m ,每個發令者通過OM(M) 演算法發送命令給n-1 個副官。下面將說明OM(m) 演算法在最多有m 個背叛者且總將軍數為3m+1 或者更多的情況下可以解決拜占庭將軍問題。(考慮到網路應用實際環境,原文使用了收到值代替收到命令,本文不做修改)
演算法定義一個函數:majority(com1,com2,…,comn)等於多數派命令。
OM(0)演算法
(1)發令者將他的命令發送給每個副官。
(2)每個副官採用他從發令者得到的命令,或者默認使用撤退命令,如果沒有收到任何命令。
OM(m)演算法
(1)發令者將他的命令發送給每個副官。
(2)對於每個i ,vi 是每個副官i 從發令者收到的命令,如果沒有收到命令則為撤退命令。副官i 在OM(m-1) 中作為發令者將vi 發送給另外n-2 個副官。
(3)對於每個i,並且j eq i,vj 是副官i 從第(2)步中的副官j 發送過來的命令(使用OM(m-1)演算法),如果沒有收到第(2)步中的副官j 的命令則默認為撤退命令。最後副官i 使用majority(v1,…,vn-1)得到命令。
接下來實際的考慮一個n=4,m=1 的情況:
1. 當副官D是背叛者
第一步發令者A執行演算法OM(1)將自己的命令發送給三個副官B,C,D,三個副官都正確地收到了命令。
第二步每個收到命令的副官都作為發令者執行演算法OM(0),將自己收到的命令轉發給其餘副官,因為副官D是背叛者,所以他給副官B和C傳遞的消息可能會是假消息。副官B和C分別根據majority 函數來決定命令。
這樣背叛的副官D 同理也干擾不了發令者的決定。下面看看如果發令者是背叛者。
2. 發令者是背叛者,其餘副官為忠誠的
第一步:發令者A向副官B,C,D發送了不同的命令,實際情況中是一個攻擊者向不同方發送了不一致的值(例如,0或1)企圖擾亂副官做出一致決定。
第二步:副官收到命令後,搖身一變為發令者執行OM(0) 向所有的副官發送命令,每個副官通過多數表決演算法仍可以達成一致的命令。
文章接著就證明了OM(m)演算法對任意m 都是可以滿足,首先引入一個引理(歸納法證明):
引理1:對於任意m 和k ,如果有超過2k+m 個將軍和最多k 個背叛者,那麼演算法OM(m) 滿足IC2 (回顧下IC2 指的是,如果將軍是忠誠的,所有的副官遵守將軍命令)。
證明:當m=0 的時候,OM(0) 在將軍是忠誠的時候滿足IC2。當m>0 時,首先將軍將命令傳遞給 n-1 個副官,然後每個副官對n-1 個將軍執行OM(m-1) 演算法。因為假設了n>2k+m(引理中有將軍數大於2k+m),所以 n-1 > 2k+(m-1) >= 2k(即每一輪中副官總數不小於背叛者的兩倍),這樣每輪OM(m-k) 演算法中忠誠的副官收到的命令都是majority(v1,v2,...,v(n-1)),其中忠誠副官發送的命令大於或者等於一半。
接著解決拜占庭將軍問題。
定理1:對於任意m,如果有超過3m 個將軍和最多m 個背叛者,演算法OM(m) 滿足條件IC1 和條件IC2。
證明:通過m 的歸納法證明,我們通過假設OM(m-1) 成立來證明OM(m) m>0。首先考慮發送命令的將軍是忠誠的。那麼將引理中k 設為m 則OM(m) 滿足IC2 ,IC1 在發令將軍是忠誠的情況下也滿足。
接著考慮m 個背叛者中有一個是發令者,那最多就只有m-1 個副官是背叛者了,又因為有3m 個將軍,所以副官的總數超過3m-1,且有3m-1>3(m-1) 。因此通過歸納法假設 OM(m-1) 滿足IC1 和IC2(最多3(m-1) 個將軍和最多m-1 個背叛者)。那麼任意兩個忠誠的副官j 在OM(m-1) 獲得相同命令vj,那麼在OM(m) 演算法中每個忠誠的副官都會收到(v1,v2,...,v(n-1)),可知滿足條件IC1 和IC2。
看完這段證明其實我也挺糊塗的~~~~,畫了張圖來看看lamport 是怎麼證明的:
簽名消息在除了滿足口頭消息A1-A3 三點要求外還應該滿足下面A4:
A4 (a)簽名不可被偽造,一旦被篡改即可發現
(b)任何人都可以驗證將軍簽名的可靠性
下面定義一個類似於上面majority() 函數的choice() 來決定副官的選擇:1.當集合V 只包含了一個元素v ,那麼choice(V)=v ;2. choice(o)=RETREAT。
有了上面A4 和choice() 基礎我們給出SM(m) 方法:
SM(m) 演算法
初始化Vi=空集合
(1)將軍簽署命令並發給每個副官
(2)對於每個副官i :
(A)如果副官i 從發令者收到v:0 的消息,且還沒有收到其他命令序列,那麼:
(i)使Vi 為{v}
(ii)發送v:0:i 給其他所有副官
(B)如果副官i 收到消息v:0:j1:...:jk 且v 不在集合Vi 中則
(i)添加v 到Vi
(ii)如果k<m ,那麼發送v:0:j1:...:jk:i 給每個不在j1,..,jk 中的副官
(3)對於每個副官i ,當不再收到消息,則遵守命令choive(Vi)
演算法的幾點說明:
演算法第三步並沒有說明副官如何判斷沒有新的消息,可以通過兩個解決方法:一是要求每個副官收到消息後要麼簽名轉發該消息,要麼發送一個通知他將不發送這個消息;二是設置一個超時時間,如果在該時間段還沒有收到消息,則認為不再收到消息。
演算法SM(m) 中,讓副官簽名是確認其收到了該消息(有點像來了份文件給每個領導批閱)。在SM(1) 中副官收到消息就不用簽字了,因為不用轉發給其他副官。
定理2:對於任意m,最多隻有m 個背叛者情況下,演算法SM(m) 解決拜占庭將軍問題
Proof:首先證明IC2,如果發令者是忠誠的,那麼所有的副官一定收到相同的命令,因為簽名無法篡改,且IC1 也就滿足了。證明IC1 只用考慮發令者是背叛者的情況(重新回顧下IC1 是指所有忠誠的副官執行相同的命令),IC1 要求兩個忠誠的副官(i,j)必須收到相同的命令集合Vi、Vj,也就是Vi 中每個v 都在Vj 中。會存在兩種情況,其一當副官i 收到v 命令的序列後,加入到Vi,並將其發送給副官j ,j 將命令v 保存;其二副官i 收到命令v:0:j1:...:jk:i,其中有jr=j,所以 由A4 可知副官j 也收到了該命令。如果沒有,則有:
k<m。這種情況下,i 發送信息v:0:j1:...:jk:i 給副官j ,那麼j 一定收到v 。(這點感覺和上面有重復)
k=m。發令者是背叛者,最多隻有m-1 個副官是背叛者。因此,最少有一個序列j1,...,jm是忠誠的。那麼j 一定收到這個忠誠的副官序列發來的值v ,所以副官j 收到v 。
證明完畢。

⑻ 康邁臣AHN`S CHOICE的優勢在哪裡

康邁臣AHN`S CHOICE優勢在龐大的資料庫、縝密的演算法及權威的專家。它集合業界知名的營養學專家,聯合有近200家大型知名三甲醫院復雜項目建設經驗、國家健康管理團體標准制定參與單位的系統開發公司,並且參考中國營養學會,中華醫學會健康管理分會等出具的10餘種權威文獻,打造出現在的龐大系統。 想了解更多可以網路一下

⑼ 計算機演算法中的遞歸法與選擇排序法是什麼請細講

遞歸是設計和描述演算法的一種有力的工具,由於它在復雜演算法的描述中被經常採用,為此在進一步介紹其他演算法設計方法之前先討論它。
能採用遞歸描述的演算法通常有這樣的特徵:為求解規模為N的問題,設法將它分解成規模較小的問題,然後從這些小問題的解方便地構造出大問題的解,並且這些規模較小的問題也能採用同樣的分解和綜合方法,分解成規模更小的問題,並從這些更小問題的解構造出規模較大問題的解。特別地,當規模N=1時,能直接得解。

遞歸演算法的執行過程分遞推和回歸兩個階段。在遞推階段,把較復雜的問題(規模為n)的求解推到比原問題簡單一些的問題(規模小於n)的求解。例如上例中,求解fib(n),把它推到求解fib(n-1)和fib(n-2)。也就是說,為計算fib(n),必須先計算fib(n-1)和fib(n-2),而計算fib(n-1)和fib(n-2),又必須先計算fib(n-3)和fib(n-4)。依次類推,直至計算fib(1)和fib(0),分別能立即得到結果1和0。在遞推階段,必須要有終止遞歸的情況。例如在函數fib中,當n為1和0的情況。
在回歸階段,當獲得最簡單情況的解後,逐級返回,依次得到稍復雜問題的解,例如得到fib(1)和fib(0)後,返回得到fib(2)的結果,……,在得到了fib(n-1)和fib(n-2)的結果後,返回得到fib(n)的結果。
在編寫遞歸函數時要注意,函數中的局部變數和參數知識局限於當前調用層,當遞推進入「簡單問題」層時,原來層次上的參數和局部變數便被隱蔽起來。在一系列「簡單問題」層,它們各有自己的參數和局部變數。
由於遞歸引起一系列的函數調用,並且可能會有一系列的重復計算,遞歸演算法的執行效率相對較低。當某個遞歸演算法能較方便地轉換成遞推演算法時,通常按遞推演算法編寫程序。例如上例計算斐波那契數列的第n項的函數fib(n)應採用遞推演算法,即從斐波那契數列的前兩項出發,逐次由前兩項計算出下一項,直至計算出要求的第n項。

選擇排序法 是對 定位比較交換法 的一種改進。在講選擇排序法之前我們先來了解一下定位比較交換法。為了便於理解,設有10個數分別存在數組元素a[0]~a[9]中。定位比較交換法是由大到小依次定位a[0]~a[9]中恰當的值(和武林大會中的比武差不多),a[9]中放的自然是最小的數。如定位a[0],先假定a[0]中當前值是最大數,a[0]與後面的元素一一比較,如果a[4]更大,則將a[0]、a[4]交換,a[0]已更新再與後面的a[5]~a[9]比較,如果a[8]還要大,則將a[0]、a[8]交換,a[0]又是新數,再與a[9]比較。一輪比完以後,a[0]就是最大的數了,本次比武的武狀元誕生了,接下來從a[1]開始,因為狀元要休息了,再來一輪a[1]就是次大的數,也就是榜眼,然後從a[2]開始,比出探花,真成比武大會了,當必到a[8]以後,排序就完成了。
下面給大家一個例子:
mai()
{
int a[10];
int i,j,t;
for ( i = 0; i < 10; i ++ ) scanf("%d",&a[ i ]); /*輸入10個數,比武報名,報名費用10000¥ ^_^*/
for ( i = 0; i < 9; i ++ )
for ( j = i + 1; j < 10; j ++)
if ( a[ i ] < a[ j ] ) { t = a[ i ]; a[ i ] = a[ j ]; a[ j ] = t; } /*打不過就要讓出頭把交椅,不過a[ i ]比較愛面子,不好意思見 a[ j ],讓t幫忙*/
for( i = 0; i < 10; i ++) printf("%4d",a[ i ]); /*顯示排序後的結果*/
}
好啦,羅嗦了半天總算把定位比較排序法講完了,這個方法不錯,容易理解,就是有點麻煩,一把椅子換來換去,哎~
所以就有了下面的選擇排序法,開始的時候椅子誰也不給,放在一邊讓大家看著,找個人k記錄比賽結果,然後發椅子。具體來講呢就是,改進定位比較排序法,但是這個改進只是一部分,比較的次數沒變,該怎麼打還是怎麼打,就是不用換椅子了。每次外循環先將定位元素的小標i值記錄到K,認為a[k]是最大元素其實i=k還是a[ i ]最大,a[k]與後面的元素一一比較,該交換的也是也不換,就是把K的值改變一下就完了,最後在把a[k]與a[ i ]交換,這樣a就是最大的元素了。然後進入下一輪的比較。選擇排序法與定位比較排序法相比較,比的次數沒變,交換的次數減少了。
下面也寫個例子:
main()
{
int a[10];
int i,j,t,k;
for ( i = 0; i < 10; i ++ ) scanf("%d",&a[ i ]); /*輸入10個數,比武報名,報名費用10000¥ ^_^*/
for ( i = 0; i < 9; i ++ )
{ k = i; /*裁判AND記者實時追蹤報道比賽情況*/
for ( j = i + 1; j < 10; j ++)
if ( a[ k ] < a[ j ] ) k = j;
t = a[ i ]; a[ i ] = a[ k ]; a[ k ] = t; /* t 發放獎品*/
}
for( i = 0; i < 10; i ++) printf("%4d",a[ i ]); /*顯示排序後的結果*/
}

⑽ 康邁臣AHN`S CHOICE是做什麼的

康邁臣AHN`S CHOICE是做精準定製營‍養‍素項目的。用科學與系統賦能,實現用戶足不出戶,通過科學的問卷設計與大數據演算法,精準捕捉其的獨特營養需求,並匹配專業安全的營養補充方案,一站式解決問詢、建檔、分析、健康定製、產品配送等全鏈條服務。精準內容設定上,康邁臣AHN`S CHOICE基於每個人的年齡、性別、健康史、軀體症狀、生活方式、心理健康、睡眠健康、劑量超標風險、葯物相互作用風險等綜合評估,找出營養狀況不良的人群或有營養改善需求的人群,經過嚴謹的邏輯演算法後,給出高度個性化定製的產品方案,並且給出改善不良生活方式的建議。 想了解更多可以網路一下

閱讀全文

與choice演算法排名相關的資料

熱點內容
南京解壓車要帶什麼 瀏覽:562
天堂2編譯視頻教程 瀏覽:392
伺服器沒有進程怎麼辦 瀏覽:784
阿里雲發布新物種神龍雲伺服器 瀏覽:59
數據結構遞歸演算法統計二叉樹節點 瀏覽:666
ev3怎麼編程 瀏覽:702
gzip壓縮教程 瀏覽:349
解壓模擬例子 瀏覽:984
流媒體伺服器如何實現視頻轉發 瀏覽:57
linux字元串md5 瀏覽:302
支撐突破選股源碼怎麼設置 瀏覽:934
湖南戴爾伺服器維修雲主機 瀏覽:494
解壓到文件夾的視頻都自動隱藏了 瀏覽:569
閱讀器支持php 瀏覽:222
人生需求怎麼解壓 瀏覽:795
pdf列印機找不到 瀏覽:1001
如何同時使用兩個apache伺服器 瀏覽:723
國外php論壇 瀏覽:966
災難是命令 瀏覽:604
linux火狐瀏覽器安裝 瀏覽:71