1. 程式人生 > 其它 >用deeplabV3+訓練自己的資料集並匯出.pb模型進行視覺化測試

用deeplabV3+訓練自己的資料集並匯出.pb模型進行視覺化測試

技術標籤:筆記

1.演算法實現題:整數變換問題。整數i的兩種變換定義為 , (向下取整);設計一個演算法求給定兩個整數a和b,用最少次數的 和 變換將整數a變換為b;例如
實現提示:
觀察f和g兩個操作可知,f總是使得i變大,g總是使得i變小。因此在決定讓x執行哪個操作之前可以先判斷i和目標值m之間的大小關係。如果x>m,就讓其執行g操作;反之,執行f操作。
問題的解分為兩種情況,一種是有解,即n可以通過函式變換成m;另一種是無解,即n無法通過函式變換成m。
有解的情況比較容易,只需要判斷最後的i是否等於m即可。如果i等於m,那麼說明n已經被變換成m了,遞迴返回。
無解的情況可用下例分析。假設我們的輸入n=9,m=5。

n>m,執行g,n=[9/2]=4
n<m,執行f,n=3*4=12
n>m,執行g,n=[12/2]=6
n>m,執行f,n=[6/2]=3

n<m,執行g,n=3*3=9
n>m,執行f,n=[9/2]=4
如果n的值陷入了一個重複的迴圈,如果在遞迴的過程中,出現了前面計算過的元素,那就說明n是無法轉換成m的。這種方法實現稍微複雜,需要判斷當前所求出的數值之前是否出現過。 另一種簡單的處理方式: 對於m無論如何變換都不能變為n的情況,可以加一個判斷條件,比如深度達一個較大值為止(如1000)。
回溯法, 用子集樹實現,子集樹結構為:
在這裡插入圖片描述
回溯返回條件有兩個,一個是i等於m,另一個是出現了重複的數字。第二個返回條件可以用一個函式test來判斷。

剪枝條件:
顯式約束:如果x>m,就剪掉它的左子樹;如果x<m,就剪掉它的右子樹;
隱式約束:如果在某次計算的過程中發現當前的計算次數已經大於或等於最少計算次數了,那麼就剪掉這個分支。

#include<stdio.h>
char a[100]={'\0'};
int k=1,c=0;
int select(int n,int m,int s)
{
	if(s==0)
		return 3*n;
	else
		return n/2;

}
bool back(int nu,int m,int n)
{
	int i,num;
	if(nu>k)
		return false
; num=n; for(i=0;i<=1;i++) { num=select(n,m,i); if(num==m||back(nu+1,m,num)) //當兩個數字相等或出現重複的數字 { if(i==0) a[c]='f'; else a[c]='g'; c++; return true; } } return false; } int main() { int nu=1; int m,n; //m為指定的數字,n為輸入的整數 scanf("%d%d",&m,&n); k=1; while(!back(1,m,n)) { k++; } printf("%d\n",k); for(int i=0;i<c;i++) printf("%c",a[i]); printf("\n"); return 0; }
  1. 子集和問題。
    問題描述:給定集合S,S中有n個正整數,M是一個正整數。子集和問題判定是否存在S的一個子集S1,使得S1中各元素之和等於M。請設計回溯法求解子集和問題,如果問題無解,輸出“No Solution”,問題有解,則輸出滿足子集S1中各元素的值。
#include<stdio.h>
int n,M,*s,*s1,x=0;
int ns=0,sum=0,flag=0;
void backtrace(int k)
{
	sum=sum+s[k];
	s1[x++]=s[k];	//複製陣列
	if(sum>M)
		return ;
	if(sum==M)
	{
		flag=1;
		return ;
	}
	for(int j=k+1;j<=n;j++)
	{
		if(flag==1)
			return;
		backtrace(j);
		if(flag==0)
		{
			sum=sum-s[j];
			x--;
		}
	}
}
int main()
{
	int i,sum1=0;;
	s1=new int[n+1];
	s=new int[n+1];
	scanf("%d%d",&n,&M);
	for(i=1;i<=n;i++)
	{
		scanf("%d",&s[i]);
		sum1=sum1+s[i];
	}
	if(sum1<M)	// 無解的情況
		printf("No Solution\n");
	s[0]=0;
	backtrace(0);
	if(flag)	// flag==1,說明有解
	{
		for(i=1;i<x;i++)
		printf("%d ",s1[i]);
		printf("\n");
	}
	else
		printf("No Solution\n");
	return 0;
}

  1. 工作分配問題。
    問題描述:設有n件工作分配給n個人。將工作i分配給第j個人的費用為cij,請設計演算法,為每個人都分配1件不同的工作,並使得總費用達到最小。
    實現提示:該問題的解空間是一#,可用搜索排列樹的回溯框架實現。
#include<stdio.h>
int n,*job,*x,c[1000][1000];
int costmin=100,nc=0;
void swap(int*a,int*b)
{
	int temp;
	temp=*a;*a=*b;*b=temp;
}
void backtrace(int k)
{
	int i;
	if(k>n)
	{	
		if(nc<costmin)
		{
			costmin=nc;
		}
	}
	else
	{
		for(i=k;i<=n;i++)
		{
			for(int j=1;j<i;j++)
			{
				job[k]=j;	//k個工作分給j個人
				nc=nc+c[k][j];	// 工作費用的計算
			}
			swap(&x[k],&x[i]);
			if(nc<costmin)
				backtrace(k+1);
			swap(&x[k],&x[i]);
		}
	}
}
int main()
{
	int i,j;
	x=new int[n+1];
	job=new int[n+1];
	scanf("%d",&n);
	for(i=1;i<=n;i++)
		for(j=1;j<=n;j++)
		{
			scanf("%d",&c[i][j]);
		}
		backtrace(1);
		printf("%d\n",costmin);
	return 0;
}